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/CONTRIBUTING.md +4 -1
- package/README.md +5 -5
- package/dist/ccxt.browser.js +157 -26
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +93 -0
- package/dist/cjs/src/bitmex.js +5 -2
- package/dist/cjs/src/bybit.js +25 -9
- package/dist/cjs/src/coinmetro.js +10 -4
- package/dist/cjs/src/okx.js +17 -4
- package/dist/cjs/src/pro/coinbase.js +1 -1
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/base/Exchange.d.ts +9 -0
- package/js/src/base/Exchange.js +93 -0
- package/js/src/bitmex.js +5 -2
- package/js/src/bybit.js +25 -9
- package/js/src/coinmetro.js +10 -4
- package/js/src/okx.js +17 -4
- package/js/src/pro/coinbase.js +2 -2
- package/package.json +1 -1
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.
|
|
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]);
|
package/dist/cjs/src/bitmex.js
CHANGED
|
@@ -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://
|
|
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':
|
|
115
|
+
'referral': {
|
|
116
|
+
'url': 'https://www.bitmex.com/app/register/NZTR1q',
|
|
117
|
+
'discount': 0.1,
|
|
118
|
+
},
|
|
116
119
|
},
|
|
117
120
|
'api': {
|
|
118
121
|
'public': {
|
package/dist/cjs/src/bybit.js
CHANGED
|
@@ -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
|
|
3350
|
+
let feeCurrencyCode = undefined;
|
|
3350
3351
|
if (market['spot']) {
|
|
3351
|
-
|
|
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
|
-
|
|
3370
|
+
feeCurrencyCode = market['inverse'] ? market['base'] : market['settle'];
|
|
3355
3371
|
}
|
|
3356
3372
|
fee = {
|
|
3357
3373
|
'cost': feeCostString,
|
|
3358
|
-
'currency':
|
|
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.
|
|
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.
|
|
5677
|
-
const positions = this.
|
|
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.
|
|
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.
|
|
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 (
|
|
1859
|
-
|
|
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) {
|
package/dist/cjs/src/okx.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
41
|
+
const version = '4.2.29';
|
|
42
42
|
Exchange.ccxtVersion = version;
|
|
43
43
|
//-----------------------------------------------------------------------------
|
|
44
44
|
import ace from './src/ace.js';
|
package/js/src/abstract/okx.d.ts
CHANGED
|
@@ -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;
|
package/js/src/base/Exchange.js
CHANGED
|
@@ -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://
|
|
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':
|
|
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
|
|
3353
|
+
let feeCurrencyCode = undefined;
|
|
3353
3354
|
if (market['spot']) {
|
|
3354
|
-
|
|
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
|
-
|
|
3373
|
+
feeCurrencyCode = market['inverse'] ? market['base'] : market['settle'];
|
|
3358
3374
|
}
|
|
3359
3375
|
fee = {
|
|
3360
3376
|
'cost': feeCostString,
|
|
3361
|
-
'currency':
|
|
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.
|
|
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.
|
|
5680
|
-
const positions = this.
|
|
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.
|
|
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.
|
|
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);
|
package/js/src/coinmetro.js
CHANGED
|
@@ -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 (
|
|
1862
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
2610
|
+
margin = this.safeBool(params, 'margin', false);
|
|
2598
2611
|
}
|
|
2599
2612
|
if (spot) {
|
|
2600
2613
|
if (margin) {
|