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
|
@@ -67,7 +67,7 @@ export default class coinbaseinternational extends Exchange {
|
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
69
|
setMargin(symbol: string, amount: number, params?: {}): Promise<any>;
|
|
70
|
-
fetchDepositsWithdrawals(code?:
|
|
70
|
+
fetchDepositsWithdrawals(code?: Str, since?: Int, limit?: Int, params?: {}): Promise<Transaction[]>;
|
|
71
71
|
fetchPosition(symbol: string, params?: {}): Promise<Position>;
|
|
72
72
|
parsePosition(position: Dict, market?: Market): Position;
|
|
73
73
|
fetchPositions(symbols?: Strings, params?: {}): Promise<Position[]>;
|
package/js/src/cryptocom.js
CHANGED
|
@@ -164,6 +164,9 @@ export default class cryptocom extends Exchange {
|
|
|
164
164
|
'public/get-expired-settlement-price': 10 / 3,
|
|
165
165
|
'public/get-insurance': 1,
|
|
166
166
|
},
|
|
167
|
+
'post': {
|
|
168
|
+
'public/staking/get-conversion-rate': 2,
|
|
169
|
+
},
|
|
167
170
|
},
|
|
168
171
|
'private': {
|
|
169
172
|
'post': {
|
|
@@ -193,6 +196,16 @@ export default class cryptocom extends Exchange {
|
|
|
193
196
|
'private/get-accounts': 10 / 3,
|
|
194
197
|
'private/get-withdrawal-history': 10 / 3,
|
|
195
198
|
'private/get-deposit-history': 10 / 3,
|
|
199
|
+
'private/staking/stake': 2,
|
|
200
|
+
'private/staking/unstake': 2,
|
|
201
|
+
'private/staking/get-staking-position': 2,
|
|
202
|
+
'private/staking/get-staking-instruments': 2,
|
|
203
|
+
'private/staking/get-open-stake': 2,
|
|
204
|
+
'private/staking/get-stake-history': 2,
|
|
205
|
+
'private/staking/get-reward-history': 2,
|
|
206
|
+
'private/staking/convert': 2,
|
|
207
|
+
'private/staking/get-open-convert': 2,
|
|
208
|
+
'private/staking/get-convert-history': 2,
|
|
196
209
|
},
|
|
197
210
|
},
|
|
198
211
|
},
|
|
@@ -818,6 +831,9 @@ export default class cryptocom extends Exchange {
|
|
|
818
831
|
'timeframe': this.safeString(this.timeframes, timeframe, timeframe),
|
|
819
832
|
};
|
|
820
833
|
if (limit !== undefined) {
|
|
834
|
+
if (limit > 300) {
|
|
835
|
+
limit = 300;
|
|
836
|
+
}
|
|
821
837
|
request['count'] = limit;
|
|
822
838
|
}
|
|
823
839
|
const now = this.microseconds();
|
|
@@ -825,9 +841,9 @@ export default class cryptocom extends Exchange {
|
|
|
825
841
|
const until = this.safeInteger(params, 'until', now);
|
|
826
842
|
params = this.omit(params, ['until']);
|
|
827
843
|
if (since !== undefined) {
|
|
828
|
-
request['start_ts'] = since;
|
|
844
|
+
request['start_ts'] = since - duration * 1000;
|
|
829
845
|
if (limit !== undefined) {
|
|
830
|
-
request['end_ts'] = this.sum(since, duration *
|
|
846
|
+
request['end_ts'] = this.sum(since, duration * limit * 1000);
|
|
831
847
|
}
|
|
832
848
|
else {
|
|
833
849
|
request['end_ts'] = until;
|
package/js/src/mercado.js
CHANGED
|
@@ -9,6 +9,7 @@ import Exchange from './abstract/mercado.js';
|
|
|
9
9
|
import { ExchangeError, ArgumentsRequired, InvalidOrder } from './base/errors.js';
|
|
10
10
|
import { TICK_SIZE } from './base/functions/number.js';
|
|
11
11
|
import { sha512 } from './static_dependencies/noble-hashes/sha512.js';
|
|
12
|
+
import { Precise } from './base/Precise.js';
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
13
14
|
/**
|
|
14
15
|
* @class mercado
|
|
@@ -463,7 +464,10 @@ export default class mercado extends Exchange {
|
|
|
463
464
|
if (price === undefined) {
|
|
464
465
|
throw new 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');
|
|
465
466
|
}
|
|
466
|
-
|
|
467
|
+
const amountString = this.numberToString(amount);
|
|
468
|
+
const priceString = this.numberToString(price);
|
|
469
|
+
const cost = this.parseToNumeric(Precise.stringMul(amountString, priceString));
|
|
470
|
+
request['cost'] = this.priceToPrecision(market['symbol'], cost);
|
|
467
471
|
}
|
|
468
472
|
else {
|
|
469
473
|
request['quantity'] = this.amountToPrecision(market['symbol'], amount);
|
package/js/src/pro/binance.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export default class binance extends binanceRest {
|
|
|
28
28
|
parseWsTrade(trade: any, market?: any): Trade;
|
|
29
29
|
handleTrade(client: Client, message: any): void;
|
|
30
30
|
watchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
|
|
31
|
+
watchOHLCVForSymbols(symbolsAndTimeframes: string[][], since?: Int, limit?: Int, params?: {}): Promise<import("../base/types.js").Dictionary<import("../base/types.js").Dictionary<OHLCV[]>>>;
|
|
31
32
|
handleOHLCV(client: Client, message: any): void;
|
|
32
33
|
fetchTickerWs(symbol: string, params?: {}): Promise<Ticker>;
|
|
33
34
|
fetchOHLCVWs(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
|
package/js/src/pro/binance.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// ----------------------------------------------------------------------------
|
|
8
8
|
import binanceRest from '../binance.js';
|
|
9
9
|
import { Precise } from '../base/Precise.js';
|
|
10
|
-
import {
|
|
10
|
+
import { ChecksumError, ArgumentsRequired, BadRequest, NotSupported } from '../base/errors.js';
|
|
11
11
|
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide } from '../base/ws/Cache.js';
|
|
12
12
|
import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
|
|
13
13
|
import { rsa } from '../base/functions/rsa.js';
|
|
@@ -27,7 +27,7 @@ export default class binance extends binanceRest {
|
|
|
27
27
|
'watchBidsAsks': true,
|
|
28
28
|
'watchMyTrades': true,
|
|
29
29
|
'watchOHLCV': true,
|
|
30
|
-
'watchOHLCVForSymbols':
|
|
30
|
+
'watchOHLCVForSymbols': true,
|
|
31
31
|
'watchOrderBook': true,
|
|
32
32
|
'watchOrderBookForSymbols': true,
|
|
33
33
|
'watchOrders': true,
|
|
@@ -130,6 +130,7 @@ export default class binance extends binanceRest {
|
|
|
130
130
|
},
|
|
131
131
|
'watchOrderBook': {
|
|
132
132
|
'maxRetries': 3,
|
|
133
|
+
'checksum': true,
|
|
133
134
|
},
|
|
134
135
|
'watchBalance': {
|
|
135
136
|
'fetchBalanceSnapshot': false,
|
|
@@ -857,10 +858,10 @@ export default class binance extends binanceRest {
|
|
|
857
858
|
}
|
|
858
859
|
}
|
|
859
860
|
else {
|
|
860
|
-
const checksum = this.
|
|
861
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
861
862
|
if (checksum) {
|
|
862
863
|
// todo: client.reject from handleOrderBookMessage properly
|
|
863
|
-
throw new
|
|
864
|
+
throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
864
865
|
}
|
|
865
866
|
}
|
|
866
867
|
}
|
|
@@ -878,10 +879,10 @@ export default class binance extends binanceRest {
|
|
|
878
879
|
}
|
|
879
880
|
}
|
|
880
881
|
else {
|
|
881
|
-
const checksum = this.
|
|
882
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
882
883
|
if (checksum) {
|
|
883
884
|
// todo: client.reject from handleOrderBookMessage properly
|
|
884
|
-
throw new
|
|
885
|
+
throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
885
886
|
}
|
|
886
887
|
}
|
|
887
888
|
}
|
|
@@ -1191,40 +1192,63 @@ export default class binance extends binanceRest {
|
|
|
1191
1192
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1192
1193
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1193
1194
|
*/
|
|
1195
|
+
params['callerMethodName'] = 'watchOHLCV';
|
|
1196
|
+
const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
|
|
1197
|
+
return result[symbol][timeframe];
|
|
1198
|
+
}
|
|
1199
|
+
async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
|
|
1200
|
+
/**
|
|
1201
|
+
* @method
|
|
1202
|
+
* @name binance#watchOHLCVForSymbols
|
|
1203
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1204
|
+
* @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
1205
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1206
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1207
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1208
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1209
|
+
*/
|
|
1194
1210
|
await this.loadMarkets();
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
const
|
|
1198
|
-
const
|
|
1199
|
-
const
|
|
1200
|
-
|
|
1201
|
-
if (
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1211
|
+
let klineType = undefined;
|
|
1212
|
+
[klineType, params] = this.handleParamString2(params, 'channel', 'name', 'kline');
|
|
1213
|
+
const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
|
|
1214
|
+
const marketSymbols = this.marketSymbols(symbols, undefined, false, false, true);
|
|
1215
|
+
const firstMarket = this.market(marketSymbols[0]);
|
|
1216
|
+
let type = firstMarket['type'];
|
|
1217
|
+
if (firstMarket['contract']) {
|
|
1218
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
1219
|
+
}
|
|
1220
|
+
const rawHashes = [];
|
|
1221
|
+
const messageHashes = [];
|
|
1222
|
+
for (let i = 0; i < symbolsAndTimeframes.length; i++) {
|
|
1223
|
+
const symAndTf = symbolsAndTimeframes[i];
|
|
1224
|
+
const symbolString = symAndTf[0];
|
|
1225
|
+
const timeframeString = symAndTf[1];
|
|
1226
|
+
const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
|
|
1227
|
+
const market = this.market(symbolString);
|
|
1228
|
+
let marketId = market['lowercaseId'];
|
|
1229
|
+
if (klineType === 'indexPriceKline') {
|
|
1230
|
+
// weird behavior for index price kline we can't use the perp suffix
|
|
1231
|
+
marketId = marketId.replace('_perp', '');
|
|
1232
|
+
}
|
|
1233
|
+
rawHashes.push(marketId + '@' + klineType + '_' + interval);
|
|
1234
|
+
messageHashes.push('ohlcv::' + symbolString + '::' + timeframeString);
|
|
1235
|
+
}
|
|
1236
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOHLCV');
|
|
1212
1237
|
const requestId = this.requestId(url);
|
|
1213
1238
|
const request = {
|
|
1214
1239
|
'method': 'SUBSCRIBE',
|
|
1215
|
-
'params':
|
|
1216
|
-
messageHash,
|
|
1217
|
-
],
|
|
1240
|
+
'params': rawHashes,
|
|
1218
1241
|
'id': requestId,
|
|
1219
1242
|
};
|
|
1220
1243
|
const subscribe = {
|
|
1221
1244
|
'id': requestId,
|
|
1222
1245
|
};
|
|
1223
|
-
const
|
|
1246
|
+
const [symbol, timeframe, candles] = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscribe);
|
|
1224
1247
|
if (this.newUpdates) {
|
|
1225
|
-
limit =
|
|
1248
|
+
limit = candles.getLimit(symbol, limit);
|
|
1226
1249
|
}
|
|
1227
|
-
|
|
1250
|
+
const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
|
|
1251
|
+
return this.createOHLCVObject(symbol, timeframe, filtered);
|
|
1228
1252
|
}
|
|
1229
1253
|
handleOHLCV(client, message) {
|
|
1230
1254
|
//
|
|
@@ -1265,11 +1289,9 @@ export default class binance extends binanceRest {
|
|
|
1265
1289
|
// indexPriceKline doesn't have the _PERP suffix
|
|
1266
1290
|
marketId = this.safeString(message, 'ps');
|
|
1267
1291
|
}
|
|
1268
|
-
const lowercaseMarketId = marketId.toLowerCase();
|
|
1269
1292
|
const interval = this.safeString(kline, 'i');
|
|
1270
1293
|
// use a reverse lookup in a static map instead
|
|
1271
|
-
const
|
|
1272
|
-
const messageHash = lowercaseMarketId + '@' + event + '_' + interval;
|
|
1294
|
+
const unifiedTimeframe = this.findTimeframe(interval);
|
|
1273
1295
|
const parsed = [
|
|
1274
1296
|
this.safeInteger(kline, 't'),
|
|
1275
1297
|
this.safeFloat(kline, 'o'),
|
|
@@ -1281,15 +1303,17 @@ export default class binance extends binanceRest {
|
|
|
1281
1303
|
const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
|
|
1282
1304
|
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1283
1305
|
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
1306
|
+
const messageHash = 'ohlcv::' + symbol + '::' + unifiedTimeframe;
|
|
1284
1307
|
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
|
|
1285
|
-
let stored = this.safeValue(this.ohlcvs[symbol],
|
|
1308
|
+
let stored = this.safeValue(this.ohlcvs[symbol], unifiedTimeframe);
|
|
1286
1309
|
if (stored === undefined) {
|
|
1287
1310
|
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
1288
1311
|
stored = new ArrayCacheByTimestamp(limit);
|
|
1289
|
-
this.ohlcvs[symbol][
|
|
1312
|
+
this.ohlcvs[symbol][unifiedTimeframe] = stored;
|
|
1290
1313
|
}
|
|
1291
1314
|
stored.append(parsed);
|
|
1292
|
-
|
|
1315
|
+
const resolveData = [symbol, unifiedTimeframe, stored];
|
|
1316
|
+
client.resolve(resolveData, messageHash);
|
|
1293
1317
|
}
|
|
1294
1318
|
async fetchTickerWs(symbol, params = {}) {
|
|
1295
1319
|
/**
|
package/js/src/pro/bitfinex2.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import bitfinex2Rest from '../bitfinex2.js';
|
|
9
9
|
import { Precise } from '../base/Precise.js';
|
|
10
|
-
import { ExchangeError, AuthenticationError,
|
|
10
|
+
import { ExchangeError, AuthenticationError, ChecksumError } from '../base/errors.js';
|
|
11
11
|
import { ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp } from '../base/ws/Cache.js';
|
|
12
12
|
import { sha384 } from '../static_dependencies/noble-hashes/sha512.js';
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
@@ -37,9 +37,9 @@ export default class bitfinex2 extends bitfinex2Rest {
|
|
|
37
37
|
'watchOrderBook': {
|
|
38
38
|
'prec': 'P0',
|
|
39
39
|
'freq': 'F0',
|
|
40
|
+
'checksum': true,
|
|
40
41
|
},
|
|
41
42
|
'ordersLimit': 1000,
|
|
42
|
-
'checksum': true,
|
|
43
43
|
},
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -684,10 +684,13 @@ export default class bitfinex2 extends bitfinex2Rest {
|
|
|
684
684
|
const localChecksum = this.crc32(payload, true);
|
|
685
685
|
const responseChecksum = this.safeInteger(message, 2);
|
|
686
686
|
if (responseChecksum !== localChecksum) {
|
|
687
|
-
const error = new InvalidNonce(this.id + ' invalid checksum');
|
|
688
687
|
delete client.subscriptions[messageHash];
|
|
689
688
|
delete this.orderbooks[symbol];
|
|
690
|
-
|
|
689
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
690
|
+
if (checksum) {
|
|
691
|
+
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
692
|
+
client.reject(error, messageHash);
|
|
693
|
+
}
|
|
691
694
|
}
|
|
692
695
|
}
|
|
693
696
|
async watchBalance(params = {}) {
|
package/js/src/pro/bitget.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import bitgetRest from '../bitget.js';
|
|
9
|
-
import { AuthenticationError, BadRequest, ArgumentsRequired,
|
|
9
|
+
import { AuthenticationError, BadRequest, ArgumentsRequired, ChecksumError, ExchangeError, RateLimitExceeded } from '../base/errors.js';
|
|
10
10
|
import { Precise } from '../base/Precise.js';
|
|
11
11
|
import { ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp } from '../base/ws/Cache.js';
|
|
12
12
|
import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
|
|
@@ -65,6 +65,9 @@ export default class bitget extends bitgetRest {
|
|
|
65
65
|
'1d': '1D',
|
|
66
66
|
'1w': '1W',
|
|
67
67
|
},
|
|
68
|
+
'watchOrderBook': {
|
|
69
|
+
'checksum': true,
|
|
70
|
+
},
|
|
68
71
|
},
|
|
69
72
|
'streaming': {
|
|
70
73
|
'ping': this.ping,
|
|
@@ -562,9 +565,9 @@ export default class bitget extends bitgetRest {
|
|
|
562
565
|
const calculatedChecksum = this.crc32(payload, true);
|
|
563
566
|
const responseChecksum = this.safeInteger(rawOrderBook, 'checksum');
|
|
564
567
|
if (calculatedChecksum !== responseChecksum) {
|
|
565
|
-
const error = new InvalidNonce(this.id + ' invalid checksum');
|
|
566
568
|
delete client.subscriptions[messageHash];
|
|
567
569
|
delete this.orderbooks[symbol];
|
|
570
|
+
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
568
571
|
client.reject(error, messageHash);
|
|
569
572
|
return;
|
|
570
573
|
}
|
package/js/src/pro/bitvavo.js
CHANGED
|
@@ -503,7 +503,7 @@ export default class bitvavo extends bitvavoRest {
|
|
|
503
503
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
504
504
|
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
505
505
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
506
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=
|
|
506
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
507
507
|
*/
|
|
508
508
|
if (symbol === undefined) {
|
|
509
509
|
throw new ArgumentsRequired(this.id + ' watchMyTrades() requires a symbol argument');
|
package/js/src/pro/bybit.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export default class bybit extends bybitRest {
|
|
|
13
13
|
watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
|
|
14
14
|
handleTicker(client: Client, message: any): void;
|
|
15
15
|
watchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
|
|
16
|
+
watchOHLCVForSymbols(symbolsAndTimeframes: string[][], since?: Int, limit?: Int, params?: {}): Promise<import("../base/types.js").Dictionary<import("../base/types.js").Dictionary<OHLCV[]>>>;
|
|
16
17
|
handleOHLCV(client: Client, message: any): void;
|
|
17
18
|
parseWsOHLCV(ohlcv: any, market?: any): OHLCV;
|
|
18
19
|
watchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
|
package/js/src/pro/bybit.js
CHANGED
|
@@ -31,7 +31,7 @@ export default class bybit extends bybitRest {
|
|
|
31
31
|
'watchMyLiquidationsForSymbols': false,
|
|
32
32
|
'watchMyTrades': true,
|
|
33
33
|
'watchOHLCV': true,
|
|
34
|
-
'watchOHLCVForSymbols':
|
|
34
|
+
'watchOHLCVForSymbols': true,
|
|
35
35
|
'watchOrderBook': true,
|
|
36
36
|
'watchOrderBookForSymbols': true,
|
|
37
37
|
'watchOrders': true,
|
|
@@ -533,20 +533,46 @@ export default class bybit extends bybitRest {
|
|
|
533
533
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
534
534
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
535
535
|
*/
|
|
536
|
+
params['callerMethodName'] = 'watchOHLCV';
|
|
537
|
+
const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
|
|
538
|
+
return result[symbol][timeframe];
|
|
539
|
+
}
|
|
540
|
+
async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
|
|
541
|
+
/**
|
|
542
|
+
* @method
|
|
543
|
+
* @name bybit#watchOHLCVForSymbols
|
|
544
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
545
|
+
* @see https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
|
546
|
+
* @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
|
547
|
+
* @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
548
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
549
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
550
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
551
|
+
* @returns {object} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
552
|
+
*/
|
|
536
553
|
await this.loadMarkets();
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
554
|
+
const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
|
|
555
|
+
const marketSymbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
556
|
+
const firstSymbol = marketSymbols[0];
|
|
557
|
+
const url = await this.getUrlByMarketType(firstSymbol, false, 'watchOHLCVForSymbols', params);
|
|
558
|
+
const rawHashes = [];
|
|
559
|
+
const messageHashes = [];
|
|
560
|
+
for (let i = 0; i < symbolsAndTimeframes.length; i++) {
|
|
561
|
+
const data = symbolsAndTimeframes[i];
|
|
562
|
+
let symbolString = this.safeString(data, 0);
|
|
563
|
+
const market = this.market(symbolString);
|
|
564
|
+
symbolString = market['symbol'];
|
|
565
|
+
const unfiedTimeframe = this.safeString(data, 1);
|
|
566
|
+
const timeframeId = this.safeString(this.timeframes, unfiedTimeframe, unfiedTimeframe);
|
|
567
|
+
rawHashes.push('kline.' + timeframeId + '.' + market['id']);
|
|
568
|
+
messageHashes.push('ohlcv::' + symbolString + '::' + unfiedTimeframe);
|
|
569
|
+
}
|
|
570
|
+
const [symbol, timeframe, stored] = await this.watchTopics(url, messageHashes, rawHashes, params);
|
|
546
571
|
if (this.newUpdates) {
|
|
547
|
-
limit =
|
|
572
|
+
limit = stored.getLimit(symbol, limit);
|
|
548
573
|
}
|
|
549
|
-
|
|
574
|
+
const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
|
|
575
|
+
return this.createOHLCVObject(symbol, timeframe, filtered);
|
|
550
576
|
}
|
|
551
577
|
handleOHLCV(client, message) {
|
|
552
578
|
//
|
|
@@ -586,18 +612,18 @@ export default class bybit extends bybitRest {
|
|
|
586
612
|
if (ohlcvsByTimeframe === undefined) {
|
|
587
613
|
this.ohlcvs[symbol] = {};
|
|
588
614
|
}
|
|
589
|
-
|
|
590
|
-
if (stored === undefined) {
|
|
615
|
+
if (this.safeValue(ohlcvsByTimeframe, timeframe) === undefined) {
|
|
591
616
|
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
592
|
-
|
|
593
|
-
this.ohlcvs[symbol][timeframe] = stored;
|
|
617
|
+
this.ohlcvs[symbol][timeframe] = new ArrayCacheByTimestamp(limit);
|
|
594
618
|
}
|
|
619
|
+
const stored = this.ohlcvs[symbol][timeframe];
|
|
595
620
|
for (let i = 0; i < data.length; i++) {
|
|
596
621
|
const parsed = this.parseWsOHLCV(data[i]);
|
|
597
622
|
stored.append(parsed);
|
|
598
623
|
}
|
|
599
|
-
const messageHash = '
|
|
600
|
-
|
|
624
|
+
const messageHash = 'ohlcv::' + symbol + '::' + timeframe;
|
|
625
|
+
const resolveData = [symbol, timeframe, stored];
|
|
626
|
+
client.resolve(resolveData, messageHash);
|
|
601
627
|
}
|
|
602
628
|
parseWsOHLCV(ohlcv, market = undefined) {
|
|
603
629
|
//
|
package/js/src/pro/cryptocom.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import cryptocomRest from '../cryptocom.js';
|
|
9
|
-
import { AuthenticationError,
|
|
9
|
+
import { AuthenticationError, ChecksumError, NetworkError } from '../base/errors.js';
|
|
10
10
|
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide } from '../base/ws/Cache.js';
|
|
11
11
|
import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
@@ -47,6 +47,9 @@ export default class cryptocom extends cryptocomRest {
|
|
|
47
47
|
'fetchPositionsSnapshot': true,
|
|
48
48
|
'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
|
|
49
49
|
},
|
|
50
|
+
'watchOrderBook': {
|
|
51
|
+
'checksum': true,
|
|
52
|
+
},
|
|
50
53
|
},
|
|
51
54
|
'streaming': {},
|
|
52
55
|
});
|
|
@@ -220,7 +223,10 @@ export default class cryptocom extends cryptocomRest {
|
|
|
220
223
|
const previousNonce = this.safeInteger(data, 'pu');
|
|
221
224
|
const currentNonce = orderbook['nonce'];
|
|
222
225
|
if (currentNonce !== previousNonce) {
|
|
223
|
-
|
|
226
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
227
|
+
if (checksum) {
|
|
228
|
+
throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
229
|
+
}
|
|
224
230
|
}
|
|
225
231
|
}
|
|
226
232
|
this.handleDeltas(orderbook['asks'], this.safeValue(books, 'asks', []));
|
package/js/src/pro/gate.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import gateRest from '../gate.js';
|
|
9
|
-
import { AuthenticationError, BadRequest, ArgumentsRequired,
|
|
9
|
+
import { AuthenticationError, BadRequest, ArgumentsRequired, ChecksumError, ExchangeError, NotSupported } from '../base/errors.js';
|
|
10
10
|
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide } from '../base/ws/Cache.js';
|
|
11
11
|
import { sha512 } from '../static_dependencies/noble-hashes/sha512.js';
|
|
12
12
|
import Precise from '../base/Precise.js';
|
|
@@ -97,6 +97,7 @@ export default class gate extends gateRest {
|
|
|
97
97
|
'interval': '100ms',
|
|
98
98
|
'snapshotDelay': 10,
|
|
99
99
|
'snapshotMaxRetries': 3,
|
|
100
|
+
'checksum': true,
|
|
100
101
|
},
|
|
101
102
|
'watchBalance': {
|
|
102
103
|
'settle': 'usdt',
|
|
@@ -482,10 +483,13 @@ export default class gate extends gateRest {
|
|
|
482
483
|
this.handleDelta(storedOrderBook, delta);
|
|
483
484
|
}
|
|
484
485
|
else {
|
|
485
|
-
const error = new InvalidNonce(this.id + ' orderbook update has a nonce bigger than u');
|
|
486
486
|
delete client.subscriptions[messageHash];
|
|
487
487
|
delete this.orderbooks[symbol];
|
|
488
|
-
|
|
488
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
489
|
+
if (checksum) {
|
|
490
|
+
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
491
|
+
client.reject(error, messageHash);
|
|
492
|
+
}
|
|
489
493
|
}
|
|
490
494
|
client.resolve(storedOrderBook, messageHash);
|
|
491
495
|
}
|
package/js/src/pro/htx.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import htxRest from '../htx.js';
|
|
9
|
-
import { ExchangeError, InvalidNonce, ArgumentsRequired, BadRequest, BadSymbol, AuthenticationError, NetworkError } from '../base/errors.js';
|
|
9
|
+
import { ExchangeError, InvalidNonce, ChecksumError, ArgumentsRequired, BadRequest, BadSymbol, AuthenticationError, NetworkError } from '../base/errors.js';
|
|
10
10
|
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide } from '../base/ws/Cache.js';
|
|
11
11
|
import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
@@ -100,6 +100,7 @@ export default class htx extends htxRest {
|
|
|
100
100
|
'api': 'api',
|
|
101
101
|
'watchOrderBook': {
|
|
102
102
|
'maxRetries': 3,
|
|
103
|
+
'checksum': true,
|
|
103
104
|
},
|
|
104
105
|
'ws': {
|
|
105
106
|
'gunzip': true,
|
|
@@ -571,7 +572,10 @@ export default class htx extends htxRest {
|
|
|
571
572
|
orderbook['nonce'] = version;
|
|
572
573
|
}
|
|
573
574
|
if ((prevSeqNum !== undefined) && prevSeqNum > orderbook['nonce']) {
|
|
574
|
-
|
|
575
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
576
|
+
if (checksum) {
|
|
577
|
+
throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
578
|
+
}
|
|
575
579
|
}
|
|
576
580
|
const spotConditon = market['spot'] && (prevSeqNum === orderbook['nonce']);
|
|
577
581
|
const nonSpotCondition = market['contract'] && (version - 1 === orderbook['nonce']);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import independentreserveRest from '../independentreserve.js';
|
|
9
|
-
import { NotSupported,
|
|
9
|
+
import { NotSupported, ChecksumError } from '../base/errors.js';
|
|
10
10
|
import { ArrayCache } from '../base/ws/Cache.js';
|
|
11
11
|
// ---------------------------------------------------------------------------
|
|
12
12
|
export default class independentreserve extends independentreserveRest {
|
|
@@ -29,7 +29,9 @@ export default class independentreserve extends independentreserveRest {
|
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
31
|
'options': {
|
|
32
|
-
'
|
|
32
|
+
'watchOrderBook': {
|
|
33
|
+
'checksum': true, // TODO: currently only working for snapshot
|
|
34
|
+
},
|
|
33
35
|
},
|
|
34
36
|
'streaming': {},
|
|
35
37
|
'exceptions': {},
|
|
@@ -199,7 +201,7 @@ export default class independentreserve extends independentreserveRest {
|
|
|
199
201
|
orderbook['timestamp'] = timestamp;
|
|
200
202
|
orderbook['datetime'] = this.iso8601(timestamp);
|
|
201
203
|
}
|
|
202
|
-
const checksum = this.
|
|
204
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
203
205
|
if (checksum && receivedSnapshot) {
|
|
204
206
|
const storedAsks = orderbook['asks'];
|
|
205
207
|
const storedBids = orderbook['bids'];
|
|
@@ -219,7 +221,7 @@ export default class independentreserve extends independentreserveRest {
|
|
|
219
221
|
const calculatedChecksum = this.crc32(payload, true);
|
|
220
222
|
const responseChecksum = this.safeInteger(orderBook, 'Crc32');
|
|
221
223
|
if (calculatedChecksum !== responseChecksum) {
|
|
222
|
-
const error = new
|
|
224
|
+
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
223
225
|
delete client.subscriptions[messageHash];
|
|
224
226
|
delete this.orderbooks[symbol];
|
|
225
227
|
client.reject(error, messageHash);
|
package/js/src/pro/kraken.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import krakenRest from '../kraken.js';
|
|
2
|
-
import type { Int, Strings, OrderSide, OrderType, Str, OrderBook, Order, Trade, Ticker, Tickers, OHLCV, Num } from '../base/types.js';
|
|
2
|
+
import type { Int, Strings, OrderSide, OrderType, Str, OrderBook, Order, Trade, Ticker, Tickers, OHLCV, Num, Balances } from '../base/types.js';
|
|
3
3
|
import Client from '../base/ws/Client.js';
|
|
4
4
|
export default class kraken extends krakenRest {
|
|
5
5
|
describe(): any;
|
|
@@ -53,6 +53,8 @@ export default class kraken extends krakenRest {
|
|
|
53
53
|
handleOrders(client: Client, message: any, subscription?: any): void;
|
|
54
54
|
parseWsOrder(order: any, market?: any): Order;
|
|
55
55
|
watchMultiHelper(unifiedName: string, channelName: string, symbols?: Strings, subscriptionArgs?: any, params?: {}): Promise<any>;
|
|
56
|
+
watchBalance(params?: {}): Promise<Balances>;
|
|
57
|
+
handleBalance(client: Client, message: any): void;
|
|
56
58
|
getMessageHash(unifiedElementName: string, subChannelName?: Str, symbol?: Str): string;
|
|
57
59
|
handleSubscriptionStatus(client: Client, message: any): void;
|
|
58
60
|
handleErrorMessage(client: Client, message: any): boolean;
|