ccxt 4.0.76__py2.py3-none-any.whl → 4.0.78__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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.0.76'
25
+ __version__ = '4.0.78'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
ccxt/abstract/bingx.py CHANGED
@@ -6,11 +6,11 @@ class ImplicitAPI:
6
6
  spot_v1_public_get_market_trades = spotV1PublicGetMarketTrades = Entry('market/trades', ['spot', 'v1', 'public'], 'GET', {'cost': 3})
7
7
  spot_v1_public_get_market_depth = spotV1PublicGetMarketDepth = Entry('market/depth', ['spot', 'v1', 'public'], 'GET', {'cost': 3})
8
8
  spot_v1_public_get_market_kline = spotV1PublicGetMarketKline = Entry('market/kline', ['spot', 'v1', 'public'], 'GET', {'cost': 3})
9
+ spot_v1_public_get_ticker_24hr = spotV1PublicGetTicker24hr = Entry('ticker/24hr', ['spot', 'v1', 'public'], 'GET', {'cost': 1})
9
10
  spot_v1_private_get_trade_query = spotV1PrivateGetTradeQuery = Entry('trade/query', ['spot', 'v1', 'private'], 'GET', {'cost': 3})
10
11
  spot_v1_private_get_trade_openorders = spotV1PrivateGetTradeOpenOrders = Entry('trade/openOrders', ['spot', 'v1', 'private'], 'GET', {'cost': 3})
11
12
  spot_v1_private_get_trade_historyorders = spotV1PrivateGetTradeHistoryOrders = Entry('trade/historyOrders', ['spot', 'v1', 'private'], 'GET', {'cost': 3})
12
13
  spot_v1_private_get_account_balance = spotV1PrivateGetAccountBalance = Entry('account/balance', ['spot', 'v1', 'private'], 'GET', {'cost': 3})
13
- spot_v1_private_get_ticker_24hr = spotV1PrivateGetTicker24hr = Entry('ticker/24hr', ['spot', 'v1', 'private'], 'GET', {'cost': 1})
14
14
  spot_v1_private_post_trade_order = spotV1PrivatePostTradeOrder = Entry('trade/order', ['spot', 'v1', 'private'], 'POST', {'cost': 3})
15
15
  spot_v1_private_post_trade_cancel = spotV1PrivatePostTradeCancel = Entry('trade/cancel', ['spot', 'v1', 'private'], 'POST', {'cost': 3})
16
16
  spot_v1_private_post_trade_batchorders = spotV1PrivatePostTradeBatchOrders = Entry('trade/batchOrders', ['spot', 'v1', 'private'], 'POST', {'cost': 3})
ccxt/abstract/gate.py CHANGED
@@ -80,6 +80,19 @@ class ImplicitAPI:
80
80
  private_subaccounts_post_sub_accounts_user_id_unlock = privateSubAccountsPostSubAccountsUserIdUnlock = Entry('sub_accounts/{user_id}/unlock', ['private', 'subAccounts'], 'POST', {'cost': 1})
81
81
  private_subaccounts_put_sub_accounts_user_id_keys_key = privateSubAccountsPutSubAccountsUserIdKeysKey = Entry('sub_accounts/{user_id}/keys/{key}', ['private', 'subAccounts'], 'PUT', {'cost': 1})
82
82
  private_subaccounts_delete_sub_accounts_user_id_keys_key = privateSubAccountsDeleteSubAccountsUserIdKeysKey = Entry('sub_accounts/{user_id}/keys/{key}', ['private', 'subAccounts'], 'DELETE', {'cost': 1})
83
+ private_portfolio_get_accounts = privatePortfolioGetAccounts = Entry('accounts', ['private', 'portfolio'], 'GET', {'cost': 1.5})
84
+ private_portfolio_get_account_mode = privatePortfolioGetAccountMode = Entry('account_mode', ['private', 'portfolio'], 'GET', {'cost': 1.5})
85
+ private_portfolio_get_borrowable = privatePortfolioGetBorrowable = Entry('borrowable', ['private', 'portfolio'], 'GET', {'cost': 1.5})
86
+ private_portfolio_get_transferable = privatePortfolioGetTransferable = Entry('transferable', ['private', 'portfolio'], 'GET', {'cost': 1.5})
87
+ private_portfolio_get_loans = privatePortfolioGetLoans = Entry('loans', ['private', 'portfolio'], 'GET', {'cost': 1.5})
88
+ private_portfolio_get_loan_records = privatePortfolioGetLoanRecords = Entry('loan_records', ['private', 'portfolio'], 'GET', {'cost': 1.5})
89
+ private_portfolio_get_interest_records = privatePortfolioGetInterestRecords = Entry('interest_records', ['private', 'portfolio'], 'GET', {'cost': 1.5})
90
+ private_portfolio_get_spot_orders = privatePortfolioGetSpotOrders = Entry('spot/orders', ['private', 'portfolio'], 'GET', {'cost': 1.5})
91
+ private_portfolio_get_spot_orders_order_id = privatePortfolioGetSpotOrdersOrderId = Entry('spot/orders/{order_id}', ['private', 'portfolio'], 'GET', {'cost': 1.5})
92
+ private_portfolio_post_loans = privatePortfolioPostLoans = Entry('loans', ['private', 'portfolio'], 'POST', {'cost': 1.5})
93
+ private_portfolio_post_spot_orders = privatePortfolioPostSpotOrders = Entry('spot/orders', ['private', 'portfolio'], 'POST', {'cost': 1.5})
94
+ private_portfolio_delete_spot_orders_order_id = privatePortfolioDeleteSpotOrdersOrderId = Entry('spot/orders/{order_id}', ['private', 'portfolio'], 'DELETE', {'cost': 1.5})
95
+ private_portfolio_patch_spot_orders_order_id = privatePortfolioPatchSpotOrdersOrderId = Entry('spot/orders/{order_id}', ['private', 'portfolio'], 'PATCH', {'cost': 1.5})
83
96
  private_spot_get_fee = privateSpotGetFee = Entry('fee', ['private', 'spot'], 'GET', {'cost': 1})
84
97
  private_spot_get_batch_fee = privateSpotGetBatchFee = Entry('batch_fee', ['private', 'spot'], 'GET', {'cost': 1})
85
98
  private_spot_get_accounts = privateSpotGetAccounts = Entry('accounts', ['private', 'spot'], 'GET', {'cost': 1})
@@ -213,10 +226,21 @@ class ImplicitAPI:
213
226
  private_earn_get_uni_interest_records = privateEarnGetUniInterestRecords = Entry('uni/interest_records', ['private', 'earn'], 'GET', {'cost': 1.5})
214
227
  private_earn_post_uni_lends = privateEarnPostUniLends = Entry('uni/lends', ['private', 'earn'], 'POST', {'cost': 1.5})
215
228
  private_earn_patch_uni_lends = privateEarnPatchUniLends = Entry('uni/lends', ['private', 'earn'], 'PATCH', {'cost': 1.5})
229
+ private_loan_get_collateral_orders = privateLoanGetCollateralOrders = Entry('collateral/orders', ['private', 'loan'], 'GET', {'cost': 1.5})
230
+ private_loan_get_collateral_orders_order_id = privateLoanGetCollateralOrdersOrderId = Entry('collateral/orders/{order_id}', ['private', 'loan'], 'GET', {'cost': 1.5})
231
+ private_loan_get_collateral_repay_records = privateLoanGetCollateralRepayRecords = Entry('collateral/repay_records', ['private', 'loan'], 'GET', {'cost': 1.5})
232
+ private_loan_get_collateral_collaterals = privateLoanGetCollateralCollaterals = Entry('collateral/collaterals', ['private', 'loan'], 'GET', {'cost': 1.5})
233
+ private_loan_get_collateral_total_amount = privateLoanGetCollateralTotalAmount = Entry('collateral/total_amount', ['private', 'loan'], 'GET', {'cost': 1.5})
234
+ private_loan_get_collateral_ltv = privateLoanGetCollateralLtv = Entry('collateral/ltv', ['private', 'loan'], 'GET', {'cost': 1.5})
235
+ private_loan_get_collateral_currencies = privateLoanGetCollateralCurrencies = Entry('collateral/currencies', ['private', 'loan'], 'GET', {'cost': 1.5})
236
+ private_loan_post_collateral_orders = privateLoanPostCollateralOrders = Entry('collateral/orders', ['private', 'loan'], 'POST', {'cost': 1.5})
237
+ private_loan_post_collateral_repay = privateLoanPostCollateralRepay = Entry('collateral/repay', ['private', 'loan'], 'POST', {'cost': 1.5})
238
+ private_loan_post_collateral_collaterals = privateLoanPostCollateralCollaterals = Entry('collateral/collaterals', ['private', 'loan'], 'POST', {'cost': 1.5})
216
239
  private_account_get_detail = privateAccountGetDetail = Entry('detail', ['private', 'account'], 'GET', {'cost': 1.5})
217
240
  private_account_get_stp_groups = privateAccountGetStpGroups = Entry('stp_groups', ['private', 'account'], 'GET', {'cost': 1.5})
218
241
  private_account_get_stp_groups_stp_id_users = privateAccountGetStpGroupsStpIdUsers = Entry('stp_groups/{stp_id}/users', ['private', 'account'], 'GET', {'cost': 1.5})
219
242
  private_account_post_stp_groups = privateAccountPostStpGroups = Entry('stp_groups', ['private', 'account'], 'POST', {'cost': 1.5})
220
243
  private_account_post_stp_groups_stp_id_users = privateAccountPostStpGroupsStpIdUsers = Entry('stp_groups/{stp_id}/users', ['private', 'account'], 'POST', {'cost': 1.5})
244
+ private_account_delete_stp_groups_stp_id_users = privateAccountDeleteStpGroupsStpIdUsers = Entry('stp_groups/{stp_id}/users', ['private', 'account'], 'DELETE', {'cost': 1.5})
221
245
  private_rebate_get_agency_transaction_history = privateRebateGetAgencyTransactionHistory = Entry('agency/transaction_history', ['private', 'rebate'], 'GET', {'cost': 1.5})
222
246
  private_rebate_get_agency_commission_history = privateRebateGetAgencyCommissionHistory = Entry('agency/commission_history', ['private', 'rebate'], 'GET', {'cost': 1.5})
ccxt/abstract/gateio.py CHANGED
@@ -80,6 +80,19 @@ class ImplicitAPI:
80
80
  private_subaccounts_post_sub_accounts_user_id_unlock = privateSubAccountsPostSubAccountsUserIdUnlock = Entry('sub_accounts/{user_id}/unlock', ['private', 'subAccounts'], 'POST', {'cost': 1})
81
81
  private_subaccounts_put_sub_accounts_user_id_keys_key = privateSubAccountsPutSubAccountsUserIdKeysKey = Entry('sub_accounts/{user_id}/keys/{key}', ['private', 'subAccounts'], 'PUT', {'cost': 1})
82
82
  private_subaccounts_delete_sub_accounts_user_id_keys_key = privateSubAccountsDeleteSubAccountsUserIdKeysKey = Entry('sub_accounts/{user_id}/keys/{key}', ['private', 'subAccounts'], 'DELETE', {'cost': 1})
83
+ private_portfolio_get_accounts = privatePortfolioGetAccounts = Entry('accounts', ['private', 'portfolio'], 'GET', {'cost': 1.5})
84
+ private_portfolio_get_account_mode = privatePortfolioGetAccountMode = Entry('account_mode', ['private', 'portfolio'], 'GET', {'cost': 1.5})
85
+ private_portfolio_get_borrowable = privatePortfolioGetBorrowable = Entry('borrowable', ['private', 'portfolio'], 'GET', {'cost': 1.5})
86
+ private_portfolio_get_transferable = privatePortfolioGetTransferable = Entry('transferable', ['private', 'portfolio'], 'GET', {'cost': 1.5})
87
+ private_portfolio_get_loans = privatePortfolioGetLoans = Entry('loans', ['private', 'portfolio'], 'GET', {'cost': 1.5})
88
+ private_portfolio_get_loan_records = privatePortfolioGetLoanRecords = Entry('loan_records', ['private', 'portfolio'], 'GET', {'cost': 1.5})
89
+ private_portfolio_get_interest_records = privatePortfolioGetInterestRecords = Entry('interest_records', ['private', 'portfolio'], 'GET', {'cost': 1.5})
90
+ private_portfolio_get_spot_orders = privatePortfolioGetSpotOrders = Entry('spot/orders', ['private', 'portfolio'], 'GET', {'cost': 1.5})
91
+ private_portfolio_get_spot_orders_order_id = privatePortfolioGetSpotOrdersOrderId = Entry('spot/orders/{order_id}', ['private', 'portfolio'], 'GET', {'cost': 1.5})
92
+ private_portfolio_post_loans = privatePortfolioPostLoans = Entry('loans', ['private', 'portfolio'], 'POST', {'cost': 1.5})
93
+ private_portfolio_post_spot_orders = privatePortfolioPostSpotOrders = Entry('spot/orders', ['private', 'portfolio'], 'POST', {'cost': 1.5})
94
+ private_portfolio_delete_spot_orders_order_id = privatePortfolioDeleteSpotOrdersOrderId = Entry('spot/orders/{order_id}', ['private', 'portfolio'], 'DELETE', {'cost': 1.5})
95
+ private_portfolio_patch_spot_orders_order_id = privatePortfolioPatchSpotOrdersOrderId = Entry('spot/orders/{order_id}', ['private', 'portfolio'], 'PATCH', {'cost': 1.5})
83
96
  private_spot_get_fee = privateSpotGetFee = Entry('fee', ['private', 'spot'], 'GET', {'cost': 1})
84
97
  private_spot_get_batch_fee = privateSpotGetBatchFee = Entry('batch_fee', ['private', 'spot'], 'GET', {'cost': 1})
85
98
  private_spot_get_accounts = privateSpotGetAccounts = Entry('accounts', ['private', 'spot'], 'GET', {'cost': 1})
@@ -213,10 +226,21 @@ class ImplicitAPI:
213
226
  private_earn_get_uni_interest_records = privateEarnGetUniInterestRecords = Entry('uni/interest_records', ['private', 'earn'], 'GET', {'cost': 1.5})
214
227
  private_earn_post_uni_lends = privateEarnPostUniLends = Entry('uni/lends', ['private', 'earn'], 'POST', {'cost': 1.5})
215
228
  private_earn_patch_uni_lends = privateEarnPatchUniLends = Entry('uni/lends', ['private', 'earn'], 'PATCH', {'cost': 1.5})
229
+ private_loan_get_collateral_orders = privateLoanGetCollateralOrders = Entry('collateral/orders', ['private', 'loan'], 'GET', {'cost': 1.5})
230
+ private_loan_get_collateral_orders_order_id = privateLoanGetCollateralOrdersOrderId = Entry('collateral/orders/{order_id}', ['private', 'loan'], 'GET', {'cost': 1.5})
231
+ private_loan_get_collateral_repay_records = privateLoanGetCollateralRepayRecords = Entry('collateral/repay_records', ['private', 'loan'], 'GET', {'cost': 1.5})
232
+ private_loan_get_collateral_collaterals = privateLoanGetCollateralCollaterals = Entry('collateral/collaterals', ['private', 'loan'], 'GET', {'cost': 1.5})
233
+ private_loan_get_collateral_total_amount = privateLoanGetCollateralTotalAmount = Entry('collateral/total_amount', ['private', 'loan'], 'GET', {'cost': 1.5})
234
+ private_loan_get_collateral_ltv = privateLoanGetCollateralLtv = Entry('collateral/ltv', ['private', 'loan'], 'GET', {'cost': 1.5})
235
+ private_loan_get_collateral_currencies = privateLoanGetCollateralCurrencies = Entry('collateral/currencies', ['private', 'loan'], 'GET', {'cost': 1.5})
236
+ private_loan_post_collateral_orders = privateLoanPostCollateralOrders = Entry('collateral/orders', ['private', 'loan'], 'POST', {'cost': 1.5})
237
+ private_loan_post_collateral_repay = privateLoanPostCollateralRepay = Entry('collateral/repay', ['private', 'loan'], 'POST', {'cost': 1.5})
238
+ private_loan_post_collateral_collaterals = privateLoanPostCollateralCollaterals = Entry('collateral/collaterals', ['private', 'loan'], 'POST', {'cost': 1.5})
216
239
  private_account_get_detail = privateAccountGetDetail = Entry('detail', ['private', 'account'], 'GET', {'cost': 1.5})
217
240
  private_account_get_stp_groups = privateAccountGetStpGroups = Entry('stp_groups', ['private', 'account'], 'GET', {'cost': 1.5})
218
241
  private_account_get_stp_groups_stp_id_users = privateAccountGetStpGroupsStpIdUsers = Entry('stp_groups/{stp_id}/users', ['private', 'account'], 'GET', {'cost': 1.5})
219
242
  private_account_post_stp_groups = privateAccountPostStpGroups = Entry('stp_groups', ['private', 'account'], 'POST', {'cost': 1.5})
220
243
  private_account_post_stp_groups_stp_id_users = privateAccountPostStpGroupsStpIdUsers = Entry('stp_groups/{stp_id}/users', ['private', 'account'], 'POST', {'cost': 1.5})
244
+ private_account_delete_stp_groups_stp_id_users = privateAccountDeleteStpGroupsStpIdUsers = Entry('stp_groups/{stp_id}/users', ['private', 'account'], 'DELETE', {'cost': 1.5})
221
245
  private_rebate_get_agency_transaction_history = privateRebateGetAgencyTransactionHistory = Entry('agency/transaction_history', ['private', 'rebate'], 'GET', {'cost': 1.5})
222
246
  private_rebate_get_agency_commission_history = privateRebateGetAgencyCommissionHistory = Entry('agency/commission_history', ['private', 'rebate'], 'GET', {'cost': 1.5})
ccxt/abstract/okex.py CHANGED
@@ -60,6 +60,7 @@ class ImplicitAPI:
60
60
  public_get_tradingbot_grid_ai_param = publicGetTradingBotGridAiParam = Entry('tradingBot/grid/ai-param', 'public', 'GET', {'cost': 1})
61
61
  public_get_tradingbot_grid_min_investment = publicGetTradingBotGridMinInvestment = Entry('tradingBot/grid/min-investment', 'public', 'GET', {'cost': 1})
62
62
  public_get_tradingbot_public_rsi_back_testing = publicGetTradingBotPublicRsiBackTesting = Entry('tradingBot/public/rsi-back-testing', 'public', 'GET', {'cost': 1})
63
+ public_get_asset_exchange_list = publicGetAssetExchangeList = Entry('asset/exchange-list', 'public', 'GET', {'cost': 1.6666666666666667})
63
64
  public_get_finance_savings_lending_rate_summary = publicGetFinanceSavingsLendingRateSummary = Entry('finance/savings/lending-rate-summary', 'public', 'GET', {'cost': 1.6666666666666667})
64
65
  public_get_finance_savings_lending_rate_history = publicGetFinanceSavingsLendingRateHistory = Entry('finance/savings/lending-rate-history', 'public', 'GET', {'cost': 1.6666666666666667})
65
66
  public_get_finance_sfp_dcd_products = publicGetFinanceSfpDcdProducts = Entry('finance/sfp/dcd/products', 'public', 'GET', {'cost': 0.6666666666666666})
ccxt/abstract/okex5.py CHANGED
@@ -60,6 +60,7 @@ class ImplicitAPI:
60
60
  public_get_tradingbot_grid_ai_param = publicGetTradingBotGridAiParam = Entry('tradingBot/grid/ai-param', 'public', 'GET', {'cost': 1})
61
61
  public_get_tradingbot_grid_min_investment = publicGetTradingBotGridMinInvestment = Entry('tradingBot/grid/min-investment', 'public', 'GET', {'cost': 1})
62
62
  public_get_tradingbot_public_rsi_back_testing = publicGetTradingBotPublicRsiBackTesting = Entry('tradingBot/public/rsi-back-testing', 'public', 'GET', {'cost': 1})
63
+ public_get_asset_exchange_list = publicGetAssetExchangeList = Entry('asset/exchange-list', 'public', 'GET', {'cost': 1.6666666666666667})
63
64
  public_get_finance_savings_lending_rate_summary = publicGetFinanceSavingsLendingRateSummary = Entry('finance/savings/lending-rate-summary', 'public', 'GET', {'cost': 1.6666666666666667})
64
65
  public_get_finance_savings_lending_rate_history = publicGetFinanceSavingsLendingRateHistory = Entry('finance/savings/lending-rate-history', 'public', 'GET', {'cost': 1.6666666666666667})
65
66
  public_get_finance_sfp_dcd_products = publicGetFinanceSfpDcdProducts = Entry('finance/sfp/dcd/products', 'public', 'GET', {'cost': 0.6666666666666666})
ccxt/abstract/okx.py CHANGED
@@ -60,6 +60,7 @@ class ImplicitAPI:
60
60
  public_get_tradingbot_grid_ai_param = publicGetTradingBotGridAiParam = Entry('tradingBot/grid/ai-param', 'public', 'GET', {'cost': 1})
61
61
  public_get_tradingbot_grid_min_investment = publicGetTradingBotGridMinInvestment = Entry('tradingBot/grid/min-investment', 'public', 'GET', {'cost': 1})
62
62
  public_get_tradingbot_public_rsi_back_testing = publicGetTradingBotPublicRsiBackTesting = Entry('tradingBot/public/rsi-back-testing', 'public', 'GET', {'cost': 1})
63
+ public_get_asset_exchange_list = publicGetAssetExchangeList = Entry('asset/exchange-list', 'public', 'GET', {'cost': 1.6666666666666667})
63
64
  public_get_finance_savings_lending_rate_summary = publicGetFinanceSavingsLendingRateSummary = Entry('finance/savings/lending-rate-summary', 'public', 'GET', {'cost': 1.6666666666666667})
64
65
  public_get_finance_savings_lending_rate_history = publicGetFinanceSavingsLendingRateHistory = Entry('finance/savings/lending-rate-history', 'public', 'GET', {'cost': 1.6666666666666667})
65
66
  public_get_finance_sfp_dcd_products = publicGetFinanceSfpDcdProducts = Entry('finance/sfp/dcd/products', 'public', 'GET', {'cost': 0.6666666666666666})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.0.76'
7
+ __version__ = '4.0.78'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.0.76'
5
+ __version__ = '4.0.78'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -2446,10 +2446,15 @@ class Exchange(BaseExchange):
2446
2446
  networkItem = self.safe_value(networks, networkCode, {})
2447
2447
  precision = self.safe_value(networkItem, 'precision', precision)
2448
2448
  if precision is None:
2449
- return fee
2449
+ return self.forceString(fee)
2450
2450
  else:
2451
2451
  return self.decimal_to_precision(fee, ROUND, precision, self.precisionMode, self.paddingMode)
2452
2452
 
2453
+ def force_string(self, value):
2454
+ if not isinstance(value, str):
2455
+ return self.number_to_string(value)
2456
+ return value
2457
+
2453
2458
  def is_tick_precision(self):
2454
2459
  return self.precisionMode == TICK_SIZE
2455
2460
 
@@ -108,6 +108,7 @@ class bingx(Exchange, ImplicitAPI):
108
108
  'market/trades': 3,
109
109
  'market/depth': 3,
110
110
  'market/kline': 3,
111
+ 'ticker/24hr': 1,
111
112
  },
112
113
  },
113
114
  'private': {
@@ -116,7 +117,6 @@ class bingx(Exchange, ImplicitAPI):
116
117
  'trade/openOrders': 3,
117
118
  'trade/historyOrders': 3,
118
119
  'account/balance': 3,
119
- 'ticker/24hr': 1,
120
120
  },
121
121
  'post': {
122
122
  'trade/order': 3,
@@ -274,6 +274,7 @@ class bingx(Exchange, ImplicitAPI):
274
274
  '500': ExchangeError,
275
275
  '504': ExchangeError,
276
276
  '100001': AuthenticationError,
277
+ '100412': AuthenticationError,
277
278
  '100202': InsufficientFunds,
278
279
  '100400': BadRequest,
279
280
  '100440': ExchangeError,
@@ -1070,9 +1071,9 @@ class bingx(Exchange, ImplicitAPI):
1070
1071
  }
1071
1072
  response = None
1072
1073
  if market['spot']:
1073
- response = await self.swapV2PublicGetQuoteTicker(self.extend(request, params))
1074
+ response = await self.spotV1PublicGetTicker24hr(self.extend(request, params))
1074
1075
  else:
1075
- response = await self.spotV1PublicGetCommonSymbols(self.extend(request, params))
1076
+ response = await self.swapV2PublicGetQuoteTicker(self.extend(request, params))
1076
1077
  #
1077
1078
  # {
1078
1079
  # "code": 0,
@@ -1094,7 +1095,8 @@ class bingx(Exchange, ImplicitAPI):
1094
1095
  # }
1095
1096
  #
1096
1097
  data = self.safe_value(response, 'data')
1097
- return self.parse_ticker(data, market)
1098
+ ticker = self.safe_value(data, 0, data)
1099
+ return self.parse_ticker(ticker, market)
1098
1100
 
1099
1101
  async def fetch_tickers(self, symbols: Optional[List[str]] = None, params={}):
1100
1102
  """
@@ -1105,13 +1107,18 @@ class bingx(Exchange, ImplicitAPI):
1105
1107
  :returns dict: a dictionary of `ticker structures <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
1106
1108
  """
1107
1109
  await self.load_markets()
1110
+ market = None
1108
1111
  if symbols is not None:
1109
1112
  symbols = self.market_symbols(symbols)
1110
1113
  firstSymbol = self.safe_string(symbols, 0)
1111
1114
  market = self.market(firstSymbol)
1112
- if not market['swap']:
1113
- raise BadRequest(self.id + ' fetchTicker is only supported for swap markets.')
1114
- response = await self.swapV2PublicGetQuoteTicker(params)
1115
+ type = None
1116
+ type, params = self.handle_market_type_and_params('fetchTickers', market, params)
1117
+ response = None
1118
+ if type == 'spot':
1119
+ response = await self.spotV1PublicGetTicker24hr(params)
1120
+ else:
1121
+ response = await self.swapV2PublicGetQuoteTicker(params)
1115
1122
  #
1116
1123
  # {
1117
1124
  # "code": 0,
@@ -1138,6 +1145,20 @@ class bingx(Exchange, ImplicitAPI):
1138
1145
  return self.parse_tickers(tickers, symbols)
1139
1146
 
1140
1147
  def parse_ticker(self, ticker, market=None):
1148
+ #
1149
+ # spot
1150
+ # {
1151
+ # symbol: 'BTC-USDT',
1152
+ # openPrice: '26032.08',
1153
+ # highPrice: '26178.86',
1154
+ # lowPrice: '25968.18',
1155
+ # lastPrice: '26113.60',
1156
+ # volume: '1161.79',
1157
+ # quoteVolume: '30288466.44',
1158
+ # openTime: '1693081020762',
1159
+ # closeTime: '1693167420762'
1160
+ # }
1161
+ # swap
1141
1162
  #
1142
1163
  # {
1143
1164
  # "symbol": "BTC-USDT",
@@ -1155,15 +1176,15 @@ class bingx(Exchange, ImplicitAPI):
1155
1176
  # }
1156
1177
  #
1157
1178
  marketId = self.safe_string(ticker, 'symbol')
1158
- defaultType = self.safe_string(self.options, 'defaultType', 'swap')
1159
- symbol = self.safe_symbol(marketId, market, '-', defaultType)
1179
+ change = self.safe_string(ticker, 'priceChange')
1180
+ type = 'spot' if (change is None) else 'swap'
1181
+ symbol = self.safe_symbol(marketId, market, None, type)
1160
1182
  open = self.safe_string(ticker, 'openPrice')
1161
1183
  high = self.safe_string(ticker, 'highPrice')
1162
1184
  low = self.safe_string(ticker, 'lowPrice')
1163
1185
  close = self.safe_string(ticker, 'lastPrice')
1164
1186
  quoteVolume = self.safe_string(ticker, 'quoteVolume')
1165
1187
  baseVolume = self.safe_string(ticker, 'volume')
1166
- change = self.safe_string(ticker, 'chapriceChangenge')
1167
1188
  percentage = self.safe_string(ticker, 'priceChangePercent')
1168
1189
  ts = self.safe_integer(ticker, 'closeTime')
1169
1190
  datetime = self.iso8601(ts)
@@ -2671,25 +2692,21 @@ class bingx(Exchange, ImplicitAPI):
2671
2692
  self.parse_transaction(data)
2672
2693
 
2673
2694
  def parse_params(self, params):
2674
- result = ''
2675
2695
  sortedParams = self.keysort(params)
2676
2696
  keys = list(sortedParams.keys())
2677
2697
  for i in range(0, len(keys)):
2678
2698
  key = keys[i]
2679
- if i > 0:
2680
- result += '&'
2681
2699
  value = sortedParams[key]
2682
2700
  if isinstance(value, list):
2683
- result += key + '=['
2701
+ arrStr = '['
2684
2702
  for j in range(0, len(value)):
2685
2703
  arrayElement = value[j]
2686
2704
  if j > 0:
2687
- result += ','
2688
- result += str(arrayElement)
2689
- result += ']'
2690
- else:
2691
- result += key + '=' + str(value)
2692
- return result
2705
+ arrStr += ','
2706
+ arrStr += str(arrayElement)
2707
+ arrStr += ']'
2708
+ sortedParams[key] = arrStr
2709
+ return sortedParams
2693
2710
 
2694
2711
  def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
2695
2712
  type = section[0]
@@ -2706,13 +2723,15 @@ class bingx(Exchange, ImplicitAPI):
2706
2723
  params = self.omit(params, self.extract_params(path))
2707
2724
  params = self.keysort(params)
2708
2725
  if access == 'public':
2726
+ params['timestamp'] = self.nonce()
2709
2727
  if params:
2710
2728
  url += '?' + self.urlencode(params)
2711
2729
  elif access == 'private':
2712
2730
  self.check_required_credentials()
2713
2731
  params['timestamp'] = self.nonce()
2714
- query = self.parse_params(params)
2715
- signature = self.hmac(self.encode(query), self.encode(self.secret), hashlib.sha256)
2732
+ parsedParams = self.parse_params(params)
2733
+ query = self.urlencode(parsedParams)
2734
+ signature = self.hmac(self.encode(self.rawencode(parsedParams)), self.encode(self.secret), hashlib.sha256)
2716
2735
  if params:
2717
2736
  query = '?' + query + '&'
2718
2737
  else:
@@ -298,6 +298,29 @@ class gate(Exchange, ImplicitAPI):
298
298
  'sub_accounts/{user_id}/keys/{key}': 1,
299
299
  },
300
300
  },
301
+ 'portfolio': {
302
+ 'get': {
303
+ 'accounts': 1.5,
304
+ 'account_mode': 1.5,
305
+ 'borrowable': 1.5,
306
+ 'transferable': 1.5,
307
+ 'loans': 1.5,
308
+ 'loan_records': 1.5,
309
+ 'interest_records': 1.5,
310
+ 'spot/orders': 1.5,
311
+ 'spot/orders/{order_id}': 1.5,
312
+ },
313
+ 'post': {
314
+ 'loans': 1.5,
315
+ 'spot/orders': 1.5,
316
+ },
317
+ 'delete': {
318
+ 'spot/orders/{order_id}': 1.5,
319
+ },
320
+ 'patch': {
321
+ 'spot/orders/{order_id}': 1.5,
322
+ },
323
+ },
301
324
  'spot': {
302
325
  'get': {
303
326
  'fee': 1,
@@ -491,6 +514,22 @@ class gate(Exchange, ImplicitAPI):
491
514
  'uni/lends': 1.5,
492
515
  },
493
516
  },
517
+ 'loan': {
518
+ 'get': {
519
+ 'collateral/orders': 1.5,
520
+ 'collateral/orders/{order_id}': 1.5,
521
+ 'collateral/repay_records': 1.5,
522
+ 'collateral/collaterals': 1.5,
523
+ 'collateral/total_amount': 1.5,
524
+ 'collateral/ltv': 1.5,
525
+ 'collateral/currencies': 1.5,
526
+ },
527
+ 'post': {
528
+ 'collateral/orders': 1.5,
529
+ 'collateral/repay': 1.5,
530
+ 'collateral/collaterals': 1.5,
531
+ },
532
+ },
494
533
  'account': {
495
534
  'get': {
496
535
  'detail': 1.5,
@@ -501,6 +540,9 @@ class gate(Exchange, ImplicitAPI):
501
540
  'stp_groups': 1.5,
502
541
  'stp_groups/{stp_id}/users': 1.5,
503
542
  },
543
+ 'delete': {
544
+ 'stp_groups/{stp_id}/users': 1.5,
545
+ },
504
546
  },
505
547
  'rebate': {
506
548
  'get': {
@@ -1098,7 +1098,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
1098
1098
  'size': preciseAmount,
1099
1099
  'leverage': 1,
1100
1100
  }
1101
- triggerPrice, stopLossPrice, takeProfitPrice = self.handleTriggerPrices(params)
1101
+ triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
1102
1102
  params = self.omit(params, ['stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'stopPrice'])
1103
1103
  if triggerPrice:
1104
1104
  request['stop'] = 'up' if (side == 'buy') else 'down'
ccxt/async_support/okx.py CHANGED
@@ -246,6 +246,7 @@ class okx(Exchange, ImplicitAPI):
246
246
  'tradingBot/grid/ai-param': 1,
247
247
  'tradingBot/grid/min-investment': 1,
248
248
  'tradingBot/public/rsi-back-testing': 1,
249
+ 'asset/exchange-list': 5 / 3,
249
250
  'finance/savings/lending-rate-summary': 5 / 3,
250
251
  'finance/savings/lending-rate-history': 5 / 3,
251
252
  # public broker
@@ -268,6 +268,7 @@ class whitebit(Exchange, ImplicitAPI):
268
268
  '422': OrderNotFound, # {"response":null,"status":422,"errors":{"orderId":["Finished order id 1295772653 not found on your account"]},"notification":null,"warning":"Finished order id 1295772653 not found on your account","_token":null}
269
269
  },
270
270
  'broad': {
271
+ 'This action is unauthorized': PermissionDenied, # {"code":2,"message":"This action is unauthorized. Enable your key in API settings"}
271
272
  'Given amount is less than min amount': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
272
273
  'Total is less than': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
273
274
  'fee must be no less than': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Total amount + fee must be no less than 5.05505"]}}
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.0.76'
7
+ __version__ = '4.0.78'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -3626,10 +3626,15 @@ class Exchange(object):
3626
3626
  networkItem = self.safe_value(networks, networkCode, {})
3627
3627
  precision = self.safe_value(networkItem, 'precision', precision)
3628
3628
  if precision is None:
3629
- return fee
3629
+ return self.forceString(fee)
3630
3630
  else:
3631
3631
  return self.decimal_to_precision(fee, ROUND, precision, self.precisionMode, self.paddingMode)
3632
3632
 
3633
+ def force_string(self, value):
3634
+ if not isinstance(value, str):
3635
+ return self.number_to_string(value)
3636
+ return value
3637
+
3633
3638
  def is_tick_precision(self):
3634
3639
  return self.precisionMode == TICK_SIZE
3635
3640
 
ccxt/bingx.py CHANGED
@@ -107,6 +107,7 @@ class bingx(Exchange, ImplicitAPI):
107
107
  'market/trades': 3,
108
108
  'market/depth': 3,
109
109
  'market/kline': 3,
110
+ 'ticker/24hr': 1,
110
111
  },
111
112
  },
112
113
  'private': {
@@ -115,7 +116,6 @@ class bingx(Exchange, ImplicitAPI):
115
116
  'trade/openOrders': 3,
116
117
  'trade/historyOrders': 3,
117
118
  'account/balance': 3,
118
- 'ticker/24hr': 1,
119
119
  },
120
120
  'post': {
121
121
  'trade/order': 3,
@@ -273,6 +273,7 @@ class bingx(Exchange, ImplicitAPI):
273
273
  '500': ExchangeError,
274
274
  '504': ExchangeError,
275
275
  '100001': AuthenticationError,
276
+ '100412': AuthenticationError,
276
277
  '100202': InsufficientFunds,
277
278
  '100400': BadRequest,
278
279
  '100440': ExchangeError,
@@ -1069,9 +1070,9 @@ class bingx(Exchange, ImplicitAPI):
1069
1070
  }
1070
1071
  response = None
1071
1072
  if market['spot']:
1072
- response = self.swapV2PublicGetQuoteTicker(self.extend(request, params))
1073
+ response = self.spotV1PublicGetTicker24hr(self.extend(request, params))
1073
1074
  else:
1074
- response = self.spotV1PublicGetCommonSymbols(self.extend(request, params))
1075
+ response = self.swapV2PublicGetQuoteTicker(self.extend(request, params))
1075
1076
  #
1076
1077
  # {
1077
1078
  # "code": 0,
@@ -1093,7 +1094,8 @@ class bingx(Exchange, ImplicitAPI):
1093
1094
  # }
1094
1095
  #
1095
1096
  data = self.safe_value(response, 'data')
1096
- return self.parse_ticker(data, market)
1097
+ ticker = self.safe_value(data, 0, data)
1098
+ return self.parse_ticker(ticker, market)
1097
1099
 
1098
1100
  def fetch_tickers(self, symbols: Optional[List[str]] = None, params={}):
1099
1101
  """
@@ -1104,13 +1106,18 @@ class bingx(Exchange, ImplicitAPI):
1104
1106
  :returns dict: a dictionary of `ticker structures <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
1105
1107
  """
1106
1108
  self.load_markets()
1109
+ market = None
1107
1110
  if symbols is not None:
1108
1111
  symbols = self.market_symbols(symbols)
1109
1112
  firstSymbol = self.safe_string(symbols, 0)
1110
1113
  market = self.market(firstSymbol)
1111
- if not market['swap']:
1112
- raise BadRequest(self.id + ' fetchTicker is only supported for swap markets.')
1113
- response = self.swapV2PublicGetQuoteTicker(params)
1114
+ type = None
1115
+ type, params = self.handle_market_type_and_params('fetchTickers', market, params)
1116
+ response = None
1117
+ if type == 'spot':
1118
+ response = self.spotV1PublicGetTicker24hr(params)
1119
+ else:
1120
+ response = self.swapV2PublicGetQuoteTicker(params)
1114
1121
  #
1115
1122
  # {
1116
1123
  # "code": 0,
@@ -1137,6 +1144,20 @@ class bingx(Exchange, ImplicitAPI):
1137
1144
  return self.parse_tickers(tickers, symbols)
1138
1145
 
1139
1146
  def parse_ticker(self, ticker, market=None):
1147
+ #
1148
+ # spot
1149
+ # {
1150
+ # symbol: 'BTC-USDT',
1151
+ # openPrice: '26032.08',
1152
+ # highPrice: '26178.86',
1153
+ # lowPrice: '25968.18',
1154
+ # lastPrice: '26113.60',
1155
+ # volume: '1161.79',
1156
+ # quoteVolume: '30288466.44',
1157
+ # openTime: '1693081020762',
1158
+ # closeTime: '1693167420762'
1159
+ # }
1160
+ # swap
1140
1161
  #
1141
1162
  # {
1142
1163
  # "symbol": "BTC-USDT",
@@ -1154,15 +1175,15 @@ class bingx(Exchange, ImplicitAPI):
1154
1175
  # }
1155
1176
  #
1156
1177
  marketId = self.safe_string(ticker, 'symbol')
1157
- defaultType = self.safe_string(self.options, 'defaultType', 'swap')
1158
- symbol = self.safe_symbol(marketId, market, '-', defaultType)
1178
+ change = self.safe_string(ticker, 'priceChange')
1179
+ type = 'spot' if (change is None) else 'swap'
1180
+ symbol = self.safe_symbol(marketId, market, None, type)
1159
1181
  open = self.safe_string(ticker, 'openPrice')
1160
1182
  high = self.safe_string(ticker, 'highPrice')
1161
1183
  low = self.safe_string(ticker, 'lowPrice')
1162
1184
  close = self.safe_string(ticker, 'lastPrice')
1163
1185
  quoteVolume = self.safe_string(ticker, 'quoteVolume')
1164
1186
  baseVolume = self.safe_string(ticker, 'volume')
1165
- change = self.safe_string(ticker, 'chapriceChangenge')
1166
1187
  percentage = self.safe_string(ticker, 'priceChangePercent')
1167
1188
  ts = self.safe_integer(ticker, 'closeTime')
1168
1189
  datetime = self.iso8601(ts)
@@ -2670,25 +2691,21 @@ class bingx(Exchange, ImplicitAPI):
2670
2691
  self.parse_transaction(data)
2671
2692
 
2672
2693
  def parse_params(self, params):
2673
- result = ''
2674
2694
  sortedParams = self.keysort(params)
2675
2695
  keys = list(sortedParams.keys())
2676
2696
  for i in range(0, len(keys)):
2677
2697
  key = keys[i]
2678
- if i > 0:
2679
- result += '&'
2680
2698
  value = sortedParams[key]
2681
2699
  if isinstance(value, list):
2682
- result += key + '=['
2700
+ arrStr = '['
2683
2701
  for j in range(0, len(value)):
2684
2702
  arrayElement = value[j]
2685
2703
  if j > 0:
2686
- result += ','
2687
- result += str(arrayElement)
2688
- result += ']'
2689
- else:
2690
- result += key + '=' + str(value)
2691
- return result
2704
+ arrStr += ','
2705
+ arrStr += str(arrayElement)
2706
+ arrStr += ']'
2707
+ sortedParams[key] = arrStr
2708
+ return sortedParams
2692
2709
 
2693
2710
  def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
2694
2711
  type = section[0]
@@ -2705,13 +2722,15 @@ class bingx(Exchange, ImplicitAPI):
2705
2722
  params = self.omit(params, self.extract_params(path))
2706
2723
  params = self.keysort(params)
2707
2724
  if access == 'public':
2725
+ params['timestamp'] = self.nonce()
2708
2726
  if params:
2709
2727
  url += '?' + self.urlencode(params)
2710
2728
  elif access == 'private':
2711
2729
  self.check_required_credentials()
2712
2730
  params['timestamp'] = self.nonce()
2713
- query = self.parse_params(params)
2714
- signature = self.hmac(self.encode(query), self.encode(self.secret), hashlib.sha256)
2731
+ parsedParams = self.parse_params(params)
2732
+ query = self.urlencode(parsedParams)
2733
+ signature = self.hmac(self.encode(self.rawencode(parsedParams)), self.encode(self.secret), hashlib.sha256)
2715
2734
  if params:
2716
2735
  query = '?' + query + '&'
2717
2736
  else:
ccxt/gate.py CHANGED
@@ -297,6 +297,29 @@ class gate(Exchange, ImplicitAPI):
297
297
  'sub_accounts/{user_id}/keys/{key}': 1,
298
298
  },
299
299
  },
300
+ 'portfolio': {
301
+ 'get': {
302
+ 'accounts': 1.5,
303
+ 'account_mode': 1.5,
304
+ 'borrowable': 1.5,
305
+ 'transferable': 1.5,
306
+ 'loans': 1.5,
307
+ 'loan_records': 1.5,
308
+ 'interest_records': 1.5,
309
+ 'spot/orders': 1.5,
310
+ 'spot/orders/{order_id}': 1.5,
311
+ },
312
+ 'post': {
313
+ 'loans': 1.5,
314
+ 'spot/orders': 1.5,
315
+ },
316
+ 'delete': {
317
+ 'spot/orders/{order_id}': 1.5,
318
+ },
319
+ 'patch': {
320
+ 'spot/orders/{order_id}': 1.5,
321
+ },
322
+ },
300
323
  'spot': {
301
324
  'get': {
302
325
  'fee': 1,
@@ -490,6 +513,22 @@ class gate(Exchange, ImplicitAPI):
490
513
  'uni/lends': 1.5,
491
514
  },
492
515
  },
516
+ 'loan': {
517
+ 'get': {
518
+ 'collateral/orders': 1.5,
519
+ 'collateral/orders/{order_id}': 1.5,
520
+ 'collateral/repay_records': 1.5,
521
+ 'collateral/collaterals': 1.5,
522
+ 'collateral/total_amount': 1.5,
523
+ 'collateral/ltv': 1.5,
524
+ 'collateral/currencies': 1.5,
525
+ },
526
+ 'post': {
527
+ 'collateral/orders': 1.5,
528
+ 'collateral/repay': 1.5,
529
+ 'collateral/collaterals': 1.5,
530
+ },
531
+ },
493
532
  'account': {
494
533
  'get': {
495
534
  'detail': 1.5,
@@ -500,6 +539,9 @@ class gate(Exchange, ImplicitAPI):
500
539
  'stp_groups': 1.5,
501
540
  'stp_groups/{stp_id}/users': 1.5,
502
541
  },
542
+ 'delete': {
543
+ 'stp_groups/{stp_id}/users': 1.5,
544
+ },
503
545
  },
504
546
  'rebate': {
505
547
  'get': {
ccxt/kucoinfutures.py CHANGED
@@ -1098,7 +1098,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
1098
1098
  'size': preciseAmount,
1099
1099
  'leverage': 1,
1100
1100
  }
1101
- triggerPrice, stopLossPrice, takeProfitPrice = self.handleTriggerPrices(params)
1101
+ triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
1102
1102
  params = self.omit(params, ['stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'stopPrice'])
1103
1103
  if triggerPrice:
1104
1104
  request['stop'] = 'up' if (side == 'buy') else 'down'
ccxt/okx.py CHANGED
@@ -245,6 +245,7 @@ class okx(Exchange, ImplicitAPI):
245
245
  'tradingBot/grid/ai-param': 1,
246
246
  'tradingBot/grid/min-investment': 1,
247
247
  'tradingBot/public/rsi-back-testing': 1,
248
+ 'asset/exchange-list': 5 / 3,
248
249
  'finance/savings/lending-rate-summary': 5 / 3,
249
250
  'finance/savings/lending-rate-history': 5 / 3,
250
251
  # public broker
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.0.76'
7
+ __version__ = '4.0.78'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/okx.py CHANGED
@@ -11,6 +11,7 @@ from ccxt.base.types import OrderType
11
11
  from ccxt.async_support.base.ws.client import Client
12
12
  from typing import Optional
13
13
  from typing import List
14
+ from ccxt.base.errors import ArgumentsRequired
14
15
  from ccxt.base.errors import BadRequest
15
16
  from ccxt.base.errors import InvalidNonce
16
17
  from ccxt.base.errors import AuthenticationError
@@ -226,6 +227,8 @@ class okx(ccxt.async_support.okx):
226
227
  :param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
227
228
  :returns dict: a `ticker structure <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
228
229
  """
230
+ if self.is_empty(symbols):
231
+ raise ArgumentsRequired(self.id + ' watchTickers requires a list of symbols')
229
232
  channel = None
230
233
  channel, params = self.handle_option_and_params(params, 'watchTickers', 'channel', 'tickers')
231
234
  newTickers = await self.subscribe_multiple('public', channel, symbols, params)
ccxt/test/test_async.py CHANGED
@@ -129,7 +129,7 @@ async def call_method(testFiles, methodName, exchange, skippedProperties, args):
129
129
 
130
130
 
131
131
  def exception_message(exc):
132
- return '[' + type(exc).__name__ + '] ' + "".join(format_exception(exc, limit=6))
132
+ return '[' + type(exc).__name__ + '] ' + "".join(format_exception(type(exc), exc, exc.__traceback__, limit=6))
133
133
 
134
134
 
135
135
  def exit_script():
@@ -296,6 +296,7 @@ class testMainClass(baseMainTestClass):
296
296
  dump(self.add_padding('[INFO:TESTING]', 25), exchange.id, methodNameInTest, argsStringified)
297
297
  skippedProperties = exchange.safe_value(self.skippedMethods, methodName, {})
298
298
  await call_method(self.testFiles, methodNameInTest, exchange, skippedProperties, args)
299
+ # if it was passed successfully, add to the list of successfull tests
299
300
  if isPublic:
300
301
  self.checkedPublicTests[methodNameInTest] = True
301
302
 
@@ -336,6 +337,9 @@ class testMainClass(baseMainTestClass):
336
337
  dump('[TEST_WARNING] Exchange is on maintenance', exchange.id)
337
338
  # If public test faces authentication error, we don't break(see comments under `testSafe` method)
338
339
  elif isPublic and isAuthError:
340
+ # in case of loadMarkets, it means that "tester"(developer or travis) does not have correct authentication, so it does not have a point to proceed at all
341
+ if methodName == 'loadMarkets':
342
+ dump('[TEST_WARNING]', 'Exchange can not be tested, because of authentication problems during loadMarkets', exception_message(e), exchange.id, methodName, argsStringified)
339
343
  if self.info:
340
344
  dump('[TEST_WARNING]', 'Authentication problem for public method', exception_message(e), exchange.id, methodName, argsStringified)
341
345
  else:
@@ -386,8 +390,9 @@ class testMainClass(baseMainTestClass):
386
390
  errors.append(testNames[i])
387
391
  # we don't raise exception for public-tests, see comments under 'testSafe' method
388
392
  failedMsg = ''
389
- if len(errors):
390
- failedMsg = ' | Failed methods: ' + ', '.join(errors)
393
+ errorsLength = len(errors)
394
+ if errorsLength > 0:
395
+ failedMsg = ' | Failed methods : ' + ', '.join(errors)
391
396
  dump(self.add_padding('[INFO:PUBLIC_TESTS_END] ' + market['type'] + failedMsg, 25), exchange.id)
392
397
 
393
398
  async def load_exchange(self, exchange):
ccxt/test/test_sync.py CHANGED
@@ -129,7 +129,7 @@ def call_method(testFiles, methodName, exchange, skippedProperties, args):
129
129
 
130
130
 
131
131
  def exception_message(exc):
132
- return '[' + type(exc).__name__ + '] ' + "".join(format_exception(exc, limit=6))
132
+ return '[' + type(exc).__name__ + '] ' + "".join(format_exception(type(exc), exc, exc.__traceback__, limit=6))
133
133
 
134
134
 
135
135
  def exit_script():
@@ -295,6 +295,7 @@ class testMainClass(baseMainTestClass):
295
295
  dump(self.add_padding('[INFO:TESTING]', 25), exchange.id, methodNameInTest, argsStringified)
296
296
  skippedProperties = exchange.safe_value(self.skippedMethods, methodName, {})
297
297
  call_method(self.testFiles, methodNameInTest, exchange, skippedProperties, args)
298
+ # if it was passed successfully, add to the list of successfull tests
298
299
  if isPublic:
299
300
  self.checkedPublicTests[methodNameInTest] = True
300
301
 
@@ -335,6 +336,9 @@ class testMainClass(baseMainTestClass):
335
336
  dump('[TEST_WARNING] Exchange is on maintenance', exchange.id)
336
337
  # If public test faces authentication error, we don't break(see comments under `testSafe` method)
337
338
  elif isPublic and isAuthError:
339
+ # in case of loadMarkets, it means that "tester"(developer or travis) does not have correct authentication, so it does not have a point to proceed at all
340
+ if methodName == 'loadMarkets':
341
+ dump('[TEST_WARNING]', 'Exchange can not be tested, because of authentication problems during loadMarkets', exception_message(e), exchange.id, methodName, argsStringified)
338
342
  if self.info:
339
343
  dump('[TEST_WARNING]', 'Authentication problem for public method', exception_message(e), exchange.id, methodName, argsStringified)
340
344
  else:
@@ -385,8 +389,9 @@ class testMainClass(baseMainTestClass):
385
389
  errors.append(testNames[i])
386
390
  # we don't raise exception for public-tests, see comments under 'testSafe' method
387
391
  failedMsg = ''
388
- if len(errors):
389
- failedMsg = ' | Failed methods: ' + ', '.join(errors)
392
+ errorsLength = len(errors)
393
+ if errorsLength > 0:
394
+ failedMsg = ' | Failed methods : ' + ', '.join(errors)
390
395
  dump(self.add_padding('[INFO:PUBLIC_TESTS_END] ' + market['type'] + failedMsg, 25), exchange.id)
391
396
 
392
397
  def load_exchange(self, exchange):
ccxt/whitebit.py CHANGED
@@ -268,6 +268,7 @@ class whitebit(Exchange, ImplicitAPI):
268
268
  '422': OrderNotFound, # {"response":null,"status":422,"errors":{"orderId":["Finished order id 1295772653 not found on your account"]},"notification":null,"warning":"Finished order id 1295772653 not found on your account","_token":null}
269
269
  },
270
270
  'broad': {
271
+ 'This action is unauthorized': PermissionDenied, # {"code":2,"message":"This action is unauthorized. Enable your key in API settings"}
271
272
  'Given amount is less than min amount': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
272
273
  'Total is less than': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
273
274
  'fee must be no less than': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Total amount + fee must be no less than 5.05505"]}}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.0.76
3
+ Version: 4.0.78
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -259,13 +259,13 @@ console.log(version, Object.keys(exchanges));
259
259
 
260
260
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
261
261
 
262
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.0.76/dist/ccxt.browser.js
263
- * unpkg: https://unpkg.com/ccxt@4.0.76/dist/ccxt.browser.js
262
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.0.78/dist/ccxt.browser.js
263
+ * unpkg: https://unpkg.com/ccxt@4.0.78/dist/ccxt.browser.js
264
264
 
265
265
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
266
266
 
267
267
  ```HTML
268
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.0.76/dist/ccxt.browser.js"></script>
268
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.0.78/dist/ccxt.browser.js"></script>
269
269
  ```
270
270
 
271
271
  Creates a global `ccxt` object:
@@ -1,4 +1,4 @@
1
- ccxt/__init__.py,sha256=l2cdoYMHRWll3DOa2eOy6hY7gyBhBUPZb1psKIrHHFI,15521
1
+ ccxt/__init__.py,sha256=Qd3AEtlnMeYGqp73_xm9yWclLNqAcJ6MqlmkpC46oVI,15521
2
2
  ccxt/ace.py,sha256=Xisv0lJgU05Ir1H00uwBDsBC7H6-1Qdv7x2qKgVv64Y,41499
3
3
  ccxt/alpaca.py,sha256=H7GYF2I-ci7WgtFHG3G74vGL8qbfIYkFI5EJrnrGWdA,33648
4
4
  ccxt/ascendex.py,sha256=01s6du4Jb3KA_iJi-_RDzYnUzApyB60Z7FnstNQLbV0,132963
@@ -8,7 +8,7 @@ ccxt/binance.py,sha256=-d6ePbJCvRCoTEz0_4DaAunBGumu7V7GFEF4yubfa-8,398374
8
8
  ccxt/binancecoinm.py,sha256=pncdw6Xw2X1Po-vEvAB4nL37scoS_axGAVxetPy1YQs,1645
9
9
  ccxt/binanceus.py,sha256=RoC8nReBHXUJzRNyqMe4vhta6gLGuh1fyFkI8FOMKBE,2151
10
10
  ccxt/binanceusdm.py,sha256=KPQGlCalQ0eGlPCs2tSanOxaP8O0zFRQjGntA16Yprw,2480
11
- ccxt/bingx.py,sha256=KR30rxdIWHTruNuiyhB230JixJQAlJO1EokqTCEL_vU,112407
11
+ ccxt/bingx.py,sha256=Ky8HkB9qqUXf_lsrQl3irubWQyVG0_o9SYNavAndYSA,113067
12
12
  ccxt/bit2c.py,sha256=i3KTftaZo0wA7hFDA6ByR-XSMg0DWnulDeE6HdGXxsI,35848
13
13
  ccxt/bitbank.py,sha256=USh3XJcwuXSm9F7eDHMSMw9xkWevDc--J6Lgn4m3KYU,39405
14
14
  ccxt/bitbay.py,sha256=xAIjzGRDVGwoy-Gygd99H0YN4wiaz_0lR0Z14oxaaxc,478
@@ -58,7 +58,7 @@ ccxt/digifinex.py,sha256=8T4BmCRqFSY_kNnf__kcskaBTzNDzvPf_zNmR2rwm3o,151393
58
58
  ccxt/exmo.py,sha256=nPepx_UuidmUorcMTE_mhPuOZMst4MNZAGOT8-0NmeE,88644
59
59
  ccxt/flowbtc.py,sha256=YPvm6tbsHJJUQBspFcHuVPQfVmiWzwnVvfzRqBdQX6U,1169
60
60
  ccxt/fmfwio.py,sha256=RbVLvzPwnqfDsE7Ea-N13ISCC82eJVPsXYjrleASmew,1236
61
- ccxt/gate.py,sha256=kn6aIL0pdtllt_YWjULDueT1H3V1XDqeNdKA1mF56Io,260325
61
+ ccxt/gate.py,sha256=7mEhQZZUCVsgcVC8oxY7YDXHOXAnZXipuMXAlmijA9Q,262151
62
62
  ccxt/gateio.py,sha256=86AETJWODl_vA5VNeQRHZprmpNIY1HAxCddKZcnKSi8,445
63
63
  ccxt/gemini.py,sha256=-huywMkpuitLZOUIJLjrKxNTooTn8nM-qLV1sLjUyp4,74061
64
64
  ccxt/hitbtc.py,sha256=5jR_sWSALrlFEs0X_SOT0ojrxeDjhW-9FFqmiSAukvU,126498
@@ -73,7 +73,7 @@ ccxt/indodax.py,sha256=1giTVcbn2vWhOQsZwjVOWgY-KKBZ2EZ-T4zaynvjla8,42696
73
73
  ccxt/kraken.py,sha256=hlvL3Trg24jOwl5h7rGt6bkPBNwwStoWKanjRgWptms,106331
74
74
  ccxt/krakenfutures.py,sha256=NK_d_-sr4XNK8qp0PTsm2qxpSFTo4vqtv5Y6PXFvHLM,87883
75
75
  ccxt/kucoin.py,sha256=n0ioHuTfwi4-sZiQcWFV_XF7eMeGL2FqTI2SdAoAr4A,182243
76
- ccxt/kucoinfutures.py,sha256=qG3oTEnkISCYbRkODSDcaC5AsAOJktcdZQewLj-MJcM,101644
76
+ ccxt/kucoinfutures.py,sha256=9BEtuhAgjtreTViXmw9aZUqjUl53s6JOlMKTbhmoCJ4,101646
77
77
  ccxt/kuna.py,sha256=niENogPCdDI73lWVlHwSRDxVLv7uq8DUuCL2PVbzWQA,37896
78
78
  ccxt/latoken.py,sha256=R04LqPIqcB14K_JHCDgHsBT82nn4ivMuvo6ec2NUd70,70360
79
79
  ccxt/lbank.py,sha256=EGLfAaTCaZOPUZt1Md40ClLacI_4mwN9Zhfu4uC0o_w,33838
@@ -89,7 +89,7 @@ ccxt/oceanex.py,sha256=tpbMBFXo_dZ067HpGBWD8Ugi18cLsZWKQdjN0LZd9fg,38405
89
89
  ccxt/okcoin.py,sha256=9rKxOvf4w_gi3EQ_tlGVA1MwhIo6KTzC2Kb30DqzV4E,178057
90
90
  ccxt/okex.py,sha256=nVDSzVztmboH593DVByjzFoOpFTzumcQFH_T9kdVKlE,434
91
91
  ccxt/okex5.py,sha256=LKTogVF1svNkqW_-Cx0AuAopu6esgFf7ucbv7CaodUg,441
92
- ccxt/okx.py,sha256=84z6mXcCzHY6NecSqZD1ZLMo0fFuNnL4TtyFo3M2qso,298976
92
+ ccxt/okx.py,sha256=uJ8l6OwvrRet6QzjRMqEo4H-m1RZ8OVoDHwNsc_k37A,299030
93
93
  ccxt/paymium.py,sha256=t3WwtUgNtjOkRQBdsWYft7NbnDbc2JKMR79dCtZPVX4,24074
94
94
  ccxt/phemex.py,sha256=eJivqcaH2i1G0cln9owAB8givPAYV1z-OHSZ5nuwSdM,199787
95
95
  ccxt/poloniex.py,sha256=7N1i2OflQkRk4Z4ibIv8GhFgO7eOdKws2dbeaffFADQ,99510
@@ -101,7 +101,7 @@ ccxt/tokocrypto.py,sha256=-g0eyDasanqa2Ni3whEnez1IQiuVeKmOQhEV7hMNE4E,121652
101
101
  ccxt/upbit.py,sha256=YpzO98GaVnSnJ4Rp2NO4FXRDtWMILr-sAxu-I3QVHhQ,75839
102
102
  ccxt/wavesexchange.py,sha256=efzFFrjlzhwoMkJEgalewR3j3iuqoJjQjAh8oCjJcwg,112924
103
103
  ccxt/wazirx.py,sha256=7wGV00xbSVnbbeYsw3lH9IyBa1E15dMwPa1qBLYgx9c,35743
104
- ccxt/whitebit.py,sha256=6sSQGWPZZo0eWmqSe7DBZ8iiGauhRsMuWfvscPd941s,98162
104
+ ccxt/whitebit.py,sha256=pSCtmXwO2Js8QXKvgzQzEVYhJpTxSIA5pH79emV4uSA,98318
105
105
  ccxt/woo.py,sha256=z1KmyemlOZXinwx7iMVJI0Rr3niRq15HwZ532joyxFE,105268
106
106
  ccxt/yobit.py,sha256=fR2NGmJnY9zhma02vJMh1Z1q9wfPz3-ssGLbfhKC5bo,51830
107
107
  ccxt/zaif.py,sha256=OWdPjhPAbCuYqjfqutqRZ-dxwUNaTqI3AZirJpQgmvs,28888
@@ -116,7 +116,7 @@ ccxt/abstract/binance.py,sha256=RRnz0rvvGi7XuCP86yQQaoTli-cjvted12ZXZGsGlpQ,8049
116
116
  ccxt/abstract/binancecoinm.py,sha256=RRnz0rvvGi7XuCP86yQQaoTli-cjvted12ZXZGsGlpQ,80495
117
117
  ccxt/abstract/binanceus.py,sha256=RRnz0rvvGi7XuCP86yQQaoTli-cjvted12ZXZGsGlpQ,80495
118
118
  ccxt/abstract/binanceusdm.py,sha256=RRnz0rvvGi7XuCP86yQQaoTli-cjvted12ZXZGsGlpQ,80495
119
- ccxt/abstract/bingx.py,sha256=K_0IyAno7pI79Rh9gcahq6Zpb9-Ewr7eFLWZaZX5mWg,10181
119
+ ccxt/abstract/bingx.py,sha256=L008EgA7iCVXpMlBqlKQAmb_Ps-REyRFXF9qs0YfZVo,10178
120
120
  ccxt/abstract/bit2c.py,sha256=np6i756kSB5dO3Nj6POLKxkWkpYcsGg-4LS8BwPrizI,2830
121
121
  ccxt/abstract/bitbank.py,sha256=k5D8PoPW2N79K_24NL9yY0qkwaCgzi_VoYUlqnj2bs8,2606
122
122
  ccxt/abstract/bitbay.py,sha256=VoxuPkSq8vAvKnDvOqnByhwsIf09m7yIrs8HejFrDk4,5482
@@ -165,8 +165,8 @@ ccxt/abstract/deribit.py,sha256=rS_982u8dOVsh2vGSB5TO7K8Tye0Alq-Rg9fYZwz8hg,1549
165
165
  ccxt/abstract/digifinex.py,sha256=2tlP2G6Niu6TSbNUcgxvXdHfln6VhAZliXV7upFwpas,9386
166
166
  ccxt/abstract/exmo.py,sha256=yq9zis5G9Qjsecs-YSHAghDjad6y52jFteWSBJZFg8o,6177
167
167
  ccxt/abstract/fmfwio.py,sha256=-bjb83y_4FGdHtHMo-naHYoI5JyltlF2M-TzjAZJ3Hg,10949
168
- ccxt/abstract/gate.py,sha256=c6k6EJqNLp9CkqWq9KYjCNJUkWHr0a51S6tQ38Jwm-o,33517
169
- ccxt/abstract/gateio.py,sha256=c6k6EJqNLp9CkqWq9KYjCNJUkWHr0a51S6tQ38Jwm-o,33517
168
+ ccxt/abstract/gate.py,sha256=-c44Lxt05-rvQaGhD57U1LyMyoC0m6bU6_IsiujbKpo,37155
169
+ ccxt/abstract/gateio.py,sha256=-c44Lxt05-rvQaGhD57U1LyMyoC0m6bU6_IsiujbKpo,37155
170
170
  ccxt/abstract/gemini.py,sha256=6TyBUDw-e4b02J5ToCX0eaXQfF0Knvkf7ToLcseqcIY,6915
171
171
  ccxt/abstract/hitbtc.py,sha256=-bjb83y_4FGdHtHMo-naHYoI5JyltlF2M-TzjAZJ3Hg,10949
172
172
  ccxt/abstract/hitbtc3.py,sha256=-bjb83y_4FGdHtHMo-naHYoI5JyltlF2M-TzjAZJ3Hg,10949
@@ -194,9 +194,9 @@ ccxt/abstract/ndax.py,sha256=M98Ys406KT6T19Y98dXriD6YjzfglHHbnfQw-PDYWtM,11878
194
194
  ccxt/abstract/novadax.py,sha256=Yy-lYKteQyZTaajK5oQTTikd5sU33cct4ZdtNxo2j30,2565
195
195
  ccxt/abstract/oceanex.py,sha256=a0xAelMYDY_J3QwwLyIX2tGQcv4z2gmX_yJyC6FqoFg,1721
196
196
  ccxt/abstract/okcoin.py,sha256=aaKdO53NvRjbEFTh8NL1YsHyaTyfApO4xkh0NQZdQWA,25825
197
- ccxt/abstract/okex.py,sha256=fud6WgR48X-7Jd7BPBA4kIA3iaxAcbKsItk35032VGA,37832
198
- ccxt/abstract/okex5.py,sha256=fud6WgR48X-7Jd7BPBA4kIA3iaxAcbKsItk35032VGA,37832
199
- ccxt/abstract/okx.py,sha256=fud6WgR48X-7Jd7BPBA4kIA3iaxAcbKsItk35032VGA,37832
197
+ ccxt/abstract/okex.py,sha256=PZ3mVv1V90hGDJY3FYUKYDE-vdEdGJibz-y8mLpW4r8,37974
198
+ ccxt/abstract/okex5.py,sha256=PZ3mVv1V90hGDJY3FYUKYDE-vdEdGJibz-y8mLpW4r8,37974
199
+ ccxt/abstract/okx.py,sha256=PZ3mVv1V90hGDJY3FYUKYDE-vdEdGJibz-y8mLpW4r8,37974
200
200
  ccxt/abstract/paymium.py,sha256=Bol6PEkHg_47betqBnL4aQQ4IhIp4owID_12VfDqn0E,2843
201
201
  ccxt/abstract/phemex.py,sha256=WI9OCdkxkid1TcE44SaCCSkucvwGjPRNDA1Pmgjhl10,13512
202
202
  ccxt/abstract/poloniex.py,sha256=zPyRTMRU_z8wnXdwFVU2a6qgrBHxveUH-lDIySfRRuk,6301
@@ -213,7 +213,7 @@ ccxt/abstract/woo.py,sha256=Z3ua45hKE0Tf9rtfSEYYgGEztaTO1Ri3mKl_hIo3OHs,8768
213
213
  ccxt/abstract/yobit.py,sha256=8ycfCO8ORFly9hc0Aa47sZyX4_ZKPXS9h9yJzI-uQ7Q,1339
214
214
  ccxt/abstract/zaif.py,sha256=m15WHdl3gYy0GOXNZ8NEH8eE7sVh8c0T_ITNuU8vXeU,3935
215
215
  ccxt/abstract/zonda.py,sha256=VoxuPkSq8vAvKnDvOqnByhwsIf09m7yIrs8HejFrDk4,5482
216
- ccxt/async_support/__init__.py,sha256=gdPy0C5Gn8QGDGngZ03EA-VAexqF3pVtbeu-TuQJu3U,15304
216
+ ccxt/async_support/__init__.py,sha256=zkhscRtyyM4GdPlmtw5Qm-3ixJdkm75CZyylc-y194c,15304
217
217
  ccxt/async_support/ace.py,sha256=GfB1wI9oK_nmj2IH-J1KYXkg8qjzWlWK7SaMuZCWRdk,41723
218
218
  ccxt/async_support/alpaca.py,sha256=frGPbeZHd2nEN9Q45phgnNOmU4Brh9e_FgDEEFnRyVM,33794
219
219
  ccxt/async_support/ascendex.py,sha256=Cv4Okc5hRD23CVReRIT9vrI_4hWtvTyOWts5XXohW_c,133595
@@ -223,7 +223,7 @@ ccxt/async_support/binance.py,sha256=KSc-Z39r6VK6HPoi2_JGJcC59YSs49bTbm90gmZyBJM
223
223
  ccxt/async_support/binancecoinm.py,sha256=IY3RLZptQA2nmZaUYRGfTa5ZY4VMWBpFYfwHc8zTHw0,1683
224
224
  ccxt/async_support/binanceus.py,sha256=Jtyl0jtSOpdjAAAYcSUzH6YRVxe88RJ6f4_IUge5gWg,2165
225
225
  ccxt/async_support/binanceusdm.py,sha256=-1r4A4tmV2pCiLGO80hzq7MIIj4MTzOD7buZGv6JauA,2518
226
- ccxt/async_support/bingx.py,sha256=IeFbN49z6OWLBKp5yS3B_G_OipbrePgIIddFGA5p-M4,113101
226
+ ccxt/async_support/bingx.py,sha256=FikgttEBAZ9ai8YvLaafwqIMCPUVCY8ALLi6AqT-vfY,113767
227
227
  ccxt/async_support/bit2c.py,sha256=BjoSNY-lVr3Fh45F-QEyKvCBy94t14dV6uzG89te9xI,36054
228
228
  ccxt/async_support/bitbank.py,sha256=FN-4xLWqfUARmKFfrWV1s_0Luv4warSDLJmc1YYfxT8,39665
229
229
  ccxt/async_support/bitbay.py,sha256=jcaEXi2IhYTva8ezO_SfJhwxEZk7HST4J3NaxD16BQA,492
@@ -273,7 +273,7 @@ ccxt/async_support/digifinex.py,sha256=G3BoD3bB1a7gRN1KlHJyVMw5uUKQ2eSLsIcLBnrqX
273
273
  ccxt/async_support/exmo.py,sha256=ezih4gdfKN8nnP11N6-NpKk0ic9g9u0hpdLPR879Exs,89186
274
274
  ccxt/async_support/flowbtc.py,sha256=bCnvtcNnPxxaxqVjI1GGXKhIpz_1r4GIFWqqPokvCR0,1183
275
275
  ccxt/async_support/fmfwio.py,sha256=lzfSnPrB2ARcC3EIqAuBM4vyg6LJ6n8RE71Zvt3ez1s,1250
276
- ccxt/async_support/gate.py,sha256=JS5w-pnM-9ijULSPrTU_NjqoumMxNH7afTvBNgeWFgI,261283
276
+ ccxt/async_support/gate.py,sha256=BW2XFFGwnb3jCHAxA3KF0qozB7KG0_986sLX02AsulU,263109
277
277
  ccxt/async_support/gateio.py,sha256=6_t032F9p9x5KGTjtSuqGXITzFOx-XAQBYLpsuQjzxw,459
278
278
  ccxt/async_support/gemini.py,sha256=Lg8YQf-3NSL8qcub6EG1Y9vhqS3x1bXFiVRwpdz3bXk,74551
279
279
  ccxt/async_support/hitbtc.py,sha256=BexA5IY_Bl82NMhIDpCmL10y9oBrJEqK5z5v5K0_Xqs,127184
@@ -288,7 +288,7 @@ ccxt/async_support/indodax.py,sha256=9nigvYH2MhCoGXaLrfLZESTG9OIkLeQScWlSYqerFjk
288
288
  ccxt/async_support/kraken.py,sha256=rJr5gIPmJa-4km1lo_dzzZ-zf_OcIkk64s0TUuKaMlI,106903
289
289
  ccxt/async_support/krakenfutures.py,sha256=lU2qgM14vZxYqy_e3g9JYnAK81zuXjLFhLtIH5ooqyQ,88239
290
290
  ccxt/async_support/kucoin.py,sha256=b_UWSmAezxEqE0D6-yvxcmkPd6mU6bQ0yhc8urYUUn4,182925
291
- ccxt/async_support/kucoinfutures.py,sha256=ZgK_6h9IR3lHKgr2-FLCKRiY0Wz1rRj8x2eXJbGaEMg,102114
291
+ ccxt/async_support/kucoinfutures.py,sha256=k8J1e4GmWMx7HrR2bu8Urs7Akbfxs6mafW0FQnqPLH0,102116
292
292
  ccxt/async_support/kuna.py,sha256=awFhHb2hrB29J06OvUvzDUbIR8lpYqnsVcFoerKXUVo,38144
293
293
  ccxt/async_support/latoken.py,sha256=EIEP2L7aM0ViKWQkiW0rdJBtTnQTkyEtpoL-6kuj_1U,70752
294
294
  ccxt/async_support/lbank.py,sha256=mvAXSMMZi9gMb1cjeMysUt8w_deNu3bQHQIq1aId7Bw,34074
@@ -304,7 +304,7 @@ ccxt/async_support/oceanex.py,sha256=9RhLU9Qg6QfPLq8Sm80x1cUrbCZZa635-u8aS8JPwOo
304
304
  ccxt/async_support/okcoin.py,sha256=r42d-1JOQv_aKG8fNw08QWxWUwtdWDNoJRX54F2z2ts,178521
305
305
  ccxt/async_support/okex.py,sha256=6dbtH4bC1C2x4cQUK6W62y7PuDgO3YazuFa7DYhM4Jw,448
306
306
  ccxt/async_support/okex5.py,sha256=tq41tKx06j3DDO9pu9iKInpjayVprbobVNTK8qb7hoM,455
307
- ccxt/async_support/okx.py,sha256=jBjPtAXsbOxFAPgoSRI5kHoU8I42caeftvwlcAMVE5A,300071
307
+ ccxt/async_support/okx.py,sha256=4ses0Vuc99oO4-cx9N6MWSvsoVMrMVJWa3TxOFMTsBg,300125
308
308
  ccxt/async_support/paymium.py,sha256=zmAviU5hbEeDjiZxOEnWsk3gSy_enP0xOFZjxqWrTog,24262
309
309
  ccxt/async_support/phemex.py,sha256=Wk4-9K2-fUvRA_5sZIyocCi7aa205iXSG3s1renmlhE,200383
310
310
  ccxt/async_support/poloniex.py,sha256=V47KddBSy52lDU8j9a866CNfKdxmfYNJpBPoK4QfnZk,100046
@@ -316,13 +316,13 @@ ccxt/async_support/tokocrypto.py,sha256=3dllnzzV6Nyby4eysWOLOSFrtBXee30DuT1eiqST
316
316
  ccxt/async_support/upbit.py,sha256=r2cQ2WDQPvOsVPCxx2Uqfh9gtQLo1tGi7Ave1voFGpQ,76273
317
317
  ccxt/async_support/wavesexchange.py,sha256=5DZkkYA0NlmWkrD-6LiqFyZQNMK1m91sCw3xvsB4sf4,113474
318
318
  ccxt/async_support/wazirx.py,sha256=PFjb3U-hAbdE7YDTwA3LGqNcVmFoE2rYQjfr2PLfZJw,35991
319
- ccxt/async_support/whitebit.py,sha256=2Wf_qZ7-86UBtMCP_7qfhvJhIoebeIbSBTSg4ulT6IQ,98656
319
+ ccxt/async_support/whitebit.py,sha256=Rl7FznEGXOglxoFzXejns01Qhcn-ycYVJkBLd_rcukU,98812
320
320
  ccxt/async_support/woo.py,sha256=_UahOgG8CHaFXFKnuelUERs4_U-8sXvWvqGxayyAijc,105870
321
321
  ccxt/async_support/yobit.py,sha256=d9hY9Sam1tIdDyUavBz_LeO74vfKPFk5_-4gS5iwurU,52114
322
322
  ccxt/async_support/zaif.py,sha256=3iz6oNEYONAjhCLVKK13T1d2eQ0pklzgxCkkdqn5zyM,29070
323
323
  ccxt/async_support/zonda.py,sha256=BGNx6UYa19tDo_UBLPC6sJKirzTQsuQpdpzsXiVR0JE,79973
324
324
  ccxt/async_support/base/__init__.py,sha256=aVYSsFi--b4InRs9zDN_wtCpj8odosAB726JdUHavrk,67
325
- ccxt/async_support/base/exchange.py,sha256=1eJMXCvOOMw7mesoFJKq5n3LqvX-wJS2q4oqBF0kpyg,145348
325
+ ccxt/async_support/base/exchange.py,sha256=neYp3LeA_QEaKIzo376jotRLsg-0UGLDLi2HB7tfxws,145510
326
326
  ccxt/async_support/base/throttler.py,sha256=tvDVcdRUVYi8fZRlEcnqtgzcgB_KMUMRs5Pu8tuU-tU,1847
327
327
  ccxt/async_support/base/ws/__init__.py,sha256=uockzpLuwntKGZbs5EOWFe-Zg-k6Cj7GhNJLc_RX0so,1791
328
328
  ccxt/async_support/base/ws/aiohttp_client.py,sha256=3YtsI6nV2ViYIZB7sGaowpoiF9Xaf93gHXH98253mJQ,5011
@@ -336,10 +336,10 @@ ccxt/async_support/base/ws/order_book_side.py,sha256=GH-475Ni0mLOx7mUDnz4jjzaGkh
336
336
  ccxt/base/__init__.py,sha256=eTx1OE3HJjspFUQjGm6LBhaQiMKJnXjkdP-JUXknyQ0,1320
337
337
  ccxt/base/decimal_to_precision.py,sha256=fgWRBzRTtsf3r2INyS4f7WHlzgjB5YM1ekiwqD21aac,6634
338
338
  ccxt/base/errors.py,sha256=2KC_p5UunRhrgPfEEHtE-II2buIPqKJUjQZHiIdAhog,3523
339
- ccxt/base/exchange.py,sha256=wGeWbLHTALnTo6fU-WwmuL7q8Y8wJ2YhmSI9GGhH618,185174
339
+ ccxt/base/exchange.py,sha256=EuHPL5E1FzFrweoIY2rxKeIucUUWVIPhr774Fm3wQj8,185336
340
340
  ccxt/base/precise.py,sha256=_xfu54sV0vWNnOfGTKRFykeuWP8mn4K1m9lk1tcllX4,8565
341
341
  ccxt/base/types.py,sha256=NQMNi7eE7XvF3LzOLkYflWL_4etzbGQgSCdp1hm0sD4,2109
342
- ccxt/pro/__init__.py,sha256=JfOx9btMPUs83jbGrbq8_8QnU6PnVwtJDLrWJ5tHt3Q,6480
342
+ ccxt/pro/__init__.py,sha256=3Gxpi905K0RMQVafxJ8nzB18hwNga257HMaK0RdgdM4,6480
343
343
  ccxt/pro/alpaca.py,sha256=OO5fBSjG89OmlSY_6gy20BCs3hJMF8kWkeHtxM-JaTY,26762
344
344
  ccxt/pro/ascendex.py,sha256=KrTNXPurOm4EySkSV8pIg8CcQ2BBFyPZ15Hbce6HSSQ,34569
345
345
  ccxt/pro/bequant.py,sha256=3IeQ0vPg-eVqPiGMfX7yqH9qtXKm1ZqocQDeLwpA8EE,1093
@@ -391,7 +391,7 @@ ccxt/pro/mexc3.py,sha256=SFCoEPWnmrD-DKTYEhEicld2aTX6s8SZHxTWeCdozwI,388
391
391
  ccxt/pro/ndax.py,sha256=Iq9alo8njEmYSI8WMmicut2eLPsHBPG82YYLi-iNbZw,22682
392
392
  ccxt/pro/okcoin.py,sha256=G-JrfC50gcLYHj99oYnJPY7RZl5_JtFY7yWiB2zpIUA,30265
393
393
  ccxt/pro/okex.py,sha256=mKJJEfmOzmt31KyDIPVRuAqV_mL280pc2mbRz5h2oOg,382
394
- ccxt/pro/okx.py,sha256=cwmVTDqUITJJNd_MGWAwYyB52hk2z8l8OIfEsfG6Hx4,56056
394
+ ccxt/pro/okx.py,sha256=J2iZgA93ZFeRzk-iyDirzTew9hYq7WN3__Wd4GXkrgI,56228
395
395
  ccxt/pro/phemex.py,sha256=bfKMh4hzMeT2Q6DbpzqWaLv-Oc2F6eK52HBNTM5bzzs,59923
396
396
  ccxt/pro/poloniex.py,sha256=K3zW2c8jGIK_SkC4lxaSwvVqL3iqiMyoQS-057SzlhE,41682
397
397
  ccxt/pro/poloniexfutures.py,sha256=abjDkiqaKvBChcDSZ_wKbW4fJyERmtHqhnfbdZLhcOs,40313
@@ -416,8 +416,8 @@ ccxt/static_dependencies/ecdsa/util.py,sha256=M0NQZ4dDQFTd8afSkF-7YyP9KbsXzOn-VU
416
416
  ccxt/static_dependencies/keccak/__init__.py,sha256=mfcrTChnMXsr-JmfN2VbzscTRt9XA2RRGchfHRMYncU,45
417
417
  ccxt/static_dependencies/keccak/keccak.py,sha256=RblmQEQkGpMhug0EU3hyE0kBjs1NDfGQqbwrBK7ZycY,6934
418
418
  ccxt/test/__init__.py,sha256=GKPbEcj0Rrz5HG-GUm-iY1IHhDYmlvcBXZAGk6-m2CI,141
419
- ccxt/test/test_async.py,sha256=k2flTOfMCRLDhkf8y7EKCqAxc0fFDF_QFE8HeaOUwf4,28890
420
- ccxt/test/test_sync.py,sha256=MS9V98uZ7fyABIF195r5GEqTlW9h0iuieUARJWHswYA,28462
419
+ ccxt/test/test_async.py,sha256=K0VGNmJt6JlQ7W3qJABZjl45i5s0TssUs6AzFqfFAYk,29465
420
+ ccxt/test/test_sync.py,sha256=ZfB8YQMKrNENy6AQhLvXX1VrMGysH1Q9oyek2JrdOCM,29037
421
421
  ccxt/test/base/__init__.py,sha256=hQPmjR9gxzFFd-nZRo-ICCD89Yk4hoQjQSnEKGHvhVM,1745
422
422
  ccxt/test/base/test_account.py,sha256=aPhLDxPTaK51x-a72mmjXHNPnrk8NvOGqJju2fzATfA,980
423
423
  ccxt/test/base/test_balance.py,sha256=Zp9CsDjWIblbf7R5KH6FKT6yw5zuy3AeEVWjS0xy_2o,2617
@@ -450,7 +450,7 @@ ccxt/test/base/test_ticker.py,sha256=h9AV_O6s-Ax3vB3sFoN0Mz22rMOi65i9BDv0SNejH98
450
450
  ccxt/test/base/test_trade.py,sha256=rOEbyHLvsB-rh7X7WOcfeOV_3MOGq_0s4ovg2SRk-2I,2284
451
451
  ccxt/test/base/test_trading_fee.py,sha256=2_WCp3qJ2UpraQQoGFlGJYwHD-T0Bm5W7KIw4zpFvSM,1068
452
452
  ccxt/test/base/test_transaction.py,sha256=BTbB4UHHXkrvYgwbrhh867nVRlevmIkIrz1W_odlQJI,1434
453
- ccxt-4.0.76.dist-info/METADATA,sha256=-YXtJ638jZ77nWIafeMntFtClUll8gA-QqeUMcTYy-g,110642
454
- ccxt-4.0.76.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
455
- ccxt-4.0.76.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
456
- ccxt-4.0.76.dist-info/RECORD,,
453
+ ccxt-4.0.78.dist-info/METADATA,sha256=79gnYY2_xRNHgZpXCXrGbZBPK6Af0DoqY0NTnc71I4g,110642
454
+ ccxt-4.0.78.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
455
+ ccxt-4.0.78.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
456
+ ccxt-4.0.78.dist-info/RECORD,,
File without changes