ccxt 4.2.11 → 4.2.13
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 +5 -5
- package/build.sh +2 -2
- package/dist/ccxt.browser.js +1347 -490
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/_virtual/agent.js +7 -0
- package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
- package/dist/cjs/_virtual/promisify.js +7 -0
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/js/ccxt.js +474 -0
- package/dist/cjs/js/src/abstract/ace.js +9 -0
- package/dist/cjs/js/src/abstract/alpaca.js +9 -0
- package/dist/cjs/js/src/abstract/ascendex.js +9 -0
- package/dist/cjs/js/src/abstract/bigone.js +9 -0
- package/dist/cjs/js/src/abstract/binance.js +9 -0
- package/dist/cjs/js/src/abstract/bingx.js +9 -0
- package/dist/cjs/js/src/abstract/bit2c.js +9 -0
- package/dist/cjs/js/src/abstract/bitbank.js +9 -0
- package/dist/cjs/js/src/abstract/bitbns.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
- package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
- package/dist/cjs/js/src/abstract/bitforex.js +9 -0
- package/dist/cjs/js/src/abstract/bitget.js +9 -0
- package/dist/cjs/js/src/abstract/bithumb.js +9 -0
- package/dist/cjs/js/src/abstract/bitmart.js +9 -0
- package/dist/cjs/js/src/abstract/bitmex.js +9 -0
- package/dist/cjs/js/src/abstract/bitopro.js +9 -0
- package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
- package/dist/cjs/js/src/abstract/bitrue.js +9 -0
- package/dist/cjs/js/src/abstract/bitso.js +9 -0
- package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
- package/dist/cjs/js/src/abstract/bitteam.js +9 -0
- package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
- package/dist/cjs/js/src/abstract/bl3p.js +9 -0
- package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
- package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
- package/dist/cjs/js/src/abstract/btcbox.js +9 -0
- package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
- package/dist/cjs/js/src/abstract/btcturk.js +9 -0
- package/dist/cjs/js/src/abstract/bybit.js +9 -0
- package/dist/cjs/js/src/abstract/cex.js +9 -0
- package/dist/cjs/js/src/abstract/coinbase.js +9 -0
- package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
- package/dist/cjs/js/src/abstract/coincheck.js +9 -0
- package/dist/cjs/js/src/abstract/coinex.js +9 -0
- package/dist/cjs/js/src/abstract/coinlist.js +9 -0
- package/dist/cjs/js/src/abstract/coinmate.js +9 -0
- package/dist/cjs/js/src/abstract/coinone.js +9 -0
- package/dist/cjs/js/src/abstract/coinsph.js +9 -0
- package/dist/cjs/js/src/abstract/coinspot.js +9 -0
- package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
- package/dist/cjs/js/src/abstract/currencycom.js +9 -0
- package/dist/cjs/js/src/abstract/delta.js +9 -0
- package/dist/cjs/js/src/abstract/deribit.js +9 -0
- package/dist/cjs/js/src/abstract/digifinex.js +9 -0
- package/dist/cjs/js/src/abstract/exmo.js +9 -0
- package/dist/cjs/js/src/abstract/gate.js +9 -0
- package/dist/cjs/js/src/abstract/gemini.js +9 -0
- package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
- package/dist/cjs/js/src/abstract/hollaex.js +9 -0
- package/dist/cjs/js/src/abstract/htx.js +9 -0
- package/dist/cjs/js/src/abstract/huobijp.js +9 -0
- package/dist/cjs/js/src/abstract/idex.js +9 -0
- package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
- package/dist/cjs/js/src/abstract/indodax.js +9 -0
- package/dist/cjs/js/src/abstract/kraken.js +9 -0
- package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kucoin.js +9 -0
- package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kuna.js +9 -0
- package/dist/cjs/js/src/abstract/latoken.js +9 -0
- package/dist/cjs/js/src/abstract/lbank.js +9 -0
- package/dist/cjs/js/src/abstract/luno.js +9 -0
- package/dist/cjs/js/src/abstract/lykke.js +9 -0
- package/dist/cjs/js/src/abstract/mercado.js +9 -0
- package/dist/cjs/js/src/abstract/mexc.js +9 -0
- package/dist/cjs/js/src/abstract/ndax.js +9 -0
- package/dist/cjs/js/src/abstract/novadax.js +9 -0
- package/dist/cjs/js/src/abstract/oceanex.js +9 -0
- package/dist/cjs/js/src/abstract/okcoin.js +9 -0
- package/dist/cjs/js/src/abstract/okx.js +9 -0
- package/dist/cjs/js/src/abstract/p2b.js +9 -0
- package/dist/cjs/js/src/abstract/paymium.js +9 -0
- package/dist/cjs/js/src/abstract/phemex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
- package/dist/cjs/js/src/abstract/probit.js +9 -0
- package/dist/cjs/js/src/abstract/timex.js +9 -0
- package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
- package/dist/cjs/js/src/abstract/upbit.js +9 -0
- package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
- package/dist/cjs/js/src/abstract/wazirx.js +9 -0
- package/dist/cjs/js/src/abstract/whitebit.js +9 -0
- package/dist/cjs/js/src/abstract/woo.js +9 -0
- package/dist/cjs/js/src/abstract/yobit.js +9 -0
- package/dist/cjs/js/src/abstract/zaif.js +9 -0
- package/dist/cjs/js/src/abstract/zonda.js +9 -0
- package/dist/cjs/js/src/ace.js +1058 -0
- package/dist/cjs/js/src/alpaca.js +1125 -0
- package/dist/cjs/js/src/ascendex.js +3360 -0
- package/dist/cjs/js/src/base/Exchange.js +5110 -0
- package/dist/cjs/js/src/base/Precise.js +263 -0
- package/dist/cjs/js/src/base/errors.js +299 -0
- package/dist/cjs/js/src/base/functions/crypto.js +78 -0
- package/dist/cjs/js/src/base/functions/encode.js +44 -0
- package/dist/cjs/js/src/base/functions/generic.js +193 -0
- package/dist/cjs/js/src/base/functions/misc.js +96 -0
- package/dist/cjs/js/src/base/functions/number.js +297 -0
- package/dist/cjs/js/src/base/functions/platform.js +28 -0
- package/dist/cjs/js/src/base/functions/rsa.js +34 -0
- package/dist/cjs/js/src/base/functions/string.js +48 -0
- package/dist/cjs/js/src/base/functions/throttle.js +66 -0
- package/dist/cjs/js/src/base/functions/time.js +187 -0
- package/dist/cjs/js/src/base/functions/totp.js +24 -0
- package/dist/cjs/js/src/base/functions/type.js +162 -0
- package/dist/cjs/js/src/base/functions.js +157 -0
- package/dist/cjs/js/src/base/ws/Cache.js +254 -0
- package/dist/cjs/js/src/base/ws/Client.js +299 -0
- package/dist/cjs/js/src/base/ws/Future.js +34 -0
- package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
- package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
- package/dist/cjs/js/src/bequant.js +33 -0
- package/dist/cjs/js/src/bigone.js +2209 -0
- package/dist/cjs/js/src/binance.js +9736 -0
- package/dist/cjs/js/src/binancecoinm.js +45 -0
- package/dist/cjs/js/src/binanceus.js +84 -0
- package/dist/cjs/js/src/binanceusdm.js +58 -0
- package/dist/cjs/js/src/bingx.js +3807 -0
- package/dist/cjs/js/src/bit2c.js +916 -0
- package/dist/cjs/js/src/bitbank.js +1000 -0
- package/dist/cjs/js/src/bitbay.js +17 -0
- package/dist/cjs/js/src/bitbns.js +1220 -0
- package/dist/cjs/js/src/bitcoincom.js +17 -0
- package/dist/cjs/js/src/bitfinex.js +1670 -0
- package/dist/cjs/js/src/bitfinex2.js +2990 -0
- package/dist/cjs/js/src/bitflyer.js +1045 -0
- package/dist/cjs/js/src/bitforex.js +852 -0
- package/dist/cjs/js/src/bitget.js +8291 -0
- package/dist/cjs/js/src/bithumb.js +1090 -0
- package/dist/cjs/js/src/bitmart.js +4454 -0
- package/dist/cjs/js/src/bitmex.js +2884 -0
- package/dist/cjs/js/src/bitopro.js +1724 -0
- package/dist/cjs/js/src/bitpanda.js +2002 -0
- package/dist/cjs/js/src/bitrue.js +3253 -0
- package/dist/cjs/js/src/bitso.js +1753 -0
- package/dist/cjs/js/src/bitstamp.js +2188 -0
- package/dist/cjs/js/src/bitteam.js +2309 -0
- package/dist/cjs/js/src/bitvavo.js +1968 -0
- package/dist/cjs/js/src/bl3p.js +447 -0
- package/dist/cjs/js/src/blockchaincom.js +1160 -0
- package/dist/cjs/js/src/btcalpha.js +929 -0
- package/dist/cjs/js/src/btcbox.js +565 -0
- package/dist/cjs/js/src/btcmarkets.js +1237 -0
- package/dist/cjs/js/src/btcturk.js +929 -0
- package/dist/cjs/js/src/bybit.js +7646 -0
- package/dist/cjs/js/src/cex.js +1693 -0
- package/dist/cjs/js/src/coinbase.js +3424 -0
- package/dist/cjs/js/src/coinbasepro.js +1866 -0
- package/dist/cjs/js/src/coincheck.js +843 -0
- package/dist/cjs/js/src/coinex.js +5414 -0
- package/dist/cjs/js/src/coinlist.js +2329 -0
- package/dist/cjs/js/src/coinmate.js +989 -0
- package/dist/cjs/js/src/coinone.js +1185 -0
- package/dist/cjs/js/src/coinsph.js +1933 -0
- package/dist/cjs/js/src/coinspot.js +548 -0
- package/dist/cjs/js/src/cryptocom.js +3007 -0
- package/dist/cjs/js/src/currencycom.js +2015 -0
- package/dist/cjs/js/src/delta.js +3256 -0
- package/dist/cjs/js/src/deribit.js +3306 -0
- package/dist/cjs/js/src/digifinex.js +4307 -0
- package/dist/cjs/js/src/exmo.js +2645 -0
- package/dist/cjs/js/src/fmfwio.js +34 -0
- package/dist/cjs/js/src/gate.js +7072 -0
- package/dist/cjs/js/src/gateio.js +16 -0
- package/dist/cjs/js/src/gemini.js +1801 -0
- package/dist/cjs/js/src/hitbtc.js +3660 -0
- package/dist/cjs/js/src/hitbtc3.js +19 -0
- package/dist/cjs/js/src/hollaex.js +1882 -0
- package/dist/cjs/js/src/htx.js +9049 -0
- package/dist/cjs/js/src/huobi.js +16 -0
- package/dist/cjs/js/src/huobijp.js +1918 -0
- package/dist/cjs/js/src/idex.js +1770 -0
- package/dist/cjs/js/src/independentreserve.js +761 -0
- package/dist/cjs/js/src/indodax.js +1069 -0
- package/dist/cjs/js/src/kraken.js +2857 -0
- package/dist/cjs/js/src/krakenfutures.js +2407 -0
- package/dist/cjs/js/src/kucoin.js +4489 -0
- package/dist/cjs/js/src/kucoinfutures.js +2475 -0
- package/dist/cjs/js/src/kuna.js +1949 -0
- package/dist/cjs/js/src/latoken.js +1729 -0
- package/dist/cjs/js/src/lbank.js +2851 -0
- package/dist/cjs/js/src/luno.js +1044 -0
- package/dist/cjs/js/src/lykke.js +1303 -0
- package/dist/cjs/js/src/mercado.js +897 -0
- package/dist/cjs/js/src/mexc.js +5407 -0
- package/dist/cjs/js/src/ndax.js +2450 -0
- package/dist/cjs/js/src/novadax.js +1556 -0
- package/dist/cjs/js/src/oceanex.js +964 -0
- package/dist/cjs/js/src/okcoin.js +3115 -0
- package/dist/cjs/js/src/okx.js +7330 -0
- package/dist/cjs/js/src/p2b.js +1243 -0
- package/dist/cjs/js/src/paymium.js +597 -0
- package/dist/cjs/js/src/phemex.js +4722 -0
- package/dist/cjs/js/src/poloniex.js +2356 -0
- package/dist/cjs/js/src/poloniexfutures.js +1794 -0
- package/dist/cjs/js/src/pro/alpaca.js +714 -0
- package/dist/cjs/js/src/pro/ascendex.js +957 -0
- package/dist/cjs/js/src/pro/bequant.js +33 -0
- package/dist/cjs/js/src/pro/binance.js +2796 -0
- package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
- package/dist/cjs/js/src/pro/binanceus.js +51 -0
- package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
- package/dist/cjs/js/src/pro/bingx.js +944 -0
- package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
- package/dist/cjs/js/src/pro/bitfinex.js +672 -0
- package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
- package/dist/cjs/js/src/pro/bitget.js +1733 -0
- package/dist/cjs/js/src/pro/bitmart.js +1486 -0
- package/dist/cjs/js/src/pro/bitmex.js +1576 -0
- package/dist/cjs/js/src/pro/bitopro.js +327 -0
- package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
- package/dist/cjs/js/src/pro/bitrue.js +462 -0
- package/dist/cjs/js/src/pro/bitstamp.js +547 -0
- package/dist/cjs/js/src/pro/bitvavo.js +704 -0
- package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
- package/dist/cjs/js/src/pro/bybit.js +1843 -0
- package/dist/cjs/js/src/pro/cex.js +1510 -0
- package/dist/cjs/js/src/pro/coinbase.js +561 -0
- package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
- package/dist/cjs/js/src/pro/coinex.js +1095 -0
- package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
- package/dist/cjs/js/src/pro/currencycom.js +563 -0
- package/dist/cjs/js/src/pro/deribit.js +825 -0
- package/dist/cjs/js/src/pro/exmo.js +658 -0
- package/dist/cjs/js/src/pro/gate.js +1316 -0
- package/dist/cjs/js/src/pro/gateio.js +16 -0
- package/dist/cjs/js/src/pro/gemini.js +649 -0
- package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
- package/dist/cjs/js/src/pro/hollaex.js +597 -0
- package/dist/cjs/js/src/pro/htx.js +2383 -0
- package/dist/cjs/js/src/pro/huobi.js +16 -0
- package/dist/cjs/js/src/pro/huobijp.js +606 -0
- package/dist/cjs/js/src/pro/idex.js +714 -0
- package/dist/cjs/js/src/pro/independentreserve.js +280 -0
- package/dist/cjs/js/src/pro/kraken.js +1364 -0
- package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
- package/dist/cjs/js/src/pro/kucoin.js +1052 -0
- package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
- package/dist/cjs/js/src/pro/luno.js +322 -0
- package/dist/cjs/js/src/pro/mexc.js +1170 -0
- package/dist/cjs/js/src/pro/ndax.js +545 -0
- package/dist/cjs/js/src/pro/okcoin.js +760 -0
- package/dist/cjs/js/src/pro/okx.js +1608 -0
- package/dist/cjs/js/src/pro/phemex.js +1511 -0
- package/dist/cjs/js/src/pro/poloniex.js +1253 -0
- package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
- package/dist/cjs/js/src/pro/probit.js +586 -0
- package/dist/cjs/js/src/pro/upbit.js +234 -0
- package/dist/cjs/js/src/pro/wazirx.js +776 -0
- package/dist/cjs/js/src/pro/whitebit.js +927 -0
- package/dist/cjs/js/src/pro/woo.js +769 -0
- package/dist/cjs/js/src/probit.js +1867 -0
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
- package/dist/cjs/js/src/timex.js +1562 -0
- package/dist/cjs/js/src/tokocrypto.js +2542 -0
- package/dist/cjs/js/src/upbit.js +1844 -0
- package/dist/cjs/js/src/wavesexchange.js +2607 -0
- package/dist/cjs/js/src/wazirx.js +953 -0
- package/dist/cjs/js/src/whitebit.js +2309 -0
- package/dist/cjs/js/src/woo.js +2765 -0
- package/dist/cjs/js/src/yobit.js +1314 -0
- package/dist/cjs/js/src/zaif.js +736 -0
- package/dist/cjs/js/src/zonda.js +1883 -0
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bigone.d.ts +18 -0
- package/js/src/abstract/binance.d.ts +2 -0
- package/js/src/abstract/binancecoinm.d.ts +2 -0
- package/js/src/abstract/binanceus.d.ts +2 -0
- package/js/src/abstract/binanceusdm.d.ts +2 -0
- package/js/src/abstract/bingx.d.ts +2 -0
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/abstract/gate.d.ts +11 -0
- package/js/src/abstract/gateio.d.ts +11 -0
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/alpaca.js +18 -18
- package/js/src/base/Exchange.d.ts +5 -1
- package/js/src/base/Exchange.js +101 -12
- package/js/src/bigone.d.ts +3 -2
- package/js/src/bigone.js +429 -167
- package/js/src/binance.js +48 -34
- package/js/src/bingx.js +115 -38
- package/js/src/bitfinex.d.ts +2 -2
- package/js/src/bitfinex.js +2 -3
- package/js/src/bitget.js +33 -13
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +5 -5
- package/js/src/bitmex.js +1 -0
- package/js/src/bybit.js +2 -0
- package/js/src/coinbase.d.ts +26 -3
- package/js/src/coinbase.js +176 -26
- package/js/src/coinlist.js +3 -4
- package/js/src/coinone.js +1 -1
- package/js/src/coinsph.js +2 -3
- package/js/src/deribit.js +1 -0
- package/js/src/gate.d.ts +4 -4
- package/js/src/gate.js +96 -59
- package/js/src/gemini.js +1 -1
- package/js/src/hitbtc.d.ts +4 -4
- package/js/src/hitbtc.js +2 -3
- package/js/src/htx.d.ts +1 -0
- package/js/src/htx.js +29 -7
- package/js/src/huobijp.js +2 -3
- package/js/src/independentreserve.js +7 -5
- package/js/src/kraken.js +3 -6
- package/js/src/lbank.js +59 -33
- package/js/src/mexc.js +2 -1
- package/js/src/oceanex.js +1 -1
- package/js/src/okx.js +14 -3
- package/js/src/phemex.js +9 -2
- package/js/src/pro/binance.d.ts +2 -23
- package/js/src/pro/binance.js +58 -22
- package/js/src/pro/coinbase.d.ts +2 -2
- package/js/src/pro/coinbase.js +4 -1
- package/js/src/pro/coinbasepro.d.ts +2 -2
- package/js/src/pro/hitbtc.d.ts +2 -2
- package/js/src/pro/kraken.js +1 -1
- package/js/src/pro/okx.d.ts +1 -0
- package/js/src/pro/okx.js +52 -2
- package/js/src/pro/poloniex.d.ts +2 -2
- package/js/src/probit.js +4 -2
- package/js/src/upbit.d.ts +3 -101
- package/js/src/upbit.js +12 -12
- package/js/src/wavesexchange.js +1 -1
- package/js/src/woo.d.ts +2 -0
- package/js/src/woo.js +52 -0
- package/package.json +1 -1
- package/skip-tests.json +5 -0
|
@@ -0,0 +1,3660 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var hitbtc$1 = require('./abstract/hitbtc.js');
|
|
4
|
+
var number = require('./base/functions/number.js');
|
|
5
|
+
var Precise = require('./base/Precise.js');
|
|
6
|
+
var errors = require('./base/errors.js');
|
|
7
|
+
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @class hitbtc
|
|
11
|
+
* @augments Exchange
|
|
12
|
+
*/
|
|
13
|
+
class hitbtc extends hitbtc$1 {
|
|
14
|
+
describe() {
|
|
15
|
+
return this.deepExtend(super.describe(), {
|
|
16
|
+
'id': 'hitbtc',
|
|
17
|
+
'name': 'HitBTC',
|
|
18
|
+
'countries': ['HK'],
|
|
19
|
+
// 300 requests per second => 1000ms / 300 = 3.333 (Trading: placing, replacing, deleting)
|
|
20
|
+
// 30 requests per second => ( 1000ms / rateLimit ) / 30 = cost = 10 (Market Data and other Public Requests)
|
|
21
|
+
// 20 requests per second => ( 1000ms / rateLimit ) / 20 = cost = 15 (All Other)
|
|
22
|
+
'rateLimit': 3.333,
|
|
23
|
+
'version': '3',
|
|
24
|
+
'has': {
|
|
25
|
+
'CORS': false,
|
|
26
|
+
'spot': true,
|
|
27
|
+
'margin': true,
|
|
28
|
+
'swap': true,
|
|
29
|
+
'future': false,
|
|
30
|
+
'option': undefined,
|
|
31
|
+
'addMargin': true,
|
|
32
|
+
'cancelAllOrders': true,
|
|
33
|
+
'cancelOrder': true,
|
|
34
|
+
'closePosition': false,
|
|
35
|
+
'createDepositAddress': true,
|
|
36
|
+
'createOrder': true,
|
|
37
|
+
'createPostOnlyOrder': true,
|
|
38
|
+
'createReduceOnlyOrder': true,
|
|
39
|
+
'createStopLimitOrder': true,
|
|
40
|
+
'createStopMarketOrder': true,
|
|
41
|
+
'createStopOrder': true,
|
|
42
|
+
'editOrder': true,
|
|
43
|
+
'fetchAccounts': false,
|
|
44
|
+
'fetchBalance': true,
|
|
45
|
+
'fetchBorrowRateHistories': undefined,
|
|
46
|
+
'fetchBorrowRateHistory': undefined,
|
|
47
|
+
'fetchClosedOrders': true,
|
|
48
|
+
'fetchCrossBorrowRate': false,
|
|
49
|
+
'fetchCrossBorrowRates': false,
|
|
50
|
+
'fetchCurrencies': true,
|
|
51
|
+
'fetchDepositAddress': true,
|
|
52
|
+
'fetchDeposits': true,
|
|
53
|
+
'fetchDepositsWithdrawals': true,
|
|
54
|
+
'fetchDepositWithdrawFee': 'emulated',
|
|
55
|
+
'fetchDepositWithdrawFees': true,
|
|
56
|
+
'fetchFundingHistory': undefined,
|
|
57
|
+
'fetchFundingRate': true,
|
|
58
|
+
'fetchFundingRateHistory': true,
|
|
59
|
+
'fetchFundingRates': true,
|
|
60
|
+
'fetchIndexOHLCV': true,
|
|
61
|
+
'fetchIsolatedBorrowRate': false,
|
|
62
|
+
'fetchIsolatedBorrowRates': false,
|
|
63
|
+
'fetchLeverage': true,
|
|
64
|
+
'fetchLeverageTiers': undefined,
|
|
65
|
+
'fetchLiquidations': false,
|
|
66
|
+
'fetchMarginMode': true,
|
|
67
|
+
'fetchMarketLeverageTiers': false,
|
|
68
|
+
'fetchMarkets': true,
|
|
69
|
+
'fetchMarkOHLCV': true,
|
|
70
|
+
'fetchMyLiquidations': false,
|
|
71
|
+
'fetchMyTrades': true,
|
|
72
|
+
'fetchOHLCV': true,
|
|
73
|
+
'fetchOpenInterest': true,
|
|
74
|
+
'fetchOpenInterestHistory': false,
|
|
75
|
+
'fetchOpenOrder': true,
|
|
76
|
+
'fetchOpenOrders': true,
|
|
77
|
+
'fetchOrder': true,
|
|
78
|
+
'fetchOrderBook': true,
|
|
79
|
+
'fetchOrderBooks': true,
|
|
80
|
+
'fetchOrders': false,
|
|
81
|
+
'fetchOrderTrades': true,
|
|
82
|
+
'fetchPosition': true,
|
|
83
|
+
'fetchPositions': true,
|
|
84
|
+
'fetchPremiumIndexOHLCV': true,
|
|
85
|
+
'fetchTicker': true,
|
|
86
|
+
'fetchTickers': true,
|
|
87
|
+
'fetchTrades': true,
|
|
88
|
+
'fetchTradingFee': true,
|
|
89
|
+
'fetchTradingFees': true,
|
|
90
|
+
'fetchTransactions': 'emulated',
|
|
91
|
+
'fetchWithdrawals': true,
|
|
92
|
+
'reduceMargin': true,
|
|
93
|
+
'setLeverage': true,
|
|
94
|
+
'setMargin': false,
|
|
95
|
+
'setMarginMode': false,
|
|
96
|
+
'setPositionMode': false,
|
|
97
|
+
'transfer': true,
|
|
98
|
+
'withdraw': true,
|
|
99
|
+
},
|
|
100
|
+
'precisionMode': number.TICK_SIZE,
|
|
101
|
+
'urls': {
|
|
102
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/27766555-8eaec20e-5edc-11e7-9c5b-6dc69fc42f5e.jpg',
|
|
103
|
+
'test': {
|
|
104
|
+
'public': 'https://api.demo.hitbtc.com/api/3',
|
|
105
|
+
'private': 'https://api.demo.hitbtc.com/api/3',
|
|
106
|
+
},
|
|
107
|
+
'api': {
|
|
108
|
+
'public': 'https://api.hitbtc.com/api/3',
|
|
109
|
+
'private': 'https://api.hitbtc.com/api/3',
|
|
110
|
+
},
|
|
111
|
+
'www': 'https://hitbtc.com',
|
|
112
|
+
'referral': 'https://hitbtc.com/?ref_id=5a5d39a65d466',
|
|
113
|
+
'doc': [
|
|
114
|
+
'https://api.hitbtc.com',
|
|
115
|
+
'https://github.com/hitbtc-com/hitbtc-api/blob/master/APIv2.md',
|
|
116
|
+
],
|
|
117
|
+
'fees': [
|
|
118
|
+
'https://hitbtc.com/fees-and-limits',
|
|
119
|
+
'https://support.hitbtc.com/hc/en-us/articles/115005148605-Fees-and-limits',
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
'api': {
|
|
123
|
+
'public': {
|
|
124
|
+
'get': {
|
|
125
|
+
'public/currency': 10,
|
|
126
|
+
'public/currency/{currency}': 10,
|
|
127
|
+
'public/symbol': 10,
|
|
128
|
+
'public/symbol/{symbol}': 10,
|
|
129
|
+
'public/ticker': 10,
|
|
130
|
+
'public/ticker/{symbol}': 10,
|
|
131
|
+
'public/price/rate': 10,
|
|
132
|
+
'public/price/history': 10,
|
|
133
|
+
'public/price/ticker': 10,
|
|
134
|
+
'public/price/ticker/{symbol}': 10,
|
|
135
|
+
'public/trades': 10,
|
|
136
|
+
'public/trades/{symbol}': 10,
|
|
137
|
+
'public/orderbook': 10,
|
|
138
|
+
'public/orderbook/{symbol}': 10,
|
|
139
|
+
'public/candles': 10,
|
|
140
|
+
'public/candles/{symbol}': 10,
|
|
141
|
+
'public/futures/info': 10,
|
|
142
|
+
'public/futures/info/{symbol}': 10,
|
|
143
|
+
'public/futures/history/funding': 10,
|
|
144
|
+
'public/futures/history/funding/{symbol}': 10,
|
|
145
|
+
'public/futures/candles/index_price': 10,
|
|
146
|
+
'public/futures/candles/index_price/{symbol}': 10,
|
|
147
|
+
'public/futures/candles/mark_price': 10,
|
|
148
|
+
'public/futures/candles/mark_price/{symbol}': 10,
|
|
149
|
+
'public/futures/candles/premium_index': 10,
|
|
150
|
+
'public/futures/candles/premium_index/{symbol}': 10,
|
|
151
|
+
'public/futures/candles/open_interest': 10,
|
|
152
|
+
'public/futures/candles/open_interest/{symbol}': 10,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
'private': {
|
|
156
|
+
'get': {
|
|
157
|
+
'spot/balance': 15,
|
|
158
|
+
'spot/balance/{currency}': 15,
|
|
159
|
+
'spot/order': 1,
|
|
160
|
+
'spot/order/{client_order_id}': 1,
|
|
161
|
+
'spot/fee': 15,
|
|
162
|
+
'spot/fee/{symbol}': 15,
|
|
163
|
+
'spot/history/order': 15,
|
|
164
|
+
'spot/history/trade': 15,
|
|
165
|
+
'margin/account': 1,
|
|
166
|
+
'margin/account/isolated/{symbol}': 1,
|
|
167
|
+
'margin/account/cross/{currency}': 1,
|
|
168
|
+
'margin/order': 1,
|
|
169
|
+
'margin/order/{client_order_id}': 1,
|
|
170
|
+
'margin/config': 15,
|
|
171
|
+
'margin/history/order': 15,
|
|
172
|
+
'margin/history/trade': 15,
|
|
173
|
+
'margin/history/positions': 15,
|
|
174
|
+
'margin/history/clearing': 15,
|
|
175
|
+
'futures/balance': 15,
|
|
176
|
+
'futures/balance/{currency}': 15,
|
|
177
|
+
'futures/account': 1,
|
|
178
|
+
'futures/account/isolated/{symbol}': 1,
|
|
179
|
+
'futures/order': 1,
|
|
180
|
+
'futures/order/{client_order_id}': 1,
|
|
181
|
+
'futures/config': 15,
|
|
182
|
+
'futures/fee': 15,
|
|
183
|
+
'futures/fee/{symbol}': 15,
|
|
184
|
+
'futures/history/order': 15,
|
|
185
|
+
'futures/history/trade': 15,
|
|
186
|
+
'futures/history/positions': 15,
|
|
187
|
+
'futures/history/clearing': 15,
|
|
188
|
+
'wallet/balance': 30,
|
|
189
|
+
'wallet/balance/{currency}': 30,
|
|
190
|
+
'wallet/crypto/address': 30,
|
|
191
|
+
'wallet/crypto/address/recent-deposit': 30,
|
|
192
|
+
'wallet/crypto/address/recent-withdraw': 30,
|
|
193
|
+
'wallet/crypto/address/check-mine': 30,
|
|
194
|
+
'wallet/transactions': 30,
|
|
195
|
+
'wallet/transactions/{tx_id}': 30,
|
|
196
|
+
'wallet/crypto/fee/estimate': 30,
|
|
197
|
+
'wallet/airdrops': 30,
|
|
198
|
+
'wallet/amount-locks': 30,
|
|
199
|
+
'sub-account': 15,
|
|
200
|
+
'sub-account/acl': 15,
|
|
201
|
+
'sub-account/balance/{subAccID}': 15,
|
|
202
|
+
'sub-account/crypto/address/{subAccID}/{currency}': 15,
|
|
203
|
+
},
|
|
204
|
+
'post': {
|
|
205
|
+
'spot/order': 1,
|
|
206
|
+
'spot/order/list': 1,
|
|
207
|
+
'margin/order': 1,
|
|
208
|
+
'margin/order/list': 1,
|
|
209
|
+
'futures/order': 1,
|
|
210
|
+
'futures/order/list': 1,
|
|
211
|
+
'wallet/crypto/address': 30,
|
|
212
|
+
'wallet/crypto/withdraw': 30,
|
|
213
|
+
'wallet/convert': 30,
|
|
214
|
+
'wallet/transfer': 30,
|
|
215
|
+
'wallet/internal/withdraw': 30,
|
|
216
|
+
'wallet/crypto/check-offchain-available': 30,
|
|
217
|
+
'wallet/crypto/fees/estimate': 30,
|
|
218
|
+
'wallet/airdrops/{id}/claim': 30,
|
|
219
|
+
'sub-account/freeze': 15,
|
|
220
|
+
'sub-account/activate': 15,
|
|
221
|
+
'sub-account/transfer': 15,
|
|
222
|
+
'sub-account/acl': 15,
|
|
223
|
+
},
|
|
224
|
+
'patch': {
|
|
225
|
+
'spot/order/{client_order_id}': 1,
|
|
226
|
+
'margin/order/{client_order_id}': 1,
|
|
227
|
+
'futures/order/{client_order_id}': 1,
|
|
228
|
+
},
|
|
229
|
+
'delete': {
|
|
230
|
+
'spot/order': 1,
|
|
231
|
+
'spot/order/{client_order_id}': 1,
|
|
232
|
+
'margin/position': 1,
|
|
233
|
+
'margin/position/isolated/{symbol}': 1,
|
|
234
|
+
'margin/order': 1,
|
|
235
|
+
'margin/order/{client_order_id}': 1,
|
|
236
|
+
'futures/position': 1,
|
|
237
|
+
'futures/position/{margin_mode}/{symbol}': 1,
|
|
238
|
+
'futures/order': 1,
|
|
239
|
+
'futures/order/{client_order_id}': 1,
|
|
240
|
+
'wallet/crypto/withdraw/{id}': 30,
|
|
241
|
+
},
|
|
242
|
+
'put': {
|
|
243
|
+
'margin/account/isolated/{symbol}': 1,
|
|
244
|
+
'futures/account/isolated/{symbol}': 1,
|
|
245
|
+
'wallet/crypto/withdraw/{id}': 30,
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
'fees': {
|
|
250
|
+
'trading': {
|
|
251
|
+
'tierBased': true,
|
|
252
|
+
'percentage': true,
|
|
253
|
+
'taker': this.parseNumber('0.0009'),
|
|
254
|
+
'maker': this.parseNumber('0.0009'),
|
|
255
|
+
'tiers': {
|
|
256
|
+
'maker': [
|
|
257
|
+
[this.parseNumber('0'), this.parseNumber('0.0009')],
|
|
258
|
+
[this.parseNumber('10'), this.parseNumber('0.0007')],
|
|
259
|
+
[this.parseNumber('100'), this.parseNumber('0.0006')],
|
|
260
|
+
[this.parseNumber('500'), this.parseNumber('0.0005')],
|
|
261
|
+
[this.parseNumber('1000'), this.parseNumber('0.0003')],
|
|
262
|
+
[this.parseNumber('5000'), this.parseNumber('0.0002')],
|
|
263
|
+
[this.parseNumber('10000'), this.parseNumber('0.0001')],
|
|
264
|
+
[this.parseNumber('20000'), this.parseNumber('0')],
|
|
265
|
+
[this.parseNumber('50000'), this.parseNumber('-0.0001')],
|
|
266
|
+
[this.parseNumber('100000'), this.parseNumber('-0.0001')],
|
|
267
|
+
],
|
|
268
|
+
'taker': [
|
|
269
|
+
[this.parseNumber('0'), this.parseNumber('0.0009')],
|
|
270
|
+
[this.parseNumber('10'), this.parseNumber('0.0008')],
|
|
271
|
+
[this.parseNumber('100'), this.parseNumber('0.0007')],
|
|
272
|
+
[this.parseNumber('500'), this.parseNumber('0.0007')],
|
|
273
|
+
[this.parseNumber('1000'), this.parseNumber('0.0006')],
|
|
274
|
+
[this.parseNumber('5000'), this.parseNumber('0.0006')],
|
|
275
|
+
[this.parseNumber('10000'), this.parseNumber('0.0005')],
|
|
276
|
+
[this.parseNumber('20000'), this.parseNumber('0.0004')],
|
|
277
|
+
[this.parseNumber('50000'), this.parseNumber('0.0003')],
|
|
278
|
+
[this.parseNumber('100000'), this.parseNumber('0.0002')],
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
'timeframes': {
|
|
284
|
+
'1m': 'M1',
|
|
285
|
+
'3m': 'M3',
|
|
286
|
+
'5m': 'M5',
|
|
287
|
+
'15m': 'M15',
|
|
288
|
+
'30m': 'M30',
|
|
289
|
+
'1h': 'H1',
|
|
290
|
+
'4h': 'H4',
|
|
291
|
+
'1d': 'D1',
|
|
292
|
+
'1w': 'D7',
|
|
293
|
+
'1M': '1M',
|
|
294
|
+
},
|
|
295
|
+
'exceptions': {
|
|
296
|
+
'exact': {
|
|
297
|
+
'429': errors.RateLimitExceeded,
|
|
298
|
+
'500': errors.ExchangeError,
|
|
299
|
+
'503': errors.ExchangeNotAvailable,
|
|
300
|
+
'504': errors.ExchangeNotAvailable,
|
|
301
|
+
'600': errors.PermissionDenied,
|
|
302
|
+
'800': errors.ExchangeError,
|
|
303
|
+
'1002': errors.AuthenticationError,
|
|
304
|
+
'1003': errors.PermissionDenied,
|
|
305
|
+
'1004': errors.AuthenticationError,
|
|
306
|
+
'1005': errors.AuthenticationError,
|
|
307
|
+
'2001': errors.BadSymbol,
|
|
308
|
+
'2002': errors.BadRequest,
|
|
309
|
+
'2003': errors.BadRequest,
|
|
310
|
+
'2010': errors.BadRequest,
|
|
311
|
+
'2011': errors.BadRequest,
|
|
312
|
+
'2012': errors.BadRequest,
|
|
313
|
+
'2020': errors.BadRequest,
|
|
314
|
+
'2022': errors.BadRequest,
|
|
315
|
+
'10001': errors.BadRequest,
|
|
316
|
+
'10021': errors.AccountSuspended,
|
|
317
|
+
'10022': errors.BadRequest,
|
|
318
|
+
'20001': errors.InsufficientFunds,
|
|
319
|
+
'20002': errors.OrderNotFound,
|
|
320
|
+
'20003': errors.ExchangeError,
|
|
321
|
+
'20004': errors.ExchangeError,
|
|
322
|
+
'20005': errors.ExchangeError,
|
|
323
|
+
'20006': errors.ExchangeError,
|
|
324
|
+
'20007': errors.ExchangeError,
|
|
325
|
+
'20008': errors.InvalidOrder,
|
|
326
|
+
'20009': errors.InvalidOrder,
|
|
327
|
+
'20010': errors.OnMaintenance,
|
|
328
|
+
'20011': errors.ExchangeError,
|
|
329
|
+
'20012': errors.ExchangeError,
|
|
330
|
+
'20014': errors.ExchangeError,
|
|
331
|
+
'20016': errors.ExchangeError,
|
|
332
|
+
'20031': errors.ExchangeError,
|
|
333
|
+
'20032': errors.ExchangeError,
|
|
334
|
+
'20033': errors.ExchangeError,
|
|
335
|
+
'20034': errors.ExchangeError,
|
|
336
|
+
'20040': errors.ExchangeError,
|
|
337
|
+
'20041': errors.ExchangeError,
|
|
338
|
+
'20042': errors.ExchangeError,
|
|
339
|
+
'20043': errors.ExchangeError,
|
|
340
|
+
'20044': errors.PermissionDenied,
|
|
341
|
+
'20045': errors.InvalidOrder,
|
|
342
|
+
'20080': errors.ExchangeError,
|
|
343
|
+
'21001': errors.ExchangeError,
|
|
344
|
+
'21003': errors.AccountSuspended,
|
|
345
|
+
'21004': errors.AccountSuspended,
|
|
346
|
+
},
|
|
347
|
+
'broad': {},
|
|
348
|
+
},
|
|
349
|
+
'options': {
|
|
350
|
+
'defaultNetwork': 'ERC20',
|
|
351
|
+
'defaultNetworks': {
|
|
352
|
+
'ETH': 'ETH',
|
|
353
|
+
'USDT': 'TRC20',
|
|
354
|
+
},
|
|
355
|
+
'networks': {
|
|
356
|
+
// mainnet network ids are in lowercase for BTC & ETH
|
|
357
|
+
'BTC': 'btc',
|
|
358
|
+
'OMNI': 'BTC',
|
|
359
|
+
'ETH': 'eth',
|
|
360
|
+
'ERC20': 'ETH',
|
|
361
|
+
'ETC': 'ETC',
|
|
362
|
+
'BEP20': 'BSC',
|
|
363
|
+
'TRC20': 'TRX',
|
|
364
|
+
// '': 'UGT',
|
|
365
|
+
'NEAR': 'NEAR',
|
|
366
|
+
// '': 'LWF',
|
|
367
|
+
'DGB': 'DGB',
|
|
368
|
+
// '': 'YOYOW',
|
|
369
|
+
'AE': 'AE',
|
|
370
|
+
// 'BCHABC': 'BCHABC',
|
|
371
|
+
// '': 'BCI',
|
|
372
|
+
// 'BYTECOIN': 'bcn',
|
|
373
|
+
'AR': 'AR',
|
|
374
|
+
// '': 'HPC',
|
|
375
|
+
'ADA': 'ADA',
|
|
376
|
+
// 'BELDEX': 'BDX',
|
|
377
|
+
// 'ARDOR': 'ARDR',
|
|
378
|
+
// 'NEBLIO': 'NEBL',
|
|
379
|
+
// '': 'DIM',
|
|
380
|
+
'CHZ': 'CHZ',
|
|
381
|
+
// '': 'BET',
|
|
382
|
+
// '': '8BT',
|
|
383
|
+
'ABBC': 'ABBC',
|
|
384
|
+
// '': 'ABTC',
|
|
385
|
+
// 'ACHAIN': 'ACT',
|
|
386
|
+
// '': 'ADK',
|
|
387
|
+
// '': 'AEON',
|
|
388
|
+
'ALGO': 'ALGO',
|
|
389
|
+
// 'AMBROSUS': 'AMB',
|
|
390
|
+
// '': 'APL',
|
|
391
|
+
'APT': 'APT',
|
|
392
|
+
// '': 'ARK',
|
|
393
|
+
// 'PIRATECHAIN': 'ARRR',
|
|
394
|
+
// '': 'ASP',
|
|
395
|
+
// '': 'ATB',
|
|
396
|
+
'ATOM': 'ATOM',
|
|
397
|
+
'AVAXC': 'AVAC',
|
|
398
|
+
'AVAXX': 'AVAX',
|
|
399
|
+
// '': 'AYA',
|
|
400
|
+
// '': 'B2G',
|
|
401
|
+
// '': 'B2X',
|
|
402
|
+
// '': 'BANANO',
|
|
403
|
+
// '': 'BCCF',
|
|
404
|
+
'BSV': 'BCHSV',
|
|
405
|
+
'BEP2': 'BNB',
|
|
406
|
+
// 'BOSON': 'BOS',
|
|
407
|
+
// '': 'BRL', // brazilian real
|
|
408
|
+
// '': 'BST',
|
|
409
|
+
// 'BITCOINADDITION': 'BTCADD',
|
|
410
|
+
// '': 'BTCP',
|
|
411
|
+
// 'SUPERBTC': 'SBTC',
|
|
412
|
+
// 'BITCOINVAULT': 'BTCV',
|
|
413
|
+
// 'BITCOINGOLD': 'BTG',
|
|
414
|
+
// 'BITCOINDIAMOND': 'BCD',
|
|
415
|
+
// 'BITCONNECT': 'BCC',
|
|
416
|
+
// '': 'BTM',
|
|
417
|
+
// 'BITSHARES_OLD': 'BTS',
|
|
418
|
+
// '': 'BTX',
|
|
419
|
+
// '': 'BWI',
|
|
420
|
+
'CELO': 'CELO',
|
|
421
|
+
// '': 'CENNZ',
|
|
422
|
+
// '': 'CHX',
|
|
423
|
+
'CKB': 'CKB',
|
|
424
|
+
// 'CALLISTO': 'CLO',
|
|
425
|
+
// '': 'CLR',
|
|
426
|
+
// '': 'CNX',
|
|
427
|
+
// '': 'CRS',
|
|
428
|
+
// '': 'CSOV',
|
|
429
|
+
'CTXC': 'CTXC',
|
|
430
|
+
// '': 'CURE',
|
|
431
|
+
// 'CONSTELLATION': 'DAG',
|
|
432
|
+
// '': 'DAPS',
|
|
433
|
+
'DASH': 'DASH',
|
|
434
|
+
// '': 'DBIX',
|
|
435
|
+
'DCR': 'DCR',
|
|
436
|
+
// '': 'DCT',
|
|
437
|
+
// '': 'DDR',
|
|
438
|
+
// '': 'DNA',
|
|
439
|
+
'DOGE': 'doge',
|
|
440
|
+
// 'POLKADOT': 'DOT',
|
|
441
|
+
// '': 'NEWDOT', POLKADOT NEW
|
|
442
|
+
// '': 'dsh',
|
|
443
|
+
// '': 'ECA',
|
|
444
|
+
// '': 'ECOIN',
|
|
445
|
+
// '': 'EEX',
|
|
446
|
+
'EGLD': 'EGLD',
|
|
447
|
+
// '': 'ELE',
|
|
448
|
+
// 'ELECTRONEUM': 'Electroneum',
|
|
449
|
+
// '': 'ELM',
|
|
450
|
+
// '': 'EMC',
|
|
451
|
+
'EOS': 'EOS',
|
|
452
|
+
// 'AERGO': 'ERG',
|
|
453
|
+
'ETHW': 'ETHW',
|
|
454
|
+
// 'ETHERLITE': 'ETL',
|
|
455
|
+
// '': 'ETP', // metaverse etp
|
|
456
|
+
// '': 'EUNO',
|
|
457
|
+
'EVER': 'EVER',
|
|
458
|
+
// '': 'EXP',
|
|
459
|
+
// '': 'fcn',
|
|
460
|
+
'FET': 'FET',
|
|
461
|
+
'FIL': 'FIL',
|
|
462
|
+
// '': 'FIRO',
|
|
463
|
+
'FLOW': 'FLOW',
|
|
464
|
+
// '': 'G999',
|
|
465
|
+
// '': 'GAME',
|
|
466
|
+
// '': 'GASP',
|
|
467
|
+
// '': 'GBX',
|
|
468
|
+
// '': 'GHOST',
|
|
469
|
+
// '': 'GLEEC',
|
|
470
|
+
'GLMR': 'GLMR',
|
|
471
|
+
// '': 'GMD',
|
|
472
|
+
// '': 'GRAPH',
|
|
473
|
+
'GRIN': 'GRIN',
|
|
474
|
+
'HBAR': 'HBAR',
|
|
475
|
+
// '': 'HDG',
|
|
476
|
+
'HIVE': 'HIVE',
|
|
477
|
+
// 'HARBOR': 'HRB',
|
|
478
|
+
// '': 'HSR',
|
|
479
|
+
// '': 'HTML',
|
|
480
|
+
'HYDRA': 'HYDRA',
|
|
481
|
+
'ICP': 'ICP',
|
|
482
|
+
'ICX': 'ICX',
|
|
483
|
+
// '': 'IML',
|
|
484
|
+
'IOST': 'IOST',
|
|
485
|
+
'IOTA': 'IOTA',
|
|
486
|
+
'IOTX': 'IOTX',
|
|
487
|
+
// '': 'IQ',
|
|
488
|
+
'KAVA': 'KAVA',
|
|
489
|
+
'KLAY': 'KIM',
|
|
490
|
+
'KOMODO': 'KMD',
|
|
491
|
+
// '': 'KRM',
|
|
492
|
+
'KSM': 'KSM',
|
|
493
|
+
// '': 'LAVA',
|
|
494
|
+
// 'LITECOINCASH': 'LCC',
|
|
495
|
+
'LSK': 'LSK',
|
|
496
|
+
// '': 'LOC',
|
|
497
|
+
'LTC': 'ltc',
|
|
498
|
+
// '': 'LTNM',
|
|
499
|
+
// 'TERRACLASSIC': 'LUNA',
|
|
500
|
+
// 'TERRA': 'LUNANEW',
|
|
501
|
+
// '': 'MAN',
|
|
502
|
+
// '': 'MESH',
|
|
503
|
+
'MINA': 'MINA',
|
|
504
|
+
// '': 'MNX',
|
|
505
|
+
// 'MOBILECOIN': 'MOB',
|
|
506
|
+
'MOVR': 'MOVR',
|
|
507
|
+
// '': 'MPK',
|
|
508
|
+
// '': 'MRV',
|
|
509
|
+
'NANO': 'NANO',
|
|
510
|
+
// '': 'NAV',
|
|
511
|
+
'NEO': 'NEO',
|
|
512
|
+
// 'NIMIQ': 'NIM',
|
|
513
|
+
// '': 'NJBC',
|
|
514
|
+
// '': 'NKN',
|
|
515
|
+
// '': 'NLC2',
|
|
516
|
+
// '': 'NOF',
|
|
517
|
+
// 'ENERGI': 'NRG',
|
|
518
|
+
// '': 'nxt',
|
|
519
|
+
// '': 'ODN',
|
|
520
|
+
'ONE': 'ONE',
|
|
521
|
+
// 'ONTOLOGYGAS': 'ONG',
|
|
522
|
+
'ONT': 'ONT',
|
|
523
|
+
'OPTIMISM': 'OP',
|
|
524
|
+
// '': 'PAD',
|
|
525
|
+
// '': 'PART',
|
|
526
|
+
// '': 'PBKX',
|
|
527
|
+
// '': 'PLC',
|
|
528
|
+
'PLCU': 'PLCU',
|
|
529
|
+
// '': 'PLI',
|
|
530
|
+
// '': 'POA',
|
|
531
|
+
'MATIC': 'POLYGON',
|
|
532
|
+
// '': 'PPC',
|
|
533
|
+
// '': 'PQT',
|
|
534
|
+
// '': 'PROC',
|
|
535
|
+
// 'PASTEL': 'PSL',
|
|
536
|
+
// '': 'qcn',
|
|
537
|
+
'QTUM': 'QTUM',
|
|
538
|
+
// '': 'RCOIN',
|
|
539
|
+
'REI': 'REI',
|
|
540
|
+
// '': 'RIF',
|
|
541
|
+
// '': 'ROOTS',
|
|
542
|
+
'OASIS': 'ROSE',
|
|
543
|
+
// '': 'RPX',
|
|
544
|
+
// '': 'RUB',
|
|
545
|
+
'RVN': 'RVN',
|
|
546
|
+
// '': 'SBD',
|
|
547
|
+
'SC': 'SC',
|
|
548
|
+
'SCRT': 'SCRT',
|
|
549
|
+
// '': 'SLX',
|
|
550
|
+
// 'SMARTMESH': 'SMART',
|
|
551
|
+
// '': 'SMT',
|
|
552
|
+
// '': 'SNM',
|
|
553
|
+
'SOL': 'SOL',
|
|
554
|
+
// '': 'SRX',
|
|
555
|
+
// '': 'STAK',
|
|
556
|
+
'STEEM': 'STEEM',
|
|
557
|
+
// 'STRATIS': 'STRAT',
|
|
558
|
+
// '': 'TCN',
|
|
559
|
+
// '': 'TENT',
|
|
560
|
+
'THETA': 'Theta',
|
|
561
|
+
// '': 'TIV',
|
|
562
|
+
// '': 'TNC',
|
|
563
|
+
// 'TON': 'TONCOIN',
|
|
564
|
+
'TRUE': 'TRUE',
|
|
565
|
+
// '': 'TRY', // turkish lira
|
|
566
|
+
// '': 'UNO',
|
|
567
|
+
// '': 'USNOTA',
|
|
568
|
+
// '': 'VEO',
|
|
569
|
+
'VET': 'VET',
|
|
570
|
+
// '': 'VITAE',
|
|
571
|
+
// 'VELAS': 'VLX',
|
|
572
|
+
'VSYS': 'VSYS',
|
|
573
|
+
// '': 'VTC',
|
|
574
|
+
'WAVES': 'WAVES',
|
|
575
|
+
'WAX': 'WAX',
|
|
576
|
+
// '': 'WEALTH',
|
|
577
|
+
// 'WALTONCHAIN': 'WTC',
|
|
578
|
+
// '': 'WTT',
|
|
579
|
+
'XCH': 'XCH',
|
|
580
|
+
// '': 'XDC', // xinfin?
|
|
581
|
+
// '': 'xdn',
|
|
582
|
+
// '': 'XDNCO',
|
|
583
|
+
// '': 'XDNICCO',
|
|
584
|
+
'XEC': 'XEC',
|
|
585
|
+
'NEM': 'XEM',
|
|
586
|
+
// 'HAVEN': 'XHV',
|
|
587
|
+
// '': 'XLC',
|
|
588
|
+
'XLM': 'XLM',
|
|
589
|
+
// '': 'XMO',
|
|
590
|
+
'XMR': 'xmr',
|
|
591
|
+
// 'MONEROCLASSIC': 'XMC',
|
|
592
|
+
// '': 'XNS',
|
|
593
|
+
// '': 'XPRM',
|
|
594
|
+
// '': 'XRC',
|
|
595
|
+
'XRD': 'XRD',
|
|
596
|
+
'XRP': 'XRP',
|
|
597
|
+
'XTZ': 'XTZ',
|
|
598
|
+
'XVG': 'XVG',
|
|
599
|
+
'XYM': 'XYM',
|
|
600
|
+
'ZEC': 'ZEC',
|
|
601
|
+
'ZEN': 'ZEN',
|
|
602
|
+
'ZIL': 'ZIL',
|
|
603
|
+
// '': 'ZYN',
|
|
604
|
+
},
|
|
605
|
+
'accountsByType': {
|
|
606
|
+
'spot': 'spot',
|
|
607
|
+
'funding': 'wallet',
|
|
608
|
+
'future': 'derivatives',
|
|
609
|
+
},
|
|
610
|
+
'withdraw': {
|
|
611
|
+
'includeFee': false,
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
'commonCurrencies': {
|
|
615
|
+
'AUTO': 'Cube',
|
|
616
|
+
'BCC': 'BCC',
|
|
617
|
+
'BDP': 'BidiPass',
|
|
618
|
+
'BET': 'DAO.Casino',
|
|
619
|
+
'BIT': 'BitRewards',
|
|
620
|
+
'BOX': 'BOX Token',
|
|
621
|
+
'CPT': 'Cryptaur',
|
|
622
|
+
'GET': 'Themis',
|
|
623
|
+
'GMT': 'GMT Token',
|
|
624
|
+
'HSR': 'HC',
|
|
625
|
+
'IQ': 'IQ.Cash',
|
|
626
|
+
'LNC': 'LinkerCoin',
|
|
627
|
+
'PLA': 'PlayChip',
|
|
628
|
+
'PNT': 'Penta',
|
|
629
|
+
'SBTC': 'Super Bitcoin',
|
|
630
|
+
'STEPN': 'GMT',
|
|
631
|
+
'STX': 'STOX',
|
|
632
|
+
'TV': 'Tokenville',
|
|
633
|
+
'XMT': 'MTL',
|
|
634
|
+
'XPNT': 'PNT',
|
|
635
|
+
},
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
nonce() {
|
|
639
|
+
return this.milliseconds();
|
|
640
|
+
}
|
|
641
|
+
async fetchMarkets(params = {}) {
|
|
642
|
+
/**
|
|
643
|
+
* @method
|
|
644
|
+
* @name hitbtc#fetchMarkets
|
|
645
|
+
* @description retrieves data on all markets for hitbtc
|
|
646
|
+
* @see https://api.hitbtc.com/#symbols
|
|
647
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
648
|
+
* @returns {object[]} an array of objects representing market data
|
|
649
|
+
*/
|
|
650
|
+
const response = await this.publicGetPublicSymbol(params);
|
|
651
|
+
//
|
|
652
|
+
// {
|
|
653
|
+
// "AAVEUSDT_PERP":{
|
|
654
|
+
// "type":"futures",
|
|
655
|
+
// "expiry":null,
|
|
656
|
+
// "underlying":"AAVE",
|
|
657
|
+
// "base_currency":null,
|
|
658
|
+
// "quote_currency":"USDT",
|
|
659
|
+
// "quantity_increment":"0.01",
|
|
660
|
+
// "tick_size":"0.001",
|
|
661
|
+
// "take_rate":"0.0005",
|
|
662
|
+
// "make_rate":"0.0002",
|
|
663
|
+
// "fee_currency":"USDT",
|
|
664
|
+
// "margin_trading":true,
|
|
665
|
+
// "max_initial_leverage":"50.00"
|
|
666
|
+
// },
|
|
667
|
+
// "MANAUSDT":{
|
|
668
|
+
// "type":"spot",
|
|
669
|
+
// "base_currency":"MANA",
|
|
670
|
+
// "quote_currency":"USDT",
|
|
671
|
+
// "quantity_increment":"1",
|
|
672
|
+
// "tick_size":"0.0000001",
|
|
673
|
+
// "take_rate":"0.0025",
|
|
674
|
+
// "make_rate":"0.001",
|
|
675
|
+
// "fee_currency":"USDT",
|
|
676
|
+
// "margin_trading":true,
|
|
677
|
+
// "max_initial_leverage":"5.00"
|
|
678
|
+
// },
|
|
679
|
+
// }
|
|
680
|
+
//
|
|
681
|
+
const result = [];
|
|
682
|
+
const ids = Object.keys(response);
|
|
683
|
+
for (let i = 0; i < ids.length; i++) {
|
|
684
|
+
const id = ids[i];
|
|
685
|
+
if (id.endsWith('_BQX')) {
|
|
686
|
+
continue; // seems like an invalid symbol and if we try to access it individually we get: {"timestamp":"2023-09-02T14:38:20.351Z","error":{"description":"Try get /public/symbol, to get list of all available symbols.","code":2001,"message":"No such symbol: EOSUSD_BQX"},"path":"/api/3/public/symbol/EOSUSD_BQX","requestId":"e1e9fce6-16374591"}
|
|
687
|
+
}
|
|
688
|
+
const market = this.safeValue(response, id);
|
|
689
|
+
const marketType = this.safeString(market, 'type');
|
|
690
|
+
const expiry = this.safeInteger(market, 'expiry');
|
|
691
|
+
const contract = (marketType === 'futures');
|
|
692
|
+
const spot = (marketType === 'spot');
|
|
693
|
+
const marginTrading = this.safeValue(market, 'margin_trading', false);
|
|
694
|
+
const margin = spot && marginTrading;
|
|
695
|
+
const future = (expiry !== undefined);
|
|
696
|
+
const swap = (contract && !future);
|
|
697
|
+
const option = false;
|
|
698
|
+
const baseId = this.safeString2(market, 'base_currency', 'underlying');
|
|
699
|
+
const quoteId = this.safeString(market, 'quote_currency');
|
|
700
|
+
const feeCurrencyId = this.safeString(market, 'fee_currency');
|
|
701
|
+
const base = this.safeCurrencyCode(baseId);
|
|
702
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
703
|
+
const feeCurrency = this.safeCurrencyCode(feeCurrencyId);
|
|
704
|
+
let settleId = undefined;
|
|
705
|
+
let settle = undefined;
|
|
706
|
+
let symbol = base + '/' + quote;
|
|
707
|
+
let type = 'spot';
|
|
708
|
+
let contractSize = undefined;
|
|
709
|
+
let linear = undefined;
|
|
710
|
+
let inverse = undefined;
|
|
711
|
+
if (contract) {
|
|
712
|
+
contractSize = this.parseNumber('1');
|
|
713
|
+
settleId = feeCurrencyId;
|
|
714
|
+
settle = this.safeCurrencyCode(settleId);
|
|
715
|
+
linear = ((quote !== undefined) && (quote === settle));
|
|
716
|
+
inverse = !linear;
|
|
717
|
+
symbol = symbol + ':' + settle;
|
|
718
|
+
if (future) {
|
|
719
|
+
symbol = symbol + '-' + expiry;
|
|
720
|
+
type = 'future';
|
|
721
|
+
}
|
|
722
|
+
else {
|
|
723
|
+
type = 'swap';
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
const lotString = this.safeString(market, 'quantity_increment');
|
|
727
|
+
const stepString = this.safeString(market, 'tick_size');
|
|
728
|
+
const lot = this.parseNumber(lotString);
|
|
729
|
+
const step = this.parseNumber(stepString);
|
|
730
|
+
result.push({
|
|
731
|
+
'id': id,
|
|
732
|
+
'symbol': symbol,
|
|
733
|
+
'base': base,
|
|
734
|
+
'quote': quote,
|
|
735
|
+
'settle': settle,
|
|
736
|
+
'baseId': baseId,
|
|
737
|
+
'quoteId': quoteId,
|
|
738
|
+
'settleId': settleId,
|
|
739
|
+
'type': type,
|
|
740
|
+
'spot': spot,
|
|
741
|
+
'margin': margin,
|
|
742
|
+
'swap': swap,
|
|
743
|
+
'future': future,
|
|
744
|
+
'option': option,
|
|
745
|
+
'active': true,
|
|
746
|
+
'contract': contract,
|
|
747
|
+
'linear': linear,
|
|
748
|
+
'inverse': inverse,
|
|
749
|
+
'taker': this.safeNumber(market, 'take_rate'),
|
|
750
|
+
'maker': this.safeNumber(market, 'make_rate'),
|
|
751
|
+
'contractSize': contractSize,
|
|
752
|
+
'expiry': expiry,
|
|
753
|
+
'expiryDatetime': undefined,
|
|
754
|
+
'strike': undefined,
|
|
755
|
+
'optionType': undefined,
|
|
756
|
+
'feeCurrency': feeCurrency,
|
|
757
|
+
'precision': {
|
|
758
|
+
'amount': lot,
|
|
759
|
+
'price': step,
|
|
760
|
+
},
|
|
761
|
+
'limits': {
|
|
762
|
+
'leverage': {
|
|
763
|
+
'min': this.parseNumber('1'),
|
|
764
|
+
'max': this.safeNumber(market, 'max_initial_leverage', 1),
|
|
765
|
+
},
|
|
766
|
+
'amount': {
|
|
767
|
+
'min': lot,
|
|
768
|
+
'max': undefined,
|
|
769
|
+
},
|
|
770
|
+
'price': {
|
|
771
|
+
'min': step,
|
|
772
|
+
'max': undefined,
|
|
773
|
+
},
|
|
774
|
+
'cost': {
|
|
775
|
+
'min': this.parseNumber(Precise["default"].stringMul(lotString, stepString)),
|
|
776
|
+
'max': undefined,
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
'created': undefined,
|
|
780
|
+
'info': market,
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
return result;
|
|
784
|
+
}
|
|
785
|
+
async fetchCurrencies(params = {}) {
|
|
786
|
+
/**
|
|
787
|
+
* @method
|
|
788
|
+
* @name hitbtc#fetchCurrencies
|
|
789
|
+
* @description fetches all available currencies on an exchange
|
|
790
|
+
* @see https://api.hitbtc.com/#currencies
|
|
791
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
792
|
+
* @returns {object} an associative dictionary of currencies
|
|
793
|
+
*/
|
|
794
|
+
const response = await this.publicGetPublicCurrency(params);
|
|
795
|
+
//
|
|
796
|
+
// {
|
|
797
|
+
// "WEALTH": {
|
|
798
|
+
// "full_name": "ConnectWealth",
|
|
799
|
+
// "payin_enabled": false,
|
|
800
|
+
// "payout_enabled": false,
|
|
801
|
+
// "transfer_enabled": true,
|
|
802
|
+
// "precision_transfer": "0.001",
|
|
803
|
+
// "networks": [
|
|
804
|
+
// {
|
|
805
|
+
// "network": "ETH",
|
|
806
|
+
// "protocol": "ERC20",
|
|
807
|
+
// "default": true,
|
|
808
|
+
// "payin_enabled": false,
|
|
809
|
+
// "payout_enabled": false,
|
|
810
|
+
// "precision_payout": "0.001",
|
|
811
|
+
// "payout_fee": "0.016800000000",
|
|
812
|
+
// "payout_is_payment_id": false,
|
|
813
|
+
// "payin_payment_id": false,
|
|
814
|
+
// "payin_confirmations": "2"
|
|
815
|
+
// }
|
|
816
|
+
// ]
|
|
817
|
+
// }
|
|
818
|
+
// }
|
|
819
|
+
//
|
|
820
|
+
const result = {};
|
|
821
|
+
const currencies = Object.keys(response);
|
|
822
|
+
for (let i = 0; i < currencies.length; i++) {
|
|
823
|
+
const currencyId = currencies[i];
|
|
824
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
825
|
+
const entry = response[currencyId];
|
|
826
|
+
const name = this.safeString(entry, 'full_name');
|
|
827
|
+
const precision = this.safeNumber(entry, 'precision_transfer');
|
|
828
|
+
const payinEnabled = this.safeValue(entry, 'payin_enabled', false);
|
|
829
|
+
const payoutEnabled = this.safeValue(entry, 'payout_enabled', false);
|
|
830
|
+
const transferEnabled = this.safeValue(entry, 'transfer_enabled', false);
|
|
831
|
+
const active = payinEnabled && payoutEnabled && transferEnabled;
|
|
832
|
+
const rawNetworks = this.safeValue(entry, 'networks', []);
|
|
833
|
+
const networks = {};
|
|
834
|
+
let fee = undefined;
|
|
835
|
+
let depositEnabled = undefined;
|
|
836
|
+
let withdrawEnabled = undefined;
|
|
837
|
+
for (let j = 0; j < rawNetworks.length; j++) {
|
|
838
|
+
const rawNetwork = rawNetworks[j];
|
|
839
|
+
const networkId = this.safeString2(rawNetwork, 'protocol', 'network');
|
|
840
|
+
const network = this.safeNetwork(networkId);
|
|
841
|
+
fee = this.safeNumber(rawNetwork, 'payout_fee');
|
|
842
|
+
const networkPrecision = this.safeNumber(rawNetwork, 'precision_payout');
|
|
843
|
+
const payinEnabledNetwork = this.safeValue(entry, 'payin_enabled', false);
|
|
844
|
+
const payoutEnabledNetwork = this.safeValue(entry, 'payout_enabled', false);
|
|
845
|
+
const activeNetwork = payinEnabledNetwork && payoutEnabledNetwork;
|
|
846
|
+
if (payinEnabledNetwork && !depositEnabled) {
|
|
847
|
+
depositEnabled = true;
|
|
848
|
+
}
|
|
849
|
+
else if (!payinEnabledNetwork) {
|
|
850
|
+
depositEnabled = false;
|
|
851
|
+
}
|
|
852
|
+
if (payoutEnabledNetwork && !withdrawEnabled) {
|
|
853
|
+
withdrawEnabled = true;
|
|
854
|
+
}
|
|
855
|
+
else if (!payoutEnabledNetwork) {
|
|
856
|
+
withdrawEnabled = false;
|
|
857
|
+
}
|
|
858
|
+
networks[network] = {
|
|
859
|
+
'info': rawNetwork,
|
|
860
|
+
'id': networkId,
|
|
861
|
+
'network': network,
|
|
862
|
+
'fee': fee,
|
|
863
|
+
'active': activeNetwork,
|
|
864
|
+
'deposit': payinEnabledNetwork,
|
|
865
|
+
'withdraw': payoutEnabledNetwork,
|
|
866
|
+
'precision': networkPrecision,
|
|
867
|
+
'limits': {
|
|
868
|
+
'withdraw': {
|
|
869
|
+
'min': undefined,
|
|
870
|
+
'max': undefined,
|
|
871
|
+
},
|
|
872
|
+
},
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
const networksKeys = Object.keys(networks);
|
|
876
|
+
const networksLength = networksKeys.length;
|
|
877
|
+
result[code] = {
|
|
878
|
+
'info': entry,
|
|
879
|
+
'code': code,
|
|
880
|
+
'id': currencyId,
|
|
881
|
+
'precision': precision,
|
|
882
|
+
'name': name,
|
|
883
|
+
'active': active,
|
|
884
|
+
'deposit': depositEnabled,
|
|
885
|
+
'withdraw': withdrawEnabled,
|
|
886
|
+
'networks': networks,
|
|
887
|
+
'fee': (networksLength <= 1) ? fee : undefined,
|
|
888
|
+
'limits': {
|
|
889
|
+
'amount': {
|
|
890
|
+
'min': undefined,
|
|
891
|
+
'max': undefined,
|
|
892
|
+
},
|
|
893
|
+
},
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
return result;
|
|
897
|
+
}
|
|
898
|
+
safeNetwork(networkId) {
|
|
899
|
+
if (networkId === undefined) {
|
|
900
|
+
return undefined;
|
|
901
|
+
}
|
|
902
|
+
else {
|
|
903
|
+
return networkId.toUpperCase();
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
async createDepositAddress(code, params = {}) {
|
|
907
|
+
/**
|
|
908
|
+
* @method
|
|
909
|
+
* @name hitbtc#createDepositAddress
|
|
910
|
+
* @description create a currency deposit address
|
|
911
|
+
* @see https://api.hitbtc.com/#generate-deposit-crypto-address
|
|
912
|
+
* @param {string} code unified currency code of the currency for the deposit address
|
|
913
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
914
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
915
|
+
*/
|
|
916
|
+
await this.loadMarkets();
|
|
917
|
+
const currency = this.currency(code);
|
|
918
|
+
const request = {
|
|
919
|
+
'currency': currency['id'],
|
|
920
|
+
};
|
|
921
|
+
const network = this.safeStringUpper(params, 'network');
|
|
922
|
+
if ((network !== undefined) && (code === 'USDT')) {
|
|
923
|
+
const networks = this.safeValue(this.options, 'networks');
|
|
924
|
+
const parsedNetwork = this.safeString(networks, network);
|
|
925
|
+
if (parsedNetwork !== undefined) {
|
|
926
|
+
request['currency'] = parsedNetwork;
|
|
927
|
+
}
|
|
928
|
+
params = this.omit(params, 'network');
|
|
929
|
+
}
|
|
930
|
+
const response = await this.privatePostWalletCryptoAddress(this.extend(request, params));
|
|
931
|
+
//
|
|
932
|
+
// {"currency":"ETH","address":"0xd0d9aea60c41988c3e68417e2616065617b7afd3"}
|
|
933
|
+
//
|
|
934
|
+
const currencyId = this.safeString(response, 'currency');
|
|
935
|
+
return {
|
|
936
|
+
'currency': this.safeCurrencyCode(currencyId),
|
|
937
|
+
'address': this.safeString(response, 'address'),
|
|
938
|
+
'tag': this.safeString(response, 'payment_id'),
|
|
939
|
+
'network': undefined,
|
|
940
|
+
'info': response,
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
async fetchDepositAddress(code, params = {}) {
|
|
944
|
+
/**
|
|
945
|
+
* @method
|
|
946
|
+
* @name hitbtc#fetchDepositAddress
|
|
947
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
948
|
+
* @see https://api.hitbtc.com/#get-deposit-crypto-address
|
|
949
|
+
* @param {string} code unified currency code
|
|
950
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
951
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
952
|
+
*/
|
|
953
|
+
await this.loadMarkets();
|
|
954
|
+
const currency = this.currency(code);
|
|
955
|
+
const request = {
|
|
956
|
+
'currency': currency['id'],
|
|
957
|
+
};
|
|
958
|
+
const network = this.safeStringUpper(params, 'network');
|
|
959
|
+
if ((network !== undefined) && (code === 'USDT')) {
|
|
960
|
+
const networks = this.safeValue(this.options, 'networks');
|
|
961
|
+
const parsedNetwork = this.safeString(networks, network);
|
|
962
|
+
if (parsedNetwork !== undefined) {
|
|
963
|
+
request['currency'] = parsedNetwork;
|
|
964
|
+
}
|
|
965
|
+
params = this.omit(params, 'network');
|
|
966
|
+
}
|
|
967
|
+
const response = await this.privateGetWalletCryptoAddress(this.extend(request, params));
|
|
968
|
+
//
|
|
969
|
+
// [{"currency":"ETH","address":"0xd0d9aea60c41988c3e68417e2616065617b7afd3"}]
|
|
970
|
+
//
|
|
971
|
+
const firstAddress = this.safeValue(response, 0);
|
|
972
|
+
const address = this.safeString(firstAddress, 'address');
|
|
973
|
+
const currencyId = this.safeString(firstAddress, 'currency');
|
|
974
|
+
const tag = this.safeString(firstAddress, 'payment_id');
|
|
975
|
+
const parsedCode = this.safeCurrencyCode(currencyId);
|
|
976
|
+
return {
|
|
977
|
+
'info': response,
|
|
978
|
+
'address': address,
|
|
979
|
+
'tag': tag,
|
|
980
|
+
'code': parsedCode,
|
|
981
|
+
'currency': parsedCode,
|
|
982
|
+
'network': undefined,
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
parseBalance(response) {
|
|
986
|
+
const result = { 'info': response };
|
|
987
|
+
for (let i = 0; i < response.length; i++) {
|
|
988
|
+
const entry = response[i];
|
|
989
|
+
const currencyId = this.safeString(entry, 'currency');
|
|
990
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
991
|
+
const account = this.account();
|
|
992
|
+
account['free'] = this.safeString(entry, 'available');
|
|
993
|
+
account['used'] = this.safeString(entry, 'reserved');
|
|
994
|
+
result[code] = account;
|
|
995
|
+
}
|
|
996
|
+
return this.safeBalance(result);
|
|
997
|
+
}
|
|
998
|
+
async fetchBalance(params = {}) {
|
|
999
|
+
/**
|
|
1000
|
+
* @method
|
|
1001
|
+
* @name hitbtc#fetchBalance
|
|
1002
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1003
|
+
* @see https://api.hitbtc.com/#wallet-balance
|
|
1004
|
+
* @see https://api.hitbtc.com/#get-spot-trading-balance
|
|
1005
|
+
* @see https://api.hitbtc.com/#get-trading-balance
|
|
1006
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1007
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1008
|
+
*/
|
|
1009
|
+
const type = this.safeStringLower(params, 'type', 'spot');
|
|
1010
|
+
params = this.omit(params, ['type']);
|
|
1011
|
+
const accountsByType = this.safeValue(this.options, 'accountsByType', {});
|
|
1012
|
+
const account = this.safeString(accountsByType, type, type);
|
|
1013
|
+
let response = undefined;
|
|
1014
|
+
if (account === 'wallet') {
|
|
1015
|
+
response = await this.privateGetWalletBalance(params);
|
|
1016
|
+
}
|
|
1017
|
+
else if (account === 'spot') {
|
|
1018
|
+
response = await this.privateGetSpotBalance(params);
|
|
1019
|
+
}
|
|
1020
|
+
else if (account === 'derivatives') {
|
|
1021
|
+
response = await this.privateGetFuturesBalance(params);
|
|
1022
|
+
}
|
|
1023
|
+
else {
|
|
1024
|
+
const keys = Object.keys(accountsByType);
|
|
1025
|
+
throw new errors.BadRequest(this.id + ' fetchBalance() type parameter must be one of ' + keys.join(', '));
|
|
1026
|
+
}
|
|
1027
|
+
//
|
|
1028
|
+
// [
|
|
1029
|
+
// {
|
|
1030
|
+
// "currency": "PAXG",
|
|
1031
|
+
// "available": "0",
|
|
1032
|
+
// "reserved": "0",
|
|
1033
|
+
// "reserved_margin": "0",
|
|
1034
|
+
// },
|
|
1035
|
+
// ...
|
|
1036
|
+
// ]
|
|
1037
|
+
//
|
|
1038
|
+
return this.parseBalance(response);
|
|
1039
|
+
}
|
|
1040
|
+
async fetchTicker(symbol, params = {}) {
|
|
1041
|
+
/**
|
|
1042
|
+
* @method
|
|
1043
|
+
* @name hitbtc#fetchTicker
|
|
1044
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1045
|
+
* @see https://api.hitbtc.com/#tickers
|
|
1046
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1047
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1048
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1049
|
+
*/
|
|
1050
|
+
await this.loadMarkets();
|
|
1051
|
+
const market = this.market(symbol);
|
|
1052
|
+
const request = {
|
|
1053
|
+
'symbol': market['id'],
|
|
1054
|
+
};
|
|
1055
|
+
const response = await this.publicGetPublicTickerSymbol(this.extend(request, params));
|
|
1056
|
+
//
|
|
1057
|
+
// {
|
|
1058
|
+
// "ask": "0.020572",
|
|
1059
|
+
// "bid": "0.020566",
|
|
1060
|
+
// "last": "0.020574",
|
|
1061
|
+
// "low": "0.020388",
|
|
1062
|
+
// "high": "0.021084",
|
|
1063
|
+
// "open": "0.020913",
|
|
1064
|
+
// "volume": "138444.3666",
|
|
1065
|
+
// "volume_quote": "2853.6874972480",
|
|
1066
|
+
// "timestamp": "2021-06-02T17:52:36.731Z"
|
|
1067
|
+
// }
|
|
1068
|
+
//
|
|
1069
|
+
return this.parseTicker(response, market);
|
|
1070
|
+
}
|
|
1071
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
1072
|
+
/**
|
|
1073
|
+
* @method
|
|
1074
|
+
* @name hitbtc#fetchTickers
|
|
1075
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1076
|
+
* @see https://api.hitbtc.com/#tickers
|
|
1077
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1078
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1079
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1080
|
+
*/
|
|
1081
|
+
await this.loadMarkets();
|
|
1082
|
+
symbols = this.marketSymbols(symbols);
|
|
1083
|
+
const request = {};
|
|
1084
|
+
if (symbols !== undefined) {
|
|
1085
|
+
const marketIds = this.marketIds(symbols);
|
|
1086
|
+
const delimited = marketIds.join(',');
|
|
1087
|
+
request['symbols'] = delimited;
|
|
1088
|
+
}
|
|
1089
|
+
const response = await this.publicGetPublicTicker(this.extend(request, params));
|
|
1090
|
+
//
|
|
1091
|
+
// {
|
|
1092
|
+
// "BTCUSDT": {
|
|
1093
|
+
// "ask": "63049.06",
|
|
1094
|
+
// "bid": "63046.41",
|
|
1095
|
+
// "last": "63048.36",
|
|
1096
|
+
// "low": "62010.00",
|
|
1097
|
+
// "high": "66657.99",
|
|
1098
|
+
// "open": "64839.75",
|
|
1099
|
+
// "volume": "15272.13278",
|
|
1100
|
+
// "volume_quote": "976312127.6277998",
|
|
1101
|
+
// "timestamp": "2021-10-22T04:25:47.573Z"
|
|
1102
|
+
// }
|
|
1103
|
+
// }
|
|
1104
|
+
//
|
|
1105
|
+
const result = {};
|
|
1106
|
+
const keys = Object.keys(response);
|
|
1107
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1108
|
+
const marketId = keys[i];
|
|
1109
|
+
const market = this.safeMarket(marketId);
|
|
1110
|
+
const symbol = market['symbol'];
|
|
1111
|
+
const entry = response[marketId];
|
|
1112
|
+
result[symbol] = this.parseTicker(entry, market);
|
|
1113
|
+
}
|
|
1114
|
+
return this.filterByArrayTickers(result, 'symbol', symbols);
|
|
1115
|
+
}
|
|
1116
|
+
parseTicker(ticker, market = undefined) {
|
|
1117
|
+
//
|
|
1118
|
+
// {
|
|
1119
|
+
// "ask": "62756.01",
|
|
1120
|
+
// "bid": "62754.09",
|
|
1121
|
+
// "last": "62755.87",
|
|
1122
|
+
// "low": "62010.00",
|
|
1123
|
+
// "high": "66657.99",
|
|
1124
|
+
// "open": "65089.27",
|
|
1125
|
+
// "volume": "16719.50366",
|
|
1126
|
+
// "volume_quote": "1063422878.8156828",
|
|
1127
|
+
// "timestamp": "2021-10-22T07:29:14.585Z"
|
|
1128
|
+
// }
|
|
1129
|
+
//
|
|
1130
|
+
const timestamp = this.parse8601(ticker['timestamp']);
|
|
1131
|
+
const symbol = this.safeSymbol(undefined, market);
|
|
1132
|
+
const baseVolume = this.safeString(ticker, 'volume');
|
|
1133
|
+
const quoteVolume = this.safeString(ticker, 'volume_quote');
|
|
1134
|
+
const open = this.safeString(ticker, 'open');
|
|
1135
|
+
const last = this.safeString(ticker, 'last');
|
|
1136
|
+
return this.safeTicker({
|
|
1137
|
+
'symbol': symbol,
|
|
1138
|
+
'timestamp': timestamp,
|
|
1139
|
+
'datetime': this.iso8601(timestamp),
|
|
1140
|
+
'high': this.safeString(ticker, 'high'),
|
|
1141
|
+
'low': this.safeString(ticker, 'low'),
|
|
1142
|
+
'bid': this.safeString(ticker, 'bid'),
|
|
1143
|
+
'bidVolume': undefined,
|
|
1144
|
+
'ask': this.safeString(ticker, 'ask'),
|
|
1145
|
+
'askVolume': undefined,
|
|
1146
|
+
'vwap': undefined,
|
|
1147
|
+
'open': open,
|
|
1148
|
+
'close': last,
|
|
1149
|
+
'last': last,
|
|
1150
|
+
'previousClose': undefined,
|
|
1151
|
+
'change': undefined,
|
|
1152
|
+
'percentage': undefined,
|
|
1153
|
+
'average': undefined,
|
|
1154
|
+
'baseVolume': baseVolume,
|
|
1155
|
+
'quoteVolume': quoteVolume,
|
|
1156
|
+
'info': ticker,
|
|
1157
|
+
}, market);
|
|
1158
|
+
}
|
|
1159
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1160
|
+
/**
|
|
1161
|
+
* @method
|
|
1162
|
+
* @name hitbtc#fetchTrades
|
|
1163
|
+
* @description get the list of most recent trades for a particular symbol
|
|
1164
|
+
* @see https://api.hitbtc.com/#trades
|
|
1165
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1166
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1167
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1168
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1169
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1170
|
+
*/
|
|
1171
|
+
await this.loadMarkets();
|
|
1172
|
+
let market = undefined;
|
|
1173
|
+
const request = {};
|
|
1174
|
+
if (limit !== undefined) {
|
|
1175
|
+
request['limit'] = Math.min(limit, 1000);
|
|
1176
|
+
}
|
|
1177
|
+
if (since !== undefined) {
|
|
1178
|
+
request['from'] = since;
|
|
1179
|
+
}
|
|
1180
|
+
let response = undefined;
|
|
1181
|
+
if (symbol !== undefined) {
|
|
1182
|
+
market = this.market(symbol);
|
|
1183
|
+
request['symbol'] = market['id'];
|
|
1184
|
+
response = await this.publicGetPublicTradesSymbol(this.extend(request, params));
|
|
1185
|
+
}
|
|
1186
|
+
else {
|
|
1187
|
+
response = await this.publicGetPublicTrades(this.extend(request, params));
|
|
1188
|
+
}
|
|
1189
|
+
if (symbol !== undefined) {
|
|
1190
|
+
return this.parseTrades(response, market);
|
|
1191
|
+
}
|
|
1192
|
+
let trades = [];
|
|
1193
|
+
const marketIds = Object.keys(response);
|
|
1194
|
+
for (let i = 0; i < marketIds.length; i++) {
|
|
1195
|
+
const marketId = marketIds[i];
|
|
1196
|
+
const marketInner = this.market(marketId);
|
|
1197
|
+
const rawTrades = response[marketId];
|
|
1198
|
+
const parsed = this.parseTrades(rawTrades, marketInner);
|
|
1199
|
+
trades = this.arrayConcat(trades, parsed);
|
|
1200
|
+
}
|
|
1201
|
+
return trades;
|
|
1202
|
+
}
|
|
1203
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1204
|
+
/**
|
|
1205
|
+
* @method
|
|
1206
|
+
* @name hitbtc#fetchMyTrades
|
|
1207
|
+
* @description fetch all trades made by the user
|
|
1208
|
+
* @see https://api.hitbtc.com/#spot-trades-history
|
|
1209
|
+
* @see https://api.hitbtc.com/#futures-trades-history
|
|
1210
|
+
* @see https://api.hitbtc.com/#margin-trades-history
|
|
1211
|
+
* @param {string} symbol unified market symbol
|
|
1212
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1213
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
1214
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1215
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
1216
|
+
* @param {bool} [params.margin] true for fetching margin trades
|
|
1217
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1218
|
+
*/
|
|
1219
|
+
await this.loadMarkets();
|
|
1220
|
+
let market = undefined;
|
|
1221
|
+
const request = {};
|
|
1222
|
+
if (symbol !== undefined) {
|
|
1223
|
+
market = this.market(symbol);
|
|
1224
|
+
request['symbol'] = market['id'];
|
|
1225
|
+
}
|
|
1226
|
+
if (limit !== undefined) {
|
|
1227
|
+
request['limit'] = limit;
|
|
1228
|
+
}
|
|
1229
|
+
if (since !== undefined) {
|
|
1230
|
+
request['from'] = since;
|
|
1231
|
+
}
|
|
1232
|
+
let marketType = undefined;
|
|
1233
|
+
let marginMode = undefined;
|
|
1234
|
+
let response = undefined;
|
|
1235
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchMyTrades', market, params);
|
|
1236
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchMyTrades', params);
|
|
1237
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
1238
|
+
if (marginMode !== undefined) {
|
|
1239
|
+
response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
|
|
1240
|
+
}
|
|
1241
|
+
else {
|
|
1242
|
+
if (marketType === 'spot') {
|
|
1243
|
+
response = await this.privateGetSpotHistoryTrade(this.extend(request, params));
|
|
1244
|
+
}
|
|
1245
|
+
else if (marketType === 'swap') {
|
|
1246
|
+
response = await this.privateGetFuturesHistoryTrade(this.extend(request, params));
|
|
1247
|
+
}
|
|
1248
|
+
else if (marketType === 'margin') {
|
|
1249
|
+
response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
|
|
1250
|
+
}
|
|
1251
|
+
else {
|
|
1252
|
+
throw new errors.NotSupported(this.id + ' fetchMyTrades() not support this market type');
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
return this.parseTrades(response, market, since, limit);
|
|
1256
|
+
}
|
|
1257
|
+
parseTrade(trade, market = undefined) {
|
|
1258
|
+
//
|
|
1259
|
+
// createOrder (market)
|
|
1260
|
+
//
|
|
1261
|
+
// {
|
|
1262
|
+
// "id": "1569252895",
|
|
1263
|
+
// "position_id": "0",
|
|
1264
|
+
// "quantity": "10",
|
|
1265
|
+
// "price": "0.03919424",
|
|
1266
|
+
// "fee": "0.000979856000",
|
|
1267
|
+
// "timestamp": "2022-01-25T19:38:36.153Z",
|
|
1268
|
+
// "taker": true
|
|
1269
|
+
// }
|
|
1270
|
+
//
|
|
1271
|
+
// fetchTrades
|
|
1272
|
+
//
|
|
1273
|
+
// {
|
|
1274
|
+
// "id": 974786185,
|
|
1275
|
+
// "price": "0.032462",
|
|
1276
|
+
// "qty": "0.3673",
|
|
1277
|
+
// "side": "buy",
|
|
1278
|
+
// "timestamp": "2020-10-16T12:57:39.846Z"
|
|
1279
|
+
// }
|
|
1280
|
+
//
|
|
1281
|
+
// fetchMyTrades spot
|
|
1282
|
+
//
|
|
1283
|
+
// {
|
|
1284
|
+
// "id": 277210397,
|
|
1285
|
+
// "clientOrderId": "6e102f3e7f3f4e04aeeb1cdc95592f1a",
|
|
1286
|
+
// "orderId": 28102855393,
|
|
1287
|
+
// "symbol": "ETHBTC",
|
|
1288
|
+
// "side": "sell",
|
|
1289
|
+
// "quantity": "0.002",
|
|
1290
|
+
// "price": "0.073365",
|
|
1291
|
+
// "fee": "0.000000147",
|
|
1292
|
+
// "timestamp": "2018-04-28T18:39:55.345Z",
|
|
1293
|
+
// "taker": true
|
|
1294
|
+
// }
|
|
1295
|
+
//
|
|
1296
|
+
// fetchMyTrades swap and margin
|
|
1297
|
+
//
|
|
1298
|
+
// {
|
|
1299
|
+
// "id": 4718564,
|
|
1300
|
+
// "order_id": 58730811958,
|
|
1301
|
+
// "client_order_id": "475c47d97f867f09726186eb22b4c3d4",
|
|
1302
|
+
// "symbol": "BTCUSDT_PERP",
|
|
1303
|
+
// "side": "sell",
|
|
1304
|
+
// "quantity": "0.0001",
|
|
1305
|
+
// "price": "41118.51",
|
|
1306
|
+
// "fee": "0.002055925500",
|
|
1307
|
+
// "timestamp": "2022-03-17T05:23:17.795Z",
|
|
1308
|
+
// "taker": true,
|
|
1309
|
+
// "position_id": 2350122,
|
|
1310
|
+
// "pnl": "0.002255000000",
|
|
1311
|
+
// "liquidation": false
|
|
1312
|
+
// }
|
|
1313
|
+
//
|
|
1314
|
+
const timestamp = this.parse8601(trade['timestamp']);
|
|
1315
|
+
const marketId = this.safeString(trade, 'symbol');
|
|
1316
|
+
market = this.safeMarket(marketId, market);
|
|
1317
|
+
const symbol = market['symbol'];
|
|
1318
|
+
let fee = undefined;
|
|
1319
|
+
const feeCostString = this.safeString(trade, 'fee');
|
|
1320
|
+
const taker = this.safeValue(trade, 'taker');
|
|
1321
|
+
let takerOrMaker = undefined;
|
|
1322
|
+
if (taker !== undefined) {
|
|
1323
|
+
takerOrMaker = taker ? 'taker' : 'maker';
|
|
1324
|
+
}
|
|
1325
|
+
else {
|
|
1326
|
+
takerOrMaker = 'taker'; // the only case when `taker` field is missing, is public fetchTrades and it must be taker
|
|
1327
|
+
}
|
|
1328
|
+
if (feeCostString !== undefined) {
|
|
1329
|
+
const info = this.safeValue(market, 'info', {});
|
|
1330
|
+
const feeCurrency = this.safeString(info, 'fee_currency');
|
|
1331
|
+
const feeCurrencyCode = this.safeCurrencyCode(feeCurrency);
|
|
1332
|
+
fee = {
|
|
1333
|
+
'cost': feeCostString,
|
|
1334
|
+
'currency': feeCurrencyCode,
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
// we use clientOrderId as the order id with this exchange intentionally
|
|
1338
|
+
// because most of their endpoints will require clientOrderId
|
|
1339
|
+
// explained here: https://github.com/ccxt/ccxt/issues/5674
|
|
1340
|
+
const orderId = this.safeString2(trade, 'clientOrderId', 'client_order_id');
|
|
1341
|
+
const priceString = this.safeString(trade, 'price');
|
|
1342
|
+
const amountString = this.safeString2(trade, 'quantity', 'qty');
|
|
1343
|
+
const side = this.safeString(trade, 'side');
|
|
1344
|
+
const id = this.safeString(trade, 'id');
|
|
1345
|
+
return this.safeTrade({
|
|
1346
|
+
'info': trade,
|
|
1347
|
+
'id': id,
|
|
1348
|
+
'order': orderId,
|
|
1349
|
+
'timestamp': timestamp,
|
|
1350
|
+
'datetime': this.iso8601(timestamp),
|
|
1351
|
+
'symbol': symbol,
|
|
1352
|
+
'type': undefined,
|
|
1353
|
+
'side': side,
|
|
1354
|
+
'takerOrMaker': takerOrMaker,
|
|
1355
|
+
'price': priceString,
|
|
1356
|
+
'amount': amountString,
|
|
1357
|
+
'cost': undefined,
|
|
1358
|
+
'fee': fee,
|
|
1359
|
+
}, market);
|
|
1360
|
+
}
|
|
1361
|
+
async fetchTransactionsHelper(types, code, since, limit, params) {
|
|
1362
|
+
await this.loadMarkets();
|
|
1363
|
+
const request = {
|
|
1364
|
+
'types': types,
|
|
1365
|
+
};
|
|
1366
|
+
let currency = undefined;
|
|
1367
|
+
if (code !== undefined) {
|
|
1368
|
+
currency = this.currency(code);
|
|
1369
|
+
request['currencies'] = currency['id'];
|
|
1370
|
+
}
|
|
1371
|
+
if (since !== undefined) {
|
|
1372
|
+
request['from'] = this.iso8601(since);
|
|
1373
|
+
}
|
|
1374
|
+
if (limit !== undefined) {
|
|
1375
|
+
request['limit'] = limit;
|
|
1376
|
+
}
|
|
1377
|
+
const response = await this.privateGetWalletTransactions(this.extend(request, params));
|
|
1378
|
+
//
|
|
1379
|
+
// [
|
|
1380
|
+
// {
|
|
1381
|
+
// "id": "101609495",
|
|
1382
|
+
// "created_at": "2018-03-06T22:05:06.507Z",
|
|
1383
|
+
// "updated_at": "2018-03-06T22:11:45.03Z",
|
|
1384
|
+
// "status": "SUCCESS",
|
|
1385
|
+
// "type": "DEPOSIT",
|
|
1386
|
+
// "subtype": "BLOCKCHAIN",
|
|
1387
|
+
// "native": {
|
|
1388
|
+
// "tx_id": "e20b0965-4024-44d0-b63f-7fb8996a6706",
|
|
1389
|
+
// "index": "881652766",
|
|
1390
|
+
// "currency": "ETH",
|
|
1391
|
+
// "amount": "0.01418088",
|
|
1392
|
+
// "hash": "d95dbbff3f9234114f1211ab0ba2a94f03f394866fd5749d74a1edab80e6c5d3",
|
|
1393
|
+
// "address": "0xd9259302c32c0a0295d86a39185c9e14f6ba0a0d",
|
|
1394
|
+
// "confirmations": "20",
|
|
1395
|
+
// "senders": [
|
|
1396
|
+
// "0x243bec9256c9a3469da22103891465b47583d9f1"
|
|
1397
|
+
// ]
|
|
1398
|
+
// }
|
|
1399
|
+
// }
|
|
1400
|
+
// ]
|
|
1401
|
+
//
|
|
1402
|
+
return this.parseTransactions(response, currency, since, limit, params);
|
|
1403
|
+
}
|
|
1404
|
+
parseTransactionStatus(status) {
|
|
1405
|
+
const statuses = {
|
|
1406
|
+
'PENDING': 'pending',
|
|
1407
|
+
'FAILED': 'failed',
|
|
1408
|
+
'SUCCESS': 'ok',
|
|
1409
|
+
};
|
|
1410
|
+
return this.safeString(statuses, status, status);
|
|
1411
|
+
}
|
|
1412
|
+
parseTransactionType(type) {
|
|
1413
|
+
const types = {
|
|
1414
|
+
'DEPOSIT': 'deposit',
|
|
1415
|
+
'WITHDRAW': 'withdrawal',
|
|
1416
|
+
};
|
|
1417
|
+
return this.safeString(types, type, type);
|
|
1418
|
+
}
|
|
1419
|
+
parseTransaction(transaction, currency = undefined) {
|
|
1420
|
+
//
|
|
1421
|
+
// transaction
|
|
1422
|
+
//
|
|
1423
|
+
// {
|
|
1424
|
+
// "id": "101609495",
|
|
1425
|
+
// "created_at": "2018-03-06T22:05:06.507Z",
|
|
1426
|
+
// "updated_at": "2018-03-06T22:11:45.03Z",
|
|
1427
|
+
// "status": "SUCCESS",
|
|
1428
|
+
// "type": "DEPOSIT", // DEPOSIT, WITHDRAW, ..
|
|
1429
|
+
// "subtype": "BLOCKCHAIN",
|
|
1430
|
+
// "native": {
|
|
1431
|
+
// "tx_id": "e20b0965-4024-44d0-b63f-7fb8996a6706",
|
|
1432
|
+
// "index": "881652766",
|
|
1433
|
+
// "currency": "ETH",
|
|
1434
|
+
// "amount": "0.01418088",
|
|
1435
|
+
// "hash": "d95dbbff3f9234114f1211ab0ba2a94f03f394866fd5749d74a1edab80e6c5d3",
|
|
1436
|
+
// "address": "0xd9259302c32c0a0295d86a39185c9e14f6ba0a0d",
|
|
1437
|
+
// "confirmations": "20",
|
|
1438
|
+
// "senders": [
|
|
1439
|
+
// "0x243bec9256c9a3469da22103891465b47583d9f1"
|
|
1440
|
+
// ],
|
|
1441
|
+
// "fee": "1.22" // only for WITHDRAW
|
|
1442
|
+
// }
|
|
1443
|
+
// }
|
|
1444
|
+
//
|
|
1445
|
+
// withdraw
|
|
1446
|
+
//
|
|
1447
|
+
// {
|
|
1448
|
+
// "id":"084cfcd5-06b9-4826-882e-fdb75ec3625d"
|
|
1449
|
+
// }
|
|
1450
|
+
//
|
|
1451
|
+
const id = this.safeString(transaction, 'id');
|
|
1452
|
+
const timestamp = this.parse8601(this.safeString(transaction, 'created_at'));
|
|
1453
|
+
const updated = this.parse8601(this.safeString(transaction, 'updated_at'));
|
|
1454
|
+
const type = this.parseTransactionType(this.safeString(transaction, 'type'));
|
|
1455
|
+
const status = this.parseTransactionStatus(this.safeString(transaction, 'status'));
|
|
1456
|
+
const native = this.safeValue(transaction, 'native', {});
|
|
1457
|
+
const currencyId = this.safeString(native, 'currency');
|
|
1458
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1459
|
+
const txhash = this.safeString(native, 'hash');
|
|
1460
|
+
const address = this.safeString(native, 'address');
|
|
1461
|
+
const addressTo = address;
|
|
1462
|
+
const tag = this.safeString(native, 'payment_id');
|
|
1463
|
+
const tagTo = tag;
|
|
1464
|
+
const sender = this.safeValue(native, 'senders');
|
|
1465
|
+
const addressFrom = this.safeString(sender, 0);
|
|
1466
|
+
const amount = this.safeNumber(native, 'amount');
|
|
1467
|
+
const subType = this.safeString(transaction, 'subtype');
|
|
1468
|
+
const internal = subType === 'OFFCHAIN';
|
|
1469
|
+
// https://api.hitbtc.com/#check-if-offchain-is-available
|
|
1470
|
+
const fee = {
|
|
1471
|
+
'currency': undefined,
|
|
1472
|
+
'cost': undefined,
|
|
1473
|
+
'rate': undefined,
|
|
1474
|
+
};
|
|
1475
|
+
const feeCost = this.safeNumber(native, 'fee');
|
|
1476
|
+
if (feeCost !== undefined) {
|
|
1477
|
+
fee['currency'] = code;
|
|
1478
|
+
fee['cost'] = feeCost;
|
|
1479
|
+
}
|
|
1480
|
+
return {
|
|
1481
|
+
'info': transaction,
|
|
1482
|
+
'id': id,
|
|
1483
|
+
'txid': txhash,
|
|
1484
|
+
'type': type,
|
|
1485
|
+
'currency': code,
|
|
1486
|
+
'network': undefined,
|
|
1487
|
+
'amount': amount,
|
|
1488
|
+
'status': status,
|
|
1489
|
+
'timestamp': timestamp,
|
|
1490
|
+
'datetime': this.iso8601(timestamp),
|
|
1491
|
+
'address': address,
|
|
1492
|
+
'addressFrom': addressFrom,
|
|
1493
|
+
'addressTo': addressTo,
|
|
1494
|
+
'tag': tag,
|
|
1495
|
+
'tagFrom': undefined,
|
|
1496
|
+
'tagTo': tagTo,
|
|
1497
|
+
'updated': updated,
|
|
1498
|
+
'comment': undefined,
|
|
1499
|
+
'internal': internal,
|
|
1500
|
+
'fee': fee,
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1504
|
+
/**
|
|
1505
|
+
* @method
|
|
1506
|
+
* @name hitbtc#fetchDepositsWithdrawals
|
|
1507
|
+
* @description fetch history of deposits and withdrawals
|
|
1508
|
+
* @see https://api.hitbtc.com/#get-transactions-history
|
|
1509
|
+
* @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
|
|
1510
|
+
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
|
1511
|
+
* @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
|
|
1512
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1513
|
+
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1514
|
+
*/
|
|
1515
|
+
return await this.fetchTransactionsHelper('DEPOSIT,WITHDRAW', code, since, limit, params);
|
|
1516
|
+
}
|
|
1517
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1518
|
+
/**
|
|
1519
|
+
* @method
|
|
1520
|
+
* @name hitbtc#fetchDeposits
|
|
1521
|
+
* @description fetch all deposits made to an account
|
|
1522
|
+
* @see https://api.hitbtc.com/#get-transactions-history
|
|
1523
|
+
* @param {string} code unified currency code
|
|
1524
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
1525
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
1526
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1527
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1528
|
+
*/
|
|
1529
|
+
return await this.fetchTransactionsHelper('DEPOSIT', code, since, limit, params);
|
|
1530
|
+
}
|
|
1531
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1532
|
+
/**
|
|
1533
|
+
* @method
|
|
1534
|
+
* @name hitbtc#fetchWithdrawals
|
|
1535
|
+
* @description fetch all withdrawals made from an account
|
|
1536
|
+
* @see https://api.hitbtc.com/#get-transactions-history
|
|
1537
|
+
* @param {string} code unified currency code
|
|
1538
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
1539
|
+
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
1540
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1541
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1542
|
+
*/
|
|
1543
|
+
return await this.fetchTransactionsHelper('WITHDRAW', code, since, limit, params);
|
|
1544
|
+
}
|
|
1545
|
+
async fetchOrderBooks(symbols = undefined, limit = undefined, params = {}) {
|
|
1546
|
+
/**
|
|
1547
|
+
* @method
|
|
1548
|
+
* @name hitbtc#fetchOrderBooks
|
|
1549
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data for multiple markets
|
|
1550
|
+
* @see https://api.hitbtc.com/#order-books
|
|
1551
|
+
* @param {string[]|undefined} symbols list of unified market symbols, all symbols fetched if undefined, default is undefined
|
|
1552
|
+
* @param {int} [limit] max number of entries per orderbook to return, default is undefined
|
|
1553
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1554
|
+
* @returns {object} a dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbol
|
|
1555
|
+
*/
|
|
1556
|
+
await this.loadMarkets();
|
|
1557
|
+
const request = {};
|
|
1558
|
+
if (symbols !== undefined) {
|
|
1559
|
+
const marketIdsInner = this.marketIds(symbols);
|
|
1560
|
+
request['symbols'] = marketIdsInner.join(',');
|
|
1561
|
+
}
|
|
1562
|
+
if (limit !== undefined) {
|
|
1563
|
+
request['depth'] = limit;
|
|
1564
|
+
}
|
|
1565
|
+
const response = await this.publicGetPublicOrderbook(this.extend(request, params));
|
|
1566
|
+
const result = {};
|
|
1567
|
+
const marketIds = Object.keys(response);
|
|
1568
|
+
for (let i = 0; i < marketIds.length; i++) {
|
|
1569
|
+
const marketId = marketIds[i];
|
|
1570
|
+
const orderbook = response[marketId];
|
|
1571
|
+
const symbol = this.safeSymbol(marketId);
|
|
1572
|
+
const timestamp = this.parse8601(this.safeString(orderbook, 'timestamp'));
|
|
1573
|
+
result[symbol] = this.parseOrderBook(response[marketId], symbol, timestamp, 'bid', 'ask');
|
|
1574
|
+
}
|
|
1575
|
+
return result;
|
|
1576
|
+
}
|
|
1577
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
1578
|
+
/**
|
|
1579
|
+
* @method
|
|
1580
|
+
* @name hitbtc#fetchOrderBook
|
|
1581
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
1582
|
+
* @see https://api.hitbtc.com/#order-books
|
|
1583
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
1584
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
1585
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1586
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
1587
|
+
*/
|
|
1588
|
+
await this.loadMarkets();
|
|
1589
|
+
const market = this.market(symbol);
|
|
1590
|
+
const request = {
|
|
1591
|
+
'symbol': market['id'],
|
|
1592
|
+
};
|
|
1593
|
+
if (limit !== undefined) {
|
|
1594
|
+
request['depth'] = limit;
|
|
1595
|
+
}
|
|
1596
|
+
const response = await this.publicGetPublicOrderbookSymbol(this.extend(request, params));
|
|
1597
|
+
const timestamp = this.parse8601(this.safeString(response, 'timestamp'));
|
|
1598
|
+
return this.parseOrderBook(response, symbol, timestamp, 'bid', 'ask');
|
|
1599
|
+
}
|
|
1600
|
+
parseTradingFee(fee, market = undefined) {
|
|
1601
|
+
//
|
|
1602
|
+
// {
|
|
1603
|
+
// "symbol":"ARVUSDT", // returned from fetchTradingFees only
|
|
1604
|
+
// "take_rate":"0.0009",
|
|
1605
|
+
// "make_rate":"0.0009"
|
|
1606
|
+
// }
|
|
1607
|
+
//
|
|
1608
|
+
const taker = this.safeNumber(fee, 'take_rate');
|
|
1609
|
+
const maker = this.safeNumber(fee, 'make_rate');
|
|
1610
|
+
const marketId = this.safeString(fee, 'symbol');
|
|
1611
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1612
|
+
return {
|
|
1613
|
+
'info': fee,
|
|
1614
|
+
'symbol': symbol,
|
|
1615
|
+
'taker': taker,
|
|
1616
|
+
'maker': maker,
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
async fetchTradingFee(symbol, params = {}) {
|
|
1620
|
+
/**
|
|
1621
|
+
* @method
|
|
1622
|
+
* @name hitbtc#fetchTradingFee
|
|
1623
|
+
* @description fetch the trading fees for a market
|
|
1624
|
+
* @see https://api.hitbtc.com/#get-trading-commission
|
|
1625
|
+
* @see https://api.hitbtc.com/#get-trading-commission-2
|
|
1626
|
+
* @param {string} symbol unified market symbol
|
|
1627
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1628
|
+
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
1629
|
+
*/
|
|
1630
|
+
await this.loadMarkets();
|
|
1631
|
+
const market = this.market(symbol);
|
|
1632
|
+
const request = {
|
|
1633
|
+
'symbol': market['id'],
|
|
1634
|
+
};
|
|
1635
|
+
let response = undefined;
|
|
1636
|
+
if (market['type'] === 'spot') {
|
|
1637
|
+
response = await this.privateGetSpotFeeSymbol(this.extend(request, params));
|
|
1638
|
+
}
|
|
1639
|
+
else if (market['type'] === 'swap') {
|
|
1640
|
+
response = await this.privateGetFuturesFeeSymbol(this.extend(request, params));
|
|
1641
|
+
}
|
|
1642
|
+
else {
|
|
1643
|
+
throw new errors.NotSupported(this.id + ' fetchTradingFee() not support this market type');
|
|
1644
|
+
}
|
|
1645
|
+
//
|
|
1646
|
+
// {
|
|
1647
|
+
// "take_rate":"0.0009",
|
|
1648
|
+
// "make_rate":"0.0009"
|
|
1649
|
+
// }
|
|
1650
|
+
//
|
|
1651
|
+
return this.parseTradingFee(response, market);
|
|
1652
|
+
}
|
|
1653
|
+
async fetchTradingFees(params = {}) {
|
|
1654
|
+
/**
|
|
1655
|
+
* @method
|
|
1656
|
+
* @name hitbtc#fetchTradingFees
|
|
1657
|
+
* @description fetch the trading fees for multiple markets
|
|
1658
|
+
* @see https://api.hitbtc.com/#get-all-trading-commissions
|
|
1659
|
+
* @see https://api.hitbtc.com/#get-all-trading-commissions-2
|
|
1660
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1661
|
+
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
1662
|
+
*/
|
|
1663
|
+
await this.loadMarkets();
|
|
1664
|
+
const [marketType, query] = this.handleMarketTypeAndParams('fetchTradingFees', undefined, params);
|
|
1665
|
+
let response = undefined;
|
|
1666
|
+
if (marketType === 'spot') {
|
|
1667
|
+
response = await this.privateGetSpotFee(query);
|
|
1668
|
+
}
|
|
1669
|
+
else if (marketType === 'swap') {
|
|
1670
|
+
response = await this.privateGetFuturesFee(query);
|
|
1671
|
+
}
|
|
1672
|
+
else {
|
|
1673
|
+
throw new errors.NotSupported(this.id + ' fetchTradingFees() not support this market type');
|
|
1674
|
+
}
|
|
1675
|
+
//
|
|
1676
|
+
// [
|
|
1677
|
+
// {
|
|
1678
|
+
// "symbol":"ARVUSDT",
|
|
1679
|
+
// "take_rate":"0.0009",
|
|
1680
|
+
// "make_rate":"0.0009"
|
|
1681
|
+
// }
|
|
1682
|
+
// ]
|
|
1683
|
+
//
|
|
1684
|
+
const result = {};
|
|
1685
|
+
for (let i = 0; i < response.length; i++) {
|
|
1686
|
+
const fee = this.parseTradingFee(response[i]);
|
|
1687
|
+
const symbol = fee['symbol'];
|
|
1688
|
+
result[symbol] = fee;
|
|
1689
|
+
}
|
|
1690
|
+
return result;
|
|
1691
|
+
}
|
|
1692
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1693
|
+
/**
|
|
1694
|
+
* @method
|
|
1695
|
+
* @name hitbtc#fetchOHLCV
|
|
1696
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1697
|
+
* @see https://api.hitbtc.com/#candles
|
|
1698
|
+
* @see https://api.hitbtc.com/#futures-index-price-candles
|
|
1699
|
+
* @see https://api.hitbtc.com/#futures-mark-price-candles
|
|
1700
|
+
* @see https://api.hitbtc.com/#futures-premium-index-candles
|
|
1701
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1702
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1703
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1704
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1705
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1706
|
+
* @param {int} [params.until] timestamp in ms of the latest funding rate
|
|
1707
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
1708
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1709
|
+
*/
|
|
1710
|
+
await this.loadMarkets();
|
|
1711
|
+
let paginate = false;
|
|
1712
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
|
|
1713
|
+
if (paginate) {
|
|
1714
|
+
return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000);
|
|
1715
|
+
}
|
|
1716
|
+
const market = this.market(symbol);
|
|
1717
|
+
let request = {
|
|
1718
|
+
'symbol': market['id'],
|
|
1719
|
+
'period': this.safeString(this.timeframes, timeframe, timeframe),
|
|
1720
|
+
};
|
|
1721
|
+
[request, params] = this.handleUntilOption('till', request, params);
|
|
1722
|
+
if (since !== undefined) {
|
|
1723
|
+
request['from'] = this.iso8601(since);
|
|
1724
|
+
}
|
|
1725
|
+
if (limit !== undefined) {
|
|
1726
|
+
request['limit'] = limit;
|
|
1727
|
+
}
|
|
1728
|
+
const price = this.safeString(params, 'price');
|
|
1729
|
+
params = this.omit(params, 'price');
|
|
1730
|
+
let response = undefined;
|
|
1731
|
+
if (price === 'mark') {
|
|
1732
|
+
response = await this.publicGetPublicFuturesCandlesMarkPriceSymbol(this.extend(request, params));
|
|
1733
|
+
}
|
|
1734
|
+
else if (price === 'index') {
|
|
1735
|
+
response = await this.publicGetPublicFuturesCandlesIndexPriceSymbol(this.extend(request, params));
|
|
1736
|
+
}
|
|
1737
|
+
else if (price === 'premiumIndex') {
|
|
1738
|
+
response = await this.publicGetPublicFuturesCandlesPremiumIndexSymbol(this.extend(request, params));
|
|
1739
|
+
}
|
|
1740
|
+
else {
|
|
1741
|
+
response = await this.publicGetPublicCandlesSymbol(this.extend(request, params));
|
|
1742
|
+
}
|
|
1743
|
+
//
|
|
1744
|
+
// Spot and Swap
|
|
1745
|
+
//
|
|
1746
|
+
// [
|
|
1747
|
+
// {
|
|
1748
|
+
// "timestamp": "2021-10-25T07:38:00.000Z",
|
|
1749
|
+
// "open": "4173.391",
|
|
1750
|
+
// "close": "4170.923",
|
|
1751
|
+
// "min": "4170.923",
|
|
1752
|
+
// "max": "4173.986",
|
|
1753
|
+
// "volume": "0.1879",
|
|
1754
|
+
// "volume_quote": "784.2517846"
|
|
1755
|
+
// }
|
|
1756
|
+
// ]
|
|
1757
|
+
//
|
|
1758
|
+
// Mark, Index and Premium Index
|
|
1759
|
+
//
|
|
1760
|
+
// [
|
|
1761
|
+
// {
|
|
1762
|
+
// "timestamp": "2022-04-01T01:28:00.000Z",
|
|
1763
|
+
// "open": "45146.39",
|
|
1764
|
+
// "close": "45219.43",
|
|
1765
|
+
// "min": "45146.39",
|
|
1766
|
+
// "max": "45219.43"
|
|
1767
|
+
// },
|
|
1768
|
+
// ]
|
|
1769
|
+
//
|
|
1770
|
+
return this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
1771
|
+
}
|
|
1772
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1773
|
+
//
|
|
1774
|
+
// Spot and Swap
|
|
1775
|
+
//
|
|
1776
|
+
// {
|
|
1777
|
+
// "timestamp":"2015-08-20T19:01:00.000Z",
|
|
1778
|
+
// "open":"0.006",
|
|
1779
|
+
// "close":"0.006",
|
|
1780
|
+
// "min":"0.006",
|
|
1781
|
+
// "max":"0.006",
|
|
1782
|
+
// "volume":"0.003",
|
|
1783
|
+
// "volume_quote":"0.000018"
|
|
1784
|
+
// }
|
|
1785
|
+
//
|
|
1786
|
+
// Mark, Index and Premium Index
|
|
1787
|
+
//
|
|
1788
|
+
// {
|
|
1789
|
+
// "timestamp": "2022-04-01T01:28:00.000Z",
|
|
1790
|
+
// "open": "45146.39",
|
|
1791
|
+
// "close": "45219.43",
|
|
1792
|
+
// "min": "45146.39",
|
|
1793
|
+
// "max": "45219.43"
|
|
1794
|
+
// },
|
|
1795
|
+
//
|
|
1796
|
+
return [
|
|
1797
|
+
this.parse8601(this.safeString(ohlcv, 'timestamp')),
|
|
1798
|
+
this.safeNumber(ohlcv, 'open'),
|
|
1799
|
+
this.safeNumber(ohlcv, 'max'),
|
|
1800
|
+
this.safeNumber(ohlcv, 'min'),
|
|
1801
|
+
this.safeNumber(ohlcv, 'close'),
|
|
1802
|
+
this.safeNumber(ohlcv, 'volume'),
|
|
1803
|
+
];
|
|
1804
|
+
}
|
|
1805
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1806
|
+
/**
|
|
1807
|
+
* @method
|
|
1808
|
+
* @name hitbtc#fetchClosedOrders
|
|
1809
|
+
* @description fetches information on multiple closed orders made by the user
|
|
1810
|
+
* @see https://api.hitbtc.com/#spot-orders-history
|
|
1811
|
+
* @see https://api.hitbtc.com/#futures-orders-history
|
|
1812
|
+
* @see https://api.hitbtc.com/#margin-orders-history
|
|
1813
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1814
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1815
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1816
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1817
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
1818
|
+
* @param {bool} [params.margin] true for fetching margin orders
|
|
1819
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1820
|
+
*/
|
|
1821
|
+
await this.loadMarkets();
|
|
1822
|
+
let market = undefined;
|
|
1823
|
+
const request = {};
|
|
1824
|
+
if (symbol !== undefined) {
|
|
1825
|
+
market = this.market(symbol);
|
|
1826
|
+
request['symbol'] = market['id'];
|
|
1827
|
+
}
|
|
1828
|
+
if (since !== undefined) {
|
|
1829
|
+
request['from'] = this.iso8601(since);
|
|
1830
|
+
}
|
|
1831
|
+
if (limit !== undefined) {
|
|
1832
|
+
request['limit'] = limit;
|
|
1833
|
+
}
|
|
1834
|
+
let marketType = undefined;
|
|
1835
|
+
let marginMode = undefined;
|
|
1836
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchClosedOrders', market, params);
|
|
1837
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchClosedOrders', params);
|
|
1838
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
1839
|
+
let response = undefined;
|
|
1840
|
+
if (marginMode !== undefined) {
|
|
1841
|
+
response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
|
|
1842
|
+
}
|
|
1843
|
+
else {
|
|
1844
|
+
if (marketType === 'spot') {
|
|
1845
|
+
response = await this.privateGetSpotHistoryOrder(this.extend(request, params));
|
|
1846
|
+
}
|
|
1847
|
+
else if (marketType === 'swap') {
|
|
1848
|
+
response = await this.privateGetFuturesHistoryOrder(this.extend(request, params));
|
|
1849
|
+
}
|
|
1850
|
+
else if (marketType === 'margin') {
|
|
1851
|
+
response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
|
|
1852
|
+
}
|
|
1853
|
+
else {
|
|
1854
|
+
throw new errors.NotSupported(this.id + ' fetchClosedOrders() not support this market type');
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
const parsed = this.parseOrders(response, market, since, limit);
|
|
1858
|
+
return this.filterByArray(parsed, 'status', ['closed', 'canceled'], false);
|
|
1859
|
+
}
|
|
1860
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1861
|
+
/**
|
|
1862
|
+
* @method
|
|
1863
|
+
* @name hitbtc#fetchOrder
|
|
1864
|
+
* @description fetches information on an order made by the user
|
|
1865
|
+
* @see https://api.hitbtc.com/#spot-orders-history
|
|
1866
|
+
* @see https://api.hitbtc.com/#futures-orders-history
|
|
1867
|
+
* @see https://api.hitbtc.com/#margin-orders-history
|
|
1868
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
1869
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1870
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
1871
|
+
* @param {bool} [params.margin] true for fetching a margin order
|
|
1872
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1873
|
+
*/
|
|
1874
|
+
await this.loadMarkets();
|
|
1875
|
+
let market = undefined;
|
|
1876
|
+
if (symbol !== undefined) {
|
|
1877
|
+
market = this.market(symbol);
|
|
1878
|
+
}
|
|
1879
|
+
const request = {
|
|
1880
|
+
'client_order_id': id,
|
|
1881
|
+
};
|
|
1882
|
+
let marketType = undefined;
|
|
1883
|
+
let marginMode = undefined;
|
|
1884
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchOrder', market, params);
|
|
1885
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchOrder', params);
|
|
1886
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
1887
|
+
let response = undefined;
|
|
1888
|
+
if (marginMode !== undefined) {
|
|
1889
|
+
response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
|
|
1890
|
+
}
|
|
1891
|
+
else {
|
|
1892
|
+
if (marketType === 'spot') {
|
|
1893
|
+
response = await this.privateGetSpotHistoryOrder(this.extend(request, params));
|
|
1894
|
+
}
|
|
1895
|
+
else if (marketType === 'swap') {
|
|
1896
|
+
response = await this.privateGetFuturesHistoryOrder(this.extend(request, params));
|
|
1897
|
+
}
|
|
1898
|
+
else if (marketType === 'margin') {
|
|
1899
|
+
response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
|
|
1900
|
+
}
|
|
1901
|
+
else {
|
|
1902
|
+
throw new errors.NotSupported(this.id + ' fetchOrder() not support this market type');
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
//
|
|
1906
|
+
// [
|
|
1907
|
+
// {
|
|
1908
|
+
// "id": "685965182082",
|
|
1909
|
+
// "client_order_id": "B3CBm9uGg9oYQlw96bBSEt38-6gbgBO0",
|
|
1910
|
+
// "symbol": "BTCUSDT",
|
|
1911
|
+
// "side": "buy",
|
|
1912
|
+
// "status": "new",
|
|
1913
|
+
// "type": "limit",
|
|
1914
|
+
// "time_in_force": "GTC",
|
|
1915
|
+
// "quantity": "0.00010",
|
|
1916
|
+
// "quantity_cumulative": "0",
|
|
1917
|
+
// "price": "50000.00",
|
|
1918
|
+
// "price_average": "0",
|
|
1919
|
+
// "created_at": "2021-10-26T11:40:09.287Z",
|
|
1920
|
+
// "updated_at": "2021-10-26T11:40:09.287Z"
|
|
1921
|
+
// }
|
|
1922
|
+
// ]
|
|
1923
|
+
//
|
|
1924
|
+
const order = this.safeValue(response, 0);
|
|
1925
|
+
return this.parseOrder(order, market);
|
|
1926
|
+
}
|
|
1927
|
+
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1928
|
+
/**
|
|
1929
|
+
* @method
|
|
1930
|
+
* @name hitbtc#fetchOrderTrades
|
|
1931
|
+
* @description fetch all the trades made from a single order
|
|
1932
|
+
* @see https://api.hitbtc.com/#spot-trades-history
|
|
1933
|
+
* @see https://api.hitbtc.com/#futures-trades-history
|
|
1934
|
+
* @see https://api.hitbtc.com/#margin-trades-history
|
|
1935
|
+
* @param {string} id order id
|
|
1936
|
+
* @param {string} symbol unified market symbol
|
|
1937
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1938
|
+
* @param {int} [limit] the maximum number of trades to retrieve
|
|
1939
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1940
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
1941
|
+
* @param {bool} [params.margin] true for fetching margin trades
|
|
1942
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1943
|
+
*/
|
|
1944
|
+
await this.loadMarkets();
|
|
1945
|
+
let market = undefined;
|
|
1946
|
+
if (symbol !== undefined) {
|
|
1947
|
+
market = this.market(symbol);
|
|
1948
|
+
}
|
|
1949
|
+
const request = {
|
|
1950
|
+
'order_id': id, // exchange assigned order id as oppose to the client order id
|
|
1951
|
+
};
|
|
1952
|
+
let marketType = undefined;
|
|
1953
|
+
let marginMode = undefined;
|
|
1954
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchOrderTrades', market, params);
|
|
1955
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchOrderTrades', params);
|
|
1956
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
1957
|
+
let response = undefined;
|
|
1958
|
+
if (marginMode !== undefined) {
|
|
1959
|
+
response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
|
|
1960
|
+
}
|
|
1961
|
+
else {
|
|
1962
|
+
if (marketType === 'spot') {
|
|
1963
|
+
response = await this.privateGetSpotHistoryTrade(this.extend(request, params));
|
|
1964
|
+
}
|
|
1965
|
+
else if (marketType === 'swap') {
|
|
1966
|
+
response = await this.privateGetFuturesHistoryTrade(this.extend(request, params));
|
|
1967
|
+
}
|
|
1968
|
+
else if (marketType === 'margin') {
|
|
1969
|
+
response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
|
|
1970
|
+
}
|
|
1971
|
+
else {
|
|
1972
|
+
throw new errors.NotSupported(this.id + ' fetchOrderTrades() not support this market type');
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
//
|
|
1976
|
+
// Spot
|
|
1977
|
+
//
|
|
1978
|
+
// [
|
|
1979
|
+
// {
|
|
1980
|
+
// "id": 1393448977,
|
|
1981
|
+
// "order_id": 653496804534,
|
|
1982
|
+
// "client_order_id": "065f6f0ff9d54547848454182263d7b4",
|
|
1983
|
+
// "symbol": "DICEETH",
|
|
1984
|
+
// "side": "buy",
|
|
1985
|
+
// "quantity": "1.4",
|
|
1986
|
+
// "price": "0.00261455",
|
|
1987
|
+
// "fee": "0.000003294333",
|
|
1988
|
+
// "timestamp": "2021-09-19T05:35:56.601Z",
|
|
1989
|
+
// "taker": true
|
|
1990
|
+
// }
|
|
1991
|
+
// ]
|
|
1992
|
+
//
|
|
1993
|
+
// Swap and Margin
|
|
1994
|
+
//
|
|
1995
|
+
// [
|
|
1996
|
+
// {
|
|
1997
|
+
// "id": 4718551,
|
|
1998
|
+
// "order_id": 58730748700,
|
|
1999
|
+
// "client_order_id": "dcbcd8549e3445ee922665946002ef67",
|
|
2000
|
+
// "symbol": "BTCUSDT_PERP",
|
|
2001
|
+
// "side": "buy",
|
|
2002
|
+
// "quantity": "0.0001",
|
|
2003
|
+
// "price": "41095.96",
|
|
2004
|
+
// "fee": "0.002054798000",
|
|
2005
|
+
// "timestamp": "2022-03-17T05:23:02.217Z",
|
|
2006
|
+
// "taker": true,
|
|
2007
|
+
// "position_id": 2350122,
|
|
2008
|
+
// "pnl": "0",
|
|
2009
|
+
// "liquidation": false
|
|
2010
|
+
// }
|
|
2011
|
+
// ]
|
|
2012
|
+
//
|
|
2013
|
+
return this.parseTrades(response, market, since, limit);
|
|
2014
|
+
}
|
|
2015
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2016
|
+
/**
|
|
2017
|
+
* @method
|
|
2018
|
+
* @name hitbtc#fetchOpenOrders
|
|
2019
|
+
* @description fetch all unfilled currently open orders
|
|
2020
|
+
* @see https://api.hitbtc.com/#get-all-active-spot-orders
|
|
2021
|
+
* @see https://api.hitbtc.com/#get-active-futures-orders
|
|
2022
|
+
* @see https://api.hitbtc.com/#get-active-margin-orders
|
|
2023
|
+
* @param {string} symbol unified market symbol
|
|
2024
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
2025
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
2026
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2027
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
2028
|
+
* @param {bool} [params.margin] true for fetching open margin orders
|
|
2029
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2030
|
+
*/
|
|
2031
|
+
await this.loadMarkets();
|
|
2032
|
+
let market = undefined;
|
|
2033
|
+
const request = {};
|
|
2034
|
+
if (symbol !== undefined) {
|
|
2035
|
+
market = this.market(symbol);
|
|
2036
|
+
request['symbol'] = market['id'];
|
|
2037
|
+
}
|
|
2038
|
+
let marketType = undefined;
|
|
2039
|
+
let marginMode = undefined;
|
|
2040
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
|
|
2041
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchOpenOrders', params);
|
|
2042
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
2043
|
+
let response = undefined;
|
|
2044
|
+
if (marginMode !== undefined) {
|
|
2045
|
+
response = await this.privateGetMarginOrder(this.extend(request, params));
|
|
2046
|
+
}
|
|
2047
|
+
else {
|
|
2048
|
+
if (marketType === 'spot') {
|
|
2049
|
+
response = await this.privateGetSpotOrder(this.extend(request, params));
|
|
2050
|
+
}
|
|
2051
|
+
else if (marketType === 'swap') {
|
|
2052
|
+
response = await this.privateGetFuturesOrder(this.extend(request, params));
|
|
2053
|
+
}
|
|
2054
|
+
else if (marketType === 'margin') {
|
|
2055
|
+
response = await this.privateGetMarginOrder(this.extend(request, params));
|
|
2056
|
+
}
|
|
2057
|
+
else {
|
|
2058
|
+
throw new errors.NotSupported(this.id + ' fetchOpenOrders() not support this market type');
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
//
|
|
2062
|
+
// [
|
|
2063
|
+
// {
|
|
2064
|
+
// "id": "488953123149",
|
|
2065
|
+
// "client_order_id": "103ad305301e4c3590045b13de15b36e",
|
|
2066
|
+
// "symbol": "BTCUSDT",
|
|
2067
|
+
// "side": "buy",
|
|
2068
|
+
// "status": "new",
|
|
2069
|
+
// "type": "limit",
|
|
2070
|
+
// "time_in_force": "GTC",
|
|
2071
|
+
// "quantity": "0.00001",
|
|
2072
|
+
// "quantity_cumulative": "0",
|
|
2073
|
+
// "price": "0.01",
|
|
2074
|
+
// "post_only": false,
|
|
2075
|
+
// "created_at": "2021-04-13T13:06:16.567Z",
|
|
2076
|
+
// "updated_at": "2021-04-13T13:06:16.567Z"
|
|
2077
|
+
// }
|
|
2078
|
+
// ]
|
|
2079
|
+
//
|
|
2080
|
+
return this.parseOrders(response, market, since, limit);
|
|
2081
|
+
}
|
|
2082
|
+
async fetchOpenOrder(id, symbol = undefined, params = {}) {
|
|
2083
|
+
/**
|
|
2084
|
+
* @method
|
|
2085
|
+
* @name hitbtc#fetchOpenOrder
|
|
2086
|
+
* @description fetch an open order by it's id
|
|
2087
|
+
* @see https://api.hitbtc.com/#get-active-spot-order
|
|
2088
|
+
* @see https://api.hitbtc.com/#get-active-futures-order
|
|
2089
|
+
* @see https://api.hitbtc.com/#get-active-margin-order
|
|
2090
|
+
* @param {string} id order id
|
|
2091
|
+
* @param {string} symbol unified market symbol, default is undefined
|
|
2092
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2093
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
2094
|
+
* @param {bool} [params.margin] true for fetching an open margin order
|
|
2095
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2096
|
+
*/
|
|
2097
|
+
await this.loadMarkets();
|
|
2098
|
+
let market = undefined;
|
|
2099
|
+
if (symbol !== undefined) {
|
|
2100
|
+
market = this.market(symbol);
|
|
2101
|
+
}
|
|
2102
|
+
const request = {
|
|
2103
|
+
'client_order_id': id,
|
|
2104
|
+
};
|
|
2105
|
+
let marketType = undefined;
|
|
2106
|
+
let marginMode = undefined;
|
|
2107
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrder', market, params);
|
|
2108
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchOpenOrder', params);
|
|
2109
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
2110
|
+
let response = undefined;
|
|
2111
|
+
if (marginMode !== undefined) {
|
|
2112
|
+
response = await this.privateGetMarginOrderClientOrderId(this.extend(request, params));
|
|
2113
|
+
}
|
|
2114
|
+
else {
|
|
2115
|
+
if (marketType === 'spot') {
|
|
2116
|
+
response = await this.privateGetSpotOrderClientOrderId(this.extend(request, params));
|
|
2117
|
+
}
|
|
2118
|
+
else if (marketType === 'swap') {
|
|
2119
|
+
response = await this.privateGetFuturesOrderClientOrderId(this.extend(request, params));
|
|
2120
|
+
}
|
|
2121
|
+
else if (marketType === 'margin') {
|
|
2122
|
+
response = await this.privateGetMarginOrderClientOrderId(this.extend(request, params));
|
|
2123
|
+
}
|
|
2124
|
+
else {
|
|
2125
|
+
throw new errors.NotSupported(this.id + ' fetchOpenOrder() not support this market type');
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
return this.parseOrder(response, market);
|
|
2129
|
+
}
|
|
2130
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
2131
|
+
/**
|
|
2132
|
+
* @method
|
|
2133
|
+
* @name hitbtc#cancelAllOrders
|
|
2134
|
+
* @description cancel all open orders
|
|
2135
|
+
* @see https://api.hitbtc.com/#cancel-all-spot-orders
|
|
2136
|
+
* @see https://api.hitbtc.com/#cancel-futures-orders
|
|
2137
|
+
* @see https://api.hitbtc.com/#cancel-all-margin-orders
|
|
2138
|
+
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
2139
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2140
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
2141
|
+
* @param {bool} [params.margin] true for canceling margin orders
|
|
2142
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2143
|
+
*/
|
|
2144
|
+
await this.loadMarkets();
|
|
2145
|
+
let market = undefined;
|
|
2146
|
+
const request = {};
|
|
2147
|
+
if (symbol !== undefined) {
|
|
2148
|
+
market = this.market(symbol);
|
|
2149
|
+
request['symbol'] = market['id'];
|
|
2150
|
+
}
|
|
2151
|
+
let marketType = undefined;
|
|
2152
|
+
let marginMode = undefined;
|
|
2153
|
+
[marketType, params] = this.handleMarketTypeAndParams('cancelAllOrders', market, params);
|
|
2154
|
+
[marginMode, params] = this.handleMarginModeAndParams('cancelAllOrders', params);
|
|
2155
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
2156
|
+
let response = undefined;
|
|
2157
|
+
if (marginMode !== undefined) {
|
|
2158
|
+
response = await this.privateDeleteMarginOrder(this.extend(request, params));
|
|
2159
|
+
}
|
|
2160
|
+
else {
|
|
2161
|
+
if (marketType === 'spot') {
|
|
2162
|
+
response = await this.privateDeleteSpotOrder(this.extend(request, params));
|
|
2163
|
+
}
|
|
2164
|
+
else if (marketType === 'swap') {
|
|
2165
|
+
response = await this.privateDeleteFuturesOrder(this.extend(request, params));
|
|
2166
|
+
}
|
|
2167
|
+
else if (marketType === 'margin') {
|
|
2168
|
+
response = await this.privateDeleteMarginOrder(this.extend(request, params));
|
|
2169
|
+
}
|
|
2170
|
+
else {
|
|
2171
|
+
throw new errors.NotSupported(this.id + ' cancelAllOrders() not support this market type');
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
return this.parseOrders(response, market);
|
|
2175
|
+
}
|
|
2176
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
2177
|
+
/**
|
|
2178
|
+
* @method
|
|
2179
|
+
* @name hitbtc#cancelOrder
|
|
2180
|
+
* @description cancels an open order
|
|
2181
|
+
* @see https://api.hitbtc.com/#cancel-spot-order
|
|
2182
|
+
* @see https://api.hitbtc.com/#cancel-futures-order
|
|
2183
|
+
* @see https://api.hitbtc.com/#cancel-margin-order
|
|
2184
|
+
* @param {string} id order id
|
|
2185
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
2186
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2187
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
|
|
2188
|
+
* @param {bool} [params.margin] true for canceling a margin order
|
|
2189
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2190
|
+
*/
|
|
2191
|
+
await this.loadMarkets();
|
|
2192
|
+
let market = undefined;
|
|
2193
|
+
const request = {
|
|
2194
|
+
'client_order_id': id,
|
|
2195
|
+
};
|
|
2196
|
+
if (symbol !== undefined) {
|
|
2197
|
+
market = this.market(symbol);
|
|
2198
|
+
}
|
|
2199
|
+
let marketType = undefined;
|
|
2200
|
+
let marginMode = undefined;
|
|
2201
|
+
[marketType, params] = this.handleMarketTypeAndParams('cancelOrder', market, params);
|
|
2202
|
+
[marginMode, params] = this.handleMarginModeAndParams('cancelOrder', params);
|
|
2203
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
2204
|
+
let response = undefined;
|
|
2205
|
+
if (marginMode !== undefined) {
|
|
2206
|
+
response = await this.privateDeleteMarginOrderClientOrderId(this.extend(request, params));
|
|
2207
|
+
}
|
|
2208
|
+
else {
|
|
2209
|
+
if (marketType === 'spot') {
|
|
2210
|
+
response = await this.privateDeleteSpotOrderClientOrderId(this.extend(request, params));
|
|
2211
|
+
}
|
|
2212
|
+
else if (marketType === 'swap') {
|
|
2213
|
+
response = await this.privateDeleteFuturesOrderClientOrderId(this.extend(request, params));
|
|
2214
|
+
}
|
|
2215
|
+
else if (marketType === 'margin') {
|
|
2216
|
+
response = await this.privateDeleteMarginOrderClientOrderId(this.extend(request, params));
|
|
2217
|
+
}
|
|
2218
|
+
else {
|
|
2219
|
+
throw new errors.NotSupported(this.id + ' cancelOrder() not support this market type');
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
return this.parseOrder(response, market);
|
|
2223
|
+
}
|
|
2224
|
+
async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
2225
|
+
await this.loadMarkets();
|
|
2226
|
+
let market = undefined;
|
|
2227
|
+
const request = {
|
|
2228
|
+
'client_order_id': id,
|
|
2229
|
+
'quantity': this.amountToPrecision(symbol, amount),
|
|
2230
|
+
};
|
|
2231
|
+
if ((type === 'limit') || (type === 'stopLimit')) {
|
|
2232
|
+
if (price === undefined) {
|
|
2233
|
+
throw new errors.ExchangeError(this.id + ' editOrder() limit order requires price');
|
|
2234
|
+
}
|
|
2235
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
2236
|
+
}
|
|
2237
|
+
if (symbol !== undefined) {
|
|
2238
|
+
market = this.market(symbol);
|
|
2239
|
+
}
|
|
2240
|
+
let marketType = undefined;
|
|
2241
|
+
let marginMode = undefined;
|
|
2242
|
+
[marketType, params] = this.handleMarketTypeAndParams('editOrder', market, params);
|
|
2243
|
+
[marginMode, params] = this.handleMarginModeAndParams('editOrder', params);
|
|
2244
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
2245
|
+
let response = undefined;
|
|
2246
|
+
if (marginMode !== undefined) {
|
|
2247
|
+
response = await this.privatePatchMarginOrderClientOrderId(this.extend(request, params));
|
|
2248
|
+
}
|
|
2249
|
+
else {
|
|
2250
|
+
if (marketType === 'spot') {
|
|
2251
|
+
response = await this.privatePatchSpotOrderClientOrderId(this.extend(request, params));
|
|
2252
|
+
}
|
|
2253
|
+
else if (marketType === 'swap') {
|
|
2254
|
+
response = await this.privatePatchFuturesOrderClientOrderId(this.extend(request, params));
|
|
2255
|
+
}
|
|
2256
|
+
else if (marketType === 'margin') {
|
|
2257
|
+
response = await this.privatePatchMarginOrderClientOrderId(this.extend(request, params));
|
|
2258
|
+
}
|
|
2259
|
+
else {
|
|
2260
|
+
throw new errors.NotSupported(this.id + ' editOrder() not support this market type');
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
return this.parseOrder(response, market);
|
|
2264
|
+
}
|
|
2265
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
2266
|
+
/**
|
|
2267
|
+
* @method
|
|
2268
|
+
* @name hitbtc#createOrder
|
|
2269
|
+
* @description create a trade order
|
|
2270
|
+
* @see https://api.hitbtc.com/#create-new-spot-order
|
|
2271
|
+
* @see https://api.hitbtc.com/#create-margin-order
|
|
2272
|
+
* @see https://api.hitbtc.com/#create-futures-order
|
|
2273
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
2274
|
+
* @param {string} type 'market' or 'limit'
|
|
2275
|
+
* @param {string} side 'buy' or 'sell'
|
|
2276
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
2277
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
2278
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2279
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported for spot-margin, swap supports both, default is 'cross'
|
|
2280
|
+
* @param {bool} [params.margin] true for creating a margin order
|
|
2281
|
+
* @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
|
|
2282
|
+
* @param {bool} [params.postOnly] if true, the order will only be posted to the order book and not executed immediately
|
|
2283
|
+
* @param {string} [params.timeInForce] "GTC", "IOC", "FOK", "Day", "GTD"
|
|
2284
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2285
|
+
*/
|
|
2286
|
+
await this.loadMarkets();
|
|
2287
|
+
const market = this.market(symbol);
|
|
2288
|
+
let request = undefined;
|
|
2289
|
+
let marketType = undefined;
|
|
2290
|
+
[marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
|
|
2291
|
+
let marginMode = undefined;
|
|
2292
|
+
[marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
|
|
2293
|
+
[request, params] = this.createOrderRequest(market, marketType, type, side, amount, price, marginMode, params);
|
|
2294
|
+
let response = undefined;
|
|
2295
|
+
if (marketType === 'swap') {
|
|
2296
|
+
response = await this.privatePostFuturesOrder(this.extend(request, params));
|
|
2297
|
+
}
|
|
2298
|
+
else if ((marketType === 'margin') || (marginMode !== undefined)) {
|
|
2299
|
+
response = await this.privatePostMarginOrder(this.extend(request, params));
|
|
2300
|
+
}
|
|
2301
|
+
else {
|
|
2302
|
+
response = await this.privatePostSpotOrder(this.extend(request, params));
|
|
2303
|
+
}
|
|
2304
|
+
return this.parseOrder(response, market);
|
|
2305
|
+
}
|
|
2306
|
+
createOrderRequest(market, marketType, type, side, amount, price = undefined, marginMode = undefined, params = {}) {
|
|
2307
|
+
const isLimit = (type === 'limit');
|
|
2308
|
+
const reduceOnly = this.safeValue(params, 'reduceOnly');
|
|
2309
|
+
const timeInForce = this.safeString(params, 'timeInForce');
|
|
2310
|
+
const triggerPrice = this.safeNumberN(params, ['triggerPrice', 'stopPrice', 'stop_price']);
|
|
2311
|
+
const isPostOnly = this.isPostOnly(type === 'market', undefined, params);
|
|
2312
|
+
const request = {
|
|
2313
|
+
'type': type,
|
|
2314
|
+
'side': side,
|
|
2315
|
+
'quantity': this.amountToPrecision(market['symbol'], amount),
|
|
2316
|
+
'symbol': market['id'],
|
|
2317
|
+
// 'client_order_id': 'r42gdPjNMZN-H_xs8RKl2wljg_dfgdg4', // Optional
|
|
2318
|
+
// 'time_in_force': 'GTC', // Optional GTC, IOC, FOK, Day, GTD
|
|
2319
|
+
// 'price': this.priceToPrecision (symbol, price), // Required if type is limit, stopLimit, or takeProfitLimit
|
|
2320
|
+
// 'stop_price': this.safeNumber (params, 'stop_price'), // Required if type is stopLimit, stopMarket, takeProfitLimit, takeProfitMarket
|
|
2321
|
+
// 'expire_time': '2021-06-15T17:01:05.092Z', // Required if timeInForce is GTD
|
|
2322
|
+
// 'strict_validate': false,
|
|
2323
|
+
// 'post_only': false, // Optional
|
|
2324
|
+
// 'reduce_only': false, // Optional
|
|
2325
|
+
// 'display_quantity': '0', // Optional
|
|
2326
|
+
// 'take_rate': 0.001, // Optional
|
|
2327
|
+
// 'make_rate': 0.001, // Optional
|
|
2328
|
+
};
|
|
2329
|
+
if (reduceOnly !== undefined) {
|
|
2330
|
+
if ((market['type'] !== 'swap') && (market['type'] !== 'margin')) {
|
|
2331
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() does not support reduce_only for ' + market['type'] + ' orders, reduce_only orders are supported for swap and margin markets only');
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
if (reduceOnly === true) {
|
|
2335
|
+
request['reduce_only'] = reduceOnly;
|
|
2336
|
+
}
|
|
2337
|
+
if (isPostOnly) {
|
|
2338
|
+
request['post_only'] = true;
|
|
2339
|
+
}
|
|
2340
|
+
if (timeInForce !== undefined) {
|
|
2341
|
+
request['time_in_force'] = timeInForce;
|
|
2342
|
+
}
|
|
2343
|
+
if (isLimit || (type === 'stopLimit') || (type === 'takeProfitLimit')) {
|
|
2344
|
+
if (price === undefined) {
|
|
2345
|
+
throw new errors.ExchangeError(this.id + ' createOrder() requires a price argument for limit orders');
|
|
2346
|
+
}
|
|
2347
|
+
request['price'] = this.priceToPrecision(market['symbol'], price);
|
|
2348
|
+
}
|
|
2349
|
+
if ((timeInForce === 'GTD')) {
|
|
2350
|
+
const expireTime = this.safeString(params, 'expire_time');
|
|
2351
|
+
if (expireTime === undefined) {
|
|
2352
|
+
throw new errors.ExchangeError(this.id + ' createOrder() requires an expire_time parameter for a GTD order');
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
if (triggerPrice !== undefined) {
|
|
2356
|
+
request['stop_price'] = this.priceToPrecision(market['symbol'], triggerPrice);
|
|
2357
|
+
if (isLimit) {
|
|
2358
|
+
request['type'] = 'stopLimit';
|
|
2359
|
+
}
|
|
2360
|
+
else if (type === 'market') {
|
|
2361
|
+
request['type'] = 'stopMarket';
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
else if ((type === 'stopLimit') || (type === 'stopMarket') || (type === 'takeProfitLimit') || (type === 'takeProfitMarket')) {
|
|
2365
|
+
throw new errors.ExchangeError(this.id + ' createOrder() requires a stopPrice parameter for stop-loss and take-profit orders');
|
|
2366
|
+
}
|
|
2367
|
+
params = this.omit(params, ['triggerPrice', 'timeInForce', 'stopPrice', 'stop_price', 'reduceOnly', 'postOnly']);
|
|
2368
|
+
if (marketType === 'swap') {
|
|
2369
|
+
// set default margin mode to cross
|
|
2370
|
+
if (marginMode === undefined) {
|
|
2371
|
+
marginMode = 'cross';
|
|
2372
|
+
}
|
|
2373
|
+
request['margin_mode'] = marginMode;
|
|
2374
|
+
}
|
|
2375
|
+
return [request, params];
|
|
2376
|
+
}
|
|
2377
|
+
parseOrderStatus(status) {
|
|
2378
|
+
const statuses = {
|
|
2379
|
+
'new': 'open',
|
|
2380
|
+
'suspended': 'open',
|
|
2381
|
+
'partiallyFilled': 'open',
|
|
2382
|
+
'filled': 'closed',
|
|
2383
|
+
'canceled': 'canceled',
|
|
2384
|
+
'expired': 'failed',
|
|
2385
|
+
};
|
|
2386
|
+
return this.safeString(statuses, status, status);
|
|
2387
|
+
}
|
|
2388
|
+
parseOrder(order, market = undefined) {
|
|
2389
|
+
//
|
|
2390
|
+
// limit
|
|
2391
|
+
// {
|
|
2392
|
+
// "id": 488953123149,
|
|
2393
|
+
// "client_order_id": "103ad305301e4c3590045b13de15b36e",
|
|
2394
|
+
// "symbol": "BTCUSDT",
|
|
2395
|
+
// "side": "buy",
|
|
2396
|
+
// "status": "new",
|
|
2397
|
+
// "type": "limit",
|
|
2398
|
+
// "time_in_force": "GTC",
|
|
2399
|
+
// "quantity": "0.00001",
|
|
2400
|
+
// "quantity_cumulative": "0",
|
|
2401
|
+
// "price": "0.01",
|
|
2402
|
+
// "price_average": "0.01",
|
|
2403
|
+
// "post_only": false,
|
|
2404
|
+
// "created_at": "2021-04-13T13:06:16.567Z",
|
|
2405
|
+
// "updated_at": "2021-04-13T13:06:16.567Z"
|
|
2406
|
+
// }
|
|
2407
|
+
//
|
|
2408
|
+
// market
|
|
2409
|
+
// {
|
|
2410
|
+
// "id": "685877626834",
|
|
2411
|
+
// "client_order_id": "Yshl7G-EjaREyXQYaGbsmdtVbW-nzQwu",
|
|
2412
|
+
// "symbol": "BTCUSDT",
|
|
2413
|
+
// "side": "buy",
|
|
2414
|
+
// "status": "filled",
|
|
2415
|
+
// "type": "market",
|
|
2416
|
+
// "time_in_force": "GTC",
|
|
2417
|
+
// "quantity": "0.00010",
|
|
2418
|
+
// "quantity_cumulative": "0.00010",
|
|
2419
|
+
// "post_only": false,
|
|
2420
|
+
// "created_at": "2021-10-26T08:55:55.1Z",
|
|
2421
|
+
// "updated_at": "2021-10-26T08:55:55.1Z",
|
|
2422
|
+
// "trades": [
|
|
2423
|
+
// {
|
|
2424
|
+
// "id": "1437229630",
|
|
2425
|
+
// "position_id": "0",
|
|
2426
|
+
// "quantity": "0.00010",
|
|
2427
|
+
// "price": "62884.78",
|
|
2428
|
+
// "fee": "0.005659630200",
|
|
2429
|
+
// "timestamp": "2021-10-26T08:55:55.1Z",
|
|
2430
|
+
// "taker": true
|
|
2431
|
+
// }
|
|
2432
|
+
// ]
|
|
2433
|
+
// }
|
|
2434
|
+
//
|
|
2435
|
+
// swap and margin
|
|
2436
|
+
//
|
|
2437
|
+
// {
|
|
2438
|
+
// "id": 58418961892,
|
|
2439
|
+
// "client_order_id": "r42gdPjNMZN-H_xs8RKl2wljg_dfgdg4",
|
|
2440
|
+
// "symbol": "BTCUSDT_PERP",
|
|
2441
|
+
// "side": "buy",
|
|
2442
|
+
// "status": "new",
|
|
2443
|
+
// "type": "limit",
|
|
2444
|
+
// "time_in_force": "GTC",
|
|
2445
|
+
// "quantity": "0.0005",
|
|
2446
|
+
// "quantity_cumulative": "0",
|
|
2447
|
+
// "price": "30000.00",
|
|
2448
|
+
// "post_only": false,
|
|
2449
|
+
// "reduce_only": false,
|
|
2450
|
+
// "created_at": "2022-03-16T08:16:53.039Z",
|
|
2451
|
+
// "updated_at": "2022-03-16T08:16:53.039Z"
|
|
2452
|
+
// }
|
|
2453
|
+
//
|
|
2454
|
+
const id = this.safeString(order, 'client_order_id');
|
|
2455
|
+
// we use clientOrderId as the order id with this exchange intentionally
|
|
2456
|
+
// because most of their endpoints will require clientOrderId
|
|
2457
|
+
// explained here: https://github.com/ccxt/ccxt/issues/5674
|
|
2458
|
+
const side = this.safeString(order, 'side');
|
|
2459
|
+
const type = this.safeString(order, 'type');
|
|
2460
|
+
const amount = this.safeString(order, 'quantity');
|
|
2461
|
+
const price = this.safeString(order, 'price');
|
|
2462
|
+
const average = this.safeString(order, 'price_average');
|
|
2463
|
+
const created = this.safeString(order, 'created_at');
|
|
2464
|
+
const timestamp = this.parse8601(created);
|
|
2465
|
+
const updated = this.safeString(order, 'updated_at');
|
|
2466
|
+
let lastTradeTimestamp = undefined;
|
|
2467
|
+
if (updated !== created) {
|
|
2468
|
+
lastTradeTimestamp = this.parse8601(updated);
|
|
2469
|
+
}
|
|
2470
|
+
const filled = this.safeString(order, 'quantity_cumulative');
|
|
2471
|
+
const status = this.parseOrderStatus(this.safeString(order, 'status'));
|
|
2472
|
+
const marketId = this.safeString(order, 'symbol');
|
|
2473
|
+
market = this.safeMarket(marketId, market);
|
|
2474
|
+
const symbol = market['symbol'];
|
|
2475
|
+
const postOnly = this.safeValue(order, 'post_only');
|
|
2476
|
+
const timeInForce = this.safeString(order, 'time_in_force');
|
|
2477
|
+
const rawTrades = this.safeValue(order, 'trades');
|
|
2478
|
+
const stopPrice = this.safeString(order, 'stop_price');
|
|
2479
|
+
return this.safeOrder({
|
|
2480
|
+
'info': order,
|
|
2481
|
+
'id': id,
|
|
2482
|
+
'clientOrderId': id,
|
|
2483
|
+
'timestamp': timestamp,
|
|
2484
|
+
'datetime': this.iso8601(timestamp),
|
|
2485
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
|
2486
|
+
'lastUpdateTimestamp': lastTradeTimestamp,
|
|
2487
|
+
'symbol': symbol,
|
|
2488
|
+
'price': price,
|
|
2489
|
+
'amount': amount,
|
|
2490
|
+
'type': type,
|
|
2491
|
+
'side': side,
|
|
2492
|
+
'timeInForce': timeInForce,
|
|
2493
|
+
'postOnly': postOnly,
|
|
2494
|
+
'reduceOnly': this.safeValue(order, 'reduce_only'),
|
|
2495
|
+
'filled': filled,
|
|
2496
|
+
'remaining': undefined,
|
|
2497
|
+
'cost': undefined,
|
|
2498
|
+
'status': status,
|
|
2499
|
+
'average': average,
|
|
2500
|
+
'trades': rawTrades,
|
|
2501
|
+
'fee': undefined,
|
|
2502
|
+
'stopPrice': stopPrice,
|
|
2503
|
+
'triggerPrice': stopPrice,
|
|
2504
|
+
'takeProfitPrice': undefined,
|
|
2505
|
+
'stopLossPrice': undefined,
|
|
2506
|
+
}, market);
|
|
2507
|
+
}
|
|
2508
|
+
async fetchMarginMode(symbol = undefined, params = {}) {
|
|
2509
|
+
/**
|
|
2510
|
+
* @method
|
|
2511
|
+
* @name hitbtc#fetchMarginMode
|
|
2512
|
+
* @description fetches margin mode of the user
|
|
2513
|
+
* @see https://api.hitbtc.com/#get-margin-position-parameters
|
|
2514
|
+
* @see https://api.hitbtc.com/#get-futures-position-parameters
|
|
2515
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
2516
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2517
|
+
* @returns {object} Struct of MarginMode
|
|
2518
|
+
*/
|
|
2519
|
+
await this.loadMarkets();
|
|
2520
|
+
let market = undefined;
|
|
2521
|
+
if (symbol !== undefined) {
|
|
2522
|
+
market = this.market(symbol);
|
|
2523
|
+
}
|
|
2524
|
+
let marketType = undefined;
|
|
2525
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchMarginMode', market, params);
|
|
2526
|
+
let response = undefined;
|
|
2527
|
+
if (marketType === 'margin') {
|
|
2528
|
+
response = await this.privateGetMarginConfig(params);
|
|
2529
|
+
}
|
|
2530
|
+
else if (marketType === 'swap') {
|
|
2531
|
+
response = await this.privateGetFuturesConfig(params);
|
|
2532
|
+
}
|
|
2533
|
+
else {
|
|
2534
|
+
throw new errors.BadSymbol(this.id + ' fetchMarginMode() supports swap contracts and margin only');
|
|
2535
|
+
}
|
|
2536
|
+
//
|
|
2537
|
+
// margin
|
|
2538
|
+
// {
|
|
2539
|
+
// "config": [{
|
|
2540
|
+
// "symbol": "BTCUSD",
|
|
2541
|
+
// "margin_call_leverage_mul": "1.50",
|
|
2542
|
+
// "liquidation_leverage_mul": "2.00",
|
|
2543
|
+
// "max_initial_leverage": "10.00",
|
|
2544
|
+
// "margin_mode": "Isolated",
|
|
2545
|
+
// "force_close_fee": "0.05",
|
|
2546
|
+
// "enabled": true,
|
|
2547
|
+
// "active": true,
|
|
2548
|
+
// "limit_base": "50000.00",
|
|
2549
|
+
// "limit_power": "2.2",
|
|
2550
|
+
// "unlimited_threshold": "10.0"
|
|
2551
|
+
// }]
|
|
2552
|
+
// }
|
|
2553
|
+
//
|
|
2554
|
+
// swap
|
|
2555
|
+
// {
|
|
2556
|
+
// "config": [{
|
|
2557
|
+
// "symbol": "BTCUSD_PERP",
|
|
2558
|
+
// "margin_call_leverage_mul": "1.20",
|
|
2559
|
+
// "liquidation_leverage_mul": "2.00",
|
|
2560
|
+
// "max_initial_leverage": "100.00",
|
|
2561
|
+
// "margin_mode": "Isolated",
|
|
2562
|
+
// "force_close_fee": "0.001",
|
|
2563
|
+
// "enabled": true,
|
|
2564
|
+
// "active": false,
|
|
2565
|
+
// "limit_base": "5000000.000000000000",
|
|
2566
|
+
// "limit_power": "1.25",
|
|
2567
|
+
// "unlimited_threshold": "2.00"
|
|
2568
|
+
// }]
|
|
2569
|
+
// }
|
|
2570
|
+
//
|
|
2571
|
+
const config = this.safeValue(response, 'config', []);
|
|
2572
|
+
const marginModes = [];
|
|
2573
|
+
for (let i = 0; i < config.length; i++) {
|
|
2574
|
+
const data = this.safeValue(config, i);
|
|
2575
|
+
const marketId = this.safeString(data, 'symbol');
|
|
2576
|
+
const marketInner = this.safeMarket(marketId);
|
|
2577
|
+
marginModes.push({
|
|
2578
|
+
'info': data,
|
|
2579
|
+
'symbol': this.safeString(marketInner, 'symbol'),
|
|
2580
|
+
'marginMode': this.safeStringLower(data, 'margin_mode'),
|
|
2581
|
+
});
|
|
2582
|
+
}
|
|
2583
|
+
const filteredMargin = this.filterBySymbol(marginModes, symbol);
|
|
2584
|
+
return this.safeValue(filteredMargin, 0);
|
|
2585
|
+
}
|
|
2586
|
+
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
2587
|
+
/**
|
|
2588
|
+
* @method
|
|
2589
|
+
* @name hitbtc#transfer
|
|
2590
|
+
* @description transfer currency internally between wallets on the same account
|
|
2591
|
+
* @see https://api.hitbtc.com/#transfer-between-wallet-and-exchange
|
|
2592
|
+
* @param {string} code unified currency code
|
|
2593
|
+
* @param {float} amount amount to transfer
|
|
2594
|
+
* @param {string} fromAccount account to transfer from
|
|
2595
|
+
* @param {string} toAccount account to transfer to
|
|
2596
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2597
|
+
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
2598
|
+
*/
|
|
2599
|
+
// account can be "spot", "wallet", or "derivatives"
|
|
2600
|
+
await this.loadMarkets();
|
|
2601
|
+
const currency = this.currency(code);
|
|
2602
|
+
const requestAmount = this.currencyToPrecision(code, amount);
|
|
2603
|
+
const accountsByType = this.safeValue(this.options, 'accountsByType', {});
|
|
2604
|
+
fromAccount = fromAccount.toLowerCase();
|
|
2605
|
+
toAccount = toAccount.toLowerCase();
|
|
2606
|
+
const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
|
|
2607
|
+
const toId = this.safeString(accountsByType, toAccount, toAccount);
|
|
2608
|
+
if (fromId === toId) {
|
|
2609
|
+
throw new errors.BadRequest(this.id + ' transfer() fromAccount and toAccount arguments cannot be the same account');
|
|
2610
|
+
}
|
|
2611
|
+
const request = {
|
|
2612
|
+
'currency': currency['id'],
|
|
2613
|
+
'amount': requestAmount,
|
|
2614
|
+
'source': fromId,
|
|
2615
|
+
'destination': toId,
|
|
2616
|
+
};
|
|
2617
|
+
const response = await this.privatePostWalletTransfer(this.extend(request, params));
|
|
2618
|
+
//
|
|
2619
|
+
// [
|
|
2620
|
+
// "2db6ebab-fb26-4537-9ef8-1a689472d236"
|
|
2621
|
+
// ]
|
|
2622
|
+
//
|
|
2623
|
+
return this.parseTransfer(response, currency);
|
|
2624
|
+
}
|
|
2625
|
+
parseTransfer(transfer, currency = undefined) {
|
|
2626
|
+
//
|
|
2627
|
+
// transfer
|
|
2628
|
+
//
|
|
2629
|
+
// [
|
|
2630
|
+
// "2db6ebab-fb26-4537-9ef8-1a689472d236"
|
|
2631
|
+
// ]
|
|
2632
|
+
//
|
|
2633
|
+
return {
|
|
2634
|
+
'id': this.safeString(transfer, 0),
|
|
2635
|
+
'timestamp': undefined,
|
|
2636
|
+
'datetime': undefined,
|
|
2637
|
+
'currency': this.safeCurrencyCode(undefined, currency),
|
|
2638
|
+
'amount': undefined,
|
|
2639
|
+
'fromAccount': undefined,
|
|
2640
|
+
'toAccount': undefined,
|
|
2641
|
+
'status': undefined,
|
|
2642
|
+
'info': transfer,
|
|
2643
|
+
};
|
|
2644
|
+
}
|
|
2645
|
+
async convertCurrencyNetwork(code, amount, fromNetwork, toNetwork, params) {
|
|
2646
|
+
await this.loadMarkets();
|
|
2647
|
+
if (code !== 'USDT') {
|
|
2648
|
+
throw new errors.ExchangeError(this.id + ' convertCurrencyNetwork() only supports USDT currently');
|
|
2649
|
+
}
|
|
2650
|
+
const networks = this.safeValue(this.options, 'networks', {});
|
|
2651
|
+
fromNetwork = fromNetwork.toUpperCase();
|
|
2652
|
+
toNetwork = toNetwork.toUpperCase();
|
|
2653
|
+
fromNetwork = this.safeString(networks, fromNetwork); // handle ETH>ERC20 alias
|
|
2654
|
+
toNetwork = this.safeString(networks, toNetwork); // handle ETH>ERC20 alias
|
|
2655
|
+
if (fromNetwork === toNetwork) {
|
|
2656
|
+
throw new errors.BadRequest(this.id + ' convertCurrencyNetwork() fromNetwork cannot be the same as toNetwork');
|
|
2657
|
+
}
|
|
2658
|
+
if ((fromNetwork === undefined) || (toNetwork === undefined)) {
|
|
2659
|
+
const keys = Object.keys(networks);
|
|
2660
|
+
throw new errors.ArgumentsRequired(this.id + ' convertCurrencyNetwork() requires a fromNetwork parameter and a toNetwork parameter, supported networks are ' + keys.join(', '));
|
|
2661
|
+
}
|
|
2662
|
+
const request = {
|
|
2663
|
+
'from_currency': fromNetwork,
|
|
2664
|
+
'to_currency': toNetwork,
|
|
2665
|
+
'amount': this.currencyToPrecision(code, amount),
|
|
2666
|
+
};
|
|
2667
|
+
const response = await this.privatePostWalletConvert(this.extend(request, params));
|
|
2668
|
+
// {"result":["587a1868-e62d-4d8e-b27c-dbdb2ee96149","e168df74-c041-41f2-b76c-e43e4fed5bc7"]}
|
|
2669
|
+
return {
|
|
2670
|
+
'info': response,
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2674
|
+
/**
|
|
2675
|
+
* @method
|
|
2676
|
+
* @name hitbtc#withdraw
|
|
2677
|
+
* @description make a withdrawal
|
|
2678
|
+
* @see https://api.hitbtc.com/#withdraw-crypto
|
|
2679
|
+
* @param {string} code unified currency code
|
|
2680
|
+
* @param {float} amount the amount to withdraw
|
|
2681
|
+
* @param {string} address the address to withdraw to
|
|
2682
|
+
* @param {string} tag
|
|
2683
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2684
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2685
|
+
*/
|
|
2686
|
+
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
2687
|
+
await this.loadMarkets();
|
|
2688
|
+
this.checkAddress(address);
|
|
2689
|
+
const currency = this.currency(code);
|
|
2690
|
+
const request = {
|
|
2691
|
+
'currency': currency['id'],
|
|
2692
|
+
'amount': amount,
|
|
2693
|
+
'address': address,
|
|
2694
|
+
};
|
|
2695
|
+
if (tag !== undefined) {
|
|
2696
|
+
request['payment_id'] = tag;
|
|
2697
|
+
}
|
|
2698
|
+
const networks = this.safeValue(this.options, 'networks', {});
|
|
2699
|
+
const network = this.safeStringUpper(params, 'network');
|
|
2700
|
+
if ((network !== undefined) && (code === 'USDT')) {
|
|
2701
|
+
const parsedNetwork = this.safeString(networks, network);
|
|
2702
|
+
if (parsedNetwork !== undefined) {
|
|
2703
|
+
request['currency'] = parsedNetwork;
|
|
2704
|
+
}
|
|
2705
|
+
params = this.omit(params, 'network');
|
|
2706
|
+
}
|
|
2707
|
+
const withdrawOptions = this.safeValue(this.options, 'withdraw', {});
|
|
2708
|
+
const includeFee = this.safeValue(withdrawOptions, 'includeFee', false);
|
|
2709
|
+
if (includeFee) {
|
|
2710
|
+
request['include_fee'] = true;
|
|
2711
|
+
}
|
|
2712
|
+
const response = await this.privatePostWalletCryptoWithdraw(this.extend(request, params));
|
|
2713
|
+
//
|
|
2714
|
+
// {
|
|
2715
|
+
// "id":"084cfcd5-06b9-4826-882e-fdb75ec3625d"
|
|
2716
|
+
// }
|
|
2717
|
+
//
|
|
2718
|
+
return this.parseTransaction(response, currency);
|
|
2719
|
+
}
|
|
2720
|
+
async fetchFundingRates(symbols = undefined, params = {}) {
|
|
2721
|
+
/**
|
|
2722
|
+
* @method
|
|
2723
|
+
* @name hitbtc#fetchFundingRates
|
|
2724
|
+
* @description fetches funding rates for multiple markets
|
|
2725
|
+
* @see https://api.hitbtc.com/#futures-info
|
|
2726
|
+
* @param {string[]} symbols unified symbols of the markets to fetch the funding rates for, all market funding rates are returned if not assigned
|
|
2727
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2728
|
+
* @returns {object} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
2729
|
+
*/
|
|
2730
|
+
await this.loadMarkets();
|
|
2731
|
+
let market = undefined;
|
|
2732
|
+
const request = {};
|
|
2733
|
+
if (symbols !== undefined) {
|
|
2734
|
+
symbols = this.marketSymbols(symbols);
|
|
2735
|
+
market = this.market(symbols[0]);
|
|
2736
|
+
const queryMarketIds = this.marketIds(symbols);
|
|
2737
|
+
request['symbols'] = queryMarketIds.join(',');
|
|
2738
|
+
}
|
|
2739
|
+
let type = undefined;
|
|
2740
|
+
[type, params] = this.handleMarketTypeAndParams('fetchFundingRates', market, params);
|
|
2741
|
+
if (type !== 'swap') {
|
|
2742
|
+
throw new errors.NotSupported(this.id + ' fetchFundingRates() does not support ' + type + ' markets');
|
|
2743
|
+
}
|
|
2744
|
+
const response = await this.publicGetPublicFuturesInfo(this.extend(request, params));
|
|
2745
|
+
//
|
|
2746
|
+
// {
|
|
2747
|
+
// "BTCUSDT_PERP": {
|
|
2748
|
+
// "contract_type": "perpetual",
|
|
2749
|
+
// "mark_price": "30897.68",
|
|
2750
|
+
// "index_price": "30895.29",
|
|
2751
|
+
// "funding_rate": "0.0001",
|
|
2752
|
+
// "open_interest": "93.7128",
|
|
2753
|
+
// "next_funding_time": "2021-07-21T16:00:00.000Z",
|
|
2754
|
+
// "indicative_funding_rate": "0.0001",
|
|
2755
|
+
// "premium_index": "0.000047541807127312",
|
|
2756
|
+
// "avg_premium_index": "0.000087063368020112",
|
|
2757
|
+
// "interest_rate": "0.0001",
|
|
2758
|
+
// "timestamp": "2021-07-21T09:48:37.235Z"
|
|
2759
|
+
// }
|
|
2760
|
+
// }
|
|
2761
|
+
//
|
|
2762
|
+
const marketIds = Object.keys(response);
|
|
2763
|
+
const fundingRates = {};
|
|
2764
|
+
for (let i = 0; i < marketIds.length; i++) {
|
|
2765
|
+
const marketId = this.safeString(marketIds, i);
|
|
2766
|
+
const rawFundingRate = this.safeValue(response, marketId);
|
|
2767
|
+
const marketInner = this.market(marketId);
|
|
2768
|
+
const symbol = marketInner['symbol'];
|
|
2769
|
+
const fundingRate = this.parseFundingRate(rawFundingRate, marketInner);
|
|
2770
|
+
fundingRates[symbol] = fundingRate;
|
|
2771
|
+
}
|
|
2772
|
+
return this.filterByArray(fundingRates, 'symbol', symbols);
|
|
2773
|
+
}
|
|
2774
|
+
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2775
|
+
/**
|
|
2776
|
+
* @method
|
|
2777
|
+
* @name hitbtc#fetchFundingRateHistory
|
|
2778
|
+
* @see https://api.hitbtc.com/#funding-history
|
|
2779
|
+
* @description fetches historical funding rate prices
|
|
2780
|
+
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
2781
|
+
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
2782
|
+
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
|
2783
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2784
|
+
* @param {int} [params.until] timestamp in ms of the latest funding rate
|
|
2785
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
2786
|
+
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
|
|
2787
|
+
*/
|
|
2788
|
+
await this.loadMarkets();
|
|
2789
|
+
let paginate = false;
|
|
2790
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
|
|
2791
|
+
if (paginate) {
|
|
2792
|
+
return await this.fetchPaginatedCallDeterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 1000);
|
|
2793
|
+
}
|
|
2794
|
+
let market = undefined;
|
|
2795
|
+
let request = {
|
|
2796
|
+
// all arguments are optional
|
|
2797
|
+
// 'symbols': Comma separated list of symbol codes,
|
|
2798
|
+
// 'sort': 'DESC' or 'ASC'
|
|
2799
|
+
// 'from': 'Datetime or Number',
|
|
2800
|
+
// 'till': 'Datetime or Number',
|
|
2801
|
+
// 'limit': 100,
|
|
2802
|
+
// 'offset': 0,
|
|
2803
|
+
};
|
|
2804
|
+
[request, params] = this.handleUntilOption('till', request, params);
|
|
2805
|
+
if (symbol !== undefined) {
|
|
2806
|
+
market = this.market(symbol);
|
|
2807
|
+
symbol = market['symbol'];
|
|
2808
|
+
request['symbols'] = market['id'];
|
|
2809
|
+
}
|
|
2810
|
+
if (since !== undefined) {
|
|
2811
|
+
request['from'] = since;
|
|
2812
|
+
}
|
|
2813
|
+
if (limit !== undefined) {
|
|
2814
|
+
request['limit'] = limit;
|
|
2815
|
+
}
|
|
2816
|
+
const response = await this.publicGetPublicFuturesHistoryFunding(this.extend(request, params));
|
|
2817
|
+
//
|
|
2818
|
+
// {
|
|
2819
|
+
// "BTCUSDT_PERP": [
|
|
2820
|
+
// {
|
|
2821
|
+
// "timestamp": "2021-07-29T16:00:00.271Z",
|
|
2822
|
+
// "funding_rate": "0.0001",
|
|
2823
|
+
// "avg_premium_index": "0.000061858585213222",
|
|
2824
|
+
// "next_funding_time": "2021-07-30T00:00:00.000Z",
|
|
2825
|
+
// "interest_rate": "0.0001"
|
|
2826
|
+
// },
|
|
2827
|
+
// ...
|
|
2828
|
+
// ],
|
|
2829
|
+
// ...
|
|
2830
|
+
// }
|
|
2831
|
+
//
|
|
2832
|
+
const contracts = Object.keys(response);
|
|
2833
|
+
const rates = [];
|
|
2834
|
+
for (let i = 0; i < contracts.length; i++) {
|
|
2835
|
+
const marketId = contracts[i];
|
|
2836
|
+
const marketInner = this.safeMarket(marketId);
|
|
2837
|
+
const fundingRateData = response[marketId];
|
|
2838
|
+
for (let j = 0; j < fundingRateData.length; j++) {
|
|
2839
|
+
const entry = fundingRateData[j];
|
|
2840
|
+
const symbolInner = this.safeSymbol(marketInner['symbol']);
|
|
2841
|
+
const fundingRate = this.safeNumber(entry, 'funding_rate');
|
|
2842
|
+
const datetime = this.safeString(entry, 'timestamp');
|
|
2843
|
+
rates.push({
|
|
2844
|
+
'info': entry,
|
|
2845
|
+
'symbol': symbolInner,
|
|
2846
|
+
'fundingRate': fundingRate,
|
|
2847
|
+
'timestamp': this.parse8601(datetime),
|
|
2848
|
+
'datetime': datetime,
|
|
2849
|
+
});
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
const sorted = this.sortBy(rates, 'timestamp');
|
|
2853
|
+
return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
|
|
2854
|
+
}
|
|
2855
|
+
async fetchPositions(symbols = undefined, params = {}) {
|
|
2856
|
+
/**
|
|
2857
|
+
* @method
|
|
2858
|
+
* @name hitbtc#fetchPositions
|
|
2859
|
+
* @description fetch all open positions
|
|
2860
|
+
* @see https://api.hitbtc.com/#get-futures-margin-accounts
|
|
2861
|
+
* @see https://api.hitbtc.com/#get-all-margin-accounts
|
|
2862
|
+
* @param {string[]|undefined} symbols not used by hitbtc fetchPositions ()
|
|
2863
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2864
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to spot-margin endpoint if this is set
|
|
2865
|
+
* @param {bool} [params.margin] true for fetching spot-margin positions
|
|
2866
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2867
|
+
*/
|
|
2868
|
+
await this.loadMarkets();
|
|
2869
|
+
const request = {};
|
|
2870
|
+
let marketType = undefined;
|
|
2871
|
+
let marginMode = undefined;
|
|
2872
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchPositions', undefined, params);
|
|
2873
|
+
if (marketType === 'spot') {
|
|
2874
|
+
marketType = 'swap';
|
|
2875
|
+
}
|
|
2876
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchPositions', params);
|
|
2877
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
2878
|
+
let response = undefined;
|
|
2879
|
+
if (marginMode !== undefined) {
|
|
2880
|
+
response = await this.privateGetMarginAccount(this.extend(request, params));
|
|
2881
|
+
}
|
|
2882
|
+
else {
|
|
2883
|
+
if (marketType === 'swap') {
|
|
2884
|
+
response = await this.privateGetFuturesAccount(this.extend(request, params));
|
|
2885
|
+
}
|
|
2886
|
+
else if (marketType === 'margin') {
|
|
2887
|
+
response = await this.privateGetMarginAccount(this.extend(request, params));
|
|
2888
|
+
}
|
|
2889
|
+
else {
|
|
2890
|
+
throw new errors.NotSupported(this.id + ' fetchPositions() not support this market type');
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
//
|
|
2894
|
+
// [
|
|
2895
|
+
// {
|
|
2896
|
+
// "symbol": "ETHUSDT_PERP",
|
|
2897
|
+
// "type": "isolated",
|
|
2898
|
+
// "leverage": "10.00",
|
|
2899
|
+
// "created_at": "2022-03-19T07:54:35.24Z",
|
|
2900
|
+
// "updated_at": "2022-03-19T07:54:58.922Z",
|
|
2901
|
+
// currencies": [
|
|
2902
|
+
// {
|
|
2903
|
+
// "code": "USDT",
|
|
2904
|
+
// "margin_balance": "7.478100643043",
|
|
2905
|
+
// "reserved_orders": "0",
|
|
2906
|
+
// "reserved_positions": "0.303530761300"
|
|
2907
|
+
// }
|
|
2908
|
+
// ],
|
|
2909
|
+
// "positions": [
|
|
2910
|
+
// {
|
|
2911
|
+
// "id": 2470568,
|
|
2912
|
+
// "symbol": "ETHUSDT_PERP",
|
|
2913
|
+
// "quantity": "0.001",
|
|
2914
|
+
// "price_entry": "2927.509",
|
|
2915
|
+
// "price_margin_call": "0",
|
|
2916
|
+
// "price_liquidation": "0",
|
|
2917
|
+
// "pnl": "0",
|
|
2918
|
+
// "created_at": "2022-03-19T07:54:35.24Z",
|
|
2919
|
+
// "updated_at": "2022-03-19T07:54:58.922Z"
|
|
2920
|
+
// }
|
|
2921
|
+
// ]
|
|
2922
|
+
// },
|
|
2923
|
+
// ]
|
|
2924
|
+
//
|
|
2925
|
+
const result = [];
|
|
2926
|
+
for (let i = 0; i < response.length; i++) {
|
|
2927
|
+
result.push(this.parsePosition(response[i]));
|
|
2928
|
+
}
|
|
2929
|
+
return result;
|
|
2930
|
+
}
|
|
2931
|
+
async fetchPosition(symbol, params = {}) {
|
|
2932
|
+
/**
|
|
2933
|
+
* @method
|
|
2934
|
+
* @name hitbtc#fetchPosition
|
|
2935
|
+
* @description fetch data on a single open contract trade position
|
|
2936
|
+
* @see https://api.hitbtc.com/#get-futures-margin-account
|
|
2937
|
+
* @see https://api.hitbtc.com/#get-isolated-margin-account
|
|
2938
|
+
* @param {string} symbol unified market symbol of the market the position is held in, default is undefined
|
|
2939
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2940
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to spot-margin endpoint if this is set
|
|
2941
|
+
* @param {bool} [params.margin] true for fetching a spot-margin position
|
|
2942
|
+
* @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2943
|
+
*/
|
|
2944
|
+
await this.loadMarkets();
|
|
2945
|
+
const market = this.market(symbol);
|
|
2946
|
+
const request = {
|
|
2947
|
+
'symbol': market['id'],
|
|
2948
|
+
};
|
|
2949
|
+
let marketType = undefined;
|
|
2950
|
+
let marginMode = undefined;
|
|
2951
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchPosition', undefined, params);
|
|
2952
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchPosition', params);
|
|
2953
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
2954
|
+
let response = undefined;
|
|
2955
|
+
if (marginMode !== undefined) {
|
|
2956
|
+
response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
|
|
2957
|
+
}
|
|
2958
|
+
else {
|
|
2959
|
+
if (marketType === 'swap') {
|
|
2960
|
+
response = await this.privateGetFuturesAccountIsolatedSymbol(this.extend(request, params));
|
|
2961
|
+
}
|
|
2962
|
+
else if (marketType === 'margin') {
|
|
2963
|
+
response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
|
|
2964
|
+
}
|
|
2965
|
+
else {
|
|
2966
|
+
throw new errors.NotSupported(this.id + ' fetchPosition() not support this market type');
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
//
|
|
2970
|
+
// [
|
|
2971
|
+
// {
|
|
2972
|
+
// "symbol": "ETHUSDT_PERP",
|
|
2973
|
+
// "type": "isolated",
|
|
2974
|
+
// "leverage": "10.00",
|
|
2975
|
+
// "created_at": "2022-03-19T07:54:35.24Z",
|
|
2976
|
+
// "updated_at": "2022-03-19T07:54:58.922Z",
|
|
2977
|
+
// currencies": [
|
|
2978
|
+
// {
|
|
2979
|
+
// "code": "USDT",
|
|
2980
|
+
// "margin_balance": "7.478100643043",
|
|
2981
|
+
// "reserved_orders": "0",
|
|
2982
|
+
// "reserved_positions": "0.303530761300"
|
|
2983
|
+
// }
|
|
2984
|
+
// ],
|
|
2985
|
+
// "positions": [
|
|
2986
|
+
// {
|
|
2987
|
+
// "id": 2470568,
|
|
2988
|
+
// "symbol": "ETHUSDT_PERP",
|
|
2989
|
+
// "quantity": "0.001",
|
|
2990
|
+
// "price_entry": "2927.509",
|
|
2991
|
+
// "price_margin_call": "0",
|
|
2992
|
+
// "price_liquidation": "0",
|
|
2993
|
+
// "pnl": "0",
|
|
2994
|
+
// "created_at": "2022-03-19T07:54:35.24Z",
|
|
2995
|
+
// "updated_at": "2022-03-19T07:54:58.922Z"
|
|
2996
|
+
// }
|
|
2997
|
+
// ]
|
|
2998
|
+
// },
|
|
2999
|
+
// ]
|
|
3000
|
+
//
|
|
3001
|
+
return this.parsePosition(response, market);
|
|
3002
|
+
}
|
|
3003
|
+
parsePosition(position, market = undefined) {
|
|
3004
|
+
//
|
|
3005
|
+
// [
|
|
3006
|
+
// {
|
|
3007
|
+
// "symbol": "ETHUSDT_PERP",
|
|
3008
|
+
// "type": "isolated",
|
|
3009
|
+
// "leverage": "10.00",
|
|
3010
|
+
// "created_at": "2022-03-19T07:54:35.24Z",
|
|
3011
|
+
// "updated_at": "2022-03-19T07:54:58.922Z",
|
|
3012
|
+
// currencies": [
|
|
3013
|
+
// {
|
|
3014
|
+
// "code": "USDT",
|
|
3015
|
+
// "margin_balance": "7.478100643043",
|
|
3016
|
+
// "reserved_orders": "0",
|
|
3017
|
+
// "reserved_positions": "0.303530761300"
|
|
3018
|
+
// }
|
|
3019
|
+
// ],
|
|
3020
|
+
// "positions": [
|
|
3021
|
+
// {
|
|
3022
|
+
// "id": 2470568,
|
|
3023
|
+
// "symbol": "ETHUSDT_PERP",
|
|
3024
|
+
// "quantity": "0.001",
|
|
3025
|
+
// "price_entry": "2927.509",
|
|
3026
|
+
// "price_margin_call": "0",
|
|
3027
|
+
// "price_liquidation": "0",
|
|
3028
|
+
// "pnl": "0",
|
|
3029
|
+
// "created_at": "2022-03-19T07:54:35.24Z",
|
|
3030
|
+
// "updated_at": "2022-03-19T07:54:58.922Z"
|
|
3031
|
+
// }
|
|
3032
|
+
// ]
|
|
3033
|
+
// },
|
|
3034
|
+
// ]
|
|
3035
|
+
//
|
|
3036
|
+
const marginMode = this.safeString(position, 'type');
|
|
3037
|
+
const leverage = this.safeNumber(position, 'leverage');
|
|
3038
|
+
const datetime = this.safeString(position, 'updated_at');
|
|
3039
|
+
const positions = this.safeValue(position, 'positions', []);
|
|
3040
|
+
let liquidationPrice = undefined;
|
|
3041
|
+
let entryPrice = undefined;
|
|
3042
|
+
let contracts = undefined;
|
|
3043
|
+
for (let i = 0; i < positions.length; i++) {
|
|
3044
|
+
const entry = positions[i];
|
|
3045
|
+
liquidationPrice = this.safeNumber(entry, 'price_liquidation');
|
|
3046
|
+
entryPrice = this.safeNumber(entry, 'price_entry');
|
|
3047
|
+
contracts = this.safeNumber(entry, 'quantity');
|
|
3048
|
+
}
|
|
3049
|
+
const currencies = this.safeValue(position, 'currencies', []);
|
|
3050
|
+
let collateral = undefined;
|
|
3051
|
+
for (let i = 0; i < currencies.length; i++) {
|
|
3052
|
+
const entry = currencies[i];
|
|
3053
|
+
collateral = this.safeNumber(entry, 'margin_balance');
|
|
3054
|
+
}
|
|
3055
|
+
const marketId = this.safeString(position, 'symbol');
|
|
3056
|
+
market = this.safeMarket(marketId, market);
|
|
3057
|
+
const symbol = market['symbol'];
|
|
3058
|
+
return this.safePosition({
|
|
3059
|
+
'info': position,
|
|
3060
|
+
'id': undefined,
|
|
3061
|
+
'symbol': symbol,
|
|
3062
|
+
'notional': undefined,
|
|
3063
|
+
'marginMode': marginMode,
|
|
3064
|
+
'marginType': marginMode,
|
|
3065
|
+
'liquidationPrice': liquidationPrice,
|
|
3066
|
+
'entryPrice': entryPrice,
|
|
3067
|
+
'unrealizedPnl': undefined,
|
|
3068
|
+
'percentage': undefined,
|
|
3069
|
+
'contracts': contracts,
|
|
3070
|
+
'contractSize': undefined,
|
|
3071
|
+
'markPrice': undefined,
|
|
3072
|
+
'lastPrice': undefined,
|
|
3073
|
+
'side': undefined,
|
|
3074
|
+
'hedged': undefined,
|
|
3075
|
+
'timestamp': this.parse8601(datetime),
|
|
3076
|
+
'datetime': datetime,
|
|
3077
|
+
'lastUpdateTimestamp': undefined,
|
|
3078
|
+
'maintenanceMargin': undefined,
|
|
3079
|
+
'maintenanceMarginPercentage': undefined,
|
|
3080
|
+
'collateral': collateral,
|
|
3081
|
+
'initialMargin': undefined,
|
|
3082
|
+
'initialMarginPercentage': undefined,
|
|
3083
|
+
'leverage': leverage,
|
|
3084
|
+
'marginRatio': undefined,
|
|
3085
|
+
'stopLossPrice': undefined,
|
|
3086
|
+
'takeProfitPrice': undefined,
|
|
3087
|
+
});
|
|
3088
|
+
}
|
|
3089
|
+
parseOpenInterest(interest, market = undefined) {
|
|
3090
|
+
//
|
|
3091
|
+
// {
|
|
3092
|
+
// "contract_type": "perpetual",
|
|
3093
|
+
// "mark_price": "42307.43",
|
|
3094
|
+
// "index_price": "42303.27",
|
|
3095
|
+
// "funding_rate": "0.0001",
|
|
3096
|
+
// "open_interest": "30.9826",
|
|
3097
|
+
// "next_funding_time": "2022-03-22T16:00:00.000Z",
|
|
3098
|
+
// "indicative_funding_rate": "0.0001",
|
|
3099
|
+
// "premium_index": "0",
|
|
3100
|
+
// "avg_premium_index": "0.000029587712038098",
|
|
3101
|
+
// "interest_rate": "0.0001",
|
|
3102
|
+
// "timestamp": "2022-03-22T08:08:26.687Z"
|
|
3103
|
+
// }
|
|
3104
|
+
//
|
|
3105
|
+
const datetime = this.safeString(interest, 'timestamp');
|
|
3106
|
+
const value = this.safeNumber(interest, 'open_interest');
|
|
3107
|
+
return this.safeOpenInterest({
|
|
3108
|
+
'symbol': market['symbol'],
|
|
3109
|
+
'openInterestAmount': undefined,
|
|
3110
|
+
'openInterestValue': value,
|
|
3111
|
+
'timestamp': this.parse8601(datetime),
|
|
3112
|
+
'datetime': datetime,
|
|
3113
|
+
'info': interest,
|
|
3114
|
+
}, market);
|
|
3115
|
+
}
|
|
3116
|
+
async fetchOpenInterest(symbol, params = {}) {
|
|
3117
|
+
/**
|
|
3118
|
+
* @method
|
|
3119
|
+
* @name hitbtc#fetchOpenInterest
|
|
3120
|
+
* @description Retrieves the open interest of a derivative trading pair
|
|
3121
|
+
* @see https://api.hitbtc.com/#futures-info
|
|
3122
|
+
* @param {string} symbol Unified CCXT market symbol
|
|
3123
|
+
* @param {object} [params] exchange specific parameters
|
|
3124
|
+
* @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=interest-history-structure}
|
|
3125
|
+
*/
|
|
3126
|
+
await this.loadMarkets();
|
|
3127
|
+
const market = this.market(symbol);
|
|
3128
|
+
if (!market['swap']) {
|
|
3129
|
+
throw new errors.BadSymbol(this.id + ' fetchOpenInterest() supports swap contracts only');
|
|
3130
|
+
}
|
|
3131
|
+
const request = {
|
|
3132
|
+
'symbol': market['id'],
|
|
3133
|
+
};
|
|
3134
|
+
const response = await this.publicGetPublicFuturesInfoSymbol(this.extend(request, params));
|
|
3135
|
+
//
|
|
3136
|
+
// {
|
|
3137
|
+
// "contract_type": "perpetual",
|
|
3138
|
+
// "mark_price": "42307.43",
|
|
3139
|
+
// "index_price": "42303.27",
|
|
3140
|
+
// "funding_rate": "0.0001",
|
|
3141
|
+
// "open_interest": "30.9826",
|
|
3142
|
+
// "next_funding_time": "2022-03-22T16:00:00.000Z",
|
|
3143
|
+
// "indicative_funding_rate": "0.0001",
|
|
3144
|
+
// "premium_index": "0",
|
|
3145
|
+
// "avg_premium_index": "0.000029587712038098",
|
|
3146
|
+
// "interest_rate": "0.0001",
|
|
3147
|
+
// "timestamp": "2022-03-22T08:08:26.687Z"
|
|
3148
|
+
// }
|
|
3149
|
+
//
|
|
3150
|
+
return this.parseOpenInterest(response, market);
|
|
3151
|
+
}
|
|
3152
|
+
async fetchFundingRate(symbol, params = {}) {
|
|
3153
|
+
/**
|
|
3154
|
+
* @method
|
|
3155
|
+
* @name hitbtc#fetchFundingRate
|
|
3156
|
+
* @description fetch the current funding rate
|
|
3157
|
+
* @see https://api.hitbtc.com/#futures-info
|
|
3158
|
+
* @param {string} symbol unified market symbol
|
|
3159
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3160
|
+
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
3161
|
+
*/
|
|
3162
|
+
await this.loadMarkets();
|
|
3163
|
+
const market = this.market(symbol);
|
|
3164
|
+
if (!market['swap']) {
|
|
3165
|
+
throw new errors.BadSymbol(this.id + ' fetchFundingRate() supports swap contracts only');
|
|
3166
|
+
}
|
|
3167
|
+
const request = {
|
|
3168
|
+
'symbol': market['id'],
|
|
3169
|
+
};
|
|
3170
|
+
const response = await this.publicGetPublicFuturesInfoSymbol(this.extend(request, params));
|
|
3171
|
+
//
|
|
3172
|
+
// {
|
|
3173
|
+
// "contract_type": "perpetual",
|
|
3174
|
+
// "mark_price": "42307.43",
|
|
3175
|
+
// "index_price": "42303.27",
|
|
3176
|
+
// "funding_rate": "0.0001",
|
|
3177
|
+
// "open_interest": "30.9826",
|
|
3178
|
+
// "next_funding_time": "2022-03-22T16:00:00.000Z",
|
|
3179
|
+
// "indicative_funding_rate": "0.0001",
|
|
3180
|
+
// "premium_index": "0",
|
|
3181
|
+
// "avg_premium_index": "0.000029587712038098",
|
|
3182
|
+
// "interest_rate": "0.0001",
|
|
3183
|
+
// "timestamp": "2022-03-22T08:08:26.687Z"
|
|
3184
|
+
// }
|
|
3185
|
+
//
|
|
3186
|
+
return this.parseFundingRate(response, market);
|
|
3187
|
+
}
|
|
3188
|
+
parseFundingRate(contract, market = undefined) {
|
|
3189
|
+
//
|
|
3190
|
+
// {
|
|
3191
|
+
// "contract_type": "perpetual",
|
|
3192
|
+
// "mark_price": "42307.43",
|
|
3193
|
+
// "index_price": "42303.27",
|
|
3194
|
+
// "funding_rate": "0.0001",
|
|
3195
|
+
// "open_interest": "30.9826",
|
|
3196
|
+
// "next_funding_time": "2022-03-22T16:00:00.000Z",
|
|
3197
|
+
// "indicative_funding_rate": "0.0001",
|
|
3198
|
+
// "premium_index": "0",
|
|
3199
|
+
// "avg_premium_index": "0.000029587712038098",
|
|
3200
|
+
// "interest_rate": "0.0001",
|
|
3201
|
+
// "timestamp": "2022-03-22T08:08:26.687Z"
|
|
3202
|
+
// }
|
|
3203
|
+
//
|
|
3204
|
+
const fundingDateTime = this.safeString(contract, 'next_funding_time');
|
|
3205
|
+
const datetime = this.safeString(contract, 'timestamp');
|
|
3206
|
+
return {
|
|
3207
|
+
'info': contract,
|
|
3208
|
+
'symbol': this.safeSymbol(undefined, market),
|
|
3209
|
+
'markPrice': this.safeNumber(contract, 'mark_price'),
|
|
3210
|
+
'indexPrice': this.safeNumber(contract, 'index_price'),
|
|
3211
|
+
'interestRate': this.safeNumber(contract, 'interest_rate'),
|
|
3212
|
+
'estimatedSettlePrice': undefined,
|
|
3213
|
+
'timestamp': this.parse8601(datetime),
|
|
3214
|
+
'datetime': datetime,
|
|
3215
|
+
'fundingRate': this.safeNumber(contract, 'funding_rate'),
|
|
3216
|
+
'fundingTimestamp': this.parse8601(fundingDateTime),
|
|
3217
|
+
'fundingDatetime': fundingDateTime,
|
|
3218
|
+
'nextFundingRate': this.safeNumber(contract, 'indicative_funding_rate'),
|
|
3219
|
+
'nextFundingTimestamp': undefined,
|
|
3220
|
+
'nextFundingDatetime': undefined,
|
|
3221
|
+
'previousFundingRate': undefined,
|
|
3222
|
+
'previousFundingTimestamp': undefined,
|
|
3223
|
+
'previousFundingDatetime': undefined,
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
async modifyMarginHelper(symbol, amount, type, params = {}) {
|
|
3227
|
+
await this.loadMarkets();
|
|
3228
|
+
const market = this.market(symbol);
|
|
3229
|
+
const leverage = this.safeString(params, 'leverage');
|
|
3230
|
+
if (market['type'] === 'swap') {
|
|
3231
|
+
if (leverage === undefined) {
|
|
3232
|
+
throw new errors.ArgumentsRequired(this.id + ' modifyMarginHelper() requires a leverage parameter for swap markets');
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
if (amount !== 0) {
|
|
3236
|
+
amount = this.amountToPrecision(symbol, amount);
|
|
3237
|
+
}
|
|
3238
|
+
else {
|
|
3239
|
+
amount = '0';
|
|
3240
|
+
}
|
|
3241
|
+
const request = {
|
|
3242
|
+
'symbol': market['id'],
|
|
3243
|
+
'margin_balance': amount, // swap and margin
|
|
3244
|
+
// "leverage": "10", // swap only required
|
|
3245
|
+
// "strict_validate": false, // swap and margin
|
|
3246
|
+
};
|
|
3247
|
+
if (leverage !== undefined) {
|
|
3248
|
+
request['leverage'] = leverage;
|
|
3249
|
+
}
|
|
3250
|
+
let marketType = undefined;
|
|
3251
|
+
let marginMode = undefined;
|
|
3252
|
+
[marketType, params] = this.handleMarketTypeAndParams('modifyMarginHelper', market, params);
|
|
3253
|
+
[marginMode, params] = this.handleMarginModeAndParams('modifyMarginHelper', params);
|
|
3254
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
3255
|
+
let response = undefined;
|
|
3256
|
+
if (marginMode !== undefined) {
|
|
3257
|
+
response = await this.privatePutMarginAccountIsolatedSymbol(this.extend(request, params));
|
|
3258
|
+
}
|
|
3259
|
+
else {
|
|
3260
|
+
if (marketType === 'swap') {
|
|
3261
|
+
response = await this.privatePutFuturesAccountIsolatedSymbol(this.extend(request, params));
|
|
3262
|
+
}
|
|
3263
|
+
else if (marketType === 'margin') {
|
|
3264
|
+
response = await this.privatePutMarginAccountIsolatedSymbol(this.extend(request, params));
|
|
3265
|
+
}
|
|
3266
|
+
else {
|
|
3267
|
+
throw new errors.NotSupported(this.id + ' modifyMarginHelper() not support this market type');
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
//
|
|
3271
|
+
// {
|
|
3272
|
+
// "symbol": "BTCUSDT_PERP",
|
|
3273
|
+
// "type": "isolated",
|
|
3274
|
+
// "leverage": "8.00",
|
|
3275
|
+
// "created_at": "2022-03-30T23:34:27.161Z",
|
|
3276
|
+
// "updated_at": "2022-03-30T23:34:27.161Z",
|
|
3277
|
+
// "currencies": [
|
|
3278
|
+
// {
|
|
3279
|
+
// "code": "USDT",
|
|
3280
|
+
// "margin_balance": "7.000000000000",
|
|
3281
|
+
// "reserved_orders": "0",
|
|
3282
|
+
// "reserved_positions": "0"
|
|
3283
|
+
// }
|
|
3284
|
+
// ],
|
|
3285
|
+
// "positions": null
|
|
3286
|
+
// }
|
|
3287
|
+
//
|
|
3288
|
+
return this.extend(this.parseMarginModification(response, market), {
|
|
3289
|
+
'amount': this.parseNumber(amount),
|
|
3290
|
+
'type': type,
|
|
3291
|
+
});
|
|
3292
|
+
}
|
|
3293
|
+
parseMarginModification(data, market = undefined) {
|
|
3294
|
+
const currencies = this.safeValue(data, 'currencies', []);
|
|
3295
|
+
const currencyInfo = this.safeValue(currencies, 0);
|
|
3296
|
+
return {
|
|
3297
|
+
'info': data,
|
|
3298
|
+
'type': undefined,
|
|
3299
|
+
'amount': undefined,
|
|
3300
|
+
'code': this.safeString(currencyInfo, 'code'),
|
|
3301
|
+
'symbol': market['symbol'],
|
|
3302
|
+
'status': undefined,
|
|
3303
|
+
};
|
|
3304
|
+
}
|
|
3305
|
+
async reduceMargin(symbol, amount, params = {}) {
|
|
3306
|
+
/**
|
|
3307
|
+
* @method
|
|
3308
|
+
* @name hitbtc#reduceMargin
|
|
3309
|
+
* @description remove margin from a position
|
|
3310
|
+
* @see https://api.hitbtc.com/#create-update-margin-account-2
|
|
3311
|
+
* @see https://api.hitbtc.com/#create-update-margin-account
|
|
3312
|
+
* @param {string} symbol unified market symbol
|
|
3313
|
+
* @param {float} amount the amount of margin to remove
|
|
3314
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3315
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to the spot-margin endpoint if this is set
|
|
3316
|
+
* @param {bool} [params.margin] true for reducing spot-margin
|
|
3317
|
+
* @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=reduce-margin-structure}
|
|
3318
|
+
*/
|
|
3319
|
+
if (amount !== 0) {
|
|
3320
|
+
throw new errors.BadRequest(this.id + ' reduceMargin() on hitbtc requires the amount to be 0 and that will remove the entire margin amount');
|
|
3321
|
+
}
|
|
3322
|
+
return await this.modifyMarginHelper(symbol, amount, 'reduce', params);
|
|
3323
|
+
}
|
|
3324
|
+
async addMargin(symbol, amount, params = {}) {
|
|
3325
|
+
/**
|
|
3326
|
+
* @method
|
|
3327
|
+
* @name hitbtc#addMargin
|
|
3328
|
+
* @description add margin
|
|
3329
|
+
* @see https://api.hitbtc.com/#create-update-margin-account-2
|
|
3330
|
+
* @see https://api.hitbtc.com/#create-update-margin-account
|
|
3331
|
+
* @param {string} symbol unified market symbol
|
|
3332
|
+
* @param {float} amount amount of margin to add
|
|
3333
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3334
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to the spot-margin endpoint if this is set
|
|
3335
|
+
* @param {bool} [params.margin] true for adding spot-margin
|
|
3336
|
+
* @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure}
|
|
3337
|
+
*/
|
|
3338
|
+
return await this.modifyMarginHelper(symbol, amount, 'add', params);
|
|
3339
|
+
}
|
|
3340
|
+
async fetchLeverage(symbol, params = {}) {
|
|
3341
|
+
/**
|
|
3342
|
+
* @method
|
|
3343
|
+
* @name hitbtc#fetchLeverage
|
|
3344
|
+
* @description fetch the set leverage for a market
|
|
3345
|
+
* @see https://api.hitbtc.com/#get-futures-margin-account
|
|
3346
|
+
* @see https://api.hitbtc.com/#get-isolated-margin-account
|
|
3347
|
+
* @param {string} symbol unified market symbol
|
|
3348
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3349
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to the spot-margin endpoint if this is set
|
|
3350
|
+
* @param {bool} [params.margin] true for fetching spot-margin leverage
|
|
3351
|
+
* @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
|
|
3352
|
+
*/
|
|
3353
|
+
await this.loadMarkets();
|
|
3354
|
+
const market = this.market(symbol);
|
|
3355
|
+
const request = {
|
|
3356
|
+
'symbol': market['id'],
|
|
3357
|
+
};
|
|
3358
|
+
let marginMode = undefined;
|
|
3359
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchLeverage', params);
|
|
3360
|
+
params = this.omit(params, ['marginMode', 'margin']);
|
|
3361
|
+
let response = undefined;
|
|
3362
|
+
if (marginMode !== undefined) {
|
|
3363
|
+
response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
|
|
3364
|
+
}
|
|
3365
|
+
else {
|
|
3366
|
+
if (market['type'] === 'spot') {
|
|
3367
|
+
response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
|
|
3368
|
+
}
|
|
3369
|
+
else if (market['type'] === 'swap') {
|
|
3370
|
+
response = await this.privateGetFuturesAccountIsolatedSymbol(this.extend(request, params));
|
|
3371
|
+
}
|
|
3372
|
+
else if (market['type'] === 'margin') {
|
|
3373
|
+
response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
|
|
3374
|
+
}
|
|
3375
|
+
else {
|
|
3376
|
+
throw new errors.NotSupported(this.id + ' fetchLeverage() not support this market type');
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
//
|
|
3380
|
+
// {
|
|
3381
|
+
// "symbol": "BTCUSDT",
|
|
3382
|
+
// "type": "isolated",
|
|
3383
|
+
// "leverage": "12.00",
|
|
3384
|
+
// "created_at": "2022-03-29T22:31:29.067Z",
|
|
3385
|
+
// "updated_at": "2022-03-30T00:00:00.125Z",
|
|
3386
|
+
// "currencies": [
|
|
3387
|
+
// {
|
|
3388
|
+
// "code": "USDT",
|
|
3389
|
+
// "margin_balance": "20.824360374174",
|
|
3390
|
+
// "reserved_orders": "0",
|
|
3391
|
+
// "reserved_positions": "0.973330435000"
|
|
3392
|
+
// }
|
|
3393
|
+
// ],
|
|
3394
|
+
// "positions": [
|
|
3395
|
+
// {
|
|
3396
|
+
// "id": 631301,
|
|
3397
|
+
// "symbol": "BTCUSDT",
|
|
3398
|
+
// "quantity": "0.00022",
|
|
3399
|
+
// "price_entry": "47425.57",
|
|
3400
|
+
// "price_margin_call": "",
|
|
3401
|
+
// "price_liquidation": "0",
|
|
3402
|
+
// "pnl": "0",
|
|
3403
|
+
// "created_at": "2022-03-29T22:31:29.067Z",
|
|
3404
|
+
// "updated_at": "2022-03-30T00:00:00.125Z"
|
|
3405
|
+
// }
|
|
3406
|
+
// ]
|
|
3407
|
+
// }
|
|
3408
|
+
//
|
|
3409
|
+
return this.safeNumber(response, 'leverage');
|
|
3410
|
+
}
|
|
3411
|
+
async setLeverage(leverage, symbol = undefined, params = {}) {
|
|
3412
|
+
/**
|
|
3413
|
+
* @method
|
|
3414
|
+
* @name hitbtc#setLeverage
|
|
3415
|
+
* @description set the level of leverage for a market
|
|
3416
|
+
* @see https://api.hitbtc.com/#create-update-margin-account-2
|
|
3417
|
+
* @param {float} leverage the rate of leverage
|
|
3418
|
+
* @param {string} symbol unified market symbol
|
|
3419
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3420
|
+
* @returns {object} response from the exchange
|
|
3421
|
+
*/
|
|
3422
|
+
if (symbol === undefined) {
|
|
3423
|
+
throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
|
|
3424
|
+
}
|
|
3425
|
+
await this.loadMarkets();
|
|
3426
|
+
if (params['margin_balance'] === undefined) {
|
|
3427
|
+
throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a margin_balance parameter that will transfer margin to the specified trading pair');
|
|
3428
|
+
}
|
|
3429
|
+
const market = this.market(symbol);
|
|
3430
|
+
const amount = this.safeNumber(params, 'margin_balance');
|
|
3431
|
+
const maxLeverage = this.safeInteger(market['limits']['leverage'], 'max', 50);
|
|
3432
|
+
if (market['type'] !== 'swap') {
|
|
3433
|
+
throw new errors.BadSymbol(this.id + ' setLeverage() supports swap contracts only');
|
|
3434
|
+
}
|
|
3435
|
+
if ((leverage < 1) || (leverage > maxLeverage)) {
|
|
3436
|
+
throw new errors.BadRequest(this.id + ' setLeverage() leverage should be between 1 and ' + maxLeverage.toString() + ' for ' + symbol);
|
|
3437
|
+
}
|
|
3438
|
+
const request = {
|
|
3439
|
+
'symbol': market['id'],
|
|
3440
|
+
'leverage': leverage.toString(),
|
|
3441
|
+
'margin_balance': this.amountToPrecision(symbol, amount),
|
|
3442
|
+
// 'strict_validate': false,
|
|
3443
|
+
};
|
|
3444
|
+
return await this.privatePutFuturesAccountIsolatedSymbol(this.extend(request, params));
|
|
3445
|
+
}
|
|
3446
|
+
async fetchDepositWithdrawFees(codes = undefined, params = {}) {
|
|
3447
|
+
/**
|
|
3448
|
+
* @method
|
|
3449
|
+
* @name hitbtc#fetchDepositWithdrawFees
|
|
3450
|
+
* @description fetch deposit and withdraw fees
|
|
3451
|
+
* @see https://api.hitbtc.com/#currencies
|
|
3452
|
+
* @param {string[]|undefined} codes list of unified currency codes
|
|
3453
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3454
|
+
* @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
3455
|
+
*/
|
|
3456
|
+
await this.loadMarkets();
|
|
3457
|
+
const response = await this.publicGetPublicCurrency(params);
|
|
3458
|
+
//
|
|
3459
|
+
// {
|
|
3460
|
+
// "WEALTH": {
|
|
3461
|
+
// "full_name": "ConnectWealth",
|
|
3462
|
+
// "payin_enabled": false,
|
|
3463
|
+
// "payout_enabled": false,
|
|
3464
|
+
// "transfer_enabled": true,
|
|
3465
|
+
// "precision_transfer": "0.001",
|
|
3466
|
+
// "networks": [
|
|
3467
|
+
// {
|
|
3468
|
+
// "network": "ETH",
|
|
3469
|
+
// "protocol": "ERC20",
|
|
3470
|
+
// "default": true,
|
|
3471
|
+
// "payin_enabled": false,
|
|
3472
|
+
// "payout_enabled": false,
|
|
3473
|
+
// "precision_payout": "0.001",
|
|
3474
|
+
// "payout_fee": "0.016800000000",
|
|
3475
|
+
// "payout_is_payment_id": false,
|
|
3476
|
+
// "payin_payment_id": false,
|
|
3477
|
+
// "payin_confirmations": "2"
|
|
3478
|
+
// }
|
|
3479
|
+
// ]
|
|
3480
|
+
// }
|
|
3481
|
+
// }
|
|
3482
|
+
//
|
|
3483
|
+
return this.parseDepositWithdrawFees(response, codes);
|
|
3484
|
+
}
|
|
3485
|
+
parseDepositWithdrawFee(fee, currency = undefined) {
|
|
3486
|
+
//
|
|
3487
|
+
// {
|
|
3488
|
+
// "full_name": "ConnectWealth",
|
|
3489
|
+
// "payin_enabled": false,
|
|
3490
|
+
// "payout_enabled": false,
|
|
3491
|
+
// "transfer_enabled": true,
|
|
3492
|
+
// "precision_transfer": "0.001",
|
|
3493
|
+
// "networks": [
|
|
3494
|
+
// {
|
|
3495
|
+
// "network": "ETH",
|
|
3496
|
+
// "protocol": "ERC20",
|
|
3497
|
+
// "default": true,
|
|
3498
|
+
// "payin_enabled": false,
|
|
3499
|
+
// "payout_enabled": false,
|
|
3500
|
+
// "precision_payout": "0.001",
|
|
3501
|
+
// "payout_fee": "0.016800000000",
|
|
3502
|
+
// "payout_is_payment_id": false,
|
|
3503
|
+
// "payin_payment_id": false,
|
|
3504
|
+
// "payin_confirmations": "2"
|
|
3505
|
+
// }
|
|
3506
|
+
// ]
|
|
3507
|
+
// }
|
|
3508
|
+
//
|
|
3509
|
+
const networks = this.safeValue(fee, 'networks', []);
|
|
3510
|
+
const result = this.depositWithdrawFee(fee);
|
|
3511
|
+
for (let j = 0; j < networks.length; j++) {
|
|
3512
|
+
const networkEntry = networks[j];
|
|
3513
|
+
const networkId = this.safeString(networkEntry, 'network');
|
|
3514
|
+
const networkCode = this.networkIdToCode(networkId);
|
|
3515
|
+
const withdrawFee = this.safeNumber(networkEntry, 'payout_fee');
|
|
3516
|
+
const isDefault = this.safeValue(networkEntry, 'default');
|
|
3517
|
+
const withdrawResult = {
|
|
3518
|
+
'fee': withdrawFee,
|
|
3519
|
+
'percentage': (withdrawFee !== undefined) ? false : undefined,
|
|
3520
|
+
};
|
|
3521
|
+
if (isDefault === true) {
|
|
3522
|
+
result['withdraw'] = withdrawResult;
|
|
3523
|
+
}
|
|
3524
|
+
result['networks'][networkCode] = {
|
|
3525
|
+
'withdraw': withdrawResult,
|
|
3526
|
+
'deposit': {
|
|
3527
|
+
'fee': undefined,
|
|
3528
|
+
'percentage': undefined,
|
|
3529
|
+
},
|
|
3530
|
+
};
|
|
3531
|
+
}
|
|
3532
|
+
return result;
|
|
3533
|
+
}
|
|
3534
|
+
async closePosition(symbol, side = undefined, params = {}) {
|
|
3535
|
+
/**
|
|
3536
|
+
* @method
|
|
3537
|
+
* @name hitbtc#closePosition
|
|
3538
|
+
* @description closes open positions for a market
|
|
3539
|
+
* @see https://api.hitbtc.com/#close-all-futures-margin-positions
|
|
3540
|
+
* @param {object} [params] extra parameters specific to the okx api endpoint
|
|
3541
|
+
* @param {string} [params.symbol] *required* unified market symbol
|
|
3542
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated', default is 'cross'
|
|
3543
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
3544
|
+
*/
|
|
3545
|
+
await this.loadMarkets();
|
|
3546
|
+
let marginMode = undefined;
|
|
3547
|
+
[marginMode, params] = this.handleMarginModeAndParams('closePosition', params, 'cross');
|
|
3548
|
+
const market = this.market(symbol);
|
|
3549
|
+
const request = {
|
|
3550
|
+
'symbol': market['id'],
|
|
3551
|
+
'margin_mode': marginMode,
|
|
3552
|
+
};
|
|
3553
|
+
const response = await this.privateDeleteFuturesPositionMarginModeSymbol(this.extend(request, params));
|
|
3554
|
+
//
|
|
3555
|
+
// {
|
|
3556
|
+
// "id":"202471640",
|
|
3557
|
+
// "symbol":"TRXUSDT_PERP",
|
|
3558
|
+
// "margin_mode":"Cross",
|
|
3559
|
+
// "leverage":"1.00",
|
|
3560
|
+
// "quantity":"0",
|
|
3561
|
+
// "price_entry":"0",
|
|
3562
|
+
// "price_margin_call":"0",
|
|
3563
|
+
// "price_liquidation":"0",
|
|
3564
|
+
// "pnl":"0.001234100000",
|
|
3565
|
+
// "created_at":"2023-10-29T14:46:13.235Z",
|
|
3566
|
+
// "updated_at":"2023-12-19T09:34:40.014Z"
|
|
3567
|
+
// }
|
|
3568
|
+
//
|
|
3569
|
+
return this.parseOrder(response, market);
|
|
3570
|
+
}
|
|
3571
|
+
handleMarginModeAndParams(methodName, params = {}, defaultValue = undefined) {
|
|
3572
|
+
/**
|
|
3573
|
+
* @ignore
|
|
3574
|
+
* @method
|
|
3575
|
+
* @description marginMode specified by params["marginMode"], this.options["marginMode"], this.options["defaultMarginMode"], params["margin"] = true or this.options["defaultType"] = 'margin'
|
|
3576
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3577
|
+
* @returns {Array} the marginMode in lowercase
|
|
3578
|
+
*/
|
|
3579
|
+
const defaultType = this.safeString(this.options, 'defaultType');
|
|
3580
|
+
const isMargin = this.safeValue(params, 'margin', false);
|
|
3581
|
+
let marginMode = undefined;
|
|
3582
|
+
[marginMode, params] = super.handleMarginModeAndParams(methodName, params, defaultValue);
|
|
3583
|
+
if (marginMode === undefined) {
|
|
3584
|
+
if ((defaultType === 'margin') || (isMargin === true)) {
|
|
3585
|
+
marginMode = 'isolated';
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
return [marginMode, params];
|
|
3589
|
+
}
|
|
3590
|
+
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
3591
|
+
//
|
|
3592
|
+
// {
|
|
3593
|
+
// "error": {
|
|
3594
|
+
// "code": 20001,
|
|
3595
|
+
// "message": "Insufficient funds",
|
|
3596
|
+
// "description": "Check that the funds are sufficient, given commissions"
|
|
3597
|
+
// }
|
|
3598
|
+
// }
|
|
3599
|
+
//
|
|
3600
|
+
// {
|
|
3601
|
+
// "error": {
|
|
3602
|
+
// "code": "600",
|
|
3603
|
+
// "message": "Action not allowed"
|
|
3604
|
+
// }
|
|
3605
|
+
// }
|
|
3606
|
+
//
|
|
3607
|
+
const error = this.safeValue(response, 'error');
|
|
3608
|
+
const errorCode = this.safeString(error, 'code');
|
|
3609
|
+
if (errorCode !== undefined) {
|
|
3610
|
+
const feedback = this.id + ' ' + body;
|
|
3611
|
+
const message = this.safeString2(error, 'message', 'description');
|
|
3612
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
|
|
3613
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
3614
|
+
throw new errors.ExchangeError(feedback);
|
|
3615
|
+
}
|
|
3616
|
+
return undefined;
|
|
3617
|
+
}
|
|
3618
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
3619
|
+
const query = this.omit(params, this.extractParams(path));
|
|
3620
|
+
const implodedPath = this.implodeParams(path, params);
|
|
3621
|
+
let url = this.urls['api'][api] + '/' + implodedPath;
|
|
3622
|
+
let getRequest = undefined;
|
|
3623
|
+
const keys = Object.keys(query);
|
|
3624
|
+
const queryLength = keys.length;
|
|
3625
|
+
headers = {
|
|
3626
|
+
'Content-Type': 'application/json',
|
|
3627
|
+
};
|
|
3628
|
+
if (method === 'GET') {
|
|
3629
|
+
if (queryLength) {
|
|
3630
|
+
getRequest = '?' + this.urlencode(query);
|
|
3631
|
+
url = url + getRequest;
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
else {
|
|
3635
|
+
body = this.json(params);
|
|
3636
|
+
}
|
|
3637
|
+
if (api === 'private') {
|
|
3638
|
+
this.checkRequiredCredentials();
|
|
3639
|
+
const timestamp = this.nonce().toString();
|
|
3640
|
+
const payload = [method, '/api/3/' + implodedPath];
|
|
3641
|
+
if (method === 'GET') {
|
|
3642
|
+
if (getRequest !== undefined) {
|
|
3643
|
+
payload.push(getRequest);
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
else {
|
|
3647
|
+
payload.push(body);
|
|
3648
|
+
}
|
|
3649
|
+
payload.push(timestamp);
|
|
3650
|
+
const payloadString = payload.join('');
|
|
3651
|
+
const signature = this.hmac(this.encode(payloadString), this.encode(this.secret), sha256.sha256, 'hex');
|
|
3652
|
+
const secondPayload = this.apiKey + ':' + signature + ':' + timestamp;
|
|
3653
|
+
const encoded = this.stringToBase64(secondPayload);
|
|
3654
|
+
headers['Authorization'] = 'HS256 ' + encoded;
|
|
3655
|
+
}
|
|
3656
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3660
|
+
module.exports = hitbtc;
|