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
walrasquant/constants.py
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Literal, Dict, List, TypedDict, NotRequired
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from dynaconf import Dynaconf
|
|
6
|
+
|
|
7
|
+
BACKEND_LITERAL = Literal["memory", "redis"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def is_sphinx_build():
|
|
11
|
+
return "sphinx" in sys.modules
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if not os.path.exists(".keys/"):
|
|
15
|
+
os.makedirs(".keys/")
|
|
16
|
+
|
|
17
|
+
_SECRETS_CANDIDATES = [
|
|
18
|
+
".keys/.secrets.toml",
|
|
19
|
+
".keys/.secrets.yaml",
|
|
20
|
+
".keys/.secrets.yml",
|
|
21
|
+
]
|
|
22
|
+
_SETTINGS_CANDIDATES = [
|
|
23
|
+
".keys/settings.toml",
|
|
24
|
+
".keys/settings.yaml",
|
|
25
|
+
".keys/settings.yml",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
_secrets_file = next((f for f in _SECRETS_CANDIDATES if os.path.exists(f)), None)
|
|
29
|
+
_settings_file = next((f for f in _SETTINGS_CANDIDATES if os.path.exists(f)), None)
|
|
30
|
+
_config_files = [f for f in (_settings_file, _secrets_file) if f]
|
|
31
|
+
|
|
32
|
+
if _secrets_file is None and not is_sphinx_build():
|
|
33
|
+
raise FileNotFoundError(
|
|
34
|
+
"Config file not found, please create a secrets file at one of: "
|
|
35
|
+
+ ", ".join(_SECRETS_CANDIDATES)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
settings = Dynaconf(
|
|
40
|
+
envvar_prefix="NEXUS",
|
|
41
|
+
settings_files=_config_files,
|
|
42
|
+
secrets=_secrets_file,
|
|
43
|
+
environments=False,
|
|
44
|
+
load_dotenv=True,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_postgresql_config():
|
|
49
|
+
"""Get PostgreSQL configuration from environment variables or settings files."""
|
|
50
|
+
return {
|
|
51
|
+
"host": settings.get("PG_HOST", "localhost"),
|
|
52
|
+
"port": settings.get("PG_PORT", 5432),
|
|
53
|
+
"user": settings.get("PG_USER", "postgres"),
|
|
54
|
+
"password": settings.get("PG_PASSWORD", ""),
|
|
55
|
+
"database": settings.get("PG_DATABASE", "postgres"),
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_redis_config():
|
|
60
|
+
try:
|
|
61
|
+
return {
|
|
62
|
+
"host": settings.REDIS_HOST,
|
|
63
|
+
"port": settings.REDIS_PORT,
|
|
64
|
+
"db": settings.REDIS_DB,
|
|
65
|
+
"password": settings.REDIS_PASSWORD,
|
|
66
|
+
}
|
|
67
|
+
except Exception as e:
|
|
68
|
+
raise ValueError(f"Failed to get Redis password: {e}")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
IntervalType = Literal[
|
|
72
|
+
"1s",
|
|
73
|
+
"1m",
|
|
74
|
+
"3m",
|
|
75
|
+
"5m",
|
|
76
|
+
"15m",
|
|
77
|
+
"30m",
|
|
78
|
+
"1h",
|
|
79
|
+
"2h",
|
|
80
|
+
"4h",
|
|
81
|
+
"6h",
|
|
82
|
+
"8h",
|
|
83
|
+
"12h",
|
|
84
|
+
"1d",
|
|
85
|
+
"3d",
|
|
86
|
+
"1w",
|
|
87
|
+
"1M",
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class BookLevel(Enum):
|
|
92
|
+
L5 = "5"
|
|
93
|
+
L10 = "10"
|
|
94
|
+
L20 = "20"
|
|
95
|
+
L50 = "50"
|
|
96
|
+
L200 = "200"
|
|
97
|
+
L400 = "400"
|
|
98
|
+
L1000 = "1000"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class KlineInterval(Enum):
|
|
102
|
+
SECOND_1 = "1s"
|
|
103
|
+
MINUTE_1 = "1m"
|
|
104
|
+
MINUTE_3 = "3m"
|
|
105
|
+
MINUTE_5 = "5m"
|
|
106
|
+
MINUTE_15 = "15m"
|
|
107
|
+
MINUTE_30 = "30m"
|
|
108
|
+
HOUR_1 = "1h"
|
|
109
|
+
HOUR_2 = "2h"
|
|
110
|
+
HOUR_4 = "4h"
|
|
111
|
+
HOUR_6 = "6h"
|
|
112
|
+
HOUR_8 = "8h"
|
|
113
|
+
HOUR_12 = "12h"
|
|
114
|
+
DAY_1 = "1d"
|
|
115
|
+
DAY_3 = "3d"
|
|
116
|
+
WEEK_1 = "1w"
|
|
117
|
+
MONTH_1 = "1M"
|
|
118
|
+
VOLUME = "volume"
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def seconds(self) -> int:
|
|
122
|
+
return {
|
|
123
|
+
KlineInterval.SECOND_1: 1,
|
|
124
|
+
KlineInterval.MINUTE_1: 60,
|
|
125
|
+
KlineInterval.MINUTE_3: 180,
|
|
126
|
+
KlineInterval.MINUTE_5: 300,
|
|
127
|
+
KlineInterval.MINUTE_15: 900,
|
|
128
|
+
KlineInterval.MINUTE_30: 1800,
|
|
129
|
+
KlineInterval.HOUR_1: 3600,
|
|
130
|
+
KlineInterval.HOUR_2: 7200,
|
|
131
|
+
KlineInterval.HOUR_4: 14400,
|
|
132
|
+
KlineInterval.HOUR_6: 21600,
|
|
133
|
+
KlineInterval.HOUR_8: 28800,
|
|
134
|
+
KlineInterval.HOUR_12: 43200,
|
|
135
|
+
KlineInterval.DAY_1: 86400,
|
|
136
|
+
KlineInterval.DAY_3: 259200,
|
|
137
|
+
KlineInterval.WEEK_1: 604800,
|
|
138
|
+
KlineInterval.MONTH_1: 2592000,
|
|
139
|
+
KlineInterval.VOLUME: 0,
|
|
140
|
+
}[self]
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def nanoseconds(self) -> int:
|
|
144
|
+
return self.seconds * 1_000_000_000
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def microseconds(self) -> int:
|
|
148
|
+
return self.seconds * 1_000_000
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def milliseconds(self) -> int:
|
|
152
|
+
return self.seconds * 1_000
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class SubmitType(Enum):
|
|
156
|
+
CREATE = 0
|
|
157
|
+
CANCEL = 1
|
|
158
|
+
TWAP = 2
|
|
159
|
+
CANCEL_TWAP = 3
|
|
160
|
+
VWAP = 4
|
|
161
|
+
CANCEL_VWAP = 5
|
|
162
|
+
TAKE_PROFIT_AND_STOP_LOSS = 6
|
|
163
|
+
MODIFY = 7
|
|
164
|
+
CANCEL_ALL = 8
|
|
165
|
+
BATCH = 9
|
|
166
|
+
CREATE_WS = 10
|
|
167
|
+
CANCEL_WS = 11
|
|
168
|
+
CANCEL_BATCH = 12
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def priority(self) -> int:
|
|
172
|
+
"""Lower value = higher priority. CREATE types return 5 (lowest); call
|
|
173
|
+
``order_priority()`` instead when the order payload is available."""
|
|
174
|
+
if self in CANCEL_SUBMIT_TYPES:
|
|
175
|
+
return 0
|
|
176
|
+
if self == SubmitType.MODIFY:
|
|
177
|
+
return 1
|
|
178
|
+
return 5 # CREATE / CREATE_WS / BATCH / TP_SL — refined by order_priority()
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
CANCEL_SUBMIT_TYPES: frozenset = frozenset(
|
|
182
|
+
{
|
|
183
|
+
SubmitType.CANCEL,
|
|
184
|
+
SubmitType.CANCEL_WS,
|
|
185
|
+
SubmitType.CANCEL_ALL,
|
|
186
|
+
SubmitType.CANCEL_BATCH,
|
|
187
|
+
SubmitType.CANCEL_TWAP,
|
|
188
|
+
SubmitType.CANCEL_VWAP,
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class EventType(Enum):
|
|
194
|
+
BOOKL1 = 0
|
|
195
|
+
TRADE = 1
|
|
196
|
+
KLINE = 2
|
|
197
|
+
MARK_PRICE = 3
|
|
198
|
+
FUNDING_RATE = 4
|
|
199
|
+
INDEX_PRICE = 5
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class OrderStatus(Enum):
|
|
203
|
+
# LOCAL
|
|
204
|
+
INITIALIZED = "INITIALIZED"
|
|
205
|
+
FAILED = "FAILED"
|
|
206
|
+
CANCEL_FAILED = "CANCEL_FAILED"
|
|
207
|
+
|
|
208
|
+
# IN-FLOW
|
|
209
|
+
PENDING = "PENDING"
|
|
210
|
+
CANCELING = "CANCELING"
|
|
211
|
+
|
|
212
|
+
# OPEN
|
|
213
|
+
ACCEPTED = "ACCEPTED"
|
|
214
|
+
PARTIALLY_FILLED = "PARTIALLY_FILLED"
|
|
215
|
+
|
|
216
|
+
# CLOSED
|
|
217
|
+
FILLED = "FILLED"
|
|
218
|
+
CANCELED = "CANCELED"
|
|
219
|
+
EXPIRED = "EXPIRED"
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class ExchangeType(Enum):
|
|
223
|
+
BINANCE = "binance"
|
|
224
|
+
OKX = "okx"
|
|
225
|
+
BYBIT = "bybit"
|
|
226
|
+
HYPERLIQUID = "hyperliquid"
|
|
227
|
+
BITGET = "bitget"
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class AccountType(Enum):
|
|
231
|
+
pass
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class OrderType(Enum):
|
|
235
|
+
MARKET = "MARKET"
|
|
236
|
+
LIMIT = "LIMIT"
|
|
237
|
+
TAKE_PROFIT_MARKET = "TAKE_PROFIT_MARKET"
|
|
238
|
+
TAKE_PROFIT_LIMIT = "TAKE_PROFIT_LIMIT"
|
|
239
|
+
STOP_LOSS_MARKET = "STOP_LOSS_MARKET"
|
|
240
|
+
STOP_LOSS_LIMIT = "STOP_LOSS_LIMIT"
|
|
241
|
+
POST_ONLY = "POST_ONLY"
|
|
242
|
+
|
|
243
|
+
@property
|
|
244
|
+
def is_take_profit(self) -> bool:
|
|
245
|
+
return self in (OrderType.TAKE_PROFIT_MARKET, OrderType.TAKE_PROFIT_LIMIT)
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def is_stop_loss(self) -> bool:
|
|
249
|
+
return self in (OrderType.STOP_LOSS_MARKET, OrderType.STOP_LOSS_LIMIT)
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def is_market(self) -> bool:
|
|
253
|
+
return self in (
|
|
254
|
+
OrderType.MARKET,
|
|
255
|
+
OrderType.TAKE_PROFIT_MARKET,
|
|
256
|
+
OrderType.STOP_LOSS_MARKET,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def is_limit(self) -> bool:
|
|
261
|
+
return self in (
|
|
262
|
+
OrderType.LIMIT,
|
|
263
|
+
OrderType.TAKE_PROFIT_LIMIT,
|
|
264
|
+
OrderType.STOP_LOSS_LIMIT,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
@property
|
|
268
|
+
def is_post_only(self) -> bool:
|
|
269
|
+
return self == OrderType.POST_ONLY
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class TriggerType(Enum):
|
|
273
|
+
LAST_PRICE = "LAST_PRICE"
|
|
274
|
+
MARK_PRICE = "MARK_PRICE"
|
|
275
|
+
INDEX_PRICE = "INDEX_PRICE"
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class OrderSide(Enum):
|
|
279
|
+
BUY = "BUY"
|
|
280
|
+
SELL = "SELL"
|
|
281
|
+
|
|
282
|
+
@property
|
|
283
|
+
def is_buy(self) -> bool:
|
|
284
|
+
return self == OrderSide.BUY
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def is_sell(self) -> bool:
|
|
288
|
+
return self == OrderSide.SELL
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class TimeInForce(Enum):
|
|
292
|
+
GTC = "GTC"
|
|
293
|
+
IOC = "IOC"
|
|
294
|
+
FOK = "FOK"
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
class PositionSide(Enum):
|
|
298
|
+
LONG = "LONG"
|
|
299
|
+
SHORT = "SHORT"
|
|
300
|
+
FLAT = "FLAT"
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
def is_long(self) -> bool:
|
|
304
|
+
return self == PositionSide.LONG
|
|
305
|
+
|
|
306
|
+
@property
|
|
307
|
+
def is_short(self) -> bool:
|
|
308
|
+
return self == PositionSide.SHORT
|
|
309
|
+
|
|
310
|
+
@property
|
|
311
|
+
def is_flat(self) -> bool:
|
|
312
|
+
return self == PositionSide.FLAT
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
class InstrumentType(Enum):
|
|
316
|
+
SPOT = "spot"
|
|
317
|
+
MARGIN = "margin"
|
|
318
|
+
FUTURE = "future"
|
|
319
|
+
OPTION = "option"
|
|
320
|
+
SWAP = "swap"
|
|
321
|
+
LINEAR = "linear"
|
|
322
|
+
INVERSE = "inverse"
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
class OptionType(Enum):
|
|
326
|
+
CALL = "call"
|
|
327
|
+
PUT = "put"
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
STATUS_TRANSITIONS: Dict[OrderStatus, List[OrderStatus]] = {
|
|
331
|
+
OrderStatus.PENDING: [
|
|
332
|
+
OrderStatus.PENDING,
|
|
333
|
+
OrderStatus.CANCELED,
|
|
334
|
+
OrderStatus.CANCELING,
|
|
335
|
+
OrderStatus.ACCEPTED,
|
|
336
|
+
OrderStatus.PARTIALLY_FILLED,
|
|
337
|
+
OrderStatus.FILLED,
|
|
338
|
+
OrderStatus.CANCEL_FAILED,
|
|
339
|
+
OrderStatus.FAILED, # e.g., rejected by exchange we mark as failed
|
|
340
|
+
],
|
|
341
|
+
OrderStatus.CANCELING: [
|
|
342
|
+
OrderStatus.ACCEPTED,
|
|
343
|
+
OrderStatus.CANCELED,
|
|
344
|
+
OrderStatus.PARTIALLY_FILLED,
|
|
345
|
+
OrderStatus.FILLED,
|
|
346
|
+
OrderStatus.EXPIRED,
|
|
347
|
+
],
|
|
348
|
+
OrderStatus.ACCEPTED: [
|
|
349
|
+
OrderStatus.ACCEPTED, # for modify order, pending -> accepted -> accepted -> (not allowed) -> pending
|
|
350
|
+
OrderStatus.PARTIALLY_FILLED,
|
|
351
|
+
OrderStatus.FILLED,
|
|
352
|
+
OrderStatus.CANCELING,
|
|
353
|
+
OrderStatus.CANCELED,
|
|
354
|
+
OrderStatus.EXPIRED,
|
|
355
|
+
OrderStatus.CANCEL_FAILED,
|
|
356
|
+
],
|
|
357
|
+
OrderStatus.PARTIALLY_FILLED: [
|
|
358
|
+
OrderStatus.ACCEPTED, # for modify order, accepted -> partially filled -> accepted -> (not allowed) -> pending
|
|
359
|
+
OrderStatus.PARTIALLY_FILLED,
|
|
360
|
+
OrderStatus.FILLED,
|
|
361
|
+
OrderStatus.CANCELING,
|
|
362
|
+
OrderStatus.CANCELED,
|
|
363
|
+
OrderStatus.EXPIRED,
|
|
364
|
+
OrderStatus.CANCEL_FAILED,
|
|
365
|
+
],
|
|
366
|
+
OrderStatus.CANCEL_FAILED: [
|
|
367
|
+
OrderStatus.CANCEL_FAILED,
|
|
368
|
+
OrderStatus.ACCEPTED,
|
|
369
|
+
OrderStatus.PARTIALLY_FILLED,
|
|
370
|
+
OrderStatus.CANCELING,
|
|
371
|
+
OrderStatus.CANCELED,
|
|
372
|
+
OrderStatus.FILLED,
|
|
373
|
+
OrderStatus.EXPIRED,
|
|
374
|
+
],
|
|
375
|
+
OrderStatus.FILLED: [],
|
|
376
|
+
OrderStatus.CANCELED: [],
|
|
377
|
+
OrderStatus.EXPIRED: [],
|
|
378
|
+
OrderStatus.FAILED: [],
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
class DataType(Enum):
|
|
383
|
+
BOOKL1 = "bookl1"
|
|
384
|
+
BOOKL2 = "bookl2"
|
|
385
|
+
TRADE = "trade"
|
|
386
|
+
KLINE = "kline"
|
|
387
|
+
VOLUME_KLINE = "volume_kline"
|
|
388
|
+
MARK_PRICE = "mark_price"
|
|
389
|
+
FUNDING_RATE = "funding_rate"
|
|
390
|
+
INDEX_PRICE = "index_price"
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
class StorageType(Enum):
|
|
394
|
+
SQLITE = "sqlite"
|
|
395
|
+
POSTGRESQL = "postgresql"
|
|
396
|
+
MEMORY = "memory"
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
class ParamBackend(Enum):
|
|
400
|
+
MEMORY = "memory"
|
|
401
|
+
REDIS = "redis"
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
class RateLimiter:
|
|
405
|
+
pass
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
class ConfigType(TypedDict):
|
|
409
|
+
apiKey: str
|
|
410
|
+
secret: str
|
|
411
|
+
exchange_id: str
|
|
412
|
+
sandbox: bool
|
|
413
|
+
password: NotRequired[str]
|
|
File without changes
|