ddx-python 1.0.5__cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. ddx/.gitignore +1 -0
  2. ddx/__init__.py +58 -0
  3. ddx/_rust/__init__.pyi +2009 -0
  4. ddx/_rust/common/__init__.pyi +17 -0
  5. ddx/_rust/common/accounting.pyi +6 -0
  6. ddx/_rust/common/enums.pyi +3 -0
  7. ddx/_rust/common/requests/__init__.pyi +21 -0
  8. ddx/_rust/common/requests/intents.pyi +19 -0
  9. ddx/_rust/common/specs.pyi +17 -0
  10. ddx/_rust/common/state/__init__.pyi +41 -0
  11. ddx/_rust/common/state/keys.pyi +29 -0
  12. ddx/_rust/common/transactions.pyi +7 -0
  13. ddx/_rust/decimal.pyi +3 -0
  14. ddx/_rust/h256.pyi +3 -0
  15. ddx/_rust.abi3.so +0 -0
  16. ddx/app_config/ethereum/addresses.json +541 -0
  17. ddx/auditor/README.md +32 -0
  18. ddx/auditor/__init__.py +0 -0
  19. ddx/auditor/auditor_driver.py +1034 -0
  20. ddx/auditor/websocket_message.py +54 -0
  21. ddx/common/__init__.py +0 -0
  22. ddx/common/epoch_params.py +28 -0
  23. ddx/common/fill_context.py +144 -0
  24. ddx/common/item_utils.py +38 -0
  25. ddx/common/logging.py +184 -0
  26. ddx/common/market_specs.py +64 -0
  27. ddx/common/trade_mining_params.py +19 -0
  28. ddx/common/transaction_utils.py +85 -0
  29. ddx/common/transactions/__init__.py +0 -0
  30. ddx/common/transactions/advance_epoch.py +91 -0
  31. ddx/common/transactions/advance_settlement_epoch.py +63 -0
  32. ddx/common/transactions/all_price_checkpoints.py +84 -0
  33. ddx/common/transactions/cancel.py +76 -0
  34. ddx/common/transactions/cancel_all.py +88 -0
  35. ddx/common/transactions/complete_fill.py +103 -0
  36. ddx/common/transactions/disaster_recovery.py +97 -0
  37. ddx/common/transactions/event.py +48 -0
  38. ddx/common/transactions/fee_distribution.py +119 -0
  39. ddx/common/transactions/funding.py +294 -0
  40. ddx/common/transactions/futures_expiry.py +123 -0
  41. ddx/common/transactions/genesis.py +108 -0
  42. ddx/common/transactions/inner/__init__.py +0 -0
  43. ddx/common/transactions/inner/adl_outcome.py +25 -0
  44. ddx/common/transactions/inner/fill.py +227 -0
  45. ddx/common/transactions/inner/liquidated_position.py +41 -0
  46. ddx/common/transactions/inner/liquidation_entry.py +41 -0
  47. ddx/common/transactions/inner/liquidation_fill.py +118 -0
  48. ddx/common/transactions/inner/outcome.py +32 -0
  49. ddx/common/transactions/inner/trade_fill.py +125 -0
  50. ddx/common/transactions/insurance_fund_update.py +142 -0
  51. ddx/common/transactions/insurance_fund_withdraw.py +99 -0
  52. ddx/common/transactions/liquidation.py +357 -0
  53. ddx/common/transactions/partial_fill.py +125 -0
  54. ddx/common/transactions/pnl_realization.py +122 -0
  55. ddx/common/transactions/post.py +72 -0
  56. ddx/common/transactions/post_order.py +95 -0
  57. ddx/common/transactions/price_checkpoint.py +96 -0
  58. ddx/common/transactions/signer_registered.py +62 -0
  59. ddx/common/transactions/specs_update.py +61 -0
  60. ddx/common/transactions/strategy_update.py +156 -0
  61. ddx/common/transactions/tradable_product_update.py +98 -0
  62. ddx/common/transactions/trade_mining.py +147 -0
  63. ddx/common/transactions/trader_update.py +105 -0
  64. ddx/common/transactions/withdraw.py +91 -0
  65. ddx/common/transactions/withdraw_ddx.py +74 -0
  66. ddx/common/utils.py +176 -0
  67. ddx/config.py +17 -0
  68. ddx/derivadex_client.py +254 -0
  69. ddx/py.typed +0 -0
  70. ddx/realtime_client/__init__.py +2 -0
  71. ddx/realtime_client/config.py +2 -0
  72. ddx/realtime_client/logs/pytest.log +0 -0
  73. ddx/realtime_client/models/__init__.py +683 -0
  74. ddx/realtime_client/realtime_client.py +567 -0
  75. ddx/rest_client/__init__.py +0 -0
  76. ddx/rest_client/clients/__init__.py +0 -0
  77. ddx/rest_client/clients/base_client.py +60 -0
  78. ddx/rest_client/clients/market_client.py +1241 -0
  79. ddx/rest_client/clients/on_chain_client.py +432 -0
  80. ddx/rest_client/clients/signed_client.py +301 -0
  81. ddx/rest_client/clients/system_client.py +843 -0
  82. ddx/rest_client/clients/trade_client.py +335 -0
  83. ddx/rest_client/constants/__init__.py +0 -0
  84. ddx/rest_client/constants/endpoints.py +67 -0
  85. ddx/rest_client/contracts/__init__.py +0 -0
  86. ddx/rest_client/contracts/checkpoint/__init__.py +560 -0
  87. ddx/rest_client/contracts/ddx/__init__.py +1949 -0
  88. ddx/rest_client/contracts/dummy_token/__init__.py +1014 -0
  89. ddx/rest_client/contracts/i_collateral/__init__.py +1414 -0
  90. ddx/rest_client/contracts/i_stake/__init__.py +696 -0
  91. ddx/rest_client/exceptions/__init__.py +0 -0
  92. ddx/rest_client/exceptions/exceptions.py +32 -0
  93. ddx/rest_client/http/__init__.py +0 -0
  94. ddx/rest_client/http/http_client.py +305 -0
  95. ddx/rest_client/models/__init__.py +0 -0
  96. ddx/rest_client/models/market.py +683 -0
  97. ddx/rest_client/models/signed.py +60 -0
  98. ddx/rest_client/models/system.py +390 -0
  99. ddx/rest_client/models/trade.py +140 -0
  100. ddx/rest_client/utils/__init__.py +0 -0
  101. ddx/rest_client/utils/encryption_utils.py +26 -0
  102. ddx_python-1.0.5.dist-info/METADATA +63 -0
  103. ddx_python-1.0.5.dist-info/RECORD +104 -0
  104. ddx_python-1.0.5.dist-info/WHEEL +4 -0
@@ -0,0 +1,227 @@
1
+ """
2
+ Fill module
3
+ """
4
+
5
+ import logging
6
+ from enum import Enum
7
+ from typing import Optional
8
+
9
+ from attrs import define, field
10
+ from ddx.common.fill_context import (MAX_DDX_PRICE_CHECKPOINT_AGE_IN_TICKS,
11
+ FillContext, apply_trade)
12
+ from ddx.common.transaction_utils import get_most_recent_price
13
+ from ddx.common.transactions.event import Event
14
+ from ddx.common.transactions.inner.outcome import Outcome
15
+ from ddx._rust.common import ProductSymbol, TokenSymbol
16
+ from ddx._rust.common.enums import OrderSide, TradeSide
17
+ from ddx._rust.common.state import (DerivadexSMT, InsuranceFund, Position,
18
+ Price, Stats)
19
+ from ddx._rust.common.state.keys import (EpochMetadataKey, InsuranceFundKey,
20
+ PositionKey, PriceKey, StatsKey,
21
+ StrategyKey, TraderKey)
22
+ from ddx._rust.decimal import Decimal
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ @define(hash=True)
28
+ class Fill(Event):
29
+ """
30
+ Defines a Fill
31
+ """
32
+
33
+ symbol: ProductSymbol
34
+ amount: Decimal = field(hash=False)
35
+ price: Decimal = field(hash=False)
36
+ taker_side: OrderSide = field(hash=False)
37
+ time_value: int
38
+ request_index: int = field(eq=False, hash=False)
39
+
40
+ def adjust_for_maker_taker(
41
+ self,
42
+ smt: DerivadexSMT,
43
+ epoch_id: int,
44
+ is_maker: bool,
45
+ outcome: Outcome,
46
+ trade_mining_active: bool = False,
47
+ maker_book_order_time_value: Optional[int] = None,
48
+ ):
49
+ """
50
+ Make some adjustments to the SMT based on whether we are
51
+ considering the maker or the taker component of the Trade.
52
+ In this method, we will be adjusting the the Strategy,
53
+ Position, and Stats leaves.
54
+
55
+ Parameters
56
+ ----------
57
+ smt: DerivadexSMT
58
+ DerivaDEX Sparse Merkle Tree
59
+ epoch_id: int
60
+ Epoch ID used for recording fees if any
61
+ is_maker : bool
62
+ Whether outcome is for the maker or taker
63
+ outcome: Outcome
64
+ Outcome to adjust
65
+ trade_mining_active : bool
66
+ Whether trade mining is active
67
+ maker_book_order_time_value: Optional[int]
68
+ Maker book order time value
69
+ """
70
+
71
+ context = FillContext(outcome)
72
+
73
+ position_key: PositionKey = PositionKey(
74
+ outcome.trader,
75
+ outcome.strategy_id_hash,
76
+ self.symbol,
77
+ )
78
+
79
+ position: Optional[Position] = smt.position(position_key)
80
+
81
+ position = context.apply_fill(
82
+ position,
83
+ (
84
+ (OrderSide.Ask if self.taker_side == OrderSide.Bid else OrderSide.Bid)
85
+ if is_maker
86
+ else self.taker_side
87
+ ),
88
+ (TradeSide.Maker if is_maker else TradeSide.Taker),
89
+ self.amount,
90
+ self.price,
91
+ )
92
+ smt.store_position(
93
+ position_key,
94
+ position,
95
+ )
96
+
97
+ trader_key: TraderKey = TraderKey(outcome.trader)
98
+ trader = smt.trader(trader_key)
99
+
100
+ if outcome.fee > Decimal("0") and trader.pay_fees_in_ddx:
101
+ # Gets the most recent DDX price within MAX_DDX_PRICE_CHECKPOINT_AGE_IN_TICKS
102
+ _, recent_ddx_price = get_most_recent_price(
103
+ smt, ProductSymbol("DDXP"), self.time_value
104
+ )
105
+ if (
106
+ recent_ddx_price.time_value
107
+ >= self.time_value - MAX_DDX_PRICE_CHECKPOINT_AGE_IN_TICKS
108
+ ):
109
+ if context.apply_ddx_fee_and_mutate_trader(
110
+ trader, recent_ddx_price.index_price
111
+ ):
112
+ smt.store_trader(trader_key, trader)
113
+ else:
114
+ raise Exception(
115
+ "DDX fee election enabled but no DDX price checkpoint within the max age was found, should have been caught by the operator"
116
+ )
117
+
118
+ strategy_key: StrategyKey = position_key.as_strategy_key()
119
+ strategy = smt.strategy(strategy_key)
120
+ context.realize_trade_and_mutate_strategy(strategy)
121
+ smt.store_strategy(strategy_key, strategy)
122
+
123
+ if outcome.fee > Decimal("0"):
124
+ if outcome.pay_fee_in_ddx:
125
+ logger.info(f"Fee of {outcome.fee} DDX to be paid")
126
+ epoch_metadata_key: EpochMetadataKey = EpochMetadataKey(epoch_id)
127
+ epoch_metadata = smt.epoch_metadata(epoch_metadata_key)
128
+ epoch_metadata.ddx_fee_pool = (
129
+ epoch_metadata.ddx_fee_pool + outcome.fee
130
+ ).recorded_amount()
131
+ smt.store_epoch_metadata(epoch_metadata_key, epoch_metadata)
132
+ else:
133
+ logger.info(f"Fee of {outcome.fee} USDC to be paid")
134
+ insurance_fund_key: InsuranceFundKey = InsuranceFundKey()
135
+ insurance_fund = smt.insurance_fund(insurance_fund_key)
136
+ insurance_fund[TokenSymbol.USDC] += outcome.fee
137
+ smt.store_insurance_fund(insurance_fund_key, insurance_fund)
138
+
139
+ if (
140
+ trade_mining_active
141
+ and maker_book_order_time_value
142
+ and self.time_value > maker_book_order_time_value + 1
143
+ ):
144
+ stats_key: StatsKey = StatsKey(outcome.trader)
145
+ stats = smt.stats(stats_key)
146
+ notional_amount = self.amount * self.price
147
+ if stats is None:
148
+ # If Stats leaf doesn't exist in the tree, we need
149
+ # to create/add a new one
150
+ if is_maker:
151
+ # Initialize the trader's maker volume
152
+ stats = Stats(notional_amount, Decimal("0"))
153
+ else:
154
+ # Initialize the trader's taker volume
155
+ stats = Stats(Decimal("0"), notional_amount)
156
+ else:
157
+ # If Stats leaf does exist, we update the existing leaf
158
+ if is_maker:
159
+ # Increment the trader's maker volume
160
+ stats.maker_volume += notional_amount
161
+ else:
162
+ # Increment the trader's taker volume
163
+ stats.taker_volume += notional_amount
164
+
165
+ smt.store_stats(stats_key, stats)
166
+
167
+ def adjust_for_maker(
168
+ self,
169
+ smt: DerivadexSMT,
170
+ epoch_id: int,
171
+ trade_mining_active: bool = False,
172
+ maker_book_order_time_value: Optional[int] = None,
173
+ ):
174
+ """
175
+ Make some adjustments to the SMT based on the maker side
176
+ of the Trade.
177
+
178
+ Parameters
179
+ ----------
180
+ smt: DerivadexSMT
181
+ DerivaDEX Sparse Merkle Tree
182
+ epoch_id: int
183
+ Epoch ID used for recording fees if any
184
+ trade_mining_active : bool
185
+ Whether trade mining is active
186
+ maker_book_order_time_value: Optional[int]
187
+ Maker book order time value
188
+ """
189
+ self.adjust_for_maker_taker(
190
+ smt,
191
+ epoch_id,
192
+ True,
193
+ self.maker_outcome,
194
+ trade_mining_active,
195
+ maker_book_order_time_value,
196
+ )
197
+
198
+ def adjust_for_taker(
199
+ self,
200
+ smt: DerivadexSMT,
201
+ epoch_id: int,
202
+ trade_mining_active: bool = False,
203
+ maker_book_order_time_value: Optional[int] = None,
204
+ ):
205
+ """
206
+ Make some adjustments to the SMT based on the taker side
207
+ of the Trade.
208
+
209
+ Parameters
210
+ ----------
211
+ smt: DerivadexSMT
212
+ DerivaDEX Sparse Merkle Tree
213
+ epoch_id: int
214
+ Epoch ID used for recording fees if any
215
+ maker_book_order_time_value: int
216
+ Maker book order time value
217
+ trade_mining_active : bool
218
+ Whether trade mining is active
219
+ """
220
+ self.adjust_for_maker_taker(
221
+ smt,
222
+ epoch_id,
223
+ False,
224
+ self.taker_outcome,
225
+ trade_mining_active,
226
+ maker_book_order_time_value,
227
+ )
@@ -0,0 +1,41 @@
1
+ """
2
+ LiquidatedPosition module
3
+ """
4
+
5
+ from attrs import define, field
6
+ from ddx.common.transactions.cancel import Cancel
7
+ from ddx.common.transactions.inner.adl_outcome import AdlOutcome
8
+ from ddx.common.transactions.inner.liquidation_fill import LiquidationFill
9
+ from ddx._rust.decimal import Decimal
10
+
11
+
12
+ @define
13
+ class LiquidatedPosition:
14
+ """
15
+ Defines a LiquidatedPosition
16
+
17
+ A LiquidatedPosition has data pertaining to a liquidated position.
18
+
19
+ Attributes:
20
+ amount (Decimal): Liquidated balance amount
21
+ trade_outcomes (list[LiquidationFill | Cancel]): A list of trade outcome objects
22
+ adl_outcomes (list[AdlOutcome]): Positions that were ADL'd as a result of the liquidation
23
+ new_insurance_fund_cap (Decimal): Insurance fund capitalization after the liquidation
24
+ request_index (int): Sequenced request index of transaction
25
+ """
26
+
27
+ amount: Decimal
28
+ trade_outcomes: list[LiquidationFill | Cancel] = field(eq=set)
29
+ adl_outcomes: list[AdlOutcome] = field(eq=set)
30
+ new_insurance_fund_cap: Decimal
31
+ request_index: int = field(default=-1, eq=False)
32
+
33
+ def __hash__(self):
34
+ return hash(
35
+ (
36
+ self.amount,
37
+ frozenset(self.trade_outcomes),
38
+ frozenset(self.adl_outcomes),
39
+ self.new_insurance_fund_cap,
40
+ )
41
+ )
@@ -0,0 +1,41 @@
1
+ """
2
+ LiquidationEntry module
3
+ """
4
+
5
+ from attrs import define, field
6
+ from ddx.common.transactions.cancel import Cancel
7
+ from ddx.common.transactions.inner.liquidated_position import LiquidatedPosition
8
+ from ddx._rust.common import ProductSymbol
9
+
10
+
11
+ @define
12
+ class LiquidationEntry:
13
+ """
14
+ Defines a LiquidationEntry
15
+
16
+ A LiquidationEntry contains data pertaining to individual trader and
17
+ strategy liquidations.
18
+
19
+ Attributes:
20
+ trader_address (str): Liquidated trader's Ethereum address
21
+ strategy_id_hash (str): Liquidated strategy ID hash
22
+ canceled_orders (list[Cancel]): Canceled orders for liquidated trader
23
+ positions (list[tuple[str, LiquidatedPosition]]): Contains information pertaining to individual liquidated positions by symbol
24
+ request_index (int): Sequenced request index of transaction
25
+ """
26
+
27
+ trader_address: str = field(eq=str.lower)
28
+ strategy_id_hash: str = field(eq=str.lower)
29
+ canceled_orders: list[Cancel] = field(eq=set)
30
+ positions: list[tuple[ProductSymbol, LiquidatedPosition]] = field(eq=set)
31
+ request_index: int = field(default=-1, eq=False)
32
+
33
+ def __hash__(self):
34
+ return hash(
35
+ (
36
+ self.trader_address,
37
+ self.strategy_id_hash,
38
+ frozenset(self.canceled_orders),
39
+ frozenset(self.positions),
40
+ )
41
+ )
@@ -0,0 +1,118 @@
1
+ """
2
+ LiquidationFill module
3
+ """
4
+
5
+ import logging
6
+
7
+ from attrs import define, field
8
+ from ddx.common.transactions.inner.fill import Fill
9
+ from ddx.common.transactions.inner.outcome import Outcome
10
+ from ddx._rust.common import ProductSymbol
11
+ from ddx._rust.common.enums import OrderSide
12
+ from ddx._rust.common.state import DerivadexSMT
13
+ from ddx._rust.common.state.keys import BookOrderKey
14
+ from ddx._rust.decimal import Decimal
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ @define(hash=True)
20
+ class LiquidationFill(Fill):
21
+ """
22
+ Defines a LiquidationFill
23
+ """
24
+
25
+ maker_order_hash: str = field(eq=str.lower)
26
+ maker_outcome: Outcome = field(hash=False)
27
+ maker_order_remaining_amount: Decimal = field(hash=False)
28
+ index_price_hash: str = field(eq=str.lower)
29
+ request_index: int = field(default=-1, eq=False, hash=False)
30
+
31
+ def __init__(
32
+ self,
33
+ symbol: ProductSymbol,
34
+ index_price_hash: str,
35
+ maker_order_hash: str,
36
+ maker_order_remaining_amount: Decimal,
37
+ amount: Decimal,
38
+ price: Decimal,
39
+ taker_side: OrderSide,
40
+ maker_outcome: Outcome,
41
+ time_value: int,
42
+ request_index: int = -1,
43
+ ):
44
+ """
45
+ Initialize a LiquidationFill instance
46
+ Parameters
47
+ ----------
48
+ symbol : ProductSymbol
49
+ Product symbol
50
+ index_price_hash : str
51
+ Index price hash
52
+ maker_order_hash : str
53
+ Maker order hash
54
+ maker_order_remaining_amount : Decimal
55
+ Maker order remaining amount
56
+ amount : Decimal
57
+ Amount
58
+ price : Decimal
59
+ Price
60
+ taker_side : OrderSide
61
+ Taker side
62
+ maker_outcome : Outcome
63
+ Maker outcome
64
+ time_value : int
65
+ Time value
66
+ request_index : int
67
+ Request index
68
+ """
69
+ super().__init__(
70
+ symbol,
71
+ amount,
72
+ price,
73
+ taker_side,
74
+ time_value,
75
+ request_index,
76
+ )
77
+ self.maker_order_hash = maker_order_hash
78
+ self.maker_outcome = maker_outcome
79
+ self.maker_order_remaining_amount = maker_order_remaining_amount
80
+ self.index_price_hash = index_price_hash
81
+
82
+ def process_tx(
83
+ self,
84
+ smt: DerivadexSMT,
85
+ **kwargs,
86
+ ):
87
+ """
88
+ Process a LiquidationFill transaction. These are Fill
89
+ transactions that have risen from either a Liquidation.
90
+
91
+ Parameters
92
+ ----------
93
+ smt: DerivadexSMT
94
+ DerivaDEX Sparse Merkle Tree
95
+ **kwargs
96
+ Additional args specific to Liquidation transactions
97
+ """
98
+
99
+ maker_book_order_key: BookOrderKey = BookOrderKey(
100
+ self.symbol, self.maker_order_hash
101
+ )
102
+
103
+ maker_book_order = smt.book_order(maker_book_order_key)
104
+ maker_book_order_time_value = maker_book_order.time_value
105
+
106
+ maker_book_order.amount = self.maker_order_remaining_amount
107
+ smt.store_book_order(maker_book_order_key, maker_book_order)
108
+
109
+ # Adjust the maker-related position. Take note that
110
+ # in a liquidation, there is no taker component, so
111
+ # unlike its counterpart (TradeFill), a
112
+ # LiquidationFill only considers the maker
113
+ self.adjust_for_maker(
114
+ smt,
115
+ kwargs["epoch_id"],
116
+ kwargs["trade_mining_active"],
117
+ maker_book_order_time_value,
118
+ )
@@ -0,0 +1,32 @@
1
+ """
2
+ Outcome module
3
+ """
4
+
5
+ from typing import Optional
6
+
7
+ from attrs import define, field
8
+ from ddx._rust.decimal import Decimal
9
+
10
+
11
+ @define(hash=True)
12
+ class Outcome:
13
+ """
14
+ Defines a Outcome
15
+
16
+ An Outcome is a part of a Fill transaction. It holds information
17
+ including the fees paid, the strategy ID and trader address, and
18
+ whether fees are being paid in DDX or not (i.e. USDC).
19
+
20
+ Attributes:
21
+ trader (str): Trader's Ethereum address
22
+ strategy_id_hash (str): Strategy ID hash
23
+ fee (Decimal): Fees paid for filled trade
24
+ pay_fee_in_ddx (bool): Whether the trader has elected to pay the fee in DDX
25
+ """
26
+
27
+ trader: str = field(eq=str.lower, default="")
28
+ strategy_id_hash: str = field(eq=str.lower, default="")
29
+ # The below fields do not exist in the txlog (and thus are not checked in transaction
30
+ # equality), and are only used when executing/processing transactions.
31
+ fee: Optional[Decimal] = field(eq=False, default=None)
32
+ pay_fee_in_ddx: Optional[bool] = field(eq=False, default=None)
@@ -0,0 +1,125 @@
1
+ """
2
+ TradeFill module
3
+ """
4
+
5
+ import asyncio
6
+
7
+ from attrs import define, field
8
+ from ddx.common.transactions.inner.fill import Fill
9
+ from ddx.common.transactions.inner.outcome import Outcome
10
+ from ddx._rust.common import ProductSymbol
11
+ from ddx._rust.common.enums import OrderSide
12
+ from ddx._rust.common.state import DerivadexSMT, Price
13
+ from ddx._rust.common.state.keys import BookOrderKey, PriceKey
14
+ from ddx._rust.decimal import Decimal
15
+
16
+
17
+ @define(hash=True)
18
+ class TradeFill(Fill):
19
+ """
20
+ Defines a TradeFill
21
+ """
22
+
23
+ maker_order_hash: str = field(eq=str.lower)
24
+ maker_outcome: Outcome = field(hash=False)
25
+ maker_order_remaining_amount: Decimal = field(hash=False)
26
+ taker_order_hash: str = field(eq=str.lower)
27
+ taker_outcome: Outcome = field(hash=False)
28
+ request_index: int = field(default=-1, eq=False, hash=False)
29
+
30
+ def __init__(
31
+ self,
32
+ symbol: ProductSymbol,
33
+ taker_order_hash: str,
34
+ maker_order_hash: str,
35
+ maker_order_remaining_amount: Decimal,
36
+ amount: Decimal,
37
+ price: Decimal,
38
+ taker_side: OrderSide,
39
+ maker_outcome: Outcome,
40
+ taker_outcome: Outcome,
41
+ time_value: int,
42
+ request_index: int = -1,
43
+ ):
44
+ """
45
+ Initialize a TradeFill instance
46
+ Parameters
47
+ ----------
48
+ symbol : ProductSymbol
49
+ Product symbol
50
+ taker_order_hash : str
51
+ Taker order hash
52
+ maker_order_hash : str
53
+ Maker order hash
54
+ maker_order_remaining_amount : Decimal
55
+ Maker order remaining amount
56
+ amount : Decimal
57
+ Amount
58
+ price : Decimal
59
+ Price
60
+ taker_side : OrderSide
61
+ Taker side
62
+ maker_outcome : Outcome
63
+ Maker outcome
64
+ taker_outcome : Outcome
65
+ Taker outcome
66
+ time_value : int
67
+ Time value
68
+ request_index : int
69
+ Request index
70
+ """
71
+ super().__init__(
72
+ symbol,
73
+ amount,
74
+ price,
75
+ taker_side,
76
+ time_value,
77
+ request_index,
78
+ )
79
+ self.maker_order_hash = maker_order_hash
80
+ self.maker_outcome = maker_outcome
81
+ self.maker_order_remaining_amount = maker_order_remaining_amount
82
+ self.taker_order_hash = taker_order_hash
83
+ self.taker_outcome = taker_outcome
84
+
85
+ def process_tx(
86
+ self,
87
+ smt: DerivadexSMT,
88
+ **kwargs,
89
+ ):
90
+ """
91
+ Process a TradeFill transaction. These are Fill transactions
92
+ that have risen from either a CompleteFill or a PartialFill
93
+ transaction.
94
+
95
+ Parameters
96
+ ----------
97
+ smt: DerivadexSMT
98
+ DerivaDEX Sparse Merkle Tree
99
+ **kwargs
100
+ Additional args specific to CompleteFill/PartialFill transactions
101
+ """
102
+
103
+ maker_book_order_key: BookOrderKey = BookOrderKey(
104
+ self.symbol, self.maker_order_hash
105
+ )
106
+ maker_book_order = smt.book_order(maker_book_order_key)
107
+ maker_book_order_time_value = maker_book_order.time_value
108
+
109
+ maker_book_order.amount = self.maker_order_remaining_amount
110
+ smt.store_book_order(maker_book_order_key, maker_book_order)
111
+
112
+ # Make the appropriate adjustments for both the maker and taker
113
+ # components of the Trade
114
+ self.adjust_for_maker(
115
+ smt,
116
+ kwargs["epoch_id"],
117
+ kwargs["trade_mining_active"],
118
+ maker_book_order_time_value,
119
+ )
120
+ self.adjust_for_taker(
121
+ smt,
122
+ kwargs["epoch_id"],
123
+ kwargs["trade_mining_active"],
124
+ maker_book_order_time_value,
125
+ )