ccxt 4.5.44 → 4.5.45
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 +9 -12
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -12
- package/dist/cjs/src/abstract/kucoinfutures.js +1 -1
- package/dist/cjs/src/base/Exchange.js +36 -3
- package/dist/cjs/src/base/functions/encode.js +2 -2
- package/dist/cjs/src/base/functions/generic.js +8 -2
- package/dist/cjs/src/bitrue.js +1 -1
- package/dist/cjs/src/bitteam.js +1 -1
- package/dist/cjs/src/btcbox.js +1 -1
- package/dist/cjs/src/cex.js +1 -0
- package/dist/cjs/src/gate.js +227 -168
- package/dist/cjs/src/grvt.js +3 -2
- package/dist/cjs/src/hyperliquid.js +16 -5
- package/dist/cjs/src/kraken.js +2 -2
- package/dist/cjs/src/krakenfutures.js +1 -5
- package/dist/cjs/src/kucoin.js +4729 -970
- package/dist/cjs/src/kucoinfutures.js +14 -3434
- package/dist/cjs/src/lbank.js +1 -1
- package/dist/cjs/src/poloniex.js +1 -1
- package/dist/cjs/src/pro/gate.js +37 -1
- package/dist/cjs/src/pro/kucoin.js +819 -178
- package/dist/cjs/src/pro/kucoinfutures.js +95 -1261
- package/dist/cjs/src/pro/mexc.js +10 -5
- package/dist/cjs/src/pro/okx.js +84 -39
- package/js/ccxt.d.ts +2 -14
- package/js/ccxt.js +2 -10
- package/js/src/abstract/kucoin.d.ts +46 -3
- package/js/src/abstract/kucoinfutures.d.ts +27 -12
- package/js/src/base/Exchange.d.ts +12 -1
- package/js/src/base/Exchange.js +36 -3
- package/js/src/base/functions/encode.js +2 -2
- package/js/src/base/functions/generic.js +9 -3
- package/js/src/bitrue.js +1 -1
- package/js/src/bitteam.js +1 -1
- package/js/src/btcbox.js +1 -1
- package/js/src/cex.js +2 -1
- package/js/src/gate.d.ts +125 -119
- package/js/src/gate.js +227 -168
- package/js/src/grvt.js +3 -2
- package/js/src/hyperliquid.d.ts +3 -1
- package/js/src/hyperliquid.js +16 -5
- package/js/src/kraken.js +2 -2
- package/js/src/krakenfutures.js +1 -5
- package/js/src/kucoin.d.ts +696 -100
- package/js/src/kucoin.js +4730 -971
- package/js/src/kucoinfutures.d.ts +4 -522
- package/js/src/kucoinfutures.js +14 -3434
- package/js/src/lbank.js +1 -1
- package/js/src/poloniex.js +1 -1
- package/js/src/pro/gate.d.ts +30 -1
- package/js/src/pro/gate.js +37 -1
- package/js/src/pro/kucoin.d.ts +70 -30
- package/js/src/pro/kucoin.js +821 -180
- package/js/src/pro/kucoinfutures.d.ts +17 -195
- package/js/src/pro/kucoinfutures.js +96 -1262
- package/js/src/pro/mexc.js +10 -5
- package/js/src/pro/okx.d.ts +1 -0
- package/js/src/pro/okx.js +84 -39
- package/package.json +1 -1
- package/dist/cjs/src/abstract/alp.js +0 -11
- package/dist/cjs/src/abstract/defx.js +0 -11
- package/dist/cjs/src/abstract/timex.js +0 -11
- package/dist/cjs/src/alp.js +0 -1059
- package/dist/cjs/src/defx.js +0 -2142
- package/dist/cjs/src/pro/defx.js +0 -866
- package/dist/cjs/src/timex.js +0 -1793
- package/js/src/abstract/alp.d.ts +0 -21
- package/js/src/abstract/alp.js +0 -5
- package/js/src/abstract/defx.d.ts +0 -72
- package/js/src/abstract/defx.js +0 -5
- package/js/src/abstract/timex.d.ts +0 -65
- package/js/src/abstract/timex.js +0 -5
- package/js/src/alp.d.ts +0 -209
- package/js/src/alp.js +0 -1052
- package/js/src/defx.d.ts +0 -348
- package/js/src/defx.js +0 -2135
- package/js/src/pro/defx.d.ts +0 -236
- package/js/src/pro/defx.js +0 -859
- package/js/src/timex.d.ts +0 -247
- package/js/src/timex.js +0 -1786
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var kucoin$1 = require('../kucoin.js');
|
|
6
6
|
var errors = require('../base/errors.js');
|
|
7
|
+
var Precise = require('../base/Precise.js');
|
|
7
8
|
var Cache = require('../base/ws/Cache.js');
|
|
8
9
|
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
@@ -23,6 +24,8 @@ class kucoin extends kucoin$1["default"] {
|
|
|
23
24
|
'watchBidsAsks': true,
|
|
24
25
|
'watchOrderBook': true,
|
|
25
26
|
'watchOrders': true,
|
|
27
|
+
'watchPosition': true,
|
|
28
|
+
'watchPositions': false,
|
|
26
29
|
'watchMyTrades': true,
|
|
27
30
|
'watchTickers': true,
|
|
28
31
|
'watchTicker': true,
|
|
@@ -40,15 +43,24 @@ class kucoin extends kucoin$1["default"] {
|
|
|
40
43
|
'options': {
|
|
41
44
|
'tradesLimit': 1000,
|
|
42
45
|
'watchTicker': {
|
|
43
|
-
'
|
|
46
|
+
'spotMethod': '/market/snapshot', // '/market/ticker'
|
|
44
47
|
},
|
|
45
48
|
'watchOrderBook': {
|
|
46
49
|
'snapshotDelay': 5,
|
|
47
50
|
'snapshotMaxRetries': 3,
|
|
48
|
-
'
|
|
51
|
+
'spotMethod': '/market/level2',
|
|
52
|
+
'contractMethod': '/contractMarket/level2', // '/contractMarket/level2Depth5' or '/contractMarket/level2Depth20'
|
|
49
53
|
},
|
|
50
54
|
'watchMyTrades': {
|
|
51
|
-
'
|
|
55
|
+
'spotMethod': '/spotMarket/tradeOrders', // or '/spot/tradeFills'
|
|
56
|
+
},
|
|
57
|
+
'watchBalance': {
|
|
58
|
+
'fetchBalanceSnapshot': true,
|
|
59
|
+
'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
|
|
60
|
+
},
|
|
61
|
+
'watchPosition': {
|
|
62
|
+
'fetchPositionSnapshot': true,
|
|
63
|
+
'awaitPositionSnapshot': true, // whether to wait for the position snapshot before providing updates
|
|
52
64
|
},
|
|
53
65
|
},
|
|
54
66
|
'streaming': {
|
|
@@ -59,9 +71,12 @@ class kucoin extends kucoin$1["default"] {
|
|
|
59
71
|
},
|
|
60
72
|
});
|
|
61
73
|
}
|
|
62
|
-
async negotiate(privateChannel, params = {}) {
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
async negotiate(privateChannel, isFuturesMethod = false, params = {}) {
|
|
75
|
+
let connectId = privateChannel ? 'private' : 'public';
|
|
76
|
+
if (isFuturesMethod) {
|
|
77
|
+
connectId += 'Futures';
|
|
78
|
+
}
|
|
79
|
+
const urls = this.safeDict(this.options, 'urls', {});
|
|
65
80
|
let future = this.safeValue(urls, connectId);
|
|
66
81
|
if (future !== undefined) {
|
|
67
82
|
return await future;
|
|
@@ -69,16 +84,15 @@ class kucoin extends kucoin$1["default"] {
|
|
|
69
84
|
// we store an awaitable to the url
|
|
70
85
|
// so that multiple calls don't asynchronously
|
|
71
86
|
// fetch different urls and overwrite each other
|
|
72
|
-
urls[connectId] = this.spawn(this.negotiateHelper, privateChannel, params);
|
|
87
|
+
urls[connectId] = this.spawn(this.negotiateHelper, privateChannel, connectId, params);
|
|
73
88
|
this.options['urls'] = urls;
|
|
74
89
|
future = urls[connectId];
|
|
75
90
|
return await future;
|
|
76
91
|
}
|
|
77
|
-
async negotiateHelper(privateChannel, params = {}) {
|
|
92
|
+
async negotiateHelper(privateChannel, connectId, params = {}) {
|
|
78
93
|
let response = undefined;
|
|
79
|
-
const connectId = privateChannel ? 'private' : 'public';
|
|
80
94
|
try {
|
|
81
|
-
if (
|
|
95
|
+
if (connectId === 'private') {
|
|
82
96
|
response = await this.privatePostBulletPrivate(params);
|
|
83
97
|
//
|
|
84
98
|
// {
|
|
@@ -98,12 +112,18 @@ class kucoin extends kucoin$1["default"] {
|
|
|
98
112
|
// }
|
|
99
113
|
//
|
|
100
114
|
}
|
|
101
|
-
else {
|
|
115
|
+
else if (connectId === 'public') {
|
|
102
116
|
response = await this.publicPostBulletPublic(params);
|
|
103
117
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
else if (connectId === 'privateFutures') {
|
|
119
|
+
response = await this.futuresPrivatePostBulletPrivate(params);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
response = await this.futuresPublicPostBulletPublic(params);
|
|
123
|
+
}
|
|
124
|
+
const data = this.safeDict(response, 'data', {});
|
|
125
|
+
const instanceServers = this.safeList(data, 'instanceServers', []);
|
|
126
|
+
const firstInstanceServer = this.safeDict(instanceServers, 0);
|
|
107
127
|
const pingInterval = this.safeInteger(firstInstanceServer, 'pingInterval');
|
|
108
128
|
const endpoint = this.safeString(firstInstanceServer, 'endpoint');
|
|
109
129
|
const token = this.safeString(data, 'token');
|
|
@@ -191,7 +211,8 @@ class kucoin extends kucoin$1["default"] {
|
|
|
191
211
|
* @method
|
|
192
212
|
* @name kucoin#watchTicker
|
|
193
213
|
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
194
|
-
* @see https://www.kucoin.com/docs
|
|
214
|
+
* @see https://www.kucoin.com/docs-new/3470063w0
|
|
215
|
+
* @see https://www.kucoin.com/docs-new/3470081w0
|
|
195
216
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
196
217
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
197
218
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
|
|
@@ -200,17 +221,25 @@ class kucoin extends kucoin$1["default"] {
|
|
|
200
221
|
await this.loadMarkets();
|
|
201
222
|
const market = this.market(symbol);
|
|
202
223
|
symbol = market['symbol'];
|
|
203
|
-
const
|
|
204
|
-
const
|
|
224
|
+
const isFuturesMethod = market['contract'];
|
|
225
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
226
|
+
let method = '/market/snapshot';
|
|
227
|
+
if (isFuturesMethod) {
|
|
228
|
+
method = '/contractMarket/ticker';
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
[method, params] = this.handleOptionAndParams(params, 'watchTicker', 'spotMethod', method);
|
|
232
|
+
}
|
|
205
233
|
const topic = method + ':' + market['id'];
|
|
206
234
|
const messageHash = 'ticker:' + symbol;
|
|
207
|
-
return await this.subscribe(url, messageHash, topic,
|
|
235
|
+
return await this.subscribe(url, messageHash, topic, params);
|
|
208
236
|
}
|
|
209
237
|
/**
|
|
210
238
|
* @method
|
|
211
239
|
* @name kucoin#unWatchTicker
|
|
212
240
|
* @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
213
|
-
* @see https://www.kucoin.com/docs
|
|
241
|
+
* @see https://www.kucoin.com/docs-new/3470063w0
|
|
242
|
+
* @see https://www.kucoin.com/docs-new/3470081w0
|
|
214
243
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
215
244
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
216
245
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
|
|
@@ -219,16 +248,25 @@ class kucoin extends kucoin$1["default"] {
|
|
|
219
248
|
await this.loadMarkets();
|
|
220
249
|
const market = this.market(symbol);
|
|
221
250
|
symbol = market['symbol'];
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
251
|
+
const isFuturesMethod = market['contract'];
|
|
252
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
253
|
+
let method = '/market/snapshot';
|
|
254
|
+
if (isFuturesMethod) {
|
|
255
|
+
method = '/contractMarket/ticker';
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
[method, params] = this.handleOptionAndParams(params, 'watchTicker', 'spotMethod', method);
|
|
259
|
+
}
|
|
225
260
|
const topic = method + ':' + market['id'];
|
|
226
261
|
const messageHash = 'unsubscribe:ticker:' + symbol;
|
|
227
262
|
const subMessageHash = 'ticker:' + symbol;
|
|
228
263
|
const subscription = {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
264
|
+
// we have to add the topic to the messageHashes and subMessageHashes
|
|
265
|
+
// because handleSubscriptionStatus needs them to remove the subscription from the client
|
|
266
|
+
// without them subscription would never be removed and re-subscribe would fail because of duplicate subscriptionHash
|
|
267
|
+
'messageHashes': [messageHash, topic],
|
|
268
|
+
'subMessageHashes': [subMessageHash, topic],
|
|
269
|
+
'topic': 'ticker',
|
|
232
270
|
'unsubscribe': true,
|
|
233
271
|
'symbols': [symbol],
|
|
234
272
|
};
|
|
@@ -237,19 +275,33 @@ class kucoin extends kucoin$1["default"] {
|
|
|
237
275
|
/**
|
|
238
276
|
* @method
|
|
239
277
|
* @name kucoin#watchTickers
|
|
240
|
-
* @see https://www.kucoin.com/docs
|
|
278
|
+
* @see https://www.kucoin.com/docs-new/3470063w0
|
|
279
|
+
* @see https://www.kucoin.com/docs-new/3470064w0
|
|
280
|
+
* @see https://www.kucoin.com/docs-new/3470081w0
|
|
241
281
|
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
242
282
|
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
243
283
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
244
|
-
* @param {string} [params.method] either '/market/snapshot' or '/market/ticker' default is '/market/ticker'
|
|
284
|
+
* @param {string} [params.method] *spot markets only* either '/market/snapshot' or '/market/ticker' default is '/market/ticker'
|
|
245
285
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
|
|
246
286
|
*/
|
|
247
287
|
async watchTickers(symbols = undefined, params = {}) {
|
|
248
288
|
await this.loadMarkets();
|
|
249
|
-
symbols = this.marketSymbols(symbols);
|
|
289
|
+
symbols = this.marketSymbols(symbols, undefined, true, true);
|
|
290
|
+
const firstMarket = this.getMarketFromSymbols(symbols);
|
|
291
|
+
let marketType = undefined;
|
|
292
|
+
[marketType, params] = this.handleMarketTypeAndParams('watchTickers', firstMarket, params);
|
|
293
|
+
const isFuturesMethod = (marketType !== 'spot') && (marketType !== 'margin');
|
|
294
|
+
if (isFuturesMethod && symbols === undefined) {
|
|
295
|
+
throw new errors.ArgumentsRequired(this.id + ' watchTickers() requires a list of symbols for ' + marketType + ' markets');
|
|
296
|
+
}
|
|
250
297
|
const messageHash = 'tickers';
|
|
251
|
-
let method =
|
|
252
|
-
|
|
298
|
+
let method = '/market/ticker';
|
|
299
|
+
if (isFuturesMethod) {
|
|
300
|
+
method = '/contractMarket/ticker';
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
[method, params] = this.handleOptionAndParams2(params, 'watchTickers', 'method', 'spotMethod', method);
|
|
304
|
+
}
|
|
253
305
|
const messageHashes = [];
|
|
254
306
|
const topics = [];
|
|
255
307
|
if (symbols !== undefined) {
|
|
@@ -260,7 +312,7 @@ class kucoin extends kucoin$1["default"] {
|
|
|
260
312
|
topics.push(method + ':' + market['id']);
|
|
261
313
|
}
|
|
262
314
|
}
|
|
263
|
-
const url = await this.negotiate(false);
|
|
315
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
264
316
|
let tickers = undefined;
|
|
265
317
|
if (symbols === undefined) {
|
|
266
318
|
const allTopic = method + ':all';
|
|
@@ -336,43 +388,106 @@ class kucoin extends kucoin$1["default"] {
|
|
|
336
388
|
// }
|
|
337
389
|
// }
|
|
338
390
|
//
|
|
391
|
+
// futures
|
|
392
|
+
// {
|
|
393
|
+
// "subject": "ticker",
|
|
394
|
+
// "topic": "/contractMarket/ticker:XBTUSDM",
|
|
395
|
+
// "data": {
|
|
396
|
+
// "symbol": "XBTUSDM", //Market of the symbol
|
|
397
|
+
// "sequence": 45, //Sequence number which is used to judge the continuity of the pushed messages
|
|
398
|
+
// "side": "sell", //Transaction side of the last traded taker order
|
|
399
|
+
// "price": "3600.0", //Filled price
|
|
400
|
+
// "size": 16, //Filled quantity
|
|
401
|
+
// "tradeId": "5c9dcf4170744d6f5a3d32fb", //Order ID
|
|
402
|
+
// "bestBidSize": 795, //Best bid size
|
|
403
|
+
// "bestBidPrice": "3200.0", //Best bid
|
|
404
|
+
// "bestAskPrice": "3600.0", //Best ask size
|
|
405
|
+
// "bestAskSize": 284, //Best ask
|
|
406
|
+
// "ts": 1553846081210004941 //Filled time - nanosecond
|
|
407
|
+
// }
|
|
408
|
+
// }
|
|
409
|
+
//
|
|
339
410
|
const topic = this.safeString(message, 'topic');
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
411
|
+
if (topic.indexOf('contractMarket') < 0) {
|
|
412
|
+
let market = undefined;
|
|
413
|
+
if (topic !== undefined) {
|
|
414
|
+
const parts = topic.split(':');
|
|
415
|
+
const first = this.safeString(parts, 1);
|
|
416
|
+
let marketId = undefined;
|
|
417
|
+
if (first === 'all') {
|
|
418
|
+
marketId = this.safeString(message, 'subject');
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
marketId = first;
|
|
422
|
+
}
|
|
423
|
+
market = this.safeMarket(marketId, market, '-');
|
|
350
424
|
}
|
|
351
|
-
|
|
425
|
+
const data = this.safeDict(message, 'data', {});
|
|
426
|
+
const rawTicker = this.safeDict(data, 'data', data);
|
|
427
|
+
const ticker = this.parseTicker(rawTicker, market);
|
|
428
|
+
const symbol = ticker['symbol'];
|
|
429
|
+
this.tickers[symbol] = ticker;
|
|
430
|
+
const messageHash = 'ticker:' + symbol;
|
|
431
|
+
client.resolve(ticker, messageHash);
|
|
432
|
+
// watchTickers
|
|
433
|
+
const allTickers = {};
|
|
434
|
+
allTickers[symbol] = ticker;
|
|
435
|
+
client.resolve(allTickers, 'tickers');
|
|
352
436
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
437
|
+
else {
|
|
438
|
+
this.handleContractTicker(client, message);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
handleContractTicker(client, message) {
|
|
442
|
+
//
|
|
443
|
+
// ticker (v1)
|
|
444
|
+
//
|
|
445
|
+
// {
|
|
446
|
+
// "subject": "ticker",
|
|
447
|
+
// "topic": "/contractMarket/ticker:XBTUSDM",
|
|
448
|
+
// "data": {
|
|
449
|
+
// "symbol": "XBTUSDM", //Market of the symbol
|
|
450
|
+
// "sequence": 45, //Sequence number which is used to judge the continuity of the pushed messages
|
|
451
|
+
// "side": "sell", //Transaction side of the last traded taker order
|
|
452
|
+
// "price": "3600.0", //Filled price
|
|
453
|
+
// "size": 16, //Filled quantity
|
|
454
|
+
// "tradeId": "5c9dcf4170744d6f5a3d32fb", //Order ID
|
|
455
|
+
// "bestBidSize": 795, //Best bid size
|
|
456
|
+
// "bestBidPrice": "3200.0", //Best bid
|
|
457
|
+
// "bestAskPrice": "3600.0", //Best ask size
|
|
458
|
+
// "bestAskSize": 284, //Best ask
|
|
459
|
+
// "ts": 1553846081210004941 //Filled time - nanosecond
|
|
460
|
+
// }
|
|
461
|
+
// }
|
|
462
|
+
//
|
|
463
|
+
const data = this.safeDict(message, 'data', {});
|
|
464
|
+
const marketId = this.safeString(data, 'symbol');
|
|
465
|
+
const market = this.safeMarket(marketId, undefined, '-');
|
|
466
|
+
const ticker = this.parseTicker(data, market);
|
|
467
|
+
this.tickers[market['symbol']] = ticker;
|
|
468
|
+
const messageHash = 'ticker:' + market['symbol'];
|
|
359
469
|
client.resolve(ticker, messageHash);
|
|
360
|
-
// watchTickers
|
|
361
|
-
const allTickers = {};
|
|
362
|
-
allTickers[symbol] = ticker;
|
|
363
|
-
client.resolve(allTickers, 'tickers');
|
|
364
470
|
}
|
|
365
471
|
/**
|
|
366
472
|
* @method
|
|
367
473
|
* @name kucoin#watchBidsAsks
|
|
368
|
-
* @see https://www.kucoin.com/docs
|
|
474
|
+
* @see https://www.kucoin.com/docs-new/3470067w0
|
|
475
|
+
* @see https://www.kucoin.com/docs-new/3470080w0
|
|
369
476
|
* @description watches best bid & ask for symbols
|
|
370
477
|
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
371
478
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
372
479
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
|
|
373
480
|
*/
|
|
374
481
|
async watchBidsAsks(symbols = undefined, params = {}) {
|
|
375
|
-
|
|
482
|
+
await this.loadMarkets();
|
|
483
|
+
symbols = this.marketSymbols(symbols, undefined, false, true, false);
|
|
484
|
+
const firstMarket = this.getMarketFromSymbols(symbols);
|
|
485
|
+
const isFuturesMethod = firstMarket['contract'];
|
|
486
|
+
let channelName = '/spotMarket/level1:';
|
|
487
|
+
if (isFuturesMethod) {
|
|
488
|
+
channelName = '/contractMarket/tickerV2:';
|
|
489
|
+
}
|
|
490
|
+
const ticker = await this.watchMultiHelper('watchBidsAsks', channelName, symbols, params);
|
|
376
491
|
if (this.newUpdates) {
|
|
377
492
|
const tickers = {};
|
|
378
493
|
tickers[ticker['symbol']] = ticker;
|
|
@@ -421,6 +536,20 @@ class kucoin extends kucoin$1["default"] {
|
|
|
421
536
|
// subject: 'level1'
|
|
422
537
|
// }
|
|
423
538
|
//
|
|
539
|
+
// futures
|
|
540
|
+
// {
|
|
541
|
+
// "subject": "tickerV2",
|
|
542
|
+
// "topic": "/contractMarket/tickerV2:XBTUSDM",
|
|
543
|
+
// "data": {
|
|
544
|
+
// "symbol": "XBTUSDM", //Market of the symbol
|
|
545
|
+
// "bestBidSize": 795, // Best bid size
|
|
546
|
+
// "bestBidPrice": 3200.0, // Best bid
|
|
547
|
+
// "bestAskPrice": 3600.0, // Best ask
|
|
548
|
+
// "bestAskSize": 284, // Best ask size
|
|
549
|
+
// "ts": 1553846081210004941 // Filled time - nanosecond
|
|
550
|
+
// }
|
|
551
|
+
// }
|
|
552
|
+
//
|
|
424
553
|
const parsedTicker = this.parseWsBidAsk(message);
|
|
425
554
|
const symbol = parsedTicker['symbol'];
|
|
426
555
|
this.bidsasks[symbol] = parsedTicker;
|
|
@@ -429,30 +558,51 @@ class kucoin extends kucoin$1["default"] {
|
|
|
429
558
|
}
|
|
430
559
|
parseWsBidAsk(ticker, market = undefined) {
|
|
431
560
|
const topic = this.safeString(ticker, 'topic');
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
561
|
+
if (topic.indexOf('contractMarket') < 0) {
|
|
562
|
+
const parts = topic.split(':');
|
|
563
|
+
const marketId = parts[1];
|
|
564
|
+
market = this.safeMarket(marketId, market);
|
|
565
|
+
const symbol = this.safeString(market, 'symbol');
|
|
566
|
+
const data = this.safeDict(ticker, 'data', {});
|
|
567
|
+
const ask = this.safeList(data, 'asks', []);
|
|
568
|
+
const bid = this.safeList(data, 'bids', []);
|
|
569
|
+
const timestamp = this.safeInteger(data, 'timestamp');
|
|
570
|
+
return this.safeTicker({
|
|
571
|
+
'symbol': symbol,
|
|
572
|
+
'timestamp': timestamp,
|
|
573
|
+
'datetime': this.iso8601(timestamp),
|
|
574
|
+
'ask': this.safeNumber(ask, 0),
|
|
575
|
+
'askVolume': this.safeNumber(ask, 1),
|
|
576
|
+
'bid': this.safeNumber(bid, 0),
|
|
577
|
+
'bidVolume': this.safeNumber(bid, 1),
|
|
578
|
+
'info': ticker,
|
|
579
|
+
}, market);
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
// futures
|
|
583
|
+
const data = this.safeDict(ticker, 'data', {});
|
|
584
|
+
const marketId = this.safeString(data, 'symbol');
|
|
585
|
+
market = this.safeMarket(marketId, market);
|
|
586
|
+
const symbol = this.safeString(market, 'symbol');
|
|
587
|
+
const timestamp = this.safeIntegerProduct(data, 'ts', 0.000001);
|
|
588
|
+
return this.safeTicker({
|
|
589
|
+
'symbol': symbol,
|
|
590
|
+
'timestamp': timestamp,
|
|
591
|
+
'datetime': this.iso8601(timestamp),
|
|
592
|
+
'ask': this.safeNumber(data, 'bestAskPrice'),
|
|
593
|
+
'askVolume': this.safeNumber(data, 'bestAskSize'),
|
|
594
|
+
'bid': this.safeNumber(data, 'bestBidPrice'),
|
|
595
|
+
'bidVolume': this.safeNumber(data, 'bestBidSize'),
|
|
596
|
+
'info': ticker,
|
|
597
|
+
}, market);
|
|
598
|
+
}
|
|
450
599
|
}
|
|
451
600
|
/**
|
|
452
601
|
* @method
|
|
453
602
|
* @name kucoin#watchOHLCV
|
|
454
603
|
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
455
|
-
* @see https://www.kucoin.com/docs
|
|
604
|
+
* @see https://www.kucoin.com/docs-new/3470071w0
|
|
605
|
+
* @see https://www.kucoin.com/docs-new/3470086w0
|
|
456
606
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
457
607
|
* @param {string} timeframe the length of time each candle represents
|
|
458
608
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
@@ -462,11 +612,16 @@ class kucoin extends kucoin$1["default"] {
|
|
|
462
612
|
*/
|
|
463
613
|
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
464
614
|
await this.loadMarkets();
|
|
465
|
-
const url = await this.negotiate(false);
|
|
466
615
|
const market = this.market(symbol);
|
|
467
616
|
symbol = market['symbol'];
|
|
617
|
+
const isFuturesMethod = market['contract'];
|
|
618
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
468
619
|
const period = this.safeString(this.timeframes, timeframe, timeframe);
|
|
469
|
-
|
|
620
|
+
let channelName = '/market/candles:';
|
|
621
|
+
if (isFuturesMethod) {
|
|
622
|
+
channelName = '/contractMarket/limitCandle:';
|
|
623
|
+
}
|
|
624
|
+
const topic = channelName + market['id'] + '_' + period;
|
|
470
625
|
const messageHash = 'candles:' + symbol + ':' + timeframe;
|
|
471
626
|
const ohlcv = await this.subscribe(url, messageHash, topic, params);
|
|
472
627
|
if (this.newUpdates) {
|
|
@@ -478,7 +633,8 @@ class kucoin extends kucoin$1["default"] {
|
|
|
478
633
|
* @method
|
|
479
634
|
* @name kucoin#unWatchOHLCV
|
|
480
635
|
* @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
481
|
-
* @see https://www.kucoin.com/docs
|
|
636
|
+
* @see https://www.kucoin.com/docs-new/3470071w0
|
|
637
|
+
* @see https://www.kucoin.com/docs-new/3470086w0
|
|
482
638
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
483
639
|
* @param {string} timeframe the length of time each candle represents
|
|
484
640
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -486,19 +642,29 @@ class kucoin extends kucoin$1["default"] {
|
|
|
486
642
|
*/
|
|
487
643
|
async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
|
|
488
644
|
await this.loadMarkets();
|
|
489
|
-
const url = await this.negotiate(false);
|
|
490
645
|
const market = this.market(symbol);
|
|
491
646
|
symbol = market['symbol'];
|
|
647
|
+
const isFuturesMethod = market['contract'];
|
|
648
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
649
|
+
let channelName = '/market/candles:';
|
|
650
|
+
if (isFuturesMethod) {
|
|
651
|
+
channelName = '/contractMarket/limitCandle:';
|
|
652
|
+
}
|
|
492
653
|
const period = this.safeString(this.timeframes, timeframe, timeframe);
|
|
493
|
-
const topic =
|
|
654
|
+
const topic = channelName + market['id'] + '_' + period;
|
|
494
655
|
const messageHash = 'unsubscribe:candles:' + symbol + ':' + timeframe;
|
|
495
656
|
const subMessageHash = 'candles:' + symbol + ':' + timeframe;
|
|
657
|
+
const symbolAndTimeframe = [symbol, timeframe];
|
|
496
658
|
const subscription = {
|
|
497
|
-
|
|
498
|
-
|
|
659
|
+
// we have to add the topic to the messageHashes and subMessageHashes
|
|
660
|
+
// because handleSubscriptionStatus needs them to remove the subscription from the client
|
|
661
|
+
// without them subscription would never be removed and re-subscribe would fail because of duplicate subscriptionHash
|
|
662
|
+
'messageHashes': [messageHash, topic],
|
|
663
|
+
'subMessageHashes': [subMessageHash, topic],
|
|
499
664
|
'topic': 'ohlcv',
|
|
500
665
|
'unsubscribe': true,
|
|
501
666
|
'symbols': [symbol],
|
|
667
|
+
'symbolsAndTimeframes': [symbolAndTimeframe],
|
|
502
668
|
};
|
|
503
669
|
return await this.unSubscribe(url, messageHash, topic, messageHash, params, subscription);
|
|
504
670
|
}
|
|
@@ -523,9 +689,29 @@ class kucoin extends kucoin$1["default"] {
|
|
|
523
689
|
// "type": "message"
|
|
524
690
|
// }
|
|
525
691
|
//
|
|
526
|
-
|
|
692
|
+
// futures
|
|
693
|
+
// {
|
|
694
|
+
// "topic":"/contractMarket/limitCandle:LTCUSDTM_1min",
|
|
695
|
+
// "type":"message",
|
|
696
|
+
// "data":{
|
|
697
|
+
// "symbol":"LTCUSDTM",
|
|
698
|
+
// "candles":[
|
|
699
|
+
// "1715470980",
|
|
700
|
+
// "81.38",
|
|
701
|
+
// "81.38",
|
|
702
|
+
// "81.38",
|
|
703
|
+
// "81.38",
|
|
704
|
+
// "61.0", - Note value 5 is incorrect and will be fixed in subsequent versions of kucoin
|
|
705
|
+
// "61"
|
|
706
|
+
// ],
|
|
707
|
+
// "time":1715470994801
|
|
708
|
+
// },
|
|
709
|
+
// "subject":"candle.stick"
|
|
710
|
+
// }
|
|
711
|
+
//
|
|
712
|
+
const data = this.safeDict(message, 'data', {});
|
|
527
713
|
const marketId = this.safeString(data, 'symbol');
|
|
528
|
-
const candles = this.
|
|
714
|
+
const candles = this.safeList(data, 'candles', []);
|
|
529
715
|
const topic = this.safeString(message, 'topic');
|
|
530
716
|
const parts = topic.split('_');
|
|
531
717
|
const interval = this.safeString(parts, 1);
|
|
@@ -541,15 +727,25 @@ class kucoin extends kucoin$1["default"] {
|
|
|
541
727
|
stored = new Cache.ArrayCacheByTimestamp(limit);
|
|
542
728
|
this.ohlcvs[symbol][timeframe] = stored;
|
|
543
729
|
}
|
|
544
|
-
const
|
|
545
|
-
|
|
730
|
+
const isContractMarket = (topic.indexOf('contractMarket') >= 0);
|
|
731
|
+
const baseVolumeIndex = isContractMarket ? 6 : 5; // Note value 5 is incorrect and will be fixed in subsequent versions of kucoin
|
|
732
|
+
const parsed = [
|
|
733
|
+
this.safeTimestamp(candles, 0),
|
|
734
|
+
this.safeNumber(candles, 1),
|
|
735
|
+
this.safeNumber(candles, 3),
|
|
736
|
+
this.safeNumber(candles, 4),
|
|
737
|
+
this.safeNumber(candles, 2),
|
|
738
|
+
this.safeNumber(candles, baseVolumeIndex),
|
|
739
|
+
];
|
|
740
|
+
stored.append(parsed);
|
|
546
741
|
client.resolve(stored, messageHash);
|
|
547
742
|
}
|
|
548
743
|
/**
|
|
549
744
|
* @method
|
|
550
745
|
* @name kucoin#watchTrades
|
|
551
746
|
* @description get the list of most recent trades for a particular symbol
|
|
552
|
-
* @see https://www.kucoin.com/docs
|
|
747
|
+
* @see https://www.kucoin.com/docs-new/3470072w0
|
|
748
|
+
* @see https://www.kucoin.com/docs-new/3470084w0
|
|
553
749
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
554
750
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
555
751
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
@@ -563,7 +759,8 @@ class kucoin extends kucoin$1["default"] {
|
|
|
563
759
|
* @method
|
|
564
760
|
* @name kucoin#watchTradesForSymbols
|
|
565
761
|
* @description get the list of most recent trades for a particular symbol
|
|
566
|
-
* @see https://www.kucoin.com/docs
|
|
762
|
+
* @see https://www.kucoin.com/docs-new/3470072w0
|
|
763
|
+
* @see https://www.kucoin.com/docs-new/3470084w0
|
|
567
764
|
* @param {string[]} symbols
|
|
568
765
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
569
766
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
@@ -576,17 +773,23 @@ class kucoin extends kucoin$1["default"] {
|
|
|
576
773
|
throw new errors.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
|
|
577
774
|
}
|
|
578
775
|
await this.loadMarkets();
|
|
579
|
-
symbols = this.marketSymbols(symbols);
|
|
776
|
+
symbols = this.marketSymbols(symbols, undefined, false, true);
|
|
777
|
+
const firstMarket = this.getMarketFromSymbols(symbols);
|
|
778
|
+
const isFuturesMethod = firstMarket['contract'];
|
|
580
779
|
const marketIds = this.marketIds(symbols);
|
|
581
|
-
const url = await this.negotiate(false);
|
|
780
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
582
781
|
const messageHashes = [];
|
|
583
782
|
const subscriptionHashes = [];
|
|
584
|
-
|
|
783
|
+
let channelName = '/market/match:';
|
|
784
|
+
if (isFuturesMethod) {
|
|
785
|
+
channelName = '/contractMarket/execution:';
|
|
786
|
+
}
|
|
787
|
+
const topic = channelName + marketIds.join(',');
|
|
585
788
|
for (let i = 0; i < symbols.length; i++) {
|
|
586
789
|
const symbol = symbols[i];
|
|
587
790
|
messageHashes.push('trades:' + symbol);
|
|
588
791
|
const marketId = marketIds[i];
|
|
589
|
-
subscriptionHashes.push(
|
|
792
|
+
subscriptionHashes.push(channelName + marketId);
|
|
590
793
|
}
|
|
591
794
|
const trades = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, params);
|
|
592
795
|
if (this.newUpdates) {
|
|
@@ -600,24 +803,36 @@ class kucoin extends kucoin$1["default"] {
|
|
|
600
803
|
* @method
|
|
601
804
|
* @name kucoin#unWatchTradesForSymbols
|
|
602
805
|
* @description unWatches trades stream
|
|
603
|
-
* @see https://www.kucoin.com/docs
|
|
806
|
+
* @see https://www.kucoin.com/docs-new/3470072w0
|
|
807
|
+
* @see https://www.kucoin.com/docs-new/3470084w0
|
|
604
808
|
* @param {string} symbols
|
|
605
809
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
606
810
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
|
|
607
811
|
*/
|
|
608
812
|
async unWatchTradesForSymbols(symbols, params = {}) {
|
|
609
813
|
await this.loadMarkets();
|
|
610
|
-
symbols = this.marketSymbols(symbols, undefined, false);
|
|
814
|
+
symbols = this.marketSymbols(symbols, undefined, false, true);
|
|
611
815
|
const marketIds = this.marketIds(symbols);
|
|
612
|
-
const
|
|
816
|
+
const firstMarket = this.getMarketFromSymbols(symbols);
|
|
817
|
+
const isFuturesMethod = firstMarket['contract'];
|
|
818
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
613
819
|
const messageHashes = [];
|
|
614
820
|
const subscriptionHashes = [];
|
|
615
|
-
|
|
821
|
+
let channelName = '/market/match:';
|
|
822
|
+
if (isFuturesMethod) {
|
|
823
|
+
channelName = '/contractMarket/execution:';
|
|
824
|
+
}
|
|
825
|
+
const topic = channelName + marketIds.join(',');
|
|
616
826
|
for (let i = 0; i < symbols.length; i++) {
|
|
617
827
|
const symbol = symbols[i];
|
|
618
828
|
messageHashes.push('unsubscribe:trades:' + symbol);
|
|
619
829
|
subscriptionHashes.push('trades:' + symbol);
|
|
620
830
|
}
|
|
831
|
+
// we have to add the topic to the messageHashes and subMessageHashes
|
|
832
|
+
// because handleSubscriptionStatus needs them to remove the subscription from the client
|
|
833
|
+
// without them subscription would never be removed and re-subscribe would fail because of duplicate subscriptionHash
|
|
834
|
+
messageHashes.push(topic);
|
|
835
|
+
subscriptionHashes.push(topic);
|
|
621
836
|
const subscription = {
|
|
622
837
|
'messageHashes': messageHashes,
|
|
623
838
|
'subMessageHashes': subscriptionHashes,
|
|
@@ -631,7 +846,8 @@ class kucoin extends kucoin$1["default"] {
|
|
|
631
846
|
* @method
|
|
632
847
|
* @name kucoin#unWatchTrades
|
|
633
848
|
* @description unWatches trades stream
|
|
634
|
-
* @see https://www.kucoin.com/docs
|
|
849
|
+
* @see https://www.kucoin.com/docs-new/3470072w0
|
|
850
|
+
* @see https://www.kucoin.com/docs-new/3470084w0
|
|
635
851
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
636
852
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
637
853
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
|
|
@@ -659,18 +875,20 @@ class kucoin extends kucoin$1["default"] {
|
|
|
659
875
|
// "type": "message"
|
|
660
876
|
// }
|
|
661
877
|
//
|
|
662
|
-
const data = this.
|
|
663
|
-
const
|
|
878
|
+
const data = this.safeDict(message, 'data', {});
|
|
879
|
+
const marketId = this.safeString(data, 'symbol');
|
|
880
|
+
const market = this.safeMarket(marketId);
|
|
881
|
+
const trade = this.parseTrade(data, market);
|
|
664
882
|
const symbol = trade['symbol'];
|
|
665
883
|
const messageHash = 'trades:' + symbol;
|
|
666
|
-
|
|
667
|
-
if (trades === undefined) {
|
|
884
|
+
if (!(symbol in this.trades)) {
|
|
668
885
|
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
669
|
-
|
|
670
|
-
this.trades[symbol] =
|
|
886
|
+
const stored = new Cache.ArrayCache(limit);
|
|
887
|
+
this.trades[symbol] = stored;
|
|
671
888
|
}
|
|
672
|
-
trades
|
|
673
|
-
|
|
889
|
+
const cache = this.trades[symbol];
|
|
890
|
+
cache.append(trade);
|
|
891
|
+
client.resolve(cache, messageHash);
|
|
674
892
|
}
|
|
675
893
|
/**
|
|
676
894
|
* @method
|
|
@@ -723,15 +941,16 @@ class kucoin extends kucoin$1["default"] {
|
|
|
723
941
|
/**
|
|
724
942
|
* @method
|
|
725
943
|
* @name kucoin#watchOrderBookForSymbols
|
|
726
|
-
* @see https://www.kucoin.com/docs/
|
|
727
|
-
* @see https://www.kucoin.com/docs/
|
|
728
|
-
* @see https://www.kucoin.com/docs/
|
|
729
|
-
* @see https://www.kucoin.com/docs
|
|
944
|
+
* @see https://www.kucoin.com/docs-new/3470069w0 // spot level 5
|
|
945
|
+
* @see https://www.kucoin.com/docs-new/3470070w0 // spot level 50
|
|
946
|
+
* @see https://www.kucoin.com/docs-new/3470068w0 // spot incremental
|
|
947
|
+
* @see https://www.kucoin.com/docs-new/3470083w0 // futures level 5
|
|
948
|
+
* @see https://www.kucoin.com/docs-new/3470097w0 // futures level 50
|
|
949
|
+
* @see https://www.kucoin.com/docs-new/3470082w0 // futures incremental
|
|
730
950
|
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
731
951
|
* @param {string[]} symbols unified array of symbols
|
|
732
952
|
* @param {int} [limit] the maximum amount of order book entries to return
|
|
733
953
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
734
|
-
* @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
|
|
735
954
|
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
|
|
736
955
|
*/
|
|
737
956
|
async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
|
|
@@ -747,11 +966,19 @@ class kucoin extends kucoin$1["default"] {
|
|
|
747
966
|
await this.loadMarkets();
|
|
748
967
|
symbols = this.marketSymbols(symbols);
|
|
749
968
|
const marketIds = this.marketIds(symbols);
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
969
|
+
const firstMarket = this.getMarketFromSymbols(symbols);
|
|
970
|
+
const isFuturesMethod = firstMarket['contract'];
|
|
971
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
972
|
+
let method = isFuturesMethod ? '/contractMarket/level2' : '/market/level2';
|
|
973
|
+
const optionName = isFuturesMethod ? 'contractMethod' : 'spotMethod';
|
|
974
|
+
[method, params] = this.handleOptionAndParams2(params, 'watchOrderBook', optionName, 'method', method);
|
|
975
|
+
if (method.indexOf('Depth') === -1) {
|
|
976
|
+
if ((limit === 5) || (limit === 50)) {
|
|
977
|
+
if (!isFuturesMethod) {
|
|
978
|
+
method = '/spotMarket/level2';
|
|
979
|
+
}
|
|
980
|
+
method += 'Depth' + limit.toString();
|
|
981
|
+
}
|
|
755
982
|
}
|
|
756
983
|
const topic = method + ':' + marketIds.join(',');
|
|
757
984
|
const messageHashes = [];
|
|
@@ -763,7 +990,7 @@ class kucoin extends kucoin$1["default"] {
|
|
|
763
990
|
subscriptionHashes.push(method + ':' + marketId);
|
|
764
991
|
}
|
|
765
992
|
let subscription = {};
|
|
766
|
-
if (method === '/market/level2') { // other streams return the entire orderbook, so we don't need to fetch the snapshot through REST
|
|
993
|
+
if ((method === '/market/level2') || (method === '/contractMarket/level2')) { // other streams return the entire orderbook, so we don't need to fetch the snapshot through REST
|
|
767
994
|
subscription = {
|
|
768
995
|
'method': this.handleOrderBookSubscription,
|
|
769
996
|
'symbols': symbols,
|
|
@@ -776,27 +1003,37 @@ class kucoin extends kucoin$1["default"] {
|
|
|
776
1003
|
/**
|
|
777
1004
|
* @method
|
|
778
1005
|
* @name kucoin#unWatchOrderBookForSymbols
|
|
779
|
-
* @see https://www.kucoin.com/docs/
|
|
780
|
-
* @see https://www.kucoin.com/docs/
|
|
781
|
-
* @see https://www.kucoin.com/docs/
|
|
782
|
-
* @see https://www.kucoin.com/docs
|
|
1006
|
+
* @see https://www.kucoin.com/docs-new/3470069w0 // spot level 5
|
|
1007
|
+
* @see https://www.kucoin.com/docs-new/3470070w0 // spot level 50
|
|
1008
|
+
* @see https://www.kucoin.com/docs-new/3470068w0 // spot incremental
|
|
1009
|
+
* @see https://www.kucoin.com/docs-new/3470083w0 // futures level 5
|
|
1010
|
+
* @see https://www.kucoin.com/docs-new/3470097w0 // futures level 50
|
|
1011
|
+
* @see https://www.kucoin.com/docs-new/3470082w0 // futures incremental
|
|
783
1012
|
* @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
784
1013
|
* @param {string[]} symbols unified array of symbols
|
|
785
1014
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
786
|
-
* @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
|
|
1015
|
+
* @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' or '/contractMarket/level2' or '/contractMarket/level2Depth5' or '/contractMarket/level2Depth50' default is '/market/level2' for spot and '/contractMarket/level2' for futures
|
|
787
1016
|
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
|
|
788
1017
|
*/
|
|
789
1018
|
async unWatchOrderBookForSymbols(symbols, params = {}) {
|
|
790
1019
|
const limit = this.safeInteger(params, 'limit');
|
|
791
1020
|
params = this.omit(params, 'limit');
|
|
792
1021
|
await this.loadMarkets();
|
|
793
|
-
symbols = this.marketSymbols(symbols, undefined, false);
|
|
1022
|
+
symbols = this.marketSymbols(symbols, undefined, false, true);
|
|
794
1023
|
const marketIds = this.marketIds(symbols);
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
1024
|
+
const firstMarket = this.getMarketFromSymbols(symbols);
|
|
1025
|
+
const isFuturesMethod = firstMarket['contract'];
|
|
1026
|
+
const url = await this.negotiate(false, isFuturesMethod);
|
|
1027
|
+
let method = isFuturesMethod ? '/contractMarket/level2' : '/market/level2';
|
|
1028
|
+
const optionName = isFuturesMethod ? 'contractMethod' : 'spotMethod';
|
|
1029
|
+
[method, params] = this.handleOptionAndParams2(params, 'watchOrderBook', optionName, 'method', method);
|
|
1030
|
+
if (method.indexOf('Depth') === -1) {
|
|
1031
|
+
if ((limit === 5) || (limit === 50)) {
|
|
1032
|
+
if (!isFuturesMethod) {
|
|
1033
|
+
method = '/spotMarket/level2';
|
|
1034
|
+
}
|
|
1035
|
+
method += 'Depth' + limit.toString();
|
|
1036
|
+
}
|
|
800
1037
|
}
|
|
801
1038
|
const topic = method + ':' + marketIds.join(',');
|
|
802
1039
|
const messageHashes = [];
|
|
@@ -806,6 +1043,11 @@ class kucoin extends kucoin$1["default"] {
|
|
|
806
1043
|
messageHashes.push('unsubscribe:orderbook:' + symbol);
|
|
807
1044
|
subscriptionHashes.push('orderbook:' + symbol);
|
|
808
1045
|
}
|
|
1046
|
+
// we have to add the topic to the messageHashes and subMessageHashes
|
|
1047
|
+
// because handleSubscriptionStatus needs them to remove the subscription from the client
|
|
1048
|
+
// without them subscription would never be removed and re-subscribe would fail because of duplicate subscriptionHash
|
|
1049
|
+
messageHashes.push(topic);
|
|
1050
|
+
subscriptionHashes.push(topic);
|
|
809
1051
|
const subscription = {
|
|
810
1052
|
'messageHashes': messageHashes,
|
|
811
1053
|
'symbols': symbols,
|
|
@@ -856,8 +1098,7 @@ class kucoin extends kucoin$1["default"] {
|
|
|
856
1098
|
// "subject": "level2"
|
|
857
1099
|
// }
|
|
858
1100
|
//
|
|
859
|
-
const data = this.
|
|
860
|
-
const subject = this.safeString(message, 'subject');
|
|
1101
|
+
const data = this.safeDict(message, 'data');
|
|
861
1102
|
const topic = this.safeString(message, 'topic');
|
|
862
1103
|
const topicParts = topic.split(':');
|
|
863
1104
|
const topicSymbol = this.safeString(topicParts, 1);
|
|
@@ -866,7 +1107,7 @@ class kucoin extends kucoin$1["default"] {
|
|
|
866
1107
|
const symbol = this.safeSymbol(marketId, undefined, '-');
|
|
867
1108
|
const messageHash = 'orderbook:' + symbol;
|
|
868
1109
|
// let orderbook = this.safeDict (this.orderbooks, symbol);
|
|
869
|
-
if (
|
|
1110
|
+
if (topic.indexOf('Depth') >= 0) {
|
|
870
1111
|
if (!(symbol in this.orderbooks)) {
|
|
871
1112
|
this.orderbooks[symbol] = this.orderBook();
|
|
872
1113
|
}
|
|
@@ -912,14 +1153,14 @@ class kucoin extends kucoin$1["default"] {
|
|
|
912
1153
|
getCacheIndex(orderbook, cache) {
|
|
913
1154
|
const firstDelta = this.safeValue(cache, 0);
|
|
914
1155
|
const nonce = this.safeInteger(orderbook, 'nonce');
|
|
915
|
-
const firstDeltaStart = this.
|
|
1156
|
+
const firstDeltaStart = this.safeInteger2(firstDelta, 'sequenceStart', 'sequence');
|
|
916
1157
|
if (nonce < firstDeltaStart - 1) {
|
|
917
1158
|
return -1;
|
|
918
1159
|
}
|
|
919
1160
|
for (let i = 0; i < cache.length; i++) {
|
|
920
1161
|
const delta = cache[i];
|
|
921
|
-
const deltaStart = this.
|
|
922
|
-
const deltaEnd = this.
|
|
1162
|
+
const deltaStart = this.safeInteger2(delta, 'sequenceStart', 'sequence');
|
|
1163
|
+
const deltaEnd = this.safeInteger2(delta, 'sequenceEnd', 'timestamp'); // todo check
|
|
923
1164
|
if ((nonce >= deltaStart - 1) && (nonce < deltaEnd)) {
|
|
924
1165
|
return i;
|
|
925
1166
|
}
|
|
@@ -928,16 +1169,34 @@ class kucoin extends kucoin$1["default"] {
|
|
|
928
1169
|
}
|
|
929
1170
|
handleDelta(orderbook, delta) {
|
|
930
1171
|
const timestamp = this.safeInteger2(delta, 'time', 'timestamp');
|
|
931
|
-
orderbook['nonce'] = this.
|
|
1172
|
+
orderbook['nonce'] = this.safeInteger2(delta, 'sequenceEnd', 'sequence', timestamp);
|
|
932
1173
|
orderbook['timestamp'] = timestamp;
|
|
933
1174
|
orderbook['datetime'] = this.iso8601(timestamp);
|
|
934
|
-
const
|
|
935
|
-
const bids = this.safeValue(changes, 'bids', []);
|
|
936
|
-
const asks = this.safeValue(changes, 'asks', []);
|
|
1175
|
+
const change = this.safeString(delta, 'change');
|
|
937
1176
|
const storedBids = orderbook['bids'];
|
|
938
1177
|
const storedAsks = orderbook['asks'];
|
|
939
|
-
|
|
940
|
-
|
|
1178
|
+
if (change !== undefined) {
|
|
1179
|
+
// handling futures orderbook update
|
|
1180
|
+
const splitChange = change.split(',');
|
|
1181
|
+
const price = this.safeNumber(splitChange, 0);
|
|
1182
|
+
const side = this.safeString(splitChange, 1);
|
|
1183
|
+
const quantity = this.safeNumber(splitChange, 2);
|
|
1184
|
+
const type = (side === 'buy') ? 'bids' : 'asks';
|
|
1185
|
+
const value = [price, quantity];
|
|
1186
|
+
if (type === 'bids') {
|
|
1187
|
+
storedBids.storeArray(value);
|
|
1188
|
+
}
|
|
1189
|
+
else {
|
|
1190
|
+
storedAsks.storeArray(value);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
else {
|
|
1194
|
+
const changes = this.safeDict(delta, 'changes', delta);
|
|
1195
|
+
const bids = this.safeList(changes, 'bids', []);
|
|
1196
|
+
const asks = this.safeList(changes, 'asks', []);
|
|
1197
|
+
this.handleBidAsks(storedBids, bids);
|
|
1198
|
+
this.handleBidAsks(storedAsks, asks);
|
|
1199
|
+
}
|
|
941
1200
|
}
|
|
942
1201
|
handleBidAsks(bookSide, bidAsks) {
|
|
943
1202
|
for (let i = 0; i < bidAsks.length; i++) {
|
|
@@ -947,7 +1206,7 @@ class kucoin extends kucoin$1["default"] {
|
|
|
947
1206
|
}
|
|
948
1207
|
handleOrderBookSubscription(client, message, subscription) {
|
|
949
1208
|
const limit = this.safeInteger(subscription, 'limit');
|
|
950
|
-
const symbols = this.
|
|
1209
|
+
const symbols = this.safeList(subscription, 'symbols');
|
|
951
1210
|
if (symbols === undefined) {
|
|
952
1211
|
const symbol = this.safeString(subscription, 'symbol');
|
|
953
1212
|
this.orderbooks[symbol] = this.orderBook({}, limit);
|
|
@@ -1010,36 +1269,63 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1010
1269
|
* @method
|
|
1011
1270
|
* @name kucoin#watchOrders
|
|
1012
1271
|
* @description watches information on multiple orders made by the user
|
|
1013
|
-
* @see https://www.kucoin.com/docs/
|
|
1014
|
-
* @see https://www.kucoin.com/docs/
|
|
1272
|
+
* @see https://www.kucoin.com/docs-new/3470074w0 // spot regular orders
|
|
1273
|
+
* @see https://www.kucoin.com/docs-new/3470139w0 // spot trigger orders
|
|
1274
|
+
* @see https://www.kucoin.com/docs-new/3470090w0 // contract regular orders
|
|
1275
|
+
* @see https://www.kucoin.com/docs-new/3470091w0 // contract trigger orders
|
|
1015
1276
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1016
1277
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1017
1278
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1018
1279
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1019
1280
|
* @param {boolean} [params.trigger] trigger orders are watched if true
|
|
1281
|
+
* @param {string} [params.type] 'spot' or 'swap' (default is 'spot' if symbol is not provided)
|
|
1020
1282
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1021
1283
|
*/
|
|
1022
1284
|
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1023
1285
|
await this.loadMarkets();
|
|
1024
|
-
const trigger = this.
|
|
1286
|
+
const trigger = this.safeBool2(params, 'stop', 'trigger');
|
|
1025
1287
|
params = this.omit(params, ['stop', 'trigger']);
|
|
1026
|
-
|
|
1027
|
-
const topic = trigger ? '/spotMarket/advancedOrders' : '/spotMarket/tradeOrders';
|
|
1028
|
-
const request = {
|
|
1029
|
-
'privateChannel': true,
|
|
1030
|
-
};
|
|
1288
|
+
let market = undefined;
|
|
1031
1289
|
let messageHash = 'orders';
|
|
1032
1290
|
if (symbol !== undefined) {
|
|
1033
|
-
|
|
1291
|
+
market = this.market(symbol);
|
|
1034
1292
|
symbol = market['symbol'];
|
|
1035
1293
|
messageHash = messageHash + ':' + symbol;
|
|
1036
1294
|
}
|
|
1295
|
+
let marketType = undefined;
|
|
1296
|
+
[marketType, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
|
|
1297
|
+
const isFuturesMethod = ((marketType !== 'spot') && (marketType !== 'margin'));
|
|
1298
|
+
const url = await this.negotiate(true, isFuturesMethod);
|
|
1299
|
+
let topic = trigger ? '/spotMarket/advancedOrders' : '/spotMarket/tradeOrders';
|
|
1300
|
+
if (isFuturesMethod) {
|
|
1301
|
+
topic = trigger ? '/contractMarket/advancedOrders' : '/contractMarket/tradeOrders';
|
|
1302
|
+
}
|
|
1303
|
+
if (symbol === undefined) {
|
|
1304
|
+
const suffix = this.getOrdersMessageHashSuffix(topic);
|
|
1305
|
+
messageHash += suffix;
|
|
1306
|
+
}
|
|
1307
|
+
const request = {
|
|
1308
|
+
'privateChannel': true,
|
|
1309
|
+
};
|
|
1037
1310
|
const orders = await this.subscribe(url, messageHash, topic, this.extend(request, params));
|
|
1038
1311
|
if (this.newUpdates) {
|
|
1039
1312
|
limit = orders.getLimit(symbol, limit);
|
|
1040
1313
|
}
|
|
1041
1314
|
return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
|
|
1042
1315
|
}
|
|
1316
|
+
getOrdersMessageHashSuffix(topic) {
|
|
1317
|
+
let suffix = '-spot';
|
|
1318
|
+
if (topic === '/spotMarket/advancedOrders') {
|
|
1319
|
+
suffix += '-trigger';
|
|
1320
|
+
}
|
|
1321
|
+
else if (topic === '/contractMarket/tradeOrders') {
|
|
1322
|
+
suffix = '-contract';
|
|
1323
|
+
}
|
|
1324
|
+
else if (topic === '/contractMarket/advancedOrders') {
|
|
1325
|
+
suffix = '-contract-trigger';
|
|
1326
|
+
}
|
|
1327
|
+
return suffix;
|
|
1328
|
+
}
|
|
1043
1329
|
parseWsOrderStatus(status) {
|
|
1044
1330
|
const statuses = {
|
|
1045
1331
|
'open': 'open',
|
|
@@ -1090,13 +1376,42 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1090
1376
|
// "type": "triggered"
|
|
1091
1377
|
// }
|
|
1092
1378
|
//
|
|
1379
|
+
// futures
|
|
1380
|
+
// {
|
|
1381
|
+
// "symbol": "ETHUSDTM",
|
|
1382
|
+
// "orderType": "market",
|
|
1383
|
+
// "side": "buy",
|
|
1384
|
+
// "canceledSize": "0",
|
|
1385
|
+
// "orderId": "416204113500479490",
|
|
1386
|
+
// "positionSide": "LONG",
|
|
1387
|
+
// "liquidity": "taker",
|
|
1388
|
+
// "marginMode": "ISOLATED",
|
|
1389
|
+
// "type": "match",
|
|
1390
|
+
// "feeType": "takerFee",
|
|
1391
|
+
// "orderTime": "1772043995356345762",
|
|
1392
|
+
// "size": "1",
|
|
1393
|
+
// "filledSize": "1",
|
|
1394
|
+
// "price": "0",
|
|
1395
|
+
// "matchPrice": "2068.55",
|
|
1396
|
+
// "matchSize": "1",
|
|
1397
|
+
// "remainSize": "0",
|
|
1398
|
+
// "tradeId": "1815302608109",
|
|
1399
|
+
// "clientOid": "9f7a2be0-effe-45bd-bdc8-1614715a583a",
|
|
1400
|
+
// "tradeType": "trade",
|
|
1401
|
+
// "status": "match",
|
|
1402
|
+
// "ts": 1772043995362000000
|
|
1403
|
+
// }
|
|
1404
|
+
//
|
|
1093
1405
|
const rawType = this.safeString(order, 'type');
|
|
1094
1406
|
let status = this.parseWsOrderStatus(rawType);
|
|
1095
|
-
|
|
1407
|
+
let timestamp = this.safeInteger2(order, 'orderTime', 'createdAt');
|
|
1096
1408
|
const marketId = this.safeString(order, 'symbol');
|
|
1097
1409
|
market = this.safeMarket(marketId, market);
|
|
1410
|
+
if (market['contract']) {
|
|
1411
|
+
timestamp = this.safeIntegerProduct(order, 'orderTime', 0.000001);
|
|
1412
|
+
}
|
|
1098
1413
|
const triggerPrice = this.safeString(order, 'stopPrice');
|
|
1099
|
-
const triggerSuccess = this.
|
|
1414
|
+
const triggerSuccess = this.safeBool(order, 'triggerSuccess');
|
|
1100
1415
|
const triggerFail = (triggerSuccess !== true) && (triggerSuccess !== undefined); // TODO: updated to triggerSuccess === False once transpiler transpiles it correctly
|
|
1101
1416
|
if ((status === 'triggered') && triggerFail) {
|
|
1102
1417
|
status = 'canceled';
|
|
@@ -1147,8 +1462,7 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1147
1462
|
// "type": "open"
|
|
1148
1463
|
// }
|
|
1149
1464
|
//
|
|
1150
|
-
const
|
|
1151
|
-
const data = this.safeValue(message, 'data');
|
|
1465
|
+
const data = this.safeDict(message, 'data');
|
|
1152
1466
|
const tradeId = this.safeString(data, 'tradeId');
|
|
1153
1467
|
if (tradeId !== undefined) {
|
|
1154
1468
|
this.handleMyTrade(client, message);
|
|
@@ -1156,7 +1470,7 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1156
1470
|
const parsed = this.parseWsOrder(data);
|
|
1157
1471
|
const symbol = this.safeString(parsed, 'symbol');
|
|
1158
1472
|
const orderId = this.safeString(parsed, 'id');
|
|
1159
|
-
const triggerPrice = this.
|
|
1473
|
+
const triggerPrice = this.safeString(parsed, 'triggerPrice');
|
|
1160
1474
|
const isTriggerOrder = (triggerPrice !== undefined);
|
|
1161
1475
|
if (this.orders === undefined) {
|
|
1162
1476
|
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
|
|
@@ -1173,42 +1487,63 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1173
1487
|
}
|
|
1174
1488
|
}
|
|
1175
1489
|
cachedOrders.append(parsed);
|
|
1176
|
-
|
|
1490
|
+
const messageHash = 'orders';
|
|
1491
|
+
const topic = this.safeString(message, 'topic');
|
|
1492
|
+
const suffix = this.getOrdersMessageHashSuffix(topic);
|
|
1493
|
+
const typeSpecificMessageHash = messageHash + suffix;
|
|
1494
|
+
client.resolve(cachedOrders, typeSpecificMessageHash);
|
|
1177
1495
|
const symbolSpecificMessageHash = messageHash + ':' + symbol;
|
|
1178
1496
|
client.resolve(cachedOrders, symbolSpecificMessageHash);
|
|
1179
1497
|
}
|
|
1180
1498
|
/**
|
|
1181
1499
|
* @method
|
|
1182
1500
|
* @name kucoin#watchMyTrades
|
|
1183
|
-
* @description watches information on multiple trades made by the user
|
|
1184
|
-
* @see https://www.kucoin.com/docs
|
|
1501
|
+
* @description watches information on multiple trades made by the user on spot
|
|
1502
|
+
* @see https://www.kucoin.com/docs-new/3470074w0
|
|
1503
|
+
* @see https://www.kucoin.com/docs-new/3470090w0
|
|
1185
1504
|
* @param {string} symbol unified market symbol of the market trades were made in
|
|
1186
1505
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1187
1506
|
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
1188
1507
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1189
|
-
* @param {string} [params.method] '/spotMarket/tradeOrders' or '/spot/tradeFills' default is '/spotMarket/tradeOrders'
|
|
1508
|
+
* @param {string} [params.method] '/spotMarket/tradeOrders' or '/spot/tradeFills' or '/contractMarket/tradeOrders', default is '/spotMarket/tradeOrders'
|
|
1190
1509
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=trade-structure}
|
|
1191
1510
|
*/
|
|
1192
1511
|
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1193
1512
|
await this.loadMarkets();
|
|
1194
|
-
const url = await this.negotiate(true);
|
|
1195
|
-
let topic = undefined;
|
|
1196
|
-
[topic, params] = this.handleOptionAndParams(params, 'watchMyTrades', 'method', '/spotMarket/tradeOrders');
|
|
1197
|
-
const request = {
|
|
1198
|
-
'privateChannel': true,
|
|
1199
|
-
};
|
|
1200
1513
|
let messageHash = 'myTrades';
|
|
1514
|
+
let market = undefined;
|
|
1201
1515
|
if (symbol !== undefined) {
|
|
1202
|
-
|
|
1516
|
+
market = this.market(symbol);
|
|
1203
1517
|
symbol = market['symbol'];
|
|
1204
1518
|
messageHash = messageHash + ':' + market['symbol'];
|
|
1205
1519
|
}
|
|
1520
|
+
let marketType = undefined;
|
|
1521
|
+
[marketType, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
|
|
1522
|
+
const isFuturesMethod = ((marketType !== 'spot') && (marketType !== 'margin'));
|
|
1523
|
+
const url = await this.negotiate(true, isFuturesMethod);
|
|
1524
|
+
let topic = isFuturesMethod ? '/contractMarket/tradeOrders' : '/spotMarket/tradeOrders';
|
|
1525
|
+
const optionName = isFuturesMethod ? 'contractMethod' : 'spotMethod';
|
|
1526
|
+
[topic, params] = this.handleOptionAndParams2(params, 'watchMyTrades', optionName, 'method', topic);
|
|
1527
|
+
const request = {
|
|
1528
|
+
'privateChannel': true,
|
|
1529
|
+
};
|
|
1530
|
+
if (symbol === undefined) {
|
|
1531
|
+
const suffix = this.getMyTradesMessageHashSuffix(topic);
|
|
1532
|
+
messageHash += suffix;
|
|
1533
|
+
}
|
|
1206
1534
|
const trades = await this.subscribe(url, messageHash, topic, this.extend(request, params));
|
|
1207
1535
|
if (this.newUpdates) {
|
|
1208
1536
|
limit = trades.getLimit(symbol, limit);
|
|
1209
1537
|
}
|
|
1210
1538
|
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
|
|
1211
1539
|
}
|
|
1540
|
+
getMyTradesMessageHashSuffix(topic) {
|
|
1541
|
+
let suffix = '-spot';
|
|
1542
|
+
if (topic.indexOf('contractMarket') >= 0) {
|
|
1543
|
+
suffix = '-contract';
|
|
1544
|
+
}
|
|
1545
|
+
return suffix;
|
|
1546
|
+
}
|
|
1212
1547
|
handleMyTrade(client, message) {
|
|
1213
1548
|
//
|
|
1214
1549
|
// {
|
|
@@ -1247,7 +1582,10 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1247
1582
|
const myTrades = this.myTrades;
|
|
1248
1583
|
myTrades.append(parsed);
|
|
1249
1584
|
const messageHash = 'myTrades';
|
|
1250
|
-
|
|
1585
|
+
const topic = this.safeString(message, 'topic');
|
|
1586
|
+
const suffix = this.getMyTradesMessageHashSuffix(topic);
|
|
1587
|
+
const typeSpecificMessageHash = messageHash + suffix;
|
|
1588
|
+
client.resolve(this.myTrades, typeSpecificMessageHash);
|
|
1251
1589
|
const symbolSpecificMessageHash = messageHash + ':' + parsed['symbol'];
|
|
1252
1590
|
client.resolve(this.myTrades, symbolSpecificMessageHash);
|
|
1253
1591
|
}
|
|
@@ -1334,19 +1672,74 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1334
1672
|
* @method
|
|
1335
1673
|
* @name kucoin#watchBalance
|
|
1336
1674
|
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1337
|
-
* @see https://www.kucoin.com/docs/
|
|
1675
|
+
* @see https://www.kucoin.com/docs-new/3470075w0 // spot balance
|
|
1676
|
+
* @see https://www.kucoin.com/docs-new/3470092w0 // contract balance
|
|
1338
1677
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1678
|
+
* @param {string} [params.type] 'spot' or 'swap' (default is 'spot')
|
|
1339
1679
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
|
|
1340
1680
|
*/
|
|
1341
1681
|
async watchBalance(params = {}) {
|
|
1342
1682
|
await this.loadMarkets();
|
|
1343
|
-
const
|
|
1344
|
-
const
|
|
1683
|
+
const defaultType = this.safeString(this.options, 'defaultType', 'spot');
|
|
1684
|
+
const type = this.safeString(params, 'type', defaultType);
|
|
1685
|
+
params = this.omit(params, 'type');
|
|
1686
|
+
const accountsByType = this.safeDict(this.options, 'accountsByType', {});
|
|
1687
|
+
const uniformType = this.safeString(accountsByType, type, type);
|
|
1688
|
+
const isFuturesMethod = (uniformType === 'contract');
|
|
1689
|
+
const url = await this.negotiate(true, isFuturesMethod);
|
|
1690
|
+
const client = this.client(url);
|
|
1691
|
+
this.setBalanceCache(client, uniformType);
|
|
1692
|
+
const options = this.safeDict(this.options, 'watchBalance');
|
|
1693
|
+
const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
|
|
1694
|
+
const awaitBalanceSnapshot = this.safeBool(options, 'awaitBalanceSnapshot', true);
|
|
1695
|
+
if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
|
|
1696
|
+
await client.future(uniformType + ':fetchBalanceSnapshot');
|
|
1697
|
+
}
|
|
1698
|
+
const messageHash = uniformType + ':balance';
|
|
1699
|
+
const requestId = this.requestId().toString();
|
|
1700
|
+
const subscriptionHash = isFuturesMethod ? '/contractAccount/wallet' : '/account/balance';
|
|
1345
1701
|
const request = {
|
|
1702
|
+
'id': requestId,
|
|
1703
|
+
'type': 'subscribe',
|
|
1704
|
+
'topic': subscriptionHash,
|
|
1705
|
+
'response': true,
|
|
1346
1706
|
'privateChannel': true,
|
|
1347
1707
|
};
|
|
1348
|
-
const
|
|
1349
|
-
|
|
1708
|
+
const message = this.extend(request, params);
|
|
1709
|
+
if (!(subscriptionHash in client.subscriptions)) {
|
|
1710
|
+
client.subscriptions[requestId] = subscriptionHash;
|
|
1711
|
+
}
|
|
1712
|
+
return await this.watch(url, messageHash, message, type);
|
|
1713
|
+
}
|
|
1714
|
+
setBalanceCache(client, type) {
|
|
1715
|
+
if ((type in client.subscriptions) && (type in this.balance)) {
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
const options = this.safeDict(this.options, 'watchBalance');
|
|
1719
|
+
const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
|
|
1720
|
+
if (fetchBalanceSnapshot) {
|
|
1721
|
+
const messageHash = type + ':fetchBalanceSnapshot';
|
|
1722
|
+
if (!(messageHash in client.futures)) {
|
|
1723
|
+
client.future(messageHash);
|
|
1724
|
+
this.spawn(this.loadBalanceSnapshot, client, messageHash, type);
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
else {
|
|
1728
|
+
this.balance[type] = {};
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
async loadBalanceSnapshot(client, messageHash, type) {
|
|
1732
|
+
const params = {
|
|
1733
|
+
'type': type,
|
|
1734
|
+
};
|
|
1735
|
+
const response = await this.fetchBalance(params);
|
|
1736
|
+
this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
|
|
1737
|
+
// don't remove the future from the .futures cache
|
|
1738
|
+
if (messageHash in client.futures) {
|
|
1739
|
+
const future = client.futures[messageHash];
|
|
1740
|
+
future.resolve();
|
|
1741
|
+
client.resolve(this.balance[type], type + ':balance');
|
|
1742
|
+
}
|
|
1350
1743
|
}
|
|
1351
1744
|
handleBalance(client, message) {
|
|
1352
1745
|
//
|
|
@@ -1372,8 +1765,51 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1372
1765
|
// "total":"89"
|
|
1373
1766
|
// }
|
|
1374
1767
|
//
|
|
1375
|
-
|
|
1376
|
-
|
|
1768
|
+
// futures
|
|
1769
|
+
// {
|
|
1770
|
+
// "id": "6375553193027a0001f6566f",
|
|
1771
|
+
// "type": "message",
|
|
1772
|
+
// "topic": "/contractAccount/wallet",
|
|
1773
|
+
// "userId": "613a896885d8660006151f01",
|
|
1774
|
+
// "channelType": "private",
|
|
1775
|
+
// "subject": "availableBalance.change",
|
|
1776
|
+
// "data": {
|
|
1777
|
+
// "currency": "USDT",
|
|
1778
|
+
// "holdBalance": "0.0000000000",
|
|
1779
|
+
// "availableBalance": "14.0350281903",
|
|
1780
|
+
// "timestamp": "1668633905657"
|
|
1781
|
+
// }
|
|
1782
|
+
// }
|
|
1783
|
+
//
|
|
1784
|
+
// {
|
|
1785
|
+
// "topic": "/contractAccount/wallet",
|
|
1786
|
+
// "type": "message",
|
|
1787
|
+
// "subject": "walletBalance.change",
|
|
1788
|
+
// "id": "699f586d4416a80001df3804",
|
|
1789
|
+
// "userId": "64f99aced178640001306e6e",
|
|
1790
|
+
// "channelType": "private",
|
|
1791
|
+
// "data": {
|
|
1792
|
+
// "crossPosMargin": "0",
|
|
1793
|
+
// "isolatedOrderMargin": "0",
|
|
1794
|
+
// "holdBalance": "0",
|
|
1795
|
+
// "equity": "49.50050236",
|
|
1796
|
+
// "version": "2874",
|
|
1797
|
+
// "availableBalance": "28.67180236",
|
|
1798
|
+
// "isolatedPosMargin": "20.7308",
|
|
1799
|
+
// "maxWithdrawAmount": "28.67180236",
|
|
1800
|
+
// "walletBalance": "49.40260236",
|
|
1801
|
+
// "isolatedFundingFeeMargin": "0",
|
|
1802
|
+
// "crossUnPnl": "0",
|
|
1803
|
+
// "totalCrossMargin": "28.67180236",
|
|
1804
|
+
// "currency": "USDT",
|
|
1805
|
+
// "isolatedUnPnl": "0.0979",
|
|
1806
|
+
// "availableMargin": "28.67180236",
|
|
1807
|
+
// "crossOrderMargin": "0",
|
|
1808
|
+
// "timestamp": "1772050541214"
|
|
1809
|
+
// }
|
|
1810
|
+
// }
|
|
1811
|
+
//
|
|
1812
|
+
const data = this.safeDict(message, 'data', {});
|
|
1377
1813
|
const currencyId = this.safeString(data, 'currency');
|
|
1378
1814
|
const relationEvent = this.safeString(data, 'relationEvent');
|
|
1379
1815
|
let requestAccountType = undefined;
|
|
@@ -1381,27 +1817,210 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1381
1817
|
const relationEventParts = relationEvent.split('.');
|
|
1382
1818
|
requestAccountType = this.safeString(relationEventParts, 0);
|
|
1383
1819
|
}
|
|
1384
|
-
const
|
|
1385
|
-
|
|
1820
|
+
const topic = this.safeString(message, 'topic');
|
|
1821
|
+
if (topic === '/contractAccount/wallet') {
|
|
1822
|
+
requestAccountType = 'contract';
|
|
1823
|
+
}
|
|
1824
|
+
const accountsByType = this.safeDict(this.options, 'accountsByType');
|
|
1386
1825
|
const uniformType = this.safeString(accountsByType, requestAccountType, 'trade');
|
|
1387
1826
|
if (!(uniformType in this.balance)) {
|
|
1388
1827
|
this.balance[uniformType] = {};
|
|
1389
1828
|
}
|
|
1390
1829
|
this.balance[uniformType]['info'] = data;
|
|
1391
|
-
const timestamp = this.
|
|
1830
|
+
const timestamp = this.safeInteger2(data, 'time', 'timestamp');
|
|
1392
1831
|
this.balance[uniformType]['timestamp'] = timestamp;
|
|
1393
1832
|
this.balance[uniformType]['datetime'] = this.iso8601(timestamp);
|
|
1394
1833
|
const code = this.safeCurrencyCode(currencyId);
|
|
1395
1834
|
const account = this.account();
|
|
1396
|
-
|
|
1397
|
-
|
|
1835
|
+
let used = this.safeString2(data, 'hold', 'holdBalance');
|
|
1836
|
+
const isolatedPosMargin = this.omitZero(this.safeString(data, 'isolatedPosMargin'));
|
|
1837
|
+
if (isolatedPosMargin !== undefined) {
|
|
1838
|
+
used = Precise["default"].stringAdd(used, isolatedPosMargin);
|
|
1839
|
+
}
|
|
1840
|
+
account['free'] = this.safeString2(data, 'available', 'availableBalance');
|
|
1841
|
+
account['used'] = used;
|
|
1398
1842
|
account['total'] = this.safeString(data, 'total');
|
|
1399
1843
|
this.balance[uniformType][code] = account;
|
|
1400
1844
|
this.balance[uniformType] = this.safeBalance(this.balance[uniformType]);
|
|
1401
|
-
|
|
1402
|
-
|
|
1845
|
+
const messageHash = uniformType + ':balance';
|
|
1846
|
+
client.resolve(this.balance[uniformType], messageHash);
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* @method
|
|
1850
|
+
* @name kucoin#watchPosition
|
|
1851
|
+
* @description watch open positions for a specific symbol
|
|
1852
|
+
* @see https://www.kucoin.com/docs-new/3470093w0
|
|
1853
|
+
* @param {string|undefined} symbol unified market symbol
|
|
1854
|
+
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
1855
|
+
* @returns {object} a [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
1856
|
+
*/
|
|
1857
|
+
async watchPosition(symbol = undefined, params = {}) {
|
|
1858
|
+
if (symbol === undefined) {
|
|
1859
|
+
throw new errors.ArgumentsRequired(this.id + ' watchPosition() requires a symbol argument');
|
|
1860
|
+
}
|
|
1861
|
+
await this.loadMarkets();
|
|
1862
|
+
const url = await this.negotiate(true);
|
|
1863
|
+
const market = this.market(symbol);
|
|
1864
|
+
const topic = '/contract/position:' + market['id'];
|
|
1865
|
+
const request = {
|
|
1866
|
+
'privateChannel': true,
|
|
1867
|
+
};
|
|
1868
|
+
const messageHash = 'position:' + market['symbol'];
|
|
1869
|
+
const client = this.client(url);
|
|
1870
|
+
this.setPositionCache(client, symbol);
|
|
1871
|
+
const fetchPositionSnapshot = this.handleOption('watchPosition', 'fetchPositionSnapshot', true);
|
|
1872
|
+
const awaitPositionSnapshot = this.handleOption('watchPosition', 'awaitPositionSnapshot', true);
|
|
1873
|
+
const currentPosition = this.getCurrentPosition(symbol);
|
|
1874
|
+
if (fetchPositionSnapshot && awaitPositionSnapshot && currentPosition === undefined) {
|
|
1875
|
+
const snapshot = await client.future('fetchPositionSnapshot:' + symbol);
|
|
1876
|
+
return snapshot;
|
|
1877
|
+
}
|
|
1878
|
+
return await this.subscribe(url, messageHash, topic, this.extend(request, params));
|
|
1879
|
+
}
|
|
1880
|
+
getCurrentPosition(symbol) {
|
|
1881
|
+
if (this.positions === undefined) {
|
|
1882
|
+
return undefined;
|
|
1883
|
+
}
|
|
1884
|
+
const cache = this.positions.hashmap;
|
|
1885
|
+
const symbolCache = this.safeValue(cache, symbol, {});
|
|
1886
|
+
const values = Object.values(symbolCache);
|
|
1887
|
+
return this.safeValue(values, 0);
|
|
1888
|
+
}
|
|
1889
|
+
setPositionCache(client, symbol) {
|
|
1890
|
+
const fetchPositionSnapshot = this.handleOption('watchPosition', 'fetchPositionSnapshot', false);
|
|
1891
|
+
if (fetchPositionSnapshot) {
|
|
1892
|
+
const messageHash = 'fetchPositionSnapshot:' + symbol;
|
|
1893
|
+
if (!(messageHash in client.futures)) {
|
|
1894
|
+
client.future(messageHash);
|
|
1895
|
+
this.spawn(this.loadPositionSnapshot, client, messageHash, symbol);
|
|
1896
|
+
}
|
|
1403
1897
|
}
|
|
1404
1898
|
}
|
|
1899
|
+
async loadPositionSnapshot(client, messageHash, symbol) {
|
|
1900
|
+
const position = await this.fetchPosition(symbol);
|
|
1901
|
+
this.positions = new Cache.ArrayCacheBySymbolById();
|
|
1902
|
+
const cache = this.positions;
|
|
1903
|
+
cache.append(position);
|
|
1904
|
+
// don't remove the future from the .futures cache
|
|
1905
|
+
if (messageHash in client.futures) {
|
|
1906
|
+
const future = client.futures[messageHash];
|
|
1907
|
+
future.resolve(cache);
|
|
1908
|
+
client.resolve(position, 'position:' + symbol);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
handlePosition(client, message) {
|
|
1912
|
+
//
|
|
1913
|
+
// Position Changes Caused Operations
|
|
1914
|
+
// {
|
|
1915
|
+
// "type": "message",
|
|
1916
|
+
// "userId": "5c32d69203aa676ce4b543c7", // Deprecated, will detele later
|
|
1917
|
+
// "channelType": "private",
|
|
1918
|
+
// "topic": "/contract/position:XBTUSDM",
|
|
1919
|
+
// "subject": "position.change",
|
|
1920
|
+
// "data": {
|
|
1921
|
+
// "realisedGrossPnl": 0E-8, //Accumulated realised profit and loss
|
|
1922
|
+
// "symbol": "XBTUSDM", //Symbol
|
|
1923
|
+
// "crossMode": false, //Cross mode or not
|
|
1924
|
+
// "liquidationPrice": 1000000.0, //Liquidation price
|
|
1925
|
+
// "posLoss": 0E-8, //Manually added margin amount
|
|
1926
|
+
// "avgEntryPrice": 7508.22, //Average entry price
|
|
1927
|
+
// "unrealisedPnl": -0.00014735, //Unrealised profit and loss
|
|
1928
|
+
// "markPrice": 7947.83, //Mark price
|
|
1929
|
+
// "posMargin": 0.00266779, //Position margin
|
|
1930
|
+
// "autoDeposit": false, //Auto deposit margin or not
|
|
1931
|
+
// "riskLimit": 100000, //Risk limit
|
|
1932
|
+
// "unrealisedCost": 0.00266375, //Unrealised value
|
|
1933
|
+
// "posComm": 0.00000392, //Bankruptcy cost
|
|
1934
|
+
// "posMaint": 0.00001724, //Maintenance margin
|
|
1935
|
+
// "posCost": 0.00266375, //Position value
|
|
1936
|
+
// "maintMarginReq": 0.005, //Maintenance margin rate
|
|
1937
|
+
// "bankruptPrice": 1000000.0, //Bankruptcy price
|
|
1938
|
+
// "realisedCost": 0.00000271, //Currently accumulated realised position value
|
|
1939
|
+
// "markValue": 0.00251640, //Mark value
|
|
1940
|
+
// "posInit": 0.00266375, //Position margin
|
|
1941
|
+
// "realisedPnl": -0.00000253, //Realised profit and losts
|
|
1942
|
+
// "maintMargin": 0.00252044, //Position margin
|
|
1943
|
+
// "realLeverage": 1.06, //Leverage of the order
|
|
1944
|
+
// "changeReason": "positionChange", //changeReason:marginChange、positionChange、liquidation、autoAppendMarginStatusChange、adl
|
|
1945
|
+
// "currentCost": 0.00266375, //Current position value
|
|
1946
|
+
// "openingTimestamp": 1558433191000, //Open time
|
|
1947
|
+
// "currentQty": -20, //Current position
|
|
1948
|
+
// "delevPercentage": 0.52, //ADL ranking percentile
|
|
1949
|
+
// "currentComm": 0.00000271, //Current commission
|
|
1950
|
+
// "realisedGrossCost": 0E-8, //Accumulated reliased gross profit value
|
|
1951
|
+
// "isOpen": true, //Opened position or not
|
|
1952
|
+
// "posCross": 1.2E-7, //Manually added margin
|
|
1953
|
+
// "currentTimestamp": 1558506060394, //Current timestamp
|
|
1954
|
+
// "unrealisedRoePcnt": -0.0553, //Rate of return on investment
|
|
1955
|
+
// "unrealisedPnlPcnt": -0.0553, //Position profit and loss ratio
|
|
1956
|
+
// "settleCurrency": "XBT" //Currency used to clear and settle the trades
|
|
1957
|
+
// }
|
|
1958
|
+
// }
|
|
1959
|
+
// Position Changes Caused by Mark Price
|
|
1960
|
+
// {
|
|
1961
|
+
// "userId": "5cd3f1a7b7ebc19ae9558591", // Deprecated, will detele later
|
|
1962
|
+
// "topic": "/contract/position:XBTUSDM",
|
|
1963
|
+
// "subject": "position.change",
|
|
1964
|
+
// "data": {
|
|
1965
|
+
// "markPrice": 7947.83, //Mark price
|
|
1966
|
+
// "markValue": 0.00251640, //Mark value
|
|
1967
|
+
// "maintMargin": 0.00252044, //Position margin
|
|
1968
|
+
// "realLeverage": 10.06, //Leverage of the order
|
|
1969
|
+
// "unrealisedPnl": -0.00014735, //Unrealised profit and lost
|
|
1970
|
+
// "unrealisedRoePcnt": -0.0553, //Rate of return on investment
|
|
1971
|
+
// "unrealisedPnlPcnt": -0.0553, //Position profit and loss ratio
|
|
1972
|
+
// "delevPercentage": 0.52, //ADL ranking percentile
|
|
1973
|
+
// "currentTimestamp": 1558087175068, //Current timestamp
|
|
1974
|
+
// "settleCurrency": "XBT" //Currency used to clear and settle the trades
|
|
1975
|
+
// }
|
|
1976
|
+
// }
|
|
1977
|
+
// Funding Settlement
|
|
1978
|
+
// {
|
|
1979
|
+
// "userId": "xbc453tg732eba53a88ggyt8c", // Deprecated, will detele later
|
|
1980
|
+
// "topic": "/contract/position:XBTUSDM",
|
|
1981
|
+
// "subject": "position.settlement",
|
|
1982
|
+
// "data": {
|
|
1983
|
+
// "fundingTime": 1551770400000, //Funding time
|
|
1984
|
+
// "qty": 100, //Position siz
|
|
1985
|
+
// "markPrice": 3610.85, //Settlement price
|
|
1986
|
+
// "fundingRate": -0.002966, //Funding rate
|
|
1987
|
+
// "fundingFee": -296, //Funding fees
|
|
1988
|
+
// "ts": 1547697294838004923, //Current time (nanosecond)
|
|
1989
|
+
// "settleCurrency": "XBT" //Currency used to clear and settle the trades
|
|
1990
|
+
// }
|
|
1991
|
+
// }
|
|
1992
|
+
// Adjustmet result of risk limit level
|
|
1993
|
+
// {
|
|
1994
|
+
// "userId": "xbc453tg732eba53a88ggyt8c",
|
|
1995
|
+
// "topic": "/contract/position:ADAUSDTM",
|
|
1996
|
+
// "subject": "position.adjustRiskLimit",
|
|
1997
|
+
// "data": {
|
|
1998
|
+
// "success": true, // Successful or not
|
|
1999
|
+
// "riskLimitLevel": 1, // Current risk limit level
|
|
2000
|
+
// "msg": "" // Failure reason
|
|
2001
|
+
// }
|
|
2002
|
+
// }
|
|
2003
|
+
//
|
|
2004
|
+
const topic = this.safeString(message, 'topic', '');
|
|
2005
|
+
const parts = topic.split(':');
|
|
2006
|
+
const marketId = this.safeString(parts, 1);
|
|
2007
|
+
const symbol = this.safeSymbol(marketId, undefined, '');
|
|
2008
|
+
const cache = this.positions;
|
|
2009
|
+
const currentPosition = this.getCurrentPosition(symbol);
|
|
2010
|
+
const messageHash = 'position:' + symbol;
|
|
2011
|
+
const data = this.safeDict(message, 'data', {});
|
|
2012
|
+
const newPosition = this.parsePosition(data);
|
|
2013
|
+
const keys = Object.keys(newPosition);
|
|
2014
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2015
|
+
const key = keys[i];
|
|
2016
|
+
if (newPosition[key] === undefined) {
|
|
2017
|
+
delete newPosition[key];
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
const position = this.extend(currentPosition, newPosition);
|
|
2021
|
+
cache.append(position);
|
|
2022
|
+
client.resolve(position, messageHash);
|
|
2023
|
+
}
|
|
1405
2024
|
handleSubject(client, message) {
|
|
1406
2025
|
//
|
|
1407
2026
|
// {
|
|
@@ -1437,6 +2056,18 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1437
2056
|
'orderChange': this.handleOrder,
|
|
1438
2057
|
'stopOrder': this.handleOrder,
|
|
1439
2058
|
'/spot/tradeFills': this.handleMyTrade,
|
|
2059
|
+
// futures messages
|
|
2060
|
+
'ticker': this.handleTicker,
|
|
2061
|
+
'tickerV2': this.handleBidAsk,
|
|
2062
|
+
'candle.stick': this.handleOHLCV,
|
|
2063
|
+
'match': this.handleTrade,
|
|
2064
|
+
'orderUpdated': this.handleOrder,
|
|
2065
|
+
'symbolOrderChange': this.handleOrder,
|
|
2066
|
+
'availableBalance.change': this.handleBalance,
|
|
2067
|
+
'walletBalance.change': this.handleBalance,
|
|
2068
|
+
'position.change': this.handlePosition,
|
|
2069
|
+
'position.settlement': this.handlePosition,
|
|
2070
|
+
'position.adjustRiskLimit': this.handlePosition,
|
|
1440
2071
|
};
|
|
1441
2072
|
const method = this.safeValue(methods, subject);
|
|
1442
2073
|
if (method !== undefined) {
|
|
@@ -1492,6 +2123,16 @@ class kucoin extends kucoin$1["default"] {
|
|
|
1492
2123
|
method.call(this, client, message);
|
|
1493
2124
|
}
|
|
1494
2125
|
}
|
|
2126
|
+
getMessageHash(elementName, symbol = undefined) {
|
|
2127
|
+
// method from kucoinfutures
|
|
2128
|
+
// elementName can be 'ticker', 'bidask', ...
|
|
2129
|
+
if (symbol !== undefined) {
|
|
2130
|
+
return elementName + ':' + symbol;
|
|
2131
|
+
}
|
|
2132
|
+
else {
|
|
2133
|
+
return elementName + 's@all';
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
1495
2136
|
}
|
|
1496
2137
|
|
|
1497
2138
|
exports["default"] = kucoin;
|