ccxt 4.5.63 → 4.5.64

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 (124) hide show
  1. package/README.md +6 -8
  2. package/dist/ccxt.browser.min.js +4 -4
  3. package/dist/cjs/ccxt.js +6 -12
  4. package/dist/cjs/src/aster.js +2 -2
  5. package/dist/cjs/src/base/Exchange.js +34 -3
  6. package/dist/cjs/src/bitget.js +5 -3
  7. package/dist/cjs/src/bitmex.js +1 -1
  8. package/dist/cjs/src/bitstamp.js +2 -1
  9. package/dist/cjs/src/bitvavo.js +1 -0
  10. package/dist/cjs/src/btcbox.js +1 -1
  11. package/dist/cjs/src/bullish.js +1 -1
  12. package/dist/cjs/src/bybiteu.js +3 -0
  13. package/dist/cjs/src/coinbase.js +3 -2
  14. package/dist/cjs/src/coinbaseinternational.js +1 -1
  15. package/dist/cjs/src/delta.js +23 -1
  16. package/dist/cjs/src/derive.js +1 -1
  17. package/dist/cjs/src/digifinex.js +12 -0
  18. package/dist/cjs/src/dydx.js +2 -2
  19. package/dist/cjs/src/extended.js +1 -1
  20. package/dist/cjs/src/gateeu.js +1 -0
  21. package/dist/cjs/src/grvt.js +1 -1
  22. package/dist/cjs/src/hashkey.js +127 -6
  23. package/dist/cjs/src/hibachi.js +20 -10
  24. package/dist/cjs/src/hyperliquid.js +1 -1
  25. package/dist/cjs/src/kraken.js +2 -0
  26. package/dist/cjs/src/kucoin.js +1 -1
  27. package/dist/cjs/src/kucoineu.js +3 -0
  28. package/dist/cjs/src/lighter.js +6 -4
  29. package/dist/cjs/src/mudrex.js +1328 -0
  30. package/dist/cjs/src/myokx.js +3 -0
  31. package/dist/cjs/src/okxus.js +1 -5
  32. package/dist/cjs/src/onetrading.js +1 -0
  33. package/dist/cjs/src/pacifica.js +1 -1
  34. package/dist/cjs/src/poloniex.js +1 -1
  35. package/dist/cjs/src/pro/bingx.js +4 -2
  36. package/dist/cjs/src/pro/bitget.js +9 -7
  37. package/dist/cjs/src/pro/grvt.js +1 -1
  38. package/dist/cjs/src/pro/hashkey.js +1 -1
  39. package/dist/cjs/src/pro/kraken.js +1 -1
  40. package/dist/cjs/src/pro/mudrex.js +226 -0
  41. package/dist/cjs/src/pro/okxus.js +1 -1
  42. package/js/ccxt.d.ts +8 -14
  43. package/js/ccxt.js +6 -10
  44. package/js/src/abstract/binance.d.ts +3 -0
  45. package/js/src/abstract/binancecoinm.d.ts +3 -0
  46. package/js/src/abstract/binanceus.d.ts +3 -0
  47. package/js/src/abstract/binanceusdm.d.ts +3 -0
  48. package/js/src/abstract/bybit.d.ts +39 -0
  49. package/js/src/abstract/bybiteu.d.ts +39 -0
  50. package/js/src/abstract/coincheck.d.ts +3 -0
  51. package/js/src/abstract/coinsph.d.ts +8 -1
  52. package/js/src/abstract/kucoineu.js +0 -6
  53. package/js/src/abstract/mudrex.d.ts +33 -0
  54. package/js/src/aster.js +2 -2
  55. package/js/src/base/Exchange.d.ts +10 -1
  56. package/js/src/base/Exchange.js +34 -3
  57. package/js/src/bitget.js +5 -3
  58. package/js/src/bitmex.js +1 -1
  59. package/js/src/bitstamp.js +2 -1
  60. package/js/src/bitvavo.js +1 -0
  61. package/js/src/btcbox.js +1 -1
  62. package/js/src/bullish.js +1 -1
  63. package/js/src/bybiteu.js +3 -0
  64. package/js/src/coinbase.js +3 -2
  65. package/js/src/coinbaseinternational.js +1 -1
  66. package/js/src/delta.d.ts +12 -0
  67. package/js/src/delta.js +23 -1
  68. package/js/src/derive.js +1 -1
  69. package/js/src/digifinex.d.ts +12 -0
  70. package/js/src/digifinex.js +12 -0
  71. package/js/src/dydx.d.ts +2 -2
  72. package/js/src/dydx.js +2 -2
  73. package/js/src/extended.js +1 -1
  74. package/js/src/gateeu.js +1 -0
  75. package/js/src/grvt.d.ts +1 -1
  76. package/js/src/grvt.js +1 -1
  77. package/js/src/hashkey.d.ts +40 -3
  78. package/js/src/hashkey.js +127 -6
  79. package/js/src/hibachi.d.ts +9 -5
  80. package/js/src/hibachi.js +20 -10
  81. package/js/src/hyperliquid.js +1 -1
  82. package/js/src/kraken.js +2 -0
  83. package/js/src/kucoin.js +1 -1
  84. package/js/src/kucoineu.js +3 -0
  85. package/js/src/lighter.js +6 -4
  86. package/js/src/mudrex.d.ts +310 -0
  87. package/js/src/mudrex.js +1321 -0
  88. package/js/src/myokx.js +3 -0
  89. package/js/src/okxus.js +1 -5
  90. package/js/src/onetrading.js +1 -0
  91. package/js/src/pacifica.js +1 -1
  92. package/js/src/poloniex.js +1 -1
  93. package/js/src/pro/bingx.js +4 -2
  94. package/js/src/pro/bitget.js +9 -7
  95. package/js/src/pro/grvt.d.ts +1 -1
  96. package/js/src/pro/grvt.js +1 -1
  97. package/js/src/pro/hashkey.d.ts +1 -1
  98. package/js/src/pro/hashkey.js +1 -1
  99. package/js/src/pro/kraken.js +1 -1
  100. package/js/src/pro/mudrex.d.ts +23 -0
  101. package/js/src/pro/mudrex.js +219 -0
  102. package/js/src/pro/okxus.js +1 -1
  103. package/package.json +3 -3
  104. package/dist/cjs/src/abstract/coinmetro.js +0 -11
  105. package/dist/cjs/src/abstract/novadax.js +0 -11
  106. package/dist/cjs/src/ascendex.js +0 -3780
  107. package/dist/cjs/src/coinmetro.js +0 -2030
  108. package/dist/cjs/src/novadax.js +0 -1678
  109. package/dist/cjs/src/pro/ascendex.js +0 -1013
  110. package/js/src/abstract/ascendex.d.ts +0 -80
  111. package/js/src/abstract/coinmetro.d.ts +0 -37
  112. package/js/src/abstract/coinmetro.js +0 -5
  113. package/js/src/abstract/novadax.d.ts +0 -32
  114. package/js/src/abstract/novadax.js +0 -5
  115. package/js/src/ascendex.d.ts +0 -436
  116. package/js/src/ascendex.js +0 -3773
  117. package/js/src/coinmetro.d.ts +0 -245
  118. package/js/src/coinmetro.js +0 -2023
  119. package/js/src/novadax.d.ts +0 -279
  120. package/js/src/novadax.js +0 -1671
  121. package/js/src/pro/ascendex.d.ts +0 -99
  122. package/js/src/pro/ascendex.js +0 -1006
  123. /package/dist/cjs/src/abstract/{ascendex.js → mudrex.js} +0 -0
  124. /package/js/src/abstract/{ascendex.js → mudrex.js} +0 -0
@@ -1,3780 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var sha2_js = require('@noble/hashes/sha2.js');
6
- var ascendex$1 = require('./abstract/ascendex.js');
7
- var errors = require('./base/errors.js');
8
- var Precise = require('./base/Precise.js');
9
- var number = require('./base/functions/number.js');
10
-
11
- // ---------------------------------------------------------------------------
12
- // ---------------------------------------------------------------------------
13
- /**
14
- * @class ascendex
15
- * @augments Exchange
16
- */
17
- class ascendex extends ascendex$1["default"] {
18
- describe() {
19
- return this.deepExtend(super.describe(), {
20
- 'id': 'ascendex',
21
- 'name': 'AscendEX',
22
- 'countries': ['SG'], // Singapore
23
- // 8 requests per minute = 0.13333 per second => rateLimit = 750
24
- // testing 400 works
25
- 'rateLimit': 400,
26
- 'certified': false,
27
- 'pro': true,
28
- // new metainfo interface
29
- 'has': {
30
- 'CORS': undefined,
31
- 'spot': true,
32
- 'margin': true,
33
- 'swap': true,
34
- 'future': false,
35
- 'option': false,
36
- 'addMargin': true,
37
- 'cancelAllOrders': true,
38
- 'cancelOrder': true,
39
- 'createOrder': true,
40
- 'createOrders': true,
41
- 'createPostOnlyOrder': true,
42
- 'createReduceOnlyOrder': true,
43
- 'createStopLimitOrder': true,
44
- 'createStopMarketOrder': true,
45
- 'createStopOrder': true,
46
- 'fetchAccounts': true,
47
- 'fetchAllGreeks': false,
48
- 'fetchBalance': true,
49
- 'fetchBorrowRate': false,
50
- 'fetchBorrowRateHistory': false,
51
- 'fetchBorrowRates': false,
52
- 'fetchClosedOrders': true,
53
- 'fetchCrossBorrowRate': false,
54
- 'fetchCrossBorrowRates': false,
55
- 'fetchCurrencies': true,
56
- 'fetchDepositAddress': true,
57
- 'fetchDepositAddresses': false,
58
- 'fetchDepositAddressesByNetwork': false,
59
- 'fetchDeposits': true,
60
- 'fetchDepositsWithdrawals': true,
61
- 'fetchDepositWithdrawFee': 'emulated',
62
- 'fetchDepositWithdrawFees': true,
63
- 'fetchFundingHistory': true,
64
- 'fetchFundingRate': 'emulated',
65
- 'fetchFundingRateHistory': false,
66
- 'fetchFundingRates': true,
67
- 'fetchGreeks': false,
68
- 'fetchIndexOHLCV': false,
69
- 'fetchIsolatedBorrowRate': false,
70
- 'fetchIsolatedBorrowRates': false,
71
- 'fetchLeverage': 'emulated',
72
- 'fetchLeverages': true,
73
- 'fetchLeverageTiers': true,
74
- 'fetchMarginMode': 'emulated',
75
- 'fetchMarginModes': true,
76
- 'fetchMarketLeverageTiers': 'emulated',
77
- 'fetchMarkets': true,
78
- 'fetchMarkOHLCV': false,
79
- 'fetchMySettlementHistory': false,
80
- 'fetchOHLCV': true,
81
- 'fetchOpenInterest': 'emulated',
82
- 'fetchOpenInterestHistory': false,
83
- 'fetchOpenInterests': true,
84
- 'fetchOpenOrders': true,
85
- 'fetchOption': false,
86
- 'fetchOptionChain': false,
87
- 'fetchOrder': true,
88
- 'fetchOrderBook': true,
89
- 'fetchOrders': false,
90
- 'fetchPosition': false,
91
- 'fetchPositionMode': false,
92
- 'fetchPositions': true,
93
- 'fetchPositionsRisk': false,
94
- 'fetchPremiumIndexOHLCV': false,
95
- 'fetchSettlementHistory': false,
96
- 'fetchTicker': true,
97
- 'fetchTickers': true,
98
- 'fetchTime': true,
99
- 'fetchTrades': true,
100
- 'fetchTradingFee': false,
101
- 'fetchTradingFees': true,
102
- 'fetchTransactionFee': false,
103
- 'fetchTransactionFees': false,
104
- 'fetchTransactions': 'emulated',
105
- 'fetchTransfer': false,
106
- 'fetchTransfers': false,
107
- 'fetchVolatilityHistory': false,
108
- 'fetchWithdrawal': false,
109
- 'fetchWithdrawals': true,
110
- 'reduceMargin': true,
111
- 'sandbox': true,
112
- 'setLeverage': true,
113
- 'setMarginMode': true,
114
- 'setPositionMode': false,
115
- 'transfer': true,
116
- },
117
- 'timeframes': {
118
- '1m': '1',
119
- '5m': '5',
120
- '15m': '15',
121
- '30m': '30',
122
- '1h': '60',
123
- '2h': '120',
124
- '4h': '240',
125
- '6h': '360',
126
- '12h': '720',
127
- '1d': '1d',
128
- '1w': '1w',
129
- '1M': '1m',
130
- },
131
- 'version': 'v2',
132
- 'urls': {
133
- 'logo': 'https://github.com/user-attachments/assets/55bab6b9-d4ca-42a8-a0e6-fac81ae557f1',
134
- 'api': {
135
- 'rest': 'https://ascendex.com',
136
- },
137
- 'test': {
138
- 'rest': 'https://api-test.ascendex-sandbox.com',
139
- },
140
- 'www': 'https://ascendex.com',
141
- 'doc': [
142
- 'https://ascendex.github.io/ascendex-pro-api/#ascendex-pro-api-documentation',
143
- ],
144
- 'fees': 'https://ascendex.com/en/feerate/transactionfee-traderate',
145
- 'referral': {
146
- 'url': 'https://ascendex.com/en-us/register?inviteCode=EL6BXBQM',
147
- 'discount': 0.25,
148
- },
149
- },
150
- 'api': {
151
- 'v1': {
152
- 'public': {
153
- 'get': {
154
- 'assets': 1,
155
- 'products': 1,
156
- 'ticker': 1,
157
- 'barhist/info': 1,
158
- 'barhist': 1,
159
- 'depth': 1,
160
- 'trades': 1,
161
- 'cash/assets': 1, // not documented
162
- 'cash/products': 1, // not documented
163
- 'margin/assets': 1, // not documented
164
- 'margin/products': 1, // not documented
165
- 'futures/collateral': 1,
166
- 'futures/contracts': 1,
167
- 'futures/ref-px': 1,
168
- 'futures/market-data': 1,
169
- 'futures/funding-rates': 1,
170
- 'risk-limit-info': 1,
171
- 'exchange-info': 1,
172
- },
173
- },
174
- 'private': {
175
- 'get': {
176
- 'info': 1,
177
- 'wallet/transactions': 1,
178
- 'wallet/deposit/address': 1,
179
- 'data/balance/snapshot': 1,
180
- 'data/balance/history': 1,
181
- },
182
- 'accountCategory': {
183
- 'get': {
184
- 'balance': 1,
185
- 'order/open': 1,
186
- 'order/status': 1,
187
- 'order/hist/current': 1,
188
- 'risk': 1,
189
- },
190
- 'post': {
191
- 'order': 1,
192
- 'order/batch': 1,
193
- },
194
- 'delete': {
195
- 'order': 1,
196
- 'order/all': 1,
197
- 'order/batch': 1,
198
- },
199
- },
200
- 'accountGroup': {
201
- 'get': {
202
- 'cash/balance': 1,
203
- 'margin/balance': 1,
204
- 'margin/risk': 1,
205
- 'futures/collateral-balance': 1,
206
- 'futures/position': 1,
207
- 'futures/risk': 1,
208
- 'futures/funding-payments': 1,
209
- 'order/hist': 1,
210
- 'spot/fee': 1,
211
- },
212
- 'post': {
213
- 'transfer': 1,
214
- 'futures/transfer/deposit': 1,
215
- 'futures/transfer/withdraw': 1,
216
- },
217
- },
218
- },
219
- },
220
- 'v2': {
221
- 'public': {
222
- 'get': {
223
- 'assets': 1,
224
- 'futures/contract': 1,
225
- 'futures/collateral': 1,
226
- 'futures/pricing-data': 1,
227
- 'futures/ticker': 1,
228
- 'risk-limit-info': 1,
229
- },
230
- },
231
- 'private': {
232
- 'data': {
233
- 'get': {
234
- 'order/hist': 1,
235
- },
236
- },
237
- 'get': {
238
- 'account/info': 1,
239
- },
240
- 'accountGroup': {
241
- 'get': {
242
- 'order/hist': 1,
243
- 'futures/position': 1,
244
- 'futures/free-margin': 1,
245
- 'futures/order/hist/current': 1,
246
- 'futures/funding-payments': 1,
247
- 'futures/order/open': 1,
248
- 'futures/order/status': 1,
249
- },
250
- 'post': {
251
- 'futures/isolated-position-margin': 1,
252
- 'futures/margin-type': 1,
253
- 'futures/leverage': 1,
254
- 'futures/transfer/deposit': 1,
255
- 'futures/transfer/withdraw': 1,
256
- 'futures/order': 1,
257
- 'futures/order/batch': 1,
258
- 'futures/order/open': 1,
259
- 'subuser/subuser-transfer': 1,
260
- 'subuser/subuser-transfer-hist': 1,
261
- },
262
- 'delete': {
263
- 'futures/order': 1,
264
- 'futures/order/batch': 1,
265
- 'futures/order/all': 1,
266
- },
267
- },
268
- },
269
- },
270
- },
271
- 'fees': {
272
- 'trading': {
273
- 'feeSide': 'get',
274
- 'tierBased': true,
275
- 'percentage': true,
276
- 'taker': this.parseNumber('0.002'),
277
- 'maker': this.parseNumber('0.002'),
278
- },
279
- },
280
- 'precisionMode': number.TICK_SIZE,
281
- 'options': {
282
- 'account-category': 'cash', // 'cash', 'margin', 'futures' // obsolete
283
- 'account-group': undefined,
284
- 'fetchClosedOrders': {
285
- 'method': 'v2PrivateDataGetOrderHist', // 'v1PrivateAccountCategoryGetOrderHistCurrent'
286
- },
287
- 'defaultType': 'spot', // 'spot', 'margin', 'swap'
288
- 'accountsByType': {
289
- 'spot': 'cash',
290
- 'swap': 'futures',
291
- 'margin': 'margin',
292
- },
293
- 'transfer': {
294
- 'fillResponseFromRequest': true,
295
- },
296
- 'networks': {
297
- 'BSC': 'BEP20 ' + '(BSC)',
298
- 'ARB': 'arbitrum',
299
- 'SOL': 'Solana',
300
- 'AVAX': 'avalanche C chain',
301
- 'OMNI': 'Omni',
302
- // 'TRC': 'TRC20',
303
- 'TRC20': 'TRC20',
304
- 'ERC20': 'ERC20',
305
- 'GO20': 'GO20',
306
- 'BEP2': 'BEP2',
307
- 'BTC': 'Bitcoin',
308
- 'BCH': 'Bitcoin ABC',
309
- 'LTC': 'Litecoin',
310
- 'MATIC': 'Matic Network',
311
- 'AKT': 'Akash',
312
- },
313
- },
314
- 'features': {
315
- 'default': {
316
- 'sandbox': true,
317
- 'createOrder': {
318
- 'marginMode': true,
319
- 'triggerPrice': true,
320
- 'triggerPriceType': undefined,
321
- 'triggerDirection': false,
322
- 'stopLossPrice': false, // todo with triggerprice
323
- 'takeProfitPrice': false, // todo with triggerprice
324
- 'attachedStopLossTakeProfit': undefined,
325
- 'timeInForce': {
326
- 'IOC': true,
327
- 'FOK': true,
328
- 'PO': true,
329
- 'GTD': false,
330
- },
331
- 'hedged': false,
332
- 'trailing': false,
333
- 'leverage': false,
334
- 'marketBuyRequiresPrice': false,
335
- 'marketBuyByCost': false,
336
- 'selfTradePrevention': false,
337
- 'iceberg': false,
338
- },
339
- 'createOrders': {
340
- 'max': 10,
341
- },
342
- 'fetchMyTrades': undefined,
343
- 'fetchOrder': {
344
- 'marginMode': false,
345
- 'trigger': false,
346
- 'trailing': false,
347
- 'marketType': true,
348
- 'symbolRequired': false,
349
- },
350
- 'fetchOpenOrders': {
351
- 'marginMode': false,
352
- 'limit': undefined,
353
- 'trigger': false,
354
- 'trailing': false,
355
- 'marketType': true,
356
- 'symbolRequired': false,
357
- },
358
- 'fetchOrders': undefined,
359
- 'fetchClosedOrders': undefined,
360
- 'fetchOHLCV': {
361
- 'limit': 500,
362
- },
363
- },
364
- 'spot': {
365
- 'extends': 'default',
366
- 'fetchClosedOrders': {
367
- 'marginMode': false,
368
- 'limit': 1000,
369
- 'daysBack': 100000,
370
- 'daysBackCanceled': 1,
371
- 'untilDays': 100000,
372
- 'trigger': false,
373
- 'trailing': false,
374
- 'symbolRequired': false,
375
- },
376
- },
377
- 'forDerivatives': {
378
- 'extends': 'default',
379
- 'createOrder': {
380
- // todo: implementation
381
- 'attachedStopLossTakeProfit': {
382
- 'triggerPriceType': {
383
- 'last': true,
384
- 'mark': false,
385
- 'index': false,
386
- },
387
- 'price': false,
388
- },
389
- },
390
- 'fetchClosedOrders': {
391
- 'marginMode': false,
392
- 'limit': 1000,
393
- 'daysBack': undefined,
394
- 'daysBackCanceled': undefined,
395
- 'untilDays': undefined,
396
- 'trigger': false,
397
- 'trailing': false,
398
- 'symbolRequired': false,
399
- },
400
- },
401
- 'swap': {
402
- 'linear': {
403
- 'extends': 'forDerivatives',
404
- },
405
- 'inverse': undefined,
406
- },
407
- 'future': {
408
- 'linear': undefined,
409
- 'inverse': undefined,
410
- },
411
- },
412
- 'exceptions': {
413
- 'exact': {
414
- // not documented
415
- '1900': errors.BadRequest, // {"code":1900,"message":"Invalid Http Request Input"}
416
- '2100': errors.AuthenticationError, // {"code":2100,"message":"ApiKeyFailure"}
417
- '5002': errors.BadSymbol, // {"code":5002,"message":"Invalid Symbol"}
418
- '6001': errors.BadSymbol, // {"code":6001,"message":"Trading is disabled on symbol."}
419
- '6010': errors.InsufficientFunds, // {'code': 6010, 'message': 'Not enough balance.'}
420
- '60060': errors.InvalidOrder, // { 'code': 60060, 'message': 'The order is already filled or canceled.' }
421
- '600503': errors.InvalidOrder, // {"code":600503,"message":"Notional is too small."}
422
- // documented
423
- '100001': errors.BadRequest, // INVALID_HTTP_INPUT Http request is invalid
424
- '100002': errors.BadRequest, // DATA_NOT_AVAILABLE Some required data is missing
425
- '100003': errors.BadRequest, // KEY_CONFLICT The same key exists already
426
- '100004': errors.BadRequest, // INVALID_REQUEST_DATA The HTTP request contains invalid field or argument
427
- '100005': errors.BadRequest, // INVALID_WS_REQUEST_DATA Websocket request contains invalid field or argument
428
- '100006': errors.BadRequest, // INVALID_ARGUMENT The arugment is invalid
429
- '100007': errors.BadRequest, // ENCRYPTION_ERROR Something wrong with data encryption
430
- '100008': errors.BadSymbol, // SYMBOL_ERROR Symbol does not exist or not valid for the request
431
- '100009': errors.AuthenticationError, // AUTHORIZATION_NEEDED Authorization is require for the API access or request
432
- '100010': errors.BadRequest, // INVALID_OPERATION The action is invalid or not allowed for the account
433
- '100011': errors.BadRequest, // INVALID_TIMESTAMP Not a valid timestamp
434
- '100012': errors.BadRequest, // INVALID_STR_FORMAT String format does not
435
- '100013': errors.BadRequest, // INVALID_NUM_FORMAT Invalid number input
436
- '100101': errors.ExchangeError, // UNKNOWN_ERROR Some unknown error
437
- '150001': errors.BadRequest, // INVALID_JSON_FORMAT Require a valid json object
438
- '200001': errors.AuthenticationError, // AUTHENTICATION_FAILED Authorization failed
439
- '200002': errors.ExchangeError, // TOO_MANY_ATTEMPTS Tried and failed too many times
440
- '200003': errors.ExchangeError, // ACCOUNT_NOT_FOUND Account not exist
441
- '200004': errors.ExchangeError, // ACCOUNT_NOT_SETUP Account not setup properly
442
- '200005': errors.ExchangeError, // ACCOUNT_ALREADY_EXIST Account already exist
443
- '200006': errors.ExchangeError, // ACCOUNT_ERROR Some error related with error
444
- '200007': errors.ExchangeError, // CODE_NOT_FOUND
445
- '200008': errors.ExchangeError, // CODE_EXPIRED Code expired
446
- '200009': errors.ExchangeError, // CODE_MISMATCH Code does not match
447
- '200010': errors.AuthenticationError, // PASSWORD_ERROR Wrong assword
448
- '200011': errors.ExchangeError, // CODE_GEN_FAILED Do not generate required code promptly
449
- '200012': errors.ExchangeError, // FAKE_COKE_VERIFY
450
- '200013': errors.ExchangeError, // SECURITY_ALERT Provide security alert message
451
- '200014': errors.PermissionDenied, // RESTRICTED_ACCOUNT Account is restricted for certain activity, such as trading, or withdraw.
452
- '200015': errors.PermissionDenied, // PERMISSION_DENIED No enough permission for the operation
453
- '300001': errors.InvalidOrder, // INVALID_PRICE Order price is invalid
454
- '300002': errors.InvalidOrder, // INVALID_QTY Order size is invalid
455
- '300003': errors.InvalidOrder, // INVALID_SIDE Order side is invalid
456
- '300004': errors.InvalidOrder, // INVALID_NOTIONAL Notional is too small or too large
457
- '300005': errors.InvalidOrder, // INVALID_TYPE Order typs is invalid
458
- '300006': errors.InvalidOrder, // INVALID_ORDER_ID Order id is invalid
459
- '300007': errors.InvalidOrder, // INVALID_TIME_IN_FORCE Time In Force in order request is invalid
460
- '300008': errors.InvalidOrder, // INVALID_ORDER_PARAMETER Some order parameter is invalid
461
- '300009': errors.InvalidOrder, // TRADING_VIOLATION Trading violation on account or asset
462
- '300011': errors.InsufficientFunds, // INVALID_BALANCE No enough account or asset balance for the trading
463
- '300012': errors.BadSymbol, // INVALID_PRODUCT Not a valid product supported by exchange
464
- '300013': errors.InvalidOrder, // INVALID_BATCH_ORDER Some or all orders are invalid in batch order request
465
- '300014': errors.InvalidOrder, // {"code":300014,"message":"Order price doesn't conform to the required tick size: 0.1","reason":"TICK_SIZE_VIOLATION"}
466
- '300020': errors.InvalidOrder, // TRADING_RESTRICTED There is some trading restriction on account or asset
467
- '300021': errors.AccountSuspended, // {"code":300021,"message":"Trading disabled for this account.","reason":"TRADING_DISABLED"}
468
- '300031': errors.InvalidOrder, // NO_MARKET_PRICE No market price for market type order trading
469
- '310001': errors.InsufficientFunds, // INVALID_MARGIN_BALANCE No enough margin balance
470
- '310002': errors.InvalidOrder, // INVALID_MARGIN_ACCOUNT Not a valid account for margin trading
471
- '310003': errors.InvalidOrder, // MARGIN_TOO_RISKY Leverage is too high
472
- '310004': errors.BadSymbol, // INVALID_MARGIN_ASSET This asset does not support margin trading
473
- '310005': errors.InvalidOrder, // INVALID_REFERENCE_PRICE There is no valid reference price
474
- '510001': errors.ExchangeError, // SERVER_ERROR Something wrong with server.
475
- '900001': errors.ExchangeError, // HUMAN_CHALLENGE Human change do not pass
476
- },
477
- 'broad': {},
478
- },
479
- 'commonCurrencies': {
480
- 'XBT': 'XBT', // this is not BTC ! just another token
481
- 'BOND': 'BONDED',
482
- 'BTCBEAR': 'BEAR',
483
- 'BTCBULL': 'BULL',
484
- 'BYN': 'BeyondFi',
485
- 'PLN': 'Pollen',
486
- },
487
- });
488
- }
489
- getAccount(params = {}) {
490
- // get current or provided bitmax sub-account
491
- const account = this.safeValue(params, 'account', this.options['account']);
492
- const lowercaseAccount = account.toLowerCase();
493
- return this.capitalize(lowercaseAccount);
494
- }
495
- /**
496
- * @method
497
- * @name ascendex#fetchCurrencies
498
- * @description fetches all available currencies on an exchange
499
- * @param {object} [params] extra parameters specific to the exchange API endpoint
500
- * @returns {object} an associative dictionary of currencies
501
- */
502
- async fetchCurrencies(params = {}) {
503
- const response = await this.v2PublicGetAssets(params);
504
- //
505
- // {
506
- // "code": "0",
507
- // "data": [
508
- // {
509
- // "assetCode": "USDT",
510
- // "assetName": "Tether",
511
- // "precisionScale": 9,
512
- // "nativeScale": 4,
513
- // "blockChain": [
514
- // {
515
- // "chainName": "Solana",
516
- // "withdrawFee": "2.0",
517
- // "allowDeposit": true,
518
- // "allowWithdraw": true,
519
- // "minDepositAmt": "0.01",
520
- // "minWithdrawal": "4.0",
521
- // "numConfirmations": 1
522
- // },
523
- // ...
524
- // ]
525
- // },
526
- // ]
527
- // }
528
- //
529
- const data = this.safeList(response, 'data', []);
530
- return this.parseCurrencies(data);
531
- }
532
- parseCurrency(rawCurrency) {
533
- const id = this.safeString(rawCurrency, 'assetCode');
534
- const code = this.safeCurrencyCode(id);
535
- const chains = this.safeList(rawCurrency, 'blockChain', []);
536
- const precision = this.parseNumber(this.parsePrecision(this.safeString(rawCurrency, 'nativeScale')));
537
- const networks = {};
538
- for (let j = 0; j < chains.length; j++) {
539
- const networkEtnry = chains[j];
540
- const networkId = this.safeString(networkEtnry, 'chainName');
541
- const networkCode = this.networkCodeToId(networkId, code);
542
- networks[networkCode] = {
543
- 'fee': this.safeNumber(networkEtnry, 'withdrawFee'),
544
- 'active': undefined,
545
- 'withdraw': this.safeBool(networkEtnry, 'allowWithdraw'),
546
- 'deposit': this.safeBool(networkEtnry, 'allowDeposit'),
547
- 'precision': precision,
548
- 'limits': {
549
- 'amount': {
550
- 'min': undefined,
551
- 'max': undefined,
552
- },
553
- 'withdraw': {
554
- 'min': this.safeNumber(networkEtnry, 'minWithdrawal'),
555
- 'max': undefined,
556
- },
557
- 'deposit': {
558
- 'min': this.safeNumber(networkEtnry, 'minDepositAmt'),
559
- 'max': undefined,
560
- },
561
- },
562
- };
563
- }
564
- // todo type: if (chainsLength === 0 && (assetName.endsWith (' Staking') || assetName.indexOf (' Reward ') >= 0 || assetName.indexOf ('Slot Auction') >= 0 || assetName.indexOf (' Freeze Asset') >= 0))
565
- return this.safeCurrencyStructure({
566
- 'id': id,
567
- 'code': code,
568
- 'info': rawCurrency,
569
- 'type': undefined,
570
- 'margin': undefined,
571
- 'name': this.safeString(rawCurrency, 'assetName'),
572
- 'active': undefined,
573
- 'deposit': undefined,
574
- 'withdraw': undefined,
575
- 'fee': undefined,
576
- 'precision': precision,
577
- 'limits': {
578
- 'amount': {
579
- 'min': undefined,
580
- 'max': undefined,
581
- },
582
- 'withdraw': {
583
- 'min': this.safeNumber(rawCurrency, 'minWithdrawalAmt'),
584
- 'max': undefined,
585
- },
586
- },
587
- 'networks': networks,
588
- });
589
- }
590
- /**
591
- * @method
592
- * @name ascendex#fetchMarkets
593
- * @description retrieves data on all markets for ascendex
594
- * @param {object} [params] extra parameters specific to the exchange API endpoint
595
- * @returns {object[]} an array of objects representing market data
596
- */
597
- async fetchMarkets(params = {}) {
598
- const spotPromise = this.fetchSpotMarkets(params);
599
- const contractPromise = this.fetchContractMarkets(params);
600
- const [spotMarkets, contractMarkets] = await Promise.all([spotPromise, contractPromise]);
601
- return this.arrayConcat(spotMarkets, contractMarkets);
602
- }
603
- async fetchSpotMarkets(params = {}) {
604
- const productsPromise = this.v1PublicGetProducts(params);
605
- //
606
- // {
607
- // "code": 0,
608
- // "data": [
609
- // {
610
- // "symbol": "LBA/BTC",
611
- // "baseAsset": "LBA",
612
- // "quoteAsset": "BTC",
613
- // "status": "Normal",
614
- // "minNotional": "0.000625",
615
- // "maxNotional": "6.25",
616
- // "marginTradable": false,
617
- // "commissionType": "Quote",
618
- // "commissionReserveRate": "0.001",
619
- // "tickSize": "0.000000001",
620
- // "lotSize": "1"
621
- // },
622
- // ]
623
- // }
624
- //
625
- const cashPromise = this.v1PublicGetCashProducts(params);
626
- //
627
- // {
628
- // "code": 0,
629
- // "data": [
630
- // {
631
- // "symbol": "QTUM/BTC",
632
- // "displayName": "QTUM/BTC",
633
- // "domain": "BTC",
634
- // "tradingStartTime": 1569506400000,
635
- // "collapseDecimals": "0.0001,0.000001,0.00000001",
636
- // "minQty": "0.000000001",
637
- // "maxQty": "1000000000",
638
- // "minNotional": "0.000625",
639
- // "maxNotional": "12.5",
640
- // "statusCode": "Normal",
641
- // "statusMessage": "",
642
- // "tickSize": "0.00000001",
643
- // "useTick": false,
644
- // "lotSize": "0.1",
645
- // "useLot": false,
646
- // "commissionType": "Quote",
647
- // "commissionReserveRate": "0.001",
648
- // "qtyScale": 1,
649
- // "priceScale": 8,
650
- // "notionalScale": 4
651
- // }
652
- // ]
653
- // }
654
- //
655
- const [products, cash] = await Promise.all([productsPromise, cashPromise]);
656
- const productsData = this.safeList(products, 'data', []);
657
- const productsById = this.indexBy(productsData, 'symbol');
658
- const cashData = this.safeList(cash, 'data', []);
659
- const cashAndPerpetualsById = this.indexBy(cashData, 'symbol');
660
- const dataById = this.deepExtend(productsById, cashAndPerpetualsById);
661
- const ids = Object.keys(dataById);
662
- const result = [];
663
- for (let i = 0; i < ids.length; i++) {
664
- const id = ids[i];
665
- if (id.indexOf('-PERP') >= 0) {
666
- continue; // skip perpetuals, as separate endpoint returns them
667
- }
668
- const market = dataById[id];
669
- const status = this.safeString(market, 'status');
670
- const domain = this.safeString(market, 'domain');
671
- let active = false;
672
- if (((status === 'Normal') || (status === 'InternalTrading')) && (domain !== 'LeveragedETF')) {
673
- active = true;
674
- }
675
- const minQty = this.safeNumber(market, 'minQty');
676
- const maxQty = this.safeNumber(market, 'maxQty');
677
- const minPrice = this.safeNumber(market, 'tickSize');
678
- const maxPrice = undefined;
679
- const underlying = this.safeString2(market, 'underlying', 'symbol');
680
- const parts = underlying.split('/');
681
- const baseId = this.safeString(parts, 0);
682
- const quoteId = this.safeString(parts, 1);
683
- const base = this.safeCurrencyCode(baseId);
684
- const quote = this.safeCurrencyCode(quoteId);
685
- const fee = this.safeNumber(market, 'commissionReserveRate');
686
- const marginTradable = this.safeBool(market, 'marginTradable', false);
687
- result.push({
688
- 'id': id,
689
- 'symbol': base + '/' + quote,
690
- 'base': base,
691
- 'baseId': baseId,
692
- 'quote': quote,
693
- 'quoteId': quoteId,
694
- 'settle': undefined,
695
- 'settleId': undefined,
696
- 'type': 'spot',
697
- 'spot': true,
698
- 'margin': marginTradable,
699
- 'swap': false,
700
- 'future': false,
701
- 'option': false,
702
- 'active': active,
703
- 'contract': false,
704
- 'linear': undefined,
705
- 'inverse': undefined,
706
- 'taker': fee,
707
- 'maker': fee,
708
- 'contractSize': undefined,
709
- 'expiry': undefined,
710
- 'expiryDatetime': undefined,
711
- 'strike': undefined,
712
- 'optionType': undefined,
713
- 'precision': {
714
- 'amount': this.safeNumber(market, 'lotSize'),
715
- 'price': this.safeNumber(market, 'tickSize'),
716
- },
717
- 'limits': {
718
- 'leverage': {
719
- 'min': undefined,
720
- 'max': undefined,
721
- },
722
- 'amount': {
723
- 'min': minQty,
724
- 'max': maxQty,
725
- },
726
- 'price': {
727
- 'min': minPrice,
728
- 'max': maxPrice,
729
- },
730
- 'cost': {
731
- 'min': this.safeNumber(market, 'minNotional'),
732
- 'max': this.safeNumber(market, 'maxNotional'),
733
- },
734
- },
735
- 'created': this.safeInteger(market, 'tradingStartTime'),
736
- 'info': market,
737
- });
738
- }
739
- return result;
740
- }
741
- async fetchContractMarkets(params = {}) {
742
- const contracts = await this.v2PublicGetFuturesContract(params);
743
- //
744
- // {
745
- // "code": 0,
746
- // "data": [
747
- // {
748
- // "symbol": "BTC-PERP",
749
- // "status": "Normal",
750
- // "displayName": "BTCUSDT",
751
- // "settlementAsset": "USDT",
752
- // "underlying": "BTC/USDT",
753
- // "tradingStartTime": 1579701600000,
754
- // "priceFilter": {
755
- // "minPrice": "0.1",
756
- // "maxPrice": "1000000",
757
- // "tickSize": "0.1"
758
- // },
759
- // "lotSizeFilter": {
760
- // "minQty": "0.0001",
761
- // "maxQty": "1000000000",
762
- // "lotSize": "0.0001"
763
- // },
764
- // "commissionType": "Quote",
765
- // "commissionReserveRate": "0.001",
766
- // "marketOrderPriceMarkup": "0.03",
767
- // "marginRequirements": [
768
- // {
769
- // "positionNotionalLowerBound": "0",
770
- // "positionNotionalUpperBound": "50000",
771
- // "initialMarginRate": "0.01",
772
- // "maintenanceMarginRate": "0.006"
773
- // },
774
- // ...
775
- // ]
776
- // }
777
- // ]
778
- // }
779
- //
780
- const data = this.safeList(contracts, 'data', []);
781
- const result = [];
782
- for (let i = 0; i < data.length; i++) {
783
- const market = data[i];
784
- const id = this.safeString(market, 'symbol');
785
- const underlying = this.safeString(market, 'underlying');
786
- const parts = underlying.split('/');
787
- const baseId = this.safeString(parts, 0);
788
- const base = this.safeCurrencyCode(baseId);
789
- const quoteId = this.safeString(parts, 1);
790
- const quote = this.safeCurrencyCode(quoteId);
791
- const settleId = this.safeString(market, 'settlementAsset');
792
- const settle = this.safeCurrencyCode(settleId);
793
- const linear = settle === quote;
794
- const inverse = settle === base;
795
- const symbol = base + '/' + quote + ':' + settle;
796
- const priceFilter = this.safeDict(market, 'priceFilter');
797
- const lotSizeFilter = this.safeDict(market, 'lotSizeFilter');
798
- const fee = this.safeNumber(market, 'commissionReserveRate');
799
- result.push({
800
- 'id': id,
801
- 'symbol': symbol,
802
- 'base': base,
803
- 'quote': quote,
804
- 'settle': settle,
805
- 'baseId': baseId,
806
- 'quoteId': quoteId,
807
- 'settleId': settleId,
808
- 'type': 'swap',
809
- 'spot': false,
810
- 'margin': undefined,
811
- 'swap': true,
812
- 'future': false,
813
- 'option': false,
814
- 'active': this.safeString(market, 'status') === 'Normal',
815
- 'contract': true,
816
- 'linear': linear,
817
- 'inverse': inverse,
818
- 'taker': fee,
819
- 'maker': fee,
820
- 'contractSize': this.parseNumber('1'),
821
- 'expiry': undefined,
822
- 'expiryDatetime': undefined,
823
- 'strike': undefined,
824
- 'optionType': undefined,
825
- 'precision': {
826
- 'amount': this.safeNumber(lotSizeFilter, 'lotSize'),
827
- 'price': this.safeNumber(priceFilter, 'tickSize'),
828
- },
829
- 'limits': {
830
- 'leverage': {
831
- 'min': undefined,
832
- 'max': undefined,
833
- },
834
- 'amount': {
835
- 'min': this.safeNumber(lotSizeFilter, 'minQty'),
836
- 'max': this.safeNumber(lotSizeFilter, 'maxQty'),
837
- },
838
- 'price': {
839
- 'min': this.safeNumber(priceFilter, 'minPrice'),
840
- 'max': this.safeNumber(priceFilter, 'maxPrice'),
841
- },
842
- 'cost': {
843
- 'min': this.safeNumber(market, 'minNotional'),
844
- 'max': this.safeNumber(market, 'maxNotional'),
845
- },
846
- },
847
- 'created': this.safeInteger(market, 'tradingStartTime'),
848
- 'info': market,
849
- });
850
- }
851
- return result;
852
- }
853
- /**
854
- * @method
855
- * @name ascendex#fetchTime
856
- * @description fetches the current integer timestamp in milliseconds from the ascendex server
857
- * @param {object} [params] extra parameters specific to the exchange API endpoint
858
- * @returns {int} the current integer timestamp in milliseconds from the ascendex server
859
- */
860
- async fetchTime(params = {}) {
861
- const request = {
862
- 'requestTime': this.milliseconds(),
863
- };
864
- const response = await this.v1PublicGetExchangeInfo(this.extend(request, params));
865
- //
866
- // {
867
- // "code": 0,
868
- // "data": {
869
- // "requestTimeEcho": 1656560463601,
870
- // "requestReceiveAt": 1656560464331,
871
- // "latency": 730
872
- // }
873
- // }
874
- //
875
- const data = this.safeDict(response, 'data', {});
876
- return this.safeInteger(data, 'requestReceiveAt');
877
- }
878
- /**
879
- * @method
880
- * @name ascendex#fetchAccounts
881
- * @description fetch all the accounts associated with a profile
882
- * @param {object} [params] extra parameters specific to the exchange API endpoint
883
- * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/?id=account-structure} indexed by the account type
884
- */
885
- async fetchAccounts(params = {}) {
886
- let accountGroup = this.safeString(this.options, 'account-group');
887
- let response = undefined;
888
- if (accountGroup === undefined) {
889
- response = await this.v1PrivateGetInfo(params);
890
- //
891
- // {
892
- // "code":0,
893
- // "data":{
894
- // "email":"igor.kroitor@gmail.com",
895
- // "accountGroup":8,
896
- // "viewPermission":true,
897
- // "tradePermission":true,
898
- // "transferPermission":true,
899
- // "cashAccount":["cshrHKLZCjlZ2ejqkmvIHHtPmLYqdnda"],
900
- // "marginAccount":["martXoh1v1N3EMQC5FDtSj5VHso8aI2Z"],
901
- // "futuresAccount":["futc9r7UmFJAyBY2rE3beA2JFxav2XFF"],
902
- // "userUID":"U6491137460"
903
- // }
904
- // }
905
- //
906
- const data = this.safeDict(response, 'data', {});
907
- accountGroup = this.safeString(data, 'accountGroup');
908
- this.options['account-group'] = accountGroup;
909
- }
910
- const finalResponse = response; // java req
911
- const finalAccountGroup = accountGroup;
912
- return [
913
- {
914
- 'id': finalAccountGroup,
915
- 'type': undefined,
916
- 'code': undefined,
917
- 'info': finalResponse,
918
- },
919
- ];
920
- }
921
- parseBalance(response) {
922
- const result = {
923
- 'info': response,
924
- 'timestamp': undefined,
925
- 'datetime': undefined,
926
- };
927
- const balances = this.safeList(response, 'data', []);
928
- for (let i = 0; i < balances.length; i++) {
929
- const balance = balances[i];
930
- const code = this.safeCurrencyCode(this.safeString(balance, 'asset'));
931
- const account = this.account();
932
- account['free'] = this.safeString(balance, 'availableBalance');
933
- account['total'] = this.safeString(balance, 'totalBalance');
934
- result[code] = account;
935
- }
936
- return this.safeBalance(result);
937
- }
938
- parseMarginBalance(response) {
939
- const result = {
940
- 'info': response,
941
- 'timestamp': undefined,
942
- 'datetime': undefined,
943
- };
944
- const balances = this.safeList(response, 'data', []);
945
- for (let i = 0; i < balances.length; i++) {
946
- const balance = balances[i];
947
- const code = this.safeCurrencyCode(this.safeString(balance, 'asset'));
948
- const account = this.account();
949
- account['free'] = this.safeString(balance, 'availableBalance');
950
- account['total'] = this.safeString(balance, 'totalBalance');
951
- const debt = this.safeString(balance, 'borrowed');
952
- const interest = this.safeString(balance, 'interest');
953
- account['debt'] = Precise["default"].stringAdd(debt, interest);
954
- result[code] = account;
955
- }
956
- return this.safeBalance(result);
957
- }
958
- parseSwapBalance(response) {
959
- const result = {
960
- 'info': response,
961
- 'timestamp': undefined,
962
- 'datetime': undefined,
963
- };
964
- const data = this.safeDict(response, 'data', {});
965
- const collaterals = this.safeList(data, 'collaterals', []);
966
- for (let i = 0; i < collaterals.length; i++) {
967
- const balance = collaterals[i];
968
- const code = this.safeCurrencyCode(this.safeString(balance, 'asset'));
969
- const account = this.account();
970
- account['total'] = this.safeString(balance, 'balance');
971
- result[code] = account;
972
- }
973
- return this.safeBalance(result);
974
- }
975
- /**
976
- * @method
977
- * @name ascendex#fetchBalance
978
- * @description query for balance and get the amount of funds available for trading or funds locked in orders
979
- * @see https://ascendex.github.io/ascendex-pro-api/#cash-account-balance
980
- * @see https://ascendex.github.io/ascendex-pro-api/#margin-account-balance
981
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
982
- * @param {object} [params] extra parameters specific to the exchange API endpoint
983
- * @param {string} [params.type] wallet type, 'spot', 'margin', or 'swap'
984
- * @param {string} [params.marginMode] 'cross' or undefined, for spot margin trading, value of 'isolated' is invalid
985
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
986
- */
987
- async fetchBalance(params = {}) {
988
- await this.loadMarkets();
989
- await this.loadAccounts();
990
- let marketType = undefined;
991
- let marginMode = undefined;
992
- [marketType, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
993
- [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
994
- const isMargin = this.safeBool(params, 'margin', false);
995
- const isCross = marginMode === 'cross';
996
- marketType = (isMargin || isCross) ? 'margin' : marketType;
997
- params = this.omit(params, 'margin');
998
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
999
- const accountCategory = this.safeString(accountsByType, marketType, 'cash');
1000
- const account = this.safeDict(this.accounts, 0, {});
1001
- const accountGroup = this.safeString(account, 'id');
1002
- const request = {
1003
- 'account-group': accountGroup,
1004
- };
1005
- if ((marginMode === 'isolated') && (marketType !== 'swap')) {
1006
- throw new errors.BadRequest(this.id + ' does not supported isolated margin trading');
1007
- }
1008
- if ((accountCategory === 'cash') || (accountCategory === 'margin')) {
1009
- request['account-category'] = accountCategory;
1010
- }
1011
- let response = undefined;
1012
- if ((marketType === 'spot') || (marketType === 'margin')) {
1013
- response = await this.v1PrivateAccountCategoryGetBalance(this.extend(request, params));
1014
- }
1015
- else if (marketType === 'swap') {
1016
- response = await this.v2PrivateAccountGroupGetFuturesPosition(this.extend(request, params));
1017
- }
1018
- else {
1019
- throw new errors.NotSupported(this.id + ' fetchBalance() is not currently supported for ' + marketType + ' markets');
1020
- }
1021
- //
1022
- // cash
1023
- //
1024
- // {
1025
- // "code": 0,
1026
- // "data": [
1027
- // {
1028
- // "asset": "BCHSV",
1029
- // "totalBalance": "64.298000048",
1030
- // "availableBalance": "64.298000048",
1031
- // },
1032
- // ]
1033
- // }
1034
- //
1035
- // margin
1036
- //
1037
- // {
1038
- // "code": 0,
1039
- // "data": [
1040
- // {
1041
- // "asset": "BCHSV",
1042
- // "totalBalance": "64.298000048",
1043
- // "availableBalance": "64.298000048",
1044
- // "borrowed": "0",
1045
- // "interest": "0",
1046
- // },
1047
- // ]
1048
- // }
1049
- //
1050
- // swap
1051
- //
1052
- // {
1053
- // "code": 0,
1054
- // "data": {
1055
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
1056
- // "ac": "FUTURES",
1057
- // "collaterals": [
1058
- // {"asset":"ADA","balance":"0.355803","referencePrice":"1.05095","discountFactor":"0.9"},
1059
- // {"asset":"USDT","balance":"0.000014519","referencePrice":"1","discountFactor":"1"}
1060
- // ],
1061
- // }j
1062
- // }
1063
- //
1064
- if (marketType === 'swap') {
1065
- return this.parseSwapBalance(response);
1066
- }
1067
- else if (marketType === 'margin') {
1068
- return this.parseMarginBalance(response);
1069
- }
1070
- else {
1071
- return this.parseBalance(response);
1072
- }
1073
- }
1074
- /**
1075
- * @method
1076
- * @name ascendex#fetchOrderBook
1077
- * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
1078
- * @param {string} symbol unified symbol of the market to fetch the order book for
1079
- * @param {int} [limit] the maximum amount of order book entries to return
1080
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1081
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure}
1082
- */
1083
- async fetchOrderBook(symbol, limit = undefined, params = {}) {
1084
- await this.loadMarkets();
1085
- const market = this.market(symbol);
1086
- const request = {
1087
- 'symbol': market['id'],
1088
- };
1089
- const response = await this.v1PublicGetDepth(this.extend(request, params));
1090
- //
1091
- // {
1092
- // "code":0,
1093
- // "data":{
1094
- // "m":"depth-snapshot",
1095
- // "symbol":"BTC-PERP",
1096
- // "data":{
1097
- // "ts":1590223998202,
1098
- // "seqnum":115444921,
1099
- // "asks":[
1100
- // ["9207.5","18.2383"],
1101
- // ["9207.75","18.8235"],
1102
- // ["9208","10.7873"],
1103
- // ],
1104
- // "bids":[
1105
- // ["9207.25","0.4009"],
1106
- // ["9207","0.003"],
1107
- // ["9206.5","0.003"],
1108
- // ]
1109
- // }
1110
- // }
1111
- // }
1112
- //
1113
- const data = this.safeDict(response, 'data', {});
1114
- const orderbook = this.safeDict(data, 'data', {});
1115
- const timestamp = this.safeInteger(orderbook, 'ts');
1116
- const result = this.parseOrderBook(orderbook, symbol, timestamp);
1117
- result['nonce'] = this.safeInteger(orderbook, 'seqnum');
1118
- return result;
1119
- }
1120
- parseTicker(ticker, market = undefined) {
1121
- //
1122
- // {
1123
- // "symbol":"QTUM/BTC",
1124
- // "open":"0.00016537",
1125
- // "close":"0.00019077",
1126
- // "high":"0.000192",
1127
- // "low":"0.00016537",
1128
- // "volume":"846.6",
1129
- // "ask":["0.00018698","26.2"],
1130
- // "bid":["0.00018408","503.7"],
1131
- // "type":"spot"
1132
- // }
1133
- //
1134
- const timestamp = undefined;
1135
- const marketId = this.safeString(ticker, 'symbol');
1136
- const type = this.safeString(ticker, 'type');
1137
- const delimiter = (type === 'spot') ? '/' : undefined;
1138
- const symbol = this.safeSymbol(marketId, market, delimiter);
1139
- const close = this.safeString(ticker, 'close');
1140
- const bid = this.safeList(ticker, 'bid', []);
1141
- const ask = this.safeList(ticker, 'ask', []);
1142
- const open = this.safeString(ticker, 'open');
1143
- return this.safeTicker({
1144
- 'symbol': symbol,
1145
- 'timestamp': timestamp,
1146
- 'datetime': undefined,
1147
- 'high': this.safeString(ticker, 'high'),
1148
- 'low': this.safeString(ticker, 'low'),
1149
- 'bid': this.safeString(bid, 0),
1150
- 'bidVolume': this.safeString(bid, 1),
1151
- 'ask': this.safeString(ask, 0),
1152
- 'askVolume': this.safeString(ask, 1),
1153
- 'vwap': undefined,
1154
- 'open': open,
1155
- 'close': close,
1156
- 'last': close,
1157
- 'previousClose': undefined, // previous day close
1158
- 'change': undefined,
1159
- 'percentage': undefined,
1160
- 'average': undefined,
1161
- 'baseVolume': this.safeString(ticker, 'volume'),
1162
- 'quoteVolume': undefined,
1163
- 'info': ticker,
1164
- }, market);
1165
- }
1166
- /**
1167
- * @method
1168
- * @name ascendex#fetchTicker
1169
- * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1170
- * @param {string} symbol unified symbol of the market to fetch the ticker for
1171
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1172
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
1173
- */
1174
- async fetchTicker(symbol, params = {}) {
1175
- await this.loadMarkets();
1176
- const market = this.market(symbol);
1177
- const request = {
1178
- 'symbol': market['id'],
1179
- };
1180
- const response = await this.v1PublicGetTicker(this.extend(request, params));
1181
- //
1182
- // {
1183
- // "code":0,
1184
- // "data":{
1185
- // "symbol":"BTC-PERP", // or "BTC/USDT"
1186
- // "open":"9073",
1187
- // "close":"9185.75",
1188
- // "high":"9185.75",
1189
- // "low":"9185.75",
1190
- // "volume":"576.8334",
1191
- // "ask":["9185.75","15.5863"],
1192
- // "bid":["9185.5","0.003"],
1193
- // "type":"derivatives", // or "spot"
1194
- // }
1195
- // }
1196
- //
1197
- const data = this.safeDict(response, 'data', {});
1198
- return this.parseTicker(data, market);
1199
- }
1200
- /**
1201
- * @method
1202
- * @name ascendex#fetchTickers
1203
- * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1204
- * @see https://ascendex.github.io/ascendex-pro-api/#ticker
1205
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#ticker
1206
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1207
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1208
- * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/?id=ticker-structure}
1209
- */
1210
- async fetchTickers(symbols = undefined, params = {}) {
1211
- await this.loadMarkets();
1212
- const request = {};
1213
- let market = undefined;
1214
- if (symbols !== undefined) {
1215
- const symbol = this.safeString(symbols, 0);
1216
- market = this.market(symbol);
1217
- const marketIds = this.marketIds(symbols);
1218
- request['symbol'] = marketIds.join(',');
1219
- }
1220
- let type = undefined;
1221
- [type, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
1222
- let response = undefined;
1223
- if (type === 'spot') {
1224
- response = await this.v1PublicGetTicker(this.extend(request, params));
1225
- }
1226
- else {
1227
- response = await this.v2PublicGetFuturesTicker(this.extend(request, params));
1228
- }
1229
- //
1230
- // {
1231
- // "code":0,
1232
- // "data": {
1233
- // "symbol":"QTUM/BTC",
1234
- // "open":"0.00016537",
1235
- // "close":"0.00019077",
1236
- // "high":"0.000192",
1237
- // "low":"0.00016537",
1238
- // "volume":"846.6",
1239
- // "ask":["0.00018698","26.2"],
1240
- // "bid":["0.00018408","503.7"],
1241
- // "type":"spot"
1242
- // }
1243
- // }
1244
- //
1245
- const data = this.safeList(response, 'data', []);
1246
- if (!Array.isArray(data)) {
1247
- return this.parseTickers([data], symbols);
1248
- }
1249
- return this.parseTickers(data, symbols);
1250
- }
1251
- parseOHLCV(ohlcv, market = undefined) {
1252
- //
1253
- // {
1254
- // "m":"bar",
1255
- // "s":"BTC/USDT",
1256
- // "data":{
1257
- // "i":"1",
1258
- // "ts":1590228000000,
1259
- // "o":"9139.59",
1260
- // "c":"9131.94",
1261
- // "h":"9139.99",
1262
- // "l":"9121.71",
1263
- // "v":"25.20648"
1264
- // }
1265
- // }
1266
- //
1267
- const data = this.safeDict(ohlcv, 'data', {});
1268
- return [
1269
- this.safeInteger(data, 'ts'),
1270
- this.safeNumber(data, 'o'),
1271
- this.safeNumber(data, 'h'),
1272
- this.safeNumber(data, 'l'),
1273
- this.safeNumber(data, 'c'),
1274
- this.safeNumber(data, 'v'),
1275
- ];
1276
- }
1277
- /**
1278
- * @method
1279
- * @name ascendex#fetchOHLCV
1280
- * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1281
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1282
- * @param {string} timeframe the length of time each candle represents
1283
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
1284
- * @param {int} [limit] the maximum amount of candles to fetch
1285
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1286
- * @param {int} [params.until] timestamp in ms of the latest candle to fetch
1287
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1288
- */
1289
- async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1290
- await this.loadMarkets();
1291
- const market = this.market(symbol);
1292
- const request = {
1293
- 'symbol': market['id'],
1294
- 'interval': this.safeString(this.timeframes, timeframe, timeframe),
1295
- };
1296
- // if since and limit are not specified
1297
- // the exchange will return just 1 last candle by default
1298
- const duration = this.parseTimeframe(timeframe);
1299
- const options = this.safeDict(this.options, 'fetchOHLCV', {});
1300
- const defaultLimit = this.safeInteger(options, 'limit', 500);
1301
- const until = this.safeInteger(params, 'until');
1302
- if (since !== undefined) {
1303
- request['from'] = since;
1304
- if (limit === undefined) {
1305
- limit = defaultLimit;
1306
- }
1307
- else {
1308
- limit = Math.min(limit, defaultLimit);
1309
- }
1310
- const toWithLimit = this.sum(since, limit * duration * 1000, 1);
1311
- if (until !== undefined) {
1312
- request['to'] = Math.min(toWithLimit, until + 1);
1313
- }
1314
- else {
1315
- request['to'] = toWithLimit;
1316
- }
1317
- }
1318
- else if (until !== undefined) {
1319
- request['to'] = until + 1;
1320
- if (limit === undefined) {
1321
- limit = defaultLimit;
1322
- }
1323
- else {
1324
- limit = Math.min(limit, defaultLimit);
1325
- }
1326
- request['from'] = until - (limit * duration * 1000);
1327
- }
1328
- else if (limit !== undefined) {
1329
- request['n'] = limit; // max 500
1330
- }
1331
- params = this.omit(params, 'until');
1332
- const response = await this.v1PublicGetBarhist(this.extend(request, params));
1333
- //
1334
- // {
1335
- // "code":0,
1336
- // "data":[
1337
- // {
1338
- // "m":"bar",
1339
- // "s":"BTC/USDT",
1340
- // "data":{
1341
- // "i":"1",
1342
- // "ts":1590228000000,
1343
- // "o":"9139.59",
1344
- // "c":"9131.94",
1345
- // "h":"9139.99",
1346
- // "l":"9121.71",
1347
- // "v":"25.20648"
1348
- // }
1349
- // }
1350
- // ]
1351
- // }
1352
- //
1353
- const data = this.safeList(response, 'data', []);
1354
- return this.parseOHLCVs(data, market, timeframe, since, limit);
1355
- }
1356
- parseTrade(trade, market = undefined) {
1357
- //
1358
- // public fetchTrades
1359
- //
1360
- // {
1361
- // "p":"9128.5", // price
1362
- // "q":"0.0030", // quantity
1363
- // "ts":1590229002385, // timestamp
1364
- // "bm":false, // if true, the buyer is the market maker, we only use this field to "define the side" of a public trade
1365
- // "seqnum":180143985289898554
1366
- // }
1367
- //
1368
- const timestamp = this.safeInteger(trade, 'ts');
1369
- const priceString = this.safeString2(trade, 'price', 'p');
1370
- const amountString = this.safeString(trade, 'q');
1371
- const buyerIsMaker = this.safeBool(trade, 'bm', false);
1372
- const side = buyerIsMaker ? 'sell' : 'buy';
1373
- market = this.safeMarket(undefined, market);
1374
- return this.safeTrade({
1375
- 'info': trade,
1376
- 'timestamp': timestamp,
1377
- 'datetime': this.iso8601(timestamp),
1378
- 'symbol': market['symbol'],
1379
- 'id': undefined,
1380
- 'order': undefined,
1381
- 'type': undefined,
1382
- 'takerOrMaker': undefined,
1383
- 'side': side,
1384
- 'price': priceString,
1385
- 'amount': amountString,
1386
- 'cost': undefined,
1387
- 'fee': undefined,
1388
- }, market);
1389
- }
1390
- /**
1391
- * @method
1392
- * @name ascendex#fetchTrades
1393
- * @description get the list of most recent trades for a particular symbol
1394
- * @see https://ascendex.github.io/ascendex-pro-api/#market-trades
1395
- * @param {string} symbol unified symbol of the market to fetch trades for
1396
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
1397
- * @param {int} [limit] the maximum amount of trades to fetch
1398
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1399
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
1400
- */
1401
- async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1402
- await this.loadMarkets();
1403
- const market = this.market(symbol);
1404
- const request = {
1405
- 'symbol': market['id'],
1406
- };
1407
- if (limit !== undefined) {
1408
- request['n'] = limit; // max 100
1409
- }
1410
- const response = await this.v1PublicGetTrades(this.extend(request, params));
1411
- //
1412
- // {
1413
- // "code":0,
1414
- // "data":{
1415
- // "m":"trades",
1416
- // "symbol":"BTC-PERP",
1417
- // "data":[
1418
- // {"p":"9128.5","q":"0.0030","ts":1590229002385,"bm":false,"seqnum":180143985289898554},
1419
- // {"p":"9129","q":"0.0030","ts":1590229002642,"bm":false,"seqnum":180143985289898587},
1420
- // {"p":"9129.5","q":"0.0030","ts":1590229021306,"bm":false,"seqnum":180143985289899043}
1421
- // ]
1422
- // }
1423
- // }
1424
- //
1425
- const records = this.safeDict(response, 'data', {});
1426
- const trades = this.safeList(records, 'data', []);
1427
- return this.parseTrades(trades, market, since, limit);
1428
- }
1429
- parseOrderStatus(status) {
1430
- const statuses = {
1431
- 'PendingNew': 'open',
1432
- 'New': 'open',
1433
- 'PartiallyFilled': 'open',
1434
- 'Filled': 'closed',
1435
- 'Canceled': 'canceled',
1436
- 'Rejected': 'rejected',
1437
- };
1438
- return this.safeString(statuses, status, status);
1439
- }
1440
- parseOrder(order, market = undefined) {
1441
- //
1442
- // createOrder
1443
- //
1444
- // {
1445
- // "id": "16e607e2b83a8bXHbAwwoqDo55c166fa",
1446
- // "orderId": "16e85b4d9b9a8bXHbAwwoqDoc3d66830",
1447
- // "orderType": "Market",
1448
- // "symbol": "BTC/USDT",
1449
- // "timestamp": 1573576916201
1450
- // }
1451
- //
1452
- // & linear (fetchClosedOrders)
1453
- //
1454
- // {
1455
- // "ac": "FUTURES",
1456
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
1457
- // "time": 1640819389454,
1458
- // "orderId": "a17e0874ecbdU0711043490bbtcpDU5X",
1459
- // "seqNum": -1,
1460
- // "orderType": "Limit",
1461
- // "execInst": "NULL_VAL", // NULL_VAL, ReduceOnly , ...
1462
- // "side": "Buy",
1463
- // "symbol": "BTC-PERP",
1464
- // "price": "30000",
1465
- // "orderQty": "0.002",
1466
- // "stopPrice": "0",
1467
- // "stopBy": "ref-px",
1468
- // "status": "Ack",
1469
- // "lastExecTime": 1640819389454,
1470
- // "lastQty": "0",
1471
- // "lastPx": "0",
1472
- // "avgFilledPx": "0",
1473
- // "cumFilledQty": "0",
1474
- // "fee": "0",
1475
- // "cumFee": "0",
1476
- // "feeAsset": "",
1477
- // "errorCode": "",
1478
- // "posStopLossPrice": "0",
1479
- // "posStopLossTrigger": "market",
1480
- // "posTakeProfitPrice": "0",
1481
- // "posTakeProfitTrigger": "market",
1482
- // "liquidityInd": "n"
1483
- // }
1484
- //
1485
- // fetchOrder, fetchOpenOrders, fetchClosedOrders
1486
- //
1487
- // {
1488
- // "symbol": "BTC/USDT",
1489
- // "price": "8131.22",
1490
- // "orderQty": "0.00082",
1491
- // "orderType": "Market",
1492
- // "avgPx": "7392.02",
1493
- // "cumFee": "0.005152238",
1494
- // "cumFilledQty": "0.00082",
1495
- // "errorCode": "",
1496
- // "feeAsset": "USDT",
1497
- // "lastExecTime": 1575953151764,
1498
- // "orderId": "a16eee20b6750866943712zWEDdAjt3",
1499
- // "seqNum": 2623469,
1500
- // "side": "Buy",
1501
- // "status": "Filled",
1502
- // "stopPrice": "",
1503
- // "execInst": "NULL_VAL" // "Post" (for postOnly orders), "reduceOnly" (for reduceOnly orders)
1504
- // }
1505
- //
1506
- // {
1507
- // "orderId": "a173ad938fc3U22666567717788c3b66", // orderId
1508
- // "seqNum": 18777366360, // sequence number
1509
- // "accountId": "cshwSjbpPjSwHmxPdz2CPQVU9mnbzPpt", // accountId
1510
- // "symbol": "BTC/USDT", // symbol
1511
- // "orderType": "Limit", // order type (Limit/Market/StopMarket/StopLimit)
1512
- // "side": "Sell", // order side (Buy/Sell)
1513
- // "price": "11346.77", // order price
1514
- // "stopPrice": "0", // stop price (0 by default)
1515
- // "orderQty": "0.01", // order quantity (in base asset)
1516
- // "status": "Canceled", // order status (Filled/Canceled/Rejected)
1517
- // "createTime": 1596344995793, // order creation time
1518
- // "lastExecTime": 1596344996053, // last execution time
1519
- // "avgFillPrice": "11346.77", // average filled price
1520
- // "fillQty": "0.01", // filled quantity (in base asset)
1521
- // "fee": "-0.004992579", // cummulative fee. if negative, this value is the commission charged; if possitive, this value is the rebate received.
1522
- // "feeAsset": "USDT" // fee asset
1523
- // }
1524
- //
1525
- // {
1526
- // "ac": "FUTURES",
1527
- // "accountId": "testabcdefg",
1528
- // "avgPx": "0",
1529
- // "cumFee": "0",
1530
- // "cumQty": "0",
1531
- // "errorCode": "NULL_VAL",
1532
- // "execInst": "NULL_VAL",
1533
- // "feeAsset": "USDT",
1534
- // "lastExecTime": 1584072844085,
1535
- // "orderId": "r170d21956dd5450276356bbtcpKa74",
1536
- // "orderQty": "1.1499",
1537
- // "orderType": "Limit",
1538
- // "price": "4000",
1539
- // "sendingTime": 1584072841033,
1540
- // "seqNum": 24105338,
1541
- // "side": "Buy",
1542
- // "status": "Canceled",
1543
- // "stopPrice": "",
1544
- // "symbol": "BTC-PERP"
1545
- // },
1546
- //
1547
- const status = this.parseOrderStatus(this.safeString(order, 'status'));
1548
- const marketId = this.safeString(order, 'symbol');
1549
- const symbol = this.safeSymbol(marketId, market, '/');
1550
- let timestamp = this.safeIntegerN(order, ['timestamp', 'sendingTime', 'time']);
1551
- const lastTradeTimestamp = this.safeInteger(order, 'lastExecTime');
1552
- if (timestamp === undefined) {
1553
- timestamp = lastTradeTimestamp;
1554
- }
1555
- const price = this.safeString(order, 'price');
1556
- const amount = this.safeString(order, 'orderQty');
1557
- const average = this.safeString2(order, 'avgPx', 'avgFilledPx');
1558
- const filled = this.safeStringN(order, ['cumFilledQty', 'cumQty', 'fillQty']);
1559
- const id = this.safeString(order, 'orderId');
1560
- let clientOrderId = this.safeString(order, 'id');
1561
- if (clientOrderId !== undefined) {
1562
- if (clientOrderId.length < 1) {
1563
- clientOrderId = undefined;
1564
- }
1565
- }
1566
- const rawTypeLower = this.safeStringLower(order, 'orderType');
1567
- let type = rawTypeLower;
1568
- if (rawTypeLower !== undefined) {
1569
- if (rawTypeLower === 'stoplimit') {
1570
- type = 'limit';
1571
- }
1572
- if (rawTypeLower === 'stopmarket') {
1573
- type = 'market';
1574
- }
1575
- }
1576
- const side = this.safeStringLower(order, 'side');
1577
- const feeCost = this.safeNumber2(order, 'cumFee', 'fee');
1578
- let fee = undefined;
1579
- if (feeCost !== undefined) {
1580
- const feeCurrencyId = this.safeString(order, 'feeAsset');
1581
- const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
1582
- fee = {
1583
- 'cost': feeCost,
1584
- 'currency': feeCurrencyCode,
1585
- };
1586
- }
1587
- const triggerPrice = this.omitZero(this.safeString(order, 'stopPrice'));
1588
- let reduceOnly = undefined;
1589
- const execInst = this.safeStringLower(order, 'execInst');
1590
- if (execInst === 'reduceonly') {
1591
- reduceOnly = true;
1592
- }
1593
- let postOnly = undefined;
1594
- if (execInst === 'post') {
1595
- postOnly = true;
1596
- }
1597
- return this.safeOrder({
1598
- 'info': order,
1599
- 'id': id,
1600
- 'clientOrderId': clientOrderId,
1601
- 'timestamp': timestamp,
1602
- 'datetime': this.iso8601(timestamp),
1603
- 'lastTradeTimestamp': lastTradeTimestamp,
1604
- 'symbol': symbol,
1605
- 'type': type,
1606
- 'timeInForce': undefined,
1607
- 'postOnly': postOnly,
1608
- 'reduceOnly': reduceOnly,
1609
- 'side': side,
1610
- 'price': price,
1611
- 'triggerPrice': triggerPrice,
1612
- 'amount': amount,
1613
- 'cost': undefined,
1614
- 'average': average,
1615
- 'filled': filled,
1616
- 'remaining': undefined,
1617
- 'status': status,
1618
- 'fee': fee,
1619
- 'trades': undefined,
1620
- }, market);
1621
- }
1622
- /**
1623
- * @method
1624
- * @name ascendex#fetchTradingFees
1625
- * @description fetch the trading fees for multiple markets
1626
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1627
- * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/?id=fee-structure} indexed by market symbols
1628
- */
1629
- async fetchTradingFees(params = {}) {
1630
- await this.loadMarkets();
1631
- await this.loadAccounts();
1632
- const account = this.safeDict(this.accounts, 0, {});
1633
- const accountGroup = this.safeString(account, 'id');
1634
- const request = {
1635
- 'account-group': accountGroup,
1636
- };
1637
- const response = await this.v1PrivateAccountGroupGetSpotFee(this.extend(request, params));
1638
- //
1639
- // {
1640
- // "code": "0",
1641
- // "data": {
1642
- // "domain": "spot",
1643
- // "userUID": "U1479576457",
1644
- // "vipLevel": "0",
1645
- // "fees": [
1646
- // { symbol: 'HT/USDT', fee: { taker: '0.001', maker: "0.001" } },
1647
- // { symbol: 'LAMB/BTC', fee: { taker: '0.002', maker: "0.002" } },
1648
- // { symbol: 'STOS/USDT', fee: { taker: '0.002', maker: "0.002" } },
1649
- // ...
1650
- // ]
1651
- // }
1652
- // }
1653
- //
1654
- const data = this.safeDict(response, 'data', {});
1655
- const fees = this.safeList(data, 'fees', []);
1656
- const result = {};
1657
- for (let i = 0; i < fees.length; i++) {
1658
- const fee = fees[i];
1659
- const marketId = this.safeString(fee, 'symbol');
1660
- const symbol = this.safeSymbol(marketId, undefined, '/');
1661
- const takerMaker = this.safeDict(fee, 'fee', {});
1662
- result[symbol] = {
1663
- 'info': fee,
1664
- 'symbol': symbol,
1665
- 'maker': this.safeNumber(takerMaker, 'maker'),
1666
- 'taker': this.safeNumber(takerMaker, 'taker'),
1667
- 'percentage': undefined,
1668
- 'tierBased': undefined,
1669
- };
1670
- }
1671
- return result;
1672
- }
1673
- createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
1674
- /**
1675
- * @method
1676
- * @ignore
1677
- * @name ascendex#createOrderRequest
1678
- * @description helper function to build request
1679
- * @param {string} symbol unified symbol of the market to create an order in
1680
- * @param {string} type 'market' or 'limit'
1681
- * @param {string} side 'buy' or 'sell'
1682
- * @param {float} amount how much you want to trade in units of the base currency
1683
- * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1684
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1685
- * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
1686
- * @param {bool} [params.postOnly] true or false
1687
- * @param {float} [params.triggerPrice] the price at which a trigger order is triggered at
1688
- * @returns {object} request to be sent to the exchange
1689
- */
1690
- const market = this.market(symbol);
1691
- let marginMode = undefined;
1692
- let marketType = undefined;
1693
- [marginMode, params] = this.handleMarginModeAndParams('createOrderRequest', params);
1694
- [marketType, params] = this.handleMarketTypeAndParams('createOrderRequest', market, params);
1695
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
1696
- let accountCategory = this.safeString(accountsByType, marketType, 'cash');
1697
- if (marginMode !== undefined) {
1698
- accountCategory = 'margin';
1699
- }
1700
- const account = this.safeDict(this.accounts, 0, {});
1701
- const accountGroup = this.safeString(account, 'id');
1702
- const clientOrderId = this.safeString2(params, 'clientOrderId', 'id');
1703
- const request = {
1704
- 'account-group': accountGroup,
1705
- 'account-category': accountCategory,
1706
- 'symbol': market['id'],
1707
- 'time': this.milliseconds(),
1708
- 'orderQty': this.amountToPrecision(symbol, amount),
1709
- 'orderType': type, // limit, market, stop_market, stop_limit
1710
- 'side': side, // buy or sell,
1711
- // 'execInst': // Post for postOnly, ReduceOnly for reduceOnly
1712
- // 'respInst': 'ACK', // ACK, 'ACCEPT, DONE
1713
- };
1714
- const isMarketOrder = ((type === 'market') || (type === 'stop_market'));
1715
- const isLimitOrder = ((type === 'limit') || (type === 'stop_limit'));
1716
- const timeInForce = this.safeString(params, 'timeInForce');
1717
- const postOnly = this.isPostOnly(isMarketOrder, false, params);
1718
- const reduceOnly = this.safeBool(params, 'reduceOnly', false);
1719
- const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
1720
- if (isLimitOrder) {
1721
- request['orderPrice'] = this.priceToPrecision(symbol, price);
1722
- }
1723
- if (timeInForce === 'IOC') {
1724
- request['timeInForce'] = 'IOC';
1725
- }
1726
- if (timeInForce === 'FOK') {
1727
- request['timeInForce'] = 'FOK';
1728
- }
1729
- if (postOnly) {
1730
- request['postOnly'] = true;
1731
- }
1732
- if (triggerPrice !== undefined) {
1733
- request['stopPrice'] = this.priceToPrecision(symbol, triggerPrice);
1734
- if (isLimitOrder) {
1735
- request['orderType'] = 'stop_limit';
1736
- }
1737
- else if (isMarketOrder) {
1738
- request['orderType'] = 'stop_market';
1739
- }
1740
- }
1741
- if (clientOrderId !== undefined) {
1742
- request['id'] = clientOrderId;
1743
- }
1744
- if (market['spot']) {
1745
- if (accountCategory !== undefined) {
1746
- request['category'] = accountCategory;
1747
- }
1748
- }
1749
- else {
1750
- request['account-category'] = accountCategory;
1751
- if (reduceOnly) {
1752
- request['execInst'] = 'ReduceOnly';
1753
- }
1754
- if (postOnly) {
1755
- request['execInst'] = 'Post';
1756
- }
1757
- }
1758
- params = this.omit(params, ['reduceOnly', 'triggerPrice']);
1759
- return this.extend(request, params);
1760
- }
1761
- /**
1762
- * @method
1763
- * @name ascendex#createOrder
1764
- * @description create a trade order on the exchange
1765
- * @see https://ascendex.github.io/ascendex-pro-api/#place-order
1766
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#new-order
1767
- * @param {string} symbol unified CCXT market symbol
1768
- * @param {string} type "limit" or "market"
1769
- * @param {string} side "buy" or "sell"
1770
- * @param {float} amount the amount of currency to trade
1771
- * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1772
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1773
- * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
1774
- * @param {bool} [params.postOnly] true or false
1775
- * @param {float} [params.triggerPrice] the price at which a trigger order is triggered at
1776
- * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice that the attached take profit order will be triggered (perpetual swap markets only)
1777
- * @param {float} [params.takeProfit.triggerPrice] *swap only* take profit trigger price
1778
- * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice that the attached stop loss order will be triggered (perpetual swap markets only)
1779
- * @param {float} [params.stopLoss.triggerPrice] *swap only* stop loss trigger price
1780
- * @returns [An order structure]{@link https://docs.ccxt.com/?id=order-structure}
1781
- */
1782
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1783
- await this.loadMarkets();
1784
- await this.loadAccounts();
1785
- const market = this.market(symbol);
1786
- const request = this.createOrderRequest(symbol, type, side, amount, price, params);
1787
- let response = undefined;
1788
- if (market['swap']) {
1789
- response = await this.v2PrivateAccountGroupPostFuturesOrder(request);
1790
- }
1791
- else {
1792
- response = await this.v1PrivateAccountCategoryPostOrder(request);
1793
- }
1794
- //
1795
- // spot
1796
- //
1797
- // {
1798
- // "code":0,
1799
- // "data": {
1800
- // "accountId":"cshwT8RKojkT1HoaA5UdeimR2SrmHG2I",
1801
- // "ac":"CASH",
1802
- // "action":"place-order",
1803
- // "status":"Ack",
1804
- // "info": {
1805
- // "symbol":"TRX/USDT",
1806
- // "orderType":"StopLimit",
1807
- // "timestamp":1654290662172,
1808
- // "id":"",
1809
- // "orderId":"a1812b6840ddU8191168955av0k6Eyhj"
1810
- // }
1811
- // }
1812
- // }
1813
- //
1814
- // swap
1815
- //
1816
- // {
1817
- // "code":0,
1818
- // "data": {
1819
- // "meta": {
1820
- // "id":"",
1821
- // "action":"place-order",
1822
- // "respInst":"ACK"
1823
- // },
1824
- // "order": {
1825
- // "ac":"FUTURES",
1826
- // "accountId":"futwT8RKojkT1HoaA5UdeimR2SrmHG2I",
1827
- // "time":1654290969965,
1828
- // "orderId":"a1812b6cf322U8191168955oJamfTh7b",
1829
- // "seqNum":-1,
1830
- // "orderType":"StopLimit",
1831
- // "execInst":"NULL_VAL",
1832
- // "side":"Buy",
1833
- // "symbol":"TRX-PERP",
1834
- // "price":"0.083",
1835
- // "orderQty":"1",
1836
- // "stopPrice":"0.082",
1837
- // "stopBy":"ref-px",
1838
- // "status":"Ack",
1839
- // "lastExecTime":1654290969965,
1840
- // "lastQty":"0",
1841
- // "lastPx":"0",
1842
- // "avgFilledPx":"0",
1843
- // "cumFilledQty":"0",
1844
- // "fee":"0",
1845
- // "cumFee":"0",
1846
- // "feeAsset":"",
1847
- // "errorCode":"",
1848
- // "posStopLossPrice":"0",
1849
- // "posStopLossTrigger":"market",
1850
- // "posTakeProfitPrice":"0",
1851
- // "posTakeProfitTrigger":"market",
1852
- // "liquidityInd":"n"
1853
- // }
1854
- // }
1855
- // }
1856
- //
1857
- const data = this.safeDict(response, 'data', {});
1858
- const order = this.safeDict2(data, 'order', 'info', {});
1859
- return this.parseOrder(order, market);
1860
- }
1861
- /**
1862
- * @method
1863
- * @name ascendex#createOrders
1864
- * @description create a list of trade orders
1865
- * @see https://ascendex.github.io/ascendex-pro-api/#place-batch-orders
1866
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#place-batch-orders
1867
- * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
1868
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1869
- * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
1870
- * @param {bool} [params.postOnly] true or false
1871
- * @param {float} [params.triggerPrice] the price at which a trigger order is triggered at
1872
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
1873
- */
1874
- async createOrders(orders, params = {}) {
1875
- await this.loadMarkets();
1876
- await this.loadAccounts();
1877
- const ordersRequests = [];
1878
- let symbol = undefined;
1879
- let marginMode = undefined;
1880
- for (let i = 0; i < orders.length; i++) {
1881
- const rawOrder = orders[i];
1882
- const marketId = this.safeString(rawOrder, 'symbol');
1883
- if (symbol === undefined) {
1884
- symbol = marketId;
1885
- }
1886
- else {
1887
- if (symbol !== marketId) {
1888
- throw new errors.BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
1889
- }
1890
- }
1891
- const type = this.safeString(rawOrder, 'type');
1892
- const side = this.safeString(rawOrder, 'side');
1893
- const amount = this.safeNumber(rawOrder, 'amount');
1894
- const price = this.safeNumber(rawOrder, 'price');
1895
- const orderParams = this.safeDict(rawOrder, 'params', {});
1896
- const marginResult = this.handleMarginModeAndParams('createOrders', orderParams);
1897
- const currentMarginMode = marginResult[0];
1898
- if (currentMarginMode !== undefined) {
1899
- if (marginMode === undefined) {
1900
- marginMode = currentMarginMode;
1901
- }
1902
- else {
1903
- if (marginMode !== currentMarginMode) {
1904
- throw new errors.BadRequest(this.id + ' createOrders() requires all orders to have the same margin mode (isolated or cross)');
1905
- }
1906
- }
1907
- }
1908
- const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
1909
- ordersRequests.push(orderRequest);
1910
- }
1911
- const market = this.market(symbol);
1912
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
1913
- let accountCategory = this.safeString(accountsByType, market['type'], 'cash');
1914
- if (marginMode !== undefined) {
1915
- accountCategory = 'margin';
1916
- }
1917
- const account = this.safeDict(this.accounts, 0, {});
1918
- const accountGroup = this.safeString(account, 'id');
1919
- const request = {};
1920
- let response = undefined;
1921
- if (market['swap']) {
1922
- throw new errors.NotSupported(this.id + ' createOrders() is not currently supported for swap markets on ascendex');
1923
- // request['account-group'] = accountGroup;
1924
- // request['category'] = accountCategory;
1925
- // request['orders'] = ordersRequests;
1926
- // response = await this.v2PrivateAccountGroupPostFuturesOrderBatch (request);
1927
- }
1928
- else {
1929
- request['account-group'] = accountGroup;
1930
- request['account-category'] = accountCategory;
1931
- request['orders'] = ordersRequests;
1932
- response = await this.v1PrivateAccountCategoryPostOrderBatch(request);
1933
- }
1934
- //
1935
- // spot
1936
- //
1937
- // {
1938
- // "code": 0,
1939
- // "data": {
1940
- // "accountId": "cshdAKBO43TKIh2kJtq7FVVb42KIePyS",
1941
- // "ac": "CASH",
1942
- // "action": "batch-place-order",
1943
- // "status": "Ack",
1944
- // "info": [
1945
- // {
1946
- // "symbol": "BTC/USDT",
1947
- // "orderType": "Limit",
1948
- // "timestamp": 1699326589344,
1949
- // "id": "",
1950
- // "orderId": "a18ba7c1f6efU0711043490p3HvjjN5x"
1951
- // }
1952
- // ]
1953
- // }
1954
- // }
1955
- //
1956
- const data = this.safeDict(response, 'data', {});
1957
- const info = this.safeList(data, 'info', []);
1958
- return this.parseOrders(info, market);
1959
- }
1960
- /**
1961
- * @method
1962
- * @name ascendex#fetchOrder
1963
- * @description fetches information on an order made by the user
1964
- * @see https://ascendex.github.io/ascendex-pro-api/#query-order
1965
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#query-order-by-id
1966
- * @param {string} id the order id
1967
- * @param {string} symbol unified symbol of the market the order was made in
1968
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1969
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/?id=order-structure}
1970
- */
1971
- async fetchOrder(id, symbol = undefined, params = {}) {
1972
- await this.loadMarkets();
1973
- await this.loadAccounts();
1974
- let market = undefined;
1975
- if (symbol !== undefined) {
1976
- market = this.market(symbol);
1977
- }
1978
- const [type, query] = this.handleMarketTypeAndParams('fetchOrder', market, params);
1979
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
1980
- const accountCategory = this.safeString(accountsByType, type, 'cash');
1981
- const account = this.safeDict(this.accounts, 0, {});
1982
- const accountGroup = this.safeString(account, 'id');
1983
- const request = {
1984
- 'account-group': accountGroup,
1985
- 'account-category': accountCategory,
1986
- 'orderId': id,
1987
- };
1988
- let response = undefined;
1989
- if ((type === 'spot') || (type === 'margin')) {
1990
- response = await this.v1PrivateAccountCategoryGetOrderStatus(this.extend(request, query));
1991
- }
1992
- else if (type === 'swap') {
1993
- request['account-category'] = accountCategory;
1994
- response = await this.v2PrivateAccountGroupGetFuturesOrderStatus(this.extend(request, query));
1995
- }
1996
- else {
1997
- throw new errors.NotSupported(this.id + ' fetchOrder() is not currently supported for ' + type + ' markets');
1998
- }
1999
- //
2000
- // AccountCategoryGetOrderStatus
2001
- //
2002
- // {
2003
- // "code": 0,
2004
- // "accountCategory": "CASH",
2005
- // "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
2006
- // "data": [
2007
- // {
2008
- // "symbol": "BTC/USDT",
2009
- // "price": "8131.22",
2010
- // "orderQty": "0.00082",
2011
- // "orderType": "Market",
2012
- // "avgPx": "7392.02",
2013
- // "cumFee": "0.005152238",
2014
- // "cumFilledQty": "0.00082",
2015
- // "errorCode": "",
2016
- // "feeAsset": "USDT",
2017
- // "lastExecTime": 1575953151764,
2018
- // "orderId": "a16eee20b6750866943712zWEDdAjt3",
2019
- // "seqNum": 2623469,
2020
- // "side": "Buy",
2021
- // "status": "Filled",
2022
- // "stopPrice": "",
2023
- // "execInst": "NULL_VAL"
2024
- // }
2025
- // ]
2026
- // }
2027
- //
2028
- // AccountGroupGetFuturesOrderStatus
2029
- //
2030
- // {
2031
- // "code": 0,
2032
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
2033
- // "ac": "FUTURES",
2034
- // "data": {
2035
- // "ac": "FUTURES",
2036
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
2037
- // "time": 1640247020217,
2038
- // "orderId": "r17de65747aeU0711043490bbtcp0cmt",
2039
- // "seqNum": 28796162908,
2040
- // "orderType": "Limit",
2041
- // "execInst": "NULL_VAL",
2042
- // "side": "Buy",
2043
- // "symbol": "BTC-PERP",
2044
- // "price": "30000",
2045
- // "orderQty": "0.0021",
2046
- // "stopPrice": "0",
2047
- // "stopBy": "market",
2048
- // "status": "New",
2049
- // "lastExecTime": 1640247020232,
2050
- // "lastQty": "0",
2051
- // "lastPx": "0",
2052
- // "avgFilledPx": "0",
2053
- // "cumFilledQty": "0",
2054
- // "fee": "0",
2055
- // "cumFee": "0",
2056
- // "feeAsset": "USDT",
2057
- // "errorCode": "",
2058
- // "posStopLossPrice": "0",
2059
- // "posStopLossTrigger": "market",
2060
- // "posTakeProfitPrice": "0",
2061
- // "posTakeProfitTrigger": "market",
2062
- // "liquidityInd": "n"
2063
- // }
2064
- // }
2065
- //
2066
- const data = this.safeDict(response, 'data', {});
2067
- return this.parseOrder(data, market);
2068
- }
2069
- /**
2070
- * @method
2071
- * @name ascendex#fetchOpenOrders
2072
- * @description fetch all unfilled currently open orders
2073
- * @see https://ascendex.github.io/ascendex-pro-api/#list-open-orders
2074
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#list-open-orders
2075
- * @param {string} symbol unified market symbol
2076
- * @param {int} [since] the earliest time in ms to fetch open orders for
2077
- * @param {int} [limit] the maximum number of open orders structures to retrieve
2078
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2079
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
2080
- */
2081
- async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2082
- await this.loadMarkets();
2083
- await this.loadAccounts();
2084
- let market = undefined;
2085
- if (symbol !== undefined) {
2086
- market = this.market(symbol);
2087
- symbol = market['symbol'];
2088
- }
2089
- const account = this.safeDict(this.accounts, 0, {});
2090
- const accountGroup = this.safeString(account, 'id');
2091
- const [type, query] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
2092
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
2093
- const accountCategory = this.safeString(accountsByType, type, 'cash');
2094
- const request = {
2095
- 'account-group': accountGroup,
2096
- 'account-category': accountCategory,
2097
- };
2098
- let response = undefined;
2099
- if ((type === 'spot') || (type === 'margin')) {
2100
- response = await this.v1PrivateAccountCategoryGetOrderOpen(this.extend(request, query));
2101
- }
2102
- else if (type === 'swap') {
2103
- request['account-category'] = accountCategory;
2104
- response = await this.v2PrivateAccountGroupGetFuturesOrderOpen(this.extend(request, query));
2105
- }
2106
- else {
2107
- throw new errors.NotSupported(this.id + ' fetchOpenOrders() is not currently supported for ' + type + ' markets');
2108
- }
2109
- //
2110
- // AccountCategoryGetOrderOpen
2111
- //
2112
- // {
2113
- // "ac": "CASH",
2114
- // "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
2115
- // "code": 0,
2116
- // "data": [
2117
- // {
2118
- // "avgPx": "0", // Average filled price of the order
2119
- // "cumFee": "0", // cumulative fee paid for this order
2120
- // "cumFilledQty": "0", // cumulative filled quantity
2121
- // "errorCode": "", // error code; could be empty
2122
- // "feeAsset": "USDT", // fee asset
2123
- // "lastExecTime": 1576019723550, // The last execution time of the order
2124
- // "orderId": "s16ef21882ea0866943712034f36d83", // server provided orderId
2125
- // "orderQty": "0.0083", // order quantity
2126
- // "orderType": "Limit", // order type
2127
- // "price": "7105", // order price
2128
- // "seqNum": 8193258, // sequence number
2129
- // "side": "Buy", // order side
2130
- // "status": "New", // order status on matching engine
2131
- // "stopPrice": "", // only available for stop market and stop limit orders; otherwise empty
2132
- // "symbol": "BTC/USDT",
2133
- // "execInst": "NULL_VAL" // execution instruction
2134
- // },
2135
- // ]
2136
- // }
2137
- //
2138
- // AccountGroupGetFuturesOrderOpen
2139
- //
2140
- // {
2141
- // "code": 0,
2142
- // "data": [
2143
- // {
2144
- // "ac": "FUTURES",
2145
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
2146
- // "time": 1640247020217,
2147
- // "orderId": "r17de65747aeU0711043490bbtcp0cmt",
2148
- // "seqNum": 28796162908,
2149
- // "orderType": "Limit",
2150
- // "execInst": "NULL_VAL",
2151
- // "side": "Buy",
2152
- // "symbol": "BTC-PERP",
2153
- // "price": "30000",
2154
- // "orderQty": "0.0021",
2155
- // "stopPrice": "0",
2156
- // "stopBy": "market",
2157
- // "status": "New",
2158
- // "lastExecTime": 1640247020232,
2159
- // "lastQty": "0",
2160
- // "lastPx": "0",
2161
- // "avgFilledPx": "0",
2162
- // "cumFilledQty": "0",
2163
- // "fee": "0",
2164
- // "cumFee": "0",
2165
- // "feeAsset": "USDT",
2166
- // "errorCode": "",
2167
- // "posStopLossPrice": "0",
2168
- // "posStopLossTrigger": "market",
2169
- // "posTakeProfitPrice": "0",
2170
- // "posTakeProfitTrigger": "market",
2171
- // "liquidityInd": "n"
2172
- // }
2173
- // ]
2174
- // }
2175
- //
2176
- const data = this.safeList(response, 'data', []);
2177
- if (accountCategory === 'futures') {
2178
- return this.parseOrders(data, market, since, limit);
2179
- }
2180
- // a workaround for https://github.com/ccxt/ccxt/issues/7187
2181
- const orders = [];
2182
- for (let i = 0; i < data.length; i++) {
2183
- const order = this.parseOrder(data[i], market);
2184
- orders.push(order);
2185
- }
2186
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
2187
- }
2188
- /**
2189
- * @method
2190
- * @name ascendex#fetchClosedOrders
2191
- * @description fetches information on multiple closed orders made by the user
2192
- * @see https://ascendex.github.io/ascendex-pro-api/#list-history-orders-v2
2193
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#list-current-history-orders
2194
- * @param {string} symbol unified market symbol of the market orders were made in
2195
- * @param {int} [since] the earliest time in ms to fetch orders for
2196
- * @param {int} [limit] the maximum number of order structures to retrieve
2197
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2198
- * @param {int} [params.until] the latest time in ms to fetch orders for
2199
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
2200
- */
2201
- async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2202
- await this.loadMarkets();
2203
- await this.loadAccounts();
2204
- const account = this.safeDict(this.accounts, 0, {});
2205
- const accountGroup = this.safeString(account, 'id');
2206
- const request = {
2207
- // 'category': accountCategory,
2208
- // 'symbol': market['id'],
2209
- // 'orderType': 'market', // optional, string
2210
- // 'side': 'buy', // or 'sell', optional, case insensitive.
2211
- // 'status': 'Filled', // "Filled", "Canceled", or "Rejected"
2212
- // 'startTime': exchange.milliseconds (),
2213
- // 'endTime': exchange.milliseconds (),
2214
- // 'page': 1,
2215
- // 'pageSize': 100,
2216
- };
2217
- let market = undefined;
2218
- if (symbol !== undefined) {
2219
- market = this.market(symbol);
2220
- request['symbol'] = market['id'];
2221
- }
2222
- const [type, query] = this.handleMarketTypeAndParams('fetchClosedOrders', market, params);
2223
- const options = this.safeDict(this.options, 'fetchClosedOrders', {});
2224
- const defaultMethod = this.safeString(options, 'method', 'v2PrivateDataGetOrderHist');
2225
- const method = this.getSupportedMapping(type, {
2226
- 'spot': defaultMethod,
2227
- 'margin': defaultMethod,
2228
- 'swap': 'v2PrivateAccountGroupGetFuturesOrderHistCurrent',
2229
- });
2230
- if (since !== undefined) {
2231
- request['startTime'] = since;
2232
- }
2233
- const until = this.safeString(params, 'until');
2234
- if (until !== undefined) {
2235
- request['endTime'] = until;
2236
- }
2237
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
2238
- const accountCategory = this.safeString(accountsByType, type, 'cash'); // margin, futures
2239
- let response = undefined;
2240
- if (method === 'v1PrivateAccountCategoryGetOrderHistCurrent') {
2241
- request['account-group'] = accountGroup;
2242
- request['account-category'] = accountCategory;
2243
- if (limit !== undefined) {
2244
- request['limit'] = limit;
2245
- }
2246
- response = await this.v1PrivateAccountCategoryGetOrderHistCurrent(this.extend(request, query));
2247
- }
2248
- else if (method === 'v2PrivateDataGetOrderHist') {
2249
- request['account'] = accountCategory;
2250
- if (limit !== undefined) {
2251
- request['limit'] = limit;
2252
- }
2253
- response = await this.v2PrivateDataGetOrderHist(this.extend(request, query));
2254
- }
2255
- else if (method === 'v2PrivateAccountGroupGetFuturesOrderHistCurrent') {
2256
- request['account-group'] = accountGroup;
2257
- request['account-category'] = accountCategory;
2258
- if (limit !== undefined) {
2259
- request['pageSize'] = limit;
2260
- }
2261
- response = await this.v2PrivateAccountGroupGetFuturesOrderHistCurrent(this.extend(request, query));
2262
- }
2263
- else {
2264
- throw new errors.NotSupported(this.id + ' fetchClosedOrders() is not currently supported for ' + type + ' markets');
2265
- }
2266
- //
2267
- // accountCategoryGetOrderHistCurrent
2268
- //
2269
- // {
2270
- // "code":0,
2271
- // "accountId":"cshrHKLZCjlZ2ejqkmvIHHtPmLYqdnda",
2272
- // "ac":"CASH",
2273
- // "data":[
2274
- // {
2275
- // "seqNum":15561826728,
2276
- // "orderId":"a17294d305c0U6491137460bethu7kw9",
2277
- // "symbol":"ETH/USDT",
2278
- // "orderType":"Limit",
2279
- // "lastExecTime":1591635618200,
2280
- // "price":"200",
2281
- // "orderQty":"0.1",
2282
- // "side":"Buy",
2283
- // "status":"Canceled",
2284
- // "avgPx":"0",
2285
- // "cumFilledQty":"0",
2286
- // "stopPrice":"",
2287
- // "errorCode":"",
2288
- // "cumFee":"0",
2289
- // "feeAsset":"USDT",
2290
- // "execInst":"NULL_VAL"
2291
- // }
2292
- // ]
2293
- // }
2294
- //
2295
- // {
2296
- // "code": 0,
2297
- // "data": [
2298
- // {
2299
- // "orderId" : "a173ad938fc3U22666567717788c3b66", // orderId
2300
- // "seqNum" : 18777366360, // sequence number
2301
- // "accountId" : "cshwSjbpPjSwHmxPdz2CPQVU9mnbzPpt", // accountId
2302
- // "symbol" : "BTC/USDT", // symbol
2303
- // "orderType" : "Limit", // order type (Limit/Market/StopMarket/StopLimit)
2304
- // "side" : "Sell", // order side (Buy/Sell)
2305
- // "price" : "11346.77", // order price
2306
- // "stopPrice" : "0", // stop price (0 by default)
2307
- // "orderQty" : "0.01", // order quantity (in base asset)
2308
- // "status" : "Canceled", // order status (Filled/Canceled/Rejected)
2309
- // "createTime" : 1596344995793, // order creation time
2310
- // "lastExecTime": 1596344996053, // last execution time
2311
- // "avgFillPrice": "11346.77", // average filled price
2312
- // "fillQty" : "0.01", // filled quantity (in base asset)
2313
- // "fee" : "-0.004992579", // cummulative fee. if negative, this value is the commission charged; if possitive, this value is the rebate received.
2314
- // "feeAsset" : "USDT" // fee asset
2315
- // }
2316
- // ]
2317
- // }
2318
- //
2319
- // accountGroupGetFuturesOrderHistCurrent
2320
- //
2321
- // {
2322
- // "code": 0,
2323
- // "data": [
2324
- // {
2325
- // "ac": "FUTURES",
2326
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
2327
- // "time": 1640245777002,
2328
- // "orderId": "r17de6444fa6U0711043490bbtcpJ2lI",
2329
- // "seqNum": 28796124902,
2330
- // "orderType": "Limit",
2331
- // "execInst": "NULL_VAL",
2332
- // "side": "Buy",
2333
- // "symbol": "BTC-PERP",
2334
- // "price": "30000",
2335
- // "orderQty": "0.0021",
2336
- // "stopPrice": "0",
2337
- // "stopBy": "market",
2338
- // "status": "Canceled",
2339
- // "lastExecTime": 1640246574886,
2340
- // "lastQty": "0",
2341
- // "lastPx": "0",
2342
- // "avgFilledPx": "0",
2343
- // "cumFilledQty": "0",
2344
- // "fee": "0",
2345
- // "cumFee": "0",
2346
- // "feeAsset": "USDT",
2347
- // "errorCode": "",
2348
- // "posStopLossPrice": "0",
2349
- // "posStopLossTrigger": "market",
2350
- // "posTakeProfitPrice": "0",
2351
- // "posTakeProfitTrigger": "market",
2352
- // "liquidityInd": "n"
2353
- // }
2354
- // ]
2355
- // }
2356
- //
2357
- let data = this.safeList(response, 'data', []);
2358
- if (!Array.isArray(data)) {
2359
- data = this.safeList(data, 'data', []);
2360
- }
2361
- return this.parseOrders(data, market, since, limit);
2362
- }
2363
- /**
2364
- * @method
2365
- * @name ascendex#cancelOrder
2366
- * @description cancels an open order
2367
- * @see https://ascendex.github.io/ascendex-pro-api/#cancel-order
2368
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#cancel-order
2369
- * @param {string} id order id
2370
- * @param {string} symbol unified symbol of the market the order was made in
2371
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2372
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/?id=order-structure}
2373
- */
2374
- async cancelOrder(id, symbol = undefined, params = {}) {
2375
- if (symbol === undefined) {
2376
- throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
2377
- }
2378
- await this.loadMarkets();
2379
- await this.loadAccounts();
2380
- const market = this.market(symbol);
2381
- const [type, query] = this.handleMarketTypeAndParams('cancelOrder', market, params);
2382
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
2383
- const accountCategory = this.safeString(accountsByType, type, 'cash');
2384
- const account = this.safeDict(this.accounts, 0, {});
2385
- const accountGroup = this.safeString(account, 'id');
2386
- const request = {
2387
- 'account-group': accountGroup,
2388
- 'account-category': accountCategory,
2389
- 'symbol': market['id'],
2390
- 'time': this.milliseconds(),
2391
- 'id': 'foobar',
2392
- };
2393
- const clientOrderId = this.safeString2(params, 'clientOrderId', 'id');
2394
- if (clientOrderId === undefined) {
2395
- request['orderId'] = id;
2396
- }
2397
- else {
2398
- request['id'] = clientOrderId;
2399
- params = this.omit(params, ['clientOrderId', 'id']);
2400
- }
2401
- let response = undefined;
2402
- if ((type === 'spot') || (type === 'margin')) {
2403
- response = await this.v1PrivateAccountCategoryDeleteOrder(this.extend(request, query));
2404
- }
2405
- else if (type === 'swap') {
2406
- request['account-category'] = accountCategory;
2407
- response = await this.v2PrivateAccountGroupDeleteFuturesOrder(this.extend(request, query));
2408
- }
2409
- else {
2410
- throw new errors.NotSupported(this.id + ' cancelOrder() is not currently supported for ' + type + ' markets');
2411
- }
2412
- //
2413
- // AccountCategoryDeleteOrder
2414
- //
2415
- // {
2416
- // "code": 0,
2417
- // "data": {
2418
- // "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
2419
- // "ac": "CASH",
2420
- // "action": "cancel-order",
2421
- // "status": "Ack",
2422
- // "info": {
2423
- // "id": "wv8QGquoeamhssvQBeHOHGQCGlcBjj23",
2424
- // "orderId": "16e6198afb4s8bXHbAwwoqDo2ebc19dc",
2425
- // "orderType": "", // could be empty
2426
- // "symbol": "ETH/USDT",
2427
- // "timestamp": 1573594877822
2428
- // }
2429
- // }
2430
- // }
2431
- //
2432
- // AccountGroupDeleteFuturesOrder
2433
- //
2434
- // {
2435
- // "code": 0,
2436
- // "data": {
2437
- // "meta": {
2438
- // "id": "foobar",
2439
- // "action": "cancel-order",
2440
- // "respInst": "ACK"
2441
- // },
2442
- // "order": {
2443
- // "ac": "FUTURES",
2444
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
2445
- // "time": 1640244480476,
2446
- // "orderId": "r17de63086f4U0711043490bbtcpPUF4",
2447
- // "seqNum": 28795959269,
2448
- // "orderType": "Limit",
2449
- // "execInst": "NULL_VAL",
2450
- // "side": "Buy",
2451
- // "symbol": "BTC-PERP",
2452
- // "price": "30000",
2453
- // "orderQty": "0.0021",
2454
- // "stopPrice": "0",
2455
- // "stopBy": "market",
2456
- // "status": "New",
2457
- // "lastExecTime": 1640244480491,
2458
- // "lastQty": "0",
2459
- // "lastPx": "0",
2460
- // "avgFilledPx": "0",
2461
- // "cumFilledQty": "0",
2462
- // "fee": "0",
2463
- // "cumFee": "0",
2464
- // "feeAsset": "BTCPC",
2465
- // "errorCode": "",
2466
- // "posStopLossPrice": "0",
2467
- // "posStopLossTrigger": "market",
2468
- // "posTakeProfitPrice": "0",
2469
- // "posTakeProfitTrigger": "market",
2470
- // "liquidityInd": "n"
2471
- // }
2472
- // }
2473
- // }
2474
- //
2475
- const data = this.safeDict(response, 'data', {});
2476
- const order = this.safeDict2(data, 'order', 'info', {});
2477
- return this.parseOrder(order, market);
2478
- }
2479
- /**
2480
- * @method
2481
- * @name ascendex#cancelAllOrders
2482
- * @description cancel all open orders
2483
- * @see https://ascendex.github.io/ascendex-pro-api/#cancel-all-orders
2484
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#cancel-all-open-orders
2485
- * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
2486
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2487
- * @returns {object[]} a list with a single [order structure]{@link https://docs.ccxt.com/?id=order-structure} with the response assigned to the info property
2488
- */
2489
- async cancelAllOrders(symbol = undefined, params = {}) {
2490
- await this.loadMarkets();
2491
- await this.loadAccounts();
2492
- let market = undefined;
2493
- if (symbol !== undefined) {
2494
- market = this.market(symbol);
2495
- }
2496
- const [type, query] = this.handleMarketTypeAndParams('cancelAllOrders', market, params);
2497
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
2498
- const accountCategory = this.safeString(accountsByType, type, 'cash');
2499
- const account = this.safeDict(this.accounts, 0, {});
2500
- const accountGroup = this.safeString(account, 'id');
2501
- const request = {
2502
- 'account-group': accountGroup,
2503
- 'account-category': accountCategory,
2504
- 'time': this.milliseconds(),
2505
- };
2506
- if (symbol !== undefined) {
2507
- request['symbol'] = this.safeString(market, 'id');
2508
- }
2509
- let response = undefined;
2510
- if ((type === 'spot') || (type === 'margin')) {
2511
- response = await this.v1PrivateAccountCategoryDeleteOrderAll(this.extend(request, query));
2512
- }
2513
- else if (type === 'swap') {
2514
- request['account-category'] = accountCategory;
2515
- response = await this.v2PrivateAccountGroupDeleteFuturesOrderAll(this.extend(request, query));
2516
- }
2517
- else {
2518
- throw new errors.NotSupported(this.id + ' cancelAllOrders() is not currently supported for ' + type + ' markets');
2519
- }
2520
- //
2521
- // AccountCategoryDeleteOrderAll
2522
- //
2523
- // {
2524
- // "code": 0,
2525
- // "data": {
2526
- // "ac": "CASH",
2527
- // "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
2528
- // "action": "cancel-all",
2529
- // "info": {
2530
- // "id": "2bmYvi7lyTrneMzpcJcf2D7Pe9V1P9wy",
2531
- // "orderId": "",
2532
- // "orderType": "NULL_VAL",
2533
- // "symbol": "",
2534
- // "timestamp": 1574118495462
2535
- // },
2536
- // "status": "Ack"
2537
- // }
2538
- // }
2539
- //
2540
- // AccountGroupDeleteFuturesOrderAll
2541
- //
2542
- // {
2543
- // "code": 0,
2544
- // "data": {
2545
- // "ac": "FUTURES",
2546
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
2547
- // "action": "cancel-all",
2548
- // "info": {
2549
- // "symbol":"BTC-PERP"
2550
- // }
2551
- // }
2552
- // }
2553
- //
2554
- return [this.safeOrder({
2555
- 'info': response,
2556
- })];
2557
- }
2558
- parseDepositAddress(depositAddress, currency = undefined) {
2559
- //
2560
- // {
2561
- // "address": "0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722",
2562
- // "destTag": "",
2563
- // "tagType": "",
2564
- // "tagId": "",
2565
- // "chainName": "ERC20",
2566
- // "numConfirmations": 20,
2567
- // "withdrawalFee": 1,
2568
- // "nativeScale": 4,
2569
- // "tips": []
2570
- // }
2571
- //
2572
- const address = this.safeString(depositAddress, 'address');
2573
- const tagId = this.safeString(depositAddress, 'tagId');
2574
- const tag = this.safeString(depositAddress, tagId);
2575
- this.checkAddress(address);
2576
- const code = (currency === undefined) ? undefined : currency['code'];
2577
- const chainName = this.safeString(depositAddress, 'blockchain');
2578
- const network = this.networkIdToCode(chainName, code);
2579
- return {
2580
- 'info': depositAddress,
2581
- 'currency': code,
2582
- 'network': network,
2583
- 'address': address,
2584
- 'tag': tag,
2585
- };
2586
- }
2587
- /**
2588
- * @method
2589
- * @name ascendex#fetchDepositAddress
2590
- * @description fetch the deposit address for a currency associated with this account
2591
- * @see https://ascendex.github.io/ascendex-pro-api/#query-deposit-addresses
2592
- * @param {string} code unified currency code
2593
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2594
- * @param {string} [params.network] unified network code for deposit chain
2595
- * @returns {object} an [address structure]{@link https://docs.ccxt.com/?id=address-structure}
2596
- */
2597
- async fetchDepositAddress(code, params = {}) {
2598
- await this.loadMarkets();
2599
- const currency = this.currency(code);
2600
- const networkCode = this.safeString2(params, 'network', 'chainName');
2601
- const networkId = this.networkCodeToId(networkCode, currency['code']);
2602
- params = this.omit(params, ['chainName']);
2603
- const request = {
2604
- 'asset': currency['id'],
2605
- 'blockchain': networkId,
2606
- };
2607
- const response = await this.v1PrivateGetWalletDepositAddress(this.extend(request, params));
2608
- //
2609
- // {
2610
- // "code":0,
2611
- // "data":{
2612
- // "asset":"USDT",
2613
- // "assetName":"Tether",
2614
- // "address":[
2615
- // {
2616
- // "address":"1N22odLHXnLPCjC8kwBJPTayarr9RtPod6",
2617
- // "destTag":"",
2618
- // "tagType":"",
2619
- // "tagId":"",
2620
- // "chainName":"Omni",
2621
- // "numConfirmations":3,
2622
- // "withdrawalFee":4.7,
2623
- // "nativeScale":4,
2624
- // "tips":[]
2625
- // },
2626
- // {
2627
- // "address":"0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722",
2628
- // "destTag":"",
2629
- // "tagType":"",
2630
- // "tagId":"",
2631
- // "chainName":"ERC20",
2632
- // "numConfirmations":20,
2633
- // "withdrawalFee":1.0,
2634
- // "nativeScale":4,
2635
- // "tips":[]
2636
- // }
2637
- // ]
2638
- // }
2639
- // }
2640
- //
2641
- const data = this.safeDict(response, 'data', {});
2642
- const addresses = this.safeList(data, 'address', []);
2643
- const numAddresses = addresses.length;
2644
- let address = undefined;
2645
- if (numAddresses > 1) {
2646
- const addressesByChainName = this.indexBy(addresses, 'chainName');
2647
- if (networkId === undefined) {
2648
- const chainNames = Object.keys(addressesByChainName);
2649
- const chains = chainNames.join(', ');
2650
- throw new errors.ArgumentsRequired(this.id + ' fetchDepositAddress() returned more than one address, a chainName parameter is required, one of ' + chains);
2651
- }
2652
- address = this.safeDict(addressesByChainName, networkId, {});
2653
- }
2654
- else {
2655
- // first address
2656
- address = this.safeDict(addresses, 0, {});
2657
- }
2658
- const result = this.parseDepositAddress(address, currency);
2659
- return this.extend(result, {
2660
- 'info': response,
2661
- });
2662
- }
2663
- /**
2664
- * @method
2665
- * @name ascendex#fetchDeposits
2666
- * @description fetch all deposits made to an account
2667
- * @param {string} code unified currency code
2668
- * @param {int} [since] the earliest time in ms to fetch deposits for
2669
- * @param {int} [limit] the maximum number of deposits structures to retrieve
2670
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2671
- * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/?id=transaction-structure}
2672
- */
2673
- async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
2674
- const request = {
2675
- 'txType': 'deposit',
2676
- };
2677
- return await this.fetchTransactions(code, since, limit, this.extend(request, params));
2678
- }
2679
- /**
2680
- * @method
2681
- * @name ascendex#fetchWithdrawals
2682
- * @description fetch all withdrawals made from an account
2683
- * @param {string} code unified currency code
2684
- * @param {int} [since] the earliest time in ms to fetch withdrawals for
2685
- * @param {int} [limit] the maximum number of withdrawals structures to retrieve
2686
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2687
- * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/?id=transaction-structure}
2688
- */
2689
- async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
2690
- const request = {
2691
- 'txType': 'withdrawal',
2692
- };
2693
- return await this.fetchTransactions(code, since, limit, this.extend(request, params));
2694
- }
2695
- /**
2696
- * @method
2697
- * @name ascendex#fetchDepositsWithdrawals
2698
- * @description fetch history of deposits and withdrawals
2699
- * @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
2700
- * @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
2701
- * @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
2702
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2703
- * @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/?id=transaction-structure}
2704
- */
2705
- async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
2706
- await this.loadMarkets();
2707
- const request = {
2708
- // 'asset': currency['id'],
2709
- // 'page': 1,
2710
- // 'pageSize': 20,
2711
- // 'startTs': this.milliseconds (),
2712
- // 'endTs': this.milliseconds (),
2713
- // 'txType': undefned, // deposit, withdrawal
2714
- };
2715
- let currency = undefined;
2716
- if (code !== undefined) {
2717
- currency = this.currency(code);
2718
- request['asset'] = currency['id'];
2719
- }
2720
- if (since !== undefined) {
2721
- request['startTs'] = since;
2722
- }
2723
- if (limit !== undefined) {
2724
- request['pageSize'] = limit;
2725
- }
2726
- const response = await this.v1PrivateGetWalletTransactions(this.extend(request, params));
2727
- //
2728
- // {
2729
- // "code": 0,
2730
- // "data": {
2731
- // "data": [
2732
- // {
2733
- // "requestId": "wuzd1Ojsqtz4bCA3UXwtUnnJDmU8PiyB",
2734
- // "time": 1591606166000,
2735
- // "asset": "USDT",
2736
- // "transactionType": "deposit",
2737
- // "amount": "25",
2738
- // "commission": "0",
2739
- // "networkTransactionId": "0xbc4eabdce92f14dbcc01d799a5f8ca1f02f4a3a804b6350ea202be4d3c738fce",
2740
- // "status": "pending",
2741
- // "numConfirmed": 8,
2742
- // "numConfirmations": 20,
2743
- // "destAddress": { address: "0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722" }
2744
- // }
2745
- // ],
2746
- // "page": 1,
2747
- // "pageSize": 20,
2748
- // "hasNext": false
2749
- // }
2750
- // }
2751
- //
2752
- const data = this.safeDict(response, 'data', {});
2753
- const transactions = this.safeList(data, 'data', []);
2754
- return this.parseTransactions(transactions, currency, since, limit);
2755
- }
2756
- parseTransactionStatus(status) {
2757
- const statuses = {
2758
- 'reviewing': 'pending',
2759
- 'pending': 'pending',
2760
- 'confirmed': 'ok',
2761
- 'rejected': 'rejected',
2762
- };
2763
- return this.safeString(statuses, status, status);
2764
- }
2765
- parseTransaction(transaction, currency = undefined) {
2766
- //
2767
- // {
2768
- // "requestId": "wuzd1Ojsqtz4bCA3UXwtUnnJDmU8PiyB",
2769
- // "time": 1591606166000,
2770
- // "asset": "USDT",
2771
- // "transactionType": "deposit",
2772
- // "amount": "25",
2773
- // "commission": "0",
2774
- // "networkTransactionId": "0xbc4eabdce92f14dbcc01d799a5f8ca1f02f4a3a804b6350ea202be4d3c738fce",
2775
- // "status": "pending",
2776
- // "numConfirmed": 8,
2777
- // "numConfirmations": 20,
2778
- // "destAddress": {
2779
- // "address": "0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722",
2780
- // "destTag": "..." // for currencies that have it
2781
- // }
2782
- // }
2783
- //
2784
- const destAddress = this.safeDict(transaction, 'destAddress', {});
2785
- const address = this.safeString(destAddress, 'address');
2786
- const tag = this.safeString(destAddress, 'destTag');
2787
- const timestamp = this.safeInteger(transaction, 'time');
2788
- const currencyId = this.safeString(transaction, 'asset');
2789
- let amountString = this.safeString(transaction, 'amount');
2790
- const feeCostString = this.safeString(transaction, 'commission');
2791
- amountString = Precise["default"].stringSub(amountString, feeCostString);
2792
- const code = this.safeCurrencyCode(currencyId, currency);
2793
- return {
2794
- 'info': transaction,
2795
- 'id': this.safeString(transaction, 'requestId'),
2796
- 'txid': this.safeString(transaction, 'networkTransactionId'),
2797
- 'type': this.safeString(transaction, 'transactionType'),
2798
- 'currency': code,
2799
- 'network': undefined,
2800
- 'amount': this.parseNumber(amountString),
2801
- 'status': this.parseTransactionStatus(this.safeString(transaction, 'status')),
2802
- 'timestamp': timestamp,
2803
- 'datetime': this.iso8601(timestamp),
2804
- 'address': address,
2805
- 'addressFrom': undefined,
2806
- 'addressTo': address,
2807
- 'tag': tag,
2808
- 'tagFrom': undefined,
2809
- 'tagTo': tag,
2810
- 'updated': undefined,
2811
- 'comment': undefined,
2812
- 'fee': {
2813
- 'currency': code,
2814
- 'cost': this.parseNumber(feeCostString),
2815
- 'rate': undefined,
2816
- },
2817
- 'internal': false,
2818
- };
2819
- }
2820
- /**
2821
- * @method
2822
- * @name ascendex#fetchPositions
2823
- * @description fetch all open positions
2824
- * @param {string[]|undefined} symbols list of unified market symbols
2825
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2826
- * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/?id=position-structure}
2827
- */
2828
- async fetchPositions(symbols = undefined, params = {}) {
2829
- await this.loadMarkets();
2830
- await this.loadAccounts();
2831
- const account = this.safeDict(this.accounts, 0, {});
2832
- const accountGroup = this.safeString(account, 'id');
2833
- const request = {
2834
- 'account-group': accountGroup,
2835
- };
2836
- const response = await this.v2PrivateAccountGroupGetFuturesPosition(this.extend(request, params));
2837
- //
2838
- // {
2839
- // "code": 0,
2840
- // "data": {
2841
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
2842
- // "ac": "FUTURES",
2843
- // "collaterals": [
2844
- // {
2845
- // "asset": "USDT",
2846
- // "balance": "44.570287262",
2847
- // "referencePrice": "1",
2848
- // "discountFactor": "1"
2849
- // }
2850
- // ],
2851
- // "contracts": [
2852
- // {
2853
- // "symbol": "BTC-PERP",
2854
- // "side": "LONG",
2855
- // "position": "0.0001",
2856
- // "referenceCost": "-3.12277254",
2857
- // "unrealizedPnl": "-0.001700233",
2858
- // "realizedPnl": "0",
2859
- // "avgOpenPrice": "31209",
2860
- // "marginType": "isolated",
2861
- // "isolatedMargin": "1.654972977",
2862
- // "leverage": "2",
2863
- // "takeProfitPrice": "0",
2864
- // "takeProfitTrigger": "market",
2865
- // "stopLossPrice": "0",
2866
- // "stopLossTrigger": "market",
2867
- // "buyOpenOrderNotional": "0",
2868
- // "sellOpenOrderNotional": "0",
2869
- // "markPrice": "31210.723063672",
2870
- // "indexPrice": "31223.148857925"
2871
- // },
2872
- // ]
2873
- // }
2874
- // }
2875
- //
2876
- const data = this.safeDict(response, 'data', {});
2877
- const position = this.safeList(data, 'contracts', []);
2878
- const result = [];
2879
- for (let i = 0; i < position.length; i++) {
2880
- result.push(this.parsePosition(position[i]));
2881
- }
2882
- symbols = this.marketSymbols(symbols);
2883
- return this.filterByArrayPositions(result, 'symbol', symbols, false);
2884
- }
2885
- parsePosition(position, market = undefined) {
2886
- //
2887
- // {
2888
- // "symbol": "BTC-PERP",
2889
- // "side": "LONG",
2890
- // "position": "0.0001",
2891
- // "referenceCost": "-3.12277254",
2892
- // "unrealizedPnl": "-0.001700233",
2893
- // "realizedPnl": "0",
2894
- // "avgOpenPrice": "31209",
2895
- // "marginType": "isolated",
2896
- // "isolatedMargin": "1.654972977",
2897
- // "leverage": "2",
2898
- // "takeProfitPrice": "0",
2899
- // "takeProfitTrigger": "market",
2900
- // "stopLossPrice": "0",
2901
- // "stopLossTrigger": "market",
2902
- // "buyOpenOrderNotional": "0",
2903
- // "sellOpenOrderNotional": "0",
2904
- // "markPrice": "31210.723063672",
2905
- // "indexPrice": "31223.148857925"
2906
- // },
2907
- //
2908
- const marketId = this.safeString(position, 'symbol');
2909
- market = this.safeMarket(marketId, market);
2910
- let notional = this.safeString(position, 'buyOpenOrderNotional');
2911
- if (Precise["default"].stringEq(notional, '0')) {
2912
- notional = this.safeString(position, 'sellOpenOrderNotional');
2913
- }
2914
- const marginType = this.safeString(position, 'marginType');
2915
- const marginMode = (marginType === 'crossed') ? 'cross' : 'isolated';
2916
- let collateral = undefined;
2917
- if (marginMode === 'isolated') {
2918
- collateral = this.safeString(position, 'isolatedMargin');
2919
- }
2920
- return this.safePosition({
2921
- 'info': position,
2922
- 'id': undefined,
2923
- 'symbol': market['symbol'],
2924
- 'notional': this.parseNumber(notional),
2925
- 'marginMode': marginMode,
2926
- 'liquidationPrice': undefined,
2927
- 'entryPrice': this.safeNumber(position, 'avgOpenPrice'),
2928
- 'unrealizedPnl': this.safeNumber(position, 'unrealizedPnl'),
2929
- 'percentage': undefined,
2930
- 'contracts': this.safeNumber(position, 'position'),
2931
- 'contractSize': this.safeNumber(market, 'contractSize'),
2932
- 'markPrice': this.safeNumber(position, 'markPrice'),
2933
- 'lastPrice': undefined,
2934
- 'side': this.safeStringLower(position, 'side'),
2935
- 'hedged': undefined,
2936
- 'timestamp': undefined,
2937
- 'datetime': undefined,
2938
- 'lastUpdateTimestamp': undefined,
2939
- 'maintenanceMargin': undefined,
2940
- 'maintenanceMarginPercentage': undefined,
2941
- 'collateral': collateral,
2942
- 'initialMargin': undefined,
2943
- 'initialMarginPercentage': undefined,
2944
- 'leverage': this.safeInteger(position, 'leverage'),
2945
- 'marginRatio': undefined,
2946
- 'stopLossPrice': this.safeNumber(position, 'stopLossPrice'),
2947
- 'takeProfitPrice': this.safeNumber(position, 'takeProfitPrice'),
2948
- });
2949
- }
2950
- parseFundingRate(contract, market = undefined) {
2951
- //
2952
- // {
2953
- // "time": 1640061364830,
2954
- // "symbol": "EOS-PERP",
2955
- // "markPrice": "3.353854865",
2956
- // "indexPrice": "3.3542",
2957
- // "openInterest": "14242",
2958
- // "fundingRate": "-0.000073026",
2959
- // "nextFundingTime": 1640073600000
2960
- // }
2961
- //
2962
- const marketId = this.safeString(contract, 'symbol');
2963
- const symbol = this.safeSymbol(marketId, market);
2964
- const currentTime = this.safeInteger(contract, 'time');
2965
- const nextFundingRate = this.safeNumber(contract, 'fundingRate');
2966
- const nextFundingRateTimestamp = this.safeInteger(contract, 'nextFundingTime');
2967
- return {
2968
- 'info': contract,
2969
- 'symbol': symbol,
2970
- 'markPrice': this.safeNumber(contract, 'markPrice'),
2971
- 'indexPrice': this.safeNumber(contract, 'indexPrice'),
2972
- 'interestRate': this.parseNumber('0'),
2973
- 'estimatedSettlePrice': undefined,
2974
- 'timestamp': currentTime,
2975
- 'datetime': this.iso8601(currentTime),
2976
- 'previousFundingRate': undefined,
2977
- 'nextFundingRate': undefined,
2978
- 'previousFundingTimestamp': undefined,
2979
- 'nextFundingTimestamp': undefined,
2980
- 'previousFundingDatetime': undefined,
2981
- 'nextFundingDatetime': undefined,
2982
- 'fundingRate': nextFundingRate,
2983
- 'fundingTimestamp': nextFundingRateTimestamp,
2984
- 'fundingDatetime': this.iso8601(nextFundingRateTimestamp),
2985
- 'interval': undefined,
2986
- };
2987
- }
2988
- /**
2989
- * @method
2990
- * @name ascendex#fetchFundingRates
2991
- * @description fetch the funding rate for multiple markets
2992
- * @param {string[]|undefined} symbols list of unified market symbols
2993
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2994
- * @returns {object[]} a list of [funding rates structures]{@link https://docs.ccxt.com/?id=funding-rates-structure}, indexe by market symbols
2995
- */
2996
- async fetchFundingRates(symbols = undefined, params = {}) {
2997
- await this.loadMarkets();
2998
- symbols = this.marketSymbols(symbols);
2999
- const response = await this.v2PublicGetFuturesPricingData(params);
3000
- //
3001
- // {
3002
- // "code": 0,
3003
- // "data": {
3004
- // "contracts": [
3005
- // {
3006
- // "time": 1640061364830,
3007
- // "symbol": "EOS-PERP",
3008
- // "markPrice": "3.353854865",
3009
- // "indexPrice": "3.3542",
3010
- // "openInterest": "14242",
3011
- // "fundingRate": "-0.000073026",
3012
- // "nextFundingTime": 1640073600000
3013
- // },
3014
- // ],
3015
- // "collaterals": [
3016
- // {
3017
- // "asset": "USDTR",
3018
- // "referencePrice": "1"
3019
- // },
3020
- // ]
3021
- // }
3022
- // }
3023
- //
3024
- const data = this.safeDict(response, 'data', {});
3025
- const contracts = this.safeList(data, 'contracts', []);
3026
- return this.parseFundingRates(contracts, symbols);
3027
- }
3028
- async modifyMarginHelper(symbol, amount, type, params = {}) {
3029
- await this.loadMarkets();
3030
- await this.loadAccounts();
3031
- const market = this.market(symbol);
3032
- const account = this.safeDict(this.accounts, 0, {});
3033
- const accountGroup = this.safeString(account, 'id');
3034
- amount = this.amountToPrecision(symbol, amount);
3035
- const request = {
3036
- 'account-group': accountGroup,
3037
- 'symbol': market['id'],
3038
- 'amount': amount, // positive value for adding margin, negative for reducing
3039
- };
3040
- const response = await this.v2PrivateAccountGroupPostFuturesIsolatedPositionMargin(this.extend(request, params));
3041
- //
3042
- // Can only change margin for perpetual futures isolated margin positions
3043
- //
3044
- // {
3045
- // "code": 0
3046
- // }
3047
- //
3048
- if (type === 'reduce') {
3049
- amount = Precise["default"].stringAbs(amount);
3050
- }
3051
- const parsedAmount = this.parseNumber(amount);
3052
- return this.extend(this.parseMarginModification(response, market), {
3053
- 'amount': parsedAmount,
3054
- 'type': type,
3055
- });
3056
- }
3057
- parseMarginModification(data, market = undefined) {
3058
- //
3059
- // addMargin/reduceMargin
3060
- //
3061
- // {
3062
- // "code": 0
3063
- // }
3064
- //
3065
- const errorCode = this.safeString(data, 'code');
3066
- const status = (errorCode === '0') ? 'ok' : 'failed';
3067
- return {
3068
- 'info': data,
3069
- 'symbol': this.safeString(market, 'symbol'),
3070
- 'type': undefined,
3071
- 'marginMode': 'isolated',
3072
- 'amount': undefined,
3073
- 'total': undefined,
3074
- 'code': this.safeString(market, 'quote'),
3075
- 'status': status,
3076
- 'timestamp': undefined,
3077
- 'datetime': undefined,
3078
- };
3079
- }
3080
- /**
3081
- * @method
3082
- * @name ascendex#reduceMargin
3083
- * @description remove margin from a position
3084
- * @param {string} symbol unified market symbol
3085
- * @param {float} amount the amount of margin to remove
3086
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3087
- * @returns {object} a [margin structure]{@link https://docs.ccxt.com/?id=margin-structure}
3088
- */
3089
- async reduceMargin(symbol, amount, params = {}) {
3090
- return await this.modifyMarginHelper(symbol, -amount, 'reduce', params);
3091
- }
3092
- /**
3093
- * @method
3094
- * @name ascendex#addMargin
3095
- * @description add margin
3096
- * @param {string} symbol unified market symbol
3097
- * @param {float} amount amount of margin to add
3098
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3099
- * @returns {object} a [margin structure]{@link https://docs.ccxt.com/?id=margin-structure}
3100
- */
3101
- async addMargin(symbol, amount, params = {}) {
3102
- return await this.modifyMarginHelper(symbol, amount, 'add', params);
3103
- }
3104
- /**
3105
- * @method
3106
- * @name ascendex#setLeverage
3107
- * @description set the level of leverage for a market
3108
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-contract-leverage
3109
- * @param {float} leverage the rate of leverage
3110
- * @param {string} symbol unified market symbol
3111
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3112
- * @returns {object} response from the exchange
3113
- */
3114
- async setLeverage(leverage, symbol = undefined, params = {}) {
3115
- if (symbol === undefined) {
3116
- throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
3117
- }
3118
- if ((leverage < 1) || (leverage > 100)) {
3119
- throw new errors.BadRequest(this.id + ' leverage should be between 1 and 100');
3120
- }
3121
- await this.loadMarkets();
3122
- await this.loadAccounts();
3123
- const market = this.market(symbol);
3124
- if (!market['swap']) {
3125
- throw new errors.BadSymbol(this.id + ' setLeverage() supports swap contracts only');
3126
- }
3127
- const account = this.safeDict(this.accounts, 0, {});
3128
- const accountGroup = this.safeString(account, 'id');
3129
- const request = {
3130
- 'account-group': accountGroup,
3131
- 'symbol': market['id'],
3132
- 'leverage': leverage,
3133
- };
3134
- return await this.v2PrivateAccountGroupPostFuturesLeverage(this.extend(request, params));
3135
- }
3136
- /**
3137
- * @method
3138
- * @name ascendex#setMarginMode
3139
- * @description set margin mode to 'cross' or 'isolated'
3140
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-margin-type
3141
- * @param {string} marginMode 'cross' or 'isolated'
3142
- * @param {string} symbol unified market symbol
3143
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3144
- * @returns {object} response from the exchange
3145
- */
3146
- async setMarginMode(marginMode, symbol = undefined, params = {}) {
3147
- if (symbol === undefined) {
3148
- throw new errors.ArgumentsRequired(this.id + ' setMarginMode() requires a symbol argument');
3149
- }
3150
- marginMode = marginMode.toLowerCase();
3151
- if (marginMode === 'cross') {
3152
- marginMode = 'crossed';
3153
- }
3154
- if (marginMode !== 'isolated' && marginMode !== 'crossed') {
3155
- throw new errors.BadRequest(this.id + ' setMarginMode() marginMode argument should be isolated or cross');
3156
- }
3157
- await this.loadMarkets();
3158
- await this.loadAccounts();
3159
- const market = this.market(symbol);
3160
- const account = this.safeDict(this.accounts, 0, {});
3161
- const accountGroup = this.safeString(account, 'id');
3162
- const request = {
3163
- 'account-group': accountGroup,
3164
- 'symbol': market['id'],
3165
- 'marginType': marginMode,
3166
- };
3167
- if (!market['swap']) {
3168
- throw new errors.BadSymbol(this.id + ' setMarginMode() supports swap contracts only');
3169
- }
3170
- return await this.v2PrivateAccountGroupPostFuturesMarginType(this.extend(request, params));
3171
- }
3172
- /**
3173
- * @method
3174
- * @name ascendex#fetchLeverageTiers
3175
- * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
3176
- * @param {string[]|undefined} symbols list of unified market symbols
3177
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3178
- * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/?id=leverage-tiers-structure}, indexed by market symbols
3179
- */
3180
- async fetchLeverageTiers(symbols = undefined, params = {}) {
3181
- await this.loadMarkets();
3182
- const response = await this.v2PublicGetFuturesContract(params);
3183
- //
3184
- // {
3185
- // "code":0,
3186
- // "data":[
3187
- // {
3188
- // "symbol":"BTC-PERP",
3189
- // "status":"Normal",
3190
- // "displayName":"BTCUSDT",
3191
- // "settlementAsset":"USDT",
3192
- // "underlying":"BTC/USDT",
3193
- // "tradingStartTime":1579701600000,
3194
- // "priceFilter":{"minPrice":"1","maxPrice":"1000000","tickSize":"1"},
3195
- // "lotSizeFilter":{"minQty":"0.0001","maxQty":"1000000000","lotSize":"0.0001"},
3196
- // "commissionType":"Quote",
3197
- // "commissionReserveRate":"0.001",
3198
- // "marketOrderPriceMarkup":"0.03",
3199
- // "marginRequirements":[
3200
- // {"positionNotionalLowerBound":"0","positionNotionalUpperBound":"50000","initialMarginRate":"0.01","maintenanceMarginRate":"0.006"},
3201
- // {"positionNotionalLowerBound":"50000","positionNotionalUpperBound":"200000","initialMarginRate":"0.02","maintenanceMarginRate":"0.012"},
3202
- // {"positionNotionalLowerBound":"200000","positionNotionalUpperBound":"2000000","initialMarginRate":"0.04","maintenanceMarginRate":"0.024"},
3203
- // {"positionNotionalLowerBound":"2000000","positionNotionalUpperBound":"20000000","initialMarginRate":"0.1","maintenanceMarginRate":"0.06"},
3204
- // {"positionNotionalLowerBound":"20000000","positionNotionalUpperBound":"40000000","initialMarginRate":"0.2","maintenanceMarginRate":"0.12"},
3205
- // {"positionNotionalLowerBound":"40000000","positionNotionalUpperBound":"1000000000","initialMarginRate":"0.333333","maintenanceMarginRate":"0.2"}
3206
- // ]
3207
- // }
3208
- // ]
3209
- // }
3210
- //
3211
- const data = this.safeList(response, 'data', []);
3212
- symbols = this.marketSymbols(symbols);
3213
- return this.parseLeverageTiers(data, symbols, 'symbol');
3214
- }
3215
- parseMarketLeverageTiers(info, market = undefined) {
3216
- /**
3217
- * @param {object} info Exchange market response for 1 market
3218
- * @param {object} market CCXT market
3219
- */
3220
- //
3221
- // {
3222
- // "symbol":"BTC-PERP",
3223
- // "status":"Normal",
3224
- // "displayName":"BTCUSDT",
3225
- // "settlementAsset":"USDT",
3226
- // "underlying":"BTC/USDT",
3227
- // "tradingStartTime":1579701600000,
3228
- // "priceFilter":{"minPrice":"1","maxPrice":"1000000","tickSize":"1"},
3229
- // "lotSizeFilter":{"minQty":"0.0001","maxQty":"1000000000","lotSize":"0.0001"},
3230
- // "commissionType":"Quote",
3231
- // "commissionReserveRate":"0.001",
3232
- // "marketOrderPriceMarkup":"0.03",
3233
- // "marginRequirements":[
3234
- // {"positionNotionalLowerBound":"0","positionNotionalUpperBound":"50000","initialMarginRate":"0.01","maintenanceMarginRate":"0.006"},
3235
- // {"positionNotionalLowerBound":"50000","positionNotionalUpperBound":"200000","initialMarginRate":"0.02","maintenanceMarginRate":"0.012"},
3236
- // {"positionNotionalLowerBound":"200000","positionNotionalUpperBound":"2000000","initialMarginRate":"0.04","maintenanceMarginRate":"0.024"},
3237
- // {"positionNotionalLowerBound":"2000000","positionNotionalUpperBound":"20000000","initialMarginRate":"0.1","maintenanceMarginRate":"0.06"},
3238
- // {"positionNotionalLowerBound":"20000000","positionNotionalUpperBound":"40000000","initialMarginRate":"0.2","maintenanceMarginRate":"0.12"},
3239
- // {"positionNotionalLowerBound":"40000000","positionNotionalUpperBound":"1000000000","initialMarginRate":"0.333333","maintenanceMarginRate":"0.2"}
3240
- // ]
3241
- // }
3242
- //
3243
- const marginRequirements = this.safeList(info, 'marginRequirements', []);
3244
- const marketId = this.safeString(info, 'symbol');
3245
- market = this.safeMarket(marketId, market);
3246
- const tiers = [];
3247
- for (let i = 0; i < marginRequirements.length; i++) {
3248
- const tier = marginRequirements[i];
3249
- const initialMarginRate = this.safeString(tier, 'initialMarginRate');
3250
- tiers.push({
3251
- 'tier': this.sum(i, 1),
3252
- 'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
3253
- 'currency': market['quote'],
3254
- 'minNotional': this.safeNumber(tier, 'positionNotionalLowerBound'),
3255
- 'maxNotional': this.safeNumber(tier, 'positionNotionalUpperBound'),
3256
- 'maintenanceMarginRate': this.safeNumber(tier, 'maintenanceMarginRate'),
3257
- 'maxLeverage': this.parseNumber(Precise["default"].stringDiv('1', initialMarginRate)),
3258
- 'info': tier,
3259
- });
3260
- }
3261
- return tiers;
3262
- }
3263
- parseDepositWithdrawFee(fee, currency = undefined) {
3264
- //
3265
- // {
3266
- // "assetCode": "USDT",
3267
- // "assetName": "Tether",
3268
- // "precisionScale": 9,
3269
- // "nativeScale": 4,
3270
- // "blockChain": [
3271
- // {
3272
- // "chainName": "Omni",
3273
- // "withdrawFee": "30.0",
3274
- // "allowDeposit": true,
3275
- // "allowWithdraw": true,
3276
- // "minDepositAmt": "0.0",
3277
- // "minWithdrawal": "50.0",
3278
- // "numConfirmations": 3
3279
- // },
3280
- // ]
3281
- // }
3282
- //
3283
- const blockChains = this.safeList(fee, 'blockChain', []);
3284
- const blockChainsLength = blockChains.length;
3285
- const result = {
3286
- 'info': fee,
3287
- 'withdraw': {
3288
- 'fee': undefined,
3289
- 'percentage': undefined,
3290
- },
3291
- 'deposit': {
3292
- 'fee': undefined,
3293
- 'percentage': undefined,
3294
- },
3295
- 'networks': {},
3296
- };
3297
- for (let i = 0; i < blockChainsLength; i++) {
3298
- const blockChain = blockChains[i];
3299
- const networkId = this.safeString(blockChain, 'chainName');
3300
- const currencyCode = this.safeString(currency, 'code');
3301
- const networkCode = this.networkIdToCode(networkId, currencyCode);
3302
- result['networks'][networkCode] = {
3303
- 'deposit': { 'fee': undefined, 'percentage': undefined },
3304
- 'withdraw': { 'fee': this.safeNumber(blockChain, 'withdrawFee'), 'percentage': false },
3305
- };
3306
- if (blockChainsLength === 1) {
3307
- result['withdraw']['fee'] = this.safeNumber(blockChain, 'withdrawFee');
3308
- result['withdraw']['percentage'] = false;
3309
- }
3310
- }
3311
- return result;
3312
- }
3313
- /**
3314
- * @method
3315
- * @name ascendex#fetchDepositWithdrawFees
3316
- * @description fetch deposit and withdraw fees
3317
- * @see https://ascendex.github.io/ascendex-pro-api/#list-all-assets
3318
- * @param {string[]|undefined} codes list of unified currency codes
3319
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3320
- * @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/?id=fee-structure}
3321
- */
3322
- async fetchDepositWithdrawFees(codes = undefined, params = {}) {
3323
- await this.loadMarkets();
3324
- const response = await this.v2PublicGetAssets(params);
3325
- const data = this.safeList(response, 'data');
3326
- return this.parseDepositWithdrawFees(data, codes, 'assetCode');
3327
- }
3328
- /**
3329
- * @method
3330
- * @name ascendex#transfer
3331
- * @description transfer currency internally between wallets on the same account
3332
- * @param {string} code unified currency codeåå
3333
- * @param {float} amount amount to transfer
3334
- * @param {string} fromAccount account to transfer from
3335
- * @param {string} toAccount account to transfer to
3336
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3337
- * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/?id=transfer-structure}
3338
- */
3339
- async transfer(code, amount, fromAccount, toAccount, params = {}) {
3340
- await this.loadMarkets();
3341
- await this.loadAccounts();
3342
- const account = this.safeDict(this.accounts, 0, {});
3343
- const accountGroup = this.safeString(account, 'id');
3344
- const currency = this.currency(code);
3345
- const accountsByType = this.safeDict(this.options, 'accountsByType', {});
3346
- const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
3347
- const toId = this.safeString(accountsByType, toAccount, toAccount);
3348
- if (fromId !== 'cash' && toId !== 'cash') {
3349
- throw new errors.ExchangeError(this.id + ' transfer() only supports direct balance transfer between spot and swap, spot and margin');
3350
- }
3351
- const request = {
3352
- 'account-group': accountGroup,
3353
- 'amount': this.currencyToPrecision(code, amount),
3354
- 'asset': currency['id'],
3355
- 'fromAccount': fromId,
3356
- 'toAccount': toId,
3357
- };
3358
- const response = await this.v1PrivateAccountGroupPostTransfer(this.extend(request, params));
3359
- //
3360
- // { "code": "0" }
3361
- //
3362
- const transferOptions = this.safeDict(this.options, 'transfer', {});
3363
- const fillResponseFromRequest = this.safeBool(transferOptions, 'fillResponseFromRequest', true);
3364
- const transfer = this.parseTransfer(response, currency);
3365
- if (fillResponseFromRequest) {
3366
- transfer['fromAccount'] = fromAccount;
3367
- transfer['toAccount'] = toAccount;
3368
- transfer['amount'] = amount;
3369
- transfer['currency'] = code;
3370
- }
3371
- return transfer;
3372
- }
3373
- parseTransfer(transfer, currency = undefined) {
3374
- //
3375
- // { "code": "0" }
3376
- //
3377
- const status = this.safeString(transfer, 'code');
3378
- const currencyCode = this.safeCurrencyCode(undefined, currency);
3379
- return {
3380
- 'info': transfer,
3381
- 'id': undefined,
3382
- 'timestamp': undefined,
3383
- 'datetime': undefined,
3384
- 'currency': currencyCode,
3385
- 'amount': undefined,
3386
- 'fromAccount': undefined,
3387
- 'toAccount': undefined,
3388
- 'status': this.parseTransferStatus(status),
3389
- };
3390
- }
3391
- parseTransferStatus(status) {
3392
- if (status === '0') {
3393
- return 'ok';
3394
- }
3395
- return 'failed';
3396
- }
3397
- /**
3398
- * @method
3399
- * @name ascendex#fetchFundingHistory
3400
- * @description fetch the history of funding payments paid and received on this account
3401
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#funding-payment-history
3402
- * @param {string} [symbol] unified market symbol
3403
- * @param {int} [since] the earliest time in ms to fetch funding history for
3404
- * @param {int} [limit] the maximum number of funding history structures to retrieve
3405
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3406
- * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3407
- * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/?id=funding-history-structure}
3408
- */
3409
- async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3410
- await this.loadMarkets();
3411
- await this.loadAccounts();
3412
- let paginate = false;
3413
- [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingHistory', 'paginate');
3414
- if (paginate) {
3415
- return await this.fetchPaginatedCallIncremental('fetchFundingHistory', symbol, since, limit, params, 'page', 25);
3416
- }
3417
- const account = this.safeDict(this.accounts, 0, {});
3418
- const accountGroup = this.safeString(account, 'id');
3419
- const request = {
3420
- 'account-group': accountGroup,
3421
- };
3422
- let market = undefined;
3423
- if (symbol !== undefined) {
3424
- market = this.market(symbol);
3425
- request['symbol'] = market['id'];
3426
- }
3427
- if (limit !== undefined) {
3428
- request['pageSize'] = limit;
3429
- }
3430
- const response = await this.v2PrivateAccountGroupGetFuturesFundingPayments(this.extend(request, params));
3431
- //
3432
- // {
3433
- // "code": 0,
3434
- // "data": {
3435
- // "data": [
3436
- // {
3437
- // "timestamp": 1640476800000,
3438
- // "symbol": "BTC-PERP",
3439
- // "paymentInUSDT": "-0.013991178",
3440
- // "fundingRate": "0.000173497"
3441
- // },
3442
- // ],
3443
- // "page": 1,
3444
- // "pageSize": 3,
3445
- // "hasNext": true
3446
- // }
3447
- // }
3448
- //
3449
- const data = this.safeDict(response, 'data', {});
3450
- const rows = this.safeList(data, 'data', []);
3451
- return this.parseIncomes(rows, market, since, limit);
3452
- }
3453
- parseIncome(income, market = undefined) {
3454
- //
3455
- // {
3456
- // "timestamp": 1640476800000,
3457
- // "symbol": "BTC-PERP",
3458
- // "paymentInUSDT": "-0.013991178",
3459
- // "fundingRate": "0.000173497"
3460
- // }
3461
- //
3462
- const marketId = this.safeString(income, 'symbol');
3463
- const timestamp = this.safeInteger(income, 'timestamp');
3464
- return {
3465
- 'info': income,
3466
- 'symbol': this.safeSymbol(marketId, market, '-', 'swap'),
3467
- 'code': 'USDT',
3468
- 'timestamp': timestamp,
3469
- 'datetime': this.iso8601(timestamp),
3470
- 'id': undefined,
3471
- 'amount': this.safeNumber(income, 'paymentInUSDT'),
3472
- };
3473
- }
3474
- /**
3475
- * @method
3476
- * @name ascendex#fetchMarginModes
3477
- * @description fetches the set margin mode of the user
3478
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
3479
- * @param {string[]} [symbols] a list of unified market symbols
3480
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3481
- * @returns {object} a list of [margin mode structures]{@link https://docs.ccxt.com/?id=margin-mode-structure}
3482
- */
3483
- async fetchMarginModes(symbols = undefined, params = {}) {
3484
- await this.loadMarkets();
3485
- await this.loadAccounts();
3486
- const account = this.safeDict(this.accounts, 0, {});
3487
- const accountGroup = this.safeString(account, 'id');
3488
- const request = {
3489
- 'account-group': accountGroup,
3490
- };
3491
- const response = await this.v2PrivateAccountGroupGetFuturesPosition(this.extend(request, params));
3492
- //
3493
- // {
3494
- // "code": 0,
3495
- // "data": {
3496
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
3497
- // "ac": "FUTURES",
3498
- // "collaterals": [
3499
- // {
3500
- // "asset": "USDT",
3501
- // "balance": "44.570287262",
3502
- // "referencePrice": "1",
3503
- // "discountFactor": "1"
3504
- // }
3505
- // ],
3506
- // "contracts": [
3507
- // {
3508
- // "symbol": "BTC-PERP",
3509
- // "side": "LONG",
3510
- // "position": "0.0001",
3511
- // "referenceCost": "-3.12277254",
3512
- // "unrealizedPnl": "-0.001700233",
3513
- // "realizedPnl": "0",
3514
- // "avgOpenPrice": "31209",
3515
- // "marginType": "isolated",
3516
- // "isolatedMargin": "1.654972977",
3517
- // "leverage": "2",
3518
- // "takeProfitPrice": "0",
3519
- // "takeProfitTrigger": "market",
3520
- // "stopLossPrice": "0",
3521
- // "stopLossTrigger": "market",
3522
- // "buyOpenOrderNotional": "0",
3523
- // "sellOpenOrderNotional": "0",
3524
- // "markPrice": "31210.723063672",
3525
- // "indexPrice": "31223.148857925"
3526
- // },
3527
- // ]
3528
- // }
3529
- // }
3530
- //
3531
- const data = this.safeDict(response, 'data', {});
3532
- const marginModes = this.safeList(data, 'contracts', []);
3533
- return this.parseMarginModes(marginModes, symbols, 'symbol');
3534
- }
3535
- parseMarginMode(marginMode, market = undefined) {
3536
- const marketId = this.safeString(marginMode, 'symbol');
3537
- const marginType = this.safeString(marginMode, 'marginType');
3538
- const margin = (marginType === 'crossed') ? 'cross' : 'isolated';
3539
- return {
3540
- 'info': marginMode,
3541
- 'symbol': this.safeSymbol(marketId, market),
3542
- 'marginMode': margin,
3543
- };
3544
- }
3545
- /**
3546
- * @method
3547
- * @name ascendex#fetchLeverages
3548
- * @description fetch the set leverage for all contract markets
3549
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
3550
- * @param {string[]} [symbols] a list of unified market symbols
3551
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3552
- * @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/?id=leverage-structure}
3553
- */
3554
- async fetchLeverages(symbols = undefined, params = {}) {
3555
- await this.loadMarkets();
3556
- await this.loadAccounts();
3557
- const account = this.safeDict(this.accounts, 0, {});
3558
- const accountGroup = this.safeString(account, 'id');
3559
- const request = {
3560
- 'account-group': accountGroup,
3561
- };
3562
- const response = await this.v2PrivateAccountGroupGetFuturesPosition(this.extend(request, params));
3563
- //
3564
- // {
3565
- // "code": 0,
3566
- // "data": {
3567
- // "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
3568
- // "ac": "FUTURES",
3569
- // "collaterals": [
3570
- // {
3571
- // "asset": "USDT",
3572
- // "balance": "44.570287262",
3573
- // "referencePrice": "1",
3574
- // "discountFactor": "1"
3575
- // }
3576
- // ],
3577
- // "contracts": [
3578
- // {
3579
- // "symbol": "BTC-PERP",
3580
- // "side": "LONG",
3581
- // "position": "0.0001",
3582
- // "referenceCost": "-3.12277254",
3583
- // "unrealizedPnl": "-0.001700233",
3584
- // "realizedPnl": "0",
3585
- // "avgOpenPrice": "31209",
3586
- // "marginType": "isolated",
3587
- // "isolatedMargin": "1.654972977",
3588
- // "leverage": "2",
3589
- // "takeProfitPrice": "0",
3590
- // "takeProfitTrigger": "market",
3591
- // "stopLossPrice": "0",
3592
- // "stopLossTrigger": "market",
3593
- // "buyOpenOrderNotional": "0",
3594
- // "sellOpenOrderNotional": "0",
3595
- // "markPrice": "31210.723063672",
3596
- // "indexPrice": "31223.148857925"
3597
- // },
3598
- // ]
3599
- // }
3600
- // }
3601
- //
3602
- const data = this.safeDict(response, 'data', {});
3603
- const leverages = this.safeList(data, 'contracts', []);
3604
- return this.parseLeverages(leverages, symbols, 'symbol');
3605
- }
3606
- /**
3607
- * @method
3608
- * @name ascendex#fetchOpenInterests
3609
- * @description Retrieves the open interest for a list of symbols
3610
- * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#futures-pricing-data
3611
- * @param {string[]} [symbols] a list of unified CCXT market symbols
3612
- * @param {object} [params] exchange specific parameters
3613
- * @returns {object[]} a list of [open interest structures]{@link https://docs.ccxt.com/?id=open-interest-structure}
3614
- */
3615
- async fetchOpenInterests(symbols = undefined, params = {}) {
3616
- await this.loadMarkets();
3617
- const request = {};
3618
- const response = await this.v2PublicGetFuturesPricingData(this.extend(request, params));
3619
- //
3620
- // {
3621
- // code: '0',
3622
- // data: {
3623
- // contracts: [
3624
- // {
3625
- // time: '1772138885616',
3626
- // symbol: 'ZIL-PERP',
3627
- // markPrice: '0.004167783',
3628
- // indexPrice: '0.004168',
3629
- // lastPrice: '0.00416',
3630
- // openInterest: '7685003',
3631
- // fundingRate: '0.0003',
3632
- // nextFundingTime: '1772139600000'
3633
- // },
3634
- // ]
3635
- // collaterals: [
3636
- // { asset: 'TAO', referencePrice: '182.15' },
3637
- // ...
3638
- // ]
3639
- // }
3640
- // }
3641
- //
3642
- symbols = this.marketSymbols(symbols);
3643
- const data = this.safeDict(response, 'data', {});
3644
- const contracts = this.safeList(data, 'contracts', []);
3645
- return this.parseOpenInterests(contracts, symbols);
3646
- }
3647
- parseOpenInterest(interest, market = undefined) {
3648
- //
3649
- // fetchOpenInterests
3650
- //
3651
- // {
3652
- // time: '1772138885616',
3653
- // symbol: 'ZIL-PERP',
3654
- // markPrice: '0.004167783',
3655
- // indexPrice: '0.004168',
3656
- // lastPrice: '0.00416',
3657
- // openInterest: '7685003',
3658
- // fundingRate: '0.0003',
3659
- // nextFundingTime: '1772139600000'
3660
- // }
3661
- //
3662
- const marketId = this.safeString(interest, 'symbol');
3663
- const timestamp = this.safeInteger(interest, 'time');
3664
- const openInterest = this.safeNumber(interest, 'openInterest');
3665
- return this.safeOpenInterest({
3666
- 'info': interest,
3667
- 'symbol': this.safeSymbol(marketId, market, undefined, 'swap'),
3668
- 'baseVolume': openInterest, // deprecated
3669
- 'quoteVolume': undefined, // deprecated
3670
- 'openInterestAmount': openInterest,
3671
- 'openInterestValue': undefined,
3672
- 'timestamp': timestamp,
3673
- 'datetime': this.iso8601(timestamp),
3674
- }, market);
3675
- }
3676
- parseLeverage(leverage, market = undefined) {
3677
- const marketId = this.safeString(leverage, 'symbol');
3678
- const leverageValue = this.safeInteger(leverage, 'leverage');
3679
- const marginType = this.safeString(leverage, 'marginType');
3680
- const marginMode = (marginType === 'crossed') ? 'cross' : 'isolated';
3681
- return {
3682
- 'info': leverage,
3683
- 'symbol': this.safeSymbol(marketId, market),
3684
- 'marginMode': marginMode,
3685
- 'longLeverage': leverageValue,
3686
- 'shortLeverage': leverageValue,
3687
- };
3688
- }
3689
- sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3690
- const version = api[0];
3691
- const access = api[1];
3692
- const type = this.safeString(api, 2);
3693
- let url = '';
3694
- const accountCategory = (type === 'accountCategory');
3695
- if (accountCategory || (type === 'accountGroup')) {
3696
- url += this.implodeParams('/{account-group}', params);
3697
- params = this.omit(params, 'account-group');
3698
- }
3699
- let request = this.implodeParams(path, params);
3700
- url += '/api/pro/';
3701
- if (version === 'v2') {
3702
- if (type === 'data') {
3703
- request = 'data/' + version + '/' + request;
3704
- }
3705
- else {
3706
- request = version + '/' + request;
3707
- }
3708
- }
3709
- else {
3710
- url += version + '/';
3711
- }
3712
- if (accountCategory) {
3713
- url += this.implodeParams('{account-category}/', params);
3714
- }
3715
- params = this.omit(params, 'account-category');
3716
- url += request;
3717
- if ((version === 'v1') && (request === 'cash/balance') || (request === 'margin/balance')) {
3718
- request = 'balance';
3719
- }
3720
- if ((version === 'v1') && (request === 'spot/fee')) {
3721
- request = 'fee';
3722
- }
3723
- if (request.indexOf('subuser') >= 0) {
3724
- const parts = request.split('/');
3725
- request = parts[2];
3726
- }
3727
- params = this.omit(params, this.extractParams(path));
3728
- if (access === 'public') {
3729
- if (Object.keys(params).length) {
3730
- url += '?' + this.urlencode(params);
3731
- }
3732
- }
3733
- else {
3734
- this.checkRequiredCredentials();
3735
- const timestamp = this.milliseconds().toString();
3736
- const payload = timestamp + '+' + request;
3737
- const hmac = this.hmac(this.encode(payload), this.encode(this.secret), sha2_js.sha256, 'base64');
3738
- headers = {
3739
- 'x-auth-key': this.apiKey,
3740
- 'x-auth-timestamp': timestamp,
3741
- 'x-auth-signature': hmac,
3742
- };
3743
- if (method === 'GET') {
3744
- if (Object.keys(params).length) {
3745
- url += '?' + this.urlencode(params);
3746
- }
3747
- }
3748
- else {
3749
- headers['Content-Type'] = 'application/json';
3750
- body = this.json(params);
3751
- }
3752
- }
3753
- url = this.urls['api']['rest'] + url;
3754
- return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3755
- }
3756
- handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3757
- if (response === undefined) {
3758
- return undefined; // fallback to default error handler
3759
- }
3760
- //
3761
- // {"code": 6010, "message": "Not enough balance."}
3762
- // {"code": 60060, "message": "The order is already filled or canceled."}
3763
- // {"code":2100,"message":"ApiKeyFailure"}
3764
- // {"code":300001,"message":"Price is too low from market price.","reason":"INVALID_PRICE","accountId":"cshrHKLZCjlZ2ejqkmvIHHtPmLYqdnda","ac":"CASH","action":"place-order","status":"Err","info":{"symbol":"BTC/USDT"}}
3765
- //
3766
- const code = this.safeString(response, 'code');
3767
- const message = this.safeString(response, 'message');
3768
- const error = (code !== undefined) && (code !== '0');
3769
- if (error || (message !== undefined)) {
3770
- const feedback = this.id + ' ' + body;
3771
- this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
3772
- this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
3773
- this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
3774
- throw new errors.ExchangeError(feedback); // unknown message
3775
- }
3776
- return undefined;
3777
- }
3778
- }
3779
-
3780
- exports["default"] = ascendex;