ccxt 4.4.32__py2.py3-none-any.whl → 4.4.34__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. ccxt/__init__.py +3 -1
  2. ccxt/abstract/bingx.py +16 -0
  3. ccxt/abstract/bitbank.py +5 -0
  4. ccxt/abstract/bitfinex2.py +1 -0
  5. ccxt/abstract/coinbaseexchange.py +1 -0
  6. ccxt/abstract/ellipx.py +25 -0
  7. ccxt/abstract/kraken.py +1 -0
  8. ccxt/alpaca.py +2 -0
  9. ccxt/async_support/__init__.py +3 -1
  10. ccxt/async_support/alpaca.py +2 -0
  11. ccxt/async_support/base/exchange.py +1 -1
  12. ccxt/async_support/binance.py +164 -7
  13. ccxt/async_support/bingx.py +155 -8
  14. ccxt/async_support/bitbank.py +5 -0
  15. ccxt/async_support/bitbns.py +2 -0
  16. ccxt/async_support/bitfinex2.py +1 -0
  17. ccxt/async_support/bitget.py +174 -40
  18. ccxt/async_support/bitmex.py +2 -0
  19. ccxt/async_support/bitopro.py +3 -0
  20. ccxt/async_support/bitrue.py +1 -0
  21. ccxt/async_support/btcmarkets.py +2 -0
  22. ccxt/async_support/bybit.py +143 -12
  23. ccxt/async_support/cex.py +16 -5
  24. ccxt/async_support/coinbase.py +5 -24
  25. ccxt/async_support/coinbaseexchange.py +2 -1
  26. ccxt/async_support/coinex.py +2 -0
  27. ccxt/async_support/coinone.py +7 -7
  28. ccxt/async_support/coinsph.py +7 -7
  29. ccxt/async_support/coinspot.py +39 -39
  30. ccxt/async_support/cryptocom.py +36 -34
  31. ccxt/async_support/ellipx.py +1828 -0
  32. ccxt/async_support/gate.py +1 -0
  33. ccxt/async_support/hyperliquid.py +13 -2
  34. ccxt/async_support/kraken.py +1 -0
  35. ccxt/async_support/krakenfutures.py +3 -1
  36. ccxt/async_support/kucoinfutures.py +1 -1
  37. ccxt/async_support/lbank.py +1 -0
  38. ccxt/async_support/okcoin.py +2 -0
  39. ccxt/async_support/okx.py +103 -8
  40. ccxt/async_support/onetrading.py +20 -1
  41. ccxt/async_support/paradex.py +2 -0
  42. ccxt/async_support/phemex.py +33 -6
  43. ccxt/async_support/poloniex.py +3 -1
  44. ccxt/async_support/poloniexfutures.py +3 -1
  45. ccxt/async_support/vertex.py +2 -0
  46. ccxt/async_support/woo.py +69 -69
  47. ccxt/base/exchange.py +100 -2
  48. ccxt/binance.py +164 -7
  49. ccxt/bingx.py +155 -8
  50. ccxt/bitbank.py +5 -0
  51. ccxt/bitbns.py +2 -0
  52. ccxt/bitfinex2.py +1 -0
  53. ccxt/bitget.py +174 -40
  54. ccxt/bitmex.py +2 -0
  55. ccxt/bitopro.py +3 -0
  56. ccxt/bitrue.py +1 -0
  57. ccxt/btcmarkets.py +2 -0
  58. ccxt/bybit.py +143 -12
  59. ccxt/cex.py +16 -5
  60. ccxt/coinbase.py +5 -24
  61. ccxt/coinbaseexchange.py +2 -1
  62. ccxt/coinex.py +2 -0
  63. ccxt/coinone.py +7 -7
  64. ccxt/coinsph.py +7 -7
  65. ccxt/coinspot.py +39 -39
  66. ccxt/cryptocom.py +36 -34
  67. ccxt/ellipx.py +1828 -0
  68. ccxt/gate.py +1 -0
  69. ccxt/hyperliquid.py +13 -2
  70. ccxt/kraken.py +1 -0
  71. ccxt/krakenfutures.py +3 -1
  72. ccxt/kucoinfutures.py +1 -1
  73. ccxt/lbank.py +1 -0
  74. ccxt/okcoin.py +2 -0
  75. ccxt/okx.py +103 -8
  76. ccxt/onetrading.py +20 -1
  77. ccxt/paradex.py +2 -0
  78. ccxt/phemex.py +33 -6
  79. ccxt/poloniex.py +3 -1
  80. ccxt/poloniexfutures.py +3 -1
  81. ccxt/pro/__init__.py +1 -1
  82. ccxt/pro/idex.py +15 -0
  83. ccxt/pro/okx.py +8 -0
  84. ccxt/pro/probit.py +4 -2
  85. ccxt/pro/woo.py +15 -15
  86. ccxt/test/tests_async.py +3 -1
  87. ccxt/test/tests_helpers.py +1 -3
  88. ccxt/test/tests_sync.py +3 -1
  89. ccxt/vertex.py +2 -0
  90. ccxt/woo.py +69 -69
  91. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/METADATA +9 -8
  92. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/RECORD +95 -92
  93. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/LICENSE.txt +0 -0
  94. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/WHEEL +0 -0
  95. {ccxt-4.4.32.dist-info → ccxt-4.4.34.dist-info}/top_level.txt +0 -0
ccxt/gate.py CHANGED
@@ -945,6 +945,7 @@ class gate(Exchange, ImplicitAPI):
945
945
  except Exception as e:
946
946
  # if the request fails, the unifiedAccount is disabled
947
947
  self.options['unifiedAccount'] = False
948
+ return self.options['unifiedAccount']
948
949
 
949
950
  def upgrade_unified_trade_account(self, params={}):
950
951
  return self.privateUnifiedPutUnifiedMode(params)
ccxt/hyperliquid.py CHANGED
@@ -55,6 +55,8 @@ class hyperliquid(Exchange, ImplicitAPI):
55
55
  'createOrder': True,
56
56
  'createOrders': True,
57
57
  'createReduceOnlyOrder': True,
58
+ 'createStopOrder': True,
59
+ 'createTriggerOrder': True,
58
60
  'editOrder': True,
59
61
  'fetchAccounts': False,
60
62
  'fetchBalance': True,
@@ -733,14 +735,23 @@ class hyperliquid(Exchange, ImplicitAPI):
733
735
  https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc
734
736
  https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-asset-contexts
735
737
 
736
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
738
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
737
739
  :param dict [params]: extra parameters specific to the exchange API endpoint
740
+ :param str [params.type]: 'spot' or 'swap', by default fetches both
738
741
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
739
742
  """
740
743
  self.load_markets()
741
744
  symbols = self.market_symbols(symbols)
742
745
  # at self stage, to get tickers data, we use fetchMarkets endpoints
743
- response = self.fetch_markets(params)
746
+ response = []
747
+ type = self.safe_string(params, 'type')
748
+ params = self.omit(params, 'type')
749
+ if type == 'spot':
750
+ response = self.fetch_spot_markets(params)
751
+ elif type == 'swap':
752
+ response = self.fetch_swap_markets(params)
753
+ else:
754
+ response = self.fetch_markets(params)
744
755
  # same response "fetchMarkets"
745
756
  result: dict = {}
746
757
  for i in range(0, len(response)):
ccxt/kraken.py CHANGED
@@ -197,6 +197,7 @@ class kraken(Exchange, ImplicitAPI):
197
197
  'AddOrder': 0,
198
198
  'AddOrderBatch': 0,
199
199
  'AddExport': 3,
200
+ 'AmendOrder': 0,
200
201
  'Balance': 3,
201
202
  'CancelAll': 3,
202
203
  'CancelAllOrdersAfter': 3,
ccxt/krakenfutures.py CHANGED
@@ -51,6 +51,8 @@ class krakenfutures(Exchange, ImplicitAPI):
51
51
  'cancelOrders': True,
52
52
  'createMarketOrder': False,
53
53
  'createOrder': True,
54
+ 'createStopOrder': True,
55
+ 'createTriggerOrder': True,
54
56
  'editOrder': True,
55
57
  'fetchBalance': True,
56
58
  'fetchBorrowRateHistories': False,
@@ -216,7 +218,7 @@ class krakenfutures(Exchange, ImplicitAPI):
216
218
  'invalidAmount': BadRequest,
217
219
  'insufficientFunds': InsufficientFunds,
218
220
  'Bad Request': BadRequest, # The URL contains invalid characters.(Please encode the json URL parameter)
219
- 'Unavailable': InsufficientFunds, # Insufficient funds in Futures account [withdraw]
221
+ 'Unavailable': ExchangeNotAvailable, # https://github.com/ccxt/ccxt/issues/24338
220
222
  'invalidUnit': BadRequest,
221
223
  'Json Parse Error': ExchangeError,
222
224
  'nonceBelowThreshold': InvalidNonce,
ccxt/kucoinfutures.py CHANGED
@@ -1423,7 +1423,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
1423
1423
  :param str [params.postOnly]: Post only flag, invalid when timeInForce is IOC or FOK
1424
1424
  :param float [params.cost]: the cost of the order in units of USDT
1425
1425
  ----------------- Exchange Specific Parameters -----------------
1426
- :param float [params.leverage]: Leverage size of the order
1426
+ :param float [params.leverage]: Leverage size of the order(mandatory param in request, default is 1)
1427
1427
  :param str [params.clientOid]: client order id, defaults to uuid if not passed
1428
1428
  :param str [params.remark]: remark for the order, length cannot exceed 100 utf8 characters
1429
1429
  :param str [params.stop]: 'up' or 'down', the direction the stopPrice is triggered from, requires stopPrice. down: Triggers when the price reaches or goes below the stopPrice. up: Triggers when the price reaches or goes above the stopPrice.
ccxt/lbank.py CHANGED
@@ -221,6 +221,7 @@ class lbank(Exchange, ImplicitAPI):
221
221
  },
222
222
  },
223
223
  'commonCurrencies': {
224
+ 'HIT': 'Hiver',
224
225
  'VET_ERC20': 'VEN',
225
226
  'PNT': 'Penta',
226
227
  },
ccxt/okcoin.py CHANGED
@@ -56,6 +56,8 @@ class okcoin(Exchange, ImplicitAPI):
56
56
  'createMarketOrderWithCost': False,
57
57
  'createMarketSellOrderWithCost': False,
58
58
  'createOrder': True,
59
+ 'createStopOrder': True,
60
+ 'createTriggerOrder': True,
59
61
  'fetchBalance': True,
60
62
  'fetchBorrowInterest': False,
61
63
  'fetchBorrowRate': False,
ccxt/okx.py CHANGED
@@ -1199,6 +1199,98 @@ class okx(Exchange, ImplicitAPI):
1199
1199
  },
1200
1200
  'brokerId': 'e847386590ce4dBC',
1201
1201
  },
1202
+ 'features': {
1203
+ # https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
1204
+ 'default': {
1205
+ 'sandbox': True,
1206
+ 'createOrder': {
1207
+ 'marginMode': True,
1208
+ 'triggerPrice': True,
1209
+ 'triggerPriceType': {
1210
+ 'last': True,
1211
+ 'mark': True,
1212
+ 'index': True,
1213
+ },
1214
+ 'triggerDirection': False,
1215
+ 'stopLossPrice': True,
1216
+ 'takeProfitPrice': True,
1217
+ 'attachedStopLossTakeProfit': {
1218
+ 'triggerPriceType': {
1219
+ 'last': True,
1220
+ 'mark': True,
1221
+ 'index': True,
1222
+ },
1223
+ 'limitPrice': True,
1224
+ },
1225
+ 'timeInForce': {
1226
+ 'GTC': True,
1227
+ 'IOC': True,
1228
+ 'FOK': True,
1229
+ 'PO': True,
1230
+ 'GTD': False,
1231
+ },
1232
+ 'hedged': True,
1233
+ # even though the below params not unified yet, it's useful metadata for users to know that exchange supports them
1234
+ 'selfTradePrevention': True,
1235
+ 'trailing': True,
1236
+ 'twap': True,
1237
+ 'iceberg': True,
1238
+ 'oco': True,
1239
+ },
1240
+ 'createOrders': {
1241
+ 'max': 20,
1242
+ },
1243
+ 'fetchMyTrades': {
1244
+ 'marginMode': False,
1245
+ 'daysBack': 90,
1246
+ 'limit': 100,
1247
+ 'untilDays': 10000,
1248
+ },
1249
+ 'fetchOrder': {
1250
+ 'marginMode': False,
1251
+ 'trigger': True,
1252
+ 'trailing': True,
1253
+ },
1254
+ 'fetchOpenOrders': {
1255
+ 'marginMode': False,
1256
+ 'limit': 100,
1257
+ 'trigger': True,
1258
+ 'trailing': True,
1259
+ },
1260
+ 'fetchOrders': None, # not supported
1261
+ 'fetchClosedOrders': {
1262
+ 'marginMode': False,
1263
+ 'limit': 100,
1264
+ 'daysBackClosed': 90, # 3 months
1265
+ 'daysBackCanceled': 1 / 12, # 2 hour
1266
+ 'untilDays': None,
1267
+ 'trigger': True,
1268
+ 'trailing': True,
1269
+ },
1270
+ 'fetchOHLCV': {
1271
+ 'limit': 300,
1272
+ },
1273
+ },
1274
+ 'spot': {
1275
+ 'extends': 'default',
1276
+ },
1277
+ 'swap': {
1278
+ 'linear': {
1279
+ 'extends': 'default',
1280
+ },
1281
+ 'inverse': {
1282
+ 'extends': 'default',
1283
+ },
1284
+ },
1285
+ 'future': {
1286
+ 'linear': {
1287
+ 'extends': 'default',
1288
+ },
1289
+ 'inverse': {
1290
+ 'extends': 'default',
1291
+ },
1292
+ },
1293
+ },
1202
1294
  'commonCurrencies': {
1203
1295
  # the exchange refers to ERC20 version of Aeternity(AEToken)
1204
1296
  'AE': 'AET', # https://github.com/ccxt/ccxt/issues/4981
@@ -1726,7 +1818,7 @@ class okx(Exchange, ImplicitAPI):
1726
1818
  'active': active,
1727
1819
  'deposit': canDeposit,
1728
1820
  'withdraw': canWithdraw,
1729
- 'fee': self.safe_number(chain, 'minFee'),
1821
+ 'fee': self.safe_number(chain, 'fee'),
1730
1822
  'precision': self.parse_number(precision),
1731
1823
  'limits': {
1732
1824
  'withdraw': {
@@ -3077,7 +3169,7 @@ class okx(Exchange, ImplicitAPI):
3077
3169
  if not isAlgoOrder:
3078
3170
  if price is not None:
3079
3171
  request['newPx'] = self.price_to_precision(symbol, price)
3080
- params = self.omit(params, ['clOrdId', 'clientOrderId', 'takeProfitPrice', 'stopLossPrice', 'stopLoss', 'takeProfit'])
3172
+ params = self.omit(params, ['clOrdId', 'clientOrderId', 'takeProfitPrice', 'stopLossPrice', 'stopLoss', 'takeProfit', 'postOnly'])
3081
3173
  return self.extend(request, params)
3082
3174
 
3083
3175
  def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
@@ -6084,7 +6176,7 @@ class okx(Exchange, ImplicitAPI):
6084
6176
  :param str symbol: unified market symbol
6085
6177
  :param dict [params]: extra parameters specific to the exchange API endpoint
6086
6178
  :param str [params.marginMode]: 'cross' or 'isolated'
6087
- :param str [params.posSide]: 'long' or 'short' for isolated margin long/short mode on futures and swap markets
6179
+ :param str [params.posSide]: 'long' or 'short' or 'net' for isolated margin long/short mode on futures and swap markets, default is 'net'
6088
6180
  :returns dict: response from the exchange
6089
6181
  """
6090
6182
  if symbol is None:
@@ -6106,12 +6198,11 @@ class okx(Exchange, ImplicitAPI):
6106
6198
  'mgnMode': marginMode,
6107
6199
  'instId': market['id'],
6108
6200
  }
6109
- posSide = self.safe_string(params, 'posSide')
6201
+ posSide = self.safe_string(params, 'posSide', 'net')
6110
6202
  if marginMode == 'isolated':
6111
- if posSide is None:
6112
- raise ArgumentsRequired(self.id + ' setLeverage() requires a posSide argument for isolated margin')
6113
6203
  if posSide != 'long' and posSide != 'short' and posSide != 'net':
6114
6204
  raise BadRequest(self.id + ' setLeverage() requires the posSide argument to be either "long", "short" or "net"')
6205
+ request['posSide'] = posSide
6115
6206
  response = self.privatePostAccountSetLeverage(self.extend(request, params))
6116
6207
  #
6117
6208
  # {
@@ -7014,7 +7105,11 @@ class okx(Exchange, ImplicitAPI):
7014
7105
  :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
7015
7106
  """
7016
7107
  self.load_markets()
7017
- response = self.privateGetAssetCurrencies(params)
7108
+ request = {}
7109
+ if codes is not None:
7110
+ ids = self.currency_ids(codes)
7111
+ request['ccy'] = ','.join(ids)
7112
+ response = self.privateGetAssetCurrencies(self.extend(request, params))
7018
7113
  #
7019
7114
  # {
7020
7115
  # "code": "0",
@@ -7099,7 +7194,7 @@ class okx(Exchange, ImplicitAPI):
7099
7194
  continue
7100
7195
  chainSplit = chain.split('-')
7101
7196
  networkId = self.safe_value(chainSplit, 1)
7102
- withdrawFee = self.safe_number(feeInfo, 'minFee')
7197
+ withdrawFee = self.safe_number(feeInfo, 'fee')
7103
7198
  withdrawResult: dict = {
7104
7199
  'fee': withdrawFee,
7105
7200
  'percentage': False if (withdrawFee is not None) else None,
ccxt/onetrading.py CHANGED
@@ -16,6 +16,7 @@ from ccxt.base.errors import InsufficientFunds
16
16
  from ccxt.base.errors import InvalidAddress
17
17
  from ccxt.base.errors import InvalidOrder
18
18
  from ccxt.base.errors import OrderNotFound
19
+ from ccxt.base.errors import NotSupported
19
20
  from ccxt.base.errors import DDoSProtection
20
21
  from ccxt.base.errors import ExchangeNotAvailable
21
22
  from ccxt.base.decimal_to_precision import TICK_SIZE
@@ -317,6 +318,9 @@ class onetrading(Exchange, ImplicitAPI):
317
318
  def fetch_time(self, params={}):
318
319
  """
319
320
  fetches the current integer timestamp in milliseconds from the exchange server
321
+
322
+ https://docs.onetrading.com/#time
323
+
320
324
  :param dict [params]: extra parameters specific to the exchange API endpoint
321
325
  :returns int: the current integer timestamp in milliseconds from the exchange server
322
326
  """
@@ -332,6 +336,9 @@ class onetrading(Exchange, ImplicitAPI):
332
336
  def fetch_currencies(self, params={}) -> Currencies:
333
337
  """
334
338
  fetches all available currencies on an exchange
339
+
340
+ https://docs.onetrading.com/#currencies
341
+
335
342
  :param dict [params]: extra parameters specific to the exchange API endpoint
336
343
  :returns dict: an associative dictionary of currencies
337
344
  """
@@ -370,6 +377,9 @@ class onetrading(Exchange, ImplicitAPI):
370
377
  def fetch_markets(self, params={}) -> List[Market]:
371
378
  """
372
379
  retrieves data on all markets for onetrading
380
+
381
+ https://docs.onetrading.com/#instruments
382
+
373
383
  :param dict [params]: extra parameters specific to the exchange API endpoint
374
384
  :returns dict[]: an array of objects representing market data
375
385
  """
@@ -450,6 +460,10 @@ class onetrading(Exchange, ImplicitAPI):
450
460
  def fetch_trading_fees(self, params={}) -> TradingFees:
451
461
  """
452
462
  fetch the trading fees for multiple markets
463
+
464
+ https://docs.onetrading.com/#fee-groups
465
+ https://docs.onetrading.com/#fees
466
+
453
467
  :param dict [params]: extra parameters specific to the exchange API endpoint
454
468
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
455
469
  """
@@ -458,7 +472,12 @@ class onetrading(Exchange, ImplicitAPI):
458
472
  if method is None:
459
473
  options = self.safe_value(self.options, 'fetchTradingFees', {})
460
474
  method = self.safe_string(options, 'method', 'fetchPrivateTradingFees')
461
- return getattr(self, method)(params)
475
+ if method == 'fetchPrivateTradingFees':
476
+ return self.fetch_private_trading_fees(params)
477
+ elif method == 'fetchPublicTradingFees':
478
+ return self.fetch_public_trading_fees(params)
479
+ else:
480
+ raise NotSupported(self.id + ' fetchTradingFees() does not support ' + method + ', fetchPrivateTradingFees and fetchPublicTradingFees are supported')
462
481
 
463
482
  def fetch_public_trading_fees(self, params={}):
464
483
  self.load_markets()
ccxt/paradex.py CHANGED
@@ -53,6 +53,8 @@ class paradex(Exchange, ImplicitAPI):
53
53
  'createOrder': True,
54
54
  'createOrders': False,
55
55
  'createReduceOnlyOrder': False,
56
+ 'createStopOrder': True,
57
+ 'createTriggerOrder': True,
56
58
  'editOrder': False,
57
59
  'fetchAccounts': False,
58
60
  'fetchBalance': True,
ccxt/phemex.py CHANGED
@@ -525,7 +525,7 @@ class phemex(Exchange, ImplicitAPI):
525
525
  def parse_swap_market(self, market: dict):
526
526
  #
527
527
  # {
528
- # "symbol":"BTCUSD",
528
+ # "symbol":"BTCUSD", #
529
529
  # "code":"1",
530
530
  # "type":"Perpetual",
531
531
  # "displaySymbol":"BTC / USD",
@@ -533,7 +533,7 @@ class phemex(Exchange, ImplicitAPI):
533
533
  # "markSymbol":".MBTC",
534
534
  # "fundingRateSymbol":".BTCFR",
535
535
  # "fundingRate8hSymbol":".BTCFR8H",
536
- # "contractUnderlyingAssets":"USD",
536
+ # "contractUnderlyingAssets":"USD", # or eg. `1000 SHIB`
537
537
  # "settleCurrency":"BTC",
538
538
  # "quoteCurrency":"USD",
539
539
  # "contractSize":"1 USD",
@@ -577,6 +577,7 @@ class phemex(Exchange, ImplicitAPI):
577
577
  quoteId = self.safe_string(market, 'quoteCurrency')
578
578
  settleId = self.safe_string(market, 'settleCurrency')
579
579
  base = self.safe_currency_code(baseId)
580
+ base = base.replace(' ', '') # replace space for junction codes, eg. `1000 SHIB`
580
581
  quote = self.safe_currency_code(quoteId)
581
582
  settle = self.safe_currency_code(settleId)
582
583
  inverse = False
@@ -2536,11 +2537,27 @@ class phemex(Exchange, ImplicitAPI):
2536
2537
  if triggerPrice is not None:
2537
2538
  triggerType = self.safe_string(params, 'triggerType', 'ByMarkPrice')
2538
2539
  request['triggerType'] = triggerType
2540
+ # set direction & exchange specific order type
2541
+ triggerDirection = None
2542
+ triggerDirection, params = self.handle_param_string(params, 'triggerDirection')
2543
+ if triggerDirection is None:
2544
+ raise ArgumentsRequired(self.id + " createOrder() also requires a 'triggerDirection' parameter with either 'up' or 'down' value")
2545
+ # the flow defined per https://phemex-docs.github.io/#more-order-type-examples
2546
+ if triggerDirection == 'up':
2547
+ if side == 'sell':
2548
+ request['ordType'] = 'MarketIfTouched' if (type == 'Market') else 'LimitIfTouched'
2549
+ elif side == 'buy':
2550
+ request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
2551
+ elif triggerDirection == 'down':
2552
+ if side == 'sell':
2553
+ request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
2554
+ elif side == 'buy':
2555
+ request['ordType'] = 'MarketIfTouched' if (type == 'Market') else 'LimitIfTouched'
2539
2556
  if stopLossDefined or takeProfitDefined:
2540
2557
  if stopLossDefined:
2541
2558
  stopLossTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice')
2542
2559
  if stopLossTriggerPrice is None:
2543
- raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"], or params["stopLoss"]["stopPrice"] for a stop loss order')
2560
+ raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"] for a stop loss order')
2544
2561
  if market['settle'] == 'USDT':
2545
2562
  request['stopLossRp'] = self.price_to_precision(symbol, stopLossTriggerPrice)
2546
2563
  else:
@@ -2554,7 +2571,7 @@ class phemex(Exchange, ImplicitAPI):
2554
2571
  if takeProfitDefined:
2555
2572
  takeProfitTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice')
2556
2573
  if takeProfitTriggerPrice is None:
2557
- raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"], or params["takeProfit"]["stopPrice"] for a take profit order')
2574
+ raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"] for a take profit order')
2558
2575
  if market['settle'] == 'USDT':
2559
2576
  request['takeProfitRp'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
2560
2577
  else:
@@ -2715,13 +2732,13 @@ class phemex(Exchange, ImplicitAPI):
2715
2732
  request['orderQtyRq'] = self.amount_to_precision(market['symbol'], amount)
2716
2733
  else:
2717
2734
  request['baseQtyEV'] = self.to_ev(amount, market)
2718
- stopPrice = self.safe_string_2(params, 'stopPx', 'stopPrice')
2735
+ stopPrice = self.safe_string_n(params, ['triggerPrice', 'stopPx', 'stopPrice'])
2719
2736
  if stopPrice is not None:
2720
2737
  if isUSDTSettled:
2721
2738
  request['stopPxRp'] = self.price_to_precision(symbol, stopPrice)
2722
2739
  else:
2723
2740
  request['stopPxEp'] = self.to_ep(stopPrice, market)
2724
- params = self.omit(params, ['stopPx', 'stopPrice'])
2741
+ params = self.omit(params, ['triggerPrice', 'stopPx', 'stopPrice'])
2725
2742
  response = None
2726
2743
  if isUSDTSettled:
2727
2744
  posSide = self.safe_string(params, 'posSide')
@@ -3960,6 +3977,9 @@ class phemex(Exchange, ImplicitAPI):
3960
3977
  def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
3961
3978
  """
3962
3979
  set margin mode to 'cross' or 'isolated'
3980
+
3981
+ https://phemex-docs.github.io/#set-leverage
3982
+
3963
3983
  :param str marginMode: 'cross' or 'isolated'
3964
3984
  :param str symbol: unified market symbol
3965
3985
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4223,6 +4243,10 @@ class phemex(Exchange, ImplicitAPI):
4223
4243
  def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
4224
4244
  """
4225
4245
  transfer currency internally between wallets on the same account
4246
+
4247
+ https://phemex-docs.github.io/#transfer-between-spot-and-futures
4248
+ https://phemex-docs.github.io/#universal-transfer-main-account-only-transfer-between-sub-to-main-main-to-sub-or-sub-to-sub
4249
+
4226
4250
  :param str code: unified currency code
4227
4251
  :param float amount: amount to transfer
4228
4252
  :param str fromAccount: account to transfer from
@@ -4299,6 +4323,9 @@ class phemex(Exchange, ImplicitAPI):
4299
4323
  def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
4300
4324
  """
4301
4325
  fetch a history of internal transfers made on an account
4326
+
4327
+ https://phemex-docs.github.io/#query-transfer-history
4328
+
4302
4329
  :param str code: unified currency code of the currency transferred
4303
4330
  :param int [since]: the earliest time in ms to fetch transfers for
4304
4331
  :param int [limit]: the maximum number of transfers structures to retrieve
ccxt/poloniex.py CHANGED
@@ -51,6 +51,8 @@ class poloniex(Exchange, ImplicitAPI):
51
51
  'createMarketOrderWithCost': False,
52
52
  'createMarketSellOrderWithCost': False,
53
53
  'createOrder': True,
54
+ 'createStopOrder': True,
55
+ 'createTriggerOrder': True,
54
56
  'editOrder': True,
55
57
  'fetchBalance': True,
56
58
  'fetchClosedOrder': False,
@@ -1256,7 +1258,7 @@ class poloniex(Exchange, ImplicitAPI):
1256
1258
  :param float amount: how much of currency you want to trade in units of base currency
1257
1259
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1258
1260
  :param dict [params]: extra parameters specific to the exchange API endpoint
1259
- :param float [params.triggerPrice]: *spot only* The price at which a trigger order is triggered at
1261
+ :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1260
1262
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
1261
1263
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1262
1264
  """
ccxt/poloniexfutures.py CHANGED
@@ -42,6 +42,8 @@ class poloniexfutures(Exchange, ImplicitAPI):
42
42
  'future': False,
43
43
  'option': None,
44
44
  'createOrder': True,
45
+ 'createStopOrder': True,
46
+ 'createTriggerOrder': True,
45
47
  'fetchBalance': True,
46
48
  'fetchClosedOrders': True,
47
49
  'fetchCurrencies': False,
@@ -827,7 +829,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
827
829
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
828
830
  :param dict [params]: extra parameters specific to the exchange API endpoint
829
831
  :param float [params.leverage]: Leverage size of the order
830
- :param float [params.stopPrice]: The price at which a trigger order is triggered at
832
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
831
833
  :param bool [params.reduceOnly]: A mark to reduce the position size only. Set to False by default. Need to set the position size when reduceOnly is True.
832
834
  :param str [params.timeInForce]: GTC, GTT, IOC, or FOK, default is GTC, limit orders only
833
835
  :param str [params.postOnly]: Post only flag, invalid when timeInForce is IOC or FOK
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.32'
7
+ __version__ = '4.4.34'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/idex.py CHANGED
@@ -72,6 +72,9 @@ class idex(ccxt.async_support.idex):
72
72
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
73
73
  """
74
74
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
75
+
76
+ https://api-docs-v4.idex.io/#tickers
77
+
75
78
  :param str symbol: unified symbol of the market to fetch the ticker for
76
79
  :param dict [params]: extra parameters specific to the exchange API endpoint
77
80
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -141,6 +144,9 @@ class idex(ccxt.async_support.idex):
141
144
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
142
145
  """
143
146
  get the list of most recent trades for a particular symbol
147
+
148
+ https://api-docs-v4.idex.io/#trades
149
+
144
150
  :param str symbol: unified symbol of the market to fetch trades for
145
151
  :param int [since]: timestamp in ms of the earliest trade to fetch
146
152
  :param int [limit]: the maximum amount of trades to fetch
@@ -231,6 +237,9 @@ class idex(ccxt.async_support.idex):
231
237
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
232
238
  """
233
239
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
240
+
241
+ https://api-docs-v4.idex.io/#candles
242
+
234
243
  :param str symbol: unified symbol of the market to fetch OHLCV data for
235
244
  :param str timeframe: the length of time each candle represents
236
245
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -383,6 +392,9 @@ class idex(ccxt.async_support.idex):
383
392
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
384
393
  """
385
394
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
395
+
396
+ https://api-docs-v4.idex.io/#l2-order-book
397
+
386
398
  :param str symbol: unified symbol of the market to fetch the order book for
387
399
  :param int [limit]: the maximum amount of order book entries to return
388
400
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -478,6 +490,9 @@ class idex(ccxt.async_support.idex):
478
490
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
479
491
  """
480
492
  watches information on multiple orders made by the user
493
+
494
+ https://api-docs-v4.idex.io/#orders
495
+
481
496
  :param str symbol: unified market symbol of the market orders were made in
482
497
  :param int [since]: the earliest time in ms to fetch orders for
483
498
  :param int [limit]: the maximum number of order structures to retrieve
ccxt/pro/okx.py CHANGED
@@ -2135,6 +2135,7 @@ class okx(ccxt.async_support.okx):
2135
2135
  #
2136
2136
  # {event: 'error', msg: "Illegal request: {"op":"subscribe","args":["spot/ticker:BTC-USDT"]}", code: "60012"}
2137
2137
  # {event: 'error", msg: "channel:ticker,instId:BTC-USDT doesn"t exist", code: "60018"}
2138
+ # {"event":"error","msg":"Illegal request: {\\"id\\":\\"17321173472466905\\",\\"op\\":\\"amend-order\\",\\"args\\":[{\\"instId\\":\\"ETH-USDC\\",\\"ordId\\":\\"2000345622407479296\\",\\"newSz\\":\\"0.050857\\",\\"newPx\\":\\"2949.4\\",\\"postOnly\\":true}],\\"postOnly\\":true}","code":"60012","connId":"0808af6c"}
2138
2139
  #
2139
2140
  errorCode = self.safe_string(message, 'code')
2140
2141
  try:
@@ -2160,6 +2161,13 @@ class okx(ccxt.async_support.okx):
2160
2161
  # if the message contains an id, it means it is a response to a request
2161
2162
  # so we only reject that promise, instead of deleting all futures, destroying the authentication future
2162
2163
  id = self.safe_string(message, 'id')
2164
+ if id is None:
2165
+ # try to parse it from the stringified json inside msg
2166
+ msg = self.safe_string(message, 'msg')
2167
+ if msg is not None and msg.startswith('Illegal request: {'):
2168
+ stringifiedJson = msg.replace('Illegal request: ', '')
2169
+ parsedJson = self.parse_json(stringifiedJson)
2170
+ id = self.safe_string(parsedJson, 'id')
2163
2171
  if id is not None:
2164
2172
  client.reject(e, id)
2165
2173
  return False
ccxt/pro/probit.py CHANGED
@@ -503,10 +503,12 @@ class probit(ccxt.async_support.probit):
503
503
  if ticker is not None:
504
504
  self.handle_ticker(client, message)
505
505
  trades = self.safe_value(message, 'recent_trades', [])
506
- if len(trades):
506
+ tradesLength = len(trades)
507
+ if tradesLength:
507
508
  self.handle_trades(client, message)
508
509
  orderBook = self.safe_value_n(message, ['order_books', 'order_books_l1', 'order_books_l2', 'order_books_l3', 'order_books_l4'], [])
509
- if len(orderBook):
510
+ orderBookLength = len(orderBook)
511
+ if orderBookLength:
510
512
  self.handle_order_book(client, message, orderBook)
511
513
 
512
514
  def handle_message(self, client: Client, message):