ccxt 4.0.86 → 4.0.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/js/src/exmo.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/exmo.js';
9
- import { ArgumentsRequired, ExchangeError, OrderNotFound, AuthenticationError, InsufficientFunds, InvalidOrder, InvalidNonce, OnMaintenance, RateLimitExceeded, BadRequest, PermissionDenied } from './base/errors.js';
9
+ import { ExchangeError, OrderNotFound, AuthenticationError, InsufficientFunds, InvalidOrder, InvalidNonce, OnMaintenance, RateLimitExceeded, BadRequest, PermissionDenied } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { TICK_SIZE } from './base/functions/number.js';
12
12
  import { sha512 } from './static_dependencies/noble-hashes/sha512.js';
@@ -1176,18 +1176,35 @@ export default class exmo extends Exchange {
1176
1176
  // "commission_percent": "0.2"
1177
1177
  // }
1178
1178
  //
1179
+ // fetchMyTrades (margin)
1180
+ //
1181
+ // {
1182
+ // "trade_id": "692861757015952517",
1183
+ // "trade_dt": "1693951853197811824",
1184
+ // "trade_type": "buy",
1185
+ // "pair": "ADA_USDT",
1186
+ // "quantity": "1.96607879",
1187
+ // "price": "0.2568",
1188
+ // "amount": "0.50488903"
1189
+ // }
1190
+ //
1179
1191
  const timestamp = this.safeTimestamp(trade, 'date');
1180
1192
  const id = this.safeString(trade, 'trade_id');
1181
1193
  const orderId = this.safeString(trade, 'order_id');
1182
1194
  const priceString = this.safeString(trade, 'price');
1183
1195
  const amountString = this.safeString(trade, 'quantity');
1184
1196
  const costString = this.safeString(trade, 'amount');
1185
- const side = this.safeString(trade, 'type');
1197
+ const side = this.safeString2(trade, 'type', 'trade_type');
1186
1198
  const type = undefined;
1187
1199
  const marketId = this.safeString(trade, 'pair');
1188
1200
  market = this.safeMarket(marketId, market, '_');
1189
1201
  const symbol = market['symbol'];
1190
- const takerOrMaker = this.safeString(trade, 'exec_type');
1202
+ const isMaker = this.safeValue(trade, 'is_maker');
1203
+ let takerOrMakerDefault = undefined;
1204
+ if (isMaker !== undefined) {
1205
+ takerOrMakerDefault = isMaker ? 'maker' : 'taker';
1206
+ }
1207
+ const takerOrMaker = this.safeString(trade, 'exec_type', takerOrMakerDefault);
1191
1208
  let fee = undefined;
1192
1209
  const feeCostString = this.safeString(trade, 'commission_amount');
1193
1210
  if (feeCostString !== undefined) {
@@ -1266,38 +1283,91 @@ export default class exmo extends Exchange {
1266
1283
  * @method
1267
1284
  * @name exmo#fetchMyTrades
1268
1285
  * @description fetch all trades made by the user
1269
- * @param {string} symbol unified market symbol
1286
+ * @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#b8d8d9af-4f46-46a1-939b-ad261d79f452 // spot
1287
+ * @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#f4b1aaf8-399f-403b-ab5e-4926d967a106 // margin
1288
+ * @param {string} symbol a symbol is required but it can be a single string, or a non-empty array
1270
1289
  * @param {int} [since] the earliest time in ms to fetch trades for
1271
- * @param {int} [limit] the maximum number of trades structures to retrieve
1290
+ * @param {int} [limit] *required for margin orders* the maximum number of trades structures to retrieve
1272
1291
  * @param {object} [params] extra parameters specific to the exmo api endpoint
1292
+ *
1293
+ * EXCHANGE SPECIFIC PARAMETERS
1294
+ * @param {int} [params.offset] last deal offset, default = 0
1273
1295
  * @returns {Trade[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#trade-structure}
1274
1296
  */
1275
- // a symbol is required but it can be a single string, or a non-empty array
1276
- if (symbol === undefined) {
1277
- throw new ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument (a single symbol or an array)');
1297
+ this.checkRequiredSymbol('fetchMyTrades', symbol);
1298
+ let marginMode = undefined;
1299
+ [marginMode, params] = this.handleMarginModeAndParams('fetchMyTrades', params);
1300
+ if (marginMode === 'cross') {
1301
+ throw new BadRequest(this.id + 'only isolated margin is supported');
1278
1302
  }
1279
1303
  await this.loadMarkets();
1280
- let pair = undefined;
1281
- let market = undefined;
1282
- if (Array.isArray(symbol)) {
1283
- const numSymbols = symbol.length;
1284
- if (numSymbols < 1) {
1285
- throw new ArgumentsRequired(this.id + ' fetchMyTrades() requires a non-empty symbol array');
1286
- }
1287
- const marketIds = this.marketIds(symbol);
1288
- pair = marketIds.join(',');
1304
+ const market = this.market(symbol);
1305
+ const pair = market['id'];
1306
+ const isSpot = marginMode !== 'isolated';
1307
+ if (limit === undefined) {
1308
+ limit = 100;
1309
+ }
1310
+ const request = {};
1311
+ if (isSpot) {
1312
+ request['pair'] = pair;
1289
1313
  }
1290
1314
  else {
1291
- market = this.market(symbol);
1292
- pair = market['id'];
1315
+ request['pair_name'] = pair;
1293
1316
  }
1294
- const request = {
1295
- 'pair': pair,
1296
- };
1297
1317
  if (limit !== undefined) {
1298
1318
  request['limit'] = limit;
1299
1319
  }
1300
- const response = await this.privatePostUserTrades(this.extend(request, params));
1320
+ const offset = this.safeInteger(params, 'offset', 0);
1321
+ request['offset'] = offset;
1322
+ let response = undefined;
1323
+ if (isSpot) {
1324
+ response = await this.privatePostUserTrades(this.extend(request, params));
1325
+ //
1326
+ // {
1327
+ // "BTC_USD": [
1328
+ // {
1329
+ // "trade_id": 20056872,
1330
+ // "client_id": 100500,
1331
+ // "date": 1435488248,
1332
+ // "type": "buy",
1333
+ // "pair": "BTC_USD",
1334
+ // "quantity": "1",
1335
+ // "price": "100",
1336
+ // "amount": "100",
1337
+ // "order_id": 7,
1338
+ // "parent_order_id": 117684023830293,
1339
+ // "exec_type": "taker",
1340
+ // "commission_amount": "0.02",
1341
+ // "commission_currency": "BTC",
1342
+ // "commission_percent": "0.2"
1343
+ // }
1344
+ // ],
1345
+ // ...
1346
+ // }
1347
+ //
1348
+ }
1349
+ else {
1350
+ const responseFromExchange = await this.privatePostMarginTrades(this.extend(request, params));
1351
+ //
1352
+ // {
1353
+ // "trades": {
1354
+ // "ADA_USDT": [
1355
+ // {
1356
+ // "trade_id": "692861757015952517",
1357
+ // "trade_dt": "1693951853197811824",
1358
+ // "trade_type": "buy",
1359
+ // "pair": "ADA_USDT",
1360
+ // "quantity": "1.96607879",
1361
+ // "price": "0.2568",
1362
+ // "amount": "0.50488903"
1363
+ // },
1364
+ // ]
1365
+ // ...
1366
+ // }
1367
+ // }
1368
+ //
1369
+ response = this.safeValue(responseFromExchange, 'trades');
1370
+ }
1301
1371
  let result = [];
1302
1372
  const marketIdsInner = Object.keys(response);
1303
1373
  for (let i = 0; i < marketIdsInner.length; i++) {
@@ -1427,13 +1497,21 @@ export default class exmo extends Exchange {
1427
1497
  * @method
1428
1498
  * @name exmo#fetchOrderTrades
1429
1499
  * @description fetch all the trades made from a single order
1500
+ * @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#cf27781e-28e5-4b39-a52d-3110f5d22459 // spot
1501
+ * @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#00810661-9119-46c5-aec5-55abe9cb42c7 // margin
1430
1502
  * @param {string} id order id
1431
1503
  * @param {string} symbol unified market symbol
1432
1504
  * @param {int} [since] the earliest time in ms to fetch trades for
1433
1505
  * @param {int} [limit] the maximum number of trades to retrieve
1434
1506
  * @param {object} [params] extra parameters specific to the exmo api endpoint
1507
+ * @param {string} [params.marginMode] set to "isolated" to fetch trades for a margin order
1435
1508
  * @returns {object[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#trade-structure}
1436
1509
  */
1510
+ let marginMode = undefined;
1511
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrderTrades', params);
1512
+ if (marginMode === 'cross') {
1513
+ throw new BadRequest(this.id + ' only supports isolated margin');
1514
+ }
1437
1515
  let market = undefined;
1438
1516
  if (symbol !== undefined) {
1439
1517
  market = this.market(symbol);
@@ -1441,32 +1519,54 @@ export default class exmo extends Exchange {
1441
1519
  const request = {
1442
1520
  'order_id': id.toString(),
1443
1521
  };
1444
- const response = await this.privatePostOrderTrades(this.extend(request, params));
1445
- //
1446
- // {
1447
- // "type": "buy",
1448
- // "in_currency": "BTC",
1449
- // "in_amount": "1",
1450
- // "out_currency": "USD",
1451
- // "out_amount": "100",
1452
- // "trades": [
1453
- // {
1454
- // "trade_id": 3,
1455
- // "date": 1435488248,
1456
- // "type": "buy",
1457
- // "pair": "BTC_USD",
1458
- // "order_id": 12345,
1459
- // "quantity": 1,
1460
- // "price": 100,
1461
- // "amount": 100,
1462
- // "exec_type": "taker",
1463
- // "commission_amount": "0.02",
1464
- // "commission_currency": "BTC",
1465
- // "commission_percent": "0.2"
1466
- // }
1467
- // ]
1468
- // }
1469
- //
1522
+ let response = undefined;
1523
+ if (marginMode === 'isolated') {
1524
+ response = await this.privatePostMarginUserOrderTrades(this.extend(request, params));
1525
+ //
1526
+ // {
1527
+ // "trades": [
1528
+ // {
1529
+ // "is_maker": false,
1530
+ // "order_id": "123",
1531
+ // "pair": "BTC_USD",
1532
+ // "price": "54122.25",
1533
+ // "quantity": "0.00069994",
1534
+ // "trade_dt": "1619069561718824428",
1535
+ // "trade_id": "692842802860135010",
1536
+ // "type": "sell"
1537
+ // }
1538
+ // ]
1539
+ // }
1540
+ //
1541
+ }
1542
+ else {
1543
+ response = await this.privatePostOrderTrades(this.extend(request, params));
1544
+ //
1545
+ // {
1546
+ // "type": "buy",
1547
+ // "in_currency": "BTC",
1548
+ // "in_amount": "1",
1549
+ // "out_currency": "USD",
1550
+ // "out_amount": "100",
1551
+ // "trades": [
1552
+ // {
1553
+ // "trade_id": 3,
1554
+ // "date": 1435488248,
1555
+ // "type": "buy",
1556
+ // "pair": "BTC_USD",
1557
+ // "order_id": 12345,
1558
+ // "quantity": 1,
1559
+ // "price": 100,
1560
+ // "amount": 100,
1561
+ // "exec_type": "taker",
1562
+ // "commission_amount": "0.02",
1563
+ // "commission_currency": "BTC",
1564
+ // "commission_percent": "0.2"
1565
+ // }
1566
+ // ]
1567
+ // }
1568
+ //
1569
+ }
1470
1570
  const trades = this.safeValue(response, 'trades');
1471
1571
  return this.parseTrades(trades, market, since, limit);
1472
1572
  }
package/js/src/gate.d.ts CHANGED
@@ -410,5 +410,6 @@ export default class gate extends Exchange {
410
410
  };
411
411
  parseLedgerEntryType(type: any): string;
412
412
  setPositionMode(hedged: any, symbol?: any, params?: {}): Promise<any>;
413
+ fetchUnderlyingAssets(params?: {}): Promise<any[]>;
413
414
  handleErrors(code: any, reason: any, url: any, method: any, headers: any, body: any, response: any, requestHeaders: any, requestBody: any): any;
414
415
  }
package/js/src/gate.js CHANGED
@@ -133,6 +133,7 @@ export default class gate extends Exchange {
133
133
  'fetchTradingFee': true,
134
134
  'fetchTradingFees': true,
135
135
  'fetchTransactionFees': true,
136
+ 'fetchUnderlyingAssets': true,
136
137
  'fetchVolatilityHistory': false,
137
138
  'fetchWithdrawals': true,
138
139
  'reduceMargin': true,
@@ -6225,6 +6226,44 @@ export default class gate extends Exchange {
6225
6226
  request['dual_mode'] = hedged;
6226
6227
  return await this.privateFuturesPostSettleDualMode(this.extend(request, query));
6227
6228
  }
6229
+ async fetchUnderlyingAssets(params = {}) {
6230
+ /**
6231
+ * @method
6232
+ * @name gate#fetchUnderlyingAssets
6233
+ * @description fetches the market ids of underlying assets for a specific contract market type
6234
+ * @param {object} [params] exchange specific params
6235
+ * @param {string} [params.type] the contract market type, 'option', 'swap' or 'future', the default is 'option'
6236
+ * @returns {object[]} a list of [underlying assets]{@link https://github.com/ccxt/ccxt/wiki/Manual#underlying-assets-structure}
6237
+ */
6238
+ await this.loadMarkets();
6239
+ let marketType = undefined;
6240
+ [marketType, params] = this.handleMarketTypeAndParams('fetchUnderlyingAssets', undefined, params);
6241
+ if ((marketType === undefined) || (marketType === 'spot')) {
6242
+ marketType = 'option';
6243
+ }
6244
+ if (marketType !== 'option') {
6245
+ throw new NotSupported(this.id + ' fetchUnderlyingAssets() supports option markets only');
6246
+ }
6247
+ const response = await this.publicOptionsGetUnderlyings(params);
6248
+ //
6249
+ // [
6250
+ // {
6251
+ // "index_time": "1646915796",
6252
+ // "name": "BTC_USDT",
6253
+ // "index_price": "39142.73"
6254
+ // }
6255
+ // ]
6256
+ //
6257
+ const underlyings = [];
6258
+ for (let i = 0; i < response.length; i++) {
6259
+ const underlying = response[i];
6260
+ const name = this.safeString(underlying, 'name');
6261
+ if (name !== undefined) {
6262
+ underlyings.push(name);
6263
+ }
6264
+ }
6265
+ return underlyings;
6266
+ }
6228
6267
  handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
6229
6268
  if (response === undefined) {
6230
6269
  return undefined;
package/js/src/hitbtc.js CHANGED
@@ -1235,6 +1235,9 @@ export default class hitbtc extends Exchange {
1235
1235
  if (taker !== undefined) {
1236
1236
  takerOrMaker = taker ? 'taker' : 'maker';
1237
1237
  }
1238
+ else {
1239
+ takerOrMaker = 'taker'; // the only case when `taker` field is missing, is public fetchTrades and it must be taker
1240
+ }
1238
1241
  if (feeCostString !== undefined) {
1239
1242
  const info = this.safeValue(market, 'info', {});
1240
1243
  const feeCurrency = this.safeString(info, 'fee_currency');
package/js/src/okx.d.ts CHANGED
@@ -432,5 +432,6 @@ export default class okx extends Exchange {
432
432
  datetime: any;
433
433
  };
434
434
  parseSettlements(settlements: any, market: any): any[];
435
+ fetchUnderlyingAssets(params?: {}): Promise<any>;
435
436
  handleErrors(httpCode: any, reason: any, url: any, method: any, headers: any, body: any, response: any, requestHeaders: any, requestBody: any): any;
436
437
  }
package/js/src/okx.js CHANGED
@@ -110,6 +110,7 @@ export default class okx extends Exchange {
110
110
  'fetchTransactions': false,
111
111
  'fetchTransfer': true,
112
112
  'fetchTransfers': true,
113
+ 'fetchUnderlyingAssets': true,
113
114
  'fetchVolatilityHistory': false,
114
115
  'fetchWithdrawal': true,
115
116
  'fetchWithdrawals': true,
@@ -6703,6 +6704,44 @@ export default class okx extends Exchange {
6703
6704
  }
6704
6705
  return result;
6705
6706
  }
6707
+ async fetchUnderlyingAssets(params = {}) {
6708
+ /**
6709
+ * @method
6710
+ * @name okx#fetchUnderlyingAssets
6711
+ * @description fetches the market ids of underlying assets for a specific contract market type
6712
+ * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-underlying
6713
+ * @param {object} [params] exchange specific params
6714
+ * @param {string} [params.type] the contract market type, 'option', 'swap' or 'future', the default is 'option'
6715
+ * @returns {object[]} a list of [underlying assets]{@link https://github.com/ccxt/ccxt/wiki/Manual#underlying-assets-structure}
6716
+ */
6717
+ await this.loadMarkets();
6718
+ let marketType = undefined;
6719
+ [marketType, params] = this.handleMarketTypeAndParams('fetchUnderlyingAssets', undefined, params);
6720
+ if ((marketType === undefined) || (marketType === 'spot')) {
6721
+ marketType = 'option';
6722
+ }
6723
+ if ((marketType !== 'option') && (marketType !== 'swap') && (marketType !== 'future')) {
6724
+ throw new NotSupported(this.id + ' fetchUnderlyingAssets() supports contract markets only');
6725
+ }
6726
+ const request = {
6727
+ 'instType': this.convertToInstrumentType(marketType),
6728
+ };
6729
+ const response = await this.publicGetPublicUnderlying(this.extend(request, params));
6730
+ //
6731
+ // {
6732
+ // "code": "0",
6733
+ // "data": [
6734
+ // [
6735
+ // "BTC-USD",
6736
+ // "ETH-USD"
6737
+ // ]
6738
+ // ],
6739
+ // "msg": ""
6740
+ // }
6741
+ //
6742
+ const underlyings = this.safeValue(response, 'data', []);
6743
+ return underlyings[0];
6744
+ }
6706
6745
  handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
6707
6746
  if (!response) {
6708
6747
  return undefined; // fallback to default error handler
@@ -270,13 +270,13 @@ export default class bitfinex2 extends bitfinex2Rest {
270
270
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
271
271
  this.myTrades = new ArrayCacheBySymbolById(limit);
272
272
  }
273
- const array = this.myTrades;
274
- array.append(trade);
275
- this.myTrades = array;
273
+ const tradesArray = this.myTrades;
274
+ tradesArray.append(trade);
275
+ this.myTrades = tradesArray;
276
276
  // generic subscription
277
- client.resolve(array, name);
277
+ client.resolve(tradesArray, name);
278
278
  // specific subscription
279
- client.resolve(array, messageHash);
279
+ client.resolve(tradesArray, messageHash);
280
280
  }
281
281
  handleTrades(client, message, subscription) {
282
282
  //
@@ -741,8 +741,8 @@ export default class blockchaincom extends blockchaincomRest {
741
741
  };
742
742
  }
743
743
  handleDelta(bookside, delta) {
744
- const array = this.parseCountedBidAsk(delta, 'px', 'qty', 'num');
745
- bookside.storeArray(array);
744
+ const bookArray = this.parseCountedBidAsk(delta, 'px', 'qty', 'num');
745
+ bookside.storeArray(bookArray);
746
746
  }
747
747
  handleDeltas(bookside, deltas) {
748
748
  for (let i = 0; i < deltas.length; i++) {
@@ -291,13 +291,13 @@ export default class luno extends lunoRest {
291
291
  const asksOrderSide = orderbook['asks'];
292
292
  const bidsOrderSide = orderbook['bids'];
293
293
  if (createUpdate !== undefined) {
294
- const array = this.customParseBidAsk(createUpdate, 'price', 'volume', 'order_id');
294
+ const bidAskArray = this.customParseBidAsk(createUpdate, 'price', 'volume', 'order_id');
295
295
  const type = this.safeString(createUpdate, 'type');
296
296
  if (type === 'ASK') {
297
- asksOrderSide.storeArray(array);
297
+ asksOrderSide.storeArray(bidAskArray);
298
298
  }
299
299
  else if (type === 'BID') {
300
- bidsOrderSide.storeArray(array);
300
+ bidsOrderSide.storeArray(bidAskArray);
301
301
  }
302
302
  }
303
303
  const deleteUpdate = this.safeValue(message, 'delete_update');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.0.86",
3
+ "version": "4.0.88",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",