ccxt 4.3.89 → 4.3.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/alpaca.js +2 -2
- package/dist/cjs/src/ascendex.js +95 -97
- package/dist/cjs/src/bingx.js +31 -17
- package/dist/cjs/src/bitfinex2.js +21 -22
- package/dist/cjs/src/bitget.js +2 -2
- package/dist/cjs/src/bitmart.js +6 -9
- package/dist/cjs/src/coinbaseinternational.js +2 -1
- package/dist/cjs/src/coinex.js +1 -17
- package/dist/cjs/src/hitbtc.js +1 -0
- package/dist/cjs/src/htx.js +49 -49
- package/dist/cjs/src/huobijp.js +0 -9
- package/dist/cjs/src/latoken.js +1 -0
- package/dist/cjs/src/okx.js +1 -8
- package/dist/cjs/src/pro/binance.js +323 -0
- package/dist/cjs/src/pro/bingx.js +263 -91
- package/dist/cjs/src/pro/bithumb.js +5 -1
- package/dist/cjs/src/pro/bybit.js +1 -1
- package/dist/cjs/src/pro/coinex.js +994 -679
- package/dist/cjs/src/pro/lbank.js +2 -3
- package/dist/cjs/src/pro/okx.js +159 -3
- package/dist/cjs/src/whitebit.js +5 -3
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/alpaca.js +2 -2
- package/js/src/ascendex.js +95 -97
- package/js/src/bingx.js +31 -17
- package/js/src/bitfinex2.d.ts +0 -1
- package/js/src/bitfinex2.js +21 -22
- package/js/src/bitget.js +2 -2
- package/js/src/bitmart.d.ts +0 -1
- package/js/src/bitmart.js +6 -9
- package/js/src/coinbaseinternational.js +2 -1
- package/js/src/coinex.d.ts +0 -2
- package/js/src/coinex.js +1 -17
- package/js/src/hitbtc.js +1 -0
- package/js/src/htx.js +49 -49
- package/js/src/huobijp.d.ts +0 -1
- package/js/src/huobijp.js +0 -9
- package/js/src/latoken.js +1 -0
- package/js/src/okx.d.ts +0 -1
- package/js/src/okx.js +1 -8
- package/js/src/pro/binance.d.ts +9 -1
- package/js/src/pro/binance.js +327 -1
- package/js/src/pro/bingx.d.ts +2 -2
- package/js/src/pro/bingx.js +263 -91
- package/js/src/pro/bithumb.js +5 -1
- package/js/src/pro/bybit.js +1 -1
- package/js/src/pro/coinex.d.ts +12 -6
- package/js/src/pro/coinex.js +996 -681
- package/js/src/pro/lbank.js +2 -3
- package/js/src/pro/okx.d.ts +7 -0
- package/js/src/pro/okx.js +162 -4
- package/js/src/whitebit.js +5 -3
- package/package.json +1 -1
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var Precise = require('../base/Precise.js');
|
|
4
3
|
var coinex$1 = require('../coinex.js');
|
|
5
4
|
var errors = require('../base/errors.js');
|
|
6
5
|
var Cache = require('../base/ws/Cache.js');
|
|
7
6
|
var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
|
|
8
|
-
var md5 = require('../static_dependencies/noble-hashes/md5.js');
|
|
9
7
|
|
|
10
8
|
// ---------------------------------------------------------------------------
|
|
11
9
|
// ---------------------------------------------------------------------------
|
|
@@ -15,25 +13,30 @@ class coinex extends coinex$1 {
|
|
|
15
13
|
'has': {
|
|
16
14
|
'ws': true,
|
|
17
15
|
'watchBalance': true,
|
|
16
|
+
'watchBidsAsks': true,
|
|
18
17
|
'watchTicker': true,
|
|
19
18
|
'watchTickers': true,
|
|
20
19
|
'watchTrades': true,
|
|
21
|
-
'
|
|
20
|
+
'watchTradesForSymbols': true,
|
|
21
|
+
'watchMyTrades': true,
|
|
22
22
|
'watchOrders': true,
|
|
23
23
|
'watchOrderBook': true,
|
|
24
|
-
'
|
|
25
|
-
'
|
|
24
|
+
'watchOrderBookForSymbols': true,
|
|
25
|
+
'watchOHLCV': false,
|
|
26
|
+
'fetchOHLCVWs': false,
|
|
26
27
|
},
|
|
27
28
|
'urls': {
|
|
28
29
|
'api': {
|
|
29
30
|
'ws': {
|
|
30
|
-
'spot': 'wss://socket.coinex.com/',
|
|
31
|
-
'swap': 'wss://
|
|
31
|
+
'spot': 'wss://socket.coinex.com/v2/spot/',
|
|
32
|
+
'swap': 'wss://socket.coinex.com/v2/futures/',
|
|
32
33
|
},
|
|
33
34
|
},
|
|
34
35
|
},
|
|
35
36
|
'options': {
|
|
36
|
-
'
|
|
37
|
+
'ws': {
|
|
38
|
+
'gunzip': true,
|
|
39
|
+
},
|
|
37
40
|
'timeframes': {
|
|
38
41
|
'1m': 60,
|
|
39
42
|
'3m': 180,
|
|
@@ -53,20 +56,31 @@ class coinex extends coinex$1 {
|
|
|
53
56
|
'watchOrderBook': {
|
|
54
57
|
'limits': [5, 10, 20, 50],
|
|
55
58
|
'defaultLimit': 50,
|
|
56
|
-
'aggregations': ['10', '1', '0', '0.1', '0.01'],
|
|
59
|
+
'aggregations': ['1000', '100', '10', '1', '0', '0.1', '0.01', '0.001', '0.0001', '0.00001', '0.000001', '0.0000001', '0.00000001', '0.000000001', '0.0000000001', '0.00000000001'],
|
|
57
60
|
'defaultAggregation': '0',
|
|
58
61
|
},
|
|
59
62
|
},
|
|
60
63
|
'streaming': {},
|
|
61
64
|
'exceptions': {
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'
|
|
65
|
+
'exact': {
|
|
66
|
+
'20001': errors.BadRequest,
|
|
67
|
+
'20002': errors.NotSupported,
|
|
68
|
+
'21001': errors.AuthenticationError,
|
|
69
|
+
'21002': errors.AuthenticationError,
|
|
70
|
+
'23001': errors.RequestTimeout,
|
|
71
|
+
'23002': errors.RateLimitExceeded,
|
|
72
|
+
'24001': errors.ExchangeError,
|
|
73
|
+
'24002': errors.ExchangeNotAvailable,
|
|
74
|
+
'30001': errors.BadRequest,
|
|
75
|
+
'30002': errors.NotSupported,
|
|
76
|
+
'31001': errors.AuthenticationError,
|
|
77
|
+
'31002': errors.AuthenticationError,
|
|
78
|
+
'33001': errors.RequestTimeout,
|
|
79
|
+
'33002': errors.RateLimitExceeded,
|
|
80
|
+
'34001': errors.ExchangeError,
|
|
81
|
+
'34002': errors.ExchangeNotAvailable, // Service unavailable temporarily
|
|
69
82
|
},
|
|
83
|
+
'broad': {},
|
|
70
84
|
},
|
|
71
85
|
});
|
|
72
86
|
}
|
|
@@ -81,61 +95,66 @@ class coinex extends coinex$1 {
|
|
|
81
95
|
//
|
|
82
96
|
// {
|
|
83
97
|
// "method": "state.update",
|
|
84
|
-
// "
|
|
85
|
-
// "
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
+
// "data": {
|
|
99
|
+
// "state_list": [
|
|
100
|
+
// {
|
|
101
|
+
// "market": "LATUSDT",
|
|
102
|
+
// "last": "0.008157",
|
|
103
|
+
// "open": "0.008286",
|
|
104
|
+
// "close": "0.008157",
|
|
105
|
+
// "high": "0.008390",
|
|
106
|
+
// "low": "0.008106",
|
|
107
|
+
// "volume": "807714.49139758",
|
|
108
|
+
// "volume_sell": "286170.69645599",
|
|
109
|
+
// "volume_buy": "266161.23236408",
|
|
110
|
+
// "value": "6689.21644207",
|
|
111
|
+
// "period": 86400
|
|
112
|
+
// },
|
|
113
|
+
// ]
|
|
114
|
+
// },
|
|
115
|
+
// "id": null
|
|
98
116
|
// }
|
|
99
117
|
//
|
|
100
118
|
// swap
|
|
101
119
|
//
|
|
102
120
|
// {
|
|
103
121
|
// "method": "state.update",
|
|
104
|
-
// "
|
|
105
|
-
// "
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
122
|
+
// "data": {
|
|
123
|
+
// "state_list": [
|
|
124
|
+
// {
|
|
125
|
+
// "market": "ETHUSD_SIGNPRICE",
|
|
126
|
+
// "last": "1892.29",
|
|
127
|
+
// "open": "1884.62",
|
|
128
|
+
// "close": "1892.29",
|
|
129
|
+
// "high": "1894.09",
|
|
130
|
+
// "low": "1863.72",
|
|
131
|
+
// "volume": "0",
|
|
132
|
+
// "value": "0",
|
|
133
|
+
// "volume_sell": "0",
|
|
134
|
+
// "volume_buy": "0",
|
|
135
|
+
// "open_interest_size": "0",
|
|
136
|
+
// "insurance_fund_size": "0",
|
|
137
|
+
// "latest_funding_rate": "0",
|
|
138
|
+
// "next_funding_rate": "0",
|
|
139
|
+
// "latest_funding_time": 0,
|
|
140
|
+
// "next_funding_time": 0,
|
|
141
|
+
// "period": 86400
|
|
142
|
+
// },
|
|
143
|
+
// ]
|
|
144
|
+
// ],
|
|
145
|
+
// "id": null
|
|
126
146
|
// }
|
|
127
147
|
//
|
|
128
148
|
const defaultType = this.safeString(this.options, 'defaultType');
|
|
129
|
-
const
|
|
130
|
-
const rawTickers = this.
|
|
131
|
-
const keys = Object.keys(rawTickers);
|
|
149
|
+
const data = this.safeDict(message, 'data', {});
|
|
150
|
+
const rawTickers = this.safeList(data, 'state_list', []);
|
|
132
151
|
const newTickers = [];
|
|
133
|
-
for (let i = 0; i <
|
|
134
|
-
const
|
|
135
|
-
const
|
|
152
|
+
for (let i = 0; i < rawTickers.length; i++) {
|
|
153
|
+
const entry = rawTickers[i];
|
|
154
|
+
const marketId = this.safeString(entry, 'market');
|
|
136
155
|
const symbol = this.safeSymbol(marketId, undefined, undefined, defaultType);
|
|
137
156
|
const market = this.safeMarket(marketId, undefined, undefined, defaultType);
|
|
138
|
-
const parsedTicker = this.parseWSTicker(
|
|
157
|
+
const parsedTicker = this.parseWSTicker(entry, market);
|
|
139
158
|
this.tickers[symbol] = parsedTicker;
|
|
140
159
|
newTickers.push(parsedTicker);
|
|
141
160
|
}
|
|
@@ -159,52 +178,53 @@ class coinex extends coinex$1 {
|
|
|
159
178
|
// spot
|
|
160
179
|
//
|
|
161
180
|
// {
|
|
162
|
-
// "
|
|
163
|
-
// "
|
|
164
|
-
// "
|
|
165
|
-
// "
|
|
166
|
-
// "
|
|
167
|
-
// "
|
|
168
|
-
// "
|
|
169
|
-
// "
|
|
170
|
-
// "
|
|
171
|
-
// "
|
|
181
|
+
// "market": "LATUSDT",
|
|
182
|
+
// "last": "0.008157",
|
|
183
|
+
// "open": "0.008286",
|
|
184
|
+
// "close": "0.008157",
|
|
185
|
+
// "high": "0.008390",
|
|
186
|
+
// "low": "0.008106",
|
|
187
|
+
// "volume": "807714.49139758",
|
|
188
|
+
// "volume_sell": "286170.69645599",
|
|
189
|
+
// "volume_buy": "266161.23236408",
|
|
190
|
+
// "value": "6689.21644207",
|
|
191
|
+
// "period": 86400
|
|
172
192
|
// }
|
|
173
193
|
//
|
|
174
194
|
// swap
|
|
175
195
|
//
|
|
176
196
|
// {
|
|
177
|
-
// "
|
|
178
|
-
// "
|
|
179
|
-
// "
|
|
180
|
-
// "
|
|
181
|
-
// "
|
|
182
|
-
// "
|
|
183
|
-
// "
|
|
184
|
-
// "
|
|
185
|
-
// "
|
|
186
|
-
// "
|
|
187
|
-
// "
|
|
188
|
-
// "
|
|
189
|
-
// "
|
|
190
|
-
// "
|
|
191
|
-
// "
|
|
192
|
-
// "
|
|
193
|
-
// "
|
|
194
|
-
// "buy_total": "25.7814"
|
|
197
|
+
// "market": "ETHUSD_SIGNPRICE",
|
|
198
|
+
// "last": "1892.29",
|
|
199
|
+
// "open": "1884.62",
|
|
200
|
+
// "close": "1892.29",
|
|
201
|
+
// "high": "1894.09",
|
|
202
|
+
// "low": "1863.72",
|
|
203
|
+
// "volume": "0",
|
|
204
|
+
// "value": "0",
|
|
205
|
+
// "volume_sell": "0",
|
|
206
|
+
// "volume_buy": "0",
|
|
207
|
+
// "open_interest_size": "0",
|
|
208
|
+
// "insurance_fund_size": "0",
|
|
209
|
+
// "latest_funding_rate": "0",
|
|
210
|
+
// "next_funding_rate": "0",
|
|
211
|
+
// "latest_funding_time": 0,
|
|
212
|
+
// "next_funding_time": 0,
|
|
213
|
+
// "period": 86400
|
|
195
214
|
// }
|
|
196
215
|
//
|
|
197
216
|
const defaultType = this.safeString(this.options, 'defaultType');
|
|
217
|
+
const marketId = this.safeString(ticker, 'market');
|
|
198
218
|
return this.safeTicker({
|
|
199
|
-
'symbol': this.safeSymbol(
|
|
219
|
+
'symbol': this.safeSymbol(marketId, market, undefined, defaultType),
|
|
200
220
|
'timestamp': undefined,
|
|
201
221
|
'datetime': undefined,
|
|
202
222
|
'high': this.safeString(ticker, 'high'),
|
|
203
223
|
'low': this.safeString(ticker, 'low'),
|
|
204
224
|
'bid': undefined,
|
|
205
|
-
'bidVolume': this.safeString(ticker, '
|
|
225
|
+
'bidVolume': this.safeString(ticker, 'volume_buy'),
|
|
206
226
|
'ask': undefined,
|
|
207
|
-
'askVolume': this.safeString(ticker, '
|
|
227
|
+
'askVolume': this.safeString(ticker, 'volume_sell'),
|
|
208
228
|
'vwap': undefined,
|
|
209
229
|
'open': this.safeString(ticker, 'open'),
|
|
210
230
|
'close': this.safeString(ticker, 'close'),
|
|
@@ -214,7 +234,7 @@ class coinex extends coinex$1 {
|
|
|
214
234
|
'percentage': undefined,
|
|
215
235
|
'average': undefined,
|
|
216
236
|
'baseVolume': this.safeString(ticker, 'volume'),
|
|
217
|
-
'quoteVolume': this.safeString(ticker, '
|
|
237
|
+
'quoteVolume': this.safeString(ticker, 'value'),
|
|
218
238
|
'info': ticker,
|
|
219
239
|
}, market);
|
|
220
240
|
}
|
|
@@ -223,78 +243,290 @@ class coinex extends coinex$1 {
|
|
|
223
243
|
* @method
|
|
224
244
|
* @name coinex#watchBalance
|
|
225
245
|
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
246
|
+
* @see https://docs.coinex.com/api/v2/assets/balance/ws/spot_balance
|
|
247
|
+
* @see https://docs.coinex.com/api/v2/assets/balance/ws/futures_balance
|
|
226
248
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
227
249
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
228
250
|
*/
|
|
229
251
|
await this.loadMarkets();
|
|
230
|
-
await this.authenticate(params);
|
|
231
|
-
const messageHash = 'balance';
|
|
232
252
|
let type = undefined;
|
|
233
|
-
[type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
|
|
253
|
+
[type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params, 'spot');
|
|
254
|
+
await this.authenticate(type);
|
|
234
255
|
const url = this.urls['api']['ws'][type];
|
|
235
|
-
|
|
256
|
+
let currencies = Object.keys(this.currencies_by_id);
|
|
257
|
+
if (currencies === undefined) {
|
|
258
|
+
currencies = [];
|
|
259
|
+
}
|
|
260
|
+
let messageHash = 'balances';
|
|
261
|
+
if (type === 'spot') {
|
|
262
|
+
messageHash += ':spot';
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
messageHash += ':swap';
|
|
266
|
+
}
|
|
236
267
|
const subscribe = {
|
|
237
|
-
'method': '
|
|
238
|
-
'params': currencies,
|
|
268
|
+
'method': 'balance.subscribe',
|
|
269
|
+
'params': { 'ccy_list': currencies },
|
|
239
270
|
'id': this.requestId(),
|
|
240
271
|
};
|
|
241
272
|
const request = this.deepExtend(subscribe, params);
|
|
242
273
|
return await this.watch(url, messageHash, request, messageHash);
|
|
243
274
|
}
|
|
244
275
|
handleBalance(client, message) {
|
|
276
|
+
//
|
|
277
|
+
// spot
|
|
245
278
|
//
|
|
246
279
|
// {
|
|
247
|
-
// "method": "
|
|
248
|
-
// "
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
// "
|
|
252
|
-
// "
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
//
|
|
280
|
+
// "method": "balance.update",
|
|
281
|
+
// "data": {
|
|
282
|
+
// "balance_list": [
|
|
283
|
+
// {
|
|
284
|
+
// "margin_market": "BTCUSDT",
|
|
285
|
+
// "ccy": "BTC",
|
|
286
|
+
// "available": "44.62207740",
|
|
287
|
+
// "frozen": "0.00000000",
|
|
288
|
+
// "updated_at": 1689152421692
|
|
289
|
+
// },
|
|
290
|
+
// ]
|
|
291
|
+
// },
|
|
256
292
|
// "id": null
|
|
257
293
|
// }
|
|
258
294
|
//
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
295
|
+
// swap
|
|
296
|
+
//
|
|
297
|
+
// {
|
|
298
|
+
// "method": "balance.update",
|
|
299
|
+
// "data": {
|
|
300
|
+
// "balance_list": [
|
|
301
|
+
// {
|
|
302
|
+
// "ccy": "USDT",
|
|
303
|
+
// "available": "97.92470982756335000001",
|
|
304
|
+
// "frozen": "0.00000000000000000000",
|
|
305
|
+
// "margin": "0.61442700000000000000",
|
|
306
|
+
// "transferrable": "97.92470982756335000001",
|
|
307
|
+
// "unrealized_pnl": "-0.00807000000000000000",
|
|
308
|
+
// "equity": "97.92470982756335000001"
|
|
309
|
+
// },
|
|
310
|
+
// ]
|
|
311
|
+
// },
|
|
312
|
+
// "id": null
|
|
313
|
+
// }
|
|
314
|
+
//
|
|
315
|
+
if (this.balance === undefined) {
|
|
316
|
+
this.balance = {};
|
|
317
|
+
}
|
|
318
|
+
const data = this.safeDict(message, 'data', {});
|
|
319
|
+
const balances = this.safeList(data, 'balance_list', []);
|
|
320
|
+
const firstEntry = balances[0];
|
|
321
|
+
const updated = this.safeInteger(firstEntry, 'updated_at');
|
|
322
|
+
const unrealizedPnl = this.safeString(firstEntry, 'unrealized_pnl');
|
|
323
|
+
const isSpot = (updated !== undefined);
|
|
324
|
+
const isSwap = (unrealizedPnl !== undefined);
|
|
325
|
+
let info = undefined;
|
|
326
|
+
let account = undefined;
|
|
327
|
+
let rawBalances = [];
|
|
328
|
+
if (isSpot) {
|
|
329
|
+
account = 'spot';
|
|
330
|
+
for (let i = 0; i < balances.length; i++) {
|
|
331
|
+
rawBalances = this.arrayConcat(rawBalances, balances);
|
|
332
|
+
}
|
|
333
|
+
info = rawBalances;
|
|
334
|
+
}
|
|
335
|
+
if (isSwap) {
|
|
336
|
+
account = 'swap';
|
|
337
|
+
for (let i = 0; i < balances.length; i++) {
|
|
338
|
+
rawBalances = this.arrayConcat(rawBalances, balances);
|
|
339
|
+
}
|
|
340
|
+
info = rawBalances;
|
|
341
|
+
}
|
|
342
|
+
for (let i = 0; i < rawBalances.length; i++) {
|
|
343
|
+
const entry = rawBalances[i];
|
|
344
|
+
this.parseWsBalance(entry, account);
|
|
345
|
+
}
|
|
346
|
+
let messageHash = undefined;
|
|
347
|
+
if (account !== undefined) {
|
|
348
|
+
if (this.safeValue(this.balance, account) === undefined) {
|
|
349
|
+
this.balance[account] = {};
|
|
350
|
+
}
|
|
351
|
+
this.balance[account]['info'] = info;
|
|
352
|
+
this.balance[account] = this.safeBalance(this.balance[account]);
|
|
353
|
+
messageHash = 'balances:' + account;
|
|
354
|
+
client.resolve(this.balance[account], messageHash);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
parseWsBalance(balance, accountType = undefined) {
|
|
358
|
+
//
|
|
359
|
+
// spot
|
|
360
|
+
//
|
|
361
|
+
// {
|
|
362
|
+
// "margin_market": "BTCUSDT",
|
|
363
|
+
// "ccy": "BTC",
|
|
364
|
+
// "available": "44.62207740",
|
|
365
|
+
// "frozen": "0.00000000",
|
|
366
|
+
// "updated_at": 1689152421692
|
|
367
|
+
// }
|
|
368
|
+
//
|
|
369
|
+
// swap
|
|
370
|
+
//
|
|
371
|
+
// {
|
|
372
|
+
// "ccy": "USDT",
|
|
373
|
+
// "available": "97.92470982756335000001",
|
|
374
|
+
// "frozen": "0.00000000000000000000",
|
|
375
|
+
// "margin": "0.61442700000000000000",
|
|
376
|
+
// "transferrable": "97.92470982756335000001",
|
|
377
|
+
// "unrealized_pnl": "-0.00807000000000000000",
|
|
378
|
+
// "equity": "97.92470982756335000001"
|
|
379
|
+
// }
|
|
380
|
+
//
|
|
381
|
+
const account = this.account();
|
|
382
|
+
const currencyId = this.safeString(balance, 'ccy');
|
|
383
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
384
|
+
account['free'] = this.safeString(balance, 'available');
|
|
385
|
+
account['used'] = this.safeString(balance, 'frozen');
|
|
386
|
+
if (accountType !== undefined) {
|
|
387
|
+
if (this.safeValue(this.balance, accountType) === undefined) {
|
|
388
|
+
this.balance[accountType] = {};
|
|
389
|
+
}
|
|
390
|
+
this.balance[accountType][code] = account;
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
271
393
|
this.balance[code] = account;
|
|
272
|
-
this.balance = this.safeBalance(this.balance);
|
|
273
394
|
}
|
|
274
|
-
|
|
275
|
-
|
|
395
|
+
}
|
|
396
|
+
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
397
|
+
/**
|
|
398
|
+
* @method
|
|
399
|
+
* @name coinex#watchMyTrades
|
|
400
|
+
* @description watches information on multiple trades made by the user
|
|
401
|
+
* @see https://docs.coinex.com/api/v2/spot/deal/ws/user-deals
|
|
402
|
+
* @see https://docs.coinex.com/api/v2/futures/deal/ws/user-deals
|
|
403
|
+
* @param {string} [symbol] unified symbol of the market the trades were made in
|
|
404
|
+
* @param {int} [since] the earliest time in ms to watch trades
|
|
405
|
+
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
406
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
407
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
408
|
+
*/
|
|
409
|
+
await this.loadMarkets();
|
|
410
|
+
let market = undefined;
|
|
411
|
+
if (symbol !== undefined) {
|
|
412
|
+
market = this.market(symbol);
|
|
413
|
+
symbol = market['symbol'];
|
|
414
|
+
}
|
|
415
|
+
let type = undefined;
|
|
416
|
+
[type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params, 'spot');
|
|
417
|
+
await this.authenticate(type);
|
|
418
|
+
const url = this.urls['api']['ws'][type];
|
|
419
|
+
const subscribedSymbols = [];
|
|
420
|
+
let messageHash = 'myTrades';
|
|
421
|
+
if (market !== undefined) {
|
|
422
|
+
messageHash += ':' + symbol;
|
|
423
|
+
subscribedSymbols.push(market['id']);
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
if (type === 'spot') {
|
|
427
|
+
messageHash += ':spot';
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
messageHash += ':swap';
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
const message = {
|
|
434
|
+
'method': 'user_deals.subscribe',
|
|
435
|
+
'params': { 'market_list': subscribedSymbols },
|
|
436
|
+
'id': this.requestId(),
|
|
437
|
+
};
|
|
438
|
+
const request = this.deepExtend(message, params);
|
|
439
|
+
const trades = await this.watch(url, messageHash, request, messageHash);
|
|
440
|
+
if (this.newUpdates) {
|
|
441
|
+
limit = trades.getLimit(symbol, limit);
|
|
442
|
+
}
|
|
443
|
+
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
|
|
444
|
+
}
|
|
445
|
+
handleMyTrades(client, message) {
|
|
446
|
+
//
|
|
447
|
+
// {
|
|
448
|
+
// "method": "user_deals.update",
|
|
449
|
+
// "data": {
|
|
450
|
+
// "deal_id": 3514376759,
|
|
451
|
+
// "created_at": 1689152421692,
|
|
452
|
+
// "market": "BTCUSDT",
|
|
453
|
+
// "side": "buy",
|
|
454
|
+
// "order_id": 8678890,
|
|
455
|
+
// "margin_market": "BTCUSDT",
|
|
456
|
+
// "price": "30718.42",
|
|
457
|
+
// "amount": "0.00000325",
|
|
458
|
+
// "role": "taker",
|
|
459
|
+
// "fee": "0.0299",
|
|
460
|
+
// "fee_ccy": "USDT"
|
|
461
|
+
// },
|
|
462
|
+
// "id": null
|
|
463
|
+
// }
|
|
464
|
+
//
|
|
465
|
+
const data = this.safeDict(message, 'data', {});
|
|
466
|
+
const marketId = this.safeString(data, 'market');
|
|
467
|
+
const isSpot = client.url.indexOf('spot') > -1;
|
|
468
|
+
const defaultType = isSpot ? 'spot' : 'swap';
|
|
469
|
+
const market = this.safeMarket(marketId, undefined, undefined, defaultType);
|
|
470
|
+
const symbol = market['symbol'];
|
|
471
|
+
const messageHash = 'myTrades:' + symbol;
|
|
472
|
+
const messageWithType = 'myTrades:' + market['type'];
|
|
473
|
+
let stored = this.safeValue(this.trades, symbol);
|
|
474
|
+
if (stored === undefined) {
|
|
475
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
476
|
+
stored = new Cache.ArrayCache(limit);
|
|
477
|
+
this.trades[symbol] = stored;
|
|
478
|
+
}
|
|
479
|
+
const parsed = this.parseWsTrade(data, market);
|
|
480
|
+
stored.append(parsed);
|
|
481
|
+
this.trades[symbol] = stored;
|
|
482
|
+
client.resolve(this.trades[symbol], messageWithType);
|
|
483
|
+
client.resolve(this.trades[symbol], messageHash);
|
|
276
484
|
}
|
|
277
485
|
handleTrades(client, message) {
|
|
486
|
+
//
|
|
487
|
+
// spot
|
|
278
488
|
//
|
|
279
489
|
// {
|
|
280
490
|
// "method": "deals.update",
|
|
281
|
-
// "
|
|
282
|
-
// "
|
|
283
|
-
// [
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
491
|
+
// "data": {
|
|
492
|
+
// "market": "BTCUSDT",
|
|
493
|
+
// "deal_list": [
|
|
494
|
+
// {
|
|
495
|
+
// "deal_id": 3514376759,
|
|
496
|
+
// "created_at": 1689152421692,
|
|
497
|
+
// "side": "buy",
|
|
498
|
+
// "price": "30718.42",
|
|
499
|
+
// "amount": "0.00000325"
|
|
500
|
+
// },
|
|
501
|
+
// ]
|
|
502
|
+
// },
|
|
291
503
|
// "id": null
|
|
292
504
|
// }
|
|
293
505
|
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
506
|
+
// swap
|
|
507
|
+
//
|
|
508
|
+
// {
|
|
509
|
+
// "method": "deals.update",
|
|
510
|
+
// "data": {
|
|
511
|
+
// "market": "BTCUSDT",
|
|
512
|
+
// "deal_list": [
|
|
513
|
+
// {
|
|
514
|
+
// "deal_id": 3514376759,
|
|
515
|
+
// "created_at": 1689152421692,
|
|
516
|
+
// "side": "buy",
|
|
517
|
+
// "price": "30718.42",
|
|
518
|
+
// "amount": "0.00000325"
|
|
519
|
+
// },
|
|
520
|
+
// ]
|
|
521
|
+
// },
|
|
522
|
+
// "id": null
|
|
523
|
+
// }
|
|
524
|
+
//
|
|
525
|
+
const data = this.safeDict(message, 'data', {});
|
|
526
|
+
const trades = this.safeList(data, 'deal_list', []);
|
|
527
|
+
const marketId = this.safeString(data, 'market');
|
|
528
|
+
const isSpot = client.url.indexOf('spot') > -1;
|
|
529
|
+
const defaultType = isSpot ? 'spot' : 'swap';
|
|
298
530
|
const market = this.safeMarket(marketId, undefined, undefined, defaultType);
|
|
299
531
|
const symbol = market['symbol'];
|
|
300
532
|
const messageHash = 'trades:' + symbol;
|
|
@@ -313,133 +545,127 @@ class coinex extends coinex$1 {
|
|
|
313
545
|
client.resolve(this.trades[symbol], messageHash);
|
|
314
546
|
}
|
|
315
547
|
parseWsTrade(trade, market = undefined) {
|
|
548
|
+
//
|
|
549
|
+
// spot watchTrades
|
|
316
550
|
//
|
|
317
551
|
// {
|
|
318
|
-
// "
|
|
319
|
-
// "
|
|
320
|
-
// "
|
|
321
|
-
// "
|
|
322
|
-
// "amount": "0.
|
|
552
|
+
// "deal_id": 3514376759,
|
|
553
|
+
// "created_at": 1689152421692,
|
|
554
|
+
// "side": "buy",
|
|
555
|
+
// "price": "30718.42",
|
|
556
|
+
// "amount": "0.00000325"
|
|
323
557
|
// }
|
|
324
558
|
//
|
|
325
|
-
|
|
326
|
-
|
|
559
|
+
// swap watchTrades
|
|
560
|
+
//
|
|
561
|
+
// {
|
|
562
|
+
// "deal_id": 3514376759,
|
|
563
|
+
// "created_at": 1689152421692,
|
|
564
|
+
// "side": "buy",
|
|
565
|
+
// "price": "30718.42",
|
|
566
|
+
// "amount": "0.00000325"
|
|
567
|
+
// }
|
|
568
|
+
//
|
|
569
|
+
// spot and swap watchMyTrades
|
|
570
|
+
//
|
|
571
|
+
// {
|
|
572
|
+
// "deal_id": 3514376759,
|
|
573
|
+
// "created_at": 1689152421692,
|
|
574
|
+
// "market": "BTCUSDT",
|
|
575
|
+
// "side": "buy",
|
|
576
|
+
// "order_id": 8678890,
|
|
577
|
+
// "margin_market": "BTCUSDT",
|
|
578
|
+
// "price": "30718.42",
|
|
579
|
+
// "amount": "0.00000325",
|
|
580
|
+
// "role": "taker",
|
|
581
|
+
// "fee": "0.0299",
|
|
582
|
+
// "fee_ccy": "USDT"
|
|
583
|
+
// }
|
|
584
|
+
//
|
|
585
|
+
const timestamp = this.safeInteger(trade, 'created_at');
|
|
586
|
+
const isSpot = ('margin_market' in trade);
|
|
587
|
+
const defaultType = isSpot ? 'spot' : 'swap';
|
|
588
|
+
const marketId = this.safeString(trade, 'market');
|
|
589
|
+
market = this.safeMarket(marketId, market, undefined, defaultType);
|
|
590
|
+
let fee = {};
|
|
591
|
+
const feeCost = this.omitZero(this.safeString(trade, 'fee'));
|
|
592
|
+
if (feeCost !== undefined) {
|
|
593
|
+
const feeCurrencyId = this.safeString(trade, 'fee_ccy', market['quote']);
|
|
594
|
+
fee = {
|
|
595
|
+
'currency': this.safeCurrencyCode(feeCurrencyId),
|
|
596
|
+
'cost': feeCost,
|
|
597
|
+
};
|
|
598
|
+
}
|
|
327
599
|
return this.safeTrade({
|
|
328
|
-
'id': this.safeString(trade, '
|
|
600
|
+
'id': this.safeString(trade, 'deal_id'),
|
|
329
601
|
'info': trade,
|
|
330
602
|
'timestamp': timestamp,
|
|
331
603
|
'datetime': this.iso8601(timestamp),
|
|
332
|
-
'symbol': this.safeSymbol(
|
|
333
|
-
'order':
|
|
604
|
+
'symbol': this.safeSymbol(marketId, market, undefined, defaultType),
|
|
605
|
+
'order': this.safeString(trade, 'order_id'),
|
|
334
606
|
'type': undefined,
|
|
335
|
-
'side': this.safeString(trade, '
|
|
336
|
-
'takerOrMaker':
|
|
607
|
+
'side': this.safeString(trade, 'side'),
|
|
608
|
+
'takerOrMaker': this.safeString(trade, 'role'),
|
|
337
609
|
'price': this.safeString(trade, 'price'),
|
|
338
610
|
'amount': this.safeString(trade, 'amount'),
|
|
339
611
|
'cost': undefined,
|
|
340
|
-
'fee':
|
|
612
|
+
'fee': fee,
|
|
341
613
|
}, market);
|
|
342
614
|
}
|
|
343
|
-
handleOHLCV(client, message) {
|
|
344
|
-
//
|
|
345
|
-
// spot
|
|
346
|
-
// {
|
|
347
|
-
// "error": null,
|
|
348
|
-
// "result": [
|
|
349
|
-
// [
|
|
350
|
-
// 1673846940,
|
|
351
|
-
// "21148.74",
|
|
352
|
-
// "21148.38",
|
|
353
|
-
// "21148.75",
|
|
354
|
-
// "21138.66",
|
|
355
|
-
// "1.57060173",
|
|
356
|
-
// "33214.9138778914"
|
|
357
|
-
// ],
|
|
358
|
-
// ]
|
|
359
|
-
// "id": 1,
|
|
360
|
-
// }
|
|
361
|
-
// swap
|
|
362
|
-
// {
|
|
363
|
-
// "method": "kline.update",
|
|
364
|
-
// "params": [
|
|
365
|
-
// [
|
|
366
|
-
// 1654019640, // timestamp
|
|
367
|
-
// "32061.99", // open
|
|
368
|
-
// "32061.28", // close
|
|
369
|
-
// "32061.99", // high
|
|
370
|
-
// "32061.28", // low
|
|
371
|
-
// "0.1285", // amount base
|
|
372
|
-
// "4119.943736" // amount quote
|
|
373
|
-
// ]
|
|
374
|
-
// ],
|
|
375
|
-
// "id": null
|
|
376
|
-
// }
|
|
377
|
-
//
|
|
378
|
-
const candles = this.safeValue2(message, 'params', 'result', []);
|
|
379
|
-
const messageHash = 'ohlcv';
|
|
380
|
-
const id = this.safeString(message, 'id');
|
|
381
|
-
const ohlcvs = this.parseOHLCVs(candles);
|
|
382
|
-
if (id !== undefined) {
|
|
383
|
-
// spot subscription response
|
|
384
|
-
client.resolve(ohlcvs, messageHash);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
const keys = Object.keys(this.ohlcvs);
|
|
388
|
-
const keysLength = keys.length;
|
|
389
|
-
if (keysLength === 0) {
|
|
390
|
-
this.ohlcvs['unknown'] = {};
|
|
391
|
-
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
392
|
-
const stored = new Cache.ArrayCacheByTimestamp(limit);
|
|
393
|
-
this.ohlcvs['unknown']['unknown'] = stored;
|
|
394
|
-
}
|
|
395
|
-
const ohlcv = this.ohlcvs['unknown']['unknown'];
|
|
396
|
-
for (let i = 0; i < ohlcvs.length; i++) {
|
|
397
|
-
const candle = ohlcvs[i];
|
|
398
|
-
ohlcv.append(candle);
|
|
399
|
-
}
|
|
400
|
-
client.resolve(ohlcv, messageHash);
|
|
401
|
-
}
|
|
402
615
|
async watchTicker(symbol, params = {}) {
|
|
403
616
|
/**
|
|
404
617
|
* @method
|
|
405
618
|
* @name coinex#watchTicker
|
|
406
|
-
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot004_websocket007_state_subscribe
|
|
407
619
|
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
620
|
+
* @see https://docs.coinex.com/api/v2/spot/market/ws/market
|
|
621
|
+
* @see https://docs.coinex.com/api/v2/futures/market/ws/market-state
|
|
408
622
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
409
623
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
410
624
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
411
625
|
*/
|
|
626
|
+
await this.loadMarkets();
|
|
627
|
+
const market = this.market(symbol);
|
|
412
628
|
const tickers = await this.watchTickers([symbol], params);
|
|
413
|
-
return
|
|
629
|
+
return tickers[market['symbol']];
|
|
414
630
|
}
|
|
415
631
|
async watchTickers(symbols = undefined, params = {}) {
|
|
416
632
|
/**
|
|
417
633
|
* @method
|
|
418
634
|
* @name coinex#watchTickers
|
|
419
|
-
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot004_websocket007_state_subscribe
|
|
420
635
|
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
636
|
+
* @see https://docs.coinex.com/api/v2/spot/market/ws/market
|
|
637
|
+
* @see https://docs.coinex.com/api/v2/futures/market/ws/market-state
|
|
421
638
|
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
422
639
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
423
640
|
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
424
641
|
*/
|
|
425
642
|
await this.loadMarkets();
|
|
426
|
-
|
|
643
|
+
const marketIds = this.marketIds(symbols);
|
|
644
|
+
let market = undefined;
|
|
645
|
+
const messageHashes = [];
|
|
646
|
+
const symbolsDefined = (symbols !== undefined);
|
|
647
|
+
if (symbolsDefined) {
|
|
648
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
649
|
+
const symbol = symbols[i];
|
|
650
|
+
market = this.market(symbol);
|
|
651
|
+
messageHashes.push('tickers::' + market['symbol']);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
else {
|
|
655
|
+
messageHashes.push('tickers');
|
|
656
|
+
}
|
|
427
657
|
let type = undefined;
|
|
428
|
-
[type, params] = this.handleMarketTypeAndParams('watchTickers',
|
|
658
|
+
[type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
|
|
429
659
|
const url = this.urls['api']['ws'][type];
|
|
430
|
-
|
|
431
|
-
if (symbols !== undefined) {
|
|
432
|
-
messageHash = 'tickers::' + symbols.join(',');
|
|
433
|
-
}
|
|
660
|
+
const subscriptionHashes = ['all@ticker'];
|
|
434
661
|
const subscribe = {
|
|
435
662
|
'method': 'state.subscribe',
|
|
663
|
+
'params': { 'market_list': marketIds },
|
|
436
664
|
'id': this.requestId(),
|
|
437
|
-
'params': [],
|
|
438
665
|
};
|
|
439
|
-
const
|
|
440
|
-
const newTickers = await this.watch(url, messageHash, request, messageHash);
|
|
666
|
+
const result = await this.watchMultiple(url, messageHashes, this.deepExtend(subscribe, params), subscriptionHashes);
|
|
441
667
|
if (this.newUpdates) {
|
|
442
|
-
return
|
|
668
|
+
return result;
|
|
443
669
|
}
|
|
444
670
|
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
445
671
|
}
|
|
@@ -447,179 +673,139 @@ class coinex extends coinex$1 {
|
|
|
447
673
|
/**
|
|
448
674
|
* @method
|
|
449
675
|
* @name coinex#watchTrades
|
|
450
|
-
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot004_websocket012_deal_subcribe
|
|
451
|
-
* @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures002_websocket019_deal_subcribe
|
|
452
676
|
* @description get the list of most recent trades for a particular symbol
|
|
677
|
+
* @see https://docs.coinex.com/api/v2/spot/market/ws/market-deals
|
|
678
|
+
* @see https://docs.coinex.com/api/v2/futures/market/ws/market-deals
|
|
453
679
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
454
680
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
455
681
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
456
682
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
457
683
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
458
684
|
*/
|
|
685
|
+
params['callerMethodName'] = 'watchTrades';
|
|
686
|
+
return await this.watchTradesForSymbols([symbol], since, limit, params);
|
|
687
|
+
}
|
|
688
|
+
async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
|
|
689
|
+
/**
|
|
690
|
+
* @method
|
|
691
|
+
* @name coinex#watchTradesForSymbols
|
|
692
|
+
* @description watch the most recent trades for a list of symbols
|
|
693
|
+
* @see https://docs.coinex.com/api/v2/spot/market/ws/market-deals
|
|
694
|
+
* @see https://docs.coinex.com/api/v2/futures/market/ws/market-deals
|
|
695
|
+
* @param {string[]} symbols unified symbols of the markets to fetch trades for
|
|
696
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
697
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
698
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
699
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
700
|
+
*/
|
|
459
701
|
await this.loadMarkets();
|
|
460
|
-
const
|
|
702
|
+
const subscribedSymbols = [];
|
|
703
|
+
const messageHashes = [];
|
|
704
|
+
let market = undefined;
|
|
705
|
+
let callerMethodName = undefined;
|
|
706
|
+
[callerMethodName, params] = this.handleParamString(params, 'callerMethodName', 'watchTradesForSymbols');
|
|
707
|
+
const symbolsDefined = (symbols !== undefined);
|
|
708
|
+
if (symbolsDefined) {
|
|
709
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
710
|
+
const symbol = symbols[i];
|
|
711
|
+
market = this.market(symbol);
|
|
712
|
+
subscribedSymbols.push(market['id']);
|
|
713
|
+
messageHashes.push('trades:' + market['symbol']);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
messageHashes.push('trades');
|
|
718
|
+
}
|
|
461
719
|
let type = undefined;
|
|
462
|
-
[type, params] = this.handleMarketTypeAndParams(
|
|
720
|
+
[type, params] = this.handleMarketTypeAndParams(callerMethodName, market, params);
|
|
463
721
|
const url = this.urls['api']['ws'][type];
|
|
464
|
-
const
|
|
465
|
-
const
|
|
466
|
-
const subscribedSymbols = this.safeValue(this.options, 'watchTradesSubscriptions', []);
|
|
467
|
-
subscribedSymbols.push(market['id']);
|
|
468
|
-
const message = {
|
|
722
|
+
const subscriptionHashes = ['trades'];
|
|
723
|
+
const subscribe = {
|
|
469
724
|
'method': 'deals.subscribe',
|
|
470
|
-
'params': subscribedSymbols,
|
|
725
|
+
'params': { 'market_list': subscribedSymbols },
|
|
471
726
|
'id': this.requestId(),
|
|
472
727
|
};
|
|
473
|
-
this.
|
|
474
|
-
|
|
475
|
-
|
|
728
|
+
const trades = await this.watchMultiple(url, messageHashes, this.deepExtend(subscribe, params), subscriptionHashes);
|
|
729
|
+
if (this.newUpdates) {
|
|
730
|
+
return trades;
|
|
731
|
+
}
|
|
476
732
|
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
477
733
|
}
|
|
478
|
-
async
|
|
734
|
+
async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
|
|
479
735
|
/**
|
|
480
736
|
* @method
|
|
481
|
-
* @name coinex#
|
|
482
|
-
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot004_websocket017_depth_subscribe_multi
|
|
483
|
-
* @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures002_websocket011_depth_subscribe_multi
|
|
737
|
+
* @name coinex#watchOrderBookForSymbols
|
|
484
738
|
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
485
|
-
* @
|
|
739
|
+
* @see https://docs.coinex.com/api/v2/spot/market/ws/market-depth
|
|
740
|
+
* @see https://docs.coinex.com/api/v2/futures/market/ws/market-depth
|
|
741
|
+
* @param {string[]} symbols unified array of symbols
|
|
486
742
|
* @param {int} [limit] the maximum amount of order book entries to return
|
|
487
743
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
488
744
|
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
489
745
|
*/
|
|
490
746
|
await this.loadMarkets();
|
|
491
|
-
const
|
|
492
|
-
|
|
747
|
+
const watchOrderBookSubscriptions = {};
|
|
748
|
+
const messageHashes = [];
|
|
749
|
+
let market = undefined;
|
|
493
750
|
let type = undefined;
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
const
|
|
498
|
-
const
|
|
499
|
-
const limits = this.safeValue(options, 'limits', []);
|
|
751
|
+
let callerMethodName = undefined;
|
|
752
|
+
[callerMethodName, params] = this.handleParamString(params, 'callerMethodName', 'watchOrderBookForSymbols');
|
|
753
|
+
[type, params] = this.handleMarketTypeAndParams(callerMethodName, undefined, params);
|
|
754
|
+
const options = this.safeDict(this.options, 'watchOrderBook', {});
|
|
755
|
+
const limits = this.safeList(options, 'limits', []);
|
|
500
756
|
if (limit === undefined) {
|
|
501
|
-
limit = this.
|
|
757
|
+
limit = this.safeInteger(options, 'defaultLimit', 50);
|
|
502
758
|
}
|
|
503
759
|
if (!this.inArray(limit, limits)) {
|
|
504
|
-
throw new errors.NotSupported(this.id + '
|
|
760
|
+
throw new errors.NotSupported(this.id + ' watchOrderBookForSymbols() limit must be one of ' + limits.join(', '));
|
|
505
761
|
}
|
|
506
762
|
const defaultAggregation = this.safeString(options, 'defaultAggregation', '0');
|
|
507
|
-
const aggregations = this.
|
|
763
|
+
const aggregations = this.safeList(options, 'aggregations', []);
|
|
508
764
|
const aggregation = this.safeString(params, 'aggregation', defaultAggregation);
|
|
509
765
|
if (!this.inArray(aggregation, aggregations)) {
|
|
510
|
-
throw new errors.NotSupported(this.id + '
|
|
766
|
+
throw new errors.NotSupported(this.id + ' watchOrderBookForSymbols() aggregation must be one of ' + aggregations.join(', '));
|
|
511
767
|
}
|
|
512
768
|
params = this.omit(params, 'aggregation');
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
const subscriptionHash = this.hash(this.encode(this.json(watchOrderBookSubscriptions)), sha256.sha256);
|
|
522
|
-
const request = this.deepExtend(subscribe, params);
|
|
523
|
-
const orderbook = await this.watch(url, messageHash, request, subscriptionHash, request);
|
|
524
|
-
return orderbook.limit();
|
|
525
|
-
}
|
|
526
|
-
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
527
|
-
/**
|
|
528
|
-
* @method
|
|
529
|
-
* @name coinex#watchOHLCV
|
|
530
|
-
* @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures002_websocket023_kline_subscribe
|
|
531
|
-
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
532
|
-
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
533
|
-
* @param {string} timeframe the length of time each candle represents
|
|
534
|
-
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
535
|
-
* @param {int} [limit] the maximum amount of candles to fetch
|
|
536
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
537
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
538
|
-
*/
|
|
539
|
-
await this.loadMarkets();
|
|
540
|
-
const market = this.market(symbol);
|
|
541
|
-
symbol = market['symbol'];
|
|
542
|
-
let type = undefined;
|
|
543
|
-
[type, params] = this.handleMarketTypeAndParams('watchOHLCV', market, params);
|
|
544
|
-
if (type !== 'swap') {
|
|
545
|
-
throw new errors.NotSupported(this.id + ' watchOHLCV() is only supported for swap markets. Try using fetchOHLCV () instead');
|
|
769
|
+
const symbolsDefined = (symbols !== undefined);
|
|
770
|
+
if (symbolsDefined) {
|
|
771
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
772
|
+
const symbol = symbols[i];
|
|
773
|
+
market = this.market(symbol);
|
|
774
|
+
messageHashes.push('orderbook:' + market['symbol']);
|
|
775
|
+
watchOrderBookSubscriptions[symbol] = [market['id'], limit, aggregation, true];
|
|
776
|
+
}
|
|
546
777
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
const watchOHLCVWarning = this.safeBool(this.options, 'watchOHLCVWarning', true);
|
|
550
|
-
const client = this.safeValue(this.clients, url, {});
|
|
551
|
-
const clientSub = this.safeValue(client, 'subscriptions', {});
|
|
552
|
-
const existingSubscription = this.safeValue(clientSub, messageHash);
|
|
553
|
-
const subSymbol = this.safeString(existingSubscription, 'symbol');
|
|
554
|
-
const subTimeframe = this.safeString(existingSubscription, 'timeframe');
|
|
555
|
-
// due to nature of coinex response can only watch one symbol at a time
|
|
556
|
-
if (watchOHLCVWarning && existingSubscription !== undefined && (subSymbol !== symbol || subTimeframe !== timeframe)) {
|
|
557
|
-
throw new errors.ExchangeError(this.id + ' watchOHLCV() can only watch one symbol and timeframe at a time. To supress this warning set watchOHLCVWarning to false in options');
|
|
778
|
+
else {
|
|
779
|
+
messageHashes.push('orderbook');
|
|
558
780
|
}
|
|
559
|
-
const
|
|
781
|
+
const marketList = Object.values(watchOrderBookSubscriptions);
|
|
560
782
|
const subscribe = {
|
|
561
|
-
'method': '
|
|
783
|
+
'method': 'depth.subscribe',
|
|
784
|
+
'params': { 'market_list': marketList },
|
|
562
785
|
'id': this.requestId(),
|
|
563
|
-
'params': [
|
|
564
|
-
market['id'],
|
|
565
|
-
this.safeInteger(timeframes, timeframe),
|
|
566
|
-
],
|
|
567
786
|
};
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
};
|
|
572
|
-
const request = this.deepExtend(subscribe, params);
|
|
573
|
-
const ohlcvs = await this.watch(url, messageHash, request, messageHash, subscription);
|
|
787
|
+
const subscriptionHashes = this.hash(this.encode(this.json(watchOrderBookSubscriptions)), sha256.sha256);
|
|
788
|
+
const url = this.urls['api']['ws'][type];
|
|
789
|
+
const orderbooks = await this.watchMultiple(url, messageHashes, this.deepExtend(subscribe, params), subscriptionHashes);
|
|
574
790
|
if (this.newUpdates) {
|
|
575
|
-
|
|
791
|
+
return orderbooks;
|
|
576
792
|
}
|
|
577
|
-
return
|
|
793
|
+
return orderbooks.limit();
|
|
578
794
|
}
|
|
579
|
-
async
|
|
795
|
+
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
580
796
|
/**
|
|
581
797
|
* @method
|
|
582
|
-
* @name coinex#
|
|
583
|
-
* @
|
|
584
|
-
* @
|
|
585
|
-
* @
|
|
586
|
-
* @param {string}
|
|
587
|
-
* @param {int
|
|
588
|
-
* @param {
|
|
589
|
-
* @
|
|
590
|
-
* @param {int|undefined} params.end the end time for spot markets, this.seconds () is set as default
|
|
591
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
798
|
+
* @name coinex#watchOrderBook
|
|
799
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
800
|
+
* @see https://docs.coinex.com/api/v2/spot/market/ws/market-depth
|
|
801
|
+
* @see https://docs.coinex.com/api/v2/futures/market/ws/market-depth
|
|
802
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
803
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
804
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
805
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
592
806
|
*/
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
const [type, query] = this.handleMarketTypeAndParams('fetchOHLCV', market, params);
|
|
596
|
-
const url = this.urls['api']['ws'][type];
|
|
597
|
-
symbol = market['symbol'];
|
|
598
|
-
const messageHash = 'ohlcv';
|
|
599
|
-
const timeframes = this.safeValue(this.options, 'timeframes', {});
|
|
600
|
-
timeframe = this.safeString(timeframes, timeframe, timeframe);
|
|
601
|
-
if (since === undefined) {
|
|
602
|
-
since = 1640995200; // January 1, 2022
|
|
603
|
-
}
|
|
604
|
-
const id = this.requestId();
|
|
605
|
-
const subscribe = {
|
|
606
|
-
'method': 'kline.query',
|
|
607
|
-
'params': [
|
|
608
|
-
market['id'],
|
|
609
|
-
this.parseToInt(since / 1000),
|
|
610
|
-
this.safeInteger(params, 'end', this.seconds()),
|
|
611
|
-
this.parseToInt(timeframe),
|
|
612
|
-
],
|
|
613
|
-
'id': id,
|
|
614
|
-
};
|
|
615
|
-
const subscription = {
|
|
616
|
-
'id': id,
|
|
617
|
-
'future': messageHash,
|
|
618
|
-
};
|
|
619
|
-
const subscriptionHash = id;
|
|
620
|
-
const request = this.deepExtend(subscribe, query);
|
|
621
|
-
const ohlcvs = await this.watch(url, messageHash, request, subscriptionHash, subscription);
|
|
622
|
-
return this.filterBySinceLimit(ohlcvs, since, limit, 0);
|
|
807
|
+
params['callerMethodName'] = 'watchOrderBook';
|
|
808
|
+
return await this.watchOrderBookForSymbols([symbol], limit, params);
|
|
623
809
|
}
|
|
624
810
|
handleDelta(bookside, delta) {
|
|
625
811
|
const bidAsk = this.parseBidAsk(delta, 0, 1);
|
|
@@ -634,52 +820,54 @@ class coinex extends coinex$1 {
|
|
|
634
820
|
//
|
|
635
821
|
// {
|
|
636
822
|
// "method": "depth.update",
|
|
637
|
-
// "
|
|
638
|
-
//
|
|
639
|
-
//
|
|
823
|
+
// "data": {
|
|
824
|
+
// "market": "BTCUSDT",
|
|
825
|
+
// "is_full": true,
|
|
826
|
+
// "depth": {
|
|
640
827
|
// "asks": [
|
|
641
|
-
// [
|
|
642
|
-
//
|
|
828
|
+
// [
|
|
829
|
+
// "30740.00",
|
|
830
|
+
// "0.31763545"
|
|
831
|
+
// ],
|
|
643
832
|
// ],
|
|
644
833
|
// "bids": [
|
|
645
|
-
// [
|
|
646
|
-
//
|
|
834
|
+
// [
|
|
835
|
+
// "30736.00",
|
|
836
|
+
// "0.04857373"
|
|
837
|
+
// ],
|
|
647
838
|
// ],
|
|
648
|
-
// "last": "
|
|
649
|
-
// "
|
|
650
|
-
// "checksum":
|
|
651
|
-
// }
|
|
652
|
-
//
|
|
653
|
-
// ],
|
|
839
|
+
// "last": "30746.28",
|
|
840
|
+
// "updated_at": 1689152421692,
|
|
841
|
+
// "checksum": 2578768879
|
|
842
|
+
// }
|
|
843
|
+
// },
|
|
654
844
|
// "id": null
|
|
655
845
|
// }
|
|
656
846
|
//
|
|
657
|
-
const
|
|
658
|
-
const
|
|
659
|
-
const
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
const marketId = this.safeString(params, 2);
|
|
663
|
-
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
847
|
+
const defaultType = this.safeString(this.options, 'defaultType');
|
|
848
|
+
const data = this.safeDict(message, 'data', {});
|
|
849
|
+
const depth = this.safeDict(data, 'depth', {});
|
|
850
|
+
const marketId = this.safeString(data, 'market');
|
|
851
|
+
const market = this.safeMarket(marketId, undefined, undefined, defaultType);
|
|
664
852
|
const symbol = market['symbol'];
|
|
665
853
|
const name = 'orderbook';
|
|
666
854
|
const messageHash = name + ':' + symbol;
|
|
667
|
-
const timestamp = this.safeInteger(
|
|
855
|
+
const timestamp = this.safeInteger(depth, 'updated_at');
|
|
668
856
|
const currentOrderBook = this.safeValue(this.orderbooks, symbol);
|
|
857
|
+
const fullOrderBook = this.safeBool(data, 'is_full', false);
|
|
669
858
|
if (fullOrderBook) {
|
|
670
|
-
const snapshot = this.parseOrderBook(
|
|
859
|
+
const snapshot = this.parseOrderBook(depth, symbol, timestamp);
|
|
671
860
|
if (currentOrderBook === undefined) {
|
|
672
|
-
|
|
673
|
-
this.orderbooks[symbol] = orderbook;
|
|
861
|
+
this.orderbooks[symbol] = this.orderBook(snapshot);
|
|
674
862
|
}
|
|
675
863
|
else {
|
|
676
|
-
orderbook = this.orderbooks[symbol];
|
|
864
|
+
const orderbook = this.orderbooks[symbol];
|
|
677
865
|
orderbook.reset(snapshot);
|
|
678
866
|
}
|
|
679
867
|
}
|
|
680
868
|
else {
|
|
681
|
-
const asks = this.
|
|
682
|
-
const bids = this.
|
|
869
|
+
const asks = this.safeList(depth, 'asks', []);
|
|
870
|
+
const bids = this.safeList(depth, 'bids', []);
|
|
683
871
|
this.handleDeltas(currentOrderBook['asks'], asks);
|
|
684
872
|
this.handleDeltas(currentOrderBook['bids'], bids);
|
|
685
873
|
currentOrderBook['nonce'] = timestamp;
|
|
@@ -691,26 +879,59 @@ class coinex extends coinex$1 {
|
|
|
691
879
|
client.resolve(this.orderbooks[symbol], messageHash);
|
|
692
880
|
}
|
|
693
881
|
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
882
|
+
/**
|
|
883
|
+
* @method
|
|
884
|
+
* @name coinex#watchOrders
|
|
885
|
+
* @description watches information on multiple orders made by the user
|
|
886
|
+
* @see https://docs.coinex.com/api/v2/spot/order/ws/user-order
|
|
887
|
+
* @see https://docs.coinex.com/api/v2/futures/order/ws/user-order
|
|
888
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
889
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
890
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
891
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
892
|
+
* @param {bool} [params.trigger] if the orders to watch are trigger orders or not
|
|
893
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
894
|
+
*/
|
|
694
895
|
await this.loadMarkets();
|
|
695
|
-
|
|
896
|
+
const stop = this.safeBool2(params, 'trigger', 'stop');
|
|
897
|
+
params = this.omit(params, ['trigger', 'stop']);
|
|
696
898
|
let messageHash = 'orders';
|
|
697
899
|
let market = undefined;
|
|
698
|
-
|
|
699
|
-
const message = {
|
|
700
|
-
'method': 'order.subscribe',
|
|
701
|
-
'id': this.requestId(),
|
|
702
|
-
};
|
|
900
|
+
let marketList = undefined;
|
|
703
901
|
if (symbol !== undefined) {
|
|
704
902
|
market = this.market(symbol);
|
|
705
903
|
symbol = market['symbol'];
|
|
706
|
-
|
|
904
|
+
}
|
|
905
|
+
let type = undefined;
|
|
906
|
+
[type, params] = this.handleMarketTypeAndParams('watchOrders', market, params, 'spot');
|
|
907
|
+
await this.authenticate(type);
|
|
908
|
+
if (symbol !== undefined) {
|
|
909
|
+
marketList = [market['id']];
|
|
707
910
|
messageHash += ':' + symbol;
|
|
708
911
|
}
|
|
709
912
|
else {
|
|
710
|
-
|
|
913
|
+
marketList = [];
|
|
914
|
+
if (type === 'spot') {
|
|
915
|
+
messageHash += ':spot';
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
messageHash += ':swap';
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
let method = undefined;
|
|
922
|
+
if (stop) {
|
|
923
|
+
method = 'stop.subscribe';
|
|
924
|
+
}
|
|
925
|
+
else {
|
|
926
|
+
method = 'order.subscribe';
|
|
711
927
|
}
|
|
928
|
+
const message = {
|
|
929
|
+
'method': method,
|
|
930
|
+
'params': { 'market_list': marketList },
|
|
931
|
+
'id': this.requestId(),
|
|
932
|
+
};
|
|
712
933
|
const url = this.urls['api']['ws'][type];
|
|
713
|
-
const request = this.deepExtend(message,
|
|
934
|
+
const request = this.deepExtend(message, params);
|
|
714
935
|
const orders = await this.watch(url, messageHash, request, messageHash, request);
|
|
715
936
|
if (this.newUpdates) {
|
|
716
937
|
limit = orders.getLimit(symbol, limit);
|
|
@@ -719,94 +940,126 @@ class coinex extends coinex$1 {
|
|
|
719
940
|
}
|
|
720
941
|
handleOrders(client, message) {
|
|
721
942
|
//
|
|
722
|
-
//
|
|
943
|
+
// spot
|
|
723
944
|
//
|
|
724
|
-
//
|
|
725
|
-
//
|
|
726
|
-
//
|
|
727
|
-
//
|
|
728
|
-
//
|
|
729
|
-
//
|
|
730
|
-
//
|
|
731
|
-
//
|
|
732
|
-
//
|
|
733
|
-
//
|
|
734
|
-
//
|
|
735
|
-
//
|
|
736
|
-
//
|
|
737
|
-
//
|
|
738
|
-
//
|
|
739
|
-
//
|
|
740
|
-
//
|
|
741
|
-
//
|
|
742
|
-
//
|
|
743
|
-
//
|
|
744
|
-
//
|
|
745
|
-
//
|
|
746
|
-
//
|
|
747
|
-
//
|
|
748
|
-
//
|
|
749
|
-
//
|
|
750
|
-
//
|
|
751
|
-
//
|
|
752
|
-
// "last_deal_price": "0",
|
|
753
|
-
// "last_deal_time": 0,
|
|
754
|
-
// "last_deal_id": 0,
|
|
755
|
-
// "last_role": 0,
|
|
756
|
-
// "fee_asset": null,
|
|
757
|
-
// "stop_id": 0
|
|
758
|
-
// }
|
|
759
|
-
// ],
|
|
760
|
-
// "id": null
|
|
761
|
-
// }
|
|
945
|
+
// {
|
|
946
|
+
// "method": "order.update",
|
|
947
|
+
// "data": {
|
|
948
|
+
// "event": "put",
|
|
949
|
+
// "order": {
|
|
950
|
+
// "order_id": 12750,
|
|
951
|
+
// "market": "BTCUSDT",
|
|
952
|
+
// "margin_market": "BTCUSDT",
|
|
953
|
+
// "type": "limit",
|
|
954
|
+
// "side": "buy",
|
|
955
|
+
// "price": "5999.00",
|
|
956
|
+
// "amount": "1.50000000",
|
|
957
|
+
// "unfill_amount": "1.50000000",
|
|
958
|
+
// "fill_value": "1.50000000",
|
|
959
|
+
// "taker_fee_rate": "0.0001",
|
|
960
|
+
// "maker_fee_rate": "0.0001",
|
|
961
|
+
// "base_ccy_fee": "0.0001",
|
|
962
|
+
// "quote_ccy_fee": "0.0001",
|
|
963
|
+
// "discount_ccy_fee": "0.0001",
|
|
964
|
+
// "last_fill_amount": "0",
|
|
965
|
+
// "last_fill_price": "0",
|
|
966
|
+
// "client_id": "buy1_1234",
|
|
967
|
+
// "created_at": 1689152421692,
|
|
968
|
+
// "updated_at": 1689152421692,
|
|
969
|
+
// }
|
|
970
|
+
// },
|
|
971
|
+
// "id": null
|
|
972
|
+
// }
|
|
762
973
|
//
|
|
763
|
-
//
|
|
974
|
+
// spot stop
|
|
975
|
+
//
|
|
976
|
+
// {
|
|
977
|
+
// "method": "stop.update",
|
|
978
|
+
// "data": {
|
|
979
|
+
// "event": 1,
|
|
980
|
+
// "stop": {
|
|
981
|
+
// "stop_id": 102067022299,
|
|
982
|
+
// "market": "BTCUSDT",
|
|
983
|
+
// "margin_market": "BTCUSDT",
|
|
984
|
+
// "type": "limit",
|
|
985
|
+
// "side": "buy",
|
|
986
|
+
// "price": "20000.00",
|
|
987
|
+
// "amount": "0.10000000",
|
|
988
|
+
// "trigger_price": "20000.00",
|
|
989
|
+
// "trigger_direction": "lower",
|
|
990
|
+
// "taker_fee_rate": "0.0016",
|
|
991
|
+
// "maker_fee_rate": "0.0016",
|
|
992
|
+
// "status": "active_success",
|
|
993
|
+
// "client_id": "",
|
|
994
|
+
// "created_at": 1689152996689,
|
|
995
|
+
// "updated_at": 1689152996689,
|
|
996
|
+
// }
|
|
997
|
+
// },
|
|
998
|
+
// "id": null
|
|
999
|
+
// }
|
|
1000
|
+
//
|
|
1001
|
+
// swap
|
|
1002
|
+
//
|
|
1003
|
+
// {
|
|
1004
|
+
// "method": "order.update",
|
|
1005
|
+
// "data": {
|
|
1006
|
+
// "event": "put",
|
|
1007
|
+
// "order": {
|
|
1008
|
+
// "order_id": 98388656341,
|
|
1009
|
+
// "stop_id": 0,
|
|
1010
|
+
// "market": "BTCUSDT",
|
|
1011
|
+
// "side": "buy",
|
|
1012
|
+
// "type": "limit",
|
|
1013
|
+
// "amount": "0.0010",
|
|
1014
|
+
// "price": "50000.00",
|
|
1015
|
+
// "unfilled_amount": "0.0010",
|
|
1016
|
+
// "filled_amount": "0",
|
|
1017
|
+
// "filled_value": "0",
|
|
1018
|
+
// "fee": "0",
|
|
1019
|
+
// "fee_ccy": "USDT",
|
|
1020
|
+
// "taker_fee_rate": "0.00046",
|
|
1021
|
+
// "maker_fee_rate": "0.00000000000000000000",
|
|
1022
|
+
// "client_id": "",
|
|
1023
|
+
// "last_filled_amount": "0.0010",
|
|
1024
|
+
// "last_filled_price": "30721.35",
|
|
1025
|
+
// "created_at": 1689145715129,
|
|
1026
|
+
// "updated_at": 1689145715129
|
|
1027
|
+
// }
|
|
1028
|
+
// },
|
|
1029
|
+
// "id": null
|
|
1030
|
+
// }
|
|
1031
|
+
//
|
|
1032
|
+
// swap stop
|
|
1033
|
+
//
|
|
1034
|
+
// {
|
|
1035
|
+
// "method": "stop.update",
|
|
1036
|
+
// "data": {
|
|
1037
|
+
// "event": "put",
|
|
1038
|
+
// "stop": {
|
|
1039
|
+
// "stop_id": 98389557871,
|
|
1040
|
+
// "market": "BTCUSDT",
|
|
1041
|
+
// "side": "sell",
|
|
1042
|
+
// "type": "limit",
|
|
1043
|
+
// "price": "20000.00",
|
|
1044
|
+
// "amount": "0.0100",
|
|
1045
|
+
// "trigger_price": "20000.00",
|
|
1046
|
+
// "trigger_direction": "higer",
|
|
1047
|
+
// "trigger_price_type": "index_price",
|
|
1048
|
+
// "taker_fee_rate": "0.00046",
|
|
1049
|
+
// "maker_fee_rate": "0.00026",
|
|
1050
|
+
// "client_id": "",
|
|
1051
|
+
// "created_at": 1689146382674,
|
|
1052
|
+
// "updated_at": 1689146382674
|
|
1053
|
+
// }
|
|
1054
|
+
// },
|
|
1055
|
+
// "id": null
|
|
1056
|
+
// }
|
|
764
1057
|
//
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
// "params": [
|
|
768
|
-
// 1,
|
|
769
|
-
// {
|
|
770
|
-
// "order_id": 23423462821,
|
|
771
|
-
// "position_id": 0,
|
|
772
|
-
// "stop_id": 0,
|
|
773
|
-
// "market": "BTCUSDT",
|
|
774
|
-
// "type": 1,
|
|
775
|
-
// "side": 2,
|
|
776
|
-
// "target": 0,
|
|
777
|
-
// "effect_type": 1,
|
|
778
|
-
// "user_id": 1849116,
|
|
779
|
-
// "create_time": 1653961509.25049,
|
|
780
|
-
// "update_time": 1653961509.25049,
|
|
781
|
-
// "source": "web",
|
|
782
|
-
// "price": "1.00",
|
|
783
|
-
// "amount": "1.0000",
|
|
784
|
-
// "taker_fee": "0.00050",
|
|
785
|
-
// "maker_fee": "0.00030",
|
|
786
|
-
// "left": "1.0000",
|
|
787
|
-
// "deal_stock": "0.00000000000000000000",
|
|
788
|
-
// "deal_fee": "0.00000000000000000000",
|
|
789
|
-
// "deal_profit": "0.00000000000000000000",
|
|
790
|
-
// "last_deal_amount": "0.00000000000000000000",
|
|
791
|
-
// "last_deal_price": "0.00000000000000000000",
|
|
792
|
-
// "last_deal_time": 0,
|
|
793
|
-
// "last_deal_id": 0,
|
|
794
|
-
// "last_deal_type": 0,
|
|
795
|
-
// "last_deal_role": 0,
|
|
796
|
-
// "client_id": '',
|
|
797
|
-
// "fee_asset": '',
|
|
798
|
-
// "fee_discount": "0.00000000000000000000",
|
|
799
|
-
// "deal_asset_fee": "0.00000000000000000000",
|
|
800
|
-
// "leverage": "3",
|
|
801
|
-
// "position_type": 2
|
|
802
|
-
// }
|
|
803
|
-
// ],
|
|
804
|
-
// "id": null
|
|
805
|
-
// }
|
|
806
|
-
//
|
|
807
|
-
const params = this.safeValue(message, 'params', []);
|
|
808
|
-
const order = this.safeValue(params, 1, {});
|
|
1058
|
+
const data = this.safeDict(message, 'data', {});
|
|
1059
|
+
const order = this.safeDict2(data, 'order', 'stop', {});
|
|
809
1060
|
const parsedOrder = this.parseWsOrder(order);
|
|
1061
|
+
const symbol = parsedOrder['symbol'];
|
|
1062
|
+
const market = this.market(symbol);
|
|
810
1063
|
if (this.orders === undefined) {
|
|
811
1064
|
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
|
|
812
1065
|
this.orders = new Cache.ArrayCacheBySymbolById(limit);
|
|
@@ -814,138 +1067,110 @@ class coinex extends coinex$1 {
|
|
|
814
1067
|
const orders = this.orders;
|
|
815
1068
|
orders.append(parsedOrder);
|
|
816
1069
|
let messageHash = 'orders';
|
|
817
|
-
|
|
818
|
-
|
|
1070
|
+
const messageWithType = messageHash + ':' + market['type'];
|
|
1071
|
+
client.resolve(this.orders, messageWithType);
|
|
1072
|
+
messageHash += ':' + symbol;
|
|
819
1073
|
client.resolve(this.orders, messageHash);
|
|
820
1074
|
}
|
|
821
1075
|
parseWsOrder(order, market = undefined) {
|
|
822
1076
|
//
|
|
823
|
-
//
|
|
1077
|
+
// spot
|
|
824
1078
|
//
|
|
825
|
-
//
|
|
826
|
-
//
|
|
827
|
-
//
|
|
828
|
-
//
|
|
829
|
-
//
|
|
830
|
-
//
|
|
831
|
-
//
|
|
832
|
-
//
|
|
833
|
-
//
|
|
834
|
-
//
|
|
835
|
-
//
|
|
836
|
-
//
|
|
837
|
-
//
|
|
838
|
-
//
|
|
839
|
-
//
|
|
840
|
-
//
|
|
841
|
-
//
|
|
842
|
-
//
|
|
843
|
-
//
|
|
844
|
-
//
|
|
845
|
-
//
|
|
846
|
-
// "asset_fee": "0",
|
|
847
|
-
// "fee_discount": "1",
|
|
848
|
-
// "last_deal_amount": "0",
|
|
849
|
-
// "last_deal_price": "0",
|
|
850
|
-
// "last_deal_time": 0,
|
|
851
|
-
// "last_deal_id": 0,
|
|
852
|
-
// "last_role": 0,
|
|
853
|
-
// "fee_asset": null,
|
|
854
|
-
// "stop_id": 0
|
|
855
|
-
// }
|
|
1079
|
+
// {
|
|
1080
|
+
// "order_id": 12750,
|
|
1081
|
+
// "market": "BTCUSDT",
|
|
1082
|
+
// "margin_market": "BTCUSDT",
|
|
1083
|
+
// "type": "limit",
|
|
1084
|
+
// "side": "buy",
|
|
1085
|
+
// "price": "5999.00",
|
|
1086
|
+
// "amount": "1.50000000",
|
|
1087
|
+
// "unfill_amount": "1.50000000",
|
|
1088
|
+
// "fill_value": "1.50000000",
|
|
1089
|
+
// "taker_fee_rate": "0.0001",
|
|
1090
|
+
// "maker_fee_rate": "0.0001",
|
|
1091
|
+
// "base_ccy_fee": "0.0001",
|
|
1092
|
+
// "quote_ccy_fee": "0.0001",
|
|
1093
|
+
// "discount_ccy_fee": "0.0001",
|
|
1094
|
+
// "last_fill_amount": "0",
|
|
1095
|
+
// "last_fill_price": "0",
|
|
1096
|
+
// "client_id": "buy1_1234",
|
|
1097
|
+
// "created_at": 1689152421692,
|
|
1098
|
+
// "updated_at": 1689152421692,
|
|
1099
|
+
// }
|
|
856
1100
|
//
|
|
857
|
-
//
|
|
1101
|
+
// spot stop
|
|
858
1102
|
//
|
|
859
|
-
//
|
|
860
|
-
//
|
|
861
|
-
//
|
|
862
|
-
//
|
|
863
|
-
//
|
|
864
|
-
//
|
|
865
|
-
//
|
|
866
|
-
//
|
|
867
|
-
//
|
|
868
|
-
//
|
|
869
|
-
//
|
|
870
|
-
//
|
|
871
|
-
//
|
|
872
|
-
//
|
|
873
|
-
//
|
|
874
|
-
//
|
|
875
|
-
//
|
|
876
|
-
//
|
|
877
|
-
//
|
|
878
|
-
//
|
|
879
|
-
//
|
|
880
|
-
//
|
|
881
|
-
//
|
|
882
|
-
//
|
|
883
|
-
//
|
|
884
|
-
//
|
|
885
|
-
//
|
|
886
|
-
//
|
|
887
|
-
//
|
|
888
|
-
//
|
|
889
|
-
//
|
|
890
|
-
//
|
|
891
|
-
//
|
|
892
|
-
//
|
|
893
|
-
//
|
|
894
|
-
//
|
|
895
|
-
//
|
|
896
|
-
//
|
|
897
|
-
//
|
|
898
|
-
//
|
|
899
|
-
//
|
|
900
|
-
//
|
|
901
|
-
//
|
|
902
|
-
//
|
|
903
|
-
//
|
|
904
|
-
//
|
|
905
|
-
//
|
|
906
|
-
//
|
|
907
|
-
//
|
|
908
|
-
//
|
|
909
|
-
//
|
|
910
|
-
//
|
|
911
|
-
//
|
|
912
|
-
//
|
|
913
|
-
//
|
|
914
|
-
//
|
|
915
|
-
//
|
|
916
|
-
//
|
|
917
|
-
//
|
|
918
|
-
//
|
|
919
|
-
|
|
1103
|
+
// {
|
|
1104
|
+
// "stop_id": 102067022299,
|
|
1105
|
+
// "market": "BTCUSDT",
|
|
1106
|
+
// "margin_market": "BTCUSDT",
|
|
1107
|
+
// "type": "limit",
|
|
1108
|
+
// "side": "buy",
|
|
1109
|
+
// "price": "20000.00",
|
|
1110
|
+
// "amount": "0.10000000",
|
|
1111
|
+
// "trigger_price": "20000.00",
|
|
1112
|
+
// "trigger_direction": "lower",
|
|
1113
|
+
// "taker_fee_rate": "0.0016",
|
|
1114
|
+
// "maker_fee_rate": "0.0016",
|
|
1115
|
+
// "status": "active_success",
|
|
1116
|
+
// "client_id": "",
|
|
1117
|
+
// "created_at": 1689152996689,
|
|
1118
|
+
// "updated_at": 1689152996689,
|
|
1119
|
+
// }
|
|
1120
|
+
//
|
|
1121
|
+
// swap
|
|
1122
|
+
//
|
|
1123
|
+
// {
|
|
1124
|
+
// "order_id": 98388656341,
|
|
1125
|
+
// "stop_id": 0,
|
|
1126
|
+
// "market": "BTCUSDT",
|
|
1127
|
+
// "side": "buy",
|
|
1128
|
+
// "type": "limit",
|
|
1129
|
+
// "amount": "0.0010",
|
|
1130
|
+
// "price": "50000.00",
|
|
1131
|
+
// "unfilled_amount": "0.0010",
|
|
1132
|
+
// "filled_amount": "0",
|
|
1133
|
+
// "filled_value": "0",
|
|
1134
|
+
// "fee": "0",
|
|
1135
|
+
// "fee_ccy": "USDT",
|
|
1136
|
+
// "taker_fee_rate": "0.00046",
|
|
1137
|
+
// "maker_fee_rate": "0.00000000000000000000",
|
|
1138
|
+
// "client_id": "",
|
|
1139
|
+
// "last_filled_amount": "0.0010",
|
|
1140
|
+
// "last_filled_price": "30721.35",
|
|
1141
|
+
// "created_at": 1689145715129,
|
|
1142
|
+
// "updated_at": 1689145715129
|
|
1143
|
+
// }
|
|
1144
|
+
//
|
|
1145
|
+
// swap stop
|
|
1146
|
+
//
|
|
1147
|
+
// {
|
|
1148
|
+
// "stop_id": 98389557871,
|
|
1149
|
+
// "market": "BTCUSDT",
|
|
1150
|
+
// "side": "sell",
|
|
1151
|
+
// "type": "limit",
|
|
1152
|
+
// "price": "20000.00",
|
|
1153
|
+
// "amount": "0.0100",
|
|
1154
|
+
// "trigger_price": "20000.00",
|
|
1155
|
+
// "trigger_direction": "higer",
|
|
1156
|
+
// "trigger_price_type": "index_price",
|
|
1157
|
+
// "taker_fee_rate": "0.00046",
|
|
1158
|
+
// "maker_fee_rate": "0.00026",
|
|
1159
|
+
// "client_id": "",
|
|
1160
|
+
// "created_at": 1689146382674,
|
|
1161
|
+
// "updated_at": 1689146382674
|
|
1162
|
+
// }
|
|
1163
|
+
//
|
|
1164
|
+
const timestamp = this.safeInteger(order, 'created_at');
|
|
920
1165
|
const marketId = this.safeString(order, 'market');
|
|
921
|
-
const typeCode = this.safeString(order, 'type');
|
|
922
|
-
const type = this.safeString({
|
|
923
|
-
'1': 'limit',
|
|
924
|
-
'2': 'market',
|
|
925
|
-
}, typeCode);
|
|
926
|
-
const sideCode = this.safeString(order, 'side');
|
|
927
|
-
const side = this.safeString({
|
|
928
|
-
'1': 'sell',
|
|
929
|
-
'2': 'buy',
|
|
930
|
-
}, sideCode);
|
|
931
|
-
const remaining = this.safeString(order, 'left');
|
|
932
|
-
const amount = this.safeString(order, 'amount');
|
|
933
1166
|
const status = this.safeString(order, 'status');
|
|
934
|
-
const
|
|
1167
|
+
const isSpot = ('margin_market' in order);
|
|
1168
|
+
const defaultType = isSpot ? 'spot' : 'swap';
|
|
935
1169
|
market = this.safeMarket(marketId, market, undefined, defaultType);
|
|
936
|
-
let cost = this.safeString(order, 'deal_money');
|
|
937
|
-
let filled = this.safeString(order, 'deal_stock');
|
|
938
|
-
let average = undefined;
|
|
939
|
-
if (market['swap']) {
|
|
940
|
-
const leverage = this.safeString(order, 'leverage');
|
|
941
|
-
cost = Precise["default"].stringDiv(filled, leverage);
|
|
942
|
-
average = Precise["default"].stringDiv(filled, amount);
|
|
943
|
-
filled = undefined;
|
|
944
|
-
}
|
|
945
1170
|
let fee = undefined;
|
|
946
|
-
const feeCost = this.omitZero(this.
|
|
1171
|
+
const feeCost = this.omitZero(this.safeString2(order, 'fee', 'quote_ccy_fee'));
|
|
947
1172
|
if (feeCost !== undefined) {
|
|
948
|
-
const feeCurrencyId = this.safeString(order, '
|
|
1173
|
+
const feeCurrencyId = this.safeString(order, 'fee_ccy', market['quote']);
|
|
949
1174
|
fee = {
|
|
950
1175
|
'currency': this.safeCurrencyCode(feeCurrencyId),
|
|
951
1176
|
'cost': feeCost,
|
|
@@ -953,24 +1178,24 @@ class coinex extends coinex$1 {
|
|
|
953
1178
|
}
|
|
954
1179
|
return this.safeOrder({
|
|
955
1180
|
'info': order,
|
|
956
|
-
'id': this.safeString2(order, 'order_id', '
|
|
1181
|
+
'id': this.safeString2(order, 'order_id', 'stop_id'),
|
|
957
1182
|
'clientOrderId': this.safeString(order, 'client_id'),
|
|
958
1183
|
'datetime': this.iso8601(timestamp),
|
|
959
1184
|
'timestamp': timestamp,
|
|
960
|
-
'lastTradeTimestamp': this.
|
|
1185
|
+
'lastTradeTimestamp': this.safeInteger(order, 'updated_at'),
|
|
961
1186
|
'symbol': market['symbol'],
|
|
962
|
-
'type': type,
|
|
1187
|
+
'type': this.safeString(order, 'type'),
|
|
963
1188
|
'timeInForce': undefined,
|
|
964
1189
|
'postOnly': undefined,
|
|
965
|
-
'side': side,
|
|
1190
|
+
'side': this.safeString(order, 'side'),
|
|
966
1191
|
'price': this.safeString(order, 'price'),
|
|
967
|
-
'stopPrice': this.safeString(order, '
|
|
968
|
-
'triggerPrice': this.safeString(order, '
|
|
969
|
-
'amount': amount,
|
|
970
|
-
'filled':
|
|
971
|
-
'remaining':
|
|
972
|
-
'cost':
|
|
973
|
-
'average':
|
|
1192
|
+
'stopPrice': this.safeString(order, 'trigger_price'),
|
|
1193
|
+
'triggerPrice': this.safeString(order, 'trigger_price'),
|
|
1194
|
+
'amount': this.safeString(order, 'amount'),
|
|
1195
|
+
'filled': this.safeString2(order, 'filled_amount', 'fill_value'),
|
|
1196
|
+
'remaining': this.safeString2(order, 'unfilled_amount', 'unfill_amount'),
|
|
1197
|
+
'cost': undefined,
|
|
1198
|
+
'average': undefined,
|
|
974
1199
|
'status': this.parseWsOrderStatus(status),
|
|
975
1200
|
'fee': fee,
|
|
976
1201
|
'trades': undefined,
|
|
@@ -978,25 +1203,116 @@ class coinex extends coinex$1 {
|
|
|
978
1203
|
}
|
|
979
1204
|
parseWsOrderStatus(status) {
|
|
980
1205
|
const statuses = {
|
|
981
|
-
'
|
|
982
|
-
'
|
|
1206
|
+
'active_success': 'open',
|
|
1207
|
+
'active_fail': 'canceled',
|
|
1208
|
+
'cancel': 'canceled',
|
|
983
1209
|
};
|
|
984
1210
|
return this.safeString(statuses, status, status);
|
|
985
1211
|
}
|
|
1212
|
+
async watchBidsAsks(symbols = undefined, params = {}) {
|
|
1213
|
+
/**
|
|
1214
|
+
* @method
|
|
1215
|
+
* @name coinex#watchBidsAsks
|
|
1216
|
+
* @description watches best bid & ask for symbols
|
|
1217
|
+
* @see https://docs.coinex.com/api/v2/spot/market/ws/market-bbo
|
|
1218
|
+
* @see https://docs.coinex.com/api/v2/futures/market/ws/market-bbo
|
|
1219
|
+
* @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
|
|
1220
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1221
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1222
|
+
*/
|
|
1223
|
+
await this.loadMarkets();
|
|
1224
|
+
const marketIds = this.marketIds(symbols);
|
|
1225
|
+
const messageHashes = [];
|
|
1226
|
+
let market = undefined;
|
|
1227
|
+
const symbolsDefined = (symbols !== undefined);
|
|
1228
|
+
if (symbolsDefined) {
|
|
1229
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1230
|
+
const symbol = symbols[i];
|
|
1231
|
+
market = this.market(symbol);
|
|
1232
|
+
messageHashes.push('bidsasks:' + market['symbol']);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
messageHashes.push('bidsasks');
|
|
1237
|
+
}
|
|
1238
|
+
let type = undefined;
|
|
1239
|
+
[type, params] = this.handleMarketTypeAndParams('watchBidsAsks', market, params);
|
|
1240
|
+
const url = this.urls['api']['ws'][type];
|
|
1241
|
+
const subscriptionHashes = ['all@bidsasks'];
|
|
1242
|
+
const subscribe = {
|
|
1243
|
+
'method': 'bbo.subscribe',
|
|
1244
|
+
'params': { 'market_list': marketIds },
|
|
1245
|
+
'id': this.requestId(),
|
|
1246
|
+
};
|
|
1247
|
+
const result = await this.watchMultiple(url, messageHashes, this.deepExtend(subscribe, params), subscriptionHashes);
|
|
1248
|
+
if (this.newUpdates) {
|
|
1249
|
+
return result;
|
|
1250
|
+
}
|
|
1251
|
+
return this.filterByArray(this.bidsasks, 'symbol', symbols);
|
|
1252
|
+
}
|
|
1253
|
+
handleBidAsk(client, message) {
|
|
1254
|
+
//
|
|
1255
|
+
// {
|
|
1256
|
+
// "method": "bbo.update",
|
|
1257
|
+
// "data": {
|
|
1258
|
+
// "market": "BTCUSDT",
|
|
1259
|
+
// "updated_at": 1656660154,
|
|
1260
|
+
// "best_bid_price": "20000",
|
|
1261
|
+
// "best_bid_size": "0.1",
|
|
1262
|
+
// "best_ask_price": "20001",
|
|
1263
|
+
// "best_ask_size": "0.15"
|
|
1264
|
+
// },
|
|
1265
|
+
// "id": null
|
|
1266
|
+
// }
|
|
1267
|
+
//
|
|
1268
|
+
const data = this.safeDict(message, 'data', {});
|
|
1269
|
+
const parsedTicker = this.parseWsBidAsk(data);
|
|
1270
|
+
const symbol = parsedTicker['symbol'];
|
|
1271
|
+
this.bidsasks[symbol] = parsedTicker;
|
|
1272
|
+
const messageHash = 'bidsasks:' + symbol;
|
|
1273
|
+
client.resolve(parsedTicker, messageHash);
|
|
1274
|
+
}
|
|
1275
|
+
parseWsBidAsk(ticker, market = undefined) {
|
|
1276
|
+
//
|
|
1277
|
+
// {
|
|
1278
|
+
// "market": "BTCUSDT",
|
|
1279
|
+
// "updated_at": 1656660154,
|
|
1280
|
+
// "best_bid_price": "20000",
|
|
1281
|
+
// "best_bid_size": "0.1",
|
|
1282
|
+
// "best_ask_price": "20001",
|
|
1283
|
+
// "best_ask_size": "0.15"
|
|
1284
|
+
// }
|
|
1285
|
+
//
|
|
1286
|
+
const defaultType = this.safeString(this.options, 'defaultType');
|
|
1287
|
+
const marketId = this.safeString(ticker, 'market');
|
|
1288
|
+
market = this.safeMarket(marketId, market, undefined, defaultType);
|
|
1289
|
+
const timestamp = this.safeTimestamp(ticker, 'updated_at');
|
|
1290
|
+
return this.safeTicker({
|
|
1291
|
+
'symbol': this.safeSymbol(marketId, market, undefined, defaultType),
|
|
1292
|
+
'timestamp': timestamp,
|
|
1293
|
+
'datetime': this.iso8601(timestamp),
|
|
1294
|
+
'ask': this.safeNumber(ticker, 'best_ask_price'),
|
|
1295
|
+
'askVolume': this.safeNumber(ticker, 'best_ask_size'),
|
|
1296
|
+
'bid': this.safeNumber(ticker, 'best_bid_price'),
|
|
1297
|
+
'bidVolume': this.safeNumber(ticker, 'best_bid_size'),
|
|
1298
|
+
'info': ticker,
|
|
1299
|
+
}, market);
|
|
1300
|
+
}
|
|
986
1301
|
handleMessage(client, message) {
|
|
987
|
-
const
|
|
1302
|
+
const method = this.safeString(message, 'method');
|
|
1303
|
+
const error = this.safeString(message, 'message');
|
|
988
1304
|
if (error !== undefined) {
|
|
989
|
-
|
|
1305
|
+
this.handleErrors(undefined, undefined, client.url, method, undefined, this.json(error), message, undefined, undefined);
|
|
990
1306
|
}
|
|
991
|
-
const method = this.safeString(message, 'method');
|
|
992
1307
|
const handlers = {
|
|
993
1308
|
'state.update': this.handleTicker,
|
|
994
|
-
'
|
|
1309
|
+
'balance.update': this.handleBalance,
|
|
995
1310
|
'deals.update': this.handleTrades,
|
|
1311
|
+
'user_deals.update': this.handleMyTrades,
|
|
996
1312
|
'depth.update': this.handleOrderBook,
|
|
997
1313
|
'order.update': this.handleOrders,
|
|
998
|
-
'
|
|
999
|
-
'
|
|
1314
|
+
'stop.update': this.handleOrders,
|
|
1315
|
+
'bbo.update': this.handleBidAsk,
|
|
1000
1316
|
};
|
|
1001
1317
|
const handler = this.safeValue(handlers, method);
|
|
1002
1318
|
if (handler !== undefined) {
|
|
@@ -1005,35 +1321,65 @@ class coinex extends coinex$1 {
|
|
|
1005
1321
|
}
|
|
1006
1322
|
this.handleSubscriptionStatus(client, message);
|
|
1007
1323
|
}
|
|
1324
|
+
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
1325
|
+
if (response === undefined) {
|
|
1326
|
+
return undefined;
|
|
1327
|
+
}
|
|
1328
|
+
//
|
|
1329
|
+
// { "id": 1, "code": 20001, "message": "invalid argument" }
|
|
1330
|
+
// { "id": 2, "code": 21001, "message": "require auth" }
|
|
1331
|
+
// { "id": 1, "code": 21002, "message": "Signature Incorrect" }
|
|
1332
|
+
//
|
|
1333
|
+
const message = this.safeStringLower(response, 'message');
|
|
1334
|
+
const isErrorMessage = (message !== undefined) && (message !== 'ok');
|
|
1335
|
+
const errorCode = this.safeString(response, 'code');
|
|
1336
|
+
const isErrorCode = (errorCode !== undefined) && (errorCode !== '0');
|
|
1337
|
+
if (isErrorCode || isErrorMessage) {
|
|
1338
|
+
const feedback = this.id + ' ' + body;
|
|
1339
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
|
|
1340
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
1341
|
+
throw new errors.ExchangeError(feedback);
|
|
1342
|
+
}
|
|
1343
|
+
return undefined;
|
|
1344
|
+
}
|
|
1008
1345
|
handleAuthenticationMessage(client, message) {
|
|
1346
|
+
//
|
|
1347
|
+
// success
|
|
1009
1348
|
//
|
|
1010
1349
|
// {
|
|
1011
|
-
// "
|
|
1012
|
-
// "
|
|
1013
|
-
//
|
|
1014
|
-
//
|
|
1015
|
-
//
|
|
1350
|
+
// "id": 1,
|
|
1351
|
+
// "code": 0,
|
|
1352
|
+
// "message": "OK"
|
|
1353
|
+
// }
|
|
1354
|
+
//
|
|
1355
|
+
// fail
|
|
1356
|
+
//
|
|
1357
|
+
// {
|
|
1358
|
+
// "id": 1,
|
|
1359
|
+
// "code": 21002,
|
|
1360
|
+
// "message": ""
|
|
1016
1361
|
// }
|
|
1017
1362
|
//
|
|
1018
|
-
const
|
|
1019
|
-
const
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1363
|
+
const status = this.safeStringLower(message, 'message');
|
|
1364
|
+
const errorCode = this.safeString(message, 'code');
|
|
1365
|
+
const messageHash = 'authenticated';
|
|
1366
|
+
if ((status === 'ok') || (errorCode === '0')) {
|
|
1367
|
+
const future = this.safeValue(client.futures, messageHash);
|
|
1368
|
+
future.resolve(true);
|
|
1369
|
+
}
|
|
1370
|
+
else {
|
|
1371
|
+
const error = new errors.AuthenticationError(this.json(message));
|
|
1372
|
+
client.reject(error, messageHash);
|
|
1373
|
+
if (messageHash in client.subscriptions) {
|
|
1374
|
+
delete client.subscriptions[messageHash];
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1027
1377
|
}
|
|
1028
1378
|
handleSubscriptionStatus(client, message) {
|
|
1029
1379
|
const id = this.safeInteger(message, 'id');
|
|
1030
1380
|
const subscription = this.safeValue(client.subscriptions, id);
|
|
1031
1381
|
if (subscription !== undefined) {
|
|
1032
1382
|
const futureIndex = this.safeString(subscription, 'future');
|
|
1033
|
-
if (futureIndex === 'ohlcv') {
|
|
1034
|
-
this.handleOHLCV(client, message);
|
|
1035
|
-
return;
|
|
1036
|
-
}
|
|
1037
1383
|
const future = this.safeValue(client.futures, futureIndex);
|
|
1038
1384
|
if (future !== undefined) {
|
|
1039
1385
|
future.resolve(true);
|
|
@@ -1041,66 +1387,35 @@ class coinex extends coinex$1 {
|
|
|
1041
1387
|
delete client.subscriptions[id];
|
|
1042
1388
|
}
|
|
1043
1389
|
}
|
|
1044
|
-
async authenticate(
|
|
1045
|
-
let type = undefined;
|
|
1046
|
-
[type, params] = this.handleMarketTypeAndParams('authenticate', undefined, params);
|
|
1390
|
+
async authenticate(type) {
|
|
1047
1391
|
const url = this.urls['api']['ws'][type];
|
|
1048
1392
|
const client = this.client(url);
|
|
1049
1393
|
const time = this.milliseconds();
|
|
1050
|
-
const
|
|
1051
|
-
const
|
|
1052
|
-
const swapMessageHash = 'authenticated:swap';
|
|
1053
|
-
const messageHash = isSpot ? spotMessageHash : swapMessageHash;
|
|
1394
|
+
const timestamp = time.toString();
|
|
1395
|
+
const messageHash = 'authenticated';
|
|
1054
1396
|
const future = client.future(messageHash);
|
|
1055
1397
|
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
1056
|
-
if (
|
|
1057
|
-
if (authenticated !== undefined) {
|
|
1058
|
-
return await future;
|
|
1059
|
-
}
|
|
1060
|
-
const requestId = this.requestId();
|
|
1061
|
-
const subscribe = {
|
|
1062
|
-
'id': requestId,
|
|
1063
|
-
'future': spotMessageHash,
|
|
1064
|
-
};
|
|
1065
|
-
const signData = 'access_id=' + this.apiKey + '&tonce=' + this.numberToString(time) + '&secret_key=' + this.secret;
|
|
1066
|
-
const hash = this.hash(this.encode(signData), md5.md5);
|
|
1067
|
-
const request = {
|
|
1068
|
-
'method': 'server.sign',
|
|
1069
|
-
'params': [
|
|
1070
|
-
this.apiKey,
|
|
1071
|
-
hash.toUpperCase(),
|
|
1072
|
-
time,
|
|
1073
|
-
],
|
|
1074
|
-
'id': requestId,
|
|
1075
|
-
};
|
|
1076
|
-
this.watch(url, messageHash, request, requestId, subscribe);
|
|
1077
|
-
client.subscriptions[messageHash] = true;
|
|
1078
|
-
return await future;
|
|
1079
|
-
}
|
|
1080
|
-
else {
|
|
1081
|
-
if (authenticated !== undefined) {
|
|
1082
|
-
return await future;
|
|
1083
|
-
}
|
|
1084
|
-
const requestId = this.requestId();
|
|
1085
|
-
const subscribe = {
|
|
1086
|
-
'id': requestId,
|
|
1087
|
-
'future': swapMessageHash,
|
|
1088
|
-
};
|
|
1089
|
-
const signData = 'access_id=' + this.apiKey + '×tamp=' + this.numberToString(time) + '&secret_key=' + this.secret;
|
|
1090
|
-
const hash = this.hash(this.encode(signData), sha256.sha256, 'hex');
|
|
1091
|
-
const request = {
|
|
1092
|
-
'method': 'server.sign',
|
|
1093
|
-
'params': [
|
|
1094
|
-
this.apiKey,
|
|
1095
|
-
hash.toLowerCase(),
|
|
1096
|
-
time,
|
|
1097
|
-
],
|
|
1098
|
-
'id': requestId,
|
|
1099
|
-
};
|
|
1100
|
-
this.watch(url, messageHash, request, requestId, subscribe);
|
|
1101
|
-
client.subscriptions[messageHash] = true;
|
|
1398
|
+
if (authenticated !== undefined) {
|
|
1102
1399
|
return await future;
|
|
1103
1400
|
}
|
|
1401
|
+
const requestId = this.requestId();
|
|
1402
|
+
const subscribe = {
|
|
1403
|
+
'id': requestId,
|
|
1404
|
+
'future': messageHash,
|
|
1405
|
+
};
|
|
1406
|
+
const hmac = this.hmac(this.encode(timestamp), this.encode(this.secret), sha256.sha256, 'hex');
|
|
1407
|
+
const request = {
|
|
1408
|
+
'id': requestId,
|
|
1409
|
+
'method': 'server.sign',
|
|
1410
|
+
'params': {
|
|
1411
|
+
'access_id': this.apiKey,
|
|
1412
|
+
'signed_str': hmac.toLowerCase(),
|
|
1413
|
+
'timestamp': time,
|
|
1414
|
+
},
|
|
1415
|
+
};
|
|
1416
|
+
this.watch(url, messageHash, request, requestId, subscribe);
|
|
1417
|
+
client.subscriptions[messageHash] = true;
|
|
1418
|
+
return await future;
|
|
1104
1419
|
}
|
|
1105
1420
|
}
|
|
1106
1421
|
|