ccxt 4.2.4 → 4.2.6

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.
@@ -11,7 +11,7 @@ const { isNode, deepExtend, extend, clone, flatten, unique, indexBy, sortBy, sor
11
11
  import { keys as keysFunc, values as valuesFunc, vwap as vwapFunc } from './functions.js';
12
12
  // import exceptions from "./errors.js"
13
13
  import { // eslint-disable-line object-curly-newline
14
- ExchangeError, BadSymbol, NullResponse, InvalidAddress, InvalidOrder, NotSupported, BadResponse, AuthenticationError, DDoSProtection, RequestTimeout, NetworkError, ProxyError, ExchangeNotAvailable, ArgumentsRequired, RateLimitExceeded, BadRequest } from "./errors.js";
14
+ ExchangeError, BadSymbol, NullResponse, InvalidAddress, InvalidOrder, NotSupported, BadResponse, AuthenticationError, DDoSProtection, RequestTimeout, NetworkError, ProxyError, ExchangeNotAvailable, ArgumentsRequired, RateLimitExceeded, BadRequest, ExchangeClosedByUser } from "./errors.js";
15
15
  import { Precise } from './Precise.js';
16
16
  //-----------------------------------------------------------------------------
17
17
  import WsClient from './ws/WsClient.js';
@@ -1227,10 +1227,15 @@ export default class Exchange {
1227
1227
  const closedClients = [];
1228
1228
  for (let i = 0; i < clients.length; i++) {
1229
1229
  const client = clients[i];
1230
- delete this.clients[client.url];
1230
+ client.error = new ExchangeClosedByUser(this.id + ' closedByUser');
1231
1231
  closedClients.push(client.close());
1232
1232
  }
1233
- return Promise.all(closedClients);
1233
+ await Promise.all(closedClients);
1234
+ for (let i = 0; i < clients.length; i++) {
1235
+ const client = clients[i];
1236
+ delete this.clients[client.url];
1237
+ }
1238
+ return;
1234
1239
  }
1235
1240
  async loadOrderBook(client, messageHash, symbol, limit = undefined, params = {}) {
1236
1241
  if (!(symbol in this.orderbooks)) {
@@ -45,6 +45,7 @@ declare const errorHierarchy: {
45
45
  RequestTimeout: {};
46
46
  };
47
47
  };
48
+ ExchangeClosedByUser: {};
48
49
  };
49
50
  };
50
51
  export default errorHierarchy;
@@ -51,6 +51,7 @@ const errorHierarchy = {
51
51
  'RequestTimeout': {},
52
52
  },
53
53
  },
54
+ 'ExchangeClosedByUser': {},
54
55
  },
55
56
  };
56
57
  export default errorHierarchy;
@@ -4,6 +4,9 @@ declare class BaseError extends Error {
4
4
  declare class ExchangeError extends Error {
5
5
  constructor(message: any);
6
6
  }
7
+ declare class ExchangeClosedByUser extends Error {
8
+ constructor(message: any);
9
+ }
7
10
  declare class AuthenticationError extends ExchangeError {
8
11
  constructor(message: any);
9
12
  }
@@ -105,6 +108,7 @@ declare class RequestTimeout extends NetworkError {
105
108
  }
106
109
  declare const errors: {
107
110
  BaseError: typeof BaseError;
111
+ ExchangeClosedByUser: typeof ExchangeClosedByUser;
108
112
  ExchangeError: typeof ExchangeError;
109
113
  PermissionDenied: typeof PermissionDenied;
110
114
  AccountNotEnabled: typeof AccountNotEnabled;
@@ -140,5 +144,5 @@ declare const errors: {
140
144
  OperationFailed: typeof OperationFailed;
141
145
  ProxyError: typeof ProxyError;
142
146
  };
143
- export { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
147
+ export { BaseError, ExchangeClosedByUser, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
144
148
  export default errors;
@@ -48,6 +48,12 @@ class ExchangeError extends Error {
48
48
  this.name = 'ExchangeError';
49
49
  }
50
50
  }
51
+ class ExchangeClosedByUser extends Error {
52
+ constructor(message) {
53
+ super(message);
54
+ this.name = 'ExchangeClosedByUser';
55
+ }
56
+ }
51
57
  class AuthenticationError extends ExchangeError {
52
58
  constructor(message) {
53
59
  super(message);
@@ -254,6 +260,6 @@ class RequestTimeout extends NetworkError {
254
260
  // // Derived class hierarchy
255
261
  // errorHierarchy
256
262
  // )
257
- const errors = { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
258
- export { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
263
+ const errors = { BaseError, ExchangeClosedByUser, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
264
+ export { BaseError, ExchangeClosedByUser, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
259
265
  export default errors;
@@ -4,7 +4,7 @@
4
4
  // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
5
  // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
6
 
7
- import { RequestTimeout, NetworkError, NotSupported, BaseError } from '../../base/errors.js';
7
+ import { RequestTimeout, NetworkError, NotSupported, BaseError, ExchangeClosedByUser } from '../../base/errors.js';
8
8
  import { inflateSync, gunzipSync } from '../../static_dependencies/fflake/browser.js';
9
9
  import { Future } from './Future.js';
10
10
  import { isNode, isJsonEncodedObject, deepExtend, milliseconds, } from '../../base/functions.js';
@@ -208,6 +208,9 @@ export default class Client {
208
208
  // todo: exception types for server-side disconnects
209
209
  this.reset(new NetworkError('connection closed by remote server, closing code ' + String(event.code)));
210
210
  }
211
+ if (this.error instanceof ExchangeClosedByUser) {
212
+ this.reset(this.error);
213
+ }
211
214
  if (this.disconnected !== undefined) {
212
215
  this.disconnected.resolve(true);
213
216
  }
@@ -228,6 +231,7 @@ export default class Client {
228
231
  const future = Future();
229
232
  if (isNode) {
230
233
  /* eslint-disable no-inner-declarations */
234
+ /* eslint-disable jsdoc/require-jsdoc */
231
235
  function onSendComplete(error) {
232
236
  if (error) {
233
237
  future.reject(error);
@@ -58,7 +58,7 @@ export default class binance extends Exchange {
58
58
  fetchCanceledOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<any>;
59
59
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
60
60
  cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
61
- cancelOrders(ids: Int[], symbol?: Str, params?: {}): Promise<Order[]>;
61
+ cancelOrders(ids: string[], symbol?: Str, params?: {}): Promise<Order[]>;
62
62
  fetchOrderTrades(id: string, symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
63
63
  fetchMyTrades(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
64
64
  fetchMyDustTrades(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<any>;
package/js/src/bingx.d.ts CHANGED
@@ -72,7 +72,7 @@ export default class bingx extends Exchange {
72
72
  parseOrderStatus(status: any): string;
73
73
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
74
74
  cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
75
- cancelOrders(ids: Int[], symbol?: Str, params?: {}): Promise<any>;
75
+ cancelOrders(ids: string[], symbol?: Str, params?: {}): Promise<any>;
76
76
  fetchOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
77
77
  fetchOpenOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
78
78
  fetchClosedOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
package/js/src/bingx.js CHANGED
@@ -1334,18 +1334,11 @@ export default class bingx extends Exchange {
1334
1334
  const close = this.safeString(ticker, 'lastPrice');
1335
1335
  const quoteVolume = this.safeString(ticker, 'quoteVolume');
1336
1336
  const baseVolume = this.safeString(ticker, 'volume');
1337
- let percentage = undefined;
1338
- let change = undefined;
1339
- if (market['swap']) {
1340
- // right now only swap uses the 24h change, spot will be added soon
1341
- percentage = this.safeString(ticker, 'priceChangePercent');
1342
- change = this.safeString(ticker, 'priceChange');
1343
- }
1344
- // let percentage = this.safeString (ticker, 'priceChangePercent');
1345
- // if (percentage !== undefined) {
1346
- // percentage = percentage.replace ('%', '');
1347
- // } similarly to change, it's not ccxt's percentage because it does priceChange/open, and priceChange is high-low
1348
- // const change = this.safeString (ticker, 'priceChange'); // this is not ccxt's change because it does high-low instead of last-open
1337
+ let percentage = this.safeString(ticker, 'priceChangePercent');
1338
+ if (percentage !== undefined) {
1339
+ percentage = percentage.replace('%', '');
1340
+ }
1341
+ const change = this.safeString(ticker, 'priceChange');
1349
1342
  const ts = this.safeInteger(ticker, 'closeTime');
1350
1343
  const datetime = this.iso8601(ts);
1351
1344
  const bid = this.safeString(ticker, 'bidPrice');
@@ -1674,6 +1667,11 @@ export default class bingx extends Exchange {
1674
1667
  };
1675
1668
  const isMarketOrder = type === 'MARKET';
1676
1669
  const isSpot = marketType === 'spot';
1670
+ const exchangeClientOrderId = isSpot ? 'newClientOrderId' : 'clientOrderID';
1671
+ const clientOrderId = this.safeString2(params, exchangeClientOrderId, 'clientOrderId');
1672
+ if (clientOrderId !== undefined) {
1673
+ request[exchangeClientOrderId] = clientOrderId;
1674
+ }
1677
1675
  const timeInForce = this.safeStringUpper(params, 'timeInForce');
1678
1676
  if (timeInForce === 'IOC') {
1679
1677
  request['timeInForce'] = 'IOC';
@@ -1818,7 +1816,7 @@ export default class bingx extends Exchange {
1818
1816
  }
1819
1817
  request['positionSide'] = positionSide;
1820
1818
  request['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, amount));
1821
- params = this.omit(params, ['reduceOnly', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'takeProfit', 'stopLoss']);
1819
+ params = this.omit(params, ['reduceOnly', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'takeProfit', 'stopLoss', 'clientOrderId']);
1822
1820
  }
1823
1821
  return this.extend(request, params);
1824
1822
  }
@@ -1835,6 +1833,7 @@ export default class bingx extends Exchange {
1835
1833
  * @param {float} amount how much you want to trade in units of the base currency
1836
1834
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1837
1835
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1836
+ * @param {string} [params.clientOrderId] a unique id for the order
1838
1837
  * @param {bool} [params.postOnly] true to place a post only order
1839
1838
  * @param {string} [params.timeInForce] spot supports 'PO' and 'IOC', swap supports 'PO', 'GTC', 'IOC' and 'FOK'
1840
1839
  * @param {bool} [params.reduceOnly] *swap only* true or false whether the order is reduce only
@@ -1899,7 +1898,7 @@ export default class bingx extends Exchange {
1899
1898
  // }
1900
1899
  //
1901
1900
  if (typeof response === 'string') {
1902
- response = JSON.parse(response);
1901
+ response = this.parseJson(response);
1903
1902
  }
1904
1903
  const data = this.safeValue(response, 'data', {});
1905
1904
  const order = this.safeValue(data, 'order', data);
@@ -2160,7 +2159,7 @@ export default class bingx extends Exchange {
2160
2159
  'currency': feeCurrencyCode,
2161
2160
  'cost': Precise.stringAbs(feeCost),
2162
2161
  };
2163
- const clientOrderId = this.safeString2(order, 'clientOrderId', 'c');
2162
+ const clientOrderId = this.safeStringN(order, ['clientOrderID', 'origClientOrderId', 'c']);
2164
2163
  let stopLoss = this.safeValue(order, 'stopLoss');
2165
2164
  let stopLossPrice = undefined;
2166
2165
  if (stopLoss !== undefined) {
@@ -2169,7 +2168,7 @@ export default class bingx extends Exchange {
2169
2168
  if ((stopLoss !== undefined) && (typeof stopLoss !== 'number')) {
2170
2169
  // stopLoss: '{"stopPrice":50,"workingType":"MARK_PRICE","type":"STOP_MARKET","quantity":1}',
2171
2170
  if (typeof stopLoss === 'string') {
2172
- stopLoss = JSON.parse(stopLoss);
2171
+ stopLoss = this.parseJson(stopLoss);
2173
2172
  }
2174
2173
  stopLossPrice = this.safeNumber(stopLoss, 'stopPrice');
2175
2174
  }
@@ -2181,7 +2180,7 @@ export default class bingx extends Exchange {
2181
2180
  if ((takeProfit !== undefined) && (typeof takeProfit !== 'number')) {
2182
2181
  // takeProfit: '{"stopPrice":150,"workingType":"MARK_PRICE","type":"TAKE_PROFIT_MARKET","quantity":1}',
2183
2182
  if (typeof takeProfit === 'string') {
2184
- takeProfit = JSON.parse(takeProfit);
2183
+ takeProfit = this.parseJson(takeProfit);
2185
2184
  }
2186
2185
  takeProfitPrice = this.safeNumber(takeProfit, 'stopPrice');
2187
2186
  }
@@ -2235,6 +2234,7 @@ export default class bingx extends Exchange {
2235
2234
  * @param {string} id order id
2236
2235
  * @param {string} symbol unified symbol of the market the order was made in
2237
2236
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2237
+ * @param {string} [params.clientOrderId] a unique id for the order
2238
2238
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2239
2239
  */
2240
2240
  if (symbol === undefined) {
@@ -2244,8 +2244,15 @@ export default class bingx extends Exchange {
2244
2244
  const market = this.market(symbol);
2245
2245
  const request = {
2246
2246
  'symbol': market['id'],
2247
- 'orderId': id,
2248
2247
  };
2248
+ const clientOrderId = this.safeString2(params, 'clientOrderId', 'clientOrderID');
2249
+ params = this.omit(params, ['clientOrderId']);
2250
+ if (clientOrderId !== undefined) {
2251
+ request['clientOrderID'] = clientOrderId;
2252
+ }
2253
+ else {
2254
+ request['orderId'] = id;
2255
+ }
2249
2256
  let response = undefined;
2250
2257
  const [marketType, query] = this.handleMarketTypeAndParams('cancelOrder', market, params);
2251
2258
  if (marketType === 'spot') {
@@ -2421,7 +2428,7 @@ export default class bingx extends Exchange {
2421
2428
  }
2422
2429
  let response = undefined;
2423
2430
  if (market['spot']) {
2424
- const spotReqKey = areClientOrderIds ? 'clientOrderIds' : 'orderIds';
2431
+ const spotReqKey = areClientOrderIds ? 'clientOrderIDs' : 'orderIds';
2425
2432
  request[spotReqKey] = parsedIds.join(',');
2426
2433
  response = await this.spotV1PrivatePostTradeCancelOrders(this.extend(request, params));
2427
2434
  }
package/js/src/bitmex.js CHANGED
@@ -1830,14 +1830,15 @@ export default class bitmex extends Exchange {
1830
1830
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1831
1831
  * @param {object} [params.triggerPrice] the price at which a trigger order is triggered at
1832
1832
  * @param {object} [params.triggerDirection] the direction whenever the trigger happens with relation to price - 'above' or 'below'
1833
+ * @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
1833
1834
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1834
1835
  */
1835
1836
  await this.loadMarkets();
1836
1837
  const market = this.market(symbol);
1837
- const orderType = this.capitalize(type);
1838
+ let orderType = this.capitalize(type);
1838
1839
  const reduceOnly = this.safeValue(params, 'reduceOnly');
1839
1840
  if (reduceOnly !== undefined) {
1840
- if ((market['type'] !== 'swap') && (market['type'] !== 'future')) {
1841
+ if ((!market['swap']) && (!market['future'])) {
1841
1842
  throw new InvalidOrder(this.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap and future markets only');
1842
1843
  }
1843
1844
  }
@@ -1850,44 +1851,54 @@ export default class bitmex extends Exchange {
1850
1851
  'ordType': orderType,
1851
1852
  'text': brokerId,
1852
1853
  };
1853
- const customTriggerType = (orderType === 'Stop') || (orderType === 'StopLimit') || (orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched');
1854
1854
  // support for unified trigger format
1855
1855
  const triggerPrice = this.safeNumberN(params, ['triggerPrice', 'stopPx', 'stopPrice']);
1856
- if ((triggerPrice !== undefined) && !customTriggerType) {
1857
- request['stopPx'] = parseFloat(this.priceToPrecision(symbol, triggerPrice));
1856
+ let trailingAmount = this.safeString2(params, 'trailingAmount', 'pegOffsetValue');
1857
+ const isTriggerOrder = triggerPrice !== undefined;
1858
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1859
+ if (isTriggerOrder || isTrailingAmountOrder) {
1858
1860
  const triggerDirection = this.safeString(params, 'triggerDirection');
1859
- params = this.omit(params, ['triggerPrice', 'stopPrice', 'stopPx', 'triggerDirection']);
1860
1861
  const triggerAbove = (triggerDirection === 'above');
1861
- this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
1862
- this.checkRequiredArgument('createOrder', side, 'side', ['buy', 'sell']);
1862
+ if ((type === 'limit') || (type === 'market')) {
1863
+ this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
1864
+ }
1863
1865
  if (type === 'limit') {
1864
- request['price'] = parseFloat(this.priceToPrecision(symbol, price));
1865
1866
  if (side === 'buy') {
1866
- request['ordType'] = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
1867
+ orderType = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
1867
1868
  }
1868
1869
  else {
1869
- request['ordType'] = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
1870
+ orderType = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
1870
1871
  }
1871
1872
  }
1872
1873
  else if (type === 'market') {
1873
1874
  if (side === 'buy') {
1874
- request['ordType'] = triggerAbove ? 'Stop' : 'MarketIfTouched';
1875
+ orderType = triggerAbove ? 'Stop' : 'MarketIfTouched';
1875
1876
  }
1876
1877
  else {
1877
- request['ordType'] = triggerAbove ? 'MarketIfTouched' : 'Stop';
1878
+ orderType = triggerAbove ? 'MarketIfTouched' : 'Stop';
1878
1879
  }
1879
1880
  }
1880
- }
1881
- else if (customTriggerType) {
1882
- if (triggerPrice === undefined) {
1883
- // if exchange specific trigger types were provided
1884
- throw new ArgumentsRequired(this.id + ' createOrder() requires a triggerPrice (stopPx|stopPrice) parameter for the ' + orderType + ' order type');
1881
+ if (isTrailingAmountOrder) {
1882
+ const isStopSellOrder = (side === 'sell') && ((orderType === 'Stop') || (orderType === 'StopLimit'));
1883
+ const isBuyIfTouchedOrder = (side === 'buy') && ((orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched'));
1884
+ if (isStopSellOrder || isBuyIfTouchedOrder) {
1885
+ trailingAmount = '-' + trailingAmount;
1886
+ }
1887
+ request['pegOffsetValue'] = this.parseToNumeric(trailingAmount);
1888
+ request['pegPriceType'] = 'TrailingStopPeg';
1889
+ }
1890
+ else {
1891
+ if (triggerPrice === undefined) {
1892
+ // if exchange specific trigger types were provided
1893
+ throw new ArgumentsRequired(this.id + ' createOrder() requires a triggerPrice (stopPx|stopPrice) parameter for the ' + orderType + ' order type');
1894
+ }
1895
+ request['stopPx'] = this.parseToNumeric(this.priceToPrecision(symbol, triggerPrice));
1885
1896
  }
1886
- params = this.omit(params, ['triggerPrice', 'stopPrice', 'stopPx']);
1887
- request['stopPx'] = parseFloat(this.priceToPrecision(symbol, triggerPrice));
1897
+ request['ordType'] = orderType;
1898
+ params = this.omit(params, ['triggerPrice', 'stopPrice', 'stopPx', 'triggerDirection', 'trailingAmount']);
1888
1899
  }
1889
1900
  if ((orderType === 'Limit') || (orderType === 'StopLimit') || (orderType === 'LimitIfTouched')) {
1890
- request['price'] = parseFloat(this.priceToPrecision(symbol, price));
1901
+ request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
1891
1902
  }
1892
1903
  const clientOrderId = this.safeString2(params, 'clOrdID', 'clientOrderId');
1893
1904
  if (clientOrderId !== undefined) {
@@ -1900,6 +1911,39 @@ export default class bitmex extends Exchange {
1900
1911
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1901
1912
  await this.loadMarkets();
1902
1913
  const request = {};
1914
+ let trailingAmount = this.safeString2(params, 'trailingAmount', 'pegOffsetValue');
1915
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1916
+ if (isTrailingAmountOrder) {
1917
+ const triggerDirection = this.safeString(params, 'triggerDirection');
1918
+ const triggerAbove = (triggerDirection === 'above');
1919
+ if ((type === 'limit') || (type === 'market')) {
1920
+ this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
1921
+ }
1922
+ let orderType = undefined;
1923
+ if (type === 'limit') {
1924
+ if (side === 'buy') {
1925
+ orderType = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
1926
+ }
1927
+ else {
1928
+ orderType = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
1929
+ }
1930
+ }
1931
+ else if (type === 'market') {
1932
+ if (side === 'buy') {
1933
+ orderType = triggerAbove ? 'Stop' : 'MarketIfTouched';
1934
+ }
1935
+ else {
1936
+ orderType = triggerAbove ? 'MarketIfTouched' : 'Stop';
1937
+ }
1938
+ }
1939
+ const isStopSellOrder = (side === 'sell') && ((orderType === 'Stop') || (orderType === 'StopLimit'));
1940
+ const isBuyIfTouchedOrder = (side === 'buy') && ((orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched'));
1941
+ if (isStopSellOrder || isBuyIfTouchedOrder) {
1942
+ trailingAmount = '-' + trailingAmount;
1943
+ }
1944
+ request['pegOffsetValue'] = this.parseToNumeric(trailingAmount);
1945
+ params = this.omit(params, ['triggerDirection', 'trailingAmount']);
1946
+ }
1903
1947
  const origClOrdID = this.safeString2(params, 'origClOrdID', 'clientOrderId');
1904
1948
  if (origClOrdID !== undefined) {
1905
1949
  request['origClOrdID'] = origClOrdID;
package/js/src/bybit.js CHANGED
@@ -283,6 +283,7 @@ export default class bybit extends Exchange {
283
283
  'v5/position/list': 5,
284
284
  'v5/execution/list': 5,
285
285
  'v5/position/closed-pnl': 5,
286
+ 'v5/position/move-history': 5,
286
287
  // pre-upgrade
287
288
  'v5/pre-upgrade/order/history': 5,
288
289
  'v5/pre-upgrade/execution/list': 5,
@@ -447,6 +448,7 @@ export default class bybit extends Exchange {
447
448
  'v5/position/trading-stop': 5,
448
449
  'v5/position/set-auto-add-margin': 5,
449
450
  'v5/position/add-margin': 5,
451
+ 'v5/position/move-positions': 5,
450
452
  'v5/position/confirm-pending-mmr': 5,
451
453
  // account
452
454
  'v5/account/upgrade-to-uta': 5,
package/js/src/delta.js CHANGED
@@ -330,14 +330,14 @@ export default class delta extends Exchange {
330
330
  const markets = this.markets_by_id[symbol];
331
331
  return markets[0];
332
332
  }
333
- else if ((symbol.indexOf('-C') > -1) || (symbol.indexOf('-P') > -1) || (symbol.indexOf('C')) || (symbol.indexOf('P'))) {
333
+ else if ((symbol.endsWith('-C')) || (symbol.endsWith('-P')) || (symbol.startsWith('C-')) || (symbol.startsWith('P-'))) {
334
334
  return this.createExpiredOptionMarket(symbol);
335
335
  }
336
336
  }
337
337
  throw new BadSymbol(this.id + ' does not have market symbol ' + symbol);
338
338
  }
339
339
  safeMarket(marketId = undefined, market = undefined, delimiter = undefined, marketType = undefined) {
340
- const isOption = (marketId !== undefined) && ((marketId.indexOf('-C') > -1) || (marketId.indexOf('-P') > -1) || (marketId.indexOf('C')) || (marketId.indexOf('P')));
340
+ const isOption = (marketId !== undefined) && ((marketId.endsWith('-C')) || (marketId.endsWith('-P')) || (marketId.startsWith('C-')) || (marketId.startsWith('P-')));
341
341
  if (isOption && !(marketId in this.markets_by_id)) {
342
342
  // handle expired option contracts
343
343
  return this.createExpiredOptionMarket(marketId);
package/js/src/htx.d.ts CHANGED
@@ -266,4 +266,5 @@ export default class htx extends Exchange {
266
266
  };
267
267
  fetchLiquidations(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<import("./base/types.js").Liquidation[]>;
268
268
  parseLiquidation(liquidation: any, market?: Market): import("./base/types.js").Liquidation;
269
+ setPositionMode(hedged: any, symbol?: Str, params?: {}): Promise<any>;
269
270
  }