ccxt 4.2.17 → 4.2.19
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 +9 -9
- package/dist/ccxt.browser.js +48992 -47725
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +12 -1
- package/dist/cjs/src/alpaca.js +18 -18
- package/dist/cjs/src/ascendex.js +13 -6
- package/dist/cjs/src/base/Exchange.js +266 -27
- package/dist/cjs/src/bigone.js +434 -168
- package/dist/cjs/src/binance.js +163 -34
- package/dist/cjs/src/binanceus.js +8 -0
- package/dist/cjs/src/bingx.js +183 -41
- package/dist/cjs/src/bitfinex.js +2 -3
- package/dist/cjs/src/bitget.js +59 -16
- package/dist/cjs/src/bitmart.js +5 -5
- package/dist/cjs/src/bitmex.js +4 -6
- package/dist/cjs/src/bitpanda.js +5 -1991
- package/dist/cjs/src/bitstamp.js +8 -0
- package/dist/cjs/src/bybit.js +27 -47
- package/dist/cjs/src/coinbase.js +176 -26
- package/dist/cjs/src/coincheck.js +1 -0
- package/dist/cjs/src/coinex.js +3 -0
- package/dist/cjs/src/coinlist.js +13 -6
- package/dist/cjs/src/coinone.js +2 -2
- package/dist/cjs/src/coinsph.js +4 -5
- package/dist/cjs/src/delta.js +7 -1
- package/dist/cjs/src/deribit.js +17 -4
- package/dist/cjs/src/gate.js +151 -169
- package/dist/cjs/src/gemini.js +1 -1
- package/dist/cjs/src/hitbtc.js +2 -3
- package/dist/cjs/src/htx.js +157 -7
- package/dist/cjs/src/huobijp.js +2 -3
- package/dist/cjs/src/independentreserve.js +7 -5
- package/dist/cjs/src/kraken.js +86 -54
- package/dist/cjs/src/kucoin.js +5 -0
- package/dist/cjs/src/kucoinfutures.js +131 -77
- package/dist/cjs/src/lbank.js +60 -33
- package/dist/cjs/src/luno.js +84 -2
- package/dist/cjs/src/mexc.js +3 -3
- package/dist/cjs/src/oceanex.js +1 -1
- package/dist/cjs/src/okx.js +23 -11
- package/dist/cjs/{js/src/bitpanda.js → src/onetrading.js} +39 -39
- package/dist/cjs/src/phemex.js +37 -27
- package/dist/cjs/src/poloniexfutures.js +1 -0
- package/dist/cjs/src/pro/binance.js +66 -25
- package/dist/cjs/src/pro/bitget.js +1 -1
- package/dist/cjs/src/pro/bitpanda.js +5 -1330
- package/dist/cjs/src/pro/coinbase.js +4 -1
- package/dist/cjs/src/pro/coincheck.js +208 -0
- package/dist/cjs/src/pro/hitbtc.js +5 -4
- package/dist/cjs/src/pro/htx.js +6 -1
- package/dist/cjs/src/pro/kraken.js +1 -1
- package/dist/cjs/src/pro/krakenfutures.js +7 -1
- package/dist/cjs/src/pro/kucoin.js +46 -36
- package/dist/cjs/src/pro/kucoinfutures.js +45 -37
- package/dist/cjs/src/pro/lbank.js +881 -0
- package/dist/cjs/src/pro/okx.js +52 -2
- package/dist/cjs/{js/src/pro/bitpanda.js → src/pro/onetrading.js} +4 -7
- package/dist/cjs/src/pro/poloniex.js +2 -2
- package/dist/cjs/src/pro/poloniexfutures.js +43 -35
- package/dist/cjs/src/pro/woo.js +126 -0
- package/dist/cjs/src/probit.js +4 -2
- package/dist/cjs/src/upbit.js +12 -12
- package/dist/cjs/src/wavesexchange.js +1 -1
- package/dist/cjs/src/whitebit.js +1 -0
- package/dist/cjs/src/woo.js +56 -0
- package/js/ccxt.d.ts +14 -2
- package/js/ccxt.js +10 -2
- package/js/src/abstract/bitpanda.d.ts +4 -4
- package/js/src/abstract/bitstamp.d.ts +8 -0
- package/js/src/abstract/gate.d.ts +1 -0
- package/js/src/abstract/gateio.d.ts +1 -0
- package/js/src/abstract/htx.d.ts +3 -0
- package/js/src/abstract/huobi.d.ts +3 -0
- package/js/src/abstract/luno.d.ts +1 -0
- package/js/src/abstract/onetrading.d.ts +38 -0
- package/js/src/ascendex.js +2 -0
- package/js/src/base/Exchange.d.ts +2 -3
- package/js/src/base/Exchange.js +5 -2
- package/js/src/binance.js +7 -1
- package/js/src/bingx.d.ts +1 -0
- package/js/src/bingx.js +26 -0
- package/js/src/bitget.js +22 -3
- package/js/src/bitpanda.d.ts +2 -72
- package/js/src/bitpanda.js +5 -1991
- package/js/src/bitstamp.js +8 -0
- package/js/src/bybit.js +21 -47
- package/js/src/coincheck.js +1 -0
- package/js/src/deribit.js +16 -4
- package/js/src/gate.d.ts +1 -0
- package/js/src/gate.js +50 -110
- package/js/src/htx.js +3 -0
- package/js/src/kraken.d.ts +1 -0
- package/js/src/kraken.js +40 -39
- package/js/src/lbank.js +1 -0
- package/js/src/luno.d.ts +3 -1
- package/js/src/luno.js +84 -2
- package/js/src/mexc.js +1 -2
- package/js/src/onetrading.d.ts +74 -0
- package/js/src/onetrading.js +2003 -0
- package/js/src/poloniexfutures.js +1 -0
- package/js/src/pro/binance.js +7 -2
- package/js/src/pro/bitget.js +1 -1
- package/js/src/pro/bitpanda.d.ts +2 -34
- package/js/src/pro/bitpanda.js +5 -1330
- package/js/src/pro/coincheck.d.ts +12 -0
- package/js/src/pro/coincheck.js +209 -0
- package/js/src/pro/kucoin.js +43 -35
- package/js/src/pro/kucoinfutures.js +45 -37
- package/js/src/pro/lbank.d.ts +29 -0
- package/js/src/pro/lbank.js +882 -0
- package/js/src/pro/onetrading.d.ts +36 -0
- package/js/src/pro/onetrading.js +1339 -0
- package/js/src/pro/poloniexfutures.js +43 -35
- package/js/src/whitebit.js +1 -0
- package/package.json +2 -2
- package/rollup.config.js +2 -0
- package/skip-tests.json +14 -2
- package/test-commonjs.cjs +25 -1
- package/dist/cjs/js/ccxt.js +0 -476
- package/dist/cjs/js/src/abstract/alpaca.js +0 -9
- package/dist/cjs/js/src/abstract/ascendex.js +0 -9
- package/dist/cjs/js/src/abstract/bigone.js +0 -9
- package/dist/cjs/js/src/abstract/binance.js +0 -9
- package/dist/cjs/js/src/abstract/bingx.js +0 -9
- package/dist/cjs/js/src/abstract/bit2c.js +0 -9
- package/dist/cjs/js/src/abstract/bitbank.js +0 -9
- package/dist/cjs/js/src/abstract/bitbns.js +0 -9
- package/dist/cjs/js/src/abstract/bitfinex.js +0 -9
- package/dist/cjs/js/src/abstract/bitfinex2.js +0 -9
- package/dist/cjs/js/src/abstract/bitflyer.js +0 -9
- package/dist/cjs/js/src/abstract/bitforex.js +0 -9
- package/dist/cjs/js/src/abstract/bitget.js +0 -9
- package/dist/cjs/js/src/abstract/bithumb.js +0 -9
- package/dist/cjs/js/src/abstract/bitmart.js +0 -9
- package/dist/cjs/js/src/abstract/bitmex.js +0 -9
- package/dist/cjs/js/src/abstract/bitopro.js +0 -9
- package/dist/cjs/js/src/abstract/bitpanda.js +0 -9
- package/dist/cjs/js/src/abstract/bitrue.js +0 -9
- package/dist/cjs/js/src/abstract/bitso.js +0 -9
- package/dist/cjs/js/src/abstract/bitstamp.js +0 -9
- package/dist/cjs/js/src/abstract/bitteam.js +0 -9
- package/dist/cjs/js/src/abstract/bitvavo.js +0 -9
- package/dist/cjs/js/src/abstract/bl3p.js +0 -9
- package/dist/cjs/js/src/abstract/blockchaincom.js +0 -9
- package/dist/cjs/js/src/abstract/btcalpha.js +0 -9
- package/dist/cjs/js/src/abstract/btcbox.js +0 -9
- package/dist/cjs/js/src/abstract/btcmarkets.js +0 -9
- package/dist/cjs/js/src/abstract/btcturk.js +0 -9
- package/dist/cjs/js/src/abstract/bybit.js +0 -9
- package/dist/cjs/js/src/abstract/cex.js +0 -9
- package/dist/cjs/js/src/abstract/coinbase.js +0 -9
- package/dist/cjs/js/src/abstract/coinbasepro.js +0 -9
- package/dist/cjs/js/src/abstract/coincheck.js +0 -9
- package/dist/cjs/js/src/abstract/coinex.js +0 -9
- package/dist/cjs/js/src/abstract/coinlist.js +0 -9
- package/dist/cjs/js/src/abstract/coinmate.js +0 -9
- package/dist/cjs/js/src/abstract/coinone.js +0 -9
- package/dist/cjs/js/src/abstract/coinsph.js +0 -9
- package/dist/cjs/js/src/abstract/coinspot.js +0 -9
- package/dist/cjs/js/src/abstract/cryptocom.js +0 -9
- package/dist/cjs/js/src/abstract/currencycom.js +0 -9
- package/dist/cjs/js/src/abstract/delta.js +0 -9
- package/dist/cjs/js/src/abstract/deribit.js +0 -9
- package/dist/cjs/js/src/abstract/digifinex.js +0 -9
- package/dist/cjs/js/src/abstract/exmo.js +0 -9
- package/dist/cjs/js/src/abstract/gate.js +0 -9
- package/dist/cjs/js/src/abstract/gemini.js +0 -9
- package/dist/cjs/js/src/abstract/hitbtc.js +0 -9
- package/dist/cjs/js/src/abstract/hollaex.js +0 -9
- package/dist/cjs/js/src/abstract/htx.js +0 -9
- package/dist/cjs/js/src/abstract/huobijp.js +0 -9
- package/dist/cjs/js/src/abstract/idex.js +0 -9
- package/dist/cjs/js/src/abstract/independentreserve.js +0 -9
- package/dist/cjs/js/src/abstract/indodax.js +0 -9
- package/dist/cjs/js/src/abstract/kraken.js +0 -9
- package/dist/cjs/js/src/abstract/krakenfutures.js +0 -9
- package/dist/cjs/js/src/abstract/kucoin.js +0 -9
- package/dist/cjs/js/src/abstract/kucoinfutures.js +0 -9
- package/dist/cjs/js/src/abstract/kuna.js +0 -9
- package/dist/cjs/js/src/abstract/latoken.js +0 -9
- package/dist/cjs/js/src/abstract/lbank.js +0 -9
- package/dist/cjs/js/src/abstract/luno.js +0 -9
- package/dist/cjs/js/src/abstract/lykke.js +0 -9
- package/dist/cjs/js/src/abstract/mercado.js +0 -9
- package/dist/cjs/js/src/abstract/mexc.js +0 -9
- package/dist/cjs/js/src/abstract/ndax.js +0 -9
- package/dist/cjs/js/src/abstract/novadax.js +0 -9
- package/dist/cjs/js/src/abstract/oceanex.js +0 -9
- package/dist/cjs/js/src/abstract/okcoin.js +0 -9
- package/dist/cjs/js/src/abstract/okx.js +0 -9
- package/dist/cjs/js/src/abstract/p2b.js +0 -9
- package/dist/cjs/js/src/abstract/paymium.js +0 -9
- package/dist/cjs/js/src/abstract/phemex.js +0 -9
- package/dist/cjs/js/src/abstract/poloniex.js +0 -9
- package/dist/cjs/js/src/abstract/poloniexfutures.js +0 -9
- package/dist/cjs/js/src/abstract/probit.js +0 -9
- package/dist/cjs/js/src/abstract/timex.js +0 -9
- package/dist/cjs/js/src/abstract/tokocrypto.js +0 -9
- package/dist/cjs/js/src/abstract/upbit.js +0 -9
- package/dist/cjs/js/src/abstract/wavesexchange.js +0 -9
- package/dist/cjs/js/src/abstract/wazirx.js +0 -9
- package/dist/cjs/js/src/abstract/whitebit.js +0 -9
- package/dist/cjs/js/src/abstract/woo.js +0 -9
- package/dist/cjs/js/src/abstract/yobit.js +0 -9
- package/dist/cjs/js/src/abstract/zaif.js +0 -9
- package/dist/cjs/js/src/abstract/zonda.js +0 -9
- package/dist/cjs/js/src/ace.js +0 -1058
- package/dist/cjs/js/src/alpaca.js +0 -1125
- package/dist/cjs/js/src/ascendex.js +0 -3365
- package/dist/cjs/js/src/base/Exchange.js +0 -5257
- package/dist/cjs/js/src/base/Precise.js +0 -263
- package/dist/cjs/js/src/base/errors.js +0 -299
- package/dist/cjs/js/src/base/functions/crypto.js +0 -78
- package/dist/cjs/js/src/base/functions/encode.js +0 -44
- package/dist/cjs/js/src/base/functions/generic.js +0 -193
- package/dist/cjs/js/src/base/functions/misc.js +0 -96
- package/dist/cjs/js/src/base/functions/number.js +0 -297
- package/dist/cjs/js/src/base/functions/platform.js +0 -28
- package/dist/cjs/js/src/base/functions/rsa.js +0 -34
- package/dist/cjs/js/src/base/functions/string.js +0 -48
- package/dist/cjs/js/src/base/functions/throttle.js +0 -66
- package/dist/cjs/js/src/base/functions/time.js +0 -187
- package/dist/cjs/js/src/base/functions/totp.js +0 -24
- package/dist/cjs/js/src/base/functions/type.js +0 -162
- package/dist/cjs/js/src/base/functions.js +0 -157
- package/dist/cjs/js/src/base/ws/Cache.js +0 -254
- package/dist/cjs/js/src/base/ws/Client.js +0 -299
- package/dist/cjs/js/src/base/ws/Future.js +0 -34
- package/dist/cjs/js/src/base/ws/OrderBook.js +0 -107
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +0 -281
- package/dist/cjs/js/src/base/ws/WsClient.js +0 -69
- package/dist/cjs/js/src/bequant.js +0 -33
- package/dist/cjs/js/src/bigone.js +0 -2213
- package/dist/cjs/js/src/binance.js +0 -9845
- package/dist/cjs/js/src/binancecoinm.js +0 -45
- package/dist/cjs/js/src/binanceus.js +0 -92
- package/dist/cjs/js/src/binanceusdm.js +0 -58
- package/dist/cjs/js/src/bingx.js +0 -3846
- package/dist/cjs/js/src/bit2c.js +0 -916
- package/dist/cjs/js/src/bitbank.js +0 -1000
- package/dist/cjs/js/src/bitbay.js +0 -17
- package/dist/cjs/js/src/bitbns.js +0 -1220
- package/dist/cjs/js/src/bitcoincom.js +0 -17
- package/dist/cjs/js/src/bitfinex.js +0 -1670
- package/dist/cjs/js/src/bitfinex2.js +0 -2990
- package/dist/cjs/js/src/bitflyer.js +0 -1045
- package/dist/cjs/js/src/bitforex.js +0 -852
- package/dist/cjs/js/src/bitget.js +0 -8295
- package/dist/cjs/js/src/bithumb.js +0 -1090
- package/dist/cjs/js/src/bitmart.js +0 -4454
- package/dist/cjs/js/src/bitmex.js +0 -2881
- package/dist/cjs/js/src/bitopro.js +0 -1724
- package/dist/cjs/js/src/bitrue.js +0 -3253
- package/dist/cjs/js/src/bitso.js +0 -1753
- package/dist/cjs/js/src/bitstamp.js +0 -2188
- package/dist/cjs/js/src/bitteam.js +0 -2309
- package/dist/cjs/js/src/bitvavo.js +0 -1968
- package/dist/cjs/js/src/bl3p.js +0 -447
- package/dist/cjs/js/src/blockchaincom.js +0 -1160
- package/dist/cjs/js/src/btcalpha.js +0 -929
- package/dist/cjs/js/src/btcbox.js +0 -565
- package/dist/cjs/js/src/btcmarkets.js +0 -1237
- package/dist/cjs/js/src/btcturk.js +0 -929
- package/dist/cjs/js/src/bybit.js +0 -7650
- package/dist/cjs/js/src/cex.js +0 -1693
- package/dist/cjs/js/src/coinbase.js +0 -3424
- package/dist/cjs/js/src/coinbasepro.js +0 -1866
- package/dist/cjs/js/src/coincheck.js +0 -843
- package/dist/cjs/js/src/coinex.js +0 -5417
- package/dist/cjs/js/src/coinlist.js +0 -2337
- package/dist/cjs/js/src/coinmate.js +0 -989
- package/dist/cjs/js/src/coinone.js +0 -1185
- package/dist/cjs/js/src/coinsph.js +0 -1933
- package/dist/cjs/js/src/coinspot.js +0 -548
- package/dist/cjs/js/src/cryptocom.js +0 -3007
- package/dist/cjs/js/src/currencycom.js +0 -2015
- package/dist/cjs/js/src/delta.js +0 -3262
- package/dist/cjs/js/src/deribit.js +0 -3306
- package/dist/cjs/js/src/digifinex.js +0 -4307
- package/dist/cjs/js/src/exmo.js +0 -2645
- package/dist/cjs/js/src/fmfwio.js +0 -34
- package/dist/cjs/js/src/gate.js +0 -7077
- package/dist/cjs/js/src/gateio.js +0 -16
- package/dist/cjs/js/src/gemini.js +0 -1801
- package/dist/cjs/js/src/hitbtc.js +0 -3660
- package/dist/cjs/js/src/hitbtc3.js +0 -19
- package/dist/cjs/js/src/hollaex.js +0 -1882
- package/dist/cjs/js/src/htx.js +0 -9174
- package/dist/cjs/js/src/huobi.js +0 -16
- package/dist/cjs/js/src/huobijp.js +0 -1918
- package/dist/cjs/js/src/idex.js +0 -1770
- package/dist/cjs/js/src/independentreserve.js +0 -761
- package/dist/cjs/js/src/indodax.js +0 -1069
- package/dist/cjs/js/src/kraken.js +0 -2891
- package/dist/cjs/js/src/krakenfutures.js +0 -2407
- package/dist/cjs/js/src/kucoin.js +0 -4494
- package/dist/cjs/js/src/kucoinfutures.js +0 -2529
- package/dist/cjs/js/src/kuna.js +0 -1949
- package/dist/cjs/js/src/latoken.js +0 -1729
- package/dist/cjs/js/src/lbank.js +0 -2851
- package/dist/cjs/js/src/luno.js +0 -1044
- package/dist/cjs/js/src/lykke.js +0 -1303
- package/dist/cjs/js/src/mercado.js +0 -897
- package/dist/cjs/js/src/mexc.js +0 -5407
- package/dist/cjs/js/src/ndax.js +0 -2450
- package/dist/cjs/js/src/novadax.js +0 -1556
- package/dist/cjs/js/src/oceanex.js +0 -964
- package/dist/cjs/js/src/okcoin.js +0 -3115
- package/dist/cjs/js/src/okx.js +0 -7331
- package/dist/cjs/js/src/p2b.js +0 -1243
- package/dist/cjs/js/src/paymium.js +0 -597
- package/dist/cjs/js/src/phemex.js +0 -4725
- package/dist/cjs/js/src/poloniex.js +0 -2356
- package/dist/cjs/js/src/poloniexfutures.js +0 -1794
- package/dist/cjs/js/src/pro/alpaca.js +0 -714
- package/dist/cjs/js/src/pro/ascendex.js +0 -957
- package/dist/cjs/js/src/pro/bequant.js +0 -33
- package/dist/cjs/js/src/pro/binance.js +0 -2796
- package/dist/cjs/js/src/pro/binancecoinm.js +0 -23
- package/dist/cjs/js/src/pro/binanceus.js +0 -51
- package/dist/cjs/js/src/pro/binanceusdm.js +0 -32
- package/dist/cjs/js/src/pro/bingx.js +0 -944
- package/dist/cjs/js/src/pro/bitcoincom.js +0 -29
- package/dist/cjs/js/src/pro/bitfinex.js +0 -672
- package/dist/cjs/js/src/pro/bitfinex2.js +0 -1159
- package/dist/cjs/js/src/pro/bitget.js +0 -1733
- package/dist/cjs/js/src/pro/bitmart.js +0 -1486
- package/dist/cjs/js/src/pro/bitmex.js +0 -1576
- package/dist/cjs/js/src/pro/bitopro.js +0 -327
- package/dist/cjs/js/src/pro/bitrue.js +0 -462
- package/dist/cjs/js/src/pro/bitstamp.js +0 -547
- package/dist/cjs/js/src/pro/bitvavo.js +0 -704
- package/dist/cjs/js/src/pro/blockchaincom.js +0 -794
- package/dist/cjs/js/src/pro/bybit.js +0 -1843
- package/dist/cjs/js/src/pro/cex.js +0 -1510
- package/dist/cjs/js/src/pro/coinbase.js +0 -561
- package/dist/cjs/js/src/pro/coinbasepro.js +0 -968
- package/dist/cjs/js/src/pro/coinex.js +0 -1095
- package/dist/cjs/js/src/pro/cryptocom.js +0 -1020
- package/dist/cjs/js/src/pro/currencycom.js +0 -563
- package/dist/cjs/js/src/pro/deribit.js +0 -825
- package/dist/cjs/js/src/pro/exmo.js +0 -658
- package/dist/cjs/js/src/pro/gate.js +0 -1316
- package/dist/cjs/js/src/pro/gateio.js +0 -16
- package/dist/cjs/js/src/pro/gemini.js +0 -649
- package/dist/cjs/js/src/pro/hitbtc.js +0 -1294
- package/dist/cjs/js/src/pro/hollaex.js +0 -597
- package/dist/cjs/js/src/pro/htx.js +0 -2388
- package/dist/cjs/js/src/pro/huobi.js +0 -16
- package/dist/cjs/js/src/pro/huobijp.js +0 -606
- package/dist/cjs/js/src/pro/idex.js +0 -714
- package/dist/cjs/js/src/pro/independentreserve.js +0 -280
- package/dist/cjs/js/src/pro/kraken.js +0 -1364
- package/dist/cjs/js/src/pro/krakenfutures.js +0 -1506
- package/dist/cjs/js/src/pro/kucoin.js +0 -1054
- package/dist/cjs/js/src/pro/kucoinfutures.js +0 -981
- package/dist/cjs/js/src/pro/luno.js +0 -322
- package/dist/cjs/js/src/pro/mexc.js +0 -1170
- package/dist/cjs/js/src/pro/ndax.js +0 -545
- package/dist/cjs/js/src/pro/okcoin.js +0 -760
- package/dist/cjs/js/src/pro/okx.js +0 -1608
- package/dist/cjs/js/src/pro/phemex.js +0 -1511
- package/dist/cjs/js/src/pro/poloniex.js +0 -1253
- package/dist/cjs/js/src/pro/poloniexfutures.js +0 -1014
- package/dist/cjs/js/src/pro/probit.js +0 -586
- package/dist/cjs/js/src/pro/upbit.js +0 -234
- package/dist/cjs/js/src/pro/wazirx.js +0 -776
- package/dist/cjs/js/src/pro/whitebit.js +0 -927
- package/dist/cjs/js/src/pro/woo.js +0 -895
- package/dist/cjs/js/src/probit.js +0 -1867
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +0 -401
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +0 -195
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +0 -308
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +0 -554
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +0 -94
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +0 -70
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +0 -91
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +0 -16
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +0 -1760
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +0 -52
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +0 -81
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +0 -376
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +0 -70
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +0 -1580
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +0 -74
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +0 -24
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +0 -158
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +0 -429
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +0 -176
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +0 -324
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +0 -163
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +0 -245
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +0 -1018
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +0 -383
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +0 -258
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +0 -53
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +0 -120
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +0 -69
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +0 -7
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +0 -83
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +0 -240
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +0 -91
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +0 -130
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +0 -214
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +0 -239
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +0 -93
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +0 -354
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +0 -16
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +0 -20
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +0 -30
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +0 -239
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +0 -372
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +0 -273
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +0 -139
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +0 -14
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +0 -16
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +0 -81
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +0 -292
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +0 -103
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +0 -140
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +0 -175
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +0 -95
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +0 -7
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +0 -383
- package/dist/cjs/js/src/timex.js +0 -1562
- package/dist/cjs/js/src/tokocrypto.js +0 -2542
- package/dist/cjs/js/src/upbit.js +0 -1844
- package/dist/cjs/js/src/wavesexchange.js +0 -2607
- package/dist/cjs/js/src/wazirx.js +0 -953
- package/dist/cjs/js/src/whitebit.js +0 -2309
- package/dist/cjs/js/src/woo.js +0 -2769
- package/dist/cjs/js/src/yobit.js +0 -1314
- package/dist/cjs/js/src/zaif.js +0 -736
- package/dist/cjs/js/src/zonda.js +0 -1883
- package/dist/cjs/src/abstract/bitpanda.js +0 -9
- package/test.ts +0 -0
- /package/dist/cjs/{js/src/abstract/ace.js → src/abstract/onetrading.js} +0 -0
- /package/dist/cjs/{js/src → src}/pro/coinone.js +0 -0
- /package/js/src/abstract/{bitpanda.js → onetrading.js} +0 -0
|
@@ -1,2796 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var binance$1 = require('../binance.js');
|
|
4
|
-
var Precise = require('../base/Precise.js');
|
|
5
|
-
var errors = require('../base/errors.js');
|
|
6
|
-
var Cache = require('../base/ws/Cache.js');
|
|
7
|
-
var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
|
|
8
|
-
var rsa = require('../base/functions/rsa.js');
|
|
9
|
-
var crypto = require('../base/functions/crypto.js');
|
|
10
|
-
var ed25519 = require('../static_dependencies/noble-curves/ed25519.js');
|
|
11
|
-
|
|
12
|
-
// ----------------------------------------------------------------------------
|
|
13
|
-
// -----------------------------------------------------------------------------
|
|
14
|
-
class binance extends binance$1 {
|
|
15
|
-
describe() {
|
|
16
|
-
return this.deepExtend(super.describe(), {
|
|
17
|
-
'has': {
|
|
18
|
-
'ws': true,
|
|
19
|
-
'watchBalance': true,
|
|
20
|
-
'watchMyTrades': true,
|
|
21
|
-
'watchOHLCV': true,
|
|
22
|
-
'watchOHLCVForSymbols': false,
|
|
23
|
-
'watchOrderBook': true,
|
|
24
|
-
'watchOrderBookForSymbols': true,
|
|
25
|
-
'watchOrders': true,
|
|
26
|
-
'watchOrdersForSymbols': true,
|
|
27
|
-
'watchPositions': true,
|
|
28
|
-
'watchTicker': true,
|
|
29
|
-
'watchTickers': true,
|
|
30
|
-
'watchTrades': true,
|
|
31
|
-
'watchTradesForSymbols': true,
|
|
32
|
-
'createOrderWs': true,
|
|
33
|
-
'editOrderWs': true,
|
|
34
|
-
'cancelOrderWs': true,
|
|
35
|
-
'cancelOrdersWs': false,
|
|
36
|
-
'cancelAllOrdersWs': true,
|
|
37
|
-
'fetchOrderWs': true,
|
|
38
|
-
'fetchOrdersWs': true,
|
|
39
|
-
'fetchBalanceWs': true,
|
|
40
|
-
'fetchMyTradesWs': true,
|
|
41
|
-
},
|
|
42
|
-
'urls': {
|
|
43
|
-
'test': {
|
|
44
|
-
'ws': {
|
|
45
|
-
'spot': 'wss://testnet.binance.vision/ws',
|
|
46
|
-
'margin': 'wss://testnet.binance.vision/ws',
|
|
47
|
-
'future': 'wss://stream.binancefuture.com/ws',
|
|
48
|
-
'delivery': 'wss://dstream.binancefuture.com/ws',
|
|
49
|
-
'ws': 'wss://testnet.binance.vision/ws-api/v3',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
'api': {
|
|
53
|
-
'ws': {
|
|
54
|
-
'spot': 'wss://stream.binance.com/ws',
|
|
55
|
-
'margin': 'wss://stream.binance.com/ws',
|
|
56
|
-
'future': 'wss://fstream.binance.com/ws',
|
|
57
|
-
'delivery': 'wss://dstream.binance.com/ws',
|
|
58
|
-
'ws': 'wss://ws-api.binance.com:443/ws-api/v3',
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
'streaming': {
|
|
63
|
-
'keepAlive': 180000,
|
|
64
|
-
},
|
|
65
|
-
'options': {
|
|
66
|
-
'returnRateLimits': false,
|
|
67
|
-
'streamLimits': {
|
|
68
|
-
'spot': 50,
|
|
69
|
-
'margin': 50,
|
|
70
|
-
'future': 50,
|
|
71
|
-
'delivery': 50, // max 200
|
|
72
|
-
},
|
|
73
|
-
'subscriptionLimitByStream': {
|
|
74
|
-
'spot': 200,
|
|
75
|
-
'margin': 200,
|
|
76
|
-
'future': 200,
|
|
77
|
-
'delivery': 200,
|
|
78
|
-
},
|
|
79
|
-
'streamBySubscriptionsHash': {},
|
|
80
|
-
'streamIndex': -1,
|
|
81
|
-
// get updates every 1000ms or 100ms
|
|
82
|
-
// or every 0ms in real-time for futures
|
|
83
|
-
'watchOrderBookRate': 100,
|
|
84
|
-
'tradesLimit': 1000,
|
|
85
|
-
'ordersLimit': 1000,
|
|
86
|
-
'OHLCVLimit': 1000,
|
|
87
|
-
'requestId': {},
|
|
88
|
-
'watchOrderBookLimit': 1000,
|
|
89
|
-
'watchTrades': {
|
|
90
|
-
'name': 'trade', // 'trade' or 'aggTrade'
|
|
91
|
-
},
|
|
92
|
-
'watchTicker': {
|
|
93
|
-
'name': 'ticker', // ticker = 1000ms L1+OHLCV, bookTicker = real-time L1
|
|
94
|
-
},
|
|
95
|
-
'watchTickers': {
|
|
96
|
-
'name': 'ticker', // ticker or miniTicker or bookTicker
|
|
97
|
-
},
|
|
98
|
-
'watchOHLCV': {
|
|
99
|
-
'name': 'kline', // or indexPriceKline or markPriceKline (coin-m futures)
|
|
100
|
-
},
|
|
101
|
-
'watchOrderBook': {
|
|
102
|
-
'maxRetries': 3,
|
|
103
|
-
},
|
|
104
|
-
'watchBalance': {
|
|
105
|
-
'fetchBalanceSnapshot': false,
|
|
106
|
-
'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
|
|
107
|
-
},
|
|
108
|
-
'watchPositions': {
|
|
109
|
-
'fetchPositionsSnapshot': true,
|
|
110
|
-
'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
|
|
111
|
-
},
|
|
112
|
-
'wallet': 'wb',
|
|
113
|
-
'listenKeyRefreshRate': 1200000,
|
|
114
|
-
'ws': {
|
|
115
|
-
'cost': 5,
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
requestId(url) {
|
|
121
|
-
const options = this.safeValue(this.options, 'requestId', {});
|
|
122
|
-
const previousValue = this.safeInteger(options, url, 0);
|
|
123
|
-
const newValue = this.sum(previousValue, 1);
|
|
124
|
-
this.options['requestId'][url] = newValue;
|
|
125
|
-
return newValue;
|
|
126
|
-
}
|
|
127
|
-
stream(type, subscriptionHash, numSubscriptions = 1) {
|
|
128
|
-
const streamBySubscriptionsHash = this.safeValue(this.options, 'streamBySubscriptionsHash', {});
|
|
129
|
-
let stream = this.safeString(streamBySubscriptionsHash, subscriptionHash);
|
|
130
|
-
if (stream === undefined) {
|
|
131
|
-
let streamIndex = this.safeInteger(this.options, 'streamIndex', -1);
|
|
132
|
-
const streamLimits = this.safeValue(this.options, 'streamLimits');
|
|
133
|
-
const streamLimit = this.safeInteger(streamLimits, type);
|
|
134
|
-
streamIndex = streamIndex + 1;
|
|
135
|
-
const normalizedIndex = streamIndex % streamLimit;
|
|
136
|
-
this.options['streamIndex'] = streamIndex;
|
|
137
|
-
stream = this.numberToString(normalizedIndex);
|
|
138
|
-
this.options['streamBySubscriptionsHash'][subscriptionHash] = stream;
|
|
139
|
-
const subscriptionsByStreams = this.safeValue(this.options, 'numSubscriptionsByStream');
|
|
140
|
-
if (subscriptionsByStreams === undefined) {
|
|
141
|
-
this.options['numSubscriptionsByStream'] = {};
|
|
142
|
-
}
|
|
143
|
-
const subscriptionsByStream = this.safeInteger(this.options['numSubscriptionsByStream'], stream, 0);
|
|
144
|
-
const newNumSubscriptions = subscriptionsByStream + numSubscriptions;
|
|
145
|
-
const subscriptionLimitByStream = this.safeInteger(this.options, 'subscriptionLimitByStream', 200);
|
|
146
|
-
if (newNumSubscriptions > subscriptionLimitByStream) {
|
|
147
|
-
throw new errors.BadRequest(this.id + ' reached the limit of subscriptions by stream. Increase the number of streams, or increase the stream limit or subscription limit by stream if the exchange allows.');
|
|
148
|
-
}
|
|
149
|
-
this.options['numSubscriptionsByStream'][stream] = subscriptionsByStream + numSubscriptions;
|
|
150
|
-
}
|
|
151
|
-
return stream;
|
|
152
|
-
}
|
|
153
|
-
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
154
|
-
/**
|
|
155
|
-
* @method
|
|
156
|
-
* @name binance#watchOrderBook
|
|
157
|
-
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
158
|
-
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
159
|
-
* @param {int} [limit] the maximum amount of order book entries to return
|
|
160
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
161
|
-
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
162
|
-
*/
|
|
163
|
-
//
|
|
164
|
-
// todo add support for <levels>-snapshots (depth)
|
|
165
|
-
// https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#partial-book-depth-streams // <symbol>@depth<levels>@100ms or <symbol>@depth<levels> (1000ms)
|
|
166
|
-
// valid <levels> are 5, 10, or 20
|
|
167
|
-
//
|
|
168
|
-
// default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
|
|
169
|
-
//
|
|
170
|
-
// notice the differences between trading futures and spot trading
|
|
171
|
-
// the algorithms use different urls in step 1
|
|
172
|
-
// delta caching and merging also differs in steps 4, 5, 6
|
|
173
|
-
//
|
|
174
|
-
// spot/margin
|
|
175
|
-
// https://binance-docs.github.io/apidocs/spot/en/#how-to-manage-a-local-order-book-correctly
|
|
176
|
-
//
|
|
177
|
-
// 1. Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth.
|
|
178
|
-
// 2. Buffer the events you receive from the stream.
|
|
179
|
-
// 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
|
|
180
|
-
// 4. Drop any event where u is <= lastUpdateId in the snapshot.
|
|
181
|
-
// 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1.
|
|
182
|
-
// 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
|
|
183
|
-
// 7. The data in each event is the absolute quantity for a price level.
|
|
184
|
-
// 8. If the quantity is 0, remove the price level.
|
|
185
|
-
// 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
|
|
186
|
-
//
|
|
187
|
-
// futures
|
|
188
|
-
// https://binance-docs.github.io/apidocs/futures/en/#how-to-manage-a-local-order-book-correctly
|
|
189
|
-
//
|
|
190
|
-
// 1. Open a stream to wss://fstream.binance.com/stream?streams=btcusdt@depth.
|
|
191
|
-
// 2. Buffer the events you receive from the stream. For same price, latest received update covers the previous one.
|
|
192
|
-
// 3. Get a depth snapshot from https://fapi.binance.com/fapi/v1/depth?symbol=BTCUSDT&limit=1000 .
|
|
193
|
-
// 4. Drop any event where u is < lastUpdateId in the snapshot.
|
|
194
|
-
// 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
|
|
195
|
-
// 6. While listening to the stream, each new event's pu should be equal to the previous event's u, otherwise initialize the process from step 3.
|
|
196
|
-
// 7. The data in each event is the absolute quantity for a price level.
|
|
197
|
-
// 8. If the quantity is 0, remove the price level.
|
|
198
|
-
// 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
|
|
199
|
-
//
|
|
200
|
-
return await this.watchOrderBookForSymbols([symbol], limit, params);
|
|
201
|
-
}
|
|
202
|
-
async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
|
|
203
|
-
/**
|
|
204
|
-
* @method
|
|
205
|
-
* @name binance#watchOrderBookForSymbols
|
|
206
|
-
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
207
|
-
* @param {string[]} symbols unified array of symbols
|
|
208
|
-
* @param {int} [limit] the maximum amount of order book entries to return
|
|
209
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
210
|
-
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
211
|
-
*/
|
|
212
|
-
await this.loadMarkets();
|
|
213
|
-
symbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
214
|
-
const firstMarket = this.market(symbols[0]);
|
|
215
|
-
let type = firstMarket['type'];
|
|
216
|
-
if (firstMarket['contract']) {
|
|
217
|
-
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
218
|
-
}
|
|
219
|
-
const name = 'depth';
|
|
220
|
-
let streamHash = 'multipleOrderbook';
|
|
221
|
-
if (symbols !== undefined) {
|
|
222
|
-
const symbolsLength = symbols.length;
|
|
223
|
-
if (symbolsLength > 200) {
|
|
224
|
-
throw new errors.BadRequest(this.id + ' watchOrderBookForSymbols() accepts 200 symbols at most. To watch more symbols call watchOrderBookForSymbols() multiple times');
|
|
225
|
-
}
|
|
226
|
-
streamHash += '::' + symbols.join(',');
|
|
227
|
-
}
|
|
228
|
-
const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
|
|
229
|
-
const subParams = [];
|
|
230
|
-
const messageHashes = [];
|
|
231
|
-
for (let i = 0; i < symbols.length; i++) {
|
|
232
|
-
const symbol = symbols[i];
|
|
233
|
-
const market = this.market(symbol);
|
|
234
|
-
const messageHash = market['lowercaseId'] + '@' + name;
|
|
235
|
-
messageHashes.push(messageHash);
|
|
236
|
-
const symbolHash = messageHash + '@' + watchOrderBookRate + 'ms';
|
|
237
|
-
subParams.push(symbolHash);
|
|
238
|
-
}
|
|
239
|
-
const messageHashesLength = messageHashes.length;
|
|
240
|
-
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, messageHashesLength);
|
|
241
|
-
const requestId = this.requestId(url);
|
|
242
|
-
const request = {
|
|
243
|
-
'method': 'SUBSCRIBE',
|
|
244
|
-
'params': subParams,
|
|
245
|
-
'id': requestId,
|
|
246
|
-
};
|
|
247
|
-
const subscription = {
|
|
248
|
-
'id': requestId.toString(),
|
|
249
|
-
'name': name,
|
|
250
|
-
'symbols': symbols,
|
|
251
|
-
'method': this.handleOrderBookSubscription,
|
|
252
|
-
'limit': limit,
|
|
253
|
-
'type': type,
|
|
254
|
-
'params': params,
|
|
255
|
-
};
|
|
256
|
-
const message = this.extend(request, params);
|
|
257
|
-
const orderbook = await this.watchMultiple(url, messageHashes, message, messageHashes, subscription);
|
|
258
|
-
return orderbook.limit();
|
|
259
|
-
}
|
|
260
|
-
async fetchOrderBookSnapshot(client, message, subscription) {
|
|
261
|
-
const name = this.safeString(subscription, 'name');
|
|
262
|
-
const symbol = this.safeString(subscription, 'symbol');
|
|
263
|
-
const market = this.market(symbol);
|
|
264
|
-
const messageHash = market['lowercaseId'] + '@' + name;
|
|
265
|
-
try {
|
|
266
|
-
const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
|
|
267
|
-
const type = this.safeValue(subscription, 'type');
|
|
268
|
-
const limit = this.safeInteger(subscription, 'limit', defaultLimit);
|
|
269
|
-
const params = this.safeValue(subscription, 'params');
|
|
270
|
-
// 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
|
|
271
|
-
// todo: this is a synch blocking call - make it async
|
|
272
|
-
// default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
|
|
273
|
-
const snapshot = await this.fetchRestOrderBookSafe(symbol, limit, params);
|
|
274
|
-
const orderbook = this.safeValue(this.orderbooks, symbol);
|
|
275
|
-
if (orderbook === undefined) {
|
|
276
|
-
// if the orderbook is dropped before the snapshot is received
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
orderbook.reset(snapshot);
|
|
280
|
-
// unroll the accumulated deltas
|
|
281
|
-
const messages = orderbook.cache;
|
|
282
|
-
for (let i = 0; i < messages.length; i++) {
|
|
283
|
-
const messageItem = messages[i];
|
|
284
|
-
const U = this.safeInteger(messageItem, 'U');
|
|
285
|
-
const u = this.safeInteger(messageItem, 'u');
|
|
286
|
-
const pu = this.safeInteger(messageItem, 'pu');
|
|
287
|
-
if (type === 'future') {
|
|
288
|
-
// 4. Drop any event where u is < lastUpdateId in the snapshot
|
|
289
|
-
if (u < orderbook['nonce']) {
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
// 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
|
|
293
|
-
if ((U <= orderbook['nonce']) && (u >= orderbook['nonce']) || (pu === orderbook['nonce'])) {
|
|
294
|
-
this.handleOrderBookMessage(client, messageItem, orderbook);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
// 4. Drop any event where u is <= lastUpdateId in the snapshot
|
|
299
|
-
if (u <= orderbook['nonce']) {
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
// 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
|
|
303
|
-
if (((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce'])) {
|
|
304
|
-
this.handleOrderBookMessage(client, messageItem, orderbook);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
this.orderbooks[symbol] = orderbook;
|
|
309
|
-
client.resolve(orderbook, messageHash);
|
|
310
|
-
}
|
|
311
|
-
catch (e) {
|
|
312
|
-
delete client.subscriptions[messageHash];
|
|
313
|
-
client.reject(e, messageHash);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
handleDelta(bookside, delta) {
|
|
317
|
-
const price = this.safeFloat(delta, 0);
|
|
318
|
-
const amount = this.safeFloat(delta, 1);
|
|
319
|
-
bookside.store(price, amount);
|
|
320
|
-
}
|
|
321
|
-
handleDeltas(bookside, deltas) {
|
|
322
|
-
for (let i = 0; i < deltas.length; i++) {
|
|
323
|
-
this.handleDelta(bookside, deltas[i]);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
handleOrderBookMessage(client, message, orderbook) {
|
|
327
|
-
const u = this.safeInteger(message, 'u');
|
|
328
|
-
this.handleDeltas(orderbook['asks'], this.safeValue(message, 'a', []));
|
|
329
|
-
this.handleDeltas(orderbook['bids'], this.safeValue(message, 'b', []));
|
|
330
|
-
orderbook['nonce'] = u;
|
|
331
|
-
const timestamp = this.safeInteger(message, 'E');
|
|
332
|
-
orderbook['timestamp'] = timestamp;
|
|
333
|
-
orderbook['datetime'] = this.iso8601(timestamp);
|
|
334
|
-
return orderbook;
|
|
335
|
-
}
|
|
336
|
-
handleOrderBook(client, message) {
|
|
337
|
-
//
|
|
338
|
-
// initial snapshot is fetched with ccxt's fetchOrderBook
|
|
339
|
-
// the feed does not include a snapshot, just the deltas
|
|
340
|
-
//
|
|
341
|
-
// {
|
|
342
|
-
// "e": "depthUpdate", // Event type
|
|
343
|
-
// "E": 1577554482280, // Event time
|
|
344
|
-
// "s": "BNBBTC", // Symbol
|
|
345
|
-
// "U": 157, // First update ID in event
|
|
346
|
-
// "u": 160, // Final update ID in event
|
|
347
|
-
// "b": [ // bids
|
|
348
|
-
// [ "0.0024", "10" ], // price, size
|
|
349
|
-
// ],
|
|
350
|
-
// "a": [ // asks
|
|
351
|
-
// [ "0.0026", "100" ], // price, size
|
|
352
|
-
// ]
|
|
353
|
-
// }
|
|
354
|
-
//
|
|
355
|
-
const isTestnetSpot = client.url.indexOf('testnet') > 0;
|
|
356
|
-
const isSpotMainNet = client.url.indexOf('/stream.binance.') > 0;
|
|
357
|
-
const isSpot = isTestnetSpot || isSpotMainNet;
|
|
358
|
-
const marketType = isSpot ? 'spot' : 'contract';
|
|
359
|
-
const marketId = this.safeString(message, 's');
|
|
360
|
-
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
361
|
-
const symbol = market['symbol'];
|
|
362
|
-
const name = 'depth';
|
|
363
|
-
const messageHash = market['lowercaseId'] + '@' + name;
|
|
364
|
-
const orderbook = this.safeValue(this.orderbooks, symbol);
|
|
365
|
-
if (orderbook === undefined) {
|
|
366
|
-
//
|
|
367
|
-
// https://github.com/ccxt/ccxt/issues/6672
|
|
368
|
-
//
|
|
369
|
-
// Sometimes Binance sends the first delta before the subscription
|
|
370
|
-
// confirmation arrives. At that point the orderbook is not
|
|
371
|
-
// initialized yet and the snapshot has not been requested yet
|
|
372
|
-
// therefore it is safe to drop these premature messages.
|
|
373
|
-
//
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
const nonce = this.safeInteger(orderbook, 'nonce');
|
|
377
|
-
if (nonce === undefined) {
|
|
378
|
-
// 2. Buffer the events you receive from the stream.
|
|
379
|
-
orderbook.cache.push(message);
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
try {
|
|
383
|
-
const U = this.safeInteger(message, 'U');
|
|
384
|
-
const u = this.safeInteger(message, 'u');
|
|
385
|
-
const pu = this.safeInteger(message, 'pu');
|
|
386
|
-
if (pu === undefined) {
|
|
387
|
-
// spot
|
|
388
|
-
// 4. Drop any event where u is <= lastUpdateId in the snapshot
|
|
389
|
-
if (u > orderbook['nonce']) {
|
|
390
|
-
const timestamp = this.safeInteger(orderbook, 'timestamp');
|
|
391
|
-
let conditional = undefined;
|
|
392
|
-
if (timestamp === undefined) {
|
|
393
|
-
// 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
|
|
394
|
-
conditional = ((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce']);
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
// 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
|
|
398
|
-
conditional = ((U - 1) === orderbook['nonce']);
|
|
399
|
-
}
|
|
400
|
-
if (conditional) {
|
|
401
|
-
this.handleOrderBookMessage(client, message, orderbook);
|
|
402
|
-
if (nonce < orderbook['nonce']) {
|
|
403
|
-
client.resolve(orderbook, messageHash);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
// todo: client.reject from handleOrderBookMessage properly
|
|
408
|
-
throw new errors.ExchangeError(this.id + ' handleOrderBook received an out-of-order nonce');
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
// future
|
|
414
|
-
// 4. Drop any event where u is < lastUpdateId in the snapshot
|
|
415
|
-
if (u >= orderbook['nonce']) {
|
|
416
|
-
// 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
|
|
417
|
-
// 6. While listening to the stream, each new event's pu should be equal to the previous event's u, otherwise initialize the process from step 3
|
|
418
|
-
if ((U <= orderbook['nonce']) || (pu === orderbook['nonce'])) {
|
|
419
|
-
this.handleOrderBookMessage(client, message, orderbook);
|
|
420
|
-
if (nonce <= orderbook['nonce']) {
|
|
421
|
-
client.resolve(orderbook, messageHash);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
// todo: client.reject from handleOrderBookMessage properly
|
|
426
|
-
throw new errors.ExchangeError(this.id + ' handleOrderBook received an out-of-order nonce');
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
catch (e) {
|
|
432
|
-
delete this.orderbooks[symbol];
|
|
433
|
-
delete client.subscriptions[messageHash];
|
|
434
|
-
client.reject(e, messageHash);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
handleOrderBookSubscription(client, message, subscription) {
|
|
439
|
-
const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
|
|
440
|
-
// const messageHash = this.safeString (subscription, 'messageHash');
|
|
441
|
-
const symbolOfSubscription = this.safeString(subscription, 'symbol'); // watchOrderBook
|
|
442
|
-
const symbols = this.safeValue(subscription, 'symbols', [symbolOfSubscription]); // watchOrderBookForSymbols
|
|
443
|
-
const limit = this.safeInteger(subscription, 'limit', defaultLimit);
|
|
444
|
-
// handle list of symbols
|
|
445
|
-
for (let i = 0; i < symbols.length; i++) {
|
|
446
|
-
const symbol = symbols[i];
|
|
447
|
-
if (symbol in this.orderbooks) {
|
|
448
|
-
delete this.orderbooks[symbol];
|
|
449
|
-
}
|
|
450
|
-
this.orderbooks[symbol] = this.orderBook({}, limit);
|
|
451
|
-
subscription = this.extend(subscription, { 'symbol': symbol });
|
|
452
|
-
// fetch the snapshot in a separate async call
|
|
453
|
-
this.spawn(this.fetchOrderBookSnapshot, client, message, subscription);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
handleSubscriptionStatus(client, message) {
|
|
457
|
-
//
|
|
458
|
-
// {
|
|
459
|
-
// "result": null,
|
|
460
|
-
// "id": 1574649734450
|
|
461
|
-
// }
|
|
462
|
-
//
|
|
463
|
-
const id = this.safeString(message, 'id');
|
|
464
|
-
const subscriptionsById = this.indexBy(client.subscriptions, 'id');
|
|
465
|
-
const subscription = this.safeValue(subscriptionsById, id, {});
|
|
466
|
-
const method = this.safeValue(subscription, 'method');
|
|
467
|
-
if (method !== undefined) {
|
|
468
|
-
method.call(this, client, message, subscription);
|
|
469
|
-
}
|
|
470
|
-
return message;
|
|
471
|
-
}
|
|
472
|
-
async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
|
|
473
|
-
/**
|
|
474
|
-
* @method
|
|
475
|
-
* @name binance#watchTradesForSymbols
|
|
476
|
-
* @description get the list of most recent trades for a list of symbols
|
|
477
|
-
* @param {string[]} symbols unified symbol of the market to fetch trades for
|
|
478
|
-
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
479
|
-
* @param {int} [limit] the maximum amount of trades to fetch
|
|
480
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
481
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
482
|
-
*/
|
|
483
|
-
await this.loadMarkets();
|
|
484
|
-
symbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
485
|
-
let streamHash = 'multipleTrades';
|
|
486
|
-
if (symbols !== undefined) {
|
|
487
|
-
const symbolsLength = symbols.length;
|
|
488
|
-
if (symbolsLength > 200) {
|
|
489
|
-
throw new errors.BadRequest(this.id + ' watchTradesForSymbols() accepts 200 symbols at most. To watch more symbols call watchTradesForSymbols() multiple times');
|
|
490
|
-
}
|
|
491
|
-
streamHash += '::' + symbols.join(',');
|
|
492
|
-
}
|
|
493
|
-
const options = this.safeValue(this.options, 'watchTradesForSymbols', {});
|
|
494
|
-
const name = this.safeString(options, 'name', 'trade');
|
|
495
|
-
const firstMarket = this.market(symbols[0]);
|
|
496
|
-
let type = firstMarket['type'];
|
|
497
|
-
if (firstMarket['contract']) {
|
|
498
|
-
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
499
|
-
}
|
|
500
|
-
const subParams = [];
|
|
501
|
-
for (let i = 0; i < symbols.length; i++) {
|
|
502
|
-
const symbol = symbols[i];
|
|
503
|
-
const market = this.market(symbol);
|
|
504
|
-
const currentMessageHash = market['lowercaseId'] + '@' + name;
|
|
505
|
-
subParams.push(currentMessageHash);
|
|
506
|
-
}
|
|
507
|
-
const query = this.omit(params, 'type');
|
|
508
|
-
const subParamsLength = subParams.length;
|
|
509
|
-
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, subParamsLength);
|
|
510
|
-
const requestId = this.requestId(url);
|
|
511
|
-
const request = {
|
|
512
|
-
'method': 'SUBSCRIBE',
|
|
513
|
-
'params': subParams,
|
|
514
|
-
'id': requestId,
|
|
515
|
-
};
|
|
516
|
-
const subscribe = {
|
|
517
|
-
'id': requestId,
|
|
518
|
-
};
|
|
519
|
-
const trades = await this.watchMultiple(url, subParams, this.extend(request, query), subParams, subscribe);
|
|
520
|
-
if (this.newUpdates) {
|
|
521
|
-
const first = this.safeValue(trades, 0);
|
|
522
|
-
const tradeSymbol = this.safeString(first, 'symbol');
|
|
523
|
-
limit = trades.getLimit(tradeSymbol, limit);
|
|
524
|
-
}
|
|
525
|
-
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
526
|
-
}
|
|
527
|
-
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
528
|
-
/**
|
|
529
|
-
* @method
|
|
530
|
-
* @name binance#watchTrades
|
|
531
|
-
* @description get the list of most recent trades for a particular symbol
|
|
532
|
-
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
533
|
-
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
534
|
-
* @param {int} [limit] the maximum amount of trades to fetch
|
|
535
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
536
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
537
|
-
*/
|
|
538
|
-
return await this.watchTradesForSymbols([symbol], since, limit, params);
|
|
539
|
-
}
|
|
540
|
-
parseTrade(trade, market = undefined) {
|
|
541
|
-
//
|
|
542
|
-
// public watchTrades
|
|
543
|
-
//
|
|
544
|
-
// {
|
|
545
|
-
// "e": "trade", // event type
|
|
546
|
-
// "E": 1579481530911, // event time
|
|
547
|
-
// "s": "ETHBTC", // symbol
|
|
548
|
-
// "t": 158410082, // trade id
|
|
549
|
-
// "p": "0.01914100", // price
|
|
550
|
-
// "q": "0.00700000", // quantity
|
|
551
|
-
// "b": 586187049, // buyer order id
|
|
552
|
-
// "a": 586186710, // seller order id
|
|
553
|
-
// "T": 1579481530910, // trade time
|
|
554
|
-
// "m": false, // is the buyer the market maker
|
|
555
|
-
// "M": true // binance docs say it should be ignored
|
|
556
|
-
// }
|
|
557
|
-
//
|
|
558
|
-
// {
|
|
559
|
-
// "e": "aggTrade", // Event type
|
|
560
|
-
// "E": 123456789, // Event time
|
|
561
|
-
// "s": "BNBBTC", // Symbol
|
|
562
|
-
// "a": 12345, // Aggregate trade ID
|
|
563
|
-
// "p": "0.001", // Price
|
|
564
|
-
// "q": "100", // Quantity
|
|
565
|
-
// "f": 100, // First trade ID
|
|
566
|
-
// "l": 105, // Last trade ID
|
|
567
|
-
// "T": 123456785, // Trade time
|
|
568
|
-
// "m": true, // Is the buyer the market maker?
|
|
569
|
-
// "M": true // Ignore
|
|
570
|
-
// }
|
|
571
|
-
//
|
|
572
|
-
// private watchMyTrades spot
|
|
573
|
-
//
|
|
574
|
-
// {
|
|
575
|
-
// "e": "executionReport",
|
|
576
|
-
// "E": 1611063861489,
|
|
577
|
-
// "s": "BNBUSDT",
|
|
578
|
-
// "c": "m4M6AD5MF3b1ERe65l4SPq",
|
|
579
|
-
// "S": "BUY",
|
|
580
|
-
// "o": "MARKET",
|
|
581
|
-
// "f": "GTC",
|
|
582
|
-
// "q": "2.00000000",
|
|
583
|
-
// "p": "0.00000000",
|
|
584
|
-
// "P": "0.00000000",
|
|
585
|
-
// "F": "0.00000000",
|
|
586
|
-
// "g": -1,
|
|
587
|
-
// "C": '',
|
|
588
|
-
// "x": "TRADE",
|
|
589
|
-
// "X": "PARTIALLY_FILLED",
|
|
590
|
-
// "r": "NONE",
|
|
591
|
-
// "i": 1296882607,
|
|
592
|
-
// "l": "0.33200000",
|
|
593
|
-
// "z": "0.33200000",
|
|
594
|
-
// "L": "46.86600000",
|
|
595
|
-
// "n": "0.00033200",
|
|
596
|
-
// "N": "BNB",
|
|
597
|
-
// "T": 1611063861488,
|
|
598
|
-
// "t": 109747654,
|
|
599
|
-
// "I": 2696953381,
|
|
600
|
-
// "w": false,
|
|
601
|
-
// "m": false,
|
|
602
|
-
// "M": true,
|
|
603
|
-
// "O": 1611063861488,
|
|
604
|
-
// "Z": "15.55951200",
|
|
605
|
-
// "Y": "15.55951200",
|
|
606
|
-
// "Q": "0.00000000"
|
|
607
|
-
// }
|
|
608
|
-
//
|
|
609
|
-
// private watchMyTrades future/delivery
|
|
610
|
-
//
|
|
611
|
-
// {
|
|
612
|
-
// "s": "BTCUSDT",
|
|
613
|
-
// "c": "pb2jD6ZQHpfzSdUac8VqMK",
|
|
614
|
-
// "S": "SELL",
|
|
615
|
-
// "o": "MARKET",
|
|
616
|
-
// "f": "GTC",
|
|
617
|
-
// "q": "0.001",
|
|
618
|
-
// "p": "0",
|
|
619
|
-
// "ap": "33468.46000",
|
|
620
|
-
// "sp": "0",
|
|
621
|
-
// "x": "TRADE",
|
|
622
|
-
// "X": "FILLED",
|
|
623
|
-
// "i": 13351197194,
|
|
624
|
-
// "l": "0.001",
|
|
625
|
-
// "z": "0.001",
|
|
626
|
-
// "L": "33468.46",
|
|
627
|
-
// "n": "0.00027086",
|
|
628
|
-
// "N": "BNB",
|
|
629
|
-
// "T": 1612095165362,
|
|
630
|
-
// "t": 458032604,
|
|
631
|
-
// "b": "0",
|
|
632
|
-
// "a": "0",
|
|
633
|
-
// "m": false,
|
|
634
|
-
// "R": false,
|
|
635
|
-
// "wt": "CONTRACT_PRICE",
|
|
636
|
-
// "ot": "MARKET",
|
|
637
|
-
// "ps": "BOTH",
|
|
638
|
-
// "cp": false,
|
|
639
|
-
// "rp": "0.00335000",
|
|
640
|
-
// "pP": false,
|
|
641
|
-
// "si": 0,
|
|
642
|
-
// "ss": 0
|
|
643
|
-
// }
|
|
644
|
-
//
|
|
645
|
-
const executionType = this.safeString(trade, 'x');
|
|
646
|
-
const isTradeExecution = (executionType === 'TRADE');
|
|
647
|
-
if (!isTradeExecution) {
|
|
648
|
-
return super.parseTrade(trade, market);
|
|
649
|
-
}
|
|
650
|
-
const id = this.safeString2(trade, 't', 'a');
|
|
651
|
-
const timestamp = this.safeInteger(trade, 'T');
|
|
652
|
-
const price = this.safeString2(trade, 'L', 'p');
|
|
653
|
-
let amount = this.safeString(trade, 'q');
|
|
654
|
-
if (isTradeExecution) {
|
|
655
|
-
amount = this.safeString(trade, 'l', amount);
|
|
656
|
-
}
|
|
657
|
-
let cost = this.safeString(trade, 'Y');
|
|
658
|
-
if (cost === undefined) {
|
|
659
|
-
if ((price !== undefined) && (amount !== undefined)) {
|
|
660
|
-
cost = Precise["default"].stringMul(price, amount);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
const marketId = this.safeString(trade, 's');
|
|
664
|
-
const marketType = ('ps' in trade) ? 'contract' : 'spot';
|
|
665
|
-
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
666
|
-
let side = this.safeStringLower(trade, 'S');
|
|
667
|
-
let takerOrMaker = undefined;
|
|
668
|
-
const orderId = this.safeString(trade, 'i');
|
|
669
|
-
if ('m' in trade) {
|
|
670
|
-
if (side === undefined) {
|
|
671
|
-
side = trade['m'] ? 'sell' : 'buy'; // this is reversed intentionally
|
|
672
|
-
}
|
|
673
|
-
takerOrMaker = trade['m'] ? 'maker' : 'taker';
|
|
674
|
-
}
|
|
675
|
-
let fee = undefined;
|
|
676
|
-
const feeCost = this.safeString(trade, 'n');
|
|
677
|
-
if (feeCost !== undefined) {
|
|
678
|
-
const feeCurrencyId = this.safeString(trade, 'N');
|
|
679
|
-
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
680
|
-
fee = {
|
|
681
|
-
'cost': feeCost,
|
|
682
|
-
'currency': feeCurrencyCode,
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
const type = this.safeStringLower(trade, 'o');
|
|
686
|
-
return this.safeTrade({
|
|
687
|
-
'info': trade,
|
|
688
|
-
'timestamp': timestamp,
|
|
689
|
-
'datetime': this.iso8601(timestamp),
|
|
690
|
-
'symbol': symbol,
|
|
691
|
-
'id': id,
|
|
692
|
-
'order': orderId,
|
|
693
|
-
'type': type,
|
|
694
|
-
'takerOrMaker': takerOrMaker,
|
|
695
|
-
'side': side,
|
|
696
|
-
'price': price,
|
|
697
|
-
'amount': amount,
|
|
698
|
-
'cost': cost,
|
|
699
|
-
'fee': fee,
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
handleTrade(client, message) {
|
|
703
|
-
// the trade streams push raw trade information in real-time
|
|
704
|
-
// each trade has a unique buyer and seller
|
|
705
|
-
const isSpot = ((client.url.indexOf('wss://stream.binance.com') > -1) || (client.url.indexOf('/testnet.binance') > -1));
|
|
706
|
-
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
707
|
-
const marketId = this.safeString(message, 's');
|
|
708
|
-
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
709
|
-
const symbol = market['symbol'];
|
|
710
|
-
const lowerCaseId = this.safeStringLower(message, 's');
|
|
711
|
-
const event = this.safeString(message, 'e');
|
|
712
|
-
const messageHash = lowerCaseId + '@' + event;
|
|
713
|
-
const trade = this.parseTrade(message, market);
|
|
714
|
-
let tradesArray = this.safeValue(this.trades, symbol);
|
|
715
|
-
if (tradesArray === undefined) {
|
|
716
|
-
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
717
|
-
tradesArray = new Cache.ArrayCache(limit);
|
|
718
|
-
}
|
|
719
|
-
tradesArray.append(trade);
|
|
720
|
-
this.trades[symbol] = tradesArray;
|
|
721
|
-
client.resolve(tradesArray, messageHash);
|
|
722
|
-
}
|
|
723
|
-
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
724
|
-
/**
|
|
725
|
-
* @method
|
|
726
|
-
* @name binance#watchOHLCV
|
|
727
|
-
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
728
|
-
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
729
|
-
* @param {string} timeframe the length of time each candle represents
|
|
730
|
-
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
731
|
-
* @param {int} [limit] the maximum amount of candles to fetch
|
|
732
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
733
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
734
|
-
*/
|
|
735
|
-
await this.loadMarkets();
|
|
736
|
-
const market = this.market(symbol);
|
|
737
|
-
let marketId = market['lowercaseId'];
|
|
738
|
-
const interval = this.safeString(this.timeframes, timeframe, timeframe);
|
|
739
|
-
const options = this.safeValue(this.options, 'watchOHLCV', {});
|
|
740
|
-
const nameOption = this.safeString(options, 'name', 'kline');
|
|
741
|
-
const name = this.safeString(params, 'name', nameOption);
|
|
742
|
-
if (name === 'indexPriceKline') {
|
|
743
|
-
marketId = marketId.replace('_perp', '');
|
|
744
|
-
// weird behavior for index price kline we can't use the perp suffix
|
|
745
|
-
}
|
|
746
|
-
params = this.omit(params, 'name');
|
|
747
|
-
const messageHash = marketId + '@' + name + '_' + interval;
|
|
748
|
-
let type = market['type'];
|
|
749
|
-
if (market['contract']) {
|
|
750
|
-
type = market['linear'] ? 'future' : 'delivery';
|
|
751
|
-
}
|
|
752
|
-
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
|
|
753
|
-
const requestId = this.requestId(url);
|
|
754
|
-
const request = {
|
|
755
|
-
'method': 'SUBSCRIBE',
|
|
756
|
-
'params': [
|
|
757
|
-
messageHash,
|
|
758
|
-
],
|
|
759
|
-
'id': requestId,
|
|
760
|
-
};
|
|
761
|
-
const subscribe = {
|
|
762
|
-
'id': requestId,
|
|
763
|
-
};
|
|
764
|
-
const ohlcv = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
|
|
765
|
-
if (this.newUpdates) {
|
|
766
|
-
limit = ohlcv.getLimit(symbol, limit);
|
|
767
|
-
}
|
|
768
|
-
return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
|
|
769
|
-
}
|
|
770
|
-
handleOHLCV(client, message) {
|
|
771
|
-
//
|
|
772
|
-
// {
|
|
773
|
-
// "e": "kline",
|
|
774
|
-
// "E": 1579482921215,
|
|
775
|
-
// "s": "ETHBTC",
|
|
776
|
-
// "k": {
|
|
777
|
-
// "t": 1579482900000,
|
|
778
|
-
// "T": 1579482959999,
|
|
779
|
-
// "s": "ETHBTC",
|
|
780
|
-
// "i": "1m",
|
|
781
|
-
// "f": 158411535,
|
|
782
|
-
// "L": 158411550,
|
|
783
|
-
// "o": "0.01913200",
|
|
784
|
-
// "c": "0.01913500",
|
|
785
|
-
// "h": "0.01913700",
|
|
786
|
-
// "l": "0.01913200",
|
|
787
|
-
// "v": "5.08400000",
|
|
788
|
-
// "n": 16,
|
|
789
|
-
// "x": false,
|
|
790
|
-
// "q": "0.09728060",
|
|
791
|
-
// "V": "3.30200000",
|
|
792
|
-
// "Q": "0.06318500",
|
|
793
|
-
// "B": "0"
|
|
794
|
-
// }
|
|
795
|
-
// }
|
|
796
|
-
//
|
|
797
|
-
let event = this.safeString(message, 'e');
|
|
798
|
-
const eventMap = {
|
|
799
|
-
'indexPrice_kline': 'indexPriceKline',
|
|
800
|
-
'markPrice_kline': 'markPriceKline',
|
|
801
|
-
};
|
|
802
|
-
event = this.safeString(eventMap, event, event);
|
|
803
|
-
const kline = this.safeValue(message, 'k');
|
|
804
|
-
let marketId = this.safeString2(kline, 's', 'ps');
|
|
805
|
-
if (event === 'indexPriceKline') {
|
|
806
|
-
// indexPriceKline doesn't have the _PERP suffix
|
|
807
|
-
marketId = this.safeString(message, 'ps');
|
|
808
|
-
}
|
|
809
|
-
const lowercaseMarketId = marketId.toLowerCase();
|
|
810
|
-
const interval = this.safeString(kline, 'i');
|
|
811
|
-
// use a reverse lookup in a static map instead
|
|
812
|
-
const timeframe = this.findTimeframe(interval);
|
|
813
|
-
const messageHash = lowercaseMarketId + '@' + event + '_' + interval;
|
|
814
|
-
const parsed = [
|
|
815
|
-
this.safeInteger(kline, 't'),
|
|
816
|
-
this.safeFloat(kline, 'o'),
|
|
817
|
-
this.safeFloat(kline, 'h'),
|
|
818
|
-
this.safeFloat(kline, 'l'),
|
|
819
|
-
this.safeFloat(kline, 'c'),
|
|
820
|
-
this.safeFloat(kline, 'v'),
|
|
821
|
-
];
|
|
822
|
-
const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
|
|
823
|
-
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
824
|
-
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
825
|
-
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
|
|
826
|
-
let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
|
|
827
|
-
if (stored === undefined) {
|
|
828
|
-
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
829
|
-
stored = new Cache.ArrayCacheByTimestamp(limit);
|
|
830
|
-
this.ohlcvs[symbol][timeframe] = stored;
|
|
831
|
-
}
|
|
832
|
-
stored.append(parsed);
|
|
833
|
-
client.resolve(stored, messageHash);
|
|
834
|
-
}
|
|
835
|
-
async watchTicker(symbol, params = {}) {
|
|
836
|
-
/**
|
|
837
|
-
* @method
|
|
838
|
-
* @name binance#watchTicker
|
|
839
|
-
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
840
|
-
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
841
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
842
|
-
* @param {string} [params.name] stream to use can be ticker or bookTicker
|
|
843
|
-
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
844
|
-
*/
|
|
845
|
-
await this.loadMarkets();
|
|
846
|
-
const market = this.market(symbol);
|
|
847
|
-
const marketId = market['lowercaseId'];
|
|
848
|
-
let type = market['type'];
|
|
849
|
-
if (market['contract']) {
|
|
850
|
-
type = market['linear'] ? 'future' : 'delivery';
|
|
851
|
-
}
|
|
852
|
-
const options = this.safeValue(this.options, 'watchTicker', {});
|
|
853
|
-
let name = this.safeString(options, 'name', 'ticker');
|
|
854
|
-
name = this.safeString(params, 'name', name);
|
|
855
|
-
params = this.omit(params, 'name');
|
|
856
|
-
const messageHash = marketId + '@' + name;
|
|
857
|
-
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
|
|
858
|
-
const requestId = this.requestId(url);
|
|
859
|
-
const request = {
|
|
860
|
-
'method': 'SUBSCRIBE',
|
|
861
|
-
'params': [
|
|
862
|
-
messageHash,
|
|
863
|
-
],
|
|
864
|
-
'id': requestId,
|
|
865
|
-
};
|
|
866
|
-
const subscribe = {
|
|
867
|
-
'id': requestId,
|
|
868
|
-
};
|
|
869
|
-
return await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
|
|
870
|
-
}
|
|
871
|
-
async watchTickers(symbols = undefined, params = {}) {
|
|
872
|
-
/**
|
|
873
|
-
* @method
|
|
874
|
-
* @name binance#watchTickers
|
|
875
|
-
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
876
|
-
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
877
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
878
|
-
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
879
|
-
*/
|
|
880
|
-
await this.loadMarkets();
|
|
881
|
-
symbols = this.marketSymbols(symbols, undefined, true, true, true);
|
|
882
|
-
const marketIds = this.marketIds(symbols);
|
|
883
|
-
let market = undefined;
|
|
884
|
-
let type = undefined;
|
|
885
|
-
if (symbols !== undefined) {
|
|
886
|
-
market = this.market(symbols[0]);
|
|
887
|
-
}
|
|
888
|
-
[type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
|
|
889
|
-
let subType = undefined;
|
|
890
|
-
[subType, params] = this.handleSubTypeAndParams('watchTickers', market, params);
|
|
891
|
-
if (this.isLinear(type, subType)) {
|
|
892
|
-
type = 'future';
|
|
893
|
-
}
|
|
894
|
-
else if (this.isInverse(type, subType)) {
|
|
895
|
-
type = 'delivery';
|
|
896
|
-
}
|
|
897
|
-
const options = this.safeValue(this.options, 'watchTickers', {});
|
|
898
|
-
let name = this.safeString(options, 'name', 'ticker');
|
|
899
|
-
name = this.safeString(params, 'name', name);
|
|
900
|
-
params = this.omit(params, 'name');
|
|
901
|
-
let wsParams = [];
|
|
902
|
-
let messageHash = 'tickers';
|
|
903
|
-
if (symbols !== undefined) {
|
|
904
|
-
messageHash = 'tickers::' + symbols.join(',');
|
|
905
|
-
}
|
|
906
|
-
if (name === 'bookTicker') {
|
|
907
|
-
if (marketIds === undefined) {
|
|
908
|
-
throw new errors.ArgumentsRequired(this.id + ' watchTickers() requires symbols for bookTicker');
|
|
909
|
-
}
|
|
910
|
-
// simulate watchTickers with subscribe multiple individual bookTicker topic
|
|
911
|
-
for (let i = 0; i < marketIds.length; i++) {
|
|
912
|
-
wsParams.push(marketIds[i].toLowerCase() + '@bookTicker');
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
else {
|
|
916
|
-
wsParams = [
|
|
917
|
-
'!' + name + '@arr',
|
|
918
|
-
];
|
|
919
|
-
}
|
|
920
|
-
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
|
|
921
|
-
const requestId = this.requestId(url);
|
|
922
|
-
const request = {
|
|
923
|
-
'method': 'SUBSCRIBE',
|
|
924
|
-
'params': wsParams,
|
|
925
|
-
'id': requestId,
|
|
926
|
-
};
|
|
927
|
-
const subscribe = {
|
|
928
|
-
'id': requestId,
|
|
929
|
-
};
|
|
930
|
-
const newTickers = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
|
|
931
|
-
if (this.newUpdates) {
|
|
932
|
-
return newTickers;
|
|
933
|
-
}
|
|
934
|
-
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
935
|
-
}
|
|
936
|
-
parseWsTicker(message, marketType) {
|
|
937
|
-
//
|
|
938
|
-
// ticker
|
|
939
|
-
// {
|
|
940
|
-
// "e": "24hrTicker", // event type
|
|
941
|
-
// "E": 1579485598569, // event time
|
|
942
|
-
// "s": "ETHBTC", // symbol
|
|
943
|
-
// "p": "-0.00004000", // price change
|
|
944
|
-
// "P": "-0.209", // price change percent
|
|
945
|
-
// "w": "0.01920495", // weighted average price
|
|
946
|
-
// "x": "0.01916500", // the price of the first trade before the 24hr rolling window
|
|
947
|
-
// "c": "0.01912500", // last (closing) price
|
|
948
|
-
// "Q": "0.10400000", // last quantity
|
|
949
|
-
// "b": "0.01912200", // best bid
|
|
950
|
-
// "B": "4.10400000", // best bid quantity
|
|
951
|
-
// "a": "0.01912500", // best ask
|
|
952
|
-
// "A": "0.00100000", // best ask quantity
|
|
953
|
-
// "o": "0.01916500", // open price
|
|
954
|
-
// "h": "0.01956500", // high price
|
|
955
|
-
// "l": "0.01887700", // low price
|
|
956
|
-
// "v": "173518.11900000", // base volume
|
|
957
|
-
// "q": "3332.40703994", // quote volume
|
|
958
|
-
// "O": 1579399197842, // open time
|
|
959
|
-
// "C": 1579485597842, // close time
|
|
960
|
-
// "F": 158251292, // first trade id
|
|
961
|
-
// "L": 158414513, // last trade id
|
|
962
|
-
// "n": 163222, // total number of trades
|
|
963
|
-
// }
|
|
964
|
-
//
|
|
965
|
-
// miniTicker
|
|
966
|
-
// {
|
|
967
|
-
// "e": "24hrMiniTicker",
|
|
968
|
-
// "E": 1671617114585,
|
|
969
|
-
// "s": "MOBBUSD",
|
|
970
|
-
// "c": "0.95900000",
|
|
971
|
-
// "o": "0.91200000",
|
|
972
|
-
// "h": "1.04000000",
|
|
973
|
-
// "l": "0.89400000",
|
|
974
|
-
// "v": "2109995.32000000",
|
|
975
|
-
// "q": "2019254.05788000"
|
|
976
|
-
// }
|
|
977
|
-
//
|
|
978
|
-
let event = this.safeString(message, 'e', 'bookTicker');
|
|
979
|
-
if (event === '24hrTicker') {
|
|
980
|
-
event = 'ticker';
|
|
981
|
-
}
|
|
982
|
-
let timestamp = undefined;
|
|
983
|
-
if (event === 'bookTicker') {
|
|
984
|
-
// take the event timestamp, if available, for spot tickers it is not
|
|
985
|
-
timestamp = this.safeInteger(message, 'E');
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
// take the timestamp of the closing price for candlestick streams
|
|
989
|
-
timestamp = this.safeInteger(message, 'C');
|
|
990
|
-
}
|
|
991
|
-
const marketId = this.safeString(message, 's');
|
|
992
|
-
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
993
|
-
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
994
|
-
const last = this.safeString(message, 'c');
|
|
995
|
-
return this.safeTicker({
|
|
996
|
-
'symbol': symbol,
|
|
997
|
-
'timestamp': timestamp,
|
|
998
|
-
'datetime': this.iso8601(timestamp),
|
|
999
|
-
'high': this.safeString(message, 'h'),
|
|
1000
|
-
'low': this.safeString(message, 'l'),
|
|
1001
|
-
'bid': this.safeString(message, 'b'),
|
|
1002
|
-
'bidVolume': this.safeString(message, 'B'),
|
|
1003
|
-
'ask': this.safeString(message, 'a'),
|
|
1004
|
-
'askVolume': this.safeString(message, 'A'),
|
|
1005
|
-
'vwap': this.safeString(message, 'w'),
|
|
1006
|
-
'open': this.safeString(message, 'o'),
|
|
1007
|
-
'close': last,
|
|
1008
|
-
'last': last,
|
|
1009
|
-
'previousClose': this.safeString(message, 'x'),
|
|
1010
|
-
'change': this.safeString(message, 'p'),
|
|
1011
|
-
'percentage': this.safeString(message, 'P'),
|
|
1012
|
-
'average': undefined,
|
|
1013
|
-
'baseVolume': this.safeString(message, 'v'),
|
|
1014
|
-
'quoteVolume': this.safeString(message, 'q'),
|
|
1015
|
-
'info': message,
|
|
1016
|
-
}, market);
|
|
1017
|
-
}
|
|
1018
|
-
handleTicker(client, message) {
|
|
1019
|
-
//
|
|
1020
|
-
// 24hr rolling window ticker statistics for a single symbol
|
|
1021
|
-
// These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs
|
|
1022
|
-
// Update Speed 1000ms
|
|
1023
|
-
//
|
|
1024
|
-
// {
|
|
1025
|
-
// "e": "24hrTicker", // event type
|
|
1026
|
-
// "E": 1579485598569, // event time
|
|
1027
|
-
// "s": "ETHBTC", // symbol
|
|
1028
|
-
// "p": "-0.00004000", // price change
|
|
1029
|
-
// "P": "-0.209", // price change percent
|
|
1030
|
-
// "w": "0.01920495", // weighted average price
|
|
1031
|
-
// "x": "0.01916500", // the price of the first trade before the 24hr rolling window
|
|
1032
|
-
// "c": "0.01912500", // last (closing) price
|
|
1033
|
-
// "Q": "0.10400000", // last quantity
|
|
1034
|
-
// "b": "0.01912200", // best bid
|
|
1035
|
-
// "B": "4.10400000", // best bid quantity
|
|
1036
|
-
// "a": "0.01912500", // best ask
|
|
1037
|
-
// "A": "0.00100000", // best ask quantity
|
|
1038
|
-
// "o": "0.01916500", // open price
|
|
1039
|
-
// "h": "0.01956500", // high price
|
|
1040
|
-
// "l": "0.01887700", // low price
|
|
1041
|
-
// "v": "173518.11900000", // base volume
|
|
1042
|
-
// "q": "3332.40703994", // quote volume
|
|
1043
|
-
// "O": 1579399197842, // open time
|
|
1044
|
-
// "C": 1579485597842, // close time
|
|
1045
|
-
// "F": 158251292, // first trade id
|
|
1046
|
-
// "L": 158414513, // last trade id
|
|
1047
|
-
// "n": 163222, // total number of trades
|
|
1048
|
-
// }
|
|
1049
|
-
//
|
|
1050
|
-
let event = this.safeString(message, 'e', 'bookTicker');
|
|
1051
|
-
if (event === '24hrTicker') {
|
|
1052
|
-
event = 'ticker';
|
|
1053
|
-
}
|
|
1054
|
-
else if (event === '24hrMiniTicker') {
|
|
1055
|
-
event = 'miniTicker';
|
|
1056
|
-
}
|
|
1057
|
-
const wsMarketId = this.safeStringLower(message, 's');
|
|
1058
|
-
const messageHash = wsMarketId + '@' + event;
|
|
1059
|
-
const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
|
|
1060
|
-
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1061
|
-
const result = this.parseWsTicker(message, marketType);
|
|
1062
|
-
const symbol = result['symbol'];
|
|
1063
|
-
this.tickers[symbol] = result;
|
|
1064
|
-
client.resolve(result, messageHash);
|
|
1065
|
-
if (event === 'bookTicker') {
|
|
1066
|
-
// watch bookTickers
|
|
1067
|
-
client.resolve(result, '!' + 'bookTicker@arr');
|
|
1068
|
-
const messageHashes = this.findMessageHashes(client, 'tickers::');
|
|
1069
|
-
for (let i = 0; i < messageHashes.length; i++) {
|
|
1070
|
-
const currentMessageHash = messageHashes[i];
|
|
1071
|
-
const parts = currentMessageHash.split('::');
|
|
1072
|
-
const symbolsString = parts[1];
|
|
1073
|
-
const symbols = symbolsString.split(',');
|
|
1074
|
-
if (this.inArray(symbol, symbols)) {
|
|
1075
|
-
client.resolve(result, currentMessageHash);
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
handleTickers(client, message) {
|
|
1081
|
-
const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
|
|
1082
|
-
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1083
|
-
let rawTickers = [];
|
|
1084
|
-
const newTickers = {};
|
|
1085
|
-
if (Array.isArray(message)) {
|
|
1086
|
-
rawTickers = message;
|
|
1087
|
-
}
|
|
1088
|
-
else {
|
|
1089
|
-
rawTickers.push(message);
|
|
1090
|
-
}
|
|
1091
|
-
for (let i = 0; i < rawTickers.length; i++) {
|
|
1092
|
-
const ticker = rawTickers[i];
|
|
1093
|
-
const result = this.parseWsTicker(ticker, marketType);
|
|
1094
|
-
const symbol = result['symbol'];
|
|
1095
|
-
this.tickers[symbol] = result;
|
|
1096
|
-
newTickers[symbol] = result;
|
|
1097
|
-
}
|
|
1098
|
-
const messageHashes = this.findMessageHashes(client, 'tickers::');
|
|
1099
|
-
for (let i = 0; i < messageHashes.length; i++) {
|
|
1100
|
-
const messageHash = messageHashes[i];
|
|
1101
|
-
const parts = messageHash.split('::');
|
|
1102
|
-
const symbolsString = parts[1];
|
|
1103
|
-
const symbols = symbolsString.split(',');
|
|
1104
|
-
const tickers = this.filterByArray(newTickers, 'symbol', symbols);
|
|
1105
|
-
const tickersSymbols = Object.keys(tickers);
|
|
1106
|
-
const numTickers = tickersSymbols.length;
|
|
1107
|
-
if (numTickers > 0) {
|
|
1108
|
-
client.resolve(tickers, messageHash);
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
client.resolve(newTickers, 'tickers');
|
|
1112
|
-
}
|
|
1113
|
-
signParams(params = {}) {
|
|
1114
|
-
this.checkRequiredCredentials();
|
|
1115
|
-
let extendedParams = this.extend({
|
|
1116
|
-
'timestamp': this.nonce(),
|
|
1117
|
-
'apiKey': this.apiKey,
|
|
1118
|
-
}, params);
|
|
1119
|
-
const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
|
|
1120
|
-
if (defaultRecvWindow !== undefined) {
|
|
1121
|
-
params['recvWindow'] = defaultRecvWindow;
|
|
1122
|
-
}
|
|
1123
|
-
const recvWindow = this.safeInteger(params, 'recvWindow');
|
|
1124
|
-
if (recvWindow !== undefined) {
|
|
1125
|
-
params['recvWindow'] = recvWindow;
|
|
1126
|
-
}
|
|
1127
|
-
extendedParams = this.keysort(extendedParams);
|
|
1128
|
-
const query = this.urlencode(extendedParams);
|
|
1129
|
-
let signature = undefined;
|
|
1130
|
-
if (this.secret.indexOf('PRIVATE KEY') > -1) {
|
|
1131
|
-
if (this.secret.length > 120) {
|
|
1132
|
-
signature = rsa.rsa(query, this.secret, sha256.sha256);
|
|
1133
|
-
}
|
|
1134
|
-
else {
|
|
1135
|
-
signature = crypto.eddsa(this.encode(query), this.secret, ed25519.ed25519);
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
signature = this.hmac(this.encode(query), this.encode(this.secret), sha256.sha256);
|
|
1140
|
-
}
|
|
1141
|
-
extendedParams['signature'] = signature;
|
|
1142
|
-
return extendedParams;
|
|
1143
|
-
}
|
|
1144
|
-
async authenticate(params = {}) {
|
|
1145
|
-
const time = this.milliseconds();
|
|
1146
|
-
let query = undefined;
|
|
1147
|
-
let type = undefined;
|
|
1148
|
-
[type, query] = this.handleMarketTypeAndParams('authenticate', undefined, params);
|
|
1149
|
-
let subType = undefined;
|
|
1150
|
-
[subType, query] = this.handleSubTypeAndParams('authenticate', undefined, query);
|
|
1151
|
-
if (this.isLinear(type, subType)) {
|
|
1152
|
-
type = 'future';
|
|
1153
|
-
}
|
|
1154
|
-
else if (this.isInverse(type, subType)) {
|
|
1155
|
-
type = 'delivery';
|
|
1156
|
-
}
|
|
1157
|
-
let marginMode = undefined;
|
|
1158
|
-
[marginMode, query] = this.handleMarginModeAndParams('authenticate', query);
|
|
1159
|
-
const isIsolatedMargin = (marginMode === 'isolated');
|
|
1160
|
-
const isCrossMargin = (marginMode === 'cross') || (marginMode === undefined);
|
|
1161
|
-
const symbol = this.safeString(query, 'symbol');
|
|
1162
|
-
query = this.omit(query, 'symbol');
|
|
1163
|
-
const options = this.safeValue(this.options, type, {});
|
|
1164
|
-
const lastAuthenticatedTime = this.safeInteger(options, 'lastAuthenticatedTime', 0);
|
|
1165
|
-
const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
|
|
1166
|
-
const delay = this.sum(listenKeyRefreshRate, 10000);
|
|
1167
|
-
if (time - lastAuthenticatedTime > delay) {
|
|
1168
|
-
let response = undefined;
|
|
1169
|
-
if (type === 'future') {
|
|
1170
|
-
response = await this.fapiPrivatePostListenKey(query);
|
|
1171
|
-
}
|
|
1172
|
-
else if (type === 'delivery') {
|
|
1173
|
-
response = await this.dapiPrivatePostListenKey(query);
|
|
1174
|
-
}
|
|
1175
|
-
else if (type === 'margin' && isCrossMargin) {
|
|
1176
|
-
response = await this.sapiPostUserDataStream(query);
|
|
1177
|
-
}
|
|
1178
|
-
else if (isIsolatedMargin) {
|
|
1179
|
-
if (symbol === undefined) {
|
|
1180
|
-
throw new errors.ArgumentsRequired(this.id + ' authenticate() requires a symbol argument for isolated margin mode');
|
|
1181
|
-
}
|
|
1182
|
-
const marketId = this.marketId(symbol);
|
|
1183
|
-
query = this.extend(query, { 'symbol': marketId });
|
|
1184
|
-
response = await this.sapiPostUserDataStreamIsolated(query);
|
|
1185
|
-
}
|
|
1186
|
-
else {
|
|
1187
|
-
response = await this.publicPostUserDataStream(query);
|
|
1188
|
-
}
|
|
1189
|
-
this.options[type] = this.extend(options, {
|
|
1190
|
-
'listenKey': this.safeString(response, 'listenKey'),
|
|
1191
|
-
'lastAuthenticatedTime': time,
|
|
1192
|
-
});
|
|
1193
|
-
this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
async keepAliveListenKey(params = {}) {
|
|
1197
|
-
// https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot
|
|
1198
|
-
let type = this.safeString2(this.options, 'defaultType', 'authenticate', 'spot');
|
|
1199
|
-
type = this.safeString(params, 'type', type);
|
|
1200
|
-
const subTypeInfo = this.handleSubTypeAndParams('keepAliveListenKey', undefined, params);
|
|
1201
|
-
const subType = subTypeInfo[0];
|
|
1202
|
-
if (this.isLinear(type, subType)) {
|
|
1203
|
-
type = 'future';
|
|
1204
|
-
}
|
|
1205
|
-
else if (this.isInverse(type, subType)) {
|
|
1206
|
-
type = 'delivery';
|
|
1207
|
-
}
|
|
1208
|
-
const options = this.safeValue(this.options, type, {});
|
|
1209
|
-
const listenKey = this.safeString(options, 'listenKey');
|
|
1210
|
-
if (listenKey === undefined) {
|
|
1211
|
-
// A network error happened: we can't renew a listen key that does not exist.
|
|
1212
|
-
return;
|
|
1213
|
-
}
|
|
1214
|
-
const request = {};
|
|
1215
|
-
const symbol = this.safeString(params, 'symbol');
|
|
1216
|
-
const sendParams = this.omit(params, ['type', 'symbol']);
|
|
1217
|
-
const time = this.milliseconds();
|
|
1218
|
-
try {
|
|
1219
|
-
if (type === 'future') {
|
|
1220
|
-
await this.fapiPrivatePutListenKey(this.extend(request, sendParams));
|
|
1221
|
-
}
|
|
1222
|
-
else if (type === 'delivery') {
|
|
1223
|
-
await this.dapiPrivatePutListenKey(this.extend(request, sendParams));
|
|
1224
|
-
}
|
|
1225
|
-
else {
|
|
1226
|
-
request['listenKey'] = listenKey;
|
|
1227
|
-
if (type === 'margin') {
|
|
1228
|
-
request['symbol'] = symbol;
|
|
1229
|
-
await this.sapiPutUserDataStream(this.extend(request, sendParams));
|
|
1230
|
-
}
|
|
1231
|
-
else {
|
|
1232
|
-
await this.publicPutUserDataStream(this.extend(request, sendParams));
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
catch (error) {
|
|
1237
|
-
const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
|
|
1238
|
-
const client = this.client(url);
|
|
1239
|
-
const messageHashes = Object.keys(client.futures);
|
|
1240
|
-
for (let i = 0; i < messageHashes.length; i++) {
|
|
1241
|
-
const messageHash = messageHashes[i];
|
|
1242
|
-
client.reject(error, messageHash);
|
|
1243
|
-
}
|
|
1244
|
-
this.options[type] = this.extend(options, {
|
|
1245
|
-
'listenKey': undefined,
|
|
1246
|
-
'lastAuthenticatedTime': 0,
|
|
1247
|
-
});
|
|
1248
|
-
return;
|
|
1249
|
-
}
|
|
1250
|
-
this.options[type] = this.extend(options, {
|
|
1251
|
-
'listenKey': listenKey,
|
|
1252
|
-
'lastAuthenticatedTime': time,
|
|
1253
|
-
});
|
|
1254
|
-
// whether or not to schedule another listenKey keepAlive request
|
|
1255
|
-
const clients = Object.values(this.clients);
|
|
1256
|
-
const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
|
|
1257
|
-
for (let i = 0; i < clients.length; i++) {
|
|
1258
|
-
const client = clients[i];
|
|
1259
|
-
const subscriptionKeys = Object.keys(client.subscriptions);
|
|
1260
|
-
for (let j = 0; j < subscriptionKeys.length; j++) {
|
|
1261
|
-
const subscribeType = subscriptionKeys[j];
|
|
1262
|
-
if (subscribeType === type) {
|
|
1263
|
-
return this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
setBalanceCache(client, type) {
|
|
1269
|
-
if (type in client.subscriptions) {
|
|
1270
|
-
return undefined;
|
|
1271
|
-
}
|
|
1272
|
-
const options = this.safeValue(this.options, 'watchBalance');
|
|
1273
|
-
const fetchBalanceSnapshot = this.safeValue(options, 'fetchBalanceSnapshot', false);
|
|
1274
|
-
if (fetchBalanceSnapshot) {
|
|
1275
|
-
const messageHash = type + ':fetchBalanceSnapshot';
|
|
1276
|
-
if (!(messageHash in client.futures)) {
|
|
1277
|
-
client.future(messageHash);
|
|
1278
|
-
this.spawn(this.loadBalanceSnapshot, client, messageHash, type);
|
|
1279
|
-
}
|
|
1280
|
-
}
|
|
1281
|
-
else {
|
|
1282
|
-
this.balance[type] = {};
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
async loadBalanceSnapshot(client, messageHash, type) {
|
|
1286
|
-
const response = await this.fetchBalance({ 'type': type });
|
|
1287
|
-
this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
|
|
1288
|
-
// don't remove the future from the .futures cache
|
|
1289
|
-
const future = client.futures[messageHash];
|
|
1290
|
-
future.resolve();
|
|
1291
|
-
client.resolve(this.balance[type], type + ':balance');
|
|
1292
|
-
}
|
|
1293
|
-
async fetchBalanceWs(params = {}) {
|
|
1294
|
-
/**
|
|
1295
|
-
* @method
|
|
1296
|
-
* @name binance#fetchBalanceWs
|
|
1297
|
-
* @description fetch balance and get the amount of funds available for trading or funds locked in orders
|
|
1298
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#account-information-user_data
|
|
1299
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1300
|
-
* @param {string|undefined} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot'
|
|
1301
|
-
* @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
|
|
1302
|
-
* @param {string[]|undefined} [params.symbols] unified market symbols, only used in isolated margin mode
|
|
1303
|
-
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1304
|
-
*/
|
|
1305
|
-
await this.loadMarkets();
|
|
1306
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1307
|
-
const requestId = this.requestId(url);
|
|
1308
|
-
const messageHash = requestId.toString();
|
|
1309
|
-
let returnRateLimits = false;
|
|
1310
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
|
|
1311
|
-
const payload = {
|
|
1312
|
-
'returnRateLimits': returnRateLimits,
|
|
1313
|
-
};
|
|
1314
|
-
const message = {
|
|
1315
|
-
'id': messageHash,
|
|
1316
|
-
'method': 'account.status',
|
|
1317
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1318
|
-
};
|
|
1319
|
-
const subscription = {
|
|
1320
|
-
'method': this.handleBalanceWs,
|
|
1321
|
-
};
|
|
1322
|
-
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1323
|
-
}
|
|
1324
|
-
handleBalanceWs(client, message) {
|
|
1325
|
-
//
|
|
1326
|
-
// {
|
|
1327
|
-
// "id": "605a6d20-6588-4cb9-afa0-b0ab087507ba",
|
|
1328
|
-
// "status": 200,
|
|
1329
|
-
// "result": {
|
|
1330
|
-
// "makerCommission": 15,
|
|
1331
|
-
// "takerCommission": 15,
|
|
1332
|
-
// "buyerCommission": 0,
|
|
1333
|
-
// "sellerCommission": 0,
|
|
1334
|
-
// "canTrade": true,
|
|
1335
|
-
// "canWithdraw": true,
|
|
1336
|
-
// "canDeposit": true,
|
|
1337
|
-
// "commissionRates": {
|
|
1338
|
-
// "maker": "0.00150000",
|
|
1339
|
-
// "taker": "0.00150000",
|
|
1340
|
-
// "buyer": "0.00000000",
|
|
1341
|
-
// "seller": "0.00000000"
|
|
1342
|
-
// },
|
|
1343
|
-
// "brokered": false,
|
|
1344
|
-
// "requireSelfTradePrevention": false,
|
|
1345
|
-
// "updateTime": 1660801833000,
|
|
1346
|
-
// "accountType": "SPOT",
|
|
1347
|
-
// "balances": [{
|
|
1348
|
-
// "asset": "BNB",
|
|
1349
|
-
// "free": "0.00000000",
|
|
1350
|
-
// "locked": "0.00000000"
|
|
1351
|
-
// },
|
|
1352
|
-
// {
|
|
1353
|
-
// "asset": "BTC",
|
|
1354
|
-
// "free": "1.3447112",
|
|
1355
|
-
// "locked": "0.08600000"
|
|
1356
|
-
// },
|
|
1357
|
-
// {
|
|
1358
|
-
// "asset": "USDT",
|
|
1359
|
-
// "free": "1021.21000000",
|
|
1360
|
-
// "locked": "0.00000000"
|
|
1361
|
-
// }
|
|
1362
|
-
// ],
|
|
1363
|
-
// "permissions": [
|
|
1364
|
-
// "SPOT"
|
|
1365
|
-
// ]
|
|
1366
|
-
// }
|
|
1367
|
-
// }
|
|
1368
|
-
//
|
|
1369
|
-
const messageHash = this.safeString(message, 'id');
|
|
1370
|
-
const result = this.safeValue(message, 'result', {});
|
|
1371
|
-
const parsedBalances = this.parseBalance(result, 'spot');
|
|
1372
|
-
client.resolve(parsedBalances, messageHash);
|
|
1373
|
-
}
|
|
1374
|
-
async watchBalance(params = {}) {
|
|
1375
|
-
/**
|
|
1376
|
-
* @method
|
|
1377
|
-
* @name binance#watchBalance
|
|
1378
|
-
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1379
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1380
|
-
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1381
|
-
*/
|
|
1382
|
-
await this.loadMarkets();
|
|
1383
|
-
await this.authenticate(params);
|
|
1384
|
-
const defaultType = this.safeString(this.options, 'defaultType', 'spot');
|
|
1385
|
-
let type = this.safeString(params, 'type', defaultType);
|
|
1386
|
-
let subType = undefined;
|
|
1387
|
-
[subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
|
|
1388
|
-
if (this.isLinear(type, subType)) {
|
|
1389
|
-
type = 'future';
|
|
1390
|
-
}
|
|
1391
|
-
else if (this.isInverse(type, subType)) {
|
|
1392
|
-
type = 'delivery';
|
|
1393
|
-
}
|
|
1394
|
-
const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
|
|
1395
|
-
const client = this.client(url);
|
|
1396
|
-
this.setBalanceCache(client, type);
|
|
1397
|
-
this.setPositionsCache(client, type);
|
|
1398
|
-
const options = this.safeValue(this.options, 'watchBalance');
|
|
1399
|
-
const fetchBalanceSnapshot = this.safeValue(options, 'fetchBalanceSnapshot', false);
|
|
1400
|
-
const awaitBalanceSnapshot = this.safeValue(options, 'awaitBalanceSnapshot', true);
|
|
1401
|
-
if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
|
|
1402
|
-
await client.future(type + ':fetchBalanceSnapshot');
|
|
1403
|
-
}
|
|
1404
|
-
const messageHash = type + ':balance';
|
|
1405
|
-
const message = undefined;
|
|
1406
|
-
return await this.watch(url, messageHash, message, type);
|
|
1407
|
-
}
|
|
1408
|
-
handleBalance(client, message) {
|
|
1409
|
-
//
|
|
1410
|
-
// sent upon a balance update not related to orders
|
|
1411
|
-
//
|
|
1412
|
-
// {
|
|
1413
|
-
// "e": "balanceUpdate",
|
|
1414
|
-
// "E": 1629352505586,
|
|
1415
|
-
// "a": "IOTX",
|
|
1416
|
-
// "d": "0.43750000",
|
|
1417
|
-
// "T": 1629352505585
|
|
1418
|
-
// }
|
|
1419
|
-
//
|
|
1420
|
-
// sent upon creating or filling an order
|
|
1421
|
-
//
|
|
1422
|
-
// {
|
|
1423
|
-
// "e": "outboundAccountPosition", // Event type
|
|
1424
|
-
// "E": 1564034571105, // Event Time
|
|
1425
|
-
// "u": 1564034571073, // Time of last account update
|
|
1426
|
-
// "B": [ // Balances Array
|
|
1427
|
-
// {
|
|
1428
|
-
// "a": "ETH", // Asset
|
|
1429
|
-
// "f": "10000.000000", // Free
|
|
1430
|
-
// "l": "0.000000" // Locked
|
|
1431
|
-
// }
|
|
1432
|
-
// ]
|
|
1433
|
-
// }
|
|
1434
|
-
//
|
|
1435
|
-
// future/delivery
|
|
1436
|
-
//
|
|
1437
|
-
// {
|
|
1438
|
-
// "e": "ACCOUNT_UPDATE", // Event Type
|
|
1439
|
-
// "E": 1564745798939, // Event Time
|
|
1440
|
-
// "T": 1564745798938 , // Transaction
|
|
1441
|
-
// "i": "SfsR", // Account Alias
|
|
1442
|
-
// "a": { // Update Data
|
|
1443
|
-
// "m":"ORDER", // Event reason type
|
|
1444
|
-
// "B":[ // Balances
|
|
1445
|
-
// {
|
|
1446
|
-
// "a":"BTC", // Asset
|
|
1447
|
-
// "wb":"122624.12345678", // Wallet Balance
|
|
1448
|
-
// "cw":"100.12345678" // Cross Wallet Balance
|
|
1449
|
-
// },
|
|
1450
|
-
// ],
|
|
1451
|
-
// "P":[
|
|
1452
|
-
// {
|
|
1453
|
-
// "s":"BTCUSD_200925", // Symbol
|
|
1454
|
-
// "pa":"0", // Position Amount
|
|
1455
|
-
// "ep":"0.0", // Entry Price
|
|
1456
|
-
// "cr":"200", // (Pre-fee) Accumulated Realized
|
|
1457
|
-
// "up":"0", // Unrealized PnL
|
|
1458
|
-
// "mt":"isolated", // Margin Type
|
|
1459
|
-
// "iw":"0.00000000", // Isolated Wallet (if isolated position)
|
|
1460
|
-
// "ps":"BOTH" // Position Side
|
|
1461
|
-
// },
|
|
1462
|
-
// ]
|
|
1463
|
-
// }
|
|
1464
|
-
// }
|
|
1465
|
-
//
|
|
1466
|
-
const wallet = this.safeValue(this.options, 'wallet', 'wb'); // cw for cross wallet
|
|
1467
|
-
// each account is connected to a different endpoint
|
|
1468
|
-
// and has exactly one subscriptionhash which is the account type
|
|
1469
|
-
const subscriptions = Object.keys(client.subscriptions);
|
|
1470
|
-
const accountType = subscriptions[0];
|
|
1471
|
-
const messageHash = accountType + ':balance';
|
|
1472
|
-
if (this.balance[accountType] === undefined) {
|
|
1473
|
-
this.balance[accountType] = {};
|
|
1474
|
-
}
|
|
1475
|
-
this.balance[accountType]['info'] = message;
|
|
1476
|
-
const event = this.safeString(message, 'e');
|
|
1477
|
-
if (event === 'balanceUpdate') {
|
|
1478
|
-
const currencyId = this.safeString(message, 'a');
|
|
1479
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1480
|
-
const account = this.account();
|
|
1481
|
-
const delta = this.safeString(message, 'd');
|
|
1482
|
-
if (code in this.balance[accountType]) {
|
|
1483
|
-
let previousValue = this.balance[accountType][code]['free'];
|
|
1484
|
-
if (typeof previousValue !== 'string') {
|
|
1485
|
-
previousValue = this.numberToString(previousValue);
|
|
1486
|
-
}
|
|
1487
|
-
account['free'] = Precise["default"].stringAdd(previousValue, delta);
|
|
1488
|
-
}
|
|
1489
|
-
else {
|
|
1490
|
-
account['free'] = delta;
|
|
1491
|
-
}
|
|
1492
|
-
this.balance[accountType][code] = account;
|
|
1493
|
-
}
|
|
1494
|
-
else {
|
|
1495
|
-
message = this.safeValue(message, 'a', message);
|
|
1496
|
-
const B = this.safeValue(message, 'B');
|
|
1497
|
-
for (let i = 0; i < B.length; i++) {
|
|
1498
|
-
const entry = B[i];
|
|
1499
|
-
const currencyId = this.safeString(entry, 'a');
|
|
1500
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1501
|
-
const account = this.account();
|
|
1502
|
-
account['free'] = this.safeString(entry, 'f');
|
|
1503
|
-
account['used'] = this.safeString(entry, 'l');
|
|
1504
|
-
account['total'] = this.safeString(entry, wallet);
|
|
1505
|
-
this.balance[accountType][code] = account;
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
const timestamp = this.safeInteger(message, 'E');
|
|
1509
|
-
this.balance[accountType]['timestamp'] = timestamp;
|
|
1510
|
-
this.balance[accountType]['datetime'] = this.iso8601(timestamp);
|
|
1511
|
-
this.balance[accountType] = this.safeBalance(this.balance[accountType]);
|
|
1512
|
-
client.resolve(this.balance[accountType], messageHash);
|
|
1513
|
-
}
|
|
1514
|
-
checkIsSpot(method, symbol, params = {}) {
|
|
1515
|
-
/**
|
|
1516
|
-
* @method
|
|
1517
|
-
* @ignore
|
|
1518
|
-
* @description checks if symbols is a spot market if not throws an error
|
|
1519
|
-
* @param {string} method name of the method to be checked
|
|
1520
|
-
* @param {string} symbol symbol or marketId of the market to be checked
|
|
1521
|
-
*/
|
|
1522
|
-
if (symbol === undefined) {
|
|
1523
|
-
const type = this.safeString(params, 'type', 'spot');
|
|
1524
|
-
const defaultType = this.safeString(this.options, 'defaultType', type);
|
|
1525
|
-
if (defaultType === 'spot') {
|
|
1526
|
-
return;
|
|
1527
|
-
}
|
|
1528
|
-
throw new errors.BadRequest(this.id + ' ' + method + ' only supports spot markets');
|
|
1529
|
-
}
|
|
1530
|
-
const market = this.market(symbol);
|
|
1531
|
-
if (!market['spot']) {
|
|
1532
|
-
throw new errors.BadRequest(this.id + ' ' + method + ' only supports spot markets');
|
|
1533
|
-
}
|
|
1534
|
-
}
|
|
1535
|
-
async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1536
|
-
/**
|
|
1537
|
-
* @method
|
|
1538
|
-
* @name binance#createOrderWs
|
|
1539
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#place-new-order-trade
|
|
1540
|
-
* @description create a trade order
|
|
1541
|
-
* @param {string} symbol unified symbol of the market to create an order in
|
|
1542
|
-
* @param {string} type 'market' or 'limit'
|
|
1543
|
-
* @param {string} side 'buy' or 'sell'
|
|
1544
|
-
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1545
|
-
* @param {float|undefined} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1546
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1547
|
-
* @param {boolean} params.test test order, default false
|
|
1548
|
-
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1549
|
-
*/
|
|
1550
|
-
await this.loadMarkets();
|
|
1551
|
-
this.checkIsSpot('createOrderWs', symbol, params);
|
|
1552
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1553
|
-
const requestId = this.requestId(url);
|
|
1554
|
-
const messageHash = requestId.toString();
|
|
1555
|
-
const sor = this.safeValue2(params, 'sor', 'SOR', false);
|
|
1556
|
-
params = this.omit(params, 'sor', 'SOR');
|
|
1557
|
-
const payload = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
1558
|
-
let returnRateLimits = false;
|
|
1559
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
|
|
1560
|
-
payload['returnRateLimits'] = returnRateLimits;
|
|
1561
|
-
const test = this.safeValue(params, 'test', false);
|
|
1562
|
-
params = this.omit(params, 'test');
|
|
1563
|
-
const message = {
|
|
1564
|
-
'id': messageHash,
|
|
1565
|
-
'method': 'order.place',
|
|
1566
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1567
|
-
};
|
|
1568
|
-
if (test) {
|
|
1569
|
-
if (sor) {
|
|
1570
|
-
message['method'] = 'sor.order.test';
|
|
1571
|
-
}
|
|
1572
|
-
else {
|
|
1573
|
-
message['method'] = 'order.test';
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
const subscription = {
|
|
1577
|
-
'method': this.handleOrderWs,
|
|
1578
|
-
};
|
|
1579
|
-
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1580
|
-
}
|
|
1581
|
-
handleOrderWs(client, message) {
|
|
1582
|
-
//
|
|
1583
|
-
// {
|
|
1584
|
-
// "id": 1,
|
|
1585
|
-
// "status": 200,
|
|
1586
|
-
// "result": {
|
|
1587
|
-
// "symbol": "BTCUSDT",
|
|
1588
|
-
// "orderId": 7663053,
|
|
1589
|
-
// "orderListId": -1,
|
|
1590
|
-
// "clientOrderId": "x-R4BD3S82d8959d0f5114499487a614",
|
|
1591
|
-
// "transactTime": 1687642291434,
|
|
1592
|
-
// "price": "25000.00000000",
|
|
1593
|
-
// "origQty": "0.00100000",
|
|
1594
|
-
// "executedQty": "0.00000000",
|
|
1595
|
-
// "cummulativeQuoteQty": "0.00000000",
|
|
1596
|
-
// "status": "NEW",
|
|
1597
|
-
// "timeInForce": "GTC",
|
|
1598
|
-
// "type": "LIMIT",
|
|
1599
|
-
// "side": "BUY",
|
|
1600
|
-
// "workingTime": 1687642291434,
|
|
1601
|
-
// "fills": [],
|
|
1602
|
-
// "selfTradePreventionMode": "NONE"
|
|
1603
|
-
// },
|
|
1604
|
-
// "rateLimits": [
|
|
1605
|
-
// {
|
|
1606
|
-
// "rateLimitType": "ORDERS",
|
|
1607
|
-
// "interval": "SECOND",
|
|
1608
|
-
// "intervalNum": 10,
|
|
1609
|
-
// "limit": 50,
|
|
1610
|
-
// "count": 1
|
|
1611
|
-
// },
|
|
1612
|
-
// {
|
|
1613
|
-
// "rateLimitType": "ORDERS",
|
|
1614
|
-
// "interval": "DAY",
|
|
1615
|
-
// "intervalNum": 1,
|
|
1616
|
-
// "limit": 160000,
|
|
1617
|
-
// "count": 1
|
|
1618
|
-
// },
|
|
1619
|
-
// {
|
|
1620
|
-
// "rateLimitType": "REQUEST_WEIGHT",
|
|
1621
|
-
// "interval": "MINUTE",
|
|
1622
|
-
// "intervalNum": 1,
|
|
1623
|
-
// "limit": 1200,
|
|
1624
|
-
// "count": 12
|
|
1625
|
-
// }
|
|
1626
|
-
// ]
|
|
1627
|
-
// }
|
|
1628
|
-
//
|
|
1629
|
-
const messageHash = this.safeString(message, 'id');
|
|
1630
|
-
const result = this.safeValue(message, 'result', {});
|
|
1631
|
-
const order = this.parseOrder(result);
|
|
1632
|
-
client.resolve(order, messageHash);
|
|
1633
|
-
}
|
|
1634
|
-
handleOrdersWs(client, message) {
|
|
1635
|
-
//
|
|
1636
|
-
// {
|
|
1637
|
-
// "id": 1,
|
|
1638
|
-
// "status": 200,
|
|
1639
|
-
// "result": [{
|
|
1640
|
-
// "symbol": "BTCUSDT",
|
|
1641
|
-
// "orderId": 7665584,
|
|
1642
|
-
// "orderListId": -1,
|
|
1643
|
-
// "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
|
|
1644
|
-
// "price": "26000.00000000",
|
|
1645
|
-
// "origQty": "0.00100000",
|
|
1646
|
-
// "executedQty": "0.00000000",
|
|
1647
|
-
// "cummulativeQuoteQty": "0.00000000",
|
|
1648
|
-
// "status": "NEW",
|
|
1649
|
-
// "timeInForce": "GTC",
|
|
1650
|
-
// "type": "LIMIT",
|
|
1651
|
-
// "side": "BUY",
|
|
1652
|
-
// "stopPrice": "0.00000000",
|
|
1653
|
-
// "icebergQty": "0.00000000",
|
|
1654
|
-
// "time": 1687642884646,
|
|
1655
|
-
// "updateTime": 1687642884646,
|
|
1656
|
-
// "isWorking": true,
|
|
1657
|
-
// "workingTime": 1687642884646,
|
|
1658
|
-
// "origQuoteOrderQty": "0.00000000",
|
|
1659
|
-
// "selfTradePreventionMode": "NONE"
|
|
1660
|
-
// },
|
|
1661
|
-
// ...
|
|
1662
|
-
// ],
|
|
1663
|
-
// "rateLimits": [{
|
|
1664
|
-
// "rateLimitType": "REQUEST_WEIGHT",
|
|
1665
|
-
// "interval": "MINUTE",
|
|
1666
|
-
// "intervalNum": 1,
|
|
1667
|
-
// "limit": 1200,
|
|
1668
|
-
// "count": 14
|
|
1669
|
-
// }]
|
|
1670
|
-
// }
|
|
1671
|
-
//
|
|
1672
|
-
const messageHash = this.safeString(message, 'id');
|
|
1673
|
-
const result = this.safeValue(message, 'result', []);
|
|
1674
|
-
const orders = this.parseOrders(result);
|
|
1675
|
-
client.resolve(orders, messageHash);
|
|
1676
|
-
}
|
|
1677
|
-
async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
|
|
1678
|
-
/**
|
|
1679
|
-
* @method
|
|
1680
|
-
* @name binance#editOrderWs
|
|
1681
|
-
* @description edit a trade order
|
|
1682
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#cancel-and-replace-order-trade
|
|
1683
|
-
* @param {string} id order id
|
|
1684
|
-
* @param {string} symbol unified symbol of the market to create an order in
|
|
1685
|
-
* @param {string} type 'market' or 'limit'
|
|
1686
|
-
* @param {string} side 'buy' or 'sell'
|
|
1687
|
-
* @param {float} amount how much of the currency you want to trade in units of the base currency
|
|
1688
|
-
* @param {float|undefined} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1689
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1690
|
-
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1691
|
-
*/
|
|
1692
|
-
await this.loadMarkets();
|
|
1693
|
-
this.checkIsSpot('editOrderWs', symbol, params);
|
|
1694
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1695
|
-
const requestId = this.requestId(url);
|
|
1696
|
-
const messageHash = requestId.toString();
|
|
1697
|
-
const payload = this.editSpotOrderRequest(id, symbol, type, side, amount, price, params);
|
|
1698
|
-
let returnRateLimits = false;
|
|
1699
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'editOrderWs', 'returnRateLimits', false);
|
|
1700
|
-
payload['returnRateLimits'] = returnRateLimits;
|
|
1701
|
-
const message = {
|
|
1702
|
-
'id': messageHash,
|
|
1703
|
-
'method': 'order.cancelReplace',
|
|
1704
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1705
|
-
};
|
|
1706
|
-
const subscription = {
|
|
1707
|
-
'method': this.handleEditOrderWs,
|
|
1708
|
-
};
|
|
1709
|
-
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1710
|
-
}
|
|
1711
|
-
handleEditOrderWs(client, message) {
|
|
1712
|
-
//
|
|
1713
|
-
// {
|
|
1714
|
-
// "id": 1,
|
|
1715
|
-
// "status": 200,
|
|
1716
|
-
// "result": {
|
|
1717
|
-
// "cancelResult": "SUCCESS",
|
|
1718
|
-
// "newOrderResult": "SUCCESS",
|
|
1719
|
-
// "cancelResponse": {
|
|
1720
|
-
// "symbol": "BTCUSDT",
|
|
1721
|
-
// "origClientOrderId": "x-R4BD3S82813c5d7ffa594104917de2",
|
|
1722
|
-
// "orderId": 7665177,
|
|
1723
|
-
// "orderListId": -1,
|
|
1724
|
-
// "clientOrderId": "mbrnbQsQhtCXCLY45d5q7S",
|
|
1725
|
-
// "price": "26000.00000000",
|
|
1726
|
-
// "origQty": "0.00100000",
|
|
1727
|
-
// "executedQty": "0.00000000",
|
|
1728
|
-
// "cummulativeQuoteQty": "0.00000000",
|
|
1729
|
-
// "status": "CANCELED",
|
|
1730
|
-
// "timeInForce": "GTC",
|
|
1731
|
-
// "type": "LIMIT",
|
|
1732
|
-
// "side": "BUY",
|
|
1733
|
-
// "selfTradePreventionMode": "NONE"
|
|
1734
|
-
// },
|
|
1735
|
-
// "newOrderResponse": {
|
|
1736
|
-
// "symbol": "BTCUSDT",
|
|
1737
|
-
// "orderId": 7665584,
|
|
1738
|
-
// "orderListId": -1,
|
|
1739
|
-
// "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
|
|
1740
|
-
// "transactTime": 1687642884646,
|
|
1741
|
-
// "price": "26000.00000000",
|
|
1742
|
-
// "origQty": "0.00100000",
|
|
1743
|
-
// "executedQty": "0.00000000",
|
|
1744
|
-
// "cummulativeQuoteQty": "0.00000000",
|
|
1745
|
-
// "status": "NEW",
|
|
1746
|
-
// "timeInForce": "GTC",
|
|
1747
|
-
// "type": "LIMIT",
|
|
1748
|
-
// "side": "BUY",
|
|
1749
|
-
// "workingTime": 1687642884646,
|
|
1750
|
-
// "fills": [],
|
|
1751
|
-
// "selfTradePreventionMode": "NONE"
|
|
1752
|
-
// }
|
|
1753
|
-
// },
|
|
1754
|
-
// "rateLimits": [{
|
|
1755
|
-
// "rateLimitType": "ORDERS",
|
|
1756
|
-
// "interval": "SECOND",
|
|
1757
|
-
// "intervalNum": 10,
|
|
1758
|
-
// "limit": 50,
|
|
1759
|
-
// "count": 1
|
|
1760
|
-
// },
|
|
1761
|
-
// {
|
|
1762
|
-
// "rateLimitType": "ORDERS",
|
|
1763
|
-
// "interval": "DAY",
|
|
1764
|
-
// "intervalNum": 1,
|
|
1765
|
-
// "limit": 160000,
|
|
1766
|
-
// "count": 3
|
|
1767
|
-
// },
|
|
1768
|
-
// {
|
|
1769
|
-
// "rateLimitType": "REQUEST_WEIGHT",
|
|
1770
|
-
// "interval": "MINUTE",
|
|
1771
|
-
// "intervalNum": 1,
|
|
1772
|
-
// "limit": 1200,
|
|
1773
|
-
// "count": 12
|
|
1774
|
-
// }
|
|
1775
|
-
// ]
|
|
1776
|
-
// }
|
|
1777
|
-
//
|
|
1778
|
-
const messageHash = this.safeString(message, 'id');
|
|
1779
|
-
const result = this.safeValue(message, 'result', {});
|
|
1780
|
-
const rawOrder = this.safeValue(result, 'newOrderResponse', {});
|
|
1781
|
-
const order = this.parseOrder(rawOrder);
|
|
1782
|
-
client.resolve(order, messageHash);
|
|
1783
|
-
}
|
|
1784
|
-
async cancelOrderWs(id, symbol = undefined, params = {}) {
|
|
1785
|
-
/**
|
|
1786
|
-
* @method
|
|
1787
|
-
* @name binance#cancelOrderWs
|
|
1788
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#cancel-order-trade
|
|
1789
|
-
* @description cancel multiple orders
|
|
1790
|
-
* @param {string} id order id
|
|
1791
|
-
* @param {string} symbol unified market symbol, default is undefined
|
|
1792
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1793
|
-
* @param {string|undefined} [params.cancelRestrictions] Supported values: ONLY_NEW - Cancel will succeed if the order status is NEW. ONLY_PARTIALLY_FILLED - Cancel will succeed if order status is PARTIALLY_FILLED.
|
|
1794
|
-
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1795
|
-
*/
|
|
1796
|
-
await this.loadMarkets();
|
|
1797
|
-
if (symbol === undefined) {
|
|
1798
|
-
throw new errors.BadRequest(this.id + ' cancelOrderWs requires a symbol');
|
|
1799
|
-
}
|
|
1800
|
-
this.checkIsSpot('cancelOrderWs', symbol, params);
|
|
1801
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1802
|
-
const requestId = this.requestId(url);
|
|
1803
|
-
const messageHash = requestId.toString();
|
|
1804
|
-
let returnRateLimits = false;
|
|
1805
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelOrderWs', 'returnRateLimits', false);
|
|
1806
|
-
const payload = {
|
|
1807
|
-
'symbol': this.marketId(symbol),
|
|
1808
|
-
'returnRateLimits': returnRateLimits,
|
|
1809
|
-
};
|
|
1810
|
-
const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
|
|
1811
|
-
if (clientOrderId !== undefined) {
|
|
1812
|
-
payload['origClientOrderId'] = clientOrderId;
|
|
1813
|
-
}
|
|
1814
|
-
else {
|
|
1815
|
-
payload['orderId'] = this.parseToInt(id);
|
|
1816
|
-
}
|
|
1817
|
-
params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
|
|
1818
|
-
const message = {
|
|
1819
|
-
'id': messageHash,
|
|
1820
|
-
'method': 'order.cancel',
|
|
1821
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1822
|
-
};
|
|
1823
|
-
const subscription = {
|
|
1824
|
-
'method': this.handleOrderWs,
|
|
1825
|
-
};
|
|
1826
|
-
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1827
|
-
}
|
|
1828
|
-
async cancelAllOrdersWs(symbol = undefined, params = {}) {
|
|
1829
|
-
/**
|
|
1830
|
-
* @method
|
|
1831
|
-
* @name binance#cancelAllOrdersWs
|
|
1832
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#current-open-orders-user_data
|
|
1833
|
-
* @description cancel all open orders in a market
|
|
1834
|
-
* @param {string} symbol unified market symbol of the market to cancel orders in
|
|
1835
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1836
|
-
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1837
|
-
*/
|
|
1838
|
-
await this.loadMarkets();
|
|
1839
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1840
|
-
const requestId = this.requestId(url);
|
|
1841
|
-
const messageHash = requestId.toString();
|
|
1842
|
-
let returnRateLimits = false;
|
|
1843
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelAllOrdersWs', 'returnRateLimits', false);
|
|
1844
|
-
const payload = {
|
|
1845
|
-
'symbol': this.marketId(symbol),
|
|
1846
|
-
'returnRateLimits': returnRateLimits,
|
|
1847
|
-
};
|
|
1848
|
-
const message = {
|
|
1849
|
-
'id': messageHash,
|
|
1850
|
-
'method': 'order.cancel',
|
|
1851
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1852
|
-
};
|
|
1853
|
-
const subscription = {
|
|
1854
|
-
'method': this.handleOrdersWs,
|
|
1855
|
-
};
|
|
1856
|
-
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1857
|
-
}
|
|
1858
|
-
async fetchOrderWs(id, symbol = undefined, params = {}) {
|
|
1859
|
-
/**
|
|
1860
|
-
* @method
|
|
1861
|
-
* @name binance#fetchOrderWs
|
|
1862
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#query-order-user_data
|
|
1863
|
-
* @description fetches information on an order made by the user
|
|
1864
|
-
* @param {string} symbol unified symbol of the market the order was made in
|
|
1865
|
-
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
1866
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1867
|
-
*/
|
|
1868
|
-
await this.loadMarkets();
|
|
1869
|
-
if (symbol === undefined) {
|
|
1870
|
-
throw new errors.BadRequest(this.id + ' cancelOrderWs requires a symbol');
|
|
1871
|
-
}
|
|
1872
|
-
this.checkIsSpot('fetchOrderWs', symbol, params);
|
|
1873
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1874
|
-
const requestId = this.requestId(url);
|
|
1875
|
-
const messageHash = requestId.toString();
|
|
1876
|
-
let returnRateLimits = false;
|
|
1877
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
|
|
1878
|
-
const payload = {
|
|
1879
|
-
'symbol': this.marketId(symbol),
|
|
1880
|
-
'returnRateLimits': returnRateLimits,
|
|
1881
|
-
};
|
|
1882
|
-
const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
|
|
1883
|
-
if (clientOrderId !== undefined) {
|
|
1884
|
-
payload['origClientOrderId'] = clientOrderId;
|
|
1885
|
-
}
|
|
1886
|
-
else {
|
|
1887
|
-
payload['orderId'] = this.parseToInt(id);
|
|
1888
|
-
}
|
|
1889
|
-
const message = {
|
|
1890
|
-
'id': messageHash,
|
|
1891
|
-
'method': 'order.status',
|
|
1892
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1893
|
-
};
|
|
1894
|
-
const subscription = {
|
|
1895
|
-
'method': this.handleOrderWs,
|
|
1896
|
-
};
|
|
1897
|
-
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1898
|
-
}
|
|
1899
|
-
async fetchOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1900
|
-
/**
|
|
1901
|
-
* @method
|
|
1902
|
-
* @name binance#fetchOrdersWs
|
|
1903
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#account-order-history-user_data
|
|
1904
|
-
* @description fetches information on multiple orders made by the user
|
|
1905
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1906
|
-
* @param {int|undefined} [since] the earliest time in ms to fetch orders for
|
|
1907
|
-
* @param {int|undefined} [limit] the maximum number of order structures to retrieve
|
|
1908
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1909
|
-
* @param {int} [params.orderId] order id to begin at
|
|
1910
|
-
* @param {int} [params.startTime] earliest time in ms to retrieve orders for
|
|
1911
|
-
* @param {int} [params.endTime] latest time in ms to retrieve orders for
|
|
1912
|
-
* @param {int} [params.limit] the maximum number of order structures to retrieve
|
|
1913
|
-
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1914
|
-
*/
|
|
1915
|
-
await this.loadMarkets();
|
|
1916
|
-
if (symbol === undefined) {
|
|
1917
|
-
throw new errors.BadRequest(this.id + ' fetchOrdersWs requires a symbol');
|
|
1918
|
-
}
|
|
1919
|
-
this.checkIsSpot('fetchOrdersWs', symbol, params);
|
|
1920
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1921
|
-
const requestId = this.requestId(url);
|
|
1922
|
-
const messageHash = requestId.toString();
|
|
1923
|
-
let returnRateLimits = false;
|
|
1924
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
|
|
1925
|
-
const payload = {
|
|
1926
|
-
'symbol': this.marketId(symbol),
|
|
1927
|
-
'returnRateLimits': returnRateLimits,
|
|
1928
|
-
};
|
|
1929
|
-
const message = {
|
|
1930
|
-
'id': messageHash,
|
|
1931
|
-
'method': 'allOrders',
|
|
1932
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1933
|
-
};
|
|
1934
|
-
const subscription = {
|
|
1935
|
-
'method': this.handleOrdersWs,
|
|
1936
|
-
};
|
|
1937
|
-
const orders = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1938
|
-
return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
|
|
1939
|
-
}
|
|
1940
|
-
async fetchOpenOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1941
|
-
/**
|
|
1942
|
-
* @method
|
|
1943
|
-
* @name binance#fetchOpenOrdersWs
|
|
1944
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#current-open-orders-user_data
|
|
1945
|
-
* @description fetch all unfilled currently open orders
|
|
1946
|
-
* @param {string} symbol unified market symbol
|
|
1947
|
-
* @param {int|undefined} [since] the earliest time in ms to fetch open orders for
|
|
1948
|
-
* @param {int|undefined} [limit] the maximum number of open orders structures to retrieve
|
|
1949
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1950
|
-
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1951
|
-
*/
|
|
1952
|
-
await this.loadMarkets();
|
|
1953
|
-
this.checkIsSpot('fetchOpenOrdersWs', symbol);
|
|
1954
|
-
const url = this.urls['api']['ws']['ws'];
|
|
1955
|
-
const requestId = this.requestId(url);
|
|
1956
|
-
const messageHash = requestId.toString();
|
|
1957
|
-
let returnRateLimits = false;
|
|
1958
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
|
|
1959
|
-
const payload = {
|
|
1960
|
-
'returnRateLimits': returnRateLimits,
|
|
1961
|
-
};
|
|
1962
|
-
if (symbol !== undefined) {
|
|
1963
|
-
payload['symbol'] = this.marketId(symbol);
|
|
1964
|
-
}
|
|
1965
|
-
const message = {
|
|
1966
|
-
'id': messageHash,
|
|
1967
|
-
'method': 'openOrders.status',
|
|
1968
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
1969
|
-
};
|
|
1970
|
-
const subscription = {
|
|
1971
|
-
'method': this.handleOrdersWs,
|
|
1972
|
-
};
|
|
1973
|
-
const orders = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1974
|
-
return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
|
|
1975
|
-
}
|
|
1976
|
-
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1977
|
-
/**
|
|
1978
|
-
* @method
|
|
1979
|
-
* @name binance#watchOrders
|
|
1980
|
-
* @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
|
|
1981
|
-
* @description watches information on multiple orders made by the user
|
|
1982
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1983
|
-
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1984
|
-
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1985
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1986
|
-
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1987
|
-
*/
|
|
1988
|
-
await this.loadMarkets();
|
|
1989
|
-
let messageHash = 'orders';
|
|
1990
|
-
let market = undefined;
|
|
1991
|
-
if (symbol !== undefined) {
|
|
1992
|
-
market = this.market(symbol);
|
|
1993
|
-
symbol = market['symbol'];
|
|
1994
|
-
messageHash += ':' + symbol;
|
|
1995
|
-
}
|
|
1996
|
-
let type = undefined;
|
|
1997
|
-
[type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
|
|
1998
|
-
let subType = undefined;
|
|
1999
|
-
[subType, params] = this.handleSubTypeAndParams('watchOrders', market, params);
|
|
2000
|
-
if (this.isLinear(type, subType)) {
|
|
2001
|
-
type = 'future';
|
|
2002
|
-
}
|
|
2003
|
-
else if (this.isInverse(type, subType)) {
|
|
2004
|
-
type = 'delivery';
|
|
2005
|
-
}
|
|
2006
|
-
params = this.extend(params, { 'type': type, 'symbol': symbol }); // needed inside authenticate for isolated margin
|
|
2007
|
-
await this.authenticate(params);
|
|
2008
|
-
let urlType = type;
|
|
2009
|
-
if (type === 'margin') {
|
|
2010
|
-
urlType = 'spot'; // spot-margin shares the same stream as regular spot
|
|
2011
|
-
}
|
|
2012
|
-
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2013
|
-
const client = this.client(url);
|
|
2014
|
-
this.setBalanceCache(client, type);
|
|
2015
|
-
this.setPositionsCache(client, type);
|
|
2016
|
-
const message = undefined;
|
|
2017
|
-
const orders = await this.watch(url, messageHash, message, type);
|
|
2018
|
-
if (this.newUpdates) {
|
|
2019
|
-
limit = orders.getLimit(symbol, limit);
|
|
2020
|
-
}
|
|
2021
|
-
return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
|
|
2022
|
-
}
|
|
2023
|
-
parseWsOrder(order, market = undefined) {
|
|
2024
|
-
//
|
|
2025
|
-
// spot
|
|
2026
|
-
//
|
|
2027
|
-
// {
|
|
2028
|
-
// "e": "executionReport", // Event type
|
|
2029
|
-
// "E": 1499405658658, // Event time
|
|
2030
|
-
// "s": "ETHBTC", // Symbol
|
|
2031
|
-
// "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
|
|
2032
|
-
// "S": "BUY", // Side
|
|
2033
|
-
// "o": "LIMIT", // Order type
|
|
2034
|
-
// "f": "GTC", // Time in force
|
|
2035
|
-
// "q": "1.00000000", // Order quantity
|
|
2036
|
-
// "p": "0.10264410", // Order price
|
|
2037
|
-
// "P": "0.00000000", // Stop price
|
|
2038
|
-
// "F": "0.00000000", // Iceberg quantity
|
|
2039
|
-
// "g": -1, // OrderListId
|
|
2040
|
-
// "C": null, // Original client order ID; This is the ID of the order being canceled
|
|
2041
|
-
// "x": "NEW", // Current execution type
|
|
2042
|
-
// "X": "NEW", // Current order status
|
|
2043
|
-
// "r": "NONE", // Order reject reason; will be an error code.
|
|
2044
|
-
// "i": 4293153, // Order ID
|
|
2045
|
-
// "l": "0.00000000", // Last executed quantity
|
|
2046
|
-
// "z": "0.00000000", // Cumulative filled quantity
|
|
2047
|
-
// "L": "0.00000000", // Last executed price
|
|
2048
|
-
// "n": "0", // Commission amount
|
|
2049
|
-
// "N": null, // Commission asset
|
|
2050
|
-
// "T": 1499405658657, // Transaction time
|
|
2051
|
-
// "t": -1, // Trade ID
|
|
2052
|
-
// "I": 8641984, // Ignore
|
|
2053
|
-
// "w": true, // Is the order on the book?
|
|
2054
|
-
// "m": false, // Is this trade the maker side?
|
|
2055
|
-
// "M": false, // Ignore
|
|
2056
|
-
// "O": 1499405658657, // Order creation time
|
|
2057
|
-
// "Z": "0.00000000", // Cumulative quote asset transacted quantity
|
|
2058
|
-
// "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
|
|
2059
|
-
// "Q": "0.00000000" // Quote Order Qty
|
|
2060
|
-
// }
|
|
2061
|
-
//
|
|
2062
|
-
// future
|
|
2063
|
-
//
|
|
2064
|
-
// {
|
|
2065
|
-
// "s":"BTCUSDT", // Symbol
|
|
2066
|
-
// "c":"TEST", // Client Order Id
|
|
2067
|
-
// // special client order id:
|
|
2068
|
-
// // starts with "autoclose-": liquidation order
|
|
2069
|
-
// // "adl_autoclose": ADL auto close order
|
|
2070
|
-
// "S":"SELL", // Side
|
|
2071
|
-
// "o":"TRAILING_STOP_MARKET", // Order Type
|
|
2072
|
-
// "f":"GTC", // Time in Force
|
|
2073
|
-
// "q":"0.001", // Original Quantity
|
|
2074
|
-
// "p":"0", // Original Price
|
|
2075
|
-
// "ap":"0", // Average Price
|
|
2076
|
-
// "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
|
2077
|
-
// "x":"NEW", // Execution Type
|
|
2078
|
-
// "X":"NEW", // Order Status
|
|
2079
|
-
// "i":8886774, // Order Id
|
|
2080
|
-
// "l":"0", // Order Last Filled Quantity
|
|
2081
|
-
// "z":"0", // Order Filled Accumulated Quantity
|
|
2082
|
-
// "L":"0", // Last Filled Price
|
|
2083
|
-
// "N":"USDT", // Commission Asset, will not push if no commission
|
|
2084
|
-
// "n":"0", // Commission, will not push if no commission
|
|
2085
|
-
// "T":1568879465651, // Order Trade Time
|
|
2086
|
-
// "t":0, // Trade Id
|
|
2087
|
-
// "b":"0", // Bids Notional
|
|
2088
|
-
// "a":"9.91", // Ask Notional
|
|
2089
|
-
// "m":false, // Is this trade the maker side?
|
|
2090
|
-
// "R":false, // Is this reduce only
|
|
2091
|
-
// "wt":"CONTRACT_PRICE", // Stop Price Working Type
|
|
2092
|
-
// "ot":"TRAILING_STOP_MARKET", // Original Order Type
|
|
2093
|
-
// "ps":"LONG", // Position Side
|
|
2094
|
-
// "cp":false, // If Close-All, pushed with conditional order
|
|
2095
|
-
// "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
|
|
2096
|
-
// "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
|
2097
|
-
// "rp":"0" // Realized Profit of the trade
|
|
2098
|
-
// }
|
|
2099
|
-
//
|
|
2100
|
-
const executionType = this.safeString(order, 'x');
|
|
2101
|
-
const orderId = this.safeString(order, 'i');
|
|
2102
|
-
const marketId = this.safeString(order, 's');
|
|
2103
|
-
const marketType = ('ps' in order) ? 'contract' : 'spot';
|
|
2104
|
-
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
2105
|
-
let timestamp = this.safeInteger(order, 'O');
|
|
2106
|
-
const T = this.safeInteger(order, 'T');
|
|
2107
|
-
let lastTradeTimestamp = undefined;
|
|
2108
|
-
if (executionType === 'NEW' || executionType === 'AMENDMENT' || executionType === 'CANCELED') {
|
|
2109
|
-
if (timestamp === undefined) {
|
|
2110
|
-
timestamp = T;
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
else if (executionType === 'TRADE') {
|
|
2114
|
-
lastTradeTimestamp = T;
|
|
2115
|
-
}
|
|
2116
|
-
const lastUpdateTimestamp = T;
|
|
2117
|
-
let fee = undefined;
|
|
2118
|
-
const feeCost = this.safeString(order, 'n');
|
|
2119
|
-
if ((feeCost !== undefined) && (Precise["default"].stringGt(feeCost, '0'))) {
|
|
2120
|
-
const feeCurrencyId = this.safeString(order, 'N');
|
|
2121
|
-
const feeCurrency = this.safeCurrencyCode(feeCurrencyId);
|
|
2122
|
-
fee = {
|
|
2123
|
-
'cost': feeCost,
|
|
2124
|
-
'currency': feeCurrency,
|
|
2125
|
-
};
|
|
2126
|
-
}
|
|
2127
|
-
const price = this.safeString(order, 'p');
|
|
2128
|
-
const amount = this.safeString(order, 'q');
|
|
2129
|
-
const side = this.safeStringLower(order, 'S');
|
|
2130
|
-
const type = this.safeStringLower(order, 'o');
|
|
2131
|
-
const filled = this.safeString(order, 'z');
|
|
2132
|
-
const cost = this.safeString(order, 'Z');
|
|
2133
|
-
const average = this.safeString(order, 'ap');
|
|
2134
|
-
const rawStatus = this.safeString(order, 'X');
|
|
2135
|
-
const status = this.parseOrderStatus(rawStatus);
|
|
2136
|
-
const trades = undefined;
|
|
2137
|
-
let clientOrderId = this.safeString(order, 'C');
|
|
2138
|
-
if ((clientOrderId === undefined) || (clientOrderId.length === 0)) {
|
|
2139
|
-
clientOrderId = this.safeString(order, 'c');
|
|
2140
|
-
}
|
|
2141
|
-
const stopPrice = this.safeString2(order, 'P', 'sp');
|
|
2142
|
-
let timeInForce = this.safeString(order, 'f');
|
|
2143
|
-
if (timeInForce === 'GTX') {
|
|
2144
|
-
// GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
|
|
2145
|
-
timeInForce = 'PO';
|
|
2146
|
-
}
|
|
2147
|
-
return this.safeOrder({
|
|
2148
|
-
'info': order,
|
|
2149
|
-
'symbol': symbol,
|
|
2150
|
-
'id': orderId,
|
|
2151
|
-
'clientOrderId': clientOrderId,
|
|
2152
|
-
'timestamp': timestamp,
|
|
2153
|
-
'datetime': this.iso8601(timestamp),
|
|
2154
|
-
'lastTradeTimestamp': lastTradeTimestamp,
|
|
2155
|
-
'lastUpdateTimestamp': lastUpdateTimestamp,
|
|
2156
|
-
'type': type,
|
|
2157
|
-
'timeInForce': timeInForce,
|
|
2158
|
-
'postOnly': undefined,
|
|
2159
|
-
'reduceOnly': this.safeValue(order, 'R'),
|
|
2160
|
-
'side': side,
|
|
2161
|
-
'price': price,
|
|
2162
|
-
'stopPrice': stopPrice,
|
|
2163
|
-
'triggerPrice': stopPrice,
|
|
2164
|
-
'amount': amount,
|
|
2165
|
-
'cost': cost,
|
|
2166
|
-
'average': average,
|
|
2167
|
-
'filled': filled,
|
|
2168
|
-
'remaining': undefined,
|
|
2169
|
-
'status': status,
|
|
2170
|
-
'fee': fee,
|
|
2171
|
-
'trades': trades,
|
|
2172
|
-
});
|
|
2173
|
-
}
|
|
2174
|
-
handleOrderUpdate(client, message) {
|
|
2175
|
-
//
|
|
2176
|
-
// spot
|
|
2177
|
-
//
|
|
2178
|
-
// {
|
|
2179
|
-
// "e": "executionReport", // Event type
|
|
2180
|
-
// "E": 1499405658658, // Event time
|
|
2181
|
-
// "s": "ETHBTC", // Symbol
|
|
2182
|
-
// "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
|
|
2183
|
-
// "S": "BUY", // Side
|
|
2184
|
-
// "o": "LIMIT", // Order type
|
|
2185
|
-
// "f": "GTC", // Time in force
|
|
2186
|
-
// "q": "1.00000000", // Order quantity
|
|
2187
|
-
// "p": "0.10264410", // Order price
|
|
2188
|
-
// "P": "0.00000000", // Stop price
|
|
2189
|
-
// "F": "0.00000000", // Iceberg quantity
|
|
2190
|
-
// "g": -1, // OrderListId
|
|
2191
|
-
// "C": null, // Original client order ID; This is the ID of the order being canceled
|
|
2192
|
-
// "x": "NEW", // Current execution type
|
|
2193
|
-
// "X": "NEW", // Current order status
|
|
2194
|
-
// "r": "NONE", // Order reject reason; will be an error code.
|
|
2195
|
-
// "i": 4293153, // Order ID
|
|
2196
|
-
// "l": "0.00000000", // Last executed quantity
|
|
2197
|
-
// "z": "0.00000000", // Cumulative filled quantity
|
|
2198
|
-
// "L": "0.00000000", // Last executed price
|
|
2199
|
-
// "n": "0", // Commission amount
|
|
2200
|
-
// "N": null, // Commission asset
|
|
2201
|
-
// "T": 1499405658657, // Transaction time
|
|
2202
|
-
// "t": -1, // Trade ID
|
|
2203
|
-
// "I": 8641984, // Ignore
|
|
2204
|
-
// "w": true, // Is the order on the book?
|
|
2205
|
-
// "m": false, // Is this trade the maker side?
|
|
2206
|
-
// "M": false, // Ignore
|
|
2207
|
-
// "O": 1499405658657, // Order creation time
|
|
2208
|
-
// "Z": "0.00000000", // Cumulative quote asset transacted quantity
|
|
2209
|
-
// "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
|
|
2210
|
-
// "Q": "0.00000000" // Quote Order Qty
|
|
2211
|
-
// }
|
|
2212
|
-
//
|
|
2213
|
-
// future
|
|
2214
|
-
//
|
|
2215
|
-
// {
|
|
2216
|
-
// "e":"ORDER_TRADE_UPDATE", // Event Type
|
|
2217
|
-
// "E":1568879465651, // Event Time
|
|
2218
|
-
// "T":1568879465650, // Trasaction Time
|
|
2219
|
-
// "o": {
|
|
2220
|
-
// "s":"BTCUSDT", // Symbol
|
|
2221
|
-
// "c":"TEST", // Client Order Id
|
|
2222
|
-
// // special client order id:
|
|
2223
|
-
// // starts with "autoclose-": liquidation order
|
|
2224
|
-
// // "adl_autoclose": ADL auto close order
|
|
2225
|
-
// "S":"SELL", // Side
|
|
2226
|
-
// "o":"TRAILING_STOP_MARKET", // Order Type
|
|
2227
|
-
// "f":"GTC", // Time in Force
|
|
2228
|
-
// "q":"0.001", // Original Quantity
|
|
2229
|
-
// "p":"0", // Original Price
|
|
2230
|
-
// "ap":"0", // Average Price
|
|
2231
|
-
// "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
|
2232
|
-
// "x":"NEW", // Execution Type
|
|
2233
|
-
// "X":"NEW", // Order Status
|
|
2234
|
-
// "i":8886774, // Order Id
|
|
2235
|
-
// "l":"0", // Order Last Filled Quantity
|
|
2236
|
-
// "z":"0", // Order Filled Accumulated Quantity
|
|
2237
|
-
// "L":"0", // Last Filled Price
|
|
2238
|
-
// "N":"USDT", // Commission Asset, will not push if no commission
|
|
2239
|
-
// "n":"0", // Commission, will not push if no commission
|
|
2240
|
-
// "T":1568879465651, // Order Trade Time
|
|
2241
|
-
// "t":0, // Trade Id
|
|
2242
|
-
// "b":"0", // Bids Notional
|
|
2243
|
-
// "a":"9.91", // Ask Notional
|
|
2244
|
-
// "m":false, // Is this trade the maker side?
|
|
2245
|
-
// "R":false, // Is this reduce only
|
|
2246
|
-
// "wt":"CONTRACT_PRICE", // Stop Price Working Type
|
|
2247
|
-
// "ot":"TRAILING_STOP_MARKET", // Original Order Type
|
|
2248
|
-
// "ps":"LONG", // Position Side
|
|
2249
|
-
// "cp":false, // If Close-All, pushed with conditional order
|
|
2250
|
-
// "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
|
|
2251
|
-
// "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
|
2252
|
-
// "rp":"0" // Realized Profit of the trade
|
|
2253
|
-
// }
|
|
2254
|
-
// }
|
|
2255
|
-
//
|
|
2256
|
-
const e = this.safeString(message, 'e');
|
|
2257
|
-
if (e === 'ORDER_TRADE_UPDATE') {
|
|
2258
|
-
message = this.safeValue(message, 'o', message);
|
|
2259
|
-
}
|
|
2260
|
-
this.handleMyTrade(client, message);
|
|
2261
|
-
this.handleOrder(client, message);
|
|
2262
|
-
}
|
|
2263
|
-
async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2264
|
-
/**
|
|
2265
|
-
* @method
|
|
2266
|
-
* @name binance#watchPositions
|
|
2267
|
-
* @description watch all open positions
|
|
2268
|
-
* @param {string[]|undefined} symbols list of unified market symbols
|
|
2269
|
-
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
2270
|
-
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
2271
|
-
*/
|
|
2272
|
-
await this.loadMarkets();
|
|
2273
|
-
await this.authenticate(params);
|
|
2274
|
-
let market = undefined;
|
|
2275
|
-
let messageHash = '';
|
|
2276
|
-
symbols = this.marketSymbols(symbols);
|
|
2277
|
-
if (!this.isEmpty(symbols)) {
|
|
2278
|
-
market = this.getMarketFromSymbols(symbols);
|
|
2279
|
-
messageHash = '::' + symbols.join(',');
|
|
2280
|
-
}
|
|
2281
|
-
let type = undefined;
|
|
2282
|
-
[type, params] = this.handleMarketTypeAndParams('watchPositions', market, params);
|
|
2283
|
-
if (type === 'spot' || type === 'margin') {
|
|
2284
|
-
type = 'future';
|
|
2285
|
-
}
|
|
2286
|
-
let subType = undefined;
|
|
2287
|
-
[subType, params] = this.handleSubTypeAndParams('watchPositions', market, params);
|
|
2288
|
-
if (this.isLinear(type, subType)) {
|
|
2289
|
-
type = 'future';
|
|
2290
|
-
}
|
|
2291
|
-
else if (this.isInverse(type, subType)) {
|
|
2292
|
-
type = 'delivery';
|
|
2293
|
-
}
|
|
2294
|
-
messageHash = type + ':positions' + messageHash;
|
|
2295
|
-
const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
|
|
2296
|
-
const client = this.client(url);
|
|
2297
|
-
this.setBalanceCache(client, type);
|
|
2298
|
-
this.setPositionsCache(client, type, symbols);
|
|
2299
|
-
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
|
|
2300
|
-
const awaitPositionsSnapshot = this.safeValue('watchPositions', 'awaitPositionsSnapshot', true);
|
|
2301
|
-
const cache = this.safeValue(this.positions, type);
|
|
2302
|
-
if (fetchPositionsSnapshot && awaitPositionsSnapshot && cache === undefined) {
|
|
2303
|
-
const snapshot = await client.future(type + ':fetchPositionsSnapshot');
|
|
2304
|
-
return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
|
|
2305
|
-
}
|
|
2306
|
-
const newPositions = await this.watch(url, messageHash, undefined, type);
|
|
2307
|
-
if (this.newUpdates) {
|
|
2308
|
-
return newPositions;
|
|
2309
|
-
}
|
|
2310
|
-
return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
|
|
2311
|
-
}
|
|
2312
|
-
setPositionsCache(client, type, symbols = undefined) {
|
|
2313
|
-
if (type === 'spot') {
|
|
2314
|
-
return;
|
|
2315
|
-
}
|
|
2316
|
-
if (this.positions === undefined) {
|
|
2317
|
-
this.positions = {};
|
|
2318
|
-
}
|
|
2319
|
-
if (type in this.positions) {
|
|
2320
|
-
return;
|
|
2321
|
-
}
|
|
2322
|
-
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', false);
|
|
2323
|
-
if (fetchPositionsSnapshot) {
|
|
2324
|
-
const messageHash = type + ':fetchPositionsSnapshot';
|
|
2325
|
-
if (!(messageHash in client.futures)) {
|
|
2326
|
-
client.future(messageHash);
|
|
2327
|
-
this.spawn(this.loadPositionsSnapshot, client, messageHash, type);
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
else {
|
|
2331
|
-
this.positions[type] = new Cache.ArrayCacheBySymbolBySide();
|
|
2332
|
-
}
|
|
2333
|
-
}
|
|
2334
|
-
async loadPositionsSnapshot(client, messageHash, type) {
|
|
2335
|
-
const positions = await this.fetchPositions(undefined, { 'type': type });
|
|
2336
|
-
this.positions[type] = new Cache.ArrayCacheBySymbolBySide();
|
|
2337
|
-
const cache = this.positions[type];
|
|
2338
|
-
for (let i = 0; i < positions.length; i++) {
|
|
2339
|
-
const position = positions[i];
|
|
2340
|
-
const contracts = this.safeNumber(position, 'contracts', 0);
|
|
2341
|
-
if (contracts > 0) {
|
|
2342
|
-
cache.append(position);
|
|
2343
|
-
}
|
|
2344
|
-
}
|
|
2345
|
-
// don't remove the future from the .futures cache
|
|
2346
|
-
const future = client.futures[messageHash];
|
|
2347
|
-
future.resolve(cache);
|
|
2348
|
-
client.resolve(cache, type + ':position');
|
|
2349
|
-
}
|
|
2350
|
-
handlePositions(client, message) {
|
|
2351
|
-
//
|
|
2352
|
-
// {
|
|
2353
|
-
// e: 'ACCOUNT_UPDATE',
|
|
2354
|
-
// T: 1667881353112,
|
|
2355
|
-
// E: 1667881353115,
|
|
2356
|
-
// a: {
|
|
2357
|
-
// B: [{
|
|
2358
|
-
// a: 'USDT',
|
|
2359
|
-
// wb: '1127.95750089',
|
|
2360
|
-
// cw: '1040.82091149',
|
|
2361
|
-
// bc: '0'
|
|
2362
|
-
// }],
|
|
2363
|
-
// P: [{
|
|
2364
|
-
// s: 'BTCUSDT',
|
|
2365
|
-
// pa: '-0.089',
|
|
2366
|
-
// ep: '19700.03933',
|
|
2367
|
-
// cr: '-1260.24809979',
|
|
2368
|
-
// up: '1.53058860',
|
|
2369
|
-
// mt: 'isolated',
|
|
2370
|
-
// iw: '87.13658940',
|
|
2371
|
-
// ps: 'BOTH',
|
|
2372
|
-
// ma: 'USDT'
|
|
2373
|
-
// }],
|
|
2374
|
-
// m: 'ORDER'
|
|
2375
|
-
// }
|
|
2376
|
-
// }
|
|
2377
|
-
//
|
|
2378
|
-
// each account is connected to a different endpoint
|
|
2379
|
-
// and has exactly one subscriptionhash which is the account type
|
|
2380
|
-
const subscriptions = Object.keys(client.subscriptions);
|
|
2381
|
-
const accountType = subscriptions[0];
|
|
2382
|
-
if (this.positions === undefined) {
|
|
2383
|
-
this.positions = {};
|
|
2384
|
-
}
|
|
2385
|
-
if (!(accountType in this.positions)) {
|
|
2386
|
-
this.positions[accountType] = new Cache.ArrayCacheBySymbolBySide();
|
|
2387
|
-
}
|
|
2388
|
-
const cache = this.positions[accountType];
|
|
2389
|
-
const data = this.safeValue(message, 'a', {});
|
|
2390
|
-
const rawPositions = this.safeValue(data, 'P', []);
|
|
2391
|
-
const newPositions = [];
|
|
2392
|
-
for (let i = 0; i < rawPositions.length; i++) {
|
|
2393
|
-
const rawPosition = rawPositions[i];
|
|
2394
|
-
const position = this.parseWsPosition(rawPosition);
|
|
2395
|
-
const timestamp = this.safeInteger(message, 'E');
|
|
2396
|
-
position['timestamp'] = timestamp;
|
|
2397
|
-
position['datetime'] = this.iso8601(timestamp);
|
|
2398
|
-
newPositions.push(position);
|
|
2399
|
-
cache.append(position);
|
|
2400
|
-
}
|
|
2401
|
-
const messageHashes = this.findMessageHashes(client, accountType + ':positions::');
|
|
2402
|
-
for (let i = 0; i < messageHashes.length; i++) {
|
|
2403
|
-
const messageHash = messageHashes[i];
|
|
2404
|
-
const parts = messageHash.split('::');
|
|
2405
|
-
const symbolsString = parts[1];
|
|
2406
|
-
const symbols = symbolsString.split(',');
|
|
2407
|
-
const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
|
|
2408
|
-
if (!this.isEmpty(positions)) {
|
|
2409
|
-
client.resolve(positions, messageHash);
|
|
2410
|
-
}
|
|
2411
|
-
}
|
|
2412
|
-
client.resolve(newPositions, accountType + ':positions');
|
|
2413
|
-
}
|
|
2414
|
-
parseWsPosition(position, market = undefined) {
|
|
2415
|
-
//
|
|
2416
|
-
// {
|
|
2417
|
-
// "s": "BTCUSDT", // Symbol
|
|
2418
|
-
// "pa": "0", // Position Amount
|
|
2419
|
-
// "ep": "0.00000", // Entry Price
|
|
2420
|
-
// "cr": "200", // (Pre-fee) Accumulated Realized
|
|
2421
|
-
// "up": "0", // Unrealized PnL
|
|
2422
|
-
// "mt": "isolated", // Margin Type
|
|
2423
|
-
// "iw": "0.00000000", // Isolated Wallet (if isolated position)
|
|
2424
|
-
// "ps": "BOTH" // Position Side
|
|
2425
|
-
// }
|
|
2426
|
-
//
|
|
2427
|
-
const marketId = this.safeString(position, 's');
|
|
2428
|
-
const positionSide = this.safeStringLower(position, 'ps');
|
|
2429
|
-
const hedged = positionSide !== 'both';
|
|
2430
|
-
return this.safePosition({
|
|
2431
|
-
'info': position,
|
|
2432
|
-
'id': undefined,
|
|
2433
|
-
'symbol': this.safeSymbol(marketId, undefined, undefined, 'future'),
|
|
2434
|
-
'notional': undefined,
|
|
2435
|
-
'marginMode': this.safeString(position, 'mt'),
|
|
2436
|
-
'liquidationPrice': undefined,
|
|
2437
|
-
'entryPrice': this.safeNumber(position, 'ep'),
|
|
2438
|
-
'unrealizedPnl': this.safeNumber(position, 'up'),
|
|
2439
|
-
'percentage': undefined,
|
|
2440
|
-
'contracts': this.safeNumber(position, 'pa'),
|
|
2441
|
-
'contractSize': undefined,
|
|
2442
|
-
'markPrice': undefined,
|
|
2443
|
-
'side': positionSide,
|
|
2444
|
-
'hedged': hedged,
|
|
2445
|
-
'timestamp': undefined,
|
|
2446
|
-
'datetime': undefined,
|
|
2447
|
-
'maintenanceMargin': undefined,
|
|
2448
|
-
'maintenanceMarginPercentage': undefined,
|
|
2449
|
-
'collateral': undefined,
|
|
2450
|
-
'initialMargin': undefined,
|
|
2451
|
-
'initialMarginPercentage': undefined,
|
|
2452
|
-
'leverage': undefined,
|
|
2453
|
-
'marginRatio': undefined,
|
|
2454
|
-
});
|
|
2455
|
-
}
|
|
2456
|
-
async fetchMyTradesWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2457
|
-
/**
|
|
2458
|
-
* @method
|
|
2459
|
-
* @name binance#fetchMyTradesWs
|
|
2460
|
-
* @see https://binance-docs.github.io/apidocs/websocket_api/en/#account-trade-history-user_data
|
|
2461
|
-
* @description fetch all trades made by the user
|
|
2462
|
-
* @param {string} symbol unified market symbol
|
|
2463
|
-
* @param {int|undefined} [since] the earliest time in ms to fetch trades for
|
|
2464
|
-
* @param {int|undefined} [limit] the maximum number of trades structures to retrieve
|
|
2465
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2466
|
-
* @param {int} [params.endTime] the latest time in ms to fetch trades for
|
|
2467
|
-
* @param {int} [params.fromId] first trade Id to fetch
|
|
2468
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2469
|
-
*/
|
|
2470
|
-
await this.loadMarkets();
|
|
2471
|
-
if (symbol === undefined) {
|
|
2472
|
-
throw new errors.BadRequest(this.id + ' fetchMyTradesWs requires a symbol');
|
|
2473
|
-
}
|
|
2474
|
-
this.checkIsSpot('fetchMyTradesWs', symbol, params);
|
|
2475
|
-
const url = this.urls['api']['ws']['ws'];
|
|
2476
|
-
const requestId = this.requestId(url);
|
|
2477
|
-
const messageHash = requestId.toString();
|
|
2478
|
-
let returnRateLimits = false;
|
|
2479
|
-
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchMyTradesWs', 'returnRateLimits', false);
|
|
2480
|
-
const payload = {
|
|
2481
|
-
'symbol': this.marketId(symbol),
|
|
2482
|
-
'returnRateLimits': returnRateLimits,
|
|
2483
|
-
};
|
|
2484
|
-
if (since !== undefined) {
|
|
2485
|
-
payload['startTime'] = since;
|
|
2486
|
-
}
|
|
2487
|
-
if (limit !== undefined) {
|
|
2488
|
-
payload['limit'] = limit;
|
|
2489
|
-
}
|
|
2490
|
-
const fromId = this.safeInteger(params, 'fromId');
|
|
2491
|
-
if (fromId !== undefined && since !== undefined) {
|
|
2492
|
-
throw new errors.BadRequest(this.id + 'fetchMyTradesWs does not support fetching by both fromId and since parameters at the same time');
|
|
2493
|
-
}
|
|
2494
|
-
const message = {
|
|
2495
|
-
'id': messageHash,
|
|
2496
|
-
'method': 'myTrades',
|
|
2497
|
-
'params': this.signParams(this.extend(payload, params)),
|
|
2498
|
-
};
|
|
2499
|
-
const subscription = {
|
|
2500
|
-
'method': this.handleTradesWs,
|
|
2501
|
-
};
|
|
2502
|
-
const trades = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
2503
|
-
return this.filterBySymbolSinceLimit(trades, symbol, since, limit);
|
|
2504
|
-
}
|
|
2505
|
-
handleTradesWs(client, message) {
|
|
2506
|
-
//
|
|
2507
|
-
// {
|
|
2508
|
-
// "id": "f4ce6a53-a29d-4f70-823b-4ab59391d6e8",
|
|
2509
|
-
// "status": 200,
|
|
2510
|
-
// "result": [{
|
|
2511
|
-
// "symbol": "BTCUSDT",
|
|
2512
|
-
// "id": 1650422481,
|
|
2513
|
-
// "orderId": 12569099453,
|
|
2514
|
-
// "orderListId": -1,
|
|
2515
|
-
// "price": "23416.10000000",
|
|
2516
|
-
// "qty": "0.00635000",
|
|
2517
|
-
// "quoteQty": "148.69223500",
|
|
2518
|
-
// "commission": "0.00000000",
|
|
2519
|
-
// "commissionAsset": "BNB",
|
|
2520
|
-
// "time": 1660801715793,
|
|
2521
|
-
// "isBuyer": false,
|
|
2522
|
-
// "isMaker": true,
|
|
2523
|
-
// "isBestMatch": true
|
|
2524
|
-
// },
|
|
2525
|
-
// ...
|
|
2526
|
-
// ],
|
|
2527
|
-
// }
|
|
2528
|
-
//
|
|
2529
|
-
const messageHash = this.safeString(message, 'id');
|
|
2530
|
-
const result = this.safeValue(message, 'result', []);
|
|
2531
|
-
const trades = this.parseTrades(result);
|
|
2532
|
-
client.resolve(trades, messageHash);
|
|
2533
|
-
}
|
|
2534
|
-
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2535
|
-
/**
|
|
2536
|
-
* @method
|
|
2537
|
-
* @name binance#watchMyTrades
|
|
2538
|
-
* @description watches information on multiple trades made by the user
|
|
2539
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
2540
|
-
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2541
|
-
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
2542
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2543
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
2544
|
-
*/
|
|
2545
|
-
await this.loadMarkets();
|
|
2546
|
-
let type = undefined;
|
|
2547
|
-
let market = undefined;
|
|
2548
|
-
if (symbol !== undefined) {
|
|
2549
|
-
market = this.market(symbol);
|
|
2550
|
-
symbol = market['symbol'];
|
|
2551
|
-
}
|
|
2552
|
-
[type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
|
|
2553
|
-
let subType = undefined;
|
|
2554
|
-
[subType, params] = this.handleSubTypeAndParams('watchMyTrades', market, params);
|
|
2555
|
-
if (this.isLinear(type, subType)) {
|
|
2556
|
-
type = 'future';
|
|
2557
|
-
}
|
|
2558
|
-
else if (this.isInverse(type, subType)) {
|
|
2559
|
-
type = 'delivery';
|
|
2560
|
-
}
|
|
2561
|
-
let messageHash = 'myTrades';
|
|
2562
|
-
if (symbol !== undefined) {
|
|
2563
|
-
symbol = this.symbol(symbol);
|
|
2564
|
-
messageHash += ':' + symbol;
|
|
2565
|
-
params = this.extend(params, { 'type': market['type'], 'symbol': symbol });
|
|
2566
|
-
}
|
|
2567
|
-
await this.authenticate(params);
|
|
2568
|
-
let urlType = type; // we don't change type because the listening key is different
|
|
2569
|
-
if (type === 'margin') {
|
|
2570
|
-
urlType = 'spot'; // spot-margin shares the same stream as regular spot
|
|
2571
|
-
}
|
|
2572
|
-
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2573
|
-
const client = this.client(url);
|
|
2574
|
-
this.setBalanceCache(client, type);
|
|
2575
|
-
this.setPositionsCache(client, type);
|
|
2576
|
-
const message = undefined;
|
|
2577
|
-
const trades = await this.watch(url, messageHash, message, type);
|
|
2578
|
-
if (this.newUpdates) {
|
|
2579
|
-
limit = trades.getLimit(symbol, limit);
|
|
2580
|
-
}
|
|
2581
|
-
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
|
|
2582
|
-
}
|
|
2583
|
-
handleMyTrade(client, message) {
|
|
2584
|
-
const messageHash = 'myTrades';
|
|
2585
|
-
const executionType = this.safeString(message, 'x');
|
|
2586
|
-
if (executionType === 'TRADE') {
|
|
2587
|
-
const trade = this.parseTrade(message);
|
|
2588
|
-
const orderId = this.safeString(trade, 'order');
|
|
2589
|
-
let tradeFee = this.safeValue(trade, 'fee');
|
|
2590
|
-
tradeFee = this.extend({}, tradeFee);
|
|
2591
|
-
const symbol = this.safeString(trade, 'symbol');
|
|
2592
|
-
if (orderId !== undefined && tradeFee !== undefined && symbol !== undefined) {
|
|
2593
|
-
const cachedOrders = this.orders;
|
|
2594
|
-
if (cachedOrders !== undefined) {
|
|
2595
|
-
const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
|
|
2596
|
-
const order = this.safeValue(orders, orderId);
|
|
2597
|
-
if (order !== undefined) {
|
|
2598
|
-
// accumulate order fees
|
|
2599
|
-
const fees = this.safeValue(order, 'fees');
|
|
2600
|
-
const fee = this.safeValue(order, 'fee');
|
|
2601
|
-
if (!this.isEmpty(fees)) {
|
|
2602
|
-
let insertNewFeeCurrency = true;
|
|
2603
|
-
for (let i = 0; i < fees.length; i++) {
|
|
2604
|
-
const orderFee = fees[i];
|
|
2605
|
-
if (orderFee['currency'] === tradeFee['currency']) {
|
|
2606
|
-
const feeCost = this.sum(tradeFee['cost'], orderFee['cost']);
|
|
2607
|
-
order['fees'][i]['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
|
|
2608
|
-
insertNewFeeCurrency = false;
|
|
2609
|
-
break;
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2612
|
-
if (insertNewFeeCurrency) {
|
|
2613
|
-
order['fees'].push(tradeFee);
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
else if (fee !== undefined) {
|
|
2617
|
-
if (fee['currency'] === tradeFee['currency']) {
|
|
2618
|
-
const feeCost = this.sum(fee['cost'], tradeFee['cost']);
|
|
2619
|
-
order['fee']['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
|
|
2620
|
-
}
|
|
2621
|
-
else if (fee['currency'] === undefined) {
|
|
2622
|
-
order['fee'] = tradeFee;
|
|
2623
|
-
}
|
|
2624
|
-
else {
|
|
2625
|
-
order['fees'] = [fee, tradeFee];
|
|
2626
|
-
order['fee'] = undefined;
|
|
2627
|
-
}
|
|
2628
|
-
}
|
|
2629
|
-
else {
|
|
2630
|
-
order['fee'] = tradeFee;
|
|
2631
|
-
}
|
|
2632
|
-
// save this trade in the order
|
|
2633
|
-
const orderTrades = this.safeValue(order, 'trades', []);
|
|
2634
|
-
orderTrades.push(trade);
|
|
2635
|
-
order['trades'] = orderTrades;
|
|
2636
|
-
// don't append twice cause it breaks newUpdates mode
|
|
2637
|
-
// this order already exists in the cache
|
|
2638
|
-
}
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
if (this.myTrades === undefined) {
|
|
2642
|
-
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
2643
|
-
this.myTrades = new Cache.ArrayCacheBySymbolById(limit);
|
|
2644
|
-
}
|
|
2645
|
-
const myTrades = this.myTrades;
|
|
2646
|
-
myTrades.append(trade);
|
|
2647
|
-
client.resolve(this.myTrades, messageHash);
|
|
2648
|
-
const messageHashSymbol = messageHash + ':' + symbol;
|
|
2649
|
-
client.resolve(this.myTrades, messageHashSymbol);
|
|
2650
|
-
}
|
|
2651
|
-
}
|
|
2652
|
-
handleOrder(client, message) {
|
|
2653
|
-
const parsed = this.parseWsOrder(message);
|
|
2654
|
-
const symbol = this.safeString(parsed, 'symbol');
|
|
2655
|
-
const orderId = this.safeString(parsed, 'id');
|
|
2656
|
-
if (symbol !== undefined) {
|
|
2657
|
-
if (this.orders === undefined) {
|
|
2658
|
-
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
|
|
2659
|
-
this.orders = new Cache.ArrayCacheBySymbolById(limit);
|
|
2660
|
-
}
|
|
2661
|
-
const cachedOrders = this.orders;
|
|
2662
|
-
const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
|
|
2663
|
-
const order = this.safeValue(orders, orderId);
|
|
2664
|
-
if (order !== undefined) {
|
|
2665
|
-
const fee = this.safeValue(order, 'fee');
|
|
2666
|
-
if (fee !== undefined) {
|
|
2667
|
-
parsed['fee'] = fee;
|
|
2668
|
-
}
|
|
2669
|
-
const fees = this.safeValue(order, 'fees');
|
|
2670
|
-
if (fees !== undefined) {
|
|
2671
|
-
parsed['fees'] = fees;
|
|
2672
|
-
}
|
|
2673
|
-
parsed['trades'] = this.safeValue(order, 'trades');
|
|
2674
|
-
const timestamp = this.safeInteger(parsed, 'timestamp');
|
|
2675
|
-
if (timestamp === undefined) {
|
|
2676
|
-
parsed['timestamp'] = this.safeInteger(order, 'timestamp');
|
|
2677
|
-
parsed['datetime'] = this.safeString(order, 'datetime');
|
|
2678
|
-
}
|
|
2679
|
-
}
|
|
2680
|
-
cachedOrders.append(parsed);
|
|
2681
|
-
const messageHash = 'orders';
|
|
2682
|
-
const symbolSpecificMessageHash = 'orders:' + symbol;
|
|
2683
|
-
client.resolve(cachedOrders, messageHash);
|
|
2684
|
-
client.resolve(cachedOrders, symbolSpecificMessageHash);
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2687
|
-
handleAcountUpdate(client, message) {
|
|
2688
|
-
this.handleBalance(client, message);
|
|
2689
|
-
this.handlePositions(client, message);
|
|
2690
|
-
}
|
|
2691
|
-
handleWsError(client, message) {
|
|
2692
|
-
//
|
|
2693
|
-
// {
|
|
2694
|
-
// "error": {
|
|
2695
|
-
// "code": 2,
|
|
2696
|
-
// "msg": "Invalid request: invalid stream"
|
|
2697
|
-
// },
|
|
2698
|
-
// "id": 1
|
|
2699
|
-
// }
|
|
2700
|
-
//
|
|
2701
|
-
const id = this.safeString(message, 'id');
|
|
2702
|
-
let rejected = false;
|
|
2703
|
-
const error = this.safeValue(message, 'error', {});
|
|
2704
|
-
const code = this.safeInteger(error, 'code');
|
|
2705
|
-
const msg = this.safeString(error, 'msg');
|
|
2706
|
-
try {
|
|
2707
|
-
this.handleErrors(code, msg, client.url, undefined, undefined, this.json(error), error, undefined, undefined);
|
|
2708
|
-
}
|
|
2709
|
-
catch (e) {
|
|
2710
|
-
rejected = true;
|
|
2711
|
-
// private endpoint uses id as messageHash
|
|
2712
|
-
client.reject(e, id);
|
|
2713
|
-
// public endpoint stores messageHash in subscriptios
|
|
2714
|
-
const subscriptionKeys = Object.keys(client.subscriptions);
|
|
2715
|
-
for (let i = 0; i < subscriptionKeys.length; i++) {
|
|
2716
|
-
const subscriptionHash = subscriptionKeys[i];
|
|
2717
|
-
const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
|
|
2718
|
-
if (id === subscriptionId) {
|
|
2719
|
-
client.reject(e, subscriptionHash);
|
|
2720
|
-
}
|
|
2721
|
-
}
|
|
2722
|
-
}
|
|
2723
|
-
if (!rejected) {
|
|
2724
|
-
client.reject(message, id);
|
|
2725
|
-
}
|
|
2726
|
-
// reset connection if 5xx error
|
|
2727
|
-
if (this.safeString(code, 0) === '5') {
|
|
2728
|
-
client.reset(message);
|
|
2729
|
-
}
|
|
2730
|
-
}
|
|
2731
|
-
handleMessage(client, message) {
|
|
2732
|
-
// handle WebSocketAPI
|
|
2733
|
-
const status = this.safeString(message, 'status');
|
|
2734
|
-
const error = this.safeValue(message, 'error');
|
|
2735
|
-
if ((error !== undefined) || (status !== undefined && status !== '200')) {
|
|
2736
|
-
return this.handleWsError(client, message);
|
|
2737
|
-
}
|
|
2738
|
-
const id = this.safeString(message, 'id');
|
|
2739
|
-
const subscriptions = this.safeValue(client.subscriptions, id);
|
|
2740
|
-
let method = this.safeValue(subscriptions, 'method');
|
|
2741
|
-
if (method !== undefined) {
|
|
2742
|
-
return method.call(this, client, message);
|
|
2743
|
-
}
|
|
2744
|
-
// handle other APIs
|
|
2745
|
-
const methods = {
|
|
2746
|
-
'depthUpdate': this.handleOrderBook,
|
|
2747
|
-
'trade': this.handleTrade,
|
|
2748
|
-
'aggTrade': this.handleTrade,
|
|
2749
|
-
'kline': this.handleOHLCV,
|
|
2750
|
-
'markPrice_kline': this.handleOHLCV,
|
|
2751
|
-
'indexPrice_kline': this.handleOHLCV,
|
|
2752
|
-
'24hrTicker@arr': this.handleTickers,
|
|
2753
|
-
'24hrMiniTicker@arr': this.handleTickers,
|
|
2754
|
-
'24hrTicker': this.handleTicker,
|
|
2755
|
-
'24hrMiniTicker': this.handleTicker,
|
|
2756
|
-
'bookTicker': this.handleTicker,
|
|
2757
|
-
'outboundAccountPosition': this.handleBalance,
|
|
2758
|
-
'balanceUpdate': this.handleBalance,
|
|
2759
|
-
'ACCOUNT_UPDATE': this.handleAcountUpdate,
|
|
2760
|
-
'executionReport': this.handleOrderUpdate,
|
|
2761
|
-
'ORDER_TRADE_UPDATE': this.handleOrderUpdate,
|
|
2762
|
-
};
|
|
2763
|
-
let event = this.safeString(message, 'e');
|
|
2764
|
-
if (Array.isArray(message)) {
|
|
2765
|
-
const data = message[0];
|
|
2766
|
-
event = this.safeString(data, 'e') + '@arr';
|
|
2767
|
-
}
|
|
2768
|
-
method = this.safeValue(methods, event);
|
|
2769
|
-
if (method === undefined) {
|
|
2770
|
-
const requestId = this.safeString(message, 'id');
|
|
2771
|
-
if (requestId !== undefined) {
|
|
2772
|
-
return this.handleSubscriptionStatus(client, message);
|
|
2773
|
-
}
|
|
2774
|
-
// special case for the real-time bookTicker, since it comes without an event identifier
|
|
2775
|
-
//
|
|
2776
|
-
// {
|
|
2777
|
-
// "u": 7488717758,
|
|
2778
|
-
// "s": "BTCUSDT",
|
|
2779
|
-
// "b": "28621.74000000",
|
|
2780
|
-
// "B": "1.43278800",
|
|
2781
|
-
// "a": "28621.75000000",
|
|
2782
|
-
// "A": "2.52500800"
|
|
2783
|
-
// }
|
|
2784
|
-
//
|
|
2785
|
-
if (event === undefined) {
|
|
2786
|
-
this.handleTicker(client, message);
|
|
2787
|
-
this.handleTickers(client, message);
|
|
2788
|
-
}
|
|
2789
|
-
}
|
|
2790
|
-
else {
|
|
2791
|
-
return method.call(this, client, message);
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
2794
|
-
}
|
|
2795
|
-
|
|
2796
|
-
module.exports = binance;
|