ccxt 4.1.88 → 4.1.90

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 (63) hide show
  1. package/CHANGELOG.md +8309 -5710
  2. package/README.md +3 -3
  3. package/changelog.js +101 -0
  4. package/dist/ccxt.browser.js +963 -387
  5. package/dist/ccxt.browser.min.js +3 -3
  6. package/dist/cjs/ccxt.js +1 -1
  7. package/dist/cjs/src/base/Exchange.js +2 -2
  8. package/dist/cjs/src/bigone.js +8 -1
  9. package/dist/cjs/src/bitforex.js +2 -0
  10. package/dist/cjs/src/bitget.js +11 -4
  11. package/dist/cjs/src/bitmex.js +2 -0
  12. package/dist/cjs/src/blockchaincom.js +0 -41
  13. package/dist/cjs/src/bybit.js +29 -14
  14. package/dist/cjs/src/coinex.js +14 -1
  15. package/dist/cjs/src/coinlist.js +2 -0
  16. package/dist/cjs/src/coinsph.js +2 -0
  17. package/dist/cjs/src/cryptocom.js +2 -0
  18. package/dist/cjs/src/gate.js +276 -11
  19. package/dist/cjs/src/htx.js +264 -219
  20. package/dist/cjs/src/kuna.js +2 -0
  21. package/dist/cjs/src/mexc.js +2 -0
  22. package/dist/cjs/src/okcoin.js +61 -17
  23. package/dist/cjs/src/phemex.js +159 -30
  24. package/dist/cjs/src/poloniex.js +28 -2
  25. package/dist/cjs/src/pro/binance.js +6 -6
  26. package/dist/cjs/src/pro/poloniex.js +15 -10
  27. package/dist/cjs/src/tokocrypto.js +30 -14
  28. package/dist/cjs/src/wazirx.js +2 -0
  29. package/dist/cjs/src/whitebit.js +2 -0
  30. package/dist/cjs/src/woo.js +41 -14
  31. package/js/ccxt.d.ts +1 -1
  32. package/js/ccxt.js +1 -1
  33. package/js/src/abstract/phemex.d.ts +1 -0
  34. package/js/src/base/Exchange.js +2 -2
  35. package/js/src/bigone.js +9 -2
  36. package/js/src/bitforex.js +2 -0
  37. package/js/src/bitget.js +11 -4
  38. package/js/src/bitmex.js +2 -0
  39. package/js/src/blockchaincom.d.ts +0 -2
  40. package/js/src/blockchaincom.js +0 -41
  41. package/js/src/bybit.js +29 -14
  42. package/js/src/coinex.js +14 -1
  43. package/js/src/coinlist.js +2 -0
  44. package/js/src/coinsph.js +2 -0
  45. package/js/src/cryptocom.js +2 -0
  46. package/js/src/gate.d.ts +47 -0
  47. package/js/src/gate.js +276 -11
  48. package/js/src/htx.js +264 -219
  49. package/js/src/kuna.js +2 -0
  50. package/js/src/mexc.js +2 -0
  51. package/js/src/okcoin.d.ts +1 -0
  52. package/js/src/okcoin.js +62 -18
  53. package/js/src/phemex.d.ts +3 -108
  54. package/js/src/phemex.js +159 -30
  55. package/js/src/poloniex.js +28 -2
  56. package/js/src/pro/binance.js +6 -6
  57. package/js/src/pro/poloniex.js +16 -11
  58. package/js/src/tokocrypto.js +30 -14
  59. package/js/src/wazirx.js +2 -0
  60. package/js/src/whitebit.js +2 -0
  61. package/js/src/woo.d.ts +1 -0
  62. package/js/src/woo.js +42 -15
  63. package/package.json +2 -2
@@ -94,6 +94,8 @@ class kuna extends kuna$1 {
94
94
  'fetchWithdrawal': true,
95
95
  'fetchWithdrawals': true,
96
96
  'reduceMargin': false,
97
+ 'repayCrossMargin': false,
98
+ 'repayIsolatedMargin': false,
97
99
  'setLeverage': false,
98
100
  'setMargin': false,
99
101
  'setMarginMode': false,
@@ -106,6 +106,8 @@ class mexc extends mexc$1 {
106
106
  'fetchWithdrawal': undefined,
107
107
  'fetchWithdrawals': true,
108
108
  'reduceMargin': true,
109
+ 'repayCrossMargin': false,
110
+ 'repayIsolatedMargin': false,
109
111
  'setLeverage': true,
110
112
  'setMarginMode': undefined,
111
113
  'setPositionMode': true,
@@ -31,8 +31,17 @@ class okcoin extends okcoin$1 {
31
31
  'future': true,
32
32
  'option': undefined,
33
33
  'cancelOrder': true,
34
+ 'createMarketBuyOrderWithCost': true,
35
+ 'createMarketOrderWithCost': false,
36
+ 'createMarketSellOrderWithCost': false,
34
37
  'createOrder': true,
35
38
  'fetchBalance': true,
39
+ 'fetchBorrowInterest': false,
40
+ 'fetchBorrowRate': false,
41
+ 'fetchBorrowRateHistories': false,
42
+ 'fetchBorrowRateHistory': false,
43
+ 'fetchBorrowRates': false,
44
+ 'fetchBorrowRatesPerSymbol': false,
36
45
  'fetchClosedOrders': true,
37
46
  'fetchCurrencies': true,
38
47
  'fetchDepositAddress': true,
@@ -54,6 +63,10 @@ class okcoin extends okcoin$1 {
54
63
  'fetchTrades': true,
55
64
  'fetchTransactions': undefined,
56
65
  'fetchWithdrawals': true,
66
+ 'reduceMargin': false,
67
+ 'repayCrossMargin': false,
68
+ 'repayIsolatedMargin': false,
69
+ 'setMargin': false,
57
70
  'transfer': true,
58
71
  'withdraw': true,
59
72
  },
@@ -1253,6 +1266,26 @@ class okcoin extends okcoin$1 {
1253
1266
  }
1254
1267
  return this.safeBalance(result);
1255
1268
  }
1269
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1270
+ /**
1271
+ * @method
1272
+ * @name okcoin#createMarketBuyOrderWithCost
1273
+ * @description create a market buy order by providing the symbol and cost
1274
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-order
1275
+ * @param {string} symbol unified symbol of the market to create an order in
1276
+ * @param {float} cost how much you want to trade in units of the quote currency
1277
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1278
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1279
+ */
1280
+ await this.loadMarkets();
1281
+ const market = this.market(symbol);
1282
+ if (!market['spot']) {
1283
+ throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
1284
+ }
1285
+ params['createMarketBuyOrderRequiresPrice'] = false;
1286
+ params['tgtCcy'] = 'quote_ccy';
1287
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
1288
+ }
1256
1289
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1257
1290
  /**
1258
1291
  * @method
@@ -1279,6 +1312,7 @@ class okcoin extends okcoin$1 {
1279
1312
  * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
1280
1313
  * @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders
1281
1314
  * @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type
1315
+ * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
1282
1316
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1283
1317
  */
1284
1318
  await this.loadMarkets();
@@ -1327,7 +1361,7 @@ class okcoin extends okcoin$1 {
1327
1361
  'ordType': type,
1328
1362
  // 'ordType': type, // privatePostTradeOrder: market, limit, post_only, fok, ioc, optimal_limit_ioc
1329
1363
  // 'ordType': type, // privatePostTradeOrderAlgo: conditional, oco, trigger, move_order_stop, iceberg, twap
1330
- 'sz': this.amountToPrecision(symbol, amount),
1364
+ // 'sz': this.amountToPrecision (symbol, amount),
1331
1365
  // 'px': this.priceToPrecision (symbol, price), // limit orders only
1332
1366
  // 'reduceOnly': false,
1333
1367
  //
@@ -1389,35 +1423,45 @@ class okcoin extends okcoin$1 {
1389
1423
  }
1390
1424
  if (isMarketOrder || marketIOC) {
1391
1425
  request['ordType'] = 'market';
1392
- if ((side === 'buy')) {
1426
+ if (side === 'buy') {
1393
1427
  // spot market buy: "sz" can refer either to base currency units or to quote currency units
1394
1428
  // see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order
1395
1429
  if (tgtCcy === 'quote_ccy') {
1396
1430
  // quote_ccy: sz refers to units of quote currency
1397
- let notional = this.safeNumber2(params, 'cost', 'sz');
1398
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
1399
- if (createMarketBuyOrderRequiresPrice) {
1400
- if (price !== undefined) {
1401
- if (notional === undefined) {
1402
- const amountString = this.numberToString(amount);
1403
- const priceString = this.numberToString(price);
1404
- const quoteAmount = Precise["default"].stringMul(amountString, priceString);
1405
- notional = this.parseNumber(quoteAmount);
1406
- }
1431
+ let quoteAmount = undefined;
1432
+ let createMarketBuyOrderRequiresPrice = true;
1433
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1434
+ const cost = this.safeNumber2(params, 'cost', 'sz');
1435
+ params = this.omit(params, ['cost', 'sz']);
1436
+ if (cost !== undefined) {
1437
+ quoteAmount = this.costToPrecision(symbol, cost);
1438
+ }
1439
+ else if (createMarketBuyOrderRequiresPrice) {
1440
+ if (price === undefined) {
1441
+ 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 (quote quantity) in the amount argument');
1407
1442
  }
1408
- else if (notional === undefined) {
1409
- throw new errors.InvalidOrder(this.id + " createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false and supply the total cost value in the 'amount' argument or in the 'cost' unified extra parameter or in exchange-specific 'sz' extra parameter (the exchange-specific behaviour)");
1443
+ else {
1444
+ const amountString = this.numberToString(amount);
1445
+ const priceString = this.numberToString(price);
1446
+ const costRequest = Precise["default"].stringMul(amountString, priceString);
1447
+ quoteAmount = this.costToPrecision(symbol, costRequest);
1410
1448
  }
1411
1449
  }
1412
1450
  else {
1413
- notional = (notional === undefined) ? amount : notional;
1451
+ quoteAmount = this.costToPrecision(symbol, amount);
1414
1452
  }
1415
- request['sz'] = this.costToPrecision(symbol, notional);
1416
- params = this.omit(params, ['cost', 'sz']);
1453
+ request['sz'] = quoteAmount;
1417
1454
  }
1455
+ else {
1456
+ request['sz'] = this.amountToPrecision(symbol, amount);
1457
+ }
1458
+ }
1459
+ else {
1460
+ request['sz'] = this.amountToPrecision(symbol, amount);
1418
1461
  }
1419
1462
  }
1420
1463
  else {
1464
+ request['sz'] = this.amountToPrecision(symbol, amount);
1421
1465
  if ((!trigger) && (!conditional)) {
1422
1466
  request['px'] = this.priceToPrecision(symbol, price);
1423
1467
  }
@@ -83,7 +83,7 @@ class phemex extends phemex$1 {
83
83
  'setMarginMode': true,
84
84
  'setPositionMode': true,
85
85
  'transfer': true,
86
- 'withdraw': undefined,
86
+ 'withdraw': true,
87
87
  },
88
88
  'urls': {
89
89
  'logo': 'https://user-images.githubusercontent.com/1294454/85225056-221eb600-b3d7-11ea-930d-564d2690e3f6.jpg',
@@ -157,6 +157,7 @@ class phemex extends phemex$1 {
157
157
  },
158
158
  'v2': {
159
159
  'get': {
160
+ 'public/products': 5,
160
161
  'md/v2/orderbook': 5,
161
162
  'md/v2/trade': 5,
162
163
  'md/v2/ticker/24hr': 5,
@@ -221,6 +222,7 @@ class phemex extends phemex$1 {
221
222
  'assets/spots/sub-accounts/transfer': 5,
222
223
  'assets/futures/sub-accounts/transfer': 5,
223
224
  'assets/quote': 5, // ?fromCurrency=<currency>&toCurrency=<currency>&amountEv=<amount>
225
+ // deposit/withdraw
224
226
  },
225
227
  'post': {
226
228
  // spot
@@ -464,6 +466,16 @@ class phemex extends phemex$1 {
464
466
  'spot': 'spot',
465
467
  'swap': 'future',
466
468
  },
469
+ 'stableCoins': [
470
+ 'BUSD',
471
+ 'FEI',
472
+ 'TUSD',
473
+ 'USD',
474
+ 'USDC',
475
+ 'USDD',
476
+ 'USDP',
477
+ 'USDT',
478
+ ],
467
479
  'transfer': {
468
480
  'fillResponseFromRequest': true,
469
481
  },
@@ -483,6 +495,8 @@ class phemex extends phemex$1 {
483
495
  //
484
496
  // {
485
497
  // "symbol":"BTCUSD",
498
+ // "code":"1",
499
+ // "type":"Perpetual",
486
500
  // "displaySymbol":"BTC / USD",
487
501
  // "indexSymbol":".BTC",
488
502
  // "markSymbol":".MBTC",
@@ -500,9 +514,10 @@ class phemex extends phemex$1 {
500
514
  // "minPriceEp":5000,
501
515
  // "maxPriceEp":10000000000,
502
516
  // "maxOrderQty":1000000,
503
- // "type":"Perpetual",
504
517
  // "status":"Listed",
505
518
  // "tipOrderQty":1000000,
519
+ // "listTime":"1574650800000",
520
+ // "majorSymbol":true,
506
521
  // "steps":"50",
507
522
  // "riskLimits":[
508
523
  // {"limit":100,"initialMargin":"1.0%","initialMarginEr":1000000,"maintenanceMargin":"0.5%","maintenanceMarginEr":500000},
@@ -560,7 +575,7 @@ class phemex extends phemex$1 {
560
575
  // "1.0"
561
576
  contractSize = this.parseNumber(contractSizeString);
562
577
  }
563
- return {
578
+ return this.safeMarketStructure({
564
579
  'id': id,
565
580
  'symbol': base + '/' + quote + ':' + settle,
566
581
  'base': base,
@@ -613,24 +628,26 @@ class phemex extends phemex$1 {
613
628
  },
614
629
  'created': undefined,
615
630
  'info': market,
616
- };
631
+ });
617
632
  }
618
633
  parseSpotMarket(market) {
619
634
  //
620
635
  // {
621
636
  // "symbol":"sBTCUSDT",
622
637
  // "code":1001,
638
+ // "type":"Spot",
623
639
  // "displaySymbol":"BTC / USDT",
624
640
  // "quoteCurrency":"USDT",
625
641
  // "priceScale":8,
626
642
  // "ratioScale":8,
627
643
  // "pricePrecision":2,
628
- // "type":"Spot",
629
644
  // "baseCurrency":"BTC",
630
645
  // "baseTickSize":"0.000001 BTC",
631
646
  // "baseTickSizeEv":100,
632
647
  // "quoteTickSize":"0.01 USDT",
633
648
  // "quoteTickSizeEv":1000000,
649
+ // "baseQtyPrecision":6,
650
+ // "quoteQtyPrecision":2,
634
651
  // "minOrderValue":"10 USDT",
635
652
  // "minOrderValueEv":1000000000,
636
653
  // "maxBaseOrderSize":"1000 BTC",
@@ -641,13 +658,13 @@ class phemex extends phemex$1 {
641
658
  // "defaultTakerFeeEr":100000,
642
659
  // "defaultMakerFee":"0.001",
643
660
  // "defaultMakerFeeEr":100000,
644
- // "baseQtyPrecision":6,
645
- // "quoteQtyPrecision":2,
661
+ // "description":"BTCUSDT is a BTC/USDT spot trading pair. Minimum order value is 1 USDT",
646
662
  // "status":"Listed",
647
663
  // "tipOrderQty":2,
648
- // "description":"BTCUSDT is a BTC/USDT spot trading pair. Minimum order value is 1 USDT",
664
+ // "listTime":1589338800000,
665
+ // "buyPriceUpperLimitPct":110,
666
+ // "sellPriceLowerLimitPct":90,
649
667
  // "leverage":5
650
- // "valueScale":8,
651
668
  // },
652
669
  //
653
670
  const type = this.safeStringLower(market, 'type');
@@ -659,7 +676,7 @@ class phemex extends phemex$1 {
659
676
  const status = this.safeString(market, 'status');
660
677
  const precisionAmount = this.parseSafeNumber(this.safeString(market, 'baseTickSize'));
661
678
  const precisionPrice = this.parseSafeNumber(this.safeString(market, 'quoteTickSize'));
662
- return {
679
+ return this.safeMarketStructure({
663
680
  'id': id,
664
681
  'symbol': base + '/' + quote,
665
682
  'base': base,
@@ -712,7 +729,7 @@ class phemex extends phemex$1 {
712
729
  },
713
730
  'created': undefined,
714
731
  'info': market,
715
- };
732
+ });
716
733
  }
717
734
  async fetchMarkets(params = {}) {
718
735
  /**
@@ -722,21 +739,22 @@ class phemex extends phemex$1 {
722
739
  * @param {object} [params] extra parameters specific to the exchange API endpoint
723
740
  * @returns {object[]} an array of objects representing market data
724
741
  */
725
- const v2Products = await this.publicGetCfgV2Products(params);
742
+ const v2Products = await this.v2GetPublicProducts(params);
726
743
  //
727
744
  // {
728
745
  // "code":0,
729
- // "msg":"OK",
746
+ // "msg":"",
730
747
  // "data":{
731
- // "ratioScale":8,
732
748
  // "currencies":[
733
- // {"code":1,"currency":"BTC","valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"name":"Bitcoin"},
734
- // {"code":2,"currency":"USD","valueScale":4,"minValueEv":1,"maxValueEv":500000000000000,"name":"USD"},
735
- // {"code":3,"currency":"USDT","valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"name":"TetherUS"},
749
+ // {"currency":"BTC","name":"Bitcoin","code":1,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"BTC","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":8},
750
+ // {"currency":"USD","name":"USD","code":2,"valueScale":4,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USD","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":2},
751
+ // {"currency":"USDT","name":"TetherUS","code":3,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USDT","inAssetsDisplay":1,"perpetual":2,"stableCoin":1,"assetsPrecision":8},
736
752
  // ],
737
753
  // "products":[
738
754
  // {
739
755
  // "symbol":"BTCUSD",
756
+ // "code":1,
757
+ // "type":"Perpetual"
740
758
  // "displaySymbol":"BTC / USD",
741
759
  // "indexSymbol":".BTC",
742
760
  // "markSymbol":".MBTC",
@@ -754,22 +772,31 @@ class phemex extends phemex$1 {
754
772
  // "minPriceEp":5000,
755
773
  // "maxPriceEp":10000000000,
756
774
  // "maxOrderQty":1000000,
757
- // "type":"Perpetual"
775
+ // "description":"BTC/USD perpetual contracts are priced on the .BTC Index. Each contract is worth 1 USD. Funding fees are paid and received every 8 hours at UTC time: 00:00, 08:00 and 16:00.",
776
+ // "status":"Listed",
777
+ // "tipOrderQty":1000000,
778
+ // "listTime":1574650800000,
779
+ // "majorSymbol":true,
780
+ // "defaultLeverage":"-10",
781
+ // "fundingInterval":28800,
782
+ // "maxLeverage":100
758
783
  // },
759
784
  // {
760
785
  // "symbol":"sBTCUSDT",
761
786
  // "code":1001,
787
+ // "type":"Spot",
762
788
  // "displaySymbol":"BTC / USDT",
763
789
  // "quoteCurrency":"USDT",
764
790
  // "priceScale":8,
765
791
  // "ratioScale":8,
766
792
  // "pricePrecision":2,
767
- // "type":"Spot",
768
793
  // "baseCurrency":"BTC",
769
794
  // "baseTickSize":"0.000001 BTC",
770
795
  // "baseTickSizeEv":100,
771
796
  // "quoteTickSize":"0.01 USDT",
772
797
  // "quoteTickSizeEv":1000000,
798
+ // "baseQtyPrecision":6,
799
+ // "quoteQtyPrecision":2,
773
800
  // "minOrderValue":"10 USDT",
774
801
  // "minOrderValueEv":1000000000,
775
802
  // "maxBaseOrderSize":"1000 BTC",
@@ -780,14 +807,51 @@ class phemex extends phemex$1 {
780
807
  // "defaultTakerFeeEr":100000,
781
808
  // "defaultMakerFee":"0.001",
782
809
  // "defaultMakerFeeEr":100000,
783
- // "baseQtyPrecision":6,
784
- // "quoteQtyPrecision":2,
810
+ // "description":"BTCUSDT is a BTC/USDT spot trading pair. Minimum order value is 1 USDT",
785
811
  // "status":"Listed",
786
812
  // "tipOrderQty":2,
787
- // "description":"BTCUSDT is a BTC/USDT spot trading pair. Minimum order value is 1 USDT",
813
+ // "listTime":1589338800000,
814
+ // "buyPriceUpperLimitPct":110,
815
+ // "sellPriceLowerLimitPct":90,
788
816
  // "leverage":5
789
817
  // },
790
818
  // ],
819
+ // "perpProductsV2":[
820
+ // {
821
+ // "symbol":"BTCUSDT",
822
+ // "code":41541,
823
+ // "type":"PerpetualV2",
824
+ // "displaySymbol":"BTC / USDT",
825
+ // "indexSymbol":".BTCUSDT",
826
+ // "markSymbol":".MBTCUSDT",
827
+ // "fundingRateSymbol":".BTCUSDTFR",
828
+ // "fundingRate8hSymbol":".BTCUSDTFR8H",
829
+ // "contractUnderlyingAssets":"BTC",
830
+ // "settleCurrency":"USDT",
831
+ // "quoteCurrency":"USDT",
832
+ // "tickSize":"0.1",
833
+ // "priceScale":0,
834
+ // "ratioScale":0,
835
+ // "pricePrecision":1,
836
+ // "baseCurrency":"BTC",
837
+ // "description":"BTC/USDT perpetual contracts are priced on the .BTCUSDT Index. Each contract is worth 1 BTC. Funding fees are paid and received every 8 hours at UTC time: 00:00, 08:00 and 16:00.",
838
+ // "status":"Listed",
839
+ // "tipOrderQty":0,
840
+ // "listTime":1668225600000,
841
+ // "majorSymbol":true,
842
+ // "defaultLeverage":"-10",
843
+ // "fundingInterval":28800,
844
+ // "maxLeverage":100,
845
+ // "maxOrderQtyRq":"1000",
846
+ // "maxPriceRp":"2000000000",
847
+ // "minOrderValueRv":"1",
848
+ // "minPriceRp":"1000.0",
849
+ // "qtyPrecision":3,
850
+ // "qtyStepSize":"0.001",
851
+ // "tipOrderQtyRq":"200",
852
+ // "maxOpenPosLeverage":100.0
853
+ // },
854
+ // ],
791
855
  // "riskLimits":[
792
856
  // {
793
857
  // "symbol":"BTCUSD",
@@ -803,7 +867,25 @@ class phemex extends phemex$1 {
803
867
  // {"initialMargin":"1.0%","initialMarginEr":1000000,"options":[1,2,3,5,10,25,50,100]},
804
868
  // {"initialMargin":"1.5%","initialMarginEr":1500000,"options":[1,2,3,5,10,25,50,66]},
805
869
  // {"initialMargin":"2.0%","initialMarginEr":2000000,"options":[1,2,3,5,10,25,33,50]},
806
- // ]
870
+ // ],
871
+ // "riskLimitsV2":[
872
+ // {
873
+ // "symbol":"BTCUSDT",
874
+ // "steps":"2000K",
875
+ // "riskLimits":[
876
+ // {"limit":2000000,"initialMarginRr":"0.01","maintenanceMarginRr":"0.005"},,
877
+ // {"limit":4000000,"initialMarginRr":"0.015","maintenanceMarginRr":"0.0075"},
878
+ // {"limit":6000000,"initialMarginRr":"0.02","maintenanceMarginRr":"0.01"},
879
+ // ]
880
+ // },
881
+ // ],
882
+ // "leveragesV2":[
883
+ // {"options":[1.0,2.0,3.0,5.0,10.0,25.0,50.0,100.0],"initialMarginRr":"0.01"},
884
+ // {"options":[1.0,2.0,3.0,5.0,10.0,25.0,50.0,66.67],"initialMarginRr":"0.015"},
885
+ // {"options":[1.0,2.0,3.0,5.0,10.0,25.0,33.0,50.0],"initialMarginRr":"0.02"},
886
+ // ],
887
+ // "ratioScale":8,
888
+ // "md5Checksum":"5c6604814d3c1bafbe602c3d11a7e8bf",
807
889
  // }
808
890
  // }
809
891
  //
@@ -845,8 +927,12 @@ class phemex extends phemex$1 {
845
927
  // }
846
928
  //
847
929
  const v2ProductsData = this.safeValue(v2Products, 'data', {});
848
- const products = this.safeValue(v2ProductsData, 'products', []);
849
- const riskLimits = this.safeValue(v2ProductsData, 'riskLimits', []);
930
+ let products = this.safeValue(v2ProductsData, 'products', []);
931
+ const perpetualProductsV2 = this.safeValue(v2ProductsData, 'perpProductsV2', []);
932
+ products = this.arrayConcat(products, perpetualProductsV2);
933
+ let riskLimits = this.safeValue(v2ProductsData, 'riskLimits', []);
934
+ const riskLimitsV2 = this.safeValue(v2ProductsData, 'riskLimitsV2', []);
935
+ riskLimits = this.arrayConcat(riskLimits, riskLimitsV2);
850
936
  const currencies = this.safeValue(v2ProductsData, 'currencies', []);
851
937
  const riskLimitsById = this.indexBy(riskLimits, 'symbol');
852
938
  const v1ProductsById = this.indexBy(v1ProductsData, 'symbol');
@@ -882,7 +968,7 @@ class phemex extends phemex$1 {
882
968
  * @param {object} [params] extra parameters specific to the exchange API endpoint
883
969
  * @returns {object} an associative dictionary of currencies
884
970
  */
885
- const response = await this.publicGetCfgV2Products(params);
971
+ const response = await this.v2GetPublicProducts(params);
886
972
  //
887
973
  // {
888
974
  // "code":0,
@@ -890,9 +976,9 @@ class phemex extends phemex$1 {
890
976
  // "data":{
891
977
  // ...,
892
978
  // "currencies":[
893
- // {"currency":"BTC","valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"name":"Bitcoin"},
894
- // {"currency":"USD","valueScale":4,"minValueEv":1,"maxValueEv":500000000000000,"name":"USD"},
895
- // {"currency":"USDT","valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"name":"TetherUS"},
979
+ // {"currency":"BTC","name":"Bitcoin","code":1,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"BTC","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":8},
980
+ // {"currency":"USD","name":"USD","code":2,"valueScale":4,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USD","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":2},
981
+ // {"currency":"USDT","name":"TetherUS","code":3,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USDT","inAssetsDisplay":1,"perpetual":2,"stableCoin":1,"assetsPrecision":8},
896
982
  // ],
897
983
  // ...
898
984
  // }
@@ -905,6 +991,7 @@ class phemex extends phemex$1 {
905
991
  const id = this.safeString(currency, 'currency');
906
992
  const name = this.safeString(currency, 'name');
907
993
  const code = this.safeCurrencyCode(id);
994
+ const status = this.safeString(currency, 'status');
908
995
  const valueScaleString = this.safeString(currency, 'valueScale');
909
996
  const valueScale = parseInt(valueScaleString);
910
997
  const minValueEv = this.safeString(currency, 'minValueEv');
@@ -923,7 +1010,7 @@ class phemex extends phemex$1 {
923
1010
  'info': currency,
924
1011
  'code': code,
925
1012
  'name': name,
926
- 'active': undefined,
1013
+ 'active': status === 'Listed',
927
1014
  'deposit': undefined,
928
1015
  'withdraw': undefined,
929
1016
  'fee': undefined,
@@ -4478,6 +4565,48 @@ class phemex extends phemex$1 {
4478
4565
  const sorted = this.sortBy(result, 'timestamp');
4479
4566
  return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
4480
4567
  }
4568
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
4569
+ /**
4570
+ * @method
4571
+ * @name phemex#withdraw
4572
+ * @description make a withdrawal
4573
+ * @see https://phemex-docs.github.io/#create-withdraw-request
4574
+ * @param {string} code unified currency code
4575
+ * @param {float} amount the amount to withdraw
4576
+ * @param {string} address the address to withdraw to
4577
+ * @param {string} tag
4578
+ * @param {object} [params] extra parameters specific to the phemex api endpoint
4579
+ * @param {string} [params.network] unified network code
4580
+ * @returns {object} a [transaction structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#transaction-structure}
4581
+ */
4582
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
4583
+ await this.loadMarkets();
4584
+ this.checkAddress(address);
4585
+ const currency = this.currency(code);
4586
+ let networkCode = undefined;
4587
+ [networkCode, params] = this.handleNetworkCodeAndParams(params);
4588
+ let networkId = this.networkCodeToId(networkCode);
4589
+ const stableCoins = this.safeValue(this.options, 'stableCoins');
4590
+ if (networkId === undefined) {
4591
+ if (!(this.inArray(code, stableCoins))) {
4592
+ networkId = currency['id'];
4593
+ }
4594
+ else {
4595
+ throw new errors.ArgumentsRequired(this.id + ' withdraw () requires an extra argument params["network"]');
4596
+ }
4597
+ }
4598
+ const request = {
4599
+ 'currency': currency['id'],
4600
+ 'address': address,
4601
+ 'amount': amount,
4602
+ 'chainName': networkId.toUpperCase(),
4603
+ };
4604
+ if (tag !== undefined) {
4605
+ request['tag'] = tag;
4606
+ }
4607
+ const response = await this.privatePostPhemexWithdrawWalletsApiCreateWithdraw(this.extend(request, params));
4608
+ return this.parseTransaction(response, currency);
4609
+ }
4481
4610
  handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
4482
4611
  if (response === undefined) {
4483
4612
  return undefined; // fallback to default error handler
@@ -32,6 +32,9 @@ class poloniex extends poloniex$1 {
32
32
  'cancelAllOrders': true,
33
33
  'cancelOrder': true,
34
34
  'createDepositAddress': true,
35
+ 'createMarketBuyOrderWithCost': true,
36
+ 'createMarketOrderWithCost': false,
37
+ 'createMarketSellOrderWithCost': false,
35
38
  'createOrder': true,
36
39
  'editOrder': true,
37
40
  'fetchBalance': true,
@@ -225,6 +228,7 @@ class poloniex extends poloniex$1 {
225
228
  'UST': 'USTC',
226
229
  },
227
230
  'options': {
231
+ 'createMarketBuyOrderRequiresPrice': true,
228
232
  'networks': {
229
233
  'BEP20': 'BSC',
230
234
  'ERC20': 'ETH',
@@ -1248,6 +1252,7 @@ class poloniex extends poloniex$1 {
1248
1252
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1249
1253
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1250
1254
  * @param {float} [params.triggerPrice] *spot only* The price at which a trigger order is triggered at
1255
+ * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
1251
1256
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1252
1257
  */
1253
1258
  await this.loadMarkets();
@@ -1283,7 +1288,6 @@ class poloniex extends poloniex$1 {
1283
1288
  return this.parseOrder(response, market);
1284
1289
  }
1285
1290
  orderRequest(symbol, type, side, amount, request, price = undefined, params = {}) {
1286
- const market = this.market(symbol);
1287
1291
  let upperCaseType = type.toUpperCase();
1288
1292
  const isMarket = upperCaseType === 'MARKET';
1289
1293
  const isPostOnly = this.isPostOnly(isMarket, upperCaseType === 'LIMIT_MAKER', params);
@@ -1299,7 +1303,29 @@ class poloniex extends poloniex$1 {
1299
1303
  request['type'] = upperCaseType;
1300
1304
  if (isMarket) {
1301
1305
  if (side === 'buy') {
1302
- request['amount'] = this.currencyToPrecision(market['quote'], amount);
1306
+ let quoteAmount = undefined;
1307
+ let createMarketBuyOrderRequiresPrice = true;
1308
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1309
+ const cost = this.safeNumber(params, 'cost');
1310
+ params = this.omit(params, 'cost');
1311
+ if (cost !== undefined) {
1312
+ quoteAmount = this.costToPrecision(symbol, cost);
1313
+ }
1314
+ else if (createMarketBuyOrderRequiresPrice) {
1315
+ if (price === undefined) {
1316
+ 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 (quote quantity) in the amount argument');
1317
+ }
1318
+ else {
1319
+ const amountString = this.numberToString(amount);
1320
+ const priceString = this.numberToString(price);
1321
+ const costRequest = Precise["default"].stringMul(amountString, priceString);
1322
+ quoteAmount = this.costToPrecision(symbol, costRequest);
1323
+ }
1324
+ }
1325
+ else {
1326
+ quoteAmount = this.costToPrecision(symbol, amount);
1327
+ }
1328
+ request['amount'] = quoteAmount;
1303
1329
  }
1304
1330
  else {
1305
1331
  request['quantity'] = this.amountToPrecision(symbol, amount);
@@ -481,7 +481,7 @@ class binance extends binance$1 {
481
481
  const subscribe = {
482
482
  'id': requestId,
483
483
  };
484
- const trades = await this.watch(url, subParams, this.extend(request, query), subParams, subscribe);
484
+ const trades = await this.watchMultiple(url, subParams, this.extend(request, query), subParams, subscribe);
485
485
  if (this.newUpdates) {
486
486
  const first = this.safeValue(trades, 0);
487
487
  const tradeSymbol = this.safeString(first, 'symbol');
@@ -1961,11 +1961,11 @@ class binance extends binance$1 {
1961
1961
  this.setBalanceCache(client, type);
1962
1962
  this.setPositionsCache(client, type);
1963
1963
  const message = undefined;
1964
- const newOrder = await this.watch(url, messageHash, message, type);
1964
+ const orders = await this.watch(url, messageHash, message, type);
1965
1965
  if (this.newUpdates) {
1966
- return newOrder;
1966
+ limit = orders.getLimit(symbol, limit);
1967
1967
  }
1968
- return this.filterBySymbolSinceLimit(this.orders, symbol, since, limit, true);
1968
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
1969
1969
  }
1970
1970
  parseWsOrder(order, market = undefined) {
1971
1971
  //
@@ -2626,8 +2626,8 @@ class binance extends binance$1 {
2626
2626
  cachedOrders.append(parsed);
2627
2627
  const messageHash = 'orders';
2628
2628
  const symbolSpecificMessageHash = 'orders:' + symbol;
2629
- client.resolve(parsed, messageHash);
2630
- client.resolve(parsed, symbolSpecificMessageHash);
2629
+ client.resolve(cachedOrders, messageHash);
2630
+ client.resolve(cachedOrders, symbolSpecificMessageHash);
2631
2631
  }
2632
2632
  }
2633
2633
  handleAcountUpdate(client, message) {