exchanges-wrapper 2.1.34__tar.gz → 2.1.35__tar.gz
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.
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/PKG-INFO +7 -2
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/README.md +6 -1
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/__init__.py +1 -1
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/client.py +21 -271
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/exch_srv.py +4 -10
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/parsers/bybit.py +2 -15
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/parsers/huobi.py +2 -15
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/LICENSE.md +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/definitions.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/errors.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/events.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/exch_srv_cfg.toml.template +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/http_client.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/lib.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/martin/__init__.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/parsers/bitfinex.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/parsers/okx.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/proto/martin.proto +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/web_sockets.py +0 -0
- {exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exchanges-wrapper
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.35
|
|
4
4
|
Summary: REST API and WebSocket asyncio wrapper with grpc powered multiplexer server
|
|
5
5
|
Author-email: Thomas Marchand <thomas.marchand@tuta.io>, Jerry Fedorenko <jerry.fedorenko@yahoo.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -36,6 +36,7 @@ Project-URL: Source, https://github.com/DogsTailFarmer/exchanges-wrapper
|
|
|
36
36
|
<a href="https://pepy.tech/project/exchanges-wrapper" target="_blank"><img alt="Downloads" title="Downloads" src="https://static.pepy.tech/badge/exchanges-wrapper/month"/></a>
|
|
37
37
|
***
|
|
38
38
|
On `Binance`: now API key type [Ed25519](https://www.binance.com/en/support/faq/detail/6b9a63f1e3384cf48a2eedb82767a69a) is used instead of `HMAC`
|
|
39
|
+
|
|
39
40
|
From `2.1.34` must be updated `exch_srv_cfg.toml` from `exchanges_wrapper/exch_srv_cfg.toml.template`
|
|
40
41
|
***
|
|
41
42
|
|
|
@@ -77,9 +78,13 @@ at real bidding. First, run applications on the [Binance Spot Test Network](http
|
|
|
77
78
|
## Get started
|
|
78
79
|
### Prepare exchange account
|
|
79
80
|
Create account on [Binance](https://accounts.binance.com/en/register?ref=FXQ6HY5O) and get 10% discount on all trading fee
|
|
80
|
-
|
|
81
|
+
|
|
82
|
+
Create account on [HTX](https://www.htx.com/invite/en-us/1f?invite_code=9uaw3223)
|
|
83
|
+
|
|
81
84
|
Create account on [Bitfinex](https://www.bitfinex.com/sign-up?refcode=v_4az2nCP) and get 6% rebate fee
|
|
85
|
+
|
|
82
86
|
Create account on [OKX](https://okx.com/join/2607649) and will be in for the chance to earn up to 100 USDT
|
|
87
|
+
|
|
83
88
|
Create account on [Bybit](https://www.bybit.com/invite?ref=9KEW1K) and get exclusive referral rewards
|
|
84
89
|
|
|
85
90
|
Also, you can start strategy on [Hetzner](https://hetzner.cloud/?ref=uFdrF8nsdGMc) cloud VPS only for 4.75 € per month
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
<a href="https://pepy.tech/project/exchanges-wrapper" target="_blank"><img alt="Downloads" title="Downloads" src="https://static.pepy.tech/badge/exchanges-wrapper/month"/></a>
|
|
14
14
|
***
|
|
15
15
|
On `Binance`: now API key type [Ed25519](https://www.binance.com/en/support/faq/detail/6b9a63f1e3384cf48a2eedb82767a69a) is used instead of `HMAC`
|
|
16
|
+
|
|
16
17
|
From `2.1.34` must be updated `exch_srv_cfg.toml` from `exchanges_wrapper/exch_srv_cfg.toml.template`
|
|
17
18
|
***
|
|
18
19
|
|
|
@@ -54,9 +55,13 @@ at real bidding. First, run applications on the [Binance Spot Test Network](http
|
|
|
54
55
|
## Get started
|
|
55
56
|
### Prepare exchange account
|
|
56
57
|
Create account on [Binance](https://accounts.binance.com/en/register?ref=FXQ6HY5O) and get 10% discount on all trading fee
|
|
57
|
-
|
|
58
|
+
|
|
59
|
+
Create account on [HTX](https://www.htx.com/invite/en-us/1f?invite_code=9uaw3223)
|
|
60
|
+
|
|
58
61
|
Create account on [Bitfinex](https://www.bitfinex.com/sign-up?refcode=v_4az2nCP) and get 6% rebate fee
|
|
62
|
+
|
|
59
63
|
Create account on [OKX](https://okx.com/join/2607649) and will be in for the chance to earn up to 100 USDT
|
|
64
|
+
|
|
60
65
|
Create account on [Bybit](https://www.bybit.com/invite?ref=9KEW1K) and get exclusive referral rewards
|
|
61
66
|
|
|
62
67
|
Also, you can start strategy on [Hetzner](https://hetzner.cloud/?ref=uFdrF8nsdGMc) cloud VPS only for 4.75 € per month
|
|
@@ -12,7 +12,7 @@ __maintainer__ = "Jerry Fedorenko"
|
|
|
12
12
|
__contact__ = "https://github.com/DogsTailFarmer"
|
|
13
13
|
__email__ = "jerry.fedorenko@yahoo.com"
|
|
14
14
|
__credits__ = ["https://github.com/DanyaSWorlD"]
|
|
15
|
-
__version__ = "2.1.
|
|
15
|
+
__version__ = "2.1.35"
|
|
16
16
|
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
import shutil
|
|
@@ -146,7 +146,7 @@ class Client:
|
|
|
146
146
|
logger.info(f"Info for {self.exchange}:{symbol} loaded successfully")
|
|
147
147
|
|
|
148
148
|
async def close(self):
|
|
149
|
-
if self.http.session:
|
|
149
|
+
if self.http and self.http.session:
|
|
150
150
|
await self.http.session.close()
|
|
151
151
|
|
|
152
152
|
@property
|
|
@@ -558,29 +558,6 @@ class Client:
|
|
|
558
558
|
"/api/v3/historicalTrades", params=params, signed=False
|
|
559
559
|
)
|
|
560
560
|
|
|
561
|
-
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list
|
|
562
|
-
async def fetch_aggregate_trades_list(
|
|
563
|
-
self, symbol, from_id=None, start_time=None, end_time=None, limit=500
|
|
564
|
-
):
|
|
565
|
-
self.assert_symbol(symbol)
|
|
566
|
-
if limit == 500:
|
|
567
|
-
params = {"symbol": symbol}
|
|
568
|
-
elif 0 < limit <= 1000:
|
|
569
|
-
params = {"symbol": symbol, "limit": limit}
|
|
570
|
-
else:
|
|
571
|
-
raise ValueError(
|
|
572
|
-
f"{limit} is not a valid limit. A valid limit should be > 0 and <= to 1000."
|
|
573
|
-
)
|
|
574
|
-
if from_id:
|
|
575
|
-
params["fromId"] = from_id
|
|
576
|
-
if start_time:
|
|
577
|
-
params["startTime"] = start_time
|
|
578
|
-
if end_time:
|
|
579
|
-
params["endTime"] = end_time
|
|
580
|
-
return await self.http.send_api_call(
|
|
581
|
-
"/api/v3/aggTrades", params=params, signed=False
|
|
582
|
-
)
|
|
583
|
-
|
|
584
561
|
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#klinecandlestick-data
|
|
585
562
|
async def fetch_klines(self, symbol, interval, start_time=None, end_time=None, limit=500):
|
|
586
563
|
self.assert_symbol(symbol)
|
|
@@ -622,8 +599,6 @@ class Client:
|
|
|
622
599
|
endpoint=self.endpoint_api_public,
|
|
623
600
|
**params
|
|
624
601
|
)
|
|
625
|
-
if res and isinstance(res, list):
|
|
626
|
-
res.sort(reverse=False)
|
|
627
602
|
if res:
|
|
628
603
|
binance_res = bfx.klines(res, interval)
|
|
629
604
|
elif self.exchange == 'huobi':
|
|
@@ -634,14 +609,12 @@ class Client:
|
|
|
634
609
|
"market/history/kline",
|
|
635
610
|
**params,
|
|
636
611
|
)
|
|
637
|
-
# print(f"fetch_klines.res: {res[::-1]}")
|
|
638
612
|
binance_res = hbp.klines(res[::-1], interval)
|
|
639
613
|
elif self.exchange == 'okx':
|
|
640
614
|
params = {'instId': self.symbol_to_okx(symbol),
|
|
641
615
|
'bar': interval,
|
|
642
616
|
'limit': str(min(limit, 300))}
|
|
643
617
|
res = await self.http.send_api_call("/api/v5/market/candles", **params)
|
|
644
|
-
res.sort(reverse=False)
|
|
645
618
|
binance_res = okx.klines(res, interval)
|
|
646
619
|
elif self.exchange == 'bybit':
|
|
647
620
|
params = {"category": "spot", "symbol": symbol, "interval": interval, "limit": limit}
|
|
@@ -651,20 +624,12 @@ class Client:
|
|
|
651
624
|
params["end"] = end_time
|
|
652
625
|
res, _ = await self.http.send_api_call("/v5/market/kline", **params)
|
|
653
626
|
res = res.get("list", [])
|
|
654
|
-
res.sort(reverse=False)
|
|
655
627
|
binance_res = bbt.klines(res, interval)
|
|
656
|
-
# print(f"fetch_klines.binance_res: {binance_res}")
|
|
657
|
-
return binance_res
|
|
658
628
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
return
|
|
663
|
-
"/api/v3/avgPrice",
|
|
664
|
-
params={"symbol": symbol},
|
|
665
|
-
signed=False,
|
|
666
|
-
send_api_key=False,
|
|
667
|
-
)
|
|
629
|
+
if self.exchange not in ('binance', 'huobi'):
|
|
630
|
+
binance_res.sort()
|
|
631
|
+
|
|
632
|
+
return binance_res
|
|
668
633
|
|
|
669
634
|
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#24hr-ticker-price-change-statistics
|
|
670
635
|
async def fetch_ticker_price_change_statistics(self, symbol=None):
|
|
@@ -791,7 +756,6 @@ class Client:
|
|
|
791
756
|
price=None,
|
|
792
757
|
new_client_order_id=None,
|
|
793
758
|
response_type=None,
|
|
794
|
-
receive_window=None,
|
|
795
759
|
test=False,
|
|
796
760
|
):
|
|
797
761
|
self.assert_symbol(symbol)
|
|
@@ -811,8 +775,6 @@ class Client:
|
|
|
811
775
|
params["newClientOrderId"] = new_client_order_id
|
|
812
776
|
if response_type:
|
|
813
777
|
params["newOrderRespType"] = response_type
|
|
814
|
-
if receive_window:
|
|
815
|
-
params["recvWindow"] = receive_window
|
|
816
778
|
binance_res = await self.user_session.handle_request(
|
|
817
779
|
trade_id,
|
|
818
780
|
"order.place",
|
|
@@ -927,7 +889,6 @@ class Client:
|
|
|
927
889
|
symbol,
|
|
928
890
|
order_id=None,
|
|
929
891
|
origin_client_order_id=None,
|
|
930
|
-
receive_window=None,
|
|
931
892
|
response_type=None,
|
|
932
893
|
):
|
|
933
894
|
self.assert_symbol(symbol)
|
|
@@ -941,8 +902,6 @@ class Client:
|
|
|
941
902
|
params["orderId"] = order_id
|
|
942
903
|
else:
|
|
943
904
|
params["origClientOrderId"] = origin_client_order_id
|
|
944
|
-
if receive_window:
|
|
945
|
-
params["recvWindow"] = receive_window
|
|
946
905
|
b_res = await self.user_session.handle_request(
|
|
947
906
|
trade_id,
|
|
948
907
|
"order.status",
|
|
@@ -1026,8 +985,7 @@ class Client:
|
|
|
1026
985
|
symbol,
|
|
1027
986
|
order_id=None,
|
|
1028
987
|
origin_client_order_id=None,
|
|
1029
|
-
new_client_order_id=None
|
|
1030
|
-
receive_window=None,
|
|
988
|
+
new_client_order_id=None
|
|
1031
989
|
):
|
|
1032
990
|
self.assert_symbol(symbol)
|
|
1033
991
|
binance_res = {}
|
|
@@ -1043,8 +1001,6 @@ class Client:
|
|
|
1043
1001
|
params["originClientOrderId"] = origin_client_order_id
|
|
1044
1002
|
if new_client_order_id:
|
|
1045
1003
|
params["newClientOrderId"] = origin_client_order_id
|
|
1046
|
-
if receive_window:
|
|
1047
|
-
params["recvWindow"] = receive_window
|
|
1048
1004
|
binance_res = await self.user_session.handle_request(
|
|
1049
1005
|
trade_id,
|
|
1050
1006
|
"order.cancel",
|
|
@@ -1139,13 +1095,11 @@ class Client:
|
|
|
1139
1095
|
return binance_res
|
|
1140
1096
|
|
|
1141
1097
|
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#cancel-all-open-orders-on-a-symbol-trade
|
|
1142
|
-
async def cancel_all_orders(self, trade_id, symbol
|
|
1098
|
+
async def cancel_all_orders(self, trade_id, symbol):
|
|
1143
1099
|
self.assert_symbol(symbol)
|
|
1144
1100
|
binance_res = []
|
|
1145
1101
|
if self.exchange == 'binance':
|
|
1146
1102
|
params = {"symbol": symbol}
|
|
1147
|
-
if receive_window:
|
|
1148
|
-
params["recvWindow"] = receive_window
|
|
1149
1103
|
binance_res = await self.user_session.handle_request(
|
|
1150
1104
|
trade_id,
|
|
1151
1105
|
"openOrders.cancelAll",
|
|
@@ -1161,7 +1115,7 @@ class Client:
|
|
|
1161
1115
|
signed=True,
|
|
1162
1116
|
)
|
|
1163
1117
|
elif self.exchange == 'bitfinex':
|
|
1164
|
-
orders = await self.fetch_open_orders(trade_id, symbol,
|
|
1118
|
+
orders = await self.fetch_open_orders(trade_id, symbol, response_type=True)
|
|
1165
1119
|
orders_id = [order.get('orderId') for order in orders]
|
|
1166
1120
|
params = {'id': orders_id}
|
|
1167
1121
|
res = await self.user_session.handle_request(trade_id, "oc_multi", _params=params)
|
|
@@ -1179,7 +1133,7 @@ class Client:
|
|
|
1179
1133
|
else:
|
|
1180
1134
|
logger.debug(f"bitfinex: cancel_all_orders.res: {res}")
|
|
1181
1135
|
elif self.exchange == 'huobi':
|
|
1182
|
-
orders = await self.fetch_open_orders(trade_id, symbol,
|
|
1136
|
+
orders = await self.fetch_open_orders(trade_id, symbol, response_type=True)
|
|
1183
1137
|
orders_id = [str(order.get('orderId')) for order in orders]
|
|
1184
1138
|
params = {'order-ids': orders_id}
|
|
1185
1139
|
|
|
@@ -1202,7 +1156,6 @@ class Client:
|
|
|
1202
1156
|
orders = await self.fetch_open_orders(
|
|
1203
1157
|
trade_id,
|
|
1204
1158
|
symbol,
|
|
1205
|
-
receive_window=receive_window,
|
|
1206
1159
|
response_type=True
|
|
1207
1160
|
)
|
|
1208
1161
|
_symbol = self.symbol_to_okx(symbol)
|
|
@@ -1261,13 +1214,11 @@ class Client:
|
|
|
1261
1214
|
return binance_res
|
|
1262
1215
|
|
|
1263
1216
|
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#current-open-orders-user_data
|
|
1264
|
-
async def fetch_open_orders(self, trade_id, symbol,
|
|
1217
|
+
async def fetch_open_orders(self, trade_id, symbol, response_type=None):
|
|
1265
1218
|
self.assert_symbol(symbol)
|
|
1266
1219
|
binance_res = []
|
|
1267
1220
|
if self.exchange == 'binance':
|
|
1268
1221
|
params = {"symbol": symbol}
|
|
1269
|
-
if receive_window:
|
|
1270
|
-
params["recvWindow"] = receive_window
|
|
1271
1222
|
binance_res = await self.user_session.handle_request(
|
|
1272
1223
|
trade_id,
|
|
1273
1224
|
"openOrders.status",
|
|
@@ -1316,204 +1267,12 @@ class Client:
|
|
|
1316
1267
|
binance_res = bbt.orders(res.get('list', []), response_type=response_type)
|
|
1317
1268
|
return binance_res
|
|
1318
1269
|
|
|
1319
|
-
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#all-orders-user_data
|
|
1320
|
-
async def fetch_all_orders(
|
|
1321
|
-
self,
|
|
1322
|
-
symbol,
|
|
1323
|
-
order_id=None,
|
|
1324
|
-
start_time=None,
|
|
1325
|
-
end_time=None,
|
|
1326
|
-
limit=500,
|
|
1327
|
-
receive_window=None,
|
|
1328
|
-
):
|
|
1329
|
-
self.assert_symbol(symbol)
|
|
1330
|
-
if limit == 500:
|
|
1331
|
-
params = {"symbol": symbol}
|
|
1332
|
-
elif 0 < limit <= 1000:
|
|
1333
|
-
params = {"symbol": symbol, "limit": limit}
|
|
1334
|
-
else:
|
|
1335
|
-
raise ValueError(
|
|
1336
|
-
f"{limit} is not a valid limit. A valid limit should be > 0 and <= to 1000."
|
|
1337
|
-
)
|
|
1338
|
-
if order_id:
|
|
1339
|
-
params["orderId"] = order_id
|
|
1340
|
-
if start_time:
|
|
1341
|
-
params["startTime"] = start_time
|
|
1342
|
-
if end_time:
|
|
1343
|
-
params["endTime"] = end_time
|
|
1344
|
-
if receive_window:
|
|
1345
|
-
params["recvWindow"] = receive_window
|
|
1346
|
-
return await self.http.send_api_call(
|
|
1347
|
-
"/api/v3/allOrders",
|
|
1348
|
-
params=params,
|
|
1349
|
-
signed=True,
|
|
1350
|
-
)
|
|
1351
|
-
|
|
1352
|
-
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#new-oco-trade
|
|
1353
|
-
async def create_oco(
|
|
1354
|
-
self,
|
|
1355
|
-
symbol,
|
|
1356
|
-
side,
|
|
1357
|
-
quantity,
|
|
1358
|
-
price,
|
|
1359
|
-
stop_price,
|
|
1360
|
-
list_client_order_id=None,
|
|
1361
|
-
limit_iceberg_quantity=None,
|
|
1362
|
-
stop_client_order_id=None,
|
|
1363
|
-
stop_limit_price=None,
|
|
1364
|
-
stop_iceberg_quantity=None,
|
|
1365
|
-
stop_limit_time_in_force=None,
|
|
1366
|
-
response_type=None,
|
|
1367
|
-
receive_window=None,
|
|
1368
|
-
):
|
|
1369
|
-
self.assert_symbol(symbol)
|
|
1370
|
-
side = self.enum_to_value(side)
|
|
1371
|
-
if not side:
|
|
1372
|
-
raise ValueError("This query requires a side.")
|
|
1373
|
-
if not quantity:
|
|
1374
|
-
raise ValueError("This query requires a quantity.")
|
|
1375
|
-
if not price:
|
|
1376
|
-
raise ValueError("This query requires a price.")
|
|
1377
|
-
if not stop_price:
|
|
1378
|
-
raise ValueError("This query requires a stop_price.")
|
|
1379
|
-
|
|
1380
|
-
params = {
|
|
1381
|
-
"symbol": symbol,
|
|
1382
|
-
"side": side,
|
|
1383
|
-
"quantity": self.refine_amount(symbol, quantity),
|
|
1384
|
-
"price": self.refine_price(symbol, price),
|
|
1385
|
-
"stopPrice": self.refine_price(symbol, stop_price),
|
|
1386
|
-
"stopLimitPrice": self.refine_price(symbol, stop_limit_price),
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
if list_client_order_id:
|
|
1390
|
-
params["listClientOrderId"] = list_client_order_id
|
|
1391
|
-
if limit_iceberg_quantity:
|
|
1392
|
-
params["limitIcebergQty"] = self.refine_amount(
|
|
1393
|
-
symbol, limit_iceberg_quantity
|
|
1394
|
-
)
|
|
1395
|
-
if stop_client_order_id:
|
|
1396
|
-
params["stopLimitPrice"] = self.refine_price(symbol, stop_client_order_id)
|
|
1397
|
-
if stop_iceberg_quantity:
|
|
1398
|
-
params["stopIcebergQty"] = self.refine_amount(symbol, stop_iceberg_quantity)
|
|
1399
|
-
if stop_limit_time_in_force:
|
|
1400
|
-
params["stopLimitTimeInForce"] = stop_limit_time_in_force
|
|
1401
|
-
if response_type:
|
|
1402
|
-
params["newOrderRespType"] = response_type
|
|
1403
|
-
if receive_window:
|
|
1404
|
-
params["recvWindow"] = receive_window
|
|
1405
|
-
|
|
1406
|
-
return await self.http.send_api_call(
|
|
1407
|
-
"/api/v3/order/oco", "POST", data=params, signed=True
|
|
1408
|
-
)
|
|
1409
|
-
|
|
1410
|
-
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#query-oco-user_data
|
|
1411
|
-
async def fetch_oco( # lgtm [py/similar-function]
|
|
1412
|
-
self,
|
|
1413
|
-
symbol,
|
|
1414
|
-
order_list_id=None,
|
|
1415
|
-
origin_client_order_id=None,
|
|
1416
|
-
receive_window=None,
|
|
1417
|
-
):
|
|
1418
|
-
self.assert_symbol(symbol)
|
|
1419
|
-
params = {"symbol": symbol}
|
|
1420
|
-
if not order_list_id and not origin_client_order_id:
|
|
1421
|
-
raise ValueError(
|
|
1422
|
-
"This query requires an order_id or an origin_client_order_id."
|
|
1423
|
-
)
|
|
1424
|
-
if order_list_id:
|
|
1425
|
-
params["orderListId"] = order_list_id
|
|
1426
|
-
if origin_client_order_id:
|
|
1427
|
-
params["originClientOrderId"] = origin_client_order_id
|
|
1428
|
-
if receive_window:
|
|
1429
|
-
params["recvWindow"] = receive_window
|
|
1430
|
-
|
|
1431
|
-
return await self.http.send_api_call(
|
|
1432
|
-
"/api/v3/orderList",
|
|
1433
|
-
params=params,
|
|
1434
|
-
signed=True,
|
|
1435
|
-
)
|
|
1436
|
-
|
|
1437
|
-
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#cancel-oco-trade
|
|
1438
|
-
async def cancel_oco( # lgtm [py/similar-function]
|
|
1439
|
-
self,
|
|
1440
|
-
symbol,
|
|
1441
|
-
order_list_id=None,
|
|
1442
|
-
list_client_order_id=None,
|
|
1443
|
-
new_client_order_id=None,
|
|
1444
|
-
receive_window=None,
|
|
1445
|
-
):
|
|
1446
|
-
self.assert_symbol(symbol)
|
|
1447
|
-
params = {"symbol": symbol}
|
|
1448
|
-
if not order_list_id and not list_client_order_id:
|
|
1449
|
-
raise ValueError(
|
|
1450
|
-
"This query requires a order_list_id or a list_client_order_id."
|
|
1451
|
-
)
|
|
1452
|
-
if order_list_id:
|
|
1453
|
-
params["orderListId"] = order_list_id
|
|
1454
|
-
if list_client_order_id:
|
|
1455
|
-
params["listClientOrderId"] = list_client_order_id
|
|
1456
|
-
if new_client_order_id:
|
|
1457
|
-
params["newClientOrderId"] = new_client_order_id
|
|
1458
|
-
if receive_window:
|
|
1459
|
-
params["recvWindow"] = receive_window
|
|
1460
|
-
|
|
1461
|
-
return await self.http.send_api_call(
|
|
1462
|
-
"/api/v3/order/oco",
|
|
1463
|
-
"DELETE",
|
|
1464
|
-
params=params,
|
|
1465
|
-
signed=True,
|
|
1466
|
-
)
|
|
1467
|
-
|
|
1468
|
-
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#query-open-oco-user_data
|
|
1469
|
-
async def fetch_open_oco(self, receive_window=None):
|
|
1470
|
-
params = {}
|
|
1471
|
-
|
|
1472
|
-
if receive_window:
|
|
1473
|
-
params["recvWindow"] = receive_window
|
|
1474
|
-
|
|
1475
|
-
return await self.http.send_api_call(
|
|
1476
|
-
"/api/v3/openOrderList",
|
|
1477
|
-
params=params,
|
|
1478
|
-
signed=True,
|
|
1479
|
-
)
|
|
1480
|
-
|
|
1481
|
-
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#query-all-oco-user_data
|
|
1482
|
-
async def fetch_all_oco(
|
|
1483
|
-
self,
|
|
1484
|
-
from_id=None,
|
|
1485
|
-
start_time=None,
|
|
1486
|
-
end_time=None,
|
|
1487
|
-
limit=None,
|
|
1488
|
-
receive_window=None,
|
|
1489
|
-
):
|
|
1490
|
-
params = {}
|
|
1491
|
-
|
|
1492
|
-
if from_id:
|
|
1493
|
-
params["fromId"] = from_id
|
|
1494
|
-
if start_time:
|
|
1495
|
-
params["startTime"] = start_time
|
|
1496
|
-
if end_time:
|
|
1497
|
-
params["endTime"] = end_time
|
|
1498
|
-
if limit:
|
|
1499
|
-
params["limit"] = limit
|
|
1500
|
-
if receive_window:
|
|
1501
|
-
params["recvWindow"] = receive_window
|
|
1502
|
-
|
|
1503
|
-
return await self.http.send_api_call(
|
|
1504
|
-
"/api/v3/allOrderList",
|
|
1505
|
-
params=params,
|
|
1506
|
-
signed=True,
|
|
1507
|
-
)
|
|
1508
|
-
|
|
1509
1270
|
# https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#account-information-user_data
|
|
1510
|
-
async def fetch_account_information(self, trade_id
|
|
1271
|
+
async def fetch_account_information(self, trade_id):
|
|
1511
1272
|
params = {}
|
|
1512
1273
|
binance_res = {}
|
|
1513
1274
|
if self.exchange == 'binance':
|
|
1514
1275
|
params["omitZeroBalances"] = "true"
|
|
1515
|
-
if receive_window:
|
|
1516
|
-
params["recvWindow"] = receive_window
|
|
1517
1276
|
binance_res = await self.user_session.handle_request(
|
|
1518
1277
|
trade_id,
|
|
1519
1278
|
"account.status",
|
|
@@ -1534,23 +1293,23 @@ class Client:
|
|
|
1534
1293
|
signed=True
|
|
1535
1294
|
)
|
|
1536
1295
|
if res:
|
|
1537
|
-
binance_res = bfx.
|
|
1296
|
+
binance_res = bfx.account_balances(res)
|
|
1538
1297
|
elif self.exchange == 'huobi':
|
|
1539
1298
|
res = await self.http.send_api_call(f"v1/account/accounts/{self.account_id}/balance", signed=True)
|
|
1540
|
-
binance_res = hbp.
|
|
1299
|
+
binance_res = hbp.account_balances(res.get('list'))
|
|
1541
1300
|
elif self.exchange == 'okx':
|
|
1542
1301
|
res = await self.http.send_api_call("/api/v5/account/balance", signed=True)
|
|
1543
|
-
binance_res = okx.
|
|
1302
|
+
binance_res = okx.account_balances(res[0].get('details'))
|
|
1544
1303
|
elif self.exchange == 'bybit':
|
|
1545
1304
|
params = {'accountType': 'UNIFIED'}
|
|
1546
|
-
res,
|
|
1547
|
-
binance_res = bbt.
|
|
1305
|
+
res, _ = await self.http.send_api_call("/v5/account/wallet-balance", signed=True, **params)
|
|
1306
|
+
binance_res = bbt.account_balances(res["list"][0]["coin"])
|
|
1548
1307
|
# logger.info(f"fetch_account_information.binance_res: {trade_id}: {binance_res}")
|
|
1549
1308
|
return binance_res
|
|
1550
1309
|
|
|
1551
1310
|
# https://binance-docs.github.io/apidocs/spot/en/#funding-wallet-user_data
|
|
1552
1311
|
# Not can be used for Spot Test Network, for real SPOT market only
|
|
1553
|
-
async def fetch_funding_wallet(self, asset=None, need_btc_valuation=None
|
|
1312
|
+
async def fetch_funding_wallet(self, asset=None, need_btc_valuation=None):
|
|
1554
1313
|
binance_res = []
|
|
1555
1314
|
if self.exchange == 'binance':
|
|
1556
1315
|
params = {}
|
|
@@ -1558,8 +1317,6 @@ class Client:
|
|
|
1558
1317
|
params["asset"] = asset
|
|
1559
1318
|
if need_btc_valuation:
|
|
1560
1319
|
params["needBtcValuation"] = "true"
|
|
1561
|
-
if receive_window:
|
|
1562
|
-
params["recvWindow"] = receive_window
|
|
1563
1320
|
binance_res = await self.http.send_api_call(
|
|
1564
1321
|
"/sapi/v1/asset/get-funding-asset",
|
|
1565
1322
|
method="POST",
|
|
@@ -1590,12 +1347,10 @@ class Client:
|
|
|
1590
1347
|
return binance_res
|
|
1591
1348
|
|
|
1592
1349
|
# https://developers.binance.com/docs/sub_account/asset-management/Transfer-to-Sub-account-of-Same-Master
|
|
1593
|
-
async def transfer_to_sub(self, email, symbol, quantity
|
|
1350
|
+
async def transfer_to_sub(self, email, symbol, quantity):
|
|
1594
1351
|
if self.exchange == 'binance':
|
|
1595
1352
|
quantity = any2str(Decimal(quantity).quantize(Decimal('0.01234567'), rounding=ROUND_HALF_DOWN))
|
|
1596
1353
|
params = {"toEmail": email, "asset": symbol, "amount": quantity}
|
|
1597
|
-
if receive_window:
|
|
1598
|
-
params["recvWindow"] = receive_window
|
|
1599
1354
|
return await self.http.send_api_call(
|
|
1600
1355
|
"/sapi/v1/sub-account/transfer/subToSub",
|
|
1601
1356
|
"POST",
|
|
@@ -1606,17 +1361,15 @@ class Client:
|
|
|
1606
1361
|
raise ValueError(f"Can't implemented for {self.exchange}")
|
|
1607
1362
|
|
|
1608
1363
|
# https://binance-docs.github.io/apidocs/spot/en/#transfer-to-master-for-sub-account
|
|
1609
|
-
async def transfer_to_master(self, symbol, quantity
|
|
1364
|
+
async def transfer_to_master(self, symbol, quantity):
|
|
1610
1365
|
_quantity = any2str(Decimal(quantity).quantize(Decimal('0.01234567'), rounding=ROUND_HALF_DOWN))
|
|
1611
1366
|
binance_res = {}
|
|
1612
1367
|
if self.exchange == 'binance':
|
|
1613
1368
|
if self.master_email:
|
|
1614
1369
|
logger.info(f"Collect {_quantity}{symbol} to {self.master_email} sub-account")
|
|
1615
|
-
binance_res = await self.transfer_to_sub(self.master_email, symbol, quantity
|
|
1370
|
+
binance_res = await self.transfer_to_sub(self.master_email, symbol, quantity)
|
|
1616
1371
|
else:
|
|
1617
1372
|
params = {"asset": symbol, "amount": _quantity}
|
|
1618
|
-
if receive_window:
|
|
1619
|
-
params["recvWindow"] = receive_window
|
|
1620
1373
|
binance_res = await self.http.send_api_call(
|
|
1621
1374
|
"/sapi/v1/sub-account/transfer/subToMaster",
|
|
1622
1375
|
"POST",
|
|
@@ -1711,8 +1464,7 @@ class Client:
|
|
|
1711
1464
|
start_time=None,
|
|
1712
1465
|
end_time=None,
|
|
1713
1466
|
from_id=None,
|
|
1714
|
-
limit=500
|
|
1715
|
-
receive_window=None,
|
|
1467
|
+
limit=500
|
|
1716
1468
|
):
|
|
1717
1469
|
self.assert_symbol(symbol)
|
|
1718
1470
|
binance_res = []
|
|
@@ -1733,8 +1485,6 @@ class Client:
|
|
|
1733
1485
|
params["endTime"] = end_time
|
|
1734
1486
|
if from_id:
|
|
1735
1487
|
params["fromId"] = from_id
|
|
1736
|
-
if receive_window:
|
|
1737
|
-
params["recvWindow"] = receive_window
|
|
1738
1488
|
binance_res = await self.user_session.handle_request(
|
|
1739
1489
|
trade_id,
|
|
1740
1490
|
"myTrades",
|
|
@@ -359,10 +359,9 @@ class Martin(mr.MartinBase):
|
|
|
359
359
|
)
|
|
360
360
|
# Send only balances
|
|
361
361
|
res = account_information.get('balances', [])
|
|
362
|
-
# Create consolidated list of asset balances from SPOT and Funding wallets
|
|
363
362
|
balances = [
|
|
364
363
|
{'asset': i['asset'], 'free': i['free'], 'locked': i['locked']}
|
|
365
|
-
for i in res if
|
|
364
|
+
for i in res if Decimal(i['free']) or Decimal(i['locked'])
|
|
366
365
|
]
|
|
367
366
|
response.items = list(map(json.dumps, balances))
|
|
368
367
|
return response
|
|
@@ -374,7 +373,6 @@ class Martin(mr.MartinBase):
|
|
|
374
373
|
res = []
|
|
375
374
|
if client.exchange in ('bitfinex', 'okx', 'bybit') \
|
|
376
375
|
or (open_client.real_market and client.exchange == 'binance'):
|
|
377
|
-
|
|
378
376
|
res, _, _ = await self.send_request(
|
|
379
377
|
'fetch_funding_wallet',
|
|
380
378
|
request,
|
|
@@ -383,7 +381,6 @@ class Martin(mr.MartinBase):
|
|
|
383
381
|
need_btc_valuation=request.need_btc_valuation,
|
|
384
382
|
receive_window=request.receive_window
|
|
385
383
|
)
|
|
386
|
-
|
|
387
384
|
response.items = list(map(json.dumps, res))
|
|
388
385
|
return response
|
|
389
386
|
|
|
@@ -507,8 +504,7 @@ class Martin(mr.MartinBase):
|
|
|
507
504
|
start_time=request.start_time,
|
|
508
505
|
end_time=None,
|
|
509
506
|
from_id=None,
|
|
510
|
-
limit=request.limit
|
|
511
|
-
receive_window=None
|
|
507
|
+
limit=request.limit
|
|
512
508
|
)
|
|
513
509
|
|
|
514
510
|
response.items = list(map(json.dumps, res))
|
|
@@ -690,7 +686,6 @@ class Martin(mr.MartinBase):
|
|
|
690
686
|
price=request.price,
|
|
691
687
|
new_client_order_id=request.new_client_order_id,
|
|
692
688
|
response_type=ResponseType.RESULT.value,
|
|
693
|
-
receive_window=None,
|
|
694
689
|
test=False
|
|
695
690
|
)
|
|
696
691
|
|
|
@@ -708,8 +703,7 @@ class Martin(mr.MartinBase):
|
|
|
708
703
|
symbol=request.symbol,
|
|
709
704
|
order_id=request.order_id,
|
|
710
705
|
origin_client_order_id=None,
|
|
711
|
-
new_client_order_id=None
|
|
712
|
-
receive_window=None
|
|
706
|
+
new_client_order_id=None
|
|
713
707
|
)
|
|
714
708
|
|
|
715
709
|
response.from_pydict(res)
|
|
@@ -788,7 +782,7 @@ class Martin(mr.MartinBase):
|
|
|
788
782
|
return response
|
|
789
783
|
|
|
790
784
|
async def client_restart(self, request: mr.MarketRequest) -> mr.SimpleResponse:
|
|
791
|
-
if session:=OpenClient.get_client(request.client_id).client.http.session:
|
|
785
|
+
if session := OpenClient.get_client(request.client_id).client.http.session:
|
|
792
786
|
await session.close()
|
|
793
787
|
OpenClient.remove_client(request.account_name)
|
|
794
788
|
return mr.SimpleResponse(success=True)
|
|
@@ -266,7 +266,7 @@ def ticker_price_change_statistics(res: dict, ts: int) -> dict:
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
|
|
269
|
-
def
|
|
269
|
+
def account_balances(res: list) -> dict:
|
|
270
270
|
balances = []
|
|
271
271
|
for asset in res:
|
|
272
272
|
locked = asset["locked"]
|
|
@@ -276,20 +276,7 @@ def account_information(res: list, ts: int) -> dict:
|
|
|
276
276
|
"free": free,
|
|
277
277
|
"locked": locked,
|
|
278
278
|
})
|
|
279
|
-
return {
|
|
280
|
-
"makerCommission": 0,
|
|
281
|
-
"takerCommission": 0,
|
|
282
|
-
"buyerCommission": 0,
|
|
283
|
-
"sellerCommission": 0,
|
|
284
|
-
"canTrade": True,
|
|
285
|
-
"canWithdraw": False,
|
|
286
|
-
"canDeposit": False,
|
|
287
|
-
"brokered": False,
|
|
288
|
-
"updateTime": ts,
|
|
289
|
-
"accountType": "SPOT",
|
|
290
|
-
"balances": balances,
|
|
291
|
-
"permissions": ["SPOT"],
|
|
292
|
-
}
|
|
279
|
+
return {"balances": balances}
|
|
293
280
|
|
|
294
281
|
|
|
295
282
|
def ticker(res: dict) -> dict:
|
|
@@ -190,7 +190,7 @@ def order_cancelled(symbol, order_id=None, origin_client_order_id=None,) -> {}:
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
|
|
193
|
-
def
|
|
193
|
+
def account_balances(res: {}) -> {}:
|
|
194
194
|
"""
|
|
195
195
|
This function parses the Huobi API response for account information and
|
|
196
196
|
returns a dictionary with relevant details.
|
|
@@ -227,20 +227,7 @@ def account_information(res: {}) -> {}:
|
|
|
227
227
|
}
|
|
228
228
|
for asset in assets
|
|
229
229
|
]
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
"makerCommission": 0,
|
|
233
|
-
"takerCommission": 0,
|
|
234
|
-
"buyerCommission": 0,
|
|
235
|
-
"sellerCommission": 0,
|
|
236
|
-
"canTrade": True,
|
|
237
|
-
"canWithdraw": False,
|
|
238
|
-
"canDeposit": False,
|
|
239
|
-
"updateTime": int(time.time() * 1000),
|
|
240
|
-
"accountType": "SPOT",
|
|
241
|
-
"balances": balances,
|
|
242
|
-
"permissions": ["SPOT"],
|
|
243
|
-
}
|
|
230
|
+
return {"balances": balances}
|
|
244
231
|
|
|
245
232
|
|
|
246
233
|
def order_book(res: {}) -> {}:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{exchanges_wrapper-2.1.34 → exchanges_wrapper-2.1.35}/exchanges_wrapper/exch_srv_cfg.toml.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|