walrasquant-lib 0.4.20__py3-none-any.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 (105) hide show
  1. walrasquant/__init__.py +7 -0
  2. walrasquant/aggregation.py +449 -0
  3. walrasquant/backends/__init__.py +5 -0
  4. walrasquant/backends/db.py +109 -0
  5. walrasquant/backends/db_memory.py +61 -0
  6. walrasquant/backends/db_postgresql.py +321 -0
  7. walrasquant/backends/db_sqlite.py +310 -0
  8. walrasquant/base/__init__.py +24 -0
  9. walrasquant/base/api_client.py +46 -0
  10. walrasquant/base/connector.py +863 -0
  11. walrasquant/base/ems.py +794 -0
  12. walrasquant/base/exchange.py +213 -0
  13. walrasquant/base/oms.py +428 -0
  14. walrasquant/base/retry.py +220 -0
  15. walrasquant/base/sms.py +545 -0
  16. walrasquant/base/ws_client.py +408 -0
  17. walrasquant/config.py +284 -0
  18. walrasquant/constants.py +413 -0
  19. walrasquant/core/__init__.py +0 -0
  20. walrasquant/core/cache.py +688 -0
  21. walrasquant/core/clock.py +59 -0
  22. walrasquant/core/connection.py +41 -0
  23. walrasquant/core/entity.py +504 -0
  24. walrasquant/core/nautilius_core.py +103 -0
  25. walrasquant/core/registry.py +41 -0
  26. walrasquant/engine.py +745 -0
  27. walrasquant/error.py +34 -0
  28. walrasquant/exchange/__init__.py +13 -0
  29. walrasquant/exchange/base_factory.py +172 -0
  30. walrasquant/exchange/binance/__init__.py +30 -0
  31. walrasquant/exchange/binance/connector.py +1093 -0
  32. walrasquant/exchange/binance/constants.py +934 -0
  33. walrasquant/exchange/binance/ems.py +140 -0
  34. walrasquant/exchange/binance/error.py +48 -0
  35. walrasquant/exchange/binance/exchange.py +144 -0
  36. walrasquant/exchange/binance/factory.py +115 -0
  37. walrasquant/exchange/binance/oms.py +1807 -0
  38. walrasquant/exchange/binance/rest_api.py +1653 -0
  39. walrasquant/exchange/binance/schema.py +1063 -0
  40. walrasquant/exchange/binance/websockets.py +389 -0
  41. walrasquant/exchange/bitget/__init__.py +28 -0
  42. walrasquant/exchange/bitget/connector.py +578 -0
  43. walrasquant/exchange/bitget/constants.py +392 -0
  44. walrasquant/exchange/bitget/ems.py +202 -0
  45. walrasquant/exchange/bitget/error.py +36 -0
  46. walrasquant/exchange/bitget/exchange.py +128 -0
  47. walrasquant/exchange/bitget/factory.py +135 -0
  48. walrasquant/exchange/bitget/oms.py +1619 -0
  49. walrasquant/exchange/bitget/rest_api.py +610 -0
  50. walrasquant/exchange/bitget/schema.py +885 -0
  51. walrasquant/exchange/bitget/websockets.py +753 -0
  52. walrasquant/exchange/bybit/__init__.py +32 -0
  53. walrasquant/exchange/bybit/connector.py +819 -0
  54. walrasquant/exchange/bybit/constants.py +479 -0
  55. walrasquant/exchange/bybit/ems.py +93 -0
  56. walrasquant/exchange/bybit/error.py +36 -0
  57. walrasquant/exchange/bybit/exchange.py +108 -0
  58. walrasquant/exchange/bybit/factory.py +128 -0
  59. walrasquant/exchange/bybit/oms.py +1195 -0
  60. walrasquant/exchange/bybit/rest_api.py +570 -0
  61. walrasquant/exchange/bybit/schema.py +867 -0
  62. walrasquant/exchange/bybit/websockets.py +307 -0
  63. walrasquant/exchange/hyperliquid/__init__.py +28 -0
  64. walrasquant/exchange/hyperliquid/connector.py +370 -0
  65. walrasquant/exchange/hyperliquid/constants.py +371 -0
  66. walrasquant/exchange/hyperliquid/ems.py +156 -0
  67. walrasquant/exchange/hyperliquid/error.py +48 -0
  68. walrasquant/exchange/hyperliquid/exchange.py +120 -0
  69. walrasquant/exchange/hyperliquid/factory.py +135 -0
  70. walrasquant/exchange/hyperliquid/oms.py +1081 -0
  71. walrasquant/exchange/hyperliquid/rest_api.py +348 -0
  72. walrasquant/exchange/hyperliquid/schema.py +583 -0
  73. walrasquant/exchange/hyperliquid/websockets.py +592 -0
  74. walrasquant/exchange/okx/__init__.py +25 -0
  75. walrasquant/exchange/okx/connector.py +931 -0
  76. walrasquant/exchange/okx/constants.py +518 -0
  77. walrasquant/exchange/okx/ems.py +144 -0
  78. walrasquant/exchange/okx/error.py +66 -0
  79. walrasquant/exchange/okx/exchange.py +102 -0
  80. walrasquant/exchange/okx/factory.py +138 -0
  81. walrasquant/exchange/okx/oms.py +1199 -0
  82. walrasquant/exchange/okx/rest_api.py +799 -0
  83. walrasquant/exchange/okx/schema.py +1449 -0
  84. walrasquant/exchange/okx/websockets.py +420 -0
  85. walrasquant/exchange/registry.py +201 -0
  86. walrasquant/execution/__init__.py +24 -0
  87. walrasquant/execution/algorithm.py +968 -0
  88. walrasquant/execution/algorithms/__init__.py +3 -0
  89. walrasquant/execution/algorithms/twap.py +392 -0
  90. walrasquant/execution/config.py +34 -0
  91. walrasquant/execution/constants.py +27 -0
  92. walrasquant/execution/schema.py +62 -0
  93. walrasquant/indicator.py +382 -0
  94. walrasquant/push.py +77 -0
  95. walrasquant/schema.py +755 -0
  96. walrasquant/strategy.py +1805 -0
  97. walrasquant/tools/__init__.py +0 -0
  98. walrasquant/tools/pm2_wrapper.py +1016 -0
  99. walrasquant/web/__init__.py +26 -0
  100. walrasquant/web/app.py +157 -0
  101. walrasquant/web/server.py +92 -0
  102. walrasquant_lib-0.4.20.dist-info/METADATA +162 -0
  103. walrasquant_lib-0.4.20.dist-info/RECORD +105 -0
  104. walrasquant_lib-0.4.20.dist-info/WHEEL +4 -0
  105. walrasquant_lib-0.4.20.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,1449 @@
1
+ import msgspec
2
+ from typing import Dict, List
3
+ from walrasquant.schema import BaseMarket
4
+ from decimal import Decimal
5
+ from msgspec import Struct
6
+
7
+ from walrasquant.schema import Balance, BookOrderData
8
+ from walrasquant.exchange.okx.constants import (
9
+ OkxInstrumentType,
10
+ OkxInstrumentFamily,
11
+ OkxOrderType,
12
+ OkxOrderSide,
13
+ OkxPositionSide,
14
+ OkxTdMode,
15
+ OkxOrderStatus,
16
+ OkxSavingsPurchaseRedemptSide,
17
+ OkxAcctLv,
18
+ OkxPositionMode,
19
+ OkxTriggerType,
20
+ OkxWsApiOp,
21
+ )
22
+
23
+
24
+ class OkxWsArgMsg(msgspec.Struct):
25
+ channel: str | None = None
26
+ instType: OkxInstrumentType | None = None
27
+ instFamily: OkxInstrumentFamily | None = None
28
+ instId: str | None = None
29
+ uid: str | None = None
30
+
31
+
32
+ class OkxWsGeneralMsg(msgspec.Struct):
33
+ event: str | None = None
34
+ msg: str | None = None
35
+ code: str | None = None
36
+ connId: str | None = None
37
+ channel: str | None = None
38
+ arg: OkxWsArgMsg | None = None
39
+
40
+ @property
41
+ def is_event_msg(self) -> bool:
42
+ return self.event is not None
43
+
44
+ @property
45
+ def error_msg(self):
46
+ return f"{self.msg} code={self.code} connId={self.connId}"
47
+
48
+ @property
49
+ def login_msg(self):
50
+ return f"login success connId={self.connId}"
51
+
52
+ @property
53
+ def subscribe_msg(self):
54
+ return f"subscribed to {self.arg.channel if self.arg else None} connId={self.connId}"
55
+
56
+
57
+ class OkxWsBboTbtData(msgspec.Struct):
58
+ ts: str
59
+ seqId: int
60
+ asks: list[list[str]]
61
+ bids: list[list[str]]
62
+
63
+
64
+ class OkxWsBboTbtMsg(msgspec.Struct):
65
+ """
66
+ {
67
+ "arg": {
68
+ "channel": "bbo-tbt",
69
+ "instId": "BCH-USDT-SWAP"
70
+ },
71
+ "data": [
72
+ {
73
+ "asks": [
74
+ [
75
+ "111.06","55154","0","2"
76
+ ]
77
+ ],
78
+ "bids": [
79
+ [
80
+ "111.05","57745","0","2"
81
+ ]
82
+ ],
83
+ "ts": "1670324386802",
84
+ "seqId": 363996337
85
+ }
86
+ ]
87
+ }
88
+ """
89
+
90
+ arg: OkxWsArgMsg
91
+ data: list[OkxWsBboTbtData]
92
+
93
+
94
+ class OkxWsBook5BookDelta(msgspec.Struct, array_like=True):
95
+ price: str
96
+ size: str
97
+ feature: str
98
+ order_number: str
99
+
100
+ def parse_to_book_order_data(self) -> BookOrderData:
101
+ return BookOrderData(
102
+ price=float(self.price),
103
+ size=float(self.size),
104
+ )
105
+
106
+
107
+ class OkxWsBook5Data(msgspec.Struct):
108
+ asks: list[OkxWsBook5BookDelta]
109
+ bids: list[OkxWsBook5BookDelta]
110
+ ts: str
111
+ seqId: int
112
+ instId: str
113
+
114
+
115
+ class OkxWsBook5Msg(msgspec.Struct):
116
+ arg: OkxWsArgMsg
117
+ data: list[OkxWsBook5Data]
118
+
119
+
120
+ class OkxWsCandleMsg(msgspec.Struct):
121
+ arg: OkxWsArgMsg
122
+ data: list[list[str]]
123
+
124
+
125
+ class OkxWsIndexTickerData(msgspec.Struct):
126
+ """
127
+ "instId": "BTC-USDT",
128
+ "idxPx": "0.1",
129
+ "high24h": "0.5",
130
+ "low24h": "0.1",
131
+ "open24h": "0.1",
132
+ "sodUtc0": "0.1",
133
+ "sodUtc8": "0.1",
134
+ "ts": "1597026383085"
135
+ """
136
+
137
+ instId: str
138
+ idxPx: str
139
+ high24h: str
140
+ low24h: str
141
+ open24h: str
142
+ sodUtc0: str
143
+ sodUtc8: str
144
+ ts: str
145
+
146
+
147
+ class OkxWsIndexTickerMsg(msgspec.Struct):
148
+ arg: OkxWsArgMsg
149
+ data: list[OkxWsIndexTickerData]
150
+
151
+
152
+ class OkxWsMarkPriceData(msgspec.Struct):
153
+ instType: OkxInstrumentType
154
+ instId: str
155
+ markPx: str
156
+ ts: str
157
+
158
+
159
+ class OkxWsMarkPriceMsg(msgspec.Struct):
160
+ arg: OkxWsArgMsg
161
+ data: list[OkxWsMarkPriceData]
162
+
163
+
164
+ class OkxWsTradeData(msgspec.Struct):
165
+ instId: str
166
+ tradeId: str
167
+ px: str
168
+ sz: str
169
+ side: OkxOrderSide
170
+ ts: str
171
+ count: str
172
+
173
+
174
+ class OkxWsTradeMsg(msgspec.Struct):
175
+ arg: OkxWsArgMsg
176
+ data: list[OkxWsTradeData]
177
+
178
+
179
+ class OkxWsFundingRateData(msgspec.Struct, kw_only=True):
180
+ formulaType: str
181
+ fundingRate: str
182
+ fundingTime: str
183
+ impactValue: str
184
+ instId: str
185
+ instType: OkxInstrumentType
186
+ interestRate: str
187
+ method: str
188
+ maxFundingRate: str
189
+ minFundingRate: str
190
+ nextFundingRate: str
191
+ nextFundingTime: str
192
+ premium: str
193
+ settFundingRate: str | None = None
194
+ settState: str
195
+ ts: str
196
+
197
+
198
+ class OkxWsFundingRateMsg(msgspec.Struct):
199
+ arg: OkxWsArgMsg
200
+ data: list[OkxWsFundingRateData]
201
+
202
+
203
+ class OkxAlgoOrderData(msgspec.Struct):
204
+ attachAlgoClOrdId: str
205
+ tpOrdKind: str
206
+ tpTriggerPx: str
207
+ tpTriggerPxType: OkxTriggerType
208
+ tpOrdPx: str
209
+ slTriggerPx: str
210
+ slTriggerPxType: OkxTriggerType
211
+ slOrdPx: str
212
+ sz: str
213
+
214
+
215
+ class OkxWsOrderData(msgspec.Struct):
216
+ instType: OkxInstrumentType
217
+ instId: str
218
+ tgtCcy: str
219
+ ccy: str
220
+ ordId: str
221
+ clOrdId: str
222
+ tag: str
223
+ px: str
224
+ pxUsd: str
225
+ pxVol: str
226
+ pxType: str
227
+ sz: str
228
+ notionalUsd: str
229
+ ordType: OkxOrderType
230
+ side: OkxOrderSide
231
+ posSide: OkxPositionSide
232
+ tdMode: OkxTdMode
233
+ fillPx: str # last fill price
234
+ tradeId: str # last trade id
235
+ fillSz: str # last filled quantity
236
+ fillPnl: str # last filled profit and loss
237
+ fillTime: str # last filled time
238
+ fillFee: str # last filled fee
239
+ fillFeeCcy: str # last filled fee currency
240
+ fillPxVol: str # last filled price volume
241
+ fillPxUsd: str # last filled price in USD
242
+ fillMarkVol: str # last filled mark volume
243
+ fillFwdPx: str # last filled forward price
244
+ fillMarkPx: str # last filled mark price
245
+ execType: str # last execution type
246
+ accFillSz: str # accumulated filled quantity
247
+ fillNotionalUsd: str # accumulated filled notional in USD
248
+ avgPx: str # average price
249
+ state: OkxOrderStatus
250
+ lever: str # leverage
251
+ attachAlgoClOrdId: str # attached algo order id
252
+ tpTriggerPx: str # take profit trigger price
253
+ tpTriggerPxType: OkxTriggerType # take profit trigger price type
254
+ tpOrdPx: str # take profit order price
255
+ slTriggerPx: str # stop loss trigger price
256
+ slTriggerPxType: OkxTriggerType # stop loss trigger price type
257
+ slOrdPx: str # stop loss order price
258
+ attachAlgoOrds: List[OkxAlgoOrderData]
259
+ stpMode: str # stop loss mode
260
+ feeCcy: str # fee currency
261
+ fee: str # fee
262
+ rebateCcy: str # rebate currency
263
+ rebate: str # rebate
264
+ pnl: str
265
+ source: str
266
+ cancelSource: str
267
+ amendSource: str
268
+ category: str
269
+ isTpLimit: bool
270
+ uTime: int
271
+ cTime: int
272
+ reqId: str
273
+ amendResult: str
274
+ reduceOnly: bool
275
+ quickMgnType: str
276
+ algoClOrdId: str
277
+ algoId: str
278
+ lastPx: str # last price
279
+ code: str
280
+ msg: str
281
+
282
+
283
+ class OkxWsOrderMsg(msgspec.Struct):
284
+ arg: OkxWsArgMsg
285
+ data: List[OkxWsOrderData]
286
+
287
+
288
+ ################################################################################
289
+ # Place Order: POST /api/v5/trade/order
290
+ ################################################################################
291
+
292
+
293
+ class OkxPlaceOrderData(msgspec.Struct):
294
+ ordId: str
295
+ clOrdId: str
296
+ tag: str
297
+ ts: str # milliseconds when OKX finished order request processing
298
+ sCode: str # event code, "0" means success
299
+ sMsg: str # rejection or success message of event execution
300
+
301
+
302
+ class OkxPlaceOrderResponse(msgspec.Struct):
303
+ code: str
304
+ msg: str
305
+ data: list[OkxPlaceOrderData]
306
+ inTime: str # milliseconds when request hit REST gateway
307
+ outTime: str # milliseconds when response leaves REST gateway
308
+
309
+
310
+ ################################################################################
311
+ # Amend order: POST /api/v5/trade/amend-order
312
+ ################################################################################
313
+
314
+
315
+ class OkxAmendOrderData(msgspec.Struct):
316
+ ordId: str
317
+ clOrdId: str
318
+ ts: str
319
+ reqId: str
320
+ sCode: str
321
+ sMsg: str
322
+
323
+
324
+ class OkxAmendOrderResponse(msgspec.Struct):
325
+ code: str
326
+ msg: str
327
+ data: list[OkxAmendOrderData]
328
+ inTime: str
329
+ outTime: str
330
+
331
+
332
+ ################################################################################
333
+ # Cancel order: POST /api/v5/trade/cancel-order
334
+ ################################################################################
335
+
336
+
337
+ class OkxGeneralResponse(msgspec.Struct):
338
+ code: str
339
+ msg: str
340
+
341
+
342
+ class OkxErrorData(msgspec.Struct):
343
+ sCode: str
344
+ sMsg: str
345
+
346
+
347
+ class OkxErrorResponse(msgspec.Struct):
348
+ code: str
349
+ data: list[OkxErrorData]
350
+ msg: str
351
+
352
+
353
+ class OkxCancelOrderData(msgspec.Struct):
354
+ ordId: str
355
+ clOrdId: str
356
+ ts: str # milliseconds when OKX finished order request processing
357
+ sCode: str # event code, "0" means success
358
+ sMsg: str # rejection or success message of event execution
359
+
360
+
361
+ class OkxCancelOrderResponse(msgspec.Struct):
362
+ code: str
363
+ msg: str
364
+ data: list[OkxCancelOrderData]
365
+ inTime: str # milliseconds when request hit REST gateway
366
+ outTime: str # milliseconds when response leaves REST gateway
367
+
368
+
369
+ class OkxMarketInfo(msgspec.Struct, kw_only=True):
370
+ """
371
+ {
372
+ "alias": "",
373
+ "auctionEndTime": "",
374
+ "baseCcy": "BTC",
375
+ "category": "1",
376
+ "ctMult": "",
377
+ "ctType": "",
378
+ "ctVal": "",
379
+ "ctValCcy": "",
380
+ "expTime": "",
381
+ "instFamily": "",
382
+ "instId": "BTC-USDT",
383
+ "instType": "SPOT",
384
+ "lever": "10",
385
+ "listTime": "1611907686000",
386
+ "lotSz": "0.00000001",
387
+ "maxIcebergSz": "9999999999.0000000000000000",
388
+ "maxLmtAmt": "20000000",
389
+ "maxLmtSz": "9999999999",
390
+ "maxMktAmt": "1000000",
391
+ "maxMktSz": "1000000",
392
+ "maxStopSz": "1000000",
393
+ "maxTriggerSz": "9999999999.0000000000000000",
394
+ "maxTwapSz": "9999999999.0000000000000000",
395
+ "minSz": "0.00001",
396
+ "optType": "",
397
+ "quoteCcy": "USDT",
398
+ "ruleType": "normal",
399
+ "settleCcy": "",
400
+ "state": "live",
401
+ "stk": "",
402
+ "tickSz": "0.1",
403
+ "uly": ""
404
+ },
405
+
406
+ {
407
+ "alias": "this_week",
408
+ "auctionEndTime": "",
409
+ "baseCcy": "",
410
+ "category": "1",
411
+ "ctMult": "1",
412
+ "ctType": "linear",
413
+ "ctVal": "0.01",
414
+ "ctValCcy": "BTC",
415
+ "expTime": "1731657600000",
416
+ "instFamily": "BTC-USDT",
417
+ "instId": "BTC-USDT-241115",
418
+ "instType": "FUTURES",
419
+ "lever": "20",
420
+ "listTime": "1730448600359",
421
+ "lotSz": "0.1",
422
+ "maxIcebergSz": "1000000.0000000000000000",
423
+ "maxLmtAmt": "20000000",
424
+ "maxLmtSz": "1000000",
425
+ "maxMktAmt": "",
426
+ "maxMktSz": "3000",
427
+ "maxStopSz": "3000",
428
+ "maxTriggerSz": "1000000.0000000000000000",
429
+ "maxTwapSz": "1000000.0000000000000000",
430
+ "minSz": "0.1",
431
+ "optType": "",
432
+ "quoteCcy": "",
433
+ "ruleType": "normal",
434
+ "settleCcy": "USDT",
435
+ "state": "live",
436
+ "stk": "",
437
+ "tickSz": "0.1",
438
+ "uly": "BTC-USDT"
439
+ },
440
+
441
+ {
442
+ "alias": "",
443
+ "auctionEndTime": "",
444
+ "baseCcy": "",
445
+ "category": "1",
446
+ "ctMult": "1",
447
+ "ctType": "linear",
448
+ "ctVal": "0.01",
449
+ "ctValCcy": "BTC",
450
+ "expTime": "",
451
+ "instFamily": "BTC-USDT",
452
+ "instId": "BTC-USDT-SWAP",
453
+ "instType": "SWAP",
454
+ "lever": "100",
455
+ "listTime": "1573557408000",
456
+ "lotSz": "0.1",
457
+ "maxIcebergSz": "100000000.0000000000000000",
458
+ "maxLmtAmt": "20000000",
459
+ "maxLmtSz": "100000000",
460
+ "maxMktAmt": "",
461
+ "maxMktSz": "12000",
462
+ "maxStopSz": "12000",
463
+ "maxTriggerSz": "100000000.0000000000000000",
464
+ "maxTwapSz": "100000000.0000000000000000",
465
+ "minSz": "0.1",
466
+ "optType": "",
467
+ "quoteCcy": "",
468
+ "ruleType": "normal",
469
+ "settleCcy": "USDT",
470
+ "state": "live",
471
+ "stk": "",
472
+ "tickSz": "0.1",
473
+ "uly": "BTC-USDT"
474
+ },
475
+ """
476
+
477
+ alias: str | None = None # Alias (this_week, next_week, etc)
478
+ auctionEndTime: str | None = None # Auction end time
479
+ baseCcy: str | None = None # Base currency
480
+ category: str | None = None # Category
481
+ ctMult: str | None = None # Contract multiplier
482
+ ctType: str | None = None # Contract type (linear/inverse)
483
+ ctVal: str | None = None # Contract value
484
+ ctValCcy: str | None = None # Contract value currency
485
+ expTime: str | None = None # Expiry time
486
+ instFamily: str | None = None # Instrument family
487
+ instId: str
488
+ instIdCode: str
489
+ instType: str | None = None # Instrument type (SPOT/FUTURES/SWAP)
490
+ lever: str | None = None # Leverage
491
+ listTime: str | None = None # Listing time
492
+ lotSz: str | None = None # Lot size
493
+ maxIcebergSz: str | None = None # Maximum iceberg order size
494
+ maxLmtAmt: str | None = None # Maximum limit order amount
495
+ maxLmtSz: str | None = None # Maximum limit order size
496
+ maxMktAmt: str | None = None # Maximum market order amount
497
+ maxMktSz: str | None = None # Maximum market order size
498
+ maxStopSz: str | None = None # Maximum stop order size
499
+ maxTriggerSz: str | None = None # Maximum trigger order size
500
+ maxTwapSz: str | None = None # Maximum TWAP order size
501
+ minSz: str | None = None # Minimum order size
502
+ optType: str | None = None # Option type
503
+ quoteCcy: str | None = None # Quote currency
504
+ ruleType: str | None = None # Rule type
505
+ settleCcy: str | None = None # Settlement currency
506
+ state: str | None = None # Instrument state
507
+ stk: str | None = None # Strike price
508
+ tickSz: str | None = None # Tick size
509
+ uly: str | None = None # Underlying
510
+
511
+
512
+ class OkxMarket(BaseMarket):
513
+ """
514
+ {
515
+ "id": "BTC-USDT-SWAP",
516
+ "lowercaseId": null,
517
+ "symbol": "BTC/USDT:USDT",
518
+ "base": "BTC",
519
+ "quote": "USDT",
520
+ "settle": "USDT",
521
+ "baseId": "BTC",
522
+ "quoteId": "USDT",
523
+ "settleId": "USDT",
524
+ "type": "swap",
525
+ "spot": false,
526
+ "margin": false,
527
+ "swap": true,
528
+ "future": false,
529
+ "option": false,
530
+ "index": null,
531
+ "active": true,
532
+ "contract": true,
533
+ "linear": true,
534
+ "inverse": false,
535
+ "subType": "linear",
536
+ "taker": 0.0005,
537
+ "maker": 0.0002,
538
+ "contractSize": 0.01,
539
+ "expiry": null,
540
+ "expiryDatetime": null,
541
+ "strike": null,
542
+ "optionType": null,
543
+ "precision": {
544
+ "amount": 0.1,
545
+ "price": 0.1,
546
+ "cost": null,
547
+ "base": null,
548
+ "quote": null
549
+ },
550
+ "limits": {
551
+ "leverage": {
552
+ "min": 1.0,
553
+ "max": 100.0
554
+ },
555
+ "amount": {
556
+ "min": 0.1,
557
+ "max": null
558
+ },
559
+ "price": {
560
+ "min": null,
561
+ "max": null
562
+ },
563
+ "cost": {
564
+ "min": null,
565
+ "max": null
566
+ }
567
+ },
568
+ "marginModes": {
569
+ "cross": null,
570
+ "isolated": null
571
+ },
572
+ "created": 1573557408000,
573
+ "info": {
574
+ "alias": "",
575
+ "auctionEndTime": "",
576
+ "baseCcy": "",
577
+ "category": "1",
578
+ "ctMult": "1",
579
+ "ctType": "linear",
580
+ "ctVal": "0.01",
581
+ "ctValCcy": "BTC",
582
+ "expTime": "",
583
+ "instFamily": "BTC-USDT",
584
+ "instId": "BTC-USDT-SWAP",
585
+ "instType": "SWAP",
586
+ "lever": "100",
587
+ "listTime": "1573557408000",
588
+ "lotSz": "0.1",
589
+ "maxIcebergSz": "100000000.0000000000000000",
590
+ "maxLmtAmt": "20000000",
591
+ "maxLmtSz": "100000000",
592
+ "maxMktAmt": "",
593
+ "maxMktSz": "12000",
594
+ "maxStopSz": "12000",
595
+ "maxTriggerSz": "100000000.0000000000000000",
596
+ "maxTwapSz": "100000000.0000000000000000",
597
+ "minSz": "0.1",
598
+ "optType": "",
599
+ "quoteCcy": "",
600
+ "ruleType": "normal",
601
+ "settleCcy": "USDT",
602
+ "state": "live",
603
+ "stk": "",
604
+ "tickSz": "0.1",
605
+ "uly": "BTC-USDT"
606
+ },
607
+ "tierBased": null,
608
+ "percentage": null
609
+ },
610
+ """
611
+
612
+ info: OkxMarketInfo
613
+
614
+
615
+ class OkxPositionCloseOrderAlgo(Struct):
616
+ algoId: str | None = None
617
+ slTriggerPx: str | None = None
618
+ slTriggerPxType: str | None = None
619
+ tpTriggerPx: str | None = None
620
+ tpTriggerPxType: str | None = None
621
+ closeFraction: str | None = None
622
+
623
+
624
+ class OkxPosition(Struct, kw_only=True):
625
+ adl: str
626
+ availPos: str
627
+ avgPx: str
628
+ baseBal: str | None = None
629
+ baseBorrowed: str | None = None
630
+ baseInterest: str | None = None
631
+ bePx: str
632
+ bizRefId: str | None = None
633
+ bizRefType: str | None = None
634
+ cTime: str
635
+ ccy: str
636
+ clSpotInUseAmt: str | None = None
637
+ closeOrderAlgo: List[OkxPositionCloseOrderAlgo] = []
638
+ deltaBS: str | None = None
639
+ deltaPA: str | None = None
640
+ fee: str
641
+ fundingFee: str
642
+ gammaBS: str | None = None
643
+ gammaPA: str | None = None
644
+ idxPx: str
645
+ imr: str | None = None
646
+ instId: str
647
+ instType: str
648
+ interest: str | None = None
649
+ last: str
650
+ lever: str
651
+ liab: str | None = None
652
+ liabCcy: str | None = None
653
+ liqPenalty: str
654
+ liqPx: str
655
+ margin: str
656
+ markPx: str
657
+ maxSpotInUseAmt: str | None = None
658
+ mgnMode: str
659
+ mgnRatio: str
660
+ mmr: str
661
+ notionalUsd: str
662
+ optVal: str | None = None
663
+ pTime: str
664
+ pendingCloseOrdLiabVal: str | None = None
665
+ pnl: str
666
+ pos: str
667
+ posCcy: str | None = None
668
+ posId: str
669
+ posSide: OkxPositionSide
670
+ quoteBal: str | None = None
671
+ quoteBorrowed: str | None = None
672
+ quoteInterest: str | None = None
673
+ realizedPnl: str
674
+ spotInUseAmt: str | None = None
675
+ spotInUseCcy: str | None = None
676
+ thetaBS: str | None = None
677
+ thetaPA: str | None = None
678
+ tradeId: str
679
+ uTime: str
680
+ upl: str
681
+ uplLastPx: str
682
+ uplRatio: str
683
+ uplRatioLastPx: str
684
+ usdPx: str
685
+ vegaBS: str | None = None
686
+ vegaPA: str | None = None
687
+
688
+
689
+ class OkxAccountDetail(Struct, kw_only=True):
690
+ accAvgPx: str | None = None
691
+ availBal: str
692
+ availEq: str
693
+ borrowFroz: str | None = None
694
+ cashBal: str
695
+ ccy: str
696
+ clSpotInUseAmt: str | None = None
697
+ coinUsdPrice: str
698
+ crossLiab: str | None = None
699
+ disEq: str
700
+ eq: str
701
+ eqUsd: str
702
+ fixedBal: str
703
+ frozenBal: str
704
+ imr: str
705
+ interest: str | None = None
706
+ isoEq: str
707
+ isoLiab: str | None = None
708
+ isoUpl: str
709
+ liab: str | None = None
710
+ maxLoan: str | None = None
711
+ maxSpotInUseAmt: str | None = None
712
+ mgnRatio: str | None = None
713
+ mmr: str
714
+ notionalLever: str
715
+ openAvgPx: str | None = None
716
+ ordFrozen: str
717
+ rewardBal: str
718
+ smtSyncEq: str
719
+ spotBal: str | None = None
720
+ spotCopyTradingEq: str
721
+ spotInUseAmt: str | None = None
722
+ spotIsoBal: str
723
+ spotUpl: str | None = None
724
+ spotUplRatio: str | None = None
725
+ stgyEq: str
726
+ totalPnl: str | None = None
727
+ totalPnlRatio: str | None = None
728
+ twap: str
729
+ uTime: str
730
+ upl: str
731
+ uplLiab: str | None = None
732
+
733
+ def parse_to_balance(self) -> Balance:
734
+ """Convert OKX account detail to standard Balance object"""
735
+ return Balance(
736
+ asset=self.ccy,
737
+ free=Decimal(self.availBal),
738
+ locked=Decimal(self.frozenBal),
739
+ )
740
+
741
+
742
+ class OkxAccount(Struct):
743
+ adjEq: str | None = None
744
+ borrowFroz: str | None = None
745
+ details: List[OkxAccountDetail] | None = None
746
+ imr: str | None = None
747
+ isoEq: str | None = None
748
+ mgnRatio: str | None = None
749
+ mmr: str | None = None
750
+ notionalUsd: str | None = None
751
+ ordFroz: str | None = None
752
+ totalEq: str | None = None
753
+ uTime: str | None = None
754
+ upl: str | None = None
755
+
756
+ def parse_to_balance(self) -> list[Balance]:
757
+ return [detail.parse_to_balance() for detail in (self.details or [])]
758
+
759
+
760
+ class OkxWsPositionMsg(Struct):
761
+ arg: dict
762
+ data: List[OkxPosition]
763
+
764
+
765
+ class OkxWsAccountMsg(Struct):
766
+ arg: dict
767
+ data: List[OkxAccount]
768
+
769
+
770
+ ################################################################################
771
+ # GET /api/v5/account/balance
772
+ ################################################################################
773
+
774
+
775
+ class OkxBalanceDetail(msgspec.Struct):
776
+ availBal: str # Available balance
777
+ availEq: str # Available equity
778
+ borrowFroz: str # Potential borrowing IMR in USD
779
+ cashBal: str # Cash balance
780
+ ccy: str # Currency
781
+ crossLiab: str # Cross liabilities
782
+ disEq: str # Discount equity in USD
783
+ eq: str # Equity
784
+ eqUsd: str # Equity in USD
785
+ smtSyncEq: str # Smart sync equity
786
+ spotCopyTradingEq: str # Spot smart sync equity
787
+ fixedBal: str # Frozen balance for Dip/Peak Sniper
788
+ frozenBal: str # Frozen balance
789
+ imr: str # Cross initial margin requirement
790
+ interest: str # Accrued interest
791
+ isoEq: str # Isolated margin equity
792
+ isoLiab: str # Isolated liabilities
793
+ isoUpl: str # Isolated unrealized PnL
794
+ liab: str # Liabilities
795
+ maxLoan: str # Max loan
796
+ mgnRatio: str # Cross margin ratio
797
+ mmr: str # Cross maintenance margin requirement
798
+ notionalLever: str # Leverage
799
+ ordFrozen: str # Margin frozen for open orders
800
+ rewardBal: str # Trial fund balance
801
+ spotInUseAmt: str # Spot in use amount
802
+ clSpotInUseAmt: str # User-defined spot risk offset amount
803
+ maxSpotInUse: str # Max possible spot risk offset amount
804
+ spotIsoBal: str # Spot isolated balance
805
+ stgyEq: str # Strategy equity
806
+ twap: str # Risk indicator of auto liability repayment
807
+ uTime: str # Update time
808
+ upl: str # Unrealized PnL
809
+ uplLiab: str # Liabilities due to unrealized loss
810
+ spotBal: str # Spot balance
811
+ openAvgPx: str # Spot average cost price
812
+ accAvgPx: str # Spot accumulated cost price
813
+ spotUpl: str # Spot unrealized PnL
814
+ spotUplRatio: str # Spot unrealized PnL ratio
815
+ totalPnl: str # Spot accumulated PnL
816
+ totalPnlRatio: str # Spot accumulated PnL ratio
817
+
818
+ def parse_to_balance(self) -> Balance:
819
+ return Balance(
820
+ asset=self.ccy,
821
+ free=Decimal(self.availBal),
822
+ locked=Decimal(self.frozenBal),
823
+ )
824
+
825
+
826
+ class OkxBalanceData(msgspec.Struct):
827
+ adjEq: str # Adjusted/Effective equity in USD
828
+ borrowFroz: str # Potential borrowing IMR of account in USD
829
+ details: list[OkxBalanceDetail] # Detailed asset information
830
+ imr: str # Initial margin requirement in USD
831
+ isoEq: str # Isolated margin equity in USD
832
+ mgnRatio: str # Margin ratio in USD
833
+ mmr: str # Maintenance margin requirement in USD
834
+ notionalUsd: str # Notional value of positions in USD
835
+ ordFroz: str # Cross margin frozen for pending orders
836
+ totalEq: str # Total equity in USD
837
+ uTime: int # Update time
838
+ upl: str # Unrealized PnL in USD
839
+
840
+ def parse_to_balances(self) -> list[Balance]:
841
+ return [detail.parse_to_balance() for detail in self.details]
842
+
843
+
844
+ class OkxBalanceResponse(msgspec.Struct):
845
+ code: str # Response code
846
+ data: list[OkxBalanceData] # Balance data
847
+ msg: str # Response message
848
+
849
+
850
+ ################################################################################
851
+ # GET /api/v5/account/positions
852
+ ################################################################################
853
+
854
+
855
+ class OkxPositionResponseData(msgspec.Struct):
856
+ adl: str
857
+ availPos: str
858
+ avgPx: str
859
+ bePx: str
860
+ bizRefId: str
861
+ bizRefType: str
862
+ cTime: str
863
+ ccy: str
864
+ clSpotInUseAmt: str
865
+ closeOrderAlgo: List[OkxPositionCloseOrderAlgo]
866
+ deltaBS: str
867
+ deltaPA: str
868
+ fee: str
869
+ fundingFee: str
870
+ gammaBS: str
871
+ gammaPA: str
872
+ idxPx: str
873
+ imr: str
874
+ instId: str
875
+ instType: str
876
+ interest: str
877
+ last: str
878
+ lever: str
879
+ liab: str
880
+ liabCcy: str
881
+ liqPenalty: str
882
+ liqPx: str
883
+ margin: str
884
+ markPx: str
885
+ maxSpotInUseAmt: str
886
+ mgnMode: str
887
+ mgnRatio: str
888
+ mmr: str
889
+ notionalUsd: str
890
+ optVal: str
891
+ pendingCloseOrdLiabVal: str
892
+ pnl: str
893
+ pos: str
894
+ posCcy: str
895
+ posId: str
896
+ posSide: OkxPositionSide
897
+ realizedPnl: str
898
+ spotInUseAmt: str
899
+ spotInUseCcy: str
900
+ thetaBS: str
901
+ thetaPA: str
902
+ tradeId: str
903
+ uTime: int
904
+ upl: str
905
+ uplLastPx: str
906
+ uplRatio: str
907
+ uplRatioLastPx: str
908
+ usdPx: str
909
+ vegaBS: str
910
+ vegaPA: str
911
+
912
+
913
+ class OkxPositionResponse(msgspec.Struct):
914
+ code: str
915
+ data: List[OkxPositionResponseData]
916
+ msg: str
917
+
918
+
919
+ class OkxIndexCandlesticksResponse(msgspec.Struct):
920
+ code: str
921
+ data: list["OkxIndexCandlesticksResponseData"]
922
+ msg: str
923
+
924
+
925
+ class OkxIndexCandlesticksResponseData(msgspec.Struct, array_like=True):
926
+ ts: int
927
+ o: str
928
+ h: str
929
+ l: str # noqa: E741
930
+ c: str
931
+ confirm: str
932
+
933
+
934
+ class OkxCandlesticksResponse(msgspec.Struct):
935
+ code: str
936
+ data: list["OkxCandlesticksResponseData"]
937
+ msg: str
938
+
939
+
940
+ class OkxCandlesticksResponseData(msgspec.Struct, array_like=True):
941
+ """
942
+ [
943
+ "1597026383085",
944
+ "3.721",
945
+ "3.743",
946
+ "3.677",
947
+ "3.708",
948
+ "8422410",
949
+ "22698348.04828491",
950
+ "12698348.04828491",
951
+ "1"
952
+ ],
953
+ """
954
+
955
+ ts: int
956
+ o: str
957
+ h: str
958
+ l: str # noqa: E741
959
+ c: str
960
+ vol: str
961
+ volCcy: str
962
+ volCcyQuote: str
963
+ confirm: int
964
+
965
+
966
+ class OkxSavingsBalanceResponse(msgspec.Struct):
967
+ code: str
968
+ data: list["OkxSavingsBalanceResponseData"]
969
+ msg: str
970
+
971
+
972
+ class OkxSavingsBalanceResponseData(msgspec.Struct):
973
+ """
974
+ ccy String 币种,如 BTC
975
+ amt String 币种数量
976
+ earnings String 币种持仓收益
977
+ rate String 最新出借利率
978
+ loanAmt String 已出借数量
979
+ pendingAmt String 未出借数量
980
+ """
981
+
982
+ ccy: str
983
+ amt: str
984
+ earnings: str
985
+ rate: str
986
+ loanAmt: str
987
+ pendingAmt: str
988
+
989
+
990
+ class OkxSavingsPurchaseRedemptResponse(msgspec.Struct):
991
+ code: str
992
+ data: list["OkxSavingsPurchaseRedemptResponseData"]
993
+ msg: str
994
+
995
+
996
+ class OkxSavingsPurchaseRedemptResponseData(msgspec.Struct):
997
+ ccy: str
998
+ amt: str
999
+ side: OkxSavingsPurchaseRedemptSide
1000
+ rate: str
1001
+
1002
+
1003
+ class OkxSavingsLendingRateSummaryResponse(msgspec.Struct):
1004
+ code: str
1005
+ data: list["OkxSavingsLendingRateSummaryResponseData"]
1006
+ msg: str
1007
+
1008
+
1009
+ class OkxSavingsLendingRateSummaryResponseData(msgspec.Struct):
1010
+ """
1011
+ ccy: str
1012
+ avgAmt: str
1013
+ avgAmtUsd: str
1014
+ avgRate: str
1015
+ preRate: str
1016
+ estRate: str
1017
+ """
1018
+
1019
+ ccy: str
1020
+ avgAmt: str
1021
+ avgAmtUsd: str
1022
+ avgRate: str
1023
+ preRate: str
1024
+ estRate: str
1025
+
1026
+
1027
+ class OkxSavingsLendingRateHistoryResponse(msgspec.Struct):
1028
+ code: str
1029
+ data: list["OkxSavingsLendingRateHistoryResponseData"]
1030
+ msg: str
1031
+
1032
+
1033
+ class OkxSavingsLendingRateHistoryResponseData(msgspec.Struct):
1034
+ """
1035
+ ccy String Currency, e.g. BTC
1036
+ amt String Lending amount
1037
+ rate String Lending annual interest rate
1038
+ ts String Timestamp
1039
+ """
1040
+
1041
+ ccy: str
1042
+ amt: str
1043
+ rate: str
1044
+ ts: str
1045
+
1046
+
1047
+ class OkxAssetTransferResponse(msgspec.Struct):
1048
+ code: str
1049
+ data: list["OkxAssetTransferResponseData"]
1050
+ msg: str
1051
+
1052
+
1053
+ class OkxAssetTransferResponseData(msgspec.Struct):
1054
+ """
1055
+ transId: str
1056
+ ccy: str
1057
+ clientId: str
1058
+ from: str
1059
+ amt: str
1060
+ to: str
1061
+
1062
+ """
1063
+
1064
+ transId: str
1065
+ ccy: str
1066
+ clientId: str
1067
+ from_acct: str = msgspec.field(name="from")
1068
+ amt: str
1069
+ to: str
1070
+
1071
+
1072
+ class OkxFinanceStakingDefiRedeemResponse(msgspec.Struct):
1073
+ code: str
1074
+ data: list["OkxFinanceStakingDefiRedeemResponseData"]
1075
+ msg: str
1076
+
1077
+
1078
+ class OkxFinanceStakingDefiRedeemResponseData(msgspec.Struct):
1079
+ ordId: str
1080
+ tag: str
1081
+
1082
+
1083
+ class OkxFinanceStakingDefiPurchaseResponse(msgspec.Struct):
1084
+ code: str
1085
+ data: list["OkxFinanceStakingDefiPurchaseResponseData"]
1086
+ msg: str
1087
+
1088
+
1089
+ class OkxFinanceStakingDefiPurchaseResponseData(msgspec.Struct):
1090
+ ordId: str
1091
+ tag: str
1092
+
1093
+
1094
+ class OkxFinanceStakingDefiOffersResponse(msgspec.Struct):
1095
+ code: str
1096
+ data: list["OkxFinanceStakingDefiOffersResponseData"]
1097
+ msg: str
1098
+
1099
+
1100
+ class OkxFinanceStakingDefiOffersResponseData(msgspec.Struct):
1101
+ ccy: str
1102
+ productId: str
1103
+ protocol: str
1104
+ protocolType: str
1105
+ term: str
1106
+ apy: str
1107
+ earlyRedeem: bool
1108
+ state: str
1109
+ investData: list["OkxFinanceStakingDefiOffersInvestData"]
1110
+ earningData: list["OkxFinanceStakingDefiOffersEarningData"]
1111
+ fastRedemptionDailyLimit: str
1112
+ redeemPeriod: list[str]
1113
+
1114
+
1115
+ class OkxFinanceStakingDefiOffersInvestData(msgspec.Struct):
1116
+ bal: str
1117
+ ccy: str
1118
+ maxAmt: str
1119
+ minAmt: str
1120
+
1121
+
1122
+ class OkxFinanceStakingDefiOffersEarningData(msgspec.Struct):
1123
+ ccy: str
1124
+ earningType: str
1125
+
1126
+
1127
+ class OkxAccountConfigResponse(msgspec.Struct):
1128
+ code: str
1129
+ data: list["OkxAccountConfigResponseData"]
1130
+ msg: str
1131
+
1132
+
1133
+ class OkxAccountConfigResponseData(msgspec.Struct):
1134
+ """
1135
+ Account configuration response data from OKX API.
1136
+ """
1137
+
1138
+ uid: str # Account ID of current request
1139
+ mainUid: str # Main Account ID of current request
1140
+ acctLv: OkxAcctLv # Account mode (1: Spot, 2: Futures, 3: Multi-currency margin, 4: Portfolio margin)
1141
+ acctStpMode: str # Account self-trade prevention mode (cancel_maker, cancel_taker, cancel_both)
1142
+ posMode: OkxPositionMode # Position mode (long_short_mode, net_mode)
1143
+ autoLoan: bool # Whether to borrow coins automatically
1144
+ greeksType: (
1145
+ str # Current display type of Greeks (PA: coins, BS: Black-Scholes in dollars)
1146
+ )
1147
+ level: str # User level of current real trading volume
1148
+ levelTmp: str # Temporary experience user level
1149
+ ctIsoMode: str # Contract isolated margin trading settings (automatic, autonomy)
1150
+ mgnIsoMode: str # Margin isolated margin trading settings (auto_transfers_ccy, automatic, quick_margin)
1151
+ spotOffsetType: str # Risk offset type (1: Spot-Derivatives(USDT), 2: Spot-Derivatives(Coin), 3: Only derivatives)
1152
+ roleType: str # Role type (0: General user, 1: Leading trader, 2: Copy trader)
1153
+ traderInsts: list[str] # Leading trade instruments
1154
+ spotRoleType: str # SPOT copy trading role type (0: General user, 1: Leading trader, 2: Copy trader)
1155
+ spotTraderInsts: list[str] # Spot lead trading instruments
1156
+ opAuth: (
1157
+ str # Whether optional trading was activated (0: not activate, 1: activated)
1158
+ )
1159
+ kycLv: str # Main account KYC level (0: No verification, 1: level 1, 2: level 2, 3: level 3)
1160
+ label: str # API key note
1161
+ ip: str # IP addresses linked with current API key
1162
+ perm: str # Permission of current API key (read_only, trade, withdraw)
1163
+ liquidationGear: str # Maintenance margin ratio level of liquidation alert
1164
+ enableSpotBorrow: bool # Whether borrow is allowed in Spot mode
1165
+ spotBorrowAutoRepay: bool # Whether auto-repay is allowed in Spot mode
1166
+ type: str # Account type (0: Main account, 1: Standard sub-account, 2: Managed trading sub-account, etc.)
1167
+
1168
+
1169
+ class OkxBatchOrderResponse(msgspec.Struct):
1170
+ """
1171
+ Response structure for batch order operations.
1172
+ """
1173
+
1174
+ code: str # Response code
1175
+ msg: str # Response message
1176
+ data: list["OkxBatchOrderResponseData"] # List of order data
1177
+ inTime: str # Time when the request was received by the REST gateway
1178
+ outTime: str # Time when the response was sent from the REST gateway
1179
+
1180
+
1181
+ class OkxBatchOrderResponseData(msgspec.Struct):
1182
+ """
1183
+ Data structure for individual order in batch order response.
1184
+ """
1185
+
1186
+ ordId: str # Order ID
1187
+ clOrdId: str # Client order ID
1188
+ tag: str # Tag associated with the order
1189
+ ts: str # Timestamp when the order was processed
1190
+ sCode: str # Status code of the order processing (0 means success)
1191
+ sMsg: str # Status message of the order processing (success or error message)
1192
+
1193
+
1194
+ ################################################################################
1195
+ # Cancel Batch Orders: POST /api/v5/trade/cancel-batch-orders
1196
+ ################################################################################
1197
+
1198
+
1199
+ class OkxCancelBatchOrderResponseData(msgspec.Struct):
1200
+ """
1201
+ Data structure for individual order in batch cancel order response.
1202
+ """
1203
+
1204
+ ordId: str # Order ID
1205
+ clOrdId: str # Client order ID
1206
+ ts: str # Timestamp when the order request processing is finished
1207
+ sCode: str # Event execution result code (0 means success)
1208
+ sMsg: str # Rejection message if the request is unsuccessful
1209
+
1210
+
1211
+ class OkxCancelBatchOrderResponse(msgspec.Struct):
1212
+ """
1213
+ Response structure for POST /api/v5/trade/cancel-batch-orders.
1214
+ """
1215
+
1216
+ code: str # Response code (0 means success)
1217
+ msg: str # Error message (empty if code is 0)
1218
+ data: list[OkxCancelBatchOrderResponseData] # Array of cancellation results
1219
+ inTime: str # Timestamp at REST gateway when request is received
1220
+ outTime: str # Timestamp at REST gateway when response is sent
1221
+
1222
+
1223
+ ################################################################################
1224
+ # GET /api/v5/market/tickers
1225
+ ################################################################################
1226
+
1227
+
1228
+ class OkxTickerData(msgspec.Struct):
1229
+ """
1230
+ Ticker data structure for OKX market tickers.
1231
+ """
1232
+
1233
+ instType: str # Instrument type
1234
+ instId: str # Instrument ID
1235
+ last: str # Last traded price
1236
+ lastSz: str # Last traded size
1237
+ askPx: str # Best ask price
1238
+ askSz: str # Best ask size
1239
+ bidPx: str # Best bid price
1240
+ bidSz: str # Best bid size
1241
+ open24h: str # Open price in the past 24 hours
1242
+ high24h: str # Highest price in the past 24 hours
1243
+ low24h: str # Lowest price in the past 24 hours
1244
+ volCcy24h: str # 24h trading volume in currency
1245
+ vol24h: str # 24h trading volume in contracts
1246
+ sodUtc0: str # Open price in UTC 0
1247
+ sodUtc8: str # Open price in UTC 8
1248
+ ts: str # Ticker data generation time
1249
+
1250
+
1251
+ class OkxTickersResponse(msgspec.Struct):
1252
+ """
1253
+ Response structure for GET /api/v5/market/tickers.
1254
+ """
1255
+
1256
+ code: str # Response code
1257
+ msg: str # Response message
1258
+ data: list[OkxTickerData] # List of ticker data
1259
+
1260
+
1261
+ ################################################################################
1262
+ # GET /api/v5/trade/order
1263
+ ################################################################################
1264
+
1265
+
1266
+ class OkxLinkedAlgoOrd(msgspec.Struct):
1267
+ """Linked algorithm order details"""
1268
+
1269
+ algoId: str
1270
+
1271
+
1272
+ class OkxAttachAlgoOrd(msgspec.Struct):
1273
+ """Attached TP/SL order details"""
1274
+
1275
+ attachAlgoId: str | None = None
1276
+ attachAlgoClOrdId: str | None = None
1277
+ tpOrdKind: str | None = None
1278
+ tpTriggerPx: str | None = None
1279
+ tpTriggerPxType: str | None = None
1280
+ tpOrdPx: str | None = None
1281
+ slTriggerPx: str | None = None
1282
+ slTriggerPxType: str | None = None
1283
+ slOrdPx: str | None = None
1284
+ sz: str | None = None
1285
+ amendPxOnTriggerType: str | None = None
1286
+ failCode: str | None = None
1287
+ failReason: str | None = None
1288
+
1289
+
1290
+ class OkxOrderData(msgspec.Struct):
1291
+ """
1292
+ Order data structure for GET /api/v5/trade/order response.
1293
+ """
1294
+
1295
+ accFillSz: str # Accumulated filled quantity
1296
+ algoClOrdId: str # Client-supplied Algo ID
1297
+ algoId: str # Algo ID
1298
+ attachAlgoClOrdId: str # Client-supplied Algo ID when placing order attaching TP/SL
1299
+ attachAlgoOrds: list[
1300
+ OkxAttachAlgoOrd
1301
+ ] # TP/SL information attached when placing order
1302
+ avgPx: str # Average filled price
1303
+ cTime: str # Creation time
1304
+ cancelSource: str # Code of the cancellation source
1305
+ cancelSourceReason: str # Reason for the cancellation
1306
+ category: str # Category (normal, twap, adl, etc.)
1307
+ ccy: str # Margin currency
1308
+ clOrdId: str # Client Order ID
1309
+ fee: str # Fee
1310
+ feeCcy: str # Fee currency
1311
+ fillPx: str # Last filled price
1312
+ fillSz: str # Last filled quantity
1313
+ fillTime: str # Last filled time
1314
+ instId: str # Instrument ID
1315
+ instType: str # Instrument type
1316
+ isTpLimit: str # Whether it is TP limit order
1317
+ lever: str # Leverage
1318
+ linkedAlgoOrd: OkxLinkedAlgoOrd # Linked SL order detail
1319
+ ordId: str # Order ID
1320
+ ordType: OkxOrderType # Order type
1321
+ pnl: str # Profit and loss
1322
+ posSide: OkxPositionSide # Position side
1323
+ px: str # Price
1324
+ pxType: str # Price type
1325
+ pxUsd: str # Options price in USD
1326
+ pxVol: str # Implied volatility of the options order
1327
+ quickMgnType: str # Quick Margin type
1328
+ rebate: str # Rebate amount
1329
+ rebateCcy: str # Rebate currency
1330
+ reduceOnly: bool # Whether the order can only reduce the position size
1331
+ side: OkxOrderSide # Order side
1332
+ slOrdPx: str # Stop-loss order price
1333
+ slTriggerPx: str # Stop-loss trigger price
1334
+ slTriggerPxType: str # Stop-loss trigger price type
1335
+ source: str # Order source
1336
+ state: OkxOrderStatus # State
1337
+ stpId: str # Self trade prevention ID
1338
+ stpMode: str # Self trade prevention mode
1339
+ sz: str # Quantity to buy or sell
1340
+ tag: str # Order tag
1341
+ tdMode: str # Trade mode
1342
+ tgtCcy: str # Order quantity unit setting for sz
1343
+ tpOrdPx: str # Take-profit order price
1344
+ tpTriggerPx: str # Take-profit trigger price
1345
+ tpTriggerPxType: str # Take-profit trigger price type
1346
+ tradeId: str # Last traded ID
1347
+ tradeQuoteCcy: str # The quote currency used for trading
1348
+ uTime: str # Update time
1349
+
1350
+
1351
+ class OkxOrderResponse(msgspec.Struct):
1352
+ """
1353
+ Response structure for GET /api/v5/trade/order.
1354
+ """
1355
+
1356
+ code: str # Response code
1357
+ data: list[OkxOrderData] # Order data
1358
+ msg: str # Response message
1359
+
1360
+
1361
+ class OkxWsApiOrderResponseData(msgspec.Struct, frozen=True, kw_only=True):
1362
+ clOrdId: str
1363
+ ordId: str
1364
+ tag: str | None = None
1365
+ ts: str
1366
+ sCode: str
1367
+ sMsg: str
1368
+
1369
+
1370
+ class OkxWsApiOrderResponse(msgspec.Struct, frozen=True):
1371
+ """
1372
+ WebSocket API order response structure.
1373
+ """
1374
+
1375
+ id: str
1376
+ op: OkxWsApiOp
1377
+ data: list[OkxWsApiOrderResponseData]
1378
+ code: str
1379
+ msg: str
1380
+ inTime: str
1381
+ outTime: str
1382
+
1383
+ @property
1384
+ def is_success(self):
1385
+ return self.code == "0"
1386
+
1387
+ @property
1388
+ def error_msg(self):
1389
+ return (
1390
+ f"code={self.data[0].sCode}, msg={self.data[0].sMsg}"
1391
+ if self.data
1392
+ else "Unknown Error"
1393
+ )
1394
+
1395
+
1396
+ class OkxWsBooksData(msgspec.Struct):
1397
+ asks: list[OkxWsBook5BookDelta]
1398
+ bids: list[OkxWsBook5BookDelta]
1399
+ ts: str
1400
+ checksum: int
1401
+ prevSeqId: int
1402
+ seqId: int
1403
+
1404
+
1405
+ class OkxWsBooksMsg(msgspec.Struct):
1406
+ arg: OkxWsArgMsg
1407
+ action: str
1408
+ data: list[OkxWsBooksData]
1409
+
1410
+
1411
+ class OkxOrderBook:
1412
+ """Local order book state manager for OKX books channel (400-level incremental)."""
1413
+
1414
+ def __init__(self):
1415
+ self.bids: Dict[float, float] = {}
1416
+ self.asks: Dict[float, float] = {}
1417
+ self.seq_id: int = -1
1418
+
1419
+ def apply_snapshot(self, data: OkxWsBooksData) -> None:
1420
+ self.bids = {float(d.price): float(d.size) for d in data.bids}
1421
+ self.asks = {float(d.price): float(d.size) for d in data.asks}
1422
+ self.seq_id = data.seqId
1423
+
1424
+ def apply_update(self, data: OkxWsBooksData) -> None:
1425
+ for d in data.bids:
1426
+ price = float(d.price)
1427
+ size = float(d.size)
1428
+ if size == 0.0:
1429
+ self.bids.pop(price, None)
1430
+ else:
1431
+ self.bids[price] = size
1432
+ for d in data.asks:
1433
+ price = float(d.price)
1434
+ size = float(d.size)
1435
+ if size == 0.0:
1436
+ self.asks.pop(price, None)
1437
+ else:
1438
+ self.asks[price] = size
1439
+ self.seq_id = data.seqId
1440
+
1441
+ def get_orderbook(self) -> dict:
1442
+ from walrasquant.schema import BookOrderData
1443
+
1444
+ bids = sorted(self.bids.items(), reverse=True)
1445
+ asks = sorted(self.asks.items())
1446
+ return {
1447
+ "bids": [BookOrderData(price=p, size=s) for p, s in bids],
1448
+ "asks": [BookOrderData(price=p, size=s) for p, s in asks],
1449
+ }