ccxt 4.1.84__py2.py3-none-any.whl → 4.1.86__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (65) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/alpaca.py +1 -1
  3. ccxt/ascendex.py +1 -1
  4. ccxt/async_support/__init__.py +1 -1
  5. ccxt/async_support/alpaca.py +1 -1
  6. ccxt/async_support/ascendex.py +1 -1
  7. ccxt/async_support/base/exchange.py +7 -2
  8. ccxt/async_support/binance.py +1 -1
  9. ccxt/async_support/bingx.py +9 -8
  10. ccxt/async_support/bitget.py +1 -2
  11. ccxt/async_support/bithumb.py +2 -2
  12. ccxt/async_support/bitmart.py +90 -73
  13. ccxt/async_support/bitmex.py +1 -1
  14. ccxt/async_support/bitopro.py +2 -2
  15. ccxt/async_support/bybit.py +2 -4
  16. ccxt/async_support/coinex.py +2 -1
  17. ccxt/async_support/cryptocom.py +2 -2
  18. ccxt/async_support/digifinex.py +119 -103
  19. ccxt/async_support/hitbtc.py +1 -1
  20. ccxt/async_support/htx.py +1 -1
  21. ccxt/async_support/kraken.py +1 -1
  22. ccxt/async_support/krakenfutures.py +2 -2
  23. ccxt/async_support/kucoin.py +1 -5
  24. ccxt/async_support/kucoinfutures.py +0 -3
  25. ccxt/async_support/latoken.py +1 -1
  26. ccxt/async_support/mexc.py +76 -49
  27. ccxt/async_support/okx.py +3 -3
  28. ccxt/async_support/p2b.py +0 -2
  29. ccxt/async_support/poloniex.py +42 -42
  30. ccxt/async_support/probit.py +25 -17
  31. ccxt/async_support/tokocrypto.py +6 -3
  32. ccxt/base/exchange.py +21 -8
  33. ccxt/binance.py +1 -1
  34. ccxt/bingx.py +9 -8
  35. ccxt/bitget.py +1 -2
  36. ccxt/bitmart.py +90 -73
  37. ccxt/bitmex.py +1 -1
  38. ccxt/bybit.py +2 -4
  39. ccxt/coinex.py +2 -1
  40. ccxt/cryptocom.py +2 -2
  41. ccxt/digifinex.py +119 -103
  42. ccxt/hitbtc.py +1 -1
  43. ccxt/htx.py +1 -1
  44. ccxt/kraken.py +1 -1
  45. ccxt/krakenfutures.py +2 -2
  46. ccxt/kucoin.py +1 -5
  47. ccxt/kucoinfutures.py +0 -3
  48. ccxt/latoken.py +1 -1
  49. ccxt/mexc.py +76 -49
  50. ccxt/okx.py +3 -3
  51. ccxt/p2b.py +0 -2
  52. ccxt/poloniex.py +42 -42
  53. ccxt/pro/__init__.py +1 -1
  54. ccxt/pro/bitmart.py +965 -247
  55. ccxt/pro/bitmex.py +200 -2
  56. ccxt/pro/krakenfutures.py +4 -4
  57. ccxt/pro/mexc.py +1 -1
  58. ccxt/pro/poloniex.py +1 -1
  59. ccxt/pro/poloniexfutures.py +3 -3
  60. ccxt/probit.py +25 -17
  61. ccxt/tokocrypto.py +6 -3
  62. {ccxt-4.1.84.dist-info → ccxt-4.1.86.dist-info}/METADATA +6 -5
  63. {ccxt-4.1.84.dist-info → ccxt-4.1.86.dist-info}/RECORD +65 -65
  64. {ccxt-4.1.84.dist-info → ccxt-4.1.86.dist-info}/WHEEL +0 -0
  65. {ccxt-4.1.84.dist-info → ccxt-4.1.86.dist-info}/top_level.txt +0 -0
@@ -1380,7 +1380,15 @@ class mexc(Exchange, ImplicitAPI):
1380
1380
  request['endTime'] = until
1381
1381
  method = self.safe_string(self.options, 'fetchTradesMethod', 'spotPublicGetAggTrades')
1382
1382
  method = self.safe_string(params, 'method', method) # AggTrades, HistoricalTrades, Trades
1383
- trades = await getattr(self, method)(self.extend(request, params))
1383
+ params = self.omit(params, ['method'])
1384
+ if method == 'spotPublicGetAggTrades':
1385
+ trades = await self.spotPublicGetAggTrades(self.extend(request, params))
1386
+ elif method == 'spotPublicGetHistoricalTrades':
1387
+ trades = await self.spotPublicGetHistoricalTrades(self.extend(request, params))
1388
+ elif method == 'spotPublicGetTrades':
1389
+ trades = await self.spotPublicGetTrades(self.extend(request, params))
1390
+ else:
1391
+ raise NotSupported(self.id + ' fetchTrades() not support self method')
1384
1392
  #
1385
1393
  # /trades, /historicalTrades
1386
1394
  #
@@ -1656,12 +1664,15 @@ class mexc(Exchange, ImplicitAPI):
1656
1664
  request['end'] = until
1657
1665
  priceType = self.safe_string(params, 'price', 'default')
1658
1666
  params = self.omit(params, 'price')
1659
- method = self.get_supported_mapping(priceType, {
1660
- 'default': 'contractPublicGetKlineSymbol',
1661
- 'index': 'contractPublicGetKlineIndexPriceSymbol',
1662
- 'mark': 'contractPublicGetKlineFairPriceSymbol',
1663
- })
1664
- response = await getattr(self, method)(self.extend(request, params))
1667
+ response = None
1668
+ if priceType == 'default':
1669
+ response = await self.contractPublicGetKlineSymbol(self.extend(request, params))
1670
+ elif priceType == 'index':
1671
+ response = await self.contractPublicGetKlineIndexPriceSymbol(self.extend(request, params))
1672
+ elif priceType == 'mark':
1673
+ response = await self.contractPublicGetKlineFairPriceSymbol(self.extend(request, params))
1674
+ else:
1675
+ raise NotSupported(self.id + ' fetchOHLCV() not support self price type, [default, index, mark]')
1665
1676
  #
1666
1677
  # {
1667
1678
  # "success":true,
@@ -2019,6 +2030,7 @@ class mexc(Exchange, ImplicitAPI):
2019
2030
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
2020
2031
  :param dict [params]: extra parameters specific to the exchange API endpoint
2021
2032
  :param str [params.marginMode]: only 'isolated' is supported for spot-margin trading
2033
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
2022
2034
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2023
2035
  """
2024
2036
  await self.load_markets()
@@ -2153,16 +2165,6 @@ class mexc(Exchange, ImplicitAPI):
2153
2165
  # 'trend': 1, # Required for trigger order 1: latest price, 2: fair price, 3: index price
2154
2166
  # 'orderType': 1, # Required for trigger order 1: limit order,2:Post Only Maker,3: close or cancel instantly ,4: close or cancel completely,5: Market order
2155
2167
  }
2156
- method = 'contractPrivatePostOrderSubmit'
2157
- stopPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
2158
- params = self.omit(params, ['stopPrice', 'triggerPrice'])
2159
- if stopPrice:
2160
- method = 'contractPrivatePostPlanorderPlace'
2161
- request['triggerPrice'] = self.price_to_precision(symbol, stopPrice)
2162
- request['triggerType'] = self.safe_integer(params, 'triggerType', 1)
2163
- request['executeCycle'] = self.safe_integer(params, 'executeCycle', 1)
2164
- request['trend'] = self.safe_integer(params, 'trend', 1)
2165
- request['orderType'] = self.safe_integer(params, 'orderType', 1)
2166
2168
  if (type != 5) and (type != 6) and (type != 'market'):
2167
2169
  request['price'] = float(self.price_to_precision(symbol, price))
2168
2170
  if openType == 1:
@@ -2177,8 +2179,18 @@ class mexc(Exchange, ImplicitAPI):
2177
2179
  clientOrderId = self.safe_string_2(params, 'clientOrderId', 'externalOid')
2178
2180
  if clientOrderId is not None:
2179
2181
  request['externalOid'] = clientOrderId
2180
- params = self.omit(params, ['clientOrderId', 'externalOid', 'postOnly'])
2181
- response = await getattr(self, method)(self.extend(request, params))
2182
+ stopPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
2183
+ params = self.omit(params, ['clientOrderId', 'externalOid', 'postOnly', 'stopPrice', 'triggerPrice'])
2184
+ response = None
2185
+ if stopPrice:
2186
+ request['triggerPrice'] = self.price_to_precision(symbol, stopPrice)
2187
+ request['triggerType'] = self.safe_integer(params, 'triggerType', 1)
2188
+ request['executeCycle'] = self.safe_integer(params, 'executeCycle', 1)
2189
+ request['trend'] = self.safe_integer(params, 'trend', 1)
2190
+ request['orderType'] = self.safe_integer(params, 'orderType', 1)
2191
+ response = await self.contractPrivatePostPlanorderPlace(self.extend(request, params))
2192
+ else:
2193
+ response = await self.contractPrivatePostOrderSubmit(self.extend(request, params))
2182
2194
  #
2183
2195
  # Swap
2184
2196
  # {"code":200,"data":"2ff3163e8617443cb9c6fc19d42b1ca4"}
@@ -2193,7 +2205,7 @@ class mexc(Exchange, ImplicitAPI):
2193
2205
  """
2194
2206
  *spot only* *all orders must have the same symbol* create a list of trade orders
2195
2207
  :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#batch-orders
2196
- :param array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
2208
+ :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
2197
2209
  :param dict [params]: extra parameters specific to api endpoint
2198
2210
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2199
2211
  """
@@ -2270,12 +2282,12 @@ class mexc(Exchange, ImplicitAPI):
2270
2282
  else:
2271
2283
  request['orderId'] = id
2272
2284
  marginMode, query = self.handle_margin_mode_and_params('fetchOrder', params)
2273
- method = 'spotPrivateGetOrder'
2274
2285
  if marginMode is not None:
2275
2286
  if marginMode != 'isolated':
2276
2287
  raise BadRequest(self.id + ' fetchOrder() does not support marginMode ' + marginMode + ' for spot-margin trading')
2277
- method = 'spotPrivateGetMarginOrder'
2278
- data = await getattr(self, method)(self.extend(request, query))
2288
+ data = await self.spotPrivateGetMarginOrder(self.extend(request, query))
2289
+ else:
2290
+ data = await self.spotPrivateGetOrder(self.extend(request, query))
2279
2291
  #
2280
2292
  # spot
2281
2293
  #
@@ -2379,16 +2391,17 @@ class mexc(Exchange, ImplicitAPI):
2379
2391
  if symbol is None:
2380
2392
  raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument for spot market')
2381
2393
  marginMode, queryInner = self.handle_margin_mode_and_params('fetchOrders', params)
2382
- method = 'spotPrivateGetAllOrders'
2383
- if marginMode is not None:
2384
- if marginMode != 'isolated':
2385
- raise BadRequest(self.id + ' fetchOrders() does not support marginMode ' + marginMode + ' for spot-margin trading')
2386
- method = 'spotPrivateGetMarginAllOrders'
2387
2394
  if since is not None:
2388
2395
  request['startTime'] = since
2389
2396
  if limit is not None:
2390
2397
  request['limit'] = limit
2391
- response = await getattr(self, method)(self.extend(request, queryInner))
2398
+ response = None
2399
+ if marginMode is not None:
2400
+ if marginMode != 'isolated':
2401
+ raise BadRequest(self.id + ' fetchOrders() does not support marginMode ' + marginMode + ' for spot-margin trading')
2402
+ response = await self.spotPrivateGetMarginAllOrders(self.extend(request, queryInner))
2403
+ else:
2404
+ response = await self.spotPrivateGetAllOrders(self.extend(request, queryInner))
2392
2405
  #
2393
2406
  # spot
2394
2407
  #
@@ -2591,13 +2604,14 @@ class mexc(Exchange, ImplicitAPI):
2591
2604
  if symbol is None:
2592
2605
  raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol argument for spot market')
2593
2606
  request['symbol'] = market['id']
2594
- method = 'spotPrivateGetOpenOrders'
2595
2607
  marginMode, query = self.handle_margin_mode_and_params('fetchOpenOrders', params)
2608
+ response = None
2596
2609
  if marginMode is not None:
2597
2610
  if marginMode != 'isolated':
2598
2611
  raise BadRequest(self.id + ' fetchOpenOrders() does not support marginMode ' + marginMode + ' for spot-margin trading')
2599
- method = 'spotPrivateGetMarginOpenOrders'
2600
- response = await getattr(self, method)(self.extend(request, query))
2612
+ response = await self.spotPrivateGetMarginOpenOrders(self.extend(request, query))
2613
+ else:
2614
+ response = await self.spotPrivateGetOpenOrders(self.extend(request, query))
2601
2615
  #
2602
2616
  # spot
2603
2617
  #
@@ -2717,12 +2731,12 @@ class mexc(Exchange, ImplicitAPI):
2717
2731
  requestInner['origClientOrderId'] = clientOrderId
2718
2732
  else:
2719
2733
  requestInner['orderId'] = id
2720
- method = 'spotPrivateDeleteOrder'
2721
2734
  if marginMode is not None:
2722
2735
  if marginMode != 'isolated':
2723
2736
  raise BadRequest(self.id + ' cancelOrder() does not support marginMode ' + marginMode + ' for spot-margin trading')
2724
- method = 'spotPrivateDeleteMarginOrder'
2725
- data = await getattr(self, method)(self.extend(requestInner, query))
2737
+ data = await self.spotPrivateDeleteMarginOrder(self.extend(requestInner, query))
2738
+ else:
2739
+ data = await self.spotPrivateDeleteOrder(self.extend(requestInner, query))
2726
2740
  #
2727
2741
  # spot
2728
2742
  #
@@ -2761,7 +2775,13 @@ class mexc(Exchange, ImplicitAPI):
2761
2775
  # TODO: PlanorderCancel endpoint has bug atm. waiting for fix.
2762
2776
  method = self.safe_string(self.options, 'cancelOrder', 'contractPrivatePostOrderCancel') # contractPrivatePostOrderCancel, contractPrivatePostPlanorderCancel
2763
2777
  method = self.safe_string(query, 'method', method)
2764
- response = await getattr(self, method)([id]) # the request cannot be changed or extended. This is the only way to send.
2778
+ response = None
2779
+ if method == 'contractPrivatePostOrderCancel':
2780
+ response = await self.contractPrivatePostOrderCancel([id]) # the request cannot be changed or extended. This is the only way to send.
2781
+ elif method == 'contractPrivatePostPlanorderCancel':
2782
+ response = await self.contractPrivatePostPlanorderCancel([id]) # the request cannot be changed or extended. This is the only way to send.
2783
+ else:
2784
+ raise NotSupported(self.id + ' cancelOrder() not support self method')
2765
2785
  #
2766
2786
  # {
2767
2787
  # "success": True,
@@ -2831,12 +2851,13 @@ class mexc(Exchange, ImplicitAPI):
2831
2851
  if symbol is None:
2832
2852
  raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument on spot')
2833
2853
  request['symbol'] = market['id']
2834
- method = 'spotPrivateDeleteOpenOrders'
2854
+ response = None
2835
2855
  if marginMode is not None:
2836
2856
  if marginMode != 'isolated':
2837
2857
  raise BadRequest(self.id + ' cancelAllOrders() does not support marginMode ' + marginMode + ' for spot-margin trading')
2838
- method = 'spotPrivateDeleteMarginOpenOrders'
2839
- response = await getattr(self, method)(self.extend(request, query))
2858
+ response = await self.spotPrivateDeleteMarginOpenOrders(self.extend(request, query))
2859
+ else:
2860
+ response = await self.spotPrivateDeleteOpenOrders(self.extend(request, query))
2840
2861
  #
2841
2862
  # spot
2842
2863
  #
@@ -2881,7 +2902,11 @@ class mexc(Exchange, ImplicitAPI):
2881
2902
  # the Planorder endpoints work not only for stop-market orders but also for stop-limit orders that are supposed to have separate endpoint
2882
2903
  method = self.safe_string(self.options, 'cancelAllOrders', 'contractPrivatePostOrderCancelAll')
2883
2904
  method = self.safe_string(query, 'method', method)
2884
- response = await getattr(self, method)(self.extend(request, query))
2905
+ response = None
2906
+ if method == 'contractPrivatePostOrderCancelAll':
2907
+ response = await self.contractPrivatePostOrderCancelAll(self.extend(request, query))
2908
+ elif method == 'contractPrivatePostPlanorderCancelAll':
2909
+ response = await self.contractPrivatePostPlanorderCancelAll(self.extend(request, query))
2885
2910
  #
2886
2911
  # {
2887
2912
  # "success": True,
@@ -3371,13 +3396,10 @@ class mexc(Exchange, ImplicitAPI):
3371
3396
  marketType = None
3372
3397
  request = {}
3373
3398
  marketType, params = self.handle_market_type_and_params('fetchBalance', None, params)
3374
- method = self.get_supported_mapping(marketType, {
3375
- 'spot': 'spotPrivateGetAccount',
3376
- 'swap': 'contractPrivateGetAccountAssets',
3377
- 'margin': 'spotPrivateGetMarginIsolatedAccount',
3378
- })
3379
3399
  marginMode = self.safe_string(params, 'marginMode')
3380
3400
  isMargin = self.safe_value(params, 'margin', False)
3401
+ params = self.omit(params, ['margin', 'marginMode'])
3402
+ response = None
3381
3403
  if (marginMode is not None) or (isMargin) or (marketType == 'margin'):
3382
3404
  parsedSymbols = None
3383
3405
  symbol = self.safe_string(params, 'symbol')
@@ -3389,11 +3411,16 @@ class mexc(Exchange, ImplicitAPI):
3389
3411
  market = self.market(symbol)
3390
3412
  parsedSymbols = market['id']
3391
3413
  self.check_required_argument('fetchBalance', parsedSymbols, 'symbol or symbols')
3392
- method = 'spotPrivateGetMarginIsolatedAccount'
3393
3414
  marketType = 'margin'
3394
3415
  request['symbols'] = parsedSymbols
3395
- params = self.omit(params, ['margin', 'marginMode', 'symbol', 'symbols'])
3396
- response = await getattr(self, method)(self.extend(request, params))
3416
+ params = self.omit(params, ['symbol', 'symbols'])
3417
+ response = await self.spotPrivateGetMarginIsolatedAccount(self.extend(request, params))
3418
+ elif marketType == 'spot':
3419
+ response = await self.spotPrivateGetAccount(self.extend(request, params))
3420
+ elif marketType == 'swap':
3421
+ response = await self.contractPrivateGetAccountAssets(self.extend(request, params))
3422
+ else:
3423
+ raise NotSupported(self.id + ' fetchBalance() not support self method')
3397
3424
  #
3398
3425
  # spot
3399
3426
  #
@@ -4929,7 +4956,7 @@ class mexc(Exchange, ImplicitAPI):
4929
4956
  marginMode specified by params["marginMode"], self.options["marginMode"], self.options["defaultMarginMode"], params["margin"] = True or self.options["defaultType"] = 'margin'
4930
4957
  :param dict [params]: extra parameters specific to the exchange API endpoint
4931
4958
  :param bool [params.margin]: True for trading spot-margin
4932
- :returns array: the marginMode in lowercase
4959
+ :returns Array: the marginMode in lowercase
4933
4960
  """
4934
4961
  defaultType = self.safe_string(self.options, 'defaultType')
4935
4962
  isMargin = self.safe_value(params, 'margin', False)
ccxt/async_support/okx.py CHANGED
@@ -2716,7 +2716,7 @@ class okx(Exchange, ImplicitAPI):
2716
2716
  """
2717
2717
  create a list of trade orders
2718
2718
  :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders
2719
- :param array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
2719
+ :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
2720
2720
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2721
2721
  """
2722
2722
  await self.load_markets()
@@ -3213,7 +3213,7 @@ class okx(Exchange, ImplicitAPI):
3213
3213
  :param str symbol: unified market symbol
3214
3214
  :param dict [params]: extra and exchange specific parameters
3215
3215
  :returns: `an order structure <https://docs.ccxt.com/#/?id=order-structure>`
3216
- """
3216
+ """
3217
3217
  if symbol is None:
3218
3218
  raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
3219
3219
  await self.load_markets()
@@ -6708,7 +6708,7 @@ class okx(Exchange, ImplicitAPI):
6708
6708
  * EXCHANGE SPECIFIC PARAMETERS
6709
6709
  :param boolean [params.autoCxl]: whether any pending orders for closing out needs to be automatically canceled when close position via a market order. False or True, the default is False
6710
6710
  :param str [params.tag]: order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters
6711
- :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6711
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6712
6712
  """
6713
6713
  await self.load_markets()
6714
6714
  market = self.market(symbol)
ccxt/async_support/p2b.py CHANGED
@@ -529,7 +529,6 @@ class p2b(Exchange, ImplicitAPI):
529
529
  :param int [since]: timestamp in ms of the earliest trade to fetch
530
530
  :param int [limit]: 1-100, default=50
531
531
  :param dict [params]: extra parameters specific to the exchange API endpoint
532
- *
533
532
  :param int params['lastId']: order id
534
533
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
535
534
  """
@@ -642,7 +641,6 @@ class p2b(Exchange, ImplicitAPI):
642
641
  :param int [since]: timestamp in ms of the earliest candle to fetch
643
642
  :param int [limit]: 1-500, default=50
644
643
  :param dict [params]: extra parameters specific to the exchange API endpoint
645
- *
646
644
  :param int [params.offset]: default=0, with self value the last candles are returned
647
645
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
648
646
  """
@@ -1209,18 +1209,18 @@ class poloniex(Exchange, ImplicitAPI):
1209
1209
 
1210
1210
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1211
1211
  """
1212
- create a trade order
1213
- :see: https://docs.poloniex.com/#authenticated-endpoints-orders-create-order
1214
- :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-create-order # trigger orders
1215
- :param str symbol: unified symbol of the market to create an order in
1216
- :param str type: 'market' or 'limit'
1217
- :param str side: 'buy' or 'sell'
1218
- :param float amount: how much of currency you want to trade in units of base currency
1219
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1220
- :param dict [params]: extra parameters specific to the exchange API endpoint
1221
- :param float [params.triggerPrice]: *spot only* The price at which a trigger order is triggered at
1222
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1223
- """
1212
+ create a trade order
1213
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-create-order
1214
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-create-order # trigger orders
1215
+ :param str symbol: unified symbol of the market to create an order in
1216
+ :param str type: 'market' or 'limit'
1217
+ :param str side: 'buy' or 'sell'
1218
+ :param float amount: how much of currency you want to trade in units of base currency
1219
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1220
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1221
+ :param float [params.triggerPrice]: *spot only* The price at which a trigger order is triggered at
1222
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1223
+ """
1224
1224
  await self.load_markets()
1225
1225
  market = self.market(symbol)
1226
1226
  if not market['spot']:
@@ -1280,19 +1280,19 @@ class poloniex(Exchange, ImplicitAPI):
1280
1280
 
1281
1281
  async def edit_order(self, id: str, symbol, type, side, amount=None, price=None, params={}):
1282
1282
  """
1283
- edit a trade order
1284
- :see: https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-replace-order
1285
- :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-cancel-replace-order
1286
- :param str id: order id
1287
- :param str symbol: unified symbol of the market to create an order in
1288
- :param str type: 'market' or 'limit'
1289
- :param str side: 'buy' or 'sell'
1290
- :param float [amount]: how much of the currency you want to trade in units of the base currency
1291
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1292
- :param dict [params]: extra parameters specific to the exchange API endpoint
1293
- :param float [params.triggerPrice]: The price at which a trigger order is triggered at
1294
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1295
- """
1283
+ edit a trade order
1284
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-replace-order
1285
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-cancel-replace-order
1286
+ :param str id: order id
1287
+ :param str symbol: unified symbol of the market to create an order in
1288
+ :param str type: 'market' or 'limit'
1289
+ :param str side: 'buy' or 'sell'
1290
+ :param float [amount]: how much of the currency you want to trade in units of the base currency
1291
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1292
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1293
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
1294
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1295
+ """
1296
1296
  await self.load_markets()
1297
1297
  market = self.market(symbol)
1298
1298
  if not market['spot']:
@@ -1358,14 +1358,14 @@ class poloniex(Exchange, ImplicitAPI):
1358
1358
 
1359
1359
  async def cancel_all_orders(self, symbol: Str = None, params={}):
1360
1360
  """
1361
- cancel all open orders
1362
- :see: https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-all-orders
1363
- :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-cancel-all-orders # trigger orders
1364
- :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1365
- :param dict [params]: extra parameters specific to the exchange API endpoint
1366
- :param boolean [params.trigger]: True if canceling trigger orders
1367
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1368
- """
1361
+ cancel all open orders
1362
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-all-orders
1363
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-cancel-all-orders # trigger orders
1364
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1365
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1366
+ :param boolean [params.trigger]: True if canceling trigger orders
1367
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1368
+ """
1369
1369
  await self.load_markets()
1370
1370
  request = {
1371
1371
  # 'accountTypes': 'SPOT',
@@ -1405,15 +1405,15 @@ class poloniex(Exchange, ImplicitAPI):
1405
1405
 
1406
1406
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
1407
1407
  """
1408
- fetch an order by it's id
1409
- :see: https://docs.poloniex.com/#authenticated-endpoints-orders-order-details
1410
- :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-open-orders # trigger orders
1411
- :param str id: order id
1412
- :param str symbol: unified market symbol, default is None
1413
- :param dict [params]: extra parameters specific to the exchange API endpoint
1414
- :param boolean [params.trigger]: True if fetching a trigger order
1415
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1416
- """
1408
+ fetch an order by it's id
1409
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-order-details
1410
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-open-orders # trigger orders
1411
+ :param str id: order id
1412
+ :param str symbol: unified market symbol, default is None
1413
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1414
+ :param boolean [params.trigger]: True if fetching a trigger order
1415
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1416
+ """
1417
1417
  await self.load_markets()
1418
1418
  id = str(id)
1419
1419
  request = {
@@ -43,7 +43,10 @@ class probit(Exchange, ImplicitAPI):
43
43
  'option': False,
44
44
  'addMargin': False,
45
45
  'cancelOrder': True,
46
+ 'createMarketBuyOrderWithCost': True,
46
47
  'createMarketOrder': True,
48
+ 'createMarketOrderWithCost': False,
49
+ 'createMarketSellOrderWithCost': False,
47
50
  'createOrder': True,
48
51
  'createReduceOnlyOrder': False,
49
52
  'createStopLimitOrder': False,
@@ -328,6 +331,7 @@ class probit(Exchange, ImplicitAPI):
328
331
  'precision': {
329
332
  'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'quantity_precision'))),
330
333
  'price': self.safe_number(market, 'price_increment'),
334
+ 'cost': self.parse_number(self.parse_precision(self.safe_string(market, 'cost_precision'))),
331
335
  },
332
336
  'limits': {
333
337
  'leverage': {
@@ -1135,14 +1139,15 @@ class probit(Exchange, ImplicitAPI):
1135
1139
 
1136
1140
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1137
1141
  """
1138
- :see: https://docs-en.probit.com/reference/order-1
1139
1142
  create a trade order
1143
+ :see: https://docs-en.probit.com/reference/order-1
1140
1144
  :param str symbol: unified symbol of the market to create an order in
1141
1145
  :param str type: 'market' or 'limit'
1142
1146
  :param str side: 'buy' or 'sell'
1143
- :param float amount: how much of currency you want to trade in units of base currency
1147
+ :param float amount: how much you want to trade in units of the base currency
1144
1148
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1145
1149
  :param dict [params]: extra parameters specific to the exchange API endpoint
1150
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
1146
1151
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1147
1152
  """
1148
1153
  await self.load_markets()
@@ -1159,27 +1164,30 @@ class probit(Exchange, ImplicitAPI):
1159
1164
  clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_order_id')
1160
1165
  if clientOrderId is not None:
1161
1166
  request['client_order_id'] = clientOrderId
1162
- costToPrecision = None
1167
+ quoteAmount = None
1163
1168
  if type == 'limit':
1164
1169
  request['limit_price'] = self.price_to_precision(symbol, price)
1165
1170
  request['quantity'] = self.amount_to_precision(symbol, amount)
1166
1171
  elif type == 'market':
1167
1172
  # for market buy it requires the amount of quote currency to spend
1168
1173
  if side == 'buy':
1169
- cost = self.safe_number(params, 'cost')
1170
- createMarketBuyOrderRequiresPrice = self.safe_value(self.options, 'createMarketBuyOrderRequiresPrice', True)
1171
- if createMarketBuyOrderRequiresPrice:
1172
- if price is not None:
1173
- if cost is None:
1174
- amountString = self.number_to_string(amount)
1175
- priceString = self.number_to_string(price)
1176
- cost = self.parse_number(Precise.string_mul(amountString, priceString))
1177
- elif cost is None:
1178
- raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options["createMarketBuyOrderRequiresPrice"] = False and supply the total cost value in the "amount" argument or in the "cost" extra parameter(the exchange-specific behaviour)')
1174
+ createMarketBuyOrderRequiresPrice = True
1175
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1176
+ cost = self.safe_string(params, 'cost')
1177
+ params = self.omit(params, 'cost')
1178
+ if cost is not None:
1179
+ quoteAmount = self.cost_to_precision(symbol, cost)
1180
+ elif createMarketBuyOrderRequiresPrice:
1181
+ if price is None:
1182
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
1183
+ else:
1184
+ amountString = self.number_to_string(amount)
1185
+ priceString = self.number_to_string(price)
1186
+ costRequest = Precise.string_mul(amountString, priceString)
1187
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
1179
1188
  else:
1180
- cost = amount if (cost is None) else cost
1181
- costToPrecision = self.cost_to_precision(symbol, cost)
1182
- request['cost'] = costToPrecision
1189
+ quoteAmount = self.cost_to_precision(symbol, amount)
1190
+ request['cost'] = quoteAmount
1183
1191
  else:
1184
1192
  request['quantity'] = self.amount_to_precision(symbol, amount)
1185
1193
  query = self.omit(params, ['timeInForce', 'time_in_force', 'clientOrderId', 'client_order_id'])
@@ -1211,7 +1219,7 @@ class probit(Exchange, ImplicitAPI):
1211
1219
  # returned by the exchange on market buys
1212
1220
  if (type == 'market') and (side == 'buy'):
1213
1221
  order['amount'] = None
1214
- order['cost'] = self.parse_number(costToPrecision)
1222
+ order['cost'] = self.parse_number(quoteAmount)
1215
1223
  order['remaining'] = None
1216
1224
  return order
1217
1225
 
@@ -1011,15 +1011,19 @@ class tokocrypto(Exchange, ImplicitAPI):
1011
1011
  responseInner = self.publicGetOpenV1MarketTrades(self.extend(request, params))
1012
1012
  data = self.safe_value(responseInner, 'data', {})
1013
1013
  return self.parse_trades(data, market, since, limit)
1014
+ if limit is not None:
1015
+ request['limit'] = limit # default = 500, maximum = 1000
1014
1016
  defaultMethod = 'binanceGetTrades'
1015
1017
  method = self.safe_string(self.options, 'fetchTradesMethod', defaultMethod)
1018
+ response = None
1016
1019
  if (method == 'binanceGetAggTrades') and (since is not None):
1017
1020
  request['startTime'] = since
1018
1021
  # https://github.com/ccxt/ccxt/issues/6400
1019
1022
  # https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list
1020
1023
  request['endTime'] = self.sum(since, 3600000)
1021
- if limit is not None:
1022
- request['limit'] = limit # default = 500, maximum = 1000
1024
+ response = await self.binanceGetAggTrades(self.extend(request, params))
1025
+ else:
1026
+ response = await self.binanceGetTrades(self.extend(request, params))
1023
1027
  #
1024
1028
  # Caveats:
1025
1029
  # - default limit(500) applies only if no other parameters set, trades up
@@ -1029,7 +1033,6 @@ class tokocrypto(Exchange, ImplicitAPI):
1029
1033
  # - 'tradeId' accepted and returned by self method is "aggregate" trade id
1030
1034
  # which is different from actual trade id
1031
1035
  # - setting both fromId and time window results in error
1032
- response = await getattr(self, method)(self.extend(request, params))
1033
1036
  #
1034
1037
  # aggregate trades
1035
1038
  #
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.1.84'
7
+ __version__ = '4.1.86'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -171,6 +171,8 @@ class Exchange(object):
171
171
  ws_proxy = None
172
172
  wssProxy = None
173
173
  wss_proxy = None
174
+ wsSocksProxy = None
175
+ ws_socks_proxy = None
174
176
  #
175
177
  userAgents = {
176
178
  'chrome': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
@@ -1822,26 +1824,34 @@ class Exchange(object):
1822
1824
  usedProxies = []
1823
1825
  wsProxy = None
1824
1826
  wssProxy = None
1825
- # wsProxy
1827
+ wsSocksProxy = None
1828
+ # ws proxy
1826
1829
  if self.wsProxy is not None:
1827
1830
  usedProxies.append('wsProxy')
1828
1831
  wsProxy = self.wsProxy
1829
1832
  if self.ws_proxy is not None:
1830
1833
  usedProxies.append('ws_proxy')
1831
1834
  wsProxy = self.ws_proxy
1832
- # wsProxy
1835
+ # wss proxy
1833
1836
  if self.wssProxy is not None:
1834
1837
  usedProxies.append('wssProxy')
1835
1838
  wssProxy = self.wssProxy
1836
1839
  if self.wss_proxy is not None:
1837
1840
  usedProxies.append('wss_proxy')
1838
1841
  wssProxy = self.wss_proxy
1842
+ # ws socks proxy
1843
+ if self.wsSocksProxy is not None:
1844
+ usedProxies.append('wsSocksProxy')
1845
+ wsSocksProxy = self.wsSocksProxy
1846
+ if self.ws_socks_proxy is not None:
1847
+ usedProxies.append('ws_socks_proxy')
1848
+ wsSocksProxy = self.ws_socks_proxy
1839
1849
  # check
1840
1850
  length = len(usedProxies)
1841
1851
  if length > 1:
1842
1852
  joinedProxyNames = ','.join(usedProxies)
1843
- raise ExchangeError(self.id + ' you have multiple conflicting settings(' + joinedProxyNames + '), please use only one from: wsProxy, wssProxy')
1844
- return [wsProxy, wssProxy]
1853
+ raise ExchangeError(self.id + ' you have multiple conflicting settings(' + joinedProxyNames + '), please use only one from: wsProxy, wssProxy, socksProxy')
1854
+ return [wsProxy, wssProxy, wsSocksProxy]
1845
1855
 
1846
1856
  def check_conflicting_proxies(self, proxyAgentSet, proxyUrlSet):
1847
1857
  if proxyAgentSet and proxyUrlSet:
@@ -3853,6 +3863,9 @@ class Exchange(object):
3853
3863
  def close_all_positions(self, params={}):
3854
3864
  raise NotSupported(self.id + ' closeAllPositions() is not supported yet')
3855
3865
 
3866
+ def fetch_l3_order_book(self, symbol: str, limit: Int = None, params={}):
3867
+ raise BadRequest(self.id + ' fetchL3OrderBook() is not supported yet')
3868
+
3856
3869
  def parse_last_price(self, price, market: Market = None):
3857
3870
  raise NotSupported(self.id + ' parseLastPrice() is not supported yet')
3858
3871
 
@@ -4336,8 +4349,8 @@ class Exchange(object):
4336
4349
  def handle_time_in_force(self, params={}):
4337
4350
  """
4338
4351
  * @ignore
4339
- * * Must add timeInForce to self.options to use self method
4340
- :return string returns: the exchange specific value for timeInForce
4352
+ * Must add timeInForce to self.options to use self method
4353
+ :returns str: returns the exchange specific value for timeInForce
4341
4354
  """
4342
4355
  timeInForce = self.safe_string_upper(params, 'timeInForce') # supported values GTC, IOC, PO
4343
4356
  if timeInForce is not None:
@@ -4350,7 +4363,7 @@ class Exchange(object):
4350
4363
  def convert_type_to_account(self, account):
4351
4364
  """
4352
4365
  * @ignore
4353
- * * Must add accountsByType to self.options to use self method
4366
+ * Must add accountsByType to self.options to use self method
4354
4367
  :param str account: key for account name in self.options['accountsByType']
4355
4368
  :returns: the exchange specific account name or the isolated margin id for transfers
4356
4369
  """
ccxt/binance.py CHANGED
@@ -4181,7 +4181,7 @@ class binance(Exchange, ImplicitAPI):
4181
4181
  """
4182
4182
  *contract only* create a list of trade orders
4183
4183
  :see: https://binance-docs.github.io/apidocs/futures/en/#place-multiple-orders-trade
4184
- :param array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
4184
+ :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
4185
4185
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4186
4186
  """
4187
4187
  self.load_markets()