ccxt 4.1.45 → 4.1.46
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 +1591 -188
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +11 -3
- package/dist/cjs/src/base/ws/Cache.js +50 -0
- 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/huobi.js +1 -2
- 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 +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/base/Exchange.d.ts +4 -1
- package/js/src/base/Exchange.js +11 -3
- package/js/src/base/ws/Cache.d.ts +5 -1
- package/js/src/base/ws/Cache.js +50 -1
- package/js/src/bitvavo.js +6 -5
- package/js/src/bybit.d.ts +0 -2
- package/js/src/bybit.js +84 -132
- package/js/src/cryptocom.js +1 -1
- package/js/src/gate.js +3 -1
- package/js/src/huobi.js +1 -2
- package/js/src/okx.js +19 -2
- 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/package.json +1 -1
- package/skip-tests.json +3 -1
|
@@ -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', '');
|