ccxt 4.4.82 → 4.4.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -9
- package/dist/ccxt.browser.min.js +7 -7
- package/dist/cjs/ccxt.js +6 -17
- package/dist/cjs/src/abstract/bittrade.js +9 -0
- package/dist/cjs/src/apex.js +2 -1
- package/dist/cjs/src/ascendex.js +189 -155
- package/dist/cjs/src/base/Exchange.js +15 -2
- package/dist/cjs/src/bequant.js +1 -1
- package/dist/cjs/src/bitget.js +6 -7
- package/dist/cjs/src/bitmart.js +1 -1
- package/dist/cjs/src/bitrue.js +14 -35
- package/dist/cjs/src/bitso.js +33 -0
- package/dist/cjs/src/bitstamp.js +33 -0
- package/dist/cjs/src/bittrade.js +2049 -0
- package/dist/cjs/src/blofin.js +154 -13
- package/dist/cjs/src/btcbox.js +25 -5
- package/dist/cjs/src/bybit.js +16 -40
- package/dist/cjs/src/cex.js +2 -4
- package/dist/cjs/src/coinbase.js +58 -46
- package/dist/cjs/src/coinbaseexchange.js +142 -32
- package/dist/cjs/src/coincatch.js +14 -67
- package/dist/cjs/src/coinex.js +29 -32
- package/dist/cjs/src/coinlist.js +16 -15
- package/dist/cjs/src/coinmetro.js +22 -11
- package/dist/cjs/src/coinone.js +8 -10
- package/dist/cjs/src/coinsph.js +126 -1
- package/dist/cjs/src/cryptocom.js +111 -1
- package/dist/cjs/src/cryptomus.js +43 -89
- package/dist/cjs/src/delta.js +76 -36
- package/dist/cjs/src/deribit.js +4 -5
- package/dist/cjs/src/derive.js +46 -10
- package/dist/cjs/src/ellipx.js +175 -79
- package/dist/cjs/src/gate.js +1 -1
- package/dist/cjs/src/gemini.js +3 -5
- package/dist/cjs/src/hitbtc.js +56 -69
- package/dist/cjs/src/hollaex.js +107 -49
- package/dist/cjs/src/htx.js +20 -44
- package/dist/cjs/src/hyperliquid.js +6 -6
- package/dist/cjs/src/kraken.js +29 -24
- package/dist/cjs/src/kucoinfutures.js +6 -0
- package/dist/cjs/src/lbank.js +1 -1
- package/dist/cjs/src/mexc.js +2 -2
- package/dist/cjs/src/ndax.js +25 -24
- package/dist/cjs/src/okcoin.js +12 -31
- package/dist/cjs/src/okx.js +9 -0
- package/dist/cjs/src/onetrading.js +9 -6
- package/dist/cjs/src/oxfun.js +42 -114
- package/dist/cjs/src/paradex.js +124 -4
- package/dist/cjs/src/pro/binance.js +32 -33
- package/dist/cjs/src/pro/bithumb.js +5 -3
- package/dist/cjs/src/pro/bittrade.js +605 -0
- package/dist/cjs/src/pro/kraken.js +289 -79
- package/dist/cjs/src/pro/luno.js +6 -5
- package/dist/cjs/src/pro/mexc.js +304 -7
- package/dist/cjs/src/pro/poloniex.js +6 -2
- package/examples/js/cli.js +127 -13
- package/js/ccxt.d.ts +8 -20
- package/js/ccxt.js +6 -14
- package/js/src/abstract/blofin.d.ts +8 -0
- package/js/src/abstract/btcbox.d.ts +1 -0
- package/js/src/abstract/myokx.d.ts +2 -0
- package/js/src/abstract/okx.d.ts +2 -0
- package/js/src/apex.js +2 -1
- package/js/src/ascendex.d.ts +2 -0
- package/js/src/ascendex.js +189 -155
- package/js/src/base/Exchange.d.ts +15 -1
- package/js/src/base/Exchange.js +15 -2
- package/js/src/base/types.d.ts +3 -0
- package/js/src/bequant.js +1 -1
- package/js/src/bitget.js +6 -7
- package/js/src/bitmart.js +1 -1
- package/js/src/bitrue.js +14 -35
- package/js/src/bitso.js +33 -0
- package/js/src/bitstamp.js +33 -0
- package/js/src/{huobijp.d.ts → bittrade.d.ts} +29 -29
- package/js/src/{huobijp.js → bittrade.js} +35 -35
- package/js/src/blofin.d.ts +42 -2
- package/js/src/blofin.js +154 -13
- package/js/src/btcbox.js +25 -5
- package/js/src/bybit.js +16 -40
- package/js/src/cex.js +2 -4
- package/js/src/coinbase.js +58 -46
- package/js/src/coinbaseexchange.js +142 -32
- package/js/src/coincatch.js +14 -67
- package/js/src/coinex.js +28 -29
- package/js/src/coinlist.js +16 -15
- package/js/src/coinmetro.js +22 -11
- package/js/src/coinone.js +8 -10
- package/js/src/coinsph.d.ts +10 -1
- package/js/src/coinsph.js +126 -1
- package/js/src/cryptocom.d.ts +10 -1
- package/js/src/cryptocom.js +111 -1
- package/js/src/cryptomus.js +43 -89
- package/js/src/delta.js +76 -36
- package/js/src/deribit.js +4 -5
- package/js/src/derive.js +46 -10
- package/js/src/ellipx.d.ts +2 -3
- package/js/src/ellipx.js +175 -80
- package/js/src/gate.js +1 -1
- package/js/src/gemini.js +3 -5
- package/js/src/hitbtc.js +56 -69
- package/js/src/hollaex.js +107 -49
- package/js/src/htx.js +20 -44
- package/js/src/hyperliquid.js +6 -6
- package/js/src/kraken.js +29 -24
- package/js/src/kucoinfutures.d.ts +1 -0
- package/js/src/kucoinfutures.js +6 -0
- package/js/src/lbank.js +1 -1
- package/js/src/mexc.js +2 -2
- package/js/src/ndax.js +25 -24
- package/js/src/okcoin.js +12 -31
- package/js/src/okx.js +9 -0
- package/js/src/onetrading.js +9 -6
- package/js/src/oxfun.js +42 -114
- package/js/src/paradex.d.ts +12 -1
- package/js/src/paradex.js +124 -4
- package/js/src/pro/binance.d.ts +26 -26
- package/js/src/pro/binance.js +32 -33
- package/js/src/pro/bithumb.js +5 -3
- package/js/src/pro/{huobijp.d.ts → bittrade.d.ts} +6 -6
- package/js/src/pro/{huobijp.js → bittrade.js} +7 -7
- package/js/src/pro/kraken.d.ts +7 -6
- package/js/src/pro/kraken.js +290 -80
- package/js/src/pro/luno.js +6 -5
- package/js/src/pro/mexc.d.ts +58 -0
- package/js/src/pro/mexc.js +304 -7
- package/js/src/pro/poloniex.d.ts +1 -1
- package/js/src/pro/poloniex.js +6 -2
- package/package.json +1 -1
- package/js/src/abstract/bl3p.d.ts +0 -22
- package/js/src/abstract/huobijp.js +0 -11
- package/js/src/abstract/idex.d.ts +0 -29
- package/js/src/abstract/idex.js +0 -11
- package/js/src/abstract/kuna.d.ts +0 -185
- package/js/src/abstract/kuna.js +0 -11
- package/js/src/bl3p.d.ts +0 -116
- package/js/src/bl3p.js +0 -552
- package/js/src/idex.d.ts +0 -312
- package/js/src/idex.js +0 -1961
- package/js/src/kuna.d.ts +0 -335
- package/js/src/kuna.js +0 -2006
- package/js/src/pro/idex.d.ts +0 -81
- package/js/src/pro/idex.js +0 -720
- /package/js/src/abstract/{huobijp.d.ts → bittrade.d.ts} +0 -0
- /package/js/src/abstract/{bl3p.js → bittrade.js} +0 -0
package/dist/cjs/src/pro/mexc.js
CHANGED
|
@@ -31,6 +31,12 @@ class mexc extends mexc$1 {
|
|
|
31
31
|
'watchBidsAsks': true,
|
|
32
32
|
'watchTrades': true,
|
|
33
33
|
'watchTradesForSymbols': false,
|
|
34
|
+
'unWatchTicker': true,
|
|
35
|
+
'unWatchTickers': true,
|
|
36
|
+
'unWatchBidsAsks': true,
|
|
37
|
+
'unWatchOHLCV': true,
|
|
38
|
+
'unWatchOrderBook': true,
|
|
39
|
+
'unWatchTrades': true,
|
|
34
40
|
},
|
|
35
41
|
'urls': {
|
|
36
42
|
'api': {
|
|
@@ -488,12 +494,15 @@ class mexc extends mexc$1 {
|
|
|
488
494
|
}, market);
|
|
489
495
|
}
|
|
490
496
|
async watchSpotPublic(channel, messageHash, params = {}) {
|
|
497
|
+
const unsubscribed = this.safeBool(params, 'unsubscribed', false);
|
|
498
|
+
params = this.omit(params, ['unsubscribed']);
|
|
491
499
|
const url = this.urls['api']['ws']['spot'];
|
|
500
|
+
const method = (unsubscribed) ? 'UNSUBSCRIPTION' : 'SUBSCRIPTION';
|
|
492
501
|
const request = {
|
|
493
|
-
'method':
|
|
502
|
+
'method': method,
|
|
494
503
|
'params': [channel],
|
|
495
504
|
};
|
|
496
|
-
return await this.watch(url, messageHash, this.extend(request, params),
|
|
505
|
+
return await this.watch(url, messageHash, this.extend(request, params), messageHash);
|
|
497
506
|
}
|
|
498
507
|
async watchSpotPrivate(channel, messageHash, params = {}) {
|
|
499
508
|
this.checkRequiredCredentials();
|
|
@@ -785,11 +794,8 @@ class mexc extends mexc$1 {
|
|
|
785
794
|
const messageHash = 'orderbook:' + symbol;
|
|
786
795
|
const subscription = this.safeValue(client.subscriptions, messageHash);
|
|
787
796
|
const limit = this.safeInteger(subscription, 'limit');
|
|
788
|
-
if (
|
|
789
|
-
|
|
790
|
-
// once we have received the first delta and initialized the orderbook
|
|
791
|
-
client.subscriptions[messageHash] = 1;
|
|
792
|
-
this.orderbooks[symbol] = this.countedOrderBook({});
|
|
797
|
+
if (!(symbol in this.orderbooks)) {
|
|
798
|
+
this.orderbooks[symbol] = this.orderBook();
|
|
793
799
|
}
|
|
794
800
|
const storedOrderBook = this.orderbooks[symbol];
|
|
795
801
|
const nonce = this.safeInteger(storedOrderBook, 'nonce');
|
|
@@ -1412,6 +1418,297 @@ class mexc extends mexc$1 {
|
|
|
1412
1418
|
this.balance[type] = this.safeBalance(this.balance[type]);
|
|
1413
1419
|
client.resolve(this.balance[type], messageHash);
|
|
1414
1420
|
}
|
|
1421
|
+
/**
|
|
1422
|
+
* @method
|
|
1423
|
+
* @name mexc#unWatchTicker
|
|
1424
|
+
* @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
1425
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1426
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1427
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1428
|
+
*/
|
|
1429
|
+
async unWatchTicker(symbol, params = {}) {
|
|
1430
|
+
await this.loadMarkets();
|
|
1431
|
+
const market = this.market(symbol);
|
|
1432
|
+
const messageHash = 'unsubscribe:ticker:' + market['symbol'];
|
|
1433
|
+
let url = undefined;
|
|
1434
|
+
let channel = undefined;
|
|
1435
|
+
if (market['spot']) {
|
|
1436
|
+
let miniTicker = false;
|
|
1437
|
+
[miniTicker, params] = this.handleOptionAndParams(params, 'watchTicker', 'miniTicker');
|
|
1438
|
+
if (miniTicker) {
|
|
1439
|
+
channel = 'spot@public.miniTicker.v3.api@' + market['id'] + '@UTC+8';
|
|
1440
|
+
}
|
|
1441
|
+
else {
|
|
1442
|
+
channel = 'spot@public.bookTicker.v3.api@' + market['id'];
|
|
1443
|
+
}
|
|
1444
|
+
url = this.urls['api']['ws']['spot'];
|
|
1445
|
+
params['unsubscribed'] = true;
|
|
1446
|
+
this.watchSpotPublic(channel, messageHash, params);
|
|
1447
|
+
}
|
|
1448
|
+
else {
|
|
1449
|
+
channel = 'unsub.ticker';
|
|
1450
|
+
const requestParams = {
|
|
1451
|
+
'symbol': market['id'],
|
|
1452
|
+
};
|
|
1453
|
+
url = this.urls['api']['ws']['swap'];
|
|
1454
|
+
this.watchSwapPublic(channel, messageHash, requestParams, params);
|
|
1455
|
+
}
|
|
1456
|
+
const client = this.client(url);
|
|
1457
|
+
this.handleUnsubscriptions(client, [messageHash]);
|
|
1458
|
+
return undefined;
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* @method
|
|
1462
|
+
* @name mexc#unWatchTickers
|
|
1463
|
+
* @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
1464
|
+
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
1465
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1466
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1467
|
+
*/
|
|
1468
|
+
async unWatchTickers(symbols = undefined, params = {}) {
|
|
1469
|
+
await this.loadMarkets();
|
|
1470
|
+
symbols = this.marketSymbols(symbols, undefined);
|
|
1471
|
+
const messageHashes = [];
|
|
1472
|
+
const firstSymbol = this.safeString(symbols, 0);
|
|
1473
|
+
let market = undefined;
|
|
1474
|
+
if (firstSymbol !== undefined) {
|
|
1475
|
+
market = this.market(firstSymbol);
|
|
1476
|
+
}
|
|
1477
|
+
let type = undefined;
|
|
1478
|
+
[type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
|
|
1479
|
+
const isSpot = (type === 'spot');
|
|
1480
|
+
const url = (isSpot) ? this.urls['api']['ws']['spot'] : this.urls['api']['ws']['swap'];
|
|
1481
|
+
const request = {};
|
|
1482
|
+
if (isSpot) {
|
|
1483
|
+
let miniTicker = false;
|
|
1484
|
+
[miniTicker, params] = this.handleOptionAndParams(params, 'watchTickers', 'miniTicker');
|
|
1485
|
+
const topics = [];
|
|
1486
|
+
if (!miniTicker) {
|
|
1487
|
+
if (symbols === undefined) {
|
|
1488
|
+
throw new errors.ArgumentsRequired(this.id + ' watchTickers required symbols argument for the bookTicker channel');
|
|
1489
|
+
}
|
|
1490
|
+
const marketIds = this.marketIds(symbols);
|
|
1491
|
+
for (let i = 0; i < marketIds.length; i++) {
|
|
1492
|
+
const marketId = marketIds[i];
|
|
1493
|
+
messageHashes.push('unsubscribe:ticker:' + symbols[i]);
|
|
1494
|
+
const channel = 'spot@public.bookTicker.v3.api@' + marketId;
|
|
1495
|
+
topics.push(channel);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
else {
|
|
1499
|
+
topics.push('spot@public.miniTickers.v3.api@UTC+8');
|
|
1500
|
+
if (symbols === undefined) {
|
|
1501
|
+
messageHashes.push('unsubscribe:spot:ticker');
|
|
1502
|
+
}
|
|
1503
|
+
else {
|
|
1504
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1505
|
+
messageHashes.push('unsubscribe:ticker:' + symbols[i]);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
request['method'] = 'UNSUBSCRIPTION';
|
|
1510
|
+
request['params'] = topics;
|
|
1511
|
+
}
|
|
1512
|
+
else {
|
|
1513
|
+
request['method'] = 'unsub.tickers';
|
|
1514
|
+
request['params'] = {};
|
|
1515
|
+
messageHashes.push('unsubscribe:ticker');
|
|
1516
|
+
}
|
|
1517
|
+
const client = this.client(url);
|
|
1518
|
+
this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes);
|
|
1519
|
+
this.handleUnsubscriptions(client, messageHashes);
|
|
1520
|
+
return undefined;
|
|
1521
|
+
}
|
|
1522
|
+
/**
|
|
1523
|
+
* @method
|
|
1524
|
+
* @name mexc#unWatchBidsAsks
|
|
1525
|
+
* @description unWatches best bid & ask for symbols
|
|
1526
|
+
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
1527
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1528
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1529
|
+
*/
|
|
1530
|
+
async unWatchBidsAsks(symbols = undefined, params = {}) {
|
|
1531
|
+
await this.loadMarkets();
|
|
1532
|
+
symbols = this.marketSymbols(symbols, undefined, true, false, true);
|
|
1533
|
+
let marketType = undefined;
|
|
1534
|
+
if (symbols === undefined) {
|
|
1535
|
+
throw new errors.ArgumentsRequired(this.id + ' watchBidsAsks required symbols argument');
|
|
1536
|
+
}
|
|
1537
|
+
const markets = this.marketsForSymbols(symbols);
|
|
1538
|
+
[marketType, params] = this.handleMarketTypeAndParams('watchBidsAsks', markets[0], params);
|
|
1539
|
+
const isSpot = marketType === 'spot';
|
|
1540
|
+
if (!isSpot) {
|
|
1541
|
+
throw new errors.NotSupported(this.id + ' watchBidsAsks only support spot market');
|
|
1542
|
+
}
|
|
1543
|
+
const messageHashes = [];
|
|
1544
|
+
const topics = [];
|
|
1545
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1546
|
+
if (isSpot) {
|
|
1547
|
+
const market = this.market(symbols[i]);
|
|
1548
|
+
topics.push('spot@public.bookTicker.v3.api@' + market['id']);
|
|
1549
|
+
}
|
|
1550
|
+
messageHashes.push('unsubscribe:bidask:' + symbols[i]);
|
|
1551
|
+
}
|
|
1552
|
+
const url = this.urls['api']['ws']['spot'];
|
|
1553
|
+
const request = {
|
|
1554
|
+
'method': 'UNSUBSCRIPTION',
|
|
1555
|
+
'params': topics,
|
|
1556
|
+
};
|
|
1557
|
+
const client = this.client(url);
|
|
1558
|
+
this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes);
|
|
1559
|
+
this.handleUnsubscriptions(client, messageHashes);
|
|
1560
|
+
return undefined;
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* @method
|
|
1564
|
+
* @name mexc#unWatchOHLCV
|
|
1565
|
+
* @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1566
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1567
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1568
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1569
|
+
* @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
|
1570
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1571
|
+
*/
|
|
1572
|
+
async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
|
|
1573
|
+
await this.loadMarkets();
|
|
1574
|
+
const market = this.market(symbol);
|
|
1575
|
+
symbol = market['symbol'];
|
|
1576
|
+
const timeframes = this.safeValue(this.options, 'timeframes', {});
|
|
1577
|
+
const timeframeId = this.safeString(timeframes, timeframe);
|
|
1578
|
+
const messageHash = 'unsubscribe:candles:' + symbol + ':' + timeframe;
|
|
1579
|
+
let url = undefined;
|
|
1580
|
+
if (market['spot']) {
|
|
1581
|
+
url = this.urls['api']['ws']['spot'];
|
|
1582
|
+
const channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId;
|
|
1583
|
+
params['unsubscribed'] = true;
|
|
1584
|
+
this.watchSpotPublic(channel, messageHash, params);
|
|
1585
|
+
}
|
|
1586
|
+
else {
|
|
1587
|
+
url = this.urls['api']['ws']['swap'];
|
|
1588
|
+
const channel = 'unsub.kline';
|
|
1589
|
+
const requestParams = {
|
|
1590
|
+
'symbol': market['id'],
|
|
1591
|
+
'interval': timeframeId,
|
|
1592
|
+
};
|
|
1593
|
+
this.watchSwapPublic(channel, messageHash, requestParams, params);
|
|
1594
|
+
}
|
|
1595
|
+
const client = this.client(url);
|
|
1596
|
+
this.handleUnsubscriptions(client, [messageHash]);
|
|
1597
|
+
return undefined;
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* @method
|
|
1601
|
+
* @name mexc#unWatchOrderBook
|
|
1602
|
+
* @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
1603
|
+
* @param {string} symbol unified array of symbols
|
|
1604
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1605
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
1606
|
+
*/
|
|
1607
|
+
async unWatchOrderBook(symbol, params = {}) {
|
|
1608
|
+
await this.loadMarkets();
|
|
1609
|
+
const market = this.market(symbol);
|
|
1610
|
+
symbol = market['symbol'];
|
|
1611
|
+
const messageHash = 'unsubscribe:orderbook:' + symbol;
|
|
1612
|
+
let url = undefined;
|
|
1613
|
+
if (market['spot']) {
|
|
1614
|
+
url = this.urls['api']['ws']['spot'];
|
|
1615
|
+
const channel = 'spot@public.increase.depth.v3.api@' + market['id'];
|
|
1616
|
+
params['unsubscribed'] = true;
|
|
1617
|
+
this.watchSpotPublic(channel, messageHash, params);
|
|
1618
|
+
}
|
|
1619
|
+
else {
|
|
1620
|
+
url = this.urls['api']['ws']['swap'];
|
|
1621
|
+
const channel = 'unsub.depth';
|
|
1622
|
+
const requestParams = {
|
|
1623
|
+
'symbol': market['id'],
|
|
1624
|
+
};
|
|
1625
|
+
this.watchSwapPublic(channel, messageHash, requestParams, params);
|
|
1626
|
+
}
|
|
1627
|
+
const client = this.client(url);
|
|
1628
|
+
this.handleUnsubscriptions(client, [messageHash]);
|
|
1629
|
+
return undefined;
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* @method
|
|
1633
|
+
* @name mexc#unWatchTrades
|
|
1634
|
+
* @description unsubscribes from the trades channel
|
|
1635
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1636
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1637
|
+
* @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
|
1638
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1639
|
+
*/
|
|
1640
|
+
async unWatchTrades(symbol, params = {}) {
|
|
1641
|
+
await this.loadMarkets();
|
|
1642
|
+
const market = this.market(symbol);
|
|
1643
|
+
symbol = market['symbol'];
|
|
1644
|
+
const messageHash = 'unsubscribe:trades:' + symbol;
|
|
1645
|
+
let url = undefined;
|
|
1646
|
+
if (market['spot']) {
|
|
1647
|
+
url = this.urls['api']['ws']['spot'];
|
|
1648
|
+
const channel = 'spot@public.deals.v3.api@' + market['id'];
|
|
1649
|
+
params['unsubscribed'] = true;
|
|
1650
|
+
this.watchSpotPublic(channel, messageHash, params);
|
|
1651
|
+
}
|
|
1652
|
+
else {
|
|
1653
|
+
url = this.urls['api']['ws']['swap'];
|
|
1654
|
+
const channel = 'unsub.deal';
|
|
1655
|
+
const requestParams = {
|
|
1656
|
+
'symbol': market['id'],
|
|
1657
|
+
};
|
|
1658
|
+
this.watchSwapPublic(channel, messageHash, requestParams, params);
|
|
1659
|
+
}
|
|
1660
|
+
const client = this.client(url);
|
|
1661
|
+
this.handleUnsubscriptions(client, [messageHash]);
|
|
1662
|
+
return undefined;
|
|
1663
|
+
}
|
|
1664
|
+
handleUnsubscriptions(client, messageHashes) {
|
|
1665
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
1666
|
+
const messageHash = messageHashes[i];
|
|
1667
|
+
const subMessageHash = messageHash.replace('unsubscribe:', '');
|
|
1668
|
+
this.cleanUnsubscription(client, subMessageHash, messageHash);
|
|
1669
|
+
if (messageHash.indexOf('ticker') >= 0) {
|
|
1670
|
+
const symbol = messageHash.replace('unsubscribe:ticker:', '');
|
|
1671
|
+
if (symbol.indexOf('unsubscribe') >= 0) {
|
|
1672
|
+
// unWatchTickers
|
|
1673
|
+
const symbols = Object.keys(this.tickers);
|
|
1674
|
+
for (let j = 0; j < symbols.length; j++) {
|
|
1675
|
+
delete this.tickers[symbols[j]];
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
else if (symbol in this.tickers) {
|
|
1679
|
+
delete this.tickers[symbol];
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
else if (messageHash.indexOf('bidask') >= 0) {
|
|
1683
|
+
const symbol = messageHash.replace('unsubscribe:bidask:', '');
|
|
1684
|
+
if (symbol in this.bidsasks) {
|
|
1685
|
+
delete this.bidsasks[symbol];
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
else if (messageHash.indexOf('candles') >= 0) {
|
|
1689
|
+
const splitHashes = messageHash.split(':');
|
|
1690
|
+
let symbol = this.safeString(splitHashes, 2);
|
|
1691
|
+
if (splitHashes.length > 4) {
|
|
1692
|
+
symbol += ':' + this.safeString(splitHashes, 3);
|
|
1693
|
+
}
|
|
1694
|
+
if (symbol in this.ohlcvs) {
|
|
1695
|
+
delete this.ohlcvs[symbol];
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
else if (messageHash.indexOf('orderbook') >= 0) {
|
|
1699
|
+
const symbol = messageHash.replace('unsubscribe:orderbook:', '');
|
|
1700
|
+
if (symbol in this.orderbooks) {
|
|
1701
|
+
delete this.orderbooks[symbol];
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
else if (messageHash.indexOf('trades') >= 0) {
|
|
1705
|
+
const symbol = messageHash.replace('unsubscribe:trades:', '');
|
|
1706
|
+
if (symbol in this.trades) {
|
|
1707
|
+
delete this.trades[symbol];
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1415
1712
|
async authenticate(subscriptionHash, params = {}) {
|
|
1416
1713
|
// we only need one listenKey since ccxt shares connections
|
|
1417
1714
|
let listenKey = this.safeString(this.options, 'listenKey');
|
|
@@ -249,7 +249,9 @@ class poloniex extends poloniex$1 {
|
|
|
249
249
|
request['price'] = this.priceToPrecision(symbol, price);
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
|
-
|
|
252
|
+
const orders = await this.tradeRequest('createOrder', this.extend(request, params));
|
|
253
|
+
const order = this.safeDict(orders, 0);
|
|
254
|
+
return order;
|
|
253
255
|
}
|
|
254
256
|
/**
|
|
255
257
|
* @method
|
|
@@ -268,7 +270,9 @@ class poloniex extends poloniex$1 {
|
|
|
268
270
|
const clientOrderIds = this.safeValue(params, 'clientOrderId', []);
|
|
269
271
|
params['clientOrderIds'] = this.arrayConcat(clientOrderIds, [clientOrderId]);
|
|
270
272
|
}
|
|
271
|
-
|
|
273
|
+
const orders = await this.cancelOrdersWs([id], symbol, params);
|
|
274
|
+
const order = this.safeDict(orders, 0);
|
|
275
|
+
return order;
|
|
272
276
|
}
|
|
273
277
|
/**
|
|
274
278
|
* @method
|
package/examples/js/cli.js
CHANGED
|
@@ -15,6 +15,21 @@ const { ExchangeError , NetworkError} = ccxt
|
|
|
15
15
|
function jsonStringify (obj, indent = undefined) {
|
|
16
16
|
return JSON.stringify (obj, function(k, v) { return v === undefined ? null : v; }, indent);
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
function countAllParams(fn) {
|
|
21
|
+
const fnStr = fn.toString()
|
|
22
|
+
.replace(/\/\/.*$/mg, '')
|
|
23
|
+
.replace(/\/\*[\s\S]*?\*\//mg, '')
|
|
24
|
+
.replace(/\s+/g, '');
|
|
25
|
+
|
|
26
|
+
const match = fnStr.match(/^[^(]*\(([^)]*)\)/);
|
|
27
|
+
if (!match) return 0;
|
|
28
|
+
|
|
29
|
+
const params = match[1].split(',').filter(p => p);
|
|
30
|
+
return params.length;
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
//-----------------------------------------------------------------------------
|
|
19
34
|
|
|
20
35
|
let [processPath, , exchangeId, methodName, ... params] = process.argv.filter (x => !x.startsWith ('--'))
|
|
@@ -45,19 +60,63 @@ let [processPath, , exchangeId, methodName, ... params] = process.argv.filter (x
|
|
|
45
60
|
, noKeys = process.argv.includes ('--no-keys')
|
|
46
61
|
|
|
47
62
|
let foundDescription = undefined;
|
|
63
|
+
const nameIndex = process.argv.indexOf ('--name')
|
|
64
|
+
if (nameIndex >= 0) {
|
|
65
|
+
foundDescription = process.argv[nameIndex + 1];
|
|
66
|
+
// search that string in `params` and remove it
|
|
67
|
+
const index = params.indexOf (foundDescription)
|
|
68
|
+
if (index >= 0) {
|
|
69
|
+
params.splice (index, 1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let lastParamObject
|
|
74
|
+
let symbol
|
|
48
75
|
for (let i = 0; i < process.argv.length; i++) {
|
|
49
|
-
if (process.argv[i] === '--
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
76
|
+
if (process.argv[i] === '--param') {
|
|
77
|
+
const nextParam = process.argv[i + 1]
|
|
78
|
+
if (nextParam) {
|
|
79
|
+
const paramIndex = params.indexOf (nextParam)
|
|
80
|
+
if (paramIndex >= 0) {
|
|
81
|
+
if (nextParam.indexOf('=') >= 0) {
|
|
82
|
+
const parsed = nextParam.split('=')
|
|
83
|
+
if (parsed.length === 2) {
|
|
84
|
+
if (!lastParamObject) {
|
|
85
|
+
lastParamObject = {}
|
|
86
|
+
}
|
|
87
|
+
const key = parsed[0];
|
|
88
|
+
const value = parsed[1];
|
|
89
|
+
if (key === 'symbol') {
|
|
90
|
+
symbol = value
|
|
91
|
+
}
|
|
92
|
+
lastParamObject[key] = value
|
|
93
|
+
params.splice(paramIndex, 1)
|
|
94
|
+
} else {
|
|
95
|
+
throw new Error ('Invalid usage of --param. Please provide a key=value pair after --param.')
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
if (!lastParamObject) {
|
|
99
|
+
lastParamObject = {}
|
|
100
|
+
}
|
|
101
|
+
lastParamObject[nextParam] = true
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
throw new Error (`Unexpected error by parsing parameters: ${nextParam} is not found in params array.`)
|
|
56
105
|
}
|
|
106
|
+
} else {
|
|
107
|
+
throw new Error ('Invalid usage of --param. Please provide a value after --param.')
|
|
57
108
|
}
|
|
58
|
-
break;
|
|
59
109
|
}
|
|
60
110
|
}
|
|
111
|
+
|
|
112
|
+
let lastParam = params[params.length - 1]
|
|
113
|
+
// exclude parasitic single quotes. Can happen on some shell processors
|
|
114
|
+
if (lastParam?.includes('{') && lastParam?.includes('}')) {
|
|
115
|
+
if (lastParam.startsWith('\'{') && lastParam.endsWith('}\'')) {
|
|
116
|
+
lastParam = params[params.length - 1] = lastParam.substring(1, lastParam.length - 1)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
61
120
|
//-----------------------------------------------------------------------------
|
|
62
121
|
if (!raw) {
|
|
63
122
|
log ((new Date ()).toISOString())
|
|
@@ -213,6 +272,7 @@ function printUsage () {
|
|
|
213
272
|
log ('node', process.argv[1], 'okcoin fetchOHLCV BTC/USD 15m')
|
|
214
273
|
log ('node', process.argv[1], 'bitfinex fetchBalance')
|
|
215
274
|
log ('node', process.argv[1], 'kraken fetchOrderBook ETH/BTC')
|
|
275
|
+
log ('node', process.argv[1], 'binanceusdm fetchTrades BTC/USDC undefined undefined --param until=1746988377067')
|
|
216
276
|
printSupportedExchanges ()
|
|
217
277
|
log ('Supported options:')
|
|
218
278
|
log ('--verbose Print verbose output')
|
|
@@ -224,6 +284,8 @@ function printUsage () {
|
|
|
224
284
|
log ('--no-table Do not print the fetch response as a table')
|
|
225
285
|
log ('--table Print the fetch response as a table')
|
|
226
286
|
log ('--iso8601 Print timestamps as ISO8601 datetimes')
|
|
287
|
+
log ('--param key=value Set a custom key=value pair for the last method\'s argument. Can be repeated multiple times')
|
|
288
|
+
log (' NOTE: don\'t forget to fill up missed arguments with "undefined" before last options parameter')
|
|
227
289
|
log ('--cors use CORS proxy for debugging')
|
|
228
290
|
log ('--sign-in Call signIn() if any')
|
|
229
291
|
log ('--sandbox Use the exchange sandbox if available, same as --testnet')
|
|
@@ -306,10 +368,16 @@ async function run () {
|
|
|
306
368
|
|
|
307
369
|
let args = params
|
|
308
370
|
.map (s => s.match (/^[0-9]{4}[-][0-9]{2}[-][0-9]{2}[T\s]?[0-9]{2}[:][0-9]{2}[:][0-9]{2}/g) ? exchange.parse8601 (s) : s)
|
|
309
|
-
.map (s =>
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
371
|
+
.map (s => {
|
|
372
|
+
return (() => {
|
|
373
|
+
if (s.match(/^\d+$/g)) return s < Number.MAX_SAFE_INTEGER ? Number(s) : s
|
|
374
|
+
try {
|
|
375
|
+
return eval('(() => (' + s + ')) ()')
|
|
376
|
+
} catch (e) {
|
|
377
|
+
return s
|
|
378
|
+
}
|
|
379
|
+
})();
|
|
380
|
+
})
|
|
313
381
|
|
|
314
382
|
const www = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
|
|
315
383
|
|
|
@@ -337,6 +405,34 @@ async function run () {
|
|
|
337
405
|
}
|
|
338
406
|
}
|
|
339
407
|
}
|
|
408
|
+
if (symbol && lastParamObject) {
|
|
409
|
+
let marketId
|
|
410
|
+
try {
|
|
411
|
+
marketId = exchange.marketId(symbol)
|
|
412
|
+
} catch (e) {
|
|
413
|
+
// noop possible loaded from cache
|
|
414
|
+
}
|
|
415
|
+
if (!marketId) {
|
|
416
|
+
try {
|
|
417
|
+
await exchange.loadMarkets();
|
|
418
|
+
marketId = exchange.marketId(symbol)
|
|
419
|
+
} catch (e) {
|
|
420
|
+
// noop
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (marketId) {
|
|
424
|
+
lastParamObject.symbol = marketId
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (typeof lastParamObject === 'object') {
|
|
429
|
+
const lastArgument = args[args.length - 1];
|
|
430
|
+
if (lastParam && typeof lastArgument === 'object') {
|
|
431
|
+
args[args.length - 1] = Object.assign (lastArgument, lastParamObject)
|
|
432
|
+
} else {
|
|
433
|
+
args.push (lastParamObject)
|
|
434
|
+
}
|
|
435
|
+
}
|
|
340
436
|
|
|
341
437
|
if (signIn && exchange.has.signIn) {
|
|
342
438
|
await exchange.signIn ()
|
|
@@ -363,7 +459,10 @@ async function run () {
|
|
|
363
459
|
|
|
364
460
|
if (typeof exchange[methodName] === 'function') {
|
|
365
461
|
|
|
366
|
-
if (!raw
|
|
462
|
+
if (!raw || details) {
|
|
463
|
+
const methodArgsPrint = JSON.stringify(args);
|
|
464
|
+
log(exchange.id + '.' + methodName, '(' + methodArgsPrint.substring(1, methodArgsPrint.length - 1) + ')')
|
|
465
|
+
}
|
|
367
466
|
|
|
368
467
|
let start = exchange.milliseconds ()
|
|
369
468
|
let end = exchange.milliseconds ()
|
|
@@ -377,6 +476,21 @@ async function run () {
|
|
|
377
476
|
|
|
378
477
|
while (true) {
|
|
379
478
|
try {
|
|
479
|
+
const fn = exchange[methodName]
|
|
480
|
+
const fnParams = countAllParams(fn)
|
|
481
|
+
const argsContainsParams = args.find( arg=> arg && typeof arg === 'object' && !Array.isArray(arg) && Object.keys(arg).length > 0)
|
|
482
|
+
if (argsContainsParams && fnParams !== args.length) {
|
|
483
|
+
// populate the missing params with undefined
|
|
484
|
+
const missingParams = fnParams - args.length
|
|
485
|
+
const paramsObj = args[args.length - 1]
|
|
486
|
+
args.pop()
|
|
487
|
+
const newArgsArray = args;
|
|
488
|
+
for (let i = 0; i < missingParams; i++) {
|
|
489
|
+
newArgsArray.push(undefined)
|
|
490
|
+
}
|
|
491
|
+
newArgsArray.push(paramsObj)
|
|
492
|
+
args = newArgsArray
|
|
493
|
+
}
|
|
380
494
|
const result = await exchange[methodName] (... args)
|
|
381
495
|
end = exchange.milliseconds ()
|
|
382
496
|
if (!isWsMethod && !raw) {
|