ccxt 4.2.28 → 4.2.29

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/dist/cjs/ccxt.js CHANGED
@@ -175,7 +175,7 @@ var woo$1 = require('./src/pro/woo.js');
175
175
 
176
176
  //-----------------------------------------------------------------------------
177
177
  // this is updated by vss.js when building
178
- const version = '4.2.28';
178
+ const version = '4.2.29';
179
179
  Exchange["default"].ccxtVersion = version;
180
180
  const exchanges = {
181
181
  'ace': ace,
@@ -1407,6 +1407,99 @@ class Exchange {
1407
1407
  // ########################################################################
1408
1408
  // ------------------------------------------------------------------------
1409
1409
  // METHODS BELOW THIS LINE ARE TRANSPILED FROM JAVASCRIPT TO PYTHON AND PHP
1410
+ safeBoolN(dictionaryOrList, keys, defaultValue = undefined) {
1411
+ /**
1412
+ * @ignore
1413
+ * @method
1414
+ * @description safely extract boolean value from dictionary or list
1415
+ * @returns {bool | undefined}
1416
+ */
1417
+ const value = this.safeValueN(dictionaryOrList, keys, defaultValue);
1418
+ if (typeof value === 'boolean') {
1419
+ return value;
1420
+ }
1421
+ return defaultValue;
1422
+ }
1423
+ safeBool2(dictionary, key1, key2, defaultValue = undefined) {
1424
+ /**
1425
+ * @ignore
1426
+ * @method
1427
+ * @description safely extract boolean value from dictionary or list
1428
+ * @returns {bool | undefined}
1429
+ */
1430
+ return this.safeBoolN(dictionary, [key1, key2], defaultValue);
1431
+ }
1432
+ safeBool(dictionary, key, defaultValue = undefined) {
1433
+ /**
1434
+ * @ignore
1435
+ * @method
1436
+ * @description safely extract boolean value from dictionary or list
1437
+ * @returns {bool | undefined}
1438
+ */
1439
+ return this.safeBoolN(dictionary, [key], defaultValue);
1440
+ }
1441
+ safeDictN(dictionaryOrList, keys, defaultValue = undefined) {
1442
+ /**
1443
+ * @ignore
1444
+ * @method
1445
+ * @description safely extract a dictionary from dictionary or list
1446
+ * @returns {object | undefined}
1447
+ */
1448
+ const value = this.safeValueN(dictionaryOrList, keys, defaultValue);
1449
+ if (typeof value === 'object') {
1450
+ return value;
1451
+ }
1452
+ return defaultValue;
1453
+ }
1454
+ safeDict(dictionary, key, defaultValue = undefined) {
1455
+ /**
1456
+ * @ignore
1457
+ * @method
1458
+ * @description safely extract a dictionary from dictionary or list
1459
+ * @returns {object | undefined}
1460
+ */
1461
+ return this.safeDictN(dictionary, [key], defaultValue);
1462
+ }
1463
+ safeDict2(dictionary, key1, key2, defaultValue = undefined) {
1464
+ /**
1465
+ * @ignore
1466
+ * @method
1467
+ * @description safely extract a dictionary from dictionary or list
1468
+ * @returns {object | undefined}
1469
+ */
1470
+ return this.safeDictN(dictionary, [key1, key2], defaultValue);
1471
+ }
1472
+ safeListN(dictionaryOrList, keys, defaultValue = undefined) {
1473
+ /**
1474
+ * @ignore
1475
+ * @method
1476
+ * @description safely extract an Array from dictionary or list
1477
+ * @returns {Array | undefined}
1478
+ */
1479
+ const value = this.safeValueN(dictionaryOrList, keys, defaultValue);
1480
+ if (Array.isArray(value)) {
1481
+ return value;
1482
+ }
1483
+ return defaultValue;
1484
+ }
1485
+ safeList2(dictionaryOrList, key1, key2, defaultValue = undefined) {
1486
+ /**
1487
+ * @ignore
1488
+ * @method
1489
+ * @description safely extract an Array from dictionary or list
1490
+ * @returns {Array | undefined}
1491
+ */
1492
+ return this.safeListN(dictionaryOrList, [key1, key2], defaultValue);
1493
+ }
1494
+ safeList(dictionaryOrList, key, defaultValue = undefined) {
1495
+ /**
1496
+ * @ignore
1497
+ * @method
1498
+ * @description safely extract an Array from dictionary or list
1499
+ * @returns {Array | undefined}
1500
+ */
1501
+ return this.safeListN(dictionaryOrList, [key], defaultValue);
1502
+ }
1410
1503
  handleDeltas(orderbook, deltas) {
1411
1504
  for (let i = 0; i < deltas.length; i++) {
1412
1505
  this.handleDelta(orderbook, deltas[i]);
@@ -101,7 +101,7 @@ class bitmex extends bitmex$1 {
101
101
  'public': 'https://testnet.bitmex.com',
102
102
  'private': 'https://testnet.bitmex.com',
103
103
  },
104
- 'logo': 'https://user-images.githubusercontent.com/1294454/27766319-f653c6e6-5ed4-11e7-933d-f0bc3699ae8f.jpg',
104
+ 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/cea9cfe5-c57e-4b84-b2ac-77b960b04445',
105
105
  'api': {
106
106
  'public': 'https://www.bitmex.com',
107
107
  'private': 'https://www.bitmex.com',
@@ -112,7 +112,10 @@ class bitmex extends bitmex$1 {
112
112
  'https://github.com/BitMEX/api-connectors/tree/master/official-http',
113
113
  ],
114
114
  'fees': 'https://www.bitmex.com/app/fees',
115
- 'referral': 'https://www.bitmex.com/register/upZpOX',
115
+ 'referral': {
116
+ 'url': 'https://www.bitmex.com/app/register/NZTR1q',
117
+ 'discount': 0.1,
118
+ },
116
119
  },
117
120
  'api': {
118
121
  'public': {
@@ -854,6 +854,7 @@ class bybit extends bybit$1 {
854
854
  '181003': errors.InvalidOrder,
855
855
  '181004': errors.InvalidOrder,
856
856
  '182000': errors.InvalidOrder,
857
+ '181017': errors.BadRequest,
857
858
  '20001': errors.OrderNotFound,
858
859
  '20003': errors.InvalidOrder,
859
860
  '20004': errors.InvalidOrder,
@@ -3346,16 +3347,31 @@ class bybit extends bybit$1 {
3346
3347
  let fee = undefined;
3347
3348
  const feeCostString = this.safeString(order, 'cumExecFee');
3348
3349
  if (feeCostString !== undefined) {
3349
- let feeCurrency = undefined;
3350
+ let feeCurrencyCode = undefined;
3350
3351
  if (market['spot']) {
3351
- feeCurrency = (side === 'buy') ? market['quote'] : market['base'];
3352
+ if (Precise["default"].stringGt(feeCostString, '0')) {
3353
+ if (side === 'buy') {
3354
+ feeCurrencyCode = market['base'];
3355
+ }
3356
+ else {
3357
+ feeCurrencyCode = market['quote'];
3358
+ }
3359
+ }
3360
+ else {
3361
+ if (side === 'buy') {
3362
+ feeCurrencyCode = market['quote'];
3363
+ }
3364
+ else {
3365
+ feeCurrencyCode = market['base'];
3366
+ }
3367
+ }
3352
3368
  }
3353
3369
  else {
3354
- feeCurrency = market['settle'];
3370
+ feeCurrencyCode = market['inverse'] ? market['base'] : market['settle'];
3355
3371
  }
3356
3372
  fee = {
3357
3373
  'cost': feeCostString,
3358
- 'currency': feeCurrency,
3374
+ 'currency': feeCurrencyCode,
3359
3375
  };
3360
3376
  }
3361
3377
  let clientOrderId = this.safeString(order, 'orderLinkId');
@@ -4515,7 +4531,7 @@ class bybit extends bybit$1 {
4515
4531
  return await this.fetchUsdcOrders(symbol, since, limit, params);
4516
4532
  }
4517
4533
  request['category'] = type;
4518
- const isStop = this.safeValueN(params, ['trigger', 'stop'], false);
4534
+ const isStop = this.safeBoolN(params, ['trigger', 'stop'], false);
4519
4535
  params = this.omit(params, ['trigger', 'stop']);
4520
4536
  if (isStop) {
4521
4537
  request['orderFilter'] = 'StopOrder';
@@ -5673,10 +5689,10 @@ class bybit extends bybit$1 {
5673
5689
  // "time": 1672280219169
5674
5690
  // }
5675
5691
  //
5676
- const result = this.safeValue(response, 'result', {});
5677
- const positions = this.safeValue2(result, 'list', 'dataList', []);
5692
+ const result = this.safeDict(response, 'result', {});
5693
+ const positions = this.safeList2(result, 'list', 'dataList', []);
5678
5694
  const timestamp = this.safeInteger(response, 'time');
5679
- const first = this.safeValue(positions, 0, {});
5695
+ const first = this.safeDict(positions, 0, {});
5680
5696
  const position = this.parsePosition(first, market);
5681
5697
  position['timestamp'] = timestamp;
5682
5698
  position['datetime'] = this.iso8601(timestamp);
@@ -6422,7 +6438,7 @@ class bybit extends bybit$1 {
6422
6438
  throw new errors.BadRequest(this.id + 'fetchOpenInterestHistory cannot use the 1m timeframe');
6423
6439
  }
6424
6440
  await this.loadMarkets();
6425
- const paginate = this.safeValue(params, 'paginate');
6441
+ const paginate = this.safeBool(params, 'paginate');
6426
6442
  if (paginate) {
6427
6443
  params = this.omit(params, 'paginate');
6428
6444
  return await this.fetchPaginatedCallDeterministic('fetchOpenInterestHistory', symbol, since, limit, timeframe, params, 500);
@@ -135,7 +135,7 @@ class coinmetro extends coinmetro$1 {
135
135
  'private': 'https://api.coinmetro.com',
136
136
  },
137
137
  'test': {
138
- 'public': 'https://api.coinmetro.com',
138
+ 'public': 'https://api.coinmetro.com/open',
139
139
  'private': 'https://api.coinmetro.com/open',
140
140
  },
141
141
  'www': 'https://coinmetro.com/',
@@ -1854,11 +1854,17 @@ class coinmetro extends coinmetro$1 {
1854
1854
  const endpoint = '/' + this.implodeParams(path, params);
1855
1855
  let url = this.urls['api'][api] + endpoint;
1856
1856
  const query = this.urlencode(request);
1857
+ if (headers === undefined) {
1858
+ headers = {};
1859
+ }
1860
+ headers['CCXT'] = 'true';
1857
1861
  if (api === 'private') {
1858
- if (headers === undefined) {
1859
- headers = {};
1862
+ if ((this.uid === undefined) && (this.apiKey !== undefined)) {
1863
+ this.uid = this.apiKey;
1864
+ }
1865
+ if ((this.token === undefined) && (this.secret !== undefined)) {
1866
+ this.token = this.secret;
1860
1867
  }
1861
- headers['CCXT'] = true;
1862
1868
  if (url === 'https://api.coinmetro.com/jwt') { // handle with headers for login endpoint
1863
1869
  headers['X-Device-Id'] = 'bypass';
1864
1870
  if (this.twofa !== undefined) {
@@ -172,6 +172,7 @@ class okx extends okx$1 {
172
172
  'api': {
173
173
  'public': {
174
174
  'get': {
175
+ 'market/books-full': 2,
175
176
  'market/tickers': 1,
176
177
  'market/ticker': 1,
177
178
  'market/index-tickers': 1,
@@ -1670,6 +1671,7 @@ class okx extends okx$1 {
1670
1671
  * @param {string} symbol unified symbol of the market to fetch the order book for
1671
1672
  * @param {int} [limit] the maximum amount of order book entries to return
1672
1673
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1674
+ * @param {string} [params.method] 'publicGetMarketBooksFull' or 'publicGetMarketBooks' default is 'publicGetMarketBooks'
1673
1675
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
1674
1676
  */
1675
1677
  await this.loadMarkets();
@@ -1677,11 +1679,22 @@ class okx extends okx$1 {
1677
1679
  const request = {
1678
1680
  'instId': market['id'],
1679
1681
  };
1680
- limit = (limit === undefined) ? 20 : limit;
1682
+ let method = undefined;
1683
+ [method, params] = this.handleOptionAndParams(params, 'fetchOrderBook', 'method', 'publicGetMarketBooks');
1684
+ if (method === 'publicGetMarketBooksFull' && limit === undefined) {
1685
+ limit = 5000;
1686
+ }
1687
+ limit = (limit === undefined) ? 100 : limit;
1681
1688
  if (limit !== undefined) {
1682
1689
  request['sz'] = limit; // max 400
1683
1690
  }
1684
- const response = await this.publicGetMarketBooks(this.extend(request, params));
1691
+ let response = undefined;
1692
+ if ((method === 'publicGetMarketBooksFull') || (limit > 400)) {
1693
+ response = await this.publicGetMarketBooksFull(this.extend(request, params));
1694
+ }
1695
+ else {
1696
+ response = await this.publicGetMarketBooks(this.extend(request, params));
1697
+ }
1685
1698
  //
1686
1699
  // {
1687
1700
  // "code": "0",
@@ -1735,7 +1748,7 @@ class okx extends okx$1 {
1735
1748
  const symbol = market['symbol'];
1736
1749
  const last = this.safeString(ticker, 'last');
1737
1750
  const open = this.safeString(ticker, 'open24h');
1738
- const spot = this.safeValue(market, 'spot', false);
1751
+ const spot = this.safeBool(market, 'spot', false);
1739
1752
  const quoteVolume = spot ? this.safeString(ticker, 'volCcy24h') : undefined;
1740
1753
  const baseVolume = this.safeString(ticker, 'vol24h');
1741
1754
  const high = this.safeString(ticker, 'high24h');
@@ -2591,7 +2604,7 @@ class okx extends okx$1 {
2591
2604
  }
2592
2605
  else {
2593
2606
  marginMode = defaultMarginMode;
2594
- margin = this.safeValue(params, 'margin', false);
2607
+ margin = this.safeBool(params, 'margin', false);
2595
2608
  }
2596
2609
  if (spot) {
2597
2610
  if (margin) {
@@ -110,7 +110,7 @@ class coinbase extends coinbase$1 {
110
110
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
111
111
  */
112
112
  if (symbols === undefined) {
113
- throw new errors.ArgumentsRequired(this.id + ' watchTickers requires a symbols argument');
113
+ symbols = this.symbols;
114
114
  }
115
115
  const name = 'ticker_batch';
116
116
  const tickers = await this.subscribe(name, symbols, params);
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
7
- declare const version = "4.2.27";
7
+ declare const version = "4.2.28";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.2.28';
41
+ const version = '4.2.29';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -1,6 +1,7 @@
1
1
  import { implicitReturnType } from '../base/types.js';
2
2
  import { Exchange as _Exchange } from '../base/Exchange.js';
3
3
  interface Exchange {
4
+ publicGetMarketBooksFull(params?: {}): Promise<implicitReturnType>;
4
5
  publicGetMarketTickers(params?: {}): Promise<implicitReturnType>;
5
6
  publicGetMarketTicker(params?: {}): Promise<implicitReturnType>;
6
7
  publicGetMarketIndexTickers(params?: {}): Promise<implicitReturnType>;
@@ -570,6 +570,15 @@ export default class Exchange {
570
570
  setProperty(obj: any, property: any, defaultValue?: any): void;
571
571
  axolotl(payload: any, hexKey: any, ed25519: any): string;
572
572
  fixStringifiedJsonMembers(content: any): any;
573
+ safeBoolN(dictionaryOrList: any, keys: IndexType[], defaultValue?: boolean): boolean | undefined;
574
+ safeBool2(dictionary: any, key1: IndexType, key2: IndexType, defaultValue?: boolean): boolean | undefined;
575
+ safeBool(dictionary: any, key: IndexType, defaultValue?: boolean): boolean | undefined;
576
+ safeDictN(dictionaryOrList: any, keys: IndexType[], defaultValue?: Dictionary<any>): Dictionary<any> | undefined;
577
+ safeDict(dictionary: any, key: IndexType, defaultValue?: Dictionary<any>): Dictionary<any> | undefined;
578
+ safeDict2(dictionary: any, key1: IndexType, key2: string, defaultValue?: Dictionary<any>): Dictionary<any> | undefined;
579
+ safeListN(dictionaryOrList: any, keys: IndexType[], defaultValue?: any[]): any[] | undefined;
580
+ safeList2(dictionaryOrList: any, key1: IndexType, key2: string, defaultValue?: any[]): any[] | undefined;
581
+ safeList(dictionaryOrList: any, key: IndexType, defaultValue?: any[]): any[] | undefined;
573
582
  handleDeltas(orderbook: any, deltas: any): void;
574
583
  handleDelta(bookside: any, delta: any): void;
575
584
  getCacheIndex(orderbook: any, deltas: any): number;
@@ -1403,6 +1403,99 @@ export default class Exchange {
1403
1403
  // ########################################################################
1404
1404
  // ------------------------------------------------------------------------
1405
1405
  // METHODS BELOW THIS LINE ARE TRANSPILED FROM JAVASCRIPT TO PYTHON AND PHP
1406
+ safeBoolN(dictionaryOrList, keys, defaultValue = undefined) {
1407
+ /**
1408
+ * @ignore
1409
+ * @method
1410
+ * @description safely extract boolean value from dictionary or list
1411
+ * @returns {bool | undefined}
1412
+ */
1413
+ const value = this.safeValueN(dictionaryOrList, keys, defaultValue);
1414
+ if (typeof value === 'boolean') {
1415
+ return value;
1416
+ }
1417
+ return defaultValue;
1418
+ }
1419
+ safeBool2(dictionary, key1, key2, defaultValue = undefined) {
1420
+ /**
1421
+ * @ignore
1422
+ * @method
1423
+ * @description safely extract boolean value from dictionary or list
1424
+ * @returns {bool | undefined}
1425
+ */
1426
+ return this.safeBoolN(dictionary, [key1, key2], defaultValue);
1427
+ }
1428
+ safeBool(dictionary, key, defaultValue = undefined) {
1429
+ /**
1430
+ * @ignore
1431
+ * @method
1432
+ * @description safely extract boolean value from dictionary or list
1433
+ * @returns {bool | undefined}
1434
+ */
1435
+ return this.safeBoolN(dictionary, [key], defaultValue);
1436
+ }
1437
+ safeDictN(dictionaryOrList, keys, defaultValue = undefined) {
1438
+ /**
1439
+ * @ignore
1440
+ * @method
1441
+ * @description safely extract a dictionary from dictionary or list
1442
+ * @returns {object | undefined}
1443
+ */
1444
+ const value = this.safeValueN(dictionaryOrList, keys, defaultValue);
1445
+ if (typeof value === 'object') {
1446
+ return value;
1447
+ }
1448
+ return defaultValue;
1449
+ }
1450
+ safeDict(dictionary, key, defaultValue = undefined) {
1451
+ /**
1452
+ * @ignore
1453
+ * @method
1454
+ * @description safely extract a dictionary from dictionary or list
1455
+ * @returns {object | undefined}
1456
+ */
1457
+ return this.safeDictN(dictionary, [key], defaultValue);
1458
+ }
1459
+ safeDict2(dictionary, key1, key2, defaultValue = undefined) {
1460
+ /**
1461
+ * @ignore
1462
+ * @method
1463
+ * @description safely extract a dictionary from dictionary or list
1464
+ * @returns {object | undefined}
1465
+ */
1466
+ return this.safeDictN(dictionary, [key1, key2], defaultValue);
1467
+ }
1468
+ safeListN(dictionaryOrList, keys, defaultValue = undefined) {
1469
+ /**
1470
+ * @ignore
1471
+ * @method
1472
+ * @description safely extract an Array from dictionary or list
1473
+ * @returns {Array | undefined}
1474
+ */
1475
+ const value = this.safeValueN(dictionaryOrList, keys, defaultValue);
1476
+ if (Array.isArray(value)) {
1477
+ return value;
1478
+ }
1479
+ return defaultValue;
1480
+ }
1481
+ safeList2(dictionaryOrList, key1, key2, defaultValue = undefined) {
1482
+ /**
1483
+ * @ignore
1484
+ * @method
1485
+ * @description safely extract an Array from dictionary or list
1486
+ * @returns {Array | undefined}
1487
+ */
1488
+ return this.safeListN(dictionaryOrList, [key1, key2], defaultValue);
1489
+ }
1490
+ safeList(dictionaryOrList, key, defaultValue = undefined) {
1491
+ /**
1492
+ * @ignore
1493
+ * @method
1494
+ * @description safely extract an Array from dictionary or list
1495
+ * @returns {Array | undefined}
1496
+ */
1497
+ return this.safeListN(dictionaryOrList, [key], defaultValue);
1498
+ }
1406
1499
  handleDeltas(orderbook, deltas) {
1407
1500
  for (let i = 0; i < deltas.length; i++) {
1408
1501
  this.handleDelta(orderbook, deltas[i]);
package/js/src/bitmex.js CHANGED
@@ -104,7 +104,7 @@ export default class bitmex extends Exchange {
104
104
  'public': 'https://testnet.bitmex.com',
105
105
  'private': 'https://testnet.bitmex.com',
106
106
  },
107
- 'logo': 'https://user-images.githubusercontent.com/1294454/27766319-f653c6e6-5ed4-11e7-933d-f0bc3699ae8f.jpg',
107
+ 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/cea9cfe5-c57e-4b84-b2ac-77b960b04445',
108
108
  'api': {
109
109
  'public': 'https://www.bitmex.com',
110
110
  'private': 'https://www.bitmex.com',
@@ -115,7 +115,10 @@ export default class bitmex extends Exchange {
115
115
  'https://github.com/BitMEX/api-connectors/tree/master/official-http',
116
116
  ],
117
117
  'fees': 'https://www.bitmex.com/app/fees',
118
- 'referral': 'https://www.bitmex.com/register/upZpOX',
118
+ 'referral': {
119
+ 'url': 'https://www.bitmex.com/app/register/NZTR1q',
120
+ 'discount': 0.1,
121
+ },
119
122
  },
120
123
  'api': {
121
124
  'public': {
package/js/src/bybit.js CHANGED
@@ -857,6 +857,7 @@ export default class bybit extends Exchange {
857
857
  '181003': InvalidOrder,
858
858
  '181004': InvalidOrder,
859
859
  '182000': InvalidOrder,
860
+ '181017': BadRequest,
860
861
  '20001': OrderNotFound,
861
862
  '20003': InvalidOrder,
862
863
  '20004': InvalidOrder,
@@ -3349,16 +3350,31 @@ export default class bybit extends Exchange {
3349
3350
  let fee = undefined;
3350
3351
  const feeCostString = this.safeString(order, 'cumExecFee');
3351
3352
  if (feeCostString !== undefined) {
3352
- let feeCurrency = undefined;
3353
+ let feeCurrencyCode = undefined;
3353
3354
  if (market['spot']) {
3354
- feeCurrency = (side === 'buy') ? market['quote'] : market['base'];
3355
+ if (Precise.stringGt(feeCostString, '0')) {
3356
+ if (side === 'buy') {
3357
+ feeCurrencyCode = market['base'];
3358
+ }
3359
+ else {
3360
+ feeCurrencyCode = market['quote'];
3361
+ }
3362
+ }
3363
+ else {
3364
+ if (side === 'buy') {
3365
+ feeCurrencyCode = market['quote'];
3366
+ }
3367
+ else {
3368
+ feeCurrencyCode = market['base'];
3369
+ }
3370
+ }
3355
3371
  }
3356
3372
  else {
3357
- feeCurrency = market['settle'];
3373
+ feeCurrencyCode = market['inverse'] ? market['base'] : market['settle'];
3358
3374
  }
3359
3375
  fee = {
3360
3376
  'cost': feeCostString,
3361
- 'currency': feeCurrency,
3377
+ 'currency': feeCurrencyCode,
3362
3378
  };
3363
3379
  }
3364
3380
  let clientOrderId = this.safeString(order, 'orderLinkId');
@@ -4518,7 +4534,7 @@ export default class bybit extends Exchange {
4518
4534
  return await this.fetchUsdcOrders(symbol, since, limit, params);
4519
4535
  }
4520
4536
  request['category'] = type;
4521
- const isStop = this.safeValueN(params, ['trigger', 'stop'], false);
4537
+ const isStop = this.safeBoolN(params, ['trigger', 'stop'], false);
4522
4538
  params = this.omit(params, ['trigger', 'stop']);
4523
4539
  if (isStop) {
4524
4540
  request['orderFilter'] = 'StopOrder';
@@ -5676,10 +5692,10 @@ export default class bybit extends Exchange {
5676
5692
  // "time": 1672280219169
5677
5693
  // }
5678
5694
  //
5679
- const result = this.safeValue(response, 'result', {});
5680
- const positions = this.safeValue2(result, 'list', 'dataList', []);
5695
+ const result = this.safeDict(response, 'result', {});
5696
+ const positions = this.safeList2(result, 'list', 'dataList', []);
5681
5697
  const timestamp = this.safeInteger(response, 'time');
5682
- const first = this.safeValue(positions, 0, {});
5698
+ const first = this.safeDict(positions, 0, {});
5683
5699
  const position = this.parsePosition(first, market);
5684
5700
  position['timestamp'] = timestamp;
5685
5701
  position['datetime'] = this.iso8601(timestamp);
@@ -6425,7 +6441,7 @@ export default class bybit extends Exchange {
6425
6441
  throw new BadRequest(this.id + 'fetchOpenInterestHistory cannot use the 1m timeframe');
6426
6442
  }
6427
6443
  await this.loadMarkets();
6428
- const paginate = this.safeValue(params, 'paginate');
6444
+ const paginate = this.safeBool(params, 'paginate');
6429
6445
  if (paginate) {
6430
6446
  params = this.omit(params, 'paginate');
6431
6447
  return await this.fetchPaginatedCallDeterministic('fetchOpenInterestHistory', symbol, since, limit, timeframe, params, 500);
@@ -138,7 +138,7 @@ export default class coinmetro extends Exchange {
138
138
  'private': 'https://api.coinmetro.com',
139
139
  },
140
140
  'test': {
141
- 'public': 'https://api.coinmetro.com',
141
+ 'public': 'https://api.coinmetro.com/open',
142
142
  'private': 'https://api.coinmetro.com/open',
143
143
  },
144
144
  'www': 'https://coinmetro.com/',
@@ -1857,11 +1857,17 @@ export default class coinmetro extends Exchange {
1857
1857
  const endpoint = '/' + this.implodeParams(path, params);
1858
1858
  let url = this.urls['api'][api] + endpoint;
1859
1859
  const query = this.urlencode(request);
1860
+ if (headers === undefined) {
1861
+ headers = {};
1862
+ }
1863
+ headers['CCXT'] = 'true';
1860
1864
  if (api === 'private') {
1861
- if (headers === undefined) {
1862
- headers = {};
1865
+ if ((this.uid === undefined) && (this.apiKey !== undefined)) {
1866
+ this.uid = this.apiKey;
1867
+ }
1868
+ if ((this.token === undefined) && (this.secret !== undefined)) {
1869
+ this.token = this.secret;
1863
1870
  }
1864
- headers['CCXT'] = true;
1865
1871
  if (url === 'https://api.coinmetro.com/jwt') { // handle with headers for login endpoint
1866
1872
  headers['X-Device-Id'] = 'bypass';
1867
1873
  if (this.twofa !== undefined) {
package/js/src/okx.js CHANGED
@@ -175,6 +175,7 @@ export default class okx extends Exchange {
175
175
  'api': {
176
176
  'public': {
177
177
  'get': {
178
+ 'market/books-full': 2,
178
179
  'market/tickers': 1,
179
180
  'market/ticker': 1,
180
181
  'market/index-tickers': 1,
@@ -1673,6 +1674,7 @@ export default class okx extends Exchange {
1673
1674
  * @param {string} symbol unified symbol of the market to fetch the order book for
1674
1675
  * @param {int} [limit] the maximum amount of order book entries to return
1675
1676
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1677
+ * @param {string} [params.method] 'publicGetMarketBooksFull' or 'publicGetMarketBooks' default is 'publicGetMarketBooks'
1676
1678
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
1677
1679
  */
1678
1680
  await this.loadMarkets();
@@ -1680,11 +1682,22 @@ export default class okx extends Exchange {
1680
1682
  const request = {
1681
1683
  'instId': market['id'],
1682
1684
  };
1683
- limit = (limit === undefined) ? 20 : limit;
1685
+ let method = undefined;
1686
+ [method, params] = this.handleOptionAndParams(params, 'fetchOrderBook', 'method', 'publicGetMarketBooks');
1687
+ if (method === 'publicGetMarketBooksFull' && limit === undefined) {
1688
+ limit = 5000;
1689
+ }
1690
+ limit = (limit === undefined) ? 100 : limit;
1684
1691
  if (limit !== undefined) {
1685
1692
  request['sz'] = limit; // max 400
1686
1693
  }
1687
- const response = await this.publicGetMarketBooks(this.extend(request, params));
1694
+ let response = undefined;
1695
+ if ((method === 'publicGetMarketBooksFull') || (limit > 400)) {
1696
+ response = await this.publicGetMarketBooksFull(this.extend(request, params));
1697
+ }
1698
+ else {
1699
+ response = await this.publicGetMarketBooks(this.extend(request, params));
1700
+ }
1688
1701
  //
1689
1702
  // {
1690
1703
  // "code": "0",
@@ -1738,7 +1751,7 @@ export default class okx extends Exchange {
1738
1751
  const symbol = market['symbol'];
1739
1752
  const last = this.safeString(ticker, 'last');
1740
1753
  const open = this.safeString(ticker, 'open24h');
1741
- const spot = this.safeValue(market, 'spot', false);
1754
+ const spot = this.safeBool(market, 'spot', false);
1742
1755
  const quoteVolume = spot ? this.safeString(ticker, 'volCcy24h') : undefined;
1743
1756
  const baseVolume = this.safeString(ticker, 'vol24h');
1744
1757
  const high = this.safeString(ticker, 'high24h');
@@ -2594,7 +2607,7 @@ export default class okx extends Exchange {
2594
2607
  }
2595
2608
  else {
2596
2609
  marginMode = defaultMarginMode;
2597
- margin = this.safeValue(params, 'margin', false);
2610
+ margin = this.safeBool(params, 'margin', false);
2598
2611
  }
2599
2612
  if (spot) {
2600
2613
  if (margin) {