ccxt 4.4.94__py2.py3-none-any.whl → 4.4.95__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 (44) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +3 -0
  3. ccxt/abstract/hyperliquid.py +1 -1
  4. ccxt/abstract/woo.py +59 -4
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/base/exchange.py +1 -1
  7. ccxt/async_support/base/ws/future.py +2 -0
  8. ccxt/async_support/bingx.py +129 -92
  9. ccxt/async_support/bitget.py +1 -1
  10. ccxt/async_support/bitstamp.py +2 -0
  11. ccxt/async_support/blofin.py +6 -1
  12. ccxt/async_support/bybit.py +1 -1
  13. ccxt/async_support/coinbase.py +36 -0
  14. ccxt/async_support/coinmate.py +34 -0
  15. ccxt/async_support/coinone.py +34 -0
  16. ccxt/async_support/coinsph.py +29 -0
  17. ccxt/async_support/gate.py +1 -1
  18. ccxt/async_support/hyperliquid.py +2 -1
  19. ccxt/async_support/woo.py +1251 -875
  20. ccxt/base/errors.py +0 -6
  21. ccxt/base/exchange.py +3 -3
  22. ccxt/bingx.py +129 -92
  23. ccxt/bitget.py +1 -1
  24. ccxt/bitstamp.py +2 -0
  25. ccxt/blofin.py +6 -1
  26. ccxt/bybit.py +1 -1
  27. ccxt/coinbase.py +36 -0
  28. ccxt/coinmate.py +34 -0
  29. ccxt/coinone.py +34 -0
  30. ccxt/coinsph.py +29 -0
  31. ccxt/gate.py +1 -1
  32. ccxt/hyperliquid.py +2 -1
  33. ccxt/pro/__init__.py +1 -1
  34. ccxt/pro/hyperliquid.py +6 -6
  35. ccxt/pro/kraken.py +17 -16
  36. ccxt/pro/mexc.py +10 -10
  37. ccxt/test/tests_async.py +2 -2
  38. ccxt/test/tests_sync.py +2 -2
  39. ccxt/woo.py +1251 -875
  40. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/METADATA +4 -4
  41. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/RECORD +44 -44
  42. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/LICENSE.txt +0 -0
  43. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/WHEEL +0 -0
  44. {ccxt-4.4.94.dist-info → ccxt-4.4.95.dist-info}/top_level.txt +0 -0
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.4.94'
25
+ __version__ = '4.4.95'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
ccxt/abstract/bingx.py CHANGED
@@ -153,6 +153,9 @@ class ImplicitAPI:
153
153
  copytrading_v1_private_post_swap_trace_settpsl = copyTradingV1PrivatePostSwapTraceSetTPSL = Entry('swap/trace/setTPSL', ['copyTrading', 'v1', 'private'], 'POST', {'cost': 2})
154
154
  copytrading_v1_private_post_spot_trader_sellorder = copyTradingV1PrivatePostSpotTraderSellOrder = Entry('spot/trader/sellOrder', ['copyTrading', 'v1', 'private'], 'POST', {'cost': 10})
155
155
  api_v3_private_get_asset_transfer = apiV3PrivateGetAssetTransfer = Entry('asset/transfer', ['api', 'v3', 'private'], 'GET', {'cost': 1})
156
+ api_v3_private_get_asset_transferrecord = apiV3PrivateGetAssetTransferRecord = Entry('asset/transferRecord', ['api', 'v3', 'private'], 'GET', {'cost': 5})
156
157
  api_v3_private_get_capital_deposit_hisrec = apiV3PrivateGetCapitalDepositHisrec = Entry('capital/deposit/hisrec', ['api', 'v3', 'private'], 'GET', {'cost': 1})
157
158
  api_v3_private_get_capital_withdraw_history = apiV3PrivateGetCapitalWithdrawHistory = Entry('capital/withdraw/history', ['api', 'v3', 'private'], 'GET', {'cost': 1})
158
159
  api_v3_private_post_post_asset_transfer = apiV3PrivatePostPostAssetTransfer = Entry('post/asset/transfer', ['api', 'v3', 'private'], 'POST', {'cost': 1})
160
+ api_asset_v1_private_post_transfer = apiAssetV1PrivatePostTransfer = Entry('transfer', ['api', 'asset', 'v1', 'private'], 'POST', {'cost': 5})
161
+ api_asset_v1_public_get_transfer_supportcoins = apiAssetV1PublicGetTransferSupportCoins = Entry('transfer/supportCoins', ['api', 'asset', 'v1', 'public'], 'GET', {'cost': 5})
@@ -2,5 +2,5 @@ from ccxt.base.types import Entry
2
2
 
3
3
 
4
4
  class ImplicitAPI:
5
- public_post_info = publicPostInfo = Entry('info', 'public', 'POST', {'cost': 20, 'byType': {'l2Book': 2, 'allMids': 2, 'clearinghouseState': 2, 'orderStatus': 2, 'spotClearinghouseState': 2, 'exchangeStatus': 2}})
5
+ public_post_info = publicPostInfo = Entry('info', 'public', 'POST', {'cost': 20, 'byType': {'l2Book': 2, 'allMids': 2, 'clearinghouseState': 2, 'orderStatus': 2, 'spotClearinghouseState': 2, 'exchangeStatus': 2, 'candleSnapshot': 3}})
6
6
  private_post_exchange = privatePostExchange = Entry('exchange', 'private', 'POST', {'cost': 1})
ccxt/abstract/woo.py CHANGED
@@ -60,26 +60,81 @@ class ImplicitAPI:
60
60
  v1_private_delete_orders = v1PrivateDeleteOrders = Entry('orders', ['v1', 'private'], 'DELETE', {'cost': 1})
61
61
  v1_private_delete_asset_withdraw = v1PrivateDeleteAssetWithdraw = Entry('asset/withdraw', ['v1', 'private'], 'DELETE', {'cost': 120})
62
62
  v2_private_get_client_holding = v2PrivateGetClientHolding = Entry('client/holding', ['v2', 'private'], 'GET', {'cost': 1})
63
- v3_public_get_insurancefund = v3PublicGetInsuranceFund = Entry('insuranceFund', ['v3', 'public'], 'GET', {'cost': 3})
63
+ v3_public_get_systeminfo = v3PublicGetSystemInfo = Entry('systemInfo', ['v3', 'public'], 'GET', {'cost': 1})
64
+ v3_public_get_instruments = v3PublicGetInstruments = Entry('instruments', ['v3', 'public'], 'GET', {'cost': 1})
65
+ v3_public_get_token = v3PublicGetToken = Entry('token', ['v3', 'public'], 'GET', {'cost': 1})
66
+ v3_public_get_tokennetwork = v3PublicGetTokenNetwork = Entry('tokenNetwork', ['v3', 'public'], 'GET', {'cost': 1})
67
+ v3_public_get_tokeninfo = v3PublicGetTokenInfo = Entry('tokenInfo', ['v3', 'public'], 'GET', {'cost': 1})
68
+ v3_public_get_markettrades = v3PublicGetMarketTrades = Entry('marketTrades', ['v3', 'public'], 'GET', {'cost': 1})
69
+ v3_public_get_markettradeshistory = v3PublicGetMarketTradesHistory = Entry('marketTradesHistory', ['v3', 'public'], 'GET', {'cost': 1})
70
+ v3_public_get_orderbook = v3PublicGetOrderbook = Entry('orderbook', ['v3', 'public'], 'GET', {'cost': 1})
71
+ v3_public_get_kline = v3PublicGetKline = Entry('kline', ['v3', 'public'], 'GET', {'cost': 1})
72
+ v3_public_get_klinehistory = v3PublicGetKlineHistory = Entry('klineHistory', ['v3', 'public'], 'GET', {'cost': 1})
73
+ v3_public_get_futures = v3PublicGetFutures = Entry('futures', ['v3', 'public'], 'GET', {'cost': 1})
74
+ v3_public_get_fundingrate = v3PublicGetFundingRate = Entry('fundingRate', ['v3', 'public'], 'GET', {'cost': 1})
75
+ v3_public_get_fundingratehistory = v3PublicGetFundingRateHistory = Entry('fundingRateHistory', ['v3', 'public'], 'GET', {'cost': 1})
76
+ v3_public_get_insurancefund = v3PublicGetInsuranceFund = Entry('insuranceFund', ['v3', 'public'], 'GET', {'cost': 1})
77
+ v3_private_get_trade_order = v3PrivateGetTradeOrder = Entry('trade/order', ['v3', 'private'], 'GET', {'cost': 2})
78
+ v3_private_get_trade_orders = v3PrivateGetTradeOrders = Entry('trade/orders', ['v3', 'private'], 'GET', {'cost': 1})
79
+ v3_private_get_trade_algoorder = v3PrivateGetTradeAlgoOrder = Entry('trade/algoOrder', ['v3', 'private'], 'GET', {'cost': 1})
80
+ v3_private_get_trade_algoorders = v3PrivateGetTradeAlgoOrders = Entry('trade/algoOrders', ['v3', 'private'], 'GET', {'cost': 1})
81
+ v3_private_get_trade_transaction = v3PrivateGetTradeTransaction = Entry('trade/transaction', ['v3', 'private'], 'GET', {'cost': 1})
82
+ v3_private_get_trade_transactionhistory = v3PrivateGetTradeTransactionHistory = Entry('trade/transactionHistory', ['v3', 'private'], 'GET', {'cost': 5})
83
+ v3_private_get_trade_tradingfee = v3PrivateGetTradeTradingFee = Entry('trade/tradingFee', ['v3', 'private'], 'GET', {'cost': 5})
84
+ v3_private_get_account_info = v3PrivateGetAccountInfo = Entry('account/info', ['v3', 'private'], 'GET', {'cost': 60})
85
+ v3_private_get_account_tokenconfig = v3PrivateGetAccountTokenConfig = Entry('account/tokenConfig', ['v3', 'private'], 'GET', {'cost': 1})
86
+ v3_private_get_account_symbolconfig = v3PrivateGetAccountSymbolConfig = Entry('account/symbolConfig', ['v3', 'private'], 'GET', {'cost': 1})
87
+ v3_private_get_account_subaccounts_all = v3PrivateGetAccountSubAccountsAll = Entry('account/subAccounts/all', ['v3', 'private'], 'GET', {'cost': 60})
88
+ v3_private_get_account_referral_summary = v3PrivateGetAccountReferralSummary = Entry('account/referral/summary', ['v3', 'private'], 'GET', {'cost': 60})
89
+ v3_private_get_account_referral_rewardhistory = v3PrivateGetAccountReferralRewardHistory = Entry('account/referral/rewardHistory', ['v3', 'private'], 'GET', {'cost': 60})
90
+ v3_private_get_account_credentials = v3PrivateGetAccountCredentials = Entry('account/credentials', ['v3', 'private'], 'GET', {'cost': 60})
91
+ v3_private_get_asset_balances = v3PrivateGetAssetBalances = Entry('asset/balances', ['v3', 'private'], 'GET', {'cost': 1})
92
+ v3_private_get_asset_token_history = v3PrivateGetAssetTokenHistory = Entry('asset/token/history', ['v3', 'private'], 'GET', {'cost': 60})
93
+ v3_private_get_asset_transfer_history = v3PrivateGetAssetTransferHistory = Entry('asset/transfer/history', ['v3', 'private'], 'GET', {'cost': 30})
94
+ v3_private_get_asset_wallet_history = v3PrivateGetAssetWalletHistory = Entry('asset/wallet/history', ['v3', 'private'], 'GET', {'cost': 60})
95
+ v3_private_get_asset_wallet_deposit = v3PrivateGetAssetWalletDeposit = Entry('asset/wallet/deposit', ['v3', 'private'], 'GET', {'cost': 60})
96
+ v3_private_get_asset_staking_yieldhistory = v3PrivateGetAssetStakingYieldHistory = Entry('asset/staking/yieldHistory', ['v3', 'private'], 'GET', {'cost': 60})
97
+ v3_private_get_futures_positions = v3PrivateGetFuturesPositions = Entry('futures/positions', ['v3', 'private'], 'GET', {'cost': 3.33})
98
+ v3_private_get_futures_leverage = v3PrivateGetFuturesLeverage = Entry('futures/leverage', ['v3', 'private'], 'GET', {'cost': 60})
99
+ v3_private_get_futures_defaultmarginmode = v3PrivateGetFuturesDefaultMarginMode = Entry('futures/defaultMarginMode', ['v3', 'private'], 'GET', {'cost': 60})
100
+ v3_private_get_futures_fundingfee_history = v3PrivateGetFuturesFundingFeeHistory = Entry('futures/fundingFee/history', ['v3', 'private'], 'GET', {'cost': 30})
101
+ v3_private_get_spotmargin_interestrate = v3PrivateGetSpotMarginInterestRate = Entry('spotMargin/interestRate', ['v3', 'private'], 'GET', {'cost': 60})
102
+ v3_private_get_spotmargin_interesthistory = v3PrivateGetSpotMarginInterestHistory = Entry('spotMargin/interestHistory', ['v3', 'private'], 'GET', {'cost': 60})
103
+ v3_private_get_spotmargin_maxmargin = v3PrivateGetSpotMarginMaxMargin = Entry('spotMargin/maxMargin', ['v3', 'private'], 'GET', {'cost': 60})
64
104
  v3_private_get_algo_order_oid = v3PrivateGetAlgoOrderOid = Entry('algo/order/{oid}', ['v3', 'private'], 'GET', {'cost': 1})
65
105
  v3_private_get_algo_orders = v3PrivateGetAlgoOrders = Entry('algo/orders', ['v3', 'private'], 'GET', {'cost': 1})
66
106
  v3_private_get_balances = v3PrivateGetBalances = Entry('balances', ['v3', 'private'], 'GET', {'cost': 1})
67
- v3_private_get_accountinfo = v3PrivateGetAccountinfo = Entry('accountinfo', ['v3', 'private'], 'GET', {'cost': 60})
68
107
  v3_private_get_positions = v3PrivateGetPositions = Entry('positions', ['v3', 'private'], 'GET', {'cost': 3.33})
69
108
  v3_private_get_buypower = v3PrivateGetBuypower = Entry('buypower', ['v3', 'private'], 'GET', {'cost': 1})
70
- v3_private_get_referrals = v3PrivateGetReferrals = Entry('referrals', ['v3', 'private'], 'GET', {'cost': 60})
71
- v3_private_get_referral_rewards = v3PrivateGetReferralRewards = Entry('referral_rewards', ['v3', 'private'], 'GET', {'cost': 60})
72
109
  v3_private_get_convert_exchangeinfo = v3PrivateGetConvertExchangeInfo = Entry('convert/exchangeInfo', ['v3', 'private'], 'GET', {'cost': 1})
73
110
  v3_private_get_convert_assetinfo = v3PrivateGetConvertAssetInfo = Entry('convert/assetInfo', ['v3', 'private'], 'GET', {'cost': 1})
74
111
  v3_private_get_convert_rfq = v3PrivateGetConvertRfq = Entry('convert/rfq', ['v3', 'private'], 'GET', {'cost': 60})
75
112
  v3_private_get_convert_trade = v3PrivateGetConvertTrade = Entry('convert/trade', ['v3', 'private'], 'GET', {'cost': 1})
76
113
  v3_private_get_convert_trades = v3PrivateGetConvertTrades = Entry('convert/trades', ['v3', 'private'], 'GET', {'cost': 1})
114
+ v3_private_post_trade_order = v3PrivatePostTradeOrder = Entry('trade/order', ['v3', 'private'], 'POST', {'cost': 2})
115
+ v3_private_post_trade_algoorder = v3PrivatePostTradeAlgoOrder = Entry('trade/algoOrder', ['v3', 'private'], 'POST', {'cost': 5})
116
+ v3_private_post_trade_cancelallafter = v3PrivatePostTradeCancelAllAfter = Entry('trade/cancelAllAfter', ['v3', 'private'], 'POST', {'cost': 1})
117
+ v3_private_post_account_tradingmode = v3PrivatePostAccountTradingMode = Entry('account/tradingMode', ['v3', 'private'], 'POST', {'cost': 120})
118
+ v3_private_post_account_listenkey = v3PrivatePostAccountListenKey = Entry('account/listenKey', ['v3', 'private'], 'POST', {'cost': 20})
119
+ v3_private_post_asset_transfer = v3PrivatePostAssetTransfer = Entry('asset/transfer', ['v3', 'private'], 'POST', {'cost': 30})
120
+ v3_private_post_asset_wallet_withdraw = v3PrivatePostAssetWalletWithdraw = Entry('asset/wallet/withdraw', ['v3', 'private'], 'POST', {'cost': 60})
121
+ v3_private_post_spotmargin_leverage = v3PrivatePostSpotMarginLeverage = Entry('spotMargin/leverage', ['v3', 'private'], 'POST', {'cost': 120})
122
+ v3_private_post_spotmargin_interestrepay = v3PrivatePostSpotMarginInterestRepay = Entry('spotMargin/interestRepay', ['v3', 'private'], 'POST', {'cost': 60})
77
123
  v3_private_post_algo_order = v3PrivatePostAlgoOrder = Entry('algo/order', ['v3', 'private'], 'POST', {'cost': 5})
78
124
  v3_private_post_convert_rft = v3PrivatePostConvertRft = Entry('convert/rft', ['v3', 'private'], 'POST', {'cost': 60})
125
+ v3_private_put_trade_order = v3PrivatePutTradeOrder = Entry('trade/order', ['v3', 'private'], 'PUT', {'cost': 2})
126
+ v3_private_put_trade_algoorder = v3PrivatePutTradeAlgoOrder = Entry('trade/algoOrder', ['v3', 'private'], 'PUT', {'cost': 2})
127
+ v3_private_put_futures_leverage = v3PrivatePutFuturesLeverage = Entry('futures/leverage', ['v3', 'private'], 'PUT', {'cost': 60})
128
+ v3_private_put_futures_positionmode = v3PrivatePutFuturesPositionMode = Entry('futures/positionMode', ['v3', 'private'], 'PUT', {'cost': 120})
79
129
  v3_private_put_order_oid = v3PrivatePutOrderOid = Entry('order/{oid}', ['v3', 'private'], 'PUT', {'cost': 2})
80
130
  v3_private_put_order_client_client_order_id = v3PrivatePutOrderClientClientOrderId = Entry('order/client/{client_order_id}', ['v3', 'private'], 'PUT', {'cost': 2})
81
131
  v3_private_put_algo_order_oid = v3PrivatePutAlgoOrderOid = Entry('algo/order/{oid}', ['v3', 'private'], 'PUT', {'cost': 2})
82
132
  v3_private_put_algo_order_client_client_order_id = v3PrivatePutAlgoOrderClientClientOrderId = Entry('algo/order/client/{client_order_id}', ['v3', 'private'], 'PUT', {'cost': 2})
133
+ v3_private_delete_trade_order = v3PrivateDeleteTradeOrder = Entry('trade/order', ['v3', 'private'], 'DELETE', {'cost': 1})
134
+ v3_private_delete_trade_orders = v3PrivateDeleteTradeOrders = Entry('trade/orders', ['v3', 'private'], 'DELETE', {'cost': 1})
135
+ v3_private_delete_trade_algoorder = v3PrivateDeleteTradeAlgoOrder = Entry('trade/algoOrder', ['v3', 'private'], 'DELETE', {'cost': 1})
136
+ v3_private_delete_trade_algoorders = v3PrivateDeleteTradeAlgoOrders = Entry('trade/algoOrders', ['v3', 'private'], 'DELETE', {'cost': 1})
137
+ v3_private_delete_trade_allorders = v3PrivateDeleteTradeAllOrders = Entry('trade/allOrders', ['v3', 'private'], 'DELETE', {'cost': 1})
83
138
  v3_private_delete_algo_order_order_id = v3PrivateDeleteAlgoOrderOrderId = Entry('algo/order/{order_id}', ['v3', 'private'], 'DELETE', {'cost': 1})
84
139
  v3_private_delete_algo_orders_pending = v3PrivateDeleteAlgoOrdersPending = Entry('algo/orders/pending', ['v3', 'private'], 'DELETE', {'cost': 1})
85
140
  v3_private_delete_algo_orders_pending_symbol = v3PrivateDeleteAlgoOrdersPendingSymbol = Entry('algo/orders/pending/{symbol}', ['v3', 'private'], 'DELETE', {'cost': 1})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.94'
7
+ __version__ = '4.4.95'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.4.94'
5
+ __version__ = '4.4.95'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -36,6 +36,8 @@ class Future(asyncio.Future):
36
36
  elif cancelled:
37
37
  future.cancel()
38
38
  else:
39
+ if future.cancelled():
40
+ return
39
41
  first_result = list(complete)[0].result()
40
42
  future.set_result(first_result)
41
43
  task.add_done_callback(callback)
@@ -128,6 +128,7 @@ class bingx(Exchange, ImplicitAPI):
128
128
  'account': 'https://open-api.{hostname}/openApi',
129
129
  'copyTrading': 'https://open-api.{hostname}/openApi',
130
130
  'cswap': 'https://open-api.{hostname}/openApi',
131
+ 'api': 'https://open-api.{hostname}/openApi',
131
132
  },
132
133
  'test': {
133
134
  'swap': 'https://open-api-vst.{hostname}/openApi', # only swap is really "test" but since the API keys are the same, we want to keep all the functionalities when the user enables the sandboxmode
@@ -457,6 +458,7 @@ class bingx(Exchange, ImplicitAPI):
457
458
  'private': {
458
459
  'get': {
459
460
  'asset/transfer': 1,
461
+ 'asset/transferRecord': 5,
460
462
  'capital/deposit/hisrec': 1,
461
463
  'capital/withdraw/history': 1,
462
464
  },
@@ -465,6 +467,20 @@ class bingx(Exchange, ImplicitAPI):
465
467
  },
466
468
  },
467
469
  },
470
+ 'asset': {
471
+ 'v1': {
472
+ 'private': {
473
+ 'post': {
474
+ 'transfer': 5,
475
+ },
476
+ },
477
+ 'public': {
478
+ 'get': {
479
+ 'transfer/supportCoins': 5,
480
+ },
481
+ },
482
+ },
483
+ },
468
484
  },
469
485
  },
470
486
  'timeframes': {
@@ -529,16 +545,19 @@ class bingx(Exchange, ImplicitAPI):
529
545
  'options': {
530
546
  'defaultType': 'spot',
531
547
  'accountsByType': {
532
- 'funding': 'FUND',
533
- 'spot': 'SPOT',
534
- 'swap': 'PFUTURES',
535
- 'future': 'SFUTURES',
548
+ 'funding': 'fund',
549
+ 'spot': 'spot',
550
+ 'future': 'stdFutures',
551
+ 'swap': 'USDTMPerp',
552
+ 'linear': 'USDTMPerp',
553
+ 'inverse': 'coinMPerp',
536
554
  },
537
555
  'accountsById': {
538
- 'FUND': 'funding',
539
- 'SPOT': 'spot',
540
- 'PFUTURES': 'swap',
541
- 'SFUTURES': 'future',
556
+ 'fund': 'funding',
557
+ 'spot': 'spot',
558
+ 'stdFutures': 'future',
559
+ 'USDTMPerp': 'linear',
560
+ 'coinMPerp': 'inverse',
542
561
  },
543
562
  'recvWindow': 5 * 1000, # 5 sec
544
563
  'broker': 'CCXT',
@@ -780,6 +799,10 @@ class bingx(Exchange, ImplicitAPI):
780
799
  'min': self.safe_number(rawNetwork, 'withdrawMin'),
781
800
  'max': self.safe_number(rawNetwork, 'withdrawMax'),
782
801
  },
802
+ 'deposit': {
803
+ 'min': self.safe_number(rawNetwork, 'depositMin'),
804
+ 'max': None,
805
+ },
783
806
  }
784
807
  precision = self.parse_number(self.parse_precision(self.safe_string(rawNetwork, 'withdrawPrecision')))
785
808
  networks[networkCode] = {
@@ -793,20 +816,35 @@ class bingx(Exchange, ImplicitAPI):
793
816
  'precision': precision,
794
817
  'limits': limits,
795
818
  }
796
- result[code] = self.safe_currency_structure({
797
- 'info': entry,
798
- 'code': code,
799
- 'id': currencyId,
800
- 'precision': None,
801
- 'name': name,
802
- 'active': None,
803
- 'deposit': None,
804
- 'withdraw': None,
805
- 'networks': networks,
806
- 'fee': None,
807
- 'limits': None,
808
- 'type': 'crypto', # only cryptos now
809
- })
819
+ if not (code in result): # the exchange could return the same currency with different networks
820
+ result[code] = {
821
+ 'info': entry,
822
+ 'code': code,
823
+ 'id': currencyId,
824
+ 'precision': None,
825
+ 'name': name,
826
+ 'active': None,
827
+ 'deposit': None,
828
+ 'withdraw': None,
829
+ 'networks': networks,
830
+ 'fee': None,
831
+ 'limits': None,
832
+ 'type': 'crypto', # only cryptos now
833
+ }
834
+ else:
835
+ existing = result[code]
836
+ existingNetworks = self.safe_dict(existing, 'networks', {})
837
+ newNetworkCodes = list(networks.keys())
838
+ for j in range(0, len(newNetworkCodes)):
839
+ newNetworkCode = newNetworkCodes[j]
840
+ if not (newNetworkCode in existingNetworks):
841
+ existingNetworks[newNetworkCode] = networks[newNetworkCode]
842
+ result[code]['networks'] = existingNetworks
843
+ codes = list(result.keys())
844
+ for i in range(0, len(codes)):
845
+ code = codes[i]
846
+ currency = result[code]
847
+ result[code] = self.safe_currency_structure(currency)
810
848
  return result
811
849
 
812
850
  async def fetch_spot_markets(self, params) -> List[Market]:
@@ -4642,26 +4680,39 @@ class bingx(Exchange, ImplicitAPI):
4642
4680
  """
4643
4681
  transfer currency internally between wallets on the same account
4644
4682
 
4645
- https://bingx-api.github.io/docs/#/en-us/common/account-api.html#Asset%20Transfer
4683
+ https://bingx-api.github.io/docs/#/en-us/common/account-api.html#Asset%20Transfer%20New
4646
4684
 
4647
4685
  :param str code: unified currency code
4648
4686
  :param float amount: amount to transfer
4649
4687
  :param str fromAccount: account to transfer from(spot, swap, futures, or funding)
4650
- :param str toAccount: account to transfer to(spot, swap, futures, or funding)
4688
+ :param str toAccount: account to transfer to(spot, swap(linear or inverse), future, or funding)
4651
4689
  :param dict [params]: extra parameters specific to the exchange API endpoint
4652
4690
  :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
4653
4691
  """
4654
4692
  await self.load_markets()
4655
4693
  currency = self.currency(code)
4656
4694
  accountsByType = self.safe_dict(self.options, 'accountsByType', {})
4695
+ subType = None
4696
+ subType, params = self.handle_sub_type_and_params('transfer', None, params)
4657
4697
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
4658
4698
  toId = self.safe_string(accountsByType, toAccount, toAccount)
4699
+ if fromId == 'swap':
4700
+ if subType == 'inverse':
4701
+ fromId = 'coinMPerp'
4702
+ else:
4703
+ fromId = 'USDTMPerp'
4704
+ if toId == 'swap':
4705
+ if subType == 'inverse':
4706
+ toId = 'coinMPerp'
4707
+ else:
4708
+ toId = 'USDTMPerp'
4659
4709
  request: dict = {
4710
+ 'fromAccount': fromId,
4711
+ 'toAccount': toId,
4660
4712
  'asset': currency['id'],
4661
4713
  'amount': self.currency_to_precision(code, amount),
4662
- 'type': fromId + '_' + toId,
4663
4714
  }
4664
- response = await self.spotV3PrivateGetGetAssetTransfer(self.extend(request, params))
4715
+ response = await self.apiAssetV1PrivatePostTransfer(self.extend(request, params))
4665
4716
  #
4666
4717
  # {
4667
4718
  # "tranId": 1933130865269936128,
@@ -4670,7 +4721,7 @@ class bingx(Exchange, ImplicitAPI):
4670
4721
  #
4671
4722
  return {
4672
4723
  'info': response,
4673
- 'id': self.safe_string(response, 'tranId'),
4724
+ 'id': self.safe_string(response, 'transferId'),
4674
4725
  'timestamp': None,
4675
4726
  'datetime': None,
4676
4727
  'currency': code,
@@ -4684,18 +4735,19 @@ class bingx(Exchange, ImplicitAPI):
4684
4735
  """
4685
4736
  fetch a history of internal transfers made on an account
4686
4737
 
4687
- https://bingx-api.github.io/docs/#/spot/account-api.html#Query%20User%20Universal%20Transfer%20History%20(USER_DATA)
4738
+ https://bingx-api.github.io/docs/#/en-us/common/account-api.html#Asset%20transfer%20records%20new
4688
4739
 
4689
4740
  :param str [code]: unified currency code of the currency transferred
4690
4741
  :param int [since]: the earliest time in ms to fetch transfers for
4691
4742
  :param int [limit]: the maximum number of transfers structures to retrieve(default 10, max 100)
4692
4743
  :param dict [params]: extra parameters specific to the exchange API endpoint
4693
- :param str params.fromAccount:(mandatory) transfer from(spot, swap, futures, or funding)
4694
- :param str params.toAccount:(mandatory) transfer to(spot, swap, futures, or funding)
4744
+ :param str params.fromAccount:(mandatory) transfer from(spot, swap(linear or inverse), future, or funding)
4745
+ :param str params.toAccount:(mandatory) transfer to(spot, swap(linear or inverse), future, or funding)
4695
4746
  :param boolean [params.paginate]: whether to paginate the results(default False)
4696
4747
  :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
4697
4748
  """
4698
4749
  await self.load_markets()
4750
+ request: dict = {}
4699
4751
  currency = None
4700
4752
  if code is not None:
4701
4753
  currency = self.currency(code)
@@ -4705,34 +4757,36 @@ class bingx(Exchange, ImplicitAPI):
4705
4757
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
4706
4758
  toId = self.safe_string(accountsByType, toAccount, toAccount)
4707
4759
  if fromId is None or toId is None:
4708
- raise ExchangeError(self.id + ' fromAccount & toAccount parameter are required')
4760
+ raise ExchangeError(self.id + ' fromAccount & toAccount parameters are required')
4761
+ if fromAccount is not None:
4762
+ request['fromAccount'] = fromId
4763
+ if toAccount is not None:
4764
+ request['toAccount'] = toId
4709
4765
  params = self.omit(params, ['fromAccount', 'toAccount'])
4710
4766
  maxLimit = 100
4711
4767
  paginate = False
4712
4768
  paginate, params = self.handle_option_and_params(params, 'fetchTransfers', 'paginate', False)
4713
4769
  if paginate:
4714
4770
  return await self.fetch_paginated_call_dynamic('fetchTransfers', None, since, limit, params, maxLimit)
4715
- request: dict = {
4716
- 'type': fromId + '_' + toId,
4717
- }
4718
4771
  if since is not None:
4719
4772
  request['startTime'] = since
4720
4773
  if limit is not None:
4721
- request['size'] = limit
4774
+ request['pageSize'] = limit
4722
4775
  request, params = self.handle_until_option('endTime', request, params)
4723
- response = await self.spotV3PrivateGetAssetTransfer(self.extend(request, params))
4776
+ response = await self.apiV3PrivateGetAssetTransferRecord(self.extend(request, params))
4724
4777
  #
4725
4778
  # {
4726
- # "total": 3,
4779
+ # "total": 2,
4727
4780
  # "rows": [
4728
4781
  # {
4729
- # "asset": "USDT",
4730
- # "amount": "100.00000000000000000000",
4731
- # "type": "FUND_SFUTURES",
4782
+ # "asset": "LTC",
4783
+ # "amount": "0.05000000000000000000",
4732
4784
  # "status": "CONFIRMED",
4733
- # "tranId": 1067594500957016069,
4734
- # "timestamp": 1658388859000
4735
- # },
4785
+ # "transferId": "1051461075661819338791",
4786
+ # "timestamp": 1752202092000,
4787
+ # "fromAccount": "spot",
4788
+ # "toAccount": "USDTMPerp"
4789
+ # }
4736
4790
  # ]
4737
4791
  # }
4738
4792
  #
@@ -4740,15 +4794,14 @@ class bingx(Exchange, ImplicitAPI):
4740
4794
  return self.parse_transfers(rows, currency, since, limit)
4741
4795
 
4742
4796
  def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
4743
- tranId = self.safe_string(transfer, 'tranId')
4797
+ tranId = self.safe_string(transfer, 'transferId')
4744
4798
  timestamp = self.safe_integer(transfer, 'timestamp')
4745
- currencyCode = self.safe_currency_code(None, currency)
4799
+ currencyId = self.safe_string(transfer, 'asset')
4800
+ currencyCode = self.safe_currency_code(currencyId, currency)
4746
4801
  status = self.safe_string(transfer, 'status')
4747
4802
  accountsById = self.safe_dict(self.options, 'accountsById', {})
4748
- typeId = self.safe_string(transfer, 'type')
4749
- typeIdSplit = typeId.split('_')
4750
- fromId = self.safe_string(typeIdSplit, 0)
4751
- toId = self.safe_string(typeIdSplit, 1)
4803
+ fromId = self.safe_string(transfer, 'fromAccount')
4804
+ toId = self.safe_string(transfer, 'toAccount')
4752
4805
  fromAccount = self.safe_string(accountsById, fromId, fromId)
4753
4806
  toAccount = self.safe_string(accountsById, toId, toId)
4754
4807
  return {
@@ -5459,37 +5512,13 @@ class bingx(Exchange, ImplicitAPI):
5459
5512
 
5460
5513
  def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
5461
5514
  #
5462
- # {
5463
- # "coin": "BTC",
5464
- # "name": "BTC",
5465
- # "networkList": [
5466
- # {
5467
- # "name": "BTC",
5468
- # "network": "BTC",
5469
- # "isDefault": True,
5470
- # "minConfirm": "2",
5471
- # "withdrawEnable": True,
5472
- # "withdrawFee": "0.00035",
5473
- # "withdrawMax": "1.62842",
5474
- # "withdrawMin": "0.0005"
5475
- # },
5476
- # {
5477
- # "name": "BTC",
5478
- # "network": "BEP20",
5479
- # "isDefault": False,
5480
- # "minConfirm": "15",
5481
- # "withdrawEnable": True,
5482
- # "withdrawFee": "0.00001",
5483
- # "withdrawMax": "1.62734",
5484
- # "withdrawMin": "0.0001"
5485
- # }
5486
- # ]
5487
- # }
5515
+ # currencie structure
5488
5516
  #
5489
- networkList = self.safe_list(fee, 'networkList', [])
5490
- networkListLength = len(networkList)
5517
+ networks = self.safe_dict(fee, 'networks', {})
5518
+ networkCodes = list(networks.keys())
5519
+ networksLength = len(networkCodes)
5491
5520
  result: dict = {
5492
- 'info': fee,
5521
+ 'info': networks,
5493
5522
  'withdraw': {
5494
5523
  'fee': None,
5495
5524
  'percentage': None,
@@ -5500,18 +5529,15 @@ class bingx(Exchange, ImplicitAPI):
5500
5529
  },
5501
5530
  'networks': {},
5502
5531
  }
5503
- if networkListLength != 0:
5504
- for i in range(0, networkListLength):
5505
- network = networkList[i]
5506
- networkId = self.safe_string(network, 'network')
5507
- isDefault = self.safe_bool(network, 'isDefault')
5508
- currencyCode = self.safe_string(currency, 'code')
5509
- networkCode = self.network_id_to_code(networkId, currencyCode)
5532
+ if networksLength != 0:
5533
+ for i in range(0, networksLength):
5534
+ networkCode = networkCodes[i]
5535
+ network = networks[networkCode]
5510
5536
  result['networks'][networkCode] = {
5511
5537
  'deposit': {'fee': None, 'percentage': None},
5512
- 'withdraw': {'fee': self.safe_number(network, 'withdrawFee'), 'percentage': False},
5538
+ 'withdraw': {'fee': self.safe_number(network, 'fee'), 'percentage': False},
5513
5539
  }
5514
- if isDefault:
5540
+ if networksLength == 1:
5515
5541
  result['withdraw']['fee'] = self.safe_number(network, 'withdrawFee')
5516
5542
  result['withdraw']['percentage'] = False
5517
5543
  return result
@@ -5527,9 +5553,15 @@ class bingx(Exchange, ImplicitAPI):
5527
5553
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
5528
5554
  """
5529
5555
  await self.load_markets()
5530
- response = await self.walletsV1PrivateGetCapitalConfigGetall(params)
5531
- coins = self.safe_list(response, 'data')
5532
- return self.parse_deposit_withdraw_fees(coins, codes, 'coin')
5556
+ response = await self.fetch_currencies(params)
5557
+ depositWithdrawFees: dict = {}
5558
+ responseCodes = list(response.keys())
5559
+ for i in range(0, len(responseCodes)):
5560
+ code = responseCodes[i]
5561
+ if (codes is None) or (self.in_array(code, codes)):
5562
+ entry = response[code]
5563
+ depositWithdrawFees[code] = self.parse_deposit_withdraw_fee(entry)
5564
+ return depositWithdrawFees
5533
5565
 
5534
5566
  async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
5535
5567
  """
@@ -6229,8 +6261,13 @@ class bingx(Exchange, ImplicitAPI):
6229
6261
  raise NotSupported(self.id + ' does not have a testnet/sandbox URL for ' + type + ' endpoints')
6230
6262
  url = self.implode_hostname(self.urls['api'][type])
6231
6263
  path = self.implode_params(path, params)
6232
- if version == 'transfer':
6233
- type = 'account/transfer'
6264
+ versionIsTransfer = (version == 'transfer')
6265
+ versionIsAsset = (version == 'asset')
6266
+ if versionIsTransfer or versionIsAsset:
6267
+ if versionIsTransfer:
6268
+ type = 'account/transfer'
6269
+ else:
6270
+ type = 'api/asset'
6234
6271
  version = section[2]
6235
6272
  access = section[3]
6236
6273
  if path != 'account/apiPermissions':
@@ -1998,7 +1998,7 @@ class bitget(Exchange, ImplicitAPI):
1998
1998
  'cross': hasCrossMargin,
1999
1999
  'isolated': hasIsolatedMargin,
2000
2000
  }
2001
- isMarginTradingAllowed = hasCrossMargin or hasCrossMargin
2001
+ isMarginTradingAllowed = hasCrossMargin or hasIsolatedMargin
2002
2002
  else:
2003
2003
  if symbolType == 'perpetual':
2004
2004
  type = 'swap'
@@ -11,6 +11,7 @@ from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
13
13
  from ccxt.base.errors import PermissionDenied
14
+ from ccxt.base.errors import AccountSuspended
14
15
  from ccxt.base.errors import BadRequest
15
16
  from ccxt.base.errors import InsufficientFunds
16
17
  from ccxt.base.errors import InvalidAddress
@@ -531,6 +532,7 @@ class bitstamp(Exchange, ImplicitAPI):
531
532
  "Bitstamp.net is under scheduled maintenance. We'll be back soon.": OnMaintenance, # {"error": "Bitstamp.net is under scheduled maintenance. We'll be back soon."}
532
533
  'Order could not be placed.': ExchangeNotAvailable, # Order could not be placed(perhaps due to internal error or trade halt). Please retry placing order.
533
534
  'Invalid offset.': BadRequest,
535
+ 'Trading is currently unavailable for your account.': AccountSuspended, # {"status": "error", "reason": {"__all__": ["Trading is currently unavailable for your account."]}, "response_code": "403.004"}
534
536
  },
535
537
  'broad': {
536
538
  'Minimum order size is': InvalidOrder, # Minimum order size is 5.0 EUR.
@@ -904,6 +904,7 @@ class blofin(Exchange, ImplicitAPI):
904
904
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
905
905
  :param dict [params]: extra parameters specific to the exchange API endpoint
906
906
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
907
+ :param int [params.until]: timestamp in ms of the latest funding rate to fetch
907
908
  :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
908
909
  """
909
910
  if symbol is None:
@@ -912,7 +913,7 @@ class blofin(Exchange, ImplicitAPI):
912
913
  paginate = False
913
914
  paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
914
915
  if paginate:
915
- return await self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params)
916
+ return await self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 100)
916
917
  market = self.market(symbol)
917
918
  request: dict = {
918
919
  'instId': market['id'],
@@ -921,6 +922,10 @@ class blofin(Exchange, ImplicitAPI):
921
922
  request['before'] = max(since - 1, 0)
922
923
  if limit is not None:
923
924
  request['limit'] = limit
925
+ until = self.safe_integer(params, 'until')
926
+ if until is not None:
927
+ request['after'] = until
928
+ params = self.omit(params, 'until')
924
929
  response = await self.publicGetMarketFundingRateHistory(self.extend(request, params))
925
930
  rates = []
926
931
  data = self.safe_list(response, 'data', [])
@@ -8083,7 +8083,7 @@ classic accounts only/ spot not supported* fetches information on an order made
8083
8083
  'timestamp': timestamp,
8084
8084
  'datetime': self.iso8601(timestamp),
8085
8085
  'id': self.safe_string(income, 'execId'),
8086
- 'amount': self.safe_number(income, 'execQty'),
8086
+ 'amount': self.safe_number(income, 'execFee'),
8087
8087
  'rate': self.safe_number(income, 'feeRate'),
8088
8088
  }
8089
8089