ccxt 4.1.39 → 4.1.41

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.1.39/dist/ccxt.browser.js
219
- * unpkg: https://unpkg.com/ccxt@4.1.39/dist/ccxt.browser.js
218
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.1.41/dist/ccxt.browser.js
219
+ * unpkg: https://unpkg.com/ccxt@4.1.41/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.1.39/dist/ccxt.browser.js"></script>
224
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.1.41/dist/ccxt.browser.js"></script>
225
225
  ```
226
226
 
227
227
  Creates a global `ccxt` object:
package/build.sh CHANGED
@@ -59,7 +59,6 @@ build_and_test_all () {
59
59
  npm run force-build
60
60
  if [[ "$IS_TRAVIS" == "TRUE" ]]; then
61
61
  npm run test-base
62
- npm run static-tests
63
62
  npm run test-base-ws
64
63
  run_tests
65
64
  fi
@@ -155,8 +154,8 @@ if [ ${#REST_EXCHANGES[@]} -eq 0 ] && [ ${#WS_EXCHANGES[@]} -eq 0 ]; then
155
154
  exit
156
155
  fi
157
156
 
158
- # run static tests:
159
- npm run static-tests
157
+ # run base tests (base js,py,php, brokerId and static-tests)
158
+ npm run test-base
160
159
 
161
160
  # rest_args=${REST_EXCHANGES[*]} || "skip"
162
161
  rest_args=$(IFS=" " ; echo "${REST_EXCHANGES[*]}") || "skip"
@@ -8057,6 +8057,17 @@ class Exchange {
8057
8057
  const convertedNumber = parseFloat(stringifiedNumber);
8058
8058
  return parseInt(convertedNumber);
8059
8059
  }
8060
+ parseToNumeric(number) {
8061
+ const stringVersion = this.numberToString(number); // this will convert 1.0 and 1 to "1" and 1.1 to "1.1"
8062
+ // keep this in mind:
8063
+ // in JS: 1 == 1.0 is true
8064
+ // in Python: 1 == 1.0 is true
8065
+ // in PHP 1 == 1.0 is false
8066
+ if (stringVersion.indexOf('.') > 0) {
8067
+ return parseFloat(stringVersion);
8068
+ }
8069
+ return parseInt(stringVersion);
8070
+ }
8060
8071
  afterConstruct() {
8061
8072
  this.createNetworksByIdObject();
8062
8073
  }
@@ -11038,7 +11049,13 @@ class Exchange {
11038
11049
  }
11039
11050
  params[cursorSent] = cursorValue;
11040
11051
  }
11041
- const response = await this[method](symbol, since, maxEntriesPerRequest, params);
11052
+ let response = undefined;
11053
+ if (method === 'fetchAccounts') {
11054
+ response = await this[method](params);
11055
+ }
11056
+ else {
11057
+ response = await this[method](symbol, since, maxEntriesPerRequest, params);
11058
+ }
11042
11059
  errors = 0;
11043
11060
  const responseLength = response.length;
11044
11061
  if (this.verbose) {
@@ -26049,6 +26066,7 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
26049
26066
  'cancelOrder': true,
26050
26067
  'cancelOrders': true,
26051
26068
  'createOrder': true,
26069
+ 'createOrders': true,
26052
26070
  'fetchBalance': true,
26053
26071
  'fetchClosedOrders': true,
26054
26072
  'fetchCurrencies': true,
@@ -27607,31 +27625,22 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27607
27625
  'takeProfitPrice': undefined,
27608
27626
  });
27609
27627
  }
27610
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
27628
+ createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
27611
27629
  /**
27612
27630
  * @method
27613
- * @name bingx#createOrder
27614
- * @description create a trade order
27615
- * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Create%20an%20Order
27616
- * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Trade%20order
27631
+ * @ignore
27632
+ * @name bingx#createOrderRequest
27633
+ * @description helper function to build request
27617
27634
  * @param {string} symbol unified symbol of the market to create an order in
27618
27635
  * @param {string} type 'market' or 'limit'
27619
27636
  * @param {string} side 'buy' or 'sell'
27620
- * @param {float} amount how much of currency you want to trade in units of base currency
27637
+ * @param {float} amount how much you want to trade in units of the base currency
27621
27638
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
27622
27639
  * @param {object} [params] extra parameters specific to the bingx api endpoint
27623
- * @param {bool} [params.postOnly] true to place a post only order
27624
- * @param {string} [params.timeInForce] spot supports 'PO' and 'IOC', swap supports 'PO', 'GTC', 'IOC' and 'FOK'
27625
- * @param {bool} [params.reduceOnly] *swap only* true or false whether the order is reduce only
27626
- * @param {float} [params.triggerPrice] *swap only* triggerPrice at which the attached take profit / stop loss order will be triggered
27627
- * @param {float} [params.stopLossPrice] *swap only* stop loss trigger price
27628
- * @param {float} [params.takeProfitPrice] *swap only* take profit trigger price
27629
- * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
27640
+ * @returns {object} request to be sent to the exchange
27630
27641
  */
27631
- await this.loadMarkets();
27632
27642
  const market = this.market(symbol);
27633
27643
  let postOnly = undefined;
27634
- let response = undefined;
27635
27644
  let marketType = undefined;
27636
27645
  [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
27637
27646
  type = type.toUpperCase();
@@ -27661,20 +27670,19 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27661
27670
  const amountString = this.numberToString(amount);
27662
27671
  const priceString = this.numberToString(price);
27663
27672
  const cost = this.parseNumber(_base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringMul */ .O.stringMul(amountString, priceString));
27664
- request['quoteOrderQty'] = this.priceToPrecision(symbol, cost);
27673
+ request['quoteOrderQty'] = this.parseToNumeric(this.priceToPrecision(symbol, cost));
27665
27674
  }
27666
27675
  }
27667
27676
  else {
27668
- request['quoteOrderQty'] = this.priceToPrecision(symbol, amount);
27677
+ request['quoteOrderQty'] = this.parseToNumeric(this.priceToPrecision(symbol, amount));
27669
27678
  }
27670
27679
  }
27671
27680
  else {
27672
- request['quantity'] = this.amountToPrecision(symbol, amount);
27681
+ request['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, amount));
27673
27682
  }
27674
27683
  if (!isMarketOrder) {
27675
- request['price'] = this.priceToPrecision(symbol, price);
27684
+ request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
27676
27685
  }
27677
- response = await this.spotV1PrivatePostTradeOrder(this.extend(request, params));
27678
27686
  }
27679
27687
  else {
27680
27688
  [postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'PostOnly', params);
@@ -27688,7 +27696,7 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27688
27696
  request['timeInForce'] = 'FOK';
27689
27697
  }
27690
27698
  if ((type === 'LIMIT') || (type === 'TRIGGER_LIMIT') || (type === 'STOP') || (type === 'TAKE_PROFIT')) {
27691
- request['price'] = this.priceToPrecision(symbol, price);
27699
+ request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
27692
27700
  }
27693
27701
  const triggerPrice = this.safeNumber2(params, 'stopPrice', 'triggerPrice');
27694
27702
  const stopLossPrice = this.safeNumber(params, 'stopLossPrice');
@@ -27696,8 +27704,9 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27696
27704
  const isTriggerOrder = triggerPrice !== undefined;
27697
27705
  const isStopLossPriceOrder = stopLossPrice !== undefined;
27698
27706
  const isTakeProfitPriceOrder = takeProfitPrice !== undefined;
27707
+ let reduceOnly = this.safeValue(params, 'reduceOnly', false);
27699
27708
  if (isTriggerOrder) {
27700
- request['stopPrice'] = this.priceToPrecision(symbol, triggerPrice);
27709
+ request['stopPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, triggerPrice));
27701
27710
  if (isMarketOrder || (type === 'TRIGGER_MARKET')) {
27702
27711
  request['type'] = 'TRIGGER_MARKET';
27703
27712
  }
@@ -27707,8 +27716,9 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27707
27716
  }
27708
27717
  else if (isStopLossPriceOrder || isTakeProfitPriceOrder) {
27709
27718
  // This can be used to set the stop loss and take profit, but the position needs to be opened first
27719
+ reduceOnly = true;
27710
27720
  if (isStopLossPriceOrder) {
27711
- request['stopPrice'] = this.priceToPrecision(symbol, stopLossPrice);
27721
+ request['stopPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, stopLossPrice));
27712
27722
  if (isMarketOrder || (type === 'STOP_MARKET')) {
27713
27723
  request['type'] = 'STOP_MARKET';
27714
27724
  }
@@ -27717,7 +27727,7 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27717
27727
  }
27718
27728
  }
27719
27729
  else if (isTakeProfitPriceOrder) {
27720
- request['stopPrice'] = this.priceToPrecision(symbol, takeProfitPrice);
27730
+ request['stopPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, takeProfitPrice));
27721
27731
  if (isMarketOrder || (type === 'TAKE_PROFIT_MARKET')) {
27722
27732
  request['type'] = 'TAKE_PROFIT_MARKET';
27723
27733
  }
@@ -27726,7 +27736,6 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27726
27736
  }
27727
27737
  }
27728
27738
  }
27729
- const reduceOnly = this.safeValue(params, 'reduceOnly', false);
27730
27739
  let positionSide = undefined;
27731
27740
  if (reduceOnly) {
27732
27741
  positionSide = (side === 'buy') ? 'SHORT' : 'LONG';
@@ -27735,9 +27744,41 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27735
27744
  positionSide = (side === 'buy') ? 'LONG' : 'SHORT';
27736
27745
  }
27737
27746
  request['positionSide'] = positionSide;
27738
- request['quantity'] = this.amountToPrecision(symbol, amount);
27747
+ request['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, amount));
27739
27748
  params = this.omit(params, ['reduceOnly', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
27740
- response = await this.swapV2PrivatePostTradeOrder(this.extend(request, params));
27749
+ }
27750
+ return this.extend(request, params);
27751
+ }
27752
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
27753
+ /**
27754
+ * @method
27755
+ * @name bingx#createOrder
27756
+ * @description create a trade order
27757
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Create%20an%20Order
27758
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Trade%20order
27759
+ * @param {string} symbol unified symbol of the market to create an order in
27760
+ * @param {string} type 'market' or 'limit'
27761
+ * @param {string} side 'buy' or 'sell'
27762
+ * @param {float} amount how much you want to trade in units of the base currency
27763
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
27764
+ * @param {object} [params] extra parameters specific to the bingx api endpoint
27765
+ * @param {bool} [params.postOnly] true to place a post only order
27766
+ * @param {string} [params.timeInForce] spot supports 'PO' and 'IOC', swap supports 'PO', 'GTC', 'IOC' and 'FOK'
27767
+ * @param {bool} [params.reduceOnly] *swap only* true or false whether the order is reduce only
27768
+ * @param {float} [params.triggerPrice] *swap only* triggerPrice at which the attached take profit / stop loss order will be triggered
27769
+ * @param {float} [params.stopLossPrice] *swap only* stop loss trigger price
27770
+ * @param {float} [params.takeProfitPrice] *swap only* take profit trigger price
27771
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
27772
+ */
27773
+ await this.loadMarkets();
27774
+ const market = this.market(symbol);
27775
+ const request = this.createOrderRequest(symbol, type, side, amount, price, params);
27776
+ let response = undefined;
27777
+ if (market['swap']) {
27778
+ response = await this.swapV2PrivatePostTradeOrder(request);
27779
+ }
27780
+ else {
27781
+ response = await this.spotV1PrivatePostTradeOrder(request);
27741
27782
  }
27742
27783
  //
27743
27784
  // spot
@@ -27781,6 +27822,99 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27781
27822
  const order = this.safeValue(data, 'order', data);
27782
27823
  return this.parseOrder(order, market);
27783
27824
  }
27825
+ async createOrders(orders, params = {}) {
27826
+ /**
27827
+ * @method
27828
+ * @name bingx#createOrders
27829
+ * @description create a list of trade orders
27830
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Batch%20Placing%20Orders
27831
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Bulk%20order
27832
+ * @param {array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
27833
+ * @param {object} [params] extra parameters specific to the bingx api endpoint
27834
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
27835
+ */
27836
+ await this.loadMarkets();
27837
+ const ordersRequests = [];
27838
+ let symbol = undefined;
27839
+ for (let i = 0; i < orders.length; i++) {
27840
+ const rawOrder = orders[i];
27841
+ const marketId = this.safeString(rawOrder, 'symbol');
27842
+ if (symbol === undefined) {
27843
+ symbol = marketId;
27844
+ }
27845
+ else {
27846
+ if (symbol !== marketId) {
27847
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
27848
+ }
27849
+ }
27850
+ const type = this.safeString(rawOrder, 'type');
27851
+ const side = this.safeString(rawOrder, 'side');
27852
+ const amount = this.safeNumber(rawOrder, 'amount');
27853
+ const price = this.safeNumber(rawOrder, 'price');
27854
+ const orderParams = this.safeValue(rawOrder, 'params', {});
27855
+ const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
27856
+ ordersRequests.push(orderRequest);
27857
+ }
27858
+ const market = this.market(symbol);
27859
+ const request = {};
27860
+ let response = undefined;
27861
+ if (market['swap']) {
27862
+ request['batchOrders'] = this.json(ordersRequests);
27863
+ response = await this.swapV2PrivatePostTradeBatchOrders(request);
27864
+ }
27865
+ else {
27866
+ request['data'] = this.json(ordersRequests);
27867
+ response = await this.spotV1PrivatePostTradeBatchOrders(request);
27868
+ }
27869
+ //
27870
+ // spot
27871
+ //
27872
+ // {
27873
+ // "code": 0,
27874
+ // "msg": "",
27875
+ // "debugMsg": "",
27876
+ // "data": {
27877
+ // "orders": [
27878
+ // {
27879
+ // "symbol": "BTC-USDT",
27880
+ // "orderId": 1720661389564968960,
27881
+ // "transactTime": 1699072618272,
27882
+ // "price": "25000",
27883
+ // "origQty": "0.0002",
27884
+ // "executedQty": "0",
27885
+ // "cummulativeQuoteQty": "0",
27886
+ // "status": "PENDING",
27887
+ // "type": "LIMIT",
27888
+ // "side": "BUY"
27889
+ // },
27890
+ // ]
27891
+ // }
27892
+ // }
27893
+ //
27894
+ // swap
27895
+ //
27896
+ // {
27897
+ // "code": 0,
27898
+ // "msg": "",
27899
+ // "data": {
27900
+ // "orders": [
27901
+ // {
27902
+ // "symbol": "BTC-USDT",
27903
+ // "orderId": 1720657081994006528,
27904
+ // "side": "BUY",
27905
+ // "positionSide": "LONG",
27906
+ // "type": "LIMIT",
27907
+ // "clientOrderID": "",
27908
+ // "workingType": ""
27909
+ // },
27910
+ // ]
27911
+ // }
27912
+ // }
27913
+ //
27914
+ const data = this.safeValue(response, 'data', {});
27915
+ const result = this.safeValue(data, 'orders', []);
27916
+ return this.parseOrders(result, market);
27917
+ }
27784
27918
  parseOrderSide(side) {
27785
27919
  const sides = {
27786
27920
  'BUY': 'buy',
@@ -27793,7 +27927,7 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27793
27927
  parseOrder(order, market = undefined) {
27794
27928
  //
27795
27929
  // spot
27796
- // createOrder, cancelOrder
27930
+ // createOrder, createOrders, cancelOrder
27797
27931
  //
27798
27932
  // {
27799
27933
  // "symbol": "XRP-USDT",
@@ -27846,7 +27980,7 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
27846
27980
  //
27847
27981
  //
27848
27982
  // swap
27849
- // createOrder
27983
+ // createOrder, createOrders
27850
27984
  //
27851
27985
  // {
27852
27986
  // "symbol": "BTC-USDT",
@@ -64563,6 +64697,7 @@ class bittrex extends _abstract_bittrex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
64563
64697
  'max': undefined,
64564
64698
  },
64565
64699
  },
64700
+ 'networks': {},
64566
64701
  };
64567
64702
  }
64568
64703
  return result;
@@ -83867,6 +84002,7 @@ class coinbase extends _abstract_coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
83867
84002
  * @name coinbase#fetchAccounts
83868
84003
  * @description fetch all the accounts associated with a profile
83869
84004
  * @param {object} [params] extra parameters specific to the coinbase api endpoint
84005
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
83870
84006
  * @returns {object} a dictionary of [account structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#account-structure} indexed by the account type
83871
84007
  */
83872
84008
  const method = this.safeString(this.options, 'fetchAccounts', 'fetchAccountsV3');
@@ -83877,6 +84013,11 @@ class coinbase extends _abstract_coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
83877
84013
  }
83878
84014
  async fetchAccountsV2(params = {}) {
83879
84015
  await this.loadMarkets();
84016
+ let paginate = false;
84017
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchAccounts', 'paginate');
84018
+ if (paginate) {
84019
+ return await this.fetchPaginatedCallCursor('fetchAccounts', undefined, undefined, undefined, params, 'next_starting_after', 'starting_after', undefined, 100);
84020
+ }
83880
84021
  const request = {
83881
84022
  'limit': 100,
83882
84023
  };
@@ -83926,10 +84067,24 @@ class coinbase extends _abstract_coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
83926
84067
  // }
83927
84068
  //
83928
84069
  const data = this.safeValue(response, 'data', []);
84070
+ const pagination = this.safeValue(response, 'pagination', {});
84071
+ const cursor = this.safeString(pagination, 'next_starting_after');
84072
+ const accounts = this.safeValue(response, 'data', []);
84073
+ const lastIndex = accounts.length - 1;
84074
+ const last = this.safeValue(accounts, lastIndex);
84075
+ if ((cursor !== undefined) && (cursor !== '')) {
84076
+ last['next_starting_after'] = cursor;
84077
+ accounts[lastIndex] = last;
84078
+ }
83929
84079
  return this.parseAccounts(data, params);
83930
84080
  }
83931
84081
  async fetchAccountsV3(params = {}) {
83932
84082
  await this.loadMarkets();
84083
+ let paginate = false;
84084
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchAccounts', 'paginate');
84085
+ if (paginate) {
84086
+ return await this.fetchPaginatedCallCursor('fetchAccounts', undefined, undefined, undefined, params, 'cursor', 'cursor', undefined, 100);
84087
+ }
83933
84088
  const request = {
83934
84089
  'limit': 100,
83935
84090
  };
@@ -83964,8 +84119,15 @@ class coinbase extends _abstract_coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
83964
84119
  // "size": 9
83965
84120
  // }
83966
84121
  //
83967
- const data = this.safeValue(response, 'accounts', []);
83968
- return this.parseAccounts(data, params);
84122
+ const accounts = this.safeValue(response, 'accounts', []);
84123
+ const lastIndex = accounts.length - 1;
84124
+ const last = this.safeValue(accounts, lastIndex);
84125
+ const cursor = this.safeString(response, 'cursor');
84126
+ if ((cursor !== undefined) && (cursor !== '')) {
84127
+ last['cursor'] = cursor;
84128
+ accounts[lastIndex] = last;
84129
+ }
84130
+ return this.parseAccounts(accounts, params);
83969
84131
  }
83970
84132
  parseAccount(account) {
83971
84133
  //
@@ -182368,9 +182530,12 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
182368
182530
  '51028': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ContractUnavailable,
182369
182531
  '51029': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ContractUnavailable,
182370
182532
  '51030': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ContractUnavailable,
182533
+ '51031': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182371
182534
  '51046': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182372
182535
  '51047': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182373
- '51031': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182536
+ '51072': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182537
+ '51073': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182538
+ '51074': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182374
182539
  '51100': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182375
182540
  '51101': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182376
182541
  '51102': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
@@ -182415,6 +182580,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
182415
182580
  '51163': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182416
182581
  '51166': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182417
182582
  '51174': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182583
+ '51185': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182418
182584
  '51201': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182419
182585
  '51202': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
182420
182586
  '51203': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder,
@@ -182562,6 +182728,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
182562
182728
  '59200': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InsufficientFunds,
182563
182729
  '59201': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InsufficientFunds,
182564
182730
  '59216': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
182731
+ '59260': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.PermissionDenied,
182732
+ '59262': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.PermissionDenied,
182565
182733
  '59300': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError,
182566
182734
  '59301': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError,
182567
182735
  '59313': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError,
@@ -182575,6 +182743,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
182575
182743
  '59506': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError,
182576
182744
  '59507': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError,
182577
182745
  '59508': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AccountSuspended,
182746
+ '59642': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
182747
+ '59643': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError,
182578
182748
  // WebSocket error Codes from 60000-63999
182579
182749
  '60001': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
182580
182750
  '60002': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
@@ -200943,10 +201113,11 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
200943
201113
  }
200944
201114
  async authenticate(params = {}) {
200945
201115
  const time = this.milliseconds();
200946
- let type = this.safeString2(this.options, 'defaultType', 'authenticate', 'spot');
200947
- type = this.safeString(params, 'type', type);
201116
+ let query = undefined;
201117
+ let type = undefined;
201118
+ [type, query] = this.handleMarketTypeAndParams('authenticate', undefined, params);
200948
201119
  let subType = undefined;
200949
- [subType, params] = this.handleSubTypeAndParams('authenticate', undefined, params);
201120
+ [subType, query] = this.handleSubTypeAndParams('authenticate', undefined, query);
200950
201121
  if (this.isLinear(type, subType)) {
200951
201122
  type = 'future';
200952
201123
  }
@@ -200954,11 +201125,11 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
200954
201125
  type = 'delivery';
200955
201126
  }
200956
201127
  let marginMode = undefined;
200957
- [marginMode, params] = this.handleMarginModeAndParams('authenticate', params);
201128
+ [marginMode, query] = this.handleMarginModeAndParams('authenticate', query);
200958
201129
  const isIsolatedMargin = (marginMode === 'isolated');
200959
201130
  const isCrossMargin = (marginMode === 'cross') || (marginMode === undefined);
200960
- const symbol = this.safeString(params, 'symbol');
200961
- params = this.omit(params, 'symbol');
201131
+ const symbol = this.safeString(query, 'symbol');
201132
+ query = this.omit(query, 'symbol');
200962
201133
  const options = this.safeValue(this.options, type, {});
200963
201134
  const lastAuthenticatedTime = this.safeInteger(options, 'lastAuthenticatedTime', 0);
200964
201135
  const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
@@ -200980,9 +201151,9 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
200980
201151
  throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' authenticate() requires a symbol argument for isolated margin mode');
200981
201152
  }
200982
201153
  const marketId = this.marketId(symbol);
200983
- params = this.extend(params, { 'symbol': marketId });
201154
+ query = this.extend(query, { 'symbol': marketId });
200984
201155
  }
200985
- const response = await this[method](params);
201156
+ const response = await this[method](query);
200986
201157
  this.options[type] = this.extend(options, {
200987
201158
  'listenKey': this.safeString(response, 'listenKey'),
200988
201159
  'lastAuthenticatedTime': time,
@@ -200994,8 +201165,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
200994
201165
  // https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot
200995
201166
  let type = this.safeString2(this.options, 'defaultType', 'authenticate', 'spot');
200996
201167
  type = this.safeString(params, 'type', type);
200997
- let subType = undefined;
200998
- [subType, params] = this.handleSubTypeAndParams('keepAliveListenKey', undefined, params);
201168
+ const subTypeInfo = this.handleSubTypeAndParams('keepAliveListenKey', undefined, params);
201169
+ const subType = subTypeInfo[0];
200999
201170
  if (this.isLinear(type, subType)) {
201000
201171
  type = 'future';
201001
201172
  }
@@ -201772,7 +201943,7 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
201772
201943
  market = this.market(symbol);
201773
201944
  symbol = market['symbol'];
201774
201945
  messageHash += ':' + symbol;
201775
- params = this.extend(params, { 'symbol': symbol }); // needed inside authenticate for isolated margin
201946
+ params = this.extend(params, { 'type': market['type'], 'symbol': symbol }); // needed inside authenticate for isolated margin
201776
201947
  }
201777
201948
  await this.authenticate(params);
201778
201949
  let type = undefined;
@@ -201785,7 +201956,11 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
201785
201956
  else if (this.isInverse(type, subType)) {
201786
201957
  type = 'delivery';
201787
201958
  }
201788
- const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
201959
+ let urlType = type;
201960
+ if (type === 'margin') {
201961
+ urlType = 'spot'; // spot-margin shares the same stream as regular spot
201962
+ }
201963
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
201789
201964
  const client = this.client(url);
201790
201965
  this.setBalanceCache(client, type);
201791
201966
  const message = undefined;
@@ -202125,10 +202300,15 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
202125
202300
  * @returns {object[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#trade-structure
202126
202301
  */
202127
202302
  await this.loadMarkets();
202128
- const defaultType = this.safeString2(this.options, 'watchMyTrades', 'defaultType', 'spot');
202129
- let type = this.safeString(params, 'type', defaultType);
202303
+ let type = undefined;
202304
+ let market = undefined;
202305
+ if (symbol !== undefined) {
202306
+ market = this.market(symbol);
202307
+ symbol = market['symbol'];
202308
+ }
202309
+ [type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
202130
202310
  let subType = undefined;
202131
- [subType, params] = this.handleSubTypeAndParams('watchMyTrades', undefined, params);
202311
+ [subType, params] = this.handleSubTypeAndParams('watchMyTrades', market, params);
202132
202312
  if (this.isLinear(type, subType)) {
202133
202313
  type = 'future';
202134
202314
  }
@@ -202139,10 +202319,14 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
202139
202319
  if (symbol !== undefined) {
202140
202320
  symbol = this.symbol(symbol);
202141
202321
  messageHash += ':' + symbol;
202142
- params = this.extend(params, { 'symbol': symbol });
202322
+ params = this.extend(params, { 'type': market['type'], 'symbol': symbol });
202143
202323
  }
202144
202324
  await this.authenticate(params);
202145
- const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
202325
+ let urlType = type; // we don't change type because the listening key is different
202326
+ if (type === 'margin') {
202327
+ urlType = 'spot'; // spot-margin shares the same stream as regular spot
202328
+ }
202329
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
202146
202330
  const client = this.client(url);
202147
202331
  this.setBalanceCache(client, type);
202148
202332
  const message = undefined;
@@ -227524,13 +227708,13 @@ class huobi extends _huobi_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
227524
227708
  // }
227525
227709
  //
227526
227710
  const channel = this.safeString(message, 'ch');
227527
- const timestamp = this.safeInteger(message, 'ts');
227711
+ const data = this.safeValue(message, 'data', []);
227712
+ const timestamp = this.safeInteger(data, 'changeTime', this.safeInteger(message, 'ts'));
227528
227713
  this.balance['timestamp'] = timestamp;
227529
227714
  this.balance['datetime'] = this.iso8601(timestamp);
227530
- this.balance['info'] = this.safeValue(message, 'data');
227715
+ this.balance['info'] = data;
227531
227716
  if (channel !== undefined) {
227532
227717
  // spot balance
227533
- const data = this.safeValue(message, 'data', {});
227534
227718
  const currencyId = this.safeString(data, 'currency');
227535
227719
  const code = this.safeCurrencyCode(currencyId);
227536
227720
  const account = this.account();
@@ -227542,7 +227726,6 @@ class huobi extends _huobi_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
227542
227726
  }
227543
227727
  else {
227544
227728
  // contract balance
227545
- const data = this.safeValue(message, 'data', []);
227546
227729
  const dataLength = data.length;
227547
227730
  if (dataLength === 0) {
227548
227731
  return;
@@ -281615,7 +281798,7 @@ SOFTWARE.
281615
281798
 
281616
281799
  //-----------------------------------------------------------------------------
281617
281800
  // this is updated by vss.js when building
281618
- const version = '4.1.39';
281801
+ const version = '4.1.41';
281619
281802
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange.ccxtVersion */ .e.ccxtVersion = version;
281620
281803
  //-----------------------------------------------------------------------------
281621
281804