ccxt 4.3.24 → 4.3.27

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.
package/README.md CHANGED
@@ -215,13 +215,13 @@ console.log(version, Object.keys(exchanges));
215
215
 
216
216
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
217
217
 
218
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.24/dist/ccxt.browser.js
219
- * unpkg: https://unpkg.com/ccxt@4.3.24/dist/ccxt.browser.js
218
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.27/dist/ccxt.browser.js
219
+ * unpkg: https://unpkg.com/ccxt@4.3.27/dist/ccxt.browser.js
220
220
 
221
221
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
222
222
 
223
223
  ```HTML
224
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.24/dist/ccxt.browser.js"></script>
224
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.27/dist/ccxt.browser.js"></script>
225
225
  ```
226
226
 
227
227
  Creates a global `ccxt` object:
package/dist/cjs/ccxt.js CHANGED
@@ -185,7 +185,7 @@ var woofipro$1 = require('./src/pro/woofipro.js');
185
185
 
186
186
  //-----------------------------------------------------------------------------
187
187
  // this is updated by vss.js when building
188
- const version = '4.3.24';
188
+ const version = '4.3.27';
189
189
  Exchange["default"].ccxtVersion = version;
190
190
  const exchanges = {
191
191
  'ace': ace,
@@ -3674,6 +3674,13 @@ class Exchange {
3674
3674
  }
3675
3675
  return [value, params];
3676
3676
  }
3677
+ handleParamString2(params, paramName1, paramName2, defaultValue = undefined) {
3678
+ const value = this.safeString2(params, paramName1, paramName2, defaultValue);
3679
+ if (value !== undefined) {
3680
+ params = this.omit(params, [paramName1, paramName2]);
3681
+ }
3682
+ return [value, params];
3683
+ }
3677
3684
  handleParamInteger(params, paramName, defaultValue = undefined) {
3678
3685
  const value = this.safeInteger(params, paramName, defaultValue);
3679
3686
  if (value !== undefined) {
@@ -3681,6 +3688,13 @@ class Exchange {
3681
3688
  }
3682
3689
  return [value, params];
3683
3690
  }
3691
+ handleParamInteger2(params, paramName1, paramName2, defaultValue = undefined) {
3692
+ const value = this.safeInteger2(params, paramName1, paramName2, defaultValue);
3693
+ if (value !== undefined) {
3694
+ params = this.omit(params, [paramName1, paramName2]);
3695
+ }
3696
+ return [value, params];
3697
+ }
3684
3698
  resolvePath(path, params) {
3685
3699
  return [
3686
3700
  this.implodeParams(path, params),
@@ -3824,7 +3838,7 @@ class Exchange {
3824
3838
  await this.cancelOrder(id, symbol);
3825
3839
  return await this.createOrder(symbol, type, side, amount, price, params);
3826
3840
  }
3827
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
3841
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
3828
3842
  await this.cancelOrderWs(id, symbol);
3829
3843
  return await this.createOrderWs(symbol, type, side, amount, price, params);
3830
3844
  }
@@ -4100,29 +4114,13 @@ class Exchange {
4100
4114
  }
4101
4115
  return [value, params];
4102
4116
  }
4103
- handleOptionAndParams2(params, methodName, methodName2, optionName, defaultValue = undefined) {
4104
- // This method can be used to obtain method specific properties, i.e: this.handleOptionAndParams (params, 'fetchPosition', 'marginMode', 'isolated')
4105
- const defaultOptionName = 'default' + this.capitalize(optionName); // we also need to check the 'defaultXyzWhatever'
4106
- // check if params contain the key
4107
- let value = this.safeValue2(params, optionName, defaultOptionName);
4108
- if (value !== undefined) {
4109
- params = this.omit(params, [optionName, defaultOptionName]);
4110
- }
4111
- else {
4112
- // check if exchange has properties for this method
4113
- const exchangeWideMethodOptions = this.safeValue2(this.options, methodName, methodName2);
4114
- if (exchangeWideMethodOptions !== undefined) {
4115
- // check if the option is defined inside this method's props
4116
- value = this.safeValue2(exchangeWideMethodOptions, optionName, defaultOptionName);
4117
- }
4118
- if (value === undefined) {
4119
- // if it's still undefined, check if global exchange-wide option exists
4120
- value = this.safeValue2(this.options, optionName, defaultOptionName);
4121
- }
4122
- // if it's still undefined, use the default value
4123
- value = (value !== undefined) ? value : defaultValue;
4124
- }
4125
- return [value, params];
4117
+ handleOptionAndParams2(params, methodName1, optionName1, optionName2, defaultValue = undefined) {
4118
+ let value = undefined;
4119
+ [value, params] = this.handleOptionAndParams(params, methodName1, optionName1, defaultValue);
4120
+ // if still undefined, try optionName2
4121
+ let value2 = undefined;
4122
+ [value2, params] = this.handleOptionAndParams(params, methodName1, optionName2, value);
4123
+ return [value2, params];
4126
4124
  }
4127
4125
  handleOption(methodName, optionName, defaultValue = undefined) {
4128
4126
  // eslint-disable-next-line no-unused-vars
@@ -272,13 +272,18 @@ const _decimalToPrecision = (x, roundingMode, numPrecisionDigits, countingMode =
272
272
  return String.fromCharCode(...out);
273
273
  };
274
274
  function omitZero(stringNumber) {
275
- if (stringNumber === undefined || stringNumber === '') {
276
- return undefined;
275
+ try {
276
+ if (stringNumber === undefined || stringNumber === '') {
277
+ return undefined;
278
+ }
279
+ if (parseFloat(stringNumber) === 0) {
280
+ return undefined;
281
+ }
282
+ return stringNumber;
277
283
  }
278
- if (parseFloat(stringNumber) === 0) {
279
- return undefined;
284
+ catch (e) {
285
+ return stringNumber;
280
286
  }
281
- return stringNumber;
282
287
  }
283
288
  /* ------------------------------------------------------------------------ */
284
289
 
@@ -444,11 +444,16 @@ class coinex extends coinex$1 {
444
444
  'fetchDepositAddress': {
445
445
  'fillResponseFromRequest': true,
446
446
  },
447
- 'accountsById': {
447
+ 'accountsByType': {
448
448
  'spot': 'SPOT',
449
449
  'margin': 'MARGIN',
450
450
  'swap': 'FUTURES',
451
451
  },
452
+ 'accountsById': {
453
+ 'SPOT': 'spot',
454
+ 'MARGIN': 'margin',
455
+ 'FUTURES': 'swap',
456
+ },
452
457
  'networks': {
453
458
  'BEP20': 'BSC',
454
459
  'TRX': 'TRC20',
@@ -4901,9 +4906,9 @@ class coinex extends coinex$1 {
4901
4906
  await this.loadMarkets();
4902
4907
  const currency = this.currency(code);
4903
4908
  const amountToPrecision = this.currencyToPrecision(code, amount);
4904
- const accountsById = this.safeDict(this.options, 'accountsById', {});
4905
- const fromId = this.safeString(accountsById, fromAccount, fromAccount);
4906
- const toId = this.safeString(accountsById, toAccount, toAccount);
4909
+ const accountsByType = this.safeDict(this.options, 'accountsById', {});
4910
+ const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
4911
+ const toId = this.safeString(accountsByType, toAccount, toAccount);
4907
4912
  const request = {
4908
4913
  'ccy': currency['id'],
4909
4914
  'amount': amountToPrecision,
@@ -4940,6 +4945,8 @@ class coinex extends coinex$1 {
4940
4945
  '0': 'ok',
4941
4946
  'SUCCESS': 'ok',
4942
4947
  'OK': 'ok',
4948
+ 'finished': 'ok',
4949
+ 'FINISHED': 'ok',
4943
4950
  };
4944
4951
  return this.safeString(statuses, status, status);
4945
4952
  }
@@ -4965,31 +4972,29 @@ class coinex extends coinex$1 {
4965
4972
  * @method
4966
4973
  * @name coinex#fetchTransfers
4967
4974
  * @description fetch a history of internal transfers made on an account
4968
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account025_margin_transfer_history
4969
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account024_contract_transfer_history
4975
+ * @see https://docs.coinex.com/api/v2/assets/transfer/http/list-transfer-history
4970
4976
  * @param {string} code unified currency code of the currency transferred
4971
4977
  * @param {int} [since] the earliest time in ms to fetch transfers for
4972
- * @param {int} [limit] the maximum number of transfers structures to retrieve
4978
+ * @param {int} [limit] the maximum number of transfer structures to retrieve
4973
4979
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4980
+ * @param {string} [params.marginMode] 'cross' or 'isolated' for fetching transfers to and from your margin account
4974
4981
  * @returns {object[]} a list of [transfer structures]{@link https://docs.ccxt.com/#/?id=transfer-structure}
4975
4982
  */
4976
4983
  await this.loadMarkets();
4977
- let currency = undefined;
4978
- const request = {
4979
- 'page': 1,
4980
- // 'limit': limit,
4981
- // 'asset': 'USDT',
4982
- // 'start_time': since,
4983
- // 'end_time': 1515806440,
4984
- // 'transfer_type': 'transfer_in', // transfer_in: from Spot to Swap Account, transfer_out: from Swap to Spot Account
4984
+ if (code === undefined) {
4985
+ throw new errors.ArgumentsRequired(this.id + ' fetchTransfers() requires a code argument');
4986
+ }
4987
+ const currency = this.currency(code);
4988
+ let request = {
4989
+ 'ccy': currency['id'],
4985
4990
  };
4986
- const page = this.safeInteger(params, 'page');
4987
- if (page !== undefined) {
4988
- request['page'] = page;
4991
+ let marginMode = undefined;
4992
+ [marginMode, params] = this.handleMarginModeAndParams('fetchTransfers', params);
4993
+ if (marginMode !== undefined) {
4994
+ request['transfer_type'] = 'MARGIN';
4989
4995
  }
4990
- if (code !== undefined) {
4991
- currency = this.currency(code);
4992
- request['asset'] = currency['id'];
4996
+ else {
4997
+ request['transfer_type'] = 'FUTURES';
4993
4998
  }
4994
4999
  if (since !== undefined) {
4995
5000
  request['start_time'] = since;
@@ -4997,66 +5002,30 @@ class coinex extends coinex$1 {
4997
5002
  if (limit !== undefined) {
4998
5003
  request['limit'] = limit;
4999
5004
  }
5000
- else {
5001
- request['limit'] = 100;
5002
- }
5003
- params = this.omit(params, 'page');
5004
- let marginMode = undefined;
5005
- [marginMode, params] = this.handleMarginModeAndParams('fetchTransfers', params);
5006
- let response = undefined;
5007
- if (marginMode !== undefined) {
5008
- response = await this.v1PrivateGetMarginTransferHistory(this.extend(request, params));
5009
- }
5010
- else {
5011
- response = await this.v1PrivateGetContractTransferHistory(this.extend(request, params));
5012
- }
5013
- //
5014
- // Swap
5005
+ [request, params] = this.handleUntilOption('end_time', request, params);
5006
+ const response = await this.v2PrivateGetAssetsTransferHistory(this.extend(request, params));
5015
5007
  //
5016
5008
  // {
5017
- // "code": 0,
5018
- // "data": {
5019
- // "records": [
5020
- // {
5021
- // "amount": "10",
5022
- // "asset": "USDT",
5023
- // "transfer_type": "transfer_out",
5024
- // "created_at": 1651633422
5025
- // },
5026
- // ],
5027
- // "total": 5
5009
+ // "data": [
5010
+ // {
5011
+ // "created_at": 1715848480646,
5012
+ // "from_account_type": "SPOT",
5013
+ // "to_account_type": "FUTURES",
5014
+ // "ccy": "USDT",
5015
+ // "amount": "10",
5016
+ // "status": "finished"
5017
+ // },
5018
+ // ],
5019
+ // "pagination": {
5020
+ // "total": 8,
5021
+ // "has_next": false
5028
5022
  // },
5029
- // "message": "Success"
5030
- // }
5031
- //
5032
- // Margin
5033
- //
5034
- // {
5035
5023
  // "code": 0,
5036
- // "data": {
5037
- // "records": [
5038
- // {
5039
- // "id": 7580062,
5040
- // "updated_at": 1653684379,
5041
- // "user_id": 3620173,
5042
- // "from_account_id": 0,
5043
- // "to_account_id": 1,
5044
- // "asset": "BTC",
5045
- // "amount": "0.00160829",
5046
- // "balance": "0.00160829",
5047
- // "transfer_type": "IN",
5048
- // "status": "SUCCESS",
5049
- // "created_at": 1653684379
5050
- // }
5051
- // ],
5052
- // "total": 1
5053
- // },
5054
- // "message": "Success"
5024
+ // "message": "OK"
5055
5025
  // }
5056
5026
  //
5057
- const data = this.safeValue(response, 'data', {});
5058
- const transfers = this.safeList(data, 'records', []);
5059
- return this.parseTransfers(transfers, currency, since, limit);
5027
+ const data = this.safeList(response, 'data', []);
5028
+ return this.parseTransfers(data, currency, since, limit);
5060
5029
  }
5061
5030
  async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
5062
5031
  /**
@@ -40,6 +40,9 @@ class kraken extends kraken$1 {
40
40
  'cancelOrder': true,
41
41
  'cancelOrders': true,
42
42
  'createDepositAddress': true,
43
+ 'createMarketBuyOrderWithCost': true,
44
+ 'createMarketOrderWithCost': false,
45
+ 'createMarketSellOrderWithCost': false,
43
46
  'createOrder': true,
44
47
  'createStopLimitOrder': true,
45
48
  'createStopMarketOrder': true,
@@ -1350,6 +1353,37 @@ class kraken extends kraken$1 {
1350
1353
  //
1351
1354
  return this.parseBalance(response);
1352
1355
  }
1356
+ async createMarketOrderWithCost(symbol, side, cost, params = {}) {
1357
+ /**
1358
+ * @method
1359
+ * @name kraken#createMarketOrderWithCost
1360
+ * @description create a market order by providing the symbol, side and cost
1361
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1362
+ * @param {string} symbol unified symbol of the market to create an order in (only USD markets are supported)
1363
+ * @param {string} side 'buy' or 'sell'
1364
+ * @param {float} cost how much you want to trade in units of the quote currency
1365
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1366
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1367
+ */
1368
+ await this.loadMarkets();
1369
+ // only buy orders are supported by the endpoint
1370
+ params['cost'] = cost;
1371
+ return await this.createOrder(symbol, 'market', side, cost, undefined, params);
1372
+ }
1373
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1374
+ /**
1375
+ * @method
1376
+ * @name kraken#createMarketBuyOrderWithCost
1377
+ * @description create a market buy order by providing the symbol, side and cost
1378
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1379
+ * @param {string} symbol unified symbol of the market to create an order in
1380
+ * @param {float} cost how much you want to trade in units of the quote currency
1381
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1382
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1383
+ */
1384
+ await this.loadMarkets();
1385
+ return await this.createMarketOrderWithCost(symbol, 'buy', cost, params);
1386
+ }
1353
1387
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1354
1388
  /**
1355
1389
  * @method
@@ -1380,7 +1414,7 @@ class kraken extends kraken$1 {
1380
1414
  'ordertype': type,
1381
1415
  'volume': this.amountToPrecision(symbol, amount),
1382
1416
  };
1383
- const orderRequest = this.orderRequest('createOrder', symbol, type, request, price, params);
1417
+ const orderRequest = this.orderRequest('createOrder', symbol, type, request, amount, price, params);
1384
1418
  const response = await this.privatePostAddOrder(this.extend(orderRequest[0], orderRequest[1]));
1385
1419
  //
1386
1420
  // {
@@ -1686,7 +1720,7 @@ class kraken extends kraken$1 {
1686
1720
  'trades': trades,
1687
1721
  }, market);
1688
1722
  }
1689
- orderRequest(method, symbol, type, request, price = undefined, params = {}) {
1723
+ orderRequest(method, symbol, type, request, amount, price = undefined, params = {}) {
1690
1724
  const clientOrderId = this.safeString2(params, 'userref', 'clientOrderId');
1691
1725
  params = this.omit(params, ['userref', 'clientOrderId']);
1692
1726
  if (clientOrderId !== undefined) {
@@ -1701,10 +1735,25 @@ class kraken extends kraken$1 {
1701
1735
  const trailingLimitAmount = this.safeString(params, 'trailingLimitAmount');
1702
1736
  const isTrailingAmountOrder = trailingAmount !== undefined;
1703
1737
  const isLimitOrder = type.endsWith('limit'); // supporting limit, stop-loss-limit, take-profit-limit, etc
1704
- if (isLimitOrder && !isTrailingAmountOrder) {
1738
+ const isMarketOrder = type === 'market';
1739
+ const cost = this.safeString(params, 'cost');
1740
+ const flags = this.safeString(params, 'oflags');
1741
+ params = this.omit(params, ['cost', 'oflags']);
1742
+ const isViqcOrder = (flags !== undefined) && (flags.indexOf('viqc') > -1); // volume in quote currency
1743
+ if (isMarketOrder && (cost !== undefined || isViqcOrder)) {
1744
+ if (cost === undefined && (amount !== undefined)) {
1745
+ request['volume'] = this.costToPrecision(symbol, this.numberToString(amount));
1746
+ }
1747
+ else {
1748
+ request['volume'] = this.costToPrecision(symbol, cost);
1749
+ }
1750
+ const extendedOflags = (flags !== undefined) ? flags + ',viqc' : 'viqc';
1751
+ request['oflags'] = extendedOflags;
1752
+ }
1753
+ else if (isLimitOrder && !isTrailingAmountOrder) {
1705
1754
  request['price'] = this.priceToPrecision(symbol, price);
1706
1755
  }
1707
- const reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1756
+ const reduceOnly = this.safeBool2(params, 'reduceOnly', 'reduce_only');
1708
1757
  if (isStopLossOrTakeProfitTrigger) {
1709
1758
  if (isStopLossTriggerOrder) {
1710
1759
  request['price'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
@@ -1752,7 +1801,7 @@ class kraken extends kraken$1 {
1752
1801
  request['reduce_only'] = 'true'; // not using boolean in this case, because the urlencodedNested transforms it into 'True' string
1753
1802
  }
1754
1803
  }
1755
- let close = this.safeValue(params, 'close');
1804
+ let close = this.safeDict(params, 'close');
1756
1805
  if (close !== undefined) {
1757
1806
  close = this.extend({}, close);
1758
1807
  const closePrice = this.safeValue(close, 'price');
@@ -1773,7 +1822,8 @@ class kraken extends kraken$1 {
1773
1822
  let postOnly = undefined;
1774
1823
  [postOnly, params] = this.handlePostOnly(isMarket, false, params);
1775
1824
  if (postOnly) {
1776
- request['oflags'] = 'post';
1825
+ const extendedPostFlags = (flags !== undefined) ? flags + ',post' : 'post';
1826
+ request['oflags'] = extendedPostFlags;
1777
1827
  }
1778
1828
  params = this.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset']);
1779
1829
  return [request, params];
@@ -1811,7 +1861,7 @@ class kraken extends kraken$1 {
1811
1861
  if (amount !== undefined) {
1812
1862
  request['volume'] = this.amountToPrecision(symbol, amount);
1813
1863
  }
1814
- const orderRequest = this.orderRequest('editOrder', symbol, type, request, price, params);
1864
+ const orderRequest = this.orderRequest('editOrder', symbol, type, request, amount, price, params);
1815
1865
  const response = await this.privatePostEditOrder(this.extend(orderRequest[0], orderRequest[1]));
1816
1866
  //
1817
1867
  // {
@@ -3004,6 +3054,9 @@ class kraken extends kraken$1 {
3004
3054
  if (body.indexOf('Invalid arguments:volume') >= 0) {
3005
3055
  throw new errors.InvalidOrder(this.id + ' ' + body);
3006
3056
  }
3057
+ if (body.indexOf('Invalid arguments:viqc') >= 0) {
3058
+ throw new errors.InvalidOrder(this.id + ' ' + body);
3059
+ }
3007
3060
  if (body.indexOf('Rate limit exceeded') >= 0) {
3008
3061
  throw new errors.RateLimitExceeded(this.id + ' ' + body);
3009
3062
  }
@@ -2249,7 +2249,7 @@ class phemex extends phemex$1 {
2249
2249
  if (feeCost !== undefined) {
2250
2250
  fee = {
2251
2251
  'cost': feeCost,
2252
- 'currency': undefined,
2252
+ 'currency': this.safeCurrencyCode(this.safeString(order, 'feeCurrency')),
2253
2253
  };
2254
2254
  }
2255
2255
  const timeInForce = this.parseTimeInForce(this.safeString(order, 'timeInForce'));
@@ -2396,6 +2396,7 @@ class phemex extends phemex$1 {
2396
2396
  }
2397
2397
  const marketId = this.safeString(order, 'symbol');
2398
2398
  const symbol = this.safeSymbol(marketId, market);
2399
+ market = this.safeMarket(marketId, market);
2399
2400
  const status = this.parseOrderStatus(this.safeString(order, 'ordStatus'));
2400
2401
  const side = this.parseOrderSide(this.safeStringLower(order, 'side'));
2401
2402
  const type = this.parseOrderType(this.safeString(order, 'orderType'));
@@ -2425,6 +2426,21 @@ class phemex extends phemex$1 {
2425
2426
  }
2426
2427
  const takeProfit = this.safeString(order, 'takeProfitRp');
2427
2428
  const stopLoss = this.safeString(order, 'stopLossRp');
2429
+ const feeValue = this.omitZero(this.safeString(order, 'execFeeRv'));
2430
+ const ptFeeRv = this.omitZero(this.safeString(order, 'ptFeeRv'));
2431
+ let fee = undefined;
2432
+ if (feeValue !== undefined) {
2433
+ fee = {
2434
+ 'cost': feeValue,
2435
+ 'currency': market['quote'],
2436
+ };
2437
+ }
2438
+ else if (ptFeeRv !== undefined) {
2439
+ fee = {
2440
+ 'cost': ptFeeRv,
2441
+ 'currency': 'PT',
2442
+ };
2443
+ }
2428
2444
  return this.safeOrder({
2429
2445
  'info': order,
2430
2446
  'id': id,
@@ -2449,7 +2465,7 @@ class phemex extends phemex$1 {
2449
2465
  'cost': cost,
2450
2466
  'average': undefined,
2451
2467
  'status': status,
2452
- 'fee': undefined,
2468
+ 'fee': fee,
2453
2469
  'trades': undefined,
2454
2470
  });
2455
2471
  }
@@ -2131,7 +2131,7 @@ class binance extends binance$1 {
2131
2131
  const orders = this.parseOrders(result);
2132
2132
  client.resolve(orders, messageHash);
2133
2133
  }
2134
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
2134
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
2135
2135
  /**
2136
2136
  * @method
2137
2137
  * @name binance#editOrderWs
@@ -102,14 +102,16 @@ class cryptocom extends cryptocom$1 {
102
102
  params['params'] = {};
103
103
  }
104
104
  let bookSubscriptionType = undefined;
105
- [bookSubscriptionType, params] = this.handleOptionAndParams2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE');
106
- if (bookSubscriptionType !== undefined) {
107
- params['params']['bookSubscriptionType'] = bookSubscriptionType;
108
- }
105
+ let bookSubscriptionType2 = undefined;
106
+ [bookSubscriptionType, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE');
107
+ [bookSubscriptionType2, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType);
108
+ params['params']['bookSubscriptionType'] = bookSubscriptionType2;
109
109
  let bookUpdateFrequency = undefined;
110
- [bookUpdateFrequency, params] = this.handleOptionAndParams2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookUpdateFrequency');
111
- if (bookUpdateFrequency !== undefined) {
112
- params['params']['bookSubscriptionType'] = bookSubscriptionType;
110
+ let bookUpdateFrequency2 = undefined;
111
+ [bookUpdateFrequency, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'bookUpdateFrequency');
112
+ [bookUpdateFrequency2, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency);
113
+ if (bookUpdateFrequency2 !== undefined) {
114
+ params['params']['bookSubscriptionType'] = bookUpdateFrequency2;
113
115
  }
114
116
  for (let i = 0; i < symbols.length; i++) {
115
117
  const symbol = symbols[i];
@@ -134,7 +134,7 @@ class kraken extends kraken$1 {
134
134
  'pair': market['wsId'],
135
135
  'volume': this.amountToPrecision(symbol, amount),
136
136
  };
137
- [request, params] = this.orderRequest('createOrderWs', symbol, type, request, price, params);
137
+ [request, params] = this.orderRequest('createOrderWs', symbol, type, request, amount, price, params);
138
138
  return await this.watch(url, messageHash, this.extend(request, params), messageHash);
139
139
  }
140
140
  handleCreateEditOrder(client, message) {
@@ -161,7 +161,7 @@ class kraken extends kraken$1 {
161
161
  const messageHash = this.safeValue(message, 'reqid');
162
162
  client.resolve(order, messageHash);
163
163
  }
164
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
164
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
165
165
  /**
166
166
  * @method
167
167
  * @name kraken#editOrderWs
@@ -188,9 +188,11 @@ class kraken extends kraken$1 {
188
188
  'reqid': requestId,
189
189
  'orderid': id,
190
190
  'pair': market['wsId'],
191
- 'volume': this.amountToPrecision(symbol, amount),
192
191
  };
193
- [request, params] = this.orderRequest('editOrderWs', symbol, type, request, price, params);
192
+ if (amount !== undefined) {
193
+ request['volume'] = this.amountToPrecision(symbol, amount);
194
+ }
195
+ [request, params] = this.orderRequest('editOrderWs', symbol, type, request, amount, price, params);
194
196
  return await this.watch(url, messageHash, this.extend(request, params), messageHash);
195
197
  }
196
198
  async cancelOrdersWs(ids, symbol = undefined, params = {}) {
@@ -1433,7 +1433,7 @@ class okx extends okx$1 {
1433
1433
  const first = this.safeDict(orders, 0, {});
1434
1434
  client.resolve(first, messageHash);
1435
1435
  }
1436
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
1436
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1437
1437
  /**
1438
1438
  * @method
1439
1439
  * @name okx#editOrderWs
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks, Leverage, Leverages, Option, OptionChain, Conversion } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout } from './src/base/errors.js';
7
- declare const version = "4.3.23";
7
+ declare const version = "4.3.26";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.3.24';
41
+ const version = '4.3.27';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -845,7 +845,9 @@ export default class Exchange {
845
845
  marketId(symbol: string): string;
846
846
  symbol(symbol: string): string;
847
847
  handleParamString(params: object, paramName: string, defaultValue?: Str): [string, object];
848
+ handleParamString2(params: object, paramName1: string, paramName2: string, defaultValue?: Str): [string, object];
848
849
  handleParamInteger(params: object, paramName: string, defaultValue?: Int): [Int, object];
850
+ handleParamInteger2(params: object, paramName1: string, paramName2: string, defaultValue?: Int): [Int, object];
849
851
  resolvePath(path: any, params: any): any[];
850
852
  getListFromObjectValues(objects: any, key: IndexType): any[];
851
853
  getSymbolsForMarketType(marketType?: Str, subType?: Str, symbolWithActiveStatus?: boolean, symbolWithUnknownStatus?: boolean): any[];
@@ -859,7 +861,7 @@ export default class Exchange {
859
861
  editLimitSellOrder(id: string, symbol: string, amount: number, price?: Num, params?: {}): Promise<Order>;
860
862
  editLimitOrder(id: string, symbol: string, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
861
863
  editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
862
- editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
864
+ editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
863
865
  fetchPermissions(params?: {}): Promise<{}>;
864
866
  fetchPosition(symbol: string, params?: {}): Promise<Position>;
865
867
  fetchPositionWs(symbol: string, params?: {}): Promise<Position[]>;
@@ -897,7 +899,7 @@ export default class Exchange {
897
899
  fetchCrossBorrowRate(code: string, params?: {}): Promise<CrossBorrowRate>;
898
900
  fetchIsolatedBorrowRate(symbol: string, params?: {}): Promise<IsolatedBorrowRate>;
899
901
  handleOptionAndParams(params: object, methodName: string, optionName: string, defaultValue?: any): any[];
900
- handleOptionAndParams2(params: object, methodName: string, methodName2: string, optionName: string, defaultValue?: any): any[];
902
+ handleOptionAndParams2(params: object, methodName1: string, optionName1: string, optionName2: string, defaultValue?: any): any[];
901
903
  handleOption(methodName: string, optionName: string, defaultValue?: any): any;
902
904
  handleMarketTypeAndParams(methodName: string, market?: Market, params?: {}, defaultValue?: any): any;
903
905
  handleSubTypeAndParams(methodName: string, market?: any, params?: {}, defaultValue?: any): any[];
@@ -3661,6 +3661,13 @@ export default class Exchange {
3661
3661
  }
3662
3662
  return [value, params];
3663
3663
  }
3664
+ handleParamString2(params, paramName1, paramName2, defaultValue = undefined) {
3665
+ const value = this.safeString2(params, paramName1, paramName2, defaultValue);
3666
+ if (value !== undefined) {
3667
+ params = this.omit(params, [paramName1, paramName2]);
3668
+ }
3669
+ return [value, params];
3670
+ }
3664
3671
  handleParamInteger(params, paramName, defaultValue = undefined) {
3665
3672
  const value = this.safeInteger(params, paramName, defaultValue);
3666
3673
  if (value !== undefined) {
@@ -3668,6 +3675,13 @@ export default class Exchange {
3668
3675
  }
3669
3676
  return [value, params];
3670
3677
  }
3678
+ handleParamInteger2(params, paramName1, paramName2, defaultValue = undefined) {
3679
+ const value = this.safeInteger2(params, paramName1, paramName2, defaultValue);
3680
+ if (value !== undefined) {
3681
+ params = this.omit(params, [paramName1, paramName2]);
3682
+ }
3683
+ return [value, params];
3684
+ }
3671
3685
  resolvePath(path, params) {
3672
3686
  return [
3673
3687
  this.implodeParams(path, params),
@@ -3811,7 +3825,7 @@ export default class Exchange {
3811
3825
  await this.cancelOrder(id, symbol);
3812
3826
  return await this.createOrder(symbol, type, side, amount, price, params);
3813
3827
  }
3814
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
3828
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
3815
3829
  await this.cancelOrderWs(id, symbol);
3816
3830
  return await this.createOrderWs(symbol, type, side, amount, price, params);
3817
3831
  }
@@ -4087,29 +4101,13 @@ export default class Exchange {
4087
4101
  }
4088
4102
  return [value, params];
4089
4103
  }
4090
- handleOptionAndParams2(params, methodName, methodName2, optionName, defaultValue = undefined) {
4091
- // This method can be used to obtain method specific properties, i.e: this.handleOptionAndParams (params, 'fetchPosition', 'marginMode', 'isolated')
4092
- const defaultOptionName = 'default' + this.capitalize(optionName); // we also need to check the 'defaultXyzWhatever'
4093
- // check if params contain the key
4094
- let value = this.safeValue2(params, optionName, defaultOptionName);
4095
- if (value !== undefined) {
4096
- params = this.omit(params, [optionName, defaultOptionName]);
4097
- }
4098
- else {
4099
- // check if exchange has properties for this method
4100
- const exchangeWideMethodOptions = this.safeValue2(this.options, methodName, methodName2);
4101
- if (exchangeWideMethodOptions !== undefined) {
4102
- // check if the option is defined inside this method's props
4103
- value = this.safeValue2(exchangeWideMethodOptions, optionName, defaultOptionName);
4104
- }
4105
- if (value === undefined) {
4106
- // if it's still undefined, check if global exchange-wide option exists
4107
- value = this.safeValue2(this.options, optionName, defaultOptionName);
4108
- }
4109
- // if it's still undefined, use the default value
4110
- value = (value !== undefined) ? value : defaultValue;
4111
- }
4112
- return [value, params];
4104
+ handleOptionAndParams2(params, methodName1, optionName1, optionName2, defaultValue = undefined) {
4105
+ let value = undefined;
4106
+ [value, params] = this.handleOptionAndParams(params, methodName1, optionName1, defaultValue);
4107
+ // if still undefined, try optionName2
4108
+ let value2 = undefined;
4109
+ [value2, params] = this.handleOptionAndParams(params, methodName1, optionName2, value);
4110
+ return [value2, params];
4113
4111
  }
4114
4112
  handleOption(methodName, optionName, defaultValue = undefined) {
4115
4113
  // eslint-disable-next-line no-unused-vars
@@ -274,13 +274,18 @@ const _decimalToPrecision = (x, roundingMode, numPrecisionDigits, countingMode =
274
274
  return String.fromCharCode(...out);
275
275
  };
276
276
  function omitZero(stringNumber) {
277
- if (stringNumber === undefined || stringNumber === '') {
278
- return undefined;
277
+ try {
278
+ if (stringNumber === undefined || stringNumber === '') {
279
+ return undefined;
280
+ }
281
+ if (parseFloat(stringNumber) === 0) {
282
+ return undefined;
283
+ }
284
+ return stringNumber;
279
285
  }
280
- if (parseFloat(stringNumber) === 0) {
281
- return undefined;
286
+ catch (e) {
287
+ return stringNumber;
282
288
  }
283
- return stringNumber;
284
289
  }
285
290
  /* ------------------------------------------------------------------------ */
286
291
  export { numberToString, precisionFromString, decimalToPrecision, truncate_to_string, truncate, omitZero, precisionConstants, ROUND, TRUNCATE, ROUND_UP, ROUND_DOWN, DECIMAL_PLACES, SIGNIFICANT_DIGITS, TICK_SIZE, NO_PADDING, PAD_WITH_ZERO, };
package/js/src/coinex.js CHANGED
@@ -447,11 +447,16 @@ export default class coinex extends Exchange {
447
447
  'fetchDepositAddress': {
448
448
  'fillResponseFromRequest': true,
449
449
  },
450
- 'accountsById': {
450
+ 'accountsByType': {
451
451
  'spot': 'SPOT',
452
452
  'margin': 'MARGIN',
453
453
  'swap': 'FUTURES',
454
454
  },
455
+ 'accountsById': {
456
+ 'SPOT': 'spot',
457
+ 'MARGIN': 'margin',
458
+ 'FUTURES': 'swap',
459
+ },
455
460
  'networks': {
456
461
  'BEP20': 'BSC',
457
462
  'TRX': 'TRC20',
@@ -4904,9 +4909,9 @@ export default class coinex extends Exchange {
4904
4909
  await this.loadMarkets();
4905
4910
  const currency = this.currency(code);
4906
4911
  const amountToPrecision = this.currencyToPrecision(code, amount);
4907
- const accountsById = this.safeDict(this.options, 'accountsById', {});
4908
- const fromId = this.safeString(accountsById, fromAccount, fromAccount);
4909
- const toId = this.safeString(accountsById, toAccount, toAccount);
4912
+ const accountsByType = this.safeDict(this.options, 'accountsById', {});
4913
+ const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
4914
+ const toId = this.safeString(accountsByType, toAccount, toAccount);
4910
4915
  const request = {
4911
4916
  'ccy': currency['id'],
4912
4917
  'amount': amountToPrecision,
@@ -4943,6 +4948,8 @@ export default class coinex extends Exchange {
4943
4948
  '0': 'ok',
4944
4949
  'SUCCESS': 'ok',
4945
4950
  'OK': 'ok',
4951
+ 'finished': 'ok',
4952
+ 'FINISHED': 'ok',
4946
4953
  };
4947
4954
  return this.safeString(statuses, status, status);
4948
4955
  }
@@ -4968,31 +4975,29 @@ export default class coinex extends Exchange {
4968
4975
  * @method
4969
4976
  * @name coinex#fetchTransfers
4970
4977
  * @description fetch a history of internal transfers made on an account
4971
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account025_margin_transfer_history
4972
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account024_contract_transfer_history
4978
+ * @see https://docs.coinex.com/api/v2/assets/transfer/http/list-transfer-history
4973
4979
  * @param {string} code unified currency code of the currency transferred
4974
4980
  * @param {int} [since] the earliest time in ms to fetch transfers for
4975
- * @param {int} [limit] the maximum number of transfers structures to retrieve
4981
+ * @param {int} [limit] the maximum number of transfer structures to retrieve
4976
4982
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4983
+ * @param {string} [params.marginMode] 'cross' or 'isolated' for fetching transfers to and from your margin account
4977
4984
  * @returns {object[]} a list of [transfer structures]{@link https://docs.ccxt.com/#/?id=transfer-structure}
4978
4985
  */
4979
4986
  await this.loadMarkets();
4980
- let currency = undefined;
4981
- const request = {
4982
- 'page': 1,
4983
- // 'limit': limit,
4984
- // 'asset': 'USDT',
4985
- // 'start_time': since,
4986
- // 'end_time': 1515806440,
4987
- // 'transfer_type': 'transfer_in', // transfer_in: from Spot to Swap Account, transfer_out: from Swap to Spot Account
4987
+ if (code === undefined) {
4988
+ throw new ArgumentsRequired(this.id + ' fetchTransfers() requires a code argument');
4989
+ }
4990
+ const currency = this.currency(code);
4991
+ let request = {
4992
+ 'ccy': currency['id'],
4988
4993
  };
4989
- const page = this.safeInteger(params, 'page');
4990
- if (page !== undefined) {
4991
- request['page'] = page;
4994
+ let marginMode = undefined;
4995
+ [marginMode, params] = this.handleMarginModeAndParams('fetchTransfers', params);
4996
+ if (marginMode !== undefined) {
4997
+ request['transfer_type'] = 'MARGIN';
4992
4998
  }
4993
- if (code !== undefined) {
4994
- currency = this.currency(code);
4995
- request['asset'] = currency['id'];
4999
+ else {
5000
+ request['transfer_type'] = 'FUTURES';
4996
5001
  }
4997
5002
  if (since !== undefined) {
4998
5003
  request['start_time'] = since;
@@ -5000,66 +5005,30 @@ export default class coinex extends Exchange {
5000
5005
  if (limit !== undefined) {
5001
5006
  request['limit'] = limit;
5002
5007
  }
5003
- else {
5004
- request['limit'] = 100;
5005
- }
5006
- params = this.omit(params, 'page');
5007
- let marginMode = undefined;
5008
- [marginMode, params] = this.handleMarginModeAndParams('fetchTransfers', params);
5009
- let response = undefined;
5010
- if (marginMode !== undefined) {
5011
- response = await this.v1PrivateGetMarginTransferHistory(this.extend(request, params));
5012
- }
5013
- else {
5014
- response = await this.v1PrivateGetContractTransferHistory(this.extend(request, params));
5015
- }
5016
- //
5017
- // Swap
5008
+ [request, params] = this.handleUntilOption('end_time', request, params);
5009
+ const response = await this.v2PrivateGetAssetsTransferHistory(this.extend(request, params));
5018
5010
  //
5019
5011
  // {
5020
- // "code": 0,
5021
- // "data": {
5022
- // "records": [
5023
- // {
5024
- // "amount": "10",
5025
- // "asset": "USDT",
5026
- // "transfer_type": "transfer_out",
5027
- // "created_at": 1651633422
5028
- // },
5029
- // ],
5030
- // "total": 5
5012
+ // "data": [
5013
+ // {
5014
+ // "created_at": 1715848480646,
5015
+ // "from_account_type": "SPOT",
5016
+ // "to_account_type": "FUTURES",
5017
+ // "ccy": "USDT",
5018
+ // "amount": "10",
5019
+ // "status": "finished"
5020
+ // },
5021
+ // ],
5022
+ // "pagination": {
5023
+ // "total": 8,
5024
+ // "has_next": false
5031
5025
  // },
5032
- // "message": "Success"
5033
- // }
5034
- //
5035
- // Margin
5036
- //
5037
- // {
5038
5026
  // "code": 0,
5039
- // "data": {
5040
- // "records": [
5041
- // {
5042
- // "id": 7580062,
5043
- // "updated_at": 1653684379,
5044
- // "user_id": 3620173,
5045
- // "from_account_id": 0,
5046
- // "to_account_id": 1,
5047
- // "asset": "BTC",
5048
- // "amount": "0.00160829",
5049
- // "balance": "0.00160829",
5050
- // "transfer_type": "IN",
5051
- // "status": "SUCCESS",
5052
- // "created_at": 1653684379
5053
- // }
5054
- // ],
5055
- // "total": 1
5056
- // },
5057
- // "message": "Success"
5027
+ // "message": "OK"
5058
5028
  // }
5059
5029
  //
5060
- const data = this.safeValue(response, 'data', {});
5061
- const transfers = this.safeList(data, 'records', []);
5062
- return this.parseTransfers(transfers, currency, since, limit);
5030
+ const data = this.safeList(response, 'data', []);
5031
+ return this.parseTransfers(data, currency, since, limit);
5063
5032
  }
5064
5033
  async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
5065
5034
  /**
@@ -56,13 +56,15 @@ export default class kraken extends Exchange {
56
56
  fetchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
57
57
  parseBalance(response: any): Balances;
58
58
  fetchBalance(params?: {}): Promise<Balances>;
59
+ createMarketOrderWithCost(symbol: string, side: OrderSide, cost: number, params?: {}): Promise<Order>;
60
+ createMarketBuyOrderWithCost(symbol: string, cost: number, params?: {}): Promise<Order>;
59
61
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
60
62
  findMarketByAltnameOrId(id: any): any;
61
63
  getDelistedMarketById(id: any): any;
62
64
  parseOrderStatus(status: any): string;
63
65
  parseOrderType(status: any): string;
64
66
  parseOrder(order: any, market?: Market): Order;
65
- orderRequest(method: any, symbol: any, type: any, request: any, price?: any, params?: {}): any[];
67
+ orderRequest(method: string, symbol: string, type: string, request: Dict, amount: Num, price?: Num, params?: {}): Dict[];
66
68
  editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
67
69
  fetchOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
68
70
  fetchOrderTrades(id: string, symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
package/js/src/kraken.js CHANGED
@@ -43,6 +43,9 @@ export default class kraken extends Exchange {
43
43
  'cancelOrder': true,
44
44
  'cancelOrders': true,
45
45
  'createDepositAddress': true,
46
+ 'createMarketBuyOrderWithCost': true,
47
+ 'createMarketOrderWithCost': false,
48
+ 'createMarketSellOrderWithCost': false,
46
49
  'createOrder': true,
47
50
  'createStopLimitOrder': true,
48
51
  'createStopMarketOrder': true,
@@ -1353,6 +1356,37 @@ export default class kraken extends Exchange {
1353
1356
  //
1354
1357
  return this.parseBalance(response);
1355
1358
  }
1359
+ async createMarketOrderWithCost(symbol, side, cost, params = {}) {
1360
+ /**
1361
+ * @method
1362
+ * @name kraken#createMarketOrderWithCost
1363
+ * @description create a market order by providing the symbol, side and cost
1364
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1365
+ * @param {string} symbol unified symbol of the market to create an order in (only USD markets are supported)
1366
+ * @param {string} side 'buy' or 'sell'
1367
+ * @param {float} cost how much you want to trade in units of the quote currency
1368
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1369
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1370
+ */
1371
+ await this.loadMarkets();
1372
+ // only buy orders are supported by the endpoint
1373
+ params['cost'] = cost;
1374
+ return await this.createOrder(symbol, 'market', side, cost, undefined, params);
1375
+ }
1376
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1377
+ /**
1378
+ * @method
1379
+ * @name kraken#createMarketBuyOrderWithCost
1380
+ * @description create a market buy order by providing the symbol, side and cost
1381
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1382
+ * @param {string} symbol unified symbol of the market to create an order in
1383
+ * @param {float} cost how much you want to trade in units of the quote currency
1384
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1385
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1386
+ */
1387
+ await this.loadMarkets();
1388
+ return await this.createMarketOrderWithCost(symbol, 'buy', cost, params);
1389
+ }
1356
1390
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1357
1391
  /**
1358
1392
  * @method
@@ -1383,7 +1417,7 @@ export default class kraken extends Exchange {
1383
1417
  'ordertype': type,
1384
1418
  'volume': this.amountToPrecision(symbol, amount),
1385
1419
  };
1386
- const orderRequest = this.orderRequest('createOrder', symbol, type, request, price, params);
1420
+ const orderRequest = this.orderRequest('createOrder', symbol, type, request, amount, price, params);
1387
1421
  const response = await this.privatePostAddOrder(this.extend(orderRequest[0], orderRequest[1]));
1388
1422
  //
1389
1423
  // {
@@ -1689,7 +1723,7 @@ export default class kraken extends Exchange {
1689
1723
  'trades': trades,
1690
1724
  }, market);
1691
1725
  }
1692
- orderRequest(method, symbol, type, request, price = undefined, params = {}) {
1726
+ orderRequest(method, symbol, type, request, amount, price = undefined, params = {}) {
1693
1727
  const clientOrderId = this.safeString2(params, 'userref', 'clientOrderId');
1694
1728
  params = this.omit(params, ['userref', 'clientOrderId']);
1695
1729
  if (clientOrderId !== undefined) {
@@ -1704,10 +1738,25 @@ export default class kraken extends Exchange {
1704
1738
  const trailingLimitAmount = this.safeString(params, 'trailingLimitAmount');
1705
1739
  const isTrailingAmountOrder = trailingAmount !== undefined;
1706
1740
  const isLimitOrder = type.endsWith('limit'); // supporting limit, stop-loss-limit, take-profit-limit, etc
1707
- if (isLimitOrder && !isTrailingAmountOrder) {
1741
+ const isMarketOrder = type === 'market';
1742
+ const cost = this.safeString(params, 'cost');
1743
+ const flags = this.safeString(params, 'oflags');
1744
+ params = this.omit(params, ['cost', 'oflags']);
1745
+ const isViqcOrder = (flags !== undefined) && (flags.indexOf('viqc') > -1); // volume in quote currency
1746
+ if (isMarketOrder && (cost !== undefined || isViqcOrder)) {
1747
+ if (cost === undefined && (amount !== undefined)) {
1748
+ request['volume'] = this.costToPrecision(symbol, this.numberToString(amount));
1749
+ }
1750
+ else {
1751
+ request['volume'] = this.costToPrecision(symbol, cost);
1752
+ }
1753
+ const extendedOflags = (flags !== undefined) ? flags + ',viqc' : 'viqc';
1754
+ request['oflags'] = extendedOflags;
1755
+ }
1756
+ else if (isLimitOrder && !isTrailingAmountOrder) {
1708
1757
  request['price'] = this.priceToPrecision(symbol, price);
1709
1758
  }
1710
- const reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1759
+ const reduceOnly = this.safeBool2(params, 'reduceOnly', 'reduce_only');
1711
1760
  if (isStopLossOrTakeProfitTrigger) {
1712
1761
  if (isStopLossTriggerOrder) {
1713
1762
  request['price'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
@@ -1755,7 +1804,7 @@ export default class kraken extends Exchange {
1755
1804
  request['reduce_only'] = 'true'; // not using boolean in this case, because the urlencodedNested transforms it into 'True' string
1756
1805
  }
1757
1806
  }
1758
- let close = this.safeValue(params, 'close');
1807
+ let close = this.safeDict(params, 'close');
1759
1808
  if (close !== undefined) {
1760
1809
  close = this.extend({}, close);
1761
1810
  const closePrice = this.safeValue(close, 'price');
@@ -1776,7 +1825,8 @@ export default class kraken extends Exchange {
1776
1825
  let postOnly = undefined;
1777
1826
  [postOnly, params] = this.handlePostOnly(isMarket, false, params);
1778
1827
  if (postOnly) {
1779
- request['oflags'] = 'post';
1828
+ const extendedPostFlags = (flags !== undefined) ? flags + ',post' : 'post';
1829
+ request['oflags'] = extendedPostFlags;
1780
1830
  }
1781
1831
  params = this.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset']);
1782
1832
  return [request, params];
@@ -1814,7 +1864,7 @@ export default class kraken extends Exchange {
1814
1864
  if (amount !== undefined) {
1815
1865
  request['volume'] = this.amountToPrecision(symbol, amount);
1816
1866
  }
1817
- const orderRequest = this.orderRequest('editOrder', symbol, type, request, price, params);
1867
+ const orderRequest = this.orderRequest('editOrder', symbol, type, request, amount, price, params);
1818
1868
  const response = await this.privatePostEditOrder(this.extend(orderRequest[0], orderRequest[1]));
1819
1869
  //
1820
1870
  // {
@@ -3007,6 +3057,9 @@ export default class kraken extends Exchange {
3007
3057
  if (body.indexOf('Invalid arguments:volume') >= 0) {
3008
3058
  throw new InvalidOrder(this.id + ' ' + body);
3009
3059
  }
3060
+ if (body.indexOf('Invalid arguments:viqc') >= 0) {
3061
+ throw new InvalidOrder(this.id + ' ' + body);
3062
+ }
3010
3063
  if (body.indexOf('Rate limit exceeded') >= 0) {
3011
3064
  throw new RateLimitExceeded(this.id + ' ' + body);
3012
3065
  }
package/js/src/phemex.js CHANGED
@@ -2252,7 +2252,7 @@ export default class phemex extends Exchange {
2252
2252
  if (feeCost !== undefined) {
2253
2253
  fee = {
2254
2254
  'cost': feeCost,
2255
- 'currency': undefined,
2255
+ 'currency': this.safeCurrencyCode(this.safeString(order, 'feeCurrency')),
2256
2256
  };
2257
2257
  }
2258
2258
  const timeInForce = this.parseTimeInForce(this.safeString(order, 'timeInForce'));
@@ -2399,6 +2399,7 @@ export default class phemex extends Exchange {
2399
2399
  }
2400
2400
  const marketId = this.safeString(order, 'symbol');
2401
2401
  const symbol = this.safeSymbol(marketId, market);
2402
+ market = this.safeMarket(marketId, market);
2402
2403
  const status = this.parseOrderStatus(this.safeString(order, 'ordStatus'));
2403
2404
  const side = this.parseOrderSide(this.safeStringLower(order, 'side'));
2404
2405
  const type = this.parseOrderType(this.safeString(order, 'orderType'));
@@ -2428,6 +2429,21 @@ export default class phemex extends Exchange {
2428
2429
  }
2429
2430
  const takeProfit = this.safeString(order, 'takeProfitRp');
2430
2431
  const stopLoss = this.safeString(order, 'stopLossRp');
2432
+ const feeValue = this.omitZero(this.safeString(order, 'execFeeRv'));
2433
+ const ptFeeRv = this.omitZero(this.safeString(order, 'ptFeeRv'));
2434
+ let fee = undefined;
2435
+ if (feeValue !== undefined) {
2436
+ fee = {
2437
+ 'cost': feeValue,
2438
+ 'currency': market['quote'],
2439
+ };
2440
+ }
2441
+ else if (ptFeeRv !== undefined) {
2442
+ fee = {
2443
+ 'cost': ptFeeRv,
2444
+ 'currency': 'PT',
2445
+ };
2446
+ }
2431
2447
  return this.safeOrder({
2432
2448
  'info': order,
2433
2449
  'id': id,
@@ -2452,7 +2468,7 @@ export default class phemex extends Exchange {
2452
2468
  'cost': cost,
2453
2469
  'average': undefined,
2454
2470
  'status': status,
2455
- 'fee': undefined,
2471
+ 'fee': fee,
2456
2472
  'trades': undefined,
2457
2473
  });
2458
2474
  }
@@ -52,7 +52,7 @@ export default class binance extends binanceRest {
52
52
  createOrderWs(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
53
53
  handleOrderWs(client: Client, message: any): void;
54
54
  handleOrdersWs(client: Client, message: any): void;
55
- editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
55
+ editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
56
56
  handleEditOrderWs(client: Client, message: any): void;
57
57
  cancelOrderWs(id: string, symbol?: Str, params?: {}): Promise<Order>;
58
58
  cancelAllOrdersWs(symbol?: Str, params?: {}): Promise<any>;
@@ -2134,7 +2134,7 @@ export default class binance extends binanceRest {
2134
2134
  const orders = this.parseOrders(result);
2135
2135
  client.resolve(orders, messageHash);
2136
2136
  }
2137
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
2137
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
2138
2138
  /**
2139
2139
  * @method
2140
2140
  * @name binance#editOrderWs
@@ -105,14 +105,16 @@ export default class cryptocom extends cryptocomRest {
105
105
  params['params'] = {};
106
106
  }
107
107
  let bookSubscriptionType = undefined;
108
- [bookSubscriptionType, params] = this.handleOptionAndParams2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE');
109
- if (bookSubscriptionType !== undefined) {
110
- params['params']['bookSubscriptionType'] = bookSubscriptionType;
111
- }
108
+ let bookSubscriptionType2 = undefined;
109
+ [bookSubscriptionType, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE');
110
+ [bookSubscriptionType2, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType);
111
+ params['params']['bookSubscriptionType'] = bookSubscriptionType2;
112
112
  let bookUpdateFrequency = undefined;
113
- [bookUpdateFrequency, params] = this.handleOptionAndParams2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookUpdateFrequency');
114
- if (bookUpdateFrequency !== undefined) {
115
- params['params']['bookSubscriptionType'] = bookSubscriptionType;
113
+ let bookUpdateFrequency2 = undefined;
114
+ [bookUpdateFrequency, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'bookUpdateFrequency');
115
+ [bookUpdateFrequency2, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency);
116
+ if (bookUpdateFrequency2 !== undefined) {
117
+ params['params']['bookSubscriptionType'] = bookUpdateFrequency2;
116
118
  }
117
119
  for (let i = 0; i < symbols.length; i++) {
118
120
  const symbol = symbols[i];
@@ -5,7 +5,7 @@ export default class kraken extends krakenRest {
5
5
  describe(): any;
6
6
  createOrderWs(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
7
7
  handleCreateEditOrder(client: any, message: any): void;
8
- editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
8
+ editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
9
9
  cancelOrdersWs(ids: string[], symbol?: Str, params?: {}): Promise<any>;
10
10
  cancelOrderWs(id: string, symbol?: Str, params?: {}): Promise<Order>;
11
11
  handleCancelOrder(client: any, message: any): void;
@@ -137,7 +137,7 @@ export default class kraken extends krakenRest {
137
137
  'pair': market['wsId'],
138
138
  'volume': this.amountToPrecision(symbol, amount),
139
139
  };
140
- [request, params] = this.orderRequest('createOrderWs', symbol, type, request, price, params);
140
+ [request, params] = this.orderRequest('createOrderWs', symbol, type, request, amount, price, params);
141
141
  return await this.watch(url, messageHash, this.extend(request, params), messageHash);
142
142
  }
143
143
  handleCreateEditOrder(client, message) {
@@ -164,7 +164,7 @@ export default class kraken extends krakenRest {
164
164
  const messageHash = this.safeValue(message, 'reqid');
165
165
  client.resolve(order, messageHash);
166
166
  }
167
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
167
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
168
168
  /**
169
169
  * @method
170
170
  * @name kraken#editOrderWs
@@ -191,9 +191,11 @@ export default class kraken extends krakenRest {
191
191
  'reqid': requestId,
192
192
  'orderid': id,
193
193
  'pair': market['wsId'],
194
- 'volume': this.amountToPrecision(symbol, amount),
195
194
  };
196
- [request, params] = this.orderRequest('editOrderWs', symbol, type, request, price, params);
195
+ if (amount !== undefined) {
196
+ request['volume'] = this.amountToPrecision(symbol, amount);
197
+ }
198
+ [request, params] = this.orderRequest('editOrderWs', symbol, type, request, amount, price, params);
197
199
  return await this.watch(url, messageHash, this.extend(request, params), messageHash);
198
200
  }
199
201
  async cancelOrdersWs(ids, symbol = undefined, params = {}) {
@@ -36,7 +36,7 @@ export default class okx extends okxRest {
36
36
  handleMyTrades(client: Client, message: any): void;
37
37
  createOrderWs(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
38
38
  handlePlaceOrders(client: Client, message: any): void;
39
- editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
39
+ editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
40
40
  cancelOrderWs(id: string, symbol?: Str, params?: {}): Promise<Order>;
41
41
  cancelOrdersWs(ids: string[], symbol?: Str, params?: {}): Promise<any>;
42
42
  cancelAllOrdersWs(symbol?: Str, params?: {}): Promise<any>;
package/js/src/pro/okx.js CHANGED
@@ -1436,7 +1436,7 @@ export default class okx extends okxRest {
1436
1436
  const first = this.safeDict(orders, 0, {});
1437
1437
  client.resolve(first, messageHash);
1438
1438
  }
1439
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
1439
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1440
1440
  /**
1441
1441
  * @method
1442
1442
  * @name okx#editOrderWs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.3.24",
3
+ "version": "4.3.27",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",