ccxt 4.2.14 → 4.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/ccxt.browser.js +805 -184
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/js/ccxt.js +3 -1
- package/dist/cjs/js/src/ascendex.js +11 -6
- package/dist/cjs/js/src/base/Exchange.js +12 -12
- package/dist/cjs/js/src/binance.js +2 -2
- package/dist/cjs/js/src/bingx.js +41 -6
- package/dist/cjs/js/src/bitget.js +3 -3
- package/dist/cjs/js/src/bitmex.js +3 -6
- package/dist/cjs/js/src/bybit.js +3 -3
- package/dist/cjs/js/src/coinex.js +3 -3
- package/dist/cjs/js/src/coinone.js +1 -1
- package/dist/cjs/js/src/gate.js +3 -3
- package/dist/cjs/js/src/htx.js +2 -2
- package/dist/cjs/js/src/kraken.js +24 -2
- package/dist/cjs/js/src/kucoin.js +1 -1
- package/dist/cjs/js/src/kucoinfutures.js +2 -2
- package/dist/cjs/js/src/okx.js +1 -1
- package/dist/cjs/js/src/phemex.js +28 -25
- package/dist/cjs/js/src/pro/coinone.js +411 -0
- package/dist/cjs/js/src/pro/htx.js +6 -1
- package/dist/cjs/js/src/pro/krakenfutures.js +7 -1
- package/dist/cjs/js/src/pro/woo.js +126 -0
- package/dist/cjs/js/src/woo.js +3 -3
- package/js/ccxt.d.ts +4 -1
- package/js/ccxt.js +3 -1
- package/js/src/ascendex.js +11 -6
- package/js/src/base/Exchange.js +12 -12
- package/js/src/binance.js +2 -2
- package/js/src/bingx.d.ts +1 -0
- package/js/src/bingx.js +42 -7
- package/js/src/bitget.js +3 -3
- package/js/src/bitmex.js +3 -6
- package/js/src/bybit.js +3 -3
- package/js/src/coinex.js +3 -3
- package/js/src/coinone.js +1 -1
- package/js/src/gate.js +3 -3
- package/js/src/htx.js +2 -2
- package/js/src/kraken.d.ts +1 -0
- package/js/src/kraken.js +24 -2
- package/js/src/kucoin.js +1 -1
- package/js/src/kucoinfutures.js +2 -2
- package/js/src/okx.js +1 -1
- package/js/src/phemex.js +28 -25
- package/js/src/pro/coinone.d.ts +21 -0
- package/js/src/pro/coinone.js +412 -0
- package/js/src/pro/htx.js +6 -1
- package/js/src/pro/krakenfutures.js +7 -1
- package/js/src/pro/woo.d.ts +5 -1
- package/js/src/pro/woo.js +127 -1
- package/js/src/woo.js +3 -3
- package/package.json +1 -1
- package/skip-tests.json +1 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var coinone$1 = require('../coinone.js');
|
|
4
|
+
var errors = require('../base/errors.js');
|
|
5
|
+
var Cache = require('../base/ws/Cache.js');
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
class coinone extends coinone$1 {
|
|
10
|
+
describe() {
|
|
11
|
+
return this.deepExtend(super.describe(), {
|
|
12
|
+
'has': {
|
|
13
|
+
'ws': true,
|
|
14
|
+
'watchOrderBook': true,
|
|
15
|
+
'watchOrders': false,
|
|
16
|
+
'watchTrades': true,
|
|
17
|
+
'watchOHLCV': false,
|
|
18
|
+
'watchTicker': true,
|
|
19
|
+
'watchTickers': false,
|
|
20
|
+
},
|
|
21
|
+
'urls': {
|
|
22
|
+
'api': {
|
|
23
|
+
'ws': 'wss://stream.coinone.co.kr',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
'options': {
|
|
27
|
+
'expiresIn': '',
|
|
28
|
+
'userId': '',
|
|
29
|
+
'wsSessionToken': '',
|
|
30
|
+
'watchOrderBook': {
|
|
31
|
+
'snapshotDelay': 6,
|
|
32
|
+
'snapshotMaxRetries': 3,
|
|
33
|
+
},
|
|
34
|
+
'tradesLimit': 1000,
|
|
35
|
+
'OHLCVLimit': 1000,
|
|
36
|
+
},
|
|
37
|
+
'exceptions': {
|
|
38
|
+
'exact': {
|
|
39
|
+
'4009': errors.AuthenticationError,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
'streaming': {
|
|
43
|
+
'ping': this.ping,
|
|
44
|
+
'keepAlive': 20000,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
49
|
+
/**
|
|
50
|
+
* @method
|
|
51
|
+
* @name coinone#watchOrderBook
|
|
52
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
53
|
+
* @see https://docs.coinone.co.kr/reference/public-websocket-orderbook
|
|
54
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
55
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
56
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
57
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
58
|
+
*/
|
|
59
|
+
await this.loadMarkets();
|
|
60
|
+
const market = this.market(symbol);
|
|
61
|
+
const messageHash = 'orderbook:' + market['symbol'];
|
|
62
|
+
const url = this.urls['api']['ws'];
|
|
63
|
+
const request = {
|
|
64
|
+
'request_type': 'SUBSCRIBE',
|
|
65
|
+
'channel': 'ORDERBOOK',
|
|
66
|
+
'topic': {
|
|
67
|
+
'quote_currency': market['quote'],
|
|
68
|
+
'target_currency': market['base'],
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const message = this.extend(request, params);
|
|
72
|
+
const orderbook = await this.watch(url, messageHash, message, messageHash);
|
|
73
|
+
return orderbook.limit();
|
|
74
|
+
}
|
|
75
|
+
handleOrderBook(client, message) {
|
|
76
|
+
//
|
|
77
|
+
// {
|
|
78
|
+
// "response_type": "DATA",
|
|
79
|
+
// "channel": "ORDERBOOK",
|
|
80
|
+
// "data": {
|
|
81
|
+
// "quote_currency": "KRW",
|
|
82
|
+
// "target_currency": "BTC",
|
|
83
|
+
// "timestamp": 1705288918649,
|
|
84
|
+
// "id": "1705288918649001",
|
|
85
|
+
// "asks": [
|
|
86
|
+
// {
|
|
87
|
+
// "price": "58412000",
|
|
88
|
+
// "qty": "0.59919807"
|
|
89
|
+
// }
|
|
90
|
+
// ],
|
|
91
|
+
// "bids": [
|
|
92
|
+
// {
|
|
93
|
+
// "price": "58292000",
|
|
94
|
+
// "qty": "0.1045"
|
|
95
|
+
// }
|
|
96
|
+
// ]
|
|
97
|
+
// }
|
|
98
|
+
// }
|
|
99
|
+
//
|
|
100
|
+
const data = this.safeValue(message, 'data', {});
|
|
101
|
+
const baseId = this.safeStringUpper(data, 'target_currency');
|
|
102
|
+
const quoteId = this.safeStringUpper(data, 'quote_currency');
|
|
103
|
+
const base = this.safeCurrencyCode(baseId);
|
|
104
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
105
|
+
const symbol = this.symbol(base + '/' + quote);
|
|
106
|
+
const timestamp = this.safeInteger(data, 'timestamp');
|
|
107
|
+
let orderbook = this.safeValue(this.orderbooks, symbol);
|
|
108
|
+
if (orderbook === undefined) {
|
|
109
|
+
orderbook = this.orderBook();
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
orderbook.reset();
|
|
113
|
+
}
|
|
114
|
+
orderbook['symbol'] = symbol;
|
|
115
|
+
const asks = this.safeValue(data, 'asks', []);
|
|
116
|
+
const bids = this.safeValue(data, 'bids', []);
|
|
117
|
+
this.handleDeltas(orderbook['asks'], asks);
|
|
118
|
+
this.handleDeltas(orderbook['bids'], bids);
|
|
119
|
+
orderbook['timestamp'] = timestamp;
|
|
120
|
+
orderbook['datetime'] = this.iso8601(timestamp);
|
|
121
|
+
const messageHash = 'orderbook:' + symbol;
|
|
122
|
+
this.orderbooks[symbol] = orderbook;
|
|
123
|
+
client.resolve(orderbook, messageHash);
|
|
124
|
+
}
|
|
125
|
+
handleDelta(bookside, delta) {
|
|
126
|
+
const bidAsk = this.parseBidAsk(delta, 'price', 'qty');
|
|
127
|
+
bookside.storeArray(bidAsk);
|
|
128
|
+
}
|
|
129
|
+
async watchTicker(symbol, params = {}) {
|
|
130
|
+
/**
|
|
131
|
+
* @method
|
|
132
|
+
* @name coinone#watchTicker
|
|
133
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
134
|
+
* @see https://docs.coinone.co.kr/reference/public-websocket-ticker
|
|
135
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
136
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
137
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
138
|
+
*/
|
|
139
|
+
await this.loadMarkets();
|
|
140
|
+
const market = this.market(symbol);
|
|
141
|
+
const messageHash = 'ticker:' + market['symbol'];
|
|
142
|
+
const url = this.urls['api']['ws'];
|
|
143
|
+
const request = {
|
|
144
|
+
'request_type': 'SUBSCRIBE',
|
|
145
|
+
'channel': 'TICKER',
|
|
146
|
+
'topic': {
|
|
147
|
+
'quote_currency': market['quote'],
|
|
148
|
+
'target_currency': market['base'],
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
const message = this.extend(request, params);
|
|
152
|
+
return await this.watch(url, messageHash, message, messageHash);
|
|
153
|
+
}
|
|
154
|
+
handleTicker(client, message) {
|
|
155
|
+
//
|
|
156
|
+
// {
|
|
157
|
+
// "response_type": "DATA",
|
|
158
|
+
// "channel": "TICKER",
|
|
159
|
+
// "data": {
|
|
160
|
+
// "quote_currency": "KRW",
|
|
161
|
+
// "target_currency": "BTC",
|
|
162
|
+
// "timestamp": 1705301117198,
|
|
163
|
+
// "quote_volume": "19521465345.504",
|
|
164
|
+
// "target_volume": "334.81445168",
|
|
165
|
+
// "high": "58710000",
|
|
166
|
+
// "low": "57276000",
|
|
167
|
+
// "first": "57293000",
|
|
168
|
+
// "last": "58532000",
|
|
169
|
+
// "volume_power": "100",
|
|
170
|
+
// "ask_best_price": "58537000",
|
|
171
|
+
// "ask_best_qty": "0.1961",
|
|
172
|
+
// "bid_best_price": "58532000",
|
|
173
|
+
// "bid_best_qty": "0.00009258",
|
|
174
|
+
// "id": "1705301117198001",
|
|
175
|
+
// "yesterday_high": "59140000",
|
|
176
|
+
// "yesterday_low": "57273000",
|
|
177
|
+
// "yesterday_first": "58897000",
|
|
178
|
+
// "yesterday_last": "57301000",
|
|
179
|
+
// "yesterday_quote_volume": "12967227517.4262",
|
|
180
|
+
// "yesterday_target_volume": "220.09232233"
|
|
181
|
+
// }
|
|
182
|
+
// }
|
|
183
|
+
//
|
|
184
|
+
const data = this.safeValue(message, 'data', {});
|
|
185
|
+
const ticker = this.parseWsTicker(data);
|
|
186
|
+
const symbol = ticker['symbol'];
|
|
187
|
+
this.tickers[symbol] = ticker;
|
|
188
|
+
const messageHash = 'ticker:' + symbol;
|
|
189
|
+
client.resolve(this.tickers[symbol], messageHash);
|
|
190
|
+
}
|
|
191
|
+
parseWsTicker(ticker, market = undefined) {
|
|
192
|
+
//
|
|
193
|
+
// {
|
|
194
|
+
// "quote_currency": "KRW",
|
|
195
|
+
// "target_currency": "BTC",
|
|
196
|
+
// "timestamp": 1705301117198,
|
|
197
|
+
// "quote_volume": "19521465345.504",
|
|
198
|
+
// "target_volume": "334.81445168",
|
|
199
|
+
// "high": "58710000",
|
|
200
|
+
// "low": "57276000",
|
|
201
|
+
// "first": "57293000",
|
|
202
|
+
// "last": "58532000",
|
|
203
|
+
// "volume_power": "100",
|
|
204
|
+
// "ask_best_price": "58537000",
|
|
205
|
+
// "ask_best_qty": "0.1961",
|
|
206
|
+
// "bid_best_price": "58532000",
|
|
207
|
+
// "bid_best_qty": "0.00009258",
|
|
208
|
+
// "id": "1705301117198001",
|
|
209
|
+
// "yesterday_high": "59140000",
|
|
210
|
+
// "yesterday_low": "57273000",
|
|
211
|
+
// "yesterday_first": "58897000",
|
|
212
|
+
// "yesterday_last": "57301000",
|
|
213
|
+
// "yesterday_quote_volume": "12967227517.4262",
|
|
214
|
+
// "yesterday_target_volume": "220.09232233"
|
|
215
|
+
// }
|
|
216
|
+
//
|
|
217
|
+
const timestamp = this.safeInteger(ticker, 'timestamp');
|
|
218
|
+
const last = this.safeString(ticker, 'last');
|
|
219
|
+
const baseId = this.safeString(ticker, 'target_currency');
|
|
220
|
+
const quoteId = this.safeString(ticker, 'quote_currency');
|
|
221
|
+
const base = this.safeCurrencyCode(baseId);
|
|
222
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
223
|
+
const symbol = this.symbol(base + '/' + quote);
|
|
224
|
+
return this.safeTicker({
|
|
225
|
+
'symbol': symbol,
|
|
226
|
+
'timestamp': timestamp,
|
|
227
|
+
'datetime': this.iso8601(timestamp),
|
|
228
|
+
'high': this.safeString(ticker, 'high'),
|
|
229
|
+
'low': this.safeString(ticker, 'low'),
|
|
230
|
+
'bid': this.safeNumber(ticker, 'bid_best_price'),
|
|
231
|
+
'bidVolume': this.safeNumber(ticker, 'bid_best_qty'),
|
|
232
|
+
'ask': this.safeNumber(ticker, 'ask_best_price'),
|
|
233
|
+
'askVolume': this.safeNumber(ticker, 'ask_best_qty'),
|
|
234
|
+
'vwap': undefined,
|
|
235
|
+
'open': this.safeString(ticker, 'first'),
|
|
236
|
+
'close': last,
|
|
237
|
+
'last': last,
|
|
238
|
+
'previousClose': undefined,
|
|
239
|
+
'change': undefined,
|
|
240
|
+
'percentage': undefined,
|
|
241
|
+
'average': undefined,
|
|
242
|
+
'baseVolume': this.safeString(ticker, 'target_volume'),
|
|
243
|
+
'quoteVolume': this.safeString(ticker, 'quote_volume'),
|
|
244
|
+
'info': ticker,
|
|
245
|
+
}, market);
|
|
246
|
+
}
|
|
247
|
+
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
248
|
+
/**
|
|
249
|
+
* @method
|
|
250
|
+
* @name coinone#watchTrades
|
|
251
|
+
* @description watches information on multiple trades made in a market
|
|
252
|
+
* @see https://docs.coinone.co.kr/reference/public-websocket-trade
|
|
253
|
+
* @param {string} symbol unified market symbol of the market trades were made in
|
|
254
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
255
|
+
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
256
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
257
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
258
|
+
*/
|
|
259
|
+
await this.loadMarkets();
|
|
260
|
+
const market = this.market(symbol);
|
|
261
|
+
const messageHash = 'trade:' + market['symbol'];
|
|
262
|
+
const url = this.urls['api']['ws'];
|
|
263
|
+
const request = {
|
|
264
|
+
'request_type': 'SUBSCRIBE',
|
|
265
|
+
'channel': 'TRADE',
|
|
266
|
+
'topic': {
|
|
267
|
+
'quote_currency': market['quote'],
|
|
268
|
+
'target_currency': market['base'],
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
const message = this.extend(request, params);
|
|
272
|
+
const trades = await this.watch(url, messageHash, message, messageHash);
|
|
273
|
+
if (this.newUpdates) {
|
|
274
|
+
limit = trades.getLimit(market['symbol'], limit);
|
|
275
|
+
}
|
|
276
|
+
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
277
|
+
}
|
|
278
|
+
handleTrades(client, message) {
|
|
279
|
+
//
|
|
280
|
+
// {
|
|
281
|
+
// "response_type": "DATA",
|
|
282
|
+
// "channel": "TRADE",
|
|
283
|
+
// "data": {
|
|
284
|
+
// "quote_currency": "KRW",
|
|
285
|
+
// "target_currency": "BTC",
|
|
286
|
+
// "id": "1705303667916001",
|
|
287
|
+
// "timestamp": 1705303667916,
|
|
288
|
+
// "price": "58490000",
|
|
289
|
+
// "qty": "0.0008",
|
|
290
|
+
// "is_seller_maker": false
|
|
291
|
+
// }
|
|
292
|
+
// }
|
|
293
|
+
//
|
|
294
|
+
const data = this.safeValue(message, 'data', {});
|
|
295
|
+
const trade = this.parseWsTrade(data);
|
|
296
|
+
const symbol = trade['symbol'];
|
|
297
|
+
let stored = this.safeValue(this.trades, symbol);
|
|
298
|
+
if (stored === undefined) {
|
|
299
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
300
|
+
stored = new Cache.ArrayCache(limit);
|
|
301
|
+
this.trades[symbol] = stored;
|
|
302
|
+
}
|
|
303
|
+
stored.append(trade);
|
|
304
|
+
const messageHash = 'trade:' + symbol;
|
|
305
|
+
client.resolve(stored, messageHash);
|
|
306
|
+
}
|
|
307
|
+
parseWsTrade(trade, market = undefined) {
|
|
308
|
+
//
|
|
309
|
+
// {
|
|
310
|
+
// "quote_currency": "KRW",
|
|
311
|
+
// "target_currency": "BTC",
|
|
312
|
+
// "id": "1705303667916001",
|
|
313
|
+
// "timestamp": 1705303667916,
|
|
314
|
+
// "price": "58490000",
|
|
315
|
+
// "qty": "0.0008",
|
|
316
|
+
// "is_seller_maker": false
|
|
317
|
+
// }
|
|
318
|
+
//
|
|
319
|
+
const baseId = this.safeStringUpper(trade, 'target_currency');
|
|
320
|
+
const quoteId = this.safeStringUpper(trade, 'quote_currency');
|
|
321
|
+
const base = this.safeCurrencyCode(baseId);
|
|
322
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
323
|
+
const symbol = base + '/' + quote;
|
|
324
|
+
const timestamp = this.safeInteger(trade, 'timestamp');
|
|
325
|
+
market = this.safeMarket(symbol, market);
|
|
326
|
+
const isSellerMaker = this.safeValue(trade, 'is_seller_maker');
|
|
327
|
+
let side = undefined;
|
|
328
|
+
if (isSellerMaker !== undefined) {
|
|
329
|
+
side = isSellerMaker ? 'sell' : 'buy';
|
|
330
|
+
}
|
|
331
|
+
const priceString = this.safeString(trade, 'price');
|
|
332
|
+
const amountString = this.safeString(trade, 'qty');
|
|
333
|
+
return this.safeTrade({
|
|
334
|
+
'id': this.safeString(trade, 'id'),
|
|
335
|
+
'info': trade,
|
|
336
|
+
'timestamp': timestamp,
|
|
337
|
+
'datetime': this.iso8601(timestamp),
|
|
338
|
+
'order': undefined,
|
|
339
|
+
'symbol': market['symbol'],
|
|
340
|
+
'type': undefined,
|
|
341
|
+
'side': side,
|
|
342
|
+
'takerOrMaker': undefined,
|
|
343
|
+
'price': priceString,
|
|
344
|
+
'amount': amountString,
|
|
345
|
+
'cost': undefined,
|
|
346
|
+
'fee': undefined,
|
|
347
|
+
}, market);
|
|
348
|
+
}
|
|
349
|
+
handleErrorMessage(client, message) {
|
|
350
|
+
//
|
|
351
|
+
// {
|
|
352
|
+
// "response_type": "ERROR",
|
|
353
|
+
// "error_code": 160012,
|
|
354
|
+
// "message": "Invalid Topic"
|
|
355
|
+
// }
|
|
356
|
+
//
|
|
357
|
+
const type = this.safeString(message, 'response_type', '');
|
|
358
|
+
if (type === 'ERROR') {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
handleMessage(client, message) {
|
|
364
|
+
if (this.handleErrorMessage(client, message)) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const type = this.safeString(message, 'response_type');
|
|
368
|
+
if (type === 'PONG') {
|
|
369
|
+
this.handlePong(client, message);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (type === 'DATA') {
|
|
373
|
+
const topic = this.safeString(message, 'channel', '');
|
|
374
|
+
const methods = {
|
|
375
|
+
'ORDERBOOK': this.handleOrderBook,
|
|
376
|
+
'TICKER': this.handleTicker,
|
|
377
|
+
'TRADE': this.handleTrades,
|
|
378
|
+
};
|
|
379
|
+
const exacMethod = this.safeValue(methods, topic);
|
|
380
|
+
if (exacMethod !== undefined) {
|
|
381
|
+
exacMethod.call(this, client, message);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const keys = Object.keys(methods);
|
|
385
|
+
for (let i = 0; i < keys.length; i++) {
|
|
386
|
+
const key = keys[i];
|
|
387
|
+
if (topic.indexOf(keys[i]) >= 0) {
|
|
388
|
+
const method = methods[key];
|
|
389
|
+
method.call(this, client, message);
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
ping(client) {
|
|
396
|
+
return {
|
|
397
|
+
'request_type': 'PING',
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
handlePong(client, message) {
|
|
401
|
+
//
|
|
402
|
+
// {
|
|
403
|
+
// "response_type":"PONG"
|
|
404
|
+
// }
|
|
405
|
+
//
|
|
406
|
+
client.lastPong = this.milliseconds();
|
|
407
|
+
return message;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
module.exports = coinone;
|
|
@@ -930,11 +930,16 @@ class htx extends htx$1 {
|
|
|
930
930
|
// inject trade in existing order by faking an order object
|
|
931
931
|
const orderId = this.safeString(parsedTrade, 'order');
|
|
932
932
|
const trades = [parsedTrade];
|
|
933
|
+
const status = this.parseOrderStatus(this.safeString2(data, 'orderStatus', 'status', 'closed'));
|
|
934
|
+
const filled = this.safeString(data, 'execAmt');
|
|
935
|
+
const remaining = this.safeString(data, 'remainAmt');
|
|
933
936
|
const order = {
|
|
934
937
|
'id': orderId,
|
|
935
938
|
'trades': trades,
|
|
936
|
-
'status':
|
|
939
|
+
'status': status,
|
|
937
940
|
'symbol': market['symbol'],
|
|
941
|
+
'filled': this.parseNumber(filled),
|
|
942
|
+
'remaining': this.parseNumber(remaining),
|
|
938
943
|
};
|
|
939
944
|
parsedOrder = order;
|
|
940
945
|
}
|
|
@@ -178,7 +178,13 @@ class krakenfutures extends krakenfutures$1 {
|
|
|
178
178
|
const name = this.safeString2(params, 'method', 'watchTickerMethod', method);
|
|
179
179
|
params = this.omit(params, ['watchTickerMethod', 'method']);
|
|
180
180
|
symbols = this.marketSymbols(symbols, undefined, false);
|
|
181
|
-
|
|
181
|
+
const ticker = await this.subscribePublic(name, symbols, params);
|
|
182
|
+
if (this.newUpdates) {
|
|
183
|
+
const tickers = {};
|
|
184
|
+
tickers[ticker['symbol']] = ticker;
|
|
185
|
+
return tickers;
|
|
186
|
+
}
|
|
187
|
+
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
182
188
|
}
|
|
183
189
|
async watchTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
184
190
|
/**
|
|
@@ -21,6 +21,7 @@ class woo extends woo$1 {
|
|
|
21
21
|
'watchTicker': true,
|
|
22
22
|
'watchTickers': true,
|
|
23
23
|
'watchTrades': true,
|
|
24
|
+
'watchPositions': true,
|
|
24
25
|
},
|
|
25
26
|
'urls': {
|
|
26
27
|
'api': {
|
|
@@ -45,6 +46,10 @@ class woo extends woo$1 {
|
|
|
45
46
|
'tradesLimit': 1000,
|
|
46
47
|
'ordersLimit': 1000,
|
|
47
48
|
'requestId': {},
|
|
49
|
+
'watchPositions': {
|
|
50
|
+
'fetchPositionsSnapshot': true,
|
|
51
|
+
'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
|
|
52
|
+
},
|
|
48
53
|
},
|
|
49
54
|
'streaming': {
|
|
50
55
|
'ping': this.ping,
|
|
@@ -603,6 +608,126 @@ class woo extends woo$1 {
|
|
|
603
608
|
client.resolve(this.orders, messageHashSymbol);
|
|
604
609
|
}
|
|
605
610
|
}
|
|
611
|
+
async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
|
|
612
|
+
/**
|
|
613
|
+
* @method
|
|
614
|
+
* @name woo#watchPositions
|
|
615
|
+
* @see https://docs.woo.org/#position-push
|
|
616
|
+
* @description watch all open positions
|
|
617
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
618
|
+
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
619
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
620
|
+
*/
|
|
621
|
+
await this.loadMarkets();
|
|
622
|
+
let messageHash = '';
|
|
623
|
+
symbols = this.marketSymbols(symbols);
|
|
624
|
+
if (!this.isEmpty(symbols)) {
|
|
625
|
+
messageHash = '::' + symbols.join(',');
|
|
626
|
+
}
|
|
627
|
+
messageHash = 'positions' + messageHash;
|
|
628
|
+
const url = this.urls['api']['ws']['private'] + '/' + this.uid;
|
|
629
|
+
const client = this.client(url);
|
|
630
|
+
this.setPositionsCache(client, symbols);
|
|
631
|
+
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
|
|
632
|
+
const awaitPositionsSnapshot = this.safeValue('watchPositions', 'awaitPositionsSnapshot', true);
|
|
633
|
+
if (fetchPositionsSnapshot && awaitPositionsSnapshot && this.positions === undefined) {
|
|
634
|
+
const snapshot = await client.future('fetchPositionsSnapshot');
|
|
635
|
+
return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
|
|
636
|
+
}
|
|
637
|
+
const request = {
|
|
638
|
+
'event': 'subscribe',
|
|
639
|
+
'topic': 'position',
|
|
640
|
+
};
|
|
641
|
+
const newPositions = await this.watchPrivate(messageHash, request, params);
|
|
642
|
+
if (this.newUpdates) {
|
|
643
|
+
return newPositions;
|
|
644
|
+
}
|
|
645
|
+
return this.filterBySymbolsSinceLimit(this.positions, symbols, since, limit, true);
|
|
646
|
+
}
|
|
647
|
+
setPositionsCache(client, type, symbols = undefined) {
|
|
648
|
+
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', false);
|
|
649
|
+
if (fetchPositionsSnapshot) {
|
|
650
|
+
const messageHash = 'fetchPositionsSnapshot';
|
|
651
|
+
if (!(messageHash in client.futures)) {
|
|
652
|
+
client.future(messageHash);
|
|
653
|
+
this.spawn(this.loadPositionsSnapshot, client, messageHash);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
this.positions = new Cache.ArrayCacheBySymbolBySide();
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async loadPositionsSnapshot(client, messageHash) {
|
|
661
|
+
const positions = await this.fetchPositions();
|
|
662
|
+
this.positions = new Cache.ArrayCacheBySymbolBySide();
|
|
663
|
+
const cache = this.positions;
|
|
664
|
+
for (let i = 0; i < positions.length; i++) {
|
|
665
|
+
const position = positions[i];
|
|
666
|
+
const contracts = this.safeNumber(position, 'contracts', 0);
|
|
667
|
+
if (contracts > 0) {
|
|
668
|
+
cache.append(position);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
// don't remove the future from the .futures cache
|
|
672
|
+
const future = client.futures[messageHash];
|
|
673
|
+
future.resolve(cache);
|
|
674
|
+
client.resolve(cache, 'positions');
|
|
675
|
+
}
|
|
676
|
+
handlePositions(client, message) {
|
|
677
|
+
//
|
|
678
|
+
// {
|
|
679
|
+
// "topic":"position",
|
|
680
|
+
// "ts":1705292345255,
|
|
681
|
+
// "data":{
|
|
682
|
+
// "positions":{
|
|
683
|
+
// "PERP_LTC_USDT":{
|
|
684
|
+
// "holding":1,
|
|
685
|
+
// "pendingLongQty":0,
|
|
686
|
+
// "pendingShortQty":0,
|
|
687
|
+
// "averageOpenPrice":71.53,
|
|
688
|
+
// "pnl24H":0,
|
|
689
|
+
// "fee24H":0.07153,
|
|
690
|
+
// "settlePrice":71.53,
|
|
691
|
+
// "markPrice":71.32098452065145,
|
|
692
|
+
// "version":7886,
|
|
693
|
+
// "openingTime":1705292304267,
|
|
694
|
+
// "pnl24HPercentage":0,
|
|
695
|
+
// "adlQuantile":1,
|
|
696
|
+
// "positionSide":"BOTH"
|
|
697
|
+
// }
|
|
698
|
+
// }
|
|
699
|
+
// }
|
|
700
|
+
// }
|
|
701
|
+
//
|
|
702
|
+
const data = this.safeValue(message, 'data', {});
|
|
703
|
+
const rawPositions = this.safeValue(data, 'positions', {});
|
|
704
|
+
const postitionsIds = Object.keys(rawPositions);
|
|
705
|
+
if (this.positions === undefined) {
|
|
706
|
+
this.positions = new Cache.ArrayCacheBySymbolBySide();
|
|
707
|
+
}
|
|
708
|
+
const cache = this.positions;
|
|
709
|
+
const newPositions = [];
|
|
710
|
+
for (let i = 0; i < postitionsIds.length; i++) {
|
|
711
|
+
const marketId = postitionsIds[i];
|
|
712
|
+
const market = this.safeMarket(marketId);
|
|
713
|
+
const rawPosition = rawPositions[marketId];
|
|
714
|
+
const position = this.parsePosition(rawPosition, market);
|
|
715
|
+
newPositions.push(position);
|
|
716
|
+
cache.append(position);
|
|
717
|
+
}
|
|
718
|
+
const messageHashes = this.findMessageHashes(client, 'positions::');
|
|
719
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
720
|
+
const messageHash = messageHashes[i];
|
|
721
|
+
const parts = messageHash.split('::');
|
|
722
|
+
const symbolsString = parts[1];
|
|
723
|
+
const symbols = symbolsString.split(',');
|
|
724
|
+
const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
|
|
725
|
+
if (!this.isEmpty(positions)) {
|
|
726
|
+
client.resolve(positions, messageHash);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
client.resolve(newPositions, 'positions');
|
|
730
|
+
}
|
|
606
731
|
async watchBalance(params = {}) {
|
|
607
732
|
/**
|
|
608
733
|
* @method
|
|
@@ -686,6 +811,7 @@ class woo extends woo$1 {
|
|
|
686
811
|
'executionreport': this.handleOrderUpdate,
|
|
687
812
|
'trade': this.handleTrade,
|
|
688
813
|
'balance': this.handleBalance,
|
|
814
|
+
'position': this.handlePositions,
|
|
689
815
|
};
|
|
690
816
|
const event = this.safeString(message, 'event');
|
|
691
817
|
let method = this.safeValue(methods, event);
|
package/dist/cjs/js/src/woo.js
CHANGED
|
@@ -42,16 +42,16 @@ class woo extends woo$1 {
|
|
|
42
42
|
'createMarketOrderWithCost': false,
|
|
43
43
|
'createMarketSellOrderWithCost': false,
|
|
44
44
|
'createOrder': true,
|
|
45
|
+
'createOrderWithTakeProfitAndStopLoss': true,
|
|
45
46
|
'createReduceOnlyOrder': true,
|
|
46
47
|
'createStopLimitOrder': false,
|
|
48
|
+
'createStopLossOrder': true,
|
|
47
49
|
'createStopMarketOrder': false,
|
|
48
50
|
'createStopOrder': false,
|
|
51
|
+
'createTakeProfitOrder': true,
|
|
49
52
|
'createTrailingAmountOrder': true,
|
|
50
53
|
'createTrailingPercentOrder': true,
|
|
51
54
|
'createTriggerOrder': true,
|
|
52
|
-
'createTakeProfitOrder': true,
|
|
53
|
-
'createStopLossOrder': true,
|
|
54
|
-
'createOrderWithTakeProfitAndStopLoss': true,
|
|
55
55
|
'fetchAccounts': true,
|
|
56
56
|
'fetchBalance': true,
|
|
57
57
|
'fetchCanceledOrders': false,
|
package/js/ccxt.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
|
|
|
4
4
|
import * as errors from './src/base/errors.js';
|
|
5
5
|
import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks } from './src/base/types.js';
|
|
6
6
|
import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
|
|
7
|
-
declare const version = "4.2.
|
|
7
|
+
declare const version = "4.2.15";
|
|
8
8
|
import ace from './src/ace.js';
|
|
9
9
|
import alpaca from './src/alpaca.js';
|
|
10
10
|
import ascendex from './src/ascendex.js';
|
|
@@ -128,6 +128,7 @@ import cexPro from './src/pro/cex.js';
|
|
|
128
128
|
import coinbasePro from './src/pro/coinbase.js';
|
|
129
129
|
import coinbaseproPro from './src/pro/coinbasepro.js';
|
|
130
130
|
import coinexPro from './src/pro/coinex.js';
|
|
131
|
+
import coinonePro from './src/pro/coinone.js';
|
|
131
132
|
import cryptocomPro from './src/pro/cryptocom.js';
|
|
132
133
|
import currencycomPro from './src/pro/currencycom.js';
|
|
133
134
|
import deribitPro from './src/pro/deribit.js';
|
|
@@ -285,6 +286,7 @@ declare const pro: {
|
|
|
285
286
|
coinbase: typeof coinbasePro;
|
|
286
287
|
coinbasepro: typeof coinbaseproPro;
|
|
287
288
|
coinex: typeof coinexPro;
|
|
289
|
+
coinone: typeof coinonePro;
|
|
288
290
|
cryptocom: typeof cryptocomPro;
|
|
289
291
|
currencycom: typeof currencycomPro;
|
|
290
292
|
deribit: typeof deribitPro;
|
|
@@ -348,6 +350,7 @@ declare const ccxt: {
|
|
|
348
350
|
coinbase: typeof coinbasePro;
|
|
349
351
|
coinbasepro: typeof coinbaseproPro;
|
|
350
352
|
coinex: typeof coinexPro;
|
|
353
|
+
coinone: typeof coinonePro;
|
|
351
354
|
cryptocom: typeof cryptocomPro;
|
|
352
355
|
currencycom: typeof currencycomPro;
|
|
353
356
|
deribit: typeof deribitPro;
|