ccxt 4.4.33__py2.py3-none-any.whl → 4.4.35__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 (100) hide show
  1. ccxt/__init__.py +3 -1
  2. ccxt/abstract/bingx.py +17 -0
  3. ccxt/abstract/bitbank.py +5 -0
  4. ccxt/abstract/bitfinex2.py +1 -0
  5. ccxt/abstract/bitpanda.py +0 -12
  6. ccxt/abstract/bitrue.py +3 -3
  7. ccxt/abstract/ellipx.py +25 -0
  8. ccxt/abstract/okx.py +1 -0
  9. ccxt/abstract/onetrading.py +0 -12
  10. ccxt/abstract/xt.py +5 -5
  11. ccxt/alpaca.py +2 -0
  12. ccxt/async_support/__init__.py +3 -1
  13. ccxt/async_support/alpaca.py +2 -0
  14. ccxt/async_support/base/exchange.py +1 -1
  15. ccxt/async_support/binance.py +19 -15
  16. ccxt/async_support/bingx.py +479 -146
  17. ccxt/async_support/bitbank.py +5 -0
  18. ccxt/async_support/bitbns.py +2 -0
  19. ccxt/async_support/bitfinex2.py +1 -0
  20. ccxt/async_support/bitget.py +174 -40
  21. ccxt/async_support/bitmex.py +3 -1
  22. ccxt/async_support/bitopro.py +3 -0
  23. ccxt/async_support/bitrue.py +3 -2
  24. ccxt/async_support/btcmarkets.py +5 -3
  25. ccxt/async_support/btcturk.py +19 -19
  26. ccxt/async_support/bybit.py +13 -10
  27. ccxt/async_support/cex.py +13 -4
  28. ccxt/async_support/coinbase.py +3 -2
  29. ccxt/async_support/coinex.py +1 -0
  30. ccxt/async_support/coinone.py +7 -7
  31. ccxt/async_support/coinsph.py +7 -7
  32. ccxt/async_support/coinspot.py +39 -39
  33. ccxt/async_support/cryptocom.py +36 -34
  34. ccxt/async_support/ellipx.py +1828 -0
  35. ccxt/async_support/gate.py +143 -39
  36. ccxt/async_support/hyperliquid.py +70 -11
  37. ccxt/async_support/idex.py +3 -4
  38. ccxt/async_support/kraken.py +58 -49
  39. ccxt/async_support/krakenfutures.py +3 -1
  40. ccxt/async_support/kucoin.py +1 -1
  41. ccxt/async_support/okcoin.py +2 -0
  42. ccxt/async_support/okx.py +15 -10
  43. ccxt/async_support/onetrading.py +67 -370
  44. ccxt/async_support/paradex.py +2 -0
  45. ccxt/async_support/phemex.py +16 -0
  46. ccxt/async_support/poloniex.py +3 -1
  47. ccxt/async_support/poloniexfutures.py +3 -1
  48. ccxt/async_support/vertex.py +2 -0
  49. ccxt/async_support/woo.py +69 -69
  50. ccxt/async_support/xt.py +10 -10
  51. ccxt/base/exchange.py +28 -7
  52. ccxt/binance.py +19 -15
  53. ccxt/bingx.py +479 -146
  54. ccxt/bitbank.py +5 -0
  55. ccxt/bitbns.py +2 -0
  56. ccxt/bitfinex2.py +1 -0
  57. ccxt/bitget.py +174 -40
  58. ccxt/bitmex.py +3 -1
  59. ccxt/bitopro.py +3 -0
  60. ccxt/bitrue.py +3 -2
  61. ccxt/btcmarkets.py +5 -3
  62. ccxt/btcturk.py +19 -19
  63. ccxt/bybit.py +13 -10
  64. ccxt/cex.py +13 -4
  65. ccxt/coinbase.py +3 -2
  66. ccxt/coinex.py +1 -0
  67. ccxt/coinone.py +7 -7
  68. ccxt/coinsph.py +7 -7
  69. ccxt/coinspot.py +39 -39
  70. ccxt/cryptocom.py +36 -34
  71. ccxt/ellipx.py +1828 -0
  72. ccxt/gate.py +143 -39
  73. ccxt/hyperliquid.py +70 -11
  74. ccxt/idex.py +3 -4
  75. ccxt/kraken.py +58 -49
  76. ccxt/krakenfutures.py +3 -1
  77. ccxt/kucoin.py +1 -1
  78. ccxt/okcoin.py +2 -0
  79. ccxt/okx.py +15 -10
  80. ccxt/onetrading.py +67 -370
  81. ccxt/paradex.py +2 -0
  82. ccxt/phemex.py +16 -0
  83. ccxt/poloniex.py +3 -1
  84. ccxt/poloniexfutures.py +3 -1
  85. ccxt/pro/__init__.py +1 -1
  86. ccxt/pro/bitrue.py +13 -11
  87. ccxt/pro/idex.py +15 -0
  88. ccxt/pro/probit.py +58 -68
  89. ccxt/pro/woo.py +15 -15
  90. ccxt/test/tests_async.py +29 -2
  91. ccxt/test/tests_helpers.py +0 -2
  92. ccxt/test/tests_sync.py +29 -2
  93. ccxt/vertex.py +2 -0
  94. ccxt/woo.py +69 -69
  95. ccxt/xt.py +10 -10
  96. {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/METADATA +9 -8
  97. {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/RECORD +100 -97
  98. {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/LICENSE.txt +0 -0
  99. {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/WHEEL +0 -0
  100. {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/top_level.txt +0 -0
@@ -59,6 +59,7 @@ class bingx(Exchange, ImplicitAPI):
59
59
  'createOrders': True,
60
60
  'createOrderWithTakeProfitAndStopLoss': True,
61
61
  'createStopLossOrder': True,
62
+ 'createStopOrder': True,
62
63
  'createTakeProfitOrder': True,
63
64
  'createTrailingAmountOrder': True,
64
65
  'createTrailingPercentOrder': True,
@@ -212,6 +213,8 @@ class bingx(Exchange, ImplicitAPI):
212
213
  'get': {
213
214
  'ticker/price': 1,
214
215
  'market/historicalTrades': 1,
216
+ 'market/markPriceKlines': 1,
217
+ 'trade/multiAssetsRules': 1,
215
218
  },
216
219
  },
217
220
  'private': {
@@ -220,12 +223,24 @@ class bingx(Exchange, ImplicitAPI):
220
223
  'market/markPriceKlines': 1,
221
224
  'trade/batchCancelReplace': 5,
222
225
  'trade/fullOrder': 2,
226
+ 'maintMarginRatio': 2,
227
+ 'trade/positionHistory': 2,
223
228
  'positionMargin/history': 2,
229
+ 'twap/openOrders': 5,
230
+ 'twap/historyOrders': 5,
231
+ 'twap/orderDetail': 5,
232
+ 'trade/assetMode': 5,
233
+ 'user/marginAssets': 5,
224
234
  },
225
235
  'post': {
226
236
  'trade/cancelReplace': 2,
227
237
  'positionSide/dual': 5,
238
+ 'trade/batchCancelReplace': 5,
228
239
  'trade/closePosition': 2,
240
+ 'trade/getVst': 5,
241
+ 'twap/order': 5,
242
+ 'twap/cancelOrder': 5,
243
+ 'trade/assetMode': 5,
229
244
  },
230
245
  },
231
246
  },
@@ -258,6 +273,7 @@ class bingx(Exchange, ImplicitAPI):
258
273
  'trade/forceOrders': 1,
259
274
  'trade/allOrders': 2,
260
275
  'trade/allFillOrders': 2,
276
+ 'trade/fillHistory': 2,
261
277
  'user/income/export': 2,
262
278
  'user/commissionRate': 2,
263
279
  'quote/bookTicker': 1,
@@ -315,12 +331,13 @@ class bingx(Exchange, ImplicitAPI):
315
331
  'post': {
316
332
  'trade/order': 2,
317
333
  'trade/leverage': 2,
334
+ 'trade/allOpenOrders': 2,
318
335
  'trade/closeAllPositions': 2,
319
336
  'trade/marginType': 2,
320
337
  'trade/positionMargin': 2,
321
338
  },
322
339
  'delete': {
323
- 'trade/allOpenOrders': 2,
340
+ 'trade/allOpenOrders': 2, # post method in doc
324
341
  'trade/cancelOrder': 2,
325
342
  },
326
343
  },
@@ -364,6 +381,7 @@ class bingx(Exchange, ImplicitAPI):
364
381
  'get': {
365
382
  'list': 10,
366
383
  'assets': 2,
384
+ 'allAccountBalance': 2,
367
385
  },
368
386
  'post': {
369
387
  'create': 10,
@@ -513,6 +531,136 @@ class bingx(Exchange, ImplicitAPI):
513
531
  'MATIC': 'POLYGON',
514
532
  },
515
533
  },
534
+ 'features': {
535
+ 'defaultForLinear': {
536
+ 'sandbox': True,
537
+ 'createOrder': {
538
+ 'marginMode': False,
539
+ 'triggerPrice': True,
540
+ 'triggerPriceType': {
541
+ 'last': True,
542
+ 'mark': True,
543
+ 'index': True,
544
+ },
545
+ 'triggerDirection': False,
546
+ 'stopLossPrice': True,
547
+ 'takeProfitPrice': True,
548
+ 'attachedStopLossTakeProfit': {
549
+ 'triggerPriceType': {
550
+ 'last': True,
551
+ 'mark': True,
552
+ 'index': True,
553
+ },
554
+ 'limitPrice': True,
555
+ },
556
+ 'timeInForce': {
557
+ 'GTC': True,
558
+ 'IOC': True,
559
+ 'FOK': True,
560
+ 'PO': True,
561
+ 'GTD': False,
562
+ },
563
+ 'hedged': True,
564
+ 'trailing': True,
565
+ },
566
+ 'createOrders': {
567
+ 'max': 5,
568
+ },
569
+ 'fetchMyTrades': {
570
+ 'marginMode': False,
571
+ 'limit': 512, # 512 days for 'allFillOrders', 1000 days for 'fillOrders'
572
+ 'daysBack': 30, # 30 for 'allFillOrders', 7 for 'fillHistory'
573
+ 'untilDays': 30, # 30 for 'allFillOrders', 7 for 'fillHistory'
574
+ },
575
+ 'fetchOrder': {
576
+ 'marginMode': False,
577
+ 'trigger': False,
578
+ 'trailing': False,
579
+ },
580
+ 'fetchOpenOrders': {
581
+ 'marginMode': False,
582
+ 'limit': None,
583
+ 'trigger': False,
584
+ 'trailing': False,
585
+ },
586
+ 'fetchOrders': {
587
+ 'marginMode': False,
588
+ 'limit': 1000,
589
+ 'daysBack': 20000, # since epoch
590
+ 'untilDays': 7,
591
+ 'trigger': False,
592
+ 'trailing': False,
593
+ },
594
+ 'fetchClosedOrders': {
595
+ 'marginMode': False,
596
+ 'limit': 1000,
597
+ 'daysBackClosed': None,
598
+ 'daysBackCanceled': None,
599
+ 'untilDays': 7,
600
+ 'trigger': False,
601
+ 'trailing': False,
602
+ },
603
+ 'fetchOHLCV': {
604
+ 'limit': 1440,
605
+ },
606
+ },
607
+ 'defaultForInverse': {
608
+ 'extends': 'defaultForLinear',
609
+ 'fetchMyTrades': {
610
+ 'limit': 1000,
611
+ 'daysBack': None,
612
+ 'untilDays': None,
613
+ },
614
+ 'fetchOHLCV': {
615
+ 'limit': 1440,
616
+ },
617
+ 'fetchOrders': None,
618
+ 'fetchClosedOrders': {
619
+ 'marginMode': False,
620
+ 'limit': 1000,
621
+ 'daysBackClosed': None,
622
+ 'daysBackCanceled': None,
623
+ 'untilDays': 7,
624
+ 'trigger': False,
625
+ 'trailing': False,
626
+ },
627
+ },
628
+ #
629
+ 'spot': {
630
+ 'extends': 'defaultForLinear',
631
+ 'createOrder': {
632
+ 'triggerPriceType': None,
633
+ 'attachedStopLossTakeProfit': None,
634
+ 'trailing': False,
635
+ },
636
+ 'fetchMyTrades': {
637
+ 'limit': 1000,
638
+ 'daysBack': 1,
639
+ 'untilDays': 1,
640
+ },
641
+ 'fetchOrders': None,
642
+ 'fetchClosedOrders': {
643
+ 'limit': 100,
644
+ 'untilDays': None,
645
+ },
646
+ },
647
+ 'swap': {
648
+ 'linear': {
649
+ 'extends': 'defaultForLinear',
650
+ },
651
+ 'inverse': {
652
+ 'extends': 'defaultForInverse',
653
+ },
654
+ },
655
+ 'future': {
656
+ 'linear': {
657
+ 'extends': 'defaultForLinear',
658
+ },
659
+ 'inverse': {
660
+ 'extends': 'defaultForInverse',
661
+ },
662
+ },
663
+ },
516
664
  })
517
665
 
518
666
  async def fetch_time(self, params={}):
@@ -2451,6 +2599,9 @@ class bingx(Exchange, ImplicitAPI):
2451
2599
  }
2452
2600
  isMarketOrder = type == 'MARKET'
2453
2601
  isSpot = marketType == 'spot'
2602
+ isTwapOrder = type == 'TWAP'
2603
+ if isTwapOrder and isSpot:
2604
+ raise BadSymbol(self.id + ' createOrder() twap order supports swap contracts only')
2454
2605
  stopLossPrice = self.safe_string(params, 'stopLossPrice')
2455
2606
  takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
2456
2607
  triggerPrice = self.safe_string_2(params, 'stopPrice', 'triggerPrice')
@@ -2499,6 +2650,26 @@ class bingx(Exchange, ImplicitAPI):
2499
2650
  request['type'] = 'TAKE_STOP_MARKET'
2500
2651
  request['stopPrice'] = self.parse_to_numeric(self.price_to_precision(symbol, stopTakePrice))
2501
2652
  else:
2653
+ if isTwapOrder:
2654
+ twapRequest: dict = {
2655
+ 'symbol': request['symbol'],
2656
+ 'side': request['side'],
2657
+ 'positionSide': 'LONG' if (side == 'buy') else 'SHORT',
2658
+ 'triggerPrice': self.parse_to_numeric(self.price_to_precision(symbol, triggerPrice)),
2659
+ 'totalAmount': self.parse_to_numeric(self.amount_to_precision(symbol, amount)),
2660
+ }
2661
+ # {
2662
+ # "symbol": "LTC-USDT",
2663
+ # "side": "BUY",
2664
+ # "positionSide": "LONG",
2665
+ # "priceType": "constant",
2666
+ # "priceVariance": "10",
2667
+ # "triggerPrice": "120",
2668
+ # "interval": 8,
2669
+ # "amountPerOrder": "0.5",
2670
+ # "totalAmount": "1"
2671
+ # }
2672
+ return self.extend(twapRequest, params)
2502
2673
  if timeInForce == 'FOK':
2503
2674
  request['timeInForce'] = 'FOK'
2504
2675
  trailingAmount = self.safe_string(params, 'trailingAmount')
@@ -2596,6 +2767,7 @@ class bingx(Exchange, ImplicitAPI):
2596
2767
  https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Trade%20order
2597
2768
  https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Create%20an%20Order
2598
2769
  https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Trade%20order
2770
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Place%20TWAP%20Order
2599
2771
 
2600
2772
  :param str symbol: unified symbol of the market to create an order in
2601
2773
  :param str type: 'market' or 'limit'
@@ -2633,6 +2805,8 @@ class bingx(Exchange, ImplicitAPI):
2633
2805
  response = await self.swapV2PrivatePostTradeOrderTest(request)
2634
2806
  elif market['inverse']:
2635
2807
  response = await self.cswapV1PrivatePostTradeOrder(request)
2808
+ elif type == 'twap':
2809
+ response = await self.swapV1PrivatePostTwapOrder(request)
2636
2810
  else:
2637
2811
  response = await self.swapV2PrivatePostTradeOrder(request)
2638
2812
  else:
@@ -2690,6 +2864,17 @@ class bingx(Exchange, ImplicitAPI):
2690
2864
  # "timeInForce": ""
2691
2865
  # }
2692
2866
  #
2867
+ # twap order
2868
+ #
2869
+ # {
2870
+ # "code": 0,
2871
+ # "msg": "",
2872
+ # "timestamp": 1732693774386,
2873
+ # "data": {
2874
+ # "mainOrderId": "4633860139993029715"
2875
+ # }
2876
+ # }
2877
+ #
2693
2878
  if isinstance(response, str):
2694
2879
  # broken api engine : order-ids are too long numbers(i.e. 1742930526912864656)
2695
2880
  # and json.loadscan not handle them in JS, so we have to use .parseJson
@@ -2702,7 +2887,7 @@ class bingx(Exchange, ImplicitAPI):
2702
2887
  if market['inverse']:
2703
2888
  result = response
2704
2889
  else:
2705
- result = self.safe_dict(data, 'order', {})
2890
+ result = self.safe_dict(data, 'order', data)
2706
2891
  else:
2707
2892
  result = data
2708
2893
  return self.parse_order(result, market)
@@ -3119,9 +3304,9 @@ class bingx(Exchange, ImplicitAPI):
3119
3304
  if market is None:
3120
3305
  market = self.safe_market(marketId, None, None, marketType)
3121
3306
  side = self.safe_string_lower_2(order, 'side', 'S')
3122
- timestamp = self.safe_integer_n(order, ['time', 'transactTime', 'E'])
3307
+ timestamp = self.safe_integer_n(order, ['time', 'transactTime', 'E', 'createdTime'])
3123
3308
  lastTradeTimestamp = self.safe_integer_2(order, 'updateTime', 'T')
3124
- statusId = self.safe_string_upper_2(order, 'status', 'X')
3309
+ statusId = self.safe_string_upper_n(order, ['status', 'X', 'orderStatus'])
3125
3310
  feeCurrencyCode = self.safe_string_2(order, 'feeAsset', 'N')
3126
3311
  feeCost = self.safe_string_n(order, ['fee', 'commission', 'n'])
3127
3312
  if (feeCurrencyCode is None):
@@ -3162,7 +3347,7 @@ class bingx(Exchange, ImplicitAPI):
3162
3347
  triggerPrice = None
3163
3348
  return self.safe_order({
3164
3349
  'info': info,
3165
- 'id': self.safe_string_2(order, 'orderId', 'i'),
3350
+ 'id': self.safe_string_n(order, ['orderId', 'i', 'mainOrderId']),
3166
3351
  'clientOrderId': self.safe_string_n(order, ['clientOrderID', 'clientOrderId', 'origClientOrderId', 'c']),
3167
3352
  'symbol': self.safe_symbol(marketId, market, '-', marketType),
3168
3353
  'timestamp': timestamp,
@@ -3180,7 +3365,7 @@ class bingx(Exchange, ImplicitAPI):
3180
3365
  'takeProfitPrice': takeProfitPrice,
3181
3366
  'average': self.safe_string_2(order, 'avgPrice', 'ap'),
3182
3367
  'cost': self.safe_string(order, 'cummulativeQuoteQty'),
3183
- 'amount': self.safe_string_n(order, ['origQty', 'q', 'quantity']),
3368
+ 'amount': self.safe_string_n(order, ['origQty', 'q', 'quantity', 'totalAmount']),
3184
3369
  'filled': self.safe_string_2(order, 'executedQty', 'z'),
3185
3370
  'remaining': None,
3186
3371
  'status': self.parse_order_status(statusId),
@@ -3197,6 +3382,7 @@ class bingx(Exchange, ImplicitAPI):
3197
3382
  'NEW': 'open',
3198
3383
  'PENDING': 'open',
3199
3384
  'PARTIALLY_FILLED': 'open',
3385
+ 'RUNNING': 'open',
3200
3386
  'FILLED': 'closed',
3201
3387
  'CANCELED': 'canceled',
3202
3388
  'CANCELLED': 'canceled',
@@ -3211,6 +3397,7 @@ class bingx(Exchange, ImplicitAPI):
3211
3397
  https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20Order
3212
3398
  https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20Order
3213
3399
  https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Cancel%20an%20Order
3400
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20TWAP%20Order
3214
3401
 
3215
3402
  :param str id: order id
3216
3403
  :param str symbol: unified symbol of the market the order was made in
@@ -3218,31 +3405,64 @@ class bingx(Exchange, ImplicitAPI):
3218
3405
  :param str [params.clientOrderId]: a unique id for the order
3219
3406
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3220
3407
  """
3221
- if symbol is None:
3222
- raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
3223
3408
  await self.load_markets()
3224
- market = self.market(symbol)
3225
- request: dict = {
3226
- 'symbol': market['id'],
3227
- }
3228
- clientOrderId = self.safe_string_2(params, 'clientOrderId', 'clientOrderID')
3229
- params = self.omit(params, ['clientOrderId'])
3230
- if clientOrderId is not None:
3231
- request['clientOrderID'] = clientOrderId
3232
- else:
3233
- request['orderId'] = id
3409
+ isTwapOrder = self.safe_bool(params, 'twap', False)
3410
+ params = self.omit(params, 'twap')
3234
3411
  response = None
3235
- type = None
3236
- subType = None
3237
- type, params = self.handle_market_type_and_params('cancelOrder', market, params)
3238
- subType, params = self.handle_sub_type_and_params('cancelOrder', market, params)
3239
- if type == 'spot':
3240
- response = await self.spotV1PrivatePostTradeCancel(self.extend(request, params))
3412
+ market = None
3413
+ if isTwapOrder:
3414
+ twapRequest: dict = {
3415
+ 'mainOrderId': id,
3416
+ }
3417
+ response = await self.swapV1PrivatePostTwapCancelOrder(self.extend(twapRequest, params))
3418
+ #
3419
+ # {
3420
+ # "code": 0,
3421
+ # "msg": "",
3422
+ # "timestamp": 1702731661854,
3423
+ # "data": {
3424
+ # "symbol": "BNB-USDT",
3425
+ # "side": "BUY",
3426
+ # "positionSide": "LONG",
3427
+ # "priceType": "constant",
3428
+ # "priceVariance": "2000",
3429
+ # "triggerPrice": "68000",
3430
+ # "interval": 8,
3431
+ # "amountPerOrder": "0.111",
3432
+ # "totalAmount": "0.511",
3433
+ # "orderStatus": "Running",
3434
+ # "executedQty": "0.1",
3435
+ # "duration": 800,
3436
+ # "maxDuration": 9000,
3437
+ # "createdTime": 1702731661854,
3438
+ # "updateTime": 1702731661854
3439
+ # }
3440
+ # }
3441
+ #
3241
3442
  else:
3242
- if subType == 'inverse':
3243
- response = await self.cswapV1PrivateDeleteTradeCancelOrder(self.extend(request, params))
3443
+ if symbol is None:
3444
+ raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
3445
+ market = self.market(symbol)
3446
+ request: dict = {
3447
+ 'symbol': market['id'],
3448
+ }
3449
+ clientOrderId = self.safe_string_2(params, 'clientOrderId', 'clientOrderID')
3450
+ params = self.omit(params, ['clientOrderId'])
3451
+ if clientOrderId is not None:
3452
+ request['clientOrderID'] = clientOrderId
3453
+ else:
3454
+ request['orderId'] = id
3455
+ type = None
3456
+ subType = None
3457
+ type, params = self.handle_market_type_and_params('cancelOrder', market, params)
3458
+ subType, params = self.handle_sub_type_and_params('cancelOrder', market, params)
3459
+ if type == 'spot':
3460
+ response = await self.spotV1PrivatePostTradeCancel(self.extend(request, params))
3244
3461
  else:
3245
- response = await self.swapV2PrivateDeleteTradeOrder(self.extend(request, params))
3462
+ if subType == 'inverse':
3463
+ response = await self.cswapV1PrivateDeleteTradeCancelOrder(self.extend(request, params))
3464
+ else:
3465
+ response = await self.swapV2PrivateDeleteTradeOrder(self.extend(request, params))
3246
3466
  #
3247
3467
  # spot
3248
3468
  #
@@ -3632,131 +3852,167 @@ class bingx(Exchange, ImplicitAPI):
3632
3852
  https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Query%20Order%20details
3633
3853
  https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20Order%20details
3634
3854
  https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20Order
3855
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#TWAP%20Order%20Details
3635
3856
 
3636
3857
  :param str id: the order id
3637
3858
  :param str symbol: unified symbol of the market the order was made in
3638
3859
  :param dict [params]: extra parameters specific to the exchange API endpoint
3860
+ :param boolean [params.twap]: if fetching twap order
3639
3861
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3640
3862
  """
3641
- if symbol is None:
3642
- raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
3643
3863
  await self.load_markets()
3644
- market = self.market(symbol)
3645
- request: dict = {
3646
- 'symbol': market['id'],
3647
- 'orderId': id,
3648
- }
3649
- type = None
3650
- subType = None
3864
+ isTwapOrder = self.safe_bool(params, 'twap', False)
3865
+ params = self.omit(params, 'twap')
3651
3866
  response = None
3652
- type, params = self.handle_market_type_and_params('fetchOrder', market, params)
3653
- subType, params = self.handle_sub_type_and_params('fetchOrder', market, params)
3654
- if type == 'spot':
3655
- response = await self.spotV1PrivateGetTradeQuery(self.extend(request, params))
3867
+ market = None
3868
+ if isTwapOrder:
3869
+ twapRequest: dict = {
3870
+ 'mainOrderId': id,
3871
+ }
3872
+ response = await self.swapV1PrivateGetTwapOrderDetail(self.extend(twapRequest, params))
3656
3873
  #
3657
3874
  # {
3658
3875
  # "code": 0,
3659
- # "msg": "",
3876
+ # "msg": "success cancel order",
3877
+ # "timestamp": 1732760856617,
3660
3878
  # "data": {
3661
- # "symbol": "XRP-USDT",
3662
- # "orderId": 1514087361158316032,
3663
- # "price": "0.5",
3664
- # "origQty": "10",
3665
- # "executedQty": "0",
3666
- # "cummulativeQuoteQty": "0",
3667
- # "status": "CANCELED",
3668
- # "type": "LIMIT",
3879
+ # "symbol": "LTC-USDT",
3880
+ # "mainOrderId": "5596903086063901779",
3669
3881
  # "side": "BUY",
3670
- # "time": 1649821532000,
3671
- # "updateTime": 1649821543000,
3672
- # "origQuoteOrderQty": "0",
3673
- # "fee": "0",
3674
- # "feeAsset": "XRP"
3882
+ # "positionSide": "LONG",
3883
+ # "priceType": "constant",
3884
+ # "priceVariance": "10.00",
3885
+ # "triggerPrice": "120.00",
3886
+ # "interval": 8,
3887
+ # "amountPerOrder": "0.5",
3888
+ # "totalAmount": "1.0",
3889
+ # "orderStatus": "Filled",
3890
+ # "executedQty": "1.0",
3891
+ # "duration": 16,
3892
+ # "maxDuration": 86400,
3893
+ # "createdTime": 1732693017000,
3894
+ # "updateTime": 1732693033000
3675
3895
  # }
3676
3896
  # }
3677
3897
  #
3678
3898
  else:
3679
- if subType == 'inverse':
3680
- response = await self.cswapV1PrivateGetTradeOrderDetail(self.extend(request, params))
3899
+ if symbol is None:
3900
+ raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
3901
+ market = self.market(symbol)
3902
+ request: dict = {
3903
+ 'symbol': market['id'],
3904
+ 'orderId': id,
3905
+ }
3906
+ type = None
3907
+ subType = None
3908
+ type, params = self.handle_market_type_and_params('fetchOrder', market, params)
3909
+ subType, params = self.handle_sub_type_and_params('fetchOrder', market, params)
3910
+ if type == 'spot':
3911
+ response = await self.spotV1PrivateGetTradeQuery(self.extend(request, params))
3681
3912
  #
3682
3913
  # {
3683
3914
  # "code": 0,
3684
3915
  # "msg": "",
3685
3916
  # "data": {
3686
- # "order": {
3687
- # "symbol": "SOL-USD",
3688
- # "orderId": "1816342420721254400",
3689
- # "side": "BUY",
3690
- # "positionSide": "Long",
3691
- # "type": "LIMIT",
3692
- # "quantity": 1,
3693
- # "origQty": "",
3694
- # "price": "150",
3695
- # "executedQty": "0",
3696
- # "avgPrice": "0.000",
3697
- # "cumQuote": "",
3698
- # "stopPrice": "",
3699
- # "profit": "0.0000",
3700
- # "commission": "0.0000",
3701
- # "status": "Pending",
3702
- # "time": 1721884753767,
3703
- # "updateTime": 1721884753786,
3704
- # "clientOrderId": "",
3705
- # "leverage": "",
3706
- # "takeProfit": {
3707
- # "type": "TAKE_PROFIT",
3708
- # "quantity": 0,
3709
- # "stopPrice": 0,
3710
- # "price": 0,
3711
- # "workingType": "MARK_PRICE",
3712
- # "stopGuaranteed": ""
3713
- # },
3714
- # "stopLoss": {
3715
- # "type": "STOP",
3716
- # "quantity": 0,
3717
- # "stopPrice": 0,
3718
- # "price": 0,
3719
- # "workingType": "MARK_PRICE",
3720
- # "stopGuaranteed": ""
3721
- # },
3722
- # "advanceAttr": 0,
3723
- # "positionID": 0,
3724
- # "takeProfitEntrustPrice": 0,
3725
- # "stopLossEntrustPrice": 0,
3726
- # "orderType": "",
3727
- # "workingType": "MARK_PRICE"
3728
- # }
3917
+ # "symbol": "XRP-USDT",
3918
+ # "orderId": 1514087361158316032,
3919
+ # "price": "0.5",
3920
+ # "origQty": "10",
3921
+ # "executedQty": "0",
3922
+ # "cummulativeQuoteQty": "0",
3923
+ # "status": "CANCELED",
3924
+ # "type": "LIMIT",
3925
+ # "side": "BUY",
3926
+ # "time": 1649821532000,
3927
+ # "updateTime": 1649821543000,
3928
+ # "origQuoteOrderQty": "0",
3929
+ # "fee": "0",
3930
+ # "feeAsset": "XRP"
3729
3931
  # }
3730
3932
  # }
3731
3933
  #
3732
3934
  else:
3733
- response = await self.swapV2PrivateGetTradeOrder(self.extend(request, params))
3734
- #
3735
- # {
3736
- # "code": 0,
3737
- # "msg": "",
3738
- # "data": {
3739
- # "order": {
3740
- # "symbol": "BTC-USDT",
3741
- # "orderId": 1597597642269917184,
3742
- # "side": "SELL",
3743
- # "positionSide": "LONG",
3744
- # "type": "TAKE_PROFIT_MARKET",
3745
- # "origQty": "1.0000",
3746
- # "price": "0.0",
3747
- # "executedQty": "0.0000",
3748
- # "avgPrice": "0.0",
3749
- # "cumQuote": "",
3750
- # "stopPrice": "16494.0",
3751
- # "profit": "",
3752
- # "commission": "",
3753
- # "status": "FILLED",
3754
- # "time": 1669731935000,
3755
- # "updateTime": 1669752524000
3756
- # }
3757
- # }
3758
- # }
3759
- #
3935
+ if subType == 'inverse':
3936
+ response = await self.cswapV1PrivateGetTradeOrderDetail(self.extend(request, params))
3937
+ #
3938
+ # {
3939
+ # "code": 0,
3940
+ # "msg": "",
3941
+ # "data": {
3942
+ # "order": {
3943
+ # "symbol": "SOL-USD",
3944
+ # "orderId": "1816342420721254400",
3945
+ # "side": "BUY",
3946
+ # "positionSide": "Long",
3947
+ # "type": "LIMIT",
3948
+ # "quantity": 1,
3949
+ # "origQty": "",
3950
+ # "price": "150",
3951
+ # "executedQty": "0",
3952
+ # "avgPrice": "0.000",
3953
+ # "cumQuote": "",
3954
+ # "stopPrice": "",
3955
+ # "profit": "0.0000",
3956
+ # "commission": "0.0000",
3957
+ # "status": "Pending",
3958
+ # "time": 1721884753767,
3959
+ # "updateTime": 1721884753786,
3960
+ # "clientOrderId": "",
3961
+ # "leverage": "",
3962
+ # "takeProfit": {
3963
+ # "type": "TAKE_PROFIT",
3964
+ # "quantity": 0,
3965
+ # "stopPrice": 0,
3966
+ # "price": 0,
3967
+ # "workingType": "MARK_PRICE",
3968
+ # "stopGuaranteed": ""
3969
+ # },
3970
+ # "stopLoss": {
3971
+ # "type": "STOP",
3972
+ # "quantity": 0,
3973
+ # "stopPrice": 0,
3974
+ # "price": 0,
3975
+ # "workingType": "MARK_PRICE",
3976
+ # "stopGuaranteed": ""
3977
+ # },
3978
+ # "advanceAttr": 0,
3979
+ # "positionID": 0,
3980
+ # "takeProfitEntrustPrice": 0,
3981
+ # "stopLossEntrustPrice": 0,
3982
+ # "orderType": "",
3983
+ # "workingType": "MARK_PRICE"
3984
+ # }
3985
+ # }
3986
+ # }
3987
+ #
3988
+ else:
3989
+ response = await self.swapV2PrivateGetTradeOrder(self.extend(request, params))
3990
+ #
3991
+ # {
3992
+ # "code": 0,
3993
+ # "msg": "",
3994
+ # "data": {
3995
+ # "order": {
3996
+ # "symbol": "BTC-USDT",
3997
+ # "orderId": 1597597642269917184,
3998
+ # "side": "SELL",
3999
+ # "positionSide": "LONG",
4000
+ # "type": "TAKE_PROFIT_MARKET",
4001
+ # "origQty": "1.0000",
4002
+ # "price": "0.0",
4003
+ # "executedQty": "0.0000",
4004
+ # "avgPrice": "0.0",
4005
+ # "cumQuote": "",
4006
+ # "stopPrice": "16494.0",
4007
+ # "profit": "",
4008
+ # "commission": "",
4009
+ # "status": "FILLED",
4010
+ # "time": 1669731935000,
4011
+ # "updateTime": 1669752524000
4012
+ # }
4013
+ # }
4014
+ # }
4015
+ #
3760
4016
  data = self.safe_dict(response, 'data', {})
3761
4017
  order = self.safe_dict(data, 'order', data)
3762
4018
  return self.parse_order(order, market)
@@ -3765,7 +4021,8 @@ class bingx(Exchange, ImplicitAPI):
3765
4021
  """
3766
4022
  fetches information on multiple orders made by the user
3767
4023
 
3768
- https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#User's%20All%20Orders
4024
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#All%20Orders
4025
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20Order%20history(returns less fields than above)
3769
4026
 
3770
4027
  :param str symbol: unified market symbol of the market orders were made in
3771
4028
  :param int [since]: the earliest time in ms to fetch orders for
@@ -3789,11 +4046,7 @@ class bingx(Exchange, ImplicitAPI):
3789
4046
  request['limit'] = limit
3790
4047
  if since is not None:
3791
4048
  request['startTime'] = since
3792
- until = self.safe_integer(params, 'until') # unified in milliseconds
3793
- endTime = self.safe_integer(params, 'endTime', until) # exchange-specific in milliseconds
3794
- params = self.omit(params, ['endTime', 'until'])
3795
- if endTime is not None:
3796
- request['endTime'] = endTime
4049
+ request, params = self.handle_until_option('endTime', request, params)
3797
4050
  response = await self.swapV1PrivateGetTradeFullOrder(self.extend(request, params))
3798
4051
  #
3799
4052
  # {
@@ -3858,11 +4111,13 @@ class bingx(Exchange, ImplicitAPI):
3858
4111
  https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Current%20Open%20Orders
3859
4112
  https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Current%20All%20Open%20Orders
3860
4113
  https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20all%20current%20pending%20orders
4114
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20TWAP%20Entrusted%20Order
3861
4115
 
3862
4116
  :param str symbol: unified market symbol
3863
4117
  :param int [since]: the earliest time in ms to fetch open orders for
3864
4118
  :param int [limit]: the maximum number of open order structures to retrieve
3865
4119
  :param dict [params]: extra parameters specific to the exchange API endpoint
4120
+ :param boolean [params.twap]: if fetching twap open orders
3866
4121
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
3867
4122
  """
3868
4123
  await self.load_markets()
@@ -3879,7 +4134,11 @@ class bingx(Exchange, ImplicitAPI):
3879
4134
  if type == 'spot':
3880
4135
  response = await self.spotV1PrivateGetTradeOpenOrders(self.extend(request, params))
3881
4136
  else:
3882
- if subType == 'inverse':
4137
+ isTwapOrder = self.safe_bool(params, 'twap', False)
4138
+ params = self.omit(params, 'twap')
4139
+ if isTwapOrder:
4140
+ response = await self.swapV1PrivateGetTwapOpenOrders(self.extend(request, params))
4141
+ elif subType == 'inverse':
3883
4142
  response = await self.cswapV1PrivateGetTradeOpenOrders(self.extend(request, params))
3884
4143
  else:
3885
4144
  response = await self.swapV2PrivateGetTradeOpenOrders(self.extend(request, params))
@@ -3992,8 +4251,38 @@ class bingx(Exchange, ImplicitAPI):
3992
4251
  # }
3993
4252
  # }
3994
4253
  #
4254
+ # twap
4255
+ #
4256
+ # {
4257
+ # "code": 0,
4258
+ # "msg": "",
4259
+ # "timestamp": 1702731661854,
4260
+ # "data": {
4261
+ # "list": [
4262
+ # {
4263
+ # "symbol": "BNB-USDT",
4264
+ # "side": "BUY",
4265
+ # "positionSide": "LONG",
4266
+ # "priceType": "constant",
4267
+ # "priceVariance": "2000",
4268
+ # "triggerPrice": "68000",
4269
+ # "interval": 8,
4270
+ # "amountPerOrder": "0.111",
4271
+ # "totalAmount": "0.511",
4272
+ # "orderStatus": "Running",
4273
+ # "executedQty": "0.1",
4274
+ # "duration": 800,
4275
+ # "maxDuration": 9000,
4276
+ # "createdTime": 1702731661854,
4277
+ # "updateTime": 1702731661854
4278
+ # }
4279
+ # ],
4280
+ # "total": 1
4281
+ # }
4282
+ # }
4283
+ #
3995
4284
  data = self.safe_dict(response, 'data', {})
3996
- orders = self.safe_list(data, 'orders', [])
4285
+ orders = self.safe_list_2(data, 'orders', 'list', [])
3997
4286
  return self.parse_orders(orders, market, since, limit)
3998
4287
 
3999
4288
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
@@ -4046,6 +4335,7 @@ class bingx(Exchange, ImplicitAPI):
4046
4335
  https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20Order%20history
4047
4336
  https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#User's%20History%20Orders
4048
4337
  https://bingx-api.github.io/docs/#/standard/contract-interface.html#Historical%20order
4338
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20TWAP%20Historical%20Orders
4049
4339
 
4050
4340
  :param str [symbol]: unified market symbol of the market orders were made in
4051
4341
  :param int [since]: the earliest time in ms to fetch orders for
@@ -4053,6 +4343,7 @@ class bingx(Exchange, ImplicitAPI):
4053
4343
  :param dict [params]: extra parameters specific to the exchange API endpoint
4054
4344
  :param int [params.until]: the latest time in ms to fetch orders for
4055
4345
  :param boolean [params.standard]: whether to fetch standard contract orders
4346
+ :param boolean [params.twap]: if fetching twap orders
4056
4347
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4057
4348
  """
4058
4349
  if symbol is None:
@@ -4072,6 +4363,8 @@ class bingx(Exchange, ImplicitAPI):
4072
4363
  if standard:
4073
4364
  response = await self.contractV1PrivateGetAllOrders(self.extend(request, params))
4074
4365
  elif type == 'spot':
4366
+ if limit is not None:
4367
+ request['limit'] = limit
4075
4368
  response = await self.spotV1PrivateGetTradeHistoryOrders(self.extend(request, params))
4076
4369
  #
4077
4370
  # {
@@ -4098,7 +4391,46 @@ class bingx(Exchange, ImplicitAPI):
4098
4391
  # }
4099
4392
  #
4100
4393
  else:
4101
- if subType == 'inverse':
4394
+ isTwapOrder = self.safe_bool(params, 'twap', False)
4395
+ params = self.omit(params, 'twap')
4396
+ if isTwapOrder:
4397
+ request['pageIndex'] = 1
4398
+ request['pageSize'] = 100 if (limit is None) else limit
4399
+ request['startTime'] = 1 if (since is None) else since
4400
+ until = self.safe_integer(params, 'until', self.milliseconds())
4401
+ params = self.omit(params, 'until')
4402
+ request['endTime'] = until
4403
+ response = await self.swapV1PrivateGetTwapHistoryOrders(self.extend(request, params))
4404
+ #
4405
+ # {
4406
+ # "code": 0,
4407
+ # "msg": "",
4408
+ # "timestamp": 1702731661854,
4409
+ # "data": {
4410
+ # "list": [
4411
+ # {
4412
+ # "symbol": "BNB-USDT",
4413
+ # "side": "BUY",
4414
+ # "positionSide": "LONG",
4415
+ # "priceType": "constant",
4416
+ # "priceVariance": "2000",
4417
+ # "triggerPrice": "68000",
4418
+ # "interval": 8,
4419
+ # "amountPerOrder": "0.111",
4420
+ # "totalAmount": "0.511",
4421
+ # "orderStatus": "Running",
4422
+ # "executedQty": "0.1",
4423
+ # "duration": 800,
4424
+ # "maxDuration": 9000,
4425
+ # "createdTime": 1702731661854,
4426
+ # "updateTime": 1702731661854
4427
+ # }
4428
+ # ],
4429
+ # "total": 1
4430
+ # }
4431
+ # }
4432
+ #
4433
+ elif subType == 'inverse':
4102
4434
  response = await self.cswapV1PrivateGetTradeOrderHistory(self.extend(request, params))
4103
4435
  #
4104
4436
  # {
@@ -4184,7 +4516,7 @@ class bingx(Exchange, ImplicitAPI):
4184
4516
  # }
4185
4517
  #
4186
4518
  data = self.safe_dict(response, 'data', {})
4187
- orders = self.safe_list(data, 'orders', [])
4519
+ orders = self.safe_list_2(data, 'orders', 'list', [])
4188
4520
  return self.parse_orders(orders, market, since, limit)
4189
4521
 
4190
4522
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
@@ -4862,6 +5194,7 @@ class bingx(Exchange, ImplicitAPI):
4862
5194
 
4863
5195
  https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Query%20transaction%20details
4864
5196
  https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20historical%20transaction%20orders
5197
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20historical%20transaction%20details
4865
5198
  https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20Order%20Trade%20Detail
4866
5199
 
4867
5200
  :param str [symbol]: unified market symbol
@@ -4921,7 +5254,7 @@ class bingx(Exchange, ImplicitAPI):
4921
5254
  startTimeReq = 'startTime' if market['spot'] else 'startTs'
4922
5255
  request[startTimeReq] = since
4923
5256
  elif market['swap']:
4924
- request['startTs'] = now - 7776000000 # 90 days
5257
+ request['startTs'] = now - 30 * 24 * 60 * 60 * 1000 # 30 days for swap
4925
5258
  until = self.safe_integer(params, 'until')
4926
5259
  params = self.omit(params, 'until')
4927
5260
  if until is not None:
@@ -5736,27 +6069,27 @@ class bingx(Exchange, ImplicitAPI):
5736
6069
  path = self.implode_params(path, params)
5737
6070
  url += path
5738
6071
  params = self.omit(params, self.extract_params(path))
6072
+ params['timestamp'] = self.nonce()
5739
6073
  params = self.keysort(params)
5740
6074
  if access == 'public':
5741
- params['timestamp'] = self.nonce()
5742
6075
  if params:
5743
6076
  url += '?' + self.urlencode(params)
5744
6077
  elif access == 'private':
5745
6078
  self.check_required_credentials()
5746
- params['timestamp'] = self.nonce()
6079
+ isJsonContentType = ((type == 'subAccount') and (method == 'POST'))
5747
6080
  parsedParams = self.parse_params(params)
5748
- query = self.urlencode(parsedParams)
5749
6081
  signature = self.hmac(self.encode(self.rawencode(parsedParams)), self.encode(self.secret), hashlib.sha256)
5750
- if params:
5751
- query = '?' + query + '&'
5752
- else:
5753
- query += '?'
5754
- query += 'signature=' + signature
5755
6082
  headers = {
5756
6083
  'X-BX-APIKEY': self.apiKey,
5757
6084
  'X-SOURCE-KEY': self.safe_string(self.options, 'broker', 'CCXT'),
5758
6085
  }
5759
- url += query
6086
+ if isJsonContentType:
6087
+ headers['Content-Type'] = 'application/json'
6088
+ parsedParams['signature'] = signature
6089
+ body = self.json(parsedParams)
6090
+ else:
6091
+ query = self.urlencode(parsedParams)
6092
+ url += '?' + query + '&signature=' + signature
5760
6093
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
5761
6094
 
5762
6095
  def nonce(self):