exchanges-wrapper 1.4.2__tar.gz → 1.4.4__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-1.4.2 → exchanges_wrapper-1.4.4}/PKG-INFO +1 -1
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/__init__.py +1 -1
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/exch_srv.py +61 -34
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/LICENSE.md +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/README.md +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/api_pb2.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/api_pb2_grpc.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/bitfinex_parser.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/bybit_parser.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/c_structures.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/client.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/definitions.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/errors.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/events.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/exch_srv_cfg.toml.template +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/http_client.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/huobi_parser.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/okx_parser.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/proto/exchanges_wrapper/api.proto +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/exchanges_wrapper/web_sockets.py +0 -0
- {exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: exchanges-wrapper
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.4
|
|
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.8
|
|
@@ -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__ = "1.4.
|
|
15
|
+
__version__ = "1.4.4"
|
|
16
16
|
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
import shutil
|
|
@@ -268,7 +268,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
268
268
|
for order in res:
|
|
269
269
|
order_id = order['orderId']
|
|
270
270
|
active_orders.append(order_id)
|
|
271
|
-
new_order = json_format.ParseDict(order, response_order)
|
|
271
|
+
new_order = json_format.ParseDict(order, response_order, ignore_unknown_fields=True)
|
|
272
272
|
# logger.debug(f"FetchOpenOrders.new_order: {new_order}")
|
|
273
273
|
response.items.append(new_order)
|
|
274
274
|
if client.exchange == 'bitfinex':
|
|
@@ -316,20 +316,23 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
316
316
|
f"{event.order_status}")
|
|
317
317
|
await _queue.put(weakref.ref(event)())
|
|
318
318
|
elif res.get('status') == 'PARTIALLY_FILLED':
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
except asyncio.CancelledError:
|
|
322
|
-
pass # Task cancellation should not be logged as an error
|
|
323
|
-
except Exception as _ex:
|
|
324
|
-
logger.error(f"Fetch order trades for {open_client.name}: {request.symbol} exception: {_ex}")
|
|
325
|
-
else:
|
|
326
|
-
logger.debug(f"FetchOrder.trades: {trades}")
|
|
327
|
-
for trade in trades:
|
|
328
|
-
event = OrderTradesEvent(trade)
|
|
329
|
-
await _queue.put(weakref.ref(event)())
|
|
330
|
-
json_format.ParseDict(res, response)
|
|
319
|
+
await self.create_trade_stream_event(_queue, client, open_client, request)
|
|
320
|
+
json_format.ParseDict(res, response, ignore_unknown_fields=True)
|
|
331
321
|
return response
|
|
332
322
|
|
|
323
|
+
async def create_trade_stream_event(self, _queue, client, open_client, request):
|
|
324
|
+
try:
|
|
325
|
+
trades = await client.fetch_order_trade_list(request.trade_id, request.symbol, request.order_id)
|
|
326
|
+
except asyncio.CancelledError:
|
|
327
|
+
pass # Task cancellation should not be logged as an error
|
|
328
|
+
except Exception as _ex:
|
|
329
|
+
logger.error(f"Fetch order trades for {open_client.name}: {request.symbol} exception: {_ex}")
|
|
330
|
+
else:
|
|
331
|
+
logger.debug(f"FetchOrder.trades: {trades}")
|
|
332
|
+
for trade in trades:
|
|
333
|
+
event = OrderTradesEvent(trade)
|
|
334
|
+
await _queue.put(weakref.ref(event)())
|
|
335
|
+
|
|
333
336
|
async def CancelAllOrders(self, request: api_pb2.MarketRequest,
|
|
334
337
|
_context: grpc.aio.ServicerContext) -> api_pb2.SimpleResponse():
|
|
335
338
|
open_client = OpenClient.get_client(request.client_id)
|
|
@@ -360,51 +363,71 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
360
363
|
else:
|
|
361
364
|
raise UserWarning(f"Symbol {request.symbol} not exist")
|
|
362
365
|
await self.rate_limit_control(open_client)
|
|
363
|
-
# logger.
|
|
366
|
+
# logger.debug(f"exchange_info_symbol: {exchange_info_symbol}")
|
|
364
367
|
open_client.ts_rlc = time.time()
|
|
365
368
|
filters_res = exchange_info_symbol.pop('filters', [])
|
|
366
|
-
json_format.ParseDict(exchange_info_symbol, response)
|
|
369
|
+
json_format.ParseDict(exchange_info_symbol, response, ignore_unknown_fields=True)
|
|
367
370
|
# logger.info(f"filters: {filters_res}")
|
|
368
371
|
filters = response.filters
|
|
369
372
|
for _filter in filters_res:
|
|
370
373
|
filter_type = _filter.get('filterType')
|
|
371
374
|
if filter_type == 'PRICE_FILTER':
|
|
372
375
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.PriceFilter()
|
|
373
|
-
filters.price_filter.CopyFrom(
|
|
376
|
+
filters.price_filter.CopyFrom(
|
|
377
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
378
|
+
)
|
|
374
379
|
elif 'PERCENT_PRICE' in filter_type:
|
|
375
380
|
if filter_type == 'PERCENT_PRICE_BY_SIDE':
|
|
376
|
-
_filter['multiplierUp'] = _filter['
|
|
381
|
+
_filter['multiplierUp'] = _filter['askMultiplierUp']
|
|
377
382
|
_filter['multiplierDown'] = _filter['bidMultiplierDown']
|
|
378
383
|
del _filter['bidMultiplierUp']
|
|
379
384
|
del _filter['bidMultiplierDown']
|
|
380
385
|
del _filter['askMultiplierUp']
|
|
381
386
|
del _filter['askMultiplierDown']
|
|
382
387
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.PercentPrice()
|
|
383
|
-
filters.percent_price.CopyFrom(
|
|
388
|
+
filters.percent_price.CopyFrom(
|
|
389
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
390
|
+
)
|
|
384
391
|
elif filter_type == 'LOT_SIZE':
|
|
385
392
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.LotSize()
|
|
386
|
-
filters.lot_size.CopyFrom(
|
|
393
|
+
filters.lot_size.CopyFrom(
|
|
394
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
395
|
+
)
|
|
387
396
|
elif filter_type == 'MIN_NOTIONAL':
|
|
388
397
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.MinNotional()
|
|
389
|
-
filters.min_notional.CopyFrom(
|
|
398
|
+
filters.min_notional.CopyFrom(
|
|
399
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
400
|
+
)
|
|
390
401
|
elif filter_type == 'NOTIONAL':
|
|
391
402
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.Notional()
|
|
392
|
-
filters.notional.CopyFrom(
|
|
403
|
+
filters.notional.CopyFrom(
|
|
404
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
405
|
+
)
|
|
393
406
|
elif filter_type == 'ICEBERG_PARTS':
|
|
394
407
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.IcebergParts()
|
|
395
|
-
filters.iceberg_parts.CopyFrom(
|
|
408
|
+
filters.iceberg_parts.CopyFrom(
|
|
409
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
410
|
+
)
|
|
396
411
|
elif filter_type == 'MARKET_LOT_SIZE':
|
|
397
412
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.MarketLotSize()
|
|
398
|
-
filters.market_lot_size.CopyFrom(
|
|
413
|
+
filters.market_lot_size.CopyFrom(
|
|
414
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
415
|
+
)
|
|
399
416
|
elif filter_type == 'MAX_NUM_ORDERS':
|
|
400
417
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.MaxNumOrders()
|
|
401
|
-
filters.max_num_orders.CopyFrom(
|
|
418
|
+
filters.max_num_orders.CopyFrom(
|
|
419
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
420
|
+
)
|
|
402
421
|
elif filter_type == 'MAX_NUM_ICEBERG_ORDERS':
|
|
403
422
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.MaxNumIcebergOrders()
|
|
404
|
-
filters.max_num_iceberg_orders.CopyFrom(
|
|
423
|
+
filters.max_num_iceberg_orders.CopyFrom(
|
|
424
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
425
|
+
)
|
|
405
426
|
elif filter_type == 'MAX_POSITION':
|
|
406
427
|
new_filter_template = api_pb2.FetchExchangeInfoSymbolResponse.Filters.MaxPosition()
|
|
407
|
-
filters.max_position.CopyFrom(
|
|
428
|
+
filters.max_position.CopyFrom(
|
|
429
|
+
json_format.ParseDict(_filter, new_filter_template, ignore_unknown_fields=True)
|
|
430
|
+
)
|
|
408
431
|
return response
|
|
409
432
|
|
|
410
433
|
async def FetchAccountInformation(self, request: api_pb2.OpenClientConnectionId,
|
|
@@ -428,7 +451,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
428
451
|
balances.append({'asset': i.get('asset'), 'free': i.get('free'), 'locked': i.get('locked')})
|
|
429
452
|
# logger.info(f"account_information.balances: {balances}")
|
|
430
453
|
for balance in balances:
|
|
431
|
-
new_balance = json_format.ParseDict(balance, response_balance)
|
|
454
|
+
new_balance = json_format.ParseDict(balance, response_balance, ignore_unknown_fields=True)
|
|
432
455
|
response.balances.extend([new_balance])
|
|
433
456
|
return response
|
|
434
457
|
|
|
@@ -451,7 +474,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
451
474
|
open_client.ts_rlc = time.time()
|
|
452
475
|
logger.debug(f"funding_wallet: {res}")
|
|
453
476
|
for balance in res:
|
|
454
|
-
new_balance = json_format.ParseDict(balance, response_balance)
|
|
477
|
+
new_balance = json_format.ParseDict(balance, response_balance, ignore_unknown_fields=True)
|
|
455
478
|
response.balances.extend([new_balance])
|
|
456
479
|
return response
|
|
457
480
|
|
|
@@ -482,7 +505,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
482
505
|
await self.rate_limit_control(open_client)
|
|
483
506
|
res = await client.fetch_symbol_price_ticker(symbol=request.symbol)
|
|
484
507
|
open_client.ts_rlc = time.time()
|
|
485
|
-
json_format.ParseDict(res, response)
|
|
508
|
+
json_format.ParseDict(res, response, ignore_unknown_fields=True)
|
|
486
509
|
return response
|
|
487
510
|
|
|
488
511
|
async def FetchTickerPriceChangeStatistics(
|
|
@@ -494,7 +517,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
494
517
|
await self.rate_limit_control(open_client)
|
|
495
518
|
res = await client.fetch_ticker_price_change_statistics(symbol=request.symbol)
|
|
496
519
|
open_client.ts_rlc = time.time()
|
|
497
|
-
json_format.ParseDict(res, response)
|
|
520
|
+
json_format.ParseDict(res, response, ignore_unknown_fields=True)
|
|
498
521
|
return response
|
|
499
522
|
|
|
500
523
|
async def FetchKlines(self, request: api_pb2.FetchKlinesRequest,
|
|
@@ -597,7 +620,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
597
620
|
# logger.info(f"FetchAccountTradeList: {res}")
|
|
598
621
|
open_client.ts_rlc = time.time()
|
|
599
622
|
for trade in res:
|
|
600
|
-
trade_order = json_format.ParseDict(trade, response_trade)
|
|
623
|
+
trade_order = json_format.ParseDict(trade, response_trade, ignore_unknown_fields=True)
|
|
601
624
|
response.items.append(trade_order)
|
|
602
625
|
return response
|
|
603
626
|
|
|
@@ -632,7 +655,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
632
655
|
'close_price': _event.close_price,
|
|
633
656
|
'event_time': _event.event_time}
|
|
634
657
|
# logger.info(f"OnTickerUpdate.event: {_event.symbol}, ticker_24h: {ticker_24h}")
|
|
635
|
-
json_format.ParseDict(ticker_24h, response)
|
|
658
|
+
json_format.ParseDict(ticker_24h, response, ignore_unknown_fields=True)
|
|
636
659
|
yield response
|
|
637
660
|
_queue.task_done()
|
|
638
661
|
|
|
@@ -813,7 +836,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
813
836
|
origin_client_order_id=request.new_client_order_id,
|
|
814
837
|
receive_window=None,
|
|
815
838
|
response_type=False)
|
|
816
|
-
json_format.ParseDict(res, response)
|
|
839
|
+
json_format.ParseDict(res, response, ignore_unknown_fields=True)
|
|
817
840
|
logger.debug(f"CreateLimitOrder: for {open_client.name}:{request.symbol}: created: {res.get('orderId')}")
|
|
818
841
|
return response
|
|
819
842
|
|
|
@@ -822,6 +845,7 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
822
845
|
response = api_pb2.CancelOrderResponse()
|
|
823
846
|
open_client = OpenClient.get_client(request.client_id)
|
|
824
847
|
client = open_client.client
|
|
848
|
+
_queue = client.on_order_update_queues.get(request.trade_id)
|
|
825
849
|
try:
|
|
826
850
|
res = await client.cancel_order(
|
|
827
851
|
request.trade_id,
|
|
@@ -842,7 +866,10 @@ class Martin(api_pb2_grpc.MartinServicer):
|
|
|
842
866
|
_context.set_details(f"{ex}")
|
|
843
867
|
_context.set_code(grpc.StatusCode.UNKNOWN)
|
|
844
868
|
else:
|
|
845
|
-
|
|
869
|
+
if float(res['executedQty']):
|
|
870
|
+
await self.create_trade_stream_event(_queue, client, open_client, request)
|
|
871
|
+
await asyncio.sleep(HEARTBEAT)
|
|
872
|
+
json_format.ParseDict(res, response, ignore_unknown_fields=True)
|
|
846
873
|
return response
|
|
847
874
|
|
|
848
875
|
async def TransferToMaster(self, request: api_pb2.MarketRequest,
|
|
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
|
|
File without changes
|
|
File without changes
|
{exchanges_wrapper-1.4.2 → exchanges_wrapper-1.4.4}/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
|