ccxt-ir 4.9.31 → 4.10.0

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.
@@ -0,0 +1,324 @@
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/asretether.js';
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * @class asretether
12
+ * @augments Exchange
13
+ * @description Set rateLimit to 1000 if fully verified
14
+ */
15
+ export default class asretether extends Exchange {
16
+ describe() {
17
+ return this.deepExtend(super.describe(), {
18
+ 'id': 'asretether',
19
+ 'name': 'Asretether',
20
+ 'countries': ['IR'],
21
+ 'rateLimit': 1000,
22
+ 'version': '2',
23
+ 'certified': false,
24
+ 'pro': false,
25
+ 'has': {
26
+ 'CORS': undefined,
27
+ 'spot': true,
28
+ 'margin': false,
29
+ 'swap': false,
30
+ 'future': false,
31
+ 'option': false,
32
+ 'addMargin': false,
33
+ 'cancelAllOrders': false,
34
+ 'cancelOrder': false,
35
+ 'cancelOrders': false,
36
+ 'createDepositAddress': false,
37
+ 'createOrder': false,
38
+ 'createStopLimitOrder': false,
39
+ 'createStopMarketOrder': false,
40
+ 'createStopOrder': false,
41
+ 'editOrder': false,
42
+ 'fetchBalance': false,
43
+ 'fetchBorrowInterest': false,
44
+ 'fetchBorrowRateHistories': false,
45
+ 'fetchBorrowRateHistory': false,
46
+ 'fetchClosedOrders': false,
47
+ 'fetchCrossBorrowRate': false,
48
+ 'fetchCrossBorrowRates': false,
49
+ 'fetchCurrencies': false,
50
+ 'fetchDepositAddress': false,
51
+ 'fetchDeposits': false,
52
+ 'fetchFundingHistory': false,
53
+ 'fetchFundingRate': false,
54
+ 'fetchFundingRateHistory': false,
55
+ 'fetchFundingRates': false,
56
+ 'fetchIndexOHLCV': false,
57
+ 'fetchIsolatedBorrowRate': false,
58
+ 'fetchIsolatedBorrowRates': false,
59
+ 'fetchL2OrderBook': false,
60
+ 'fetchL3OrderBook': false,
61
+ 'fetchLedger': false,
62
+ 'fetchLedgerEntry': false,
63
+ 'fetchLeverageTiers': false,
64
+ 'fetchMarkets': true,
65
+ 'fetchMarkOHLCV': false,
66
+ 'fetchMyTrades': false,
67
+ 'fetchOHLCV': false,
68
+ 'fetchOpenInterestHistory': false,
69
+ 'fetchOpenOrders': false,
70
+ 'fetchOrder': false,
71
+ 'fetchOrderBook': false,
72
+ 'fetchOrders': false,
73
+ 'fetchOrderTrades': false,
74
+ 'fetchPositions': false,
75
+ 'fetchPremiumIndexOHLCV': false,
76
+ 'fetchTicker': true,
77
+ 'fetchTickers': true,
78
+ 'fetchTime': false,
79
+ 'fetchTrades': false,
80
+ 'fetchTradingFee': false,
81
+ 'fetchTradingFees': false,
82
+ 'fetchWithdrawals': false,
83
+ 'otc': true,
84
+ 'setLeverage': false,
85
+ 'setMarginMode': false,
86
+ 'transfer': false,
87
+ 'withdraw': false,
88
+ },
89
+ 'comment': 'OTC market for USDT and other cryptocurrencies',
90
+ 'urls': {
91
+ 'logo': 'https://cdn.arz.digital/cr-odin/img/exchanges/asretether/64x64.png',
92
+ 'api': {
93
+ 'public': 'https://api.asretether.com',
94
+ },
95
+ 'www': 'https://asretether.com',
96
+ 'doc': [
97
+ 'https://api.asretether.com/docs',
98
+ ],
99
+ },
100
+ 'api': {
101
+ 'public': {
102
+ 'get': {
103
+ 'v2/market': 1,
104
+ },
105
+ },
106
+ },
107
+ 'fees': {
108
+ 'trading': {
109
+ 'tierBased': false,
110
+ 'percentage': true,
111
+ 'maker': this.parseNumber('0'),
112
+ 'taker': this.parseNumber('0'),
113
+ },
114
+ },
115
+ });
116
+ }
117
+ async fetchMarkets(params = {}) {
118
+ /**
119
+ * @method
120
+ * @name asretether#fetchMarkets
121
+ * @description retrieves data on all markets for asretether
122
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
123
+ * @returns {object[]} an array of objects representing market data
124
+ */
125
+ const response = await this.publicGetV2Market(params);
126
+ const data = this.safeList(response, 'data', []);
127
+ const result = [];
128
+ for (let i = 0; i < data.length; i++) {
129
+ const market = this.parseMarket(data[i]);
130
+ result.push(market);
131
+ }
132
+ return result;
133
+ }
134
+ parseMarket(market) {
135
+ // {
136
+ // id: 2,
137
+ // symbol: "USDT-IRT",
138
+ // status: "ACTIVE",
139
+ // high_24h: "181978",
140
+ // low_24h: "172874",
141
+ // irt_high_24h: 0,
142
+ // irt_low_24h: 0,
143
+ // change_24h: 0,
144
+ // volume_24h: 100000,
145
+ // price: {
146
+ // price_buy: "178410",
147
+ // price_sell: "176402",
148
+ // price_in_tether: "1.0000"
149
+ // },
150
+ // base_currency: {
151
+ // slug: "USDT",
152
+ // decimals: 6,
153
+ // full_name: "Tether",
154
+ // persian_name: "تتر",
155
+ // icon_url: "https://box.asretether.com/currency-icons/usdt.png"
156
+ // },
157
+ // quote_currency: {
158
+ // slug: "IRT",
159
+ // decimals: 0,
160
+ // full_name: "IR Toman",
161
+ // persian_name: "تومان",
162
+ // icon_url: "https://box.asretether.com/currency-icons/irt.png"
163
+ // }
164
+ // },
165
+ const id = this.safeString(market, 'symbol');
166
+ const baseCurrency = this.safeDict(market, 'base_currency', {});
167
+ const quoteCurrency = this.safeDict(market, 'quote_currency', {});
168
+ const baseId = this.safeString(baseCurrency, 'slug');
169
+ const quoteId = this.safeString(quoteCurrency, 'slug');
170
+ const base = this.safeCurrencyCode(baseId);
171
+ const quote = this.safeCurrencyCode(quoteId);
172
+ const basePrecision = this.safeInteger(baseCurrency, 'decimals');
173
+ const quotePrecision = this.safeInteger(quoteCurrency, 'decimals');
174
+ const status = this.safeString(market, 'status');
175
+ const enabled = status === 'ACTIVE';
176
+ return {
177
+ 'id': id,
178
+ 'symbol': base + '/' + quote,
179
+ 'base': base,
180
+ 'quote': quote,
181
+ 'settle': undefined,
182
+ 'baseId': baseId,
183
+ 'quoteId': quoteId,
184
+ 'settleId': undefined,
185
+ 'type': 'otc',
186
+ 'spot': false,
187
+ 'margin': false,
188
+ 'swap': false,
189
+ 'future': false,
190
+ 'option': false,
191
+ 'active': enabled,
192
+ 'contract': false,
193
+ 'linear': undefined,
194
+ 'inverse': undefined,
195
+ 'contractSize': undefined,
196
+ 'expiry': undefined,
197
+ 'expiryDatetime': undefined,
198
+ 'strike': undefined,
199
+ 'optionType': undefined,
200
+ 'precision': {
201
+ 'amount': basePrecision,
202
+ 'price': quotePrecision,
203
+ },
204
+ 'limits': {
205
+ 'leverage': {
206
+ 'min': undefined,
207
+ 'max': undefined,
208
+ },
209
+ 'amount': {
210
+ 'min': undefined,
211
+ 'max': undefined,
212
+ },
213
+ 'price': {
214
+ 'min': undefined,
215
+ 'max': undefined,
216
+ },
217
+ 'cost': {
218
+ 'min': undefined,
219
+ 'max': undefined,
220
+ },
221
+ },
222
+ 'created': undefined,
223
+ 'info': market,
224
+ };
225
+ }
226
+ async fetchTickers(symbols = undefined, params = {}) {
227
+ /**
228
+ * @method
229
+ * @name asretether#fetchTickers
230
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
231
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
232
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
233
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
234
+ */
235
+ await this.loadMarkets();
236
+ if (symbols !== undefined) {
237
+ symbols = this.marketSymbols(symbols);
238
+ }
239
+ const response = await this.publicGetV2Market(params);
240
+ const data = this.safeList(response, 'data', []);
241
+ const result = {};
242
+ for (let i = 0; i < data.length; i++) {
243
+ const ticker = this.parseTicker(data[i]);
244
+ const symbol = ticker['symbol'];
245
+ result[symbol] = ticker;
246
+ }
247
+ return this.filterByArrayTickers(result, 'symbol', symbols);
248
+ }
249
+ async fetchTicker(symbol, params = {}) {
250
+ /**
251
+ * @method
252
+ * @name asretether#fetchTicker
253
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
254
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
255
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
256
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
257
+ */
258
+ await this.loadMarkets();
259
+ const market = this.market(symbol);
260
+ const request = {
261
+ 'symbol': market['id'],
262
+ };
263
+ const response = await this.publicGetV2Market(request);
264
+ const data = this.safeList(response, 'data', []);
265
+ if (data.length > 0) {
266
+ return this.parseTicker(data[0], market);
267
+ }
268
+ throw new Error('Ticker not found');
269
+ }
270
+ parseTicker(ticker, market = undefined) {
271
+ const baseCurrency = this.safeDict(ticker, 'base_currency', {});
272
+ const quoteCurrency = this.safeDict(ticker, 'quote_currency', {});
273
+ const baseId = this.safeString(baseCurrency, 'slug');
274
+ const quoteId = this.safeString(quoteCurrency, 'slug');
275
+ const base = this.safeCurrencyCode(baseId);
276
+ const quote = this.safeCurrencyCode(quoteId);
277
+ const symbol = base + '/' + quote;
278
+ // Handle price selection based on quote currency
279
+ const price = this.safeDict(ticker, 'price', {});
280
+ let last = undefined;
281
+ if (quote === 'IRT') {
282
+ last = this.safeFloat(price, 'price_sell');
283
+ }
284
+ else if (quote === 'USDT') {
285
+ last = this.safeFloat(price, 'price_in_tether');
286
+ }
287
+ const high = this.safeFloat(ticker, 'high_24h');
288
+ const low = this.safeFloat(ticker, 'low_24h');
289
+ const baseVolume = this.safeFloat(ticker, 'volume_24h');
290
+ return this.safeTicker({
291
+ 'symbol': symbol,
292
+ 'timestamp': undefined,
293
+ 'datetime': undefined,
294
+ 'high': high,
295
+ 'low': low,
296
+ 'bid': undefined,
297
+ 'bidVolume': undefined,
298
+ 'ask': undefined,
299
+ 'askVolume': undefined,
300
+ 'vwap': undefined,
301
+ 'open': undefined,
302
+ 'close': last,
303
+ 'last': last,
304
+ 'previousClose': undefined,
305
+ 'change': this.safeFloat(ticker, 'change_24h'),
306
+ 'percentage': undefined,
307
+ 'average': undefined,
308
+ 'baseVolume': baseVolume,
309
+ 'quoteVolume': undefined,
310
+ 'info': ticker,
311
+ }, market);
312
+ }
313
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
314
+ let url = this.urls['api']['public'] + '/' + path;
315
+ const query = this.omit(params, this.extractParams(path));
316
+ query['limit'] = this.safeString(query, 'limit', '1000');
317
+ // Add query parameters if any remain
318
+ if (Object.keys(query).length) {
319
+ url = url + '?' + this.urlencode(query);
320
+ }
321
+ headers = { 'Content-Type': 'application/json' };
322
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
323
+ }
324
+ }
package/js/src/bit24.d.ts CHANGED
@@ -9,9 +9,12 @@ export default class bit24 extends Exchange {
9
9
  describe(): any;
10
10
  fetchMarkets(params?: {}): Promise<Market[]>;
11
11
  parseMarket(market: any): Market;
12
+ parseOtcMarket(market: any): Market;
12
13
  fetchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
13
14
  fetchTicker(symbol: string, params?: {}): Promise<Ticker>;
14
15
  parseTicker(ticker: any, market?: Market): Ticker;
16
+ parseOtcTicker(ticker: any, market?: Market): Ticker;
17
+ removeDuplicateValues(markets: Market[]): Promise<Market[]>;
15
18
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
16
19
  url: string;
17
20
  method: string;
package/js/src/bit24.js CHANGED
@@ -91,6 +91,7 @@ export default class bit24 extends Exchange {
91
91
  'logo': 'https://cdn.arz.digital/cr-odin/img/exchanges/bit24/64x64.png',
92
92
  'api': {
93
93
  'public': 'https://rest.bit24.cash',
94
+ 'otc': 'https://otc-api.bit24.cash',
94
95
  },
95
96
  'www': 'https://bit24.cash/',
96
97
  'doc': [
@@ -101,6 +102,7 @@ export default class bit24 extends Exchange {
101
102
  'public': {
102
103
  'get': {
103
104
  'pro/capi/v1/markets': 1,
105
+ 'api/v1/coins/simple-list': 1,
104
106
  },
105
107
  },
106
108
  },
@@ -117,6 +119,14 @@ export default class bit24 extends Exchange {
117
119
  * @returns {object[]} an array of objects representing market data
118
120
  */
119
121
  const result = [];
122
+ const OTCresponse = await this.publicGetApiV1CoinsSimpleList();
123
+ const OTCmarkets = this.safeDict(OTCresponse, 'data');
124
+ const OTCmarketList = this.safeList(OTCmarkets, 'results', []);
125
+ for (let i = 0; i < OTCmarketList.length; i++) {
126
+ const marketdata = OTCmarketList[i];
127
+ const market = this.parseOtcMarket(marketdata);
128
+ result.push(market);
129
+ }
120
130
  let page = 1;
121
131
  const limit = 100; // check Bit24 docs for max allowed per page
122
132
  while (true) {
@@ -137,7 +147,7 @@ export default class bit24 extends Exchange {
137
147
  }
138
148
  page += 1;
139
149
  }
140
- return result;
150
+ return this.removeDuplicateValues(result);
141
151
  }
142
152
  parseMarket(market) {
143
153
  // {
@@ -242,6 +252,68 @@ export default class bit24 extends Exchange {
242
252
  'info': market,
243
253
  };
244
254
  }
255
+ parseOtcMarket(market) {
256
+ // {
257
+ // symbol: "0G",
258
+ // name: "0G"
259
+ // },
260
+ let baseId = this.safeString(market, 'symbol');
261
+ let quoteId = 'IRT'; // assuming quote currency is always IRT for OTC markets
262
+ const base = this.safeCurrencyCode(baseId);
263
+ const quote = this.safeCurrencyCode(quoteId);
264
+ baseId = baseId.toLowerCase();
265
+ quoteId = quoteId.toLowerCase();
266
+ const id = baseId + '-' + quoteId;
267
+ return {
268
+ 'id': id,
269
+ 'symbol': base + '/' + quote,
270
+ 'base': base,
271
+ 'quote': quote,
272
+ 'settle': undefined,
273
+ 'baseId': baseId,
274
+ 'quoteId': quoteId,
275
+ 'settleId': undefined,
276
+ 'type': 'otc',
277
+ 'spot': false,
278
+ 'margin': false,
279
+ 'swap': false,
280
+ 'future': false,
281
+ 'option': false,
282
+ 'active': true,
283
+ 'contract': false,
284
+ 'linear': undefined,
285
+ 'inverse': undefined,
286
+ 'contractSize': undefined,
287
+ 'expiry': undefined,
288
+ 'expiryDatetime': undefined,
289
+ 'strike': undefined,
290
+ 'optionType': undefined,
291
+ 'precision': {
292
+ 'amount': undefined,
293
+ 'price': undefined,
294
+ },
295
+ 'limits': {
296
+ 'leverage': {
297
+ 'min': undefined,
298
+ 'max': undefined,
299
+ },
300
+ 'amount': {
301
+ 'min': undefined,
302
+ 'max': undefined,
303
+ },
304
+ 'price': {
305
+ 'min': undefined,
306
+ 'max': undefined,
307
+ },
308
+ 'cost': {
309
+ 'min': undefined,
310
+ 'max': undefined,
311
+ },
312
+ },
313
+ 'created': undefined,
314
+ 'info': market,
315
+ };
316
+ }
245
317
  async fetchTickers(symbols = undefined, params = {}) {
246
318
  /**
247
319
  * @method
@@ -256,9 +328,18 @@ export default class bit24 extends Exchange {
256
328
  if (symbols !== undefined) {
257
329
  symbols = this.marketSymbols(symbols);
258
330
  }
331
+ const result = {};
332
+ const Otcresponse = await this.publicGetApiV1CoinsSimpleList(params);
333
+ const Otcdata = this.safeDict(Otcresponse, 'data', {});
334
+ const OtctickerList = this.safeList(Otcdata, 'results', []);
335
+ for (let i = 0; i < OtctickerList.length; i++) {
336
+ const tickerData = OtctickerList[i];
337
+ const ticker = this.parseOtcTicker(tickerData);
338
+ const symbol = ticker['symbol'];
339
+ result[symbol] = ticker;
340
+ }
259
341
  let page = 1;
260
342
  const limit = 100; // adjust if Bit24 docs show a different default
261
- const result = {};
262
343
  while (true) {
263
344
  const response = await this.publicGetProCapiV1Markets(this.extend(params, {
264
345
  'page': page,
@@ -374,11 +455,65 @@ export default class bit24 extends Exchange {
374
455
  'info': ticker,
375
456
  }, market);
376
457
  }
458
+ parseOtcTicker(ticker, market = undefined) {
459
+ // {
460
+ // symbol: "0G",
461
+ // name: "0G"
462
+ // },
463
+ const marketType = 'otc';
464
+ let base_symbol = this.safeString(ticker, 'symbol');
465
+ base_symbol = base_symbol.toLowerCase();
466
+ const quote_symbol = 'irt'; // assuming quote currency is always IRT for OTC markets
467
+ const marketId = base_symbol + '-' + quote_symbol;
468
+ const symbol = this.safeSymbol(marketId, market, undefined, marketType);
469
+ return this.safeTicker({
470
+ 'symbol': symbol,
471
+ 'timestamp': undefined,
472
+ 'datetime': undefined,
473
+ 'high': undefined,
474
+ 'low': undefined,
475
+ 'bid': undefined,
476
+ 'bidVolume': undefined,
477
+ 'ask': undefined,
478
+ 'askVolume': undefined,
479
+ 'vwap': undefined,
480
+ 'open': undefined,
481
+ 'close': undefined,
482
+ 'last': undefined,
483
+ 'previousClose': undefined,
484
+ 'change': undefined,
485
+ 'percentage': undefined,
486
+ 'average': undefined,
487
+ 'baseVolume': undefined,
488
+ 'quoteVolume': undefined,
489
+ 'info': ticker,
490
+ }, market);
491
+ }
492
+ async removeDuplicateValues(markets) {
493
+ const uniqueMarkets = [];
494
+ const seenIds = new Set();
495
+ for (let i = 0; i < markets.length; i++) {
496
+ const market = markets[i];
497
+ if (!seenIds.has(market['id'])) {
498
+ seenIds.add(market['id']);
499
+ uniqueMarkets.push(market);
500
+ }
501
+ }
502
+ return uniqueMarkets;
503
+ }
377
504
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
505
+ if (path === 'api/v1/coins/simple-list') {
506
+ api = 'otc';
507
+ }
378
508
  const query = this.omit(params, this.extractParams(path));
379
509
  let url = this.urls['api'][api] + '/' + this.implodeParams(path, params);
380
510
  url = url + '?' + this.urlencode(query);
381
- headers = { 'Content-Type': 'application/json', 'X-BIT24-APIKEY': 'bdfa2c8c971445d5a4a95c95a5a2a4c2' };
511
+ if (api === 'otc') {
512
+ headers = { 'Content-Type': 'application/json' };
513
+ }
514
+ else {
515
+ headers = { 'Content-Type': 'application/json', 'X-BIT24-APIKEY': 'bdfa2c8c971445d5a4a95c95a5a2a4c2' };
516
+ }
382
517
  return { 'url': url, 'method': method, 'body': body, 'headers': headers };
383
518
  }
384
519
  }
@@ -9,9 +9,11 @@ export default class raastin extends Exchange {
9
9
  describe(): any;
10
10
  fetchMarkets(params?: {}): Promise<Market[]>;
11
11
  parseMarket(market: any): Market;
12
+ parseOtcMarket(market: any): Market;
12
13
  fetchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
13
14
  fetchTicker(symbol: string, params?: {}): Promise<Ticker>;
14
15
  parseTicker(ticker: any, market?: Market): Ticker;
16
+ parseOTCTicker(ticker: any, market?: Market): Ticker;
15
17
  fetchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
16
18
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
17
19
  url: string;