ccxt 4.4.64 → 4.4.65

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.
@@ -1,2123 +0,0 @@
1
- // ----------------------------------------------------------------------------
2
-
3
- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
- // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
-
7
- // ---------------------------------------------------------------------------
8
- import Exchange from './abstract/currencycom.js';
9
- import { BadSymbol, ExchangeError, ArgumentsRequired, ExchangeNotAvailable, InsufficientFunds, OrderNotFound, InvalidOrder, DDoSProtection, InvalidNonce, AuthenticationError, BadRequest, NotSupported } from './base/errors.js';
10
- import { Precise } from './base/Precise.js';
11
- import { TICK_SIZE } from './base/functions/number.js';
12
- import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
13
- // ---------------------------------------------------------------------------
14
- /**
15
- * @class currencycom
16
- * @augments Exchange
17
- */
18
- export default class currencycom extends Exchange {
19
- describe() {
20
- return this.deepExtend(super.describe(), {
21
- 'id': 'currencycom',
22
- 'name': 'Currency.com',
23
- 'countries': ['BY'],
24
- 'rateLimit': 100,
25
- 'certified': false,
26
- 'pro': true,
27
- 'version': 'v2',
28
- // new metainfo interface
29
- 'has': {
30
- 'CORS': undefined,
31
- 'spot': true,
32
- 'margin': true,
33
- 'swap': true,
34
- 'future': false,
35
- 'option': false,
36
- 'addMargin': undefined,
37
- 'cancelAllOrders': undefined,
38
- 'cancelOrder': true,
39
- 'cancelOrders': undefined,
40
- 'createDepositAddress': undefined,
41
- 'createLimitOrder': true,
42
- 'createMarketOrder': true,
43
- 'createOrder': true,
44
- 'createStopLimitOrder': true,
45
- 'createStopMarketOrder': true,
46
- 'createStopOrder': true,
47
- 'editOrder': 'emulated',
48
- 'fetchAccounts': true,
49
- 'fetchBalance': true,
50
- 'fetchBidsAsks': undefined,
51
- 'fetchBorrowRateHistory': undefined,
52
- 'fetchCanceledOrders': undefined,
53
- 'fetchClosedOrder': undefined,
54
- 'fetchClosedOrders': undefined,
55
- 'fetchCrossBorrowRate': false,
56
- 'fetchCrossBorrowRates': false,
57
- 'fetchCurrencies': true,
58
- 'fetchDeposit': undefined,
59
- 'fetchDepositAddress': true,
60
- 'fetchDepositAddresses': false,
61
- 'fetchDepositAddressesByNetwork': false,
62
- 'fetchDeposits': true,
63
- 'fetchDepositsWithdrawals': true,
64
- 'fetchFundingHistory': false,
65
- 'fetchFundingRate': false,
66
- 'fetchFundingRateHistory': false,
67
- 'fetchFundingRates': false,
68
- 'fetchIndexOHLCV': false,
69
- 'fetchIsolatedBorrowRate': false,
70
- 'fetchIsolatedBorrowRates': false,
71
- 'fetchL2OrderBook': true,
72
- 'fetchLedger': true,
73
- 'fetchLedgerEntry': false,
74
- 'fetchLeverage': true,
75
- 'fetchLeverageTiers': false,
76
- 'fetchMarginMode': false,
77
- 'fetchMarkets': true,
78
- 'fetchMarkOHLCV': false,
79
- 'fetchMyTrades': true,
80
- 'fetchOHLCV': true,
81
- 'fetchOpenOrder': undefined,
82
- 'fetchOpenOrders': true,
83
- 'fetchOrder': true,
84
- 'fetchOrderBook': true,
85
- 'fetchOrderBooks': undefined,
86
- 'fetchOrders': undefined,
87
- 'fetchOrderTrades': undefined,
88
- 'fetchPosition': undefined,
89
- 'fetchPositionMode': false,
90
- 'fetchPositions': true,
91
- 'fetchPositionsRisk': undefined,
92
- 'fetchPremiumIndexOHLCV': false,
93
- 'fetchTicker': true,
94
- 'fetchTickers': true,
95
- 'fetchTime': true,
96
- 'fetchTrades': true,
97
- 'fetchTradingFee': false,
98
- 'fetchTradingFees': true,
99
- 'fetchTradingLimits': undefined,
100
- 'fetchTransactionFee': undefined,
101
- 'fetchTransactionFees': undefined,
102
- 'fetchTransactions': 'emulated',
103
- 'fetchTransfers': undefined,
104
- 'fetchWithdrawal': undefined,
105
- 'fetchWithdrawals': true,
106
- 'reduceMargin': undefined,
107
- 'sandbox': true,
108
- 'setLeverage': undefined,
109
- 'setMarginMode': undefined,
110
- 'setPositionMode': undefined,
111
- 'signIn': undefined,
112
- 'transfer': undefined,
113
- 'withdraw': undefined,
114
- },
115
- 'timeframes': {
116
- '1m': '1m',
117
- '5m': '5m',
118
- '10m': '10m',
119
- '15m': '15m',
120
- '30m': '30m',
121
- '1h': '1h',
122
- '4h': '4h',
123
- '1d': '1d',
124
- '1w': '1w',
125
- },
126
- 'hostname': 'backend.currency.com',
127
- 'urls': {
128
- 'logo': 'https://user-images.githubusercontent.com/1294454/83718672-36745c00-a63e-11ea-81a9-677b1f789a4d.jpg',
129
- 'api': {
130
- 'public': 'https://api-adapter.{hostname}/api',
131
- 'private': 'https://api-adapter.{hostname}/api',
132
- 'marketcap': 'https://marketcap.{hostname}/api',
133
- },
134
- 'test': {
135
- 'public': 'https://demo-api-adapter.{hostname}/api',
136
- 'private': 'https://demo-api-adapter.{hostname}/api',
137
- },
138
- 'www': 'https://www.currency.com',
139
- 'referral': 'https://currency.com/trading/signup?c=362jaimv&pid=referral',
140
- 'doc': [
141
- 'https://currency.com/api',
142
- ],
143
- 'fees': 'https://currency.com/fees-charges',
144
- },
145
- // rate-limits are described at: https://currency.com/api-get-started
146
- 'api': {
147
- 'public': {
148
- 'get': {
149
- 'v1/time': 1,
150
- 'v1/exchangeInfo': 1,
151
- 'v1/depth': 1,
152
- 'v1/aggTrades': 1,
153
- 'v1/klines': 1,
154
- 'v1/ticker/24hr': 1,
155
- 'v2/time': 1,
156
- 'v2/exchangeInfo': 1,
157
- 'v2/depth': 1,
158
- 'v2/aggTrades': 1,
159
- 'v2/klines': 1,
160
- 'v2/ticker/24hr': 1,
161
- },
162
- },
163
- 'marketcap': {
164
- 'get': {
165
- 'v1/assets': 1,
166
- 'v1/candles': 1,
167
- 'v1/orderbook': 1,
168
- 'v1/summary': 1,
169
- 'v1/ticker': 1,
170
- 'v1/token/assets': 1,
171
- 'v1/token/orderbook': 1,
172
- 'v1/token/summary': 1,
173
- 'v1/token/ticker': 1,
174
- 'v1/token/trades': 1,
175
- 'v1/token_crypto/OHLC': 1,
176
- 'v1/token_crypto/assets': 1,
177
- 'v1/token_crypto/orderbook': 1,
178
- 'v1/token_crypto/summary': 1,
179
- 'v1/token_crypto/ticker': 1,
180
- 'v1/token_crypto/trades': 1,
181
- 'v1/trades': 1,
182
- },
183
- },
184
- 'private': {
185
- 'get': {
186
- 'v1/account': 1,
187
- 'v1/currencies': 1,
188
- 'v1/deposits': 1,
189
- 'v1/depositAddress': 1,
190
- 'v1/ledger': 1,
191
- 'v1/leverageSettings': 1,
192
- 'v1/myTrades': 1,
193
- 'v1/openOrders': 1,
194
- 'v1/tradingPositions': 1,
195
- 'v1/tradingPositionsHistory': 1,
196
- 'v1/transactions': 1,
197
- 'v1/withdrawals': 1,
198
- 'v2/account': 1,
199
- 'v2/currencies': 1,
200
- 'v2/deposits': 1,
201
- 'v2/depositAddress': 1,
202
- 'v2/ledger': 1,
203
- 'v2/leverageSettings': 1,
204
- 'v2/myTrades': 1,
205
- 'v2/openOrders': 1,
206
- 'v2/tradingPositions': 1,
207
- 'v2/tradingPositionsHistory': 1,
208
- 'v2/transactions': 1,
209
- 'v2/withdrawals': 1,
210
- 'v2/fetchOrder': 1,
211
- },
212
- 'post': {
213
- 'v1/order': 1,
214
- 'v1/updateTradingPosition': 1,
215
- 'v1/updateTradingOrder': 1,
216
- 'v1/closeTradingPosition': 1,
217
- 'v2/order': 1,
218
- 'v2/updateTradingPosition': 1,
219
- 'v2/updateTradingOrder': 1,
220
- 'v2/closeTradingPosition': 1,
221
- },
222
- 'delete': {
223
- 'v1/order': 1,
224
- 'v2/order': 1,
225
- },
226
- },
227
- },
228
- 'fees': {
229
- 'trading': {
230
- 'feeSide': 'get',
231
- 'tierBased': false,
232
- 'percentage': true,
233
- 'taker': this.parseNumber('0.002'),
234
- 'maker': this.parseNumber('0.002'),
235
- },
236
- },
237
- 'precisionMode': TICK_SIZE,
238
- // exchange-specific options
239
- 'options': {
240
- 'defaultTimeInForce': 'GTC',
241
- 'warnOnFetchOpenOrdersWithoutSymbol': true,
242
- 'recvWindow': 5 * 1000,
243
- 'timeDifference': 0,
244
- 'adjustForTimeDifference': false,
245
- 'parseOrderToPrecision': false,
246
- 'newOrderRespType': {
247
- 'market': 'FULL',
248
- 'limit': 'RESULT',
249
- 'stop': 'RESULT',
250
- },
251
- 'leverage_markets_suffix': '_LEVERAGE',
252
- 'collateralCurrencies': ['USD', 'EUR', 'USDT'],
253
- },
254
- 'features': {
255
- 'default': {
256
- 'sandbox': true,
257
- 'createOrder': {
258
- 'marginMode': true,
259
- 'triggerPrice': true,
260
- 'triggerPriceType': undefined,
261
- 'triggerDirection': false,
262
- 'stopLossPrice': false,
263
- 'takeProfitPrice': false,
264
- 'attachedStopLossTakeProfit': {
265
- 'triggerPriceType': undefined,
266
- 'price': false,
267
- },
268
- 'timeInForce': {
269
- 'IOC': true,
270
- 'FOK': true,
271
- 'PO': false,
272
- 'GTD': true,
273
- },
274
- 'hedged': false,
275
- 'selfTradePrevention': false,
276
- 'trailing': false,
277
- 'iceberg': false,
278
- 'leverage': true,
279
- 'marketBuyByCost': false,
280
- 'marketBuyRequiresPrice': false,
281
- },
282
- 'createOrders': undefined,
283
- 'fetchMyTrades': {
284
- 'marginMode': false,
285
- 'limit': 500,
286
- 'daysBack': 100000,
287
- 'untilDays': 100000,
288
- 'symbolRequired': false,
289
- },
290
- 'fetchOrder': {
291
- 'marginMode': false,
292
- 'trigger': false,
293
- 'trailing': false,
294
- 'symbolRequired': false,
295
- },
296
- 'fetchOpenOrders': {
297
- 'marginMode': true,
298
- 'limit': 100,
299
- 'trigger': false,
300
- 'trailing': false,
301
- 'symbolRequired': false,
302
- },
303
- 'fetchOrders': undefined,
304
- 'fetchClosedOrders': undefined,
305
- 'fetchOHLCV': {
306
- 'limit': 1000,
307
- },
308
- },
309
- 'spot': {
310
- 'extends': 'default',
311
- },
312
- 'swap': {
313
- 'linear': {
314
- 'extends': 'default',
315
- },
316
- 'inverse': {
317
- 'extends': 'default',
318
- },
319
- },
320
- 'future': {
321
- 'linear': {
322
- 'extends': 'default',
323
- },
324
- 'inverse': {
325
- 'extends': 'default',
326
- },
327
- },
328
- },
329
- 'exceptions': {
330
- 'broad': {
331
- 'FIELD_VALIDATION_ERROR Cancel is available only for LIMIT order': InvalidOrder,
332
- 'API key does not exist': AuthenticationError,
333
- 'Order would trigger immediately.': InvalidOrder,
334
- 'Account has insufficient balance for requested action.': InsufficientFunds,
335
- 'Rest API trading is not enabled.': ExchangeNotAvailable,
336
- 'Combination of parameters invalid': BadRequest,
337
- 'Invalid limit price': BadRequest,
338
- 'Only leverage symbol allowed here:': BadSymbol,
339
- 'market data service is not available': ExchangeNotAvailable,
340
- 'your time is ahead of server': InvalidNonce,
341
- 'Can not find account': BadRequest,
342
- 'You mentioned an invalid value for the price parameter': BadRequest, // -1030
343
- },
344
- 'exact': {
345
- '-1000': ExchangeNotAvailable,
346
- '-1013': InvalidOrder,
347
- // '-1021': InvalidNonce, // {"code":"-1021","msg":"your time is ahead of server"} // see above in the broad section
348
- '-1022': AuthenticationError,
349
- '-1030': InvalidOrder,
350
- '-1100': InvalidOrder,
351
- '-1104': ExchangeError,
352
- '-1025': AuthenticationError,
353
- '-1128': BadRequest,
354
- '-2010': ExchangeError,
355
- '-2011': OrderNotFound,
356
- '-2013': OrderNotFound,
357
- '-2014': AuthenticationError,
358
- '-2015': AuthenticationError, // "Invalid API-key, IP, or permissions for action."
359
- },
360
- },
361
- 'commonCurrencies': {
362
- 'ACN': 'Accenture',
363
- 'AMC': 'AMC Entertainment Holdings',
364
- 'BNS': 'Bank of Nova Scotia',
365
- 'CAR': 'Avis Budget Group Inc',
366
- 'CLR': 'Continental Resources',
367
- 'EDU': 'New Oriental Education & Technology Group Inc',
368
- 'ETN': 'Eaton',
369
- 'FOX': 'Fox Corporation',
370
- 'GM': 'General Motors Co',
371
- 'IQ': 'iQIYI',
372
- 'OSK': 'Oshkosh',
373
- 'PLAY': "Dave & Buster's Entertainment",
374
- },
375
- });
376
- }
377
- nonce() {
378
- return this.milliseconds() - this.options['timeDifference'];
379
- }
380
- /**
381
- * @method
382
- * @name currencycom#fetchTime
383
- * @description fetches the current integer timestamp in milliseconds from the exchange server
384
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/timeUsingGET
385
- * @param {object} [params] extra parameters specific to the exchange API endpoint
386
- * @returns {int} the current integer timestamp in milliseconds from the exchange server
387
- */
388
- async fetchTime(params = {}) {
389
- const response = await this.publicGetV2Time(params);
390
- //
391
- // {
392
- // "serverTime": 1590998366609
393
- // }
394
- //
395
- return this.safeInteger(response, 'serverTime');
396
- }
397
- /**
398
- * @method
399
- * @name currencycom#fetchCurrencies
400
- * @description fetches all available currencies on an exchange
401
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getCurrenciesUsingGET
402
- * @param {object} [params] extra parameters specific to the exchange API endpoint
403
- * @returns {object} an associative dictionary of currencies
404
- */
405
- async fetchCurrencies(params = {}) {
406
- // requires authentication
407
- if (!this.checkRequiredCredentials(false)) {
408
- return undefined;
409
- }
410
- const response = await this.privateGetV2Currencies(params);
411
- //
412
- // [
413
- // {
414
- // "name": "Euro",
415
- // "displaySymbol": "EUR.cx",
416
- // "precision": "2",
417
- // "type": "FIAT",
418
- // "minWithdrawal": "90.0",
419
- // "maxWithdrawal": "1.0E+8",
420
- // "commissionMin": "0.02", // some instruments do not have this property
421
- // "commissionPercent": "1.5", // some instruments do not have this property
422
- // "minDeposit": "90.0",
423
- // },
424
- // {
425
- // "name": "Bitcoin",
426
- // "displaySymbol": "BTC",
427
- // "precision": "8",
428
- // "type": "CRYPTO", // only a few major currencies have this value, others like USDT have a value of "TOKEN"
429
- // "minWithdrawal": "0.00020",
430
- // "commissionFixed": "0.00010",
431
- // "minDeposit": "0.00010",
432
- // },
433
- // ]
434
- //
435
- const result = {};
436
- for (let i = 0; i < response.length; i++) {
437
- const currency = response[i];
438
- const id = this.safeString(currency, 'displaySymbol');
439
- const code = this.safeCurrencyCode(id);
440
- const fee = this.safeNumber(currency, 'commissionFixed');
441
- result[code] = {
442
- 'id': id,
443
- 'code': code,
444
- 'type': this.safeStringLower(currency, 'type'),
445
- 'name': this.safeString(currency, 'name'),
446
- 'active': undefined,
447
- 'deposit': undefined,
448
- 'withdraw': undefined,
449
- 'fee': fee,
450
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(currency, 'precision'))),
451
- 'limits': {
452
- 'amount': {
453
- 'min': undefined,
454
- 'max': undefined,
455
- },
456
- 'withdraw': {
457
- 'min': this.safeNumber(currency, 'minWithdrawal'),
458
- 'max': this.safeNumber(currency, 'maxWithdrawal'),
459
- },
460
- 'deposit': {
461
- 'min': this.safeNumber(currency, 'minDeposit'),
462
- 'max': undefined,
463
- },
464
- },
465
- 'info': currency,
466
- };
467
- }
468
- return result;
469
- }
470
- /**
471
- * @method
472
- * @name currencycom#fetchMarkets
473
- * @description retrieves data on all markets for currencycom
474
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/exchangeInfoUsingGET
475
- * @param {object} [params] extra parameters specific to the exchange API endpoint
476
- * @returns {object[]} an array of objects representing market data
477
- */
478
- async fetchMarkets(params = {}) {
479
- const response = await this.publicGetV2ExchangeInfo(params);
480
- //
481
- // {
482
- // "timezone": "UTC",
483
- // "serverTime": "1645186287261",
484
- // "rateLimits": [
485
- // { rateLimitType: "REQUEST_WEIGHT", interval: "MINUTE", intervalNum: "1", limit: "1200" },
486
- // { rateLimitType: "ORDERS", interval: "SECOND", intervalNum: "1", limit: "10" },
487
- // { rateLimitType: "ORDERS", interval: "DAY", intervalNum: "1", limit: "864000" },
488
- // ],
489
- // "exchangeFilters": [],
490
- // "symbols": [
491
- // {
492
- // "symbol": "BTC/USDT", // BTC/USDT, BTC/USDT_LEVERAGE
493
- // "name": "Bitcoin / Tether",
494
- // "status": "TRADING", // TRADING, BREAK, HALT
495
- // "baseAsset": "BTC",
496
- // "baseAssetPrecision": "4",
497
- // "quoteAsset": "USDT",
498
- // "quoteAssetId": "USDT", // USDT, USDT_LEVERAGE
499
- // "quotePrecision": "4",
500
- // "orderTypes": [ "LIMIT", "MARKET" ], // LIMIT, MARKET, STOP
501
- // "filters": [
502
- // { filterType: "LOT_SIZE", minQty: "0.0001", maxQty: "100", stepSize: "0.0001", },
503
- // { filterType: "MIN_NOTIONAL", minNotional: "5", },
504
- // ],
505
- // "marketModes": [ "REGULAR" ], // CLOSE_ONLY, LONG_ONLY, REGULAR
506
- // "marketType": "SPOT", // SPOT, LEVERAGE
507
- // "longRate": -0.0684932, // LEVERAGE only
508
- // "shortRate": -0.0684932, // LEVERAGE only
509
- // "swapChargeInterval": 1440, // LEVERAGE only
510
- // "country": "",
511
- // "sector": "",
512
- // "industry": "",
513
- // "tradingHours": "UTC; Mon - 22:00, 22:05 -; Tue - 22:00, 22:05 -; Wed - 22:00, 22:05 -; Thu - 22:00, 22:05 -; Fri - 22:00, 23:01 -; Sat - 22:00, 22:05 -; Sun - 21:00, 22:05 -",
514
- // "tickSize": "0.01",
515
- // "tickValue": "403.4405", // not available in BTC/USDT_LEVERAGE, but available in BTC/USD_LEVERAGE
516
- // "exchangeFee": "0.2", // SPOT only
517
- // "tradingFee": 0.075, // LEVERAGE only
518
- // "makerFee": -0.025, // LEVERAGE only
519
- // "takerFee": 0.06, // LEVERAGE only
520
- // "maxSLGap": 50, // LEVERAGE only
521
- // "minSLGap": 1, // LEVERAGE only
522
- // "maxTPGap": 50, // LEVERAGE only
523
- // "minTPGap": 0.5, // LEVERAGE only
524
- // "assetType": "CRYPTOCURRENCY",
525
- // },
526
- // ]
527
- // }
528
- //
529
- if (this.options['adjustForTimeDifference']) {
530
- await this.loadTimeDifference();
531
- }
532
- const markets = this.safeValue(response, 'symbols', []);
533
- const result = [];
534
- for (let i = 0; i < markets.length; i++) {
535
- const market = markets[i];
536
- const id = this.safeString(market, 'symbol');
537
- const baseId = this.safeString(market, 'baseAsset');
538
- const quoteId = this.safeString(market, 'quoteAsset');
539
- const base = this.safeCurrencyCode(baseId);
540
- const quote = this.safeCurrencyCode(quoteId);
541
- let symbol = base + '/' + quote;
542
- const typeRaw = this.safeString(market, 'marketType');
543
- const spot = (typeRaw === 'SPOT');
544
- const futures = false;
545
- const swap = (typeRaw === 'LEVERAGE');
546
- const type = swap ? 'swap' : 'spot';
547
- const margin = undefined;
548
- if (swap) {
549
- symbol = symbol.replace(this.options['leverage_markets_suffix'], '');
550
- symbol += ':' + quote;
551
- }
552
- const active = this.safeString(market, 'status') === 'TRADING';
553
- // to set taker & maker fees, we use one from the below data - pairs either have 'exchangeFee' or 'tradingFee', if none of them (rare cases), then they should have 'takerFee & makerFee'
554
- const exchangeFee = this.safeString2(market, 'exchangeFee', 'tradingFee');
555
- let makerFee = this.safeString(market, 'makerFee', exchangeFee);
556
- let takerFee = this.safeString(market, 'takerFee', exchangeFee);
557
- makerFee = Precise.stringDiv(makerFee, '100');
558
- takerFee = Precise.stringDiv(takerFee, '100');
559
- const filters = this.safeValue(market, 'filters', []);
560
- const filtersByType = this.indexBy(filters, 'filterType');
561
- let limitPriceMin = undefined;
562
- let limitPriceMax = undefined;
563
- let precisionPrice = this.safeNumber(market, 'tickSize');
564
- if ('PRICE_FILTER' in filtersByType) {
565
- const filter = this.safeValue(filtersByType, 'PRICE_FILTER', {});
566
- precisionPrice = this.safeNumber(filter, 'tickSize');
567
- // PRICE_FILTER reports zero values for maxPrice
568
- // since they updated filter types in November 2018
569
- // https://github.com/ccxt/ccxt/issues/4286
570
- // therefore limits['price']['max'] doesn't have any meaningful value except undefined
571
- limitPriceMin = this.safeNumber(filter, 'minPrice');
572
- const maxPrice = this.safeString(filter, 'maxPrice');
573
- if ((maxPrice !== undefined) && (Precise.stringGt(maxPrice, '0'))) {
574
- limitPriceMax = maxPrice;
575
- }
576
- }
577
- let precisionAmount = this.parseNumber(this.parsePrecision(this.safeString(market, 'baseAssetPrecision')));
578
- let limitAmount = {
579
- 'min': undefined,
580
- 'max': undefined,
581
- };
582
- if ('LOT_SIZE' in filtersByType) {
583
- const filter = this.safeValue(filtersByType, 'LOT_SIZE', {});
584
- precisionAmount = this.safeNumber(filter, 'stepSize');
585
- limitAmount = {
586
- 'min': this.safeNumber(filter, 'minQty'),
587
- 'max': this.safeNumber(filter, 'maxQty'),
588
- };
589
- }
590
- let limitMarket = {
591
- 'min': undefined,
592
- 'max': undefined,
593
- };
594
- if ('MARKET_LOT_SIZE' in filtersByType) {
595
- const filter = this.safeValue(filtersByType, 'MARKET_LOT_SIZE', {});
596
- limitMarket = {
597
- 'min': this.safeNumber(filter, 'minQty'),
598
- 'max': this.safeNumber(filter, 'maxQty'),
599
- };
600
- }
601
- let costMin = undefined;
602
- if ('MIN_NOTIONAL' in filtersByType) {
603
- const filter = this.safeValue(filtersByType, 'MIN_NOTIONAL', {});
604
- costMin = this.safeNumber(filter, 'minNotional');
605
- }
606
- const isContract = swap || futures;
607
- result.push({
608
- 'id': id,
609
- 'symbol': symbol,
610
- 'base': base,
611
- 'quote': quote,
612
- 'settle': undefined,
613
- 'baseId': baseId,
614
- 'quoteId': quoteId,
615
- 'settleId': undefined,
616
- 'type': type,
617
- 'spot': spot,
618
- 'margin': margin,
619
- 'swap': swap,
620
- 'future': futures,
621
- 'option': false,
622
- 'active': active,
623
- 'contract': isContract,
624
- 'linear': isContract ? true : undefined,
625
- 'inverse': undefined,
626
- 'taker': this.parseNumber(takerFee),
627
- 'maker': this.parseNumber(makerFee),
628
- 'contractSize': undefined,
629
- 'expiry': undefined,
630
- 'expiryDatetime': undefined,
631
- 'strike': undefined,
632
- 'optionType': undefined,
633
- 'precision': {
634
- 'amount': precisionAmount,
635
- 'price': precisionPrice,
636
- },
637
- 'limits': {
638
- 'leverage': {
639
- 'min': undefined,
640
- 'max': undefined,
641
- },
642
- 'amount': limitAmount,
643
- 'market': limitMarket,
644
- 'price': {
645
- 'min': limitPriceMin,
646
- 'max': this.parseNumber(limitPriceMax),
647
- },
648
- 'cost': {
649
- 'min': costMin,
650
- 'max': undefined,
651
- },
652
- },
653
- 'created': undefined,
654
- 'info': market,
655
- });
656
- }
657
- return result;
658
- }
659
- /**
660
- * @method
661
- * @name currencycom#fetchAccounts
662
- * @description fetch all the accounts associated with a profile
663
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/accountUsingGET
664
- * @param {object} [params] extra parameters specific to the exchange API endpoint
665
- * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type
666
- */
667
- async fetchAccounts(params = {}) {
668
- const response = await this.privateGetV2Account(params);
669
- //
670
- // {
671
- // "makerCommission": "0.20",
672
- // "takerCommission": "0.20",
673
- // "buyerCommission": "0.20",
674
- // "sellerCommission": "0.20",
675
- // "canTrade": true,
676
- // "canWithdraw": true,
677
- // "canDeposit": true,
678
- // "updateTime": "1645266330",
679
- // "userId": "644722",
680
- // "balances": [
681
- // {
682
- // "accountId": "120702016179403605",
683
- // "collateralCurrency": false,
684
- // "asset": "CAKE",
685
- // "free": "3.1",
686
- // "locked": "0.0",
687
- // "default": false,
688
- // },
689
- // {
690
- // "accountId": "109698017713125316",
691
- // "collateralCurrency": true,
692
- // "asset": "USD",
693
- // "free": "17.58632",
694
- // "locked": "0.0",
695
- // "default": true,
696
- // }
697
- // ]
698
- // }
699
- //
700
- const accounts = this.safeValue(response, 'balances', []);
701
- const result = [];
702
- for (let i = 0; i < accounts.length; i++) {
703
- const account = accounts[i];
704
- const accountId = this.safeString(account, 'accountId'); // must be string, because the numeric value is far too big for integer, and causes bugs
705
- const currencyId = this.safeString(account, 'asset');
706
- const currencyCode = this.safeCurrencyCode(currencyId);
707
- result.push({
708
- 'id': accountId,
709
- 'type': undefined,
710
- 'currency': currencyCode,
711
- 'info': account,
712
- });
713
- }
714
- return result;
715
- }
716
- /**
717
- * @method
718
- * @name currencycom#fetchTradingFees
719
- * @description fetch the trading fees for multiple markets
720
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/accountUsingGET
721
- * @param {object} [params] extra parameters specific to the exchange API endpoint
722
- * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
723
- */
724
- async fetchTradingFees(params = {}) {
725
- await this.loadMarkets();
726
- const response = await this.privateGetV2Account(params);
727
- //
728
- // {
729
- // "makerCommission": "0.20",
730
- // "takerCommission": "0.20",
731
- // "buyerCommission": "0.20",
732
- // "sellerCommission": "0.20",
733
- // "canTrade": true,
734
- // "canWithdraw": true,
735
- // "canDeposit": true,
736
- // "updateTime": "1645738976",
737
- // "userId": "-1924114235",
738
- // "balances": []
739
- // }
740
- //
741
- const makerFee = this.safeNumber(response, 'makerCommission');
742
- const takerFee = this.safeNumber(response, 'takerCommission');
743
- const result = {};
744
- for (let i = 0; i < this.symbols.length; i++) {
745
- const symbol = this.symbols[i];
746
- result[symbol] = {
747
- 'info': response,
748
- 'symbol': symbol,
749
- 'maker': makerFee,
750
- 'taker': takerFee,
751
- 'percentage': true,
752
- 'tierBased': false,
753
- };
754
- }
755
- return result;
756
- }
757
- parseBalance(response, type = undefined) {
758
- //
759
- // {
760
- // "makerCommission":0.20,
761
- // "takerCommission":0.20,
762
- // "buyerCommission":0.20,
763
- // "sellerCommission":0.20,
764
- // "canTrade":true,
765
- // "canWithdraw":true,
766
- // "canDeposit":true,
767
- // "updateTime":1591056268,
768
- // "balances":[
769
- // {
770
- // "accountId":5470306579272368,
771
- // "collateralCurrency":true,
772
- // "asset":"ETH",
773
- // "free":0.0,
774
- // "locked":0.0,
775
- // "default":false,
776
- // },
777
- // ]
778
- // }
779
- //
780
- const result = { 'info': response };
781
- const balances = this.safeValue(response, 'balances', []);
782
- for (let i = 0; i < balances.length; i++) {
783
- const balance = balances[i];
784
- const currencyId = this.safeString(balance, 'asset');
785
- const code = this.safeCurrencyCode(currencyId);
786
- const account = this.account();
787
- account['free'] = this.safeString(balance, 'free');
788
- account['used'] = this.safeString(balance, 'locked');
789
- result[code] = account;
790
- }
791
- return this.safeBalance(result);
792
- }
793
- /**
794
- * @method
795
- * @name currencycom#fetchBalance
796
- * @description query for balance and get the amount of funds available for trading or funds locked in orders
797
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/accountUsingGET
798
- * @param {object} [params] extra parameters specific to the exchange API endpoint
799
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
800
- */
801
- async fetchBalance(params = {}) {
802
- await this.loadMarkets();
803
- const response = await this.privateGetV2Account(params);
804
- //
805
- // {
806
- // "makerCommission": "0.20",
807
- // "takerCommission": "0.20",
808
- // "buyerCommission": "0.20",
809
- // "sellerCommission": "0.20",
810
- // "canTrade": true,
811
- // "canWithdraw": true,
812
- // "canDeposit": true,
813
- // "updateTime": "1645266330",
814
- // "userId": "644722",
815
- // "balances": [
816
- // {
817
- // "accountId": "120702016179403605",
818
- // "collateralCurrency": false,
819
- // "asset": "CAKE",
820
- // "free": "1.784",
821
- // "locked": "0.0",
822
- // "default": false,
823
- // },
824
- // {
825
- // "accountId": "109698017413175316",
826
- // "collateralCurrency": true,
827
- // "asset": "USD",
828
- // "free": "7.58632",
829
- // "locked": "0.0",
830
- // "default": true,
831
- // }
832
- // ]
833
- // }
834
- //
835
- return this.parseBalance(response);
836
- }
837
- /**
838
- * @method
839
- * @name currencycom#fetchOrderBook
840
- * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
841
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/depthUsingGET
842
- * @param {string} symbol unified symbol of the market to fetch the order book for
843
- * @param {int} [limit] the maximum amount of order book entries to return
844
- * @param {object} [params] extra parameters specific to the exchange API endpoint
845
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
846
- */
847
- async fetchOrderBook(symbol, limit = undefined, params = {}) {
848
- await this.loadMarkets();
849
- const market = this.market(symbol);
850
- const request = {
851
- 'symbol': market['id'],
852
- };
853
- if (limit !== undefined) {
854
- request['limit'] = limit; // default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000, 5000
855
- }
856
- const response = await this.publicGetV2Depth(this.extend(request, params));
857
- //
858
- // {
859
- // "lastUpdateId":1590999849037,
860
- // "asks":[
861
- // [0.02495,60.0345],
862
- // [0.02496,34.1],
863
- // ...
864
- // ],
865
- // "bids":[
866
- // [0.02487,72.4144854],
867
- // [0.02486,24.043],
868
- // ...
869
- // ]
870
- // }
871
- //
872
- const orderbook = this.parseOrderBook(response, symbol);
873
- orderbook['nonce'] = this.safeInteger(response, 'lastUpdateId');
874
- return orderbook;
875
- }
876
- parseTicker(ticker, market = undefined) {
877
- //
878
- // fetchTicker
879
- //
880
- // {
881
- // "symbol":"ETH/BTC",
882
- // "priceChange":"0.00030",
883
- // "priceChangePercent":"1.21",
884
- // "weightedAvgPrice":"0.02481",
885
- // "prevClosePrice":"0.02447",
886
- // "lastPrice":"0.02477",
887
- // "lastQty":"60.0",
888
- // "bidPrice":"0.02477",
889
- // "askPrice":"0.02484",
890
- // "openPrice":"0.02447",
891
- // "highPrice":"0.02524",
892
- // "lowPrice":"0.02438",
893
- // "volume":"11.97",
894
- // "quoteVolume":"0.298053",
895
- // "openTime":1590969600000,
896
- // "closeTime":1591000072693
897
- // }
898
- //
899
- // fetchTickers
900
- //
901
- // {
902
- // "symbol": "SHIB/USD_LEVERAGE",
903
- // "weightedAvgPrice": "0.000027595",
904
- // "lastPrice": "0.00002737",
905
- // "lastQty": "1.11111111E8",
906
- // "bidPrice": "0.00002737",
907
- // "askPrice": "0.00002782",
908
- // "highPrice": "0.00002896",
909
- // "lowPrice": "0.00002738",
910
- // "volume": "16472160000",
911
- // "quoteVolume": "454796.3376",
912
- // "openTime": "1645187472000",
913
- // "closeTime": "1645273872000",
914
- // }
915
- //
916
- // ws:marketData.subscribe
917
- //
918
- // {
919
- // "symbolName":"TXN",
920
- // "bid":139.85,
921
- // "bidQty":2500,
922
- // "ofr":139.92000000000002,
923
- // "ofrQty":2500,
924
- // "timestamp":1597850971558
925
- // }
926
- //
927
- const timestamp = this.safeInteger2(ticker, 'closeTime', 'timestamp');
928
- const marketId = this.safeString2(ticker, 'symbol', 'symbolName');
929
- market = this.safeMarket(marketId, market, '/');
930
- const last = this.safeString(ticker, 'lastPrice');
931
- return this.safeTicker({
932
- 'symbol': market['symbol'],
933
- 'timestamp': timestamp,
934
- 'datetime': this.iso8601(timestamp),
935
- 'high': this.safeString(ticker, 'highPrice'),
936
- 'low': this.safeString(ticker, 'lowPrice'),
937
- 'bid': this.safeString2(ticker, 'bidPrice', 'bid'),
938
- 'bidVolume': this.safeString(ticker, 'bidQty'),
939
- 'ask': this.safeString2(ticker, 'askPrice', 'ofr'),
940
- 'askVolume': this.safeString(ticker, 'ofrQty'),
941
- 'vwap': this.safeString(ticker, 'weightedAvgPrice'),
942
- 'open': this.safeString(ticker, 'openPrice'),
943
- 'close': last,
944
- 'last': last,
945
- 'previousClose': this.safeString(ticker, 'prevClosePrice'),
946
- 'change': this.safeString(ticker, 'priceChange'),
947
- 'percentage': this.safeString(ticker, 'priceChangePercent'),
948
- 'average': undefined,
949
- 'baseVolume': this.safeString(ticker, 'volume'),
950
- 'quoteVolume': this.safeString(ticker, 'quoteVolume'),
951
- 'info': ticker,
952
- }, market);
953
- }
954
- /**
955
- * @method
956
- * @name currencycom#fetchTicker
957
- * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
958
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/ticker_24hrUsingGET
959
- * @param {string} symbol unified symbol of the market to fetch the ticker for
960
- * @param {object} [params] extra parameters specific to the exchange API endpoint
961
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
962
- */
963
- async fetchTicker(symbol, params = {}) {
964
- await this.loadMarkets();
965
- const market = this.market(symbol);
966
- const request = {
967
- 'symbol': market['id'],
968
- };
969
- const response = await this.publicGetV2Ticker24hr(this.extend(request, params));
970
- //
971
- // {
972
- // "symbol":"ETH/BTC",
973
- // "priceChange":"0.00030",
974
- // "priceChangePercent":"1.21",
975
- // "weightedAvgPrice":"0.02481",
976
- // "prevClosePrice":"0.02447",
977
- // "lastPrice":"0.02477",
978
- // "lastQty":"60.0",
979
- // "bidPrice":"0.02477",
980
- // "askPrice":"0.02484",
981
- // "openPrice":"0.02447",
982
- // "highPrice":"0.02524",
983
- // "lowPrice":"0.02438",
984
- // "volume":"11.97",
985
- // "quoteVolume":"0.298053",
986
- // "openTime":1590969600000,
987
- // "closeTime":1591000072693
988
- // }
989
- //
990
- return this.parseTicker(response, market);
991
- }
992
- /**
993
- * @method
994
- * @name currencycom#fetchTickers
995
- * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
996
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/ticker_24hrUsingGET
997
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
998
- * @param {object} [params] extra parameters specific to the exchange API endpoint
999
- * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1000
- */
1001
- async fetchTickers(symbols = undefined, params = {}) {
1002
- await this.loadMarkets();
1003
- const response = await this.publicGetV2Ticker24hr(params);
1004
- //
1005
- // [
1006
- // {
1007
- // "symbol": "SHIB/USD_LEVERAGE",
1008
- // "weightedAvgPrice": "0.000027595",
1009
- // "lastPrice": "0.00002737",
1010
- // "lastQty": "1.11111111E8",
1011
- // "bidPrice": "0.00002737",
1012
- // "askPrice": "0.00002782",
1013
- // "highPrice": "0.00002896",
1014
- // "lowPrice": "0.00002738",
1015
- // "volume": "16472160000",
1016
- // "quoteVolume": "454796.3376",
1017
- // "openTime": "1645187472000",
1018
- // "closeTime": "1645273872000",
1019
- // }
1020
- // ]
1021
- //
1022
- return this.parseTickers(response, symbols);
1023
- }
1024
- parseOHLCV(ohlcv, market = undefined) {
1025
- //
1026
- // [
1027
- // 1590971040000,
1028
- // "0.02454",
1029
- // "0.02456",
1030
- // "0.02452",
1031
- // "0.02456",
1032
- // 249
1033
- // ]
1034
- //
1035
- return [
1036
- this.safeInteger(ohlcv, 0),
1037
- this.safeNumber(ohlcv, 1),
1038
- this.safeNumber(ohlcv, 2),
1039
- this.safeNumber(ohlcv, 3),
1040
- this.safeNumber(ohlcv, 4),
1041
- this.safeNumber(ohlcv, 5),
1042
- ];
1043
- }
1044
- /**
1045
- * @method
1046
- * @name currencycom#fetchOHLCV
1047
- * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1048
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/klinesUsingGET
1049
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1050
- * @param {string} timeframe the length of time each candle represents
1051
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
1052
- * @param {int} [limit] the maximum amount of candles to fetch
1053
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1054
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1055
- */
1056
- async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1057
- await this.loadMarkets();
1058
- const market = this.market(symbol);
1059
- const request = {
1060
- 'symbol': market['id'],
1061
- 'interval': this.safeString(this.timeframes, timeframe, timeframe),
1062
- };
1063
- if (since !== undefined) {
1064
- request['startTime'] = since;
1065
- }
1066
- if (limit !== undefined) {
1067
- request['limit'] = Math.min(limit, 1000); // default 500, max 1000
1068
- }
1069
- const response = await this.publicGetV2Klines(this.extend(request, params));
1070
- //
1071
- // [
1072
- // [1590971040000,"0.02454","0.02456","0.02452","0.02456",249],
1073
- // [1590971100000,"0.02455","0.02457","0.02452","0.02456",300],
1074
- // [1590971160000,"0.02455","0.02456","0.02453","0.02454",286],
1075
- // ]
1076
- //
1077
- return this.parseOHLCVs(response, market, timeframe, since, limit);
1078
- }
1079
- parseTrade(trade, market = undefined) {
1080
- //
1081
- // fetchTrades (public aggregate trades)
1082
- //
1083
- // {
1084
- // "a":"1658318071", // Aggregate tradeId
1085
- // "p":"0.02476", // Price
1086
- // "q":"0.0", // Official doc says: "Quantity (should be ignored)"
1087
- // "T":"1591001423382", // Epoch timestamp in MS
1088
- // "m":false // Was the buyer the maker
1089
- // }
1090
- //
1091
- // createOrder fills (private)
1092
- //
1093
- // {
1094
- // "price": "9807.05",
1095
- // "qty": "0.01",
1096
- // "commission": "0",
1097
- // "commissionAsset": "dUSD"
1098
- // }
1099
- //
1100
- // fetchMyTrades
1101
- //
1102
- // {
1103
- // "symbol": "DOGE/USD",
1104
- // "id": "116046000",
1105
- // "orderId": "00000000-0000-0000-0000-000006dbb8ad",
1106
- // "price": "0.14094",
1107
- // "qty": "40.0",
1108
- // "commission": "0.01",
1109
- // "commissionAsset": "USD",
1110
- // "time": "1645283022351",
1111
- // "buyer": false,
1112
- // "maker": false,
1113
- // "isBuyer": false,
1114
- // "isMaker": false
1115
- // }
1116
- //
1117
- const timestamp = this.safeInteger2(trade, 'T', 'time');
1118
- const priceString = this.safeString2(trade, 'p', 'price');
1119
- const amountString = this.safeString2(trade, 'q', 'qty');
1120
- const id = this.safeString2(trade, 'a', 'id');
1121
- let side = undefined;
1122
- const orderId = this.safeString(trade, 'orderId');
1123
- let takerOrMaker = undefined;
1124
- if ('m' in trade) {
1125
- side = trade['m'] ? 'sell' : 'buy'; // this is reversed intentionally [TODO: needs reason to be mentioned]
1126
- takerOrMaker = 'taker'; // in public trades, it's always taker
1127
- }
1128
- else if ('isBuyer' in trade) {
1129
- side = (trade['isBuyer']) ? 'buy' : 'sell'; // this is a true side
1130
- takerOrMaker = trade['isMaker'] ? 'maker' : 'taker';
1131
- }
1132
- let fee = undefined;
1133
- if ('commission' in trade) {
1134
- fee = {
1135
- 'cost': this.safeString(trade, 'commission'),
1136
- 'currency': this.safeCurrencyCode(this.safeString(trade, 'commissionAsset')),
1137
- };
1138
- }
1139
- const marketId = this.safeString(trade, 'symbol');
1140
- const symbol = this.safeSymbol(marketId, market);
1141
- return this.safeTrade({
1142
- 'id': id,
1143
- 'order': orderId,
1144
- 'timestamp': timestamp,
1145
- 'datetime': this.iso8601(timestamp),
1146
- 'symbol': symbol,
1147
- 'type': undefined,
1148
- 'takerOrMaker': takerOrMaker,
1149
- 'side': side,
1150
- 'price': priceString,
1151
- 'amount': amountString,
1152
- 'cost': undefined,
1153
- 'fee': fee,
1154
- 'info': trade,
1155
- }, market);
1156
- }
1157
- /**
1158
- * @method
1159
- * @name currencycom#fetchTrades
1160
- * @description get the list of most recent trades for a particular symbol
1161
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/aggTradesUsingGET
1162
- * @param {string} symbol unified symbol of the market to fetch trades for
1163
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
1164
- * @param {int} [limit] the maximum amount of trades to fetch
1165
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1166
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1167
- */
1168
- async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1169
- await this.loadMarkets();
1170
- const market = this.market(symbol);
1171
- const request = {
1172
- 'symbol': market['id'],
1173
- // 'limit': 500, // default 500, max 1000
1174
- };
1175
- if (limit !== undefined) {
1176
- request['limit'] = Math.min(limit, 1000); // default 500, max 1000
1177
- }
1178
- if (since !== undefined) {
1179
- request['startTime'] = since;
1180
- }
1181
- const response = await this.publicGetV2AggTrades(this.extend(request, params));
1182
- //
1183
- // [
1184
- // {
1185
- // "a":"1658318071", // Aggregate tradeId
1186
- // "p":"0.02476", // Price
1187
- // "q":"0.0", // Official doc says: "Quantity (should be ignored)"
1188
- // "T":"1591001423382", // Epoch timestamp in MS
1189
- // "m":false // Was the buyer the maker
1190
- // },
1191
- // ]
1192
- //
1193
- return this.parseTrades(response, market, since, limit);
1194
- }
1195
- parseOrder(order, market = undefined) {
1196
- //
1197
- // createOrder
1198
- //
1199
- // limit
1200
- //
1201
- // {
1202
- // "symbol": "BTC/USD",
1203
- // "orderId": "00000000-0000-0000-0000-000006eacaa0",
1204
- // "transactTime": "1645281669295",
1205
- // "price": "30000.00000000",
1206
- // "origQty": "0.0002", // might not be present for "market" order
1207
- // "executedQty": "0.0", // positive for BUY, negative for SELL. This property might not be present in Leverage markets
1208
- // "margin": 0.1, // present in leverage markets
1209
- // "status": "NEW", // NEW, FILLED, ...
1210
- // "timeInForce": "GTC",
1211
- // "type": "LIMIT", // LIMIT, MARKET
1212
- // "side": "BUY",
1213
- // "fills": [ // this field might not be present if there were no fills
1214
- // {
1215
- // "price": "0.14094",
1216
- // "qty": "40.0",
1217
- // "commission": "0",
1218
- // "commissionAsset": "dUSD",
1219
- // },
1220
- // ],
1221
- // }
1222
- //
1223
- // fetchOrder (fetchOpenOrders is an array same structure, with some extra fields)
1224
- //
1225
- // {
1226
- // "symbol": "BTC/USD_LEVERAGE",
1227
- // "accountId": "123456789012345678",
1228
- // "orderId": "00a01234-0123-54c4-0000-123451234567",
1229
- // "price": "25779.35",
1230
- // "status": "MODIFIED",
1231
- // "type": "LIMIT",
1232
- // "timeInForceType": "GTC",
1233
- // "side": "BUY",
1234
- // "guaranteedStopLoss": false,
1235
- // "trailingStopLoss": false,
1236
- // "margin": "0.05",
1237
- // "takeProfit": "27020.00",
1238
- // "stopLoss": "24500.35",
1239
- // "fills": [], // might not be present
1240
- // "timestamp": "1685958369623", // "time" in "fetchOpenOrders"
1241
- // "expireTime": "1686167960000", // "expireTimestamp" in "fetchOpenOrders"
1242
- // "quantity": "0.00040", // "origQty" in "fetchOpenOrders"
1243
- // "executedQty": "0.0", // present in "fetchOpenOrders"
1244
- // "updateTime": "1685958369542", // present in "fetchOpenOrders"
1245
- // "leverage": true, // present in "fetchOpenOrders"
1246
- // "working": true // present in "fetchOpenOrders"
1247
- // }
1248
- //
1249
- // cancelOrder
1250
- //
1251
- // {
1252
- // "symbol": "DOGE/USD",
1253
- // "orderId": "00000000-0000-0003-0000-000006db714c",
1254
- // "price": "0.13",
1255
- // "origQty": "30.0",
1256
- // "executedQty": "0.0",
1257
- // "status": "CANCELED",
1258
- // "timeInForce": "GTC",
1259
- // "type": "LIMIT",
1260
- // "side": "BUY",
1261
- // }
1262
- //
1263
- const marketId = this.safeString(order, 'symbol');
1264
- const symbol = this.safeSymbol(marketId, market, '/');
1265
- const id = this.safeString(order, 'orderId');
1266
- const price = this.safeString(order, 'price');
1267
- const amount = this.safeString2(order, 'origQty', 'quantity');
1268
- const filledRaw = this.safeString(order, 'executedQty');
1269
- const filled = Precise.stringAbs(filledRaw);
1270
- const status = this.parseOrderStatus(this.safeString(order, 'status'));
1271
- const timeInForce = this.parseOrderTimeInForce(this.safeString2(order, 'timeInForce', 'timeInForceType'));
1272
- const type = this.parseOrderType(this.safeString(order, 'type'));
1273
- const side = this.parseOrderSide(this.safeString(order, 'side'));
1274
- const timestamp = this.safeIntegerN(order, ['time', 'transactTime', 'timestamp']);
1275
- const fills = this.safeValue(order, 'fills');
1276
- return this.safeOrder({
1277
- 'info': order,
1278
- 'id': id,
1279
- 'timestamp': timestamp,
1280
- 'datetime': this.iso8601(timestamp),
1281
- 'lastTradeTimestamp': undefined,
1282
- 'symbol': symbol,
1283
- 'type': type,
1284
- 'timeInForce': timeInForce,
1285
- 'side': side,
1286
- 'price': price,
1287
- 'triggerPrice': undefined,
1288
- 'amount': amount,
1289
- 'cost': undefined,
1290
- 'average': undefined,
1291
- 'filled': filled,
1292
- 'remaining': undefined,
1293
- 'status': status,
1294
- 'fee': undefined,
1295
- 'trades': fills,
1296
- }, market);
1297
- }
1298
- parseOrderStatus(status) {
1299
- const statuses = {
1300
- 'NEW': 'open',
1301
- 'CREATED': 'open',
1302
- 'MODIFIED': 'open',
1303
- 'PARTIALLY_FILLED': 'open',
1304
- 'FILLED': 'closed',
1305
- 'CANCELED': 'canceled',
1306
- 'PENDING_CANCEL': 'canceling',
1307
- 'REJECTED': 'rejected',
1308
- 'EXPIRED': 'expired',
1309
- };
1310
- return this.safeString(statuses, status, status);
1311
- }
1312
- parseOrderType(status) {
1313
- const statuses = {
1314
- 'MARKET': 'market',
1315
- 'LIMIT': 'limit',
1316
- 'STOP': 'stop',
1317
- // temporarily we remove custom mappings
1318
- // 'LIMIT_MAKER': '',
1319
- // 'STOP_LOSS': 'stop-loss',
1320
- // 'STOP_LOSS_LIMIT': 'stop-limit',
1321
- // 'TAKE_PROFIT': 'take-profit',
1322
- // 'TAKE_PROFIT_LIMIT': 'take-profit',
1323
- };
1324
- return this.safeString(statuses, status, status);
1325
- }
1326
- parseOrderTimeInForce(status) {
1327
- const statuses = {
1328
- 'GTC': 'GTC',
1329
- 'FOK': 'FOK',
1330
- 'IOC': 'IOC',
1331
- };
1332
- return this.safeString(statuses, status, status);
1333
- }
1334
- parseOrderSide(status) {
1335
- const statuses = {
1336
- 'BUY': 'buy',
1337
- 'SELL': 'sell',
1338
- };
1339
- return this.safeString(statuses, status, status);
1340
- }
1341
- /**
1342
- * @method
1343
- * @name currencycom#createOrder
1344
- * @description create a trade order
1345
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/orderUsingPOST
1346
- * @param {string} symbol unified symbol of the market to create an order in
1347
- * @param {string} type 'market' or 'limit'
1348
- * @param {string} side 'buy' or 'sell'
1349
- * @param {float} amount how much of currency you want to trade in units of base currency
1350
- * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1351
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1352
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1353
- */
1354
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1355
- await this.loadMarkets();
1356
- const market = this.market(symbol);
1357
- let accountId = undefined;
1358
- if (market['margin']) {
1359
- accountId = this.safeString(this.options, 'accountId');
1360
- accountId = this.safeString(params, 'accountId', accountId);
1361
- if (accountId === undefined) {
1362
- throw new ArgumentsRequired(this.id + " createOrder() requires an accountId parameter or an exchange.options['accountId'] option for " + market['type'] + ' markets');
1363
- }
1364
- }
1365
- const newOrderRespType = this.safeValue(this.options['newOrderRespType'], type, 'RESULT');
1366
- const request = {
1367
- 'symbol': market['id'],
1368
- 'quantity': this.amountToPrecision(symbol, amount),
1369
- 'type': type.toUpperCase(),
1370
- 'side': side.toUpperCase(),
1371
- 'newOrderRespType': newOrderRespType, // 'RESULT' for full order or 'FULL' for order with fills
1372
- // 'leverage': 1,
1373
- // 'accountId': 5470306579272968, // required for leverage markets
1374
- // 'takeProfit': '123.45',
1375
- // 'stopLoss': '54.321',
1376
- // 'guaranteedStopLoss': '54.321',
1377
- };
1378
- if (type === 'limit') {
1379
- request['price'] = this.priceToPrecision(symbol, price);
1380
- request['timeInForce'] = this.options['defaultTimeInForce'];
1381
- }
1382
- else {
1383
- if (type === 'stop') {
1384
- request['type'] = 'STOP';
1385
- request['price'] = this.priceToPrecision(symbol, price);
1386
- }
1387
- else if (type === 'market') {
1388
- const triggerPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
1389
- params = this.omit(params, ['triggerPrice', 'stopPrice']);
1390
- if (triggerPrice !== undefined) {
1391
- request['type'] = 'STOP';
1392
- request['price'] = this.priceToPrecision(symbol, triggerPrice);
1393
- }
1394
- }
1395
- }
1396
- const response = await this.privatePostV2Order(this.extend(request, params));
1397
- //
1398
- // limit
1399
- //
1400
- // {
1401
- // "symbol": "BTC/USD",
1402
- // "orderId": "00000000-0000-0000-0000-000006eaaaa0",
1403
- // "transactTime": "1645281669295",
1404
- // "price": "30000.00000000",
1405
- // "origQty": "0.0002",
1406
- // "executedQty": "0.0", // positive for BUY, negative for SELL
1407
- // "status": "NEW",
1408
- // "timeInForce": "GTC",
1409
- // "type": "LIMIT",
1410
- // "side": "BUY",
1411
- // }
1412
- //
1413
- // market
1414
- //
1415
- // {
1416
- // "symbol": "DOGE/USD",
1417
- // "orderId": "00000000-0000-0000-0000-000006eab8ad",
1418
- // "transactTime": "1645283022252",
1419
- // "price": "0.14066000",
1420
- // "origQty": "40",
1421
- // "executedQty": "40.0", // positive for BUY, negative for SELL
1422
- // "status": "FILLED",
1423
- // "timeInForce": "FOK",
1424
- // "type": "MARKET",
1425
- // "side": "BUY",
1426
- // "fills": [
1427
- // {
1428
- // "price": "0.14094",
1429
- // "qty": "40.0",
1430
- // "commission": "0",
1431
- // "commissionAsset": "dUSD"
1432
- // }
1433
- // ]
1434
- // }
1435
- //
1436
- return this.parseOrder(response, market);
1437
- }
1438
- /**
1439
- * @method
1440
- * @name currencycom#fetchOrder
1441
- * @description fetches information on an order made by the user
1442
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getOrderUsingGET
1443
- * @param {string} id order id
1444
- * @param {string} symbol unified symbol of the market the order was made in
1445
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1446
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1447
- */
1448
- async fetchOrder(id, symbol = undefined, params = {}) {
1449
- if (symbol === undefined) {
1450
- throw new ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
1451
- }
1452
- await this.loadMarkets();
1453
- const market = this.market(symbol);
1454
- const request = {
1455
- 'orderId': id,
1456
- 'symbol': market['id'],
1457
- };
1458
- const response = await this.privateGetV2FetchOrder(this.extend(request, params));
1459
- //
1460
- // {
1461
- // "accountId": "109698017413125316",
1462
- // "orderId": "2810f1c5-0079-54c4-0000-000080421601",
1463
- // "quantity": "20.0",
1464
- // "price": "0.06",
1465
- // "timestamp": "1661157503788",
1466
- // "status": "CREATED",
1467
- // "type": "LIMIT",
1468
- // "timeInForceType": "GTC",
1469
- // "side": "BUY",
1470
- // "margin": "0.1",
1471
- // "fills": [ // might not be present
1472
- // {
1473
- // "price": "0.14094",
1474
- // "qty": "40.0",
1475
- // "commission": "0",
1476
- // "commissionAsset": "dUSD"
1477
- // }
1478
- // ]
1479
- // }
1480
- //
1481
- return this.parseOrder(response);
1482
- }
1483
- /**
1484
- * @method
1485
- * @name currencycom#fetchOpenOrders
1486
- * @description fetch all unfilled currently open orders
1487
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/openOrdersUsingGET
1488
- * @param {string} symbol unified market symbol
1489
- * @param {int} [since] the earliest time in ms to fetch open orders for
1490
- * @param {int} [limit] the maximum number of open orders structures to retrieve
1491
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1492
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1493
- */
1494
- async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1495
- await this.loadMarkets();
1496
- let market = undefined;
1497
- const request = {};
1498
- if (symbol !== undefined) {
1499
- market = this.market(symbol);
1500
- request['symbol'] = market['id'];
1501
- }
1502
- else if (this.options['warnOnFetchOpenOrdersWithoutSymbol']) {
1503
- const symbols = this.symbols;
1504
- const numSymbols = symbols.length;
1505
- const fetchOpenOrdersRateLimit = this.parseToInt(numSymbols / 2);
1506
- throw new ExchangeError(this.id + ' fetchOpenOrders() WARNING: fetching open orders without specifying a symbol is rate-limited to one call per ' + fetchOpenOrdersRateLimit.toString() + ' seconds. Do not call this method frequently to avoid ban. Set ' + this.id + '.options["warnOnFetchOpenOrdersWithoutSymbol"] = false to suppress this warning message.');
1507
- }
1508
- const response = await this.privateGetV2OpenOrders(this.extend(request, params));
1509
- //
1510
- // [
1511
- // {
1512
- // "symbol": "DOGE/USD",
1513
- // "orderId": "00000000-0000-0003-0000-000004bac57a",
1514
- // "price": "0.13",
1515
- // "origQty": "39.0",
1516
- // "executedQty": "0.0", // positive for BUY, negative for SELL
1517
- // "status": "NEW",
1518
- // "timeInForce": "GTC",
1519
- // "type": "LIMIT",
1520
- // "side": "BUY",
1521
- // "time": "1645284216240",
1522
- // "updateTime": "1645284216240",
1523
- // "leverage": false,
1524
- // "working": true
1525
- // },
1526
- // ]
1527
- //
1528
- return this.parseOrders(response, market, since, limit, params);
1529
- }
1530
- /**
1531
- * @method
1532
- * @name currencycom#cancelOrder
1533
- * @description cancels an open order
1534
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/cancelOrderUsingDELETE
1535
- * @param {string} id order id
1536
- * @param {string} symbol unified symbol of the market the order was made in
1537
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1538
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1539
- */
1540
- async cancelOrder(id, symbol = undefined, params = {}) {
1541
- if (symbol === undefined) {
1542
- throw new ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
1543
- }
1544
- await this.loadMarkets();
1545
- const market = this.market(symbol);
1546
- const origClientOrderId = this.safeValue(params, 'origClientOrderId');
1547
- const request = {
1548
- 'symbol': market['id'],
1549
- // 'orderId': parseInt (id),
1550
- // 'origClientOrderId': id,
1551
- };
1552
- if (origClientOrderId === undefined) {
1553
- request['orderId'] = id;
1554
- }
1555
- else {
1556
- request['origClientOrderId'] = origClientOrderId;
1557
- }
1558
- const response = await this.privateDeleteV2Order(this.extend(request, params));
1559
- //
1560
- // {
1561
- // "symbol": "DOGE/USD",
1562
- // "orderId": "00000000-0000-0003-0000-000006db764c",
1563
- // "price": "0.13",
1564
- // "origQty": "30.0",
1565
- // "executedQty": "0.0", // positive for BUY, negative for SELL
1566
- // "status": "CANCELED",
1567
- // "timeInForce": "GTC",
1568
- // "type": "LIMIT",
1569
- // "side": "BUY",
1570
- // }
1571
- //
1572
- return this.parseOrder(response, market);
1573
- }
1574
- /**
1575
- * @method
1576
- * @name currencycom#fetchMyTrades
1577
- * @description fetch all trades made by the user
1578
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/myTradesUsingGET
1579
- * @param {string} symbol unified market symbol
1580
- * @param {int} [since] the earliest time in ms to fetch trades for
1581
- * @param {int} [limit] the maximum number of trades structures to retrieve
1582
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1583
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1584
- */
1585
- async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1586
- if (symbol === undefined) {
1587
- throw new ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
1588
- }
1589
- await this.loadMarkets();
1590
- const market = this.market(symbol);
1591
- const request = {
1592
- 'symbol': market['id'],
1593
- };
1594
- if (limit !== undefined) {
1595
- request['limit'] = limit;
1596
- }
1597
- const response = await this.privateGetV2MyTrades(this.extend(request, params));
1598
- //
1599
- // [
1600
- // {
1601
- // "symbol": "DOGE/USD",
1602
- // "id": "116046000",
1603
- // "orderId": "00000000-0000-0000-0000-000006dbb8ad",
1604
- // "price": "0.14094",
1605
- // "qty": "40.0",
1606
- // "commission": "0.01",
1607
- // "commissionAsset": "USD",
1608
- // "time": "1645283022351",
1609
- // "buyer": false,
1610
- // "maker": false,
1611
- // "isBuyer": false,
1612
- // "isMaker": false
1613
- // },
1614
- // ]
1615
- //
1616
- return this.parseTrades(response, market, since, limit);
1617
- }
1618
- /**
1619
- * @method
1620
- * @name currencycom#fetchDeposits
1621
- * @description fetch all deposits made to an account
1622
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getDepositsUsingGET
1623
- * @param {string} code unified currency code
1624
- * @param {int} [since] the earliest time in ms to fetch deposits for
1625
- * @param {int} [limit] the maximum number of deposits structures to retrieve
1626
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1627
- * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1628
- */
1629
- async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
1630
- return await this.fetchTransactionsByMethod('privateGetV2Deposits', code, since, limit, params);
1631
- }
1632
- /**
1633
- * @method
1634
- * @name currencycom#fetchWithdrawals
1635
- * @description fetch all withdrawals made from an account
1636
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getWithdrawalsUsingGET
1637
- * @param {string} code unified currency code
1638
- * @param {int} [since] the earliest time in ms to fetch withdrawals for
1639
- * @param {int} [limit] the maximum number of withdrawals structures to retrieve
1640
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1641
- * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1642
- */
1643
- async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
1644
- return await this.fetchTransactionsByMethod('privateGetV2Withdrawals', code, since, limit, params);
1645
- }
1646
- /**
1647
- * @method
1648
- * @name currencycom#fetchDepositsWithdrawals
1649
- * @description fetch history of deposits and withdrawals
1650
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getTransactionsUsingGET
1651
- * @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
1652
- * @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
1653
- * @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
1654
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1655
- * @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1656
- */
1657
- async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
1658
- return await this.fetchTransactionsByMethod('privateGetV2Transactions', code, since, limit, params);
1659
- }
1660
- async fetchTransactionsByMethod(method, code = undefined, since = undefined, limit = undefined, params = {}) {
1661
- await this.loadMarkets();
1662
- const request = {};
1663
- let currency = undefined;
1664
- if (code !== undefined) {
1665
- currency = this.currency(code);
1666
- }
1667
- if (since !== undefined) {
1668
- request['startTime'] = since;
1669
- }
1670
- if (limit !== undefined) {
1671
- request['limit'] = limit;
1672
- }
1673
- let response = undefined;
1674
- if (method === 'privateGetV2Deposits') {
1675
- response = await this.privateGetV2Deposits(this.extend(request, params));
1676
- }
1677
- else if (method === 'privateGetV2Withdrawals') {
1678
- response = await this.privateGetV2Withdrawals(this.extend(request, params));
1679
- }
1680
- else if (method === 'privateGetV2Transactions') {
1681
- response = await this.privateGetV2Transactions(this.extend(request, params));
1682
- }
1683
- else {
1684
- throw new NotSupported(this.id + ' fetchTransactionsByMethod() not support this method');
1685
- }
1686
- //
1687
- // [
1688
- // {
1689
- // "id": "616769213",
1690
- // "balance": "2.088",
1691
- // "amount": "1.304", // negative for 'withdrawal'
1692
- // "currency": "CAKE",
1693
- // "type": "deposit",
1694
- // "timestamp": "1645282121023",
1695
- // "paymentMethod": "BLOCKCHAIN",
1696
- // "blockchainTransactionHash": "0x57c68c1f2ae74d5eda5a2a00516361d241a5c9e1ee95bf32573523857c38c112",
1697
- // "status": "PROCESSED",
1698
- // "commission": "0.14", // this property only exists in withdrawal
1699
- // },
1700
- // ]
1701
- //
1702
- return this.parseTransactions(response, currency, since, limit, params);
1703
- }
1704
- parseTransaction(transaction, currency = undefined) {
1705
- //
1706
- // {
1707
- // "id": "616769213",
1708
- // "balance": "2.088",
1709
- // "amount": "1.304", // negative for 'withdrawal'
1710
- // "currency": "CAKE",
1711
- // "type": "deposit",
1712
- // "timestamp": "1645282121023",
1713
- // "paymentMethod": "BLOCKCHAIN",
1714
- // "blockchainTransactionHash": "0x57c68c1f2ae74d5eda5a2a00516361d241a5c9e1ee95bf32573523857c38c112",
1715
- // "status": "PROCESSED",
1716
- // "commission": "0.14", // this property only exists in withdrawal
1717
- // }
1718
- //
1719
- const timestamp = this.safeInteger(transaction, 'timestamp');
1720
- const currencyId = this.safeString(transaction, 'currency');
1721
- const code = this.safeCurrencyCode(currencyId, currency);
1722
- const feeCost = this.safeString(transaction, 'commission');
1723
- const fee = {
1724
- 'currency': undefined,
1725
- 'cost': undefined,
1726
- 'rate': undefined,
1727
- };
1728
- if (feeCost !== undefined) {
1729
- fee['currency'] = code;
1730
- fee['cost'] = feeCost;
1731
- }
1732
- return {
1733
- 'info': transaction,
1734
- 'id': this.safeString(transaction, 'id'),
1735
- 'txid': this.safeString(transaction, 'blockchainTransactionHash'),
1736
- 'type': this.parseTransactionType(this.safeString(transaction, 'type')),
1737
- 'currency': code,
1738
- 'network': undefined,
1739
- 'amount': this.safeNumber(transaction, 'amount'),
1740
- 'status': this.parseTransactionStatus(this.safeString(transaction, 'state')),
1741
- 'timestamp': timestamp,
1742
- 'datetime': this.iso8601(timestamp),
1743
- 'address': undefined,
1744
- 'addressFrom': undefined,
1745
- 'addressTo': undefined,
1746
- 'tag': undefined,
1747
- 'tagFrom': undefined,
1748
- 'tagTo': undefined,
1749
- 'updated': undefined,
1750
- 'internal': undefined,
1751
- 'comment': undefined,
1752
- 'fee': fee,
1753
- };
1754
- }
1755
- parseTransactionStatus(status) {
1756
- const statuses = {
1757
- 'APPROVAL': 'pending',
1758
- 'PROCESSED': 'ok',
1759
- };
1760
- return this.safeString(statuses, status, status);
1761
- }
1762
- parseTransactionType(type) {
1763
- const types = {
1764
- 'deposit': 'deposit',
1765
- 'withdrawal': 'withdrawal',
1766
- };
1767
- return this.safeString(types, type, type);
1768
- }
1769
- /**
1770
- * @method
1771
- * @name currencycom#fetchLedger
1772
- * @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
1773
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getLedgerUsingGET
1774
- * @param {string} [code] unified currency code, default is undefined
1775
- * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
1776
- * @param {int} [limit] max number of ledger entries to return, default is undefined
1777
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1778
- * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
1779
- */
1780
- async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
1781
- await this.loadMarkets();
1782
- const request = {};
1783
- let currency = undefined;
1784
- if (code !== undefined) {
1785
- currency = this.currency(code);
1786
- }
1787
- if (since !== undefined) {
1788
- request['startTime'] = since;
1789
- }
1790
- if (limit !== undefined) {
1791
- request['limit'] = limit;
1792
- }
1793
- const response = await this.privateGetV2Ledger(this.extend(request, params));
1794
- // in the below example, first item expresses withdrawal/deposit type, second example expresses trade
1795
- //
1796
- // [
1797
- // {
1798
- // "id": "619031398",
1799
- // "balance": "0.0",
1800
- // "amount": "-1.088",
1801
- // "currency": "CAKE",
1802
- // "type": "withdrawal",
1803
- // "timestamp": "1645460496425",
1804
- // "commission": "0.13",
1805
- // "paymentMethod": "BLOCKCHAIN", // present in withdrawal/deposit
1806
- // "blockchainTransactionHash": "0x400ac905557c3d34638b1c60eba110b3ee0f97f4eb0f7318015ab76e7f16b7d6", // present in withdrawal/deposit
1807
- // "status": "PROCESSED"
1808
- // },
1809
- // {
1810
- // "id": "619031034",
1811
- // "balance": "8.17223588",
1812
- // "amount": "-0.01326294",
1813
- // "currency": "USD",
1814
- // "type": "exchange_commission",
1815
- // "timestamp": "1645460461235",
1816
- // "commission": "0.01326294",
1817
- // "status": "PROCESSED"
1818
- // },
1819
- // ]
1820
- //
1821
- return this.parseLedger(response, currency, since, limit);
1822
- }
1823
- parseLedgerEntry(item, currency = undefined) {
1824
- const id = this.safeString(item, 'id');
1825
- const amountString = this.safeString(item, 'amount');
1826
- const amount = Precise.stringAbs(amountString);
1827
- const timestamp = this.safeInteger(item, 'timestamp');
1828
- const currencyId = this.safeString(item, 'currency');
1829
- const code = this.safeCurrencyCode(currencyId, currency);
1830
- currency = this.safeCurrency(currencyId, currency);
1831
- const feeCost = this.safeString(item, 'commission');
1832
- let fee = undefined;
1833
- if (feeCost !== undefined) {
1834
- fee = { 'currency': code, 'cost': feeCost };
1835
- }
1836
- const direction = Precise.stringLt(amountString, '0') ? 'out' : 'in';
1837
- return this.safeLedgerEntry({
1838
- 'id': id,
1839
- 'timestamp': timestamp,
1840
- 'datetime': this.iso8601(timestamp),
1841
- 'direction': direction,
1842
- 'account': undefined,
1843
- 'referenceId': this.safeString(item, 'blockchainTransactionHash'),
1844
- 'referenceAccount': undefined,
1845
- 'type': this.parseLedgerEntryType(this.safeString(item, 'type')),
1846
- 'currency': code,
1847
- 'amount': amount,
1848
- 'before': undefined,
1849
- 'after': this.safeString(item, 'balance'),
1850
- 'status': this.parseLedgerEntryStatus(this.safeString(item, 'status')),
1851
- 'fee': fee,
1852
- 'info': item,
1853
- }, currency);
1854
- }
1855
- parseLedgerEntryStatus(status) {
1856
- const statuses = {
1857
- 'APPROVAL': 'pending',
1858
- 'PROCESSED': 'ok',
1859
- 'CANCELLED': 'canceled',
1860
- };
1861
- return this.safeString(statuses, status, status);
1862
- }
1863
- parseLedgerEntryType(type) {
1864
- const types = {
1865
- 'deposit': 'transaction',
1866
- 'withdrawal': 'transaction',
1867
- 'exchange_commission': 'fee',
1868
- };
1869
- return this.safeString(types, type, type);
1870
- }
1871
- /**
1872
- * @method
1873
- * @name currencycom#fetchLeverage
1874
- * @description fetch the set leverage for a market
1875
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/leverageSettingsUsingGET
1876
- * @param {string} symbol unified market symbol
1877
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1878
- * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
1879
- */
1880
- async fetchLeverage(symbol, params = {}) {
1881
- await this.loadMarkets();
1882
- const market = this.market(symbol);
1883
- const request = {
1884
- 'symbol': market['id'],
1885
- };
1886
- const response = await this.privateGetV2LeverageSettings(this.extend(request, params));
1887
- //
1888
- // {
1889
- // "values": [ 1, 2, 5, 10, ],
1890
- // "value": "10",
1891
- // }
1892
- //
1893
- return this.parseLeverage(response, market);
1894
- }
1895
- parseLeverage(leverage, market = undefined) {
1896
- const leverageValue = this.safeInteger(leverage, 'value');
1897
- return {
1898
- 'info': leverage,
1899
- 'symbol': market['symbol'],
1900
- 'marginMode': undefined,
1901
- 'longLeverage': leverageValue,
1902
- 'shortLeverage': leverageValue,
1903
- };
1904
- }
1905
- /**
1906
- * @method
1907
- * @name currencycom#fetchDepositAddress
1908
- * @description fetch the deposit address for a currency associated with this account
1909
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getDepositAddressUsingGET
1910
- * @param {string} code unified currency code
1911
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1912
- * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
1913
- */
1914
- async fetchDepositAddress(code, params = {}) {
1915
- await this.loadMarkets();
1916
- const currency = this.currency(code);
1917
- const request = {
1918
- 'coin': currency['id'],
1919
- };
1920
- const response = await this.privateGetV2DepositAddress(this.extend(request, params));
1921
- //
1922
- // { "address":"0x97d64eb014ac779194991e7264f01c74c90327f0" }
1923
- //
1924
- return this.parseDepositAddress(response, currency);
1925
- }
1926
- parseDepositAddress(depositAddress, currency = undefined) {
1927
- const address = this.safeString(depositAddress, 'address');
1928
- this.checkAddress(address);
1929
- currency = this.safeCurrency(undefined, currency);
1930
- return {
1931
- 'info': depositAddress,
1932
- 'currency': currency['code'],
1933
- 'network': undefined,
1934
- 'address': address,
1935
- 'tag': undefined,
1936
- };
1937
- }
1938
- sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1939
- let url = this.urls['api'][api] + '/' + path;
1940
- if (path === 'historicalTrades') {
1941
- headers = {
1942
- 'X-MBX-APIKEY': this.apiKey,
1943
- };
1944
- }
1945
- if (api === 'private') {
1946
- this.checkRequiredCredentials();
1947
- let query = this.urlencode(this.extend({
1948
- 'timestamp': this.nonce(),
1949
- 'recvWindow': this.options['recvWindow'],
1950
- }, params));
1951
- const signature = this.hmac(this.encode(query), this.encode(this.secret), sha256);
1952
- query += '&' + 'signature=' + signature;
1953
- headers = {
1954
- 'X-MBX-APIKEY': this.apiKey,
1955
- };
1956
- if ((method === 'GET') || (method === 'DELETE')) {
1957
- url += '?' + query;
1958
- }
1959
- else {
1960
- body = query;
1961
- headers['Content-Type'] = 'application/x-www-form-urlencoded';
1962
- }
1963
- }
1964
- else {
1965
- if (Object.keys(params).length) {
1966
- url += '?' + this.urlencode(params);
1967
- }
1968
- }
1969
- url = this.implodeHostname(url);
1970
- return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1971
- }
1972
- /**
1973
- * @method
1974
- * @name currencycom#fetchPositions
1975
- * @description fetch all open positions
1976
- * @see https://apitradedoc.currency.com/swagger-ui.html#/rest-api/tradingPositionsUsingGET
1977
- * @param {string[]|undefined} symbols list of unified market symbols
1978
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1979
- * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
1980
- */
1981
- async fetchPositions(symbols = undefined, params = {}) {
1982
- await this.loadMarkets();
1983
- const response = await this.privateGetV2TradingPositions(params);
1984
- //
1985
- // {
1986
- // "positions": [
1987
- // {
1988
- // "accountId": "109698017416453793",
1989
- // "id": "00a18490-0079-54c4-0000-0000803e73d3",
1990
- // "instrumentId": "45463225268524228",
1991
- // "orderId": "00a18490-0079-54c4-0000-0000803e73d2",
1992
- // "openQuantity": "13.6",
1993
- // "openPrice": "0.75724",
1994
- // "closeQuantity": "0.0",
1995
- // "closePrice": "0",
1996
- // "rpl": "-0.007723848",
1997
- // "rplConverted": "0",
1998
- // "upl": "-0.006664",
1999
- // "uplConverted": "-0.006664",
2000
- // "swap": "0",
2001
- // "swapConverted": "0",
2002
- // "fee": "-0.007723848",
2003
- // "dividend": "0",
2004
- // "margin": "0.2",
2005
- // "state": "ACTIVE",
2006
- // "currency": "USD",
2007
- // "createdTimestamp": "1645473877236",
2008
- // "openTimestamp": "1645473877193",
2009
- // "type": "NET",
2010
- // "cost": "2.0583600",
2011
- // "symbol": "XRP/USD_LEVERAGE"
2012
- // }
2013
- // ]
2014
- // }
2015
- //
2016
- const data = this.safeList(response, 'positions', []);
2017
- return this.parsePositions(data, symbols);
2018
- }
2019
- parsePosition(position, market = undefined) {
2020
- //
2021
- // {
2022
- // "accountId": "109698017416453793",
2023
- // "id": "00a18490-0079-54c4-0000-0000803e73d3",
2024
- // "instrumentId": "45463225268524228",
2025
- // "orderId": "00a18490-0079-54c4-0000-0000803e73d2",
2026
- // "openQuantity": "13.6",
2027
- // "openPrice": "0.75724",
2028
- // "closeQuantity": "0.0",
2029
- // "closePrice": "0",
2030
- // "rpl": "-0.007723848",
2031
- // "rplConverted": "0",
2032
- // "upl": "-0.006664",
2033
- // "uplConverted": "-0.006664",
2034
- // "swap": "0",
2035
- // "swapConverted": "0",
2036
- // "fee": "-0.007723848",
2037
- // "dividend": "0",
2038
- // "margin": "0.2",
2039
- // "state": "ACTIVE",
2040
- // "currency": "USD",
2041
- // "createdTimestamp": "1645473877236",
2042
- // "openTimestamp": "1645473877193",
2043
- // "type": "NET",
2044
- // "cost": "2.0583600",
2045
- // "symbol": "XRP/USD_LEVERAGE"
2046
- // }
2047
- //
2048
- market = this.safeMarket(this.safeString(position, 'symbol'), market);
2049
- const symbol = market['symbol'];
2050
- const timestamp = this.safeInteger(position, 'createdTimestamp');
2051
- const quantityRaw = this.safeString(position, 'openQuantity');
2052
- const side = Precise.stringGt(quantityRaw, '0') ? 'long' : 'short';
2053
- const quantity = Precise.stringAbs(quantityRaw);
2054
- const entryPrice = this.safeNumber(position, 'openPrice');
2055
- const unrealizedProfit = this.safeNumber(position, 'upl');
2056
- const marginCoeff = this.safeString(position, 'margin');
2057
- const leverage = Precise.stringDiv('1', marginCoeff);
2058
- return this.safePosition({
2059
- 'info': position,
2060
- 'symbol': symbol,
2061
- 'timestamp': timestamp,
2062
- 'datetime': this.iso8601(timestamp),
2063
- 'lastUpdateTimestamp': undefined,
2064
- 'contracts': this.parseNumber(quantity),
2065
- 'contractSize': undefined,
2066
- 'entryPrice': entryPrice,
2067
- 'collateral': undefined,
2068
- 'side': side,
2069
- // 'realizedProfit': this.safeNumber (position, 'rpl'),
2070
- 'unrealizedPnl': unrealizedProfit,
2071
- 'leverage': leverage,
2072
- 'percentage': undefined,
2073
- 'marginMode': undefined,
2074
- 'notional': undefined,
2075
- 'markPrice': undefined,
2076
- 'lastPrice': undefined,
2077
- 'liquidationPrice': undefined,
2078
- 'initialMargin': undefined,
2079
- 'initialMarginPercentage': undefined,
2080
- 'maintenanceMargin': this.parseNumber(marginCoeff),
2081
- 'maintenanceMarginPercentage': undefined,
2082
- 'marginRatio': undefined,
2083
- 'id': undefined,
2084
- 'hedged': undefined,
2085
- 'stopLossPrice': undefined,
2086
- 'takeProfitPrice': undefined,
2087
- });
2088
- }
2089
- handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2090
- if ((httpCode === 418) || (httpCode === 429)) {
2091
- throw new DDoSProtection(this.id + ' ' + httpCode.toString() + ' ' + reason + ' ' + body);
2092
- }
2093
- // error response in a form: { "code": -1013, "msg": "Invalid quantity." }
2094
- // following block cointains legacy checks against message patterns in "msg" property
2095
- // will switch "code" checks eventually, when we know all of them
2096
- if (httpCode >= 400) {
2097
- if (body.indexOf('Price * QTY is zero or less') >= 0) {
2098
- throw new InvalidOrder(this.id + ' order cost = amount * price is zero or less ' + body);
2099
- }
2100
- if (body.indexOf('LOT_SIZE') >= 0) {
2101
- throw new InvalidOrder(this.id + ' order amount should be evenly divisible by lot size ' + body);
2102
- }
2103
- if (body.indexOf('PRICE_FILTER') >= 0) {
2104
- throw new InvalidOrder(this.id + ' order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use this.priceToPrecision (symbol, amount) ' + body);
2105
- }
2106
- }
2107
- if (response === undefined) {
2108
- return undefined; // fallback to default error handler
2109
- }
2110
- //
2111
- // {"code":-1128,"msg":"Combination of optional parameters invalid."}
2112
- //
2113
- const errorCode = this.safeString(response, 'code');
2114
- if ((errorCode !== undefined) && (errorCode !== '0')) {
2115
- const feedback = this.id + ' ' + this.json(response);
2116
- this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
2117
- const message = this.safeString(response, 'msg');
2118
- this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
2119
- throw new ExchangeError(feedback);
2120
- }
2121
- return undefined;
2122
- }
2123
- }