ccxt 4.5.35 → 4.5.36

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 (42) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/base/Exchange.js +4 -4
  5. package/dist/cjs/src/base/functions/generic.js +27 -10
  6. package/dist/cjs/src/base/functions/time.js +0 -2
  7. package/dist/cjs/src/base/functions.js +0 -1
  8. package/dist/cjs/src/bybit.js +9 -4
  9. package/dist/cjs/src/coinbase.js +18 -7
  10. package/dist/cjs/src/coinex.js +2 -0
  11. package/dist/cjs/src/krakenfutures.js +1 -1
  12. package/dist/cjs/src/pro/aster.js +27 -24
  13. package/dist/cjs/src/pro/binance.js +9 -12
  14. package/dist/cjs/src/pro/bitmex.js +5 -8
  15. package/dist/cjs/src/pro/bybit.js +8 -12
  16. package/dist/cjs/src/pro/bydfi.js +20 -43
  17. package/dist/cjs/src/pro/gate.js +7 -8
  18. package/dist/cjs/src/pro/okx.js +8 -12
  19. package/dist/cjs/src/woo.js +1 -1
  20. package/js/ccxt.d.ts +1 -1
  21. package/js/ccxt.js +1 -1
  22. package/js/src/abstract/coinex.d.ts +2 -0
  23. package/js/src/base/Exchange.d.ts +4 -4
  24. package/js/src/base/Exchange.js +4 -4
  25. package/js/src/base/functions/generic.d.ts +1 -1
  26. package/js/src/base/functions/generic.js +28 -11
  27. package/js/src/base/functions/time.d.ts +1 -2
  28. package/js/src/base/functions/time.js +1 -2
  29. package/js/src/bybit.js +9 -4
  30. package/js/src/coinbase.d.ts +2 -0
  31. package/js/src/coinbase.js +18 -7
  32. package/js/src/coinex.js +2 -0
  33. package/js/src/krakenfutures.js +1 -1
  34. package/js/src/pro/aster.js +27 -24
  35. package/js/src/pro/binance.js +9 -12
  36. package/js/src/pro/bitmex.js +5 -8
  37. package/js/src/pro/bybit.js +8 -12
  38. package/js/src/pro/bydfi.js +20 -43
  39. package/js/src/pro/gate.js +7 -8
  40. package/js/src/pro/okx.js +8 -12
  41. package/js/src/woo.js +1 -1
  42. package/package.json +1 -1
@@ -95,7 +95,7 @@ export default class Exchange {
95
95
  this.verbose = false;
96
96
  this.twofa = undefined; // two-factor authentication (2-FA)
97
97
  this.balance = {};
98
- this.liquidations = {};
98
+ this.liquidations = undefined;
99
99
  this.orderbooks = {};
100
100
  this.tickers = {};
101
101
  this.fundingRates = {};
@@ -103,7 +103,7 @@ export default class Exchange {
103
103
  this.orders = undefined;
104
104
  this.triggerOrders = undefined;
105
105
  this.transactions = {};
106
- this.myLiquidations = {};
106
+ this.myLiquidations = undefined;
107
107
  this.requiresWeb3 = false;
108
108
  this.requiresEddsa = false;
109
109
  this.precision = undefined;
@@ -313,12 +313,12 @@ export default class Exchange {
313
313
  this.bidsasks = {};
314
314
  this.orderbooks = {};
315
315
  this.tickers = {};
316
- this.liquidations = {};
316
+ this.liquidations = undefined;
317
317
  this.orders = undefined;
318
318
  this.trades = {};
319
319
  this.transactions = {};
320
320
  this.ohlcvs = {};
321
- this.myLiquidations = {};
321
+ this.myLiquidations = undefined;
322
322
  this.myTrades = undefined;
323
323
  this.positions = undefined;
324
324
  // web3 and cryptography flags
@@ -24,6 +24,6 @@ declare const flatten: (x: any[], out?: any[]) => any[];
24
24
  declare const pluck: (x: Dictionary<any>, k: any) => any[];
25
25
  declare const omit: (x: Dictionary<any>, ...args: any) => any;
26
26
  declare const sum: (...xs: any[]) => any;
27
- declare const deepExtend: (...xs: any) => any;
27
+ declare const deepExtend: (...args: any) => any;
28
28
  declare const merge: (target: Dictionary<any>, ...args: any) => Dictionary<any>;
29
29
  export { keys, values, extend, clone, index, ordered, unique, arrayConcat, inArray, toArray, isEmpty, sort, keysort, indexBy, groupBy, filterBy, sortBy, sortBy2, flatten, pluck, omit, sum, deepExtend, merge, };
@@ -5,7 +5,7 @@
5
5
  // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
6
 
7
7
  // ----------------------------------------------------------------------------
8
- import { isNumber, isDictionary, isArray } from './type.js';
8
+ import { isNumber, isArray } from './type.js';
9
9
  // ----------------------------------------------------------------------------
10
10
  const keys = Object.keys; // eslint-disable-line padding-line-between-statements
11
11
  const values = (x) => ((!isArray(x)) ? Object.values(x) : x); // don't copy arrays if they're already arrays
@@ -142,22 +142,39 @@ const sum = (...xs) => {
142
142
  const ns = xs.filter(isNumber); // leave only numbers
143
143
  return (ns.length > 0) ? ns.reduce((a, b) => a + b, 0) : undefined;
144
144
  };
145
- const deepExtend = function deepExtend(...xs) {
146
- let out = undefined;
147
- for (const x of xs) {
148
- if (isDictionary(x)) {
149
- if (!isDictionary(out)) {
150
- out = {};
145
+ const deepExtend = function (...args) {
146
+ let result = null;
147
+ let resultIsObject = false;
148
+ for (const arg of args) {
149
+ if (arg !== null && typeof arg === 'object' && arg.constructor === Object) {
150
+ // This is a plain object (even if empty) so set the return type.
151
+ if (result === null || !resultIsObject) {
152
+ result = {};
153
+ resultIsObject = true;
151
154
  }
152
- for (const k in x) {
153
- out[k] = deepExtend(out[k], x[k]);
155
+ // Skip actual merging if object is empty.
156
+ if (Object.keys(arg).length === 0) {
157
+ continue;
158
+ }
159
+ for (const key in arg) {
160
+ const value = arg[key];
161
+ const current = result[key];
162
+ if (current !== null && typeof current === 'object' && current.constructor === Object &&
163
+ value !== null && typeof value === 'object' && value.constructor === Object) {
164
+ result[key] = deepExtend(current, value);
165
+ }
166
+ else {
167
+ result[key] = value;
168
+ }
154
169
  }
155
170
  }
156
171
  else {
157
- out = x;
172
+ // arg is null or other non-object.
173
+ result = arg;
174
+ resultIsObject = false;
158
175
  }
159
176
  }
160
- return out;
177
+ return result;
161
178
  };
162
179
  const merge = (target, ...args) => {
163
180
  // doesn't overwrite defined keys with undefined
@@ -10,7 +10,6 @@ declare class TimedOut extends Error {
10
10
  declare const iso8601: (timestamp: any) => string;
11
11
  declare const parse8601: (x: any) => number;
12
12
  declare const parseDate: (x: any) => number;
13
- declare const rfc2616: (timestamp?: any) => string;
14
13
  declare const mdy: (timestamp: any, infix?: string) => string;
15
14
  declare const ymd: (timestamp: any, infix: any, fullYear?: boolean) => string;
16
15
  declare const yymmdd: (timestamp: any, infix?: string) => string;
@@ -18,4 +17,4 @@ declare const yyyymmdd: (timestamp: any, infix?: string) => string;
18
17
  declare const ymdhms: (timestamp: any, infix?: string) => string;
19
18
  declare const sleep: (ms: any) => Promise<unknown>;
20
19
  declare const timeout: (ms: any, promise: any) => Promise<any>;
21
- export { now, microseconds, milliseconds, seconds, iso8601, parse8601, rfc2616, uuidv1, parseDate, mdy, ymd, yymmdd, yyyymmdd, ymdhms, setTimeout_safe, sleep, TimedOut, timeout, };
20
+ export { now, microseconds, milliseconds, seconds, iso8601, parse8601, uuidv1, parseDate, mdy, ymd, yymmdd, yyyymmdd, ymdhms, setTimeout_safe, sleep, TimedOut, timeout, };
@@ -115,7 +115,6 @@ const parseDate = (x) => {
115
115
  }
116
116
  return parse8601(x);
117
117
  };
118
- const rfc2616 = (timestamp = undefined) => new Date(timestamp).toUTCString();
119
118
  const mdy = (timestamp, infix = '-') => {
120
119
  infix = infix || '';
121
120
  const date = new Date(timestamp);
@@ -168,4 +167,4 @@ const timeout = async (ms, promise) => {
168
167
  clear(); // fixes https://github.com/ccxt/ccxt/issues/749
169
168
  }
170
169
  };
171
- export { now, microseconds, milliseconds, seconds, iso8601, parse8601, rfc2616, uuidv1, parseDate, mdy, ymd, yymmdd, yyyymmdd, ymdhms, setTimeout_safe, sleep, TimedOut, timeout, };
170
+ export { now, microseconds, milliseconds, seconds, iso8601, parse8601, uuidv1, parseDate, mdy, ymd, yymmdd, yyyymmdd, ymdhms, setTimeout_safe, sleep, TimedOut, timeout, };
package/js/src/bybit.js CHANGED
@@ -350,7 +350,7 @@ export default class bybit extends Exchange {
350
350
  'v5/asset/coin-greeks': 1,
351
351
  'v5/account/fee-rate': 10,
352
352
  'v5/account/info': 5,
353
- 'v5/account/transaction-log': 1,
353
+ 'v5/account/transaction-log': 1.66,
354
354
  'v5/account/contract-transaction-log': 1,
355
355
  'v5/account/smp-group': 1,
356
356
  'v5/account/mmp-state': 5,
@@ -4187,11 +4187,16 @@ export default class bybit extends Exchange {
4187
4187
  }
4188
4188
  }
4189
4189
  }
4190
- if (tpslModeSl !== tpslModeTp) {
4190
+ if (isTakeProfitOrder && isStopLossOrder && tpslModeSl !== tpslModeTp) {
4191
4191
  throw new InvalidOrder(this.id + ' createOrder() requires both stopLoss and takeProfit to be full or partial when using as OCO combination');
4192
4192
  }
4193
- request['tpslMode'] = tpslModeSl; // same as tpslModeTp
4194
- params = this.omit(params, ['stopLossLimitPrice', 'takeProfitLimitPrice']);
4193
+ if (tpslModeSl !== undefined) {
4194
+ request['tpslMode'] = tpslModeSl;
4195
+ }
4196
+ else {
4197
+ request['tpslMode'] = tpslModeTp;
4198
+ }
4199
+ params = this.omit(params, ['stopLossLimitPrice', 'takeProfitLimitPrice', 'tradingStopEndpoint']);
4195
4200
  }
4196
4201
  }
4197
4202
  else {
@@ -251,6 +251,7 @@ export default class coinbase extends Exchange {
251
251
  * @param {string} [params.retail_portfolio_id] portfolio uid
252
252
  * @param {boolean} [params.is_max] Used in conjunction with tradable_balance to indicate the user wants to use their entire tradable balance
253
253
  * @param {string} [params.tradable_balance] amount of tradable balance
254
+ * @param {float} [params.reduceOnly] set to true for closing a position or use closePosition
254
255
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
255
256
  */
256
257
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
@@ -439,6 +440,7 @@ export default class coinbase extends Exchange {
439
440
  * @param {string} [tag] an optional tag for the withdrawal
440
441
  * @param {object} [params] extra parameters specific to the exchange API endpoint
441
442
  * @param {string} [params.network] the cryptocurrency network to use for the withdrawal using the lowercase name like bitcoin, ethereum, solana, etc.
443
+ * @param {object} [params.travel_rule_data] some regions require travel rule information for crypto withdrawals, see the exchange docs for details https://docs.cdp.coinbase.com/coinbase-app/transfer-apis/travel-rule
442
444
  * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/?id=transaction-structure}
443
445
  */
444
446
  withdraw(code: string, amount: number, address: string, tag?: Str, params?: {}): Promise<Transaction>;
@@ -2978,6 +2978,7 @@ export default class coinbase extends Exchange {
2978
2978
  * @param {string} [params.retail_portfolio_id] portfolio uid
2979
2979
  * @param {boolean} [params.is_max] Used in conjunction with tradable_balance to indicate the user wants to use their entire tradable balance
2980
2980
  * @param {string} [params.tradable_balance] amount of tradable balance
2981
+ * @param {float} [params.reduceOnly] set to true for closing a position or use closePosition
2981
2982
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
2982
2983
  */
2983
2984
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
@@ -2989,6 +2990,12 @@ export default class coinbase extends Exchange {
2989
2990
  'product_id': market['id'],
2990
2991
  'side': side.toUpperCase(),
2991
2992
  };
2993
+ const reduceOnly = this.safeBool(params, 'reduceOnly');
2994
+ if (reduceOnly) {
2995
+ params = this.omit(params, 'reduceOnly');
2996
+ params['amount'] = amount;
2997
+ return await this.closePosition(symbol, side, params);
2998
+ }
2992
2999
  const triggerPrice = this.safeNumberN(params, ['stopPrice', 'stop_price', 'triggerPrice']);
2993
3000
  const stopLossPrice = this.safeNumber(params, 'stopLossPrice');
2994
3001
  const takeProfitPrice = this.safeNumber(params, 'takeProfitPrice');
@@ -4102,6 +4109,7 @@ export default class coinbase extends Exchange {
4102
4109
  * @param {string} [tag] an optional tag for the withdrawal
4103
4110
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4104
4111
  * @param {string} [params.network] the cryptocurrency network to use for the withdrawal using the lowercase name like bitcoin, ethereum, solana, etc.
4112
+ * @param {object} [params.travel_rule_data] some regions require travel rule information for crypto withdrawals, see the exchange docs for details https://docs.cdp.coinbase.com/coinbase-app/transfer-apis/travel-rule
4105
4113
  * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/?id=transaction-structure}
4106
4114
  */
4107
4115
  async withdraw(code, amount, address, tag = undefined, params = {}) {
@@ -4109,6 +4117,12 @@ export default class coinbase extends Exchange {
4109
4117
  this.checkAddress(address);
4110
4118
  await this.loadMarkets();
4111
4119
  const currency = this.currency(code);
4120
+ const request = {
4121
+ 'type': 'send',
4122
+ 'to': address,
4123
+ 'amount': this.numberToString(amount),
4124
+ 'currency': currency['id'],
4125
+ };
4112
4126
  let accountId = this.safeString2(params, 'account_id', 'accountId');
4113
4127
  params = this.omit(params, ['account_id', 'accountId']);
4114
4128
  if (accountId === undefined) {
@@ -4119,14 +4133,11 @@ export default class coinbase extends Exchange {
4119
4133
  if (accountId === undefined) {
4120
4134
  throw new ExchangeError(this.id + ' withdraw() could not find account id for ' + code);
4121
4135
  }
4136
+ request['account_id'] = accountId;
4137
+ }
4138
+ else {
4139
+ request['account_id'] = accountId;
4122
4140
  }
4123
- const request = {
4124
- 'account_id': accountId,
4125
- 'type': 'send',
4126
- 'to': address,
4127
- 'amount': amount,
4128
- 'currency': currency['id'],
4129
- };
4130
4141
  if (tag !== undefined) {
4131
4142
  request['destination_tag'] = tag;
4132
4143
  }
package/js/src/coinex.js CHANGED
@@ -421,6 +421,8 @@ export default class coinex extends Exchange {
421
421
  'futures/stop-order': 20,
422
422
  'futures/batch-order': 1,
423
423
  'futures/batch-stop-order': 1,
424
+ 'futures/cancel-position-stop-loss': 20,
425
+ 'futures/cancel-position-take-profit': 20,
424
426
  'futures/modify-order': 20,
425
427
  'futures/modify-stop-order': 20,
426
428
  'futures/batch-modify-order': 20,
@@ -2693,7 +2693,7 @@ export default class krakenfutures extends Exchange {
2693
2693
  for (let i = 0; i < marginLevels.length; i++) {
2694
2694
  const tier = marginLevels[i];
2695
2695
  const initialMargin = this.safeString(tier, 'initialMargin');
2696
- const minNotional = this.safeNumber(tier, 'numNonContractUnits');
2696
+ const minNotional = this.safeNumber2(tier, 'numNonContractUnits', 'contracts');
2697
2697
  if (i !== 0) {
2698
2698
  const tiersLength = tiers.length;
2699
2699
  const previousTier = tiers[tiersLength - 1];
@@ -1481,23 +1481,26 @@ export default class aster extends asterRest {
1481
1481
  // }
1482
1482
  //
1483
1483
  const messageHash = 'positions';
1484
+ if (this.positions === undefined) {
1485
+ this.positions = new ArrayCacheBySymbolBySide();
1486
+ }
1487
+ const cache = this.positions;
1488
+ const data = this.safeDict(message, 'a', {});
1489
+ const rawPositions = this.safeList(data, 'P', []);
1490
+ const newPositions = [];
1491
+ for (let i = 0; i < rawPositions.length; i++) {
1492
+ const rawPosition = rawPositions[i];
1493
+ const position = this.parseWsPosition(rawPosition);
1494
+ const timestamp = this.safeInteger(message, 'E');
1495
+ position['timestamp'] = timestamp;
1496
+ position['datetime'] = this.iso8601(timestamp);
1497
+ newPositions.push(position);
1498
+ cache.append(position);
1499
+ }
1484
1500
  const messageHashes = this.findMessageHashes(client, messageHash);
1485
1501
  if (!this.isEmpty(messageHashes)) {
1486
- if (this.positions === undefined) {
1487
- this.positions = new ArrayCacheBySymbolBySide();
1488
- }
1489
- const cache = this.positions;
1490
- const data = this.safeDict(message, 'a', {});
1491
- const rawPositions = this.safeList(data, 'P', []);
1492
- const newPositions = [];
1493
- for (let i = 0; i < rawPositions.length; i++) {
1494
- const rawPosition = rawPositions[i];
1495
- const position = this.parseWsPosition(rawPosition);
1496
- const timestamp = this.safeInteger(message, 'E');
1497
- position['timestamp'] = timestamp;
1498
- position['datetime'] = this.iso8601(timestamp);
1499
- newPositions.push(position);
1500
- cache.append(position);
1502
+ for (let i = 0; i < newPositions.length; i++) {
1503
+ const position = newPositions[i];
1501
1504
  const symbol = position['symbol'];
1502
1505
  const symbolMessageHash = messageHash + '::' + symbol;
1503
1506
  client.resolve(position, symbolMessageHash);
@@ -1789,18 +1792,18 @@ export default class aster extends asterRest {
1789
1792
  // }
1790
1793
  //
1791
1794
  const messageHash = 'orders';
1795
+ const market = this.getMarketFromOrder(client, message);
1796
+ if (this.orders === undefined) {
1797
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
1798
+ this.orders = new ArrayCacheBySymbolById(limit);
1799
+ }
1800
+ const cache = this.orders;
1801
+ const parsed = this.parseWsOrder(message, market);
1802
+ const symbol = market['symbol'];
1803
+ cache.append(parsed);
1792
1804
  const messageHashes = this.findMessageHashes(client, messageHash);
1793
1805
  if (!this.isEmpty(messageHashes)) {
1794
- const market = this.getMarketFromOrder(client, message);
1795
- if (this.orders === undefined) {
1796
- const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
1797
- this.orders = new ArrayCacheBySymbolById(limit);
1798
- }
1799
- const cache = this.orders;
1800
- const parsed = this.parseWsOrder(message, market);
1801
- const symbol = market['symbol'];
1802
1806
  const symbolMessageHash = messageHash + '::' + symbol;
1803
- cache.append(parsed);
1804
1807
  client.resolve(cache, symbolMessageHash);
1805
1808
  client.resolve(cache, messageHash);
1806
1809
  }
@@ -352,13 +352,11 @@ export default class binance extends binanceRest {
352
352
  const market = this.safeMarket(marketId, undefined, '', 'contract');
353
353
  const symbol = market['symbol'];
354
354
  const liquidation = this.parseWsLiquidation(rawLiquidation, market);
355
- let liquidations = this.safeValue(this.liquidations, symbol);
356
- if (liquidations === undefined) {
357
- const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
358
- liquidations = new ArrayCache(limit);
355
+ if (this.liquidations === undefined) {
356
+ this.liquidations = new ArrayCacheBySymbolBySide();
359
357
  }
360
- liquidations.append(liquidation);
361
- this.liquidations[symbol] = liquidations;
358
+ const cache = this.liquidations;
359
+ cache.append(liquidation);
362
360
  client.resolve([liquidation], 'liquidations');
363
361
  client.resolve([liquidation], 'liquidations::' + symbol);
364
362
  }
@@ -563,13 +561,12 @@ export default class binance extends binanceRest {
563
561
  const market = this.safeMarket(marketId, undefined, undefined, 'swap');
564
562
  const symbol = this.safeSymbol(marketId, market);
565
563
  const liquidation = this.parseWsLiquidation(message, market);
566
- let myLiquidations = this.safeValue(this.myLiquidations, symbol);
567
- if (myLiquidations === undefined) {
568
- const limit = this.safeInteger(this.options, 'myLiquidationsLimit', 1000);
569
- myLiquidations = new ArrayCache(limit);
564
+ let cache = this.myLiquidations;
565
+ if (cache === undefined) {
566
+ cache = new ArrayCacheBySymbolBySide();
570
567
  }
571
- myLiquidations.append(liquidation);
572
- this.myLiquidations[symbol] = myLiquidations;
568
+ cache.append(liquidation);
569
+ this.myLiquidations = cache;
573
570
  client.resolve([liquidation], 'myLiquidations');
574
571
  client.resolve([liquidation], 'myLiquidations::' + symbol);
575
572
  }
@@ -442,17 +442,14 @@ export default class bitmex extends bitmexRest {
442
442
  //
443
443
  const rawLiquidations = this.safeValue(message, 'data', []);
444
444
  const newLiquidations = [];
445
+ if (this.liquidations === undefined) {
446
+ this.liquidations = new ArrayCacheBySymbolBySide();
447
+ }
448
+ const cache = this.liquidations;
445
449
  for (let i = 0; i < rawLiquidations.length; i++) {
446
450
  const rawLiquidation = rawLiquidations[i];
447
451
  const liquidation = this.parseLiquidation(rawLiquidation);
448
- const symbol = liquidation['symbol'];
449
- let liquidations = this.safeValue(this.liquidations, symbol);
450
- if (liquidations === undefined) {
451
- const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
452
- liquidations = new ArrayCache(limit);
453
- }
454
- liquidations.append(liquidation);
455
- this.liquidations[symbol] = liquidations;
452
+ cache.append(liquidation);
456
453
  newLiquidations.push(liquidation);
457
454
  }
458
455
  client.resolve(newLiquidations, 'liquidations');
@@ -1696,13 +1696,11 @@ export default class bybit extends bybitRest {
1696
1696
  const market = this.safeMarket(marketId, undefined, '', 'contract');
1697
1697
  const symbol = market['symbol'];
1698
1698
  const liquidation = this.parseWsLiquidation(rawLiquidation, market);
1699
- let liquidations = this.safeValue(this.liquidations, symbol);
1700
- if (liquidations === undefined) {
1701
- const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
1702
- liquidations = new ArrayCache(limit);
1699
+ if (this.liquidations === undefined) {
1700
+ this.liquidations = new ArrayCacheBySymbolBySide();
1703
1701
  }
1704
- liquidations.append(liquidation);
1705
- this.liquidations[symbol] = liquidations;
1702
+ const cache = this.liquidations;
1703
+ cache.append(liquidation);
1706
1704
  client.resolve([liquidation], 'liquidations');
1707
1705
  client.resolve([liquidation], 'liquidations::' + symbol);
1708
1706
  }
@@ -1713,13 +1711,11 @@ export default class bybit extends bybitRest {
1713
1711
  const market = this.safeMarket(marketId, undefined, '', 'contract');
1714
1712
  const symbol = market['symbol'];
1715
1713
  const liquidation = this.parseWsLiquidation(rawLiquidation, market);
1716
- let liquidations = this.safeValue(this.liquidations, symbol);
1717
- if (liquidations === undefined) {
1718
- const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
1719
- liquidations = new ArrayCache(limit);
1714
+ if (this.liquidations === undefined) {
1715
+ this.liquidations = new ArrayCacheBySymbolBySide();
1720
1716
  }
1721
- liquidations.append(liquidation);
1722
- this.liquidations[symbol] = liquidations;
1717
+ const cache = this.liquidations;
1718
+ cache.append(liquidation);
1723
1719
  client.resolve([liquidation], 'liquidations');
1724
1720
  client.resolve([liquidation], 'liquidations::' + symbol);
1725
1721
  }
@@ -618,30 +618,19 @@ export default class bydfi extends bydfiRest {
618
618
  const marketId = this.safeString(rawOrder, 's');
619
619
  const market = this.safeMarket(marketId);
620
620
  const symbol = market['symbol'];
621
- let match = false;
622
621
  const messageHash = 'orders';
623
622
  const symbolMessageHash = messageHash + '::' + symbol;
624
- const messageHashes = this.findMessageHashes(client, messageHash);
625
- for (let i = 0; i < messageHashes.length; i++) {
626
- const hash = messageHashes[i];
627
- if (hash === symbolMessageHash || hash === messageHash) {
628
- match = true;
629
- break;
630
- }
631
- }
632
- if (match) {
633
- if (this.orders === undefined) {
634
- const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
635
- this.orders = new ArrayCacheBySymbolById(limit);
636
- }
637
- const orders = this.orders;
638
- const order = this.parseWsOrder(rawOrder, market);
639
- const lastUpdateTimestamp = this.safeInteger(message, 'T');
640
- order['lastUpdateTimestamp'] = lastUpdateTimestamp;
641
- orders.append(order);
642
- client.resolve(orders, messageHash);
643
- client.resolve(orders, symbolMessageHash);
623
+ if (this.orders === undefined) {
624
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
625
+ this.orders = new ArrayCacheBySymbolById(limit);
644
626
  }
627
+ const orders = this.orders;
628
+ const order = this.parseWsOrder(rawOrder, market);
629
+ const lastUpdateTimestamp = this.safeInteger(message, 'T');
630
+ order['lastUpdateTimestamp'] = lastUpdateTimestamp;
631
+ orders.append(order);
632
+ client.resolve(orders, messageHash);
633
+ client.resolve(orders, symbolMessageHash);
645
634
  }
646
635
  parseWsOrder(order, market = undefined) {
647
636
  //
@@ -787,29 +776,17 @@ export default class bydfi extends bydfiRest {
787
776
  const symbol = market['symbol'];
788
777
  const messageHash = 'positions';
789
778
  const symbolMessageHash = messageHash + '::' + symbol;
790
- const messageHashes = this.findMessageHashes(client, messageHash);
791
- let match = false;
792
- for (let i = 0; i < messageHashes.length; i++) {
793
- const hash = messageHashes[i];
794
- if (hash === symbolMessageHash || hash === messageHash) {
795
- match = true;
796
- break;
797
- }
798
- }
799
- if (match) {
800
- if (this.positions === undefined) {
801
- this.positions = new ArrayCacheBySymbolBySide();
802
- }
803
- const cache = this.positions;
804
- const parsedPosition = this.parseWsPosition(rawPosition, market);
805
- const timestamp = this.safeInteger(message, 'T');
806
- parsedPosition['timestamp'] = timestamp;
807
- parsedPosition['datetime'] = this.iso8601(timestamp);
808
- cache.append(parsedPosition);
809
- const symbolSpecificMessageHash = messageHash + ':' + parsedPosition['symbol'];
810
- client.resolve([parsedPosition], messageHash);
811
- client.resolve([parsedPosition], symbolSpecificMessageHash);
779
+ if (this.positions === undefined) {
780
+ this.positions = new ArrayCacheBySymbolBySide();
812
781
  }
782
+ const cache = this.positions;
783
+ const parsedPosition = this.parseWsPosition(rawPosition, market);
784
+ const timestamp = this.safeInteger(message, 'T');
785
+ parsedPosition['timestamp'] = timestamp;
786
+ parsedPosition['datetime'] = this.iso8601(timestamp);
787
+ cache.append(parsedPosition);
788
+ client.resolve([parsedPosition], messageHash);
789
+ client.resolve([parsedPosition], symbolMessageHash);
813
790
  }
814
791
  parseWsPosition(position, market = undefined) {
815
792
  //
@@ -1524,18 +1524,17 @@ export default class gate extends gateRest {
1524
1524
  //
1525
1525
  const rawLiquidations = this.safeList(message, 'result', []);
1526
1526
  const newLiquidations = [];
1527
+ if (this.liquidations === undefined) {
1528
+ this.liquidations = new ArrayCacheBySymbolBySide();
1529
+ }
1530
+ const cache = this.liquidations;
1527
1531
  for (let i = 0; i < rawLiquidations.length; i++) {
1528
1532
  const rawLiquidation = rawLiquidations[i];
1529
1533
  const liquidation = this.parseWsLiquidation(rawLiquidation);
1534
+ cache.append(liquidation);
1530
1535
  const symbol = this.safeString(liquidation, 'symbol');
1531
- let liquidations = this.safeValue(this.liquidations, symbol);
1532
- if (liquidations === undefined) {
1533
- const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
1534
- liquidations = new ArrayCache(limit);
1535
- }
1536
- liquidations.append(liquidation);
1537
- this.liquidations[symbol] = liquidations;
1538
- client.resolve(liquidations, 'myLiquidations::' + symbol);
1536
+ const symbolLiquidations = this.safeValue(cache, symbol, []);
1537
+ client.resolve(symbolLiquidations, 'myLiquidations::' + symbol);
1539
1538
  }
1540
1539
  client.resolve(newLiquidations, 'myLiquidations');
1541
1540
  }
package/js/src/pro/okx.js CHANGED
@@ -758,13 +758,11 @@ export default class okx extends okxRest {
758
758
  const rawLiquidation = rawLiquidations[i];
759
759
  const liquidation = this.parseWsLiquidation(rawLiquidation);
760
760
  const symbol = this.safeString(liquidation, 'symbol');
761
- let liquidations = this.safeValue(this.liquidations, symbol);
762
- if (liquidations === undefined) {
763
- const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
764
- liquidations = new ArrayCache(limit);
761
+ if (this.liquidations === undefined) {
762
+ this.liquidations = new ArrayCacheBySymbolBySide();
765
763
  }
766
- liquidations.append(liquidation);
767
- this.liquidations[symbol] = liquidations;
764
+ const cache = this.liquidations;
765
+ cache.append(liquidation);
768
766
  client.resolve([liquidation], 'liquidations');
769
767
  client.resolve([liquidation], 'liquidations::' + symbol);
770
768
  }
@@ -857,13 +855,11 @@ export default class okx extends okxRest {
857
855
  }
858
856
  const liquidation = this.parseWsMyLiquidation(rawLiquidation);
859
857
  const symbol = this.safeString(liquidation, 'symbol');
860
- let liquidations = this.safeValue(this.liquidations, symbol);
861
- if (liquidations === undefined) {
862
- const limit = this.safeInteger(this.options, 'myLiquidationsLimit', 1000);
863
- liquidations = new ArrayCache(limit);
858
+ if (this.liquidations === undefined) {
859
+ this.liquidations = new ArrayCacheBySymbolBySide();
864
860
  }
865
- liquidations.append(liquidation);
866
- this.liquidations[symbol] = liquidations;
861
+ const cache = this.liquidations;
862
+ cache.append(liquidation);
867
863
  client.resolve([liquidation], 'myLiquidations');
868
864
  client.resolve([liquidation], 'myLiquidations::' + symbol);
869
865
  }
package/js/src/woo.js CHANGED
@@ -2151,7 +2151,7 @@ export default class woo extends Exchange {
2151
2151
  request['limit'] = Math.min(limit, 1000);
2152
2152
  }
2153
2153
  if (since !== undefined) {
2154
- request['after'] = since;
2154
+ request['after'] = since - 1; // #27793
2155
2155
  }
2156
2156
  const until = this.safeInteger(params, 'until');
2157
2157
  params = this.omit(params, 'until');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.5.35",
3
+ "version": "4.5.36",
4
4
  "description": "A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go",
5
5
  "unpkg": "dist/ccxt.browser.min.js",
6
6
  "type": "module",