ccxt-ir 4.9.32 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +7 -1
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/abstract/asretether.js +11 -0
- package/dist/cjs/src/abstract/bidarz.js +11 -0
- package/dist/cjs/src/asretether.js +325 -0
- package/dist/cjs/src/bidarz.js +337 -0
- package/dist/cjs/src/bit24.js +4 -3
- package/dist/cjs/src/raastin.js +144 -16
- package/js/ccxt.d.ts +8 -2
- package/js/ccxt.js +6 -2
- package/js/src/abstract/asretether.d.ts +8 -0
- package/js/src/abstract/asretether.js +11 -0
- package/js/src/abstract/bidarz.d.ts +9 -0
- package/js/src/abstract/bidarz.js +11 -0
- package/js/src/abstract/raastin.d.ts +1 -0
- package/js/src/asretether.d.ts +21 -0
- package/js/src/asretether.js +324 -0
- package/js/src/bidarz.d.ts +22 -0
- package/js/src/bidarz.js +336 -0
- package/js/src/bit24.js +4 -3
- package/js/src/raastin.d.ts +2 -0
- package/js/src/raastin.js +144 -16
- package/js/src/src/abantether.d.ts +21 -0
- package/js/src/src/abantether.js +353 -0
- package/js/src/src/abstract/abantether.d.ts +8 -0
- package/js/src/src/abstract/abantether.js +11 -0
- package/js/src/src/abstract/afratether.d.ts +9 -0
- package/js/src/src/abstract/afratether.js +11 -0
- package/js/src/src/abstract/alpaca.d.ts +77 -0
- package/js/src/src/abstract/alpaca.js +11 -0
- package/js/src/src/abstract/apex.d.ts +34 -0
- package/js/src/src/abstract/apex.js +11 -0
- package/js/src/src/abstract/arzinja.d.ts +8 -0
- package/js/src/src/abstract/arzinja.js +11 -0
- package/js/src/src/abstract/arzplus.d.ts +11 -0
- package/js/src/src/abstract/arzplus.js +11 -0
- package/js/src/src/abstract/ascendex.d.ts +80 -0
- package/js/src/src/abstract/ascendex.js +11 -0
- package/js/src/src/abstract/asretether.d.ts +8 -0
- package/js/src/src/abstract/asretether.js +11 -0
- package/js/src/src/abstract/bidarz.d.ts +9 -0
- package/js/src/src/abstract/bidarz.js +11 -0
- package/js/src/src/abstract/bigone.d.ts +48 -0
- package/js/src/src/abstract/bigone.js +11 -0
- package/js/src/src/abstract/binance.d.ts +773 -0
- package/js/src/src/abstract/binance.js +11 -0
- package/js/src/src/abstract/bingx.d.ts +165 -0
- package/js/src/src/abstract/bingx.js +11 -0
- package/js/src/src/abstract/bit24.d.ts +9 -0
- package/js/src/src/abstract/bit24.js +11 -0
- package/js/src/src/abstract/bit2c.d.ts +30 -0
- package/js/src/src/abstract/bit2c.js +11 -0
- package/js/src/src/abstract/bitbank.d.ts +35 -0
- package/js/src/src/abstract/bitbank.js +11 -0
- package/js/src/src/abstract/bitbarg.d.ts +8 -0
- package/js/src/src/abstract/bitbarg.js +11 -0
- package/js/src/src/abstract/bitbns.d.ts +43 -0
- package/js/src/src/abstract/bitbns.js +11 -0
- package/js/src/src/abstract/bitfinex.d.ts +143 -0
- package/js/src/src/abstract/bitfinex.js +11 -0
- package/js/src/src/abstract/bitflyer.d.ts +42 -0
- package/js/src/src/abstract/bitflyer.js +11 -0
- package/js/src/src/abstract/bitget.d.ts +578 -0
- package/js/src/src/abstract/bitget.js +11 -0
- package/js/src/src/abstract/bithumb.d.ts +35 -0
- package/js/src/src/abstract/bithumb.js +11 -0
- package/js/src/src/abstract/bitimen.d.ts +10 -0
- package/js/src/src/abstract/bitimen.js +11 -0
- package/js/src/src/abstract/bitir.d.ts +10 -0
- package/js/src/src/abstract/bitir.js +11 -0
- package/js/src/src/abstract/bitmart.d.ts +120 -0
- package/js/src/src/abstract/bitmart.js +11 -0
- package/js/src/src/abstract/bitmex.d.ts +100 -0
- package/js/src/src/abstract/bitmex.js +11 -0
- package/js/src/src/abstract/bitopro.d.ts +33 -0
- package/js/src/src/abstract/bitopro.js +11 -0
- package/js/src/src/abstract/bitpin.d.ts +11 -0
- package/js/src/src/abstract/bitpin.js +11 -0
- package/js/src/src/abstract/bitrue.d.ts +75 -0
- package/js/src/src/abstract/bitrue.js +11 -0
- package/js/src/src/abstract/bitso.d.ts +46 -0
- package/js/src/src/abstract/bitso.js +11 -0
- package/js/src/src/abstract/bitstamp.d.ts +262 -0
- package/js/src/src/abstract/bitstamp.js +11 -0
- package/js/src/src/abstract/bitteam.d.ts +32 -0
- package/js/src/src/abstract/bitteam.js +11 -0
- package/js/src/src/abstract/bittrade.d.ts +117 -0
- package/js/src/src/abstract/bittrade.js +11 -0
- package/js/src/src/abstract/bitunix.d.ts +9 -0
- package/js/src/src/abstract/bitunix.js +11 -0
- package/js/src/src/abstract/bitvavo.d.ts +30 -0
- package/js/src/src/abstract/bitvavo.js +11 -0
- package/js/src/src/abstract/blockchaincom.d.ts +31 -0
- package/js/src/src/abstract/blockchaincom.js +11 -0
- package/js/src/src/abstract/blofin.d.ts +70 -0
- package/js/src/src/abstract/blofin.js +11 -0
- package/js/src/src/abstract/btcalpha.d.ts +21 -0
- package/js/src/src/abstract/btcalpha.js +11 -0
- package/js/src/src/abstract/btcbox.d.ts +18 -0
- package/js/src/src/abstract/btcbox.js +11 -0
- package/js/src/src/abstract/btcmarkets.d.ts +42 -0
- package/js/src/src/abstract/btcmarkets.js +11 -0
- package/js/src/src/abstract/btcturk.d.ts +23 -0
- package/js/src/src/abstract/btcturk.js +11 -0
- package/js/src/src/abstract/bybit.d.ts +316 -0
- package/js/src/src/abstract/bybit.js +11 -0
- package/js/src/src/abstract/bydfi.d.ts +11 -0
- package/js/src/src/abstract/bydfi.js +11 -0
- package/js/src/src/abstract/cafearz.d.ts +8 -0
- package/js/src/src/abstract/cafearz.js +11 -0
- package/js/src/src/abstract/cex.d.ts +35 -0
- package/js/src/src/abstract/cex.js +11 -0
- package/js/src/src/abstract/coinbase.d.ts +97 -0
- package/js/src/src/abstract/coinbase.js +11 -0
- package/js/src/src/abstract/coinbaseexchange.d.ts +71 -0
- package/js/src/src/abstract/coinbaseexchange.js +11 -0
- package/js/src/src/abstract/coinbaseinternational.d.ts +42 -0
- package/js/src/src/abstract/coinbaseinternational.js +11 -0
- package/js/src/src/abstract/coincatch.d.ts +97 -0
- package/js/src/src/abstract/coincatch.js +11 -0
- package/js/src/src/abstract/coincheck.d.ts +36 -0
- package/js/src/src/abstract/coincheck.js +11 -0
- package/js/src/src/abstract/coinex.d.ts +240 -0
- package/js/src/src/abstract/coinex.js +11 -0
- package/js/src/src/abstract/coinmate.d.ts +65 -0
- package/js/src/src/abstract/coinmate.js +11 -0
- package/js/src/src/abstract/coinmetro.d.ts +37 -0
- package/js/src/src/abstract/coinmetro.js +11 -0
- package/js/src/src/abstract/coinone.d.ts +70 -0
- package/js/src/src/abstract/coinone.js +11 -0
- package/js/src/src/abstract/coinsph.d.ts +57 -0
- package/js/src/src/abstract/coinsph.js +11 -0
- package/js/src/src/abstract/coinspot.d.ts +31 -0
- package/js/src/src/abstract/coinspot.js +11 -0
- package/js/src/src/abstract/cryptocom.d.ts +126 -0
- package/js/src/src/abstract/cryptocom.js +11 -0
- package/js/src/src/abstract/cryptomus.d.ts +23 -0
- package/js/src/src/abstract/cryptomus.js +11 -0
- package/js/src/src/abstract/defx.d.ts +72 -0
- package/js/src/src/abstract/defx.js +11 -0
- package/js/src/src/abstract/delta.d.ts +53 -0
- package/js/src/src/abstract/delta.js +11 -0
- package/js/src/src/abstract/deribit.d.ts +129 -0
- package/js/src/src/abstract/deribit.js +11 -0
- package/js/src/src/abstract/derive.d.ts +120 -0
- package/js/src/src/abstract/derive.js +11 -0
- package/js/src/src/abstract/digifinex.d.ts +95 -0
- package/js/src/src/abstract/digifinex.js +11 -0
- package/js/src/src/abstract/ellipx.d.ts +28 -0
- package/js/src/src/abstract/ellipx.js +11 -0
- package/js/src/src/abstract/eterex.d.ts +8 -0
- package/js/src/src/abstract/eterex.js +11 -0
- package/js/src/src/abstract/excoino.d.ts +10 -0
- package/js/src/src/abstract/excoino.js +11 -0
- package/js/src/src/abstract/exir.d.ts +11 -0
- package/js/src/src/abstract/exir.js +11 -0
- package/js/src/src/abstract/exmo.d.ts +58 -0
- package/js/src/src/abstract/exmo.js +11 -0
- package/js/src/src/abstract/exnovin.d.ts +9 -0
- package/js/src/src/abstract/exnovin.js +11 -0
- package/js/src/src/abstract/farhadexchange.d.ts +8 -0
- package/js/src/src/abstract/farhadexchange.js +11 -0
- package/js/src/src/abstract/foxbit.d.ts +29 -0
- package/js/src/src/abstract/foxbit.js +11 -0
- package/js/src/src/abstract/gate.d.ts +287 -0
- package/js/src/src/abstract/gate.js +11 -0
- package/js/src/src/abstract/gemini.d.ts +62 -0
- package/js/src/src/abstract/gemini.js +11 -0
- package/js/src/src/abstract/hamtapay.d.ts +9 -0
- package/js/src/src/abstract/hamtapay.js +11 -0
- package/js/src/src/abstract/hashkey.d.ts +70 -0
- package/js/src/src/abstract/hashkey.js +11 -0
- package/js/src/src/abstract/hibachi.d.ts +29 -0
- package/js/src/src/abstract/hibachi.js +11 -0
- package/js/src/src/abstract/hitbtc.d.ts +118 -0
- package/js/src/src/abstract/hitbtc.js +11 -0
- package/js/src/src/abstract/hitobit.d.ts +11 -0
- package/js/src/src/abstract/hitobit.js +11 -0
- package/js/src/src/abstract/hollaex.d.ts +36 -0
- package/js/src/src/abstract/hollaex.js +11 -0
- package/js/src/src/abstract/htx.d.ts +551 -0
- package/js/src/src/abstract/htx.js +11 -0
- package/js/src/src/abstract/hyperliquid.d.ts +9 -0
- package/js/src/src/abstract/hyperliquid.js +11 -0
- package/js/src/src/abstract/independentreserve.d.ts +46 -0
- package/js/src/src/abstract/independentreserve.js +11 -0
- package/js/src/src/abstract/indodax.d.ts +29 -0
- package/js/src/src/abstract/indodax.js +11 -0
- package/js/src/src/abstract/iranexchange.d.ts +9 -0
- package/js/src/src/abstract/iranexchange.js +11 -0
- package/js/src/src/abstract/jibitex.d.ts +10 -0
- package/js/src/src/abstract/jibitex.js +11 -0
- package/js/src/src/abstract/kcex.d.ts +10 -0
- package/js/src/src/abstract/kcex.js +11 -0
- package/js/src/src/abstract/kifpoolme.d.ts +9 -0
- package/js/src/src/abstract/kifpoolme.js +11 -0
- package/js/src/src/abstract/kraken.d.ts +61 -0
- package/js/src/src/abstract/kraken.js +11 -0
- package/js/src/src/abstract/krakenfutures.d.ts +45 -0
- package/js/src/src/abstract/krakenfutures.js +11 -0
- package/js/src/src/abstract/kucoin.d.ts +227 -0
- package/js/src/src/abstract/kucoin.js +11 -0
- package/js/src/src/abstract/kucoinfutures.d.ts +254 -0
- package/js/src/src/abstract/kucoinfutures.js +11 -0
- package/js/src/src/abstract/latoken.d.ts +59 -0
- package/js/src/src/abstract/latoken.js +11 -0
- package/js/src/src/abstract/lbank.d.ts +65 -0
- package/js/src/src/abstract/lbank.js +11 -0
- package/js/src/src/abstract/luno.d.ts +41 -0
- package/js/src/src/abstract/luno.js +11 -0
- package/js/src/src/abstract/mazdax.d.ts +11 -0
- package/js/src/src/abstract/mazdax.js +11 -0
- package/js/src/src/abstract/mercado.d.ts +28 -0
- package/js/src/src/abstract/mercado.js +11 -0
- package/js/src/src/abstract/mexc.d.ts +183 -0
- package/js/src/src/abstract/mexc.js +11 -0
- package/js/src/src/abstract/modetrade.d.ts +122 -0
- package/js/src/src/abstract/modetrade.js +11 -0
- package/js/src/src/abstract/ndax.d.ts +100 -0
- package/js/src/src/abstract/ndax.js +11 -0
- package/js/src/src/abstract/nobitex.d.ts +10 -0
- package/js/src/src/abstract/nobitex.js +11 -0
- package/js/src/src/abstract/novadax.d.ts +32 -0
- package/js/src/src/abstract/novadax.js +11 -0
- package/js/src/src/abstract/oceanex.d.ts +30 -0
- package/js/src/src/abstract/oceanex.js +11 -0
- package/js/src/src/abstract/okcoin.d.ts +77 -0
- package/js/src/src/abstract/okcoin.js +11 -0
- package/js/src/src/abstract/okexchange.d.ts +11 -0
- package/js/src/src/abstract/okexchange.js +11 -0
- package/js/src/src/abstract/okx.d.ts +352 -0
- package/js/src/src/abstract/okx.js +11 -0
- package/js/src/src/abstract/ompfinex.d.ts +10 -0
- package/js/src/src/abstract/ompfinex.js +11 -0
- package/js/src/src/abstract/onetrading.d.ts +26 -0
- package/js/src/src/abstract/onetrading.js +11 -0
- package/js/src/src/abstract/oxfun.d.ts +37 -0
- package/js/src/src/abstract/oxfun.js +11 -0
- package/js/src/src/abstract/p2b.d.ts +25 -0
- package/js/src/src/abstract/p2b.js +11 -0
- package/js/src/src/abstract/paradex.d.ts +66 -0
- package/js/src/src/abstract/paradex.js +11 -0
- package/js/src/src/abstract/paymium.d.ts +31 -0
- package/js/src/src/abstract/paymium.js +11 -0
- package/js/src/src/abstract/phemex.d.ts +120 -0
- package/js/src/src/abstract/phemex.js +11 -0
- package/js/src/src/abstract/pingi.d.ts +9 -0
- package/js/src/src/abstract/pingi.js +11 -0
- package/js/src/src/abstract/poloniex.d.ts +108 -0
- package/js/src/src/abstract/poloniex.js +11 -0
- package/js/src/src/abstract/pooleno.d.ts +8 -0
- package/js/src/src/abstract/pooleno.js +11 -0
- package/js/src/src/abstract/probit.d.ts +26 -0
- package/js/src/src/abstract/probit.js +11 -0
- package/js/src/src/abstract/raastin.d.ts +11 -0
- package/js/src/src/abstract/raastin.js +11 -0
- package/js/src/src/abstract/ramzinex.d.ts +10 -0
- package/js/src/src/abstract/ramzinex.js +11 -0
- package/js/src/src/abstract/sarmayex.d.ts +8 -0
- package/js/src/src/abstract/sarmayex.js +11 -0
- package/js/src/src/abstract/sarrafex.d.ts +10 -0
- package/js/src/src/abstract/sarrafex.js +11 -0
- package/js/src/src/abstract/tabdeal.d.ts +10 -0
- package/js/src/src/abstract/tabdeal.js +11 -0
- package/js/src/src/abstract/tehran_exchange.d.ts +9 -0
- package/js/src/src/abstract/tehran_exchange.js +11 -0
- package/js/src/src/abstract/tetherland.d.ts +8 -0
- package/js/src/src/abstract/tetherland.js +11 -0
- package/js/src/src/abstract/timex.d.ts +65 -0
- package/js/src/src/abstract/timex.js +11 -0
- package/js/src/src/abstract/tokocrypto.d.ts +40 -0
- package/js/src/src/abstract/tokocrypto.js +11 -0
- package/js/src/src/abstract/toobit.d.ts +10 -0
- package/js/src/src/abstract/toobit.js +11 -0
- package/js/src/src/abstract/tradeogre.d.ts +21 -0
- package/js/src/src/abstract/tradeogre.js +11 -0
- package/js/src/src/abstract/twox.d.ts +8 -0
- package/js/src/src/abstract/twox.js +11 -0
- package/js/src/src/abstract/ubitex.d.ts +10 -0
- package/js/src/src/abstract/ubitex.js +11 -0
- package/js/src/src/abstract/upbit.d.ts +58 -0
- package/js/src/src/abstract/upbit.js +11 -0
- package/js/src/src/abstract/vertex.d.ts +22 -0
- package/js/src/src/abstract/vertex.js +11 -0
- package/js/src/src/abstract/wallex.d.ts +11 -0
- package/js/src/src/abstract/wallex.js +11 -0
- package/js/src/src/abstract/wavesexchange.d.ts +157 -0
- package/js/src/src/abstract/wavesexchange.js +11 -0
- package/js/src/src/abstract/whitebit.d.ts +117 -0
- package/js/src/src/abstract/whitebit.js +11 -0
- package/js/src/src/abstract/woo.d.ts +144 -0
- package/js/src/src/abstract/woo.js +11 -0
- package/js/src/src/abstract/woofipro.d.ts +122 -0
- package/js/src/src/abstract/woofipro.js +11 -0
- package/js/src/src/abstract/xt.d.ts +160 -0
- package/js/src/src/abstract/xt.js +11 -0
- package/js/src/src/abstract/yobit.d.ts +19 -0
- package/js/src/src/abstract/yobit.js +11 -0
- package/js/src/src/abstract/zaif.d.ts +41 -0
- package/js/src/src/abstract/zaif.js +11 -0
- package/js/src/src/abstract/zonda.d.ts +56 -0
- package/js/src/src/abstract/zonda.js +11 -0
- package/js/src/src/afratether.d.ts +21 -0
- package/js/src/src/afratether.js +356 -0
- package/js/src/src/alpaca.d.ts +332 -0
- package/js/src/src/alpaca.js +1908 -0
- package/js/src/src/apex.d.ts +333 -0
- package/js/src/src/apex.js +1942 -0
- package/js/src/src/arzinja.d.ts +21 -0
- package/js/src/src/arzinja.js +298 -0
- package/js/src/src/arzplus.d.ts +26 -0
- package/js/src/src/arzplus.js +581 -0
- package/js/src/src/ascendex.d.ts +424 -0
- package/js/src/src/ascendex.js +3699 -0
- package/js/src/src/asretether.d.ts +21 -0
- package/js/src/src/asretether.js +324 -0
- package/js/src/src/base/Exchange.d.ts +926 -0
- package/js/src/src/base/Exchange.js +7399 -0
- package/js/src/src/base/Precise.d.ts +42 -0
- package/js/src/src/base/Precise.js +275 -0
- package/js/src/src/base/errors.d.ts +168 -0
- package/js/src/src/base/errors.js +255 -0
- package/js/src/src/base/functions/crypto.d.ts +16 -0
- package/js/src/src/base/functions/crypto.js +131 -0
- package/js/src/src/base/functions/encode.d.ts +4 -0
- package/js/src/src/base/functions/encode.js +32 -0
- package/js/src/src/base/functions/generic.d.ts +29 -0
- package/js/src/src/base/functions/generic.js +203 -0
- package/js/src/src/base/functions/misc.d.ts +9 -0
- package/js/src/src/base/functions/misc.js +101 -0
- package/js/src/src/base/functions/number.d.ts +27 -0
- package/js/src/src/base/functions/number.js +313 -0
- package/js/src/src/base/functions/platform.d.ts +7 -0
- package/js/src/src/base/functions/platform.js +27 -0
- package/js/src/src/base/functions/rsa.d.ts +5 -0
- package/js/src/src/base/functions/rsa.js +49 -0
- package/js/src/src/base/functions/string.d.ts +7 -0
- package/js/src/src/base/functions/string.js +44 -0
- package/js/src/src/base/functions/throttle.d.ts +6 -0
- package/js/src/src/base/functions/throttle.js +67 -0
- package/js/src/src/base/functions/time.d.ts +21 -0
- package/js/src/src/base/functions/time.js +171 -0
- package/js/src/src/base/functions/totp.d.ts +3 -0
- package/js/src/src/base/functions/totp.js +25 -0
- package/js/src/src/base/functions/type.d.ts +37 -0
- package/js/src/src/base/functions/type.js +179 -0
- package/js/src/src/base/functions.d.ts +10 -0
- package/js/src/src/base/functions.js +18 -0
- package/js/src/src/base/types.d.ts +586 -0
- package/js/src/src/base/types.js +7 -0
- package/js/src/src/base/ws/Cache.d.ts +27 -0
- package/js/src/src/base/ws/Cache.js +260 -0
- package/js/src/src/base/ws/Client.d.ts +53 -0
- package/js/src/src/base/ws/Client.js +307 -0
- package/js/src/src/base/ws/Future.d.ts +8 -0
- package/js/src/src/base/ws/Future.js +35 -0
- package/js/src/src/base/ws/OrderBook.d.ts +25 -0
- package/js/src/src/base/ws/OrderBook.js +130 -0
- package/js/src/src/base/ws/OrderBookSide.d.ts +40 -0
- package/js/src/src/base/ws/OrderBookSide.js +286 -0
- package/js/src/src/base/ws/WsClient.d.ts +11 -0
- package/js/src/src/base/ws/WsClient.js +69 -0
- package/js/src/src/bequant.d.ts +4 -0
- package/js/src/src/bequant.js +35 -0
- package/js/src/src/bidarz.d.ts +16 -0
- package/js/src/src/bidarz.js +327 -0
- package/js/src/src/bigone.d.ts +296 -0
- package/js/src/src/bigone.js +2340 -0
- package/js/src/src/binance.d.ts +1667 -0
- package/js/src/src/binance.js +14400 -0
- package/js/src/src/binancecoinm.d.ts +6 -0
- package/js/src/src/binancecoinm.js +51 -0
- package/js/src/src/binanceus.d.ts +4 -0
- package/js/src/src/binanceus.js +225 -0
- package/js/src/src/binanceusdm.d.ts +6 -0
- package/js/src/src/binanceusdm.js +63 -0
- package/js/src/src/bingx.d.ts +778 -0
- package/js/src/src/bingx.js +6705 -0
- package/js/src/src/bit24.d.ts +24 -0
- package/js/src/src/bit24.js +520 -0
- package/js/src/src/bit2c.d.ts +146 -0
- package/js/src/src/bit2c.js +1029 -0
- package/js/src/src/bitbank.d.ts +181 -0
- package/js/src/src/bitbank.js +1146 -0
- package/js/src/src/bitbarg.d.ts +21 -0
- package/js/src/src/bitbarg.js +312 -0
- package/js/src/src/bitbns.d.ts +184 -0
- package/js/src/src/bitbns.js +1288 -0
- package/js/src/src/bitfinex.d.ts +516 -0
- package/js/src/src/bitfinex.js +3951 -0
- package/js/src/src/bitflyer.d.ts +229 -0
- package/js/src/src/bitflyer.js +1209 -0
- package/js/src/src/bitget.d.ts +1109 -0
- package/js/src/src/bitget.js +11033 -0
- package/js/src/src/bithumb.d.ts +165 -0
- package/js/src/src/bithumb.js +1257 -0
- package/js/src/src/bitimen.d.ts +23 -0
- package/js/src/src/bitimen.js +424 -0
- package/js/src/src/bitir.d.ts +23 -0
- package/js/src/src/bitir.js +521 -0
- package/js/src/src/bitmart.d.ts +736 -0
- package/js/src/src/bitmart.js +5639 -0
- package/js/src/src/bitmex.d.ts +395 -0
- package/js/src/src/bitmex.js +3088 -0
- package/js/src/src/bitopro.d.ts +295 -0
- package/js/src/src/bitopro.js +1892 -0
- package/js/src/src/bitpin.d.ts +23 -0
- package/js/src/src/bitpin.js +487 -0
- package/js/src/src/bitrue.d.ts +384 -0
- package/js/src/src/bitrue.js +3382 -0
- package/js/src/src/bitso.d.ts +270 -0
- package/js/src/src/bitso.js +1881 -0
- package/js/src/src/bitstamp.d.ts +355 -0
- package/js/src/src/bitstamp.js +2445 -0
- package/js/src/src/bitteam.d.ts +229 -0
- package/js/src/src/bitteam.js +2420 -0
- package/js/src/src/bittrade.d.ts +298 -0
- package/js/src/src/bittrade.js +2050 -0
- package/js/src/src/bitunix.d.ts +21 -0
- package/js/src/src/bitunix.js +326 -0
- package/js/src/src/bitvavo.d.ts +311 -0
- package/js/src/src/bitvavo.js +2204 -0
- package/js/src/src/blockchaincom.d.ts +256 -0
- package/js/src/src/blockchaincom.js +1259 -0
- package/js/src/src/blofin.d.ts +439 -0
- package/js/src/src/blofin.js +2576 -0
- package/js/src/src/btcalpha.d.ts +209 -0
- package/js/src/src/btcalpha.js +1056 -0
- package/js/src/src/btcbox.d.ts +144 -0
- package/js/src/src/btcbox.js +834 -0
- package/js/src/src/btcmarkets.d.ts +253 -0
- package/js/src/src/btcmarkets.js +1418 -0
- package/js/src/src/btcturk.d.ts +161 -0
- package/js/src/src/btcturk.js +1058 -0
- package/js/src/src/bybit.d.ts +1097 -0
- package/js/src/src/bybit.js +9382 -0
- package/js/src/src/bydfi.d.ts +23 -0
- package/js/src/src/bydfi.js +434 -0
- package/js/src/src/cafearz.d.ts +21 -0
- package/js/src/src/cafearz.js +346 -0
- package/js/src/src/cex.d.ts +286 -0
- package/js/src/src/cex.js +1799 -0
- package/js/src/src/coinbase.d.ts +623 -0
- package/js/src/src/coinbase.js +5220 -0
- package/js/src/src/coinbaseadvanced.d.ts +4 -0
- package/js/src/src/coinbaseadvanced.js +18 -0
- package/js/src/src/coinbaseexchange.d.ts +334 -0
- package/js/src/src/coinbaseexchange.js +2127 -0
- package/js/src/src/coinbaseinternational.d.ts +443 -0
- package/js/src/src/coinbaseinternational.js +2336 -0
- package/js/src/src/coincatch.d.ts +786 -0
- package/js/src/src/coincatch.js +5492 -0
- package/js/src/src/coincheck.d.ts +147 -0
- package/js/src/src/coincheck.js +962 -0
- package/js/src/src/coinex.d.ts +719 -0
- package/js/src/src/coinex.js +6166 -0
- package/js/src/src/coinmate.d.ts +202 -0
- package/js/src/src/coinmate.js +1215 -0
- package/js/src/src/coinmetro.d.ts +244 -0
- package/js/src/src/coinmetro.js +2024 -0
- package/js/src/src/coinone.d.ts +158 -0
- package/js/src/src/coinone.js +1278 -0
- package/js/src/src/coinsph.d.ts +310 -0
- package/js/src/src/coinsph.js +2203 -0
- package/js/src/src/coinspot.d.ts +108 -0
- package/js/src/src/coinspot.js +653 -0
- package/js/src/src/cryptocom.d.ts +463 -0
- package/js/src/src/cryptocom.js +3549 -0
- package/js/src/src/cryptomus.d.ts +158 -0
- package/js/src/src/cryptomus.js +1169 -0
- package/js/src/src/defx.d.ts +348 -0
- package/js/src/src/defx.js +2139 -0
- package/js/src/src/delta.d.ts +407 -0
- package/js/src/src/delta.js +3654 -0
- package/js/src/src/deribit.d.ts +516 -0
- package/js/src/src/deribit.js +3790 -0
- package/js/src/src/derive.d.ts +324 -0
- package/js/src/src/derive.js +2655 -0
- package/js/src/src/digifinex.d.ts +544 -0
- package/js/src/src/digifinex.js +4453 -0
- package/js/src/src/ellipx.d.ts +237 -0
- package/js/src/src/ellipx.js +2071 -0
- package/js/src/src/eterex.d.ts +21 -0
- package/js/src/src/eterex.js +299 -0
- package/js/src/src/excoino.d.ts +23 -0
- package/js/src/src/excoino.js +426 -0
- package/js/src/src/exir.d.ts +23 -0
- package/js/src/src/exir.js +403 -0
- package/js/src/src/exmo.d.ts +426 -0
- package/js/src/src/exmo.js +2825 -0
- package/js/src/src/exnovin.d.ts +22 -0
- package/js/src/src/exnovin.js +378 -0
- package/js/src/src/farhadexchange.d.ts +21 -0
- package/js/src/src/farhadexchange.js +280 -0
- package/js/src/src/fmfwio.d.ts +4 -0
- package/js/src/src/fmfwio.js +35 -0
- package/js/src/src/foxbit.d.ts +352 -0
- package/js/src/src/foxbit.js +2016 -0
- package/js/src/src/gate.d.ts +1071 -0
- package/js/src/src/gate.js +8282 -0
- package/js/src/src/gateio.d.ts +4 -0
- package/js/src/src/gateio.js +17 -0
- package/js/src/src/gemini.d.ts +257 -0
- package/js/src/src/gemini.js +2006 -0
- package/js/src/src/hamtapay.d.ts +21 -0
- package/js/src/src/hamtapay.js +303 -0
- package/js/src/src/hashkey.d.ts +628 -0
- package/js/src/src/hashkey.js +4363 -0
- package/js/src/src/hibachi.d.ts +346 -0
- package/js/src/src/hibachi.js +2137 -0
- package/js/src/src/hitbtc.d.ts +558 -0
- package/js/src/src/hitbtc.js +3847 -0
- package/js/src/src/hitobit.d.ts +23 -0
- package/js/src/src/hitobit.js +412 -0
- package/js/src/src/hollaex.d.ts +305 -0
- package/js/src/src/hollaex.js +2046 -0
- package/js/src/src/htx.d.ts +961 -0
- package/js/src/src/htx.js +9668 -0
- package/js/src/src/huobi.d.ts +4 -0
- package/js/src/src/huobi.js +17 -0
- package/js/src/src/hyperliquid.d.ts +651 -0
- package/js/src/src/hyperliquid.js +3937 -0
- package/js/src/src/independentreserve.d.ts +169 -0
- package/js/src/src/independentreserve.js +1115 -0
- package/js/src/src/indodax.d.ts +217 -0
- package/js/src/src/indodax.js +1454 -0
- package/js/src/src/iranexchange.d.ts +21 -0
- package/js/src/src/iranexchange.js +399 -0
- package/js/src/src/jibitex.d.ts +23 -0
- package/js/src/src/jibitex.js +416 -0
- package/js/src/src/kcex.d.ts +21 -0
- package/js/src/src/kcex.js +335 -0
- package/js/src/src/kifpoolme.d.ts +23 -0
- package/js/src/src/kifpoolme.js +410 -0
- package/js/src/src/kraken.d.ts +484 -0
- package/js/src/src/kraken.js +3518 -0
- package/js/src/src/krakenfutures.d.ts +362 -0
- package/js/src/src/krakenfutures.js +2885 -0
- package/js/src/src/kucoin.d.ts +759 -0
- package/js/src/src/kucoin.js +5153 -0
- package/js/src/src/kucoinfutures.d.ts +521 -0
- package/js/src/src/kucoinfutures.js +3381 -0
- package/js/src/src/latoken.d.ts +274 -0
- package/js/src/src/latoken.js +1824 -0
- package/js/src/src/lbank.d.ts +350 -0
- package/js/src/src/lbank.js +3146 -0
- package/js/src/src/luno.d.ts +252 -0
- package/js/src/src/luno.js +1479 -0
- package/js/src/src/mazdax.d.ts +23 -0
- package/js/src/src/mazdax.js +534 -0
- package/js/src/src/mercado.d.ts +160 -0
- package/js/src/src/mercado.js +1011 -0
- package/js/src/src/mexc.d.ts +768 -0
- package/js/src/src/mexc.js +6102 -0
- package/js/src/src/modetrade.d.ts +496 -0
- package/js/src/src/modetrade.js +2936 -0
- package/js/src/src/myokx.d.ts +4 -0
- package/js/src/src/myokx.js +54 -0
- package/js/src/src/ndax.d.ts +285 -0
- package/js/src/src/ndax.js +2598 -0
- package/js/src/src/nobitex.d.ts +23 -0
- package/js/src/src/nobitex.js +454 -0
- package/js/src/src/novadax.d.ts +279 -0
- package/js/src/src/novadax.js +1676 -0
- package/js/src/src/oceanex.d.ts +231 -0
- package/js/src/src/oceanex.js +1123 -0
- package/js/src/src/okcoin.d.ts +346 -0
- package/js/src/src/okcoin.js +3211 -0
- package/js/src/src/okexchange.d.ts +23 -0
- package/js/src/src/okexchange.js +373 -0
- package/js/src/src/okx.d.ts +1125 -0
- package/js/src/src/okx.js +9009 -0
- package/js/src/src/okxus.d.ts +4 -0
- package/js/src/src/okxus.js +54 -0
- package/js/src/src/ompfinex.d.ts +23 -0
- package/js/src/src/ompfinex.js +510 -0
- package/js/src/src/onetrading.d.ts +228 -0
- package/js/src/src/onetrading.js +1769 -0
- package/js/src/src/oxfun.d.ts +442 -0
- package/js/src/src/oxfun.js +2920 -0
- package/js/src/src/p2b.d.ts +189 -0
- package/js/src/src/p2b.js +1344 -0
- package/js/src/src/paradex.d.ts +389 -0
- package/js/src/src/paradex.js +2607 -0
- package/js/src/src/paymium.d.ts +133 -0
- package/js/src/src/paymium.js +644 -0
- package/js/src/src/phemex.d.ts +497 -0
- package/js/src/src/phemex.js +5333 -0
- package/js/src/src/pingi.d.ts +22 -0
- package/js/src/src/pingi.js +446 -0
- package/js/src/src/poloniex.d.ts +441 -0
- package/js/src/src/poloniex.js +3681 -0
- package/js/src/src/pooleno.d.ts +21 -0
- package/js/src/src/pooleno.js +347 -0
- package/js/src/src/pro/alpaca.d.ts +95 -0
- package/js/src/src/pro/alpaca.js +724 -0
- package/js/src/src/pro/apex.d.ts +160 -0
- package/js/src/src/pro/apex.js +1044 -0
- package/js/src/src/pro/ascendex.d.ts +99 -0
- package/js/src/src/pro/ascendex.js +1012 -0
- package/js/src/src/pro/bequant.d.ts +4 -0
- package/js/src/src/pro/bequant.js +42 -0
- package/js/src/src/pro/binance.d.ts +796 -0
- package/js/src/src/pro/binance.js +4373 -0
- package/js/src/src/pro/binancecoinm.d.ts +4 -0
- package/js/src/src/pro/binancecoinm.js +32 -0
- package/js/src/src/pro/binanceus.d.ts +4 -0
- package/js/src/src/pro/binanceus.js +52 -0
- package/js/src/src/pro/binanceusdm.d.ts +4 -0
- package/js/src/src/pro/binanceusdm.js +37 -0
- package/js/src/src/pro/bingx.d.ts +151 -0
- package/js/src/src/pro/bingx.js +1568 -0
- package/js/src/src/pro/bitfinex.d.ts +99 -0
- package/js/src/src/pro/bitfinex.js +1165 -0
- package/js/src/src/pro/bitget.d.ts +257 -0
- package/js/src/src/pro/bitget.js +2327 -0
- package/js/src/src/pro/bithumb.d.ts +59 -0
- package/js/src/src/pro/bithumb.js +395 -0
- package/js/src/src/pro/bitmart.d.ts +168 -0
- package/js/src/src/pro/bitmart.js +1686 -0
- package/js/src/src/pro/bitmex.d.ts +170 -0
- package/js/src/src/pro/bitmex.js +1760 -0
- package/js/src/src/pro/bitopro.d.ts +69 -0
- package/js/src/src/pro/bitopro.js +477 -0
- package/js/src/src/pro/bitrue.d.ts +40 -0
- package/js/src/src/pro/bitrue.js +461 -0
- package/js/src/src/pro/bitstamp.d.ts +53 -0
- package/js/src/src/pro/bitstamp.js +587 -0
- package/js/src/src/pro/bittrade.d.ts +66 -0
- package/js/src/src/pro/bittrade.js +606 -0
- package/js/src/src/pro/bitvavo.d.ts +321 -0
- package/js/src/src/pro/bitvavo.js +1451 -0
- package/js/src/src/pro/blockchaincom.d.ts +89 -0
- package/js/src/src/pro/blockchaincom.js +777 -0
- package/js/src/src/pro/blofin.d.ts +174 -0
- package/js/src/src/pro/blofin.js +743 -0
- package/js/src/src/pro/bybit.d.ts +397 -0
- package/js/src/src/pro/bybit.js +2519 -0
- package/js/src/src/pro/cex.d.ts +220 -0
- package/js/src/src/pro/cex.js +1535 -0
- package/js/src/src/pro/coinbase.d.ts +119 -0
- package/js/src/src/pro/coinbase.js +736 -0
- package/js/src/src/pro/coinbaseadvanced.d.ts +4 -0
- package/js/src/src/pro/coinbaseadvanced.js +18 -0
- package/js/src/src/pro/coinbaseexchange.d.ts +133 -0
- package/js/src/src/pro/coinbaseexchange.js +969 -0
- package/js/src/src/pro/coinbaseinternational.d.ts +143 -0
- package/js/src/src/pro/coinbaseinternational.js +804 -0
- package/js/src/src/pro/coincatch.d.ts +207 -0
- package/js/src/src/pro/coincatch.js +1562 -0
- package/js/src/src/pro/coincheck.d.ts +33 -0
- package/js/src/src/pro/coincheck.js +210 -0
- package/js/src/src/pro/coinex.d.ts +147 -0
- package/js/src/src/pro/coinex.js +1426 -0
- package/js/src/src/pro/coinone.d.ts +51 -0
- package/js/src/src/pro/coinone.js +413 -0
- package/js/src/src/pro/cryptocom.d.ts +300 -0
- package/js/src/src/pro/cryptocom.js +1414 -0
- package/js/src/src/pro/defx.d.ts +236 -0
- package/js/src/src/pro/defx.js +865 -0
- package/js/src/src/pro/deribit.d.ts +163 -0
- package/js/src/src/pro/deribit.js +1066 -0
- package/js/src/src/pro/derive.d.ts +100 -0
- package/js/src/src/pro/derive.js +753 -0
- package/js/src/src/pro/exmo.d.ts +97 -0
- package/js/src/src/pro/exmo.js +903 -0
- package/js/src/src/pro/gate.d.ts +360 -0
- package/js/src/src/pro/gate.js +2119 -0
- package/js/src/src/pro/gateio.d.ts +4 -0
- package/js/src/src/pro/gateio.js +17 -0
- package/js/src/src/pro/gemini.d.ts +106 -0
- package/js/src/src/pro/gemini.js +932 -0
- package/js/src/src/pro/hashkey.d.ts +121 -0
- package/js/src/src/pro/hashkey.js +843 -0
- package/js/src/src/pro/hitbtc.d.ts +235 -0
- package/js/src/src/pro/hitbtc.js +1400 -0
- package/js/src/src/pro/hollaex.d.ts +77 -0
- package/js/src/src/pro/hollaex.js +604 -0
- package/js/src/src/pro/htx.d.ts +141 -0
- package/js/src/src/pro/htx.js +2415 -0
- package/js/src/src/pro/huobi.d.ts +4 -0
- package/js/src/src/pro/huobi.js +17 -0
- package/js/src/src/pro/hyperliquid.d.ts +218 -0
- package/js/src/src/pro/hyperliquid.js +1126 -0
- package/js/src/src/pro/independentreserve.d.ts +36 -0
- package/js/src/src/pro/independentreserve.js +287 -0
- package/js/src/src/pro/kraken.d.ts +233 -0
- package/js/src/src/pro/kraken.js +1785 -0
- package/js/src/src/pro/krakenfutures.d.ts +178 -0
- package/js/src/src/pro/krakenfutures.js +1592 -0
- package/js/src/src/pro/kucoin.d.ts +221 -0
- package/js/src/src/pro/kucoin.js +1430 -0
- package/js/src/src/pro/kucoinfutures.d.ts +205 -0
- package/js/src/src/pro/kucoinfutures.js +1295 -0
- package/js/src/src/pro/lbank.d.ts +134 -0
- package/js/src/src/pro/lbank.js +950 -0
- package/js/src/src/pro/luno.d.ts +44 -0
- package/js/src/src/pro/luno.js +322 -0
- package/js/src/src/pro/mexc.d.ts +210 -0
- package/js/src/src/pro/mexc.js +2009 -0
- package/js/src/src/pro/modetrade.d.ts +155 -0
- package/js/src/src/pro/modetrade.js +1335 -0
- package/js/src/src/pro/myokx.d.ts +4 -0
- package/js/src/src/pro/myokx.js +39 -0
- package/js/src/src/pro/ndax.d.ts +60 -0
- package/js/src/src/pro/ndax.js +545 -0
- package/js/src/src/pro/okcoin.d.ts +91 -0
- package/js/src/src/pro/okcoin.js +763 -0
- package/js/src/src/pro/okx.d.ts +408 -0
- package/js/src/src/pro/okx.js +2479 -0
- package/js/src/src/pro/okxus.d.ts +4 -0
- package/js/src/src/pro/okxus.js +39 -0
- package/js/src/src/pro/onetrading.d.ts +107 -0
- package/js/src/src/pro/onetrading.js +1343 -0
- package/js/src/src/pro/oxfun.d.ts +234 -0
- package/js/src/src/pro/oxfun.js +1112 -0
- package/js/src/src/pro/p2b.d.ts +104 -0
- package/js/src/src/pro/p2b.js +506 -0
- package/js/src/src/pro/paradex.d.ts +54 -0
- package/js/src/src/pro/paradex.js +370 -0
- package/js/src/src/pro/phemex.d.ts +129 -0
- package/js/src/src/pro/phemex.js +1569 -0
- package/js/src/src/pro/poloniex.d.ts +214 -0
- package/js/src/src/pro/poloniex.js +1318 -0
- package/js/src/src/pro/probit.d.ts +91 -0
- package/js/src/src/pro/probit.js +593 -0
- package/js/src/src/pro/tradeogre.d.ts +49 -0
- package/js/src/src/pro/tradeogre.js +284 -0
- package/js/src/src/pro/upbit.d.ts +124 -0
- package/js/src/src/pro/upbit.js +689 -0
- package/js/src/src/pro/vertex.d.ts +104 -0
- package/js/src/src/pro/vertex.js +999 -0
- package/js/src/src/pro/whitebit.d.ts +123 -0
- package/js/src/src/pro/whitebit.js +971 -0
- package/js/src/src/pro/woo.d.ts +161 -0
- package/js/src/src/pro/woo.js +1351 -0
- package/js/src/src/pro/woofipro.d.ts +155 -0
- package/js/src/src/pro/woofipro.js +1335 -0
- package/js/src/src/pro/xt.d.ts +165 -0
- package/js/src/src/pro/xt.js +1230 -0
- package/js/src/src/probit.d.ts +283 -0
- package/js/src/src/probit.js +1935 -0
- package/js/src/src/protobuf/mexc/compiled.cjs +7186 -0
- package/js/src/src/protobuf/mexc/compiled.d.cts +8 -0
- package/js/src/src/raastin.d.ts +24 -0
- package/js/src/src/raastin.js +494 -0
- package/js/src/src/ramzinex.d.ts +23 -0
- package/js/src/src/ramzinex.js +510 -0
- package/js/src/src/sarmayex.d.ts +21 -0
- package/js/src/src/sarmayex.js +376 -0
- package/js/src/src/sarrafex.d.ts +23 -0
- package/js/src/src/sarrafex.js +501 -0
- package/js/src/src/static_dependencies/ethers/abi-coder.d.ts +50 -0
- package/js/src/src/static_dependencies/ethers/abi-coder.js +148 -0
- package/js/src/src/static_dependencies/ethers/address/address.d.ts +55 -0
- package/js/src/src/static_dependencies/ethers/address/address.js +162 -0
- package/js/src/src/static_dependencies/ethers/address/checks.d.ts +80 -0
- package/js/src/src/static_dependencies/ethers/address/checks.js +119 -0
- package/js/src/src/static_dependencies/ethers/address/contract-address.d.ts +47 -0
- package/js/src/src/static_dependencies/ethers/address/contract-address.js +73 -0
- package/js/src/src/static_dependencies/ethers/address/index.d.ts +48 -0
- package/js/src/src/static_dependencies/ethers/address/index.js +24 -0
- package/js/src/src/static_dependencies/ethers/bytes32.d.ts +14 -0
- package/js/src/src/static_dependencies/ethers/bytes32.js +45 -0
- package/js/src/src/static_dependencies/ethers/coders/abstract-coder.d.ts +120 -0
- package/js/src/src/static_dependencies/ethers/coders/abstract-coder.js +424 -0
- package/js/src/src/static_dependencies/ethers/coders/address.d.ts +12 -0
- package/js/src/src/static_dependencies/ethers/coders/address.js +34 -0
- package/js/src/src/static_dependencies/ethers/coders/anonymous.d.ts +14 -0
- package/js/src/src/static_dependencies/ethers/coders/anonymous.js +27 -0
- package/js/src/src/static_dependencies/ethers/coders/array.d.ts +24 -0
- package/js/src/src/static_dependencies/ethers/coders/array.js +162 -0
- package/js/src/src/static_dependencies/ethers/coders/boolean.d.ts +12 -0
- package/js/src/src/static_dependencies/ethers/coders/boolean.js +26 -0
- package/js/src/src/static_dependencies/ethers/coders/bytes.d.ts +18 -0
- package/js/src/src/static_dependencies/ethers/coders/bytes.js +39 -0
- package/js/src/src/static_dependencies/ethers/coders/fixed-bytes.d.ts +14 -0
- package/js/src/src/static_dependencies/ethers/coders/fixed-bytes.js +32 -0
- package/js/src/src/static_dependencies/ethers/coders/null.d.ts +11 -0
- package/js/src/src/static_dependencies/ethers/coders/null.js +29 -0
- package/js/src/src/static_dependencies/ethers/coders/number.d.ts +15 -0
- package/js/src/src/static_dependencies/ethers/coders/number.js +48 -0
- package/js/src/src/static_dependencies/ethers/coders/string.d.ts +12 -0
- package/js/src/src/static_dependencies/ethers/coders/string.js +26 -0
- package/js/src/src/static_dependencies/ethers/coders/tuple.d.ts +15 -0
- package/js/src/src/static_dependencies/ethers/coders/tuple.js +67 -0
- package/js/src/src/static_dependencies/ethers/fragments.d.ts +458 -0
- package/js/src/src/static_dependencies/ethers/fragments.js +1252 -0
- package/js/src/src/static_dependencies/ethers/hash/index.d.ts +10 -0
- package/js/src/src/static_dependencies/ethers/hash/index.js +15 -0
- package/js/src/src/static_dependencies/ethers/hash/solidity.d.ts +30 -0
- package/js/src/src/static_dependencies/ethers/hash/solidity.js +107 -0
- package/js/src/src/static_dependencies/ethers/hash/typed-data.d.ts +144 -0
- package/js/src/src/static_dependencies/ethers/hash/typed-data.js +490 -0
- package/js/src/src/static_dependencies/ethers/index.d.ts +19 -0
- package/js/src/src/static_dependencies/ethers/index.js +22 -0
- package/js/src/src/static_dependencies/ethers/interface.d.ts +380 -0
- package/js/src/src/static_dependencies/ethers/interface.js +990 -0
- package/js/src/src/static_dependencies/ethers/typed.d.ts +569 -0
- package/js/src/src/static_dependencies/ethers/typed.js +608 -0
- package/js/src/src/static_dependencies/ethers/utils/base58.d.ts +22 -0
- package/js/src/src/static_dependencies/ethers/utils/base58.js +68 -0
- package/js/src/src/static_dependencies/ethers/utils/base64.d.ts +39 -0
- package/js/src/src/static_dependencies/ethers/utils/base64.js +58 -0
- package/js/src/src/static_dependencies/ethers/utils/data.d.ts +92 -0
- package/js/src/src/static_dependencies/ethers/utils/data.js +175 -0
- package/js/src/src/static_dependencies/ethers/utils/errors.d.ts +509 -0
- package/js/src/src/static_dependencies/ethers/utils/errors.js +227 -0
- package/js/src/src/static_dependencies/ethers/utils/events.d.ts +76 -0
- package/js/src/src/static_dependencies/ethers/utils/events.js +52 -0
- package/js/src/src/static_dependencies/ethers/utils/fixednumber.d.ts +251 -0
- package/js/src/src/static_dependencies/ethers/utils/fixednumber.js +529 -0
- package/js/src/src/static_dependencies/ethers/utils/index.d.ts +30 -0
- package/js/src/src/static_dependencies/ethers/utils/index.js +38 -0
- package/js/src/src/static_dependencies/ethers/utils/maths.d.ts +65 -0
- package/js/src/src/static_dependencies/ethers/utils/maths.js +220 -0
- package/js/src/src/static_dependencies/ethers/utils/properties.d.ts +22 -0
- package/js/src/src/static_dependencies/ethers/utils/properties.js +59 -0
- package/js/src/src/static_dependencies/ethers/utils/rlp-decode.d.ts +5 -0
- package/js/src/src/static_dependencies/ethers/utils/rlp-decode.js +84 -0
- package/js/src/src/static_dependencies/ethers/utils/rlp-encode.d.ts +5 -0
- package/js/src/src/static_dependencies/ethers/utils/rlp-encode.js +54 -0
- package/js/src/src/static_dependencies/ethers/utils/rlp.d.ts +16 -0
- package/js/src/src/static_dependencies/ethers/utils/rlp.js +14 -0
- package/js/src/src/static_dependencies/ethers/utils/units.d.ts +23 -0
- package/js/src/src/static_dependencies/ethers/utils/units.js +88 -0
- package/js/src/src/static_dependencies/ethers/utils/utf8.d.ts +95 -0
- package/js/src/src/static_dependencies/ethers/utils/utf8.js +225 -0
- package/js/src/src/static_dependencies/ethers/utils/uuid.d.ts +7 -0
- package/js/src/src/static_dependencies/ethers/utils/uuid.js +35 -0
- package/js/src/src/static_dependencies/fflake/browser.d.ts +222 -0
- package/js/src/src/static_dependencies/fflake/browser.js +2578 -0
- package/js/src/src/static_dependencies/jsencrypt/JSEncrypt.d.ts +116 -0
- package/js/src/src/static_dependencies/jsencrypt/JSEncrypt.js +194 -0
- package/js/src/src/static_dependencies/jsencrypt/JSEncryptRSAKey.d.ts +142 -0
- package/js/src/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +307 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/asn1.d.ts +51 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +565 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/base64.d.ts +5 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/hex.d.ts +3 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/int10.d.ts +9 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/base64.d.ts +3 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +25 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.d.ts +101 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1757 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/prng4.d.ts +10 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +50 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rng.d.ts +3 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +80 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rsa.d.ts +23 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +377 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/util.d.ts +7 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/util.js +64 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.d.ts +24 -0
- package/js/src/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1627 -0
- package/js/src/src/static_dependencies/noble-curves/_shortw_utils.d.ts +60 -0
- package/js/src/src/static_dependencies/noble-curves/_shortw_utils.js +22 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/curve.d.ts +67 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/curve.js +157 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/edwards.d.ts +79 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/edwards.js +432 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/hash-to-curve.d.ts +56 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +171 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/modular.d.ts +68 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/modular.js +351 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/montgomery.d.ts +25 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/montgomery.js +162 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/poseidon.d.ts +29 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/poseidon.js +115 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/utils.d.ts +53 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/utils.js +227 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/weierstrass.d.ts +204 -0
- package/js/src/src/static_dependencies/noble-curves/abstract/weierstrass.js +1016 -0
- package/js/src/src/static_dependencies/noble-curves/ed25519.d.ts +53 -0
- package/js/src/src/static_dependencies/noble-curves/ed25519.js +402 -0
- package/js/src/src/static_dependencies/noble-curves/p256.d.ts +103 -0
- package/js/src/src/static_dependencies/noble-curves/p256.js +47 -0
- package/js/src/src/static_dependencies/noble-curves/secp256k1.d.ts +91 -0
- package/js/src/src/static_dependencies/noble-curves/secp256k1.js +257 -0
- package/js/src/src/static_dependencies/noble-hashes/_assert.d.ts +21 -0
- package/js/src/src/static_dependencies/noble-hashes/_assert.js +48 -0
- package/js/src/src/static_dependencies/noble-hashes/_sha2.d.ts +23 -0
- package/js/src/src/static_dependencies/noble-hashes/_sha2.js +119 -0
- package/js/src/src/static_dependencies/noble-hashes/_u64.d.ts +35 -0
- package/js/src/src/static_dependencies/noble-hashes/_u64.js +66 -0
- package/js/src/src/static_dependencies/noble-hashes/crypto.d.ts +1 -0
- package/js/src/src/static_dependencies/noble-hashes/crypto.js +7 -0
- package/js/src/src/static_dependencies/noble-hashes/hmac.d.ts +26 -0
- package/js/src/src/static_dependencies/noble-hashes/hmac.js +82 -0
- package/js/src/src/static_dependencies/noble-hashes/md5.d.ts +18 -0
- package/js/src/src/static_dependencies/noble-hashes/md5.js +242 -0
- package/js/src/src/static_dependencies/noble-hashes/sha1.d.ts +21 -0
- package/js/src/src/static_dependencies/noble-hashes/sha1.js +90 -0
- package/js/src/src/static_dependencies/noble-hashes/sha256.d.ts +34 -0
- package/js/src/src/static_dependencies/noble-hashes/sha256.js +129 -0
- package/js/src/src/static_dependencies/noble-hashes/sha3.d.ts +97 -0
- package/js/src/src/static_dependencies/noble-hashes/sha3.js +211 -0
- package/js/src/src/static_dependencies/noble-hashes/sha512.d.ts +66 -0
- package/js/src/src/static_dependencies/noble-hashes/sha512.js +236 -0
- package/js/src/src/static_dependencies/noble-hashes/utils.d.ts +77 -0
- package/js/src/src/static_dependencies/noble-hashes/utils.js +147 -0
- package/js/src/src/static_dependencies/proxies/agent-base/helpers.d.ts +14 -0
- package/js/src/src/static_dependencies/proxies/agent-base/helpers.js +42 -0
- package/js/src/src/static_dependencies/proxies/agent-base/index.d.ts +33 -0
- package/js/src/src/static_dependencies/proxies/agent-base/index.js +82 -0
- package/js/src/src/static_dependencies/proxies/http-proxy-agent/index.d.ts +40 -0
- package/js/src/src/static_dependencies/proxies/http-proxy-agent/index.js +119 -0
- package/js/src/src/static_dependencies/proxies/https-proxy-agent/index.d.ts +45 -0
- package/js/src/src/static_dependencies/proxies/https-proxy-agent/index.js +150 -0
- package/js/src/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.d.ts +15 -0
- package/js/src/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
- package/js/src/src/static_dependencies/qs/formats.cjs +22 -0
- package/js/src/src/static_dependencies/qs/formats.d.cts +14 -0
- package/js/src/src/static_dependencies/qs/index.cjs +15 -0
- package/js/src/src/static_dependencies/qs/index.d.cts +10 -0
- package/js/src/src/static_dependencies/qs/parse.cjs +208 -0
- package/js/src/src/static_dependencies/qs/parse.d.cts +8 -0
- package/js/src/src/static_dependencies/qs/stringify.cjs +192 -0
- package/js/src/src/static_dependencies/qs/stringify.d.cts +8 -0
- package/js/src/src/static_dependencies/qs/utils.cjs +202 -0
- package/js/src/src/static_dependencies/qs/utils.d.cts +15 -0
- package/js/src/src/static_dependencies/scure-base/index.d.ts +92 -0
- package/js/src/src/static_dependencies/scure-base/index.js +420 -0
- package/js/src/src/static_dependencies/scure-starknet/index.d.ts +79 -0
- package/js/src/src/static_dependencies/scure-starknet/index.js +323 -0
- package/js/src/src/static_dependencies/starknet/constants.d.ts +61 -0
- package/js/src/src/static_dependencies/starknet/constants.js +67 -0
- package/js/src/src/static_dependencies/starknet/index.d.ts +3 -0
- package/js/src/src/static_dependencies/starknet/index.js +9 -0
- package/js/src/src/static_dependencies/starknet/types/cairoEnum.d.ts +2 -0
- package/js/src/src/static_dependencies/starknet/types/cairoEnum.js +7 -0
- package/js/src/src/static_dependencies/starknet/types/calldata.d.ts +19 -0
- package/js/src/src/static_dependencies/starknet/types/calldata.js +28 -0
- package/js/src/src/static_dependencies/starknet/types/index.d.ts +13 -0
- package/js/src/src/static_dependencies/starknet/types/index.js +16 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/abi.d.ts +71 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/abi.js +13 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/index.d.ts +24 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/index.js +16 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/legacy.d.ts +33 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/legacy.js +7 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/sierra.d.ts +52 -0
- package/js/src/src/static_dependencies/starknet/types/lib/contract/sierra.js +7 -0
- package/js/src/src/static_dependencies/starknet/types/lib/index.d.ts +248 -0
- package/js/src/src/static_dependencies/starknet/types/lib/index.js +52 -0
- package/js/src/src/static_dependencies/starknet/types/typedData.d.ts +44 -0
- package/js/src/src/static_dependencies/starknet/types/typedData.js +19 -0
- package/js/src/src/static_dependencies/starknet/utils/assert.d.ts +7 -0
- package/js/src/src/static_dependencies/starknet/utils/assert.js +17 -0
- package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/felt.d.ts +6 -0
- package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/felt.js +43 -0
- package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint256.d.ts +72 -0
- package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint256.js +117 -0
- package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint512.d.ts +76 -0
- package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint512.js +136 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/byteArray.d.ts +32 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/byteArray.js +59 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/cairo.d.ts +183 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/cairo.js +229 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoCustomEnum.d.ts +38 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoCustomEnum.js +57 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoOption.d.ts +35 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoOption.js +64 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoResult.d.ts +34 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoResult.js +63 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/index.d.ts +3 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/enum/index.js +9 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/formatter.d.ts +9 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/formatter.js +67 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/index.d.ts +89 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/index.js +280 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/index.d.ts +5 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/index.js +30 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/interface.d.ts +20 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/interface.js +8 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-0-1.1.0.d.ts +24 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-0-1.1.0.js +36 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-2.0.0.d.ts +23 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-2.0.0.js +40 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/propertyOrder.d.ts +2 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/propertyOrder.js +155 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/requestParser.d.ts +11 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/requestParser.js +248 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/responseParser.d.ts +11 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/responseParser.js +214 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/tuple.d.ts +6 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/tuple.js +113 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/validate.d.ts +6 -0
- package/js/src/src/static_dependencies/starknet/utils/calldata/validate.js +208 -0
- package/js/src/src/static_dependencies/starknet/utils/encode.d.ts +207 -0
- package/js/src/src/static_dependencies/starknet/utils/encode.js +282 -0
- package/js/src/src/static_dependencies/starknet/utils/hash/classHash.d.ts +57 -0
- package/js/src/src/static_dependencies/starknet/utils/hash/classHash.js +223 -0
- package/js/src/src/static_dependencies/starknet/utils/hash/index.d.ts +6 -0
- package/js/src/src/static_dependencies/starknet/utils/hash/index.js +13 -0
- package/js/src/src/static_dependencies/starknet/utils/merkle.d.ts +35 -0
- package/js/src/src/static_dependencies/starknet/utils/merkle.js +84 -0
- package/js/src/src/static_dependencies/starknet/utils/num.d.ts +182 -0
- package/js/src/src/static_dependencies/starknet/utils/num.js +244 -0
- package/js/src/src/static_dependencies/starknet/utils/selector.d.ts +48 -0
- package/js/src/src/static_dependencies/starknet/utils/selector.js +85 -0
- package/js/src/src/static_dependencies/starknet/utils/shortString.d.ts +57 -0
- package/js/src/src/static_dependencies/starknet/utils/shortString.js +96 -0
- package/js/src/src/static_dependencies/starknet/utils/typedData.d.ts +54 -0
- package/js/src/src/static_dependencies/starknet/utils/typedData.js +321 -0
- package/js/src/src/static_dependencies/watchable/src/types.d.ts +28 -0
- package/js/src/src/static_dependencies/watchable/src/types.js +8 -0
- package/js/src/src/static_dependencies/watchable/src/unpromise.d.ts +120 -0
- package/js/src/src/static_dependencies/watchable/src/unpromise.js +297 -0
- package/js/src/src/static_dependencies/zklink/zklink-sdk-web.d.ts +1279 -0
- package/js/src/src/static_dependencies/zklink/zklink-sdk-web.js +4282 -0
- package/js/src/src/tabdeal.d.ts +23 -0
- package/js/src/src/tabdeal.js +387 -0
- package/js/src/src/tehran_exchange.d.ts +21 -0
- package/js/src/src/tehran_exchange.js +333 -0
- package/js/src/src/tetherland.d.ts +21 -0
- package/js/src/src/tetherland.js +367 -0
- package/js/src/src/timex.d.ts +247 -0
- package/js/src/src/timex.js +1792 -0
- package/js/src/src/tokocrypto.d.ts +261 -0
- package/js/src/src/tokocrypto.js +2641 -0
- package/js/src/src/toobit.d.ts +22 -0
- package/js/src/src/toobit.js +445 -0
- package/js/src/src/tradeogre.d.ts +149 -0
- package/js/src/src/tradeogre.js +878 -0
- package/js/src/src/twox.d.ts +21 -0
- package/js/src/src/twox.js +371 -0
- package/js/src/src/ubitex.d.ts +23 -0
- package/js/src/src/ubitex.js +433 -0
- package/js/src/src/upbit.d.ts +377 -0
- package/js/src/src/upbit.js +2340 -0
- package/js/src/src/vertex.d.ts +346 -0
- package/js/src/src/vertex.js +3146 -0
- package/js/src/src/wallex.d.ts +23 -0
- package/js/src/src/wallex.js +467 -0
- package/js/src/src/wavesexchange.d.ts +244 -0
- package/js/src/src/wavesexchange.js +2747 -0
- package/js/src/src/whitebit.d.ts +571 -0
- package/js/src/src/whitebit.js +3437 -0
- package/js/src/src/woo.d.ts +727 -0
- package/js/src/src/woo.js +4183 -0
- package/js/src/src/woofipro.d.ts +497 -0
- package/js/src/src/woofipro.js +2941 -0
- package/js/src/src/xt.d.ts +568 -0
- package/js/src/src/xt.js +5184 -0
- package/js/src/src/yobit.d.ts +197 -0
- package/js/src/src/yobit.js +1453 -0
- package/js/src/src/zaif.d.ts +136 -0
- package/js/src/src/zaif.js +821 -0
- package/js/src/src/zonda.d.ts +214 -0
- package/js/src/src/zonda.js +1984 -0
- package/js/test.d.ts +1 -1
- package/js/test.js +33 -33
- package/package.json +1 -1
|
@@ -0,0 +1,4373 @@
|
|
|
1
|
+
// ----------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
4
|
+
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
5
|
+
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
|
6
|
+
|
|
7
|
+
// ----------------------------------------------------------------------------
|
|
8
|
+
import binanceRest from '../binance.js';
|
|
9
|
+
import { Precise } from '../base/Precise.js';
|
|
10
|
+
import { ChecksumError, ArgumentsRequired, BadRequest, NotSupported } from '../base/errors.js';
|
|
11
|
+
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide } from '../base/ws/Cache.js';
|
|
12
|
+
import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
|
|
13
|
+
import { rsa } from '../base/functions/rsa.js';
|
|
14
|
+
import { eddsa } from '../base/functions/crypto.js';
|
|
15
|
+
import { ed25519 } from '../static_dependencies/noble-curves/ed25519.js';
|
|
16
|
+
// -----------------------------------------------------------------------------
|
|
17
|
+
export default class binance extends binanceRest {
|
|
18
|
+
describe() {
|
|
19
|
+
const superDescribe = super.describe();
|
|
20
|
+
return this.deepExtend(superDescribe, this.describeData());
|
|
21
|
+
}
|
|
22
|
+
describeData() {
|
|
23
|
+
return {
|
|
24
|
+
'has': {
|
|
25
|
+
'ws': true,
|
|
26
|
+
'watchBalance': true,
|
|
27
|
+
'watchLiquidations': true,
|
|
28
|
+
'watchLiquidationsForSymbols': true,
|
|
29
|
+
'watchMyLiquidations': true,
|
|
30
|
+
'watchMyLiquidationsForSymbols': true,
|
|
31
|
+
'watchBidsAsks': true,
|
|
32
|
+
'watchMyTrades': true,
|
|
33
|
+
'watchOHLCV': true,
|
|
34
|
+
'watchOHLCVForSymbols': true,
|
|
35
|
+
'watchOrderBook': true,
|
|
36
|
+
'watchOrderBookForSymbols': true,
|
|
37
|
+
'watchOrders': true,
|
|
38
|
+
'watchOrdersForSymbols': true,
|
|
39
|
+
'watchPositions': true,
|
|
40
|
+
'watchTicker': true,
|
|
41
|
+
'watchTickers': true,
|
|
42
|
+
'watchMarkPrices': true,
|
|
43
|
+
'watchMarkPrice': true,
|
|
44
|
+
'watchTrades': true,
|
|
45
|
+
'watchTradesForSymbols': true,
|
|
46
|
+
'createOrderWs': true,
|
|
47
|
+
'editOrderWs': true,
|
|
48
|
+
'cancelOrderWs': true,
|
|
49
|
+
'cancelOrdersWs': false,
|
|
50
|
+
'cancelAllOrdersWs': true,
|
|
51
|
+
'fetchBalanceWs': true,
|
|
52
|
+
'fetchDepositsWs': false,
|
|
53
|
+
'fetchMarketsWs': false,
|
|
54
|
+
'fetchMyTradesWs': true,
|
|
55
|
+
'fetchOHLCVWs': true,
|
|
56
|
+
'fetchOrderBookWs': true,
|
|
57
|
+
'fetchOpenOrdersWs': true,
|
|
58
|
+
'fetchOrderWs': true,
|
|
59
|
+
'fetchOrdersWs': true,
|
|
60
|
+
'fetchPositionWs': true,
|
|
61
|
+
'fetchPositionForSymbolWs': true,
|
|
62
|
+
'fetchPositionsWs': true,
|
|
63
|
+
'fetchTickerWs': true,
|
|
64
|
+
'fetchTradesWs': true,
|
|
65
|
+
'fetchTradingFeesWs': false,
|
|
66
|
+
'fetchWithdrawalsWs': false,
|
|
67
|
+
},
|
|
68
|
+
'urls': {
|
|
69
|
+
'test': {
|
|
70
|
+
'ws': {
|
|
71
|
+
'spot': 'wss://stream.testnet.binance.vision/ws',
|
|
72
|
+
'margin': 'wss://stream.testnet.binance.vision/ws',
|
|
73
|
+
'future': 'wss://fstream.binancefuture.com/ws',
|
|
74
|
+
'delivery': 'wss://dstream.binancefuture.com/ws',
|
|
75
|
+
'ws-api': {
|
|
76
|
+
'spot': 'wss://ws-api.testnet.binance.vision/ws-api/v3',
|
|
77
|
+
'future': 'wss://testnet.binancefuture.com/ws-fapi/v1',
|
|
78
|
+
'delivery': 'wss://testnet.binancefuture.com/ws-dapi/v1',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
'api': {
|
|
83
|
+
'ws': {
|
|
84
|
+
'spot': 'wss://stream.binance.com:9443/ws',
|
|
85
|
+
'margin': 'wss://stream.binance.com:9443/ws',
|
|
86
|
+
'future': 'wss://fstream.binance.com/ws',
|
|
87
|
+
'delivery': 'wss://dstream.binance.com/ws',
|
|
88
|
+
'ws-api': {
|
|
89
|
+
'spot': 'wss://ws-api.binance.com:443/ws-api/v3',
|
|
90
|
+
'future': 'wss://ws-fapi.binance.com/ws-fapi/v1',
|
|
91
|
+
'delivery': 'wss://ws-dapi.binance.com/ws-dapi/v1',
|
|
92
|
+
},
|
|
93
|
+
'papi': 'wss://fstream.binance.com/pm/ws',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
'doc': 'https://developers.binance.com/en',
|
|
97
|
+
},
|
|
98
|
+
'streaming': {
|
|
99
|
+
'keepAlive': 180000,
|
|
100
|
+
},
|
|
101
|
+
'options': {
|
|
102
|
+
'returnRateLimits': false,
|
|
103
|
+
'streamLimits': {
|
|
104
|
+
'spot': 50,
|
|
105
|
+
'margin': 50,
|
|
106
|
+
'future': 50,
|
|
107
|
+
'delivery': 50, // max 200
|
|
108
|
+
},
|
|
109
|
+
'subscriptionLimitByStream': {
|
|
110
|
+
'spot': 200,
|
|
111
|
+
'margin': 200,
|
|
112
|
+
'future': 200,
|
|
113
|
+
'delivery': 200,
|
|
114
|
+
},
|
|
115
|
+
'streamBySubscriptionsHash': this.createSafeDictionary(),
|
|
116
|
+
'streamIndex': -1,
|
|
117
|
+
// get updates every 1000ms or 100ms
|
|
118
|
+
// or every 0ms in real-time for futures
|
|
119
|
+
'watchOrderBookRate': 100,
|
|
120
|
+
'liquidationsLimit': 1000,
|
|
121
|
+
'myLiquidationsLimit': 1000,
|
|
122
|
+
'tradesLimit': 1000,
|
|
123
|
+
'ordersLimit': 1000,
|
|
124
|
+
'OHLCVLimit': 1000,
|
|
125
|
+
'requestId': this.createSafeDictionary(),
|
|
126
|
+
'watchOrderBookLimit': 1000,
|
|
127
|
+
'watchTrades': {
|
|
128
|
+
'name': 'trade', // 'trade' or 'aggTrade'
|
|
129
|
+
},
|
|
130
|
+
'watchTicker': {
|
|
131
|
+
'name': 'ticker', // ticker or miniTicker or ticker_<window_size>
|
|
132
|
+
},
|
|
133
|
+
'watchTickers': {
|
|
134
|
+
'name': 'ticker', // ticker or miniTicker or ticker_<window_size>
|
|
135
|
+
},
|
|
136
|
+
'watchOHLCV': {
|
|
137
|
+
'name': 'kline', // or indexPriceKline or markPriceKline (coin-m futures)
|
|
138
|
+
},
|
|
139
|
+
'watchOrderBook': {
|
|
140
|
+
'maxRetries': 3,
|
|
141
|
+
'checksum': true,
|
|
142
|
+
},
|
|
143
|
+
'watchBalance': {
|
|
144
|
+
'fetchBalanceSnapshot': false,
|
|
145
|
+
'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
|
|
146
|
+
},
|
|
147
|
+
'watchLiquidationsForSymbols': {
|
|
148
|
+
'defaultType': 'swap',
|
|
149
|
+
},
|
|
150
|
+
'watchPositions': {
|
|
151
|
+
'fetchPositionsSnapshot': true,
|
|
152
|
+
'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
|
|
153
|
+
},
|
|
154
|
+
'wallet': 'wb',
|
|
155
|
+
'listenKeyRefreshRate': 1200000,
|
|
156
|
+
'ws': {
|
|
157
|
+
'cost': 5,
|
|
158
|
+
},
|
|
159
|
+
'tickerChannelsMap': {
|
|
160
|
+
'24hrTicker': 'ticker',
|
|
161
|
+
'24hrMiniTicker': 'miniTicker',
|
|
162
|
+
'markPriceUpdate': 'markPrice',
|
|
163
|
+
// rolling window tickers
|
|
164
|
+
'1hTicker': 'ticker_1h',
|
|
165
|
+
'4hTicker': 'ticker_4h',
|
|
166
|
+
'1dTicker': 'ticker_1d',
|
|
167
|
+
'bookTicker': 'bookTicker',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
requestId(url) {
|
|
173
|
+
const options = this.safeDict(this.options, 'requestId', this.createSafeDictionary());
|
|
174
|
+
const previousValue = this.safeInteger(options, url, 0);
|
|
175
|
+
const newValue = this.sum(previousValue, 1);
|
|
176
|
+
this.options['requestId'][url] = newValue;
|
|
177
|
+
return newValue;
|
|
178
|
+
}
|
|
179
|
+
stream(type, subscriptionHash, numSubscriptions = 1) {
|
|
180
|
+
const streamBySubscriptionsHash = this.safeDict(this.options, 'streamBySubscriptionsHash', this.createSafeDictionary());
|
|
181
|
+
let stream = this.safeString(streamBySubscriptionsHash, subscriptionHash);
|
|
182
|
+
if (stream === undefined) {
|
|
183
|
+
let streamIndex = this.safeInteger(this.options, 'streamIndex', -1);
|
|
184
|
+
const streamLimits = this.safeValue(this.options, 'streamLimits');
|
|
185
|
+
const streamLimit = this.safeInteger(streamLimits, type);
|
|
186
|
+
streamIndex = streamIndex + 1;
|
|
187
|
+
const normalizedIndex = streamIndex % streamLimit;
|
|
188
|
+
this.options['streamIndex'] = streamIndex;
|
|
189
|
+
stream = this.numberToString(normalizedIndex);
|
|
190
|
+
this.options['streamBySubscriptionsHash'][subscriptionHash] = stream;
|
|
191
|
+
const subscriptionsByStreams = this.safeValue(this.options, 'numSubscriptionsByStream');
|
|
192
|
+
if (subscriptionsByStreams === undefined) {
|
|
193
|
+
this.options['numSubscriptionsByStream'] = this.createSafeDictionary();
|
|
194
|
+
}
|
|
195
|
+
const subscriptionsByStream = this.safeInteger(this.options['numSubscriptionsByStream'], stream, 0);
|
|
196
|
+
const newNumSubscriptions = subscriptionsByStream + numSubscriptions;
|
|
197
|
+
const subscriptionLimitByStream = this.safeInteger(this.options['subscriptionLimitByStream'], type, 200);
|
|
198
|
+
if (newNumSubscriptions > subscriptionLimitByStream) {
|
|
199
|
+
throw new 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.');
|
|
200
|
+
}
|
|
201
|
+
this.options['numSubscriptionsByStream'][stream] = subscriptionsByStream + numSubscriptions;
|
|
202
|
+
}
|
|
203
|
+
return stream;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* @method
|
|
207
|
+
* @name binance#watchLiquidations
|
|
208
|
+
* @description watch the public liquidations of a trading pair
|
|
209
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Liquidation-Order-Streams
|
|
210
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Liquidation-Order-Streams
|
|
211
|
+
* @param {string} symbol unified CCXT market symbol
|
|
212
|
+
* @param {int} [since] the earliest time in ms to fetch liquidations for
|
|
213
|
+
* @param {int} [limit] the maximum number of liquidation structures to retrieve
|
|
214
|
+
* @param {object} [params] exchange specific parameters for the bitmex api endpoint
|
|
215
|
+
* @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
|
|
216
|
+
*/
|
|
217
|
+
async watchLiquidations(symbol, since = undefined, limit = undefined, params = {}) {
|
|
218
|
+
return await this.watchLiquidationsForSymbols([symbol], since, limit, params);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* @method
|
|
222
|
+
* @name binance#watchLiquidationsForSymbols
|
|
223
|
+
* @description watch the public liquidations of a trading pair
|
|
224
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Liquidation-Order-Streams
|
|
225
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Liquidation-Order-Streams
|
|
226
|
+
* @param {string[]} symbols list of unified market symbols
|
|
227
|
+
* @param {int} [since] the earliest time in ms to fetch liquidations for
|
|
228
|
+
* @param {int} [limit] the maximum number of liquidation structures to retrieve
|
|
229
|
+
* @param {object} [params] exchange specific parameters for the bitmex api endpoint
|
|
230
|
+
* @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
|
|
231
|
+
*/
|
|
232
|
+
async watchLiquidationsForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
|
|
233
|
+
await this.loadMarkets();
|
|
234
|
+
const subscriptionHashes = [];
|
|
235
|
+
const messageHashes = [];
|
|
236
|
+
let streamHash = 'liquidations';
|
|
237
|
+
symbols = this.marketSymbols(symbols, undefined, true, true);
|
|
238
|
+
if (this.isEmpty(symbols)) {
|
|
239
|
+
subscriptionHashes.push('!' + 'forceOrder@arr');
|
|
240
|
+
messageHashes.push('liquidations');
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
244
|
+
const market = this.market(symbols[i]);
|
|
245
|
+
subscriptionHashes.push(market['lowercaseId'] + '@forceOrder');
|
|
246
|
+
messageHashes.push('liquidations::' + symbols[i]);
|
|
247
|
+
}
|
|
248
|
+
streamHash += '::' + symbols.join(',');
|
|
249
|
+
}
|
|
250
|
+
const firstMarket = this.getMarketFromSymbols(symbols);
|
|
251
|
+
let type = undefined;
|
|
252
|
+
[type, params] = this.handleMarketTypeAndParams('watchLiquidationsForSymbols', firstMarket, params);
|
|
253
|
+
if (type === 'spot') {
|
|
254
|
+
throw new BadRequest(this.id + ' watchLiquidationsForSymbols is not supported for spot symbols');
|
|
255
|
+
}
|
|
256
|
+
let subType = undefined;
|
|
257
|
+
[subType, params] = this.handleSubTypeAndParams('watchLiquidationsForSymbols', firstMarket, params);
|
|
258
|
+
if (this.isLinear(type, subType)) {
|
|
259
|
+
type = 'future';
|
|
260
|
+
}
|
|
261
|
+
else if (this.isInverse(type, subType)) {
|
|
262
|
+
type = 'delivery';
|
|
263
|
+
}
|
|
264
|
+
const numSubscriptions = subscriptionHashes.length;
|
|
265
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, numSubscriptions);
|
|
266
|
+
const requestId = this.requestId(url);
|
|
267
|
+
const request = {
|
|
268
|
+
'method': 'SUBSCRIBE',
|
|
269
|
+
'params': subscriptionHashes,
|
|
270
|
+
'id': requestId,
|
|
271
|
+
};
|
|
272
|
+
const subscribe = {
|
|
273
|
+
'id': requestId,
|
|
274
|
+
};
|
|
275
|
+
const newLiquidations = await this.watchMultiple(url, messageHashes, this.extend(request, params), subscriptionHashes, subscribe);
|
|
276
|
+
if (this.newUpdates) {
|
|
277
|
+
return newLiquidations;
|
|
278
|
+
}
|
|
279
|
+
return this.filterBySymbolsSinceLimit(this.liquidations, symbols, since, limit, true);
|
|
280
|
+
}
|
|
281
|
+
handleLiquidation(client, message) {
|
|
282
|
+
//
|
|
283
|
+
// future
|
|
284
|
+
// {
|
|
285
|
+
// "e":"forceOrder",
|
|
286
|
+
// "E":1698871323061,
|
|
287
|
+
// "o":{
|
|
288
|
+
// "s":"BTCUSDT",
|
|
289
|
+
// "S":"BUY",
|
|
290
|
+
// "o":"LIMIT",
|
|
291
|
+
// "f":"IOC",
|
|
292
|
+
// "q":"1.437",
|
|
293
|
+
// "p":"35100.81",
|
|
294
|
+
// "ap":"34959.70",
|
|
295
|
+
// "X":"FILLED",
|
|
296
|
+
// "l":"1.437",
|
|
297
|
+
// "z":"1.437",
|
|
298
|
+
// "T":1698871323059
|
|
299
|
+
// }
|
|
300
|
+
// }
|
|
301
|
+
// delivery
|
|
302
|
+
// {
|
|
303
|
+
// "e":"forceOrder", // Event Type
|
|
304
|
+
// "E": 1591154240950, // Event Time
|
|
305
|
+
// "o":{
|
|
306
|
+
// "s":"BTCUSD_200925", // Symbol
|
|
307
|
+
// "ps": "BTCUSD", // Pair
|
|
308
|
+
// "S":"SELL", // Side
|
|
309
|
+
// "o":"LIMIT", // Order Type
|
|
310
|
+
// "f":"IOC", // Time in Force
|
|
311
|
+
// "q":"1", // Original Quantity
|
|
312
|
+
// "p":"9425.5", // Price
|
|
313
|
+
// "ap":"9496.5", // Average Price
|
|
314
|
+
// "X":"FILLED", // Order Status
|
|
315
|
+
// "l":"1", // Order Last Filled Quantity
|
|
316
|
+
// "z":"1", // Order Filled Accumulated Quantity
|
|
317
|
+
// "T": 1591154240949, // Order Trade Time
|
|
318
|
+
// }
|
|
319
|
+
// }
|
|
320
|
+
//
|
|
321
|
+
const rawLiquidation = this.safeValue(message, 'o', {});
|
|
322
|
+
const marketId = this.safeString(rawLiquidation, 's');
|
|
323
|
+
const market = this.safeMarket(marketId, undefined, '', 'contract');
|
|
324
|
+
const symbol = market['symbol'];
|
|
325
|
+
const liquidation = this.parseWsLiquidation(rawLiquidation, market);
|
|
326
|
+
let liquidations = this.safeValue(this.liquidations, symbol);
|
|
327
|
+
if (liquidations === undefined) {
|
|
328
|
+
const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
|
|
329
|
+
liquidations = new ArrayCache(limit);
|
|
330
|
+
}
|
|
331
|
+
liquidations.append(liquidation);
|
|
332
|
+
this.liquidations[symbol] = liquidations;
|
|
333
|
+
client.resolve([liquidation], 'liquidations');
|
|
334
|
+
client.resolve([liquidation], 'liquidations::' + symbol);
|
|
335
|
+
}
|
|
336
|
+
parseWsLiquidation(liquidation, market = undefined) {
|
|
337
|
+
//
|
|
338
|
+
// future
|
|
339
|
+
// {
|
|
340
|
+
// "s":"BTCUSDT",
|
|
341
|
+
// "S":"BUY",
|
|
342
|
+
// "o":"LIMIT",
|
|
343
|
+
// "f":"IOC",
|
|
344
|
+
// "q":"1.437",
|
|
345
|
+
// "p":"35100.81",
|
|
346
|
+
// "ap":"34959.70",
|
|
347
|
+
// "X":"FILLED",
|
|
348
|
+
// "l":"1.437",
|
|
349
|
+
// "z":"1.437",
|
|
350
|
+
// "T":1698871323059
|
|
351
|
+
// }
|
|
352
|
+
// delivery
|
|
353
|
+
// {
|
|
354
|
+
// "s":"BTCUSD_200925", // Symbol
|
|
355
|
+
// "ps": "BTCUSD", // Pair
|
|
356
|
+
// "S":"SELL", // Side
|
|
357
|
+
// "o":"LIMIT", // Order Type
|
|
358
|
+
// "f":"IOC", // Time in Force
|
|
359
|
+
// "q":"1", // Original Quantity
|
|
360
|
+
// "p":"9425.5", // Price
|
|
361
|
+
// "ap":"9496.5", // Average Price
|
|
362
|
+
// "X":"FILLED", // Order Status
|
|
363
|
+
// "l":"1", // Order Last Filled Quantity
|
|
364
|
+
// "z":"1", // Order Filled Accumulated Quantity
|
|
365
|
+
// "T": 1591154240949, // Order Trade Time
|
|
366
|
+
// }
|
|
367
|
+
// myLiquidation
|
|
368
|
+
// {
|
|
369
|
+
// "s":"BTCUSDT", // Symbol
|
|
370
|
+
// "c":"TEST", // Client Order Id
|
|
371
|
+
// // special client order id:
|
|
372
|
+
// // starts with "autoclose-": liquidation order
|
|
373
|
+
// // "adl_autoclose": ADL auto close order
|
|
374
|
+
// // "settlement_autoclose-": settlement order for delisting or delivery
|
|
375
|
+
// "S":"SELL", // Side
|
|
376
|
+
// "o":"TRAILING_STOP_MARKET", // Order Type
|
|
377
|
+
// "f":"GTC", // Time in Force
|
|
378
|
+
// "q":"0.001", // Original Quantity
|
|
379
|
+
// "p":"0", // Original Price
|
|
380
|
+
// "ap":"0", // Average Price
|
|
381
|
+
// "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
|
382
|
+
// "x":"NEW", // Execution Type
|
|
383
|
+
// "X":"NEW", // Order Status
|
|
384
|
+
// "i":8886774, // Order Id
|
|
385
|
+
// "l":"0", // Order Last Filled Quantity
|
|
386
|
+
// "z":"0", // Order Filled Accumulated Quantity
|
|
387
|
+
// "L":"0", // Last Filled Price
|
|
388
|
+
// "N":"USDT", // Commission Asset, will not push if no commission
|
|
389
|
+
// "n":"0", // Commission, will not push if no commission
|
|
390
|
+
// "T":1568879465650, // Order Trade Time
|
|
391
|
+
// "t":0, // Trade Id
|
|
392
|
+
// "b":"0", // Bids Notional
|
|
393
|
+
// "a":"9.91", // Ask Notional
|
|
394
|
+
// "m":false, // Is this trade the maker side?
|
|
395
|
+
// "R":false, // Is this reduce only
|
|
396
|
+
// "wt":"CONTRACT_PRICE", // Stop Price Working Type
|
|
397
|
+
// "ot":"TRAILING_STOP_MARKET",// Original Order Type
|
|
398
|
+
// "ps":"LONG", // Position Side
|
|
399
|
+
// "cp":false, // If Close-All, pushed with conditional order
|
|
400
|
+
// "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
|
|
401
|
+
// "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
|
402
|
+
// "pP": false, // If price protection is turned on
|
|
403
|
+
// "si": 0, // ignore
|
|
404
|
+
// "ss": 0, // ignore
|
|
405
|
+
// "rp":"0", // Realized Profit of the trade
|
|
406
|
+
// "V":"EXPIRE_TAKER", // STP mode
|
|
407
|
+
// "pm":"OPPONENT", // Price match mode
|
|
408
|
+
// "gtd":0 // TIF GTD order auto cancel time
|
|
409
|
+
// }
|
|
410
|
+
//
|
|
411
|
+
const marketId = this.safeString(liquidation, 's');
|
|
412
|
+
market = this.safeMarket(marketId, market);
|
|
413
|
+
const timestamp = this.safeInteger(liquidation, 'T');
|
|
414
|
+
return this.safeLiquidation({
|
|
415
|
+
'info': liquidation,
|
|
416
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
417
|
+
'contracts': this.safeNumber(liquidation, 'l'),
|
|
418
|
+
'contractSize': this.safeNumber(market, 'contractSize'),
|
|
419
|
+
'price': this.safeNumber(liquidation, 'ap'),
|
|
420
|
+
'side': this.safeStringLower(liquidation, 'S'),
|
|
421
|
+
'baseValue': undefined,
|
|
422
|
+
'quoteValue': undefined,
|
|
423
|
+
'timestamp': timestamp,
|
|
424
|
+
'datetime': this.iso8601(timestamp),
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* @method
|
|
429
|
+
* @name binance#watchMyLiquidations
|
|
430
|
+
* @description watch the private liquidations of a trading pair
|
|
431
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Event-Order-Update
|
|
432
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/user-data-streams/Event-Order-Update
|
|
433
|
+
* @param {string} symbol unified CCXT market symbol
|
|
434
|
+
* @param {int} [since] the earliest time in ms to fetch liquidations for
|
|
435
|
+
* @param {int} [limit] the maximum number of liquidation structures to retrieve
|
|
436
|
+
* @param {object} [params] exchange specific parameters for the bitmex api endpoint
|
|
437
|
+
* @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
|
|
438
|
+
*/
|
|
439
|
+
async watchMyLiquidations(symbol, since = undefined, limit = undefined, params = {}) {
|
|
440
|
+
return this.watchMyLiquidationsForSymbols([symbol], since, limit, params);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* @method
|
|
444
|
+
* @name binance#watchMyLiquidationsForSymbols
|
|
445
|
+
* @description watch the private liquidations of a trading pair
|
|
446
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Event-Order-Update
|
|
447
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/user-data-streams/Event-Order-Update
|
|
448
|
+
* @param {string[]} symbols list of unified market symbols
|
|
449
|
+
* @param {int} [since] the earliest time in ms to fetch liquidations for
|
|
450
|
+
* @param {int} [limit] the maximum number of liquidation structures to retrieve
|
|
451
|
+
* @param {object} [params] exchange specific parameters for the bitmex api endpoint
|
|
452
|
+
* @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
|
|
453
|
+
*/
|
|
454
|
+
async watchMyLiquidationsForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
|
|
455
|
+
await this.loadMarkets();
|
|
456
|
+
symbols = this.marketSymbols(symbols, undefined, true, true, true);
|
|
457
|
+
const market = this.getMarketFromSymbols(symbols);
|
|
458
|
+
const messageHashes = ['myLiquidations'];
|
|
459
|
+
if (!this.isEmpty(symbols)) {
|
|
460
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
461
|
+
const symbol = symbols[i];
|
|
462
|
+
messageHashes.push('myLiquidations::' + symbol);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
let type = undefined;
|
|
466
|
+
[type, params] = this.handleMarketTypeAndParams('watchMyLiquidationsForSymbols', market, params);
|
|
467
|
+
let subType = undefined;
|
|
468
|
+
[subType, params] = this.handleSubTypeAndParams('watchMyLiquidationsForSymbols', market, params);
|
|
469
|
+
if (this.isLinear(type, subType)) {
|
|
470
|
+
type = 'future';
|
|
471
|
+
}
|
|
472
|
+
else if (this.isInverse(type, subType)) {
|
|
473
|
+
type = 'delivery';
|
|
474
|
+
}
|
|
475
|
+
await this.authenticate(params);
|
|
476
|
+
const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
|
|
477
|
+
const message = undefined;
|
|
478
|
+
const newLiquidations = await this.watchMultiple(url, messageHashes, message, [type]);
|
|
479
|
+
if (this.newUpdates) {
|
|
480
|
+
return newLiquidations;
|
|
481
|
+
}
|
|
482
|
+
return this.filterBySymbolsSinceLimit(this.liquidations, symbols, since, limit);
|
|
483
|
+
}
|
|
484
|
+
handleMyLiquidation(client, message) {
|
|
485
|
+
//
|
|
486
|
+
// {
|
|
487
|
+
// "s":"BTCUSDT", // Symbol
|
|
488
|
+
// "c":"TEST", // Client Order Id
|
|
489
|
+
// // special client order id:
|
|
490
|
+
// // starts with "autoclose-": liquidation order
|
|
491
|
+
// // "adl_autoclose": ADL auto close order
|
|
492
|
+
// // "settlement_autoclose-": settlement order for delisting or delivery
|
|
493
|
+
// "S":"SELL", // Side
|
|
494
|
+
// "o":"TRAILING_STOP_MARKET", // Order Type
|
|
495
|
+
// "f":"GTC", // Time in Force
|
|
496
|
+
// "q":"0.001", // Original Quantity
|
|
497
|
+
// "p":"0", // Original Price
|
|
498
|
+
// "ap":"0", // Average Price
|
|
499
|
+
// "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
|
500
|
+
// "x":"NEW", // Execution Type
|
|
501
|
+
// "X":"NEW", // Order Status
|
|
502
|
+
// "i":8886774, // Order Id
|
|
503
|
+
// "l":"0", // Order Last Filled Quantity
|
|
504
|
+
// "z":"0", // Order Filled Accumulated Quantity
|
|
505
|
+
// "L":"0", // Last Filled Price
|
|
506
|
+
// "N":"USDT", // Commission Asset, will not push if no commission
|
|
507
|
+
// "n":"0", // Commission, will not push if no commission
|
|
508
|
+
// "T":1568879465650, // Order Trade Time
|
|
509
|
+
// "t":0, // Trade Id
|
|
510
|
+
// "b":"0", // Bids Notional
|
|
511
|
+
// "a":"9.91", // Ask Notional
|
|
512
|
+
// "m":false, // Is this trade the maker side?
|
|
513
|
+
// "R":false, // Is this reduce only
|
|
514
|
+
// "wt":"CONTRACT_PRICE", // Stop Price Working Type
|
|
515
|
+
// "ot":"TRAILING_STOP_MARKET",// Original Order Type
|
|
516
|
+
// "ps":"LONG", // Position Side
|
|
517
|
+
// "cp":false, // If Close-All, pushed with conditional order
|
|
518
|
+
// "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
|
|
519
|
+
// "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
|
520
|
+
// "pP": false, // If price protection is turned on
|
|
521
|
+
// "si": 0, // ignore
|
|
522
|
+
// "ss": 0, // ignore
|
|
523
|
+
// "rp":"0", // Realized Profit of the trade
|
|
524
|
+
// "V":"EXPIRE_TAKER", // STP mode
|
|
525
|
+
// "pm":"OPPONENT", // Price match mode
|
|
526
|
+
// "gtd":0 // TIF GTD order auto cancel time
|
|
527
|
+
// }
|
|
528
|
+
//
|
|
529
|
+
const orderType = this.safeString(message, 'o');
|
|
530
|
+
if (orderType !== 'LIQUIDATION') {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
const marketId = this.safeString(message, 's');
|
|
534
|
+
const market = this.safeMarket(marketId);
|
|
535
|
+
const symbol = this.safeSymbol(marketId);
|
|
536
|
+
const liquidation = this.parseWsLiquidation(message, market);
|
|
537
|
+
let myLiquidations = this.safeValue(this.myLiquidations, symbol);
|
|
538
|
+
if (myLiquidations === undefined) {
|
|
539
|
+
const limit = this.safeInteger(this.options, 'myLiquidationsLimit', 1000);
|
|
540
|
+
myLiquidations = new ArrayCache(limit);
|
|
541
|
+
}
|
|
542
|
+
myLiquidations.append(liquidation);
|
|
543
|
+
this.myLiquidations[symbol] = myLiquidations;
|
|
544
|
+
client.resolve([liquidation], 'myLiquidations');
|
|
545
|
+
client.resolve([liquidation], 'myLiquidations::' + symbol);
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* @method
|
|
549
|
+
* @name binance#watchOrderBook
|
|
550
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
551
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
|
|
552
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
|
|
553
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
554
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
555
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
556
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
557
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
558
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
559
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
560
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
561
|
+
*/
|
|
562
|
+
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
563
|
+
//
|
|
564
|
+
// todo add support for <levels>-snapshots (depth)
|
|
565
|
+
// 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)
|
|
566
|
+
// valid <levels> are 5, 10, or 20
|
|
567
|
+
//
|
|
568
|
+
// default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
|
|
569
|
+
//
|
|
570
|
+
// notice the differences between trading futures and spot trading
|
|
571
|
+
// the algorithms use different urls in step 1
|
|
572
|
+
// delta caching and merging also differs in steps 4, 5, 6
|
|
573
|
+
//
|
|
574
|
+
// spot/margin
|
|
575
|
+
// https://binance-docs.github.io/apidocs/spot/en/#how-to-manage-a-local-order-book-correctly
|
|
576
|
+
//
|
|
577
|
+
// 1. Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth.
|
|
578
|
+
// 2. Buffer the events you receive from the stream.
|
|
579
|
+
// 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
|
|
580
|
+
// 4. Drop any event where u is <= lastUpdateId in the snapshot.
|
|
581
|
+
// 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1.
|
|
582
|
+
// 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
|
|
583
|
+
// 7. The data in each event is the absolute quantity for a price level.
|
|
584
|
+
// 8. If the quantity is 0, remove the price level.
|
|
585
|
+
// 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
|
|
586
|
+
//
|
|
587
|
+
// futures
|
|
588
|
+
// https://binance-docs.github.io/apidocs/futures/en/#how-to-manage-a-local-order-book-correctly
|
|
589
|
+
//
|
|
590
|
+
// 1. Open a stream to wss://fstream.binance.com/stream?streams=btcusdt@depth.
|
|
591
|
+
// 2. Buffer the events you receive from the stream. For same price, latest received update covers the previous one.
|
|
592
|
+
// 3. Get a depth snapshot from https://fapi.binance.com/fapi/v1/depth?symbol=BTCUSDT&limit=1000 .
|
|
593
|
+
// 4. Drop any event where u is < lastUpdateId in the snapshot.
|
|
594
|
+
// 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
|
|
595
|
+
// 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.
|
|
596
|
+
// 7. The data in each event is the absolute quantity for a price level.
|
|
597
|
+
// 8. If the quantity is 0, remove the price level.
|
|
598
|
+
// 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
|
|
599
|
+
//
|
|
600
|
+
return await this.watchOrderBookForSymbols([symbol], limit, params);
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* @method
|
|
604
|
+
* @name binance#watchOrderBookForSymbols
|
|
605
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
606
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
|
|
607
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
|
|
608
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
609
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
610
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
611
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
612
|
+
* @param {string[]} symbols unified array of symbols
|
|
613
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
614
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
615
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
616
|
+
*/
|
|
617
|
+
async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
|
|
618
|
+
await this.loadMarkets();
|
|
619
|
+
symbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
620
|
+
const firstMarket = this.market(symbols[0]);
|
|
621
|
+
let type = firstMarket['type'];
|
|
622
|
+
if (firstMarket['contract']) {
|
|
623
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
624
|
+
}
|
|
625
|
+
const name = 'depth';
|
|
626
|
+
let streamHash = 'multipleOrderbook';
|
|
627
|
+
if (symbols !== undefined) {
|
|
628
|
+
const symbolsLength = symbols.length;
|
|
629
|
+
if (symbolsLength > 200) {
|
|
630
|
+
throw new BadRequest(this.id + ' watchOrderBookForSymbols() accepts 200 symbols at most. To watch more symbols call watchOrderBookForSymbols() multiple times');
|
|
631
|
+
}
|
|
632
|
+
streamHash += '::' + symbols.join(',');
|
|
633
|
+
}
|
|
634
|
+
const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
|
|
635
|
+
const subParams = [];
|
|
636
|
+
const messageHashes = [];
|
|
637
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
638
|
+
const symbol = symbols[i];
|
|
639
|
+
const market = this.market(symbol);
|
|
640
|
+
messageHashes.push('orderbook::' + symbol);
|
|
641
|
+
const subscriptionHash = market['lowercaseId'] + '@' + name;
|
|
642
|
+
const symbolHash = subscriptionHash + '@' + watchOrderBookRate + 'ms';
|
|
643
|
+
subParams.push(symbolHash);
|
|
644
|
+
}
|
|
645
|
+
const messageHashesLength = messageHashes.length;
|
|
646
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, messageHashesLength);
|
|
647
|
+
const requestId = this.requestId(url);
|
|
648
|
+
const request = {
|
|
649
|
+
'method': 'SUBSCRIBE',
|
|
650
|
+
'params': subParams,
|
|
651
|
+
'id': requestId,
|
|
652
|
+
};
|
|
653
|
+
const subscription = {
|
|
654
|
+
'id': requestId.toString(),
|
|
655
|
+
'name': name,
|
|
656
|
+
'symbols': symbols,
|
|
657
|
+
'method': this.handleOrderBookSubscription,
|
|
658
|
+
'limit': limit,
|
|
659
|
+
'type': type,
|
|
660
|
+
'params': params,
|
|
661
|
+
};
|
|
662
|
+
const orderbook = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscription);
|
|
663
|
+
return orderbook.limit();
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* @method
|
|
667
|
+
* @name binance#unWatchOrderBookForSymbols
|
|
668
|
+
* @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
669
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
|
|
670
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
|
|
671
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
672
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
673
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
674
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
675
|
+
* @param {string[]} symbols unified array of symbols
|
|
676
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
677
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
678
|
+
*/
|
|
679
|
+
async unWatchOrderBookForSymbols(symbols, params = {}) {
|
|
680
|
+
await this.loadMarkets();
|
|
681
|
+
symbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
682
|
+
const firstMarket = this.market(symbols[0]);
|
|
683
|
+
let type = firstMarket['type'];
|
|
684
|
+
if (firstMarket['contract']) {
|
|
685
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
686
|
+
}
|
|
687
|
+
const name = 'depth';
|
|
688
|
+
let streamHash = 'multipleOrderbook';
|
|
689
|
+
if (symbols !== undefined) {
|
|
690
|
+
streamHash += '::' + symbols.join(',');
|
|
691
|
+
}
|
|
692
|
+
const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
|
|
693
|
+
const subParams = [];
|
|
694
|
+
const subMessageHashes = [];
|
|
695
|
+
const messageHashes = [];
|
|
696
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
697
|
+
const symbol = symbols[i];
|
|
698
|
+
const market = this.market(symbol);
|
|
699
|
+
subMessageHashes.push('orderbook::' + symbol);
|
|
700
|
+
messageHashes.push('unsubscribe:orderbook:' + symbol);
|
|
701
|
+
const subscriptionHash = market['lowercaseId'] + '@' + name;
|
|
702
|
+
const symbolHash = subscriptionHash + '@' + watchOrderBookRate + 'ms';
|
|
703
|
+
subParams.push(symbolHash);
|
|
704
|
+
}
|
|
705
|
+
const messageHashesLength = subMessageHashes.length;
|
|
706
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, messageHashesLength);
|
|
707
|
+
const requestId = this.requestId(url);
|
|
708
|
+
const request = {
|
|
709
|
+
'method': 'UNSUBSCRIBE',
|
|
710
|
+
'params': subParams,
|
|
711
|
+
'id': requestId,
|
|
712
|
+
};
|
|
713
|
+
const subscription = {
|
|
714
|
+
'unsubscribe': true,
|
|
715
|
+
'id': requestId.toString(),
|
|
716
|
+
'symbols': symbols,
|
|
717
|
+
'subMessageHashes': subMessageHashes,
|
|
718
|
+
'messageHashes': messageHashes,
|
|
719
|
+
'topic': 'orderbook',
|
|
720
|
+
};
|
|
721
|
+
return await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscription);
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* @method
|
|
725
|
+
* @name binance#unWatchOrderBook
|
|
726
|
+
* @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
727
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
|
|
728
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
|
|
729
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
730
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
731
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
|
|
732
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
|
|
733
|
+
* @param {string} symbol unified array of symbols
|
|
734
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
735
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
736
|
+
*/
|
|
737
|
+
async unWatchOrderBook(symbol, params = {}) {
|
|
738
|
+
return await this.unWatchOrderBookForSymbols([symbol], params);
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* @method
|
|
742
|
+
* @name binance#fetchOrderBookWs
|
|
743
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
744
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#order-book
|
|
745
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api/Order-Book
|
|
746
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
747
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
748
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
749
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
750
|
+
*/
|
|
751
|
+
async fetchOrderBookWs(symbol, limit = undefined, params = {}) {
|
|
752
|
+
await this.loadMarkets();
|
|
753
|
+
const market = this.market(symbol);
|
|
754
|
+
const payload = {
|
|
755
|
+
'symbol': market['id'],
|
|
756
|
+
};
|
|
757
|
+
if (limit !== undefined) {
|
|
758
|
+
payload['limit'] = limit;
|
|
759
|
+
}
|
|
760
|
+
const marketType = this.getMarketType('fetchOrderBookWs', market, params);
|
|
761
|
+
if (marketType !== 'future') {
|
|
762
|
+
throw new BadRequest(this.id + ' fetchOrderBookWs only supports swap markets');
|
|
763
|
+
}
|
|
764
|
+
const url = this.urls['api']['ws']['ws-api'][marketType];
|
|
765
|
+
const requestId = this.requestId(url);
|
|
766
|
+
const messageHash = requestId.toString();
|
|
767
|
+
let returnRateLimits = false;
|
|
768
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
|
|
769
|
+
payload['returnRateLimits'] = returnRateLimits;
|
|
770
|
+
params = this.omit(params, 'test');
|
|
771
|
+
const message = {
|
|
772
|
+
'id': messageHash,
|
|
773
|
+
'method': 'depth',
|
|
774
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
775
|
+
};
|
|
776
|
+
const subscription = {
|
|
777
|
+
'method': this.handleFetchOrderBook,
|
|
778
|
+
};
|
|
779
|
+
const orderbook = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
780
|
+
orderbook['symbol'] = market['symbol'];
|
|
781
|
+
return orderbook;
|
|
782
|
+
}
|
|
783
|
+
handleFetchOrderBook(client, message) {
|
|
784
|
+
//
|
|
785
|
+
// {
|
|
786
|
+
// "id":"51e2affb-0aba-4821-ba75-f2625006eb43",
|
|
787
|
+
// "status":200,
|
|
788
|
+
// "result":{
|
|
789
|
+
// "lastUpdateId":1027024,
|
|
790
|
+
// "E":1589436922972,
|
|
791
|
+
// "T":1589436922959,
|
|
792
|
+
// "bids":[
|
|
793
|
+
// [
|
|
794
|
+
// "4.00000000",
|
|
795
|
+
// "431.00000000"
|
|
796
|
+
// ]
|
|
797
|
+
// ],
|
|
798
|
+
// "asks":[
|
|
799
|
+
// [
|
|
800
|
+
// "4.00000200",
|
|
801
|
+
// "12.00000000"
|
|
802
|
+
// ]
|
|
803
|
+
// ]
|
|
804
|
+
// }
|
|
805
|
+
// }
|
|
806
|
+
//
|
|
807
|
+
const messageHash = this.safeString(message, 'id');
|
|
808
|
+
const result = this.safeDict(message, 'result');
|
|
809
|
+
const timestamp = this.safeInteger(result, 'T');
|
|
810
|
+
const orderbook = this.parseOrderBook(result, undefined, timestamp);
|
|
811
|
+
orderbook['nonce'] = this.safeInteger2(result, 'lastUpdateId', 'u');
|
|
812
|
+
client.resolve(orderbook, messageHash);
|
|
813
|
+
}
|
|
814
|
+
async fetchOrderBookSnapshot(client, message, subscription) {
|
|
815
|
+
const symbol = this.safeString(subscription, 'symbol');
|
|
816
|
+
const messageHash = 'orderbook::' + symbol;
|
|
817
|
+
try {
|
|
818
|
+
const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
|
|
819
|
+
const type = this.safeValue(subscription, 'type');
|
|
820
|
+
const limit = this.safeInteger(subscription, 'limit', defaultLimit);
|
|
821
|
+
const params = this.safeValue(subscription, 'params');
|
|
822
|
+
// 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
|
|
823
|
+
// todo: this is a synch blocking call - make it async
|
|
824
|
+
// default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
|
|
825
|
+
const snapshot = await this.fetchRestOrderBookSafe(symbol, limit, params);
|
|
826
|
+
if (this.safeValue(this.orderbooks, symbol) === undefined) {
|
|
827
|
+
// if the orderbook is dropped before the snapshot is received
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
const orderbook = this.orderbooks[symbol];
|
|
831
|
+
orderbook.reset(snapshot);
|
|
832
|
+
// unroll the accumulated deltas
|
|
833
|
+
const messages = orderbook.cache;
|
|
834
|
+
orderbook.cache = [];
|
|
835
|
+
for (let i = 0; i < messages.length; i++) {
|
|
836
|
+
const messageItem = messages[i];
|
|
837
|
+
const U = this.safeInteger(messageItem, 'U');
|
|
838
|
+
const u = this.safeInteger(messageItem, 'u');
|
|
839
|
+
const pu = this.safeInteger(messageItem, 'pu');
|
|
840
|
+
if (type === 'future') {
|
|
841
|
+
// 4. Drop any event where u is < lastUpdateId in the snapshot
|
|
842
|
+
if (u < orderbook['nonce']) {
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
// 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
|
|
846
|
+
if ((U <= orderbook['nonce']) && (u >= orderbook['nonce']) || (pu === orderbook['nonce'])) {
|
|
847
|
+
this.handleOrderBookMessage(client, messageItem, orderbook);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
// 4. Drop any event where u is <= lastUpdateId in the snapshot
|
|
852
|
+
if (u <= orderbook['nonce']) {
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
855
|
+
// 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
|
|
856
|
+
if (((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce'])) {
|
|
857
|
+
this.handleOrderBookMessage(client, messageItem, orderbook);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
this.orderbooks[symbol] = orderbook;
|
|
862
|
+
client.resolve(orderbook, messageHash);
|
|
863
|
+
}
|
|
864
|
+
catch (e) {
|
|
865
|
+
delete client.subscriptions[messageHash];
|
|
866
|
+
client.reject(e, messageHash);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
handleDelta(bookside, delta) {
|
|
870
|
+
const price = this.safeFloat(delta, 0);
|
|
871
|
+
const amount = this.safeFloat(delta, 1);
|
|
872
|
+
bookside.store(price, amount);
|
|
873
|
+
}
|
|
874
|
+
handleDeltas(bookside, deltas) {
|
|
875
|
+
for (let i = 0; i < deltas.length; i++) {
|
|
876
|
+
this.handleDelta(bookside, deltas[i]);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
handleOrderBookMessage(client, message, orderbook) {
|
|
880
|
+
const u = this.safeInteger(message, 'u');
|
|
881
|
+
this.handleDeltas(orderbook['asks'], this.safeValue(message, 'a', []));
|
|
882
|
+
this.handleDeltas(orderbook['bids'], this.safeValue(message, 'b', []));
|
|
883
|
+
orderbook['nonce'] = u;
|
|
884
|
+
const timestamp = this.safeInteger(message, 'E');
|
|
885
|
+
orderbook['timestamp'] = timestamp;
|
|
886
|
+
orderbook['datetime'] = this.iso8601(timestamp);
|
|
887
|
+
return orderbook;
|
|
888
|
+
}
|
|
889
|
+
handleOrderBook(client, message) {
|
|
890
|
+
//
|
|
891
|
+
// initial snapshot is fetched with ccxt's fetchOrderBook
|
|
892
|
+
// the feed does not include a snapshot, just the deltas
|
|
893
|
+
//
|
|
894
|
+
// {
|
|
895
|
+
// "e": "depthUpdate", // Event type
|
|
896
|
+
// "E": 1577554482280, // Event time
|
|
897
|
+
// "s": "BNBBTC", // Symbol
|
|
898
|
+
// "U": 157, // First update ID in event
|
|
899
|
+
// "u": 160, // Final update ID in event
|
|
900
|
+
// "b": [ // bids
|
|
901
|
+
// [ "0.0024", "10" ], // price, size
|
|
902
|
+
// ],
|
|
903
|
+
// "a": [ // asks
|
|
904
|
+
// [ "0.0026", "100" ], // price, size
|
|
905
|
+
// ]
|
|
906
|
+
// }
|
|
907
|
+
//
|
|
908
|
+
const isSpot = (client.url.indexOf('/stream') > -1);
|
|
909
|
+
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
910
|
+
const marketId = this.safeString(message, 's');
|
|
911
|
+
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
912
|
+
const symbol = market['symbol'];
|
|
913
|
+
const messageHash = 'orderbook::' + symbol;
|
|
914
|
+
if (!(symbol in this.orderbooks)) {
|
|
915
|
+
//
|
|
916
|
+
// https://github.com/ccxt/ccxt/issues/6672
|
|
917
|
+
//
|
|
918
|
+
// Sometimes Binance sends the first delta before the subscription
|
|
919
|
+
// confirmation arrives. At that point the orderbook is not
|
|
920
|
+
// initialized yet and the snapshot has not been requested yet
|
|
921
|
+
// therefore it is safe to drop these premature messages.
|
|
922
|
+
//
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
const orderbook = this.orderbooks[symbol];
|
|
926
|
+
const nonce = this.safeInteger(orderbook, 'nonce');
|
|
927
|
+
if (nonce === undefined) {
|
|
928
|
+
// 2. Buffer the events you receive from the stream.
|
|
929
|
+
orderbook.cache.push(message);
|
|
930
|
+
}
|
|
931
|
+
else {
|
|
932
|
+
try {
|
|
933
|
+
const U = this.safeInteger(message, 'U');
|
|
934
|
+
const u = this.safeInteger(message, 'u');
|
|
935
|
+
const pu = this.safeInteger(message, 'pu');
|
|
936
|
+
if (pu === undefined) {
|
|
937
|
+
// spot
|
|
938
|
+
// 4. Drop any event where u is <= lastUpdateId in the snapshot
|
|
939
|
+
if (u > orderbook['nonce']) {
|
|
940
|
+
const timestamp = this.safeInteger(orderbook, 'timestamp');
|
|
941
|
+
let conditional = undefined;
|
|
942
|
+
if (timestamp === undefined) {
|
|
943
|
+
// 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
|
|
944
|
+
conditional = ((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce']);
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
// 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
|
|
948
|
+
conditional = ((U - 1) === orderbook['nonce']);
|
|
949
|
+
}
|
|
950
|
+
if (conditional) {
|
|
951
|
+
this.handleOrderBookMessage(client, message, orderbook);
|
|
952
|
+
if (nonce < orderbook['nonce']) {
|
|
953
|
+
client.resolve(orderbook, messageHash);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
else {
|
|
957
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
958
|
+
if (checksum) {
|
|
959
|
+
// todo: client.reject from handleOrderBookMessage properly
|
|
960
|
+
throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
else {
|
|
966
|
+
// future
|
|
967
|
+
// 4. Drop any event where u is < lastUpdateId in the snapshot
|
|
968
|
+
if (u >= orderbook['nonce']) {
|
|
969
|
+
// 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
|
|
970
|
+
// 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
|
|
971
|
+
if ((U <= orderbook['nonce']) || (pu === orderbook['nonce'])) {
|
|
972
|
+
this.handleOrderBookMessage(client, message, orderbook);
|
|
973
|
+
if (nonce <= orderbook['nonce']) {
|
|
974
|
+
client.resolve(orderbook, messageHash);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
else {
|
|
978
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
979
|
+
if (checksum) {
|
|
980
|
+
// todo: client.reject from handleOrderBookMessage properly
|
|
981
|
+
throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
catch (e) {
|
|
988
|
+
delete this.orderbooks[symbol];
|
|
989
|
+
delete client.subscriptions[messageHash];
|
|
990
|
+
client.reject(e, messageHash);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
handleOrderBookSubscription(client, message, subscription) {
|
|
995
|
+
const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
|
|
996
|
+
// const messageHash = this.safeString (subscription, 'messageHash');
|
|
997
|
+
const symbolOfSubscription = this.safeString(subscription, 'symbol'); // watchOrderBook
|
|
998
|
+
const symbols = this.safeValue(subscription, 'symbols', [symbolOfSubscription]); // watchOrderBookForSymbols
|
|
999
|
+
const limit = this.safeInteger(subscription, 'limit', defaultLimit);
|
|
1000
|
+
// handle list of symbols
|
|
1001
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1002
|
+
const symbol = symbols[i];
|
|
1003
|
+
if (symbol in this.orderbooks) {
|
|
1004
|
+
delete this.orderbooks[symbol];
|
|
1005
|
+
}
|
|
1006
|
+
this.orderbooks[symbol] = this.orderBook({}, limit);
|
|
1007
|
+
subscription = this.extend(subscription, { 'symbol': symbol });
|
|
1008
|
+
// fetch the snapshot in a separate async call
|
|
1009
|
+
this.spawn(this.fetchOrderBookSnapshot, client, message, subscription);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
handleSubscriptionStatus(client, message) {
|
|
1013
|
+
//
|
|
1014
|
+
// {
|
|
1015
|
+
// "result": null,
|
|
1016
|
+
// "id": 1574649734450
|
|
1017
|
+
// }
|
|
1018
|
+
//
|
|
1019
|
+
const id = this.safeString(message, 'id');
|
|
1020
|
+
const subscriptionsById = this.indexBy(client.subscriptions, 'id');
|
|
1021
|
+
const subscription = this.safeValue(subscriptionsById, id, {});
|
|
1022
|
+
const method = this.safeValue(subscription, 'method');
|
|
1023
|
+
if (method !== undefined) {
|
|
1024
|
+
method.call(this, client, message, subscription);
|
|
1025
|
+
}
|
|
1026
|
+
const isUnSubMessage = this.safeBool(subscription, 'unsubscribe', false);
|
|
1027
|
+
if (isUnSubMessage) {
|
|
1028
|
+
this.handleUnSubscription(client, subscription);
|
|
1029
|
+
}
|
|
1030
|
+
return message;
|
|
1031
|
+
}
|
|
1032
|
+
handleUnSubscription(client, subscription) {
|
|
1033
|
+
const messageHashes = this.safeList(subscription, 'messageHashes', []);
|
|
1034
|
+
const subMessageHashes = this.safeList(subscription, 'subMessageHashes', []);
|
|
1035
|
+
for (let j = 0; j < messageHashes.length; j++) {
|
|
1036
|
+
const unsubHash = messageHashes[j];
|
|
1037
|
+
const subHash = subMessageHashes[j];
|
|
1038
|
+
this.cleanUnsubscription(client, subHash, unsubHash);
|
|
1039
|
+
}
|
|
1040
|
+
this.cleanCache(subscription);
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* @method
|
|
1044
|
+
* @name binance#watchTradesForSymbols
|
|
1045
|
+
* @description get the list of most recent trades for a list of symbols
|
|
1046
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
|
|
1047
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
|
|
1048
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1049
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1050
|
+
* @param {string[]} symbols unified symbol of the market to fetch trades for
|
|
1051
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1052
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1053
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1054
|
+
* @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
|
1055
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1056
|
+
*/
|
|
1057
|
+
async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
|
|
1058
|
+
await this.loadMarkets();
|
|
1059
|
+
symbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
1060
|
+
let streamHash = 'multipleTrades';
|
|
1061
|
+
if (symbols !== undefined) {
|
|
1062
|
+
const symbolsLength = symbols.length;
|
|
1063
|
+
if (symbolsLength > 200) {
|
|
1064
|
+
throw new BadRequest(this.id + ' watchTradesForSymbols() accepts 200 symbols at most. To watch more symbols call watchTradesForSymbols() multiple times');
|
|
1065
|
+
}
|
|
1066
|
+
streamHash += '::' + symbols.join(',');
|
|
1067
|
+
}
|
|
1068
|
+
let name = undefined;
|
|
1069
|
+
[name, params] = this.handleOptionAndParams(params, 'watchTradesForSymbols', 'name', 'trade');
|
|
1070
|
+
params = this.omit(params, 'callerMethodName');
|
|
1071
|
+
const firstMarket = this.market(symbols[0]);
|
|
1072
|
+
let type = firstMarket['type'];
|
|
1073
|
+
if (firstMarket['contract']) {
|
|
1074
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
1075
|
+
}
|
|
1076
|
+
const messageHashes = [];
|
|
1077
|
+
const subParams = [];
|
|
1078
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1079
|
+
const symbol = symbols[i];
|
|
1080
|
+
const market = this.market(symbol);
|
|
1081
|
+
messageHashes.push('trade::' + symbol);
|
|
1082
|
+
const rawHash = market['lowercaseId'] + '@' + name;
|
|
1083
|
+
subParams.push(rawHash);
|
|
1084
|
+
}
|
|
1085
|
+
const query = this.omit(params, 'type');
|
|
1086
|
+
const subParamsLength = subParams.length;
|
|
1087
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, subParamsLength);
|
|
1088
|
+
const requestId = this.requestId(url);
|
|
1089
|
+
const request = {
|
|
1090
|
+
'method': 'SUBSCRIBE',
|
|
1091
|
+
'params': subParams,
|
|
1092
|
+
'id': requestId,
|
|
1093
|
+
};
|
|
1094
|
+
const subscribe = {
|
|
1095
|
+
'id': requestId,
|
|
1096
|
+
};
|
|
1097
|
+
const trades = await this.watchMultiple(url, messageHashes, this.extend(request, query), messageHashes, subscribe);
|
|
1098
|
+
if (this.newUpdates) {
|
|
1099
|
+
const first = this.safeValue(trades, 0);
|
|
1100
|
+
const tradeSymbol = this.safeString(first, 'symbol');
|
|
1101
|
+
limit = trades.getLimit(tradeSymbol, limit);
|
|
1102
|
+
}
|
|
1103
|
+
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* @method
|
|
1107
|
+
* @name binance#unWatchTradesForSymbols
|
|
1108
|
+
* @description unsubscribes from the trades channel
|
|
1109
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
|
|
1110
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
|
|
1111
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1112
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1113
|
+
* @param {string[]} symbols unified symbol of the market to fetch trades for
|
|
1114
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1115
|
+
* @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
|
1116
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1117
|
+
*/
|
|
1118
|
+
async unWatchTradesForSymbols(symbols, params = {}) {
|
|
1119
|
+
await this.loadMarkets();
|
|
1120
|
+
symbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
1121
|
+
let streamHash = 'multipleTrades';
|
|
1122
|
+
if (symbols !== undefined) {
|
|
1123
|
+
const symbolsLength = symbols.length;
|
|
1124
|
+
if (symbolsLength > 200) {
|
|
1125
|
+
throw new BadRequest(this.id + ' watchTradesForSymbols() accepts 200 symbols at most. To watch more symbols call watchTradesForSymbols() multiple times');
|
|
1126
|
+
}
|
|
1127
|
+
streamHash += '::' + symbols.join(',');
|
|
1128
|
+
}
|
|
1129
|
+
let name = undefined;
|
|
1130
|
+
[name, params] = this.handleOptionAndParams(params, 'watchTradesForSymbols', 'name', 'trade');
|
|
1131
|
+
params = this.omit(params, 'callerMethodName');
|
|
1132
|
+
const firstMarket = this.market(symbols[0]);
|
|
1133
|
+
let type = firstMarket['type'];
|
|
1134
|
+
if (firstMarket['contract']) {
|
|
1135
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
1136
|
+
}
|
|
1137
|
+
const subMessageHashes = [];
|
|
1138
|
+
const subParams = [];
|
|
1139
|
+
const messageHashes = [];
|
|
1140
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1141
|
+
const symbol = symbols[i];
|
|
1142
|
+
const market = this.market(symbol);
|
|
1143
|
+
subMessageHashes.push('trade::' + symbol);
|
|
1144
|
+
messageHashes.push('unsubscribe:trade:' + symbol);
|
|
1145
|
+
const rawHash = market['lowercaseId'] + '@' + name;
|
|
1146
|
+
subParams.push(rawHash);
|
|
1147
|
+
}
|
|
1148
|
+
const query = this.omit(params, 'type');
|
|
1149
|
+
const subParamsLength = subParams.length;
|
|
1150
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, subParamsLength);
|
|
1151
|
+
const requestId = this.requestId(url);
|
|
1152
|
+
const request = {
|
|
1153
|
+
'method': 'UNSUBSCRIBE',
|
|
1154
|
+
'params': subParams,
|
|
1155
|
+
'id': requestId,
|
|
1156
|
+
};
|
|
1157
|
+
const subscription = {
|
|
1158
|
+
'unsubscribe': true,
|
|
1159
|
+
'id': requestId.toString(),
|
|
1160
|
+
'subMessageHashes': subMessageHashes,
|
|
1161
|
+
'messageHashes': messageHashes,
|
|
1162
|
+
'symbols': symbols,
|
|
1163
|
+
'topic': 'trades',
|
|
1164
|
+
};
|
|
1165
|
+
return await this.watchMultiple(url, messageHashes, this.extend(request, query), messageHashes, subscription);
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* @method
|
|
1169
|
+
* @name binance#unWatchTrades
|
|
1170
|
+
* @description unsubscribes from the trades channel
|
|
1171
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
|
|
1172
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
|
|
1173
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1174
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1175
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1176
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1177
|
+
* @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
|
1178
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1179
|
+
*/
|
|
1180
|
+
async unWatchTrades(symbol, params = {}) {
|
|
1181
|
+
await this.loadMarkets();
|
|
1182
|
+
return await this.unWatchTradesForSymbols([symbol], params);
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* @method
|
|
1186
|
+
* @name binance#watchTrades
|
|
1187
|
+
* @description get the list of most recent trades for a particular symbol
|
|
1188
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
|
|
1189
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
|
|
1190
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1191
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
|
|
1192
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1193
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1194
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1195
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1196
|
+
* @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
|
1197
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1198
|
+
*/
|
|
1199
|
+
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1200
|
+
params['callerMethodName'] = 'watchTrades';
|
|
1201
|
+
return await this.watchTradesForSymbols([symbol], since, limit, params);
|
|
1202
|
+
}
|
|
1203
|
+
parseWsTrade(trade, market = undefined) {
|
|
1204
|
+
//
|
|
1205
|
+
// public watchTrades
|
|
1206
|
+
//
|
|
1207
|
+
// {
|
|
1208
|
+
// "e": "trade", // event type
|
|
1209
|
+
// "E": 1579481530911, // event time
|
|
1210
|
+
// "s": "ETHBTC", // symbol
|
|
1211
|
+
// "t": 158410082, // trade id
|
|
1212
|
+
// "p": "0.01914100", // price
|
|
1213
|
+
// "q": "0.00700000", // quantity
|
|
1214
|
+
// "b": 586187049, // buyer order id
|
|
1215
|
+
// "a": 586186710, // seller order id
|
|
1216
|
+
// "T": 1579481530910, // trade time
|
|
1217
|
+
// "m": false, // is the buyer the market maker
|
|
1218
|
+
// "M": true // binance docs say it should be ignored
|
|
1219
|
+
// }
|
|
1220
|
+
//
|
|
1221
|
+
// {
|
|
1222
|
+
// "e": "aggTrade", // Event type
|
|
1223
|
+
// "E": 123456789, // Event time
|
|
1224
|
+
// "s": "BNBBTC", // Symbol
|
|
1225
|
+
// "a": 12345, // Aggregate trade ID
|
|
1226
|
+
// "p": "0.001", // Price
|
|
1227
|
+
// "q": "100", // Quantity
|
|
1228
|
+
// "f": 100, // First trade ID
|
|
1229
|
+
// "l": 105, // Last trade ID
|
|
1230
|
+
// "T": 123456785, // Trade time
|
|
1231
|
+
// "m": true, // Is the buyer the market maker?
|
|
1232
|
+
// "M": true // Ignore
|
|
1233
|
+
// }
|
|
1234
|
+
//
|
|
1235
|
+
// private watchMyTrades spot
|
|
1236
|
+
//
|
|
1237
|
+
// {
|
|
1238
|
+
// "e": "executionReport",
|
|
1239
|
+
// "E": 1611063861489,
|
|
1240
|
+
// "s": "BNBUSDT",
|
|
1241
|
+
// "c": "m4M6AD5MF3b1ERe65l4SPq",
|
|
1242
|
+
// "S": "BUY",
|
|
1243
|
+
// "o": "MARKET",
|
|
1244
|
+
// "f": "GTC",
|
|
1245
|
+
// "q": "2.00000000",
|
|
1246
|
+
// "p": "0.00000000",
|
|
1247
|
+
// "P": "0.00000000",
|
|
1248
|
+
// "F": "0.00000000",
|
|
1249
|
+
// "g": -1,
|
|
1250
|
+
// "C": '',
|
|
1251
|
+
// "x": "TRADE",
|
|
1252
|
+
// "X": "PARTIALLY_FILLED",
|
|
1253
|
+
// "r": "NONE",
|
|
1254
|
+
// "i": 1296882607,
|
|
1255
|
+
// "l": "0.33200000",
|
|
1256
|
+
// "z": "0.33200000",
|
|
1257
|
+
// "L": "46.86600000",
|
|
1258
|
+
// "n": "0.00033200",
|
|
1259
|
+
// "N": "BNB",
|
|
1260
|
+
// "T": 1611063861488,
|
|
1261
|
+
// "t": 109747654,
|
|
1262
|
+
// "I": 2696953381,
|
|
1263
|
+
// "w": false,
|
|
1264
|
+
// "m": false,
|
|
1265
|
+
// "M": true,
|
|
1266
|
+
// "O": 1611063861488,
|
|
1267
|
+
// "Z": "15.55951200",
|
|
1268
|
+
// "Y": "15.55951200",
|
|
1269
|
+
// "Q": "0.00000000"
|
|
1270
|
+
// }
|
|
1271
|
+
//
|
|
1272
|
+
// private watchMyTrades future/delivery
|
|
1273
|
+
//
|
|
1274
|
+
// {
|
|
1275
|
+
// "s": "BTCUSDT",
|
|
1276
|
+
// "c": "pb2jD6ZQHpfzSdUac8VqMK",
|
|
1277
|
+
// "S": "SELL",
|
|
1278
|
+
// "o": "MARKET",
|
|
1279
|
+
// "f": "GTC",
|
|
1280
|
+
// "q": "0.001",
|
|
1281
|
+
// "p": "0",
|
|
1282
|
+
// "ap": "33468.46000",
|
|
1283
|
+
// "sp": "0",
|
|
1284
|
+
// "x": "TRADE",
|
|
1285
|
+
// "X": "FILLED",
|
|
1286
|
+
// "i": 13351197194,
|
|
1287
|
+
// "l": "0.001",
|
|
1288
|
+
// "z": "0.001",
|
|
1289
|
+
// "L": "33468.46",
|
|
1290
|
+
// "n": "0.00027086",
|
|
1291
|
+
// "N": "BNB",
|
|
1292
|
+
// "T": 1612095165362,
|
|
1293
|
+
// "t": 458032604,
|
|
1294
|
+
// "b": "0",
|
|
1295
|
+
// "a": "0",
|
|
1296
|
+
// "m": false,
|
|
1297
|
+
// "R": false,
|
|
1298
|
+
// "wt": "CONTRACT_PRICE",
|
|
1299
|
+
// "ot": "MARKET",
|
|
1300
|
+
// "ps": "BOTH",
|
|
1301
|
+
// "cp": false,
|
|
1302
|
+
// "rp": "0.00335000",
|
|
1303
|
+
// "pP": false,
|
|
1304
|
+
// "si": 0,
|
|
1305
|
+
// "ss": 0
|
|
1306
|
+
// }
|
|
1307
|
+
//
|
|
1308
|
+
const executionType = this.safeString(trade, 'x');
|
|
1309
|
+
const isTradeExecution = (executionType === 'TRADE');
|
|
1310
|
+
if (!isTradeExecution) {
|
|
1311
|
+
return this.parseTrade(trade, market);
|
|
1312
|
+
}
|
|
1313
|
+
const id = this.safeString2(trade, 't', 'a');
|
|
1314
|
+
const timestamp = this.safeInteger(trade, 'T');
|
|
1315
|
+
const price = this.safeString2(trade, 'L', 'p');
|
|
1316
|
+
let amount = this.safeString(trade, 'q');
|
|
1317
|
+
if (isTradeExecution) {
|
|
1318
|
+
amount = this.safeString(trade, 'l', amount);
|
|
1319
|
+
}
|
|
1320
|
+
let cost = this.safeString(trade, 'Y');
|
|
1321
|
+
if (cost === undefined) {
|
|
1322
|
+
if ((price !== undefined) && (amount !== undefined)) {
|
|
1323
|
+
cost = Precise.stringMul(price, amount);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
const marketId = this.safeString(trade, 's');
|
|
1327
|
+
const marketType = ('ps' in trade) ? 'contract' : 'spot';
|
|
1328
|
+
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
1329
|
+
let side = this.safeStringLower(trade, 'S');
|
|
1330
|
+
let takerOrMaker = undefined;
|
|
1331
|
+
const orderId = this.safeString(trade, 'i');
|
|
1332
|
+
if ('m' in trade) {
|
|
1333
|
+
if (side === undefined) {
|
|
1334
|
+
side = trade['m'] ? 'sell' : 'buy'; // this is reversed intentionally
|
|
1335
|
+
}
|
|
1336
|
+
takerOrMaker = trade['m'] ? 'maker' : 'taker';
|
|
1337
|
+
}
|
|
1338
|
+
let fee = undefined;
|
|
1339
|
+
const feeCost = this.safeString(trade, 'n');
|
|
1340
|
+
if (feeCost !== undefined) {
|
|
1341
|
+
const feeCurrencyId = this.safeString(trade, 'N');
|
|
1342
|
+
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
1343
|
+
fee = {
|
|
1344
|
+
'cost': feeCost,
|
|
1345
|
+
'currency': feeCurrencyCode,
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
const type = this.safeStringLower(trade, 'o');
|
|
1349
|
+
return this.safeTrade({
|
|
1350
|
+
'info': trade,
|
|
1351
|
+
'timestamp': timestamp,
|
|
1352
|
+
'datetime': this.iso8601(timestamp),
|
|
1353
|
+
'symbol': symbol,
|
|
1354
|
+
'id': id,
|
|
1355
|
+
'order': orderId,
|
|
1356
|
+
'type': type,
|
|
1357
|
+
'takerOrMaker': takerOrMaker,
|
|
1358
|
+
'side': side,
|
|
1359
|
+
'price': price,
|
|
1360
|
+
'amount': amount,
|
|
1361
|
+
'cost': cost,
|
|
1362
|
+
'fee': fee,
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
handleTrade(client, message) {
|
|
1366
|
+
// the trade streams push raw trade information in real-time
|
|
1367
|
+
// each trade has a unique buyer and seller
|
|
1368
|
+
const isSpot = (client.url.indexOf('/stream') > -1);
|
|
1369
|
+
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1370
|
+
const marketId = this.safeString(message, 's');
|
|
1371
|
+
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
1372
|
+
const symbol = market['symbol'];
|
|
1373
|
+
const messageHash = 'trade::' + symbol;
|
|
1374
|
+
const trade = this.parseWsTrade(message, market);
|
|
1375
|
+
let tradesArray = this.safeValue(this.trades, symbol);
|
|
1376
|
+
if (tradesArray === undefined) {
|
|
1377
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
1378
|
+
tradesArray = new ArrayCache(limit);
|
|
1379
|
+
}
|
|
1380
|
+
tradesArray.append(trade);
|
|
1381
|
+
this.trades[symbol] = tradesArray;
|
|
1382
|
+
client.resolve(tradesArray, messageHash);
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* @method
|
|
1386
|
+
* @name binance#watchOHLCV
|
|
1387
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1388
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
|
|
1389
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1390
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1391
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1392
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1393
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1394
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1395
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1396
|
+
* @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
|
1397
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1398
|
+
*/
|
|
1399
|
+
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1400
|
+
await this.loadMarkets();
|
|
1401
|
+
const market = this.market(symbol);
|
|
1402
|
+
symbol = market['symbol'];
|
|
1403
|
+
params['callerMethodName'] = 'watchOHLCV';
|
|
1404
|
+
const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
|
|
1405
|
+
return result[symbol][timeframe];
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* @method
|
|
1409
|
+
* @name binance#watchOHLCVForSymbols
|
|
1410
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1411
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
|
|
1412
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1413
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1414
|
+
* @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
1415
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1416
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1417
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1418
|
+
* @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
|
1419
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1420
|
+
*/
|
|
1421
|
+
async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
|
|
1422
|
+
await this.loadMarkets();
|
|
1423
|
+
let klineType = undefined;
|
|
1424
|
+
[klineType, params] = this.handleParamString2(params, 'channel', 'name', 'kline');
|
|
1425
|
+
const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
|
|
1426
|
+
const marketSymbols = this.marketSymbols(symbols, undefined, false, false, true);
|
|
1427
|
+
const firstMarket = this.market(marketSymbols[0]);
|
|
1428
|
+
let type = firstMarket['type'];
|
|
1429
|
+
if (firstMarket['contract']) {
|
|
1430
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
1431
|
+
}
|
|
1432
|
+
const isSpot = (type === 'spot');
|
|
1433
|
+
let timezone = undefined;
|
|
1434
|
+
[timezone, params] = this.handleParamString(params, 'timezone', undefined);
|
|
1435
|
+
const isUtc8 = (timezone !== undefined) && ((timezone === '+08:00') || Precise.stringEq(timezone, '8'));
|
|
1436
|
+
const rawHashes = [];
|
|
1437
|
+
const messageHashes = [];
|
|
1438
|
+
for (let i = 0; i < symbolsAndTimeframes.length; i++) {
|
|
1439
|
+
const symAndTf = symbolsAndTimeframes[i];
|
|
1440
|
+
const symbolString = symAndTf[0];
|
|
1441
|
+
const timeframeString = symAndTf[1];
|
|
1442
|
+
const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
|
|
1443
|
+
const market = this.market(symbolString);
|
|
1444
|
+
let marketId = market['lowercaseId'];
|
|
1445
|
+
if (klineType === 'indexPriceKline') {
|
|
1446
|
+
// weird behavior for index price kline we can't use the perp suffix
|
|
1447
|
+
marketId = marketId.replace('_perp', '');
|
|
1448
|
+
}
|
|
1449
|
+
const shouldUseUTC8 = (isUtc8 && isSpot);
|
|
1450
|
+
const suffix = '@+08:00';
|
|
1451
|
+
const utcSuffix = shouldUseUTC8 ? suffix : '';
|
|
1452
|
+
rawHashes.push(marketId + '@' + klineType + '_' + interval + utcSuffix);
|
|
1453
|
+
messageHashes.push('ohlcv::' + market['symbol'] + '::' + timeframeString);
|
|
1454
|
+
}
|
|
1455
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOHLCV');
|
|
1456
|
+
const requestId = this.requestId(url);
|
|
1457
|
+
const request = {
|
|
1458
|
+
'method': 'SUBSCRIBE',
|
|
1459
|
+
'params': rawHashes,
|
|
1460
|
+
'id': requestId,
|
|
1461
|
+
};
|
|
1462
|
+
const subscribe = {
|
|
1463
|
+
'id': requestId,
|
|
1464
|
+
};
|
|
1465
|
+
params = this.omit(params, 'callerMethodName');
|
|
1466
|
+
const [symbol, timeframe, candles] = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscribe);
|
|
1467
|
+
if (this.newUpdates) {
|
|
1468
|
+
limit = candles.getLimit(symbol, limit);
|
|
1469
|
+
}
|
|
1470
|
+
const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
|
|
1471
|
+
return this.createOHLCVObject(symbol, timeframe, filtered);
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* @method
|
|
1475
|
+
* @name binance#unWatchOHLCVForSymbols
|
|
1476
|
+
* @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1477
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
|
|
1478
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1479
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1480
|
+
* @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
1481
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1482
|
+
* @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
|
1483
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1484
|
+
*/
|
|
1485
|
+
async unWatchOHLCVForSymbols(symbolsAndTimeframes, params = {}) {
|
|
1486
|
+
await this.loadMarkets();
|
|
1487
|
+
let klineType = undefined;
|
|
1488
|
+
[klineType, params] = this.handleParamString2(params, 'channel', 'name', 'kline');
|
|
1489
|
+
const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
|
|
1490
|
+
const marketSymbols = this.marketSymbols(symbols, undefined, false, false, true);
|
|
1491
|
+
const firstMarket = this.market(marketSymbols[0]);
|
|
1492
|
+
let type = firstMarket['type'];
|
|
1493
|
+
if (firstMarket['contract']) {
|
|
1494
|
+
type = firstMarket['linear'] ? 'future' : 'delivery';
|
|
1495
|
+
}
|
|
1496
|
+
const isSpot = (type === 'spot');
|
|
1497
|
+
let timezone = undefined;
|
|
1498
|
+
[timezone, params] = this.handleParamString(params, 'timezone', undefined);
|
|
1499
|
+
const isUtc8 = (timezone !== undefined) && ((timezone === '+08:00') || Precise.stringEq(timezone, '8'));
|
|
1500
|
+
const rawHashes = [];
|
|
1501
|
+
const subMessageHashes = [];
|
|
1502
|
+
const messageHashes = [];
|
|
1503
|
+
for (let i = 0; i < symbolsAndTimeframes.length; i++) {
|
|
1504
|
+
const symAndTf = symbolsAndTimeframes[i];
|
|
1505
|
+
const symbolString = symAndTf[0];
|
|
1506
|
+
const timeframeString = symAndTf[1];
|
|
1507
|
+
const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
|
|
1508
|
+
const market = this.market(symbolString);
|
|
1509
|
+
let marketId = market['lowercaseId'];
|
|
1510
|
+
if (klineType === 'indexPriceKline') {
|
|
1511
|
+
// weird behavior for index price kline we can't use the perp suffix
|
|
1512
|
+
marketId = marketId.replace('_perp', '');
|
|
1513
|
+
}
|
|
1514
|
+
const shouldUseUTC8 = (isUtc8 && isSpot);
|
|
1515
|
+
const suffix = '@+08:00';
|
|
1516
|
+
const utcSuffix = shouldUseUTC8 ? suffix : '';
|
|
1517
|
+
rawHashes.push(marketId + '@' + klineType + '_' + interval + utcSuffix);
|
|
1518
|
+
subMessageHashes.push('ohlcv::' + market['symbol'] + '::' + timeframeString);
|
|
1519
|
+
messageHashes.push('unsubscribe::ohlcv::' + market['symbol'] + '::' + timeframeString);
|
|
1520
|
+
}
|
|
1521
|
+
const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOHLCV');
|
|
1522
|
+
const requestId = this.requestId(url);
|
|
1523
|
+
const request = {
|
|
1524
|
+
'method': 'UNSUBSCRIBE',
|
|
1525
|
+
'params': rawHashes,
|
|
1526
|
+
'id': requestId,
|
|
1527
|
+
};
|
|
1528
|
+
const subscribe = {
|
|
1529
|
+
'unsubscribe': true,
|
|
1530
|
+
'id': requestId.toString(),
|
|
1531
|
+
'symbols': symbols,
|
|
1532
|
+
'symbolsAndTimeframes': symbolsAndTimeframes,
|
|
1533
|
+
'subMessageHashes': subMessageHashes,
|
|
1534
|
+
'messageHashes': messageHashes,
|
|
1535
|
+
'topic': 'ohlcv',
|
|
1536
|
+
};
|
|
1537
|
+
params = this.omit(params, 'callerMethodName');
|
|
1538
|
+
return await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscribe);
|
|
1539
|
+
}
|
|
1540
|
+
/**
|
|
1541
|
+
* @method
|
|
1542
|
+
* @name binance#unWatchOHLCV
|
|
1543
|
+
* @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1544
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
|
|
1545
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1546
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
|
|
1547
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1548
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1549
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1550
|
+
* @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
|
1551
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1552
|
+
*/
|
|
1553
|
+
async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
|
|
1554
|
+
await this.loadMarkets();
|
|
1555
|
+
const market = this.market(symbol);
|
|
1556
|
+
symbol = market['symbol'];
|
|
1557
|
+
params['callerMethodName'] = 'watchOHLCV';
|
|
1558
|
+
return await this.unWatchOHLCVForSymbols([[symbol, timeframe]], params);
|
|
1559
|
+
}
|
|
1560
|
+
handleOHLCV(client, message) {
|
|
1561
|
+
//
|
|
1562
|
+
// {
|
|
1563
|
+
// "e": "kline",
|
|
1564
|
+
// "E": 1579482921215,
|
|
1565
|
+
// "s": "ETHBTC",
|
|
1566
|
+
// "k": {
|
|
1567
|
+
// "t": 1579482900000,
|
|
1568
|
+
// "T": 1579482959999,
|
|
1569
|
+
// "s": "ETHBTC",
|
|
1570
|
+
// "i": "1m",
|
|
1571
|
+
// "f": 158411535,
|
|
1572
|
+
// "L": 158411550,
|
|
1573
|
+
// "o": "0.01913200",
|
|
1574
|
+
// "c": "0.01913500",
|
|
1575
|
+
// "h": "0.01913700",
|
|
1576
|
+
// "l": "0.01913200",
|
|
1577
|
+
// "v": "5.08400000",
|
|
1578
|
+
// "n": 16,
|
|
1579
|
+
// "x": false,
|
|
1580
|
+
// "q": "0.09728060",
|
|
1581
|
+
// "V": "3.30200000",
|
|
1582
|
+
// "Q": "0.06318500",
|
|
1583
|
+
// "B": "0"
|
|
1584
|
+
// }
|
|
1585
|
+
// }
|
|
1586
|
+
//
|
|
1587
|
+
let event = this.safeString(message, 'e');
|
|
1588
|
+
const eventMap = {
|
|
1589
|
+
'indexPrice_kline': 'indexPriceKline',
|
|
1590
|
+
'markPrice_kline': 'markPriceKline',
|
|
1591
|
+
};
|
|
1592
|
+
event = this.safeString(eventMap, event, event);
|
|
1593
|
+
const kline = this.safeValue(message, 'k');
|
|
1594
|
+
let marketId = this.safeString2(kline, 's', 'ps');
|
|
1595
|
+
if (event === 'indexPriceKline') {
|
|
1596
|
+
// indexPriceKline doesn't have the _PERP suffix
|
|
1597
|
+
marketId = this.safeString(message, 'ps');
|
|
1598
|
+
}
|
|
1599
|
+
const interval = this.safeString(kline, 'i');
|
|
1600
|
+
// use a reverse lookup in a static map instead
|
|
1601
|
+
const unifiedTimeframe = this.findTimeframe(interval);
|
|
1602
|
+
const parsed = [
|
|
1603
|
+
this.safeInteger(kline, 't'),
|
|
1604
|
+
this.safeFloat(kline, 'o'),
|
|
1605
|
+
this.safeFloat(kline, 'h'),
|
|
1606
|
+
this.safeFloat(kline, 'l'),
|
|
1607
|
+
this.safeFloat(kline, 'c'),
|
|
1608
|
+
this.safeFloat(kline, 'v'),
|
|
1609
|
+
];
|
|
1610
|
+
const isSpot = (client.url.indexOf('/stream') > -1);
|
|
1611
|
+
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
1612
|
+
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
1613
|
+
const messageHash = 'ohlcv::' + symbol + '::' + unifiedTimeframe;
|
|
1614
|
+
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
|
|
1615
|
+
let stored = this.safeValue(this.ohlcvs[symbol], unifiedTimeframe);
|
|
1616
|
+
if (stored === undefined) {
|
|
1617
|
+
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
1618
|
+
stored = new ArrayCacheByTimestamp(limit);
|
|
1619
|
+
this.ohlcvs[symbol][unifiedTimeframe] = stored;
|
|
1620
|
+
}
|
|
1621
|
+
stored.append(parsed);
|
|
1622
|
+
const resolveData = [symbol, unifiedTimeframe, stored];
|
|
1623
|
+
client.resolve(resolveData, messageHash);
|
|
1624
|
+
}
|
|
1625
|
+
/**
|
|
1626
|
+
* @method
|
|
1627
|
+
* @name binance#fetchTickerWs
|
|
1628
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1629
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1630
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1631
|
+
* @param {string} [params.method] method to use can be ticker.price or ticker.book
|
|
1632
|
+
* @param {boolean} [params.returnRateLimits] return the rate limits for the exchange
|
|
1633
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1634
|
+
*/
|
|
1635
|
+
async fetchTickerWs(symbol, params = {}) {
|
|
1636
|
+
await this.loadMarkets();
|
|
1637
|
+
const market = this.market(symbol);
|
|
1638
|
+
const payload = {
|
|
1639
|
+
'symbol': market['id'],
|
|
1640
|
+
};
|
|
1641
|
+
const type = this.getMarketType('fetchTickerWs', market, params);
|
|
1642
|
+
if (type !== 'future') {
|
|
1643
|
+
throw new BadRequest(this.id + ' fetchTickerWs only supports swap markets');
|
|
1644
|
+
}
|
|
1645
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
1646
|
+
const requestId = this.requestId(url);
|
|
1647
|
+
const messageHash = requestId.toString();
|
|
1648
|
+
const subscription = {
|
|
1649
|
+
'method': this.handleTickerWs,
|
|
1650
|
+
};
|
|
1651
|
+
let returnRateLimits = false;
|
|
1652
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchTickerWs', 'returnRateLimits', false);
|
|
1653
|
+
payload['returnRateLimits'] = returnRateLimits;
|
|
1654
|
+
params = this.omit(params, 'test');
|
|
1655
|
+
let method = undefined;
|
|
1656
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchTickerWs', 'method', 'ticker.book');
|
|
1657
|
+
const message = {
|
|
1658
|
+
'id': messageHash,
|
|
1659
|
+
'method': method,
|
|
1660
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
1661
|
+
};
|
|
1662
|
+
const ticker = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1663
|
+
return ticker;
|
|
1664
|
+
}
|
|
1665
|
+
/**
|
|
1666
|
+
* @method
|
|
1667
|
+
* @name binance#fetchOHLCVWs
|
|
1668
|
+
* @description query historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1669
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
|
|
1670
|
+
* @param {string} symbol unified symbol of the market to query OHLCV data for
|
|
1671
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1672
|
+
* @param {int} since timestamp in ms of the earliest candle to fetch
|
|
1673
|
+
* @param {int} limit the maximum amount of candles to fetch
|
|
1674
|
+
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
1675
|
+
* @param {int} params.until timestamp in ms of the earliest candle to fetch
|
|
1676
|
+
*
|
|
1677
|
+
* EXCHANGE SPECIFIC PARAMETERS
|
|
1678
|
+
* @param {string} params.timeZone default=0 (UTC)
|
|
1679
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1680
|
+
*/
|
|
1681
|
+
async fetchOHLCVWs(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1682
|
+
await this.loadMarkets();
|
|
1683
|
+
const market = this.market(symbol);
|
|
1684
|
+
const marketType = this.getMarketType('fetchOHLCVWs', market, params);
|
|
1685
|
+
if (marketType !== 'spot' && marketType !== 'future') {
|
|
1686
|
+
throw new BadRequest(this.id + ' fetchOHLCVWs only supports spot or swap markets');
|
|
1687
|
+
}
|
|
1688
|
+
const url = this.urls['api']['ws']['ws-api'][marketType];
|
|
1689
|
+
const requestId = this.requestId(url);
|
|
1690
|
+
const messageHash = requestId.toString();
|
|
1691
|
+
let returnRateLimits = false;
|
|
1692
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOHLCVWs', 'returnRateLimits', false);
|
|
1693
|
+
const payload = {
|
|
1694
|
+
'symbol': this.marketId(symbol),
|
|
1695
|
+
'returnRateLimits': returnRateLimits,
|
|
1696
|
+
'interval': this.timeframes[timeframe],
|
|
1697
|
+
};
|
|
1698
|
+
const until = this.safeInteger(params, 'until');
|
|
1699
|
+
params = this.omit(params, 'until');
|
|
1700
|
+
if (since !== undefined) {
|
|
1701
|
+
payload['startTime'] = since;
|
|
1702
|
+
}
|
|
1703
|
+
if (limit !== undefined) {
|
|
1704
|
+
payload['limit'] = limit;
|
|
1705
|
+
}
|
|
1706
|
+
if (until !== undefined) {
|
|
1707
|
+
payload['endTime'] = until;
|
|
1708
|
+
}
|
|
1709
|
+
const message = {
|
|
1710
|
+
'id': messageHash,
|
|
1711
|
+
'method': 'klines',
|
|
1712
|
+
'params': this.extend(payload, params),
|
|
1713
|
+
};
|
|
1714
|
+
const subscription = {
|
|
1715
|
+
'method': this.handleFetchOHLCV,
|
|
1716
|
+
};
|
|
1717
|
+
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
1718
|
+
}
|
|
1719
|
+
handleFetchOHLCV(client, message) {
|
|
1720
|
+
//
|
|
1721
|
+
// {
|
|
1722
|
+
// "id": "1dbbeb56-8eea-466a-8f6e-86bdcfa2fc0b",
|
|
1723
|
+
// "status": 200,
|
|
1724
|
+
// "result": [
|
|
1725
|
+
// [
|
|
1726
|
+
// 1655971200000, // Kline open time
|
|
1727
|
+
// "0.01086000", // Open price
|
|
1728
|
+
// "0.01086600", // High price
|
|
1729
|
+
// "0.01083600", // Low price
|
|
1730
|
+
// "0.01083800", // Close price
|
|
1731
|
+
// "2290.53800000", // Volume
|
|
1732
|
+
// 1655974799999, // Kline close time
|
|
1733
|
+
// "24.85074442", // Quote asset volume
|
|
1734
|
+
// 2283, // Number of trades
|
|
1735
|
+
// "1171.64000000", // Taker buy base asset volume
|
|
1736
|
+
// "12.71225884", // Taker buy quote asset volume
|
|
1737
|
+
// "0" // Unused field, ignore
|
|
1738
|
+
// ]
|
|
1739
|
+
// ],
|
|
1740
|
+
// "rateLimits": [
|
|
1741
|
+
// {
|
|
1742
|
+
// "rateLimitType": "REQUEST_WEIGHT",
|
|
1743
|
+
// "interval": "MINUTE",
|
|
1744
|
+
// "intervalNum": 1,
|
|
1745
|
+
// "limit": 6000,
|
|
1746
|
+
// "count": 2
|
|
1747
|
+
// }
|
|
1748
|
+
// ]
|
|
1749
|
+
// }
|
|
1750
|
+
//
|
|
1751
|
+
const result = this.safeList(message, 'result');
|
|
1752
|
+
const parsed = this.parseOHLCVs(result);
|
|
1753
|
+
// use a reverse lookup in a static map instead
|
|
1754
|
+
const messageHash = this.safeString(message, 'id');
|
|
1755
|
+
client.resolve(parsed, messageHash);
|
|
1756
|
+
}
|
|
1757
|
+
/**
|
|
1758
|
+
* @method
|
|
1759
|
+
* @name binance#watchTicker
|
|
1760
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1761
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
|
|
1762
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
|
|
1763
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1764
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1765
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1766
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1767
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1768
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1769
|
+
* @param {string} [params.name] stream to use can be ticker or miniTicker
|
|
1770
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1771
|
+
*/
|
|
1772
|
+
async watchTicker(symbol, params = {}) {
|
|
1773
|
+
await this.loadMarkets();
|
|
1774
|
+
symbol = this.symbol(symbol);
|
|
1775
|
+
const tickers = await this.watchTickers([symbol], this.extend(params, { 'callerMethodName': 'watchTicker' }));
|
|
1776
|
+
return tickers[symbol];
|
|
1777
|
+
}
|
|
1778
|
+
/**
|
|
1779
|
+
* @method
|
|
1780
|
+
* @name binance#watchMarkPrice
|
|
1781
|
+
* @description watches a mark price for a specific market
|
|
1782
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Mark-Price-Stream
|
|
1783
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1784
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1785
|
+
* @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds
|
|
1786
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1787
|
+
*/
|
|
1788
|
+
async watchMarkPrice(symbol, params = {}) {
|
|
1789
|
+
await this.loadMarkets();
|
|
1790
|
+
symbol = this.symbol(symbol);
|
|
1791
|
+
const tickers = await this.watchMarkPrices([symbol], this.extend(params, { 'callerMethodName': 'watchMarkPrice' }));
|
|
1792
|
+
return tickers[symbol];
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* @method
|
|
1796
|
+
* @name binance#watchMarkPrices
|
|
1797
|
+
* @description watches the mark price for all markets
|
|
1798
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Mark-Price-Stream-for-All-market
|
|
1799
|
+
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
1800
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1801
|
+
* @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds
|
|
1802
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1803
|
+
*/
|
|
1804
|
+
async watchMarkPrices(symbols = undefined, params = {}) {
|
|
1805
|
+
let channelName = undefined;
|
|
1806
|
+
// for now watchmarkPrice uses the same messageHash as watchTicker
|
|
1807
|
+
// so it's impossible to watch both at the same time
|
|
1808
|
+
// refactor this to use different messageHashes
|
|
1809
|
+
[channelName, params] = this.handleOptionAndParams(params, 'watchMarkPrices', 'name', 'markPrice');
|
|
1810
|
+
const newTickers = await this.watchMultiTickerHelper('watchMarkPrices', channelName, symbols, params);
|
|
1811
|
+
if (this.newUpdates) {
|
|
1812
|
+
return newTickers;
|
|
1813
|
+
}
|
|
1814
|
+
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
1815
|
+
}
|
|
1816
|
+
/**
|
|
1817
|
+
* @method
|
|
1818
|
+
* @name binance#watchTickers
|
|
1819
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
1820
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
|
|
1821
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
|
|
1822
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1823
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1824
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1825
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1826
|
+
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
1827
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1828
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1829
|
+
*/
|
|
1830
|
+
async watchTickers(symbols = undefined, params = {}) {
|
|
1831
|
+
let channelName = undefined;
|
|
1832
|
+
[channelName, params] = this.handleOptionAndParams(params, 'watchTickers', 'name', 'ticker');
|
|
1833
|
+
if (channelName === 'bookTicker') {
|
|
1834
|
+
throw new BadRequest(this.id + ' deprecation notice - to subscribe for bids-asks, use watch_bids_asks() method instead');
|
|
1835
|
+
}
|
|
1836
|
+
const newTickers = await this.watchMultiTickerHelper('watchTickers', channelName, symbols, params);
|
|
1837
|
+
if (this.newUpdates) {
|
|
1838
|
+
return newTickers;
|
|
1839
|
+
}
|
|
1840
|
+
return this.filterByArray(this.tickers, 'symbol', symbols);
|
|
1841
|
+
}
|
|
1842
|
+
/**
|
|
1843
|
+
* @method
|
|
1844
|
+
* @name binance#unWatchTickers
|
|
1845
|
+
* @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
1846
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
|
|
1847
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
|
|
1848
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1849
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1850
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1851
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1852
|
+
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
1853
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1854
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1855
|
+
*/
|
|
1856
|
+
async unWatchTickers(symbols = undefined, params = {}) {
|
|
1857
|
+
let channelName = undefined;
|
|
1858
|
+
[channelName, params] = this.handleOptionAndParams(params, 'watchTickers', 'name', 'ticker');
|
|
1859
|
+
if (channelName === 'bookTicker') {
|
|
1860
|
+
throw new BadRequest(this.id + ' deprecation notice - to subscribe for bids-asks, use watch_bids_asks() method instead');
|
|
1861
|
+
}
|
|
1862
|
+
await this.loadMarkets();
|
|
1863
|
+
const methodName = 'watchTickers';
|
|
1864
|
+
symbols = this.marketSymbols(symbols, undefined, true, false, true);
|
|
1865
|
+
let firstMarket = undefined;
|
|
1866
|
+
let marketType = undefined;
|
|
1867
|
+
const symbolsDefined = (symbols !== undefined);
|
|
1868
|
+
if (symbolsDefined) {
|
|
1869
|
+
firstMarket = this.market(symbols[0]);
|
|
1870
|
+
}
|
|
1871
|
+
[marketType, params] = this.handleMarketTypeAndParams(methodName, firstMarket, params);
|
|
1872
|
+
let subType = undefined;
|
|
1873
|
+
[subType, params] = this.handleSubTypeAndParams(methodName, firstMarket, params);
|
|
1874
|
+
let rawMarketType = undefined;
|
|
1875
|
+
if (this.isLinear(marketType, subType)) {
|
|
1876
|
+
rawMarketType = 'future';
|
|
1877
|
+
}
|
|
1878
|
+
else if (this.isInverse(marketType, subType)) {
|
|
1879
|
+
rawMarketType = 'delivery';
|
|
1880
|
+
}
|
|
1881
|
+
else if (marketType === 'spot') {
|
|
1882
|
+
rawMarketType = marketType;
|
|
1883
|
+
}
|
|
1884
|
+
else {
|
|
1885
|
+
throw new NotSupported(this.id + ' ' + methodName + '() does not support options markets');
|
|
1886
|
+
}
|
|
1887
|
+
const isBidAsk = (channelName === 'bookTicker');
|
|
1888
|
+
const subscriptionArgs = [];
|
|
1889
|
+
const subMessageHashes = [];
|
|
1890
|
+
const messageHashes = [];
|
|
1891
|
+
if (symbolsDefined) {
|
|
1892
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1893
|
+
const symbol = symbols[i];
|
|
1894
|
+
const market = this.market(symbol);
|
|
1895
|
+
subscriptionArgs.push(market['lowercaseId'] + '@' + channelName);
|
|
1896
|
+
subMessageHashes.push(this.getMessageHash(channelName, market['symbol'], isBidAsk));
|
|
1897
|
+
messageHashes.push('unsubscribe:ticker:' + symbol);
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
else {
|
|
1901
|
+
if (isBidAsk) {
|
|
1902
|
+
if (marketType === 'spot') {
|
|
1903
|
+
throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires symbols for this channel for spot markets');
|
|
1904
|
+
}
|
|
1905
|
+
subscriptionArgs.push('!' + channelName);
|
|
1906
|
+
}
|
|
1907
|
+
else {
|
|
1908
|
+
subscriptionArgs.push('!' + channelName + '@arr');
|
|
1909
|
+
}
|
|
1910
|
+
subMessageHashes.push(this.getMessageHash(channelName, undefined, isBidAsk));
|
|
1911
|
+
messageHashes.push('unsubscribe:ticker');
|
|
1912
|
+
}
|
|
1913
|
+
let streamHash = channelName;
|
|
1914
|
+
if (symbolsDefined) {
|
|
1915
|
+
streamHash = channelName + '::' + symbols.join(',');
|
|
1916
|
+
}
|
|
1917
|
+
const url = this.urls['api']['ws'][rawMarketType] + '/' + this.stream(rawMarketType, streamHash);
|
|
1918
|
+
const requestId = this.requestId(url);
|
|
1919
|
+
const request = {
|
|
1920
|
+
'method': 'UNSUBSCRIBE',
|
|
1921
|
+
'params': subscriptionArgs,
|
|
1922
|
+
'id': requestId,
|
|
1923
|
+
};
|
|
1924
|
+
const subscription = {
|
|
1925
|
+
'unsubscribe': true,
|
|
1926
|
+
'id': requestId.toString(),
|
|
1927
|
+
'subMessageHashes': subMessageHashes,
|
|
1928
|
+
'messageHashes': subMessageHashes,
|
|
1929
|
+
'symbols': symbols,
|
|
1930
|
+
'topic': 'ticker',
|
|
1931
|
+
};
|
|
1932
|
+
return await this.watchMultiple(url, subMessageHashes, this.extend(request, params), subMessageHashes, subscription);
|
|
1933
|
+
}
|
|
1934
|
+
/**
|
|
1935
|
+
* @method
|
|
1936
|
+
* @name binance#unWatchTicker
|
|
1937
|
+
* @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
1938
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
|
|
1939
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
|
|
1940
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1941
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1942
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
|
|
1943
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
|
|
1944
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1945
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1946
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1947
|
+
*/
|
|
1948
|
+
async unWatchTicker(symbol, params = {}) {
|
|
1949
|
+
return await this.unWatchTickers([symbol], params);
|
|
1950
|
+
}
|
|
1951
|
+
/**
|
|
1952
|
+
* @method
|
|
1953
|
+
* @name binance#watchBidsAsks
|
|
1954
|
+
* @description watches best bid & ask for symbols
|
|
1955
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#symbol-order-book-ticker
|
|
1956
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Book-Tickers-Stream
|
|
1957
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Book-Tickers-Stream
|
|
1958
|
+
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
1959
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1960
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1961
|
+
*/
|
|
1962
|
+
async watchBidsAsks(symbols = undefined, params = {}) {
|
|
1963
|
+
await this.loadMarkets();
|
|
1964
|
+
symbols = this.marketSymbols(symbols, undefined, true, false, true);
|
|
1965
|
+
const result = await this.watchMultiTickerHelper('watchBidsAsks', 'bookTicker', symbols, params);
|
|
1966
|
+
if (this.newUpdates) {
|
|
1967
|
+
return result;
|
|
1968
|
+
}
|
|
1969
|
+
return this.filterByArray(this.bidsasks, 'symbol', symbols);
|
|
1970
|
+
}
|
|
1971
|
+
async watchMultiTickerHelper(methodName, channelName, symbols = undefined, params = {}) {
|
|
1972
|
+
await this.loadMarkets();
|
|
1973
|
+
symbols = this.marketSymbols(symbols, undefined, true, false, true);
|
|
1974
|
+
const isBidAsk = (channelName === 'bookTicker');
|
|
1975
|
+
const isMarkPrice = (channelName === 'markPrice');
|
|
1976
|
+
const use1sFreq = this.safeBool(params, 'use1sFreq', true);
|
|
1977
|
+
let firstMarket = undefined;
|
|
1978
|
+
let marketType = undefined;
|
|
1979
|
+
const symbolsDefined = (symbols !== undefined);
|
|
1980
|
+
if (symbolsDefined) {
|
|
1981
|
+
firstMarket = this.market(symbols[0]);
|
|
1982
|
+
}
|
|
1983
|
+
const defaultMarket = (isMarkPrice) ? 'swap' : undefined;
|
|
1984
|
+
[marketType, params] = this.handleMarketTypeAndParams(methodName, firstMarket, params, defaultMarket);
|
|
1985
|
+
let subType = undefined;
|
|
1986
|
+
[subType, params] = this.handleSubTypeAndParams(methodName, firstMarket, params);
|
|
1987
|
+
let rawMarketType = undefined;
|
|
1988
|
+
if (this.isLinear(marketType, subType)) {
|
|
1989
|
+
rawMarketType = 'future';
|
|
1990
|
+
}
|
|
1991
|
+
else if (this.isInverse(marketType, subType)) {
|
|
1992
|
+
rawMarketType = 'delivery';
|
|
1993
|
+
}
|
|
1994
|
+
else if (marketType === 'spot') {
|
|
1995
|
+
rawMarketType = marketType;
|
|
1996
|
+
}
|
|
1997
|
+
else {
|
|
1998
|
+
throw new NotSupported(this.id + ' ' + methodName + '() does not support options markets');
|
|
1999
|
+
}
|
|
2000
|
+
const subscriptionArgs = [];
|
|
2001
|
+
const messageHashes = [];
|
|
2002
|
+
let suffix = '';
|
|
2003
|
+
if (isMarkPrice) {
|
|
2004
|
+
suffix = (use1sFreq) ? '@1s' : '';
|
|
2005
|
+
}
|
|
2006
|
+
if (symbolsDefined) {
|
|
2007
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
2008
|
+
const symbol = symbols[i];
|
|
2009
|
+
const market = this.market(symbol);
|
|
2010
|
+
subscriptionArgs.push(market['lowercaseId'] + '@' + channelName + suffix);
|
|
2011
|
+
messageHashes.push(this.getMessageHash(channelName, market['symbol'], isBidAsk));
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
else {
|
|
2015
|
+
if (isBidAsk) {
|
|
2016
|
+
if (marketType === 'spot') {
|
|
2017
|
+
throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires symbols for this channel for spot markets');
|
|
2018
|
+
}
|
|
2019
|
+
subscriptionArgs.push('!' + channelName);
|
|
2020
|
+
}
|
|
2021
|
+
else if (isMarkPrice) {
|
|
2022
|
+
subscriptionArgs.push('!' + channelName + '@arr' + suffix);
|
|
2023
|
+
}
|
|
2024
|
+
else {
|
|
2025
|
+
subscriptionArgs.push('!' + channelName + '@arr');
|
|
2026
|
+
}
|
|
2027
|
+
messageHashes.push(this.getMessageHash(channelName, undefined, isBidAsk));
|
|
2028
|
+
}
|
|
2029
|
+
let streamHash = channelName;
|
|
2030
|
+
if (symbolsDefined) {
|
|
2031
|
+
streamHash = channelName + '::' + symbols.join(',');
|
|
2032
|
+
}
|
|
2033
|
+
const url = this.urls['api']['ws'][rawMarketType] + '/' + this.stream(rawMarketType, streamHash);
|
|
2034
|
+
const requestId = this.requestId(url);
|
|
2035
|
+
const request = {
|
|
2036
|
+
'method': 'SUBSCRIBE',
|
|
2037
|
+
'params': subscriptionArgs,
|
|
2038
|
+
'id': requestId,
|
|
2039
|
+
};
|
|
2040
|
+
const subscribe = {
|
|
2041
|
+
'id': requestId,
|
|
2042
|
+
};
|
|
2043
|
+
const result = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), subscriptionArgs, subscribe);
|
|
2044
|
+
// for efficiency, we have two type of returned structure here - if symbols array was provided, then individual
|
|
2045
|
+
// ticker dict comes in, otherwise all-tickers dict comes in
|
|
2046
|
+
if (!symbolsDefined) {
|
|
2047
|
+
return result;
|
|
2048
|
+
}
|
|
2049
|
+
else {
|
|
2050
|
+
const newDict = {};
|
|
2051
|
+
newDict[result['symbol']] = result;
|
|
2052
|
+
return newDict;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
parseWsTicker(message, marketType) {
|
|
2056
|
+
// markPrice
|
|
2057
|
+
// {
|
|
2058
|
+
// "e": "markPriceUpdate", // Event type
|
|
2059
|
+
// "E": 1562305380000, // Event time
|
|
2060
|
+
// "s": "BTCUSDT", // Symbol
|
|
2061
|
+
// "p": "11794.15000000", // Mark price
|
|
2062
|
+
// "i": "11784.62659091", // Index price
|
|
2063
|
+
// "P": "11784.25641265", // Estimated Settle Price, only useful in the last hour before the settlement starts
|
|
2064
|
+
// "r": "0.00038167", // Funding rate
|
|
2065
|
+
// "T": 1562306400000 // Next funding time
|
|
2066
|
+
// }
|
|
2067
|
+
//
|
|
2068
|
+
// ticker
|
|
2069
|
+
// {
|
|
2070
|
+
// "e": "24hrTicker", // event type
|
|
2071
|
+
// "E": 1579485598569, // event time
|
|
2072
|
+
// "s": "ETHBTC", // symbol
|
|
2073
|
+
// "p": "-0.00004000", // price change
|
|
2074
|
+
// "P": "-0.209", // price change percent
|
|
2075
|
+
// "w": "0.01920495", // weighted average price
|
|
2076
|
+
// "x": "0.01916500", // the price of the first trade before the 24hr rolling window
|
|
2077
|
+
// "c": "0.01912500", // last (closing) price
|
|
2078
|
+
// "Q": "0.10400000", // last quantity
|
|
2079
|
+
// "b": "0.01912200", // best bid
|
|
2080
|
+
// "B": "4.10400000", // best bid quantity
|
|
2081
|
+
// "a": "0.01912500", // best ask
|
|
2082
|
+
// "A": "0.00100000", // best ask quantity
|
|
2083
|
+
// "o": "0.01916500", // open price
|
|
2084
|
+
// "h": "0.01956500", // high price
|
|
2085
|
+
// "l": "0.01887700", // low price
|
|
2086
|
+
// "v": "173518.11900000", // base volume
|
|
2087
|
+
// "q": "3332.40703994", // quote volume
|
|
2088
|
+
// "O": 1579399197842, // open time
|
|
2089
|
+
// "C": 1579485597842, // close time
|
|
2090
|
+
// "F": 158251292, // first trade id
|
|
2091
|
+
// "L": 158414513, // last trade id
|
|
2092
|
+
// "n": 163222, // total number of trades
|
|
2093
|
+
// }
|
|
2094
|
+
//
|
|
2095
|
+
// miniTicker
|
|
2096
|
+
// {
|
|
2097
|
+
// "e": "24hrMiniTicker",
|
|
2098
|
+
// "E": 1671617114585,
|
|
2099
|
+
// "s": "MOBBUSD",
|
|
2100
|
+
// "c": "0.95900000",
|
|
2101
|
+
// "o": "0.91200000",
|
|
2102
|
+
// "h": "1.04000000",
|
|
2103
|
+
// "l": "0.89400000",
|
|
2104
|
+
// "v": "2109995.32000000",
|
|
2105
|
+
// "q": "2019254.05788000"
|
|
2106
|
+
// }
|
|
2107
|
+
// fetchTickerWs
|
|
2108
|
+
// {
|
|
2109
|
+
// "symbol":"BTCUSDT",
|
|
2110
|
+
// "price":"72606.70",
|
|
2111
|
+
// "time":1712526204284
|
|
2112
|
+
// }
|
|
2113
|
+
// fetchTickerWs - ticker.book
|
|
2114
|
+
// {
|
|
2115
|
+
// "lastUpdateId":1027024,
|
|
2116
|
+
// "symbol":"BTCUSDT",
|
|
2117
|
+
// "bidPrice":"4.00000000",
|
|
2118
|
+
// "bidQty":"431.00000000",
|
|
2119
|
+
// "askPrice":"4.00000200",
|
|
2120
|
+
// "askQty":"9.00000000",
|
|
2121
|
+
// "time":1589437530011,
|
|
2122
|
+
// }
|
|
2123
|
+
//
|
|
2124
|
+
const marketId = this.safeString2(message, 's', 'symbol');
|
|
2125
|
+
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
2126
|
+
let event = this.safeString(message, 'e', 'bookTicker');
|
|
2127
|
+
if (event === '24hrTicker') {
|
|
2128
|
+
event = 'ticker';
|
|
2129
|
+
}
|
|
2130
|
+
if (event === 'markPriceUpdate') {
|
|
2131
|
+
// handle this separately because some fields clash with the ticker fields
|
|
2132
|
+
return this.safeTicker({
|
|
2133
|
+
'symbol': symbol,
|
|
2134
|
+
'timestamp': this.safeInteger(message, 'E'),
|
|
2135
|
+
'datetime': this.iso8601(this.safeInteger(message, 'E')),
|
|
2136
|
+
'info': message,
|
|
2137
|
+
'markPrice': this.safeString(message, 'p'),
|
|
2138
|
+
'indexPrice': this.safeString(message, 'i'),
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
let timestamp = undefined;
|
|
2142
|
+
if (event === 'bookTicker') {
|
|
2143
|
+
// take the event timestamp, if available, for spot tickers it is not
|
|
2144
|
+
timestamp = this.safeInteger2(message, 'E', 'time');
|
|
2145
|
+
}
|
|
2146
|
+
else {
|
|
2147
|
+
// take the timestamp of the closing price for candlestick streams
|
|
2148
|
+
timestamp = this.safeIntegerN(message, ['C', 'E', 'time']);
|
|
2149
|
+
}
|
|
2150
|
+
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
2151
|
+
const last = this.safeString2(message, 'c', 'price');
|
|
2152
|
+
return this.safeTicker({
|
|
2153
|
+
'symbol': symbol,
|
|
2154
|
+
'timestamp': timestamp,
|
|
2155
|
+
'datetime': this.iso8601(timestamp),
|
|
2156
|
+
'high': this.safeString(message, 'h'),
|
|
2157
|
+
'low': this.safeString(message, 'l'),
|
|
2158
|
+
'bid': this.safeString2(message, 'b', 'bidPrice'),
|
|
2159
|
+
'bidVolume': this.safeString2(message, 'B', 'bidQty'),
|
|
2160
|
+
'ask': this.safeString2(message, 'a', 'askPrice'),
|
|
2161
|
+
'askVolume': this.safeString2(message, 'A', 'askQty'),
|
|
2162
|
+
'vwap': this.safeString(message, 'w'),
|
|
2163
|
+
'open': this.safeString(message, 'o'),
|
|
2164
|
+
'close': last,
|
|
2165
|
+
'last': last,
|
|
2166
|
+
'previousClose': this.safeString(message, 'x'),
|
|
2167
|
+
'change': this.safeString(message, 'p'),
|
|
2168
|
+
'percentage': this.safeString(message, 'P'),
|
|
2169
|
+
'average': undefined,
|
|
2170
|
+
'baseVolume': this.safeString(message, 'v'),
|
|
2171
|
+
'quoteVolume': this.safeString(message, 'q'),
|
|
2172
|
+
'info': message,
|
|
2173
|
+
}, market);
|
|
2174
|
+
}
|
|
2175
|
+
handleTickerWs(client, message) {
|
|
2176
|
+
//
|
|
2177
|
+
// ticker.price
|
|
2178
|
+
// {
|
|
2179
|
+
// "id":"1",
|
|
2180
|
+
// "status":200,
|
|
2181
|
+
// "result":{
|
|
2182
|
+
// "symbol":"BTCUSDT",
|
|
2183
|
+
// "price":"73178.50",
|
|
2184
|
+
// "time":1712527052374
|
|
2185
|
+
// }
|
|
2186
|
+
// }
|
|
2187
|
+
// ticker.book
|
|
2188
|
+
// {
|
|
2189
|
+
// "id":"9d32157c-a556-4d27-9866-66760a174b57",
|
|
2190
|
+
// "status":200,
|
|
2191
|
+
// "result":{
|
|
2192
|
+
// "lastUpdateId":1027024,
|
|
2193
|
+
// "symbol":"BTCUSDT",
|
|
2194
|
+
// "bidPrice":"4.00000000",
|
|
2195
|
+
// "bidQty":"431.00000000",
|
|
2196
|
+
// "askPrice":"4.00000200",
|
|
2197
|
+
// "askQty":"9.00000000",
|
|
2198
|
+
// "time":1589437530011 // Transaction time
|
|
2199
|
+
// }
|
|
2200
|
+
// }
|
|
2201
|
+
//
|
|
2202
|
+
const messageHash = this.safeString(message, 'id');
|
|
2203
|
+
const result = this.safeValue(message, 'result', {});
|
|
2204
|
+
const ticker = this.parseWsTicker(result, 'future');
|
|
2205
|
+
client.resolve(ticker, messageHash);
|
|
2206
|
+
}
|
|
2207
|
+
handleBidsAsks(client, message) {
|
|
2208
|
+
//
|
|
2209
|
+
// arrives one symbol dict or array of symbol dicts
|
|
2210
|
+
//
|
|
2211
|
+
// {
|
|
2212
|
+
// "u": 7488717758,
|
|
2213
|
+
// "s": "BTCUSDT",
|
|
2214
|
+
// "b": "28621.74000000",
|
|
2215
|
+
// "B": "1.43278800",
|
|
2216
|
+
// "a": "28621.75000000",
|
|
2217
|
+
// "A": "2.52500800"
|
|
2218
|
+
// }
|
|
2219
|
+
//
|
|
2220
|
+
this.handleTickersAndBidsAsks(client, message, 'bidasks');
|
|
2221
|
+
}
|
|
2222
|
+
handleTickers(client, message) {
|
|
2223
|
+
//
|
|
2224
|
+
// arrives one symbol dict or array of symbol dicts
|
|
2225
|
+
//
|
|
2226
|
+
// {
|
|
2227
|
+
// "e": "24hrTicker", // event type
|
|
2228
|
+
// "E": 1579485598569, // event time
|
|
2229
|
+
// "s": "ETHBTC", // symbol
|
|
2230
|
+
// "p": "-0.00004000", // price change
|
|
2231
|
+
// "P": "-0.209", // price change percent
|
|
2232
|
+
// "w": "0.01920495", // weighted average price
|
|
2233
|
+
// "x": "0.01916500", // the price of the first trade before the 24hr rolling window
|
|
2234
|
+
// "c": "0.01912500", // last (closing) price
|
|
2235
|
+
// "Q": "0.10400000", // last quantity
|
|
2236
|
+
// "b": "0.01912200", // best bid
|
|
2237
|
+
// "B": "4.10400000", // best bid quantity
|
|
2238
|
+
// "a": "0.01912500", // best ask
|
|
2239
|
+
// "A": "0.00100000", // best ask quantity
|
|
2240
|
+
// "o": "0.01916500", // open price
|
|
2241
|
+
// "h": "0.01956500", // high price
|
|
2242
|
+
// "l": "0.01887700", // low price
|
|
2243
|
+
// "v": "173518.11900000", // base volume
|
|
2244
|
+
// "q": "3332.40703994", // quote volume
|
|
2245
|
+
// "O": 1579399197842, // open time
|
|
2246
|
+
// "C": 1579485597842, // close time
|
|
2247
|
+
// "F": 158251292, // first trade id
|
|
2248
|
+
// "L": 158414513, // last trade id
|
|
2249
|
+
// "n": 163222, // total number of trades
|
|
2250
|
+
// }
|
|
2251
|
+
//
|
|
2252
|
+
this.handleTickersAndBidsAsks(client, message, 'tickers');
|
|
2253
|
+
}
|
|
2254
|
+
handleTickersAndBidsAsks(client, message, methodType) {
|
|
2255
|
+
const isSpot = (client.url.indexOf('/stream') > -1);
|
|
2256
|
+
const marketType = (isSpot) ? 'spot' : 'contract';
|
|
2257
|
+
const isBidAsk = (methodType === 'bidasks');
|
|
2258
|
+
let channelName = undefined;
|
|
2259
|
+
const resolvedMessageHashes = [];
|
|
2260
|
+
let rawTickers = [];
|
|
2261
|
+
const newTickers = {};
|
|
2262
|
+
if (Array.isArray(message)) {
|
|
2263
|
+
rawTickers = message;
|
|
2264
|
+
}
|
|
2265
|
+
else {
|
|
2266
|
+
rawTickers.push(message);
|
|
2267
|
+
}
|
|
2268
|
+
for (let i = 0; i < rawTickers.length; i++) {
|
|
2269
|
+
const ticker = rawTickers[i];
|
|
2270
|
+
let event = this.safeString(ticker, 'e');
|
|
2271
|
+
if (isBidAsk) {
|
|
2272
|
+
event = 'bookTicker'; // as noted in `handleMessage`, bookTicker doesn't have identifier, so manually set here
|
|
2273
|
+
}
|
|
2274
|
+
channelName = this.safeString(this.options['tickerChannelsMap'], event, event);
|
|
2275
|
+
if (channelName === undefined) {
|
|
2276
|
+
continue;
|
|
2277
|
+
}
|
|
2278
|
+
const parsedTicker = this.parseWsTicker(ticker, marketType);
|
|
2279
|
+
const symbol = parsedTicker['symbol'];
|
|
2280
|
+
newTickers[symbol] = parsedTicker;
|
|
2281
|
+
if (isBidAsk) {
|
|
2282
|
+
this.bidsasks[symbol] = parsedTicker;
|
|
2283
|
+
}
|
|
2284
|
+
else {
|
|
2285
|
+
this.tickers[symbol] = parsedTicker;
|
|
2286
|
+
}
|
|
2287
|
+
const messageHash = this.getMessageHash(channelName, symbol, isBidAsk);
|
|
2288
|
+
resolvedMessageHashes.push(messageHash);
|
|
2289
|
+
client.resolve(parsedTicker, messageHash);
|
|
2290
|
+
}
|
|
2291
|
+
// resolve batch endpoint
|
|
2292
|
+
const length = resolvedMessageHashes.length;
|
|
2293
|
+
if (length > 0) {
|
|
2294
|
+
const batchMessageHash = this.getMessageHash(channelName, undefined, isBidAsk);
|
|
2295
|
+
client.resolve(newTickers, batchMessageHash);
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
getMessageHash(channelName, symbol, isBidAsk) {
|
|
2299
|
+
const prefix = isBidAsk ? 'bidask' : 'ticker';
|
|
2300
|
+
if (symbol !== undefined) {
|
|
2301
|
+
return prefix + ':' + channelName + '@' + symbol;
|
|
2302
|
+
}
|
|
2303
|
+
else {
|
|
2304
|
+
return prefix + 's' + ':' + channelName;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
signParams(params = {}) {
|
|
2308
|
+
this.checkRequiredCredentials();
|
|
2309
|
+
let extendedParams = this.extend({
|
|
2310
|
+
'timestamp': this.nonce(),
|
|
2311
|
+
'apiKey': this.apiKey,
|
|
2312
|
+
}, params);
|
|
2313
|
+
const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
|
|
2314
|
+
if (defaultRecvWindow !== undefined) {
|
|
2315
|
+
params['recvWindow'] = defaultRecvWindow;
|
|
2316
|
+
}
|
|
2317
|
+
const recvWindow = this.safeInteger(params, 'recvWindow');
|
|
2318
|
+
if (recvWindow !== undefined) {
|
|
2319
|
+
params['recvWindow'] = recvWindow;
|
|
2320
|
+
}
|
|
2321
|
+
extendedParams = this.keysort(extendedParams);
|
|
2322
|
+
const query = this.urlencode(extendedParams);
|
|
2323
|
+
let signature = undefined;
|
|
2324
|
+
if (this.secret.indexOf('PRIVATE KEY') > -1) {
|
|
2325
|
+
if (this.secret.length > 120) {
|
|
2326
|
+
signature = rsa(query, this.secret, sha256);
|
|
2327
|
+
}
|
|
2328
|
+
else {
|
|
2329
|
+
signature = eddsa(this.encode(query), this.secret, ed25519);
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
else {
|
|
2333
|
+
signature = this.hmac(this.encode(query), this.encode(this.secret), sha256);
|
|
2334
|
+
}
|
|
2335
|
+
extendedParams['signature'] = signature;
|
|
2336
|
+
return extendedParams;
|
|
2337
|
+
}
|
|
2338
|
+
async authenticate(params = {}) {
|
|
2339
|
+
const time = this.milliseconds();
|
|
2340
|
+
let type = undefined;
|
|
2341
|
+
[type, params] = this.handleMarketTypeAndParams('authenticate', undefined, params);
|
|
2342
|
+
let subType = undefined;
|
|
2343
|
+
[subType, params] = this.handleSubTypeAndParams('authenticate', undefined, params);
|
|
2344
|
+
let isPortfolioMargin = undefined;
|
|
2345
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'authenticate', 'papi', 'portfolioMargin', false);
|
|
2346
|
+
if (this.isLinear(type, subType)) {
|
|
2347
|
+
type = 'future';
|
|
2348
|
+
}
|
|
2349
|
+
else if (this.isInverse(type, subType)) {
|
|
2350
|
+
type = 'delivery';
|
|
2351
|
+
}
|
|
2352
|
+
let marginMode = undefined;
|
|
2353
|
+
[marginMode, params] = this.handleMarginModeAndParams('authenticate', params);
|
|
2354
|
+
const isIsolatedMargin = (marginMode === 'isolated');
|
|
2355
|
+
const isCrossMargin = (marginMode === 'cross') || (marginMode === undefined);
|
|
2356
|
+
const symbol = this.safeString(params, 'symbol');
|
|
2357
|
+
params = this.omit(params, 'symbol');
|
|
2358
|
+
const options = this.safeValue(this.options, type, {});
|
|
2359
|
+
const lastAuthenticatedTime = this.safeInteger(options, 'lastAuthenticatedTime', 0);
|
|
2360
|
+
const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
|
|
2361
|
+
const delay = this.sum(listenKeyRefreshRate, 10000);
|
|
2362
|
+
if (time - lastAuthenticatedTime > delay) {
|
|
2363
|
+
let response = undefined;
|
|
2364
|
+
if (isPortfolioMargin) {
|
|
2365
|
+
response = await this.papiPostListenKey(params);
|
|
2366
|
+
params = this.extend(params, { 'portfolioMargin': true });
|
|
2367
|
+
}
|
|
2368
|
+
else if (type === 'future') {
|
|
2369
|
+
response = await this.fapiPrivatePostListenKey(params);
|
|
2370
|
+
}
|
|
2371
|
+
else if (type === 'delivery') {
|
|
2372
|
+
response = await this.dapiPrivatePostListenKey(params);
|
|
2373
|
+
}
|
|
2374
|
+
else if (type === 'margin' && isCrossMargin) {
|
|
2375
|
+
response = await this.sapiPostUserDataStream(params);
|
|
2376
|
+
}
|
|
2377
|
+
else if (isIsolatedMargin) {
|
|
2378
|
+
if (symbol === undefined) {
|
|
2379
|
+
throw new ArgumentsRequired(this.id + ' authenticate() requires a symbol argument for isolated margin mode');
|
|
2380
|
+
}
|
|
2381
|
+
const marketId = this.marketId(symbol);
|
|
2382
|
+
params = this.extend(params, { 'symbol': marketId });
|
|
2383
|
+
response = await this.sapiPostUserDataStreamIsolated(params);
|
|
2384
|
+
}
|
|
2385
|
+
else {
|
|
2386
|
+
response = await this.publicPostUserDataStream(params);
|
|
2387
|
+
}
|
|
2388
|
+
this.options[type] = this.extend(options, {
|
|
2389
|
+
'listenKey': this.safeString(response, 'listenKey'),
|
|
2390
|
+
'lastAuthenticatedTime': time,
|
|
2391
|
+
});
|
|
2392
|
+
this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
async keepAliveListenKey(params = {}) {
|
|
2396
|
+
// https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot
|
|
2397
|
+
let type = this.safeString2(this.options, 'defaultType', 'authenticate', 'spot');
|
|
2398
|
+
type = this.safeString(params, 'type', type);
|
|
2399
|
+
let isPortfolioMargin = undefined;
|
|
2400
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'keepAliveListenKey', 'papi', 'portfolioMargin', false);
|
|
2401
|
+
const subTypeInfo = this.handleSubTypeAndParams('keepAliveListenKey', undefined, params);
|
|
2402
|
+
const subType = subTypeInfo[0];
|
|
2403
|
+
if (this.isLinear(type, subType)) {
|
|
2404
|
+
type = 'future';
|
|
2405
|
+
}
|
|
2406
|
+
else if (this.isInverse(type, subType)) {
|
|
2407
|
+
type = 'delivery';
|
|
2408
|
+
}
|
|
2409
|
+
const options = this.safeValue(this.options, type, {});
|
|
2410
|
+
const listenKey = this.safeString(options, 'listenKey');
|
|
2411
|
+
if (listenKey === undefined) {
|
|
2412
|
+
// A network error happened: we can't renew a listen key that does not exist.
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
const request = {};
|
|
2416
|
+
const symbol = this.safeString(params, 'symbol');
|
|
2417
|
+
params = this.omit(params, ['type', 'symbol']);
|
|
2418
|
+
const time = this.milliseconds();
|
|
2419
|
+
try {
|
|
2420
|
+
if (isPortfolioMargin) {
|
|
2421
|
+
await this.papiPutListenKey(this.extend(request, params));
|
|
2422
|
+
params = this.extend(params, { 'portfolioMargin': true });
|
|
2423
|
+
}
|
|
2424
|
+
else if (type === 'future') {
|
|
2425
|
+
await this.fapiPrivatePutListenKey(this.extend(request, params));
|
|
2426
|
+
}
|
|
2427
|
+
else if (type === 'delivery') {
|
|
2428
|
+
await this.dapiPrivatePutListenKey(this.extend(request, params));
|
|
2429
|
+
}
|
|
2430
|
+
else {
|
|
2431
|
+
request['listenKey'] = listenKey;
|
|
2432
|
+
if (type === 'margin') {
|
|
2433
|
+
request['symbol'] = symbol;
|
|
2434
|
+
await this.sapiPutUserDataStream(this.extend(request, params));
|
|
2435
|
+
}
|
|
2436
|
+
else {
|
|
2437
|
+
await this.publicPutUserDataStream(this.extend(request, params));
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
catch (error) {
|
|
2442
|
+
let urlType = type;
|
|
2443
|
+
if (isPortfolioMargin) {
|
|
2444
|
+
urlType = 'papi';
|
|
2445
|
+
}
|
|
2446
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2447
|
+
const client = this.client(url);
|
|
2448
|
+
const messageHashes = Object.keys(client.futures);
|
|
2449
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
2450
|
+
const messageHash = messageHashes[i];
|
|
2451
|
+
client.reject(error, messageHash);
|
|
2452
|
+
}
|
|
2453
|
+
this.options[type] = this.extend(options, {
|
|
2454
|
+
'listenKey': undefined,
|
|
2455
|
+
'lastAuthenticatedTime': 0,
|
|
2456
|
+
});
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2459
|
+
this.options[type] = this.extend(options, {
|
|
2460
|
+
'listenKey': listenKey,
|
|
2461
|
+
'lastAuthenticatedTime': time,
|
|
2462
|
+
});
|
|
2463
|
+
// whether or not to schedule another listenKey keepAlive request
|
|
2464
|
+
const clients = Object.values(this.clients);
|
|
2465
|
+
const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
|
|
2466
|
+
for (let i = 0; i < clients.length; i++) {
|
|
2467
|
+
const client = clients[i];
|
|
2468
|
+
const subscriptionKeys = Object.keys(client.subscriptions);
|
|
2469
|
+
for (let j = 0; j < subscriptionKeys.length; j++) {
|
|
2470
|
+
const subscribeType = subscriptionKeys[j];
|
|
2471
|
+
if (subscribeType === type) {
|
|
2472
|
+
this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
|
|
2473
|
+
return;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
setBalanceCache(client, type, isPortfolioMargin = false) {
|
|
2479
|
+
if (type in client.subscriptions) {
|
|
2480
|
+
return;
|
|
2481
|
+
}
|
|
2482
|
+
const options = this.safeValue(this.options, 'watchBalance');
|
|
2483
|
+
const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
|
|
2484
|
+
if (fetchBalanceSnapshot) {
|
|
2485
|
+
const messageHash = type + ':fetchBalanceSnapshot';
|
|
2486
|
+
if (!(messageHash in client.futures)) {
|
|
2487
|
+
client.future(messageHash);
|
|
2488
|
+
this.spawn(this.loadBalanceSnapshot, client, messageHash, type, isPortfolioMargin);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
else {
|
|
2492
|
+
this.balance[type] = {};
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
async loadBalanceSnapshot(client, messageHash, type, isPortfolioMargin) {
|
|
2496
|
+
const params = {
|
|
2497
|
+
'type': type,
|
|
2498
|
+
};
|
|
2499
|
+
if (isPortfolioMargin) {
|
|
2500
|
+
params['portfolioMargin'] = true;
|
|
2501
|
+
}
|
|
2502
|
+
const response = await this.fetchBalance(params);
|
|
2503
|
+
this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
|
|
2504
|
+
// don't remove the future from the .futures cache
|
|
2505
|
+
const future = client.futures[messageHash];
|
|
2506
|
+
future.resolve();
|
|
2507
|
+
client.resolve(this.balance[type], type + ':balance');
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2510
|
+
* @method
|
|
2511
|
+
* @name binance#fetchBalanceWs
|
|
2512
|
+
* @description fetch balance and get the amount of funds available for trading or funds locked in orders
|
|
2513
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Futures-Account-Balance
|
|
2514
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/account-requests#account-information-user_data
|
|
2515
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/account/websocket-api
|
|
2516
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2517
|
+
* @param {string|undefined} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot'
|
|
2518
|
+
* @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
|
|
2519
|
+
* @param {string[]|undefined} [params.symbols] unified market symbols, only used in isolated margin mode
|
|
2520
|
+
* @param {string|undefined} [params.method] method to use. Can be account.balance, account.status, v2/account.balance or v2/account.status
|
|
2521
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
2522
|
+
*/
|
|
2523
|
+
async fetchBalanceWs(params = {}) {
|
|
2524
|
+
await this.loadMarkets();
|
|
2525
|
+
const type = this.getMarketType('fetchBalanceWs', undefined, params);
|
|
2526
|
+
if (type !== 'spot' && type !== 'future' && type !== 'delivery') {
|
|
2527
|
+
throw new BadRequest(this.id + ' fetchBalanceWs only supports spot or swap markets');
|
|
2528
|
+
}
|
|
2529
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
2530
|
+
const requestId = this.requestId(url);
|
|
2531
|
+
const messageHash = requestId.toString();
|
|
2532
|
+
let returnRateLimits = false;
|
|
2533
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchBalanceWs', 'returnRateLimits', false);
|
|
2534
|
+
const payload = {
|
|
2535
|
+
'returnRateLimits': returnRateLimits,
|
|
2536
|
+
};
|
|
2537
|
+
let method = undefined;
|
|
2538
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchBalanceWs', 'method', 'account.status');
|
|
2539
|
+
const message = {
|
|
2540
|
+
'id': messageHash,
|
|
2541
|
+
'method': method,
|
|
2542
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
2543
|
+
};
|
|
2544
|
+
const subscription = {
|
|
2545
|
+
'method': (method === 'account.status') ? this.handleAccountStatusWs : this.handleBalanceWs,
|
|
2546
|
+
};
|
|
2547
|
+
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
2548
|
+
}
|
|
2549
|
+
handleBalanceWs(client, message) {
|
|
2550
|
+
//
|
|
2551
|
+
//
|
|
2552
|
+
const messageHash = this.safeString(message, 'id');
|
|
2553
|
+
let rawBalance = undefined;
|
|
2554
|
+
if (Array.isArray(message['result'])) {
|
|
2555
|
+
// account.balance
|
|
2556
|
+
rawBalance = this.safeList(message, 'result', []);
|
|
2557
|
+
}
|
|
2558
|
+
else {
|
|
2559
|
+
// account.status
|
|
2560
|
+
const result = this.safeDict(message, 'result', {});
|
|
2561
|
+
rawBalance = this.safeList(result, 'assets', []);
|
|
2562
|
+
}
|
|
2563
|
+
const parsedBalances = this.parseBalanceCustom(rawBalance);
|
|
2564
|
+
client.resolve(parsedBalances, messageHash);
|
|
2565
|
+
}
|
|
2566
|
+
handleAccountStatusWs(client, message) {
|
|
2567
|
+
//
|
|
2568
|
+
// spot
|
|
2569
|
+
// {
|
|
2570
|
+
// "id": "605a6d20-6588-4cb9-afa0-b0ab087507ba",
|
|
2571
|
+
// "status": 200,
|
|
2572
|
+
// "result": {
|
|
2573
|
+
// "makerCommission": 15,
|
|
2574
|
+
// "takerCommission": 15,
|
|
2575
|
+
// "buyerCommission": 0,
|
|
2576
|
+
// "sellerCommission": 0,
|
|
2577
|
+
// "canTrade": true,
|
|
2578
|
+
// "canWithdraw": true,
|
|
2579
|
+
// "canDeposit": true,
|
|
2580
|
+
// "commissionRates": {
|
|
2581
|
+
// "maker": "0.00150000",
|
|
2582
|
+
// "taker": "0.00150000",
|
|
2583
|
+
// "buyer": "0.00000000",
|
|
2584
|
+
// "seller": "0.00000000"
|
|
2585
|
+
// },
|
|
2586
|
+
// "brokered": false,
|
|
2587
|
+
// "requireSelfTradePrevention": false,
|
|
2588
|
+
// "updateTime": 1660801833000,
|
|
2589
|
+
// "accountType": "SPOT",
|
|
2590
|
+
// "balances": [{
|
|
2591
|
+
// "asset": "BNB",
|
|
2592
|
+
// "free": "0.00000000",
|
|
2593
|
+
// "locked": "0.00000000"
|
|
2594
|
+
// },
|
|
2595
|
+
// {
|
|
2596
|
+
// "asset": "BTC",
|
|
2597
|
+
// "free": "1.3447112",
|
|
2598
|
+
// "locked": "0.08600000"
|
|
2599
|
+
// },
|
|
2600
|
+
// {
|
|
2601
|
+
// "asset": "USDT",
|
|
2602
|
+
// "free": "1021.21000000",
|
|
2603
|
+
// "locked": "0.00000000"
|
|
2604
|
+
// }
|
|
2605
|
+
// ],
|
|
2606
|
+
// "permissions": [
|
|
2607
|
+
// "SPOT"
|
|
2608
|
+
// ]
|
|
2609
|
+
// }
|
|
2610
|
+
// }
|
|
2611
|
+
// swap
|
|
2612
|
+
//
|
|
2613
|
+
const messageHash = this.safeString(message, 'id');
|
|
2614
|
+
const result = this.safeDict(message, 'result', {});
|
|
2615
|
+
const parsedBalances = this.parseBalanceCustom(result);
|
|
2616
|
+
client.resolve(parsedBalances, messageHash);
|
|
2617
|
+
}
|
|
2618
|
+
/**
|
|
2619
|
+
* @method
|
|
2620
|
+
* @name binance#fetchPositionWs
|
|
2621
|
+
* @description fetch data on an open position
|
|
2622
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Information
|
|
2623
|
+
* @param {string} symbol unified market symbol of the market the position is held in
|
|
2624
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2625
|
+
* @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2626
|
+
*/
|
|
2627
|
+
async fetchPositionWs(symbol, params = {}) {
|
|
2628
|
+
return await this.fetchPositionsWs([symbol], params);
|
|
2629
|
+
}
|
|
2630
|
+
/**
|
|
2631
|
+
* @method
|
|
2632
|
+
* @name binance#fetchPositionsWs
|
|
2633
|
+
* @description fetch all open positions
|
|
2634
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Information
|
|
2635
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Position-Information
|
|
2636
|
+
* @param {string[]} [symbols] list of unified market symbols
|
|
2637
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2638
|
+
* @param {boolean} [params.returnRateLimits] set to true to return rate limit informations, defaults to false.
|
|
2639
|
+
* @param {string|undefined} [params.method] method to use. Can be account.position or v2/account.position
|
|
2640
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2641
|
+
*/
|
|
2642
|
+
async fetchPositionsWs(symbols = undefined, params = {}) {
|
|
2643
|
+
await this.loadMarkets();
|
|
2644
|
+
const payload = {};
|
|
2645
|
+
let market = undefined;
|
|
2646
|
+
symbols = this.marketSymbols(symbols, 'swap', true, true, true);
|
|
2647
|
+
if (symbols !== undefined) {
|
|
2648
|
+
const symbolsLength = symbols.length;
|
|
2649
|
+
if (symbolsLength === 1) {
|
|
2650
|
+
market = this.market(symbols[0]);
|
|
2651
|
+
payload['symbol'] = market['id'];
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
const type = this.getMarketType('fetchPositionsWs', market, params);
|
|
2655
|
+
if (type !== 'future' && type !== 'delivery') {
|
|
2656
|
+
throw new BadRequest(this.id + ' fetchPositionsWs only supports swap markets');
|
|
2657
|
+
}
|
|
2658
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
2659
|
+
const requestId = this.requestId(url);
|
|
2660
|
+
const messageHash = requestId.toString();
|
|
2661
|
+
let returnRateLimits = false;
|
|
2662
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchPositionsWs', 'returnRateLimits', false);
|
|
2663
|
+
payload['returnRateLimits'] = returnRateLimits;
|
|
2664
|
+
let method = undefined;
|
|
2665
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchPositionsWs', 'method', 'account.position');
|
|
2666
|
+
const message = {
|
|
2667
|
+
'id': messageHash,
|
|
2668
|
+
'method': method,
|
|
2669
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
2670
|
+
};
|
|
2671
|
+
const subscription = {
|
|
2672
|
+
'method': this.handlePositionsWs,
|
|
2673
|
+
};
|
|
2674
|
+
const result = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
2675
|
+
return this.filterByArrayPositions(result, 'symbol', symbols, false);
|
|
2676
|
+
}
|
|
2677
|
+
handlePositionsWs(client, message) {
|
|
2678
|
+
//
|
|
2679
|
+
// {
|
|
2680
|
+
// id: '1',
|
|
2681
|
+
// status: 200,
|
|
2682
|
+
// result: [
|
|
2683
|
+
// {
|
|
2684
|
+
// symbol: 'BTCUSDT',
|
|
2685
|
+
// positionAmt: '-0.014',
|
|
2686
|
+
// entryPrice: '42901.1',
|
|
2687
|
+
// breakEvenPrice: '30138.83333142',
|
|
2688
|
+
// markPrice: '71055.98470333',
|
|
2689
|
+
// unRealizedProfit: '-394.16838584',
|
|
2690
|
+
// liquidationPrice: '137032.02272908',
|
|
2691
|
+
// leverage: '123',
|
|
2692
|
+
// maxNotionalValue: '50000',
|
|
2693
|
+
// marginType: 'cross',
|
|
2694
|
+
// isolatedMargin: '0.00000000',
|
|
2695
|
+
// isAutoAddMargin: 'false',
|
|
2696
|
+
// positionSide: 'BOTH',
|
|
2697
|
+
// notional: '-994.78378584',
|
|
2698
|
+
// isolatedWallet: '0',
|
|
2699
|
+
// updateTime: 1708906343111,
|
|
2700
|
+
// isolated: false,
|
|
2701
|
+
// adlQuantile: 2
|
|
2702
|
+
// },
|
|
2703
|
+
// ...
|
|
2704
|
+
// ]
|
|
2705
|
+
// }
|
|
2706
|
+
//
|
|
2707
|
+
//
|
|
2708
|
+
const messageHash = this.safeString(message, 'id');
|
|
2709
|
+
const result = this.safeList(message, 'result', []);
|
|
2710
|
+
const positions = [];
|
|
2711
|
+
for (let i = 0; i < result.length; i++) {
|
|
2712
|
+
const parsed = this.parsePositionRisk(result[i]);
|
|
2713
|
+
const entryPrice = this.safeString(parsed, 'entryPrice');
|
|
2714
|
+
if ((entryPrice !== '0') && (entryPrice !== '0.0') && (entryPrice !== '0.00000000')) {
|
|
2715
|
+
positions.push(parsed);
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
client.resolve(positions, messageHash);
|
|
2719
|
+
}
|
|
2720
|
+
/**
|
|
2721
|
+
* @method
|
|
2722
|
+
* @name binance#watchBalance
|
|
2723
|
+
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
2724
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2725
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch the balance of a portfolio margin account
|
|
2726
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
2727
|
+
*/
|
|
2728
|
+
async watchBalance(params = {}) {
|
|
2729
|
+
await this.loadMarkets();
|
|
2730
|
+
await this.authenticate(params);
|
|
2731
|
+
const defaultType = this.safeString(this.options, 'defaultType', 'spot');
|
|
2732
|
+
let type = this.safeString(params, 'type', defaultType);
|
|
2733
|
+
let subType = undefined;
|
|
2734
|
+
[subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
|
|
2735
|
+
let isPortfolioMargin = undefined;
|
|
2736
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchBalance', 'papi', 'portfolioMargin', false);
|
|
2737
|
+
if (this.isLinear(type, subType)) {
|
|
2738
|
+
type = 'future';
|
|
2739
|
+
}
|
|
2740
|
+
else if (this.isInverse(type, subType)) {
|
|
2741
|
+
type = 'delivery';
|
|
2742
|
+
}
|
|
2743
|
+
let urlType = type;
|
|
2744
|
+
if (isPortfolioMargin) {
|
|
2745
|
+
urlType = 'papi';
|
|
2746
|
+
}
|
|
2747
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2748
|
+
const client = this.client(url);
|
|
2749
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
2750
|
+
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
2751
|
+
const options = this.safeDict(this.options, 'watchBalance');
|
|
2752
|
+
const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
|
|
2753
|
+
const awaitBalanceSnapshot = this.safeBool(options, 'awaitBalanceSnapshot', true);
|
|
2754
|
+
if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
|
|
2755
|
+
await client.future(type + ':fetchBalanceSnapshot');
|
|
2756
|
+
}
|
|
2757
|
+
const messageHash = type + ':balance';
|
|
2758
|
+
const message = undefined;
|
|
2759
|
+
return await this.watch(url, messageHash, message, type);
|
|
2760
|
+
}
|
|
2761
|
+
handleBalance(client, message) {
|
|
2762
|
+
//
|
|
2763
|
+
// sent upon a balance update not related to orders
|
|
2764
|
+
//
|
|
2765
|
+
// {
|
|
2766
|
+
// "e": "balanceUpdate",
|
|
2767
|
+
// "E": 1629352505586,
|
|
2768
|
+
// "a": "IOTX",
|
|
2769
|
+
// "d": "0.43750000",
|
|
2770
|
+
// "T": 1629352505585
|
|
2771
|
+
// }
|
|
2772
|
+
//
|
|
2773
|
+
// sent upon creating or filling an order
|
|
2774
|
+
//
|
|
2775
|
+
// {
|
|
2776
|
+
// "e": "outboundAccountPosition", // Event type
|
|
2777
|
+
// "E": 1564034571105, // Event Time
|
|
2778
|
+
// "u": 1564034571073, // Time of last account update
|
|
2779
|
+
// "B": [ // Balances Array
|
|
2780
|
+
// {
|
|
2781
|
+
// "a": "ETH", // Asset
|
|
2782
|
+
// "f": "10000.000000", // Free
|
|
2783
|
+
// "l": "0.000000" // Locked
|
|
2784
|
+
// }
|
|
2785
|
+
// ]
|
|
2786
|
+
// }
|
|
2787
|
+
//
|
|
2788
|
+
// future/delivery
|
|
2789
|
+
//
|
|
2790
|
+
// {
|
|
2791
|
+
// "e": "ACCOUNT_UPDATE", // Event Type
|
|
2792
|
+
// "E": 1564745798939, // Event Time
|
|
2793
|
+
// "T": 1564745798938 , // Transaction
|
|
2794
|
+
// "i": "SfsR", // Account Alias
|
|
2795
|
+
// "a": { // Update Data
|
|
2796
|
+
// "m":"ORDER", // Event reason type
|
|
2797
|
+
// "B":[ // Balances
|
|
2798
|
+
// {
|
|
2799
|
+
// "a":"BTC", // Asset
|
|
2800
|
+
// "wb":"122624.12345678", // Wallet Balance
|
|
2801
|
+
// "cw":"100.12345678" // Cross Wallet Balance
|
|
2802
|
+
// },
|
|
2803
|
+
// ],
|
|
2804
|
+
// "P":[
|
|
2805
|
+
// {
|
|
2806
|
+
// "s":"BTCUSD_200925", // Symbol
|
|
2807
|
+
// "pa":"0", // Position Amount
|
|
2808
|
+
// "ep":"0.0", // Entry Price
|
|
2809
|
+
// "cr":"200", // (Pre-fee) Accumulated Realized
|
|
2810
|
+
// "up":"0", // Unrealized PnL
|
|
2811
|
+
// "mt":"isolated", // Margin Type
|
|
2812
|
+
// "iw":"0.00000000", // Isolated Wallet (if isolated position)
|
|
2813
|
+
// "ps":"BOTH" // Position Side
|
|
2814
|
+
// },
|
|
2815
|
+
// ]
|
|
2816
|
+
// }
|
|
2817
|
+
// }
|
|
2818
|
+
//
|
|
2819
|
+
const wallet = this.safeString(this.options, 'wallet', 'wb'); // cw for cross wallet
|
|
2820
|
+
// each account is connected to a different endpoint
|
|
2821
|
+
// and has exactly one subscriptionhash which is the account type
|
|
2822
|
+
const subscriptions = Object.keys(client.subscriptions);
|
|
2823
|
+
const accountType = subscriptions[0];
|
|
2824
|
+
const messageHash = accountType + ':balance';
|
|
2825
|
+
if (this.balance[accountType] === undefined) {
|
|
2826
|
+
this.balance[accountType] = {};
|
|
2827
|
+
}
|
|
2828
|
+
this.balance[accountType]['info'] = message;
|
|
2829
|
+
const event = this.safeString(message, 'e');
|
|
2830
|
+
if (event === 'balanceUpdate') {
|
|
2831
|
+
const currencyId = this.safeString(message, 'a');
|
|
2832
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
2833
|
+
const account = this.account();
|
|
2834
|
+
const delta = this.safeString(message, 'd');
|
|
2835
|
+
if (code in this.balance[accountType]) {
|
|
2836
|
+
let previousValue = this.balance[accountType][code]['free'];
|
|
2837
|
+
if (typeof previousValue !== 'string') {
|
|
2838
|
+
previousValue = this.numberToString(previousValue);
|
|
2839
|
+
}
|
|
2840
|
+
account['free'] = Precise.stringAdd(previousValue, delta);
|
|
2841
|
+
}
|
|
2842
|
+
else {
|
|
2843
|
+
account['free'] = delta;
|
|
2844
|
+
}
|
|
2845
|
+
this.balance[accountType][code] = account;
|
|
2846
|
+
}
|
|
2847
|
+
else {
|
|
2848
|
+
message = this.safeDict(message, 'a', message);
|
|
2849
|
+
const B = this.safeList(message, 'B');
|
|
2850
|
+
for (let i = 0; i < B.length; i++) {
|
|
2851
|
+
const entry = B[i];
|
|
2852
|
+
const currencyId = this.safeString(entry, 'a');
|
|
2853
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
2854
|
+
const account = this.account();
|
|
2855
|
+
account['free'] = this.safeString(entry, 'f');
|
|
2856
|
+
account['used'] = this.safeString(entry, 'l');
|
|
2857
|
+
account['total'] = this.safeString(entry, wallet);
|
|
2858
|
+
this.balance[accountType][code] = account;
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
const timestamp = this.safeInteger(message, 'E');
|
|
2862
|
+
this.balance[accountType]['timestamp'] = timestamp;
|
|
2863
|
+
this.balance[accountType]['datetime'] = this.iso8601(timestamp);
|
|
2864
|
+
this.balance[accountType] = this.safeBalance(this.balance[accountType]);
|
|
2865
|
+
client.resolve(this.balance[accountType], messageHash);
|
|
2866
|
+
}
|
|
2867
|
+
getMarketType(method, market, params = {}) {
|
|
2868
|
+
let type = undefined;
|
|
2869
|
+
[type, params] = this.handleMarketTypeAndParams(method, market, params);
|
|
2870
|
+
let subType = undefined;
|
|
2871
|
+
[subType, params] = this.handleSubTypeAndParams(method, market, params);
|
|
2872
|
+
if (this.isLinear(type, subType)) {
|
|
2873
|
+
type = 'future';
|
|
2874
|
+
}
|
|
2875
|
+
else if (this.isInverse(type, subType)) {
|
|
2876
|
+
type = 'delivery';
|
|
2877
|
+
}
|
|
2878
|
+
return type;
|
|
2879
|
+
}
|
|
2880
|
+
/**
|
|
2881
|
+
* @method
|
|
2882
|
+
* @name binance#createOrderWs
|
|
2883
|
+
* @description create a trade order
|
|
2884
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#place-new-order-trade
|
|
2885
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/New-Order
|
|
2886
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api
|
|
2887
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
2888
|
+
* @param {string} type 'market' or 'limit'
|
|
2889
|
+
* @param {string} side 'buy' or 'sell'
|
|
2890
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
2891
|
+
* @param {float|undefined} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
2892
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2893
|
+
* @param {boolean} params.test test order, default false
|
|
2894
|
+
* @param {boolean} params.returnRateLimits set to true to return rate limit information, default false
|
|
2895
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2896
|
+
*/
|
|
2897
|
+
async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
|
|
2898
|
+
await this.loadMarkets();
|
|
2899
|
+
const market = this.market(symbol);
|
|
2900
|
+
const marketType = this.getMarketType('createOrderWs', market, params);
|
|
2901
|
+
if (marketType !== 'spot' && marketType !== 'future' && marketType !== 'delivery') {
|
|
2902
|
+
throw new BadRequest(this.id + ' createOrderWs only supports spot or swap markets');
|
|
2903
|
+
}
|
|
2904
|
+
const url = this.urls['api']['ws']['ws-api'][marketType];
|
|
2905
|
+
const requestId = this.requestId(url);
|
|
2906
|
+
const messageHash = requestId.toString();
|
|
2907
|
+
const sor = this.safeBool2(params, 'sor', 'SOR', false);
|
|
2908
|
+
params = this.omit(params, 'sor', 'SOR');
|
|
2909
|
+
const payload = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
2910
|
+
let returnRateLimits = false;
|
|
2911
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
|
|
2912
|
+
payload['returnRateLimits'] = returnRateLimits;
|
|
2913
|
+
const test = this.safeBool(params, 'test', false);
|
|
2914
|
+
params = this.omit(params, 'test');
|
|
2915
|
+
const message = {
|
|
2916
|
+
'id': messageHash,
|
|
2917
|
+
'method': 'order.place',
|
|
2918
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
2919
|
+
};
|
|
2920
|
+
if (test) {
|
|
2921
|
+
if (sor) {
|
|
2922
|
+
message['method'] = 'sor.order.test';
|
|
2923
|
+
}
|
|
2924
|
+
else {
|
|
2925
|
+
message['method'] = 'order.test';
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
const subscription = {
|
|
2929
|
+
'method': this.handleOrderWs,
|
|
2930
|
+
};
|
|
2931
|
+
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
2932
|
+
}
|
|
2933
|
+
handleOrderWs(client, message) {
|
|
2934
|
+
//
|
|
2935
|
+
// {
|
|
2936
|
+
// "id": 1,
|
|
2937
|
+
// "status": 200,
|
|
2938
|
+
// "result": {
|
|
2939
|
+
// "symbol": "BTCUSDT",
|
|
2940
|
+
// "orderId": 7663053,
|
|
2941
|
+
// "orderListId": -1,
|
|
2942
|
+
// "clientOrderId": "x-R4BD3S82d8959d0f5114499487a614",
|
|
2943
|
+
// "transactTime": 1687642291434,
|
|
2944
|
+
// "price": "25000.00000000",
|
|
2945
|
+
// "origQty": "0.00100000",
|
|
2946
|
+
// "executedQty": "0.00000000",
|
|
2947
|
+
// "cummulativeQuoteQty": "0.00000000",
|
|
2948
|
+
// "status": "NEW",
|
|
2949
|
+
// "timeInForce": "GTC",
|
|
2950
|
+
// "type": "LIMIT",
|
|
2951
|
+
// "side": "BUY",
|
|
2952
|
+
// "workingTime": 1687642291434,
|
|
2953
|
+
// "fills": [],
|
|
2954
|
+
// "selfTradePreventionMode": "NONE"
|
|
2955
|
+
// },
|
|
2956
|
+
// "rateLimits": [
|
|
2957
|
+
// {
|
|
2958
|
+
// "rateLimitType": "ORDERS",
|
|
2959
|
+
// "interval": "SECOND",
|
|
2960
|
+
// "intervalNum": 10,
|
|
2961
|
+
// "limit": 50,
|
|
2962
|
+
// "count": 1
|
|
2963
|
+
// },
|
|
2964
|
+
// {
|
|
2965
|
+
// "rateLimitType": "ORDERS",
|
|
2966
|
+
// "interval": "DAY",
|
|
2967
|
+
// "intervalNum": 1,
|
|
2968
|
+
// "limit": 160000,
|
|
2969
|
+
// "count": 1
|
|
2970
|
+
// },
|
|
2971
|
+
// {
|
|
2972
|
+
// "rateLimitType": "REQUEST_WEIGHT",
|
|
2973
|
+
// "interval": "MINUTE",
|
|
2974
|
+
// "intervalNum": 1,
|
|
2975
|
+
// "limit": 1200,
|
|
2976
|
+
// "count": 12
|
|
2977
|
+
// }
|
|
2978
|
+
// ]
|
|
2979
|
+
// }
|
|
2980
|
+
//
|
|
2981
|
+
const messageHash = this.safeString(message, 'id');
|
|
2982
|
+
const result = this.safeDict(message, 'result', {});
|
|
2983
|
+
const order = this.parseOrder(result);
|
|
2984
|
+
client.resolve(order, messageHash);
|
|
2985
|
+
}
|
|
2986
|
+
handleOrdersWs(client, message) {
|
|
2987
|
+
//
|
|
2988
|
+
// {
|
|
2989
|
+
// "id": 1,
|
|
2990
|
+
// "status": 200,
|
|
2991
|
+
// "result": [{
|
|
2992
|
+
// "symbol": "BTCUSDT",
|
|
2993
|
+
// "orderId": 7665584,
|
|
2994
|
+
// "orderListId": -1,
|
|
2995
|
+
// "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
|
|
2996
|
+
// "price": "26000.00000000",
|
|
2997
|
+
// "origQty": "0.00100000",
|
|
2998
|
+
// "executedQty": "0.00000000",
|
|
2999
|
+
// "cummulativeQuoteQty": "0.00000000",
|
|
3000
|
+
// "status": "NEW",
|
|
3001
|
+
// "timeInForce": "GTC",
|
|
3002
|
+
// "type": "LIMIT",
|
|
3003
|
+
// "side": "BUY",
|
|
3004
|
+
// "stopPrice": "0.00000000",
|
|
3005
|
+
// "icebergQty": "0.00000000",
|
|
3006
|
+
// "time": 1687642884646,
|
|
3007
|
+
// "updateTime": 1687642884646,
|
|
3008
|
+
// "isWorking": true,
|
|
3009
|
+
// "workingTime": 1687642884646,
|
|
3010
|
+
// "origQuoteOrderQty": "0.00000000",
|
|
3011
|
+
// "selfTradePreventionMode": "NONE"
|
|
3012
|
+
// },
|
|
3013
|
+
// ...
|
|
3014
|
+
// ],
|
|
3015
|
+
// "rateLimits": [{
|
|
3016
|
+
// "rateLimitType": "REQUEST_WEIGHT",
|
|
3017
|
+
// "interval": "MINUTE",
|
|
3018
|
+
// "intervalNum": 1,
|
|
3019
|
+
// "limit": 1200,
|
|
3020
|
+
// "count": 14
|
|
3021
|
+
// }]
|
|
3022
|
+
// }
|
|
3023
|
+
//
|
|
3024
|
+
const messageHash = this.safeString(message, 'id');
|
|
3025
|
+
const result = this.safeList(message, 'result', []);
|
|
3026
|
+
const orders = this.parseOrders(result);
|
|
3027
|
+
client.resolve(orders, messageHash);
|
|
3028
|
+
}
|
|
3029
|
+
/**
|
|
3030
|
+
* @method
|
|
3031
|
+
* @name binance#editOrderWs
|
|
3032
|
+
* @description edit a trade order
|
|
3033
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#cancel-and-replace-order-trade
|
|
3034
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Modify-Order
|
|
3035
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Modify-Order
|
|
3036
|
+
* @param {string} id order id
|
|
3037
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
3038
|
+
* @param {string} type 'market' or 'limit'
|
|
3039
|
+
* @param {string} side 'buy' or 'sell'
|
|
3040
|
+
* @param {float} amount how much of the currency you want to trade in units of the base currency
|
|
3041
|
+
* @param {float|undefined} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
3042
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3043
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3044
|
+
*/
|
|
3045
|
+
async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
3046
|
+
await this.loadMarkets();
|
|
3047
|
+
const market = this.market(symbol);
|
|
3048
|
+
const marketType = this.getMarketType('editOrderWs', market, params);
|
|
3049
|
+
if (marketType !== 'spot' && marketType !== 'future' && marketType !== 'delivery') {
|
|
3050
|
+
throw new BadRequest(this.id + ' editOrderWs only supports spot or swap markets');
|
|
3051
|
+
}
|
|
3052
|
+
const url = this.urls['api']['ws']['ws-api'][marketType];
|
|
3053
|
+
const requestId = this.requestId(url);
|
|
3054
|
+
const messageHash = requestId.toString();
|
|
3055
|
+
const isSwap = (marketType === 'future' || marketType === 'delivery');
|
|
3056
|
+
let payload = undefined;
|
|
3057
|
+
if (marketType === 'spot') {
|
|
3058
|
+
payload = this.editSpotOrderRequest(id, symbol, type, side, amount, price, params);
|
|
3059
|
+
}
|
|
3060
|
+
else if (isSwap) {
|
|
3061
|
+
payload = this.editContractOrderRequest(id, symbol, type, side, amount, price, params);
|
|
3062
|
+
}
|
|
3063
|
+
let returnRateLimits = false;
|
|
3064
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'editOrderWs', 'returnRateLimits', false);
|
|
3065
|
+
payload['returnRateLimits'] = returnRateLimits;
|
|
3066
|
+
const message = {
|
|
3067
|
+
'id': messageHash,
|
|
3068
|
+
'method': (isSwap) ? 'order.modify' : 'order.cancelReplace',
|
|
3069
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
3070
|
+
};
|
|
3071
|
+
const subscription = {
|
|
3072
|
+
'method': this.handleEditOrderWs,
|
|
3073
|
+
};
|
|
3074
|
+
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
3075
|
+
}
|
|
3076
|
+
handleEditOrderWs(client, message) {
|
|
3077
|
+
//
|
|
3078
|
+
// spot
|
|
3079
|
+
// {
|
|
3080
|
+
// "id": 1,
|
|
3081
|
+
// "status": 200,
|
|
3082
|
+
// "result": {
|
|
3083
|
+
// "cancelResult": "SUCCESS",
|
|
3084
|
+
// "newOrderResult": "SUCCESS",
|
|
3085
|
+
// "cancelResponse": {
|
|
3086
|
+
// "symbol": "BTCUSDT",
|
|
3087
|
+
// "origClientOrderId": "x-R4BD3S82813c5d7ffa594104917de2",
|
|
3088
|
+
// "orderId": 7665177,
|
|
3089
|
+
// "orderListId": -1,
|
|
3090
|
+
// "clientOrderId": "mbrnbQsQhtCXCLY45d5q7S",
|
|
3091
|
+
// "price": "26000.00000000",
|
|
3092
|
+
// "origQty": "0.00100000",
|
|
3093
|
+
// "executedQty": "0.00000000",
|
|
3094
|
+
// "cummulativeQuoteQty": "0.00000000",
|
|
3095
|
+
// "status": "CANCELED",
|
|
3096
|
+
// "timeInForce": "GTC",
|
|
3097
|
+
// "type": "LIMIT",
|
|
3098
|
+
// "side": "BUY",
|
|
3099
|
+
// "selfTradePreventionMode": "NONE"
|
|
3100
|
+
// },
|
|
3101
|
+
// "newOrderResponse": {
|
|
3102
|
+
// "symbol": "BTCUSDT",
|
|
3103
|
+
// "orderId": 7665584,
|
|
3104
|
+
// "orderListId": -1,
|
|
3105
|
+
// "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
|
|
3106
|
+
// "transactTime": 1687642884646,
|
|
3107
|
+
// "price": "26000.00000000",
|
|
3108
|
+
// "origQty": "0.00100000",
|
|
3109
|
+
// "executedQty": "0.00000000",
|
|
3110
|
+
// "cummulativeQuoteQty": "0.00000000",
|
|
3111
|
+
// "status": "NEW",
|
|
3112
|
+
// "timeInForce": "GTC",
|
|
3113
|
+
// "type": "LIMIT",
|
|
3114
|
+
// "side": "BUY",
|
|
3115
|
+
// "workingTime": 1687642884646,
|
|
3116
|
+
// "fills": [],
|
|
3117
|
+
// "selfTradePreventionMode": "NONE"
|
|
3118
|
+
// }
|
|
3119
|
+
// },
|
|
3120
|
+
// "rateLimits": [{
|
|
3121
|
+
// "rateLimitType": "ORDERS",
|
|
3122
|
+
// "interval": "SECOND",
|
|
3123
|
+
// "intervalNum": 10,
|
|
3124
|
+
// "limit": 50,
|
|
3125
|
+
// "count": 1
|
|
3126
|
+
// },
|
|
3127
|
+
// {
|
|
3128
|
+
// "rateLimitType": "ORDERS",
|
|
3129
|
+
// "interval": "DAY",
|
|
3130
|
+
// "intervalNum": 1,
|
|
3131
|
+
// "limit": 160000,
|
|
3132
|
+
// "count": 3
|
|
3133
|
+
// },
|
|
3134
|
+
// {
|
|
3135
|
+
// "rateLimitType": "REQUEST_WEIGHT",
|
|
3136
|
+
// "interval": "MINUTE",
|
|
3137
|
+
// "intervalNum": 1,
|
|
3138
|
+
// "limit": 1200,
|
|
3139
|
+
// "count": 12
|
|
3140
|
+
// }
|
|
3141
|
+
// ]
|
|
3142
|
+
// }
|
|
3143
|
+
// swap
|
|
3144
|
+
// {
|
|
3145
|
+
// "id":"1",
|
|
3146
|
+
// "status":200,
|
|
3147
|
+
// "result":{
|
|
3148
|
+
// "orderId":667061487,
|
|
3149
|
+
// "symbol":"LTCUSDT",
|
|
3150
|
+
// "status":"NEW",
|
|
3151
|
+
// "clientOrderId":"x-xcKtGhcu91a74c818749ee42c0f70",
|
|
3152
|
+
// "price":"82.00",
|
|
3153
|
+
// "avgPrice":"0.00",
|
|
3154
|
+
// "origQty":"1.000",
|
|
3155
|
+
// "executedQty":"0.000",
|
|
3156
|
+
// "cumQty":"0.000",
|
|
3157
|
+
// "cumQuote":"0.00000",
|
|
3158
|
+
// "timeInForce":"GTC",
|
|
3159
|
+
// "type":"LIMIT",
|
|
3160
|
+
// "reduceOnly":false,
|
|
3161
|
+
// "closePosition":false,
|
|
3162
|
+
// "side":"BUY",
|
|
3163
|
+
// "positionSide":"BOTH",
|
|
3164
|
+
// "stopPrice":"0.00",
|
|
3165
|
+
// "workingType":"CONTRACT_PRICE",
|
|
3166
|
+
// "priceProtect":false,
|
|
3167
|
+
// "origType":"LIMIT",
|
|
3168
|
+
// "priceMatch":"NONE",
|
|
3169
|
+
// "selfTradePreventionMode":"NONE",
|
|
3170
|
+
// "goodTillDate":0,
|
|
3171
|
+
// "updateTime":1712918927511
|
|
3172
|
+
// }
|
|
3173
|
+
// }
|
|
3174
|
+
//
|
|
3175
|
+
const messageHash = this.safeString(message, 'id');
|
|
3176
|
+
const result = this.safeDict(message, 'result', {});
|
|
3177
|
+
const newSpotOrder = this.safeDict(result, 'newOrderResponse');
|
|
3178
|
+
let order = undefined;
|
|
3179
|
+
if (newSpotOrder !== undefined) {
|
|
3180
|
+
order = this.parseOrder(newSpotOrder);
|
|
3181
|
+
}
|
|
3182
|
+
else {
|
|
3183
|
+
order = this.parseOrder(result);
|
|
3184
|
+
}
|
|
3185
|
+
client.resolve(order, messageHash);
|
|
3186
|
+
}
|
|
3187
|
+
/**
|
|
3188
|
+
* @method
|
|
3189
|
+
* @name binance#cancelOrderWs
|
|
3190
|
+
* @description cancel multiple orders
|
|
3191
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#cancel-order-trade
|
|
3192
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Cancel-Order
|
|
3193
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Cancel-Order
|
|
3194
|
+
* @param {string} id order id
|
|
3195
|
+
* @param {string} [symbol] unified market symbol, default is undefined
|
|
3196
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3197
|
+
* @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.
|
|
3198
|
+
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3199
|
+
*/
|
|
3200
|
+
async cancelOrderWs(id, symbol = undefined, params = {}) {
|
|
3201
|
+
await this.loadMarkets();
|
|
3202
|
+
if (symbol === undefined) {
|
|
3203
|
+
throw new BadRequest(this.id + ' cancelOrderWs requires a symbol');
|
|
3204
|
+
}
|
|
3205
|
+
const market = this.market(symbol);
|
|
3206
|
+
const type = this.getMarketType('cancelOrderWs', market, params);
|
|
3207
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
3208
|
+
const requestId = this.requestId(url);
|
|
3209
|
+
const messageHash = requestId.toString();
|
|
3210
|
+
let returnRateLimits = false;
|
|
3211
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelOrderWs', 'returnRateLimits', false);
|
|
3212
|
+
const payload = {
|
|
3213
|
+
'symbol': this.marketId(symbol),
|
|
3214
|
+
'returnRateLimits': returnRateLimits,
|
|
3215
|
+
};
|
|
3216
|
+
const clientOrderId = this.safeString2(params, 'origClientOrderId', 'clientOrderId');
|
|
3217
|
+
if (clientOrderId !== undefined) {
|
|
3218
|
+
payload['origClientOrderId'] = clientOrderId;
|
|
3219
|
+
}
|
|
3220
|
+
else {
|
|
3221
|
+
payload['orderId'] = this.parseToInt(id);
|
|
3222
|
+
}
|
|
3223
|
+
params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
|
|
3224
|
+
const message = {
|
|
3225
|
+
'id': messageHash,
|
|
3226
|
+
'method': 'order.cancel',
|
|
3227
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
3228
|
+
};
|
|
3229
|
+
const subscription = {
|
|
3230
|
+
'method': this.handleOrderWs,
|
|
3231
|
+
};
|
|
3232
|
+
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
3233
|
+
}
|
|
3234
|
+
/**
|
|
3235
|
+
* @method
|
|
3236
|
+
* @name binance#cancelAllOrdersWs
|
|
3237
|
+
* @description cancel all open orders in a market
|
|
3238
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#cancel-open-orders-trade
|
|
3239
|
+
* @param {string} [symbol] unified market symbol of the market to cancel orders in
|
|
3240
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3241
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3242
|
+
*/
|
|
3243
|
+
async cancelAllOrdersWs(symbol = undefined, params = {}) {
|
|
3244
|
+
await this.loadMarkets();
|
|
3245
|
+
const market = this.market(symbol);
|
|
3246
|
+
const type = this.getMarketType('cancelAllOrdersWs', market, params);
|
|
3247
|
+
if (type !== 'spot' && type !== 'future') {
|
|
3248
|
+
throw new BadRequest(this.id + ' cancelAllOrdersWs only supports spot or swap markets');
|
|
3249
|
+
}
|
|
3250
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
3251
|
+
const requestId = this.requestId(url);
|
|
3252
|
+
const messageHash = requestId.toString();
|
|
3253
|
+
let returnRateLimits = false;
|
|
3254
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelAllOrdersWs', 'returnRateLimits', false);
|
|
3255
|
+
const payload = {
|
|
3256
|
+
'symbol': this.marketId(symbol),
|
|
3257
|
+
'returnRateLimits': returnRateLimits,
|
|
3258
|
+
};
|
|
3259
|
+
const message = {
|
|
3260
|
+
'id': messageHash,
|
|
3261
|
+
'method': 'order.cancel',
|
|
3262
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
3263
|
+
};
|
|
3264
|
+
const subscription = {
|
|
3265
|
+
'method': this.handleOrdersWs,
|
|
3266
|
+
};
|
|
3267
|
+
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
3268
|
+
}
|
|
3269
|
+
/**
|
|
3270
|
+
* @method
|
|
3271
|
+
* @name binance#fetchOrderWs
|
|
3272
|
+
* @description fetches information on an order made by the user
|
|
3273
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#query-order-user_data
|
|
3274
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Query-Order
|
|
3275
|
+
* @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Query-Order
|
|
3276
|
+
* @param {string} id order id
|
|
3277
|
+
* @param {string} [symbol] unified symbol of the market the order was made in
|
|
3278
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3279
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3280
|
+
*/
|
|
3281
|
+
async fetchOrderWs(id, symbol = undefined, params = {}) {
|
|
3282
|
+
await this.loadMarkets();
|
|
3283
|
+
if (symbol === undefined) {
|
|
3284
|
+
throw new BadRequest(this.id + ' cancelOrderWs requires a symbol');
|
|
3285
|
+
}
|
|
3286
|
+
const market = this.market(symbol);
|
|
3287
|
+
const type = this.getMarketType('fetchOrderWs', market, params);
|
|
3288
|
+
if (type !== 'spot' && type !== 'future' && type !== 'delivery') {
|
|
3289
|
+
throw new BadRequest(this.id + ' fetchOrderWs only supports spot or swap markets');
|
|
3290
|
+
}
|
|
3291
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
3292
|
+
const requestId = this.requestId(url);
|
|
3293
|
+
const messageHash = requestId.toString();
|
|
3294
|
+
let returnRateLimits = false;
|
|
3295
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
|
|
3296
|
+
const payload = {
|
|
3297
|
+
'symbol': this.marketId(symbol),
|
|
3298
|
+
'returnRateLimits': returnRateLimits,
|
|
3299
|
+
};
|
|
3300
|
+
const clientOrderId = this.safeString2(params, 'origClientOrderId', 'clientOrderId');
|
|
3301
|
+
if (clientOrderId !== undefined) {
|
|
3302
|
+
payload['origClientOrderId'] = clientOrderId;
|
|
3303
|
+
}
|
|
3304
|
+
else {
|
|
3305
|
+
payload['orderId'] = this.parseToInt(id);
|
|
3306
|
+
}
|
|
3307
|
+
const message = {
|
|
3308
|
+
'id': messageHash,
|
|
3309
|
+
'method': 'order.status',
|
|
3310
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
3311
|
+
};
|
|
3312
|
+
const subscription = {
|
|
3313
|
+
'method': this.handleOrderWs,
|
|
3314
|
+
};
|
|
3315
|
+
return await this.watch(url, messageHash, message, messageHash, subscription);
|
|
3316
|
+
}
|
|
3317
|
+
/**
|
|
3318
|
+
* @method
|
|
3319
|
+
* @name binance#fetchOrdersWs
|
|
3320
|
+
* @description fetches information on multiple orders made by the user
|
|
3321
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#order-lists
|
|
3322
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
3323
|
+
* @param {int|undefined} [since] the earliest time in ms to fetch orders for
|
|
3324
|
+
* @param {int|undefined} [limit] the maximum number of order structures to retrieve
|
|
3325
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3326
|
+
* @param {int} [params.orderId] order id to begin at
|
|
3327
|
+
* @param {int} [params.startTime] earliest time in ms to retrieve orders for
|
|
3328
|
+
* @param {int} [params.endTime] latest time in ms to retrieve orders for
|
|
3329
|
+
* @param {int} [params.limit] the maximum number of order structures to retrieve
|
|
3330
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3331
|
+
*/
|
|
3332
|
+
async fetchOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3333
|
+
await this.loadMarkets();
|
|
3334
|
+
if (symbol === undefined) {
|
|
3335
|
+
throw new BadRequest(this.id + ' fetchOrdersWs requires a symbol');
|
|
3336
|
+
}
|
|
3337
|
+
const market = this.market(symbol);
|
|
3338
|
+
const type = this.getMarketType('fetchOrdersWs', market, params);
|
|
3339
|
+
if (type !== 'spot') {
|
|
3340
|
+
throw new BadRequest(this.id + ' fetchOrdersWs only supports spot markets');
|
|
3341
|
+
}
|
|
3342
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
3343
|
+
const requestId = this.requestId(url);
|
|
3344
|
+
const messageHash = requestId.toString();
|
|
3345
|
+
let returnRateLimits = false;
|
|
3346
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
|
|
3347
|
+
const payload = {
|
|
3348
|
+
'symbol': this.marketId(symbol),
|
|
3349
|
+
'returnRateLimits': returnRateLimits,
|
|
3350
|
+
};
|
|
3351
|
+
const message = {
|
|
3352
|
+
'id': messageHash,
|
|
3353
|
+
'method': 'allOrders',
|
|
3354
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
3355
|
+
};
|
|
3356
|
+
const subscription = {
|
|
3357
|
+
'method': this.handleOrdersWs,
|
|
3358
|
+
};
|
|
3359
|
+
const orders = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
3360
|
+
return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
|
|
3361
|
+
}
|
|
3362
|
+
/**
|
|
3363
|
+
* @method
|
|
3364
|
+
* @name binance#fetchClosedOrdersWs
|
|
3365
|
+
* @description fetch closed orders
|
|
3366
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#order-lists
|
|
3367
|
+
* @param {string} symbol unified market symbol
|
|
3368
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
3369
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
3370
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3371
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3372
|
+
*/
|
|
3373
|
+
async fetchClosedOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3374
|
+
const orders = await this.fetchOrdersWs(symbol, since, limit, params);
|
|
3375
|
+
const closedOrders = [];
|
|
3376
|
+
for (let i = 0; i < orders.length; i++) {
|
|
3377
|
+
const order = orders[i];
|
|
3378
|
+
if (order['status'] === 'closed') {
|
|
3379
|
+
closedOrders.push(order);
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
return closedOrders;
|
|
3383
|
+
}
|
|
3384
|
+
/**
|
|
3385
|
+
* @method
|
|
3386
|
+
* @name binance#fetchOpenOrdersWs
|
|
3387
|
+
* @description fetch all unfilled currently open orders
|
|
3388
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#current-open-orders-user_data
|
|
3389
|
+
* @param {string} symbol unified market symbol
|
|
3390
|
+
* @param {int|undefined} [since] the earliest time in ms to fetch open orders for
|
|
3391
|
+
* @param {int|undefined} [limit] the maximum number of open orders structures to retrieve
|
|
3392
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3393
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3394
|
+
*/
|
|
3395
|
+
async fetchOpenOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3396
|
+
await this.loadMarkets();
|
|
3397
|
+
const market = this.market(symbol);
|
|
3398
|
+
const type = this.getMarketType('fetchOpenOrdersWs', market, params);
|
|
3399
|
+
if (type !== 'spot' && type !== 'future') {
|
|
3400
|
+
throw new BadRequest(this.id + ' fetchOpenOrdersWs only supports spot or swap markets');
|
|
3401
|
+
}
|
|
3402
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
3403
|
+
const requestId = this.requestId(url);
|
|
3404
|
+
const messageHash = requestId.toString();
|
|
3405
|
+
let returnRateLimits = false;
|
|
3406
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
|
|
3407
|
+
const payload = {
|
|
3408
|
+
'returnRateLimits': returnRateLimits,
|
|
3409
|
+
};
|
|
3410
|
+
if (symbol !== undefined) {
|
|
3411
|
+
payload['symbol'] = this.marketId(symbol);
|
|
3412
|
+
}
|
|
3413
|
+
const message = {
|
|
3414
|
+
'id': messageHash,
|
|
3415
|
+
'method': 'openOrders.status',
|
|
3416
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
3417
|
+
};
|
|
3418
|
+
const subscription = {
|
|
3419
|
+
'method': this.handleOrdersWs,
|
|
3420
|
+
};
|
|
3421
|
+
const orders = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
3422
|
+
return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
|
|
3423
|
+
}
|
|
3424
|
+
/**
|
|
3425
|
+
* @method
|
|
3426
|
+
* @name binance#watchOrders
|
|
3427
|
+
* @description watches information on multiple orders made by the user
|
|
3428
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/user-data-stream#order-update
|
|
3429
|
+
* @see https://developers.binance.com/docs/margin_trading/trade-data-stream/Event-Order-Update
|
|
3430
|
+
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Event-Order-Update
|
|
3431
|
+
* @param {string} symbol unified market symbol of the market the orders were made in
|
|
3432
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
3433
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
3434
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3435
|
+
* @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for spot margin
|
|
3436
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch portfolio margin account orders
|
|
3437
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3438
|
+
*/
|
|
3439
|
+
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3440
|
+
await this.loadMarkets();
|
|
3441
|
+
let messageHash = 'orders';
|
|
3442
|
+
let market = undefined;
|
|
3443
|
+
if (symbol !== undefined) {
|
|
3444
|
+
market = this.market(symbol);
|
|
3445
|
+
symbol = market['symbol'];
|
|
3446
|
+
messageHash += ':' + symbol;
|
|
3447
|
+
}
|
|
3448
|
+
let type = undefined;
|
|
3449
|
+
[type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
|
|
3450
|
+
let subType = undefined;
|
|
3451
|
+
[subType, params] = this.handleSubTypeAndParams('watchOrders', market, params);
|
|
3452
|
+
if (this.isLinear(type, subType)) {
|
|
3453
|
+
type = 'future';
|
|
3454
|
+
}
|
|
3455
|
+
else if (this.isInverse(type, subType)) {
|
|
3456
|
+
type = 'delivery';
|
|
3457
|
+
}
|
|
3458
|
+
params = this.extend(params, { 'type': type, 'symbol': symbol }); // needed inside authenticate for isolated margin
|
|
3459
|
+
await this.authenticate(params);
|
|
3460
|
+
let marginMode = undefined;
|
|
3461
|
+
[marginMode, params] = this.handleMarginModeAndParams('watchOrders', params);
|
|
3462
|
+
let urlType = type;
|
|
3463
|
+
if ((type === 'margin') || ((type === 'spot') && (marginMode !== undefined))) {
|
|
3464
|
+
urlType = 'spot'; // spot-margin shares the same stream as regular spot
|
|
3465
|
+
}
|
|
3466
|
+
let isPortfolioMargin = undefined;
|
|
3467
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchOrders', 'papi', 'portfolioMargin', false);
|
|
3468
|
+
if (isPortfolioMargin) {
|
|
3469
|
+
urlType = 'papi';
|
|
3470
|
+
}
|
|
3471
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
3472
|
+
const client = this.client(url);
|
|
3473
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
3474
|
+
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
3475
|
+
const message = undefined;
|
|
3476
|
+
const orders = await this.watch(url, messageHash, message, type);
|
|
3477
|
+
if (this.newUpdates) {
|
|
3478
|
+
limit = orders.getLimit(symbol, limit);
|
|
3479
|
+
}
|
|
3480
|
+
return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
|
|
3481
|
+
}
|
|
3482
|
+
parseWsOrder(order, market = undefined) {
|
|
3483
|
+
//
|
|
3484
|
+
// spot
|
|
3485
|
+
//
|
|
3486
|
+
// {
|
|
3487
|
+
// "e": "executionReport", // Event type
|
|
3488
|
+
// "E": 1499405658658, // Event time
|
|
3489
|
+
// "s": "ETHBTC", // Symbol
|
|
3490
|
+
// "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
|
|
3491
|
+
// "S": "BUY", // Side
|
|
3492
|
+
// "o": "LIMIT", // Order type
|
|
3493
|
+
// "f": "GTC", // Time in force
|
|
3494
|
+
// "q": "1.00000000", // Order quantity
|
|
3495
|
+
// "p": "0.10264410", // Order price
|
|
3496
|
+
// "P": "0.00000000", // Stop price
|
|
3497
|
+
// "F": "0.00000000", // Iceberg quantity
|
|
3498
|
+
// "g": -1, // OrderListId
|
|
3499
|
+
// "C": null, // Original client order ID; This is the ID of the order being canceled
|
|
3500
|
+
// "x": "NEW", // Current execution type
|
|
3501
|
+
// "X": "NEW", // Current order status
|
|
3502
|
+
// "r": "NONE", // Order reject reason; will be an error code.
|
|
3503
|
+
// "i": 4293153, // Order ID
|
|
3504
|
+
// "l": "0.00000000", // Last executed quantity
|
|
3505
|
+
// "z": "0.00000000", // Cumulative filled quantity
|
|
3506
|
+
// "L": "0.00000000", // Last executed price
|
|
3507
|
+
// "n": "0", // Commission amount
|
|
3508
|
+
// "N": null, // Commission asset
|
|
3509
|
+
// "T": 1499405658657, // Transaction time
|
|
3510
|
+
// "t": -1, // Trade ID
|
|
3511
|
+
// "I": 8641984, // Ignore
|
|
3512
|
+
// "w": true, // Is the order on the book?
|
|
3513
|
+
// "m": false, // Is this trade the maker side?
|
|
3514
|
+
// "M": false, // Ignore
|
|
3515
|
+
// "O": 1499405658657, // Order creation time
|
|
3516
|
+
// "Z": "0.00000000", // Cumulative quote asset transacted quantity
|
|
3517
|
+
// "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
|
|
3518
|
+
// "Q": "0.00000000" // Quote Order Qty
|
|
3519
|
+
// }
|
|
3520
|
+
//
|
|
3521
|
+
// future
|
|
3522
|
+
//
|
|
3523
|
+
// {
|
|
3524
|
+
// "s":"BTCUSDT", // Symbol
|
|
3525
|
+
// "c":"TEST", // Client Order Id
|
|
3526
|
+
// // special client order id:
|
|
3527
|
+
// // starts with "autoclose-": liquidation order
|
|
3528
|
+
// // "adl_autoclose": ADL auto close order
|
|
3529
|
+
// "S":"SELL", // Side
|
|
3530
|
+
// "o":"TRAILING_STOP_MARKET", // Order Type
|
|
3531
|
+
// "f":"GTC", // Time in Force
|
|
3532
|
+
// "q":"0.001", // Original Quantity
|
|
3533
|
+
// "p":"0", // Original Price
|
|
3534
|
+
// "ap":"0", // Average Price
|
|
3535
|
+
// "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
|
3536
|
+
// "x":"NEW", // Execution Type
|
|
3537
|
+
// "X":"NEW", // Order Status
|
|
3538
|
+
// "i":8886774, // Order Id
|
|
3539
|
+
// "l":"0", // Order Last Filled Quantity
|
|
3540
|
+
// "z":"0", // Order Filled Accumulated Quantity
|
|
3541
|
+
// "L":"0", // Last Filled Price
|
|
3542
|
+
// "N":"USDT", // Commission Asset, will not push if no commission
|
|
3543
|
+
// "n":"0", // Commission, will not push if no commission
|
|
3544
|
+
// "T":1568879465651, // Order Trade Time
|
|
3545
|
+
// "t":0, // Trade Id
|
|
3546
|
+
// "b":"0", // Bids Notional
|
|
3547
|
+
// "a":"9.91", // Ask Notional
|
|
3548
|
+
// "m":false, // Is this trade the maker side?
|
|
3549
|
+
// "R":false, // Is this reduce only
|
|
3550
|
+
// "wt":"CONTRACT_PRICE", // Stop Price Working Type
|
|
3551
|
+
// "ot":"TRAILING_STOP_MARKET", // Original Order Type
|
|
3552
|
+
// "ps":"LONG", // Position Side
|
|
3553
|
+
// "cp":false, // If Close-All, pushed with conditional order
|
|
3554
|
+
// "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
|
|
3555
|
+
// "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
|
3556
|
+
// "rp":"0" // Realized Profit of the trade
|
|
3557
|
+
// }
|
|
3558
|
+
//
|
|
3559
|
+
const executionType = this.safeString(order, 'x');
|
|
3560
|
+
const orderId = this.safeString(order, 'i');
|
|
3561
|
+
const marketId = this.safeString(order, 's');
|
|
3562
|
+
const marketType = ('ps' in order) ? 'contract' : 'spot';
|
|
3563
|
+
const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
|
|
3564
|
+
let timestamp = this.safeInteger(order, 'O');
|
|
3565
|
+
const T = this.safeInteger(order, 'T');
|
|
3566
|
+
let lastTradeTimestamp = undefined;
|
|
3567
|
+
if (executionType === 'NEW' || executionType === 'AMENDMENT' || executionType === 'CANCELED') {
|
|
3568
|
+
if (timestamp === undefined) {
|
|
3569
|
+
timestamp = T;
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
else if (executionType === 'TRADE') {
|
|
3573
|
+
lastTradeTimestamp = T;
|
|
3574
|
+
}
|
|
3575
|
+
const lastUpdateTimestamp = T;
|
|
3576
|
+
let fee = undefined;
|
|
3577
|
+
const feeCost = this.safeString(order, 'n');
|
|
3578
|
+
if ((feeCost !== undefined) && (Precise.stringGt(feeCost, '0'))) {
|
|
3579
|
+
const feeCurrencyId = this.safeString(order, 'N');
|
|
3580
|
+
const feeCurrency = this.safeCurrencyCode(feeCurrencyId);
|
|
3581
|
+
fee = {
|
|
3582
|
+
'cost': feeCost,
|
|
3583
|
+
'currency': feeCurrency,
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
const price = this.safeString(order, 'p');
|
|
3587
|
+
const amount = this.safeString(order, 'q');
|
|
3588
|
+
const side = this.safeStringLower(order, 'S');
|
|
3589
|
+
const type = this.safeStringLower(order, 'o');
|
|
3590
|
+
const filled = this.safeString(order, 'z');
|
|
3591
|
+
const cost = this.safeString(order, 'Z');
|
|
3592
|
+
const average = this.safeString(order, 'ap');
|
|
3593
|
+
const rawStatus = this.safeString(order, 'X');
|
|
3594
|
+
const status = this.parseOrderStatus(rawStatus);
|
|
3595
|
+
const trades = undefined;
|
|
3596
|
+
let clientOrderId = this.safeString(order, 'C');
|
|
3597
|
+
if ((clientOrderId === undefined) || (clientOrderId.length === 0)) {
|
|
3598
|
+
clientOrderId = this.safeString(order, 'c');
|
|
3599
|
+
}
|
|
3600
|
+
const stopPrice = this.safeString2(order, 'P', 'sp');
|
|
3601
|
+
let timeInForce = this.safeString(order, 'f');
|
|
3602
|
+
if (timeInForce === 'GTX') {
|
|
3603
|
+
// GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
|
|
3604
|
+
timeInForce = 'PO';
|
|
3605
|
+
}
|
|
3606
|
+
return this.safeOrder({
|
|
3607
|
+
'info': order,
|
|
3608
|
+
'symbol': symbol,
|
|
3609
|
+
'id': orderId,
|
|
3610
|
+
'clientOrderId': clientOrderId,
|
|
3611
|
+
'timestamp': timestamp,
|
|
3612
|
+
'datetime': this.iso8601(timestamp),
|
|
3613
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
|
3614
|
+
'lastUpdateTimestamp': lastUpdateTimestamp,
|
|
3615
|
+
'type': type,
|
|
3616
|
+
'timeInForce': timeInForce,
|
|
3617
|
+
'postOnly': undefined,
|
|
3618
|
+
'reduceOnly': this.safeBool(order, 'R'),
|
|
3619
|
+
'side': side,
|
|
3620
|
+
'price': price,
|
|
3621
|
+
'stopPrice': stopPrice,
|
|
3622
|
+
'triggerPrice': stopPrice,
|
|
3623
|
+
'amount': amount,
|
|
3624
|
+
'cost': cost,
|
|
3625
|
+
'average': average,
|
|
3626
|
+
'filled': filled,
|
|
3627
|
+
'remaining': undefined,
|
|
3628
|
+
'status': status,
|
|
3629
|
+
'fee': fee,
|
|
3630
|
+
'trades': trades,
|
|
3631
|
+
});
|
|
3632
|
+
}
|
|
3633
|
+
handleOrderUpdate(client, message) {
|
|
3634
|
+
//
|
|
3635
|
+
// spot
|
|
3636
|
+
//
|
|
3637
|
+
// {
|
|
3638
|
+
// "e": "executionReport", // Event type
|
|
3639
|
+
// "E": 1499405658658, // Event time
|
|
3640
|
+
// "s": "ETHBTC", // Symbol
|
|
3641
|
+
// "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
|
|
3642
|
+
// "S": "BUY", // Side
|
|
3643
|
+
// "o": "LIMIT", // Order type
|
|
3644
|
+
// "f": "GTC", // Time in force
|
|
3645
|
+
// "q": "1.00000000", // Order quantity
|
|
3646
|
+
// "p": "0.10264410", // Order price
|
|
3647
|
+
// "P": "0.00000000", // Stop price
|
|
3648
|
+
// "F": "0.00000000", // Iceberg quantity
|
|
3649
|
+
// "g": -1, // OrderListId
|
|
3650
|
+
// "C": null, // Original client order ID; This is the ID of the order being canceled
|
|
3651
|
+
// "x": "NEW", // Current execution type
|
|
3652
|
+
// "X": "NEW", // Current order status
|
|
3653
|
+
// "r": "NONE", // Order reject reason; will be an error code.
|
|
3654
|
+
// "i": 4293153, // Order ID
|
|
3655
|
+
// "l": "0.00000000", // Last executed quantity
|
|
3656
|
+
// "z": "0.00000000", // Cumulative filled quantity
|
|
3657
|
+
// "L": "0.00000000", // Last executed price
|
|
3658
|
+
// "n": "0", // Commission amount
|
|
3659
|
+
// "N": null, // Commission asset
|
|
3660
|
+
// "T": 1499405658657, // Transaction time
|
|
3661
|
+
// "t": -1, // Trade ID
|
|
3662
|
+
// "I": 8641984, // Ignore
|
|
3663
|
+
// "w": true, // Is the order on the book?
|
|
3664
|
+
// "m": false, // Is this trade the maker side?
|
|
3665
|
+
// "M": false, // Ignore
|
|
3666
|
+
// "O": 1499405658657, // Order creation time
|
|
3667
|
+
// "Z": "0.00000000", // Cumulative quote asset transacted quantity
|
|
3668
|
+
// "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
|
|
3669
|
+
// "Q": "0.00000000" // Quote Order Qty
|
|
3670
|
+
// }
|
|
3671
|
+
//
|
|
3672
|
+
// future
|
|
3673
|
+
//
|
|
3674
|
+
// {
|
|
3675
|
+
// "e":"ORDER_TRADE_UPDATE", // Event Type
|
|
3676
|
+
// "E":1568879465651, // Event Time
|
|
3677
|
+
// "T":1568879465650, // Trasaction Time
|
|
3678
|
+
// "o": {
|
|
3679
|
+
// "s":"BTCUSDT", // Symbol
|
|
3680
|
+
// "c":"TEST", // Client Order Id
|
|
3681
|
+
// // special client order id:
|
|
3682
|
+
// // starts with "autoclose-": liquidation order
|
|
3683
|
+
// // "adl_autoclose": ADL auto close order
|
|
3684
|
+
// "S":"SELL", // Side
|
|
3685
|
+
// "o":"TRAILING_STOP_MARKET", // Order Type
|
|
3686
|
+
// "f":"GTC", // Time in Force
|
|
3687
|
+
// "q":"0.001", // Original Quantity
|
|
3688
|
+
// "p":"0", // Original Price
|
|
3689
|
+
// "ap":"0", // Average Price
|
|
3690
|
+
// "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
|
3691
|
+
// "x":"NEW", // Execution Type
|
|
3692
|
+
// "X":"NEW", // Order Status
|
|
3693
|
+
// "i":8886774, // Order Id
|
|
3694
|
+
// "l":"0", // Order Last Filled Quantity
|
|
3695
|
+
// "z":"0", // Order Filled Accumulated Quantity
|
|
3696
|
+
// "L":"0", // Last Filled Price
|
|
3697
|
+
// "N":"USDT", // Commission Asset, will not push if no commission
|
|
3698
|
+
// "n":"0", // Commission, will not push if no commission
|
|
3699
|
+
// "T":1568879465651, // Order Trade Time
|
|
3700
|
+
// "t":0, // Trade Id
|
|
3701
|
+
// "b":"0", // Bids Notional
|
|
3702
|
+
// "a":"9.91", // Ask Notional
|
|
3703
|
+
// "m":false, // Is this trade the maker side?
|
|
3704
|
+
// "R":false, // Is this reduce only
|
|
3705
|
+
// "wt":"CONTRACT_PRICE", // Stop Price Working Type
|
|
3706
|
+
// "ot":"TRAILING_STOP_MARKET", // Original Order Type
|
|
3707
|
+
// "ps":"LONG", // Position Side
|
|
3708
|
+
// "cp":false, // If Close-All, pushed with conditional order
|
|
3709
|
+
// "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
|
|
3710
|
+
// "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
|
3711
|
+
// "rp":"0" // Realized Profit of the trade
|
|
3712
|
+
// }
|
|
3713
|
+
// }
|
|
3714
|
+
//
|
|
3715
|
+
const e = this.safeString(message, 'e');
|
|
3716
|
+
if (e === 'ORDER_TRADE_UPDATE') {
|
|
3717
|
+
message = this.safeDict(message, 'o', message);
|
|
3718
|
+
}
|
|
3719
|
+
this.handleMyTrade(client, message);
|
|
3720
|
+
this.handleOrder(client, message);
|
|
3721
|
+
this.handleMyLiquidation(client, message);
|
|
3722
|
+
}
|
|
3723
|
+
/**
|
|
3724
|
+
* @method
|
|
3725
|
+
* @name binance#watchPositions
|
|
3726
|
+
* @description watch all open positions
|
|
3727
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
3728
|
+
* @param {number} [since] since timestamp
|
|
3729
|
+
* @param {number} [limit] limit
|
|
3730
|
+
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
3731
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch positions in a portfolio margin account
|
|
3732
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
3733
|
+
*/
|
|
3734
|
+
async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3735
|
+
await this.loadMarkets();
|
|
3736
|
+
let market = undefined;
|
|
3737
|
+
let messageHash = '';
|
|
3738
|
+
symbols = this.marketSymbols(symbols);
|
|
3739
|
+
if (!this.isEmpty(symbols)) {
|
|
3740
|
+
market = this.getMarketFromSymbols(symbols);
|
|
3741
|
+
messageHash = '::' + symbols.join(',');
|
|
3742
|
+
}
|
|
3743
|
+
let type = undefined;
|
|
3744
|
+
[type, params] = this.handleMarketTypeAndParams('watchPositions', market, params);
|
|
3745
|
+
if (type === 'spot' || type === 'margin') {
|
|
3746
|
+
type = 'future';
|
|
3747
|
+
}
|
|
3748
|
+
let subType = undefined;
|
|
3749
|
+
[subType, params] = this.handleSubTypeAndParams('watchPositions', market, params);
|
|
3750
|
+
if (this.isLinear(type, subType)) {
|
|
3751
|
+
type = 'future';
|
|
3752
|
+
}
|
|
3753
|
+
else if (this.isInverse(type, subType)) {
|
|
3754
|
+
type = 'delivery';
|
|
3755
|
+
}
|
|
3756
|
+
const marketTypeObject = {};
|
|
3757
|
+
marketTypeObject['type'] = type;
|
|
3758
|
+
marketTypeObject['subType'] = subType;
|
|
3759
|
+
await this.authenticate(this.extend(marketTypeObject, params));
|
|
3760
|
+
messageHash = type + ':positions' + messageHash;
|
|
3761
|
+
let isPortfolioMargin = undefined;
|
|
3762
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchPositions', 'papi', 'portfolioMargin', false);
|
|
3763
|
+
let urlType = type;
|
|
3764
|
+
if (isPortfolioMargin) {
|
|
3765
|
+
urlType = 'papi';
|
|
3766
|
+
}
|
|
3767
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
3768
|
+
const client = this.client(url);
|
|
3769
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
3770
|
+
this.setPositionsCache(client, type, symbols, isPortfolioMargin);
|
|
3771
|
+
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
|
|
3772
|
+
const awaitPositionsSnapshot = this.handleOption('watchPositions', 'awaitPositionsSnapshot', true);
|
|
3773
|
+
const cache = this.safeValue(this.positions, type);
|
|
3774
|
+
if (fetchPositionsSnapshot && awaitPositionsSnapshot && cache === undefined) {
|
|
3775
|
+
const snapshot = await client.future(type + ':fetchPositionsSnapshot');
|
|
3776
|
+
return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
|
|
3777
|
+
}
|
|
3778
|
+
const newPositions = await this.watch(url, messageHash, undefined, type);
|
|
3779
|
+
if (this.newUpdates) {
|
|
3780
|
+
return newPositions;
|
|
3781
|
+
}
|
|
3782
|
+
return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
|
|
3783
|
+
}
|
|
3784
|
+
setPositionsCache(client, type, symbols = undefined, isPortfolioMargin = false) {
|
|
3785
|
+
if (type === 'spot') {
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
if (this.positions === undefined) {
|
|
3789
|
+
this.positions = {};
|
|
3790
|
+
}
|
|
3791
|
+
if (type in this.positions) {
|
|
3792
|
+
return;
|
|
3793
|
+
}
|
|
3794
|
+
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', false);
|
|
3795
|
+
if (fetchPositionsSnapshot) {
|
|
3796
|
+
const messageHash = type + ':fetchPositionsSnapshot';
|
|
3797
|
+
if (!(messageHash in client.futures)) {
|
|
3798
|
+
client.future(messageHash);
|
|
3799
|
+
this.spawn(this.loadPositionsSnapshot, client, messageHash, type, isPortfolioMargin);
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
else {
|
|
3803
|
+
this.positions[type] = new ArrayCacheBySymbolBySide();
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
async loadPositionsSnapshot(client, messageHash, type, isPortfolioMargin) {
|
|
3807
|
+
const params = {
|
|
3808
|
+
'type': type,
|
|
3809
|
+
};
|
|
3810
|
+
if (isPortfolioMargin) {
|
|
3811
|
+
params['portfolioMargin'] = true;
|
|
3812
|
+
}
|
|
3813
|
+
const positions = await this.fetchPositions(undefined, params);
|
|
3814
|
+
this.positions[type] = new ArrayCacheBySymbolBySide();
|
|
3815
|
+
const cache = this.positions[type];
|
|
3816
|
+
for (let i = 0; i < positions.length; i++) {
|
|
3817
|
+
const position = positions[i];
|
|
3818
|
+
const contracts = this.safeNumber(position, 'contracts', 0);
|
|
3819
|
+
if (contracts > 0) {
|
|
3820
|
+
cache.append(position);
|
|
3821
|
+
}
|
|
3822
|
+
}
|
|
3823
|
+
// don't remove the future from the .futures cache
|
|
3824
|
+
const future = client.futures[messageHash];
|
|
3825
|
+
future.resolve(cache);
|
|
3826
|
+
client.resolve(cache, type + ':position');
|
|
3827
|
+
}
|
|
3828
|
+
handlePositions(client, message) {
|
|
3829
|
+
//
|
|
3830
|
+
// {
|
|
3831
|
+
// e: 'ACCOUNT_UPDATE',
|
|
3832
|
+
// T: 1667881353112,
|
|
3833
|
+
// E: 1667881353115,
|
|
3834
|
+
// a: {
|
|
3835
|
+
// B: [{
|
|
3836
|
+
// a: 'USDT',
|
|
3837
|
+
// wb: '1127.95750089',
|
|
3838
|
+
// cw: '1040.82091149',
|
|
3839
|
+
// bc: '0'
|
|
3840
|
+
// }],
|
|
3841
|
+
// P: [{
|
|
3842
|
+
// s: 'BTCUSDT',
|
|
3843
|
+
// pa: '-0.089',
|
|
3844
|
+
// ep: '19700.03933',
|
|
3845
|
+
// cr: '-1260.24809979',
|
|
3846
|
+
// up: '1.53058860',
|
|
3847
|
+
// mt: 'isolated',
|
|
3848
|
+
// iw: '87.13658940',
|
|
3849
|
+
// ps: 'BOTH',
|
|
3850
|
+
// ma: 'USDT'
|
|
3851
|
+
// }],
|
|
3852
|
+
// m: 'ORDER'
|
|
3853
|
+
// }
|
|
3854
|
+
// }
|
|
3855
|
+
//
|
|
3856
|
+
// each account is connected to a different endpoint
|
|
3857
|
+
// and has exactly one subscriptionhash which is the account type
|
|
3858
|
+
const subscriptions = Object.keys(client.subscriptions);
|
|
3859
|
+
const accountType = subscriptions[0];
|
|
3860
|
+
if (this.positions === undefined) {
|
|
3861
|
+
this.positions = {};
|
|
3862
|
+
}
|
|
3863
|
+
if (!(accountType in this.positions)) {
|
|
3864
|
+
this.positions[accountType] = new ArrayCacheBySymbolBySide();
|
|
3865
|
+
}
|
|
3866
|
+
const cache = this.positions[accountType];
|
|
3867
|
+
const data = this.safeDict(message, 'a', {});
|
|
3868
|
+
const rawPositions = this.safeList(data, 'P', []);
|
|
3869
|
+
const newPositions = [];
|
|
3870
|
+
for (let i = 0; i < rawPositions.length; i++) {
|
|
3871
|
+
const rawPosition = rawPositions[i];
|
|
3872
|
+
const position = this.parseWsPosition(rawPosition);
|
|
3873
|
+
const timestamp = this.safeInteger(message, 'E');
|
|
3874
|
+
position['timestamp'] = timestamp;
|
|
3875
|
+
position['datetime'] = this.iso8601(timestamp);
|
|
3876
|
+
newPositions.push(position);
|
|
3877
|
+
cache.append(position);
|
|
3878
|
+
}
|
|
3879
|
+
const messageHashes = this.findMessageHashes(client, accountType + ':positions::');
|
|
3880
|
+
for (let i = 0; i < messageHashes.length; i++) {
|
|
3881
|
+
const messageHash = messageHashes[i];
|
|
3882
|
+
const parts = messageHash.split('::');
|
|
3883
|
+
const symbolsString = parts[1];
|
|
3884
|
+
const symbols = symbolsString.split(',');
|
|
3885
|
+
const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
|
|
3886
|
+
if (!this.isEmpty(positions)) {
|
|
3887
|
+
client.resolve(positions, messageHash);
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
client.resolve(newPositions, accountType + ':positions');
|
|
3891
|
+
}
|
|
3892
|
+
parseWsPosition(position, market = undefined) {
|
|
3893
|
+
//
|
|
3894
|
+
// {
|
|
3895
|
+
// "s": "BTCUSDT", // Symbol
|
|
3896
|
+
// "pa": "0", // Position Amount
|
|
3897
|
+
// "ep": "0.00000", // Entry Price
|
|
3898
|
+
// "cr": "200", // (Pre-fee) Accumulated Realized
|
|
3899
|
+
// "up": "0", // Unrealized PnL
|
|
3900
|
+
// "mt": "isolated", // Margin Type
|
|
3901
|
+
// "iw": "0.00000000", // Isolated Wallet (if isolated position)
|
|
3902
|
+
// "ps": "BOTH" // Position Side
|
|
3903
|
+
// }
|
|
3904
|
+
//
|
|
3905
|
+
const marketId = this.safeString(position, 's');
|
|
3906
|
+
const contracts = this.safeString(position, 'pa');
|
|
3907
|
+
const contractsAbs = Precise.stringAbs(this.safeString(position, 'pa'));
|
|
3908
|
+
let positionSide = this.safeStringLower(position, 'ps');
|
|
3909
|
+
let hedged = true;
|
|
3910
|
+
if (positionSide === 'both') {
|
|
3911
|
+
hedged = false;
|
|
3912
|
+
if (!Precise.stringEq(contracts, '0')) {
|
|
3913
|
+
if (Precise.stringLt(contracts, '0')) {
|
|
3914
|
+
positionSide = 'short';
|
|
3915
|
+
}
|
|
3916
|
+
else {
|
|
3917
|
+
positionSide = 'long';
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
return this.safePosition({
|
|
3922
|
+
'info': position,
|
|
3923
|
+
'id': undefined,
|
|
3924
|
+
'symbol': this.safeSymbol(marketId, undefined, undefined, 'contract'),
|
|
3925
|
+
'notional': undefined,
|
|
3926
|
+
'marginMode': this.safeString(position, 'mt'),
|
|
3927
|
+
'liquidationPrice': undefined,
|
|
3928
|
+
'entryPrice': this.safeNumber(position, 'ep'),
|
|
3929
|
+
'unrealizedPnl': this.safeNumber(position, 'up'),
|
|
3930
|
+
'percentage': undefined,
|
|
3931
|
+
'contracts': this.parseNumber(contractsAbs),
|
|
3932
|
+
'contractSize': undefined,
|
|
3933
|
+
'markPrice': undefined,
|
|
3934
|
+
'side': positionSide,
|
|
3935
|
+
'hedged': hedged,
|
|
3936
|
+
'timestamp': undefined,
|
|
3937
|
+
'datetime': undefined,
|
|
3938
|
+
'maintenanceMargin': undefined,
|
|
3939
|
+
'maintenanceMarginPercentage': undefined,
|
|
3940
|
+
'collateral': undefined,
|
|
3941
|
+
'initialMargin': undefined,
|
|
3942
|
+
'initialMarginPercentage': undefined,
|
|
3943
|
+
'leverage': undefined,
|
|
3944
|
+
'marginRatio': undefined,
|
|
3945
|
+
});
|
|
3946
|
+
}
|
|
3947
|
+
/**
|
|
3948
|
+
* @method
|
|
3949
|
+
* @name binance#fetchMyTradesWs
|
|
3950
|
+
* @description fetch all trades made by the user
|
|
3951
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/account-requests#account-trade-history-user_data
|
|
3952
|
+
* @param {string} symbol unified market symbol
|
|
3953
|
+
* @param {int|undefined} [since] the earliest time in ms to fetch trades for
|
|
3954
|
+
* @param {int|undefined} [limit] the maximum number of trades structures to retrieve
|
|
3955
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3956
|
+
* @param {int} [params.endTime] the latest time in ms to fetch trades for
|
|
3957
|
+
* @param {int} [params.fromId] first trade Id to fetch
|
|
3958
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
3959
|
+
*/
|
|
3960
|
+
async fetchMyTradesWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3961
|
+
await this.loadMarkets();
|
|
3962
|
+
if (symbol === undefined) {
|
|
3963
|
+
throw new BadRequest(this.id + ' fetchMyTradesWs requires a symbol');
|
|
3964
|
+
}
|
|
3965
|
+
const market = this.market(symbol);
|
|
3966
|
+
const type = this.getMarketType('fetchMyTradesWs', market, params);
|
|
3967
|
+
if (type !== 'spot' && type !== 'future') {
|
|
3968
|
+
throw new BadRequest(this.id + ' fetchMyTradesWs does not support ' + type + ' markets');
|
|
3969
|
+
}
|
|
3970
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
3971
|
+
const requestId = this.requestId(url);
|
|
3972
|
+
const messageHash = requestId.toString();
|
|
3973
|
+
let returnRateLimits = false;
|
|
3974
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchMyTradesWs', 'returnRateLimits', false);
|
|
3975
|
+
const payload = {
|
|
3976
|
+
'symbol': this.marketId(symbol),
|
|
3977
|
+
'returnRateLimits': returnRateLimits,
|
|
3978
|
+
};
|
|
3979
|
+
if (since !== undefined) {
|
|
3980
|
+
payload['startTime'] = since;
|
|
3981
|
+
}
|
|
3982
|
+
if (limit !== undefined) {
|
|
3983
|
+
payload['limit'] = limit;
|
|
3984
|
+
}
|
|
3985
|
+
const fromId = this.safeInteger(params, 'fromId');
|
|
3986
|
+
if (fromId !== undefined && since !== undefined) {
|
|
3987
|
+
throw new BadRequest(this.id + ' fetchMyTradesWs does not support fetching by both fromId and since parameters at the same time');
|
|
3988
|
+
}
|
|
3989
|
+
const message = {
|
|
3990
|
+
'id': messageHash,
|
|
3991
|
+
'method': 'myTrades',
|
|
3992
|
+
'params': this.signParams(this.extend(payload, params)),
|
|
3993
|
+
};
|
|
3994
|
+
const subscription = {
|
|
3995
|
+
'method': this.handleTradesWs,
|
|
3996
|
+
};
|
|
3997
|
+
const trades = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
3998
|
+
return this.filterBySymbolSinceLimit(trades, symbol, since, limit);
|
|
3999
|
+
}
|
|
4000
|
+
/**
|
|
4001
|
+
* @method
|
|
4002
|
+
* @name binance#fetchTradesWs
|
|
4003
|
+
* @description fetch all trades made by the user
|
|
4004
|
+
* @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
|
|
4005
|
+
* @param {string} symbol unified market symbol
|
|
4006
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
4007
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve, default=500, max=1000
|
|
4008
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
4009
|
+
*
|
|
4010
|
+
* EXCHANGE SPECIFIC PARAMETERS
|
|
4011
|
+
* @param {int} [params.fromId] trade ID to begin at
|
|
4012
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
4013
|
+
*/
|
|
4014
|
+
async fetchTradesWs(symbol, since = undefined, limit = undefined, params = {}) {
|
|
4015
|
+
await this.loadMarkets();
|
|
4016
|
+
const market = this.market(symbol);
|
|
4017
|
+
const type = this.getMarketType('fetchTradesWs', market, params);
|
|
4018
|
+
if (type !== 'spot' && type !== 'future') {
|
|
4019
|
+
throw new BadRequest(this.id + ' fetchTradesWs does not support ' + type + ' markets');
|
|
4020
|
+
}
|
|
4021
|
+
const url = this.urls['api']['ws']['ws-api'][type];
|
|
4022
|
+
const requestId = this.requestId(url);
|
|
4023
|
+
const messageHash = requestId.toString();
|
|
4024
|
+
let returnRateLimits = false;
|
|
4025
|
+
[returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchTradesWs', 'returnRateLimits', false);
|
|
4026
|
+
const payload = {
|
|
4027
|
+
'symbol': this.marketId(symbol),
|
|
4028
|
+
'returnRateLimits': returnRateLimits,
|
|
4029
|
+
};
|
|
4030
|
+
if (limit !== undefined) {
|
|
4031
|
+
payload['limit'] = limit;
|
|
4032
|
+
}
|
|
4033
|
+
const message = {
|
|
4034
|
+
'id': messageHash,
|
|
4035
|
+
'method': 'trades.historical',
|
|
4036
|
+
'params': this.extend(payload, params),
|
|
4037
|
+
};
|
|
4038
|
+
const subscription = {
|
|
4039
|
+
'method': this.handleTradesWs,
|
|
4040
|
+
};
|
|
4041
|
+
const trades = await this.watch(url, messageHash, message, messageHash, subscription);
|
|
4042
|
+
return this.filterBySinceLimit(trades, since, limit);
|
|
4043
|
+
}
|
|
4044
|
+
handleTradesWs(client, message) {
|
|
4045
|
+
//
|
|
4046
|
+
// fetchMyTradesWs
|
|
4047
|
+
//
|
|
4048
|
+
// {
|
|
4049
|
+
// "id": "f4ce6a53-a29d-4f70-823b-4ab59391d6e8",
|
|
4050
|
+
// "status": 200,
|
|
4051
|
+
// "result": [
|
|
4052
|
+
// {
|
|
4053
|
+
// "symbol": "BTCUSDT",
|
|
4054
|
+
// "id": 1650422481,
|
|
4055
|
+
// "orderId": 12569099453,
|
|
4056
|
+
// "orderListId": -1,
|
|
4057
|
+
// "price": "23416.10000000",
|
|
4058
|
+
// "qty": "0.00635000",
|
|
4059
|
+
// "quoteQty": "148.69223500",
|
|
4060
|
+
// "commission": "0.00000000",
|
|
4061
|
+
// "commissionAsset": "BNB",
|
|
4062
|
+
// "time": 1660801715793,
|
|
4063
|
+
// "isBuyer": false,
|
|
4064
|
+
// "isMaker": true,
|
|
4065
|
+
// "isBestMatch": true
|
|
4066
|
+
// },
|
|
4067
|
+
// ...
|
|
4068
|
+
// ],
|
|
4069
|
+
// }
|
|
4070
|
+
//
|
|
4071
|
+
// fetchTradesWs
|
|
4072
|
+
//
|
|
4073
|
+
// {
|
|
4074
|
+
// "id": "f4ce6a53-a29d-4f70-823b-4ab59391d6e8",
|
|
4075
|
+
// "status": 200,
|
|
4076
|
+
// "result": [
|
|
4077
|
+
// {
|
|
4078
|
+
// "id": 0,
|
|
4079
|
+
// "price": "0.00005000",
|
|
4080
|
+
// "qty": "40.00000000",
|
|
4081
|
+
// "quoteQty": "0.00200000",
|
|
4082
|
+
// "time": 1500004800376,
|
|
4083
|
+
// "isBuyerMaker": true,
|
|
4084
|
+
// "isBestMatch": true
|
|
4085
|
+
// }
|
|
4086
|
+
// ...
|
|
4087
|
+
// ],
|
|
4088
|
+
// }
|
|
4089
|
+
//
|
|
4090
|
+
const messageHash = this.safeString(message, 'id');
|
|
4091
|
+
const result = this.safeList(message, 'result', []);
|
|
4092
|
+
const trades = this.parseTrades(result);
|
|
4093
|
+
client.resolve(trades, messageHash);
|
|
4094
|
+
}
|
|
4095
|
+
/**
|
|
4096
|
+
* @method
|
|
4097
|
+
* @name binance#watchMyTrades
|
|
4098
|
+
* @description watches information on multiple trades made by the user
|
|
4099
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
4100
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
4101
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
4102
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
4103
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch trades in a portfolio margin account
|
|
4104
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
4105
|
+
*/
|
|
4106
|
+
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
4107
|
+
await this.loadMarkets();
|
|
4108
|
+
let type = undefined;
|
|
4109
|
+
let market = undefined;
|
|
4110
|
+
if (symbol !== undefined) {
|
|
4111
|
+
market = this.market(symbol);
|
|
4112
|
+
symbol = market['symbol'];
|
|
4113
|
+
}
|
|
4114
|
+
[type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
|
|
4115
|
+
let subType = undefined;
|
|
4116
|
+
[subType, params] = this.handleSubTypeAndParams('watchMyTrades', market, params);
|
|
4117
|
+
if (this.isLinear(type, subType)) {
|
|
4118
|
+
type = 'future';
|
|
4119
|
+
}
|
|
4120
|
+
else if (this.isInverse(type, subType)) {
|
|
4121
|
+
type = 'delivery';
|
|
4122
|
+
}
|
|
4123
|
+
let messageHash = 'myTrades';
|
|
4124
|
+
if (symbol !== undefined) {
|
|
4125
|
+
symbol = this.symbol(symbol);
|
|
4126
|
+
messageHash += ':' + symbol;
|
|
4127
|
+
params = this.extend(params, { 'type': market['type'], 'symbol': symbol });
|
|
4128
|
+
}
|
|
4129
|
+
await this.authenticate(params);
|
|
4130
|
+
let urlType = type; // we don't change type because the listening key is different
|
|
4131
|
+
if (type === 'margin') {
|
|
4132
|
+
urlType = 'spot'; // spot-margin shares the same stream as regular spot
|
|
4133
|
+
}
|
|
4134
|
+
let isPortfolioMargin = undefined;
|
|
4135
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchMyTrades', 'papi', 'portfolioMargin', false);
|
|
4136
|
+
if (isPortfolioMargin) {
|
|
4137
|
+
urlType = 'papi';
|
|
4138
|
+
}
|
|
4139
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
4140
|
+
const client = this.client(url);
|
|
4141
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
4142
|
+
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
4143
|
+
const message = undefined;
|
|
4144
|
+
const trades = await this.watch(url, messageHash, message, type);
|
|
4145
|
+
if (this.newUpdates) {
|
|
4146
|
+
limit = trades.getLimit(symbol, limit);
|
|
4147
|
+
}
|
|
4148
|
+
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
|
|
4149
|
+
}
|
|
4150
|
+
handleMyTrade(client, message) {
|
|
4151
|
+
const messageHash = 'myTrades';
|
|
4152
|
+
const executionType = this.safeString(message, 'x');
|
|
4153
|
+
if (executionType === 'TRADE') {
|
|
4154
|
+
const trade = this.parseWsTrade(message);
|
|
4155
|
+
const orderId = this.safeString(trade, 'order');
|
|
4156
|
+
let tradeFee = this.safeDict(trade, 'fee', {});
|
|
4157
|
+
tradeFee = this.extend({}, tradeFee);
|
|
4158
|
+
const symbol = this.safeString(trade, 'symbol');
|
|
4159
|
+
if (orderId !== undefined && tradeFee !== undefined && symbol !== undefined) {
|
|
4160
|
+
const cachedOrders = this.orders;
|
|
4161
|
+
if (cachedOrders !== undefined) {
|
|
4162
|
+
const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
|
|
4163
|
+
const order = this.safeValue(orders, orderId);
|
|
4164
|
+
if (order !== undefined) {
|
|
4165
|
+
// accumulate order fees
|
|
4166
|
+
const fees = this.safeValue(order, 'fees');
|
|
4167
|
+
const fee = this.safeValue(order, 'fee');
|
|
4168
|
+
if (!this.isEmpty(fees)) {
|
|
4169
|
+
let insertNewFeeCurrency = true;
|
|
4170
|
+
for (let i = 0; i < fees.length; i++) {
|
|
4171
|
+
const orderFee = fees[i];
|
|
4172
|
+
if (orderFee['currency'] === tradeFee['currency']) {
|
|
4173
|
+
const feeCost = this.sum(tradeFee['cost'], orderFee['cost']);
|
|
4174
|
+
order['fees'][i]['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
|
|
4175
|
+
insertNewFeeCurrency = false;
|
|
4176
|
+
break;
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
if (insertNewFeeCurrency) {
|
|
4180
|
+
order['fees'].push(tradeFee);
|
|
4181
|
+
}
|
|
4182
|
+
}
|
|
4183
|
+
else if (fee !== undefined) {
|
|
4184
|
+
if (fee['currency'] === tradeFee['currency']) {
|
|
4185
|
+
const feeCost = this.sum(fee['cost'], tradeFee['cost']);
|
|
4186
|
+
order['fee']['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
|
|
4187
|
+
}
|
|
4188
|
+
else if (fee['currency'] === undefined) {
|
|
4189
|
+
order['fee'] = tradeFee;
|
|
4190
|
+
}
|
|
4191
|
+
else {
|
|
4192
|
+
order['fees'] = [fee, tradeFee];
|
|
4193
|
+
order['fee'] = undefined;
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
else {
|
|
4197
|
+
order['fee'] = tradeFee;
|
|
4198
|
+
}
|
|
4199
|
+
// save this trade in the order
|
|
4200
|
+
const orderTrades = this.safeList(order, 'trades', []);
|
|
4201
|
+
orderTrades.push(trade);
|
|
4202
|
+
order['trades'] = orderTrades;
|
|
4203
|
+
// don't append twice cause it breaks newUpdates mode
|
|
4204
|
+
// this order already exists in the cache
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
if (this.myTrades === undefined) {
|
|
4209
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
4210
|
+
this.myTrades = new ArrayCacheBySymbolById(limit);
|
|
4211
|
+
}
|
|
4212
|
+
const myTrades = this.myTrades;
|
|
4213
|
+
myTrades.append(trade);
|
|
4214
|
+
client.resolve(this.myTrades, messageHash);
|
|
4215
|
+
const messageHashSymbol = messageHash + ':' + symbol;
|
|
4216
|
+
client.resolve(this.myTrades, messageHashSymbol);
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
handleOrder(client, message) {
|
|
4220
|
+
const parsed = this.parseWsOrder(message);
|
|
4221
|
+
const symbol = this.safeString(parsed, 'symbol');
|
|
4222
|
+
const orderId = this.safeString(parsed, 'id');
|
|
4223
|
+
if (symbol !== undefined) {
|
|
4224
|
+
if (this.orders === undefined) {
|
|
4225
|
+
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
|
|
4226
|
+
this.orders = new ArrayCacheBySymbolById(limit);
|
|
4227
|
+
}
|
|
4228
|
+
const cachedOrders = this.orders;
|
|
4229
|
+
const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
|
|
4230
|
+
const order = this.safeValue(orders, orderId);
|
|
4231
|
+
if (order !== undefined) {
|
|
4232
|
+
const fee = this.safeValue(order, 'fee');
|
|
4233
|
+
if (fee !== undefined) {
|
|
4234
|
+
parsed['fee'] = fee;
|
|
4235
|
+
}
|
|
4236
|
+
const fees = this.safeValue(order, 'fees');
|
|
4237
|
+
if (fees !== undefined) {
|
|
4238
|
+
parsed['fees'] = fees;
|
|
4239
|
+
}
|
|
4240
|
+
parsed['trades'] = this.safeValue(order, 'trades');
|
|
4241
|
+
const timestamp = this.safeInteger(parsed, 'timestamp');
|
|
4242
|
+
if (timestamp === undefined) {
|
|
4243
|
+
parsed['timestamp'] = this.safeInteger(order, 'timestamp');
|
|
4244
|
+
parsed['datetime'] = this.safeString(order, 'datetime');
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
cachedOrders.append(parsed);
|
|
4248
|
+
const messageHash = 'orders';
|
|
4249
|
+
const symbolSpecificMessageHash = 'orders:' + symbol;
|
|
4250
|
+
client.resolve(cachedOrders, messageHash);
|
|
4251
|
+
client.resolve(cachedOrders, symbolSpecificMessageHash);
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
handleAcountUpdate(client, message) {
|
|
4255
|
+
this.handleBalance(client, message);
|
|
4256
|
+
this.handlePositions(client, message);
|
|
4257
|
+
}
|
|
4258
|
+
handleWsError(client, message) {
|
|
4259
|
+
//
|
|
4260
|
+
// {
|
|
4261
|
+
// "error": {
|
|
4262
|
+
// "code": 2,
|
|
4263
|
+
// "msg": "Invalid request: invalid stream"
|
|
4264
|
+
// },
|
|
4265
|
+
// "id": 1
|
|
4266
|
+
// }
|
|
4267
|
+
//
|
|
4268
|
+
const id = this.safeString(message, 'id');
|
|
4269
|
+
let rejected = false;
|
|
4270
|
+
const error = this.safeDict(message, 'error', {});
|
|
4271
|
+
const code = this.safeInteger(error, 'code');
|
|
4272
|
+
const msg = this.safeString(error, 'msg');
|
|
4273
|
+
try {
|
|
4274
|
+
this.handleErrors(code, msg, client.url, '', {}, this.json(error), error, {}, {});
|
|
4275
|
+
}
|
|
4276
|
+
catch (e) {
|
|
4277
|
+
rejected = true;
|
|
4278
|
+
// private endpoint uses id as messageHash
|
|
4279
|
+
client.reject(e, id);
|
|
4280
|
+
// public endpoint stores messageHash in subscriptions
|
|
4281
|
+
const subscriptionKeys = Object.keys(client.subscriptions);
|
|
4282
|
+
for (let i = 0; i < subscriptionKeys.length; i++) {
|
|
4283
|
+
const subscriptionHash = subscriptionKeys[i];
|
|
4284
|
+
const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
|
|
4285
|
+
if (id === subscriptionId) {
|
|
4286
|
+
client.reject(e, subscriptionHash);
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
if (!rejected) {
|
|
4291
|
+
client.reject(message, id);
|
|
4292
|
+
}
|
|
4293
|
+
// reset connection if 5xx error
|
|
4294
|
+
const codeString = this.safeString(error, 'code');
|
|
4295
|
+
if ((codeString !== undefined) && (codeString[0] === '5')) {
|
|
4296
|
+
client.reset(message);
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
handleMessage(client, message) {
|
|
4300
|
+
// handle WebSocketAPI
|
|
4301
|
+
const status = this.safeString(message, 'status');
|
|
4302
|
+
const error = this.safeValue(message, 'error');
|
|
4303
|
+
if ((error !== undefined) || (status !== undefined && status !== '200')) {
|
|
4304
|
+
this.handleWsError(client, message);
|
|
4305
|
+
return;
|
|
4306
|
+
}
|
|
4307
|
+
const id = this.safeString(message, 'id');
|
|
4308
|
+
const subscriptions = this.safeValue(client.subscriptions, id);
|
|
4309
|
+
let method = this.safeValue(subscriptions, 'method');
|
|
4310
|
+
if (method !== undefined) {
|
|
4311
|
+
method.call(this, client, message);
|
|
4312
|
+
return;
|
|
4313
|
+
}
|
|
4314
|
+
// handle other APIs
|
|
4315
|
+
const methods = {
|
|
4316
|
+
'depthUpdate': this.handleOrderBook,
|
|
4317
|
+
'trade': this.handleTrade,
|
|
4318
|
+
'aggTrade': this.handleTrade,
|
|
4319
|
+
'kline': this.handleOHLCV,
|
|
4320
|
+
'markPrice_kline': this.handleOHLCV,
|
|
4321
|
+
'indexPrice_kline': this.handleOHLCV,
|
|
4322
|
+
'1hTicker@arr': this.handleTickers,
|
|
4323
|
+
'4hTicker@arr': this.handleTickers,
|
|
4324
|
+
'1dTicker@arr': this.handleTickers,
|
|
4325
|
+
'24hrTicker@arr': this.handleTickers,
|
|
4326
|
+
'24hrMiniTicker@arr': this.handleTickers,
|
|
4327
|
+
'1hTicker': this.handleTickers,
|
|
4328
|
+
'4hTicker': this.handleTickers,
|
|
4329
|
+
'1dTicker': this.handleTickers,
|
|
4330
|
+
'24hrTicker': this.handleTickers,
|
|
4331
|
+
'24hrMiniTicker': this.handleTickers,
|
|
4332
|
+
'markPriceUpdate': this.handleTickers,
|
|
4333
|
+
'markPriceUpdate@arr': this.handleTickers,
|
|
4334
|
+
'bookTicker': this.handleBidsAsks,
|
|
4335
|
+
'outboundAccountPosition': this.handleBalance,
|
|
4336
|
+
'balanceUpdate': this.handleBalance,
|
|
4337
|
+
'ACCOUNT_UPDATE': this.handleAcountUpdate,
|
|
4338
|
+
'executionReport': this.handleOrderUpdate,
|
|
4339
|
+
'ORDER_TRADE_UPDATE': this.handleOrderUpdate,
|
|
4340
|
+
'forceOrder': this.handleLiquidation,
|
|
4341
|
+
};
|
|
4342
|
+
let event = this.safeString(message, 'e');
|
|
4343
|
+
if (Array.isArray(message)) {
|
|
4344
|
+
const data = message[0];
|
|
4345
|
+
event = this.safeString(data, 'e') + '@arr';
|
|
4346
|
+
}
|
|
4347
|
+
method = this.safeValue(methods, event);
|
|
4348
|
+
if (method === undefined) {
|
|
4349
|
+
const requestId = this.safeString(message, 'id');
|
|
4350
|
+
if (requestId !== undefined) {
|
|
4351
|
+
this.handleSubscriptionStatus(client, message);
|
|
4352
|
+
return;
|
|
4353
|
+
}
|
|
4354
|
+
// special case for the real-time bookTicker, since it comes without an event identifier
|
|
4355
|
+
//
|
|
4356
|
+
// {
|
|
4357
|
+
// "u": 7488717758,
|
|
4358
|
+
// "s": "BTCUSDT",
|
|
4359
|
+
// "b": "28621.74000000",
|
|
4360
|
+
// "B": "1.43278800",
|
|
4361
|
+
// "a": "28621.75000000",
|
|
4362
|
+
// "A": "2.52500800"
|
|
4363
|
+
// }
|
|
4364
|
+
//
|
|
4365
|
+
if (event === undefined && ('a' in message) && ('b' in message)) {
|
|
4366
|
+
this.handleBidsAsks(client, message);
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
else {
|
|
4370
|
+
method.call(this, client, message);
|
|
4371
|
+
}
|
|
4372
|
+
}
|
|
4373
|
+
}
|