ccxt 4.2.11 → 4.2.12
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 +640 -261
- 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 +2142 -0
- package/dist/cjs/js/src/binance.js +9729 -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 +3737 -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 +8284 -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 +3274 -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 +7054 -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 +9024 -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 +759 -0
- package/dist/cjs/js/src/indodax.js +1069 -0
- package/dist/cjs/js/src/kraken.js +2861 -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 +2825 -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 +7329 -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 +4715 -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 +1558 -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 +1865 -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 +2715 -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/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/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 +1 -2
- package/js/src/bigone.js +340 -145
- package/js/src/binance.js +15 -8
- package/js/src/bingx.js +9 -2
- package/js/src/bitfinex.d.ts +2 -2
- package/js/src/bitfinex.js +2 -3
- package/js/src/bitget.js +21 -8
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +3 -3
- package/js/src/bitmex.js +1 -0
- package/js/src/bybit.js +2 -0
- package/js/src/coinlist.js +2 -3
- 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 +22 -3
- package/js/src/hitbtc.d.ts +4 -4
- package/js/src/hitbtc.js +2 -3
- package/js/src/htx.js +4 -7
- package/js/src/huobijp.js +2 -3
- package/js/src/kraken.js +1 -0
- package/js/src/mexc.js +2 -1
- package/js/src/okx.js +13 -3
- 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/poloniex.d.ts +2 -2
- package/js/src/upbit.d.ts +3 -101
- package/js/src/upbit.js +12 -12
- package/js/src/woo.js +2 -0
- package/package.json +1 -1
- package/skip-tests.json +5 -0
|
@@ -0,0 +1,3253 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var bitrue$1 = require('./abstract/bitrue.js');
|
|
4
|
+
var errors = require('./base/errors.js');
|
|
5
|
+
var Precise = require('./base/Precise.js');
|
|
6
|
+
var number = require('./base/functions/number.js');
|
|
7
|
+
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* @class bitrue
|
|
13
|
+
* @augments Exchange
|
|
14
|
+
*/
|
|
15
|
+
class bitrue extends bitrue$1 {
|
|
16
|
+
describe() {
|
|
17
|
+
return this.deepExtend(super.describe(), {
|
|
18
|
+
'id': 'bitrue',
|
|
19
|
+
'name': 'Bitrue',
|
|
20
|
+
'countries': ['SG'],
|
|
21
|
+
'rateLimit': 1000,
|
|
22
|
+
'certified': false,
|
|
23
|
+
'version': 'v1',
|
|
24
|
+
'pro': true,
|
|
25
|
+
// new metainfo interface
|
|
26
|
+
'has': {
|
|
27
|
+
'CORS': undefined,
|
|
28
|
+
'spot': true,
|
|
29
|
+
'margin': false,
|
|
30
|
+
'swap': true,
|
|
31
|
+
'future': false,
|
|
32
|
+
'option': false,
|
|
33
|
+
'cancelAllOrders': true,
|
|
34
|
+
'cancelOrder': true,
|
|
35
|
+
'createMarketBuyOrderWithCost': true,
|
|
36
|
+
'createMarketOrderWithCost': false,
|
|
37
|
+
'createMarketSellOrderWithCost': false,
|
|
38
|
+
'createOrder': true,
|
|
39
|
+
'createStopLimitOrder': true,
|
|
40
|
+
'createStopMarketOrder': true,
|
|
41
|
+
'createStopOrder': true,
|
|
42
|
+
'fetchBalance': true,
|
|
43
|
+
'fetchBidsAsks': true,
|
|
44
|
+
'fetchBorrowRateHistories': false,
|
|
45
|
+
'fetchBorrowRateHistory': false,
|
|
46
|
+
'fetchClosedOrders': true,
|
|
47
|
+
'fetchCrossBorrowRate': false,
|
|
48
|
+
'fetchCrossBorrowRates': false,
|
|
49
|
+
'fetchCurrencies': true,
|
|
50
|
+
'fetchDepositAddress': false,
|
|
51
|
+
'fetchDeposits': true,
|
|
52
|
+
'fetchDepositsWithdrawals': false,
|
|
53
|
+
'fetchDepositWithdrawFee': 'emulated',
|
|
54
|
+
'fetchDepositWithdrawFees': true,
|
|
55
|
+
'fetchIsolatedBorrowRate': false,
|
|
56
|
+
'fetchIsolatedBorrowRates': false,
|
|
57
|
+
'fetchMarginMode': false,
|
|
58
|
+
'fetchMarkets': true,
|
|
59
|
+
'fetchMyTrades': true,
|
|
60
|
+
'fetchOHLCV': true,
|
|
61
|
+
'fetchOpenOrders': true,
|
|
62
|
+
'fetchOrder': true,
|
|
63
|
+
'fetchOrderBook': true,
|
|
64
|
+
'fetchOrders': false,
|
|
65
|
+
'fetchPositionMode': false,
|
|
66
|
+
'fetchStatus': true,
|
|
67
|
+
'fetchTicker': true,
|
|
68
|
+
'fetchTickers': true,
|
|
69
|
+
'fetchTime': true,
|
|
70
|
+
'fetchTrades': true,
|
|
71
|
+
'fetchTradingFee': false,
|
|
72
|
+
'fetchTradingFees': false,
|
|
73
|
+
'fetchTransactionFees': false,
|
|
74
|
+
'fetchTransactions': false,
|
|
75
|
+
'fetchTransfers': true,
|
|
76
|
+
'fetchWithdrawals': true,
|
|
77
|
+
'setLeverage': true,
|
|
78
|
+
'setMargin': true,
|
|
79
|
+
'transfer': true,
|
|
80
|
+
'withdraw': true,
|
|
81
|
+
},
|
|
82
|
+
'timeframes': {
|
|
83
|
+
'1m': '1m',
|
|
84
|
+
'5m': '5m',
|
|
85
|
+
'15m': '15m',
|
|
86
|
+
'30m': '30m',
|
|
87
|
+
'1h': '1H',
|
|
88
|
+
'2h': '2H',
|
|
89
|
+
'4h': '4H',
|
|
90
|
+
'1d': '1D',
|
|
91
|
+
'1w': '1W',
|
|
92
|
+
},
|
|
93
|
+
'urls': {
|
|
94
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/139516488-243a830d-05dd-446b-91c6-c1f18fe30c63.jpg',
|
|
95
|
+
'api': {
|
|
96
|
+
'spot': 'https://www.bitrue.com/api',
|
|
97
|
+
'fapi': 'https://fapi.bitrue.com/fapi',
|
|
98
|
+
'dapi': 'https://fapi.bitrue.com/dapi',
|
|
99
|
+
'kline': 'https://www.bitrue.com/kline-api',
|
|
100
|
+
},
|
|
101
|
+
'www': 'https://www.bitrue.com',
|
|
102
|
+
'referral': 'https://www.bitrue.com/affiliate/landing?cn=600000&inviteCode=EZWETQE',
|
|
103
|
+
'doc': [
|
|
104
|
+
'https://github.com/Bitrue-exchange/bitrue-official-api-docs',
|
|
105
|
+
'https://www.bitrue.com/api-docs',
|
|
106
|
+
],
|
|
107
|
+
'fees': 'https://bitrue.zendesk.com/hc/en-001/articles/4405479952537',
|
|
108
|
+
},
|
|
109
|
+
'api': {
|
|
110
|
+
'spot': {
|
|
111
|
+
'kline': {
|
|
112
|
+
'public': {
|
|
113
|
+
'get': {
|
|
114
|
+
'public.json': 1,
|
|
115
|
+
'public{currency}.json': 1,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
'v1': {
|
|
120
|
+
'public': {
|
|
121
|
+
'get': {
|
|
122
|
+
'ping': 1,
|
|
123
|
+
'time': 1,
|
|
124
|
+
'exchangeInfo': 1,
|
|
125
|
+
'depth': { 'cost': 1, 'byLimit': [[100, 1], [500, 5], [1000, 10]] },
|
|
126
|
+
'trades': 1,
|
|
127
|
+
'historicalTrades': 5,
|
|
128
|
+
'aggTrades': 1,
|
|
129
|
+
'ticker/24hr': { 'cost': 1, 'noSymbol': 40 },
|
|
130
|
+
'ticker/price': { 'cost': 1, 'noSymbol': 2 },
|
|
131
|
+
'ticker/bookTicker': { 'cost': 1, 'noSymbol': 2 },
|
|
132
|
+
'market/kline': 1,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
'private': {
|
|
136
|
+
'get': {
|
|
137
|
+
'order': 1,
|
|
138
|
+
'openOrders': 1,
|
|
139
|
+
'allOrders': 5,
|
|
140
|
+
'account': 5,
|
|
141
|
+
'myTrades': { 'cost': 5, 'noSymbol': 40 },
|
|
142
|
+
'etf/net-value/{symbol}': 1,
|
|
143
|
+
'withdraw/history': 1,
|
|
144
|
+
'deposit/history': 1,
|
|
145
|
+
},
|
|
146
|
+
'post': {
|
|
147
|
+
'order': 4,
|
|
148
|
+
'withdraw/commit': 1,
|
|
149
|
+
},
|
|
150
|
+
'delete': {
|
|
151
|
+
'order': 1,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
'v2': {
|
|
156
|
+
'private': {
|
|
157
|
+
'get': {
|
|
158
|
+
'myTrades': 5,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
'fapi': {
|
|
164
|
+
'v1': {
|
|
165
|
+
'public': {
|
|
166
|
+
'get': {
|
|
167
|
+
'ping': 1,
|
|
168
|
+
'time': 1,
|
|
169
|
+
'contracts': 1,
|
|
170
|
+
'depth': 1,
|
|
171
|
+
'ticker': 1,
|
|
172
|
+
'klines': 1,
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
'v2': {
|
|
177
|
+
'private': {
|
|
178
|
+
'get': {
|
|
179
|
+
'myTrades': 1,
|
|
180
|
+
'openOrders': 1,
|
|
181
|
+
'order': 1,
|
|
182
|
+
'account': 1,
|
|
183
|
+
'leverageBracket': 1,
|
|
184
|
+
'commissionRate': 1,
|
|
185
|
+
'futures_transfer_history': 1,
|
|
186
|
+
'forceOrdersHistory': 1,
|
|
187
|
+
},
|
|
188
|
+
'post': {
|
|
189
|
+
'positionMargin': 1,
|
|
190
|
+
'level_edit': 1,
|
|
191
|
+
'cancel': 1,
|
|
192
|
+
'order': 1,
|
|
193
|
+
'allOpenOrders': 1,
|
|
194
|
+
'futures_transfer': 1,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
'dapi': {
|
|
200
|
+
'v1': {
|
|
201
|
+
'public': {
|
|
202
|
+
'get': {
|
|
203
|
+
'ping': 1,
|
|
204
|
+
'time': 1,
|
|
205
|
+
'contracts': 1,
|
|
206
|
+
'depth': 1,
|
|
207
|
+
'ticker': 1,
|
|
208
|
+
'klines': 1,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
'v2': {
|
|
213
|
+
'private': {
|
|
214
|
+
'get': {
|
|
215
|
+
'myTrades': 1,
|
|
216
|
+
'openOrders': 1,
|
|
217
|
+
'order': 1,
|
|
218
|
+
'account': 1,
|
|
219
|
+
'leverageBracket': 1,
|
|
220
|
+
'commissionRate': 1,
|
|
221
|
+
'futures_transfer_history': 1,
|
|
222
|
+
'forceOrdersHistory': 1,
|
|
223
|
+
},
|
|
224
|
+
'post': {
|
|
225
|
+
'positionMargin': 1,
|
|
226
|
+
'level_edit': 1,
|
|
227
|
+
'cancel': 1,
|
|
228
|
+
'order': 1,
|
|
229
|
+
'allOpenOrders': 1,
|
|
230
|
+
'futures_transfer': 1,
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
'fees': {
|
|
237
|
+
'trading': {
|
|
238
|
+
'feeSide': 'get',
|
|
239
|
+
'tierBased': false,
|
|
240
|
+
'percentage': true,
|
|
241
|
+
'taker': this.parseNumber('0.00098'),
|
|
242
|
+
'maker': this.parseNumber('0.00098'),
|
|
243
|
+
},
|
|
244
|
+
'future': {
|
|
245
|
+
'trading': {
|
|
246
|
+
'feeSide': 'quote',
|
|
247
|
+
'tierBased': true,
|
|
248
|
+
'percentage': true,
|
|
249
|
+
'taker': this.parseNumber('0.000400'),
|
|
250
|
+
'maker': this.parseNumber('0.000200'),
|
|
251
|
+
'tiers': {
|
|
252
|
+
'taker': [
|
|
253
|
+
[this.parseNumber('0'), this.parseNumber('0.000400')],
|
|
254
|
+
[this.parseNumber('250'), this.parseNumber('0.000400')],
|
|
255
|
+
[this.parseNumber('2500'), this.parseNumber('0.000350')],
|
|
256
|
+
[this.parseNumber('7500'), this.parseNumber('0.000320')],
|
|
257
|
+
[this.parseNumber('22500'), this.parseNumber('0.000300')],
|
|
258
|
+
[this.parseNumber('50000'), this.parseNumber('0.000270')],
|
|
259
|
+
[this.parseNumber('100000'), this.parseNumber('0.000250')],
|
|
260
|
+
[this.parseNumber('200000'), this.parseNumber('0.000220')],
|
|
261
|
+
[this.parseNumber('400000'), this.parseNumber('0.000200')],
|
|
262
|
+
[this.parseNumber('750000'), this.parseNumber('0.000170')],
|
|
263
|
+
],
|
|
264
|
+
'maker': [
|
|
265
|
+
[this.parseNumber('0'), this.parseNumber('0.000200')],
|
|
266
|
+
[this.parseNumber('250'), this.parseNumber('0.000160')],
|
|
267
|
+
[this.parseNumber('2500'), this.parseNumber('0.000140')],
|
|
268
|
+
[this.parseNumber('7500'), this.parseNumber('0.000120')],
|
|
269
|
+
[this.parseNumber('22500'), this.parseNumber('0.000100')],
|
|
270
|
+
[this.parseNumber('50000'), this.parseNumber('0.000080')],
|
|
271
|
+
[this.parseNumber('100000'), this.parseNumber('0.000060')],
|
|
272
|
+
[this.parseNumber('200000'), this.parseNumber('0.000040')],
|
|
273
|
+
[this.parseNumber('400000'), this.parseNumber('0.000020')],
|
|
274
|
+
[this.parseNumber('750000'), this.parseNumber('0')],
|
|
275
|
+
],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
'delivery': {
|
|
280
|
+
'trading': {
|
|
281
|
+
'feeSide': 'base',
|
|
282
|
+
'tierBased': true,
|
|
283
|
+
'percentage': true,
|
|
284
|
+
'taker': this.parseNumber('0.000500'),
|
|
285
|
+
'maker': this.parseNumber('0.000100'),
|
|
286
|
+
'tiers': {
|
|
287
|
+
'taker': [
|
|
288
|
+
[this.parseNumber('0'), this.parseNumber('0.000500')],
|
|
289
|
+
[this.parseNumber('250'), this.parseNumber('0.000450')],
|
|
290
|
+
[this.parseNumber('2500'), this.parseNumber('0.000400')],
|
|
291
|
+
[this.parseNumber('7500'), this.parseNumber('0.000300')],
|
|
292
|
+
[this.parseNumber('22500'), this.parseNumber('0.000250')],
|
|
293
|
+
[this.parseNumber('50000'), this.parseNumber('0.000240')],
|
|
294
|
+
[this.parseNumber('100000'), this.parseNumber('0.000240')],
|
|
295
|
+
[this.parseNumber('200000'), this.parseNumber('0.000240')],
|
|
296
|
+
[this.parseNumber('400000'), this.parseNumber('0.000240')],
|
|
297
|
+
[this.parseNumber('750000'), this.parseNumber('0.000240')],
|
|
298
|
+
],
|
|
299
|
+
'maker': [
|
|
300
|
+
[this.parseNumber('0'), this.parseNumber('0.000100')],
|
|
301
|
+
[this.parseNumber('250'), this.parseNumber('0.000080')],
|
|
302
|
+
[this.parseNumber('2500'), this.parseNumber('0.000050')],
|
|
303
|
+
[this.parseNumber('7500'), this.parseNumber('0.0000030')],
|
|
304
|
+
[this.parseNumber('22500'), this.parseNumber('0')],
|
|
305
|
+
[this.parseNumber('50000'), this.parseNumber('-0.000050')],
|
|
306
|
+
[this.parseNumber('100000'), this.parseNumber('-0.000060')],
|
|
307
|
+
[this.parseNumber('200000'), this.parseNumber('-0.000070')],
|
|
308
|
+
[this.parseNumber('400000'), this.parseNumber('-0.000080')],
|
|
309
|
+
[this.parseNumber('750000'), this.parseNumber('-0.000090')],
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
// exchange-specific options
|
|
316
|
+
'options': {
|
|
317
|
+
'createMarketBuyOrderRequiresPrice': true,
|
|
318
|
+
'fetchMarkets': [
|
|
319
|
+
'spot',
|
|
320
|
+
'linear',
|
|
321
|
+
'inverse',
|
|
322
|
+
],
|
|
323
|
+
// 'fetchTradesMethod': 'publicGetAggTrades', // publicGetTrades, publicGetHistoricalTrades
|
|
324
|
+
'fetchMyTradesMethod': 'v2PrivateGetMyTrades',
|
|
325
|
+
'hasAlreadyAuthenticatedSuccessfully': false,
|
|
326
|
+
'recvWindow': 5 * 1000,
|
|
327
|
+
'timeDifference': 0,
|
|
328
|
+
'adjustForTimeDifference': false,
|
|
329
|
+
'parseOrderToPrecision': false,
|
|
330
|
+
'newOrderRespType': {
|
|
331
|
+
'market': 'FULL',
|
|
332
|
+
'limit': 'FULL', // we change it from 'ACK' by default to 'FULL' (returns immediately if limit is not hit)
|
|
333
|
+
},
|
|
334
|
+
'networks': {
|
|
335
|
+
'ERC20': 'ETH',
|
|
336
|
+
'TRC20': 'TRX',
|
|
337
|
+
},
|
|
338
|
+
'defaultType': 'spot',
|
|
339
|
+
'timeframes': {
|
|
340
|
+
'spot': {
|
|
341
|
+
'1m': '1m',
|
|
342
|
+
'5m': '5m',
|
|
343
|
+
'15m': '15m',
|
|
344
|
+
'30m': '30m',
|
|
345
|
+
'1h': '1H',
|
|
346
|
+
'2h': '2H',
|
|
347
|
+
'4h': '4H',
|
|
348
|
+
'12h': '12H',
|
|
349
|
+
'1d': '1D',
|
|
350
|
+
'1w': '1W',
|
|
351
|
+
},
|
|
352
|
+
'future': {
|
|
353
|
+
'1m': '1min',
|
|
354
|
+
'5m': '5min',
|
|
355
|
+
'15m': '15min',
|
|
356
|
+
'30m': '30min',
|
|
357
|
+
'1h': '1h',
|
|
358
|
+
'1d': '1day',
|
|
359
|
+
'1w': '1week',
|
|
360
|
+
'1M': '1month',
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
'accountsByType': {
|
|
364
|
+
'spot': 'wallet',
|
|
365
|
+
'future': 'contract',
|
|
366
|
+
'swap': 'contract',
|
|
367
|
+
'funding': 'wallet',
|
|
368
|
+
'fund': 'wallet',
|
|
369
|
+
'contract': 'contract',
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
'commonCurrencies': {
|
|
373
|
+
'MIM': 'MIM Swarm',
|
|
374
|
+
},
|
|
375
|
+
'precisionMode': number.TICK_SIZE,
|
|
376
|
+
// https://binance-docs.github.io/apidocs/spot/en/#error-codes-2
|
|
377
|
+
'exceptions': {
|
|
378
|
+
'exact': {
|
|
379
|
+
'System is under maintenance.': errors.OnMaintenance,
|
|
380
|
+
'System abnormality': errors.ExchangeError,
|
|
381
|
+
'You are not authorized to execute this request.': errors.PermissionDenied,
|
|
382
|
+
'API key does not exist': errors.AuthenticationError,
|
|
383
|
+
'Order would trigger immediately.': errors.OrderImmediatelyFillable,
|
|
384
|
+
'Stop price would trigger immediately.': errors.OrderImmediatelyFillable,
|
|
385
|
+
'Order would immediately match and take.': errors.OrderImmediatelyFillable,
|
|
386
|
+
'Account has insufficient balance for requested action.': errors.InsufficientFunds,
|
|
387
|
+
'Rest API trading is not enabled.': errors.ExchangeNotAvailable,
|
|
388
|
+
"You don't have permission.": errors.PermissionDenied,
|
|
389
|
+
'Market is closed.': errors.ExchangeNotAvailable,
|
|
390
|
+
'Too many requests. Please try again later.': errors.DDoSProtection,
|
|
391
|
+
'-1000': errors.ExchangeNotAvailable,
|
|
392
|
+
'-1001': errors.ExchangeNotAvailable,
|
|
393
|
+
'-1002': errors.AuthenticationError,
|
|
394
|
+
'-1003': errors.RateLimitExceeded,
|
|
395
|
+
'-1013': errors.InvalidOrder,
|
|
396
|
+
'-1015': errors.RateLimitExceeded,
|
|
397
|
+
'-1016': errors.ExchangeNotAvailable,
|
|
398
|
+
'-1020': errors.BadRequest,
|
|
399
|
+
'-1021': errors.InvalidNonce,
|
|
400
|
+
'-1022': errors.AuthenticationError,
|
|
401
|
+
'-1100': errors.BadRequest,
|
|
402
|
+
'-1101': errors.BadRequest,
|
|
403
|
+
'-1102': errors.BadRequest,
|
|
404
|
+
'-1103': errors.BadRequest,
|
|
405
|
+
'-1104': errors.BadRequest,
|
|
406
|
+
'-1105': errors.BadRequest,
|
|
407
|
+
'-1106': errors.BadRequest,
|
|
408
|
+
'-1111': errors.BadRequest,
|
|
409
|
+
'-1112': errors.InvalidOrder,
|
|
410
|
+
'-1114': errors.BadRequest,
|
|
411
|
+
'-1115': errors.BadRequest,
|
|
412
|
+
'-1116': errors.BadRequest,
|
|
413
|
+
'-1117': errors.BadRequest,
|
|
414
|
+
'-1166': errors.InvalidOrder,
|
|
415
|
+
'-1118': errors.BadRequest,
|
|
416
|
+
'-1119': errors.BadRequest,
|
|
417
|
+
'-1120': errors.BadRequest,
|
|
418
|
+
'-1121': errors.BadSymbol,
|
|
419
|
+
'-1125': errors.AuthenticationError,
|
|
420
|
+
'-1127': errors.BadRequest,
|
|
421
|
+
'-1128': errors.BadRequest,
|
|
422
|
+
'-1130': errors.BadRequest,
|
|
423
|
+
'-1131': errors.BadRequest,
|
|
424
|
+
'-1160': errors.InvalidOrder,
|
|
425
|
+
'-1156': errors.InvalidOrder,
|
|
426
|
+
'-2008': errors.AuthenticationError,
|
|
427
|
+
'-2010': errors.ExchangeError,
|
|
428
|
+
'-2011': errors.OrderNotFound,
|
|
429
|
+
'-2013': errors.OrderNotFound,
|
|
430
|
+
'-2014': errors.AuthenticationError,
|
|
431
|
+
'-2015': errors.AuthenticationError,
|
|
432
|
+
'-2017': errors.InsufficientFunds,
|
|
433
|
+
'-2019': errors.InsufficientFunds,
|
|
434
|
+
'-3005': errors.InsufficientFunds,
|
|
435
|
+
'-3006': errors.InsufficientFunds,
|
|
436
|
+
'-3008': errors.InsufficientFunds,
|
|
437
|
+
'-3010': errors.ExchangeError,
|
|
438
|
+
'-3015': errors.ExchangeError,
|
|
439
|
+
'-3022': errors.AccountSuspended,
|
|
440
|
+
'-4028': errors.BadRequest,
|
|
441
|
+
'-3020': errors.InsufficientFunds,
|
|
442
|
+
'-3041': errors.InsufficientFunds,
|
|
443
|
+
'-5013': errors.InsufficientFunds,
|
|
444
|
+
'-11008': errors.InsufficientFunds,
|
|
445
|
+
'-4051': errors.InsufficientFunds, // {"code":-4051,"msg":"Isolated balance insufficient."}
|
|
446
|
+
},
|
|
447
|
+
'broad': {
|
|
448
|
+
'has no operation privilege': errors.PermissionDenied,
|
|
449
|
+
'MAX_POSITION': errors.InvalidOrder, // {"code":-2010,"msg":"Filter failure: MAX_POSITION"}
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
currencyToPrecision(code, fee, networkCode = undefined) {
|
|
455
|
+
// info is available in currencies only if the user has configured his api keys
|
|
456
|
+
if (this.safeValue(this.currencies[code], 'precision') !== undefined) {
|
|
457
|
+
return this.decimalToPrecision(fee, number.TRUNCATE, this.currencies[code]['precision'], this.precisionMode, this.paddingMode);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
return this.numberToString(fee);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
nonce() {
|
|
464
|
+
return this.milliseconds() - this.options['timeDifference'];
|
|
465
|
+
}
|
|
466
|
+
async fetchStatus(params = {}) {
|
|
467
|
+
/**
|
|
468
|
+
* @method
|
|
469
|
+
* @name bitrue#fetchStatus
|
|
470
|
+
* @description the latest known information on the availability of the exchange API
|
|
471
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#test-connectivity
|
|
472
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
473
|
+
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
|
|
474
|
+
*/
|
|
475
|
+
const response = await this.spotV1PublicGetPing(params);
|
|
476
|
+
//
|
|
477
|
+
// empty means working status.
|
|
478
|
+
//
|
|
479
|
+
// {}
|
|
480
|
+
//
|
|
481
|
+
const keys = Object.keys(response);
|
|
482
|
+
const keysLength = keys.length;
|
|
483
|
+
const formattedStatus = keysLength ? 'maintenance' : 'ok';
|
|
484
|
+
return {
|
|
485
|
+
'status': formattedStatus,
|
|
486
|
+
'updated': undefined,
|
|
487
|
+
'eta': undefined,
|
|
488
|
+
'url': undefined,
|
|
489
|
+
'info': response,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
async fetchTime(params = {}) {
|
|
493
|
+
/**
|
|
494
|
+
* @method
|
|
495
|
+
* @name bitrue#fetchTime
|
|
496
|
+
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
497
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#check-server-time
|
|
498
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
499
|
+
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
500
|
+
*/
|
|
501
|
+
const response = await this.spotV1PublicGetTime(params);
|
|
502
|
+
//
|
|
503
|
+
// {
|
|
504
|
+
// "serverTime":1635467280514
|
|
505
|
+
// }
|
|
506
|
+
//
|
|
507
|
+
return this.safeInteger(response, 'serverTime');
|
|
508
|
+
}
|
|
509
|
+
safeNetwork(networkId) {
|
|
510
|
+
const uppercaseNetworkId = networkId.toUpperCase();
|
|
511
|
+
const networksById = {
|
|
512
|
+
'Aeternity': 'Aeternity',
|
|
513
|
+
'AION': 'AION',
|
|
514
|
+
'Algorand': 'Algorand',
|
|
515
|
+
'ASK': 'ASK',
|
|
516
|
+
'ATOM': 'ATOM',
|
|
517
|
+
'AVAX C-Chain': 'AVAX C-Chain',
|
|
518
|
+
'bch': 'bch',
|
|
519
|
+
'BCH': 'BCH',
|
|
520
|
+
'BEP2': 'BEP2',
|
|
521
|
+
'BEP20': 'BEP20',
|
|
522
|
+
'Bitcoin': 'Bitcoin',
|
|
523
|
+
'BRP20': 'BRP20',
|
|
524
|
+
'Cardano': 'ADA',
|
|
525
|
+
'CasinoCoin': 'CasinoCoin',
|
|
526
|
+
'CasinoCoin XRPL': 'CasinoCoin XRPL',
|
|
527
|
+
'Contentos': 'Contentos',
|
|
528
|
+
'Dash': 'Dash',
|
|
529
|
+
'Decoin': 'Decoin',
|
|
530
|
+
'DeFiChain': 'DeFiChain',
|
|
531
|
+
'DGB': 'DGB',
|
|
532
|
+
'Divi': 'Divi',
|
|
533
|
+
'dogecoin': 'DOGE',
|
|
534
|
+
'EOS': 'EOS',
|
|
535
|
+
'ERC20': 'ERC20',
|
|
536
|
+
'ETC': 'ETC',
|
|
537
|
+
'Filecoin': 'Filecoin',
|
|
538
|
+
'FREETON': 'FREETON',
|
|
539
|
+
'HBAR': 'HBAR',
|
|
540
|
+
'Hedera Hashgraph': 'Hedera Hashgraph',
|
|
541
|
+
'HRC20': 'HRC20',
|
|
542
|
+
'ICON': 'ICON',
|
|
543
|
+
'ICP': 'ICP',
|
|
544
|
+
'Ignis': 'Ignis',
|
|
545
|
+
'Internet Computer': 'Internet Computer',
|
|
546
|
+
'IOTA': 'IOTA',
|
|
547
|
+
'KAVA': 'KAVA',
|
|
548
|
+
'KSM': 'KSM',
|
|
549
|
+
'LiteCoin': 'LiteCoin',
|
|
550
|
+
'Luna': 'Luna',
|
|
551
|
+
'MATIC': 'MATIC',
|
|
552
|
+
'Mobile Coin': 'Mobile Coin',
|
|
553
|
+
'MonaCoin': 'MonaCoin',
|
|
554
|
+
'Monero': 'Monero',
|
|
555
|
+
'NEM': 'NEM',
|
|
556
|
+
'NEP5': 'NEP5',
|
|
557
|
+
'OMNI': 'OMNI',
|
|
558
|
+
'PAC': 'PAC',
|
|
559
|
+
'Polkadot': 'Polkadot',
|
|
560
|
+
'Ravencoin': 'Ravencoin',
|
|
561
|
+
'Safex': 'Safex',
|
|
562
|
+
'SOLANA': 'SOL',
|
|
563
|
+
'Songbird': 'Songbird',
|
|
564
|
+
'Stellar Lumens': 'Stellar Lumens',
|
|
565
|
+
'Symbol': 'Symbol',
|
|
566
|
+
'Tezos': 'XTZ',
|
|
567
|
+
'theta': 'theta',
|
|
568
|
+
'THETA': 'THETA',
|
|
569
|
+
'TRC20': 'TRC20',
|
|
570
|
+
'VeChain': 'VeChain',
|
|
571
|
+
'VECHAIN': 'VECHAIN',
|
|
572
|
+
'Wanchain': 'Wanchain',
|
|
573
|
+
'XinFin Network': 'XinFin Network',
|
|
574
|
+
'XRP': 'XRP',
|
|
575
|
+
'XRPL': 'XRPL',
|
|
576
|
+
'ZIL': 'ZIL',
|
|
577
|
+
};
|
|
578
|
+
return this.safeString2(networksById, networkId, uppercaseNetworkId, networkId);
|
|
579
|
+
}
|
|
580
|
+
async fetchCurrencies(params = {}) {
|
|
581
|
+
/**
|
|
582
|
+
* @method
|
|
583
|
+
* @name bitrue#fetchCurrencies
|
|
584
|
+
* @description fetches all available currencies on an exchange
|
|
585
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
586
|
+
* @returns {object} an associative dictionary of currencies
|
|
587
|
+
*/
|
|
588
|
+
const response = await this.spotV1PublicGetExchangeInfo(params);
|
|
589
|
+
//
|
|
590
|
+
// {
|
|
591
|
+
// "timezone":"CTT",
|
|
592
|
+
// "serverTime":1635464889117,
|
|
593
|
+
// "rateLimits":[
|
|
594
|
+
// {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000},
|
|
595
|
+
// {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150},
|
|
596
|
+
// {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000},
|
|
597
|
+
// ],
|
|
598
|
+
// "exchangeFilters":[],
|
|
599
|
+
// "symbols":[
|
|
600
|
+
// {
|
|
601
|
+
// "symbol":"SHABTC",
|
|
602
|
+
// "status":"TRADING",
|
|
603
|
+
// "baseAsset":"sha",
|
|
604
|
+
// "baseAssetPrecision":0,
|
|
605
|
+
// "quoteAsset":"btc",
|
|
606
|
+
// "quotePrecision":10,
|
|
607
|
+
// "orderTypes":["MARKET","LIMIT"],
|
|
608
|
+
// "icebergAllowed":false,
|
|
609
|
+
// "filters":[
|
|
610
|
+
// {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10},
|
|
611
|
+
// {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0},
|
|
612
|
+
// ],
|
|
613
|
+
// "defaultPrice":"0.0000006100",
|
|
614
|
+
// },
|
|
615
|
+
// ],
|
|
616
|
+
// "coins":[
|
|
617
|
+
// {
|
|
618
|
+
// "coin": "near",
|
|
619
|
+
// "coinFulName": "NEAR Protocol",
|
|
620
|
+
// "chains": [ "BEP20", ],
|
|
621
|
+
// "chainDetail": [
|
|
622
|
+
// {
|
|
623
|
+
// "chain": "BEP20",
|
|
624
|
+
// "enableWithdraw": true,
|
|
625
|
+
// "enableDeposit": true,
|
|
626
|
+
// "withdrawFee": "0.2000",
|
|
627
|
+
// "minWithdraw": "5.0000",
|
|
628
|
+
// "maxWithdraw": "1000000000000000.0000",
|
|
629
|
+
// },
|
|
630
|
+
// ],
|
|
631
|
+
// },
|
|
632
|
+
// ],
|
|
633
|
+
// }
|
|
634
|
+
//
|
|
635
|
+
const result = {};
|
|
636
|
+
const coins = this.safeValue(response, 'coins', []);
|
|
637
|
+
for (let i = 0; i < coins.length; i++) {
|
|
638
|
+
const currency = coins[i];
|
|
639
|
+
const id = this.safeString(currency, 'coin');
|
|
640
|
+
const name = this.safeString(currency, 'coinFulName');
|
|
641
|
+
const code = this.safeCurrencyCode(id);
|
|
642
|
+
let deposit = undefined;
|
|
643
|
+
let withdraw = undefined;
|
|
644
|
+
let minWithdrawString = undefined;
|
|
645
|
+
let maxWithdrawString = undefined;
|
|
646
|
+
let minWithdrawFeeString = undefined;
|
|
647
|
+
const networkDetails = this.safeValue(currency, 'chainDetail', []);
|
|
648
|
+
const networks = {};
|
|
649
|
+
for (let j = 0; j < networkDetails.length; j++) {
|
|
650
|
+
const entry = networkDetails[j];
|
|
651
|
+
const networkId = this.safeString(entry, 'chain');
|
|
652
|
+
const network = this.networkIdToCode(networkId, code);
|
|
653
|
+
const enableDeposit = this.safeValue(entry, 'enableDeposit');
|
|
654
|
+
deposit = (enableDeposit) ? enableDeposit : deposit;
|
|
655
|
+
const enableWithdraw = this.safeValue(entry, 'enableWithdraw');
|
|
656
|
+
withdraw = (enableWithdraw) ? enableWithdraw : withdraw;
|
|
657
|
+
const networkWithdrawFeeString = this.safeString(entry, 'withdrawFee');
|
|
658
|
+
if (networkWithdrawFeeString !== undefined) {
|
|
659
|
+
minWithdrawFeeString = (minWithdrawFeeString === undefined) ? networkWithdrawFeeString : Precise["default"].stringMin(networkWithdrawFeeString, minWithdrawFeeString);
|
|
660
|
+
}
|
|
661
|
+
const networkMinWithdrawString = this.safeString(entry, 'minWithdraw');
|
|
662
|
+
if (networkMinWithdrawString !== undefined) {
|
|
663
|
+
minWithdrawString = (minWithdrawString === undefined) ? networkMinWithdrawString : Precise["default"].stringMin(networkMinWithdrawString, minWithdrawString);
|
|
664
|
+
}
|
|
665
|
+
const networkMaxWithdrawString = this.safeString(entry, 'maxWithdraw');
|
|
666
|
+
if (networkMaxWithdrawString !== undefined) {
|
|
667
|
+
maxWithdrawString = (maxWithdrawString === undefined) ? networkMaxWithdrawString : Precise["default"].stringMax(networkMaxWithdrawString, maxWithdrawString);
|
|
668
|
+
}
|
|
669
|
+
networks[network] = {
|
|
670
|
+
'info': entry,
|
|
671
|
+
'id': networkId,
|
|
672
|
+
'network': network,
|
|
673
|
+
'deposit': enableDeposit,
|
|
674
|
+
'withdraw': enableWithdraw,
|
|
675
|
+
'active': enableDeposit && enableWithdraw,
|
|
676
|
+
'fee': this.parseNumber(networkWithdrawFeeString),
|
|
677
|
+
'precision': undefined,
|
|
678
|
+
'limits': {
|
|
679
|
+
'withdraw': {
|
|
680
|
+
'min': this.parseNumber(networkMinWithdrawString),
|
|
681
|
+
'max': this.parseNumber(networkMaxWithdrawString),
|
|
682
|
+
},
|
|
683
|
+
},
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
result[code] = {
|
|
687
|
+
'id': id,
|
|
688
|
+
'name': name,
|
|
689
|
+
'code': code,
|
|
690
|
+
'precision': undefined,
|
|
691
|
+
'info': currency,
|
|
692
|
+
'active': deposit && withdraw,
|
|
693
|
+
'deposit': deposit,
|
|
694
|
+
'withdraw': withdraw,
|
|
695
|
+
'networks': networks,
|
|
696
|
+
'fee': this.parseNumber(minWithdrawFeeString),
|
|
697
|
+
// 'fees': fees,
|
|
698
|
+
'limits': {
|
|
699
|
+
'withdraw': {
|
|
700
|
+
'min': this.parseNumber(minWithdrawString),
|
|
701
|
+
'max': this.parseNumber(maxWithdrawString),
|
|
702
|
+
},
|
|
703
|
+
},
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
return result;
|
|
707
|
+
}
|
|
708
|
+
async fetchMarkets(params = {}) {
|
|
709
|
+
/**
|
|
710
|
+
* @method
|
|
711
|
+
* @name bitrue#fetchMarkets
|
|
712
|
+
* @description retrieves data on all markets for bitrue
|
|
713
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint
|
|
714
|
+
* @see https://www.bitrue.com/api-docs#current-open-contract
|
|
715
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#current-open-contract
|
|
716
|
+
* @param {object} [params] extra parameters specific to the exchange api endpoint
|
|
717
|
+
* @returns {object[]} an array of objects representing market data
|
|
718
|
+
*/
|
|
719
|
+
const promisesRaw = [];
|
|
720
|
+
const fetchMarkets = this.safeValue(this.options, 'fetchMarkets', ['spot', 'linear', 'inverse']);
|
|
721
|
+
for (let i = 0; i < fetchMarkets.length; i++) {
|
|
722
|
+
const marketType = fetchMarkets[i];
|
|
723
|
+
if (marketType === 'spot') {
|
|
724
|
+
promisesRaw.push(this.spotV1PublicGetExchangeInfo(params));
|
|
725
|
+
}
|
|
726
|
+
else if (marketType === 'linear') {
|
|
727
|
+
promisesRaw.push(this.fapiV1PublicGetContracts(params));
|
|
728
|
+
}
|
|
729
|
+
else if (marketType === 'inverse') {
|
|
730
|
+
promisesRaw.push(this.dapiV1PublicGetContracts(params));
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
throw new errors.ExchangeError(this.id + ' fetchMarkets() this.options fetchMarkets "' + marketType + '" is not a supported market type');
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
const promises = await Promise.all(promisesRaw);
|
|
737
|
+
const spotMarkets = this.safeValue(this.safeValue(promises, 0), 'symbols', []);
|
|
738
|
+
const futureMarkets = this.safeValue(promises, 1);
|
|
739
|
+
const deliveryMarkets = this.safeValue(promises, 2);
|
|
740
|
+
let markets = spotMarkets;
|
|
741
|
+
markets = this.arrayConcat(markets, futureMarkets);
|
|
742
|
+
markets = this.arrayConcat(markets, deliveryMarkets);
|
|
743
|
+
//
|
|
744
|
+
// spot
|
|
745
|
+
//
|
|
746
|
+
// {
|
|
747
|
+
// "timezone":"CTT",
|
|
748
|
+
// "serverTime":1635464889117,
|
|
749
|
+
// "rateLimits":[
|
|
750
|
+
// {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000},
|
|
751
|
+
// {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150},
|
|
752
|
+
// {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000},
|
|
753
|
+
// ],
|
|
754
|
+
// "exchangeFilters":[],
|
|
755
|
+
// "symbols":[
|
|
756
|
+
// {
|
|
757
|
+
// "symbol":"SHABTC",
|
|
758
|
+
// "status":"TRADING",
|
|
759
|
+
// "baseAsset":"sha",
|
|
760
|
+
// "baseAssetPrecision":0,
|
|
761
|
+
// "quoteAsset":"btc",
|
|
762
|
+
// "quotePrecision":10,
|
|
763
|
+
// "orderTypes":["MARKET","LIMIT"],
|
|
764
|
+
// "icebergAllowed":false,
|
|
765
|
+
// "filters":[
|
|
766
|
+
// {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10},
|
|
767
|
+
// {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0},
|
|
768
|
+
// ],
|
|
769
|
+
// "defaultPrice":"0.0000006100",
|
|
770
|
+
// },
|
|
771
|
+
// ],
|
|
772
|
+
// "coins":[
|
|
773
|
+
// {
|
|
774
|
+
// "coin":"sbr",
|
|
775
|
+
// "coinFulName":"Saber",
|
|
776
|
+
// "enableWithdraw":true,
|
|
777
|
+
// "enableDeposit":true,
|
|
778
|
+
// "chains":["SOLANA"],
|
|
779
|
+
// "withdrawFee":"2.0",
|
|
780
|
+
// "minWithdraw":"5.0",
|
|
781
|
+
// "maxWithdraw":"1000000000000000",
|
|
782
|
+
// },
|
|
783
|
+
// ],
|
|
784
|
+
// }
|
|
785
|
+
//
|
|
786
|
+
// swap / delivery
|
|
787
|
+
//
|
|
788
|
+
// [
|
|
789
|
+
// {
|
|
790
|
+
// "symbol": "H-HT-USDT",
|
|
791
|
+
// "pricePrecision": 8,
|
|
792
|
+
// "side": 1,
|
|
793
|
+
// "maxMarketVolume": 100000,
|
|
794
|
+
// "multiplier": 6,
|
|
795
|
+
// "minOrderVolume": 1,
|
|
796
|
+
// "maxMarketMoney": 10000000,
|
|
797
|
+
// "type": "H", // E: perpetual contract, S: test contract, others are mixed contract
|
|
798
|
+
// "maxLimitVolume": 1000000,
|
|
799
|
+
// "maxValidOrder": 20,
|
|
800
|
+
// "multiplierCoin": "HT",
|
|
801
|
+
// "minOrderMoney": 0.001,
|
|
802
|
+
// "maxLimitMoney": 1000000,
|
|
803
|
+
// "status": 1
|
|
804
|
+
// }
|
|
805
|
+
// ]
|
|
806
|
+
//
|
|
807
|
+
if (this.options['adjustForTimeDifference']) {
|
|
808
|
+
await this.loadTimeDifference();
|
|
809
|
+
}
|
|
810
|
+
return this.parseMarkets(markets);
|
|
811
|
+
}
|
|
812
|
+
parseMarket(market) {
|
|
813
|
+
const id = this.safeString(market, 'symbol');
|
|
814
|
+
const lowercaseId = this.safeStringLower(market, 'symbol');
|
|
815
|
+
const side = this.safeInteger(market, 'side'); // 1 linear, 0 inverse, undefined spot
|
|
816
|
+
let type = undefined;
|
|
817
|
+
let isLinear = undefined;
|
|
818
|
+
let isInverse = undefined;
|
|
819
|
+
if (side === undefined) {
|
|
820
|
+
type = 'spot';
|
|
821
|
+
}
|
|
822
|
+
else {
|
|
823
|
+
type = 'swap';
|
|
824
|
+
isLinear = (side === 1);
|
|
825
|
+
isInverse = (side === 0);
|
|
826
|
+
}
|
|
827
|
+
const isContract = (type !== 'spot');
|
|
828
|
+
let baseId = this.safeString(market, 'baseAsset');
|
|
829
|
+
let quoteId = this.safeString(market, 'quoteAsset');
|
|
830
|
+
let settleId = undefined;
|
|
831
|
+
let settle = undefined;
|
|
832
|
+
if (isContract) {
|
|
833
|
+
const symbolSplit = id.split('-');
|
|
834
|
+
baseId = this.safeString(symbolSplit, 1);
|
|
835
|
+
quoteId = this.safeString(symbolSplit, 2);
|
|
836
|
+
if (isLinear) {
|
|
837
|
+
settleId = quoteId;
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
settleId = baseId;
|
|
841
|
+
}
|
|
842
|
+
settle = this.safeCurrencyCode(settleId);
|
|
843
|
+
}
|
|
844
|
+
const base = this.safeCurrencyCode(baseId);
|
|
845
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
846
|
+
let symbol = base + '/' + quote;
|
|
847
|
+
if (settle !== undefined) {
|
|
848
|
+
symbol += ':' + settle;
|
|
849
|
+
}
|
|
850
|
+
const filters = this.safeValue(market, 'filters', []);
|
|
851
|
+
const filtersByType = this.indexBy(filters, 'filterType');
|
|
852
|
+
const status = this.safeString(market, 'status');
|
|
853
|
+
const priceFilter = this.safeValue(filtersByType, 'PRICE_FILTER', {});
|
|
854
|
+
const amountFilter = this.safeValue(filtersByType, 'LOT_SIZE', {});
|
|
855
|
+
const defaultPricePrecision = this.safeString(market, 'pricePrecision');
|
|
856
|
+
const defaultAmountPrecision = this.safeString(market, 'quantityPrecision');
|
|
857
|
+
const pricePrecision = this.safeString(priceFilter, 'priceScale', defaultPricePrecision);
|
|
858
|
+
const amountPrecision = this.safeString(amountFilter, 'volumeScale', defaultAmountPrecision);
|
|
859
|
+
const multiplier = this.safeString(market, 'multiplier');
|
|
860
|
+
let maxQuantity = this.safeNumber(amountFilter, 'maxQty');
|
|
861
|
+
if (maxQuantity === undefined) {
|
|
862
|
+
maxQuantity = this.safeNumber(market, 'maxValidOrder');
|
|
863
|
+
}
|
|
864
|
+
let minCost = this.safeNumber(amountFilter, 'minVal');
|
|
865
|
+
if (minCost === undefined) {
|
|
866
|
+
minCost = this.safeNumber(market, 'minOrderMoney');
|
|
867
|
+
}
|
|
868
|
+
return {
|
|
869
|
+
'id': id,
|
|
870
|
+
'lowercaseId': lowercaseId,
|
|
871
|
+
'symbol': symbol,
|
|
872
|
+
'base': base,
|
|
873
|
+
'quote': quote,
|
|
874
|
+
'settle': settle,
|
|
875
|
+
'baseId': baseId,
|
|
876
|
+
'quoteId': quoteId,
|
|
877
|
+
'settleId': settleId,
|
|
878
|
+
'type': type,
|
|
879
|
+
'spot': (type === 'spot'),
|
|
880
|
+
'margin': false,
|
|
881
|
+
'swap': isContract,
|
|
882
|
+
'future': false,
|
|
883
|
+
'option': false,
|
|
884
|
+
'active': (status === 'TRADING'),
|
|
885
|
+
'contract': isContract,
|
|
886
|
+
'linear': isLinear,
|
|
887
|
+
'inverse': isInverse,
|
|
888
|
+
'contractSize': this.parseNumber(Precise["default"].stringAbs(multiplier)),
|
|
889
|
+
'expiry': undefined,
|
|
890
|
+
'expiryDatetime': undefined,
|
|
891
|
+
'strike': undefined,
|
|
892
|
+
'optionType': undefined,
|
|
893
|
+
'precision': {
|
|
894
|
+
'amount': this.parseNumber(this.parsePrecision(amountPrecision)),
|
|
895
|
+
'price': this.parseNumber(this.parsePrecision(pricePrecision)),
|
|
896
|
+
},
|
|
897
|
+
'limits': {
|
|
898
|
+
'leverage': {
|
|
899
|
+
'min': undefined,
|
|
900
|
+
'max': undefined,
|
|
901
|
+
},
|
|
902
|
+
'amount': {
|
|
903
|
+
'min': this.safeNumber(amountFilter, 'minQty'),
|
|
904
|
+
'max': maxQuantity,
|
|
905
|
+
},
|
|
906
|
+
'price': {
|
|
907
|
+
'min': this.safeNumber(priceFilter, 'minPrice'),
|
|
908
|
+
'max': this.safeNumber(priceFilter, 'maxPrice'),
|
|
909
|
+
},
|
|
910
|
+
'cost': {
|
|
911
|
+
'min': minCost,
|
|
912
|
+
'max': undefined,
|
|
913
|
+
},
|
|
914
|
+
},
|
|
915
|
+
'created': undefined,
|
|
916
|
+
'info': market,
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
parseBalance(response) {
|
|
920
|
+
//
|
|
921
|
+
// spot
|
|
922
|
+
//
|
|
923
|
+
// {
|
|
924
|
+
// "makerCommission":0,
|
|
925
|
+
// "takerCommission":0,
|
|
926
|
+
// "buyerCommission":0,
|
|
927
|
+
// "sellerCommission":0,
|
|
928
|
+
// "updateTime":null,
|
|
929
|
+
// "balances":[
|
|
930
|
+
// {"asset":"sbr","free":"0","locked":"0"},
|
|
931
|
+
// {"asset":"ksm","free":"0","locked":"0"},
|
|
932
|
+
// {"asset":"neo3s","free":"0","locked":"0"},
|
|
933
|
+
// ],
|
|
934
|
+
// "canTrade":false,
|
|
935
|
+
// "canWithdraw":false,
|
|
936
|
+
// "canDeposit":false
|
|
937
|
+
// }
|
|
938
|
+
//
|
|
939
|
+
// swap
|
|
940
|
+
//
|
|
941
|
+
// {
|
|
942
|
+
// "account":[
|
|
943
|
+
// {
|
|
944
|
+
// "marginCoin":"USDT",
|
|
945
|
+
// "coinPrecious":4,
|
|
946
|
+
// "accountNormal":1010.4043400372839856,
|
|
947
|
+
// "accountLock":2.9827889600000006,
|
|
948
|
+
// "partPositionNormal":0,
|
|
949
|
+
// "totalPositionNormal":0,
|
|
950
|
+
// "achievedAmount":0,
|
|
951
|
+
// "unrealizedAmount":0,
|
|
952
|
+
// "totalMarginRate":0,
|
|
953
|
+
// "totalEquity":1010.4043400372839856,
|
|
954
|
+
// "partEquity":0,
|
|
955
|
+
// "totalCost":0,
|
|
956
|
+
// "sumMarginRate":0,
|
|
957
|
+
// "sumOpenRealizedAmount":0,
|
|
958
|
+
// "canUseTrialFund":0,
|
|
959
|
+
// "sumMaintenanceMargin":null,
|
|
960
|
+
// "futureModel":null,
|
|
961
|
+
// "positionVos":[]
|
|
962
|
+
// }
|
|
963
|
+
// ]
|
|
964
|
+
// }
|
|
965
|
+
//
|
|
966
|
+
const result = {
|
|
967
|
+
'info': response,
|
|
968
|
+
};
|
|
969
|
+
const timestamp = this.safeInteger(response, 'updateTime');
|
|
970
|
+
const balances = this.safeValue2(response, 'balances', 'account', []);
|
|
971
|
+
for (let i = 0; i < balances.length; i++) {
|
|
972
|
+
const balance = balances[i];
|
|
973
|
+
const currencyId = this.safeString2(balance, 'asset', 'marginCoin');
|
|
974
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
975
|
+
const account = this.account();
|
|
976
|
+
account['free'] = this.safeString2(balance, 'free', 'accountNormal');
|
|
977
|
+
account['used'] = this.safeString2(balance, 'locked', 'accountLock');
|
|
978
|
+
result[code] = account;
|
|
979
|
+
}
|
|
980
|
+
result['timestamp'] = timestamp;
|
|
981
|
+
result['datetime'] = this.iso8601(timestamp);
|
|
982
|
+
return this.safeBalance(result);
|
|
983
|
+
}
|
|
984
|
+
async fetchBalance(params = {}) {
|
|
985
|
+
/**
|
|
986
|
+
* @method
|
|
987
|
+
* @name bitrue#fetchBalance
|
|
988
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
989
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#account-information-user_data
|
|
990
|
+
* @see https://www.bitrue.com/api-docs#account-information-v2-user_data-hmac-sha256
|
|
991
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#account-information-v2-user_data-hmac-sha256
|
|
992
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
993
|
+
* @param {string} [params.type] 'future', 'delivery', 'spot', 'swap'
|
|
994
|
+
* @param {string} [params.subType] 'linear', 'inverse'
|
|
995
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
996
|
+
*/
|
|
997
|
+
await this.loadMarkets();
|
|
998
|
+
let type = undefined;
|
|
999
|
+
[type, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
|
|
1000
|
+
let subType = undefined;
|
|
1001
|
+
[subType, params] = this.handleSubTypeAndParams('fetchBalance', undefined, params);
|
|
1002
|
+
let response = undefined;
|
|
1003
|
+
let result = undefined;
|
|
1004
|
+
if (type === 'swap') {
|
|
1005
|
+
if (subType !== undefined && subType === 'inverse') {
|
|
1006
|
+
response = await this.dapiV2PrivateGetAccount(params);
|
|
1007
|
+
result = this.safeValue(response, 'data', {});
|
|
1008
|
+
//
|
|
1009
|
+
// {
|
|
1010
|
+
// "code":"0",
|
|
1011
|
+
// "msg":"Success",
|
|
1012
|
+
// "data":{
|
|
1013
|
+
// "account":[
|
|
1014
|
+
// {
|
|
1015
|
+
// "marginCoin":"USD",
|
|
1016
|
+
// "coinPrecious":4,
|
|
1017
|
+
// "accountNormal":1010.4043400372839856,
|
|
1018
|
+
// "accountLock":2.9827889600000006,
|
|
1019
|
+
// "partPositionNormal":0,
|
|
1020
|
+
// "totalPositionNormal":0,
|
|
1021
|
+
// "achievedAmount":0,
|
|
1022
|
+
// "unrealizedAmount":0,
|
|
1023
|
+
// "totalMarginRate":0,
|
|
1024
|
+
// "totalEquity":1010.4043400372839856,
|
|
1025
|
+
// "partEquity":0,
|
|
1026
|
+
// "totalCost":0,
|
|
1027
|
+
// "sumMarginRate":0,
|
|
1028
|
+
// "sumOpenRealizedAmount":0,
|
|
1029
|
+
// "canUseTrialFund":0,
|
|
1030
|
+
// "sumMaintenanceMargin":null,
|
|
1031
|
+
// "futureModel":null,
|
|
1032
|
+
// "positionVos":[]
|
|
1033
|
+
// }
|
|
1034
|
+
// ]
|
|
1035
|
+
// }
|
|
1036
|
+
// }
|
|
1037
|
+
//
|
|
1038
|
+
}
|
|
1039
|
+
else {
|
|
1040
|
+
response = await this.fapiV2PrivateGetAccount(params);
|
|
1041
|
+
result = this.safeValue(response, 'data', {});
|
|
1042
|
+
//
|
|
1043
|
+
// {
|
|
1044
|
+
// "code":"0",
|
|
1045
|
+
// "msg":"Success",
|
|
1046
|
+
// "data":{
|
|
1047
|
+
// "account":[
|
|
1048
|
+
// {
|
|
1049
|
+
// "marginCoin":"USDT",
|
|
1050
|
+
// "coinPrecious":4,
|
|
1051
|
+
// "accountNormal":1010.4043400372839856,
|
|
1052
|
+
// "accountLock":2.9827889600000006,
|
|
1053
|
+
// "partPositionNormal":0,
|
|
1054
|
+
// "totalPositionNormal":0,
|
|
1055
|
+
// "achievedAmount":0,
|
|
1056
|
+
// "unrealizedAmount":0,
|
|
1057
|
+
// "totalMarginRate":0,
|
|
1058
|
+
// "totalEquity":1010.4043400372839856,
|
|
1059
|
+
// "partEquity":0,
|
|
1060
|
+
// "totalCost":0,
|
|
1061
|
+
// "sumMarginRate":0,
|
|
1062
|
+
// "sumOpenRealizedAmount":0,
|
|
1063
|
+
// "canUseTrialFund":0,
|
|
1064
|
+
// "sumMaintenanceMargin":null,
|
|
1065
|
+
// "futureModel":null,
|
|
1066
|
+
// "positionVos":[]
|
|
1067
|
+
// }
|
|
1068
|
+
// ]
|
|
1069
|
+
// }
|
|
1070
|
+
// }
|
|
1071
|
+
//
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
else {
|
|
1075
|
+
response = await this.spotV1PrivateGetAccount(params);
|
|
1076
|
+
result = response;
|
|
1077
|
+
//
|
|
1078
|
+
// {
|
|
1079
|
+
// "makerCommission":0,
|
|
1080
|
+
// "takerCommission":0,
|
|
1081
|
+
// "buyerCommission":0,
|
|
1082
|
+
// "sellerCommission":0,
|
|
1083
|
+
// "updateTime":null,
|
|
1084
|
+
// "balances":[
|
|
1085
|
+
// {"asset":"sbr","free":"0","locked":"0"},
|
|
1086
|
+
// {"asset":"ksm","free":"0","locked":"0"},
|
|
1087
|
+
// {"asset":"neo3s","free":"0","locked":"0"},
|
|
1088
|
+
// ],
|
|
1089
|
+
// "canTrade":false,
|
|
1090
|
+
// "canWithdraw":false,
|
|
1091
|
+
// "canDeposit":false
|
|
1092
|
+
// }
|
|
1093
|
+
//
|
|
1094
|
+
}
|
|
1095
|
+
return this.parseBalance(result);
|
|
1096
|
+
}
|
|
1097
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
1098
|
+
/**
|
|
1099
|
+
* @method
|
|
1100
|
+
* @name bitrue#fetchOrderBook
|
|
1101
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
1102
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#order-book
|
|
1103
|
+
* @see https://www.bitrue.com/api-docs#order-book
|
|
1104
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#order-book
|
|
1105
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
1106
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
1107
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1108
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
1109
|
+
*/
|
|
1110
|
+
await this.loadMarkets();
|
|
1111
|
+
const market = this.market(symbol);
|
|
1112
|
+
let response = undefined;
|
|
1113
|
+
if (market['swap']) {
|
|
1114
|
+
const request = {
|
|
1115
|
+
'contractName': market['id'],
|
|
1116
|
+
};
|
|
1117
|
+
if (limit !== undefined) {
|
|
1118
|
+
if (limit > 100) {
|
|
1119
|
+
limit = 100;
|
|
1120
|
+
}
|
|
1121
|
+
request['limit'] = limit; // default 100, max 100, see https://www.bitrue.com/api-docs#order-book
|
|
1122
|
+
}
|
|
1123
|
+
if (market['linear']) {
|
|
1124
|
+
response = await this.fapiV1PublicGetDepth(this.extend(request, params));
|
|
1125
|
+
}
|
|
1126
|
+
else if (market['inverse']) {
|
|
1127
|
+
response = await this.dapiV1PublicGetDepth(this.extend(request, params));
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
else if (market['spot']) {
|
|
1131
|
+
const request = {
|
|
1132
|
+
'symbol': market['id'],
|
|
1133
|
+
};
|
|
1134
|
+
if (limit !== undefined) {
|
|
1135
|
+
if (limit > 1000) {
|
|
1136
|
+
limit = 1000;
|
|
1137
|
+
}
|
|
1138
|
+
request['limit'] = limit; // default 100, max 1000, see https://github.com/Bitrue-exchange/bitrue-official-api-docs#order-book
|
|
1139
|
+
}
|
|
1140
|
+
response = await this.spotV1PublicGetDepth(this.extend(request, params));
|
|
1141
|
+
}
|
|
1142
|
+
else {
|
|
1143
|
+
throw new errors.NotSupported(this.id + ' fetchOrderBook only support spot & swap markets');
|
|
1144
|
+
}
|
|
1145
|
+
//
|
|
1146
|
+
// spot
|
|
1147
|
+
//
|
|
1148
|
+
// {
|
|
1149
|
+
// "lastUpdateId":1635474910177,
|
|
1150
|
+
// "bids":[
|
|
1151
|
+
// ["61436.84","0.05",[]],
|
|
1152
|
+
// ["61435.77","0.0124",[]],
|
|
1153
|
+
// ["61434.88","0.012",[]],
|
|
1154
|
+
// ],
|
|
1155
|
+
// "asks":[
|
|
1156
|
+
// ["61452.46","0.0001",[]],
|
|
1157
|
+
// ["61452.47","0.0597",[]],
|
|
1158
|
+
// ["61452.76","0.0713",[]],
|
|
1159
|
+
// ]
|
|
1160
|
+
// }
|
|
1161
|
+
//
|
|
1162
|
+
// swap
|
|
1163
|
+
//
|
|
1164
|
+
// {
|
|
1165
|
+
// "asks": [[34916.5, 2582], [34916.6, 2193], [34916.7, 2629], [34916.8, 3478], [34916.9, 2718]],
|
|
1166
|
+
// "bids": [[34916.4, 92065], [34916.3, 25703], [34916.2, 37259], [34916.1, 26446], [34916, 44456]],
|
|
1167
|
+
// "time": 1699338305000
|
|
1168
|
+
// }
|
|
1169
|
+
//
|
|
1170
|
+
const timestamp = this.safeInteger(response, 'time');
|
|
1171
|
+
const orderbook = this.parseOrderBook(response, symbol, timestamp);
|
|
1172
|
+
orderbook['nonce'] = this.safeInteger(response, 'lastUpdateId');
|
|
1173
|
+
return orderbook;
|
|
1174
|
+
}
|
|
1175
|
+
parseTicker(ticker, market = undefined) {
|
|
1176
|
+
//
|
|
1177
|
+
// fetchBidsAsks
|
|
1178
|
+
//
|
|
1179
|
+
// {
|
|
1180
|
+
// "symbol": "LTCBTC",
|
|
1181
|
+
// "bidPrice": "4.00000000",
|
|
1182
|
+
// "bidQty": "431.00000000",
|
|
1183
|
+
// "askPrice": "4.00000200",
|
|
1184
|
+
// "askQty": "9.00000000"
|
|
1185
|
+
// }
|
|
1186
|
+
//
|
|
1187
|
+
// fetchTicker
|
|
1188
|
+
//
|
|
1189
|
+
// {
|
|
1190
|
+
// "symbol": "BNBBTC",
|
|
1191
|
+
// "priceChange": "0.000248",
|
|
1192
|
+
// "priceChangePercent": "3.5500",
|
|
1193
|
+
// "weightedAvgPrice": null,
|
|
1194
|
+
// "prevClosePrice": null,
|
|
1195
|
+
// "lastPrice": "0.007226",
|
|
1196
|
+
// "lastQty": null,
|
|
1197
|
+
// "bidPrice": "0.007208",
|
|
1198
|
+
// "askPrice": "0.007240",
|
|
1199
|
+
// "openPrice": "0.006978",
|
|
1200
|
+
// "highPrice": "0.007295",
|
|
1201
|
+
// "lowPrice": "0.006935",
|
|
1202
|
+
// "volume": "11749.86",
|
|
1203
|
+
// "quoteVolume": "84.1066211",
|
|
1204
|
+
// "openTime": 0,
|
|
1205
|
+
// "closeTime": 0,
|
|
1206
|
+
// "firstId": 0,
|
|
1207
|
+
// "lastId": 0,
|
|
1208
|
+
// "count": 0
|
|
1209
|
+
// }
|
|
1210
|
+
//
|
|
1211
|
+
const symbol = this.safeSymbol(undefined, market);
|
|
1212
|
+
const last = this.safeString2(ticker, 'lastPrice', 'last');
|
|
1213
|
+
const timestamp = this.safeInteger(ticker, 'time');
|
|
1214
|
+
let percentage = undefined;
|
|
1215
|
+
if (market['swap']) {
|
|
1216
|
+
percentage = Precise["default"].stringMul(this.safeString(ticker, 'rose'), '100');
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
percentage = this.safeString(ticker, 'priceChangePercent');
|
|
1220
|
+
}
|
|
1221
|
+
return this.safeTicker({
|
|
1222
|
+
'symbol': symbol,
|
|
1223
|
+
'timestamp': timestamp,
|
|
1224
|
+
'datetime': this.iso8601(timestamp),
|
|
1225
|
+
'high': this.safeString2(ticker, 'highPrice', 'high'),
|
|
1226
|
+
'low': this.safeString2(ticker, 'lowPrice', 'low'),
|
|
1227
|
+
'bid': this.safeString2(ticker, 'bidPrice', 'buy'),
|
|
1228
|
+
'bidVolume': this.safeString(ticker, 'bidQty'),
|
|
1229
|
+
'ask': this.safeString2(ticker, 'askPrice', 'sell'),
|
|
1230
|
+
'askVolume': this.safeString(ticker, 'askQty'),
|
|
1231
|
+
'vwap': this.safeString(ticker, 'weightedAvgPrice'),
|
|
1232
|
+
'open': this.safeString(ticker, 'openPrice'),
|
|
1233
|
+
'close': last,
|
|
1234
|
+
'last': last,
|
|
1235
|
+
'previousClose': undefined,
|
|
1236
|
+
'change': this.safeString(ticker, 'priceChange'),
|
|
1237
|
+
'percentage': percentage,
|
|
1238
|
+
'average': undefined,
|
|
1239
|
+
'baseVolume': this.safeString2(ticker, 'volume', 'vol'),
|
|
1240
|
+
'quoteVolume': this.safeString(ticker, 'quoteVolume'),
|
|
1241
|
+
'info': ticker,
|
|
1242
|
+
}, market);
|
|
1243
|
+
}
|
|
1244
|
+
async fetchTicker(symbol, params = {}) {
|
|
1245
|
+
/**
|
|
1246
|
+
* @method
|
|
1247
|
+
* @name bitrue#fetchTicker
|
|
1248
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1249
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics
|
|
1250
|
+
* @see https://www.bitrue.com/api-docs#ticker
|
|
1251
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
|
|
1252
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1253
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1254
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1255
|
+
*/
|
|
1256
|
+
await this.loadMarkets();
|
|
1257
|
+
const market = this.market(symbol);
|
|
1258
|
+
let response = undefined;
|
|
1259
|
+
let data = undefined;
|
|
1260
|
+
if (market['swap']) {
|
|
1261
|
+
const request = {
|
|
1262
|
+
'contractName': market['id'],
|
|
1263
|
+
};
|
|
1264
|
+
if (market['linear']) {
|
|
1265
|
+
response = await this.fapiV1PublicGetTicker(this.extend(request, params));
|
|
1266
|
+
}
|
|
1267
|
+
else if (market['inverse']) {
|
|
1268
|
+
response = await this.dapiV1PublicGetTicker(this.extend(request, params));
|
|
1269
|
+
}
|
|
1270
|
+
data = response;
|
|
1271
|
+
}
|
|
1272
|
+
else if (market['spot']) {
|
|
1273
|
+
const request = {
|
|
1274
|
+
'symbol': market['id'],
|
|
1275
|
+
};
|
|
1276
|
+
response = await this.spotV1PublicGetTicker24hr(this.extend(request, params));
|
|
1277
|
+
data = this.safeValue(response, 0, {});
|
|
1278
|
+
}
|
|
1279
|
+
else {
|
|
1280
|
+
throw new errors.NotSupported(this.id + ' fetchTicker only support spot & swap markets');
|
|
1281
|
+
}
|
|
1282
|
+
//
|
|
1283
|
+
// spot
|
|
1284
|
+
//
|
|
1285
|
+
// [{
|
|
1286
|
+
// symbol: 'BTCUSDT',
|
|
1287
|
+
// priceChange: '105.20',
|
|
1288
|
+
// priceChangePercent: '0.3000',
|
|
1289
|
+
// weightedAvgPrice: null,
|
|
1290
|
+
// prevClosePrice: null,
|
|
1291
|
+
// lastPrice: '34905.21',
|
|
1292
|
+
// lastQty: null,
|
|
1293
|
+
// bidPrice: '34905.21',
|
|
1294
|
+
// askPrice: '34905.22',
|
|
1295
|
+
// openPrice: '34800.01',
|
|
1296
|
+
// highPrice: '35276.33',
|
|
1297
|
+
// lowPrice: '34787.51',
|
|
1298
|
+
// volume: '12549.6481',
|
|
1299
|
+
// quoteVolume: '439390492.917',
|
|
1300
|
+
// openTime: '0',
|
|
1301
|
+
// closeTime: '0',
|
|
1302
|
+
// firstId: '0',
|
|
1303
|
+
// lastId: '0',
|
|
1304
|
+
// count: '0'
|
|
1305
|
+
// }]
|
|
1306
|
+
//
|
|
1307
|
+
// swap
|
|
1308
|
+
//
|
|
1309
|
+
// {
|
|
1310
|
+
// "high": "35296",
|
|
1311
|
+
// "vol": "779308354",
|
|
1312
|
+
// "last": "34884.1",
|
|
1313
|
+
// "low": "34806.7",
|
|
1314
|
+
// "buy": 34883.9,
|
|
1315
|
+
// "sell": 34884,
|
|
1316
|
+
// "rose": "-0.0027957315",
|
|
1317
|
+
// "time": 1699348013000
|
|
1318
|
+
// }
|
|
1319
|
+
//
|
|
1320
|
+
return this.parseTicker(data, market);
|
|
1321
|
+
}
|
|
1322
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1323
|
+
/**
|
|
1324
|
+
* @method
|
|
1325
|
+
* @name bitrue#fetchOHLCV
|
|
1326
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1327
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#kline-data
|
|
1328
|
+
* @see https://www.bitrue.com/api-docs#kline-candlestick-data
|
|
1329
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#kline-candlestick-data
|
|
1330
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1331
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1332
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1333
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1334
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1335
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1336
|
+
*/
|
|
1337
|
+
await this.loadMarkets();
|
|
1338
|
+
const market = this.market(symbol);
|
|
1339
|
+
const timeframes = this.safeValue(this.options, 'timeframes', {});
|
|
1340
|
+
let response = undefined;
|
|
1341
|
+
let data = undefined;
|
|
1342
|
+
if (market['swap']) {
|
|
1343
|
+
const timeframesFuture = this.safeValue(timeframes, 'future', {});
|
|
1344
|
+
const request = {
|
|
1345
|
+
'contractName': market['id'],
|
|
1346
|
+
// 1min / 5min / 15min / 30min / 1h / 1day / 1week / 1month
|
|
1347
|
+
'interval': this.safeString(timeframesFuture, timeframe, '1min'),
|
|
1348
|
+
};
|
|
1349
|
+
if (limit !== undefined) {
|
|
1350
|
+
if (limit > 300) {
|
|
1351
|
+
limit = 300;
|
|
1352
|
+
}
|
|
1353
|
+
request['limit'] = limit;
|
|
1354
|
+
}
|
|
1355
|
+
if (market['linear']) {
|
|
1356
|
+
response = await this.fapiV1PublicGetKlines(this.extend(request, params));
|
|
1357
|
+
}
|
|
1358
|
+
else if (market['inverse']) {
|
|
1359
|
+
response = await this.dapiV1PublicGetKlines(this.extend(request, params));
|
|
1360
|
+
}
|
|
1361
|
+
data = response;
|
|
1362
|
+
}
|
|
1363
|
+
else if (market['spot']) {
|
|
1364
|
+
const timeframesSpot = this.safeValue(timeframes, 'spot', {});
|
|
1365
|
+
const request = {
|
|
1366
|
+
'symbol': market['id'],
|
|
1367
|
+
// 1m / 5m / 15m / 30m / 1H / 2H / 4H / 12H / 1D / 1W
|
|
1368
|
+
'scale': this.safeString(timeframesSpot, timeframe, '1m'),
|
|
1369
|
+
};
|
|
1370
|
+
if (limit !== undefined) {
|
|
1371
|
+
if (limit > 1440) {
|
|
1372
|
+
limit = 1440;
|
|
1373
|
+
}
|
|
1374
|
+
request['limit'] = limit;
|
|
1375
|
+
}
|
|
1376
|
+
if (since !== undefined) {
|
|
1377
|
+
request['fromIdx'] = since;
|
|
1378
|
+
}
|
|
1379
|
+
response = await this.spotV1PublicGetMarketKline(this.extend(request, params));
|
|
1380
|
+
data = this.safeValue(response, 'data', []);
|
|
1381
|
+
}
|
|
1382
|
+
else {
|
|
1383
|
+
throw new errors.NotSupported(this.id + ' fetchOHLCV only support spot & swap markets');
|
|
1384
|
+
}
|
|
1385
|
+
//
|
|
1386
|
+
// spot
|
|
1387
|
+
//
|
|
1388
|
+
// {
|
|
1389
|
+
// "symbol":"BTCUSDT",
|
|
1390
|
+
// "scale":"KLINE_1MIN",
|
|
1391
|
+
// "data":[
|
|
1392
|
+
// {
|
|
1393
|
+
// "i":"1660825020",
|
|
1394
|
+
// "a":"93458.778",
|
|
1395
|
+
// "v":"3.9774",
|
|
1396
|
+
// "c":"23494.99",
|
|
1397
|
+
// "h":"23509.63",
|
|
1398
|
+
// "l":"23491.93",
|
|
1399
|
+
// "o":"23508.34"
|
|
1400
|
+
// }
|
|
1401
|
+
// ]
|
|
1402
|
+
// }
|
|
1403
|
+
//
|
|
1404
|
+
// swap
|
|
1405
|
+
//
|
|
1406
|
+
// [
|
|
1407
|
+
// {
|
|
1408
|
+
// "high": "35360.7",
|
|
1409
|
+
// "vol": "110288",
|
|
1410
|
+
// "low": "35347.9",
|
|
1411
|
+
// "idx": 1699411680000,
|
|
1412
|
+
// "close": "35347.9",
|
|
1413
|
+
// "open": "35349.4"
|
|
1414
|
+
// }
|
|
1415
|
+
// ]
|
|
1416
|
+
//
|
|
1417
|
+
return this.parseOHLCVs(data, market, timeframe, since, limit);
|
|
1418
|
+
}
|
|
1419
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1420
|
+
//
|
|
1421
|
+
// spot
|
|
1422
|
+
//
|
|
1423
|
+
// {
|
|
1424
|
+
// "i":"1660825020",
|
|
1425
|
+
// "a":"93458.778",
|
|
1426
|
+
// "v":"3.9774",
|
|
1427
|
+
// "c":"23494.99",
|
|
1428
|
+
// "h":"23509.63",
|
|
1429
|
+
// "l":"23491.93",
|
|
1430
|
+
// "o":"23508.34"
|
|
1431
|
+
// }
|
|
1432
|
+
//
|
|
1433
|
+
// swap
|
|
1434
|
+
//
|
|
1435
|
+
// {
|
|
1436
|
+
// "high": "35360.7",
|
|
1437
|
+
// "vol": "110288",
|
|
1438
|
+
// "low": "35347.9",
|
|
1439
|
+
// "idx": 1699411680000,
|
|
1440
|
+
// "close": "35347.9",
|
|
1441
|
+
// "open": "35349.4"
|
|
1442
|
+
// }
|
|
1443
|
+
//
|
|
1444
|
+
let timestamp = this.safeTimestamp(ohlcv, 'i');
|
|
1445
|
+
if (timestamp === undefined) {
|
|
1446
|
+
timestamp = this.safeInteger(ohlcv, 'idx');
|
|
1447
|
+
}
|
|
1448
|
+
return [
|
|
1449
|
+
timestamp,
|
|
1450
|
+
this.safeNumber2(ohlcv, 'o', 'open'),
|
|
1451
|
+
this.safeNumber2(ohlcv, 'h', 'high'),
|
|
1452
|
+
this.safeNumber2(ohlcv, 'l', 'low'),
|
|
1453
|
+
this.safeNumber2(ohlcv, 'c', 'close'),
|
|
1454
|
+
this.safeNumber2(ohlcv, 'v', 'vol'),
|
|
1455
|
+
];
|
|
1456
|
+
}
|
|
1457
|
+
async fetchBidsAsks(symbols = undefined, params = {}) {
|
|
1458
|
+
/**
|
|
1459
|
+
* @method
|
|
1460
|
+
* @name bitrue#fetchBidsAsks
|
|
1461
|
+
* @description fetches the bid and ask price and volume for multiple markets
|
|
1462
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#symbol-order-book-ticker
|
|
1463
|
+
* @see https://www.bitrue.com/api-docs#ticker
|
|
1464
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
|
|
1465
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
|
1466
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1467
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1468
|
+
*/
|
|
1469
|
+
await this.loadMarkets();
|
|
1470
|
+
symbols = this.marketSymbols(symbols, undefined, false);
|
|
1471
|
+
const first = this.safeString(symbols, 0);
|
|
1472
|
+
const market = this.market(first);
|
|
1473
|
+
let response = undefined;
|
|
1474
|
+
if (market['swap']) {
|
|
1475
|
+
const request = {
|
|
1476
|
+
'contractName': market['id'],
|
|
1477
|
+
};
|
|
1478
|
+
if (market['linear']) {
|
|
1479
|
+
response = await this.fapiV1PublicGetTicker(this.extend(request, params));
|
|
1480
|
+
}
|
|
1481
|
+
else if (market['inverse']) {
|
|
1482
|
+
response = await this.dapiV1PublicGetTicker(this.extend(request, params));
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
else if (market['spot']) {
|
|
1486
|
+
const request = {
|
|
1487
|
+
'symbol': market['id'],
|
|
1488
|
+
};
|
|
1489
|
+
response = await this.spotV1PublicGetTickerBookTicker(this.extend(request, params));
|
|
1490
|
+
}
|
|
1491
|
+
else {
|
|
1492
|
+
throw new errors.NotSupported(this.id + ' fetchBidsAsks only support spot & swap markets');
|
|
1493
|
+
}
|
|
1494
|
+
//
|
|
1495
|
+
// spot
|
|
1496
|
+
//
|
|
1497
|
+
// {
|
|
1498
|
+
// "symbol": "LTCBTC",
|
|
1499
|
+
// "bidPrice": "4.00000000",
|
|
1500
|
+
// "bidQty": "431.00000000",
|
|
1501
|
+
// "askPrice": "4.00000200",
|
|
1502
|
+
// "askQty": "9.00000000"
|
|
1503
|
+
// }
|
|
1504
|
+
//
|
|
1505
|
+
// swap
|
|
1506
|
+
//
|
|
1507
|
+
// {
|
|
1508
|
+
// "high": "35296",
|
|
1509
|
+
// "vol": "779308354",
|
|
1510
|
+
// "last": "34884.1",
|
|
1511
|
+
// "low": "34806.7",
|
|
1512
|
+
// "buy": 34883.9,
|
|
1513
|
+
// "sell": 34884,
|
|
1514
|
+
// "rose": "-0.0027957315",
|
|
1515
|
+
// "time": 1699348013000
|
|
1516
|
+
// }
|
|
1517
|
+
//
|
|
1518
|
+
const data = {};
|
|
1519
|
+
data[market['id']] = response;
|
|
1520
|
+
return this.parseTickers(data, symbols);
|
|
1521
|
+
}
|
|
1522
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
1523
|
+
/**
|
|
1524
|
+
* @method
|
|
1525
|
+
* @name bitrue#fetchTickers
|
|
1526
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1527
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics
|
|
1528
|
+
* @see https://www.bitrue.com/api-docs#ticker
|
|
1529
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
|
|
1530
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1531
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1532
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1533
|
+
*/
|
|
1534
|
+
await this.loadMarkets();
|
|
1535
|
+
symbols = this.marketSymbols(symbols);
|
|
1536
|
+
let response = undefined;
|
|
1537
|
+
let data = undefined;
|
|
1538
|
+
const request = {};
|
|
1539
|
+
let type = undefined;
|
|
1540
|
+
if (symbols !== undefined) {
|
|
1541
|
+
const first = this.safeString(symbols, 0);
|
|
1542
|
+
const market = this.market(first);
|
|
1543
|
+
if (market['swap']) {
|
|
1544
|
+
throw new errors.NotSupported(this.id + ' fetchTickers does not support swap markets, please use fetchTicker instead');
|
|
1545
|
+
}
|
|
1546
|
+
else if (market['spot']) {
|
|
1547
|
+
response = await this.spotV1PublicGetTicker24hr(this.extend(request, params));
|
|
1548
|
+
data = response;
|
|
1549
|
+
}
|
|
1550
|
+
else {
|
|
1551
|
+
throw new errors.NotSupported(this.id + ' fetchTickers only support spot & swap markets');
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
else {
|
|
1555
|
+
[type, params] = this.handleMarketTypeAndParams('fetchTickers', undefined, params);
|
|
1556
|
+
if (type !== 'spot') {
|
|
1557
|
+
throw new errors.NotSupported(this.id + ' fetchTickers only support spot when symbols are not proved');
|
|
1558
|
+
}
|
|
1559
|
+
response = await this.spotV1PublicGetTicker24hr(this.extend(request, params));
|
|
1560
|
+
data = response;
|
|
1561
|
+
}
|
|
1562
|
+
//
|
|
1563
|
+
// spot
|
|
1564
|
+
//
|
|
1565
|
+
// [{
|
|
1566
|
+
// symbol: 'BTCUSDT',
|
|
1567
|
+
// priceChange: '105.20',
|
|
1568
|
+
// priceChangePercent: '0.3000',
|
|
1569
|
+
// weightedAvgPrice: null,
|
|
1570
|
+
// prevClosePrice: null,
|
|
1571
|
+
// lastPrice: '34905.21',
|
|
1572
|
+
// lastQty: null,
|
|
1573
|
+
// bidPrice: '34905.21',
|
|
1574
|
+
// askPrice: '34905.22',
|
|
1575
|
+
// openPrice: '34800.01',
|
|
1576
|
+
// highPrice: '35276.33',
|
|
1577
|
+
// lowPrice: '34787.51',
|
|
1578
|
+
// volume: '12549.6481',
|
|
1579
|
+
// quoteVolume: '439390492.917',
|
|
1580
|
+
// openTime: '0',
|
|
1581
|
+
// closeTime: '0',
|
|
1582
|
+
// firstId: '0',
|
|
1583
|
+
// lastId: '0',
|
|
1584
|
+
// count: '0'
|
|
1585
|
+
// }]
|
|
1586
|
+
//
|
|
1587
|
+
// swap
|
|
1588
|
+
//
|
|
1589
|
+
// {
|
|
1590
|
+
// "high": "35296",
|
|
1591
|
+
// "vol": "779308354",
|
|
1592
|
+
// "last": "34884.1",
|
|
1593
|
+
// "low": "34806.7",
|
|
1594
|
+
// "buy": 34883.9,
|
|
1595
|
+
// "sell": 34884,
|
|
1596
|
+
// "rose": "-0.0027957315",
|
|
1597
|
+
// "time": 1699348013000
|
|
1598
|
+
// }
|
|
1599
|
+
//
|
|
1600
|
+
// the exchange returns market ids with an underscore from the tickers endpoint
|
|
1601
|
+
// the market ids do not have an underscore, so it has to be removed
|
|
1602
|
+
// https://github.com/ccxt/ccxt/issues/13856
|
|
1603
|
+
const tickers = {};
|
|
1604
|
+
for (let i = 0; i < data.length; i++) {
|
|
1605
|
+
const ticker = this.safeValue(data, i, {});
|
|
1606
|
+
const market = this.market(this.safeValue(ticker, 'symbol'));
|
|
1607
|
+
tickers[market['id']] = ticker;
|
|
1608
|
+
}
|
|
1609
|
+
return this.parseTickers(tickers, symbols);
|
|
1610
|
+
}
|
|
1611
|
+
parseTrade(trade, market = undefined) {
|
|
1612
|
+
//
|
|
1613
|
+
// fetchTrades
|
|
1614
|
+
//
|
|
1615
|
+
// {
|
|
1616
|
+
// "id": 28457,
|
|
1617
|
+
// "price": "4.00000100",
|
|
1618
|
+
// "qty": "12.00000000",
|
|
1619
|
+
// "time": 1499865549590, // Actual timestamp of trade
|
|
1620
|
+
// "isBuyerMaker": true,
|
|
1621
|
+
// "isBestMatch": true
|
|
1622
|
+
// }
|
|
1623
|
+
//
|
|
1624
|
+
// fetchTrades - spot
|
|
1625
|
+
//
|
|
1626
|
+
// {
|
|
1627
|
+
// "symbol":"USDCUSDT",
|
|
1628
|
+
// "id":20725156,
|
|
1629
|
+
// "orderId":2880918576,
|
|
1630
|
+
// "origClientOrderId":null,
|
|
1631
|
+
// "price":"0.9996000000000000",
|
|
1632
|
+
// "qty":"100.0000000000000000",
|
|
1633
|
+
// "commission":null,
|
|
1634
|
+
// "commissionAssert":null,
|
|
1635
|
+
// "time":1635558511000,
|
|
1636
|
+
// "isBuyer":false,
|
|
1637
|
+
// "isMaker":false,
|
|
1638
|
+
// "isBestMatch":true
|
|
1639
|
+
// }
|
|
1640
|
+
//
|
|
1641
|
+
// fetchTrades - future
|
|
1642
|
+
//
|
|
1643
|
+
// {
|
|
1644
|
+
// "tradeId":12,
|
|
1645
|
+
// "price":0.9,
|
|
1646
|
+
// "qty":1,
|
|
1647
|
+
// "amount":9,
|
|
1648
|
+
// "contractName":"E-SAND-USDT",
|
|
1649
|
+
// "side":"BUY",
|
|
1650
|
+
// "fee":"0.0018",
|
|
1651
|
+
// "bidId":1558124009467904992,
|
|
1652
|
+
// "askId":1558124043827644908,
|
|
1653
|
+
// "bidUserId":10294,
|
|
1654
|
+
// "askUserId":10467,
|
|
1655
|
+
// "isBuyer":true,
|
|
1656
|
+
// "isMaker":true,
|
|
1657
|
+
// "ctime":1678426306000
|
|
1658
|
+
// }
|
|
1659
|
+
//
|
|
1660
|
+
const timestamp = this.safeInteger2(trade, 'ctime', 'time');
|
|
1661
|
+
const priceString = this.safeString(trade, 'price');
|
|
1662
|
+
const amountString = this.safeString(trade, 'qty');
|
|
1663
|
+
const marketId = this.safeString2(trade, 'symbol', 'contractName');
|
|
1664
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1665
|
+
const orderId = this.safeString(trade, 'orderId');
|
|
1666
|
+
const id = this.safeString2(trade, 'id', 'tradeId');
|
|
1667
|
+
let side = undefined;
|
|
1668
|
+
const buyerMaker = this.safeValue(trade, 'isBuyerMaker'); // ignore "m" until Bitrue fixes api
|
|
1669
|
+
const isBuyer = this.safeValue(trade, 'isBuyer');
|
|
1670
|
+
if (buyerMaker !== undefined) {
|
|
1671
|
+
side = buyerMaker ? 'sell' : 'buy';
|
|
1672
|
+
}
|
|
1673
|
+
if (isBuyer !== undefined) {
|
|
1674
|
+
side = isBuyer ? 'buy' : 'sell'; // this is a true side
|
|
1675
|
+
}
|
|
1676
|
+
let fee = undefined;
|
|
1677
|
+
if ('commission' in trade) {
|
|
1678
|
+
fee = {
|
|
1679
|
+
'cost': this.safeString2(trade, 'commission', 'fee'),
|
|
1680
|
+
'currency': this.safeCurrencyCode(this.safeString(trade, 'commissionAssert')),
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
let takerOrMaker = undefined;
|
|
1684
|
+
const isMaker = this.safeValue(trade, 'isMaker');
|
|
1685
|
+
if (isMaker !== undefined) {
|
|
1686
|
+
takerOrMaker = isMaker ? 'maker' : 'taker';
|
|
1687
|
+
}
|
|
1688
|
+
return this.safeTrade({
|
|
1689
|
+
'info': trade,
|
|
1690
|
+
'timestamp': timestamp,
|
|
1691
|
+
'datetime': this.iso8601(timestamp),
|
|
1692
|
+
'symbol': symbol,
|
|
1693
|
+
'id': id,
|
|
1694
|
+
'order': orderId,
|
|
1695
|
+
'type': undefined,
|
|
1696
|
+
'side': side,
|
|
1697
|
+
'takerOrMaker': takerOrMaker,
|
|
1698
|
+
'price': priceString,
|
|
1699
|
+
'amount': amountString,
|
|
1700
|
+
'cost': undefined,
|
|
1701
|
+
'fee': fee,
|
|
1702
|
+
}, market);
|
|
1703
|
+
}
|
|
1704
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1705
|
+
/**
|
|
1706
|
+
* @method
|
|
1707
|
+
* @name bitrue#fetchTrades
|
|
1708
|
+
* @description get the list of most recent trades for a particular symbol
|
|
1709
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#recent-trades-list
|
|
1710
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1711
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1712
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1713
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1714
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1715
|
+
*/
|
|
1716
|
+
await this.loadMarkets();
|
|
1717
|
+
const market = this.market(symbol);
|
|
1718
|
+
let response = undefined;
|
|
1719
|
+
if (market['spot']) {
|
|
1720
|
+
const request = {
|
|
1721
|
+
'symbol': market['id'],
|
|
1722
|
+
// 'limit': 100, // default 100, max = 1000
|
|
1723
|
+
};
|
|
1724
|
+
if (limit !== undefined) {
|
|
1725
|
+
request['limit'] = limit; // default 100, max 1000
|
|
1726
|
+
}
|
|
1727
|
+
response = await this.spotV1PublicGetTrades(this.extend(request, params));
|
|
1728
|
+
}
|
|
1729
|
+
else {
|
|
1730
|
+
throw new errors.NotSupported(this.id + ' fetchTrades only support spot markets');
|
|
1731
|
+
}
|
|
1732
|
+
//
|
|
1733
|
+
// spot
|
|
1734
|
+
//
|
|
1735
|
+
// [
|
|
1736
|
+
// {
|
|
1737
|
+
// "id": 28457,
|
|
1738
|
+
// "price": "4.00000100",
|
|
1739
|
+
// "qty": "12.00000000",
|
|
1740
|
+
// "time": 1499865549590,
|
|
1741
|
+
// "isBuyerMaker": true,
|
|
1742
|
+
// "isBestMatch": true
|
|
1743
|
+
// }
|
|
1744
|
+
// ]
|
|
1745
|
+
//
|
|
1746
|
+
return this.parseTrades(response, market, since, limit);
|
|
1747
|
+
}
|
|
1748
|
+
parseOrderStatus(status) {
|
|
1749
|
+
const statuses = {
|
|
1750
|
+
'INIT': 'open',
|
|
1751
|
+
'PENDING_CREATE': 'open',
|
|
1752
|
+
'NEW': 'open',
|
|
1753
|
+
'PARTIALLY_FILLED': 'open',
|
|
1754
|
+
'FILLED': 'closed',
|
|
1755
|
+
'CANCELED': 'canceled',
|
|
1756
|
+
'PENDING_CANCEL': 'canceling',
|
|
1757
|
+
'REJECTED': 'rejected',
|
|
1758
|
+
'EXPIRED': 'expired',
|
|
1759
|
+
};
|
|
1760
|
+
return this.safeString(statuses, status, status);
|
|
1761
|
+
}
|
|
1762
|
+
parseOrder(order, market = undefined) {
|
|
1763
|
+
//
|
|
1764
|
+
// createOrder - spot
|
|
1765
|
+
//
|
|
1766
|
+
// {
|
|
1767
|
+
// "symbol":"USDCUSDT",
|
|
1768
|
+
// "orderId":2878854881,
|
|
1769
|
+
// "clientOrderId":"",
|
|
1770
|
+
// "transactTime":1635551031276
|
|
1771
|
+
// }
|
|
1772
|
+
//
|
|
1773
|
+
// createOrder - future
|
|
1774
|
+
//
|
|
1775
|
+
// {
|
|
1776
|
+
// "orderId":1690615676032452985,
|
|
1777
|
+
// }
|
|
1778
|
+
//
|
|
1779
|
+
// fetchOrders - spot
|
|
1780
|
+
//
|
|
1781
|
+
// {
|
|
1782
|
+
// "symbol":"USDCUSDT",
|
|
1783
|
+
// "orderId":"2878854881",
|
|
1784
|
+
// "clientOrderId":"",
|
|
1785
|
+
// "price":"1.1000000000000000",
|
|
1786
|
+
// "origQty":"100.0000000000000000",
|
|
1787
|
+
// "executedQty":"0.0000000000000000",
|
|
1788
|
+
// "cummulativeQuoteQty":"0.0000000000000000",
|
|
1789
|
+
// "status":"NEW",
|
|
1790
|
+
// "timeInForce":"",
|
|
1791
|
+
// "type":"LIMIT",
|
|
1792
|
+
// "side":"SELL",
|
|
1793
|
+
// "stopPrice":"",
|
|
1794
|
+
// "icebergQty":"",
|
|
1795
|
+
// "time":1635551031000,
|
|
1796
|
+
// "updateTime":1635551031000,
|
|
1797
|
+
// "isWorking":false
|
|
1798
|
+
// }
|
|
1799
|
+
//
|
|
1800
|
+
// fetchOrders - future
|
|
1801
|
+
//
|
|
1802
|
+
// {
|
|
1803
|
+
// "orderId":1917641,
|
|
1804
|
+
// "price":100,
|
|
1805
|
+
// "origQty":10,
|
|
1806
|
+
// "origAmount":10,
|
|
1807
|
+
// "executedQty":1,
|
|
1808
|
+
// "avgPrice":10000,
|
|
1809
|
+
// "status":"INIT",
|
|
1810
|
+
// "type":"LIMIT",
|
|
1811
|
+
// "side":"BUY",
|
|
1812
|
+
// "action":"OPEN",
|
|
1813
|
+
// "transactTime":1686716571425
|
|
1814
|
+
// "clientOrderId":4949299210
|
|
1815
|
+
// }
|
|
1816
|
+
//
|
|
1817
|
+
const status = this.parseOrderStatus(this.safeString2(order, 'status', 'orderStatus'));
|
|
1818
|
+
const marketId = this.safeString(order, 'symbol');
|
|
1819
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1820
|
+
const filled = this.safeString(order, 'executedQty');
|
|
1821
|
+
let timestamp = undefined;
|
|
1822
|
+
let lastTradeTimestamp = undefined;
|
|
1823
|
+
if ('time' in order) {
|
|
1824
|
+
timestamp = this.safeInteger(order, 'time');
|
|
1825
|
+
}
|
|
1826
|
+
else if ('transactTime' in order) {
|
|
1827
|
+
timestamp = this.safeInteger(order, 'transactTime');
|
|
1828
|
+
}
|
|
1829
|
+
else if ('updateTime' in order) {
|
|
1830
|
+
if (status === 'open') {
|
|
1831
|
+
if (Precise["default"].stringGt(filled, '0')) {
|
|
1832
|
+
lastTradeTimestamp = this.safeInteger(order, 'updateTime');
|
|
1833
|
+
}
|
|
1834
|
+
else {
|
|
1835
|
+
timestamp = this.safeInteger(order, 'updateTime');
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
const average = this.safeString(order, 'avgPrice');
|
|
1840
|
+
const price = this.safeString(order, 'price');
|
|
1841
|
+
const amount = this.safeString(order, 'origQty');
|
|
1842
|
+
// - Spot/Margin market: cummulativeQuoteQty
|
|
1843
|
+
// - Futures market: cumQuote.
|
|
1844
|
+
// Note this is not the actual cost, since Binance futures uses leverage to calculate margins.
|
|
1845
|
+
const cost = this.safeString2(order, 'cummulativeQuoteQty', 'cumQuote');
|
|
1846
|
+
const id = this.safeString(order, 'orderId');
|
|
1847
|
+
let type = this.safeStringLower(order, 'type');
|
|
1848
|
+
const side = this.safeStringLower(order, 'side');
|
|
1849
|
+
const fills = this.safeValue(order, 'fills', []);
|
|
1850
|
+
const clientOrderId = this.safeString(order, 'clientOrderId');
|
|
1851
|
+
const timeInForce = this.safeString(order, 'timeInForce');
|
|
1852
|
+
const postOnly = (type === 'limit_maker') || (timeInForce === 'GTX') || (type === 'post_only');
|
|
1853
|
+
if (type === 'limit_maker') {
|
|
1854
|
+
type = 'limit';
|
|
1855
|
+
}
|
|
1856
|
+
const stopPriceString = this.safeString(order, 'stopPrice');
|
|
1857
|
+
const stopPrice = this.parseNumber(this.omitZero(stopPriceString));
|
|
1858
|
+
return this.safeOrder({
|
|
1859
|
+
'info': order,
|
|
1860
|
+
'id': id,
|
|
1861
|
+
'clientOrderId': clientOrderId,
|
|
1862
|
+
'timestamp': timestamp,
|
|
1863
|
+
'datetime': this.iso8601(timestamp),
|
|
1864
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
|
1865
|
+
'symbol': symbol,
|
|
1866
|
+
'type': type,
|
|
1867
|
+
'timeInForce': timeInForce,
|
|
1868
|
+
'postOnly': postOnly,
|
|
1869
|
+
'side': side,
|
|
1870
|
+
'price': price,
|
|
1871
|
+
'stopPrice': stopPrice,
|
|
1872
|
+
'triggerPrice': stopPrice,
|
|
1873
|
+
'amount': amount,
|
|
1874
|
+
'cost': cost,
|
|
1875
|
+
'average': average,
|
|
1876
|
+
'filled': filled,
|
|
1877
|
+
'remaining': undefined,
|
|
1878
|
+
'status': status,
|
|
1879
|
+
'fee': undefined,
|
|
1880
|
+
'trades': fills,
|
|
1881
|
+
}, market);
|
|
1882
|
+
}
|
|
1883
|
+
async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
|
|
1884
|
+
/**
|
|
1885
|
+
* @method
|
|
1886
|
+
* @name bitrue#createMarketBuyOrderWithCost
|
|
1887
|
+
* @description create a market buy order by providing the symbol and cost
|
|
1888
|
+
* @see https://www.bitrue.com/api-docs#new-order-trade-hmac-sha256
|
|
1889
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#new-order-trade-hmac-sha256
|
|
1890
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1891
|
+
* @param {float} cost how much you want to trade in units of the quote currency
|
|
1892
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1893
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1894
|
+
*/
|
|
1895
|
+
await this.loadMarkets();
|
|
1896
|
+
const market = this.market(symbol);
|
|
1897
|
+
if (!market['swap']) {
|
|
1898
|
+
throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports swap orders only');
|
|
1899
|
+
}
|
|
1900
|
+
params['createMarketBuyOrderRequiresPrice'] = false;
|
|
1901
|
+
return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
|
|
1902
|
+
}
|
|
1903
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1904
|
+
/**
|
|
1905
|
+
* @method
|
|
1906
|
+
* @name bitrue#createOrder
|
|
1907
|
+
* @description create a trade order
|
|
1908
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#recent-trades-list
|
|
1909
|
+
* @see https://www.bitrue.com/api-docs#new-order-trade-hmac-sha256
|
|
1910
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#new-order-trade-hmac-sha256
|
|
1911
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1912
|
+
* @param {string} type 'market' or 'limit'
|
|
1913
|
+
* @param {string} side 'buy' or 'sell'
|
|
1914
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1915
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1916
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1917
|
+
* @param {float} [params.triggerPrice] *spot only* the price at which a trigger order is triggered at
|
|
1918
|
+
* @param {string} [params.clientOrderId] a unique id for the order, automatically generated if not sent
|
|
1919
|
+
* @param {decimal} [params.leverage] in future order, the leverage value of the order should consistent with the user contract configuration, default is 1
|
|
1920
|
+
* @param {string} [params.timeInForce] 'fok', 'ioc' or 'po'
|
|
1921
|
+
* @param {bool} [params.postOnly] default false
|
|
1922
|
+
* @param {bool} [params.reduceOnly] default false
|
|
1923
|
+
* EXCHANGE SPECIFIC PARAMETERS
|
|
1924
|
+
* @param {decimal} [params.icebergQty]
|
|
1925
|
+
* @param {long} [params.recvWindow]
|
|
1926
|
+
* @param {float} [params.cost] *swap market buy only* the quote quantity that can be used as an alternative for the amount
|
|
1927
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1928
|
+
*/
|
|
1929
|
+
await this.loadMarkets();
|
|
1930
|
+
const market = this.market(symbol);
|
|
1931
|
+
let response = undefined;
|
|
1932
|
+
let data = undefined;
|
|
1933
|
+
const uppercaseType = type.toUpperCase();
|
|
1934
|
+
const request = {
|
|
1935
|
+
'side': side.toUpperCase(),
|
|
1936
|
+
'type': uppercaseType,
|
|
1937
|
+
// 'timeInForce': '',
|
|
1938
|
+
// 'price': this.priceToPrecision (symbol, price),
|
|
1939
|
+
// 'newClientOrderId': clientOrderId, // automatically generated if not sent
|
|
1940
|
+
// 'stopPrice': this.priceToPrecision (symbol, 'stopPrice'),
|
|
1941
|
+
// 'icebergQty': this.amountToPrecision (symbol, icebergQty),
|
|
1942
|
+
};
|
|
1943
|
+
if (uppercaseType === 'LIMIT') {
|
|
1944
|
+
if (price === undefined) {
|
|
1945
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a price argument');
|
|
1946
|
+
}
|
|
1947
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
1948
|
+
}
|
|
1949
|
+
if (market['swap']) {
|
|
1950
|
+
const isMarket = uppercaseType === 'MARKET';
|
|
1951
|
+
const timeInForce = this.safeStringLower(params, 'timeInForce');
|
|
1952
|
+
const postOnly = this.isPostOnly(isMarket, undefined, params);
|
|
1953
|
+
if (postOnly) {
|
|
1954
|
+
request['type'] = 'POST_ONLY';
|
|
1955
|
+
}
|
|
1956
|
+
else if (timeInForce === 'fok') {
|
|
1957
|
+
request['type'] = 'FOK';
|
|
1958
|
+
}
|
|
1959
|
+
else if (timeInForce === 'ioc') {
|
|
1960
|
+
request['type'] = 'IOC';
|
|
1961
|
+
}
|
|
1962
|
+
request['contractName'] = market['id'];
|
|
1963
|
+
let createMarketBuyOrderRequiresPrice = true;
|
|
1964
|
+
[createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
|
|
1965
|
+
if (isMarket && (side === 'buy') && createMarketBuyOrderRequiresPrice) {
|
|
1966
|
+
const cost = this.safeString(params, 'cost');
|
|
1967
|
+
params = this.omit(params, 'cost');
|
|
1968
|
+
if (price === undefined && cost === undefined) {
|
|
1969
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires the price argument with swap market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options["createMarketBuyOrderRequiresPrice"] = false to supply the cost in the amount argument (the exchange-specific behaviour)');
|
|
1970
|
+
}
|
|
1971
|
+
else {
|
|
1972
|
+
const amountString = this.numberToString(amount);
|
|
1973
|
+
const priceString = this.numberToString(price);
|
|
1974
|
+
const quoteAmount = Precise["default"].stringMul(amountString, priceString);
|
|
1975
|
+
amount = (cost !== undefined) ? cost : quoteAmount;
|
|
1976
|
+
request['amount'] = this.costToPrecision(symbol, amount);
|
|
1977
|
+
request['volume'] = this.costToPrecision(symbol, amount);
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
else {
|
|
1981
|
+
request['amount'] = this.parseToNumeric(amount);
|
|
1982
|
+
request['volume'] = this.parseToNumeric(amount);
|
|
1983
|
+
}
|
|
1984
|
+
request['positionType'] = 1;
|
|
1985
|
+
const reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
|
|
1986
|
+
request['open'] = reduceOnly ? 'CLOSE' : 'OPEN';
|
|
1987
|
+
const leverage = this.safeString(params, 'leverage', '1');
|
|
1988
|
+
request['leverage'] = this.parseToNumeric(leverage);
|
|
1989
|
+
params = this.omit(params, ['leverage', 'reduceOnly', 'reduce_only', 'timeInForce']);
|
|
1990
|
+
if (market['linear']) {
|
|
1991
|
+
response = await this.fapiV2PrivatePostOrder(this.extend(request, params));
|
|
1992
|
+
}
|
|
1993
|
+
else if (market['inverse']) {
|
|
1994
|
+
response = await this.dapiV2PrivatePostOrder(this.extend(request, params));
|
|
1995
|
+
}
|
|
1996
|
+
data = this.safeValue(response, 'data', {});
|
|
1997
|
+
}
|
|
1998
|
+
else if (market['spot']) {
|
|
1999
|
+
request['symbol'] = market['id'];
|
|
2000
|
+
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
2001
|
+
const validOrderTypes = this.safeValue(market['info'], 'orderTypes');
|
|
2002
|
+
if (!this.inArray(uppercaseType, validOrderTypes)) {
|
|
2003
|
+
throw new errors.InvalidOrder(this.id + ' ' + type + ' is not a valid order type in market ' + symbol);
|
|
2004
|
+
}
|
|
2005
|
+
const clientOrderId = this.safeString2(params, 'newClientOrderId', 'clientOrderId');
|
|
2006
|
+
if (clientOrderId !== undefined) {
|
|
2007
|
+
params = this.omit(params, ['newClientOrderId', 'clientOrderId']);
|
|
2008
|
+
request['newClientOrderId'] = clientOrderId;
|
|
2009
|
+
}
|
|
2010
|
+
const stopPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
|
|
2011
|
+
if (stopPrice !== undefined) {
|
|
2012
|
+
params = this.omit(params, ['triggerPrice', 'stopPrice']);
|
|
2013
|
+
request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
|
|
2014
|
+
}
|
|
2015
|
+
response = await this.spotV1PrivatePostOrder(this.extend(request, params));
|
|
2016
|
+
data = response;
|
|
2017
|
+
}
|
|
2018
|
+
else {
|
|
2019
|
+
throw new errors.NotSupported(this.id + ' createOrder only support spot & swap markets');
|
|
2020
|
+
}
|
|
2021
|
+
//
|
|
2022
|
+
// spot
|
|
2023
|
+
//
|
|
2024
|
+
// {
|
|
2025
|
+
// "symbol": "BTCUSDT",
|
|
2026
|
+
// "orderId": 307650651173648896,
|
|
2027
|
+
// "orderIdStr": "307650651173648896",
|
|
2028
|
+
// "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
|
|
2029
|
+
// "transactTime": 1507725176595
|
|
2030
|
+
// }
|
|
2031
|
+
//
|
|
2032
|
+
// swap
|
|
2033
|
+
//
|
|
2034
|
+
// {
|
|
2035
|
+
// "code": "0",
|
|
2036
|
+
// "msg": "Success",
|
|
2037
|
+
// "data": {
|
|
2038
|
+
// "orderId": 1690615676032452985
|
|
2039
|
+
// }
|
|
2040
|
+
// }
|
|
2041
|
+
//
|
|
2042
|
+
return this.parseOrder(data, market);
|
|
2043
|
+
}
|
|
2044
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
2045
|
+
/**
|
|
2046
|
+
* @method
|
|
2047
|
+
* @name bitrue#fetchOrder
|
|
2048
|
+
* @description fetches information on an order made by the user
|
|
2049
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#query-order-user_data
|
|
2050
|
+
* @see https://www.bitrue.com/api-docs#query-order-user_data-hmac-sha256
|
|
2051
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#query-order-user_data-hmac-sha256
|
|
2052
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
2053
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2054
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2055
|
+
*/
|
|
2056
|
+
if (symbol === undefined) {
|
|
2057
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
|
|
2058
|
+
}
|
|
2059
|
+
await this.loadMarkets();
|
|
2060
|
+
const market = this.market(symbol);
|
|
2061
|
+
const origClientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
|
|
2062
|
+
params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
|
|
2063
|
+
let response = undefined;
|
|
2064
|
+
let data = undefined;
|
|
2065
|
+
const request = {};
|
|
2066
|
+
if (origClientOrderId === undefined) {
|
|
2067
|
+
request['orderId'] = id;
|
|
2068
|
+
}
|
|
2069
|
+
else {
|
|
2070
|
+
if (market['swap']) {
|
|
2071
|
+
request['clientOrderId'] = origClientOrderId;
|
|
2072
|
+
}
|
|
2073
|
+
else {
|
|
2074
|
+
request['origClientOrderId'] = origClientOrderId;
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
if (market['swap']) {
|
|
2078
|
+
request['contractName'] = market['id'];
|
|
2079
|
+
if (market['linear']) {
|
|
2080
|
+
response = await this.fapiV2PrivateGetOrder(this.extend(request, params));
|
|
2081
|
+
}
|
|
2082
|
+
else if (market['inverse']) {
|
|
2083
|
+
response = await this.dapiV2PrivateGetOrder(this.extend(request, params));
|
|
2084
|
+
}
|
|
2085
|
+
data = this.safeValue(response, 'data', {});
|
|
2086
|
+
}
|
|
2087
|
+
else if (market['spot']) {
|
|
2088
|
+
request['orderId'] = id; // spot market id is mandatory
|
|
2089
|
+
request['symbol'] = market['id'];
|
|
2090
|
+
response = await this.spotV1PrivateGetOrder(this.extend(request, params));
|
|
2091
|
+
data = response;
|
|
2092
|
+
}
|
|
2093
|
+
else {
|
|
2094
|
+
throw new errors.NotSupported(this.id + ' fetchOrder only support spot & swap markets');
|
|
2095
|
+
}
|
|
2096
|
+
//
|
|
2097
|
+
// spot
|
|
2098
|
+
//
|
|
2099
|
+
// {
|
|
2100
|
+
// "symbol": "LTCBTC",
|
|
2101
|
+
// "orderId": 1,
|
|
2102
|
+
// "clientOrderId": "myOrder1",
|
|
2103
|
+
// "price": "0.1",
|
|
2104
|
+
// "origQty": "1.0",
|
|
2105
|
+
// "executedQty": "0.0",
|
|
2106
|
+
// "cummulativeQuoteQty": "0.0",
|
|
2107
|
+
// "status": "NEW",
|
|
2108
|
+
// "timeInForce": "GTC",
|
|
2109
|
+
// "type": "LIMIT",
|
|
2110
|
+
// "side": "BUY",
|
|
2111
|
+
// "stopPrice": "0.0",
|
|
2112
|
+
// "icebergQty": "0.0",
|
|
2113
|
+
// "time": 1499827319559,
|
|
2114
|
+
// "updateTime": 1499827319559,
|
|
2115
|
+
// "isWorking": true
|
|
2116
|
+
// }
|
|
2117
|
+
//
|
|
2118
|
+
// swap
|
|
2119
|
+
//
|
|
2120
|
+
// {
|
|
2121
|
+
// "code":0,
|
|
2122
|
+
// "msg":"success",
|
|
2123
|
+
// "data":{
|
|
2124
|
+
// "orderId":1917641,
|
|
2125
|
+
// "price":100,
|
|
2126
|
+
// "origQty":10,
|
|
2127
|
+
// "origAmount":10,
|
|
2128
|
+
// "executedQty":1,
|
|
2129
|
+
// "avgPrice":10000,
|
|
2130
|
+
// "status":"INIT",
|
|
2131
|
+
// "type":"LIMIT",
|
|
2132
|
+
// "side":"BUY",
|
|
2133
|
+
// "action":"OPEN",
|
|
2134
|
+
// "transactTime":1686716571425
|
|
2135
|
+
// "clientOrderId":4949299210
|
|
2136
|
+
// }
|
|
2137
|
+
// }
|
|
2138
|
+
//
|
|
2139
|
+
return this.parseOrder(data, market);
|
|
2140
|
+
}
|
|
2141
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2142
|
+
/**
|
|
2143
|
+
* @method
|
|
2144
|
+
* @name bitrue#fetchClosedOrders
|
|
2145
|
+
* @description fetches information on multiple closed orders made by the user
|
|
2146
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#all-orders-user_data
|
|
2147
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
2148
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2149
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
2150
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2151
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2152
|
+
*/
|
|
2153
|
+
if (symbol === undefined) {
|
|
2154
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchClosedOrders() requires a symbol argument');
|
|
2155
|
+
}
|
|
2156
|
+
await this.loadMarkets();
|
|
2157
|
+
const market = this.market(symbol);
|
|
2158
|
+
if (!market['spot']) {
|
|
2159
|
+
throw new errors.NotSupported(this.id + ' fetchClosedOrders only support spot markets');
|
|
2160
|
+
}
|
|
2161
|
+
const request = {
|
|
2162
|
+
'symbol': market['id'],
|
|
2163
|
+
// 'orderId': 123445, // long
|
|
2164
|
+
// 'startTime': since,
|
|
2165
|
+
// 'endTime': this.milliseconds (),
|
|
2166
|
+
// 'limit': limit, // default 100, max 1000
|
|
2167
|
+
};
|
|
2168
|
+
if (since !== undefined) {
|
|
2169
|
+
request['startTime'] = since;
|
|
2170
|
+
}
|
|
2171
|
+
if (limit !== undefined) {
|
|
2172
|
+
request['limit'] = limit; // default 100, max 1000
|
|
2173
|
+
}
|
|
2174
|
+
const response = await this.spotV1PrivateGetAllOrders(this.extend(request, params));
|
|
2175
|
+
//
|
|
2176
|
+
// [
|
|
2177
|
+
// {
|
|
2178
|
+
// "symbol": "LTCBTC",
|
|
2179
|
+
// "orderId": 1,
|
|
2180
|
+
// "clientOrderId": "myOrder1",
|
|
2181
|
+
// "price": "0.1",
|
|
2182
|
+
// "origQty": "1.0",
|
|
2183
|
+
// "executedQty": "0.0",
|
|
2184
|
+
// "cummulativeQuoteQty": "0.0",
|
|
2185
|
+
// "status": "NEW",
|
|
2186
|
+
// "timeInForce": "GTC",
|
|
2187
|
+
// "type": "LIMIT",
|
|
2188
|
+
// "side": "BUY",
|
|
2189
|
+
// "stopPrice": "0.0",
|
|
2190
|
+
// "icebergQty": "0.0",
|
|
2191
|
+
// "time": 1499827319559,
|
|
2192
|
+
// "updateTime": 1499827319559,
|
|
2193
|
+
// "isWorking": true
|
|
2194
|
+
// }
|
|
2195
|
+
// ]
|
|
2196
|
+
//
|
|
2197
|
+
return this.parseOrders(response, market, since, limit);
|
|
2198
|
+
}
|
|
2199
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2200
|
+
/**
|
|
2201
|
+
* @method
|
|
2202
|
+
* @name bitrue#fetchOpenOrders
|
|
2203
|
+
* @description fetch all unfilled currently open orders
|
|
2204
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#current-open-orders-user_data
|
|
2205
|
+
* @see https://www.bitrue.com/api-docs#current-all-open-orders-user_data-hmac-sha256
|
|
2206
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#current-all-open-orders-user_data-hmac-sha256
|
|
2207
|
+
* @param {string} symbol unified market symbol
|
|
2208
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
2209
|
+
* @param {int} [limit] the maximum number of open order structures to retrieve
|
|
2210
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2211
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2212
|
+
*/
|
|
2213
|
+
if (symbol === undefined) {
|
|
2214
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchOpenOrders() requires a symbol argument');
|
|
2215
|
+
}
|
|
2216
|
+
await this.loadMarkets();
|
|
2217
|
+
const market = this.market(symbol);
|
|
2218
|
+
let response = undefined;
|
|
2219
|
+
let data = undefined;
|
|
2220
|
+
const request = {};
|
|
2221
|
+
if (market['swap']) {
|
|
2222
|
+
request['contractName'] = market['id'];
|
|
2223
|
+
if (market['linear']) {
|
|
2224
|
+
response = await this.fapiV2PrivateGetOpenOrders(this.extend(request, params));
|
|
2225
|
+
}
|
|
2226
|
+
else if (market['inverse']) {
|
|
2227
|
+
response = await this.dapiV2PrivateGetOpenOrders(this.extend(request, params));
|
|
2228
|
+
}
|
|
2229
|
+
data = this.safeValue(response, 'data', []);
|
|
2230
|
+
}
|
|
2231
|
+
else if (market['spot']) {
|
|
2232
|
+
request['symbol'] = market['id'];
|
|
2233
|
+
response = await this.spotV1PrivateGetOpenOrders(this.extend(request, params));
|
|
2234
|
+
data = response;
|
|
2235
|
+
}
|
|
2236
|
+
else {
|
|
2237
|
+
throw new errors.NotSupported(this.id + ' fetchOpenOrders only support spot & swap markets');
|
|
2238
|
+
}
|
|
2239
|
+
//
|
|
2240
|
+
// spot
|
|
2241
|
+
//
|
|
2242
|
+
// [
|
|
2243
|
+
// {
|
|
2244
|
+
// "symbol":"USDCUSDT",
|
|
2245
|
+
// "orderId":"2878854881",
|
|
2246
|
+
// "clientOrderId":"",
|
|
2247
|
+
// "price":"1.1000000000000000",
|
|
2248
|
+
// "origQty":"100.0000000000000000",
|
|
2249
|
+
// "executedQty":"0.0000000000000000",
|
|
2250
|
+
// "cummulativeQuoteQty":"0.0000000000000000",
|
|
2251
|
+
// "status":"NEW",
|
|
2252
|
+
// "timeInForce":"",
|
|
2253
|
+
// "type":"LIMIT",
|
|
2254
|
+
// "side":"SELL",
|
|
2255
|
+
// "stopPrice":"",
|
|
2256
|
+
// "icebergQty":"",
|
|
2257
|
+
// "time":1635551031000,
|
|
2258
|
+
// "updateTime":1635551031000,
|
|
2259
|
+
// "isWorking":false
|
|
2260
|
+
// }
|
|
2261
|
+
// ]
|
|
2262
|
+
//
|
|
2263
|
+
// swap
|
|
2264
|
+
//
|
|
2265
|
+
// {
|
|
2266
|
+
// "code": "0",
|
|
2267
|
+
// "msg": "Success",
|
|
2268
|
+
// "data": [{
|
|
2269
|
+
// "orderId": 1917641,
|
|
2270
|
+
// "clientOrderId": "2488514315",
|
|
2271
|
+
// "price": 100,
|
|
2272
|
+
// "origQty": 10,
|
|
2273
|
+
// "origAmount": 10,
|
|
2274
|
+
// "executedQty": 1,
|
|
2275
|
+
// "avgPrice": 12451,
|
|
2276
|
+
// "status": "INIT",
|
|
2277
|
+
// "type": "LIMIT",
|
|
2278
|
+
// "side": "BUY",
|
|
2279
|
+
// "action": "OPEN",
|
|
2280
|
+
// "transactTime": 1686717303975
|
|
2281
|
+
// }
|
|
2282
|
+
// ]
|
|
2283
|
+
// }
|
|
2284
|
+
//
|
|
2285
|
+
return this.parseOrders(data, market, since, limit);
|
|
2286
|
+
}
|
|
2287
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
2288
|
+
/**
|
|
2289
|
+
* @method
|
|
2290
|
+
* @name bitrue#cancelOrder
|
|
2291
|
+
* @description cancels an open order
|
|
2292
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#cancel-order-trade
|
|
2293
|
+
* @see https://www.bitrue.com/api-docs#cancel-order-trade-hmac-sha256
|
|
2294
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-order-trade-hmac-sha256
|
|
2295
|
+
* @param {string} id order id
|
|
2296
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
2297
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2298
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2299
|
+
*/
|
|
2300
|
+
if (symbol === undefined) {
|
|
2301
|
+
throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
|
|
2302
|
+
}
|
|
2303
|
+
await this.loadMarkets();
|
|
2304
|
+
const market = this.market(symbol);
|
|
2305
|
+
const origClientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
|
|
2306
|
+
params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
|
|
2307
|
+
let response = undefined;
|
|
2308
|
+
let data = undefined;
|
|
2309
|
+
const request = {};
|
|
2310
|
+
if (origClientOrderId === undefined) {
|
|
2311
|
+
request['orderId'] = id;
|
|
2312
|
+
}
|
|
2313
|
+
else {
|
|
2314
|
+
if (market['swap']) {
|
|
2315
|
+
request['clientOrderId'] = origClientOrderId;
|
|
2316
|
+
}
|
|
2317
|
+
else {
|
|
2318
|
+
request['origClientOrderId'] = origClientOrderId;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
if (market['swap']) {
|
|
2322
|
+
request['contractName'] = market['id'];
|
|
2323
|
+
if (market['linear']) {
|
|
2324
|
+
response = await this.fapiV2PrivatePostCancel(this.extend(request, params));
|
|
2325
|
+
}
|
|
2326
|
+
else if (market['inverse']) {
|
|
2327
|
+
response = await this.dapiV2PrivatePostCancel(this.extend(request, params));
|
|
2328
|
+
}
|
|
2329
|
+
data = this.safeValue(response, 'data', {});
|
|
2330
|
+
}
|
|
2331
|
+
else if (market['spot']) {
|
|
2332
|
+
request['symbol'] = market['id'];
|
|
2333
|
+
response = await this.spotV1PrivateDeleteOrder(this.extend(request, params));
|
|
2334
|
+
data = response;
|
|
2335
|
+
}
|
|
2336
|
+
else {
|
|
2337
|
+
throw new errors.NotSupported(this.id + ' cancelOrder only support spot & swap markets');
|
|
2338
|
+
}
|
|
2339
|
+
//
|
|
2340
|
+
// spot
|
|
2341
|
+
//
|
|
2342
|
+
// {
|
|
2343
|
+
// "symbol": "LTCBTC",
|
|
2344
|
+
// "origClientOrderId": "myOrder1",
|
|
2345
|
+
// "orderId": 1,
|
|
2346
|
+
// "clientOrderId": "cancelMyOrder1"
|
|
2347
|
+
// }
|
|
2348
|
+
//
|
|
2349
|
+
// swap
|
|
2350
|
+
//
|
|
2351
|
+
// {
|
|
2352
|
+
// "code": "0",
|
|
2353
|
+
// "msg": "Success",
|
|
2354
|
+
// "data": {
|
|
2355
|
+
// "orderId": 1690615847831143159
|
|
2356
|
+
// }
|
|
2357
|
+
// }
|
|
2358
|
+
//
|
|
2359
|
+
return this.parseOrder(data, market);
|
|
2360
|
+
}
|
|
2361
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
2362
|
+
/**
|
|
2363
|
+
* @method
|
|
2364
|
+
* @name bitrue#cancelAllOrders
|
|
2365
|
+
* @description cancel all open orders in a market
|
|
2366
|
+
* @see https://www.bitrue.com/api-docs#cancel-all-open-orders-trade-hmac-sha256
|
|
2367
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-all-open-orders-trade-hmac-sha256
|
|
2368
|
+
* @param {string} symbol unified market symbol of the market to cancel orders in
|
|
2369
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2370
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
|
|
2371
|
+
* @returns {object[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
|
|
2372
|
+
*/
|
|
2373
|
+
await this.loadMarkets();
|
|
2374
|
+
const market = this.market(symbol);
|
|
2375
|
+
let response = undefined;
|
|
2376
|
+
let data = undefined;
|
|
2377
|
+
if (market['swap']) {
|
|
2378
|
+
const request = {
|
|
2379
|
+
'contractName': market['id'],
|
|
2380
|
+
};
|
|
2381
|
+
if (market['linear']) {
|
|
2382
|
+
response = await this.fapiV2PrivatePostAllOpenOrders(this.extend(request, params));
|
|
2383
|
+
}
|
|
2384
|
+
else if (market['inverse']) {
|
|
2385
|
+
response = await this.dapiV2PrivatePostAllOpenOrders(this.extend(request, params));
|
|
2386
|
+
}
|
|
2387
|
+
data = this.safeValue(response, 'data', []);
|
|
2388
|
+
}
|
|
2389
|
+
else {
|
|
2390
|
+
throw new errors.NotSupported(this.id + ' cancelAllOrders only support future markets');
|
|
2391
|
+
}
|
|
2392
|
+
//
|
|
2393
|
+
// swap
|
|
2394
|
+
//
|
|
2395
|
+
// {
|
|
2396
|
+
// 'code': '0',
|
|
2397
|
+
// 'msg': 'Success',
|
|
2398
|
+
// 'data': null
|
|
2399
|
+
// }
|
|
2400
|
+
//
|
|
2401
|
+
return this.parseOrders(data, market);
|
|
2402
|
+
}
|
|
2403
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2404
|
+
/**
|
|
2405
|
+
* @method
|
|
2406
|
+
* @name bitrue#fetchMyTrades
|
|
2407
|
+
* @description fetch all trades made by the user
|
|
2408
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#account-trade-list-user_data
|
|
2409
|
+
* @see https://www.bitrue.com/api-docs#account-trade-list-user_data-hmac-sha256
|
|
2410
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#account-trade-list-user_data-hmac-sha256
|
|
2411
|
+
* @param {string} symbol unified market symbol
|
|
2412
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
2413
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
2414
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2415
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2416
|
+
*/
|
|
2417
|
+
await this.loadMarkets();
|
|
2418
|
+
if (symbol === undefined) {
|
|
2419
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
|
|
2420
|
+
}
|
|
2421
|
+
const market = this.market(symbol);
|
|
2422
|
+
let response = undefined;
|
|
2423
|
+
let data = undefined;
|
|
2424
|
+
const request = {};
|
|
2425
|
+
if (since !== undefined) {
|
|
2426
|
+
request['startTime'] = since;
|
|
2427
|
+
}
|
|
2428
|
+
if (limit !== undefined) {
|
|
2429
|
+
if (limit > 1000) {
|
|
2430
|
+
limit = 1000;
|
|
2431
|
+
}
|
|
2432
|
+
request['limit'] = limit;
|
|
2433
|
+
}
|
|
2434
|
+
if (market['swap']) {
|
|
2435
|
+
request['contractName'] = market['id'];
|
|
2436
|
+
if (market['linear']) {
|
|
2437
|
+
response = await this.fapiV2PrivateGetMyTrades(this.extend(request, params));
|
|
2438
|
+
}
|
|
2439
|
+
else if (market['inverse']) {
|
|
2440
|
+
response = await this.dapiV2PrivateGetMyTrades(this.extend(request, params));
|
|
2441
|
+
}
|
|
2442
|
+
data = this.safeValue(response, 'data', []);
|
|
2443
|
+
}
|
|
2444
|
+
else if (market['spot']) {
|
|
2445
|
+
request['symbol'] = market['id'];
|
|
2446
|
+
response = await this.spotV2PrivateGetMyTrades(this.extend(request, params));
|
|
2447
|
+
data = response;
|
|
2448
|
+
}
|
|
2449
|
+
else {
|
|
2450
|
+
throw new errors.NotSupported(this.id + ' fetchMyTrades only support spot & swap markets');
|
|
2451
|
+
}
|
|
2452
|
+
//
|
|
2453
|
+
// spot
|
|
2454
|
+
//
|
|
2455
|
+
// [
|
|
2456
|
+
// {
|
|
2457
|
+
// "symbol":"USDCUSDT",
|
|
2458
|
+
// "id":20725156,
|
|
2459
|
+
// "orderId":2880918576,
|
|
2460
|
+
// "origClientOrderId":null,
|
|
2461
|
+
// "price":"0.9996000000000000",
|
|
2462
|
+
// "qty":"100.0000000000000000",
|
|
2463
|
+
// "commission":null,
|
|
2464
|
+
// "commissionAssert":null,
|
|
2465
|
+
// "time":1635558511000,
|
|
2466
|
+
// "isBuyer":false,
|
|
2467
|
+
// "isMaker":false,
|
|
2468
|
+
// "isBestMatch":true
|
|
2469
|
+
// }
|
|
2470
|
+
// ]
|
|
2471
|
+
//
|
|
2472
|
+
// swap
|
|
2473
|
+
//
|
|
2474
|
+
// {
|
|
2475
|
+
// "code":"0",
|
|
2476
|
+
// "msg":"Success",
|
|
2477
|
+
// "data":[
|
|
2478
|
+
// {
|
|
2479
|
+
// "tradeId":12,
|
|
2480
|
+
// "price":0.9,
|
|
2481
|
+
// "qty":1,
|
|
2482
|
+
// "amount":9,
|
|
2483
|
+
// "contractName":"E-SAND-USDT",
|
|
2484
|
+
// "side":"BUY",
|
|
2485
|
+
// "fee":"0.0018",
|
|
2486
|
+
// "bidId":1558124009467904992,
|
|
2487
|
+
// "askId":1558124043827644908,
|
|
2488
|
+
// "bidUserId":10294,
|
|
2489
|
+
// "askUserId":10467,
|
|
2490
|
+
// "isBuyer":true,
|
|
2491
|
+
// "isMaker":true,
|
|
2492
|
+
// "ctime":1678426306000
|
|
2493
|
+
// }
|
|
2494
|
+
// ]
|
|
2495
|
+
// }
|
|
2496
|
+
//
|
|
2497
|
+
return this.parseTrades(data, market, since, limit);
|
|
2498
|
+
}
|
|
2499
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2500
|
+
/**
|
|
2501
|
+
* @method
|
|
2502
|
+
* @name bitrue#fetchDeposits
|
|
2503
|
+
* @description fetch all deposits made to an account
|
|
2504
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#deposit-history--withdraw_data
|
|
2505
|
+
* @param {string} code unified currency code
|
|
2506
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
2507
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
2508
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2509
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2510
|
+
*/
|
|
2511
|
+
if (code === undefined) {
|
|
2512
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchDeposits() requires a code argument');
|
|
2513
|
+
}
|
|
2514
|
+
await this.loadMarkets();
|
|
2515
|
+
const currency = this.currency(code);
|
|
2516
|
+
const request = {
|
|
2517
|
+
'coin': currency['id'],
|
|
2518
|
+
'status': 1, // 0 init, 1 finished, default 0
|
|
2519
|
+
// 'offset': 0,
|
|
2520
|
+
// 'limit': limit, // default 10, max 1000
|
|
2521
|
+
// 'startTime': since,
|
|
2522
|
+
// 'endTime': this.milliseconds (),
|
|
2523
|
+
};
|
|
2524
|
+
if (since !== undefined) {
|
|
2525
|
+
request['startTime'] = since;
|
|
2526
|
+
// request['endTime'] = this.sum (since, 7776000000);
|
|
2527
|
+
}
|
|
2528
|
+
if (limit !== undefined) {
|
|
2529
|
+
request['limit'] = limit;
|
|
2530
|
+
}
|
|
2531
|
+
const response = await this.spotV1PrivateGetDepositHistory(this.extend(request, params));
|
|
2532
|
+
//
|
|
2533
|
+
// {
|
|
2534
|
+
// "code":200,
|
|
2535
|
+
// "msg":"succ",
|
|
2536
|
+
// "data":[
|
|
2537
|
+
// {
|
|
2538
|
+
// "id":2659137,
|
|
2539
|
+
// "symbol":"USDC",
|
|
2540
|
+
// "amount":"200.0000000000000000",
|
|
2541
|
+
// "fee":"0.0E-15",
|
|
2542
|
+
// "createdAt":1635503169000,
|
|
2543
|
+
// "updatedAt":1635503202000,
|
|
2544
|
+
// "addressFrom":"0x2faf487a4414fe77e2327f0bf4ae2a264a776ad2",
|
|
2545
|
+
// "addressTo":"0x190ceccb1f8bfbec1749180f0ba8922b488d865b",
|
|
2546
|
+
// "txid":"0x9970aec41099ac385568859517308707bc7d716df8dabae7b52f5b17351c3ed0",
|
|
2547
|
+
// "confirmations":5,
|
|
2548
|
+
// "status":0,
|
|
2549
|
+
// "tagType":null,
|
|
2550
|
+
// },
|
|
2551
|
+
// {
|
|
2552
|
+
// "id":2659137,
|
|
2553
|
+
// "symbol": "XRP",
|
|
2554
|
+
// "amount": "20.0000000000000000",
|
|
2555
|
+
// "fee": "0.0E-15",
|
|
2556
|
+
// "createdAt": 1544669393000,
|
|
2557
|
+
// "updatedAt": 1544669413000,
|
|
2558
|
+
// "addressFrom": "",
|
|
2559
|
+
// "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
|
|
2560
|
+
// "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC",
|
|
2561
|
+
// "confirmations": 7,
|
|
2562
|
+
// "status": 1,
|
|
2563
|
+
// "tagType": "Tag"
|
|
2564
|
+
// }
|
|
2565
|
+
// ]
|
|
2566
|
+
// }
|
|
2567
|
+
//
|
|
2568
|
+
const data = this.safeValue(response, 'data', []);
|
|
2569
|
+
return this.parseTransactions(data, currency, since, limit);
|
|
2570
|
+
}
|
|
2571
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2572
|
+
/**
|
|
2573
|
+
* @method
|
|
2574
|
+
* @name bitrue#fetchWithdrawals
|
|
2575
|
+
* @description fetch all withdrawals made from an account
|
|
2576
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-history--withdraw_data
|
|
2577
|
+
* @param {string} code unified currency code
|
|
2578
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
2579
|
+
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
2580
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2581
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2582
|
+
*/
|
|
2583
|
+
if (code === undefined) {
|
|
2584
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchWithdrawals() requires a code argument');
|
|
2585
|
+
}
|
|
2586
|
+
await this.loadMarkets();
|
|
2587
|
+
const currency = this.currency(code);
|
|
2588
|
+
const request = {
|
|
2589
|
+
'coin': currency['id'],
|
|
2590
|
+
'status': 5, // 0 init, 5 finished, 6 canceled, default 0
|
|
2591
|
+
// 'offset': 0,
|
|
2592
|
+
// 'limit': limit, // default 10, max 1000
|
|
2593
|
+
// 'startTime': since,
|
|
2594
|
+
// 'endTime': this.milliseconds (),
|
|
2595
|
+
};
|
|
2596
|
+
if (since !== undefined) {
|
|
2597
|
+
request['startTime'] = since;
|
|
2598
|
+
// request['endTime'] = this.sum (since, 7776000000);
|
|
2599
|
+
}
|
|
2600
|
+
if (limit !== undefined) {
|
|
2601
|
+
request['limit'] = limit;
|
|
2602
|
+
}
|
|
2603
|
+
const response = await this.spotV1PrivateGetWithdrawHistory(this.extend(request, params));
|
|
2604
|
+
//
|
|
2605
|
+
// {
|
|
2606
|
+
// "code": 200,
|
|
2607
|
+
// "msg": "succ",
|
|
2608
|
+
// "data": {
|
|
2609
|
+
// "msg": null,
|
|
2610
|
+
// "amount": 1000,
|
|
2611
|
+
// "fee": 1,
|
|
2612
|
+
// "ctime": null,
|
|
2613
|
+
// "coin": "usdt_erc20",
|
|
2614
|
+
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
|
|
2615
|
+
// }
|
|
2616
|
+
// }
|
|
2617
|
+
//
|
|
2618
|
+
const data = this.safeValue(response, 'data', {});
|
|
2619
|
+
return this.parseTransactions(data, currency);
|
|
2620
|
+
}
|
|
2621
|
+
parseTransactionStatusByType(status, type = undefined) {
|
|
2622
|
+
const statusesByType = {
|
|
2623
|
+
'deposit': {
|
|
2624
|
+
'0': 'pending',
|
|
2625
|
+
'1': 'ok',
|
|
2626
|
+
},
|
|
2627
|
+
'withdrawal': {
|
|
2628
|
+
'0': 'pending',
|
|
2629
|
+
'5': 'ok',
|
|
2630
|
+
'6': 'canceled',
|
|
2631
|
+
},
|
|
2632
|
+
};
|
|
2633
|
+
const statuses = this.safeValue(statusesByType, type, {});
|
|
2634
|
+
return this.safeString(statuses, status, status);
|
|
2635
|
+
}
|
|
2636
|
+
parseTransaction(transaction, currency = undefined) {
|
|
2637
|
+
//
|
|
2638
|
+
// fetchDeposits
|
|
2639
|
+
//
|
|
2640
|
+
// {
|
|
2641
|
+
// "symbol": "XRP",
|
|
2642
|
+
// "amount": "261.3361000000000000",
|
|
2643
|
+
// "fee": "0.0E-15",
|
|
2644
|
+
// "createdAt": 1548816979000,
|
|
2645
|
+
// "updatedAt": 1548816999000,
|
|
2646
|
+
// "addressFrom": "",
|
|
2647
|
+
// "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
|
|
2648
|
+
// "txid": "86D6EB68A7A28938BCE06BD348F8C07DEF500C5F7FE92069EF8C0551CE0F2C7D",
|
|
2649
|
+
// "confirmations": 8,
|
|
2650
|
+
// "status": 1,
|
|
2651
|
+
// "tagType": "Tag"
|
|
2652
|
+
// },
|
|
2653
|
+
// {
|
|
2654
|
+
// "symbol": "XRP",
|
|
2655
|
+
// "amount": "20.0000000000000000",
|
|
2656
|
+
// "fee": "0.0E-15",
|
|
2657
|
+
// "createdAt": 1544669393000,
|
|
2658
|
+
// "updatedAt": 1544669413000,
|
|
2659
|
+
// "addressFrom": "",
|
|
2660
|
+
// "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
|
|
2661
|
+
// "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC",
|
|
2662
|
+
// "confirmations": 7,
|
|
2663
|
+
// "status": 1,
|
|
2664
|
+
// "tagType": "Tag"
|
|
2665
|
+
// }
|
|
2666
|
+
//
|
|
2667
|
+
// fetchWithdrawals
|
|
2668
|
+
//
|
|
2669
|
+
// {
|
|
2670
|
+
// "id": 183745,
|
|
2671
|
+
// "symbol": "usdt_erc20",
|
|
2672
|
+
// "amount": "8.4000000000000000",
|
|
2673
|
+
// "fee": "1.6000000000000000",
|
|
2674
|
+
// "payAmount": "0.0000000000000000",
|
|
2675
|
+
// "createdAt": 1595336441000,
|
|
2676
|
+
// "updatedAt": 1595336576000,
|
|
2677
|
+
// "addressFrom": "",
|
|
2678
|
+
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83",
|
|
2679
|
+
// "txid": "",
|
|
2680
|
+
// "confirmations": 0,
|
|
2681
|
+
// "status": 6,
|
|
2682
|
+
// "tagType": null
|
|
2683
|
+
// }
|
|
2684
|
+
//
|
|
2685
|
+
// withdraw
|
|
2686
|
+
//
|
|
2687
|
+
// {
|
|
2688
|
+
// "msg": null,
|
|
2689
|
+
// "amount": 1000,
|
|
2690
|
+
// "fee": 1,
|
|
2691
|
+
// "ctime": null,
|
|
2692
|
+
// "coin": "usdt_erc20",
|
|
2693
|
+
// "withdrawId": 1156423,
|
|
2694
|
+
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
|
|
2695
|
+
// }
|
|
2696
|
+
//
|
|
2697
|
+
const id = this.safeString2(transaction, 'id', 'withdrawId');
|
|
2698
|
+
const tagType = this.safeString(transaction, 'tagType');
|
|
2699
|
+
let addressTo = this.safeString(transaction, 'addressTo');
|
|
2700
|
+
let addressFrom = this.safeString(transaction, 'addressFrom');
|
|
2701
|
+
let tagTo = undefined;
|
|
2702
|
+
let tagFrom = undefined;
|
|
2703
|
+
if (tagType !== undefined) {
|
|
2704
|
+
if (addressTo !== undefined) {
|
|
2705
|
+
const parts = addressTo.split('_');
|
|
2706
|
+
addressTo = this.safeString(parts, 0);
|
|
2707
|
+
tagTo = this.safeString(parts, 1);
|
|
2708
|
+
}
|
|
2709
|
+
if (addressFrom !== undefined) {
|
|
2710
|
+
const parts = addressFrom.split('_');
|
|
2711
|
+
addressFrom = this.safeString(parts, 0);
|
|
2712
|
+
tagFrom = this.safeString(parts, 1);
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
const txid = this.safeString(transaction, 'txid');
|
|
2716
|
+
const timestamp = this.safeInteger(transaction, 'createdAt');
|
|
2717
|
+
const updated = this.safeInteger(transaction, 'updatedAt');
|
|
2718
|
+
const payAmount = ('payAmount' in transaction);
|
|
2719
|
+
const ctime = ('ctime' in transaction);
|
|
2720
|
+
const type = (payAmount || ctime) ? 'withdrawal' : 'deposit';
|
|
2721
|
+
const status = this.parseTransactionStatusByType(this.safeString(transaction, 'status'), type);
|
|
2722
|
+
const amount = this.safeNumber(transaction, 'amount');
|
|
2723
|
+
let network = undefined;
|
|
2724
|
+
let currencyId = this.safeString2(transaction, 'symbol', 'coin');
|
|
2725
|
+
if (currencyId !== undefined) {
|
|
2726
|
+
const parts = currencyId.split('_');
|
|
2727
|
+
currencyId = this.safeString(parts, 0);
|
|
2728
|
+
const networkId = this.safeString(parts, 1);
|
|
2729
|
+
if (networkId !== undefined) {
|
|
2730
|
+
network = networkId.toUpperCase();
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
2734
|
+
const feeCost = this.safeNumber(transaction, 'fee');
|
|
2735
|
+
let fee = undefined;
|
|
2736
|
+
if (feeCost !== undefined) {
|
|
2737
|
+
fee = { 'currency': code, 'cost': feeCost };
|
|
2738
|
+
}
|
|
2739
|
+
return {
|
|
2740
|
+
'info': transaction,
|
|
2741
|
+
'id': id,
|
|
2742
|
+
'txid': txid,
|
|
2743
|
+
'timestamp': timestamp,
|
|
2744
|
+
'datetime': this.iso8601(timestamp),
|
|
2745
|
+
'network': network,
|
|
2746
|
+
'address': addressTo,
|
|
2747
|
+
'addressTo': addressTo,
|
|
2748
|
+
'addressFrom': addressFrom,
|
|
2749
|
+
'tag': tagTo,
|
|
2750
|
+
'tagTo': tagTo,
|
|
2751
|
+
'tagFrom': tagFrom,
|
|
2752
|
+
'type': type,
|
|
2753
|
+
'amount': amount,
|
|
2754
|
+
'currency': code,
|
|
2755
|
+
'status': status,
|
|
2756
|
+
'updated': updated,
|
|
2757
|
+
'internal': false,
|
|
2758
|
+
'comment': undefined,
|
|
2759
|
+
'fee': fee,
|
|
2760
|
+
};
|
|
2761
|
+
}
|
|
2762
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2763
|
+
/**
|
|
2764
|
+
* @method
|
|
2765
|
+
* @name bitrue#withdraw
|
|
2766
|
+
* @description make a withdrawal
|
|
2767
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-commit--withdraw_data
|
|
2768
|
+
* @param {string} code unified currency code
|
|
2769
|
+
* @param {float} amount the amount to withdraw
|
|
2770
|
+
* @param {string} address the address to withdraw to
|
|
2771
|
+
* @param {string} tag
|
|
2772
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2773
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2774
|
+
*/
|
|
2775
|
+
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
2776
|
+
this.checkAddress(address);
|
|
2777
|
+
await this.loadMarkets();
|
|
2778
|
+
const currency = this.currency(code);
|
|
2779
|
+
let chainName = this.safeString2(params, 'network', 'chainName');
|
|
2780
|
+
if (chainName === undefined) {
|
|
2781
|
+
const networks = this.safeValue(currency, 'networks', {});
|
|
2782
|
+
const optionsNetworks = this.safeValue(this.options, 'networks', {});
|
|
2783
|
+
let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
|
|
2784
|
+
network = this.safeString(optionsNetworks, network, network);
|
|
2785
|
+
const networkEntry = this.safeValue(networks, network, {});
|
|
2786
|
+
chainName = this.safeString(networkEntry, 'id'); // handle ERC20>ETH alias
|
|
2787
|
+
if (chainName === undefined) {
|
|
2788
|
+
throw new errors.ArgumentsRequired(this.id + ' withdraw() requires a network parameter or a chainName parameter');
|
|
2789
|
+
}
|
|
2790
|
+
params = this.omit(params, 'network');
|
|
2791
|
+
}
|
|
2792
|
+
const request = {
|
|
2793
|
+
'coin': currency['id'].toUpperCase(),
|
|
2794
|
+
'amount': amount,
|
|
2795
|
+
'addressTo': address,
|
|
2796
|
+
'chainName': chainName, // 'ERC20', 'TRC20', 'SOL'
|
|
2797
|
+
// 'addressMark': '', // mark of address
|
|
2798
|
+
// 'addrType': '', // type of address
|
|
2799
|
+
// 'tag': tag,
|
|
2800
|
+
};
|
|
2801
|
+
if (tag !== undefined) {
|
|
2802
|
+
request['tag'] = tag;
|
|
2803
|
+
}
|
|
2804
|
+
const response = await this.spotV1PrivatePostWithdrawCommit(this.extend(request, params));
|
|
2805
|
+
//
|
|
2806
|
+
// {
|
|
2807
|
+
// "code": 200,
|
|
2808
|
+
// "msg": "succ",
|
|
2809
|
+
// "data": {
|
|
2810
|
+
// "msg": null,
|
|
2811
|
+
// "amount": 1000,
|
|
2812
|
+
// "fee": 1,
|
|
2813
|
+
// "ctime": null,
|
|
2814
|
+
// "coin": "usdt_erc20",
|
|
2815
|
+
// "withdrawId": 1156423,
|
|
2816
|
+
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
|
|
2817
|
+
// }
|
|
2818
|
+
// }
|
|
2819
|
+
//
|
|
2820
|
+
const data = this.safeValue(response, 'data', {});
|
|
2821
|
+
return this.parseTransaction(data, currency);
|
|
2822
|
+
}
|
|
2823
|
+
parseDepositWithdrawFee(fee, currency = undefined) {
|
|
2824
|
+
//
|
|
2825
|
+
// {
|
|
2826
|
+
// "coin": "adx",
|
|
2827
|
+
// "coinFulName": "Ambire AdEx",
|
|
2828
|
+
// "chains": [ "BSC" ],
|
|
2829
|
+
// "chainDetail": [ [Object] ]
|
|
2830
|
+
// }
|
|
2831
|
+
//
|
|
2832
|
+
const chainDetails = this.safeValue(fee, 'chainDetail', []);
|
|
2833
|
+
const chainDetailLength = chainDetails.length;
|
|
2834
|
+
const result = {
|
|
2835
|
+
'info': fee,
|
|
2836
|
+
'withdraw': {
|
|
2837
|
+
'fee': undefined,
|
|
2838
|
+
'percentage': undefined,
|
|
2839
|
+
},
|
|
2840
|
+
'deposit': {
|
|
2841
|
+
'fee': undefined,
|
|
2842
|
+
'percentage': undefined,
|
|
2843
|
+
},
|
|
2844
|
+
'networks': {},
|
|
2845
|
+
};
|
|
2846
|
+
if (chainDetailLength !== 0) {
|
|
2847
|
+
for (let i = 0; i < chainDetailLength; i++) {
|
|
2848
|
+
const chainDetail = chainDetails[i];
|
|
2849
|
+
const networkId = this.safeString(chainDetail, 'chain');
|
|
2850
|
+
const currencyCode = this.safeString(currency, 'code');
|
|
2851
|
+
const networkCode = this.networkIdToCode(networkId, currencyCode);
|
|
2852
|
+
result['networks'][networkCode] = {
|
|
2853
|
+
'deposit': { 'fee': undefined, 'percentage': undefined },
|
|
2854
|
+
'withdraw': { 'fee': this.safeNumber(chainDetail, 'withdrawFee'), 'percentage': false },
|
|
2855
|
+
};
|
|
2856
|
+
if (chainDetailLength === 1) {
|
|
2857
|
+
result['withdraw']['fee'] = this.safeNumber(chainDetail, 'withdrawFee');
|
|
2858
|
+
result['withdraw']['percentage'] = false;
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
return result;
|
|
2863
|
+
}
|
|
2864
|
+
async fetchDepositWithdrawFees(codes = undefined, params = {}) {
|
|
2865
|
+
/**
|
|
2866
|
+
* @method
|
|
2867
|
+
* @name bitrue#fetchDepositWithdrawFees
|
|
2868
|
+
* @description fetch deposit and withdraw fees
|
|
2869
|
+
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint
|
|
2870
|
+
* @param {string[]|undefined} codes list of unified currency codes
|
|
2871
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2872
|
+
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
2873
|
+
*/
|
|
2874
|
+
await this.loadMarkets();
|
|
2875
|
+
const response = await this.spotV1PublicGetExchangeInfo(params);
|
|
2876
|
+
const coins = this.safeValue(response, 'coins');
|
|
2877
|
+
return this.parseDepositWithdrawFees(coins, codes, 'coin');
|
|
2878
|
+
}
|
|
2879
|
+
parseTransfer(transfer, currency = undefined) {
|
|
2880
|
+
//
|
|
2881
|
+
// fetchTransfers
|
|
2882
|
+
//
|
|
2883
|
+
// {
|
|
2884
|
+
// 'transferType': 'wallet_to_contract',
|
|
2885
|
+
// 'symbol': 'USDT',
|
|
2886
|
+
// 'amount': 1.0,
|
|
2887
|
+
// 'status': 1,
|
|
2888
|
+
// 'ctime': 1685404575000
|
|
2889
|
+
// }
|
|
2890
|
+
//
|
|
2891
|
+
// transfer
|
|
2892
|
+
//
|
|
2893
|
+
// {}
|
|
2894
|
+
//
|
|
2895
|
+
const transferType = this.safeString(transfer, 'transferType');
|
|
2896
|
+
let fromAccount = undefined;
|
|
2897
|
+
let toAccount = undefined;
|
|
2898
|
+
if (transferType !== undefined) {
|
|
2899
|
+
const accountSplit = transferType.split('_to_');
|
|
2900
|
+
fromAccount = this.safeString(accountSplit, 0);
|
|
2901
|
+
toAccount = this.safeString(accountSplit, 1);
|
|
2902
|
+
}
|
|
2903
|
+
const timestamp = this.safeInteger(transfer, 'ctime');
|
|
2904
|
+
return {
|
|
2905
|
+
'info': transfer,
|
|
2906
|
+
'id': undefined,
|
|
2907
|
+
'timestamp': timestamp,
|
|
2908
|
+
'datetime': this.iso8601(timestamp),
|
|
2909
|
+
'currency': this.safeString(currency, 'code'),
|
|
2910
|
+
'amount': this.safeNumber(transfer, 'amount'),
|
|
2911
|
+
'fromAccount': fromAccount,
|
|
2912
|
+
'toAccount': toAccount,
|
|
2913
|
+
'status': 'ok',
|
|
2914
|
+
};
|
|
2915
|
+
}
|
|
2916
|
+
async fetchTransfers(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2917
|
+
/**
|
|
2918
|
+
* @method
|
|
2919
|
+
* @name bitrue#fetchTransfers
|
|
2920
|
+
* @description fetch a history of internal transfers made on an account
|
|
2921
|
+
* @see https://www.bitrue.com/api-docs#get-future-account-transfer-history-list-user_data-hmac-sha256
|
|
2922
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#get-future-account-transfer-history-list-user_data-hmac-sha256
|
|
2923
|
+
* @param {string} code unified currency code of the currency transferred
|
|
2924
|
+
* @param {int} [since] the earliest time in ms to fetch transfers for
|
|
2925
|
+
* @param {int} [limit] the maximum number of transfers structures to retrieve
|
|
2926
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2927
|
+
* @param {int} [params.until] the latest time in ms to fetch transfers for
|
|
2928
|
+
* @param {string} [params.type] transfer type wallet_to_contract or contract_to_wallet
|
|
2929
|
+
* @returns {object[]} a list of [transfer structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure}
|
|
2930
|
+
*/
|
|
2931
|
+
await this.loadMarkets();
|
|
2932
|
+
const type = this.safeString2(params, 'type', 'transferType');
|
|
2933
|
+
const request = {
|
|
2934
|
+
'transferType': type,
|
|
2935
|
+
};
|
|
2936
|
+
let currency = undefined;
|
|
2937
|
+
if (code !== undefined) {
|
|
2938
|
+
currency = this.currency(code);
|
|
2939
|
+
request['coinSymbol'] = currency['id'];
|
|
2940
|
+
}
|
|
2941
|
+
if (since !== undefined) {
|
|
2942
|
+
request['beginTime'] = since;
|
|
2943
|
+
}
|
|
2944
|
+
if (limit !== undefined) {
|
|
2945
|
+
if (limit > 200) {
|
|
2946
|
+
limit = 200;
|
|
2947
|
+
}
|
|
2948
|
+
request['limit'] = limit;
|
|
2949
|
+
}
|
|
2950
|
+
const until = this.safeInteger(params, 'until');
|
|
2951
|
+
if (until !== undefined) {
|
|
2952
|
+
params = this.omit(params, 'until');
|
|
2953
|
+
request['endTime'] = until;
|
|
2954
|
+
}
|
|
2955
|
+
const response = await this.fapiV2PrivateGetFuturesTransferHistory(this.extend(request, params));
|
|
2956
|
+
//
|
|
2957
|
+
// {
|
|
2958
|
+
// 'code': '0',
|
|
2959
|
+
// 'msg': 'Success',
|
|
2960
|
+
// 'data': [{
|
|
2961
|
+
// 'transferType': 'wallet_to_contract',
|
|
2962
|
+
// 'symbol': 'USDT',
|
|
2963
|
+
// 'amount': 1.0,
|
|
2964
|
+
// 'status': 1,
|
|
2965
|
+
// 'ctime': 1685404575000
|
|
2966
|
+
// }]
|
|
2967
|
+
// }
|
|
2968
|
+
//
|
|
2969
|
+
const data = this.safeValue(response, 'data', {});
|
|
2970
|
+
return this.parseTransfers(data, currency, since, limit);
|
|
2971
|
+
}
|
|
2972
|
+
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
2973
|
+
/**
|
|
2974
|
+
* @method
|
|
2975
|
+
* @name bitrue#transfer
|
|
2976
|
+
* @description transfer currency internally between wallets on the same account
|
|
2977
|
+
* @see https://www.bitrue.com/api-docs#new-future-account-transfer-user_data-hmac-sha256
|
|
2978
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#user-commission-rate-user_data-hmac-sha256
|
|
2979
|
+
* @param {string} code unified currency code
|
|
2980
|
+
* @param {float} amount amount to transfer
|
|
2981
|
+
* @param {string} fromAccount account to transfer from
|
|
2982
|
+
* @param {string} toAccount account to transfer to
|
|
2983
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2984
|
+
* @returns {object} a [transfer structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure}
|
|
2985
|
+
*/
|
|
2986
|
+
await this.loadMarkets();
|
|
2987
|
+
const currency = this.currency(code);
|
|
2988
|
+
const accountTypes = this.safeValue(this.options, 'accountsByType', {});
|
|
2989
|
+
const fromId = this.safeString(accountTypes, fromAccount, fromAccount);
|
|
2990
|
+
const toId = this.safeString(accountTypes, toAccount, toAccount);
|
|
2991
|
+
const request = {
|
|
2992
|
+
'coinSymbol': currency['id'],
|
|
2993
|
+
'amount': this.currencyToPrecision(code, amount),
|
|
2994
|
+
'transferType': fromId + '_to_' + toId,
|
|
2995
|
+
};
|
|
2996
|
+
const response = await this.fapiV2PrivatePostFuturesTransfer(this.extend(request, params));
|
|
2997
|
+
//
|
|
2998
|
+
// {
|
|
2999
|
+
// 'code': '0',
|
|
3000
|
+
// 'msg': 'Success',
|
|
3001
|
+
// 'data': null
|
|
3002
|
+
// }
|
|
3003
|
+
//
|
|
3004
|
+
const data = this.safeValue(response, 'data', {});
|
|
3005
|
+
return this.parseTransfer(data, currency);
|
|
3006
|
+
}
|
|
3007
|
+
async setLeverage(leverage, symbol = undefined, params = {}) {
|
|
3008
|
+
/**
|
|
3009
|
+
* @method
|
|
3010
|
+
* @name bitrue#setLeverage
|
|
3011
|
+
* @description set the level of leverage for a market
|
|
3012
|
+
* @see https://www.bitrue.com/api-docs#change-initial-leverage-trade-hmac-sha256
|
|
3013
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#change-initial-leverage-trade-hmac-sha256
|
|
3014
|
+
* @param {float} leverage the rate of leverage
|
|
3015
|
+
* @param {string} symbol unified market symbol
|
|
3016
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3017
|
+
* @returns {object} response from the exchange
|
|
3018
|
+
*/
|
|
3019
|
+
if (symbol === undefined) {
|
|
3020
|
+
throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
|
|
3021
|
+
}
|
|
3022
|
+
if ((leverage < 1) || (leverage > 125)) {
|
|
3023
|
+
throw new errors.BadRequest(this.id + ' leverage should be between 1 and 125');
|
|
3024
|
+
}
|
|
3025
|
+
await this.loadMarkets();
|
|
3026
|
+
const market = this.market(symbol);
|
|
3027
|
+
let response = undefined;
|
|
3028
|
+
const request = {
|
|
3029
|
+
'contractName': market['id'],
|
|
3030
|
+
'leverage': leverage,
|
|
3031
|
+
};
|
|
3032
|
+
if (!market['swap']) {
|
|
3033
|
+
throw new errors.NotSupported(this.id + ' setLeverage only support swap markets');
|
|
3034
|
+
}
|
|
3035
|
+
if (market['linear']) {
|
|
3036
|
+
response = await this.fapiV2PrivatePostLevelEdit(this.extend(request, params));
|
|
3037
|
+
}
|
|
3038
|
+
else if (market['inverse']) {
|
|
3039
|
+
response = await this.dapiV2PrivatePostLevelEdit(this.extend(request, params));
|
|
3040
|
+
}
|
|
3041
|
+
return response;
|
|
3042
|
+
}
|
|
3043
|
+
parseMarginModification(data, market = undefined) {
|
|
3044
|
+
return {
|
|
3045
|
+
'info': data,
|
|
3046
|
+
'type': undefined,
|
|
3047
|
+
'amount': undefined,
|
|
3048
|
+
'code': undefined,
|
|
3049
|
+
'symbol': market['symbol'],
|
|
3050
|
+
'status': undefined,
|
|
3051
|
+
};
|
|
3052
|
+
}
|
|
3053
|
+
async setMargin(symbol, amount, params = {}) {
|
|
3054
|
+
/**
|
|
3055
|
+
* @method
|
|
3056
|
+
* @name bitrue#setMargin
|
|
3057
|
+
* @description Either adds or reduces margin in an isolated position in order to set the margin to a specific value
|
|
3058
|
+
* @see https://www.bitrue.com/api-docs#modify-isolated-position-margin-trade-hmac-sha256
|
|
3059
|
+
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#modify-isolated-position-margin-trade-hmac-sha256
|
|
3060
|
+
* @param {string} symbol unified market symbol of the market to set margin in
|
|
3061
|
+
* @param {float} amount the amount to set the margin to
|
|
3062
|
+
* @param {object} [params] parameters specific to the exchange API endpoint
|
|
3063
|
+
* @returns {object} A [margin structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#add-margin-structure}
|
|
3064
|
+
*/
|
|
3065
|
+
await this.loadMarkets();
|
|
3066
|
+
const market = this.market(symbol);
|
|
3067
|
+
if (!market['swap']) {
|
|
3068
|
+
throw new errors.NotSupported(this.id + ' setMargin only support swap markets');
|
|
3069
|
+
}
|
|
3070
|
+
let response = undefined;
|
|
3071
|
+
const request = {
|
|
3072
|
+
'contractName': market['id'],
|
|
3073
|
+
'amount': this.parseToNumeric(amount),
|
|
3074
|
+
};
|
|
3075
|
+
if (market['linear']) {
|
|
3076
|
+
response = await this.fapiV2PrivatePostPositionMargin(this.extend(request, params));
|
|
3077
|
+
}
|
|
3078
|
+
else if (market['inverse']) {
|
|
3079
|
+
response = await this.dapiV2PrivatePostPositionMargin(this.extend(request, params));
|
|
3080
|
+
}
|
|
3081
|
+
//
|
|
3082
|
+
// {
|
|
3083
|
+
// "code": 0,
|
|
3084
|
+
// "msg": "success"
|
|
3085
|
+
// "data": null
|
|
3086
|
+
// }
|
|
3087
|
+
//
|
|
3088
|
+
return this.parseMarginModification(response, market);
|
|
3089
|
+
}
|
|
3090
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
3091
|
+
const type = this.safeString(api, 0);
|
|
3092
|
+
const version = this.safeString(api, 1);
|
|
3093
|
+
const access = this.safeString(api, 2);
|
|
3094
|
+
let url = undefined;
|
|
3095
|
+
if (type === 'api' && version === 'kline') {
|
|
3096
|
+
url = this.urls['api'][type];
|
|
3097
|
+
}
|
|
3098
|
+
else {
|
|
3099
|
+
url = this.urls['api'][type] + '/' + version;
|
|
3100
|
+
}
|
|
3101
|
+
url = url + '/' + this.implodeParams(path, params);
|
|
3102
|
+
params = this.omit(params, this.extractParams(path));
|
|
3103
|
+
if (access === 'private') {
|
|
3104
|
+
this.checkRequiredCredentials();
|
|
3105
|
+
const recvWindow = this.safeInteger(this.options, 'recvWindow', 5000);
|
|
3106
|
+
if (type === 'spot') {
|
|
3107
|
+
let query = this.urlencode(this.extend({
|
|
3108
|
+
'timestamp': this.nonce(),
|
|
3109
|
+
'recvWindow': recvWindow,
|
|
3110
|
+
}, params));
|
|
3111
|
+
const signature = this.hmac(this.encode(query), this.encode(this.secret), sha256.sha256);
|
|
3112
|
+
query += '&' + 'signature=' + signature;
|
|
3113
|
+
headers = {
|
|
3114
|
+
'X-MBX-APIKEY': this.apiKey,
|
|
3115
|
+
};
|
|
3116
|
+
if ((method === 'GET') || (method === 'DELETE')) {
|
|
3117
|
+
url += '?' + query;
|
|
3118
|
+
}
|
|
3119
|
+
else {
|
|
3120
|
+
body = query;
|
|
3121
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
else {
|
|
3125
|
+
const timestamp = this.nonce().toString();
|
|
3126
|
+
let signPath = undefined;
|
|
3127
|
+
if (type === 'fapi') {
|
|
3128
|
+
signPath = '/fapi';
|
|
3129
|
+
}
|
|
3130
|
+
else if (type === 'dapi') {
|
|
3131
|
+
signPath = '/dapi';
|
|
3132
|
+
}
|
|
3133
|
+
signPath = signPath + '/' + version + '/' + path;
|
|
3134
|
+
let signMessage = timestamp + method + signPath;
|
|
3135
|
+
if (method === 'GET') {
|
|
3136
|
+
const signature = this.hmac(this.encode(signMessage), this.encode(this.secret), sha256.sha256);
|
|
3137
|
+
headers = {
|
|
3138
|
+
'X-CH-APIKEY': this.apiKey,
|
|
3139
|
+
'X-CH-SIGN': signature,
|
|
3140
|
+
'X-CH-TS': timestamp,
|
|
3141
|
+
};
|
|
3142
|
+
url += '?' + this.urlencode(params);
|
|
3143
|
+
}
|
|
3144
|
+
else {
|
|
3145
|
+
const query = this.extend({
|
|
3146
|
+
'recvWindow': recvWindow,
|
|
3147
|
+
}, params);
|
|
3148
|
+
body = this.json(query);
|
|
3149
|
+
signMessage = signMessage + JSON.stringify(body);
|
|
3150
|
+
const signature = this.hmac(this.encode(signMessage), this.encode(this.secret), sha256.sha256);
|
|
3151
|
+
headers = {
|
|
3152
|
+
'Content-Type': 'application/json',
|
|
3153
|
+
'X-CH-APIKEY': this.apiKey,
|
|
3154
|
+
'X-CH-SIGN': signature,
|
|
3155
|
+
'X-CH-TS': timestamp,
|
|
3156
|
+
};
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
else {
|
|
3161
|
+
if (Object.keys(params).length) {
|
|
3162
|
+
url += '?' + this.urlencode(params);
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
3166
|
+
}
|
|
3167
|
+
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
3168
|
+
if ((code === 418) || (code === 429)) {
|
|
3169
|
+
throw new errors.DDoSProtection(this.id + ' ' + code.toString() + ' ' + reason + ' ' + body);
|
|
3170
|
+
}
|
|
3171
|
+
// error response in a form: { "code": -1013, "msg": "Invalid quantity." }
|
|
3172
|
+
// following block cointains legacy checks against message patterns in "msg" property
|
|
3173
|
+
// will switch "code" checks eventually, when we know all of them
|
|
3174
|
+
if (code >= 400) {
|
|
3175
|
+
if (body.indexOf('Price * QTY is zero or less') >= 0) {
|
|
3176
|
+
throw new errors.InvalidOrder(this.id + ' order cost = amount * price is zero or less ' + body);
|
|
3177
|
+
}
|
|
3178
|
+
if (body.indexOf('LOT_SIZE') >= 0) {
|
|
3179
|
+
throw new errors.InvalidOrder(this.id + ' order amount should be evenly divisible by lot size ' + body);
|
|
3180
|
+
}
|
|
3181
|
+
if (body.indexOf('PRICE_FILTER') >= 0) {
|
|
3182
|
+
throw new errors.InvalidOrder(this.id + ' order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use this.priceToPrecision (symbol, amount) ' + body);
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
if (response === undefined) {
|
|
3186
|
+
return undefined; // fallback to default error handler
|
|
3187
|
+
}
|
|
3188
|
+
// check success value for wapi endpoints
|
|
3189
|
+
// response in format {'msg': 'The coin does not exist.', 'success': true/false}
|
|
3190
|
+
const success = this.safeValue(response, 'success', true);
|
|
3191
|
+
if (!success) {
|
|
3192
|
+
const messageInner = this.safeString(response, 'msg');
|
|
3193
|
+
let parsedMessage = undefined;
|
|
3194
|
+
if (messageInner !== undefined) {
|
|
3195
|
+
try {
|
|
3196
|
+
parsedMessage = JSON.parse(messageInner);
|
|
3197
|
+
}
|
|
3198
|
+
catch (e) {
|
|
3199
|
+
// do nothing
|
|
3200
|
+
parsedMessage = undefined;
|
|
3201
|
+
}
|
|
3202
|
+
if (parsedMessage !== undefined) {
|
|
3203
|
+
response = parsedMessage;
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
const message = this.safeString(response, 'msg');
|
|
3208
|
+
if (message !== undefined) {
|
|
3209
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, this.id + ' ' + message);
|
|
3210
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, this.id + ' ' + message);
|
|
3211
|
+
}
|
|
3212
|
+
// checks against error codes
|
|
3213
|
+
const error = this.safeString(response, 'code');
|
|
3214
|
+
if (error !== undefined) {
|
|
3215
|
+
// https://github.com/ccxt/ccxt/issues/6501
|
|
3216
|
+
// https://github.com/ccxt/ccxt/issues/7742
|
|
3217
|
+
if ((error === '200') || Precise["default"].stringEquals(error, '0')) {
|
|
3218
|
+
return undefined;
|
|
3219
|
+
}
|
|
3220
|
+
// a workaround for {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."}
|
|
3221
|
+
// despite that their message is very confusing, it is raised by Binance
|
|
3222
|
+
// on a temporary ban, the API key is valid, but disabled for a while
|
|
3223
|
+
if ((error === '-2015') && this.options['hasAlreadyAuthenticatedSuccessfully']) {
|
|
3224
|
+
throw new errors.DDoSProtection(this.id + ' temporary banned: ' + body);
|
|
3225
|
+
}
|
|
3226
|
+
const feedback = this.id + ' ' + body;
|
|
3227
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], error, feedback);
|
|
3228
|
+
throw new errors.ExchangeError(feedback);
|
|
3229
|
+
}
|
|
3230
|
+
if (!success) {
|
|
3231
|
+
throw new errors.ExchangeError(this.id + ' ' + body);
|
|
3232
|
+
}
|
|
3233
|
+
return undefined;
|
|
3234
|
+
}
|
|
3235
|
+
calculateRateLimiterCost(api, method, path, params, config = {}) {
|
|
3236
|
+
if (('noSymbol' in config) && !('symbol' in params)) {
|
|
3237
|
+
return config['noSymbol'];
|
|
3238
|
+
}
|
|
3239
|
+
else if (('byLimit' in config) && ('limit' in params)) {
|
|
3240
|
+
const limit = params['limit'];
|
|
3241
|
+
const byLimit = config['byLimit'];
|
|
3242
|
+
for (let i = 0; i < byLimit.length; i++) {
|
|
3243
|
+
const entry = byLimit[i];
|
|
3244
|
+
if (limit <= entry[0]) {
|
|
3245
|
+
return entry[1];
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
return this.safeValue(config, 'cost', 1);
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
module.exports = bitrue;
|