ccxt 4.0.66 → 4.0.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -12
- package/dist/ccxt.browser.js +166 -59
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +1 -1
- package/dist/cjs/src/binance.js +1 -0
- package/dist/cjs/src/bitget.js +8 -1
- package/dist/cjs/src/bybit.js +12 -2
- package/dist/cjs/src/lykke.js +1 -1
- package/dist/cjs/src/phemex.js +2 -1
- package/dist/cjs/src/pro/binance.js +1 -1
- package/dist/cjs/src/pro/bitfinex2.js +7 -6
- package/dist/cjs/src/pro/bitget.js +10 -7
- package/dist/cjs/src/pro/bitmart.js +7 -6
- package/dist/cjs/src/pro/bittrex.js +2 -3
- package/dist/cjs/src/pro/bybit.js +3 -2
- package/dist/cjs/src/pro/coinbasepro.js +71 -9
- package/dist/cjs/src/pro/huobi.js +4 -2
- package/dist/cjs/src/pro/idex.js +1 -1
- package/dist/cjs/src/wavesexchange.js +34 -15
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/base/Exchange.js +1 -1
- package/js/src/binance.js +1 -0
- package/js/src/bitget.js +8 -1
- package/js/src/bybit.js +12 -2
- package/js/src/lykke.js +1 -1
- package/js/src/phemex.js +2 -1
- package/js/src/pro/binance.js +1 -1
- package/js/src/pro/bitfinex2.d.ts +1 -1
- package/js/src/pro/bitfinex2.js +7 -6
- package/js/src/pro/bitget.d.ts +1 -1
- package/js/src/pro/bitget.js +10 -7
- package/js/src/pro/bitmart.d.ts +1 -1
- package/js/src/pro/bitmart.js +7 -6
- package/js/src/pro/bittrex.js +2 -3
- package/js/src/pro/bybit.js +3 -2
- package/js/src/pro/coinbasepro.d.ts +3 -1
- package/js/src/pro/coinbasepro.js +71 -9
- package/js/src/pro/huobi.js +4 -2
- package/js/src/pro/idex.js +1 -1
- package/js/src/wavesexchange.d.ts +2 -1
- package/js/src/wavesexchange.js +34 -15
- package/package.json +1 -1
package/js/src/lykke.js
CHANGED
|
@@ -57,7 +57,7 @@ export default class lykke extends Exchange {
|
|
|
57
57
|
'fetchMarkets': true,
|
|
58
58
|
'fetchMarkOHLCV': false,
|
|
59
59
|
'fetchMyTrades': true,
|
|
60
|
-
'fetchOHLCV':
|
|
60
|
+
'fetchOHLCV': undefined,
|
|
61
61
|
'fetchOpenInterestHistory': false,
|
|
62
62
|
'fetchOpenOrders': true,
|
|
63
63
|
'fetchOrder': true,
|
package/js/src/phemex.js
CHANGED
|
@@ -3551,6 +3551,7 @@ export default class phemex extends Exchange {
|
|
|
3551
3551
|
}
|
|
3552
3552
|
const unrealizedPnl = Precise.stringMul(Precise.stringMul(priceDiff, contracts), contractSizeString);
|
|
3553
3553
|
const marginRatio = Precise.stringDiv(maintenanceMarginString, collateral);
|
|
3554
|
+
const isCross = this.safeValue(position, 'crossMargin');
|
|
3554
3555
|
return this.safePosition({
|
|
3555
3556
|
'info': position,
|
|
3556
3557
|
'id': undefined,
|
|
@@ -3573,7 +3574,7 @@ export default class phemex extends Exchange {
|
|
|
3573
3574
|
'maintenanceMarginPercentage': this.parseNumber(maintenanceMarginPercentageString),
|
|
3574
3575
|
'marginRatio': this.parseNumber(marginRatio),
|
|
3575
3576
|
'datetime': undefined,
|
|
3576
|
-
'marginMode':
|
|
3577
|
+
'marginMode': isCross ? 'cross' : 'isolated',
|
|
3577
3578
|
'side': side,
|
|
3578
3579
|
'hedged': false,
|
|
3579
3580
|
'percentage': undefined,
|
package/js/src/pro/binance.js
CHANGED
|
@@ -88,7 +88,7 @@ export default class binance extends binanceRest {
|
|
|
88
88
|
'name': 'kline', // or indexPriceKline or markPriceKline (coin-m futures)
|
|
89
89
|
},
|
|
90
90
|
'watchOrderBook': {
|
|
91
|
-
'
|
|
91
|
+
'maxRetries': 3,
|
|
92
92
|
},
|
|
93
93
|
'watchBalance': {
|
|
94
94
|
'fetchBalanceSnapshot': false,
|
|
@@ -23,7 +23,7 @@ export default class bitfinex2 extends bitfinex2Rest {
|
|
|
23
23
|
parseWsBalance(balance: any): import("../base/types.js").Balance;
|
|
24
24
|
handleSystemStatus(client: Client, message: any): any;
|
|
25
25
|
handleSubscriptionStatus(client: Client, message: any): any;
|
|
26
|
-
authenticate(params?: {}): any
|
|
26
|
+
authenticate(params?: {}): Promise<any>;
|
|
27
27
|
handleAuthenticationMessage(client: Client, message: any): void;
|
|
28
28
|
watchOrders(symbol?: string, since?: Int, limit?: Int, params?: {}): Promise<any>;
|
|
29
29
|
handleOrders(client: Client, message: any, subscription: any): void;
|
package/js/src/pro/bitfinex2.js
CHANGED
|
@@ -834,12 +834,13 @@ export default class bitfinex2 extends bitfinex2Rest {
|
|
|
834
834
|
client.subscriptions[channelId] = message;
|
|
835
835
|
return message;
|
|
836
836
|
}
|
|
837
|
-
authenticate(params = {}) {
|
|
837
|
+
async authenticate(params = {}) {
|
|
838
838
|
const url = this.urls['api']['ws']['private'];
|
|
839
839
|
const client = this.client(url);
|
|
840
840
|
const messageHash = 'authenticated';
|
|
841
|
-
|
|
842
|
-
|
|
841
|
+
const future = client.future(messageHash);
|
|
842
|
+
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
843
|
+
if (authenticated === undefined) {
|
|
843
844
|
const nonce = this.milliseconds();
|
|
844
845
|
const payload = 'AUTH' + nonce.toString();
|
|
845
846
|
const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha384, 'hex');
|
|
@@ -852,8 +853,7 @@ export default class bitfinex2 extends bitfinex2Rest {
|
|
|
852
853
|
'event': event,
|
|
853
854
|
};
|
|
854
855
|
const message = this.extend(request, params);
|
|
855
|
-
|
|
856
|
-
client.subscriptions[messageHash] = future;
|
|
856
|
+
this.watch(url, messageHash, message, messageHash);
|
|
857
857
|
}
|
|
858
858
|
return future;
|
|
859
859
|
}
|
|
@@ -862,7 +862,8 @@ export default class bitfinex2 extends bitfinex2Rest {
|
|
|
862
862
|
const status = this.safeString(message, 'status');
|
|
863
863
|
if (status === 'OK') {
|
|
864
864
|
// we resolve the future here permanently so authentication only happens once
|
|
865
|
-
client.
|
|
865
|
+
const future = this.safeValue(client.futures, messageHash);
|
|
866
|
+
future.resolve(true);
|
|
866
867
|
}
|
|
867
868
|
else {
|
|
868
869
|
const error = new AuthenticationError(this.json(message));
|
package/js/src/pro/bitget.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export default class bitget extends bitgetRest {
|
|
|
28
28
|
watchBalance(params?: {}): Promise<any>;
|
|
29
29
|
handleBalance(client: Client, message: any): void;
|
|
30
30
|
watchPublic(messageHash: any, args: any, params?: {}): Promise<any>;
|
|
31
|
-
authenticate(params?: {}): any
|
|
31
|
+
authenticate(params?: {}): Promise<any>;
|
|
32
32
|
watchPrivate(messageHash: any, subscriptionHash: any, args: any, params?: {}): Promise<any>;
|
|
33
33
|
handleAuthenticate(client: Client, message: any): void;
|
|
34
34
|
handleErrorMessage(client: Client, message: any): boolean;
|
package/js/src/pro/bitget.js
CHANGED
|
@@ -54,7 +54,9 @@ export default class bitget extends bitgetRest {
|
|
|
54
54
|
'ws': {
|
|
55
55
|
'exact': {
|
|
56
56
|
'30001': BadRequest,
|
|
57
|
-
'30015': AuthenticationError,
|
|
57
|
+
'30015': AuthenticationError,
|
|
58
|
+
'30016': BadRequest,
|
|
59
|
+
'30011': AuthenticationError, // { event: 'error', code: 30011, msg: 'Invalid ACCESS_KEY' }
|
|
58
60
|
},
|
|
59
61
|
},
|
|
60
62
|
},
|
|
@@ -1088,13 +1090,14 @@ export default class bitget extends bitgetRest {
|
|
|
1088
1090
|
const message = this.extend(request, params);
|
|
1089
1091
|
return await this.watch(url, messageHash, message, messageHash);
|
|
1090
1092
|
}
|
|
1091
|
-
authenticate(params = {}) {
|
|
1093
|
+
async authenticate(params = {}) {
|
|
1092
1094
|
this.checkRequiredCredentials();
|
|
1093
1095
|
const url = this.urls['api']['ws'];
|
|
1094
1096
|
const client = this.client(url);
|
|
1095
1097
|
const messageHash = 'authenticated';
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
+
const future = client.future(messageHash);
|
|
1099
|
+
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
1100
|
+
if (authenticated === undefined) {
|
|
1098
1101
|
const timestamp = this.seconds().toString();
|
|
1099
1102
|
const auth = timestamp + 'GET' + '/user/verify';
|
|
1100
1103
|
const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256, 'base64');
|
|
@@ -1111,8 +1114,7 @@ export default class bitget extends bitgetRest {
|
|
|
1111
1114
|
],
|
|
1112
1115
|
};
|
|
1113
1116
|
const message = this.extend(request, params);
|
|
1114
|
-
|
|
1115
|
-
client.subscriptions[messageHash] = future;
|
|
1117
|
+
this.watch(url, messageHash, message, messageHash);
|
|
1116
1118
|
}
|
|
1117
1119
|
return future;
|
|
1118
1120
|
}
|
|
@@ -1131,7 +1133,8 @@ export default class bitget extends bitgetRest {
|
|
|
1131
1133
|
// { event: 'login', code: 0 }
|
|
1132
1134
|
//
|
|
1133
1135
|
const messageHash = 'authenticated';
|
|
1134
|
-
client.
|
|
1136
|
+
const future = this.safeValue(client.futures, messageHash);
|
|
1137
|
+
future.resolve(true);
|
|
1135
1138
|
}
|
|
1136
1139
|
handleErrorMessage(client, message) {
|
|
1137
1140
|
//
|
package/js/src/pro/bitmart.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export default class bitmart extends bitmartRest {
|
|
|
19
19
|
handleDeltas(bookside: any, deltas: any): void;
|
|
20
20
|
handleOrderBookMessage(client: Client, message: any, orderbook: any): any;
|
|
21
21
|
handleOrderBook(client: Client, message: any): any;
|
|
22
|
-
authenticate(params?: {}): any
|
|
22
|
+
authenticate(params?: {}): Promise<any>;
|
|
23
23
|
handleSubscriptionStatus(client: Client, message: any): any;
|
|
24
24
|
handleAuthenticate(client: Client, message: any): void;
|
|
25
25
|
handleErrorMessage(client: Client, message: any): boolean;
|
package/js/src/pro/bitmart.js
CHANGED
|
@@ -485,13 +485,14 @@ export default class bitmart extends bitmartRest {
|
|
|
485
485
|
}
|
|
486
486
|
return message;
|
|
487
487
|
}
|
|
488
|
-
authenticate(params = {}) {
|
|
488
|
+
async authenticate(params = {}) {
|
|
489
489
|
this.checkRequiredCredentials();
|
|
490
490
|
const url = this.implodeHostname(this.urls['api']['ws']['private']);
|
|
491
491
|
const messageHash = 'authenticated';
|
|
492
492
|
const client = this.client(url);
|
|
493
|
-
|
|
494
|
-
|
|
493
|
+
const future = client.future(messageHash);
|
|
494
|
+
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
495
|
+
if (authenticated === undefined) {
|
|
495
496
|
const timestamp = this.milliseconds().toString();
|
|
496
497
|
const memo = this.uid;
|
|
497
498
|
const path = 'bitmart.WebSocket';
|
|
@@ -507,8 +508,7 @@ export default class bitmart extends bitmartRest {
|
|
|
507
508
|
],
|
|
508
509
|
};
|
|
509
510
|
const message = this.extend(request, params);
|
|
510
|
-
|
|
511
|
-
client.subscriptions[messageHash] = future;
|
|
511
|
+
this.watch(url, messageHash, message, messageHash);
|
|
512
512
|
}
|
|
513
513
|
return future;
|
|
514
514
|
}
|
|
@@ -523,7 +523,8 @@ export default class bitmart extends bitmartRest {
|
|
|
523
523
|
// { event: 'login' }
|
|
524
524
|
//
|
|
525
525
|
const messageHash = 'authenticated';
|
|
526
|
-
client.
|
|
526
|
+
const future = this.safeValue(client.futures, messageHash);
|
|
527
|
+
future.resolve(true);
|
|
527
528
|
}
|
|
528
529
|
handleErrorMessage(client, message) {
|
|
529
530
|
//
|
package/js/src/pro/bittrex.js
CHANGED
|
@@ -46,7 +46,7 @@ export default class bittrex extends bittrexRest {
|
|
|
46
46
|
'hub': 'c3',
|
|
47
47
|
'I': this.milliseconds(),
|
|
48
48
|
'watchOrderBook': {
|
|
49
|
-
'
|
|
49
|
+
'maxRetries': 3,
|
|
50
50
|
},
|
|
51
51
|
},
|
|
52
52
|
});
|
|
@@ -632,8 +632,7 @@ export default class bittrex extends bittrexRest {
|
|
|
632
632
|
// then we cannot align it with the cached deltas and we need to
|
|
633
633
|
// retry synchronizing in maxAttempts
|
|
634
634
|
if ((sequence !== undefined) && (nonce < sequence)) {
|
|
635
|
-
const
|
|
636
|
-
const maxAttempts = this.safeInteger(options, 'maxAttempts', 3);
|
|
635
|
+
const maxAttempts = this.handleOption('watchOrderBook', 'maxRetries', 3);
|
|
637
636
|
let numAttempts = this.safeInteger(subscription, 'numAttempts', 0);
|
|
638
637
|
// retry to syncrhonize if we haven't reached maxAttempts yet
|
|
639
638
|
if (numAttempts < maxAttempts) {
|
package/js/src/pro/bybit.js
CHANGED
|
@@ -286,7 +286,8 @@ export default class bybit extends bybitRest {
|
|
|
286
286
|
const topic = this.safeString(message, 'topic', '');
|
|
287
287
|
const updateType = this.safeString(message, 'type', '');
|
|
288
288
|
const data = this.safeValue(message, 'data', {});
|
|
289
|
-
const isSpot = this.safeString(data, '
|
|
289
|
+
const isSpot = this.safeString(data, 'openInterestValue') === undefined;
|
|
290
|
+
const type = isSpot ? 'spot' : 'contract';
|
|
290
291
|
let symbol = undefined;
|
|
291
292
|
let parsed = undefined;
|
|
292
293
|
if ((updateType === 'snapshot') || isSpot) {
|
|
@@ -297,7 +298,7 @@ export default class bybit extends bybitRest {
|
|
|
297
298
|
const topicParts = topic.split('.');
|
|
298
299
|
const topicLength = topicParts.length;
|
|
299
300
|
const marketId = this.safeString(topicParts, topicLength - 1);
|
|
300
|
-
const market = this.
|
|
301
|
+
const market = this.safeMarket(marketId, undefined, undefined, type);
|
|
301
302
|
symbol = market['symbol'];
|
|
302
303
|
// update the info in place
|
|
303
304
|
const ticker = this.safeValue(this.tickers, symbol, {});
|
|
@@ -9,8 +9,10 @@ export default class coinbasepro extends coinbaseproRest {
|
|
|
9
9
|
signature: any;
|
|
10
10
|
passphrase: string;
|
|
11
11
|
};
|
|
12
|
-
subscribe(name: any, symbol
|
|
12
|
+
subscribe(name: any, symbol?: any, messageHashStart?: any, params?: {}): Promise<any>;
|
|
13
|
+
subscribeMultiple(name: any, symbols?: any[], messageHashStart?: any, params?: {}): Promise<any>;
|
|
13
14
|
watchTicker(symbol: string, params?: {}): Promise<any>;
|
|
15
|
+
watchTickers(symbols?: string[], params?: {}): Promise<any>;
|
|
14
16
|
watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<any>;
|
|
15
17
|
watchMyTrades(symbol?: string, since?: Int, limit?: Int, params?: {}): Promise<any>;
|
|
16
18
|
watchOrders(symbol?: string, since?: Int, limit?: Int, params?: {}): Promise<any>;
|
|
@@ -18,7 +18,7 @@ export default class coinbasepro extends coinbaseproRest {
|
|
|
18
18
|
'watchOHLCV': false,
|
|
19
19
|
'watchOrderBook': true,
|
|
20
20
|
'watchTicker': true,
|
|
21
|
-
'watchTickers':
|
|
21
|
+
'watchTickers': true,
|
|
22
22
|
'watchTrades': true,
|
|
23
23
|
'watchBalance': false,
|
|
24
24
|
'watchStatus': false,
|
|
@@ -53,10 +53,16 @@ export default class coinbasepro extends coinbaseproRest {
|
|
|
53
53
|
'passphrase': this.password,
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
-
async subscribe(name, symbol, messageHashStart, params = {}) {
|
|
56
|
+
async subscribe(name, symbol = undefined, messageHashStart = undefined, params = {}) {
|
|
57
57
|
await this.loadMarkets();
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
let market = undefined;
|
|
59
|
+
let messageHash = messageHashStart;
|
|
60
|
+
const productIds = [];
|
|
61
|
+
if (symbol !== undefined) {
|
|
62
|
+
market = this.market(symbol);
|
|
63
|
+
messageHash += ':' + market['id'];
|
|
64
|
+
productIds.push(market['id']);
|
|
65
|
+
}
|
|
60
66
|
let url = this.urls['api']['ws'];
|
|
61
67
|
if ('signature' in params) {
|
|
62
68
|
// need to distinguish between public trades and user trades
|
|
@@ -64,9 +70,33 @@ export default class coinbasepro extends coinbaseproRest {
|
|
|
64
70
|
}
|
|
65
71
|
const subscribe = {
|
|
66
72
|
'type': 'subscribe',
|
|
67
|
-
'product_ids':
|
|
68
|
-
|
|
73
|
+
'product_ids': productIds,
|
|
74
|
+
'channels': [
|
|
75
|
+
name,
|
|
69
76
|
],
|
|
77
|
+
};
|
|
78
|
+
const request = this.extend(subscribe, params);
|
|
79
|
+
return await this.watch(url, messageHash, request, messageHash);
|
|
80
|
+
}
|
|
81
|
+
async subscribeMultiple(name, symbols = [], messageHashStart = undefined, params = {}) {
|
|
82
|
+
await this.loadMarkets();
|
|
83
|
+
let market = undefined;
|
|
84
|
+
symbols = this.marketSymbols(symbols);
|
|
85
|
+
const messageHash = messageHashStart + symbols.join(',');
|
|
86
|
+
const productIds = [];
|
|
87
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
88
|
+
const symbol = symbols[i];
|
|
89
|
+
market = this.market(symbol);
|
|
90
|
+
productIds.push(market['id']);
|
|
91
|
+
}
|
|
92
|
+
let url = this.urls['api']['ws'];
|
|
93
|
+
if ('signature' in params) {
|
|
94
|
+
// need to distinguish between public trades and user trades
|
|
95
|
+
url = url + '?';
|
|
96
|
+
}
|
|
97
|
+
const subscribe = {
|
|
98
|
+
'type': 'subscribe',
|
|
99
|
+
'product_ids': productIds,
|
|
70
100
|
'channels': [
|
|
71
101
|
name,
|
|
72
102
|
],
|
|
@@ -86,6 +116,30 @@ export default class coinbasepro extends coinbaseproRest {
|
|
|
86
116
|
const name = 'ticker';
|
|
87
117
|
return await this.subscribe(name, symbol, name, params);
|
|
88
118
|
}
|
|
119
|
+
async watchTickers(symbols = undefined, params = {}) {
|
|
120
|
+
/**
|
|
121
|
+
* @method
|
|
122
|
+
* @name okx#watchTickers
|
|
123
|
+
* @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
|
124
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
125
|
+
* @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
|
|
126
|
+
* @param {object} [params] extra parameters specific to the okx api endpoint
|
|
127
|
+
* @param {string} [params.channel] the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
|
128
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
129
|
+
*/
|
|
130
|
+
await this.loadMarkets();
|
|
131
|
+
const symbolsLength = symbols.length;
|
|
132
|
+
if (symbolsLength === 0) {
|
|
133
|
+
throw new BadSymbol(this.id + ' watchTickers requires a non-empty symbols array');
|
|
134
|
+
}
|
|
135
|
+
const channel = 'ticker';
|
|
136
|
+
const messageHash = 'tickers::';
|
|
137
|
+
const newTickers = await this.subscribeMultiple(channel, symbols, messageHash, params);
|
|
138
|
+
if (this.newUpdates) {
|
|
139
|
+
return newTickers;
|
|
140
|
+
}
|
|
141
|
+
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
142
|
+
}
|
|
89
143
|
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
90
144
|
/**
|
|
91
145
|
* @method
|
|
@@ -117,9 +171,7 @@ export default class coinbasepro extends coinbaseproRest {
|
|
|
117
171
|
* @param {object} [params] extra parameters specific to the coinbasepro api endpoint
|
|
118
172
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
119
173
|
*/
|
|
120
|
-
|
|
121
|
-
throw new BadSymbol(this.id + ' watchMyTrades requires a symbol');
|
|
122
|
-
}
|
|
174
|
+
this.checkRequiredSymbol('watchMyTrades', symbol);
|
|
123
175
|
await this.loadMarkets();
|
|
124
176
|
symbol = this.symbol(symbol);
|
|
125
177
|
const name = 'user';
|
|
@@ -575,6 +627,16 @@ export default class coinbasepro extends coinbaseproRest {
|
|
|
575
627
|
const type = this.safeString(message, 'type');
|
|
576
628
|
const messageHash = type + ':' + marketId;
|
|
577
629
|
client.resolve(ticker, messageHash);
|
|
630
|
+
const messageHashes = this.findMessageHashes(client, 'tickers::');
|
|
631
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
632
|
+
const messageHash = messageHashes[i];
|
|
633
|
+
const parts = messageHash.split('::');
|
|
634
|
+
const symbolsString = parts[1];
|
|
635
|
+
const symbols = symbolsString.split(',');
|
|
636
|
+
if (this.inArray(symbol, symbols)) {
|
|
637
|
+
client.resolve(ticker, messageHash);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
578
640
|
}
|
|
579
641
|
return message;
|
|
580
642
|
}
|
package/js/src/pro/huobi.js
CHANGED
|
@@ -87,7 +87,9 @@ export default class huobi extends huobiRest {
|
|
|
87
87
|
'tradesLimit': 1000,
|
|
88
88
|
'OHLCVLimit': 1000,
|
|
89
89
|
'api': 'api',
|
|
90
|
-
'
|
|
90
|
+
'watchOrderBook': {
|
|
91
|
+
'maxRetries': 3,
|
|
92
|
+
},
|
|
91
93
|
'ws': {
|
|
92
94
|
'gunzip': true,
|
|
93
95
|
},
|
|
@@ -385,7 +387,7 @@ export default class huobi extends huobiRest {
|
|
|
385
387
|
const snapshotOrderBook = this.orderBook(snapshot, snapshotLimit);
|
|
386
388
|
client.resolve(snapshotOrderBook, id);
|
|
387
389
|
if ((sequence !== undefined) && (nonce < sequence)) {
|
|
388
|
-
const maxAttempts = this.
|
|
390
|
+
const maxAttempts = this.handleOption('watchOrderBook', 'maxRetries', 3);
|
|
389
391
|
let numAttempts = this.safeInteger(subscription, 'numAttempts', 0);
|
|
390
392
|
// retry to synchronize if we have not reached maxAttempts yet
|
|
391
393
|
if (numAttempts < maxAttempts) {
|
package/js/src/pro/idex.js
CHANGED
|
@@ -37,7 +37,7 @@ export default class idex extends idexRest {
|
|
|
37
37
|
'orderBookSubscriptions': {},
|
|
38
38
|
'token': undefined,
|
|
39
39
|
'watchOrderBook': {
|
|
40
|
-
'
|
|
40
|
+
'maxRetries': 3,
|
|
41
41
|
},
|
|
42
42
|
'fetchOrderBookSnapshotMaxAttempts': 10,
|
|
43
43
|
'fetchOrderBookSnapshotMaxDelay': 10000, // throw if there are no orders in 10 seconds
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Exchange from './abstract/wavesexchange.js';
|
|
2
|
+
import { Precise } from './base/Precise.js';
|
|
2
3
|
import { Int, OrderSide, OrderType } from './base/types.js';
|
|
3
4
|
/**
|
|
4
5
|
* @class wavesexchange
|
|
@@ -47,7 +48,7 @@ export default class wavesexchange extends Exchange {
|
|
|
47
48
|
customAmountToPrecision(symbol: any, amount: any): number;
|
|
48
49
|
currencyToPrecision(code: any, amount: any, networkCode?: any): number;
|
|
49
50
|
fromPrecision(amount: any, scale: any): string;
|
|
50
|
-
toPrecision(amount: any, scale: any):
|
|
51
|
+
toPrecision(amount: any, scale: any): Precise;
|
|
51
52
|
currencyFromPrecision(currency: any, amount: any): string;
|
|
52
53
|
priceFromPrecision(symbol: any, price: any): string;
|
|
53
54
|
safeGetDynamic(settings: any): any;
|
package/js/src/wavesexchange.js
CHANGED
|
@@ -617,19 +617,32 @@ export default class wavesexchange extends Exchange {
|
|
|
617
617
|
}
|
|
618
618
|
parseOrderBookSide(bookSide, market = undefined, limit = undefined) {
|
|
619
619
|
const precision = market['precision'];
|
|
620
|
-
const wavesPrecision = this.
|
|
621
|
-
const amountPrecision =
|
|
622
|
-
const
|
|
623
|
-
const
|
|
620
|
+
const wavesPrecision = this.safeString(this.options, 'wavesPrecision', '8');
|
|
621
|
+
const amountPrecision = '1e' + this.numberToString(precision['amount']);
|
|
622
|
+
const amountPrecisionString = this.numberToString(precision['amount']);
|
|
623
|
+
const pricePrecisionString = this.numberToString(precision['price']);
|
|
624
|
+
const difference = Precise.stringSub(amountPrecisionString, pricePrecisionString);
|
|
625
|
+
const pricePrecision = '1e' + Precise.stringSub(wavesPrecision, difference);
|
|
624
626
|
const result = [];
|
|
625
627
|
for (let i = 0; i < bookSide.length; i++) {
|
|
626
628
|
const entry = bookSide[i];
|
|
627
|
-
const
|
|
628
|
-
const
|
|
629
|
+
const entryPrice = this.safeString(entry, 'price', '0');
|
|
630
|
+
const entryAmount = this.safeString(entry, 'amount', '0');
|
|
631
|
+
let price = undefined;
|
|
632
|
+
let amount = undefined;
|
|
633
|
+
if ((pricePrecision !== undefined) && (entryPrice !== undefined)) {
|
|
634
|
+
price = Precise.stringDiv(entryPrice, pricePrecision);
|
|
635
|
+
}
|
|
636
|
+
if ((amountPrecision !== undefined) && (entryAmount !== undefined)) {
|
|
637
|
+
amount = Precise.stringDiv(entryAmount, amountPrecision);
|
|
638
|
+
}
|
|
629
639
|
if ((limit !== undefined) && (i > limit)) {
|
|
630
640
|
break;
|
|
631
641
|
}
|
|
632
|
-
result.push([
|
|
642
|
+
result.push([
|
|
643
|
+
this.parseNumber(price),
|
|
644
|
+
this.parseNumber(amount),
|
|
645
|
+
]);
|
|
633
646
|
}
|
|
634
647
|
return result;
|
|
635
648
|
}
|
|
@@ -1209,15 +1222,21 @@ export default class wavesexchange extends Exchange {
|
|
|
1209
1222
|
}
|
|
1210
1223
|
customPriceToPrecision(symbol, price) {
|
|
1211
1224
|
const market = this.markets[symbol];
|
|
1212
|
-
const wavesPrecision = this.
|
|
1213
|
-
const
|
|
1214
|
-
|
|
1225
|
+
const wavesPrecision = this.safeString(this.options, 'wavesPrecision', '8');
|
|
1226
|
+
const amount = this.numberToString(market['precision']['amount']);
|
|
1227
|
+
const precisionPrice = this.numberToString(market['precision']['price']);
|
|
1228
|
+
const difference = Precise.stringSub(amount, precisionPrice);
|
|
1229
|
+
const precision = Precise.stringSub(wavesPrecision, difference);
|
|
1230
|
+
const pricePrecision = this.toPrecision(price, precision).toString();
|
|
1231
|
+
return this.parseToInt(parseFloat(pricePrecision));
|
|
1215
1232
|
}
|
|
1216
1233
|
customAmountToPrecision(symbol, amount) {
|
|
1217
|
-
|
|
1234
|
+
const amountPrecision = this.numberToString(this.toPrecision(amount, this.numberToString(this.markets[symbol]['precision']['amount'])));
|
|
1235
|
+
return this.parseToInt(parseFloat(amountPrecision));
|
|
1218
1236
|
}
|
|
1219
1237
|
currencyToPrecision(code, amount, networkCode = undefined) {
|
|
1220
|
-
|
|
1238
|
+
const amountPrecision = this.numberToString(this.toPrecision(amount, this.currencies[code]['precision']));
|
|
1239
|
+
return this.parseToInt(parseFloat(amountPrecision));
|
|
1221
1240
|
}
|
|
1222
1241
|
fromPrecision(amount, scale) {
|
|
1223
1242
|
if (amount === undefined) {
|
|
@@ -1229,11 +1248,11 @@ export default class wavesexchange extends Exchange {
|
|
|
1229
1248
|
return precise.toString();
|
|
1230
1249
|
}
|
|
1231
1250
|
toPrecision(amount, scale) {
|
|
1232
|
-
const amountString =
|
|
1251
|
+
const amountString = this.numberToString(amount);
|
|
1233
1252
|
const precise = new Precise(amountString);
|
|
1234
|
-
precise.decimals = precise.decimals
|
|
1253
|
+
precise.decimals = Precise.stringSub(precise.decimals, scale);
|
|
1235
1254
|
precise.reduce();
|
|
1236
|
-
return precise
|
|
1255
|
+
return precise;
|
|
1237
1256
|
}
|
|
1238
1257
|
currencyFromPrecision(currency, amount) {
|
|
1239
1258
|
const scale = this.currencies[currency]['precision'];
|
package/package.json
CHANGED