ccxt 4.2.39 → 4.2.40

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 (47) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +923 -310
  3. package/dist/ccxt.browser.min.js +2 -2
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/ascendex.js +28 -24
  6. package/dist/cjs/src/base/Exchange.js +14 -14
  7. package/dist/cjs/src/binance.js +372 -146
  8. package/dist/cjs/src/bingx.js +250 -23
  9. package/dist/cjs/src/bitget.js +13 -2
  10. package/dist/cjs/src/bybit.js +3 -1
  11. package/dist/cjs/src/coinbase.js +8 -6
  12. package/dist/cjs/src/coinbasepro.js +1 -0
  13. package/dist/cjs/src/coinlist.js +9 -7
  14. package/dist/cjs/src/coinmetro.js +2 -1
  15. package/dist/cjs/src/krakenfutures.js +126 -2
  16. package/dist/cjs/src/mexc.js +43 -43
  17. package/dist/cjs/src/okx.js +9 -15
  18. package/dist/cjs/src/phemex.js +1 -0
  19. package/dist/cjs/src/pro/bitmart.js +38 -20
  20. package/dist/cjs/src/pro/bybit.js +5 -5
  21. package/js/ccxt.d.ts +1 -1
  22. package/js/ccxt.js +1 -1
  23. package/js/src/abstract/bingx.d.ts +4 -0
  24. package/js/src/abstract/coinbasepro.d.ts +1 -0
  25. package/js/src/ascendex.js +28 -24
  26. package/js/src/base/Exchange.d.ts +8 -8
  27. package/js/src/base/Exchange.js +14 -14
  28. package/js/src/binance.d.ts +1 -1
  29. package/js/src/binance.js +372 -146
  30. package/js/src/bingx.d.ts +1 -0
  31. package/js/src/bingx.js +250 -23
  32. package/js/src/bitget.js +13 -2
  33. package/js/src/bybit.js +3 -1
  34. package/js/src/coinbase.js +8 -6
  35. package/js/src/coinbasepro.js +1 -0
  36. package/js/src/coinlist.js +9 -7
  37. package/js/src/coinmetro.js +2 -1
  38. package/js/src/krakenfutures.d.ts +2 -0
  39. package/js/src/krakenfutures.js +126 -2
  40. package/js/src/mexc.js +43 -43
  41. package/js/src/okx.js +9 -15
  42. package/js/src/phemex.js +1 -0
  43. package/js/src/pro/bitmart.d.ts +2 -0
  44. package/js/src/pro/bitmart.js +38 -20
  45. package/js/src/pro/bybit.d.ts +1 -1
  46. package/js/src/pro/bybit.js +5 -5
  47. package/package.json +1 -1
@@ -140,6 +140,7 @@ class bingx extends bingx$1 {
140
140
  'trade/order': 3,
141
141
  'trade/cancel': 3,
142
142
  'trade/batchOrders': 3,
143
+ 'trade/order/cancelReplace': 3,
143
144
  'trade/cancelOrders': 3,
144
145
  'trade/cancelOpenOrders': 3,
145
146
  },
@@ -161,12 +162,19 @@ class bingx extends bingx$1 {
161
162
  },
162
163
  'swap': {
163
164
  'v1': {
165
+ 'public': {
166
+ 'get': {
167
+ 'ticker/price': 1,
168
+ },
169
+ },
164
170
  'private': {
165
171
  'get': {
166
172
  'positionSide/dual': 1,
167
173
  'market/markPriceKlines': 1,
174
+ 'trade/batchCancelReplace': 1,
168
175
  },
169
176
  'post': {
177
+ 'trade/cancelReplace': 1,
170
178
  'positionSide/dual': 1,
171
179
  },
172
180
  },
@@ -2241,22 +2249,104 @@ class bingx extends bingx$1 {
2241
2249
  // reduceOnly: false
2242
2250
  // }
2243
2251
  //
2252
+ // editOrder (swap)
2253
+ //
2254
+ // {
2255
+ // cancelResult: 'true',
2256
+ // cancelMsg: '',
2257
+ // cancelResponse: {
2258
+ // cancelClientOrderId: '',
2259
+ // cancelOrderId: '1755336244265705472',
2260
+ // symbol: 'SOL-USDT',
2261
+ // orderId: '1755336244265705472',
2262
+ // side: 'SELL',
2263
+ // positionSide: 'SHORT',
2264
+ // type: 'LIMIT',
2265
+ // origQty: '1',
2266
+ // price: '100.000',
2267
+ // executedQty: '0',
2268
+ // avgPrice: '0.000',
2269
+ // cumQuote: '0',
2270
+ // stopPrice: '',
2271
+ // profit: '0.0000',
2272
+ // commission: '0.000000',
2273
+ // status: 'PENDING',
2274
+ // time: '1707339747860',
2275
+ // updateTime: '1707339747860',
2276
+ // clientOrderId: '',
2277
+ // leverage: '20X',
2278
+ // workingType: 'MARK_PRICE',
2279
+ // onlyOnePosition: false,
2280
+ // reduceOnly: false
2281
+ // },
2282
+ // replaceResult: 'true',
2283
+ // replaceMsg: '',
2284
+ // newOrderResponse: {
2285
+ // orderId: '1755338440612995072',
2286
+ // symbol: 'SOL-USDT',
2287
+ // positionSide: 'SHORT',
2288
+ // side: 'SELL',
2289
+ // type: 'LIMIT',
2290
+ // price: '99',
2291
+ // quantity: '2',
2292
+ // stopPrice: '0',
2293
+ // workingType: 'MARK_PRICE',
2294
+ // clientOrderID: '',
2295
+ // timeInForce: 'GTC',
2296
+ // priceRate: '0',
2297
+ // stopLoss: '',
2298
+ // takeProfit: '',
2299
+ // reduceOnly: false
2300
+ // }
2301
+ // }
2302
+ //
2303
+ // editOrder (spot)
2304
+ //
2305
+ // {
2306
+ // cancelResult: { code: '0', msg: '', result: true },
2307
+ // openResult: { code: '0', msg: '', result: true },
2308
+ // orderOpenResponse: {
2309
+ // symbol: 'SOL-USDT',
2310
+ // orderId: '1755334007697866752',
2311
+ // transactTime: '1707339214620',
2312
+ // price: '99',
2313
+ // stopPrice: '0',
2314
+ // origQty: '0.2',
2315
+ // executedQty: '0',
2316
+ // cummulativeQuoteQty: '0',
2317
+ // status: 'PENDING',
2318
+ // type: 'LIMIT',
2319
+ // side: 'SELL',
2320
+ // clientOrderID: ''
2321
+ // },
2322
+ // orderCancelResponse: {
2323
+ // symbol: 'SOL-USDT',
2324
+ // orderId: '1755117055251480576',
2325
+ // price: '100',
2326
+ // stopPrice: '0',
2327
+ // origQty: '0.2',
2328
+ // executedQty: '0',
2329
+ // cummulativeQuoteQty: '0',
2330
+ // status: 'CANCELED',
2331
+ // type: 'LIMIT',
2332
+ // side: 'SELL'
2333
+ // }
2334
+ // }
2335
+ //
2336
+ const info = order;
2337
+ const newOrder = this.safeDict2(order, 'newOrderResponse', 'orderOpenResponse');
2338
+ if (newOrder !== undefined) {
2339
+ order = newOrder;
2340
+ }
2244
2341
  const positionSide = this.safeString2(order, 'positionSide', 'ps');
2245
2342
  const marketType = (positionSide === undefined) ? 'spot' : 'swap';
2246
2343
  const marketId = this.safeString2(order, 'symbol', 's');
2247
2344
  if (market === undefined) {
2248
2345
  market = this.safeMarket(marketId, undefined, undefined, marketType);
2249
2346
  }
2250
- const symbol = this.safeSymbol(marketId, market, '-', marketType);
2251
- const orderId = this.safeString2(order, 'orderId', 'i');
2252
2347
  const side = this.safeStringLower2(order, 'side', 'S');
2253
- const type = this.safeStringLower2(order, 'type', 'o');
2254
2348
  const timestamp = this.safeIntegerN(order, ['time', 'transactTime', 'E']);
2255
2349
  const lastTradeTimestamp = this.safeInteger2(order, 'updateTime', 'T');
2256
- const price = this.safeString2(order, 'price', 'p');
2257
- const average = this.safeString2(order, 'avgPrice', 'ap');
2258
- const amount = this.safeString2(order, 'origQty', 'q');
2259
- const filled = this.safeString2(order, 'executedQty', 'z');
2260
2350
  const statusId = this.safeString2(order, 'status', 'X');
2261
2351
  let feeCurrencyCode = this.safeString2(order, 'feeAsset', 'N');
2262
2352
  const feeCost = this.safeStringN(order, ['fee', 'commission', 'n']);
@@ -2273,11 +2363,6 @@ class bingx extends bingx$1 {
2273
2363
  feeCurrencyCode = market['quote'];
2274
2364
  }
2275
2365
  }
2276
- const fee = {
2277
- 'currency': feeCurrencyCode,
2278
- 'cost': Precise["default"].stringAbs(feeCost),
2279
- };
2280
- const clientOrderId = this.safeStringN(order, ['clientOrderID', 'origClientOrderId', 'c']);
2281
2366
  let stopLoss = this.safeValue(order, 'stopLoss');
2282
2367
  let stopLossPrice = undefined;
2283
2368
  if ((stopLoss !== undefined) && (stopLoss !== '')) {
@@ -2303,31 +2388,35 @@ class bingx extends bingx$1 {
2303
2388
  takeProfitPrice = this.safeNumber(takeProfit, 'stopPrice');
2304
2389
  }
2305
2390
  return this.safeOrder({
2306
- 'info': order,
2307
- 'id': orderId,
2308
- 'clientOrderId': clientOrderId,
2391
+ 'info': info,
2392
+ 'id': this.safeString2(order, 'orderId', 'i'),
2393
+ 'clientOrderId': this.safeStringN(order, ['clientOrderID', 'origClientOrderId', 'c']),
2394
+ 'symbol': this.safeSymbol(marketId, market, '-', marketType),
2309
2395
  'timestamp': timestamp,
2310
2396
  'datetime': this.iso8601(timestamp),
2311
2397
  'lastTradeTimestamp': lastTradeTimestamp,
2312
2398
  'lastUpdateTimestamp': this.safeInteger(order, 'updateTime'),
2313
- 'symbol': symbol,
2314
- 'type': type,
2315
- 'timeInForce': undefined,
2399
+ 'type': this.safeStringLower2(order, 'type', 'o'),
2400
+ 'timeInForce': this.safeString(order, 'timeInForce'),
2316
2401
  'postOnly': undefined,
2317
2402
  'side': this.parseOrderSide(side),
2318
- 'price': price,
2403
+ 'price': this.safeString2(order, 'price', 'p'),
2319
2404
  'stopPrice': this.safeNumber(order, 'stopPrice'),
2320
2405
  'triggerPrice': this.safeNumber(order, 'stopPrice'),
2321
2406
  'stopLossPrice': stopLossPrice,
2322
2407
  'takeProfitPrice': takeProfitPrice,
2323
- 'average': average,
2408
+ 'average': this.safeString2(order, 'avgPrice', 'ap'),
2324
2409
  'cost': undefined,
2325
- 'amount': amount,
2326
- 'filled': filled,
2410
+ 'amount': this.safeStringN(order, ['origQty', 'q', 'quantity']),
2411
+ 'filled': this.safeString2(order, 'executedQty', 'z'),
2327
2412
  'remaining': undefined,
2328
2413
  'status': this.parseOrderStatus(statusId),
2329
- 'fee': fee,
2414
+ 'fee': {
2415
+ 'currency': feeCurrencyCode,
2416
+ 'cost': Precise["default"].stringAbs(feeCost),
2417
+ },
2330
2418
  'trades': undefined,
2419
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
2331
2420
  }, market);
2332
2421
  }
2333
2422
  parseOrderStatus(status) {
@@ -3836,6 +3925,144 @@ class bingx extends bingx$1 {
3836
3925
  //
3837
3926
  return await this.swapV1PrivatePostPositionSideDual(this.extend(request, params));
3838
3927
  }
3928
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
3929
+ /**
3930
+ * @method
3931
+ * @name bingx#editOrder
3932
+ * @description cancels an order and places a new order
3933
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20order%20and%20place%20a%20new%20order // spot
3934
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20an%20order%20and%20then%20Place%20a%20new%20order // swap
3935
+ * @param {string} id order id
3936
+ * @param {string} symbol unified symbol of the market to create an order in
3937
+ * @param {string} type 'market' or 'limit'
3938
+ * @param {string} side 'buy' or 'sell'
3939
+ * @param {float} amount how much of the currency you want to trade in units of the base currency
3940
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
3941
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3942
+ * @param {string} [params.stopPrice] Trigger price used for TAKE_STOP_LIMIT, TAKE_STOP_MARKET, TRIGGER_LIMIT, TRIGGER_MARKET order types.
3943
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
3944
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
3945
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
3946
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
3947
+ *
3948
+ * EXCHANGE SPECIFIC PARAMETERS
3949
+ * @param {string} [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
3950
+ * @param {string} [params.cancelRestrictions] cancel orders with specified status, NEW: New order, PENDING: Pending order, PARTIALLY_FILLED: Partially filled
3951
+ * @param {string} [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
3952
+ * @param {float} [params.quoteOrderQty] order amount
3953
+ * @param {string} [params.newClientOrderId] custom order id consisting of letters, numbers, and _, 1-40 characters, different orders cannot use the same newClientOrderId.
3954
+ * @param {string} [params.positionSide] *contract only* position direction, required for single position as BOTH, for both long and short positions only LONG or SHORT can be chosen, defaults to LONG if empty
3955
+ * @param {string} [params.reduceOnly] *contract only* true or false, default=false for single position mode. this parameter is not accepted for both long and short positions mode
3956
+ * @param {float} [params.priceRate] *contract only* for type TRAILING_STOP_Market, Max = 1
3957
+ * @param {string} [params.workingType] *contract only* StopPrice trigger price types, MARK_PRICE (default), CONTRACT_PRICE, or INDEX_PRICE
3958
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3959
+ */
3960
+ await this.loadMarkets();
3961
+ const market = this.market(symbol);
3962
+ const request = this.createOrderRequest(symbol, type, side, amount, price, params);
3963
+ request['cancelOrderId'] = id;
3964
+ request['cancelReplaceMode'] = 'STOP_ON_FAILURE';
3965
+ let response = undefined;
3966
+ if (market['swap']) {
3967
+ response = await this.swapV1PrivatePostTradeCancelReplace(this.extend(request, params));
3968
+ //
3969
+ // {
3970
+ // code: '0',
3971
+ // msg: '',
3972
+ // data: {
3973
+ // cancelResult: 'true',
3974
+ // cancelMsg: '',
3975
+ // cancelResponse: {
3976
+ // cancelClientOrderId: '',
3977
+ // cancelOrderId: '1755336244265705472',
3978
+ // symbol: 'SOL-USDT',
3979
+ // orderId: '1755336244265705472',
3980
+ // side: 'SELL',
3981
+ // positionSide: 'SHORT',
3982
+ // type: 'LIMIT',
3983
+ // origQty: '1',
3984
+ // price: '100.000',
3985
+ // executedQty: '0',
3986
+ // avgPrice: '0.000',
3987
+ // cumQuote: '0',
3988
+ // stopPrice: '',
3989
+ // profit: '0.0000',
3990
+ // commission: '0.000000',
3991
+ // status: 'PENDING',
3992
+ // time: '1707339747860',
3993
+ // updateTime: '1707339747860',
3994
+ // clientOrderId: '',
3995
+ // leverage: '20X',
3996
+ // workingType: 'MARK_PRICE',
3997
+ // onlyOnePosition: false,
3998
+ // reduceOnly: false
3999
+ // },
4000
+ // replaceResult: 'true',
4001
+ // replaceMsg: '',
4002
+ // newOrderResponse: {
4003
+ // orderId: '1755338440612995072',
4004
+ // symbol: 'SOL-USDT',
4005
+ // positionSide: 'SHORT',
4006
+ // side: 'SELL',
4007
+ // type: 'LIMIT',
4008
+ // price: '99',
4009
+ // quantity: '2',
4010
+ // stopPrice: '0',
4011
+ // workingType: 'MARK_PRICE',
4012
+ // clientOrderID: '',
4013
+ // timeInForce: 'GTC',
4014
+ // priceRate: '0',
4015
+ // stopLoss: '',
4016
+ // takeProfit: '',
4017
+ // reduceOnly: false
4018
+ // }
4019
+ // }
4020
+ // }
4021
+ //
4022
+ }
4023
+ else {
4024
+ response = await this.spotV1PrivatePostTradeOrderCancelReplace(this.extend(request, params));
4025
+ //
4026
+ // {
4027
+ // code: '0',
4028
+ // msg: '',
4029
+ // debugMsg: '',
4030
+ // data: {
4031
+ // cancelResult: { code: '0', msg: '', result: true },
4032
+ // openResult: { code: '0', msg: '', result: true },
4033
+ // orderOpenResponse: {
4034
+ // symbol: 'SOL-USDT',
4035
+ // orderId: '1755334007697866752',
4036
+ // transactTime: '1707339214620',
4037
+ // price: '99',
4038
+ // stopPrice: '0',
4039
+ // origQty: '0.2',
4040
+ // executedQty: '0',
4041
+ // cummulativeQuoteQty: '0',
4042
+ // status: 'PENDING',
4043
+ // type: 'LIMIT',
4044
+ // side: 'SELL',
4045
+ // clientOrderID: ''
4046
+ // },
4047
+ // orderCancelResponse: {
4048
+ // symbol: 'SOL-USDT',
4049
+ // orderId: '1755117055251480576',
4050
+ // price: '100',
4051
+ // stopPrice: '0',
4052
+ // origQty: '0.2',
4053
+ // executedQty: '0',
4054
+ // cummulativeQuoteQty: '0',
4055
+ // status: 'CANCELED',
4056
+ // type: 'LIMIT',
4057
+ // side: 'SELL'
4058
+ // }
4059
+ // }
4060
+ // }
4061
+ //
4062
+ }
4063
+ const data = this.safeDict(response, 'data');
4064
+ return this.parseOrder(data, market);
4065
+ }
3839
4066
  sign(path, section = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3840
4067
  const type = section[0];
3841
4068
  const version = section[1];
@@ -3949,6 +3949,13 @@ class bitget extends bitget$1 {
3949
3949
  size = this.safeString(order, 'size');
3950
3950
  filled = this.safeString(order, 'baseVolume');
3951
3951
  }
3952
+ let side = this.safeString(order, 'side');
3953
+ const posMode = this.safeString(order, 'posMode');
3954
+ if (posMode === 'hedge_mode' && reduceOnly) {
3955
+ side = (side === 'buy') ? 'sell' : 'buy';
3956
+ // 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
3957
+ // so the side of the reduceOnly order is inversed
3958
+ }
3952
3959
  return this.safeOrder({
3953
3960
  'info': order,
3954
3961
  'id': this.safeString2(order, 'orderId', 'data'),
@@ -3959,7 +3966,7 @@ class bitget extends bitget$1 {
3959
3966
  'lastUpdateTimestamp': updateTimestamp,
3960
3967
  'symbol': market['symbol'],
3961
3968
  'type': this.safeString(order, 'orderType'),
3962
- 'side': this.safeString(order, 'side'),
3969
+ 'side': side,
3963
3970
  'price': price,
3964
3971
  'amount': size,
3965
3972
  'cost': this.safeString2(order, 'quoteVolume', 'quoteSize'),
@@ -8286,7 +8293,11 @@ class bitget extends bitget$1 {
8286
8293
  }
8287
8294
  else {
8288
8295
  if (Object.keys(params).length) {
8289
- const queryInner = '?' + this.urlencode(this.keysort(params));
8296
+ let queryInner = '?' + this.urlencode(this.keysort(params));
8297
+ // check #21169 pr
8298
+ if (queryInner.indexOf('%24') > -1) {
8299
+ queryInner = queryInner.replace('%24', '$');
8300
+ }
8290
8301
  url += queryInner;
8291
8302
  auth += queryInner;
8292
8303
  }
@@ -2217,6 +2217,7 @@ class bybit extends bybit$1 {
2217
2217
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
2218
2218
  * @param {int} [limit] the maximum amount of candles to fetch
2219
2219
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2220
+ * @param {int} [params.until] the latest time in ms to fetch orders for
2220
2221
  * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2221
2222
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
2222
2223
  */
@@ -2230,7 +2231,7 @@ class bybit extends bybit$1 {
2230
2231
  return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000);
2231
2232
  }
2232
2233
  const market = this.market(symbol);
2233
- const request = {
2234
+ let request = {
2234
2235
  'symbol': market['id'],
2235
2236
  };
2236
2237
  if (limit === undefined) {
@@ -2242,6 +2243,7 @@ class bybit extends bybit$1 {
2242
2243
  if (limit !== undefined) {
2243
2244
  request['limit'] = limit; // max 1000, default 1000
2244
2245
  }
2246
+ [request, params] = this.handleUntilOption('end', request, params);
2245
2247
  request['interval'] = this.safeString(this.timeframes, timeframe, timeframe);
2246
2248
  let response = undefined;
2247
2249
  if (market['spot']) {
@@ -427,11 +427,12 @@ class coinbase extends coinbase$1 {
427
427
  // ]
428
428
  // }
429
429
  //
430
- const data = this.safeValue(response, 'data', []);
431
- const pagination = this.safeValue(response, 'pagination', {});
430
+ const data = this.safeList(response, 'data', []);
431
+ const pagination = this.safeDict(response, 'pagination', {});
432
432
  const cursor = this.safeString(pagination, 'next_starting_after');
433
- const accounts = this.safeValue(response, 'data', []);
434
- const lastIndex = accounts.length - 1;
433
+ const accounts = this.safeList(response, 'data', []);
434
+ const length = accounts.length;
435
+ const lastIndex = length - 1;
435
436
  const last = this.safeValue(accounts, lastIndex);
436
437
  if ((cursor !== undefined) && (cursor !== '')) {
437
438
  last['next_starting_after'] = cursor;
@@ -480,8 +481,9 @@ class coinbase extends coinbase$1 {
480
481
  // "size": 9
481
482
  // }
482
483
  //
483
- const accounts = this.safeValue(response, 'accounts', []);
484
- const lastIndex = accounts.length - 1;
484
+ const accounts = this.safeList(response, 'accounts', []);
485
+ const length = accounts.length;
486
+ const lastIndex = length - 1;
485
487
  const last = this.safeValue(accounts, lastIndex);
486
488
  const cursor = this.safeString(response, 'cursor');
487
489
  if ((cursor !== undefined) && (cursor !== '')) {
@@ -147,6 +147,7 @@ class coinbasepro extends coinbasepro$1 {
147
147
  'users/self/trailing-volume',
148
148
  'withdrawals/fee-estimate',
149
149
  'conversions/{conversion_id}',
150
+ 'conversions/fees',
150
151
  ],
151
152
  'post': [
152
153
  'conversions',
@@ -1034,13 +1034,15 @@ class coinlist extends coinlist$1 {
1034
1034
  }
1035
1035
  takerFees = this.sortBy(takerFees, 1, true);
1036
1036
  makerFees = this.sortBy(makerFees, 1, true);
1037
- const firstTier = this.safeValue(takerFees, 0, []);
1038
- const exchangeFees = this.safeValue(this, 'fees', {});
1039
- const exchangeFeesTrading = this.safeValue(exchangeFees, 'trading', {});
1040
- const exchangeFeesTradingTiers = this.safeValue(exchangeFeesTrading, 'tiers', {});
1041
- const exchangeFeesTradingTiersTaker = this.safeValue(exchangeFeesTradingTiers, 'taker', []);
1042
- const exchangeFeesTradingTiersMaker = this.safeValue(exchangeFeesTradingTiers, 'maker', []);
1043
- if ((keysLength === exchangeFeesTradingTiersTaker.length) && (firstTier.length > 0)) {
1037
+ const firstTier = this.safeDict(takerFees, 0, []);
1038
+ const exchangeFees = this.safeDict(this, 'fees', {});
1039
+ const exchangeFeesTrading = this.safeDict(exchangeFees, 'trading', {});
1040
+ const exchangeFeesTradingTiers = this.safeDict(exchangeFeesTrading, 'tiers', {});
1041
+ const exchangeFeesTradingTiersTaker = this.safeList(exchangeFeesTradingTiers, 'taker', []);
1042
+ const exchangeFeesTradingTiersMaker = this.safeList(exchangeFeesTradingTiers, 'maker', []);
1043
+ const exchangeFeesTradingTiersTakerLength = exchangeFeesTradingTiersTaker.length;
1044
+ const firstTierLength = firstTier.length;
1045
+ if ((keysLength === exchangeFeesTradingTiersTakerLength) && (firstTierLength > 0)) {
1044
1046
  for (let i = 0; i < keysLength; i++) {
1045
1047
  takerFees[i][0] = exchangeFeesTradingTiersTaker[i][0];
1046
1048
  makerFees[i][0] = exchangeFeesTradingTiersMaker[i][0];
@@ -1166,7 +1166,8 @@ class coinmetro extends coinmetro$1 {
1166
1166
  }
1167
1167
  let type = undefined;
1168
1168
  let referenceId = undefined;
1169
- if (descriptionArray.length > 1) {
1169
+ const length = descriptionArray.length;
1170
+ if (length > 1) {
1170
1171
  type = this.parseLedgerEntryType(descriptionArray[0]);
1171
1172
  if (descriptionArray[1] !== '-') {
1172
1173
  referenceId = descriptionArray[1];
@@ -39,7 +39,8 @@ class krakenfutures extends krakenfutures$1 {
39
39
  'fetchBalance': true,
40
40
  'fetchBorrowRateHistories': false,
41
41
  'fetchBorrowRateHistory': false,
42
- 'fetchClosedOrders': undefined,
42
+ 'fetchCanceledOrders': true,
43
+ 'fetchClosedOrders': true,
43
44
  'fetchCrossBorrowRate': false,
44
45
  'fetchCrossBorrowRates': false,
45
46
  'fetchDepositAddress': false,
@@ -1186,6 +1187,102 @@ class krakenfutures extends krakenfutures$1 {
1186
1187
  const orders = this.safeValue(response, 'openOrders', []);
1187
1188
  return this.parseOrders(orders, market, since, limit);
1188
1189
  }
1190
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1191
+ /**
1192
+ * @method
1193
+ * @name krakenfutures#fetchClosedOrders
1194
+ * @see https://docs.futures.kraken.com/#http-api-history-account-history-get-order-events
1195
+ * @description Gets all closed orders, including trigger orders, for an account from the exchange api
1196
+ * @param {string} symbol Unified market symbol
1197
+ * @param {int} [since] Timestamp (ms) of earliest order.
1198
+ * @param {int} [limit] How many orders to return.
1199
+ * @param {object} [params] Exchange specific parameters
1200
+ * @returns An array of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1201
+ */
1202
+ await this.loadMarkets();
1203
+ let market = undefined;
1204
+ if (symbol !== undefined) {
1205
+ market = this.market(symbol);
1206
+ }
1207
+ const request = {};
1208
+ if (limit !== undefined) {
1209
+ request['count'] = limit;
1210
+ }
1211
+ if (since !== undefined) {
1212
+ request['from'] = since;
1213
+ }
1214
+ const response = await this.historyGetOrders(this.extend(request, params));
1215
+ const allOrders = this.safeList(response, 'elements', []);
1216
+ const closedOrders = [];
1217
+ for (let i = 0; i < allOrders.length; i++) {
1218
+ const order = allOrders[i];
1219
+ const event = this.safeDict(order, 'event', {});
1220
+ const orderPlaced = this.safeDict(event, 'OrderPlaced');
1221
+ if (orderPlaced !== undefined) {
1222
+ const innerOrder = this.safeDict(orderPlaced, 'order', {});
1223
+ const filled = this.safeString(innerOrder, 'filled');
1224
+ if (filled !== '0') {
1225
+ innerOrder['status'] = 'closed'; // status not available in the response
1226
+ closedOrders.push(innerOrder);
1227
+ }
1228
+ }
1229
+ }
1230
+ return this.parseOrders(closedOrders, market, since, limit);
1231
+ }
1232
+ async fetchCanceledOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1233
+ /**
1234
+ * @method
1235
+ * @name krakenfutures#fetchCanceledOrders
1236
+ * @see https://docs.futures.kraken.com/#http-api-history-account-history-get-order-events
1237
+ * @description Gets all canceled orders, including trigger orders, for an account from the exchange api
1238
+ * @param {string} symbol Unified market symbol
1239
+ * @param {int} [since] Timestamp (ms) of earliest order.
1240
+ * @param {int} [limit] How many orders to return.
1241
+ * @param {object} [params] Exchange specific parameters
1242
+ * @returns An array of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1243
+ */
1244
+ await this.loadMarkets();
1245
+ let market = undefined;
1246
+ if (symbol !== undefined) {
1247
+ market = this.market(symbol);
1248
+ }
1249
+ const request = {};
1250
+ if (limit !== undefined) {
1251
+ request['count'] = limit;
1252
+ }
1253
+ if (since !== undefined) {
1254
+ request['from'] = since;
1255
+ }
1256
+ const response = await this.historyGetOrders(this.extend(request, params));
1257
+ const allOrders = this.safeList(response, 'elements', []);
1258
+ const canceledAndRejected = [];
1259
+ for (let i = 0; i < allOrders.length; i++) {
1260
+ const order = allOrders[i];
1261
+ const event = this.safeDict(order, 'event', {});
1262
+ const orderPlaced = this.safeDict(event, 'OrderPlaced');
1263
+ if (orderPlaced !== undefined) {
1264
+ const innerOrder = this.safeDict(orderPlaced, 'order', {});
1265
+ const filled = this.safeString(innerOrder, 'filled');
1266
+ if (filled === '0') {
1267
+ innerOrder['status'] = 'canceled'; // status not available in the response
1268
+ canceledAndRejected.push(innerOrder);
1269
+ }
1270
+ }
1271
+ const orderCanceled = this.safeDict(event, 'OrderCancelled');
1272
+ if (orderCanceled !== undefined) {
1273
+ const innerOrder = this.safeDict(orderCanceled, 'order', {});
1274
+ innerOrder['status'] = 'canceled'; // status not available in the response
1275
+ canceledAndRejected.push(innerOrder);
1276
+ }
1277
+ const orderRejected = this.safeDict(event, 'OrderRejected');
1278
+ if (orderRejected !== undefined) {
1279
+ const innerOrder = this.safeDict(orderRejected, 'order', {});
1280
+ innerOrder['status'] = 'rejected'; // status not available in the response
1281
+ canceledAndRejected.push(innerOrder);
1282
+ }
1283
+ }
1284
+ return this.parseOrders(canceledAndRejected, market, since, limit);
1285
+ }
1189
1286
  parseOrderType(orderType) {
1190
1287
  const map = {
1191
1288
  'lmt': 'limit',
@@ -1429,6 +1526,32 @@ class krakenfutures extends krakenfutures$1 {
1429
1526
  // "status": "requiredArgumentMissing",
1430
1527
  // "orderEvents": []
1431
1528
  // }
1529
+ // closed orders
1530
+ // {
1531
+ // uid: '2f00cd63-e61d-44f8-8569-adabde885941',
1532
+ // timestamp: '1707258274849',
1533
+ // event: {
1534
+ // OrderPlaced: {
1535
+ // order: {
1536
+ // uid: '85805e01-9eed-4395-8360-ed1a228237c9',
1537
+ // accountUid: '406142dd-7c5c-4a8b-acbc-5f16eca30009',
1538
+ // tradeable: 'PF_LTCUSD',
1539
+ // direction: 'Buy',
1540
+ // quantity: '0',
1541
+ // filled: '0.1',
1542
+ // timestamp: '1707258274849',
1543
+ // limitPrice: '69.2200000000',
1544
+ // orderType: 'IoC',
1545
+ // clientId: '',
1546
+ // reduceOnly: false,
1547
+ // lastUpdateTimestamp: '1707258274849'
1548
+ // },
1549
+ // reason: 'new_user_order',
1550
+ // reducedQuantity: '',
1551
+ // algoId: ''
1552
+ // }
1553
+ // }
1554
+ // }
1432
1555
  //
1433
1556
  const orderEvents = this.safeValue(order, 'orderEvents', []);
1434
1557
  const errorStatus = this.safeString(order, 'status');
@@ -1491,7 +1614,8 @@ class krakenfutures extends krakenfutures$1 {
1491
1614
  let remaining = this.safeString(details, 'unfilledSize');
1492
1615
  let average = undefined;
1493
1616
  let filled2 = '0.0';
1494
- if (trades.length) {
1617
+ const tradesLength = trades.length;
1618
+ if (tradesLength > 0) {
1495
1619
  let vwapSum = '0.0';
1496
1620
  for (let i = 0; i < trades.length; i++) {
1497
1621
  const trade = trades[i];