ccxt 4.4.78__py2.py3-none-any.whl → 4.4.80__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.
Files changed (83) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bitmart.py +1 -0
  3. ccxt/apex.py +2 -2
  4. ccxt/ascendex.py +22 -5
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/apex.py +2 -2
  7. ccxt/async_support/ascendex.py +22 -5
  8. ccxt/async_support/base/exchange.py +5 -1
  9. ccxt/async_support/binance.py +6 -0
  10. ccxt/async_support/bingx.py +3 -3
  11. ccxt/async_support/bitfinex.py +59 -34
  12. ccxt/async_support/bitget.py +52 -64
  13. ccxt/async_support/bitmart.py +7 -2
  14. ccxt/async_support/bitmex.py +8 -1
  15. ccxt/async_support/bitopro.py +5 -1
  16. ccxt/async_support/bitrue.py +2 -1
  17. ccxt/async_support/bitso.py +1 -1
  18. ccxt/async_support/bitteam.py +2 -0
  19. ccxt/async_support/bitvavo.py +25 -10
  20. ccxt/async_support/btcalpha.py +1 -1
  21. ccxt/async_support/btcmarkets.py +1 -1
  22. ccxt/async_support/btcturk.py +1 -1
  23. ccxt/async_support/bybit.py +27 -15
  24. ccxt/async_support/coinbase.py +3 -15
  25. ccxt/async_support/coinex.py +1 -0
  26. ccxt/async_support/coinlist.py +1 -0
  27. ccxt/async_support/coinone.py +1 -0
  28. ccxt/async_support/delta.py +3 -0
  29. ccxt/async_support/deribit.py +1 -0
  30. ccxt/async_support/hollaex.py +1 -0
  31. ccxt/async_support/htx.py +7 -3
  32. ccxt/async_support/huobijp.py +1 -0
  33. ccxt/async_support/hyperliquid.py +1 -0
  34. ccxt/async_support/kraken.py +2 -0
  35. ccxt/async_support/okx.py +1 -1
  36. ccxt/async_support/poloniex.py +1 -0
  37. ccxt/async_support/timex.py +2 -2
  38. ccxt/async_support/upbit.py +43 -21
  39. ccxt/async_support/whitebit.py +65 -12
  40. ccxt/base/errors.py +0 -6
  41. ccxt/base/exchange.py +1 -1
  42. ccxt/binance.py +6 -0
  43. ccxt/bingx.py +3 -3
  44. ccxt/bitfinex.py +59 -34
  45. ccxt/bitget.py +52 -64
  46. ccxt/bitmart.py +7 -2
  47. ccxt/bitmex.py +8 -1
  48. ccxt/bitopro.py +5 -1
  49. ccxt/bitrue.py +2 -1
  50. ccxt/bitso.py +1 -1
  51. ccxt/bitteam.py +2 -0
  52. ccxt/bitvavo.py +25 -10
  53. ccxt/btcalpha.py +1 -1
  54. ccxt/btcmarkets.py +1 -1
  55. ccxt/btcturk.py +1 -1
  56. ccxt/bybit.py +27 -15
  57. ccxt/coinbase.py +3 -15
  58. ccxt/coinex.py +1 -0
  59. ccxt/coinlist.py +1 -0
  60. ccxt/coinone.py +1 -0
  61. ccxt/delta.py +3 -0
  62. ccxt/deribit.py +1 -0
  63. ccxt/hollaex.py +1 -0
  64. ccxt/htx.py +7 -3
  65. ccxt/huobijp.py +1 -0
  66. ccxt/hyperliquid.py +1 -0
  67. ccxt/kraken.py +2 -0
  68. ccxt/okx.py +1 -1
  69. ccxt/poloniex.py +1 -0
  70. ccxt/pro/__init__.py +1 -1
  71. ccxt/pro/binance.py +3 -3
  72. ccxt/pro/coinbase.py +40 -52
  73. ccxt/pro/upbit.py +42 -0
  74. ccxt/test/tests_async.py +0 -1
  75. ccxt/test/tests_sync.py +0 -1
  76. ccxt/timex.py +2 -2
  77. ccxt/upbit.py +43 -21
  78. ccxt/whitebit.py +65 -12
  79. {ccxt-4.4.78.dist-info → ccxt-4.4.80.dist-info}/METADATA +9 -11
  80. {ccxt-4.4.78.dist-info → ccxt-4.4.80.dist-info}/RECORD +83 -83
  81. {ccxt-4.4.78.dist-info → ccxt-4.4.80.dist-info}/LICENSE.txt +0 -0
  82. {ccxt-4.4.78.dist-info → ccxt-4.4.80.dist-info}/WHEEL +0 -0
  83. {ccxt-4.4.78.dist-info → ccxt-4.4.80.dist-info}/top_level.txt +0 -0
@@ -225,6 +225,7 @@ class bitmart(Exchange, ImplicitAPI):
225
225
  'contract/private/order': 1.2,
226
226
  'contract/private/order-history': 10,
227
227
  'contract/private/position': 10,
228
+ 'contract/private/position-v2': 10,
228
229
  'contract/private/get-open-orders': 1.2,
229
230
  'contract/private/current-plan-order': 1.2,
230
231
  'contract/private/trades': 10,
@@ -1214,6 +1215,7 @@ class bitmart(Exchange, ImplicitAPI):
1214
1215
  # {
1215
1216
  # "currency": "BTC",
1216
1217
  # "name": "Bitcoin",
1218
+ # "recharge_minsize": '0.00000001',
1217
1219
  # "contract_address": null,
1218
1220
  # "network": "BTC",
1219
1221
  # "withdraw_enabled": True,
@@ -1235,7 +1237,8 @@ class bitmart(Exchange, ImplicitAPI):
1235
1237
  fullId = self.safe_string(currency, 'currency')
1236
1238
  currencyId = fullId
1237
1239
  networkId = self.safe_string(currency, 'network')
1238
- if fullId.find('NFT') < 0:
1240
+ isNtf = (fullId.find('NFT') >= 0)
1241
+ if not isNtf:
1239
1242
  parts = fullId.split('-')
1240
1243
  currencyId = self.safe_string(parts, 0)
1241
1244
  second = self.safe_string(parts, 1)
@@ -1254,6 +1257,7 @@ class bitmart(Exchange, ImplicitAPI):
1254
1257
  'withdraw': None,
1255
1258
  'active': None,
1256
1259
  'networks': {},
1260
+ 'type': 'other' if isNtf else 'crypto',
1257
1261
  }
1258
1262
  networkCode = self.network_id_to_code(networkId)
1259
1263
  withdraw = self.safe_bool(currency, 'withdraw_enabled')
@@ -4659,6 +4663,7 @@ class bitmart(Exchange, ImplicitAPI):
4659
4663
  fetch all open contract positions
4660
4664
 
4661
4665
  https://developer-pro.bitmart.com/en/futuresv2/#get-current-position-keyed
4666
+ https://developer-pro.bitmart.com/en/futuresv2/#get-current-position-v2-keyed
4662
4667
 
4663
4668
  :param str[]|None symbols: list of unified market symbols
4664
4669
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4675,7 +4680,7 @@ class bitmart(Exchange, ImplicitAPI):
4675
4680
  if symbolsLength == 1:
4676
4681
  # only supports symbols or sending one symbol
4677
4682
  request['symbol'] = market['id']
4678
- response = await self.privateGetContractPrivatePosition(self.extend(request, params))
4683
+ response = await self.privateGetContractPrivatePositionV2(self.extend(request, params))
4679
4684
  #
4680
4685
  # {
4681
4686
  # "code": 1000,
@@ -503,6 +503,7 @@ class bitmex(Exchange, ImplicitAPI):
503
503
  maxWithdrawal = self.parse_number(Precise.string_mul(maxWithdrawalString, precisionString))
504
504
  minDepositString = self.safe_string(currency, 'minDepositAmount')
505
505
  minDeposit = self.parse_number(Precise.string_mul(minDepositString, precisionString))
506
+ isCrypto = self.safe_string(currency, 'currencyType') == 'Crypto'
506
507
  result[code] = {
507
508
  'id': id,
508
509
  'code': code,
@@ -528,6 +529,7 @@ class bitmex(Exchange, ImplicitAPI):
528
529
  },
529
530
  },
530
531
  'networks': networks,
532
+ 'type': 'crypto' if isCrypto else 'other',
531
533
  }
532
534
  return result
533
535
 
@@ -756,6 +758,11 @@ class bitmex(Exchange, ImplicitAPI):
756
758
  maxOrderQty = self.safe_number(market, 'maxOrderQty')
757
759
  initMargin = self.safe_string(market, 'initMargin', '1')
758
760
  maxLeverage = self.parse_number(Precise.string_div('1', initMargin))
761
+ # subtype should be None for spot markets
762
+ if spot:
763
+ isInverse = None
764
+ isQuanto = None
765
+ linear = None
759
766
  return {
760
767
  'id': id,
761
768
  'symbol': symbol,
@@ -805,7 +812,7 @@ class bitmex(Exchange, ImplicitAPI):
805
812
  'max': maxOrderQty if positionIsQuote else None,
806
813
  },
807
814
  },
808
- 'created': self.parse8601(self.safe_string(market, 'listing')),
815
+ 'created': None, # 'listing' field is buggy, e.g. 2200-02-01T00:00:00.000Z
809
816
  'info': market,
810
817
  }
811
818
 
@@ -245,6 +245,7 @@ class bitopro(Exchange, ImplicitAPI):
245
245
  'BEP20': 'BSC',
246
246
  'BSC': 'BSC',
247
247
  },
248
+ 'fiatCurrencies': ['TWD'], # the only fiat currency for exchange
248
249
  },
249
250
  'features': {
250
251
  'spot': {
@@ -373,6 +374,7 @@ class bitopro(Exchange, ImplicitAPI):
373
374
  # }
374
375
  #
375
376
  result: dict = {}
377
+ fiatCurrencies = self.safe_list(self.options, 'fiatCurrencies', [])
376
378
  for i in range(0, len(currencies)):
377
379
  currency = currencies[i]
378
380
  currencyId = self.safe_string(currency, 'currency')
@@ -392,11 +394,12 @@ class bitopro(Exchange, ImplicitAPI):
392
394
  'max': None,
393
395
  },
394
396
  }
397
+ isFiat = self.in_array(code, fiatCurrencies)
395
398
  result[code] = {
396
399
  'id': currencyId,
397
400
  'code': code,
398
401
  'info': currency,
399
- 'type': None,
402
+ 'type': 'fiat' if isFiat else 'crypto',
400
403
  'name': None,
401
404
  'active': deposit and withdraw,
402
405
  'deposit': deposit,
@@ -404,6 +407,7 @@ class bitopro(Exchange, ImplicitAPI):
404
407
  'fee': fee,
405
408
  'precision': None,
406
409
  'limits': limits,
410
+ 'networks': None,
407
411
  }
408
412
  return result
409
413
 
@@ -834,7 +834,8 @@ class bitrue(Exchange, ImplicitAPI):
834
834
  'withdraw': withdraw,
835
835
  'networks': networks,
836
836
  'fee': self.parse_number(minWithdrawFeeString),
837
- # 'fees': fees,
837
+ 'fees': None,
838
+ 'type': 'crypto',
838
839
  'limits': {
839
840
  'withdraw': {
840
841
  'min': self.parse_number(minWithdrawString),
@@ -742,7 +742,7 @@ class bitso(Exchange, ImplicitAPI):
742
742
  # {
743
743
  # "bucket_start_time":1648219140000,
744
744
  # "first_trade_time":1648219154990,
745
- # "last_trade_time":1648219189441,
745
+ # "last_trade_time":1648219189442,
746
746
  # "first_rate":"44958.60",
747
747
  # "last_rate":"44979.88",
748
748
  # "min_rate":"44957.33",
@@ -650,6 +650,7 @@ class bitteam(Exchange, ImplicitAPI):
650
650
  networkIds = list(feesByNetworkId.keys())
651
651
  networks: dict = {}
652
652
  networkPrecision = self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals')))
653
+ typeRaw = self.safe_string(currency, 'type')
653
654
  for j in range(0, len(networkIds)):
654
655
  networkId = networkIds[j]
655
656
  networkCode = self.network_id_to_code(networkId, code)
@@ -703,6 +704,7 @@ class bitteam(Exchange, ImplicitAPI):
703
704
  'max': None,
704
705
  },
705
706
  },
707
+ 'type': typeRaw, # 'crypto' or 'fiat'
706
708
  'networks': networks,
707
709
  }
708
710
  return result
@@ -361,6 +361,8 @@ class bitvavo(Exchange, ImplicitAPI):
361
361
  'ERC20': 'ETH',
362
362
  'TRC20': 'TRX',
363
363
  },
364
+ 'operatorId': None, # self will be required soon for order-related endpoints
365
+ 'fiatCurrencies': ['EUR'], # only fiat atm
364
366
  },
365
367
  'precisionMode': SIGNIFICANT_DIGITS,
366
368
  'commonCurrencies': {
@@ -567,24 +569,24 @@ class bitvavo(Exchange, ImplicitAPI):
567
569
  # },
568
570
  # ]
569
571
  #
572
+ fiatCurrencies = self.safe_list(self.options, 'fiatCurrencies', [])
570
573
  result: dict = {}
571
574
  for i in range(0, len(currencies)):
572
575
  currency = currencies[i]
573
576
  id = self.safe_string(currency, 'symbol')
574
577
  code = self.safe_currency_code(id)
578
+ isFiat = self.in_array(code, fiatCurrencies)
575
579
  networks: dict = {}
576
- networksArray = self.safe_value(currency, 'networks', [])
577
- networksLength = len(networksArray)
578
- isOneNetwork = (networksLength == 1)
579
- deposit = (self.safe_value(currency, 'depositStatus') == 'OK')
580
- withdrawal = (self.safe_value(currency, 'withdrawalStatus') == 'OK')
580
+ networksArray = self.safe_list(currency, 'networks', [])
581
+ deposit = self.safe_string(currency, 'depositStatus') == 'OK'
582
+ withdrawal = self.safe_string(currency, 'withdrawalStatus') == 'OK'
581
583
  active = deposit and withdrawal
582
584
  withdrawFee = self.safe_number(currency, 'withdrawalFee')
583
585
  precision = self.safe_integer(currency, 'decimals', 8)
584
586
  minWithdraw = self.safe_number(currency, 'withdrawalMinAmount')
585
- # absolutely all of them have 1 network atm - ETH. So, we can reliably assign that inside networks
586
- if isOneNetwork:
587
- networkId = networksArray[0]
587
+ # btw, absolutely all of them have 1 network atm
588
+ for j in range(0, len(networksArray)):
589
+ networkId = networksArray[j]
588
590
  networkCode = self.network_id_to_code(networkId)
589
591
  networks[networkCode] = {
590
592
  'info': currency,
@@ -602,7 +604,7 @@ class bitvavo(Exchange, ImplicitAPI):
602
604
  },
603
605
  },
604
606
  }
605
- result[code] = {
607
+ result[code] = self.safe_currency_structure({
606
608
  'info': currency,
607
609
  'id': id,
608
610
  'code': code,
@@ -613,6 +615,7 @@ class bitvavo(Exchange, ImplicitAPI):
613
615
  'networks': networks,
614
616
  'fee': withdrawFee,
615
617
  'precision': precision,
618
+ 'type': 'fiat' if isFiat else 'crypto',
616
619
  'limits': {
617
620
  'amount': {
618
621
  'min': None,
@@ -627,7 +630,7 @@ class bitvavo(Exchange, ImplicitAPI):
627
630
  'max': None,
628
631
  },
629
632
  },
630
- }
633
+ })
631
634
  # set currencies here to avoid calling publicGetAssets twice
632
635
  self.currencies = self.deep_extend(self.currencies, result)
633
636
  return result
@@ -1166,6 +1169,10 @@ class bitvavo(Exchange, ImplicitAPI):
1166
1169
  request['timeInForce'] = timeInForce
1167
1170
  if postOnly:
1168
1171
  request['postOnly'] = True
1172
+ operatorId = None
1173
+ operatorId, params = self.handle_option_and_params(params, 'createOrder', 'operatorId')
1174
+ if operatorId is not None:
1175
+ request['operatorId'] = self.parse_to_int(operatorId)
1169
1176
  return self.extend(request, params)
1170
1177
 
1171
1178
  async def create_order(self, symbol: Str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
@@ -1259,6 +1266,10 @@ class bitvavo(Exchange, ImplicitAPI):
1259
1266
  clientOrderId = self.safe_string(params, 'clientOrderId')
1260
1267
  if clientOrderId is None:
1261
1268
  request['orderId'] = id
1269
+ operatorId = None
1270
+ operatorId, params = self.handle_option_and_params(params, 'editOrder', 'operatorId')
1271
+ if operatorId is not None:
1272
+ request['operatorId'] = self.parse_to_int(operatorId)
1262
1273
  request['market'] = market['id']
1263
1274
  return request
1264
1275
 
@@ -1293,6 +1304,10 @@ class bitvavo(Exchange, ImplicitAPI):
1293
1304
  clientOrderId = self.safe_string(params, 'clientOrderId')
1294
1305
  if clientOrderId is None:
1295
1306
  request['orderId'] = id
1307
+ operatorId = None
1308
+ operatorId, params = self.handle_option_and_params(params, 'cancelOrder', 'operatorId')
1309
+ if operatorId is not None:
1310
+ request['operatorId'] = self.parse_to_int(operatorId)
1296
1311
  return self.extend(request, params)
1297
1312
 
1298
1313
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
@@ -216,7 +216,7 @@ class btcalpha(Exchange, ImplicitAPI):
216
216
  'symbolRequired': False,
217
217
  },
218
218
  'fetchOHLCV': {
219
- 'max': 720,
219
+ 'limit': 720,
220
220
  },
221
221
  },
222
222
  'swap': {
@@ -455,7 +455,7 @@ class btcmarkets(Exchange, ImplicitAPI):
455
455
  # "marketId":"COMP-AUD",
456
456
  # "baseAssetName":"COMP",
457
457
  # "quoteAssetName":"AUD",
458
- # "minOrderAmount":"0.00007",
458
+ # "minOrderAmount":"0.00006",
459
459
  # "maxOrderAmount":"1000000",
460
460
  # "amountDecimals":"8",
461
461
  # "priceDecimals":"2",
@@ -248,7 +248,7 @@ class btcturk(Exchange, ImplicitAPI):
248
248
  # "minPrice": "0.0000000000001",
249
249
  # "maxPrice": "10000000",
250
250
  # "tickSize": "10",
251
- # "minExchangeValue": "99.91",
251
+ # "minExchangeValue": "99.92",
252
252
  # "minAmount": null,
253
253
  # "maxAmount": null
254
254
  # }
@@ -1041,9 +1041,6 @@ class bybit(Exchange, ImplicitAPI):
1041
1041
  'usePrivateInstrumentsInfo': False,
1042
1042
  'enableDemoTrading': False,
1043
1043
  'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
1044
- 'createOrder': {
1045
- 'method': 'privatePostV5OrderCreate', # 'privatePostV5PositionTradingStop'
1046
- },
1047
1044
  'enableUnifiedMargin': None,
1048
1045
  'enableUnifiedAccount': None,
1049
1046
  'unifiedMarginStatus': None,
@@ -2142,7 +2139,7 @@ class bybit(Exchange, ImplicitAPI):
2142
2139
  'quoteId': quoteId,
2143
2140
  'settleId': settleId,
2144
2141
  'type': 'option',
2145
- 'subType': 'linear',
2142
+ 'subType': None,
2146
2143
  'spot': False,
2147
2144
  'margin': False,
2148
2145
  'swap': False,
@@ -2150,8 +2147,8 @@ class bybit(Exchange, ImplicitAPI):
2150
2147
  'option': True,
2151
2148
  'active': isActive,
2152
2149
  'contract': True,
2153
- 'linear': True,
2154
- 'inverse': False,
2150
+ 'linear': None,
2151
+ 'inverse': None,
2155
2152
  'taker': self.safe_number(market, 'takerFee', self.parse_number('0.0006')),
2156
2153
  'maker': self.safe_number(market, 'makerFee', self.parse_number('0.0001')),
2157
2154
  'contractSize': self.parse_number('1'),
@@ -3775,12 +3772,21 @@ class bybit(Exchange, ImplicitAPI):
3775
3772
  parts = await self.is_unified_enabled()
3776
3773
  enableUnifiedAccount = parts[1]
3777
3774
  trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trailingStop')
3775
+ stopLossPrice = self.safe_string(params, 'stopLossPrice')
3776
+ takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
3778
3777
  isTrailingAmountOrder = trailingAmount is not None
3778
+ isStopLoss = stopLossPrice is not None
3779
+ isTakeProfit = takeProfitPrice is not None
3779
3780
  orderRequest = self.create_order_request(symbol, type, side, amount, price, params, enableUnifiedAccount)
3780
- options = self.safe_dict(self.options, 'createOrder', {})
3781
- defaultMethod = self.safe_string(options, 'method', 'privatePostV5OrderCreate')
3781
+ defaultMethod = None
3782
+ if isTrailingAmountOrder or isStopLoss or isTakeProfit:
3783
+ defaultMethod = 'privatePostV5PositionTradingStop'
3784
+ else:
3785
+ defaultMethod = 'privatePostV5OrderCreate'
3786
+ method = None
3787
+ method, params = self.handle_option_and_params(params, 'createOrder', 'method', defaultMethod)
3782
3788
  response = None
3783
- if isTrailingAmountOrder or (defaultMethod == 'privatePostV5PositionTradingStop'):
3789
+ if method == 'privatePostV5PositionTradingStop':
3784
3790
  response = await self.privatePostV5PositionTradingStop(orderRequest)
3785
3791
  else:
3786
3792
  response = await self.privatePostV5OrderCreate(orderRequest) # already extended inside createOrderRequest
@@ -3805,8 +3811,6 @@ class bybit(Exchange, ImplicitAPI):
3805
3811
  lowerCaseType = type.lower()
3806
3812
  if (price is None) and (lowerCaseType == 'limit'):
3807
3813
  raise ArgumentsRequired(self.id + ' createOrder requires a price argument for limit orders')
3808
- defaultMethod = None
3809
- defaultMethod, params = self.handle_option_and_params(params, 'createOrder', 'method', 'privatePostV5OrderCreate')
3810
3814
  request: dict = {
3811
3815
  'symbol': market['id'],
3812
3816
  # 'side': self.capitalize(side),
@@ -3850,7 +3854,14 @@ class bybit(Exchange, ImplicitAPI):
3850
3854
  isMarket = lowerCaseType == 'market'
3851
3855
  isLimit = lowerCaseType == 'limit'
3852
3856
  isBuy = side == 'buy'
3853
- isAlternativeEndpoint = defaultMethod == 'privatePostV5PositionTradingStop'
3857
+ defaultMethod = None
3858
+ if isTrailingAmountOrder or isStopLossTriggerOrder or isTakeProfitTriggerOrder:
3859
+ defaultMethod = 'privatePostV5PositionTradingStop'
3860
+ else:
3861
+ defaultMethod = 'privatePostV5OrderCreate'
3862
+ method = None
3863
+ method, params = self.handle_option_and_params(params, 'createOrder', 'method', defaultMethod)
3864
+ isAlternativeEndpoint = method == 'privatePostV5PositionTradingStop'
3854
3865
  amountString = self.get_amount(symbol, amount)
3855
3866
  priceString = self.get_price(symbol, self.number_to_string(price)) if (price is not None) else None
3856
3867
  if isTrailingAmountOrder or isAlternativeEndpoint:
@@ -3901,12 +3912,12 @@ class bybit(Exchange, ImplicitAPI):
3901
3912
  request['price'] = priceString
3902
3913
  if market['spot']:
3903
3914
  request['category'] = 'spot'
3915
+ elif market['option']:
3916
+ request['category'] = 'option'
3904
3917
  elif market['linear']:
3905
3918
  request['category'] = 'linear'
3906
3919
  elif market['inverse']:
3907
3920
  request['category'] = 'inverse'
3908
- elif market['option']:
3909
- request['category'] = 'option'
3910
3921
  cost = self.safe_string(params, 'cost')
3911
3922
  params = self.omit(params, 'cost')
3912
3923
  # if the cost is inferable, let's keep the old logic and ignore marketUnit, to minimize the impact of the changes
@@ -5651,7 +5662,8 @@ classic accounts only/ spot not supported* fetches information on an order made
5651
5662
  subType, params = self.handle_sub_type_and_params('fetchLedger', None, params)
5652
5663
  response = None
5653
5664
  if enableUnified[1]:
5654
- if subType == 'inverse':
5665
+ unifiedMarginStatus = self.safe_integer(self.options, 'unifiedMarginStatus', 5) # 3/4 uta 1.0, 5/6 uta 2.0
5666
+ if subType == 'inverse' and (unifiedMarginStatus < 5):
5655
5667
  response = await self.privateGetV5AccountContractTransactionLog(self.extend(request, params))
5656
5668
  else:
5657
5669
  response = await self.privateGetV5AccountTransactionLog(self.extend(request, params))
@@ -387,7 +387,6 @@ class coinbase(Exchange, ImplicitAPI):
387
387
  'fetchBalance': 'v2PrivateGetAccounts', # 'v2PrivateGetAccounts' or 'v3PrivateGetBrokerageAccounts'
388
388
  'fetchTime': 'v2PublicGetTime', # 'v2PublicGetTime' or 'v3PublicGetBrokerageTime'
389
389
  'user_native_currency': 'USD', # needed to get fees for v3
390
- 'aliasCbMarketIds': {},
391
390
  },
392
391
  'features': {
393
392
  'default': {
@@ -1475,8 +1474,6 @@ class coinbase(Exchange, ImplicitAPI):
1475
1474
  perpetualData = self.safe_list(perpetualFutures, 'products', [])
1476
1475
  for i in range(0, len(perpetualData)):
1477
1476
  result.append(self.parse_contract_market(perpetualData[i], perpetualFeeTier))
1478
- # remove aliases
1479
- self.options['aliasCbMarketIds'] = {}
1480
1477
  newMarkets = []
1481
1478
  for i in range(0, len(result)):
1482
1479
  market = result[i]
@@ -1484,21 +1481,12 @@ class coinbase(Exchange, ImplicitAPI):
1484
1481
  realMarketIds = self.safe_list(info, 'alias_to', [])
1485
1482
  length = len(realMarketIds)
1486
1483
  if length > 0:
1487
- self.options['aliasCbMarketIds'][market['id']] = realMarketIds[0]
1488
- self.options['aliasCbMarketIds'][market['symbol']] = realMarketIds[0]
1484
+ market['alias'] = realMarketIds[0]
1489
1485
  else:
1490
- newMarkets.append(market)
1486
+ market['alias'] = None
1487
+ newMarkets.append(market)
1491
1488
  return newMarkets
1492
1489
 
1493
- def market(self, symbol: str) -> MarketInterface:
1494
- finalSymbol = self.safe_string(self.options['aliasCbMarketIds'], symbol, symbol)
1495
- return super(coinbase, self).market(finalSymbol)
1496
-
1497
- def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
1498
- if marketId in self.options['aliasCbMarketIds']:
1499
- return self.market(marketId)
1500
- return super(coinbase, self).safe_market(marketId, market, delimiter, marketType)
1501
-
1502
1490
  def parse_spot_market(self, market, feeTier) -> MarketInterface:
1503
1491
  #
1504
1492
  # {
@@ -758,6 +758,7 @@ class coinex(Exchange, ImplicitAPI):
758
758
  },
759
759
  },
760
760
  'networks': {},
761
+ 'type': 'crypto',
761
762
  'info': coin,
762
763
  }
763
764
  for j in range(0, len(chains)):
@@ -489,6 +489,7 @@ class coinlist(Exchange, ImplicitAPI):
489
489
  'withdraw': {'min': minWithdrawal, 'max': None},
490
490
  },
491
491
  'networks': {},
492
+ 'type': 'crypto',
492
493
  }
493
494
  return result
494
495
 
@@ -330,6 +330,7 @@ class coinone(Exchange, ImplicitAPI):
330
330
  },
331
331
  },
332
332
  'networks': {},
333
+ 'type': 'crypto',
333
334
  }
334
335
  return result
335
336
 
@@ -357,6 +357,8 @@ class delta(Exchange, ImplicitAPI):
357
357
  base = self.safe_string(optionParts, 1)
358
358
  expiry = self.safe_string(optionParts, 3)
359
359
  optionType = self.safe_string(optionParts, 0)
360
+ if expiry is not None:
361
+ expiry = expiry[4:] + expiry[2:4] + expiry[0:2]
360
362
  settle = quote
361
363
  strike = self.safe_string(optionParts, 2)
362
364
  datetime = self.convert_expire_date(expiry)
@@ -567,6 +569,7 @@ class delta(Exchange, ImplicitAPI):
567
569
  },
568
570
  },
569
571
  'networks': {},
572
+ 'type': 'crypto',
570
573
  }
571
574
  return result
572
575
 
@@ -655,6 +655,7 @@ class deribit(Exchange, ImplicitAPI):
655
655
  'active': None,
656
656
  'deposit': None,
657
657
  'withdraw': None,
658
+ 'type': 'crypto',
658
659
  'fee': self.safe_number(currency, 'withdrawal_fee'),
659
660
  'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'fee_precision'))),
660
661
  'limits': {
@@ -493,6 +493,7 @@ class hollaex(Exchange, ImplicitAPI):
493
493
  },
494
494
  },
495
495
  'networks': {},
496
+ 'type': 'crypto',
496
497
  }
497
498
  return result
498
499
 
ccxt/async_support/htx.py CHANGED
@@ -963,6 +963,7 @@ class htx(Exchange, ImplicitAPI):
963
963
  },
964
964
  'precisionMode': TICK_SIZE,
965
965
  'options': {
966
+ 'include_OS_certificates': False, # temporarily leave self, remove in future
966
967
  'fetchMarkets': {
967
968
  'types': {
968
969
  'spot': True,
@@ -2173,14 +2174,14 @@ class htx(Exchange, ImplicitAPI):
2173
2174
  ask = None
2174
2175
  askVolume = None
2175
2176
  if 'bid' in ticker:
2176
- if isinstance(ticker['bid'], list):
2177
+ if ticker['bid'] is not None and isinstance(ticker['bid'], list):
2177
2178
  bid = self.safe_string(ticker['bid'], 0)
2178
2179
  bidVolume = self.safe_string(ticker['bid'], 1)
2179
2180
  else:
2180
2181
  bid = self.safe_string(ticker, 'bid')
2181
2182
  bidVolume = self.safe_string(ticker, 'bidSize')
2182
2183
  if 'ask' in ticker:
2183
- if isinstance(ticker['ask'], list):
2184
+ if ticker['ask'] is not None and isinstance(ticker['ask'], list):
2184
2185
  ask = self.safe_string(ticker['ask'], 0)
2185
2186
  askVolume = self.safe_string(ticker['ask'], 1)
2186
2187
  else:
@@ -3271,7 +3272,7 @@ class htx(Exchange, ImplicitAPI):
3271
3272
  # "withdrawQuotaPerYear": null,
3272
3273
  # "withdrawQuotaTotal": null,
3273
3274
  # "withdrawFeeType": "fixed",
3274
- # "transactFeeWithdraw": "11.1653",
3275
+ # "transactFeeWithdraw": "11.1654",
3275
3276
  # "addrWithTag": False,
3276
3277
  # "addrDepositTag": False
3277
3278
  # }
@@ -3294,6 +3295,8 @@ class htx(Exchange, ImplicitAPI):
3294
3295
  chains = self.safe_value(entry, 'chains', [])
3295
3296
  networks: dict = {}
3296
3297
  instStatus = self.safe_string(entry, 'instStatus')
3298
+ assetType = self.safe_string(entry, 'assetType')
3299
+ type = assetType == 'crypto' if '1' else 'fiat'
3297
3300
  currencyActive = instStatus == 'normal'
3298
3301
  minPrecision = None
3299
3302
  minDeposit = None
@@ -3351,6 +3354,7 @@ class htx(Exchange, ImplicitAPI):
3351
3354
  'withdraw': withdraw,
3352
3355
  'fee': None,
3353
3356
  'name': None,
3357
+ 'type': type,
3354
3358
  'limits': {
3355
3359
  'amount': {
3356
3360
  'min': None,
@@ -1110,6 +1110,7 @@ class huobijp(Exchange, ImplicitAPI):
1110
1110
  'withdraw': withdrawEnabled,
1111
1111
  'fee': None, # todo need to fetch from fee endpoint
1112
1112
  'precision': precision,
1113
+ 'networks': None,
1113
1114
  'limits': {
1114
1115
  'amount': {
1115
1116
  'min': precision,
@@ -380,6 +380,7 @@ class hyperliquid(Exchange, ImplicitAPI):
380
380
  'withdraw': None,
381
381
  'networks': None,
382
382
  'fee': None,
383
+ 'type': 'crypto',
383
384
  'limits': {
384
385
  'amount': {
385
386
  'min': None,
@@ -864,12 +864,14 @@ class kraken(Exchange, ImplicitAPI):
864
864
  precision = self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals')))
865
865
  # assumes all currencies are active except those listed above
866
866
  active = self.safe_string(currency, 'status') == 'enabled'
867
+ isFiat = code.find('.HOLD') >= 0
867
868
  result[code] = {
868
869
  'id': id,
869
870
  'code': code,
870
871
  'info': currency,
871
872
  'name': self.safe_string(currency, 'altname'),
872
873
  'active': active,
874
+ 'type': 'fiat' if isFiat else 'crypto',
873
875
  'deposit': None,
874
876
  'withdraw': None,
875
877
  'fee': None,
ccxt/async_support/okx.py CHANGED
@@ -4832,7 +4832,7 @@ class okx(Exchange, ImplicitAPI):
4832
4832
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
4833
4833
  """
4834
4834
  await self.load_markets()
4835
- rawNetwork = self.safe_string_upper(params, 'network')
4835
+ rawNetwork = self.safe_string(params, 'network') # some networks are like "Dora Vota Mainnet"
4836
4836
  params = self.omit(params, 'network')
4837
4837
  code = self.safe_currency_code(code)
4838
4838
  network = self.network_id_to_code(rawNetwork, code)
@@ -1204,6 +1204,7 @@ class poloniex(Exchange, ImplicitAPI):
1204
1204
  'withdraw': withdrawEnabled,
1205
1205
  'fee': self.parse_number(feeString),
1206
1206
  'precision': None,
1207
+ 'type': 'crypto',
1207
1208
  'limits': {
1208
1209
  'amount': {
1209
1210
  'min': None,
@@ -1526,7 +1526,7 @@ class timex(Exchange, ImplicitAPI):
1526
1526
  'cost': feeCost,
1527
1527
  'currency': feeCurrency,
1528
1528
  }
1529
- return {
1529
+ return self.safe_trade({
1530
1530
  'info': trade,
1531
1531
  'id': id,
1532
1532
  'timestamp': timestamp,
@@ -1540,7 +1540,7 @@ class timex(Exchange, ImplicitAPI):
1540
1540
  'cost': cost,
1541
1541
  'takerOrMaker': takerOrMaker,
1542
1542
  'fee': fee,
1543
- }
1543
+ })
1544
1544
 
1545
1545
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
1546
1546
  #