ccxt 4.5.51 → 4.5.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -9
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/aster.js +1532 -1072
- package/dist/cjs/src/base/Exchange.js +29 -24
- package/dist/cjs/src/bequant.js +3 -0
- package/dist/cjs/src/binance.js +36 -37
- package/dist/cjs/src/binanceusdm.js +1 -0
- package/dist/cjs/src/grvt.js +15 -8
- package/dist/cjs/src/kraken.js +6 -1
- package/dist/cjs/src/pro/aster.js +130 -138
- package/dist/cjs/src/pro/bequant.js +4 -3
- package/dist/cjs/src/pro/binance.js +3 -0
- package/dist/cjs/src/pro/binanceusdm.js +6 -1
- package/dist/cjs/src/pro/grvt.js +3 -3
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/aster.d.ts +43 -9
- package/js/src/aster.d.ts +136 -71
- package/js/src/aster.js +1532 -1072
- package/js/src/base/Exchange.d.ts +3 -4
- package/js/src/base/Exchange.js +29 -24
- package/js/src/bequant.js +3 -0
- package/js/src/binance.js +35 -32
- package/js/src/binanceusdm.js +1 -0
- package/js/src/grvt.js +15 -8
- package/js/src/kraken.js +6 -1
- package/js/src/pro/aster.d.ts +81 -45
- package/js/src/pro/aster.js +130 -138
- package/js/src/pro/bequant.js +4 -3
- package/js/src/pro/binance.js +3 -0
- package/js/src/pro/binanceusdm.js +6 -1
- package/js/src/pro/grvt.js +3 -3
- package/package.json +2 -1
package/js/src/aster.js
CHANGED
|
@@ -3,7 +3,6 @@ import Exchange from './abstract/aster.js';
|
|
|
3
3
|
import { AccountNotEnabled, AccountSuspended, ArgumentsRequired, AuthenticationError, BadRequest, BadResponse, BadSymbol, DuplicateOrderId, ExchangeClosedByUser, ExchangeError, InsufficientFunds, InvalidNonce, InvalidOrder, MarketClosed, NetworkError, NoChange, NotSupported, OperationFailed, OperationRejected, OrderImmediatelyFillable, OrderNotFillable, OrderNotFound, PermissionDenied, RateLimitExceeded, RequestTimeout } from './base/errors.js';
|
|
4
4
|
import { TRUNCATE, TICK_SIZE } from './base/functions/number.js';
|
|
5
5
|
import Precise from './base/Precise.js';
|
|
6
|
-
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
|
|
7
6
|
import { ecdsa } from './base/functions/crypto.js';
|
|
8
7
|
import { keccak_256 as keccak } from './static_dependencies/noble-hashes/sha3.js';
|
|
9
8
|
import { secp256k1 } from './static_dependencies/noble-curves/secp256k1.js';
|
|
@@ -183,169 +182,217 @@ export default class aster extends Exchange {
|
|
|
183
182
|
'setMargin': false,
|
|
184
183
|
'setMarginMode': true,
|
|
185
184
|
'setPositionMode': true,
|
|
186
|
-
'signIn':
|
|
185
|
+
'signIn': true,
|
|
187
186
|
'transfer': true,
|
|
188
187
|
'withdraw': true,
|
|
189
188
|
},
|
|
190
189
|
'api': {
|
|
191
190
|
'fapiPublic': {
|
|
192
|
-
'get':
|
|
193
|
-
'v1/ping',
|
|
194
|
-
'v3/ping',
|
|
195
|
-
'v1/time',
|
|
196
|
-
'v3/time',
|
|
197
|
-
'v1/exchangeInfo',
|
|
198
|
-
'v3/exchangeInfo',
|
|
199
|
-
'v1/depth',
|
|
200
|
-
'v3/depth',
|
|
201
|
-
'v1/trades',
|
|
202
|
-
'v3/trades',
|
|
203
|
-
'v1/historicalTrades',
|
|
204
|
-
'v3/historicalTrades',
|
|
205
|
-
'v1/aggTrades',
|
|
206
|
-
'v3/aggTrades',
|
|
207
|
-
'v1/klines',
|
|
208
|
-
'v3/klines',
|
|
209
|
-
'v1/indexPriceKlines',
|
|
210
|
-
'v3/indexPriceKlines',
|
|
211
|
-
'v1/markPriceKlines',
|
|
212
|
-
'v3/markPriceKlines',
|
|
213
|
-
'v1/premiumIndex',
|
|
214
|
-
'v3/premiumIndex',
|
|
215
|
-
'v1/fundingRate',
|
|
216
|
-
'v3/fundingRate',
|
|
217
|
-
'v1/fundingInfo',
|
|
218
|
-
'v3/fundingInfo',
|
|
219
|
-
'v1/ticker/24hr',
|
|
220
|
-
'v3/ticker/24hr',
|
|
221
|
-
'v1/ticker/price',
|
|
222
|
-
'v3/ticker/price',
|
|
223
|
-
'v1/ticker/bookTicker',
|
|
224
|
-
'v3/ticker/bookTicker',
|
|
225
|
-
|
|
226
|
-
'v1/adlQuantile',
|
|
227
|
-
'v1/forceOrders',
|
|
228
|
-
|
|
191
|
+
'get': {
|
|
192
|
+
'v1/ping': 1,
|
|
193
|
+
'v3/ping': 1,
|
|
194
|
+
'v1/time': 1,
|
|
195
|
+
'v3/time': 1,
|
|
196
|
+
'v1/exchangeInfo': 1,
|
|
197
|
+
'v3/exchangeInfo': 1,
|
|
198
|
+
'v1/depth': 1,
|
|
199
|
+
'v3/depth': 2,
|
|
200
|
+
'v1/trades': 1,
|
|
201
|
+
'v3/trades': 1,
|
|
202
|
+
'v1/historicalTrades': 1,
|
|
203
|
+
'v3/historicalTrades': 20,
|
|
204
|
+
'v1/aggTrades': 1,
|
|
205
|
+
'v3/aggTrades': 20,
|
|
206
|
+
'v1/klines': 1,
|
|
207
|
+
'v3/klines': 1,
|
|
208
|
+
'v1/indexPriceKlines': 1,
|
|
209
|
+
'v3/indexPriceKlines': 1,
|
|
210
|
+
'v1/markPriceKlines': 1,
|
|
211
|
+
'v3/markPriceKlines': 1,
|
|
212
|
+
'v1/premiumIndex': 1,
|
|
213
|
+
'v3/premiumIndex': 1,
|
|
214
|
+
'v1/fundingRate': 1,
|
|
215
|
+
'v3/fundingRate': 1,
|
|
216
|
+
'v1/fundingInfo': 1,
|
|
217
|
+
'v3/fundingInfo': 1,
|
|
218
|
+
'v1/ticker/24hr': 1,
|
|
219
|
+
'v3/ticker/24hr': 1,
|
|
220
|
+
'v1/ticker/price': 1,
|
|
221
|
+
'v3/ticker/price': 1,
|
|
222
|
+
'v1/ticker/bookTicker': 1,
|
|
223
|
+
'v3/ticker/bookTicker': 1,
|
|
224
|
+
// different endpoints
|
|
225
|
+
'v1/adlQuantile': 1,
|
|
226
|
+
'v1/forceOrders': 1,
|
|
227
|
+
'v3/indexreferences': 1,
|
|
228
|
+
},
|
|
229
229
|
},
|
|
230
230
|
'fapiPrivate': {
|
|
231
|
-
'get':
|
|
232
|
-
'v1/positionSide/dual',
|
|
233
|
-
'v3/positionSide/dual',
|
|
234
|
-
'v1/multiAssetsMargin',
|
|
235
|
-
'v3/multiAssetsMargin',
|
|
236
|
-
'v1/order',
|
|
237
|
-
'v3/order',
|
|
238
|
-
'v1/openOrder',
|
|
239
|
-
'v3/openOrder',
|
|
240
|
-
'v1/openOrders',
|
|
241
|
-
'v3/openOrders',
|
|
242
|
-
'v1/allOrders',
|
|
243
|
-
'v3/allOrders',
|
|
244
|
-
'v2/balance',
|
|
245
|
-
'v3/balance',
|
|
246
|
-
'v3/account',
|
|
247
|
-
'
|
|
248
|
-
'
|
|
249
|
-
'
|
|
250
|
-
'v3/
|
|
251
|
-
'
|
|
252
|
-
'v3/
|
|
253
|
-
'v1/
|
|
254
|
-
'v3/
|
|
255
|
-
'v1/
|
|
256
|
-
'v3/
|
|
257
|
-
'v1/
|
|
258
|
-
'v3/
|
|
259
|
-
|
|
260
|
-
'v3/
|
|
261
|
-
'
|
|
262
|
-
'v3/
|
|
263
|
-
'v3/
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
'v3/
|
|
267
|
-
'
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
'
|
|
271
|
-
'
|
|
272
|
-
'
|
|
273
|
-
'
|
|
274
|
-
'
|
|
275
|
-
'
|
|
276
|
-
'
|
|
277
|
-
'
|
|
278
|
-
'
|
|
279
|
-
'
|
|
280
|
-
'
|
|
281
|
-
'
|
|
282
|
-
'
|
|
283
|
-
'
|
|
284
|
-
'
|
|
285
|
-
'
|
|
286
|
-
'
|
|
287
|
-
'v3/
|
|
288
|
-
'
|
|
289
|
-
'
|
|
290
|
-
'
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
'
|
|
294
|
-
'v3/
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
'
|
|
298
|
-
'v3/
|
|
299
|
-
'
|
|
300
|
-
'v3/
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
'
|
|
304
|
-
'
|
|
305
|
-
|
|
306
|
-
|
|
231
|
+
'get': {
|
|
232
|
+
'v1/positionSide/dual': 1,
|
|
233
|
+
'v3/positionSide/dual': 30,
|
|
234
|
+
'v1/multiAssetsMargin': 1,
|
|
235
|
+
'v3/multiAssetsMargin': 1,
|
|
236
|
+
'v1/order': 1,
|
|
237
|
+
'v3/order': 1,
|
|
238
|
+
'v1/openOrder': 1,
|
|
239
|
+
'v3/openOrder': 1,
|
|
240
|
+
'v1/openOrders': 1,
|
|
241
|
+
'v3/openOrders': 1,
|
|
242
|
+
'v1/allOrders': 1,
|
|
243
|
+
'v3/allOrders': 1,
|
|
244
|
+
'v2/balance': 1,
|
|
245
|
+
'v3/balance': 1,
|
|
246
|
+
'v3/account': 1,
|
|
247
|
+
'v1/positionMargin/history': 1,
|
|
248
|
+
'v3/positionMargin/history': 1,
|
|
249
|
+
'v2/positionRisk': 1,
|
|
250
|
+
'v3/positionRisk': 1,
|
|
251
|
+
'v1/userTrades': 1,
|
|
252
|
+
'v3/userTrades': 5,
|
|
253
|
+
'v1/income': 1,
|
|
254
|
+
'v3/income': 1,
|
|
255
|
+
'v1/leverageBracket': 1,
|
|
256
|
+
'v3/leverageBracket': 1,
|
|
257
|
+
'v1/commissionRate': 1,
|
|
258
|
+
'v3/commissionRate': 1,
|
|
259
|
+
// others
|
|
260
|
+
'v3/adlQuantile': 1,
|
|
261
|
+
'v3/forceOrders': 1,
|
|
262
|
+
'v3/mmp': 1,
|
|
263
|
+
'v3/accountWithJoinMargin': 1,
|
|
264
|
+
'v4/account': 1,
|
|
265
|
+
// builder
|
|
266
|
+
'v3/agent': 1,
|
|
267
|
+
'v3/builder': 1,
|
|
268
|
+
},
|
|
269
|
+
'post': {
|
|
270
|
+
'v1/positionSide/dual': 1,
|
|
271
|
+
'v3/positionSide/dual': 1,
|
|
272
|
+
'v1/multiAssetsMargin': 1,
|
|
273
|
+
'v3/multiAssetsMargin': 1,
|
|
274
|
+
'v1/order': 1,
|
|
275
|
+
'v3/order': 1,
|
|
276
|
+
'v1/order/test': 1,
|
|
277
|
+
'v3/order/test': 1,
|
|
278
|
+
'v1/batchOrders': 1,
|
|
279
|
+
'v3/batchOrders': 1,
|
|
280
|
+
'v1/asset/wallet/transfer': 1,
|
|
281
|
+
'v3/asset/wallet/transfer': 1,
|
|
282
|
+
'v1/countdownCancelAll': 1,
|
|
283
|
+
'v3/countdownCancelAll': 1,
|
|
284
|
+
'v1/leverage': 1,
|
|
285
|
+
'v3/leverage': 1,
|
|
286
|
+
'v1/marginType': 1,
|
|
287
|
+
'v3/marginType': 1,
|
|
288
|
+
'v1/positionMargin': 1,
|
|
289
|
+
'v3/positionMargin': 1,
|
|
290
|
+
'v1/listenKey': 1,
|
|
291
|
+
'v3/listenKey': 1,
|
|
292
|
+
// others
|
|
293
|
+
'v3/mmp': 1,
|
|
294
|
+
'v3/mmpReset': 1,
|
|
295
|
+
'v3/noop': 1,
|
|
296
|
+
// builder
|
|
297
|
+
'v3/approveAgent': 1,
|
|
298
|
+
'v3/updateAgent': 1,
|
|
299
|
+
'v3/approveBuilder': 1,
|
|
300
|
+
'v3/updateBuilder': 1,
|
|
301
|
+
},
|
|
302
|
+
'put': {
|
|
303
|
+
'v1/listenKey': 1,
|
|
304
|
+
'v3/listenKey': 1,
|
|
305
|
+
},
|
|
306
|
+
'delete': {
|
|
307
|
+
'v1/order': 1,
|
|
308
|
+
'v3/order': 1,
|
|
309
|
+
'v1/allOpenOrders': 1,
|
|
310
|
+
'v3/allOpenOrders': 1,
|
|
311
|
+
'v1/batchOrders': 1,
|
|
312
|
+
'v3/batchOrders': 1,
|
|
313
|
+
'v3/mmp': 1,
|
|
314
|
+
'v1/listenKey': 1,
|
|
315
|
+
'v3/listenKey': 1,
|
|
316
|
+
// builder
|
|
317
|
+
'v3/agent': 1,
|
|
318
|
+
'v3/builder': 1,
|
|
319
|
+
},
|
|
307
320
|
},
|
|
308
321
|
'sapiPublic': {
|
|
309
|
-
'get':
|
|
310
|
-
|
|
311
|
-
'v1/
|
|
312
|
-
'v1/
|
|
313
|
-
'v1/
|
|
314
|
-
'v1/
|
|
315
|
-
'v1/
|
|
316
|
-
'v1/
|
|
317
|
-
'v1/
|
|
318
|
-
'v1/
|
|
319
|
-
'v1/ticker/
|
|
320
|
-
'v1/ticker/
|
|
321
|
-
'v1/
|
|
322
|
-
|
|
322
|
+
'get': {
|
|
323
|
+
// v1
|
|
324
|
+
'v1/ping': 1,
|
|
325
|
+
'v1/time': 1,
|
|
326
|
+
'v1/exchangeInfo': 1,
|
|
327
|
+
'v1/depth': 1,
|
|
328
|
+
'v1/trades': 1,
|
|
329
|
+
'v1/historicalTrades': 1,
|
|
330
|
+
'v1/aggTrades': 1,
|
|
331
|
+
'v1/klines': 1,
|
|
332
|
+
'v1/ticker/24hr': 1,
|
|
333
|
+
'v1/ticker/price': 1,
|
|
334
|
+
'v1/ticker/bookTicker': 1,
|
|
335
|
+
'v1/aster/withdraw/estimateFee': 1,
|
|
336
|
+
// v3
|
|
337
|
+
'v3/ping': 1,
|
|
338
|
+
'v3/time': 1,
|
|
339
|
+
'v3/exchangeInfo': 1,
|
|
340
|
+
'v3/depth': { 'cost': 2, 'byLimit': [[50, 2], [100, 5], [500, 10], [1000, 20]] },
|
|
341
|
+
'v3/trades': 1,
|
|
342
|
+
'v3/historicalTrades': 20,
|
|
343
|
+
'v3/aggTrades': 20,
|
|
344
|
+
'v3/klines': { 'cost': 1, 'byLimit': [[99, 1], [499, 2], [1000, 5], [10000, 10]] },
|
|
345
|
+
'v3/ticker/24hr': { 'cost': 1, 'noSymbol': 40 },
|
|
346
|
+
'v3/ticker/price': { 'cost': 1, 'noSymbol': 2 },
|
|
347
|
+
'v3/ticker/bookTicker': { 'cost': 1, 'noSymbol': 2 },
|
|
348
|
+
'v3/aster/withdraw/estimateFee': 1,
|
|
349
|
+
},
|
|
323
350
|
},
|
|
324
351
|
'sapiPrivate': {
|
|
325
|
-
'get':
|
|
326
|
-
|
|
327
|
-
'v1/
|
|
328
|
-
'v1/
|
|
329
|
-
'v1/
|
|
330
|
-
'v1/
|
|
331
|
-
'v1/
|
|
332
|
-
'v1/
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
'
|
|
336
|
-
'
|
|
337
|
-
'
|
|
338
|
-
'
|
|
339
|
-
'
|
|
340
|
-
|
|
352
|
+
'get': {
|
|
353
|
+
// v1
|
|
354
|
+
'v1/commissionRate': 1,
|
|
355
|
+
'v1/order': 1,
|
|
356
|
+
'v1/openOrders': 1,
|
|
357
|
+
'v1/allOrders': 1,
|
|
358
|
+
'v1/transactionHistory': 1,
|
|
359
|
+
'v1/account': 1,
|
|
360
|
+
'v1/userTrades': 1,
|
|
361
|
+
// v3
|
|
362
|
+
'v3/commissionRate': { 'cost': 1, 'noSymbol': 2 },
|
|
363
|
+
'v3/order': 1,
|
|
364
|
+
'v3/openOrders': 1,
|
|
365
|
+
'v3/allOrders': 5,
|
|
366
|
+
'v3/account': 5,
|
|
367
|
+
'v3/userTrades': 5,
|
|
368
|
+
'v3/openOrder': 1,
|
|
369
|
+
},
|
|
370
|
+
'post': {
|
|
371
|
+
// v1
|
|
372
|
+
'v1/order': 1,
|
|
373
|
+
'v1/asset/wallet/transfer': 5,
|
|
374
|
+
'v1/asset/sendToAddress': 1,
|
|
375
|
+
'v1/listenKey': 1,
|
|
376
|
+
// v3
|
|
377
|
+
'v3/order': 1,
|
|
378
|
+
'v3/asset/wallet/transfer': 5,
|
|
379
|
+
'v3/aster/user-withdraw': 1,
|
|
380
|
+
'v3/listenKey': 1,
|
|
381
|
+
},
|
|
341
382
|
'put': [
|
|
342
383
|
'v1/listenKey',
|
|
384
|
+
'v3/listenKey',
|
|
343
385
|
],
|
|
344
|
-
'delete':
|
|
345
|
-
|
|
346
|
-
'v1/
|
|
347
|
-
'v1/
|
|
348
|
-
|
|
386
|
+
'delete': {
|
|
387
|
+
// v1
|
|
388
|
+
'v1/order': 1,
|
|
389
|
+
'v1/allOpenOrders': 1,
|
|
390
|
+
'v1/listenKey': 1,
|
|
391
|
+
// v3
|
|
392
|
+
'v3/allOpenOrders': 1,
|
|
393
|
+
'v3/order': 1,
|
|
394
|
+
'v3/listenKey': 1,
|
|
395
|
+
},
|
|
349
396
|
},
|
|
350
397
|
},
|
|
351
398
|
'timeframes': {
|
|
@@ -367,8 +414,9 @@ export default class aster extends Exchange {
|
|
|
367
414
|
},
|
|
368
415
|
'precisionMode': TICK_SIZE,
|
|
369
416
|
'requiredCredentials': {
|
|
370
|
-
'apiKey':
|
|
371
|
-
'secret':
|
|
417
|
+
'apiKey': false,
|
|
418
|
+
'secret': false,
|
|
419
|
+
'privateKey': true,
|
|
372
420
|
},
|
|
373
421
|
'fees': {
|
|
374
422
|
'trading': {
|
|
@@ -383,28 +431,35 @@ export default class aster extends Exchange {
|
|
|
383
431
|
'recvWindow': 10 * 1000,
|
|
384
432
|
'defaultTimeInForce': 'GTC',
|
|
385
433
|
'zeroAddress': '0x0000000000000000000000000000000000000000',
|
|
434
|
+
'v3ChainId': 1666,
|
|
386
435
|
'quoteOrderQty': true,
|
|
387
436
|
'accountsByType': {
|
|
388
437
|
'spot': 'SPOT',
|
|
438
|
+
'swap': 'FUTURE',
|
|
389
439
|
'future': 'FUTURE',
|
|
390
440
|
'linear': 'FUTURE',
|
|
391
|
-
'swap': 'FUTURE',
|
|
392
441
|
},
|
|
393
442
|
'networks': {
|
|
394
443
|
'ERC20': 'ETH',
|
|
395
444
|
'BEP20': 'BSC',
|
|
396
|
-
'
|
|
445
|
+
'ARBONE': 'Arbitrum',
|
|
397
446
|
},
|
|
398
447
|
'networksToChainId': {
|
|
399
448
|
'ETH': 1,
|
|
400
449
|
'BSC': 56,
|
|
401
450
|
'Arbitrum': 42161,
|
|
402
451
|
},
|
|
452
|
+
'fetchOpenOrders': {
|
|
453
|
+
'warnIfNoSymbol': true, // set to false to suppress warning when calling fetchOpenOrders without symbol
|
|
454
|
+
},
|
|
455
|
+
'builderFee': true,
|
|
456
|
+
'builder': '0x1F5877C19e3777Cfd15F9d57253eA4aA5254Ec39',
|
|
457
|
+
'builderRate': '0.001',
|
|
403
458
|
},
|
|
404
459
|
'exceptions': {
|
|
405
460
|
'exact': {
|
|
406
461
|
// 10xx - General Server or Network issues
|
|
407
|
-
'-1000':
|
|
462
|
+
'-1000': OperationRejected,
|
|
408
463
|
'-1001': NetworkError,
|
|
409
464
|
'-1002': AuthenticationError,
|
|
410
465
|
'-1003': RateLimitExceeded,
|
|
@@ -412,7 +467,7 @@ export default class aster extends Exchange {
|
|
|
412
467
|
'-1005': BadRequest,
|
|
413
468
|
'-1006': BadResponse,
|
|
414
469
|
'-1007': RequestTimeout,
|
|
415
|
-
'-1010':
|
|
470
|
+
'-1010': OperationRejected,
|
|
416
471
|
'-1011': PermissionDenied,
|
|
417
472
|
'-1013': BadRequest,
|
|
418
473
|
'-1014': OrderNotFillable,
|
|
@@ -566,7 +621,9 @@ export default class aster extends Exchange {
|
|
|
566
621
|
'-4183': InvalidOrder,
|
|
567
622
|
'-4184': InvalidOrder,
|
|
568
623
|
'-5060': OperationRejected,
|
|
569
|
-
'-5076': OperationRejected,
|
|
624
|
+
'-5076': OperationRejected,
|
|
625
|
+
// occured errors:
|
|
626
|
+
'-4168': OperationRejected, // Unable to adjust to isolated-margin mode under the Multi-Assets mode.
|
|
570
627
|
},
|
|
571
628
|
'broad': {},
|
|
572
629
|
},
|
|
@@ -592,15 +649,15 @@ export default class aster extends Exchange {
|
|
|
592
649
|
* @method
|
|
593
650
|
* @name aster#fetchCurrencies
|
|
594
651
|
* @description fetches all available currencies on an exchange
|
|
595
|
-
* @see https://github.
|
|
596
|
-
* @see https://github.
|
|
652
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#trading-specification-information
|
|
653
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#exchange-information
|
|
597
654
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
598
655
|
* @returns {object} an associative dictionary of currencies
|
|
599
656
|
*/
|
|
600
657
|
async fetchCurrencies(params = {}) {
|
|
601
658
|
const promises = [
|
|
602
|
-
this.
|
|
603
|
-
this.
|
|
659
|
+
this.sapiPublicGetV3ExchangeInfo(params),
|
|
660
|
+
this.fapiPublicGetV3ExchangeInfo(params),
|
|
604
661
|
];
|
|
605
662
|
const results = await Promise.all(promises);
|
|
606
663
|
const sapiResult = this.safeDict(results, 0, {});
|
|
@@ -612,8 +669,8 @@ export default class aster extends Exchange {
|
|
|
612
669
|
// [
|
|
613
670
|
// {
|
|
614
671
|
// "asset": "USDT",
|
|
615
|
-
// "marginAvailable": true,
|
|
616
|
-
// "autoAssetExchange": "-10000"
|
|
672
|
+
// "marginAvailable": true, // only in PERP
|
|
673
|
+
// "autoAssetExchange": "-10000" // only in PERP
|
|
617
674
|
// }
|
|
618
675
|
// ]
|
|
619
676
|
//
|
|
@@ -656,263 +713,267 @@ export default class aster extends Exchange {
|
|
|
656
713
|
* @method
|
|
657
714
|
* @name aster#fetchMarkets
|
|
658
715
|
* @description retrieves data on all markets for bigone
|
|
659
|
-
* @see https://github.
|
|
660
|
-
* @see https://github.
|
|
716
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#trading-specification-information
|
|
717
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#exchange-information
|
|
661
718
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
662
719
|
* @returns {object[]} an array of objects representing market data
|
|
663
720
|
*/
|
|
664
721
|
async fetchMarkets(params = {}) {
|
|
665
722
|
const promises = [
|
|
666
|
-
this.
|
|
667
|
-
this.
|
|
723
|
+
this.sapiPublicGetV3ExchangeInfo(params),
|
|
724
|
+
this.fapiPublicGetV3ExchangeInfo(params),
|
|
668
725
|
];
|
|
726
|
+
promises.push(this.signIn());
|
|
669
727
|
const results = await Promise.all(promises);
|
|
670
728
|
const sapiResult = this.safeDict(results, 0, {});
|
|
671
729
|
const sapiRows = this.safeList(sapiResult, 'symbols', []);
|
|
672
730
|
const fapiResult = this.safeDict(results, 1, {});
|
|
673
731
|
const fapiRows = this.safeList(fapiResult, 'symbols', []);
|
|
674
|
-
|
|
732
|
+
//
|
|
733
|
+
// example:
|
|
675
734
|
//
|
|
676
735
|
// [
|
|
677
|
-
//
|
|
678
|
-
//
|
|
679
|
-
//
|
|
680
|
-
//
|
|
681
|
-
//
|
|
682
|
-
//
|
|
683
|
-
//
|
|
684
|
-
//
|
|
685
|
-
//
|
|
686
|
-
//
|
|
687
|
-
//
|
|
688
|
-
//
|
|
689
|
-
//
|
|
690
|
-
//
|
|
691
|
-
//
|
|
692
|
-
//
|
|
693
|
-
//
|
|
694
|
-
//
|
|
695
|
-
//
|
|
696
|
-
//
|
|
697
|
-
//
|
|
698
|
-
//
|
|
699
|
-
//
|
|
700
|
-
//
|
|
701
|
-
//
|
|
702
|
-
//
|
|
703
|
-
//
|
|
704
|
-
//
|
|
705
|
-
//
|
|
706
|
-
//
|
|
707
|
-
//
|
|
708
|
-
//
|
|
709
|
-
//
|
|
710
|
-
//
|
|
711
|
-
//
|
|
712
|
-
//
|
|
713
|
-
//
|
|
714
|
-
//
|
|
715
|
-
//
|
|
716
|
-
//
|
|
717
|
-
//
|
|
718
|
-
//
|
|
719
|
-
//
|
|
720
|
-
//
|
|
721
|
-
//
|
|
722
|
-
//
|
|
723
|
-
//
|
|
724
|
-
//
|
|
725
|
-
//
|
|
726
|
-
//
|
|
727
|
-
//
|
|
728
|
-
//
|
|
729
|
-
//
|
|
730
|
-
//
|
|
731
|
-
//
|
|
732
|
-
//
|
|
733
|
-
//
|
|
734
|
-
//
|
|
735
|
-
//
|
|
736
|
-
//
|
|
737
|
-
//
|
|
738
|
-
//
|
|
739
|
-
//
|
|
740
|
-
//
|
|
741
|
-
//
|
|
742
|
-
//
|
|
743
|
-
//
|
|
744
|
-
//
|
|
745
|
-
//
|
|
746
|
-
// "
|
|
747
|
-
//
|
|
748
|
-
//
|
|
749
|
-
//
|
|
750
|
-
//
|
|
751
|
-
//
|
|
752
|
-
//
|
|
753
|
-
//
|
|
736
|
+
// {
|
|
737
|
+
// symbol: "TESTUSDT",
|
|
738
|
+
// status: "TRADING",
|
|
739
|
+
// baseAsset: "TEST",
|
|
740
|
+
// quoteAsset: "USDT",
|
|
741
|
+
// pricePrecision: "2",
|
|
742
|
+
// quantityPrecision: "5",
|
|
743
|
+
// baseAssetPrecision: "8",
|
|
744
|
+
// quotePrecision: "8",
|
|
745
|
+
// listingTime: "1756289680210", // only in SPOT
|
|
746
|
+
// baseAssetAddress: null, // only in SPOT
|
|
747
|
+
// ocoAllowed: false, // only in SPOT
|
|
748
|
+
// pair: "ASTERUSDT", // only in PERP
|
|
749
|
+
// contractType: "PERPETUAL", // only in PERP
|
|
750
|
+
// deliveryDate: "4133404800000", // only in PERP
|
|
751
|
+
// onboardDate: "1758178800000", // only in PERP
|
|
752
|
+
// maintMarginPercent: "12.5000", // only in PERP
|
|
753
|
+
// requiredMarginPercent: "25.0000", // only in PERP
|
|
754
|
+
// marginAsset: "USDT", // only in PERP
|
|
755
|
+
// underlyingType: "COIN", // only in PERP
|
|
756
|
+
// underlyingSubType: [ "Top", ], // only in PERP
|
|
757
|
+
// symbolType: "0", // only in PERP
|
|
758
|
+
// tradingMode: "0", // only in PERP
|
|
759
|
+
// name: "", // only in PERP
|
|
760
|
+
// channel: "{}", // only in PERP
|
|
761
|
+
// sequenceNo: "100", // only in PERP
|
|
762
|
+
// twapMinNotional: "1000", // only in PERP
|
|
763
|
+
// imn: "4000.00", // only in PERP
|
|
764
|
+
// tags: [], // only in PERP
|
|
765
|
+
// settlePlan: "0", // only in PERP
|
|
766
|
+
// triggerProtect: "0.1500", // only in PERP
|
|
767
|
+
// liquidationFee: "0.025000", // only in PERP
|
|
768
|
+
// marketTakeBound: "0.05", // only in PERP
|
|
769
|
+
// createTime: "1758215451058", // only in PERP
|
|
770
|
+
// filters: [
|
|
771
|
+
// {
|
|
772
|
+
// minPrice: "0.01",
|
|
773
|
+
// maxPrice: "1000000",
|
|
774
|
+
// filterType: "PRICE_FILTER",
|
|
775
|
+
// tickSize: "0.01",
|
|
776
|
+
// },
|
|
777
|
+
// {
|
|
778
|
+
// stepSize: "0.00001",
|
|
779
|
+
// filterType: "LOT_SIZE",
|
|
780
|
+
// maxQty: "9000",
|
|
781
|
+
// minQty: "0.00001",
|
|
782
|
+
// },
|
|
783
|
+
// {
|
|
784
|
+
// stepSize: "0.00001",
|
|
785
|
+
// filterType: "MARKET_LOT_SIZE",
|
|
786
|
+
// maxQty: "9000",
|
|
787
|
+
// minQty: "0.00001",
|
|
788
|
+
// },
|
|
789
|
+
// {
|
|
790
|
+
// limit: "200",
|
|
791
|
+
// filterType: "MAX_NUM_ORDERS",
|
|
792
|
+
// },
|
|
793
|
+
// {
|
|
794
|
+
// minNotional: "5",
|
|
795
|
+
// filterType: "MIN_NOTIONAL",
|
|
796
|
+
// },
|
|
797
|
+
// {
|
|
798
|
+
// minNotional: "5",
|
|
799
|
+
// avgPriceMins: "5",
|
|
800
|
+
// applyMinToMarket: true,
|
|
801
|
+
// filterType: "NOTIONAL", // only in SPOT
|
|
802
|
+
// applyMaxToMarket: true,
|
|
803
|
+
// },
|
|
804
|
+
// {
|
|
805
|
+
// multiplierDown: "0.2",
|
|
806
|
+
// multiplierUp: "5",
|
|
807
|
+
// multiplierDecimal: "1",
|
|
808
|
+
// filterType: "PERCENT_PRICE",
|
|
809
|
+
// },
|
|
810
|
+
// {
|
|
811
|
+
// bidMultiplierUp: "5",
|
|
812
|
+
// askMultiplierUp: "5",
|
|
813
|
+
// bidMultiplierDown: "0.2",
|
|
814
|
+
// avgPriceMins: "5",
|
|
815
|
+
// multiplierDecimal: "1",
|
|
816
|
+
// filterType: "PERCENT_PRICE_BY_SIDE", // only in SPOT
|
|
817
|
+
// askMultiplierDown: "0.2",
|
|
818
|
+
// },
|
|
819
|
+
// ],
|
|
820
|
+
// orderTypes: [ "LIMIT", "MARKET", "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET", ],
|
|
821
|
+
// timeInForce: [ "GTC", "IOC", "FOK", "GTX", "HIDDEN", ],
|
|
822
|
+
// }
|
|
754
823
|
// ]
|
|
755
824
|
//
|
|
756
|
-
|
|
757
|
-
const
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
825
|
+
//
|
|
826
|
+
const rows = this.arrayConcat(sapiRows, fapiRows);
|
|
827
|
+
return this.parseMarkets(rows);
|
|
828
|
+
}
|
|
829
|
+
parseMarket(market) {
|
|
830
|
+
const id = this.safeString(market, 'symbol');
|
|
831
|
+
const baseId = this.safeString(market, 'baseAsset');
|
|
832
|
+
const quoteId = this.safeString(market, 'quoteAsset');
|
|
833
|
+
const base = this.safeCurrencyCode(baseId);
|
|
834
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
835
|
+
const active = this.safeString(market, 'status') === 'TRADING';
|
|
836
|
+
let spot = undefined;
|
|
837
|
+
let symbol = undefined;
|
|
838
|
+
let settle = undefined;
|
|
839
|
+
let settleId = undefined;
|
|
840
|
+
let swap = undefined;
|
|
841
|
+
let linear = undefined;
|
|
842
|
+
let inverse = undefined;
|
|
843
|
+
let contractSize = undefined;
|
|
844
|
+
const contractType = this.safeString(market, 'contractType');
|
|
845
|
+
const isContract = contractType !== undefined;
|
|
846
|
+
if (isContract) {
|
|
847
|
+
// currently, there is only perpetuals, not futures
|
|
848
|
+
spot = false;
|
|
849
|
+
swap = true;
|
|
850
|
+
settleId = this.safeString(market, 'marginAsset');
|
|
851
|
+
settle = this.safeCurrencyCode(settleId);
|
|
852
|
+
symbol = base + '/' + quote + ':' + settle;
|
|
853
|
+
linear = settle === quote;
|
|
854
|
+
inverse = settle === base;
|
|
855
|
+
contractSize = this.safeNumber2(market, 'contractSize', 'unit', this.parseNumber('1'));
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
spot = true;
|
|
859
|
+
swap = false;
|
|
860
|
+
symbol = base + '/' + quote;
|
|
861
|
+
}
|
|
862
|
+
// filters
|
|
863
|
+
const filters = this.safeList(market, 'filters', []);
|
|
864
|
+
const filtersByType = this.indexBy(filters, 'filterType');
|
|
865
|
+
const filterNotional = this.safeDict2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL');
|
|
866
|
+
const filterPrice = this.safeDict(filtersByType, 'PRICE_FILTER');
|
|
867
|
+
const filterLotSize = this.safeDict(filtersByType, 'LOT_SIZE');
|
|
868
|
+
const filterMarketLotSize = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {});
|
|
869
|
+
let pricePrecision = this.safeNumber(filterPrice, 'tickSize');
|
|
870
|
+
if (pricePrecision === undefined) {
|
|
871
|
+
pricePrecision = this.parseNumber(this.parsePrecision(this.safeString(market, 'pricePrecision')));
|
|
872
|
+
}
|
|
873
|
+
const amountPrecision = (filterLotSize !== undefined) ? this.safeNumber(filterLotSize, 'stepSize') : this.parseNumber(this.parsePrecision(this.safeString(market, 'quantityPrecision')));
|
|
874
|
+
return this.safeMarketStructure({
|
|
875
|
+
'id': id,
|
|
876
|
+
'symbol': symbol,
|
|
877
|
+
'base': base,
|
|
878
|
+
'quote': quote,
|
|
879
|
+
'settle': settle,
|
|
880
|
+
'baseId': baseId,
|
|
881
|
+
'quoteId': quoteId,
|
|
882
|
+
'settleId': settleId,
|
|
883
|
+
'type': isContract ? 'swap' : 'spot',
|
|
884
|
+
'spot': spot,
|
|
885
|
+
'margin': false,
|
|
886
|
+
'swap': swap,
|
|
887
|
+
'future': false,
|
|
888
|
+
'option': false,
|
|
889
|
+
'active': active,
|
|
890
|
+
'contract': isContract,
|
|
891
|
+
'linear': linear,
|
|
892
|
+
'inverse': inverse,
|
|
893
|
+
'taker': this.fees['trading']['taker'],
|
|
894
|
+
'maker': this.fees['trading']['maker'],
|
|
895
|
+
'contractSize': contractSize,
|
|
896
|
+
'expiry': undefined,
|
|
897
|
+
'expiryDatetime': undefined,
|
|
898
|
+
'strike': undefined,
|
|
899
|
+
'optionType': undefined,
|
|
900
|
+
'precision': {
|
|
901
|
+
'amount': amountPrecision,
|
|
902
|
+
'price': pricePrecision,
|
|
903
|
+
'base': this.parseNumber(this.parsePrecision(this.safeString(market, 'baseAssetPrecision'))),
|
|
904
|
+
'quote': this.parseNumber(this.parsePrecision(this.safeString(market, 'quotePrecision'))),
|
|
905
|
+
},
|
|
906
|
+
'limits': {
|
|
907
|
+
'leverage': {
|
|
908
|
+
'min': undefined,
|
|
909
|
+
'max': undefined,
|
|
831
910
|
},
|
|
832
|
-
'
|
|
833
|
-
'
|
|
834
|
-
|
|
835
|
-
'max': undefined,
|
|
836
|
-
},
|
|
837
|
-
'amount': {
|
|
838
|
-
'min': undefined,
|
|
839
|
-
'max': undefined,
|
|
840
|
-
},
|
|
841
|
-
'price': {
|
|
842
|
-
'min': undefined,
|
|
843
|
-
'max': undefined,
|
|
844
|
-
},
|
|
845
|
-
'cost': {
|
|
846
|
-
'min': undefined,
|
|
847
|
-
'max': undefined,
|
|
848
|
-
},
|
|
911
|
+
'amount': {
|
|
912
|
+
'min': this.safeNumber(filterLotSize, 'minQty'),
|
|
913
|
+
'max': this.safeNumber(filterLotSize, 'maxQty'),
|
|
849
914
|
},
|
|
850
|
-
'
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
'
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
'max': this.safeNumber(filter, 'maxQty'),
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
if ('MARKET_LOT_SIZE' in filtersByType) {
|
|
870
|
-
const filter = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {});
|
|
871
|
-
entry['limits']['market'] = {
|
|
872
|
-
'min': this.safeNumber(filter, 'minQty'),
|
|
873
|
-
'max': this.safeNumber(filter, 'maxQty'),
|
|
874
|
-
};
|
|
875
|
-
}
|
|
876
|
-
if (('MIN_NOTIONAL' in filtersByType) || ('NOTIONAL' in filtersByType)) {
|
|
877
|
-
const filter = this.safeDict2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL', {});
|
|
878
|
-
entry['limits']['cost']['min'] = this.safeNumber(filter, 'notional');
|
|
879
|
-
}
|
|
880
|
-
result.push(entry);
|
|
881
|
-
}
|
|
882
|
-
return result;
|
|
915
|
+
'price': {
|
|
916
|
+
'min': this.safeNumber(filterPrice, 'minPrice'),
|
|
917
|
+
'max': this.safeNumber(filterPrice, 'maxPrice'),
|
|
918
|
+
},
|
|
919
|
+
'cost': {
|
|
920
|
+
'min': this.safeNumber2(filterNotional, 'notional', 'minNotional'),
|
|
921
|
+
'max': undefined,
|
|
922
|
+
},
|
|
923
|
+
'market': {
|
|
924
|
+
'min': this.safeNumber(filterMarketLotSize, 'minQty'),
|
|
925
|
+
'max': this.safeNumber(filterMarketLotSize, 'maxQty'),
|
|
926
|
+
},
|
|
927
|
+
},
|
|
928
|
+
'created': this.safeInteger2(market, 'listingTime', 'createTime'),
|
|
929
|
+
'info': market,
|
|
930
|
+
});
|
|
883
931
|
}
|
|
884
932
|
/**
|
|
885
933
|
* @method
|
|
886
934
|
* @name aster#fetchTime
|
|
887
935
|
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
888
|
-
* @see https://github.
|
|
936
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#get-server-time
|
|
937
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#check-server-time
|
|
889
938
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
890
939
|
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
891
940
|
*/
|
|
892
941
|
async fetchTime(params = {}) {
|
|
893
|
-
|
|
942
|
+
let marketType = undefined;
|
|
943
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchTime', undefined, params);
|
|
944
|
+
let response = undefined;
|
|
945
|
+
if (marketType === 'swap') {
|
|
946
|
+
response = await this.fapiPublicGetV3Time(params);
|
|
947
|
+
}
|
|
948
|
+
else {
|
|
949
|
+
response = await this.sapiPublicGetV3Time(params);
|
|
950
|
+
}
|
|
894
951
|
//
|
|
895
|
-
//
|
|
896
|
-
//
|
|
897
|
-
//
|
|
952
|
+
// both SPOT & PERP has same format
|
|
953
|
+
//
|
|
954
|
+
// {
|
|
955
|
+
// "serverTime": 1499827319559
|
|
956
|
+
// }
|
|
898
957
|
//
|
|
899
958
|
return this.safeInteger(response, 'serverTime');
|
|
900
959
|
}
|
|
901
960
|
parseOHLCV(ohlcv, market = undefined) {
|
|
961
|
+
//
|
|
962
|
+
// spot:
|
|
902
963
|
//
|
|
903
964
|
// [
|
|
904
|
-
//
|
|
905
|
-
// "
|
|
906
|
-
// "
|
|
907
|
-
// "
|
|
908
|
-
// "
|
|
909
|
-
// "
|
|
910
|
-
//
|
|
911
|
-
// "
|
|
912
|
-
//
|
|
913
|
-
// "
|
|
914
|
-
// "
|
|
915
|
-
// "0"
|
|
965
|
+
// 1499040000000, // Open time
|
|
966
|
+
// "0.01634790", // Open
|
|
967
|
+
// "0.80000000", // High
|
|
968
|
+
// "0.01575800", // Low
|
|
969
|
+
// "0.01577100", // Close
|
|
970
|
+
// "148976.11427815", // Volume
|
|
971
|
+
// 1499644799999, // Close time
|
|
972
|
+
// "2434.19055334", // Quote asset volume
|
|
973
|
+
// 308, // Number of trades
|
|
974
|
+
// "1756.87402397", // Taker buy base asset volume
|
|
975
|
+
// "28.46694368", // Taker buy quote asset volume
|
|
976
|
+
// "0" // ??
|
|
916
977
|
// ]
|
|
917
978
|
//
|
|
918
979
|
return [
|
|
@@ -928,8 +989,10 @@ export default class aster extends Exchange {
|
|
|
928
989
|
* @method
|
|
929
990
|
* @name aster#fetchOHLCV
|
|
930
991
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
931
|
-
* @see https://github.
|
|
932
|
-
* @see https://github.
|
|
992
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#k-line-data
|
|
993
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#klinecandlestick-data
|
|
994
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#index-price-klinecandlestick-data
|
|
995
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#mark-price-klinecandlestick-data
|
|
933
996
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
934
997
|
* @param {string} timeframe the length of time each candle represents
|
|
935
998
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
@@ -940,9 +1003,6 @@ export default class aster extends Exchange {
|
|
|
940
1003
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
941
1004
|
*/
|
|
942
1005
|
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
943
|
-
if (symbol === undefined) {
|
|
944
|
-
throw new ArgumentsRequired(this.id + ' fetchOHLCV() requires a symbol argument');
|
|
945
|
-
}
|
|
946
1006
|
await this.loadMarkets();
|
|
947
1007
|
const market = this.market(symbol);
|
|
948
1008
|
let request = {};
|
|
@@ -950,10 +1010,7 @@ export default class aster extends Exchange {
|
|
|
950
1010
|
request['startTime'] = since;
|
|
951
1011
|
}
|
|
952
1012
|
if (limit !== undefined) {
|
|
953
|
-
|
|
954
|
-
limit = 1500; // Default 500; max 1500.
|
|
955
|
-
}
|
|
956
|
-
request['limit'] = limit;
|
|
1013
|
+
request['limit'] = Math.min(limit, 1500);
|
|
957
1014
|
}
|
|
958
1015
|
[request, params] = this.handleUntilOption('endTime', request, params);
|
|
959
1016
|
request['interval'] = this.safeString(this.timeframes, timeframe, timeframe);
|
|
@@ -964,97 +1021,116 @@ export default class aster extends Exchange {
|
|
|
964
1021
|
let response = undefined;
|
|
965
1022
|
if (isMark) {
|
|
966
1023
|
request['symbol'] = market['id'];
|
|
967
|
-
response = await this.
|
|
1024
|
+
response = await this.fapiPublicGetV3MarkPriceKlines(this.extend(request, params));
|
|
968
1025
|
}
|
|
969
1026
|
else if (isIndex) {
|
|
970
1027
|
request['pair'] = market['id'];
|
|
971
|
-
response = await this.
|
|
1028
|
+
response = await this.fapiPublicGetV3IndexPriceKlines(this.extend(request, params));
|
|
972
1029
|
}
|
|
973
1030
|
else {
|
|
974
1031
|
request['symbol'] = market['id'];
|
|
975
1032
|
if (market['linear']) {
|
|
976
|
-
response = await this.
|
|
1033
|
+
response = await this.fapiPublicGetV3Klines(this.extend(request, params));
|
|
977
1034
|
}
|
|
978
1035
|
else {
|
|
979
|
-
response = await this.
|
|
1036
|
+
response = await this.sapiPublicGetV3Klines(this.extend(request, params));
|
|
980
1037
|
}
|
|
1038
|
+
//
|
|
1039
|
+
// both SPOT & PERP has same format
|
|
1040
|
+
//
|
|
1041
|
+
// [
|
|
1042
|
+
// [
|
|
1043
|
+
// 1499040000000, // Open time
|
|
1044
|
+
// "0.01634790", // Open
|
|
1045
|
+
// "0.80000000", // High
|
|
1046
|
+
// "0.01575800", // Low
|
|
1047
|
+
// "0.01577100", // Close
|
|
1048
|
+
// "148976.11427815", // Volume
|
|
1049
|
+
// 1499644799999, // Close time
|
|
1050
|
+
// "2434.19055334", // Quote asset volume
|
|
1051
|
+
// 308, // Number of trades
|
|
1052
|
+
// "1756.87402397", // Taker buy base asset volume
|
|
1053
|
+
// "28.46694368", // Taker buy quote asset volume,
|
|
1054
|
+
// "0"
|
|
1055
|
+
// ]
|
|
1056
|
+
// ]
|
|
1057
|
+
//
|
|
981
1058
|
}
|
|
982
|
-
//
|
|
983
|
-
// [
|
|
984
|
-
// [
|
|
985
|
-
// 1631158560000,
|
|
986
|
-
// "208.1850",
|
|
987
|
-
// "208.1850",
|
|
988
|
-
// "208.1850",
|
|
989
|
-
// "208.1850",
|
|
990
|
-
// "11.84",
|
|
991
|
-
// 1631158619999,
|
|
992
|
-
// "2464.910400",
|
|
993
|
-
// 1,
|
|
994
|
-
// "11.84",
|
|
995
|
-
// "2464.910400",
|
|
996
|
-
// "0"
|
|
997
|
-
// ]
|
|
998
|
-
// ]
|
|
999
|
-
//
|
|
1000
1059
|
return this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
1001
1060
|
}
|
|
1002
1061
|
parseTrade(trade, market = undefined) {
|
|
1003
1062
|
//
|
|
1004
1063
|
// fetchTrades
|
|
1005
1064
|
//
|
|
1065
|
+
// recent trades:
|
|
1066
|
+
//
|
|
1006
1067
|
// {
|
|
1007
1068
|
// "id": 3913206,
|
|
1008
1069
|
// "price": "644.100",
|
|
1009
1070
|
// "qty": "0.08",
|
|
1010
|
-
// "quoteQty": "51.528",
|
|
1071
|
+
// "quoteQty": "51.528", // present in PERP
|
|
1072
|
+
// "baseQty": "4.95049505", // present in SPOT
|
|
1011
1073
|
// "time": 1749784506633,
|
|
1012
1074
|
// "isBuyerMaker": true
|
|
1013
1075
|
// }
|
|
1014
1076
|
//
|
|
1077
|
+
// aggrTrades
|
|
1078
|
+
//
|
|
1015
1079
|
// {
|
|
1016
|
-
// "
|
|
1017
|
-
// "
|
|
1018
|
-
// "
|
|
1019
|
-
// "
|
|
1020
|
-
// "
|
|
1021
|
-
// "
|
|
1080
|
+
// "a": 26129, // Aggregate tradeId
|
|
1081
|
+
// "p": "0.01633102", // Price
|
|
1082
|
+
// "q": "4.70443515", // Quantity
|
|
1083
|
+
// "f": 27781, // First tradeId
|
|
1084
|
+
// "l": 27781, // Last tradeId
|
|
1085
|
+
// "T": 1498793709153, // Timestamp
|
|
1086
|
+
// "m": true, // Was the buyer the maker?
|
|
1022
1087
|
// }
|
|
1023
1088
|
//
|
|
1024
|
-
// fetchMyTrades
|
|
1089
|
+
// fetchMyTrades (SPOT & PERP have similar format)
|
|
1025
1090
|
//
|
|
1026
|
-
//
|
|
1027
|
-
//
|
|
1028
|
-
//
|
|
1029
|
-
//
|
|
1030
|
-
//
|
|
1031
|
-
//
|
|
1032
|
-
//
|
|
1033
|
-
//
|
|
1034
|
-
//
|
|
1035
|
-
//
|
|
1036
|
-
//
|
|
1037
|
-
//
|
|
1038
|
-
//
|
|
1039
|
-
//
|
|
1040
|
-
//
|
|
1041
|
-
//
|
|
1091
|
+
// {
|
|
1092
|
+
// "symbol": "ETHUSDT",
|
|
1093
|
+
// "id": 2583152,
|
|
1094
|
+
// "orderId": 418588675,
|
|
1095
|
+
// "side": "SELL",
|
|
1096
|
+
// "price": "2330.04",
|
|
1097
|
+
// "qty": "0.0030",
|
|
1098
|
+
// "quoteQty": "6.99000000",
|
|
1099
|
+
// "commission": "0.00279605",
|
|
1100
|
+
// "commissionAsset": "USDT",
|
|
1101
|
+
// "time": 1776409179230,
|
|
1102
|
+
// "counterpartyId": 5143150, // only in SPOT
|
|
1103
|
+
// "createUpdateId": null, // only in SPOT
|
|
1104
|
+
// "maker": false, // only in SPOT
|
|
1105
|
+
// "buyer": false, // only in SPOT
|
|
1106
|
+
// "realizedPnl": "0.00029999", // only in PERP
|
|
1107
|
+
// "marginAsset": "USDT", // only in PERP
|
|
1108
|
+
// "positionSide": "BOTH", // only in PERP
|
|
1109
|
+
// }
|
|
1042
1110
|
//
|
|
1043
|
-
const id = this.
|
|
1044
|
-
const
|
|
1045
|
-
const
|
|
1111
|
+
const id = this.safeString2(trade, 'id', 'a');
|
|
1112
|
+
const marketId = this.safeString(trade, 'symbol');
|
|
1113
|
+
const marketType = ('positionSide' in trade) ? 'swap' : 'spot';
|
|
1114
|
+
market = this.safeMarket(marketId, market, undefined, marketType);
|
|
1115
|
+
const currencyId = this.safeString2(trade, 'commissionAsset', 'marginAsset');
|
|
1046
1116
|
const currencyCode = this.safeCurrencyCode(currencyId);
|
|
1047
|
-
const amountString = this.
|
|
1048
|
-
const priceString = this.
|
|
1117
|
+
const amountString = this.safeString2(trade, 'qty', 'q');
|
|
1118
|
+
const priceString = this.safeString2(trade, 'price', 'p');
|
|
1049
1119
|
const costString = this.safeString2(trade, 'quoteQty', 'baseQty');
|
|
1050
|
-
const timestamp = this.
|
|
1120
|
+
const timestamp = this.safeInteger2(trade, 'time', 'T');
|
|
1051
1121
|
let side = this.safeStringLower(trade, 'side');
|
|
1052
1122
|
const isMaker = this.safeBool(trade, 'maker');
|
|
1053
1123
|
let takerOrMaker = undefined;
|
|
1054
1124
|
if (isMaker !== undefined) {
|
|
1055
1125
|
takerOrMaker = isMaker ? 'maker' : 'taker';
|
|
1126
|
+
if (side === undefined) {
|
|
1127
|
+
const isBuyer = this.safeBool(trade, 'buyer');
|
|
1128
|
+
if (isBuyer !== undefined) {
|
|
1129
|
+
side = isBuyer ? 'buy' : 'sell';
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1056
1132
|
}
|
|
1057
|
-
const isBuyerMaker = this.
|
|
1133
|
+
const isBuyerMaker = this.safeBool2(trade, 'isBuyerMaker', 'm');
|
|
1058
1134
|
if (isBuyerMaker !== undefined) {
|
|
1059
1135
|
side = isBuyerMaker ? 'sell' : 'buy';
|
|
1060
1136
|
}
|
|
@@ -1063,7 +1139,7 @@ export default class aster extends Exchange {
|
|
|
1063
1139
|
'info': trade,
|
|
1064
1140
|
'timestamp': timestamp,
|
|
1065
1141
|
'datetime': this.iso8601(timestamp),
|
|
1066
|
-
'symbol': symbol,
|
|
1142
|
+
'symbol': market['symbol'],
|
|
1067
1143
|
'order': this.safeString(trade, 'orderId'),
|
|
1068
1144
|
'type': undefined,
|
|
1069
1145
|
'side': side,
|
|
@@ -1081,8 +1157,10 @@ export default class aster extends Exchange {
|
|
|
1081
1157
|
* @method
|
|
1082
1158
|
* @name aster#fetchTrades
|
|
1083
1159
|
* @description get the list of most recent trades for a particular symbol
|
|
1084
|
-
* @see https://github.
|
|
1085
|
-
* @see https://github.
|
|
1160
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#recent-trades-list
|
|
1161
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#recent-trades-aggregated
|
|
1162
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#recent-trades-list
|
|
1163
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#compressedaggregate-trades-list
|
|
1086
1164
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1087
1165
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1088
1166
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
@@ -1090,48 +1168,68 @@ export default class aster extends Exchange {
|
|
|
1090
1168
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1091
1169
|
*/
|
|
1092
1170
|
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1093
|
-
if (symbol === undefined) {
|
|
1094
|
-
throw new ArgumentsRequired(this.id + ' fetchTrades() requires a symbol argument');
|
|
1095
|
-
}
|
|
1096
1171
|
await this.loadMarkets();
|
|
1097
1172
|
const market = this.market(symbol);
|
|
1098
|
-
|
|
1173
|
+
let request = {
|
|
1099
1174
|
'symbol': market['id'],
|
|
1100
1175
|
};
|
|
1101
1176
|
if (limit !== undefined) {
|
|
1102
|
-
|
|
1103
|
-
limit = 1000; // Default 500; max 1000.
|
|
1104
|
-
}
|
|
1105
|
-
request['limit'] = limit;
|
|
1177
|
+
request['limit'] = Math.min(limit, 1000);
|
|
1106
1178
|
}
|
|
1107
1179
|
let response = undefined;
|
|
1108
|
-
|
|
1109
|
-
|
|
1180
|
+
const sinceDefined = since !== undefined;
|
|
1181
|
+
const untilDefined = ('until' in params);
|
|
1182
|
+
if (sinceDefined) {
|
|
1183
|
+
request['startTime'] = since;
|
|
1184
|
+
}
|
|
1185
|
+
if (untilDefined) {
|
|
1186
|
+
request = this.handleUntilOption('endTime', request, params);
|
|
1187
|
+
}
|
|
1188
|
+
// use historical endpoint for targeted requests
|
|
1189
|
+
if ('startTime' in request) {
|
|
1190
|
+
if (market['swap']) {
|
|
1191
|
+
response = await this.fapiPublicGetV3AggTrades(this.extend(request, params));
|
|
1192
|
+
}
|
|
1193
|
+
else {
|
|
1194
|
+
response = await this.sapiPublicGetV3AggTrades(this.extend(request, params));
|
|
1195
|
+
}
|
|
1110
1196
|
//
|
|
1111
|
-
//
|
|
1112
|
-
//
|
|
1113
|
-
//
|
|
1114
|
-
//
|
|
1115
|
-
//
|
|
1116
|
-
//
|
|
1117
|
-
//
|
|
1118
|
-
//
|
|
1119
|
-
//
|
|
1120
|
-
//
|
|
1197
|
+
// both FAPI and SAPI have same response format
|
|
1198
|
+
//
|
|
1199
|
+
// [
|
|
1200
|
+
// {
|
|
1201
|
+
// "a": 26129, // Aggregate tradeId
|
|
1202
|
+
// "p": "0.01633102", // Price
|
|
1203
|
+
// "q": "4.70443515", // Quantity
|
|
1204
|
+
// "f": 27781, // First tradeId
|
|
1205
|
+
// "l": 27781, // Last tradeId
|
|
1206
|
+
// "T": 1498793709153, // Timestamp
|
|
1207
|
+
// "m": true, // Was the buyer the maker?
|
|
1208
|
+
// }
|
|
1209
|
+
// ]
|
|
1121
1210
|
//
|
|
1122
1211
|
}
|
|
1123
1212
|
else {
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
//
|
|
1131
|
-
//
|
|
1132
|
-
//
|
|
1133
|
-
//
|
|
1134
|
-
//
|
|
1213
|
+
if (market['swap']) {
|
|
1214
|
+
response = await this.fapiPublicGetV3Trades(this.extend(request, params));
|
|
1215
|
+
}
|
|
1216
|
+
else {
|
|
1217
|
+
response = await this.sapiPublicGetV3Trades(this.extend(request, params));
|
|
1218
|
+
}
|
|
1219
|
+
//
|
|
1220
|
+
// SAPI & FAPI have only one field difference
|
|
1221
|
+
//
|
|
1222
|
+
// [
|
|
1223
|
+
// {
|
|
1224
|
+
// "id": "73620768",
|
|
1225
|
+
// "price": "2324.07",
|
|
1226
|
+
// "qty": "0.430",
|
|
1227
|
+
// "quoteQty": "999.35", // only in PERP
|
|
1228
|
+
// "baseQty": "4.95049505", // only in SPOT
|
|
1229
|
+
// "time": "1776407252900",
|
|
1230
|
+
// "isBuyerMaker": false
|
|
1231
|
+
// }, ...
|
|
1232
|
+
//
|
|
1135
1233
|
}
|
|
1136
1234
|
return this.parseTrades(response, market, since, limit);
|
|
1137
1235
|
}
|
|
@@ -1139,8 +1237,8 @@ export default class aster extends Exchange {
|
|
|
1139
1237
|
* @method
|
|
1140
1238
|
* @name aster#fetchMyTrades
|
|
1141
1239
|
* @description fetch all trades made by the user
|
|
1142
|
-
* @see https://github.
|
|
1143
|
-
* @see https://github.
|
|
1240
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#account-trade-history-user_data
|
|
1241
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#account-trade-list-user_data
|
|
1144
1242
|
* @param {string} [symbol] unified market symbol
|
|
1145
1243
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1146
1244
|
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
@@ -1149,50 +1247,51 @@ export default class aster extends Exchange {
|
|
|
1149
1247
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1150
1248
|
*/
|
|
1151
1249
|
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1152
|
-
|
|
1153
|
-
|
|
1250
|
+
await this.loadMarketsAndSignIn();
|
|
1251
|
+
let request = {};
|
|
1252
|
+
let market = undefined;
|
|
1253
|
+
if (symbol !== undefined) {
|
|
1254
|
+
market = this.market(symbol);
|
|
1255
|
+
request['symbol'] = market['id'];
|
|
1154
1256
|
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
let request = {
|
|
1158
|
-
'symbol': market['id'],
|
|
1159
|
-
};
|
|
1257
|
+
let marketType = undefined;
|
|
1258
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
|
|
1160
1259
|
if (since !== undefined) {
|
|
1161
1260
|
request['startTime'] = since;
|
|
1162
1261
|
}
|
|
1163
1262
|
if (limit !== undefined) {
|
|
1164
|
-
|
|
1165
|
-
limit = 1000; // Default 500; max 1000.
|
|
1166
|
-
}
|
|
1167
|
-
request['limit'] = limit;
|
|
1263
|
+
request['limit'] = Math.min(limit, 1000);
|
|
1168
1264
|
}
|
|
1169
1265
|
[request, params] = this.handleUntilOption('endTime', request, params);
|
|
1170
1266
|
let response = undefined;
|
|
1171
|
-
if (
|
|
1172
|
-
response = await this.
|
|
1267
|
+
if (marketType === 'swap') {
|
|
1268
|
+
response = await this.fapiPrivateGetV3UserTrades(this.extend(request, params));
|
|
1173
1269
|
}
|
|
1174
1270
|
else {
|
|
1175
|
-
response = await this.
|
|
1271
|
+
response = await this.sapiPrivateGetV3UserTrades(this.extend(request, params));
|
|
1176
1272
|
}
|
|
1177
1273
|
//
|
|
1178
|
-
//
|
|
1179
|
-
//
|
|
1180
|
-
//
|
|
1181
|
-
//
|
|
1182
|
-
//
|
|
1183
|
-
//
|
|
1184
|
-
//
|
|
1185
|
-
//
|
|
1186
|
-
//
|
|
1187
|
-
//
|
|
1188
|
-
//
|
|
1189
|
-
//
|
|
1190
|
-
//
|
|
1191
|
-
//
|
|
1192
|
-
//
|
|
1193
|
-
//
|
|
1194
|
-
//
|
|
1195
|
-
//
|
|
1274
|
+
// SPOT & PERP have similar format
|
|
1275
|
+
//
|
|
1276
|
+
// {
|
|
1277
|
+
// "symbol": "ETHUSDT",
|
|
1278
|
+
// "id": 2583152,
|
|
1279
|
+
// "orderId": 418588675,
|
|
1280
|
+
// "side": "SELL",
|
|
1281
|
+
// "price": "2330.04",
|
|
1282
|
+
// "qty": "0.0030",
|
|
1283
|
+
// "quoteQty": "6.99000000",
|
|
1284
|
+
// "commission": "0.00279605",
|
|
1285
|
+
// "commissionAsset": "USDT",
|
|
1286
|
+
// "time": 1776409179230,
|
|
1287
|
+
// "counterpartyId": 5143150, // only in PERP
|
|
1288
|
+
// "createUpdateId": null, // only in PERP
|
|
1289
|
+
// "maker": false, // only in PERP
|
|
1290
|
+
// "buyer": false, // only in PERP
|
|
1291
|
+
// "realizedPnl": "0.00029999", // only in SPOT
|
|
1292
|
+
// "marginAsset": "USDT", // only in SPOT
|
|
1293
|
+
// "positionSide": "BOTH", // only in SPOT
|
|
1294
|
+
// }
|
|
1196
1295
|
//
|
|
1197
1296
|
return this.parseTrades(response, market, since, limit, params);
|
|
1198
1297
|
}
|
|
@@ -1200,37 +1299,32 @@ export default class aster extends Exchange {
|
|
|
1200
1299
|
* @method
|
|
1201
1300
|
* @name aster#fetchOrderBook
|
|
1202
1301
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
1203
|
-
* @see https://github.
|
|
1204
|
-
* @see https://github.
|
|
1302
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#depth-information
|
|
1303
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#order-book
|
|
1205
1304
|
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
1206
1305
|
* @param {int} [limit] the maximum amount of order book entries to return
|
|
1207
1306
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1208
1307
|
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
1209
1308
|
*/
|
|
1210
1309
|
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
1211
|
-
if (symbol === undefined) {
|
|
1212
|
-
throw new ArgumentsRequired(this.id + ' fetchOrderBook() requires a symbol argument');
|
|
1213
|
-
}
|
|
1214
1310
|
await this.loadMarkets();
|
|
1215
1311
|
const market = this.market(symbol);
|
|
1216
1312
|
const request = {
|
|
1217
1313
|
'symbol': market['id'],
|
|
1218
1314
|
};
|
|
1315
|
+
let response = undefined;
|
|
1219
1316
|
if (limit !== undefined) {
|
|
1220
|
-
|
|
1221
|
-
if (limit > 1000) {
|
|
1222
|
-
limit = 1000; // Default 500; max 1000.
|
|
1223
|
-
}
|
|
1224
|
-
request['limit'] = limit;
|
|
1317
|
+
request['limit'] = this.findNearestCeiling([5, 10, 20, 50, 100, 500, 1000], limit);
|
|
1225
1318
|
}
|
|
1226
|
-
let response = undefined;
|
|
1227
1319
|
if (market['swap']) {
|
|
1228
|
-
response = await this.
|
|
1320
|
+
response = await this.fapiPublicGetV3Depth(this.extend(request, params));
|
|
1229
1321
|
}
|
|
1230
1322
|
else {
|
|
1231
|
-
response = await this.
|
|
1323
|
+
response = await this.sapiPublicGetV3Depth(this.extend(request, params));
|
|
1232
1324
|
}
|
|
1233
1325
|
//
|
|
1326
|
+
// both SPOT & PERP has same format
|
|
1327
|
+
//
|
|
1234
1328
|
// {
|
|
1235
1329
|
// "lastUpdateId": 1027024,
|
|
1236
1330
|
// "E": 1589436922972, // Message output time
|
|
@@ -1252,118 +1346,50 @@ export default class aster extends Exchange {
|
|
|
1252
1346
|
const timestamp = this.safeInteger(response, 'T');
|
|
1253
1347
|
return this.parseOrderBook(response, symbol, timestamp, 'bids', 'asks');
|
|
1254
1348
|
}
|
|
1255
|
-
|
|
1256
|
-
* @method
|
|
1257
|
-
* @name aster#fetchFundingRateHistory
|
|
1258
|
-
* @description fetches historical funding rate prices
|
|
1259
|
-
* @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#get-funding-rate-history
|
|
1260
|
-
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
1261
|
-
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
1262
|
-
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
|
1263
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1264
|
-
* @param {int} [params.until] timestamp in ms of the latest funding rate
|
|
1265
|
-
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
|
|
1266
|
-
*/
|
|
1267
|
-
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1268
|
-
await this.loadMarkets();
|
|
1269
|
-
let request = {};
|
|
1270
|
-
if (symbol !== undefined) {
|
|
1271
|
-
const market = this.market(symbol);
|
|
1272
|
-
request['symbol'] = market['id'];
|
|
1273
|
-
}
|
|
1274
|
-
if (since !== undefined) {
|
|
1275
|
-
request['startTime'] = since;
|
|
1276
|
-
}
|
|
1277
|
-
if (limit !== undefined) {
|
|
1278
|
-
if (limit > 1000) {
|
|
1279
|
-
limit = 1000; // Default 100; max 1000
|
|
1280
|
-
}
|
|
1281
|
-
request['limit'] = limit;
|
|
1282
|
-
}
|
|
1283
|
-
[request, params] = this.handleUntilOption('endTime', request, params);
|
|
1284
|
-
const response = await this.fapiPublicGetV1FundingRate(this.extend(request, params));
|
|
1349
|
+
parseTicker(ticker, market = undefined) {
|
|
1285
1350
|
//
|
|
1286
|
-
//
|
|
1287
|
-
// {
|
|
1288
|
-
// "symbol": "BTCUSDT",
|
|
1289
|
-
// "fundingTime": 1747209600000,
|
|
1290
|
-
// "fundingRate": "0.00010000"
|
|
1291
|
-
// }
|
|
1292
|
-
// ]
|
|
1351
|
+
// fetchTicker & fetchTickers: both SPOT & PERP has similar format
|
|
1293
1352
|
//
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1353
|
+
// {
|
|
1354
|
+
// "symbol": "ETHUSDT",
|
|
1355
|
+
// "priceChange": "6.54",
|
|
1356
|
+
// "priceChangePercent": "0.279",
|
|
1357
|
+
// "weightedAvgPrice": "2330.70",
|
|
1358
|
+
// "lastPrice": "2350.00",
|
|
1359
|
+
// "lastQty": "4.437",
|
|
1360
|
+
// "openPrice": "2343.46",
|
|
1361
|
+
// "highPrice": "2363.20",
|
|
1362
|
+
// "lowPrice": "2283.86",
|
|
1363
|
+
// "volume": "267154.248",
|
|
1364
|
+
// "quoteVolume": "622657018.70",
|
|
1365
|
+
// "openTime": "1776329400000",
|
|
1366
|
+
// "closeTime": "1776415832593",
|
|
1367
|
+
// "firstId": "73520536",
|
|
1368
|
+
// "lastId": "73630176",
|
|
1369
|
+
// "count": "109640",
|
|
1370
|
+
// "baseAsset": "BTC", // only in SPOT
|
|
1371
|
+
// "quoteAsset": "USDT", // only in SPOT
|
|
1372
|
+
// "bidPrice": "71125.98", // only in SPOT
|
|
1373
|
+
// "bidQty": "0.00737", // only in SPOT
|
|
1374
|
+
// "askPrice": "71152.10", // only in SPOT
|
|
1375
|
+
// "askQty": "0.32399" // only in SPOT
|
|
1376
|
+
// }
|
|
1310
1377
|
//
|
|
1311
|
-
//
|
|
1312
|
-
//
|
|
1313
|
-
//
|
|
1314
|
-
//
|
|
1315
|
-
//
|
|
1316
|
-
//
|
|
1317
|
-
//
|
|
1318
|
-
//
|
|
1319
|
-
//
|
|
1320
|
-
//
|
|
1321
|
-
//
|
|
1322
|
-
//
|
|
1323
|
-
//
|
|
1324
|
-
// "openTime": "1760578800000",
|
|
1325
|
-
// "closeTime": "1760665024749",
|
|
1326
|
-
// "firstId": "37447",
|
|
1327
|
-
// "lastId": "39698",
|
|
1328
|
-
// "count": "2252",
|
|
1329
|
-
// "baseAsset": "BTC",
|
|
1330
|
-
// "quoteAsset": "USDT",
|
|
1331
|
-
// "bidPrice": "108705.11",
|
|
1332
|
-
// "bidQty": "0.03351",
|
|
1333
|
-
// "askPrice": "108725.99",
|
|
1334
|
-
// "askQty": "0.08724"
|
|
1335
|
-
// }
|
|
1336
|
-
// swap
|
|
1337
|
-
// {
|
|
1338
|
-
// "symbol": "BTCUSDT",
|
|
1339
|
-
// "priceChange": "1845.7",
|
|
1340
|
-
// "priceChangePercent": "1.755",
|
|
1341
|
-
// "weightedAvgPrice": "105515.5",
|
|
1342
|
-
// "lastPrice": "107037.7",
|
|
1343
|
-
// "lastQty": "0.004",
|
|
1344
|
-
// "openPrice": "105192.0",
|
|
1345
|
-
// "highPrice": "107223.5",
|
|
1346
|
-
// "lowPrice": "104431.6",
|
|
1347
|
-
// "volume": "8753.286",
|
|
1348
|
-
// "quoteVolume": "923607368.61",
|
|
1349
|
-
// "openTime": 1749976620000,
|
|
1350
|
-
// "closeTime": 1750063053754,
|
|
1351
|
-
// "firstId": 24195078,
|
|
1352
|
-
// "lastId": 24375783,
|
|
1353
|
-
// "count": 180706
|
|
1354
|
-
// }
|
|
1378
|
+
//
|
|
1379
|
+
// fetchBidsAsks: SPOT & PERP have only one field difference
|
|
1380
|
+
//
|
|
1381
|
+
// [
|
|
1382
|
+
// {
|
|
1383
|
+
// "symbol": "BMTUSDT",
|
|
1384
|
+
// "bidPrice": "0.004000",
|
|
1385
|
+
// "bidQty": "1250.0",
|
|
1386
|
+
// "askPrice": "0.000000",
|
|
1387
|
+
// "askQty": "0.0",
|
|
1388
|
+
// "time": "1776411276072",
|
|
1389
|
+
// "lastUpdateId": "453174307613" // only in PERP
|
|
1390
|
+
// }, ...
|
|
1355
1391
|
//
|
|
1356
1392
|
const timestamp = this.safeInteger(ticker, 'closeTime');
|
|
1357
|
-
let marketType = undefined;
|
|
1358
|
-
if ('bidQty' in ticker) {
|
|
1359
|
-
marketType = 'spot';
|
|
1360
|
-
}
|
|
1361
|
-
else {
|
|
1362
|
-
marketType = 'contract';
|
|
1363
|
-
}
|
|
1364
|
-
const marketId = this.safeString(ticker, 'symbol');
|
|
1365
|
-
market = this.safeMarket(marketId, market, undefined, marketType);
|
|
1366
|
-
const symbol = market['symbol'];
|
|
1367
1393
|
const last = this.safeString(ticker, 'lastPrice');
|
|
1368
1394
|
const open = this.safeString(ticker, 'openPrice');
|
|
1369
1395
|
let percentage = this.safeString(ticker, 'priceChangePercent');
|
|
@@ -1372,8 +1398,18 @@ export default class aster extends Exchange {
|
|
|
1372
1398
|
const baseVolume = this.safeString(ticker, 'volume');
|
|
1373
1399
|
const high = this.safeString(ticker, 'highPrice');
|
|
1374
1400
|
const low = this.safeString(ticker, 'lowPrice');
|
|
1401
|
+
const isTickerResponse = ('priceChange' in ticker);
|
|
1402
|
+
let marketType = undefined;
|
|
1403
|
+
if (isTickerResponse) {
|
|
1404
|
+
marketType = ('baseAsset' in ticker) ? 'spot' : 'swap';
|
|
1405
|
+
}
|
|
1406
|
+
else {
|
|
1407
|
+
marketType = ('lastUpdateId' in ticker) ? 'swap' : 'spot';
|
|
1408
|
+
}
|
|
1409
|
+
const marketId = this.safeString(ticker, 'symbol');
|
|
1410
|
+
market = this.safeMarket(marketId, market, undefined, marketType);
|
|
1375
1411
|
return this.safeTicker({
|
|
1376
|
-
'symbol': symbol,
|
|
1412
|
+
'symbol': market['symbol'],
|
|
1377
1413
|
'timestamp': timestamp,
|
|
1378
1414
|
'datetime': this.iso8601(timestamp),
|
|
1379
1415
|
'high': high,
|
|
@@ -1401,16 +1437,13 @@ export default class aster extends Exchange {
|
|
|
1401
1437
|
* @method
|
|
1402
1438
|
* @name aster#fetchTicker
|
|
1403
1439
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1404
|
-
* @see https://github.
|
|
1405
|
-
* @see https://github.
|
|
1440
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#24h-price-change
|
|
1441
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#24hr-ticker-price-change-statistics
|
|
1406
1442
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1407
1443
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1408
1444
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1409
1445
|
*/
|
|
1410
1446
|
async fetchTicker(symbol, params = {}) {
|
|
1411
|
-
if (symbol === undefined) {
|
|
1412
|
-
throw new ArgumentsRequired(this.id + ' fetchTicker() requires a symbol argument');
|
|
1413
|
-
}
|
|
1414
1447
|
await this.loadMarkets();
|
|
1415
1448
|
const market = this.market(symbol);
|
|
1416
1449
|
const request = {
|
|
@@ -1418,63 +1451,47 @@ export default class aster extends Exchange {
|
|
|
1418
1451
|
};
|
|
1419
1452
|
let response = undefined;
|
|
1420
1453
|
if (market['swap']) {
|
|
1421
|
-
response = await this.
|
|
1422
|
-
//
|
|
1423
|
-
// {
|
|
1424
|
-
// "symbol": "BTCUSDT",
|
|
1425
|
-
// "priceChange": "1845.7",
|
|
1426
|
-
// "priceChangePercent": "1.755",
|
|
1427
|
-
// "weightedAvgPrice": "105515.5",
|
|
1428
|
-
// "lastPrice": "107037.7",
|
|
1429
|
-
// "lastQty": "0.004",
|
|
1430
|
-
// "openPrice": "105192.0",
|
|
1431
|
-
// "highPrice": "107223.5",
|
|
1432
|
-
// "lowPrice": "104431.6",
|
|
1433
|
-
// "volume": "8753.286",
|
|
1434
|
-
// "quoteVolume": "923607368.61",
|
|
1435
|
-
// "openTime": 1749976620000,
|
|
1436
|
-
// "closeTime": 1750063053754,
|
|
1437
|
-
// "firstId": 24195078,
|
|
1438
|
-
// "lastId": 24375783,
|
|
1439
|
-
// "count": 180706
|
|
1440
|
-
// }
|
|
1441
|
-
//
|
|
1454
|
+
response = await this.fapiPublicGetV3Ticker24hr(this.extend(request, params));
|
|
1442
1455
|
}
|
|
1443
1456
|
else {
|
|
1444
|
-
response = await this.
|
|
1445
|
-
// {
|
|
1446
|
-
// "symbol": "BTCUSDT",
|
|
1447
|
-
// "priceChange": "-2274.38",
|
|
1448
|
-
// "priceChangePercent": "-2.049",
|
|
1449
|
-
// "weightedAvgPrice": "109524.37084136",
|
|
1450
|
-
// "lastPrice": "108738.78",
|
|
1451
|
-
// "lastQty": "0.00034",
|
|
1452
|
-
// "openPrice": "111013.16",
|
|
1453
|
-
// "highPrice": "111975.81",
|
|
1454
|
-
// "lowPrice": "107459.25",
|
|
1455
|
-
// "volume": "28.67876",
|
|
1456
|
-
// "quoteVolume": "3141023.14551030",
|
|
1457
|
-
// "openTime": "1760578800000",
|
|
1458
|
-
// "closeTime": "1760665024749",
|
|
1459
|
-
// "firstId": "37447",
|
|
1460
|
-
// "lastId": "39698",
|
|
1461
|
-
// "count": "2252",
|
|
1462
|
-
// "baseAsset": "BTC",
|
|
1463
|
-
// "quoteAsset": "USDT",
|
|
1464
|
-
// "bidPrice": "108705.11",
|
|
1465
|
-
// "bidQty": "0.03351",
|
|
1466
|
-
// "askPrice": "108725.99",
|
|
1467
|
-
// "askQty": "0.08724"
|
|
1468
|
-
// }
|
|
1457
|
+
response = await this.sapiPublicGetV3Ticker24hr(this.extend(request, params));
|
|
1469
1458
|
}
|
|
1459
|
+
//
|
|
1460
|
+
// both SPOT & PERP has same format
|
|
1461
|
+
//
|
|
1462
|
+
// {
|
|
1463
|
+
// "symbol": "ETHUSDT",
|
|
1464
|
+
// "priceChange": "6.54",
|
|
1465
|
+
// "priceChangePercent": "0.279",
|
|
1466
|
+
// "weightedAvgPrice": "2330.70",
|
|
1467
|
+
// "lastPrice": "2350.00",
|
|
1468
|
+
// "lastQty": "4.437",
|
|
1469
|
+
// "openPrice": "2343.46",
|
|
1470
|
+
// "highPrice": "2363.20",
|
|
1471
|
+
// "lowPrice": "2283.86",
|
|
1472
|
+
// "volume": "267154.248",
|
|
1473
|
+
// "quoteVolume": "622657018.70",
|
|
1474
|
+
// "openTime": "1776329400000",
|
|
1475
|
+
// "closeTime": "1776415832593",
|
|
1476
|
+
// "firstId": "73520536",
|
|
1477
|
+
// "lastId": "73630176",
|
|
1478
|
+
// "count": "109640",
|
|
1479
|
+
// "baseAsset": "BTC", // only in SPOT
|
|
1480
|
+
// "quoteAsset": "USDT", // only in SPOT
|
|
1481
|
+
// "bidPrice": "71125.98", // only in SPOT
|
|
1482
|
+
// "bidQty": "0.00737", // only in SPOT
|
|
1483
|
+
// "askPrice": "71152.10", // only in SPOT
|
|
1484
|
+
// "askQty": "0.32399" // only in SPOT
|
|
1485
|
+
// }
|
|
1486
|
+
//
|
|
1470
1487
|
return this.parseTicker(response, market);
|
|
1471
1488
|
}
|
|
1472
1489
|
/**
|
|
1473
1490
|
* @method
|
|
1474
1491
|
* @name aster#fetchTickers
|
|
1475
1492
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1476
|
-
* @see https://github.
|
|
1477
|
-
* @see https://github.
|
|
1493
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#24h-price-change
|
|
1494
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#24hr-ticker-price-change-statistics
|
|
1478
1495
|
* @param {string[]} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1479
1496
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1480
1497
|
* @param {string} [params.subType] "linear" or "inverse"
|
|
@@ -1485,19 +1502,14 @@ export default class aster extends Exchange {
|
|
|
1485
1502
|
await this.loadMarkets();
|
|
1486
1503
|
symbols = this.marketSymbols(symbols, undefined, true, true, true);
|
|
1487
1504
|
const market = this.getMarketFromSymbols(symbols);
|
|
1488
|
-
let
|
|
1489
|
-
[
|
|
1490
|
-
let subType = undefined;
|
|
1491
|
-
[subType, params] = this.handleSubTypeAndParams('fetchTickers', market, params);
|
|
1505
|
+
let marketType = undefined;
|
|
1506
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
|
|
1492
1507
|
let response = undefined;
|
|
1493
|
-
if (
|
|
1494
|
-
response = await this.
|
|
1495
|
-
}
|
|
1496
|
-
else if (type === 'spot') {
|
|
1497
|
-
response = await this.sapiPublicGetV1Ticker24hr(params);
|
|
1508
|
+
if (marketType === 'swap') {
|
|
1509
|
+
response = await this.fapiPublicGetV3Ticker24hr(params);
|
|
1498
1510
|
}
|
|
1499
|
-
else {
|
|
1500
|
-
|
|
1511
|
+
else if (marketType === 'spot') {
|
|
1512
|
+
response = await this.sapiPublicGetV3Ticker24hr(params);
|
|
1501
1513
|
}
|
|
1502
1514
|
//
|
|
1503
1515
|
// [
|
|
@@ -1517,13 +1529,127 @@ export default class aster extends Exchange {
|
|
|
1517
1529
|
// "closeTime": 1750063053754,
|
|
1518
1530
|
// "firstId": 24195078,
|
|
1519
1531
|
// "lastId": 24375783,
|
|
1520
|
-
// "count": 180706
|
|
1532
|
+
// "count": 180706,
|
|
1533
|
+
// "baseAsset": "BTC", // only in SPOT
|
|
1534
|
+
// "quoteAsset": "USDT", // only in SPOT
|
|
1535
|
+
// "bidPrice": "71125.98", // only in SPOT
|
|
1536
|
+
// "bidQty": "0.00737", // only in SPOT
|
|
1537
|
+
// "askPrice": "71152.10", // only in SPOT
|
|
1538
|
+
// "askQty": "0.32399" // only in SPOT
|
|
1521
1539
|
// }
|
|
1522
1540
|
// ]
|
|
1523
1541
|
//
|
|
1524
1542
|
return this.parseTickers(response, symbols);
|
|
1525
1543
|
}
|
|
1544
|
+
/**
|
|
1545
|
+
* @method
|
|
1546
|
+
* @name aster#fetchLastPrices
|
|
1547
|
+
* @description fetches the last price for multiple markets
|
|
1548
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#latest-price
|
|
1549
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#symbol-price-ticker
|
|
1550
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the last prices
|
|
1551
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1552
|
+
* @param {string} [params.subType] "linear" or "inverse"
|
|
1553
|
+
* @returns {object} a dictionary of lastprices structures
|
|
1554
|
+
*/
|
|
1555
|
+
async fetchLastPrices(symbols = undefined, params = {}) {
|
|
1556
|
+
await this.loadMarkets();
|
|
1557
|
+
symbols = this.marketSymbols(symbols, undefined, true, true, true);
|
|
1558
|
+
const market = this.getMarketFromSymbols(symbols);
|
|
1559
|
+
let marketType = undefined;
|
|
1560
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchLastPrices', market, params);
|
|
1561
|
+
let response = undefined;
|
|
1562
|
+
if (marketType === 'swap') {
|
|
1563
|
+
response = await this.fapiPublicGetV3TickerPrice(params);
|
|
1564
|
+
}
|
|
1565
|
+
else if (marketType === 'spot') {
|
|
1566
|
+
response = await this.sapiPublicGetV3TickerPrice(params);
|
|
1567
|
+
}
|
|
1568
|
+
//
|
|
1569
|
+
// both SPOT & SWAP has same format
|
|
1570
|
+
//
|
|
1571
|
+
// [
|
|
1572
|
+
// {
|
|
1573
|
+
// "symbol": "LTCBTC",
|
|
1574
|
+
// "price": "4.00000200"
|
|
1575
|
+
// "time": "1649666690902"
|
|
1576
|
+
// },
|
|
1577
|
+
// ...
|
|
1578
|
+
// ]
|
|
1579
|
+
//
|
|
1580
|
+
const results = [];
|
|
1581
|
+
for (let i = 0; i < response.length; i++) {
|
|
1582
|
+
const marketId = this.safeString(response[i], 'symbol');
|
|
1583
|
+
const safeMarket = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
1584
|
+
const priceData = this.extend(this.parseLastPrice(response[i], safeMarket), params);
|
|
1585
|
+
results.push(priceData);
|
|
1586
|
+
}
|
|
1587
|
+
symbols = this.marketSymbols(symbols);
|
|
1588
|
+
return this.filterByArray(results, 'symbol', symbols);
|
|
1589
|
+
}
|
|
1590
|
+
parseLastPrice(entry, market = undefined) {
|
|
1591
|
+
//
|
|
1592
|
+
// spot & swap
|
|
1593
|
+
//
|
|
1594
|
+
// {
|
|
1595
|
+
// "symbol": "LTCBTC",
|
|
1596
|
+
// "price": "4.00000200"
|
|
1597
|
+
// "time": "1649666690902"
|
|
1598
|
+
// }
|
|
1599
|
+
//
|
|
1600
|
+
const timestamp = this.safeInteger(entry, 'time');
|
|
1601
|
+
return {
|
|
1602
|
+
'symbol': market['symbol'],
|
|
1603
|
+
'timestamp': timestamp,
|
|
1604
|
+
'datetime': this.iso8601(timestamp),
|
|
1605
|
+
'price': this.safeNumberOmitZero(entry, 'price'),
|
|
1606
|
+
'side': undefined,
|
|
1607
|
+
'info': entry,
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* @method
|
|
1612
|
+
* @name aster#fetchBidsAsks
|
|
1613
|
+
* @description fetches the bid and ask price and volume for multiple markets
|
|
1614
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#current-best-order
|
|
1615
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#symbol-order-book-ticker
|
|
1616
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
|
1617
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1618
|
+
* @param {string} [params.subType] "linear" or "inverse"
|
|
1619
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/?id=ticker-structure}
|
|
1620
|
+
*/
|
|
1621
|
+
async fetchBidsAsks(symbols = undefined, params = {}) {
|
|
1622
|
+
await this.loadMarkets();
|
|
1623
|
+
symbols = this.marketSymbols(symbols, undefined, true, true, true);
|
|
1624
|
+
const market = this.getMarketFromSymbols(symbols);
|
|
1625
|
+
let marketType = undefined;
|
|
1626
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchBidsAsks', market, params);
|
|
1627
|
+
let response = undefined;
|
|
1628
|
+
if (marketType === 'swap') {
|
|
1629
|
+
response = await this.fapiPublicGetV3TickerBookTicker(params);
|
|
1630
|
+
}
|
|
1631
|
+
else if (marketType === 'spot') {
|
|
1632
|
+
response = await this.sapiPublicGetV3TickerBookTicker(params);
|
|
1633
|
+
}
|
|
1634
|
+
//
|
|
1635
|
+
// SPOT & PERP have only one field difference
|
|
1636
|
+
//
|
|
1637
|
+
// [
|
|
1638
|
+
// {
|
|
1639
|
+
// "symbol": "BMTUSDT",
|
|
1640
|
+
// "bidPrice": "0.004000",
|
|
1641
|
+
// "bidQty": "1250.0",
|
|
1642
|
+
// "askPrice": "0.000000",
|
|
1643
|
+
// "askQty": "0.0",
|
|
1644
|
+
// "time": "1776411276072",
|
|
1645
|
+
// "lastUpdateId": "453174307613" // only in PERP
|
|
1646
|
+
// }, ...
|
|
1647
|
+
//
|
|
1648
|
+
return this.parseTickers(response, symbols);
|
|
1649
|
+
}
|
|
1526
1650
|
parseFundingRate(contract, market = undefined) {
|
|
1651
|
+
//
|
|
1652
|
+
// fundingRate
|
|
1527
1653
|
//
|
|
1528
1654
|
// {
|
|
1529
1655
|
// "symbol": "BTCUSDT",
|
|
@@ -1535,6 +1661,9 @@ export default class aster extends Exchange {
|
|
|
1535
1661
|
// "nextFundingTime": 1750147200000,
|
|
1536
1662
|
// "time": 1750146970000
|
|
1537
1663
|
// }
|
|
1664
|
+
//
|
|
1665
|
+
// funding interval
|
|
1666
|
+
//
|
|
1538
1667
|
// {
|
|
1539
1668
|
// "symbol": "INJUSDT",
|
|
1540
1669
|
// "interestRate": "0.00010000",
|
|
@@ -1577,7 +1706,7 @@ export default class aster extends Exchange {
|
|
|
1577
1706
|
* @method
|
|
1578
1707
|
* @name aster#fetchFundingRate
|
|
1579
1708
|
* @description fetch the current funding rate
|
|
1580
|
-
* @see https://github.
|
|
1709
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#symbol-price-ticker
|
|
1581
1710
|
* @param {string} symbol unified market symbol
|
|
1582
1711
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1583
1712
|
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
@@ -1591,7 +1720,7 @@ export default class aster extends Exchange {
|
|
|
1591
1720
|
const request = {
|
|
1592
1721
|
'symbol': market['id'],
|
|
1593
1722
|
};
|
|
1594
|
-
const response = await this.
|
|
1723
|
+
const response = await this.fapiPublicGetV3PremiumIndex(this.extend(request, params));
|
|
1595
1724
|
//
|
|
1596
1725
|
// {
|
|
1597
1726
|
// "symbol": "BTCUSDT",
|
|
@@ -1610,7 +1739,7 @@ export default class aster extends Exchange {
|
|
|
1610
1739
|
* @method
|
|
1611
1740
|
* @name aster#fetchFundingRates
|
|
1612
1741
|
* @description fetch the current funding rate for multiple symbols
|
|
1613
|
-
* @see https://github.
|
|
1742
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#symbol-price-ticker
|
|
1614
1743
|
* @param {string[]} [symbols] list of unified market symbols
|
|
1615
1744
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1616
1745
|
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
@@ -1618,7 +1747,7 @@ export default class aster extends Exchange {
|
|
|
1618
1747
|
async fetchFundingRates(symbols = undefined, params = {}) {
|
|
1619
1748
|
await this.loadMarkets();
|
|
1620
1749
|
symbols = this.marketSymbols(symbols);
|
|
1621
|
-
const response = await this.
|
|
1750
|
+
const response = await this.fapiPublicGetV3PremiumIndex(this.extend(params));
|
|
1622
1751
|
//
|
|
1623
1752
|
// [
|
|
1624
1753
|
// {
|
|
@@ -1639,7 +1768,7 @@ export default class aster extends Exchange {
|
|
|
1639
1768
|
* @method
|
|
1640
1769
|
* @name aster#fetchFundingIntervals
|
|
1641
1770
|
* @description fetch the funding rate interval for multiple markets
|
|
1642
|
-
* @see https://github.
|
|
1771
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#get-funding-rate-config
|
|
1643
1772
|
* @param {string[]} [symbols] list of unified market symbols
|
|
1644
1773
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1645
1774
|
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
@@ -1649,7 +1778,7 @@ export default class aster extends Exchange {
|
|
|
1649
1778
|
if (symbols !== undefined) {
|
|
1650
1779
|
symbols = this.marketSymbols(symbols);
|
|
1651
1780
|
}
|
|
1652
|
-
const response = await this.
|
|
1781
|
+
const response = await this.fapiPublicGetV3FundingInfo(params);
|
|
1653
1782
|
//
|
|
1654
1783
|
// [
|
|
1655
1784
|
// {
|
|
@@ -1664,64 +1793,98 @@ export default class aster extends Exchange {
|
|
|
1664
1793
|
//
|
|
1665
1794
|
return this.parseFundingRates(response, symbols);
|
|
1666
1795
|
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1796
|
+
/**
|
|
1797
|
+
* @method
|
|
1798
|
+
* @name aster#fetchFundingRateHistory
|
|
1799
|
+
* @description fetches historical funding rate prices
|
|
1800
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#get-funding-rate-history
|
|
1801
|
+
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
1802
|
+
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
1803
|
+
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
|
1804
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1805
|
+
* @param {int} [params.until] timestamp in ms of the latest funding rate
|
|
1806
|
+
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
|
|
1807
|
+
*/
|
|
1808
|
+
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1809
|
+
await this.loadMarkets();
|
|
1810
|
+
let request = {};
|
|
1811
|
+
let market = undefined;
|
|
1812
|
+
if (symbol !== undefined) {
|
|
1813
|
+
market = this.market(symbol);
|
|
1814
|
+
request['symbol'] = market['id'];
|
|
1678
1815
|
}
|
|
1679
|
-
|
|
1816
|
+
if (since !== undefined) {
|
|
1817
|
+
request['startTime'] = since;
|
|
1818
|
+
}
|
|
1819
|
+
if (limit !== undefined) {
|
|
1820
|
+
request['limit'] = Math.min(limit, 1000);
|
|
1821
|
+
}
|
|
1822
|
+
[request, params] = this.handleUntilOption('endTime', request, params);
|
|
1823
|
+
const response = await this.fapiPublicGetV3FundingRate(this.extend(request, params));
|
|
1824
|
+
//
|
|
1825
|
+
// [
|
|
1826
|
+
// {
|
|
1827
|
+
// "symbol": "BTCUSDT",
|
|
1828
|
+
// "fundingTime": 1747209600000,
|
|
1829
|
+
// "fundingRate": "0.00010000"
|
|
1830
|
+
// }
|
|
1831
|
+
// ]
|
|
1832
|
+
//
|
|
1833
|
+
return this.parseFundingRateHistories(response, market);
|
|
1834
|
+
}
|
|
1835
|
+
parseFundingRateHistory(contract, market = undefined) {
|
|
1836
|
+
//
|
|
1837
|
+
// {
|
|
1838
|
+
// "symbol": "BTCUSDT",
|
|
1839
|
+
// "fundingRate": "0.00063521",
|
|
1840
|
+
// "fundingTime": "1621267200000",
|
|
1841
|
+
// }
|
|
1842
|
+
//
|
|
1843
|
+
const timestamp = this.safeInteger(contract, 'fundingTime');
|
|
1844
|
+
return {
|
|
1845
|
+
'info': contract,
|
|
1846
|
+
'symbol': this.safeSymbol(this.safeString(contract, 'symbol'), undefined, undefined, 'swap'),
|
|
1847
|
+
'fundingRate': this.safeNumber(contract, 'fundingRate'),
|
|
1848
|
+
'timestamp': timestamp,
|
|
1849
|
+
'datetime': this.iso8601(timestamp),
|
|
1850
|
+
};
|
|
1680
1851
|
}
|
|
1681
1852
|
/**
|
|
1682
1853
|
* @method
|
|
1683
1854
|
* @name aster#fetchBalance
|
|
1684
1855
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1685
|
-
* @see https://github.
|
|
1686
|
-
* @see https://github.
|
|
1856
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#account-information-user_data
|
|
1857
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#futures-account-balance-v3-user_data
|
|
1687
1858
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1688
1859
|
* @param {string} [params.subType] "linear" or "inverse"
|
|
1689
1860
|
* @param {string} [params.type] 'spot', 'option', use params["subType"] for swap and future markets
|
|
1690
1861
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1691
1862
|
*/
|
|
1692
1863
|
async fetchBalance(params = {}) {
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
[subType, params] = this.handleSubTypeAndParams('fetchBalance', undefined, params);
|
|
1864
|
+
await this.loadMarketsAndSignIn();
|
|
1865
|
+
let marketType = undefined;
|
|
1866
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
|
|
1697
1867
|
let response = undefined;
|
|
1698
1868
|
let data = undefined;
|
|
1699
|
-
if (
|
|
1700
|
-
|
|
1701
|
-
data = this.safeList(response, 'assets', []);
|
|
1869
|
+
if (marketType === 'swap') {
|
|
1870
|
+
data = await this.fapiPrivateGetV3Balance(params);
|
|
1702
1871
|
//
|
|
1703
|
-
//
|
|
1704
|
-
//
|
|
1705
|
-
//
|
|
1706
|
-
//
|
|
1707
|
-
//
|
|
1708
|
-
//
|
|
1709
|
-
//
|
|
1710
|
-
//
|
|
1711
|
-
//
|
|
1712
|
-
//
|
|
1713
|
-
//
|
|
1714
|
-
//
|
|
1715
|
-
// "availableBalance": "23.72469206", // available balance
|
|
1716
|
-
// "maxWithdrawAmount": "23.72469206", // maximum amount for transfer out
|
|
1717
|
-
// "marginAvailable": true, // whether the asset can be used as margin in Multi-Assets mode
|
|
1718
|
-
// "updateTime": 1625474304765 // last update time
|
|
1719
|
-
// }
|
|
1720
|
-
// ]
|
|
1872
|
+
// [
|
|
1873
|
+
// {
|
|
1874
|
+
// "accountAlias": "FzXquXsRFzXqAufW",
|
|
1875
|
+
// "asset": "CDL",
|
|
1876
|
+
// "balance": "0.00000000",
|
|
1877
|
+
// "crossWalletBalance": "0.00000000",
|
|
1878
|
+
// "crossUnPnl": "0.00000000",
|
|
1879
|
+
// "availableBalance": "878.90500233",
|
|
1880
|
+
// "maxWithdrawAmount": "0.00000000",
|
|
1881
|
+
// "marginAvailable": true,
|
|
1882
|
+
// "updateTime": "0"
|
|
1883
|
+
// }, ...
|
|
1721
1884
|
//
|
|
1722
1885
|
}
|
|
1723
|
-
else if (
|
|
1724
|
-
response = await this.
|
|
1886
|
+
else if (marketType === 'spot') {
|
|
1887
|
+
response = await this.sapiPrivateGetV3Account(params);
|
|
1725
1888
|
data = this.safeList(response, 'balances', []);
|
|
1726
1889
|
//
|
|
1727
1890
|
// [
|
|
@@ -1733,16 +1896,27 @@ export default class aster extends Exchange {
|
|
|
1733
1896
|
// ]
|
|
1734
1897
|
//
|
|
1735
1898
|
}
|
|
1736
|
-
else {
|
|
1737
|
-
throw new NotSupported(this.id + ' fetchBalance() does not support ' + type + ' markets yet');
|
|
1738
|
-
}
|
|
1739
1899
|
return this.parseBalance(data);
|
|
1740
1900
|
}
|
|
1901
|
+
parseBalance(response) {
|
|
1902
|
+
const result = { 'info': response };
|
|
1903
|
+
for (let i = 0; i < response.length; i++) {
|
|
1904
|
+
const balance = response[i];
|
|
1905
|
+
const currencyId = this.safeString(balance, 'asset');
|
|
1906
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1907
|
+
const account = this.account();
|
|
1908
|
+
account['free'] = this.safeString2(balance, 'free', 'availableBalance');
|
|
1909
|
+
account['used'] = this.safeString(balance, 'locked');
|
|
1910
|
+
account['total'] = this.safeString(balance, 'balance');
|
|
1911
|
+
result[code] = account;
|
|
1912
|
+
}
|
|
1913
|
+
return this.safeBalance(result);
|
|
1914
|
+
}
|
|
1741
1915
|
/**
|
|
1742
1916
|
* @method
|
|
1743
1917
|
* @name aster#setMarginMode
|
|
1744
1918
|
* @description set margin mode to 'cross' or 'isolated'
|
|
1745
|
-
* @see https://github.
|
|
1919
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#change-margin-type-trade
|
|
1746
1920
|
* @param {string} marginMode 'cross' or 'isolated'
|
|
1747
1921
|
* @param {string} symbol unified market symbol
|
|
1748
1922
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -1759,20 +1933,15 @@ export default class aster extends Exchange {
|
|
|
1759
1933
|
if ((marginMode !== 'ISOLATED') && (marginMode !== 'CROSSED')) {
|
|
1760
1934
|
throw new BadRequest(this.id + ' marginMode must be either isolated or cross');
|
|
1761
1935
|
}
|
|
1762
|
-
await this.
|
|
1936
|
+
await this.loadMarketsAndSignIn();
|
|
1763
1937
|
const market = this.market(symbol);
|
|
1764
1938
|
const request = {
|
|
1765
1939
|
'symbol': market['id'],
|
|
1766
1940
|
'marginType': marginMode,
|
|
1767
1941
|
};
|
|
1768
|
-
const response = await this.
|
|
1942
|
+
const response = await this.fapiPrivatePostV3MarginType(this.extend(request, params));
|
|
1769
1943
|
//
|
|
1770
|
-
// {
|
|
1771
|
-
// "amount": 100.0,
|
|
1772
|
-
// "code": 200,
|
|
1773
|
-
// "msg": "Successfully modify position margin.",
|
|
1774
|
-
// "type": 1
|
|
1775
|
-
// }
|
|
1944
|
+
// { "code": 200,"msg": "success" }
|
|
1776
1945
|
//
|
|
1777
1946
|
return response;
|
|
1778
1947
|
}
|
|
@@ -1780,37 +1949,37 @@ export default class aster extends Exchange {
|
|
|
1780
1949
|
* @method
|
|
1781
1950
|
* @name aster#fetchPositionMode
|
|
1782
1951
|
* @description fetchs the position mode, hedged or one way, hedged for aster is set identically for all linear markets or all inverse markets
|
|
1783
|
-
* @see https://github.
|
|
1952
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#get-current-position-modeuser_data
|
|
1784
1953
|
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
1785
1954
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1786
1955
|
* @returns {object} an object detailing whether the market is in hedged or one-way mode
|
|
1787
1956
|
*/
|
|
1788
1957
|
async fetchPositionMode(symbol = undefined, params = {}) {
|
|
1789
|
-
const response = await this.
|
|
1958
|
+
const response = await this.fapiPrivateGetV3PositionSideDual(params);
|
|
1790
1959
|
//
|
|
1791
1960
|
// {
|
|
1792
1961
|
// "dualSidePosition": true // "true": Hedge Mode; "false": One-way Mode
|
|
1793
1962
|
// }
|
|
1794
1963
|
//
|
|
1795
|
-
const dualSidePosition = this.safeBool(response, 'dualSidePosition');
|
|
1796
1964
|
return {
|
|
1797
1965
|
'info': response,
|
|
1798
|
-
'hedged': (dualSidePosition
|
|
1966
|
+
'hedged': this.safeBool(response, 'dualSidePosition'),
|
|
1799
1967
|
};
|
|
1800
1968
|
}
|
|
1801
1969
|
/**
|
|
1802
1970
|
* @method
|
|
1803
1971
|
* @name aster#setPositionMode
|
|
1804
1972
|
* @description set hedged to true or false for a market
|
|
1805
|
-
* @see https://github.
|
|
1973
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#change-position-modetrade
|
|
1806
1974
|
* @param {bool} hedged set to true to use dualSidePosition
|
|
1807
1975
|
* @param {string} symbol not used by bingx setPositionMode ()
|
|
1808
1976
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1809
1977
|
* @returns {object} response from the exchange
|
|
1810
1978
|
*/
|
|
1811
1979
|
async setPositionMode(hedged, symbol = undefined, params = {}) {
|
|
1980
|
+
const strValue = hedged ? 'true' : 'false';
|
|
1812
1981
|
const request = {
|
|
1813
|
-
'dualSidePosition':
|
|
1982
|
+
'dualSidePosition': strValue,
|
|
1814
1983
|
};
|
|
1815
1984
|
//
|
|
1816
1985
|
// {
|
|
@@ -1818,7 +1987,7 @@ export default class aster extends Exchange {
|
|
|
1818
1987
|
// "msg": "success"
|
|
1819
1988
|
// }
|
|
1820
1989
|
//
|
|
1821
|
-
return await this.
|
|
1990
|
+
return await this.fapiPrivatePostV3PositionSideDual(this.extend(request, params));
|
|
1822
1991
|
}
|
|
1823
1992
|
parseTradingFee(fee, market = undefined) {
|
|
1824
1993
|
const marketId = this.safeString(fee, 'symbol');
|
|
@@ -1837,26 +2006,28 @@ export default class aster extends Exchange {
|
|
|
1837
2006
|
* @method
|
|
1838
2007
|
* @name aster#fetchTradingFee
|
|
1839
2008
|
* @description fetch the trading fees for a market
|
|
1840
|
-
* @see https://github.
|
|
1841
|
-
* @see https://github.
|
|
2009
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#get-symbol-fees
|
|
2010
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#user-commission-rate-user_data
|
|
1842
2011
|
* @param {string} symbol unified market symbol
|
|
1843
2012
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1844
2013
|
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
1845
2014
|
*/
|
|
1846
2015
|
async fetchTradingFee(symbol, params = {}) {
|
|
1847
|
-
await this.
|
|
2016
|
+
await this.loadMarketsAndSignIn();
|
|
1848
2017
|
const market = this.market(symbol);
|
|
1849
2018
|
const request = {
|
|
1850
2019
|
'symbol': market['id'],
|
|
1851
2020
|
};
|
|
1852
2021
|
let response = undefined;
|
|
1853
2022
|
if (market['swap']) {
|
|
1854
|
-
response = await this.
|
|
2023
|
+
response = await this.fapiPrivateGetV3CommissionRate(this.extend(request, params));
|
|
1855
2024
|
}
|
|
1856
2025
|
else {
|
|
1857
|
-
response = await this.
|
|
2026
|
+
response = await this.sapiPrivateGetV3CommissionRate(this.extend(request, params));
|
|
1858
2027
|
}
|
|
1859
2028
|
//
|
|
2029
|
+
// both SPOT & SWAP has same format
|
|
2030
|
+
//
|
|
1860
2031
|
// {
|
|
1861
2032
|
// "symbol": "BTCUSDT",
|
|
1862
2033
|
// "makerCommissionRate": "0.0002",
|
|
@@ -1916,32 +2087,36 @@ export default class aster extends Exchange {
|
|
|
1916
2087
|
// "workingType": "CONTRACT_PRICE",
|
|
1917
2088
|
// "priceProtect": false
|
|
1918
2089
|
// }
|
|
2090
|
+
//
|
|
1919
2091
|
// spot
|
|
1920
|
-
//
|
|
1921
|
-
//
|
|
1922
|
-
//
|
|
1923
|
-
//
|
|
1924
|
-
//
|
|
1925
|
-
//
|
|
1926
|
-
//
|
|
1927
|
-
//
|
|
1928
|
-
//
|
|
1929
|
-
//
|
|
1930
|
-
//
|
|
1931
|
-
//
|
|
1932
|
-
//
|
|
1933
|
-
//
|
|
1934
|
-
//
|
|
1935
|
-
//
|
|
1936
|
-
//
|
|
1937
|
-
//
|
|
2092
|
+
//
|
|
2093
|
+
// fetchOrders, fetchOpenOrders, fetchOpenOrder, fetchOrder, cancelOrder, createOrder
|
|
2094
|
+
//
|
|
2095
|
+
// {
|
|
2096
|
+
// "orderId": "417594542",
|
|
2097
|
+
// "symbol": "ETHUSDT",
|
|
2098
|
+
// "status": "FILLED",
|
|
2099
|
+
// "clientOrderId": "web_qnvMAhOJsiVbSyu0BdKG",
|
|
2100
|
+
// "price": "0", // value set for unfilled
|
|
2101
|
+
// "avgPrice": "2351.580000", // value zero for unfilled
|
|
2102
|
+
// "origQty": "0.0054",
|
|
2103
|
+
// "executedQty": "0.0054", // value zero for unfilled
|
|
2104
|
+
// "cumQuote": "12.69853200", // value zero for unfilled
|
|
2105
|
+
// "timeInForce": "GTC",
|
|
2106
|
+
// "type": "MARKET",
|
|
2107
|
+
// "side": "SELL",
|
|
2108
|
+
// "stopPrice": "0",
|
|
2109
|
+
// "origType": "MARKET",
|
|
2110
|
+
// "time": "1776274219582",
|
|
2111
|
+
// "updateTime": "1776274219609",
|
|
2112
|
+
// "orderListId": "-1"
|
|
2113
|
+
// }
|
|
1938
2114
|
//
|
|
1939
2115
|
const info = order;
|
|
1940
2116
|
const marketId = this.safeString(order, 'symbol');
|
|
1941
2117
|
market = this.safeMarket(marketId, market);
|
|
1942
2118
|
const side = this.safeStringLower(order, 'side');
|
|
1943
2119
|
const timestamp = this.safeInteger(order, 'time');
|
|
1944
|
-
const lastTradeTimestamp = this.safeInteger(order, 'updateTime');
|
|
1945
2120
|
const statusId = this.safeStringUpper(order, 'status');
|
|
1946
2121
|
const rawType = this.safeStringUpper(order, 'type');
|
|
1947
2122
|
const stopPriceString = this.safeString(order, 'stopPrice');
|
|
@@ -1953,7 +2128,7 @@ export default class aster extends Exchange {
|
|
|
1953
2128
|
'symbol': this.safeSymbol(marketId, market),
|
|
1954
2129
|
'timestamp': timestamp,
|
|
1955
2130
|
'datetime': this.iso8601(timestamp),
|
|
1956
|
-
'lastTradeTimestamp':
|
|
2131
|
+
'lastTradeTimestamp': undefined,
|
|
1957
2132
|
'lastUpdateTimestamp': this.safeInteger(order, 'updateTime'),
|
|
1958
2133
|
'type': this.parseOrderType(rawType),
|
|
1959
2134
|
'timeInForce': this.safeString(order, 'timeInForce'),
|
|
@@ -1976,8 +2151,8 @@ export default class aster extends Exchange {
|
|
|
1976
2151
|
* @method
|
|
1977
2152
|
* @name aster#fetchOrder
|
|
1978
2153
|
* @description fetches information on an order made by the user
|
|
1979
|
-
* @see https://github.
|
|
1980
|
-
* @see https://github.
|
|
2154
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#query-order-user_data
|
|
2155
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#query-order-user_data
|
|
1981
2156
|
* @param {string} id the order id
|
|
1982
2157
|
* @param {string} symbol unified symbol of the market the order was made in
|
|
1983
2158
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -1988,7 +2163,7 @@ export default class aster extends Exchange {
|
|
|
1988
2163
|
if (symbol === undefined) {
|
|
1989
2164
|
throw new ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
|
|
1990
2165
|
}
|
|
1991
|
-
await this.
|
|
2166
|
+
await this.loadMarketsAndSignIn();
|
|
1992
2167
|
const market = this.market(symbol);
|
|
1993
2168
|
const request = {
|
|
1994
2169
|
'symbol': market['id'],
|
|
@@ -2003,18 +2178,48 @@ export default class aster extends Exchange {
|
|
|
2003
2178
|
}
|
|
2004
2179
|
let response = undefined;
|
|
2005
2180
|
if (market['swap']) {
|
|
2006
|
-
response = await this.
|
|
2181
|
+
response = await this.fapiPrivateGetV3Order(this.extend(request, params));
|
|
2007
2182
|
}
|
|
2008
2183
|
else {
|
|
2009
|
-
response = await this.
|
|
2184
|
+
response = await this.sapiPrivateGetV3Order(this.extend(request, params));
|
|
2010
2185
|
}
|
|
2186
|
+
//
|
|
2187
|
+
// SPOT & SWAP has similar formats
|
|
2188
|
+
//
|
|
2189
|
+
// {
|
|
2190
|
+
// "orderId": "17338441758",
|
|
2191
|
+
// "symbol": "ETHUSDT",
|
|
2192
|
+
// "status": "FILLED",
|
|
2193
|
+
// "clientOrderId": "727Wt3TIUgkUCxXp20E543",
|
|
2194
|
+
// "price": "0",
|
|
2195
|
+
// "avgPrice": "2304.56000",
|
|
2196
|
+
// "origQty": "0.010",
|
|
2197
|
+
// "executedQty": "0.010",
|
|
2198
|
+
// "cumQuote": "23.04560",
|
|
2199
|
+
// "timeInForce": "GTC",
|
|
2200
|
+
// "type": "MARKET",
|
|
2201
|
+
// "side": "BUY",
|
|
2202
|
+
// "stopPrice": "0",
|
|
2203
|
+
// "origType": "MARKET",
|
|
2204
|
+
// "time": "1776800300736",
|
|
2205
|
+
// "updateTime": "1776800300700",
|
|
2206
|
+
// "orderListId": "-1" // only in SPOT
|
|
2207
|
+
// "positionSide": "BOTH", // only in SWAP
|
|
2208
|
+
// "reduceOnly": false, // only in SWAP
|
|
2209
|
+
// "closePosition": false, // only in SWAP
|
|
2210
|
+
// "workingType": "CONTRACT_PRICE", // only in SWAP
|
|
2211
|
+
// "priceProtect": false, // only in SWAP
|
|
2212
|
+
// "newChainData": { "hash": "0x46aed5...67bdbec8ba" } // only in SWAP
|
|
2213
|
+
// }
|
|
2214
|
+
//
|
|
2011
2215
|
return this.parseOrder(response, market);
|
|
2012
2216
|
}
|
|
2013
2217
|
/**
|
|
2014
2218
|
* @method
|
|
2015
2219
|
* @name aster#fetchOpenOrder
|
|
2016
2220
|
* @description fetch an open order by the id
|
|
2017
|
-
* @see https://github.
|
|
2221
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#query-current-open-order-user_data
|
|
2222
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#query-current-open-order-user_data
|
|
2018
2223
|
* @param {string} id order id
|
|
2019
2224
|
* @param {string} symbol unified market symbol
|
|
2020
2225
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -2024,7 +2229,7 @@ export default class aster extends Exchange {
|
|
|
2024
2229
|
if (symbol === undefined) {
|
|
2025
2230
|
throw new ArgumentsRequired(this.id + ' fetchOpenOrder() requires a symbol argument');
|
|
2026
2231
|
}
|
|
2027
|
-
await this.
|
|
2232
|
+
await this.loadMarketsAndSignIn();
|
|
2028
2233
|
const market = this.market(symbol);
|
|
2029
2234
|
const request = {
|
|
2030
2235
|
'symbol': market['id'],
|
|
@@ -2037,15 +2242,50 @@ export default class aster extends Exchange {
|
|
|
2037
2242
|
else {
|
|
2038
2243
|
request['orderId'] = id;
|
|
2039
2244
|
}
|
|
2040
|
-
|
|
2245
|
+
let response = undefined;
|
|
2246
|
+
if (market['spot']) {
|
|
2247
|
+
response = await this.sapiPrivateGetV3OpenOrder(this.extend(request, params));
|
|
2248
|
+
}
|
|
2249
|
+
else {
|
|
2250
|
+
response = await this.fapiPrivateGetV3OpenOrder(this.extend(request, params));
|
|
2251
|
+
}
|
|
2252
|
+
//
|
|
2253
|
+
// SPOT & SWAP has similar formats
|
|
2254
|
+
//
|
|
2255
|
+
// {
|
|
2256
|
+
// "orderId": "17338441758",
|
|
2257
|
+
// "symbol": "ETHUSDT",
|
|
2258
|
+
// "status": "FILLED",
|
|
2259
|
+
// "clientOrderId": "727Wt3TIUgkUCxXp20E543",
|
|
2260
|
+
// "price": "0",
|
|
2261
|
+
// "avgPrice": "2304.56000",
|
|
2262
|
+
// "origQty": "0.010",
|
|
2263
|
+
// "executedQty": "0.010",
|
|
2264
|
+
// "cumQuote": "23.04560",
|
|
2265
|
+
// "timeInForce": "GTC",
|
|
2266
|
+
// "type": "MARKET",
|
|
2267
|
+
// "side": "BUY",
|
|
2268
|
+
// "stopPrice": "0",
|
|
2269
|
+
// "origType": "MARKET",
|
|
2270
|
+
// "time": "1776800300736",
|
|
2271
|
+
// "updateTime": "1776800300700",
|
|
2272
|
+
// "orderListId": "-1" // only in SPOT
|
|
2273
|
+
// "positionSide": "BOTH", // only in SWAP
|
|
2274
|
+
// "reduceOnly": false, // only in SWAP
|
|
2275
|
+
// "closePosition": false, // only in SWAP
|
|
2276
|
+
// "workingType": "CONTRACT_PRICE", // only in SWAP
|
|
2277
|
+
// "priceProtect": false, // only in SWAP
|
|
2278
|
+
// "newChainData": { "hash": "0x46aed5...67bdbec8ba" } // only in SWAP
|
|
2279
|
+
// }
|
|
2280
|
+
//
|
|
2041
2281
|
return this.parseOrder(response, market);
|
|
2042
2282
|
}
|
|
2043
2283
|
/**
|
|
2044
2284
|
* @method
|
|
2045
2285
|
* @name aster#fetchOrders
|
|
2046
2286
|
* @description fetches information on multiple orders made by the user
|
|
2047
|
-
* @see https://github.
|
|
2048
|
-
* @see https://github.
|
|
2287
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#query-all-orders-user_data
|
|
2288
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#all-orders-user_data
|
|
2049
2289
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
2050
2290
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2051
2291
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
@@ -2054,39 +2294,66 @@ export default class aster extends Exchange {
|
|
|
2054
2294
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2055
2295
|
*/
|
|
2056
2296
|
async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2057
|
-
await this.loadMarkets();
|
|
2058
2297
|
if (symbol === undefined) {
|
|
2059
2298
|
throw new ArgumentsRequired(this.id + ' fetchOrders() requires a symbol argument');
|
|
2060
2299
|
}
|
|
2300
|
+
await this.loadMarketsAndSignIn();
|
|
2061
2301
|
const market = this.market(symbol);
|
|
2062
2302
|
let request = {
|
|
2063
2303
|
'symbol': market['id'],
|
|
2064
2304
|
};
|
|
2305
|
+
if (limit !== undefined) {
|
|
2306
|
+
request['limit'] = Math.min(limit, 1000);
|
|
2307
|
+
}
|
|
2065
2308
|
if (since !== undefined) {
|
|
2066
2309
|
request['startTime'] = since;
|
|
2067
2310
|
}
|
|
2068
|
-
if (limit !== undefined) {
|
|
2069
|
-
if (limit > 1000) {
|
|
2070
|
-
limit = 1000; // Default 500; max 1000
|
|
2071
|
-
}
|
|
2072
|
-
request['limit'] = limit;
|
|
2073
|
-
}
|
|
2074
2311
|
[request, params] = this.handleUntilOption('endTime', request, params);
|
|
2075
2312
|
let response = undefined;
|
|
2076
2313
|
if (market['swap']) {
|
|
2077
|
-
response = await this.
|
|
2314
|
+
response = await this.fapiPrivateGetV3AllOrders(this.extend(request, params));
|
|
2078
2315
|
}
|
|
2079
2316
|
else {
|
|
2080
|
-
response = await this.
|
|
2317
|
+
response = await this.sapiPrivateGetV3AllOrders(this.extend(request, params));
|
|
2081
2318
|
}
|
|
2319
|
+
//
|
|
2320
|
+
// SPOT & SWAP has similar responses
|
|
2321
|
+
//
|
|
2322
|
+
// [
|
|
2323
|
+
// {
|
|
2324
|
+
// "orderId": "417594542",
|
|
2325
|
+
// "symbol": "ETHUSDT",
|
|
2326
|
+
// "status": "FILLED",
|
|
2327
|
+
// "clientOrderId": "web_qnvMAhOJsiVbSyu0BdKG",
|
|
2328
|
+
// "price": "0", // value set for unfilled
|
|
2329
|
+
// "avgPrice": "2351.580000", // value zero for unfilled
|
|
2330
|
+
// "origQty": "0.0054",
|
|
2331
|
+
// "executedQty": "0.0054", // value zero for unfilled
|
|
2332
|
+
// "cumQuote": "12.69853200", // value zero for unfilled
|
|
2333
|
+
// "timeInForce": "GTC",
|
|
2334
|
+
// "type": "MARKET",
|
|
2335
|
+
// "side": "SELL",
|
|
2336
|
+
// "stopPrice": "0",
|
|
2337
|
+
// "origType": "MARKET",
|
|
2338
|
+
// "time": "1776274219582",
|
|
2339
|
+
// "updateTime": "1776274219609",
|
|
2340
|
+
// "orderListId": "-1", // only in SPOT
|
|
2341
|
+
// "reduceOnly": false, // only in PERP
|
|
2342
|
+
// "closePosition": false, // only in PERP
|
|
2343
|
+
// "positionSide": "BOTH", // only in PERP
|
|
2344
|
+
// "workingType": "CONTRACT_PRICE", // only in PERP
|
|
2345
|
+
// "priceProtect": false, // only in PERP
|
|
2346
|
+
// "newChainData": { "hash": "0xe17d3d5b...dbca8b01" } // only in PERP
|
|
2347
|
+
// }, ...
|
|
2348
|
+
//
|
|
2082
2349
|
return this.parseOrders(response, market, since, limit);
|
|
2083
2350
|
}
|
|
2084
2351
|
/**
|
|
2085
2352
|
* @method
|
|
2086
2353
|
* @name aster#fetchOpenOrders
|
|
2087
2354
|
* @description fetch all unfilled currently open orders
|
|
2088
|
-
* @see https://github.
|
|
2089
|
-
* @see https://github.
|
|
2355
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#current-open-orders-user_data
|
|
2356
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#current-all-open-orders-user_data
|
|
2090
2357
|
* @param {string} symbol unified market symbol
|
|
2091
2358
|
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
2092
2359
|
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
@@ -2096,55 +2363,63 @@ export default class aster extends Exchange {
|
|
|
2096
2363
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2097
2364
|
*/
|
|
2098
2365
|
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2099
|
-
await this.
|
|
2366
|
+
await this.loadMarketsAndSignIn();
|
|
2100
2367
|
const request = {};
|
|
2101
2368
|
let market = undefined;
|
|
2102
|
-
let
|
|
2103
|
-
let subType = undefined;
|
|
2104
|
-
[subType, params] = this.handleSubTypeAndParams('fetchOpenOrders', market, params);
|
|
2369
|
+
let marketType = undefined;
|
|
2105
2370
|
if (symbol !== undefined) {
|
|
2106
2371
|
market = this.market(symbol);
|
|
2107
2372
|
request['symbol'] = market['id'];
|
|
2108
2373
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
}
|
|
2114
|
-
else if (type === 'spot') {
|
|
2115
|
-
response = await this.sapiPrivateGetV1OpenOrders(this.extend(request, params));
|
|
2374
|
+
if (symbol === undefined) {
|
|
2375
|
+
if (this.options['fetchOpenOrders']['warnIfNoSymbol']) {
|
|
2376
|
+
throw new ExchangeError(this.id + ' fetchOpenOrders(): WARNING - this method without providing "symbol" argument uses 40 times more rate-limit quota. If you acknowledge this warning, set ' + this.id + '.options["fetchOpenOrders"]["warnIfNoSymbol"] = false to suppress this warning message.');
|
|
2377
|
+
}
|
|
2116
2378
|
}
|
|
2117
2379
|
else {
|
|
2118
|
-
|
|
2380
|
+
market = this.market(symbol);
|
|
2381
|
+
request['symbol'] = market['id'];
|
|
2382
|
+
}
|
|
2383
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
|
|
2384
|
+
let subType = undefined;
|
|
2385
|
+
[subType, params] = this.handleSubTypeAndParams('fetchOpenOrders', market, params);
|
|
2386
|
+
let response = undefined;
|
|
2387
|
+
if (this.isLinear(marketType, subType)) {
|
|
2388
|
+
response = await this.fapiPrivateGetV3OpenOrders(this.extend(request, params));
|
|
2389
|
+
}
|
|
2390
|
+
else if (marketType === 'spot') {
|
|
2391
|
+
response = await this.sapiPrivateGetV3OpenOrders(this.extend(request, params));
|
|
2119
2392
|
}
|
|
2120
2393
|
//
|
|
2121
|
-
//
|
|
2122
|
-
//
|
|
2123
|
-
//
|
|
2124
|
-
//
|
|
2125
|
-
//
|
|
2126
|
-
//
|
|
2127
|
-
//
|
|
2128
|
-
//
|
|
2129
|
-
//
|
|
2130
|
-
//
|
|
2131
|
-
//
|
|
2132
|
-
//
|
|
2133
|
-
//
|
|
2134
|
-
//
|
|
2135
|
-
//
|
|
2136
|
-
//
|
|
2137
|
-
//
|
|
2138
|
-
//
|
|
2139
|
-
//
|
|
2140
|
-
//
|
|
2141
|
-
//
|
|
2142
|
-
//
|
|
2143
|
-
//
|
|
2144
|
-
//
|
|
2145
|
-
//
|
|
2146
|
-
//
|
|
2147
|
-
//
|
|
2394
|
+
// SPOT & SWAP has similar responses
|
|
2395
|
+
//
|
|
2396
|
+
// [
|
|
2397
|
+
// {
|
|
2398
|
+
// "orderId": "17338239315",
|
|
2399
|
+
// "symbol": "ETHUSDT",
|
|
2400
|
+
// "status": "NEW",
|
|
2401
|
+
// "clientOrderId": "web_AD_mbhgla7k15gptmwyr_x",
|
|
2402
|
+
// "price": "2216.62",
|
|
2403
|
+
// "avgPrice": "0",
|
|
2404
|
+
// "origQty": "0.012",
|
|
2405
|
+
// "executedQty": "0",
|
|
2406
|
+
// "cumQuote": "0",
|
|
2407
|
+
// "timeInForce": "GTC",
|
|
2408
|
+
// "type": "LIMIT",
|
|
2409
|
+
// "side": "BUY",
|
|
2410
|
+
// "stopPrice": "0",
|
|
2411
|
+
// "origType": "LIMIT",
|
|
2412
|
+
// "time": "1776798208476",
|
|
2413
|
+
// "updateTime": "1776798208450",
|
|
2414
|
+
// "orderListId": "-1" // only in SPOT
|
|
2415
|
+
// "reduceOnly": false, // only in PERP
|
|
2416
|
+
// "closePosition": false, // only in PERP
|
|
2417
|
+
// "positionSide": "BOTH", // only in PERP
|
|
2418
|
+
// "workingType": "CONTRACT_PRICE", // only in PERP
|
|
2419
|
+
// "priceProtect": false, // only in PERP
|
|
2420
|
+
// "newChainData": { "hash": "0xf8a496....a7fd5" } // only in PERP
|
|
2421
|
+
// }
|
|
2422
|
+
// ]
|
|
2148
2423
|
//
|
|
2149
2424
|
return this.parseOrders(response, market, since, limit);
|
|
2150
2425
|
}
|
|
@@ -2152,8 +2427,8 @@ export default class aster extends Exchange {
|
|
|
2152
2427
|
* @method
|
|
2153
2428
|
* @name aster#createOrder
|
|
2154
2429
|
* @description create a trade order
|
|
2155
|
-
* @see https://github.
|
|
2156
|
-
* @see https://github.
|
|
2430
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#place-order-trade
|
|
2431
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#new-order-trade
|
|
2157
2432
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
2158
2433
|
* @param {string} type 'market' or 'limit' or 'STOP' or 'STOP_MARKET' or 'TAKE_PROFIT' or 'TAKE_PROFIT_MARKET' or 'TRAILING_STOP_MARKET'
|
|
2159
2434
|
* @param {string} side 'buy' or 'sell'
|
|
@@ -2171,36 +2446,59 @@ export default class aster extends Exchange {
|
|
|
2171
2446
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2172
2447
|
*/
|
|
2173
2448
|
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
2174
|
-
await this.
|
|
2449
|
+
await this.loadMarketsAndSignIn();
|
|
2175
2450
|
const market = this.market(symbol);
|
|
2176
|
-
const test = this.safeBool(params, 'test', false);
|
|
2177
|
-
params = this.omit(params, 'test');
|
|
2178
2451
|
const request = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
2179
2452
|
let response = undefined;
|
|
2180
2453
|
if (market['swap']) {
|
|
2181
|
-
|
|
2182
|
-
response = await this.fapiPrivatePostV1OrderTest(request);
|
|
2183
|
-
}
|
|
2184
|
-
else {
|
|
2185
|
-
response = await this.fapiPrivatePostV1Order(request);
|
|
2186
|
-
}
|
|
2454
|
+
response = await this.fapiPrivatePostV3Order(request);
|
|
2187
2455
|
}
|
|
2188
2456
|
else {
|
|
2189
|
-
response = await this.
|
|
2457
|
+
response = await this.sapiPrivatePostV3Order(request);
|
|
2190
2458
|
}
|
|
2459
|
+
//
|
|
2460
|
+
// SPOT & SWAP has similar responses
|
|
2461
|
+
//
|
|
2462
|
+
// {
|
|
2463
|
+
// "orderId": "17338441758",
|
|
2464
|
+
// "symbol": "ETHUSDT",
|
|
2465
|
+
// "status": "NEW",
|
|
2466
|
+
// "clientOrderId": "727Wt3TIUgkUCxXp20E543",
|
|
2467
|
+
// "price": "0",
|
|
2468
|
+
// "avgPrice": "0.00000",
|
|
2469
|
+
// "origQty": "0.010",
|
|
2470
|
+
// "executedQty": "0",
|
|
2471
|
+
// "cumQty": "0",
|
|
2472
|
+
// "cumQuote": "0",
|
|
2473
|
+
// "timeInForce": "GTC",
|
|
2474
|
+
// "type": "MARKET",
|
|
2475
|
+
// "side": "BUY",
|
|
2476
|
+
// "stopPrice": "0",
|
|
2477
|
+
// "origType": "MARKET",
|
|
2478
|
+
// "time": "1776800300700",
|
|
2479
|
+
// "updateTime": "1776800300700",
|
|
2480
|
+
// "orderListId": "-1", // only in SPOT
|
|
2481
|
+
// "workingType": "CONTRACT_PRICE", // only in PERP
|
|
2482
|
+
// "positionSide": "BOTH", // only in PERP
|
|
2483
|
+
// "reduceOnly": false, // only in PERP
|
|
2484
|
+
// "closePosition": false, // only in PERP
|
|
2485
|
+
// "priceProtect": false, // only in PERP
|
|
2486
|
+
// "newChainData": { "hash": "0x46ae....c8ba" } // only in PERP
|
|
2487
|
+
// }
|
|
2488
|
+
//
|
|
2191
2489
|
return this.parseOrder(response, market);
|
|
2192
2490
|
}
|
|
2193
2491
|
/**
|
|
2194
2492
|
* @method
|
|
2195
2493
|
* @name aster#createOrders
|
|
2196
2494
|
* @description create a list of trade orders
|
|
2197
|
-
* @see https://github.
|
|
2495
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#new-order-trade
|
|
2198
2496
|
* @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
|
|
2199
2497
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2200
2498
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2201
2499
|
*/
|
|
2202
2500
|
async createOrders(orders, params = {}) {
|
|
2203
|
-
await this.
|
|
2501
|
+
await this.loadMarketsAndSignIn();
|
|
2204
2502
|
const ordersRequests = [];
|
|
2205
2503
|
let orderSymbols = [];
|
|
2206
2504
|
if (orders.length > 5) {
|
|
@@ -2209,6 +2507,8 @@ export default class aster extends Exchange {
|
|
|
2209
2507
|
for (let i = 0; i < orders.length; i++) {
|
|
2210
2508
|
const rawOrder = orders[i];
|
|
2211
2509
|
const marketId = this.safeString(rawOrder, 'symbol');
|
|
2510
|
+
const currentMarket = this.market(marketId);
|
|
2511
|
+
orderSymbols.push(currentMarket['symbol']);
|
|
2212
2512
|
const type = this.safeString(rawOrder, 'type');
|
|
2213
2513
|
const side = this.safeString(rawOrder, 'side');
|
|
2214
2514
|
const amount = this.safeValue(rawOrder, 'amount');
|
|
@@ -2225,7 +2525,37 @@ export default class aster extends Exchange {
|
|
|
2225
2525
|
const request = {
|
|
2226
2526
|
'batchOrders': ordersRequests,
|
|
2227
2527
|
};
|
|
2228
|
-
const response = await this.
|
|
2528
|
+
const response = await this.fapiPrivatePostV3BatchOrders(this.extend(request, params));
|
|
2529
|
+
//
|
|
2530
|
+
// [
|
|
2531
|
+
// {
|
|
2532
|
+
// "orderId": 17338699853,
|
|
2533
|
+
// "symbol": "ETHUSDT",
|
|
2534
|
+
// "status": "NEW",
|
|
2535
|
+
// "clientOrderId": "NxMWPvOEyiF6TWh5UB8BQf0",
|
|
2536
|
+
// "price": "0",
|
|
2537
|
+
// "avgPrice": "0.00000",
|
|
2538
|
+
// "origQty": "0.010",
|
|
2539
|
+
// "executedQty": "0",
|
|
2540
|
+
// "cumQty": "0",
|
|
2541
|
+
// "cumQuote": "0",
|
|
2542
|
+
// "timeInForce": "GTC",
|
|
2543
|
+
// "type": "MARKET",
|
|
2544
|
+
// "reduceOnly": false,
|
|
2545
|
+
// "closePosition": false,
|
|
2546
|
+
// "side": "BUY",
|
|
2547
|
+
// "positionSide": "BOTH",
|
|
2548
|
+
// "stopPrice": "0",
|
|
2549
|
+
// "workingType": "CONTRACT_PRICE",
|
|
2550
|
+
// "priceProtect": false,
|
|
2551
|
+
// "origType": "MARKET",
|
|
2552
|
+
// "updateTime": 1776802276050,
|
|
2553
|
+
// "newChainData": {
|
|
2554
|
+
// "hash": "0x5e569d9794cf726f72c2d000d401d20315e78e4df7b58023a489864624527dfe"
|
|
2555
|
+
// }
|
|
2556
|
+
// }
|
|
2557
|
+
// ]
|
|
2558
|
+
//
|
|
2229
2559
|
return this.parseOrders(response);
|
|
2230
2560
|
}
|
|
2231
2561
|
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
@@ -2400,14 +2730,18 @@ export default class aster extends Exchange {
|
|
|
2400
2730
|
request['timeInForce'] = this.safeString(this.options, 'defaultTimeInForce'); // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
|
|
2401
2731
|
}
|
|
2402
2732
|
const requestParams = this.omit(params, ['newClientOrderId', 'clientOrderId', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent', 'trailingDelta', 'stopPrice', 'stopLossPrice', 'takeProfitPrice']);
|
|
2733
|
+
if (this.safeBool(this.options, 'builderFee') && market['swap']) {
|
|
2734
|
+
request['builder'] = this.safeString(this.options, 'builder');
|
|
2735
|
+
request['feeRate'] = this.safeString(this.options, 'builderRate');
|
|
2736
|
+
}
|
|
2403
2737
|
return this.extend(request, requestParams);
|
|
2404
2738
|
}
|
|
2405
2739
|
/**
|
|
2406
2740
|
* @method
|
|
2407
2741
|
* @name aster#cancelAllOrders
|
|
2408
2742
|
* @description cancel all open orders in a market
|
|
2409
|
-
* @see https://github.
|
|
2410
|
-
* @see https://github.
|
|
2743
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#cancel-all-open-orders-trade
|
|
2744
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#current-all-open-orders-user_data
|
|
2411
2745
|
* @param {string} symbol unified market symbol of the market to cancel orders in
|
|
2412
2746
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2413
2747
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
@@ -2416,19 +2750,21 @@ export default class aster extends Exchange {
|
|
|
2416
2750
|
if (symbol === undefined) {
|
|
2417
2751
|
throw new ArgumentsRequired(this.id + ' cancelAllOrders() requires a symbol argument');
|
|
2418
2752
|
}
|
|
2419
|
-
await this.
|
|
2753
|
+
await this.loadMarketsAndSignIn();
|
|
2420
2754
|
const market = this.market(symbol);
|
|
2421
2755
|
const request = {
|
|
2422
2756
|
'symbol': market['id'],
|
|
2423
2757
|
};
|
|
2424
2758
|
let response = undefined;
|
|
2425
2759
|
if (market['swap']) {
|
|
2426
|
-
response = await this.
|
|
2760
|
+
response = await this.fapiPrivateDeleteV3AllOpenOrders(this.extend(request, params));
|
|
2427
2761
|
}
|
|
2428
2762
|
else {
|
|
2429
|
-
response = await this.
|
|
2763
|
+
response = await this.sapiPrivateDeleteV3AllOpenOrders(this.extend(request, params));
|
|
2430
2764
|
}
|
|
2431
2765
|
//
|
|
2766
|
+
// SPOT & SWAP has same response
|
|
2767
|
+
//
|
|
2432
2768
|
// {
|
|
2433
2769
|
// "code": "200",
|
|
2434
2770
|
// "msg": "The operation of cancel all open order is done."
|
|
@@ -2444,8 +2780,8 @@ export default class aster extends Exchange {
|
|
|
2444
2780
|
* @method
|
|
2445
2781
|
* @name aster#cancelOrder
|
|
2446
2782
|
* @description cancels an open order
|
|
2447
|
-
* @see https://github.
|
|
2448
|
-
* @see https://github.
|
|
2783
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#cancel-order-trade
|
|
2784
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#cancel-order-trade
|
|
2449
2785
|
* @param {string} id order id
|
|
2450
2786
|
* @param {string} symbol unified symbol of the market the order was made in
|
|
2451
2787
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -2455,25 +2791,25 @@ export default class aster extends Exchange {
|
|
|
2455
2791
|
if (symbol === undefined) {
|
|
2456
2792
|
throw new ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
|
|
2457
2793
|
}
|
|
2458
|
-
await this.
|
|
2794
|
+
await this.loadMarketsAndSignIn();
|
|
2459
2795
|
const market = this.market(symbol);
|
|
2460
2796
|
const request = {
|
|
2461
2797
|
'symbol': market['id'],
|
|
2462
2798
|
};
|
|
2463
|
-
const clientOrderId = this.safeStringN(params, ['origClientOrderId', 'clientOrderId'
|
|
2799
|
+
const clientOrderId = this.safeStringN(params, ['origClientOrderId', 'clientOrderId']);
|
|
2464
2800
|
if (clientOrderId !== undefined) {
|
|
2465
2801
|
request['origClientOrderId'] = clientOrderId;
|
|
2466
2802
|
}
|
|
2467
2803
|
else {
|
|
2468
2804
|
request['orderId'] = id;
|
|
2469
2805
|
}
|
|
2470
|
-
params = this.omit(params, ['origClientOrderId', 'clientOrderId'
|
|
2806
|
+
params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
|
|
2471
2807
|
let response = undefined;
|
|
2472
2808
|
if (market['swap']) {
|
|
2473
|
-
response = await this.
|
|
2809
|
+
response = await this.fapiPrivateDeleteV3Order(this.extend(request, params));
|
|
2474
2810
|
}
|
|
2475
2811
|
else {
|
|
2476
|
-
response = await this.
|
|
2812
|
+
response = await this.sapiPrivateDeleteV3Order(this.extend(request, params));
|
|
2477
2813
|
}
|
|
2478
2814
|
return this.parseOrder(response, market);
|
|
2479
2815
|
}
|
|
@@ -2481,7 +2817,8 @@ export default class aster extends Exchange {
|
|
|
2481
2817
|
* @method
|
|
2482
2818
|
* @name aster#cancelOrders
|
|
2483
2819
|
* @description cancel multiple orders
|
|
2484
|
-
* @see https://github.
|
|
2820
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#cancel-all-open-orders-trade
|
|
2821
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#cancel-multiple-orders-trade
|
|
2485
2822
|
* @param {string[]} ids order ids
|
|
2486
2823
|
* @param {string} [symbol] unified market symbol
|
|
2487
2824
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -2495,11 +2832,8 @@ export default class aster extends Exchange {
|
|
|
2495
2832
|
if (symbol === undefined) {
|
|
2496
2833
|
throw new ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
|
|
2497
2834
|
}
|
|
2498
|
-
await this.
|
|
2835
|
+
await this.loadMarketsAndSignIn();
|
|
2499
2836
|
const market = this.market(symbol);
|
|
2500
|
-
if (market['spot']) {
|
|
2501
|
-
throw new NotSupported(this.id + ' cancelOrders() does not support ' + market['type'] + ' orders');
|
|
2502
|
-
}
|
|
2503
2837
|
const request = {
|
|
2504
2838
|
'symbol': market['id'],
|
|
2505
2839
|
};
|
|
@@ -2510,46 +2844,55 @@ export default class aster extends Exchange {
|
|
|
2510
2844
|
else {
|
|
2511
2845
|
request['orderIdList'] = ids;
|
|
2512
2846
|
}
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2847
|
+
let response = undefined;
|
|
2848
|
+
if (market['swap']) {
|
|
2849
|
+
response = await this.fapiPrivateDeleteV3BatchOrders(this.extend(request, params));
|
|
2850
|
+
//
|
|
2851
|
+
// [
|
|
2852
|
+
// {
|
|
2853
|
+
// "clientOrderId": "myOrder1",
|
|
2854
|
+
// "cumQty": "0",
|
|
2855
|
+
// "cumQuote": "0",
|
|
2856
|
+
// "executedQty": "0",
|
|
2857
|
+
// "orderId": 283194212,
|
|
2858
|
+
// "origQty": "11",
|
|
2859
|
+
// "origType": "TRAILING_STOP_MARKET",
|
|
2860
|
+
// "price": "0",
|
|
2861
|
+
// "reduceOnly": false,
|
|
2862
|
+
// "side": "BUY",
|
|
2863
|
+
// "positionSide": "SHORT",
|
|
2864
|
+
// "status": "CANCELED",
|
|
2865
|
+
// "stopPrice": "9300", // please ignore when order type is TRAILING_STOP_MARKET
|
|
2866
|
+
// "closePosition": false, // if Close-All
|
|
2867
|
+
// "symbol": "BTCUSDT",
|
|
2868
|
+
// "timeInForce": "GTC",
|
|
2869
|
+
// "type": "TRAILING_STOP_MARKET",
|
|
2870
|
+
// "activatePrice": "9020", // activation price, only return with TRAILING_STOP_MARKET order
|
|
2871
|
+
// "priceRate": "0.3", // callback rate, only return with TRAILING_STOP_MARKET order
|
|
2872
|
+
// "updateTime": 1571110484038,
|
|
2873
|
+
// "workingType": "CONTRACT_PRICE",
|
|
2874
|
+
// "priceProtect": false, // if conditional order trigger is protected
|
|
2875
|
+
// },
|
|
2876
|
+
// {
|
|
2877
|
+
// "code": -2011,
|
|
2878
|
+
// "msg": "Unknown order sent."
|
|
2879
|
+
// }
|
|
2880
|
+
// ]
|
|
2881
|
+
//
|
|
2882
|
+
}
|
|
2883
|
+
else {
|
|
2884
|
+
response = await this.sapiPrivateDeleteV3AllOpenOrders(this.extend(request, params));
|
|
2885
|
+
//
|
|
2886
|
+
// {"code": 200,"msg": "The operation of cancel all open order is done."}
|
|
2887
|
+
//
|
|
2888
|
+
}
|
|
2546
2889
|
return this.parseOrders(response, market);
|
|
2547
2890
|
}
|
|
2548
2891
|
/**
|
|
2549
2892
|
* @method
|
|
2550
2893
|
* @name aster#setLeverage
|
|
2551
2894
|
* @description set the level of leverage for a market
|
|
2552
|
-
* @see https://github.
|
|
2895
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#change-initial-leverage-trade
|
|
2553
2896
|
* @param {float} leverage the rate of leverage
|
|
2554
2897
|
* @param {string} symbol unified market symbol
|
|
2555
2898
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -2562,13 +2905,13 @@ export default class aster extends Exchange {
|
|
|
2562
2905
|
if ((leverage < 1) || (leverage > 125)) {
|
|
2563
2906
|
throw new BadRequest(this.id + ' leverage should be between 1 and 125');
|
|
2564
2907
|
}
|
|
2565
|
-
await this.
|
|
2908
|
+
await this.loadMarketsAndSignIn();
|
|
2566
2909
|
const market = this.market(symbol);
|
|
2567
2910
|
const request = {
|
|
2568
2911
|
'symbol': market['id'],
|
|
2569
2912
|
'leverage': leverage,
|
|
2570
2913
|
};
|
|
2571
|
-
const response = await this.
|
|
2914
|
+
const response = await this.fapiPrivatePostV3Leverage(this.extend(request, params));
|
|
2572
2915
|
//
|
|
2573
2916
|
// {
|
|
2574
2917
|
// "leverage": 21,
|
|
@@ -2582,14 +2925,14 @@ export default class aster extends Exchange {
|
|
|
2582
2925
|
* @method
|
|
2583
2926
|
* @name aster#fetchLeverages
|
|
2584
2927
|
* @description fetch the set leverage for all markets
|
|
2585
|
-
* @see https://github.
|
|
2928
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#position-information-v3-user_data
|
|
2586
2929
|
* @param {string[]} [symbols] a list of unified market symbols
|
|
2587
2930
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2588
2931
|
* @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure}
|
|
2589
2932
|
*/
|
|
2590
2933
|
async fetchLeverages(symbols = undefined, params = {}) {
|
|
2591
|
-
await this.
|
|
2592
|
-
const response = await this.
|
|
2934
|
+
await this.loadMarketsAndSignIn();
|
|
2935
|
+
const response = await this.fapiPrivateGetV3PositionRisk(params);
|
|
2593
2936
|
//
|
|
2594
2937
|
// [
|
|
2595
2938
|
// {
|
|
@@ -2661,14 +3004,14 @@ export default class aster extends Exchange {
|
|
|
2661
3004
|
* @method
|
|
2662
3005
|
* @name aster#fetchMarginModes
|
|
2663
3006
|
* @description fetches margin mode of the user
|
|
2664
|
-
* @see https://github.
|
|
3007
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#position-information-v3-user_data
|
|
2665
3008
|
* @param {string[]} symbols unified market symbols
|
|
2666
3009
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2667
3010
|
* @returns {object} a list of [margin mode structures]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
|
|
2668
3011
|
*/
|
|
2669
3012
|
async fetchMarginModes(symbols = undefined, params = {}) {
|
|
2670
|
-
await this.
|
|
2671
|
-
const response = await this.
|
|
3013
|
+
await this.loadMarketsAndSignIn();
|
|
3014
|
+
const response = await this.fapiPrivateGetV3PositionRisk(params);
|
|
2672
3015
|
//
|
|
2673
3016
|
//
|
|
2674
3017
|
// [
|
|
@@ -2726,7 +3069,7 @@ export default class aster extends Exchange {
|
|
|
2726
3069
|
* @method
|
|
2727
3070
|
* @name aster#fetchMarginAdjustmentHistory
|
|
2728
3071
|
* @description fetches the history of margin added or reduced from contract isolated positions
|
|
2729
|
-
* @see https://github.
|
|
3072
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#get-position-margin-change-history-trade
|
|
2730
3073
|
* @param {string} symbol unified market symbol
|
|
2731
3074
|
* @param {string} [type] "add" or "reduce"
|
|
2732
3075
|
* @param {int} [since] timestamp in ms of the earliest change to fetch
|
|
@@ -2736,10 +3079,10 @@ export default class aster extends Exchange {
|
|
|
2736
3079
|
* @returns {object[]} a list of [margin structures]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
|
|
2737
3080
|
*/
|
|
2738
3081
|
async fetchMarginAdjustmentHistory(symbol = undefined, type = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2739
|
-
await this.loadMarkets();
|
|
2740
3082
|
if (symbol === undefined) {
|
|
2741
3083
|
throw new ArgumentsRequired(this.id + ' fetchMarginAdjustmentHistory () requires a symbol argument');
|
|
2742
3084
|
}
|
|
3085
|
+
await this.loadMarketsAndSignIn();
|
|
2743
3086
|
const market = this.market(symbol);
|
|
2744
3087
|
const until = this.safeInteger(params, 'until');
|
|
2745
3088
|
params = this.omit(params, 'until');
|
|
@@ -2749,16 +3092,16 @@ export default class aster extends Exchange {
|
|
|
2749
3092
|
if (type !== undefined) {
|
|
2750
3093
|
request['type'] = (type === 'add') ? 1 : 2;
|
|
2751
3094
|
}
|
|
3095
|
+
if (limit !== undefined) {
|
|
3096
|
+
request['limit'] = Math.min(limit, 1000);
|
|
3097
|
+
}
|
|
2752
3098
|
if (since !== undefined) {
|
|
2753
3099
|
request['startTime'] = since;
|
|
2754
3100
|
}
|
|
2755
|
-
if (limit !== undefined) {
|
|
2756
|
-
request['limit'] = limit;
|
|
2757
|
-
}
|
|
2758
3101
|
if (until !== undefined) {
|
|
2759
3102
|
request['endTime'] = until;
|
|
2760
3103
|
}
|
|
2761
|
-
const response = await this.
|
|
3104
|
+
const response = await this.fapiPrivateGetV3PositionMarginHistory(this.extend(request, params));
|
|
2762
3105
|
//
|
|
2763
3106
|
// [
|
|
2764
3107
|
// {
|
|
@@ -2813,7 +3156,7 @@ export default class aster extends Exchange {
|
|
|
2813
3156
|
};
|
|
2814
3157
|
}
|
|
2815
3158
|
async modifyMarginHelper(symbol, amount, addOrReduce, params = {}) {
|
|
2816
|
-
await this.
|
|
3159
|
+
await this.loadMarketsAndSignIn();
|
|
2817
3160
|
const market = this.market(symbol);
|
|
2818
3161
|
amount = this.amountToPrecision(symbol, amount);
|
|
2819
3162
|
const request = {
|
|
@@ -2822,7 +3165,7 @@ export default class aster extends Exchange {
|
|
|
2822
3165
|
'amount': amount,
|
|
2823
3166
|
};
|
|
2824
3167
|
const code = market['quote'];
|
|
2825
|
-
const response = await this.
|
|
3168
|
+
const response = await this.fapiPrivatePostV3PositionMargin(this.extend(request, params));
|
|
2826
3169
|
//
|
|
2827
3170
|
// {
|
|
2828
3171
|
// "amount": 100.0,
|
|
@@ -2831,15 +3174,13 @@ export default class aster extends Exchange {
|
|
|
2831
3174
|
// "type": 1
|
|
2832
3175
|
// }
|
|
2833
3176
|
//
|
|
2834
|
-
return this.extend(this.parseMarginModification(response, market), {
|
|
2835
|
-
'code': code,
|
|
2836
|
-
});
|
|
3177
|
+
return this.extend(this.parseMarginModification(response, market), { 'code': code });
|
|
2837
3178
|
}
|
|
2838
3179
|
/**
|
|
2839
3180
|
* @method
|
|
2840
3181
|
* @name aster#reduceMargin
|
|
2841
3182
|
* @description remove margin from a position
|
|
2842
|
-
* @see https://github.
|
|
3183
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#modify-isolated-position-margin-trade
|
|
2843
3184
|
* @param {string} symbol unified market symbol
|
|
2844
3185
|
* @param {float} amount the amount of margin to remove
|
|
2845
3186
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -2852,7 +3193,7 @@ export default class aster extends Exchange {
|
|
|
2852
3193
|
* @method
|
|
2853
3194
|
* @name aster#addMargin
|
|
2854
3195
|
* @description add margin
|
|
2855
|
-
* @see https://github.
|
|
3196
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#modify-isolated-position-margin-trade
|
|
2856
3197
|
* @param {string} symbol unified market symbol
|
|
2857
3198
|
* @param {float} amount amount of margin to add
|
|
2858
3199
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -2891,7 +3232,7 @@ export default class aster extends Exchange {
|
|
|
2891
3232
|
* @method
|
|
2892
3233
|
* @name aster#fetchFundingHistory
|
|
2893
3234
|
* @description fetch the history of funding payments paid and received on this account
|
|
2894
|
-
* @see https://github.
|
|
3235
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#get-income-historyuser_data
|
|
2895
3236
|
* @param {string} symbol unified market symbol
|
|
2896
3237
|
* @param {int} [since] the earliest time in ms to fetch funding history for
|
|
2897
3238
|
* @param {int} [limit] the maximum number of funding history structures to retrieve
|
|
@@ -2902,7 +3243,7 @@ export default class aster extends Exchange {
|
|
|
2902
3243
|
* @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
|
|
2903
3244
|
*/
|
|
2904
3245
|
async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2905
|
-
await this.
|
|
3246
|
+
await this.loadMarketsAndSignIn();
|
|
2906
3247
|
let market = undefined;
|
|
2907
3248
|
let request = {
|
|
2908
3249
|
'incomeType': 'FUNDING_FEE', // "TRANSFER","WELCOME_BONUS", "REALIZED_PNL","FUNDING_FEE", "COMMISSION", "INSURANCE_CLEAR", and "MARKET_MERCHANT_RETURN_REWARD"
|
|
@@ -2918,7 +3259,7 @@ export default class aster extends Exchange {
|
|
|
2918
3259
|
if (limit !== undefined) {
|
|
2919
3260
|
request['limit'] = Math.min(limit, 1000); // max 1000
|
|
2920
3261
|
}
|
|
2921
|
-
const response = await this.
|
|
3262
|
+
const response = await this.fapiPrivateGetV3Income(this.extend(request, params));
|
|
2922
3263
|
return this.parseIncomes(response, market, since, limit);
|
|
2923
3264
|
}
|
|
2924
3265
|
parseLedgerEntry(item, currency = undefined) {
|
|
@@ -2982,7 +3323,7 @@ export default class aster extends Exchange {
|
|
|
2982
3323
|
* @method
|
|
2983
3324
|
* @name aster#fetchLedger
|
|
2984
3325
|
* @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
|
2985
|
-
* @see https://github.
|
|
3326
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#get-income-historyuser_data
|
|
2986
3327
|
* @param {string} [code] unified currency code
|
|
2987
3328
|
* @param {int} [since] timestamp in ms of the earliest ledger entry
|
|
2988
3329
|
* @param {int} [limit] max number of ledger entries to return
|
|
@@ -2991,7 +3332,7 @@ export default class aster extends Exchange {
|
|
|
2991
3332
|
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
|
|
2992
3333
|
*/
|
|
2993
3334
|
async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2994
|
-
await this.
|
|
3335
|
+
await this.loadMarketsAndSignIn();
|
|
2995
3336
|
let currency = undefined;
|
|
2996
3337
|
if (code !== undefined) {
|
|
2997
3338
|
currency = this.currency(code);
|
|
@@ -3008,7 +3349,7 @@ export default class aster extends Exchange {
|
|
|
3008
3349
|
params = this.omit(params, 'until');
|
|
3009
3350
|
request['endTime'] = until;
|
|
3010
3351
|
}
|
|
3011
|
-
const response = await this.
|
|
3352
|
+
const response = await this.fapiPrivateGetV3Income(this.extend(request, params));
|
|
3012
3353
|
//
|
|
3013
3354
|
// [
|
|
3014
3355
|
// {
|
|
@@ -3204,7 +3545,7 @@ export default class aster extends Exchange {
|
|
|
3204
3545
|
* @method
|
|
3205
3546
|
* @name aster#fetchPositionsRisk
|
|
3206
3547
|
* @description fetch positions risk
|
|
3207
|
-
* @see https://github.
|
|
3548
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#position-information-v3-user_data
|
|
3208
3549
|
* @param {string[]|undefined} symbols list of unified market symbols
|
|
3209
3550
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3210
3551
|
* @returns {object} data on the positions risk
|
|
@@ -3215,10 +3556,10 @@ export default class aster extends Exchange {
|
|
|
3215
3556
|
throw new ArgumentsRequired(this.id + ' fetchPositionsRisk() requires an array argument for symbols');
|
|
3216
3557
|
}
|
|
3217
3558
|
}
|
|
3218
|
-
await this.
|
|
3559
|
+
await this.loadMarketsAndSignIn();
|
|
3219
3560
|
await this.loadLeverageBrackets(false, params);
|
|
3220
3561
|
const request = {};
|
|
3221
|
-
const response = await this.
|
|
3562
|
+
const response = await this.fapiPrivateGetV3PositionRisk(this.extend(request, params));
|
|
3222
3563
|
//
|
|
3223
3564
|
// [
|
|
3224
3565
|
// {
|
|
@@ -3253,7 +3594,7 @@ export default class aster extends Exchange {
|
|
|
3253
3594
|
* @method
|
|
3254
3595
|
* @name aster#fetchPositions
|
|
3255
3596
|
* @description fetch all open positions
|
|
3256
|
-
* @see https://github.
|
|
3597
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#position-information-v3-user_data
|
|
3257
3598
|
* @param {string[]} [symbols] list of unified market symbols
|
|
3258
3599
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3259
3600
|
* @param {string} [params.method] method name to call, "positionRisk", "account" or "option", default is "positionRisk"
|
|
@@ -3490,7 +3831,7 @@ export default class aster extends Exchange {
|
|
|
3490
3831
|
* @name aster#fetchAccountPositions
|
|
3491
3832
|
* @ignore
|
|
3492
3833
|
* @description fetch account positions
|
|
3493
|
-
|
|
3834
|
+
https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#position-information-v3-user_data
|
|
3494
3835
|
* @param {string[]} [symbols] list of unified market symbols
|
|
3495
3836
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3496
3837
|
* @returns {object} data on account positions
|
|
@@ -3501,7 +3842,7 @@ export default class aster extends Exchange {
|
|
|
3501
3842
|
throw new ArgumentsRequired(this.id + ' fetchPositions() requires an array argument for symbols');
|
|
3502
3843
|
}
|
|
3503
3844
|
}
|
|
3504
|
-
await this.
|
|
3845
|
+
await this.loadMarketsAndSignIn();
|
|
3505
3846
|
await this.loadLeverageBrackets(false, params);
|
|
3506
3847
|
const response = await this.fapiPrivateGetV4Account(params);
|
|
3507
3848
|
let filterClosed = undefined;
|
|
@@ -3511,12 +3852,35 @@ export default class aster extends Exchange {
|
|
|
3511
3852
|
return this.filterByArrayPositions(result, 'symbol', symbols, false);
|
|
3512
3853
|
}
|
|
3513
3854
|
async loadLeverageBrackets(reload = false, params = {}) {
|
|
3514
|
-
await this.
|
|
3855
|
+
await this.loadMarketsAndSignIn();
|
|
3515
3856
|
// by default cache the leverage bracket
|
|
3516
3857
|
// it contains useful stuff like the maintenance margin and initial margin for positions
|
|
3517
3858
|
const leverageBrackets = this.safeDict(this.options, 'leverageBrackets');
|
|
3518
3859
|
if ((leverageBrackets === undefined) || (reload)) {
|
|
3519
|
-
const response = await this.
|
|
3860
|
+
const response = await this.fapiPrivateGetV3LeverageBracket(params);
|
|
3861
|
+
//
|
|
3862
|
+
// [
|
|
3863
|
+
// {
|
|
3864
|
+
// "symbol": "TRUTHUSDT",
|
|
3865
|
+
// "brackets": [
|
|
3866
|
+
// {
|
|
3867
|
+
// "bracket": "1",
|
|
3868
|
+
// "initialLeverage": "50",
|
|
3869
|
+
// "notionalCap": "5000",
|
|
3870
|
+
// "notionalFloor": "0",
|
|
3871
|
+
// "maintMarginRatio": "0.01",
|
|
3872
|
+
// "cum": "0.0"
|
|
3873
|
+
// },
|
|
3874
|
+
// {
|
|
3875
|
+
// "bracket": "2",
|
|
3876
|
+
// "initialLeverage": "20",
|
|
3877
|
+
// "notionalCap": "10000",
|
|
3878
|
+
// "notionalFloor": "5000",
|
|
3879
|
+
// "maintMarginRatio": "0.025",
|
|
3880
|
+
// "cum": "75.0"
|
|
3881
|
+
// },
|
|
3882
|
+
// ...
|
|
3883
|
+
//
|
|
3520
3884
|
this.options['leverageBrackets'] = this.createSafeDictionary();
|
|
3521
3885
|
for (let i = 0; i < response.length; i++) {
|
|
3522
3886
|
const entry = response[i];
|
|
@@ -3542,12 +3906,11 @@ export default class aster extends Exchange {
|
|
|
3542
3906
|
return this.signHash(this.keccakMessage(message), privateKey.slice(-64));
|
|
3543
3907
|
}
|
|
3544
3908
|
signWithdrawPayload(withdrawPayload, network) {
|
|
3545
|
-
const zeroAddress = this.safeString(this.options, 'zeroAddress');
|
|
3546
3909
|
const chainId = this.safeInteger(withdrawPayload, 'chainId');
|
|
3547
3910
|
const domain = {
|
|
3548
3911
|
'chainId': chainId,
|
|
3549
3912
|
'name': 'Aster',
|
|
3550
|
-
'verifyingContract': zeroAddress,
|
|
3913
|
+
'verifyingContract': this.safeString(this.options, 'zeroAddress'),
|
|
3551
3914
|
'version': '1',
|
|
3552
3915
|
};
|
|
3553
3916
|
const messageTypes = {
|
|
@@ -3562,17 +3925,17 @@ export default class aster extends Exchange {
|
|
|
3562
3925
|
{ 'name': 'aster chain', 'type': 'string' },
|
|
3563
3926
|
],
|
|
3564
3927
|
};
|
|
3565
|
-
const
|
|
3928
|
+
const request = {
|
|
3566
3929
|
'type': 'Withdraw',
|
|
3567
3930
|
'destination': this.safeString(withdrawPayload, 'receiver'),
|
|
3568
3931
|
'destination Chain': network,
|
|
3569
3932
|
'token': this.safeString(withdrawPayload, 'asset'),
|
|
3570
3933
|
'amount': this.safeString(withdrawPayload, 'amount'),
|
|
3571
3934
|
'fee': this.safeString(withdrawPayload, 'fee'),
|
|
3572
|
-
'nonce': this.safeInteger(withdrawPayload, '
|
|
3935
|
+
'nonce': this.safeInteger(withdrawPayload, 'userNonce'),
|
|
3573
3936
|
'aster chain': 'Mainnet',
|
|
3574
3937
|
};
|
|
3575
|
-
const msg = this.ethEncodeStructuredData(domain, messageTypes,
|
|
3938
|
+
const msg = this.ethEncodeStructuredData(domain, messageTypes, request);
|
|
3576
3939
|
const signature = this.signMessage(msg, this.privateKey);
|
|
3577
3940
|
return signature;
|
|
3578
3941
|
}
|
|
@@ -3580,7 +3943,9 @@ export default class aster extends Exchange {
|
|
|
3580
3943
|
* @method
|
|
3581
3944
|
* @name aster#withdraw
|
|
3582
3945
|
* @description make a withdrawal
|
|
3583
|
-
* @see https://github.
|
|
3946
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#withdraw-user_data
|
|
3947
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/deposit%26withdrawal/#withdraw-by-fapiv3-evm-futures
|
|
3948
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/deposit%26withdrawal/#withdraw-by-fapiv3-evm-spot
|
|
3584
3949
|
* @param {string} code unified currency code
|
|
3585
3950
|
* @param {float} amount the amount to withdraw
|
|
3586
3951
|
* @param {string} address the address to withdraw to
|
|
@@ -3591,12 +3956,13 @@ export default class aster extends Exchange {
|
|
|
3591
3956
|
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
3592
3957
|
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
3593
3958
|
this.checkAddress(address);
|
|
3594
|
-
await this.
|
|
3959
|
+
await this.loadMarketsAndSignIn();
|
|
3595
3960
|
const currency = this.currency(code);
|
|
3961
|
+
const nonce = this.milliseconds() * 1000;
|
|
3596
3962
|
const request = {
|
|
3597
3963
|
'asset': currency['id'],
|
|
3598
3964
|
'receiver': address,
|
|
3599
|
-
'
|
|
3965
|
+
'userNonce': nonce.toString(),
|
|
3600
3966
|
};
|
|
3601
3967
|
let chainId = this.safeInteger(params, 'chainId');
|
|
3602
3968
|
// TODO: check how ARBI signature would work
|
|
@@ -3619,23 +3985,32 @@ export default class aster extends Exchange {
|
|
|
3619
3985
|
params = this.omit(params, ['chainId', 'network', 'fee']);
|
|
3620
3986
|
request['amount'] = this.currencyToPrecision(code, amount, network);
|
|
3621
3987
|
request['userSignature'] = this.signWithdrawPayload(request, network);
|
|
3622
|
-
const response = await this.
|
|
3988
|
+
const response = await this.sapiPrivatePostV3AsterUserWithdraw(this.extend(request, params));
|
|
3989
|
+
//
|
|
3990
|
+
// {
|
|
3991
|
+
// "withdrawId": "1097219372504338432",
|
|
3992
|
+
// "hash": "0x9e6baa3eb75d92a1164eef51a0cc97b9591930518ba3e8e5ab40ce524ba4e463"
|
|
3993
|
+
// }
|
|
3994
|
+
//
|
|
3995
|
+
return this.parseTransaction(response, currency);
|
|
3996
|
+
}
|
|
3997
|
+
parseTransaction(transaction, currency = undefined) {
|
|
3623
3998
|
return {
|
|
3624
|
-
'info':
|
|
3625
|
-
'id': this.safeString(
|
|
3626
|
-
'txid': this.safeString(
|
|
3999
|
+
'info': transaction,
|
|
4000
|
+
'id': this.safeString(transaction, 'withdrawId'),
|
|
4001
|
+
'txid': this.safeString(transaction, 'hash'),
|
|
3627
4002
|
'timestamp': undefined,
|
|
3628
4003
|
'datetime': undefined,
|
|
3629
|
-
'network':
|
|
3630
|
-
'address':
|
|
3631
|
-
'addressTo':
|
|
4004
|
+
'network': undefined,
|
|
4005
|
+
'address': undefined,
|
|
4006
|
+
'addressTo': undefined,
|
|
3632
4007
|
'addressFrom': undefined,
|
|
3633
|
-
'tag':
|
|
3634
|
-
'tagTo':
|
|
4008
|
+
'tag': undefined,
|
|
4009
|
+
'tagTo': undefined,
|
|
3635
4010
|
'tagFrom': undefined,
|
|
3636
4011
|
'type': 'withdrawal',
|
|
3637
|
-
'amount':
|
|
3638
|
-
'currency':
|
|
4012
|
+
'amount': undefined,
|
|
4013
|
+
'currency': undefined,
|
|
3639
4014
|
'status': undefined,
|
|
3640
4015
|
'updated': undefined,
|
|
3641
4016
|
'internal': undefined,
|
|
@@ -3647,8 +4022,8 @@ export default class aster extends Exchange {
|
|
|
3647
4022
|
* @method
|
|
3648
4023
|
* @name aster#transfer
|
|
3649
4024
|
* @description transfer currency internally between wallets on the same account
|
|
3650
|
-
* @see https://github.
|
|
3651
|
-
* @see https://github.
|
|
4025
|
+
* @see https://asterdex.github.io/aster-api-website/spot-v3/account%26trades/#perp-spot-transfer-trade
|
|
4026
|
+
* @see https://asterdex.github.io/aster-api-website/futures-v3/account%26trades/#transfer-between-futures-and-spot-transfer
|
|
3652
4027
|
* @param {string} code unified currency code
|
|
3653
4028
|
* @param {float} amount amount to transfer
|
|
3654
4029
|
* @param {string} fromAccount account to transfer from
|
|
@@ -3657,7 +4032,7 @@ export default class aster extends Exchange {
|
|
|
3657
4032
|
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
3658
4033
|
*/
|
|
3659
4034
|
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
3660
|
-
await this.
|
|
4035
|
+
await this.loadMarketsAndSignIn();
|
|
3661
4036
|
const currency = this.currency(code);
|
|
3662
4037
|
const request = {
|
|
3663
4038
|
'asset': currency['id'],
|
|
@@ -3678,47 +4053,36 @@ export default class aster extends Exchange {
|
|
|
3678
4053
|
else if (fromId === 'FUTURE' && toId === 'SPOT') {
|
|
3679
4054
|
type = 'FUTURE_SPOT';
|
|
3680
4055
|
}
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
const defaultClientTranId = this.numberToString(this.milliseconds());
|
|
3684
|
-
const clientTranId = this.safeString(params, 'clientTranId', defaultClientTranId);
|
|
3685
|
-
request['kindType'] = type;
|
|
3686
|
-
request['clientTranId'] = clientTranId;
|
|
3687
|
-
response = await this.fapiPrivatePostV1AssetWalletTransfer(this.extend(request, params));
|
|
3688
|
-
}
|
|
3689
|
-
else {
|
|
3690
|
-
// transfer asset to other address
|
|
3691
|
-
request['toAddress'] = toAccount;
|
|
3692
|
-
response = await this.sapiPrivatePostV1AssetSendToAddress(this.extend(request, params));
|
|
4056
|
+
if (type === undefined) {
|
|
4057
|
+
throw new ArgumentsRequired(this.id + ' transfer() requires fromAccount and toAccount parameters to be either SPOT or FUTURE');
|
|
3693
4058
|
}
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
4059
|
+
let response = undefined;
|
|
4060
|
+
const defaultClientTranId = this.numberToString(this.milliseconds());
|
|
4061
|
+
const clientTranId = this.safeString(params, 'clientTranId', defaultClientTranId);
|
|
4062
|
+
request['kindType'] = type;
|
|
4063
|
+
request['clientTranId'] = clientTranId;
|
|
4064
|
+
response = await this.sapiPrivatePostV3AssetWalletTransfer(this.extend(request, params));
|
|
4065
|
+
return this.parseTransfer(response, currency);
|
|
4066
|
+
}
|
|
4067
|
+
parseTransfer(transfer, currency = undefined) {
|
|
4068
|
+
const currencyId = this.safeString(transfer, 'code');
|
|
3700
4069
|
return {
|
|
3701
|
-
'info':
|
|
3702
|
-
'id': this.safeString(
|
|
3703
|
-
'txid': undefined,
|
|
4070
|
+
'info': transfer,
|
|
4071
|
+
'id': this.safeString(transfer, 'tranId'),
|
|
3704
4072
|
'timestamp': undefined,
|
|
3705
4073
|
'datetime': undefined,
|
|
3706
|
-
'
|
|
3707
|
-
'
|
|
3708
|
-
'
|
|
3709
|
-
'
|
|
3710
|
-
'
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
'
|
|
3716
|
-
'status': undefined,
|
|
3717
|
-
'updated': undefined,
|
|
3718
|
-
'internal': undefined,
|
|
3719
|
-
'comment': undefined,
|
|
3720
|
-
'fee': undefined,
|
|
4074
|
+
'currency': this.safeCurrencyCode(currencyId, currency),
|
|
4075
|
+
'amount': undefined,
|
|
4076
|
+
'fromAccount': undefined,
|
|
4077
|
+
'toAccount': undefined,
|
|
4078
|
+
'status': this.parseTransferStatus(this.safeString(transfer, 'status')),
|
|
4079
|
+
};
|
|
4080
|
+
}
|
|
4081
|
+
parseTransferStatus(status) {
|
|
4082
|
+
const statuses = {
|
|
4083
|
+
'SUCCESS': 'ok',
|
|
3721
4084
|
};
|
|
4085
|
+
return this.safeString(statuses, status, status);
|
|
3722
4086
|
}
|
|
3723
4087
|
hashMessage(binaryMessage) {
|
|
3724
4088
|
// const binaryMessage = this.encode (message);
|
|
@@ -3745,78 +4109,174 @@ export default class aster extends Exchange {
|
|
|
3745
4109
|
}
|
|
3746
4110
|
else if (api === 'fapiPrivate' || api === 'sapiPrivate') {
|
|
3747
4111
|
this.checkRequiredCredentials();
|
|
3748
|
-
|
|
3749
|
-
|
|
4112
|
+
const nonce = this.milliseconds() * 1000;
|
|
4113
|
+
// Sign using EIP-712 typed data per the AsterSignTransaction spec
|
|
4114
|
+
const zeroAddress = this.safeString(this.options, 'zeroAddress', '0x0000000000000000000000000000000000000000');
|
|
4115
|
+
const v3ChainId = this.safeInteger(this.options, 'v3ChainId', 1666);
|
|
4116
|
+
const signerAddress = this.safeString(this.options, 'signerAddress');
|
|
4117
|
+
if (signerAddress === undefined) {
|
|
4118
|
+
throw new ArgumentsRequired(this.id + ' requires signerAddress in options when use v3 api');
|
|
4119
|
+
}
|
|
4120
|
+
const domain = {
|
|
4121
|
+
'name': 'AsterSignTransaction',
|
|
4122
|
+
'version': '1',
|
|
4123
|
+
'chainId': v3ChainId,
|
|
4124
|
+
'verifyingContract': zeroAddress,
|
|
3750
4125
|
};
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
4126
|
+
let messageTypes = {
|
|
4127
|
+
'Message': [
|
|
4128
|
+
{ 'name': 'msg', 'type': 'string' },
|
|
4129
|
+
],
|
|
4130
|
+
};
|
|
4131
|
+
// Build v3 params: original endpoint params + nonce (macroseconds) + user + signer
|
|
4132
|
+
// Note: timestamp and recvWindow are not used for v3; nonce replaces timestamp
|
|
4133
|
+
const finalParams = this.extend({
|
|
4134
|
+
'nonce': nonce.toString(),
|
|
4135
|
+
'user': this.walletAddress,
|
|
4136
|
+
'signer': signerAddress,
|
|
3757
4137
|
}, params);
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
if (origclientorderidlistLength > 0) {
|
|
3777
|
-
query = query + '&' + 'origclientorderidlist=%5B' + origclientorderidlist.join('%2C') + '%5D';
|
|
3778
|
-
}
|
|
3779
|
-
}
|
|
3780
|
-
else {
|
|
3781
|
-
query = this.rawencode(extendedParams);
|
|
3782
|
-
}
|
|
3783
|
-
let signature = '';
|
|
3784
|
-
if (path.indexOf('v3') >= 0) {
|
|
3785
|
-
const signerAddress = this.options['signerAddress'];
|
|
3786
|
-
if (signerAddress === undefined) {
|
|
3787
|
-
throw new ArgumentsRequired(this.id + ' requires signerAddress in options when use v3 api');
|
|
3788
|
-
}
|
|
3789
|
-
// the keys order matter
|
|
3790
|
-
const keys = Object.keys(extendedParams);
|
|
3791
|
-
const sortedKeys = this.sort(keys);
|
|
3792
|
-
const signingPayload = {};
|
|
3793
|
-
for (let i = 0; i < sortedKeys.length; i++) {
|
|
3794
|
-
const key = sortedKeys[i];
|
|
3795
|
-
signingPayload[key] = extendedParams[key].toString();
|
|
3796
|
-
}
|
|
3797
|
-
const signingHash = this.hashMessage(this.hash(this.ethAbiEncode([
|
|
3798
|
-
'string', 'address', 'address', 'uint256',
|
|
3799
|
-
], [this.json(signingPayload), this.walletAddress, signerAddress, nonce]), keccak, 'binary'));
|
|
3800
|
-
signature = this.signHash(signingHash, this.privateKey);
|
|
3801
|
-
extendedParams['user'] = this.walletAddress;
|
|
3802
|
-
extendedParams['signer'] = signerAddress;
|
|
3803
|
-
extendedParams['nonce'] = nonce;
|
|
3804
|
-
query = this.rawencode(extendedParams);
|
|
4138
|
+
let paramString = undefined;
|
|
4139
|
+
let paramsToEncode = undefined;
|
|
4140
|
+
const isApproveBuilder = (path.indexOf('/approveBuilder') >= 0);
|
|
4141
|
+
if (isApproveBuilder) {
|
|
4142
|
+
// domain['name'] = 'Aster';
|
|
4143
|
+
messageTypes = {
|
|
4144
|
+
'ApproveBuilder': [
|
|
4145
|
+
{ 'name': 'Builder', 'type': 'string' },
|
|
4146
|
+
{ 'name': 'MaxFeeRate', 'type': 'string' },
|
|
4147
|
+
{ 'name': 'BuilderName', 'type': 'string' },
|
|
4148
|
+
{ 'name': 'AsterChain', 'type': 'string' },
|
|
4149
|
+
{ 'name': 'User', 'type': 'string' },
|
|
4150
|
+
{ 'name': 'Nonce', 'type': 'uint256' },
|
|
4151
|
+
],
|
|
4152
|
+
};
|
|
4153
|
+
delete finalParams['signer']; // signer is not needed for approveBuilder endpoint
|
|
4154
|
+
paramString = this.encodeValuesWithJson(finalParams);
|
|
4155
|
+
paramsToEncode = this.capitalizeKeys(finalParams);
|
|
3805
4156
|
}
|
|
3806
4157
|
else {
|
|
3807
|
-
|
|
4158
|
+
paramString = this.encodeValuesWithJson(finalParams);
|
|
4159
|
+
paramsToEncode = { 'msg': paramString };
|
|
3808
4160
|
}
|
|
3809
|
-
|
|
4161
|
+
const encodedMessage = this.ethEncodeStructuredData(domain, messageTypes, paramsToEncode);
|
|
4162
|
+
const signature = this.signMessage(encodedMessage, this.privateKey);
|
|
4163
|
+
const queryString = paramString + '&' + 'signature=' + signature;
|
|
3810
4164
|
if (method === 'GET') {
|
|
3811
|
-
url += '?' +
|
|
4165
|
+
url += '?' + queryString;
|
|
3812
4166
|
}
|
|
3813
4167
|
else {
|
|
3814
|
-
|
|
4168
|
+
headers = {};
|
|
3815
4169
|
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
4170
|
+
body = queryString;
|
|
3816
4171
|
}
|
|
3817
4172
|
}
|
|
3818
4173
|
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
3819
4174
|
}
|
|
4175
|
+
encodeValuesWithJson(values) {
|
|
4176
|
+
let encodedString = '';
|
|
4177
|
+
const keys = Object.keys(values);
|
|
4178
|
+
for (let i = 0; i < keys.length; i++) {
|
|
4179
|
+
const key = keys[i];
|
|
4180
|
+
const value = values[key];
|
|
4181
|
+
const isObj = Array.isArray(value) || this.isDictionary(value);
|
|
4182
|
+
const valueJsonified = isObj ? this.json(value) : value.toString();
|
|
4183
|
+
const encoded = this.encodeURIComponent(valueJsonified);
|
|
4184
|
+
encodedString += key + '=' + encoded + '&';
|
|
4185
|
+
}
|
|
4186
|
+
return encodedString.slice(0, -1);
|
|
4187
|
+
}
|
|
4188
|
+
capitalizeKeys(dict) {
|
|
4189
|
+
const capitalized = {};
|
|
4190
|
+
const keys = Object.keys(dict);
|
|
4191
|
+
for (let i = 0; i < keys.length; i++) {
|
|
4192
|
+
const key = keys[i];
|
|
4193
|
+
const value = dict[key];
|
|
4194
|
+
const capitalizedKey = this.capitalize(key);
|
|
4195
|
+
capitalized[capitalizedKey] = value;
|
|
4196
|
+
}
|
|
4197
|
+
return capitalized;
|
|
4198
|
+
}
|
|
4199
|
+
async loadMarketsAndSignIn() {
|
|
4200
|
+
await Promise.all([this.loadMarkets(), this.signIn()]);
|
|
4201
|
+
}
|
|
4202
|
+
/**
|
|
4203
|
+
* @method
|
|
4204
|
+
* @name aster#signIn
|
|
4205
|
+
* @description sign in, must be called prior to using other authenticated methods
|
|
4206
|
+
* @see https://asterdex.github.io/aster-api-website/asterCode/integration-flow/
|
|
4207
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
4208
|
+
* @returns response from exchange
|
|
4209
|
+
*/
|
|
4210
|
+
async signIn(params = {}) {
|
|
4211
|
+
if (this.isEmptyString(this.privateKey)) {
|
|
4212
|
+
if (!this.isEmptyString(this.apiKey) || !this.isEmptyString(this.secret)) {
|
|
4213
|
+
throw new NotSupported(this.id + 'after the latest upgrade (v4.5.52), CCXT now expects the l1 private key to be provided in the credentials.');
|
|
4214
|
+
}
|
|
4215
|
+
return false;
|
|
4216
|
+
}
|
|
4217
|
+
if (this.privateKey.length > 66) {
|
|
4218
|
+
throw new NotSupported(this.id + ' after the latest update (v4.5.52), CCXT now expects the l1 private key to be provided in the credentials.');
|
|
4219
|
+
}
|
|
4220
|
+
await this.initializeClient(params);
|
|
4221
|
+
return true;
|
|
4222
|
+
}
|
|
4223
|
+
async initializeClient(params = {}) {
|
|
4224
|
+
const builderFee = this.safeBool(params, 'builderFee', this.safeBool(this.options, 'builderFee', true)); // we shouldn't omit here
|
|
4225
|
+
if (!builderFee) {
|
|
4226
|
+
return false; // skip if builder fee is not enabled
|
|
4227
|
+
}
|
|
4228
|
+
const approvedBuilderFee = this.safeBool(this.options, 'approvedBuilderFee', false);
|
|
4229
|
+
if (approvedBuilderFee) {
|
|
4230
|
+
return true; // skip if builder fee is already approved
|
|
4231
|
+
}
|
|
4232
|
+
const result = await this.fapiPrivateGetV3Builder();
|
|
4233
|
+
//
|
|
4234
|
+
// [
|
|
4235
|
+
// {
|
|
4236
|
+
// "userAddress": "0x35a5B33Be664B09F78b5089eb6185f71c8a7f11f",
|
|
4237
|
+
// "builderAddress": "0x1F5877C19e3777Cfd15F9d57253eA4aA5254Ec39",
|
|
4238
|
+
// "maxFeeRate": "0.001",
|
|
4239
|
+
// "builderName": "ccxt"
|
|
4240
|
+
// }
|
|
4241
|
+
// ]
|
|
4242
|
+
//
|
|
4243
|
+
const approvedBuilders = result;
|
|
4244
|
+
const length = approvedBuilders.length;
|
|
4245
|
+
let found = false;
|
|
4246
|
+
for (let i = 0; i < length; i++) {
|
|
4247
|
+
const builderInfo = this.safeDict(approvedBuilders, i, {});
|
|
4248
|
+
const builderAccountId = this.safeString(builderInfo, 'builderAddress');
|
|
4249
|
+
if (builderAccountId === this.safeString(this.options, 'builder')) {
|
|
4250
|
+
found = true;
|
|
4251
|
+
break;
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
if (!found) {
|
|
4255
|
+
this.options['approvedBuilderFee'] = true;
|
|
4256
|
+
try {
|
|
4257
|
+
const request = {
|
|
4258
|
+
'builder': this.safeString(this.options, 'builder'),
|
|
4259
|
+
'builderName': this.safeString(this.options, 'builderName', 'ccxt'),
|
|
4260
|
+
'maxFeeRate': this.safeString(this.options, 'builderRate'),
|
|
4261
|
+
'signatureChainId': this.safeInteger(this.options, 'v3ChainId', 1666),
|
|
4262
|
+
'asterChain': 'Mainnet',
|
|
4263
|
+
};
|
|
4264
|
+
const authResponse = await this.fapiPrivatePostV3ApproveBuilder(this.extend(request, params));
|
|
4265
|
+
//
|
|
4266
|
+
// {"code": 200,"msg": "success"}
|
|
4267
|
+
//
|
|
4268
|
+
const codeRes = this.safeInteger(authResponse, 'code');
|
|
4269
|
+
if (codeRes !== 200) {
|
|
4270
|
+
throw new ExchangeError('Builder authorization failed, ' + this.json(authResponse));
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
catch (e) {
|
|
4274
|
+
this.options['approvedBuilderFee'] = false;
|
|
4275
|
+
this.options['builderFee'] = false; // disable if err
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
return undefined; // just c#
|
|
4279
|
+
}
|
|
3820
4280
|
handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
3821
4281
|
if (response === undefined) {
|
|
3822
4282
|
return undefined; // fallback to default error handler
|