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