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.

ccxt/bingx.py CHANGED
@@ -153,6 +153,7 @@ class bingx(Exchange, ImplicitAPI):
153
153
  'trade/order': 3,
154
154
  'trade/cancel': 3,
155
155
  'trade/batchOrders': 3,
156
+ 'trade/order/cancelReplace': 3,
156
157
  'trade/cancelOrders': 3,
157
158
  'trade/cancelOpenOrders': 3,
158
159
  },
@@ -174,12 +175,19 @@ class bingx(Exchange, ImplicitAPI):
174
175
  },
175
176
  'swap': {
176
177
  'v1': {
178
+ 'public': {
179
+ 'get': {
180
+ 'ticker/price': 1,
181
+ },
182
+ },
177
183
  'private': {
178
184
  'get': {
179
185
  'positionSide/dual': 1,
180
186
  'market/markPriceKlines': 1,
187
+ 'trade/batchCancelReplace': 1,
181
188
  },
182
189
  'post': {
190
+ 'trade/cancelReplace': 1,
183
191
  'positionSide/dual': 1,
184
192
  },
185
193
  },
@@ -2116,21 +2124,102 @@ class bingx(Exchange, ImplicitAPI):
2116
2124
  # reduceOnly: False
2117
2125
  # }
2118
2126
  #
2127
+ # editOrder(swap)
2128
+ #
2129
+ # {
2130
+ # cancelResult: 'true',
2131
+ # cancelMsg: '',
2132
+ # cancelResponse: {
2133
+ # cancelClientOrderId: '',
2134
+ # cancelOrderId: '1755336244265705472',
2135
+ # symbol: 'SOL-USDT',
2136
+ # orderId: '1755336244265705472',
2137
+ # side: 'SELL',
2138
+ # positionSide: 'SHORT',
2139
+ # type: 'LIMIT',
2140
+ # origQty: '1',
2141
+ # price: '100.000',
2142
+ # executedQty: '0',
2143
+ # avgPrice: '0.000',
2144
+ # cumQuote: '0',
2145
+ # stopPrice: '',
2146
+ # profit: '0.0000',
2147
+ # commission: '0.000000',
2148
+ # status: 'PENDING',
2149
+ # time: '1707339747860',
2150
+ # updateTime: '1707339747860',
2151
+ # clientOrderId: '',
2152
+ # leverage: '20X',
2153
+ # workingType: 'MARK_PRICE',
2154
+ # onlyOnePosition: False,
2155
+ # reduceOnly: False
2156
+ # },
2157
+ # replaceResult: 'true',
2158
+ # replaceMsg: '',
2159
+ # newOrderResponse: {
2160
+ # orderId: '1755338440612995072',
2161
+ # symbol: 'SOL-USDT',
2162
+ # positionSide: 'SHORT',
2163
+ # side: 'SELL',
2164
+ # type: 'LIMIT',
2165
+ # price: '99',
2166
+ # quantity: '2',
2167
+ # stopPrice: '0',
2168
+ # workingType: 'MARK_PRICE',
2169
+ # clientOrderID: '',
2170
+ # timeInForce: 'GTC',
2171
+ # priceRate: '0',
2172
+ # stopLoss: '',
2173
+ # takeProfit: '',
2174
+ # reduceOnly: False
2175
+ # }
2176
+ # }
2177
+ #
2178
+ # editOrder(spot)
2179
+ #
2180
+ # {
2181
+ # cancelResult: {code: '0', msg: '', result: True},
2182
+ # openResult: {code: '0', msg: '', result: True},
2183
+ # orderOpenResponse: {
2184
+ # symbol: 'SOL-USDT',
2185
+ # orderId: '1755334007697866752',
2186
+ # transactTime: '1707339214620',
2187
+ # price: '99',
2188
+ # stopPrice: '0',
2189
+ # origQty: '0.2',
2190
+ # executedQty: '0',
2191
+ # cummulativeQuoteQty: '0',
2192
+ # status: 'PENDING',
2193
+ # type: 'LIMIT',
2194
+ # side: 'SELL',
2195
+ # clientOrderID: ''
2196
+ # },
2197
+ # orderCancelResponse: {
2198
+ # symbol: 'SOL-USDT',
2199
+ # orderId: '1755117055251480576',
2200
+ # price: '100',
2201
+ # stopPrice: '0',
2202
+ # origQty: '0.2',
2203
+ # executedQty: '0',
2204
+ # cummulativeQuoteQty: '0',
2205
+ # status: 'CANCELED',
2206
+ # type: 'LIMIT',
2207
+ # side: 'SELL'
2208
+ # }
2209
+ # }
2210
+ #
2211
+ info = order
2212
+ newOrder = self.safe_dict_2(order, 'newOrderResponse', 'orderOpenResponse')
2213
+ if newOrder is not None:
2214
+ order = newOrder
2119
2215
  positionSide = self.safe_string_2(order, 'positionSide', 'ps')
2120
2216
  marketType = 'spot' if (positionSide is None) else 'swap'
2121
2217
  marketId = self.safe_string_2(order, 'symbol', 's')
2122
2218
  if market is None:
2123
2219
  market = self.safe_market(marketId, None, None, marketType)
2124
- symbol = self.safe_symbol(marketId, market, '-', marketType)
2125
- orderId = self.safe_string_2(order, 'orderId', 'i')
2126
2220
  side = self.safe_string_lower_2(order, 'side', 'S')
2127
- type = self.safe_string_lower_2(order, 'type', 'o')
2128
2221
  timestamp = self.safe_integer_n(order, ['time', 'transactTime', 'E'])
2129
2222
  lastTradeTimestamp = self.safe_integer_2(order, 'updateTime', 'T')
2130
- price = self.safe_string_2(order, 'price', 'p')
2131
- average = self.safe_string_2(order, 'avgPrice', 'ap')
2132
- amount = self.safe_string_2(order, 'origQty', 'q')
2133
- filled = self.safe_string_2(order, 'executedQty', 'z')
2134
2223
  statusId = self.safe_string_2(order, 'status', 'X')
2135
2224
  feeCurrencyCode = self.safe_string_2(order, 'feeAsset', 'N')
2136
2225
  feeCost = self.safe_string_n(order, ['fee', 'commission', 'n'])
@@ -2142,11 +2231,6 @@ class bingx(Exchange, ImplicitAPI):
2142
2231
  feeCurrencyCode = market['quote']
2143
2232
  else:
2144
2233
  feeCurrencyCode = market['quote']
2145
- fee = {
2146
- 'currency': feeCurrencyCode,
2147
- 'cost': Precise.string_abs(feeCost),
2148
- }
2149
- clientOrderId = self.safe_string_n(order, ['clientOrderID', 'origClientOrderId', 'c'])
2150
2234
  stopLoss = self.safe_value(order, 'stopLoss')
2151
2235
  stopLossPrice = None
2152
2236
  if (stopLoss is not None) and (stopLoss != ''):
@@ -2166,31 +2250,35 @@ class bingx(Exchange, ImplicitAPI):
2166
2250
  takeProfit = self.parse_json(takeProfit)
2167
2251
  takeProfitPrice = self.safe_number(takeProfit, 'stopPrice')
2168
2252
  return self.safe_order({
2169
- 'info': order,
2170
- 'id': orderId,
2171
- 'clientOrderId': clientOrderId,
2253
+ 'info': info,
2254
+ 'id': self.safe_string_2(order, 'orderId', 'i'),
2255
+ 'clientOrderId': self.safe_string_n(order, ['clientOrderID', 'origClientOrderId', 'c']),
2256
+ 'symbol': self.safe_symbol(marketId, market, '-', marketType),
2172
2257
  'timestamp': timestamp,
2173
2258
  'datetime': self.iso8601(timestamp),
2174
2259
  'lastTradeTimestamp': lastTradeTimestamp,
2175
2260
  'lastUpdateTimestamp': self.safe_integer(order, 'updateTime'),
2176
- 'symbol': symbol,
2177
- 'type': type,
2178
- 'timeInForce': None,
2261
+ 'type': self.safe_string_lower_2(order, 'type', 'o'),
2262
+ 'timeInForce': self.safe_string(order, 'timeInForce'),
2179
2263
  'postOnly': None,
2180
2264
  'side': self.parse_order_side(side),
2181
- 'price': price,
2265
+ 'price': self.safe_string_2(order, 'price', 'p'),
2182
2266
  'stopPrice': self.safe_number(order, 'stopPrice'),
2183
2267
  'triggerPrice': self.safe_number(order, 'stopPrice'),
2184
2268
  'stopLossPrice': stopLossPrice,
2185
2269
  'takeProfitPrice': takeProfitPrice,
2186
- 'average': average,
2270
+ 'average': self.safe_string_2(order, 'avgPrice', 'ap'),
2187
2271
  'cost': None,
2188
- 'amount': amount,
2189
- 'filled': filled,
2272
+ 'amount': self.safe_string_n(order, ['origQty', 'q', 'quantity']),
2273
+ 'filled': self.safe_string_2(order, 'executedQty', 'z'),
2190
2274
  'remaining': None,
2191
2275
  'status': self.parse_order_status(statusId),
2192
- 'fee': fee,
2276
+ 'fee': {
2277
+ 'currency': feeCurrencyCode,
2278
+ 'cost': Precise.string_abs(feeCost),
2279
+ },
2193
2280
  'trades': None,
2281
+ 'reduceOnly': self.safe_bool(order, 'reduceOnly'),
2194
2282
  }, market)
2195
2283
 
2196
2284
  def parse_order_status(self, status):
@@ -3587,6 +3675,140 @@ class bingx(Exchange, ImplicitAPI):
3587
3675
  #
3588
3676
  return self.swapV1PrivatePostPositionSideDual(self.extend(request, params))
3589
3677
 
3678
+ def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float = None, price: float = None, params={}) -> Order:
3679
+ """
3680
+ cancels an order and places a new order
3681
+ :see: https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20order%20and%20place%20a%20new%20order # spot
3682
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20an%20order%20and%20then%20Place%20a%20new%20order # swap
3683
+ :param str id: order id
3684
+ :param str symbol: unified symbol of the market to create an order in
3685
+ :param str type: 'market' or 'limit'
3686
+ :param str side: 'buy' or 'sell'
3687
+ :param float amount: how much of the currency you want to trade in units of the base currency
3688
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
3689
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3690
+ :param str [params.stopPrice]: Trigger price used for TAKE_STOP_LIMIT, TAKE_STOP_MARKET, TRIGGER_LIMIT, TRIGGER_MARKET order types.
3691
+ :param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
3692
+ :param float [params.takeProfit.triggerPrice]: take profit trigger price
3693
+ :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
3694
+ :param float [params.stopLoss.triggerPrice]: stop loss trigger price
3695
+ *
3696
+ * EXCHANGE SPECIFIC PARAMETERS
3697
+ :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
3698
+ :param str [params.cancelRestrictions]: cancel orders with specified status, NEW: New order, PENDING: Pending order, PARTIALLY_FILLED: Partially filled
3699
+ :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
3700
+ :param float [params.quoteOrderQty]: order amount
3701
+ :param str [params.newClientOrderId]: custom order id consisting of letters, numbers, and _, 1-40 characters, different orders cannot use the same newClientOrderId.
3702
+ :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
3703
+ :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
3704
+ :param float [params.priceRate]: *contract only* for type TRAILING_STOP_Market, Max = 1
3705
+ :param str [params.workingType]: *contract only* StopPrice trigger price types, MARK_PRICE(default), CONTRACT_PRICE, or INDEX_PRICE
3706
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3707
+ """
3708
+ self.load_markets()
3709
+ market = self.market(symbol)
3710
+ request = self.create_order_request(symbol, type, side, amount, price, params)
3711
+ request['cancelOrderId'] = id
3712
+ request['cancelReplaceMode'] = 'STOP_ON_FAILURE'
3713
+ response = None
3714
+ if market['swap']:
3715
+ response = self.swapV1PrivatePostTradeCancelReplace(self.extend(request, params))
3716
+ #
3717
+ # {
3718
+ # code: '0',
3719
+ # msg: '',
3720
+ # data: {
3721
+ # cancelResult: 'true',
3722
+ # cancelMsg: '',
3723
+ # cancelResponse: {
3724
+ # cancelClientOrderId: '',
3725
+ # cancelOrderId: '1755336244265705472',
3726
+ # symbol: 'SOL-USDT',
3727
+ # orderId: '1755336244265705472',
3728
+ # side: 'SELL',
3729
+ # positionSide: 'SHORT',
3730
+ # type: 'LIMIT',
3731
+ # origQty: '1',
3732
+ # price: '100.000',
3733
+ # executedQty: '0',
3734
+ # avgPrice: '0.000',
3735
+ # cumQuote: '0',
3736
+ # stopPrice: '',
3737
+ # profit: '0.0000',
3738
+ # commission: '0.000000',
3739
+ # status: 'PENDING',
3740
+ # time: '1707339747860',
3741
+ # updateTime: '1707339747860',
3742
+ # clientOrderId: '',
3743
+ # leverage: '20X',
3744
+ # workingType: 'MARK_PRICE',
3745
+ # onlyOnePosition: False,
3746
+ # reduceOnly: False
3747
+ # },
3748
+ # replaceResult: 'true',
3749
+ # replaceMsg: '',
3750
+ # newOrderResponse: {
3751
+ # orderId: '1755338440612995072',
3752
+ # symbol: 'SOL-USDT',
3753
+ # positionSide: 'SHORT',
3754
+ # side: 'SELL',
3755
+ # type: 'LIMIT',
3756
+ # price: '99',
3757
+ # quantity: '2',
3758
+ # stopPrice: '0',
3759
+ # workingType: 'MARK_PRICE',
3760
+ # clientOrderID: '',
3761
+ # timeInForce: 'GTC',
3762
+ # priceRate: '0',
3763
+ # stopLoss: '',
3764
+ # takeProfit: '',
3765
+ # reduceOnly: False
3766
+ # }
3767
+ # }
3768
+ # }
3769
+ #
3770
+ else:
3771
+ response = self.spotV1PrivatePostTradeOrderCancelReplace(self.extend(request, params))
3772
+ #
3773
+ # {
3774
+ # code: '0',
3775
+ # msg: '',
3776
+ # debugMsg: '',
3777
+ # data: {
3778
+ # cancelResult: {code: '0', msg: '', result: True},
3779
+ # openResult: {code: '0', msg: '', result: True},
3780
+ # orderOpenResponse: {
3781
+ # symbol: 'SOL-USDT',
3782
+ # orderId: '1755334007697866752',
3783
+ # transactTime: '1707339214620',
3784
+ # price: '99',
3785
+ # stopPrice: '0',
3786
+ # origQty: '0.2',
3787
+ # executedQty: '0',
3788
+ # cummulativeQuoteQty: '0',
3789
+ # status: 'PENDING',
3790
+ # type: 'LIMIT',
3791
+ # side: 'SELL',
3792
+ # clientOrderID: ''
3793
+ # },
3794
+ # orderCancelResponse: {
3795
+ # symbol: 'SOL-USDT',
3796
+ # orderId: '1755117055251480576',
3797
+ # price: '100',
3798
+ # stopPrice: '0',
3799
+ # origQty: '0.2',
3800
+ # executedQty: '0',
3801
+ # cummulativeQuoteQty: '0',
3802
+ # status: 'CANCELED',
3803
+ # type: 'LIMIT',
3804
+ # side: 'SELL'
3805
+ # }
3806
+ # }
3807
+ # }
3808
+ #
3809
+ data = self.safe_dict(response, 'data')
3810
+ return self.parse_order(data, market)
3811
+
3590
3812
  def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
3591
3813
  type = section[0]
3592
3814
  version = section[1]
ccxt/bitget.py CHANGED
@@ -3794,6 +3794,12 @@ class bitget(Exchange, ImplicitAPI):
3794
3794
  else:
3795
3795
  size = self.safe_string(order, 'size')
3796
3796
  filled = self.safe_string(order, 'baseVolume')
3797
+ side = self.safe_string(order, 'side')
3798
+ posMode = self.safe_string(order, 'posMode')
3799
+ if posMode == 'hedge_mode' and reduceOnly:
3800
+ side = 'sell' if (side == 'buy') else 'buy'
3801
+ # 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
3802
+ # so the side of the reduceOnly order is inversed
3797
3803
  return self.safe_order({
3798
3804
  'info': order,
3799
3805
  'id': self.safe_string_2(order, 'orderId', 'data'),
@@ -3804,7 +3810,7 @@ class bitget(Exchange, ImplicitAPI):
3804
3810
  'lastUpdateTimestamp': updateTimestamp,
3805
3811
  'symbol': market['symbol'],
3806
3812
  'type': self.safe_string(order, 'orderType'),
3807
- 'side': self.safe_string(order, 'side'),
3813
+ 'side': side,
3808
3814
  'price': price,
3809
3815
  'amount': size,
3810
3816
  'cost': self.safe_string_2(order, 'quoteVolume', 'quoteSize'),
@@ -7711,6 +7717,9 @@ class bitget(Exchange, ImplicitAPI):
7711
7717
  else:
7712
7718
  if params:
7713
7719
  queryInner = '?' + self.urlencode(self.keysort(params))
7720
+ # check #21169 pr
7721
+ if queryInner.find('%24') > -1:
7722
+ queryInner = queryInner.replace('%24', '$')
7714
7723
  url += queryInner
7715
7724
  auth += queryInner
7716
7725
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256, 'base64')
ccxt/bybit.py CHANGED
@@ -2154,6 +2154,7 @@ class bybit(Exchange, ImplicitAPI):
2154
2154
  :param int [since]: timestamp in ms of the earliest candle to fetch
2155
2155
  :param int [limit]: the maximum amount of candles to fetch
2156
2156
  :param dict [params]: extra parameters specific to the exchange API endpoint
2157
+ :param int [params.until]: the latest time in ms to fetch orders for
2157
2158
  :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)
2158
2159
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
2159
2160
  """
@@ -2174,6 +2175,7 @@ class bybit(Exchange, ImplicitAPI):
2174
2175
  request['start'] = since
2175
2176
  if limit is not None:
2176
2177
  request['limit'] = limit # max 1000, default 1000
2178
+ request, params = self.handle_until_option('end', request, params)
2177
2179
  request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
2178
2180
  response = None
2179
2181
  if market['spot']:
ccxt/coinbase.py CHANGED
@@ -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 != ''):
ccxt/coinbasepro.py CHANGED
@@ -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',
ccxt/coinlist.py CHANGED
@@ -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]
ccxt/coinmetro.py CHANGED
@@ -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]
ccxt/krakenfutures.py CHANGED
@@ -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
+ 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
+ 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 = 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
+ 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
+ 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 = 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]
ccxt/mexc.py CHANGED
@@ -1043,7 +1043,7 @@ class mexc(Exchange, ImplicitAPI):
1043
1043
 
1044
1044
  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
  """