ccxt-ir 4.16.0 → 4.16.3

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.
@@ -4,306 +4,366 @@
4
4
  // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
5
  // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
6
 
7
- // ---------------------------------------------------------------------------
8
- import Exchange from './base/Exchange.js';
9
- import Precise from './base/Precise.js';
10
- // ---------------------------------------------------------------------------
11
- /**
12
- * @class asacoine
13
- * @augments Exchange
14
- */
15
- export default class asacoine extends Exchange {
16
- describe() {
17
- return this.deepExtend(super.describe(), {
18
- 'id': 'asacoine',
19
- 'name': 'Asacoine',
20
- 'countries': ['IR'],
21
- 'rateLimit': 1000,
22
- 'version': 'v1',
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
- 'fetchMarkets': true,
33
- 'fetchTicker': true,
34
- 'fetchTickers': true,
35
- 'otc': true,
36
- },
37
- 'urls': {
38
- 'logo': 'https://cdn.arz.digital/cr-odin/img/exchanges/asacoine/64x64.png',
39
- 'api': {
40
- 'public': 'https://api.asacoine.com/api',
41
- },
42
- 'www': 'https://asacoine.com',
43
- 'doc': 'https://api.asacoine.com/api/v1/market/pairs/pricing',
44
- },
45
- 'api': {
46
- 'public': {
47
- 'get': {
48
- 'v1/market/pairs/pricing': 1,
49
- 'v1/market/pairs/cumulative': 1,
50
- },
51
- },
52
- },
53
- 'commonCurrencies': {
54
- 'TMN': 'IRT',
55
- },
56
- 'fees': {
57
- 'trading': {
58
- 'tierBased': false,
59
- 'percentage': true,
60
- 'maker': this.parseNumber('0'),
61
- 'taker': this.parseNumber('0'),
62
- },
63
- },
64
- });
65
- }
66
- parseMarket(market) {
67
- const baseId = this.safeString(market, 'baseId');
68
- const quoteId = this.safeString(market, 'quoteId');
69
- const base = this.safeCurrencyCode(baseId);
70
- const quote = this.safeCurrencyCode(quoteId);
71
- const isOtc = this.safeString(market, 'type', 'spot') === 'otc';
72
- let marketType = 'spot';
73
- if (isOtc) {
74
- marketType = 'otc';
75
- }
76
- const suffix = '';
77
- return {
78
- 'id': baseId + '/' + quoteId + suffix,
79
- 'symbol': base + '/' + quote + suffix,
80
- 'base': base,
81
- 'quote': quote,
82
- 'settle': undefined,
83
- 'baseId': baseId,
84
- 'quoteId': quoteId,
85
- 'settleId': undefined,
86
- 'type': marketType,
87
- 'spot': !isOtc,
88
- 'margin': false,
89
- 'swap': false,
90
- 'future': false,
91
- 'option': false,
92
- 'active': true,
93
- 'contract': false,
94
- 'linear': undefined,
95
- 'inverse': undefined,
96
- 'contractSize': undefined,
97
- 'expiry': undefined,
98
- 'expiryDatetime': undefined,
99
- 'strike': undefined,
100
- 'optionType': undefined,
101
- 'precision': {
102
- 'amount': undefined,
103
- 'price': undefined,
104
- },
105
- 'limits': {
106
- 'leverage': {
107
- 'min': undefined,
108
- 'max': undefined,
109
- },
110
- 'amount': {
111
- 'min': undefined,
112
- 'max': undefined,
113
- },
114
- 'price': {
115
- 'min': undefined,
116
- 'max': undefined,
117
- },
118
- 'cost': {
119
- 'min': undefined,
120
- 'max': undefined,
121
- },
122
- },
123
- 'created': undefined,
124
- 'info': this.safeValue(market, 'info', market),
125
- };
126
- }
127
- parseMarkets(response) {
128
- const data = this.safeDict(response, 'data', {});
129
- const baseIds = Object.keys(data);
130
- const result = [];
131
- for (let i = 0; i < baseIds.length; i++) {
132
- const baseId = baseIds[i];
133
- const quotes = this.safeDict(data, baseId, {});
134
- const quoteIds = Object.keys(quotes);
135
- for (let j = 0; j < quoteIds.length; j++) {
136
- const quoteId = quoteIds[j];
137
- const ticker = this.safeDict(quotes, quoteId, {});
138
- result.push(this.parseMarket({ 'baseId': baseId, 'quoteId': quoteId, 'info': ticker, 'type': 'spot' }));
139
- }
140
- }
141
- return result;
142
- }
143
- parseCumulativeMarkets(response, type = 'otc') {
144
- const data = this.safeDict(response, 'data', {});
145
- const keys = this.safeList(data, 'keys', []);
146
- const values = this.safeList(data, 'values', []);
147
- const result = [];
148
- for (let i = 0; i < values.length; i++) {
149
- const row = values[i];
150
- const market = {};
151
- for (let j = 0; j < keys.length; j++) {
152
- market[keys[j]] = row[j];
153
- }
154
- const marketTypes = this.safeList(market, 'marketTypes', []);
155
- if (!this.inArray(type, marketTypes)) {
156
- continue;
157
- }
158
- const name = this.safeString(market, 'name');
159
- const [baseId, quoteId] = name.split('-');
160
- market['baseId'] = baseId;
161
- market['quoteId'] = quoteId;
162
- market['type'] = type;
163
- result.push(this.parseMarket(market));
164
- }
165
- return result;
166
- }
167
- async fetchMarkets(params = {}) {
168
- /**
169
- * @method
170
- * @name asacoine#fetchMarkets
171
- * @description retrieves data on all markets for asacoine
172
- * @see https://api.asacoine.com/api/v1/market/pairs/pricing
173
- * @param {object} [params] extra parameters specific to the exchange API endpoint
174
- * @returns {object[]} an array of objects representing market data
175
- */
176
- const type = this.safeString(params, 'type', 'spot');
177
- const request = this.omit(params, ['type']);
178
- if (type === 'otc') {
179
- const cumulativeResponse = await this.publicGetV1MarketPairsCumulative(request);
180
- return this.parseCumulativeMarkets(cumulativeResponse, type);
181
- }
182
- const response = await this.publicGetV1MarketPairsPricing(request);
183
- return this.parseMarkets(response);
184
- }
185
- parseTicker(ticker, market = undefined) {
186
- const bid = this.safeList(ticker, 'bid', []);
187
- const ask = this.safeList(ticker, 'ask', []);
188
- const nestedOrderBook = this.safeDict(ticker, 'orderBook');
189
- const cumulativeOrderBook = nestedOrderBook === undefined && this.safeString(ticker, 'bestBid') !== undefined ? ticker : nestedOrderBook;
190
- const orderBook = cumulativeOrderBook === undefined ? {} : cumulativeOrderBook;
191
- const bidPriceString = cumulativeOrderBook === undefined ? this.safeString(bid, 0) : this.safeString(orderBook, 'bestBid');
192
- const askPriceString = cumulativeOrderBook === undefined ? this.safeString(ask, 0) : this.safeString(orderBook, 'bestAsk');
193
- const bidPrice = this.parseNumber(bidPriceString);
194
- const askPrice = this.parseNumber(askPriceString);
195
- const bidVolume = cumulativeOrderBook === undefined ? this.safeNumber(bid, 1) : this.safeNumber(orderBook, 'bidSize');
196
- const askVolume = cumulativeOrderBook === undefined ? this.safeNumber(ask, 1) : this.safeNumber(orderBook, 'askSize');
197
- let last = undefined;
198
- if ((bidPriceString !== undefined) && (askPriceString !== undefined)) {
199
- last = this.parseNumber(Precise.stringDiv(Precise.stringAdd(bidPriceString, askPriceString), '2'));
200
- }
201
- return this.safeTicker({
202
- 'symbol': this.safeString(market, 'symbol'),
203
- 'timestamp': undefined,
204
- 'datetime': undefined,
205
- 'high': undefined,
206
- 'low': undefined,
207
- 'bid': bidPrice,
208
- 'bidVolume': bidVolume,
209
- 'ask': askPrice,
210
- 'askVolume': askVolume,
211
- 'vwap': undefined,
212
- 'open': undefined,
213
- 'close': last,
214
- 'last': last,
215
- 'previousClose': undefined,
216
- 'change': undefined,
217
- 'percentage': undefined,
218
- 'average': last,
219
- 'baseVolume': undefined,
220
- 'quoteVolume': undefined,
221
- 'info': ticker,
222
- }, market);
223
- }
224
- async fetchTickers(symbols = undefined, params = {}) {
225
- /**
226
- * @method
227
- * @name asacoine#fetchTickers
228
- * @description fetches price tickers for multiple markets
229
- * @see https://api.asacoine.com/api/v1/market/pairs/pricing
230
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the tickers for, all market tickers are returned if not assigned
231
- * @param {object} [params] extra parameters specific to the exchange API endpoint
232
- * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
233
- */
234
- const type = this.safeString(params, 'type', 'spot');
235
- const request = this.omit(params, ['type']);
236
- await this.loadMarkets(false, { 'type': type });
237
- if (symbols !== undefined) {
238
- symbols = this.marketSymbols(symbols);
239
- }
240
- let response;
241
- if (type === 'otc') {
242
- response = await this.publicGetV1MarketPairsCumulative(request);
243
- }
244
- else {
245
- response = await this.publicGetV1MarketPairsPricing(request);
246
- }
247
- if (type === 'otc') {
248
- const cumulativeData = this.safeDict(response, 'data', {});
249
- const keys = this.safeList(cumulativeData, 'keys', []);
250
- const values = this.safeList(cumulativeData, 'values', []);
251
- const cumulativeTickers = {};
252
- for (let i = 0; i < values.length; i++) {
253
- const row = values[i];
254
- const raw = {};
255
- for (let j = 0; j < keys.length; j++) {
256
- raw[keys[j]] = row[j];
257
- }
258
- const name = this.safeString(raw, 'name');
259
- const [baseId, quoteId] = name.split('-');
260
- const base = this.safeCurrencyCode(baseId);
261
- const quote = this.safeCurrencyCode(quoteId);
262
- const market = this.safeMarket(base + '/' + quote);
263
- const parsed = this.parseTicker(this.safeDict(raw, 'orderBook', {}), market);
264
- cumulativeTickers[parsed['symbol']] = parsed;
265
- }
266
- return this.filterByArrayTickers(cumulativeTickers, 'symbol', symbols);
267
- }
268
- const data = this.safeDict(response, 'data', {});
269
- const baseIds = Object.keys(data);
270
- const result = {};
271
- for (let i = 0; i < baseIds.length; i++) {
272
- const baseId = baseIds[i];
273
- const quotes = this.safeDict(data, baseId, {});
274
- const quoteIds = Object.keys(quotes);
275
- for (let j = 0; j < quoteIds.length; j++) {
276
- const quoteId = quoteIds[j];
277
- const ticker = this.safeDict(quotes, quoteId, {});
278
- const market = this.safeMarket(baseId + '/' + quoteId);
279
- const parsed = this.parseTicker(ticker, market);
280
- result[parsed['symbol']] = parsed;
281
- }
282
- }
283
- return this.filterByArrayTickers(result, 'symbol', symbols);
284
- }
285
- async fetchTicker(symbol, params = {}) {
286
- /**
287
- * @method
288
- * @name asacoine#fetchTicker
289
- * @description fetches a price ticker, a statistical calculation for a specific market
290
- * @see https://api.asacoine.com/api/v1/market/pairs/pricing
291
- * @param {string} symbol unified symbol of the market to fetch the ticker for
292
- * @param {object} [params] extra parameters specific to the exchange API endpoint
293
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
294
- */
295
- const tickers = await this.fetchTickers([symbol], params);
296
- return tickers[symbol];
297
- }
298
- sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
299
- const query = this.omit(params, this.extractParams(path));
300
- let url = this.urls['api'][api] + '/' + this.implodeParams(path, params);
301
- if (Object.keys(query).length) {
302
- url += '?' + this.urlencode(query);
303
- }
304
- headers = {
305
- 'Content-Type': 'application/json',
306
- };
307
- return { 'url': url, 'method': method, 'body': body, 'headers': headers };
308
- }
309
- }
7
+ // ---------------------------------------------------------------------------
8
+ import Exchange from './base/Exchange.js';
9
+ import Precise from './base/Precise.js';
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * @class asacoine
13
+ * @augments Exchange
14
+ */
15
+ export default class asacoine extends Exchange {
16
+ describe() {
17
+ return this.deepExtend(super.describe(), {
18
+ 'id': 'asacoine',
19
+ 'name': 'Asacoine',
20
+ 'countries': ['IR'],
21
+ 'rateLimit': 1000,
22
+ 'version': 'v1',
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
+ 'fetchMarkets': true,
33
+ 'fetchTicker': true,
34
+ 'fetchTickers': true,
35
+ 'otc': true,
36
+ },
37
+ 'urls': {
38
+ 'logo': 'https://cdn.arz.digital/cr-odin/img/exchanges/asacoine/64x64.png',
39
+ 'api': {
40
+ 'public': 'https://api.asacoine.com/api',
41
+ },
42
+ 'www': 'https://asacoine.com',
43
+ 'doc': 'https://api.asacoine.com/api/v1/market/pairs/pricing',
44
+ },
45
+ 'api': {
46
+ 'public': {
47
+ 'get': {
48
+ 'v1/market/pairs/pricing': 1,
49
+ 'v1/market/pairs/cumulative': 1,
50
+ },
51
+ },
52
+ },
53
+ 'commonCurrencies': {
54
+ 'TMN': 'IRT',
55
+ },
56
+ 'fees': {
57
+ 'trading': {
58
+ 'tierBased': false,
59
+ 'percentage': true,
60
+ 'maker': this.parseNumber('0'),
61
+ 'taker': this.parseNumber('0'),
62
+ },
63
+ },
64
+ });
65
+ }
66
+ parseMarket(market) {
67
+ const baseId = this.safeString(market, 'baseId');
68
+ const quoteId = this.safeString(market, 'quoteId');
69
+ const base = this.safeCurrencyCode(baseId);
70
+ const quote = this.safeCurrencyCode(quoteId);
71
+ return {
72
+ 'id': baseId + '/' + quoteId,
73
+ 'symbol': base + '/' + quote,
74
+ 'base': base,
75
+ 'quote': quote,
76
+ 'settle': undefined,
77
+ 'baseId': baseId,
78
+ 'quoteId': quoteId,
79
+ 'settleId': undefined,
80
+ 'type': 'spot',
81
+ 'spot': true,
82
+ 'margin': false,
83
+ 'swap': false,
84
+ 'future': false,
85
+ 'option': false,
86
+ 'active': true,
87
+ 'contract': false,
88
+ 'linear': undefined,
89
+ 'inverse': undefined,
90
+ 'contractSize': undefined,
91
+ 'expiry': undefined,
92
+ 'expiryDatetime': undefined,
93
+ 'strike': undefined,
94
+ 'optionType': undefined,
95
+ 'precision': {
96
+ 'amount': undefined,
97
+ 'price': undefined,
98
+ },
99
+ 'limits': {
100
+ 'leverage': {
101
+ 'min': undefined,
102
+ 'max': undefined,
103
+ },
104
+ 'amount': {
105
+ 'min': undefined,
106
+ 'max': undefined,
107
+ },
108
+ 'price': {
109
+ 'min': undefined,
110
+ 'max': undefined,
111
+ },
112
+ 'cost': {
113
+ 'min': undefined,
114
+ 'max': undefined,
115
+ },
116
+ },
117
+ 'created': undefined,
118
+ 'info': this.safeValue(market, 'info', market),
119
+ };
120
+ }
121
+ parseOtcMarket(market) {
122
+ const baseId = this.safeString(market, 'baseId');
123
+ const quoteId = this.safeString(market, 'quoteId');
124
+ const base = this.safeCurrencyCode(baseId);
125
+ const quote = this.safeCurrencyCode(quoteId);
126
+ return {
127
+ 'id': baseId + '/' + quoteId,
128
+ 'symbol': base + '/' + quote,
129
+ 'base': base,
130
+ 'quote': quote,
131
+ 'settle': undefined,
132
+ 'baseId': baseId,
133
+ 'quoteId': quoteId,
134
+ 'settleId': undefined,
135
+ 'type': 'otc',
136
+ 'spot': false,
137
+ 'margin': false,
138
+ 'swap': false,
139
+ 'future': false,
140
+ 'option': false,
141
+ 'active': true,
142
+ 'contract': false,
143
+ 'linear': undefined,
144
+ 'inverse': undefined,
145
+ 'contractSize': undefined,
146
+ 'expiry': undefined,
147
+ 'expiryDatetime': undefined,
148
+ 'strike': undefined,
149
+ 'optionType': undefined,
150
+ 'precision': {
151
+ 'amount': undefined,
152
+ 'price': undefined,
153
+ },
154
+ 'limits': {
155
+ 'leverage': {
156
+ 'min': undefined,
157
+ 'max': undefined,
158
+ },
159
+ 'amount': {
160
+ 'min': undefined,
161
+ 'max': undefined,
162
+ },
163
+ 'price': {
164
+ 'min': undefined,
165
+ 'max': undefined,
166
+ },
167
+ 'cost': {
168
+ 'min': undefined,
169
+ 'max': undefined,
170
+ },
171
+ },
172
+ 'created': undefined,
173
+ 'info': this.safeValue(market, 'info', market),
174
+ };
175
+ }
176
+ parseMarkets(response) {
177
+ const data = this.safeDict(response, 'data', {});
178
+ const baseIds = Object.keys(data);
179
+ const result = [];
180
+ for (let i = 0; i < baseIds.length; i++) {
181
+ const baseId = baseIds[i];
182
+ const quotes = this.safeDict(data, baseId, {});
183
+ const quoteIds = Object.keys(quotes);
184
+ for (let j = 0; j < quoteIds.length; j++) {
185
+ const quoteId = quoteIds[j];
186
+ const ticker = this.safeDict(quotes, quoteId, {});
187
+ result.push(this.parseMarket({ 'baseId': baseId, 'quoteId': quoteId, 'info': ticker }));
188
+ }
189
+ }
190
+ return result;
191
+ }
192
+ parseCumulativeMarkets(response) {
193
+ const data = this.safeDict(response, 'data', {});
194
+ const keys = this.safeList(data, 'keys', []);
195
+ const values = this.safeList(data, 'values', []);
196
+ const result = [];
197
+ for (let i = 0; i < values.length; i++) {
198
+ const row = values[i];
199
+ const market = {};
200
+ for (let j = 0; j < keys.length; j++) {
201
+ market[keys[j]] = row[j];
202
+ }
203
+ const marketTypes = this.safeList(market, 'marketTypes', []);
204
+ if (!this.inArray('otc', marketTypes)) {
205
+ continue;
206
+ }
207
+ const name = this.safeString(market, 'name');
208
+ const [baseId, quoteId] = name.split('-');
209
+ market['baseId'] = baseId;
210
+ market['quoteId'] = quoteId;
211
+ result.push(this.parseOtcMarket(market));
212
+ }
213
+ return result;
214
+ }
215
+ async fetchMarkets(params = {}) {
216
+ /**
217
+ * @method
218
+ * @name asacoine#fetchMarkets
219
+ * @description retrieves data on all markets for asacoine
220
+ * @see https://api.asacoine.com/api/v1/market/pairs/pricing
221
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
222
+ * @returns {object[]} an array of objects representing market data
223
+ */
224
+ const type = this.safeString(params, 'type', 'spot');
225
+ const request = this.omit(params, ['type']);
226
+ if (type === 'otc') {
227
+ const cumulativeResponse = await this.publicGetV1MarketPairsCumulative(request);
228
+ return this.parseCumulativeMarkets(cumulativeResponse);
229
+ }
230
+ const response = await this.publicGetV1MarketPairsPricing(request);
231
+ return this.parseMarkets(response);
232
+ }
233
+ parseTicker(ticker, market = undefined) {
234
+ const bid = this.safeList(ticker, 'bid', []);
235
+ const ask = this.safeList(ticker, 'ask', []);
236
+ const nestedOrderBook = this.safeDict(ticker, 'orderBook');
237
+ let cumulativeOrderBook = nestedOrderBook;
238
+ if ((nestedOrderBook === undefined) && (this.safeString(ticker, 'bestBid') !== undefined)) {
239
+ cumulativeOrderBook = ticker;
240
+ }
241
+ let orderBook = cumulativeOrderBook;
242
+ if (orderBook === undefined) {
243
+ orderBook = {};
244
+ }
245
+ let bidPriceString = this.safeString(orderBook, 'bestBid');
246
+ let askPriceString = this.safeString(orderBook, 'bestAsk');
247
+ let bidVolume = this.safeNumber(orderBook, 'bidSize');
248
+ let askVolume = this.safeNumber(orderBook, 'askSize');
249
+ if (cumulativeOrderBook === undefined) {
250
+ bidPriceString = this.safeString(bid, 0);
251
+ askPriceString = this.safeString(ask, 0);
252
+ bidVolume = this.safeNumber(bid, 1);
253
+ askVolume = this.safeNumber(ask, 1);
254
+ }
255
+ const bidPrice = this.parseNumber(bidPriceString);
256
+ const askPrice = this.parseNumber(askPriceString);
257
+ let last = undefined;
258
+ if ((bidPriceString !== undefined) && (askPriceString !== undefined)) {
259
+ last = this.parseNumber(Precise.stringDiv(Precise.stringAdd(bidPriceString, askPriceString), '2'));
260
+ }
261
+ return this.safeTicker({
262
+ 'symbol': this.safeString(market, 'symbol'),
263
+ 'timestamp': undefined,
264
+ 'datetime': undefined,
265
+ 'high': undefined,
266
+ 'low': undefined,
267
+ 'bid': bidPrice,
268
+ 'bidVolume': bidVolume,
269
+ 'ask': askPrice,
270
+ 'askVolume': askVolume,
271
+ 'vwap': undefined,
272
+ 'open': undefined,
273
+ 'close': last,
274
+ 'last': last,
275
+ 'previousClose': undefined,
276
+ 'change': undefined,
277
+ 'percentage': undefined,
278
+ 'average': last,
279
+ 'baseVolume': undefined,
280
+ 'quoteVolume': undefined,
281
+ 'info': ticker,
282
+ }, market);
283
+ }
284
+ async fetchTickers(symbols = undefined, params = {}) {
285
+ /**
286
+ * @method
287
+ * @name asacoine#fetchTickers
288
+ * @description fetches price tickers for multiple markets
289
+ * @see https://api.asacoine.com/api/v1/market/pairs/pricing
290
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the tickers for, all market tickers are returned if not assigned
291
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
292
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
293
+ */
294
+ const type = this.safeString(params, 'type', 'spot');
295
+ const request = this.omit(params, ['type']);
296
+ await this.loadMarkets(false, { 'type': type });
297
+ if (symbols !== undefined) {
298
+ symbols = this.marketSymbols(symbols);
299
+ }
300
+ let response = {};
301
+ if (type === 'otc') {
302
+ response = await this.publicGetV1MarketPairsCumulative(request);
303
+ }
304
+ else {
305
+ response = await this.publicGetV1MarketPairsPricing(request);
306
+ }
307
+ if (type === 'otc') {
308
+ const cumulativeData = this.safeDict(response, 'data', {});
309
+ const keys = this.safeList(cumulativeData, 'keys', []);
310
+ const values = this.safeList(cumulativeData, 'values', []);
311
+ const cumulativeTickers = {};
312
+ for (let i = 0; i < values.length; i++) {
313
+ const row = values[i];
314
+ const raw = {};
315
+ for (let j = 0; j < keys.length; j++) {
316
+ raw[keys[j]] = row[j];
317
+ }
318
+ const name = this.safeString(raw, 'name');
319
+ const [baseId, quoteId] = name.split('-');
320
+ const base = this.safeCurrencyCode(baseId);
321
+ const quote = this.safeCurrencyCode(quoteId);
322
+ const market = this.safeMarket(base + '/' + quote);
323
+ const parsed = this.parseTicker(this.safeDict(raw, 'orderBook', {}), market);
324
+ cumulativeTickers[parsed['symbol']] = parsed;
325
+ }
326
+ return this.filterByArrayTickers(cumulativeTickers, 'symbol', symbols);
327
+ }
328
+ const data = this.safeDict(response, 'data', {});
329
+ const baseIds = Object.keys(data);
330
+ const result = {};
331
+ for (let i = 0; i < baseIds.length; i++) {
332
+ const baseId = baseIds[i];
333
+ const quotes = this.safeDict(data, baseId, {});
334
+ const quoteIds = Object.keys(quotes);
335
+ for (let j = 0; j < quoteIds.length; j++) {
336
+ const quoteId = quoteIds[j];
337
+ const ticker = this.safeDict(quotes, quoteId, {});
338
+ const market = this.safeMarket(baseId + '/' + quoteId);
339
+ const parsed = this.parseTicker(ticker, market);
340
+ result[parsed['symbol']] = parsed;
341
+ }
342
+ }
343
+ return this.filterByArrayTickers(result, 'symbol', symbols);
344
+ }
345
+ async fetchTicker(symbol, params = {}) {
346
+ /**
347
+ * @method
348
+ * @name asacoine#fetchTicker
349
+ * @description fetches a price ticker, a statistical calculation for a specific market
350
+ * @see https://api.asacoine.com/api/v1/market/pairs/pricing
351
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
352
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
353
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
354
+ */
355
+ const tickers = await this.fetchTickers([symbol], params);
356
+ return tickers[symbol];
357
+ }
358
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
359
+ const query = this.omit(params, this.extractParams(path));
360
+ let url = this.urls['api'][api] + '/' + this.implodeParams(path, params);
361
+ if (Object.keys(query).length) {
362
+ url += '?' + this.urlencode(query);
363
+ }
364
+ headers = {
365
+ 'Content-Type': 'application/json',
366
+ };
367
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
368
+ }
369
+ }