ccxt 4.2.39__py2.py3-none-any.whl → 4.2.40__py2.py3-none-any.whl

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

Potentially problematic release.


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

@@ -154,6 +154,7 @@ class bingx(Exchange, ImplicitAPI):
154
154
  'trade/order': 3,
155
155
  'trade/cancel': 3,
156
156
  'trade/batchOrders': 3,
157
+ 'trade/order/cancelReplace': 3,
157
158
  'trade/cancelOrders': 3,
158
159
  'trade/cancelOpenOrders': 3,
159
160
  },
@@ -175,12 +176,19 @@ class bingx(Exchange, ImplicitAPI):
175
176
  },
176
177
  'swap': {
177
178
  'v1': {
179
+ 'public': {
180
+ 'get': {
181
+ 'ticker/price': 1,
182
+ },
183
+ },
178
184
  'private': {
179
185
  'get': {
180
186
  'positionSide/dual': 1,
181
187
  'market/markPriceKlines': 1,
188
+ 'trade/batchCancelReplace': 1,
182
189
  },
183
190
  'post': {
191
+ 'trade/cancelReplace': 1,
184
192
  'positionSide/dual': 1,
185
193
  },
186
194
  },
@@ -2117,21 +2125,102 @@ class bingx(Exchange, ImplicitAPI):
2117
2125
  # reduceOnly: False
2118
2126
  # }
2119
2127
  #
2128
+ # editOrder(swap)
2129
+ #
2130
+ # {
2131
+ # cancelResult: 'true',
2132
+ # cancelMsg: '',
2133
+ # cancelResponse: {
2134
+ # cancelClientOrderId: '',
2135
+ # cancelOrderId: '1755336244265705472',
2136
+ # symbol: 'SOL-USDT',
2137
+ # orderId: '1755336244265705472',
2138
+ # side: 'SELL',
2139
+ # positionSide: 'SHORT',
2140
+ # type: 'LIMIT',
2141
+ # origQty: '1',
2142
+ # price: '100.000',
2143
+ # executedQty: '0',
2144
+ # avgPrice: '0.000',
2145
+ # cumQuote: '0',
2146
+ # stopPrice: '',
2147
+ # profit: '0.0000',
2148
+ # commission: '0.000000',
2149
+ # status: 'PENDING',
2150
+ # time: '1707339747860',
2151
+ # updateTime: '1707339747860',
2152
+ # clientOrderId: '',
2153
+ # leverage: '20X',
2154
+ # workingType: 'MARK_PRICE',
2155
+ # onlyOnePosition: False,
2156
+ # reduceOnly: False
2157
+ # },
2158
+ # replaceResult: 'true',
2159
+ # replaceMsg: '',
2160
+ # newOrderResponse: {
2161
+ # orderId: '1755338440612995072',
2162
+ # symbol: 'SOL-USDT',
2163
+ # positionSide: 'SHORT',
2164
+ # side: 'SELL',
2165
+ # type: 'LIMIT',
2166
+ # price: '99',
2167
+ # quantity: '2',
2168
+ # stopPrice: '0',
2169
+ # workingType: 'MARK_PRICE',
2170
+ # clientOrderID: '',
2171
+ # timeInForce: 'GTC',
2172
+ # priceRate: '0',
2173
+ # stopLoss: '',
2174
+ # takeProfit: '',
2175
+ # reduceOnly: False
2176
+ # }
2177
+ # }
2178
+ #
2179
+ # editOrder(spot)
2180
+ #
2181
+ # {
2182
+ # cancelResult: {code: '0', msg: '', result: True},
2183
+ # openResult: {code: '0', msg: '', result: True},
2184
+ # orderOpenResponse: {
2185
+ # symbol: 'SOL-USDT',
2186
+ # orderId: '1755334007697866752',
2187
+ # transactTime: '1707339214620',
2188
+ # price: '99',
2189
+ # stopPrice: '0',
2190
+ # origQty: '0.2',
2191
+ # executedQty: '0',
2192
+ # cummulativeQuoteQty: '0',
2193
+ # status: 'PENDING',
2194
+ # type: 'LIMIT',
2195
+ # side: 'SELL',
2196
+ # clientOrderID: ''
2197
+ # },
2198
+ # orderCancelResponse: {
2199
+ # symbol: 'SOL-USDT',
2200
+ # orderId: '1755117055251480576',
2201
+ # price: '100',
2202
+ # stopPrice: '0',
2203
+ # origQty: '0.2',
2204
+ # executedQty: '0',
2205
+ # cummulativeQuoteQty: '0',
2206
+ # status: 'CANCELED',
2207
+ # type: 'LIMIT',
2208
+ # side: 'SELL'
2209
+ # }
2210
+ # }
2211
+ #
2212
+ info = order
2213
+ newOrder = self.safe_dict_2(order, 'newOrderResponse', 'orderOpenResponse')
2214
+ if newOrder is not None:
2215
+ order = newOrder
2120
2216
  positionSide = self.safe_string_2(order, 'positionSide', 'ps')
2121
2217
  marketType = 'spot' if (positionSide is None) else 'swap'
2122
2218
  marketId = self.safe_string_2(order, 'symbol', 's')
2123
2219
  if market is None:
2124
2220
  market = self.safe_market(marketId, None, None, marketType)
2125
- symbol = self.safe_symbol(marketId, market, '-', marketType)
2126
- orderId = self.safe_string_2(order, 'orderId', 'i')
2127
2221
  side = self.safe_string_lower_2(order, 'side', 'S')
2128
- type = self.safe_string_lower_2(order, 'type', 'o')
2129
2222
  timestamp = self.safe_integer_n(order, ['time', 'transactTime', 'E'])
2130
2223
  lastTradeTimestamp = self.safe_integer_2(order, 'updateTime', 'T')
2131
- price = self.safe_string_2(order, 'price', 'p')
2132
- average = self.safe_string_2(order, 'avgPrice', 'ap')
2133
- amount = self.safe_string_2(order, 'origQty', 'q')
2134
- filled = self.safe_string_2(order, 'executedQty', 'z')
2135
2224
  statusId = self.safe_string_2(order, 'status', 'X')
2136
2225
  feeCurrencyCode = self.safe_string_2(order, 'feeAsset', 'N')
2137
2226
  feeCost = self.safe_string_n(order, ['fee', 'commission', 'n'])
@@ -2143,11 +2232,6 @@ class bingx(Exchange, ImplicitAPI):
2143
2232
  feeCurrencyCode = market['quote']
2144
2233
  else:
2145
2234
  feeCurrencyCode = market['quote']
2146
- fee = {
2147
- 'currency': feeCurrencyCode,
2148
- 'cost': Precise.string_abs(feeCost),
2149
- }
2150
- clientOrderId = self.safe_string_n(order, ['clientOrderID', 'origClientOrderId', 'c'])
2151
2235
  stopLoss = self.safe_value(order, 'stopLoss')
2152
2236
  stopLossPrice = None
2153
2237
  if (stopLoss is not None) and (stopLoss != ''):
@@ -2167,31 +2251,35 @@ class bingx(Exchange, ImplicitAPI):
2167
2251
  takeProfit = self.parse_json(takeProfit)
2168
2252
  takeProfitPrice = self.safe_number(takeProfit, 'stopPrice')
2169
2253
  return self.safe_order({
2170
- 'info': order,
2171
- 'id': orderId,
2172
- 'clientOrderId': clientOrderId,
2254
+ 'info': info,
2255
+ 'id': self.safe_string_2(order, 'orderId', 'i'),
2256
+ 'clientOrderId': self.safe_string_n(order, ['clientOrderID', 'origClientOrderId', 'c']),
2257
+ 'symbol': self.safe_symbol(marketId, market, '-', marketType),
2173
2258
  'timestamp': timestamp,
2174
2259
  'datetime': self.iso8601(timestamp),
2175
2260
  'lastTradeTimestamp': lastTradeTimestamp,
2176
2261
  'lastUpdateTimestamp': self.safe_integer(order, 'updateTime'),
2177
- 'symbol': symbol,
2178
- 'type': type,
2179
- 'timeInForce': None,
2262
+ 'type': self.safe_string_lower_2(order, 'type', 'o'),
2263
+ 'timeInForce': self.safe_string(order, 'timeInForce'),
2180
2264
  'postOnly': None,
2181
2265
  'side': self.parse_order_side(side),
2182
- 'price': price,
2266
+ 'price': self.safe_string_2(order, 'price', 'p'),
2183
2267
  'stopPrice': self.safe_number(order, 'stopPrice'),
2184
2268
  'triggerPrice': self.safe_number(order, 'stopPrice'),
2185
2269
  'stopLossPrice': stopLossPrice,
2186
2270
  'takeProfitPrice': takeProfitPrice,
2187
- 'average': average,
2271
+ 'average': self.safe_string_2(order, 'avgPrice', 'ap'),
2188
2272
  'cost': None,
2189
- 'amount': amount,
2190
- 'filled': filled,
2273
+ 'amount': self.safe_string_n(order, ['origQty', 'q', 'quantity']),
2274
+ 'filled': self.safe_string_2(order, 'executedQty', 'z'),
2191
2275
  'remaining': None,
2192
2276
  'status': self.parse_order_status(statusId),
2193
- 'fee': fee,
2277
+ 'fee': {
2278
+ 'currency': feeCurrencyCode,
2279
+ 'cost': Precise.string_abs(feeCost),
2280
+ },
2194
2281
  'trades': None,
2282
+ 'reduceOnly': self.safe_bool(order, 'reduceOnly'),
2195
2283
  }, market)
2196
2284
 
2197
2285
  def parse_order_status(self, status):
@@ -3588,6 +3676,140 @@ class bingx(Exchange, ImplicitAPI):
3588
3676
  #
3589
3677
  return await self.swapV1PrivatePostPositionSideDual(self.extend(request, params))
3590
3678
 
3679
+ async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float = None, price: float = None, params={}) -> Order:
3680
+ """
3681
+ cancels an order and places a new order
3682
+ :see: https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20order%20and%20place%20a%20new%20order # spot
3683
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20an%20order%20and%20then%20Place%20a%20new%20order # swap
3684
+ :param str id: order id
3685
+ :param str symbol: unified symbol of the market to create an order in
3686
+ :param str type: 'market' or 'limit'
3687
+ :param str side: 'buy' or 'sell'
3688
+ :param float amount: how much of the currency you want to trade in units of the base currency
3689
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
3690
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3691
+ :param str [params.stopPrice]: Trigger price used for TAKE_STOP_LIMIT, TAKE_STOP_MARKET, TRIGGER_LIMIT, TRIGGER_MARKET order types.
3692
+ :param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
3693
+ :param float [params.takeProfit.triggerPrice]: take profit trigger price
3694
+ :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
3695
+ :param float [params.stopLoss.triggerPrice]: stop loss trigger price
3696
+ *
3697
+ * EXCHANGE SPECIFIC PARAMETERS
3698
+ :param str [params.cancelClientOrderID]: the user-defined id of the order to be canceled, 1-40 characters, different orders cannot use the same clientOrderID, only supports a query range of 2 hours
3699
+ :param str [params.cancelRestrictions]: cancel orders with specified status, NEW: New order, PENDING: Pending order, PARTIALLY_FILLED: Partially filled
3700
+ :param str [params.cancelReplaceMode]: STOP_ON_FAILURE - if the cancel order fails, it will not continue to place a new order, ALLOW_FAILURE - regardless of whether the cancel order succeeds or fails, it will continue to place a new order
3701
+ :param float [params.quoteOrderQty]: order amount
3702
+ :param str [params.newClientOrderId]: custom order id consisting of letters, numbers, and _, 1-40 characters, different orders cannot use the same newClientOrderId.
3703
+ :param str [params.positionSide]: *contract only* position direction, required for single position, for both long and short positions only LONG or SHORT can be chosen, defaults to LONG if empty
3704
+ :param str [params.reduceOnly]: *contract only* True or False, default=false for single position mode. self parameter is not accepted for both long and short positions mode
3705
+ :param float [params.priceRate]: *contract only* for type TRAILING_STOP_Market, Max = 1
3706
+ :param str [params.workingType]: *contract only* StopPrice trigger price types, MARK_PRICE(default), CONTRACT_PRICE, or INDEX_PRICE
3707
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3708
+ """
3709
+ await self.load_markets()
3710
+ market = self.market(symbol)
3711
+ request = self.create_order_request(symbol, type, side, amount, price, params)
3712
+ request['cancelOrderId'] = id
3713
+ request['cancelReplaceMode'] = 'STOP_ON_FAILURE'
3714
+ response = None
3715
+ if market['swap']:
3716
+ response = await self.swapV1PrivatePostTradeCancelReplace(self.extend(request, params))
3717
+ #
3718
+ # {
3719
+ # code: '0',
3720
+ # msg: '',
3721
+ # data: {
3722
+ # cancelResult: 'true',
3723
+ # cancelMsg: '',
3724
+ # cancelResponse: {
3725
+ # cancelClientOrderId: '',
3726
+ # cancelOrderId: '1755336244265705472',
3727
+ # symbol: 'SOL-USDT',
3728
+ # orderId: '1755336244265705472',
3729
+ # side: 'SELL',
3730
+ # positionSide: 'SHORT',
3731
+ # type: 'LIMIT',
3732
+ # origQty: '1',
3733
+ # price: '100.000',
3734
+ # executedQty: '0',
3735
+ # avgPrice: '0.000',
3736
+ # cumQuote: '0',
3737
+ # stopPrice: '',
3738
+ # profit: '0.0000',
3739
+ # commission: '0.000000',
3740
+ # status: 'PENDING',
3741
+ # time: '1707339747860',
3742
+ # updateTime: '1707339747860',
3743
+ # clientOrderId: '',
3744
+ # leverage: '20X',
3745
+ # workingType: 'MARK_PRICE',
3746
+ # onlyOnePosition: False,
3747
+ # reduceOnly: False
3748
+ # },
3749
+ # replaceResult: 'true',
3750
+ # replaceMsg: '',
3751
+ # newOrderResponse: {
3752
+ # orderId: '1755338440612995072',
3753
+ # symbol: 'SOL-USDT',
3754
+ # positionSide: 'SHORT',
3755
+ # side: 'SELL',
3756
+ # type: 'LIMIT',
3757
+ # price: '99',
3758
+ # quantity: '2',
3759
+ # stopPrice: '0',
3760
+ # workingType: 'MARK_PRICE',
3761
+ # clientOrderID: '',
3762
+ # timeInForce: 'GTC',
3763
+ # priceRate: '0',
3764
+ # stopLoss: '',
3765
+ # takeProfit: '',
3766
+ # reduceOnly: False
3767
+ # }
3768
+ # }
3769
+ # }
3770
+ #
3771
+ else:
3772
+ response = await self.spotV1PrivatePostTradeOrderCancelReplace(self.extend(request, params))
3773
+ #
3774
+ # {
3775
+ # code: '0',
3776
+ # msg: '',
3777
+ # debugMsg: '',
3778
+ # data: {
3779
+ # cancelResult: {code: '0', msg: '', result: True},
3780
+ # openResult: {code: '0', msg: '', result: True},
3781
+ # orderOpenResponse: {
3782
+ # symbol: 'SOL-USDT',
3783
+ # orderId: '1755334007697866752',
3784
+ # transactTime: '1707339214620',
3785
+ # price: '99',
3786
+ # stopPrice: '0',
3787
+ # origQty: '0.2',
3788
+ # executedQty: '0',
3789
+ # cummulativeQuoteQty: '0',
3790
+ # status: 'PENDING',
3791
+ # type: 'LIMIT',
3792
+ # side: 'SELL',
3793
+ # clientOrderID: ''
3794
+ # },
3795
+ # orderCancelResponse: {
3796
+ # symbol: 'SOL-USDT',
3797
+ # orderId: '1755117055251480576',
3798
+ # price: '100',
3799
+ # stopPrice: '0',
3800
+ # origQty: '0.2',
3801
+ # executedQty: '0',
3802
+ # cummulativeQuoteQty: '0',
3803
+ # status: 'CANCELED',
3804
+ # type: 'LIMIT',
3805
+ # side: 'SELL'
3806
+ # }
3807
+ # }
3808
+ # }
3809
+ #
3810
+ data = self.safe_dict(response, 'data')
3811
+ return self.parse_order(data, market)
3812
+
3591
3813
  def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
3592
3814
  type = section[0]
3593
3815
  version = section[1]
@@ -3795,6 +3795,12 @@ class bitget(Exchange, ImplicitAPI):
3795
3795
  else:
3796
3796
  size = self.safe_string(order, 'size')
3797
3797
  filled = self.safe_string(order, 'baseVolume')
3798
+ side = self.safe_string(order, 'side')
3799
+ posMode = self.safe_string(order, 'posMode')
3800
+ if posMode == 'hedge_mode' and reduceOnly:
3801
+ side = 'sell' if (side == 'buy') else 'buy'
3802
+ # on bitget hedge mode if the position is long the side is always buy, and if the position is short the side is always sell
3803
+ # so the side of the reduceOnly order is inversed
3798
3804
  return self.safe_order({
3799
3805
  'info': order,
3800
3806
  'id': self.safe_string_2(order, 'orderId', 'data'),
@@ -3805,7 +3811,7 @@ class bitget(Exchange, ImplicitAPI):
3805
3811
  'lastUpdateTimestamp': updateTimestamp,
3806
3812
  'symbol': market['symbol'],
3807
3813
  'type': self.safe_string(order, 'orderType'),
3808
- 'side': self.safe_string(order, 'side'),
3814
+ 'side': side,
3809
3815
  'price': price,
3810
3816
  'amount': size,
3811
3817
  'cost': self.safe_string_2(order, 'quoteVolume', 'quoteSize'),
@@ -7712,6 +7718,9 @@ class bitget(Exchange, ImplicitAPI):
7712
7718
  else:
7713
7719
  if params:
7714
7720
  queryInner = '?' + self.urlencode(self.keysort(params))
7721
+ # check #21169 pr
7722
+ if queryInner.find('%24') > -1:
7723
+ queryInner = queryInner.replace('%24', '$')
7715
7724
  url += queryInner
7716
7725
  auth += queryInner
7717
7726
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256, 'base64')
@@ -2155,6 +2155,7 @@ class bybit(Exchange, ImplicitAPI):
2155
2155
  :param int [since]: timestamp in ms of the earliest candle to fetch
2156
2156
  :param int [limit]: the maximum amount of candles to fetch
2157
2157
  :param dict [params]: extra parameters specific to the exchange API endpoint
2158
+ :param int [params.until]: the latest time in ms to fetch orders for
2158
2159
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2159
2160
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
2160
2161
  """
@@ -2175,6 +2176,7 @@ class bybit(Exchange, ImplicitAPI):
2175
2176
  request['start'] = since
2176
2177
  if limit is not None:
2177
2178
  request['limit'] = limit # max 1000, default 1000
2179
+ request, params = self.handle_until_option('end', request, params)
2178
2180
  request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
2179
2181
  response = None
2180
2182
  if market['spot']:
@@ -431,11 +431,12 @@ class coinbase(Exchange, ImplicitAPI):
431
431
  # ]
432
432
  # }
433
433
  #
434
- data = self.safe_value(response, 'data', [])
435
- pagination = self.safe_value(response, 'pagination', {})
434
+ data = self.safe_list(response, 'data', [])
435
+ pagination = self.safe_dict(response, 'pagination', {})
436
436
  cursor = self.safe_string(pagination, 'next_starting_after')
437
- accounts = self.safe_value(response, 'data', [])
438
- lastIndex = len(accounts) - 1
437
+ accounts = self.safe_list(response, 'data', [])
438
+ length = len(accounts)
439
+ lastIndex = length - 1
439
440
  last = self.safe_value(accounts, lastIndex)
440
441
  if (cursor is not None) and (cursor != ''):
441
442
  last['next_starting_after'] = cursor
@@ -482,8 +483,9 @@ class coinbase(Exchange, ImplicitAPI):
482
483
  # "size": 9
483
484
  # }
484
485
  #
485
- accounts = self.safe_value(response, 'accounts', [])
486
- lastIndex = len(accounts) - 1
486
+ accounts = self.safe_list(response, 'accounts', [])
487
+ length = len(accounts)
488
+ lastIndex = length - 1
487
489
  last = self.safe_value(accounts, lastIndex)
488
490
  cursor = self.safe_string(response, 'cursor')
489
491
  if (cursor is not None) and (cursor != ''):
@@ -158,6 +158,7 @@ class coinbasepro(Exchange, ImplicitAPI):
158
158
  'users/self/trailing-volume',
159
159
  'withdrawals/fee-estimate',
160
160
  'conversions/{conversion_id}',
161
+ 'conversions/fees',
161
162
  ],
162
163
  'post': [
163
164
  'conversions',
@@ -1014,13 +1014,15 @@ class coinlist(Exchange, ImplicitAPI):
1014
1014
  takerFees.append([None, self.parse_number(taker)])
1015
1015
  takerFees = self.sort_by(takerFees, 1, True)
1016
1016
  makerFees = self.sort_by(makerFees, 1, True)
1017
- firstTier = self.safe_value(takerFees, 0, [])
1018
- exchangeFees = self.safe_value(self, 'fees', {})
1019
- exchangeFeesTrading = self.safe_value(exchangeFees, 'trading', {})
1020
- exchangeFeesTradingTiers = self.safe_value(exchangeFeesTrading, 'tiers', {})
1021
- exchangeFeesTradingTiersTaker = self.safe_value(exchangeFeesTradingTiers, 'taker', [])
1022
- exchangeFeesTradingTiersMaker = self.safe_value(exchangeFeesTradingTiers, 'maker', [])
1023
- if (keysLength == len(exchangeFeesTradingTiersTaker)) and (len(firstTier) > 0):
1017
+ firstTier = self.safe_dict(takerFees, 0, [])
1018
+ exchangeFees = self.safe_dict(self, 'fees', {})
1019
+ exchangeFeesTrading = self.safe_dict(exchangeFees, 'trading', {})
1020
+ exchangeFeesTradingTiers = self.safe_dict(exchangeFeesTrading, 'tiers', {})
1021
+ exchangeFeesTradingTiersTaker = self.safe_list(exchangeFeesTradingTiers, 'taker', [])
1022
+ exchangeFeesTradingTiersMaker = self.safe_list(exchangeFeesTradingTiers, 'maker', [])
1023
+ exchangeFeesTradingTiersTakerLength = len(exchangeFeesTradingTiersTaker)
1024
+ firstTierLength = len(firstTier)
1025
+ if (keysLength == exchangeFeesTradingTiersTakerLength) and (firstTierLength > 0):
1024
1026
  for i in range(0, keysLength):
1025
1027
  takerFees[i][0] = exchangeFeesTradingTiersTaker[i][0]
1026
1028
  makerFees[i][0] = exchangeFeesTradingTiersMaker[i][0]
@@ -1123,7 +1123,8 @@ class coinmetro(Exchange, ImplicitAPI):
1123
1123
  descriptionArray = description.split(' ')
1124
1124
  type = None
1125
1125
  referenceId = None
1126
- if len(descriptionArray) > 1:
1126
+ length = len(descriptionArray)
1127
+ if length > 1:
1127
1128
  type = self.parse_ledger_entry_type(descriptionArray[0])
1128
1129
  if descriptionArray[1] != '-':
1129
1130
  referenceId = descriptionArray[1]
@@ -54,7 +54,8 @@ class krakenfutures(Exchange, ImplicitAPI):
54
54
  'fetchBalance': True,
55
55
  'fetchBorrowRateHistories': False,
56
56
  'fetchBorrowRateHistory': False,
57
- 'fetchClosedOrders': None, # https://support.kraken.com/hc/en-us/articles/360058243651-Historical-orders
57
+ 'fetchCanceledOrders': True,
58
+ 'fetchClosedOrders': True, # https://support.kraken.com/hc/en-us/articles/360058243651-Historical-orders
58
59
  'fetchCrossBorrowRate': False,
59
60
  'fetchCrossBorrowRates': False,
60
61
  'fetchDepositAddress': False,
@@ -1125,6 +1126,84 @@ class krakenfutures(Exchange, ImplicitAPI):
1125
1126
  orders = self.safe_value(response, 'openOrders', [])
1126
1127
  return self.parse_orders(orders, market, since, limit)
1127
1128
 
1129
+ async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1130
+ """
1131
+ :see: https://docs.futures.kraken.com/#http-api-history-account-history-get-order-events
1132
+ Gets all closed orders, including trigger orders, for an account from the exchange api
1133
+ :param str symbol: Unified market symbol
1134
+ :param int [since]: Timestamp(ms) of earliest order.
1135
+ :param int [limit]: How many orders to return.
1136
+ :param dict [params]: Exchange specific parameters
1137
+ :returns: An array of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1138
+ """
1139
+ await self.load_markets()
1140
+ market = None
1141
+ if symbol is not None:
1142
+ market = self.market(symbol)
1143
+ request = {}
1144
+ if limit is not None:
1145
+ request['count'] = limit
1146
+ if since is not None:
1147
+ request['from'] = since
1148
+ response = await self.historyGetOrders(self.extend(request, params))
1149
+ allOrders = self.safe_list(response, 'elements', [])
1150
+ closedOrders = []
1151
+ for i in range(0, len(allOrders)):
1152
+ order = allOrders[i]
1153
+ event = self.safe_dict(order, 'event', {})
1154
+ orderPlaced = self.safe_dict(event, 'OrderPlaced')
1155
+ if orderPlaced is not None:
1156
+ innerOrder = self.safe_dict(orderPlaced, 'order', {})
1157
+ filled = self.safe_string(innerOrder, 'filled')
1158
+ if filled != '0':
1159
+ innerOrder['status'] = 'closed' # status not available in the response
1160
+ closedOrders.append(innerOrder)
1161
+ return self.parse_orders(closedOrders, market, since, limit)
1162
+
1163
+ async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1164
+ """
1165
+ :see: https://docs.futures.kraken.com/#http-api-history-account-history-get-order-events
1166
+ Gets all canceled orders, including trigger orders, for an account from the exchange api
1167
+ :param str symbol: Unified market symbol
1168
+ :param int [since]: Timestamp(ms) of earliest order.
1169
+ :param int [limit]: How many orders to return.
1170
+ :param dict [params]: Exchange specific parameters
1171
+ :returns: An array of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1172
+ """
1173
+ await self.load_markets()
1174
+ market = None
1175
+ if symbol is not None:
1176
+ market = self.market(symbol)
1177
+ request = {}
1178
+ if limit is not None:
1179
+ request['count'] = limit
1180
+ if since is not None:
1181
+ request['from'] = since
1182
+ response = await self.historyGetOrders(self.extend(request, params))
1183
+ allOrders = self.safe_list(response, 'elements', [])
1184
+ canceledAndRejected = []
1185
+ for i in range(0, len(allOrders)):
1186
+ order = allOrders[i]
1187
+ event = self.safe_dict(order, 'event', {})
1188
+ orderPlaced = self.safe_dict(event, 'OrderPlaced')
1189
+ if orderPlaced is not None:
1190
+ innerOrder = self.safe_dict(orderPlaced, 'order', {})
1191
+ filled = self.safe_string(innerOrder, 'filled')
1192
+ if filled == '0':
1193
+ innerOrder['status'] = 'canceled' # status not available in the response
1194
+ canceledAndRejected.append(innerOrder)
1195
+ orderCanceled = self.safe_dict(event, 'OrderCancelled')
1196
+ if orderCanceled is not None:
1197
+ innerOrder = self.safe_dict(orderCanceled, 'order', {})
1198
+ innerOrder['status'] = 'canceled' # status not available in the response
1199
+ canceledAndRejected.append(innerOrder)
1200
+ orderRejected = self.safe_dict(event, 'OrderRejected')
1201
+ if orderRejected is not None:
1202
+ innerOrder = self.safe_dict(orderRejected, 'order', {})
1203
+ innerOrder['status'] = 'rejected' # status not available in the response
1204
+ canceledAndRejected.append(innerOrder)
1205
+ return self.parse_orders(canceledAndRejected, market, since, limit)
1206
+
1128
1207
  def parse_order_type(self, orderType):
1129
1208
  map = {
1130
1209
  'lmt': 'limit',
@@ -1367,6 +1446,32 @@ class krakenfutures(Exchange, ImplicitAPI):
1367
1446
  # "status": "requiredArgumentMissing",
1368
1447
  # "orderEvents": []
1369
1448
  # }
1449
+ # closed orders
1450
+ # {
1451
+ # uid: '2f00cd63-e61d-44f8-8569-adabde885941',
1452
+ # timestamp: '1707258274849',
1453
+ # event: {
1454
+ # OrderPlaced: {
1455
+ # order: {
1456
+ # uid: '85805e01-9eed-4395-8360-ed1a228237c9',
1457
+ # accountUid: '406142dd-7c5c-4a8b-acbc-5f16eca30009',
1458
+ # tradeable: 'PF_LTCUSD',
1459
+ # direction: 'Buy',
1460
+ # quantity: '0',
1461
+ # filled: '0.1',
1462
+ # timestamp: '1707258274849',
1463
+ # limitPrice: '69.2200000000',
1464
+ # orderType: 'IoC',
1465
+ # clientId: '',
1466
+ # reduceOnly: False,
1467
+ # lastUpdateTimestamp: '1707258274849'
1468
+ # },
1469
+ # reason: 'new_user_order',
1470
+ # reducedQuantity: '',
1471
+ # algoId: ''
1472
+ # }
1473
+ # }
1474
+ # }
1370
1475
  #
1371
1476
  orderEvents = self.safe_value(order, 'orderEvents', [])
1372
1477
  errorStatus = self.safe_string(order, 'status')
@@ -1419,7 +1524,8 @@ class krakenfutures(Exchange, ImplicitAPI):
1419
1524
  remaining = self.safe_string(details, 'unfilledSize')
1420
1525
  average = None
1421
1526
  filled2 = '0.0'
1422
- if len(trades):
1527
+ tradesLength = len(trades)
1528
+ if tradesLength > 0:
1423
1529
  vwapSum = '0.0'
1424
1530
  for i in range(0, len(trades)):
1425
1531
  trade = trades[i]
@@ -1043,7 +1043,7 @@ class mexc(Exchange, ImplicitAPI):
1043
1043
 
1044
1044
  async def fetch_markets(self, params={}):
1045
1045
  """
1046
- retrieves data on all markets for mexc3
1046
+ retrieves data on all markets for mexc
1047
1047
  :param dict [params]: extra parameters specific to the exchange API endpoint
1048
1048
  :returns dict[]: an array of objects representing market data
1049
1049
  """