ccxt 4.4.61 → 4.4.62
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/README.md +3 -3
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +56 -34
- package/dist/cjs/src/bingx.js +6 -7
- package/dist/cjs/src/bybit.js +113 -2
- package/dist/cjs/src/kraken.js +2 -2
- package/dist/cjs/src/phemex.js +226 -4
- package/dist/cjs/src/pro/binance.js +26 -11
- package/dist/cjs/src/pro/lbank.js +11 -4
- package/dist/cjs/src/pro/myokx.js +10 -1
- package/dist/cjs/src/whitebit.js +3 -1
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/base/Exchange.d.ts +3 -1
- package/js/src/base/Exchange.js +56 -34
- package/js/src/bingx.js +6 -7
- package/js/src/bybit.d.ts +22 -0
- package/js/src/bybit.js +113 -2
- package/js/src/kraken.js +2 -2
- package/js/src/phemex.d.ts +42 -1
- package/js/src/phemex.js +226 -4
- package/js/src/pro/binance.d.ts +8 -0
- package/js/src/pro/binance.js +26 -11
- package/js/src/pro/lbank.js +11 -4
- package/js/src/pro/myokx.js +10 -1
- package/js/src/whitebit.js +3 -1
- package/package.json +1 -1
package/dist/cjs/ccxt.js
CHANGED
|
@@ -199,7 +199,7 @@ var xt$1 = require('./src/pro/xt.js');
|
|
|
199
199
|
|
|
200
200
|
//-----------------------------------------------------------------------------
|
|
201
201
|
// this is updated by vss.js when building
|
|
202
|
-
const version = '4.4.
|
|
202
|
+
const version = '4.4.62';
|
|
203
203
|
Exchange["default"].ccxtVersion = version;
|
|
204
204
|
const exchanges = {
|
|
205
205
|
'ace': ace,
|
|
@@ -74,6 +74,7 @@ class Exchange {
|
|
|
74
74
|
};
|
|
75
75
|
this.headers = {};
|
|
76
76
|
this.origin = '*'; // CORS origin
|
|
77
|
+
this.MAX_VALUE = Number.MAX_VALUE;
|
|
77
78
|
//
|
|
78
79
|
this.agent = undefined; // maintained for backwards compatibility
|
|
79
80
|
this.nodeHttpModuleLoaded = false;
|
|
@@ -360,18 +361,8 @@ class Exchange {
|
|
|
360
361
|
if (this.api) {
|
|
361
362
|
this.defineRestApi(this.api, 'request');
|
|
362
363
|
}
|
|
363
|
-
// init the request rate limiter
|
|
364
|
-
this.initRestRateLimiter();
|
|
365
|
-
// init predefined markets if any
|
|
366
|
-
if (this.markets) {
|
|
367
|
-
this.setMarkets(this.markets);
|
|
368
|
-
}
|
|
369
364
|
this.newUpdates = (this.options.newUpdates !== undefined) ? this.options.newUpdates : true;
|
|
370
365
|
this.afterConstruct();
|
|
371
|
-
const isSandbox = this.safeBool2(this.options, 'sandbox', 'testnet', false);
|
|
372
|
-
if (isSandbox) {
|
|
373
|
-
this.setSandboxMode(isSandbox);
|
|
374
|
-
}
|
|
375
366
|
}
|
|
376
367
|
encodeURIComponent(...args) {
|
|
377
368
|
// @ts-expect-error
|
|
@@ -401,22 +392,12 @@ class Exchange {
|
|
|
401
392
|
}
|
|
402
393
|
return result;
|
|
403
394
|
}
|
|
404
|
-
initRestRateLimiter() {
|
|
405
|
-
if (this.rateLimit === undefined) {
|
|
406
|
-
throw new Error(this.id + '.rateLimit property is not configured');
|
|
407
|
-
}
|
|
408
|
-
this.tokenBucket = this.extend({
|
|
409
|
-
delay: 0.001,
|
|
410
|
-
capacity: 1,
|
|
411
|
-
cost: 1,
|
|
412
|
-
maxCapacity: 1000,
|
|
413
|
-
refillRate: (this.rateLimit > 0) ? 1 / this.rateLimit : Number.MAX_VALUE,
|
|
414
|
-
}, this.tokenBucket);
|
|
415
|
-
this.throttler = new Throttler(this.tokenBucket);
|
|
416
|
-
}
|
|
417
395
|
throttle(cost = undefined) {
|
|
418
396
|
return this.throttler.throttle(cost);
|
|
419
397
|
}
|
|
398
|
+
initThrottler() {
|
|
399
|
+
this.throttler = new Throttler(this.tokenBucket);
|
|
400
|
+
}
|
|
420
401
|
defineRestApiEndpoint(methodName, uppercaseMethod, lowercaseMethod, camelcaseMethod, path, paths, config = {}) {
|
|
421
402
|
const splitPath = path.split(/[^a-zA-Z0-9]/);
|
|
422
403
|
const camelcaseSuffix = splitPath.map(this.capitalize).join('');
|
|
@@ -2339,8 +2320,39 @@ class Exchange {
|
|
|
2339
2320
|
return timestamp;
|
|
2340
2321
|
}
|
|
2341
2322
|
afterConstruct() {
|
|
2323
|
+
// networks
|
|
2342
2324
|
this.createNetworksByIdObject();
|
|
2343
2325
|
this.featuresGenerator();
|
|
2326
|
+
// init predefined markets if any
|
|
2327
|
+
if (this.markets) {
|
|
2328
|
+
this.setMarkets(this.markets);
|
|
2329
|
+
}
|
|
2330
|
+
// init the request rate limiter
|
|
2331
|
+
this.initRestRateLimiter();
|
|
2332
|
+
// sanbox mode
|
|
2333
|
+
const isSandbox = this.safeBool2(this.options, 'sandbox', 'testnet', false);
|
|
2334
|
+
if (isSandbox) {
|
|
2335
|
+
this.setSandboxMode(isSandbox);
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
initRestRateLimiter() {
|
|
2339
|
+
if (this.rateLimit === undefined || (this.id !== undefined && this.rateLimit === -1)) {
|
|
2340
|
+
throw new errors.ExchangeError(this.id + '.rateLimit property is not configured');
|
|
2341
|
+
}
|
|
2342
|
+
let refillRate = this.MAX_VALUE;
|
|
2343
|
+
if (this.rateLimit > 0) {
|
|
2344
|
+
refillRate = 1 / this.rateLimit;
|
|
2345
|
+
}
|
|
2346
|
+
const defaultBucket = {
|
|
2347
|
+
'delay': 0.001,
|
|
2348
|
+
'capacity': 1,
|
|
2349
|
+
'cost': 1,
|
|
2350
|
+
'maxCapacity': 1000,
|
|
2351
|
+
'refillRate': refillRate,
|
|
2352
|
+
};
|
|
2353
|
+
const existingBucket = (this.tokenBucket === undefined) ? {} : this.tokenBucket;
|
|
2354
|
+
this.tokenBucket = this.extend(defaultBucket, existingBucket);
|
|
2355
|
+
this.initThrottler();
|
|
2344
2356
|
}
|
|
2345
2357
|
featuresGenerator() {
|
|
2346
2358
|
//
|
|
@@ -4611,24 +4623,34 @@ class Exchange {
|
|
|
4611
4623
|
* @param {string} [defaultValue] assigned programatically in the method calling handleMarketTypeAndParams
|
|
4612
4624
|
* @returns {[string, object]} the market type and params with type and defaultType omitted
|
|
4613
4625
|
*/
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4626
|
+
// type from param
|
|
4627
|
+
const type = this.safeString2(params, 'defaultType', 'type');
|
|
4628
|
+
if (type !== undefined) {
|
|
4629
|
+
params = this.omit(params, ['defaultType', 'type']);
|
|
4630
|
+
return [type, params];
|
|
4631
|
+
}
|
|
4632
|
+
// type from market
|
|
4633
|
+
if (market !== undefined) {
|
|
4634
|
+
return [market['type'], params];
|
|
4635
|
+
}
|
|
4636
|
+
// type from default-argument
|
|
4637
|
+
if (defaultValue !== undefined) {
|
|
4638
|
+
return [defaultValue, params];
|
|
4617
4639
|
}
|
|
4618
4640
|
const methodOptions = this.safeDict(this.options, methodName);
|
|
4619
|
-
|
|
4620
|
-
if (methodOptions !== undefined) { // user defined methodType takes precedence over defaultValue
|
|
4641
|
+
if (methodOptions !== undefined) {
|
|
4621
4642
|
if (typeof methodOptions === 'string') {
|
|
4622
|
-
|
|
4643
|
+
return [methodOptions, params];
|
|
4623
4644
|
}
|
|
4624
4645
|
else {
|
|
4625
|
-
|
|
4646
|
+
const typeFromMethod = this.safeString2(methodOptions, 'defaultType', 'type');
|
|
4647
|
+
if (typeFromMethod !== undefined) {
|
|
4648
|
+
return [typeFromMethod, params];
|
|
4649
|
+
}
|
|
4626
4650
|
}
|
|
4627
4651
|
}
|
|
4628
|
-
const
|
|
4629
|
-
|
|
4630
|
-
params = this.omit(params, ['defaultType', 'type']);
|
|
4631
|
-
return [type, params];
|
|
4652
|
+
const defaultType = this.safeString2(this.options, 'defaultType', 'type', 'spot');
|
|
4653
|
+
return [defaultType, params];
|
|
4632
4654
|
}
|
|
4633
4655
|
handleSubTypeAndParams(methodName, market = undefined, params = {}, defaultValue = undefined) {
|
|
4634
4656
|
let subType = undefined;
|
package/dist/cjs/src/bingx.js
CHANGED
|
@@ -4667,14 +4667,13 @@ class bingx extends bingx$1 {
|
|
|
4667
4667
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
4668
4668
|
*/
|
|
4669
4669
|
async fetchCanceledAndClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
4670
|
-
if (symbol === undefined) {
|
|
4671
|
-
throw new errors.ArgumentsRequired(this.id + ' fetchClosedOrders() requires a symbol argument');
|
|
4672
|
-
}
|
|
4673
4670
|
await this.loadMarkets();
|
|
4674
|
-
|
|
4675
|
-
const request = {
|
|
4676
|
-
|
|
4677
|
-
|
|
4671
|
+
let market = undefined;
|
|
4672
|
+
const request = {};
|
|
4673
|
+
if (symbol !== undefined) {
|
|
4674
|
+
market = this.market(symbol);
|
|
4675
|
+
request['symbol'] = market['id'];
|
|
4676
|
+
}
|
|
4678
4677
|
let type = undefined;
|
|
4679
4678
|
let subType = undefined;
|
|
4680
4679
|
let standard = undefined;
|
package/dist/cjs/src/bybit.js
CHANGED
|
@@ -56,7 +56,9 @@ class bybit extends bybit$1 {
|
|
|
56
56
|
'createTrailingAmountOrder': true,
|
|
57
57
|
'createTriggerOrder': true,
|
|
58
58
|
'editOrder': true,
|
|
59
|
+
'editOrders': true,
|
|
59
60
|
'fetchBalance': true,
|
|
61
|
+
'fetchBidsAsks': 'emulated',
|
|
60
62
|
'fetchBorrowInterest': false,
|
|
61
63
|
'fetchBorrowRateHistories': false,
|
|
62
64
|
'fetchBorrowRateHistory': false,
|
|
@@ -237,6 +239,7 @@ class bybit extends bybit$1 {
|
|
|
237
239
|
'v5/spot-lever-token/reference': 5,
|
|
238
240
|
// spot margin trade
|
|
239
241
|
'v5/spot-margin-trade/data': 5,
|
|
242
|
+
'v5/spot-margin-trade/collateral': 5,
|
|
240
243
|
'v5/spot-cross-margin-trade/data': 5,
|
|
241
244
|
'v5/spot-cross-margin-trade/pledge-token': 5,
|
|
242
245
|
'v5/spot-cross-margin-trade/borrow-token': 5,
|
|
@@ -1222,6 +1225,9 @@ class bybit extends bybit$1 {
|
|
|
1222
1225
|
'fetchOHLCV': {
|
|
1223
1226
|
'limit': 1000,
|
|
1224
1227
|
},
|
|
1228
|
+
'editOrders': {
|
|
1229
|
+
'max': 10,
|
|
1230
|
+
},
|
|
1225
1231
|
},
|
|
1226
1232
|
'spot': {
|
|
1227
1233
|
'extends': 'default',
|
|
@@ -2524,6 +2530,20 @@ class bybit extends bybit$1 {
|
|
|
2524
2530
|
const tickerList = this.safeList(result, 'list', []);
|
|
2525
2531
|
return this.parseTickers(tickerList, parsedSymbols);
|
|
2526
2532
|
}
|
|
2533
|
+
/**
|
|
2534
|
+
* @method
|
|
2535
|
+
* @name bybit#fetchBidsAsks
|
|
2536
|
+
* @description fetches the bid and ask price and volume for multiple markets
|
|
2537
|
+
* @see https://bybit-exchange.github.io/docs/v5/market/tickers
|
|
2538
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
|
2539
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2540
|
+
* @param {string} [params.subType] *contract only* 'linear', 'inverse'
|
|
2541
|
+
* @param {string} [params.baseCoin] *option only* base coin, default is 'BTC'
|
|
2542
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
2543
|
+
*/
|
|
2544
|
+
async fetchBidsAsks(symbols = undefined, params = {}) {
|
|
2545
|
+
return await this.fetchTickers(symbols, params);
|
|
2546
|
+
}
|
|
2527
2547
|
parseOHLCV(ohlcv, market = undefined) {
|
|
2528
2548
|
//
|
|
2529
2549
|
// [
|
|
@@ -4207,14 +4227,16 @@ class bybit extends bybit$1 {
|
|
|
4207
4227
|
const price = this.safeValue(rawOrder, 'price');
|
|
4208
4228
|
const orderParams = this.safeDict(rawOrder, 'params', {});
|
|
4209
4229
|
const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams, isUta);
|
|
4230
|
+
delete orderRequest['category'];
|
|
4210
4231
|
ordersRequests.push(orderRequest);
|
|
4211
4232
|
}
|
|
4212
4233
|
const symbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
|
|
4213
4234
|
const market = this.market(symbols[0]);
|
|
4235
|
+
const unifiedMarginStatus = this.safeInteger(this.options, 'unifiedMarginStatus', 3);
|
|
4214
4236
|
let category = undefined;
|
|
4215
4237
|
[category, params] = this.getBybitType('createOrders', market, params);
|
|
4216
|
-
if (category === 'inverse') {
|
|
4217
|
-
throw new errors.NotSupported(this.id + ' createOrders does not allow inverse orders');
|
|
4238
|
+
if ((category === 'inverse') && (unifiedMarginStatus < 5)) {
|
|
4239
|
+
throw new errors.NotSupported(this.id + ' createOrders does not allow inverse orders for non UTA2.0 account');
|
|
4218
4240
|
}
|
|
4219
4241
|
const request = {
|
|
4220
4242
|
'category': category,
|
|
@@ -4397,6 +4419,95 @@ class bybit extends bybit$1 {
|
|
|
4397
4419
|
'id': this.safeString(result, 'orderId'),
|
|
4398
4420
|
});
|
|
4399
4421
|
}
|
|
4422
|
+
/**
|
|
4423
|
+
* @method
|
|
4424
|
+
* @name bybit#editOrders
|
|
4425
|
+
* @description edit a list of trade orders
|
|
4426
|
+
* @see https://bybit-exchange.github.io/docs/v5/order/batch-amend
|
|
4427
|
+
* @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
|
4428
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
4429
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
4430
|
+
*/
|
|
4431
|
+
async editOrders(orders, params = {}) {
|
|
4432
|
+
await this.loadMarkets();
|
|
4433
|
+
const ordersRequests = [];
|
|
4434
|
+
let orderSymbols = [];
|
|
4435
|
+
for (let i = 0; i < orders.length; i++) {
|
|
4436
|
+
const rawOrder = orders[i];
|
|
4437
|
+
const symbol = this.safeString(rawOrder, 'symbol');
|
|
4438
|
+
orderSymbols.push(symbol);
|
|
4439
|
+
const id = this.safeString(rawOrder, 'id');
|
|
4440
|
+
const type = this.safeString(rawOrder, 'type');
|
|
4441
|
+
const side = this.safeString(rawOrder, 'side');
|
|
4442
|
+
const amount = this.safeValue(rawOrder, 'amount');
|
|
4443
|
+
const price = this.safeValue(rawOrder, 'price');
|
|
4444
|
+
const orderParams = this.safeDict(rawOrder, 'params', {});
|
|
4445
|
+
const orderRequest = this.editOrderRequest(id, symbol, type, side, amount, price, orderParams);
|
|
4446
|
+
delete orderRequest['category'];
|
|
4447
|
+
ordersRequests.push(orderRequest);
|
|
4448
|
+
}
|
|
4449
|
+
orderSymbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
|
|
4450
|
+
const market = this.market(orderSymbols[0]);
|
|
4451
|
+
const unifiedMarginStatus = this.safeInteger(this.options, 'unifiedMarginStatus', 3);
|
|
4452
|
+
let category = undefined;
|
|
4453
|
+
[category, params] = this.getBybitType('editOrders', market, params);
|
|
4454
|
+
if ((category === 'inverse') && (unifiedMarginStatus < 5)) {
|
|
4455
|
+
throw new errors.NotSupported(this.id + ' editOrders does not allow inverse orders for non UTA2.0 account');
|
|
4456
|
+
}
|
|
4457
|
+
const request = {
|
|
4458
|
+
'category': category,
|
|
4459
|
+
'request': ordersRequests,
|
|
4460
|
+
};
|
|
4461
|
+
const response = await this.privatePostV5OrderAmendBatch(this.extend(request, params));
|
|
4462
|
+
const result = this.safeDict(response, 'result', {});
|
|
4463
|
+
const data = this.safeList(result, 'list', []);
|
|
4464
|
+
const retInfo = this.safeDict(response, 'retExtInfo', {});
|
|
4465
|
+
const codes = this.safeList(retInfo, 'list', []);
|
|
4466
|
+
// extend the error with the unsuccessful orders
|
|
4467
|
+
for (let i = 0; i < codes.length; i++) {
|
|
4468
|
+
const code = codes[i];
|
|
4469
|
+
const retCode = this.safeInteger(code, 'code');
|
|
4470
|
+
if (retCode !== 0) {
|
|
4471
|
+
data[i] = this.extend(data[i], code);
|
|
4472
|
+
}
|
|
4473
|
+
}
|
|
4474
|
+
//
|
|
4475
|
+
// {
|
|
4476
|
+
// "retCode": 0,
|
|
4477
|
+
// "retMsg": "OK",
|
|
4478
|
+
// "result": {
|
|
4479
|
+
// "list": [
|
|
4480
|
+
// {
|
|
4481
|
+
// "category": "option",
|
|
4482
|
+
// "symbol": "ETH-30DEC22-500-C",
|
|
4483
|
+
// "orderId": "b551f227-7059-4fb5-a6a6-699c04dbd2f2",
|
|
4484
|
+
// "orderLinkId": ""
|
|
4485
|
+
// },
|
|
4486
|
+
// {
|
|
4487
|
+
// "category": "option",
|
|
4488
|
+
// "symbol": "ETH-30DEC22-700-C",
|
|
4489
|
+
// "orderId": "fa6a595f-1a57-483f-b9d3-30e9c8235a52",
|
|
4490
|
+
// "orderLinkId": ""
|
|
4491
|
+
// }
|
|
4492
|
+
// ]
|
|
4493
|
+
// },
|
|
4494
|
+
// "retExtInfo": {
|
|
4495
|
+
// "list": [
|
|
4496
|
+
// {
|
|
4497
|
+
// "code": 0,
|
|
4498
|
+
// "msg": "OK"
|
|
4499
|
+
// },
|
|
4500
|
+
// {
|
|
4501
|
+
// "code": 0,
|
|
4502
|
+
// "msg": "OK"
|
|
4503
|
+
// }
|
|
4504
|
+
// ]
|
|
4505
|
+
// },
|
|
4506
|
+
// "time": 1672222808060
|
|
4507
|
+
// }
|
|
4508
|
+
//
|
|
4509
|
+
return this.parseOrders(data);
|
|
4510
|
+
}
|
|
4400
4511
|
cancelOrderRequest(id, symbol = undefined, params = {}) {
|
|
4401
4512
|
const market = this.market(symbol);
|
|
4402
4513
|
const request = {
|
package/dist/cjs/src/kraken.js
CHANGED
|
@@ -976,9 +976,9 @@ class kraken extends kraken$1 {
|
|
|
976
976
|
'high': this.safeString(high, 1),
|
|
977
977
|
'low': this.safeString(low, 1),
|
|
978
978
|
'bid': this.safeString(bid, 0),
|
|
979
|
-
'bidVolume':
|
|
979
|
+
'bidVolume': this.safeString(bid, 2),
|
|
980
980
|
'ask': this.safeString(ask, 0),
|
|
981
|
-
'askVolume':
|
|
981
|
+
'askVolume': this.safeString(ask, 2),
|
|
982
982
|
'vwap': vwap,
|
|
983
983
|
'open': this.safeString(ticker, 'o'),
|
|
984
984
|
'close': last,
|
package/dist/cjs/src/phemex.js
CHANGED
|
@@ -34,6 +34,7 @@ class phemex extends phemex$1 {
|
|
|
34
34
|
'cancelAllOrders': true,
|
|
35
35
|
'cancelOrder': true,
|
|
36
36
|
'closePosition': false,
|
|
37
|
+
'createConvertTrade': true,
|
|
37
38
|
'createOrder': true,
|
|
38
39
|
'createReduceOnlyOrder': true,
|
|
39
40
|
'createStopLimitOrder': true,
|
|
@@ -44,6 +45,9 @@ class phemex extends phemex$1 {
|
|
|
44
45
|
'fetchBorrowRateHistories': false,
|
|
45
46
|
'fetchBorrowRateHistory': false,
|
|
46
47
|
'fetchClosedOrders': true,
|
|
48
|
+
'fetchConvertQuote': true,
|
|
49
|
+
'fetchConvertTrade': false,
|
|
50
|
+
'fetchConvertTradeHistory': true,
|
|
47
51
|
'fetchCrossBorrowRate': false,
|
|
48
52
|
'fetchCrossBorrowRates': false,
|
|
49
53
|
'fetchCurrencies': true,
|
|
@@ -1067,7 +1071,7 @@ class phemex extends phemex$1 {
|
|
|
1067
1071
|
for (let i = 0; i < products.length; i++) {
|
|
1068
1072
|
let market = products[i];
|
|
1069
1073
|
const type = this.safeStringLower(market, 'type');
|
|
1070
|
-
if ((type === 'perpetual') || (type === 'perpetualv2') || (type === '
|
|
1074
|
+
if ((type === 'perpetual') || (type === 'perpetualv2') || (type === 'perpetualpilot')) {
|
|
1071
1075
|
const id = this.safeString(market, 'symbol');
|
|
1072
1076
|
const riskLimitValues = this.safeValue(riskLimitsById, id, {});
|
|
1073
1077
|
market = this.extend(market, riskLimitValues);
|
|
@@ -1258,7 +1262,7 @@ class phemex extends phemex$1 {
|
|
|
1258
1262
|
precise.decimals = precise.decimals - scale;
|
|
1259
1263
|
precise.reduce();
|
|
1260
1264
|
const preciseString = precise.toString();
|
|
1261
|
-
return this.
|
|
1265
|
+
return this.parseToNumeric(preciseString);
|
|
1262
1266
|
}
|
|
1263
1267
|
toEv(amount, market = undefined) {
|
|
1264
1268
|
if ((amount === undefined) || (market === undefined)) {
|
|
@@ -2625,7 +2629,6 @@ class phemex extends phemex$1 {
|
|
|
2625
2629
|
const market = this.market(symbol);
|
|
2626
2630
|
const requestSide = this.capitalize(side);
|
|
2627
2631
|
type = this.capitalize(type);
|
|
2628
|
-
const reduceOnly = this.safeBool(params, 'reduceOnly');
|
|
2629
2632
|
const request = {
|
|
2630
2633
|
// common
|
|
2631
2634
|
'symbol': market['id'],
|
|
@@ -2725,8 +2728,10 @@ class phemex extends phemex$1 {
|
|
|
2725
2728
|
let posSide = this.safeStringLower(params, 'posSide');
|
|
2726
2729
|
if (posSide === undefined) {
|
|
2727
2730
|
if (hedged) {
|
|
2731
|
+
const reduceOnly = this.safeBool(params, 'reduceOnly');
|
|
2728
2732
|
if (reduceOnly) {
|
|
2729
2733
|
side = (side === 'buy') ? 'sell' : 'buy';
|
|
2734
|
+
params = this.omit(params, 'reduceOnly');
|
|
2730
2735
|
}
|
|
2731
2736
|
posSide = (side === 'buy') ? 'Long' : 'Short';
|
|
2732
2737
|
}
|
|
@@ -2841,7 +2846,6 @@ class phemex extends phemex$1 {
|
|
|
2841
2846
|
}
|
|
2842
2847
|
params = this.omit(params, 'stopLossPrice');
|
|
2843
2848
|
}
|
|
2844
|
-
params = this.omit(params, 'reduceOnly');
|
|
2845
2849
|
let response = undefined;
|
|
2846
2850
|
if (market['settle'] === 'USDT') {
|
|
2847
2851
|
response = await this.privatePostGOrders(this.extend(request, params));
|
|
@@ -5066,6 +5070,224 @@ class phemex extends phemex$1 {
|
|
|
5066
5070
|
'datetime': this.iso8601(timestamp),
|
|
5067
5071
|
}, market);
|
|
5068
5072
|
}
|
|
5073
|
+
/**
|
|
5074
|
+
* @method
|
|
5075
|
+
* @name phemex#fetchConvertQuote
|
|
5076
|
+
* @description fetch a quote for converting from one currency to another
|
|
5077
|
+
* @see https://phemex-docs.github.io/#rfq-quote
|
|
5078
|
+
* @param {string} fromCode the currency that you want to sell and convert from
|
|
5079
|
+
* @param {string} toCode the currency that you want to buy and convert into
|
|
5080
|
+
* @param {float} amount how much you want to trade in units of the from currency
|
|
5081
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
5082
|
+
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
|
5083
|
+
*/
|
|
5084
|
+
async fetchConvertQuote(fromCode, toCode, amount = undefined, params = {}) {
|
|
5085
|
+
await this.loadMarkets();
|
|
5086
|
+
const fromCurrency = this.currency(fromCode);
|
|
5087
|
+
const toCurrency = this.currency(toCode);
|
|
5088
|
+
const valueScale = this.safeInteger(fromCurrency, 'valueScale');
|
|
5089
|
+
const request = {
|
|
5090
|
+
'fromCurrency': fromCode,
|
|
5091
|
+
'toCurrency': toCode,
|
|
5092
|
+
'fromAmountEv': this.toEn(amount, valueScale),
|
|
5093
|
+
};
|
|
5094
|
+
const response = await this.privateGetAssetsQuote(this.extend(request, params));
|
|
5095
|
+
//
|
|
5096
|
+
// {
|
|
5097
|
+
// "code": 0,
|
|
5098
|
+
// "msg": "OK",
|
|
5099
|
+
// "data": {
|
|
5100
|
+
// "code": "GIF...AAA",
|
|
5101
|
+
// "quoteArgs": {
|
|
5102
|
+
// "origin": 10,
|
|
5103
|
+
// "price": "0.00000939",
|
|
5104
|
+
// "proceeds": "0.00000000",
|
|
5105
|
+
// "ttlMs": 7000,
|
|
5106
|
+
// "expireAt": 1739875826009,
|
|
5107
|
+
// "requestAt": 1739875818009,
|
|
5108
|
+
// "quoteAt": 1739875816594
|
|
5109
|
+
// }
|
|
5110
|
+
// }
|
|
5111
|
+
// }
|
|
5112
|
+
//
|
|
5113
|
+
const data = this.safeDict(response, 'data', {});
|
|
5114
|
+
return this.parseConversion(data, fromCurrency, toCurrency);
|
|
5115
|
+
}
|
|
5116
|
+
/**
|
|
5117
|
+
* @method
|
|
5118
|
+
* @name phemex#createConvertTrade
|
|
5119
|
+
* @description convert from one currency to another
|
|
5120
|
+
* @see https://phemex-docs.github.io/#convert
|
|
5121
|
+
* @param {string} id the id of the trade that you want to make
|
|
5122
|
+
* @param {string} fromCode the currency that you want to sell and convert from
|
|
5123
|
+
* @param {string} toCode the currency that you want to buy and convert into
|
|
5124
|
+
* @param {float} [amount] how much you want to trade in units of the from currency
|
|
5125
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
5126
|
+
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
|
5127
|
+
*/
|
|
5128
|
+
async createConvertTrade(id, fromCode, toCode, amount = undefined, params = {}) {
|
|
5129
|
+
await this.loadMarkets();
|
|
5130
|
+
const fromCurrency = this.currency(fromCode);
|
|
5131
|
+
const toCurrency = this.currency(toCode);
|
|
5132
|
+
const valueScale = this.safeInteger(fromCurrency, 'valueScale');
|
|
5133
|
+
const request = {
|
|
5134
|
+
'code': id,
|
|
5135
|
+
'fromCurrency': fromCode,
|
|
5136
|
+
'toCurrency': toCode,
|
|
5137
|
+
};
|
|
5138
|
+
if (amount !== undefined) {
|
|
5139
|
+
request['fromAmountEv'] = this.toEn(amount, valueScale);
|
|
5140
|
+
}
|
|
5141
|
+
const response = await this.privatePostAssetsConvert(this.extend(request, params));
|
|
5142
|
+
//
|
|
5143
|
+
// {
|
|
5144
|
+
// "code": 0,
|
|
5145
|
+
// "msg": "OK",
|
|
5146
|
+
// "data": {
|
|
5147
|
+
// "moveOp": 0,
|
|
5148
|
+
// "fromCurrency": "USDT",
|
|
5149
|
+
// "toCurrency": "BTC",
|
|
5150
|
+
// "fromAmountEv": 4000000000,
|
|
5151
|
+
// "toAmountEv": 41511,
|
|
5152
|
+
// "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
5153
|
+
// "status": 10
|
|
5154
|
+
// }
|
|
5155
|
+
// }
|
|
5156
|
+
//
|
|
5157
|
+
const data = this.safeDict(response, 'data', {});
|
|
5158
|
+
const fromCurrencyId = this.safeString(data, 'fromCurrency');
|
|
5159
|
+
const fromResult = this.safeCurrency(fromCurrencyId, fromCurrency);
|
|
5160
|
+
const toCurrencyId = this.safeString(data, 'toCurrency');
|
|
5161
|
+
const to = this.safeCurrency(toCurrencyId, toCurrency);
|
|
5162
|
+
return this.parseConversion(data, fromResult, to);
|
|
5163
|
+
}
|
|
5164
|
+
/**
|
|
5165
|
+
* @method
|
|
5166
|
+
* @name phemex#fetchConvertTradeHistory
|
|
5167
|
+
* @description fetch the users history of conversion trades
|
|
5168
|
+
* @see https://phemex-docs.github.io/#query-convert-history
|
|
5169
|
+
* @param {string} [code] the unified currency code
|
|
5170
|
+
* @param {int} [since] the earliest time in ms to fetch conversions for
|
|
5171
|
+
* @param {int} [limit] the maximum number of conversion structures to retrieve, default 20, max 200
|
|
5172
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
5173
|
+
* @param {string} [params.until] the end time in ms
|
|
5174
|
+
* @param {string} [params.fromCurrency] the currency that you sold and converted from
|
|
5175
|
+
* @param {string} [params.toCurrency] the currency that you bought and converted into
|
|
5176
|
+
* @returns {object[]} a list of [conversion structures]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
|
5177
|
+
*/
|
|
5178
|
+
async fetchConvertTradeHistory(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
5179
|
+
await this.loadMarkets();
|
|
5180
|
+
let request = {};
|
|
5181
|
+
if (code !== undefined) {
|
|
5182
|
+
request['fromCurrency'] = code;
|
|
5183
|
+
}
|
|
5184
|
+
if (since !== undefined) {
|
|
5185
|
+
request['startTime'] = since;
|
|
5186
|
+
}
|
|
5187
|
+
if (limit !== undefined) {
|
|
5188
|
+
request['limit'] = limit;
|
|
5189
|
+
}
|
|
5190
|
+
[request, params] = this.handleUntilOption('endTime', request, params);
|
|
5191
|
+
const response = await this.privateGetAssetsConvert(this.extend(request, params));
|
|
5192
|
+
//
|
|
5193
|
+
// {
|
|
5194
|
+
// "code": 0,
|
|
5195
|
+
// "msg": "OK",
|
|
5196
|
+
// "data": {
|
|
5197
|
+
// "total": 2,
|
|
5198
|
+
// "rows": [
|
|
5199
|
+
// {
|
|
5200
|
+
// "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
5201
|
+
// "createTime": 1739882294000,
|
|
5202
|
+
// "fromCurrency": "USDT",
|
|
5203
|
+
// "toCurrency": "BTC",
|
|
5204
|
+
// "fromAmountEv": 4000000000,
|
|
5205
|
+
// "toAmountEv": 41511,
|
|
5206
|
+
// "status": 10,
|
|
5207
|
+
// "conversionRate": 1037,
|
|
5208
|
+
// "errorCode": 0
|
|
5209
|
+
// },
|
|
5210
|
+
// ]
|
|
5211
|
+
// }
|
|
5212
|
+
// }
|
|
5213
|
+
//
|
|
5214
|
+
const data = this.safeDict(response, 'data', {});
|
|
5215
|
+
const rows = this.safeList(data, 'rows', []);
|
|
5216
|
+
return this.parseConversions(rows, code, 'fromCurrency', 'toCurrency', since, limit);
|
|
5217
|
+
}
|
|
5218
|
+
parseConversion(conversion, fromCurrency = undefined, toCurrency = undefined) {
|
|
5219
|
+
//
|
|
5220
|
+
// fetchConvertQuote
|
|
5221
|
+
//
|
|
5222
|
+
// {
|
|
5223
|
+
// "code": "GIF...AAA",
|
|
5224
|
+
// "quoteArgs": {
|
|
5225
|
+
// "origin": 10,
|
|
5226
|
+
// "price": "0.00000939",
|
|
5227
|
+
// "proceeds": "0.00000000",
|
|
5228
|
+
// "ttlMs": 7000,
|
|
5229
|
+
// "expireAt": 1739875826009,
|
|
5230
|
+
// "requestAt": 1739875818009,
|
|
5231
|
+
// "quoteAt": 1739875816594
|
|
5232
|
+
// }
|
|
5233
|
+
// }
|
|
5234
|
+
//
|
|
5235
|
+
// createConvertTrade
|
|
5236
|
+
//
|
|
5237
|
+
// {
|
|
5238
|
+
// "moveOp": 0,
|
|
5239
|
+
// "fromCurrency": "USDT",
|
|
5240
|
+
// "toCurrency": "BTC",
|
|
5241
|
+
// "fromAmountEv": 4000000000,
|
|
5242
|
+
// "toAmountEv": 41511,
|
|
5243
|
+
// "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
5244
|
+
// "status": 10
|
|
5245
|
+
// }
|
|
5246
|
+
//
|
|
5247
|
+
// fetchConvertTradeHistory
|
|
5248
|
+
//
|
|
5249
|
+
// {
|
|
5250
|
+
// "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
5251
|
+
// "createTime": 1739882294000,
|
|
5252
|
+
// "fromCurrency": "USDT",
|
|
5253
|
+
// "toCurrency": "BTC",
|
|
5254
|
+
// "fromAmountEv": 4000000000,
|
|
5255
|
+
// "toAmountEv": 41511,
|
|
5256
|
+
// "status": 10,
|
|
5257
|
+
// "conversionRate": 1037,
|
|
5258
|
+
// "errorCode": 0
|
|
5259
|
+
// }
|
|
5260
|
+
//
|
|
5261
|
+
const quoteArgs = this.safeDict(conversion, 'quoteArgs', {});
|
|
5262
|
+
const requestTime = this.safeInteger(quoteArgs, 'requestAt');
|
|
5263
|
+
const timestamp = this.safeInteger(conversion, 'createTime', requestTime);
|
|
5264
|
+
const fromCoin = this.safeString(conversion, 'fromCurrency', this.safeString(fromCurrency, 'code'));
|
|
5265
|
+
const fromCode = this.safeCurrencyCode(fromCoin, fromCurrency);
|
|
5266
|
+
const toCoin = this.safeString(conversion, 'toCurrency', this.safeString(toCurrency, 'code'));
|
|
5267
|
+
const toCode = this.safeCurrencyCode(toCoin, toCurrency);
|
|
5268
|
+
const fromValueScale = this.safeInteger(fromCurrency, 'valueScale');
|
|
5269
|
+
const toValueScale = this.safeInteger(toCurrency, 'valueScale');
|
|
5270
|
+
let fromAmount = this.fromEn(this.safeString(conversion, 'fromAmountEv'), fromValueScale);
|
|
5271
|
+
if (fromAmount === undefined && quoteArgs !== undefined) {
|
|
5272
|
+
fromAmount = this.fromEn(this.safeString(quoteArgs, 'origin'), fromValueScale);
|
|
5273
|
+
}
|
|
5274
|
+
let toAmount = this.fromEn(this.safeString(conversion, 'toAmountEv'), toValueScale);
|
|
5275
|
+
if (toAmount === undefined && quoteArgs !== undefined) {
|
|
5276
|
+
toAmount = this.fromEn(this.safeString(quoteArgs, 'proceeds'), toValueScale);
|
|
5277
|
+
}
|
|
5278
|
+
return {
|
|
5279
|
+
'info': conversion,
|
|
5280
|
+
'timestamp': timestamp,
|
|
5281
|
+
'datetime': this.iso8601(timestamp),
|
|
5282
|
+
'id': this.safeString(conversion, 'code'),
|
|
5283
|
+
'fromCurrency': fromCode,
|
|
5284
|
+
'fromAmount': this.parseNumber(fromAmount),
|
|
5285
|
+
'toCurrency': toCode,
|
|
5286
|
+
'toAmount': this.parseNumber(toAmount),
|
|
5287
|
+
'price': this.safeNumber(quoteArgs, 'price'),
|
|
5288
|
+
'fee': undefined,
|
|
5289
|
+
};
|
|
5290
|
+
}
|
|
5069
5291
|
handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
5070
5292
|
if (response === undefined) {
|
|
5071
5293
|
return undefined; // fallback to default error handler
|