ccxt 4.2.5 → 4.2.7

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
  }
@@ -546,7 +546,7 @@ export default class Exchange {
546
546
  onConnected(client: any, message?: any): void;
547
547
  onError(client: any, error: any): void;
548
548
  onClose(client: any, error: any): void;
549
- close(): Promise<any[]>;
549
+ close(): Promise<void>;
550
550
  loadOrderBook(client: any, messageHash: any, symbol: any, limit?: any, params?: {}): Promise<void>;
551
551
  convertToBigInt(value: string): bigint;
552
552
  stringToCharsArray(value: any): any;
@@ -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);
package/js/src/bingx.js CHANGED
@@ -2234,6 +2234,7 @@ export default class bingx extends Exchange {
2234
2234
  * @param {string} id order id
2235
2235
  * @param {string} symbol unified symbol of the market the order was made in
2236
2236
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2237
+ * @param {string} [params.clientOrderId] a unique id for the order
2237
2238
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2238
2239
  */
2239
2240
  if (symbol === undefined) {
@@ -2243,8 +2244,15 @@ export default class bingx extends Exchange {
2243
2244
  const market = this.market(symbol);
2244
2245
  const request = {
2245
2246
  'symbol': market['id'],
2246
- 'orderId': id,
2247
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
+ }
2248
2256
  let response = undefined;
2249
2257
  const [marketType, query] = this.handleMarketTypeAndParams('cancelOrder', market, params);
2250
2258
  if (marketType === 'spot') {
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
@@ -1830,14 +1848,15 @@ export default class bitmex extends Exchange {
1830
1848
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1831
1849
  * @param {object} [params.triggerPrice] the price at which a trigger order is triggered at
1832
1850
  * @param {object} [params.triggerDirection] the direction whenever the trigger happens with relation to price - 'above' or 'below'
1851
+ * @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
1833
1852
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1834
1853
  */
1835
1854
  await this.loadMarkets();
1836
1855
  const market = this.market(symbol);
1837
- const orderType = this.capitalize(type);
1856
+ let orderType = this.capitalize(type);
1838
1857
  const reduceOnly = this.safeValue(params, 'reduceOnly');
1839
1858
  if (reduceOnly !== undefined) {
1840
- if ((market['type'] !== 'swap') && (market['type'] !== 'future')) {
1859
+ if ((!market['swap']) && (!market['future'])) {
1841
1860
  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
1861
  }
1843
1862
  }
@@ -1850,44 +1869,54 @@ export default class bitmex extends Exchange {
1850
1869
  'ordType': orderType,
1851
1870
  'text': brokerId,
1852
1871
  };
1853
- const customTriggerType = (orderType === 'Stop') || (orderType === 'StopLimit') || (orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched');
1854
1872
  // support for unified trigger format
1855
1873
  const triggerPrice = this.safeNumberN(params, ['triggerPrice', 'stopPx', 'stopPrice']);
1856
- if ((triggerPrice !== undefined) && !customTriggerType) {
1857
- request['stopPx'] = parseFloat(this.priceToPrecision(symbol, triggerPrice));
1874
+ let trailingAmount = this.safeString2(params, 'trailingAmount', 'pegOffsetValue');
1875
+ const isTriggerOrder = triggerPrice !== undefined;
1876
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1877
+ if (isTriggerOrder || isTrailingAmountOrder) {
1858
1878
  const triggerDirection = this.safeString(params, 'triggerDirection');
1859
- params = this.omit(params, ['triggerPrice', 'stopPrice', 'stopPx', 'triggerDirection']);
1860
1879
  const triggerAbove = (triggerDirection === 'above');
1861
- this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
1862
- this.checkRequiredArgument('createOrder', side, 'side', ['buy', 'sell']);
1880
+ if ((type === 'limit') || (type === 'market')) {
1881
+ this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
1882
+ }
1863
1883
  if (type === 'limit') {
1864
- request['price'] = parseFloat(this.priceToPrecision(symbol, price));
1865
1884
  if (side === 'buy') {
1866
- request['ordType'] = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
1885
+ orderType = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
1867
1886
  }
1868
1887
  else {
1869
- request['ordType'] = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
1888
+ orderType = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
1870
1889
  }
1871
1890
  }
1872
1891
  else if (type === 'market') {
1873
1892
  if (side === 'buy') {
1874
- request['ordType'] = triggerAbove ? 'Stop' : 'MarketIfTouched';
1893
+ orderType = triggerAbove ? 'Stop' : 'MarketIfTouched';
1875
1894
  }
1876
1895
  else {
1877
- request['ordType'] = triggerAbove ? 'MarketIfTouched' : 'Stop';
1896
+ orderType = triggerAbove ? 'MarketIfTouched' : 'Stop';
1878
1897
  }
1879
1898
  }
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');
1899
+ if (isTrailingAmountOrder) {
1900
+ const isStopSellOrder = (side === 'sell') && ((orderType === 'Stop') || (orderType === 'StopLimit'));
1901
+ const isBuyIfTouchedOrder = (side === 'buy') && ((orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched'));
1902
+ if (isStopSellOrder || isBuyIfTouchedOrder) {
1903
+ trailingAmount = '-' + trailingAmount;
1904
+ }
1905
+ request['pegOffsetValue'] = this.parseToNumeric(trailingAmount);
1906
+ request['pegPriceType'] = 'TrailingStopPeg';
1907
+ }
1908
+ else {
1909
+ if (triggerPrice === undefined) {
1910
+ // if exchange specific trigger types were provided
1911
+ throw new ArgumentsRequired(this.id + ' createOrder() requires a triggerPrice (stopPx|stopPrice) parameter for the ' + orderType + ' order type');
1912
+ }
1913
+ request['stopPx'] = this.parseToNumeric(this.priceToPrecision(symbol, triggerPrice));
1885
1914
  }
1886
- params = this.omit(params, ['triggerPrice', 'stopPrice', 'stopPx']);
1887
- request['stopPx'] = parseFloat(this.priceToPrecision(symbol, triggerPrice));
1915
+ request['ordType'] = orderType;
1916
+ params = this.omit(params, ['triggerPrice', 'stopPrice', 'stopPx', 'triggerDirection', 'trailingAmount']);
1888
1917
  }
1889
1918
  if ((orderType === 'Limit') || (orderType === 'StopLimit') || (orderType === 'LimitIfTouched')) {
1890
- request['price'] = parseFloat(this.priceToPrecision(symbol, price));
1919
+ request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
1891
1920
  }
1892
1921
  const clientOrderId = this.safeString2(params, 'clOrdID', 'clientOrderId');
1893
1922
  if (clientOrderId !== undefined) {
@@ -1900,6 +1929,39 @@ export default class bitmex extends Exchange {
1900
1929
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1901
1930
  await this.loadMarkets();
1902
1931
  const request = {};
1932
+ let trailingAmount = this.safeString2(params, 'trailingAmount', 'pegOffsetValue');
1933
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1934
+ if (isTrailingAmountOrder) {
1935
+ const triggerDirection = this.safeString(params, 'triggerDirection');
1936
+ const triggerAbove = (triggerDirection === 'above');
1937
+ if ((type === 'limit') || (type === 'market')) {
1938
+ this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
1939
+ }
1940
+ let orderType = undefined;
1941
+ if (type === 'limit') {
1942
+ if (side === 'buy') {
1943
+ orderType = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
1944
+ }
1945
+ else {
1946
+ orderType = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
1947
+ }
1948
+ }
1949
+ else if (type === 'market') {
1950
+ if (side === 'buy') {
1951
+ orderType = triggerAbove ? 'Stop' : 'MarketIfTouched';
1952
+ }
1953
+ else {
1954
+ orderType = triggerAbove ? 'MarketIfTouched' : 'Stop';
1955
+ }
1956
+ }
1957
+ const isStopSellOrder = (side === 'sell') && ((orderType === 'Stop') || (orderType === 'StopLimit'));
1958
+ const isBuyIfTouchedOrder = (side === 'buy') && ((orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched'));
1959
+ if (isStopSellOrder || isBuyIfTouchedOrder) {
1960
+ trailingAmount = '-' + trailingAmount;
1961
+ }
1962
+ request['pegOffsetValue'] = this.parseToNumeric(trailingAmount);
1963
+ params = this.omit(params, ['triggerDirection', 'trailingAmount']);
1964
+ }
1903
1965
  const origClOrdID = this.safeString2(params, 'origClOrdID', 'clientOrderId');
1904
1966
  if (origClOrdID !== undefined) {
1905
1967
  request['origClOrdID'] = origClOrdID;
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
  }
package/js/src/htx.js CHANGED
@@ -123,7 +123,7 @@ export default class htx extends Exchange {
123
123
  'repayIsolatedMargin': true,
124
124
  'setLeverage': true,
125
125
  'setMarginMode': false,
126
- 'setPositionMode': false,
126
+ 'setPositionMode': true,
127
127
  'signIn': undefined,
128
128
  'transfer': true,
129
129
  'withdraw': true,
@@ -8960,4 +8960,69 @@ export default class htx extends Exchange {
8960
8960
  'datetime': this.iso8601(timestamp),
8961
8961
  });
8962
8962
  }
8963
+ async setPositionMode(hedged, symbol = undefined, params = {}) {
8964
+ /**
8965
+ * @method
8966
+ * @name htx#setPositionMode
8967
+ * @description set hedged to true or false
8968
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-position-mode
8969
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-position-mode
8970
+ * @param {bool} hedged set to true to for hedged mode, must be set separately for each market in isolated margin mode, only valid for linear markets
8971
+ * @param {string} [symbol] unified market symbol, required for isolated margin mode
8972
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8973
+ * @param {string} [params.marginMode] "cross" (default) or "isolated"
8974
+ * @returns {object} response from the exchange
8975
+ */
8976
+ await this.loadMarkets();
8977
+ const posMode = hedged ? 'dual_side' : 'single_side';
8978
+ let market = undefined;
8979
+ if (symbol !== undefined) {
8980
+ market = this.market(symbol);
8981
+ }
8982
+ let marginMode = undefined;
8983
+ [marginMode, params] = this.handleMarginModeAndParams('setPositionMode', params, 'cross');
8984
+ const request = {
8985
+ 'position_mode': posMode,
8986
+ };
8987
+ let response = undefined;
8988
+ if ((market !== undefined) && (market['inverse'])) {
8989
+ throw new BadRequest(this.id + ' setPositionMode can only be used for linear markets');
8990
+ }
8991
+ if (marginMode === 'isolated') {
8992
+ if (symbol === undefined) {
8993
+ throw new ArgumentsRequired(this.id + ' setPositionMode requires a symbol argument for isolated margin mode');
8994
+ }
8995
+ request['margin_account'] = market['id'];
8996
+ response = await this.contractPrivatePostLinearSwapApiV1SwapSwitchPositionMode(this.extend(request, params));
8997
+ //
8998
+ // {
8999
+ // "status": "ok",
9000
+ // "data": [
9001
+ // {
9002
+ // "margin_account": "BTC-USDT",
9003
+ // "position_mode": "single_side"
9004
+ // }
9005
+ // ],
9006
+ // "ts": 1566899973811
9007
+ // }
9008
+ //
9009
+ }
9010
+ else {
9011
+ request['margin_account'] = 'USDT';
9012
+ response = await this.contractPrivatePostLinearSwapApiV1SwapCrossSwitchPositionMode(this.extend(request, params));
9013
+ //
9014
+ // {
9015
+ // "status": "ok",
9016
+ // "data": [
9017
+ // {
9018
+ // "margin_account": "USDT",
9019
+ // "position_mode": "single_side"
9020
+ // }
9021
+ // ],
9022
+ // "ts": 1566899973811
9023
+ // }
9024
+ //
9025
+ }
9026
+ return response;
9027
+ }
8963
9028
  }
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': {