ccxt 4.2.29 → 4.2.30
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 +4 -4
- package/dist/ccxt.browser.js +1709 -533
- package/dist/ccxt.browser.min.js +7 -7
- package/dist/cjs/ccxt.js +3 -1
- package/dist/cjs/src/ascendex.js +5 -5
- package/dist/cjs/src/base/Exchange.js +21 -21
- package/dist/cjs/src/base/errors.js +3 -3
- package/dist/cjs/src/base/functions/type.js +12 -0
- package/dist/cjs/src/bigone.js +2 -2
- package/dist/cjs/src/binance.js +896 -217
- package/dist/cjs/src/bingx.js +1 -1
- package/dist/cjs/src/bitfinex.js +1 -1
- package/dist/cjs/src/bitfinex2.js +52 -62
- package/dist/cjs/src/bitget.js +8 -4
- package/dist/cjs/src/bitmart.js +3 -3
- package/dist/cjs/src/bitmex.js +4 -4
- package/dist/cjs/src/bitrue.js +1 -1
- package/dist/cjs/src/bitso.js +1 -1
- package/dist/cjs/src/bitteam.js +2 -2
- package/dist/cjs/src/btcalpha.js +1 -1
- package/dist/cjs/src/bybit.js +3 -3
- package/dist/cjs/src/coinbase.js +12 -5
- package/dist/cjs/src/coincheck.js +1 -1
- package/dist/cjs/src/coinex.js +2 -2
- package/dist/cjs/src/coinlist.js +1 -1
- package/dist/cjs/src/coinmate.js +1 -1
- package/dist/cjs/src/coinmetro.js +2 -2
- package/dist/cjs/src/coinsph.js +1 -1
- package/dist/cjs/src/cryptocom.js +3 -3
- package/dist/cjs/src/digifinex.js +6 -4
- package/dist/cjs/src/exmo.js +2 -2
- package/dist/cjs/src/gate.js +5 -5
- package/dist/cjs/src/gemini.js +3 -3
- package/dist/cjs/src/hitbtc.js +14 -20
- package/dist/cjs/src/hollaex.js +2 -2
- package/dist/cjs/src/htx.js +5 -5
- package/dist/cjs/src/huobijp.js +1 -1
- package/dist/cjs/src/krakenfutures.js +1 -1
- package/dist/cjs/src/kucoin.js +17 -17
- package/dist/cjs/src/kucoinfutures.js +3 -3
- package/dist/cjs/src/lbank.js +1 -1
- package/dist/cjs/src/mexc.js +7 -7
- package/dist/cjs/src/novadax.js +1 -1
- package/dist/cjs/src/okcoin.js +2 -2
- package/dist/cjs/src/okx.js +7 -6
- package/dist/cjs/src/p2b.js +1 -0
- package/dist/cjs/src/phemex.js +3 -3
- package/dist/cjs/src/poloniexfutures.js +3 -3
- package/dist/cjs/src/pro/alpaca.js +1 -1
- package/dist/cjs/src/pro/binance.js +4 -4
- package/dist/cjs/src/pro/bitget.js +1 -1
- package/dist/cjs/src/pro/bitmart.js +1 -1
- package/dist/cjs/src/pro/bitmex.js +49 -6
- package/dist/cjs/src/pro/bitvavo.js +1 -1
- package/dist/cjs/src/pro/bybit.js +2 -2
- package/dist/cjs/src/pro/cex.js +2 -2
- package/dist/cjs/src/pro/independentreserve.js +1 -1
- package/dist/cjs/src/pro/okx.js +1 -1
- package/dist/cjs/src/pro/onetrading.js +2 -2
- package/dist/cjs/src/pro/p2b.js +432 -0
- package/dist/cjs/src/pro/probit.js +5 -5
- package/dist/cjs/src/pro/whitebit.js +1 -1
- package/dist/cjs/src/probit.js +1 -1
- package/dist/cjs/src/timex.js +1 -1
- package/dist/cjs/src/tokocrypto.js +3 -3
- package/dist/cjs/src/wavesexchange.js +2 -2
- package/dist/cjs/src/whitebit.js +2 -2
- package/dist/cjs/src/woo.js +3 -3
- package/dist/cjs/src/yobit.js +1 -1
- package/dist/cjs/src/zaif.js +1 -1
- package/dist/cjs/src/zonda.js +3 -3
- package/js/ccxt.d.ts +4 -1
- package/js/ccxt.js +3 -1
- package/js/src/abstract/bybit.d.ts +2 -2
- package/js/src/ascendex.js +5 -5
- package/js/src/base/Exchange.d.ts +1 -1
- package/js/src/base/Exchange.js +21 -21
- package/js/src/base/errorHierarchy.d.ts +7 -6
- package/js/src/base/errorHierarchy.js +7 -6
- package/js/src/base/errors.d.ts +3 -3
- package/js/src/base/errors.js +3 -3
- package/js/src/base/functions/type.js +12 -0
- package/js/src/bigone.js +2 -2
- package/js/src/binance.d.ts +1 -0
- package/js/src/binance.js +897 -218
- package/js/src/bingx.js +1 -1
- package/js/src/bitfinex.js +1 -1
- package/js/src/bitfinex2.js +52 -62
- package/js/src/bitget.js +8 -4
- package/js/src/bitmart.js +3 -3
- package/js/src/bitmex.js +4 -4
- package/js/src/bitrue.js +1 -1
- package/js/src/bitso.d.ts +1 -1
- package/js/src/bitso.js +1 -1
- package/js/src/bitteam.js +2 -2
- package/js/src/btcalpha.js +1 -1
- package/js/src/bybit.js +3 -3
- package/js/src/coinbase.js +12 -5
- package/js/src/coincheck.js +1 -1
- package/js/src/coinex.js +2 -2
- package/js/src/coinlist.js +1 -1
- package/js/src/coinmate.js +1 -1
- package/js/src/coinmetro.d.ts +1 -1
- package/js/src/coinmetro.js +2 -2
- package/js/src/coinsph.js +1 -1
- package/js/src/cryptocom.js +3 -3
- package/js/src/digifinex.js +6 -4
- package/js/src/exmo.js +2 -2
- package/js/src/gate.js +5 -5
- package/js/src/gemini.d.ts +1 -1
- package/js/src/gemini.js +3 -3
- package/js/src/hitbtc.js +14 -20
- package/js/src/hollaex.js +2 -2
- package/js/src/htx.js +5 -5
- package/js/src/huobijp.js +1 -1
- package/js/src/krakenfutures.js +1 -1
- package/js/src/kucoin.js +17 -17
- package/js/src/kucoinfutures.js +3 -3
- package/js/src/lbank.js +1 -1
- package/js/src/mexc.js +7 -7
- package/js/src/novadax.js +1 -1
- package/js/src/okcoin.js +2 -2
- package/js/src/okx.js +7 -6
- package/js/src/p2b.js +1 -0
- package/js/src/phemex.js +3 -3
- package/js/src/poloniexfutures.js +3 -3
- package/js/src/pro/alpaca.js +1 -1
- package/js/src/pro/binance.js +4 -4
- package/js/src/pro/bitget.js +1 -1
- package/js/src/pro/bitmart.js +1 -1
- package/js/src/pro/bitmex.d.ts +2 -1
- package/js/src/pro/bitmex.js +49 -6
- package/js/src/pro/bitvavo.js +1 -1
- package/js/src/pro/bybit.js +2 -2
- package/js/src/pro/cex.js +2 -2
- package/js/src/pro/independentreserve.js +1 -1
- package/js/src/pro/okx.js +1 -1
- package/js/src/pro/onetrading.js +2 -2
- package/js/src/pro/p2b.d.ts +23 -0
- package/js/src/pro/p2b.js +433 -0
- package/js/src/pro/probit.js +5 -5
- package/js/src/pro/whitebit.js +1 -1
- package/js/src/probit.js +1 -1
- package/js/src/timex.js +1 -1
- package/js/src/tokocrypto.js +3 -3
- package/js/src/wavesexchange.js +2 -2
- package/js/src/whitebit.js +2 -2
- package/js/src/woo.js +3 -3
- package/js/src/yobit.js +1 -1
- package/js/src/zaif.js +1 -1
- package/js/src/zonda.d.ts +1 -1
- package/js/src/zonda.js +3 -3
- package/package.json +1 -1
- package/skip-tests.json +3 -10
package/js/src/pro/bitget.js
CHANGED
|
@@ -895,7 +895,7 @@ export default class bitget extends bitgetRest {
|
|
|
895
895
|
await this.loadMarkets();
|
|
896
896
|
let market = undefined;
|
|
897
897
|
let marketId = undefined;
|
|
898
|
-
const isStop = this.
|
|
898
|
+
const isStop = this.safeBool(params, 'stop', false);
|
|
899
899
|
params = this.omit(params, 'stop');
|
|
900
900
|
let messageHash = (isStop) ? 'triggerOrder' : 'order';
|
|
901
901
|
let subscriptionHash = 'order:trades';
|
package/js/src/pro/bitmart.js
CHANGED
|
@@ -146,7 +146,7 @@ export default class bitmart extends bitmartRest {
|
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
148
|
const options = this.safeValue(this.options, 'watchBalance');
|
|
149
|
-
const snapshot = this.
|
|
149
|
+
const snapshot = this.safeBool(options, 'fetchBalanceSnapshot', true);
|
|
150
150
|
if (snapshot) {
|
|
151
151
|
const messageHash = type + ':' + 'fetchBalanceSnapshot';
|
|
152
152
|
if (!(messageHash in client.futures)) {
|
package/js/src/pro/bitmex.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import bitmexRest from '../bitmex.js';
|
|
2
|
-
import type { Int, Str, Strings, OrderBook, Order, Trade, Ticker, OHLCV, Position, Balances } from '../base/types.js';
|
|
2
|
+
import type { Int, Str, Strings, OrderBook, Order, Trade, Ticker, Tickers, OHLCV, Position, Balances } from '../base/types.js';
|
|
3
3
|
import Client from '../base/ws/Client.js';
|
|
4
4
|
export default class bitmex extends bitmexRest {
|
|
5
5
|
describe(): any;
|
|
6
6
|
watchTicker(symbol: string, params?: {}): Promise<Ticker>;
|
|
7
|
+
watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
|
|
7
8
|
handleTicker(client: Client, message: any): any;
|
|
8
9
|
watchBalance(params?: {}): Promise<Balances>;
|
|
9
10
|
handleBalance(client: Client, message: any): void;
|
package/js/src/pro/bitmex.js
CHANGED
|
@@ -23,7 +23,7 @@ export default class bitmex extends bitmexRest {
|
|
|
23
23
|
'watchOrders': true,
|
|
24
24
|
'watchPostions': true,
|
|
25
25
|
'watchTicker': true,
|
|
26
|
-
'watchTickers':
|
|
26
|
+
'watchTickers': true,
|
|
27
27
|
'watchTrades': true,
|
|
28
28
|
'watchTradesForSymbols': true,
|
|
29
29
|
},
|
|
@@ -75,6 +75,46 @@ export default class bitmex extends bitmexRest {
|
|
|
75
75
|
};
|
|
76
76
|
return await this.watch(url, messageHash, this.extend(request, params), messageHash);
|
|
77
77
|
}
|
|
78
|
+
async watchTickers(symbols = undefined, params = {}) {
|
|
79
|
+
/**
|
|
80
|
+
* @method
|
|
81
|
+
* @name bitmex#watchTickers
|
|
82
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
83
|
+
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
84
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
85
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
86
|
+
*/
|
|
87
|
+
await this.loadMarkets();
|
|
88
|
+
symbols = this.marketSymbols(symbols, undefined, true);
|
|
89
|
+
const name = 'instrument';
|
|
90
|
+
const url = this.urls['api']['ws'];
|
|
91
|
+
const messageHashes = [];
|
|
92
|
+
if (symbols !== undefined) {
|
|
93
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
94
|
+
const symbol = symbols[i];
|
|
95
|
+
const market = this.market(symbol);
|
|
96
|
+
const hash = name + ':' + market['id'];
|
|
97
|
+
messageHashes.push(hash);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
messageHashes.push(name);
|
|
102
|
+
}
|
|
103
|
+
const request = {
|
|
104
|
+
'op': 'subscribe',
|
|
105
|
+
'args': messageHashes,
|
|
106
|
+
};
|
|
107
|
+
const ticker = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes);
|
|
108
|
+
if (this.newUpdates) {
|
|
109
|
+
if (symbols === undefined) {
|
|
110
|
+
return ticker;
|
|
111
|
+
}
|
|
112
|
+
const result = {};
|
|
113
|
+
result[ticker['symbol']] = ticker;
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
117
|
+
}
|
|
78
118
|
handleTicker(client, message) {
|
|
79
119
|
//
|
|
80
120
|
// {
|
|
@@ -303,19 +343,22 @@ export default class bitmex extends bitmexRest {
|
|
|
303
343
|
// }
|
|
304
344
|
//
|
|
305
345
|
const table = this.safeString(message, 'table');
|
|
306
|
-
const data = this.
|
|
346
|
+
const data = this.safeList(message, 'data', []);
|
|
347
|
+
const tickers = {};
|
|
307
348
|
for (let i = 0; i < data.length; i++) {
|
|
308
349
|
const update = data[i];
|
|
309
|
-
const marketId = this.
|
|
350
|
+
const marketId = this.safeString(update, 'symbol');
|
|
310
351
|
const market = this.safeMarket(marketId);
|
|
311
352
|
const symbol = market['symbol'];
|
|
312
353
|
const messageHash = table + ':' + marketId;
|
|
313
|
-
let ticker = this.
|
|
314
|
-
const info = this.
|
|
354
|
+
let ticker = this.safeDict(this.tickers, symbol, {});
|
|
355
|
+
const info = this.safeDict(ticker, 'info', {});
|
|
315
356
|
ticker = this.parseTicker(this.extend(info, update), market);
|
|
357
|
+
tickers[symbol] = ticker;
|
|
316
358
|
this.tickers[symbol] = ticker;
|
|
317
359
|
client.resolve(ticker, messageHash);
|
|
318
360
|
}
|
|
361
|
+
client.resolve(tickers, 'instrument');
|
|
319
362
|
return message;
|
|
320
363
|
}
|
|
321
364
|
async watchBalance(params = {}) {
|
|
@@ -579,7 +622,7 @@ export default class bitmex extends bitmexRest {
|
|
|
579
622
|
return future;
|
|
580
623
|
}
|
|
581
624
|
handleAuthenticationMessage(client, message) {
|
|
582
|
-
const authenticated = this.
|
|
625
|
+
const authenticated = this.safeBool(message, 'success', false);
|
|
583
626
|
const messageHash = 'authenticated';
|
|
584
627
|
if (authenticated) {
|
|
585
628
|
// we resolve the future here permanently so authentication only happens once
|
package/js/src/pro/bitvavo.js
CHANGED
|
@@ -1228,7 +1228,7 @@ export default class bitvavo extends bitvavoRest {
|
|
|
1228
1228
|
// }
|
|
1229
1229
|
//
|
|
1230
1230
|
const messageHash = 'authenticated';
|
|
1231
|
-
const authenticated = this.
|
|
1231
|
+
const authenticated = this.safeBool(message, 'authenticated', false);
|
|
1232
1232
|
if (authenticated) {
|
|
1233
1233
|
// we resolve the future here permanently so authentication only happens once
|
|
1234
1234
|
client.resolve(message, messageHash);
|
package/js/src/pro/bybit.js
CHANGED
|
@@ -1345,8 +1345,8 @@ export default class bybit extends bybitRest {
|
|
|
1345
1345
|
let subType = undefined;
|
|
1346
1346
|
[subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
|
|
1347
1347
|
const unified = await this.isUnifiedEnabled();
|
|
1348
|
-
const isUnifiedMargin = this.
|
|
1349
|
-
const isUnifiedAccount = this.
|
|
1348
|
+
const isUnifiedMargin = this.safeBool(unified, 0, false);
|
|
1349
|
+
const isUnifiedAccount = this.safeBool(unified, 1, false);
|
|
1350
1350
|
const url = this.getUrlByMarketType(undefined, true, method, params);
|
|
1351
1351
|
await this.authenticate(url);
|
|
1352
1352
|
const topicByMarket = {
|
package/js/src/pro/cex.js
CHANGED
|
@@ -720,7 +720,7 @@ export default class cex extends cexRest {
|
|
|
720
720
|
order = this.parseWsOrderUpdate(data, market);
|
|
721
721
|
}
|
|
722
722
|
order['remaining'] = remains;
|
|
723
|
-
const canceled = this.
|
|
723
|
+
const canceled = this.safeBool(data, 'cancel', false);
|
|
724
724
|
if (canceled) {
|
|
725
725
|
order['status'] = 'canceled';
|
|
726
726
|
}
|
|
@@ -809,7 +809,7 @@ export default class cex extends cexRest {
|
|
|
809
809
|
if (isTransaction) {
|
|
810
810
|
timestamp = this.parse8601(time);
|
|
811
811
|
}
|
|
812
|
-
const canceled = this.
|
|
812
|
+
const canceled = this.safeBool(order, 'cancel', false);
|
|
813
813
|
let status = 'open';
|
|
814
814
|
if (canceled) {
|
|
815
815
|
status = 'canceled';
|
|
@@ -179,7 +179,7 @@ export default class independentreserve extends independentreserveRest {
|
|
|
179
179
|
const orderBook = this.safeValue(message, 'Data', {});
|
|
180
180
|
const messageHash = 'orderbook:' + symbol + ':' + depth;
|
|
181
181
|
const subscription = this.safeValue(client.subscriptions, messageHash, {});
|
|
182
|
-
const receivedSnapshot = this.
|
|
182
|
+
const receivedSnapshot = this.safeBool(subscription, 'receivedSnapshot', false);
|
|
183
183
|
const timestamp = this.safeInteger(message, 'Time');
|
|
184
184
|
let storedOrderBook = this.safeValue(this.orderbooks, symbol);
|
|
185
185
|
if (storedOrderBook === undefined) {
|
package/js/src/pro/okx.js
CHANGED
|
@@ -867,7 +867,7 @@ export default class okx extends okxRest {
|
|
|
867
867
|
// By default, receive order updates from any instrument type
|
|
868
868
|
let type = undefined;
|
|
869
869
|
[type, params] = this.handleOptionAndParams(params, 'watchMyTrades', 'type', 'ANY');
|
|
870
|
-
const isStop = this.
|
|
870
|
+
const isStop = this.safeBool(params, 'stop', false);
|
|
871
871
|
params = this.omit(params, ['stop']);
|
|
872
872
|
await this.loadMarkets();
|
|
873
873
|
await this.authenticate({ 'access': isStop ? 'business' : 'private' });
|
package/js/src/pro/onetrading.js
CHANGED
|
@@ -1060,7 +1060,7 @@ export default class onetrading extends onetradingRest {
|
|
|
1060
1060
|
subscription = this.safeValue(client.subscriptions, subscriptionHash);
|
|
1061
1061
|
if (subscription !== undefined) {
|
|
1062
1062
|
const ohlcvMarket = this.safeValue(subscription, marketId, {});
|
|
1063
|
-
const marketSubscribed = this.
|
|
1063
|
+
const marketSubscribed = this.safeBool(ohlcvMarket, timeframe, false);
|
|
1064
1064
|
if (!marketSubscribed) {
|
|
1065
1065
|
type = 'UPDATE_SUBSCRIPTION';
|
|
1066
1066
|
client.subscriptions[subscriptionHash] = undefined;
|
|
@@ -1301,7 +1301,7 @@ export default class onetrading extends onetradingRest {
|
|
|
1301
1301
|
if (subscription !== undefined) {
|
|
1302
1302
|
for (let i = 0; i < marketIds.length; i++) {
|
|
1303
1303
|
const marketId = marketIds[i];
|
|
1304
|
-
const marketSubscribed = this.
|
|
1304
|
+
const marketSubscribed = this.safeBool(subscription, marketId, false);
|
|
1305
1305
|
if (!marketSubscribed) {
|
|
1306
1306
|
type = 'UPDATE_SUBSCRIPTION';
|
|
1307
1307
|
client.subscriptions[subscriptionHash] = undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import p2bRest from '../p2b.js';
|
|
2
|
+
import type { Int, OHLCV, OrderBook, Trade, Ticker } from '../base/types.js';
|
|
3
|
+
import Client from '../base/ws/Client.js';
|
|
4
|
+
export default class p2b extends p2bRest {
|
|
5
|
+
describe(): any;
|
|
6
|
+
subscribe(name: string, messageHash: string, request: any, params?: {}): Promise<any>;
|
|
7
|
+
watchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
|
|
8
|
+
watchTicker(symbol: string, params?: {}): Promise<Ticker>;
|
|
9
|
+
watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
|
|
10
|
+
watchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
|
|
11
|
+
handleOHLCV(client: Client, message: any): any;
|
|
12
|
+
handleTrade(client: Client, message: any): any;
|
|
13
|
+
handleTicker(client: Client, message: any): any;
|
|
14
|
+
handleOrderBook(client: Client, message: any): void;
|
|
15
|
+
handleMessage(client: Client, message: any): any;
|
|
16
|
+
handleErrorMessage(client: Client, message: any): boolean;
|
|
17
|
+
ping(client: any): {
|
|
18
|
+
method: string;
|
|
19
|
+
params: any[];
|
|
20
|
+
id: number;
|
|
21
|
+
};
|
|
22
|
+
handlePong(client: Client, message: any): any;
|
|
23
|
+
}
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
// ----------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
4
|
+
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
5
|
+
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
import p2bRest from '../p2b.js';
|
|
9
|
+
import { BadRequest, ExchangeError } from '../base/errors.js';
|
|
10
|
+
import { ArrayCache, ArrayCacheByTimestamp } from '../base/ws/Cache.js';
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
export default class p2b extends p2bRest {
|
|
13
|
+
describe() {
|
|
14
|
+
return this.deepExtend(super.describe(), {
|
|
15
|
+
'has': {
|
|
16
|
+
'ws': true,
|
|
17
|
+
'cancelAllOrdersWs': false,
|
|
18
|
+
'cancelOrdersWs': false,
|
|
19
|
+
'cancelOrderWs': false,
|
|
20
|
+
'createOrderWs': false,
|
|
21
|
+
'editOrderWs': false,
|
|
22
|
+
'fetchBalanceWs': false,
|
|
23
|
+
'fetchOpenOrdersWs': false,
|
|
24
|
+
'fetchOrderWs': false,
|
|
25
|
+
'fetchTradesWs': false,
|
|
26
|
+
'watchBalance': false,
|
|
27
|
+
'watchMyTrades': false,
|
|
28
|
+
'watchOHLCV': true,
|
|
29
|
+
'watchOrderBook': true,
|
|
30
|
+
'watchOrders': false,
|
|
31
|
+
// 'watchStatus': true,
|
|
32
|
+
'watchTicker': true,
|
|
33
|
+
'watchTickers': false,
|
|
34
|
+
'watchTrades': true,
|
|
35
|
+
},
|
|
36
|
+
'urls': {
|
|
37
|
+
'api': {
|
|
38
|
+
'ws': 'wss://apiws.p2pb2b.com/',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
'options': {
|
|
42
|
+
'OHLCVLimit': 1000,
|
|
43
|
+
'tradesLimit': 1000,
|
|
44
|
+
'timeframes': {
|
|
45
|
+
'15m': 900,
|
|
46
|
+
'30m': 1800,
|
|
47
|
+
'1h': 3600,
|
|
48
|
+
'1d': 86400,
|
|
49
|
+
},
|
|
50
|
+
'watchTicker': {
|
|
51
|
+
'name': 'state', // or 'price'
|
|
52
|
+
},
|
|
53
|
+
'watchTickers': {
|
|
54
|
+
'name': 'state', // or 'price'
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
'streaming': {
|
|
58
|
+
'ping': this.ping,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async subscribe(name, messageHash, request, params = {}) {
|
|
63
|
+
/**
|
|
64
|
+
* @ignore
|
|
65
|
+
* @method
|
|
66
|
+
* @description Connects to a websocket channel
|
|
67
|
+
* @param {string} name name of the channel
|
|
68
|
+
* @param {string} messageHash string to look up in handler
|
|
69
|
+
* @param {string[]|float[]} request endpoint parameters
|
|
70
|
+
* @param {object} [params] extra parameters specific to the p2b api
|
|
71
|
+
* @returns {object} data from the websocket stream
|
|
72
|
+
*/
|
|
73
|
+
const url = this.urls['api']['ws'];
|
|
74
|
+
const subscribe = {
|
|
75
|
+
'method': name,
|
|
76
|
+
'params': request,
|
|
77
|
+
'id': this.milliseconds(),
|
|
78
|
+
};
|
|
79
|
+
const query = this.extend(subscribe, params);
|
|
80
|
+
return await this.watch(url, messageHash, query, messageHash);
|
|
81
|
+
}
|
|
82
|
+
async watchOHLCV(symbol, timeframe = '15m', since = undefined, limit = undefined, params = {}) {
|
|
83
|
+
/**
|
|
84
|
+
* @method
|
|
85
|
+
* @name p2b#watchOHLCV
|
|
86
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market. Can only subscribe to one timeframe at a time for each symbol
|
|
87
|
+
* @see https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#kline-candlestick
|
|
88
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
89
|
+
* @param {string} timeframe 15m, 30m, 1h or 1d
|
|
90
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
91
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
92
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
93
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
94
|
+
*/
|
|
95
|
+
await this.loadMarkets();
|
|
96
|
+
const timeframes = this.safeValue(this.options, 'timeframes', {});
|
|
97
|
+
const channel = this.safeInteger(timeframes, timeframe);
|
|
98
|
+
if (channel === undefined) {
|
|
99
|
+
throw new BadRequest(this.id + ' watchOHLCV cannot take a timeframe of ' + timeframe);
|
|
100
|
+
}
|
|
101
|
+
const market = this.market(symbol);
|
|
102
|
+
const request = [
|
|
103
|
+
market['id'],
|
|
104
|
+
channel,
|
|
105
|
+
];
|
|
106
|
+
const messageHash = 'kline::' + market['symbol'];
|
|
107
|
+
const ohlcv = await this.subscribe('kline.subscribe', messageHash, request, params);
|
|
108
|
+
if (this.newUpdates) {
|
|
109
|
+
limit = ohlcv.getLimit(symbol, limit);
|
|
110
|
+
}
|
|
111
|
+
return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
|
|
112
|
+
}
|
|
113
|
+
async watchTicker(symbol, params = {}) {
|
|
114
|
+
/**
|
|
115
|
+
* @method
|
|
116
|
+
* @name p2b#watchTicker
|
|
117
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
118
|
+
* @see https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#last-price
|
|
119
|
+
* @see https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#market-status
|
|
120
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
121
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
122
|
+
* @param {object} [params.method] 'state' (default) or 'price'
|
|
123
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
124
|
+
*/
|
|
125
|
+
await this.loadMarkets();
|
|
126
|
+
const watchTickerOptions = this.safeValue(this.options, 'watchTicker');
|
|
127
|
+
let name = this.safeString(watchTickerOptions, 'name', 'state'); // or price
|
|
128
|
+
[name, params] = this.handleOptionAndParams(params, 'method', 'name', name);
|
|
129
|
+
const market = this.market(symbol);
|
|
130
|
+
const request = [
|
|
131
|
+
market['id'],
|
|
132
|
+
];
|
|
133
|
+
const messageHash = name + '::' + market['symbol'];
|
|
134
|
+
return await this.subscribe(name + '.subscribe', messageHash, request, params);
|
|
135
|
+
}
|
|
136
|
+
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
137
|
+
/**
|
|
138
|
+
* @method
|
|
139
|
+
* @name p2b#watchTrades
|
|
140
|
+
* @description get the list of most recent trades for a particular symbol
|
|
141
|
+
* @see https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#deals
|
|
142
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
143
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
144
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
145
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
146
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
147
|
+
*/
|
|
148
|
+
await this.loadMarkets();
|
|
149
|
+
const market = this.market(symbol);
|
|
150
|
+
const request = [
|
|
151
|
+
market['id'],
|
|
152
|
+
];
|
|
153
|
+
const messageHash = 'deals::' + market['symbol'];
|
|
154
|
+
const trades = await this.subscribe('deals.subscribe', messageHash, request, params);
|
|
155
|
+
if (this.newUpdates) {
|
|
156
|
+
limit = trades.getLimit(symbol, limit);
|
|
157
|
+
}
|
|
158
|
+
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
159
|
+
}
|
|
160
|
+
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
161
|
+
/**
|
|
162
|
+
* @method
|
|
163
|
+
* @name p2b#watchOrderBook
|
|
164
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
165
|
+
* @see https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#depth-of-market
|
|
166
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
167
|
+
* @param {int} [limit] 1-100, default=100
|
|
168
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
169
|
+
* @param {float} [params.interval] 0, 0.00000001, 0.0000001, 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, interval of precision for order, default=0.001
|
|
170
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
171
|
+
*/
|
|
172
|
+
await this.loadMarkets();
|
|
173
|
+
const market = this.market(symbol);
|
|
174
|
+
const name = 'depth.subscribe';
|
|
175
|
+
const messageHash = 'orderbook::' + market['symbol'];
|
|
176
|
+
const interval = this.safeString(params, 'interval', '0.001');
|
|
177
|
+
if (limit === undefined) {
|
|
178
|
+
limit = 100;
|
|
179
|
+
}
|
|
180
|
+
const request = [
|
|
181
|
+
market['id'],
|
|
182
|
+
limit,
|
|
183
|
+
interval,
|
|
184
|
+
];
|
|
185
|
+
const orderbook = await this.subscribe(name, messageHash, request, params);
|
|
186
|
+
return orderbook.limit();
|
|
187
|
+
}
|
|
188
|
+
handleOHLCV(client, message) {
|
|
189
|
+
//
|
|
190
|
+
// {
|
|
191
|
+
// "method": "kline.update",
|
|
192
|
+
// "params": [
|
|
193
|
+
// [
|
|
194
|
+
// 1657648800, // Kline start time
|
|
195
|
+
// "0.054146", // Kline open price
|
|
196
|
+
// "0.053938", // Kline close price (current price)
|
|
197
|
+
// "0.054146", // Kline high price
|
|
198
|
+
// "0.053911", // Kline low price
|
|
199
|
+
// "596.4674", // Volume for stock currency
|
|
200
|
+
// "32.2298758767", // Volume for money currency
|
|
201
|
+
// "ETH_BTC" // Market
|
|
202
|
+
// ]
|
|
203
|
+
// ],
|
|
204
|
+
// "id": null
|
|
205
|
+
// }
|
|
206
|
+
//
|
|
207
|
+
let data = this.safeList(message, 'params');
|
|
208
|
+
data = this.safeList(data, 0);
|
|
209
|
+
const method = this.safeString(message, 'method');
|
|
210
|
+
const splitMethod = method.split('.');
|
|
211
|
+
const channel = this.safeString(splitMethod, 0);
|
|
212
|
+
const marketId = this.safeString(data, 7);
|
|
213
|
+
const market = this.safeMarket(marketId);
|
|
214
|
+
const timeframes = this.safeDict(this.options, 'timeframes', {});
|
|
215
|
+
const timeframe = this.findTimeframe(channel, timeframes);
|
|
216
|
+
const symbol = this.safeString(market, 'symbol');
|
|
217
|
+
const messageHash = channel + '::' + symbol;
|
|
218
|
+
const parsed = this.parseOHLCV(data, market);
|
|
219
|
+
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
|
|
220
|
+
let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
|
|
221
|
+
if (symbol !== undefined) {
|
|
222
|
+
if (stored === undefined) {
|
|
223
|
+
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
224
|
+
stored = new ArrayCacheByTimestamp(limit);
|
|
225
|
+
this.ohlcvs[symbol][timeframe] = stored;
|
|
226
|
+
}
|
|
227
|
+
stored.append(parsed);
|
|
228
|
+
client.resolve(stored, messageHash);
|
|
229
|
+
}
|
|
230
|
+
return message;
|
|
231
|
+
}
|
|
232
|
+
handleTrade(client, message) {
|
|
233
|
+
//
|
|
234
|
+
// {
|
|
235
|
+
// "method": "deals.update",
|
|
236
|
+
// "params": [
|
|
237
|
+
// "ETH_BTC",
|
|
238
|
+
// [
|
|
239
|
+
// {
|
|
240
|
+
// "id": 4503032979, // Order_id
|
|
241
|
+
// "amount": "0.103",
|
|
242
|
+
// "type": "sell", // Side
|
|
243
|
+
// "time": 1657661950.8487639, // Creation time
|
|
244
|
+
// "price": "0.05361"
|
|
245
|
+
// },
|
|
246
|
+
// ...
|
|
247
|
+
// ]
|
|
248
|
+
// ],
|
|
249
|
+
// "id": null
|
|
250
|
+
// }
|
|
251
|
+
//
|
|
252
|
+
const data = this.safeList(message, 'params', []);
|
|
253
|
+
const trades = this.safeList(data, 1);
|
|
254
|
+
const marketId = this.safeString(data, 0);
|
|
255
|
+
const market = this.safeMarket(marketId);
|
|
256
|
+
const symbol = this.safeString(market, 'symbol');
|
|
257
|
+
let tradesArray = this.safeValue(this.trades, symbol);
|
|
258
|
+
if (tradesArray === undefined) {
|
|
259
|
+
const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
260
|
+
tradesArray = new ArrayCache(tradesLimit);
|
|
261
|
+
this.trades[symbol] = tradesArray;
|
|
262
|
+
}
|
|
263
|
+
for (let i = 0; i < trades.length; i++) {
|
|
264
|
+
const item = trades[i];
|
|
265
|
+
const trade = this.parseTrade(item, market);
|
|
266
|
+
tradesArray.append(trade);
|
|
267
|
+
}
|
|
268
|
+
const messageHash = 'deals::' + symbol;
|
|
269
|
+
client.resolve(tradesArray, messageHash);
|
|
270
|
+
return message;
|
|
271
|
+
}
|
|
272
|
+
handleTicker(client, message) {
|
|
273
|
+
//
|
|
274
|
+
// state
|
|
275
|
+
//
|
|
276
|
+
// {
|
|
277
|
+
// "method": "state.update",
|
|
278
|
+
// "params": [
|
|
279
|
+
// "ETH_BTC",
|
|
280
|
+
// {
|
|
281
|
+
// "high": "0.055774", // High price for the last 24h
|
|
282
|
+
// "close": "0.053679", // Close price for the last 24h
|
|
283
|
+
// "low": "0.053462", // Low price for the last 24h
|
|
284
|
+
// "period": 86400, // Period 24h
|
|
285
|
+
// "last": "0.053679", // Last price for the last 24h
|
|
286
|
+
// "volume": "38463.6132", // Stock volume for the last 24h
|
|
287
|
+
// "open": "0.055682", // Open price for the last 24h
|
|
288
|
+
// "deal": "2091.0038055314" // Money volume for the last 24h
|
|
289
|
+
// }
|
|
290
|
+
// ],
|
|
291
|
+
// "id": null
|
|
292
|
+
// }
|
|
293
|
+
//
|
|
294
|
+
// price
|
|
295
|
+
//
|
|
296
|
+
// {
|
|
297
|
+
// "method": "price.update",
|
|
298
|
+
// "params": [
|
|
299
|
+
// "ETH_BTC", // market
|
|
300
|
+
// "0.053836" // last price
|
|
301
|
+
// ],
|
|
302
|
+
// "id": null
|
|
303
|
+
// }
|
|
304
|
+
//
|
|
305
|
+
const data = this.safeList(message, 'params', []);
|
|
306
|
+
const marketId = this.safeString(data, 0);
|
|
307
|
+
const market = this.safeMarket(marketId);
|
|
308
|
+
const method = this.safeString(message, 'method');
|
|
309
|
+
const splitMethod = method.split('.');
|
|
310
|
+
const messageHashStart = this.safeString(splitMethod, 0);
|
|
311
|
+
const tickerData = this.safeDict(data, 1);
|
|
312
|
+
let ticker = undefined;
|
|
313
|
+
if (method === 'price.update') {
|
|
314
|
+
const lastPrice = this.safeString(data, 1);
|
|
315
|
+
ticker = this.safeTicker({
|
|
316
|
+
'last': lastPrice,
|
|
317
|
+
'close': lastPrice,
|
|
318
|
+
'symbol': market['symbol'],
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
ticker = this.parseTicker(tickerData, market);
|
|
323
|
+
}
|
|
324
|
+
const symbol = ticker['symbol'];
|
|
325
|
+
const messageHash = messageHashStart + '::' + symbol;
|
|
326
|
+
client.resolve(ticker, messageHash);
|
|
327
|
+
return message;
|
|
328
|
+
}
|
|
329
|
+
handleOrderBook(client, message) {
|
|
330
|
+
//
|
|
331
|
+
// {
|
|
332
|
+
// "method": "depth.update",
|
|
333
|
+
// "params": [
|
|
334
|
+
// false, // true - all records, false - new records
|
|
335
|
+
// {
|
|
336
|
+
// "asks": [ // side
|
|
337
|
+
// [
|
|
338
|
+
// "19509.81", // price
|
|
339
|
+
// "0.277" // amount
|
|
340
|
+
// ]
|
|
341
|
+
// ]
|
|
342
|
+
// },
|
|
343
|
+
// "BTC_USDT"
|
|
344
|
+
// ],
|
|
345
|
+
// "id": null
|
|
346
|
+
// }
|
|
347
|
+
//
|
|
348
|
+
const params = this.safeList(message, 'params', []);
|
|
349
|
+
const data = this.safeDict(params, 1);
|
|
350
|
+
const asks = this.safeList(data, 'asks');
|
|
351
|
+
const bids = this.safeList(data, 'bids');
|
|
352
|
+
const marketId = this.safeString(params, 2);
|
|
353
|
+
const market = this.safeMarket(marketId);
|
|
354
|
+
const symbol = market['symbol'];
|
|
355
|
+
const messageHash = 'orderbook::' + market['symbol'];
|
|
356
|
+
const subscription = this.safeValue(client.subscriptions, messageHash, {});
|
|
357
|
+
const limit = this.safeInteger(subscription, 'limit');
|
|
358
|
+
let orderbook = this.safeValue(this.orderbooks, symbol);
|
|
359
|
+
if (orderbook === undefined) {
|
|
360
|
+
this.orderbooks[symbol] = this.orderBook({}, limit);
|
|
361
|
+
orderbook = this.orderbooks[symbol];
|
|
362
|
+
}
|
|
363
|
+
if (bids !== undefined) {
|
|
364
|
+
for (let i = 0; i < bids.length; i++) {
|
|
365
|
+
const bid = this.safeValue(bids, i);
|
|
366
|
+
const price = this.safeNumber(bid, 0);
|
|
367
|
+
const amount = this.safeNumber(bid, 1);
|
|
368
|
+
orderbook['bids'].store(price, amount);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (asks !== undefined) {
|
|
372
|
+
for (let i = 0; i < asks.length; i++) {
|
|
373
|
+
const ask = this.safeValue(asks, i);
|
|
374
|
+
const price = this.safeNumber(ask, 0);
|
|
375
|
+
const amount = this.safeNumber(ask, 1);
|
|
376
|
+
orderbook['asks'].store(price, amount);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
orderbook['symbol'] = symbol;
|
|
380
|
+
client.resolve(orderbook, messageHash);
|
|
381
|
+
}
|
|
382
|
+
handleMessage(client, message) {
|
|
383
|
+
if (this.handleErrorMessage(client, message)) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
const result = this.safeString(message, 'result');
|
|
387
|
+
if (result === 'pong') {
|
|
388
|
+
this.handlePong(client, message);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
const method = this.safeString(message, 'method');
|
|
392
|
+
const methods = {
|
|
393
|
+
'depth.update': this.handleOrderBook,
|
|
394
|
+
'price.update': this.handleTicker,
|
|
395
|
+
'kline.update': this.handleOHLCV,
|
|
396
|
+
'state.update': this.handleTicker,
|
|
397
|
+
'deals.update': this.handleTrade,
|
|
398
|
+
};
|
|
399
|
+
const endpoint = this.safeValue(methods, method);
|
|
400
|
+
if (endpoint !== undefined) {
|
|
401
|
+
return endpoint.call(this, client, message);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
handleErrorMessage(client, message) {
|
|
405
|
+
const error = this.safeString(message, 'error');
|
|
406
|
+
if (error !== undefined) {
|
|
407
|
+
throw new ExchangeError(this.id + ' error: ' + this.json(error));
|
|
408
|
+
}
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
ping(client) {
|
|
412
|
+
/**
|
|
413
|
+
* @see https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#ping
|
|
414
|
+
* @param client
|
|
415
|
+
*/
|
|
416
|
+
return {
|
|
417
|
+
'method': 'server.ping',
|
|
418
|
+
'params': [],
|
|
419
|
+
'id': this.milliseconds(),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
handlePong(client, message) {
|
|
423
|
+
//
|
|
424
|
+
// {
|
|
425
|
+
// error: null,
|
|
426
|
+
// result: 'pong',
|
|
427
|
+
// id: 1706539608030
|
|
428
|
+
// }
|
|
429
|
+
//
|
|
430
|
+
client.lastPong = this.safeInteger(message, 'id');
|
|
431
|
+
return message;
|
|
432
|
+
}
|
|
433
|
+
}
|