ccxt 4.1.45 → 4.1.47
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.js +1692 -194
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +14 -3
- package/dist/cjs/src/base/ws/Cache.js +50 -0
- package/dist/cjs/src/binance.js +4 -0
- package/dist/cjs/src/bitmart.js +2 -2
- package/dist/cjs/src/bitvavo.js +6 -5
- package/dist/cjs/src/bybit.js +84 -132
- package/dist/cjs/src/cryptocom.js +1 -1
- package/dist/cjs/src/gate.js +3 -1
- package/dist/cjs/src/hitbtc.js +79 -1
- package/dist/cjs/src/huobi.js +1 -2
- package/dist/cjs/src/krakenfutures.js +13 -3
- package/dist/cjs/src/okx.js +19 -2
- package/dist/cjs/src/pro/binance.js +203 -1
- package/dist/cjs/src/pro/bitget.js +181 -0
- package/dist/cjs/src/pro/bybit.js +154 -10
- package/dist/cjs/src/pro/cryptocom.js +131 -1
- package/dist/cjs/src/pro/gate.js +161 -0
- package/dist/cjs/src/pro/huobi.js +128 -4
- package/dist/cjs/src/pro/krakenfutures.js +129 -0
- package/dist/cjs/src/pro/kucoinfutures.js +182 -0
- package/dist/cjs/src/pro/okx.js +121 -0
- package/js/ccxt.d.ts +3 -3
- package/js/ccxt.js +1 -1
- package/js/src/abstract/binance.d.ts +4 -0
- package/js/src/abstract/binancecoinm.d.ts +4 -0
- package/js/src/abstract/binanceus.d.ts +4 -0
- package/js/src/abstract/binanceusdm.d.ts +4 -0
- package/js/src/ascendex.d.ts +3 -3
- package/js/src/base/Exchange.d.ts +6 -2
- package/js/src/base/Exchange.js +14 -3
- package/js/src/base/types.d.ts +5 -0
- package/js/src/base/ws/Cache.d.ts +5 -1
- package/js/src/base/ws/Cache.js +50 -1
- package/js/src/bigone.d.ts +2 -2
- package/js/src/binance.d.ts +2 -2
- package/js/src/binance.js +4 -0
- package/js/src/bingx.d.ts +2 -2
- package/js/src/bitbns.d.ts +2 -2
- package/js/src/bitfinex.d.ts +3 -3
- package/js/src/bitfinex2.d.ts +3 -3
- package/js/src/bitflyer.d.ts +2 -2
- package/js/src/bitget.d.ts +2 -2
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +2 -2
- package/js/src/bitmex.d.ts +1 -1
- package/js/src/bitopro.d.ts +2 -2
- package/js/src/bitpanda.d.ts +2 -2
- package/js/src/bitrue.d.ts +2 -2
- package/js/src/bitso.d.ts +1 -1
- package/js/src/bitstamp.d.ts +2 -2
- package/js/src/bittrex.d.ts +4 -4
- package/js/src/bitvavo.d.ts +2 -2
- package/js/src/bitvavo.js +6 -5
- package/js/src/blockchaincom.d.ts +4 -4
- package/js/src/btcalpha.d.ts +2 -2
- package/js/src/btcmarkets.d.ts +3 -3
- package/js/src/bybit.d.ts +2 -4
- package/js/src/bybit.js +84 -132
- package/js/src/coinbase.d.ts +5 -5
- package/js/src/coinbasepro.d.ts +3 -3
- package/js/src/coincheck.d.ts +2 -2
- package/js/src/coinex.d.ts +8 -8
- package/js/src/coinfalcon.d.ts +2 -2
- package/js/src/coinlist.d.ts +1 -1
- package/js/src/coinmate.d.ts +1 -1
- package/js/src/coinsph.d.ts +2 -2
- package/js/src/cryptocom.d.ts +2 -2
- package/js/src/cryptocom.js +1 -1
- package/js/src/currencycom.d.ts +6 -6
- package/js/src/deribit.d.ts +2 -2
- package/js/src/digifinex.d.ts +2 -2
- package/js/src/exmo.d.ts +3 -3
- package/js/src/gate.d.ts +2 -2
- package/js/src/gate.js +3 -1
- package/js/src/gemini.d.ts +1 -1
- package/js/src/hitbtc.d.ts +5 -4
- package/js/src/hitbtc.js +79 -1
- package/js/src/hollaex.d.ts +2 -2
- package/js/src/huobi.d.ts +2 -2
- package/js/src/huobi.js +1 -2
- package/js/src/huobijp.d.ts +2 -2
- package/js/src/idex.d.ts +2 -2
- package/js/src/indodax.d.ts +1 -1
- package/js/src/kraken.d.ts +2 -2
- package/js/src/krakenfutures.js +14 -4
- package/js/src/kucoin.d.ts +2 -2
- package/js/src/kucoinfutures.d.ts +3 -3
- package/js/src/kuna.d.ts +2 -2
- package/js/src/latoken.d.ts +2 -2
- package/js/src/lbank2.d.ts +2 -2
- package/js/src/lykke.d.ts +1 -1
- package/js/src/mexc.d.ts +2 -2
- package/js/src/ndax.d.ts +2 -2
- package/js/src/novadax.d.ts +3 -3
- package/js/src/okcoin.d.ts +8 -8
- package/js/src/okx.d.ts +7 -7
- package/js/src/okx.js +19 -2
- package/js/src/phemex.d.ts +6 -6
- package/js/src/poloniex.d.ts +3 -3
- package/js/src/pro/binance.d.ts +6 -0
- package/js/src/pro/binance.js +204 -2
- package/js/src/pro/bitget.d.ts +3 -0
- package/js/src/pro/bitget.js +182 -1
- package/js/src/pro/bybit.d.ts +5 -1
- package/js/src/pro/bybit.js +156 -12
- package/js/src/pro/cryptocom.d.ts +4 -0
- package/js/src/pro/cryptocom.js +132 -2
- package/js/src/pro/gate.d.ts +5 -0
- package/js/src/pro/gate.js +162 -1
- package/js/src/pro/huobi.d.ts +2 -0
- package/js/src/pro/huobi.js +129 -5
- package/js/src/pro/krakenfutures.d.ts +3 -0
- package/js/src/pro/krakenfutures.js +129 -0
- package/js/src/pro/kucoinfutures.d.ts +5 -0
- package/js/src/pro/kucoinfutures.js +182 -0
- package/js/src/pro/okx.d.ts +2 -0
- package/js/src/pro/okx.js +123 -2
- package/js/src/probit.d.ts +2 -2
- package/js/src/timex.d.ts +2 -2
- package/js/src/tokocrypto.d.ts +5 -5
- package/js/src/upbit.d.ts +2 -2
- package/js/src/wavesexchange.d.ts +2 -2
- package/js/src/whitebit.d.ts +1 -1
- package/js/src/woo.d.ts +3 -3
- package/package.json +1 -1
- package/skip-tests.json +8 -1
package/dist/cjs/src/okx.js
CHANGED
|
@@ -2551,6 +2551,13 @@ class okx extends okx$1 {
|
|
|
2551
2551
|
request['tdMode'] = tradeMode;
|
|
2552
2552
|
}
|
|
2553
2553
|
else if (contract) {
|
|
2554
|
+
if (market['swap'] || market['future']) {
|
|
2555
|
+
let positionSide = undefined;
|
|
2556
|
+
[positionSide, params] = this.handleOptionAndParams(params, 'createOrder', 'positionSide');
|
|
2557
|
+
if (positionSide !== undefined) {
|
|
2558
|
+
request['posSide'] = positionSide;
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2554
2561
|
request['tdMode'] = marginMode;
|
|
2555
2562
|
}
|
|
2556
2563
|
const isMarketOrder = type === 'market';
|
|
@@ -2747,7 +2754,7 @@ class okx extends okx$1 {
|
|
|
2747
2754
|
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
2748
2755
|
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
2749
2756
|
* @param {object} [params] extra parameters specific to the okx api endpoint
|
|
2750
|
-
* @param {bool} [params.reduceOnly]
|
|
2757
|
+
* @param {bool} [params.reduceOnly] a mark to reduce the position size for margin, swap and future orders
|
|
2751
2758
|
* @param {bool} [params.postOnly] true to place a post only order
|
|
2752
2759
|
* @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered (perpetual swap markets only)
|
|
2753
2760
|
* @param {float} [params.takeProfit.triggerPrice] take profit trigger price
|
|
@@ -2757,6 +2764,7 @@ class okx extends okx$1 {
|
|
|
2757
2764
|
* @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
|
|
2758
2765
|
* @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders
|
|
2759
2766
|
* @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type
|
|
2767
|
+
* @param {string} [params.positionSide] if position mode is one-way: set to 'net', if position mode is hedge-mode: set to 'long' or 'short'
|
|
2760
2768
|
* @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
|
|
2761
2769
|
*/
|
|
2762
2770
|
await this.loadMarkets();
|
|
@@ -2776,7 +2784,16 @@ class okx extends okx$1 {
|
|
|
2776
2784
|
// because it has a lower ratelimit
|
|
2777
2785
|
request = [request];
|
|
2778
2786
|
}
|
|
2779
|
-
|
|
2787
|
+
let response = undefined;
|
|
2788
|
+
if (method === 'privatePostTradeOrder') {
|
|
2789
|
+
response = await this.privatePostTradeOrder(request);
|
|
2790
|
+
}
|
|
2791
|
+
else if (method === 'privatePostTradeOrderAlgo') {
|
|
2792
|
+
response = await this.privatePostTradeOrderAlgo(request);
|
|
2793
|
+
}
|
|
2794
|
+
else {
|
|
2795
|
+
response = await this.privatePostTradeBatchOrders(request);
|
|
2796
|
+
}
|
|
2780
2797
|
const data = this.safeValue(response, 'data', []);
|
|
2781
2798
|
const first = this.safeValue(data, 0);
|
|
2782
2799
|
const order = this.parseOrder(first, market);
|
|
@@ -23,6 +23,7 @@ class binance extends binance$1 {
|
|
|
23
23
|
'watchOrderBook': true,
|
|
24
24
|
'watchOrderBookForSymbols': true,
|
|
25
25
|
'watchOrders': true,
|
|
26
|
+
'watchPositions': true,
|
|
26
27
|
'watchTicker': true,
|
|
27
28
|
'watchTickers': true,
|
|
28
29
|
'watchTrades': true,
|
|
@@ -97,6 +98,10 @@ class binance extends binance$1 {
|
|
|
97
98
|
'fetchBalanceSnapshot': false,
|
|
98
99
|
'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
|
|
99
100
|
},
|
|
101
|
+
'watchPositions': {
|
|
102
|
+
'fetchPositionsSnapshot': true,
|
|
103
|
+
'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
|
|
104
|
+
},
|
|
100
105
|
'wallet': 'wb',
|
|
101
106
|
'listenKeyRefreshRate': 1200000,
|
|
102
107
|
'ws': {
|
|
@@ -1479,6 +1484,7 @@ class binance extends binance$1 {
|
|
|
1479
1484
|
const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
|
|
1480
1485
|
const client = this.client(url);
|
|
1481
1486
|
this.setBalanceCache(client, type);
|
|
1487
|
+
this.setPositionsCache(client, type);
|
|
1482
1488
|
const options = this.safeValue(this.options, 'watchBalance');
|
|
1483
1489
|
const fetchBalanceSnapshot = this.safeValue(options, 'fetchBalanceSnapshot', false);
|
|
1484
1490
|
const awaitBalanceSnapshot = this.safeValue(options, 'awaitBalanceSnapshot', true);
|
|
@@ -1553,6 +1559,9 @@ class binance extends binance$1 {
|
|
|
1553
1559
|
const subscriptions = Object.keys(client.subscriptions);
|
|
1554
1560
|
const accountType = subscriptions[0];
|
|
1555
1561
|
const messageHash = accountType + ':balance';
|
|
1562
|
+
if (this.balance[accountType] === undefined) {
|
|
1563
|
+
this.balance[accountType] = {};
|
|
1564
|
+
}
|
|
1556
1565
|
this.balance[accountType]['info'] = message;
|
|
1557
1566
|
const event = this.safeString(message, 'e');
|
|
1558
1567
|
if (event === 'balanceUpdate') {
|
|
@@ -2084,6 +2093,7 @@ class binance extends binance$1 {
|
|
|
2084
2093
|
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2085
2094
|
const client = this.client(url);
|
|
2086
2095
|
this.setBalanceCache(client, type);
|
|
2096
|
+
this.setPositionsCache(client, type);
|
|
2087
2097
|
const message = undefined;
|
|
2088
2098
|
const orders = await this.watch(url, messageHash, message, type);
|
|
2089
2099
|
if (this.newUpdates) {
|
|
@@ -2331,6 +2341,193 @@ class binance extends binance$1 {
|
|
|
2331
2341
|
this.handleMyTrade(client, message);
|
|
2332
2342
|
this.handleOrder(client, message);
|
|
2333
2343
|
}
|
|
2344
|
+
async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2345
|
+
/**
|
|
2346
|
+
* @method
|
|
2347
|
+
* @name binance#watchPositions
|
|
2348
|
+
* @description watch all open positions
|
|
2349
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
2350
|
+
* @param {object} params extra parameters specific to the binance api endpoint
|
|
2351
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
2352
|
+
*/
|
|
2353
|
+
await this.loadMarkets();
|
|
2354
|
+
await this.authenticate(params);
|
|
2355
|
+
let market = undefined;
|
|
2356
|
+
let messageHash = '';
|
|
2357
|
+
symbols = this.marketSymbols(symbols);
|
|
2358
|
+
if (!this.isEmpty(symbols)) {
|
|
2359
|
+
market = this.getMarketFromSymbols(symbols);
|
|
2360
|
+
messageHash = '::' + symbols.join(',');
|
|
2361
|
+
}
|
|
2362
|
+
const defaultType = this.safeString2(this.options, 'watchPositions', 'defaultType', 'future');
|
|
2363
|
+
let type = this.safeString(params, 'type', defaultType);
|
|
2364
|
+
let subType = undefined;
|
|
2365
|
+
[subType, params] = this.handleSubTypeAndParams('watchPositions', market, params);
|
|
2366
|
+
if (this.isLinear(type, subType)) {
|
|
2367
|
+
type = 'future';
|
|
2368
|
+
}
|
|
2369
|
+
else if (this.isInverse(type, subType)) {
|
|
2370
|
+
type = 'delivery';
|
|
2371
|
+
}
|
|
2372
|
+
messageHash = type + ':positions' + messageHash;
|
|
2373
|
+
const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
|
|
2374
|
+
const client = this.client(url);
|
|
2375
|
+
this.setBalanceCache(client, type);
|
|
2376
|
+
this.setPositionsCache(client, type, symbols);
|
|
2377
|
+
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
|
|
2378
|
+
const awaitPositionsSnapshot = this.safeValue('watchPositions', 'awaitPositionsSnapshot', true);
|
|
2379
|
+
const cache = this.safeValue(this.positions, type);
|
|
2380
|
+
if (fetchPositionsSnapshot && awaitPositionsSnapshot && cache === undefined) {
|
|
2381
|
+
const snapshot = await client.future(type + ':fetchPositionsSnapshot');
|
|
2382
|
+
return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
|
|
2383
|
+
}
|
|
2384
|
+
const newPositions = await this.watch(url, messageHash, undefined, type);
|
|
2385
|
+
if (this.newUpdates) {
|
|
2386
|
+
return newPositions;
|
|
2387
|
+
}
|
|
2388
|
+
return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
|
|
2389
|
+
}
|
|
2390
|
+
setPositionsCache(client, type, symbols = undefined) {
|
|
2391
|
+
if (this.positions === undefined) {
|
|
2392
|
+
this.positions = {};
|
|
2393
|
+
}
|
|
2394
|
+
if (type in this.positions) {
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2397
|
+
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', false);
|
|
2398
|
+
if (fetchPositionsSnapshot) {
|
|
2399
|
+
const messageHash = type + ':fetchPositionsSnapshot';
|
|
2400
|
+
if (!(messageHash in client.futures)) {
|
|
2401
|
+
client.future(messageHash);
|
|
2402
|
+
this.spawn(this.loadPositionsSnapshot, client, messageHash, type);
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
else {
|
|
2406
|
+
this.positions[type] = new Cache.ArrayCacheBySymbolBySide();
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
async loadPositionsSnapshot(client, messageHash, type) {
|
|
2410
|
+
const positions = await this.fetchPositions(undefined, { 'type': type });
|
|
2411
|
+
this.positions[type] = new Cache.ArrayCacheBySymbolBySide();
|
|
2412
|
+
const cache = this.positions[type];
|
|
2413
|
+
for (let i = 0; i < positions.length; i++) {
|
|
2414
|
+
const position = positions[i];
|
|
2415
|
+
const contracts = this.safeNumber(position, 'contracts', 0);
|
|
2416
|
+
if (contracts > 0) {
|
|
2417
|
+
cache.append(position);
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
// don't remove the future from the .futures cache
|
|
2421
|
+
const future = client.futures[messageHash];
|
|
2422
|
+
future.resolve(cache);
|
|
2423
|
+
client.resolve(cache, type + ':position');
|
|
2424
|
+
}
|
|
2425
|
+
handlePositions(client, message) {
|
|
2426
|
+
//
|
|
2427
|
+
// {
|
|
2428
|
+
// e: 'ACCOUNT_UPDATE',
|
|
2429
|
+
// T: 1667881353112,
|
|
2430
|
+
// E: 1667881353115,
|
|
2431
|
+
// a: {
|
|
2432
|
+
// B: [{
|
|
2433
|
+
// a: 'USDT',
|
|
2434
|
+
// wb: '1127.95750089',
|
|
2435
|
+
// cw: '1040.82091149',
|
|
2436
|
+
// bc: '0'
|
|
2437
|
+
// }],
|
|
2438
|
+
// P: [{
|
|
2439
|
+
// s: 'BTCUSDT',
|
|
2440
|
+
// pa: '-0.089',
|
|
2441
|
+
// ep: '19700.03933',
|
|
2442
|
+
// cr: '-1260.24809979',
|
|
2443
|
+
// up: '1.53058860',
|
|
2444
|
+
// mt: 'isolated',
|
|
2445
|
+
// iw: '87.13658940',
|
|
2446
|
+
// ps: 'BOTH',
|
|
2447
|
+
// ma: 'USDT'
|
|
2448
|
+
// }],
|
|
2449
|
+
// m: 'ORDER'
|
|
2450
|
+
// }
|
|
2451
|
+
// }
|
|
2452
|
+
//
|
|
2453
|
+
// each account is connected to a different endpoint
|
|
2454
|
+
// and has exactly one subscriptionhash which is the account type
|
|
2455
|
+
const subscriptions = Object.keys(client.subscriptions);
|
|
2456
|
+
const accountType = subscriptions[0];
|
|
2457
|
+
if (this.positions === undefined) {
|
|
2458
|
+
this.positions = {};
|
|
2459
|
+
}
|
|
2460
|
+
if (!(accountType in this.positions)) {
|
|
2461
|
+
this.positions[accountType] = new Cache.ArrayCacheBySymbolBySide();
|
|
2462
|
+
}
|
|
2463
|
+
const cache = this.positions[accountType];
|
|
2464
|
+
const data = this.safeValue(message, 'a', {});
|
|
2465
|
+
const rawPositions = this.safeValue(data, 'P', []);
|
|
2466
|
+
const newPositions = [];
|
|
2467
|
+
for (let i = 0; i < rawPositions.length; i++) {
|
|
2468
|
+
const rawPosition = rawPositions[i];
|
|
2469
|
+
const position = this.parseWsPosition(rawPosition);
|
|
2470
|
+
const timestamp = this.safeInteger(message, 'E');
|
|
2471
|
+
position['timestamp'] = timestamp;
|
|
2472
|
+
position['datetime'] = this.iso8601(timestamp);
|
|
2473
|
+
newPositions.push(position);
|
|
2474
|
+
cache.append(position);
|
|
2475
|
+
}
|
|
2476
|
+
const messageHashes = this.findMessageHashes(client, accountType + ':positions::');
|
|
2477
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
2478
|
+
const messageHash = messageHashes[i];
|
|
2479
|
+
const parts = messageHash.split('::');
|
|
2480
|
+
const symbolsString = parts[1];
|
|
2481
|
+
const symbols = symbolsString.split(',');
|
|
2482
|
+
const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
|
|
2483
|
+
if (!this.isEmpty(positions)) {
|
|
2484
|
+
client.resolve(positions, messageHash);
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
client.resolve(newPositions, accountType + ':positions');
|
|
2488
|
+
}
|
|
2489
|
+
parseWsPosition(position, market = undefined) {
|
|
2490
|
+
//
|
|
2491
|
+
// {
|
|
2492
|
+
// "s": "BTCUSDT", // Symbol
|
|
2493
|
+
// "pa": "0", // Position Amount
|
|
2494
|
+
// "ep": "0.00000", // Entry Price
|
|
2495
|
+
// "cr": "200", // (Pre-fee) Accumulated Realized
|
|
2496
|
+
// "up": "0", // Unrealized PnL
|
|
2497
|
+
// "mt": "isolated", // Margin Type
|
|
2498
|
+
// "iw": "0.00000000", // Isolated Wallet (if isolated position)
|
|
2499
|
+
// "ps": "BOTH" // Position Side
|
|
2500
|
+
// }
|
|
2501
|
+
//
|
|
2502
|
+
const marketId = this.safeString(position, 's');
|
|
2503
|
+
const positionSide = this.safeStringLower(position, 'ps');
|
|
2504
|
+
const hedged = positionSide !== 'both';
|
|
2505
|
+
return this.safePosition({
|
|
2506
|
+
'info': position,
|
|
2507
|
+
'id': undefined,
|
|
2508
|
+
'symbol': this.safeSymbol(marketId),
|
|
2509
|
+
'notional': undefined,
|
|
2510
|
+
'marginMode': this.safeString(position, 'mt'),
|
|
2511
|
+
'liquidationPrice': undefined,
|
|
2512
|
+
'entryPrice': this.safeNumber(position, 'ep'),
|
|
2513
|
+
'unrealizedPnl': this.safeNumber(position, 'up'),
|
|
2514
|
+
'percentage': undefined,
|
|
2515
|
+
'contracts': this.safeNumber(position, 'pa'),
|
|
2516
|
+
'contractSize': undefined,
|
|
2517
|
+
'markPrice': undefined,
|
|
2518
|
+
'side': positionSide,
|
|
2519
|
+
'hedged': hedged,
|
|
2520
|
+
'timestamp': undefined,
|
|
2521
|
+
'datetime': undefined,
|
|
2522
|
+
'maintenanceMargin': undefined,
|
|
2523
|
+
'maintenanceMarginPercentage': undefined,
|
|
2524
|
+
'collateral': undefined,
|
|
2525
|
+
'initialMargin': undefined,
|
|
2526
|
+
'initialMarginPercentage': undefined,
|
|
2527
|
+
'leverage': undefined,
|
|
2528
|
+
'marginRatio': undefined,
|
|
2529
|
+
});
|
|
2530
|
+
}
|
|
2334
2531
|
async fetchMyTradesWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2335
2532
|
/**
|
|
2336
2533
|
* @method
|
|
@@ -2450,6 +2647,7 @@ class binance extends binance$1 {
|
|
|
2450
2647
|
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2451
2648
|
const client = this.client(url);
|
|
2452
2649
|
this.setBalanceCache(client, type);
|
|
2650
|
+
this.setPositionsCache(client, type);
|
|
2453
2651
|
const message = undefined;
|
|
2454
2652
|
const trades = await this.watch(url, messageHash, message, type);
|
|
2455
2653
|
if (this.newUpdates) {
|
|
@@ -2561,6 +2759,10 @@ class binance extends binance$1 {
|
|
|
2561
2759
|
client.resolve(this.orders, messageHashSymbol);
|
|
2562
2760
|
}
|
|
2563
2761
|
}
|
|
2762
|
+
handleAcountUpdate(client, message) {
|
|
2763
|
+
this.handleBalance(client, message);
|
|
2764
|
+
this.handlePositions(client, message);
|
|
2765
|
+
}
|
|
2564
2766
|
handleWsError(client, message) {
|
|
2565
2767
|
//
|
|
2566
2768
|
// {
|
|
@@ -2629,7 +2831,7 @@ class binance extends binance$1 {
|
|
|
2629
2831
|
'bookTicker': this.handleTicker,
|
|
2630
2832
|
'outboundAccountPosition': this.handleBalance,
|
|
2631
2833
|
'balanceUpdate': this.handleBalance,
|
|
2632
|
-
'ACCOUNT_UPDATE': this.
|
|
2834
|
+
'ACCOUNT_UPDATE': this.handleAcountUpdate,
|
|
2633
2835
|
'executionReport': this.handleOrderUpdate,
|
|
2634
2836
|
'ORDER_TRADE_UPDATE': this.handleOrderUpdate,
|
|
2635
2837
|
};
|
|
@@ -29,6 +29,7 @@ class bitget extends bitget$1 {
|
|
|
29
29
|
'watchTickers': true,
|
|
30
30
|
'watchTrades': true,
|
|
31
31
|
'watchTradesForSymbols': true,
|
|
32
|
+
'watchPositions': true,
|
|
32
33
|
},
|
|
33
34
|
'urls': {
|
|
34
35
|
'api': {
|
|
@@ -750,6 +751,185 @@ class bitget extends bitget$1 {
|
|
|
750
751
|
'fee': undefined,
|
|
751
752
|
}, market);
|
|
752
753
|
}
|
|
754
|
+
async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
|
|
755
|
+
/**
|
|
756
|
+
* @method
|
|
757
|
+
* @name bitget#watchPositions
|
|
758
|
+
* @description watch all open positions
|
|
759
|
+
* @see https://bitgetlimited.github.io/apidoc/en/mix/#positions-channel
|
|
760
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
761
|
+
* @param {object} params extra parameters specific to the bitget api endpoint
|
|
762
|
+
* @param {string} params.instType Instrument Type umcbl:USDT Perpetual Contract Private Channel; dmcbl:Coin Margin Perpetual Contract Private Channel; cmcbl: USDC margin Perpetual Contract Private Channel
|
|
763
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
764
|
+
*/
|
|
765
|
+
await this.loadMarkets();
|
|
766
|
+
let market = undefined;
|
|
767
|
+
let messageHash = '';
|
|
768
|
+
const subscriptionHash = 'positions';
|
|
769
|
+
let instType = 'umcbl';
|
|
770
|
+
symbols = this.marketSymbols(symbols);
|
|
771
|
+
if (!this.isEmpty(symbols)) {
|
|
772
|
+
instType = 'dmcbl';
|
|
773
|
+
market = this.getMarketFromSymbols(symbols);
|
|
774
|
+
messageHash = '::' + symbols.join(',');
|
|
775
|
+
if (market['settle'] === 'USDT') {
|
|
776
|
+
instType = 'umcbl';
|
|
777
|
+
}
|
|
778
|
+
else if (market['settle'] === 'USDC') {
|
|
779
|
+
instType = 'cmcbl';
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
[instType, params] = this.handleOptionAndParams(params, 'watchPositions', 'instType', instType);
|
|
783
|
+
messageHash = instType + ':positions' + messageHash;
|
|
784
|
+
const args = {
|
|
785
|
+
'instType': instType,
|
|
786
|
+
'channel': 'positions',
|
|
787
|
+
'instId': 'default',
|
|
788
|
+
};
|
|
789
|
+
const newPositions = await this.watchPrivate(messageHash, subscriptionHash, args, params);
|
|
790
|
+
if (this.newUpdates) {
|
|
791
|
+
return newPositions;
|
|
792
|
+
}
|
|
793
|
+
return this.filterBySymbolsSinceLimit(newPositions, symbols, since, limit, true);
|
|
794
|
+
}
|
|
795
|
+
handlePositions(client, message) {
|
|
796
|
+
//
|
|
797
|
+
// {
|
|
798
|
+
// action: 'snapshot',
|
|
799
|
+
// arg: {
|
|
800
|
+
// instType: 'umcbl',
|
|
801
|
+
// channel: 'positions',
|
|
802
|
+
// instId: 'default'
|
|
803
|
+
// },
|
|
804
|
+
// data: [{
|
|
805
|
+
// posId: '926036334386778112',
|
|
806
|
+
// instId: 'LTCUSDT_UMCBL',
|
|
807
|
+
// instName: 'LTCUSDT',
|
|
808
|
+
// marginCoin: 'USDT',
|
|
809
|
+
// margin: '9.667',
|
|
810
|
+
// marginMode: 'crossed',
|
|
811
|
+
// holdSide: 'long',
|
|
812
|
+
// holdMode: 'double_hold',
|
|
813
|
+
// total: '0.3',
|
|
814
|
+
// available: '0.3',
|
|
815
|
+
// locked: '0',
|
|
816
|
+
// averageOpenPrice: '64.44',
|
|
817
|
+
// leverage: 2,
|
|
818
|
+
// achievedProfits: '0',
|
|
819
|
+
// upl: '0.0759',
|
|
820
|
+
// uplRate: '0.0078',
|
|
821
|
+
// liqPx: '-153.32',
|
|
822
|
+
// keepMarginRate: '0.010',
|
|
823
|
+
// marginRate: '0.005910309637',
|
|
824
|
+
// cTime: '1656510187717',
|
|
825
|
+
// uTime: '1694880005480',
|
|
826
|
+
// markPrice: '64.7',
|
|
827
|
+
// autoMargin: 'off'
|
|
828
|
+
// },
|
|
829
|
+
// ...
|
|
830
|
+
// ]
|
|
831
|
+
// }
|
|
832
|
+
//
|
|
833
|
+
const arg = this.safeValue(message, 'arg', {});
|
|
834
|
+
const instType = this.safeString(arg, 'instType', '');
|
|
835
|
+
if (this.positions === undefined) {
|
|
836
|
+
this.positions = {};
|
|
837
|
+
}
|
|
838
|
+
if (!(instType in this.positions)) {
|
|
839
|
+
this.positions[instType] = new Cache.ArrayCacheBySymbolBySide();
|
|
840
|
+
}
|
|
841
|
+
const cache = this.positions[instType];
|
|
842
|
+
const rawPositions = this.safeValue(message, 'data', []);
|
|
843
|
+
const dataLength = rawPositions.length;
|
|
844
|
+
if (dataLength === 0) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
const newPositions = [];
|
|
848
|
+
for (let i = 0; i < rawPositions.length; i++) {
|
|
849
|
+
const rawPosition = rawPositions[i];
|
|
850
|
+
const position = this.parseWsPosition(rawPosition);
|
|
851
|
+
newPositions.push(position);
|
|
852
|
+
cache.append(position);
|
|
853
|
+
}
|
|
854
|
+
const messageHashes = this.findMessageHashes(client, instType + ':positions::');
|
|
855
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
856
|
+
const messageHash = messageHashes[i];
|
|
857
|
+
const parts = messageHash.split('::');
|
|
858
|
+
const symbolsString = parts[1];
|
|
859
|
+
const symbols = symbolsString.split(',');
|
|
860
|
+
const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
|
|
861
|
+
if (!this.isEmpty(positions)) {
|
|
862
|
+
client.resolve(positions, messageHash);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
client.resolve(newPositions, instType + ':positions');
|
|
866
|
+
}
|
|
867
|
+
parseWsPosition(position, market = undefined) {
|
|
868
|
+
//
|
|
869
|
+
// {
|
|
870
|
+
// posId: '926036334386778112',
|
|
871
|
+
// instId: 'LTCUSDT_UMCBL',
|
|
872
|
+
// instName: 'LTCUSDT',
|
|
873
|
+
// marginCoin: 'USDT',
|
|
874
|
+
// margin: '9.667',
|
|
875
|
+
// marginMode: 'crossed',
|
|
876
|
+
// holdSide: 'long',
|
|
877
|
+
// holdMode: 'double_hold',
|
|
878
|
+
// total: '0.3',
|
|
879
|
+
// available: '0.3',
|
|
880
|
+
// locked: '0',
|
|
881
|
+
// averageOpenPrice: '64.44',
|
|
882
|
+
// leverage: 2,
|
|
883
|
+
// achievedProfits: '0',
|
|
884
|
+
// upl: '0.0759',
|
|
885
|
+
// uplRate: '0.0078',
|
|
886
|
+
// liqPx: '-153.32',
|
|
887
|
+
// keepMarginRate: '0.010',
|
|
888
|
+
// marginRate: '0.005910309637',
|
|
889
|
+
// cTime: '1656510187717',
|
|
890
|
+
// uTime: '1694880005480',
|
|
891
|
+
// markPrice: '64.7',
|
|
892
|
+
// autoMargin: 'off'
|
|
893
|
+
// }
|
|
894
|
+
//
|
|
895
|
+
const marketId = this.safeString(position, 'instId');
|
|
896
|
+
const marginModeId = this.safeString(position, 'marginMode');
|
|
897
|
+
const marginMode = this.getSupportedMapping(marginModeId, {
|
|
898
|
+
'crossed': 'cross',
|
|
899
|
+
'fixed': 'isolated',
|
|
900
|
+
});
|
|
901
|
+
const hedgedId = this.safeString(position, 'holdMode');
|
|
902
|
+
const hedged = this.getSupportedMapping(hedgedId, {
|
|
903
|
+
'double_hold': true,
|
|
904
|
+
'single_hold': false,
|
|
905
|
+
});
|
|
906
|
+
const timestamp = this.safeInteger2(position, 'uTime', 'cTime');
|
|
907
|
+
return this.safePosition({
|
|
908
|
+
'info': position,
|
|
909
|
+
'id': this.safeString(position, 'posId'),
|
|
910
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
911
|
+
'notional': undefined,
|
|
912
|
+
'marginMode': marginMode,
|
|
913
|
+
'liquidationPrice': undefined,
|
|
914
|
+
'entryPrice': this.safeNumber(position, 'averageOpenPrice'),
|
|
915
|
+
'unrealizedPnl': this.safeNumber(position, 'upl'),
|
|
916
|
+
'percentage': this.safeNumber(position, 'uplRate'),
|
|
917
|
+
'contracts': this.safeNumber(position, 'total'),
|
|
918
|
+
'contractSize': undefined,
|
|
919
|
+
'markPrice': this.safeNumber(position, 'markPrice'),
|
|
920
|
+
'side': this.safeString(position, 'holdSide'),
|
|
921
|
+
'hedged': hedged,
|
|
922
|
+
'timestamp': timestamp,
|
|
923
|
+
'datetime': this.iso8601(timestamp),
|
|
924
|
+
'maintenanceMargin': undefined,
|
|
925
|
+
'maintenanceMarginPercentage': this.safeNumber(position, 'keepMarginRate'),
|
|
926
|
+
'collateral': undefined,
|
|
927
|
+
'initialMargin': undefined,
|
|
928
|
+
'initialMarginPercentage': undefined,
|
|
929
|
+
'leverage': this.safeNumber(position, 'leverage'),
|
|
930
|
+
'marginRatio': this.safeNumber(position, 'marginRate'),
|
|
931
|
+
});
|
|
932
|
+
}
|
|
753
933
|
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
754
934
|
/**
|
|
755
935
|
* @method
|
|
@@ -1464,6 +1644,7 @@ class bitget extends bitget$1 {
|
|
|
1464
1644
|
'orders': this.handleOrder,
|
|
1465
1645
|
'ordersAlgo': this.handleOrder,
|
|
1466
1646
|
'account': this.handleBalance,
|
|
1647
|
+
'positions': this.handlePositions,
|
|
1467
1648
|
};
|
|
1468
1649
|
const arg = this.safeValue(message, 'arg', {});
|
|
1469
1650
|
const topic = this.safeValue(arg, 'channel', '');
|