ddx-python 1.0.4__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.
- ddx/.gitignore +1 -0
- ddx/__init__.py +58 -0
- ddx/_rust/__init__.pyi +2685 -0
- ddx/_rust/common/__init__.pyi +17 -0
- ddx/_rust/common/accounting.pyi +6 -0
- ddx/_rust/common/enums.pyi +3 -0
- ddx/_rust/common/requests/__init__.pyi +23 -0
- ddx/_rust/common/requests/intents.pyi +19 -0
- ddx/_rust/common/specs.pyi +17 -0
- ddx/_rust/common/state/__init__.pyi +41 -0
- ddx/_rust/common/state/keys.pyi +29 -0
- ddx/_rust/common/transactions.pyi +7 -0
- ddx/_rust/decimal.pyi +3 -0
- ddx/_rust/h256.pyi +3 -0
- ddx/_rust.abi3.so +0 -0
- ddx/app_config/ethereum/addresses.json +526 -0
- ddx/auditor/README.md +32 -0
- ddx/auditor/__init__.py +0 -0
- ddx/auditor/auditor_driver.py +1043 -0
- ddx/auditor/websocket_message.py +54 -0
- ddx/common/__init__.py +0 -0
- ddx/common/epoch_params.py +28 -0
- ddx/common/fill_context.py +141 -0
- ddx/common/logging.py +184 -0
- ddx/common/market_aware_account.py +259 -0
- ddx/common/market_specs.py +64 -0
- ddx/common/trade_mining_params.py +19 -0
- ddx/common/transaction_utils.py +85 -0
- ddx/common/transactions/__init__.py +0 -0
- ddx/common/transactions/advance_epoch.py +91 -0
- ddx/common/transactions/advance_settlement_epoch.py +63 -0
- ddx/common/transactions/all_price_checkpoints.py +84 -0
- ddx/common/transactions/cancel.py +76 -0
- ddx/common/transactions/cancel_all.py +88 -0
- ddx/common/transactions/complete_fill.py +103 -0
- ddx/common/transactions/disaster_recovery.py +96 -0
- ddx/common/transactions/event.py +48 -0
- ddx/common/transactions/fee_distribution.py +119 -0
- ddx/common/transactions/funding.py +292 -0
- ddx/common/transactions/futures_expiry.py +123 -0
- ddx/common/transactions/genesis.py +108 -0
- ddx/common/transactions/inner/__init__.py +0 -0
- ddx/common/transactions/inner/adl_outcome.py +25 -0
- ddx/common/transactions/inner/fill.py +232 -0
- ddx/common/transactions/inner/liquidated_position.py +41 -0
- ddx/common/transactions/inner/liquidation_entry.py +41 -0
- ddx/common/transactions/inner/liquidation_fill.py +118 -0
- ddx/common/transactions/inner/outcome.py +32 -0
- ddx/common/transactions/inner/trade_fill.py +292 -0
- ddx/common/transactions/insurance_fund_update.py +138 -0
- ddx/common/transactions/insurance_fund_withdraw.py +100 -0
- ddx/common/transactions/liquidation.py +353 -0
- ddx/common/transactions/partial_fill.py +125 -0
- ddx/common/transactions/pnl_realization.py +120 -0
- ddx/common/transactions/post.py +72 -0
- ddx/common/transactions/post_order.py +95 -0
- ddx/common/transactions/price_checkpoint.py +97 -0
- ddx/common/transactions/signer_registered.py +62 -0
- ddx/common/transactions/specs_update.py +61 -0
- ddx/common/transactions/strategy_update.py +158 -0
- ddx/common/transactions/tradable_product_update.py +98 -0
- ddx/common/transactions/trade_mining.py +147 -0
- ddx/common/transactions/trader_update.py +131 -0
- ddx/common/transactions/withdraw.py +90 -0
- ddx/common/transactions/withdraw_ddx.py +74 -0
- ddx/common/utils.py +176 -0
- ddx/config.py +17 -0
- ddx/derivadex_client.py +270 -0
- ddx/models/__init__.py +0 -0
- ddx/models/base.py +132 -0
- ddx/py.typed +0 -0
- ddx/realtime_client/__init__.py +2 -0
- ddx/realtime_client/config.py +2 -0
- ddx/realtime_client/models/__init__.py +611 -0
- ddx/realtime_client/realtime_client.py +646 -0
- ddx/rest_client/__init__.py +0 -0
- ddx/rest_client/clients/__init__.py +0 -0
- ddx/rest_client/clients/base_client.py +60 -0
- ddx/rest_client/clients/market_client.py +1243 -0
- ddx/rest_client/clients/on_chain_client.py +439 -0
- ddx/rest_client/clients/signed_client.py +292 -0
- ddx/rest_client/clients/system_client.py +843 -0
- ddx/rest_client/clients/trade_client.py +357 -0
- ddx/rest_client/constants/__init__.py +0 -0
- ddx/rest_client/constants/endpoints.py +66 -0
- ddx/rest_client/contracts/__init__.py +0 -0
- ddx/rest_client/contracts/checkpoint/__init__.py +560 -0
- ddx/rest_client/contracts/ddx/__init__.py +1949 -0
- ddx/rest_client/contracts/dummy_token/__init__.py +1014 -0
- ddx/rest_client/contracts/i_collateral/__init__.py +1414 -0
- ddx/rest_client/contracts/i_stake/__init__.py +696 -0
- ddx/rest_client/exceptions/__init__.py +0 -0
- ddx/rest_client/exceptions/exceptions.py +32 -0
- ddx/rest_client/http/__init__.py +0 -0
- ddx/rest_client/http/http_client.py +336 -0
- ddx/rest_client/models/__init__.py +0 -0
- ddx/rest_client/models/market.py +693 -0
- ddx/rest_client/models/signed.py +61 -0
- ddx/rest_client/models/system.py +311 -0
- ddx/rest_client/models/trade.py +185 -0
- ddx/rest_client/utils/__init__.py +0 -0
- ddx/rest_client/utils/encryption_utils.py +26 -0
- ddx/utils/__init__.py +0 -0
- ddx_python-1.0.4.dist-info/METADATA +63 -0
- ddx_python-1.0.4.dist-info/RECORD +106 -0
- ddx_python-1.0.4.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,1243 @@
|
|
|
1
|
+
from typing import Optional, AsyncIterator, Dict
|
|
2
|
+
|
|
3
|
+
from ddx.rest_client.constants.endpoints import System, Market
|
|
4
|
+
from ddx.rest_client.clients.base_client import BaseClient
|
|
5
|
+
from ddx.rest_client.models.market import (
|
|
6
|
+
MarkPriceHistoryResponse,
|
|
7
|
+
MarkPrice,
|
|
8
|
+
OrderBookL3Response,
|
|
9
|
+
OrderUpdateHistoryResponse,
|
|
10
|
+
OrderUpdate,
|
|
11
|
+
StrategyUpdateHistoryResponse,
|
|
12
|
+
StrategyUpdate,
|
|
13
|
+
TickersResponse,
|
|
14
|
+
TraderUpdateHistoryResponse,
|
|
15
|
+
TraderUpdate,
|
|
16
|
+
BalanceAggregationResponse,
|
|
17
|
+
FeesAggregationResponse,
|
|
18
|
+
FeesAggregation,
|
|
19
|
+
FundingRateComparisonResponse,
|
|
20
|
+
TopTradersAggregationResponse,
|
|
21
|
+
TopTrader,
|
|
22
|
+
VolumeAggregationResponse,
|
|
23
|
+
VolumeAggregation,
|
|
24
|
+
FundingRateHistoryResponse,
|
|
25
|
+
FundingRateHistory,
|
|
26
|
+
OpenInterestHistoryResponse,
|
|
27
|
+
OrderBook,
|
|
28
|
+
OrderBookL2Response,
|
|
29
|
+
PriceCheckpointHistoryResponse,
|
|
30
|
+
PriceCheckpoint,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class MarketClient(BaseClient):
|
|
35
|
+
"""
|
|
36
|
+
System-related operations and data access.
|
|
37
|
+
|
|
38
|
+
Provides access to exchange configuration, system status, and other
|
|
39
|
+
system-related information through the API endpoints.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
async def get_mark_price_history_page(
|
|
43
|
+
self,
|
|
44
|
+
limit: Optional[int] = None,
|
|
45
|
+
epoch: Optional[int] = None,
|
|
46
|
+
symbol: Optional[str] = None,
|
|
47
|
+
order: Optional[str] = None,
|
|
48
|
+
global_ordinal: Optional[int] = None,
|
|
49
|
+
) -> MarkPriceHistoryResponse:
|
|
50
|
+
"""
|
|
51
|
+
Get a single page of mark prices over time.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
limit : Optional[int]
|
|
56
|
+
The number of rows to return
|
|
57
|
+
epoch : Optional[int]
|
|
58
|
+
The epoch boundary used when fetching the next timeseries page
|
|
59
|
+
symbol : Optional[str]
|
|
60
|
+
The symbol
|
|
61
|
+
order : Optional[str]
|
|
62
|
+
The ordering of the results. Values: "asc", "desc"
|
|
63
|
+
global_ordinal : Optional[int]
|
|
64
|
+
The global ordinal boundary used when fetching the next timeseries page
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
MarkPriceHistoryResponse
|
|
69
|
+
Single page of mark price history data
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
params = {
|
|
73
|
+
"limit": limit,
|
|
74
|
+
"epoch": epoch,
|
|
75
|
+
"symbol": symbol,
|
|
76
|
+
"order": order,
|
|
77
|
+
"globalOrdinal": global_ordinal,
|
|
78
|
+
}
|
|
79
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
80
|
+
|
|
81
|
+
response = await self._http.get(
|
|
82
|
+
self._build_url(Market.GET_MARK_PRICE_HISTORY), params=params
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return MarkPriceHistoryResponse.model_validate(response)
|
|
86
|
+
|
|
87
|
+
async def get_mark_price_history(
|
|
88
|
+
self,
|
|
89
|
+
epoch: Optional[int] = None,
|
|
90
|
+
symbol: Optional[str] = None,
|
|
91
|
+
order: Optional[str] = None,
|
|
92
|
+
limit: Optional[int] = 100,
|
|
93
|
+
) -> AsyncIterator[MarkPrice]:
|
|
94
|
+
"""
|
|
95
|
+
Get all mark price history data.
|
|
96
|
+
|
|
97
|
+
Automatically handles pagination using global_ordinal.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
epoch : Optional[int]
|
|
102
|
+
The epoch boundary used when fetching the next timeseries page
|
|
103
|
+
symbol : Optional[str]
|
|
104
|
+
The symbol
|
|
105
|
+
order : Optional[str]
|
|
106
|
+
The ordering of the results. Values: "asc", "desc"
|
|
107
|
+
limit : Optional[int]
|
|
108
|
+
The number of rows to return per page
|
|
109
|
+
|
|
110
|
+
Yields
|
|
111
|
+
------
|
|
112
|
+
MarkPrice
|
|
113
|
+
Mark price history entries
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
global_ordinal = None
|
|
117
|
+
|
|
118
|
+
while True:
|
|
119
|
+
response = await self.get_mark_price_history_page(
|
|
120
|
+
limit=limit,
|
|
121
|
+
epoch=epoch,
|
|
122
|
+
symbol=symbol,
|
|
123
|
+
order=order,
|
|
124
|
+
global_ordinal=global_ordinal,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
if not response.value:
|
|
128
|
+
break
|
|
129
|
+
|
|
130
|
+
for item in response.value:
|
|
131
|
+
yield item
|
|
132
|
+
|
|
133
|
+
if response.next_global_ordinal is None:
|
|
134
|
+
break
|
|
135
|
+
|
|
136
|
+
global_ordinal = response.next_global_ordinal
|
|
137
|
+
|
|
138
|
+
async def get_order_book_l3(
|
|
139
|
+
self,
|
|
140
|
+
trader: Optional[str] = None,
|
|
141
|
+
strategy_id_hash: Optional[str] = None,
|
|
142
|
+
depth: Optional[int] = None,
|
|
143
|
+
symbol: Optional[str] = None,
|
|
144
|
+
side: Optional[int] = None,
|
|
145
|
+
) -> OrderBookL3Response:
|
|
146
|
+
"""
|
|
147
|
+
Get current L3 order book.
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
trader : Optional[str]
|
|
152
|
+
The trader address, with the discriminant prefix
|
|
153
|
+
strategy_id_hash : Optional[str]
|
|
154
|
+
The strategy id hash
|
|
155
|
+
depth : Optional[int]
|
|
156
|
+
The best N bids and asks to return, where N = depth
|
|
157
|
+
symbol : Optional[str]
|
|
158
|
+
The symbol
|
|
159
|
+
side : Optional[int]
|
|
160
|
+
The side of the order. Values: 0 (Bid), 1 (Ask)
|
|
161
|
+
|
|
162
|
+
Returns
|
|
163
|
+
-------
|
|
164
|
+
OrderBookL3Response
|
|
165
|
+
L3 order book data with individual orders
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
params = {
|
|
169
|
+
"trader": trader,
|
|
170
|
+
"strategyIdHash": strategy_id_hash,
|
|
171
|
+
"depth": depth,
|
|
172
|
+
"symbol": symbol,
|
|
173
|
+
"side": side,
|
|
174
|
+
}
|
|
175
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
176
|
+
|
|
177
|
+
response = await self._http.get(
|
|
178
|
+
self._build_url(Market.GET_ORDER_BOOK_L3), params=params
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
return OrderBookL3Response.model_validate(response)
|
|
182
|
+
|
|
183
|
+
async def get_order_update_history_page(
|
|
184
|
+
self,
|
|
185
|
+
trader: Optional[str] = None,
|
|
186
|
+
strategy_id_hash: Optional[str] = None,
|
|
187
|
+
limit: Optional[int] = None,
|
|
188
|
+
global_ordinal: Optional[int] = None,
|
|
189
|
+
order: Optional[str] = None,
|
|
190
|
+
symbol: Optional[str] = None,
|
|
191
|
+
order_hash: Optional[str] = None,
|
|
192
|
+
reason: Optional[int] = None,
|
|
193
|
+
since: Optional[int] = None,
|
|
194
|
+
) -> OrderUpdateHistoryResponse:
|
|
195
|
+
"""
|
|
196
|
+
Get a single page of order updates (trades, liquidations, cancels).
|
|
197
|
+
|
|
198
|
+
Parameters
|
|
199
|
+
----------
|
|
200
|
+
trader : Optional[str]
|
|
201
|
+
The trader address, with the discriminant prefix
|
|
202
|
+
strategy_id_hash : Optional[str]
|
|
203
|
+
The strategy id hash
|
|
204
|
+
limit : Optional[int]
|
|
205
|
+
The number of rows to return
|
|
206
|
+
global_ordinal : Optional[int]
|
|
207
|
+
The global ordinal boundary used when fetching the next timeseries page
|
|
208
|
+
order : Optional[str]
|
|
209
|
+
The ordering of the results. Values: "asc", "desc"
|
|
210
|
+
symbol : Optional[str]
|
|
211
|
+
The symbol
|
|
212
|
+
order_hash : Optional[str]
|
|
213
|
+
The order hash of the order intent. Multiple order hash values can be provided
|
|
214
|
+
reason : Optional[int]
|
|
215
|
+
The reason for the creation of this row. Multiple reason values can be provided.
|
|
216
|
+
Values: 0 (Trade), 1 (Liquidation), 2 (Cancel), 3 (Order Rejection), 4 (Cancel Rejection)
|
|
217
|
+
since : Optional[int]
|
|
218
|
+
The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc'
|
|
219
|
+
|
|
220
|
+
Returns
|
|
221
|
+
-------
|
|
222
|
+
OrderUpdateHistoryResponse
|
|
223
|
+
Single page of order update history data
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
params = {
|
|
227
|
+
"trader": trader,
|
|
228
|
+
"strategyIdHash": strategy_id_hash,
|
|
229
|
+
"limit": limit,
|
|
230
|
+
"globalOrdinal": global_ordinal,
|
|
231
|
+
"order": order,
|
|
232
|
+
"symbol": symbol,
|
|
233
|
+
"orderHash": order_hash,
|
|
234
|
+
"reason": reason,
|
|
235
|
+
"since": since,
|
|
236
|
+
}
|
|
237
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
238
|
+
|
|
239
|
+
response = await self._http.get(
|
|
240
|
+
self._build_url(Market.GET_ORDER_UPDATE_HISTORY), params=params
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
return OrderUpdateHistoryResponse.model_validate(response)
|
|
244
|
+
|
|
245
|
+
async def get_order_update_history(
|
|
246
|
+
self,
|
|
247
|
+
trader: Optional[str] = None,
|
|
248
|
+
strategy_id_hash: Optional[str] = None,
|
|
249
|
+
order: Optional[str] = None,
|
|
250
|
+
symbol: Optional[str] = None,
|
|
251
|
+
order_hash: Optional[str] = None,
|
|
252
|
+
reason: Optional[int] = None,
|
|
253
|
+
since: Optional[int] = None,
|
|
254
|
+
limit: Optional[int] = 100,
|
|
255
|
+
) -> AsyncIterator[OrderUpdate]:
|
|
256
|
+
"""
|
|
257
|
+
Get all order updates (trades, liquidations, cancels).
|
|
258
|
+
|
|
259
|
+
Automatically handles pagination using global_ordinal.
|
|
260
|
+
|
|
261
|
+
Parameters
|
|
262
|
+
----------
|
|
263
|
+
trader : Optional[str]
|
|
264
|
+
The trader address, with the discriminant prefix
|
|
265
|
+
strategy_id_hash : Optional[str]
|
|
266
|
+
The strategy id hash
|
|
267
|
+
order : Optional[str]
|
|
268
|
+
The ordering of the results. Values: "asc", "desc"
|
|
269
|
+
symbol : Optional[str]
|
|
270
|
+
The symbol
|
|
271
|
+
order_hash : Optional[str]
|
|
272
|
+
The order hash of the order intent. Multiple order hash values can be provided
|
|
273
|
+
reason : Optional[int]
|
|
274
|
+
The reason for the creation of this row. Multiple reason values can be provided.
|
|
275
|
+
Values: 0 (Trade), 1 (Liquidation), 2 (Cancel), 3 (Order Rejection), 4 (Cancel Rejection)
|
|
276
|
+
since : Optional[int]
|
|
277
|
+
The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc'
|
|
278
|
+
limit : Optional[int]
|
|
279
|
+
The number of rows to return per page
|
|
280
|
+
|
|
281
|
+
Yields
|
|
282
|
+
------
|
|
283
|
+
OrderUpdate
|
|
284
|
+
Order update entries
|
|
285
|
+
"""
|
|
286
|
+
|
|
287
|
+
global_ordinal = None
|
|
288
|
+
|
|
289
|
+
while True:
|
|
290
|
+
response = await self.get_order_update_history_page(
|
|
291
|
+
trader=trader,
|
|
292
|
+
strategy_id_hash=strategy_id_hash,
|
|
293
|
+
limit=limit,
|
|
294
|
+
global_ordinal=global_ordinal,
|
|
295
|
+
order=order,
|
|
296
|
+
symbol=symbol,
|
|
297
|
+
order_hash=order_hash,
|
|
298
|
+
reason=reason,
|
|
299
|
+
since=since,
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
if not response.value:
|
|
303
|
+
break
|
|
304
|
+
|
|
305
|
+
for item in response.value:
|
|
306
|
+
yield item
|
|
307
|
+
|
|
308
|
+
if response.next_global_ordinal is None:
|
|
309
|
+
break
|
|
310
|
+
|
|
311
|
+
global_ordinal = response.next_global_ordinal
|
|
312
|
+
|
|
313
|
+
async def get_strategy_update_history_page(
|
|
314
|
+
self,
|
|
315
|
+
trader: Optional[str] = None,
|
|
316
|
+
strategy_id_hash: Optional[str] = None,
|
|
317
|
+
reason: Optional[int] = None,
|
|
318
|
+
limit: Optional[int] = None,
|
|
319
|
+
global_ordinal: Optional[int] = None,
|
|
320
|
+
order: Optional[str] = None,
|
|
321
|
+
) -> StrategyUpdateHistoryResponse:
|
|
322
|
+
"""
|
|
323
|
+
Get a single page of strategy updates over time.
|
|
324
|
+
|
|
325
|
+
Parameters
|
|
326
|
+
----------
|
|
327
|
+
trader : Optional[str]
|
|
328
|
+
The trader address, with the discriminant prefix
|
|
329
|
+
strategy_id_hash : Optional[str]
|
|
330
|
+
The strategy id hash
|
|
331
|
+
reason : Optional[int]
|
|
332
|
+
The type of strategy update. Multiple strategy update values can be provided.
|
|
333
|
+
Values: 0 (Deposit), 1 (Withdraw), 2 (WithdrawIntent), 3 (FundingPayment),
|
|
334
|
+
4 (RealizedPnl), 5 (Liquidation), 6 (ADL), 7 (Withdraw Rejection)
|
|
335
|
+
limit : Optional[int]
|
|
336
|
+
The number of rows to return
|
|
337
|
+
global_ordinal : Optional[int]
|
|
338
|
+
The global ordinal boundary used when fetching the next timeseries page
|
|
339
|
+
order : Optional[str]
|
|
340
|
+
The ordering of the results. Values: "asc", "desc"
|
|
341
|
+
|
|
342
|
+
Returns
|
|
343
|
+
-------
|
|
344
|
+
StrategyUpdateHistoryResponse
|
|
345
|
+
Single page of strategy update history data
|
|
346
|
+
"""
|
|
347
|
+
|
|
348
|
+
params = {
|
|
349
|
+
"trader": trader,
|
|
350
|
+
"strategyIdHash": strategy_id_hash,
|
|
351
|
+
"reason": reason,
|
|
352
|
+
"limit": limit,
|
|
353
|
+
"globalOrdinal": global_ordinal,
|
|
354
|
+
"order": order,
|
|
355
|
+
}
|
|
356
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
357
|
+
|
|
358
|
+
response = await self._http.get(
|
|
359
|
+
self._build_url(Market.GET_STRATEGY_UPDATE_HISTORY), params=params
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
return StrategyUpdateHistoryResponse.model_validate(response)
|
|
363
|
+
|
|
364
|
+
async def get_strategy_update_history(
|
|
365
|
+
self,
|
|
366
|
+
trader: Optional[str] = None,
|
|
367
|
+
strategy_id_hash: Optional[str] = None,
|
|
368
|
+
reason: Optional[int] = None,
|
|
369
|
+
order: Optional[str] = None,
|
|
370
|
+
limit: Optional[int] = 100,
|
|
371
|
+
) -> AsyncIterator[StrategyUpdate]:
|
|
372
|
+
"""
|
|
373
|
+
Get all strategy updates over time.
|
|
374
|
+
|
|
375
|
+
Automatically handles pagination using global_ordinal.
|
|
376
|
+
|
|
377
|
+
Parameters
|
|
378
|
+
----------
|
|
379
|
+
trader : Optional[str]
|
|
380
|
+
The trader address, with the discriminant prefix
|
|
381
|
+
strategy_id_hash : Optional[str]
|
|
382
|
+
The strategy id hash
|
|
383
|
+
reason : Optional[int]
|
|
384
|
+
The type of strategy update. Multiple strategy update values can be provided.
|
|
385
|
+
Values: 0 (Deposit), 1 (Withdraw), 2 (WithdrawIntent), 3 (FundingPayment),
|
|
386
|
+
4 (RealizedPnl), 5 (Liquidation), 6 (ADL), 7 (Withdraw Rejection)
|
|
387
|
+
order : Optional[str]
|
|
388
|
+
The ordering of the results. Values: "asc", "desc"
|
|
389
|
+
limit : Optional[int]
|
|
390
|
+
The number of rows to return per page
|
|
391
|
+
|
|
392
|
+
Yields
|
|
393
|
+
------
|
|
394
|
+
StrategyUpdate
|
|
395
|
+
Strategy update entries
|
|
396
|
+
"""
|
|
397
|
+
|
|
398
|
+
global_ordinal = None
|
|
399
|
+
|
|
400
|
+
while True:
|
|
401
|
+
response = await self.get_strategy_update_history_page(
|
|
402
|
+
trader=trader,
|
|
403
|
+
strategy_id_hash=strategy_id_hash,
|
|
404
|
+
reason=reason,
|
|
405
|
+
limit=limit,
|
|
406
|
+
global_ordinal=global_ordinal,
|
|
407
|
+
order=order,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
if not response.value:
|
|
411
|
+
break
|
|
412
|
+
|
|
413
|
+
for item in response.value:
|
|
414
|
+
yield item
|
|
415
|
+
|
|
416
|
+
if response.next_global_ordinal is None:
|
|
417
|
+
break
|
|
418
|
+
|
|
419
|
+
global_ordinal = response.next_global_ordinal
|
|
420
|
+
|
|
421
|
+
async def get_tickers(
|
|
422
|
+
self,
|
|
423
|
+
symbol: Optional[str] = None,
|
|
424
|
+
market_kind: Optional[int] = None,
|
|
425
|
+
) -> TickersResponse:
|
|
426
|
+
"""
|
|
427
|
+
Get convenient market tickers data.
|
|
428
|
+
|
|
429
|
+
Includes funding rate and open interest data, price related data,
|
|
430
|
+
and trading volume in the last 24 hours.
|
|
431
|
+
|
|
432
|
+
Parameters
|
|
433
|
+
----------
|
|
434
|
+
symbol : Optional[str]
|
|
435
|
+
The symbol
|
|
436
|
+
market_kind : Optional[int]
|
|
437
|
+
The type of markets to return data for. Values: 0 (SingleNamePerpetual),
|
|
438
|
+
2 (IndexFundPerpetual), 4 (FixedExpiryFuture).
|
|
439
|
+
|
|
440
|
+
Returns
|
|
441
|
+
-------
|
|
442
|
+
TickersResponse
|
|
443
|
+
Market ticker data for requested symbols and market kinds
|
|
444
|
+
"""
|
|
445
|
+
|
|
446
|
+
params = {
|
|
447
|
+
"symbol": symbol,
|
|
448
|
+
"marketKind": market_kind,
|
|
449
|
+
}
|
|
450
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
451
|
+
|
|
452
|
+
response = await self._http.get(
|
|
453
|
+
self._build_url(Market.GET_TICKERS), params=params
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
return TickersResponse.model_validate(response)
|
|
457
|
+
|
|
458
|
+
async def get_trader_update_history_page(
|
|
459
|
+
self,
|
|
460
|
+
trader: Optional[str] = None,
|
|
461
|
+
reason: Optional[int] = None,
|
|
462
|
+
limit: Optional[int] = None,
|
|
463
|
+
global_ordinal: Optional[int] = None,
|
|
464
|
+
order: Optional[str] = None,
|
|
465
|
+
) -> TraderUpdateHistoryResponse:
|
|
466
|
+
"""
|
|
467
|
+
Get a single page of trader DDX balance and profile updates over time.
|
|
468
|
+
|
|
469
|
+
Parameters
|
|
470
|
+
----------
|
|
471
|
+
trader : Optional[str]
|
|
472
|
+
The trader address, with the discriminant prefix
|
|
473
|
+
reason : Optional[int]
|
|
474
|
+
The type of trader update. Multiple trader update values can be provided.
|
|
475
|
+
Values: 0 (Deposit), 1 (WithdrawDDX), 2 (WithdrawDDXIntent),
|
|
476
|
+
3 (TradeMiningReward), 4 (ProfileUpdate), 5 (FeeDistribution),
|
|
477
|
+
6 (Admission), 7 (Denial), 8 (Fee),
|
|
478
|
+
9 (WithdrawDDXRejection)
|
|
479
|
+
limit : Optional[int]
|
|
480
|
+
The number of rows to return
|
|
481
|
+
global_ordinal : Optional[int]
|
|
482
|
+
The global ordinal boundary used when fetching the next timeseries page
|
|
483
|
+
order : Optional[str]
|
|
484
|
+
The ordering of the results. Values: "asc", "desc"
|
|
485
|
+
|
|
486
|
+
Returns
|
|
487
|
+
-------
|
|
488
|
+
TraderUpdateHistoryResponse
|
|
489
|
+
Single page of trader update history data
|
|
490
|
+
"""
|
|
491
|
+
|
|
492
|
+
params = {
|
|
493
|
+
"trader": trader,
|
|
494
|
+
"reason": reason,
|
|
495
|
+
"limit": limit,
|
|
496
|
+
"globalOrdinal": global_ordinal,
|
|
497
|
+
"order": order,
|
|
498
|
+
}
|
|
499
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
500
|
+
|
|
501
|
+
response = await self._http.get(
|
|
502
|
+
self._build_url(Market.GET_TRADER_UPDATE_HISTORY), params=params
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
return TraderUpdateHistoryResponse.model_validate(response)
|
|
506
|
+
|
|
507
|
+
async def get_trader_update_history(
|
|
508
|
+
self,
|
|
509
|
+
trader: Optional[str] = None,
|
|
510
|
+
reason: Optional[int] = None,
|
|
511
|
+
order: Optional[str] = None,
|
|
512
|
+
limit: Optional[int] = 100,
|
|
513
|
+
) -> AsyncIterator[TraderUpdate]:
|
|
514
|
+
"""
|
|
515
|
+
Get all trader DDX balance and profile updates over time.
|
|
516
|
+
|
|
517
|
+
Automatically handles pagination using global_ordinal.
|
|
518
|
+
|
|
519
|
+
Parameters
|
|
520
|
+
----------
|
|
521
|
+
trader : Optional[str]
|
|
522
|
+
The trader address, with the discriminant prefix
|
|
523
|
+
reason : Optional[int]
|
|
524
|
+
The type of trader update. Multiple trader update values can be provided.
|
|
525
|
+
Values: 0 (Deposit), 1 (WithdrawDDX), 2 (WithdrawDDXIntent),
|
|
526
|
+
3 (TradeMiningReward), 4 (ProfileUpdate), 5 (FeeDistribution),
|
|
527
|
+
6 (Admission), 7 (Denial), 8 (Fee),
|
|
528
|
+
9 (WithdrawDDXRejection)
|
|
529
|
+
order : Optional[str]
|
|
530
|
+
The ordering of the results. Values: "asc", "desc"
|
|
531
|
+
limit : Optional[int]
|
|
532
|
+
The number of rows to return per page
|
|
533
|
+
|
|
534
|
+
Yields
|
|
535
|
+
------
|
|
536
|
+
TraderUpdate
|
|
537
|
+
Trader update history entries
|
|
538
|
+
"""
|
|
539
|
+
|
|
540
|
+
global_ordinal = None
|
|
541
|
+
|
|
542
|
+
while True:
|
|
543
|
+
response = await self.get_trader_update_history_page(
|
|
544
|
+
trader=trader,
|
|
545
|
+
reason=reason,
|
|
546
|
+
limit=limit,
|
|
547
|
+
global_ordinal=global_ordinal,
|
|
548
|
+
order=order,
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
if not response.value:
|
|
552
|
+
break
|
|
553
|
+
|
|
554
|
+
for item in response.value:
|
|
555
|
+
yield item
|
|
556
|
+
|
|
557
|
+
if response.next_global_ordinal is None:
|
|
558
|
+
break
|
|
559
|
+
|
|
560
|
+
global_ordinal = response.next_global_ordinal
|
|
561
|
+
|
|
562
|
+
async def get_balance_aggregation(
|
|
563
|
+
self,
|
|
564
|
+
trader: Optional[str] = None,
|
|
565
|
+
strategy_id: Optional[str] = None,
|
|
566
|
+
limit: Optional[int] = None,
|
|
567
|
+
aggregation_period: Optional[str] = None,
|
|
568
|
+
lookback_count: Optional[int] = None,
|
|
569
|
+
) -> BalanceAggregationResponse:
|
|
570
|
+
"""
|
|
571
|
+
Get the change of trader's balance for a specific strategy over a specific time period.
|
|
572
|
+
|
|
573
|
+
Returns the change of trader's balance for a specific strategy over a specific
|
|
574
|
+
time period, looking back from the present.
|
|
575
|
+
|
|
576
|
+
Parameters
|
|
577
|
+
----------
|
|
578
|
+
trader : Optional[str]
|
|
579
|
+
The trader address, with the discriminant prefix
|
|
580
|
+
strategy_id : Optional[str]
|
|
581
|
+
The strategy ID
|
|
582
|
+
limit : Optional[int]
|
|
583
|
+
The number of rows to return
|
|
584
|
+
aggregation_period : Optional[str]
|
|
585
|
+
The period for the aggregation. Values: "week", "day", "hour", "minute"
|
|
586
|
+
lookback_count : Optional[int]
|
|
587
|
+
The number of periods to look back from present
|
|
588
|
+
|
|
589
|
+
Returns
|
|
590
|
+
-------
|
|
591
|
+
BalanceAggregationResponse
|
|
592
|
+
Balance aggregation data showing trader balance changes over time
|
|
593
|
+
"""
|
|
594
|
+
|
|
595
|
+
params = {
|
|
596
|
+
"trader": trader,
|
|
597
|
+
"strategyId": strategy_id,
|
|
598
|
+
"limit": limit,
|
|
599
|
+
"aggregationPeriod": aggregation_period,
|
|
600
|
+
"lookbackCount": lookback_count,
|
|
601
|
+
}
|
|
602
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
603
|
+
|
|
604
|
+
response = await self._http.get(
|
|
605
|
+
self._build_url(Market.GET_BALANCE_AGGREGATION), params=params
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
return BalanceAggregationResponse.model_validate(response)
|
|
609
|
+
|
|
610
|
+
async def get_fees_aggregation_page(
|
|
611
|
+
self,
|
|
612
|
+
group: str,
|
|
613
|
+
symbol: Optional[str] = None,
|
|
614
|
+
fee_symbol: Optional[str] = None,
|
|
615
|
+
aggregation_period: Optional[str] = None,
|
|
616
|
+
lookback_count: Optional[int] = None,
|
|
617
|
+
lookback_timestamp: Optional[int] = None,
|
|
618
|
+
) -> FeesAggregationResponse:
|
|
619
|
+
"""
|
|
620
|
+
Get a single page of fees aggregation data.
|
|
621
|
+
|
|
622
|
+
Returns fees per time period looking back from the present.
|
|
623
|
+
|
|
624
|
+
Parameters
|
|
625
|
+
----------
|
|
626
|
+
group : str
|
|
627
|
+
The grouping for the aggregation. Values: "symbol", "feeSymbol"
|
|
628
|
+
symbol : Optional[str]
|
|
629
|
+
The symbol
|
|
630
|
+
fee_symbol : Optional[str]
|
|
631
|
+
The fee symbol. Values: "USDC", "DDX"
|
|
632
|
+
aggregation_period : Optional[str]
|
|
633
|
+
The period for the aggregation. Values: "week", "day", "hour", "minute"
|
|
634
|
+
lookback_count : Optional[int]
|
|
635
|
+
The number of periods to look back from present
|
|
636
|
+
lookback_timestamp : Optional[int]
|
|
637
|
+
The timestamp of the when to begin the lookback from. Each lookback query
|
|
638
|
+
will return nextLookbackTimestamp in the response, which can be passed as
|
|
639
|
+
a query parameter here to get the next page of results
|
|
640
|
+
|
|
641
|
+
Returns
|
|
642
|
+
-------
|
|
643
|
+
FeesAggregationResponse
|
|
644
|
+
Single page of fees aggregation data
|
|
645
|
+
"""
|
|
646
|
+
|
|
647
|
+
params = {
|
|
648
|
+
"group": group,
|
|
649
|
+
"symbol": symbol,
|
|
650
|
+
"feeSymbol": fee_symbol,
|
|
651
|
+
"aggregationPeriod": aggregation_period,
|
|
652
|
+
"lookbackCount": lookback_count,
|
|
653
|
+
"lookbackTimestamp": lookback_timestamp,
|
|
654
|
+
}
|
|
655
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
656
|
+
|
|
657
|
+
response = await self._http.get(
|
|
658
|
+
self._build_url(Market.GET_FEES_AGGREGATION), params=params
|
|
659
|
+
)
|
|
660
|
+
|
|
661
|
+
return FeesAggregationResponse.model_validate(response)
|
|
662
|
+
|
|
663
|
+
async def get_fees_aggregation(
|
|
664
|
+
self,
|
|
665
|
+
group: str,
|
|
666
|
+
symbol: Optional[str] = None,
|
|
667
|
+
fee_symbol: Optional[str] = None,
|
|
668
|
+
aggregation_period: Optional[str] = None,
|
|
669
|
+
lookback_count: Optional[int] = None,
|
|
670
|
+
) -> AsyncIterator[FeesAggregation]:
|
|
671
|
+
"""
|
|
672
|
+
Get all fees aggregation data.
|
|
673
|
+
|
|
674
|
+
Automatically handles pagination using lookback_timestamp.
|
|
675
|
+
|
|
676
|
+
Parameters
|
|
677
|
+
----------
|
|
678
|
+
group : str
|
|
679
|
+
The grouping for the aggregation. Values: "symbol", "feeSymbol"
|
|
680
|
+
symbol : Optional[str]
|
|
681
|
+
The symbol
|
|
682
|
+
fee_symbol : Optional[str]
|
|
683
|
+
The fee symbol. Values: "USDC", "DDX"
|
|
684
|
+
aggregation_period : Optional[str]
|
|
685
|
+
The period for the aggregation. Values: "week", "day", "hour", "minute"
|
|
686
|
+
lookback_count : Optional[int]
|
|
687
|
+
The number of periods to look back from present
|
|
688
|
+
|
|
689
|
+
Yields
|
|
690
|
+
------
|
|
691
|
+
FeesAggregation
|
|
692
|
+
Fees aggregation entries
|
|
693
|
+
"""
|
|
694
|
+
|
|
695
|
+
lookback_timestamp = None
|
|
696
|
+
|
|
697
|
+
while True:
|
|
698
|
+
response = await self.get_fees_aggregation_page(
|
|
699
|
+
group=group,
|
|
700
|
+
symbol=symbol,
|
|
701
|
+
fee_symbol=fee_symbol,
|
|
702
|
+
aggregation_period=aggregation_period,
|
|
703
|
+
lookback_count=lookback_count,
|
|
704
|
+
lookback_timestamp=lookback_timestamp,
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
if not response.value:
|
|
708
|
+
break
|
|
709
|
+
|
|
710
|
+
for item in response.value:
|
|
711
|
+
yield item
|
|
712
|
+
|
|
713
|
+
if response.next_lookback_timestamp is None:
|
|
714
|
+
break
|
|
715
|
+
|
|
716
|
+
lookback_timestamp = response.next_lookback_timestamp
|
|
717
|
+
|
|
718
|
+
async def get_funding_rate_comparison_aggregation(
|
|
719
|
+
self,
|
|
720
|
+
symbol: Optional[str] = None,
|
|
721
|
+
) -> FundingRateComparisonResponse:
|
|
722
|
+
"""
|
|
723
|
+
Get funding rate comparison data between DerivaDEX and major exchanges.
|
|
724
|
+
|
|
725
|
+
Parameters
|
|
726
|
+
----------
|
|
727
|
+
symbol : Optional[str]
|
|
728
|
+
The symbol
|
|
729
|
+
|
|
730
|
+
Returns
|
|
731
|
+
-------
|
|
732
|
+
FundingRateComparisonResponse
|
|
733
|
+
Funding rate comparison data showing rates and arbitrage opportunities
|
|
734
|
+
between DerivaDEX and other major exchanges (Binance, Bybit, Hyperliquid)
|
|
735
|
+
"""
|
|
736
|
+
|
|
737
|
+
params = {
|
|
738
|
+
"symbol": symbol,
|
|
739
|
+
}
|
|
740
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
741
|
+
|
|
742
|
+
response = await self._http.get(
|
|
743
|
+
self._build_url(Market.GET_FUNDING_RATE_COMPARISON_AGGREGATION),
|
|
744
|
+
params=params,
|
|
745
|
+
)
|
|
746
|
+
|
|
747
|
+
return FundingRateComparisonResponse.model_validate(response)
|
|
748
|
+
|
|
749
|
+
async def get_top_traders_aggregation_page(
|
|
750
|
+
self,
|
|
751
|
+
trader: Optional[str] = None,
|
|
752
|
+
limit: Optional[int] = None,
|
|
753
|
+
cursor: Optional[int] = None,
|
|
754
|
+
top_traders_ordering: Optional[str] = None,
|
|
755
|
+
order: Optional[str] = None,
|
|
756
|
+
) -> TopTradersAggregationResponse:
|
|
757
|
+
"""
|
|
758
|
+
Get a single page of top N traders by volume.
|
|
759
|
+
|
|
760
|
+
Parameters
|
|
761
|
+
----------
|
|
762
|
+
trader : Optional[str]
|
|
763
|
+
The trader address, with the discriminant prefix
|
|
764
|
+
limit : Optional[int]
|
|
765
|
+
The number of rows to return
|
|
766
|
+
cursor : Optional[int]
|
|
767
|
+
The cursor for the beginning of the next page of top traders to fetch
|
|
768
|
+
top_traders_ordering : Optional[str]
|
|
769
|
+
The order by which to fetch top traders. Values: "volume", "pnl", "accountValue"
|
|
770
|
+
order : Optional[str]
|
|
771
|
+
The ordering of the results. Values: "asc", "desc"
|
|
772
|
+
|
|
773
|
+
Returns
|
|
774
|
+
-------
|
|
775
|
+
TopTradersAggregationResponse
|
|
776
|
+
Single page of top traders aggregation data
|
|
777
|
+
"""
|
|
778
|
+
|
|
779
|
+
params = {
|
|
780
|
+
"trader": trader,
|
|
781
|
+
"limit": limit,
|
|
782
|
+
"cursor": cursor,
|
|
783
|
+
"topTradersOrdering": top_traders_ordering,
|
|
784
|
+
"order": order,
|
|
785
|
+
}
|
|
786
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
787
|
+
|
|
788
|
+
response = await self._http.get(
|
|
789
|
+
self._build_url(Market.GET_TOP_TRADERS_AGGREGATION), params=params
|
|
790
|
+
)
|
|
791
|
+
|
|
792
|
+
return TopTradersAggregationResponse.model_validate(response)
|
|
793
|
+
|
|
794
|
+
async def get_top_traders_aggregation(
|
|
795
|
+
self,
|
|
796
|
+
trader: Optional[str] = None,
|
|
797
|
+
top_traders_ordering: Optional[str] = None,
|
|
798
|
+
order: Optional[str] = None,
|
|
799
|
+
limit: Optional[int] = 100,
|
|
800
|
+
) -> AsyncIterator[TopTrader]:
|
|
801
|
+
"""
|
|
802
|
+
Get all top traders data.
|
|
803
|
+
|
|
804
|
+
Automatically handles pagination using cursor.
|
|
805
|
+
|
|
806
|
+
Parameters
|
|
807
|
+
----------
|
|
808
|
+
trader : Optional[str]
|
|
809
|
+
The trader address, with the discriminant prefix
|
|
810
|
+
top_traders_ordering : Optional[str]
|
|
811
|
+
The order by which to fetch top traders. Values: "volume", "pnl", "accountValue"
|
|
812
|
+
order : Optional[str]
|
|
813
|
+
The ordering of the results. Values: "asc", "desc"
|
|
814
|
+
limit : Optional[int]
|
|
815
|
+
The number of rows to return per page
|
|
816
|
+
|
|
817
|
+
Yields
|
|
818
|
+
------
|
|
819
|
+
TopTrader
|
|
820
|
+
Top trader entries
|
|
821
|
+
"""
|
|
822
|
+
|
|
823
|
+
cursor = None
|
|
824
|
+
|
|
825
|
+
while True:
|
|
826
|
+
response = await self.get_top_traders_aggregation_page(
|
|
827
|
+
trader=trader,
|
|
828
|
+
limit=limit,
|
|
829
|
+
cursor=cursor,
|
|
830
|
+
top_traders_ordering=top_traders_ordering,
|
|
831
|
+
order=order,
|
|
832
|
+
)
|
|
833
|
+
|
|
834
|
+
if not response.value:
|
|
835
|
+
break
|
|
836
|
+
|
|
837
|
+
for item in response.value:
|
|
838
|
+
yield item
|
|
839
|
+
|
|
840
|
+
if response.next_cursor is None:
|
|
841
|
+
break
|
|
842
|
+
|
|
843
|
+
cursor = response.next_cursor
|
|
844
|
+
|
|
845
|
+
async def get_volume_aggregation_page(
|
|
846
|
+
self,
|
|
847
|
+
group: Optional[str] = None,
|
|
848
|
+
symbol: Optional[str] = None,
|
|
849
|
+
aggregation_period: Optional[str] = None,
|
|
850
|
+
lookback_count: Optional[int] = None,
|
|
851
|
+
lookback_timestamp: Optional[int] = None,
|
|
852
|
+
) -> VolumeAggregationResponse:
|
|
853
|
+
"""
|
|
854
|
+
Get a single page of volume aggregation data.
|
|
855
|
+
|
|
856
|
+
Returns volume per time period looking back from the present.
|
|
857
|
+
|
|
858
|
+
Parameters
|
|
859
|
+
----------
|
|
860
|
+
group : Optional[str]
|
|
861
|
+
The grouping for the aggregation. Values: "symbol"
|
|
862
|
+
symbol : Optional[str]
|
|
863
|
+
The symbol
|
|
864
|
+
aggregation_period : Optional[str]
|
|
865
|
+
The period for the aggregation. Values: "week", "day", "hour", "minute"
|
|
866
|
+
lookback_count : Optional[int]
|
|
867
|
+
The number of periods to look back from present
|
|
868
|
+
lookback_timestamp : Optional[int]
|
|
869
|
+
The timestamp of the when to begin the lookback from. Each lookback query
|
|
870
|
+
will return nextLookbackTimestamp in the response, which can be passed as
|
|
871
|
+
a query parameter here to get the next page of results
|
|
872
|
+
|
|
873
|
+
Returns
|
|
874
|
+
-------
|
|
875
|
+
VolumeAggregationResponse
|
|
876
|
+
Single page of volume aggregation data
|
|
877
|
+
"""
|
|
878
|
+
|
|
879
|
+
params = {
|
|
880
|
+
"group": group,
|
|
881
|
+
"symbol": symbol,
|
|
882
|
+
"aggregationPeriod": aggregation_period,
|
|
883
|
+
"lookbackCount": lookback_count,
|
|
884
|
+
"lookbackTimestamp": lookback_timestamp,
|
|
885
|
+
}
|
|
886
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
887
|
+
|
|
888
|
+
response = await self._http.get(
|
|
889
|
+
self._build_url(Market.GET_VOLUME_AGGREGATION), params=params
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
return VolumeAggregationResponse.model_validate(response)
|
|
893
|
+
|
|
894
|
+
async def get_volume_aggregation(
|
|
895
|
+
self,
|
|
896
|
+
group: Optional[str] = None,
|
|
897
|
+
symbol: Optional[str] = None,
|
|
898
|
+
aggregation_period: Optional[str] = None,
|
|
899
|
+
lookback_count: Optional[int] = None,
|
|
900
|
+
) -> AsyncIterator[VolumeAggregation]:
|
|
901
|
+
"""
|
|
902
|
+
Get all volume aggregation data.
|
|
903
|
+
|
|
904
|
+
Automatically handles pagination using lookback_timestamp.
|
|
905
|
+
|
|
906
|
+
Parameters
|
|
907
|
+
----------
|
|
908
|
+
group : Optional[str]
|
|
909
|
+
The grouping for the aggregation. Values: "symbol"
|
|
910
|
+
symbol : Optional[str]
|
|
911
|
+
The symbol
|
|
912
|
+
aggregation_period : Optional[str]
|
|
913
|
+
The period for the aggregation. Values: "week", "day", "hour", "minute"
|
|
914
|
+
lookback_count : Optional[int]
|
|
915
|
+
The number of periods to look back from present
|
|
916
|
+
|
|
917
|
+
Yields
|
|
918
|
+
------
|
|
919
|
+
VolumeAggregation
|
|
920
|
+
Volume aggregation entries
|
|
921
|
+
"""
|
|
922
|
+
|
|
923
|
+
lookback_timestamp = None
|
|
924
|
+
|
|
925
|
+
while True:
|
|
926
|
+
response = await self.get_volume_aggregation_page(
|
|
927
|
+
group=group,
|
|
928
|
+
symbol=symbol,
|
|
929
|
+
aggregation_period=aggregation_period,
|
|
930
|
+
lookback_count=lookback_count,
|
|
931
|
+
lookback_timestamp=lookback_timestamp,
|
|
932
|
+
)
|
|
933
|
+
|
|
934
|
+
if not response.value:
|
|
935
|
+
break
|
|
936
|
+
|
|
937
|
+
for item in response.value:
|
|
938
|
+
yield item
|
|
939
|
+
|
|
940
|
+
if response.next_lookback_timestamp is None:
|
|
941
|
+
break
|
|
942
|
+
|
|
943
|
+
lookback_timestamp = response.next_lookback_timestamp
|
|
944
|
+
|
|
945
|
+
async def get_funding_rate_history_page(
|
|
946
|
+
self,
|
|
947
|
+
limit: Optional[int] = None,
|
|
948
|
+
epoch: Optional[int] = None,
|
|
949
|
+
tx_ordinal: Optional[int] = None,
|
|
950
|
+
order: Optional[str] = None,
|
|
951
|
+
symbol: Optional[str] = None,
|
|
952
|
+
since: Optional[int] = None,
|
|
953
|
+
) -> FundingRateHistoryResponse:
|
|
954
|
+
"""
|
|
955
|
+
Get a single page of funding rates over time.
|
|
956
|
+
|
|
957
|
+
Parameters
|
|
958
|
+
----------
|
|
959
|
+
limit : Optional[int]
|
|
960
|
+
The number of rows to return
|
|
961
|
+
epoch : Optional[int]
|
|
962
|
+
The epoch boundary used when fetching the next timeseries page
|
|
963
|
+
tx_ordinal : Optional[int]
|
|
964
|
+
The txOrdinal boundary used when fetching the next timeseries page.
|
|
965
|
+
Must be passed along with epoch
|
|
966
|
+
order : Optional[str]
|
|
967
|
+
The ordering of the results. Values: "asc", "desc"
|
|
968
|
+
symbol : Optional[str]
|
|
969
|
+
The symbol
|
|
970
|
+
since : Optional[int]
|
|
971
|
+
The earliest time in seconds to fetch rows for.
|
|
972
|
+
This param cannot be used together with param order = 'desc'
|
|
973
|
+
|
|
974
|
+
Returns
|
|
975
|
+
-------
|
|
976
|
+
FundingRateHistoryResponse
|
|
977
|
+
Single page of funding rate history data
|
|
978
|
+
"""
|
|
979
|
+
|
|
980
|
+
params = {
|
|
981
|
+
"limit": limit,
|
|
982
|
+
"epoch": epoch,
|
|
983
|
+
"txOrdinal": tx_ordinal,
|
|
984
|
+
"order": order,
|
|
985
|
+
"symbol": symbol,
|
|
986
|
+
"since": since,
|
|
987
|
+
}
|
|
988
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
989
|
+
|
|
990
|
+
response = await self._http.get(
|
|
991
|
+
self._build_url(Market.GET_FUNDING_RATE_HISTORY), params=params
|
|
992
|
+
)
|
|
993
|
+
|
|
994
|
+
return FundingRateHistoryResponse.model_validate(response)
|
|
995
|
+
|
|
996
|
+
async def get_funding_rate_history(
|
|
997
|
+
self,
|
|
998
|
+
order: Optional[str] = None,
|
|
999
|
+
symbol: Optional[str] = None,
|
|
1000
|
+
since: Optional[int] = None,
|
|
1001
|
+
limit: Optional[int] = 100,
|
|
1002
|
+
) -> AsyncIterator[FundingRateHistory]:
|
|
1003
|
+
"""
|
|
1004
|
+
Get all funding rate history data.
|
|
1005
|
+
|
|
1006
|
+
Automatically handles pagination using epoch and tx_ordinal.
|
|
1007
|
+
|
|
1008
|
+
Parameters
|
|
1009
|
+
----------
|
|
1010
|
+
order : Optional[str]
|
|
1011
|
+
The ordering of the results. Values: "asc", "desc"
|
|
1012
|
+
symbol : Optional[str]
|
|
1013
|
+
The symbol
|
|
1014
|
+
since : Optional[int]
|
|
1015
|
+
The earliest time in seconds to fetch rows for.
|
|
1016
|
+
This param cannot be used together with param order = 'desc'
|
|
1017
|
+
limit : Optional[int]
|
|
1018
|
+
The number of rows to return per page
|
|
1019
|
+
|
|
1020
|
+
Yields
|
|
1021
|
+
------
|
|
1022
|
+
FundingRateHistory
|
|
1023
|
+
Funding rate history entries
|
|
1024
|
+
"""
|
|
1025
|
+
|
|
1026
|
+
epoch = None
|
|
1027
|
+
tx_ordinal = None
|
|
1028
|
+
|
|
1029
|
+
while True:
|
|
1030
|
+
response = await self.get_funding_rate_history_page(
|
|
1031
|
+
limit=limit,
|
|
1032
|
+
epoch=epoch,
|
|
1033
|
+
tx_ordinal=tx_ordinal,
|
|
1034
|
+
order=order,
|
|
1035
|
+
symbol=symbol,
|
|
1036
|
+
since=since,
|
|
1037
|
+
)
|
|
1038
|
+
|
|
1039
|
+
if not response.value:
|
|
1040
|
+
break
|
|
1041
|
+
|
|
1042
|
+
for item in response.value:
|
|
1043
|
+
yield item
|
|
1044
|
+
|
|
1045
|
+
if response.next_epoch is None:
|
|
1046
|
+
break
|
|
1047
|
+
|
|
1048
|
+
epoch = response.next_epoch
|
|
1049
|
+
tx_ordinal = response.next_tx_ordinal
|
|
1050
|
+
|
|
1051
|
+
async def get_open_interest_history(
|
|
1052
|
+
self,
|
|
1053
|
+
limit: Optional[int] = None,
|
|
1054
|
+
order: Optional[str] = None,
|
|
1055
|
+
symbol: Optional[str] = None,
|
|
1056
|
+
interval: Optional[str] = None,
|
|
1057
|
+
since: Optional[int] = None,
|
|
1058
|
+
) -> OpenInterestHistoryResponse:
|
|
1059
|
+
"""
|
|
1060
|
+
Get open interest over time.
|
|
1061
|
+
|
|
1062
|
+
Parameters
|
|
1063
|
+
----------
|
|
1064
|
+
limit : Optional[int]
|
|
1065
|
+
The number of rows to return
|
|
1066
|
+
order : Optional[str]
|
|
1067
|
+
The ordering of the results. Values: "asc", "desc"
|
|
1068
|
+
symbol : Optional[str]
|
|
1069
|
+
The symbol
|
|
1070
|
+
interval : Optional[str]
|
|
1071
|
+
The interval for open interest history. Values: "5m", "1h", "1d"
|
|
1072
|
+
since : Optional[int]
|
|
1073
|
+
The earliest time in seconds to fetch rows for. This param cannot be
|
|
1074
|
+
used together with param order = 'desc'
|
|
1075
|
+
|
|
1076
|
+
Returns
|
|
1077
|
+
-------
|
|
1078
|
+
OpenInterestHistoryResponse
|
|
1079
|
+
Open interest history data
|
|
1080
|
+
"""
|
|
1081
|
+
|
|
1082
|
+
params = {
|
|
1083
|
+
"limit": limit,
|
|
1084
|
+
"order": order,
|
|
1085
|
+
"symbol": symbol,
|
|
1086
|
+
"interval": interval,
|
|
1087
|
+
"since": since,
|
|
1088
|
+
}
|
|
1089
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
1090
|
+
|
|
1091
|
+
response = await self._http.get(
|
|
1092
|
+
self._build_url(Market.GET_OPEN_INTEREST_HISTORY), params=params
|
|
1093
|
+
)
|
|
1094
|
+
|
|
1095
|
+
return OpenInterestHistoryResponse.model_validate(response)
|
|
1096
|
+
|
|
1097
|
+
async def get_order_book_l2(
|
|
1098
|
+
self,
|
|
1099
|
+
symbol: Optional[str] = None,
|
|
1100
|
+
depth: Optional[int] = None,
|
|
1101
|
+
side: Optional[int] = None,
|
|
1102
|
+
price_aggregation: Optional[float] = None,
|
|
1103
|
+
) -> Dict[str, OrderBook]:
|
|
1104
|
+
"""
|
|
1105
|
+
Get current L2 aggregated order book.
|
|
1106
|
+
|
|
1107
|
+
Parameters
|
|
1108
|
+
----------
|
|
1109
|
+
symbol : Optional[str]
|
|
1110
|
+
The symbol
|
|
1111
|
+
depth : Optional[int]
|
|
1112
|
+
The best N bids and asks to return, where N = depth
|
|
1113
|
+
side : Optional[int]
|
|
1114
|
+
The side of the order. Values: 0 (Bid), 1 (Ask)
|
|
1115
|
+
price_aggregation : Optional[float]
|
|
1116
|
+
The price aggregation to use for the L2 orderbook.
|
|
1117
|
+
Valid values for each symbol include: ETHP: 0.1, 1, 10; BTCP: 1, 10, 100
|
|
1118
|
+
|
|
1119
|
+
Returns
|
|
1120
|
+
-------
|
|
1121
|
+
Dict[str, OrderBook]
|
|
1122
|
+
Dictionary mapping symbols to their respective order books
|
|
1123
|
+
"""
|
|
1124
|
+
|
|
1125
|
+
params = {
|
|
1126
|
+
"symbol": symbol,
|
|
1127
|
+
"depth": depth,
|
|
1128
|
+
"side": side,
|
|
1129
|
+
"priceAggregation": price_aggregation,
|
|
1130
|
+
}
|
|
1131
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
1132
|
+
|
|
1133
|
+
response = await self._http.get(
|
|
1134
|
+
self._build_url(Market.GET_ORDER_BOOK_L2), params=params
|
|
1135
|
+
)
|
|
1136
|
+
|
|
1137
|
+
order_book_response = OrderBookL2Response.model_validate(response)
|
|
1138
|
+
|
|
1139
|
+
return OrderBook.from_response(order_book_response, symbol)
|
|
1140
|
+
|
|
1141
|
+
async def get_price_checkpoint_history_page(
|
|
1142
|
+
self,
|
|
1143
|
+
limit: Optional[int] = None,
|
|
1144
|
+
epoch: Optional[int] = None,
|
|
1145
|
+
tx_ordinal: Optional[int] = None,
|
|
1146
|
+
order: Optional[str] = None,
|
|
1147
|
+
symbol: Optional[str] = None,
|
|
1148
|
+
price_hash: Optional[str] = None,
|
|
1149
|
+
) -> PriceCheckpointHistoryResponse:
|
|
1150
|
+
"""
|
|
1151
|
+
Get a single page of price checkpoints over time.
|
|
1152
|
+
|
|
1153
|
+
Parameters
|
|
1154
|
+
----------
|
|
1155
|
+
limit : Optional[int]
|
|
1156
|
+
The number of rows to return
|
|
1157
|
+
epoch : Optional[int]
|
|
1158
|
+
The epoch boundary used when fetching the next timeseries page
|
|
1159
|
+
tx_ordinal : Optional[int]
|
|
1160
|
+
The txOrdinal boundary used when fetching the next timeseries page.
|
|
1161
|
+
Must be passed along with epoch
|
|
1162
|
+
order : Optional[str]
|
|
1163
|
+
The ordering of the results. Values: "asc", "desc"
|
|
1164
|
+
symbol : Optional[str]
|
|
1165
|
+
The symbol
|
|
1166
|
+
price_hash : Optional[str]
|
|
1167
|
+
The index price hash of the mark price. Multiple price hash values can be provided
|
|
1168
|
+
|
|
1169
|
+
Returns
|
|
1170
|
+
-------
|
|
1171
|
+
PriceCheckpointHistoryResponse
|
|
1172
|
+
Single page of price checkpoint history data
|
|
1173
|
+
"""
|
|
1174
|
+
|
|
1175
|
+
params = {
|
|
1176
|
+
"limit": limit,
|
|
1177
|
+
"epoch": epoch,
|
|
1178
|
+
"txOrdinal": tx_ordinal,
|
|
1179
|
+
"order": order,
|
|
1180
|
+
"symbol": symbol,
|
|
1181
|
+
"priceHash": price_hash,
|
|
1182
|
+
}
|
|
1183
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
1184
|
+
|
|
1185
|
+
response = await self._http.get(
|
|
1186
|
+
self._build_url(Market.GET_PRICE_CHECKPOINT_HISTORY), params=params
|
|
1187
|
+
)
|
|
1188
|
+
|
|
1189
|
+
return PriceCheckpointHistoryResponse.model_validate(response)
|
|
1190
|
+
|
|
1191
|
+
async def get_price_checkpoint_history(
|
|
1192
|
+
self,
|
|
1193
|
+
order: Optional[str] = None,
|
|
1194
|
+
symbol: Optional[str] = None,
|
|
1195
|
+
price_hash: Optional[str] = None,
|
|
1196
|
+
limit: Optional[int] = 100,
|
|
1197
|
+
) -> AsyncIterator[PriceCheckpoint]:
|
|
1198
|
+
"""
|
|
1199
|
+
Get all price checkpoints over time.
|
|
1200
|
+
|
|
1201
|
+
Automatically handles pagination using epoch and tx_ordinal.
|
|
1202
|
+
|
|
1203
|
+
Parameters
|
|
1204
|
+
----------
|
|
1205
|
+
order : Optional[str]
|
|
1206
|
+
The ordering of the results. Values: "asc", "desc"
|
|
1207
|
+
symbol : Optional[str]
|
|
1208
|
+
The symbol
|
|
1209
|
+
price_hash : Optional[str]
|
|
1210
|
+
The index price hash of the mark price. Multiple price hash values can be provided
|
|
1211
|
+
limit : Optional[int]
|
|
1212
|
+
The number of rows to return per page
|
|
1213
|
+
|
|
1214
|
+
Yields
|
|
1215
|
+
------
|
|
1216
|
+
PriceCheckpoint
|
|
1217
|
+
Price checkpoint entries
|
|
1218
|
+
"""
|
|
1219
|
+
|
|
1220
|
+
epoch = None
|
|
1221
|
+
tx_ordinal = None
|
|
1222
|
+
|
|
1223
|
+
while True:
|
|
1224
|
+
response = await self.get_price_checkpoint_history_page(
|
|
1225
|
+
limit=limit,
|
|
1226
|
+
epoch=epoch,
|
|
1227
|
+
tx_ordinal=tx_ordinal,
|
|
1228
|
+
order=order,
|
|
1229
|
+
symbol=symbol,
|
|
1230
|
+
price_hash=price_hash,
|
|
1231
|
+
)
|
|
1232
|
+
|
|
1233
|
+
if not response.value:
|
|
1234
|
+
break
|
|
1235
|
+
|
|
1236
|
+
for item in response.value:
|
|
1237
|
+
yield item
|
|
1238
|
+
|
|
1239
|
+
if response.next_epoch is None:
|
|
1240
|
+
break
|
|
1241
|
+
|
|
1242
|
+
epoch = response.next_epoch
|
|
1243
|
+
tx_ordinal = response.next_tx_ordinal
|