ccxt 4.3.62 → 4.3.64
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/alpaca.js +1 -0
- package/dist/cjs/src/base/Exchange.js +11 -4
- package/dist/cjs/src/base/errors.js +8 -1
- package/dist/cjs/src/binance.js +6 -9
- package/dist/cjs/src/bingx.js +554 -151
- package/dist/cjs/src/bitfinex.js +1 -1
- package/dist/cjs/src/bitfinex2.js +1 -1
- package/dist/cjs/src/cryptocom.js +18 -2
- package/dist/cjs/src/independentreserve.js +107 -0
- package/dist/cjs/src/kucoin.js +2 -0
- 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/bitmart.js +3 -3
- 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 +7 -3
- package/dist/cjs/src/pro/gemini.js +4 -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/onetrading.js +3 -2
- package/dist/cjs/src/pro/poloniexfutures.js +5 -1
- package/dist/cjs/src/pro/vertex.js +3 -2
- package/dist/cjs/src/pro/woo.js +2 -1
- package/dist/cjs/src/pro/woofipro.js +3 -2
- package/dist/cjs/src/woo.js +344 -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/kucoin.d.ts +1 -0
- package/js/src/abstract/kucoinfutures.d.ts +1 -0
- package/js/src/abstract/woo.d.ts +3 -0
- package/js/src/ace.js +34 -15
- package/js/src/alpaca.js +1 -0
- package/js/src/base/Exchange.d.ts +1 -0
- package/js/src/base/Exchange.js +11 -4
- 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 +4 -1
- package/js/src/bingx.js +554 -151
- package/js/src/bitfinex.js +1 -1
- package/js/src/bitfinex2.js +1 -1
- package/js/src/coinbaseinternational.d.ts +1 -1
- package/js/src/cryptocom.js +18 -2
- package/js/src/independentreserve.d.ts +3 -1
- package/js/src/independentreserve.js +106 -0
- package/js/src/kucoin.js +2 -0
- 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/bitmart.js +3 -3
- 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 +8 -4
- package/js/src/pro/gemini.js +4 -2
- 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/onetrading.js +3 -2
- package/js/src/pro/poloniexfutures.js +6 -2
- package/js/src/pro/vertex.js +3 -2
- package/js/src/pro/woo.js +2 -1
- package/js/src/pro/woofipro.js +3 -2
- package/js/src/whitebit.d.ts +1 -1
- package/js/src/woo.d.ts +6 -2
- package/js/src/woo.js +344 -81
- package/js/src/xt.d.ts +3 -3
- package/js/src/zonda.d.ts +1 -1
- package/package.json +1 -1
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
|
}
|
|
@@ -1285,7 +1289,7 @@ export default class gate extends gateRest {
|
|
|
1285
1289
|
else if (event === 'finish') {
|
|
1286
1290
|
const status = this.safeString(parsed, 'status');
|
|
1287
1291
|
if (status === undefined) {
|
|
1288
|
-
const left = this.
|
|
1292
|
+
const left = this.safeInteger(info, 'left');
|
|
1289
1293
|
parsed['status'] = (left === 0) ? 'closed' : 'canceled';
|
|
1290
1294
|
}
|
|
1291
1295
|
}
|
package/js/src/pro/gemini.js
CHANGED
|
@@ -9,6 +9,7 @@ import geminiRest from '../gemini.js';
|
|
|
9
9
|
import { ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp } from '../base/ws/Cache.js';
|
|
10
10
|
import { ExchangeError, NotSupported } from '../base/errors.js';
|
|
11
11
|
import { sha384 } from '../static_dependencies/noble-hashes/sha512.js';
|
|
12
|
+
import Precise from '../base/Precise.js';
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
13
14
|
export default class gemini extends geminiRest {
|
|
14
15
|
describe() {
|
|
@@ -473,10 +474,11 @@ export default class gemini extends geminiRest {
|
|
|
473
474
|
const entry = rawBidAskChanges[i];
|
|
474
475
|
const rawSide = this.safeString(entry, 'side');
|
|
475
476
|
const price = this.safeNumber(entry, 'price');
|
|
476
|
-
const
|
|
477
|
-
if (
|
|
477
|
+
const sizeString = this.safeString(entry, 'remaining');
|
|
478
|
+
if (Precise.stringEq(sizeString, '0')) {
|
|
478
479
|
continue;
|
|
479
480
|
}
|
|
481
|
+
const size = this.parseNumber(sizeString);
|
|
480
482
|
if (rawSide === 'bid') {
|
|
481
483
|
currentBidAsk['bid'] = price;
|
|
482
484
|
currentBidAsk['bidVolume'] = size;
|
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;
|
package/js/src/pro/kraken.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import krakenRest from '../kraken.js';
|
|
9
|
-
import { ExchangeError, BadSymbol, PermissionDenied, AccountSuspended, BadRequest, InsufficientFunds, InvalidOrder, OrderNotFound, NotSupported, RateLimitExceeded, ExchangeNotAvailable,
|
|
9
|
+
import { ExchangeError, BadSymbol, PermissionDenied, AccountSuspended, BadRequest, InsufficientFunds, InvalidOrder, OrderNotFound, NotSupported, RateLimitExceeded, ExchangeNotAvailable, ChecksumError, AuthenticationError } from '../base/errors.js';
|
|
10
10
|
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
|
|
11
11
|
import { Precise } from '../base/Precise.js';
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
@@ -15,7 +15,7 @@ export default class kraken extends krakenRest {
|
|
|
15
15
|
return this.deepExtend(super.describe(), {
|
|
16
16
|
'has': {
|
|
17
17
|
'ws': true,
|
|
18
|
-
'watchBalance':
|
|
18
|
+
'watchBalance': true,
|
|
19
19
|
'watchMyTrades': true,
|
|
20
20
|
'watchOHLCV': true,
|
|
21
21
|
'watchOrderBook': true,
|
|
@@ -38,6 +38,7 @@ export default class kraken extends krakenRest {
|
|
|
38
38
|
'ws': {
|
|
39
39
|
'public': 'wss://ws.kraken.com',
|
|
40
40
|
'private': 'wss://ws-auth.kraken.com',
|
|
41
|
+
'privateV2': 'wss://ws-auth.kraken.com/v2',
|
|
41
42
|
'beta': 'wss://beta-ws.kraken.com',
|
|
42
43
|
'beta-private': 'wss://beta-ws-auth.kraken.com',
|
|
43
44
|
},
|
|
@@ -51,7 +52,9 @@ export default class kraken extends krakenRest {
|
|
|
51
52
|
'OHLCVLimit': 1000,
|
|
52
53
|
'ordersLimit': 1000,
|
|
53
54
|
'symbolsByOrderId': {},
|
|
54
|
-
'
|
|
55
|
+
'watchOrderBook': {
|
|
56
|
+
'checksum': true,
|
|
57
|
+
},
|
|
55
58
|
},
|
|
56
59
|
'exceptions': {
|
|
57
60
|
'ws': {
|
|
@@ -749,7 +752,7 @@ export default class kraken extends krakenRest {
|
|
|
749
752
|
}
|
|
750
753
|
// don't remove this line or I will poop on your face
|
|
751
754
|
orderbook.limit();
|
|
752
|
-
const checksum = this.
|
|
755
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
753
756
|
if (checksum) {
|
|
754
757
|
const priceString = this.safeString(example, 0);
|
|
755
758
|
const amountString = this.safeString(example, 1);
|
|
@@ -771,7 +774,7 @@ export default class kraken extends krakenRest {
|
|
|
771
774
|
const payload = payloadArray.join('');
|
|
772
775
|
const localChecksum = this.crc32(payload, false);
|
|
773
776
|
if (localChecksum !== c) {
|
|
774
|
-
const error = new
|
|
777
|
+
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
775
778
|
delete client.subscriptions[messageHash];
|
|
776
779
|
delete this.orderbooks[symbol];
|
|
777
780
|
client.reject(error, messageHash);
|
|
@@ -1329,6 +1332,71 @@ export default class kraken extends krakenRest {
|
|
|
1329
1332
|
const url = this.urls['api']['ws']['public'];
|
|
1330
1333
|
return await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), messageHashes, subscriptionArgs);
|
|
1331
1334
|
}
|
|
1335
|
+
async watchBalance(params = {}) {
|
|
1336
|
+
/**
|
|
1337
|
+
* @method
|
|
1338
|
+
* @name kraken#watchBalance
|
|
1339
|
+
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1340
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/balances
|
|
1341
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1342
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1343
|
+
*/
|
|
1344
|
+
await this.loadMarkets();
|
|
1345
|
+
const token = await this.authenticate();
|
|
1346
|
+
const messageHash = 'balances';
|
|
1347
|
+
const url = this.urls['api']['ws']['privateV2'];
|
|
1348
|
+
const requestId = this.requestId();
|
|
1349
|
+
const subscribe = {
|
|
1350
|
+
'method': 'subscribe',
|
|
1351
|
+
'req_id': requestId,
|
|
1352
|
+
'params': {
|
|
1353
|
+
'channel': 'balances',
|
|
1354
|
+
'token': token,
|
|
1355
|
+
},
|
|
1356
|
+
};
|
|
1357
|
+
const request = this.deepExtend(subscribe, params);
|
|
1358
|
+
return await this.watch(url, messageHash, request, messageHash);
|
|
1359
|
+
}
|
|
1360
|
+
handleBalance(client, message) {
|
|
1361
|
+
//
|
|
1362
|
+
// {
|
|
1363
|
+
// "channel": "balances",
|
|
1364
|
+
// "data": [
|
|
1365
|
+
// {
|
|
1366
|
+
// "asset": "BTC",
|
|
1367
|
+
// "asset_class": "currency",
|
|
1368
|
+
// "balance": 1.2,
|
|
1369
|
+
// "wallets": [
|
|
1370
|
+
// {
|
|
1371
|
+
// "type": "spot",
|
|
1372
|
+
// "id": "main",
|
|
1373
|
+
// "balance": 1.2
|
|
1374
|
+
// }
|
|
1375
|
+
// ]
|
|
1376
|
+
// }
|
|
1377
|
+
// ],
|
|
1378
|
+
// "type": "snapshot",
|
|
1379
|
+
// "sequence": 1
|
|
1380
|
+
// }
|
|
1381
|
+
//
|
|
1382
|
+
const data = this.safeList(message, 'data', []);
|
|
1383
|
+
const result = { 'info': message };
|
|
1384
|
+
for (let i = 0; i < data.length; i++) {
|
|
1385
|
+
const currencyId = this.safeString(data[i], 'asset');
|
|
1386
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1387
|
+
const account = this.account();
|
|
1388
|
+
const eq = this.safeString(data[i], 'balance');
|
|
1389
|
+
account['total'] = eq;
|
|
1390
|
+
result[code] = account;
|
|
1391
|
+
}
|
|
1392
|
+
const type = 'spot';
|
|
1393
|
+
const balance = this.safeBalance(result);
|
|
1394
|
+
const oldBalance = this.safeValue(this.balance, type, {});
|
|
1395
|
+
const newBalance = this.deepExtend(oldBalance, balance);
|
|
1396
|
+
this.balance[type] = this.safeBalance(newBalance);
|
|
1397
|
+
const channel = this.safeString(message, 'channel');
|
|
1398
|
+
client.resolve(this.balance[type], channel);
|
|
1399
|
+
}
|
|
1332
1400
|
getMessageHash(unifiedElementName, subChannelName = undefined, symbol = undefined) {
|
|
1333
1401
|
// unifiedElementName can be : orderbook, trade, ticker, bidask ...
|
|
1334
1402
|
// subChannelName only applies to channel that needs specific variation (i.e. depth_50, depth_100..) to be selected
|
|
@@ -1432,6 +1500,16 @@ export default class kraken extends krakenRest {
|
|
|
1432
1500
|
}
|
|
1433
1501
|
}
|
|
1434
1502
|
else {
|
|
1503
|
+
const channel = this.safeString(message, 'channel');
|
|
1504
|
+
if (channel !== undefined) {
|
|
1505
|
+
const methods = {
|
|
1506
|
+
'balances': this.handleBalance,
|
|
1507
|
+
};
|
|
1508
|
+
const method = this.safeValue(methods, channel);
|
|
1509
|
+
if (method !== undefined) {
|
|
1510
|
+
method.call(this, client, message);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1435
1513
|
if (this.handleErrorMessage(client, message)) {
|
|
1436
1514
|
const event = this.safeString(message, 'event');
|
|
1437
1515
|
const methods = {
|
package/js/src/pro/okx.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import okxRest from '../okx.js';
|
|
9
|
-
import { ArgumentsRequired, BadRequest, ExchangeError,
|
|
9
|
+
import { ArgumentsRequired, BadRequest, ExchangeError, ChecksumError, AuthenticationError } 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
|
// ---------------------------------------------------------------------------
|
|
@@ -49,6 +49,7 @@ export default class okx extends okxRest {
|
|
|
49
49
|
},
|
|
50
50
|
'options': {
|
|
51
51
|
'watchOrderBook': {
|
|
52
|
+
'checksum': true,
|
|
52
53
|
//
|
|
53
54
|
// bbo-tbt
|
|
54
55
|
// 1. Newly added channel that sends tick-by-tick Level 1 data
|
|
@@ -96,7 +97,6 @@ export default class okx extends okxRest {
|
|
|
96
97
|
'ws': {
|
|
97
98
|
// 'inflate': true,
|
|
98
99
|
},
|
|
99
|
-
'checksum': true,
|
|
100
100
|
},
|
|
101
101
|
'streaming': {
|
|
102
102
|
// okex does not support built-in ws protocol-level ping-pong
|
|
@@ -922,7 +922,7 @@ export default class okx extends okxRest {
|
|
|
922
922
|
this.handleDeltas(storedBids, bids);
|
|
923
923
|
const marketId = this.safeString(message, 'instId');
|
|
924
924
|
const symbol = this.safeSymbol(marketId);
|
|
925
|
-
const checksum = this.
|
|
925
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
926
926
|
if (checksum) {
|
|
927
927
|
const asksLength = storedAsks.length;
|
|
928
928
|
const bidsLength = storedBids.length;
|
|
@@ -941,7 +941,7 @@ export default class okx extends okxRest {
|
|
|
941
941
|
const responseChecksum = this.safeInteger(message, 'checksum');
|
|
942
942
|
const localChecksum = this.crc32(payload, true);
|
|
943
943
|
if (responseChecksum !== localChecksum) {
|
|
944
|
-
const error = new
|
|
944
|
+
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
945
945
|
delete client.subscriptions[messageHash];
|
|
946
946
|
delete this.orderbooks[symbol];
|
|
947
947
|
client.reject(error, messageHash);
|
package/js/src/pro/onetrading.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import onetradingRest from '../onetrading.js';
|
|
9
9
|
import { NotSupported, ExchangeError } from '../base/errors.js';
|
|
10
10
|
import { ArrayCacheBySymbolById, ArrayCacheByTimestamp } from '../base/ws/Cache.js';
|
|
11
|
+
import Precise from '../base/Precise.js';
|
|
11
12
|
// ---------------------------------------------------------------------------
|
|
12
13
|
export default class onetrading extends onetradingRest {
|
|
13
14
|
describe() {
|
|
@@ -965,9 +966,9 @@ export default class onetrading extends onetradingRest {
|
|
|
965
966
|
const previousOrderArray = this.filterByArray(this.orders, 'id', orderId, false);
|
|
966
967
|
const previousOrder = this.safeValue(previousOrderArray, 0, {});
|
|
967
968
|
symbol = previousOrder['symbol'];
|
|
968
|
-
const filled = this.
|
|
969
|
+
const filled = this.safeString(update, 'filled_amount');
|
|
969
970
|
let status = this.parseWsOrderStatus(updateType);
|
|
970
|
-
if (updateType === 'ORDER_CLOSED' && filled
|
|
971
|
+
if (updateType === 'ORDER_CLOSED' && Precise.stringEq(filled, '0')) {
|
|
971
972
|
status = 'canceled';
|
|
972
973
|
}
|
|
973
974
|
const orderObject = {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import poloniexfuturesRest from '../poloniexfutures.js';
|
|
9
|
-
import { AuthenticationError, BadRequest,
|
|
9
|
+
import { AuthenticationError, BadRequest, ChecksumError } from '../base/errors.js';
|
|
10
10
|
import { ArrayCache, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
|
|
11
11
|
// ---------------------------------------------------------------------------
|
|
12
12
|
export default class poloniexfutures extends poloniexfuturesRest {
|
|
@@ -52,6 +52,7 @@ export default class poloniexfutures extends poloniexfuturesRest {
|
|
|
52
52
|
'method': '/contractMarket/level2',
|
|
53
53
|
'snapshotDelay': 5,
|
|
54
54
|
'snapshotMaxRetries': 3,
|
|
55
|
+
'checksum': true,
|
|
55
56
|
},
|
|
56
57
|
'streamLimit': 5,
|
|
57
58
|
'streamBySubscriptionsHash': {},
|
|
@@ -860,7 +861,10 @@ export default class poloniexfutures extends poloniexfuturesRest {
|
|
|
860
861
|
return;
|
|
861
862
|
}
|
|
862
863
|
if (nonce !== lastSequence) {
|
|
863
|
-
|
|
864
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
865
|
+
if (checksum) {
|
|
866
|
+
throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(''));
|
|
867
|
+
}
|
|
864
868
|
}
|
|
865
869
|
const changes = this.safeList(delta, 'changes');
|
|
866
870
|
for (let i = 0; i < changes.length; i++) {
|
package/js/src/pro/vertex.js
CHANGED
|
@@ -845,9 +845,10 @@ export default class vertex extends vertexRest {
|
|
|
845
845
|
//
|
|
846
846
|
const marketId = this.safeString(order, 'product_id');
|
|
847
847
|
const timestamp = this.parseToInt(Precise.stringDiv(this.safeString(order, 'timestamp'), '1000000'));
|
|
848
|
-
const
|
|
848
|
+
const remainingString = this.convertFromX18(this.safeString(order, 'amount'));
|
|
849
|
+
const remaining = this.parseToNumeric(remainingString);
|
|
849
850
|
let status = this.parseWsOrderStatus(this.safeString(order, 'reason'));
|
|
850
|
-
if (
|
|
851
|
+
if (Precise.stringEq(remainingString, '0') && status === 'open') {
|
|
851
852
|
status = 'closed';
|
|
852
853
|
}
|
|
853
854
|
market = this.safeMarket(marketId, market);
|
package/js/src/pro/woo.js
CHANGED
|
@@ -665,9 +665,10 @@ export default class woo extends wooRest {
|
|
|
665
665
|
'cost': this.safeString(order, 'totalFee'),
|
|
666
666
|
'currency': this.safeString(order, 'feeAsset'),
|
|
667
667
|
};
|
|
668
|
+
const priceString = this.safeString(order, 'price');
|
|
668
669
|
let price = this.safeNumber(order, 'price');
|
|
669
670
|
const avgPrice = this.safeNumber(order, 'avgPrice');
|
|
670
|
-
if ((
|
|
671
|
+
if (Precise.stringEq(priceString, '0') && (avgPrice !== undefined)) {
|
|
671
672
|
price = avgPrice;
|
|
672
673
|
}
|
|
673
674
|
const amount = this.safeFloat(order, 'quantity');
|
package/js/src/pro/woofipro.js
CHANGED
|
@@ -377,7 +377,7 @@ export default class woofipro extends woofiproRest {
|
|
|
377
377
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
378
378
|
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
379
379
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
380
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
380
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
381
381
|
*/
|
|
382
382
|
await this.loadMarkets();
|
|
383
383
|
const market = this.market(symbol);
|
|
@@ -717,9 +717,10 @@ export default class woofipro extends woofiproRest {
|
|
|
717
717
|
'cost': this.safeString(order, 'totalFee'),
|
|
718
718
|
'currency': this.safeString(order, 'feeAsset'),
|
|
719
719
|
};
|
|
720
|
+
const priceString = this.safeString(order, 'price');
|
|
720
721
|
let price = this.safeNumber(order, 'price');
|
|
721
722
|
const avgPrice = this.safeNumber(order, 'avgPrice');
|
|
722
|
-
if ((
|
|
723
|
+
if (Precise.stringEq(priceString, '0') && (avgPrice !== undefined)) {
|
|
723
724
|
price = avgPrice;
|
|
724
725
|
}
|
|
725
726
|
const amount = this.safeString(order, 'quantity');
|
package/js/src/whitebit.d.ts
CHANGED
|
@@ -96,7 +96,7 @@ export default class whitebit extends Exchange {
|
|
|
96
96
|
previousFundingDatetime: any;
|
|
97
97
|
};
|
|
98
98
|
fetchDepositsWithdrawals(code?: Str, since?: Int, limit?: Int, params?: {}): Promise<Transaction[]>;
|
|
99
|
-
isFiat(currency:
|
|
99
|
+
isFiat(currency: string): boolean;
|
|
100
100
|
nonce(): number;
|
|
101
101
|
sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
|
|
102
102
|
url: string;
|
package/js/src/woo.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Exchange from './abstract/woo.js';
|
|
2
|
-
import type { TransferEntry, Balances, Conversion, Currency, FundingRateHistory, Int, Market, Num, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Dict, Strings, Trade, Transaction, Leverage, Account, Currencies, TradingFees, TransferEntries, int } from './base/types.js';
|
|
2
|
+
import type { TransferEntry, Balances, Conversion, Currency, FundingRateHistory, Int, Market, MarginModification, Num, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Dict, Strings, Trade, Transaction, Leverage, Account, Currencies, TradingFees, TransferEntries, int, FundingHistory } from './base/types.js';
|
|
3
3
|
/**
|
|
4
4
|
* @class woo
|
|
5
5
|
* @augments Exchange
|
|
@@ -26,6 +26,7 @@ export default class woo extends Exchange {
|
|
|
26
26
|
createTrailingAmountOrder(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, trailingAmount?: any, trailingTriggerPrice?: any, params?: {}): Promise<Order>;
|
|
27
27
|
createTrailingPercentOrder(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, trailingPercent?: any, trailingTriggerPrice?: any, params?: {}): Promise<Order>;
|
|
28
28
|
createOrder(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
|
|
29
|
+
encodeMarginMode(mode: any): string;
|
|
29
30
|
editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
|
|
30
31
|
cancelOrder(id: string, symbol?: Str, params?: {}): Promise<any>;
|
|
31
32
|
cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
|
|
@@ -118,7 +119,7 @@ export default class woo extends Exchange {
|
|
|
118
119
|
amount: number;
|
|
119
120
|
rate: number;
|
|
120
121
|
};
|
|
121
|
-
fetchFundingHistory(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<
|
|
122
|
+
fetchFundingHistory(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<FundingHistory[]>;
|
|
122
123
|
parseFundingRate(fundingRate: any, market?: Market): {
|
|
123
124
|
info: any;
|
|
124
125
|
symbol: string;
|
|
@@ -163,6 +164,9 @@ export default class woo extends Exchange {
|
|
|
163
164
|
fetchLeverage(symbol: string, params?: {}): Promise<Leverage>;
|
|
164
165
|
parseLeverage(leverage: Dict, market?: Market): Leverage;
|
|
165
166
|
setLeverage(leverage: Int, symbol?: Str, params?: {}): Promise<any>;
|
|
167
|
+
addMargin(symbol: string, amount: number, params?: {}): Promise<MarginModification>;
|
|
168
|
+
reduceMargin(symbol: string, amount: number, params?: {}): Promise<MarginModification>;
|
|
169
|
+
modifyMarginHelper(symbol: string, amount: any, type: any, params?: {}): Promise<MarginModification>;
|
|
166
170
|
fetchPosition(symbol?: Str, params?: {}): Promise<import("./base/types.js").Position>;
|
|
167
171
|
fetchPositions(symbols?: Strings, params?: {}): Promise<import("./base/types.js").Position[]>;
|
|
168
172
|
parsePosition(position: Dict, market?: Market): import("./base/types.js").Position;
|