ccxt 4.0.66 → 4.0.68
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 +3 -12
- package/dist/ccxt.browser.js +166 -59
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +1 -1
- package/dist/cjs/src/binance.js +1 -0
- package/dist/cjs/src/bitget.js +8 -1
- package/dist/cjs/src/bybit.js +12 -2
- package/dist/cjs/src/lykke.js +1 -1
- package/dist/cjs/src/phemex.js +2 -1
- package/dist/cjs/src/pro/binance.js +1 -1
- package/dist/cjs/src/pro/bitfinex2.js +7 -6
- package/dist/cjs/src/pro/bitget.js +10 -7
- package/dist/cjs/src/pro/bitmart.js +7 -6
- package/dist/cjs/src/pro/bittrex.js +2 -3
- package/dist/cjs/src/pro/bybit.js +3 -2
- package/dist/cjs/src/pro/coinbasepro.js +71 -9
- package/dist/cjs/src/pro/huobi.js +4 -2
- package/dist/cjs/src/pro/idex.js +1 -1
- package/dist/cjs/src/wavesexchange.js +34 -15
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/base/Exchange.js +1 -1
- package/js/src/binance.js +1 -0
- package/js/src/bitget.js +8 -1
- package/js/src/bybit.js +12 -2
- package/js/src/lykke.js +1 -1
- package/js/src/phemex.js +2 -1
- package/js/src/pro/binance.js +1 -1
- package/js/src/pro/bitfinex2.d.ts +1 -1
- package/js/src/pro/bitfinex2.js +7 -6
- package/js/src/pro/bitget.d.ts +1 -1
- package/js/src/pro/bitget.js +10 -7
- package/js/src/pro/bitmart.d.ts +1 -1
- package/js/src/pro/bitmart.js +7 -6
- package/js/src/pro/bittrex.js +2 -3
- package/js/src/pro/bybit.js +3 -2
- package/js/src/pro/coinbasepro.d.ts +3 -1
- package/js/src/pro/coinbasepro.js +71 -9
- package/js/src/pro/huobi.js +4 -2
- package/js/src/pro/idex.js +1 -1
- package/js/src/wavesexchange.d.ts +2 -1
- package/js/src/wavesexchange.js +34 -15
- package/package.json +1 -1
package/dist/cjs/ccxt.js
CHANGED
|
@@ -180,7 +180,7 @@ var woo$1 = require('./src/pro/woo.js');
|
|
|
180
180
|
|
|
181
181
|
//-----------------------------------------------------------------------------
|
|
182
182
|
// this is updated by vss.js when building
|
|
183
|
-
const version = '4.0.
|
|
183
|
+
const version = '4.0.68';
|
|
184
184
|
Exchange["default"].ccxtVersion = version;
|
|
185
185
|
const exchanges = {
|
|
186
186
|
'ace': ace,
|
|
@@ -1300,7 +1300,7 @@ class Exchange {
|
|
|
1300
1300
|
throw new errors.NotSupported(this.id + ' fetchOrderBook() is not supported yet');
|
|
1301
1301
|
}
|
|
1302
1302
|
async fetchRestOrderBookSafe(symbol, limit = undefined, params = {}) {
|
|
1303
|
-
const fetchSnapshotMaxRetries = this.handleOption('watchOrderBook', '
|
|
1303
|
+
const fetchSnapshotMaxRetries = this.handleOption('watchOrderBook', 'maxRetries', 3);
|
|
1304
1304
|
for (let i = 0; i < fetchSnapshotMaxRetries; i++) {
|
|
1305
1305
|
try {
|
|
1306
1306
|
const orderBook = await this.fetchOrderBook(symbol, limit, params);
|
package/dist/cjs/src/binance.js
CHANGED
|
@@ -1501,6 +1501,7 @@ class binance extends binance$1 {
|
|
|
1501
1501
|
'-4045': errors.ExchangeError,
|
|
1502
1502
|
'-4046': errors.AuthenticationError,
|
|
1503
1503
|
'-4047': errors.BadRequest,
|
|
1504
|
+
'-4054': errors.BadRequest,
|
|
1504
1505
|
'-5001': errors.BadRequest,
|
|
1505
1506
|
'-5002': errors.InsufficientFunds,
|
|
1506
1507
|
'-5003': errors.InsufficientFunds,
|
package/dist/cjs/src/bitget.js
CHANGED
|
@@ -2451,8 +2451,9 @@ class bitget extends bitget$1 {
|
|
|
2451
2451
|
'symbol': market['id'],
|
|
2452
2452
|
};
|
|
2453
2453
|
const until = this.safeInteger2(params, 'until', 'till');
|
|
2454
|
+
const limitIsUndefined = (limit === undefined);
|
|
2454
2455
|
if (limit === undefined) {
|
|
2455
|
-
limit =
|
|
2456
|
+
limit = 200;
|
|
2456
2457
|
}
|
|
2457
2458
|
request['limit'] = limit;
|
|
2458
2459
|
const marketType = market['spot'] ? 'spot' : 'swap';
|
|
@@ -2498,6 +2499,9 @@ class bitget extends bitget$1 {
|
|
|
2498
2499
|
const method = this.safeString(params, 'method', defaultSpotMethod);
|
|
2499
2500
|
params = this.omit(params, 'method');
|
|
2500
2501
|
if (method === 'publicSpotGetMarketCandles') {
|
|
2502
|
+
if (limitIsUndefined) {
|
|
2503
|
+
request['limit'] = 1000;
|
|
2504
|
+
}
|
|
2501
2505
|
response = await this.publicSpotGetMarketCandles(this.extend(request, params));
|
|
2502
2506
|
}
|
|
2503
2507
|
else if (method === 'publicSpotGetMarketHistoryCandles') {
|
|
@@ -2517,6 +2521,9 @@ class bitget extends bitget$1 {
|
|
|
2517
2521
|
response = await this.publicMixGetMarketHistoryIndexCandles(this.extend(request, params));
|
|
2518
2522
|
}
|
|
2519
2523
|
else if (swapMethod === 'publicMixGetMarketCandles') {
|
|
2524
|
+
if (limitIsUndefined) {
|
|
2525
|
+
request['limit'] = 1000;
|
|
2526
|
+
}
|
|
2520
2527
|
response = await this.publicMixGetMarketCandles(this.extend(request, params));
|
|
2521
2528
|
}
|
|
2522
2529
|
else if (swapMethod === 'publicMixGetMarketHistoryCandles') {
|
package/dist/cjs/src/bybit.js
CHANGED
|
@@ -1385,6 +1385,16 @@ class bybit extends bybit$1 {
|
|
|
1385
1385
|
}
|
|
1386
1386
|
else if (symbol in this.markets_by_id) {
|
|
1387
1387
|
const markets = this.markets_by_id[symbol];
|
|
1388
|
+
let defaultType = this.safeString2(this.options, 'defaultType', 'defaultSubType', 'spot');
|
|
1389
|
+
if (defaultType === 'future') {
|
|
1390
|
+
defaultType = 'contract';
|
|
1391
|
+
}
|
|
1392
|
+
for (let i = 0; i < markets.length; i++) {
|
|
1393
|
+
const market = markets[i];
|
|
1394
|
+
if (market[defaultType]) {
|
|
1395
|
+
return market;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1388
1398
|
return markets[0];
|
|
1389
1399
|
}
|
|
1390
1400
|
else if ((symbol.indexOf('-C') > -1) || (symbol.indexOf('-P') > -1)) {
|
|
@@ -2081,10 +2091,10 @@ class bybit extends bybit$1 {
|
|
|
2081
2091
|
// "change24h": "86"
|
|
2082
2092
|
// }
|
|
2083
2093
|
//
|
|
2094
|
+
const isSpot = this.safeString(ticker, 'openInterestValue') === undefined;
|
|
2084
2095
|
const timestamp = this.safeInteger(ticker, 'time');
|
|
2085
2096
|
const marketId = this.safeString(ticker, 'symbol');
|
|
2086
|
-
const
|
|
2087
|
-
const type = this.safeString(market, 'type', defaultType);
|
|
2097
|
+
const type = isSpot ? 'spot' : 'contract';
|
|
2088
2098
|
market = this.safeMarket(marketId, market, undefined, type);
|
|
2089
2099
|
const symbol = this.safeSymbol(marketId, market, undefined, type);
|
|
2090
2100
|
const last = this.safeString(ticker, 'lastPrice');
|
package/dist/cjs/src/lykke.js
CHANGED
package/dist/cjs/src/phemex.js
CHANGED
|
@@ -3548,6 +3548,7 @@ class phemex extends phemex$1 {
|
|
|
3548
3548
|
}
|
|
3549
3549
|
const unrealizedPnl = Precise["default"].stringMul(Precise["default"].stringMul(priceDiff, contracts), contractSizeString);
|
|
3550
3550
|
const marginRatio = Precise["default"].stringDiv(maintenanceMarginString, collateral);
|
|
3551
|
+
const isCross = this.safeValue(position, 'crossMargin');
|
|
3551
3552
|
return this.safePosition({
|
|
3552
3553
|
'info': position,
|
|
3553
3554
|
'id': undefined,
|
|
@@ -3570,7 +3571,7 @@ class phemex extends phemex$1 {
|
|
|
3570
3571
|
'maintenanceMarginPercentage': this.parseNumber(maintenanceMarginPercentageString),
|
|
3571
3572
|
'marginRatio': this.parseNumber(marginRatio),
|
|
3572
3573
|
'datetime': undefined,
|
|
3573
|
-
'marginMode':
|
|
3574
|
+
'marginMode': isCross ? 'cross' : 'isolated',
|
|
3574
3575
|
'side': side,
|
|
3575
3576
|
'hedged': false,
|
|
3576
3577
|
'percentage': undefined,
|
|
@@ -831,12 +831,13 @@ class bitfinex2 extends bitfinex2$1 {
|
|
|
831
831
|
client.subscriptions[channelId] = message;
|
|
832
832
|
return message;
|
|
833
833
|
}
|
|
834
|
-
authenticate(params = {}) {
|
|
834
|
+
async authenticate(params = {}) {
|
|
835
835
|
const url = this.urls['api']['ws']['private'];
|
|
836
836
|
const client = this.client(url);
|
|
837
837
|
const messageHash = 'authenticated';
|
|
838
|
-
|
|
839
|
-
|
|
838
|
+
const future = client.future(messageHash);
|
|
839
|
+
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
840
|
+
if (authenticated === undefined) {
|
|
840
841
|
const nonce = this.milliseconds();
|
|
841
842
|
const payload = 'AUTH' + nonce.toString();
|
|
842
843
|
const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha512.sha384, 'hex');
|
|
@@ -849,8 +850,7 @@ class bitfinex2 extends bitfinex2$1 {
|
|
|
849
850
|
'event': event,
|
|
850
851
|
};
|
|
851
852
|
const message = this.extend(request, params);
|
|
852
|
-
|
|
853
|
-
client.subscriptions[messageHash] = future;
|
|
853
|
+
this.watch(url, messageHash, message, messageHash);
|
|
854
854
|
}
|
|
855
855
|
return future;
|
|
856
856
|
}
|
|
@@ -859,7 +859,8 @@ class bitfinex2 extends bitfinex2$1 {
|
|
|
859
859
|
const status = this.safeString(message, 'status');
|
|
860
860
|
if (status === 'OK') {
|
|
861
861
|
// we resolve the future here permanently so authentication only happens once
|
|
862
|
-
client.
|
|
862
|
+
const future = this.safeValue(client.futures, messageHash);
|
|
863
|
+
future.resolve(true);
|
|
863
864
|
}
|
|
864
865
|
else {
|
|
865
866
|
const error = new errors.AuthenticationError(this.json(message));
|
|
@@ -51,7 +51,9 @@ class bitget extends bitget$1 {
|
|
|
51
51
|
'ws': {
|
|
52
52
|
'exact': {
|
|
53
53
|
'30001': errors.BadRequest,
|
|
54
|
-
'30015': errors.AuthenticationError,
|
|
54
|
+
'30015': errors.AuthenticationError,
|
|
55
|
+
'30016': errors.BadRequest,
|
|
56
|
+
'30011': errors.AuthenticationError, // { event: 'error', code: 30011, msg: 'Invalid ACCESS_KEY' }
|
|
55
57
|
},
|
|
56
58
|
},
|
|
57
59
|
},
|
|
@@ -1085,13 +1087,14 @@ class bitget extends bitget$1 {
|
|
|
1085
1087
|
const message = this.extend(request, params);
|
|
1086
1088
|
return await this.watch(url, messageHash, message, messageHash);
|
|
1087
1089
|
}
|
|
1088
|
-
authenticate(params = {}) {
|
|
1090
|
+
async authenticate(params = {}) {
|
|
1089
1091
|
this.checkRequiredCredentials();
|
|
1090
1092
|
const url = this.urls['api']['ws'];
|
|
1091
1093
|
const client = this.client(url);
|
|
1092
1094
|
const messageHash = 'authenticated';
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
+
const future = client.future(messageHash);
|
|
1096
|
+
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
1097
|
+
if (authenticated === undefined) {
|
|
1095
1098
|
const timestamp = this.seconds().toString();
|
|
1096
1099
|
const auth = timestamp + 'GET' + '/user/verify';
|
|
1097
1100
|
const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256, 'base64');
|
|
@@ -1108,8 +1111,7 @@ class bitget extends bitget$1 {
|
|
|
1108
1111
|
],
|
|
1109
1112
|
};
|
|
1110
1113
|
const message = this.extend(request, params);
|
|
1111
|
-
|
|
1112
|
-
client.subscriptions[messageHash] = future;
|
|
1114
|
+
this.watch(url, messageHash, message, messageHash);
|
|
1113
1115
|
}
|
|
1114
1116
|
return future;
|
|
1115
1117
|
}
|
|
@@ -1128,7 +1130,8 @@ class bitget extends bitget$1 {
|
|
|
1128
1130
|
// { event: 'login', code: 0 }
|
|
1129
1131
|
//
|
|
1130
1132
|
const messageHash = 'authenticated';
|
|
1131
|
-
client.
|
|
1133
|
+
const future = this.safeValue(client.futures, messageHash);
|
|
1134
|
+
future.resolve(true);
|
|
1132
1135
|
}
|
|
1133
1136
|
handleErrorMessage(client, message) {
|
|
1134
1137
|
//
|
|
@@ -482,13 +482,14 @@ class bitmart extends bitmart$1 {
|
|
|
482
482
|
}
|
|
483
483
|
return message;
|
|
484
484
|
}
|
|
485
|
-
authenticate(params = {}) {
|
|
485
|
+
async authenticate(params = {}) {
|
|
486
486
|
this.checkRequiredCredentials();
|
|
487
487
|
const url = this.implodeHostname(this.urls['api']['ws']['private']);
|
|
488
488
|
const messageHash = 'authenticated';
|
|
489
489
|
const client = this.client(url);
|
|
490
|
-
|
|
491
|
-
|
|
490
|
+
const future = client.future(messageHash);
|
|
491
|
+
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
492
|
+
if (authenticated === undefined) {
|
|
492
493
|
const timestamp = this.milliseconds().toString();
|
|
493
494
|
const memo = this.uid;
|
|
494
495
|
const path = 'bitmart.WebSocket';
|
|
@@ -504,8 +505,7 @@ class bitmart extends bitmart$1 {
|
|
|
504
505
|
],
|
|
505
506
|
};
|
|
506
507
|
const message = this.extend(request, params);
|
|
507
|
-
|
|
508
|
-
client.subscriptions[messageHash] = future;
|
|
508
|
+
this.watch(url, messageHash, message, messageHash);
|
|
509
509
|
}
|
|
510
510
|
return future;
|
|
511
511
|
}
|
|
@@ -520,7 +520,8 @@ class bitmart extends bitmart$1 {
|
|
|
520
520
|
// { event: 'login' }
|
|
521
521
|
//
|
|
522
522
|
const messageHash = 'authenticated';
|
|
523
|
-
client.
|
|
523
|
+
const future = this.safeValue(client.futures, messageHash);
|
|
524
|
+
future.resolve(true);
|
|
524
525
|
}
|
|
525
526
|
handleErrorMessage(client, message) {
|
|
526
527
|
//
|
|
@@ -43,7 +43,7 @@ class bittrex extends bittrex$1 {
|
|
|
43
43
|
'hub': 'c3',
|
|
44
44
|
'I': this.milliseconds(),
|
|
45
45
|
'watchOrderBook': {
|
|
46
|
-
'
|
|
46
|
+
'maxRetries': 3,
|
|
47
47
|
},
|
|
48
48
|
},
|
|
49
49
|
});
|
|
@@ -629,8 +629,7 @@ class bittrex extends bittrex$1 {
|
|
|
629
629
|
// then we cannot align it with the cached deltas and we need to
|
|
630
630
|
// retry synchronizing in maxAttempts
|
|
631
631
|
if ((sequence !== undefined) && (nonce < sequence)) {
|
|
632
|
-
const
|
|
633
|
-
const maxAttempts = this.safeInteger(options, 'maxAttempts', 3);
|
|
632
|
+
const maxAttempts = this.handleOption('watchOrderBook', 'maxRetries', 3);
|
|
634
633
|
let numAttempts = this.safeInteger(subscription, 'numAttempts', 0);
|
|
635
634
|
// retry to syncrhonize if we haven't reached maxAttempts yet
|
|
636
635
|
if (numAttempts < maxAttempts) {
|
|
@@ -283,7 +283,8 @@ class bybit extends bybit$1 {
|
|
|
283
283
|
const topic = this.safeString(message, 'topic', '');
|
|
284
284
|
const updateType = this.safeString(message, 'type', '');
|
|
285
285
|
const data = this.safeValue(message, 'data', {});
|
|
286
|
-
const isSpot = this.safeString(data, '
|
|
286
|
+
const isSpot = this.safeString(data, 'openInterestValue') === undefined;
|
|
287
|
+
const type = isSpot ? 'spot' : 'contract';
|
|
287
288
|
let symbol = undefined;
|
|
288
289
|
let parsed = undefined;
|
|
289
290
|
if ((updateType === 'snapshot') || isSpot) {
|
|
@@ -294,7 +295,7 @@ class bybit extends bybit$1 {
|
|
|
294
295
|
const topicParts = topic.split('.');
|
|
295
296
|
const topicLength = topicParts.length;
|
|
296
297
|
const marketId = this.safeString(topicParts, topicLength - 1);
|
|
297
|
-
const market = this.
|
|
298
|
+
const market = this.safeMarket(marketId, undefined, undefined, type);
|
|
298
299
|
symbol = market['symbol'];
|
|
299
300
|
// update the info in place
|
|
300
301
|
const ticker = this.safeValue(this.tickers, symbol, {});
|
|
@@ -15,7 +15,7 @@ class coinbasepro extends coinbasepro$1 {
|
|
|
15
15
|
'watchOHLCV': false,
|
|
16
16
|
'watchOrderBook': true,
|
|
17
17
|
'watchTicker': true,
|
|
18
|
-
'watchTickers':
|
|
18
|
+
'watchTickers': true,
|
|
19
19
|
'watchTrades': true,
|
|
20
20
|
'watchBalance': false,
|
|
21
21
|
'watchStatus': false,
|
|
@@ -50,10 +50,16 @@ class coinbasepro extends coinbasepro$1 {
|
|
|
50
50
|
'passphrase': this.password,
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
async subscribe(name, symbol, messageHashStart, params = {}) {
|
|
53
|
+
async subscribe(name, symbol = undefined, messageHashStart = undefined, params = {}) {
|
|
54
54
|
await this.loadMarkets();
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
let market = undefined;
|
|
56
|
+
let messageHash = messageHashStart;
|
|
57
|
+
const productIds = [];
|
|
58
|
+
if (symbol !== undefined) {
|
|
59
|
+
market = this.market(symbol);
|
|
60
|
+
messageHash += ':' + market['id'];
|
|
61
|
+
productIds.push(market['id']);
|
|
62
|
+
}
|
|
57
63
|
let url = this.urls['api']['ws'];
|
|
58
64
|
if ('signature' in params) {
|
|
59
65
|
// need to distinguish between public trades and user trades
|
|
@@ -61,9 +67,33 @@ class coinbasepro extends coinbasepro$1 {
|
|
|
61
67
|
}
|
|
62
68
|
const subscribe = {
|
|
63
69
|
'type': 'subscribe',
|
|
64
|
-
'product_ids':
|
|
65
|
-
|
|
70
|
+
'product_ids': productIds,
|
|
71
|
+
'channels': [
|
|
72
|
+
name,
|
|
66
73
|
],
|
|
74
|
+
};
|
|
75
|
+
const request = this.extend(subscribe, params);
|
|
76
|
+
return await this.watch(url, messageHash, request, messageHash);
|
|
77
|
+
}
|
|
78
|
+
async subscribeMultiple(name, symbols = [], messageHashStart = undefined, params = {}) {
|
|
79
|
+
await this.loadMarkets();
|
|
80
|
+
let market = undefined;
|
|
81
|
+
symbols = this.marketSymbols(symbols);
|
|
82
|
+
const messageHash = messageHashStart + symbols.join(',');
|
|
83
|
+
const productIds = [];
|
|
84
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
85
|
+
const symbol = symbols[i];
|
|
86
|
+
market = this.market(symbol);
|
|
87
|
+
productIds.push(market['id']);
|
|
88
|
+
}
|
|
89
|
+
let url = this.urls['api']['ws'];
|
|
90
|
+
if ('signature' in params) {
|
|
91
|
+
// need to distinguish between public trades and user trades
|
|
92
|
+
url = url + '?';
|
|
93
|
+
}
|
|
94
|
+
const subscribe = {
|
|
95
|
+
'type': 'subscribe',
|
|
96
|
+
'product_ids': productIds,
|
|
67
97
|
'channels': [
|
|
68
98
|
name,
|
|
69
99
|
],
|
|
@@ -83,6 +113,30 @@ class coinbasepro extends coinbasepro$1 {
|
|
|
83
113
|
const name = 'ticker';
|
|
84
114
|
return await this.subscribe(name, symbol, name, params);
|
|
85
115
|
}
|
|
116
|
+
async watchTickers(symbols = undefined, params = {}) {
|
|
117
|
+
/**
|
|
118
|
+
* @method
|
|
119
|
+
* @name okx#watchTickers
|
|
120
|
+
* @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
|
121
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
122
|
+
* @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
|
|
123
|
+
* @param {object} [params] extra parameters specific to the okx api endpoint
|
|
124
|
+
* @param {string} [params.channel] the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
|
125
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
126
|
+
*/
|
|
127
|
+
await this.loadMarkets();
|
|
128
|
+
const symbolsLength = symbols.length;
|
|
129
|
+
if (symbolsLength === 0) {
|
|
130
|
+
throw new errors.BadSymbol(this.id + ' watchTickers requires a non-empty symbols array');
|
|
131
|
+
}
|
|
132
|
+
const channel = 'ticker';
|
|
133
|
+
const messageHash = 'tickers::';
|
|
134
|
+
const newTickers = await this.subscribeMultiple(channel, symbols, messageHash, params);
|
|
135
|
+
if (this.newUpdates) {
|
|
136
|
+
return newTickers;
|
|
137
|
+
}
|
|
138
|
+
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
139
|
+
}
|
|
86
140
|
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
87
141
|
/**
|
|
88
142
|
* @method
|
|
@@ -114,9 +168,7 @@ class coinbasepro extends coinbasepro$1 {
|
|
|
114
168
|
* @param {object} [params] extra parameters specific to the coinbasepro api endpoint
|
|
115
169
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
116
170
|
*/
|
|
117
|
-
|
|
118
|
-
throw new errors.BadSymbol(this.id + ' watchMyTrades requires a symbol');
|
|
119
|
-
}
|
|
171
|
+
this.checkRequiredSymbol('watchMyTrades', symbol);
|
|
120
172
|
await this.loadMarkets();
|
|
121
173
|
symbol = this.symbol(symbol);
|
|
122
174
|
const name = 'user';
|
|
@@ -572,6 +624,16 @@ class coinbasepro extends coinbasepro$1 {
|
|
|
572
624
|
const type = this.safeString(message, 'type');
|
|
573
625
|
const messageHash = type + ':' + marketId;
|
|
574
626
|
client.resolve(ticker, messageHash);
|
|
627
|
+
const messageHashes = this.findMessageHashes(client, 'tickers::');
|
|
628
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
629
|
+
const messageHash = messageHashes[i];
|
|
630
|
+
const parts = messageHash.split('::');
|
|
631
|
+
const symbolsString = parts[1];
|
|
632
|
+
const symbols = symbolsString.split(',');
|
|
633
|
+
if (this.inArray(symbol, symbols)) {
|
|
634
|
+
client.resolve(ticker, messageHash);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
575
637
|
}
|
|
576
638
|
return message;
|
|
577
639
|
}
|
|
@@ -84,7 +84,9 @@ class huobi extends huobi$1 {
|
|
|
84
84
|
'tradesLimit': 1000,
|
|
85
85
|
'OHLCVLimit': 1000,
|
|
86
86
|
'api': 'api',
|
|
87
|
-
'
|
|
87
|
+
'watchOrderBook': {
|
|
88
|
+
'maxRetries': 3,
|
|
89
|
+
},
|
|
88
90
|
'ws': {
|
|
89
91
|
'gunzip': true,
|
|
90
92
|
},
|
|
@@ -382,7 +384,7 @@ class huobi extends huobi$1 {
|
|
|
382
384
|
const snapshotOrderBook = this.orderBook(snapshot, snapshotLimit);
|
|
383
385
|
client.resolve(snapshotOrderBook, id);
|
|
384
386
|
if ((sequence !== undefined) && (nonce < sequence)) {
|
|
385
|
-
const maxAttempts = this.
|
|
387
|
+
const maxAttempts = this.handleOption('watchOrderBook', 'maxRetries', 3);
|
|
386
388
|
let numAttempts = this.safeInteger(subscription, 'numAttempts', 0);
|
|
387
389
|
// retry to synchronize if we have not reached maxAttempts yet
|
|
388
390
|
if (numAttempts < maxAttempts) {
|
package/dist/cjs/src/pro/idex.js
CHANGED
|
@@ -34,7 +34,7 @@ class idex extends idex$1 {
|
|
|
34
34
|
'orderBookSubscriptions': {},
|
|
35
35
|
'token': undefined,
|
|
36
36
|
'watchOrderBook': {
|
|
37
|
-
'
|
|
37
|
+
'maxRetries': 3,
|
|
38
38
|
},
|
|
39
39
|
'fetchOrderBookSnapshotMaxAttempts': 10,
|
|
40
40
|
'fetchOrderBookSnapshotMaxDelay': 10000, // throw if there are no orders in 10 seconds
|
|
@@ -614,19 +614,32 @@ class wavesexchange extends wavesexchange$1 {
|
|
|
614
614
|
}
|
|
615
615
|
parseOrderBookSide(bookSide, market = undefined, limit = undefined) {
|
|
616
616
|
const precision = market['precision'];
|
|
617
|
-
const wavesPrecision = this.
|
|
618
|
-
const amountPrecision =
|
|
619
|
-
const
|
|
620
|
-
const
|
|
617
|
+
const wavesPrecision = this.safeString(this.options, 'wavesPrecision', '8');
|
|
618
|
+
const amountPrecision = '1e' + this.numberToString(precision['amount']);
|
|
619
|
+
const amountPrecisionString = this.numberToString(precision['amount']);
|
|
620
|
+
const pricePrecisionString = this.numberToString(precision['price']);
|
|
621
|
+
const difference = Precise["default"].stringSub(amountPrecisionString, pricePrecisionString);
|
|
622
|
+
const pricePrecision = '1e' + Precise["default"].stringSub(wavesPrecision, difference);
|
|
621
623
|
const result = [];
|
|
622
624
|
for (let i = 0; i < bookSide.length; i++) {
|
|
623
625
|
const entry = bookSide[i];
|
|
624
|
-
const
|
|
625
|
-
const
|
|
626
|
+
const entryPrice = this.safeString(entry, 'price', '0');
|
|
627
|
+
const entryAmount = this.safeString(entry, 'amount', '0');
|
|
628
|
+
let price = undefined;
|
|
629
|
+
let amount = undefined;
|
|
630
|
+
if ((pricePrecision !== undefined) && (entryPrice !== undefined)) {
|
|
631
|
+
price = Precise["default"].stringDiv(entryPrice, pricePrecision);
|
|
632
|
+
}
|
|
633
|
+
if ((amountPrecision !== undefined) && (entryAmount !== undefined)) {
|
|
634
|
+
amount = Precise["default"].stringDiv(entryAmount, amountPrecision);
|
|
635
|
+
}
|
|
626
636
|
if ((limit !== undefined) && (i > limit)) {
|
|
627
637
|
break;
|
|
628
638
|
}
|
|
629
|
-
result.push([
|
|
639
|
+
result.push([
|
|
640
|
+
this.parseNumber(price),
|
|
641
|
+
this.parseNumber(amount),
|
|
642
|
+
]);
|
|
630
643
|
}
|
|
631
644
|
return result;
|
|
632
645
|
}
|
|
@@ -1206,15 +1219,21 @@ class wavesexchange extends wavesexchange$1 {
|
|
|
1206
1219
|
}
|
|
1207
1220
|
customPriceToPrecision(symbol, price) {
|
|
1208
1221
|
const market = this.markets[symbol];
|
|
1209
|
-
const wavesPrecision = this.
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1222
|
+
const wavesPrecision = this.safeString(this.options, 'wavesPrecision', '8');
|
|
1223
|
+
const amount = this.numberToString(market['precision']['amount']);
|
|
1224
|
+
const precisionPrice = this.numberToString(market['precision']['price']);
|
|
1225
|
+
const difference = Precise["default"].stringSub(amount, precisionPrice);
|
|
1226
|
+
const precision = Precise["default"].stringSub(wavesPrecision, difference);
|
|
1227
|
+
const pricePrecision = this.toPrecision(price, precision).toString();
|
|
1228
|
+
return this.parseToInt(parseFloat(pricePrecision));
|
|
1212
1229
|
}
|
|
1213
1230
|
customAmountToPrecision(symbol, amount) {
|
|
1214
|
-
|
|
1231
|
+
const amountPrecision = this.numberToString(this.toPrecision(amount, this.numberToString(this.markets[symbol]['precision']['amount'])));
|
|
1232
|
+
return this.parseToInt(parseFloat(amountPrecision));
|
|
1215
1233
|
}
|
|
1216
1234
|
currencyToPrecision(code, amount, networkCode = undefined) {
|
|
1217
|
-
|
|
1235
|
+
const amountPrecision = this.numberToString(this.toPrecision(amount, this.currencies[code]['precision']));
|
|
1236
|
+
return this.parseToInt(parseFloat(amountPrecision));
|
|
1218
1237
|
}
|
|
1219
1238
|
fromPrecision(amount, scale) {
|
|
1220
1239
|
if (amount === undefined) {
|
|
@@ -1226,11 +1245,11 @@ class wavesexchange extends wavesexchange$1 {
|
|
|
1226
1245
|
return precise.toString();
|
|
1227
1246
|
}
|
|
1228
1247
|
toPrecision(amount, scale) {
|
|
1229
|
-
const amountString =
|
|
1248
|
+
const amountString = this.numberToString(amount);
|
|
1230
1249
|
const precise = new Precise["default"](amountString);
|
|
1231
|
-
precise.decimals = precise.decimals
|
|
1250
|
+
precise.decimals = Precise["default"].stringSub(precise.decimals, scale);
|
|
1232
1251
|
precise.reduce();
|
|
1233
|
-
return precise
|
|
1252
|
+
return precise;
|
|
1234
1253
|
}
|
|
1235
1254
|
currencyFromPrecision(currency, amount) {
|
|
1236
1255
|
const scale = this.currencies[currency]['precision'];
|
package/js/ccxt.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
|
|
|
4
4
|
import * as errors from './src/base/errors.js';
|
|
5
5
|
import { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax } from './src/base/types.js';
|
|
6
6
|
import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending } from './src/base/errors.js';
|
|
7
|
-
declare const version = "4.0.
|
|
7
|
+
declare const version = "4.0.67";
|
|
8
8
|
import ace from './src/ace.js';
|
|
9
9
|
import alpaca from './src/alpaca.js';
|
|
10
10
|
import ascendex from './src/ascendex.js';
|
package/js/ccxt.js
CHANGED
|
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
|
|
|
38
38
|
import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending } from './src/base/errors.js';
|
|
39
39
|
//-----------------------------------------------------------------------------
|
|
40
40
|
// this is updated by vss.js when building
|
|
41
|
-
const version = '4.0.
|
|
41
|
+
const version = '4.0.68';
|
|
42
42
|
Exchange.ccxtVersion = version;
|
|
43
43
|
//-----------------------------------------------------------------------------
|
|
44
44
|
import ace from './src/ace.js';
|
package/js/src/base/Exchange.js
CHANGED
|
@@ -1295,7 +1295,7 @@ export default class Exchange {
|
|
|
1295
1295
|
throw new NotSupported(this.id + ' fetchOrderBook() is not supported yet');
|
|
1296
1296
|
}
|
|
1297
1297
|
async fetchRestOrderBookSafe(symbol, limit = undefined, params = {}) {
|
|
1298
|
-
const fetchSnapshotMaxRetries = this.handleOption('watchOrderBook', '
|
|
1298
|
+
const fetchSnapshotMaxRetries = this.handleOption('watchOrderBook', 'maxRetries', 3);
|
|
1299
1299
|
for (let i = 0; i < fetchSnapshotMaxRetries; i++) {
|
|
1300
1300
|
try {
|
|
1301
1301
|
const orderBook = await this.fetchOrderBook(symbol, limit, params);
|
package/js/src/binance.js
CHANGED
|
@@ -1504,6 +1504,7 @@ export default class binance extends Exchange {
|
|
|
1504
1504
|
'-4045': ExchangeError,
|
|
1505
1505
|
'-4046': AuthenticationError,
|
|
1506
1506
|
'-4047': BadRequest,
|
|
1507
|
+
'-4054': BadRequest,
|
|
1507
1508
|
'-5001': BadRequest,
|
|
1508
1509
|
'-5002': InsufficientFunds,
|
|
1509
1510
|
'-5003': InsufficientFunds,
|
package/js/src/bitget.js
CHANGED
|
@@ -2454,8 +2454,9 @@ export default class bitget extends Exchange {
|
|
|
2454
2454
|
'symbol': market['id'],
|
|
2455
2455
|
};
|
|
2456
2456
|
const until = this.safeInteger2(params, 'until', 'till');
|
|
2457
|
+
const limitIsUndefined = (limit === undefined);
|
|
2457
2458
|
if (limit === undefined) {
|
|
2458
|
-
limit =
|
|
2459
|
+
limit = 200;
|
|
2459
2460
|
}
|
|
2460
2461
|
request['limit'] = limit;
|
|
2461
2462
|
const marketType = market['spot'] ? 'spot' : 'swap';
|
|
@@ -2501,6 +2502,9 @@ export default class bitget extends Exchange {
|
|
|
2501
2502
|
const method = this.safeString(params, 'method', defaultSpotMethod);
|
|
2502
2503
|
params = this.omit(params, 'method');
|
|
2503
2504
|
if (method === 'publicSpotGetMarketCandles') {
|
|
2505
|
+
if (limitIsUndefined) {
|
|
2506
|
+
request['limit'] = 1000;
|
|
2507
|
+
}
|
|
2504
2508
|
response = await this.publicSpotGetMarketCandles(this.extend(request, params));
|
|
2505
2509
|
}
|
|
2506
2510
|
else if (method === 'publicSpotGetMarketHistoryCandles') {
|
|
@@ -2520,6 +2524,9 @@ export default class bitget extends Exchange {
|
|
|
2520
2524
|
response = await this.publicMixGetMarketHistoryIndexCandles(this.extend(request, params));
|
|
2521
2525
|
}
|
|
2522
2526
|
else if (swapMethod === 'publicMixGetMarketCandles') {
|
|
2527
|
+
if (limitIsUndefined) {
|
|
2528
|
+
request['limit'] = 1000;
|
|
2529
|
+
}
|
|
2523
2530
|
response = await this.publicMixGetMarketCandles(this.extend(request, params));
|
|
2524
2531
|
}
|
|
2525
2532
|
else if (swapMethod === 'publicMixGetMarketHistoryCandles') {
|
package/js/src/bybit.js
CHANGED
|
@@ -1388,6 +1388,16 @@ export default class bybit extends Exchange {
|
|
|
1388
1388
|
}
|
|
1389
1389
|
else if (symbol in this.markets_by_id) {
|
|
1390
1390
|
const markets = this.markets_by_id[symbol];
|
|
1391
|
+
let defaultType = this.safeString2(this.options, 'defaultType', 'defaultSubType', 'spot');
|
|
1392
|
+
if (defaultType === 'future') {
|
|
1393
|
+
defaultType = 'contract';
|
|
1394
|
+
}
|
|
1395
|
+
for (let i = 0; i < markets.length; i++) {
|
|
1396
|
+
const market = markets[i];
|
|
1397
|
+
if (market[defaultType]) {
|
|
1398
|
+
return market;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1391
1401
|
return markets[0];
|
|
1392
1402
|
}
|
|
1393
1403
|
else if ((symbol.indexOf('-C') > -1) || (symbol.indexOf('-P') > -1)) {
|
|
@@ -2084,10 +2094,10 @@ export default class bybit extends Exchange {
|
|
|
2084
2094
|
// "change24h": "86"
|
|
2085
2095
|
// }
|
|
2086
2096
|
//
|
|
2097
|
+
const isSpot = this.safeString(ticker, 'openInterestValue') === undefined;
|
|
2087
2098
|
const timestamp = this.safeInteger(ticker, 'time');
|
|
2088
2099
|
const marketId = this.safeString(ticker, 'symbol');
|
|
2089
|
-
const
|
|
2090
|
-
const type = this.safeString(market, 'type', defaultType);
|
|
2100
|
+
const type = isSpot ? 'spot' : 'contract';
|
|
2091
2101
|
market = this.safeMarket(marketId, market, undefined, type);
|
|
2092
2102
|
const symbol = this.safeSymbol(marketId, market, undefined, type);
|
|
2093
2103
|
const last = this.safeString(ticker, 'lastPrice');
|