ccxt 4.2.21 → 4.2.22

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.
Files changed (56) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +352 -42
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/bigone.js +1 -0
  6. package/dist/cjs/src/binance.js +14 -3
  7. package/dist/cjs/src/bitget.js +11 -1
  8. package/dist/cjs/src/bitrue.js +1 -0
  9. package/dist/cjs/src/bybit.js +57 -9
  10. package/dist/cjs/src/coinbasepro.js +1 -0
  11. package/dist/cjs/src/coinex.js +37 -12
  12. package/dist/cjs/src/deribit.js +164 -0
  13. package/dist/cjs/src/okcoin.js +3 -0
  14. package/dist/cjs/src/phemex.js +5 -2
  15. package/dist/cjs/src/poloniex.js +1 -0
  16. package/dist/cjs/src/pro/bequant.js +6 -1
  17. package/dist/cjs/src/pro/binance.js +7 -4
  18. package/dist/cjs/src/pro/binancecoinm.js +6 -1
  19. package/dist/cjs/src/pro/binanceus.js +6 -1
  20. package/dist/cjs/src/pro/bitcoincom.js +6 -1
  21. package/dist/cjs/src/pro/bitget.js +1 -1
  22. package/dist/cjs/src/pro/bitrue.js +6 -1
  23. package/dist/cjs/src/pro/okx.js +13 -3
  24. package/dist/cjs/src/woo.js +1 -1
  25. package/js/ccxt.d.ts +1 -1
  26. package/js/ccxt.js +1 -1
  27. package/js/src/abstract/binance.d.ts +3 -0
  28. package/js/src/abstract/binancecoinm.d.ts +3 -0
  29. package/js/src/abstract/binanceus.d.ts +4 -0
  30. package/js/src/abstract/binanceusdm.d.ts +3 -0
  31. package/js/src/bigone.js +1 -0
  32. package/js/src/binance.js +14 -3
  33. package/js/src/bitget.js +11 -1
  34. package/js/src/bitrue.js +1 -0
  35. package/js/src/bybit.d.ts +2 -1
  36. package/js/src/bybit.js +57 -9
  37. package/js/src/coinbasepro.js +1 -0
  38. package/js/src/coinex.d.ts +1 -0
  39. package/js/src/coinex.js +37 -12
  40. package/js/src/deribit.d.ts +6 -1
  41. package/js/src/deribit.js +164 -0
  42. package/js/src/okcoin.js +3 -0
  43. package/js/src/phemex.js +5 -2
  44. package/js/src/poloniex.js +1 -0
  45. package/js/src/pro/bequant.js +6 -1
  46. package/js/src/pro/binance.js +7 -4
  47. package/js/src/pro/binancecoinm.js +6 -1
  48. package/js/src/pro/binanceus.js +6 -1
  49. package/js/src/pro/bitcoincom.js +6 -1
  50. package/js/src/pro/bitget.js +1 -1
  51. package/js/src/pro/bitrue.js +6 -1
  52. package/js/src/pro/okx.js +13 -3
  53. package/js/src/woo.js +1 -1
  54. package/jsdoc2md.js +38 -16
  55. package/package.json +4 -1
  56. package/skip-tests.json +4 -0
package/dist/cjs/ccxt.js CHANGED
@@ -174,7 +174,7 @@ var woo$1 = require('./src/pro/woo.js');
174
174
 
175
175
  //-----------------------------------------------------------------------------
176
176
  // this is updated by vss.js when building
177
- const version = '4.2.21';
177
+ const version = '4.2.22';
178
178
  Exchange["default"].ccxtVersion = version;
179
179
  const exchanges = {
180
180
  'ace': ace,
@@ -43,6 +43,7 @@ class bigone extends bigone$1 {
43
43
  'fetchCurrencies': true,
44
44
  'fetchDepositAddress': true,
45
45
  'fetchDeposits': true,
46
+ 'fetchFundingRate': false,
46
47
  'fetchMarkets': true,
47
48
  'fetchMyTrades': true,
48
49
  'fetchOHLCV': true,
@@ -308,6 +308,7 @@ class binance extends binance$1 {
308
308
  'convert/exchangeInfo': 50,
309
309
  'convert/assetInfo': 10,
310
310
  'convert/orderStatus': 0.6667,
311
+ 'convert/limit/queryOpenOrders': 20.001,
311
312
  'account/status': 0.1,
312
313
  'account/apiTradingStatus': 0.1,
313
314
  'account/apiRestrictions/ipRestriction': 0.1,
@@ -579,6 +580,8 @@ class binance extends binance$1 {
579
580
  'loan/vip/repay': 40.002,
580
581
  'convert/getQuote': 1.3334,
581
582
  'convert/acceptQuote': 3.3335,
583
+ 'convert/limit/placeOrder': 3.3335,
584
+ 'convert/limit/cancelOrder': 1.3334,
582
585
  'portfolio/auto-collection': 150,
583
586
  'portfolio/asset-collection': 6,
584
587
  'portfolio/bnb-transfer': 150,
@@ -7965,12 +7968,20 @@ class binance extends binance$1 {
7965
7968
  /**
7966
7969
  * @method
7967
7970
  * @name binance#fetchPositions
7971
+ * @see https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data
7972
+ * @see https://binance-docs.github.io/apidocs/delivery/en/#position-information-user_data
7973
+ * @see https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data
7974
+ * @see https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data
7975
+ * @see https://binance-docs.github.io/apidocs/voptions/en/#option-position-information-user_data
7968
7976
  * @description fetch all open positions
7969
- * @param {string[]|undefined} symbols list of unified market symbols
7977
+ * @param {string[]} [symbols] list of unified market symbols
7970
7978
  * @param {object} [params] extra parameters specific to the exchange API endpoint
7979
+ * @param {string} [method] method name to call, "positionRisk", "account" or "option", default is "positionRisk"
7971
7980
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
7972
7981
  */
7973
- const defaultMethod = this.safeString(this.options, 'fetchPositions', 'positionRisk');
7982
+ const defaultValue = this.safeString(this.options, 'fetchPositions', 'positionRisk');
7983
+ let defaultMethod = undefined;
7984
+ [defaultMethod, params] = this.handleOptionAndParams(params, 'fetchPositions', 'method', defaultValue);
7974
7985
  if (defaultMethod === 'positionRisk') {
7975
7986
  return await this.fetchPositionsRisk(symbols, params);
7976
7987
  }
@@ -7981,7 +7992,7 @@ class binance extends binance$1 {
7981
7992
  return await this.fetchOptionPositions(symbols, params);
7982
7993
  }
7983
7994
  else {
7984
- throw new errors.NotSupported(this.id + '.options["fetchPositions"] = "' + defaultMethod + '" is invalid, please choose between "account", "positionRisk" and "option"');
7995
+ throw new errors.NotSupported(this.id + '.options["fetchPositions"]/params["method"] = "' + defaultMethod + '" is invalid, please choose between "account", "positionRisk" and "option"');
7985
7996
  }
7986
7997
  }
7987
7998
  async fetchAccountPositions(symbols = undefined, params = {}) {
@@ -37,6 +37,7 @@ class bitget extends bitget$1 {
37
37
  'cancelOrders': true,
38
38
  'closeAllPositions': true,
39
39
  'closePosition': true,
40
+ 'createDepositAddress': false,
40
41
  'createMarketBuyOrderWithCost': true,
41
42
  'createMarketOrderWithCost': false,
42
43
  'createMarketSellOrderWithCost': false,
@@ -46,8 +47,13 @@ class bitget extends bitget$1 {
46
47
  'createReduceOnlyOrder': false,
47
48
  'createStopLossOrder': true,
48
49
  'createTakeProfitOrder': true,
50
+ 'createPostOnlyOrder': true,
51
+ 'createStopOrder': true,
52
+ 'createStopLimitOrder': true,
53
+ 'createStopMarketOrder': true,
49
54
  'createTrailingPercentOrder': true,
50
55
  'createTriggerOrder': true,
56
+ 'signIn': false,
51
57
  'editOrder': true,
52
58
  'fetchAccounts': false,
53
59
  'fetchBalance': true,
@@ -65,7 +71,10 @@ class bitget extends bitget$1 {
65
71
  'fetchDeposits': true,
66
72
  'fetchDepositWithdrawFee': 'emulated',
67
73
  'fetchDepositWithdrawFees': true,
74
+ 'fetchDepositsWithdrawals': false,
68
75
  'fetchFundingHistory': true,
76
+ 'fetchWithdrawAddresses': false,
77
+ 'fetchTransactions': false,
69
78
  'fetchFundingRate': true,
70
79
  'fetchFundingRateHistory': true,
71
80
  'fetchFundingRates': false,
@@ -76,7 +85,7 @@ class bitget extends bitget$1 {
76
85
  'fetchLeverage': true,
77
86
  'fetchLeverageTiers': false,
78
87
  'fetchLiquidations': false,
79
- 'fetchMarginMode': undefined,
88
+ 'fetchMarginMode': false,
80
89
  'fetchMarketLeverageTiers': true,
81
90
  'fetchMarkets': true,
82
91
  'fetchMarkOHLCV': true,
@@ -89,6 +98,7 @@ class bitget extends bitget$1 {
89
98
  'fetchOrder': true,
90
99
  'fetchOrderBook': true,
91
100
  'fetchOrders': false,
101
+ 'createTrailingAmountOrder': false,
92
102
  'fetchOrderTrades': false,
93
103
  'fetchPosition': true,
94
104
  'fetchPositionMode': false,
@@ -52,6 +52,7 @@ class bitrue extends bitrue$1 {
52
52
  'fetchDepositsWithdrawals': false,
53
53
  'fetchDepositWithdrawFee': 'emulated',
54
54
  'fetchDepositWithdrawFees': true,
55
+ 'fetchFundingRate': false,
55
56
  'fetchIsolatedBorrowRate': false,
56
57
  'fetchIsolatedBorrowRates': false,
57
58
  'fetchMarginMode': false,
@@ -38,7 +38,7 @@ class bybit extends bybit$1 {
38
38
  'closeAllPositions': false,
39
39
  'closePosition': false,
40
40
  'createMarketBuyOrderWithCost': true,
41
- 'createMarketSellOrderWithCost': false,
41
+ 'createMarketSellOrderWithCost': true,
42
42
  'createOrder': true,
43
43
  'createOrders': true,
44
44
  'createOrderWithTakeProfitAndStopLoss': true,
@@ -3468,8 +3468,30 @@ class bybit extends bybit$1 {
3468
3468
  if (!market['spot']) {
3469
3469
  throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
3470
3470
  }
3471
- params['createMarketBuyOrderRequiresPrice'] = false;
3472
- return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
3471
+ return await this.createOrder(symbol, 'market', 'buy', cost, 1, params);
3472
+ }
3473
+ async createMarketSellOrderWithCost(symbol, cost, params = {}) {
3474
+ /**
3475
+ * @method
3476
+ * @name bybit#createMarkeSellOrderWithCost
3477
+ * @see https://bybit-exchange.github.io/docs/v5/order/create-order
3478
+ * @description create a market sell order by providing the symbol and cost
3479
+ * @param {string} symbol unified symbol of the market to create an order in
3480
+ * @param {float} cost how much you want to trade in units of the quote currency
3481
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3482
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3483
+ */
3484
+ await this.loadMarkets();
3485
+ const types = await this.isUnifiedEnabled();
3486
+ const enableUnifiedAccount = types[1];
3487
+ if (!enableUnifiedAccount) {
3488
+ throw new errors.NotSupported(this.id + ' createMarketSellOrderWithCost() supports UTA accounts only');
3489
+ }
3490
+ const market = this.market(symbol);
3491
+ if (!market['spot']) {
3492
+ throw new errors.NotSupported(this.id + ' createMarketSellOrderWithCost() supports spot orders only');
3493
+ }
3494
+ return await this.createOrder(symbol, 'market', 'sell', cost, 1, params);
3473
3495
  }
3474
3496
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
3475
3497
  /**
@@ -3513,7 +3535,7 @@ class bybit extends bybit$1 {
3513
3535
  }
3514
3536
  const trailingAmount = this.safeString2(params, 'trailingAmount', 'trailingStop');
3515
3537
  const isTrailingAmountOrder = trailingAmount !== undefined;
3516
- const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
3538
+ const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params, enableUnifiedAccount);
3517
3539
  let response = undefined;
3518
3540
  if (isTrailingAmountOrder) {
3519
3541
  response = await this.privatePostV5PositionTradingStop(orderRequest);
@@ -3536,7 +3558,7 @@ class bybit extends bybit$1 {
3536
3558
  const order = this.safeValue(response, 'result', {});
3537
3559
  return this.parseOrder(order, market);
3538
3560
  }
3539
- createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
3561
+ createOrderRequest(symbol, type, side, amount, price = undefined, params = {}, isUTA = true) {
3540
3562
  const market = this.market(symbol);
3541
3563
  symbol = market['symbol'];
3542
3564
  const lowerCaseType = type.toLowerCase();
@@ -3580,12 +3602,36 @@ class bybit extends bybit$1 {
3580
3602
  else if (market['option']) {
3581
3603
  request['category'] = 'option';
3582
3604
  }
3583
- if (market['spot'] && (type === 'market') && (side === 'buy')) {
3605
+ const cost = this.safeString(params, 'cost');
3606
+ params = this.omit(params, 'cost');
3607
+ // if the cost is inferable, let's keep the old logic and ignore marketUnit, to minimize the impact of the changes
3608
+ const isMarketBuyAndCostInferable = (lowerCaseType === 'market') && (side === 'buy') && ((price !== undefined) || (cost !== undefined));
3609
+ if (market['spot'] && (type === 'market') && isUTA && !isMarketBuyAndCostInferable) {
3610
+ // UTA account can specify the cost of the order on both sides
3611
+ if ((cost !== undefined) || (price !== undefined)) {
3612
+ request['marketUnit'] = 'quoteCoin';
3613
+ let orderCost = undefined;
3614
+ if (cost !== undefined) {
3615
+ orderCost = cost;
3616
+ }
3617
+ else {
3618
+ const amountString = this.numberToString(amount);
3619
+ const priceString = this.numberToString(price);
3620
+ const quoteAmount = Precise["default"].stringMul(amountString, priceString);
3621
+ orderCost = quoteAmount;
3622
+ }
3623
+ request['qty'] = this.costToPrecision(symbol, orderCost);
3624
+ }
3625
+ else {
3626
+ request['marketUnit'] = 'baseCoin';
3627
+ request['qty'] = this.amountToPrecision(symbol, amount);
3628
+ }
3629
+ }
3630
+ else if (market['spot'] && (type === 'market') && (side === 'buy')) {
3631
+ // classic accounts
3584
3632
  // for market buy it requires the amount of quote currency to spend
3585
3633
  let createMarketBuyOrderRequiresPrice = true;
3586
3634
  [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
3587
- const cost = this.safeNumber(params, 'cost');
3588
- params = this.omit(params, 'cost');
3589
3635
  if (createMarketBuyOrderRequiresPrice) {
3590
3636
  if ((price === undefined) && (cost === undefined)) {
3591
3637
  throw new errors.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
@@ -3712,6 +3758,8 @@ class bybit extends bybit$1 {
3712
3758
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3713
3759
  */
3714
3760
  await this.loadMarkets();
3761
+ const accounts = await this.isUnifiedEnabled();
3762
+ const isUta = accounts[1];
3715
3763
  const ordersRequests = [];
3716
3764
  const orderSymbols = [];
3717
3765
  for (let i = 0; i < orders.length; i++) {
@@ -3723,7 +3771,7 @@ class bybit extends bybit$1 {
3723
3771
  const amount = this.safeValue(rawOrder, 'amount');
3724
3772
  const price = this.safeValue(rawOrder, 'price');
3725
3773
  const orderParams = this.safeValue(rawOrder, 'params', {});
3726
- const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
3774
+ const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams, isUta);
3727
3775
  ordersRequests.push(orderRequest);
3728
3776
  }
3729
3777
  const symbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
@@ -43,6 +43,7 @@ class coinbasepro extends coinbasepro$1 {
43
43
  'fetchDeposits': true,
44
44
  'fetchDepositsWithdrawals': true,
45
45
  'fetchLedger': true,
46
+ 'fetchFundingRate': false,
46
47
  'fetchMarginMode': false,
47
48
  'fetchMarkets': true,
48
49
  'fetchMyTrades': true,
@@ -1577,8 +1577,9 @@ class coinex extends coinex$1 {
1577
1577
  */
1578
1578
  let marketType = undefined;
1579
1579
  [marketType, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
1580
- const isMargin = this.safeValue(params, 'margin', false);
1581
- marketType = isMargin ? 'margin' : marketType;
1580
+ let marginMode = undefined;
1581
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
1582
+ marketType = (marginMode !== undefined) ? 'margin' : marketType;
1582
1583
  params = this.omit(params, 'margin');
1583
1584
  if (marketType === 'margin') {
1584
1585
  return await this.fetchMarginBalance(params);
@@ -2108,8 +2109,9 @@ class coinex extends coinex$1 {
2108
2109
  }
2109
2110
  }
2110
2111
  const accountId = this.safeInteger(params, 'account_id');
2111
- const defaultType = this.safeString(this.options, 'defaultType');
2112
- if (defaultType === 'margin') {
2112
+ let marginMode = undefined;
2113
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
2114
+ if (marginMode !== undefined) {
2113
2115
  if (accountId === undefined) {
2114
2116
  throw new errors.BadRequest(this.id + ' createOrder() requires an account_id parameter for margin orders');
2115
2117
  }
@@ -2628,9 +2630,10 @@ class coinex extends coinex$1 {
2628
2630
  'market': market['id'],
2629
2631
  };
2630
2632
  const accountId = this.safeInteger(params, 'account_id');
2631
- const defaultType = this.safeString(this.options, 'defaultType');
2633
+ let marginMode = undefined;
2634
+ [marginMode, params] = this.handleMarginModeAndParams('cancelOrder', params);
2632
2635
  const clientOrderId = this.safeString2(params, 'client_id', 'clientOrderId');
2633
- if (defaultType === 'margin') {
2636
+ if (marginMode !== undefined) {
2634
2637
  if (accountId === undefined) {
2635
2638
  throw new errors.BadRequest(this.id + ' cancelOrder() requires an account_id parameter for margin orders');
2636
2639
  }
@@ -3002,8 +3005,9 @@ class coinex extends coinex$1 {
3002
3005
  }
3003
3006
  const [marketType, query] = this.handleMarketTypeAndParams('fetchOrdersByStatus', market, params);
3004
3007
  const accountId = this.safeInteger(params, 'account_id');
3005
- const defaultType = this.safeString(this.options, 'defaultType');
3006
- if (defaultType === 'margin') {
3008
+ let marginMode = undefined;
3009
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrdersByStatus', params);
3010
+ if (marginMode !== undefined) {
3007
3011
  if (accountId === undefined) {
3008
3012
  throw new errors.BadRequest(this.id + ' fetchOpenOrders() and fetchClosedOrders() require an account_id parameter for margin orders');
3009
3013
  }
@@ -3406,8 +3410,9 @@ class coinex extends coinex$1 {
3406
3410
  }
3407
3411
  const swap = (type === 'swap');
3408
3412
  const accountId = this.safeInteger(params, 'account_id');
3409
- const defaultType = this.safeString(this.options, 'defaultType');
3410
- if (defaultType === 'margin') {
3413
+ let marginMode = undefined;
3414
+ [marginMode, params] = this.handleMarginModeAndParams('fetchMyTrades', params);
3415
+ if (marginMode !== undefined) {
3411
3416
  if (accountId === undefined) {
3412
3417
  throw new errors.BadRequest(this.id + ' fetchMyTrades() requires an account_id parameter for margin trades');
3413
3418
  }
@@ -4732,9 +4737,10 @@ class coinex extends coinex$1 {
4732
4737
  request['limit'] = 100;
4733
4738
  }
4734
4739
  params = this.omit(params, 'page');
4735
- const defaultType = this.safeString(this.options, 'defaultType');
4740
+ let marginMode = undefined;
4741
+ [marginMode, params] = this.handleMarginModeAndParams('fetchTransfers', params);
4736
4742
  let response = undefined;
4737
- if (defaultType === 'margin') {
4743
+ if (marginMode !== undefined) {
4738
4744
  response = await this.privateGetMarginTransferHistory(this.extend(request, params));
4739
4745
  }
4740
4746
  else {
@@ -5315,6 +5321,25 @@ class coinex extends coinex$1 {
5315
5321
  }
5316
5322
  return depositWithdrawFees;
5317
5323
  }
5324
+ handleMarginModeAndParams(methodName, params = {}, defaultValue = undefined) {
5325
+ /**
5326
+ * @ignore
5327
+ * @method
5328
+ * @description marginMode specified by params["marginMode"], this.options["marginMode"], this.options["defaultMarginMode"], params["margin"] = true or this.options["defaultType"] = 'margin'
5329
+ * @param {object} params extra parameters specific to the exchange api endpoint
5330
+ * @returns {Array} the marginMode in lowercase
5331
+ */
5332
+ const defaultType = this.safeString(this.options, 'defaultType');
5333
+ const isMargin = this.safeValue(params, 'margin', false);
5334
+ let marginMode = undefined;
5335
+ [marginMode, params] = super.handleMarginModeAndParams(methodName, params, defaultValue);
5336
+ if (marginMode === undefined) {
5337
+ if ((defaultType === 'margin') || (isMargin === true)) {
5338
+ marginMode = 'isolated';
5339
+ }
5340
+ }
5341
+ return [marginMode, params];
5342
+ }
5318
5343
  nonce() {
5319
5344
  return this.milliseconds();
5320
5345
  }
@@ -402,6 +402,170 @@ class deribit extends deribit$1 {
402
402
  },
403
403
  });
404
404
  }
405
+ convertExpireDate(date) {
406
+ // parse YYMMDD to timestamp
407
+ const year = date.slice(0, 2);
408
+ const month = date.slice(2, 4);
409
+ const day = date.slice(4, 6);
410
+ const reconstructedDate = '20' + year + '-' + month + '-' + day + 'T00:00:00Z';
411
+ return reconstructedDate;
412
+ }
413
+ convertMarketIdExpireDate(date) {
414
+ // parse 19JAN24 to 240119
415
+ const monthMappping = {
416
+ 'JAN': '01',
417
+ 'FEB': '02',
418
+ 'MAR': '03',
419
+ 'APR': '04',
420
+ 'MAY': '05',
421
+ 'JUN': '06',
422
+ 'JUL': '07',
423
+ 'AUG': '08',
424
+ 'SEP': '09',
425
+ 'OCT': '10',
426
+ 'NOV': '11',
427
+ 'DEC': '12',
428
+ };
429
+ const year = date.slice(0, 2);
430
+ const monthName = date.slice(2, 5);
431
+ const month = this.safeString(monthMappping, monthName);
432
+ const day = date.slice(5, 7);
433
+ const reconstructedDate = day + month + year;
434
+ return reconstructedDate;
435
+ }
436
+ convertExpireDateToMarketIdDate(date) {
437
+ // parse 240119 to 19JAN24
438
+ const year = date.slice(0, 2);
439
+ const monthRaw = date.slice(2, 4);
440
+ let month = undefined;
441
+ const day = date.slice(4, 6);
442
+ if (monthRaw === '01') {
443
+ month = 'JAN';
444
+ }
445
+ else if (monthRaw === '02') {
446
+ month = 'FEB';
447
+ }
448
+ else if (monthRaw === '03') {
449
+ month = 'MAR';
450
+ }
451
+ else if (monthRaw === '04') {
452
+ month = 'APR';
453
+ }
454
+ else if (monthRaw === '05') {
455
+ month = 'MAY';
456
+ }
457
+ else if (monthRaw === '06') {
458
+ month = 'JUN';
459
+ }
460
+ else if (monthRaw === '07') {
461
+ month = 'JUL';
462
+ }
463
+ else if (monthRaw === '08') {
464
+ month = 'AUG';
465
+ }
466
+ else if (monthRaw === '09') {
467
+ month = 'SEP';
468
+ }
469
+ else if (monthRaw === '10') {
470
+ month = 'OCT';
471
+ }
472
+ else if (monthRaw === '11') {
473
+ month = 'NOV';
474
+ }
475
+ else if (monthRaw === '12') {
476
+ month = 'DEC';
477
+ }
478
+ const reconstructedDate = day + month + year;
479
+ return reconstructedDate;
480
+ }
481
+ createExpiredOptionMarket(symbol) {
482
+ // support expired option contracts
483
+ let quote = 'USD';
484
+ let settle = undefined;
485
+ const optionParts = symbol.split('-');
486
+ const symbolBase = symbol.split('/');
487
+ let base = undefined;
488
+ let expiry = undefined;
489
+ if (symbol.indexOf('/') > -1) {
490
+ base = this.safeString(symbolBase, 0);
491
+ expiry = this.safeString(optionParts, 1);
492
+ if (symbol.indexOf('USDC') > -1) {
493
+ base = base + '_USDC';
494
+ }
495
+ }
496
+ else {
497
+ base = this.safeString(optionParts, 0);
498
+ expiry = this.convertMarketIdExpireDate(this.safeString(optionParts, 1));
499
+ }
500
+ if (symbol.indexOf('USDC') > -1) {
501
+ quote = 'USDC';
502
+ settle = 'USDC';
503
+ }
504
+ else {
505
+ settle = base;
506
+ }
507
+ let splitBase = base;
508
+ if (base.indexOf('_') > -1) {
509
+ const splitSymbol = base.split('_');
510
+ splitBase = this.safeString(splitSymbol, 0);
511
+ }
512
+ const strike = this.safeString(optionParts, 2);
513
+ const optionType = this.safeString(optionParts, 3);
514
+ const datetime = this.convertExpireDate(expiry);
515
+ const timestamp = this.parse8601(datetime);
516
+ return {
517
+ 'id': base + '-' + this.convertExpireDateToMarketIdDate(expiry) + '-' + strike + '-' + optionType,
518
+ 'symbol': splitBase + '/' + quote + ':' + settle + '-' + expiry + '-' + strike + '-' + optionType,
519
+ 'base': base,
520
+ 'quote': quote,
521
+ 'settle': settle,
522
+ 'baseId': base,
523
+ 'quoteId': quote,
524
+ 'settleId': settle,
525
+ 'active': false,
526
+ 'type': 'option',
527
+ 'linear': undefined,
528
+ 'inverse': undefined,
529
+ 'spot': false,
530
+ 'swap': false,
531
+ 'future': false,
532
+ 'option': true,
533
+ 'margin': false,
534
+ 'contract': true,
535
+ 'contractSize': undefined,
536
+ 'expiry': timestamp,
537
+ 'expiryDatetime': datetime,
538
+ 'optionType': (optionType === 'C') ? 'call' : 'put',
539
+ 'strike': this.parseNumber(strike),
540
+ 'precision': {
541
+ 'amount': undefined,
542
+ 'price': undefined,
543
+ },
544
+ 'limits': {
545
+ 'amount': {
546
+ 'min': undefined,
547
+ 'max': undefined,
548
+ },
549
+ 'price': {
550
+ 'min': undefined,
551
+ 'max': undefined,
552
+ },
553
+ 'cost': {
554
+ 'min': undefined,
555
+ 'max': undefined,
556
+ },
557
+ },
558
+ 'info': undefined,
559
+ };
560
+ }
561
+ safeMarket(marketId = undefined, market = undefined, delimiter = undefined, marketType = undefined) {
562
+ const isOption = (marketId !== undefined) && ((marketId.endsWith('-C')) || (marketId.endsWith('-P')));
563
+ if (isOption && !(marketId in this.markets_by_id)) {
564
+ // handle expired option contracts
565
+ return this.createExpiredOptionMarket(marketId);
566
+ }
567
+ return super.safeMarket(marketId, market, delimiter, marketType);
568
+ }
405
569
  async fetchTime(params = {}) {
406
570
  /**
407
571
  * @method
@@ -46,6 +46,9 @@ class okcoin extends okcoin$1 {
46
46
  'fetchCurrencies': true,
47
47
  'fetchDepositAddress': true,
48
48
  'fetchDeposits': true,
49
+ 'fetchFundingHistory': false,
50
+ 'fetchFundingRate': false,
51
+ 'fetchFundingRateHistory': false,
49
52
  'fetchLedger': true,
50
53
  'fetchMarkets': true,
51
54
  'fetchMyTrades': true,
@@ -1915,16 +1915,19 @@ class phemex extends phemex$1 {
1915
1915
  * @method
1916
1916
  * @name phemex#fetchBalance
1917
1917
  * @description query for balance and get the amount of funds available for trading or funds locked in orders
1918
+ * @see https://phemex-docs.github.io/#query-wallets
1918
1919
  * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions
1920
+ * @see https://phemex-docs.github.io/#query-trading-account-and-positions
1919
1921
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1920
1922
  * @param {string} [params.type] spot or swap
1923
+ * @param {string} [params.code] *swap only* currency code of the balance to query (USD, USDT, etc), default is USDT
1921
1924
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1922
1925
  */
1923
1926
  await this.loadMarkets();
1924
1927
  let type = undefined;
1925
1928
  [type, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
1926
1929
  const code = this.safeString(params, 'code');
1927
- params = this.omit(params, ['type', 'code']);
1930
+ params = this.omit(params, ['code']);
1928
1931
  let response = undefined;
1929
1932
  const request = {};
1930
1933
  if ((type !== 'spot') && (type !== 'swap')) {
@@ -1932,7 +1935,7 @@ class phemex extends phemex$1 {
1932
1935
  }
1933
1936
  if (type === 'swap') {
1934
1937
  let settle = undefined;
1935
- [settle, params] = this.handleOptionAndParams(params, 'fetchBalance', 'settle');
1938
+ [settle, params] = this.handleOptionAndParams(params, 'fetchBalance', 'settle', 'USDT');
1936
1939
  if (code !== undefined || settle !== undefined) {
1937
1940
  let coin = undefined;
1938
1941
  if (code !== undefined) {
@@ -55,6 +55,7 @@ class poloniex extends poloniex$1 {
55
55
  'fetchOrder': true,
56
56
  'fetchOrderBook': true,
57
57
  'fetchOrderBooks': false,
58
+ 'fetchFundingRate': false,
58
59
  'fetchOrderTrades': true,
59
60
  'fetchPosition': false,
60
61
  'fetchPositionMode': false,
@@ -1,12 +1,17 @@
1
1
  'use strict';
2
2
 
3
3
  var hitbtc = require('./hitbtc.js');
4
+ var bequant$1 = require('../bequant.js');
4
5
 
5
6
  // ---------------------------------------------------------------------------
6
7
  // ---------------------------------------------------------------------------
7
8
  class bequant extends hitbtc {
8
9
  describe() {
9
- return this.deepExtend(super.describe(), {
10
+ // eslint-disable-next-line new-cap
11
+ const restInstance = new bequant$1();
12
+ const restDescribe = restInstance.describe();
13
+ const extended = this.deepExtend(super.describe(), restDescribe);
14
+ return this.deepExtend(extended, {
10
15
  'id': 'bequant',
11
16
  'name': 'Bequant',
12
17
  'countries': ['MT'],
@@ -44,7 +44,7 @@ class binance extends binance$1 {
44
44
  'ws': {
45
45
  'spot': 'wss://testnet.binance.vision/ws',
46
46
  'margin': 'wss://testnet.binance.vision/ws',
47
- 'future': 'wss://stream.binancefuture.com/ws',
47
+ 'future': 'wss://fstream.binancefuture.com/ws',
48
48
  'delivery': 'wss://dstream.binancefuture.com/ws',
49
49
  'ws': 'wss://testnet.binance.vision/ws-api/v3',
50
50
  },
@@ -1977,12 +1977,13 @@ class binance extends binance$1 {
1977
1977
  /**
1978
1978
  * @method
1979
1979
  * @name binance#watchOrders
1980
- * @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
1981
1980
  * @description watches information on multiple orders made by the user
1982
- * @param {string} symbol unified market symbol of the market orders were made in
1981
+ * @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
1982
+ * @param {string} symbol unified market symbol of the market the orders were made in
1983
1983
  * @param {int} [since] the earliest time in ms to fetch orders for
1984
1984
  * @param {int} [limit] the maximum number of order structures to retrieve
1985
1985
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1986
+ * @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for spot margin
1986
1987
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1987
1988
  */
1988
1989
  await this.loadMarkets();
@@ -2005,8 +2006,10 @@ class binance extends binance$1 {
2005
2006
  }
2006
2007
  params = this.extend(params, { 'type': type, 'symbol': symbol }); // needed inside authenticate for isolated margin
2007
2008
  await this.authenticate(params);
2009
+ let marginMode = undefined;
2010
+ [marginMode, params] = this.handleMarginModeAndParams('watchOrders', params);
2008
2011
  let urlType = type;
2009
- if (type === 'margin') {
2012
+ if ((type === 'margin') || ((type === 'spot') && (marginMode !== undefined))) {
2010
2013
  urlType = 'spot'; // spot-margin shares the same stream as regular spot
2011
2014
  }
2012
2015
  const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
@@ -1,12 +1,17 @@
1
1
  'use strict';
2
2
 
3
3
  var binance = require('./binance.js');
4
+ var binancecoinm$1 = require('../binancecoinm.js');
4
5
 
5
6
  // ---------------------------------------------------------------------------
6
7
  // ---------------------------------------------------------------------------
7
8
  class binancecoinm extends binance {
8
9
  describe() {
9
- return this.deepExtend(super.describe(), {
10
+ // eslint-disable-next-line new-cap
11
+ const restInstance = new binancecoinm$1();
12
+ const restDescribe = restInstance.describe();
13
+ const extended = this.deepExtend(super.describe(), restDescribe);
14
+ return this.deepExtend(extended, {
10
15
  'id': 'binancecoinm',
11
16
  'name': 'Binance COIN-M',
12
17
  'urls': {