ccxt 4.4.82 → 4.4.85

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 (103) hide show
  1. package/README.md +5 -7
  2. package/dist/ccxt.browser.min.js +7 -7
  3. package/dist/cjs/ccxt.js +1 -9
  4. package/dist/cjs/src/apex.js +2 -1
  5. package/dist/cjs/src/base/Exchange.js +15 -2
  6. package/dist/cjs/src/bitget.js +1 -3
  7. package/dist/cjs/src/bitrue.js +14 -35
  8. package/dist/cjs/src/bitso.js +33 -0
  9. package/dist/cjs/src/bitstamp.js +33 -0
  10. package/dist/cjs/src/blofin.js +154 -13
  11. package/dist/cjs/src/btcbox.js +25 -5
  12. package/dist/cjs/src/bybit.js +16 -40
  13. package/dist/cjs/src/cex.js +2 -4
  14. package/dist/cjs/src/coinbase.js +56 -40
  15. package/dist/cjs/src/coinbaseexchange.js +142 -32
  16. package/dist/cjs/src/coincatch.js +14 -67
  17. package/dist/cjs/src/coinex.js +29 -32
  18. package/dist/cjs/src/coinlist.js +16 -15
  19. package/dist/cjs/src/coinmetro.js +22 -11
  20. package/dist/cjs/src/coinone.js +8 -10
  21. package/dist/cjs/src/coinsph.js +126 -1
  22. package/dist/cjs/src/cryptocom.js +111 -1
  23. package/dist/cjs/src/cryptomus.js +43 -89
  24. package/dist/cjs/src/delta.js +76 -36
  25. package/dist/cjs/src/derive.js +46 -10
  26. package/dist/cjs/src/ellipx.js +175 -79
  27. package/dist/cjs/src/gate.js +1 -1
  28. package/dist/cjs/src/gemini.js +3 -5
  29. package/dist/cjs/src/hitbtc.js +56 -69
  30. package/dist/cjs/src/hyperliquid.js +2 -2
  31. package/dist/cjs/src/kraken.js +29 -24
  32. package/dist/cjs/src/kucoinfutures.js +6 -0
  33. package/dist/cjs/src/lbank.js +1 -1
  34. package/dist/cjs/src/paradex.js +119 -3
  35. package/dist/cjs/src/pro/binance.js +31 -33
  36. package/dist/cjs/src/pro/bithumb.js +5 -3
  37. package/dist/cjs/src/pro/kraken.js +289 -79
  38. package/dist/cjs/src/pro/mexc.js +302 -8
  39. package/dist/cjs/src/pro/poloniex.js +6 -2
  40. package/examples/js/cli.js +127 -13
  41. package/js/ccxt.d.ts +2 -11
  42. package/js/ccxt.js +2 -8
  43. package/js/src/abstract/blofin.d.ts +8 -0
  44. package/js/src/abstract/btcbox.d.ts +1 -0
  45. package/js/src/apex.js +2 -1
  46. package/js/src/base/Exchange.d.ts +15 -1
  47. package/js/src/base/Exchange.js +15 -2
  48. package/js/src/base/types.d.ts +3 -0
  49. package/js/src/bitget.js +1 -3
  50. package/js/src/bitrue.js +14 -35
  51. package/js/src/bitso.js +33 -0
  52. package/js/src/bitstamp.js +33 -0
  53. package/js/src/blofin.d.ts +42 -2
  54. package/js/src/blofin.js +154 -13
  55. package/js/src/btcbox.js +25 -5
  56. package/js/src/bybit.js +16 -40
  57. package/js/src/cex.js +2 -4
  58. package/js/src/coinbase.js +56 -40
  59. package/js/src/coinbaseexchange.js +142 -32
  60. package/js/src/coincatch.js +14 -67
  61. package/js/src/coinex.js +28 -29
  62. package/js/src/coinlist.js +16 -15
  63. package/js/src/coinmetro.js +22 -11
  64. package/js/src/coinone.js +8 -10
  65. package/js/src/coinsph.d.ts +10 -1
  66. package/js/src/coinsph.js +126 -1
  67. package/js/src/cryptocom.d.ts +10 -1
  68. package/js/src/cryptocom.js +111 -1
  69. package/js/src/cryptomus.js +43 -89
  70. package/js/src/delta.js +76 -36
  71. package/js/src/derive.js +46 -10
  72. package/js/src/ellipx.d.ts +2 -3
  73. package/js/src/ellipx.js +175 -80
  74. package/js/src/gate.js +1 -1
  75. package/js/src/gemini.js +3 -5
  76. package/js/src/hitbtc.js +56 -69
  77. package/js/src/hyperliquid.js +2 -2
  78. package/js/src/kraken.js +29 -24
  79. package/js/src/kucoinfutures.d.ts +1 -0
  80. package/js/src/kucoinfutures.js +6 -0
  81. package/js/src/lbank.js +1 -1
  82. package/js/src/paradex.d.ts +12 -1
  83. package/js/src/paradex.js +119 -3
  84. package/js/src/pro/binance.d.ts +26 -26
  85. package/js/src/pro/binance.js +31 -33
  86. package/js/src/pro/bithumb.js +5 -3
  87. package/js/src/pro/kraken.d.ts +7 -6
  88. package/js/src/pro/kraken.js +290 -80
  89. package/js/src/pro/mexc.d.ts +58 -0
  90. package/js/src/pro/mexc.js +302 -8
  91. package/js/src/pro/poloniex.d.ts +1 -1
  92. package/js/src/pro/poloniex.js +6 -2
  93. package/package.json +1 -1
  94. package/js/src/abstract/bl3p.d.ts +0 -22
  95. package/js/src/abstract/bl3p.js +0 -11
  96. package/js/src/abstract/idex.d.ts +0 -29
  97. package/js/src/abstract/idex.js +0 -11
  98. package/js/src/bl3p.d.ts +0 -116
  99. package/js/src/bl3p.js +0 -552
  100. package/js/src/idex.d.ts +0 -312
  101. package/js/src/idex.js +0 -1961
  102. package/js/src/pro/idex.d.ts +0 -81
  103. package/js/src/pro/idex.js +0 -720
package/js/src/blofin.js CHANGED
@@ -51,6 +51,7 @@ export default class blofin extends Exchange {
51
51
  'createStopMarketOrder': false,
52
52
  'createStopOrder': false,
53
53
  'createTakeProfitOrder': true,
54
+ 'createTriggerOrder': true,
54
55
  'editOrder': false,
55
56
  'fetchAccounts': false,
56
57
  'fetchBalance': true,
@@ -104,6 +105,7 @@ export default class blofin extends Exchange {
104
105
  'fetchOrders': false,
105
106
  'fetchOrderTrades': true,
106
107
  'fetchPosition': true,
108
+ 'fetchPositionMode': true,
107
109
  'fetchPositions': true,
108
110
  'fetchPositionsForSymbol': false,
109
111
  'fetchPositionsRisk': false,
@@ -131,8 +133,8 @@ export default class blofin extends Exchange {
131
133
  'repayCrossMargin': false,
132
134
  'setLeverage': true,
133
135
  'setMargin': false,
134
- 'setMarginMode': false,
135
- 'setPositionMode': false,
136
+ 'setMarginMode': true,
137
+ 'setPositionMode': true,
136
138
  'signIn': false,
137
139
  'transfer': true,
138
140
  'withdraw': false,
@@ -195,10 +197,14 @@ export default class blofin extends Exchange {
195
197
  'account/positions': 1,
196
198
  'account/leverage-info': 1,
197
199
  'account/margin-mode': 1,
200
+ 'account/position-mode': 1,
198
201
  'account/batch-leverage-info': 1,
199
202
  'trade/orders-tpsl-pending': 1,
203
+ 'trade/orders-algo-pending': 1,
200
204
  'trade/orders-history': 1,
201
205
  'trade/orders-tpsl-history': 1,
206
+ 'trade/orders-algo-history': 1,
207
+ 'trade/order/price-range': 1,
202
208
  'user/query-apikey': 1,
203
209
  'affiliate/basic': 1,
204
210
  'copytrading/instruments': 1,
@@ -215,8 +221,12 @@ export default class blofin extends Exchange {
215
221
  'copytrading/trade/pending-tpsl-by-order': 1,
216
222
  },
217
223
  'post': {
224
+ 'account/set-margin-mode': 1,
225
+ 'account/set-position-mode': 1,
218
226
  'trade/order': 1,
227
+ 'trade/order-algo': 1,
219
228
  'trade/cancel-order': 1,
229
+ 'trade/cancel-algo': 1,
220
230
  'account/set-leverage': 1,
221
231
  'trade/batch-orders': 1,
222
232
  'trade/order-tpsl': 1,
@@ -1151,7 +1161,12 @@ export default class blofin extends Exchange {
1151
1161
  let marginMode = undefined;
1152
1162
  [marginMode, params] = this.handleMarginModeAndParams('createOrder', params, 'cross');
1153
1163
  request['marginMode'] = marginMode;
1164
+ const triggerPrice = this.safeString(params, 'triggerPrice');
1154
1165
  const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
1166
+ const isHedged = this.safeBool(params, 'hedged', false);
1167
+ if (isHedged) {
1168
+ request['positionSide'] = (side === 'buy') ? 'long' : 'short';
1169
+ }
1155
1170
  const isMarketOrder = type === 'market';
1156
1171
  params = this.omit(params, ['timeInForce']);
1157
1172
  const ioc = (timeInForce === 'IOC') || (type === 'ioc');
@@ -1160,7 +1175,8 @@ export default class blofin extends Exchange {
1160
1175
  request['orderType'] = 'market';
1161
1176
  }
1162
1177
  else {
1163
- request['price'] = this.priceToPrecision(symbol, price);
1178
+ const key = (triggerPrice !== undefined) ? 'orderPrice' : 'price';
1179
+ request[key] = this.priceToPrecision(symbol, price);
1164
1180
  }
1165
1181
  let postOnly = false;
1166
1182
  [postOnly, params] = this.handlePostOnly(isMarketOrder, type === 'post_only', params);
@@ -1169,7 +1185,7 @@ export default class blofin extends Exchange {
1169
1185
  }
1170
1186
  const stopLoss = this.safeDict(params, 'stopLoss');
1171
1187
  const takeProfit = this.safeDict(params, 'takeProfit');
1172
- params = this.omit(params, ['stopLoss', 'takeProfit']);
1188
+ params = this.omit(params, ['stopLoss', 'takeProfit', 'hedged']);
1173
1189
  const isStopLoss = stopLoss !== undefined;
1174
1190
  const isTakeProfit = takeProfit !== undefined;
1175
1191
  if (isStopLoss || isTakeProfit) {
@@ -1186,6 +1202,13 @@ export default class blofin extends Exchange {
1186
1202
  request['tpOrderPrice'] = this.priceToPrecision(symbol, tpPrice);
1187
1203
  }
1188
1204
  }
1205
+ else if (triggerPrice !== undefined) {
1206
+ request['orderType'] = 'trigger';
1207
+ request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
1208
+ if (isMarketOrder) {
1209
+ request['orderPrice'] = '-1';
1210
+ }
1211
+ }
1189
1212
  return this.extend(request, params);
1190
1213
  }
1191
1214
  parseOrderStatus(status) {
@@ -1235,7 +1258,7 @@ export default class blofin extends Exchange {
1235
1258
  // "instType": "SWAP", // only in WS
1236
1259
  // }
1237
1260
  //
1238
- const id = this.safeString2(order, 'tpslId', 'orderId');
1261
+ const id = this.safeStringN(order, ['tpslId', 'orderId', 'algoId']);
1239
1262
  const timestamp = this.safeInteger(order, 'createTime');
1240
1263
  const lastUpdateTimestamp = this.safeInteger(order, 'updateTime');
1241
1264
  const lastTradeTimestamp = this.safeInteger(order, 'fillTime');
@@ -1334,12 +1357,14 @@ export default class blofin extends Exchange {
1334
1357
  * @param {float} amount how much of currency you want to trade in units of base currency
1335
1358
  * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1336
1359
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1360
+ * @param {string} [params.triggerPrice] the trigger price for a trigger order
1337
1361
  * @param {bool} [params.reduceOnly] a mark to reduce the position size for margin, swap and future orders
1338
1362
  * @param {bool} [params.postOnly] true to place a post only order
1339
1363
  * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'cross'
1340
1364
  * @param {float} [params.stopLossPrice] stop loss trigger price (will use privatePostTradeOrderTpsl)
1341
1365
  * @param {float} [params.takeProfitPrice] take profit trigger price (will use privatePostTradeOrderTpsl)
1342
1366
  * @param {string} [params.positionSide] *stopLossPrice/takeProfitPrice orders only* 'long' or 'short' or 'net' default is 'net'
1367
+ * @param {boolean} [params.hedged] if true, the positionSide will be set to long/short instead of net, default is false
1343
1368
  * @param {string} [params.clientOrderId] a unique id for the order
1344
1369
  * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
1345
1370
  * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
@@ -1358,16 +1383,30 @@ export default class blofin extends Exchange {
1358
1383
  [method, params] = this.handleOptionAndParams(params, 'createOrder', 'method', 'privatePostTradeOrder');
1359
1384
  const isStopLossPriceDefined = this.safeString(params, 'stopLossPrice') !== undefined;
1360
1385
  const isTakeProfitPriceDefined = this.safeString(params, 'takeProfitPrice') !== undefined;
1386
+ const isTriggerOrder = this.safeString(params, 'triggerPrice') !== undefined;
1361
1387
  const isType2Order = (isStopLossPriceDefined || isTakeProfitPriceDefined);
1362
1388
  let response = undefined;
1389
+ const reduceOnly = this.safeBool(params, 'reduceOnly');
1390
+ if (reduceOnly !== undefined) {
1391
+ params['reduceOnly'] = reduceOnly ? 'true' : 'false';
1392
+ }
1363
1393
  if (tpsl || (method === 'privatePostTradeOrderTpsl') || isType2Order) {
1364
1394
  const tpslRequest = this.createTpslOrderRequest(symbol, type, side, amount, price, params);
1365
1395
  response = await this.privatePostTradeOrderTpsl(tpslRequest);
1366
1396
  }
1397
+ else if (isTriggerOrder || (method === 'privatePostTradeOrderAlgo')) {
1398
+ const triggerRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
1399
+ response = await this.privatePostTradeOrderAlgo(triggerRequest);
1400
+ }
1367
1401
  else {
1368
1402
  const request = this.createOrderRequest(symbol, type, side, amount, price, params);
1369
1403
  response = await this.privatePostTradeOrder(request);
1370
1404
  }
1405
+ if (isTriggerOrder || (method === 'privatePostTradeOrderAlgo')) {
1406
+ const dataDict = this.safeDict(response, 'data', {});
1407
+ const triggerOrder = this.parseOrder(dataDict, market);
1408
+ return triggerOrder;
1409
+ }
1371
1410
  const data = this.safeList(response, 'data', []);
1372
1411
  const first = this.safeDict(data, 0);
1373
1412
  const order = this.parseOrder(first, market);
@@ -1424,7 +1463,8 @@ export default class blofin extends Exchange {
1424
1463
  * @param {string} id order id
1425
1464
  * @param {string} symbol unified symbol of the market the order was made in
1426
1465
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1427
- * @param {boolean} [params.trigger] True if cancelling a trigger/conditional order/tp sl orders
1466
+ * @param {boolean} [params.trigger] True if cancelling a trigger/conditional
1467
+ * @param {boolean} [params.tpsl] True if cancelling a tpsl order
1428
1468
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1429
1469
  */
1430
1470
  async cancelOrder(id, symbol = undefined, params = {}) {
@@ -1436,25 +1476,34 @@ export default class blofin extends Exchange {
1436
1476
  const request = {
1437
1477
  'instId': market['id'],
1438
1478
  };
1439
- const isTrigger = this.safeBoolN(params, ['stop', 'trigger', 'tpsl'], false);
1479
+ const isTrigger = this.safeBoolN(params, ['trigger'], false);
1480
+ const isTpsl = this.safeBool2(params, 'tpsl', 'TPSL', false);
1440
1481
  const clientOrderId = this.safeString(params, 'clientOrderId');
1441
1482
  if (clientOrderId !== undefined) {
1442
1483
  request['clientOrderId'] = clientOrderId;
1443
1484
  }
1444
1485
  else {
1445
- if (!isTrigger) {
1486
+ if (!isTrigger && !isTpsl) {
1446
1487
  request['orderId'] = id.toString();
1447
1488
  }
1448
- else {
1489
+ else if (isTpsl) {
1449
1490
  request['tpslId'] = id.toString();
1450
1491
  }
1492
+ else if (isTrigger) {
1493
+ request['algoId'] = id.toString();
1494
+ }
1451
1495
  }
1452
1496
  const query = this.omit(params, ['orderId', 'clientOrderId', 'stop', 'trigger', 'tpsl']);
1453
- if (isTrigger) {
1497
+ if (isTpsl) {
1454
1498
  const tpslResponse = await this.cancelOrders([id], symbol, params);
1455
1499
  const first = this.safeDict(tpslResponse, 0);
1456
1500
  return first;
1457
1501
  }
1502
+ else if (isTrigger) {
1503
+ const triggerResponse = await this.privatePostTradeCancelAlgo(this.extend(request, query));
1504
+ const triggerData = this.safeDict(triggerResponse, 'data');
1505
+ return this.parseOrder(triggerData, market);
1506
+ }
1458
1507
  const response = await this.privatePostTradeCancelOrder(this.extend(request, query));
1459
1508
  const data = this.safeList(response, 'data', []);
1460
1509
  const order = this.safeDict(data, 0);
@@ -1494,6 +1543,7 @@ export default class blofin extends Exchange {
1494
1543
  * @description Fetch orders that are still open
1495
1544
  * @see https://blofin.com/docs#get-active-orders
1496
1545
  * @see https://blofin.com/docs#get-active-tpsl-orders
1546
+ * @see https://docs.blofin.com/index.html#get-active-algo-orders
1497
1547
  * @param {string} symbol unified market symbol
1498
1548
  * @param {int} [since] the earliest time in ms to fetch open orders for
1499
1549
  * @param {int} [limit] the maximum number of open orders structures to retrieve
@@ -1518,14 +1568,19 @@ export default class blofin extends Exchange {
1518
1568
  if (limit !== undefined) {
1519
1569
  request['limit'] = limit; // default 100, max 100
1520
1570
  }
1521
- const isTrigger = this.safeBoolN(params, ['stop', 'trigger', 'tpsl', 'TPSL'], false);
1571
+ const isTrigger = this.safeBoolN(params, ['stop', 'trigger'], false);
1572
+ const isTpSl = this.safeBool2(params, 'tpsl', 'TPSL', false);
1522
1573
  let method = undefined;
1523
1574
  [method, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'method', 'privateGetTradeOrdersPending');
1524
1575
  const query = this.omit(params, ['method', 'stop', 'trigger', 'tpsl', 'TPSL']);
1525
1576
  let response = undefined;
1526
- if (isTrigger || (method === 'privateGetTradeOrdersTpslPending')) {
1577
+ if (isTpSl || (method === 'privateGetTradeOrdersTpslPending')) {
1527
1578
  response = await this.privateGetTradeOrdersTpslPending(this.extend(request, query));
1528
1579
  }
1580
+ else if (isTrigger || (method === 'privateGetTradeOrdersAlgoPending')) {
1581
+ request['orderType'] = 'trigger';
1582
+ response = await this.privateGetTradeOrdersAlgoPending(this.extend(request, query));
1583
+ }
1529
1584
  else {
1530
1585
  response = await this.privateGetTradeOrdersPending(this.extend(request, query));
1531
1586
  }
@@ -2213,6 +2268,7 @@ export default class blofin extends Exchange {
2213
2268
  * @param {string} symbol unified market symbol
2214
2269
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2215
2270
  * @param {string} [params.marginMode] 'cross' or 'isolated'
2271
+ * @param {string} [params.positionSide] 'long' or 'short' - required for hedged mode in isolated margin
2216
2272
  * @returns {object} response from the exchange
2217
2273
  */
2218
2274
  async setLeverage(leverage, symbol = undefined, params = {}) {
@@ -2347,10 +2403,95 @@ export default class blofin extends Exchange {
2347
2403
  parseMarginMode(marginMode, market = undefined) {
2348
2404
  return {
2349
2405
  'info': marginMode,
2350
- 'symbol': market['symbol'],
2406
+ 'symbol': this.safeString(market, 'symbol'),
2351
2407
  'marginMode': this.safeString(marginMode, 'marginMode'),
2352
2408
  };
2353
2409
  }
2410
+ /**
2411
+ * @method
2412
+ * @name blofin#setMarginMode
2413
+ * @description set margin mode to 'cross' or 'isolated'
2414
+ * @see https://docs.blofin.com/index.html#set-margin-mode
2415
+ * @param {string} marginMode 'cross' or 'isolated'
2416
+ * @param {string} [symbol] unified market symbol (not used in blofin setMarginMode)
2417
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2418
+ * @returns {object} response from the exchange
2419
+ */
2420
+ async setMarginMode(marginMode, symbol = undefined, params = {}) {
2421
+ this.checkRequiredArgument('setMarginMode', marginMode, 'marginMode', ['cross', 'isolated']);
2422
+ await this.loadMarkets();
2423
+ let market = undefined;
2424
+ if (symbol !== undefined) {
2425
+ market = this.market(symbol);
2426
+ }
2427
+ const request = {
2428
+ 'marginMode': marginMode,
2429
+ };
2430
+ const response = await this.privatePostAccountSetMarginMode(this.extend(request, params));
2431
+ //
2432
+ // {
2433
+ // "code": "0",
2434
+ // "msg": "success",
2435
+ // "data": {
2436
+ // "marginMode": "isolated"
2437
+ // }
2438
+ // }
2439
+ //
2440
+ const data = this.safeDict(response, 'data', {});
2441
+ return this.parseMarginMode(data, market);
2442
+ }
2443
+ /**
2444
+ * @method
2445
+ * @name blofin#fetchPositionMode
2446
+ * @description fetchs the position mode, hedged or one way
2447
+ * @see https://docs.blofin.com/index.html#get-position-mode
2448
+ * @param {string} [symbol] unified symbol of the market to fetch the position mode for (not used in blofin fetchPositionMode)
2449
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2450
+ * @returns {object} an object detailing whether the market is in hedged or one-way mode
2451
+ */
2452
+ async fetchPositionMode(symbol = undefined, params = {}) {
2453
+ const response = await this.privateGetAccountPositionMode(params);
2454
+ const data = this.safeDict(response, 'data', {});
2455
+ const positionMode = this.safeString(data, 'positionMode');
2456
+ //
2457
+ // {
2458
+ // "code": "0",
2459
+ // "msg": "success",
2460
+ // "data": {
2461
+ // "positionMode": "long_short_mode"
2462
+ // }
2463
+ // }
2464
+ //
2465
+ return {
2466
+ 'info': data,
2467
+ 'hedged': positionMode === 'long_short_mode',
2468
+ };
2469
+ }
2470
+ /**
2471
+ * @method
2472
+ * @name blofin#setPositionMode
2473
+ * @description set hedged to true or false for a market
2474
+ * @see https://docs.blofin.com/index.html#set-position-mode
2475
+ * @param {bool} hedged set to true to use hedged mode, false for one-way mode
2476
+ * @param {string} [symbol] not used by blofin setPositionMode ()
2477
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2478
+ * @returns {object} response from the exchange
2479
+ */
2480
+ async setPositionMode(hedged, symbol = undefined, params = {}) {
2481
+ const request = {
2482
+ 'positionMode': hedged ? 'long_short_mode' : 'net_mode',
2483
+ };
2484
+ //
2485
+ // {
2486
+ // "code": "0",
2487
+ // "msg": "success",
2488
+ // "data": {
2489
+ // "positionMode": "net_mode"
2490
+ // }
2491
+ // }
2492
+ //
2493
+ return await this.privatePostAccountSetPositionMode(this.extend(request, params));
2494
+ }
2354
2495
  handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2355
2496
  if (response === undefined) {
2356
2497
  return undefined; // fallback to default error handler
package/js/src/btcbox.js CHANGED
@@ -109,6 +109,18 @@ export default class btcbox extends Exchange {
109
109
  'wallet',
110
110
  ],
111
111
  },
112
+ 'webApi': {
113
+ 'get': [
114
+ 'ajax/coin/coinInfo',
115
+ ],
116
+ },
117
+ },
118
+ 'options': {
119
+ 'fetchMarkets': {
120
+ 'webApiEnable': true,
121
+ 'webApiRetries': 3,
122
+ },
123
+ 'amountPrecision': '0.0001', // exchange has only few pairs and all of them
112
124
  },
113
125
  'features': {
114
126
  'spot': {
@@ -194,9 +206,12 @@ export default class btcbox extends Exchange {
194
206
  * @returns {object[]} an array of objects representing market data
195
207
  */
196
208
  async fetchMarkets(params = {}) {
197
- const response = await this.publicGetTickers();
209
+ const promise1 = this.publicGetTickers();
210
+ const promise2 = this.fetchWebEndpoint('fetchMarkets', 'webApiGetAjaxCoinCoinInfo', true);
211
+ const [response1, response2] = await Promise.all([promise1, promise2]);
198
212
  //
199
- const marketIds = Object.keys(response);
213
+ const result2Data = this.safeDict(response2, 'data', {});
214
+ const marketIds = Object.keys(response1);
200
215
  const markets = [];
201
216
  for (let i = 0; i < marketIds.length; i++) {
202
217
  const marketId = marketIds[i];
@@ -205,9 +220,11 @@ export default class btcbox extends Exchange {
205
220
  const quote = this.safeString(symbolParts, 1);
206
221
  const quoteId = quote.toLowerCase();
207
222
  const id = baseCurr.toLowerCase();
208
- const res = response[marketId];
223
+ const res = response1[marketId];
209
224
  const symbol = baseCurr + '/' + quote;
210
225
  const fee = (id === 'BTC') ? this.parseNumber('0.0005') : this.parseNumber('0.0010');
226
+ const details = this.safeDict(result2Data, id, {});
227
+ const tradeDetails = this.safeDict(details, 'trade', {});
211
228
  markets.push(this.safeMarketStructure({
212
229
  'id': id,
213
230
  'uppercaseId': undefined,
@@ -253,10 +270,10 @@ export default class btcbox extends Exchange {
253
270
  },
254
271
  },
255
272
  'precision': {
256
- 'price': undefined,
273
+ 'price': this.parseNumber(this.parsePrecision(this.safeString(tradeDetails, 'pricedecimal'))),
257
274
  'amount': undefined,
258
275
  },
259
- 'active': undefined,
276
+ 'active': this.safeString(tradeDetails, 'enable') === '1',
260
277
  'created': undefined,
261
278
  'info': res,
262
279
  }));
@@ -730,6 +747,9 @@ export default class btcbox extends Exchange {
730
747
  url += '?' + this.urlencode(params);
731
748
  }
732
749
  }
750
+ else if (api === 'webApi') {
751
+ url = this.urls['www'] + '/' + path;
752
+ }
733
753
  else {
734
754
  this.checkRequiredCredentials();
735
755
  const nonce = this.nonce().toString();
package/js/src/bybit.js CHANGED
@@ -1643,82 +1643,58 @@ export default class bybit extends Exchange {
1643
1643
  const name = this.safeString(currency, 'name');
1644
1644
  const chains = this.safeList(currency, 'chains', []);
1645
1645
  const networks = {};
1646
- let minPrecision = undefined;
1647
- let minWithdrawFeeString = undefined;
1648
- let minWithdrawString = undefined;
1649
- let minDepositString = undefined;
1650
- let deposit = false;
1651
- let withdraw = false;
1652
1646
  for (let j = 0; j < chains.length; j++) {
1653
1647
  const chain = chains[j];
1654
1648
  const networkId = this.safeString(chain, 'chain');
1655
1649
  const networkCode = this.networkIdToCode(networkId);
1656
- const precision = this.parseNumber(this.parsePrecision(this.safeString(chain, 'minAccuracy')));
1657
- minPrecision = (minPrecision === undefined) ? precision : Math.min(minPrecision, precision);
1658
- const depositAllowed = this.safeInteger(chain, 'chainDeposit') === 1;
1659
- deposit = (depositAllowed) ? depositAllowed : deposit;
1660
- const withdrawAllowed = this.safeInteger(chain, 'chainWithdraw') === 1;
1661
- withdraw = (withdrawAllowed) ? withdrawAllowed : withdraw;
1662
- const withdrawFeeString = this.safeString(chain, 'withdrawFee');
1663
- if (withdrawFeeString !== undefined) {
1664
- minWithdrawFeeString = (minWithdrawFeeString === undefined) ? withdrawFeeString : Precise.stringMin(withdrawFeeString, minWithdrawFeeString);
1665
- }
1666
- const minNetworkWithdrawString = this.safeString(chain, 'withdrawMin');
1667
- if (minNetworkWithdrawString !== undefined) {
1668
- minWithdrawString = (minWithdrawString === undefined) ? minNetworkWithdrawString : Precise.stringMin(minNetworkWithdrawString, minWithdrawString);
1669
- }
1670
- const minNetworkDepositString = this.safeString(chain, 'depositMin');
1671
- if (minNetworkDepositString !== undefined) {
1672
- minDepositString = (minDepositString === undefined) ? minNetworkDepositString : Precise.stringMin(minNetworkDepositString, minDepositString);
1673
- }
1674
1650
  networks[networkCode] = {
1675
1651
  'info': chain,
1676
1652
  'id': networkId,
1677
1653
  'network': networkCode,
1678
- 'active': depositAllowed && withdrawAllowed,
1679
- 'deposit': depositAllowed,
1680
- 'withdraw': withdrawAllowed,
1681
- 'fee': this.parseNumber(withdrawFeeString),
1682
- 'precision': precision,
1654
+ 'active': undefined,
1655
+ 'deposit': this.safeInteger(chain, 'chainDeposit') === 1,
1656
+ 'withdraw': this.safeInteger(chain, 'chainWithdraw') === 1,
1657
+ 'fee': this.safeNumber(chain, 'withdrawFee'),
1658
+ 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'minAccuracy'))),
1683
1659
  'limits': {
1684
1660
  'withdraw': {
1685
- 'min': this.parseNumber(minNetworkWithdrawString),
1661
+ 'min': this.safeNumber(chain, 'withdrawMin'),
1686
1662
  'max': undefined,
1687
1663
  },
1688
1664
  'deposit': {
1689
- 'min': this.parseNumber(minNetworkDepositString),
1665
+ 'min': this.safeNumber(chain, 'depositMin'),
1690
1666
  'max': undefined,
1691
1667
  },
1692
1668
  },
1693
1669
  };
1694
1670
  }
1695
- result[code] = {
1671
+ result[code] = this.safeCurrencyStructure({
1696
1672
  'info': currency,
1697
1673
  'code': code,
1698
1674
  'id': currencyId,
1699
1675
  'name': name,
1700
- 'active': deposit && withdraw,
1701
- 'deposit': deposit,
1702
- 'withdraw': withdraw,
1703
- 'fee': this.parseNumber(minWithdrawFeeString),
1704
- 'precision': minPrecision,
1676
+ 'active': undefined,
1677
+ 'deposit': undefined,
1678
+ 'withdraw': undefined,
1679
+ 'fee': undefined,
1680
+ 'precision': undefined,
1705
1681
  'limits': {
1706
1682
  'amount': {
1707
1683
  'min': undefined,
1708
1684
  'max': undefined,
1709
1685
  },
1710
1686
  'withdraw': {
1711
- 'min': this.parseNumber(minWithdrawString),
1687
+ 'min': undefined,
1712
1688
  'max': undefined,
1713
1689
  },
1714
1690
  'deposit': {
1715
- 'min': this.parseNumber(minDepositString),
1691
+ 'min': undefined,
1716
1692
  'max': undefined,
1717
1693
  },
1718
1694
  },
1719
1695
  'networks': networks,
1720
1696
  'type': 'crypto', // atm exchange api provides only cryptos
1721
- };
1697
+ });
1722
1698
  }
1723
1699
  return result;
1724
1700
  }
package/js/src/cex.js CHANGED
@@ -305,8 +305,6 @@ export default class cex extends Exchange {
305
305
  const id = this.safeString(rawCurrency, 'currency');
306
306
  const code = this.safeCurrencyCode(id);
307
307
  const type = this.safeBool(rawCurrency, 'fiat') ? 'fiat' : 'crypto';
308
- const currencyDepositEnabled = this.safeBool(rawCurrency, 'walletDeposit');
309
- const currencyWithdrawEnabled = this.safeBool(rawCurrency, 'walletWithdrawal');
310
308
  const currencyPrecision = this.parseNumber(this.parsePrecision(this.safeString(rawCurrency, 'precision')));
311
309
  const networks = {};
312
310
  const rawNetworks = this.safeDict(rawCurrency, 'blockchains', {});
@@ -345,8 +343,8 @@ export default class cex extends Exchange {
345
343
  'name': undefined,
346
344
  'type': type,
347
345
  'active': undefined,
348
- 'deposit': currencyDepositEnabled,
349
- 'withdraw': currencyWithdrawEnabled,
346
+ 'deposit': this.safeBool(rawCurrency, 'walletDeposit'),
347
+ 'withdraw': this.safeBool(rawCurrency, 'walletWithdrawal'),
350
348
  'fee': undefined,
351
349
  'precision': currencyPrecision,
352
350
  'limits': {
@@ -1877,45 +1877,46 @@ export default class coinbase extends Exchange {
1877
1877
  * @returns {object} an associative dictionary of currencies
1878
1878
  */
1879
1879
  async fetchCurrencies(params = {}) {
1880
- const response = await this.fetchCurrenciesFromCache(params);
1881
- const currencies = this.safeList(response, 'currencies', []);
1882
- //
1883
- // fiat
1884
- //
1885
- // {
1886
- // id: 'IMP',
1887
- // name: 'Isle of Man Pound',
1888
- // min_size: '0.01'
1889
- // },
1890
- //
1891
- // crypto
1892
- //
1893
- // {
1894
- // asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
1895
- // code: 'AERO',
1896
- // name: 'Aerodrome Finance',
1897
- // color: '#0433FF',
1898
- // sort_index: '340',
1899
- // exponent: '8',
1900
- // type: 'crypto',
1901
- // address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
1902
- // }
1880
+ const promises = [
1881
+ this.v2PublicGetCurrencies(params),
1882
+ this.v2PublicGetCurrenciesCrypto(params),
1883
+ this.v2PublicGetExchangeRates(params),
1884
+ ];
1885
+ const promisesResult = await Promise.all(promises);
1886
+ const fiatResponse = this.safeDict(promisesResult, 0, {});
1903
1887
  //
1888
+ // [
1889
+ // "data": [
1890
+ // {
1891
+ // id: 'IMP',
1892
+ // name: 'Isle of Man Pound',
1893
+ // min_size: '0.01'
1894
+ // },
1895
+ // ...
1904
1896
  //
1905
- // {
1906
- // "data":{
1907
- // "currency":"USD",
1908
- // "rates":{
1909
- // "AED":"3.67",
1910
- // "AFN":"78.21",
1911
- // "ALL":"110.42",
1912
- // "AMD":"474.18",
1913
- // "ANG":"1.75",
1914
- // ...
1915
- // },
1916
- // }
1917
- // }
1897
+ const cryptoResponse = this.safeDict(promisesResult, 1, {});
1918
1898
  //
1899
+ // [
1900
+ // "data": [
1901
+ // {
1902
+ // asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
1903
+ // code: 'AERO',
1904
+ // name: 'Aerodrome Finance',
1905
+ // color: '#0433FF',
1906
+ // sort_index: '340',
1907
+ // exponent: '8',
1908
+ // type: 'crypto',
1909
+ // address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
1910
+ // },
1911
+ // ...
1912
+ //
1913
+ const ratesResponse = this.safeDict(promisesResult, 2, {});
1914
+ const fiatData = this.safeList(fiatResponse, 'data', []);
1915
+ const cryptoData = this.safeList(cryptoResponse, 'data', []);
1916
+ const ratesData = this.safeDict(ratesResponse, 'data', {});
1917
+ const rates = this.safeDict(ratesData, 'rates', {});
1918
+ const ratesIds = Object.keys(rates);
1919
+ const currencies = this.arrayConcat(fiatData, cryptoData);
1919
1920
  const result = {};
1920
1921
  const networks = {};
1921
1922
  const networksById = {};
@@ -1927,12 +1928,13 @@ export default class coinbase extends Exchange {
1927
1928
  const name = this.safeString(currency, 'name');
1928
1929
  this.options['networks'][code] = name.toLowerCase();
1929
1930
  this.options['networksById'][code] = name.toLowerCase();
1930
- result[code] = {
1931
+ const type = (assetId !== undefined) ? 'crypto' : 'fiat';
1932
+ result[code] = this.safeCurrencyStructure({
1931
1933
  'info': currency,
1932
1934
  'id': id,
1933
1935
  'code': code,
1934
- 'type': (assetId !== undefined) ? 'crypto' : 'fiat',
1935
- 'name': this.safeString(currency, 'name'),
1936
+ 'type': type,
1937
+ 'name': name,
1936
1938
  'active': true,
1937
1939
  'deposit': undefined,
1938
1940
  'withdraw': undefined,
@@ -1949,13 +1951,27 @@ export default class coinbase extends Exchange {
1949
1951
  'max': undefined,
1950
1952
  },
1951
1953
  },
1952
- };
1954
+ });
1953
1955
  if (assetId !== undefined) {
1954
1956
  const lowerCaseName = name.toLowerCase();
1955
1957
  networks[code] = lowerCaseName;
1956
1958
  networksById[lowerCaseName] = code;
1957
1959
  }
1958
1960
  }
1961
+ // we have to add other currencies here ( https://discord.com/channels/1220414409550336183/1220464770239430761/1372215891940479098 )
1962
+ for (let i = 0; i < ratesIds.length; i++) {
1963
+ const currencyId = ratesIds[i];
1964
+ const code = this.safeCurrencyCode(currencyId);
1965
+ if (!(code in result)) {
1966
+ result[code] = this.safeCurrencyStructure({
1967
+ 'info': {},
1968
+ 'id': currencyId,
1969
+ 'code': code,
1970
+ 'type': 'crypto',
1971
+ 'networks': {}, // todo
1972
+ });
1973
+ }
1974
+ }
1959
1975
  this.options['networks'] = this.extend(networks, this.options['networks']);
1960
1976
  this.options['networksById'] = this.extend(networksById, this.options['networksById']);
1961
1977
  return result;