ccxt 4.4.1__py2.py3-none-any.whl → 4.4.3__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.
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.1'
7
+ __version__ = '4.4.3'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -24,6 +24,7 @@ from ccxt.base.errors import RateLimitExceeded
24
24
  from ccxt.base.errors import BadRequest
25
25
  from ccxt.base.errors import BadResponse
26
26
  from ccxt.base.errors import InvalidProxySettings
27
+ from ccxt.base.errors import UnsubscribeError
27
28
 
28
29
  # -----------------------------------------------------------------------------
29
30
 
@@ -2798,6 +2799,10 @@ class Exchange(object):
2798
2799
  'max': None,
2799
2800
  },
2800
2801
  },
2802
+ 'marginModes': {
2803
+ 'cross': None,
2804
+ 'isolated': None,
2805
+ },
2801
2806
  'created': None,
2802
2807
  'info': None,
2803
2808
  }
@@ -6261,3 +6266,50 @@ class Exchange(object):
6261
6266
  :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
6262
6267
  """
6263
6268
  raise NotSupported(self.id + ' fetchTransfers() is not supported yet')
6269
+
6270
+ def clean_unsubscription(self, client, subHash: str, unsubHash: str):
6271
+ if unsubHash in client.subscriptions:
6272
+ del client.subscriptions[unsubHash]
6273
+ if subHash in client.subscriptions:
6274
+ del client.subscriptions[subHash]
6275
+ if subHash in client.futures:
6276
+ error = UnsubscribeError(self.id + ' ' + subHash)
6277
+ client.reject(error, subHash)
6278
+ client.resolve(True, unsubHash)
6279
+
6280
+ def clean_cache(self, subscription: dict):
6281
+ topic = self.safe_string(subscription, 'topic')
6282
+ symbols = self.safe_list(subscription, 'symbols', [])
6283
+ symbolsLength = len(symbols)
6284
+ if topic == 'ohlcv':
6285
+ symbolsAndTimeFrames = self.safe_list(subscription, 'symbolsAndTimeframes', [])
6286
+ for i in range(0, len(symbolsAndTimeFrames)):
6287
+ symbolAndTimeFrame = symbolsAndTimeFrames[i]
6288
+ symbol = self.safe_string(symbolAndTimeFrame, 0)
6289
+ timeframe = self.safe_string(symbolAndTimeFrame, 1)
6290
+ if timeframe in self.ohlcvs[symbol]:
6291
+ del self.ohlcvs[symbol][timeframe]
6292
+ elif symbolsLength > 0:
6293
+ for i in range(0, len(symbols)):
6294
+ symbol = symbols[i]
6295
+ if topic == 'trades':
6296
+ del self.trades[symbol]
6297
+ elif topic == 'orderbook':
6298
+ del self.orderbooks[symbol]
6299
+ elif topic == 'ticker':
6300
+ del self.tickers[symbol]
6301
+ else:
6302
+ if topic == 'myTrades':
6303
+ # don't reset self.myTrades directly here
6304
+ # because in c# we need to use a different object
6305
+ keys = list(self.myTrades.keys())
6306
+ for i in range(0, len(keys)):
6307
+ del self.myTrades[keys[i]]
6308
+ elif topic == 'orders':
6309
+ orderSymbols = list(self.orders.keys())
6310
+ for i in range(0, len(orderSymbols)):
6311
+ del self.orders[orderSymbols[i]]
6312
+ elif topic == 'ticker':
6313
+ tickerSymbols = list(self.tickers.keys())
6314
+ for i in range(0, len(tickerSymbols)):
6315
+ del self.tickers[tickerSymbols[i]]
ccxt/base/types.py CHANGED
@@ -354,7 +354,7 @@ class Option(TypedDict):
354
354
 
355
355
  OptionChain = Dict[str, Option]
356
356
 
357
- class MarketMarginMode(TypedDict):
357
+ class MarketMarginModes(TypedDict):
358
358
  cross: bool
359
359
  isolated: bool
360
360
 
@@ -371,7 +371,7 @@ class MarketInterface(TypedDict):
371
371
  subType: Str
372
372
  spot: bool
373
373
  margin: bool
374
- marginMode: MarketMarginMode
374
+ marginModes: MarketMarginModes
375
375
  swap: bool
376
376
  future: bool
377
377
  option: bool
ccxt/binance.py CHANGED
@@ -2633,6 +2633,7 @@ class binance(Exchange, ImplicitAPI):
2633
2633
  """
2634
2634
  fetches all available currencies on an exchange
2635
2635
  :see: https://developers.binance.com/docs/wallet/capital/all-coins-info
2636
+ :see: https://developers.binance.com/docs/margin_trading/market-data/Get-All-Margin-Assets
2636
2637
  :param dict [params]: extra parameters specific to the exchange API endpoint
2637
2638
  :returns dict: an associative dictionary of currencies
2638
2639
  """
@@ -2649,9 +2650,13 @@ class binance(Exchange, ImplicitAPI):
2649
2650
  apiBackup = self.safe_value(self.urls, 'apiBackup')
2650
2651
  if apiBackup is not None:
2651
2652
  return None
2652
- response = self.sapiGetCapitalConfigGetall(params)
2653
+ promises = [self.sapiGetCapitalConfigGetall(params), self.sapiGetMarginAllAssets(params)]
2654
+ results = promises
2655
+ responseCurrencies = results[0]
2656
+ responseMarginables = results[1]
2657
+ marginablesById = self.index_by(responseMarginables, 'assetName')
2653
2658
  result: dict = {}
2654
- for i in range(0, len(response)):
2659
+ for i in range(0, len(responseCurrencies)):
2655
2660
  #
2656
2661
  # {
2657
2662
  # "coin": "LINK",
@@ -2747,7 +2752,7 @@ class binance(Exchange, ImplicitAPI):
2747
2752
  # ]
2748
2753
  # }
2749
2754
  #
2750
- entry = response[i]
2755
+ entry = responseCurrencies[i]
2751
2756
  id = self.safe_string(entry, 'coin')
2752
2757
  name = self.safe_string(entry, 'name')
2753
2758
  code = self.safe_currency_code(id)
@@ -2799,6 +2804,17 @@ class binance(Exchange, ImplicitAPI):
2799
2804
  }
2800
2805
  trading = self.safe_bool(entry, 'trading')
2801
2806
  active = (isWithdrawEnabled and isDepositEnabled and trading)
2807
+ marginEntry = self.safe_dict(marginablesById, id, {})
2808
+ #
2809
+ # {
2810
+ # assetName: "BTC",
2811
+ # assetFullName: "Bitcoin",
2812
+ # isBorrowable: True,
2813
+ # isMortgageable: True,
2814
+ # userMinBorrow: "0",
2815
+ # userMinRepay: "0",
2816
+ # }
2817
+ #
2802
2818
  result[code] = {
2803
2819
  'id': id,
2804
2820
  'name': name,
@@ -2812,6 +2828,7 @@ class binance(Exchange, ImplicitAPI):
2812
2828
  'fee': fee,
2813
2829
  'fees': fees,
2814
2830
  'limits': self.limits,
2831
+ 'margin': self.safe_bool(marginEntry, 'isBorrowable'),
2815
2832
  }
2816
2833
  return result
2817
2834
 
@@ -2822,6 +2839,8 @@ class binance(Exchange, ImplicitAPI):
2822
2839
  :see: https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Exchange-Information # swap
2823
2840
  :see: https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/Exchange-Information # future
2824
2841
  :see: https://developers.binance.com/docs/derivatives/option/market-data/Exchange-Information # option
2842
+ :see: https://developers.binance.com/docs/margin_trading/market-data/Get-All-Cross-Margin-Pairs # cross margin
2843
+ :see: https://developers.binance.com/docs/margin_trading/market-data/Get-All-Isolated-Margin-Symbol # isolated margin
2825
2844
  :param dict [params]: extra parameters specific to the exchange API endpoint
2826
2845
  :returns dict[]: an array of objects representing market data
2827
2846
  """
@@ -2834,10 +2853,15 @@ class binance(Exchange, ImplicitAPI):
2834
2853
  if type == 'option' and sandboxMode:
2835
2854
  continue
2836
2855
  fetchMarkets.append(type)
2856
+ fetchMargins = False
2837
2857
  for i in range(0, len(fetchMarkets)):
2838
2858
  marketType = fetchMarkets[i]
2839
2859
  if marketType == 'spot':
2840
2860
  promisesRaw.append(self.publicGetExchangeInfo(params))
2861
+ if self.check_required_credentials(False) and not sandboxMode:
2862
+ fetchMargins = True
2863
+ promisesRaw.append(self.sapiGetMarginAllPairs(params))
2864
+ promisesRaw.append(self.sapiGetMarginIsolatedAllPairs(params))
2841
2865
  elif marketType == 'linear':
2842
2866
  promisesRaw.append(self.fapiPublicGetExchangeInfo(params))
2843
2867
  elif marketType == 'inverse':
@@ -2846,12 +2870,23 @@ class binance(Exchange, ImplicitAPI):
2846
2870
  promisesRaw.append(self.eapiPublicGetExchangeInfo(params))
2847
2871
  else:
2848
2872
  raise ExchangeError(self.id + ' fetchMarkets() self.options fetchMarkets "' + marketType + '" is not a supported market type')
2849
- promises = promisesRaw
2873
+ results = promisesRaw
2850
2874
  markets = []
2851
- for i in range(0, len(fetchMarkets)):
2852
- promise = self.safe_dict(promises, i)
2853
- promiseMarkets = self.safe_list_2(promise, 'symbols', 'optionSymbols', [])
2854
- markets = self.array_concat(markets, promiseMarkets)
2875
+ self.options['crossMarginPairsData'] = []
2876
+ self.options['isolatedMarginPairsData'] = []
2877
+ for i in range(0, len(results)):
2878
+ res = self.safe_value(results, i)
2879
+ if fetchMargins and isinstance(res, list):
2880
+ keysList = list(self.index_by(res, 'symbol').keys())
2881
+ length = (self.options['crossMarginPairsData'])
2882
+ # first one is the cross-margin promise
2883
+ if length == 0:
2884
+ self.options['crossMarginPairsData'] = keysList
2885
+ else:
2886
+ self.options['isolatedMarginPairsData'] = keysList
2887
+ else:
2888
+ resultMarkets = self.safe_list_2(res, 'symbols', 'optionSymbols', [])
2889
+ markets = self.array_concat(markets, resultMarkets)
2855
2890
  #
2856
2891
  # spot / margin
2857
2892
  #
@@ -2896,6 +2931,20 @@ class binance(Exchange, ImplicitAPI):
2896
2931
  # ],
2897
2932
  # }
2898
2933
  #
2934
+ # cross & isolated pairs response:
2935
+ #
2936
+ # [
2937
+ # {
2938
+ # symbol: "BTCUSDT",
2939
+ # base: "BTC",
2940
+ # quote: "USDT",
2941
+ # isMarginTrade: True,
2942
+ # isBuyAllowed: True,
2943
+ # isSellAllowed: True,
2944
+ # id: "376870555451677893", # doesn't exist in isolated
2945
+ # },
2946
+ # ]
2947
+ #
2899
2948
  # futures/usdt-margined(fapi)
2900
2949
  #
2901
2950
  # {
@@ -3118,6 +3167,19 @@ class binance(Exchange, ImplicitAPI):
3118
3167
  active = False
3119
3168
  break
3120
3169
  isMarginTradingAllowed = self.safe_bool(market, 'isMarginTradingAllowed', False)
3170
+ marginModes = None
3171
+ if spot:
3172
+ hasCrossMargin = self.in_array(id, self.options['crossMarginPairsData'])
3173
+ hasIsolatedMargin = self.in_array(id, self.options['isolatedMarginPairsData'])
3174
+ marginModes = {
3175
+ 'cross': hasCrossMargin,
3176
+ 'isolated': hasIsolatedMargin,
3177
+ }
3178
+ elif linear or inverse:
3179
+ marginModes = {
3180
+ 'cross': True,
3181
+ 'isolated': True,
3182
+ }
3121
3183
  unifiedType = None
3122
3184
  if spot:
3123
3185
  unifiedType = 'spot'
@@ -3144,6 +3206,7 @@ class binance(Exchange, ImplicitAPI):
3144
3206
  'type': unifiedType,
3145
3207
  'spot': spot,
3146
3208
  'margin': spot and isMarginTradingAllowed,
3209
+ 'marginModes': marginModes,
3147
3210
  'swap': swap,
3148
3211
  'future': future,
3149
3212
  'option': option,
@@ -5969,8 +6032,8 @@ class binance(Exchange, ImplicitAPI):
5969
6032
  marginMode, params = self.handle_margin_mode_and_params('fetchOrders', params)
5970
6033
  isPortfolioMargin = None
5971
6034
  isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchOrders', 'papi', 'portfolioMargin', False)
5972
- isConditional = self.safe_bool_2(params, 'stop', 'conditional')
5973
- params = self.omit(params, ['stop', 'conditional', 'type'])
6035
+ isConditional = self.safe_bool_n(params, ['stop', 'trigger', 'conditional'])
6036
+ params = self.omit(params, ['stop', 'trigger', 'conditional', 'type'])
5974
6037
  request: dict = {
5975
6038
  'symbol': market['id'],
5976
6039
  }
@@ -6219,7 +6282,7 @@ class binance(Exchange, ImplicitAPI):
6219
6282
  marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrders', params)
6220
6283
  isPortfolioMargin = None
6221
6284
  isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchOpenOrders', 'papi', 'portfolioMargin', False)
6222
- isConditional = self.safe_bool_n(params, ['stop', 'conditional', 'trigger'])
6285
+ isConditional = self.safe_bool_n(params, ['stop', 'trigger', 'conditional'])
6223
6286
  if symbol is not None:
6224
6287
  market = self.market(symbol)
6225
6288
  request['symbol'] = market['id']
@@ -6233,7 +6296,7 @@ class binance(Exchange, ImplicitAPI):
6233
6296
  type = self.safe_string(params, 'type', defaultType)
6234
6297
  subType = None
6235
6298
  subType, params = self.handle_sub_type_and_params('fetchOpenOrders', market, params)
6236
- params = self.omit(params, ['type', 'stop', 'conditional', 'trigger'])
6299
+ params = self.omit(params, ['type', 'stop', 'trigger', 'conditional'])
6237
6300
  response = None
6238
6301
  if type == 'option':
6239
6302
  if since is not None:
@@ -6294,8 +6357,8 @@ class binance(Exchange, ImplicitAPI):
6294
6357
  }
6295
6358
  isPortfolioMargin = None
6296
6359
  isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchOpenOrder', 'papi', 'portfolioMargin', False)
6297
- isConditional = self.safe_bool_n(params, ['stop', 'conditional', 'trigger'])
6298
- params = self.omit(params, ['stop', 'conditional', 'trigger'])
6360
+ isConditional = self.safe_bool_n(params, ['stop', 'trigger', 'conditional'])
6361
+ params = self.omit(params, ['stop', 'trigger', 'conditional'])
6299
6362
  isPortfolioMarginConditional = (isPortfolioMargin and isConditional)
6300
6363
  orderIdRequest = 'strategyId' if isPortfolioMarginConditional else 'orderId'
6301
6364
  request[orderIdRequest] = id
@@ -6585,7 +6648,7 @@ class binance(Exchange, ImplicitAPI):
6585
6648
  marginMode, params = self.handle_margin_mode_and_params('cancelOrder', params)
6586
6649
  isPortfolioMargin = None
6587
6650
  isPortfolioMargin, params = self.handle_option_and_params_2(params, 'cancelOrder', 'papi', 'portfolioMargin', False)
6588
- isConditional = self.safe_bool_2(params, 'stop', 'conditional')
6651
+ isConditional = self.safe_bool_n(params, ['stop', 'trigger', 'conditional'])
6589
6652
  request: dict = {
6590
6653
  'symbol': market['id'],
6591
6654
  }
@@ -6603,7 +6666,7 @@ class binance(Exchange, ImplicitAPI):
6603
6666
  request['strategyId'] = id
6604
6667
  else:
6605
6668
  request['orderId'] = id
6606
- params = self.omit(params, ['type', 'origClientOrderId', 'clientOrderId', 'newClientStrategyId', 'stop', 'conditional'])
6669
+ params = self.omit(params, ['type', 'origClientOrderId', 'clientOrderId', 'newClientStrategyId', 'stop', 'trigger', 'conditional'])
6607
6670
  response = None
6608
6671
  if market['option']:
6609
6672
  response = self.eapiPrivateDeleteOrder(self.extend(request, params))
@@ -6662,9 +6725,9 @@ class binance(Exchange, ImplicitAPI):
6662
6725
  }
6663
6726
  isPortfolioMargin = None
6664
6727
  isPortfolioMargin, params = self.handle_option_and_params_2(params, 'cancelAllOrders', 'papi', 'portfolioMargin', False)
6665
- isConditional = self.safe_bool_2(params, 'stop', 'conditional')
6728
+ isConditional = self.safe_bool_n(params, ['stop', 'trigger', 'conditional'])
6666
6729
  type = self.safe_string(params, 'type', market['type'])
6667
- params = self.omit(params, ['type', 'stop', 'conditional'])
6730
+ params = self.omit(params, ['type', 'stop', 'trigger', 'conditional'])
6668
6731
  marginMode = None
6669
6732
  marginMode, params = self.handle_margin_mode_and_params('cancelAllOrders', params)
6670
6733
  response = None
ccxt/bitmart.py CHANGED
@@ -248,6 +248,7 @@ class bitmart(Exchange, ImplicitAPI):
248
248
  'spot/v4/query/trades': 5, # 12 times/2 sec = 6/s => 30/6 = 5
249
249
  'spot/v4/query/order-trades': 5, # 12 times/2 sec = 6/s => 30/6 = 5
250
250
  'spot/v4/cancel_orders': 3,
251
+ 'spot/v4/cancel_all': 90,
251
252
  'spot/v4/batch_orders': 3,
252
253
  # newer endpoint
253
254
  'spot/v3/cancel_order': 1,
@@ -2789,6 +2790,7 @@ class bitmart(Exchange, ImplicitAPI):
2789
2790
  """
2790
2791
  cancel all open orders in a market
2791
2792
  :see: https://developer-pro.bitmart.com/en/spot/#cancel-all-orders
2793
+ :see: https://developer-pro.bitmart.com/en/spot/#new-batch-order-v4-signed
2792
2794
  :see: https://developer-pro.bitmart.com/en/futures/#cancel-all-orders-signed
2793
2795
  :see: https://developer-pro.bitmart.com/en/futuresv2/#cancel-all-orders-signed
2794
2796
  :param str symbol: unified market symbol of the market to cancel orders in
@@ -2806,7 +2808,7 @@ class bitmart(Exchange, ImplicitAPI):
2806
2808
  type = None
2807
2809
  type, params = self.handle_market_type_and_params('cancelAllOrders', market, params)
2808
2810
  if type == 'spot':
2809
- response = self.privatePostSpotV1CancelOrders(self.extend(request, params))
2811
+ response = self.privatePostSpotV4CancelAll(self.extend(request, params))
2810
2812
  elif type == 'swap':
2811
2813
  if symbol is None:
2812
2814
  raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
ccxt/bitstamp.py CHANGED
@@ -402,46 +402,34 @@ class bitstamp(Exchange, ImplicitAPI):
402
402
  'trading': {
403
403
  'tierBased': True,
404
404
  'percentage': True,
405
- 'taker': self.parse_number('0.005'),
406
- 'maker': self.parse_number('0.005'),
405
+ 'taker': self.parse_number('0.004'),
406
+ 'maker': self.parse_number('0.004'),
407
407
  'tiers': {
408
408
  'taker': [
409
- [self.parse_number('0'), self.parse_number('0.005')],
410
- [self.parse_number('20000'), self.parse_number('0.0025')],
411
- [self.parse_number('100000'), self.parse_number('0.0024')],
412
- [self.parse_number('200000'), self.parse_number('0.0022')],
413
- [self.parse_number('400000'), self.parse_number('0.0020')],
414
- [self.parse_number('600000'), self.parse_number('0.0015')],
415
- [self.parse_number('1000000'), self.parse_number('0.0014')],
416
- [self.parse_number('2000000'), self.parse_number('0.0013')],
417
- [self.parse_number('4000000'), self.parse_number('0.0012')],
418
- [self.parse_number('20000000'), self.parse_number('0.0011')],
419
- [self.parse_number('50000000'), self.parse_number('0.0010')],
420
- [self.parse_number('100000000'), self.parse_number('0.0007')],
421
- [self.parse_number('500000000'), self.parse_number('0.0005')],
422
- [self.parse_number('2000000000'), self.parse_number('0.0003')],
423
- [self.parse_number('6000000000'), self.parse_number('0.0001')],
424
- [self.parse_number('20000000000'), self.parse_number('0.00005')],
425
- [self.parse_number('20000000001'), self.parse_number('0')],
409
+ [self.parse_number('0'), self.parse_number('0.004')],
410
+ [self.parse_number('10000'), self.parse_number('0.003')],
411
+ [self.parse_number('100000'), self.parse_number('0.002')],
412
+ [self.parse_number('500000'), self.parse_number('0.0018')],
413
+ [self.parse_number('1500000'), self.parse_number('0.0016')],
414
+ [self.parse_number('5000000'), self.parse_number('0.0012')],
415
+ [self.parse_number('20000000'), self.parse_number('0.001')],
416
+ [self.parse_number('50000000'), self.parse_number('0.0008')],
417
+ [self.parse_number('100000000'), self.parse_number('0.0006')],
418
+ [self.parse_number('250000000'), self.parse_number('0.0005')],
419
+ [self.parse_number('1000000000'), self.parse_number('0.0003')],
426
420
  ],
427
421
  'maker': [
428
- [self.parse_number('0'), self.parse_number('0.005')],
429
- [self.parse_number('20000'), self.parse_number('0.0025')],
430
- [self.parse_number('100000'), self.parse_number('0.0024')],
431
- [self.parse_number('200000'), self.parse_number('0.0022')],
432
- [self.parse_number('400000'), self.parse_number('0.0020')],
433
- [self.parse_number('600000'), self.parse_number('0.0015')],
434
- [self.parse_number('1000000'), self.parse_number('0.0014')],
435
- [self.parse_number('2000000'), self.parse_number('0.0013')],
436
- [self.parse_number('4000000'), self.parse_number('0.0012')],
437
- [self.parse_number('20000000'), self.parse_number('0.0011')],
438
- [self.parse_number('50000000'), self.parse_number('0.0010')],
439
- [self.parse_number('100000000'), self.parse_number('0.0007')],
440
- [self.parse_number('500000000'), self.parse_number('0.0005')],
441
- [self.parse_number('2000000000'), self.parse_number('0.0003')],
442
- [self.parse_number('6000000000'), self.parse_number('0.0001')],
443
- [self.parse_number('20000000000'), self.parse_number('0.00005')],
444
- [self.parse_number('20000000001'), self.parse_number('0')],
422
+ [self.parse_number('0'), self.parse_number('0.003')],
423
+ [self.parse_number('10000'), self.parse_number('0.002')],
424
+ [self.parse_number('100000'), self.parse_number('0.001')],
425
+ [self.parse_number('500000'), self.parse_number('0.0008')],
426
+ [self.parse_number('1500000'), self.parse_number('0.0006')],
427
+ [self.parse_number('5000000'), self.parse_number('0.0003')],
428
+ [self.parse_number('20000000'), self.parse_number('0.002')],
429
+ [self.parse_number('50000000'), self.parse_number('0.0001')],
430
+ [self.parse_number('100000000'), self.parse_number('0')],
431
+ [self.parse_number('250000000'), self.parse_number('0')],
432
+ [self.parse_number('1000000000'), self.parse_number('0')],
445
433
  ],
446
434
  },
447
435
  },
ccxt/bybit.py CHANGED
@@ -13,6 +13,7 @@ from ccxt.base.errors import AuthenticationError
13
13
  from ccxt.base.errors import PermissionDenied
14
14
  from ccxt.base.errors import ArgumentsRequired
15
15
  from ccxt.base.errors import BadRequest
16
+ from ccxt.base.errors import BadSymbol
16
17
  from ccxt.base.errors import NoChange
17
18
  from ccxt.base.errors import MarginModeAlreadySet
18
19
  from ccxt.base.errors import ManualInteractionNeeded
@@ -991,6 +992,7 @@ class bybit(Exchange, ImplicitAPI):
991
992
  '3200300': InsufficientFunds, # {"retCode":3200300,"retMsg":"Insufficient margin balance.","result":null,"retExtMap":{}}
992
993
  },
993
994
  'broad': {
995
+ 'Not supported symbols': BadSymbol, # {"retCode":10001,"retMsg":"Not supported symbols","result":{},"retExtInfo":{},"time":1726147060461}
994
996
  'Request timeout': RequestTimeout, # {"retCode":10016,"retMsg":"Request timeout, please try again later","result":{},"retExtInfo":{},"time":1675307914985}
995
997
  'unknown orderInfo': OrderNotFound, # {"ret_code":-1,"ret_msg":"unknown orderInfo","ext_code":"","ext_info":"","result":null,"time_now":"1584030414.005545","rate_limit_status":99,"rate_limit_reset_ms":1584030414003,"rate_limit":100}
996
998
  'invalid api_key': AuthenticationError, # {"ret_code":10003,"ret_msg":"invalid api_key","ext_code":"","ext_info":"","result":null,"time_now":"1599547085.415797"}
ccxt/cryptocom.py CHANGED
@@ -156,7 +156,7 @@ class cryptocom(Exchange, ImplicitAPI):
156
156
  'www': 'https://crypto.com/',
157
157
  'referral': {
158
158
  'url': 'https://crypto.com/exch/kdacthrnxt',
159
- 'discount': 0.15,
159
+ 'discount': 0.75,
160
160
  },
161
161
  'doc': [
162
162
  'https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html',
@@ -611,7 +611,7 @@ class cryptocom(Exchange, ImplicitAPI):
611
611
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
612
612
  """
613
613
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
614
- :see: https://exchange-docs.crypto.com/spot/index.html#public-get-ticker
614
+ :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#public-get-tickers
615
615
  :see: https://exchange-docs.crypto.com/derivatives/index.html#public-get-tickers
616
616
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
617
617
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1660,6 +1660,7 @@ class cryptocom(Exchange, ImplicitAPI):
1660
1660
  def fetch_deposit_address(self, code: str, params={}):
1661
1661
  """
1662
1662
  fetch the deposit address for a currency associated with self account
1663
+ :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-get-deposit-address
1663
1664
  :param str code: unified currency code
1664
1665
  :param dict [params]: extra parameters specific to the exchange API endpoint
1665
1666
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
ccxt/currencycom.py CHANGED
@@ -1902,7 +1902,7 @@ class currencycom(Exchange, ImplicitAPI):
1902
1902
  'collateral': None,
1903
1903
  'side': side,
1904
1904
  # 'realizedProfit': self.safe_number(position, 'rpl'),
1905
- 'unrealizedProfit': unrealizedProfit,
1905
+ 'unrealizedPnl': unrealizedProfit,
1906
1906
  'leverage': leverage,
1907
1907
  'percentage': None,
1908
1908
  'marginMode': None,
@@ -1916,7 +1916,6 @@ class currencycom(Exchange, ImplicitAPI):
1916
1916
  'maintenanceMarginPercentage': None,
1917
1917
  'marginRatio': None,
1918
1918
  'id': None,
1919
- 'unrealizedPnl': None,
1920
1919
  'hedged': None,
1921
1920
  'stopLossPrice': None,
1922
1921
  'takeProfitPrice': None,
ccxt/htx.py CHANGED
@@ -6978,7 +6978,7 @@ class htx(Exchange, ImplicitAPI):
6978
6978
  'entryPrice': entryPrice,
6979
6979
  'collateral': self.parse_number(collateral),
6980
6980
  'side': side,
6981
- 'unrealizedProfit': unrealizedProfit,
6981
+ 'unrealizedPnl': unrealizedProfit,
6982
6982
  'leverage': self.parse_number(leverage),
6983
6983
  'percentage': self.parse_number(percentage),
6984
6984
  'marginMode': marginMode,
ccxt/mexc.py CHANGED
@@ -1012,6 +1012,13 @@ class mexc(Exchange, ImplicitAPI):
1012
1012
  return self.array_concat(spotMarket, swapMarket)
1013
1013
 
1014
1014
  def fetch_spot_markets(self, params={}):
1015
+ """
1016
+ * @ignore
1017
+ retrieves data on all spot markets for mexc
1018
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#exchange-information
1019
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1020
+ :returns dict[]: an array of objects representing market data
1021
+ """
1015
1022
  response = self.spotPublicGetExchangeInfo(params)
1016
1023
  #
1017
1024
  # {
@@ -1127,6 +1134,13 @@ class mexc(Exchange, ImplicitAPI):
1127
1134
  return result
1128
1135
 
1129
1136
  def fetch_swap_markets(self, params={}):
1137
+ """
1138
+ * @ignore
1139
+ retrieves data on all swap markets for mexc
1140
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-the-contract-information
1141
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1142
+ :returns dict[]: an array of objects representing market data
1143
+ """
1130
1144
  response = self.contractPublicGetDetail(params)
1131
1145
  #
1132
1146
  # {
@@ -1666,6 +1680,8 @@ class mexc(Exchange, ImplicitAPI):
1666
1680
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1667
1681
  """
1668
1682
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1683
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#24hr-ticker-price-change-statistics
1684
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-trend-data
1669
1685
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1670
1686
  :param dict [params]: extra parameters specific to the exchange API endpoint
1671
1687
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1747,6 +1763,8 @@ class mexc(Exchange, ImplicitAPI):
1747
1763
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1748
1764
  """
1749
1765
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1766
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#24hr-ticker-price-change-statistics
1767
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-trend-data
1750
1768
  :param str symbol: unified symbol of the market to fetch the ticker for
1751
1769
  :param dict [params]: extra parameters specific to the exchange API endpoint
1752
1770
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1929,6 +1947,7 @@ class mexc(Exchange, ImplicitAPI):
1929
1947
  def fetch_bids_asks(self, symbols: Strings = None, params={}):
1930
1948
  """
1931
1949
  fetches the bid and ask price and volume for multiple markets
1950
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#symbol-order-book-ticker
1932
1951
  :param str[]|None symbols: unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
1933
1952
  :param dict [params]: extra parameters specific to the exchange API endpoint
1934
1953
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2052,6 +2071,21 @@ class mexc(Exchange, ImplicitAPI):
2052
2071
  return self.extend(request, params)
2053
2072
 
2054
2073
  def create_spot_order(self, market, type, side, amount, price=None, marginMode=None, params={}):
2074
+ """
2075
+ * @ignore
2076
+ create a trade order
2077
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#new-order
2078
+ :param str symbol: unified symbol of the market to create an order in
2079
+ :param str type: 'market' or 'limit'
2080
+ :param str side: 'buy' or 'sell'
2081
+ :param float amount: how much of currency you want to trade in units of base currency
2082
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
2083
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2084
+ :param str [params.marginMode]: only 'isolated' is supported for spot-margin trading
2085
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
2086
+ :param bool [params.postOnly]: if True, the order will only be posted if it will be a maker order
2087
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2088
+ """
2055
2089
  self.load_markets()
2056
2090
  request = self.create_spot_order_request(market, type, side, amount, price, marginMode, params)
2057
2091
  response = self.spotPrivatePostOrder(self.extend(request, params))
@@ -2082,6 +2116,30 @@ class mexc(Exchange, ImplicitAPI):
2082
2116
  return order
2083
2117
 
2084
2118
  def create_swap_order(self, market, type, side, amount, price=None, marginMode=None, params={}):
2119
+ """
2120
+ * @ignore
2121
+ create a trade order
2122
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#new-order
2123
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#order-under-maintenance
2124
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#trigger-order-under-maintenance
2125
+ :param str symbol: unified symbol of the market to create an order in
2126
+ :param str type: 'market' or 'limit'
2127
+ :param str side: 'buy' or 'sell'
2128
+ :param float amount: how much of currency you want to trade in units of base currency
2129
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
2130
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2131
+ :param str [params.marginMode]: only 'isolated' is supported for spot-margin trading
2132
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
2133
+ :param bool [params.postOnly]: if True, the order will only be posted if it will be a maker order
2134
+ :param bool [params.reduceOnly]: indicates if self order is to reduce the size of a position
2135
+ *
2136
+ * EXCHANGE SPECIFIC PARAMETERS
2137
+ :param int [params.leverage]: leverage is necessary on isolated margin
2138
+ :param long [params.positionId]: it is recommended to hasattr(self, fill) parameter when closing a position
2139
+ :param str [params.externalOid]: external order ID
2140
+ :param int [params.positionMode]: 1:hedge, 2:one-way, default: the user's current config
2141
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2142
+ """
2085
2143
  self.load_markets()
2086
2144
  symbol = market['symbol']
2087
2145
  unavailableContracts = self.safe_value(self.options, 'unavailableContracts', {})
@@ -2230,6 +2288,8 @@ class mexc(Exchange, ImplicitAPI):
2230
2288
  def fetch_order(self, id: str, symbol: Str = None, params={}):
2231
2289
  """
2232
2290
  fetches information on an order made by the user
2291
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#query-order
2292
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#query-the-order-based-on-the-order-number
2233
2293
  :param str symbol: unified symbol of the market the order was made in
2234
2294
  :param dict [params]: extra parameters specific to the exchange API endpoint
2235
2295
  :param str [params.marginMode]: only 'isolated' is supported, for spot-margin trading
@@ -4506,7 +4566,7 @@ class mexc(Exchange, ImplicitAPI):
4506
4566
  'entryPrice': entryPrice,
4507
4567
  'collateral': None,
4508
4568
  'side': side,
4509
- 'unrealizedProfit': None,
4569
+ 'unrealizedPnl': None,
4510
4570
  'leverage': self.parse_number(leverage),
4511
4571
  'percentage': None,
4512
4572
  'marginMode': marginType,
@@ -4795,6 +4855,14 @@ class mexc(Exchange, ImplicitAPI):
4795
4855
  return self.parse_transaction(response, currency)
4796
4856
 
4797
4857
  def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
4858
+ """
4859
+ set hedged to True or False for a market
4860
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#change-position-mode
4861
+ :param bool hedged: set to True to use dualSidePosition
4862
+ :param str symbol: not used by mexc setPositionMode()
4863
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4864
+ :returns dict: response from the exchange
4865
+ """
4798
4866
  request: dict = {
4799
4867
  'positionMode': 1 if hedged else 2, # 1 Hedge, 2 One-way, before changing position mode make sure that there are no active orders, planned orders, or open positions, the risk limit level will be reset to 1
4800
4868
  }
@@ -4808,6 +4876,13 @@ class mexc(Exchange, ImplicitAPI):
4808
4876
  return response
4809
4877
 
4810
4878
  def fetch_position_mode(self, symbol: Str = None, params={}):
4879
+ """
4880
+ fetchs the position mode, hedged or one way, hedged for binance is set identically for all linear markets or all inverse markets
4881
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-position-mode
4882
+ :param str symbol: not used by mexc fetchPositionMode
4883
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4884
+ :returns dict: an object detailing whether the market is in hedged or one-way mode
4885
+ """
4811
4886
  response = self.contractPrivateGetPositionPositionMode(params)
4812
4887
  #
4813
4888
  # {