ccxt 4.3.62 → 4.3.63
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 -3
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +2 -1
- package/dist/cjs/src/ace.js +34 -15
- package/dist/cjs/src/base/Exchange.js +8 -1
- package/dist/cjs/src/base/errors.js +8 -1
- package/dist/cjs/src/binance.js +6 -9
- package/dist/cjs/src/bingx.js +466 -151
- package/dist/cjs/src/cryptocom.js +18 -2
- package/dist/cjs/src/mercado.js +5 -1
- package/dist/cjs/src/pro/binance.js +58 -34
- package/dist/cjs/src/pro/bitfinex2.js +6 -3
- package/dist/cjs/src/pro/bitget.js +4 -1
- package/dist/cjs/src/pro/bitvavo.js +1 -1
- package/dist/cjs/src/pro/bybit.js +44 -18
- package/dist/cjs/src/pro/cryptocom.js +7 -1
- package/dist/cjs/src/pro/gate.js +6 -2
- package/dist/cjs/src/pro/htx.js +5 -1
- package/dist/cjs/src/pro/independentreserve.js +5 -3
- package/dist/cjs/src/pro/kraken.js +82 -4
- package/dist/cjs/src/pro/okx.js +3 -3
- package/dist/cjs/src/pro/poloniexfutures.js +5 -1
- package/dist/cjs/src/pro/woofipro.js +1 -1
- package/dist/cjs/src/woo.js +313 -81
- package/js/ccxt.d.ts +3 -3
- package/js/ccxt.js +3 -3
- package/js/src/abstract/cryptocom.d.ts +11 -0
- package/js/src/abstract/woo.d.ts +3 -0
- package/js/src/ace.js +34 -15
- package/js/src/base/Exchange.d.ts +1 -0
- package/js/src/base/Exchange.js +8 -1
- package/js/src/base/errorHierarchy.d.ts +3 -1
- package/js/src/base/errorHierarchy.js +3 -1
- package/js/src/base/errors.d.ts +5 -1
- package/js/src/base/errors.js +8 -2
- package/js/src/binance.js +6 -9
- package/js/src/bingx.d.ts +1 -0
- package/js/src/bingx.js +466 -151
- package/js/src/coinbaseinternational.d.ts +1 -1
- package/js/src/cryptocom.js +18 -2
- package/js/src/mercado.js +5 -1
- package/js/src/pro/binance.d.ts +1 -0
- package/js/src/pro/binance.js +59 -35
- package/js/src/pro/bitfinex2.js +7 -4
- package/js/src/pro/bitget.js +5 -2
- package/js/src/pro/bitvavo.js +1 -1
- package/js/src/pro/bybit.d.ts +1 -0
- package/js/src/pro/bybit.js +44 -18
- package/js/src/pro/cryptocom.js +8 -2
- package/js/src/pro/gate.js +7 -3
- package/js/src/pro/htx.js +6 -2
- package/js/src/pro/independentreserve.js +6 -4
- package/js/src/pro/kraken.d.ts +3 -1
- package/js/src/pro/kraken.js +83 -5
- package/js/src/pro/okx.js +4 -4
- package/js/src/pro/poloniexfutures.js +6 -2
- package/js/src/pro/woofipro.js +1 -1
- package/js/src/woo.d.ts +5 -1
- package/js/src/woo.js +313 -81
- package/js/src/xt.d.ts +3 -3
- package/package.json +1 -1
|
@@ -161,6 +161,9 @@ class cryptocom extends cryptocom$1 {
|
|
|
161
161
|
'public/get-expired-settlement-price': 10 / 3,
|
|
162
162
|
'public/get-insurance': 1,
|
|
163
163
|
},
|
|
164
|
+
'post': {
|
|
165
|
+
'public/staking/get-conversion-rate': 2,
|
|
166
|
+
},
|
|
164
167
|
},
|
|
165
168
|
'private': {
|
|
166
169
|
'post': {
|
|
@@ -190,6 +193,16 @@ class cryptocom extends cryptocom$1 {
|
|
|
190
193
|
'private/get-accounts': 10 / 3,
|
|
191
194
|
'private/get-withdrawal-history': 10 / 3,
|
|
192
195
|
'private/get-deposit-history': 10 / 3,
|
|
196
|
+
'private/staking/stake': 2,
|
|
197
|
+
'private/staking/unstake': 2,
|
|
198
|
+
'private/staking/get-staking-position': 2,
|
|
199
|
+
'private/staking/get-staking-instruments': 2,
|
|
200
|
+
'private/staking/get-open-stake': 2,
|
|
201
|
+
'private/staking/get-stake-history': 2,
|
|
202
|
+
'private/staking/get-reward-history': 2,
|
|
203
|
+
'private/staking/convert': 2,
|
|
204
|
+
'private/staking/get-open-convert': 2,
|
|
205
|
+
'private/staking/get-convert-history': 2,
|
|
193
206
|
},
|
|
194
207
|
},
|
|
195
208
|
},
|
|
@@ -815,6 +828,9 @@ class cryptocom extends cryptocom$1 {
|
|
|
815
828
|
'timeframe': this.safeString(this.timeframes, timeframe, timeframe),
|
|
816
829
|
};
|
|
817
830
|
if (limit !== undefined) {
|
|
831
|
+
if (limit > 300) {
|
|
832
|
+
limit = 300;
|
|
833
|
+
}
|
|
818
834
|
request['count'] = limit;
|
|
819
835
|
}
|
|
820
836
|
const now = this.microseconds();
|
|
@@ -822,9 +838,9 @@ class cryptocom extends cryptocom$1 {
|
|
|
822
838
|
const until = this.safeInteger(params, 'until', now);
|
|
823
839
|
params = this.omit(params, ['until']);
|
|
824
840
|
if (since !== undefined) {
|
|
825
|
-
request['start_ts'] = since;
|
|
841
|
+
request['start_ts'] = since - duration * 1000;
|
|
826
842
|
if (limit !== undefined) {
|
|
827
|
-
request['end_ts'] = this.sum(since, duration *
|
|
843
|
+
request['end_ts'] = this.sum(since, duration * limit * 1000);
|
|
828
844
|
}
|
|
829
845
|
else {
|
|
830
846
|
request['end_ts'] = until;
|
package/dist/cjs/src/mercado.js
CHANGED
|
@@ -4,6 +4,7 @@ var mercado$1 = require('./abstract/mercado.js');
|
|
|
4
4
|
var errors = require('./base/errors.js');
|
|
5
5
|
var number = require('./base/functions/number.js');
|
|
6
6
|
var sha512 = require('./static_dependencies/noble-hashes/sha512.js');
|
|
7
|
+
var Precise = require('./base/Precise.js');
|
|
7
8
|
|
|
8
9
|
// ---------------------------------------------------------------------------
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
@@ -460,7 +461,10 @@ class mercado extends mercado$1 {
|
|
|
460
461
|
if (price === undefined) {
|
|
461
462
|
throw new errors.InvalidOrder(this.id + ' createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount');
|
|
462
463
|
}
|
|
463
|
-
|
|
464
|
+
const amountString = this.numberToString(amount);
|
|
465
|
+
const priceString = this.numberToString(price);
|
|
466
|
+
const cost = this.parseToNumeric(Precise["default"].stringMul(amountString, priceString));
|
|
467
|
+
request['cost'] = this.priceToPrecision(market['symbol'], cost);
|
|
464
468
|
}
|
|
465
469
|
else {
|
|
466
470
|
request['quantity'] = this.amountToPrecision(market['symbol'], amount);
|
|
@@ -24,7 +24,7 @@ class binance extends binance$1 {
|
|
|
24
24
|
'watchBidsAsks': true,
|
|
25
25
|
'watchMyTrades': true,
|
|
26
26
|
'watchOHLCV': true,
|
|
27
|
-
'watchOHLCVForSymbols':
|
|
27
|
+
'watchOHLCVForSymbols': true,
|
|
28
28
|
'watchOrderBook': true,
|
|
29
29
|
'watchOrderBookForSymbols': true,
|
|
30
30
|
'watchOrders': true,
|
|
@@ -127,6 +127,7 @@ class binance extends binance$1 {
|
|
|
127
127
|
},
|
|
128
128
|
'watchOrderBook': {
|
|
129
129
|
'maxRetries': 3,
|
|
130
|
+
'checksum': true,
|
|
130
131
|
},
|
|
131
132
|
'watchBalance': {
|
|
132
133
|
'fetchBalanceSnapshot': false,
|
|
@@ -854,10 +855,10 @@ class binance extends binance$1 {
|
|
|
854
855
|
}
|
|
855
856
|
}
|
|
856
857
|
else {
|
|
857
|
-
const checksum = this.
|
|
858
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
858
859
|
if (checksum) {
|
|
859
860
|
// todo: client.reject from handleOrderBookMessage properly
|
|
860
|
-
throw new errors.
|
|
861
|
+
throw new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
861
862
|
}
|
|
862
863
|
}
|
|
863
864
|
}
|
|
@@ -875,10 +876,10 @@ class binance extends binance$1 {
|
|
|
875
876
|
}
|
|
876
877
|
}
|
|
877
878
|
else {
|
|
878
|
-
const checksum = this.
|
|
879
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
879
880
|
if (checksum) {
|
|
880
881
|
// todo: client.reject from handleOrderBookMessage properly
|
|
881
|
-
throw new errors.
|
|
882
|
+
throw new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
882
883
|
}
|
|
883
884
|
}
|
|
884
885
|
}
|
|
@@ -1188,40 +1189,63 @@ class binance extends binance$1 {
|
|
|
1188
1189
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1189
1190
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1190
1191
|
*/
|
|
1192
|
+
params['callerMethodName'] = 'watchOHLCV';
|
|
1193
|
+
const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
|
|
1194
|
+
return result[symbol][timeframe];
|
|
1195
|
+
}
|
|
1196
|
+
async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
|
|
1197
|
+
/**
|
|
1198
|
+
* @method
|
|
1199
|
+
* @name binance#watchOHLCVForSymbols
|
|
1200
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1201
|
+
* @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
1202
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1203
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1204
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1205
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1206
|
+
*/
|
|
1191
1207
|
await this.loadMarkets();
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
const
|
|
1195
|
-
const
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1198
|
-
if (
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1208
|
+
let klineType = undefined;
|
|
1209
|
+
[klineType, params] = this.handleParamString2(params, 'channel', 'name', 'kline');
|
|
1210
|
+
const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
|
|
1211
|
+
const marketSymbols = this.marketSymbols(symbols, undefined, false, false, true);
|
|
1212
|
+
const firstMarket = this.market(marketSymbols[0]);
|
|
1213
|
+
let type = firstMarket['type'];
|
|
1214
|
+
if (firstMarket['contract']) {
|
|
1215
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
1216
|
+
}
|
|
1217
|
+
const rawHashes = [];
|
|
1218
|
+
const messageHashes = [];
|
|
1219
|
+
for (let i = 0; i < symbolsAndTimeframes.length; i++) {
|
|
1220
|
+
const symAndTf = symbolsAndTimeframes[i];
|
|
1221
|
+
const symbolString = symAndTf[0];
|
|
1222
|
+
const timeframeString = symAndTf[1];
|
|
1223
|
+
const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
|
|
1224
|
+
const market = this.market(symbolString);
|
|
1225
|
+
let marketId = market['lowercaseId'];
|
|
1226
|
+
if (klineType === 'indexPriceKline') {
|
|
1227
|
+
// weird behavior for index price kline we can't use the perp suffix
|
|
1228
|
+
marketId = marketId.replace('_perp', '');
|
|
1229
|
+
}
|
|
1230
|
+
rawHashes.push(marketId + '@' + klineType + '_' + interval);
|
|
1231
|
+
messageHashes.push('ohlcv::' + symbolString + '::' + timeframeString);
|
|
1232
|
+
}
|
|
1233
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOHLCV');
|
|
1209
1234
|
const requestId = this.requestId(url);
|
|
1210
1235
|
const request = {
|
|
1211
1236
|
'method': 'SUBSCRIBE',
|
|
1212
|
-
'params':
|
|
1213
|
-
messageHash,
|
|
1214
|
-
],
|
|
1237
|
+
'params': rawHashes,
|
|
1215
1238
|
'id': requestId,
|
|
1216
1239
|
};
|
|
1217
1240
|
const subscribe = {
|
|
1218
1241
|
'id': requestId,
|
|
1219
1242
|
};
|
|
1220
|
-
const
|
|
1243
|
+
const [symbol, timeframe, candles] = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscribe);
|
|
1221
1244
|
if (this.newUpdates) {
|
|
1222
|
-
limit =
|
|
1245
|
+
limit = candles.getLimit(symbol, limit);
|
|
1223
1246
|
}
|
|
1224
|
-
|
|
1247
|
+
const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
|
|
1248
|
+
return this.createOHLCVObject(symbol, timeframe, filtered);
|
|
1225
1249
|
}
|
|
1226
1250
|
handleOHLCV(client, message) {
|
|
1227
1251
|
//
|
|
@@ -1262,11 +1286,9 @@ class binance extends binance$1 {
|
|
|
1262
1286
|
// indexPriceKline doesn't have the _PERP suffix
|
|
1263
1287
|
marketId = this.safeString(message, 'ps');
|
|
1264
1288
|
}
|
|
1265
|
-
const lowercaseMarketId = marketId.toLowerCase();
|
|
1266
1289
|
const interval = this.safeString(kline, 'i');
|
|
1267
1290
|
// use a reverse lookup in a static map instead
|
|
1268
|
-
const
|
|
1269
|
-
const messageHash = lowercaseMarketId + '@' + event + '_' + interval;
|
|
1291
|
+
const unifiedTimeframe = this.findTimeframe(interval);
|
|
1270
1292
|
const parsed = [
|
|
1271
1293
|
this.safeInteger(kline, 't'),
|
|
1272
1294
|
this.safeFloat(kline, 'o'),
|
|
@@ -1278,15 +1300,17 @@ class binance extends binance$1 {
|
|
|
1278
1300
|
const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
|
|
1279
1301
|
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1280
1302
|
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
1303
|
+
const messageHash = 'ohlcv::' + symbol + '::' + unifiedTimeframe;
|
|
1281
1304
|
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
|
|
1282
|
-
let stored = this.safeValue(this.ohlcvs[symbol],
|
|
1305
|
+
let stored = this.safeValue(this.ohlcvs[symbol], unifiedTimeframe);
|
|
1283
1306
|
if (stored === undefined) {
|
|
1284
1307
|
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
1285
1308
|
stored = new Cache.ArrayCacheByTimestamp(limit);
|
|
1286
|
-
this.ohlcvs[symbol][
|
|
1309
|
+
this.ohlcvs[symbol][unifiedTimeframe] = stored;
|
|
1287
1310
|
}
|
|
1288
1311
|
stored.append(parsed);
|
|
1289
|
-
|
|
1312
|
+
const resolveData = [symbol, unifiedTimeframe, stored];
|
|
1313
|
+
client.resolve(resolveData, messageHash);
|
|
1290
1314
|
}
|
|
1291
1315
|
async fetchTickerWs(symbol, params = {}) {
|
|
1292
1316
|
/**
|
|
@@ -34,9 +34,9 @@ class bitfinex2 extends bitfinex2$1 {
|
|
|
34
34
|
'watchOrderBook': {
|
|
35
35
|
'prec': 'P0',
|
|
36
36
|
'freq': 'F0',
|
|
37
|
+
'checksum': true,
|
|
37
38
|
},
|
|
38
39
|
'ordersLimit': 1000,
|
|
39
|
-
'checksum': true,
|
|
40
40
|
},
|
|
41
41
|
});
|
|
42
42
|
}
|
|
@@ -681,10 +681,13 @@ class bitfinex2 extends bitfinex2$1 {
|
|
|
681
681
|
const localChecksum = this.crc32(payload, true);
|
|
682
682
|
const responseChecksum = this.safeInteger(message, 2);
|
|
683
683
|
if (responseChecksum !== localChecksum) {
|
|
684
|
-
const error = new errors.InvalidNonce(this.id + ' invalid checksum');
|
|
685
684
|
delete client.subscriptions[messageHash];
|
|
686
685
|
delete this.orderbooks[symbol];
|
|
687
|
-
|
|
686
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
687
|
+
if (checksum) {
|
|
688
|
+
const error = new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
689
|
+
client.reject(error, messageHash);
|
|
690
|
+
}
|
|
688
691
|
}
|
|
689
692
|
}
|
|
690
693
|
async watchBalance(params = {}) {
|
|
@@ -62,6 +62,9 @@ class bitget extends bitget$1 {
|
|
|
62
62
|
'1d': '1D',
|
|
63
63
|
'1w': '1W',
|
|
64
64
|
},
|
|
65
|
+
'watchOrderBook': {
|
|
66
|
+
'checksum': true,
|
|
67
|
+
},
|
|
65
68
|
},
|
|
66
69
|
'streaming': {
|
|
67
70
|
'ping': this.ping,
|
|
@@ -559,9 +562,9 @@ class bitget extends bitget$1 {
|
|
|
559
562
|
const calculatedChecksum = this.crc32(payload, true);
|
|
560
563
|
const responseChecksum = this.safeInteger(rawOrderBook, 'checksum');
|
|
561
564
|
if (calculatedChecksum !== responseChecksum) {
|
|
562
|
-
const error = new errors.InvalidNonce(this.id + ' invalid checksum');
|
|
563
565
|
delete client.subscriptions[messageHash];
|
|
564
566
|
delete this.orderbooks[symbol];
|
|
567
|
+
const error = new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
565
568
|
client.reject(error, messageHash);
|
|
566
569
|
return;
|
|
567
570
|
}
|
|
@@ -500,7 +500,7 @@ class bitvavo extends bitvavo$1 {
|
|
|
500
500
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
501
501
|
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
502
502
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
503
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=
|
|
503
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
504
504
|
*/
|
|
505
505
|
if (symbol === undefined) {
|
|
506
506
|
throw new errors.ArgumentsRequired(this.id + ' watchMyTrades() requires a symbol argument');
|
|
@@ -28,7 +28,7 @@ class bybit extends bybit$1 {
|
|
|
28
28
|
'watchMyLiquidationsForSymbols': false,
|
|
29
29
|
'watchMyTrades': true,
|
|
30
30
|
'watchOHLCV': true,
|
|
31
|
-
'watchOHLCVForSymbols':
|
|
31
|
+
'watchOHLCVForSymbols': true,
|
|
32
32
|
'watchOrderBook': true,
|
|
33
33
|
'watchOrderBookForSymbols': true,
|
|
34
34
|
'watchOrders': true,
|
|
@@ -530,20 +530,46 @@ class bybit extends bybit$1 {
|
|
|
530
530
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
531
531
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
532
532
|
*/
|
|
533
|
+
params['callerMethodName'] = 'watchOHLCV';
|
|
534
|
+
const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
|
|
535
|
+
return result[symbol][timeframe];
|
|
536
|
+
}
|
|
537
|
+
async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
|
|
538
|
+
/**
|
|
539
|
+
* @method
|
|
540
|
+
* @name bybit#watchOHLCVForSymbols
|
|
541
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
542
|
+
* @see https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
|
543
|
+
* @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
|
544
|
+
* @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
545
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
546
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
547
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
548
|
+
* @returns {object} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
549
|
+
*/
|
|
533
550
|
await this.loadMarkets();
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
551
|
+
const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
|
|
552
|
+
const marketSymbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
553
|
+
const firstSymbol = marketSymbols[0];
|
|
554
|
+
const url = await this.getUrlByMarketType(firstSymbol, false, 'watchOHLCVForSymbols', params);
|
|
555
|
+
const rawHashes = [];
|
|
556
|
+
const messageHashes = [];
|
|
557
|
+
for (let i = 0; i < symbolsAndTimeframes.length; i++) {
|
|
558
|
+
const data = symbolsAndTimeframes[i];
|
|
559
|
+
let symbolString = this.safeString(data, 0);
|
|
560
|
+
const market = this.market(symbolString);
|
|
561
|
+
symbolString = market['symbol'];
|
|
562
|
+
const unfiedTimeframe = this.safeString(data, 1);
|
|
563
|
+
const timeframeId = this.safeString(this.timeframes, unfiedTimeframe, unfiedTimeframe);
|
|
564
|
+
rawHashes.push('kline.' + timeframeId + '.' + market['id']);
|
|
565
|
+
messageHashes.push('ohlcv::' + symbolString + '::' + unfiedTimeframe);
|
|
566
|
+
}
|
|
567
|
+
const [symbol, timeframe, stored] = await this.watchTopics(url, messageHashes, rawHashes, params);
|
|
543
568
|
if (this.newUpdates) {
|
|
544
|
-
limit =
|
|
569
|
+
limit = stored.getLimit(symbol, limit);
|
|
545
570
|
}
|
|
546
|
-
|
|
571
|
+
const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
|
|
572
|
+
return this.createOHLCVObject(symbol, timeframe, filtered);
|
|
547
573
|
}
|
|
548
574
|
handleOHLCV(client, message) {
|
|
549
575
|
//
|
|
@@ -583,18 +609,18 @@ class bybit extends bybit$1 {
|
|
|
583
609
|
if (ohlcvsByTimeframe === undefined) {
|
|
584
610
|
this.ohlcvs[symbol] = {};
|
|
585
611
|
}
|
|
586
|
-
|
|
587
|
-
if (stored === undefined) {
|
|
612
|
+
if (this.safeValue(ohlcvsByTimeframe, timeframe) === undefined) {
|
|
588
613
|
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
589
|
-
|
|
590
|
-
this.ohlcvs[symbol][timeframe] = stored;
|
|
614
|
+
this.ohlcvs[symbol][timeframe] = new Cache.ArrayCacheByTimestamp(limit);
|
|
591
615
|
}
|
|
616
|
+
const stored = this.ohlcvs[symbol][timeframe];
|
|
592
617
|
for (let i = 0; i < data.length; i++) {
|
|
593
618
|
const parsed = this.parseWsOHLCV(data[i]);
|
|
594
619
|
stored.append(parsed);
|
|
595
620
|
}
|
|
596
|
-
const messageHash = '
|
|
597
|
-
|
|
621
|
+
const messageHash = 'ohlcv::' + symbol + '::' + timeframe;
|
|
622
|
+
const resolveData = [symbol, timeframe, stored];
|
|
623
|
+
client.resolve(resolveData, messageHash);
|
|
598
624
|
}
|
|
599
625
|
parseWsOHLCV(ohlcv, market = undefined) {
|
|
600
626
|
//
|
|
@@ -44,6 +44,9 @@ class cryptocom extends cryptocom$1 {
|
|
|
44
44
|
'fetchPositionsSnapshot': true,
|
|
45
45
|
'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
|
|
46
46
|
},
|
|
47
|
+
'watchOrderBook': {
|
|
48
|
+
'checksum': true,
|
|
49
|
+
},
|
|
47
50
|
},
|
|
48
51
|
'streaming': {},
|
|
49
52
|
});
|
|
@@ -217,7 +220,10 @@ class cryptocom extends cryptocom$1 {
|
|
|
217
220
|
const previousNonce = this.safeInteger(data, 'pu');
|
|
218
221
|
const currentNonce = orderbook['nonce'];
|
|
219
222
|
if (currentNonce !== previousNonce) {
|
|
220
|
-
|
|
223
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
224
|
+
if (checksum) {
|
|
225
|
+
throw new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
226
|
+
}
|
|
221
227
|
}
|
|
222
228
|
}
|
|
223
229
|
this.handleDeltas(orderbook['asks'], this.safeValue(books, 'asks', []));
|
package/dist/cjs/src/pro/gate.js
CHANGED
|
@@ -94,6 +94,7 @@ class gate extends gate$1 {
|
|
|
94
94
|
'interval': '100ms',
|
|
95
95
|
'snapshotDelay': 10,
|
|
96
96
|
'snapshotMaxRetries': 3,
|
|
97
|
+
'checksum': true,
|
|
97
98
|
},
|
|
98
99
|
'watchBalance': {
|
|
99
100
|
'settle': 'usdt',
|
|
@@ -479,10 +480,13 @@ class gate extends gate$1 {
|
|
|
479
480
|
this.handleDelta(storedOrderBook, delta);
|
|
480
481
|
}
|
|
481
482
|
else {
|
|
482
|
-
const error = new errors.InvalidNonce(this.id + ' orderbook update has a nonce bigger than u');
|
|
483
483
|
delete client.subscriptions[messageHash];
|
|
484
484
|
delete this.orderbooks[symbol];
|
|
485
|
-
|
|
485
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
486
|
+
if (checksum) {
|
|
487
|
+
const error = new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
488
|
+
client.reject(error, messageHash);
|
|
489
|
+
}
|
|
486
490
|
}
|
|
487
491
|
client.resolve(storedOrderBook, messageHash);
|
|
488
492
|
}
|
package/dist/cjs/src/pro/htx.js
CHANGED
|
@@ -97,6 +97,7 @@ class htx extends htx$1 {
|
|
|
97
97
|
'api': 'api',
|
|
98
98
|
'watchOrderBook': {
|
|
99
99
|
'maxRetries': 3,
|
|
100
|
+
'checksum': true,
|
|
100
101
|
},
|
|
101
102
|
'ws': {
|
|
102
103
|
'gunzip': true,
|
|
@@ -568,7 +569,10 @@ class htx extends htx$1 {
|
|
|
568
569
|
orderbook['nonce'] = version;
|
|
569
570
|
}
|
|
570
571
|
if ((prevSeqNum !== undefined) && prevSeqNum > orderbook['nonce']) {
|
|
571
|
-
|
|
572
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
573
|
+
if (checksum) {
|
|
574
|
+
throw new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
575
|
+
}
|
|
572
576
|
}
|
|
573
577
|
const spotConditon = market['spot'] && (prevSeqNum === orderbook['nonce']);
|
|
574
578
|
const nonSpotCondition = market['contract'] && (version - 1 === orderbook['nonce']);
|
|
@@ -26,7 +26,9 @@ class independentreserve extends independentreserve$1 {
|
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
28
|
'options': {
|
|
29
|
-
'
|
|
29
|
+
'watchOrderBook': {
|
|
30
|
+
'checksum': true, // TODO: currently only working for snapshot
|
|
31
|
+
},
|
|
30
32
|
},
|
|
31
33
|
'streaming': {},
|
|
32
34
|
'exceptions': {},
|
|
@@ -196,7 +198,7 @@ class independentreserve extends independentreserve$1 {
|
|
|
196
198
|
orderbook['timestamp'] = timestamp;
|
|
197
199
|
orderbook['datetime'] = this.iso8601(timestamp);
|
|
198
200
|
}
|
|
199
|
-
const checksum = this.
|
|
201
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
200
202
|
if (checksum && receivedSnapshot) {
|
|
201
203
|
const storedAsks = orderbook['asks'];
|
|
202
204
|
const storedBids = orderbook['bids'];
|
|
@@ -216,7 +218,7 @@ class independentreserve extends independentreserve$1 {
|
|
|
216
218
|
const calculatedChecksum = this.crc32(payload, true);
|
|
217
219
|
const responseChecksum = this.safeInteger(orderBook, 'Crc32');
|
|
218
220
|
if (calculatedChecksum !== responseChecksum) {
|
|
219
|
-
const error = new errors.
|
|
221
|
+
const error = new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
220
222
|
delete client.subscriptions[messageHash];
|
|
221
223
|
delete this.orderbooks[symbol];
|
|
222
224
|
client.reject(error, messageHash);
|
|
@@ -12,7 +12,7 @@ class kraken extends kraken$1 {
|
|
|
12
12
|
return this.deepExtend(super.describe(), {
|
|
13
13
|
'has': {
|
|
14
14
|
'ws': true,
|
|
15
|
-
'watchBalance':
|
|
15
|
+
'watchBalance': true,
|
|
16
16
|
'watchMyTrades': true,
|
|
17
17
|
'watchOHLCV': true,
|
|
18
18
|
'watchOrderBook': true,
|
|
@@ -35,6 +35,7 @@ class kraken extends kraken$1 {
|
|
|
35
35
|
'ws': {
|
|
36
36
|
'public': 'wss://ws.kraken.com',
|
|
37
37
|
'private': 'wss://ws-auth.kraken.com',
|
|
38
|
+
'privateV2': 'wss://ws-auth.kraken.com/v2',
|
|
38
39
|
'beta': 'wss://beta-ws.kraken.com',
|
|
39
40
|
'beta-private': 'wss://beta-ws-auth.kraken.com',
|
|
40
41
|
},
|
|
@@ -48,7 +49,9 @@ class kraken extends kraken$1 {
|
|
|
48
49
|
'OHLCVLimit': 1000,
|
|
49
50
|
'ordersLimit': 1000,
|
|
50
51
|
'symbolsByOrderId': {},
|
|
51
|
-
'
|
|
52
|
+
'watchOrderBook': {
|
|
53
|
+
'checksum': true,
|
|
54
|
+
},
|
|
52
55
|
},
|
|
53
56
|
'exceptions': {
|
|
54
57
|
'ws': {
|
|
@@ -746,7 +749,7 @@ class kraken extends kraken$1 {
|
|
|
746
749
|
}
|
|
747
750
|
// don't remove this line or I will poop on your face
|
|
748
751
|
orderbook.limit();
|
|
749
|
-
const checksum = this.
|
|
752
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
750
753
|
if (checksum) {
|
|
751
754
|
const priceString = this.safeString(example, 0);
|
|
752
755
|
const amountString = this.safeString(example, 1);
|
|
@@ -768,7 +771,7 @@ class kraken extends kraken$1 {
|
|
|
768
771
|
const payload = payloadArray.join('');
|
|
769
772
|
const localChecksum = this.crc32(payload, false);
|
|
770
773
|
if (localChecksum !== c) {
|
|
771
|
-
const error = new errors.
|
|
774
|
+
const error = new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
772
775
|
delete client.subscriptions[messageHash];
|
|
773
776
|
delete this.orderbooks[symbol];
|
|
774
777
|
client.reject(error, messageHash);
|
|
@@ -1326,6 +1329,71 @@ class kraken extends kraken$1 {
|
|
|
1326
1329
|
const url = this.urls['api']['ws']['public'];
|
|
1327
1330
|
return await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), messageHashes, subscriptionArgs);
|
|
1328
1331
|
}
|
|
1332
|
+
async watchBalance(params = {}) {
|
|
1333
|
+
/**
|
|
1334
|
+
* @method
|
|
1335
|
+
* @name kraken#watchBalance
|
|
1336
|
+
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1337
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/balances
|
|
1338
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1339
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1340
|
+
*/
|
|
1341
|
+
await this.loadMarkets();
|
|
1342
|
+
const token = await this.authenticate();
|
|
1343
|
+
const messageHash = 'balances';
|
|
1344
|
+
const url = this.urls['api']['ws']['privateV2'];
|
|
1345
|
+
const requestId = this.requestId();
|
|
1346
|
+
const subscribe = {
|
|
1347
|
+
'method': 'subscribe',
|
|
1348
|
+
'req_id': requestId,
|
|
1349
|
+
'params': {
|
|
1350
|
+
'channel': 'balances',
|
|
1351
|
+
'token': token,
|
|
1352
|
+
},
|
|
1353
|
+
};
|
|
1354
|
+
const request = this.deepExtend(subscribe, params);
|
|
1355
|
+
return await this.watch(url, messageHash, request, messageHash);
|
|
1356
|
+
}
|
|
1357
|
+
handleBalance(client, message) {
|
|
1358
|
+
//
|
|
1359
|
+
// {
|
|
1360
|
+
// "channel": "balances",
|
|
1361
|
+
// "data": [
|
|
1362
|
+
// {
|
|
1363
|
+
// "asset": "BTC",
|
|
1364
|
+
// "asset_class": "currency",
|
|
1365
|
+
// "balance": 1.2,
|
|
1366
|
+
// "wallets": [
|
|
1367
|
+
// {
|
|
1368
|
+
// "type": "spot",
|
|
1369
|
+
// "id": "main",
|
|
1370
|
+
// "balance": 1.2
|
|
1371
|
+
// }
|
|
1372
|
+
// ]
|
|
1373
|
+
// }
|
|
1374
|
+
// ],
|
|
1375
|
+
// "type": "snapshot",
|
|
1376
|
+
// "sequence": 1
|
|
1377
|
+
// }
|
|
1378
|
+
//
|
|
1379
|
+
const data = this.safeList(message, 'data', []);
|
|
1380
|
+
const result = { 'info': message };
|
|
1381
|
+
for (let i = 0; i < data.length; i++) {
|
|
1382
|
+
const currencyId = this.safeString(data[i], 'asset');
|
|
1383
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1384
|
+
const account = this.account();
|
|
1385
|
+
const eq = this.safeString(data[i], 'balance');
|
|
1386
|
+
account['total'] = eq;
|
|
1387
|
+
result[code] = account;
|
|
1388
|
+
}
|
|
1389
|
+
const type = 'spot';
|
|
1390
|
+
const balance = this.safeBalance(result);
|
|
1391
|
+
const oldBalance = this.safeValue(this.balance, type, {});
|
|
1392
|
+
const newBalance = this.deepExtend(oldBalance, balance);
|
|
1393
|
+
this.balance[type] = this.safeBalance(newBalance);
|
|
1394
|
+
const channel = this.safeString(message, 'channel');
|
|
1395
|
+
client.resolve(this.balance[type], channel);
|
|
1396
|
+
}
|
|
1329
1397
|
getMessageHash(unifiedElementName, subChannelName = undefined, symbol = undefined) {
|
|
1330
1398
|
// unifiedElementName can be : orderbook, trade, ticker, bidask ...
|
|
1331
1399
|
// subChannelName only applies to channel that needs specific variation (i.e. depth_50, depth_100..) to be selected
|
|
@@ -1429,6 +1497,16 @@ class kraken extends kraken$1 {
|
|
|
1429
1497
|
}
|
|
1430
1498
|
}
|
|
1431
1499
|
else {
|
|
1500
|
+
const channel = this.safeString(message, 'channel');
|
|
1501
|
+
if (channel !== undefined) {
|
|
1502
|
+
const methods = {
|
|
1503
|
+
'balances': this.handleBalance,
|
|
1504
|
+
};
|
|
1505
|
+
const method = this.safeValue(methods, channel);
|
|
1506
|
+
if (method !== undefined) {
|
|
1507
|
+
method.call(this, client, message);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1432
1510
|
if (this.handleErrorMessage(client, message)) {
|
|
1433
1511
|
const event = this.safeString(message, 'event');
|
|
1434
1512
|
const methods = {
|