ccxt 4.4.40__py2.py3-none-any.whl → 4.4.42__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 (173) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/binance.py +3 -0
  3. ccxt/abstract/binancecoinm.py +3 -0
  4. ccxt/abstract/binanceus.py +3 -0
  5. ccxt/abstract/binanceusdm.py +3 -0
  6. ccxt/abstract/bitmart.py +2 -0
  7. ccxt/abstract/okx.py +5 -0
  8. ccxt/ace.py +1 -1
  9. ccxt/alpaca.py +0 -1
  10. ccxt/ascendex.py +0 -1
  11. ccxt/async_support/__init__.py +1 -1
  12. ccxt/async_support/ace.py +1 -1
  13. ccxt/async_support/alpaca.py +0 -1
  14. ccxt/async_support/ascendex.py +0 -1
  15. ccxt/async_support/base/exchange.py +24 -17
  16. ccxt/async_support/bigone.py +0 -1
  17. ccxt/async_support/binance.py +27 -24
  18. ccxt/async_support/bingx.py +5 -1
  19. ccxt/async_support/bitfinex.py +123 -1
  20. ccxt/async_support/bitget.py +1 -0
  21. ccxt/async_support/bitmart.py +243 -2
  22. ccxt/async_support/blofin.py +16 -7
  23. ccxt/async_support/bybit.py +8 -8
  24. ccxt/async_support/cex.py +1 -1
  25. ccxt/async_support/coinbase.py +8 -9
  26. ccxt/async_support/coinbaseexchange.py +5 -6
  27. ccxt/async_support/coinbaseinternational.py +7 -8
  28. ccxt/async_support/coincatch.py +0 -1
  29. ccxt/async_support/coincheck.py +0 -1
  30. ccxt/async_support/coinex.py +91 -6
  31. ccxt/async_support/coinlist.py +3 -4
  32. ccxt/async_support/coinmate.py +1 -3
  33. ccxt/async_support/coinmetro.py +4 -5
  34. ccxt/async_support/coinone.py +0 -1
  35. ccxt/async_support/coinsph.py +7 -8
  36. ccxt/async_support/cryptocom.py +3 -0
  37. ccxt/async_support/currencycom.py +3 -4
  38. ccxt/async_support/defx.py +6 -7
  39. ccxt/async_support/deribit.py +1 -3
  40. ccxt/async_support/digifinex.py +0 -1
  41. ccxt/async_support/ellipx.py +0 -2
  42. ccxt/async_support/exmo.py +61 -6
  43. ccxt/async_support/gate.py +2 -3
  44. ccxt/async_support/gemini.py +4 -5
  45. ccxt/async_support/hashkey.py +79 -67
  46. ccxt/async_support/hitbtc.py +47 -5
  47. ccxt/async_support/hollaex.py +4 -6
  48. ccxt/async_support/htx.py +2 -4
  49. ccxt/async_support/huobijp.py +0 -1
  50. ccxt/async_support/hyperliquid.py +60 -1
  51. ccxt/async_support/idex.py +8 -8
  52. ccxt/async_support/independentreserve.py +0 -1
  53. ccxt/async_support/indodax.py +0 -1
  54. ccxt/async_support/kraken.py +186 -28
  55. ccxt/async_support/krakenfutures.py +75 -3
  56. ccxt/async_support/kucoin.py +6 -4
  57. ccxt/async_support/kucoinfutures.py +10 -9
  58. ccxt/async_support/kuna.py +1 -3
  59. ccxt/async_support/latoken.py +1 -3
  60. ccxt/async_support/lbank.py +0 -1
  61. ccxt/async_support/luno.py +0 -1
  62. ccxt/async_support/lykke.py +0 -1
  63. ccxt/async_support/mercado.py +0 -1
  64. ccxt/async_support/mexc.py +6 -7
  65. ccxt/async_support/ndax.py +1 -1
  66. ccxt/async_support/novadax.py +4 -6
  67. ccxt/async_support/oceanex.py +0 -1
  68. ccxt/async_support/okcoin.py +1 -3
  69. ccxt/async_support/okx.py +7 -4
  70. ccxt/async_support/onetrading.py +1 -3
  71. ccxt/async_support/p2b.py +1 -1
  72. ccxt/async_support/paradex.py +5 -7
  73. ccxt/async_support/phemex.py +8 -10
  74. ccxt/async_support/poloniex.py +1 -3
  75. ccxt/async_support/poloniexfutures.py +6 -6
  76. ccxt/async_support/probit.py +0 -1
  77. ccxt/async_support/timex.py +0 -1
  78. ccxt/async_support/tokocrypto.py +11 -14
  79. ccxt/async_support/tradeogre.py +1 -1
  80. ccxt/async_support/upbit.py +0 -1
  81. ccxt/async_support/wavesexchange.py +4 -5
  82. ccxt/async_support/whitebit.py +8 -9
  83. ccxt/async_support/woo.py +98 -12
  84. ccxt/async_support/woofipro.py +96 -15
  85. ccxt/async_support/xt.py +6 -3
  86. ccxt/async_support/yobit.py +0 -1
  87. ccxt/async_support/zaif.py +0 -1
  88. ccxt/async_support/zonda.py +1 -2
  89. ccxt/base/exchange.py +39 -20
  90. ccxt/base/types.py +10 -0
  91. ccxt/bigone.py +0 -1
  92. ccxt/binance.py +27 -24
  93. ccxt/bingx.py +5 -1
  94. ccxt/bitfinex.py +123 -1
  95. ccxt/bitget.py +1 -0
  96. ccxt/bitmart.py +243 -2
  97. ccxt/blofin.py +16 -7
  98. ccxt/bybit.py +8 -8
  99. ccxt/cex.py +1 -1
  100. ccxt/coinbase.py +8 -9
  101. ccxt/coinbaseexchange.py +5 -6
  102. ccxt/coinbaseinternational.py +7 -8
  103. ccxt/coincatch.py +0 -1
  104. ccxt/coincheck.py +0 -1
  105. ccxt/coinex.py +91 -6
  106. ccxt/coinlist.py +3 -4
  107. ccxt/coinmate.py +1 -3
  108. ccxt/coinmetro.py +4 -5
  109. ccxt/coinone.py +0 -1
  110. ccxt/coinsph.py +7 -8
  111. ccxt/cryptocom.py +3 -0
  112. ccxt/currencycom.py +3 -4
  113. ccxt/defx.py +6 -7
  114. ccxt/deribit.py +1 -3
  115. ccxt/digifinex.py +0 -1
  116. ccxt/ellipx.py +0 -2
  117. ccxt/exmo.py +61 -6
  118. ccxt/gate.py +2 -3
  119. ccxt/gemini.py +4 -5
  120. ccxt/hashkey.py +79 -67
  121. ccxt/hitbtc.py +47 -5
  122. ccxt/hollaex.py +4 -6
  123. ccxt/htx.py +2 -4
  124. ccxt/huobijp.py +0 -1
  125. ccxt/hyperliquid.py +60 -1
  126. ccxt/idex.py +8 -8
  127. ccxt/independentreserve.py +0 -1
  128. ccxt/indodax.py +0 -1
  129. ccxt/kraken.py +186 -28
  130. ccxt/krakenfutures.py +75 -3
  131. ccxt/kucoin.py +6 -4
  132. ccxt/kucoinfutures.py +10 -9
  133. ccxt/kuna.py +1 -3
  134. ccxt/latoken.py +1 -3
  135. ccxt/lbank.py +0 -1
  136. ccxt/luno.py +0 -1
  137. ccxt/lykke.py +0 -1
  138. ccxt/mercado.py +0 -1
  139. ccxt/mexc.py +6 -7
  140. ccxt/ndax.py +1 -1
  141. ccxt/novadax.py +4 -6
  142. ccxt/oceanex.py +0 -1
  143. ccxt/okcoin.py +1 -3
  144. ccxt/okx.py +7 -4
  145. ccxt/onetrading.py +1 -3
  146. ccxt/p2b.py +1 -1
  147. ccxt/paradex.py +5 -7
  148. ccxt/phemex.py +8 -10
  149. ccxt/poloniex.py +1 -3
  150. ccxt/poloniexfutures.py +6 -6
  151. ccxt/pro/__init__.py +1 -1
  152. ccxt/probit.py +0 -1
  153. ccxt/timex.py +0 -1
  154. ccxt/tokocrypto.py +11 -14
  155. ccxt/tradeogre.py +1 -1
  156. ccxt/upbit.py +0 -1
  157. ccxt/wavesexchange.py +4 -5
  158. ccxt/whitebit.py +8 -9
  159. ccxt/woo.py +98 -12
  160. ccxt/woofipro.py +96 -15
  161. ccxt/xt.py +6 -3
  162. ccxt/yobit.py +0 -1
  163. ccxt/zaif.py +0 -1
  164. ccxt/zonda.py +1 -2
  165. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/METADATA +5 -5
  166. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/RECORD +169 -173
  167. ccxt/bitbay.py +0 -17
  168. ccxt/bitfinex2.py +0 -3624
  169. ccxt/hitbtc3.py +0 -16
  170. ccxt/pro/bitfinex2.py +0 -1086
  171. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/LICENSE.txt +0 -0
  172. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/WHEEL +0 -0
  173. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/top_level.txt +0 -0
ccxt/hyperliquid.py CHANGED
@@ -94,8 +94,9 @@ class hyperliquid(Exchange, ImplicitAPI):
94
94
  'fetchMyLiquidations': False,
95
95
  'fetchMyTrades': True,
96
96
  'fetchOHLCV': True,
97
- 'fetchOpenInterest': False,
97
+ 'fetchOpenInterest': True,
98
98
  'fetchOpenInterestHistory': False,
99
+ 'fetchOpenInterests': True,
99
100
  'fetchOpenOrders': True,
100
101
  'fetchOrder': True,
101
102
  'fetchOrderBook': True,
@@ -3131,6 +3132,64 @@ class hyperliquid(Exchange, ImplicitAPI):
3131
3132
  withdrawals = self.filter_by_array(records, 'type', ['withdraw'], False)
3132
3133
  return self.parse_transactions(withdrawals, None, since, limit)
3133
3134
 
3135
+ def fetch_open_interests(self, symbols: Strings = None, params={}):
3136
+ """
3137
+ Retrieves the open interest for a list of symbols
3138
+ :param str[] [symbols]: Unified CCXT market symbol
3139
+ :param dict [params]: exchange specific parameters
3140
+ :returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
3141
+ """
3142
+ self.load_markets()
3143
+ symbols = self.market_symbols(symbols)
3144
+ swapMarkets = self.fetch_swap_markets()
3145
+ result = self.parse_open_interests(swapMarkets)
3146
+ return self.filter_by_array(result, 'symbol', symbols)
3147
+
3148
+ def fetch_open_interest(self, symbol: str, params={}):
3149
+ """
3150
+ retrieves the open interest of a contract trading pair
3151
+ :param str symbol: unified CCXT market symbol
3152
+ :param dict [params]: exchange specific parameters
3153
+ :returns dict: an `open interest structure <https://docs.ccxt.com/#/?id=open-interest-structure>`
3154
+ """
3155
+ symbol = self.symbol(symbol)
3156
+ self.load_markets()
3157
+ ois = self.fetch_open_interests([symbol], params)
3158
+ return ois[symbol]
3159
+
3160
+ def parse_open_interest(self, interest, market: Market = None):
3161
+ #
3162
+ # {
3163
+ # szDecimals: '2',
3164
+ # name: 'HYPE',
3165
+ # maxLeverage: '3',
3166
+ # funding: '0.00014735',
3167
+ # openInterest: '14677900.74',
3168
+ # prevDayPx: '26.145',
3169
+ # dayNtlVlm: '299643445.12560016',
3170
+ # premium: '0.00081613',
3171
+ # oraclePx: '27.569',
3172
+ # markPx: '27.63',
3173
+ # midPx: '27.599',
3174
+ # impactPxs: ['27.5915', '27.6319'],
3175
+ # dayBaseVlm: '10790652.83',
3176
+ # baseId: 159
3177
+ # }
3178
+ #
3179
+ interest = self.safe_dict(interest, 'info', {})
3180
+ coin = self.safe_string(interest, 'name')
3181
+ marketId = None
3182
+ if coin is not None:
3183
+ marketId = self.coin_to_market_id(coin)
3184
+ return self.safe_open_interest({
3185
+ 'symbol': self.safe_symbol(marketId),
3186
+ 'openInterestAmount': self.safe_number(interest, 'openInterest'),
3187
+ 'openInterestValue': None,
3188
+ 'timestamp': None,
3189
+ 'datetime': None,
3190
+ 'info': interest,
3191
+ }, market)
3192
+
3134
3193
  def extract_type_from_delta(self, data=[]):
3135
3194
  records = []
3136
3195
  for i in range(0, len(data)):
ccxt/idex.py CHANGED
@@ -1098,7 +1098,6 @@ class idex(Exchange, ImplicitAPI):
1098
1098
  'postOnly': None,
1099
1099
  'side': side,
1100
1100
  'price': price,
1101
- 'stopPrice': None,
1102
1101
  'triggerPrice': None,
1103
1102
  'amount': amount,
1104
1103
  'cost': None,
@@ -1163,11 +1162,12 @@ class idex(Exchange, ImplicitAPI):
1163
1162
  'takeProfit': 5,
1164
1163
  'takeProfitLimit': 6,
1165
1164
  }
1166
- stopPriceString = None
1167
- if (type == 'stopLossLimit') or (type == 'takeProfitLimit') or ('stopPrice' in params):
1168
- if not ('stopPrice' in params):
1169
- raise BadRequest(self.id + ' createOrder() stopPrice is a required parameter for ' + type + 'orders')
1170
- stopPriceString = self.price_to_precision(symbol, params['stopPrice'])
1165
+ triggerPrice = self.safe_string(params, 'triggerPrice', 'stopPrice')
1166
+ triggerPriceString = None
1167
+ if (type == 'stopLossLimit') or (type == 'takeProfitLimit'):
1168
+ if triggerPrice is None:
1169
+ raise BadRequest(self.id + ' createOrder() triggerPrice is a required parameter for ' + type + 'orders')
1170
+ triggerPriceString = self.price_to_precision(symbol, triggerPrice)
1171
1171
  limitTypeEnums: dict = {
1172
1172
  'limit': 1,
1173
1173
  'limitMaker': 2,
@@ -1245,7 +1245,7 @@ class idex(Exchange, ImplicitAPI):
1245
1245
  encodedPrice = self.encode(priceString)
1246
1246
  byteArray.append(encodedPrice)
1247
1247
  if type in stopLossTypeEnums:
1248
- encodedPrice = self.encode(stopPriceString or priceString)
1248
+ encodedPrice = self.encode(triggerPriceString or priceString)
1249
1249
  byteArray.append(encodedPrice)
1250
1250
  clientOrderId = self.safe_string(params, 'clientOrderId')
1251
1251
  if clientOrderId is not None:
@@ -1275,7 +1275,7 @@ class idex(Exchange, ImplicitAPI):
1275
1275
  if limitOrder:
1276
1276
  request['parameters']['price'] = priceString
1277
1277
  if type in stopLossTypeEnums:
1278
- request['parameters']['stopPrice'] = stopPriceString or priceString
1278
+ request['parameters']['stopPrice'] = triggerPriceString or priceString
1279
1279
  if amountEnum == 0:
1280
1280
  request['parameters']['quantity'] = amountString
1281
1281
  else:
@@ -436,7 +436,6 @@ class independentreserve(Exchange, ImplicitAPI):
436
436
  'postOnly': None,
437
437
  'side': side,
438
438
  'price': self.safe_string(order, 'Price'),
439
- 'stopPrice': None,
440
439
  'triggerPrice': None,
441
440
  'cost': self.safe_string(order, 'Value'),
442
441
  'average': self.safe_string(order, 'AvgPrice'),
ccxt/indodax.py CHANGED
@@ -713,7 +713,6 @@ class indodax(Exchange, ImplicitAPI):
713
713
  'postOnly': None,
714
714
  'side': side,
715
715
  'price': price,
716
- 'stopPrice': None,
717
716
  'triggerPrice': None,
718
717
  'cost': cost,
719
718
  'average': None,
ccxt/kraken.py CHANGED
@@ -445,6 +445,67 @@ class kraken(Exchange, ImplicitAPI):
445
445
  'Celestia': 'TIA',
446
446
  },
447
447
  },
448
+ 'features': {
449
+ 'spot': {
450
+ 'sandbox': False,
451
+ 'createOrder': {
452
+ 'marginMode': False,
453
+ 'triggerPrice': False, # todo
454
+ 'triggerPriceType': None,
455
+ 'triggerDirection': False,
456
+ 'stopLossPrice': True,
457
+ 'takeProfitPrice': True,
458
+ 'attachedStopLossTakeProfit': None,
459
+ 'timeInForce': {
460
+ 'IOC': True,
461
+ 'FOK': True,
462
+ 'PO': True,
463
+ 'GTD': False,
464
+ },
465
+ 'hedged': False,
466
+ 'trailing': True,
467
+ },
468
+ 'createOrders': None,
469
+ 'fetchMyTrades': {
470
+ 'marginMode': False,
471
+ 'limit': None,
472
+ 'daysBack': None,
473
+ 'untilDays': None,
474
+ },
475
+ 'fetchOrder': {
476
+ 'marginMode': False,
477
+ 'trigger': False,
478
+ 'trailing': False,
479
+ },
480
+ 'fetchOpenOrders': {
481
+ 'marginMode': False,
482
+ 'limit': None,
483
+ 'trigger': False,
484
+ 'trailing': False,
485
+ },
486
+ 'fetchOrders': None,
487
+ 'fetchClosedOrders': {
488
+ 'marginMode': False,
489
+ 'limit': None,
490
+ 'daysBackClosed': None,
491
+ 'daysBackCanceled': None,
492
+ 'untilDays': 100000,
493
+ 'trigger': False,
494
+ 'trailing': False,
495
+ },
496
+ 'fetchOHLCV': {
497
+ 'limit': 720,
498
+ },
499
+ },
500
+ 'swap': {
501
+ 'linear': None,
502
+ 'inverse': None,
503
+ },
504
+ 'future': {
505
+ 'linear': None,
506
+ 'inverse': None,
507
+ },
508
+ },
448
509
  'precisionMode': TICK_SIZE,
449
510
  'exceptions': {
450
511
  'exact': {
@@ -1008,7 +1069,7 @@ class kraken(Exchange, ImplicitAPI):
1008
1069
  """
1009
1070
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1010
1071
 
1011
- https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOHLCData
1072
+ https://docs.kraken.com/api/docs/rest-api/get-ohlc-data
1012
1073
 
1013
1074
  :param str symbol: unified symbol of the market to fetch OHLCV data for
1014
1075
  :param str timeframe: the length of time each candle represents
@@ -1621,6 +1682,37 @@ class kraken(Exchange, ImplicitAPI):
1621
1682
  # }
1622
1683
  # }
1623
1684
  #
1685
+ # fetchOpenOrders
1686
+ #
1687
+ # {
1688
+ # "refid": null,
1689
+ # "userref": null,
1690
+ # "cl_ord_id": "1234",
1691
+ # "status": "open",
1692
+ # "opentm": 1733815269.370054,
1693
+ # "starttm": 0,
1694
+ # "expiretm": 0,
1695
+ # "descr": {
1696
+ # "pair": "XBTUSD",
1697
+ # "type": "buy",
1698
+ # "ordertype": "limit",
1699
+ # "price": "70000.0",
1700
+ # "price2": "0",
1701
+ # "leverage": "none",
1702
+ # "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
1703
+ # "close": ""
1704
+ # },
1705
+ # "vol": "0.00010000",
1706
+ # "vol_exec": "0.00000000",
1707
+ # "cost": "0.00000",
1708
+ # "fee": "0.00000",
1709
+ # "price": "0.00000",
1710
+ # "stopprice": "0.00000",
1711
+ # "limitprice": "0.00000",
1712
+ # "misc": "",
1713
+ # "oflags": "fciq"
1714
+ # }
1715
+ #
1624
1716
  description = self.safe_dict(order, 'descr', {})
1625
1717
  orderDescriptionObj = self.safe_dict(order, 'descr') # can be null
1626
1718
  orderDescription = None
@@ -1694,7 +1786,8 @@ class kraken(Exchange, ImplicitAPI):
1694
1786
  if (id is None) or (id.startswith('[')):
1695
1787
  txid = self.safe_list(order, 'txid')
1696
1788
  id = self.safe_string(txid, 0)
1697
- clientOrderId = self.safe_string(order, 'userref')
1789
+ userref = self.safe_string(order, 'userref')
1790
+ clientOrderId = self.safe_string(order, 'cl_ord_id', userref)
1698
1791
  rawTrades = self.safe_value(order, 'trades', [])
1699
1792
  trades = []
1700
1793
  for i in range(0, len(rawTrades)):
@@ -1743,7 +1836,6 @@ class kraken(Exchange, ImplicitAPI):
1743
1836
  'postOnly': isPostOnly,
1744
1837
  'side': side,
1745
1838
  'price': price,
1746
- 'stopPrice': triggerPrice,
1747
1839
  'triggerPrice': triggerPrice,
1748
1840
  'takeProfitPrice': takeProfitPrice,
1749
1841
  'stopLossPrice': stopLossPrice,
@@ -1888,10 +1980,10 @@ class kraken(Exchange, ImplicitAPI):
1888
1980
  request: dict = {
1889
1981
  'txid': id,
1890
1982
  }
1891
- clientOrderId = self.safe_string(params, 'clientOrderId')
1983
+ clientOrderId = self.safe_string_2(params, 'clientOrderId', 'cl_ord_id')
1892
1984
  if clientOrderId is not None:
1893
1985
  request['cl_ord_id'] = clientOrderId
1894
- params = self.omit(params, 'clientOrderId')
1986
+ params = self.omit(params, ['clientOrderId', 'cl_ord_id'])
1895
1987
  request = self.omit(request, 'txid')
1896
1988
  isMarket = (type == 'market')
1897
1989
  postOnly = None
@@ -2091,7 +2183,7 @@ class kraken(Exchange, ImplicitAPI):
2091
2183
  """
2092
2184
  fetch all trades made by the user
2093
2185
 
2094
- https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradeHistory
2186
+ https://docs.kraken.com/api/docs/rest-api/get-trade-history
2095
2187
 
2096
2188
  :param str symbol: unified market symbol
2097
2189
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2158,20 +2250,27 @@ class kraken(Exchange, ImplicitAPI):
2158
2250
  """
2159
2251
  cancels an open order
2160
2252
 
2161
- https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelOrder
2253
+ https://docs.kraken.com/api/docs/rest-api/cancel-order
2162
2254
 
2163
2255
  :param str id: order id
2164
- :param str symbol: unified symbol of the market the order was made in
2256
+ :param str [symbol]: unified symbol of the market the order was made in
2165
2257
  :param dict [params]: extra parameters specific to the exchange API endpoint
2166
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2258
+ :param str [params.clientOrderId]: the orders client order id
2259
+ :param int [params.userref]: the orders user reference id
2260
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2167
2261
  """
2168
2262
  self.load_markets()
2169
2263
  response = None
2170
- clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId', id)
2264
+ requestId = self.safe_value(params, 'userref', id) # string or integer
2265
+ params = self.omit(params, 'userref')
2171
2266
  request: dict = {
2172
- 'txid': clientOrderId, # order id or userref
2267
+ 'txid': requestId, # order id or userref
2173
2268
  }
2174
- params = self.omit(params, ['userref', 'clientOrderId'])
2269
+ clientOrderId = self.safe_string_2(params, 'clientOrderId', 'cl_ord_id')
2270
+ if clientOrderId is not None:
2271
+ request['cl_ord_id'] = clientOrderId
2272
+ params = self.omit(params, ['clientOrderId', 'cl_ord_id'])
2273
+ request = self.omit(request, 'txid')
2175
2274
  try:
2176
2275
  response = self.privatePostCancelOrder(self.extend(request, params))
2177
2276
  #
@@ -2278,55 +2377,108 @@ class kraken(Exchange, ImplicitAPI):
2278
2377
  """
2279
2378
  fetch all unfilled currently open orders
2280
2379
 
2281
- https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenOrders
2380
+ https://docs.kraken.com/api/docs/rest-api/get-open-orders
2282
2381
 
2283
- :param str symbol: unified market symbol
2382
+ :param str [symbol]: unified market symbol
2284
2383
  :param int [since]: the earliest time in ms to fetch open orders for
2285
2384
  :param int [limit]: the maximum number of open orders structures to retrieve
2286
2385
  :param dict [params]: extra parameters specific to the exchange API endpoint
2386
+ :param str [params.clientOrderId]: the orders client order id
2387
+ :param int [params.userref]: the orders user reference id
2287
2388
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
2288
2389
  """
2289
2390
  self.load_markets()
2290
2391
  request: dict = {}
2291
2392
  if since is not None:
2292
2393
  request['start'] = self.parse_to_int(since / 1000)
2293
- query = params
2294
- clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId')
2394
+ userref = self.safe_integer(params, 'userref')
2395
+ if userref is not None:
2396
+ request['userref'] = userref
2397
+ params = self.omit(params, 'userref')
2398
+ clientOrderId = self.safe_string(params, 'clientOrderId')
2295
2399
  if clientOrderId is not None:
2296
- request['userref'] = clientOrderId
2297
- query = self.omit(params, ['userref', 'clientOrderId'])
2298
- response = self.privatePostOpenOrders(self.extend(request, query))
2400
+ request['cl_ord_id'] = clientOrderId
2401
+ params = self.omit(params, 'clientOrderId')
2402
+ response = self.privatePostOpenOrders(self.extend(request, params))
2403
+ #
2404
+ # {
2405
+ # "error": [],
2406
+ # "result": {
2407
+ # "open": {
2408
+ # "O45M52-BFD5S-YXKQOU": {
2409
+ # "refid": null,
2410
+ # "userref": null,
2411
+ # "cl_ord_id": "1234",
2412
+ # "status": "open",
2413
+ # "opentm": 1733815269.370054,
2414
+ # "starttm": 0,
2415
+ # "expiretm": 0,
2416
+ # "descr": {
2417
+ # "pair": "XBTUSD",
2418
+ # "type": "buy",
2419
+ # "ordertype": "limit",
2420
+ # "price": "70000.0",
2421
+ # "price2": "0",
2422
+ # "leverage": "none",
2423
+ # "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
2424
+ # "close": ""
2425
+ # },
2426
+ # "vol": "0.00010000",
2427
+ # "vol_exec": "0.00000000",
2428
+ # "cost": "0.00000",
2429
+ # "fee": "0.00000",
2430
+ # "price": "0.00000",
2431
+ # "stopprice": "0.00000",
2432
+ # "limitprice": "0.00000",
2433
+ # "misc": "",
2434
+ # "oflags": "fciq"
2435
+ # }
2436
+ # }
2437
+ # }
2438
+ # }
2439
+ #
2299
2440
  market = None
2300
2441
  if symbol is not None:
2301
2442
  market = self.market(symbol)
2302
2443
  result = self.safe_dict(response, 'result', {})
2303
- orders = self.safe_dict(result, 'open', {})
2444
+ open = self.safe_dict(result, 'open', {})
2445
+ orders = []
2446
+ orderIds = list(open.keys())
2447
+ for i in range(0, len(orderIds)):
2448
+ id = orderIds[i]
2449
+ item = open[id]
2450
+ orders.append(self.extend({'id': id}, item))
2304
2451
  return self.parse_orders(orders, market, since, limit)
2305
2452
 
2306
2453
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2307
2454
  """
2308
2455
  fetches information on multiple closed orders made by the user
2309
2456
 
2310
- https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
2457
+ https://docs.kraken.com/api/docs/rest-api/get-closed-orders
2311
2458
 
2312
- :param str symbol: unified market symbol of the market orders were made in
2459
+ :param str [symbol]: unified market symbol of the market orders were made in
2313
2460
  :param int [since]: the earliest time in ms to fetch orders for
2314
2461
  :param int [limit]: the maximum number of order structures to retrieve
2315
2462
  :param dict [params]: extra parameters specific to the exchange API endpoint
2316
2463
  :param int [params.until]: timestamp in ms of the latest entry
2464
+ :param str [params.clientOrderId]: the orders client order id
2465
+ :param int [params.userref]: the orders user reference id
2317
2466
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
2318
2467
  """
2319
2468
  self.load_markets()
2320
2469
  request: dict = {}
2321
2470
  if since is not None:
2322
2471
  request['start'] = self.parse_to_int(since / 1000)
2323
- query = params
2324
- clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId')
2472
+ userref = self.safe_integer(params, 'userref')
2473
+ if userref is not None:
2474
+ request['userref'] = userref
2475
+ params = self.omit(params, 'userref')
2476
+ clientOrderId = self.safe_string(params, 'clientOrderId')
2325
2477
  if clientOrderId is not None:
2326
- request['userref'] = clientOrderId
2327
- query = self.omit(params, ['userref', 'clientOrderId'])
2478
+ request['cl_ord_id'] = clientOrderId
2479
+ params = self.omit(params, 'clientOrderId')
2328
2480
  request, params = self.handle_until_option('end', request, params)
2329
- response = self.privatePostClosedOrders(self.extend(request, query))
2481
+ response = self.privatePostClosedOrders(self.extend(request, params))
2330
2482
  #
2331
2483
  # {
2332
2484
  # "error":[],
@@ -2370,7 +2522,13 @@ class kraken(Exchange, ImplicitAPI):
2370
2522
  if symbol is not None:
2371
2523
  market = self.market(symbol)
2372
2524
  result = self.safe_dict(response, 'result', {})
2373
- orders = self.safe_dict(result, 'closed', {})
2525
+ closed = self.safe_dict(result, 'closed', {})
2526
+ orders = []
2527
+ orderIds = list(closed.keys())
2528
+ for i in range(0, len(orderIds)):
2529
+ id = orderIds[i]
2530
+ item = closed[id]
2531
+ orders.append(self.extend({'id': id}, item))
2374
2532
  return self.parse_orders(orders, market, since, limit)
2375
2533
 
2376
2534
  def parse_transaction_status(self, status: Str):
ccxt/krakenfutures.py CHANGED
@@ -276,6 +276,78 @@ class krakenfutures(Exchange, ImplicitAPI):
276
276
  'method': 'historyGetMarketSymbolExecutions', # historyGetMarketSymbolExecutions, publicGetHistory
277
277
  },
278
278
  },
279
+ 'features': {
280
+ 'default': {
281
+ 'sandbox': True,
282
+ 'createOrder': {
283
+ 'marginMode': False,
284
+ 'triggerPrice': True,
285
+ 'triggerPriceType': {
286
+ 'last': True,
287
+ 'mark': True,
288
+ 'index': True,
289
+ },
290
+ 'triggerDirection': False,
291
+ 'stopLossPrice': True,
292
+ 'takeProfitPrice': True,
293
+ 'attachedStopLossTakeProfit': None,
294
+ 'timeInForce': {
295
+ 'IOC': True,
296
+ 'FOK': True,
297
+ 'PO': True,
298
+ 'GTD': False,
299
+ },
300
+ 'hedged': False,
301
+ 'trailing': False,
302
+ },
303
+ 'createOrders': {
304
+ 'max': 100,
305
+ },
306
+ 'fetchMyTrades': {
307
+ 'marginMode': False,
308
+ 'limit': None,
309
+ 'daysBack': None,
310
+ 'untilDays': 100000,
311
+ },
312
+ 'fetchOrder': None,
313
+ 'fetchOpenOrders': {
314
+ 'marginMode': False,
315
+ 'limit': None,
316
+ 'trigger': False,
317
+ 'trailing': False,
318
+ },
319
+ 'fetchOrders': None,
320
+ 'fetchClosedOrders': {
321
+ 'marginMode': False,
322
+ 'limit': None,
323
+ 'daysBackClosed': None,
324
+ 'daysBackCanceled': None,
325
+ 'untilDays': None,
326
+ 'trigger': False,
327
+ 'trailing': False,
328
+ },
329
+ 'fetchOHLCV': {
330
+ 'limit': 5000,
331
+ },
332
+ },
333
+ 'spot': None,
334
+ 'swap': {
335
+ 'linear': {
336
+ 'extends': 'default',
337
+ },
338
+ 'inverse': {
339
+ 'extends': 'default',
340
+ },
341
+ },
342
+ 'future': {
343
+ 'linear': {
344
+ 'extends': 'default',
345
+ },
346
+ 'inverse': {
347
+ 'extends': 'default',
348
+ },
349
+ },
350
+ },
279
351
  'timeframes': {
280
352
  '1m': '1m',
281
353
  '5m': '5m',
@@ -1011,7 +1083,7 @@ class krakenfutures(Exchange, ImplicitAPI):
1011
1083
  """
1012
1084
  Create an order on the exchange
1013
1085
 
1014
- https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-send-order
1086
+ https://docs.kraken.com/api/docs/futures-api/trading/send-order
1015
1087
 
1016
1088
  :param str symbol: unified market symbol
1017
1089
  :param str type: 'limit' or 'market'
@@ -1071,7 +1143,7 @@ class krakenfutures(Exchange, ImplicitAPI):
1071
1143
  """
1072
1144
  create a list of trade orders
1073
1145
 
1074
- https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-batch-order-management
1146
+ https://docs.kraken.com/api/docs/futures-api/trading/send-batch-order
1075
1147
 
1076
1148
  :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
1077
1149
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1804,7 +1876,6 @@ class krakenfutures(Exchange, ImplicitAPI):
1804
1876
  'reduceOnly': self.safe_bool_2(details, 'reduceOnly', 'reduce_only'),
1805
1877
  'side': self.safe_string(details, 'side'),
1806
1878
  'price': price,
1807
- 'stopPrice': self.safe_string(details, 'triggerPrice'),
1808
1879
  'triggerPrice': self.safe_string(details, 'triggerPrice'),
1809
1880
  'amount': amount,
1810
1881
  'cost': cost,
@@ -1834,6 +1905,7 @@ class krakenfutures(Exchange, ImplicitAPI):
1834
1905
  market = None
1835
1906
  if symbol is not None:
1836
1907
  market = self.market(symbol)
1908
+ # todo: lastFillTime: self.iso8601(end)
1837
1909
  response = self.privateGetFills(params)
1838
1910
  #
1839
1911
  # {
ccxt/kucoin.py CHANGED
@@ -659,6 +659,8 @@ class kucoin(Exchange, ImplicitAPI):
659
659
  'version': 'v1',
660
660
  'symbolSeparator': '-',
661
661
  'fetchMyTradesMethod': 'private_get_fills',
662
+ 'timeDifference': 0, # the difference between system clock and Binance clock
663
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
662
664
  'fetchCurrencies': {
663
665
  'webApiEnable': True, # fetches from WEB
664
666
  'webApiRetries': 1,
@@ -1075,7 +1077,7 @@ class kucoin(Exchange, ImplicitAPI):
1075
1077
  })
1076
1078
 
1077
1079
  def nonce(self):
1078
- return self.milliseconds()
1080
+ return self.milliseconds() - self.options['timeDifference']
1079
1081
 
1080
1082
  def fetch_time(self, params={}):
1081
1083
  """
@@ -1312,6 +1314,8 @@ class kucoin(Exchange, ImplicitAPI):
1312
1314
  'created': None,
1313
1315
  'info': market,
1314
1316
  })
1317
+ if self.options['adjustForTimeDifference']:
1318
+ self.load_time_difference()
1315
1319
  return result
1316
1320
 
1317
1321
  def load_migration_status(self, force: bool = False):
@@ -3038,7 +3042,6 @@ class kucoin(Exchange, ImplicitAPI):
3038
3042
  status = 'canceled'
3039
3043
  if responseStatus == 'fail':
3040
3044
  status = 'rejected'
3041
- stopPrice = self.safe_number(order, 'stopPrice')
3042
3045
  return self.safe_order({
3043
3046
  'info': order,
3044
3047
  'id': self.safe_string_n(order, ['id', 'orderId', 'newOrderId', 'cancelledOrderId']),
@@ -3050,8 +3053,7 @@ class kucoin(Exchange, ImplicitAPI):
3050
3053
  'side': self.safe_string(order, 'side'),
3051
3054
  'amount': self.safe_string(order, 'size'),
3052
3055
  'price': self.safe_string(order, 'price'), # price is zero for market order, omitZero is called in safeOrder2
3053
- 'stopPrice': stopPrice,
3054
- 'triggerPrice': stopPrice,
3056
+ 'triggerPrice': self.safe_number(order, 'stopPrice'),
3055
3057
  'cost': self.safe_string(order, 'dealFunds'),
3056
3058
  'filled': self.safe_string(order, 'dealSize'),
3057
3059
  'remaining': None,