ccxt 4.2.6 → 4.2.8

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.
@@ -8,6 +8,7 @@ interface Exchange {
8
8
  publicGetChatConnected(params?: {}): Promise<implicitReturnType>;
9
9
  publicGetChatPinned(params?: {}): Promise<implicitReturnType>;
10
10
  publicGetFunding(params?: {}): Promise<implicitReturnType>;
11
+ publicGetGuild(params?: {}): Promise<implicitReturnType>;
11
12
  publicGetInstrument(params?: {}): Promise<implicitReturnType>;
12
13
  publicGetInstrumentActive(params?: {}): Promise<implicitReturnType>;
13
14
  publicGetInstrumentActiveAndIndices(params?: {}): Promise<implicitReturnType>;
@@ -32,6 +33,7 @@ interface Exchange {
32
33
  publicGetTradeBucketed(params?: {}): Promise<implicitReturnType>;
33
34
  publicGetWalletAssets(params?: {}): Promise<implicitReturnType>;
34
35
  publicGetWalletNetworks(params?: {}): Promise<implicitReturnType>;
36
+ privateGetAddress(params?: {}): Promise<implicitReturnType>;
35
37
  privateGetApiKey(params?: {}): Promise<implicitReturnType>;
36
38
  privateGetExecution(params?: {}): Promise<implicitReturnType>;
37
39
  privateGetExecutionTradeHistory(params?: {}): Promise<implicitReturnType>;
@@ -44,19 +46,31 @@ interface Exchange {
44
46
  privateGetUserAffiliateStatus(params?: {}): Promise<implicitReturnType>;
45
47
  privateGetUserCheckReferralCode(params?: {}): Promise<implicitReturnType>;
46
48
  privateGetUserCommission(params?: {}): Promise<implicitReturnType>;
49
+ privateGetUserCsa(params?: {}): Promise<implicitReturnType>;
47
50
  privateGetUserDepositAddress(params?: {}): Promise<implicitReturnType>;
48
51
  privateGetUserExecutionHistory(params?: {}): Promise<implicitReturnType>;
52
+ privateGetUserGetWalletTransferAccounts(params?: {}): Promise<implicitReturnType>;
49
53
  privateGetUserMargin(params?: {}): Promise<implicitReturnType>;
50
54
  privateGetUserQuoteFillRatio(params?: {}): Promise<implicitReturnType>;
51
55
  privateGetUserQuoteValueRatio(params?: {}): Promise<implicitReturnType>;
56
+ privateGetUserStaking(params?: {}): Promise<implicitReturnType>;
57
+ privateGetUserStakingInstruments(params?: {}): Promise<implicitReturnType>;
58
+ privateGetUserStakingTiers(params?: {}): Promise<implicitReturnType>;
52
59
  privateGetUserTradingVolume(params?: {}): Promise<implicitReturnType>;
60
+ privateGetUserUnstakingRequests(params?: {}): Promise<implicitReturnType>;
53
61
  privateGetUserWallet(params?: {}): Promise<implicitReturnType>;
54
62
  privateGetUserWalletHistory(params?: {}): Promise<implicitReturnType>;
55
63
  privateGetUserWalletSummary(params?: {}): Promise<implicitReturnType>;
64
+ privateGetUserAffiliates(params?: {}): Promise<implicitReturnType>;
56
65
  privateGetUserEvent(params?: {}): Promise<implicitReturnType>;
66
+ privatePostAddress(params?: {}): Promise<implicitReturnType>;
57
67
  privatePostChat(params?: {}): Promise<implicitReturnType>;
68
+ privatePostGuild(params?: {}): Promise<implicitReturnType>;
69
+ privatePostGuildArchive(params?: {}): Promise<implicitReturnType>;
58
70
  privatePostGuildJoin(params?: {}): Promise<implicitReturnType>;
71
+ privatePostGuildKick(params?: {}): Promise<implicitReturnType>;
59
72
  privatePostGuildLeave(params?: {}): Promise<implicitReturnType>;
73
+ privatePostGuildSharesTrades(params?: {}): Promise<implicitReturnType>;
60
74
  privatePostOrder(params?: {}): Promise<implicitReturnType>;
61
75
  privatePostOrderCancelAllAfter(params?: {}): Promise<implicitReturnType>;
62
76
  privatePostOrderClosePosition(params?: {}): Promise<implicitReturnType>;
@@ -64,6 +78,7 @@ interface Exchange {
64
78
  privatePostPositionLeverage(params?: {}): Promise<implicitReturnType>;
65
79
  privatePostPositionRiskLimit(params?: {}): Promise<implicitReturnType>;
66
80
  privatePostPositionTransferMargin(params?: {}): Promise<implicitReturnType>;
81
+ privatePostUserAddSubaccount(params?: {}): Promise<implicitReturnType>;
67
82
  privatePostUserCancelWithdrawal(params?: {}): Promise<implicitReturnType>;
68
83
  privatePostUserCommunicationToken(params?: {}): Promise<implicitReturnType>;
69
84
  privatePostUserConfirmEmail(params?: {}): Promise<implicitReturnType>;
@@ -71,9 +86,14 @@ interface Exchange {
71
86
  privatePostUserLogout(params?: {}): Promise<implicitReturnType>;
72
87
  privatePostUserPreferences(params?: {}): Promise<implicitReturnType>;
73
88
  privatePostUserRequestWithdrawal(params?: {}): Promise<implicitReturnType>;
89
+ privatePostUserUnstakingRequests(params?: {}): Promise<implicitReturnType>;
90
+ privatePostUserUpdateSubaccount(params?: {}): Promise<implicitReturnType>;
91
+ privatePostUserWalletTransfer(params?: {}): Promise<implicitReturnType>;
92
+ privatePutGuild(params?: {}): Promise<implicitReturnType>;
74
93
  privatePutOrder(params?: {}): Promise<implicitReturnType>;
75
94
  privateDeleteOrder(params?: {}): Promise<implicitReturnType>;
76
95
  privateDeleteOrderAll(params?: {}): Promise<implicitReturnType>;
96
+ privateDeleteUserUnstakingRequests(params?: {}): Promise<implicitReturnType>;
77
97
  }
78
98
  declare abstract class Exchange extends _Exchange {
79
99
  }
package/js/src/binance.js CHANGED
@@ -4417,6 +4417,8 @@ export default class binance extends Exchange {
4417
4417
  * @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
4418
4418
  * @param {boolean} [params.sor] *spot only* whether to use SOR (Smart Order Routing) or not, default is false
4419
4419
  * @param {boolean} [params.test] *spot only* whether to use the test endpoint or not, default is false
4420
+ * @param {float} [params.trailingPercent] the percent to trail away from the current market price
4421
+ * @param {float} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
4420
4422
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
4421
4423
  */
4422
4424
  await this.loadMarkets();
@@ -4465,6 +4467,8 @@ export default class binance extends Exchange {
4465
4467
  * @param {float|undefined} price the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4466
4468
  * @param {object} params extra parameters specific to the exchange API endpoint
4467
4469
  * @param {string|undefined} params.marginMode 'cross' or 'isolated', for spot margin trading
4470
+ * @param {float} [params.trailingPercent] the percent to trail away from the current market price
4471
+ * @param {float} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
4468
4472
  * @returns {object} request to be sent to the exchange
4469
4473
  */
4470
4474
  const market = this.market(symbol);
@@ -4478,9 +4482,12 @@ export default class binance extends Exchange {
4478
4482
  const stopLossPrice = this.safeValue(params, 'stopLossPrice', triggerPrice); // fallback to stopLoss
4479
4483
  const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
4480
4484
  const trailingDelta = this.safeValue(params, 'trailingDelta');
4485
+ const trailingTriggerPrice = this.safeString2(params, 'trailingTriggerPrice', 'activationPrice', price);
4486
+ const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRate');
4487
+ const isTrailingPercentOrder = trailingPercent !== undefined;
4481
4488
  const isStopLoss = stopLossPrice !== undefined || trailingDelta !== undefined;
4482
4489
  const isTakeProfit = takeProfitPrice !== undefined;
4483
- params = this.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice']);
4490
+ params = this.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent']);
4484
4491
  const [marginMode, query] = this.handleMarginModeAndParams('createOrder', params);
4485
4492
  const request = {
4486
4493
  'symbol': market['id'],
@@ -4501,7 +4508,14 @@ export default class binance extends Exchange {
4501
4508
  }
4502
4509
  let uppercaseType = type.toUpperCase();
4503
4510
  let stopPrice = undefined;
4504
- if (isStopLoss) {
4511
+ if (isTrailingPercentOrder) {
4512
+ uppercaseType = 'TRAILING_STOP_MARKET';
4513
+ request['callbackRate'] = trailingPercent;
4514
+ if (trailingTriggerPrice !== undefined) {
4515
+ request['activationPrice'] = this.priceToPrecision(symbol, trailingTriggerPrice);
4516
+ }
4517
+ }
4518
+ else if (isStopLoss) {
4505
4519
  stopPrice = stopLossPrice;
4506
4520
  if (isMarketOrder) {
4507
4521
  // spot STOP_LOSS market orders are not a valid order type
@@ -4645,9 +4659,8 @@ export default class binance extends Exchange {
4645
4659
  }
4646
4660
  else if (uppercaseType === 'TRAILING_STOP_MARKET') {
4647
4661
  quantityIsRequired = true;
4648
- const callbackRate = this.safeNumber(query, 'callbackRate');
4649
- if (callbackRate === undefined) {
4650
- throw new InvalidOrder(this.id + ' createOrder() requires a callbackRate extra param for a ' + type + ' order');
4662
+ if (trailingPercent === undefined) {
4663
+ throw new InvalidOrder(this.id + ' createOrder() requires a trailingPercent param for a ' + type + ' order');
4651
4664
  }
4652
4665
  }
4653
4666
  if (quantityIsRequired) {
package/js/src/bingx.d.ts CHANGED
@@ -66,6 +66,7 @@ export default class bingx extends Exchange {
66
66
  createMarketSellOrderWithCost(symbol: string, cost: any, params?: {}): Promise<Order>;
67
67
  createOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): any;
68
68
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<Order>;
69
+ fixStringifiedJsonMembers(content: any): any;
69
70
  createOrders(orders: OrderRequest[], params?: {}): Promise<Order[]>;
70
71
  parseOrderSide(side: any): string;
71
72
  parseOrder(order: any, market?: Market): Order;
package/js/src/bingx.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/bingx.js';
9
- import { AuthenticationError, ExchangeNotAvailable, PermissionDenied, ExchangeError, InsufficientFunds, BadRequest, OrderNotFound, DDoSProtection, BadSymbol, ArgumentsRequired } from './base/errors.js';
9
+ import { AuthenticationError, ExchangeNotAvailable, PermissionDenied, AccountSuspended, ExchangeError, InsufficientFunds, BadRequest, OrderNotFound, DDoSProtection, BadSymbol, ArgumentsRequired } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
12
12
  import { DECIMAL_PLACES } from './base/functions/number.js';
@@ -355,6 +355,7 @@ export default class bingx extends Exchange {
355
355
  '80014': BadRequest,
356
356
  '80016': OrderNotFound,
357
357
  '80017': OrderNotFound,
358
+ '100414': AccountSuspended,
358
359
  '100437': BadRequest, // {"code":100437,"msg":"The withdrawal amount is lower than the minimum limit, please re-enter.","timestamp":1689258588845}
359
360
  },
360
361
  'broad': {},
@@ -1898,12 +1899,26 @@ export default class bingx extends Exchange {
1898
1899
  // }
1899
1900
  //
1900
1901
  if (typeof response === 'string') {
1902
+ // broken api engine : order-ids are too long numbers (i.e. 1742930526912864656)
1903
+ // and JSON.parse can not handle them in JS, so we have to use .parseJson
1904
+ // however, when order has an attached SL/TP, their value types need extra parsing
1905
+ response = this.fixStringifiedJsonMembers(response);
1901
1906
  response = this.parseJson(response);
1902
1907
  }
1903
1908
  const data = this.safeValue(response, 'data', {});
1904
1909
  const order = this.safeValue(data, 'order', data);
1905
1910
  return this.parseOrder(order, market);
1906
1911
  }
1912
+ fixStringifiedJsonMembers(content) {
1913
+ // when stringified json has members with their values also stringified, like:
1914
+ // '{"code":0, "data":{"order":{"orderId":1742968678528512345,"symbol":"BTC-USDT", "takeProfit":"{\"type\":\"TAKE_PROFIT\",\"stopPrice\":43320.1}","reduceOnly":false}}}'
1915
+ // we can fix with below manipulations
1916
+ // @ts-ignore
1917
+ let modifiedContent = content.replaceAll('\\', '');
1918
+ modifiedContent = modifiedContent.replaceAll('"{', '{');
1919
+ modifiedContent = modifiedContent.replaceAll('}"', '}');
1920
+ return modifiedContent;
1921
+ }
1907
1922
  async createOrders(orders, params = {}) {
1908
1923
  /**
1909
1924
  * @method
package/js/src/bitmex.js CHANGED
@@ -126,6 +126,7 @@ export default class bitmex extends Exchange {
126
126
  'chat/connected': 5,
127
127
  'chat/pinned': 5,
128
128
  'funding': 5,
129
+ 'guild': 5,
129
130
  'instrument': 5,
130
131
  'instrument/active': 5,
131
132
  'instrument/activeAndIndices': 5,
@@ -154,6 +155,7 @@ export default class bitmex extends Exchange {
154
155
  },
155
156
  'private': {
156
157
  'get': {
158
+ 'address': 5,
157
159
  'apiKey': 5,
158
160
  'execution': 5,
159
161
  'execution/tradeHistory': 5,
@@ -166,21 +168,33 @@ export default class bitmex extends Exchange {
166
168
  'user/affiliateStatus': 5,
167
169
  'user/checkReferralCode': 5,
168
170
  'user/commission': 5,
171
+ 'user/csa': 5,
169
172
  'user/depositAddress': 5,
170
173
  'user/executionHistory': 5,
174
+ 'user/getWalletTransferAccounts': 5,
171
175
  'user/margin': 5,
172
176
  'user/quoteFillRatio': 5,
173
177
  'user/quoteValueRatio': 5,
178
+ 'user/staking': 5,
179
+ 'user/staking/instruments': 5,
180
+ 'user/staking/tiers': 5,
174
181
  'user/tradingVolume': 5,
182
+ 'user/unstakingRequests': 5,
175
183
  'user/wallet': 5,
176
184
  'user/walletHistory': 5,
177
185
  'user/walletSummary': 5,
186
+ 'userAffiliates': 5,
178
187
  'userEvent': 5,
179
188
  },
180
189
  'post': {
190
+ 'address': 5,
181
191
  'chat': 5,
192
+ 'guild': 5,
193
+ 'guild/archive': 5,
182
194
  'guild/join': 5,
195
+ 'guild/kick': 5,
183
196
  'guild/leave': 5,
197
+ 'guild/sharesTrades': 5,
184
198
  'order': 1,
185
199
  'order/cancelAllAfter': 5,
186
200
  'order/closePosition': 5,
@@ -188,6 +202,7 @@ export default class bitmex extends Exchange {
188
202
  'position/leverage': 1,
189
203
  'position/riskLimit': 5,
190
204
  'position/transferMargin': 1,
205
+ 'user/addSubaccount': 5,
191
206
  'user/cancelWithdrawal': 5,
192
207
  'user/communicationToken': 5,
193
208
  'user/confirmEmail': 5,
@@ -195,13 +210,18 @@ export default class bitmex extends Exchange {
195
210
  'user/logout': 5,
196
211
  'user/preferences': 5,
197
212
  'user/requestWithdrawal': 5,
213
+ 'user/unstakingRequests': 5,
214
+ 'user/updateSubaccount': 5,
215
+ 'user/walletTransfer': 5,
198
216
  },
199
217
  'put': {
218
+ 'guild': 5,
200
219
  'order': 1,
201
220
  },
202
221
  'delete': {
203
222
  'order': 1,
204
223
  'order/all': 1,
224
+ 'user/unstakingRequests': 5,
205
225
  },
206
226
  },
207
227
  },
@@ -1589,13 +1609,11 @@ export default class bitmex extends Exchange {
1589
1609
  let fee = undefined;
1590
1610
  const feeCostString = this.numberToString(this.convertFromRawCost(symbol, this.safeString(trade, 'execComm')));
1591
1611
  if (feeCostString !== undefined) {
1592
- const currencyId = this.safeString(trade, 'settlCurrency');
1593
- const feeCurrencyCode = this.safeCurrencyCode(currencyId);
1594
- const feeRateString = this.safeString(trade, 'commission');
1612
+ const currencyId = this.safeString2(trade, 'settlCurrency', 'currency');
1595
1613
  fee = {
1596
- 'cost': Precise.stringAbs(feeCostString),
1597
- 'currency': feeCurrencyCode,
1598
- 'rate': Precise.stringAbs(feeRateString),
1614
+ 'cost': feeCostString,
1615
+ 'currency': this.safeCurrencyCode(currencyId),
1616
+ 'rate': this.safeString(trade, 'commission'),
1599
1617
  };
1600
1618
  }
1601
1619
  // Trade or Funding
package/js/src/bybit.js CHANGED
@@ -3502,6 +3502,7 @@ export default class bybit extends Exchange {
3502
3502
  * @name bybit#createOrder
3503
3503
  * @description create a trade order
3504
3504
  * @see https://bybit-exchange.github.io/docs/v5/order/create-order
3505
+ * @see https://bybit-exchange.github.io/docs/v5/position/trading-stop
3505
3506
  * @param {string} symbol unified symbol of the market to create an order in
3506
3507
  * @param {string} type 'market' or 'limit'
3507
3508
  * @param {string} side 'buy' or 'sell'
@@ -3523,6 +3524,8 @@ export default class bybit extends Exchange {
3523
3524
  * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
3524
3525
  * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
3525
3526
  * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
3527
+ * @param {string} [params.trailingAmount] the quote amount to trail away from the current market price
3528
+ * @param {string} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
3526
3529
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3527
3530
  */
3528
3531
  await this.loadMarkets();
@@ -3533,8 +3536,16 @@ export default class bybit extends Exchange {
3533
3536
  if (isUsdcSettled && !isUnifiedAccount) {
3534
3537
  return await this.createUsdcOrder(symbol, type, side, amount, price, params);
3535
3538
  }
3539
+ const trailingAmount = this.safeString2(params, 'trailingAmount', 'trailingStop');
3540
+ const isTrailingAmountOrder = trailingAmount !== undefined;
3536
3541
  const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
3537
- const response = await this.privatePostV5OrderCreate(orderRequest); // already extended inside createOrderRequest
3542
+ let response = undefined;
3543
+ if (isTrailingAmountOrder) {
3544
+ response = await this.privatePostV5PositionTradingStop(orderRequest);
3545
+ }
3546
+ else {
3547
+ response = await this.privatePostV5OrderCreate(orderRequest); // already extended inside createOrderRequest
3548
+ }
3538
3549
  //
3539
3550
  // {
3540
3551
  // "retCode": 0,
@@ -3644,12 +3655,21 @@ export default class bybit extends Exchange {
3644
3655
  const takeProfitTriggerPrice = this.safeValue(params, 'takeProfitPrice');
3645
3656
  const stopLoss = this.safeValue(params, 'stopLoss');
3646
3657
  const takeProfit = this.safeValue(params, 'takeProfit');
3658
+ const trailingTriggerPrice = this.safeString2(params, 'trailingTriggerPrice', 'activePrice', price);
3659
+ const trailingAmount = this.safeString2(params, 'trailingAmount', 'trailingStop');
3660
+ const isTrailingAmountOrder = trailingAmount !== undefined;
3647
3661
  const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
3648
3662
  const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
3649
3663
  const isStopLoss = stopLoss !== undefined;
3650
3664
  const isTakeProfit = takeProfit !== undefined;
3651
3665
  const isBuy = side === 'buy';
3652
- if (triggerPrice !== undefined) {
3666
+ if (isTrailingAmountOrder) {
3667
+ if (trailingTriggerPrice !== undefined) {
3668
+ request['activePrice'] = this.priceToPrecision(symbol, trailingTriggerPrice);
3669
+ }
3670
+ request['trailingStop'] = trailingAmount;
3671
+ }
3672
+ else if (triggerPrice !== undefined) {
3653
3673
  const triggerDirection = this.safeString(params, 'triggerDirection');
3654
3674
  params = this.omit(params, ['triggerPrice', 'stopPrice', 'triggerDirection']);
3655
3675
  if (market['spot']) {
@@ -3704,7 +3724,7 @@ export default class bybit extends Exchange {
3704
3724
  // mandatory field for options
3705
3725
  request['orderLinkId'] = this.uuid16();
3706
3726
  }
3707
- params = this.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId', 'triggerPrice', 'stopLoss', 'takeProfit']);
3727
+ params = this.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingAmount', 'trailingTriggerPrice']);
3708
3728
  return this.extend(request, params);
3709
3729
  }
3710
3730
  async createOrders(orders, params = {}) {
package/js/src/okx.js CHANGED
@@ -2590,6 +2590,8 @@ export default class okx extends Exchange {
2590
2590
  const stopLossDefined = (stopLoss !== undefined);
2591
2591
  const takeProfit = this.safeValue(params, 'takeProfit');
2592
2592
  const takeProfitDefined = (takeProfit !== undefined);
2593
+ const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRatio');
2594
+ const isTrailingPercentOrder = trailingPercent !== undefined;
2593
2595
  const defaultMarginMode = this.safeString2(this.options, 'defaultMarginMode', 'marginMode', 'cross');
2594
2596
  let marginMode = this.safeString2(params, 'marginMode', 'tdMode'); // cross or isolated, tdMode not ommited so as to be extended into the request
2595
2597
  let margin = false;
@@ -2622,7 +2624,7 @@ export default class okx extends Exchange {
2622
2624
  const isMarketOrder = type === 'market';
2623
2625
  let postOnly = false;
2624
2626
  [postOnly, params] = this.handlePostOnly(isMarketOrder, type === 'post_only', params);
2625
- params = this.omit(params, ['currency', 'ccy', 'marginMode', 'timeInForce', 'stopPrice', 'triggerPrice', 'clientOrderId', 'stopLossPrice', 'takeProfitPrice', 'slOrdPx', 'tpOrdPx', 'margin', 'stopLoss', 'takeProfit']);
2627
+ params = this.omit(params, ['currency', 'ccy', 'marginMode', 'timeInForce', 'stopPrice', 'triggerPrice', 'clientOrderId', 'stopLossPrice', 'takeProfitPrice', 'slOrdPx', 'tpOrdPx', 'margin', 'stopLoss', 'takeProfit', 'trailingPercent']);
2626
2628
  const ioc = (timeInForce === 'IOC') || (type === 'ioc');
2627
2629
  const fok = (timeInForce === 'FOK') || (type === 'fok');
2628
2630
  const trigger = (triggerPrice !== undefined) || (type === 'trigger');
@@ -2681,7 +2683,12 @@ export default class okx extends Exchange {
2681
2683
  else if (fok) {
2682
2684
  request['ordType'] = 'fok';
2683
2685
  }
2684
- if (stopLossDefined || takeProfitDefined) {
2686
+ if (isTrailingPercentOrder) {
2687
+ const convertedTrailingPercent = Precise.stringDiv(trailingPercent, '100');
2688
+ request['callbackRatio'] = convertedTrailingPercent;
2689
+ request['ordType'] = 'move_order_stop';
2690
+ }
2691
+ else if (stopLossDefined || takeProfitDefined) {
2685
2692
  if (stopLossDefined) {
2686
2693
  const stopLossTriggerPrice = this.safeValueN(stopLoss, ['triggerPrice', 'stopPrice', 'slTriggerPx']);
2687
2694
  if (stopLossTriggerPrice === undefined) {
@@ -2825,6 +2832,7 @@ export default class okx extends Exchange {
2825
2832
  * @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders
2826
2833
  * @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type
2827
2834
  * @param {string} [params.positionSide] if position mode is one-way: set to 'net', if position mode is hedge-mode: set to 'long' or 'short'
2835
+ * @param {string} [params.trailingPercent] the percent to trail away from the current market price
2828
2836
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2829
2837
  */
2830
2838
  await this.loadMarkets();
@@ -2832,7 +2840,7 @@ export default class okx extends Exchange {
2832
2840
  let request = this.createOrderRequest(symbol, type, side, amount, price, params);
2833
2841
  let method = this.safeString(this.options, 'createOrder', 'privatePostTradeBatchOrders');
2834
2842
  const requestOrdType = this.safeString(request, 'ordType');
2835
- if ((requestOrdType === 'trigger') || (requestOrdType === 'conditional') || (type === 'oco') || (type === 'move_order_stop') || (type === 'iceberg') || (type === 'twap')) {
2843
+ if ((requestOrdType === 'trigger') || (requestOrdType === 'conditional') || (requestOrdType === 'move_order_stop') || (type === 'move_order_stop') || (type === 'oco') || (type === 'iceberg') || (type === 'twap')) {
2836
2844
  method = 'privatePostTradeOrderAlgo';
2837
2845
  }
2838
2846
  if ((method !== 'privatePostTradeOrder') && (method !== 'privatePostTradeOrderAlgo') && (method !== 'privatePostTradeBatchOrders')) {
@@ -3029,17 +3037,20 @@ export default class okx extends Exchange {
3029
3037
  * @name okx#cancelOrder
3030
3038
  * @description cancels an open order
3031
3039
  * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-order
3040
+ * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3032
3041
  * @param {string} id order id
3033
3042
  * @param {string} symbol unified symbol of the market the order was made in
3034
3043
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3035
3044
  * @param {boolean} [params.trigger] true if trigger orders
3045
+ * @param {boolean} [params.trailing] set to true if you want to cancel a trailing order
3036
3046
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3037
3047
  */
3038
3048
  if (symbol === undefined) {
3039
3049
  throw new ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
3040
3050
  }
3041
3051
  const stop = this.safeValue2(params, 'stop', 'trigger');
3042
- if (stop) {
3052
+ const trailing = this.safeValue(params, 'trailing', false);
3053
+ if (stop || trailing) {
3043
3054
  const orderInner = await this.cancelOrders([id], symbol, params);
3044
3055
  return this.safeValue(orderInner, 0);
3045
3056
  }
@@ -3090,6 +3101,7 @@ export default class okx extends Exchange {
3090
3101
  * @param {string} symbol unified market symbol
3091
3102
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3092
3103
  * @param {boolean} [params.trigger] whether the order is a stop/trigger order
3104
+ * @param {boolean} [params.trailing] set to true if you want to cancel trailing orders
3093
3105
  * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3094
3106
  */
3095
3107
  // TODO : the original endpoint signature differs, according to that you can skip individual symbol and assign ids in batch. At this moment, `params` is not being used too.
@@ -3105,7 +3117,8 @@ export default class okx extends Exchange {
3105
3117
  const clientOrderIds = this.parseIds(this.safeValue2(params, 'clOrdId', 'clientOrderId'));
3106
3118
  const algoIds = this.parseIds(this.safeValue(params, 'algoId'));
3107
3119
  const stop = this.safeValue2(params, 'stop', 'trigger');
3108
- if (stop) {
3120
+ const trailing = this.safeValue(params, 'trailing', false);
3121
+ if (stop || trailing) {
3109
3122
  method = 'privatePostTradeCancelAlgos';
3110
3123
  }
3111
3124
  if (clientOrderIds === undefined) {
@@ -3119,7 +3132,7 @@ export default class okx extends Exchange {
3119
3132
  }
3120
3133
  }
3121
3134
  for (let i = 0; i < ids.length; i++) {
3122
- if (stop) {
3135
+ if (trailing || stop) {
3123
3136
  request.push({
3124
3137
  'algoId': ids[i],
3125
3138
  'instId': market['id'],
@@ -3558,7 +3571,6 @@ export default class okx extends Exchange {
3558
3571
  /**
3559
3572
  * @method
3560
3573
  * @name okx#fetchOpenOrders
3561
- * @description Fetch orders that are still open
3562
3574
  * @description fetch all unfilled currently open orders
3563
3575
  * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-list
3564
3576
  * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-list
@@ -3571,6 +3583,7 @@ export default class okx extends Exchange {
3571
3583
  * @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
3572
3584
  * @param {string} [params.algoId] Algo ID "'433845797218942976'"
3573
3585
  * @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)
3586
+ * @param {boolean} [params.trailing] set to true if you want to fetch trailing orders
3574
3587
  * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3575
3588
  */
3576
3589
  await this.loadMarkets();
@@ -3603,15 +3616,21 @@ export default class okx extends Exchange {
3603
3616
  let method = this.safeString(params, 'method', defaultMethod);
3604
3617
  const ordType = this.safeString(params, 'ordType');
3605
3618
  const stop = this.safeValue2(params, 'stop', 'trigger');
3606
- if (stop || (ordType in algoOrderTypes)) {
3619
+ const trailing = this.safeValue(params, 'trailing', false);
3620
+ if (trailing || stop || (ordType in algoOrderTypes)) {
3607
3621
  method = 'privateGetTradeOrdersAlgoPending';
3622
+ }
3623
+ if (trailing) {
3624
+ request['ordType'] = 'move_order_stop';
3625
+ }
3626
+ else if (stop || (ordType in algoOrderTypes)) {
3608
3627
  if (stop) {
3609
3628
  if (ordType === undefined) {
3610
3629
  throw new ArgumentsRequired(this.id + ' fetchOpenOrders() requires an "ordType" string parameter, "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"');
3611
3630
  }
3612
3631
  }
3613
3632
  }
3614
- const query = this.omit(params, ['method', 'stop', 'trigger']);
3633
+ const query = this.omit(params, ['method', 'stop', 'trigger', 'trailing']);
3615
3634
  let response = undefined;
3616
3635
  if (method === 'privateGetTradeOrdersAlgoPending') {
3617
3636
  response = await this.privateGetTradeOrdersAlgoPending(this.extend(request, query));
@@ -3732,6 +3751,7 @@ export default class okx extends Exchange {
3732
3751
  * @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
3733
3752
  * @param {string} [params.algoId] Algo ID "'433845797218942976'"
3734
3753
  * @param {int} [params.until] timestamp in ms to fetch orders for
3754
+ * @param {boolean} [params.trailing] set to true if you want to fetch trailing orders
3735
3755
  * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3736
3756
  */
3737
3757
  await this.loadMarkets();
@@ -3765,7 +3785,12 @@ export default class okx extends Exchange {
3765
3785
  let method = this.safeString(params, 'method', defaultMethod);
3766
3786
  const ordType = this.safeString(params, 'ordType');
3767
3787
  const stop = this.safeValue2(params, 'stop', 'trigger');
3768
- if (stop || (ordType in algoOrderTypes)) {
3788
+ const trailing = this.safeValue(params, 'trailing', false);
3789
+ if (trailing) {
3790
+ method = 'privateGetTradeOrdersAlgoHistory';
3791
+ request['ordType'] = 'move_order_stop';
3792
+ }
3793
+ else if (stop || (ordType in algoOrderTypes)) {
3769
3794
  method = 'privateGetTradeOrdersAlgoHistory';
3770
3795
  const algoId = this.safeString(params, 'algoId');
3771
3796
  if (algoId !== undefined) {
@@ -3776,7 +3801,6 @@ export default class okx extends Exchange {
3776
3801
  if (ordType === undefined) {
3777
3802
  throw new ArgumentsRequired(this.id + ' fetchCanceledOrders() requires an "ordType" string parameter, "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"');
3778
3803
  }
3779
- request['ordType'] = ordType;
3780
3804
  }
3781
3805
  }
3782
3806
  else {
@@ -3789,7 +3813,7 @@ export default class okx extends Exchange {
3789
3813
  query = this.omit(query, ['until', 'till']);
3790
3814
  }
3791
3815
  }
3792
- const send = this.omit(query, ['method', 'stop', 'ordType', 'trigger']);
3816
+ const send = this.omit(query, ['method', 'stop', 'trigger', 'trailing']);
3793
3817
  let response = undefined;
3794
3818
  if (method === 'privateGetTradeOrdersAlgoHistory') {
3795
3819
  response = await this.privateGetTradeOrdersAlgoHistory(this.extend(request, send));
@@ -3917,6 +3941,7 @@ export default class okx extends Exchange {
3917
3941
  * @param {int} [params.until] timestamp in ms to fetch orders for
3918
3942
  * @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)
3919
3943
  * @param {string} [params.method] method to be used, either 'privateGetTradeOrdersHistory', 'privateGetTradeOrdersHistoryArchive' or 'privateGetTradeOrdersAlgoHistory' default is 'privateGetTradeOrdersHistory'
3944
+ * @param {boolean} [params.trailing] set to true if you want to fetch trailing orders
3920
3945
  * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3921
3946
  */
3922
3947
  await this.loadMarkets();
@@ -3954,14 +3979,20 @@ export default class okx extends Exchange {
3954
3979
  let method = this.safeString(params, 'method', defaultMethod);
3955
3980
  const ordType = this.safeString(params, 'ordType');
3956
3981
  const stop = this.safeValue2(params, 'stop', 'trigger');
3957
- if (stop || (ordType in algoOrderTypes)) {
3982
+ const trailing = this.safeValue(params, 'trailing', false);
3983
+ if (trailing || stop || (ordType in algoOrderTypes)) {
3958
3984
  method = 'privateGetTradeOrdersAlgoHistory';
3985
+ request['state'] = 'effective';
3986
+ }
3987
+ if (trailing) {
3988
+ request['ordType'] = 'move_order_stop';
3989
+ }
3990
+ else if (stop || (ordType in algoOrderTypes)) {
3959
3991
  if (stop) {
3960
3992
  if (ordType === undefined) {
3961
3993
  throw new ArgumentsRequired(this.id + ' fetchClosedOrders() requires an "ordType" string parameter, "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"');
3962
3994
  }
3963
3995
  }
3964
- request['state'] = 'effective';
3965
3996
  }
3966
3997
  else {
3967
3998
  if (since !== undefined) {
@@ -3974,7 +4005,7 @@ export default class okx extends Exchange {
3974
4005
  }
3975
4006
  request['state'] = 'filled';
3976
4007
  }
3977
- const send = this.omit(query, ['method', 'stop', 'trigger']);
4008
+ const send = this.omit(query, ['method', 'stop', 'trigger', 'trailing']);
3978
4009
  let response = undefined;
3979
4010
  if (method === 'privateGetTradeOrdersAlgoHistory') {
3980
4011
  response = await this.privateGetTradeOrdersAlgoHistory(this.extend(request, send));
package/js/src/phemex.js CHANGED
@@ -455,7 +455,7 @@ export default class phemex extends Exchange {
455
455
  },
456
456
  },
457
457
  'options': {
458
- 'brokerId': 'ccxt2022',
458
+ 'brokerId': 'CCXT',
459
459
  'x-phemex-request-expiry': 60,
460
460
  'createOrderByQuoteRequiresPrice': true,
461
461
  'networks': {
@@ -124,8 +124,7 @@ export default class coinbasepro extends coinbaseproRest {
124
124
  async watchTickers(symbols = undefined, params = {}) {
125
125
  /**
126
126
  * @method
127
- * @name okx#watchTickers
128
- * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
127
+ * @name coinbasepro#watchTickers
129
128
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
130
129
  * @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
131
130
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -92,13 +92,19 @@ export default class cryptocom extends cryptocomRest {
92
92
  await this.loadMarkets();
93
93
  symbols = this.marketSymbols(symbols);
94
94
  const topics = [];
95
+ const messageHashes = [];
96
+ if (!limit) {
97
+ limit = 150;
98
+ }
95
99
  for (let i = 0; i < symbols.length; i++) {
96
100
  const symbol = symbols[i];
97
101
  const market = this.market(symbol);
98
- const currentTopic = 'book' + '.' + market['id'];
102
+ const currentTopic = 'book' + '.' + market['id'] + '.' + limit;
103
+ const messageHash = 'orderbook:' + market['symbol'];
104
+ messageHashes.push(messageHash);
99
105
  topics.push(currentTopic);
100
106
  }
101
- const orderbook = await this.watchPublicMultiple(topics, topics, params);
107
+ const orderbook = await this.watchPublicMultiple(messageHashes, topics, params);
102
108
  return orderbook.limit();
103
109
  }
104
110
  handleOrderBookSnapshot(client, message) {
@@ -123,7 +129,6 @@ export default class cryptocom extends cryptocomRest {
123
129
  // ]
124
130
  // }
125
131
  //
126
- const messageHash = this.safeString(message, 'subscription');
127
132
  const marketId = this.safeString(message, 'instrument_name');
128
133
  const market = this.safeMarket(marketId);
129
134
  const symbol = market['symbol'];
@@ -139,6 +144,7 @@ export default class cryptocom extends cryptocomRest {
139
144
  }
140
145
  orderbook.reset(snapshot);
141
146
  this.orderbooks[symbol] = orderbook;
147
+ const messageHash = 'orderbook:' + symbol;
142
148
  client.resolve(orderbook, messageHash);
143
149
  }
144
150
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
@@ -542,7 +542,8 @@ export default class poloniex extends poloniexRest {
542
542
  const marketId = this.safeString(data, 'symbol');
543
543
  const symbol = this.safeSymbol(marketId);
544
544
  const market = this.safeMarket(symbol);
545
- const timeframe = this.findTimeframe(channel);
545
+ const timeframes = this.safeValue(this.options, 'timeframes', {});
546
+ const timeframe = this.findTimeframe(channel, timeframes);
546
547
  const messageHash = channel + '::' + symbol;
547
548
  const parsed = this.parseWsOHLCV(data, market);
548
549
  this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});