ccxt 4.4.35__py2.py3-none-any.whl → 4.4.36__py2.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.
- ccxt/__init__.py +3 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bybit.py +15 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/gate.py +14 -0
- ccxt/abstract/gateio.py +14 -0
- ccxt/async_support/__init__.py +3 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bitfinex2.py +18 -13
- ccxt/async_support/bitmex.py +103 -1
- ccxt/async_support/bitopro.py +21 -4
- ccxt/async_support/bitso.py +2 -1
- ccxt/async_support/bybit.py +21 -1
- ccxt/async_support/defx.py +1981 -0
- ccxt/async_support/deribit.py +27 -12
- ccxt/async_support/gate.py +14 -0
- ccxt/async_support/htx.py +11 -2
- ccxt/async_support/kraken.py +39 -41
- ccxt/base/exchange.py +1 -1
- ccxt/bitfinex2.py +18 -13
- ccxt/bitmex.py +103 -1
- ccxt/bitopro.py +21 -4
- ccxt/bitso.py +2 -1
- ccxt/bybit.py +21 -1
- ccxt/defx.py +1980 -0
- ccxt/deribit.py +27 -12
- ccxt/gate.py +14 -0
- ccxt/htx.py +11 -2
- ccxt/kraken.py +39 -41
- ccxt/pro/__init__.py +3 -1
- ccxt/pro/defx.py +832 -0
- ccxt/test/tests_async.py +15 -1
- ccxt/test/tests_sync.py +15 -1
- {ccxt-4.4.35.dist-info → ccxt-4.4.36.dist-info}/METADATA +7 -6
- {ccxt-4.4.35.dist-info → ccxt-4.4.36.dist-info}/RECORD +39 -35
- {ccxt-4.4.35.dist-info → ccxt-4.4.36.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.35.dist-info → ccxt-4.4.36.dist-info}/WHEEL +0 -0
- {ccxt-4.4.35.dist-info → ccxt-4.4.36.dist-info}/top_level.txt +0 -0
ccxt/async_support/deribit.py
CHANGED
@@ -220,6 +220,7 @@ class deribit(Exchange, ImplicitAPI):
|
|
220
220
|
'enable_api_key': 1,
|
221
221
|
'get_access_log': 1,
|
222
222
|
'get_account_summary': 1,
|
223
|
+
'get_account_summaries': 1,
|
223
224
|
'get_affiliate_program_info': 1,
|
224
225
|
'get_email_language': 1,
|
225
226
|
'get_new_announcements': 1,
|
@@ -931,13 +932,20 @@ class deribit(Exchange, ImplicitAPI):
|
|
931
932
|
result: dict = {
|
932
933
|
'info': balance,
|
933
934
|
}
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
935
|
+
summaries = []
|
936
|
+
if 'summaries' in balance:
|
937
|
+
summaries = self.safe_list(balance, 'summaries')
|
938
|
+
else:
|
939
|
+
summaries = [balance]
|
940
|
+
for i in range(0, len(summaries)):
|
941
|
+
data = summaries[i]
|
942
|
+
currencyId = self.safe_string(data, 'currency')
|
943
|
+
currencyCode = self.safe_currency_code(currencyId)
|
944
|
+
account = self.account()
|
945
|
+
account['free'] = self.safe_string(data, 'available_funds')
|
946
|
+
account['used'] = self.safe_string(data, 'maintenance_margin')
|
947
|
+
account['total'] = self.safe_string(data, 'equity')
|
948
|
+
result[currencyCode] = account
|
941
949
|
return self.safe_balance(result)
|
942
950
|
|
943
951
|
async def fetch_balance(self, params={}) -> Balances:
|
@@ -945,17 +953,24 @@ class deribit(Exchange, ImplicitAPI):
|
|
945
953
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
946
954
|
|
947
955
|
https://docs.deribit.com/#private-get_account_summary
|
956
|
+
https://docs.deribit.com/#private-get_account_summaries
|
948
957
|
|
949
958
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
959
|
+
:param str [params.code]: unified currency code of the currency for the balance, if defined 'privateGetGetAccountSummary' will be used, otherwise 'privateGetGetAccountSummaries' will be used
|
950
960
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
951
961
|
"""
|
952
962
|
await self.load_markets()
|
953
|
-
code = self.
|
954
|
-
|
963
|
+
code = self.safe_string(params, 'code')
|
964
|
+
params = self.omit(params, 'code')
|
955
965
|
request: dict = {
|
956
|
-
'currency': currency['id'],
|
957
966
|
}
|
958
|
-
|
967
|
+
if code is not None:
|
968
|
+
request['currency'] = self.currency_id(code)
|
969
|
+
response = None
|
970
|
+
if code is None:
|
971
|
+
response = await self.privateGetGetAccountSummaries(params)
|
972
|
+
else:
|
973
|
+
response = await self.privateGetGetAccountSummary(self.extend(request, params))
|
959
974
|
#
|
960
975
|
# {
|
961
976
|
# "jsonrpc": "2.0",
|
@@ -998,7 +1013,7 @@ class deribit(Exchange, ImplicitAPI):
|
|
998
1013
|
# "testnet": False
|
999
1014
|
# }
|
1000
1015
|
#
|
1001
|
-
result = self.
|
1016
|
+
result = self.safe_dict(response, 'result', {})
|
1002
1017
|
return self.parse_balance(result)
|
1003
1018
|
|
1004
1019
|
async def create_deposit_address(self, code: str, params={}):
|
ccxt/async_support/gate.py
CHANGED
@@ -240,6 +240,7 @@ class gate(Exchange, ImplicitAPI):
|
|
240
240
|
'{settle}/contract_stats': 1,
|
241
241
|
'{settle}/index_constituents/{index}': 1,
|
242
242
|
'{settle}/liq_orders': 1,
|
243
|
+
'{settle}/risk_limit_tiers': 1,
|
243
244
|
},
|
244
245
|
},
|
245
246
|
'delivery': {
|
@@ -281,6 +282,7 @@ class gate(Exchange, ImplicitAPI):
|
|
281
282
|
'withdrawals': {
|
282
283
|
'post': {
|
283
284
|
'withdrawals': 20, # 1r/s cost = 20 / 1 = 20
|
285
|
+
'push': 1,
|
284
286
|
},
|
285
287
|
'delete': {
|
286
288
|
'withdrawals/{withdrawal_id}': 1,
|
@@ -292,6 +294,7 @@ class gate(Exchange, ImplicitAPI):
|
|
292
294
|
'withdrawals': 1,
|
293
295
|
'deposits': 1,
|
294
296
|
'sub_account_transfers': 1,
|
297
|
+
'order_status': 1,
|
295
298
|
'withdraw_status': 1,
|
296
299
|
'sub_account_balances': 2.5,
|
297
300
|
'sub_account_margin_balances': 2.5,
|
@@ -302,6 +305,7 @@ class gate(Exchange, ImplicitAPI):
|
|
302
305
|
'total_balance': 2.5,
|
303
306
|
'small_balance': 1,
|
304
307
|
'small_balance_history': 1,
|
308
|
+
'push': 1,
|
305
309
|
},
|
306
310
|
'post': {
|
307
311
|
'transfers': 2.5, # 8r/s cost = 20 / 8 = 2.5
|
@@ -344,11 +348,14 @@ class gate(Exchange, ImplicitAPI):
|
|
344
348
|
'risk_units': 20 / 15,
|
345
349
|
'unified_mode': 20 / 15,
|
346
350
|
'loan_margin_tiers': 20 / 15,
|
351
|
+
'leverage/user_currency_config': 20 / 15,
|
352
|
+
'leverage/user_currency_setting': 20 / 15,
|
347
353
|
},
|
348
354
|
'post': {
|
349
355
|
'account_mode': 20 / 15,
|
350
356
|
'loans': 200 / 15, # 15r/10s cost = 20 / 1.5 = 13.33
|
351
357
|
'portfolio_calculator': 20 / 15,
|
358
|
+
'leverage/user_currency_setting': 20 / 15,
|
352
359
|
},
|
353
360
|
'put': {
|
354
361
|
'unified_mode': 20 / 15,
|
@@ -528,9 +535,13 @@ class gate(Exchange, ImplicitAPI):
|
|
528
535
|
'orders': 20 / 15,
|
529
536
|
'orders/{order_id}': 20 / 15,
|
530
537
|
'my_trades': 20 / 15,
|
538
|
+
'mmp': 20 / 15,
|
531
539
|
},
|
532
540
|
'post': {
|
533
541
|
'orders': 20 / 15,
|
542
|
+
'countdown_cancel_all': 20 / 15,
|
543
|
+
'mmp': 20 / 15,
|
544
|
+
'mmp/reset': 20 / 15,
|
534
545
|
},
|
535
546
|
'delete': {
|
536
547
|
'orders': 20 / 15,
|
@@ -574,6 +585,7 @@ class gate(Exchange, ImplicitAPI):
|
|
574
585
|
'multi_collateral/currencies': 20 / 15,
|
575
586
|
'multi_collateral/ltv': 20 / 15,
|
576
587
|
'multi_collateral/fixed_rate': 20 / 15,
|
588
|
+
'multi_collateral/current_rate': 20 / 15,
|
577
589
|
},
|
578
590
|
'post': {
|
579
591
|
'collateral/orders': 20 / 15,
|
@@ -587,8 +599,10 @@ class gate(Exchange, ImplicitAPI):
|
|
587
599
|
'account': {
|
588
600
|
'get': {
|
589
601
|
'detail': 20 / 15,
|
602
|
+
'rate_limit': 20 / 15,
|
590
603
|
'stp_groups': 20 / 15,
|
591
604
|
'stp_groups/{stp_id}/users': 20 / 15,
|
605
|
+
'stp_groups/debit_fee': 20 / 15,
|
592
606
|
},
|
593
607
|
'post': {
|
594
608
|
'stp_groups': 20 / 15,
|
ccxt/async_support/htx.py
CHANGED
@@ -5092,17 +5092,23 @@ class htx(Exchange, ImplicitAPI):
|
|
5092
5092
|
params = self.omit(params, ['clientOrderId'])
|
5093
5093
|
if type == 'limit' or type == 'ioc' or type == 'fok' or type == 'post_only':
|
5094
5094
|
request['price'] = self.price_to_precision(symbol, price)
|
5095
|
+
reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only', False)
|
5095
5096
|
if not isStopLossTriggerOrder and not isTakeProfitTriggerOrder:
|
5096
|
-
reduceOnly = self.safe_value_2(params, 'reduceOnly', 'reduce_only', False)
|
5097
5097
|
if reduceOnly:
|
5098
5098
|
request['reduce_only'] = 1
|
5099
5099
|
request['lever_rate'] = self.safe_integer_n(params, ['leverRate', 'lever_rate', 'leverage'], 1)
|
5100
5100
|
if not isTrailingPercentOrder:
|
5101
5101
|
request['order_price_type'] = type
|
5102
|
+
hedged = self.safe_bool(params, 'hedged', False)
|
5103
|
+
if hedged:
|
5104
|
+
if reduceOnly:
|
5105
|
+
request['offset'] = 'close'
|
5106
|
+
else:
|
5107
|
+
request['offset'] = 'open'
|
5102
5108
|
broker = self.safe_value(self.options, 'broker', {})
|
5103
5109
|
brokerId = self.safe_string(broker, 'id')
|
5104
5110
|
request['channel_code'] = brokerId
|
5105
|
-
params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice'])
|
5111
|
+
params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice', 'hedged'])
|
5106
5112
|
return self.extend(request, params)
|
5107
5113
|
|
5108
5114
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
@@ -5116,6 +5122,8 @@ class htx(Exchange, ImplicitAPI):
|
|
5116
5122
|
https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order # usdt-m swap cross trigger
|
5117
5123
|
https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order # usdt-m swap isolated
|
5118
5124
|
https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order # usdt-m swap isolated trigger
|
5125
|
+
https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-set-a-take-profit-and-stop-loss-order-for-an-existing-position
|
5126
|
+
https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-set-a-take-profit-and-stop-loss-order-for-an-existing-position
|
5119
5127
|
https://huobiapi.github.io/docs/dm/v1/en/#place-an-order # coin-m futures
|
5120
5128
|
https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order # coin-m futures contract trigger
|
5121
5129
|
|
@@ -5137,6 +5145,7 @@ class htx(Exchange, ImplicitAPI):
|
|
5137
5145
|
:param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
|
5138
5146
|
:param float [params.trailingPercent]: *contract only* the percent to trail away from the current market price
|
5139
5147
|
:param float [params.trailingTriggerPrice]: *contract only* the price to trigger a trailing order, default uses the price argument
|
5148
|
+
:param bool [params.hedged]: *contract only* True for hedged mode, False for one way mode, default is False
|
5140
5149
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
5141
5150
|
"""
|
5142
5151
|
await self.load_markets()
|
ccxt/async_support/kraken.py
CHANGED
@@ -447,31 +447,43 @@ class kraken(Exchange, ImplicitAPI):
|
|
447
447
|
},
|
448
448
|
'precisionMode': TICK_SIZE,
|
449
449
|
'exceptions': {
|
450
|
-
'
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
450
|
+
'exact': {
|
451
|
+
'EQuery:Invalid asset pair': BadSymbol, # {"error":["EQuery:Invalid asset pair"]}
|
452
|
+
'EAPI:Invalid key': AuthenticationError,
|
453
|
+
'EFunding:Unknown withdraw key': InvalidAddress, # {"error":["EFunding:Unknown withdraw key"]}
|
454
|
+
'EFunding:Invalid amount': InsufficientFunds,
|
455
|
+
'EService:Unavailable': ExchangeNotAvailable,
|
456
|
+
'EDatabase:Internal error': ExchangeNotAvailable,
|
457
|
+
'EService:Busy': ExchangeNotAvailable,
|
458
|
+
'EQuery:Unknown asset': BadSymbol, # {"error":["EQuery:Unknown asset"]}
|
459
|
+
'EAPI:Rate limit exceeded': DDoSProtection,
|
460
|
+
'EOrder:Rate limit exceeded': DDoSProtection,
|
461
|
+
'EGeneral:Internal error': ExchangeNotAvailable,
|
462
|
+
'EGeneral:Temporary lockout': DDoSProtection,
|
463
|
+
'EGeneral:Permission denied': PermissionDenied,
|
464
|
+
'EGeneral:Invalid arguments:price': InvalidOrder,
|
465
|
+
'EOrder:Unknown order': InvalidOrder,
|
466
|
+
'EOrder:Invalid price:Invalid price argument': InvalidOrder,
|
467
|
+
'EOrder:Order minimum not met': InvalidOrder,
|
468
|
+
'EOrder:Insufficient funds': InsufficientFunds,
|
469
|
+
'EGeneral:Invalid arguments': BadRequest,
|
470
|
+
'ESession:Invalid session': AuthenticationError,
|
471
|
+
'EAPI:Invalid nonce': InvalidNonce,
|
472
|
+
'EFunding:No funding method': BadRequest, # {"error":"EFunding:No funding method"}
|
473
|
+
'EFunding:Unknown asset': BadSymbol, # {"error":["EFunding:Unknown asset"]}
|
474
|
+
'EService:Market in post_only mode': OnMaintenance, # {"error":["EService:Market in post_only mode"]}
|
475
|
+
'EGeneral:Too many requests': DDoSProtection, # {"error":["EGeneral:Too many requests"]}
|
476
|
+
'ETrade:User Locked': AccountSuspended, # {"error":["ETrade:User Locked"]}
|
477
|
+
},
|
478
|
+
'broad': {
|
479
|
+
':Invalid order': InvalidOrder,
|
480
|
+
':Invalid arguments:volume': InvalidOrder,
|
481
|
+
':Invalid arguments:viqc': InvalidOrder,
|
482
|
+
':Invalid nonce': InvalidNonce,
|
483
|
+
':IInsufficient funds': InsufficientFunds,
|
484
|
+
':Cancel pending': CancelPending,
|
485
|
+
':Rate limit exceeded': RateLimitExceeded,
|
486
|
+
},
|
475
487
|
},
|
476
488
|
})
|
477
489
|
|
@@ -3064,21 +3076,6 @@ class kraken(Exchange, ImplicitAPI):
|
|
3064
3076
|
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
3065
3077
|
if code == 520:
|
3066
3078
|
raise ExchangeNotAvailable(self.id + ' ' + str(code) + ' ' + reason)
|
3067
|
-
# todo: rewrite self for "broad" exceptions matching
|
3068
|
-
if body.find('Invalid order') >= 0:
|
3069
|
-
raise InvalidOrder(self.id + ' ' + body)
|
3070
|
-
if body.find('Invalid nonce') >= 0:
|
3071
|
-
raise InvalidNonce(self.id + ' ' + body)
|
3072
|
-
if body.find('Insufficient funds') >= 0:
|
3073
|
-
raise InsufficientFunds(self.id + ' ' + body)
|
3074
|
-
if body.find('Cancel pending') >= 0:
|
3075
|
-
raise CancelPending(self.id + ' ' + body)
|
3076
|
-
if body.find('Invalid arguments:volume') >= 0:
|
3077
|
-
raise InvalidOrder(self.id + ' ' + body)
|
3078
|
-
if body.find('Invalid arguments:viqc') >= 0:
|
3079
|
-
raise InvalidOrder(self.id + ' ' + body)
|
3080
|
-
if body.find('Rate limit exceeded') >= 0:
|
3081
|
-
raise RateLimitExceeded(self.id + ' ' + body)
|
3082
3079
|
if response is None:
|
3083
3080
|
return None
|
3084
3081
|
if body[0] == '{':
|
@@ -3089,6 +3086,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
3089
3086
|
message = self.id + ' ' + body
|
3090
3087
|
for i in range(0, len(response['error'])):
|
3091
3088
|
error = response['error'][i]
|
3092
|
-
self.throw_exactly_matched_exception(self.exceptions, error, message)
|
3089
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], error, message)
|
3090
|
+
self.throw_exactly_matched_exception(self.exceptions['broad'], error, message)
|
3093
3091
|
raise ExchangeError(message)
|
3094
3092
|
return None
|
ccxt/base/exchange.py
CHANGED
ccxt/bitfinex2.py
CHANGED
@@ -15,7 +15,6 @@ from ccxt.base.errors import ArgumentsRequired
|
|
15
15
|
from ccxt.base.errors import BadRequest
|
16
16
|
from ccxt.base.errors import BadSymbol
|
17
17
|
from ccxt.base.errors import InsufficientFunds
|
18
|
-
from ccxt.base.errors import InvalidAddress
|
19
18
|
from ccxt.base.errors import InvalidOrder
|
20
19
|
from ccxt.base.errors import OrderNotFound
|
21
20
|
from ccxt.base.errors import NotSupported
|
@@ -432,12 +431,10 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
432
431
|
'temporarily_unavailable': ExchangeNotAvailable,
|
433
432
|
},
|
434
433
|
'broad': {
|
435
|
-
'address': InvalidAddress,
|
436
434
|
'available balance is only': InsufficientFunds,
|
437
435
|
'not enough exchange balance': InsufficientFunds,
|
438
436
|
'Order not found': OrderNotFound,
|
439
437
|
'symbol: invalid': BadSymbol,
|
440
|
-
'Invalid order': InvalidOrder,
|
441
438
|
},
|
442
439
|
},
|
443
440
|
'commonCurrencies': {
|
@@ -781,7 +778,10 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
781
778
|
name = self.safe_string(label, 1)
|
782
779
|
pool = self.safe_value(indexed['pool'], id, [])
|
783
780
|
rawType = self.safe_string(pool, 1)
|
784
|
-
|
781
|
+
isCryptoCoin = (rawType is not None) or (id in indexed['explorer']) # "hacky" solution
|
782
|
+
type = None
|
783
|
+
if isCryptoCoin:
|
784
|
+
type = 'crypto'
|
785
785
|
feeValues = self.safe_value(indexed['fees'], id, [])
|
786
786
|
fees = self.safe_value(feeValues, 1, [])
|
787
787
|
fee = self.safe_number(fees, 1)
|
@@ -1680,7 +1680,8 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
1680
1680
|
raise ExchangeError(self.id + ' ' + response[6] + ': ' + errorText + '(#' + errorCode + ')')
|
1681
1681
|
orders = self.safe_list(response, 4, [])
|
1682
1682
|
order = self.safe_list(orders, 0)
|
1683
|
-
|
1683
|
+
newOrder = {'result': order}
|
1684
|
+
return self.parse_order(newOrder, market)
|
1684
1685
|
|
1685
1686
|
def create_orders(self, orders: List[OrderRequest], params={}):
|
1686
1687
|
"""
|
@@ -1776,6 +1777,9 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
1776
1777
|
self.load_markets()
|
1777
1778
|
cid = self.safe_value_2(params, 'cid', 'clientOrderId') # client order id
|
1778
1779
|
request = None
|
1780
|
+
market = None
|
1781
|
+
if symbol is not None:
|
1782
|
+
market = self.market(symbol)
|
1779
1783
|
if cid is not None:
|
1780
1784
|
cidDate = self.safe_value(params, 'cidDate') # client order id date
|
1781
1785
|
if cidDate is None:
|
@@ -1791,8 +1795,8 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
1791
1795
|
}
|
1792
1796
|
response = self.privatePostAuthWOrderCancel(self.extend(request, params))
|
1793
1797
|
order = self.safe_value(response, 4)
|
1794
|
-
|
1795
|
-
return self.parse_order(
|
1798
|
+
newOrder = {'result': order}
|
1799
|
+
return self.parse_order(newOrder, market)
|
1796
1800
|
|
1797
1801
|
def cancel_orders(self, ids, symbol: Str = None, params={}):
|
1798
1802
|
"""
|
@@ -2293,6 +2297,8 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
2293
2297
|
status = 'failed'
|
2294
2298
|
tag = self.safe_string(data, 3)
|
2295
2299
|
type = 'withdrawal'
|
2300
|
+
networkId = self.safe_string(data, 2)
|
2301
|
+
network = self.network_id_to_code(networkId.upper()) # withdraw returns in lowercase
|
2296
2302
|
elif transactionLength == 22:
|
2297
2303
|
id = self.safe_string(transaction, 0)
|
2298
2304
|
currencyId = self.safe_string(transaction, 1)
|
@@ -2589,10 +2595,7 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
2589
2595
|
text = self.safe_string(response, 7)
|
2590
2596
|
if text != 'success':
|
2591
2597
|
self.throw_broadly_matched_exception(self.exceptions['broad'], text, text)
|
2592
|
-
|
2593
|
-
return self.extend(transaction, {
|
2594
|
-
'address': address,
|
2595
|
-
})
|
2598
|
+
return self.parse_transaction(response, currency)
|
2596
2599
|
|
2597
2600
|
def fetch_positions(self, symbols: Strings = None, params={}):
|
2598
2601
|
"""
|
@@ -3501,7 +3504,8 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
3501
3504
|
# ]
|
3502
3505
|
#
|
3503
3506
|
order = self.safe_list(response, 0)
|
3504
|
-
|
3507
|
+
newOrder = {'result': order}
|
3508
|
+
return self.parse_order(newOrder, market)
|
3505
3509
|
|
3506
3510
|
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
3507
3511
|
"""
|
@@ -3616,4 +3620,5 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
3616
3620
|
errorText = response[7]
|
3617
3621
|
raise ExchangeError(self.id + ' ' + response[6] + ': ' + errorText + '(#' + errorCode + ')')
|
3618
3622
|
order = self.safe_list(response, 4, [])
|
3619
|
-
|
3623
|
+
newOrder = {'result': order}
|
3624
|
+
return self.parse_order(newOrder, market)
|
ccxt/bitmex.py
CHANGED
@@ -286,6 +286,108 @@ class bitmex(Exchange, ImplicitAPI):
|
|
286
286
|
'SOL': 'sol',
|
287
287
|
'ADA': 'ada',
|
288
288
|
},
|
289
|
+
'features': {
|
290
|
+
'default': {
|
291
|
+
'sandbox': True,
|
292
|
+
'createOrder': {
|
293
|
+
'marginMode': True,
|
294
|
+
'triggerPrice': True,
|
295
|
+
'triggerPriceType': {
|
296
|
+
'last': True,
|
297
|
+
'mark': True,
|
298
|
+
},
|
299
|
+
'triggerDirection': True,
|
300
|
+
'stopLossPrice': False,
|
301
|
+
'takeProfitPrice': False,
|
302
|
+
'attachedStopLossTakeProfit': None,
|
303
|
+
'timeInForce': {
|
304
|
+
'IOC': True,
|
305
|
+
'FOK': True,
|
306
|
+
'PO': True,
|
307
|
+
'GTD': False,
|
308
|
+
},
|
309
|
+
'hedged': False,
|
310
|
+
'trailing': True,
|
311
|
+
'marketBuyRequiresPrice': False,
|
312
|
+
'marketBuyByCost': False,
|
313
|
+
# exchange-supported features
|
314
|
+
# 'selfTradePrevention': True,
|
315
|
+
# 'twap': False,
|
316
|
+
# 'iceberg': False,
|
317
|
+
# 'oco': False,
|
318
|
+
},
|
319
|
+
'createOrders': None,
|
320
|
+
'fetchMyTrades': {
|
321
|
+
'marginMode': False,
|
322
|
+
'limit': 500,
|
323
|
+
'daysBack': None,
|
324
|
+
'untilDays': 1000000,
|
325
|
+
},
|
326
|
+
'fetchOrder': {
|
327
|
+
'marginMode': False,
|
328
|
+
'trigger': False,
|
329
|
+
'trailing': False,
|
330
|
+
},
|
331
|
+
'fetchOpenOrders': {
|
332
|
+
'marginMode': False,
|
333
|
+
'limit': 500,
|
334
|
+
'trigger': False,
|
335
|
+
'trailing': False,
|
336
|
+
},
|
337
|
+
'fetchOrders': {
|
338
|
+
'marginMode': False,
|
339
|
+
'limit': 500,
|
340
|
+
'daysBack': None,
|
341
|
+
'untilDays': 1000000,
|
342
|
+
'trigger': False,
|
343
|
+
'trailing': False,
|
344
|
+
},
|
345
|
+
'fetchClosedOrders': {
|
346
|
+
'marginMode': False,
|
347
|
+
'limit': 500,
|
348
|
+
'daysBackClosed': None,
|
349
|
+
'daysBackCanceled': None,
|
350
|
+
'untilDays': 1000000,
|
351
|
+
'trigger': False,
|
352
|
+
'trailing': False,
|
353
|
+
},
|
354
|
+
'fetchOHLCV': {
|
355
|
+
'limit': 10000,
|
356
|
+
},
|
357
|
+
},
|
358
|
+
'spot': {
|
359
|
+
'extends': 'default',
|
360
|
+
'createOrder': {
|
361
|
+
'triggerPriceType': {
|
362
|
+
'index': False,
|
363
|
+
},
|
364
|
+
},
|
365
|
+
},
|
366
|
+
'forDeriv': {
|
367
|
+
'extends': 'default',
|
368
|
+
'createOrder': {
|
369
|
+
'triggerPriceType': {
|
370
|
+
'index': True,
|
371
|
+
},
|
372
|
+
},
|
373
|
+
},
|
374
|
+
'swap': {
|
375
|
+
'linear': {
|
376
|
+
'extends': 'forDeriv',
|
377
|
+
},
|
378
|
+
'inverse': {
|
379
|
+
'extends': 'forDeriv',
|
380
|
+
},
|
381
|
+
},
|
382
|
+
'future': {
|
383
|
+
'linear': {
|
384
|
+
'extends': 'forDeriv',
|
385
|
+
},
|
386
|
+
'inverse': {
|
387
|
+
'extends': 'forDeriv',
|
388
|
+
},
|
389
|
+
},
|
390
|
+
},
|
289
391
|
},
|
290
392
|
'commonCurrencies': {
|
291
393
|
'USDt': 'USDT',
|
@@ -991,7 +1093,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
991
1093
|
if since is not None:
|
992
1094
|
request['startTime'] = self.iso8601(since)
|
993
1095
|
if limit is not None:
|
994
|
-
request['count'] = limit
|
1096
|
+
request['count'] = min(500, limit)
|
995
1097
|
until = self.safe_integer_2(params, 'until', 'endTime')
|
996
1098
|
if until is not None:
|
997
1099
|
params = self.omit(params, ['until'])
|
ccxt/bitopro.py
CHANGED
@@ -153,6 +153,7 @@ class bitopro(Exchange, ImplicitAPI):
|
|
153
153
|
'wallet/withdraw/{currency}/id/{id}': 1,
|
154
154
|
'wallet/depositHistory/{currency}': 1,
|
155
155
|
'wallet/withdrawHistory/{currency}': 1,
|
156
|
+
'orders/open': 1,
|
156
157
|
},
|
157
158
|
'post': {
|
158
159
|
'orders/{pair}': 1 / 2, # 1200/m => 20/s => 10/20 = 1/2
|
@@ -1248,10 +1249,26 @@ class bitopro(Exchange, ImplicitAPI):
|
|
1248
1249
|
return self.parse_orders(orders, market, since, limit)
|
1249
1250
|
|
1250
1251
|
def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1252
|
+
"""
|
1253
|
+
fetch all unfilled currently open orders
|
1254
|
+
|
1255
|
+
https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_open_orders_data.md
|
1256
|
+
|
1257
|
+
:param str symbol: unified market symbol
|
1258
|
+
:param int [since]: the earliest time in ms to fetch open orders for
|
1259
|
+
:param int [limit]: the maximum number of open orders structures to retrieve
|
1260
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1261
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1262
|
+
"""
|
1263
|
+
self.load_markets()
|
1264
|
+
request: dict = {}
|
1265
|
+
market = None
|
1266
|
+
if symbol is not None:
|
1267
|
+
market = self.market(symbol)
|
1268
|
+
request['pair'] = market['id']
|
1269
|
+
response = self.privateGetOrdersOpen(self.extend(request, params))
|
1270
|
+
orders = self.safe_list(response, 'data', [])
|
1271
|
+
return self.parse_orders(orders, market, since, limit)
|
1255
1272
|
|
1256
1273
|
def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1257
1274
|
"""
|
ccxt/bitso.py
CHANGED
@@ -1683,6 +1683,7 @@ class bitso(Exchange, ImplicitAPI):
|
|
1683
1683
|
if api == 'private':
|
1684
1684
|
self.check_required_credentials()
|
1685
1685
|
nonce = str(self.nonce())
|
1686
|
+
endpoint = '/api' + endpoint
|
1686
1687
|
request = ''.join([nonce, method, endpoint])
|
1687
1688
|
if method != 'GET' and method != 'DELETE':
|
1688
1689
|
if query:
|
@@ -1692,7 +1693,7 @@ class bitso(Exchange, ImplicitAPI):
|
|
1692
1693
|
auth = self.apiKey + ':' + nonce + ':' + signature
|
1693
1694
|
headers = {
|
1694
1695
|
'Authorization': 'Bitso ' + auth,
|
1695
|
-
'Content-Type': 'application/json',
|
1696
|
+
# 'Content-Type': 'application/json',
|
1696
1697
|
}
|
1697
1698
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
1698
1699
|
|
ccxt/bybit.py
CHANGED
@@ -257,6 +257,9 @@ class bybit(Exchange, ImplicitAPI):
|
|
257
257
|
'v5/spot-cross-margin-trade/data': 5,
|
258
258
|
'v5/spot-cross-margin-trade/pledge-token': 5,
|
259
259
|
'v5/spot-cross-margin-trade/borrow-token': 5,
|
260
|
+
# crypto loan
|
261
|
+
'v5/crypto-loan/collateral-data': 5,
|
262
|
+
'v5/crypto-loan/loanable-data': 5,
|
260
263
|
# institutional lending
|
261
264
|
'v5/ins-loan/product-infos': 5,
|
262
265
|
'v5/ins-loan/ensure-tokens-convert': 5,
|
@@ -384,6 +387,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
384
387
|
'v5/user/aff-customer-info': 5,
|
385
388
|
'v5/user/del-submember': 5,
|
386
389
|
'v5/user/submembers': 5,
|
390
|
+
# affilate
|
391
|
+
'v5/affiliate/aff-user-list': 5,
|
387
392
|
# spot leverage token
|
388
393
|
'v5/spot-lever-token/order-record': 1, # 50/s => cost = 50 / 50 = 1
|
389
394
|
# spot margin trade
|
@@ -393,6 +398,13 @@ class bybit(Exchange, ImplicitAPI):
|
|
393
398
|
'v5/spot-cross-margin-trade/account': 1, # 50/s => cost = 50 / 50 = 1
|
394
399
|
'v5/spot-cross-margin-trade/orders': 1, # 50/s => cost = 50 / 50 = 1
|
395
400
|
'v5/spot-cross-margin-trade/repay-history': 1, # 50/s => cost = 50 / 50 = 1
|
401
|
+
# crypto loan
|
402
|
+
'v5/crypto-loan/borrowable-collateralisable-number': 5,
|
403
|
+
'v5/crypto-loan/ongoing-orders': 5,
|
404
|
+
'v5/crypto-loan/repayment-history': 5,
|
405
|
+
'v5/crypto-loan/borrow-history': 5,
|
406
|
+
'v5/crypto-loan/max-collateral-amount': 5,
|
407
|
+
'v5/crypto-loan/adjustment-history': 5,
|
396
408
|
# institutional lending
|
397
409
|
'v5/ins-loan/product-infos': 5,
|
398
410
|
'v5/ins-loan/ensure-tokens-convert': 5,
|
@@ -404,7 +416,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
404
416
|
'v5/lending/history-order': 5,
|
405
417
|
'v5/lending/account': 5,
|
406
418
|
# broker
|
407
|
-
'v5/broker/earning-record': 5,
|
419
|
+
'v5/broker/earning-record': 5, # deprecated
|
408
420
|
'v5/broker/earnings-info': 5,
|
409
421
|
'v5/broker/account-info': 5,
|
410
422
|
'v5/broker/asset/query-sub-member-deposit-record': 10,
|
@@ -525,6 +537,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
525
537
|
'v5/spot-cross-margin-trade/loan': 2.5, # 20/s => cost = 50 / 20 = 2.5
|
526
538
|
'v5/spot-cross-margin-trade/repay': 2.5, # 20/s => cost = 50 / 20 = 2.5
|
527
539
|
'v5/spot-cross-margin-trade/switch': 2.5, # 20/s => cost = 50 / 20 = 2.5
|
540
|
+
# crypto loan
|
541
|
+
'v5/crypto-loan/borrow': 5,
|
542
|
+
'v5/crypto-loan/repay': 5,
|
543
|
+
'v5/crypto-loan/adjust-ltv': 5,
|
528
544
|
# institutional lending
|
529
545
|
'v5/ins-loan/association-uid': 5,
|
530
546
|
# c2c lending
|
@@ -535,6 +551,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
535
551
|
'v5/account/set-collateral-switch-batch': 5,
|
536
552
|
# demo trading
|
537
553
|
'v5/account/demo-apply-money': 5,
|
554
|
+
# broker
|
555
|
+
'v5/broker/award/info': 5,
|
556
|
+
'v5/broker/award/distribute-award': 5,
|
557
|
+
'v5/broker/award/distribution-record': 5,
|
538
558
|
},
|
539
559
|
},
|
540
560
|
},
|