ccxt 4.2.39 → 4.2.41

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 (57) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1140 -341
  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 +561 -168
  8. package/dist/cjs/src/bingx.js +271 -25
  9. package/dist/cjs/src/bitforex.js +2 -2
  10. package/dist/cjs/src/bitget.js +13 -2
  11. package/dist/cjs/src/bybit.js +3 -1
  12. package/dist/cjs/src/coinbase.js +8 -6
  13. package/dist/cjs/src/coinbasepro.js +1 -0
  14. package/dist/cjs/src/coinlist.js +9 -7
  15. package/dist/cjs/src/coinmetro.js +2 -1
  16. package/dist/cjs/src/currencycom.js +1 -1
  17. package/dist/cjs/src/htx.js +1 -1
  18. package/dist/cjs/src/krakenfutures.js +126 -2
  19. package/dist/cjs/src/mexc.js +44 -44
  20. package/dist/cjs/src/okx.js +9 -15
  21. package/dist/cjs/src/phemex.js +1 -0
  22. package/dist/cjs/src/pro/bitmart.js +38 -20
  23. package/dist/cjs/src/pro/bybit.js +5 -5
  24. package/dist/cjs/src/pro/cex.js +1 -1
  25. package/dist/cjs/src/pro/gemini.js +1 -1
  26. package/js/ccxt.d.ts +1 -1
  27. package/js/ccxt.js +1 -1
  28. package/js/src/abstract/bingx.d.ts +4 -0
  29. package/js/src/abstract/coinbasepro.d.ts +1 -0
  30. package/js/src/ascendex.js +28 -24
  31. package/js/src/base/Exchange.d.ts +8 -8
  32. package/js/src/base/Exchange.js +14 -14
  33. package/js/src/binance.d.ts +1 -1
  34. package/js/src/binance.js +561 -168
  35. package/js/src/bingx.d.ts +2 -0
  36. package/js/src/bingx.js +271 -25
  37. package/js/src/bitforex.js +2 -2
  38. package/js/src/bitget.js +13 -2
  39. package/js/src/bybit.js +3 -1
  40. package/js/src/coinbase.js +8 -6
  41. package/js/src/coinbasepro.js +1 -0
  42. package/js/src/coinlist.js +9 -7
  43. package/js/src/coinmetro.js +2 -1
  44. package/js/src/currencycom.js +1 -1
  45. package/js/src/htx.js +1 -1
  46. package/js/src/krakenfutures.d.ts +2 -0
  47. package/js/src/krakenfutures.js +126 -2
  48. package/js/src/mexc.js +44 -44
  49. package/js/src/okx.js +9 -15
  50. package/js/src/phemex.js +1 -0
  51. package/js/src/pro/bitmart.d.ts +2 -0
  52. package/js/src/pro/bitmart.js +38 -20
  53. package/js/src/pro/bybit.d.ts +1 -1
  54. package/js/src/pro/bybit.js +5 -5
  55. package/js/src/pro/cex.js +1 -1
  56. package/js/src/pro/gemini.js +1 -1
  57. package/package.json +1 -1
package/js/src/bingx.d.ts CHANGED
@@ -73,6 +73,7 @@ export default class bingx extends Exchange {
73
73
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: number, params?: {}): Promise<Order>;
74
74
  createOrders(orders: OrderRequest[], params?: {}): Promise<Order[]>;
75
75
  parseOrderSide(side: any): string;
76
+ parseOrderType(type: any): string;
76
77
  parseOrder(order: any, market?: Market): Order;
77
78
  parseOrderStatus(status: any): string;
78
79
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
@@ -131,6 +132,7 @@ export default class bingx extends Exchange {
131
132
  closePosition(symbol: string, side?: OrderSide, params?: {}): Promise<Order>;
132
133
  closeAllPositions(params?: {}): Promise<Position[]>;
133
134
  setPositionMode(hedged: boolean, symbol?: Str, params?: {}): Promise<any>;
135
+ editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: number, price?: number, params?: {}): Promise<Order>;
134
136
  sign(path: any, section?: string, method?: string, params?: {}, headers?: any, body?: any): {
135
137
  url: any;
136
138
  method: string;
package/js/src/bingx.js CHANGED
@@ -143,6 +143,7 @@ export default class bingx extends Exchange {
143
143
  'trade/order': 3,
144
144
  'trade/cancel': 3,
145
145
  'trade/batchOrders': 3,
146
+ 'trade/order/cancelReplace': 3,
146
147
  'trade/cancelOrders': 3,
147
148
  'trade/cancelOpenOrders': 3,
148
149
  },
@@ -164,12 +165,19 @@ export default class bingx extends Exchange {
164
165
  },
165
166
  'swap': {
166
167
  'v1': {
168
+ 'public': {
169
+ 'get': {
170
+ 'ticker/price': 1,
171
+ },
172
+ },
167
173
  'private': {
168
174
  'get': {
169
175
  'positionSide/dual': 1,
170
176
  'market/markPriceKlines': 1,
177
+ 'trade/batchCancelReplace': 1,
171
178
  },
172
179
  'post': {
180
+ 'trade/cancelReplace': 1,
173
181
  'positionSide/dual': 1,
174
182
  },
175
183
  },
@@ -1792,6 +1800,7 @@ export default class bingx extends Exchange {
1792
1800
  if (timeInForce === 'IOC') {
1793
1801
  request['timeInForce'] = 'IOC';
1794
1802
  }
1803
+ const triggerPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
1795
1804
  if (isSpot) {
1796
1805
  [postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'POC', params);
1797
1806
  if (postOnly || (timeInForce === 'POC')) {
@@ -1803,7 +1812,7 @@ export default class bingx extends Exchange {
1803
1812
  request['quoteOrderQty'] = this.parseToNumeric(this.costToPrecision(symbol, cost));
1804
1813
  }
1805
1814
  else {
1806
- if (market['spot'] && isMarketOrder && (price !== undefined)) {
1815
+ if (isMarketOrder && (price !== undefined)) {
1807
1816
  // keep the legacy behavior, to avoid breaking the old spot-market-buying code
1808
1817
  const calculatedCost = Precise.stringMul(this.numberToString(amount), this.numberToString(price));
1809
1818
  request['quoteOrderQty'] = this.parseToNumeric(calculatedCost);
@@ -1815,6 +1824,18 @@ export default class bingx extends Exchange {
1815
1824
  if (!isMarketOrder) {
1816
1825
  request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
1817
1826
  }
1827
+ if (triggerPrice !== undefined) {
1828
+ if (isMarketOrder && this.safeString(request, 'quoteOrderQty') === undefined) {
1829
+ throw new ArgumentsRequired(this.id + ' createOrder() requires the cost parameter (or the amount + price) for placing spot market-buy trigger orders');
1830
+ }
1831
+ request['stopPrice'] = this.priceToPrecision(symbol, triggerPrice);
1832
+ if (type === 'LIMIT') {
1833
+ request['type'] = 'TRIGGER_LIMIT';
1834
+ }
1835
+ else if (type === 'MARKET') {
1836
+ request['type'] = 'TRIGGER_MARKET';
1837
+ }
1838
+ }
1818
1839
  }
1819
1840
  else {
1820
1841
  [postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'PostOnly', params);
@@ -1827,7 +1848,6 @@ export default class bingx extends Exchange {
1827
1848
  else if (timeInForce === 'FOK') {
1828
1849
  request['timeInForce'] = 'FOK';
1829
1850
  }
1830
- const triggerPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
1831
1851
  const stopLossPrice = this.safeString(params, 'stopLossPrice');
1832
1852
  const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
1833
1853
  const trailingAmount = this.safeString(params, 'trailingAmount');
@@ -2127,6 +2147,13 @@ export default class bingx extends Exchange {
2127
2147
  };
2128
2148
  return this.safeString(sides, side, side);
2129
2149
  }
2150
+ parseOrderType(type) {
2151
+ const types = {
2152
+ 'trigger_market': 'market',
2153
+ 'trigger_limit': 'limit',
2154
+ };
2155
+ return this.safeString(types, type, type);
2156
+ }
2130
2157
  parseOrder(order, market = undefined) {
2131
2158
  //
2132
2159
  // spot
@@ -2244,22 +2271,104 @@ export default class bingx extends Exchange {
2244
2271
  // reduceOnly: false
2245
2272
  // }
2246
2273
  //
2274
+ // editOrder (swap)
2275
+ //
2276
+ // {
2277
+ // cancelResult: 'true',
2278
+ // cancelMsg: '',
2279
+ // cancelResponse: {
2280
+ // cancelClientOrderId: '',
2281
+ // cancelOrderId: '1755336244265705472',
2282
+ // symbol: 'SOL-USDT',
2283
+ // orderId: '1755336244265705472',
2284
+ // side: 'SELL',
2285
+ // positionSide: 'SHORT',
2286
+ // type: 'LIMIT',
2287
+ // origQty: '1',
2288
+ // price: '100.000',
2289
+ // executedQty: '0',
2290
+ // avgPrice: '0.000',
2291
+ // cumQuote: '0',
2292
+ // stopPrice: '',
2293
+ // profit: '0.0000',
2294
+ // commission: '0.000000',
2295
+ // status: 'PENDING',
2296
+ // time: '1707339747860',
2297
+ // updateTime: '1707339747860',
2298
+ // clientOrderId: '',
2299
+ // leverage: '20X',
2300
+ // workingType: 'MARK_PRICE',
2301
+ // onlyOnePosition: false,
2302
+ // reduceOnly: false
2303
+ // },
2304
+ // replaceResult: 'true',
2305
+ // replaceMsg: '',
2306
+ // newOrderResponse: {
2307
+ // orderId: '1755338440612995072',
2308
+ // symbol: 'SOL-USDT',
2309
+ // positionSide: 'SHORT',
2310
+ // side: 'SELL',
2311
+ // type: 'LIMIT',
2312
+ // price: '99',
2313
+ // quantity: '2',
2314
+ // stopPrice: '0',
2315
+ // workingType: 'MARK_PRICE',
2316
+ // clientOrderID: '',
2317
+ // timeInForce: 'GTC',
2318
+ // priceRate: '0',
2319
+ // stopLoss: '',
2320
+ // takeProfit: '',
2321
+ // reduceOnly: false
2322
+ // }
2323
+ // }
2324
+ //
2325
+ // editOrder (spot)
2326
+ //
2327
+ // {
2328
+ // cancelResult: { code: '0', msg: '', result: true },
2329
+ // openResult: { code: '0', msg: '', result: true },
2330
+ // orderOpenResponse: {
2331
+ // symbol: 'SOL-USDT',
2332
+ // orderId: '1755334007697866752',
2333
+ // transactTime: '1707339214620',
2334
+ // price: '99',
2335
+ // stopPrice: '0',
2336
+ // origQty: '0.2',
2337
+ // executedQty: '0',
2338
+ // cummulativeQuoteQty: '0',
2339
+ // status: 'PENDING',
2340
+ // type: 'LIMIT',
2341
+ // side: 'SELL',
2342
+ // clientOrderID: ''
2343
+ // },
2344
+ // orderCancelResponse: {
2345
+ // symbol: 'SOL-USDT',
2346
+ // orderId: '1755117055251480576',
2347
+ // price: '100',
2348
+ // stopPrice: '0',
2349
+ // origQty: '0.2',
2350
+ // executedQty: '0',
2351
+ // cummulativeQuoteQty: '0',
2352
+ // status: 'CANCELED',
2353
+ // type: 'LIMIT',
2354
+ // side: 'SELL'
2355
+ // }
2356
+ // }
2357
+ //
2358
+ const info = order;
2359
+ const newOrder = this.safeDict2(order, 'newOrderResponse', 'orderOpenResponse');
2360
+ if (newOrder !== undefined) {
2361
+ order = newOrder;
2362
+ }
2247
2363
  const positionSide = this.safeString2(order, 'positionSide', 'ps');
2248
2364
  const marketType = (positionSide === undefined) ? 'spot' : 'swap';
2249
2365
  const marketId = this.safeString2(order, 'symbol', 's');
2250
2366
  if (market === undefined) {
2251
2367
  market = this.safeMarket(marketId, undefined, undefined, marketType);
2252
2368
  }
2253
- const symbol = this.safeSymbol(marketId, market, '-', marketType);
2254
- const orderId = this.safeString2(order, 'orderId', 'i');
2255
2369
  const side = this.safeStringLower2(order, 'side', 'S');
2256
- const type = this.safeStringLower2(order, 'type', 'o');
2257
2370
  const timestamp = this.safeIntegerN(order, ['time', 'transactTime', 'E']);
2258
2371
  const lastTradeTimestamp = this.safeInteger2(order, 'updateTime', 'T');
2259
- const price = this.safeString2(order, 'price', 'p');
2260
- const average = this.safeString2(order, 'avgPrice', 'ap');
2261
- const amount = this.safeString2(order, 'origQty', 'q');
2262
- const filled = this.safeString2(order, 'executedQty', 'z');
2263
2372
  const statusId = this.safeString2(order, 'status', 'X');
2264
2373
  let feeCurrencyCode = this.safeString2(order, 'feeAsset', 'N');
2265
2374
  const feeCost = this.safeStringN(order, ['fee', 'commission', 'n']);
@@ -2276,11 +2385,6 @@ export default class bingx extends Exchange {
2276
2385
  feeCurrencyCode = market['quote'];
2277
2386
  }
2278
2387
  }
2279
- const fee = {
2280
- 'currency': feeCurrencyCode,
2281
- 'cost': Precise.stringAbs(feeCost),
2282
- };
2283
- const clientOrderId = this.safeStringN(order, ['clientOrderID', 'origClientOrderId', 'c']);
2284
2388
  let stopLoss = this.safeValue(order, 'stopLoss');
2285
2389
  let stopLossPrice = undefined;
2286
2390
  if ((stopLoss !== undefined) && (stopLoss !== '')) {
@@ -2306,31 +2410,35 @@ export default class bingx extends Exchange {
2306
2410
  takeProfitPrice = this.safeNumber(takeProfit, 'stopPrice');
2307
2411
  }
2308
2412
  return this.safeOrder({
2309
- 'info': order,
2310
- 'id': orderId,
2311
- 'clientOrderId': clientOrderId,
2413
+ 'info': info,
2414
+ 'id': this.safeString2(order, 'orderId', 'i'),
2415
+ 'clientOrderId': this.safeStringN(order, ['clientOrderID', 'origClientOrderId', 'c']),
2416
+ 'symbol': this.safeSymbol(marketId, market, '-', marketType),
2312
2417
  'timestamp': timestamp,
2313
2418
  'datetime': this.iso8601(timestamp),
2314
2419
  'lastTradeTimestamp': lastTradeTimestamp,
2315
2420
  'lastUpdateTimestamp': this.safeInteger(order, 'updateTime'),
2316
- 'symbol': symbol,
2317
- 'type': type,
2318
- 'timeInForce': undefined,
2421
+ 'type': this.parseOrderType(this.safeStringLower2(order, 'type', 'o')),
2422
+ 'timeInForce': this.safeString(order, 'timeInForce'),
2319
2423
  'postOnly': undefined,
2320
2424
  'side': this.parseOrderSide(side),
2321
- 'price': price,
2425
+ 'price': this.safeString2(order, 'price', 'p'),
2322
2426
  'stopPrice': this.safeNumber(order, 'stopPrice'),
2323
2427
  'triggerPrice': this.safeNumber(order, 'stopPrice'),
2324
2428
  'stopLossPrice': stopLossPrice,
2325
2429
  'takeProfitPrice': takeProfitPrice,
2326
- 'average': average,
2430
+ 'average': this.safeString2(order, 'avgPrice', 'ap'),
2327
2431
  'cost': undefined,
2328
- 'amount': amount,
2329
- 'filled': filled,
2432
+ 'amount': this.safeStringN(order, ['origQty', 'q', 'quantity']),
2433
+ 'filled': this.safeString2(order, 'executedQty', 'z'),
2330
2434
  'remaining': undefined,
2331
2435
  'status': this.parseOrderStatus(statusId),
2332
- 'fee': fee,
2436
+ 'fee': {
2437
+ 'currency': feeCurrencyCode,
2438
+ 'cost': Precise.stringAbs(feeCost),
2439
+ },
2333
2440
  'trades': undefined,
2441
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
2334
2442
  }, market);
2335
2443
  }
2336
2444
  parseOrderStatus(status) {
@@ -3839,6 +3947,144 @@ export default class bingx extends Exchange {
3839
3947
  //
3840
3948
  return await this.swapV1PrivatePostPositionSideDual(this.extend(request, params));
3841
3949
  }
3950
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
3951
+ /**
3952
+ * @method
3953
+ * @name bingx#editOrder
3954
+ * @description cancels an order and places a new order
3955
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20order%20and%20place%20a%20new%20order // spot
3956
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20an%20order%20and%20then%20Place%20a%20new%20order // swap
3957
+ * @param {string} id order id
3958
+ * @param {string} symbol unified symbol of the market to create an order in
3959
+ * @param {string} type 'market' or 'limit'
3960
+ * @param {string} side 'buy' or 'sell'
3961
+ * @param {float} amount how much of the currency you want to trade in units of the base currency
3962
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
3963
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3964
+ * @param {string} [params.stopPrice] Trigger price used for TAKE_STOP_LIMIT, TAKE_STOP_MARKET, TRIGGER_LIMIT, TRIGGER_MARKET order types.
3965
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
3966
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
3967
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
3968
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
3969
+ *
3970
+ * EXCHANGE SPECIFIC PARAMETERS
3971
+ * @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
3972
+ * @param {string} [params.cancelRestrictions] cancel orders with specified status, NEW: New order, PENDING: Pending order, PARTIALLY_FILLED: Partially filled
3973
+ * @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
3974
+ * @param {float} [params.quoteOrderQty] order amount
3975
+ * @param {string} [params.newClientOrderId] custom order id consisting of letters, numbers, and _, 1-40 characters, different orders cannot use the same newClientOrderId.
3976
+ * @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
3977
+ * @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
3978
+ * @param {float} [params.priceRate] *contract only* for type TRAILING_STOP_Market, Max = 1
3979
+ * @param {string} [params.workingType] *contract only* StopPrice trigger price types, MARK_PRICE (default), CONTRACT_PRICE, or INDEX_PRICE
3980
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3981
+ */
3982
+ await this.loadMarkets();
3983
+ const market = this.market(symbol);
3984
+ const request = this.createOrderRequest(symbol, type, side, amount, price, params);
3985
+ request['cancelOrderId'] = id;
3986
+ request['cancelReplaceMode'] = 'STOP_ON_FAILURE';
3987
+ let response = undefined;
3988
+ if (market['swap']) {
3989
+ response = await this.swapV1PrivatePostTradeCancelReplace(this.extend(request, params));
3990
+ //
3991
+ // {
3992
+ // code: '0',
3993
+ // msg: '',
3994
+ // data: {
3995
+ // cancelResult: 'true',
3996
+ // cancelMsg: '',
3997
+ // cancelResponse: {
3998
+ // cancelClientOrderId: '',
3999
+ // cancelOrderId: '1755336244265705472',
4000
+ // symbol: 'SOL-USDT',
4001
+ // orderId: '1755336244265705472',
4002
+ // side: 'SELL',
4003
+ // positionSide: 'SHORT',
4004
+ // type: 'LIMIT',
4005
+ // origQty: '1',
4006
+ // price: '100.000',
4007
+ // executedQty: '0',
4008
+ // avgPrice: '0.000',
4009
+ // cumQuote: '0',
4010
+ // stopPrice: '',
4011
+ // profit: '0.0000',
4012
+ // commission: '0.000000',
4013
+ // status: 'PENDING',
4014
+ // time: '1707339747860',
4015
+ // updateTime: '1707339747860',
4016
+ // clientOrderId: '',
4017
+ // leverage: '20X',
4018
+ // workingType: 'MARK_PRICE',
4019
+ // onlyOnePosition: false,
4020
+ // reduceOnly: false
4021
+ // },
4022
+ // replaceResult: 'true',
4023
+ // replaceMsg: '',
4024
+ // newOrderResponse: {
4025
+ // orderId: '1755338440612995072',
4026
+ // symbol: 'SOL-USDT',
4027
+ // positionSide: 'SHORT',
4028
+ // side: 'SELL',
4029
+ // type: 'LIMIT',
4030
+ // price: '99',
4031
+ // quantity: '2',
4032
+ // stopPrice: '0',
4033
+ // workingType: 'MARK_PRICE',
4034
+ // clientOrderID: '',
4035
+ // timeInForce: 'GTC',
4036
+ // priceRate: '0',
4037
+ // stopLoss: '',
4038
+ // takeProfit: '',
4039
+ // reduceOnly: false
4040
+ // }
4041
+ // }
4042
+ // }
4043
+ //
4044
+ }
4045
+ else {
4046
+ response = await this.spotV1PrivatePostTradeOrderCancelReplace(this.extend(request, params));
4047
+ //
4048
+ // {
4049
+ // code: '0',
4050
+ // msg: '',
4051
+ // debugMsg: '',
4052
+ // data: {
4053
+ // cancelResult: { code: '0', msg: '', result: true },
4054
+ // openResult: { code: '0', msg: '', result: true },
4055
+ // orderOpenResponse: {
4056
+ // symbol: 'SOL-USDT',
4057
+ // orderId: '1755334007697866752',
4058
+ // transactTime: '1707339214620',
4059
+ // price: '99',
4060
+ // stopPrice: '0',
4061
+ // origQty: '0.2',
4062
+ // executedQty: '0',
4063
+ // cummulativeQuoteQty: '0',
4064
+ // status: 'PENDING',
4065
+ // type: 'LIMIT',
4066
+ // side: 'SELL',
4067
+ // clientOrderID: ''
4068
+ // },
4069
+ // orderCancelResponse: {
4070
+ // symbol: 'SOL-USDT',
4071
+ // orderId: '1755117055251480576',
4072
+ // price: '100',
4073
+ // stopPrice: '0',
4074
+ // origQty: '0.2',
4075
+ // executedQty: '0',
4076
+ // cummulativeQuoteQty: '0',
4077
+ // status: 'CANCELED',
4078
+ // type: 'LIMIT',
4079
+ // side: 'SELL'
4080
+ // }
4081
+ // }
4082
+ // }
4083
+ //
4084
+ }
4085
+ const data = this.safeDict(response, 'data');
4086
+ return this.parseOrder(data, market);
4087
+ }
3842
4088
  sign(path, section = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3843
4089
  const type = section[0];
3844
4090
  const version = section[1];
@@ -645,8 +645,8 @@ export default class bitforex extends Exchange {
645
645
  }
646
646
  parseOrder(order, market = undefined) {
647
647
  const id = this.safeString(order, 'orderId');
648
- const timestamp = this.safeNumber(order, 'createTime');
649
- const lastTradeTimestamp = this.safeNumber(order, 'lastTime');
648
+ const timestamp = this.safeInteger(order, 'createTime');
649
+ const lastTradeTimestamp = this.safeInteger(order, 'lastTime');
650
650
  const symbol = market['symbol'];
651
651
  const sideId = this.safeInteger(order, 'tradeType');
652
652
  const side = this.parseSide(sideId);
package/js/src/bitget.js CHANGED
@@ -3952,6 +3952,13 @@ export default class bitget extends Exchange {
3952
3952
  size = this.safeString(order, 'size');
3953
3953
  filled = this.safeString(order, 'baseVolume');
3954
3954
  }
3955
+ let side = this.safeString(order, 'side');
3956
+ const posMode = this.safeString(order, 'posMode');
3957
+ if (posMode === 'hedge_mode' && reduceOnly) {
3958
+ side = (side === 'buy') ? 'sell' : 'buy';
3959
+ // 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
3960
+ // so the side of the reduceOnly order is inversed
3961
+ }
3955
3962
  return this.safeOrder({
3956
3963
  'info': order,
3957
3964
  'id': this.safeString2(order, 'orderId', 'data'),
@@ -3962,7 +3969,7 @@ export default class bitget extends Exchange {
3962
3969
  'lastUpdateTimestamp': updateTimestamp,
3963
3970
  'symbol': market['symbol'],
3964
3971
  'type': this.safeString(order, 'orderType'),
3965
- 'side': this.safeString(order, 'side'),
3972
+ 'side': side,
3966
3973
  'price': price,
3967
3974
  'amount': size,
3968
3975
  'cost': this.safeString2(order, 'quoteVolume', 'quoteSize'),
@@ -8289,7 +8296,11 @@ export default class bitget extends Exchange {
8289
8296
  }
8290
8297
  else {
8291
8298
  if (Object.keys(params).length) {
8292
- const queryInner = '?' + this.urlencode(this.keysort(params));
8299
+ let queryInner = '?' + this.urlencode(this.keysort(params));
8300
+ // check #21169 pr
8301
+ if (queryInner.indexOf('%24') > -1) {
8302
+ queryInner = queryInner.replace('%24', '$');
8303
+ }
8293
8304
  url += queryInner;
8294
8305
  auth += queryInner;
8295
8306
  }
package/js/src/bybit.js CHANGED
@@ -2220,6 +2220,7 @@ export default class bybit extends Exchange {
2220
2220
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
2221
2221
  * @param {int} [limit] the maximum amount of candles to fetch
2222
2222
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2223
+ * @param {int} [params.until] the latest time in ms to fetch orders for
2223
2224
  * @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)
2224
2225
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
2225
2226
  */
@@ -2233,7 +2234,7 @@ export default class bybit extends Exchange {
2233
2234
  return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000);
2234
2235
  }
2235
2236
  const market = this.market(symbol);
2236
- const request = {
2237
+ let request = {
2237
2238
  'symbol': market['id'],
2238
2239
  };
2239
2240
  if (limit === undefined) {
@@ -2245,6 +2246,7 @@ export default class bybit extends Exchange {
2245
2246
  if (limit !== undefined) {
2246
2247
  request['limit'] = limit; // max 1000, default 1000
2247
2248
  }
2249
+ [request, params] = this.handleUntilOption('end', request, params);
2248
2250
  request['interval'] = this.safeString(this.timeframes, timeframe, timeframe);
2249
2251
  let response = undefined;
2250
2252
  if (market['spot']) {
@@ -430,11 +430,12 @@ export default class coinbase extends Exchange {
430
430
  // ]
431
431
  // }
432
432
  //
433
- const data = this.safeValue(response, 'data', []);
434
- const pagination = this.safeValue(response, 'pagination', {});
433
+ const data = this.safeList(response, 'data', []);
434
+ const pagination = this.safeDict(response, 'pagination', {});
435
435
  const cursor = this.safeString(pagination, 'next_starting_after');
436
- const accounts = this.safeValue(response, 'data', []);
437
- const lastIndex = accounts.length - 1;
436
+ const accounts = this.safeList(response, 'data', []);
437
+ const length = accounts.length;
438
+ const lastIndex = length - 1;
438
439
  const last = this.safeValue(accounts, lastIndex);
439
440
  if ((cursor !== undefined) && (cursor !== '')) {
440
441
  last['next_starting_after'] = cursor;
@@ -483,8 +484,9 @@ export default class coinbase extends Exchange {
483
484
  // "size": 9
484
485
  // }
485
486
  //
486
- const accounts = this.safeValue(response, 'accounts', []);
487
- const lastIndex = accounts.length - 1;
487
+ const accounts = this.safeList(response, 'accounts', []);
488
+ const length = accounts.length;
489
+ const lastIndex = length - 1;
488
490
  const last = this.safeValue(accounts, lastIndex);
489
491
  const cursor = this.safeString(response, 'cursor');
490
492
  if ((cursor !== undefined) && (cursor !== '')) {
@@ -150,6 +150,7 @@ export default class coinbasepro extends Exchange {
150
150
  'users/self/trailing-volume',
151
151
  'withdrawals/fee-estimate',
152
152
  'conversions/{conversion_id}',
153
+ 'conversions/fees',
153
154
  ],
154
155
  'post': [
155
156
  'conversions',
@@ -1037,13 +1037,15 @@ export default class coinlist extends Exchange {
1037
1037
  }
1038
1038
  takerFees = this.sortBy(takerFees, 1, true);
1039
1039
  makerFees = this.sortBy(makerFees, 1, true);
1040
- const firstTier = this.safeValue(takerFees, 0, []);
1041
- const exchangeFees = this.safeValue(this, 'fees', {});
1042
- const exchangeFeesTrading = this.safeValue(exchangeFees, 'trading', {});
1043
- const exchangeFeesTradingTiers = this.safeValue(exchangeFeesTrading, 'tiers', {});
1044
- const exchangeFeesTradingTiersTaker = this.safeValue(exchangeFeesTradingTiers, 'taker', []);
1045
- const exchangeFeesTradingTiersMaker = this.safeValue(exchangeFeesTradingTiers, 'maker', []);
1046
- if ((keysLength === exchangeFeesTradingTiersTaker.length) && (firstTier.length > 0)) {
1040
+ const firstTier = this.safeDict(takerFees, 0, []);
1041
+ const exchangeFees = this.safeDict(this, 'fees', {});
1042
+ const exchangeFeesTrading = this.safeDict(exchangeFees, 'trading', {});
1043
+ const exchangeFeesTradingTiers = this.safeDict(exchangeFeesTrading, 'tiers', {});
1044
+ const exchangeFeesTradingTiersTaker = this.safeList(exchangeFeesTradingTiers, 'taker', []);
1045
+ const exchangeFeesTradingTiersMaker = this.safeList(exchangeFeesTradingTiers, 'maker', []);
1046
+ const exchangeFeesTradingTiersTakerLength = exchangeFeesTradingTiersTaker.length;
1047
+ const firstTierLength = firstTier.length;
1048
+ if ((keysLength === exchangeFeesTradingTiersTakerLength) && (firstTierLength > 0)) {
1047
1049
  for (let i = 0; i < keysLength; i++) {
1048
1050
  takerFees[i][0] = exchangeFeesTradingTiersTaker[i][0];
1049
1051
  makerFees[i][0] = exchangeFeesTradingTiersMaker[i][0];
@@ -1169,7 +1169,8 @@ export default class coinmetro extends Exchange {
1169
1169
  }
1170
1170
  let type = undefined;
1171
1171
  let referenceId = undefined;
1172
- if (descriptionArray.length > 1) {
1172
+ const length = descriptionArray.length;
1173
+ if (length > 1) {
1173
1174
  type = this.parseLedgerEntryType(descriptionArray[0]);
1174
1175
  if (descriptionArray[1] !== '-') {
1175
1176
  referenceId = descriptionArray[1];
@@ -1939,7 +1939,7 @@ export default class currencycom extends Exchange {
1939
1939
  //
1940
1940
  market = this.safeMarket(this.safeString(position, 'symbol'), market);
1941
1941
  const symbol = market['symbol'];
1942
- const timestamp = this.safeNumber(position, 'createdTimestamp');
1942
+ const timestamp = this.safeInteger(position, 'createdTimestamp');
1943
1943
  const quantityRaw = this.safeString(position, 'openQuantity');
1944
1944
  const side = Precise.stringGt(quantityRaw, '0') ? 'long' : 'short';
1945
1945
  const quantity = Precise.stringAbs(quantityRaw);
package/js/src/htx.js CHANGED
@@ -7091,7 +7091,7 @@ export default class htx extends Exchange {
7091
7091
  const marginMode = (marketId === undefined) ? 'cross' : 'isolated';
7092
7092
  market = this.safeMarket(marketId);
7093
7093
  const symbol = this.safeString(market, 'symbol');
7094
- const timestamp = this.safeNumber(info, 'accrued-at');
7094
+ const timestamp = this.safeInteger(info, 'accrued-at');
7095
7095
  return {
7096
7096
  'account': (marginMode === 'isolated') ? symbol : 'cross',
7097
7097
  'symbol': symbol,
@@ -22,6 +22,8 @@ export default class krakenfutures extends Exchange {
22
22
  cancelOrders(ids: string[], symbol?: Str, params?: {}): Promise<Order[]>;
23
23
  cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
24
24
  fetchOpenOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
25
+ fetchClosedOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
26
+ fetchCanceledOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
25
27
  parseOrderType(orderType: any): string;
26
28
  verifyOrderActionSuccess(status: any, method: any, omit?: any[]): void;
27
29
  parseOrderStatus(status: any): string;