ccxt 4.5.10 → 4.5.11
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 +5 -6
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -6
- package/dist/cjs/src/base/Exchange.js +14 -2
- package/dist/cjs/src/bingx.js +1 -1
- package/dist/cjs/src/bitfinex.js +4 -2
- package/dist/cjs/src/bitget.js +5 -2
- package/dist/cjs/src/btcmarkets.js +4 -2
- package/dist/cjs/src/coinbase.js +1 -0
- package/dist/cjs/src/deribit.js +21 -19
- package/dist/cjs/src/kraken.js +4 -0
- package/dist/cjs/src/kucoin.js +1 -1
- package/dist/cjs/src/latoken.js +1 -0
- package/dist/cjs/src/mexc.js +1 -0
- package/dist/cjs/src/onetrading.js +2 -1
- package/dist/cjs/src/phemex.js +1 -0
- package/dist/cjs/src/pro/bitget.js +1 -0
- package/dist/cjs/src/pro/htx.js +22 -3
- package/dist/cjs/src/pro/kraken.js +282 -458
- package/dist/cjs/src/pro/mexc.js +15 -10
- package/dist/cjs/src/probit.js +1 -1
- package/js/ccxt.d.ts +2 -8
- package/js/ccxt.js +2 -6
- package/js/src/abstract/coinbase.d.ts +1 -0
- package/js/src/abstract/coinbaseadvanced.d.ts +1 -0
- package/js/src/abstract/phemex.d.ts +1 -0
- package/js/src/base/Exchange.d.ts +5 -2
- package/js/src/base/Exchange.js +14 -2
- package/js/src/bingx.js +1 -1
- package/js/src/bitfinex.d.ts +1 -1
- package/js/src/bitfinex.js +4 -2
- package/js/src/bitget.d.ts +1 -1
- package/js/src/bitget.js +5 -2
- package/js/src/bithumb.d.ts +1 -1
- package/js/src/bitmex.d.ts +1 -1
- package/js/src/bitopro.d.ts +1 -1
- package/js/src/bitso.d.ts +1 -1
- package/js/src/bittrade.d.ts +1 -1
- package/js/src/blofin.d.ts +1 -1
- package/js/src/btcmarkets.d.ts +1 -1
- package/js/src/btcmarkets.js +4 -2
- package/js/src/bybit.d.ts +1 -1
- package/js/src/coinbase.d.ts +1 -1
- package/js/src/coinbase.js +1 -0
- package/js/src/coinex.d.ts +1 -1
- package/js/src/cryptocom.d.ts +1 -1
- package/js/src/deribit.js +21 -19
- package/js/src/digifinex.d.ts +1 -1
- package/js/src/hibachi.d.ts +1 -1
- package/js/src/htx.d.ts +1 -1
- package/js/src/hyperliquid.d.ts +1 -1
- package/js/src/kraken.d.ts +1 -1
- package/js/src/kraken.js +4 -0
- package/js/src/kucoin.js +1 -1
- package/js/src/kucoinfutures.d.ts +1 -1
- package/js/src/latoken.js +1 -0
- package/js/src/mexc.d.ts +1 -1
- package/js/src/mexc.js +1 -0
- package/js/src/oceanex.d.ts +1 -1
- package/js/src/okx.d.ts +1 -1
- package/js/src/onetrading.d.ts +1 -1
- package/js/src/onetrading.js +2 -1
- package/js/src/phemex.js +1 -0
- package/js/src/pro/bitget.d.ts +1 -0
- package/js/src/pro/bitget.js +1 -0
- package/js/src/pro/bitvavo.d.ts +2 -2
- package/js/src/pro/htx.js +22 -3
- package/js/src/pro/kraken.d.ts +7 -8
- package/js/src/pro/kraken.js +282 -458
- package/js/src/pro/mexc.js +15 -10
- package/js/src/probit.js +1 -1
- package/js/src/timex.d.ts +1 -1
- package/package.json +1 -1
- package/js/src/abstract/okcoin.d.ts +0 -77
- package/js/src/abstract/okcoin.js +0 -11
- package/js/src/okcoin.d.ts +0 -346
- package/js/src/okcoin.js +0 -3214
- package/js/src/pro/okcoin.d.ts +0 -91
- package/js/src/pro/okcoin.js +0 -763
package/js/src/okcoin.js
DELETED
|
@@ -1,3214 +0,0 @@
|
|
|
1
|
-
// ----------------------------------------------------------------------------
|
|
2
|
-
|
|
3
|
-
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
4
|
-
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
5
|
-
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
|
6
|
-
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
import Exchange from './abstract/okcoin.js';
|
|
9
|
-
import { ExchangeError, ExchangeNotAvailable, OnMaintenance, ArgumentsRequired, BadRequest, AccountSuspended, InvalidAddress, PermissionDenied, NetworkError, InsufficientFunds, InvalidNonce, CancelPending, InvalidOrder, OrderNotFound, AuthenticationError, RequestTimeout, AccountNotEnabled, BadSymbol, RateLimitExceeded, NotSupported } from './base/errors.js';
|
|
10
|
-
import { Precise } from './base/Precise.js';
|
|
11
|
-
import { TICK_SIZE } from './base/functions/number.js';
|
|
12
|
-
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
/**
|
|
15
|
-
* @class okcoin
|
|
16
|
-
* @augments Exchange
|
|
17
|
-
*/
|
|
18
|
-
export default class okcoin extends Exchange {
|
|
19
|
-
describe() {
|
|
20
|
-
return this.deepExtend(super.describe(), {
|
|
21
|
-
'id': 'okcoin',
|
|
22
|
-
'name': 'OKCoin',
|
|
23
|
-
'countries': ['CN', 'US'],
|
|
24
|
-
'version': 'v5',
|
|
25
|
-
// cheapest endpoint is 100 requests per 2 seconds
|
|
26
|
-
// 50 requests per second => 1000 / 50 = 20ms
|
|
27
|
-
'rateLimit': 20,
|
|
28
|
-
'pro': true,
|
|
29
|
-
'has': {
|
|
30
|
-
'CORS': undefined,
|
|
31
|
-
'spot': true,
|
|
32
|
-
'margin': false,
|
|
33
|
-
'swap': false,
|
|
34
|
-
'future': true,
|
|
35
|
-
'option': undefined,
|
|
36
|
-
'cancelOrder': true,
|
|
37
|
-
'createMarketBuyOrderWithCost': true,
|
|
38
|
-
'createMarketOrderWithCost': false,
|
|
39
|
-
'createMarketSellOrderWithCost': false,
|
|
40
|
-
'createOrder': true,
|
|
41
|
-
'createPostOnlyOrder': true,
|
|
42
|
-
'createReduceOnlyOrder': true,
|
|
43
|
-
'createStopLimitOrder': true,
|
|
44
|
-
'createStopMarketOrder': true,
|
|
45
|
-
'createStopOrder': true,
|
|
46
|
-
'createTriggerOrder': true,
|
|
47
|
-
'fetchBalance': true,
|
|
48
|
-
'fetchBorrowInterest': false,
|
|
49
|
-
'fetchBorrowRate': false,
|
|
50
|
-
'fetchBorrowRateHistories': false,
|
|
51
|
-
'fetchBorrowRateHistory': false,
|
|
52
|
-
'fetchBorrowRates': false,
|
|
53
|
-
'fetchBorrowRatesPerSymbol': false,
|
|
54
|
-
'fetchClosedOrders': true,
|
|
55
|
-
'fetchCurrencies': true,
|
|
56
|
-
'fetchDepositAddress': true,
|
|
57
|
-
'fetchDepositAddresses': false,
|
|
58
|
-
'fetchDepositAddressesByNetwork': false,
|
|
59
|
-
'fetchDeposits': true,
|
|
60
|
-
'fetchFundingHistory': false,
|
|
61
|
-
'fetchFundingRate': false,
|
|
62
|
-
'fetchFundingRateHistory': false,
|
|
63
|
-
'fetchFundingRates': false,
|
|
64
|
-
'fetchLedger': true,
|
|
65
|
-
'fetchMarkets': true,
|
|
66
|
-
'fetchMyTrades': true,
|
|
67
|
-
'fetchOHLCV': true,
|
|
68
|
-
'fetchOpenOrders': true,
|
|
69
|
-
'fetchOrder': true,
|
|
70
|
-
'fetchOrderBook': true,
|
|
71
|
-
'fetchOrders': undefined,
|
|
72
|
-
'fetchOrderTrades': true,
|
|
73
|
-
'fetchPosition': false,
|
|
74
|
-
'fetchPositions': false,
|
|
75
|
-
'fetchTicker': true,
|
|
76
|
-
'fetchTickers': true,
|
|
77
|
-
'fetchTime': true,
|
|
78
|
-
'fetchTrades': true,
|
|
79
|
-
'fetchTransactions': undefined,
|
|
80
|
-
'fetchWithdrawals': true,
|
|
81
|
-
'reduceMargin': false,
|
|
82
|
-
'repayCrossMargin': false,
|
|
83
|
-
'repayIsolatedMargin': false,
|
|
84
|
-
'setMargin': false,
|
|
85
|
-
'transfer': true,
|
|
86
|
-
'withdraw': true,
|
|
87
|
-
},
|
|
88
|
-
'timeframes': {
|
|
89
|
-
'1m': '1m',
|
|
90
|
-
'3m': '3m',
|
|
91
|
-
'5m': '5m',
|
|
92
|
-
'15m': '15m',
|
|
93
|
-
'30m': '30m',
|
|
94
|
-
'1h': '1H',
|
|
95
|
-
'2h': '2H',
|
|
96
|
-
'4h': '4H',
|
|
97
|
-
'6h': '6H',
|
|
98
|
-
'12h': '12H',
|
|
99
|
-
'1d': '1D',
|
|
100
|
-
'1w': '1W',
|
|
101
|
-
'1M': '1M',
|
|
102
|
-
'3M': '3M',
|
|
103
|
-
},
|
|
104
|
-
'hostname': 'okcoin.com',
|
|
105
|
-
'urls': {
|
|
106
|
-
'logo': 'https://user-images.githubusercontent.com/51840849/87295551-102fbf00-c50e-11ea-90a9-462eebba5829.jpg',
|
|
107
|
-
'api': {
|
|
108
|
-
'rest': 'https://www.{hostname}',
|
|
109
|
-
},
|
|
110
|
-
'www': 'https://www.okcoin.com',
|
|
111
|
-
'doc': 'https://www.okcoin.com/docs/en/',
|
|
112
|
-
'fees': 'https://www.okcoin.com/coin-fees',
|
|
113
|
-
'referral': 'https://www.okcoin.com/account/register?flag=activity&channelId=600001513',
|
|
114
|
-
'test': {
|
|
115
|
-
'rest': 'https://testnet.okex.com',
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
'api': {
|
|
119
|
-
'public': {
|
|
120
|
-
'get': {
|
|
121
|
-
'market/tickers': 1,
|
|
122
|
-
'market/ticker': 1,
|
|
123
|
-
'market/books': 1 / 2,
|
|
124
|
-
'market/candles': 1 / 2,
|
|
125
|
-
'market/history-candles': 1 / 2,
|
|
126
|
-
'market/trades': 1 / 5,
|
|
127
|
-
'market/history-trades': 2,
|
|
128
|
-
'market/platform-24-volume': 10,
|
|
129
|
-
'market/open-oracle': 50,
|
|
130
|
-
'market/exchange-rate': 20,
|
|
131
|
-
'public/instruments': 1,
|
|
132
|
-
'public/time': 2,
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
'private': {
|
|
136
|
-
'get': {
|
|
137
|
-
// trade
|
|
138
|
-
'trade/order': 1 / 3,
|
|
139
|
-
'trade/orders-pending': 1 / 3,
|
|
140
|
-
'trade/orders-history': 1 / 2,
|
|
141
|
-
'trade/orders-history-archive': 1 / 2,
|
|
142
|
-
'trade/fills': 1 / 3,
|
|
143
|
-
'trade/fills-history': 2.2,
|
|
144
|
-
'trade/fills-archive': 2,
|
|
145
|
-
'trade/order-algo': 1,
|
|
146
|
-
'trade/orders-algo-pending': 1,
|
|
147
|
-
'trade/orders-algo-history': 1,
|
|
148
|
-
// rfq
|
|
149
|
-
'otc/rfq/trade': 4,
|
|
150
|
-
'otc/rfq/history': 4,
|
|
151
|
-
// account
|
|
152
|
-
'account/balance': 2,
|
|
153
|
-
'account/bills': 5 / 3,
|
|
154
|
-
'account/bills-archive': 5 / 3,
|
|
155
|
-
'account/config': 4,
|
|
156
|
-
'account/max-size': 4,
|
|
157
|
-
'account/max-avail-size': 4,
|
|
158
|
-
'account/trade-fee': 4,
|
|
159
|
-
'account/max-withdrawal': 4,
|
|
160
|
-
// funding or assets
|
|
161
|
-
'asset/currencies': 5 / 3,
|
|
162
|
-
'asset/balances': 5 / 3,
|
|
163
|
-
'asset/asset-valuation': 10,
|
|
164
|
-
'asset/transfer-state': 10,
|
|
165
|
-
'asset/bills': 5 / 3,
|
|
166
|
-
'asset/deposit-lightning': 5,
|
|
167
|
-
'asset/deposit-address': 5 / 3,
|
|
168
|
-
'asset/deposit-history': 5 / 3,
|
|
169
|
-
'asset/withdrawal-history': 5 / 3,
|
|
170
|
-
'asset/deposit-withdraw-status': 20,
|
|
171
|
-
// fiat
|
|
172
|
-
'fiat/deposit-history': 5 / 3,
|
|
173
|
-
'fiat-withdraw-history': 5 / 3,
|
|
174
|
-
'fiat-channel': 5 / 3,
|
|
175
|
-
// sub-account
|
|
176
|
-
'users/subaccount/list': 10,
|
|
177
|
-
'users/subaccount/apiKey': 10,
|
|
178
|
-
'account/subaccount/balances': 10,
|
|
179
|
-
'asset/subaccount/balances': 10,
|
|
180
|
-
'asset/subaccount/bills': 10,
|
|
181
|
-
},
|
|
182
|
-
'post': {
|
|
183
|
-
// trade
|
|
184
|
-
'trade/order': 1 / 3,
|
|
185
|
-
'trade/batch-orders': 1 / 15,
|
|
186
|
-
'trade/cancel-order': 1 / 3,
|
|
187
|
-
'trade/cancel-batch-orders': 1 / 15,
|
|
188
|
-
'trade/amend-order': 1 / 3,
|
|
189
|
-
'trade/amend-batch-orders': 1 / 150,
|
|
190
|
-
'trade/order-algo': 1,
|
|
191
|
-
'trade/cancel-algos': 1,
|
|
192
|
-
'trade/cancel-advance-algos': 1,
|
|
193
|
-
// rfq
|
|
194
|
-
'otc/rfq/quote': 4,
|
|
195
|
-
'otc/rfq/trade': 4,
|
|
196
|
-
// funding
|
|
197
|
-
'asset/transfer': 4,
|
|
198
|
-
'asset/withdrawal': 4,
|
|
199
|
-
'asset/withdrawal-lightning': 4,
|
|
200
|
-
'asset/withdrawal-cancel': 4,
|
|
201
|
-
// fiat
|
|
202
|
-
'fiat/deposit': 5 / 3,
|
|
203
|
-
'fiat/cancel-deposit': 5 / 3,
|
|
204
|
-
'fiat/withdrawal': 5 / 3,
|
|
205
|
-
'fiat/cancel-withdrawal': 5 / 3,
|
|
206
|
-
// sub-account
|
|
207
|
-
'asset/subaccount/transfer': 10,
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
'features': {
|
|
212
|
-
'spot': {
|
|
213
|
-
'sandbox': false,
|
|
214
|
-
'fetchCurrencies': {
|
|
215
|
-
'private': true,
|
|
216
|
-
},
|
|
217
|
-
'createOrder': {
|
|
218
|
-
'marginMode': true,
|
|
219
|
-
'triggerPrice': true,
|
|
220
|
-
'triggerDirection': true,
|
|
221
|
-
'triggerPriceType': {
|
|
222
|
-
'last': true,
|
|
223
|
-
'mark': false,
|
|
224
|
-
'index': false,
|
|
225
|
-
},
|
|
226
|
-
'stopLossPrice': true,
|
|
227
|
-
'takeProfitPrice': true,
|
|
228
|
-
'attachedStopLossTakeProfit': {
|
|
229
|
-
'triggerPriceType': {
|
|
230
|
-
'last': true,
|
|
231
|
-
'mark': false,
|
|
232
|
-
'index': false,
|
|
233
|
-
},
|
|
234
|
-
'price': true,
|
|
235
|
-
},
|
|
236
|
-
'timeInForce': {
|
|
237
|
-
'IOC': true,
|
|
238
|
-
'FOK': true,
|
|
239
|
-
'PO': true,
|
|
240
|
-
'GTD': false,
|
|
241
|
-
},
|
|
242
|
-
'hedged': false,
|
|
243
|
-
'trailing': true,
|
|
244
|
-
'leverage': false,
|
|
245
|
-
'marketBuyByCost': true,
|
|
246
|
-
'marketBuyRequiresPrice': true,
|
|
247
|
-
'selfTradePrevention': false,
|
|
248
|
-
'iceberg': true, // todo
|
|
249
|
-
},
|
|
250
|
-
'createOrders': undefined,
|
|
251
|
-
'fetchMyTrades': {
|
|
252
|
-
'marginMode': false,
|
|
253
|
-
'limit': 100,
|
|
254
|
-
'daysBack': 90,
|
|
255
|
-
'untilDays': 90,
|
|
256
|
-
'symbolRequired': false,
|
|
257
|
-
},
|
|
258
|
-
'fetchOrder': {
|
|
259
|
-
'marginMode': false,
|
|
260
|
-
'trigger': true,
|
|
261
|
-
'trailing': true,
|
|
262
|
-
'symbolRequired': true,
|
|
263
|
-
},
|
|
264
|
-
'fetchOpenOrders': {
|
|
265
|
-
'marginMode': false,
|
|
266
|
-
'limit': 100,
|
|
267
|
-
'trigger': true,
|
|
268
|
-
'trailing': true,
|
|
269
|
-
'symbolRequired': false,
|
|
270
|
-
},
|
|
271
|
-
'fetchOrders': undefined,
|
|
272
|
-
'fetchClosedOrders': {
|
|
273
|
-
'marginMode': false,
|
|
274
|
-
'limit': 100,
|
|
275
|
-
'daysBack': 90,
|
|
276
|
-
'daysBackCanceled': 1 / 12,
|
|
277
|
-
'untilDays': 90,
|
|
278
|
-
'trigger': true,
|
|
279
|
-
'trailing': true,
|
|
280
|
-
'symbolRequired': false,
|
|
281
|
-
},
|
|
282
|
-
'fetchOHLCV': {
|
|
283
|
-
'limit': 100, // 300 is only possible for 'recent' 1440 candles, which does not make much sense
|
|
284
|
-
},
|
|
285
|
-
},
|
|
286
|
-
'swap': {
|
|
287
|
-
'linear': undefined,
|
|
288
|
-
'inverse': undefined,
|
|
289
|
-
},
|
|
290
|
-
'future': {
|
|
291
|
-
'linear': undefined,
|
|
292
|
-
'inverse': undefined,
|
|
293
|
-
},
|
|
294
|
-
},
|
|
295
|
-
'fees': {
|
|
296
|
-
'trading': {
|
|
297
|
-
'taker': 0.002,
|
|
298
|
-
'maker': 0.001,
|
|
299
|
-
},
|
|
300
|
-
'spot': {
|
|
301
|
-
'taker': 0.0015,
|
|
302
|
-
'maker': 0.0010,
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
|
-
'requiredCredentials': {
|
|
306
|
-
'apiKey': true,
|
|
307
|
-
'secret': true,
|
|
308
|
-
'password': true,
|
|
309
|
-
},
|
|
310
|
-
'exceptions': {
|
|
311
|
-
'exact': {
|
|
312
|
-
// Public error codes from 50000-53999
|
|
313
|
-
// General Class
|
|
314
|
-
'1': ExchangeError,
|
|
315
|
-
'2': ExchangeError,
|
|
316
|
-
'50000': BadRequest,
|
|
317
|
-
'50001': OnMaintenance,
|
|
318
|
-
'50002': BadRequest,
|
|
319
|
-
'50004': RequestTimeout,
|
|
320
|
-
'50005': ExchangeNotAvailable,
|
|
321
|
-
'50006': BadRequest,
|
|
322
|
-
'50007': AccountSuspended,
|
|
323
|
-
'50008': AuthenticationError,
|
|
324
|
-
'50009': AccountSuspended,
|
|
325
|
-
'50010': ExchangeError,
|
|
326
|
-
'50011': RateLimitExceeded,
|
|
327
|
-
'50012': ExchangeError,
|
|
328
|
-
'50013': ExchangeNotAvailable,
|
|
329
|
-
'50014': BadRequest,
|
|
330
|
-
'50015': ExchangeError,
|
|
331
|
-
'50016': ExchangeError,
|
|
332
|
-
'50017': ExchangeError,
|
|
333
|
-
'50018': ExchangeError,
|
|
334
|
-
'50019': ExchangeError,
|
|
335
|
-
'50020': ExchangeError,
|
|
336
|
-
'50021': ExchangeError,
|
|
337
|
-
'50022': ExchangeError,
|
|
338
|
-
'50023': ExchangeError,
|
|
339
|
-
'50024': BadRequest,
|
|
340
|
-
'50025': ExchangeError,
|
|
341
|
-
'50026': ExchangeNotAvailable,
|
|
342
|
-
'50027': PermissionDenied,
|
|
343
|
-
'50028': ExchangeError,
|
|
344
|
-
'50029': ExchangeError,
|
|
345
|
-
'50030': PermissionDenied,
|
|
346
|
-
'50032': AccountSuspended,
|
|
347
|
-
'50033': AccountSuspended,
|
|
348
|
-
'50035': BadRequest,
|
|
349
|
-
'50036': BadRequest,
|
|
350
|
-
'50037': BadRequest,
|
|
351
|
-
'50038': ExchangeError,
|
|
352
|
-
'50039': ExchangeError,
|
|
353
|
-
'50041': ExchangeError,
|
|
354
|
-
'50044': BadRequest,
|
|
355
|
-
// API Class
|
|
356
|
-
'50100': ExchangeError,
|
|
357
|
-
'50101': AuthenticationError,
|
|
358
|
-
'50102': InvalidNonce,
|
|
359
|
-
'50103': AuthenticationError,
|
|
360
|
-
'50104': AuthenticationError,
|
|
361
|
-
'50105': AuthenticationError,
|
|
362
|
-
'50106': AuthenticationError,
|
|
363
|
-
'50107': AuthenticationError,
|
|
364
|
-
'50108': ExchangeError,
|
|
365
|
-
'50109': ExchangeError,
|
|
366
|
-
'50110': PermissionDenied,
|
|
367
|
-
'50111': AuthenticationError,
|
|
368
|
-
'50112': AuthenticationError,
|
|
369
|
-
'50113': AuthenticationError,
|
|
370
|
-
'50114': AuthenticationError,
|
|
371
|
-
'50115': BadRequest,
|
|
372
|
-
// Trade Class
|
|
373
|
-
'51000': BadRequest,
|
|
374
|
-
'51001': BadSymbol,
|
|
375
|
-
'51002': BadSymbol,
|
|
376
|
-
'51003': BadRequest,
|
|
377
|
-
'51004': InvalidOrder,
|
|
378
|
-
'51005': InvalidOrder,
|
|
379
|
-
'51006': InvalidOrder,
|
|
380
|
-
'51007': InvalidOrder,
|
|
381
|
-
'51008': InsufficientFunds,
|
|
382
|
-
'51009': AccountSuspended,
|
|
383
|
-
'51010': AccountNotEnabled,
|
|
384
|
-
'51011': InvalidOrder,
|
|
385
|
-
'51012': BadSymbol,
|
|
386
|
-
'51014': BadSymbol,
|
|
387
|
-
'51015': BadSymbol,
|
|
388
|
-
'51016': InvalidOrder,
|
|
389
|
-
'51017': ExchangeError,
|
|
390
|
-
'51018': ExchangeError,
|
|
391
|
-
'51019': ExchangeError,
|
|
392
|
-
'51020': InvalidOrder,
|
|
393
|
-
'51023': ExchangeError,
|
|
394
|
-
'51024': AccountSuspended,
|
|
395
|
-
'51025': ExchangeError,
|
|
396
|
-
'51026': BadSymbol,
|
|
397
|
-
'51030': InvalidOrder,
|
|
398
|
-
'51031': InvalidOrder,
|
|
399
|
-
'51032': InvalidOrder,
|
|
400
|
-
'51033': InvalidOrder,
|
|
401
|
-
'51037': InvalidOrder,
|
|
402
|
-
'51038': InvalidOrder,
|
|
403
|
-
'51044': InvalidOrder,
|
|
404
|
-
'51046': InvalidOrder,
|
|
405
|
-
'51047': InvalidOrder,
|
|
406
|
-
'51048': InvalidOrder,
|
|
407
|
-
'51049': InvalidOrder,
|
|
408
|
-
'51050': InvalidOrder,
|
|
409
|
-
'51051': InvalidOrder,
|
|
410
|
-
'51052': InvalidOrder,
|
|
411
|
-
'51053': InvalidOrder,
|
|
412
|
-
'51054': BadRequest,
|
|
413
|
-
'51056': InvalidOrder,
|
|
414
|
-
'51058': InvalidOrder,
|
|
415
|
-
'51059': InvalidOrder,
|
|
416
|
-
'51100': InvalidOrder,
|
|
417
|
-
'51102': InvalidOrder,
|
|
418
|
-
'51103': InvalidOrder,
|
|
419
|
-
'51108': InvalidOrder,
|
|
420
|
-
'51109': InvalidOrder,
|
|
421
|
-
'51110': InvalidOrder,
|
|
422
|
-
'51111': BadRequest,
|
|
423
|
-
'51112': InvalidOrder,
|
|
424
|
-
'51113': RateLimitExceeded,
|
|
425
|
-
'51115': InvalidOrder,
|
|
426
|
-
'51116': InvalidOrder,
|
|
427
|
-
'51117': InvalidOrder,
|
|
428
|
-
'51118': InvalidOrder,
|
|
429
|
-
'51119': InsufficientFunds,
|
|
430
|
-
'51120': InvalidOrder,
|
|
431
|
-
'51121': InvalidOrder,
|
|
432
|
-
'51122': InvalidOrder,
|
|
433
|
-
'51124': InvalidOrder,
|
|
434
|
-
'51125': InvalidOrder,
|
|
435
|
-
'51126': InvalidOrder,
|
|
436
|
-
'51127': InsufficientFunds,
|
|
437
|
-
'51128': InvalidOrder,
|
|
438
|
-
'51129': InvalidOrder,
|
|
439
|
-
'51130': BadSymbol,
|
|
440
|
-
'51131': InsufficientFunds,
|
|
441
|
-
'51132': InvalidOrder,
|
|
442
|
-
'51133': InvalidOrder,
|
|
443
|
-
'51134': InvalidOrder,
|
|
444
|
-
'51135': InvalidOrder,
|
|
445
|
-
'51136': InvalidOrder,
|
|
446
|
-
'51137': InvalidOrder,
|
|
447
|
-
'51138': InvalidOrder,
|
|
448
|
-
'51139': InvalidOrder,
|
|
449
|
-
'51156': BadRequest,
|
|
450
|
-
'51159': BadRequest,
|
|
451
|
-
'51162': InvalidOrder,
|
|
452
|
-
'51163': InvalidOrder,
|
|
453
|
-
'51166': InvalidOrder,
|
|
454
|
-
'51174': InvalidOrder,
|
|
455
|
-
'51201': InvalidOrder,
|
|
456
|
-
'51202': InvalidOrder,
|
|
457
|
-
'51203': InvalidOrder,
|
|
458
|
-
'51204': InvalidOrder,
|
|
459
|
-
'51205': InvalidOrder,
|
|
460
|
-
'51250': InvalidOrder,
|
|
461
|
-
'51251': InvalidOrder,
|
|
462
|
-
'51252': InvalidOrder,
|
|
463
|
-
'51253': InvalidOrder,
|
|
464
|
-
'51254': InvalidOrder,
|
|
465
|
-
'51255': InvalidOrder,
|
|
466
|
-
'51256': InvalidOrder,
|
|
467
|
-
'51257': InvalidOrder,
|
|
468
|
-
'51258': InvalidOrder,
|
|
469
|
-
'51259': InvalidOrder,
|
|
470
|
-
'51260': InvalidOrder,
|
|
471
|
-
'51261': InvalidOrder,
|
|
472
|
-
'51262': InvalidOrder,
|
|
473
|
-
'51263': InvalidOrder,
|
|
474
|
-
'51264': InvalidOrder,
|
|
475
|
-
'51265': InvalidOrder,
|
|
476
|
-
'51267': InvalidOrder,
|
|
477
|
-
'51268': InvalidOrder,
|
|
478
|
-
'51269': InvalidOrder,
|
|
479
|
-
'51270': InvalidOrder,
|
|
480
|
-
'51271': InvalidOrder,
|
|
481
|
-
'51272': InvalidOrder,
|
|
482
|
-
'51273': InvalidOrder,
|
|
483
|
-
'51274': InvalidOrder,
|
|
484
|
-
'51275': InvalidOrder,
|
|
485
|
-
'51276': InvalidOrder,
|
|
486
|
-
'51277': InvalidOrder,
|
|
487
|
-
'51278': InvalidOrder,
|
|
488
|
-
'51279': InvalidOrder,
|
|
489
|
-
'51280': InvalidOrder,
|
|
490
|
-
'51321': InvalidOrder,
|
|
491
|
-
'51322': InvalidOrder,
|
|
492
|
-
'51323': BadRequest,
|
|
493
|
-
'51324': BadRequest,
|
|
494
|
-
'51325': InvalidOrder,
|
|
495
|
-
'51327': InvalidOrder,
|
|
496
|
-
'51328': InvalidOrder,
|
|
497
|
-
'51329': InvalidOrder,
|
|
498
|
-
'51330': InvalidOrder,
|
|
499
|
-
'51400': OrderNotFound,
|
|
500
|
-
'51401': OrderNotFound,
|
|
501
|
-
'51402': OrderNotFound,
|
|
502
|
-
'51403': InvalidOrder,
|
|
503
|
-
'51404': InvalidOrder,
|
|
504
|
-
'51405': ExchangeError,
|
|
505
|
-
'51406': ExchangeError,
|
|
506
|
-
'51407': BadRequest,
|
|
507
|
-
'51408': ExchangeError,
|
|
508
|
-
'51409': ExchangeError,
|
|
509
|
-
'51410': CancelPending,
|
|
510
|
-
'51500': ExchangeError,
|
|
511
|
-
'51501': ExchangeError,
|
|
512
|
-
'51502': InsufficientFunds,
|
|
513
|
-
'51503': ExchangeError,
|
|
514
|
-
'51506': ExchangeError,
|
|
515
|
-
'51508': ExchangeError,
|
|
516
|
-
'51509': ExchangeError,
|
|
517
|
-
'51510': ExchangeError,
|
|
518
|
-
'51511': ExchangeError,
|
|
519
|
-
'51600': ExchangeError,
|
|
520
|
-
'51601': ExchangeError,
|
|
521
|
-
'51602': ExchangeError,
|
|
522
|
-
'51603': OrderNotFound,
|
|
523
|
-
'51732': AuthenticationError,
|
|
524
|
-
'51733': AuthenticationError,
|
|
525
|
-
'51734': AuthenticationError,
|
|
526
|
-
'51735': ExchangeError,
|
|
527
|
-
'51736': InsufficientFunds,
|
|
528
|
-
// Data class
|
|
529
|
-
'52000': ExchangeError,
|
|
530
|
-
// SPOT/MARGIN error codes 54000-54999
|
|
531
|
-
'54000': ExchangeError,
|
|
532
|
-
'54001': ExchangeError,
|
|
533
|
-
// FUNDING error codes 58000-58999
|
|
534
|
-
'58000': ExchangeError,
|
|
535
|
-
'58001': AuthenticationError,
|
|
536
|
-
'58002': PermissionDenied,
|
|
537
|
-
'58003': ExchangeError,
|
|
538
|
-
'58004': AccountSuspended,
|
|
539
|
-
'58005': ExchangeError,
|
|
540
|
-
'58006': ExchangeError,
|
|
541
|
-
'58007': ExchangeError,
|
|
542
|
-
'58100': ExchangeError,
|
|
543
|
-
'58101': AccountSuspended,
|
|
544
|
-
'58102': RateLimitExceeded,
|
|
545
|
-
'58103': ExchangeError,
|
|
546
|
-
'58104': ExchangeError,
|
|
547
|
-
'58105': ExchangeError,
|
|
548
|
-
'58106': ExchangeError,
|
|
549
|
-
'58107': ExchangeError,
|
|
550
|
-
'58108': ExchangeError,
|
|
551
|
-
'58109': ExchangeError,
|
|
552
|
-
'58110': ExchangeError,
|
|
553
|
-
'58111': ExchangeError,
|
|
554
|
-
'58112': ExchangeError,
|
|
555
|
-
'58114': ExchangeError,
|
|
556
|
-
'58115': ExchangeError,
|
|
557
|
-
'58116': ExchangeError,
|
|
558
|
-
'58117': ExchangeError,
|
|
559
|
-
'58125': BadRequest,
|
|
560
|
-
'58126': BadRequest,
|
|
561
|
-
'58127': BadRequest,
|
|
562
|
-
'58128': BadRequest,
|
|
563
|
-
'58200': ExchangeError,
|
|
564
|
-
'58201': ExchangeError,
|
|
565
|
-
'58202': ExchangeError,
|
|
566
|
-
'58203': InvalidAddress,
|
|
567
|
-
'58204': AccountSuspended,
|
|
568
|
-
'58205': ExchangeError,
|
|
569
|
-
'58206': ExchangeError,
|
|
570
|
-
'58207': InvalidAddress,
|
|
571
|
-
'58208': ExchangeError,
|
|
572
|
-
'58209': ExchangeError,
|
|
573
|
-
'58210': ExchangeError,
|
|
574
|
-
'58211': ExchangeError,
|
|
575
|
-
'58212': ExchangeError,
|
|
576
|
-
'58213': AuthenticationError,
|
|
577
|
-
'58221': BadRequest,
|
|
578
|
-
'58222': BadRequest,
|
|
579
|
-
'58224': BadRequest,
|
|
580
|
-
'58227': BadRequest,
|
|
581
|
-
'58228': BadRequest,
|
|
582
|
-
'58229': InsufficientFunds,
|
|
583
|
-
'58300': ExchangeError,
|
|
584
|
-
'58350': InsufficientFunds,
|
|
585
|
-
// Account error codes 59000-59999
|
|
586
|
-
'59000': ExchangeError,
|
|
587
|
-
'59001': ExchangeError,
|
|
588
|
-
'59100': ExchangeError,
|
|
589
|
-
'59101': ExchangeError,
|
|
590
|
-
'59102': ExchangeError,
|
|
591
|
-
'59103': InsufficientFunds,
|
|
592
|
-
'59104': ExchangeError,
|
|
593
|
-
'59105': ExchangeError,
|
|
594
|
-
'59106': ExchangeError,
|
|
595
|
-
'59107': ExchangeError,
|
|
596
|
-
'59108': InsufficientFunds,
|
|
597
|
-
'59109': ExchangeError,
|
|
598
|
-
'59128': InvalidOrder,
|
|
599
|
-
'59200': InsufficientFunds,
|
|
600
|
-
'59201': InsufficientFunds,
|
|
601
|
-
'59216': BadRequest,
|
|
602
|
-
'59300': ExchangeError,
|
|
603
|
-
'59301': ExchangeError,
|
|
604
|
-
'59313': ExchangeError,
|
|
605
|
-
'59401': ExchangeError,
|
|
606
|
-
'59500': ExchangeError,
|
|
607
|
-
'59501': ExchangeError,
|
|
608
|
-
'59502': ExchangeError,
|
|
609
|
-
'59503': ExchangeError,
|
|
610
|
-
'59504': ExchangeError,
|
|
611
|
-
'59505': ExchangeError,
|
|
612
|
-
'59506': ExchangeError,
|
|
613
|
-
'59507': ExchangeError,
|
|
614
|
-
'59508': AccountSuspended,
|
|
615
|
-
// WebSocket error Codes from 60000-63999
|
|
616
|
-
'60001': AuthenticationError,
|
|
617
|
-
'60002': AuthenticationError,
|
|
618
|
-
'60003': AuthenticationError,
|
|
619
|
-
'60004': AuthenticationError,
|
|
620
|
-
'60005': AuthenticationError,
|
|
621
|
-
'60006': InvalidNonce,
|
|
622
|
-
'60007': AuthenticationError,
|
|
623
|
-
'60008': AuthenticationError,
|
|
624
|
-
'60009': AuthenticationError,
|
|
625
|
-
'60010': AuthenticationError,
|
|
626
|
-
'60011': AuthenticationError,
|
|
627
|
-
'60012': BadRequest,
|
|
628
|
-
'60013': BadRequest,
|
|
629
|
-
'60014': RateLimitExceeded,
|
|
630
|
-
'60015': NetworkError,
|
|
631
|
-
'60016': ExchangeNotAvailable,
|
|
632
|
-
'60017': BadRequest,
|
|
633
|
-
'60018': BadRequest,
|
|
634
|
-
'60019': BadRequest,
|
|
635
|
-
'63999': ExchangeError,
|
|
636
|
-
'70010': BadRequest,
|
|
637
|
-
'70013': BadRequest,
|
|
638
|
-
'70016': BadRequest, // Please specify your instrument settings for at least one instType.
|
|
639
|
-
},
|
|
640
|
-
'broad': {
|
|
641
|
-
'Internal Server Error': ExchangeNotAvailable,
|
|
642
|
-
'server error': ExchangeNotAvailable, // {"code":500,"data":{},"detailMsg":"","error_code":"500","error_message":"server error 1236805249","msg":"server error 1236805249"}
|
|
643
|
-
},
|
|
644
|
-
},
|
|
645
|
-
'precisionMode': TICK_SIZE,
|
|
646
|
-
'options': {
|
|
647
|
-
'fetchOHLCV': {
|
|
648
|
-
'type': 'Candles', // Candles or HistoryCandles
|
|
649
|
-
},
|
|
650
|
-
'createMarketBuyOrderRequiresPrice': true,
|
|
651
|
-
'fetchMarkets': ['spot'],
|
|
652
|
-
'defaultType': 'spot',
|
|
653
|
-
'accountsByType': {
|
|
654
|
-
'classic': '1',
|
|
655
|
-
'spot': '1',
|
|
656
|
-
'funding': '6',
|
|
657
|
-
'main': '6',
|
|
658
|
-
'unified': '18',
|
|
659
|
-
},
|
|
660
|
-
'accountsById': {
|
|
661
|
-
'1': 'spot',
|
|
662
|
-
'6': 'funding',
|
|
663
|
-
'18': 'unified',
|
|
664
|
-
},
|
|
665
|
-
'auth': {
|
|
666
|
-
'time': 'public',
|
|
667
|
-
'currencies': 'private',
|
|
668
|
-
'instruments': 'public',
|
|
669
|
-
'rate': 'public',
|
|
670
|
-
'{instrument_id}/constituents': 'public',
|
|
671
|
-
},
|
|
672
|
-
'warnOnFetchCurrenciesWithoutAuthorization': false,
|
|
673
|
-
'defaultNetwork': 'ERC20',
|
|
674
|
-
'networks': {
|
|
675
|
-
'ERC20': 'Ethereum',
|
|
676
|
-
'BTC': 'Bitcoin',
|
|
677
|
-
'OMNI': 'Omni',
|
|
678
|
-
'TRC20': 'TRON',
|
|
679
|
-
},
|
|
680
|
-
},
|
|
681
|
-
'commonCurrencies': {
|
|
682
|
-
// OKEX refers to ERC20 version of Aeternity (AEToken)
|
|
683
|
-
'AE': 'AET',
|
|
684
|
-
'BOX': 'DefiBox',
|
|
685
|
-
'HOT': 'Hydro Protocol',
|
|
686
|
-
'HSR': 'HC',
|
|
687
|
-
'MAG': 'Maggie',
|
|
688
|
-
'SBTC': 'Super Bitcoin',
|
|
689
|
-
'TRADE': 'Unitrade',
|
|
690
|
-
'YOYO': 'YOYOW',
|
|
691
|
-
'WIN': 'WinToken', // https://github.com/ccxt/ccxt/issues/5701
|
|
692
|
-
},
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
/**
|
|
696
|
-
* @method
|
|
697
|
-
* @name okcoin#fetchTime
|
|
698
|
-
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
699
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
700
|
-
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
701
|
-
*/
|
|
702
|
-
async fetchTime(params = {}) {
|
|
703
|
-
const response = await this.publicGetPublicTime(params);
|
|
704
|
-
//
|
|
705
|
-
// {
|
|
706
|
-
// "code": "0",
|
|
707
|
-
// "data":
|
|
708
|
-
// [
|
|
709
|
-
// {
|
|
710
|
-
// "ts": "1737379360033"
|
|
711
|
-
// }
|
|
712
|
-
// ],
|
|
713
|
-
// "msg": ""
|
|
714
|
-
// }
|
|
715
|
-
//
|
|
716
|
-
const data = this.safeList(response, 'data');
|
|
717
|
-
const timestamp = this.safeDict(data, 0);
|
|
718
|
-
return this.safeInteger(timestamp, 'ts');
|
|
719
|
-
}
|
|
720
|
-
/**
|
|
721
|
-
* @method
|
|
722
|
-
* @name okcoin#fetchMarkets
|
|
723
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-public-data-get-instruments
|
|
724
|
-
* @description retrieves data on all markets for okcoin
|
|
725
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
726
|
-
* @returns {object[]} an array of objects representing market data
|
|
727
|
-
*/
|
|
728
|
-
async fetchMarkets(params = {}) {
|
|
729
|
-
const request = {
|
|
730
|
-
'instType': 'SPOT',
|
|
731
|
-
};
|
|
732
|
-
const response = await this.publicGetPublicInstruments(this.extend(request, params));
|
|
733
|
-
const markets = this.safeValue(response, 'data', []);
|
|
734
|
-
return this.parseMarkets(markets);
|
|
735
|
-
}
|
|
736
|
-
parseMarket(market) {
|
|
737
|
-
//
|
|
738
|
-
// spot markets
|
|
739
|
-
//
|
|
740
|
-
// {
|
|
741
|
-
// "base_currency": "EOS",
|
|
742
|
-
// "instrument_id": "EOS-OKB",
|
|
743
|
-
// "min_size": "0.01",
|
|
744
|
-
// "quote_currency": "OKB",
|
|
745
|
-
// "size_increment": "0.000001",
|
|
746
|
-
// "tick_size": "0.0001"
|
|
747
|
-
// }
|
|
748
|
-
//
|
|
749
|
-
const id = this.safeString(market, 'instId');
|
|
750
|
-
let type = this.safeStringLower(market, 'instType');
|
|
751
|
-
if (type === 'futures') {
|
|
752
|
-
type = 'future';
|
|
753
|
-
}
|
|
754
|
-
const spot = (type === 'spot');
|
|
755
|
-
const future = (type === 'future');
|
|
756
|
-
const swap = (type === 'swap');
|
|
757
|
-
const option = (type === 'option');
|
|
758
|
-
const contract = swap || future || option;
|
|
759
|
-
const baseId = this.safeString(market, 'baseCcy');
|
|
760
|
-
const quoteId = this.safeString(market, 'quoteCcy');
|
|
761
|
-
const base = this.safeCurrencyCode(baseId);
|
|
762
|
-
const quote = this.safeCurrencyCode(quoteId);
|
|
763
|
-
const symbol = base + '/' + quote;
|
|
764
|
-
const tickSize = this.safeString(market, 'tickSz');
|
|
765
|
-
const fees = this.safeValue2(this.fees, type, 'trading', {});
|
|
766
|
-
let maxLeverage = this.safeString(market, 'lever', '1');
|
|
767
|
-
maxLeverage = Precise.stringMax(maxLeverage, '1');
|
|
768
|
-
const maxSpotCost = this.safeNumber(market, 'maxMktSz');
|
|
769
|
-
return this.extend(fees, {
|
|
770
|
-
'id': id,
|
|
771
|
-
'symbol': symbol,
|
|
772
|
-
'base': base,
|
|
773
|
-
'quote': quote,
|
|
774
|
-
'settle': undefined,
|
|
775
|
-
'baseId': baseId,
|
|
776
|
-
'quoteId': quoteId,
|
|
777
|
-
'settleId': undefined,
|
|
778
|
-
'type': type,
|
|
779
|
-
'spot': spot,
|
|
780
|
-
'margin': spot && (Precise.stringGt(maxLeverage, '1')),
|
|
781
|
-
'swap': false,
|
|
782
|
-
'future': false,
|
|
783
|
-
'option': false,
|
|
784
|
-
'active': true,
|
|
785
|
-
'contract': false,
|
|
786
|
-
'linear': undefined,
|
|
787
|
-
'inverse': undefined,
|
|
788
|
-
'contractSize': contract ? this.safeNumber(market, 'ctVal') : undefined,
|
|
789
|
-
'expiry': undefined,
|
|
790
|
-
'expiryDatetime': undefined,
|
|
791
|
-
'strike': undefined,
|
|
792
|
-
'optionType': undefined,
|
|
793
|
-
'created': this.safeInteger(market, 'listTime'),
|
|
794
|
-
'precision': {
|
|
795
|
-
'amount': this.safeNumber(market, 'lotSz'),
|
|
796
|
-
'price': this.parseNumber(tickSize),
|
|
797
|
-
},
|
|
798
|
-
'limits': {
|
|
799
|
-
'leverage': {
|
|
800
|
-
'min': this.parseNumber('1'),
|
|
801
|
-
'max': this.parseNumber(maxLeverage),
|
|
802
|
-
},
|
|
803
|
-
'amount': {
|
|
804
|
-
'min': this.safeNumber(market, 'minSz'),
|
|
805
|
-
'max': undefined,
|
|
806
|
-
},
|
|
807
|
-
'price': {
|
|
808
|
-
'min': undefined,
|
|
809
|
-
'max': undefined,
|
|
810
|
-
},
|
|
811
|
-
'cost': {
|
|
812
|
-
'min': undefined,
|
|
813
|
-
'max': contract ? undefined : maxSpotCost,
|
|
814
|
-
},
|
|
815
|
-
},
|
|
816
|
-
'info': market,
|
|
817
|
-
});
|
|
818
|
-
}
|
|
819
|
-
/**
|
|
820
|
-
* @method
|
|
821
|
-
* @name okcoin#fetchCurrencies
|
|
822
|
-
* @description fetches all available currencies on an exchange
|
|
823
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
824
|
-
* @returns {object} an associative dictionary of currencies
|
|
825
|
-
*/
|
|
826
|
-
async fetchCurrencies(params = {}) {
|
|
827
|
-
if (!this.checkRequiredCredentials(false)) {
|
|
828
|
-
if (this.options['warnOnFetchCurrenciesWithoutAuthorization']) {
|
|
829
|
-
throw new ExchangeError(this.id + ' fetchCurrencies() is a private API endpoint that requires authentication with API keys. Set the API keys on the exchange instance or exchange.options["warnOnFetchCurrenciesWithoutAuthorization"] = false to suppress this warning message.');
|
|
830
|
-
}
|
|
831
|
-
return {};
|
|
832
|
-
}
|
|
833
|
-
else {
|
|
834
|
-
const response = await this.privateGetAssetCurrencies(params);
|
|
835
|
-
const data = this.safeList(response, 'data', []);
|
|
836
|
-
const result = {};
|
|
837
|
-
const dataByCurrencyId = this.groupBy(data, 'ccy');
|
|
838
|
-
const currencyIds = Object.keys(dataByCurrencyId);
|
|
839
|
-
for (let i = 0; i < currencyIds.length; i++) {
|
|
840
|
-
const currencyId = currencyIds[i];
|
|
841
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
842
|
-
const chains = dataByCurrencyId[currencyId];
|
|
843
|
-
const networks = {};
|
|
844
|
-
for (let j = 0; j < chains.length; j++) {
|
|
845
|
-
const chain = chains[j];
|
|
846
|
-
const networkId = this.safeString(chain, 'chain');
|
|
847
|
-
if ((networkId !== undefined) && (networkId.indexOf('-') >= 0)) {
|
|
848
|
-
const parts = networkId.split('-');
|
|
849
|
-
const chainPart = this.safeString(parts, 1, networkId);
|
|
850
|
-
const networkCode = this.networkIdToCode(chainPart);
|
|
851
|
-
networks[networkCode] = {
|
|
852
|
-
'id': networkId,
|
|
853
|
-
'network': networkCode,
|
|
854
|
-
'active': undefined,
|
|
855
|
-
'deposit': this.safeBool(chain, 'canDep'),
|
|
856
|
-
'withdraw': this.safeBool(chain, 'canWd'),
|
|
857
|
-
'fee': this.safeNumber(chain, 'minFee'),
|
|
858
|
-
'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'wdTickSz'))),
|
|
859
|
-
'limits': {
|
|
860
|
-
'withdraw': {
|
|
861
|
-
'min': this.safeNumber(chain, 'minWd'),
|
|
862
|
-
'max': this.safeNumber(chain, 'maxWd'),
|
|
863
|
-
},
|
|
864
|
-
},
|
|
865
|
-
'info': chain,
|
|
866
|
-
};
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
const firstChain = this.safeValue(chains, 0);
|
|
870
|
-
result[code] = this.safeCurrencyStructure({
|
|
871
|
-
'info': chains,
|
|
872
|
-
'code': code,
|
|
873
|
-
'id': currencyId,
|
|
874
|
-
'name': this.safeString(firstChain, 'name'),
|
|
875
|
-
'active': undefined,
|
|
876
|
-
'deposit': undefined,
|
|
877
|
-
'withdraw': undefined,
|
|
878
|
-
'fee': undefined,
|
|
879
|
-
'precision': undefined,
|
|
880
|
-
'limits': {
|
|
881
|
-
'amount': {
|
|
882
|
-
'min': undefined,
|
|
883
|
-
'max': undefined,
|
|
884
|
-
},
|
|
885
|
-
},
|
|
886
|
-
'networks': networks,
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
return result;
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
/**
|
|
893
|
-
* @method
|
|
894
|
-
* @name okcoin#fetchOrderBook
|
|
895
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-order-book
|
|
896
|
-
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
897
|
-
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
898
|
-
* @param {int} [limit] the maximum amount of order book entries to return
|
|
899
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
900
|
-
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
901
|
-
*/
|
|
902
|
-
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
903
|
-
await this.loadMarkets();
|
|
904
|
-
const market = this.market(symbol);
|
|
905
|
-
const request = {
|
|
906
|
-
'instId': market['id'],
|
|
907
|
-
};
|
|
908
|
-
limit = (limit === undefined) ? 20 : limit;
|
|
909
|
-
if (limit !== undefined) {
|
|
910
|
-
request['sz'] = limit; // max 400
|
|
911
|
-
}
|
|
912
|
-
const response = await this.publicGetMarketBooks(this.extend(request, params));
|
|
913
|
-
//
|
|
914
|
-
// {
|
|
915
|
-
// "code": "0",
|
|
916
|
-
// "msg": "",
|
|
917
|
-
// "data": [
|
|
918
|
-
// {
|
|
919
|
-
// "asks": [
|
|
920
|
-
// ["0.07228","4.211619","0","2"], // price, amount, liquidated orders, total open orders
|
|
921
|
-
// ["0.0723","299.880364","0","2"],
|
|
922
|
-
// ["0.07231","3.72832","0","1"],
|
|
923
|
-
// ],
|
|
924
|
-
// "bids": [
|
|
925
|
-
// ["0.07221","18.5","0","1"],
|
|
926
|
-
// ["0.0722","18.5","0","1"],
|
|
927
|
-
// ["0.07219","0.505407","0","1"],
|
|
928
|
-
// ],
|
|
929
|
-
// "ts": "1621438475342"
|
|
930
|
-
// }
|
|
931
|
-
// ]
|
|
932
|
-
// }
|
|
933
|
-
//
|
|
934
|
-
const data = this.safeValue(response, 'data', []);
|
|
935
|
-
const first = this.safeValue(data, 0, {});
|
|
936
|
-
const timestamp = this.safeInteger(first, 'ts');
|
|
937
|
-
return this.parseOrderBook(first, symbol, timestamp);
|
|
938
|
-
}
|
|
939
|
-
parseTicker(ticker, market = undefined) {
|
|
940
|
-
//
|
|
941
|
-
// {
|
|
942
|
-
// "instType": "SPOT",
|
|
943
|
-
// "instId": "ETH-BTC",
|
|
944
|
-
// "last": "0.07319",
|
|
945
|
-
// "lastSz": "0.044378",
|
|
946
|
-
// "askPx": "0.07322",
|
|
947
|
-
// "askSz": "4.2",
|
|
948
|
-
// "bidPx": "0.0732",
|
|
949
|
-
// "bidSz": "6.050058",
|
|
950
|
-
// "open24h": "0.07801",
|
|
951
|
-
// "high24h": "0.07975",
|
|
952
|
-
// "low24h": "0.06019",
|
|
953
|
-
// "volCcy24h": "11788.887619",
|
|
954
|
-
// "vol24h": "167493.829229",
|
|
955
|
-
// "ts": "1621440583784",
|
|
956
|
-
// "sodUtc0": "0.07872",
|
|
957
|
-
// "sodUtc8": "0.07345"
|
|
958
|
-
// }
|
|
959
|
-
//
|
|
960
|
-
const timestamp = this.safeInteger(ticker, 'ts');
|
|
961
|
-
const marketId = this.safeString(ticker, 'instId');
|
|
962
|
-
market = this.safeMarket(marketId, market, '-');
|
|
963
|
-
const symbol = market['symbol'];
|
|
964
|
-
const last = this.safeString(ticker, 'last');
|
|
965
|
-
const open = this.safeString(ticker, 'open24h');
|
|
966
|
-
const spot = this.safeBool(market, 'spot', false);
|
|
967
|
-
const quoteVolume = spot ? this.safeString(ticker, 'volCcy24h') : undefined;
|
|
968
|
-
const baseVolume = this.safeString(ticker, 'vol24h');
|
|
969
|
-
const high = this.safeString(ticker, 'high24h');
|
|
970
|
-
const low = this.safeString(ticker, 'low24h');
|
|
971
|
-
return this.safeTicker({
|
|
972
|
-
'symbol': symbol,
|
|
973
|
-
'timestamp': timestamp,
|
|
974
|
-
'datetime': this.iso8601(timestamp),
|
|
975
|
-
'high': high,
|
|
976
|
-
'low': low,
|
|
977
|
-
'bid': this.safeString(ticker, 'bidPx'),
|
|
978
|
-
'bidVolume': this.safeString(ticker, 'bidSz'),
|
|
979
|
-
'ask': this.safeString(ticker, 'askPx'),
|
|
980
|
-
'askVolume': this.safeString(ticker, 'askSz'),
|
|
981
|
-
'vwap': undefined,
|
|
982
|
-
'open': open,
|
|
983
|
-
'close': last,
|
|
984
|
-
'last': last,
|
|
985
|
-
'previousClose': undefined,
|
|
986
|
-
'change': undefined,
|
|
987
|
-
'percentage': undefined,
|
|
988
|
-
'average': undefined,
|
|
989
|
-
'baseVolume': baseVolume,
|
|
990
|
-
'quoteVolume': quoteVolume,
|
|
991
|
-
'info': ticker,
|
|
992
|
-
}, market);
|
|
993
|
-
}
|
|
994
|
-
/**
|
|
995
|
-
* @method
|
|
996
|
-
* @name okcoin#fetchTicker
|
|
997
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-ticker
|
|
998
|
-
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
999
|
-
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1000
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1001
|
-
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1002
|
-
*/
|
|
1003
|
-
async fetchTicker(symbol, params = {}) {
|
|
1004
|
-
await this.loadMarkets();
|
|
1005
|
-
const market = this.market(symbol);
|
|
1006
|
-
const request = {
|
|
1007
|
-
'instId': market['id'],
|
|
1008
|
-
};
|
|
1009
|
-
const response = await this.publicGetMarketTicker(this.extend(request, params));
|
|
1010
|
-
const data = this.safeValue(response, 'data', []);
|
|
1011
|
-
const first = this.safeValue(data, 0, {});
|
|
1012
|
-
//
|
|
1013
|
-
// {
|
|
1014
|
-
// "code": "0",
|
|
1015
|
-
// "msg": "",
|
|
1016
|
-
// "data": [
|
|
1017
|
-
// {
|
|
1018
|
-
// "instType": "SPOT",
|
|
1019
|
-
// "instId": "ETH-BTC",
|
|
1020
|
-
// "last": "0.07319",
|
|
1021
|
-
// "lastSz": "0.044378",
|
|
1022
|
-
// "askPx": "0.07322",
|
|
1023
|
-
// "askSz": "4.2",
|
|
1024
|
-
// "bidPx": "0.0732",
|
|
1025
|
-
// "bidSz": "6.050058",
|
|
1026
|
-
// "open24h": "0.07801",
|
|
1027
|
-
// "high24h": "0.07975",
|
|
1028
|
-
// "low24h": "0.06019",
|
|
1029
|
-
// "volCcy24h": "11788.887619",
|
|
1030
|
-
// "vol24h": "167493.829229",
|
|
1031
|
-
// "ts": "1621440583784",
|
|
1032
|
-
// "sodUtc0": "0.07872",
|
|
1033
|
-
// "sodUtc8": "0.07345"
|
|
1034
|
-
// }
|
|
1035
|
-
// ]
|
|
1036
|
-
// }
|
|
1037
|
-
//
|
|
1038
|
-
return this.parseTicker(first, market);
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
* @method
|
|
1042
|
-
* @name okcoin#fetchTickers
|
|
1043
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-tickers
|
|
1044
|
-
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1045
|
-
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1046
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1047
|
-
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1048
|
-
*/
|
|
1049
|
-
async fetchTickers(symbols = undefined, params = {}) {
|
|
1050
|
-
symbols = this.marketSymbols(symbols);
|
|
1051
|
-
const request = {
|
|
1052
|
-
'instType': 'SPOT',
|
|
1053
|
-
};
|
|
1054
|
-
const response = await this.publicGetMarketTickers(this.extend(request, params));
|
|
1055
|
-
const data = this.safeList(response, 'data', []);
|
|
1056
|
-
return this.parseTickers(data, symbols, params);
|
|
1057
|
-
}
|
|
1058
|
-
parseTrade(trade, market = undefined) {
|
|
1059
|
-
//
|
|
1060
|
-
// public fetchTrades
|
|
1061
|
-
//
|
|
1062
|
-
// {
|
|
1063
|
-
// "instId": "ETH-BTC",
|
|
1064
|
-
// "side": "sell",
|
|
1065
|
-
// "sz": "0.119501",
|
|
1066
|
-
// "px": "0.07065",
|
|
1067
|
-
// "tradeId": "15826757",
|
|
1068
|
-
// "ts": "1621446178316"
|
|
1069
|
-
// }
|
|
1070
|
-
//
|
|
1071
|
-
// private fetchMyTrades
|
|
1072
|
-
//
|
|
1073
|
-
// {
|
|
1074
|
-
// "side": "buy",
|
|
1075
|
-
// "fillSz": "0.007533",
|
|
1076
|
-
// "fillPx": "2654.98",
|
|
1077
|
-
// "fee": "-0.000007533",
|
|
1078
|
-
// "ordId": "317321390244397056",
|
|
1079
|
-
// "instType": "SPOT",
|
|
1080
|
-
// "instId": "ETH-USDT",
|
|
1081
|
-
// "clOrdId": "",
|
|
1082
|
-
// "posSide": "net",
|
|
1083
|
-
// "billId": "317321390265368576",
|
|
1084
|
-
// "tag": "0",
|
|
1085
|
-
// "execType": "T",
|
|
1086
|
-
// "tradeId": "107601752",
|
|
1087
|
-
// "feeCcy": "ETH",
|
|
1088
|
-
// "ts": "1621927314985"
|
|
1089
|
-
// }
|
|
1090
|
-
//
|
|
1091
|
-
const id = this.safeString(trade, 'tradeId');
|
|
1092
|
-
const marketId = this.safeString(trade, 'instId');
|
|
1093
|
-
market = this.safeMarket(marketId, market, '-');
|
|
1094
|
-
const symbol = market['symbol'];
|
|
1095
|
-
const timestamp = this.safeInteger(trade, 'ts');
|
|
1096
|
-
const price = this.safeString2(trade, 'fillPx', 'px');
|
|
1097
|
-
const amount = this.safeString2(trade, 'fillSz', 'sz');
|
|
1098
|
-
const side = this.safeString(trade, 'side');
|
|
1099
|
-
const orderId = this.safeString(trade, 'ordId');
|
|
1100
|
-
const feeCostString = this.safeString(trade, 'fee');
|
|
1101
|
-
let fee = undefined;
|
|
1102
|
-
if (feeCostString !== undefined) {
|
|
1103
|
-
const feeCostSigned = Precise.stringNeg(feeCostString);
|
|
1104
|
-
const feeCurrencyId = this.safeString(trade, 'feeCcy');
|
|
1105
|
-
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
1106
|
-
fee = {
|
|
1107
|
-
'cost': feeCostSigned,
|
|
1108
|
-
'currency': feeCurrencyCode,
|
|
1109
|
-
};
|
|
1110
|
-
}
|
|
1111
|
-
let takerOrMaker = this.safeString(trade, 'execType');
|
|
1112
|
-
if (takerOrMaker === 'T') {
|
|
1113
|
-
takerOrMaker = 'taker';
|
|
1114
|
-
}
|
|
1115
|
-
else if (takerOrMaker === 'M') {
|
|
1116
|
-
takerOrMaker = 'maker';
|
|
1117
|
-
}
|
|
1118
|
-
return this.safeTrade({
|
|
1119
|
-
'info': trade,
|
|
1120
|
-
'timestamp': timestamp,
|
|
1121
|
-
'datetime': this.iso8601(timestamp),
|
|
1122
|
-
'symbol': symbol,
|
|
1123
|
-
'id': id,
|
|
1124
|
-
'order': orderId,
|
|
1125
|
-
'type': undefined,
|
|
1126
|
-
'takerOrMaker': takerOrMaker,
|
|
1127
|
-
'side': side,
|
|
1128
|
-
'price': price,
|
|
1129
|
-
'amount': amount,
|
|
1130
|
-
'cost': undefined,
|
|
1131
|
-
'fee': fee,
|
|
1132
|
-
}, market);
|
|
1133
|
-
}
|
|
1134
|
-
/**
|
|
1135
|
-
* @method
|
|
1136
|
-
* @name okcoin#fetchTrades
|
|
1137
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-trades
|
|
1138
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-trades-history
|
|
1139
|
-
* @description get the list of most recent trades for a particular symbol
|
|
1140
|
-
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1141
|
-
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1142
|
-
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1143
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1144
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1145
|
-
*/
|
|
1146
|
-
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1147
|
-
await this.loadMarkets();
|
|
1148
|
-
const market = this.market(symbol);
|
|
1149
|
-
if ((limit === undefined) || (limit > 100)) {
|
|
1150
|
-
limit = 100; // maximum = default = 100
|
|
1151
|
-
}
|
|
1152
|
-
const request = {
|
|
1153
|
-
'instId': market['id'],
|
|
1154
|
-
};
|
|
1155
|
-
let method = undefined;
|
|
1156
|
-
[method, params] = this.handleOptionAndParams(params, 'fetchTrades', 'method', 'publicGetMarketTrades');
|
|
1157
|
-
let response = undefined;
|
|
1158
|
-
if (method === 'publicGetMarketTrades') {
|
|
1159
|
-
response = await this.publicGetMarketTrades(this.extend(request, params));
|
|
1160
|
-
}
|
|
1161
|
-
else {
|
|
1162
|
-
response = await this.publicGetMarketHistoryTrades(this.extend(request, params));
|
|
1163
|
-
}
|
|
1164
|
-
const data = this.safeList(response, 'data', []);
|
|
1165
|
-
return this.parseTrades(data, market, since, limit);
|
|
1166
|
-
}
|
|
1167
|
-
parseOHLCV(ohlcv, market = undefined) {
|
|
1168
|
-
//
|
|
1169
|
-
// [
|
|
1170
|
-
// "1678928760000", // timestamp
|
|
1171
|
-
// "24341.4", // open
|
|
1172
|
-
// "24344", // high
|
|
1173
|
-
// "24313.2", // low
|
|
1174
|
-
// "24323", // close
|
|
1175
|
-
// "628", // contract volume
|
|
1176
|
-
// "2.5819", // base volume
|
|
1177
|
-
// "62800", // quote volume
|
|
1178
|
-
// "0" // candlestick state
|
|
1179
|
-
// ]
|
|
1180
|
-
//
|
|
1181
|
-
return [
|
|
1182
|
-
this.safeInteger(ohlcv, 0),
|
|
1183
|
-
this.safeNumber(ohlcv, 1),
|
|
1184
|
-
this.safeNumber(ohlcv, 2),
|
|
1185
|
-
this.safeNumber(ohlcv, 3),
|
|
1186
|
-
this.safeNumber(ohlcv, 4),
|
|
1187
|
-
this.safeNumber(ohlcv, 5),
|
|
1188
|
-
];
|
|
1189
|
-
}
|
|
1190
|
-
/**
|
|
1191
|
-
* @method
|
|
1192
|
-
* @name okcoin#fetchOHLCV
|
|
1193
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-candlesticks
|
|
1194
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-candlesticks-history
|
|
1195
|
-
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1196
|
-
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1197
|
-
* @param {string} timeframe the length of time each candle represents
|
|
1198
|
-
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1199
|
-
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1200
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1201
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1202
|
-
*/
|
|
1203
|
-
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1204
|
-
await this.loadMarkets();
|
|
1205
|
-
const market = this.market(symbol);
|
|
1206
|
-
const duration = this.parseTimeframe(timeframe);
|
|
1207
|
-
const options = this.safeValue(this.options, 'fetchOHLCV', {});
|
|
1208
|
-
let bar = this.safeString(this.timeframes, timeframe, timeframe);
|
|
1209
|
-
const timezone = this.safeString(options, 'timezone', 'UTC');
|
|
1210
|
-
if ((timezone === 'UTC') && (duration >= 21600)) { // if utc and timeframe >= 6h
|
|
1211
|
-
bar += timezone.toLowerCase();
|
|
1212
|
-
}
|
|
1213
|
-
const request = {
|
|
1214
|
-
'instId': market['id'],
|
|
1215
|
-
'bar': bar,
|
|
1216
|
-
};
|
|
1217
|
-
if (limit !== undefined) {
|
|
1218
|
-
request['limit'] = limit; // default 100, max 100
|
|
1219
|
-
}
|
|
1220
|
-
let method = undefined;
|
|
1221
|
-
[method, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'method', 'publicGetMarketCandles');
|
|
1222
|
-
let response = undefined;
|
|
1223
|
-
if (method === 'publicGetMarketCandles') {
|
|
1224
|
-
response = await this.publicGetMarketCandles(this.extend(request, params));
|
|
1225
|
-
}
|
|
1226
|
-
else {
|
|
1227
|
-
response = await this.publicGetMarketHistoryCandles(this.extend(request, params));
|
|
1228
|
-
}
|
|
1229
|
-
const data = this.safeList(response, 'data', []);
|
|
1230
|
-
return this.parseOHLCVs(data, market, timeframe, since, limit);
|
|
1231
|
-
}
|
|
1232
|
-
parseAccountBalance(response) {
|
|
1233
|
-
//
|
|
1234
|
-
// account
|
|
1235
|
-
//
|
|
1236
|
-
// [
|
|
1237
|
-
// {
|
|
1238
|
-
// "balance": 0,
|
|
1239
|
-
// "available": 0,
|
|
1240
|
-
// "currency": "BTC",
|
|
1241
|
-
// "hold": 0
|
|
1242
|
-
// },
|
|
1243
|
-
// {
|
|
1244
|
-
// "balance": 0,
|
|
1245
|
-
// "available": 0,
|
|
1246
|
-
// "currency": "ETH",
|
|
1247
|
-
// "hold": 0
|
|
1248
|
-
// }
|
|
1249
|
-
// ]
|
|
1250
|
-
//
|
|
1251
|
-
// spot
|
|
1252
|
-
//
|
|
1253
|
-
// [
|
|
1254
|
-
// {
|
|
1255
|
-
// "frozen": "0",
|
|
1256
|
-
// "hold": "0",
|
|
1257
|
-
// "id": "2149632",
|
|
1258
|
-
// "currency": "BTC",
|
|
1259
|
-
// "balance": "0.0000000497717339",
|
|
1260
|
-
// "available": "0.0000000497717339",
|
|
1261
|
-
// "holds": "0"
|
|
1262
|
-
// },
|
|
1263
|
-
// {
|
|
1264
|
-
// "frozen": "0",
|
|
1265
|
-
// "hold": "0",
|
|
1266
|
-
// "id": "2149632",
|
|
1267
|
-
// "currency": "ICN",
|
|
1268
|
-
// "balance": "0.00000000925",
|
|
1269
|
-
// "available": "0.00000000925",
|
|
1270
|
-
// "holds": "0"
|
|
1271
|
-
// }
|
|
1272
|
-
// ]
|
|
1273
|
-
//
|
|
1274
|
-
const result = {
|
|
1275
|
-
'info': response,
|
|
1276
|
-
'timestamp': undefined,
|
|
1277
|
-
'datetime': undefined,
|
|
1278
|
-
};
|
|
1279
|
-
for (let i = 0; i < response.length; i++) {
|
|
1280
|
-
const balance = response[i];
|
|
1281
|
-
const currencyId = this.safeString(balance, 'currency');
|
|
1282
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1283
|
-
const account = this.account();
|
|
1284
|
-
account['total'] = this.safeString(balance, 'balance');
|
|
1285
|
-
account['used'] = this.safeString(balance, 'hold');
|
|
1286
|
-
account['free'] = this.safeString(balance, 'available');
|
|
1287
|
-
result[code] = account;
|
|
1288
|
-
}
|
|
1289
|
-
return this.safeBalance(result);
|
|
1290
|
-
}
|
|
1291
|
-
/**
|
|
1292
|
-
* @method
|
|
1293
|
-
* @name okcoin#fetchBalance
|
|
1294
|
-
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1295
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1296
|
-
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1297
|
-
*/
|
|
1298
|
-
async fetchBalance(params = {}) {
|
|
1299
|
-
await this.loadMarkets();
|
|
1300
|
-
const [marketType, query] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
|
|
1301
|
-
const request = {
|
|
1302
|
-
// 'ccy': 'BTC,ETH', // comma-separated list of currency ids
|
|
1303
|
-
};
|
|
1304
|
-
let response = undefined;
|
|
1305
|
-
if (marketType === 'funding') {
|
|
1306
|
-
response = await this.privateGetAssetBalances(this.extend(request, query));
|
|
1307
|
-
}
|
|
1308
|
-
else {
|
|
1309
|
-
response = await this.privateGetAccountBalance(this.extend(request, query));
|
|
1310
|
-
}
|
|
1311
|
-
//
|
|
1312
|
-
// {
|
|
1313
|
-
// "code": "0",
|
|
1314
|
-
// "data": [
|
|
1315
|
-
// {
|
|
1316
|
-
// "category": "1",
|
|
1317
|
-
// "delivery": "",
|
|
1318
|
-
// "exercise": "",
|
|
1319
|
-
// "instType": "SPOT",
|
|
1320
|
-
// "level": "Lv1",
|
|
1321
|
-
// "maker": "-0.0008",
|
|
1322
|
-
// "taker": "-0.001",
|
|
1323
|
-
// "ts": "1639043138472"
|
|
1324
|
-
// }
|
|
1325
|
-
// ],
|
|
1326
|
-
// "msg": ""
|
|
1327
|
-
// }
|
|
1328
|
-
//
|
|
1329
|
-
if (marketType === 'funding') {
|
|
1330
|
-
return this.parseFundingBalance(response);
|
|
1331
|
-
}
|
|
1332
|
-
else {
|
|
1333
|
-
return this.parseTradingBalance(response);
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
parseTradingBalance(response) {
|
|
1337
|
-
const result = { 'info': response };
|
|
1338
|
-
const data = this.safeValue(response, 'data', []);
|
|
1339
|
-
const first = this.safeValue(data, 0, {});
|
|
1340
|
-
const timestamp = this.safeInteger(first, 'uTime');
|
|
1341
|
-
const details = this.safeValue(first, 'details', []);
|
|
1342
|
-
for (let i = 0; i < details.length; i++) {
|
|
1343
|
-
const balance = details[i];
|
|
1344
|
-
const currencyId = this.safeString(balance, 'ccy');
|
|
1345
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1346
|
-
const account = this.account();
|
|
1347
|
-
// it may be incorrect to use total, free and used for swap accounts
|
|
1348
|
-
const eq = this.safeString(balance, 'eq');
|
|
1349
|
-
const availEq = this.safeString(balance, 'availEq');
|
|
1350
|
-
if ((eq === undefined) || (availEq === undefined)) {
|
|
1351
|
-
account['free'] = this.safeString(balance, 'availBal');
|
|
1352
|
-
account['used'] = this.safeString(balance, 'frozenBal');
|
|
1353
|
-
}
|
|
1354
|
-
else {
|
|
1355
|
-
account['total'] = eq;
|
|
1356
|
-
account['free'] = availEq;
|
|
1357
|
-
}
|
|
1358
|
-
result[code] = account;
|
|
1359
|
-
}
|
|
1360
|
-
result['timestamp'] = timestamp;
|
|
1361
|
-
result['datetime'] = this.iso8601(timestamp);
|
|
1362
|
-
return this.safeBalance(result);
|
|
1363
|
-
}
|
|
1364
|
-
parseFundingBalance(response) {
|
|
1365
|
-
const result = { 'info': response };
|
|
1366
|
-
const data = this.safeValue(response, 'data', []);
|
|
1367
|
-
for (let i = 0; i < data.length; i++) {
|
|
1368
|
-
const balance = data[i];
|
|
1369
|
-
const currencyId = this.safeString(balance, 'ccy');
|
|
1370
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1371
|
-
const account = this.account();
|
|
1372
|
-
// it may be incorrect to use total, free and used for swap accounts
|
|
1373
|
-
account['total'] = this.safeString(balance, 'bal');
|
|
1374
|
-
account['free'] = this.safeString(balance, 'availBal');
|
|
1375
|
-
account['used'] = this.safeString(balance, 'frozenBal');
|
|
1376
|
-
result[code] = account;
|
|
1377
|
-
}
|
|
1378
|
-
return this.safeBalance(result);
|
|
1379
|
-
}
|
|
1380
|
-
/**
|
|
1381
|
-
* @method
|
|
1382
|
-
* @name okcoin#createMarketBuyOrderWithCost
|
|
1383
|
-
* @description create a market buy order by providing the symbol and cost
|
|
1384
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-order
|
|
1385
|
-
* @param {string} symbol unified symbol of the market to create an order in
|
|
1386
|
-
* @param {float} cost how much you want to trade in units of the quote currency
|
|
1387
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1388
|
-
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1389
|
-
*/
|
|
1390
|
-
async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
|
|
1391
|
-
await this.loadMarkets();
|
|
1392
|
-
const market = this.market(symbol);
|
|
1393
|
-
if (!market['spot']) {
|
|
1394
|
-
throw new NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
|
|
1395
|
-
}
|
|
1396
|
-
params['createMarketBuyOrderRequiresPrice'] = false;
|
|
1397
|
-
params['tgtCcy'] = 'quote_ccy';
|
|
1398
|
-
return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
|
|
1399
|
-
}
|
|
1400
|
-
/**
|
|
1401
|
-
* @method
|
|
1402
|
-
* @name okcoin#createOrder
|
|
1403
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-order
|
|
1404
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-algo-order
|
|
1405
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-multiple-orders
|
|
1406
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
|
|
1407
|
-
* @description create a trade order
|
|
1408
|
-
* @param {string} symbol unified symbol of the market to create an order in
|
|
1409
|
-
* @param {string} type 'market' or 'limit'
|
|
1410
|
-
* @param {string} side 'buy' or 'sell'
|
|
1411
|
-
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1412
|
-
* @param {float} price the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1413
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1414
|
-
* @param {bool} [params.reduceOnly] MARGIN orders only, or swap/future orders in net mode
|
|
1415
|
-
* @param {bool} [params.postOnly] true to place a post only order
|
|
1416
|
-
* @param {float} [params.triggerPrice] conditional orders only, the price at which the order is to be triggered
|
|
1417
|
-
* @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered (perpetual swap markets only)
|
|
1418
|
-
* @param {float} [params.takeProfit.triggerPrice] take profit trigger price
|
|
1419
|
-
* @param {float} [params.takeProfit.price] used for take profit limit orders, not used for take profit market price orders
|
|
1420
|
-
* @param {string} [params.takeProfit.type] 'market' or 'limit' used to specify the take profit price type
|
|
1421
|
-
* @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered (perpetual swap markets only)
|
|
1422
|
-
* @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
|
|
1423
|
-
* @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders
|
|
1424
|
-
* @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type
|
|
1425
|
-
* @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
|
|
1426
|
-
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1427
|
-
*/
|
|
1428
|
-
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1429
|
-
await this.loadMarkets();
|
|
1430
|
-
const market = this.market(symbol);
|
|
1431
|
-
let request = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
1432
|
-
let method = this.safeString(this.options, 'createOrder', 'privatePostTradeBatchOrders');
|
|
1433
|
-
const requestOrdType = this.safeString(request, 'ordType');
|
|
1434
|
-
if ((requestOrdType === 'trigger') || (requestOrdType === 'conditional') || (type === 'oco') || (type === 'move_order_stop') || (type === 'iceberg') || (type === 'twap')) {
|
|
1435
|
-
method = 'privatePostTradeOrderAlgo';
|
|
1436
|
-
}
|
|
1437
|
-
if (method === 'privatePostTradeBatchOrders') {
|
|
1438
|
-
// keep the request body the same
|
|
1439
|
-
// submit a single order in an array to the batch order endpoint
|
|
1440
|
-
// because it has a lower ratelimit
|
|
1441
|
-
request = [request];
|
|
1442
|
-
}
|
|
1443
|
-
let response = undefined;
|
|
1444
|
-
if (method === 'privatePostTradeOrder') {
|
|
1445
|
-
response = await this.privatePostTradeOrder(request);
|
|
1446
|
-
}
|
|
1447
|
-
else if (method === 'privatePostTradeOrderAlgo') {
|
|
1448
|
-
response = await this.privatePostTradeOrderAlgo(request);
|
|
1449
|
-
}
|
|
1450
|
-
else if (method === 'privatePostTradeBatchOrders') {
|
|
1451
|
-
response = await this.privatePostTradeBatchOrders(request);
|
|
1452
|
-
}
|
|
1453
|
-
else {
|
|
1454
|
-
throw new ExchangeError(this.id + ' createOrder() this.options["createOrder"] must be either privatePostTradeBatchOrders or privatePostTradeOrder or privatePostTradeOrderAlgo');
|
|
1455
|
-
}
|
|
1456
|
-
const data = this.safeValue(response, 'data', []);
|
|
1457
|
-
const first = this.safeValue(data, 0);
|
|
1458
|
-
const order = this.parseOrder(first, market);
|
|
1459
|
-
order['type'] = type;
|
|
1460
|
-
order['side'] = side;
|
|
1461
|
-
return order;
|
|
1462
|
-
}
|
|
1463
|
-
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1464
|
-
const market = this.market(symbol);
|
|
1465
|
-
const request = {
|
|
1466
|
-
'instId': market['id'],
|
|
1467
|
-
// 'ccy': currency['id'], // only applicable to cross MARGIN orders in single-currency margin
|
|
1468
|
-
// 'clOrdId': clientOrderId, // up to 32 characters, must be unique
|
|
1469
|
-
// 'tag': tag, // up to 8 characters
|
|
1470
|
-
'side': side,
|
|
1471
|
-
// 'posSide': 'long', // long, short, // required in the long/short mode, and can only be long or short (only for future or swap)
|
|
1472
|
-
'ordType': type,
|
|
1473
|
-
// 'ordType': type, // privatePostTradeOrder: market, limit, post_only, fok, ioc, optimal_limit_ioc
|
|
1474
|
-
// 'ordType': type, // privatePostTradeOrderAlgo: conditional, oco, trigger, move_order_stop, iceberg, twap
|
|
1475
|
-
// 'sz': this.amountToPrecision (symbol, amount),
|
|
1476
|
-
// 'px': this.priceToPrecision (symbol, price), // limit orders only
|
|
1477
|
-
// 'reduceOnly': false,
|
|
1478
|
-
//
|
|
1479
|
-
// 'triggerPx': 10, // stopPrice (trigger orders)
|
|
1480
|
-
// 'orderPx': 10, // Order price if -1, the order will be executed at the market price. (trigger orders)
|
|
1481
|
-
// 'triggerPxType': 'last', // Conditional default is last, mark or index (trigger orders)
|
|
1482
|
-
//
|
|
1483
|
-
// 'tpTriggerPx': 10, // takeProfitPrice (conditional orders)
|
|
1484
|
-
// 'tpTriggerPxType': 'last', // Conditional default is last, mark or index (conditional orders)
|
|
1485
|
-
// 'tpOrdPx': 10, // Order price for Take-Profit orders, if -1 will be executed at market price (conditional orders)
|
|
1486
|
-
//
|
|
1487
|
-
// 'slTriggerPx': 10, // stopLossPrice (conditional orders)
|
|
1488
|
-
// 'slTriggerPxType': 'last', // Conditional default is last, mark or index (conditional orders)
|
|
1489
|
-
// 'slOrdPx': 10, // Order price for Stop-Loss orders, if -1 will be executed at market price (conditional orders)
|
|
1490
|
-
};
|
|
1491
|
-
const triggerPrice = this.safeValueN(params, ['triggerPrice', 'stopPrice', 'triggerPx']);
|
|
1492
|
-
const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
|
|
1493
|
-
const takeProfitPrice = this.safeValue2(params, 'takeProfitPrice', 'tpTriggerPx');
|
|
1494
|
-
const tpOrdPx = this.safeValue(params, 'tpOrdPx', price);
|
|
1495
|
-
const tpTriggerPxType = this.safeString(params, 'tpTriggerPxType', 'last');
|
|
1496
|
-
const stopLossPrice = this.safeValue2(params, 'stopLossPrice', 'slTriggerPx');
|
|
1497
|
-
const slOrdPx = this.safeValue(params, 'slOrdPx', price);
|
|
1498
|
-
const slTriggerPxType = this.safeString(params, 'slTriggerPxType', 'last');
|
|
1499
|
-
const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
|
|
1500
|
-
const stopLoss = this.safeValue(params, 'stopLoss');
|
|
1501
|
-
const stopLossDefined = (stopLoss !== undefined);
|
|
1502
|
-
const takeProfit = this.safeValue(params, 'takeProfit');
|
|
1503
|
-
const takeProfitDefined = (takeProfit !== undefined);
|
|
1504
|
-
const defaultMarginMode = this.safeString2(this.options, 'defaultMarginMode', 'marginMode', 'cross');
|
|
1505
|
-
let marginMode = this.safeString2(params, 'marginMode', 'tdMode'); // cross or isolated, tdMode not ommited so as to be extended into the request
|
|
1506
|
-
let margin = false;
|
|
1507
|
-
if ((marginMode !== undefined) && (marginMode !== 'cash')) {
|
|
1508
|
-
margin = true;
|
|
1509
|
-
}
|
|
1510
|
-
else {
|
|
1511
|
-
marginMode = defaultMarginMode;
|
|
1512
|
-
margin = this.safeBool(params, 'margin', false);
|
|
1513
|
-
}
|
|
1514
|
-
if (margin) {
|
|
1515
|
-
const defaultCurrency = (side === 'buy') ? market['quote'] : market['base'];
|
|
1516
|
-
const currency = this.safeString(params, 'ccy', defaultCurrency);
|
|
1517
|
-
request['ccy'] = this.safeCurrencyCode(currency);
|
|
1518
|
-
}
|
|
1519
|
-
const tradeMode = margin ? marginMode : 'cash';
|
|
1520
|
-
request['tdMode'] = tradeMode;
|
|
1521
|
-
const isMarketOrder = type === 'market';
|
|
1522
|
-
let postOnly = false;
|
|
1523
|
-
[postOnly, params] = this.handlePostOnly(isMarketOrder, type === 'post_only', params);
|
|
1524
|
-
params = this.omit(params, ['currency', 'ccy', 'marginMode', 'timeInForce', 'stopPrice', 'triggerPrice', 'clientOrderId', 'stopLossPrice', 'takeProfitPrice', 'slOrdPx', 'tpOrdPx', 'margin', 'stopLoss', 'takeProfit']);
|
|
1525
|
-
const ioc = (timeInForce === 'IOC') || (type === 'ioc');
|
|
1526
|
-
const fok = (timeInForce === 'FOK') || (type === 'fok');
|
|
1527
|
-
const trigger = (triggerPrice !== undefined) || (type === 'trigger');
|
|
1528
|
-
const conditional = (stopLossPrice !== undefined) || (takeProfitPrice !== undefined) || (type === 'conditional');
|
|
1529
|
-
const marketIOC = (isMarketOrder && ioc) || (type === 'optimal_limit_ioc');
|
|
1530
|
-
const defaultTgtCcy = this.safeString(this.options, 'tgtCcy', 'base_ccy');
|
|
1531
|
-
const tgtCcy = this.safeString(params, 'tgtCcy', defaultTgtCcy);
|
|
1532
|
-
if ((!margin)) {
|
|
1533
|
-
request['tgtCcy'] = tgtCcy;
|
|
1534
|
-
}
|
|
1535
|
-
if (isMarketOrder || marketIOC) {
|
|
1536
|
-
request['ordType'] = 'market';
|
|
1537
|
-
if (side === 'buy') {
|
|
1538
|
-
// spot market buy: "sz" can refer either to base currency units or to quote currency units
|
|
1539
|
-
// see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order
|
|
1540
|
-
if (tgtCcy === 'quote_ccy') {
|
|
1541
|
-
// quote_ccy: sz refers to units of quote currency
|
|
1542
|
-
let quoteAmount = undefined;
|
|
1543
|
-
let createMarketBuyOrderRequiresPrice = true;
|
|
1544
|
-
[createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
|
|
1545
|
-
const cost = this.safeNumber2(params, 'cost', 'sz');
|
|
1546
|
-
params = this.omit(params, ['cost', 'sz']);
|
|
1547
|
-
if (cost !== undefined) {
|
|
1548
|
-
quoteAmount = this.costToPrecision(symbol, cost);
|
|
1549
|
-
}
|
|
1550
|
-
else if (createMarketBuyOrderRequiresPrice) {
|
|
1551
|
-
if (price === undefined) {
|
|
1552
|
-
throw new InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend (quote quantity) in the amount argument');
|
|
1553
|
-
}
|
|
1554
|
-
else {
|
|
1555
|
-
const amountString = this.numberToString(amount);
|
|
1556
|
-
const priceString = this.numberToString(price);
|
|
1557
|
-
const costRequest = Precise.stringMul(amountString, priceString);
|
|
1558
|
-
quoteAmount = this.costToPrecision(symbol, costRequest);
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
else {
|
|
1562
|
-
quoteAmount = this.costToPrecision(symbol, amount);
|
|
1563
|
-
}
|
|
1564
|
-
request['sz'] = quoteAmount;
|
|
1565
|
-
}
|
|
1566
|
-
else {
|
|
1567
|
-
request['sz'] = this.amountToPrecision(symbol, amount);
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
else {
|
|
1571
|
-
request['sz'] = this.amountToPrecision(symbol, amount);
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
|
-
else {
|
|
1575
|
-
request['sz'] = this.amountToPrecision(symbol, amount);
|
|
1576
|
-
if ((!trigger) && (!conditional)) {
|
|
1577
|
-
request['px'] = this.priceToPrecision(symbol, price);
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
|
-
if (postOnly) {
|
|
1581
|
-
request['ordType'] = 'post_only';
|
|
1582
|
-
}
|
|
1583
|
-
else if (ioc && !marketIOC) {
|
|
1584
|
-
request['ordType'] = 'ioc';
|
|
1585
|
-
}
|
|
1586
|
-
else if (fok) {
|
|
1587
|
-
request['ordType'] = 'fok';
|
|
1588
|
-
}
|
|
1589
|
-
else if (stopLossDefined || takeProfitDefined) {
|
|
1590
|
-
if (stopLossDefined) {
|
|
1591
|
-
const stopLossTriggerPrice = this.safeValueN(stopLoss, ['triggerPrice', 'stopPrice', 'slTriggerPx']);
|
|
1592
|
-
if (stopLossTriggerPrice === undefined) {
|
|
1593
|
-
throw new InvalidOrder(this.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"] for a stop loss order');
|
|
1594
|
-
}
|
|
1595
|
-
request['slTriggerPx'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
|
|
1596
|
-
const stopLossLimitPrice = this.safeValueN(stopLoss, ['price', 'stopLossPrice', 'slOrdPx']);
|
|
1597
|
-
const stopLossOrderType = this.safeString(stopLoss, 'type');
|
|
1598
|
-
if (stopLossOrderType !== undefined) {
|
|
1599
|
-
const stopLossLimitOrderType = (stopLossOrderType === 'limit');
|
|
1600
|
-
const stopLossMarketOrderType = (stopLossOrderType === 'market');
|
|
1601
|
-
if ((!stopLossLimitOrderType) && (!stopLossMarketOrderType)) {
|
|
1602
|
-
throw new InvalidOrder(this.id + ' createOrder() params["stopLoss"]["type"] must be either "limit" or "market"');
|
|
1603
|
-
}
|
|
1604
|
-
else if (stopLossLimitOrderType) {
|
|
1605
|
-
if (stopLossLimitPrice === undefined) {
|
|
1606
|
-
throw new InvalidOrder(this.id + ' createOrder() requires a limit price in params["stopLoss"]["price"] for a stop loss limit order');
|
|
1607
|
-
}
|
|
1608
|
-
else {
|
|
1609
|
-
request['slOrdPx'] = this.priceToPrecision(symbol, stopLossLimitPrice);
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
else if (stopLossOrderType === 'market') {
|
|
1613
|
-
request['slOrdPx'] = '-1';
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
else if (stopLossLimitPrice !== undefined) {
|
|
1617
|
-
request['slOrdPx'] = this.priceToPrecision(symbol, stopLossLimitPrice); // limit sl order
|
|
1618
|
-
}
|
|
1619
|
-
else {
|
|
1620
|
-
request['slOrdPx'] = '-1'; // market sl order
|
|
1621
|
-
}
|
|
1622
|
-
const stopLossTriggerPriceType = this.safeString2(stopLoss, 'triggerPriceType', 'slTriggerPxType', 'last');
|
|
1623
|
-
if (stopLossTriggerPriceType !== undefined) {
|
|
1624
|
-
if ((stopLossTriggerPriceType !== 'last') && (stopLossTriggerPriceType !== 'index') && (stopLossTriggerPriceType !== 'mark')) {
|
|
1625
|
-
throw new InvalidOrder(this.id + ' createOrder() stop loss trigger price type must be one of "last", "index" or "mark"');
|
|
1626
|
-
}
|
|
1627
|
-
request['slTriggerPxType'] = stopLossTriggerPriceType;
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
if (takeProfitDefined) {
|
|
1631
|
-
const takeProfitTriggerPrice = this.safeValueN(takeProfit, ['triggerPrice', 'stopPrice', 'tpTriggerPx']);
|
|
1632
|
-
if (takeProfitTriggerPrice === undefined) {
|
|
1633
|
-
throw new InvalidOrder(this.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"], or params["takeProfit"]["stopPrice"], or params["takeProfit"]["tpTriggerPx"] for a take profit order');
|
|
1634
|
-
}
|
|
1635
|
-
request['tpTriggerPx'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
|
|
1636
|
-
const takeProfitLimitPrice = this.safeValueN(takeProfit, ['price', 'takeProfitPrice', 'tpOrdPx']);
|
|
1637
|
-
const takeProfitOrderType = this.safeString(takeProfit, 'type');
|
|
1638
|
-
if (takeProfitOrderType !== undefined) {
|
|
1639
|
-
const takeProfitLimitOrderType = (takeProfitOrderType === 'limit');
|
|
1640
|
-
const takeProfitMarketOrderType = (takeProfitOrderType === 'market');
|
|
1641
|
-
if ((!takeProfitLimitOrderType) && (!takeProfitMarketOrderType)) {
|
|
1642
|
-
throw new InvalidOrder(this.id + ' createOrder() params["takeProfit"]["type"] must be either "limit" or "market"');
|
|
1643
|
-
}
|
|
1644
|
-
else if (takeProfitLimitOrderType) {
|
|
1645
|
-
if (takeProfitLimitPrice === undefined) {
|
|
1646
|
-
throw new InvalidOrder(this.id + ' createOrder() requires a limit price in params["takeProfit"]["price"] or params["takeProfit"]["tpOrdPx"] for a take profit limit order');
|
|
1647
|
-
}
|
|
1648
|
-
else {
|
|
1649
|
-
request['tpOrdPx'] = this.priceToPrecision(symbol, takeProfitLimitPrice);
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
else if (takeProfitOrderType === 'market') {
|
|
1653
|
-
request['tpOrdPx'] = '-1';
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
else if (takeProfitLimitPrice !== undefined) {
|
|
1657
|
-
request['tpOrdPx'] = this.priceToPrecision(symbol, takeProfitLimitPrice); // limit tp order
|
|
1658
|
-
}
|
|
1659
|
-
else {
|
|
1660
|
-
request['tpOrdPx'] = '-1'; // market tp order
|
|
1661
|
-
}
|
|
1662
|
-
const takeProfitTriggerPriceType = this.safeString2(takeProfit, 'triggerPriceType', 'tpTriggerPxType', 'last');
|
|
1663
|
-
if (takeProfitTriggerPriceType !== undefined) {
|
|
1664
|
-
if ((takeProfitTriggerPriceType !== 'last') && (takeProfitTriggerPriceType !== 'index') && (takeProfitTriggerPriceType !== 'mark')) {
|
|
1665
|
-
throw new InvalidOrder(this.id + ' createOrder() take profit trigger price type must be one of "last", "index" or "mark"');
|
|
1666
|
-
}
|
|
1667
|
-
request['tpTriggerPxType'] = takeProfitTriggerPriceType;
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
else if (trigger) {
|
|
1672
|
-
request['ordType'] = 'trigger';
|
|
1673
|
-
request['triggerPx'] = this.priceToPrecision(symbol, triggerPrice);
|
|
1674
|
-
request['orderPx'] = isMarketOrder ? '-1' : this.priceToPrecision(symbol, price);
|
|
1675
|
-
}
|
|
1676
|
-
else if (conditional) {
|
|
1677
|
-
request['ordType'] = 'conditional';
|
|
1678
|
-
const twoWayCondition = ((takeProfitPrice !== undefined) && (stopLossPrice !== undefined));
|
|
1679
|
-
// if TP and SL are sent together
|
|
1680
|
-
// as ordType 'conditional' only stop-loss order will be applied
|
|
1681
|
-
if (twoWayCondition) {
|
|
1682
|
-
request['ordType'] = 'oco';
|
|
1683
|
-
}
|
|
1684
|
-
if (takeProfitPrice !== undefined) {
|
|
1685
|
-
request['tpTriggerPx'] = this.priceToPrecision(symbol, takeProfitPrice);
|
|
1686
|
-
request['tpOrdPx'] = (tpOrdPx === undefined) ? '-1' : this.priceToPrecision(symbol, tpOrdPx);
|
|
1687
|
-
request['tpTriggerPxType'] = tpTriggerPxType;
|
|
1688
|
-
}
|
|
1689
|
-
if (stopLossPrice !== undefined) {
|
|
1690
|
-
request['slTriggerPx'] = this.priceToPrecision(symbol, stopLossPrice);
|
|
1691
|
-
request['slOrdPx'] = (slOrdPx === undefined) ? '-1' : this.priceToPrecision(symbol, slOrdPx);
|
|
1692
|
-
request['slTriggerPxType'] = slTriggerPxType;
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
if (clientOrderId === undefined) {
|
|
1696
|
-
const brokerId = this.safeString(this.options, 'brokerId');
|
|
1697
|
-
if (brokerId !== undefined) {
|
|
1698
|
-
request['clOrdId'] = brokerId + this.uuid16();
|
|
1699
|
-
request['tag'] = brokerId;
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
else {
|
|
1703
|
-
request['clOrdId'] = clientOrderId;
|
|
1704
|
-
params = this.omit(params, ['clOrdId', 'clientOrderId']);
|
|
1705
|
-
}
|
|
1706
|
-
return this.extend(request, params);
|
|
1707
|
-
}
|
|
1708
|
-
/**
|
|
1709
|
-
* @method
|
|
1710
|
-
* @name okcoin#cancelOrder
|
|
1711
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-order
|
|
1712
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-algo-order
|
|
1713
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
|
|
1714
|
-
* @description cancels an open order
|
|
1715
|
-
* @param {string} id order id
|
|
1716
|
-
* @param {string} symbol unified symbol of the market the order was made in
|
|
1717
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1718
|
-
* @param {bool} [params.trigger] True if cancel trigger or conditional orders
|
|
1719
|
-
* @param {bool} [params.advanced] True if canceling advanced orders only
|
|
1720
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1721
|
-
*/
|
|
1722
|
-
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1723
|
-
if (symbol === undefined) {
|
|
1724
|
-
throw new ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
|
|
1725
|
-
}
|
|
1726
|
-
await this.loadMarkets();
|
|
1727
|
-
const trigger = this.safeValue2(params, 'stop', 'trigger');
|
|
1728
|
-
const advanced = this.safeValue(params, 'advanced');
|
|
1729
|
-
if (trigger || advanced) {
|
|
1730
|
-
const orderInner = await this.cancelOrders([id], symbol, params);
|
|
1731
|
-
return this.safeDict(orderInner, 0);
|
|
1732
|
-
}
|
|
1733
|
-
const market = this.market(symbol);
|
|
1734
|
-
const request = {
|
|
1735
|
-
'instId': market['id'],
|
|
1736
|
-
// 'ordId': id, // either ordId or clOrdId is required
|
|
1737
|
-
// 'clOrdId': clientOrderId,
|
|
1738
|
-
};
|
|
1739
|
-
const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
|
|
1740
|
-
if (clientOrderId !== undefined) {
|
|
1741
|
-
request['clOrdId'] = clientOrderId;
|
|
1742
|
-
}
|
|
1743
|
-
else {
|
|
1744
|
-
request['ordId'] = id.toString();
|
|
1745
|
-
}
|
|
1746
|
-
const query = this.omit(params, ['clOrdId', 'clientOrderId']);
|
|
1747
|
-
const response = await this.privatePostTradeCancelOrder(this.extend(request, query));
|
|
1748
|
-
// {"code":"0","data":[{"clOrdId":"","ordId":"317251910906576896","sCode":"0","sMsg":""}],"msg":""}
|
|
1749
|
-
const data = this.safeValue(response, 'data', []);
|
|
1750
|
-
const order = this.safeDict(data, 0);
|
|
1751
|
-
return this.parseOrder(order, market);
|
|
1752
|
-
}
|
|
1753
|
-
parseIds(ids) {
|
|
1754
|
-
/**
|
|
1755
|
-
* @ignore
|
|
1756
|
-
* @method
|
|
1757
|
-
* @name okx#parseIds
|
|
1758
|
-
* @param {string[]|string} ids order ids
|
|
1759
|
-
* @returns {string[]} list of order ids
|
|
1760
|
-
*/
|
|
1761
|
-
if (typeof ids === 'string') {
|
|
1762
|
-
return ids.split(',');
|
|
1763
|
-
}
|
|
1764
|
-
else {
|
|
1765
|
-
return ids;
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
/**
|
|
1769
|
-
* @method
|
|
1770
|
-
* @name okcoin#cancelOrders
|
|
1771
|
-
* @description cancel multiple orders
|
|
1772
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-multiple-orders
|
|
1773
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-algo-order
|
|
1774
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
|
|
1775
|
-
* @param {string[]} ids order ids
|
|
1776
|
-
* @param {string} symbol unified market symbol
|
|
1777
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1778
|
-
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1779
|
-
*/
|
|
1780
|
-
async cancelOrders(ids, symbol = undefined, params = {}) {
|
|
1781
|
-
if (symbol === undefined) {
|
|
1782
|
-
throw new ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
|
|
1783
|
-
}
|
|
1784
|
-
await this.loadMarkets();
|
|
1785
|
-
const trigger = this.safeValue2(params, 'stop', 'trigger');
|
|
1786
|
-
const advanced = this.safeValue(params, 'advanced');
|
|
1787
|
-
params = this.omit(params, ['stop', 'trigger', 'advanced']);
|
|
1788
|
-
const market = this.market(symbol);
|
|
1789
|
-
const request = [];
|
|
1790
|
-
const clientOrderIds = this.parseIds(this.safeValue2(params, 'clOrdId', 'clientOrderId'));
|
|
1791
|
-
const algoIds = this.parseIds(this.safeValue(params, 'algoId'));
|
|
1792
|
-
if (clientOrderIds === undefined) {
|
|
1793
|
-
ids = this.parseIds(ids);
|
|
1794
|
-
if (algoIds !== undefined) {
|
|
1795
|
-
for (let i = 0; i < algoIds.length; i++) {
|
|
1796
|
-
request.push({
|
|
1797
|
-
'algoId': algoIds[i],
|
|
1798
|
-
'instId': market['id'],
|
|
1799
|
-
});
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
for (let i = 0; i < ids.length; i++) {
|
|
1803
|
-
if (trigger || advanced) {
|
|
1804
|
-
request.push({
|
|
1805
|
-
'algoId': ids[i],
|
|
1806
|
-
'instId': market['id'],
|
|
1807
|
-
});
|
|
1808
|
-
}
|
|
1809
|
-
else {
|
|
1810
|
-
request.push({
|
|
1811
|
-
'ordId': ids[i],
|
|
1812
|
-
'instId': market['id'],
|
|
1813
|
-
});
|
|
1814
|
-
}
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
else {
|
|
1818
|
-
for (let i = 0; i < clientOrderIds.length; i++) {
|
|
1819
|
-
request.push({
|
|
1820
|
-
'instId': market['id'],
|
|
1821
|
-
'clOrdId': clientOrderIds[i],
|
|
1822
|
-
});
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1825
|
-
let response = undefined;
|
|
1826
|
-
if (trigger) {
|
|
1827
|
-
response = await this.privatePostTradeCancelAlgos(request);
|
|
1828
|
-
}
|
|
1829
|
-
else if (advanced) {
|
|
1830
|
-
response = await this.privatePostTradeCancelAdvanceAlgos(request);
|
|
1831
|
-
}
|
|
1832
|
-
else {
|
|
1833
|
-
response = await this.privatePostTradeCancelBatchOrders(request); // * dont extend with params, otherwise ARRAY will be turned into OBJECT
|
|
1834
|
-
}
|
|
1835
|
-
//
|
|
1836
|
-
// {
|
|
1837
|
-
// "code": "0",
|
|
1838
|
-
// "data": [
|
|
1839
|
-
// {
|
|
1840
|
-
// "clOrdId": "e123456789ec4dBC1123456ba123b45e",
|
|
1841
|
-
// "ordId": "405071912345641543",
|
|
1842
|
-
// "sCode": "0",
|
|
1843
|
-
// "sMsg": ""
|
|
1844
|
-
// },
|
|
1845
|
-
// ...
|
|
1846
|
-
// ],
|
|
1847
|
-
// "msg": ""
|
|
1848
|
-
// }
|
|
1849
|
-
//
|
|
1850
|
-
//
|
|
1851
|
-
const ordersData = this.safeList(response, 'data', []);
|
|
1852
|
-
return this.parseOrders(ordersData, market, undefined, undefined, params);
|
|
1853
|
-
}
|
|
1854
|
-
parseOrderStatus(status) {
|
|
1855
|
-
const statuses = {
|
|
1856
|
-
'canceled': 'canceled',
|
|
1857
|
-
'live': 'open',
|
|
1858
|
-
'partially_filled': 'open',
|
|
1859
|
-
'filled': 'closed',
|
|
1860
|
-
'effective': 'closed',
|
|
1861
|
-
};
|
|
1862
|
-
return this.safeString(statuses, status, status);
|
|
1863
|
-
}
|
|
1864
|
-
parseOrder(order, market = undefined) {
|
|
1865
|
-
//
|
|
1866
|
-
// createOrder
|
|
1867
|
-
//
|
|
1868
|
-
// {
|
|
1869
|
-
// "clOrdId": "oktswap6",
|
|
1870
|
-
// "ordId": "312269865356374016",
|
|
1871
|
-
// "tag": "",
|
|
1872
|
-
// "sCode": "0",
|
|
1873
|
-
// "sMsg": ""
|
|
1874
|
-
// }
|
|
1875
|
-
//
|
|
1876
|
-
// editOrder
|
|
1877
|
-
//
|
|
1878
|
-
// {
|
|
1879
|
-
// "clOrdId": "e847386590ce4dBCc1a045253497a547",
|
|
1880
|
-
// "ordId": "559176536793178112",
|
|
1881
|
-
// "reqId": "",
|
|
1882
|
-
// "sCode": "0",
|
|
1883
|
-
// "sMsg": ""
|
|
1884
|
-
// }
|
|
1885
|
-
//
|
|
1886
|
-
// Spot and Swap fetchOrder, fetchOpenOrders
|
|
1887
|
-
//
|
|
1888
|
-
// {
|
|
1889
|
-
// "accFillSz": "0",
|
|
1890
|
-
// "avgPx": "",
|
|
1891
|
-
// "cTime": "1621910749815",
|
|
1892
|
-
// "category": "normal",
|
|
1893
|
-
// "ccy": "",
|
|
1894
|
-
// "clOrdId": "",
|
|
1895
|
-
// "fee": "0",
|
|
1896
|
-
// "feeCcy": "ETH",
|
|
1897
|
-
// "fillPx": "",
|
|
1898
|
-
// "fillSz": "0",
|
|
1899
|
-
// "fillTime": "",
|
|
1900
|
-
// "instId": "ETH-USDT",
|
|
1901
|
-
// "instType": "SPOT",
|
|
1902
|
-
// "lever": "",
|
|
1903
|
-
// "ordId": "317251910906576896",
|
|
1904
|
-
// "ordType": "limit",
|
|
1905
|
-
// "pnl": "0",
|
|
1906
|
-
// "posSide": "net",
|
|
1907
|
-
// "px": "2000",
|
|
1908
|
-
// "rebate": "0",
|
|
1909
|
-
// "rebateCcy": "USDT",
|
|
1910
|
-
// "side": "buy",
|
|
1911
|
-
// "slOrdPx": "",
|
|
1912
|
-
// "slTriggerPx": "",
|
|
1913
|
-
// "state": "live",
|
|
1914
|
-
// "sz": "0.001",
|
|
1915
|
-
// "tag": "",
|
|
1916
|
-
// "tdMode": "cash",
|
|
1917
|
-
// "tpOrdPx": "",
|
|
1918
|
-
// "tpTriggerPx": "",
|
|
1919
|
-
// "tradeId": "",
|
|
1920
|
-
// "uTime": "1621910749815"
|
|
1921
|
-
// }
|
|
1922
|
-
//
|
|
1923
|
-
// Algo Order fetchOpenOrders, fetchCanceledOrders, fetchClosedOrders
|
|
1924
|
-
//
|
|
1925
|
-
// {
|
|
1926
|
-
// "activePx": "",
|
|
1927
|
-
// "activePxType": "",
|
|
1928
|
-
// "actualPx": "",
|
|
1929
|
-
// "actualSide": "buy",
|
|
1930
|
-
// "actualSz": "0",
|
|
1931
|
-
// "algoId": "431375349042380800",
|
|
1932
|
-
// "cTime": "1649119897778",
|
|
1933
|
-
// "callbackRatio": "",
|
|
1934
|
-
// "callbackSpread": "",
|
|
1935
|
-
// "ccy": "",
|
|
1936
|
-
// "ctVal": "0.01",
|
|
1937
|
-
// "instId": "BTC-USDT-SWAP",
|
|
1938
|
-
// "instType": "SWAP",
|
|
1939
|
-
// "last": "46538.9",
|
|
1940
|
-
// "lever": "125",
|
|
1941
|
-
// "moveTriggerPx": "",
|
|
1942
|
-
// "notionalUsd": "467.059",
|
|
1943
|
-
// "ordId": "",
|
|
1944
|
-
// "ordPx": "50000",
|
|
1945
|
-
// "ordType": "trigger",
|
|
1946
|
-
// "posSide": "long",
|
|
1947
|
-
// "pxLimit": "",
|
|
1948
|
-
// "pxSpread": "",
|
|
1949
|
-
// "pxVar": "",
|
|
1950
|
-
// "side": "buy",
|
|
1951
|
-
// "slOrdPx": "",
|
|
1952
|
-
// "slTriggerPx": "",
|
|
1953
|
-
// "slTriggerPxType": "",
|
|
1954
|
-
// "state": "live",
|
|
1955
|
-
// "sz": "1",
|
|
1956
|
-
// "szLimit": "",
|
|
1957
|
-
// "tag": "",
|
|
1958
|
-
// "tdMode": "isolated",
|
|
1959
|
-
// "tgtCcy": "",
|
|
1960
|
-
// "timeInterval": "",
|
|
1961
|
-
// "tpOrdPx": "",
|
|
1962
|
-
// "tpTriggerPx": "",
|
|
1963
|
-
// "tpTriggerPxType": "",
|
|
1964
|
-
// "triggerPx": "50000",
|
|
1965
|
-
// "triggerPxType": "last",
|
|
1966
|
-
// "triggerTime": "",
|
|
1967
|
-
// "uly": "BTC-USDT"
|
|
1968
|
-
// }
|
|
1969
|
-
//
|
|
1970
|
-
const id = this.safeString2(order, 'algoId', 'ordId');
|
|
1971
|
-
const timestamp = this.safeInteger(order, 'cTime');
|
|
1972
|
-
const lastUpdateTimestamp = this.safeInteger(order, 'uTime');
|
|
1973
|
-
const lastTradeTimestamp = this.safeInteger(order, 'fillTime');
|
|
1974
|
-
const side = this.safeString(order, 'side');
|
|
1975
|
-
let type = this.safeString(order, 'ordType');
|
|
1976
|
-
let postOnly = undefined;
|
|
1977
|
-
let timeInForce = undefined;
|
|
1978
|
-
if (type === 'post_only') {
|
|
1979
|
-
postOnly = true;
|
|
1980
|
-
type = 'limit';
|
|
1981
|
-
}
|
|
1982
|
-
else if (type === 'fok') {
|
|
1983
|
-
timeInForce = 'FOK';
|
|
1984
|
-
type = 'limit';
|
|
1985
|
-
}
|
|
1986
|
-
else if (type === 'ioc') {
|
|
1987
|
-
timeInForce = 'IOC';
|
|
1988
|
-
type = 'limit';
|
|
1989
|
-
}
|
|
1990
|
-
const marketId = this.safeString(order, 'instId');
|
|
1991
|
-
market = this.safeMarket(marketId, market);
|
|
1992
|
-
const symbol = this.safeSymbol(marketId, market, '-');
|
|
1993
|
-
const filled = this.safeString(order, 'accFillSz');
|
|
1994
|
-
const price = this.safeString2(order, 'px', 'ordPx');
|
|
1995
|
-
const average = this.safeString(order, 'avgPx');
|
|
1996
|
-
const status = this.parseOrderStatus(this.safeString(order, 'state'));
|
|
1997
|
-
const feeCostString = this.safeString(order, 'fee');
|
|
1998
|
-
let amount = undefined;
|
|
1999
|
-
let cost = undefined;
|
|
2000
|
-
// spot market buy: "sz" can refer either to base currency units or to quote currency units
|
|
2001
|
-
// see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order
|
|
2002
|
-
const defaultTgtCcy = this.safeString(this.options, 'tgtCcy', 'base_ccy');
|
|
2003
|
-
const tgtCcy = this.safeString(order, 'tgtCcy', defaultTgtCcy);
|
|
2004
|
-
if ((side === 'buy') && (type === 'market') && (tgtCcy === 'quote_ccy')) {
|
|
2005
|
-
// "sz" refers to the cost
|
|
2006
|
-
cost = this.safeString(order, 'sz');
|
|
2007
|
-
}
|
|
2008
|
-
else {
|
|
2009
|
-
// "sz" refers to the trade currency amount
|
|
2010
|
-
amount = this.safeString(order, 'sz');
|
|
2011
|
-
}
|
|
2012
|
-
let fee = undefined;
|
|
2013
|
-
if (feeCostString !== undefined) {
|
|
2014
|
-
const feeCostSigned = Precise.stringNeg(feeCostString);
|
|
2015
|
-
const feeCurrencyId = this.safeString(order, 'feeCcy');
|
|
2016
|
-
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
2017
|
-
fee = {
|
|
2018
|
-
'cost': this.parseNumber(feeCostSigned),
|
|
2019
|
-
'currency': feeCurrencyCode,
|
|
2020
|
-
};
|
|
2021
|
-
}
|
|
2022
|
-
let clientOrderId = this.safeString(order, 'clOrdId');
|
|
2023
|
-
if ((clientOrderId !== undefined) && (clientOrderId.length < 1)) {
|
|
2024
|
-
clientOrderId = undefined; // fix empty clientOrderId string
|
|
2025
|
-
}
|
|
2026
|
-
const stopLossPrice = this.safeNumber2(order, 'slTriggerPx', 'slOrdPx');
|
|
2027
|
-
const takeProfitPrice = this.safeNumber2(order, 'tpTriggerPx', 'tpOrdPx');
|
|
2028
|
-
const reduceOnlyRaw = this.safeString(order, 'reduceOnly');
|
|
2029
|
-
let reduceOnly = false;
|
|
2030
|
-
if (reduceOnly !== undefined) {
|
|
2031
|
-
reduceOnly = (reduceOnlyRaw === 'true');
|
|
2032
|
-
}
|
|
2033
|
-
return this.safeOrder({
|
|
2034
|
-
'info': order,
|
|
2035
|
-
'id': id,
|
|
2036
|
-
'clientOrderId': clientOrderId,
|
|
2037
|
-
'timestamp': timestamp,
|
|
2038
|
-
'datetime': this.iso8601(timestamp),
|
|
2039
|
-
'lastTradeTimestamp': lastTradeTimestamp,
|
|
2040
|
-
'lastUpdateTimestamp': lastUpdateTimestamp,
|
|
2041
|
-
'symbol': symbol,
|
|
2042
|
-
'type': type,
|
|
2043
|
-
'timeInForce': timeInForce,
|
|
2044
|
-
'postOnly': postOnly,
|
|
2045
|
-
'side': side,
|
|
2046
|
-
'price': price,
|
|
2047
|
-
'stopLossPrice': stopLossPrice,
|
|
2048
|
-
'takeProfitPrice': takeProfitPrice,
|
|
2049
|
-
'triggerPrice': this.safeNumberN(order, ['triggerPx', 'moveTriggerPx']),
|
|
2050
|
-
'average': average,
|
|
2051
|
-
'cost': cost,
|
|
2052
|
-
'amount': amount,
|
|
2053
|
-
'filled': filled,
|
|
2054
|
-
'remaining': undefined,
|
|
2055
|
-
'status': status,
|
|
2056
|
-
'fee': fee,
|
|
2057
|
-
'trades': undefined,
|
|
2058
|
-
'reduceOnly': reduceOnly,
|
|
2059
|
-
}, market);
|
|
2060
|
-
}
|
|
2061
|
-
/**
|
|
2062
|
-
* @method
|
|
2063
|
-
* @name okcoin#fetchOrder
|
|
2064
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-details
|
|
2065
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-list
|
|
2066
|
-
* @description fetches information on an order made by the user
|
|
2067
|
-
* @param {string} id order id
|
|
2068
|
-
* @param {string} symbol unified symbol of the market the order was made in
|
|
2069
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2070
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2071
|
-
*/
|
|
2072
|
-
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
2073
|
-
if (symbol === undefined) {
|
|
2074
|
-
throw new ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
|
|
2075
|
-
}
|
|
2076
|
-
await this.loadMarkets();
|
|
2077
|
-
const market = this.market(symbol);
|
|
2078
|
-
const request = {
|
|
2079
|
-
'instId': market['id'],
|
|
2080
|
-
// 'clOrdId': 'abcdef12345', // optional, [a-z0-9]{1,32}
|
|
2081
|
-
// 'ordId': id,
|
|
2082
|
-
};
|
|
2083
|
-
const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
|
|
2084
|
-
const trigger = this.safeValue2(params, 'stop', 'trigger');
|
|
2085
|
-
if (trigger) {
|
|
2086
|
-
if (clientOrderId !== undefined) {
|
|
2087
|
-
request['algoClOrdId'] = clientOrderId;
|
|
2088
|
-
}
|
|
2089
|
-
else {
|
|
2090
|
-
request['algoId'] = id;
|
|
2091
|
-
}
|
|
2092
|
-
}
|
|
2093
|
-
else {
|
|
2094
|
-
if (clientOrderId !== undefined) {
|
|
2095
|
-
request['clOrdId'] = clientOrderId;
|
|
2096
|
-
}
|
|
2097
|
-
else {
|
|
2098
|
-
request['ordId'] = id;
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
const query = this.omit(params, ['clientOrderId', 'stop', 'trigger']);
|
|
2102
|
-
let response = undefined;
|
|
2103
|
-
if (trigger) {
|
|
2104
|
-
response = await this.privateGetTradeOrderAlgo(this.extend(request, query));
|
|
2105
|
-
}
|
|
2106
|
-
else {
|
|
2107
|
-
response = await this.privateGetTradeOrder(this.extend(request, query));
|
|
2108
|
-
}
|
|
2109
|
-
const data = this.safeValue(response, 'data', []);
|
|
2110
|
-
const order = this.safeDict(data, 0);
|
|
2111
|
-
return this.parseOrder(order);
|
|
2112
|
-
}
|
|
2113
|
-
/**
|
|
2114
|
-
* @method
|
|
2115
|
-
* @name okcoin#fetchOpenOrders
|
|
2116
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-list
|
|
2117
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-list
|
|
2118
|
-
* @description fetch all unfilled currently open orders
|
|
2119
|
-
* @param {string} symbol unified market symbol
|
|
2120
|
-
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
2121
|
-
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
2122
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2123
|
-
* @param {bool} [params.trigger] True if fetching trigger or conditional orders
|
|
2124
|
-
* @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
|
|
2125
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2126
|
-
*/
|
|
2127
|
-
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2128
|
-
await this.loadMarkets();
|
|
2129
|
-
const request = {
|
|
2130
|
-
// 'instId': market['id'],
|
|
2131
|
-
// 'ordType': 'limit', // market, limit, post_only, fok, ioc, comma-separated, stop orders: conditional, oco, trigger, move_order_stop, iceberg, or twap
|
|
2132
|
-
// 'state': 'live', // live, partially_filled
|
|
2133
|
-
// 'after': orderId,
|
|
2134
|
-
// 'before': orderId,
|
|
2135
|
-
// 'limit': limit, // default 100, max 100
|
|
2136
|
-
};
|
|
2137
|
-
let market = undefined;
|
|
2138
|
-
if (symbol !== undefined) {
|
|
2139
|
-
market = this.market(symbol);
|
|
2140
|
-
request['instId'] = market['id'];
|
|
2141
|
-
}
|
|
2142
|
-
if (limit !== undefined) {
|
|
2143
|
-
request['limit'] = limit; // default 100, max 100
|
|
2144
|
-
}
|
|
2145
|
-
const ordType = this.safeString(params, 'ordType');
|
|
2146
|
-
const trigger = this.safeValue(params, 'stop') || (this.safeString(params, 'ordType') !== undefined);
|
|
2147
|
-
if (trigger && (ordType === undefined)) {
|
|
2148
|
-
request['ordType'] = 'trigger'; // default to trigger
|
|
2149
|
-
}
|
|
2150
|
-
params = this.omit(params, ['stop']);
|
|
2151
|
-
let response = undefined;
|
|
2152
|
-
if (trigger) {
|
|
2153
|
-
response = await this.privateGetTradeOrdersAlgoPending(this.extend(request, params));
|
|
2154
|
-
}
|
|
2155
|
-
else {
|
|
2156
|
-
response = await this.privateGetTradeOrdersPending(this.extend(request, params));
|
|
2157
|
-
}
|
|
2158
|
-
const data = this.safeList(response, 'data', []);
|
|
2159
|
-
return this.parseOrders(data, market, since, limit);
|
|
2160
|
-
}
|
|
2161
|
-
/**
|
|
2162
|
-
* @method
|
|
2163
|
-
* @name okcoin#fetchClosedOrders
|
|
2164
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-history
|
|
2165
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-history-last-3-months
|
|
2166
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-history-last-7-days
|
|
2167
|
-
* @description fetches information on multiple closed orders made by the user
|
|
2168
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
2169
|
-
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2170
|
-
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
2171
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2172
|
-
* @param {bool} [params.trigger] True if fetching trigger or conditional orders
|
|
2173
|
-
* @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
|
|
2174
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2175
|
-
*/
|
|
2176
|
-
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2177
|
-
await this.loadMarkets();
|
|
2178
|
-
const request = {
|
|
2179
|
-
'instType': 'SPOT',
|
|
2180
|
-
};
|
|
2181
|
-
let market = undefined;
|
|
2182
|
-
if (symbol !== undefined) {
|
|
2183
|
-
market = this.market(symbol);
|
|
2184
|
-
request['instId'] = market['id'];
|
|
2185
|
-
}
|
|
2186
|
-
const ordType = this.safeString(params, 'ordType');
|
|
2187
|
-
const trigger = this.safeValue(params, 'stop') || (this.safeString(params, 'ordType') !== undefined);
|
|
2188
|
-
if (trigger && (ordType === undefined)) {
|
|
2189
|
-
request['ordType'] = 'trigger'; // default to trigger
|
|
2190
|
-
}
|
|
2191
|
-
params = this.omit(params, ['stop']);
|
|
2192
|
-
let response = undefined;
|
|
2193
|
-
if (trigger) {
|
|
2194
|
-
response = await this.privateGetTradeOrdersAlgoHistory(this.extend(request, params));
|
|
2195
|
-
}
|
|
2196
|
-
else {
|
|
2197
|
-
let method = undefined;
|
|
2198
|
-
[method, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'method', 'privateGetTradeOrdersHistory');
|
|
2199
|
-
if (method === 'privateGetTradeOrdersHistory') {
|
|
2200
|
-
response = await this.privateGetTradeOrdersHistory(this.extend(request, params));
|
|
2201
|
-
}
|
|
2202
|
-
else {
|
|
2203
|
-
response = await this.privateGetTradeOrdersHistoryArchive(this.extend(request, params));
|
|
2204
|
-
}
|
|
2205
|
-
}
|
|
2206
|
-
// {
|
|
2207
|
-
// "code": "0",
|
|
2208
|
-
// "data": [
|
|
2209
|
-
// {
|
|
2210
|
-
// "accFillSz": "0",
|
|
2211
|
-
// "avgPx": "",
|
|
2212
|
-
// "cTime": "1621910749815",
|
|
2213
|
-
// "category": "normal",
|
|
2214
|
-
// "ccy": "",
|
|
2215
|
-
// "clOrdId": "",
|
|
2216
|
-
// "fee": "0",
|
|
2217
|
-
// "feeCcy": "ETH",
|
|
2218
|
-
// "fillPx": "",
|
|
2219
|
-
// "fillSz": "0",
|
|
2220
|
-
// "fillTime": "",
|
|
2221
|
-
// "instId": "ETH-USDT",
|
|
2222
|
-
// "instType": "SPOT",
|
|
2223
|
-
// "lever": "",
|
|
2224
|
-
// "ordId": "317251910906576896",
|
|
2225
|
-
// "ordType": "limit",
|
|
2226
|
-
// "pnl": "0",
|
|
2227
|
-
// "posSide": "net",
|
|
2228
|
-
// "px":"20 00",
|
|
2229
|
-
// "rebate": "0",
|
|
2230
|
-
// "rebateCcy": "USDT",
|
|
2231
|
-
// "side": "buy",
|
|
2232
|
-
// "slOrdPx": "",
|
|
2233
|
-
// "slTriggerPx": "",
|
|
2234
|
-
// "state": "live",
|
|
2235
|
-
// "sz":"0. 001",
|
|
2236
|
-
// "tag": "",
|
|
2237
|
-
// "tdMode": "cash",
|
|
2238
|
-
// "tpOrdPx": "",
|
|
2239
|
-
// "tpTriggerPx": "",
|
|
2240
|
-
// "tradeId": "",
|
|
2241
|
-
// "uTime": "1621910749815"
|
|
2242
|
-
// }
|
|
2243
|
-
// ],
|
|
2244
|
-
// "msg":""
|
|
2245
|
-
// }
|
|
2246
|
-
//
|
|
2247
|
-
const data = this.safeList(response, 'data', []);
|
|
2248
|
-
return this.parseOrders(data, market, since, limit);
|
|
2249
|
-
}
|
|
2250
|
-
parseDepositAddress(depositAddress, currency = undefined) {
|
|
2251
|
-
//
|
|
2252
|
-
// {
|
|
2253
|
-
// "addr": "okbtothemoon",
|
|
2254
|
-
// "memo": "971668", // may be missing
|
|
2255
|
-
// "tag":"52055", // may be missing
|
|
2256
|
-
// "pmtId": "", // may be missing
|
|
2257
|
-
// "ccy": "BTC",
|
|
2258
|
-
// "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account
|
|
2259
|
-
// "selected": true
|
|
2260
|
-
// }
|
|
2261
|
-
//
|
|
2262
|
-
// {
|
|
2263
|
-
// "ccy":"usdt-erc20",
|
|
2264
|
-
// "to":"6",
|
|
2265
|
-
// "addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa",
|
|
2266
|
-
// "selected":true
|
|
2267
|
-
// }
|
|
2268
|
-
//
|
|
2269
|
-
// {
|
|
2270
|
-
// "chain": "ETH-OKExChain",
|
|
2271
|
-
// "addrEx": { "comment": "6040348" }, // some currencies like TON may have this field,
|
|
2272
|
-
// "ctAddr": "72315c",
|
|
2273
|
-
// "ccy": "ETH",
|
|
2274
|
-
// "to": "6",
|
|
2275
|
-
// "addr": "0x1c9f2244d1ccaa060bd536827c18925db10db102",
|
|
2276
|
-
// "selected": true
|
|
2277
|
-
// }
|
|
2278
|
-
//
|
|
2279
|
-
const address = this.safeString(depositAddress, 'addr');
|
|
2280
|
-
let tag = this.safeStringN(depositAddress, ['tag', 'pmtId', 'memo']);
|
|
2281
|
-
if (tag === undefined) {
|
|
2282
|
-
const addrEx = this.safeValue(depositAddress, 'addrEx', {});
|
|
2283
|
-
tag = this.safeString(addrEx, 'comment');
|
|
2284
|
-
}
|
|
2285
|
-
const currencyId = this.safeString(depositAddress, 'ccy');
|
|
2286
|
-
currency = this.safeCurrency(currencyId, currency);
|
|
2287
|
-
const code = currency['code'];
|
|
2288
|
-
const chain = this.safeString(depositAddress, 'chain');
|
|
2289
|
-
const networkId = chain.replace(currencyId + '-', '');
|
|
2290
|
-
const network = this.networkIdToCode(networkId);
|
|
2291
|
-
// inconsistent naming responses from exchange
|
|
2292
|
-
// with respect to network naming provided in currency info vs address chain-names and ids
|
|
2293
|
-
//
|
|
2294
|
-
// response from address endpoint:
|
|
2295
|
-
// {
|
|
2296
|
-
// "chain": "USDT-Polygon",
|
|
2297
|
-
// "ctAddr": "",
|
|
2298
|
-
// "ccy": "USDT",
|
|
2299
|
-
// "to":"6" ,
|
|
2300
|
-
// "addr": "0x1903441e386cc49d937f6302955b5feb4286dcfa",
|
|
2301
|
-
// "selected": true
|
|
2302
|
-
// }
|
|
2303
|
-
// network information from currency['networks'] field:
|
|
2304
|
-
// Polygon: {
|
|
2305
|
-
// "info": {
|
|
2306
|
-
// "canDep": false,
|
|
2307
|
-
// "canInternal": false,
|
|
2308
|
-
// "canWd": false,
|
|
2309
|
-
// "ccy": "USDT",
|
|
2310
|
-
// "chain": "USDT-Polygon-Bridge",
|
|
2311
|
-
// "mainNet": false,
|
|
2312
|
-
// "maxFee": "26.879528",
|
|
2313
|
-
// "minFee": "13.439764",
|
|
2314
|
-
// "minWd": "0.001",
|
|
2315
|
-
// "name": ''
|
|
2316
|
-
// },
|
|
2317
|
-
// "id": "USDT-Polygon-Bridge",
|
|
2318
|
-
// "network": "Polygon",
|
|
2319
|
-
// "active": false,
|
|
2320
|
-
// "deposit": false,
|
|
2321
|
-
// "withdraw": false,
|
|
2322
|
-
// "fee": 13.439764,
|
|
2323
|
-
// "precision": undefined,
|
|
2324
|
-
// "limits": {
|
|
2325
|
-
// "withdraw": {
|
|
2326
|
-
// "min": 0.001,
|
|
2327
|
-
// "max": undefined
|
|
2328
|
-
// }
|
|
2329
|
-
// }
|
|
2330
|
-
// },
|
|
2331
|
-
//
|
|
2332
|
-
this.checkAddress(address);
|
|
2333
|
-
return {
|
|
2334
|
-
'info': depositAddress,
|
|
2335
|
-
'currency': code,
|
|
2336
|
-
'network': network,
|
|
2337
|
-
'address': address,
|
|
2338
|
-
'tag': tag,
|
|
2339
|
-
};
|
|
2340
|
-
}
|
|
2341
|
-
/**
|
|
2342
|
-
* @method
|
|
2343
|
-
* @name okcoin#fetchDepositAddress
|
|
2344
|
-
* @description fetch the deposit address for a currency associated with this account
|
|
2345
|
-
* @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
|
|
2346
|
-
* @param {string} code unified currency code
|
|
2347
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2348
|
-
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
2349
|
-
*/
|
|
2350
|
-
async fetchDepositAddress(code, params = {}) {
|
|
2351
|
-
await this.loadMarkets();
|
|
2352
|
-
const defaultNetwork = this.safeString(this.options, 'defaultNetwork', 'ERC20');
|
|
2353
|
-
const networkId = this.safeString(params, 'network', defaultNetwork);
|
|
2354
|
-
const networkCode = this.networkIdToCode(networkId);
|
|
2355
|
-
params = this.omit(params, 'network');
|
|
2356
|
-
const response = await this.fetchDepositAddressesByNetwork(code, params);
|
|
2357
|
-
const result = this.safeValue(response, networkCode);
|
|
2358
|
-
if (result === undefined) {
|
|
2359
|
-
throw new InvalidAddress(this.id + ' fetchDepositAddress() cannot find ' + networkCode + ' deposit address for ' + code);
|
|
2360
|
-
}
|
|
2361
|
-
return result;
|
|
2362
|
-
}
|
|
2363
|
-
/**
|
|
2364
|
-
* @method
|
|
2365
|
-
* @name okcoin#fetchDepositAddressesByNetwork
|
|
2366
|
-
* @description fetch a dictionary of addresses for a currency, indexed by network
|
|
2367
|
-
* @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
|
|
2368
|
-
* @param {string} code unified currency code of the currency for the deposit address
|
|
2369
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2370
|
-
* @returns {object} a dictionary of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure} indexed by the network
|
|
2371
|
-
*/
|
|
2372
|
-
async fetchDepositAddressesByNetwork(code, params = {}) {
|
|
2373
|
-
await this.loadMarkets();
|
|
2374
|
-
const currency = this.currency(code);
|
|
2375
|
-
const request = {
|
|
2376
|
-
'ccy': currency['id'],
|
|
2377
|
-
};
|
|
2378
|
-
const response = await this.privateGetAssetDepositAddress(this.extend(request, params));
|
|
2379
|
-
//
|
|
2380
|
-
// {
|
|
2381
|
-
// "code": "0",
|
|
2382
|
-
// "msg": "",
|
|
2383
|
-
// "data": [
|
|
2384
|
-
// {
|
|
2385
|
-
// "addr": "okbtothemoon",
|
|
2386
|
-
// "memo": "971668", // may be missing
|
|
2387
|
-
// "tag":"52055", // may be missing
|
|
2388
|
-
// "pmtId": "", // may be missing
|
|
2389
|
-
// "ccy": "BTC",
|
|
2390
|
-
// "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account
|
|
2391
|
-
// "selected": true
|
|
2392
|
-
// },
|
|
2393
|
-
// // {"ccy":"usdt-erc20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
|
|
2394
|
-
// // {"ccy":"usdt-trc20","to":"6","addr":"TRrd5SiSZrfQVRKm4e9SRSbn2LNTYqCjqx","selected":true},
|
|
2395
|
-
// // {"ccy":"usdt_okexchain","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
|
|
2396
|
-
// // {"ccy":"usdt_kip20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
|
|
2397
|
-
// ]
|
|
2398
|
-
// }
|
|
2399
|
-
//
|
|
2400
|
-
const data = this.safeValue(response, 'data', []);
|
|
2401
|
-
const filtered = this.filterBy(data, 'selected', true);
|
|
2402
|
-
const parsed = this.parseDepositAddresses(filtered, [currency['code']], false);
|
|
2403
|
-
return this.indexBy(parsed, 'network');
|
|
2404
|
-
}
|
|
2405
|
-
/**
|
|
2406
|
-
* @method
|
|
2407
|
-
* @name okcoin#transfer
|
|
2408
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-funds-transfer
|
|
2409
|
-
* @description transfer currency internally between wallets on the same account
|
|
2410
|
-
* @param {string} code unified currency code
|
|
2411
|
-
* @param {float} amount amount to transfer
|
|
2412
|
-
* @param {string} fromAccount account to transfer from
|
|
2413
|
-
* @param {string} toAccount account to transfer to
|
|
2414
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2415
|
-
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
2416
|
-
*/
|
|
2417
|
-
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
2418
|
-
await this.loadMarkets();
|
|
2419
|
-
const currency = this.currency(code);
|
|
2420
|
-
const accountsByType = this.safeValue(this.options, 'accountsByType', {});
|
|
2421
|
-
const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
|
|
2422
|
-
const toId = this.safeString(accountsByType, toAccount, toAccount);
|
|
2423
|
-
const request = {
|
|
2424
|
-
'ccy': currency['id'],
|
|
2425
|
-
'amt': this.currencyToPrecision(code, amount),
|
|
2426
|
-
'type': '0',
|
|
2427
|
-
'from': fromId,
|
|
2428
|
-
'to': toId, // beneficiary account, 6: Funding account, 18: Trading account
|
|
2429
|
-
// 'subAcct': 'sub-account-name', // optional, only required when type is 1, 2 or 4
|
|
2430
|
-
// 'loanTrans': false, // Whether or not borrowed coins can be transferred out under Multi-currency margin and Portfolio margin. The default is false
|
|
2431
|
-
// 'clientId': 'client-supplied id', // A combination of case-sensitive alphanumerics, all numbers, or all letters of up to 32 characters
|
|
2432
|
-
// 'omitPosRisk': false, // Ignore position risk. Default is false. Applicable to Portfolio margin
|
|
2433
|
-
};
|
|
2434
|
-
if (fromId === 'master') {
|
|
2435
|
-
request['type'] = '1';
|
|
2436
|
-
request['subAcct'] = toId;
|
|
2437
|
-
request['from'] = this.safeString(params, 'from', '6');
|
|
2438
|
-
request['to'] = this.safeString(params, 'to', '6');
|
|
2439
|
-
}
|
|
2440
|
-
else if (toId === 'master') {
|
|
2441
|
-
request['type'] = '2';
|
|
2442
|
-
request['subAcct'] = fromId;
|
|
2443
|
-
request['from'] = this.safeString(params, 'from', '6');
|
|
2444
|
-
request['to'] = this.safeString(params, 'to', '6');
|
|
2445
|
-
}
|
|
2446
|
-
const response = await this.privatePostAssetTransfer(this.extend(request, params));
|
|
2447
|
-
//
|
|
2448
|
-
// {
|
|
2449
|
-
// "code": "0",
|
|
2450
|
-
// "msg": "",
|
|
2451
|
-
// "data": [
|
|
2452
|
-
// {
|
|
2453
|
-
// "transId": "754147",
|
|
2454
|
-
// "ccy": "USDT",
|
|
2455
|
-
// "from": "6",
|
|
2456
|
-
// "amt": "0.1",
|
|
2457
|
-
// "to": "18"
|
|
2458
|
-
// }
|
|
2459
|
-
// ]
|
|
2460
|
-
// }
|
|
2461
|
-
//
|
|
2462
|
-
const data = this.safeValue(response, 'data', []);
|
|
2463
|
-
const rawTransfer = this.safeDict(data, 0, {});
|
|
2464
|
-
return this.parseTransfer(rawTransfer, currency);
|
|
2465
|
-
}
|
|
2466
|
-
parseTransfer(transfer, currency = undefined) {
|
|
2467
|
-
//
|
|
2468
|
-
// transfer
|
|
2469
|
-
//
|
|
2470
|
-
// {
|
|
2471
|
-
// "transId": "754147",
|
|
2472
|
-
// "ccy": "USDT",
|
|
2473
|
-
// "from": "6",
|
|
2474
|
-
// "amt": "0.1",
|
|
2475
|
-
// "to": "18"
|
|
2476
|
-
// }
|
|
2477
|
-
//
|
|
2478
|
-
// fetchTransfer
|
|
2479
|
-
//
|
|
2480
|
-
// {
|
|
2481
|
-
// "amt": "5",
|
|
2482
|
-
// "ccy": "USDT",
|
|
2483
|
-
// "from": "18",
|
|
2484
|
-
// "instId": "",
|
|
2485
|
-
// "state": "success",
|
|
2486
|
-
// "subAcct": "",
|
|
2487
|
-
// "to": "6",
|
|
2488
|
-
// "toInstId": "",
|
|
2489
|
-
// "transId": "464424732",
|
|
2490
|
-
// "type": "0"
|
|
2491
|
-
// }
|
|
2492
|
-
//
|
|
2493
|
-
// fetchTransfers
|
|
2494
|
-
//
|
|
2495
|
-
// {
|
|
2496
|
-
// "bal": "70.6874353780312913",
|
|
2497
|
-
// "balChg": "-4.0000000000000000", // negative means "to funding", positive meand "from funding"
|
|
2498
|
-
// "billId": "588900695232225299",
|
|
2499
|
-
// "ccy": "USDT",
|
|
2500
|
-
// "execType": "",
|
|
2501
|
-
// "fee": "",
|
|
2502
|
-
// "from": "18",
|
|
2503
|
-
// "instId": "",
|
|
2504
|
-
// "instType": "",
|
|
2505
|
-
// "mgnMode": "",
|
|
2506
|
-
// "notes": "To Funding Account",
|
|
2507
|
-
// "ordId": "",
|
|
2508
|
-
// "pnl": "",
|
|
2509
|
-
// "posBal": "",
|
|
2510
|
-
// "posBalChg": "",
|
|
2511
|
-
// "price": "0",
|
|
2512
|
-
// "subType": "12",
|
|
2513
|
-
// "sz": "-4",
|
|
2514
|
-
// "to": "6",
|
|
2515
|
-
// "ts": "1686676866989",
|
|
2516
|
-
// "type": "1"
|
|
2517
|
-
// }
|
|
2518
|
-
//
|
|
2519
|
-
const id = this.safeString2(transfer, 'transId', 'billId');
|
|
2520
|
-
const currencyId = this.safeString(transfer, 'ccy');
|
|
2521
|
-
const code = this.safeCurrencyCode(currencyId, currency);
|
|
2522
|
-
let amount = this.safeNumber(transfer, 'amt');
|
|
2523
|
-
const fromAccountId = this.safeString(transfer, 'from');
|
|
2524
|
-
const toAccountId = this.safeString(transfer, 'to');
|
|
2525
|
-
const accountsById = this.safeValue(this.options, 'accountsById', {});
|
|
2526
|
-
const timestamp = this.safeInteger(transfer, 'ts', this.milliseconds());
|
|
2527
|
-
const balanceChange = this.safeString(transfer, 'sz');
|
|
2528
|
-
if (balanceChange !== undefined) {
|
|
2529
|
-
amount = this.parseNumber(Precise.stringAbs(balanceChange));
|
|
2530
|
-
}
|
|
2531
|
-
return {
|
|
2532
|
-
'info': transfer,
|
|
2533
|
-
'id': id,
|
|
2534
|
-
'timestamp': timestamp,
|
|
2535
|
-
'datetime': this.iso8601(timestamp),
|
|
2536
|
-
'currency': code,
|
|
2537
|
-
'amount': amount,
|
|
2538
|
-
'fromAccount': this.safeString(accountsById, fromAccountId),
|
|
2539
|
-
'toAccount': this.safeString(accountsById, toAccountId),
|
|
2540
|
-
'status': this.parseTransferStatus(this.safeString(transfer, 'state')),
|
|
2541
|
-
};
|
|
2542
|
-
}
|
|
2543
|
-
parseTransferStatus(status) {
|
|
2544
|
-
const statuses = {
|
|
2545
|
-
'success': 'ok',
|
|
2546
|
-
};
|
|
2547
|
-
return this.safeString(statuses, status, status);
|
|
2548
|
-
}
|
|
2549
|
-
/**
|
|
2550
|
-
* @method
|
|
2551
|
-
* @name okcoin#withdraw
|
|
2552
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-withdrawal
|
|
2553
|
-
* @description make a withdrawal
|
|
2554
|
-
* @param {string} code unified currency code
|
|
2555
|
-
* @param {float} amount the amount to withdraw
|
|
2556
|
-
* @param {string} address the address to withdraw to
|
|
2557
|
-
* @param {string} tag
|
|
2558
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2559
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2560
|
-
*/
|
|
2561
|
-
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2562
|
-
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
2563
|
-
this.checkAddress(address);
|
|
2564
|
-
await this.loadMarkets();
|
|
2565
|
-
const currency = this.currency(code);
|
|
2566
|
-
if ((tag !== undefined) && (tag.length > 0)) {
|
|
2567
|
-
address = address + ':' + tag;
|
|
2568
|
-
}
|
|
2569
|
-
const request = {
|
|
2570
|
-
'ccy': currency['id'],
|
|
2571
|
-
'toAddr': address,
|
|
2572
|
-
'dest': '4',
|
|
2573
|
-
'amt': this.numberToString(amount),
|
|
2574
|
-
};
|
|
2575
|
-
let network = this.safeString(params, 'network'); // this line allows the user to specify either ERC20 or ETH
|
|
2576
|
-
if (network !== undefined) {
|
|
2577
|
-
const networks = this.safeValue(this.options, 'networks', {});
|
|
2578
|
-
network = this.safeString(networks, network.toUpperCase(), network); // handle ETH>ERC20 alias
|
|
2579
|
-
request['chain'] = currency['id'] + '-' + network;
|
|
2580
|
-
params = this.omit(params, 'network');
|
|
2581
|
-
}
|
|
2582
|
-
let fee = this.safeString(params, 'fee');
|
|
2583
|
-
if (fee === undefined) {
|
|
2584
|
-
const targetNetwork = this.safeValue(currency['networks'], this.networkIdToCode(network), {});
|
|
2585
|
-
fee = this.safeString(targetNetwork, 'fee');
|
|
2586
|
-
if (fee === undefined) {
|
|
2587
|
-
throw new ArgumentsRequired(this.id + ' withdraw() requires a "fee" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set "0". Withdrawing to external digital asset address requires network transaction fee.');
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
request['fee'] = this.numberToString(fee); // withdrawals to OKCoin or OKX are fee-free, please set 0
|
|
2591
|
-
const response = await this.privatePostAssetWithdrawal(this.extend(request, params));
|
|
2592
|
-
//
|
|
2593
|
-
// {
|
|
2594
|
-
// "code": "0",
|
|
2595
|
-
// "msg": "",
|
|
2596
|
-
// "data": [
|
|
2597
|
-
// {
|
|
2598
|
-
// "amt": "0.1",
|
|
2599
|
-
// "wdId": "67485",
|
|
2600
|
-
// "ccy": "BTC"
|
|
2601
|
-
// }
|
|
2602
|
-
// ]
|
|
2603
|
-
// }
|
|
2604
|
-
//
|
|
2605
|
-
const data = this.safeValue(response, 'data', []);
|
|
2606
|
-
const transaction = this.safeDict(data, 0);
|
|
2607
|
-
return this.parseTransaction(transaction, currency);
|
|
2608
|
-
}
|
|
2609
|
-
/**
|
|
2610
|
-
* @method
|
|
2611
|
-
* @name okcoin#fetchDeposits
|
|
2612
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-get-deposit-history
|
|
2613
|
-
* @description fetch all deposits made to an account
|
|
2614
|
-
* @param {string} code unified currency code
|
|
2615
|
-
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
2616
|
-
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
2617
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2618
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2619
|
-
*/
|
|
2620
|
-
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2621
|
-
await this.loadMarkets();
|
|
2622
|
-
let request = {
|
|
2623
|
-
// 'ccy': currency['id'],
|
|
2624
|
-
// 'state': 2, // 0 waiting for confirmation, 1 deposit credited, 2 deposit successful
|
|
2625
|
-
// 'after': since,
|
|
2626
|
-
// 'before' this.milliseconds (),
|
|
2627
|
-
// 'limit': limit, // default 100, max 100
|
|
2628
|
-
};
|
|
2629
|
-
let currency = undefined;
|
|
2630
|
-
if (code !== undefined) {
|
|
2631
|
-
currency = this.currency(code);
|
|
2632
|
-
request['ccy'] = currency['id'];
|
|
2633
|
-
}
|
|
2634
|
-
if (since !== undefined) {
|
|
2635
|
-
request['before'] = Math.max(since - 1, 0);
|
|
2636
|
-
}
|
|
2637
|
-
if (limit !== undefined) {
|
|
2638
|
-
request['limit'] = limit; // default 100, max 100
|
|
2639
|
-
}
|
|
2640
|
-
[request, params] = this.handleUntilOption('after', request, params);
|
|
2641
|
-
const response = await this.privateGetAssetDepositHistory(this.extend(request, params));
|
|
2642
|
-
//
|
|
2643
|
-
// {
|
|
2644
|
-
// "code": "0",
|
|
2645
|
-
// "msg": "",
|
|
2646
|
-
// "data": [
|
|
2647
|
-
// {
|
|
2648
|
-
// "amt": "0.01044408",
|
|
2649
|
-
// "txId": "1915737_3_0_0_asset",
|
|
2650
|
-
// "ccy": "BTC",
|
|
2651
|
-
// "from": "13801825426",
|
|
2652
|
-
// "to": "",
|
|
2653
|
-
// "ts": "1597026383085",
|
|
2654
|
-
// "state": "2",
|
|
2655
|
-
// "depId": "4703879"
|
|
2656
|
-
// },
|
|
2657
|
-
// {
|
|
2658
|
-
// "amt": "491.6784211",
|
|
2659
|
-
// "txId": "1744594_3_184_0_asset",
|
|
2660
|
-
// "ccy": "OKB",
|
|
2661
|
-
// "from": "",
|
|
2662
|
-
// "to": "",
|
|
2663
|
-
// "ts": "1597026383085",
|
|
2664
|
-
// "state": "2",
|
|
2665
|
-
// "depId": "4703809"
|
|
2666
|
-
// },
|
|
2667
|
-
// {
|
|
2668
|
-
// "amt": "223.18782496",
|
|
2669
|
-
// "txId": "6d892c669225b1092c780bf0da0c6f912fc7dc8f6b8cc53b003288624c",
|
|
2670
|
-
// "ccy": "USDT",
|
|
2671
|
-
// "from": "",
|
|
2672
|
-
// "to": "39kK4XvgEuM7rX9frgyHoZkWqx4iKu1spD",
|
|
2673
|
-
// "ts": "1597026383085",
|
|
2674
|
-
// "state": "2",
|
|
2675
|
-
// "depId": "4703779"
|
|
2676
|
-
// }
|
|
2677
|
-
// ]
|
|
2678
|
-
// }
|
|
2679
|
-
//
|
|
2680
|
-
const data = this.safeList(response, 'data', []);
|
|
2681
|
-
return this.parseTransactions(data, currency, since, limit, params);
|
|
2682
|
-
}
|
|
2683
|
-
/**
|
|
2684
|
-
* @method
|
|
2685
|
-
* @name okcoin#fetchWithdrawals
|
|
2686
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
|
|
2687
|
-
* @description fetch all withdrawals made from an account
|
|
2688
|
-
* @param {string} code unified currency code
|
|
2689
|
-
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
2690
|
-
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
2691
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2692
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2693
|
-
*/
|
|
2694
|
-
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2695
|
-
await this.loadMarkets();
|
|
2696
|
-
let request = {
|
|
2697
|
-
// 'ccy': currency['id'],
|
|
2698
|
-
// 'state': 2, // -3: pending cancel, -2 canceled, -1 failed, 0, pending, 1 sending, 2 sent, 3 awaiting email verification, 4 awaiting manual verification, 5 awaiting identity verification
|
|
2699
|
-
// 'after': since,
|
|
2700
|
-
// 'before': this.milliseconds (),
|
|
2701
|
-
// 'limit': limit, // default 100, max 100
|
|
2702
|
-
};
|
|
2703
|
-
let currency = undefined;
|
|
2704
|
-
if (code !== undefined) {
|
|
2705
|
-
currency = this.currency(code);
|
|
2706
|
-
request['ccy'] = currency['id'];
|
|
2707
|
-
}
|
|
2708
|
-
if (since !== undefined) {
|
|
2709
|
-
request['before'] = Math.max(since - 1, 0);
|
|
2710
|
-
}
|
|
2711
|
-
if (limit !== undefined) {
|
|
2712
|
-
request['limit'] = limit; // default 100, max 100
|
|
2713
|
-
}
|
|
2714
|
-
[request, params] = this.handleUntilOption('after', request, params);
|
|
2715
|
-
const response = await this.privateGetAssetWithdrawalHistory(this.extend(request, params));
|
|
2716
|
-
//
|
|
2717
|
-
// {
|
|
2718
|
-
// "code": "0",
|
|
2719
|
-
// "msg": "",
|
|
2720
|
-
// "data": [
|
|
2721
|
-
// {
|
|
2722
|
-
// "amt": "0.094",
|
|
2723
|
-
// "wdId": "4703879",
|
|
2724
|
-
// "fee": "0.01000000eth",
|
|
2725
|
-
// "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85",
|
|
2726
|
-
// "ccy": "ETH",
|
|
2727
|
-
// "from": "13426335357",
|
|
2728
|
-
// "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519",
|
|
2729
|
-
// "ts": "1597026383085",
|
|
2730
|
-
// "state": "2"
|
|
2731
|
-
// },
|
|
2732
|
-
// {
|
|
2733
|
-
// "amt": "0.01",
|
|
2734
|
-
// "wdId": "4703879",
|
|
2735
|
-
// "fee": "0.00000000btc",
|
|
2736
|
-
// "txId": "",
|
|
2737
|
-
// "ccy": "BTC",
|
|
2738
|
-
// "from": "13426335357",
|
|
2739
|
-
// "to": "13426335357",
|
|
2740
|
-
// "ts": "1597026383085",
|
|
2741
|
-
// "state": "2"
|
|
2742
|
-
// }
|
|
2743
|
-
// ]
|
|
2744
|
-
// }
|
|
2745
|
-
//
|
|
2746
|
-
const data = this.safeList(response, 'data', []);
|
|
2747
|
-
return this.parseTransactions(data, currency, since, limit, params);
|
|
2748
|
-
}
|
|
2749
|
-
parseTransactionStatus(status) {
|
|
2750
|
-
//
|
|
2751
|
-
// deposit statuses
|
|
2752
|
-
//
|
|
2753
|
-
// {
|
|
2754
|
-
// "0": "waiting for confirmation",
|
|
2755
|
-
// "1": "confirmation account",
|
|
2756
|
-
// "2": "recharge success"
|
|
2757
|
-
// }
|
|
2758
|
-
//
|
|
2759
|
-
// withdrawal statues
|
|
2760
|
-
//
|
|
2761
|
-
// {
|
|
2762
|
-
// '-3': "pending cancel",
|
|
2763
|
-
// "-2": "cancelled",
|
|
2764
|
-
// "-1": "failed",
|
|
2765
|
-
// "0": "pending",
|
|
2766
|
-
// "1": "sending",
|
|
2767
|
-
// "2": "sent",
|
|
2768
|
-
// "3": "email confirmation",
|
|
2769
|
-
// "4": "manual confirmation",
|
|
2770
|
-
// "5": "awaiting identity confirmation"
|
|
2771
|
-
// }
|
|
2772
|
-
//
|
|
2773
|
-
const statuses = {
|
|
2774
|
-
'-3': 'pending',
|
|
2775
|
-
'-2': 'canceled',
|
|
2776
|
-
'-1': 'failed',
|
|
2777
|
-
'0': 'pending',
|
|
2778
|
-
'1': 'pending',
|
|
2779
|
-
'2': 'ok',
|
|
2780
|
-
'3': 'pending',
|
|
2781
|
-
'4': 'pending',
|
|
2782
|
-
'5': 'pending',
|
|
2783
|
-
};
|
|
2784
|
-
return this.safeString(statuses, status, status);
|
|
2785
|
-
}
|
|
2786
|
-
parseTransaction(transaction, currency = undefined) {
|
|
2787
|
-
//
|
|
2788
|
-
// withdraw
|
|
2789
|
-
//
|
|
2790
|
-
// {
|
|
2791
|
-
// "amt": "0.1",
|
|
2792
|
-
// "wdId": "67485",
|
|
2793
|
-
// "ccy": "BTC"
|
|
2794
|
-
// }
|
|
2795
|
-
//
|
|
2796
|
-
// fetchWithdrawals
|
|
2797
|
-
//
|
|
2798
|
-
// {
|
|
2799
|
-
// "amt": "0.094",
|
|
2800
|
-
// "wdId": "4703879",
|
|
2801
|
-
// "fee": "0.01000000eth",
|
|
2802
|
-
// "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85",
|
|
2803
|
-
// "ccy": "ETH",
|
|
2804
|
-
// "from": "13426335357",
|
|
2805
|
-
// "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519",
|
|
2806
|
-
// "tag",
|
|
2807
|
-
// "pmtId",
|
|
2808
|
-
// "memo",
|
|
2809
|
-
// "ts": "1597026383085",
|
|
2810
|
-
// "state": "2"
|
|
2811
|
-
// }
|
|
2812
|
-
//
|
|
2813
|
-
// fetchDeposits
|
|
2814
|
-
//
|
|
2815
|
-
// {
|
|
2816
|
-
// "amt": "0.01044408",
|
|
2817
|
-
// "txId": "1915737_3_0_0_asset",
|
|
2818
|
-
// "ccy": "BTC",
|
|
2819
|
-
// "from": "13801825426",
|
|
2820
|
-
// "to": "",
|
|
2821
|
-
// "ts": "1597026383085",
|
|
2822
|
-
// "state": "2",
|
|
2823
|
-
// "depId": "4703879"
|
|
2824
|
-
// }
|
|
2825
|
-
//
|
|
2826
|
-
let type = undefined;
|
|
2827
|
-
let id = undefined;
|
|
2828
|
-
const withdrawalId = this.safeString(transaction, 'wdId');
|
|
2829
|
-
const addressFrom = this.safeString(transaction, 'from');
|
|
2830
|
-
const addressTo = this.safeString(transaction, 'to');
|
|
2831
|
-
const address = addressTo;
|
|
2832
|
-
let tagTo = this.safeString2(transaction, 'tag', 'memo');
|
|
2833
|
-
tagTo = this.safeString2(transaction, 'pmtId', tagTo);
|
|
2834
|
-
if (withdrawalId !== undefined) {
|
|
2835
|
-
type = 'withdrawal';
|
|
2836
|
-
id = withdrawalId;
|
|
2837
|
-
}
|
|
2838
|
-
else {
|
|
2839
|
-
// the payment_id will appear on new deposits but appears to be removed from the response after 2 months
|
|
2840
|
-
id = this.safeString(transaction, 'depId');
|
|
2841
|
-
type = 'deposit';
|
|
2842
|
-
}
|
|
2843
|
-
const currencyId = this.safeString(transaction, 'ccy');
|
|
2844
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
2845
|
-
const amount = this.safeNumber(transaction, 'amt');
|
|
2846
|
-
const status = this.parseTransactionStatus(this.safeString(transaction, 'state'));
|
|
2847
|
-
const txid = this.safeString(transaction, 'txId');
|
|
2848
|
-
const timestamp = this.safeInteger(transaction, 'ts');
|
|
2849
|
-
let feeCost = undefined;
|
|
2850
|
-
if (type === 'deposit') {
|
|
2851
|
-
feeCost = 0;
|
|
2852
|
-
}
|
|
2853
|
-
else {
|
|
2854
|
-
feeCost = this.safeNumber(transaction, 'fee');
|
|
2855
|
-
}
|
|
2856
|
-
// todo parse tags
|
|
2857
|
-
return {
|
|
2858
|
-
'info': transaction,
|
|
2859
|
-
'id': id,
|
|
2860
|
-
'currency': code,
|
|
2861
|
-
'amount': amount,
|
|
2862
|
-
'network': undefined,
|
|
2863
|
-
'addressFrom': addressFrom,
|
|
2864
|
-
'addressTo': addressTo,
|
|
2865
|
-
'address': address,
|
|
2866
|
-
'tagFrom': undefined,
|
|
2867
|
-
'tagTo': tagTo,
|
|
2868
|
-
'tag': tagTo,
|
|
2869
|
-
'status': status,
|
|
2870
|
-
'type': type,
|
|
2871
|
-
'updated': undefined,
|
|
2872
|
-
'txid': txid,
|
|
2873
|
-
'timestamp': timestamp,
|
|
2874
|
-
'datetime': this.iso8601(timestamp),
|
|
2875
|
-
'comment': undefined,
|
|
2876
|
-
'internal': undefined,
|
|
2877
|
-
'fee': {
|
|
2878
|
-
'currency': code,
|
|
2879
|
-
'cost': feeCost,
|
|
2880
|
-
},
|
|
2881
|
-
};
|
|
2882
|
-
}
|
|
2883
|
-
/**
|
|
2884
|
-
* @method
|
|
2885
|
-
* @name okcoin#fetchMyTrades
|
|
2886
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-days
|
|
2887
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-months
|
|
2888
|
-
* @description fetch all trades made by the user
|
|
2889
|
-
* @param {string} symbol unified market symbol
|
|
2890
|
-
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
2891
|
-
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
2892
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2893
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2894
|
-
*/
|
|
2895
|
-
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2896
|
-
await this.loadMarkets();
|
|
2897
|
-
const request = {
|
|
2898
|
-
'instType': 'SPOT',
|
|
2899
|
-
};
|
|
2900
|
-
if ((limit !== undefined) && (limit > 100)) {
|
|
2901
|
-
limit = 100;
|
|
2902
|
-
}
|
|
2903
|
-
let market = undefined;
|
|
2904
|
-
if (symbol !== undefined) {
|
|
2905
|
-
market = this.market(symbol);
|
|
2906
|
-
request['instId'] = market['id'];
|
|
2907
|
-
}
|
|
2908
|
-
let method = undefined;
|
|
2909
|
-
[method, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'method', 'privateGetTradeFillsHistory');
|
|
2910
|
-
let response = undefined;
|
|
2911
|
-
if (method === 'privateGetTradeFillsHistory') {
|
|
2912
|
-
response = await this.privateGetTradeFillsHistory(this.extend(request, params));
|
|
2913
|
-
}
|
|
2914
|
-
else {
|
|
2915
|
-
response = await this.privateGetTradeFills(this.extend(request, params));
|
|
2916
|
-
}
|
|
2917
|
-
const data = this.safeList(response, 'data', []);
|
|
2918
|
-
return this.parseTrades(data, market, since, limit);
|
|
2919
|
-
}
|
|
2920
|
-
/**
|
|
2921
|
-
* @method
|
|
2922
|
-
* @name okcoin#fetchOrderTrades
|
|
2923
|
-
* @description fetch all the trades made from a single order
|
|
2924
|
-
* @param {string} id order id
|
|
2925
|
-
* @param {string} symbol unified market symbol
|
|
2926
|
-
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
2927
|
-
* @param {int} [limit] the maximum number of trades to retrieve
|
|
2928
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2929
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2930
|
-
*/
|
|
2931
|
-
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2932
|
-
const request = {
|
|
2933
|
-
// 'instrument_id': market['id'],
|
|
2934
|
-
'order_id': id,
|
|
2935
|
-
// 'after': '1', // return the page after the specified page number
|
|
2936
|
-
// 'before': '1', // return the page before the specified page number
|
|
2937
|
-
// 'limit': limit, // optional, number of results per request, default = maximum = 100
|
|
2938
|
-
};
|
|
2939
|
-
return await this.fetchMyTrades(symbol, since, limit, this.extend(request, params));
|
|
2940
|
-
}
|
|
2941
|
-
/**
|
|
2942
|
-
* @method
|
|
2943
|
-
* @name okcoin#fetchLedger
|
|
2944
|
-
* @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
|
2945
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-asset-bills-details
|
|
2946
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
|
|
2947
|
-
* @see https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
|
|
2948
|
-
* @param {string} [code] unified currency code, default is undefined
|
|
2949
|
-
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
|
2950
|
-
* @param {int} [limit] max number of ledger entries to return, default is undefined
|
|
2951
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2952
|
-
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
|
|
2953
|
-
*/
|
|
2954
|
-
async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2955
|
-
await this.loadMarkets();
|
|
2956
|
-
let method = undefined;
|
|
2957
|
-
[method, params] = this.handleOptionAndParams(params, 'fetchLedger', 'method', 'privateGetAccountBills');
|
|
2958
|
-
let request = {
|
|
2959
|
-
// 'instType': undefined, // 'SPOT', 'MARGIN', 'SWAP', 'FUTURES", 'OPTION'
|
|
2960
|
-
// 'ccy': undefined, // currency['id'],
|
|
2961
|
-
// 'ctType': undefined, // 'linear', 'inverse', only applicable to FUTURES/SWAP
|
|
2962
|
-
// 'type': varies depending the 'method' endpoint :
|
|
2963
|
-
// - https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
|
|
2964
|
-
// - https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details
|
|
2965
|
-
// - https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
|
|
2966
|
-
// 'after': 'id', // return records earlier than the requested bill id
|
|
2967
|
-
// 'before': 'id', // return records newer than the requested bill id
|
|
2968
|
-
// 'limit': 100, // default 100, max 100
|
|
2969
|
-
};
|
|
2970
|
-
if (limit !== undefined) {
|
|
2971
|
-
request['limit'] = limit;
|
|
2972
|
-
}
|
|
2973
|
-
let currency = undefined;
|
|
2974
|
-
if (code !== undefined) {
|
|
2975
|
-
currency = this.currency(code);
|
|
2976
|
-
request['ccy'] = currency['id'];
|
|
2977
|
-
}
|
|
2978
|
-
[request, params] = this.handleUntilOption('end', request, params);
|
|
2979
|
-
let response = undefined;
|
|
2980
|
-
if (method === 'privateGetAccountBillsArchive') {
|
|
2981
|
-
response = await this.privateGetAccountBillsArchive(this.extend(request, params));
|
|
2982
|
-
}
|
|
2983
|
-
else if (method === 'privateGetAssetBills') {
|
|
2984
|
-
response = await this.privateGetAssetBills(this.extend(request, params));
|
|
2985
|
-
}
|
|
2986
|
-
else {
|
|
2987
|
-
response = await this.privateGetAccountBills(this.extend(request, params));
|
|
2988
|
-
}
|
|
2989
|
-
//
|
|
2990
|
-
// privateGetAccountBills, privateGetAccountBillsArchive
|
|
2991
|
-
//
|
|
2992
|
-
// {
|
|
2993
|
-
// "code": "0",
|
|
2994
|
-
// "msg": "",
|
|
2995
|
-
// "data": [
|
|
2996
|
-
// {
|
|
2997
|
-
// "bal": "0.0000819307998198",
|
|
2998
|
-
// "balChg": "-664.2679586599999802",
|
|
2999
|
-
// "billId": "310394313544966151",
|
|
3000
|
-
// "ccy": "USDT",
|
|
3001
|
-
// "fee": "0",
|
|
3002
|
-
// "from": "",
|
|
3003
|
-
// "instId": "LTC-USDT",
|
|
3004
|
-
// "instType": "SPOT",
|
|
3005
|
-
// "mgnMode": "cross",
|
|
3006
|
-
// "notes": "",
|
|
3007
|
-
// "ordId": "310394313519800320",
|
|
3008
|
-
// "pnl": "0",
|
|
3009
|
-
// "posBal": "0",
|
|
3010
|
-
// "posBalChg": "0",
|
|
3011
|
-
// "subType": "2",
|
|
3012
|
-
// "sz": "664.26795866",
|
|
3013
|
-
// "to": "",
|
|
3014
|
-
// "ts": "1620275771196",
|
|
3015
|
-
// "type": "2"
|
|
3016
|
-
// }
|
|
3017
|
-
// ]
|
|
3018
|
-
// }
|
|
3019
|
-
//
|
|
3020
|
-
// privateGetAssetBills
|
|
3021
|
-
//
|
|
3022
|
-
// {
|
|
3023
|
-
// "code": "0",
|
|
3024
|
-
// "msg": "",
|
|
3025
|
-
// "data": [
|
|
3026
|
-
// {
|
|
3027
|
-
// "billId": "12344",
|
|
3028
|
-
// "ccy": "BTC",
|
|
3029
|
-
// "balChg": "2",
|
|
3030
|
-
// "bal": "12",
|
|
3031
|
-
// "type": "1",
|
|
3032
|
-
// "ts": "1597026383085"
|
|
3033
|
-
// }
|
|
3034
|
-
// ]
|
|
3035
|
-
// }
|
|
3036
|
-
//
|
|
3037
|
-
const data = this.safeValue(response, 'data', []);
|
|
3038
|
-
return this.parseLedger(data, currency, since, limit);
|
|
3039
|
-
}
|
|
3040
|
-
parseLedgerEntryType(type) {
|
|
3041
|
-
const types = {
|
|
3042
|
-
'1': 'transfer',
|
|
3043
|
-
'2': 'trade',
|
|
3044
|
-
'3': 'trade',
|
|
3045
|
-
'4': 'rebate',
|
|
3046
|
-
'5': 'trade',
|
|
3047
|
-
'6': 'transfer',
|
|
3048
|
-
'7': 'trade',
|
|
3049
|
-
'8': 'fee',
|
|
3050
|
-
'9': 'trade',
|
|
3051
|
-
'10': 'trade',
|
|
3052
|
-
'11': 'trade', // system token conversion
|
|
3053
|
-
};
|
|
3054
|
-
return this.safeString(types, type, type);
|
|
3055
|
-
}
|
|
3056
|
-
parseLedgerEntry(item, currency = undefined) {
|
|
3057
|
-
//
|
|
3058
|
-
// privateGetAccountBills, privateGetAccountBillsArchive
|
|
3059
|
-
//
|
|
3060
|
-
// {
|
|
3061
|
-
// "bal": "0.0000819307998198",
|
|
3062
|
-
// "balChg": "-664.2679586599999802",
|
|
3063
|
-
// "billId": "310394313544966151",
|
|
3064
|
-
// "ccy": "USDT",
|
|
3065
|
-
// "fee": "0",
|
|
3066
|
-
// "from": "",
|
|
3067
|
-
// "instId": "LTC-USDT",
|
|
3068
|
-
// "instType": "SPOT",
|
|
3069
|
-
// "mgnMode": "cross",
|
|
3070
|
-
// "notes": "",
|
|
3071
|
-
// "ordId": "310394313519800320",
|
|
3072
|
-
// "pnl": "0",
|
|
3073
|
-
// "posBal": "0",
|
|
3074
|
-
// "posBalChg": "0",
|
|
3075
|
-
// "subType": "2",
|
|
3076
|
-
// "sz": "664.26795866",
|
|
3077
|
-
// "to": "",
|
|
3078
|
-
// "ts": "1620275771196",
|
|
3079
|
-
// "type": "2"
|
|
3080
|
-
// }
|
|
3081
|
-
//
|
|
3082
|
-
// privateGetAssetBills
|
|
3083
|
-
//
|
|
3084
|
-
// {
|
|
3085
|
-
// "billId": "12344",
|
|
3086
|
-
// "ccy": "BTC",
|
|
3087
|
-
// "balChg": "2",
|
|
3088
|
-
// "bal": "12",
|
|
3089
|
-
// "type": "1",
|
|
3090
|
-
// "ts": "1597026383085"
|
|
3091
|
-
// }
|
|
3092
|
-
//
|
|
3093
|
-
const currencyId = this.safeString(item, 'ccy');
|
|
3094
|
-
const code = this.safeCurrencyCode(currencyId, currency);
|
|
3095
|
-
currency = this.safeCurrency(currencyId, currency);
|
|
3096
|
-
const timestamp = this.safeInteger(item, 'ts');
|
|
3097
|
-
const feeCostString = this.safeString(item, 'fee');
|
|
3098
|
-
let fee = undefined;
|
|
3099
|
-
if (feeCostString !== undefined) {
|
|
3100
|
-
fee = {
|
|
3101
|
-
'cost': this.parseToNumeric(Precise.stringNeg(feeCostString)),
|
|
3102
|
-
'currency': code,
|
|
3103
|
-
};
|
|
3104
|
-
}
|
|
3105
|
-
const marketId = this.safeString(item, 'instId');
|
|
3106
|
-
const symbol = this.safeSymbol(marketId, undefined, '-');
|
|
3107
|
-
return this.safeLedgerEntry({
|
|
3108
|
-
'info': item,
|
|
3109
|
-
'id': this.safeString(item, 'billId'),
|
|
3110
|
-
'timestamp': timestamp,
|
|
3111
|
-
'datetime': this.iso8601(timestamp),
|
|
3112
|
-
'account': undefined,
|
|
3113
|
-
'referenceId': this.safeString(item, 'ordId'),
|
|
3114
|
-
'referenceAccount': undefined,
|
|
3115
|
-
'type': this.parseLedgerEntryType(this.safeString(item, 'type')),
|
|
3116
|
-
'currency': code,
|
|
3117
|
-
'symbol': symbol,
|
|
3118
|
-
'amount': this.safeNumber(item, 'balChg'),
|
|
3119
|
-
'before': undefined,
|
|
3120
|
-
'after': this.safeNumber(item, 'bal'),
|
|
3121
|
-
'status': 'ok',
|
|
3122
|
-
'fee': fee,
|
|
3123
|
-
}, currency);
|
|
3124
|
-
}
|
|
3125
|
-
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
3126
|
-
const isArray = Array.isArray(params);
|
|
3127
|
-
const request = '/api/' + this.version + '/' + this.implodeParams(path, params);
|
|
3128
|
-
const query = this.omit(params, this.extractParams(path));
|
|
3129
|
-
let url = this.implodeHostname(this.urls['api']['rest']) + request;
|
|
3130
|
-
if (api === 'public') {
|
|
3131
|
-
if (Object.keys(query).length) {
|
|
3132
|
-
url += '?' + this.urlencode(query);
|
|
3133
|
-
}
|
|
3134
|
-
}
|
|
3135
|
-
else if (api === 'private') {
|
|
3136
|
-
this.checkRequiredCredentials();
|
|
3137
|
-
const timestamp = this.iso8601(this.milliseconds());
|
|
3138
|
-
headers = {
|
|
3139
|
-
'OK-ACCESS-KEY': this.apiKey,
|
|
3140
|
-
'OK-ACCESS-PASSPHRASE': this.password,
|
|
3141
|
-
'OK-ACCESS-TIMESTAMP': timestamp,
|
|
3142
|
-
// 'OK-FROM': '',
|
|
3143
|
-
// 'OK-TO': '',
|
|
3144
|
-
// 'OK-LIMIT': '',
|
|
3145
|
-
};
|
|
3146
|
-
let auth = timestamp + method + request;
|
|
3147
|
-
if (method === 'GET') {
|
|
3148
|
-
if (Object.keys(query).length) {
|
|
3149
|
-
const urlencodedQuery = '?' + this.urlencode(query);
|
|
3150
|
-
url += urlencodedQuery;
|
|
3151
|
-
auth += urlencodedQuery;
|
|
3152
|
-
}
|
|
3153
|
-
}
|
|
3154
|
-
else {
|
|
3155
|
-
if (isArray || Object.keys(query).length) {
|
|
3156
|
-
body = this.json(query);
|
|
3157
|
-
auth += body;
|
|
3158
|
-
}
|
|
3159
|
-
headers['Content-Type'] = 'application/json';
|
|
3160
|
-
}
|
|
3161
|
-
const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256, 'base64');
|
|
3162
|
-
headers['OK-ACCESS-SIGN'] = signature;
|
|
3163
|
-
}
|
|
3164
|
-
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
3165
|
-
}
|
|
3166
|
-
parseBalanceByType(type, response) {
|
|
3167
|
-
if (type === 'funding') {
|
|
3168
|
-
return this.parseFundingBalance(response);
|
|
3169
|
-
}
|
|
3170
|
-
else {
|
|
3171
|
-
return this.parseTradingBalance(response);
|
|
3172
|
-
}
|
|
3173
|
-
}
|
|
3174
|
-
handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
3175
|
-
if (!response) {
|
|
3176
|
-
return undefined; // fallback to default error handler
|
|
3177
|
-
}
|
|
3178
|
-
//
|
|
3179
|
-
// {
|
|
3180
|
-
// "code": "1",
|
|
3181
|
-
// "data": [
|
|
3182
|
-
// {
|
|
3183
|
-
// "clOrdId": "",
|
|
3184
|
-
// "ordId": "",
|
|
3185
|
-
// "sCode": "51119",
|
|
3186
|
-
// "sMsg": "Order placement failed due to insufficient balance. ",
|
|
3187
|
-
// "tag": ""
|
|
3188
|
-
// }
|
|
3189
|
-
// ],
|
|
3190
|
-
// "msg": ""
|
|
3191
|
-
// },
|
|
3192
|
-
// {
|
|
3193
|
-
// "code": "58001",
|
|
3194
|
-
// "data": [],
|
|
3195
|
-
// "msg": "Incorrect trade password"
|
|
3196
|
-
// }
|
|
3197
|
-
//
|
|
3198
|
-
const code = this.safeString(response, 'code');
|
|
3199
|
-
if (code !== '0') {
|
|
3200
|
-
const feedback = this.id + ' ' + body;
|
|
3201
|
-
const data = this.safeValue(response, 'data', []);
|
|
3202
|
-
for (let i = 0; i < data.length; i++) {
|
|
3203
|
-
const error = data[i];
|
|
3204
|
-
const errorCode = this.safeString(error, 'sCode');
|
|
3205
|
-
const message = this.safeString(error, 'sMsg');
|
|
3206
|
-
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
|
|
3207
|
-
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
3208
|
-
}
|
|
3209
|
-
this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
|
|
3210
|
-
throw new ExchangeError(feedback); // unknown message
|
|
3211
|
-
}
|
|
3212
|
-
return undefined;
|
|
3213
|
-
}
|
|
3214
|
-
}
|