ccxt 4.5.5 → 4.5.7
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 +4 -4
- package/dist/ccxt.browser.min.js +15 -15
- package/dist/cjs/ccxt.js +6 -6
- package/dist/cjs/src/abstract/toobit.js +11 -0
- package/dist/cjs/src/abstract/tradeogre.js +1 -1
- package/dist/cjs/src/apex.js +2 -2
- package/dist/cjs/src/backpack.js +1 -1
- package/dist/cjs/src/base/Exchange.js +129 -2
- package/dist/cjs/src/bigone.js +4 -4
- package/dist/cjs/src/binance.js +82 -20
- package/dist/cjs/src/bingx.js +5 -2
- package/dist/cjs/src/bitbank.js +1 -0
- package/dist/cjs/src/bitbns.js +1 -0
- package/dist/cjs/src/bitflyer.js +1 -0
- package/dist/cjs/src/bitget.js +16 -9
- package/dist/cjs/src/bithumb.js +1 -0
- package/dist/cjs/src/bitso.js +1 -0
- package/dist/cjs/src/bitvavo.js +26 -40
- package/dist/cjs/src/blockchaincom.js +1 -0
- package/dist/cjs/src/btcalpha.js +1 -0
- package/dist/cjs/src/btcbox.js +1 -0
- package/dist/cjs/src/btcmarkets.js +1 -0
- package/dist/cjs/src/btcturk.js +1 -0
- package/dist/cjs/src/bybit.js +186 -127
- package/dist/cjs/src/coinsph.js +4 -1
- package/dist/cjs/src/cryptocom.js +6 -3
- package/dist/cjs/src/deribit.js +3 -2
- package/dist/cjs/src/digifinex.js +1 -1
- package/dist/cjs/src/gate.js +9 -13
- package/dist/cjs/src/gemini.js +5 -5
- package/dist/cjs/src/htx.js +11 -1
- package/dist/cjs/src/hyperliquid.js +3 -0
- package/dist/cjs/src/independentreserve.js +1 -0
- package/dist/cjs/src/indodax.js +17 -6
- package/dist/cjs/src/kraken.js +31 -8
- package/dist/cjs/src/krakenfutures.js +1 -0
- package/dist/cjs/src/kucoin.js +1 -2
- package/dist/cjs/src/luno.js +4 -1
- package/dist/cjs/src/mercado.js +1 -0
- package/dist/cjs/src/mexc.js +84 -37
- package/dist/cjs/src/novadax.js +1 -0
- package/dist/cjs/src/oceanex.js +1 -0
- package/dist/cjs/src/okcoin.js +4 -1
- package/dist/cjs/src/okx.js +52 -8
- package/dist/cjs/src/phemex.js +1 -1
- package/dist/cjs/src/pro/apex.js +8 -4
- package/dist/cjs/src/pro/backpack.js +7 -5
- package/dist/cjs/src/pro/binance.js +150 -19
- package/dist/cjs/src/pro/bingx.js +206 -220
- package/dist/cjs/src/pro/bitget.js +332 -76
- package/dist/cjs/src/pro/cex.js +1 -0
- package/dist/cjs/src/pro/htx.js +1 -1
- package/dist/cjs/src/pro/independentreserve.js +1 -0
- package/dist/cjs/src/pro/mexc.js +23 -23
- package/dist/cjs/src/pro/okx.js +46 -10
- package/dist/cjs/src/pro/toobit.js +1163 -0
- package/dist/cjs/src/pro/tradeogre.js +1 -1
- package/dist/cjs/src/toobit.js +2999 -0
- package/dist/cjs/src/tradeogre.js +1 -1
- package/dist/cjs/src/upbit.js +1 -0
- package/dist/cjs/src/wavesexchange.js +1 -0
- package/dist/cjs/src/yobit.js +1 -0
- package/dist/cjs/src/zaif.js +1 -0
- package/dist/cjs/src/zonda.js +1 -0
- package/js/ccxt.d.ts +8 -8
- package/js/ccxt.js +6 -6
- package/js/src/abstract/mexc.d.ts +1 -0
- package/js/src/abstract/myokx.d.ts +1 -0
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/abstract/okxus.d.ts +1 -0
- package/js/src/abstract/toobit.d.ts +66 -0
- package/js/src/apex.js +2 -2
- package/js/src/backpack.js +1 -1
- package/js/src/base/Exchange.d.ts +9 -0
- package/js/src/base/Exchange.js +129 -2
- package/js/src/bigone.js +4 -4
- package/js/src/binance.d.ts +9 -0
- package/js/src/binance.js +82 -20
- package/js/src/bingx.js +5 -2
- package/js/src/bitbank.js +1 -0
- package/js/src/bitbns.js +1 -0
- package/js/src/bitflyer.js +1 -0
- package/js/src/bitget.js +16 -9
- package/js/src/bithumb.js +1 -0
- package/js/src/bitso.js +1 -0
- package/js/src/bitvavo.d.ts +0 -2
- package/js/src/bitvavo.js +27 -41
- package/js/src/blockchaincom.js +1 -0
- package/js/src/btcalpha.js +1 -0
- package/js/src/btcbox.js +1 -0
- package/js/src/btcmarkets.js +1 -0
- package/js/src/btcturk.js +1 -0
- package/js/src/bybit.d.ts +8 -0
- package/js/src/bybit.js +186 -127
- package/js/src/coinsph.js +4 -1
- package/js/src/cryptocom.js +6 -3
- package/js/src/deribit.js +3 -2
- package/js/src/digifinex.js +1 -1
- package/js/src/gate.d.ts +2 -2
- package/js/src/gate.js +9 -13
- package/js/src/gemini.js +5 -5
- package/js/src/htx.js +11 -1
- package/js/src/hyperliquid.js +3 -0
- package/js/src/independentreserve.js +1 -0
- package/js/src/indodax.js +17 -6
- package/js/src/kraken.d.ts +2 -2
- package/js/src/kraken.js +31 -8
- package/js/src/krakenfutures.js +1 -0
- package/js/src/kucoin.js +1 -2
- package/js/src/luno.js +4 -1
- package/js/src/mercado.js +1 -0
- package/js/src/mexc.d.ts +4 -1
- package/js/src/mexc.js +84 -37
- package/js/src/novadax.js +1 -0
- package/js/src/oceanex.js +1 -0
- package/js/src/okcoin.js +4 -1
- package/js/src/okx.js +52 -8
- package/js/src/phemex.js +1 -1
- package/js/src/pro/apex.js +8 -4
- package/js/src/pro/backpack.d.ts +1 -1
- package/js/src/pro/backpack.js +7 -5
- package/js/src/pro/binance.d.ts +24 -0
- package/js/src/pro/binance.js +150 -19
- package/js/src/pro/bingx.d.ts +53 -33
- package/js/src/pro/bingx.js +207 -221
- package/js/src/pro/bitget.d.ts +6 -0
- package/js/src/pro/bitget.js +332 -76
- package/js/src/pro/cex.js +1 -0
- package/js/src/pro/htx.js +1 -1
- package/js/src/pro/independentreserve.js +1 -0
- package/js/src/pro/mexc.js +23 -23
- package/js/src/pro/okx.d.ts +7 -1
- package/js/src/pro/okx.js +46 -10
- package/js/src/pro/toobit.d.ts +174 -0
- package/js/src/pro/toobit.js +1162 -0
- package/js/src/toobit.d.ts +456 -0
- package/js/src/toobit.js +2992 -0
- package/js/src/upbit.js +1 -0
- package/js/src/wavesexchange.js +1 -0
- package/js/src/yobit.js +1 -0
- package/js/src/zaif.js +1 -0
- package/js/src/zonda.js +1 -0
- package/package.json +1 -1
- package/dist/373.ccxt.browser.js +0 -7630
- package/dist/373.ccxt.browser.min.js +0 -1
- package/js/src/abstract/tradeogre.d.ts +0 -21
- package/js/src/pro/tradeogre.d.ts +0 -49
- package/js/src/pro/tradeogre.js +0 -278
- package/js/src/tradeogre.d.ts +0 -149
- package/js/src/tradeogre.js +0 -872
- /package/js/src/abstract/{tradeogre.js → toobit.js} +0 -0
package/js/src/okx.js
CHANGED
|
@@ -502,6 +502,7 @@ export default class okx extends Exchange {
|
|
|
502
502
|
'account/fixed-loan/repay-borrowing-order': 5,
|
|
503
503
|
'account/bills-history-archive': 72000,
|
|
504
504
|
'account/move-positions': 10,
|
|
505
|
+
'account/set-settle-currency': 1,
|
|
505
506
|
// subaccount
|
|
506
507
|
'users/subaccount/modify-apikey': 10,
|
|
507
508
|
'asset/subaccount/transfer': 10,
|
|
@@ -684,6 +685,7 @@ export default class okx extends Exchange {
|
|
|
684
685
|
'51031': InvalidOrder,
|
|
685
686
|
'51046': InvalidOrder,
|
|
686
687
|
'51047': InvalidOrder,
|
|
688
|
+
'51051': InvalidOrder,
|
|
687
689
|
'51072': InvalidOrder,
|
|
688
690
|
'51073': InvalidOrder,
|
|
689
691
|
'51074': InvalidOrder,
|
|
@@ -823,6 +825,9 @@ export default class okx extends Exchange {
|
|
|
823
825
|
'54008': InvalidOrder,
|
|
824
826
|
'54009': InvalidOrder,
|
|
825
827
|
'54011': InvalidOrder,
|
|
828
|
+
'54072': ExchangeError,
|
|
829
|
+
'54073': BadRequest,
|
|
830
|
+
'54074': ExchangeError,
|
|
826
831
|
// Trading bot Error Code from 55100 to 55999
|
|
827
832
|
'55100': InvalidOrder,
|
|
828
833
|
'55101': InvalidOrder,
|
|
@@ -928,6 +933,9 @@ export default class okx extends Exchange {
|
|
|
928
933
|
'59519': ExchangeError,
|
|
929
934
|
'59642': BadRequest,
|
|
930
935
|
'59643': ExchangeError,
|
|
936
|
+
'59683': ExchangeError,
|
|
937
|
+
'59684': BadRequest,
|
|
938
|
+
'59686': BadRequest,
|
|
931
939
|
// WebSocket error Codes from 60000-63999
|
|
932
940
|
'60001': AuthenticationError,
|
|
933
941
|
'60002': AuthenticationError,
|
|
@@ -1294,6 +1302,9 @@ export default class okx extends Exchange {
|
|
|
1294
1302
|
},
|
|
1295
1303
|
'spot': {
|
|
1296
1304
|
'extends': 'default',
|
|
1305
|
+
'fetchCurrencies': {
|
|
1306
|
+
'private': true,
|
|
1307
|
+
},
|
|
1297
1308
|
},
|
|
1298
1309
|
'swap': {
|
|
1299
1310
|
'linear': {
|
|
@@ -1501,14 +1512,33 @@ export default class okx extends Exchange {
|
|
|
1501
1512
|
// "data": [
|
|
1502
1513
|
// {
|
|
1503
1514
|
// "acctLv": "2",
|
|
1515
|
+
// "acctStpMode": "cancel_maker",
|
|
1504
1516
|
// "autoLoan": false,
|
|
1505
1517
|
// "ctIsoMode": "automatic",
|
|
1518
|
+
// "enableSpotBorrow": false,
|
|
1506
1519
|
// "greeksType": "PA",
|
|
1520
|
+
// "feeType": "0",
|
|
1521
|
+
// "ip": "",
|
|
1522
|
+
// "type": "0",
|
|
1523
|
+
// "kycLv": "3",
|
|
1524
|
+
// "label": "v5 test",
|
|
1507
1525
|
// "level": "Lv1",
|
|
1508
1526
|
// "levelTmp": "",
|
|
1527
|
+
// "liquidationGear": "-1",
|
|
1528
|
+
// "mainUid": "44705892343619584",
|
|
1509
1529
|
// "mgnIsoMode": "automatic",
|
|
1530
|
+
// "opAuth": "1",
|
|
1531
|
+
// "perm": "read_only,withdraw,trade",
|
|
1510
1532
|
// "posMode": "long_short_mode",
|
|
1511
|
-
// "
|
|
1533
|
+
// "roleType": "0",
|
|
1534
|
+
// "spotBorrowAutoRepay": false,
|
|
1535
|
+
// "spotOffsetType": "",
|
|
1536
|
+
// "spotRoleType": "0",
|
|
1537
|
+
// "spotTraderInsts": [],
|
|
1538
|
+
// "traderInsts": [],
|
|
1539
|
+
// "uid": "44705892343619584",
|
|
1540
|
+
// "settleCcy": "USDT",
|
|
1541
|
+
// "settleCcyList": ["USD", "USDC", "USDG"],
|
|
1512
1542
|
// }
|
|
1513
1543
|
// ],
|
|
1514
1544
|
// "msg": ""
|
|
@@ -1790,7 +1820,7 @@ export default class okx extends Exchange {
|
|
|
1790
1820
|
// and fallback to generating the currencies from the markets
|
|
1791
1821
|
const isSandboxMode = this.safeBool(this.options, 'sandboxMode', false);
|
|
1792
1822
|
if (!this.checkRequiredCredentials(false) || isSandboxMode) {
|
|
1793
|
-
return
|
|
1823
|
+
return {};
|
|
1794
1824
|
}
|
|
1795
1825
|
//
|
|
1796
1826
|
// has['fetchCurrencies'] is currently set to true, but an unauthorized request returns
|
|
@@ -3154,7 +3184,8 @@ export default class okx extends Exchange {
|
|
|
3154
3184
|
request['attachAlgoOrds'] = [attachAlgoOrd];
|
|
3155
3185
|
}
|
|
3156
3186
|
}
|
|
3157
|
-
|
|
3187
|
+
// algo order details
|
|
3188
|
+
if (trigger) {
|
|
3158
3189
|
request['ordType'] = 'trigger';
|
|
3159
3190
|
request['triggerPx'] = this.priceToPrecision(symbol, triggerPrice);
|
|
3160
3191
|
request['orderPx'] = isMarketOrder ? '-1' : this.priceToPrecision(symbol, price);
|
|
@@ -3605,10 +3636,18 @@ export default class okx extends Exchange {
|
|
|
3605
3636
|
}
|
|
3606
3637
|
else {
|
|
3607
3638
|
for (let i = 0; i < clientOrderIds.length; i++) {
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3639
|
+
if (trailing || trigger) {
|
|
3640
|
+
request.push({
|
|
3641
|
+
'instId': market['id'],
|
|
3642
|
+
'algoClOrdId': clientOrderIds[i],
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
else {
|
|
3646
|
+
request.push({
|
|
3647
|
+
'instId': market['id'],
|
|
3648
|
+
'clOrdId': clientOrderIds[i],
|
|
3649
|
+
});
|
|
3650
|
+
}
|
|
3612
3651
|
}
|
|
3613
3652
|
}
|
|
3614
3653
|
let response = undefined;
|
|
@@ -3685,7 +3724,12 @@ export default class okx extends Exchange {
|
|
|
3685
3724
|
idKey = 'algoId';
|
|
3686
3725
|
}
|
|
3687
3726
|
else if (clientOrderId !== undefined) {
|
|
3688
|
-
|
|
3727
|
+
if (isStopOrTrailing) {
|
|
3728
|
+
idKey = 'algoClOrdId';
|
|
3729
|
+
}
|
|
3730
|
+
else {
|
|
3731
|
+
idKey = 'clOrdId';
|
|
3732
|
+
}
|
|
3689
3733
|
}
|
|
3690
3734
|
const requestItem = {
|
|
3691
3735
|
'instId': market['id'],
|
package/js/src/phemex.js
CHANGED
|
@@ -4067,7 +4067,7 @@ export default class phemex extends Exchange {
|
|
|
4067
4067
|
const isCross = this.safeValue(position, 'crossMargin');
|
|
4068
4068
|
return this.safePosition({
|
|
4069
4069
|
'info': position,
|
|
4070
|
-
'id':
|
|
4070
|
+
'id': this.safeString(position, 'execSeq'),
|
|
4071
4071
|
'symbol': symbol,
|
|
4072
4072
|
'contracts': this.parseNumber(contracts),
|
|
4073
4073
|
'contractSize': contractSize,
|
package/js/src/pro/apex.js
CHANGED
|
@@ -112,9 +112,10 @@ export default class apex extends apexRest {
|
|
|
112
112
|
// "v": "0.001",
|
|
113
113
|
// "p": "16578.50",
|
|
114
114
|
// "L": "PlusTick",
|
|
115
|
-
// "i": "20f43950-d8dd-5b31-9112-
|
|
115
|
+
// "i": "20f43950-d8dd-5b31-9112-a178eb6023ef",
|
|
116
116
|
// "BT": false
|
|
117
|
-
// }
|
|
117
|
+
// },
|
|
118
|
+
// // sorted by newest first
|
|
118
119
|
// ]
|
|
119
120
|
// }
|
|
120
121
|
//
|
|
@@ -131,8 +132,10 @@ export default class apex extends apexRest {
|
|
|
131
132
|
stored = new ArrayCache(limit);
|
|
132
133
|
this.trades[symbol] = stored;
|
|
133
134
|
}
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
const length = trades.length;
|
|
136
|
+
for (let j = 0; j < length; j++) {
|
|
137
|
+
const index = length - j - 1;
|
|
138
|
+
const parsed = this.parseWsTrade(trades[index], market);
|
|
136
139
|
stored.append(parsed);
|
|
137
140
|
}
|
|
138
141
|
const messageHash = 'trade' + ':' + symbol;
|
|
@@ -959,6 +962,7 @@ export default class apex extends apexRest {
|
|
|
959
962
|
}
|
|
960
963
|
ping(client) {
|
|
961
964
|
const timeStamp = this.milliseconds().toString();
|
|
965
|
+
client.lastPong = timeStamp; // server won't send a pong, so we set it here
|
|
962
966
|
return {
|
|
963
967
|
'args': [timeStamp],
|
|
964
968
|
'op': 'ping',
|
package/js/src/pro/backpack.d.ts
CHANGED
|
@@ -197,7 +197,7 @@ export default class backpack extends backpackRest {
|
|
|
197
197
|
unWatchOrderBook(symbol: string, params?: {}): Promise<any>;
|
|
198
198
|
/**
|
|
199
199
|
* @method
|
|
200
|
-
* @name
|
|
200
|
+
* @name backpack#unWatchOrderBookForSymbols
|
|
201
201
|
* @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
202
202
|
* @param {string[]} symbols unified array of symbols
|
|
203
203
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
package/js/src/pro/backpack.js
CHANGED
|
@@ -797,7 +797,7 @@ export default class backpack extends backpackRest {
|
|
|
797
797
|
}
|
|
798
798
|
/**
|
|
799
799
|
* @method
|
|
800
|
-
* @name
|
|
800
|
+
* @name backpack#unWatchOrderBookForSymbols
|
|
801
801
|
* @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
802
802
|
* @param {string[]} symbols unified array of symbols
|
|
803
803
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -859,7 +859,7 @@ export default class backpack extends backpackRest {
|
|
|
859
859
|
storedOrderBook.cache.push(data);
|
|
860
860
|
return;
|
|
861
861
|
}
|
|
862
|
-
else if (nonce
|
|
862
|
+
else if (nonce > deltaNonce) {
|
|
863
863
|
return;
|
|
864
864
|
}
|
|
865
865
|
this.handleDelta(storedOrderBook, data);
|
|
@@ -884,16 +884,18 @@ export default class backpack extends backpackRest {
|
|
|
884
884
|
}
|
|
885
885
|
}
|
|
886
886
|
getCacheIndex(orderbook, cache) {
|
|
887
|
+
//
|
|
888
|
+
// {"E":"1759338824897386","T":"1759338824895616","U":1662976171,"a":[],"b":[["117357.0","0.00000"]],"e":"depth","s":"BTC_USDC_PERP","u":1662976171}
|
|
887
889
|
const firstDelta = this.safeDict(cache, 0);
|
|
888
890
|
const nonce = this.safeInteger(orderbook, 'nonce');
|
|
889
|
-
const firstDeltaStart = this.safeInteger(firstDelta, '
|
|
891
|
+
const firstDeltaStart = this.safeInteger(firstDelta, 'U');
|
|
890
892
|
if (nonce < firstDeltaStart - 1) {
|
|
891
893
|
return -1;
|
|
892
894
|
}
|
|
893
895
|
for (let i = 0; i < cache.length; i++) {
|
|
894
896
|
const delta = cache[i];
|
|
895
|
-
const deltaStart = this.safeInteger(delta, '
|
|
896
|
-
const deltaEnd = this.safeInteger(delta, '
|
|
897
|
+
const deltaStart = this.safeInteger(delta, 'U');
|
|
898
|
+
const deltaEnd = this.safeInteger(delta, 'u');
|
|
897
899
|
if ((nonce >= deltaStart - 1) && (nonce < deltaEnd)) {
|
|
898
900
|
return i;
|
|
899
901
|
}
|
package/js/src/pro/binance.d.ts
CHANGED
|
@@ -62,6 +62,19 @@ export default class binance extends binanceRest {
|
|
|
62
62
|
};
|
|
63
63
|
};
|
|
64
64
|
};
|
|
65
|
+
demo: {
|
|
66
|
+
ws: {
|
|
67
|
+
spot: string;
|
|
68
|
+
margin: string;
|
|
69
|
+
future: string;
|
|
70
|
+
delivery: string;
|
|
71
|
+
'ws-api': {
|
|
72
|
+
spot: string;
|
|
73
|
+
future: string;
|
|
74
|
+
delivery: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
65
78
|
api: {
|
|
66
79
|
ws: {
|
|
67
80
|
spot: string;
|
|
@@ -149,6 +162,7 @@ export default class binance extends binanceRest {
|
|
|
149
162
|
};
|
|
150
163
|
};
|
|
151
164
|
requestId(url: any): any;
|
|
165
|
+
isSpotUrl(client: Client): boolean;
|
|
152
166
|
stream(type: Str, subscriptionHash: Str, numSubscriptions?: number): string;
|
|
153
167
|
/**
|
|
154
168
|
* @method
|
|
@@ -541,6 +555,14 @@ export default class binance extends binanceRest {
|
|
|
541
555
|
handleTickersAndBidsAsks(client: Client, message: any, methodType: any): void;
|
|
542
556
|
getMessageHash(channelName: string, symbol: Str, isBidAsk: boolean): string;
|
|
543
557
|
signParams(params?: {}): any;
|
|
558
|
+
/**
|
|
559
|
+
* Ensures a User Data Stream WebSocket subscription is active for the specified scope
|
|
560
|
+
* @param marketType {string} only support on 'spot'
|
|
561
|
+
* @see {@link https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#subscribe-to-user-data-stream-through-signature-subscription-user_data Binance User Data Stream Documentation}
|
|
562
|
+
* @returns Promise<number> The subscription ID for the user data stream
|
|
563
|
+
*/
|
|
564
|
+
ensureUserDataStreamWsSubscribeSignature(marketType?: string): Promise<void>;
|
|
565
|
+
handleUserDataStreamSubscribe(client: Client, message: any): void;
|
|
544
566
|
authenticate(params?: {}): Promise<void>;
|
|
545
567
|
keepAliveListenKey(params?: {}): Promise<void>;
|
|
546
568
|
setBalanceCache(client: Client, type: any, isPortfolioMargin?: boolean): void;
|
|
@@ -596,6 +618,7 @@ export default class binance extends binanceRest {
|
|
|
596
618
|
*/
|
|
597
619
|
watchBalance(params?: {}): Promise<Balances>;
|
|
598
620
|
handleBalance(client: Client, message: any): void;
|
|
621
|
+
getAccountTypeFromSubscriptions(subscriptions: string[]): string;
|
|
599
622
|
getMarketType(method: any, market: any, params?: {}): any;
|
|
600
623
|
/**
|
|
601
624
|
* @method
|
|
@@ -792,5 +815,6 @@ export default class binance extends binanceRest {
|
|
|
792
815
|
handleOrder(client: Client, message: any): void;
|
|
793
816
|
handleAcountUpdate(client: any, message: any): void;
|
|
794
817
|
handleWsError(client: Client, message: any): void;
|
|
818
|
+
handleEventStreamTerminated(client: Client, message: any): void;
|
|
795
819
|
handleMessage(client: Client, message: any): void;
|
|
796
820
|
}
|
package/js/src/pro/binance.js
CHANGED
|
@@ -73,6 +73,19 @@ export default class binance extends binanceRest {
|
|
|
73
73
|
},
|
|
74
74
|
},
|
|
75
75
|
},
|
|
76
|
+
'demo': {
|
|
77
|
+
'ws': {
|
|
78
|
+
'spot': 'wss://demo-stream.binance.com/ws',
|
|
79
|
+
'margin': 'wss://demo-stream.binance.com/ws',
|
|
80
|
+
'future': 'wss://fstream.binancefuture.com/ws',
|
|
81
|
+
'delivery': 'wss://dstream.binancefuture.com/ws',
|
|
82
|
+
'ws-api': {
|
|
83
|
+
'spot': 'wss://demo-ws-api.binance.com/ws-api/v3',
|
|
84
|
+
'future': 'wss://testnet.binancefuture.com/ws-fapi/v1',
|
|
85
|
+
'delivery': 'wss://testnet.binancefuture.com/ws-dapi/v1',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
76
89
|
'api': {
|
|
77
90
|
'ws': {
|
|
78
91
|
'spot': 'wss://stream.binance.com:9443/ws',
|
|
@@ -170,6 +183,9 @@ export default class binance extends binanceRest {
|
|
|
170
183
|
this.options['requestId'][url] = newValue;
|
|
171
184
|
return newValue;
|
|
172
185
|
}
|
|
186
|
+
isSpotUrl(client) {
|
|
187
|
+
return (client.url.indexOf('/stream') > -1) || (client.url.indexOf('demo-stream') > -1);
|
|
188
|
+
}
|
|
173
189
|
stream(type, subscriptionHash, numSubscriptions = 1) {
|
|
174
190
|
const streamBySubscriptionsHash = this.safeDict(this.options, 'streamBySubscriptionsHash', this.createSafeDictionary());
|
|
175
191
|
let stream = this.safeString(streamBySubscriptionsHash, subscriptionHash);
|
|
@@ -899,7 +915,7 @@ export default class binance extends binanceRest {
|
|
|
899
915
|
// ]
|
|
900
916
|
// }
|
|
901
917
|
//
|
|
902
|
-
const isSpot = (client
|
|
918
|
+
const isSpot = this.isSpotUrl(client);
|
|
903
919
|
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
904
920
|
const marketId = this.safeString(message, 's');
|
|
905
921
|
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
@@ -1359,7 +1375,7 @@ export default class binance extends binanceRest {
|
|
|
1359
1375
|
handleTrade(client, message) {
|
|
1360
1376
|
// the trade streams push raw trade information in real-time
|
|
1361
1377
|
// each trade has a unique buyer and seller
|
|
1362
|
-
const isSpot = (client
|
|
1378
|
+
const isSpot = this.isSpotUrl(client);
|
|
1363
1379
|
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1364
1380
|
const marketId = this.safeString(message, 's');
|
|
1365
1381
|
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
@@ -1601,7 +1617,7 @@ export default class binance extends binanceRest {
|
|
|
1601
1617
|
this.safeFloat(kline, 'c'),
|
|
1602
1618
|
this.safeFloat(kline, 'v'),
|
|
1603
1619
|
];
|
|
1604
|
-
const isSpot = (client
|
|
1620
|
+
const isSpot = this.isSpotUrl(client);
|
|
1605
1621
|
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1606
1622
|
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
1607
1623
|
const messageHash = 'ohlcv::' + symbol + '::' + unifiedTimeframe;
|
|
@@ -2246,7 +2262,7 @@ export default class binance extends binanceRest {
|
|
|
2246
2262
|
this.handleTickersAndBidsAsks(client, message, 'tickers');
|
|
2247
2263
|
}
|
|
2248
2264
|
handleTickersAndBidsAsks(client, message, methodType) {
|
|
2249
|
-
const isSpot = (client
|
|
2265
|
+
const isSpot = this.isSpotUrl(client);
|
|
2250
2266
|
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
2251
2267
|
const isBidAsk = (methodType === 'bidasks');
|
|
2252
2268
|
let channelName = undefined;
|
|
@@ -2329,6 +2345,58 @@ export default class binance extends binanceRest {
|
|
|
2329
2345
|
extendedParams['signature'] = signature;
|
|
2330
2346
|
return extendedParams;
|
|
2331
2347
|
}
|
|
2348
|
+
/**
|
|
2349
|
+
* Ensures a User Data Stream WebSocket subscription is active for the specified scope
|
|
2350
|
+
* @param marketType {string} only support on 'spot'
|
|
2351
|
+
* @see {@link https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#subscribe-to-user-data-stream-through-signature-subscription-user_data Binance User Data Stream Documentation}
|
|
2352
|
+
* @returns Promise<number> The subscription ID for the user data stream
|
|
2353
|
+
*/
|
|
2354
|
+
async ensureUserDataStreamWsSubscribeSignature(marketType = 'spot') {
|
|
2355
|
+
const url = this.urls['api']['ws']['ws-api'][marketType];
|
|
2356
|
+
const client = this.client(url);
|
|
2357
|
+
const subscriptions = client.subscriptions;
|
|
2358
|
+
const subscriptionsKeys = Object.keys(subscriptions);
|
|
2359
|
+
const accountType = this.getAccountTypeFromSubscriptions(subscriptionsKeys);
|
|
2360
|
+
if (accountType === marketType) {
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
client.subscriptions[marketType] = true;
|
|
2364
|
+
const requestId = this.requestId(url);
|
|
2365
|
+
const messageHash = requestId.toString();
|
|
2366
|
+
const message = {
|
|
2367
|
+
'id': messageHash,
|
|
2368
|
+
'method': 'userDataStream.subscribe.signature',
|
|
2369
|
+
'params': this.signParams({}),
|
|
2370
|
+
};
|
|
2371
|
+
const subscription = {
|
|
2372
|
+
'id': messageHash,
|
|
2373
|
+
'method': this.handleUserDataStreamSubscribe,
|
|
2374
|
+
'subscription': marketType,
|
|
2375
|
+
};
|
|
2376
|
+
await this.watch(url, messageHash, message, messageHash, subscription);
|
|
2377
|
+
}
|
|
2378
|
+
handleUserDataStreamSubscribe(client, message) {
|
|
2379
|
+
//
|
|
2380
|
+
// {
|
|
2381
|
+
// "id": 1,
|
|
2382
|
+
// "status": 200,
|
|
2383
|
+
// "result": {
|
|
2384
|
+
// "subscriptionId": 0
|
|
2385
|
+
// }
|
|
2386
|
+
// }
|
|
2387
|
+
//
|
|
2388
|
+
const messageHash = this.safeString(message, 'id');
|
|
2389
|
+
const subscriptions = client.subscriptions;
|
|
2390
|
+
const subscriptionsKeys = Object.keys(subscriptions);
|
|
2391
|
+
const accountType = this.getAccountTypeFromSubscriptions(subscriptionsKeys);
|
|
2392
|
+
const result = this.safeDict(message, 'result', {});
|
|
2393
|
+
const subscriptionId = this.safeInteger(result, 'subscriptionId');
|
|
2394
|
+
if (subscriptionId === undefined) {
|
|
2395
|
+
delete client.subscriptions[accountType];
|
|
2396
|
+
client.reject(message, accountType);
|
|
2397
|
+
}
|
|
2398
|
+
client.resolve(message, messageHash);
|
|
2399
|
+
}
|
|
2332
2400
|
async authenticate(params = {}) {
|
|
2333
2401
|
const time = this.milliseconds();
|
|
2334
2402
|
let type = undefined;
|
|
@@ -2343,6 +2411,11 @@ export default class binance extends binanceRest {
|
|
|
2343
2411
|
else if (this.isInverse(type, subType)) {
|
|
2344
2412
|
type = 'delivery';
|
|
2345
2413
|
}
|
|
2414
|
+
// For spot use WebSocket API signature subscription
|
|
2415
|
+
if (type === 'spot') {
|
|
2416
|
+
await this.ensureUserDataStreamWsSubscribeSignature('spot');
|
|
2417
|
+
return;
|
|
2418
|
+
}
|
|
2346
2419
|
let marginMode = undefined;
|
|
2347
2420
|
[marginMode, params] = this.handleMarginModeAndParams('authenticate', params);
|
|
2348
2421
|
const isIsolatedMargin = (marginMode === 'isolated');
|
|
@@ -2470,7 +2543,7 @@ export default class binance extends binanceRest {
|
|
|
2470
2543
|
}
|
|
2471
2544
|
}
|
|
2472
2545
|
setBalanceCache(client, type, isPortfolioMargin = false) {
|
|
2473
|
-
if (type in client.subscriptions) {
|
|
2546
|
+
if ((type in client.subscriptions) && (type in this.balance)) {
|
|
2474
2547
|
return;
|
|
2475
2548
|
}
|
|
2476
2549
|
const options = this.safeValue(this.options, 'watchBalance');
|
|
@@ -2734,11 +2807,18 @@ export default class binance extends binanceRest {
|
|
|
2734
2807
|
else if (this.isInverse(type, subType)) {
|
|
2735
2808
|
type = 'delivery';
|
|
2736
2809
|
}
|
|
2810
|
+
let url = '';
|
|
2737
2811
|
let urlType = type;
|
|
2738
|
-
if (
|
|
2739
|
-
|
|
2812
|
+
if (type === 'spot') {
|
|
2813
|
+
// route to WebSocket API connection where the user data stream is subscribed
|
|
2814
|
+
url = this.urls['api']['ws']['ws-api'][type];
|
|
2815
|
+
}
|
|
2816
|
+
else {
|
|
2817
|
+
if (isPortfolioMargin) {
|
|
2818
|
+
urlType = 'papi';
|
|
2819
|
+
}
|
|
2820
|
+
url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2740
2821
|
}
|
|
2741
|
-
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2742
2822
|
const client = this.client(url);
|
|
2743
2823
|
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
2744
2824
|
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
@@ -2820,9 +2900,9 @@ export default class binance extends binanceRest {
|
|
|
2820
2900
|
//
|
|
2821
2901
|
const wallet = this.safeString(this.options, 'wallet', 'wb'); // cw for cross wallet
|
|
2822
2902
|
// each account is connected to a different endpoint
|
|
2823
|
-
|
|
2824
|
-
const
|
|
2825
|
-
const accountType =
|
|
2903
|
+
const subscriptions = client.subscriptions;
|
|
2904
|
+
const subscriptionsKeys = Object.keys(subscriptions);
|
|
2905
|
+
const accountType = this.getAccountTypeFromSubscriptions(subscriptionsKeys);
|
|
2826
2906
|
const messageHash = accountType + ':balance';
|
|
2827
2907
|
if (this.balance[accountType] === undefined) {
|
|
2828
2908
|
this.balance[accountType] = {};
|
|
@@ -2866,6 +2946,17 @@ export default class binance extends binanceRest {
|
|
|
2866
2946
|
this.balance[accountType] = this.safeBalance(this.balance[accountType]);
|
|
2867
2947
|
client.resolve(this.balance[accountType], messageHash);
|
|
2868
2948
|
}
|
|
2949
|
+
getAccountTypeFromSubscriptions(subscriptions) {
|
|
2950
|
+
let accountType = '';
|
|
2951
|
+
for (let i = 0; i < subscriptions.length; i++) {
|
|
2952
|
+
const subscription = subscriptions[i];
|
|
2953
|
+
if ((subscription === 'spot') || (subscription === 'margin') || (subscription === 'future') || (subscription === 'delivery')) {
|
|
2954
|
+
accountType = subscription;
|
|
2955
|
+
break;
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
return accountType;
|
|
2959
|
+
}
|
|
2869
2960
|
getMarketType(method, market, params = {}) {
|
|
2870
2961
|
let type = undefined;
|
|
2871
2962
|
[type, params] = this.handleMarketTypeAndParams(method, market, params);
|
|
@@ -3467,10 +3558,17 @@ export default class binance extends binanceRest {
|
|
|
3467
3558
|
}
|
|
3468
3559
|
let isPortfolioMargin = undefined;
|
|
3469
3560
|
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchOrders', 'papi', 'portfolioMargin', false);
|
|
3470
|
-
|
|
3471
|
-
|
|
3561
|
+
let url = '';
|
|
3562
|
+
if (type === 'spot') {
|
|
3563
|
+
// route orders to ws-api user data stream
|
|
3564
|
+
url = this.urls['api']['ws']['ws-api'][type];
|
|
3565
|
+
}
|
|
3566
|
+
else {
|
|
3567
|
+
if (isPortfolioMargin) {
|
|
3568
|
+
urlType = 'papi';
|
|
3569
|
+
}
|
|
3570
|
+
url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
3472
3571
|
}
|
|
3473
|
-
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
3474
3572
|
const client = this.client(url);
|
|
3475
3573
|
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
3476
3574
|
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
@@ -3857,8 +3955,9 @@ export default class binance extends binanceRest {
|
|
|
3857
3955
|
//
|
|
3858
3956
|
// each account is connected to a different endpoint
|
|
3859
3957
|
// and has exactly one subscriptionhash which is the account type
|
|
3860
|
-
const subscriptions =
|
|
3861
|
-
const
|
|
3958
|
+
const subscriptions = client.subscriptions;
|
|
3959
|
+
const subscriptionsKeys = Object.keys(subscriptions);
|
|
3960
|
+
const accountType = this.getAccountTypeFromSubscriptions(subscriptionsKeys);
|
|
3862
3961
|
if (this.positions === undefined) {
|
|
3863
3962
|
this.positions = {};
|
|
3864
3963
|
}
|
|
@@ -4135,10 +4234,16 @@ export default class binance extends binanceRest {
|
|
|
4135
4234
|
}
|
|
4136
4235
|
let isPortfolioMargin = undefined;
|
|
4137
4236
|
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchMyTrades', 'papi', 'portfolioMargin', false);
|
|
4138
|
-
|
|
4139
|
-
|
|
4237
|
+
let url = '';
|
|
4238
|
+
if (type === 'spot') {
|
|
4239
|
+
url = this.urls['api']['ws']['ws-api'][type];
|
|
4240
|
+
}
|
|
4241
|
+
else {
|
|
4242
|
+
if (isPortfolioMargin) {
|
|
4243
|
+
urlType = 'papi';
|
|
4244
|
+
}
|
|
4245
|
+
url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
4140
4246
|
}
|
|
4141
|
-
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
4142
4247
|
const client = this.client(url);
|
|
4143
4248
|
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
4144
4249
|
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
@@ -4284,8 +4389,12 @@ export default class binance extends binanceRest {
|
|
|
4284
4389
|
for (let i = 0; i < subscriptionKeys.length; i++) {
|
|
4285
4390
|
const subscriptionHash = subscriptionKeys[i];
|
|
4286
4391
|
const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
|
|
4392
|
+
const subscription = this.safeString(client.subscriptions[subscriptionHash], 'subscription');
|
|
4287
4393
|
if (id === subscriptionId) {
|
|
4288
4394
|
client.reject(e, subscriptionHash);
|
|
4395
|
+
if (subscription !== undefined) {
|
|
4396
|
+
delete client.subscriptions[subscription];
|
|
4397
|
+
}
|
|
4289
4398
|
}
|
|
4290
4399
|
}
|
|
4291
4400
|
}
|
|
@@ -4298,14 +4407,35 @@ export default class binance extends binanceRest {
|
|
|
4298
4407
|
client.reset(message);
|
|
4299
4408
|
}
|
|
4300
4409
|
}
|
|
4410
|
+
handleEventStreamTerminated(client, message) {
|
|
4411
|
+
//
|
|
4412
|
+
// {
|
|
4413
|
+
// e: 'eventStreamTerminated',
|
|
4414
|
+
// E: 1757896885229
|
|
4415
|
+
// }
|
|
4416
|
+
//
|
|
4417
|
+
const event = this.safeString(message, 'e');
|
|
4418
|
+
const subscriptions = client.subscriptions;
|
|
4419
|
+
const subscriptionsKeys = Object.keys(subscriptions);
|
|
4420
|
+
const accountType = this.getAccountTypeFromSubscriptions(subscriptionsKeys);
|
|
4421
|
+
if (event === 'eventStreamTerminated') {
|
|
4422
|
+
delete client.subscriptions[accountType];
|
|
4423
|
+
client.reject(message, accountType);
|
|
4424
|
+
}
|
|
4425
|
+
}
|
|
4301
4426
|
handleMessage(client, message) {
|
|
4302
4427
|
// handle WebSocketAPI
|
|
4428
|
+
const eventMsg = this.safeDict(message, 'event');
|
|
4429
|
+
if (eventMsg !== undefined) {
|
|
4430
|
+
message = eventMsg;
|
|
4431
|
+
}
|
|
4303
4432
|
const status = this.safeString(message, 'status');
|
|
4304
4433
|
const error = this.safeValue(message, 'error');
|
|
4305
4434
|
if ((error !== undefined) || (status !== undefined && status !== '200')) {
|
|
4306
4435
|
this.handleWsError(client, message);
|
|
4307
4436
|
return;
|
|
4308
4437
|
}
|
|
4438
|
+
// user subscription wraps message in subscriptionId and event
|
|
4309
4439
|
const id = this.safeString(message, 'id');
|
|
4310
4440
|
const subscriptions = this.safeValue(client.subscriptions, id);
|
|
4311
4441
|
let method = this.safeValue(subscriptions, 'method');
|
|
@@ -4340,6 +4470,7 @@ export default class binance extends binanceRest {
|
|
|
4340
4470
|
'executionReport': this.handleOrderUpdate,
|
|
4341
4471
|
'ORDER_TRADE_UPDATE': this.handleOrderUpdate,
|
|
4342
4472
|
'forceOrder': this.handleLiquidation,
|
|
4473
|
+
'eventStreamTerminated': this.handleEventStreamTerminated,
|
|
4343
4474
|
'externalLockUpdate': this.handleBalance,
|
|
4344
4475
|
};
|
|
4345
4476
|
let event = this.safeString(message, 'e');
|