ccxt 4.4.78__py2.py3-none-any.whl → 4.4.82__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 (87) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bitmart.py +1 -0
  3. ccxt/apex.py +21 -31
  4. ccxt/ascendex.py +23 -6
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/apex.py +21 -31
  7. ccxt/async_support/ascendex.py +23 -6
  8. ccxt/async_support/base/exchange.py +5 -1
  9. ccxt/async_support/bigone.py +17 -14
  10. ccxt/async_support/binance.py +6 -0
  11. ccxt/async_support/bingx.py +16 -35
  12. ccxt/async_support/bitfinex.py +120 -82
  13. ccxt/async_support/bitget.py +58 -66
  14. ccxt/async_support/bitmart.py +7 -2
  15. ccxt/async_support/bitmex.py +8 -1
  16. ccxt/async_support/bitopro.py +5 -1
  17. ccxt/async_support/bitrue.py +2 -1
  18. ccxt/async_support/bitso.py +1 -1
  19. ccxt/async_support/bitteam.py +2 -0
  20. ccxt/async_support/bitvavo.py +25 -10
  21. ccxt/async_support/btcalpha.py +1 -1
  22. ccxt/async_support/btcmarkets.py +1 -1
  23. ccxt/async_support/btcturk.py +1 -1
  24. ccxt/async_support/bybit.py +29 -15
  25. ccxt/async_support/coinbase.py +3 -15
  26. ccxt/async_support/coinex.py +1 -0
  27. ccxt/async_support/coinlist.py +1 -0
  28. ccxt/async_support/coinone.py +1 -0
  29. ccxt/async_support/delta.py +3 -0
  30. ccxt/async_support/deribit.py +1 -0
  31. ccxt/async_support/hollaex.py +1 -0
  32. ccxt/async_support/htx.py +9 -5
  33. ccxt/async_support/huobijp.py +1 -0
  34. ccxt/async_support/hyperliquid.py +14 -0
  35. ccxt/async_support/kraken.py +2 -0
  36. ccxt/async_support/okx.py +2 -3
  37. ccxt/async_support/oxfun.py +21 -1
  38. ccxt/async_support/poloniex.py +1 -0
  39. ccxt/async_support/timex.py +2 -2
  40. ccxt/async_support/upbit.py +43 -21
  41. ccxt/async_support/whitebit.py +65 -12
  42. ccxt/base/exchange.py +20 -2
  43. ccxt/bigone.py +17 -14
  44. ccxt/binance.py +6 -0
  45. ccxt/bingx.py +16 -35
  46. ccxt/bitfinex.py +120 -82
  47. ccxt/bitget.py +58 -66
  48. ccxt/bitmart.py +7 -2
  49. ccxt/bitmex.py +8 -1
  50. ccxt/bitopro.py +5 -1
  51. ccxt/bitrue.py +2 -1
  52. ccxt/bitso.py +1 -1
  53. ccxt/bitteam.py +2 -0
  54. ccxt/bitvavo.py +25 -10
  55. ccxt/btcalpha.py +1 -1
  56. ccxt/btcmarkets.py +1 -1
  57. ccxt/btcturk.py +1 -1
  58. ccxt/bybit.py +29 -15
  59. ccxt/coinbase.py +3 -15
  60. ccxt/coinex.py +1 -0
  61. ccxt/coinlist.py +1 -0
  62. ccxt/coinone.py +1 -0
  63. ccxt/delta.py +3 -0
  64. ccxt/deribit.py +1 -0
  65. ccxt/hollaex.py +1 -0
  66. ccxt/htx.py +9 -5
  67. ccxt/huobijp.py +1 -0
  68. ccxt/hyperliquid.py +14 -0
  69. ccxt/kraken.py +2 -0
  70. ccxt/okx.py +2 -3
  71. ccxt/oxfun.py +21 -1
  72. ccxt/poloniex.py +1 -0
  73. ccxt/pro/__init__.py +1 -1
  74. ccxt/pro/binance.py +3 -3
  75. ccxt/pro/coinbase.py +41 -53
  76. ccxt/pro/hyperliquid.py +10 -2
  77. ccxt/pro/upbit.py +42 -0
  78. ccxt/test/tests_async.py +0 -1
  79. ccxt/test/tests_sync.py +0 -1
  80. ccxt/timex.py +2 -2
  81. ccxt/upbit.py +43 -21
  82. ccxt/whitebit.py +65 -12
  83. {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/METADATA +9 -13
  84. {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/RECORD +87 -87
  85. {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/LICENSE.txt +0 -0
  86. {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/WHEEL +0 -0
  87. {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/top_level.txt +0 -0
@@ -752,6 +752,7 @@ class bitfinex(Exchange, ImplicitAPI):
752
752
  'pub:map:currency:explorer', # maps symbols to their recognised block explorer URLs
753
753
  'pub:map:currency:tx:fee', # maps currencies to their withdrawal fees https://github.com/ccxt/ccxt/issues/7745,
754
754
  'pub:map:tx:method', # maps withdrawal/deposit methods to their API symbols
755
+ 'pub:info:tx:status', # maps withdrawal/deposit statuses, coins: 1 = enabled, 0 = maintenance
755
756
  ]
756
757
  config = ','.join(labels)
757
758
  request: dict = {
@@ -834,40 +835,81 @@ class bitfinex(Exchange, ImplicitAPI):
834
835
  # ["ABS",[0,131.3]],
835
836
  # ["ADA",[0,0.3]],
836
837
  # ],
838
+ # # deposit/withdrawal data
839
+ # [
840
+ # ["BITCOIN", 1, 1, null, null, null, null, 0, 0, null, null, 3],
841
+ # ...
842
+ # ]
837
843
  # ]
838
844
  #
839
845
  indexed: dict = {
840
- 'sym': self.index_by(self.safe_value(response, 1, []), 0),
841
- 'label': self.index_by(self.safe_value(response, 2, []), 0),
842
- 'unit': self.index_by(self.safe_value(response, 3, []), 0),
843
- 'undl': self.index_by(self.safe_value(response, 4, []), 0),
844
- 'pool': self.index_by(self.safe_value(response, 5, []), 0),
845
- 'explorer': self.index_by(self.safe_value(response, 6, []), 0),
846
- 'fees': self.index_by(self.safe_value(response, 7, []), 0),
846
+ 'sym': self.index_by(self.safe_list(response, 1, []), 0),
847
+ 'label': self.index_by(self.safe_list(response, 2, []), 0),
848
+ 'unit': self.index_by(self.safe_list(response, 3, []), 0),
849
+ 'undl': self.index_by(self.safe_list(response, 4, []), 0),
850
+ 'pool': self.index_by(self.safe_list(response, 5, []), 0),
851
+ 'explorer': self.index_by(self.safe_list(response, 6, []), 0),
852
+ 'fees': self.index_by(self.safe_list(response, 7, []), 0),
853
+ 'networks': self.safe_list(response, 8, []),
854
+ 'statuses': self.index_by(self.safe_list(response, 9, []), 0),
847
855
  }
848
- ids = self.safe_value(response, 0, [])
856
+ indexedNetworks: dict = {}
857
+ for i in range(0, len(indexed['networks'])):
858
+ networkObj = indexed['networks'][i]
859
+ networkId = self.safe_string(networkObj, 0)
860
+ valuesList = self.safe_list(networkObj, 1)
861
+ networkName = self.safe_string(valuesList, 0)
862
+ # for GOlang transpiler, do with "safe" method
863
+ networksList = self.safe_list(indexedNetworks, networkName, [])
864
+ networksList.append(networkId)
865
+ indexedNetworks[networkName] = networksList
866
+ ids = self.safe_list(response, 0, [])
849
867
  result: dict = {}
850
868
  for i in range(0, len(ids)):
851
869
  id = ids[i]
852
- if id.find('F0') >= 0:
870
+ if id.endswith('F0'):
853
871
  # we get a lot of F0 currencies, skip those
854
872
  continue
855
873
  code = self.safe_currency_code(id)
856
- label = self.safe_value(indexed['label'], id, [])
874
+ label = self.safe_list(indexed['label'], id, [])
857
875
  name = self.safe_string(label, 1)
858
- pool = self.safe_value(indexed['pool'], id, [])
876
+ pool = self.safe_list(indexed['pool'], id, [])
859
877
  rawType = self.safe_string(pool, 1)
860
878
  isCryptoCoin = (rawType is not None) or (id in indexed['explorer']) # "hacky" solution
861
879
  type = None
862
880
  if isCryptoCoin:
863
881
  type = 'crypto'
864
- feeValues = self.safe_value(indexed['fees'], id, [])
865
- fees = self.safe_value(feeValues, 1, [])
882
+ feeValues = self.safe_list(indexed['fees'], id, [])
883
+ fees = self.safe_list(feeValues, 1, [])
866
884
  fee = self.safe_number(fees, 1)
867
- undl = self.safe_value(indexed['undl'], id, [])
885
+ undl = self.safe_list(indexed['undl'], id, [])
868
886
  precision = '8' # default precision, todo: fix "magic constants"
869
887
  fid = 'f' + id
870
- result[code] = {
888
+ dwStatuses = self.safe_list(indexed['statuses'], id, [])
889
+ depositEnabled = self.safe_integer(dwStatuses, 1) == 1
890
+ withdrawEnabled = self.safe_integer(dwStatuses, 2) == 1
891
+ networks: dict = {}
892
+ netwokIds = self.safe_list(indexedNetworks, id, [])
893
+ for j in range(0, len(netwokIds)):
894
+ networkId = netwokIds[j]
895
+ network = self.network_id_to_code(networkId)
896
+ networks[network] = {
897
+ 'info': networkId,
898
+ 'id': networkId.lower(),
899
+ 'network': networkId,
900
+ 'active': None,
901
+ 'deposit': None,
902
+ 'withdraw': None,
903
+ 'fee': None,
904
+ 'precision': None,
905
+ 'limits': {
906
+ 'withdraw': {
907
+ 'min': None,
908
+ 'max': None,
909
+ },
910
+ },
911
+ }
912
+ result[code] = self.safe_currency_structure({
871
913
  'id': fid,
872
914
  'uppercaseId': id,
873
915
  'code': code,
@@ -875,8 +917,8 @@ class bitfinex(Exchange, ImplicitAPI):
875
917
  'type': type,
876
918
  'name': name,
877
919
  'active': True,
878
- 'deposit': None,
879
- 'withdraw': None,
920
+ 'deposit': depositEnabled,
921
+ 'withdraw': withdrawEnabled,
880
922
  'fee': fee,
881
923
  'precision': int(precision),
882
924
  'limits': {
@@ -889,37 +931,8 @@ class bitfinex(Exchange, ImplicitAPI):
889
931
  'max': None,
890
932
  },
891
933
  },
892
- 'networks': {},
893
- }
894
- networks: dict = {}
895
- currencyNetworks = self.safe_value(response, 8, [])
896
- cleanId = id.replace('F0', '')
897
- for j in range(0, len(currencyNetworks)):
898
- pair = currencyNetworks[j]
899
- networkId = self.safe_string(pair, 0)
900
- currencyId = self.safe_string(self.safe_value(pair, 1, []), 0)
901
- if currencyId == cleanId:
902
- network = self.network_id_to_code(networkId)
903
- networks[network] = {
904
- 'info': networkId,
905
- 'id': networkId.lower(),
906
- 'network': networkId,
907
- 'active': None,
908
- 'deposit': None,
909
- 'withdraw': None,
910
- 'fee': None,
911
- 'precision': None,
912
- 'limits': {
913
- 'withdraw': {
914
- 'min': None,
915
- 'max': None,
916
- },
917
- },
918
- }
919
- keysNetworks = list(networks.keys())
920
- networksLength = len(keysNetworks)
921
- if networksLength > 0:
922
- result[code]['networks'] = networks
934
+ 'networks': networks,
935
+ })
923
936
  return result
924
937
 
925
938
  async def fetch_balance(self, params={}) -> Balances:
@@ -1151,9 +1164,8 @@ class bitfinex(Exchange, ImplicitAPI):
1151
1164
  #
1152
1165
  # on trading pairs(ex. tBTCUSD)
1153
1166
  #
1154
- # {
1155
- # 'result': [
1156
- # SYMBOL,
1167
+ # [
1168
+ # SYMBOL, # self index is not present in singular-ticker
1157
1169
  # BID,
1158
1170
  # BID_SIZE,
1159
1171
  # ASK,
@@ -1164,15 +1176,13 @@ class bitfinex(Exchange, ImplicitAPI):
1164
1176
  # VOLUME,
1165
1177
  # HIGH,
1166
1178
  # LOW
1167
- # ]
1168
- # }
1179
+ # ]
1169
1180
  #
1170
1181
  #
1171
1182
  # on funding currencies(ex. fUSD)
1172
1183
  #
1173
- # {
1174
- # 'result': [
1175
- # SYMBOL,
1184
+ # [
1185
+ # SYMBOL, # self index is not present in singular-ticker
1176
1186
  # FRR,
1177
1187
  # BID,
1178
1188
  # BID_PERIOD,
@@ -1189,35 +1199,71 @@ class bitfinex(Exchange, ImplicitAPI):
1189
1199
  # _PLACEHOLDER,
1190
1200
  # _PLACEHOLDER,
1191
1201
  # FRR_AMOUNT_AVAILABLE
1192
- # ]
1193
- # }
1202
+ # ]
1194
1203
  #
1195
- result = self.safe_list(ticker, 'result')
1204
+ length = len(ticker)
1205
+ isFetchTicker = (length == 10) or (length == 16)
1206
+ symbol: Str = None
1207
+ minusIndex = 0
1208
+ isFundingCurrency = False
1209
+ if isFetchTicker:
1210
+ minusIndex = 1
1211
+ isFundingCurrency = (length == 16)
1212
+ else:
1213
+ marketId = self.safe_string(ticker, 0)
1214
+ market = self.safe_market(marketId, market)
1215
+ isFundingCurrency = (length == 17)
1196
1216
  symbol = self.safe_symbol(None, market)
1197
- length = len(result)
1198
- last = self.safe_string(result, length - 4)
1199
- percentage = self.safe_string(result, length - 5)
1217
+ last: Str = None
1218
+ bid: Str = None
1219
+ ask: Str = None
1220
+ change: Str = None
1221
+ percentage: Str = None
1222
+ volume: Str = None
1223
+ high: Str = None
1224
+ low: Str = None
1225
+ if isFundingCurrency:
1226
+ # per api docs, they are different array type
1227
+ last = self.safe_string(ticker, 10 - minusIndex)
1228
+ bid = self.safe_string(ticker, 2 - minusIndex)
1229
+ ask = self.safe_string(ticker, 5 - minusIndex)
1230
+ change = self.safe_string(ticker, 8 - minusIndex)
1231
+ percentage = self.safe_string(ticker, 9 - minusIndex)
1232
+ volume = self.safe_string(ticker, 11 - minusIndex)
1233
+ high = self.safe_string(ticker, 12 - minusIndex)
1234
+ low = self.safe_string(ticker, 13 - minusIndex)
1235
+ else:
1236
+ # on trading pairs(ex. tBTCUSD or tHMSTR:USD)
1237
+ last = self.safe_string(ticker, 7 - minusIndex)
1238
+ bid = self.safe_string(ticker, 1 - minusIndex)
1239
+ ask = self.safe_string(ticker, 3 - minusIndex)
1240
+ change = self.safe_string(ticker, 5 - minusIndex)
1241
+ percentage = self.safe_string(ticker, 6 - minusIndex)
1242
+ percentage = Precise.string_mul(percentage, '100')
1243
+ volume = self.safe_string(ticker, 8 - minusIndex)
1244
+ high = self.safe_string(ticker, 9 - minusIndex)
1245
+ low = self.safe_string(ticker, 10 - minusIndex)
1200
1246
  return self.safe_ticker({
1201
1247
  'symbol': symbol,
1202
1248
  'timestamp': None,
1203
1249
  'datetime': None,
1204
- 'high': self.safe_string(result, length - 2),
1205
- 'low': self.safe_string(result, length - 1),
1206
- 'bid': self.safe_string(result, length - 10),
1207
- 'bidVolume': self.safe_string(result, length - 9),
1208
- 'ask': self.safe_string(result, length - 8),
1209
- 'askVolume': self.safe_string(result, length - 7),
1250
+ 'high': high,
1251
+ 'low': low,
1252
+ 'bid': bid,
1253
+ 'bidVolume': None,
1254
+ 'ask': ask,
1255
+ 'askVolume': None,
1210
1256
  'vwap': None,
1211
1257
  'open': None,
1212
1258
  'close': last,
1213
1259
  'last': last,
1214
1260
  'previousClose': None,
1215
- 'change': self.safe_string(result, length - 6),
1216
- 'percentage': Precise.string_mul(percentage, '100'),
1261
+ 'change': change,
1262
+ 'percentage': percentage,
1217
1263
  'average': None,
1218
- 'baseVolume': self.safe_string(result, length - 3),
1264
+ 'baseVolume': volume,
1219
1265
  'quoteVolume': None,
1220
- 'info': result,
1266
+ 'info': ticker,
1221
1267
  }, market)
1222
1268
 
1223
1269
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
@@ -1278,14 +1324,7 @@ class bitfinex(Exchange, ImplicitAPI):
1278
1324
  # ...
1279
1325
  # ]
1280
1326
  #
1281
- result: dict = {}
1282
- for i in range(0, len(tickers)):
1283
- ticker = tickers[i]
1284
- marketId = self.safe_string(ticker, 0)
1285
- market = self.safe_market(marketId)
1286
- symbol = market['symbol']
1287
- result[symbol] = self.parse_ticker({'result': ticker}, market)
1288
- return self.filter_by_array_tickers(result, 'symbol', symbols)
1327
+ return self.parse_tickers(tickers, symbols)
1289
1328
 
1290
1329
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1291
1330
  """
@@ -1303,8 +1342,7 @@ class bitfinex(Exchange, ImplicitAPI):
1303
1342
  'symbol': market['id'],
1304
1343
  }
1305
1344
  ticker = await self.publicGetTickerSymbol(self.extend(request, params))
1306
- result: dict = {'result': ticker}
1307
- return self.parse_ticker(result, market)
1345
+ return self.parse_ticker(ticker, market)
1308
1346
 
1309
1347
  def parse_trade(self, trade: dict, market: Market = None) -> Trade:
1310
1348
  #
@@ -1567,6 +1567,8 @@ class bitget(Exchange, ImplicitAPI):
1567
1567
  'method': 'privateMixGetV2MixPositionAllPosition', # or privateMixGetV2MixPositionHistoryPosition
1568
1568
  },
1569
1569
  'defaultTimeInForce': 'GTC', # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
1570
+ # fiat currencies on deposit page
1571
+ 'fiatCurrencies': ['EUR', 'VND', 'PLN', 'CZK', 'HUF', 'DKK', 'AUD', 'CAD', 'NOK', 'SEK', 'CHF', 'MXN', 'COP', 'ARS', 'GBP', 'BRL', 'UAH', 'ZAR'],
1570
1572
  },
1571
1573
  'features': {
1572
1574
  'spot': {
@@ -2025,99 +2027,85 @@ class bitget(Exchange, ImplicitAPI):
2025
2027
  """
2026
2028
  response = await self.publicSpotGetV2SpotPublicCoins(params)
2027
2029
  #
2028
- # {
2029
- # "code": "00000",
2030
- # "data": [
2031
- # {
2032
- # "chains": [
2033
- # {
2034
- # "browserUrl": "https://blockchair.com/bitcoin/transaction/",
2035
- # "chain": "BTC",
2036
- # "depositConfirm": "1",
2037
- # "extraWithdrawFee": "0",
2038
- # "minDepositAmount": "0.0001",
2039
- # "minWithdrawAmount": "0.005",
2040
- # "needTag": "false",
2041
- # "rechargeable": "true",
2042
- # "withdrawConfirm": "1",
2043
- # "withdrawFee": "0.0004",
2044
- # "withdrawable": "true"
2045
- # },
2046
- # ],
2047
- # "coin": "BTC",
2048
- # "coinId": "1",
2049
- # "transfer": "true""
2050
- # }
2051
- # ],
2052
- # "msg": "success",
2053
- # "requestTime": "1700120731773"
2054
- # }
2030
+ # {
2031
+ # "code": "00000",
2032
+ # "msg": "success",
2033
+ # "requestTime": "1746195617812",
2034
+ # "data": [
2035
+ # {
2036
+ # "coinId": "1456",
2037
+ # "coin": "NEIROETH",
2038
+ # "transfer": "false",
2039
+ # "chains": [
2040
+ # {
2041
+ # "chain": "ERC20",
2042
+ # "needTag": "false",
2043
+ # "withdrawable": "true",
2044
+ # "rechargeable": "true",
2045
+ # "withdrawFee": "44.91017965",
2046
+ # "extraWithdrawFee": "0",
2047
+ # "depositConfirm": "12",
2048
+ # "withdrawConfirm": "64",
2049
+ # "minDepositAmount": "0.06",
2050
+ # "minWithdrawAmount": "60",
2051
+ # "browserUrl": "https://etherscan.io/tx/",
2052
+ # "contractAddress": "0xee2a03aa6dacf51c18679c516ad5283d8e7c2637",
2053
+ # "withdrawStep": "0",
2054
+ # "withdrawMinScale": "8",
2055
+ # "congestion": "normal"
2056
+ # }
2057
+ # ],
2058
+ # "areaCoin": "no"
2059
+ # },
2060
+ # ...
2055
2061
  #
2056
2062
  result: dict = {}
2057
2063
  data = self.safe_value(response, 'data', [])
2064
+ fiatCurrencies = self.safe_list(self.options, 'fiatCurrencies', [])
2058
2065
  for i in range(0, len(data)):
2059
2066
  entry = data[i]
2060
2067
  id = self.safe_string(entry, 'coin') # we don't use 'coinId' has no use. it is 'coin' field that needs to be used in currency related endpoints(deposit, withdraw, etc..)
2061
2068
  code = self.safe_currency_code(id)
2062
2069
  chains = self.safe_value(entry, 'chains', [])
2063
2070
  networks: dict = {}
2064
- deposit = False
2065
- withdraw = False
2066
- minWithdrawString = None
2067
- minDepositString = None
2068
- minWithdrawFeeString = None
2069
2071
  for j in range(0, len(chains)):
2070
2072
  chain = chains[j]
2071
2073
  networkId = self.safe_string(chain, 'chain')
2072
2074
  network = self.network_id_to_code(networkId, code)
2073
2075
  if network is not None:
2074
2076
  network = network.upper()
2075
- withdrawEnabled = self.safe_string(chain, 'withdrawable')
2076
- canWithdraw = withdrawEnabled == 'true'
2077
- withdraw = canWithdraw if (canWithdraw) else withdraw
2078
- depositEnabled = self.safe_string(chain, 'rechargeable')
2079
- canDeposit = depositEnabled == 'true'
2080
- deposit = canDeposit if (canDeposit) else deposit
2081
- networkWithdrawFeeString = self.safe_string(chain, 'withdrawFee')
2082
- if networkWithdrawFeeString is not None:
2083
- minWithdrawFeeString = networkWithdrawFeeString if (minWithdrawFeeString is None) else Precise.string_min(networkWithdrawFeeString, minWithdrawFeeString)
2084
- networkMinWithdrawString = self.safe_string(chain, 'minWithdrawAmount')
2085
- if networkMinWithdrawString is not None:
2086
- minWithdrawString = networkMinWithdrawString if (minWithdrawString is None) else Precise.string_min(networkMinWithdrawString, minWithdrawString)
2087
- networkMinDepositString = self.safe_string(chain, 'minDepositAmount')
2088
- if networkMinDepositString is not None:
2089
- minDepositString = networkMinDepositString if (minDepositString is None) else Precise.string_min(networkMinDepositString, minDepositString)
2090
2077
  networks[network] = {
2091
2078
  'info': chain,
2092
2079
  'id': networkId,
2093
2080
  'network': network,
2094
2081
  'limits': {
2095
2082
  'withdraw': {
2096
- 'min': self.parse_number(networkMinWithdrawString),
2083
+ 'min': self.safe_number(chain, 'minWithdrawAmount'),
2097
2084
  'max': None,
2098
2085
  },
2099
2086
  'deposit': {
2100
- 'min': self.parse_number(networkMinDepositString),
2087
+ 'min': self.safe_number(chain, 'minDepositAmount'),
2101
2088
  'max': None,
2102
2089
  },
2103
2090
  },
2104
- 'active': canWithdraw and canDeposit,
2105
- 'withdraw': canWithdraw,
2106
- 'deposit': canDeposit,
2107
- 'fee': self.parse_number(networkWithdrawFeeString),
2108
- 'precision': None,
2091
+ 'active': None,
2092
+ 'withdraw': self.safe_string(chain, 'withdrawable') == 'true',
2093
+ 'deposit': self.safe_string(chain, 'rechargeable') == 'true',
2094
+ 'fee': self.safe_number(chain, 'withdrawFee'),
2095
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawMinScale'))),
2109
2096
  }
2110
- result[code] = {
2097
+ isFiat = self.in_array(code, fiatCurrencies)
2098
+ result[code] = self.safe_currency_structure({
2111
2099
  'info': entry,
2112
2100
  'id': id,
2113
2101
  'code': code,
2114
2102
  'networks': networks,
2115
- 'type': None,
2103
+ 'type': 'fiat' if isFiat else 'crypto',
2116
2104
  'name': None,
2117
- 'active': deposit and withdraw,
2118
- 'deposit': deposit,
2119
- 'withdraw': withdraw,
2120
- 'fee': self.parse_number(minWithdrawFeeString),
2105
+ 'active': None,
2106
+ 'deposit': None,
2107
+ 'withdraw': None,
2108
+ 'fee': None,
2121
2109
  'precision': None,
2122
2110
  'limits': {
2123
2111
  'amount': {
@@ -2125,16 +2113,16 @@ class bitget(Exchange, ImplicitAPI):
2125
2113
  'max': None,
2126
2114
  },
2127
2115
  'withdraw': {
2128
- 'min': self.parse_number(minWithdrawString),
2116
+ 'min': None,
2129
2117
  'max': None,
2130
2118
  },
2131
2119
  'deposit': {
2132
- 'min': self.parse_number(minDepositString),
2120
+ 'min': None,
2133
2121
  'max': None,
2134
2122
  },
2135
2123
  },
2136
2124
  'created': None,
2137
- }
2125
+ })
2138
2126
  return result
2139
2127
 
2140
2128
  async def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
@@ -2753,7 +2741,7 @@ class bitget(Exchange, ImplicitAPI):
2753
2741
  close = self.safe_string(ticker, 'lastPr')
2754
2742
  timestamp = self.safe_integer_omit_zero(ticker, 'ts') # exchange bitget provided 0
2755
2743
  change = self.safe_string(ticker, 'change24h')
2756
- open24 = self.safe_string(ticker, 'open24')
2744
+ open24 = self.safe_string_2(ticker, 'open24', 'open24h')
2757
2745
  open = self.safe_string(ticker, 'open')
2758
2746
  symbol: str
2759
2747
  openValue: str
@@ -3420,6 +3408,7 @@ class bitget(Exchange, ImplicitAPI):
3420
3408
  :param dict [params]: extra parameters specific to the exchange API endpoint
3421
3409
  :param int [params.until]: timestamp in ms of the latest candle to fetch
3422
3410
  :param boolean [params.useHistoryEndpoint]: whether to force to use historical endpoint(it has max limit of 200)
3411
+ :param boolean [params.useHistoryEndpointForPagination]: whether to force to use historical endpoint for pagination(default True)
3423
3412
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3424
3413
  :param str [params.price]: *swap only* "mark"(to fetch mark price candles) or "index"(to fetch index price candles)
3425
3414
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
@@ -3428,11 +3417,13 @@ class bitget(Exchange, ImplicitAPI):
3428
3417
  defaultLimit = 100 # default 100, max 1000
3429
3418
  maxLimitForRecentEndpoint = 1000
3430
3419
  maxLimitForHistoryEndpoint = 200 # note, max 1000 bars are supported for "recent-candles" endpoint, but "historical-candles" support only max 200
3420
+ useHistoryEndpoint = self.safe_bool(params, 'useHistoryEndpoint', False)
3421
+ useHistoryEndpointForPagination = self.safe_bool(params, 'useHistoryEndpointForPagination', True)
3431
3422
  paginate = False
3432
3423
  paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate')
3433
3424
  if paginate:
3434
- return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimitForRecentEndpoint)
3435
- useHistoryEndpoint = self.safe_bool(params, 'useHistoryEndpoint', False)
3425
+ limitForPagination = maxLimitForHistoryEndpoint if useHistoryEndpointForPagination else maxLimitForRecentEndpoint
3426
+ return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, limitForPagination)
3436
3427
  market = self.market(symbol)
3437
3428
  marketType = 'spot' if market['spot'] else 'swap'
3438
3429
  timeframes = self.options['timeframes'][marketType]
@@ -4051,6 +4042,7 @@ class bitget(Exchange, ImplicitAPI):
4051
4042
  timestamp = self.safe_integer_2(order, 'cTime', 'ctime')
4052
4043
  updateTimestamp = self.safe_integer(order, 'uTime')
4053
4044
  rawStatus = self.safe_string_2(order, 'status', 'state')
4045
+ rawStatus = self.safe_string(order, 'planStatus', rawStatus)
4054
4046
  fee = None
4055
4047
  feeCostString = self.safe_string(order, 'fee')
4056
4048
  if feeCostString is not None:
@@ -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),