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.
- walrasquant/__init__.py +7 -0
- walrasquant/aggregation.py +449 -0
- walrasquant/backends/__init__.py +5 -0
- walrasquant/backends/db.py +109 -0
- walrasquant/backends/db_memory.py +61 -0
- walrasquant/backends/db_postgresql.py +321 -0
- walrasquant/backends/db_sqlite.py +310 -0
- walrasquant/base/__init__.py +24 -0
- walrasquant/base/api_client.py +46 -0
- walrasquant/base/connector.py +863 -0
- walrasquant/base/ems.py +794 -0
- walrasquant/base/exchange.py +213 -0
- walrasquant/base/oms.py +428 -0
- walrasquant/base/retry.py +220 -0
- walrasquant/base/sms.py +545 -0
- walrasquant/base/ws_client.py +408 -0
- walrasquant/config.py +284 -0
- walrasquant/constants.py +413 -0
- walrasquant/core/__init__.py +0 -0
- walrasquant/core/cache.py +688 -0
- walrasquant/core/clock.py +59 -0
- walrasquant/core/connection.py +41 -0
- walrasquant/core/entity.py +504 -0
- walrasquant/core/nautilius_core.py +103 -0
- walrasquant/core/registry.py +41 -0
- walrasquant/engine.py +745 -0
- walrasquant/error.py +34 -0
- walrasquant/exchange/__init__.py +13 -0
- walrasquant/exchange/base_factory.py +172 -0
- walrasquant/exchange/binance/__init__.py +30 -0
- walrasquant/exchange/binance/connector.py +1093 -0
- walrasquant/exchange/binance/constants.py +934 -0
- walrasquant/exchange/binance/ems.py +140 -0
- walrasquant/exchange/binance/error.py +48 -0
- walrasquant/exchange/binance/exchange.py +144 -0
- walrasquant/exchange/binance/factory.py +115 -0
- walrasquant/exchange/binance/oms.py +1807 -0
- walrasquant/exchange/binance/rest_api.py +1653 -0
- walrasquant/exchange/binance/schema.py +1063 -0
- walrasquant/exchange/binance/websockets.py +389 -0
- walrasquant/exchange/bitget/__init__.py +28 -0
- walrasquant/exchange/bitget/connector.py +578 -0
- walrasquant/exchange/bitget/constants.py +392 -0
- walrasquant/exchange/bitget/ems.py +202 -0
- walrasquant/exchange/bitget/error.py +36 -0
- walrasquant/exchange/bitget/exchange.py +128 -0
- walrasquant/exchange/bitget/factory.py +135 -0
- walrasquant/exchange/bitget/oms.py +1619 -0
- walrasquant/exchange/bitget/rest_api.py +610 -0
- walrasquant/exchange/bitget/schema.py +885 -0
- walrasquant/exchange/bitget/websockets.py +753 -0
- walrasquant/exchange/bybit/__init__.py +32 -0
- walrasquant/exchange/bybit/connector.py +819 -0
- walrasquant/exchange/bybit/constants.py +479 -0
- walrasquant/exchange/bybit/ems.py +93 -0
- walrasquant/exchange/bybit/error.py +36 -0
- walrasquant/exchange/bybit/exchange.py +108 -0
- walrasquant/exchange/bybit/factory.py +128 -0
- walrasquant/exchange/bybit/oms.py +1195 -0
- walrasquant/exchange/bybit/rest_api.py +570 -0
- walrasquant/exchange/bybit/schema.py +867 -0
- walrasquant/exchange/bybit/websockets.py +307 -0
- walrasquant/exchange/hyperliquid/__init__.py +28 -0
- walrasquant/exchange/hyperliquid/connector.py +370 -0
- walrasquant/exchange/hyperliquid/constants.py +371 -0
- walrasquant/exchange/hyperliquid/ems.py +156 -0
- walrasquant/exchange/hyperliquid/error.py +48 -0
- walrasquant/exchange/hyperliquid/exchange.py +120 -0
- walrasquant/exchange/hyperliquid/factory.py +135 -0
- walrasquant/exchange/hyperliquid/oms.py +1081 -0
- walrasquant/exchange/hyperliquid/rest_api.py +348 -0
- walrasquant/exchange/hyperliquid/schema.py +583 -0
- walrasquant/exchange/hyperliquid/websockets.py +592 -0
- walrasquant/exchange/okx/__init__.py +25 -0
- walrasquant/exchange/okx/connector.py +931 -0
- walrasquant/exchange/okx/constants.py +518 -0
- walrasquant/exchange/okx/ems.py +144 -0
- walrasquant/exchange/okx/error.py +66 -0
- walrasquant/exchange/okx/exchange.py +102 -0
- walrasquant/exchange/okx/factory.py +138 -0
- walrasquant/exchange/okx/oms.py +1199 -0
- walrasquant/exchange/okx/rest_api.py +799 -0
- walrasquant/exchange/okx/schema.py +1449 -0
- walrasquant/exchange/okx/websockets.py +420 -0
- walrasquant/exchange/registry.py +201 -0
- walrasquant/execution/__init__.py +24 -0
- walrasquant/execution/algorithm.py +968 -0
- walrasquant/execution/algorithms/__init__.py +3 -0
- walrasquant/execution/algorithms/twap.py +392 -0
- walrasquant/execution/config.py +34 -0
- walrasquant/execution/constants.py +27 -0
- walrasquant/execution/schema.py +62 -0
- walrasquant/indicator.py +382 -0
- walrasquant/push.py +77 -0
- walrasquant/schema.py +755 -0
- walrasquant/strategy.py +1805 -0
- walrasquant/tools/__init__.py +0 -0
- walrasquant/tools/pm2_wrapper.py +1016 -0
- walrasquant/web/__init__.py +26 -0
- walrasquant/web/app.py +157 -0
- walrasquant/web/server.py +92 -0
- walrasquant_lib-0.4.20.dist-info/METADATA +162 -0
- walrasquant_lib-0.4.20.dist-info/RECORD +105 -0
- walrasquant_lib-0.4.20.dist-info/WHEEL +4 -0
- walrasquant_lib-0.4.20.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,1063 @@
|
|
|
1
|
+
import msgspec
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from walrasquant.schema import BaseMarket, Balance, BookOrderData # noqa: F401
|
|
5
|
+
from walrasquant.exchange.binance.constants import (
|
|
6
|
+
BinanceAccountEventReasonType,
|
|
7
|
+
BinanceOrderStatus,
|
|
8
|
+
BinanceOrderType,
|
|
9
|
+
BinancePositionSide,
|
|
10
|
+
BinanceWsEventType,
|
|
11
|
+
BinanceKlineInterval,
|
|
12
|
+
BinancePriceMatch,
|
|
13
|
+
BinanceUserDataStreamWsEventType,
|
|
14
|
+
BinanceOrderSide,
|
|
15
|
+
BinanceTimeInForce,
|
|
16
|
+
BinanceExecutionType,
|
|
17
|
+
BinanceFuturesWorkingType,
|
|
18
|
+
BinanceBusinessUnit,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BinanceResultId(msgspec.Struct):
|
|
23
|
+
id: int | None = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class BinanceBnbTransferResponse(msgspec.Struct):
|
|
27
|
+
tranId: int
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class BinanceFuturesBalanceInfo(msgspec.Struct, frozen=True):
|
|
31
|
+
asset: str # asset name
|
|
32
|
+
walletBalance: str # wallet balance
|
|
33
|
+
unrealizedProfit: str # unrealized profit
|
|
34
|
+
marginBalance: str # margin balance
|
|
35
|
+
maintMargin: str # maintenance margin required
|
|
36
|
+
initialMargin: str # total initial margin required with current mark price
|
|
37
|
+
positionInitialMargin: (
|
|
38
|
+
str # initial margin required for positions with current mark price
|
|
39
|
+
)
|
|
40
|
+
openOrderInitialMargin: (
|
|
41
|
+
str # initial margin required for open orders with current mark price
|
|
42
|
+
)
|
|
43
|
+
crossWalletBalance: str # crossed wallet balance
|
|
44
|
+
crossUnPnl: str # unrealized profit of crossed positions
|
|
45
|
+
availableBalance: str # available balance
|
|
46
|
+
maxWithdrawAmount: str # maximum amount for transfer out
|
|
47
|
+
# whether the asset can be used as margin in Multi - Assets mode
|
|
48
|
+
marginAvailable: bool | None = None
|
|
49
|
+
updateTime: int | None = None # last update time
|
|
50
|
+
|
|
51
|
+
def parse_to_balance(self) -> Balance:
|
|
52
|
+
free = Decimal(self.availableBalance)
|
|
53
|
+
locked = Decimal(self.marginBalance) - free
|
|
54
|
+
return Balance(
|
|
55
|
+
asset=self.asset,
|
|
56
|
+
free=free,
|
|
57
|
+
locked=locked,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class BinanceFuturesPositionInfo(msgspec.Struct, kw_only=True):
|
|
62
|
+
symbol: str # symbol name
|
|
63
|
+
initialMargin: str # initial margin required with current mark price
|
|
64
|
+
maintMargin: str # maintenance margin required
|
|
65
|
+
unrealizedProfit: str # unrealized profit
|
|
66
|
+
positionInitialMargin: (
|
|
67
|
+
str # initial margin required for positions with current mark price
|
|
68
|
+
)
|
|
69
|
+
openOrderInitialMargin: (
|
|
70
|
+
str # initial margin required for open orders with current mark price
|
|
71
|
+
)
|
|
72
|
+
leverage: str # current initial leverage
|
|
73
|
+
isolated: bool # if the position is isolated
|
|
74
|
+
entryPrice: str # average entry price
|
|
75
|
+
maxNotional: str | None = None # maximum available notional with current leverage
|
|
76
|
+
bidNotional: str | None = None # bids notional, ignore
|
|
77
|
+
askNotional: str | None = None # ask notional, ignore
|
|
78
|
+
positionSide: BinancePositionSide # position side
|
|
79
|
+
positionAmt: str # position amount
|
|
80
|
+
updateTime: int
|
|
81
|
+
breakEvenPrice: str | None = None # break-even price
|
|
82
|
+
maxQty: str | None = None # maximum quantity of base asset
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class BinancePortfolioMarginPositionRisk(msgspec.Struct, kw_only=True):
|
|
86
|
+
"""
|
|
87
|
+
"entryPrice": "0.00000",
|
|
88
|
+
"leverage": "10",
|
|
89
|
+
"markPrice": "6679.50671178",
|
|
90
|
+
"maxNotionalValue": "20000000",
|
|
91
|
+
"positionAmt": "0.000",
|
|
92
|
+
"notional": "0",
|
|
93
|
+
"symbol": "BTCUSDT",
|
|
94
|
+
"unRealizedProfit": "0.00000000",
|
|
95
|
+
"liquidationPrice": "6170.20509059",
|
|
96
|
+
"positionSide": "BOTH",
|
|
97
|
+
"updateTime": 1625474304765
|
|
98
|
+
|
|
99
|
+
"symbol": "BTCUSD_201225",
|
|
100
|
+
"positionAmt": "1",
|
|
101
|
+
"entryPrice": "11707.70000003",
|
|
102
|
+
"markPrice": "11788.66626667",
|
|
103
|
+
"unRealizedProfit": "0.00005866",
|
|
104
|
+
"liquidationPrice": "6170.20509059",
|
|
105
|
+
"leverage": "125",
|
|
106
|
+
"positionSide": "LONG",
|
|
107
|
+
"updateTime": 1627026881327,
|
|
108
|
+
"maxQty": "50",
|
|
109
|
+
"notionalValue": "0.00084827"
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
symbol: str
|
|
113
|
+
markPrice: str
|
|
114
|
+
entryPrice: str
|
|
115
|
+
unRealizedProfit: str
|
|
116
|
+
positionAmt: str
|
|
117
|
+
positionSide: BinancePositionSide
|
|
118
|
+
liquidationPrice: str
|
|
119
|
+
updateTime: int
|
|
120
|
+
leverage: str
|
|
121
|
+
|
|
122
|
+
notional: str | None = None
|
|
123
|
+
maxNotionalValue: str | None = None
|
|
124
|
+
|
|
125
|
+
maxQty: str | None = None
|
|
126
|
+
notionalValue: str | None = None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class BinancePortfolioMarginBalance(msgspec.Struct, kw_only=True):
|
|
130
|
+
"""
|
|
131
|
+
"asset": "USDT", // asset name
|
|
132
|
+
"totalWalletBalance": "122607.35137903", // wallet balance = cross margin free + cross margin locked + UM wallet balance + CM wallet balance
|
|
133
|
+
"crossMarginAsset": "92.27530794", // crossMarginAsset = crossMarginFree + crossMarginLocked
|
|
134
|
+
"crossMarginBorrowed": "10.00000000", // principal of cross margin
|
|
135
|
+
"crossMarginFree": "100.00000000", // free asset of cross margin
|
|
136
|
+
"crossMarginInterest": "0.72469206", // interest of cross margin
|
|
137
|
+
"crossMarginLocked": "3.00000000", //lock asset of cross margin
|
|
138
|
+
"umWalletBalance": "0.00000000", // wallet balance of um
|
|
139
|
+
"umUnrealizedPNL": "23.72469206", // unrealized profit of um
|
|
140
|
+
"cmWalletBalance": "23.72469206", // wallet balance of cm
|
|
141
|
+
"cmUnrealizedPNL": "", // unrealized profit of cm
|
|
142
|
+
"updateTime": 1617939110373,
|
|
143
|
+
"negativeBalance": "0"
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
asset: str
|
|
147
|
+
totalWalletBalance: str
|
|
148
|
+
crossMarginAsset: str
|
|
149
|
+
crossMarginBorrowed: str
|
|
150
|
+
crossMarginFree: str
|
|
151
|
+
crossMarginInterest: str
|
|
152
|
+
crossMarginLocked: str
|
|
153
|
+
umWalletBalance: str
|
|
154
|
+
umUnrealizedPNL: str
|
|
155
|
+
cmWalletBalance: str
|
|
156
|
+
cmUnrealizedPNL: str
|
|
157
|
+
updateTime: int
|
|
158
|
+
negativeBalance: str
|
|
159
|
+
|
|
160
|
+
def parse_to_balances(self) -> list[Balance]:
|
|
161
|
+
return [
|
|
162
|
+
Balance(
|
|
163
|
+
asset=f"{self.asset}.SPOT",
|
|
164
|
+
free=Decimal(self.crossMarginFree),
|
|
165
|
+
locked=Decimal(self.crossMarginLocked),
|
|
166
|
+
),
|
|
167
|
+
Balance(
|
|
168
|
+
asset=f"{self.asset}.UM",
|
|
169
|
+
free=Decimal(self.umWalletBalance),
|
|
170
|
+
),
|
|
171
|
+
Balance(
|
|
172
|
+
asset=f"{self.asset}.CM",
|
|
173
|
+
free=Decimal(self.cmWalletBalance),
|
|
174
|
+
),
|
|
175
|
+
]
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class BinanceFuturesAccountInfo(msgspec.Struct, kw_only=True):
|
|
179
|
+
feeTier: int # account commission tier
|
|
180
|
+
canTrade: bool # if can trade
|
|
181
|
+
canDeposit: bool # if can transfer in asset
|
|
182
|
+
canWithdraw: bool # if can transfer out asset
|
|
183
|
+
updateTime: int
|
|
184
|
+
totalInitialMargin: str | None = (
|
|
185
|
+
None # total initial margin required with current mark price (useless with isolated positions), only for USDT
|
|
186
|
+
)
|
|
187
|
+
totalMaintMargin: str | None = (
|
|
188
|
+
None # total maintenance margin required, only for USDT asset
|
|
189
|
+
)
|
|
190
|
+
totalWalletBalance: str | None = None # total wallet balance, only for USDT asset
|
|
191
|
+
totalUnrealizedProfit: str | None = (
|
|
192
|
+
None # total unrealized profit, only for USDT asset
|
|
193
|
+
)
|
|
194
|
+
totalMarginBalance: str | None = None # total margin balance, only for USDT asset
|
|
195
|
+
# initial margin required for positions with current mark price, only for USDT asset
|
|
196
|
+
totalPositionInitialMargin: str | None = None
|
|
197
|
+
# initial margin required for open orders with current mark price, only for USDT asset
|
|
198
|
+
totalOpenOrderInitialMargin: str | None = None
|
|
199
|
+
totalCrossWalletBalance: str | None = (
|
|
200
|
+
None # crossed wallet balance, only for USDT asset
|
|
201
|
+
)
|
|
202
|
+
# unrealized profit of crossed positions, only for USDT asset
|
|
203
|
+
totalCrossUnPnl: str | None = None
|
|
204
|
+
availableBalance: str | None = None # available balance, only for USDT asset
|
|
205
|
+
maxWithdrawAmount: str | None = (
|
|
206
|
+
None # maximum amount for transfer out, only for USDT asset
|
|
207
|
+
)
|
|
208
|
+
assets: list[BinanceFuturesBalanceInfo]
|
|
209
|
+
positions: list[BinanceFuturesPositionInfo]
|
|
210
|
+
|
|
211
|
+
def parse_to_balances(self) -> List[Balance]:
|
|
212
|
+
return [balance.parse_to_balance() for balance in self.assets]
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class BinanceSpotBalanceInfo(msgspec.Struct):
|
|
216
|
+
asset: str
|
|
217
|
+
free: str
|
|
218
|
+
locked: str
|
|
219
|
+
|
|
220
|
+
def parse_to_balance(self) -> Balance:
|
|
221
|
+
return Balance(
|
|
222
|
+
asset=self.asset,
|
|
223
|
+
free=Decimal(self.free),
|
|
224
|
+
locked=Decimal(self.locked),
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class BinanceSpotAccountInfo(msgspec.Struct, frozen=True):
|
|
229
|
+
makerCommission: int
|
|
230
|
+
takerCommission: int
|
|
231
|
+
buyerCommission: int
|
|
232
|
+
sellerCommission: int
|
|
233
|
+
canTrade: bool
|
|
234
|
+
canWithdraw: bool
|
|
235
|
+
canDeposit: bool
|
|
236
|
+
updateTime: int
|
|
237
|
+
accountType: str
|
|
238
|
+
balances: list[BinanceSpotBalanceInfo]
|
|
239
|
+
permissions: list[str]
|
|
240
|
+
|
|
241
|
+
def parse_to_balances(self) -> List[Balance]:
|
|
242
|
+
return [balance.parse_to_balance() for balance in self.balances]
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class _BinanceSpotOrderUpdateMsg(msgspec.Struct, kw_only=True):
|
|
246
|
+
C: str | None = None
|
|
247
|
+
E: int
|
|
248
|
+
F: str | None = None
|
|
249
|
+
I: int # noqa: E741
|
|
250
|
+
L: str
|
|
251
|
+
M: bool | None = None
|
|
252
|
+
N: str | None = None
|
|
253
|
+
O: int # noqa: E741
|
|
254
|
+
P: str
|
|
255
|
+
Q: str | None = None
|
|
256
|
+
S: BinanceOrderSide
|
|
257
|
+
T: int
|
|
258
|
+
V: str
|
|
259
|
+
W: int | None = None # Working Time
|
|
260
|
+
X: BinanceOrderStatus
|
|
261
|
+
Y: str
|
|
262
|
+
Z: str
|
|
263
|
+
c: str
|
|
264
|
+
e: BinanceUserDataStreamWsEventType
|
|
265
|
+
f: BinanceTimeInForce
|
|
266
|
+
g: int
|
|
267
|
+
i: int
|
|
268
|
+
l: str # noqa: E741
|
|
269
|
+
m: bool
|
|
270
|
+
n: str | None = None
|
|
271
|
+
o: BinanceOrderType
|
|
272
|
+
p: str
|
|
273
|
+
q: str
|
|
274
|
+
r: str | None = None
|
|
275
|
+
s: str
|
|
276
|
+
t: int
|
|
277
|
+
v: int | None = None
|
|
278
|
+
w: bool
|
|
279
|
+
x: BinanceExecutionType
|
|
280
|
+
z: str
|
|
281
|
+
|
|
282
|
+
A: str | None = None # Prevented Quantity
|
|
283
|
+
B: str | None = None # Last Prevented Quantity
|
|
284
|
+
D: int | None = None # trailing time
|
|
285
|
+
J: int | None = None # strategy type
|
|
286
|
+
U: int | None = None # CounterOrderId
|
|
287
|
+
d: int | None = None # trailing Delta
|
|
288
|
+
j: int | None = None # strategy id
|
|
289
|
+
u: int | None = None # Trade Group id
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class BinanceSpotOrderUpdateMsg(msgspec.Struct, kw_only=True):
|
|
293
|
+
event: _BinanceSpotOrderUpdateMsg
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class BinanceFuturesOrderData(msgspec.Struct, kw_only=True):
|
|
297
|
+
L: str # Last Filled Price
|
|
298
|
+
N: str | None = None # Commission Asset, omitted when no commission is charged
|
|
299
|
+
R: bool # Is reduce only
|
|
300
|
+
S: BinanceOrderSide
|
|
301
|
+
T: int # Order Trade Time
|
|
302
|
+
V: str # Order Filled Accumulated Quantity
|
|
303
|
+
X: BinanceOrderStatus
|
|
304
|
+
a: str # Ask Notional
|
|
305
|
+
ap: str # Average Price
|
|
306
|
+
b: str # Bids Notional
|
|
307
|
+
c: str # Client Order ID
|
|
308
|
+
f: BinanceTimeInForce
|
|
309
|
+
i: int # Order ID
|
|
310
|
+
l: str # Order Last Filled Quantity # noqa: E741
|
|
311
|
+
m: bool # Is trade the maker side
|
|
312
|
+
n: str | None = None # Commission, omitted when no commission is charged
|
|
313
|
+
o: BinanceOrderType
|
|
314
|
+
p: str # Original Price
|
|
315
|
+
ps: BinancePositionSide
|
|
316
|
+
q: str # Original Quantity
|
|
317
|
+
rp: str # Realized Profit of the trade
|
|
318
|
+
s: str # Symbol
|
|
319
|
+
sp: str # Stop Price
|
|
320
|
+
t: int # Trade ID
|
|
321
|
+
x: BinanceExecutionType
|
|
322
|
+
z: str # Order Filled Accumulated Quantity
|
|
323
|
+
|
|
324
|
+
AP: str | None = None # Activation Price
|
|
325
|
+
cp: bool | None = None # If Close-All, pushed with conditional order
|
|
326
|
+
cr: str | None = None # Callback Rate
|
|
327
|
+
gtd: int | None = None # TIF GTD order auto cancel time
|
|
328
|
+
ot: BinanceOrderType | None = None
|
|
329
|
+
pP: bool | None = None # ignore
|
|
330
|
+
pm: str | None = None # Order Margin Type
|
|
331
|
+
si: int | None = None # ignore
|
|
332
|
+
ss: int | None = None # ignore
|
|
333
|
+
wt: BinanceFuturesWorkingType | None = None
|
|
334
|
+
ma: str | None = None # Order Margin Type
|
|
335
|
+
st: str | None = (
|
|
336
|
+
None # Strategy type, only pushed with conditional order triggered
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
class BinanceFuturesOrderUpdateMsg(msgspec.Struct, kw_only=True):
|
|
341
|
+
"""
|
|
342
|
+
WebSocket message for Binance Futures Order Update events.
|
|
343
|
+
"""
|
|
344
|
+
|
|
345
|
+
e: BinanceUserDataStreamWsEventType
|
|
346
|
+
E: int # Event Time
|
|
347
|
+
T: int # Transaction Time
|
|
348
|
+
fs: BinanceBusinessUnit | None = (
|
|
349
|
+
None # Event business unit. 'UM' for USDS-M futures and 'CM' for COIN-M futures
|
|
350
|
+
)
|
|
351
|
+
o: BinanceFuturesOrderData
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
class BinanceMarkPriceDataStream(msgspec.Struct):
|
|
355
|
+
e: BinanceWsEventType
|
|
356
|
+
E: int
|
|
357
|
+
s: str
|
|
358
|
+
p: str
|
|
359
|
+
i: str
|
|
360
|
+
P: str
|
|
361
|
+
r: str
|
|
362
|
+
T: int
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class BinanceMarkPrice(msgspec.Struct):
|
|
366
|
+
data: BinanceMarkPriceDataStream
|
|
367
|
+
stream: str
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
class BinanceKlineData(msgspec.Struct):
|
|
371
|
+
t: int # Kline start time
|
|
372
|
+
T: int # Kline close time
|
|
373
|
+
s: str # Symbol
|
|
374
|
+
i: BinanceKlineInterval # Interval
|
|
375
|
+
f: int # First trade ID
|
|
376
|
+
L: int # Last trade ID
|
|
377
|
+
o: str # Open price
|
|
378
|
+
c: str # Close price
|
|
379
|
+
h: str # High price
|
|
380
|
+
l: str # Low price # noqa
|
|
381
|
+
v: str # Base asset volume
|
|
382
|
+
n: int # Number of trades
|
|
383
|
+
x: bool # Is this kline closed?
|
|
384
|
+
q: str # Quote asset volume
|
|
385
|
+
V: str # Taker buy base asset volume
|
|
386
|
+
Q: str # Taker buy quote asset volume
|
|
387
|
+
B: str # Ignore
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
class BinanceKlineDataStream(msgspec.Struct):
|
|
391
|
+
e: BinanceWsEventType
|
|
392
|
+
E: int
|
|
393
|
+
s: str
|
|
394
|
+
k: BinanceKlineData
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
class BinanceKline(msgspec.Struct):
|
|
398
|
+
data: BinanceKlineDataStream
|
|
399
|
+
stream: str
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
class BinanceTradeDataStream(msgspec.Struct):
|
|
403
|
+
e: BinanceWsEventType
|
|
404
|
+
E: int
|
|
405
|
+
s: str
|
|
406
|
+
t: int
|
|
407
|
+
p: str
|
|
408
|
+
q: str
|
|
409
|
+
T: int
|
|
410
|
+
m: bool # Is the buyer the market maker? true -> side=SELL, false -> side=BUY
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
class BinanceTradeData(msgspec.Struct):
|
|
414
|
+
data: BinanceTradeDataStream
|
|
415
|
+
stream: str
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
class BinanceSpotBookTickerData(msgspec.Struct):
|
|
419
|
+
"""
|
|
420
|
+
{
|
|
421
|
+
"u":400900217, // order book updateId
|
|
422
|
+
"s":"BNBUSDT", // symbol
|
|
423
|
+
"b":"25.35190000", // best bid price
|
|
424
|
+
"B":"31.21000000", // best bid qty
|
|
425
|
+
"a":"25.36520000", // best ask price
|
|
426
|
+
"A":"40.66000000" // best ask qty
|
|
427
|
+
}
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
u: int
|
|
431
|
+
s: str
|
|
432
|
+
b: str
|
|
433
|
+
B: str
|
|
434
|
+
a: str
|
|
435
|
+
A: str
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
class BinanceSpotBookTicker(msgspec.Struct):
|
|
439
|
+
data: BinanceSpotBookTickerData
|
|
440
|
+
stream: str
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
class BinanceFuturesBookTickerData(msgspec.Struct):
|
|
444
|
+
e: BinanceWsEventType
|
|
445
|
+
u: int
|
|
446
|
+
E: int
|
|
447
|
+
T: int
|
|
448
|
+
s: str
|
|
449
|
+
b: str
|
|
450
|
+
B: str
|
|
451
|
+
a: str
|
|
452
|
+
A: str
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
class BinanceFuturesBookTicker(msgspec.Struct):
|
|
456
|
+
data: BinanceFuturesBookTickerData
|
|
457
|
+
stream: str
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
class BinanceWsMessageGeneralData(msgspec.Struct):
|
|
461
|
+
e: BinanceWsEventType | None = None
|
|
462
|
+
u: int | None = None
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
class BinanceWsMessageGeneral(msgspec.Struct):
|
|
466
|
+
data: BinanceWsMessageGeneralData
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
class BinanceUserDataStreamMsg(msgspec.Struct):
|
|
470
|
+
e: BinanceUserDataStreamWsEventType | None = None
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
class BinanceSpotUserDataStreamMsg(msgspec.Struct):
|
|
474
|
+
event: BinanceUserDataStreamMsg | None = None
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
class BinanceListenKey(msgspec.Struct):
|
|
478
|
+
listenKey: str
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
class BinanceUserTrade(msgspec.Struct, frozen=True):
|
|
482
|
+
commission: str
|
|
483
|
+
commissionAsset: str
|
|
484
|
+
price: str
|
|
485
|
+
qty: str
|
|
486
|
+
|
|
487
|
+
# Parameters not present in 'fills' list (see FULL response of BinanceOrder)
|
|
488
|
+
symbol: str | None = None
|
|
489
|
+
id: int | None = None
|
|
490
|
+
orderId: int | None = None
|
|
491
|
+
time: int | None = None
|
|
492
|
+
quoteQty: str | None = None # SPOT/MARGIN & USD-M FUTURES only
|
|
493
|
+
|
|
494
|
+
# Parameters in SPOT/MARGIN only:
|
|
495
|
+
orderListId: int | None = None # unless OCO, the value will always be -1
|
|
496
|
+
isBuyer: bool | None = None
|
|
497
|
+
isMaker: bool | None = None
|
|
498
|
+
isBestMatch: bool | None = None
|
|
499
|
+
tradeId: int | None = None # only in BinanceOrder FULL response
|
|
500
|
+
|
|
501
|
+
# Parameters in FUTURES only:
|
|
502
|
+
buyer: bool | None = None
|
|
503
|
+
maker: bool | None = None
|
|
504
|
+
realizedPnl: str | None = None
|
|
505
|
+
side: BinanceOrderSide | None = None
|
|
506
|
+
positionSide: str | None = None
|
|
507
|
+
baseQty: str | None = None # COIN-M FUTURES only
|
|
508
|
+
pair: str | None = None # COIN-M FUTURES only
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
class BinanceOrder(msgspec.Struct, frozen=True):
|
|
512
|
+
symbol: str
|
|
513
|
+
orderId: int
|
|
514
|
+
clientOrderId: str
|
|
515
|
+
|
|
516
|
+
# Parameters not in ACK response:
|
|
517
|
+
price: str | None = None
|
|
518
|
+
origQty: str | None = None
|
|
519
|
+
executedQty: str | None = None
|
|
520
|
+
status: BinanceOrderStatus | None = None
|
|
521
|
+
timeInForce: BinanceTimeInForce | None = None
|
|
522
|
+
goodTillDate: int | None = None
|
|
523
|
+
type: BinanceOrderType | None = None
|
|
524
|
+
side: BinanceOrderSide | None = None
|
|
525
|
+
stopPrice: str | None = (
|
|
526
|
+
None # please ignore when order type is TRAILING_STOP_MARKET
|
|
527
|
+
)
|
|
528
|
+
time: int | None = None
|
|
529
|
+
updateTime: int | None = None
|
|
530
|
+
|
|
531
|
+
# Parameters in SPOT/MARGIN only:
|
|
532
|
+
orderListId: int | None = None # Unless OCO, the value will always be -1
|
|
533
|
+
cumulativeQuoteQty: str | None = None # cumulative quote qty
|
|
534
|
+
icebergQty: str | None = None
|
|
535
|
+
isWorking: bool | None = None
|
|
536
|
+
workingTime: int | None = None
|
|
537
|
+
origQuoteOrderQty: str | None = None
|
|
538
|
+
selfTradePreventionMode: str | None = None
|
|
539
|
+
transactTime: int | None = None # POST & DELETE methods only
|
|
540
|
+
fills: list[BinanceUserTrade] | None = None # FULL response only
|
|
541
|
+
|
|
542
|
+
# Parameters in FUTURES only:
|
|
543
|
+
avgPrice: str | None = None
|
|
544
|
+
origType: BinanceOrderType | None = None
|
|
545
|
+
reduceOnly: bool | None = None
|
|
546
|
+
positionSide: BinancePositionSide | None = None
|
|
547
|
+
closePosition: bool | None = None
|
|
548
|
+
activatePrice: str | None = (
|
|
549
|
+
None # activation price, only for TRAILING_STOP_MARKET order
|
|
550
|
+
)
|
|
551
|
+
priceRate: str | None = None # callback rate, only for TRAILING_STOP_MARKET order
|
|
552
|
+
workingType: str | None = None
|
|
553
|
+
priceProtect: bool | None = None # if conditional order trigger is protected
|
|
554
|
+
cumQuote: str | None = None # USD-M FUTURES only
|
|
555
|
+
cumBase: str | None = None # COIN-M FUTURES only
|
|
556
|
+
pair: str | None = None # COIN-M FUTURES only
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
class BinanceFuturesModifyOrderResponse(msgspec.Struct, frozen=True, kw_only=True):
|
|
560
|
+
"""
|
|
561
|
+
{
|
|
562
|
+
"orderId": 20072994037,
|
|
563
|
+
"symbol": "BTCUSDT",
|
|
564
|
+
"pair": "BTCUSDT",
|
|
565
|
+
"status": "NEW",
|
|
566
|
+
"clientOrderId": "LJ9R4QZDihCaS8UAOOLpgW",
|
|
567
|
+
"price": "30005",
|
|
568
|
+
"avgPrice": "0.0",
|
|
569
|
+
"origQty": "1",
|
|
570
|
+
"executedQty": "0",
|
|
571
|
+
"cumQty": "0",
|
|
572
|
+
"cumBase": "0",
|
|
573
|
+
"timeInForce": "GTC",
|
|
574
|
+
"type": "LIMIT",
|
|
575
|
+
"reduceOnly": false,
|
|
576
|
+
"closePosition": false,
|
|
577
|
+
"side": "BUY",
|
|
578
|
+
"positionSide": "LONG",
|
|
579
|
+
"stopPrice": "0",
|
|
580
|
+
"workingType": "CONTRACT_PRICE",
|
|
581
|
+
"priceProtect": false,
|
|
582
|
+
"origType": "LIMIT",
|
|
583
|
+
"priceMatch": "NONE", //price match mode
|
|
584
|
+
"selfTradePreventionMode": "NONE", //self trading preventation mode
|
|
585
|
+
"goodTillDate": 0, //order pre-set auot cancel time for TIF GTD order
|
|
586
|
+
"updateTime": 1629182711600
|
|
587
|
+
}
|
|
588
|
+
"""
|
|
589
|
+
|
|
590
|
+
orderId: int
|
|
591
|
+
symbol: str
|
|
592
|
+
pair: str | None = None
|
|
593
|
+
status: BinanceOrderStatus
|
|
594
|
+
clientOrderId: str
|
|
595
|
+
price: str
|
|
596
|
+
avgPrice: str
|
|
597
|
+
origQty: str
|
|
598
|
+
executedQty: str
|
|
599
|
+
cumQty: str
|
|
600
|
+
cumBase: str | None = None
|
|
601
|
+
cumQuote: str | None = None
|
|
602
|
+
timeInForce: BinanceTimeInForce
|
|
603
|
+
type: BinanceOrderType
|
|
604
|
+
reduceOnly: bool | None = None
|
|
605
|
+
closePosition: bool | None = None
|
|
606
|
+
side: BinanceOrderSide
|
|
607
|
+
positionSide: BinancePositionSide
|
|
608
|
+
stopPrice: str | None = None
|
|
609
|
+
workingType: BinanceFuturesWorkingType | None = None
|
|
610
|
+
priceProtect: bool | None = None
|
|
611
|
+
origType: BinanceOrderType
|
|
612
|
+
priceMatch: BinancePriceMatch | None = None
|
|
613
|
+
selfTradePreventionMode: str | None = None
|
|
614
|
+
goodTillDate: int | None = None
|
|
615
|
+
updateTime: int
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
class BinanceMarketInfo(msgspec.Struct):
|
|
619
|
+
symbol: str | None = None
|
|
620
|
+
status: str | None = None
|
|
621
|
+
baseAsset: str | None = None
|
|
622
|
+
baseAssetPrecision: str | int | None = None
|
|
623
|
+
quoteAsset: str | None = None
|
|
624
|
+
quotePrecision: str | int | None = None
|
|
625
|
+
quoteAssetPrecision: str | int | None = None
|
|
626
|
+
baseCommissionPrecision: str | int | None = None
|
|
627
|
+
quoteCommissionPrecision: str | int | None = None
|
|
628
|
+
orderTypes: List[BinanceOrderType] | None = None
|
|
629
|
+
icebergAllowed: bool | None = None
|
|
630
|
+
ocoAllowed: bool | None = None
|
|
631
|
+
otoAllowed: bool | None = None
|
|
632
|
+
quoteOrderQtyMarketAllowed: bool | None = None
|
|
633
|
+
allowTrailingStop: bool | None = None
|
|
634
|
+
cancelReplaceAllowed: bool | None = None
|
|
635
|
+
isSpotTradingAllowed: bool | None = None
|
|
636
|
+
isMarginTradingAllowed: bool | None = None
|
|
637
|
+
filters: List[Dict[str, Any]] | None = None
|
|
638
|
+
permissions: List[str] | None = None
|
|
639
|
+
permissionSets: List[List[str] | str] | None = None
|
|
640
|
+
defaultSelfTradePreventionMode: str | None = None
|
|
641
|
+
allowedSelfTradePreventionModes: List[str] | None = None
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
class BinanceMarket(BaseMarket):
|
|
645
|
+
info: BinanceMarketInfo
|
|
646
|
+
feeSide: str
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
class BinanceFuturesBalanceData(msgspec.Struct):
|
|
650
|
+
a: str
|
|
651
|
+
wb: str # wallet balance
|
|
652
|
+
cw: str # cross wallet balance
|
|
653
|
+
bc: str # wallet change except PnL and Commission
|
|
654
|
+
|
|
655
|
+
def parse_to_balance(self) -> Balance:
|
|
656
|
+
return Balance(
|
|
657
|
+
asset=self.a,
|
|
658
|
+
free=Decimal(self.wb),
|
|
659
|
+
locked=Decimal(0),
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
def pm_parse_to_balance(self, fs: BinanceBusinessUnit) -> Balance:
|
|
663
|
+
return Balance(
|
|
664
|
+
asset=f"{self.a}.{fs.value}",
|
|
665
|
+
free=Decimal(self.wb),
|
|
666
|
+
locked=Decimal(0),
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
class BinanceFuturesPositionData(msgspec.Struct, kw_only=True):
|
|
671
|
+
s: str
|
|
672
|
+
pa: str # position amount
|
|
673
|
+
ep: str # entry price
|
|
674
|
+
bep: str | float # breakeven price
|
|
675
|
+
cr: str # (Pre-fee) Accumulated Realized
|
|
676
|
+
up: str # Unrealized PnL
|
|
677
|
+
mt: str | None = None # margin type (if isolated position)
|
|
678
|
+
iw: str | None = None # isolated wallet (if isolated position)
|
|
679
|
+
ps: BinancePositionSide
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
class BinanceFuturesUpdateData(msgspec.Struct, kw_only=True):
|
|
683
|
+
m: BinanceAccountEventReasonType
|
|
684
|
+
B: list[BinanceFuturesBalanceData]
|
|
685
|
+
P: list[BinanceFuturesPositionData]
|
|
686
|
+
|
|
687
|
+
def parse_to_balances(self) -> List[Balance]:
|
|
688
|
+
return [balance.parse_to_balance() for balance in self.B]
|
|
689
|
+
|
|
690
|
+
def pm_parse_to_balances(self, fs: BinanceBusinessUnit) -> List[Balance]:
|
|
691
|
+
return [balance.pm_parse_to_balance(fs) for balance in self.B]
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
class BinanceFuturesUpdateMsg(msgspec.Struct, kw_only=True):
|
|
695
|
+
e: BinanceUserDataStreamWsEventType
|
|
696
|
+
E: int
|
|
697
|
+
T: int
|
|
698
|
+
fs: BinanceBusinessUnit | None = None
|
|
699
|
+
a: BinanceFuturesUpdateData
|
|
700
|
+
|
|
701
|
+
def parse_to_balances(self) -> List[Balance]:
|
|
702
|
+
if self.fs is not None:
|
|
703
|
+
return self.a.pm_parse_to_balances(self.fs)
|
|
704
|
+
else:
|
|
705
|
+
return self.a.parse_to_balances()
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
class BinanceSpotBalanceData(msgspec.Struct):
|
|
709
|
+
a: str # asset
|
|
710
|
+
f: str # free
|
|
711
|
+
l: str # locked # noqa: E741
|
|
712
|
+
|
|
713
|
+
def parse_to_balance(self) -> Balance:
|
|
714
|
+
return Balance(
|
|
715
|
+
asset=self.a,
|
|
716
|
+
free=Decimal(self.f),
|
|
717
|
+
locked=Decimal(self.l),
|
|
718
|
+
)
|
|
719
|
+
|
|
720
|
+
def pm_parse_to_balance(self) -> Balance:
|
|
721
|
+
return Balance(
|
|
722
|
+
asset=f"{self.a}.SPOT",
|
|
723
|
+
free=Decimal(self.f),
|
|
724
|
+
locked=Decimal(self.l),
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
class _BinanceSpotUpdateMsg(msgspec.Struct, kw_only=True):
|
|
729
|
+
e: BinanceUserDataStreamWsEventType # event type
|
|
730
|
+
E: int # event time
|
|
731
|
+
u: int # Time of last account update
|
|
732
|
+
B: list[BinanceSpotBalanceData] # balance array of the account
|
|
733
|
+
|
|
734
|
+
def parse_to_balances(self) -> List[Balance]:
|
|
735
|
+
return [balance.parse_to_balance() for balance in self.B]
|
|
736
|
+
|
|
737
|
+
def pm_parse_to_balances(self) -> List[Balance]:
|
|
738
|
+
return [balance.pm_parse_to_balance() for balance in self.B]
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
class BinanceSpotUpdateMsg(msgspec.Struct, kw_only=True):
|
|
742
|
+
event: _BinanceSpotUpdateMsg
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
class BinanceResponseKline(msgspec.Struct, array_like=True):
|
|
746
|
+
"""
|
|
747
|
+
[
|
|
748
|
+
1499040000000, // Kline open time
|
|
749
|
+
"0.01634790", // Open price
|
|
750
|
+
"0.80000000", // High price
|
|
751
|
+
"0.01575800", // Low price
|
|
752
|
+
"0.01577100", // Close price
|
|
753
|
+
"148976.11427815", // Volume
|
|
754
|
+
1499644799999, // Kline Close time
|
|
755
|
+
"2434.19055334", // Quote asset volume
|
|
756
|
+
308, // Number of trades
|
|
757
|
+
"1756.87402397", // Taker buy base asset volume
|
|
758
|
+
"28.46694368", // Taker buy quote asset volume
|
|
759
|
+
"0" // Unused field, ignore.
|
|
760
|
+
]
|
|
761
|
+
"""
|
|
762
|
+
|
|
763
|
+
open_time: int
|
|
764
|
+
open: str
|
|
765
|
+
high: str
|
|
766
|
+
low: str
|
|
767
|
+
close: str
|
|
768
|
+
volume: str
|
|
769
|
+
close_time: int
|
|
770
|
+
asset_volume: str
|
|
771
|
+
trades_count: int
|
|
772
|
+
taker_base_volume: str
|
|
773
|
+
taker_quote_volume: str
|
|
774
|
+
ignore: str
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
class BinanceIndexResponseKline(msgspec.Struct, array_like=True):
|
|
778
|
+
"""
|
|
779
|
+
1591256400000, // Open time
|
|
780
|
+
"9653.69440000", // Open
|
|
781
|
+
"9653.69640000", // High
|
|
782
|
+
"9651.38600000", // Low
|
|
783
|
+
"9651.55200000", // Close (or latest price)
|
|
784
|
+
"0 ", // Ignore
|
|
785
|
+
1591256459999, // Close time
|
|
786
|
+
"0", // Ignore
|
|
787
|
+
60, // Ignore
|
|
788
|
+
"0", // Ignore
|
|
789
|
+
"0", // Ignore
|
|
790
|
+
"0" // Ignore
|
|
791
|
+
"""
|
|
792
|
+
|
|
793
|
+
open_time: int
|
|
794
|
+
open: str
|
|
795
|
+
high: str
|
|
796
|
+
low: str
|
|
797
|
+
close: str
|
|
798
|
+
ignore_1: str
|
|
799
|
+
close_time: int
|
|
800
|
+
ignore_2: str
|
|
801
|
+
ignore_3: int
|
|
802
|
+
ignore_4: str
|
|
803
|
+
ignore_5: str
|
|
804
|
+
ignore_6: str
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
class BinanceSpotOrderBookMsg(msgspec.Struct):
|
|
808
|
+
"""
|
|
809
|
+
WebSocket message for 'Binance Spot/Margin' Partial Book Depth Streams.
|
|
810
|
+
"""
|
|
811
|
+
|
|
812
|
+
stream: str
|
|
813
|
+
data: "BinanceSpotOrderBookData"
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
class BinanceSpotOrderBookData(msgspec.Struct):
|
|
817
|
+
"""
|
|
818
|
+
Websocket message 'inner struct' for 'Binance Spot/Margin Partial Book Depth
|
|
819
|
+
Streams.'.
|
|
820
|
+
"""
|
|
821
|
+
|
|
822
|
+
lastUpdateId: int
|
|
823
|
+
bids: list["BinanceOrderBookDelta"]
|
|
824
|
+
asks: list["BinanceOrderBookDelta"]
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
class BinanceOrderBookDelta(msgspec.Struct, array_like=True):
|
|
828
|
+
"""
|
|
829
|
+
Schema of single ask/bid delta.
|
|
830
|
+
"""
|
|
831
|
+
|
|
832
|
+
price: str
|
|
833
|
+
size: str
|
|
834
|
+
|
|
835
|
+
def parse_to_book_order_data(self) -> BookOrderData:
|
|
836
|
+
return BookOrderData(
|
|
837
|
+
price=float(self.price),
|
|
838
|
+
size=float(self.size),
|
|
839
|
+
)
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
class BinanceFuturesOrderBookMsg(msgspec.Struct, frozen=True):
|
|
843
|
+
"""
|
|
844
|
+
WebSocket message from Binance Partial & Diff.
|
|
845
|
+
|
|
846
|
+
Book Depth Streams.
|
|
847
|
+
|
|
848
|
+
"""
|
|
849
|
+
|
|
850
|
+
stream: str
|
|
851
|
+
data: "BinanceFuturesOrderBookData"
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
class BinanceFuturesOrderBookData(msgspec.Struct, frozen=True):
|
|
855
|
+
"""
|
|
856
|
+
WebSocket message 'inner struct' for Binance Partial & Diff.
|
|
857
|
+
|
|
858
|
+
Book Depth Streams.
|
|
859
|
+
|
|
860
|
+
"""
|
|
861
|
+
|
|
862
|
+
e: str # Event type
|
|
863
|
+
E: int # Event time
|
|
864
|
+
s: str # Symbol
|
|
865
|
+
U: int # First update ID in event
|
|
866
|
+
u: int # Final update ID in event
|
|
867
|
+
b: list[BinanceOrderBookDelta] # Bids to be updated
|
|
868
|
+
a: list[BinanceOrderBookDelta] # Asks to be updated
|
|
869
|
+
|
|
870
|
+
T: int | None = None # FUTURES only, transaction time
|
|
871
|
+
pu: int | None = None # FUTURES only, previous final update ID
|
|
872
|
+
ps: str | None = None # COIN-M FUTURES only, pair
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
class BinanceCancelAllOrdersResponse(msgspec.Struct, frozen=True):
|
|
876
|
+
code: int
|
|
877
|
+
msg: str
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
class BinanceFundingRateResponse(msgspec.Struct, frozen=True):
|
|
881
|
+
symbol: str
|
|
882
|
+
fundingRate: str
|
|
883
|
+
fundingTime: int
|
|
884
|
+
markPrice: str | None = None
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
class BinanceBatchOrderResponse(msgspec.Struct, frozen=True, omit_defaults=True):
|
|
888
|
+
clientOrderId: str | None = None
|
|
889
|
+
cumQty: str | None = None
|
|
890
|
+
executedQty: str | None = None
|
|
891
|
+
orderId: int | None = None
|
|
892
|
+
avgPrice: str | None = None
|
|
893
|
+
origQty: str | None = None
|
|
894
|
+
price: str | None = None
|
|
895
|
+
reduceOnly: bool | None = None
|
|
896
|
+
side: BinanceOrderSide | None = None
|
|
897
|
+
positionSide: BinancePositionSide | None = None
|
|
898
|
+
status: BinanceOrderStatus | None = None
|
|
899
|
+
stopPrice: str | None = None
|
|
900
|
+
closePosition: bool | None = None
|
|
901
|
+
symbol: str | None = None
|
|
902
|
+
timeInForce: BinanceTimeInForce | None = None
|
|
903
|
+
type: BinanceOrderType | None = None
|
|
904
|
+
origType: BinanceOrderType | None = None
|
|
905
|
+
updateTime: int | None = None
|
|
906
|
+
priceProtect: bool | None = None
|
|
907
|
+
# USD-M specific fields
|
|
908
|
+
cumQuote: str | None = None
|
|
909
|
+
goodTillDate: int | None = None
|
|
910
|
+
# Coin-M specific fields
|
|
911
|
+
cumBase: str | None = None
|
|
912
|
+
pair: str | None = None
|
|
913
|
+
# Optional fields for both
|
|
914
|
+
activatePrice: str | None = None
|
|
915
|
+
priceRate: str | None = None
|
|
916
|
+
workingType: BinanceFuturesWorkingType | None = None
|
|
917
|
+
priceMatch: BinancePriceMatch | None = None
|
|
918
|
+
selfTradePreventionMode: str | None = None
|
|
919
|
+
code: int | None = None
|
|
920
|
+
msg: str | None = None
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
################################################################################
|
|
924
|
+
# GET /fapi/v1/ticker/24hr and GET /dapi/v1/ticker/24hr
|
|
925
|
+
################################################################################
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
class BinanceFuture24hrTicker(msgspec.Struct):
|
|
929
|
+
"""
|
|
930
|
+
24hr ticker data structure for Binance Futures (FAPI and DAPI).
|
|
931
|
+
Supports both USD-M and Coin-M futures.
|
|
932
|
+
"""
|
|
933
|
+
|
|
934
|
+
symbol: str # Symbol name
|
|
935
|
+
priceChange: str # Price change
|
|
936
|
+
priceChangePercent: str # Price change percentage
|
|
937
|
+
weightedAvgPrice: str # Weighted average price
|
|
938
|
+
lastPrice: str # Last price
|
|
939
|
+
lastQty: str # Last quantity
|
|
940
|
+
openPrice: str # Open price
|
|
941
|
+
highPrice: str # High price
|
|
942
|
+
lowPrice: str # Low price
|
|
943
|
+
volume: str # Volume
|
|
944
|
+
openTime: int # Open time
|
|
945
|
+
closeTime: int # Close time
|
|
946
|
+
firstId: int # First trade ID
|
|
947
|
+
lastId: int # Last trade ID
|
|
948
|
+
count: int # Trade count
|
|
949
|
+
|
|
950
|
+
# FAPI specific fields
|
|
951
|
+
quoteVolume: str | None = None # Quote volume (FAPI only)
|
|
952
|
+
|
|
953
|
+
# DAPI specific fields
|
|
954
|
+
pair: str | None = None # Pair name (DAPI only)
|
|
955
|
+
baseVolume: str | None = None # Base volume (DAPI only)
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
class BinanceSpot24hrTicker(msgspec.Struct):
|
|
959
|
+
"""
|
|
960
|
+
24hr ticker data structure for Binance Spot.
|
|
961
|
+
Supports both FULL and MINI response types.
|
|
962
|
+
"""
|
|
963
|
+
|
|
964
|
+
symbol: str # Symbol name
|
|
965
|
+
openPrice: str # Opening price
|
|
966
|
+
highPrice: str # Highest price
|
|
967
|
+
lowPrice: str # Lowest price
|
|
968
|
+
lastPrice: str # Last price
|
|
969
|
+
volume: str # Total trade volume (base asset)
|
|
970
|
+
quoteVolume: str # Total trade volume (quote asset)
|
|
971
|
+
openTime: int # Start of ticker interval
|
|
972
|
+
closeTime: int # End of ticker interval
|
|
973
|
+
firstId: int # First trade ID
|
|
974
|
+
lastId: int # Last trade ID
|
|
975
|
+
count: int # Total trade count
|
|
976
|
+
|
|
977
|
+
# FULL response additional fields
|
|
978
|
+
priceChange: str | None = None # Price change
|
|
979
|
+
priceChangePercent: str | None = None # Price change percentage
|
|
980
|
+
weightedAvgPrice: str | None = None # Weighted average price
|
|
981
|
+
prevClosePrice: str | None = None # Previous close price
|
|
982
|
+
lastQty: str | None = None # Last quantity
|
|
983
|
+
bidPrice: str | None = None # Best bid price
|
|
984
|
+
bidQty: str | None = None # Best bid quantity
|
|
985
|
+
askPrice: str | None = None # Best ask price
|
|
986
|
+
askQty: str | None = None # Best ask quantity
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
class BinanceWsOrderResponseResult(msgspec.Struct, frozen=True):
|
|
990
|
+
orderId: int
|
|
991
|
+
symbol: str
|
|
992
|
+
clientOrderId: str
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
class BinanceWsOrderResponseError(msgspec.Struct, frozen=True):
|
|
996
|
+
code: int
|
|
997
|
+
msg: str
|
|
998
|
+
|
|
999
|
+
@property
|
|
1000
|
+
def format_str(self) -> str:
|
|
1001
|
+
return f"code={self.code} error={self.msg}"
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
class BinanceWsOrderResponse(msgspec.Struct, frozen=True):
|
|
1005
|
+
id: str
|
|
1006
|
+
status: int
|
|
1007
|
+
result: BinanceWsOrderResponseResult | None = None
|
|
1008
|
+
error: BinanceWsOrderResponseError | None = None
|
|
1009
|
+
|
|
1010
|
+
@property
|
|
1011
|
+
def is_success(self) -> bool:
|
|
1012
|
+
return self.status == 200
|
|
1013
|
+
|
|
1014
|
+
@property
|
|
1015
|
+
def is_failed(self) -> bool:
|
|
1016
|
+
return self.status != 200
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
class BinanceDepthSnapshotData(msgspec.Struct):
|
|
1020
|
+
lastUpdateId: int
|
|
1021
|
+
bids: list[BinanceOrderBookDelta]
|
|
1022
|
+
asks: list[BinanceOrderBookDelta]
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
class BinanceOrderBook:
|
|
1026
|
+
"""Local order book state manager for Binance full diff depth stream."""
|
|
1027
|
+
|
|
1028
|
+
def __init__(self):
|
|
1029
|
+
self.bids: Dict[float, float] = {}
|
|
1030
|
+
self.asks: Dict[float, float] = {}
|
|
1031
|
+
self.last_update_id: int = 0
|
|
1032
|
+
self.ready: bool = False
|
|
1033
|
+
self.buffer: list = []
|
|
1034
|
+
|
|
1035
|
+
def apply_snapshot(self, snapshot: BinanceDepthSnapshotData) -> None:
|
|
1036
|
+
self.bids = {float(d.price): float(d.size) for d in snapshot.bids}
|
|
1037
|
+
self.asks = {float(d.price): float(d.size) for d in snapshot.asks}
|
|
1038
|
+
self.last_update_id = snapshot.lastUpdateId
|
|
1039
|
+
|
|
1040
|
+
def apply_delta(self, data: "BinanceFuturesOrderBookData") -> None:
|
|
1041
|
+
for b in data.b:
|
|
1042
|
+
price = float(b.price)
|
|
1043
|
+
size = float(b.size)
|
|
1044
|
+
if size == 0.0:
|
|
1045
|
+
self.bids.pop(price, None)
|
|
1046
|
+
else:
|
|
1047
|
+
self.bids[price] = size
|
|
1048
|
+
for a in data.a:
|
|
1049
|
+
price = float(a.price)
|
|
1050
|
+
size = float(a.size)
|
|
1051
|
+
if size == 0.0:
|
|
1052
|
+
self.asks.pop(price, None)
|
|
1053
|
+
else:
|
|
1054
|
+
self.asks[price] = size
|
|
1055
|
+
self.last_update_id = data.u
|
|
1056
|
+
|
|
1057
|
+
def get_orderbook(self) -> dict:
|
|
1058
|
+
bids = sorted(self.bids.items(), reverse=True)
|
|
1059
|
+
asks = sorted(self.asks.items())
|
|
1060
|
+
return {
|
|
1061
|
+
"bids": [BookOrderData(price=p, size=s) for p, s in bids],
|
|
1062
|
+
"asks": [BookOrderData(price=p, size=s) for p, s in asks],
|
|
1063
|
+
}
|