ccxt 4.2.18 → 4.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/ccxt.browser.js +34202 -33193
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +12 -1
- package/dist/cjs/src/alpaca.js +18 -18
- package/dist/cjs/src/ascendex.js +13 -6
- package/dist/cjs/src/base/Exchange.js +266 -27
- package/dist/cjs/src/bigone.js +434 -168
- package/dist/cjs/src/binance.js +163 -34
- package/dist/cjs/src/binanceus.js +8 -0
- package/dist/cjs/src/bingx.js +183 -41
- package/dist/cjs/src/bitfinex.js +2 -3
- package/dist/cjs/src/bitget.js +59 -16
- package/dist/cjs/src/bitmart.js +5 -5
- package/dist/cjs/src/bitmex.js +4 -6
- package/dist/cjs/src/bitpanda.js +5 -1991
- package/dist/cjs/src/bitstamp.js +8 -0
- package/dist/cjs/src/bybit.js +27 -47
- package/dist/cjs/src/coinbase.js +176 -26
- package/dist/cjs/src/coincheck.js +1 -0
- package/dist/cjs/src/coinex.js +3 -0
- package/dist/cjs/src/coinlist.js +13 -6
- package/dist/cjs/src/coinone.js +2 -2
- package/dist/cjs/src/coinsph.js +4 -5
- package/dist/cjs/src/delta.js +7 -1
- package/dist/cjs/src/deribit.js +17 -4
- package/dist/cjs/src/gate.js +151 -169
- package/dist/cjs/src/gemini.js +1 -1
- package/dist/cjs/src/hitbtc.js +2 -3
- package/dist/cjs/src/htx.js +157 -7
- package/dist/cjs/src/huobijp.js +2 -3
- package/dist/cjs/src/independentreserve.js +7 -5
- package/dist/cjs/src/kraken.js +86 -54
- package/dist/cjs/src/kucoin.js +5 -0
- package/dist/cjs/src/kucoinfutures.js +131 -77
- package/dist/cjs/src/lbank.js +60 -33
- package/dist/cjs/src/luno.js +84 -2
- package/dist/cjs/src/mexc.js +3 -3
- package/dist/cjs/src/oceanex.js +1 -1
- package/dist/cjs/src/okx.js +23 -11
- package/dist/cjs/{js/src/bitpanda.js → src/onetrading.js} +39 -39
- package/dist/cjs/src/phemex.js +37 -27
- package/dist/cjs/src/poloniexfutures.js +1 -0
- package/dist/cjs/src/pro/binance.js +66 -25
- package/dist/cjs/src/pro/bitget.js +1 -1
- package/dist/cjs/src/pro/bitpanda.js +5 -1330
- package/dist/cjs/src/pro/coinbase.js +4 -1
- package/dist/cjs/src/pro/hitbtc.js +5 -4
- package/dist/cjs/src/pro/htx.js +6 -1
- package/dist/cjs/src/pro/kraken.js +1 -1
- package/dist/cjs/src/pro/krakenfutures.js +7 -1
- package/dist/cjs/src/pro/kucoin.js +46 -36
- package/dist/cjs/src/pro/kucoinfutures.js +45 -37
- package/dist/cjs/src/pro/lbank.js +881 -0
- package/dist/cjs/src/pro/okx.js +52 -2
- package/dist/cjs/{js/src/pro/bitpanda.js → src/pro/onetrading.js} +4 -7
- package/dist/cjs/src/pro/poloniex.js +2 -2
- package/dist/cjs/src/pro/poloniexfutures.js +43 -35
- package/dist/cjs/src/pro/woo.js +126 -0
- package/dist/cjs/src/probit.js +4 -2
- package/dist/cjs/src/upbit.js +12 -12
- package/dist/cjs/src/wavesexchange.js +1 -1
- package/dist/cjs/src/whitebit.js +1 -0
- package/dist/cjs/src/woo.js +56 -0
- package/js/ccxt.d.ts +11 -2
- package/js/ccxt.js +8 -2
- package/js/src/abstract/bitpanda.d.ts +4 -4
- package/js/src/abstract/bitstamp.d.ts +8 -0
- package/js/src/abstract/gate.d.ts +1 -0
- package/js/src/abstract/gateio.d.ts +1 -0
- package/js/src/abstract/htx.d.ts +3 -0
- package/js/src/abstract/huobi.d.ts +3 -0
- package/js/src/abstract/luno.d.ts +1 -0
- package/js/src/abstract/onetrading.d.ts +38 -0
- package/js/src/ascendex.js +2 -0
- package/js/src/bingx.js +1 -1
- package/js/src/bitget.js +22 -3
- package/js/src/bitpanda.d.ts +2 -72
- package/js/src/bitpanda.js +5 -1991
- package/js/src/bitstamp.js +8 -0
- package/js/src/deribit.js +11 -3
- package/js/src/gate.d.ts +1 -0
- package/js/src/gate.js +50 -110
- package/js/src/htx.js +3 -0
- package/js/src/kraken.d.ts +1 -0
- package/js/src/kraken.js +39 -38
- package/js/src/lbank.js +1 -0
- package/js/src/luno.d.ts +3 -1
- package/js/src/luno.js +84 -2
- package/js/src/mexc.js +1 -2
- package/js/src/onetrading.d.ts +74 -0
- package/js/src/onetrading.js +2003 -0
- package/js/src/poloniexfutures.js +1 -0
- package/js/src/pro/binance.js +6 -1
- package/js/src/pro/bitpanda.d.ts +2 -34
- package/js/src/pro/bitpanda.js +5 -1330
- package/js/src/pro/lbank.d.ts +29 -0
- package/js/src/pro/lbank.js +882 -0
- package/js/src/pro/onetrading.d.ts +36 -0
- package/js/src/pro/onetrading.js +1339 -0
- package/package.json +2 -2
- package/rollup.config.js +2 -0
- package/skip-tests.json +2 -1
- package/test-commonjs.cjs +25 -1
- package/dist/cjs/js/ccxt.js +0 -478
- package/dist/cjs/js/src/abstract/alpaca.js +0 -9
- package/dist/cjs/js/src/abstract/ascendex.js +0 -9
- package/dist/cjs/js/src/abstract/bigone.js +0 -9
- package/dist/cjs/js/src/abstract/binance.js +0 -9
- package/dist/cjs/js/src/abstract/bingx.js +0 -9
- package/dist/cjs/js/src/abstract/bit2c.js +0 -9
- package/dist/cjs/js/src/abstract/bitbank.js +0 -9
- package/dist/cjs/js/src/abstract/bitbns.js +0 -9
- package/dist/cjs/js/src/abstract/bitfinex.js +0 -9
- package/dist/cjs/js/src/abstract/bitfinex2.js +0 -9
- package/dist/cjs/js/src/abstract/bitflyer.js +0 -9
- package/dist/cjs/js/src/abstract/bitforex.js +0 -9
- package/dist/cjs/js/src/abstract/bitget.js +0 -9
- package/dist/cjs/js/src/abstract/bithumb.js +0 -9
- package/dist/cjs/js/src/abstract/bitmart.js +0 -9
- package/dist/cjs/js/src/abstract/bitmex.js +0 -9
- package/dist/cjs/js/src/abstract/bitopro.js +0 -9
- package/dist/cjs/js/src/abstract/bitpanda.js +0 -9
- package/dist/cjs/js/src/abstract/bitrue.js +0 -9
- package/dist/cjs/js/src/abstract/bitso.js +0 -9
- package/dist/cjs/js/src/abstract/bitstamp.js +0 -9
- package/dist/cjs/js/src/abstract/bitteam.js +0 -9
- package/dist/cjs/js/src/abstract/bitvavo.js +0 -9
- package/dist/cjs/js/src/abstract/bl3p.js +0 -9
- package/dist/cjs/js/src/abstract/blockchaincom.js +0 -9
- package/dist/cjs/js/src/abstract/btcalpha.js +0 -9
- package/dist/cjs/js/src/abstract/btcbox.js +0 -9
- package/dist/cjs/js/src/abstract/btcmarkets.js +0 -9
- package/dist/cjs/js/src/abstract/btcturk.js +0 -9
- package/dist/cjs/js/src/abstract/bybit.js +0 -9
- package/dist/cjs/js/src/abstract/cex.js +0 -9
- package/dist/cjs/js/src/abstract/coinbase.js +0 -9
- package/dist/cjs/js/src/abstract/coinbasepro.js +0 -9
- package/dist/cjs/js/src/abstract/coincheck.js +0 -9
- package/dist/cjs/js/src/abstract/coinex.js +0 -9
- package/dist/cjs/js/src/abstract/coinlist.js +0 -9
- package/dist/cjs/js/src/abstract/coinmate.js +0 -9
- package/dist/cjs/js/src/abstract/coinone.js +0 -9
- package/dist/cjs/js/src/abstract/coinsph.js +0 -9
- package/dist/cjs/js/src/abstract/coinspot.js +0 -9
- package/dist/cjs/js/src/abstract/cryptocom.js +0 -9
- package/dist/cjs/js/src/abstract/currencycom.js +0 -9
- package/dist/cjs/js/src/abstract/delta.js +0 -9
- package/dist/cjs/js/src/abstract/deribit.js +0 -9
- package/dist/cjs/js/src/abstract/digifinex.js +0 -9
- package/dist/cjs/js/src/abstract/exmo.js +0 -9
- package/dist/cjs/js/src/abstract/gate.js +0 -9
- package/dist/cjs/js/src/abstract/gemini.js +0 -9
- package/dist/cjs/js/src/abstract/hitbtc.js +0 -9
- package/dist/cjs/js/src/abstract/hollaex.js +0 -9
- package/dist/cjs/js/src/abstract/htx.js +0 -9
- package/dist/cjs/js/src/abstract/huobijp.js +0 -9
- package/dist/cjs/js/src/abstract/idex.js +0 -9
- package/dist/cjs/js/src/abstract/independentreserve.js +0 -9
- package/dist/cjs/js/src/abstract/indodax.js +0 -9
- package/dist/cjs/js/src/abstract/kraken.js +0 -9
- package/dist/cjs/js/src/abstract/krakenfutures.js +0 -9
- package/dist/cjs/js/src/abstract/kucoin.js +0 -9
- package/dist/cjs/js/src/abstract/kucoinfutures.js +0 -9
- package/dist/cjs/js/src/abstract/kuna.js +0 -9
- package/dist/cjs/js/src/abstract/latoken.js +0 -9
- package/dist/cjs/js/src/abstract/lbank.js +0 -9
- package/dist/cjs/js/src/abstract/luno.js +0 -9
- package/dist/cjs/js/src/abstract/lykke.js +0 -9
- package/dist/cjs/js/src/abstract/mercado.js +0 -9
- package/dist/cjs/js/src/abstract/mexc.js +0 -9
- package/dist/cjs/js/src/abstract/ndax.js +0 -9
- package/dist/cjs/js/src/abstract/novadax.js +0 -9
- package/dist/cjs/js/src/abstract/oceanex.js +0 -9
- package/dist/cjs/js/src/abstract/okcoin.js +0 -9
- package/dist/cjs/js/src/abstract/okx.js +0 -9
- package/dist/cjs/js/src/abstract/p2b.js +0 -9
- package/dist/cjs/js/src/abstract/paymium.js +0 -9
- package/dist/cjs/js/src/abstract/phemex.js +0 -9
- package/dist/cjs/js/src/abstract/poloniex.js +0 -9
- package/dist/cjs/js/src/abstract/poloniexfutures.js +0 -9
- package/dist/cjs/js/src/abstract/probit.js +0 -9
- package/dist/cjs/js/src/abstract/timex.js +0 -9
- package/dist/cjs/js/src/abstract/tokocrypto.js +0 -9
- package/dist/cjs/js/src/abstract/upbit.js +0 -9
- package/dist/cjs/js/src/abstract/wavesexchange.js +0 -9
- package/dist/cjs/js/src/abstract/wazirx.js +0 -9
- package/dist/cjs/js/src/abstract/whitebit.js +0 -9
- package/dist/cjs/js/src/abstract/woo.js +0 -9
- package/dist/cjs/js/src/abstract/yobit.js +0 -9
- package/dist/cjs/js/src/abstract/zaif.js +0 -9
- package/dist/cjs/js/src/abstract/zonda.js +0 -9
- package/dist/cjs/js/src/ace.js +0 -1058
- package/dist/cjs/js/src/alpaca.js +0 -1125
- package/dist/cjs/js/src/ascendex.js +0 -3365
- package/dist/cjs/js/src/base/Exchange.js +0 -5260
- package/dist/cjs/js/src/base/Precise.js +0 -263
- package/dist/cjs/js/src/base/errors.js +0 -299
- package/dist/cjs/js/src/base/functions/crypto.js +0 -78
- package/dist/cjs/js/src/base/functions/encode.js +0 -44
- package/dist/cjs/js/src/base/functions/generic.js +0 -193
- package/dist/cjs/js/src/base/functions/misc.js +0 -96
- package/dist/cjs/js/src/base/functions/number.js +0 -297
- package/dist/cjs/js/src/base/functions/platform.js +0 -28
- package/dist/cjs/js/src/base/functions/rsa.js +0 -34
- package/dist/cjs/js/src/base/functions/string.js +0 -48
- package/dist/cjs/js/src/base/functions/throttle.js +0 -66
- package/dist/cjs/js/src/base/functions/time.js +0 -187
- package/dist/cjs/js/src/base/functions/totp.js +0 -24
- package/dist/cjs/js/src/base/functions/type.js +0 -162
- package/dist/cjs/js/src/base/functions.js +0 -157
- package/dist/cjs/js/src/base/ws/Cache.js +0 -254
- package/dist/cjs/js/src/base/ws/Client.js +0 -299
- package/dist/cjs/js/src/base/ws/Future.js +0 -34
- package/dist/cjs/js/src/base/ws/OrderBook.js +0 -107
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +0 -281
- package/dist/cjs/js/src/base/ws/WsClient.js +0 -69
- package/dist/cjs/js/src/bequant.js +0 -33
- package/dist/cjs/js/src/bigone.js +0 -2213
- package/dist/cjs/js/src/binance.js +0 -9851
- package/dist/cjs/js/src/binancecoinm.js +0 -45
- package/dist/cjs/js/src/binanceus.js +0 -92
- package/dist/cjs/js/src/binanceusdm.js +0 -58
- package/dist/cjs/js/src/bingx.js +0 -3872
- package/dist/cjs/js/src/bit2c.js +0 -916
- package/dist/cjs/js/src/bitbank.js +0 -1000
- package/dist/cjs/js/src/bitbay.js +0 -17
- package/dist/cjs/js/src/bitbns.js +0 -1220
- package/dist/cjs/js/src/bitcoincom.js +0 -17
- package/dist/cjs/js/src/bitfinex.js +0 -1670
- package/dist/cjs/js/src/bitfinex2.js +0 -2990
- package/dist/cjs/js/src/bitflyer.js +0 -1045
- package/dist/cjs/js/src/bitforex.js +0 -852
- package/dist/cjs/js/src/bitget.js +0 -8295
- package/dist/cjs/js/src/bithumb.js +0 -1090
- package/dist/cjs/js/src/bitmart.js +0 -4454
- package/dist/cjs/js/src/bitmex.js +0 -2881
- package/dist/cjs/js/src/bitopro.js +0 -1724
- package/dist/cjs/js/src/bitrue.js +0 -3253
- package/dist/cjs/js/src/bitso.js +0 -1753
- package/dist/cjs/js/src/bitstamp.js +0 -2188
- package/dist/cjs/js/src/bitteam.js +0 -2309
- package/dist/cjs/js/src/bitvavo.js +0 -1968
- package/dist/cjs/js/src/bl3p.js +0 -447
- package/dist/cjs/js/src/blockchaincom.js +0 -1160
- package/dist/cjs/js/src/btcalpha.js +0 -929
- package/dist/cjs/js/src/btcbox.js +0 -565
- package/dist/cjs/js/src/btcmarkets.js +0 -1237
- package/dist/cjs/js/src/btcturk.js +0 -929
- package/dist/cjs/js/src/bybit.js +0 -7624
- package/dist/cjs/js/src/cex.js +0 -1693
- package/dist/cjs/js/src/coinbase.js +0 -3424
- package/dist/cjs/js/src/coinbasepro.js +0 -1866
- package/dist/cjs/js/src/coincheck.js +0 -844
- package/dist/cjs/js/src/coinex.js +0 -5417
- package/dist/cjs/js/src/coinlist.js +0 -2337
- package/dist/cjs/js/src/coinmate.js +0 -989
- package/dist/cjs/js/src/coinone.js +0 -1185
- package/dist/cjs/js/src/coinsph.js +0 -1933
- package/dist/cjs/js/src/coinspot.js +0 -548
- package/dist/cjs/js/src/cryptocom.js +0 -3007
- package/dist/cjs/js/src/currencycom.js +0 -2015
- package/dist/cjs/js/src/delta.js +0 -3262
- package/dist/cjs/js/src/deribit.js +0 -3310
- package/dist/cjs/js/src/digifinex.js +0 -4307
- package/dist/cjs/js/src/exmo.js +0 -2645
- package/dist/cjs/js/src/fmfwio.js +0 -34
- package/dist/cjs/js/src/gate.js +0 -7077
- package/dist/cjs/js/src/gateio.js +0 -16
- package/dist/cjs/js/src/gemini.js +0 -1801
- package/dist/cjs/js/src/hitbtc.js +0 -3660
- package/dist/cjs/js/src/hitbtc3.js +0 -19
- package/dist/cjs/js/src/hollaex.js +0 -1882
- package/dist/cjs/js/src/htx.js +0 -9174
- package/dist/cjs/js/src/huobi.js +0 -16
- package/dist/cjs/js/src/huobijp.js +0 -1918
- package/dist/cjs/js/src/idex.js +0 -1770
- package/dist/cjs/js/src/independentreserve.js +0 -761
- package/dist/cjs/js/src/indodax.js +0 -1069
- package/dist/cjs/js/src/kraken.js +0 -2891
- package/dist/cjs/js/src/krakenfutures.js +0 -2407
- package/dist/cjs/js/src/kucoin.js +0 -4494
- package/dist/cjs/js/src/kucoinfutures.js +0 -2529
- package/dist/cjs/js/src/kuna.js +0 -1949
- package/dist/cjs/js/src/latoken.js +0 -1729
- package/dist/cjs/js/src/lbank.js +0 -2851
- package/dist/cjs/js/src/luno.js +0 -1044
- package/dist/cjs/js/src/lykke.js +0 -1303
- package/dist/cjs/js/src/mercado.js +0 -897
- package/dist/cjs/js/src/mexc.js +0 -5407
- package/dist/cjs/js/src/ndax.js +0 -2450
- package/dist/cjs/js/src/novadax.js +0 -1556
- package/dist/cjs/js/src/oceanex.js +0 -964
- package/dist/cjs/js/src/okcoin.js +0 -3115
- package/dist/cjs/js/src/okx.js +0 -7331
- package/dist/cjs/js/src/p2b.js +0 -1243
- package/dist/cjs/js/src/paymium.js +0 -597
- package/dist/cjs/js/src/phemex.js +0 -4725
- package/dist/cjs/js/src/poloniex.js +0 -2356
- package/dist/cjs/js/src/poloniexfutures.js +0 -1794
- package/dist/cjs/js/src/pro/alpaca.js +0 -714
- package/dist/cjs/js/src/pro/ascendex.js +0 -957
- package/dist/cjs/js/src/pro/bequant.js +0 -33
- package/dist/cjs/js/src/pro/binance.js +0 -2796
- package/dist/cjs/js/src/pro/binancecoinm.js +0 -23
- package/dist/cjs/js/src/pro/binanceus.js +0 -51
- package/dist/cjs/js/src/pro/binanceusdm.js +0 -32
- package/dist/cjs/js/src/pro/bingx.js +0 -944
- package/dist/cjs/js/src/pro/bitcoincom.js +0 -29
- package/dist/cjs/js/src/pro/bitfinex.js +0 -672
- package/dist/cjs/js/src/pro/bitfinex2.js +0 -1159
- package/dist/cjs/js/src/pro/bitget.js +0 -1733
- package/dist/cjs/js/src/pro/bitmart.js +0 -1486
- package/dist/cjs/js/src/pro/bitmex.js +0 -1576
- package/dist/cjs/js/src/pro/bitopro.js +0 -327
- package/dist/cjs/js/src/pro/bitrue.js +0 -462
- package/dist/cjs/js/src/pro/bitstamp.js +0 -547
- package/dist/cjs/js/src/pro/bitvavo.js +0 -704
- package/dist/cjs/js/src/pro/blockchaincom.js +0 -794
- package/dist/cjs/js/src/pro/bybit.js +0 -1843
- package/dist/cjs/js/src/pro/cex.js +0 -1510
- package/dist/cjs/js/src/pro/coinbase.js +0 -561
- package/dist/cjs/js/src/pro/coinbasepro.js +0 -968
- package/dist/cjs/js/src/pro/coinex.js +0 -1095
- package/dist/cjs/js/src/pro/cryptocom.js +0 -1020
- package/dist/cjs/js/src/pro/currencycom.js +0 -563
- package/dist/cjs/js/src/pro/deribit.js +0 -825
- package/dist/cjs/js/src/pro/exmo.js +0 -658
- package/dist/cjs/js/src/pro/gate.js +0 -1316
- package/dist/cjs/js/src/pro/gateio.js +0 -16
- package/dist/cjs/js/src/pro/gemini.js +0 -649
- package/dist/cjs/js/src/pro/hitbtc.js +0 -1294
- package/dist/cjs/js/src/pro/hollaex.js +0 -597
- package/dist/cjs/js/src/pro/htx.js +0 -2388
- package/dist/cjs/js/src/pro/huobi.js +0 -16
- package/dist/cjs/js/src/pro/huobijp.js +0 -606
- package/dist/cjs/js/src/pro/idex.js +0 -714
- package/dist/cjs/js/src/pro/independentreserve.js +0 -280
- package/dist/cjs/js/src/pro/kraken.js +0 -1364
- package/dist/cjs/js/src/pro/krakenfutures.js +0 -1506
- package/dist/cjs/js/src/pro/kucoin.js +0 -1062
- package/dist/cjs/js/src/pro/kucoinfutures.js +0 -989
- package/dist/cjs/js/src/pro/luno.js +0 -322
- package/dist/cjs/js/src/pro/mexc.js +0 -1170
- package/dist/cjs/js/src/pro/ndax.js +0 -545
- package/dist/cjs/js/src/pro/okcoin.js +0 -760
- package/dist/cjs/js/src/pro/okx.js +0 -1608
- package/dist/cjs/js/src/pro/phemex.js +0 -1511
- package/dist/cjs/js/src/pro/poloniex.js +0 -1253
- package/dist/cjs/js/src/pro/poloniexfutures.js +0 -1022
- package/dist/cjs/js/src/pro/probit.js +0 -586
- package/dist/cjs/js/src/pro/upbit.js +0 -234
- package/dist/cjs/js/src/pro/wazirx.js +0 -776
- package/dist/cjs/js/src/pro/whitebit.js +0 -927
- package/dist/cjs/js/src/pro/woo.js +0 -895
- package/dist/cjs/js/src/probit.js +0 -1867
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +0 -401
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +0 -195
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +0 -308
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +0 -554
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +0 -94
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +0 -70
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +0 -91
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +0 -16
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +0 -1760
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +0 -52
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +0 -81
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +0 -376
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +0 -70
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +0 -1580
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +0 -74
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +0 -24
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +0 -158
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +0 -429
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +0 -176
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +0 -324
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +0 -163
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +0 -245
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +0 -1018
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +0 -383
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +0 -258
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +0 -53
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +0 -120
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +0 -69
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +0 -7
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +0 -83
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +0 -240
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +0 -91
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +0 -130
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +0 -214
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +0 -239
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +0 -93
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +0 -354
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +0 -16
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +0 -20
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +0 -30
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +0 -239
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +0 -372
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +0 -273
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +0 -139
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +0 -14
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +0 -16
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +0 -81
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +0 -292
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +0 -103
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +0 -140
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +0 -175
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +0 -95
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +0 -7
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +0 -383
- package/dist/cjs/js/src/timex.js +0 -1562
- package/dist/cjs/js/src/tokocrypto.js +0 -2542
- package/dist/cjs/js/src/upbit.js +0 -1844
- package/dist/cjs/js/src/wavesexchange.js +0 -2607
- package/dist/cjs/js/src/wazirx.js +0 -953
- package/dist/cjs/js/src/whitebit.js +0 -2310
- package/dist/cjs/js/src/woo.js +0 -2769
- package/dist/cjs/js/src/yobit.js +0 -1314
- package/dist/cjs/js/src/zaif.js +0 -736
- package/dist/cjs/js/src/zonda.js +0 -1883
- package/dist/cjs/src/abstract/bitpanda.js +0 -9
- package/test.ts +0 -0
- /package/dist/cjs/{js/src/abstract/ace.js → src/abstract/onetrading.js} +0 -0
- /package/dist/cjs/{js/src → src}/pro/coincheck.js +0 -0
- /package/dist/cjs/{js/src → src}/pro/coinone.js +0 -0
- /package/js/src/abstract/{bitpanda.js → onetrading.js} +0 -0
|
@@ -1,2388 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var htx$1 = require('../htx.js');
|
|
4
|
-
var errors = require('../base/errors.js');
|
|
5
|
-
var Cache = require('../base/ws/Cache.js');
|
|
6
|
-
var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
|
|
7
|
-
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
class htx extends htx$1 {
|
|
11
|
-
describe() {
|
|
12
|
-
return this.deepExtend(super.describe(), {
|
|
13
|
-
'has': {
|
|
14
|
-
'ws': true,
|
|
15
|
-
'createOrderWs': false,
|
|
16
|
-
'editOrderWs': false,
|
|
17
|
-
'fetchOpenOrdersWs': false,
|
|
18
|
-
'fetchOrderWs': false,
|
|
19
|
-
'cancelOrderWs': false,
|
|
20
|
-
'cancelOrdersWs': false,
|
|
21
|
-
'cancelAllOrdersWs': false,
|
|
22
|
-
'fetchTradesWs': false,
|
|
23
|
-
'fetchBalanceWs': false,
|
|
24
|
-
'watchOrderBook': true,
|
|
25
|
-
'watchOrders': true,
|
|
26
|
-
'watchTickers': false,
|
|
27
|
-
'watchTicker': true,
|
|
28
|
-
'watchTrades': true,
|
|
29
|
-
'watchMyTrades': true,
|
|
30
|
-
'watchBalance': true,
|
|
31
|
-
'watchOHLCV': true,
|
|
32
|
-
},
|
|
33
|
-
'urls': {
|
|
34
|
-
'api': {
|
|
35
|
-
'ws': {
|
|
36
|
-
'api': {
|
|
37
|
-
'spot': {
|
|
38
|
-
'public': 'wss://{hostname}/ws',
|
|
39
|
-
'private': 'wss://{hostname}/ws/v2',
|
|
40
|
-
'feed': 'wss://{hostname}/feed',
|
|
41
|
-
},
|
|
42
|
-
'future': {
|
|
43
|
-
'linear': {
|
|
44
|
-
'public': 'wss://api.hbdm.com/linear-swap-ws',
|
|
45
|
-
'private': 'wss://api.hbdm.com/linear-swap-notification',
|
|
46
|
-
},
|
|
47
|
-
'inverse': {
|
|
48
|
-
'public': 'wss://api.hbdm.com/ws',
|
|
49
|
-
'private': 'wss://api.hbdm.com/notification',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
'swap': {
|
|
53
|
-
'inverse': {
|
|
54
|
-
'public': 'wss://api.hbdm.com/swap-ws',
|
|
55
|
-
'private': 'wss://api.hbdm.com/swap-notification',
|
|
56
|
-
},
|
|
57
|
-
'linear': {
|
|
58
|
-
'public': 'wss://api.hbdm.com/linear-swap-ws',
|
|
59
|
-
'private': 'wss://api.hbdm.com/linear-swap-notification',
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
// these settings work faster for clients hosted on AWS
|
|
64
|
-
'api-aws': {
|
|
65
|
-
'spot': {
|
|
66
|
-
'public': 'wss://api-aws.huobi.pro/ws',
|
|
67
|
-
'private': 'wss://api-aws.huobi.pro/ws/v2',
|
|
68
|
-
'feed': 'wss://{hostname}/feed',
|
|
69
|
-
},
|
|
70
|
-
'future': {
|
|
71
|
-
'linear': {
|
|
72
|
-
'public': 'wss://api.hbdm.vn/linear-swap-ws',
|
|
73
|
-
'private': 'wss://api.hbdm.vn/linear-swap-notification',
|
|
74
|
-
},
|
|
75
|
-
'inverse': {
|
|
76
|
-
'public': 'wss://api.hbdm.vn/ws',
|
|
77
|
-
'private': 'wss://api.hbdm.vn/notification',
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
'swap': {
|
|
81
|
-
'linear': {
|
|
82
|
-
'public': 'wss://api.hbdm.vn/linear-swap-ws',
|
|
83
|
-
'private': 'wss://api.hbdm.vn/linear-swap-notification',
|
|
84
|
-
},
|
|
85
|
-
'inverse': {
|
|
86
|
-
'public': 'wss://api.hbdm.vn/swap-ws',
|
|
87
|
-
'private': 'wss://api.hbdm.vn/swap-notification',
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
'options': {
|
|
95
|
-
'tradesLimit': 1000,
|
|
96
|
-
'OHLCVLimit': 1000,
|
|
97
|
-
'api': 'api',
|
|
98
|
-
'watchOrderBook': {
|
|
99
|
-
'maxRetries': 3,
|
|
100
|
-
},
|
|
101
|
-
'ws': {
|
|
102
|
-
'gunzip': true,
|
|
103
|
-
},
|
|
104
|
-
'watchTicker': {
|
|
105
|
-
'name': 'market.{marketId}.detail', // 'market.{marketId}.bbo' or 'market.{marketId}.ticker'
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
'exceptions': {
|
|
109
|
-
'ws': {
|
|
110
|
-
'exact': {
|
|
111
|
-
'bad-request': errors.BadRequest,
|
|
112
|
-
'2002': errors.AuthenticationError,
|
|
113
|
-
'2021': errors.BadRequest,
|
|
114
|
-
'2001': errors.BadSymbol,
|
|
115
|
-
'2011': errors.BadSymbol,
|
|
116
|
-
'2040': errors.BadRequest,
|
|
117
|
-
'4007': errors.BadRequest, // { op: 'sub', cid: '1', topic: 'accounts_unify.USDT', 'err-code': 4007, 'err-msg': 'Non - single account user is not available, please check through the cross and isolated account asset interface', ts: 1698419318540 }
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
requestId() {
|
|
124
|
-
const requestId = this.sum(this.safeInteger(this.options, 'requestId', 0), 1);
|
|
125
|
-
this.options['requestId'] = requestId;
|
|
126
|
-
return requestId.toString();
|
|
127
|
-
}
|
|
128
|
-
async watchTicker(symbol, params = {}) {
|
|
129
|
-
/**
|
|
130
|
-
* @method
|
|
131
|
-
* @name huobi#watchTicker
|
|
132
|
-
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
133
|
-
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
134
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
135
|
-
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
136
|
-
*/
|
|
137
|
-
await this.loadMarkets();
|
|
138
|
-
const market = this.market(symbol);
|
|
139
|
-
symbol = market['symbol'];
|
|
140
|
-
const options = this.safeValue(this.options, 'watchTicker', {});
|
|
141
|
-
const topic = this.safeString(options, 'name', 'market.{marketId}.detail');
|
|
142
|
-
if (topic === 'market.{marketId}.ticker' && market['type'] !== 'spot') {
|
|
143
|
-
throw new errors.BadRequest(this.id + ' watchTicker() with name market.{marketId}.ticker is only allowed for spot markets, use market.{marketId}.detail instead');
|
|
144
|
-
}
|
|
145
|
-
const messageHash = this.implodeParams(topic, { 'marketId': market['id'] });
|
|
146
|
-
const url = this.getUrlByMarketType(market['type'], market['linear']);
|
|
147
|
-
return await this.subscribePublic(url, symbol, messageHash, undefined, params);
|
|
148
|
-
}
|
|
149
|
-
handleTicker(client, message) {
|
|
150
|
-
//
|
|
151
|
-
// "market.btcusdt.detail"
|
|
152
|
-
// {
|
|
153
|
-
// "ch": "market.btcusdt.detail",
|
|
154
|
-
// "ts": 1583494163784,
|
|
155
|
-
// "tick": {
|
|
156
|
-
// "id": 209988464418,
|
|
157
|
-
// "low": 8988,
|
|
158
|
-
// "high": 9155.41,
|
|
159
|
-
// "open": 9078.91,
|
|
160
|
-
// "close": 9136.46,
|
|
161
|
-
// "vol": 237813910.5928412,
|
|
162
|
-
// "amount": 26184.202558551195,
|
|
163
|
-
// "version": 209988464418,
|
|
164
|
-
// "count": 265673
|
|
165
|
-
// }
|
|
166
|
-
// }
|
|
167
|
-
// "market.btcusdt.bbo"
|
|
168
|
-
// {
|
|
169
|
-
// "ch": "market.btcusdt.bbo",
|
|
170
|
-
// "ts": 1671941599613,
|
|
171
|
-
// "tick": {
|
|
172
|
-
// "seqId": 161499562790,
|
|
173
|
-
// "ask": 16829.51,
|
|
174
|
-
// "askSize": 0.707776,
|
|
175
|
-
// "bid": 16829.5,
|
|
176
|
-
// "bidSize": 1.685945,
|
|
177
|
-
// "quoteTime": 1671941599612,
|
|
178
|
-
// "symbol": "btcusdt"
|
|
179
|
-
// }
|
|
180
|
-
// }
|
|
181
|
-
//
|
|
182
|
-
const tick = this.safeValue(message, 'tick', {});
|
|
183
|
-
const ch = this.safeString(message, 'ch');
|
|
184
|
-
const parts = ch.split('.');
|
|
185
|
-
const marketId = this.safeString(parts, 1);
|
|
186
|
-
const market = this.safeMarket(marketId);
|
|
187
|
-
const ticker = this.parseTicker(tick, market);
|
|
188
|
-
const timestamp = this.safeValue(message, 'ts');
|
|
189
|
-
ticker['timestamp'] = timestamp;
|
|
190
|
-
ticker['datetime'] = this.iso8601(timestamp);
|
|
191
|
-
const symbol = ticker['symbol'];
|
|
192
|
-
this.tickers[symbol] = ticker;
|
|
193
|
-
client.resolve(ticker, ch);
|
|
194
|
-
return message;
|
|
195
|
-
}
|
|
196
|
-
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
197
|
-
/**
|
|
198
|
-
* @method
|
|
199
|
-
* @name huobi#watchTrades
|
|
200
|
-
* @description get the list of most recent trades for a particular symbol
|
|
201
|
-
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
202
|
-
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
203
|
-
* @param {int} [limit] the maximum amount of trades to fetch
|
|
204
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
205
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
206
|
-
*/
|
|
207
|
-
await this.loadMarkets();
|
|
208
|
-
const market = this.market(symbol);
|
|
209
|
-
symbol = market['symbol'];
|
|
210
|
-
const messageHash = 'market.' + market['id'] + '.trade.detail';
|
|
211
|
-
const url = this.getUrlByMarketType(market['type'], market['linear']);
|
|
212
|
-
const trades = await this.subscribePublic(url, symbol, messageHash, undefined, params);
|
|
213
|
-
if (this.newUpdates) {
|
|
214
|
-
limit = trades.getLimit(symbol, limit);
|
|
215
|
-
}
|
|
216
|
-
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
217
|
-
}
|
|
218
|
-
handleTrades(client, message) {
|
|
219
|
-
//
|
|
220
|
-
// {
|
|
221
|
-
// "ch": "market.btcusdt.trade.detail",
|
|
222
|
-
// "ts": 1583495834011,
|
|
223
|
-
// "tick": {
|
|
224
|
-
// "id": 105004645372,
|
|
225
|
-
// "ts": 1583495833751,
|
|
226
|
-
// "data": [
|
|
227
|
-
// {
|
|
228
|
-
// "id": 1.050046453727319e+22,
|
|
229
|
-
// "ts": 1583495833751,
|
|
230
|
-
// "tradeId": 102090727790,
|
|
231
|
-
// "amount": 0.003893,
|
|
232
|
-
// "price": 9150.01,
|
|
233
|
-
// "direction": "sell"
|
|
234
|
-
// }
|
|
235
|
-
// ]
|
|
236
|
-
// }
|
|
237
|
-
// }
|
|
238
|
-
//
|
|
239
|
-
const tick = this.safeValue(message, 'tick', {});
|
|
240
|
-
const data = this.safeValue(tick, 'data', {});
|
|
241
|
-
const ch = this.safeString(message, 'ch');
|
|
242
|
-
const parts = ch.split('.');
|
|
243
|
-
const marketId = this.safeString(parts, 1);
|
|
244
|
-
const market = this.safeMarket(marketId);
|
|
245
|
-
const symbol = market['symbol'];
|
|
246
|
-
let tradesCache = this.safeValue(this.trades, symbol);
|
|
247
|
-
if (tradesCache === undefined) {
|
|
248
|
-
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
249
|
-
tradesCache = new Cache.ArrayCache(limit);
|
|
250
|
-
this.trades[symbol] = tradesCache;
|
|
251
|
-
}
|
|
252
|
-
for (let i = 0; i < data.length; i++) {
|
|
253
|
-
const trade = this.parseTrade(data[i], market);
|
|
254
|
-
tradesCache.append(trade);
|
|
255
|
-
}
|
|
256
|
-
client.resolve(tradesCache, ch);
|
|
257
|
-
return message;
|
|
258
|
-
}
|
|
259
|
-
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
260
|
-
/**
|
|
261
|
-
* @method
|
|
262
|
-
* @name huobi#watchOHLCV
|
|
263
|
-
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
264
|
-
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
265
|
-
* @param {string} timeframe the length of time each candle represents
|
|
266
|
-
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
267
|
-
* @param {int} [limit] the maximum amount of candles to fetch
|
|
268
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
269
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
270
|
-
*/
|
|
271
|
-
await this.loadMarkets();
|
|
272
|
-
const market = this.market(symbol);
|
|
273
|
-
symbol = market['symbol'];
|
|
274
|
-
const interval = this.safeString(this.timeframes, timeframe, timeframe);
|
|
275
|
-
const messageHash = 'market.' + market['id'] + '.kline.' + interval;
|
|
276
|
-
const url = this.getUrlByMarketType(market['type'], market['linear']);
|
|
277
|
-
const ohlcv = await this.subscribePublic(url, symbol, messageHash, undefined, params);
|
|
278
|
-
if (this.newUpdates) {
|
|
279
|
-
limit = ohlcv.getLimit(symbol, limit);
|
|
280
|
-
}
|
|
281
|
-
return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
|
|
282
|
-
}
|
|
283
|
-
handleOHLCV(client, message) {
|
|
284
|
-
//
|
|
285
|
-
// {
|
|
286
|
-
// "ch": "market.btcusdt.kline.1min",
|
|
287
|
-
// "ts": 1583501786794,
|
|
288
|
-
// "tick": {
|
|
289
|
-
// "id": 1583501760,
|
|
290
|
-
// "open": 9094.5,
|
|
291
|
-
// "close": 9094.51,
|
|
292
|
-
// "low": 9094.5,
|
|
293
|
-
// "high": 9094.51,
|
|
294
|
-
// "amount": 0.44639786263800907,
|
|
295
|
-
// "vol": 4059.76919054,
|
|
296
|
-
// "count": 16
|
|
297
|
-
// }
|
|
298
|
-
// }
|
|
299
|
-
//
|
|
300
|
-
const ch = this.safeString(message, 'ch');
|
|
301
|
-
const parts = ch.split('.');
|
|
302
|
-
const marketId = this.safeString(parts, 1);
|
|
303
|
-
const market = this.safeMarket(marketId);
|
|
304
|
-
const symbol = market['symbol'];
|
|
305
|
-
const interval = this.safeString(parts, 3);
|
|
306
|
-
const timeframe = this.findTimeframe(interval);
|
|
307
|
-
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
|
|
308
|
-
let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
|
|
309
|
-
if (stored === undefined) {
|
|
310
|
-
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
311
|
-
stored = new Cache.ArrayCacheByTimestamp(limit);
|
|
312
|
-
this.ohlcvs[symbol][timeframe] = stored;
|
|
313
|
-
}
|
|
314
|
-
const tick = this.safeValue(message, 'tick');
|
|
315
|
-
const parsed = this.parseOHLCV(tick, market);
|
|
316
|
-
stored.append(parsed);
|
|
317
|
-
client.resolve(stored, ch);
|
|
318
|
-
}
|
|
319
|
-
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
320
|
-
/**
|
|
321
|
-
* @method
|
|
322
|
-
* @name huobi#watchOrderBook
|
|
323
|
-
* @see https://huobiapi.github.io/docs/dm/v1/en/#subscribe-market-depth-data
|
|
324
|
-
* @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#subscribe-incremental-market-depth-data
|
|
325
|
-
* @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-subscribe-incremental-market-depth-data
|
|
326
|
-
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
327
|
-
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
328
|
-
* @param {int} [limit] the maximum amount of order book entries to return
|
|
329
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
330
|
-
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
331
|
-
*/
|
|
332
|
-
await this.loadMarkets();
|
|
333
|
-
const market = this.market(symbol);
|
|
334
|
-
symbol = market['symbol'];
|
|
335
|
-
const allowedLimits = [20, 150];
|
|
336
|
-
// 2) 5-level/20-level incremental MBP is a tick by tick feed,
|
|
337
|
-
// which means whenever there is an order book change at that level, it pushes an update;
|
|
338
|
-
// 150-levels/400-level incremental MBP feed is based on the gap
|
|
339
|
-
// between two snapshots at 100ms interval.
|
|
340
|
-
if (limit === undefined) {
|
|
341
|
-
limit = market['spot'] ? 150 : 20;
|
|
342
|
-
}
|
|
343
|
-
if (!this.inArray(limit, allowedLimits)) {
|
|
344
|
-
throw new errors.ExchangeError(this.id + ' watchOrderBook market accepts limits of 20 and 150 only');
|
|
345
|
-
}
|
|
346
|
-
let messageHash = undefined;
|
|
347
|
-
if (market['spot']) {
|
|
348
|
-
messageHash = 'market.' + market['id'] + '.mbp.' + limit.toString();
|
|
349
|
-
}
|
|
350
|
-
else {
|
|
351
|
-
messageHash = 'market.' + market['id'] + '.depth.size_' + limit.toString() + '.high_freq';
|
|
352
|
-
}
|
|
353
|
-
const url = this.getUrlByMarketType(market['type'], market['linear'], false, true);
|
|
354
|
-
let method = this.handleOrderBookSubscription;
|
|
355
|
-
if (!market['spot']) {
|
|
356
|
-
params = this.extend(params);
|
|
357
|
-
params['data_type'] = 'incremental';
|
|
358
|
-
method = undefined;
|
|
359
|
-
}
|
|
360
|
-
const orderbook = await this.subscribePublic(url, symbol, messageHash, method, params);
|
|
361
|
-
return orderbook.limit();
|
|
362
|
-
}
|
|
363
|
-
handleOrderBookSnapshot(client, message, subscription) {
|
|
364
|
-
//
|
|
365
|
-
// {
|
|
366
|
-
// "id": 1583473663565,
|
|
367
|
-
// "rep": "market.btcusdt.mbp.150",
|
|
368
|
-
// "status": "ok",
|
|
369
|
-
// "ts": 1698359289261,
|
|
370
|
-
// "data": {
|
|
371
|
-
// "seqNum": 104999417756,
|
|
372
|
-
// "bids": [
|
|
373
|
-
// [9058.27, 0],
|
|
374
|
-
// [9058.43, 0],
|
|
375
|
-
// [9058.99, 0],
|
|
376
|
-
// ],
|
|
377
|
-
// "asks": [
|
|
378
|
-
// [9084.27, 0.2],
|
|
379
|
-
// [9085.69, 0],
|
|
380
|
-
// [9085.81, 0],
|
|
381
|
-
// ]
|
|
382
|
-
// }
|
|
383
|
-
// }
|
|
384
|
-
//
|
|
385
|
-
const symbol = this.safeString(subscription, 'symbol');
|
|
386
|
-
const messageHash = this.safeString(subscription, 'messageHash');
|
|
387
|
-
const id = this.safeString(message, 'id');
|
|
388
|
-
const lastTimestamp = this.safeInteger(subscription, 'lastTimestamp');
|
|
389
|
-
try {
|
|
390
|
-
const orderbook = this.orderbooks[symbol];
|
|
391
|
-
const data = this.safeValue(message, 'data');
|
|
392
|
-
const messages = orderbook.cache;
|
|
393
|
-
const firstMessage = this.safeValue(messages, 0, {});
|
|
394
|
-
const snapshot = this.parseOrderBook(data, symbol);
|
|
395
|
-
const tick = this.safeValue(firstMessage, 'tick');
|
|
396
|
-
const sequence = this.safeInteger(tick, 'prevSeqNum');
|
|
397
|
-
const nonce = this.safeInteger(data, 'seqNum');
|
|
398
|
-
snapshot['nonce'] = nonce;
|
|
399
|
-
const snapshotTimestamp = this.safeInteger(message, 'ts');
|
|
400
|
-
subscription['lastTimestamp'] = snapshotTimestamp;
|
|
401
|
-
const snapshotLimit = this.safeInteger(subscription, 'limit');
|
|
402
|
-
const snapshotOrderBook = this.orderBook(snapshot, snapshotLimit);
|
|
403
|
-
client.resolve(snapshotOrderBook, id);
|
|
404
|
-
if ((sequence === undefined) || (nonce < sequence)) {
|
|
405
|
-
const maxAttempts = this.handleOption('watchOrderBook', 'maxRetries', 3);
|
|
406
|
-
let numAttempts = this.safeInteger(subscription, 'numAttempts', 0);
|
|
407
|
-
// retry to synchronize if we have not reached maxAttempts yet
|
|
408
|
-
if (numAttempts < maxAttempts) {
|
|
409
|
-
// safety guard
|
|
410
|
-
if (messageHash in client.subscriptions) {
|
|
411
|
-
numAttempts = this.sum(numAttempts, 1);
|
|
412
|
-
const delayTime = this.sum(1000, lastTimestamp - snapshotTimestamp);
|
|
413
|
-
subscription['numAttempts'] = numAttempts;
|
|
414
|
-
client.subscriptions[messageHash] = subscription;
|
|
415
|
-
this.delay(delayTime, this.watchOrderBookSnapshot, client, message, subscription);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
else {
|
|
419
|
-
// throw upon failing to synchronize in maxAttempts
|
|
420
|
-
throw new errors.InvalidNonce(this.id + ' failed to synchronize WebSocket feed with the snapshot for symbol ' + symbol + ' in ' + maxAttempts.toString() + ' attempts');
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
orderbook.reset(snapshot);
|
|
425
|
-
// unroll the accumulated deltas
|
|
426
|
-
for (let i = 0; i < messages.length; i++) {
|
|
427
|
-
this.handleOrderBookMessage(client, messages[i]);
|
|
428
|
-
}
|
|
429
|
-
orderbook.cache = [];
|
|
430
|
-
this.orderbooks[symbol] = orderbook;
|
|
431
|
-
client.resolve(orderbook, messageHash);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
catch (e) {
|
|
435
|
-
client.reject(e, messageHash);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
async watchOrderBookSnapshot(client, message, subscription) {
|
|
439
|
-
const messageHash = this.safeString(subscription, 'messageHash');
|
|
440
|
-
const symbol = this.safeString(subscription, 'symbol');
|
|
441
|
-
const limit = this.safeInteger(subscription, 'limit');
|
|
442
|
-
const timestamp = this.safeInteger(message, 'ts');
|
|
443
|
-
const params = this.safeValue(subscription, 'params');
|
|
444
|
-
const attempts = this.safeInteger(subscription, 'numAttempts', 0);
|
|
445
|
-
const market = this.market(symbol);
|
|
446
|
-
const url = this.getUrlByMarketType(market['type'], market['linear'], false, true);
|
|
447
|
-
const requestId = this.requestId();
|
|
448
|
-
const request = {
|
|
449
|
-
'req': messageHash,
|
|
450
|
-
'id': requestId,
|
|
451
|
-
};
|
|
452
|
-
// this is a temporary subscription by a specific requestId
|
|
453
|
-
// it has a very short lifetime until the snapshot is received over ws
|
|
454
|
-
const snapshotSubscription = {
|
|
455
|
-
'id': requestId,
|
|
456
|
-
'messageHash': messageHash,
|
|
457
|
-
'symbol': symbol,
|
|
458
|
-
'limit': limit,
|
|
459
|
-
'params': params,
|
|
460
|
-
'numAttempts': attempts,
|
|
461
|
-
'lastTimestamp': timestamp,
|
|
462
|
-
'method': this.handleOrderBookSnapshot,
|
|
463
|
-
};
|
|
464
|
-
try {
|
|
465
|
-
const orderbook = await this.watch(url, requestId, request, requestId, snapshotSubscription);
|
|
466
|
-
return orderbook.limit();
|
|
467
|
-
}
|
|
468
|
-
catch (e) {
|
|
469
|
-
delete client.subscriptions[messageHash];
|
|
470
|
-
client.reject(e, messageHash);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
handleDelta(bookside, delta) {
|
|
474
|
-
const price = this.safeFloat(delta, 0);
|
|
475
|
-
const amount = this.safeFloat(delta, 1);
|
|
476
|
-
bookside.store(price, amount);
|
|
477
|
-
}
|
|
478
|
-
handleDeltas(bookside, deltas) {
|
|
479
|
-
for (let i = 0; i < deltas.length; i++) {
|
|
480
|
-
this.handleDelta(bookside, deltas[i]);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
handleOrderBookMessage(client, message) {
|
|
484
|
-
// spot markets
|
|
485
|
-
//
|
|
486
|
-
// {
|
|
487
|
-
// "ch": "market.btcusdt.mbp.150",
|
|
488
|
-
// "ts": 1583472025885,
|
|
489
|
-
// "tick": {
|
|
490
|
-
// "seqNum": 104998984994,
|
|
491
|
-
// "prevSeqNum": 104998984977,
|
|
492
|
-
// "bids": [
|
|
493
|
-
// [9058.27, 0],
|
|
494
|
-
// [9058.43, 0],
|
|
495
|
-
// [9058.99, 0],
|
|
496
|
-
// ],
|
|
497
|
-
// "asks": [
|
|
498
|
-
// [9084.27, 0.2],
|
|
499
|
-
// [9085.69, 0],
|
|
500
|
-
// [9085.81, 0],
|
|
501
|
-
// ]
|
|
502
|
-
// }
|
|
503
|
-
// }
|
|
504
|
-
//
|
|
505
|
-
// non-spot market update
|
|
506
|
-
//
|
|
507
|
-
// {
|
|
508
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
509
|
-
// "tick":{
|
|
510
|
-
// "asks":[],
|
|
511
|
-
// "bids":[
|
|
512
|
-
// [43445.74,1],
|
|
513
|
-
// [43444.48,0 ],
|
|
514
|
-
// [40593.92,9]
|
|
515
|
-
// ],
|
|
516
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
517
|
-
// "event":"update",
|
|
518
|
-
// "id":152727500274,
|
|
519
|
-
// "mrid":152727500274,
|
|
520
|
-
// "ts":1645023376098,
|
|
521
|
-
// "version":37536690
|
|
522
|
-
// },
|
|
523
|
-
// "ts":1645023376098
|
|
524
|
-
// }
|
|
525
|
-
// non-spot market snapshot
|
|
526
|
-
//
|
|
527
|
-
// {
|
|
528
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
529
|
-
// "tick":{
|
|
530
|
-
// "asks":[
|
|
531
|
-
// [43445.74,1],
|
|
532
|
-
// [43444.48,0 ],
|
|
533
|
-
// [40593.92,9]
|
|
534
|
-
// ],
|
|
535
|
-
// "bids":[
|
|
536
|
-
// [43445.74,1],
|
|
537
|
-
// [43444.48,0 ],
|
|
538
|
-
// [40593.92,9]
|
|
539
|
-
// ],
|
|
540
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
541
|
-
// "event":"snapshot",
|
|
542
|
-
// "id":152727500274,
|
|
543
|
-
// "mrid":152727500274,
|
|
544
|
-
// "ts":1645023376098,
|
|
545
|
-
// "version":37536690
|
|
546
|
-
// },
|
|
547
|
-
// "ts":1645023376098
|
|
548
|
-
// }
|
|
549
|
-
//
|
|
550
|
-
const ch = this.safeValue(message, 'ch');
|
|
551
|
-
const parts = ch.split('.');
|
|
552
|
-
const marketId = this.safeString(parts, 1);
|
|
553
|
-
const market = this.safeMarket(marketId);
|
|
554
|
-
const symbol = market['symbol'];
|
|
555
|
-
const orderbook = this.orderbooks[symbol];
|
|
556
|
-
const tick = this.safeValue(message, 'tick', {});
|
|
557
|
-
const seqNum = this.safeInteger(tick, 'seqNum');
|
|
558
|
-
const prevSeqNum = this.safeInteger(tick, 'prevSeqNum');
|
|
559
|
-
const event = this.safeString(tick, 'event');
|
|
560
|
-
const version = this.safeInteger(tick, 'version');
|
|
561
|
-
const timestamp = this.safeInteger(message, 'ts');
|
|
562
|
-
if (event === 'snapshot') {
|
|
563
|
-
const snapshot = this.parseOrderBook(tick, symbol, timestamp);
|
|
564
|
-
orderbook.reset(snapshot);
|
|
565
|
-
orderbook['nonce'] = version;
|
|
566
|
-
}
|
|
567
|
-
if ((prevSeqNum !== undefined) && prevSeqNum > orderbook['nonce']) {
|
|
568
|
-
throw new errors.InvalidNonce(this.id + ' watchOrderBook() received a mesage out of order');
|
|
569
|
-
}
|
|
570
|
-
const spotConditon = market['spot'] && (prevSeqNum === orderbook['nonce']);
|
|
571
|
-
const nonSpotCondition = market['contract'] && (version - 1 === orderbook['nonce']);
|
|
572
|
-
if (spotConditon || nonSpotCondition) {
|
|
573
|
-
const asks = this.safeValue(tick, 'asks', []);
|
|
574
|
-
const bids = this.safeValue(tick, 'bids', []);
|
|
575
|
-
this.handleDeltas(orderbook['asks'], asks);
|
|
576
|
-
this.handleDeltas(orderbook['bids'], bids);
|
|
577
|
-
orderbook['nonce'] = spotConditon ? seqNum : version;
|
|
578
|
-
orderbook['timestamp'] = timestamp;
|
|
579
|
-
orderbook['datetime'] = this.iso8601(timestamp);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
handleOrderBook(client, message) {
|
|
583
|
-
//
|
|
584
|
-
// deltas
|
|
585
|
-
//
|
|
586
|
-
// spot markets
|
|
587
|
-
//
|
|
588
|
-
// {
|
|
589
|
-
// "ch": "market.btcusdt.mbp.150",
|
|
590
|
-
// "ts": 1583472025885,
|
|
591
|
-
// "tick": {
|
|
592
|
-
// "seqNum": 104998984994,
|
|
593
|
-
// "prevSeqNum": 104998984977,
|
|
594
|
-
// "bids": [
|
|
595
|
-
// [9058.27, 0],
|
|
596
|
-
// [9058.43, 0],
|
|
597
|
-
// [9058.99, 0],
|
|
598
|
-
// ],
|
|
599
|
-
// "asks": [
|
|
600
|
-
// [9084.27, 0.2],
|
|
601
|
-
// [9085.69, 0],
|
|
602
|
-
// [9085.81, 0],
|
|
603
|
-
// ]
|
|
604
|
-
// }
|
|
605
|
-
// }
|
|
606
|
-
//
|
|
607
|
-
// non spot markets
|
|
608
|
-
//
|
|
609
|
-
// {
|
|
610
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
611
|
-
// "tick":{
|
|
612
|
-
// "asks":[],
|
|
613
|
-
// "bids":[
|
|
614
|
-
// [43445.74,1],
|
|
615
|
-
// [43444.48,0 ],
|
|
616
|
-
// [40593.92,9]
|
|
617
|
-
// ],
|
|
618
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
619
|
-
// "event":"update",
|
|
620
|
-
// "id":152727500274,
|
|
621
|
-
// "mrid":152727500274,
|
|
622
|
-
// "ts":1645023376098,
|
|
623
|
-
// "version":37536690
|
|
624
|
-
// },
|
|
625
|
-
// "ts":1645023376098
|
|
626
|
-
// }
|
|
627
|
-
//
|
|
628
|
-
const messageHash = this.safeString(message, 'ch');
|
|
629
|
-
const tick = this.safeValue(message, 'tick');
|
|
630
|
-
const event = this.safeString(tick, 'event');
|
|
631
|
-
const ch = this.safeValue(message, 'ch');
|
|
632
|
-
const parts = ch.split('.');
|
|
633
|
-
const marketId = this.safeString(parts, 1);
|
|
634
|
-
const symbol = this.safeSymbol(marketId);
|
|
635
|
-
let orderbook = this.safeValue(this.orderbooks, symbol);
|
|
636
|
-
if (orderbook === undefined) {
|
|
637
|
-
const size = this.safeString(parts, 3);
|
|
638
|
-
const sizeParts = size.split('_');
|
|
639
|
-
const limit = this.safeInteger(sizeParts, 1);
|
|
640
|
-
orderbook = this.orderBook({}, limit);
|
|
641
|
-
this.orderbooks[symbol] = orderbook;
|
|
642
|
-
}
|
|
643
|
-
if ((event === undefined) && (orderbook['nonce'] === undefined)) {
|
|
644
|
-
orderbook.cache.push(message);
|
|
645
|
-
}
|
|
646
|
-
else {
|
|
647
|
-
this.handleOrderBookMessage(client, message);
|
|
648
|
-
client.resolve(orderbook, messageHash);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
handleOrderBookSubscription(client, message, subscription) {
|
|
652
|
-
const symbol = this.safeString(subscription, 'symbol');
|
|
653
|
-
const market = this.market(symbol);
|
|
654
|
-
const limit = this.safeInteger(subscription, 'limit');
|
|
655
|
-
this.orderbooks[symbol] = this.orderBook({}, limit);
|
|
656
|
-
if (market['spot']) {
|
|
657
|
-
this.spawn(this.watchOrderBookSnapshot, client, message, subscription);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
661
|
-
/**
|
|
662
|
-
* @method
|
|
663
|
-
* @name huobi#watchMyTrades
|
|
664
|
-
* @description watches information on multiple trades made by the user
|
|
665
|
-
* @param {string} symbol unified market symbol of the market trades were made in
|
|
666
|
-
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
667
|
-
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
668
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
669
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
670
|
-
*/
|
|
671
|
-
this.checkRequiredCredentials();
|
|
672
|
-
await this.loadMarkets();
|
|
673
|
-
let type = undefined;
|
|
674
|
-
let marketId = '*'; // wildcard
|
|
675
|
-
let market = undefined;
|
|
676
|
-
let messageHash = undefined;
|
|
677
|
-
let channel = undefined;
|
|
678
|
-
let trades = undefined;
|
|
679
|
-
let subType = undefined;
|
|
680
|
-
if (symbol !== undefined) {
|
|
681
|
-
market = this.market(symbol);
|
|
682
|
-
symbol = market['symbol'];
|
|
683
|
-
type = market['type'];
|
|
684
|
-
subType = market['linear'] ? 'linear' : 'inverse';
|
|
685
|
-
marketId = market['lowercaseId'];
|
|
686
|
-
}
|
|
687
|
-
else {
|
|
688
|
-
type = this.safeString(this.options, 'defaultType', 'spot');
|
|
689
|
-
type = this.safeString(params, 'type', type);
|
|
690
|
-
subType = this.safeString2(this.options, 'subType', 'defaultSubType', 'linear');
|
|
691
|
-
subType = this.safeString(params, 'subType', subType);
|
|
692
|
-
params = this.omit(params, ['type', 'subType']);
|
|
693
|
-
}
|
|
694
|
-
if (type === 'spot') {
|
|
695
|
-
let mode = undefined;
|
|
696
|
-
if (mode === undefined) {
|
|
697
|
-
mode = this.safeString2(this.options, 'watchMyTrades', 'mode', '0');
|
|
698
|
-
mode = this.safeString(params, 'mode', mode);
|
|
699
|
-
params = this.omit(params, 'mode');
|
|
700
|
-
}
|
|
701
|
-
messageHash = 'trade.clearing' + '#' + marketId + '#' + mode;
|
|
702
|
-
channel = messageHash;
|
|
703
|
-
}
|
|
704
|
-
else {
|
|
705
|
-
const channelAndMessageHash = this.getOrderChannelAndMessageHash(type, subType, market, params);
|
|
706
|
-
channel = this.safeString(channelAndMessageHash, 0);
|
|
707
|
-
const orderMessageHash = this.safeString(channelAndMessageHash, 1);
|
|
708
|
-
// we will take advantage of the order messageHash because already handles stuff
|
|
709
|
-
// like symbol/margin/subtype/type variations
|
|
710
|
-
messageHash = orderMessageHash + ':' + 'trade';
|
|
711
|
-
}
|
|
712
|
-
trades = await this.subscribePrivate(channel, messageHash, type, subType, params);
|
|
713
|
-
if (this.newUpdates) {
|
|
714
|
-
limit = trades.getLimit(symbol, limit);
|
|
715
|
-
}
|
|
716
|
-
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
|
|
717
|
-
}
|
|
718
|
-
getOrderChannelAndMessageHash(type, subType, market = undefined, params = {}) {
|
|
719
|
-
let messageHash = undefined;
|
|
720
|
-
let channel = undefined;
|
|
721
|
-
let orderType = this.safeString(this.options, 'orderType', 'orders'); // orders or matchOrders
|
|
722
|
-
orderType = this.safeString(params, 'orderType', orderType);
|
|
723
|
-
params = this.omit(params, 'orderType');
|
|
724
|
-
const marketCode = (market !== undefined) ? market['lowercaseId'].toLowerCase() : undefined;
|
|
725
|
-
const baseId = (market !== undefined) ? market['baseId'] : undefined;
|
|
726
|
-
const prefix = orderType;
|
|
727
|
-
messageHash = prefix;
|
|
728
|
-
if (subType === 'linear') {
|
|
729
|
-
// USDT Margined Contracts Example: LTC/USDT:USDT
|
|
730
|
-
const marginMode = this.safeString(params, 'margin', 'cross');
|
|
731
|
-
const marginPrefix = (marginMode === 'cross') ? prefix + '_cross' : prefix;
|
|
732
|
-
messageHash = marginPrefix;
|
|
733
|
-
if (marketCode !== undefined) {
|
|
734
|
-
messageHash += '.' + marketCode;
|
|
735
|
-
channel = messageHash;
|
|
736
|
-
}
|
|
737
|
-
else {
|
|
738
|
-
channel = marginPrefix + '.' + '*';
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
else if (type === 'future') {
|
|
742
|
-
// inverse futures Example: BCH/USD:BCH-220408
|
|
743
|
-
if (baseId !== undefined) {
|
|
744
|
-
channel = prefix + '.' + baseId.toLowerCase();
|
|
745
|
-
messageHash = channel;
|
|
746
|
-
}
|
|
747
|
-
else {
|
|
748
|
-
channel = prefix + '.' + '*';
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
else {
|
|
752
|
-
// inverse swaps: Example: BTC/USD:BTC
|
|
753
|
-
if (marketCode !== undefined) {
|
|
754
|
-
channel = prefix + '.' + marketCode;
|
|
755
|
-
messageHash = channel;
|
|
756
|
-
}
|
|
757
|
-
else {
|
|
758
|
-
channel = prefix + '.' + '*';
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
return [channel, messageHash];
|
|
762
|
-
}
|
|
763
|
-
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
764
|
-
/**
|
|
765
|
-
* @method
|
|
766
|
-
* @name huobi#watchOrders
|
|
767
|
-
* @description watches information on multiple orders made by the user
|
|
768
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
769
|
-
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
770
|
-
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
771
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
772
|
-
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
773
|
-
*/
|
|
774
|
-
await this.loadMarkets();
|
|
775
|
-
let type = undefined;
|
|
776
|
-
let subType = undefined;
|
|
777
|
-
let market = undefined;
|
|
778
|
-
let suffix = '*'; // wildcard
|
|
779
|
-
if (symbol !== undefined) {
|
|
780
|
-
market = this.market(symbol);
|
|
781
|
-
symbol = market['symbol'];
|
|
782
|
-
type = market['type'];
|
|
783
|
-
suffix = market['lowercaseId'];
|
|
784
|
-
subType = market['linear'] ? 'linear' : 'inverse';
|
|
785
|
-
}
|
|
786
|
-
else {
|
|
787
|
-
type = this.safeString(this.options, 'defaultType', 'spot');
|
|
788
|
-
type = this.safeString(params, 'type', type);
|
|
789
|
-
subType = this.safeString2(this.options, 'subType', 'defaultSubType', 'linear');
|
|
790
|
-
subType = this.safeString(params, 'subType', subType);
|
|
791
|
-
params = this.omit(params, ['type', 'subType']);
|
|
792
|
-
}
|
|
793
|
-
let messageHash = undefined;
|
|
794
|
-
let channel = undefined;
|
|
795
|
-
if (type === 'spot') {
|
|
796
|
-
messageHash = 'orders' + '#' + suffix;
|
|
797
|
-
channel = messageHash;
|
|
798
|
-
}
|
|
799
|
-
else {
|
|
800
|
-
const channelAndMessageHash = this.getOrderChannelAndMessageHash(type, subType, market, params);
|
|
801
|
-
channel = this.safeString(channelAndMessageHash, 0);
|
|
802
|
-
messageHash = this.safeString(channelAndMessageHash, 1);
|
|
803
|
-
}
|
|
804
|
-
const orders = await this.subscribePrivate(channel, messageHash, type, subType, params);
|
|
805
|
-
if (this.newUpdates) {
|
|
806
|
-
limit = orders.getLimit(symbol, limit);
|
|
807
|
-
}
|
|
808
|
-
return this.filterBySinceLimit(orders, since, limit, 'timestamp', true);
|
|
809
|
-
}
|
|
810
|
-
handleOrder(client, message) {
|
|
811
|
-
//
|
|
812
|
-
// spot
|
|
813
|
-
//
|
|
814
|
-
// {
|
|
815
|
-
// "action":"push",
|
|
816
|
-
// "ch":"orders#btcusdt", // or "orders#*" for global subscriptions
|
|
817
|
-
// "data": {
|
|
818
|
-
// "orderSource": "spot-web",
|
|
819
|
-
// "orderCreateTime": 1645116048355,
|
|
820
|
-
// "accountId": 44234548,
|
|
821
|
-
// "orderPrice": "100",
|
|
822
|
-
// "orderSize": "0.05",
|
|
823
|
-
// "symbol": "ethusdt",
|
|
824
|
-
// "type": "buy-limit",
|
|
825
|
-
// "orderId": "478861479986886",
|
|
826
|
-
// "eventType": "creation",
|
|
827
|
-
// "clientOrderId": '',
|
|
828
|
-
// "orderStatus": "submitted"
|
|
829
|
-
// }
|
|
830
|
-
// }
|
|
831
|
-
//
|
|
832
|
-
// spot wrapped trade
|
|
833
|
-
//
|
|
834
|
-
// {
|
|
835
|
-
// "action": "push",
|
|
836
|
-
// "ch": "orders#ltcusdt",
|
|
837
|
-
// "data": {
|
|
838
|
-
// "tradePrice": "130.01",
|
|
839
|
-
// "tradeVolume": "0.0385",
|
|
840
|
-
// "tradeTime": 1648714741525,
|
|
841
|
-
// "aggressor": true,
|
|
842
|
-
// "execAmt": "0.0385",
|
|
843
|
-
// "orderSource": "spot-web",
|
|
844
|
-
// "orderSize": "0.0385",
|
|
845
|
-
// "remainAmt": "0",
|
|
846
|
-
// "tradeId": 101541578884,
|
|
847
|
-
// "symbol": "ltcusdt",
|
|
848
|
-
// "type": "sell-market",
|
|
849
|
-
// "eventType": "trade",
|
|
850
|
-
// "clientOrderId": '',
|
|
851
|
-
// "orderStatus": "filled",
|
|
852
|
-
// "orderId": 509835753860328
|
|
853
|
-
// }
|
|
854
|
-
// }
|
|
855
|
-
//
|
|
856
|
-
// non spot order
|
|
857
|
-
//
|
|
858
|
-
// {
|
|
859
|
-
// "contract_type": "swap",
|
|
860
|
-
// "pair": "LTC-USDT",
|
|
861
|
-
// "business_type": "swap",
|
|
862
|
-
// "op": "notify",
|
|
863
|
-
// "topic": "orders_cross.ltc-usdt",
|
|
864
|
-
// "ts": 1650354508696,
|
|
865
|
-
// "symbol": "LTC",
|
|
866
|
-
// "contract_code": "LTC-USDT",
|
|
867
|
-
// "volume": 1,
|
|
868
|
-
// "price": 110.34,
|
|
869
|
-
// "order_price_type": "lightning",
|
|
870
|
-
// "direction": "sell",
|
|
871
|
-
// "offset": "close",
|
|
872
|
-
// "status": 6,
|
|
873
|
-
// "lever_rate": 1,
|
|
874
|
-
// "order_id": "966002354015051776",
|
|
875
|
-
// "order_id_str": "966002354015051776",
|
|
876
|
-
// "client_order_id": null,
|
|
877
|
-
// "order_source": "web",
|
|
878
|
-
// "order_type": 1,
|
|
879
|
-
// "created_at": 1650354508649,
|
|
880
|
-
// "trade_volume": 1,
|
|
881
|
-
// "trade_turnover": 11.072,
|
|
882
|
-
// "fee": -0.005536,
|
|
883
|
-
// "trade_avg_price": 110.72,
|
|
884
|
-
// "margin_frozen": 0,
|
|
885
|
-
// "profit": -0.045,
|
|
886
|
-
// "trade": [
|
|
887
|
-
// {
|
|
888
|
-
// "trade_fee": -0.005536,
|
|
889
|
-
// "fee_asset": "USDT",
|
|
890
|
-
// "real_profit": 0.473,
|
|
891
|
-
// "profit": -0.045,
|
|
892
|
-
// "trade_id": 86678766507,
|
|
893
|
-
// "id": "86678766507-966002354015051776-1",
|
|
894
|
-
// "trade_volume": 1,
|
|
895
|
-
// "trade_price": 110.72,
|
|
896
|
-
// "trade_turnover": 11.072,
|
|
897
|
-
// "created_at": 1650354508656,
|
|
898
|
-
// "role": "taker"
|
|
899
|
-
// }
|
|
900
|
-
// ],
|
|
901
|
-
// "canceled_at": 0,
|
|
902
|
-
// "fee_asset": "USDT",
|
|
903
|
-
// "margin_asset": "USDT",
|
|
904
|
-
// "uid": "359305390",
|
|
905
|
-
// "liquidation_type": "0",
|
|
906
|
-
// "margin_mode": "cross",
|
|
907
|
-
// "margin_account": "USDT",
|
|
908
|
-
// "is_tpsl": 0,
|
|
909
|
-
// "real_profit": 0.473,
|
|
910
|
-
// "trade_partition": "USDT",
|
|
911
|
-
// "reduce_only": 1
|
|
912
|
-
// }
|
|
913
|
-
//
|
|
914
|
-
//
|
|
915
|
-
const messageHash = this.safeString2(message, 'ch', 'topic');
|
|
916
|
-
const data = this.safeValue(message, 'data');
|
|
917
|
-
let marketId = this.safeString(message, 'contract_code');
|
|
918
|
-
if (marketId === undefined) {
|
|
919
|
-
marketId = this.safeString(data, 'symbol');
|
|
920
|
-
}
|
|
921
|
-
const market = this.safeMarket(marketId);
|
|
922
|
-
let parsedOrder = undefined;
|
|
923
|
-
if (data !== undefined) {
|
|
924
|
-
// spot updates
|
|
925
|
-
const eventType = this.safeString(data, 'eventType');
|
|
926
|
-
if (eventType === 'trade') {
|
|
927
|
-
// when a spot order is filled we get an update message
|
|
928
|
-
// with the trade info
|
|
929
|
-
const parsedTrade = this.parseOrderTrade(data, market);
|
|
930
|
-
// inject trade in existing order by faking an order object
|
|
931
|
-
const orderId = this.safeString(parsedTrade, 'order');
|
|
932
|
-
const trades = [parsedTrade];
|
|
933
|
-
const status = this.parseOrderStatus(this.safeString2(data, 'orderStatus', 'status', 'closed'));
|
|
934
|
-
const filled = this.safeString(data, 'execAmt');
|
|
935
|
-
const remaining = this.safeString(data, 'remainAmt');
|
|
936
|
-
const order = {
|
|
937
|
-
'id': orderId,
|
|
938
|
-
'trades': trades,
|
|
939
|
-
'status': status,
|
|
940
|
-
'symbol': market['symbol'],
|
|
941
|
-
'filled': this.parseNumber(filled),
|
|
942
|
-
'remaining': this.parseNumber(remaining),
|
|
943
|
-
};
|
|
944
|
-
parsedOrder = order;
|
|
945
|
-
}
|
|
946
|
-
else {
|
|
947
|
-
parsedOrder = this.parseWsOrder(data, market);
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
else {
|
|
951
|
-
// contract branch
|
|
952
|
-
parsedOrder = this.parseWsOrder(message, market);
|
|
953
|
-
const rawTrades = this.safeValue(message, 'trade', []);
|
|
954
|
-
const tradesLength = rawTrades.length;
|
|
955
|
-
if (tradesLength > 0) {
|
|
956
|
-
const tradesObject = {
|
|
957
|
-
'trades': rawTrades,
|
|
958
|
-
'ch': messageHash,
|
|
959
|
-
'symbol': marketId,
|
|
960
|
-
};
|
|
961
|
-
// inject order params in every trade
|
|
962
|
-
const extendTradeParams = {
|
|
963
|
-
'order': this.safeString(parsedOrder, 'id'),
|
|
964
|
-
'type': this.safeString(parsedOrder, 'type'),
|
|
965
|
-
'side': this.safeString(parsedOrder, 'side'),
|
|
966
|
-
};
|
|
967
|
-
// trades arrive inside an order update
|
|
968
|
-
// we're forwarding them to handleMyTrade
|
|
969
|
-
// so they can be properly resolved
|
|
970
|
-
this.handleMyTrade(client, tradesObject, extendTradeParams);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
if (this.orders === undefined) {
|
|
974
|
-
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
|
|
975
|
-
this.orders = new Cache.ArrayCacheBySymbolById(limit);
|
|
976
|
-
}
|
|
977
|
-
const cachedOrders = this.orders;
|
|
978
|
-
cachedOrders.append(parsedOrder);
|
|
979
|
-
client.resolve(this.orders, messageHash);
|
|
980
|
-
// when we make a global subscription (for contracts only) our message hash can't have a symbol/currency attached
|
|
981
|
-
// so we're removing it here
|
|
982
|
-
let genericMessageHash = messageHash.replace('.' + market['lowercaseId'], '');
|
|
983
|
-
const lowerCaseBaseId = this.safeStringLower(market, 'baseId');
|
|
984
|
-
genericMessageHash = genericMessageHash.replace('.' + lowerCaseBaseId, '');
|
|
985
|
-
client.resolve(this.orders, genericMessageHash);
|
|
986
|
-
}
|
|
987
|
-
parseWsOrder(order, market = undefined) {
|
|
988
|
-
//
|
|
989
|
-
// spot
|
|
990
|
-
//
|
|
991
|
-
// {
|
|
992
|
-
// "orderSource": "spot-web",
|
|
993
|
-
// "orderCreateTime": 1645116048355, // creating only
|
|
994
|
-
// "accountId": 44234548,
|
|
995
|
-
// "orderPrice": "100",
|
|
996
|
-
// "orderSize": "0.05",
|
|
997
|
-
// "orderValue": "3.71676361", // market-buy only
|
|
998
|
-
// "symbol": "ethusdt",
|
|
999
|
-
// "type": "buy-limit",
|
|
1000
|
-
// "orderId": "478861479986886",
|
|
1001
|
-
// "eventType": "creation",
|
|
1002
|
-
// "clientOrderId": '',
|
|
1003
|
-
// "orderStatus": "submitted"
|
|
1004
|
-
// "lastActTime":1645118621810 // except creating
|
|
1005
|
-
// "execAmt":"0"
|
|
1006
|
-
// }
|
|
1007
|
-
//
|
|
1008
|
-
// swap order
|
|
1009
|
-
//
|
|
1010
|
-
// {
|
|
1011
|
-
// "contract_type": "swap",
|
|
1012
|
-
// "pair": "LTC-USDT",
|
|
1013
|
-
// "business_type": "swap",
|
|
1014
|
-
// "op": "notify",
|
|
1015
|
-
// "topic": "orders_cross.ltc-usdt",
|
|
1016
|
-
// "ts": 1648717911384,
|
|
1017
|
-
// "symbol": "LTC",
|
|
1018
|
-
// "contract_code": "LTC-USDT",
|
|
1019
|
-
// "volume": 1,
|
|
1020
|
-
// "price": 129.13,
|
|
1021
|
-
// "order_price_type": "lightning",
|
|
1022
|
-
// "direction": "sell",
|
|
1023
|
-
// "offset": "close",
|
|
1024
|
-
// "status": 6,
|
|
1025
|
-
// "lever_rate": 5,
|
|
1026
|
-
// "order_id": "959137967397068800",
|
|
1027
|
-
// "order_id_str": "959137967397068800",
|
|
1028
|
-
// "client_order_id": null,
|
|
1029
|
-
// "order_source": "web",
|
|
1030
|
-
// "order_type": 1,
|
|
1031
|
-
// "created_at": 1648717911344,
|
|
1032
|
-
// "trade_volume": 1,
|
|
1033
|
-
// "trade_turnover": 12.952,
|
|
1034
|
-
// "fee": -0.006476,
|
|
1035
|
-
// "trade_avg_price": 129.52,
|
|
1036
|
-
// "margin_frozen": 0,
|
|
1037
|
-
// "profit": -0.005,
|
|
1038
|
-
// "trade": [
|
|
1039
|
-
// {
|
|
1040
|
-
// "trade_fee": -0.006476,
|
|
1041
|
-
// "fee_asset": "USDT",
|
|
1042
|
-
// "real_profit": -0.005,
|
|
1043
|
-
// "profit": -0.005,
|
|
1044
|
-
// "trade_id": 83619995370,
|
|
1045
|
-
// "id": "83619995370-959137967397068800-1",
|
|
1046
|
-
// "trade_volume": 1,
|
|
1047
|
-
// "trade_price": 129.52,
|
|
1048
|
-
// "trade_turnover": 12.952,
|
|
1049
|
-
// "created_at": 1648717911352,
|
|
1050
|
-
// "role": "taker"
|
|
1051
|
-
// }
|
|
1052
|
-
// ],
|
|
1053
|
-
// "canceled_at": 0,
|
|
1054
|
-
// "fee_asset": "USDT",
|
|
1055
|
-
// "margin_asset": "USDT",
|
|
1056
|
-
// "uid": "359305390",
|
|
1057
|
-
// "liquidation_type": "0",
|
|
1058
|
-
// "margin_mode": "cross",
|
|
1059
|
-
// "margin_account": "USDT",
|
|
1060
|
-
// "is_tpsl": 0,
|
|
1061
|
-
// "real_profit": -0.005,
|
|
1062
|
-
// "trade_partition": "USDT",
|
|
1063
|
-
// "reduce_only": 1
|
|
1064
|
-
// }
|
|
1065
|
-
//
|
|
1066
|
-
// {
|
|
1067
|
-
// "op":"notify",
|
|
1068
|
-
// "topic":"orders.ada",
|
|
1069
|
-
// "ts":1604388667226,
|
|
1070
|
-
// "symbol":"ADA",
|
|
1071
|
-
// "contract_type":"quarter",
|
|
1072
|
-
// "contract_code":"ADA201225",
|
|
1073
|
-
// "volume":1,
|
|
1074
|
-
// "price":0.0905,
|
|
1075
|
-
// "order_price_type":"post_only",
|
|
1076
|
-
// "direction":"sell",
|
|
1077
|
-
// "offset":"open",
|
|
1078
|
-
// "status":6,
|
|
1079
|
-
// "lever_rate":20,
|
|
1080
|
-
// "order_id":773207641127878656,
|
|
1081
|
-
// "order_id_str":"773207641127878656",
|
|
1082
|
-
// "client_order_id":null,
|
|
1083
|
-
// "order_source":"web",
|
|
1084
|
-
// "order_type":1,
|
|
1085
|
-
// "created_at":1604388667146,
|
|
1086
|
-
// "trade_volume":1,
|
|
1087
|
-
// "trade_turnover":10,
|
|
1088
|
-
// "fee":-0.022099447513812154,
|
|
1089
|
-
// "trade_avg_price":0.0905,
|
|
1090
|
-
// "margin_frozen":0,
|
|
1091
|
-
// "profit":0,
|
|
1092
|
-
// "trade":[],
|
|
1093
|
-
// "canceled_at":0,
|
|
1094
|
-
// "fee_asset":"ADA",
|
|
1095
|
-
// "uid":"123456789",
|
|
1096
|
-
// "liquidation_type":"0",
|
|
1097
|
-
// "is_tpsl": 0,
|
|
1098
|
-
// "real_profit": 0
|
|
1099
|
-
// }
|
|
1100
|
-
//
|
|
1101
|
-
const lastTradeTimestamp = this.safeInteger2(order, 'lastActTime', 'ts');
|
|
1102
|
-
const created = this.safeInteger(order, 'orderCreateTime');
|
|
1103
|
-
const marketId = this.safeString2(order, 'contract_code', 'symbol');
|
|
1104
|
-
market = this.safeMarket(marketId, market);
|
|
1105
|
-
const symbol = this.safeSymbol(marketId, market);
|
|
1106
|
-
const amount = this.safeString2(order, 'orderSize', 'volume');
|
|
1107
|
-
const status = this.parseOrderStatus(this.safeString2(order, 'orderStatus', 'status'));
|
|
1108
|
-
const id = this.safeString2(order, 'orderId', 'order_id');
|
|
1109
|
-
const clientOrderId = this.safeString2(order, 'clientOrderId', 'client_order_id');
|
|
1110
|
-
const price = this.safeString2(order, 'orderPrice', 'price');
|
|
1111
|
-
const filled = this.safeString(order, 'execAmt');
|
|
1112
|
-
const typeSide = this.safeString(order, 'type');
|
|
1113
|
-
const feeCost = this.safeString(order, 'fee');
|
|
1114
|
-
let fee = undefined;
|
|
1115
|
-
if (feeCost !== undefined) {
|
|
1116
|
-
const feeCurrencyId = this.safeString(order, 'fee_asset');
|
|
1117
|
-
fee = {
|
|
1118
|
-
'cost': feeCost,
|
|
1119
|
-
'currency': this.safeCurrencyCode(feeCurrencyId),
|
|
1120
|
-
};
|
|
1121
|
-
}
|
|
1122
|
-
const avgPrice = this.safeString(order, 'trade_avg_price');
|
|
1123
|
-
const rawTrades = this.safeValue(order, 'trade');
|
|
1124
|
-
let typeSideParts = [];
|
|
1125
|
-
if (typeSide !== undefined) {
|
|
1126
|
-
typeSideParts = typeSide.split('-');
|
|
1127
|
-
}
|
|
1128
|
-
let type = this.safeStringLower(typeSideParts, 1);
|
|
1129
|
-
if (type === undefined) {
|
|
1130
|
-
type = this.safeString(order, 'order_price_type');
|
|
1131
|
-
}
|
|
1132
|
-
let side = this.safeStringLower(typeSideParts, 0);
|
|
1133
|
-
if (side === undefined) {
|
|
1134
|
-
side = this.safeString(order, 'direction');
|
|
1135
|
-
}
|
|
1136
|
-
const cost = this.safeString(order, 'orderValue');
|
|
1137
|
-
return this.safeOrder({
|
|
1138
|
-
'info': order,
|
|
1139
|
-
'id': id,
|
|
1140
|
-
'clientOrderId': clientOrderId,
|
|
1141
|
-
'timestamp': created,
|
|
1142
|
-
'datetime': this.iso8601(created),
|
|
1143
|
-
'lastTradeTimestamp': lastTradeTimestamp,
|
|
1144
|
-
'status': status,
|
|
1145
|
-
'symbol': symbol,
|
|
1146
|
-
'type': type,
|
|
1147
|
-
'timeInForce': undefined,
|
|
1148
|
-
'postOnly': undefined,
|
|
1149
|
-
'side': side,
|
|
1150
|
-
'price': price,
|
|
1151
|
-
'amount': amount,
|
|
1152
|
-
'filled': filled,
|
|
1153
|
-
'remaining': undefined,
|
|
1154
|
-
'cost': cost,
|
|
1155
|
-
'fee': fee,
|
|
1156
|
-
'average': avgPrice,
|
|
1157
|
-
'trades': rawTrades,
|
|
1158
|
-
}, market);
|
|
1159
|
-
}
|
|
1160
|
-
parseOrderTrade(trade, market = undefined) {
|
|
1161
|
-
// spot private wrapped trade
|
|
1162
|
-
//
|
|
1163
|
-
// {
|
|
1164
|
-
// "tradePrice": "130.01",
|
|
1165
|
-
// "tradeVolume": "0.0385",
|
|
1166
|
-
// "tradeTime": 1648714741525,
|
|
1167
|
-
// "aggressor": true,
|
|
1168
|
-
// "execAmt": "0.0385",
|
|
1169
|
-
// "orderSource": "spot-web",
|
|
1170
|
-
// "orderSize": "0.0385",
|
|
1171
|
-
// "remainAmt": "0",
|
|
1172
|
-
// "tradeId": 101541578884,
|
|
1173
|
-
// "symbol": "ltcusdt",
|
|
1174
|
-
// "type": "sell-market",
|
|
1175
|
-
// "eventType": "trade",
|
|
1176
|
-
// "clientOrderId": '',
|
|
1177
|
-
// "orderStatus": "filled",
|
|
1178
|
-
// "orderId": 509835753860328
|
|
1179
|
-
// }
|
|
1180
|
-
//
|
|
1181
|
-
market = this.safeMarket(undefined, market);
|
|
1182
|
-
const symbol = market['symbol'];
|
|
1183
|
-
const tradeId = this.safeString(trade, 'tradeId');
|
|
1184
|
-
const price = this.safeString(trade, 'tradePrice');
|
|
1185
|
-
const amount = this.safeString(trade, 'tradeVolume');
|
|
1186
|
-
const order = this.safeString(trade, 'orderId');
|
|
1187
|
-
const timestamp = this.safeInteger(trade, 'tradeTime');
|
|
1188
|
-
let type = this.safeString(trade, 'type');
|
|
1189
|
-
let side = undefined;
|
|
1190
|
-
if (type !== undefined) {
|
|
1191
|
-
const typeParts = type.split('-');
|
|
1192
|
-
side = typeParts[0];
|
|
1193
|
-
type = typeParts[1];
|
|
1194
|
-
}
|
|
1195
|
-
const aggressor = this.safeValue(trade, 'aggressor');
|
|
1196
|
-
let takerOrMaker = undefined;
|
|
1197
|
-
if (aggressor !== undefined) {
|
|
1198
|
-
takerOrMaker = aggressor ? 'taker' : 'maker';
|
|
1199
|
-
}
|
|
1200
|
-
return this.safeTrade({
|
|
1201
|
-
'info': trade,
|
|
1202
|
-
'timestamp': timestamp,
|
|
1203
|
-
'datetime': this.iso8601(timestamp),
|
|
1204
|
-
'symbol': symbol,
|
|
1205
|
-
'id': tradeId,
|
|
1206
|
-
'order': order,
|
|
1207
|
-
'type': type,
|
|
1208
|
-
'takerOrMaker': takerOrMaker,
|
|
1209
|
-
'side': side,
|
|
1210
|
-
'price': price,
|
|
1211
|
-
'amount': amount,
|
|
1212
|
-
'cost': undefined,
|
|
1213
|
-
'fee': undefined,
|
|
1214
|
-
}, market);
|
|
1215
|
-
}
|
|
1216
|
-
async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1217
|
-
/**
|
|
1218
|
-
* @method
|
|
1219
|
-
* @name huobi#watchPositions
|
|
1220
|
-
* @see https://www.huobi.com/en-in/opend/newApiPages/?id=8cb7de1c-77b5-11ed-9966-0242ac110003
|
|
1221
|
-
* @see https://www.huobi.com/en-in/opend/newApiPages/?id=8cb7df0f-77b5-11ed-9966-0242ac110003
|
|
1222
|
-
* @see https://www.huobi.com/en-in/opend/newApiPages/?id=28c34a7d-77ae-11ed-9966-0242ac110003
|
|
1223
|
-
* @see https://www.huobi.com/en-in/opend/newApiPages/?id=5d5156b5-77b6-11ed-9966-0242ac110003
|
|
1224
|
-
* @description watch all open positions. Note: huobi has one channel for each marginMode and type
|
|
1225
|
-
* @param {string[]|undefined} symbols list of unified market symbols
|
|
1226
|
-
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
1227
|
-
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
1228
|
-
*/
|
|
1229
|
-
await this.loadMarkets();
|
|
1230
|
-
let market = undefined;
|
|
1231
|
-
let messageHash = '';
|
|
1232
|
-
if (!this.isEmpty(symbols)) {
|
|
1233
|
-
market = this.getMarketFromSymbols(symbols);
|
|
1234
|
-
messageHash = '::' + symbols.join(',');
|
|
1235
|
-
}
|
|
1236
|
-
let type = undefined;
|
|
1237
|
-
let subType = undefined;
|
|
1238
|
-
if (market !== undefined) {
|
|
1239
|
-
type = market['type'];
|
|
1240
|
-
subType = market['linear'] ? 'linear' : 'inverse';
|
|
1241
|
-
}
|
|
1242
|
-
else {
|
|
1243
|
-
[type, params] = this.handleMarketTypeAndParams('watchPositions', market, params);
|
|
1244
|
-
if (type === 'spot') {
|
|
1245
|
-
type = 'future';
|
|
1246
|
-
}
|
|
1247
|
-
[subType, params] = this.handleOptionAndParams(params, 'watchPositions', 'subType', subType);
|
|
1248
|
-
}
|
|
1249
|
-
symbols = this.marketSymbols(symbols);
|
|
1250
|
-
let marginMode = undefined;
|
|
1251
|
-
[marginMode, params] = this.handleMarginModeAndParams('watchPositions', params, 'cross');
|
|
1252
|
-
const isLinear = (subType === 'linear');
|
|
1253
|
-
const url = this.getUrlByMarketType(type, isLinear, true);
|
|
1254
|
-
messageHash = marginMode + ':positions' + messageHash;
|
|
1255
|
-
const channel = (marginMode === 'cross') ? 'positions_cross.*' : 'positions.*';
|
|
1256
|
-
const newPositions = await this.subscribePrivate(channel, messageHash, type, subType, params);
|
|
1257
|
-
if (this.newUpdates) {
|
|
1258
|
-
return newPositions;
|
|
1259
|
-
}
|
|
1260
|
-
return this.filterBySymbolsSinceLimit(this.positions[url][marginMode], symbols, since, limit, false);
|
|
1261
|
-
}
|
|
1262
|
-
handlePositions(client, message) {
|
|
1263
|
-
//
|
|
1264
|
-
// {
|
|
1265
|
-
// op: 'notify',
|
|
1266
|
-
// topic: 'positions_cross',
|
|
1267
|
-
// ts: 1696767149650,
|
|
1268
|
-
// event: 'snapshot',
|
|
1269
|
-
// data: [
|
|
1270
|
-
// {
|
|
1271
|
-
// contract_type: 'swap',
|
|
1272
|
-
// pair: 'BTC-USDT',
|
|
1273
|
-
// business_type: 'swap',
|
|
1274
|
-
// liquidation_price: null,
|
|
1275
|
-
// symbol: 'BTC',
|
|
1276
|
-
// contract_code: 'BTC-USDT',
|
|
1277
|
-
// volume: 1,
|
|
1278
|
-
// available: 1,
|
|
1279
|
-
// frozen: 0,
|
|
1280
|
-
// cost_open: 27802.2,
|
|
1281
|
-
// cost_hold: 27802.2,
|
|
1282
|
-
// profit_unreal: 0.0175,
|
|
1283
|
-
// profit_rate: 0.000629446590557581,
|
|
1284
|
-
// profit: 0.0175,
|
|
1285
|
-
// margin_asset: 'USDT',
|
|
1286
|
-
// position_margin: 27.8197,
|
|
1287
|
-
// lever_rate: 1,
|
|
1288
|
-
// direction: 'buy',
|
|
1289
|
-
// last_price: 27819.7,
|
|
1290
|
-
// margin_mode: 'cross',
|
|
1291
|
-
// margin_account: 'USDT',
|
|
1292
|
-
// trade_partition: 'USDT',
|
|
1293
|
-
// position_mode: 'dual_side'
|
|
1294
|
-
// },
|
|
1295
|
-
// ]
|
|
1296
|
-
// }
|
|
1297
|
-
//
|
|
1298
|
-
const url = client.url;
|
|
1299
|
-
const topic = this.safeString(message, 'topic', '');
|
|
1300
|
-
const marginMode = (topic === 'positions_cross') ? 'cross' : 'isolated';
|
|
1301
|
-
if (this.positions === undefined) {
|
|
1302
|
-
this.positions = {};
|
|
1303
|
-
}
|
|
1304
|
-
const clientPositions = this.safeValue(this.positions, url);
|
|
1305
|
-
if (clientPositions === undefined) {
|
|
1306
|
-
this.positions[url] = {};
|
|
1307
|
-
}
|
|
1308
|
-
const clientMarginModePositions = this.safeValue(clientPositions, marginMode);
|
|
1309
|
-
if (clientMarginModePositions === undefined) {
|
|
1310
|
-
this.positions[url][marginMode] = new Cache.ArrayCacheBySymbolBySide();
|
|
1311
|
-
}
|
|
1312
|
-
const cache = this.positions[url][marginMode];
|
|
1313
|
-
const rawPositions = this.safeValue(message, 'data', []);
|
|
1314
|
-
const newPositions = [];
|
|
1315
|
-
const timestamp = this.safeInteger(message, 'ts');
|
|
1316
|
-
for (let i = 0; i < rawPositions.length; i++) {
|
|
1317
|
-
const rawPosition = rawPositions[i];
|
|
1318
|
-
const position = this.parsePosition(rawPosition);
|
|
1319
|
-
position['timestamp'] = timestamp;
|
|
1320
|
-
position['datetime'] = this.iso8601(timestamp);
|
|
1321
|
-
newPositions.push(position);
|
|
1322
|
-
cache.append(position);
|
|
1323
|
-
}
|
|
1324
|
-
const messageHashes = this.findMessageHashes(client, marginMode + ':positions::');
|
|
1325
|
-
for (let i = 0; i < messageHashes.length; i++) {
|
|
1326
|
-
const messageHash = messageHashes[i];
|
|
1327
|
-
const parts = messageHash.split('::');
|
|
1328
|
-
const symbolsString = parts[1];
|
|
1329
|
-
const symbols = symbolsString.split(',');
|
|
1330
|
-
const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
|
|
1331
|
-
if (!this.isEmpty(positions)) {
|
|
1332
|
-
client.resolve(positions, messageHash);
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
|
-
client.resolve(newPositions, marginMode + ':positions');
|
|
1336
|
-
}
|
|
1337
|
-
async watchBalance(params = {}) {
|
|
1338
|
-
/**
|
|
1339
|
-
* @method
|
|
1340
|
-
* @name huobi#watchBalance
|
|
1341
|
-
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1342
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1343
|
-
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1344
|
-
*/
|
|
1345
|
-
let type = undefined;
|
|
1346
|
-
[type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
|
|
1347
|
-
let subType = undefined;
|
|
1348
|
-
[subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params, 'linear');
|
|
1349
|
-
const isUnifiedAccount = this.safeValue2(params, 'isUnifiedAccount', 'unified', false);
|
|
1350
|
-
params = this.omit(params, ['isUnifiedAccount', 'unified']);
|
|
1351
|
-
await this.loadMarkets();
|
|
1352
|
-
let messageHash = undefined;
|
|
1353
|
-
let channel = undefined;
|
|
1354
|
-
let marginMode = undefined;
|
|
1355
|
-
if (type === 'spot') {
|
|
1356
|
-
let mode = this.safeString2(this.options, 'watchBalance', 'mode', '2');
|
|
1357
|
-
mode = this.safeString(params, 'mode', mode);
|
|
1358
|
-
messageHash = 'accounts.update' + '#' + mode;
|
|
1359
|
-
channel = messageHash;
|
|
1360
|
-
}
|
|
1361
|
-
else {
|
|
1362
|
-
const symbol = this.safeString(params, 'symbol');
|
|
1363
|
-
const currency = this.safeString(params, 'currency');
|
|
1364
|
-
const market = (symbol !== undefined) ? this.market(symbol) : undefined;
|
|
1365
|
-
const currencyCode = (currency !== undefined) ? this.currency(currency) : undefined;
|
|
1366
|
-
marginMode = this.safeString(params, 'margin', 'cross');
|
|
1367
|
-
params = this.omit(params, ['currency', 'symbol', 'margin']);
|
|
1368
|
-
let prefix = 'accounts';
|
|
1369
|
-
messageHash = prefix;
|
|
1370
|
-
if (subType === 'linear') {
|
|
1371
|
-
if (isUnifiedAccount) {
|
|
1372
|
-
// usdt contracts account
|
|
1373
|
-
prefix = 'accounts_unify';
|
|
1374
|
-
messageHash = prefix;
|
|
1375
|
-
channel = prefix + '.' + 'usdt';
|
|
1376
|
-
}
|
|
1377
|
-
else {
|
|
1378
|
-
// usdt contracts account
|
|
1379
|
-
prefix = (marginMode === 'cross') ? prefix + '_cross' : prefix;
|
|
1380
|
-
messageHash = prefix;
|
|
1381
|
-
if (marginMode === 'isolated') {
|
|
1382
|
-
// isolated margin only allows filtering by symbol3
|
|
1383
|
-
if (symbol !== undefined) {
|
|
1384
|
-
messageHash += '.' + market['id'];
|
|
1385
|
-
channel = messageHash;
|
|
1386
|
-
}
|
|
1387
|
-
else {
|
|
1388
|
-
// subscribe to all
|
|
1389
|
-
channel = prefix + '.' + '*';
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
else {
|
|
1393
|
-
// cross margin
|
|
1394
|
-
if (currencyCode !== undefined) {
|
|
1395
|
-
channel = prefix + '.' + currencyCode['id'];
|
|
1396
|
-
messageHash = channel;
|
|
1397
|
-
}
|
|
1398
|
-
else {
|
|
1399
|
-
// subscribe to all
|
|
1400
|
-
channel = prefix + '.' + '*';
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
else if (type === 'future') {
|
|
1406
|
-
// inverse futures account
|
|
1407
|
-
if (currencyCode !== undefined) {
|
|
1408
|
-
messageHash += '.' + currencyCode['id'];
|
|
1409
|
-
channel = messageHash;
|
|
1410
|
-
}
|
|
1411
|
-
else {
|
|
1412
|
-
// subscribe to all
|
|
1413
|
-
channel = prefix + '.' + '*';
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
else {
|
|
1417
|
-
// inverse swaps account
|
|
1418
|
-
if (market !== undefined) {
|
|
1419
|
-
messageHash += '.' + market['id'];
|
|
1420
|
-
channel = messageHash;
|
|
1421
|
-
}
|
|
1422
|
-
else {
|
|
1423
|
-
// subscribe to all
|
|
1424
|
-
channel = prefix + '.' + '*';
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
const subscriptionParams = {
|
|
1429
|
-
'type': type,
|
|
1430
|
-
'subType': subType,
|
|
1431
|
-
'margin': marginMode,
|
|
1432
|
-
};
|
|
1433
|
-
// we are differentiating the channel from the messageHash for global subscriptions (*)
|
|
1434
|
-
// because huobi returns a different topic than the topic sent. Example: we send
|
|
1435
|
-
// "accounts.*" and "accounts" is returned so we're setting channel = "accounts.*" and
|
|
1436
|
-
// messageHash = "accounts" allowing handleBalance to freely resolve the topic in the message
|
|
1437
|
-
return await this.subscribePrivate(channel, messageHash, type, subType, params, subscriptionParams);
|
|
1438
|
-
}
|
|
1439
|
-
handleBalance(client, message) {
|
|
1440
|
-
// spot
|
|
1441
|
-
//
|
|
1442
|
-
// {
|
|
1443
|
-
// "action": "push",
|
|
1444
|
-
// "ch": "accounts.update#0",
|
|
1445
|
-
// "data": {
|
|
1446
|
-
// "currency": "btc",
|
|
1447
|
-
// "accountId": 123456,
|
|
1448
|
-
// "balance": "23.111",
|
|
1449
|
-
// "available": "2028.699426619837209087",
|
|
1450
|
-
// "changeType": "transfer",
|
|
1451
|
-
// "accountType":"trade",
|
|
1452
|
-
// "seqNum": "86872993928",
|
|
1453
|
-
// "changeTime": 1568601800000
|
|
1454
|
-
// }
|
|
1455
|
-
// }
|
|
1456
|
-
//
|
|
1457
|
-
// inverse future
|
|
1458
|
-
//
|
|
1459
|
-
// {
|
|
1460
|
-
// "op":"notify",
|
|
1461
|
-
// "topic":"accounts.ada",
|
|
1462
|
-
// "ts":1604388667226,
|
|
1463
|
-
// "event":"order.match",
|
|
1464
|
-
// "data":[
|
|
1465
|
-
// {
|
|
1466
|
-
// "symbol":"ADA",
|
|
1467
|
-
// "margin_balance":446.417641681222726716,
|
|
1468
|
-
// "margin_static":445.554085945257745136,
|
|
1469
|
-
// "margin_position":11.049723756906077348,
|
|
1470
|
-
// "margin_frozen":0,
|
|
1471
|
-
// "margin_available":435.367917924316649368,
|
|
1472
|
-
// "profit_real":21.627049781983019459,
|
|
1473
|
-
// "profit_unreal":0.86355573596498158,
|
|
1474
|
-
// "risk_rate":40.000796572150656768,
|
|
1475
|
-
// "liquidation_price":0.018674308027108984,
|
|
1476
|
-
// "withdraw_available":423.927036163274725677,
|
|
1477
|
-
// "lever_rate":20,
|
|
1478
|
-
// "adjust_factor":0.4
|
|
1479
|
-
// }
|
|
1480
|
-
// ],
|
|
1481
|
-
// "uid":"123456789"
|
|
1482
|
-
// }
|
|
1483
|
-
//
|
|
1484
|
-
// usdt / linear future, swap
|
|
1485
|
-
//
|
|
1486
|
-
// {
|
|
1487
|
-
// "op":"notify",
|
|
1488
|
-
// "topic":"accounts.btc-usdt", // or "accounts" for global subscriptions
|
|
1489
|
-
// "ts":1603711370689,
|
|
1490
|
-
// "event":"order.open",
|
|
1491
|
-
// "data":[
|
|
1492
|
-
// {
|
|
1493
|
-
// "margin_mode":"cross",
|
|
1494
|
-
// "margin_account":"USDT",
|
|
1495
|
-
// "margin_asset":"USDT",
|
|
1496
|
-
// "margin_balance":30.959342395,
|
|
1497
|
-
// "margin_static":30.959342395,
|
|
1498
|
-
// "margin_position":0,
|
|
1499
|
-
// "margin_frozen":10,
|
|
1500
|
-
// "profit_real":0,
|
|
1501
|
-
// "profit_unreal":0,
|
|
1502
|
-
// "withdraw_available":20.959342395,
|
|
1503
|
-
// "risk_rate":153.796711975,
|
|
1504
|
-
// "position_mode":"dual_side",
|
|
1505
|
-
// "contract_detail":[
|
|
1506
|
-
// {
|
|
1507
|
-
// "symbol":"LTC",
|
|
1508
|
-
// "contract_code":"LTC-USDT",
|
|
1509
|
-
// "margin_position":0,
|
|
1510
|
-
// "margin_frozen":0,
|
|
1511
|
-
// "margin_available":20.959342395,
|
|
1512
|
-
// "profit_unreal":0,
|
|
1513
|
-
// "liquidation_price":null,
|
|
1514
|
-
// "lever_rate":1,
|
|
1515
|
-
// "adjust_factor":0.01,
|
|
1516
|
-
// "contract_type":"swap",
|
|
1517
|
-
// "pair":"LTC-USDT",
|
|
1518
|
-
// "business_type":"swap",
|
|
1519
|
-
// "trade_partition":"USDT"
|
|
1520
|
-
// },
|
|
1521
|
-
// ],
|
|
1522
|
-
// "futures_contract_detail":[],
|
|
1523
|
-
// }
|
|
1524
|
-
// ]
|
|
1525
|
-
// }
|
|
1526
|
-
//
|
|
1527
|
-
// inverse future
|
|
1528
|
-
//
|
|
1529
|
-
// {
|
|
1530
|
-
// "op":"notify",
|
|
1531
|
-
// "topic":"accounts.ada",
|
|
1532
|
-
// "ts":1604388667226,
|
|
1533
|
-
// "event":"order.match",
|
|
1534
|
-
// "data":[
|
|
1535
|
-
// {
|
|
1536
|
-
// "symbol":"ADA",
|
|
1537
|
-
// "margin_balance":446.417641681222726716,
|
|
1538
|
-
// "margin_static":445.554085945257745136,
|
|
1539
|
-
// "margin_position":11.049723756906077348,
|
|
1540
|
-
// "margin_frozen":0,
|
|
1541
|
-
// "margin_available":435.367917924316649368,
|
|
1542
|
-
// "profit_real":21.627049781983019459,
|
|
1543
|
-
// "profit_unreal":0.86355573596498158,
|
|
1544
|
-
// "risk_rate":40.000796572150656768,
|
|
1545
|
-
// "liquidation_price":0.018674308027108984,
|
|
1546
|
-
// "withdraw_available":423.927036163274725677,
|
|
1547
|
-
// "lever_rate":20,
|
|
1548
|
-
// "adjust_factor":0.4
|
|
1549
|
-
// }
|
|
1550
|
-
// ],
|
|
1551
|
-
// "uid":"123456789"
|
|
1552
|
-
// }
|
|
1553
|
-
//
|
|
1554
|
-
const channel = this.safeString(message, 'ch');
|
|
1555
|
-
const data = this.safeValue(message, 'data', []);
|
|
1556
|
-
const timestamp = this.safeInteger(data, 'changeTime', this.safeInteger(message, 'ts'));
|
|
1557
|
-
this.balance['timestamp'] = timestamp;
|
|
1558
|
-
this.balance['datetime'] = this.iso8601(timestamp);
|
|
1559
|
-
this.balance['info'] = data;
|
|
1560
|
-
if (channel !== undefined) {
|
|
1561
|
-
// spot balance
|
|
1562
|
-
const currencyId = this.safeString(data, 'currency');
|
|
1563
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1564
|
-
const account = this.account();
|
|
1565
|
-
account['free'] = this.safeString(data, 'available');
|
|
1566
|
-
account['total'] = this.safeString(data, 'balance');
|
|
1567
|
-
this.balance[code] = account;
|
|
1568
|
-
this.balance = this.safeBalance(this.balance);
|
|
1569
|
-
client.resolve(this.balance, channel);
|
|
1570
|
-
}
|
|
1571
|
-
else {
|
|
1572
|
-
// contract balance
|
|
1573
|
-
const dataLength = data.length;
|
|
1574
|
-
if (dataLength === 0) {
|
|
1575
|
-
return;
|
|
1576
|
-
}
|
|
1577
|
-
const first = this.safeValue(data, 0, {});
|
|
1578
|
-
const topic = this.safeString(message, 'topic');
|
|
1579
|
-
const splitTopic = topic.split('.');
|
|
1580
|
-
let messageHash = this.safeString(splitTopic, 0);
|
|
1581
|
-
let subscription = this.safeValue2(client.subscriptions, messageHash, messageHash + '.*');
|
|
1582
|
-
if (subscription === undefined) {
|
|
1583
|
-
// if subscription not found means that we subscribed to a specific currency/symbol
|
|
1584
|
-
// and we use the first data entry to find it
|
|
1585
|
-
// Example: topic = 'accounts'
|
|
1586
|
-
// client.subscription hash = 'accounts.usdt'
|
|
1587
|
-
// we do 'accounts' + '.' + data[0]]['margin_asset'] to get it
|
|
1588
|
-
const currencyId = this.safeString2(first, 'margin_asset', 'symbol');
|
|
1589
|
-
messageHash += '.' + currencyId.toLowerCase();
|
|
1590
|
-
subscription = this.safeValue(client.subscriptions, messageHash);
|
|
1591
|
-
}
|
|
1592
|
-
const type = this.safeString(subscription, 'type');
|
|
1593
|
-
const subType = this.safeString(subscription, 'subType');
|
|
1594
|
-
if (topic === 'accounts_unify') {
|
|
1595
|
-
// {
|
|
1596
|
-
// "margin_asset": "USDT",
|
|
1597
|
-
// "margin_static": 10,
|
|
1598
|
-
// "cross_margin_static": 10,
|
|
1599
|
-
// "margin_balance": 10,
|
|
1600
|
-
// "cross_profit_unreal": 0,
|
|
1601
|
-
// "margin_frozen": 0,
|
|
1602
|
-
// "withdraw_available": 10,
|
|
1603
|
-
// "cross_risk_rate": null,
|
|
1604
|
-
// "cross_swap": [],
|
|
1605
|
-
// "cross_future": [],
|
|
1606
|
-
// "isolated_swap": []
|
|
1607
|
-
// }
|
|
1608
|
-
const marginAsset = this.safeString(first, 'margin_asset');
|
|
1609
|
-
const code = this.safeCurrencyCode(marginAsset);
|
|
1610
|
-
const marginFrozen = this.safeString(first, 'margin_frozen');
|
|
1611
|
-
const unifiedAccount = this.account();
|
|
1612
|
-
unifiedAccount['free'] = this.safeString(first, 'withdraw_available');
|
|
1613
|
-
unifiedAccount['used'] = marginFrozen;
|
|
1614
|
-
this.balance[code] = unifiedAccount;
|
|
1615
|
-
this.balance = this.safeBalance(this.balance);
|
|
1616
|
-
client.resolve(this.balance, 'accounts_unify');
|
|
1617
|
-
}
|
|
1618
|
-
else if (subType === 'linear') {
|
|
1619
|
-
const margin = this.safeString(subscription, 'margin');
|
|
1620
|
-
if (margin === 'cross') {
|
|
1621
|
-
const fieldName = (type === 'future') ? 'futures_contract_detail' : 'contract_detail';
|
|
1622
|
-
const balances = this.safeValue(first, fieldName, []);
|
|
1623
|
-
const balancesLength = balances.length;
|
|
1624
|
-
if (balancesLength > 0) {
|
|
1625
|
-
for (let i = 0; i < balances.length; i++) {
|
|
1626
|
-
const balance = balances[i];
|
|
1627
|
-
const marketId = this.safeString2(balance, 'contract_code', 'margin_account');
|
|
1628
|
-
const market = this.safeMarket(marketId);
|
|
1629
|
-
const currencyId = this.safeString(balance, 'margin_asset');
|
|
1630
|
-
const currency = this.safeCurrency(currencyId);
|
|
1631
|
-
const code = this.safeString(market, 'settle', currency['code']);
|
|
1632
|
-
// the exchange outputs positions for delisted markets
|
|
1633
|
-
// https://www.huobi.com/support/en-us/detail/74882968522337
|
|
1634
|
-
// we skip it if the market was delisted
|
|
1635
|
-
if (code !== undefined) {
|
|
1636
|
-
const account = this.account();
|
|
1637
|
-
account['free'] = this.safeString2(balance, 'margin_balance', 'margin_available');
|
|
1638
|
-
account['used'] = this.safeString(balance, 'margin_frozen');
|
|
1639
|
-
const accountsByCode = {};
|
|
1640
|
-
accountsByCode[code] = account;
|
|
1641
|
-
const symbol = market['symbol'];
|
|
1642
|
-
this.balance[symbol] = this.safeBalance(accountsByCode);
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
else {
|
|
1648
|
-
// isolated margin
|
|
1649
|
-
for (let i = 0; i < data.length; i++) {
|
|
1650
|
-
const isolatedBalance = data[i];
|
|
1651
|
-
const account = this.account();
|
|
1652
|
-
account['free'] = this.safeString(isolatedBalance, 'margin_balance', 'margin_available');
|
|
1653
|
-
account['used'] = this.safeString(isolatedBalance, 'margin_frozen');
|
|
1654
|
-
const currencyId = this.safeString2(isolatedBalance, 'margin_asset', 'symbol');
|
|
1655
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1656
|
-
this.balance[code] = account;
|
|
1657
|
-
this.balance = this.safeBalance(this.balance);
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
else {
|
|
1662
|
-
// inverse branch
|
|
1663
|
-
for (let i = 0; i < data.length; i++) {
|
|
1664
|
-
const balance = data[i];
|
|
1665
|
-
const currencyId = this.safeString(balance, 'symbol');
|
|
1666
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
1667
|
-
const account = this.account();
|
|
1668
|
-
account['free'] = this.safeString(balance, 'margin_available');
|
|
1669
|
-
account['used'] = this.safeString(balance, 'margin_frozen');
|
|
1670
|
-
this.balance[code] = account;
|
|
1671
|
-
this.balance = this.safeBalance(this.balance);
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
client.resolve(this.balance, messageHash);
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
handleSubscriptionStatus(client, message) {
|
|
1678
|
-
//
|
|
1679
|
-
// {
|
|
1680
|
-
// "id": 1583414227,
|
|
1681
|
-
// "status": "ok",
|
|
1682
|
-
// "subbed": "market.btcusdt.mbp.150",
|
|
1683
|
-
// "ts": 1583414229143
|
|
1684
|
-
// }
|
|
1685
|
-
//
|
|
1686
|
-
const id = this.safeString(message, 'id');
|
|
1687
|
-
const subscriptionsById = this.indexBy(client.subscriptions, 'id');
|
|
1688
|
-
const subscription = this.safeValue(subscriptionsById, id);
|
|
1689
|
-
if (subscription !== undefined) {
|
|
1690
|
-
const method = this.safeValue(subscription, 'method');
|
|
1691
|
-
if (method !== undefined) {
|
|
1692
|
-
return method.call(this, client, message, subscription);
|
|
1693
|
-
}
|
|
1694
|
-
// clean up
|
|
1695
|
-
if (id in client.subscriptions) {
|
|
1696
|
-
delete client.subscriptions[id];
|
|
1697
|
-
}
|
|
1698
|
-
}
|
|
1699
|
-
return message;
|
|
1700
|
-
}
|
|
1701
|
-
handleSystemStatus(client, message) {
|
|
1702
|
-
//
|
|
1703
|
-
// todo: answer the question whether handleSystemStatus should be renamed
|
|
1704
|
-
// and unified as handleStatus for any usage pattern that
|
|
1705
|
-
// involves system status and maintenance updates
|
|
1706
|
-
//
|
|
1707
|
-
// {
|
|
1708
|
-
// "id": "1578090234088", // connectId
|
|
1709
|
-
// "type": "welcome",
|
|
1710
|
-
// }
|
|
1711
|
-
//
|
|
1712
|
-
return message;
|
|
1713
|
-
}
|
|
1714
|
-
handleSubject(client, message) {
|
|
1715
|
-
// spot
|
|
1716
|
-
// {
|
|
1717
|
-
// "ch": "market.btcusdt.mbp.150",
|
|
1718
|
-
// "ts": 1583472025885,
|
|
1719
|
-
// "tick": {
|
|
1720
|
-
// "seqNum": 104998984994,
|
|
1721
|
-
// "prevSeqNum": 104998984977,
|
|
1722
|
-
// "bids": [
|
|
1723
|
-
// [9058.27, 0],
|
|
1724
|
-
// [9058.43, 0],
|
|
1725
|
-
// [9058.99, 0],
|
|
1726
|
-
// ],
|
|
1727
|
-
// "asks": [
|
|
1728
|
-
// [9084.27, 0.2],
|
|
1729
|
-
// [9085.69, 0],
|
|
1730
|
-
// [9085.81, 0],
|
|
1731
|
-
// ]
|
|
1732
|
-
// }
|
|
1733
|
-
// }
|
|
1734
|
-
// non spot
|
|
1735
|
-
//
|
|
1736
|
-
// {
|
|
1737
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
1738
|
-
// "tick":{
|
|
1739
|
-
// "asks":[],
|
|
1740
|
-
// "bids":[
|
|
1741
|
-
// [43445.74,1],
|
|
1742
|
-
// [43444.48,0 ],
|
|
1743
|
-
// [40593.92,9]
|
|
1744
|
-
// ],
|
|
1745
|
-
// "ch":"market.BTC220218.depth.size_150.high_freq",
|
|
1746
|
-
// "event":"update",
|
|
1747
|
-
// "id":152727500274,
|
|
1748
|
-
// "mrid":152727500274,
|
|
1749
|
-
// "ts":1645023376098,
|
|
1750
|
-
// "version":37536690
|
|
1751
|
-
// },
|
|
1752
|
-
// "ts":1645023376098
|
|
1753
|
-
// }
|
|
1754
|
-
//
|
|
1755
|
-
// spot private trade
|
|
1756
|
-
//
|
|
1757
|
-
// {
|
|
1758
|
-
// "action":"push",
|
|
1759
|
-
// "ch":"trade.clearing#ltcusdt#1",
|
|
1760
|
-
// "data":{
|
|
1761
|
-
// "eventType":"trade",
|
|
1762
|
-
// "symbol":"ltcusdt",
|
|
1763
|
-
// // ...
|
|
1764
|
-
// },
|
|
1765
|
-
// }
|
|
1766
|
-
//
|
|
1767
|
-
// spot order
|
|
1768
|
-
//
|
|
1769
|
-
// {
|
|
1770
|
-
// "action":"push",
|
|
1771
|
-
// "ch":"orders#btcusdt",
|
|
1772
|
-
// "data": {
|
|
1773
|
-
// "orderSide":"buy",
|
|
1774
|
-
// "lastActTime":1583853365586,
|
|
1775
|
-
// "clientOrderId":"abc123",
|
|
1776
|
-
// "orderStatus":"rejected",
|
|
1777
|
-
// "symbol":"btcusdt",
|
|
1778
|
-
// "eventType":"trigger",
|
|
1779
|
-
// "errCode": 2002,
|
|
1780
|
-
// "errMessage":"invalid.client.order.id (NT)"
|
|
1781
|
-
// }
|
|
1782
|
-
// }
|
|
1783
|
-
//
|
|
1784
|
-
// contract order
|
|
1785
|
-
//
|
|
1786
|
-
// {
|
|
1787
|
-
// "op":"notify",
|
|
1788
|
-
// "topic":"orders.ada",
|
|
1789
|
-
// "ts":1604388667226,
|
|
1790
|
-
// // ?
|
|
1791
|
-
// }
|
|
1792
|
-
//
|
|
1793
|
-
const ch = this.safeValue(message, 'ch', '');
|
|
1794
|
-
const parts = ch.split('.');
|
|
1795
|
-
const type = this.safeString(parts, 0);
|
|
1796
|
-
if (type === 'market') {
|
|
1797
|
-
const methodName = this.safeString(parts, 2);
|
|
1798
|
-
const methods = {
|
|
1799
|
-
'depth': this.handleOrderBook,
|
|
1800
|
-
'mbp': this.handleOrderBook,
|
|
1801
|
-
'detail': this.handleTicker,
|
|
1802
|
-
'bbo': this.handleTicker,
|
|
1803
|
-
'ticker': this.handleTicker,
|
|
1804
|
-
'trade': this.handleTrades,
|
|
1805
|
-
'kline': this.handleOHLCV,
|
|
1806
|
-
};
|
|
1807
|
-
const method = this.safeValue(methods, methodName);
|
|
1808
|
-
if (method === undefined) {
|
|
1809
|
-
return message;
|
|
1810
|
-
}
|
|
1811
|
-
else {
|
|
1812
|
-
return method.call(this, client, message);
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
// private spot subjects
|
|
1816
|
-
const privateParts = ch.split('#');
|
|
1817
|
-
const privateType = this.safeString(privateParts, 0, '');
|
|
1818
|
-
if (privateType === 'trade.clearing') {
|
|
1819
|
-
this.handleMyTrade(client, message);
|
|
1820
|
-
return;
|
|
1821
|
-
}
|
|
1822
|
-
if (privateType.indexOf('accounts.update') >= 0) {
|
|
1823
|
-
this.handleBalance(client, message);
|
|
1824
|
-
return;
|
|
1825
|
-
}
|
|
1826
|
-
if (privateType === 'orders') {
|
|
1827
|
-
this.handleOrder(client, message);
|
|
1828
|
-
return;
|
|
1829
|
-
}
|
|
1830
|
-
// private contract subjects
|
|
1831
|
-
const op = this.safeString(message, 'op');
|
|
1832
|
-
if (op === 'notify') {
|
|
1833
|
-
const topic = this.safeString(message, 'topic', '');
|
|
1834
|
-
if (topic.indexOf('orders') >= 0) {
|
|
1835
|
-
this.handleOrder(client, message);
|
|
1836
|
-
}
|
|
1837
|
-
if (topic.indexOf('account') >= 0) {
|
|
1838
|
-
this.handleBalance(client, message);
|
|
1839
|
-
}
|
|
1840
|
-
if (topic.indexOf('positions') >= 0) {
|
|
1841
|
-
this.handlePositions(client, message);
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1845
|
-
async pong(client, message) {
|
|
1846
|
-
//
|
|
1847
|
-
// { ping: 1583491673714 }
|
|
1848
|
-
// { action: "ping", data: { ts: 1645108204665 } }
|
|
1849
|
-
// { op: "ping", ts: "1645202800015" }
|
|
1850
|
-
//
|
|
1851
|
-
try {
|
|
1852
|
-
const ping = this.safeInteger(message, 'ping');
|
|
1853
|
-
if (ping !== undefined) {
|
|
1854
|
-
await client.send({ 'pong': ping });
|
|
1855
|
-
return;
|
|
1856
|
-
}
|
|
1857
|
-
const action = this.safeString(message, 'action');
|
|
1858
|
-
if (action === 'ping') {
|
|
1859
|
-
const data = this.safeValue(message, 'data');
|
|
1860
|
-
const pingTs = this.safeInteger(data, 'ts');
|
|
1861
|
-
await client.send({ 'action': 'pong', 'data': { 'ts': pingTs } });
|
|
1862
|
-
return;
|
|
1863
|
-
}
|
|
1864
|
-
const op = this.safeString(message, 'op');
|
|
1865
|
-
if (op === 'ping') {
|
|
1866
|
-
const pingTs = this.safeInteger(message, 'ts');
|
|
1867
|
-
await client.send({ 'op': 'pong', 'ts': pingTs });
|
|
1868
|
-
}
|
|
1869
|
-
}
|
|
1870
|
-
catch (e) {
|
|
1871
|
-
const error = new errors.NetworkError(this.id + ' pong failed ' + this.json(e));
|
|
1872
|
-
client.reset(error);
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
handlePing(client, message) {
|
|
1876
|
-
this.spawn(this.pong, client, message);
|
|
1877
|
-
}
|
|
1878
|
-
handleAuthenticate(client, message) {
|
|
1879
|
-
//
|
|
1880
|
-
// spot
|
|
1881
|
-
//
|
|
1882
|
-
// {
|
|
1883
|
-
// "action": "req",
|
|
1884
|
-
// "code": 200,
|
|
1885
|
-
// "ch": "auth",
|
|
1886
|
-
// "data": {}
|
|
1887
|
-
// }
|
|
1888
|
-
//
|
|
1889
|
-
// non spot
|
|
1890
|
-
//
|
|
1891
|
-
// {
|
|
1892
|
-
// "op": "auth",
|
|
1893
|
-
// "type": "api",
|
|
1894
|
-
// "err-code": 0,
|
|
1895
|
-
// "ts": 1645200307319,
|
|
1896
|
-
// "data": { "user-id": "35930539" }
|
|
1897
|
-
// }
|
|
1898
|
-
//
|
|
1899
|
-
const promise = client.futures['authenticated'];
|
|
1900
|
-
promise.resolve(message);
|
|
1901
|
-
}
|
|
1902
|
-
handleErrorMessage(client, message) {
|
|
1903
|
-
//
|
|
1904
|
-
// {
|
|
1905
|
-
// "action": "sub",
|
|
1906
|
-
// "code": 2002,
|
|
1907
|
-
// "ch": "accounts.update#2",
|
|
1908
|
-
// "message": "invalid.auth.state"
|
|
1909
|
-
// }
|
|
1910
|
-
//
|
|
1911
|
-
// {
|
|
1912
|
-
// "ts": 1586323747018,
|
|
1913
|
-
// "status": "error",
|
|
1914
|
-
// 'err-code': "bad-request",
|
|
1915
|
-
// 'err-msg': "invalid mbp.150.symbol linkusdt",
|
|
1916
|
-
// "id": "2"
|
|
1917
|
-
// }
|
|
1918
|
-
//
|
|
1919
|
-
// {
|
|
1920
|
-
// "op": "sub",
|
|
1921
|
-
// "cid": "1",
|
|
1922
|
-
// "topic": "accounts_unify.USDT",
|
|
1923
|
-
// "err-code": 4007,
|
|
1924
|
-
// 'err-msg': "Non - single account user is not available, please check through the cross and isolated account asset interface",
|
|
1925
|
-
// "ts": 1698419490189
|
|
1926
|
-
// }
|
|
1927
|
-
//
|
|
1928
|
-
const status = this.safeString(message, 'status');
|
|
1929
|
-
if (status === 'error') {
|
|
1930
|
-
const id = this.safeString(message, 'id');
|
|
1931
|
-
const subscriptionsById = this.indexBy(client.subscriptions, 'id');
|
|
1932
|
-
const subscription = this.safeValue(subscriptionsById, id);
|
|
1933
|
-
if (subscription !== undefined) {
|
|
1934
|
-
const errorCode = this.safeString(message, 'err-code');
|
|
1935
|
-
try {
|
|
1936
|
-
this.throwExactlyMatchedException(this.exceptions['ws']['exact'], errorCode, this.json(message));
|
|
1937
|
-
}
|
|
1938
|
-
catch (e) {
|
|
1939
|
-
const messageHash = this.safeString(subscription, 'messageHash');
|
|
1940
|
-
client.reject(e, messageHash);
|
|
1941
|
-
client.reject(e, id);
|
|
1942
|
-
if (id in client.subscriptions) {
|
|
1943
|
-
delete client.subscriptions[id];
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
return false;
|
|
1948
|
-
}
|
|
1949
|
-
const code = this.safeInteger2(message, 'code', 'err-code');
|
|
1950
|
-
if (code !== undefined && ((code !== 200) && (code !== 0))) {
|
|
1951
|
-
const feedback = this.id + ' ' + this.json(message);
|
|
1952
|
-
try {
|
|
1953
|
-
this.throwExactlyMatchedException(this.exceptions['ws']['exact'], code, feedback);
|
|
1954
|
-
}
|
|
1955
|
-
catch (e) {
|
|
1956
|
-
if (e instanceof errors.AuthenticationError) {
|
|
1957
|
-
client.reject(e, 'auth');
|
|
1958
|
-
const method = 'auth';
|
|
1959
|
-
if (method in client.subscriptions) {
|
|
1960
|
-
delete client.subscriptions[method];
|
|
1961
|
-
}
|
|
1962
|
-
return false;
|
|
1963
|
-
}
|
|
1964
|
-
else {
|
|
1965
|
-
client.reject(e);
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
}
|
|
1969
|
-
return message;
|
|
1970
|
-
}
|
|
1971
|
-
handleMessage(client, message) {
|
|
1972
|
-
if (this.handleErrorMessage(client, message)) {
|
|
1973
|
-
//
|
|
1974
|
-
// {"id":1583414227,"status":"ok","subbed":"market.btcusdt.mbp.150","ts":1583414229143}
|
|
1975
|
-
//
|
|
1976
|
-
// first ping format
|
|
1977
|
-
//
|
|
1978
|
-
// {"ping": 1645106821667 }
|
|
1979
|
-
//
|
|
1980
|
-
// second ping format
|
|
1981
|
-
//
|
|
1982
|
-
// {"action":"ping","data":{"ts":1645106821667}}
|
|
1983
|
-
//
|
|
1984
|
-
// third pong format
|
|
1985
|
-
//
|
|
1986
|
-
//
|
|
1987
|
-
// auth spot
|
|
1988
|
-
//
|
|
1989
|
-
// {
|
|
1990
|
-
// "action": "req",
|
|
1991
|
-
// "code": 200,
|
|
1992
|
-
// "ch": "auth",
|
|
1993
|
-
// "data": {}
|
|
1994
|
-
// }
|
|
1995
|
-
//
|
|
1996
|
-
// auth non spot
|
|
1997
|
-
//
|
|
1998
|
-
// {
|
|
1999
|
-
// "op": "auth",
|
|
2000
|
-
// "type": "api",
|
|
2001
|
-
// "err-code": 0,
|
|
2002
|
-
// "ts": 1645200307319,
|
|
2003
|
-
// "data": { "user-id": "35930539" }
|
|
2004
|
-
// }
|
|
2005
|
-
//
|
|
2006
|
-
// trade
|
|
2007
|
-
//
|
|
2008
|
-
// {
|
|
2009
|
-
// "action":"push",
|
|
2010
|
-
// "ch":"trade.clearing#ltcusdt#1",
|
|
2011
|
-
// "data":{
|
|
2012
|
-
// "eventType":"trade",
|
|
2013
|
-
// // ?
|
|
2014
|
-
// }
|
|
2015
|
-
// }
|
|
2016
|
-
//
|
|
2017
|
-
if ('id' in message) {
|
|
2018
|
-
this.handleSubscriptionStatus(client, message);
|
|
2019
|
-
return;
|
|
2020
|
-
}
|
|
2021
|
-
if ('action' in message) {
|
|
2022
|
-
const action = this.safeString(message, 'action');
|
|
2023
|
-
if (action === 'ping') {
|
|
2024
|
-
this.handlePing(client, message);
|
|
2025
|
-
return;
|
|
2026
|
-
}
|
|
2027
|
-
if (action === 'sub') {
|
|
2028
|
-
this.handleSubscriptionStatus(client, message);
|
|
2029
|
-
return;
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
if ('ch' in message) {
|
|
2033
|
-
if (message['ch'] === 'auth') {
|
|
2034
|
-
this.handleAuthenticate(client, message);
|
|
2035
|
-
return;
|
|
2036
|
-
}
|
|
2037
|
-
else {
|
|
2038
|
-
// route by channel aka topic aka subject
|
|
2039
|
-
this.handleSubject(client, message);
|
|
2040
|
-
return;
|
|
2041
|
-
}
|
|
2042
|
-
}
|
|
2043
|
-
if ('op' in message) {
|
|
2044
|
-
const op = this.safeString(message, 'op');
|
|
2045
|
-
if (op === 'ping') {
|
|
2046
|
-
this.handlePing(client, message);
|
|
2047
|
-
return;
|
|
2048
|
-
}
|
|
2049
|
-
if (op === 'auth') {
|
|
2050
|
-
this.handleAuthenticate(client, message);
|
|
2051
|
-
return;
|
|
2052
|
-
}
|
|
2053
|
-
if (op === 'sub') {
|
|
2054
|
-
this.handleSubscriptionStatus(client, message);
|
|
2055
|
-
return;
|
|
2056
|
-
}
|
|
2057
|
-
if (op === 'notify') {
|
|
2058
|
-
this.handleSubject(client, message);
|
|
2059
|
-
return;
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
if ('ping' in message) {
|
|
2063
|
-
this.handlePing(client, message);
|
|
2064
|
-
}
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
|
-
handleMyTrade(client, message, extendParams = {}) {
|
|
2068
|
-
//
|
|
2069
|
-
// spot
|
|
2070
|
-
//
|
|
2071
|
-
// {
|
|
2072
|
-
// "action":"push",
|
|
2073
|
-
// "ch":"trade.clearing#ltcusdt#1",
|
|
2074
|
-
// "data":{
|
|
2075
|
-
// "eventType":"trade",
|
|
2076
|
-
// "symbol":"ltcusdt",
|
|
2077
|
-
// "orderId":"478862728954426",
|
|
2078
|
-
// "orderSide":"buy",
|
|
2079
|
-
// "orderType":"buy-market",
|
|
2080
|
-
// "accountId":44234548,
|
|
2081
|
-
// "source":"spot-web",
|
|
2082
|
-
// "orderValue":"5.01724137",
|
|
2083
|
-
// "orderCreateTime":1645124660365,
|
|
2084
|
-
// "orderStatus":"filled",
|
|
2085
|
-
// "feeCurrency":"ltc",
|
|
2086
|
-
// "tradePrice":"118.89",
|
|
2087
|
-
// "tradeVolume":"0.042200701236437042",
|
|
2088
|
-
// "aggressor":true,
|
|
2089
|
-
// "tradeId":101539740584,
|
|
2090
|
-
// "tradeTime":1645124660368,
|
|
2091
|
-
// "transactFee":"0.000041778694224073",
|
|
2092
|
-
// "feeDeduct":"0",
|
|
2093
|
-
// "feeDeductType":""
|
|
2094
|
-
// }
|
|
2095
|
-
// }
|
|
2096
|
-
//
|
|
2097
|
-
// contract
|
|
2098
|
-
//
|
|
2099
|
-
// {
|
|
2100
|
-
// "symbol": "ADA/USDT:USDT"
|
|
2101
|
-
// "ch": "orders_cross.ada-usdt"
|
|
2102
|
-
// "trades": [
|
|
2103
|
-
// {
|
|
2104
|
-
// "trade_fee":-0.022099447513812154,
|
|
2105
|
-
// "fee_asset":"ADA",
|
|
2106
|
-
// "trade_id":113913755890,
|
|
2107
|
-
// "id":"113913755890-773207641127878656-1",
|
|
2108
|
-
// "trade_volume":1,
|
|
2109
|
-
// "trade_price":0.0905,
|
|
2110
|
-
// "trade_turnover":10,
|
|
2111
|
-
// "created_at":1604388667194,
|
|
2112
|
-
// "profit":0,
|
|
2113
|
-
// "real_profit": 0,
|
|
2114
|
-
// "role":"maker"
|
|
2115
|
-
// }
|
|
2116
|
-
// ],
|
|
2117
|
-
// }
|
|
2118
|
-
//
|
|
2119
|
-
if (this.myTrades === undefined) {
|
|
2120
|
-
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
2121
|
-
this.myTrades = new Cache.ArrayCacheBySymbolById(limit);
|
|
2122
|
-
}
|
|
2123
|
-
const cachedTrades = this.myTrades;
|
|
2124
|
-
const messageHash = this.safeString(message, 'ch');
|
|
2125
|
-
if (messageHash !== undefined) {
|
|
2126
|
-
const data = this.safeValue(message, 'data');
|
|
2127
|
-
if (data !== undefined) {
|
|
2128
|
-
const parsed = this.parseWsTrade(data);
|
|
2129
|
-
const symbol = this.safeString(parsed, 'symbol');
|
|
2130
|
-
if (symbol !== undefined) {
|
|
2131
|
-
cachedTrades.append(parsed);
|
|
2132
|
-
client.resolve(this.myTrades, messageHash);
|
|
2133
|
-
}
|
|
2134
|
-
}
|
|
2135
|
-
else {
|
|
2136
|
-
// this trades object is artificially created
|
|
2137
|
-
// in handleOrder
|
|
2138
|
-
const rawTrades = this.safeValue(message, 'trades', []);
|
|
2139
|
-
const marketId = this.safeValue(message, 'symbol');
|
|
2140
|
-
const market = this.market(marketId);
|
|
2141
|
-
for (let i = 0; i < rawTrades.length; i++) {
|
|
2142
|
-
const trade = rawTrades[i];
|
|
2143
|
-
let parsedTrade = this.parseTrade(trade, market);
|
|
2144
|
-
// add extra params (side, type, ...) coming from the order
|
|
2145
|
-
parsedTrade = this.extend(parsedTrade, extendParams);
|
|
2146
|
-
cachedTrades.append(parsedTrade);
|
|
2147
|
-
}
|
|
2148
|
-
// messageHash here is the orders one, so
|
|
2149
|
-
// we have to recreate the trades messageHash = orderMessageHash + ':' + 'trade'
|
|
2150
|
-
const tradesHash = messageHash + ':' + 'trade';
|
|
2151
|
-
client.resolve(this.myTrades, tradesHash);
|
|
2152
|
-
// when we make an global order sub we have to send the channel like this
|
|
2153
|
-
// ch = orders_cross.* and we store messageHash = 'orders_cross'
|
|
2154
|
-
// however it is returned with the specific order update symbol: ch = orders_cross.btc-usd
|
|
2155
|
-
// since this is a global sub, our messageHash does not specify any symbol (ex: orders_cross:trade)
|
|
2156
|
-
// so we must remove it
|
|
2157
|
-
let genericOrderHash = messageHash.replace('.' + market['lowercaseId'], '');
|
|
2158
|
-
const lowerCaseBaseId = this.safeStringLower(market, 'baseId');
|
|
2159
|
-
genericOrderHash = genericOrderHash.replace('.' + lowerCaseBaseId, '');
|
|
2160
|
-
const genericTradesHash = genericOrderHash + ':' + 'trade';
|
|
2161
|
-
client.resolve(this.myTrades, genericTradesHash);
|
|
2162
|
-
}
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
parseWsTrade(trade, market = undefined) {
|
|
2166
|
-
// spot private
|
|
2167
|
-
//
|
|
2168
|
-
// {
|
|
2169
|
-
// "eventType":"trade",
|
|
2170
|
-
// "symbol":"ltcusdt",
|
|
2171
|
-
// "orderId":"478862728954426",
|
|
2172
|
-
// "orderSide":"buy",
|
|
2173
|
-
// "orderType":"buy-market",
|
|
2174
|
-
// "accountId":44234548,
|
|
2175
|
-
// "source":"spot-web",
|
|
2176
|
-
// "orderValue":"5.01724137",
|
|
2177
|
-
// "orderCreateTime":1645124660365,
|
|
2178
|
-
// "orderStatus":"filled",
|
|
2179
|
-
// "feeCurrency":"ltc",
|
|
2180
|
-
// "tradePrice":"118.89",
|
|
2181
|
-
// "tradeVolume":"0.042200701236437042",
|
|
2182
|
-
// "aggressor":true,
|
|
2183
|
-
// "tradeId":101539740584,
|
|
2184
|
-
// "tradeTime":1645124660368,
|
|
2185
|
-
// "transactFee":"0.000041778694224073",
|
|
2186
|
-
// "feeDeduct":"0",
|
|
2187
|
-
// "feeDeductType":""
|
|
2188
|
-
// }
|
|
2189
|
-
//
|
|
2190
|
-
const symbol = this.safeSymbol(this.safeString(trade, 'symbol'));
|
|
2191
|
-
const side = this.safeString2(trade, 'side', 'orderSide');
|
|
2192
|
-
const tradeId = this.safeString(trade, 'tradeId');
|
|
2193
|
-
const price = this.safeString(trade, 'tradePrice');
|
|
2194
|
-
const amount = this.safeString(trade, 'tradeVolume');
|
|
2195
|
-
const order = this.safeString(trade, 'orderId');
|
|
2196
|
-
const timestamp = this.safeInteger(trade, 'tradeTime');
|
|
2197
|
-
market = this.market(symbol);
|
|
2198
|
-
const orderType = this.safeString(trade, 'orderType');
|
|
2199
|
-
const aggressor = this.safeValue(trade, 'aggressor');
|
|
2200
|
-
let takerOrMaker = undefined;
|
|
2201
|
-
if (aggressor !== undefined) {
|
|
2202
|
-
takerOrMaker = aggressor ? 'taker' : 'maker';
|
|
2203
|
-
}
|
|
2204
|
-
let type = undefined;
|
|
2205
|
-
let orderTypeParts = [];
|
|
2206
|
-
if (orderType !== undefined) {
|
|
2207
|
-
orderTypeParts = orderType.split('-');
|
|
2208
|
-
type = this.safeString(orderTypeParts, 1);
|
|
2209
|
-
}
|
|
2210
|
-
let fee = undefined;
|
|
2211
|
-
const feeCurrency = this.safeCurrencyCode(this.safeString(trade, 'feeCurrency'));
|
|
2212
|
-
if (feeCurrency !== undefined) {
|
|
2213
|
-
fee = {
|
|
2214
|
-
'cost': this.safeString(trade, 'transactFee'),
|
|
2215
|
-
'currency': feeCurrency,
|
|
2216
|
-
};
|
|
2217
|
-
}
|
|
2218
|
-
return this.safeTrade({
|
|
2219
|
-
'info': trade,
|
|
2220
|
-
'timestamp': timestamp,
|
|
2221
|
-
'datetime': this.iso8601(timestamp),
|
|
2222
|
-
'symbol': symbol,
|
|
2223
|
-
'id': tradeId,
|
|
2224
|
-
'order': order,
|
|
2225
|
-
'type': type,
|
|
2226
|
-
'takerOrMaker': takerOrMaker,
|
|
2227
|
-
'side': side,
|
|
2228
|
-
'price': price,
|
|
2229
|
-
'amount': amount,
|
|
2230
|
-
'cost': undefined,
|
|
2231
|
-
'fee': fee,
|
|
2232
|
-
}, market);
|
|
2233
|
-
}
|
|
2234
|
-
getUrlByMarketType(type, isLinear = true, isPrivate = false, isFeed = false) {
|
|
2235
|
-
const api = this.safeString(this.options, 'api', 'api');
|
|
2236
|
-
const hostname = { 'hostname': this.hostname };
|
|
2237
|
-
let hostnameURL = undefined;
|
|
2238
|
-
let url = undefined;
|
|
2239
|
-
if (type === 'spot') {
|
|
2240
|
-
if (isPrivate) {
|
|
2241
|
-
hostnameURL = this.urls['api']['ws'][api]['spot']['private'];
|
|
2242
|
-
}
|
|
2243
|
-
else {
|
|
2244
|
-
if (isFeed) {
|
|
2245
|
-
hostnameURL = this.urls['api']['ws'][api]['spot']['feed'];
|
|
2246
|
-
}
|
|
2247
|
-
else {
|
|
2248
|
-
hostnameURL = this.urls['api']['ws'][api]['spot']['public'];
|
|
2249
|
-
}
|
|
2250
|
-
}
|
|
2251
|
-
url = this.implodeParams(hostnameURL, hostname);
|
|
2252
|
-
}
|
|
2253
|
-
else {
|
|
2254
|
-
const baseUrl = this.urls['api']['ws'][api][type];
|
|
2255
|
-
const subTypeUrl = isLinear ? baseUrl['linear'] : baseUrl['inverse'];
|
|
2256
|
-
url = isPrivate ? subTypeUrl['private'] : subTypeUrl['public'];
|
|
2257
|
-
}
|
|
2258
|
-
return url;
|
|
2259
|
-
}
|
|
2260
|
-
async subscribePublic(url, symbol, messageHash, method = undefined, params = {}) {
|
|
2261
|
-
const requestId = this.requestId();
|
|
2262
|
-
const request = {
|
|
2263
|
-
'sub': messageHash,
|
|
2264
|
-
'id': requestId,
|
|
2265
|
-
};
|
|
2266
|
-
const subscription = {
|
|
2267
|
-
'id': requestId,
|
|
2268
|
-
'messageHash': messageHash,
|
|
2269
|
-
'symbol': symbol,
|
|
2270
|
-
'params': params,
|
|
2271
|
-
};
|
|
2272
|
-
if (method !== undefined) {
|
|
2273
|
-
subscription['method'] = method;
|
|
2274
|
-
}
|
|
2275
|
-
return await this.watch(url, messageHash, this.extend(request, params), messageHash, subscription);
|
|
2276
|
-
}
|
|
2277
|
-
async subscribePrivate(channel, messageHash, type, subtype, params = {}, subscriptionParams = {}) {
|
|
2278
|
-
const requestId = this.requestId();
|
|
2279
|
-
const subscription = {
|
|
2280
|
-
'id': requestId,
|
|
2281
|
-
'messageHash': messageHash,
|
|
2282
|
-
'params': params,
|
|
2283
|
-
};
|
|
2284
|
-
const extendedSubsription = this.extend(subscription, subscriptionParams);
|
|
2285
|
-
let request = undefined;
|
|
2286
|
-
if (type === 'spot') {
|
|
2287
|
-
request = {
|
|
2288
|
-
'action': 'sub',
|
|
2289
|
-
'ch': channel,
|
|
2290
|
-
};
|
|
2291
|
-
}
|
|
2292
|
-
else {
|
|
2293
|
-
request = {
|
|
2294
|
-
'op': 'sub',
|
|
2295
|
-
'topic': channel,
|
|
2296
|
-
'cid': requestId,
|
|
2297
|
-
};
|
|
2298
|
-
}
|
|
2299
|
-
const isLinear = subtype === 'linear';
|
|
2300
|
-
const url = this.getUrlByMarketType(type, isLinear, true);
|
|
2301
|
-
const hostname = (type === 'spot') ? this.urls['hostnames']['spot'] : this.urls['hostnames']['contract'];
|
|
2302
|
-
const authParams = {
|
|
2303
|
-
'type': type,
|
|
2304
|
-
'url': url,
|
|
2305
|
-
'hostname': hostname,
|
|
2306
|
-
};
|
|
2307
|
-
if (type === 'spot') {
|
|
2308
|
-
this.options['ws']['gunzip'] = false;
|
|
2309
|
-
}
|
|
2310
|
-
await this.authenticate(authParams);
|
|
2311
|
-
return await this.watch(url, messageHash, this.extend(request, params), channel, extendedSubsription);
|
|
2312
|
-
}
|
|
2313
|
-
async authenticate(params = {}) {
|
|
2314
|
-
const url = this.safeString(params, 'url');
|
|
2315
|
-
const hostname = this.safeString(params, 'hostname');
|
|
2316
|
-
const type = this.safeString(params, 'type');
|
|
2317
|
-
if (url === undefined || hostname === undefined || type === undefined) {
|
|
2318
|
-
throw new errors.ArgumentsRequired(this.id + ' authenticate requires a url, hostname and type argument');
|
|
2319
|
-
}
|
|
2320
|
-
this.checkRequiredCredentials();
|
|
2321
|
-
const messageHash = 'authenticated';
|
|
2322
|
-
const relativePath = url.replace('wss://' + hostname, '');
|
|
2323
|
-
const client = this.client(url);
|
|
2324
|
-
const future = client.future(messageHash);
|
|
2325
|
-
const authenticated = this.safeValue(client.subscriptions, messageHash);
|
|
2326
|
-
if (authenticated === undefined) {
|
|
2327
|
-
const timestamp = this.ymdhms(this.milliseconds(), 'T');
|
|
2328
|
-
let signatureParams = undefined;
|
|
2329
|
-
if (type === 'spot') {
|
|
2330
|
-
signatureParams = {
|
|
2331
|
-
'accessKey': this.apiKey,
|
|
2332
|
-
'signatureMethod': 'HmacSHA256',
|
|
2333
|
-
'signatureVersion': '2.1',
|
|
2334
|
-
'timestamp': timestamp,
|
|
2335
|
-
};
|
|
2336
|
-
}
|
|
2337
|
-
else {
|
|
2338
|
-
signatureParams = {
|
|
2339
|
-
'AccessKeyId': this.apiKey,
|
|
2340
|
-
'SignatureMethod': 'HmacSHA256',
|
|
2341
|
-
'SignatureVersion': '2',
|
|
2342
|
-
'Timestamp': timestamp,
|
|
2343
|
-
};
|
|
2344
|
-
}
|
|
2345
|
-
signatureParams = this.keysort(signatureParams);
|
|
2346
|
-
const auth = this.urlencode(signatureParams);
|
|
2347
|
-
const payload = ['GET', hostname, relativePath, auth].join("\n"); // eslint-disable-line quotes
|
|
2348
|
-
const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256.sha256, 'base64');
|
|
2349
|
-
let request = undefined;
|
|
2350
|
-
if (type === 'spot') {
|
|
2351
|
-
const newParams = {
|
|
2352
|
-
'authType': 'api',
|
|
2353
|
-
'accessKey': this.apiKey,
|
|
2354
|
-
'signatureMethod': 'HmacSHA256',
|
|
2355
|
-
'signatureVersion': '2.1',
|
|
2356
|
-
'timestamp': timestamp,
|
|
2357
|
-
'signature': signature,
|
|
2358
|
-
};
|
|
2359
|
-
request = {
|
|
2360
|
-
'params': newParams,
|
|
2361
|
-
'action': 'req',
|
|
2362
|
-
'ch': 'auth',
|
|
2363
|
-
};
|
|
2364
|
-
}
|
|
2365
|
-
else {
|
|
2366
|
-
request = {
|
|
2367
|
-
'op': 'auth',
|
|
2368
|
-
'type': 'api',
|
|
2369
|
-
'AccessKeyId': this.apiKey,
|
|
2370
|
-
'SignatureMethod': 'HmacSHA256',
|
|
2371
|
-
'SignatureVersion': '2',
|
|
2372
|
-
'Timestamp': timestamp,
|
|
2373
|
-
'Signature': signature,
|
|
2374
|
-
};
|
|
2375
|
-
}
|
|
2376
|
-
const requestId = this.requestId();
|
|
2377
|
-
const subscription = {
|
|
2378
|
-
'id': requestId,
|
|
2379
|
-
'messageHash': messageHash,
|
|
2380
|
-
'params': params,
|
|
2381
|
-
};
|
|
2382
|
-
this.watch(url, messageHash, request, messageHash, subscription);
|
|
2383
|
-
}
|
|
2384
|
-
return future;
|
|
2385
|
-
}
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2388
|
-
module.exports = htx;
|