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.
@@ -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
- currencyId = self.safe_string(balance, 'currency')
935
- currencyCode = self.safe_currency_code(currencyId)
936
- account = self.account()
937
- account['free'] = self.safe_string(balance, 'available_funds')
938
- account['used'] = self.safe_string(balance, 'maintenance_margin')
939
- account['total'] = self.safe_string(balance, 'equity')
940
- result[currencyCode] = account
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.code_from_options('fetchBalance', params)
954
- currency = self.currency(code)
963
+ code = self.safe_string(params, 'code')
964
+ params = self.omit(params, 'code')
955
965
  request: dict = {
956
- 'currency': currency['id'],
957
966
  }
958
- response = await self.privateGetGetAccountSummary(self.extend(request, params))
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.safe_value(response, 'result', {})
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={}):
@@ -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()
@@ -447,31 +447,43 @@ class kraken(Exchange, ImplicitAPI):
447
447
  },
448
448
  'precisionMode': TICK_SIZE,
449
449
  'exceptions': {
450
- 'EQuery:Invalid asset pair': BadSymbol, # {"error":["EQuery:Invalid asset pair"]}
451
- 'EAPI:Invalid key': AuthenticationError,
452
- 'EFunding:Unknown withdraw key': InvalidAddress, # {"error":["EFunding:Unknown withdraw key"]}
453
- 'EFunding:Invalid amount': InsufficientFunds,
454
- 'EService:Unavailable': ExchangeNotAvailable,
455
- 'EDatabase:Internal error': ExchangeNotAvailable,
456
- 'EService:Busy': ExchangeNotAvailable,
457
- 'EQuery:Unknown asset': BadSymbol, # {"error":["EQuery:Unknown asset"]}
458
- 'EAPI:Rate limit exceeded': DDoSProtection,
459
- 'EOrder:Rate limit exceeded': DDoSProtection,
460
- 'EGeneral:Internal error': ExchangeNotAvailable,
461
- 'EGeneral:Temporary lockout': DDoSProtection,
462
- 'EGeneral:Permission denied': PermissionDenied,
463
- 'EGeneral:Invalid arguments:price': InvalidOrder,
464
- 'EOrder:Unknown order': InvalidOrder,
465
- 'EOrder:Invalid price:Invalid price argument': InvalidOrder,
466
- 'EOrder:Order minimum not met': InvalidOrder,
467
- 'EGeneral:Invalid arguments': BadRequest,
468
- 'ESession:Invalid session': AuthenticationError,
469
- 'EAPI:Invalid nonce': InvalidNonce,
470
- 'EFunding:No funding method': BadRequest, # {"error":"EFunding:No funding method"}
471
- 'EFunding:Unknown asset': BadSymbol, # {"error":["EFunding:Unknown asset"]}
472
- 'EService:Market in post_only mode': OnMaintenance, # {"error":["EService:Market in post_only mode"]}
473
- 'EGeneral:Too many requests': DDoSProtection, # {"error":["EGeneral:Too many requests"]}
474
- 'ETrade:User Locked': AccountSuspended, # {"error":["ETrade:User Locked"]}
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
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.35'
7
+ __version__ = '4.4.36'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
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
- type = 'other' if (rawType is None) else 'crypto'
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
- return self.parse_order(self.extend({'result': order}), market)
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
- orderObject = {'result': order}
1795
- return self.parse_order(orderObject)
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
- transaction = self.parse_transaction(response, currency)
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
- return self.parse_order(order, market)
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
- return self.parse_order(order, market)
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
- request: dict = {
1252
- 'statusKind': 'OPEN',
1253
- }
1254
- return self.fetch_orders(symbol, since, limit, self.extend(request, params))
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
  },