ccxt 4.3.84__py2.py3-none-any.whl → 4.3.86__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 (51) hide show
  1. ccxt/__init__.py +4 -1
  2. ccxt/abstract/cryptocom.py +2 -0
  3. ccxt/abstract/hashkey.py +67 -0
  4. ccxt/abstract/kucoinfutures.py +2 -0
  5. ccxt/async_support/__init__.py +4 -1
  6. ccxt/async_support/base/exchange.py +2 -2
  7. ccxt/async_support/binance.py +4 -2
  8. ccxt/async_support/bitfinex.py +2 -2
  9. ccxt/async_support/bitmex.py +2 -0
  10. ccxt/async_support/bybit.py +16 -14
  11. ccxt/async_support/cryptocom.py +113 -3
  12. ccxt/async_support/hashkey.py +4062 -0
  13. ccxt/async_support/hyperliquid.py +80 -62
  14. ccxt/async_support/indodax.py +29 -8
  15. ccxt/async_support/kraken.py +28 -1
  16. ccxt/async_support/krakenfutures.py +10 -9
  17. ccxt/async_support/kucoinfutures.py +5 -0
  18. ccxt/async_support/mexc.py +2 -2
  19. ccxt/base/errors.py +6 -0
  20. ccxt/base/exchange.py +2 -2
  21. ccxt/binance.py +4 -2
  22. ccxt/bitfinex.py +2 -2
  23. ccxt/bitmex.py +2 -0
  24. ccxt/bybit.py +16 -14
  25. ccxt/cryptocom.py +113 -3
  26. ccxt/hashkey.py +4062 -0
  27. ccxt/hyperliquid.py +80 -62
  28. ccxt/indodax.py +29 -8
  29. ccxt/kraken.py +28 -1
  30. ccxt/krakenfutures.py +10 -9
  31. ccxt/kucoinfutures.py +5 -0
  32. ccxt/mexc.py +2 -2
  33. ccxt/pro/__init__.py +3 -1
  34. ccxt/pro/ascendex.py +41 -5
  35. ccxt/pro/binance.py +1 -1
  36. ccxt/pro/bingx.py +13 -12
  37. ccxt/pro/bitget.py +104 -4
  38. ccxt/pro/hashkey.py +783 -0
  39. ccxt/pro/hyperliquid.py +118 -1
  40. ccxt/pro/mexc.py +13 -7
  41. ccxt/pro/okx.py +21 -3
  42. ccxt/pro/woo.py +1 -0
  43. ccxt/pro/woofipro.py +1 -0
  44. ccxt/pro/xt.py +1 -0
  45. ccxt/test/tests_async.py +13 -30
  46. ccxt/test/tests_sync.py +13 -30
  47. {ccxt-4.3.84.dist-info → ccxt-4.3.86.dist-info}/METADATA +8 -6
  48. {ccxt-4.3.84.dist-info → ccxt-4.3.86.dist-info}/RECORD +51 -47
  49. {ccxt-4.3.84.dist-info → ccxt-4.3.86.dist-info}/LICENSE.txt +0 -0
  50. {ccxt-4.3.84.dist-info → ccxt-4.3.86.dist-info}/WHEEL +0 -0
  51. {ccxt-4.3.84.dist-info → ccxt-4.3.86.dist-info}/top_level.txt +0 -0
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.3.84'
25
+ __version__ = '4.3.86'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -54,6 +54,7 @@ from ccxt.base.errors import OperationRejected # noqa: F4
54
54
  from ccxt.base.errors import NoChange # noqa: F401
55
55
  from ccxt.base.errors import MarginModeAlreadySet # noqa: F401
56
56
  from ccxt.base.errors import MarketClosed # noqa: F401
57
+ from ccxt.base.errors import ManualInteractionNeeded # noqa: F401
57
58
  from ccxt.base.errors import InsufficientFunds # noqa: F401
58
59
  from ccxt.base.errors import InvalidAddress # noqa: F401
59
60
  from ccxt.base.errors import AddressPending # noqa: F401
@@ -141,6 +142,7 @@ from ccxt.fmfwio import fmfwio # noqa: F4
141
142
  from ccxt.gate import gate # noqa: F401
142
143
  from ccxt.gateio import gateio # noqa: F401
143
144
  from ccxt.gemini import gemini # noqa: F401
145
+ from ccxt.hashkey import hashkey # noqa: F401
144
146
  from ccxt.hitbtc import hitbtc # noqa: F401
145
147
  from ccxt.hitbtc3 import hitbtc3 # noqa: F401
146
148
  from ccxt.hollaex import hollaex # noqa: F401
@@ -252,6 +254,7 @@ exchanges = [
252
254
  'gate',
253
255
  'gateio',
254
256
  'gemini',
257
+ 'hashkey',
255
258
  'hitbtc',
256
259
  'hitbtc3',
257
260
  'hollaex',
@@ -38,6 +38,8 @@ class ImplicitAPI:
38
38
  v1_private_post_private_get_accounts = v1PrivatePostPrivateGetAccounts = Entry('private/get-accounts', ['v1', 'private'], 'POST', {'cost': 3.3333333333333335})
39
39
  v1_private_post_private_get_withdrawal_history = v1PrivatePostPrivateGetWithdrawalHistory = Entry('private/get-withdrawal-history', ['v1', 'private'], 'POST', {'cost': 3.3333333333333335})
40
40
  v1_private_post_private_get_deposit_history = v1PrivatePostPrivateGetDepositHistory = Entry('private/get-deposit-history', ['v1', 'private'], 'POST', {'cost': 3.3333333333333335})
41
+ v1_private_post_private_get_fee_rate = v1PrivatePostPrivateGetFeeRate = Entry('private/get-fee-rate', ['v1', 'private'], 'POST', {'cost': 2})
42
+ v1_private_post_private_get_instrument_fee_rate = v1PrivatePostPrivateGetInstrumentFeeRate = Entry('private/get-instrument-fee-rate', ['v1', 'private'], 'POST', {'cost': 2})
41
43
  v1_private_post_private_staking_stake = v1PrivatePostPrivateStakingStake = Entry('private/staking/stake', ['v1', 'private'], 'POST', {'cost': 2})
42
44
  v1_private_post_private_staking_unstake = v1PrivatePostPrivateStakingUnstake = Entry('private/staking/unstake', ['v1', 'private'], 'POST', {'cost': 2})
43
45
  v1_private_post_private_staking_get_staking_position = v1PrivatePostPrivateStakingGetStakingPosition = Entry('private/staking/get-staking-position', ['v1', 'private'], 'POST', {'cost': 2})
@@ -0,0 +1,67 @@
1
+ from ccxt.base.types import Entry
2
+
3
+
4
+ class ImplicitAPI:
5
+ public_get_api_v1_exchangeinfo = publicGetApiV1ExchangeInfo = Entry('api/v1/exchangeInfo', 'public', 'GET', {'cost': 5})
6
+ public_get_quote_v1_depth = publicGetQuoteV1Depth = Entry('quote/v1/depth', 'public', 'GET', {'cost': 1})
7
+ public_get_quote_v1_trades = publicGetQuoteV1Trades = Entry('quote/v1/trades', 'public', 'GET', {'cost': 1})
8
+ public_get_quote_v1_klines = publicGetQuoteV1Klines = Entry('quote/v1/klines', 'public', 'GET', {'cost': 1})
9
+ public_get_quote_v1_ticker_24hr = publicGetQuoteV1Ticker24hr = Entry('quote/v1/ticker/24hr', 'public', 'GET', {'cost': 1})
10
+ public_get_quote_v1_ticker_price = publicGetQuoteV1TickerPrice = Entry('quote/v1/ticker/price', 'public', 'GET', {'cost': 1})
11
+ public_get_quote_v1_ticker_bookticker = publicGetQuoteV1TickerBookTicker = Entry('quote/v1/ticker/bookTicker', 'public', 'GET', {'cost': 1})
12
+ public_get_quote_v1_depth_merged = publicGetQuoteV1DepthMerged = Entry('quote/v1/depth/merged', 'public', 'GET', {'cost': 1})
13
+ public_get_quote_v1_markprice = publicGetQuoteV1MarkPrice = Entry('quote/v1/markPrice', 'public', 'GET', {'cost': 1})
14
+ public_get_quote_v1_index = publicGetQuoteV1Index = Entry('quote/v1/index', 'public', 'GET', {'cost': 1})
15
+ public_get_api_v1_futures_fundingrate = publicGetApiV1FuturesFundingRate = Entry('api/v1/futures/fundingRate', 'public', 'GET', {'cost': 1})
16
+ public_get_api_v1_futures_historyfundingrate = publicGetApiV1FuturesHistoryFundingRate = Entry('api/v1/futures/historyFundingRate', 'public', 'GET', {'cost': 1})
17
+ public_get_api_v1_ping = publicGetApiV1Ping = Entry('api/v1/ping', 'public', 'GET', {'cost': 1})
18
+ public_get_api_v1_time = publicGetApiV1Time = Entry('api/v1/time', 'public', 'GET', {'cost': 1})
19
+ private_get_api_v1_spot_order = privateGetApiV1SpotOrder = Entry('api/v1/spot/order', 'private', 'GET', {'cost': 1})
20
+ private_get_api_v1_spot_openorders = privateGetApiV1SpotOpenOrders = Entry('api/v1/spot/openOrders', 'private', 'GET', {'cost': 1})
21
+ private_get_api_v1_spot_tradeorders = privateGetApiV1SpotTradeOrders = Entry('api/v1/spot/tradeOrders', 'private', 'GET', {'cost': 5})
22
+ private_get_api_v1_futures_leverage = privateGetApiV1FuturesLeverage = Entry('api/v1/futures/leverage', 'private', 'GET', {'cost': 1})
23
+ private_get_api_v1_futures_order = privateGetApiV1FuturesOrder = Entry('api/v1/futures/order', 'private', 'GET', {'cost': 1})
24
+ private_get_api_v1_futures_openorders = privateGetApiV1FuturesOpenOrders = Entry('api/v1/futures/openOrders', 'private', 'GET', {'cost': 1})
25
+ private_get_api_v1_futures_usertrades = privateGetApiV1FuturesUserTrades = Entry('api/v1/futures/userTrades', 'private', 'GET', {'cost': 1})
26
+ private_get_api_v1_futures_positions = privateGetApiV1FuturesPositions = Entry('api/v1/futures/positions', 'private', 'GET', {'cost': 1})
27
+ private_get_api_v1_futures_historyorders = privateGetApiV1FuturesHistoryOrders = Entry('api/v1/futures/historyOrders', 'private', 'GET', {'cost': 1})
28
+ private_get_api_v1_futures_balance = privateGetApiV1FuturesBalance = Entry('api/v1/futures/balance', 'private', 'GET', {'cost': 1})
29
+ private_get_api_v1_futures_liquidationassignstatus = privateGetApiV1FuturesLiquidationAssignStatus = Entry('api/v1/futures/liquidationAssignStatus', 'private', 'GET', {'cost': 1})
30
+ private_get_api_v1_futures_risklimit = privateGetApiV1FuturesRiskLimit = Entry('api/v1/futures/riskLimit', 'private', 'GET', {'cost': 1})
31
+ private_get_api_v1_futures_commissionrate = privateGetApiV1FuturesCommissionRate = Entry('api/v1/futures/commissionRate', 'private', 'GET', {'cost': 1})
32
+ private_get_api_v1_futures_getbestorder = privateGetApiV1FuturesGetBestOrder = Entry('api/v1/futures/getBestOrder', 'private', 'GET', {'cost': 1})
33
+ private_get_api_v1_account_vipinfo = privateGetApiV1AccountVipInfo = Entry('api/v1/account/vipInfo', 'private', 'GET', {'cost': 1})
34
+ private_get_api_v1_account = privateGetApiV1Account = Entry('api/v1/account', 'private', 'GET', {'cost': 1})
35
+ private_get_api_v1_account_trades = privateGetApiV1AccountTrades = Entry('api/v1/account/trades', 'private', 'GET', {'cost': 5})
36
+ private_get_api_v1_account_type = privateGetApiV1AccountType = Entry('api/v1/account/type', 'private', 'GET', {'cost': 5})
37
+ private_get_api_v1_account_checkapikey = privateGetApiV1AccountCheckApiKey = Entry('api/v1/account/checkApiKey', 'private', 'GET', {'cost': 1})
38
+ private_get_api_v1_account_balanceflow = privateGetApiV1AccountBalanceFlow = Entry('api/v1/account/balanceFlow', 'private', 'GET', {'cost': 5})
39
+ private_get_api_v1_spot_subaccount_openorders = privateGetApiV1SpotSubAccountOpenOrders = Entry('api/v1/spot/subAccount/openOrders', 'private', 'GET', {'cost': 1})
40
+ private_get_api_v1_spot_subaccount_tradeorders = privateGetApiV1SpotSubAccountTradeOrders = Entry('api/v1/spot/subAccount/tradeOrders', 'private', 'GET', {'cost': 1})
41
+ private_get_api_v1_subaccount_trades = privateGetApiV1SubAccountTrades = Entry('api/v1/subAccount/trades', 'private', 'GET', {'cost': 1})
42
+ private_get_api_v1_futures_subaccount_openorders = privateGetApiV1FuturesSubAccountOpenOrders = Entry('api/v1/futures/subAccount/openOrders', 'private', 'GET', {'cost': 1})
43
+ private_get_api_v1_futures_subaccount_historyorders = privateGetApiV1FuturesSubAccountHistoryOrders = Entry('api/v1/futures/subAccount/historyOrders', 'private', 'GET', {'cost': 1})
44
+ private_get_api_v1_futures_subaccount_usertrades = privateGetApiV1FuturesSubAccountUserTrades = Entry('api/v1/futures/subAccount/userTrades', 'private', 'GET', {'cost': 1})
45
+ private_get_api_v1_account_deposit_address = privateGetApiV1AccountDepositAddress = Entry('api/v1/account/deposit/address', 'private', 'GET', {'cost': 1})
46
+ private_get_api_v1_account_depositorders = privateGetApiV1AccountDepositOrders = Entry('api/v1/account/depositOrders', 'private', 'GET', {'cost': 1})
47
+ private_get_api_v1_account_withdraworders = privateGetApiV1AccountWithdrawOrders = Entry('api/v1/account/withdrawOrders', 'private', 'GET', {'cost': 1})
48
+ private_post_api_v1_userdatastream = privatePostApiV1UserDataStream = Entry('api/v1/userDataStream', 'private', 'POST', {'cost': 1})
49
+ private_post_api_v1_spot_ordertest = privatePostApiV1SpotOrderTest = Entry('api/v1/spot/orderTest', 'private', 'POST', {'cost': 1})
50
+ private_post_api_v1_spot_order = privatePostApiV1SpotOrder = Entry('api/v1/spot/order', 'private', 'POST', {'cost': 1})
51
+ private_post_api_v1_1_spot_order = privatePostApiV11SpotOrder = Entry('api/v1.1/spot/order', 'private', 'POST', {'cost': 1})
52
+ private_post_api_v1_spot_batchorders = privatePostApiV1SpotBatchOrders = Entry('api/v1/spot/batchOrders', 'private', 'POST', {'cost': 5})
53
+ private_post_api_v1_futures_leverage = privatePostApiV1FuturesLeverage = Entry('api/v1/futures/leverage', 'private', 'POST', {'cost': 1})
54
+ private_post_api_v1_futures_order = privatePostApiV1FuturesOrder = Entry('api/v1/futures/order', 'private', 'POST', {'cost': 1})
55
+ private_post_api_v1_futures_position_trading_stop = privatePostApiV1FuturesPositionTradingStop = Entry('api/v1/futures/position/trading-stop', 'private', 'POST', {'cost': 3})
56
+ private_post_api_v1_futures_batchorders = privatePostApiV1FuturesBatchOrders = Entry('api/v1/futures/batchOrders', 'private', 'POST', {'cost': 5})
57
+ private_post_api_v1_account_assettransfer = privatePostApiV1AccountAssetTransfer = Entry('api/v1/account/assetTransfer', 'private', 'POST', {'cost': 1})
58
+ private_post_api_v1_account_authaddress = privatePostApiV1AccountAuthAddress = Entry('api/v1/account/authAddress', 'private', 'POST', {'cost': 1})
59
+ private_post_api_v1_account_withdraw = privatePostApiV1AccountWithdraw = Entry('api/v1/account/withdraw', 'private', 'POST', {'cost': 1})
60
+ private_put_api_v1_userdatastream = privatePutApiV1UserDataStream = Entry('api/v1/userDataStream', 'private', 'PUT', {'cost': 1})
61
+ private_delete_api_v1_spot_order = privateDeleteApiV1SpotOrder = Entry('api/v1/spot/order', 'private', 'DELETE', {'cost': 1})
62
+ private_delete_api_v1_spot_openorders = privateDeleteApiV1SpotOpenOrders = Entry('api/v1/spot/openOrders', 'private', 'DELETE', {'cost': 5})
63
+ private_delete_api_v1_spot_cancelorderbyids = privateDeleteApiV1SpotCancelOrderByIds = Entry('api/v1/spot/cancelOrderByIds', 'private', 'DELETE', {'cost': 5})
64
+ private_delete_api_v1_futures_order = privateDeleteApiV1FuturesOrder = Entry('api/v1/futures/order', 'private', 'DELETE', {'cost': 1})
65
+ private_delete_api_v1_futures_batchorders = privateDeleteApiV1FuturesBatchOrders = Entry('api/v1/futures/batchOrders', 'private', 'DELETE', {'cost': 1})
66
+ private_delete_api_v1_futures_cancelorderbyids = privateDeleteApiV1FuturesCancelOrderByIds = Entry('api/v1/futures/cancelOrderByIds', 'private', 'DELETE', {'cost': 1})
67
+ private_delete_api_v1_userdatastream = privateDeleteApiV1UserDataStream = Entry('api/v1/userDataStream', 'private', 'DELETE', {'cost': 1})
@@ -162,6 +162,7 @@ class ImplicitAPI:
162
162
  futurespublic_get_status = futuresPublicGetStatus = Entry('status', 'futuresPublic', 'GET', {'cost': 1})
163
163
  futurespublic_get_level2_message_query = futuresPublicGetLevel2MessageQuery = Entry('level2/message/query', 'futuresPublic', 'GET', {'cost': 1})
164
164
  futurespublic_get_contracts_risk_limit_symbol = futuresPublicGetContractsRiskLimitSymbol = Entry('contracts/risk-limit/{symbol}', 'futuresPublic', 'GET', {'cost': 1})
165
+ futurespublic_get_alltickers = futuresPublicGetAllTickers = Entry('allTickers', 'futuresPublic', 'GET', {'cost': 1})
165
166
  futurespublic_get_level2_depth_limit = futuresPublicGetLevel2DepthLimit = Entry('level2/depth{limit}', 'futuresPublic', 'GET', {'cost': 1})
166
167
  futurespublic_get_level3_message_query = futuresPublicGetLevel3MessageQuery = Entry('level3/message/query', 'futuresPublic', 'GET', {'cost': 1})
167
168
  futurespublic_get_level3_snapshot = futuresPublicGetLevel3Snapshot = Entry('level3/snapshot', 'futuresPublic', 'GET', {'cost': 1})
@@ -191,6 +192,7 @@ class ImplicitAPI:
191
192
  futuresprivate_get_trade_statistics = futuresPrivateGetTradeStatistics = Entry('trade-statistics', 'futuresPrivate', 'GET', {'cost': 1})
192
193
  futuresprivate_get_trade_fees = futuresPrivateGetTradeFees = Entry('trade-fees', 'futuresPrivate', 'GET', {'cost': 1})
193
194
  futuresprivate_get_history_positions = futuresPrivateGetHistoryPositions = Entry('history-positions', 'futuresPrivate', 'GET', {'cost': 1})
195
+ futuresprivate_get_getmaxopensize = futuresPrivateGetGetMaxOpenSize = Entry('getMaxOpenSize', 'futuresPrivate', 'GET', {'cost': 1})
194
196
  futuresprivate_post_transfer_out = futuresPrivatePostTransferOut = Entry('transfer-out', 'futuresPrivate', 'POST', {'cost': 1})
195
197
  futuresprivate_post_transfer_in = futuresPrivatePostTransferIn = Entry('transfer-in', 'futuresPrivate', 'POST', {'cost': 1})
196
198
  futuresprivate_post_orders = futuresPrivatePostOrders = Entry('orders', 'futuresPrivate', 'POST', {'cost': 1.33})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.84'
7
+ __version__ = '4.3.86'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -33,6 +33,7 @@ from ccxt.base.errors import OperationRejected # noqa: F4
33
33
  from ccxt.base.errors import NoChange # noqa: F401
34
34
  from ccxt.base.errors import MarginModeAlreadySet # noqa: F401
35
35
  from ccxt.base.errors import MarketClosed # noqa: F401
36
+ from ccxt.base.errors import ManualInteractionNeeded # noqa: F401
36
37
  from ccxt.base.errors import InsufficientFunds # noqa: F401
37
38
  from ccxt.base.errors import InvalidAddress # noqa: F401
38
39
  from ccxt.base.errors import AddressPending # noqa: F401
@@ -121,6 +122,7 @@ from ccxt.async_support.fmfwio import fmfwio
121
122
  from ccxt.async_support.gate import gate # noqa: F401
122
123
  from ccxt.async_support.gateio import gateio # noqa: F401
123
124
  from ccxt.async_support.gemini import gemini # noqa: F401
125
+ from ccxt.async_support.hashkey import hashkey # noqa: F401
124
126
  from ccxt.async_support.hitbtc import hitbtc # noqa: F401
125
127
  from ccxt.async_support.hitbtc3 import hitbtc3 # noqa: F401
126
128
  from ccxt.async_support.hollaex import hollaex # noqa: F401
@@ -232,6 +234,7 @@ exchanges = [
232
234
  'gate',
233
235
  'gateio',
234
236
  'gemini',
237
+ 'hashkey',
235
238
  'hitbtc',
236
239
  'hitbtc3',
237
240
  'hollaex',
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.3.84'
5
+ __version__ = '4.3.86'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -1873,7 +1873,7 @@ class Exchange(BaseExchange):
1873
1873
  response = None
1874
1874
  if method == 'fetchAccounts':
1875
1875
  response = await getattr(self, method)(params)
1876
- elif method == 'getLeverageTiersPaginated':
1876
+ elif method == 'getLeverageTiersPaginated' or method == 'fetchPositions':
1877
1877
  response = await getattr(self, method)(symbol, params)
1878
1878
  else:
1879
1879
  response = await getattr(self, method)(symbol, since, maxEntriesPerRequest, params)
@@ -3761,12 +3761,14 @@ class binance(Exchange, ImplicitAPI):
3761
3761
  marketId = self.safe_string(ticker, 'symbol')
3762
3762
  symbol = self.safe_symbol(marketId, market, None, marketType)
3763
3763
  last = self.safe_string(ticker, 'lastPrice')
3764
+ wAvg = self.safe_string(ticker, 'weightedAvgPrice')
3764
3765
  isCoinm = ('baseVolume' in ticker)
3765
3766
  baseVolume = None
3766
3767
  quoteVolume = None
3767
3768
  if isCoinm:
3768
3769
  baseVolume = self.safe_string(ticker, 'baseVolume')
3769
- quoteVolume = self.safe_string(ticker, 'volume')
3770
+ # 'volume' field in inverse markets is not quoteVolume, but traded amount(per contracts)
3771
+ quoteVolume = Precise.string_mul(baseVolume, wAvg)
3770
3772
  else:
3771
3773
  baseVolume = self.safe_string(ticker, 'volume')
3772
3774
  quoteVolume = self.safe_string_2(ticker, 'quoteVolume', 'amount')
@@ -3780,7 +3782,7 @@ class binance(Exchange, ImplicitAPI):
3780
3782
  'bidVolume': self.safe_string(ticker, 'bidQty'),
3781
3783
  'ask': self.safe_string(ticker, 'askPrice'),
3782
3784
  'askVolume': self.safe_string(ticker, 'askQty'),
3783
- 'vwap': self.safe_string(ticker, 'weightedAvgPrice'),
3785
+ 'vwap': wAvg,
3784
3786
  'open': self.safe_string_2(ticker, 'openPrice', 'open'),
3785
3787
  'close': last,
3786
3788
  'last': last,
@@ -832,7 +832,7 @@ class bitfinex(Exchange, ImplicitAPI):
832
832
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
833
833
  """
834
834
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
835
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
835
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
836
836
  :param dict [params]: extra parameters specific to the exchange API endpoint
837
837
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
838
838
  """
@@ -841,7 +841,7 @@ class bitfinex(Exchange, ImplicitAPI):
841
841
  response = await self.publicGetTickers(params)
842
842
  result: dict = {}
843
843
  for i in range(0, len(response)):
844
- ticker = self.parse_ticker({'result': response[i]})
844
+ ticker = self.parse_ticker(response[i])
845
845
  symbol = ticker['symbol']
846
846
  result[symbol] = ticker
847
847
  return self.filter_by_array_tickers(result, 'symbol', symbols)
@@ -2307,6 +2307,8 @@ class bitmex(Exchange, ImplicitAPI):
2307
2307
  # 'otpToken': '123456', # requires if two-factor auth(OTP) is enabled
2308
2308
  # 'fee': 0.001, # bitcoin network fee
2309
2309
  }
2310
+ if self.twofa is not None:
2311
+ request['otpToken'] = self.totp(self.twofa)
2310
2312
  response = await self.privatePostUserRequestWithdrawal(self.extend(request, params))
2311
2313
  #
2312
2314
  # {
@@ -16,6 +16,7 @@ from ccxt.base.errors import ArgumentsRequired
16
16
  from ccxt.base.errors import BadRequest
17
17
  from ccxt.base.errors import NoChange
18
18
  from ccxt.base.errors import MarginModeAlreadySet
19
+ from ccxt.base.errors import ManualInteractionNeeded
19
20
  from ccxt.base.errors import InsufficientFunds
20
21
  from ccxt.base.errors import InvalidOrder
21
22
  from ccxt.base.errors import OrderNotFound
@@ -768,8 +769,11 @@ class bybit(Exchange, ImplicitAPI):
768
769
  '140069': PermissionDenied, # Do not allow OTC lending users to trade
769
770
  '140070': InvalidOrder, # ETP symbols are not allowed to be traded
770
771
  '170001': ExchangeError, # Internal error.
771
- '170007': RequestTimeout, # Timeout waiting for response from backend server.
772
772
  '170005': InvalidOrder, # Too many new orders; current limit is %s orders per %s.
773
+ '170007': RequestTimeout, # Timeout waiting for response from backend server.
774
+ '170010': InvalidOrder, # Purchase failed: Exceed the maximum position limit of leveraged tokens, the current available limit is %s USDT
775
+ '170011': InvalidOrder, # "Purchase failed: Exceed the maximum position limit of innovation tokens,
776
+ '170019': InvalidOrder, # the current available limit is replaceKey0 USDT"
773
777
  '170031': ExchangeError, # The feature has been suspended
774
778
  '170032': ExchangeError, # Network error. Please try again later
775
779
  '170033': InsufficientFunds, # margin Insufficient account balance
@@ -782,6 +786,7 @@ class bybit(Exchange, ImplicitAPI):
782
786
  '170116': InvalidOrder, # Invalid orderType.
783
787
  '170117': InvalidOrder, # Invalid side.
784
788
  '170121': InvalidOrder, # Invalid symbol.
789
+ '170124': InvalidOrder, # Order amount too large.
785
790
  '170130': BadRequest, # Data sent for paramter '%s' is not valid.
786
791
  '170131': InsufficientFunds, # Balance insufficient
787
792
  '170132': InvalidOrder, # Order price too high.
@@ -792,7 +797,6 @@ class bybit(Exchange, ImplicitAPI):
792
797
  '170137': InvalidOrder, # Order volume decimal too long
793
798
  '170139': InvalidOrder, # Order has been filled.
794
799
  '170140': InvalidOrder, # Transaction amount lower than the minimum.
795
- '170124': InvalidOrder, # Order amount too large.
796
800
  '170141': InvalidOrder, # Duplicate clientOrderId
797
801
  '170142': InvalidOrder, # Order has been canceled
798
802
  '170143': InvalidOrder, # Cannot be found on order book
@@ -817,6 +821,15 @@ class bybit(Exchange, ImplicitAPI):
817
821
  '170198': InvalidOrder, # Your order quantity to sell is too large. The filled price may deviate significantly from the market price. Please try again
818
822
  '170199': InvalidOrder, # Your order quantity to buy is too large. The filled price may deviate significantly from the nav. Please try again.
819
823
  '170200': InvalidOrder, # Your order quantity to sell is too large. The filled price may deviate significantly from the nav. Please try again.
824
+ '170201': PermissionDenied, # Your account has been restricted for trades. If you have any questions, please email us at support@bybit.com
825
+ '170202': InvalidOrder, # Invalid orderFilter parameter.
826
+ '170203': InvalidOrder, # Please enter the TP/SL price.
827
+ '170204': InvalidOrder, # trigger price cannot be higher than 110% price.
828
+ '170206': InvalidOrder, # trigger price cannot be lower than 90% of qty.
829
+ '170210': InvalidOrder, # New order rejected.
830
+ '170213': OrderNotFound, # Order does not exist.
831
+ '170217': InvalidOrder, # Only LIMIT-MAKER order is supported for the current pair.
832
+ '170218': InvalidOrder, # The LIMIT-MAKER order is rejected due to invalid price.
820
833
  '170221': BadRequest, # This coin does not exist.
821
834
  '170222': RateLimitExceeded, # Too many hasattr(self, requests) time frame.
822
835
  '170223': InsufficientFunds, # Your Spot Account with Institutional Lending triggers an alert or liquidation.
@@ -826,18 +839,7 @@ class bybit(Exchange, ImplicitAPI):
826
839
  '170228': InvalidOrder, # The purchase amount of each order exceeds the estimated maximum purchase amount.
827
840
  '170229': InvalidOrder, # The sell quantity per order exceeds the estimated maximum sell quantity.
828
841
  '170234': ExchangeError, # System Error
829
- '170210': InvalidOrder, # New order rejected.
830
- '170213': OrderNotFound, # Order does not exist.
831
- '170217': InvalidOrder, # Only LIMIT-MAKER order is supported for the current pair.
832
- '170218': InvalidOrder, # The LIMIT-MAKER order is rejected due to invalid price.
833
- '170010': InvalidOrder, # Purchase failed: Exceed the maximum position limit of leveraged tokens, the current available limit is %s USDT
834
- '170011': InvalidOrder, # "Purchase failed: Exceed the maximum position limit of innovation tokens,
835
- '170019': InvalidOrder, # the current available limit is replaceKey0 USDT"
836
- '170201': PermissionDenied, # Your account has been restricted for trades. If you have any questions, please email us at support@bybit.com
837
- '170202': InvalidOrder, # Invalid orderFilter parameter.
838
- '170203': InvalidOrder, # Please enter the TP/SL price.
839
- '170204': InvalidOrder, # trigger price cannot be higher than 110% price.
840
- '170206': InvalidOrder, # trigger price cannot be lower than 90% of qty.
842
+ '170241': ManualInteractionNeeded, # To proceed with trading, users must read through and confirm that they fully understand the project's risk disclosure document.
841
843
  '175000': InvalidOrder, # The serialNum is already in use.
842
844
  '175001': InvalidOrder, # Daily purchase limit has been exceeded. Please try again later.
843
845
  '175002': InvalidOrder, # There's a large number of purchase orders. Please try again later.
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.cryptocom import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -109,8 +109,8 @@ class cryptocom(Exchange, ImplicitAPI):
109
109
  'fetchTickers': True,
110
110
  'fetchTime': False,
111
111
  'fetchTrades': True,
112
- 'fetchTradingFee': False,
113
- 'fetchTradingFees': False,
112
+ 'fetchTradingFee': True,
113
+ 'fetchTradingFees': True,
114
114
  'fetchTransactionFees': False,
115
115
  'fetchTransactions': False,
116
116
  'fetchTransfers': False,
@@ -211,6 +211,8 @@ class cryptocom(Exchange, ImplicitAPI):
211
211
  'private/get-accounts': 10 / 3,
212
212
  'private/get-withdrawal-history': 10 / 3,
213
213
  'private/get-deposit-history': 10 / 3,
214
+ 'private/get-fee-rate': 2,
215
+ 'private/get-instrument-fee-rate': 2,
214
216
  'private/staking/stake': 2,
215
217
  'private/staking/unstake': 2,
216
218
  'private/staking/get-staking-position': 2,
@@ -2806,6 +2808,114 @@ class cryptocom(Exchange, ImplicitAPI):
2806
2808
  result = self.safe_dict(response, 'result')
2807
2809
  return self.parse_order(result, market)
2808
2810
 
2811
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
2812
+ """
2813
+ fetch the trading fees for a market
2814
+ :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-get-instrument-fee-rate
2815
+ :param str symbol: unified market symbol
2816
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2817
+ :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
2818
+ """
2819
+ await self.load_markets()
2820
+ market = self.market(symbol)
2821
+ request: dict = {
2822
+ 'instrument_name': market['id'],
2823
+ }
2824
+ response = await self.v1PrivatePostPrivateGetInstrumentFeeRate(self.extend(request, params))
2825
+ #
2826
+ # {
2827
+ # "id": 1,
2828
+ # "code": 0,
2829
+ # "method": "private/staking/unstake",
2830
+ # "result": {
2831
+ # "staking_id": "1",
2832
+ # "instrument_name": "SOL.staked",
2833
+ # "status": "NEW",
2834
+ # "quantity": "1",
2835
+ # "underlying_inst_name": "SOL",
2836
+ # "reason": "NO_ERROR"
2837
+ # }
2838
+ # }
2839
+ #
2840
+ data = self.safe_dict(response, 'result', {})
2841
+ return self.parse_trading_fee(data, market)
2842
+
2843
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
2844
+ """
2845
+ :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-get-fee-rate
2846
+ fetch the trading fees for multiple markets
2847
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2848
+ :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
2849
+ """
2850
+ await self.load_markets()
2851
+ response = await self.v1PrivatePostPrivateGetFeeRate(params)
2852
+ #
2853
+ # {
2854
+ # "id": 1,
2855
+ # "method": "/private/get-fee-rate",
2856
+ # "code": 0,
2857
+ # "result": {
2858
+ # "spot_tier": "3",
2859
+ # "deriv_tier": "3",
2860
+ # "effective_spot_maker_rate_bps": "6.5",
2861
+ # "effective_spot_taker_rate_bps": "6.9",
2862
+ # "effective_deriv_maker_rate_bps": "1.1",
2863
+ # "effective_deriv_taker_rate_bps": "3"
2864
+ # }
2865
+ # }
2866
+ #
2867
+ result = self.safe_dict(response, 'result', {})
2868
+ return self.parse_trading_fees(result)
2869
+
2870
+ def parse_trading_fees(self, response):
2871
+ #
2872
+ # {
2873
+ # "spot_tier": "3",
2874
+ # "deriv_tier": "3",
2875
+ # "effective_spot_maker_rate_bps": "6.5",
2876
+ # "effective_spot_taker_rate_bps": "6.9",
2877
+ # "effective_deriv_maker_rate_bps": "1.1",
2878
+ # "effective_deriv_taker_rate_bps": "3"
2879
+ # }
2880
+ #
2881
+ result: dict = {}
2882
+ result['info'] = response
2883
+ for i in range(0, len(self.symbols)):
2884
+ symbol = self.symbols[i]
2885
+ market = self.market(symbol)
2886
+ isSwap = market['swap']
2887
+ takerFeeKey = 'effective_deriv_taker_rate_bps' if isSwap else 'effective_spot_taker_rate_bps'
2888
+ makerFeeKey = 'effective_deriv_maker_rate_bps' if isSwap else 'effective_spot_maker_rate_bps'
2889
+ tradingFee = {
2890
+ 'info': response,
2891
+ 'symbol': symbol,
2892
+ 'maker': self.parse_number(Precise.string_div(self.safe_string(response, makerFeeKey), '10000')),
2893
+ 'taker': self.parse_number(Precise.string_div(self.safe_string(response, takerFeeKey), '10000')),
2894
+ 'percentage': None,
2895
+ 'tierBased': None,
2896
+ }
2897
+ result[symbol] = tradingFee
2898
+ return result
2899
+
2900
+ def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
2901
+ #
2902
+ # {
2903
+ # "instrument_name": "BTC_USD",
2904
+ # "effective_maker_rate_bps": "6.5",
2905
+ # "effective_taker_rate_bps": "6.9"
2906
+ # }
2907
+ #
2908
+ marketId = self.safe_string(fee, 'instrument_name')
2909
+ symbol = self.safe_symbol(marketId, market)
2910
+ return {
2911
+ 'info': fee,
2912
+ 'symbol': symbol,
2913
+ 'maker': self.parse_number(Precise.string_div(self.safe_string(fee, 'effective_maker_rate_bps'), '10000')),
2914
+ 'taker': self.parse_number(Precise.string_div(self.safe_string(fee, 'effective_taker_rate_bps'), '10000')),
2915
+ 'percentage': None,
2916
+ 'tierBased': None,
2917
+ }
2918
+
2809
2919
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2810
2920
  type = self.safe_string(api, 0)
2811
2921
  access = self.safe_string(api, 1)