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.
Files changed (79) hide show
  1. package/README.md +5 -6
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +1 -6
  4. package/dist/cjs/src/base/Exchange.js +14 -2
  5. package/dist/cjs/src/bingx.js +1 -1
  6. package/dist/cjs/src/bitfinex.js +4 -2
  7. package/dist/cjs/src/bitget.js +5 -2
  8. package/dist/cjs/src/btcmarkets.js +4 -2
  9. package/dist/cjs/src/coinbase.js +1 -0
  10. package/dist/cjs/src/deribit.js +21 -19
  11. package/dist/cjs/src/kraken.js +4 -0
  12. package/dist/cjs/src/kucoin.js +1 -1
  13. package/dist/cjs/src/latoken.js +1 -0
  14. package/dist/cjs/src/mexc.js +1 -0
  15. package/dist/cjs/src/onetrading.js +2 -1
  16. package/dist/cjs/src/phemex.js +1 -0
  17. package/dist/cjs/src/pro/bitget.js +1 -0
  18. package/dist/cjs/src/pro/htx.js +22 -3
  19. package/dist/cjs/src/pro/kraken.js +282 -458
  20. package/dist/cjs/src/pro/mexc.js +15 -10
  21. package/dist/cjs/src/probit.js +1 -1
  22. package/js/ccxt.d.ts +2 -8
  23. package/js/ccxt.js +2 -6
  24. package/js/src/abstract/coinbase.d.ts +1 -0
  25. package/js/src/abstract/coinbaseadvanced.d.ts +1 -0
  26. package/js/src/abstract/phemex.d.ts +1 -0
  27. package/js/src/base/Exchange.d.ts +5 -2
  28. package/js/src/base/Exchange.js +14 -2
  29. package/js/src/bingx.js +1 -1
  30. package/js/src/bitfinex.d.ts +1 -1
  31. package/js/src/bitfinex.js +4 -2
  32. package/js/src/bitget.d.ts +1 -1
  33. package/js/src/bitget.js +5 -2
  34. package/js/src/bithumb.d.ts +1 -1
  35. package/js/src/bitmex.d.ts +1 -1
  36. package/js/src/bitopro.d.ts +1 -1
  37. package/js/src/bitso.d.ts +1 -1
  38. package/js/src/bittrade.d.ts +1 -1
  39. package/js/src/blofin.d.ts +1 -1
  40. package/js/src/btcmarkets.d.ts +1 -1
  41. package/js/src/btcmarkets.js +4 -2
  42. package/js/src/bybit.d.ts +1 -1
  43. package/js/src/coinbase.d.ts +1 -1
  44. package/js/src/coinbase.js +1 -0
  45. package/js/src/coinex.d.ts +1 -1
  46. package/js/src/cryptocom.d.ts +1 -1
  47. package/js/src/deribit.js +21 -19
  48. package/js/src/digifinex.d.ts +1 -1
  49. package/js/src/hibachi.d.ts +1 -1
  50. package/js/src/htx.d.ts +1 -1
  51. package/js/src/hyperliquid.d.ts +1 -1
  52. package/js/src/kraken.d.ts +1 -1
  53. package/js/src/kraken.js +4 -0
  54. package/js/src/kucoin.js +1 -1
  55. package/js/src/kucoinfutures.d.ts +1 -1
  56. package/js/src/latoken.js +1 -0
  57. package/js/src/mexc.d.ts +1 -1
  58. package/js/src/mexc.js +1 -0
  59. package/js/src/oceanex.d.ts +1 -1
  60. package/js/src/okx.d.ts +1 -1
  61. package/js/src/onetrading.d.ts +1 -1
  62. package/js/src/onetrading.js +2 -1
  63. package/js/src/phemex.js +1 -0
  64. package/js/src/pro/bitget.d.ts +1 -0
  65. package/js/src/pro/bitget.js +1 -0
  66. package/js/src/pro/bitvavo.d.ts +2 -2
  67. package/js/src/pro/htx.js +22 -3
  68. package/js/src/pro/kraken.d.ts +7 -8
  69. package/js/src/pro/kraken.js +282 -458
  70. package/js/src/pro/mexc.js +15 -10
  71. package/js/src/probit.js +1 -1
  72. package/js/src/timex.d.ts +1 -1
  73. package/package.json +1 -1
  74. package/js/src/abstract/okcoin.d.ts +0 -77
  75. package/js/src/abstract/okcoin.js +0 -11
  76. package/js/src/okcoin.d.ts +0 -346
  77. package/js/src/okcoin.js +0 -3214
  78. package/js/src/pro/okcoin.d.ts +0 -91
  79. 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
- }