ccxt 4.2.11 → 4.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/build.sh +2 -2
- package/dist/ccxt.browser.js +1347 -490
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/_virtual/agent.js +7 -0
- package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
- package/dist/cjs/_virtual/promisify.js +7 -0
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/js/ccxt.js +474 -0
- package/dist/cjs/js/src/abstract/ace.js +9 -0
- package/dist/cjs/js/src/abstract/alpaca.js +9 -0
- package/dist/cjs/js/src/abstract/ascendex.js +9 -0
- package/dist/cjs/js/src/abstract/bigone.js +9 -0
- package/dist/cjs/js/src/abstract/binance.js +9 -0
- package/dist/cjs/js/src/abstract/bingx.js +9 -0
- package/dist/cjs/js/src/abstract/bit2c.js +9 -0
- package/dist/cjs/js/src/abstract/bitbank.js +9 -0
- package/dist/cjs/js/src/abstract/bitbns.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
- package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
- package/dist/cjs/js/src/abstract/bitforex.js +9 -0
- package/dist/cjs/js/src/abstract/bitget.js +9 -0
- package/dist/cjs/js/src/abstract/bithumb.js +9 -0
- package/dist/cjs/js/src/abstract/bitmart.js +9 -0
- package/dist/cjs/js/src/abstract/bitmex.js +9 -0
- package/dist/cjs/js/src/abstract/bitopro.js +9 -0
- package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
- package/dist/cjs/js/src/abstract/bitrue.js +9 -0
- package/dist/cjs/js/src/abstract/bitso.js +9 -0
- package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
- package/dist/cjs/js/src/abstract/bitteam.js +9 -0
- package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
- package/dist/cjs/js/src/abstract/bl3p.js +9 -0
- package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
- package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
- package/dist/cjs/js/src/abstract/btcbox.js +9 -0
- package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
- package/dist/cjs/js/src/abstract/btcturk.js +9 -0
- package/dist/cjs/js/src/abstract/bybit.js +9 -0
- package/dist/cjs/js/src/abstract/cex.js +9 -0
- package/dist/cjs/js/src/abstract/coinbase.js +9 -0
- package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
- package/dist/cjs/js/src/abstract/coincheck.js +9 -0
- package/dist/cjs/js/src/abstract/coinex.js +9 -0
- package/dist/cjs/js/src/abstract/coinlist.js +9 -0
- package/dist/cjs/js/src/abstract/coinmate.js +9 -0
- package/dist/cjs/js/src/abstract/coinone.js +9 -0
- package/dist/cjs/js/src/abstract/coinsph.js +9 -0
- package/dist/cjs/js/src/abstract/coinspot.js +9 -0
- package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
- package/dist/cjs/js/src/abstract/currencycom.js +9 -0
- package/dist/cjs/js/src/abstract/delta.js +9 -0
- package/dist/cjs/js/src/abstract/deribit.js +9 -0
- package/dist/cjs/js/src/abstract/digifinex.js +9 -0
- package/dist/cjs/js/src/abstract/exmo.js +9 -0
- package/dist/cjs/js/src/abstract/gate.js +9 -0
- package/dist/cjs/js/src/abstract/gemini.js +9 -0
- package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
- package/dist/cjs/js/src/abstract/hollaex.js +9 -0
- package/dist/cjs/js/src/abstract/htx.js +9 -0
- package/dist/cjs/js/src/abstract/huobijp.js +9 -0
- package/dist/cjs/js/src/abstract/idex.js +9 -0
- package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
- package/dist/cjs/js/src/abstract/indodax.js +9 -0
- package/dist/cjs/js/src/abstract/kraken.js +9 -0
- package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kucoin.js +9 -0
- package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kuna.js +9 -0
- package/dist/cjs/js/src/abstract/latoken.js +9 -0
- package/dist/cjs/js/src/abstract/lbank.js +9 -0
- package/dist/cjs/js/src/abstract/luno.js +9 -0
- package/dist/cjs/js/src/abstract/lykke.js +9 -0
- package/dist/cjs/js/src/abstract/mercado.js +9 -0
- package/dist/cjs/js/src/abstract/mexc.js +9 -0
- package/dist/cjs/js/src/abstract/ndax.js +9 -0
- package/dist/cjs/js/src/abstract/novadax.js +9 -0
- package/dist/cjs/js/src/abstract/oceanex.js +9 -0
- package/dist/cjs/js/src/abstract/okcoin.js +9 -0
- package/dist/cjs/js/src/abstract/okx.js +9 -0
- package/dist/cjs/js/src/abstract/p2b.js +9 -0
- package/dist/cjs/js/src/abstract/paymium.js +9 -0
- package/dist/cjs/js/src/abstract/phemex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
- package/dist/cjs/js/src/abstract/probit.js +9 -0
- package/dist/cjs/js/src/abstract/timex.js +9 -0
- package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
- package/dist/cjs/js/src/abstract/upbit.js +9 -0
- package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
- package/dist/cjs/js/src/abstract/wazirx.js +9 -0
- package/dist/cjs/js/src/abstract/whitebit.js +9 -0
- package/dist/cjs/js/src/abstract/woo.js +9 -0
- package/dist/cjs/js/src/abstract/yobit.js +9 -0
- package/dist/cjs/js/src/abstract/zaif.js +9 -0
- package/dist/cjs/js/src/abstract/zonda.js +9 -0
- package/dist/cjs/js/src/ace.js +1058 -0
- package/dist/cjs/js/src/alpaca.js +1125 -0
- package/dist/cjs/js/src/ascendex.js +3360 -0
- package/dist/cjs/js/src/base/Exchange.js +5110 -0
- package/dist/cjs/js/src/base/Precise.js +263 -0
- package/dist/cjs/js/src/base/errors.js +299 -0
- package/dist/cjs/js/src/base/functions/crypto.js +78 -0
- package/dist/cjs/js/src/base/functions/encode.js +44 -0
- package/dist/cjs/js/src/base/functions/generic.js +193 -0
- package/dist/cjs/js/src/base/functions/misc.js +96 -0
- package/dist/cjs/js/src/base/functions/number.js +297 -0
- package/dist/cjs/js/src/base/functions/platform.js +28 -0
- package/dist/cjs/js/src/base/functions/rsa.js +34 -0
- package/dist/cjs/js/src/base/functions/string.js +48 -0
- package/dist/cjs/js/src/base/functions/throttle.js +66 -0
- package/dist/cjs/js/src/base/functions/time.js +187 -0
- package/dist/cjs/js/src/base/functions/totp.js +24 -0
- package/dist/cjs/js/src/base/functions/type.js +162 -0
- package/dist/cjs/js/src/base/functions.js +157 -0
- package/dist/cjs/js/src/base/ws/Cache.js +254 -0
- package/dist/cjs/js/src/base/ws/Client.js +299 -0
- package/dist/cjs/js/src/base/ws/Future.js +34 -0
- package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
- package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
- package/dist/cjs/js/src/bequant.js +33 -0
- package/dist/cjs/js/src/bigone.js +2209 -0
- package/dist/cjs/js/src/binance.js +9736 -0
- package/dist/cjs/js/src/binancecoinm.js +45 -0
- package/dist/cjs/js/src/binanceus.js +84 -0
- package/dist/cjs/js/src/binanceusdm.js +58 -0
- package/dist/cjs/js/src/bingx.js +3807 -0
- package/dist/cjs/js/src/bit2c.js +916 -0
- package/dist/cjs/js/src/bitbank.js +1000 -0
- package/dist/cjs/js/src/bitbay.js +17 -0
- package/dist/cjs/js/src/bitbns.js +1220 -0
- package/dist/cjs/js/src/bitcoincom.js +17 -0
- package/dist/cjs/js/src/bitfinex.js +1670 -0
- package/dist/cjs/js/src/bitfinex2.js +2990 -0
- package/dist/cjs/js/src/bitflyer.js +1045 -0
- package/dist/cjs/js/src/bitforex.js +852 -0
- package/dist/cjs/js/src/bitget.js +8291 -0
- package/dist/cjs/js/src/bithumb.js +1090 -0
- package/dist/cjs/js/src/bitmart.js +4454 -0
- package/dist/cjs/js/src/bitmex.js +2884 -0
- package/dist/cjs/js/src/bitopro.js +1724 -0
- package/dist/cjs/js/src/bitpanda.js +2002 -0
- package/dist/cjs/js/src/bitrue.js +3253 -0
- package/dist/cjs/js/src/bitso.js +1753 -0
- package/dist/cjs/js/src/bitstamp.js +2188 -0
- package/dist/cjs/js/src/bitteam.js +2309 -0
- package/dist/cjs/js/src/bitvavo.js +1968 -0
- package/dist/cjs/js/src/bl3p.js +447 -0
- package/dist/cjs/js/src/blockchaincom.js +1160 -0
- package/dist/cjs/js/src/btcalpha.js +929 -0
- package/dist/cjs/js/src/btcbox.js +565 -0
- package/dist/cjs/js/src/btcmarkets.js +1237 -0
- package/dist/cjs/js/src/btcturk.js +929 -0
- package/dist/cjs/js/src/bybit.js +7646 -0
- package/dist/cjs/js/src/cex.js +1693 -0
- package/dist/cjs/js/src/coinbase.js +3424 -0
- package/dist/cjs/js/src/coinbasepro.js +1866 -0
- package/dist/cjs/js/src/coincheck.js +843 -0
- package/dist/cjs/js/src/coinex.js +5414 -0
- package/dist/cjs/js/src/coinlist.js +2329 -0
- package/dist/cjs/js/src/coinmate.js +989 -0
- package/dist/cjs/js/src/coinone.js +1185 -0
- package/dist/cjs/js/src/coinsph.js +1933 -0
- package/dist/cjs/js/src/coinspot.js +548 -0
- package/dist/cjs/js/src/cryptocom.js +3007 -0
- package/dist/cjs/js/src/currencycom.js +2015 -0
- package/dist/cjs/js/src/delta.js +3256 -0
- package/dist/cjs/js/src/deribit.js +3306 -0
- package/dist/cjs/js/src/digifinex.js +4307 -0
- package/dist/cjs/js/src/exmo.js +2645 -0
- package/dist/cjs/js/src/fmfwio.js +34 -0
- package/dist/cjs/js/src/gate.js +7072 -0
- package/dist/cjs/js/src/gateio.js +16 -0
- package/dist/cjs/js/src/gemini.js +1801 -0
- package/dist/cjs/js/src/hitbtc.js +3660 -0
- package/dist/cjs/js/src/hitbtc3.js +19 -0
- package/dist/cjs/js/src/hollaex.js +1882 -0
- package/dist/cjs/js/src/htx.js +9049 -0
- package/dist/cjs/js/src/huobi.js +16 -0
- package/dist/cjs/js/src/huobijp.js +1918 -0
- package/dist/cjs/js/src/idex.js +1770 -0
- package/dist/cjs/js/src/independentreserve.js +761 -0
- package/dist/cjs/js/src/indodax.js +1069 -0
- package/dist/cjs/js/src/kraken.js +2857 -0
- package/dist/cjs/js/src/krakenfutures.js +2407 -0
- package/dist/cjs/js/src/kucoin.js +4489 -0
- package/dist/cjs/js/src/kucoinfutures.js +2475 -0
- package/dist/cjs/js/src/kuna.js +1949 -0
- package/dist/cjs/js/src/latoken.js +1729 -0
- package/dist/cjs/js/src/lbank.js +2851 -0
- package/dist/cjs/js/src/luno.js +1044 -0
- package/dist/cjs/js/src/lykke.js +1303 -0
- package/dist/cjs/js/src/mercado.js +897 -0
- package/dist/cjs/js/src/mexc.js +5407 -0
- package/dist/cjs/js/src/ndax.js +2450 -0
- package/dist/cjs/js/src/novadax.js +1556 -0
- package/dist/cjs/js/src/oceanex.js +964 -0
- package/dist/cjs/js/src/okcoin.js +3115 -0
- package/dist/cjs/js/src/okx.js +7330 -0
- package/dist/cjs/js/src/p2b.js +1243 -0
- package/dist/cjs/js/src/paymium.js +597 -0
- package/dist/cjs/js/src/phemex.js +4722 -0
- package/dist/cjs/js/src/poloniex.js +2356 -0
- package/dist/cjs/js/src/poloniexfutures.js +1794 -0
- package/dist/cjs/js/src/pro/alpaca.js +714 -0
- package/dist/cjs/js/src/pro/ascendex.js +957 -0
- package/dist/cjs/js/src/pro/bequant.js +33 -0
- package/dist/cjs/js/src/pro/binance.js +2796 -0
- package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
- package/dist/cjs/js/src/pro/binanceus.js +51 -0
- package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
- package/dist/cjs/js/src/pro/bingx.js +944 -0
- package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
- package/dist/cjs/js/src/pro/bitfinex.js +672 -0
- package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
- package/dist/cjs/js/src/pro/bitget.js +1733 -0
- package/dist/cjs/js/src/pro/bitmart.js +1486 -0
- package/dist/cjs/js/src/pro/bitmex.js +1576 -0
- package/dist/cjs/js/src/pro/bitopro.js +327 -0
- package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
- package/dist/cjs/js/src/pro/bitrue.js +462 -0
- package/dist/cjs/js/src/pro/bitstamp.js +547 -0
- package/dist/cjs/js/src/pro/bitvavo.js +704 -0
- package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
- package/dist/cjs/js/src/pro/bybit.js +1843 -0
- package/dist/cjs/js/src/pro/cex.js +1510 -0
- package/dist/cjs/js/src/pro/coinbase.js +561 -0
- package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
- package/dist/cjs/js/src/pro/coinex.js +1095 -0
- package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
- package/dist/cjs/js/src/pro/currencycom.js +563 -0
- package/dist/cjs/js/src/pro/deribit.js +825 -0
- package/dist/cjs/js/src/pro/exmo.js +658 -0
- package/dist/cjs/js/src/pro/gate.js +1316 -0
- package/dist/cjs/js/src/pro/gateio.js +16 -0
- package/dist/cjs/js/src/pro/gemini.js +649 -0
- package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
- package/dist/cjs/js/src/pro/hollaex.js +597 -0
- package/dist/cjs/js/src/pro/htx.js +2383 -0
- package/dist/cjs/js/src/pro/huobi.js +16 -0
- package/dist/cjs/js/src/pro/huobijp.js +606 -0
- package/dist/cjs/js/src/pro/idex.js +714 -0
- package/dist/cjs/js/src/pro/independentreserve.js +280 -0
- package/dist/cjs/js/src/pro/kraken.js +1364 -0
- package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
- package/dist/cjs/js/src/pro/kucoin.js +1052 -0
- package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
- package/dist/cjs/js/src/pro/luno.js +322 -0
- package/dist/cjs/js/src/pro/mexc.js +1170 -0
- package/dist/cjs/js/src/pro/ndax.js +545 -0
- package/dist/cjs/js/src/pro/okcoin.js +760 -0
- package/dist/cjs/js/src/pro/okx.js +1608 -0
- package/dist/cjs/js/src/pro/phemex.js +1511 -0
- package/dist/cjs/js/src/pro/poloniex.js +1253 -0
- package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
- package/dist/cjs/js/src/pro/probit.js +586 -0
- package/dist/cjs/js/src/pro/upbit.js +234 -0
- package/dist/cjs/js/src/pro/wazirx.js +776 -0
- package/dist/cjs/js/src/pro/whitebit.js +927 -0
- package/dist/cjs/js/src/pro/woo.js +769 -0
- package/dist/cjs/js/src/probit.js +1867 -0
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
- package/dist/cjs/js/src/timex.js +1562 -0
- package/dist/cjs/js/src/tokocrypto.js +2542 -0
- package/dist/cjs/js/src/upbit.js +1844 -0
- package/dist/cjs/js/src/wavesexchange.js +2607 -0
- package/dist/cjs/js/src/wazirx.js +953 -0
- package/dist/cjs/js/src/whitebit.js +2309 -0
- package/dist/cjs/js/src/woo.js +2765 -0
- package/dist/cjs/js/src/yobit.js +1314 -0
- package/dist/cjs/js/src/zaif.js +736 -0
- package/dist/cjs/js/src/zonda.js +1883 -0
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bigone.d.ts +18 -0
- package/js/src/abstract/binance.d.ts +2 -0
- package/js/src/abstract/binancecoinm.d.ts +2 -0
- package/js/src/abstract/binanceus.d.ts +2 -0
- package/js/src/abstract/binanceusdm.d.ts +2 -0
- package/js/src/abstract/bingx.d.ts +2 -0
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/abstract/gate.d.ts +11 -0
- package/js/src/abstract/gateio.d.ts +11 -0
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/alpaca.js +18 -18
- package/js/src/base/Exchange.d.ts +5 -1
- package/js/src/base/Exchange.js +101 -12
- package/js/src/bigone.d.ts +3 -2
- package/js/src/bigone.js +429 -167
- package/js/src/binance.js +48 -34
- package/js/src/bingx.js +115 -38
- package/js/src/bitfinex.d.ts +2 -2
- package/js/src/bitfinex.js +2 -3
- package/js/src/bitget.js +33 -13
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +5 -5
- package/js/src/bitmex.js +1 -0
- package/js/src/bybit.js +2 -0
- package/js/src/coinbase.d.ts +26 -3
- package/js/src/coinbase.js +176 -26
- package/js/src/coinlist.js +3 -4
- package/js/src/coinone.js +1 -1
- package/js/src/coinsph.js +2 -3
- package/js/src/deribit.js +1 -0
- package/js/src/gate.d.ts +4 -4
- package/js/src/gate.js +96 -59
- package/js/src/gemini.js +1 -1
- package/js/src/hitbtc.d.ts +4 -4
- package/js/src/hitbtc.js +2 -3
- package/js/src/htx.d.ts +1 -0
- package/js/src/htx.js +29 -7
- package/js/src/huobijp.js +2 -3
- package/js/src/independentreserve.js +7 -5
- package/js/src/kraken.js +3 -6
- package/js/src/lbank.js +59 -33
- package/js/src/mexc.js +2 -1
- package/js/src/oceanex.js +1 -1
- package/js/src/okx.js +14 -3
- package/js/src/phemex.js +9 -2
- package/js/src/pro/binance.d.ts +2 -23
- package/js/src/pro/binance.js +58 -22
- package/js/src/pro/coinbase.d.ts +2 -2
- package/js/src/pro/coinbase.js +4 -1
- package/js/src/pro/coinbasepro.d.ts +2 -2
- package/js/src/pro/hitbtc.d.ts +2 -2
- package/js/src/pro/kraken.js +1 -1
- package/js/src/pro/okx.d.ts +1 -0
- package/js/src/pro/okx.js +52 -2
- package/js/src/pro/poloniex.d.ts +2 -2
- package/js/src/probit.js +4 -2
- package/js/src/upbit.d.ts +3 -101
- package/js/src/upbit.js +12 -12
- package/js/src/wavesexchange.js +1 -1
- package/js/src/woo.d.ts +2 -0
- package/js/src/woo.js +52 -0
- package/package.json +1 -1
- package/skip-tests.json +5 -0
|
@@ -0,0 +1,4489 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var kucoin$1 = require('./abstract/kucoin.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 kucoin
|
|
13
|
+
* @augments Exchange
|
|
14
|
+
*/
|
|
15
|
+
class kucoin extends kucoin$1 {
|
|
16
|
+
describe() {
|
|
17
|
+
return this.deepExtend(super.describe(), {
|
|
18
|
+
'id': 'kucoin',
|
|
19
|
+
'name': 'KuCoin',
|
|
20
|
+
'countries': ['SC'],
|
|
21
|
+
'rateLimit': 10,
|
|
22
|
+
'version': 'v2',
|
|
23
|
+
'certified': true,
|
|
24
|
+
'pro': true,
|
|
25
|
+
'comment': 'Platform 2.0',
|
|
26
|
+
'quoteJsonNumbers': false,
|
|
27
|
+
'has': {
|
|
28
|
+
'CORS': undefined,
|
|
29
|
+
'spot': true,
|
|
30
|
+
'margin': true,
|
|
31
|
+
'swap': false,
|
|
32
|
+
'future': false,
|
|
33
|
+
'option': false,
|
|
34
|
+
'borrowCrossMargin': true,
|
|
35
|
+
'borrowIsolatedMargin': true,
|
|
36
|
+
'cancelAllOrders': true,
|
|
37
|
+
'cancelOrder': true,
|
|
38
|
+
'closeAllPositions': false,
|
|
39
|
+
'closePosition': false,
|
|
40
|
+
'createDepositAddress': true,
|
|
41
|
+
'createMarketBuyOrderWithCost': true,
|
|
42
|
+
'createMarketOrderWithCost': true,
|
|
43
|
+
'createMarketSellOrderWithCost': true,
|
|
44
|
+
'createOrder': true,
|
|
45
|
+
'createOrders': true,
|
|
46
|
+
'createPostOnlyOrder': true,
|
|
47
|
+
'createStopLimitOrder': true,
|
|
48
|
+
'createStopMarketOrder': true,
|
|
49
|
+
'createStopOrder': true,
|
|
50
|
+
'editOrder': true,
|
|
51
|
+
'fetchAccounts': true,
|
|
52
|
+
'fetchBalance': true,
|
|
53
|
+
'fetchBorrowInterest': true,
|
|
54
|
+
'fetchBorrowRateHistories': false,
|
|
55
|
+
'fetchBorrowRateHistory': false,
|
|
56
|
+
'fetchClosedOrders': true,
|
|
57
|
+
'fetchCrossBorrowRate': false,
|
|
58
|
+
'fetchCrossBorrowRates': false,
|
|
59
|
+
'fetchCurrencies': true,
|
|
60
|
+
'fetchDepositAddress': true,
|
|
61
|
+
'fetchDepositAddressesByNetwork': true,
|
|
62
|
+
'fetchDeposits': true,
|
|
63
|
+
'fetchDepositWithdrawFee': true,
|
|
64
|
+
'fetchDepositWithdrawFees': true,
|
|
65
|
+
'fetchFundingHistory': false,
|
|
66
|
+
'fetchFundingRate': false,
|
|
67
|
+
'fetchFundingRateHistory': false,
|
|
68
|
+
'fetchFundingRates': false,
|
|
69
|
+
'fetchIndexOHLCV': false,
|
|
70
|
+
'fetchIsolatedBorrowRate': false,
|
|
71
|
+
'fetchIsolatedBorrowRates': false,
|
|
72
|
+
'fetchL3OrderBook': true,
|
|
73
|
+
'fetchLedger': true,
|
|
74
|
+
'fetchLeverageTiers': false,
|
|
75
|
+
'fetchMarginMode': false,
|
|
76
|
+
'fetchMarketLeverageTiers': false,
|
|
77
|
+
'fetchMarkets': true,
|
|
78
|
+
'fetchMarkOHLCV': false,
|
|
79
|
+
'fetchMyTrades': true,
|
|
80
|
+
'fetchOHLCV': true,
|
|
81
|
+
'fetchOpenInterest': false,
|
|
82
|
+
'fetchOpenInterestHistory': false,
|
|
83
|
+
'fetchOpenOrders': true,
|
|
84
|
+
'fetchOrder': true,
|
|
85
|
+
'fetchOrderBook': true,
|
|
86
|
+
'fetchOrderBooks': false,
|
|
87
|
+
'fetchOrdersByStatus': true,
|
|
88
|
+
'fetchOrderTrades': true,
|
|
89
|
+
'fetchPositionMode': false,
|
|
90
|
+
'fetchPremiumIndexOHLCV': false,
|
|
91
|
+
'fetchStatus': true,
|
|
92
|
+
'fetchTicker': true,
|
|
93
|
+
'fetchTickers': true,
|
|
94
|
+
'fetchTime': true,
|
|
95
|
+
'fetchTrades': true,
|
|
96
|
+
'fetchTradingFee': true,
|
|
97
|
+
'fetchTradingFees': false,
|
|
98
|
+
'fetchTransactionFee': true,
|
|
99
|
+
'fetchTransfers': false,
|
|
100
|
+
'fetchWithdrawals': true,
|
|
101
|
+
'repayCrossMargin': true,
|
|
102
|
+
'repayIsolatedMargin': true,
|
|
103
|
+
'setLeverage': false,
|
|
104
|
+
'setMarginMode': false,
|
|
105
|
+
'setPositionMode': false,
|
|
106
|
+
'signIn': false,
|
|
107
|
+
'transfer': true,
|
|
108
|
+
'withdraw': true,
|
|
109
|
+
},
|
|
110
|
+
'urls': {
|
|
111
|
+
'logo': 'https://user-images.githubusercontent.com/51840849/87295558-132aaf80-c50e-11ea-9801-a2fb0c57c799.jpg',
|
|
112
|
+
'referral': 'https://www.kucoin.com/ucenter/signup?rcode=E5wkqe',
|
|
113
|
+
'api': {
|
|
114
|
+
'public': 'https://api.kucoin.com',
|
|
115
|
+
'private': 'https://api.kucoin.com',
|
|
116
|
+
'futuresPrivate': 'https://api-futures.kucoin.com',
|
|
117
|
+
'futuresPublic': 'https://api-futures.kucoin.com',
|
|
118
|
+
'webExchange': 'https://kucoin.com/_api',
|
|
119
|
+
},
|
|
120
|
+
'www': 'https://www.kucoin.com',
|
|
121
|
+
'doc': [
|
|
122
|
+
'https://docs.kucoin.com',
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
'requiredCredentials': {
|
|
126
|
+
'apiKey': true,
|
|
127
|
+
'secret': true,
|
|
128
|
+
'password': true,
|
|
129
|
+
},
|
|
130
|
+
'api': {
|
|
131
|
+
// level VIP0
|
|
132
|
+
// Spot => 3000/30s => 100/s
|
|
133
|
+
// Weight = x => 100/(100/x) = x
|
|
134
|
+
// Futures Management Public => 2000/30s => 200/3/s
|
|
135
|
+
// Weight = x => 100/(200/3/x) = x*1.5
|
|
136
|
+
'public': {
|
|
137
|
+
'get': {
|
|
138
|
+
// spot trading
|
|
139
|
+
'currencies': 4.5,
|
|
140
|
+
'currencies/{currency}': 4.5,
|
|
141
|
+
'symbols': 6,
|
|
142
|
+
'market/orderbook/level1': 3,
|
|
143
|
+
'market/allTickers': 22.5,
|
|
144
|
+
'market/stats': 22.5,
|
|
145
|
+
'markets': 4.5,
|
|
146
|
+
'market/orderbook/level{level}_{limit}': 6,
|
|
147
|
+
'market/orderbook/level2_20': 3,
|
|
148
|
+
'market/orderbook/level2_100': 6,
|
|
149
|
+
'market/histories': 4.5,
|
|
150
|
+
'market/candles': 4.5,
|
|
151
|
+
'prices': 4.5,
|
|
152
|
+
'timestamp': 4.5,
|
|
153
|
+
'status': 4.5,
|
|
154
|
+
// margin trading
|
|
155
|
+
'mark-price/{symbol}/current': 3,
|
|
156
|
+
'margin/config': 25, // 25SW
|
|
157
|
+
},
|
|
158
|
+
'post': {
|
|
159
|
+
// ws
|
|
160
|
+
'bullet-public': 15, // 10PW
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
'private': {
|
|
164
|
+
'get': {
|
|
165
|
+
// account
|
|
166
|
+
'user-info': 30,
|
|
167
|
+
'accounts': 7.5,
|
|
168
|
+
'accounts/{accountId}': 7.5,
|
|
169
|
+
'accounts/ledgers': 3,
|
|
170
|
+
'hf/accounts/ledgers': 2,
|
|
171
|
+
'hf/margin/account/ledgers': 2,
|
|
172
|
+
'transaction-history': 3,
|
|
173
|
+
'sub/user': 30,
|
|
174
|
+
'sub-accounts/{subUserId}': 22.5,
|
|
175
|
+
'sub-accounts': 30,
|
|
176
|
+
'sub/api-key': 30,
|
|
177
|
+
// funding
|
|
178
|
+
'margin/account': 40,
|
|
179
|
+
'margin/accounts': 15,
|
|
180
|
+
'isolated/accounts': 15,
|
|
181
|
+
'deposit-addresses': 7.5,
|
|
182
|
+
'deposits': 7.5,
|
|
183
|
+
'hist-deposits': 7.5,
|
|
184
|
+
'withdrawals': 30,
|
|
185
|
+
'hist-withdrawals': 30,
|
|
186
|
+
'withdrawals/quotas': 30,
|
|
187
|
+
'accounts/transferable': 30,
|
|
188
|
+
'transfer-list': 30,
|
|
189
|
+
'base-fee': 3,
|
|
190
|
+
'trade-fees': 3,
|
|
191
|
+
// spot trading
|
|
192
|
+
'market/orderbook/level{level}': 3,
|
|
193
|
+
'market/orderbook/level2': 3,
|
|
194
|
+
'market/orderbook/level3': 3,
|
|
195
|
+
'hf/orders/active': 2,
|
|
196
|
+
'hf/orders/active/symbols': 2,
|
|
197
|
+
'hf/orders/done': 2,
|
|
198
|
+
'hf/orders/{orderId}': 2,
|
|
199
|
+
'hf/orders/client-order/{clientOid}': 2,
|
|
200
|
+
'hf/orders/dead-cancel-all/query': 2,
|
|
201
|
+
'hf/fills': 2,
|
|
202
|
+
'orders': 2,
|
|
203
|
+
'limit/orders': 3,
|
|
204
|
+
'orders/{orderId}': 2,
|
|
205
|
+
'order/client-order/{clientOid}': 3,
|
|
206
|
+
'fills': 10,
|
|
207
|
+
'limit/fills': 20,
|
|
208
|
+
'stop-order': 8,
|
|
209
|
+
'stop-order/{orderId}': 3,
|
|
210
|
+
'stop-order/queryOrderByClientOid': 3,
|
|
211
|
+
'oco/order/{orderId}': 2,
|
|
212
|
+
'oco/order/details/{orderId}': 2,
|
|
213
|
+
'oco/client-order/{clientOid}': 2,
|
|
214
|
+
'oco/orders': 2,
|
|
215
|
+
// margin trading
|
|
216
|
+
'hf/margin/orders/active': 4,
|
|
217
|
+
'hf/margin/orders/done': 10,
|
|
218
|
+
'hf/margin/orders/{orderId}': 4,
|
|
219
|
+
'hf/margin/orders/client-order/{clientOid}': 5,
|
|
220
|
+
'hf/margin/fills': 5,
|
|
221
|
+
'etf/info': 25,
|
|
222
|
+
'margin/currencies': 20,
|
|
223
|
+
'risk/limit/strategy': 20,
|
|
224
|
+
'isolated/symbols': 20,
|
|
225
|
+
'isolated/account/{symbol}': 50,
|
|
226
|
+
'margin/borrow': 15,
|
|
227
|
+
'margin/repay': 15,
|
|
228
|
+
'project/list': 10,
|
|
229
|
+
'project/marketInterestRate': 7.5,
|
|
230
|
+
'redeem/orders': 10,
|
|
231
|
+
'purchase/orders': 10, // 10SW
|
|
232
|
+
},
|
|
233
|
+
'post': {
|
|
234
|
+
// account
|
|
235
|
+
'sub/user/created': 22.5,
|
|
236
|
+
'sub/api-key': 30,
|
|
237
|
+
'sub/api-key/update': 45,
|
|
238
|
+
// funding
|
|
239
|
+
'deposit-addresses': 30,
|
|
240
|
+
'withdrawals': 7.5,
|
|
241
|
+
'accounts/universal-transfer': 6,
|
|
242
|
+
'accounts/sub-transfer': 45,
|
|
243
|
+
'accounts/inner-transfer': 15,
|
|
244
|
+
'transfer-out': 30,
|
|
245
|
+
'transfer-in': 30,
|
|
246
|
+
// spot trading
|
|
247
|
+
'hf/orders': 1,
|
|
248
|
+
'hf/orders/test': 1,
|
|
249
|
+
'hf/orders/sync': 1,
|
|
250
|
+
'hf/orders/multi': 1,
|
|
251
|
+
'hf/orders/multi/sync': 1,
|
|
252
|
+
'hf/orders/alter': 3,
|
|
253
|
+
'hf/orders/dead-cancel-all': 2,
|
|
254
|
+
'orders': 2,
|
|
255
|
+
'orders/test': 2,
|
|
256
|
+
'orders/multi': 3,
|
|
257
|
+
'stop-order': 2,
|
|
258
|
+
'oco/order': 2,
|
|
259
|
+
// margin trading
|
|
260
|
+
'hf/margin/order': 5,
|
|
261
|
+
'hf/margin/order/test': 5,
|
|
262
|
+
'margin/order': 5,
|
|
263
|
+
'margin/order/test': 5,
|
|
264
|
+
'margin/borrow': 15,
|
|
265
|
+
'margin/repay': 10,
|
|
266
|
+
'purchase': 15,
|
|
267
|
+
'redeem': 15,
|
|
268
|
+
'lend/purchase/update': 10,
|
|
269
|
+
// ws
|
|
270
|
+
'bullet-private': 10, // 10SW
|
|
271
|
+
},
|
|
272
|
+
'delete': {
|
|
273
|
+
// account
|
|
274
|
+
'sub/api-key': 45,
|
|
275
|
+
// funding
|
|
276
|
+
'withdrawals/{withdrawalId}': 30,
|
|
277
|
+
// spot trading
|
|
278
|
+
'hf/orders/{orderId}': 1,
|
|
279
|
+
'hf/orders/sync/{orderId}': 1,
|
|
280
|
+
'hf/orders/client-order/{clientOid}': 1,
|
|
281
|
+
'hf/orders/sync/client-order/{clientOid}': 1,
|
|
282
|
+
'hf/orders/cancel/{orderId}': 2,
|
|
283
|
+
'hf/orders': 2,
|
|
284
|
+
'hf/orders/cancelAll': 30,
|
|
285
|
+
'orders/{orderId}': 3,
|
|
286
|
+
'order/client-order/{clientOid}': 5,
|
|
287
|
+
'orders': 20,
|
|
288
|
+
'stop-order/{orderId}': 3,
|
|
289
|
+
'stop-order/cancelOrderByClientOid': 5,
|
|
290
|
+
'stop-order/cancel': 3,
|
|
291
|
+
'oco/order/{orderId}': 3,
|
|
292
|
+
'oco/client-order/{clientOid}': 3,
|
|
293
|
+
'oco/orders': 3,
|
|
294
|
+
// margin trading
|
|
295
|
+
'hf/margin/orders/{orderId}': 5,
|
|
296
|
+
'hf/margin/orders/client-order/{clientOid}': 5,
|
|
297
|
+
'hf/margin/orders': 10, // 10SW
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
'futuresPublic': {
|
|
301
|
+
'get': {
|
|
302
|
+
'contracts/active': 4.5,
|
|
303
|
+
'contracts/{symbol}': 4.5,
|
|
304
|
+
'ticker': 3,
|
|
305
|
+
'level2/snapshot': 4.5,
|
|
306
|
+
'level2/depth20': 7.5,
|
|
307
|
+
'level2/depth100': 15,
|
|
308
|
+
'trade/history': 7.5,
|
|
309
|
+
'kline/query': 4.5,
|
|
310
|
+
'interest/query': 7.5,
|
|
311
|
+
'index/query': 3,
|
|
312
|
+
'mark-price/{symbol}/current': 4.5,
|
|
313
|
+
'premium/query': 4.5,
|
|
314
|
+
'trade-statistics': 4.5,
|
|
315
|
+
'funding-rate/{symbol}/current': 3,
|
|
316
|
+
'timestamp': 3,
|
|
317
|
+
'status': 6,
|
|
318
|
+
// ?
|
|
319
|
+
'level2/message/query': 1.3953,
|
|
320
|
+
},
|
|
321
|
+
'post': {
|
|
322
|
+
// ws
|
|
323
|
+
'bullet-public': 15, // 10PW
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
'futuresPrivate': {
|
|
327
|
+
'get': {
|
|
328
|
+
// account
|
|
329
|
+
'transaction-history': 3,
|
|
330
|
+
// funding
|
|
331
|
+
'account-overview': 7.5,
|
|
332
|
+
'account-overview-all': 9,
|
|
333
|
+
'transfer-list': 30,
|
|
334
|
+
// futures
|
|
335
|
+
'orders': 3,
|
|
336
|
+
'stopOrders': 9,
|
|
337
|
+
'recentDoneOrders': 7.5,
|
|
338
|
+
'orders/{orderId}': 7.5,
|
|
339
|
+
'orders/byClientOid': 7.5,
|
|
340
|
+
'fills': 7.5,
|
|
341
|
+
'recentFills': 4.5,
|
|
342
|
+
'openOrderStatistics': 15,
|
|
343
|
+
'position': 3,
|
|
344
|
+
'positions': 3,
|
|
345
|
+
'contracts/risk-limit/{symbol}': 7.5,
|
|
346
|
+
'funding-history': 7.5, // 5FW
|
|
347
|
+
},
|
|
348
|
+
'post': {
|
|
349
|
+
// funding
|
|
350
|
+
'transfer-out': 30,
|
|
351
|
+
'transfer-in': 30,
|
|
352
|
+
// futures
|
|
353
|
+
'orders': 3,
|
|
354
|
+
'orders/test': 3,
|
|
355
|
+
'position/margin/auto-deposit-status': 6,
|
|
356
|
+
'position/margin/deposit-margin': 6,
|
|
357
|
+
'position/risk-limit-level/change': 6,
|
|
358
|
+
// ws
|
|
359
|
+
'bullet-private': 15, // 10FW
|
|
360
|
+
},
|
|
361
|
+
'delete': {
|
|
362
|
+
'orders/{orderId}': 1.5,
|
|
363
|
+
'orders/client-order/{clientOid}': 1.5,
|
|
364
|
+
'orders': 45,
|
|
365
|
+
'stopOrders': 22.5, // 15FW
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
'webExchange': {
|
|
369
|
+
'get': {
|
|
370
|
+
'currency/currency/chain-info': 1, // this is temporary from webApi
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
'timeframes': {
|
|
375
|
+
'1m': '1min',
|
|
376
|
+
'3m': '3min',
|
|
377
|
+
'5m': '5min',
|
|
378
|
+
'15m': '15min',
|
|
379
|
+
'30m': '30min',
|
|
380
|
+
'1h': '1hour',
|
|
381
|
+
'2h': '2hour',
|
|
382
|
+
'4h': '4hour',
|
|
383
|
+
'6h': '6hour',
|
|
384
|
+
'8h': '8hour',
|
|
385
|
+
'12h': '12hour',
|
|
386
|
+
'1d': '1day',
|
|
387
|
+
'1w': '1week',
|
|
388
|
+
},
|
|
389
|
+
'precisionMode': number.TICK_SIZE,
|
|
390
|
+
'exceptions': {
|
|
391
|
+
'exact': {
|
|
392
|
+
'order not exist': errors.OrderNotFound,
|
|
393
|
+
'order not exist.': errors.OrderNotFound,
|
|
394
|
+
'order_not_exist': errors.OrderNotFound,
|
|
395
|
+
'order_not_exist_or_not_allow_to_cancel': errors.InvalidOrder,
|
|
396
|
+
'Order size below the minimum requirement.': errors.InvalidOrder,
|
|
397
|
+
'The withdrawal amount is below the minimum requirement.': errors.ExchangeError,
|
|
398
|
+
'Unsuccessful! Exceeded the max. funds out-transfer limit': errors.InsufficientFunds,
|
|
399
|
+
'400': errors.BadRequest,
|
|
400
|
+
'401': errors.AuthenticationError,
|
|
401
|
+
'403': errors.NotSupported,
|
|
402
|
+
'404': errors.NotSupported,
|
|
403
|
+
'405': errors.NotSupported,
|
|
404
|
+
'415': errors.NotSupported,
|
|
405
|
+
'429': errors.RateLimitExceeded,
|
|
406
|
+
'500': errors.ExchangeNotAvailable,
|
|
407
|
+
'503': errors.ExchangeNotAvailable,
|
|
408
|
+
'101030': errors.PermissionDenied,
|
|
409
|
+
'103000': errors.InvalidOrder,
|
|
410
|
+
'130101': errors.BadRequest,
|
|
411
|
+
'130102': errors.ExchangeError,
|
|
412
|
+
'130103': errors.OrderNotFound,
|
|
413
|
+
'130104': errors.ExchangeError,
|
|
414
|
+
'130105': errors.InsufficientFunds,
|
|
415
|
+
'130106': errors.NotSupported,
|
|
416
|
+
'130107': errors.ExchangeError,
|
|
417
|
+
'130108': errors.OrderNotFound,
|
|
418
|
+
'130201': errors.PermissionDenied,
|
|
419
|
+
'130202': errors.ExchangeError,
|
|
420
|
+
'130203': errors.InsufficientFunds,
|
|
421
|
+
'130204': errors.BadRequest,
|
|
422
|
+
'200004': errors.InsufficientFunds,
|
|
423
|
+
'210014': errors.InvalidOrder,
|
|
424
|
+
'210021': errors.InsufficientFunds,
|
|
425
|
+
'230003': errors.InsufficientFunds,
|
|
426
|
+
'260000': errors.InvalidAddress,
|
|
427
|
+
'260100': errors.InsufficientFunds,
|
|
428
|
+
'300000': errors.InvalidOrder,
|
|
429
|
+
'400000': errors.BadSymbol,
|
|
430
|
+
'400001': errors.AuthenticationError,
|
|
431
|
+
'400002': errors.InvalidNonce,
|
|
432
|
+
'400003': errors.AuthenticationError,
|
|
433
|
+
'400004': errors.AuthenticationError,
|
|
434
|
+
'400005': errors.AuthenticationError,
|
|
435
|
+
'400006': errors.AuthenticationError,
|
|
436
|
+
'400007': errors.AuthenticationError,
|
|
437
|
+
'400008': errors.NotSupported,
|
|
438
|
+
'400100': errors.BadRequest,
|
|
439
|
+
'400200': errors.InvalidOrder,
|
|
440
|
+
'400350': errors.InvalidOrder,
|
|
441
|
+
'400370': errors.InvalidOrder,
|
|
442
|
+
'400400': errors.BadRequest,
|
|
443
|
+
'400500': errors.InvalidOrder,
|
|
444
|
+
'400600': errors.BadSymbol,
|
|
445
|
+
'400760': errors.InvalidOrder,
|
|
446
|
+
'401000': errors.BadRequest,
|
|
447
|
+
'411100': errors.AccountSuspended,
|
|
448
|
+
'415000': errors.BadRequest,
|
|
449
|
+
'400303': errors.PermissionDenied,
|
|
450
|
+
'500000': errors.ExchangeNotAvailable,
|
|
451
|
+
'260220': errors.InvalidAddress,
|
|
452
|
+
'900014': errors.BadRequest, // {"code":"900014","msg":"Invalid chainId"}
|
|
453
|
+
},
|
|
454
|
+
'broad': {
|
|
455
|
+
'Exceeded the access frequency': errors.RateLimitExceeded,
|
|
456
|
+
'require more permission': errors.PermissionDenied,
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
'fees': {
|
|
460
|
+
'trading': {
|
|
461
|
+
'tierBased': true,
|
|
462
|
+
'percentage': true,
|
|
463
|
+
'taker': this.parseNumber('0.001'),
|
|
464
|
+
'maker': this.parseNumber('0.001'),
|
|
465
|
+
'tiers': {
|
|
466
|
+
'taker': [
|
|
467
|
+
[this.parseNumber('0'), this.parseNumber('0.001')],
|
|
468
|
+
[this.parseNumber('50'), this.parseNumber('0.001')],
|
|
469
|
+
[this.parseNumber('200'), this.parseNumber('0.0009')],
|
|
470
|
+
[this.parseNumber('500'), this.parseNumber('0.0008')],
|
|
471
|
+
[this.parseNumber('1000'), this.parseNumber('0.0007')],
|
|
472
|
+
[this.parseNumber('2000'), this.parseNumber('0.0007')],
|
|
473
|
+
[this.parseNumber('4000'), this.parseNumber('0.0006')],
|
|
474
|
+
[this.parseNumber('8000'), this.parseNumber('0.0005')],
|
|
475
|
+
[this.parseNumber('15000'), this.parseNumber('0.00045')],
|
|
476
|
+
[this.parseNumber('25000'), this.parseNumber('0.0004')],
|
|
477
|
+
[this.parseNumber('40000'), this.parseNumber('0.00035')],
|
|
478
|
+
[this.parseNumber('60000'), this.parseNumber('0.0003')],
|
|
479
|
+
[this.parseNumber('80000'), this.parseNumber('0.00025')],
|
|
480
|
+
],
|
|
481
|
+
'maker': [
|
|
482
|
+
[this.parseNumber('0'), this.parseNumber('0.001')],
|
|
483
|
+
[this.parseNumber('50'), this.parseNumber('0.0009')],
|
|
484
|
+
[this.parseNumber('200'), this.parseNumber('0.0007')],
|
|
485
|
+
[this.parseNumber('500'), this.parseNumber('0.0005')],
|
|
486
|
+
[this.parseNumber('1000'), this.parseNumber('0.0003')],
|
|
487
|
+
[this.parseNumber('2000'), this.parseNumber('0')],
|
|
488
|
+
[this.parseNumber('4000'), this.parseNumber('0')],
|
|
489
|
+
[this.parseNumber('8000'), this.parseNumber('0')],
|
|
490
|
+
[this.parseNumber('15000'), this.parseNumber('-0.00005')],
|
|
491
|
+
[this.parseNumber('25000'), this.parseNumber('-0.00005')],
|
|
492
|
+
[this.parseNumber('40000'), this.parseNumber('-0.00005')],
|
|
493
|
+
[this.parseNumber('60000'), this.parseNumber('-0.00005')],
|
|
494
|
+
[this.parseNumber('80000'), this.parseNumber('-0.00005')],
|
|
495
|
+
],
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
'funding': {
|
|
499
|
+
'tierBased': false,
|
|
500
|
+
'percentage': false,
|
|
501
|
+
'withdraw': {},
|
|
502
|
+
'deposit': {},
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
'commonCurrencies': {
|
|
506
|
+
'BIFI': 'BIFIF',
|
|
507
|
+
'VAI': 'VAIOT',
|
|
508
|
+
'WAX': 'WAXP',
|
|
509
|
+
},
|
|
510
|
+
'options': {
|
|
511
|
+
'version': 'v1',
|
|
512
|
+
'symbolSeparator': '-',
|
|
513
|
+
'fetchMyTradesMethod': 'private_get_fills',
|
|
514
|
+
'fetchCurrencies': {
|
|
515
|
+
'webApiEnable': true,
|
|
516
|
+
'webApiRetries': 1,
|
|
517
|
+
'webApiMuteFailure': true,
|
|
518
|
+
},
|
|
519
|
+
'fetchMarkets': {
|
|
520
|
+
'fetchTickersFees': true,
|
|
521
|
+
},
|
|
522
|
+
'withdraw': {
|
|
523
|
+
'includeFee': false,
|
|
524
|
+
},
|
|
525
|
+
// endpoint versions
|
|
526
|
+
'versions': {
|
|
527
|
+
'public': {
|
|
528
|
+
'GET': {
|
|
529
|
+
// spot trading
|
|
530
|
+
'currencies': 'v3',
|
|
531
|
+
'currencies/{currency}': 'v3',
|
|
532
|
+
'symbols': 'v2',
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
'private': {
|
|
536
|
+
'GET': {
|
|
537
|
+
// account
|
|
538
|
+
'user-info': 'v2',
|
|
539
|
+
'hf/margin/account/ledgers': 'v3',
|
|
540
|
+
'sub/user': 'v2',
|
|
541
|
+
'sub-accounts': 'v2',
|
|
542
|
+
// funding
|
|
543
|
+
'margin/accounts': 'v3',
|
|
544
|
+
'isolated/accounts': 'v3',
|
|
545
|
+
// 'deposit-addresses': 'v2',
|
|
546
|
+
'deposit-addresses': 'v1',
|
|
547
|
+
// spot trading
|
|
548
|
+
'market/orderbook/level2': 'v3',
|
|
549
|
+
'market/orderbook/level3': 'v3',
|
|
550
|
+
'market/orderbook/level{level}': 'v3',
|
|
551
|
+
'oco/order/{orderId}': 'v3',
|
|
552
|
+
'oco/order/details/{orderId}': 'v3',
|
|
553
|
+
'oco/client-order/{clientOid}': 'v3',
|
|
554
|
+
'oco/orders': 'v3',
|
|
555
|
+
// margin trading
|
|
556
|
+
'hf/margin/orders/active': 'v3',
|
|
557
|
+
'hf/margin/orders/done': 'v3',
|
|
558
|
+
'hf/margin/orders/{orderId}': 'v3',
|
|
559
|
+
'hf/margin/orders/client-order/{clientOid}': 'v3',
|
|
560
|
+
'hf/margin/fills': 'v3',
|
|
561
|
+
'etf/info': 'v3',
|
|
562
|
+
'margin/currencies': 'v3',
|
|
563
|
+
'margin/borrow': 'v3',
|
|
564
|
+
'margin/repay': 'v3',
|
|
565
|
+
'project/list': 'v3',
|
|
566
|
+
'project/marketInterestRate': 'v3',
|
|
567
|
+
'redeem/orders': 'v3',
|
|
568
|
+
'purchase/orders': 'v3',
|
|
569
|
+
},
|
|
570
|
+
'POST': {
|
|
571
|
+
// account
|
|
572
|
+
'sub/user/created': 'v2',
|
|
573
|
+
// funding
|
|
574
|
+
'accounts/universal-transfer': 'v3',
|
|
575
|
+
'accounts/sub-transfer': 'v2',
|
|
576
|
+
'accounts/inner-transfer': 'v2',
|
|
577
|
+
'transfer-out': 'v3',
|
|
578
|
+
// spot trading
|
|
579
|
+
'oco/order': 'v3',
|
|
580
|
+
// margin trading
|
|
581
|
+
'hf/margin/order': 'v3',
|
|
582
|
+
'hf/margin/order/test': 'v3',
|
|
583
|
+
'margin/borrow': 'v3',
|
|
584
|
+
'margin/repay': 'v3',
|
|
585
|
+
'purchase': 'v3',
|
|
586
|
+
'redeem': 'v3',
|
|
587
|
+
'lend/purchase/update': 'v3',
|
|
588
|
+
},
|
|
589
|
+
'DELETE': {
|
|
590
|
+
// account
|
|
591
|
+
// funding
|
|
592
|
+
// spot trading
|
|
593
|
+
'hf/margin/orders/{orderId}': 'v3',
|
|
594
|
+
'hf/margin/orders/client-order/{clientOid}': 'v3',
|
|
595
|
+
'hf/margin/orders': 'v3',
|
|
596
|
+
'oco/order/{orderId}': 'v3',
|
|
597
|
+
'oco/client-order/{clientOid}': 'v3',
|
|
598
|
+
'oco/orders': 'v3',
|
|
599
|
+
// margin trading
|
|
600
|
+
},
|
|
601
|
+
},
|
|
602
|
+
'futuresPrivate': {
|
|
603
|
+
'POST': {
|
|
604
|
+
'transfer-out': 'v3',
|
|
605
|
+
},
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
'partner': {
|
|
609
|
+
// the support for spot and future exchanges as separate settings
|
|
610
|
+
'spot': {
|
|
611
|
+
'id': 'ccxt',
|
|
612
|
+
'key': '9e58cc35-5b5e-4133-92ec-166e3f077cb8',
|
|
613
|
+
},
|
|
614
|
+
'future': {
|
|
615
|
+
'id': 'ccxtfutures',
|
|
616
|
+
'key': '1b327198-f30c-4f14-a0ac-918871282f15',
|
|
617
|
+
},
|
|
618
|
+
// exchange-wide settings are also supported
|
|
619
|
+
// 'id': 'ccxt'
|
|
620
|
+
// 'key': '9e58cc35-5b5e-4133-92ec-166e3f077cb8',
|
|
621
|
+
},
|
|
622
|
+
'accountsByType': {
|
|
623
|
+
'spot': 'trade',
|
|
624
|
+
'margin': 'margin',
|
|
625
|
+
'cross': 'margin',
|
|
626
|
+
'isolated': 'isolated',
|
|
627
|
+
'main': 'main',
|
|
628
|
+
'funding': 'main',
|
|
629
|
+
'future': 'contract',
|
|
630
|
+
'swap': 'contract',
|
|
631
|
+
'mining': 'pool',
|
|
632
|
+
'hf': 'trade_hf',
|
|
633
|
+
},
|
|
634
|
+
'networks': {
|
|
635
|
+
'BTC': 'btc',
|
|
636
|
+
'BTCNATIVESEGWIT': 'bech32',
|
|
637
|
+
'ERC20': 'eth',
|
|
638
|
+
'TRC20': 'trx',
|
|
639
|
+
'HRC20': 'heco',
|
|
640
|
+
'MATIC': 'matic',
|
|
641
|
+
'KCC': 'kcc',
|
|
642
|
+
'SOL': 'sol',
|
|
643
|
+
'ALGO': 'algo',
|
|
644
|
+
'EOS': 'eos',
|
|
645
|
+
'BEP20': 'bsc',
|
|
646
|
+
'BEP2': 'bnb',
|
|
647
|
+
'ARBONE': 'arbitrum',
|
|
648
|
+
'AVAXX': 'avax',
|
|
649
|
+
'AVAXC': 'avaxc',
|
|
650
|
+
'TLOS': 'tlos',
|
|
651
|
+
'CFX': 'cfx',
|
|
652
|
+
'ACA': 'aca',
|
|
653
|
+
'OPTIMISM': 'optimism',
|
|
654
|
+
'ONT': 'ont',
|
|
655
|
+
'GLMR': 'glmr',
|
|
656
|
+
'CSPR': 'cspr',
|
|
657
|
+
'KLAY': 'klay',
|
|
658
|
+
'XRD': 'xrd',
|
|
659
|
+
'RVN': 'rvn',
|
|
660
|
+
'NEAR': 'near',
|
|
661
|
+
'APT': 'aptos',
|
|
662
|
+
'ETHW': 'ethw',
|
|
663
|
+
'TON': 'ton',
|
|
664
|
+
'BCH': 'bch',
|
|
665
|
+
'BSV': 'bchsv',
|
|
666
|
+
'BCHA': 'bchabc',
|
|
667
|
+
'OSMO': 'osmo',
|
|
668
|
+
'NANO': 'nano',
|
|
669
|
+
'XLM': 'xlm',
|
|
670
|
+
'VET': 'vet',
|
|
671
|
+
'IOST': 'iost',
|
|
672
|
+
'ZIL': 'zil',
|
|
673
|
+
'XRP': 'xrp',
|
|
674
|
+
'TOMO': 'tomo',
|
|
675
|
+
'XMR': 'xmr',
|
|
676
|
+
'COTI': 'coti',
|
|
677
|
+
'XTZ': 'xtz',
|
|
678
|
+
'ADA': 'ada',
|
|
679
|
+
'WAX': 'waxp',
|
|
680
|
+
'THETA': 'theta',
|
|
681
|
+
'ONE': 'one',
|
|
682
|
+
'IOTEX': 'iotx',
|
|
683
|
+
'NULS': 'nuls',
|
|
684
|
+
'KSM': 'ksm',
|
|
685
|
+
'LTC': 'ltc',
|
|
686
|
+
'WAVES': 'waves',
|
|
687
|
+
'DOT': 'dot',
|
|
688
|
+
'STEEM': 'steem',
|
|
689
|
+
'QTUM': 'qtum',
|
|
690
|
+
'DOGE': 'doge',
|
|
691
|
+
'FIL': 'fil',
|
|
692
|
+
'XYM': 'xym',
|
|
693
|
+
'FLUX': 'flux',
|
|
694
|
+
'ATOM': 'atom',
|
|
695
|
+
'XDC': 'xdc',
|
|
696
|
+
'KDA': 'kda',
|
|
697
|
+
'ICP': 'icp',
|
|
698
|
+
'CELO': 'celo',
|
|
699
|
+
'LSK': 'lsk',
|
|
700
|
+
'VSYS': 'vsys',
|
|
701
|
+
'KAR': 'kar',
|
|
702
|
+
'XCH': 'xch',
|
|
703
|
+
'FLOW': 'flow',
|
|
704
|
+
'BAND': 'band',
|
|
705
|
+
'EGLD': 'egld',
|
|
706
|
+
'HBAR': 'hbar',
|
|
707
|
+
'XPR': 'xpr',
|
|
708
|
+
'AR': 'ar',
|
|
709
|
+
'FTM': 'ftm',
|
|
710
|
+
'KAVA': 'kava',
|
|
711
|
+
'KMA': 'kma',
|
|
712
|
+
'XEC': 'xec',
|
|
713
|
+
'IOTA': 'iota',
|
|
714
|
+
'HNT': 'hnt',
|
|
715
|
+
'ASTR': 'astr',
|
|
716
|
+
'PDEX': 'pdex',
|
|
717
|
+
'METIS': 'metis',
|
|
718
|
+
'ZEC': 'zec',
|
|
719
|
+
'POKT': 'pokt',
|
|
720
|
+
'OASYS': 'oas',
|
|
721
|
+
'OASIS': 'oasis',
|
|
722
|
+
'ETC': 'etc',
|
|
723
|
+
'AKT': 'akt',
|
|
724
|
+
'FSN': 'fsn',
|
|
725
|
+
'SCRT': 'scrt',
|
|
726
|
+
'CFG': 'cfg',
|
|
727
|
+
'ICX': 'icx',
|
|
728
|
+
'KMD': 'kmd',
|
|
729
|
+
'NEM': 'NEM',
|
|
730
|
+
'STX': 'stx',
|
|
731
|
+
'DGB': 'dgb',
|
|
732
|
+
'DCR': 'dcr',
|
|
733
|
+
'CKB': 'ckb',
|
|
734
|
+
'ELA': 'ela',
|
|
735
|
+
'HYDRA': 'hydra',
|
|
736
|
+
'BTM': 'btm',
|
|
737
|
+
'KARDIA': 'kai',
|
|
738
|
+
'SXP': 'sxp',
|
|
739
|
+
'NEBL': 'nebl',
|
|
740
|
+
'ZEN': 'zen',
|
|
741
|
+
'SDN': 'sdn',
|
|
742
|
+
'LTO': 'lto',
|
|
743
|
+
'WEMIX': 'wemix',
|
|
744
|
+
// 'BOBA': 'boba', // tbd
|
|
745
|
+
'EVER': 'ever',
|
|
746
|
+
'BNC': 'bnc',
|
|
747
|
+
'BNCDOT': 'bncdot',
|
|
748
|
+
// 'CMP': 'cmp', // todo: after consensus
|
|
749
|
+
'AION': 'aion',
|
|
750
|
+
'GRIN': 'grin',
|
|
751
|
+
'LOKI': 'loki',
|
|
752
|
+
'QKC': 'qkc',
|
|
753
|
+
'TT': 'TT',
|
|
754
|
+
'PIVX': 'pivx',
|
|
755
|
+
'SERO': 'sero',
|
|
756
|
+
'METER': 'meter',
|
|
757
|
+
'STATEMINE': 'statemine',
|
|
758
|
+
'DVPN': 'dvpn',
|
|
759
|
+
'XPRT': 'xprt',
|
|
760
|
+
'MOVR': 'movr',
|
|
761
|
+
'ERGO': 'ergo',
|
|
762
|
+
'ABBC': 'abbc',
|
|
763
|
+
'DIVI': 'divi',
|
|
764
|
+
'PURA': 'pura',
|
|
765
|
+
'DFI': 'dfi',
|
|
766
|
+
// 'NEO': 'neo', // tbd neo legacy
|
|
767
|
+
'NEON3': 'neon3',
|
|
768
|
+
'DOCK': 'dock',
|
|
769
|
+
'TRUE': 'true',
|
|
770
|
+
'CS': 'cs',
|
|
771
|
+
'ORAI': 'orai',
|
|
772
|
+
// below will be uncommented after consensus
|
|
773
|
+
// 'BITCOINDIAMON': 'bcd',
|
|
774
|
+
// 'BITCOINGOLD': 'btg',
|
|
775
|
+
// 'HTR': 'htr',
|
|
776
|
+
// 'DEROHE': 'derohe',
|
|
777
|
+
// 'NDAU': 'ndau',
|
|
778
|
+
// 'HPB': 'hpb',
|
|
779
|
+
// 'AXE': 'axe',
|
|
780
|
+
// 'BITCOINPRIVATE': 'btcp',
|
|
781
|
+
// 'EDGEWARE': 'edg',
|
|
782
|
+
// 'JUPITER': 'jup',
|
|
783
|
+
// 'VELAS': 'vlx', // vlxevm is different
|
|
784
|
+
// // 'terra' luna lunc TBD
|
|
785
|
+
// 'DIGITALBITS': 'xdb',
|
|
786
|
+
// // fra is fra-emv on kucoin
|
|
787
|
+
// 'PASTEL': 'psl',
|
|
788
|
+
// // sysevm
|
|
789
|
+
// 'CONCORDIUM': 'ccd',
|
|
790
|
+
// 'AURORA': 'aurora',
|
|
791
|
+
// 'PHA': 'pha', // a.k.a. khala
|
|
792
|
+
// 'PAL': 'pal',
|
|
793
|
+
// 'RSK': 'rbtc',
|
|
794
|
+
// 'NIX': 'nix',
|
|
795
|
+
// 'NIM': 'nim',
|
|
796
|
+
// 'NRG': 'nrg',
|
|
797
|
+
// 'RFOX': 'rfox',
|
|
798
|
+
// 'PIONEER': 'neer',
|
|
799
|
+
// 'PIXIE': 'pix',
|
|
800
|
+
// 'ALEPHZERO': 'azero',
|
|
801
|
+
// 'ACHAIN': 'act', // actevm is different
|
|
802
|
+
// 'BOSCOIN': 'bos',
|
|
803
|
+
// 'ELECTRONEUM': 'etn',
|
|
804
|
+
// 'GOCHAIN': 'go',
|
|
805
|
+
// 'SOPHIATX': 'sphtx',
|
|
806
|
+
// 'WANCHAIN': 'wan',
|
|
807
|
+
// 'ZEEPIN': 'zpt',
|
|
808
|
+
// 'MATRIXAI': 'man',
|
|
809
|
+
// 'METADIUM': 'meta',
|
|
810
|
+
// 'METAHASH': 'mhc',
|
|
811
|
+
// // eosc --"eosforce" tbd
|
|
812
|
+
// 'IOTCHAIN': 'itc',
|
|
813
|
+
// 'CONTENTOS': 'cos',
|
|
814
|
+
// 'CPCHAIN': 'cpc',
|
|
815
|
+
// 'INTCHAIN': 'int',
|
|
816
|
+
// // 'DASH': 'dash', tbd digita-cash
|
|
817
|
+
// 'WALTONCHAIN': 'wtc',
|
|
818
|
+
// 'CONSTELLATION': 'dag',
|
|
819
|
+
// 'ONELEDGER': 'olt',
|
|
820
|
+
// 'AIRDAO': 'amb', // a.k.a. AMBROSUS
|
|
821
|
+
// 'ENERGYWEB': 'ewt',
|
|
822
|
+
// 'WAVESENTERPRISE': 'west',
|
|
823
|
+
// 'HYPERCASH': 'hc',
|
|
824
|
+
// 'ENECUUM': 'enq',
|
|
825
|
+
// 'HAVEN': 'xhv',
|
|
826
|
+
// 'CHAINX': 'pcx',
|
|
827
|
+
// // 'FLUXOLD': 'zel', // zel seems old chain (with uppercase FLUX in kucoin UI and with id 'zel')
|
|
828
|
+
// 'BUMO': 'bu',
|
|
829
|
+
// 'DEEPONION': 'onion',
|
|
830
|
+
// 'ULORD': 'ut',
|
|
831
|
+
// 'ASCH': 'xas',
|
|
832
|
+
// 'SOLARIS': 'xlr',
|
|
833
|
+
// 'APOLLO': 'apl',
|
|
834
|
+
// 'PIRATECHAIN': 'arrr',
|
|
835
|
+
// 'ULTRA': 'uos',
|
|
836
|
+
// 'EMONEY': 'ngm',
|
|
837
|
+
// 'AURORACHAIN': 'aoa',
|
|
838
|
+
// 'KLEVER': 'klv',
|
|
839
|
+
// undetermined: xns(insolar), rhoc, luk (luniverse), kts (klimatas), bchn (bitcoin cash node), god (shallow entry), lit (litmus),
|
|
840
|
+
},
|
|
841
|
+
'marginModes': {
|
|
842
|
+
'cross': 'MARGIN_TRADE',
|
|
843
|
+
'isolated': 'MARGIN_ISOLATED_TRADE',
|
|
844
|
+
'spot': 'TRADE',
|
|
845
|
+
},
|
|
846
|
+
},
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
nonce() {
|
|
850
|
+
return this.milliseconds();
|
|
851
|
+
}
|
|
852
|
+
async fetchTime(params = {}) {
|
|
853
|
+
/**
|
|
854
|
+
* @method
|
|
855
|
+
* @name kucoin#fetchTime
|
|
856
|
+
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
857
|
+
* @see https://docs.kucoin.com/#server-time
|
|
858
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
859
|
+
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
860
|
+
*/
|
|
861
|
+
const response = await this.publicGetTimestamp(params);
|
|
862
|
+
//
|
|
863
|
+
// {
|
|
864
|
+
// "code":"200000",
|
|
865
|
+
// "msg":"success",
|
|
866
|
+
// "data":1546837113087
|
|
867
|
+
// }
|
|
868
|
+
//
|
|
869
|
+
return this.safeInteger(response, 'data');
|
|
870
|
+
}
|
|
871
|
+
async fetchStatus(params = {}) {
|
|
872
|
+
/**
|
|
873
|
+
* @method
|
|
874
|
+
* @name kucoin#fetchStatus
|
|
875
|
+
* @description the latest known information on the availability of the exchange API
|
|
876
|
+
* @see https://docs.kucoin.com/#service-status
|
|
877
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
878
|
+
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
|
|
879
|
+
*/
|
|
880
|
+
const response = await this.publicGetStatus(params);
|
|
881
|
+
//
|
|
882
|
+
// {
|
|
883
|
+
// "code":"200000",
|
|
884
|
+
// "data":{
|
|
885
|
+
// "status":"open", //open, close, cancelonly
|
|
886
|
+
// "msg":"upgrade match engine" //remark for operation
|
|
887
|
+
// }
|
|
888
|
+
// }
|
|
889
|
+
//
|
|
890
|
+
const data = this.safeValue(response, 'data', {});
|
|
891
|
+
const status = this.safeString(data, 'status');
|
|
892
|
+
return {
|
|
893
|
+
'status': (status === 'open') ? 'ok' : 'maintenance',
|
|
894
|
+
'updated': undefined,
|
|
895
|
+
'eta': undefined,
|
|
896
|
+
'url': undefined,
|
|
897
|
+
'info': response,
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
async fetchMarkets(params = {}) {
|
|
901
|
+
/**
|
|
902
|
+
* @method
|
|
903
|
+
* @name kucoin#fetchMarkets
|
|
904
|
+
* @description retrieves data on all markets for kucoin
|
|
905
|
+
* @see https://docs.kucoin.com/#get-symbols-list-deprecated
|
|
906
|
+
* @see https://docs.kucoin.com/#get-all-tickers
|
|
907
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
908
|
+
* @returns {object[]} an array of objects representing market data
|
|
909
|
+
*/
|
|
910
|
+
const response = await this.publicGetSymbols(params);
|
|
911
|
+
//
|
|
912
|
+
// {
|
|
913
|
+
// "code": "200000",
|
|
914
|
+
// "data": [
|
|
915
|
+
// {
|
|
916
|
+
// "symbol": "XLM-USDT",
|
|
917
|
+
// "name": "XLM-USDT",
|
|
918
|
+
// "baseCurrency": "XLM",
|
|
919
|
+
// "quoteCurrency": "USDT",
|
|
920
|
+
// "feeCurrency": "USDT",
|
|
921
|
+
// "market": "USDS",
|
|
922
|
+
// "baseMinSize": "0.1",
|
|
923
|
+
// "quoteMinSize": "0.01",
|
|
924
|
+
// "baseMaxSize": "10000000000",
|
|
925
|
+
// "quoteMaxSize": "99999999",
|
|
926
|
+
// "baseIncrement": "0.0001",
|
|
927
|
+
// "quoteIncrement": "0.000001",
|
|
928
|
+
// "priceIncrement": "0.000001",
|
|
929
|
+
// "priceLimitRate": "0.1",
|
|
930
|
+
// "isMarginEnabled": true,
|
|
931
|
+
// "enableTrading": true
|
|
932
|
+
// },
|
|
933
|
+
// ]
|
|
934
|
+
// }
|
|
935
|
+
//
|
|
936
|
+
const data = this.safeValue(response, 'data');
|
|
937
|
+
const options = this.safeValue(this.options, 'fetchMarkets', {});
|
|
938
|
+
const fetchTickersFees = this.safeValue(options, 'fetchTickersFees', true);
|
|
939
|
+
let tickersResponse = {};
|
|
940
|
+
if (fetchTickersFees) {
|
|
941
|
+
tickersResponse = await this.publicGetMarketAllTickers(params);
|
|
942
|
+
}
|
|
943
|
+
//
|
|
944
|
+
// {
|
|
945
|
+
// "code": "200000",
|
|
946
|
+
// "data": {
|
|
947
|
+
// "time":1602832092060,
|
|
948
|
+
// "ticker":[
|
|
949
|
+
// {
|
|
950
|
+
// "symbol": "BTC-USDT", // symbol
|
|
951
|
+
// "symbolName":"BTC-USDT", // Name of trading pairs, it would change after renaming
|
|
952
|
+
// "buy": "11328.9", // bestAsk
|
|
953
|
+
// "sell": "11329", // bestBid
|
|
954
|
+
// "changeRate": "-0.0055", // 24h change rate
|
|
955
|
+
// "changePrice": "-63.6", // 24h change price
|
|
956
|
+
// "high": "11610", // 24h highest price
|
|
957
|
+
// "low": "11200", // 24h lowest price
|
|
958
|
+
// "vol": "2282.70993217", // 24h volume,the aggregated trading volume in BTC
|
|
959
|
+
// "volValue": "25984946.157790431", // 24h total, the trading volume in quote currency of last 24 hours
|
|
960
|
+
// "last": "11328.9", // last price
|
|
961
|
+
// "averagePrice": "11360.66065903", // 24h average transaction price yesterday
|
|
962
|
+
// "takerFeeRate": "0.001", // Basic Taker Fee
|
|
963
|
+
// "makerFeeRate": "0.001", // Basic Maker Fee
|
|
964
|
+
// "takerCoefficient": "1", // Taker Fee Coefficient
|
|
965
|
+
// "makerCoefficient": "1" // Maker Fee Coefficient
|
|
966
|
+
// }
|
|
967
|
+
// ]
|
|
968
|
+
// }
|
|
969
|
+
// }
|
|
970
|
+
//
|
|
971
|
+
const tickersData = this.safeValue(tickersResponse, 'data', {});
|
|
972
|
+
const tickers = this.safeValue(tickersData, 'ticker', []);
|
|
973
|
+
const tickersByMarketId = this.indexBy(tickers, 'symbol');
|
|
974
|
+
const result = [];
|
|
975
|
+
for (let i = 0; i < data.length; i++) {
|
|
976
|
+
const market = data[i];
|
|
977
|
+
const id = this.safeString(market, 'symbol');
|
|
978
|
+
const [baseId, quoteId] = id.split('-');
|
|
979
|
+
const base = this.safeCurrencyCode(baseId);
|
|
980
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
981
|
+
// const quoteIncrement = this.safeNumber (market, 'quoteIncrement');
|
|
982
|
+
const ticker = this.safeValue(tickersByMarketId, id, {});
|
|
983
|
+
const makerFeeRate = this.safeString(ticker, 'makerFeeRate');
|
|
984
|
+
const takerFeeRate = this.safeString(ticker, 'takerFeeRate');
|
|
985
|
+
const makerCoefficient = this.safeString(ticker, 'makerCoefficient');
|
|
986
|
+
const takerCoefficient = this.safeString(ticker, 'takerCoefficient');
|
|
987
|
+
result.push({
|
|
988
|
+
'id': id,
|
|
989
|
+
'symbol': base + '/' + quote,
|
|
990
|
+
'base': base,
|
|
991
|
+
'quote': quote,
|
|
992
|
+
'settle': undefined,
|
|
993
|
+
'baseId': baseId,
|
|
994
|
+
'quoteId': quoteId,
|
|
995
|
+
'settleId': undefined,
|
|
996
|
+
'type': 'spot',
|
|
997
|
+
'spot': true,
|
|
998
|
+
'margin': this.safeValue(market, 'isMarginEnabled'),
|
|
999
|
+
'swap': false,
|
|
1000
|
+
'future': false,
|
|
1001
|
+
'option': false,
|
|
1002
|
+
'active': this.safeValue(market, 'enableTrading'),
|
|
1003
|
+
'contract': false,
|
|
1004
|
+
'linear': undefined,
|
|
1005
|
+
'inverse': undefined,
|
|
1006
|
+
'taker': this.parseNumber(Precise["default"].stringMul(takerFeeRate, takerCoefficient)),
|
|
1007
|
+
'maker': this.parseNumber(Precise["default"].stringMul(makerFeeRate, makerCoefficient)),
|
|
1008
|
+
'contractSize': undefined,
|
|
1009
|
+
'expiry': undefined,
|
|
1010
|
+
'expiryDatetime': undefined,
|
|
1011
|
+
'strike': undefined,
|
|
1012
|
+
'optionType': undefined,
|
|
1013
|
+
'precision': {
|
|
1014
|
+
'amount': this.safeNumber(market, 'baseIncrement'),
|
|
1015
|
+
'price': this.safeNumber(market, 'priceIncrement'),
|
|
1016
|
+
},
|
|
1017
|
+
'limits': {
|
|
1018
|
+
'leverage': {
|
|
1019
|
+
'min': undefined,
|
|
1020
|
+
'max': undefined,
|
|
1021
|
+
},
|
|
1022
|
+
'amount': {
|
|
1023
|
+
'min': this.safeNumber(market, 'baseMinSize'),
|
|
1024
|
+
'max': this.safeNumber(market, 'baseMaxSize'),
|
|
1025
|
+
},
|
|
1026
|
+
'price': {
|
|
1027
|
+
'min': undefined,
|
|
1028
|
+
'max': undefined,
|
|
1029
|
+
},
|
|
1030
|
+
'cost': {
|
|
1031
|
+
'min': this.safeNumber(market, 'quoteMinSize'),
|
|
1032
|
+
'max': this.safeNumber(market, 'quoteMaxSize'),
|
|
1033
|
+
},
|
|
1034
|
+
},
|
|
1035
|
+
'created': undefined,
|
|
1036
|
+
'info': market,
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
return result;
|
|
1040
|
+
}
|
|
1041
|
+
async fetchCurrencies(params = {}) {
|
|
1042
|
+
/**
|
|
1043
|
+
* @method
|
|
1044
|
+
* @name kucoin#fetchCurrencies
|
|
1045
|
+
* @description fetches all available currencies on an exchange
|
|
1046
|
+
* @see https://docs.kucoin.com/#get-currencies
|
|
1047
|
+
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
1048
|
+
* @returns {object} an associative dictionary of currencies
|
|
1049
|
+
*/
|
|
1050
|
+
const promises = [];
|
|
1051
|
+
promises.push(this.publicGetCurrencies(params));
|
|
1052
|
+
//
|
|
1053
|
+
// {
|
|
1054
|
+
// "code":"200000",
|
|
1055
|
+
// "data":[
|
|
1056
|
+
// {
|
|
1057
|
+
// "currency":"CSP",
|
|
1058
|
+
// "name":"CSP",
|
|
1059
|
+
// "fullName":"Caspian",
|
|
1060
|
+
// "precision":8,
|
|
1061
|
+
// "confirms":null,
|
|
1062
|
+
// "contractAddress":null,
|
|
1063
|
+
// "isMarginEnabled":false,
|
|
1064
|
+
// "isDebitEnabled":false,
|
|
1065
|
+
// "chains":[
|
|
1066
|
+
// {
|
|
1067
|
+
// "chainName":"ERC20",
|
|
1068
|
+
// "chain":"eth",
|
|
1069
|
+
// "withdrawalMinSize":"2999",
|
|
1070
|
+
// "withdrawalMinFee":"2999",
|
|
1071
|
+
// "isWithdrawEnabled":false,
|
|
1072
|
+
// "isDepositEnabled":false,
|
|
1073
|
+
// "confirms":12,
|
|
1074
|
+
// "preConfirms":12,
|
|
1075
|
+
// "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
|
|
1076
|
+
// "depositFeeRate": "0.001", // present for some currencies/networks
|
|
1077
|
+
// }
|
|
1078
|
+
// ]
|
|
1079
|
+
// },
|
|
1080
|
+
// }
|
|
1081
|
+
//
|
|
1082
|
+
promises.push(this.fetchWebEndpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', true));
|
|
1083
|
+
//
|
|
1084
|
+
// {
|
|
1085
|
+
// "success": true,
|
|
1086
|
+
// "code": "200",
|
|
1087
|
+
// "msg": "success",
|
|
1088
|
+
// "retry": false,
|
|
1089
|
+
// "data": [
|
|
1090
|
+
// {
|
|
1091
|
+
// "status": "enabled",
|
|
1092
|
+
// "currency": "BTC",
|
|
1093
|
+
// "isChainEnabled": "true",
|
|
1094
|
+
// "chain": "btc",
|
|
1095
|
+
// "chainName": "BTC",
|
|
1096
|
+
// "chainFullName": "Bitcoin",
|
|
1097
|
+
// "walletPrecision": "8",
|
|
1098
|
+
// "isDepositEnabled": "true",
|
|
1099
|
+
// "depositMinSize": "0.00005",
|
|
1100
|
+
// "confirmationCount": "2",
|
|
1101
|
+
// "isWithdrawEnabled": "true",
|
|
1102
|
+
// "withdrawMinSize": "0.001",
|
|
1103
|
+
// "withdrawMinFee": "0.0005",
|
|
1104
|
+
// "withdrawFeeRate": "0",
|
|
1105
|
+
// "depositDisabledTip": "Wallet Maintenance",
|
|
1106
|
+
// "preDepositTipEnabled": "true",
|
|
1107
|
+
// "preDepositTip": "Do not transfer from ETH network directly",
|
|
1108
|
+
// "withdrawDisabledTip": "",
|
|
1109
|
+
// "preWithdrawTipEnabled": "false",
|
|
1110
|
+
// "preWithdrawTip": "",
|
|
1111
|
+
// "orgAddress": "",
|
|
1112
|
+
// "userAddressName": "Memo",
|
|
1113
|
+
// },
|
|
1114
|
+
// ]
|
|
1115
|
+
// }
|
|
1116
|
+
//
|
|
1117
|
+
const responses = await Promise.all(promises);
|
|
1118
|
+
const currenciesResponse = this.safeValue(responses, 0, {});
|
|
1119
|
+
const currenciesData = this.safeValue(currenciesResponse, 'data', []);
|
|
1120
|
+
const additionalResponse = this.safeValue(responses, 1, {});
|
|
1121
|
+
const additionalData = this.safeValue(additionalResponse, 'data', []);
|
|
1122
|
+
const additionalDataGrouped = this.groupBy(additionalData, 'currency');
|
|
1123
|
+
const result = {};
|
|
1124
|
+
for (let i = 0; i < currenciesData.length; i++) {
|
|
1125
|
+
const entry = currenciesData[i];
|
|
1126
|
+
const id = this.safeString(entry, 'currency');
|
|
1127
|
+
const name = this.safeString(entry, 'fullName');
|
|
1128
|
+
const code = this.safeCurrencyCode(id);
|
|
1129
|
+
let isWithdrawEnabled = undefined;
|
|
1130
|
+
let isDepositEnabled = undefined;
|
|
1131
|
+
const networks = {};
|
|
1132
|
+
const chains = this.safeValue(entry, 'chains', []);
|
|
1133
|
+
const extraChainsData = this.indexBy(this.safeValue(additionalDataGrouped, id, []), 'chain');
|
|
1134
|
+
const rawPrecision = this.safeString(entry, 'precision');
|
|
1135
|
+
const precision = this.parseNumber(this.parsePrecision(rawPrecision));
|
|
1136
|
+
const chainsLength = chains.length;
|
|
1137
|
+
if (!chainsLength) {
|
|
1138
|
+
// https://t.me/KuCoin_API/173118
|
|
1139
|
+
isWithdrawEnabled = false;
|
|
1140
|
+
isDepositEnabled = false;
|
|
1141
|
+
}
|
|
1142
|
+
for (let j = 0; j < chainsLength; j++) {
|
|
1143
|
+
const chain = chains[j];
|
|
1144
|
+
const chainId = this.safeString(chain, 'chainId');
|
|
1145
|
+
const networkCode = this.networkIdToCode(chainId);
|
|
1146
|
+
const chainWithdrawEnabled = this.safeValue(chain, 'isWithdrawEnabled', false);
|
|
1147
|
+
if (isWithdrawEnabled === undefined) {
|
|
1148
|
+
isWithdrawEnabled = chainWithdrawEnabled;
|
|
1149
|
+
}
|
|
1150
|
+
else {
|
|
1151
|
+
isWithdrawEnabled = isWithdrawEnabled || chainWithdrawEnabled;
|
|
1152
|
+
}
|
|
1153
|
+
const chainDepositEnabled = this.safeValue(chain, 'isDepositEnabled', false);
|
|
1154
|
+
if (isDepositEnabled === undefined) {
|
|
1155
|
+
isDepositEnabled = chainDepositEnabled;
|
|
1156
|
+
}
|
|
1157
|
+
else {
|
|
1158
|
+
isDepositEnabled = isDepositEnabled || chainDepositEnabled;
|
|
1159
|
+
}
|
|
1160
|
+
const chainExtraData = this.safeValue(extraChainsData, chainId, {});
|
|
1161
|
+
networks[networkCode] = {
|
|
1162
|
+
'info': chain,
|
|
1163
|
+
'id': chainId,
|
|
1164
|
+
'name': this.safeString(chain, 'chainName'),
|
|
1165
|
+
'code': networkCode,
|
|
1166
|
+
'active': chainWithdrawEnabled && chainDepositEnabled,
|
|
1167
|
+
'fee': this.safeNumber(chain, 'withdrawalMinFee'),
|
|
1168
|
+
'deposit': chainDepositEnabled,
|
|
1169
|
+
'withdraw': chainWithdrawEnabled,
|
|
1170
|
+
'precision': this.parseNumber(this.parsePrecision(this.safeString(chainExtraData, 'walletPrecision'))),
|
|
1171
|
+
'limits': {
|
|
1172
|
+
'withdraw': {
|
|
1173
|
+
'min': this.safeNumber(chain, 'withdrawalMinSize'),
|
|
1174
|
+
'max': undefined,
|
|
1175
|
+
},
|
|
1176
|
+
'deposit': {
|
|
1177
|
+
'min': this.safeNumber(chainExtraData, 'depositMinSize'),
|
|
1178
|
+
'max': undefined,
|
|
1179
|
+
},
|
|
1180
|
+
},
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
// kucoin has determined 'fiat' currencies with below logic
|
|
1184
|
+
const isFiat = (rawPrecision === '2') && (chainsLength === 0);
|
|
1185
|
+
result[code] = {
|
|
1186
|
+
'id': id,
|
|
1187
|
+
'name': name,
|
|
1188
|
+
'code': code,
|
|
1189
|
+
'type': isFiat ? 'fiat' : 'crypto',
|
|
1190
|
+
'precision': precision,
|
|
1191
|
+
'info': entry,
|
|
1192
|
+
'active': (isDepositEnabled || isWithdrawEnabled),
|
|
1193
|
+
'deposit': isDepositEnabled,
|
|
1194
|
+
'withdraw': isWithdrawEnabled,
|
|
1195
|
+
'fee': undefined,
|
|
1196
|
+
'limits': this.limits,
|
|
1197
|
+
'networks': networks,
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
return result;
|
|
1201
|
+
}
|
|
1202
|
+
async fetchAccounts(params = {}) {
|
|
1203
|
+
/**
|
|
1204
|
+
* @method
|
|
1205
|
+
* @name kucoin#fetchAccounts
|
|
1206
|
+
* @description fetch all the accounts associated with a profile
|
|
1207
|
+
* @see https://docs.kucoin.com/#list-accounts
|
|
1208
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1209
|
+
* @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type
|
|
1210
|
+
*/
|
|
1211
|
+
const response = await this.privateGetAccounts(params);
|
|
1212
|
+
//
|
|
1213
|
+
// {
|
|
1214
|
+
// "code": "200000",
|
|
1215
|
+
// "data": [
|
|
1216
|
+
// {
|
|
1217
|
+
// "balance": "0.00009788",
|
|
1218
|
+
// "available": "0.00009788",
|
|
1219
|
+
// "holds": "0",
|
|
1220
|
+
// "currency": "BTC",
|
|
1221
|
+
// "id": "5c6a4fd399a1d81c4f9cc4d0",
|
|
1222
|
+
// "type": "trade"
|
|
1223
|
+
// },
|
|
1224
|
+
// {
|
|
1225
|
+
// "balance": "0.00000001",
|
|
1226
|
+
// "available": "0.00000001",
|
|
1227
|
+
// "holds": "0",
|
|
1228
|
+
// "currency": "ETH",
|
|
1229
|
+
// "id": "5c6a49ec99a1d819392e8e9f",
|
|
1230
|
+
// "type": "trade"
|
|
1231
|
+
// }
|
|
1232
|
+
// ]
|
|
1233
|
+
// }
|
|
1234
|
+
//
|
|
1235
|
+
const data = this.safeValue(response, 'data', []);
|
|
1236
|
+
const result = [];
|
|
1237
|
+
for (let i = 0; i < data.length; i++) {
|
|
1238
|
+
const account = data[i];
|
|
1239
|
+
const accountId = this.safeString(account, 'id');
|
|
1240
|
+
const currencyId = this.safeString(account, 'currency');
|
|
1241
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1242
|
+
const type = this.safeString(account, 'type'); // main or trade
|
|
1243
|
+
result.push({
|
|
1244
|
+
'id': accountId,
|
|
1245
|
+
'type': type,
|
|
1246
|
+
'currency': code,
|
|
1247
|
+
'code': code,
|
|
1248
|
+
'info': account,
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
return result;
|
|
1252
|
+
}
|
|
1253
|
+
async fetchTransactionFee(code, params = {}) {
|
|
1254
|
+
/**
|
|
1255
|
+
* @method
|
|
1256
|
+
* @name kucoin#fetchTransactionFee
|
|
1257
|
+
* @description *DEPRECATED* please use fetchDepositWithdrawFee instead
|
|
1258
|
+
* @see https://docs.kucoin.com/#get-withdrawal-quotas
|
|
1259
|
+
* @param {string} code unified currency code
|
|
1260
|
+
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
1261
|
+
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
1262
|
+
*/
|
|
1263
|
+
await this.loadMarkets();
|
|
1264
|
+
const currency = this.currency(code);
|
|
1265
|
+
const request = {
|
|
1266
|
+
'currency': currency['id'],
|
|
1267
|
+
};
|
|
1268
|
+
let networkCode = undefined;
|
|
1269
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
1270
|
+
if (networkCode !== undefined) {
|
|
1271
|
+
request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
|
|
1272
|
+
}
|
|
1273
|
+
const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params));
|
|
1274
|
+
const data = this.safeValue(response, 'data');
|
|
1275
|
+
const withdrawFees = {};
|
|
1276
|
+
withdrawFees[code] = this.safeNumber(data, 'withdrawMinFee');
|
|
1277
|
+
return {
|
|
1278
|
+
'info': response,
|
|
1279
|
+
'withdraw': withdrawFees,
|
|
1280
|
+
'deposit': {},
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
async fetchDepositWithdrawFee(code, params = {}) {
|
|
1284
|
+
/**
|
|
1285
|
+
* @method
|
|
1286
|
+
* @name kucoin#fetchDepositWithdrawFee
|
|
1287
|
+
* @description fetch the fee for deposits and withdrawals
|
|
1288
|
+
* @see https://docs.kucoin.com/#get-withdrawal-quotas
|
|
1289
|
+
* @param {string} code unified currency code
|
|
1290
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1291
|
+
* @param {string} [params.network] The chain of currency. This only apply for multi-chain currency, and there is no need for single chain currency; you can query the chain through the response of the GET /api/v2/currencies/{currency} interface
|
|
1292
|
+
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
1293
|
+
*/
|
|
1294
|
+
await this.loadMarkets();
|
|
1295
|
+
const currency = this.currency(code);
|
|
1296
|
+
const request = {
|
|
1297
|
+
'currency': currency['id'],
|
|
1298
|
+
};
|
|
1299
|
+
let networkCode = undefined;
|
|
1300
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
1301
|
+
if (networkCode !== undefined) {
|
|
1302
|
+
request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
|
|
1303
|
+
}
|
|
1304
|
+
const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params));
|
|
1305
|
+
//
|
|
1306
|
+
// {
|
|
1307
|
+
// "code": "200000",
|
|
1308
|
+
// "data": {
|
|
1309
|
+
// "currency": "USDT",
|
|
1310
|
+
// "limitBTCAmount": "1.00000000",
|
|
1311
|
+
// "usedBTCAmount": "0.00000000",
|
|
1312
|
+
// "remainAmount": "16548.072149",
|
|
1313
|
+
// "availableAmount": "0",
|
|
1314
|
+
// "withdrawMinFee": "25",
|
|
1315
|
+
// "innerWithdrawMinFee": "0",
|
|
1316
|
+
// "withdrawMinSize": "50",
|
|
1317
|
+
// "isWithdrawEnabled": true,
|
|
1318
|
+
// "precision": 6,
|
|
1319
|
+
// "chain": "ERC20"
|
|
1320
|
+
// }
|
|
1321
|
+
// }
|
|
1322
|
+
//
|
|
1323
|
+
const data = this.safeValue(response, 'data');
|
|
1324
|
+
return this.parseDepositWithdrawFee(data, currency);
|
|
1325
|
+
}
|
|
1326
|
+
parseDepositWithdrawFee(fee, currency = undefined) {
|
|
1327
|
+
//
|
|
1328
|
+
// {
|
|
1329
|
+
// "currency": "USDT",
|
|
1330
|
+
// "limitBTCAmount": "1.00000000",
|
|
1331
|
+
// "usedBTCAmount": "0.00000000",
|
|
1332
|
+
// "remainAmount": "16548.072149",
|
|
1333
|
+
// "availableAmount": "0",
|
|
1334
|
+
// "withdrawMinFee": "25",
|
|
1335
|
+
// "innerWithdrawMinFee": "0",
|
|
1336
|
+
// "withdrawMinSize": "50",
|
|
1337
|
+
// "isWithdrawEnabled": true,
|
|
1338
|
+
// "precision": 6,
|
|
1339
|
+
// "chain": "ERC20"
|
|
1340
|
+
// }
|
|
1341
|
+
//
|
|
1342
|
+
const result = {
|
|
1343
|
+
'info': fee,
|
|
1344
|
+
'withdraw': {
|
|
1345
|
+
'fee': undefined,
|
|
1346
|
+
'percentage': undefined,
|
|
1347
|
+
},
|
|
1348
|
+
'deposit': {
|
|
1349
|
+
'fee': undefined,
|
|
1350
|
+
'percentage': undefined,
|
|
1351
|
+
},
|
|
1352
|
+
'networks': {},
|
|
1353
|
+
};
|
|
1354
|
+
const isWithdrawEnabled = this.safeValue(fee, 'isWithdrawEnabled');
|
|
1355
|
+
if (isWithdrawEnabled) {
|
|
1356
|
+
result['withdraw']['fee'] = this.safeNumber2(fee, 'withdrawalMinFee', 'withdrawMinFee');
|
|
1357
|
+
result['withdraw']['percentage'] = false;
|
|
1358
|
+
const networkId = this.safeString(fee, 'chain');
|
|
1359
|
+
if (networkId) {
|
|
1360
|
+
const networkCode = this.networkIdToCode(networkId, this.safeString(currency, 'code'));
|
|
1361
|
+
result['networks'][networkCode] = {
|
|
1362
|
+
'withdraw': result['withdraw'],
|
|
1363
|
+
'deposit': {
|
|
1364
|
+
'fee': undefined,
|
|
1365
|
+
'percentage': undefined,
|
|
1366
|
+
},
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
return result;
|
|
1371
|
+
}
|
|
1372
|
+
isFuturesMethod(methodName, params) {
|
|
1373
|
+
//
|
|
1374
|
+
// Helper
|
|
1375
|
+
// @methodName (string): The name of the method
|
|
1376
|
+
// @params (dict): The parameters passed into {methodName}
|
|
1377
|
+
// @return: true if the method used is meant for futures trading, false otherwise
|
|
1378
|
+
//
|
|
1379
|
+
const defaultType = this.safeString2(this.options, methodName, 'defaultType', 'trade');
|
|
1380
|
+
const requestedType = this.safeString(params, 'type', defaultType);
|
|
1381
|
+
const accountsByType = this.safeValue(this.options, 'accountsByType');
|
|
1382
|
+
const type = this.safeString(accountsByType, requestedType);
|
|
1383
|
+
if (type === undefined) {
|
|
1384
|
+
const keys = Object.keys(accountsByType);
|
|
1385
|
+
throw new errors.ExchangeError(this.id + ' isFuturesMethod() type must be one of ' + keys.join(', '));
|
|
1386
|
+
}
|
|
1387
|
+
params = this.omit(params, 'type');
|
|
1388
|
+
return (type === 'contract') || (type === 'future') || (type === 'futures'); // * (type === 'futures') deprecated, use (type === 'future')
|
|
1389
|
+
}
|
|
1390
|
+
parseTicker(ticker, market = undefined) {
|
|
1391
|
+
//
|
|
1392
|
+
// {
|
|
1393
|
+
// "symbol": "BTC-USDT", // symbol
|
|
1394
|
+
// "symbolName":"BTC-USDT", // Name of trading pairs, it would change after renaming
|
|
1395
|
+
// "buy": "11328.9", // bestAsk
|
|
1396
|
+
// "sell": "11329", // bestBid
|
|
1397
|
+
// "changeRate": "-0.0055", // 24h change rate
|
|
1398
|
+
// "changePrice": "-63.6", // 24h change price
|
|
1399
|
+
// "high": "11610", // 24h highest price
|
|
1400
|
+
// "low": "11200", // 24h lowest price
|
|
1401
|
+
// "vol": "2282.70993217", // 24h volume,the aggregated trading volume in BTC
|
|
1402
|
+
// "volValue": "25984946.157790431", // 24h total, the trading volume in quote currency of last 24 hours
|
|
1403
|
+
// "last": "11328.9", // last price
|
|
1404
|
+
// "averagePrice": "11360.66065903", // 24h average transaction price yesterday
|
|
1405
|
+
// "takerFeeRate": "0.001", // Basic Taker Fee
|
|
1406
|
+
// "makerFeeRate": "0.001", // Basic Maker Fee
|
|
1407
|
+
// "takerCoefficient": "1", // Taker Fee Coefficient
|
|
1408
|
+
// "makerCoefficient": "1" // Maker Fee Coefficient
|
|
1409
|
+
// }
|
|
1410
|
+
//
|
|
1411
|
+
// {
|
|
1412
|
+
// "trading": true,
|
|
1413
|
+
// "symbol": "KCS-BTC",
|
|
1414
|
+
// "buy": 0.00011,
|
|
1415
|
+
// "sell": 0.00012,
|
|
1416
|
+
// "sort": 100,
|
|
1417
|
+
// "volValue": 3.13851792584, //total
|
|
1418
|
+
// "baseCurrency": "KCS",
|
|
1419
|
+
// "market": "BTC",
|
|
1420
|
+
// "quoteCurrency": "BTC",
|
|
1421
|
+
// "symbolCode": "KCS-BTC",
|
|
1422
|
+
// "datetime": 1548388122031,
|
|
1423
|
+
// "high": 0.00013,
|
|
1424
|
+
// "vol": 27514.34842,
|
|
1425
|
+
// "low": 0.0001,
|
|
1426
|
+
// "changePrice": -1.0e-5,
|
|
1427
|
+
// "changeRate": -0.0769,
|
|
1428
|
+
// "lastTradedPrice": 0.00012,
|
|
1429
|
+
// "board": 0,
|
|
1430
|
+
// "mark": 0
|
|
1431
|
+
// }
|
|
1432
|
+
//
|
|
1433
|
+
// market/ticker ws subscription
|
|
1434
|
+
//
|
|
1435
|
+
// {
|
|
1436
|
+
// "bestAsk": "62258.9",
|
|
1437
|
+
// "bestAskSize": "0.38579986",
|
|
1438
|
+
// "bestBid": "62258.8",
|
|
1439
|
+
// "bestBidSize": "0.0078381",
|
|
1440
|
+
// "price": "62260.7",
|
|
1441
|
+
// "sequence": "1621383297064",
|
|
1442
|
+
// "size": "0.00002841",
|
|
1443
|
+
// "time": 1634641777363
|
|
1444
|
+
// }
|
|
1445
|
+
//
|
|
1446
|
+
let percentage = this.safeString(ticker, 'changeRate');
|
|
1447
|
+
if (percentage !== undefined) {
|
|
1448
|
+
percentage = Precise["default"].stringMul(percentage, '100');
|
|
1449
|
+
}
|
|
1450
|
+
let last = this.safeString2(ticker, 'last', 'lastTradedPrice');
|
|
1451
|
+
last = this.safeString(ticker, 'price', last);
|
|
1452
|
+
const marketId = this.safeString(ticker, 'symbol');
|
|
1453
|
+
market = this.safeMarket(marketId, market, '-');
|
|
1454
|
+
const symbol = market['symbol'];
|
|
1455
|
+
const baseVolume = this.safeString(ticker, 'vol');
|
|
1456
|
+
const quoteVolume = this.safeString(ticker, 'volValue');
|
|
1457
|
+
const timestamp = this.safeInteger2(ticker, 'time', 'datetime');
|
|
1458
|
+
return this.safeTicker({
|
|
1459
|
+
'symbol': symbol,
|
|
1460
|
+
'timestamp': timestamp,
|
|
1461
|
+
'datetime': this.iso8601(timestamp),
|
|
1462
|
+
'high': this.safeString(ticker, 'high'),
|
|
1463
|
+
'low': this.safeString(ticker, 'low'),
|
|
1464
|
+
'bid': this.safeString2(ticker, 'buy', 'bestBid'),
|
|
1465
|
+
'bidVolume': this.safeString(ticker, 'bestBidSize'),
|
|
1466
|
+
'ask': this.safeString2(ticker, 'sell', 'bestAsk'),
|
|
1467
|
+
'askVolume': this.safeString(ticker, 'bestAskSize'),
|
|
1468
|
+
'vwap': undefined,
|
|
1469
|
+
'open': this.safeString(ticker, 'open'),
|
|
1470
|
+
'close': last,
|
|
1471
|
+
'last': last,
|
|
1472
|
+
'previousClose': undefined,
|
|
1473
|
+
'change': this.safeString(ticker, 'changePrice'),
|
|
1474
|
+
'percentage': percentage,
|
|
1475
|
+
'average': this.safeString(ticker, 'averagePrice'),
|
|
1476
|
+
'baseVolume': baseVolume,
|
|
1477
|
+
'quoteVolume': quoteVolume,
|
|
1478
|
+
'info': ticker,
|
|
1479
|
+
}, market);
|
|
1480
|
+
}
|
|
1481
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
1482
|
+
/**
|
|
1483
|
+
* @method
|
|
1484
|
+
* @name kucoin#fetchTickers
|
|
1485
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1486
|
+
* @see https://docs.kucoin.com/#get-all-tickers
|
|
1487
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1488
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1489
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1490
|
+
*/
|
|
1491
|
+
await this.loadMarkets();
|
|
1492
|
+
symbols = this.marketSymbols(symbols);
|
|
1493
|
+
const response = await this.publicGetMarketAllTickers(params);
|
|
1494
|
+
//
|
|
1495
|
+
// {
|
|
1496
|
+
// "code": "200000",
|
|
1497
|
+
// "data": {
|
|
1498
|
+
// "time":1602832092060,
|
|
1499
|
+
// "ticker":[
|
|
1500
|
+
// {
|
|
1501
|
+
// "symbol": "BTC-USDT", // symbol
|
|
1502
|
+
// "symbolName":"BTC-USDT", // Name of trading pairs, it would change after renaming
|
|
1503
|
+
// "buy": "11328.9", // bestAsk
|
|
1504
|
+
// "sell": "11329", // bestBid
|
|
1505
|
+
// "changeRate": "-0.0055", // 24h change rate
|
|
1506
|
+
// "changePrice": "-63.6", // 24h change price
|
|
1507
|
+
// "high": "11610", // 24h highest price
|
|
1508
|
+
// "low": "11200", // 24h lowest price
|
|
1509
|
+
// "vol": "2282.70993217", // 24h volume,the aggregated trading volume in BTC
|
|
1510
|
+
// "volValue": "25984946.157790431", // 24h total, the trading volume in quote currency of last 24 hours
|
|
1511
|
+
// "last": "11328.9", // last price
|
|
1512
|
+
// "averagePrice": "11360.66065903", // 24h average transaction price yesterday
|
|
1513
|
+
// "takerFeeRate": "0.001", // Basic Taker Fee
|
|
1514
|
+
// "makerFeeRate": "0.001", // Basic Maker Fee
|
|
1515
|
+
// "takerCoefficient": "1", // Taker Fee Coefficient
|
|
1516
|
+
// "makerCoefficient": "1" // Maker Fee Coefficient
|
|
1517
|
+
// }
|
|
1518
|
+
// ]
|
|
1519
|
+
// }
|
|
1520
|
+
// }
|
|
1521
|
+
//
|
|
1522
|
+
const data = this.safeValue(response, 'data', {});
|
|
1523
|
+
const tickers = this.safeValue(data, 'ticker', []);
|
|
1524
|
+
const time = this.safeInteger(data, 'time');
|
|
1525
|
+
const result = {};
|
|
1526
|
+
for (let i = 0; i < tickers.length; i++) {
|
|
1527
|
+
tickers[i]['time'] = time;
|
|
1528
|
+
const ticker = this.parseTicker(tickers[i]);
|
|
1529
|
+
const symbol = this.safeString(ticker, 'symbol');
|
|
1530
|
+
if (symbol !== undefined) {
|
|
1531
|
+
result[symbol] = ticker;
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
return this.filterByArrayTickers(result, 'symbol', symbols);
|
|
1535
|
+
}
|
|
1536
|
+
async fetchTicker(symbol, params = {}) {
|
|
1537
|
+
/**
|
|
1538
|
+
* @method
|
|
1539
|
+
* @name kucoin#fetchTicker
|
|
1540
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1541
|
+
* @see https://docs.kucoin.com/#get-24hr-stats
|
|
1542
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1543
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1544
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1545
|
+
*/
|
|
1546
|
+
await this.loadMarkets();
|
|
1547
|
+
const market = this.market(symbol);
|
|
1548
|
+
const request = {
|
|
1549
|
+
'symbol': market['id'],
|
|
1550
|
+
};
|
|
1551
|
+
const response = await this.publicGetMarketStats(this.extend(request, params));
|
|
1552
|
+
//
|
|
1553
|
+
// {
|
|
1554
|
+
// "code": "200000",
|
|
1555
|
+
// "data": {
|
|
1556
|
+
// "time": 1602832092060, // time
|
|
1557
|
+
// "symbol": "BTC-USDT", // symbol
|
|
1558
|
+
// "buy": "11328.9", // bestAsk
|
|
1559
|
+
// "sell": "11329", // bestBid
|
|
1560
|
+
// "changeRate": "-0.0055", // 24h change rate
|
|
1561
|
+
// "changePrice": "-63.6", // 24h change price
|
|
1562
|
+
// "high": "11610", // 24h highest price
|
|
1563
|
+
// "low": "11200", // 24h lowest price
|
|
1564
|
+
// "vol": "2282.70993217", // 24h volume,the aggregated trading volume in BTC
|
|
1565
|
+
// "volValue": "25984946.157790431", // 24h total, the trading volume in quote currency of last 24 hours
|
|
1566
|
+
// "last": "11328.9", // last price
|
|
1567
|
+
// "averagePrice": "11360.66065903", // 24h average transaction price yesterday
|
|
1568
|
+
// "takerFeeRate": "0.001", // Basic Taker Fee
|
|
1569
|
+
// "makerFeeRate": "0.001", // Basic Maker Fee
|
|
1570
|
+
// "takerCoefficient": "1", // Taker Fee Coefficient
|
|
1571
|
+
// "makerCoefficient": "1" // Maker Fee Coefficient
|
|
1572
|
+
// }
|
|
1573
|
+
// }
|
|
1574
|
+
//
|
|
1575
|
+
return this.parseTicker(response['data'], market);
|
|
1576
|
+
}
|
|
1577
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1578
|
+
//
|
|
1579
|
+
// [
|
|
1580
|
+
// "1545904980", // Start time of the candle cycle
|
|
1581
|
+
// "0.058", // opening price
|
|
1582
|
+
// "0.049", // closing price
|
|
1583
|
+
// "0.058", // highest price
|
|
1584
|
+
// "0.049", // lowest price
|
|
1585
|
+
// "0.018", // base volume
|
|
1586
|
+
// "0.000945", // quote volume
|
|
1587
|
+
// ]
|
|
1588
|
+
//
|
|
1589
|
+
return [
|
|
1590
|
+
this.safeTimestamp(ohlcv, 0),
|
|
1591
|
+
this.safeNumber(ohlcv, 1),
|
|
1592
|
+
this.safeNumber(ohlcv, 3),
|
|
1593
|
+
this.safeNumber(ohlcv, 4),
|
|
1594
|
+
this.safeNumber(ohlcv, 2),
|
|
1595
|
+
this.safeNumber(ohlcv, 5),
|
|
1596
|
+
];
|
|
1597
|
+
}
|
|
1598
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1599
|
+
/**
|
|
1600
|
+
* @method
|
|
1601
|
+
* @name kucoin#fetchOHLCV
|
|
1602
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1603
|
+
* @see https://docs.kucoin.com/#get-klines
|
|
1604
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1605
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1606
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1607
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1608
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1609
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
1610
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1611
|
+
*/
|
|
1612
|
+
await this.loadMarkets();
|
|
1613
|
+
let paginate = false;
|
|
1614
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
|
|
1615
|
+
if (paginate) {
|
|
1616
|
+
return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1500);
|
|
1617
|
+
}
|
|
1618
|
+
const market = this.market(symbol);
|
|
1619
|
+
const marketId = market['id'];
|
|
1620
|
+
const request = {
|
|
1621
|
+
'symbol': marketId,
|
|
1622
|
+
'type': this.safeString(this.timeframes, timeframe, timeframe),
|
|
1623
|
+
};
|
|
1624
|
+
const duration = this.parseTimeframe(timeframe) * 1000;
|
|
1625
|
+
let endAt = this.milliseconds(); // required param
|
|
1626
|
+
if (since !== undefined) {
|
|
1627
|
+
request['startAt'] = this.parseToInt(Math.floor(since / 1000));
|
|
1628
|
+
if (limit === undefined) {
|
|
1629
|
+
// https://docs.kucoin.com/#get-klines
|
|
1630
|
+
// https://docs.kucoin.com/#details
|
|
1631
|
+
// For each query, the system would return at most 1500 pieces of data.
|
|
1632
|
+
// To obtain more data, please page the data by time.
|
|
1633
|
+
limit = this.safeInteger(this.options, 'fetchOHLCVLimit', 1500);
|
|
1634
|
+
}
|
|
1635
|
+
endAt = this.sum(since, limit * duration);
|
|
1636
|
+
}
|
|
1637
|
+
else if (limit !== undefined) {
|
|
1638
|
+
since = endAt - limit * duration;
|
|
1639
|
+
request['startAt'] = this.parseToInt(Math.floor(since / 1000));
|
|
1640
|
+
}
|
|
1641
|
+
request['endAt'] = this.parseToInt(Math.floor(endAt / 1000));
|
|
1642
|
+
const response = await this.publicGetMarketCandles(this.extend(request, params));
|
|
1643
|
+
//
|
|
1644
|
+
// {
|
|
1645
|
+
// "code":"200000",
|
|
1646
|
+
// "data":[
|
|
1647
|
+
// ["1591517700","0.025078","0.025069","0.025084","0.025064","18.9883256","0.4761861079404"],
|
|
1648
|
+
// ["1591516800","0.025089","0.025079","0.025089","0.02506","99.4716622","2.494143499081"],
|
|
1649
|
+
// ["1591515900","0.025079","0.02509","0.025091","0.025068","59.83701271","1.50060885172798"],
|
|
1650
|
+
// ]
|
|
1651
|
+
// }
|
|
1652
|
+
//
|
|
1653
|
+
const data = this.safeValue(response, 'data', []);
|
|
1654
|
+
return this.parseOHLCVs(data, market, timeframe, since, limit);
|
|
1655
|
+
}
|
|
1656
|
+
async createDepositAddress(code, params = {}) {
|
|
1657
|
+
/**
|
|
1658
|
+
* @method
|
|
1659
|
+
* @name kucoin#createDepositAddress
|
|
1660
|
+
* @see https://docs.kucoin.com/#create-deposit-address
|
|
1661
|
+
* @description create a currency deposit address
|
|
1662
|
+
* @param {string} code unified currency code of the currency for the deposit address
|
|
1663
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1664
|
+
* @param {string} [params.network] the blockchain network name
|
|
1665
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1666
|
+
*/
|
|
1667
|
+
await this.loadMarkets();
|
|
1668
|
+
const currency = this.currency(code);
|
|
1669
|
+
const request = {
|
|
1670
|
+
'currency': currency['id'],
|
|
1671
|
+
};
|
|
1672
|
+
let networkCode = undefined;
|
|
1673
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
1674
|
+
if (networkCode !== undefined) {
|
|
1675
|
+
request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
|
|
1676
|
+
}
|
|
1677
|
+
const response = await this.privatePostDepositAddresses(this.extend(request, params));
|
|
1678
|
+
// {"code":"260000","msg":"Deposit address already exists."}
|
|
1679
|
+
// BCH {"code":"200000","data":{"address":"bitcoincash:qza3m4nj9rx7l9r0cdadfqxts6f92shvhvr5ls4q7z","memo":""}}
|
|
1680
|
+
// BTC {"code":"200000","data":{"address":"36SjucKqQpQSvsak9A7h6qzFjrVXpRNZhE","memo":""}}
|
|
1681
|
+
const data = this.safeValue(response, 'data', {});
|
|
1682
|
+
return this.parseDepositAddress(data, currency);
|
|
1683
|
+
}
|
|
1684
|
+
async fetchDepositAddress(code, params = {}) {
|
|
1685
|
+
/**
|
|
1686
|
+
* @method
|
|
1687
|
+
* @name kucoin#fetchDepositAddress
|
|
1688
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
1689
|
+
* @see https://docs.kucoin.com/#get-deposit-addresses-v2
|
|
1690
|
+
* @param {string} code unified currency code
|
|
1691
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1692
|
+
* @param {string} [params.network] the blockchain network name
|
|
1693
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1694
|
+
*/
|
|
1695
|
+
await this.loadMarkets();
|
|
1696
|
+
const currency = this.currency(code);
|
|
1697
|
+
const request = {
|
|
1698
|
+
'currency': currency['id'],
|
|
1699
|
+
// for USDT - OMNI, ERC20, TRC20, default is ERC20
|
|
1700
|
+
// for BTC - Native, Segwit, TRC20, the parameters are bech32, btc, trx, default is Native
|
|
1701
|
+
// 'chain': 'ERC20', // optional
|
|
1702
|
+
};
|
|
1703
|
+
let networkCode = undefined;
|
|
1704
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
1705
|
+
if (networkCode !== undefined) {
|
|
1706
|
+
request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
|
|
1707
|
+
}
|
|
1708
|
+
const version = this.options['versions']['private']['GET']['deposit-addresses'];
|
|
1709
|
+
this.options['versions']['private']['GET']['deposit-addresses'] = 'v1';
|
|
1710
|
+
const response = await this.privateGetDepositAddresses(this.extend(request, params));
|
|
1711
|
+
// BCH {"code":"200000","data":{"address":"bitcoincash:qza3m4nj9rx7l9r0cdadfqxts6f92shvhvr5ls4q7z","memo":""}}
|
|
1712
|
+
// BTC {"code":"200000","data":{"address":"36SjucKqQpQSvsak9A7h6qzFjrVXpRNZhE","memo":""}}
|
|
1713
|
+
this.options['versions']['private']['GET']['deposit-addresses'] = version;
|
|
1714
|
+
const data = this.safeValue(response, 'data');
|
|
1715
|
+
if (data === undefined) {
|
|
1716
|
+
throw new errors.ExchangeError(this.id + ' fetchDepositAddress() returned an empty response, you might try to run createDepositAddress() first and try again');
|
|
1717
|
+
}
|
|
1718
|
+
return this.parseDepositAddress(data, currency);
|
|
1719
|
+
}
|
|
1720
|
+
parseDepositAddress(depositAddress, currency = undefined) {
|
|
1721
|
+
let address = this.safeString(depositAddress, 'address');
|
|
1722
|
+
// BCH/BSV is returned with a "bitcoincash:" prefix, which we cut off here and only keep the address
|
|
1723
|
+
if (address !== undefined) {
|
|
1724
|
+
address = address.replace('bitcoincash:', '');
|
|
1725
|
+
}
|
|
1726
|
+
let code = undefined;
|
|
1727
|
+
if (currency !== undefined) {
|
|
1728
|
+
code = currency['id'];
|
|
1729
|
+
if (code !== 'NIM') {
|
|
1730
|
+
// contains spaces
|
|
1731
|
+
this.checkAddress(address);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
return {
|
|
1735
|
+
'info': depositAddress,
|
|
1736
|
+
'currency': code,
|
|
1737
|
+
'address': address,
|
|
1738
|
+
'tag': this.safeString(depositAddress, 'memo'),
|
|
1739
|
+
'network': this.networkIdToCode(this.safeString(depositAddress, 'chain')),
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
async fetchDepositAddressesByNetwork(code, params = {}) {
|
|
1743
|
+
/**
|
|
1744
|
+
* @method
|
|
1745
|
+
* @name kucoin#fetchDepositAddressesByNetwork
|
|
1746
|
+
* @see https://docs.kucoin.com/#get-deposit-addresses-v2
|
|
1747
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
1748
|
+
* @param {string} code unified currency code
|
|
1749
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1750
|
+
* @returns {object} an array of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1751
|
+
*/
|
|
1752
|
+
await this.loadMarkets();
|
|
1753
|
+
const currency = this.currency(code);
|
|
1754
|
+
const request = {
|
|
1755
|
+
'currency': currency['id'],
|
|
1756
|
+
};
|
|
1757
|
+
const version = this.options['versions']['private']['GET']['deposit-addresses'];
|
|
1758
|
+
this.options['versions']['private']['GET']['deposit-addresses'] = 'v2';
|
|
1759
|
+
const response = await this.privateGetDepositAddresses(this.extend(request, params));
|
|
1760
|
+
//
|
|
1761
|
+
// {
|
|
1762
|
+
// "code": "200000",
|
|
1763
|
+
// "data": [
|
|
1764
|
+
// {
|
|
1765
|
+
// "address": "fr1qvus7d4d5fgxj5e7zvqe6yhxd7txm95h2and69r",
|
|
1766
|
+
// "memo": "",
|
|
1767
|
+
// "chain": "BTC-Segwit",
|
|
1768
|
+
// "contractAddress": ""
|
|
1769
|
+
// },
|
|
1770
|
+
// {"address":"37icNMEWbiF8ZkwUMxmfzMxi2A1MQ44bMn","memo":"","chain":"BTC","contractAddress":""},
|
|
1771
|
+
// {"address":"Deposit temporarily blocked","memo":"","chain":"TRC20","contractAddress":""}
|
|
1772
|
+
// ]
|
|
1773
|
+
// }
|
|
1774
|
+
//
|
|
1775
|
+
this.options['versions']['private']['GET']['deposit-addresses'] = version;
|
|
1776
|
+
const chains = this.safeValue(response, 'data', []);
|
|
1777
|
+
const parsed = this.parseDepositAddresses(chains, [currency['code']], false, {
|
|
1778
|
+
'currency': currency['id'],
|
|
1779
|
+
});
|
|
1780
|
+
return this.indexBy(parsed, 'network');
|
|
1781
|
+
}
|
|
1782
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
1783
|
+
/**
|
|
1784
|
+
* @method
|
|
1785
|
+
* @name kucoin#fetchOrderBook
|
|
1786
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
1787
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/market-data/get-part-order-book-aggregated-
|
|
1788
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/market-data/get-full-order-book-aggregated-
|
|
1789
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
1790
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
1791
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1792
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
1793
|
+
*/
|
|
1794
|
+
await this.loadMarkets();
|
|
1795
|
+
const market = this.market(symbol);
|
|
1796
|
+
const level = this.safeInteger(params, 'level', 2);
|
|
1797
|
+
const request = { 'symbol': market['id'] };
|
|
1798
|
+
const isAuthenticated = this.checkRequiredCredentials(false);
|
|
1799
|
+
let response = undefined;
|
|
1800
|
+
if (!isAuthenticated || limit !== undefined) {
|
|
1801
|
+
if (level === 2) {
|
|
1802
|
+
request['level'] = level;
|
|
1803
|
+
if (limit !== undefined) {
|
|
1804
|
+
if ((limit === 20) || (limit === 100)) {
|
|
1805
|
+
request['limit'] = limit;
|
|
1806
|
+
}
|
|
1807
|
+
else {
|
|
1808
|
+
throw new errors.ExchangeError(this.id + ' fetchOrderBook() limit argument must be 20 or 100');
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
request['limit'] = limit ? limit : 100;
|
|
1812
|
+
}
|
|
1813
|
+
response = await this.publicGetMarketOrderbookLevelLevelLimit(this.extend(request, params));
|
|
1814
|
+
}
|
|
1815
|
+
else {
|
|
1816
|
+
response = await this.privateGetMarketOrderbookLevel2(this.extend(request, params));
|
|
1817
|
+
}
|
|
1818
|
+
//
|
|
1819
|
+
// public (v1) market/orderbook/level2_20 and market/orderbook/level2_100
|
|
1820
|
+
//
|
|
1821
|
+
// {
|
|
1822
|
+
// "sequence": "3262786978",
|
|
1823
|
+
// "time": 1550653727731,
|
|
1824
|
+
// "bids": [
|
|
1825
|
+
// ["6500.12", "0.45054140"],
|
|
1826
|
+
// ["6500.11", "0.45054140"],
|
|
1827
|
+
// ],
|
|
1828
|
+
// "asks": [
|
|
1829
|
+
// ["6500.16", "0.57753524"],
|
|
1830
|
+
// ["6500.15", "0.57753524"],
|
|
1831
|
+
// ]
|
|
1832
|
+
// }
|
|
1833
|
+
//
|
|
1834
|
+
// private (v3) market/orderbook/level2
|
|
1835
|
+
//
|
|
1836
|
+
// {
|
|
1837
|
+
// "sequence": "3262786978",
|
|
1838
|
+
// "time": 1550653727731,
|
|
1839
|
+
// "bids": [
|
|
1840
|
+
// ["6500.12", "0.45054140"],
|
|
1841
|
+
// ["6500.11", "0.45054140"],
|
|
1842
|
+
// ],
|
|
1843
|
+
// "asks": [
|
|
1844
|
+
// ["6500.16", "0.57753524"],
|
|
1845
|
+
// ["6500.15", "0.57753524"],
|
|
1846
|
+
// ]
|
|
1847
|
+
// }
|
|
1848
|
+
//
|
|
1849
|
+
const data = this.safeValue(response, 'data', {});
|
|
1850
|
+
const timestamp = this.safeInteger(data, 'time');
|
|
1851
|
+
const orderbook = this.parseOrderBook(data, market['symbol'], timestamp, 'bids', 'asks', level - 2, level - 1);
|
|
1852
|
+
orderbook['nonce'] = this.safeInteger(data, 'sequence');
|
|
1853
|
+
return orderbook;
|
|
1854
|
+
}
|
|
1855
|
+
handleTriggerPrices(params) {
|
|
1856
|
+
const triggerPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
|
|
1857
|
+
const stopLossPrice = this.safeValue(params, 'stopLossPrice');
|
|
1858
|
+
const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
|
|
1859
|
+
const isStopLoss = stopLossPrice !== undefined;
|
|
1860
|
+
const isTakeProfit = takeProfitPrice !== undefined;
|
|
1861
|
+
if ((isStopLoss && isTakeProfit) || (triggerPrice && stopLossPrice) || (triggerPrice && isTakeProfit)) {
|
|
1862
|
+
throw new errors.ExchangeError(this.id + ' createOrder() - you should use either triggerPrice or stopLossPrice or takeProfitPrice');
|
|
1863
|
+
}
|
|
1864
|
+
return [triggerPrice, stopLossPrice, takeProfitPrice];
|
|
1865
|
+
}
|
|
1866
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1867
|
+
/**
|
|
1868
|
+
* @method
|
|
1869
|
+
* @name kucoin#createOrder
|
|
1870
|
+
* @description Create an order on the exchange
|
|
1871
|
+
* @see https://docs.kucoin.com/spot#place-a-new-order
|
|
1872
|
+
* @see https://docs.kucoin.com/spot#place-a-new-order-2
|
|
1873
|
+
* @see https://docs.kucoin.com/spot#place-a-margin-order
|
|
1874
|
+
* @see https://docs.kucoin.com/spot-hf/#place-hf-order
|
|
1875
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/orders/place-order-test
|
|
1876
|
+
* @see https://www.kucoin.com/docs/rest/margin-trading/orders/place-margin-order-test
|
|
1877
|
+
* @param {string} symbol Unified CCXT market symbol
|
|
1878
|
+
* @param {string} type 'limit' or 'market'
|
|
1879
|
+
* @param {string} side 'buy' or 'sell'
|
|
1880
|
+
* @param {float} amount the amount of currency to trade
|
|
1881
|
+
* @param {float} [price] *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
|
|
1882
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1883
|
+
* @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
|
|
1884
|
+
* @param {string} [params.marginMode] 'cross', // cross (cross mode) and isolated (isolated mode), set to cross by default, the isolated mode will be released soon, stay tuned
|
|
1885
|
+
* @param {string} [params.timeInForce] GTC, GTT, IOC, or FOK, default is GTC, limit orders only
|
|
1886
|
+
* @param {string} [params.postOnly] Post only flag, invalid when timeInForce is IOC or FOK
|
|
1887
|
+
*
|
|
1888
|
+
* EXCHANGE SPECIFIC PARAMETERS
|
|
1889
|
+
* @param {string} [params.clientOid] client order id, defaults to uuid if not passed
|
|
1890
|
+
* @param {string} [params.remark] remark for the order, length cannot exceed 100 utf8 characters
|
|
1891
|
+
* @param {string} [params.tradeType] 'TRADE', // TRADE, MARGIN_TRADE // not used with margin orders
|
|
1892
|
+
* limit orders ---------------------------------------------------
|
|
1893
|
+
* @param {float} [params.cancelAfter] long, // cancel after n seconds, requires timeInForce to be GTT
|
|
1894
|
+
* @param {bool} [params.hidden] false, // Order will not be displayed in the order book
|
|
1895
|
+
* @param {bool} [params.iceberg] false, // Only a portion of the order is displayed in the order book
|
|
1896
|
+
* @param {string} [params.visibleSize] this.amountToPrecision (symbol, visibleSize), // The maximum visible size of an iceberg order
|
|
1897
|
+
* market orders --------------------------------------------------
|
|
1898
|
+
* @param {string} [params.funds] // Amount of quote currency to use
|
|
1899
|
+
* stop orders ----------------------------------------------------
|
|
1900
|
+
* @param {string} [params.stop] Either loss or entry, the default is loss. Requires stopPrice to be defined
|
|
1901
|
+
* margin orders --------------------------------------------------
|
|
1902
|
+
* @param {float} [params.leverage] Leverage size of the order
|
|
1903
|
+
* @param {string} [params.stp] '', // self trade prevention, CN, CO, CB or DC
|
|
1904
|
+
* @param {bool} [params.autoBorrow] false, // The system will first borrow you funds at the optimal interest rate and then place an order for you
|
|
1905
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
1906
|
+
* @param {bool} [params.test] set to true to test an order, no order will be created but the request will be validated
|
|
1907
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1908
|
+
*/
|
|
1909
|
+
await this.loadMarkets();
|
|
1910
|
+
const market = this.market(symbol);
|
|
1911
|
+
const testOrder = this.safeValue(params, 'test', false);
|
|
1912
|
+
params = this.omit(params, 'test');
|
|
1913
|
+
const isHf = this.safeValue(params, 'hf', false);
|
|
1914
|
+
const [triggerPrice, stopLossPrice, takeProfitPrice] = this.handleTriggerPrices(params);
|
|
1915
|
+
const tradeType = this.safeString(params, 'tradeType'); // keep it for backward compatibility
|
|
1916
|
+
const isTriggerOrder = (triggerPrice || stopLossPrice || takeProfitPrice);
|
|
1917
|
+
const marginResult = this.handleMarginModeAndParams('createOrder', params);
|
|
1918
|
+
const marginMode = this.safeString(marginResult, 0);
|
|
1919
|
+
const isMarginOrder = tradeType === 'MARGIN_TRADE' || marginMode !== undefined;
|
|
1920
|
+
// don't omit anything before calling createOrderRequest
|
|
1921
|
+
const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
1922
|
+
let response = undefined;
|
|
1923
|
+
if (testOrder) {
|
|
1924
|
+
if (isMarginOrder) {
|
|
1925
|
+
response = await this.privatePostMarginOrderTest(orderRequest);
|
|
1926
|
+
}
|
|
1927
|
+
else {
|
|
1928
|
+
response = await this.privatePostOrdersTest(orderRequest);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
else if (isHf) {
|
|
1932
|
+
response = await this.privatePostHfOrders(orderRequest);
|
|
1933
|
+
}
|
|
1934
|
+
else if (isTriggerOrder) {
|
|
1935
|
+
response = await this.privatePostStopOrder(orderRequest);
|
|
1936
|
+
}
|
|
1937
|
+
else if (isMarginOrder) {
|
|
1938
|
+
response = await this.privatePostMarginOrder(orderRequest);
|
|
1939
|
+
}
|
|
1940
|
+
else {
|
|
1941
|
+
response = await this.privatePostOrders(orderRequest);
|
|
1942
|
+
}
|
|
1943
|
+
//
|
|
1944
|
+
// {
|
|
1945
|
+
// "code": "200000",
|
|
1946
|
+
// "data": {
|
|
1947
|
+
// "orderId": "5bd6e9286d99522a52e458de"
|
|
1948
|
+
// }
|
|
1949
|
+
// }
|
|
1950
|
+
//
|
|
1951
|
+
const data = this.safeValue(response, 'data', {});
|
|
1952
|
+
return this.parseOrder(data, market);
|
|
1953
|
+
}
|
|
1954
|
+
async createMarketOrderWithCost(symbol, side, cost, params = {}) {
|
|
1955
|
+
/**
|
|
1956
|
+
* @method
|
|
1957
|
+
* @name kucoin#createMarketOrderWithCost
|
|
1958
|
+
* @description create a market order by providing the symbol, side and cost
|
|
1959
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
|
1960
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1961
|
+
* @param {string} side 'buy' or 'sell'
|
|
1962
|
+
* @param {float} cost how much you want to trade in units of the quote currency
|
|
1963
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1964
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1965
|
+
*/
|
|
1966
|
+
await this.loadMarkets();
|
|
1967
|
+
params['cost'] = cost;
|
|
1968
|
+
return await this.createOrder(symbol, 'market', side, cost, undefined, params);
|
|
1969
|
+
}
|
|
1970
|
+
async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
|
|
1971
|
+
/**
|
|
1972
|
+
* @method
|
|
1973
|
+
* @name kucoin#createMarketBuyOrderWithCost
|
|
1974
|
+
* @description create a market buy order by providing the symbol and cost
|
|
1975
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
|
1976
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1977
|
+
* @param {float} cost how much you want to trade in units of the quote currency
|
|
1978
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1979
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1980
|
+
*/
|
|
1981
|
+
await this.loadMarkets();
|
|
1982
|
+
return await this.createMarketOrderWithCost(symbol, 'buy', cost, params);
|
|
1983
|
+
}
|
|
1984
|
+
async createMarketSellOrderWithCost(symbol, cost, params = {}) {
|
|
1985
|
+
/**
|
|
1986
|
+
* @method
|
|
1987
|
+
* @name kucoin#createMarketSellOrderWithCost
|
|
1988
|
+
* @description create a market sell order by providing the symbol and cost
|
|
1989
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
|
1990
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1991
|
+
* @param {float} cost how much you want to trade in units of the quote currency
|
|
1992
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1993
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1994
|
+
*/
|
|
1995
|
+
await this.loadMarkets();
|
|
1996
|
+
return await this.createMarketOrderWithCost(symbol, 'sell', cost, params);
|
|
1997
|
+
}
|
|
1998
|
+
async createOrders(orders, params = {}) {
|
|
1999
|
+
/**
|
|
2000
|
+
* @method
|
|
2001
|
+
* @name kucoin#createOrders
|
|
2002
|
+
* @description create a list of trade orders
|
|
2003
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/orders/place-multiple-orders
|
|
2004
|
+
* @see https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/place-multiple-hf-orders
|
|
2005
|
+
* @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
|
2006
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2007
|
+
* @param {bool} [params.hf] false, // true for hf orders
|
|
2008
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2009
|
+
*/
|
|
2010
|
+
await this.loadMarkets();
|
|
2011
|
+
const ordersRequests = [];
|
|
2012
|
+
let symbol = undefined;
|
|
2013
|
+
for (let i = 0; i < orders.length; i++) {
|
|
2014
|
+
const rawOrder = orders[i];
|
|
2015
|
+
const marketId = this.safeString(rawOrder, 'symbol');
|
|
2016
|
+
if (symbol === undefined) {
|
|
2017
|
+
symbol = marketId;
|
|
2018
|
+
}
|
|
2019
|
+
else {
|
|
2020
|
+
if (symbol !== marketId) {
|
|
2021
|
+
throw new errors.BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
const type = this.safeString(rawOrder, 'type');
|
|
2025
|
+
if (type !== 'limit') {
|
|
2026
|
+
throw new errors.BadRequest(this.id + ' createOrders() only supports limit orders');
|
|
2027
|
+
}
|
|
2028
|
+
const side = this.safeString(rawOrder, 'side');
|
|
2029
|
+
const amount = this.safeValue(rawOrder, 'amount');
|
|
2030
|
+
const price = this.safeValue(rawOrder, 'price');
|
|
2031
|
+
const orderParams = this.safeValue(rawOrder, 'params', {});
|
|
2032
|
+
const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
|
|
2033
|
+
ordersRequests.push(orderRequest);
|
|
2034
|
+
}
|
|
2035
|
+
const market = this.market(symbol);
|
|
2036
|
+
const request = {
|
|
2037
|
+
'symbol': market['id'],
|
|
2038
|
+
'orderList': ordersRequests,
|
|
2039
|
+
};
|
|
2040
|
+
const hf = this.safeValue(params, 'hf', false);
|
|
2041
|
+
params = this.omit(params, 'hf');
|
|
2042
|
+
let response = undefined;
|
|
2043
|
+
if (hf) {
|
|
2044
|
+
response = await this.privatePostHfOrdersMulti(this.extend(request, params));
|
|
2045
|
+
}
|
|
2046
|
+
else {
|
|
2047
|
+
response = await this.privatePostOrdersMulti(this.extend(request, params));
|
|
2048
|
+
}
|
|
2049
|
+
//
|
|
2050
|
+
// {
|
|
2051
|
+
// "code": "200000",
|
|
2052
|
+
// "data": {
|
|
2053
|
+
// "data": [
|
|
2054
|
+
// {
|
|
2055
|
+
// "symbol": "LTC-USDT",
|
|
2056
|
+
// "type": "limit",
|
|
2057
|
+
// "side": "sell",
|
|
2058
|
+
// "price": "90",
|
|
2059
|
+
// "size": "0.1",
|
|
2060
|
+
// "funds": null,
|
|
2061
|
+
// "stp": "",
|
|
2062
|
+
// "stop": "",
|
|
2063
|
+
// "stopPrice": null,
|
|
2064
|
+
// "timeInForce": "GTC",
|
|
2065
|
+
// "cancelAfter": 0,
|
|
2066
|
+
// "postOnly": false,
|
|
2067
|
+
// "hidden": false,
|
|
2068
|
+
// "iceberge": false,
|
|
2069
|
+
// "iceberg": false,
|
|
2070
|
+
// "visibleSize": null,
|
|
2071
|
+
// "channel": "API",
|
|
2072
|
+
// "id": "6539148443fcf500079d15e5",
|
|
2073
|
+
// "status": "success",
|
|
2074
|
+
// "failMsg": null,
|
|
2075
|
+
// "clientOid": "5c4c5398-8ab2-4b4e-af8a-e2d90ad2488f"
|
|
2076
|
+
// },
|
|
2077
|
+
// }
|
|
2078
|
+
//
|
|
2079
|
+
let data = this.safeValue(response, 'data', {});
|
|
2080
|
+
data = this.safeValue(data, 'data', []);
|
|
2081
|
+
return this.parseOrders(data);
|
|
2082
|
+
}
|
|
2083
|
+
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
2084
|
+
const market = this.market(symbol);
|
|
2085
|
+
// required param, cannot be used twice
|
|
2086
|
+
const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId', this.uuid());
|
|
2087
|
+
params = this.omit(params, ['clientOid', 'clientOrderId']);
|
|
2088
|
+
const request = {
|
|
2089
|
+
'clientOid': clientOrderId,
|
|
2090
|
+
'side': side,
|
|
2091
|
+
'symbol': market['id'],
|
|
2092
|
+
'type': type, // limit or market
|
|
2093
|
+
};
|
|
2094
|
+
const quoteAmount = this.safeNumber2(params, 'cost', 'funds');
|
|
2095
|
+
let amountString = undefined;
|
|
2096
|
+
let costString = undefined;
|
|
2097
|
+
let marginMode = undefined;
|
|
2098
|
+
[marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
|
|
2099
|
+
if (type === 'market') {
|
|
2100
|
+
if (quoteAmount !== undefined) {
|
|
2101
|
+
params = this.omit(params, ['cost', 'funds']);
|
|
2102
|
+
// kucoin uses base precision even for quote values
|
|
2103
|
+
costString = this.amountToPrecision(symbol, quoteAmount);
|
|
2104
|
+
request['funds'] = costString;
|
|
2105
|
+
}
|
|
2106
|
+
else {
|
|
2107
|
+
amountString = this.amountToPrecision(symbol, amount);
|
|
2108
|
+
request['size'] = this.amountToPrecision(symbol, amount);
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
else {
|
|
2112
|
+
amountString = this.amountToPrecision(symbol, amount);
|
|
2113
|
+
request['size'] = amountString;
|
|
2114
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
2115
|
+
}
|
|
2116
|
+
const tradeType = this.safeString(params, 'tradeType'); // keep it for backward compatibility
|
|
2117
|
+
const [triggerPrice, stopLossPrice, takeProfitPrice] = this.handleTriggerPrices(params);
|
|
2118
|
+
const isTriggerOrder = (triggerPrice || stopLossPrice || takeProfitPrice);
|
|
2119
|
+
const isMarginOrder = tradeType === 'MARGIN_TRADE' || marginMode !== undefined;
|
|
2120
|
+
params = this.omit(params, ['stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'stopPrice']);
|
|
2121
|
+
if (isTriggerOrder) {
|
|
2122
|
+
if (triggerPrice) {
|
|
2123
|
+
request['stopPrice'] = this.priceToPrecision(symbol, triggerPrice);
|
|
2124
|
+
}
|
|
2125
|
+
else if (stopLossPrice || takeProfitPrice) {
|
|
2126
|
+
if (stopLossPrice) {
|
|
2127
|
+
request['stop'] = (side === 'buy') ? 'entry' : 'loss';
|
|
2128
|
+
request['stopPrice'] = this.priceToPrecision(symbol, stopLossPrice);
|
|
2129
|
+
}
|
|
2130
|
+
else {
|
|
2131
|
+
request['stop'] = (side === 'buy') ? 'loss' : 'entry';
|
|
2132
|
+
request['stopPrice'] = this.priceToPrecision(symbol, takeProfitPrice);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
if (marginMode === 'isolated') {
|
|
2136
|
+
throw new errors.BadRequest(this.id + ' createOrder does not support isolated margin for stop orders');
|
|
2137
|
+
}
|
|
2138
|
+
else if (marginMode === 'cross') {
|
|
2139
|
+
request['tradeType'] = this.options['marginModes'][marginMode];
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
else if (isMarginOrder) {
|
|
2143
|
+
if (marginMode === 'isolated') {
|
|
2144
|
+
request['marginModel'] = 'isolated';
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
let postOnly = undefined;
|
|
2148
|
+
[postOnly, params] = this.handlePostOnly(type === 'market', false, params);
|
|
2149
|
+
if (postOnly) {
|
|
2150
|
+
request['postOnly'] = true;
|
|
2151
|
+
}
|
|
2152
|
+
return this.extend(request, params);
|
|
2153
|
+
}
|
|
2154
|
+
async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
2155
|
+
/**
|
|
2156
|
+
* @method
|
|
2157
|
+
* @name kucoin#editOrder
|
|
2158
|
+
* @description edit an order, kucoin currently only supports the modification of HF orders
|
|
2159
|
+
* @see https://docs.kucoin.com/spot-hf/#modify-order
|
|
2160
|
+
* @param {string} id order id
|
|
2161
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
2162
|
+
* @param {string} type not used
|
|
2163
|
+
* @param {string} side not used
|
|
2164
|
+
* @param {float} amount how much of the currency you want to trade in units of the base currency
|
|
2165
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
|
|
2166
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2167
|
+
* @param {string} [params.clientOrderId] client order id, defaults to id if not passed
|
|
2168
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2169
|
+
*/
|
|
2170
|
+
await this.loadMarkets();
|
|
2171
|
+
const market = this.market(symbol);
|
|
2172
|
+
const request = {
|
|
2173
|
+
'symbol': market['id'],
|
|
2174
|
+
};
|
|
2175
|
+
const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
|
|
2176
|
+
if (clientOrderId !== undefined) {
|
|
2177
|
+
request['clientOid'] = clientOrderId;
|
|
2178
|
+
}
|
|
2179
|
+
else {
|
|
2180
|
+
request['orderId'] = id;
|
|
2181
|
+
}
|
|
2182
|
+
if (amount !== undefined) {
|
|
2183
|
+
request['newSize'] = this.amountToPrecision(symbol, amount);
|
|
2184
|
+
}
|
|
2185
|
+
if (price !== undefined) {
|
|
2186
|
+
request['newPrice'] = this.priceToPrecision(symbol, price);
|
|
2187
|
+
}
|
|
2188
|
+
const response = await this.privatePostHfOrdersAlter(this.extend(request, params));
|
|
2189
|
+
//
|
|
2190
|
+
// {
|
|
2191
|
+
// "code":"200000",
|
|
2192
|
+
// "data":{
|
|
2193
|
+
// "newOrderId":"6478d7a6c883280001e92d8b"
|
|
2194
|
+
// }
|
|
2195
|
+
// }
|
|
2196
|
+
//
|
|
2197
|
+
const data = this.safeValue(response, 'data', {});
|
|
2198
|
+
return this.parseOrder(data, market);
|
|
2199
|
+
}
|
|
2200
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
2201
|
+
/**
|
|
2202
|
+
* @method
|
|
2203
|
+
* @name kucoin#cancelOrder
|
|
2204
|
+
* @description cancels an open order
|
|
2205
|
+
* @see https://docs.kucoin.com/spot#cancel-an-order
|
|
2206
|
+
* @see https://docs.kucoin.com/spot#cancel-an-order-2
|
|
2207
|
+
* @see https://docs.kucoin.com/spot#cancel-single-order-by-clientoid
|
|
2208
|
+
* @see https://docs.kucoin.com/spot#cancel-single-order-by-clientoid-2
|
|
2209
|
+
* @see https://docs.kucoin.com/spot-hf/#cancel-orders-by-orderid
|
|
2210
|
+
* @see https://docs.kucoin.com/spot-hf/#cancel-order-by-clientoid
|
|
2211
|
+
* @param {string} id order id
|
|
2212
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
2213
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2214
|
+
* @param {bool} [params.stop] True if cancelling a stop order
|
|
2215
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
2216
|
+
* @returns Response from the exchange
|
|
2217
|
+
*/
|
|
2218
|
+
await this.loadMarkets();
|
|
2219
|
+
const request = {};
|
|
2220
|
+
const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
|
|
2221
|
+
const stop = this.safeValue2(params, 'stop', 'trigger', false);
|
|
2222
|
+
const hf = this.safeValue(params, 'hf', false);
|
|
2223
|
+
if (hf) {
|
|
2224
|
+
if (symbol === undefined) {
|
|
2225
|
+
throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol parameter for hf orders');
|
|
2226
|
+
}
|
|
2227
|
+
const market = this.market(symbol);
|
|
2228
|
+
request['symbol'] = market['id'];
|
|
2229
|
+
}
|
|
2230
|
+
let response = undefined;
|
|
2231
|
+
params = this.omit(params, ['clientOid', 'clientOrderId', 'stop', 'hf', 'trigger']);
|
|
2232
|
+
if (clientOrderId !== undefined) {
|
|
2233
|
+
request['clientOid'] = clientOrderId;
|
|
2234
|
+
if (stop) {
|
|
2235
|
+
response = await this.privateDeleteStopOrderCancelOrderByClientOid(this.extend(request, params));
|
|
2236
|
+
}
|
|
2237
|
+
else if (hf) {
|
|
2238
|
+
response = await this.privateDeleteHfOrdersClientOrderClientOid(this.extend(request, params));
|
|
2239
|
+
}
|
|
2240
|
+
else {
|
|
2241
|
+
response = await this.privateDeleteOrderClientOrderClientOid(this.extend(request, params));
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
else {
|
|
2245
|
+
request['orderId'] = id;
|
|
2246
|
+
if (stop) {
|
|
2247
|
+
response = await this.privateDeleteStopOrderOrderId(this.extend(request, params));
|
|
2248
|
+
}
|
|
2249
|
+
else if (hf) {
|
|
2250
|
+
response = await this.privateDeleteHfOrdersOrderId(this.extend(request, params));
|
|
2251
|
+
}
|
|
2252
|
+
else {
|
|
2253
|
+
response = await this.privateDeleteOrdersOrderId(this.extend(request, params));
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
return response;
|
|
2257
|
+
}
|
|
2258
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
2259
|
+
/**
|
|
2260
|
+
* @method
|
|
2261
|
+
* @name kucoin#cancelAllOrders
|
|
2262
|
+
* @description cancel all open orders
|
|
2263
|
+
* @see https://docs.kucoin.com/spot#cancel-all-orders
|
|
2264
|
+
* @see https://docs.kucoin.com/spot#cancel-orders
|
|
2265
|
+
* @see https://docs.kucoin.com/spot-hf/#cancel-all-hf-orders-by-symbol
|
|
2266
|
+
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
2267
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2268
|
+
* @param {bool} [params.stop] *invalid for isolated margin* true if cancelling all stop orders
|
|
2269
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated'
|
|
2270
|
+
* @param {string} [params.orderIds] *stop orders only* Comma seperated order IDs
|
|
2271
|
+
* @param {bool} [params.stop] True if cancelling a stop order
|
|
2272
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
2273
|
+
* @returns Response from the exchange
|
|
2274
|
+
*/
|
|
2275
|
+
await this.loadMarkets();
|
|
2276
|
+
const request = {};
|
|
2277
|
+
const stop = this.safeValue(params, 'stop', false);
|
|
2278
|
+
const hf = this.safeValue(params, 'hf', false);
|
|
2279
|
+
params = this.omit(params, ['stop', 'hf']);
|
|
2280
|
+
const [marginMode, query] = this.handleMarginModeAndParams('cancelAllOrders', params);
|
|
2281
|
+
if (symbol !== undefined) {
|
|
2282
|
+
request['symbol'] = this.marketId(symbol);
|
|
2283
|
+
}
|
|
2284
|
+
if (marginMode !== undefined) {
|
|
2285
|
+
request['tradeType'] = this.options['marginModes'][marginMode];
|
|
2286
|
+
if (marginMode === 'isolated' && stop) {
|
|
2287
|
+
throw new errors.BadRequest(this.id + ' cancelAllOrders does not support isolated margin for stop orders');
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
let response = undefined;
|
|
2291
|
+
if (stop) {
|
|
2292
|
+
response = await this.privateDeleteStopOrderCancel(this.extend(request, query));
|
|
2293
|
+
}
|
|
2294
|
+
else if (hf) {
|
|
2295
|
+
if (symbol === undefined) {
|
|
2296
|
+
response = await this.privateDeleteHfOrdersCancelAll(this.extend(request, query));
|
|
2297
|
+
}
|
|
2298
|
+
else {
|
|
2299
|
+
response = await this.privateDeleteHfOrders(this.extend(request, query));
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
else {
|
|
2303
|
+
response = await this.privateDeleteOrders(this.extend(request, query));
|
|
2304
|
+
}
|
|
2305
|
+
return response;
|
|
2306
|
+
}
|
|
2307
|
+
async fetchOrdersByStatus(status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2308
|
+
/**
|
|
2309
|
+
* @method
|
|
2310
|
+
* @name kucoin#fetchOrdersByStatus
|
|
2311
|
+
* @description fetch a list of orders
|
|
2312
|
+
* @see https://docs.kucoin.com/spot#list-orders
|
|
2313
|
+
* @see https://docs.kucoin.com/spot#list-stop-orders
|
|
2314
|
+
* @see https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
|
|
2315
|
+
* @see https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
|
|
2316
|
+
* @param {string} status *not used for stop orders* 'open' or 'closed'
|
|
2317
|
+
* @param {string} symbol unified market symbol
|
|
2318
|
+
* @param {int} [since] timestamp in ms of the earliest order
|
|
2319
|
+
* @param {int} [limit] max number of orders to return
|
|
2320
|
+
* @param {object} [params] exchange specific params
|
|
2321
|
+
* @param {int} [params.until] end time in ms
|
|
2322
|
+
* @param {bool} [params.stop] true if fetching stop orders
|
|
2323
|
+
* @param {string} [params.side] buy or sell
|
|
2324
|
+
* @param {string} [params.type] limit, market, limit_stop or market_stop
|
|
2325
|
+
* @param {string} [params.tradeType] TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
|
2326
|
+
* @param {int} [params.currentPage] *stop orders only* current page
|
|
2327
|
+
* @param {string} [params.orderIds] *stop orders only* comma seperated order ID list
|
|
2328
|
+
* @param {bool} [params.stop] True if fetching a stop order
|
|
2329
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
2330
|
+
* @returns An [array of order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2331
|
+
*/
|
|
2332
|
+
await this.loadMarkets();
|
|
2333
|
+
let lowercaseStatus = status.toLowerCase();
|
|
2334
|
+
const until = this.safeInteger2(params, 'until', 'till');
|
|
2335
|
+
const stop = this.safeValue(params, 'stop', false);
|
|
2336
|
+
const hf = this.safeValue(params, 'hf', false);
|
|
2337
|
+
params = this.omit(params, ['stop', 'hf', 'till', 'until']);
|
|
2338
|
+
const [marginMode, query] = this.handleMarginModeAndParams('fetchOrdersByStatus', params);
|
|
2339
|
+
if (lowercaseStatus === 'open') {
|
|
2340
|
+
lowercaseStatus = 'active';
|
|
2341
|
+
}
|
|
2342
|
+
else if (lowercaseStatus === 'closed') {
|
|
2343
|
+
lowercaseStatus = 'done';
|
|
2344
|
+
}
|
|
2345
|
+
const request = {
|
|
2346
|
+
'status': lowercaseStatus,
|
|
2347
|
+
};
|
|
2348
|
+
let market = undefined;
|
|
2349
|
+
if (symbol !== undefined) {
|
|
2350
|
+
market = this.market(symbol);
|
|
2351
|
+
request['symbol'] = market['id'];
|
|
2352
|
+
}
|
|
2353
|
+
if (since !== undefined) {
|
|
2354
|
+
request['startAt'] = since;
|
|
2355
|
+
}
|
|
2356
|
+
if (limit !== undefined) {
|
|
2357
|
+
request['pageSize'] = limit;
|
|
2358
|
+
}
|
|
2359
|
+
if (until) {
|
|
2360
|
+
request['endAt'] = until;
|
|
2361
|
+
}
|
|
2362
|
+
request['tradeType'] = this.safeString(this.options['marginModes'], marginMode, 'TRADE');
|
|
2363
|
+
let response = undefined;
|
|
2364
|
+
if (stop) {
|
|
2365
|
+
response = await this.privateGetStopOrder(this.extend(request, query));
|
|
2366
|
+
}
|
|
2367
|
+
else if (hf) {
|
|
2368
|
+
if (lowercaseStatus === 'active') {
|
|
2369
|
+
response = await this.privateGetHfOrdersActive(this.extend(request, query));
|
|
2370
|
+
}
|
|
2371
|
+
else if (lowercaseStatus === 'done') {
|
|
2372
|
+
response = await this.privateGetHfOrdersDone(this.extend(request, query));
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
else {
|
|
2376
|
+
response = await this.privateGetOrders(this.extend(request, query));
|
|
2377
|
+
}
|
|
2378
|
+
//
|
|
2379
|
+
// {
|
|
2380
|
+
// "code": "200000",
|
|
2381
|
+
// "data": {
|
|
2382
|
+
// "currentPage": 1,
|
|
2383
|
+
// "pageSize": 1,
|
|
2384
|
+
// "totalNum": 153408,
|
|
2385
|
+
// "totalPage": 153408,
|
|
2386
|
+
// "items": [
|
|
2387
|
+
// {
|
|
2388
|
+
// "id": "5c35c02703aa673ceec2a168", //orderid
|
|
2389
|
+
// "symbol": "BTC-USDT", //symbol
|
|
2390
|
+
// "opType": "DEAL", // operation type,deal is pending order,cancel is cancel order
|
|
2391
|
+
// "type": "limit", // order type,e.g. limit,markrt,stop_limit.
|
|
2392
|
+
// "side": "buy", // transaction direction,include buy and sell
|
|
2393
|
+
// "price": "10", // order price
|
|
2394
|
+
// "size": "2", // order quantity
|
|
2395
|
+
// "funds": "0", // order funds
|
|
2396
|
+
// "dealFunds": "0.166", // deal funds
|
|
2397
|
+
// "dealSize": "2", // deal quantity
|
|
2398
|
+
// "fee": "0", // fee
|
|
2399
|
+
// "feeCurrency": "USDT", // charge fee currency
|
|
2400
|
+
// "stp": "", // self trade prevention,include CN,CO,DC,CB
|
|
2401
|
+
// "stop": "", // stop type
|
|
2402
|
+
// "stopTriggered": false, // stop order is triggered
|
|
2403
|
+
// "stopPrice": "0", // stop price
|
|
2404
|
+
// "timeInForce": "GTC", // time InForce,include GTC,GTT,IOC,FOK
|
|
2405
|
+
// "postOnly": false, // postOnly
|
|
2406
|
+
// "hidden": false, // hidden order
|
|
2407
|
+
// "iceberg": false, // iceberg order
|
|
2408
|
+
// "visibleSize": "0", // display quantity for iceberg order
|
|
2409
|
+
// "cancelAfter": 0, // cancel orders time,requires timeInForce to be GTT
|
|
2410
|
+
// "channel": "IOS", // order source
|
|
2411
|
+
// "clientOid": "", // user-entered order unique mark
|
|
2412
|
+
// "remark": "", // remark
|
|
2413
|
+
// "tags": "", // tag order source
|
|
2414
|
+
// "isActive": false, // status before unfilled or uncancelled
|
|
2415
|
+
// "cancelExist": false, // order cancellation transaction record
|
|
2416
|
+
// "createdAt": 1547026471000 // time
|
|
2417
|
+
// },
|
|
2418
|
+
// ]
|
|
2419
|
+
// }
|
|
2420
|
+
// }
|
|
2421
|
+
const responseData = this.safeValue(response, 'data', {});
|
|
2422
|
+
const orders = this.safeValue(responseData, 'items', responseData);
|
|
2423
|
+
return this.parseOrders(orders, market, since, limit);
|
|
2424
|
+
}
|
|
2425
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2426
|
+
/**
|
|
2427
|
+
* @method
|
|
2428
|
+
* @name kucoin#fetchClosedOrders
|
|
2429
|
+
* @description fetches information on multiple closed orders made by the user
|
|
2430
|
+
* @see https://docs.kucoin.com/spot#list-orders
|
|
2431
|
+
* @see https://docs.kucoin.com/spot#list-stop-orders
|
|
2432
|
+
* @see https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
|
|
2433
|
+
* @see https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
|
|
2434
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
2435
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2436
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
2437
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2438
|
+
* @param {int} [params.till] end time in ms
|
|
2439
|
+
* @param {string} [params.side] buy or sell
|
|
2440
|
+
* @param {string} [params.type] limit, market, limit_stop or market_stop
|
|
2441
|
+
* @param {string} [params.tradeType] TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
|
2442
|
+
* @param {bool} [params.stop] True if fetching a stop order
|
|
2443
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
2444
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
2445
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2446
|
+
*/
|
|
2447
|
+
await this.loadMarkets();
|
|
2448
|
+
let paginate = false;
|
|
2449
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'paginate');
|
|
2450
|
+
if (paginate) {
|
|
2451
|
+
return await this.fetchPaginatedCallDynamic('fetchClosedOrders', symbol, since, limit, params);
|
|
2452
|
+
}
|
|
2453
|
+
return await this.fetchOrdersByStatus('done', symbol, since, limit, params);
|
|
2454
|
+
}
|
|
2455
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2456
|
+
/**
|
|
2457
|
+
* @method
|
|
2458
|
+
* @name kucoin#fetchOpenOrders
|
|
2459
|
+
* @description fetch all unfilled currently open orders
|
|
2460
|
+
* @see https://docs.kucoin.com/spot#list-orders
|
|
2461
|
+
* @see https://docs.kucoin.com/spot#list-stop-orders
|
|
2462
|
+
* @see https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
|
|
2463
|
+
* @see https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
|
|
2464
|
+
* @param {string} symbol unified market symbol
|
|
2465
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
2466
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
2467
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2468
|
+
* @param {int} [params.till] end time in ms
|
|
2469
|
+
* @param {bool} [params.stop] true if fetching stop orders
|
|
2470
|
+
* @param {string} [params.side] buy or sell
|
|
2471
|
+
* @param {string} [params.type] limit, market, limit_stop or market_stop
|
|
2472
|
+
* @param {string} [params.tradeType] TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
|
2473
|
+
* @param {int} [params.currentPage] *stop orders only* current page
|
|
2474
|
+
* @param {string} [params.orderIds] *stop orders only* comma seperated order ID list
|
|
2475
|
+
* @param {bool} [params.stop] True if fetching a stop order
|
|
2476
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
2477
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
2478
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2479
|
+
*/
|
|
2480
|
+
await this.loadMarkets();
|
|
2481
|
+
let paginate = false;
|
|
2482
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'paginate');
|
|
2483
|
+
if (paginate) {
|
|
2484
|
+
return await this.fetchPaginatedCallDynamic('fetchOpenOrders', symbol, since, limit, params);
|
|
2485
|
+
}
|
|
2486
|
+
return await this.fetchOrdersByStatus('active', symbol, since, limit, params);
|
|
2487
|
+
}
|
|
2488
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
2489
|
+
/**
|
|
2490
|
+
* @method
|
|
2491
|
+
* @name kucoin#fetchOrder
|
|
2492
|
+
* @description fetch an order
|
|
2493
|
+
* @see https://docs.kucoin.com/spot#get-an-order
|
|
2494
|
+
* @see https://docs.kucoin.com/spot#get-single-active-order-by-clientoid
|
|
2495
|
+
* @see https://docs.kucoin.com/spot#get-single-order-info
|
|
2496
|
+
* @see https://docs.kucoin.com/spot#get-single-order-by-clientoid
|
|
2497
|
+
* @see https://docs.kucoin.com/spot-hf/#details-of-a-single-hf-order
|
|
2498
|
+
* @see https://docs.kucoin.com/spot-hf/#obtain-details-of-a-single-hf-order-using-clientoid
|
|
2499
|
+
* @param {string} id Order id
|
|
2500
|
+
* @param {string} symbol not sent to exchange except for stop orders with clientOid, but used internally by CCXT to filter
|
|
2501
|
+
* @param {object} [params] exchange specific parameters
|
|
2502
|
+
* @param {bool} [params.stop] true if fetching a stop order
|
|
2503
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
2504
|
+
* @param {bool} [params.clientOid] unique order id created by users to identify their orders
|
|
2505
|
+
* @returns An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2506
|
+
*/
|
|
2507
|
+
await this.loadMarkets();
|
|
2508
|
+
const request = {};
|
|
2509
|
+
const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
|
|
2510
|
+
const stop = this.safeValue(params, 'stop', false);
|
|
2511
|
+
const hf = this.safeValue(params, 'hf', false);
|
|
2512
|
+
let market = undefined;
|
|
2513
|
+
if (symbol !== undefined) {
|
|
2514
|
+
market = this.market(symbol);
|
|
2515
|
+
}
|
|
2516
|
+
if (hf) {
|
|
2517
|
+
if (symbol === undefined) {
|
|
2518
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires a symbol parameter for hf orders');
|
|
2519
|
+
}
|
|
2520
|
+
request['symbol'] = market['id'];
|
|
2521
|
+
}
|
|
2522
|
+
params = this.omit(params, ['stop', 'hf', 'clientOid', 'clientOrderId']);
|
|
2523
|
+
let response = undefined;
|
|
2524
|
+
if (clientOrderId !== undefined) {
|
|
2525
|
+
request['clientOid'] = clientOrderId;
|
|
2526
|
+
if (stop) {
|
|
2527
|
+
if (symbol !== undefined) {
|
|
2528
|
+
request['symbol'] = market['id'];
|
|
2529
|
+
}
|
|
2530
|
+
response = await this.privateGetStopOrderQueryOrderByClientOid(this.extend(request, params));
|
|
2531
|
+
}
|
|
2532
|
+
else if (hf) {
|
|
2533
|
+
response = await this.privateGetHfOrdersClientOrderClientOid(this.extend(request, params));
|
|
2534
|
+
}
|
|
2535
|
+
else {
|
|
2536
|
+
response = await this.privateGetOrderClientOrderClientOid(this.extend(request, params));
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
else {
|
|
2540
|
+
// a special case for undefined ids
|
|
2541
|
+
// otherwise a wrong endpoint for all orders will be triggered
|
|
2542
|
+
// https://github.com/ccxt/ccxt/issues/7234
|
|
2543
|
+
if (id === undefined) {
|
|
2544
|
+
throw new errors.InvalidOrder(this.id + ' fetchOrder() requires an order id');
|
|
2545
|
+
}
|
|
2546
|
+
request['orderId'] = id;
|
|
2547
|
+
if (stop) {
|
|
2548
|
+
response = await this.privateGetStopOrderOrderId(this.extend(request, params));
|
|
2549
|
+
}
|
|
2550
|
+
else if (hf) {
|
|
2551
|
+
response = await this.privateGetHfOrdersOrderId(this.extend(request, params));
|
|
2552
|
+
}
|
|
2553
|
+
else {
|
|
2554
|
+
response = await this.privateGetOrdersOrderId(this.extend(request, params));
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
let responseData = this.safeValue(response, 'data', {});
|
|
2558
|
+
if (Array.isArray(responseData)) {
|
|
2559
|
+
responseData = this.safeValue(responseData, 0);
|
|
2560
|
+
}
|
|
2561
|
+
return this.parseOrder(responseData, market);
|
|
2562
|
+
}
|
|
2563
|
+
parseOrder(order, market = undefined) {
|
|
2564
|
+
//
|
|
2565
|
+
// createOrder
|
|
2566
|
+
//
|
|
2567
|
+
// {
|
|
2568
|
+
// "orderId": "63c97e47d686c5000159a656"
|
|
2569
|
+
// }
|
|
2570
|
+
//
|
|
2571
|
+
// cancelOrder
|
|
2572
|
+
//
|
|
2573
|
+
// {
|
|
2574
|
+
// "cancelledOrderIds": [ "63c97e47d686c5000159a656" ]
|
|
2575
|
+
// }
|
|
2576
|
+
//
|
|
2577
|
+
// fetchOpenOrders, fetchClosedOrders
|
|
2578
|
+
//
|
|
2579
|
+
// {
|
|
2580
|
+
// "id": "63c97ce8d686c500015793bb",
|
|
2581
|
+
// "symbol": "USDC-USDT",
|
|
2582
|
+
// "opType": "DEAL",
|
|
2583
|
+
// "type": "limit",
|
|
2584
|
+
// "side": "sell",
|
|
2585
|
+
// "price": "1.05",
|
|
2586
|
+
// "size": "1",
|
|
2587
|
+
// "funds": "0",
|
|
2588
|
+
// "dealFunds": "0",
|
|
2589
|
+
// "dealSize": "0",
|
|
2590
|
+
// "fee": "0",
|
|
2591
|
+
// "feeCurrency": "USDT",
|
|
2592
|
+
// "stp": "",
|
|
2593
|
+
// "stop": "",
|
|
2594
|
+
// "stopTriggered": false,
|
|
2595
|
+
// "stopPrice": "0",
|
|
2596
|
+
// "timeInForce": "GTC",
|
|
2597
|
+
// "postOnly": false,
|
|
2598
|
+
// "hidden": false,
|
|
2599
|
+
// "iceberg": false,
|
|
2600
|
+
// "visibleSize": "0",
|
|
2601
|
+
// "cancelAfter": 0,
|
|
2602
|
+
// "channel": "API",
|
|
2603
|
+
// "clientOid": "d602d73f-5424-4751-bef0-8debce8f0a82",
|
|
2604
|
+
// "remark": null,
|
|
2605
|
+
// "tags": "partner:ccxt",
|
|
2606
|
+
// "isActive": true,
|
|
2607
|
+
// "cancelExist": false,
|
|
2608
|
+
// "createdAt": 1674149096927,
|
|
2609
|
+
// "tradeType": "TRADE"
|
|
2610
|
+
// }
|
|
2611
|
+
//
|
|
2612
|
+
// stop orders (fetchOpenOrders, fetchClosedOrders)
|
|
2613
|
+
//
|
|
2614
|
+
// {
|
|
2615
|
+
// "id": "vs9f6ou9e864rgq8000t4qnm",
|
|
2616
|
+
// "symbol": "USDC-USDT",
|
|
2617
|
+
// "userId": "613a896885d8660006151f01",
|
|
2618
|
+
// "status": "NEW",
|
|
2619
|
+
// "type": "market",
|
|
2620
|
+
// "side": "sell",
|
|
2621
|
+
// "price": null,
|
|
2622
|
+
// "size": "1.00000000000000000000",
|
|
2623
|
+
// "funds": null,
|
|
2624
|
+
// "stp": null,
|
|
2625
|
+
// "timeInForce": "GTC",
|
|
2626
|
+
// "cancelAfter": -1,
|
|
2627
|
+
// "postOnly": false,
|
|
2628
|
+
// "hidden": false,
|
|
2629
|
+
// "iceberg": false,
|
|
2630
|
+
// "visibleSize": null,
|
|
2631
|
+
// "channel": "API",
|
|
2632
|
+
// "clientOid": "5d3fd727-6456-438d-9550-40d9d85eee0b",
|
|
2633
|
+
// "remark": null,
|
|
2634
|
+
// "tags": "partner:ccxt",
|
|
2635
|
+
// "relatedNo": null,
|
|
2636
|
+
// "orderTime": 1674146316994000028,
|
|
2637
|
+
// "domainId": "kucoin",
|
|
2638
|
+
// "tradeSource": "USER",
|
|
2639
|
+
// "tradeType": "MARGIN_TRADE",
|
|
2640
|
+
// "feeCurrency": "USDT",
|
|
2641
|
+
// "takerFeeRate": "0.00100000000000000000",
|
|
2642
|
+
// "makerFeeRate": "0.00100000000000000000",
|
|
2643
|
+
// "createdAt": 1674146316994,
|
|
2644
|
+
// "stop": "loss",
|
|
2645
|
+
// "stopTriggerTime": null,
|
|
2646
|
+
// "stopPrice": "0.97000000000000000000"
|
|
2647
|
+
// }
|
|
2648
|
+
// hf order
|
|
2649
|
+
// {
|
|
2650
|
+
// "id":"6478cf1439bdfc0001528a1d",
|
|
2651
|
+
// "symbol":"LTC-USDT",
|
|
2652
|
+
// "opType":"DEAL",
|
|
2653
|
+
// "type":"limit",
|
|
2654
|
+
// "side":"buy",
|
|
2655
|
+
// "price":"50",
|
|
2656
|
+
// "size":"0.1",
|
|
2657
|
+
// "funds":"5",
|
|
2658
|
+
// "dealSize":"0",
|
|
2659
|
+
// "dealFunds":"0",
|
|
2660
|
+
// "fee":"0",
|
|
2661
|
+
// "feeCurrency":"USDT",
|
|
2662
|
+
// "stp":null,
|
|
2663
|
+
// "timeInForce":"GTC",
|
|
2664
|
+
// "postOnly":false,
|
|
2665
|
+
// "hidden":false,
|
|
2666
|
+
// "iceberg":false,
|
|
2667
|
+
// "visibleSize":"0",
|
|
2668
|
+
// "cancelAfter":0,
|
|
2669
|
+
// "channel":"API",
|
|
2670
|
+
// "clientOid":"d4d2016b-8e3a-445c-aa5d-dc6df5d1678d",
|
|
2671
|
+
// "remark":null,
|
|
2672
|
+
// "tags":"partner:ccxt",
|
|
2673
|
+
// "cancelExist":false,
|
|
2674
|
+
// "createdAt":1685638932074,
|
|
2675
|
+
// "lastUpdatedAt":1685639013735,
|
|
2676
|
+
// "tradeType":"TRADE",
|
|
2677
|
+
// "inOrderBook":true,
|
|
2678
|
+
// "cancelledSize":"0",
|
|
2679
|
+
// "cancelledFunds":"0",
|
|
2680
|
+
// "remainSize":"0.1",
|
|
2681
|
+
// "remainFunds":"5",
|
|
2682
|
+
// "active":true
|
|
2683
|
+
// }
|
|
2684
|
+
//
|
|
2685
|
+
const marketId = this.safeString(order, 'symbol');
|
|
2686
|
+
const timestamp = this.safeInteger(order, 'createdAt');
|
|
2687
|
+
const feeCurrencyId = this.safeString(order, 'feeCurrency');
|
|
2688
|
+
const cancelExist = this.safeValue(order, 'cancelExist', false);
|
|
2689
|
+
const responseStop = this.safeString(order, 'stop');
|
|
2690
|
+
const stop = responseStop !== undefined;
|
|
2691
|
+
const stopTriggered = this.safeValue(order, 'stopTriggered', false);
|
|
2692
|
+
const isActive = this.safeValue2(order, 'isActive', 'active');
|
|
2693
|
+
const responseStatus = this.safeString(order, 'status');
|
|
2694
|
+
let status = undefined;
|
|
2695
|
+
if (isActive !== undefined) {
|
|
2696
|
+
if (isActive === true) {
|
|
2697
|
+
status = 'open';
|
|
2698
|
+
}
|
|
2699
|
+
else {
|
|
2700
|
+
status = 'closed';
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
if (stop) {
|
|
2704
|
+
if (responseStatus === 'NEW') {
|
|
2705
|
+
status = 'open';
|
|
2706
|
+
}
|
|
2707
|
+
else if (!isActive && !stopTriggered) {
|
|
2708
|
+
status = 'cancelled';
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
if (cancelExist) {
|
|
2712
|
+
status = 'canceled';
|
|
2713
|
+
}
|
|
2714
|
+
if (responseStatus === 'fail') {
|
|
2715
|
+
status = 'rejected';
|
|
2716
|
+
}
|
|
2717
|
+
const stopPrice = this.safeNumber(order, 'stopPrice');
|
|
2718
|
+
return this.safeOrder({
|
|
2719
|
+
'info': order,
|
|
2720
|
+
'id': this.safeStringN(order, ['id', 'orderId', 'newOrderId']),
|
|
2721
|
+
'clientOrderId': this.safeString(order, 'clientOid'),
|
|
2722
|
+
'symbol': this.safeSymbol(marketId, market, '-'),
|
|
2723
|
+
'type': this.safeString(order, 'type'),
|
|
2724
|
+
'timeInForce': this.safeString(order, 'timeInForce'),
|
|
2725
|
+
'postOnly': this.safeValue(order, 'postOnly'),
|
|
2726
|
+
'side': this.safeString(order, 'side'),
|
|
2727
|
+
'amount': this.safeString(order, 'size'),
|
|
2728
|
+
'price': this.safeString(order, 'price'),
|
|
2729
|
+
'stopPrice': stopPrice,
|
|
2730
|
+
'triggerPrice': stopPrice,
|
|
2731
|
+
'cost': this.safeString(order, 'dealFunds'),
|
|
2732
|
+
'filled': this.safeString(order, 'dealSize'),
|
|
2733
|
+
'remaining': undefined,
|
|
2734
|
+
'timestamp': timestamp,
|
|
2735
|
+
'datetime': this.iso8601(timestamp),
|
|
2736
|
+
'fee': {
|
|
2737
|
+
'currency': this.safeCurrencyCode(feeCurrencyId),
|
|
2738
|
+
'cost': this.safeNumber(order, 'fee'),
|
|
2739
|
+
},
|
|
2740
|
+
'status': status,
|
|
2741
|
+
'lastTradeTimestamp': undefined,
|
|
2742
|
+
'average': undefined,
|
|
2743
|
+
'trades': undefined,
|
|
2744
|
+
}, market);
|
|
2745
|
+
}
|
|
2746
|
+
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2747
|
+
/**
|
|
2748
|
+
* @method
|
|
2749
|
+
* @name kucoin#fetchOrderTrades
|
|
2750
|
+
* @description fetch all the trades made from a single order
|
|
2751
|
+
* @see https://docs.kucoin.com/#list-fills
|
|
2752
|
+
* @see https://docs.kucoin.com/spot-hf/#transaction-details
|
|
2753
|
+
* @param {string} id order id
|
|
2754
|
+
* @param {string} symbol unified market symbol
|
|
2755
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
2756
|
+
* @param {int} [limit] the maximum number of trades to retrieve
|
|
2757
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2758
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2759
|
+
*/
|
|
2760
|
+
const request = {
|
|
2761
|
+
'orderId': id,
|
|
2762
|
+
};
|
|
2763
|
+
return await this.fetchMyTrades(symbol, since, limit, this.extend(request, params));
|
|
2764
|
+
}
|
|
2765
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2766
|
+
/**
|
|
2767
|
+
* @method
|
|
2768
|
+
* @name kucoin#fetchMyTrades
|
|
2769
|
+
* @see https://docs.kucoin.com/#list-fills
|
|
2770
|
+
* @see https://docs.kucoin.com/spot-hf/#transaction-details
|
|
2771
|
+
* @description fetch all trades made by the user
|
|
2772
|
+
* @param {string} symbol unified market symbol
|
|
2773
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
2774
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
2775
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2776
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
2777
|
+
* @param {bool} [params.hf] false, // true for hf order
|
|
2778
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
2779
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2780
|
+
*/
|
|
2781
|
+
await this.loadMarkets();
|
|
2782
|
+
let paginate = false;
|
|
2783
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'paginate');
|
|
2784
|
+
if (paginate) {
|
|
2785
|
+
return await this.fetchPaginatedCallDynamic('fetchMyTrades', symbol, since, limit, params);
|
|
2786
|
+
}
|
|
2787
|
+
let request = {};
|
|
2788
|
+
const hf = this.safeValue(params, 'hf', false);
|
|
2789
|
+
if (hf && symbol === undefined) {
|
|
2790
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol parameter for hf orders');
|
|
2791
|
+
}
|
|
2792
|
+
let market = undefined;
|
|
2793
|
+
if (symbol !== undefined) {
|
|
2794
|
+
market = this.market(symbol);
|
|
2795
|
+
request['symbol'] = market['id'];
|
|
2796
|
+
}
|
|
2797
|
+
if (limit !== undefined) {
|
|
2798
|
+
request['pageSize'] = limit;
|
|
2799
|
+
}
|
|
2800
|
+
const method = this.options['fetchMyTradesMethod'];
|
|
2801
|
+
let parseResponseData = false;
|
|
2802
|
+
let response = undefined;
|
|
2803
|
+
[request, params] = this.handleUntilOption('endAt', request, params);
|
|
2804
|
+
if (hf) {
|
|
2805
|
+
response = await this.privateGetHfFills(this.extend(request, params));
|
|
2806
|
+
}
|
|
2807
|
+
else if (method === 'private_get_fills') {
|
|
2808
|
+
// does not return trades earlier than 2019-02-18T00:00:00Z
|
|
2809
|
+
if (since !== undefined) {
|
|
2810
|
+
// only returns trades up to one week after the since param
|
|
2811
|
+
request['startAt'] = since;
|
|
2812
|
+
}
|
|
2813
|
+
response = await this.privateGetFills(this.extend(request, params));
|
|
2814
|
+
}
|
|
2815
|
+
else if (method === 'private_get_limit_fills') {
|
|
2816
|
+
// does not return trades earlier than 2019-02-18T00:00:00Z
|
|
2817
|
+
// takes no params
|
|
2818
|
+
// only returns first 1000 trades (not only "in the last 24 hours" as stated in the docs)
|
|
2819
|
+
parseResponseData = true;
|
|
2820
|
+
response = await this.privateGetLimitFills(this.extend(request, params));
|
|
2821
|
+
}
|
|
2822
|
+
else {
|
|
2823
|
+
throw new errors.ExchangeError(this.id + ' fetchMyTradesMethod() invalid method');
|
|
2824
|
+
}
|
|
2825
|
+
//
|
|
2826
|
+
// {
|
|
2827
|
+
// "currentPage": 1,
|
|
2828
|
+
// "pageSize": 50,
|
|
2829
|
+
// "totalNum": 1,
|
|
2830
|
+
// "totalPage": 1,
|
|
2831
|
+
// "items": [
|
|
2832
|
+
// {
|
|
2833
|
+
// "symbol":"BTC-USDT", // symbol
|
|
2834
|
+
// "tradeId":"5c35c02709e4f67d5266954e", // trade id
|
|
2835
|
+
// "orderId":"5c35c02703aa673ceec2a168", // order id
|
|
2836
|
+
// "counterOrderId":"5c1ab46003aa676e487fa8e3", // counter order id
|
|
2837
|
+
// "side":"buy", // transaction direction,include buy and sell
|
|
2838
|
+
// "liquidity":"taker", // include taker and maker
|
|
2839
|
+
// "forceTaker":true, // forced to become taker
|
|
2840
|
+
// "price":"0.083", // order price
|
|
2841
|
+
// "size":"0.8424304", // order quantity
|
|
2842
|
+
// "funds":"0.0699217232", // order funds
|
|
2843
|
+
// "fee":"0", // fee
|
|
2844
|
+
// "feeRate":"0", // fee rate
|
|
2845
|
+
// "feeCurrency":"USDT", // charge fee currency
|
|
2846
|
+
// "stop":"", // stop type
|
|
2847
|
+
// "type":"limit", // order type, e.g. limit, market, stop_limit.
|
|
2848
|
+
// "createdAt":1547026472000 // time
|
|
2849
|
+
// },
|
|
2850
|
+
// //------------------------------------------------------
|
|
2851
|
+
// // v1 (historical) trade response structure
|
|
2852
|
+
// {
|
|
2853
|
+
// "symbol": "SNOV-ETH",
|
|
2854
|
+
// "dealPrice": "0.0000246",
|
|
2855
|
+
// "dealValue": "0.018942",
|
|
2856
|
+
// "amount": "770",
|
|
2857
|
+
// "fee": "0.00001137",
|
|
2858
|
+
// "side": "sell",
|
|
2859
|
+
// "createdAt": 1540080199
|
|
2860
|
+
// "id":"5c4d389e4c8c60413f78e2e5",
|
|
2861
|
+
// }
|
|
2862
|
+
// ]
|
|
2863
|
+
// }
|
|
2864
|
+
//
|
|
2865
|
+
const data = this.safeValue(response, 'data', {});
|
|
2866
|
+
let trades = undefined;
|
|
2867
|
+
if (parseResponseData) {
|
|
2868
|
+
trades = data;
|
|
2869
|
+
}
|
|
2870
|
+
else {
|
|
2871
|
+
trades = this.safeValue(data, 'items', []);
|
|
2872
|
+
}
|
|
2873
|
+
return this.parseTrades(trades, market, since, limit);
|
|
2874
|
+
}
|
|
2875
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
2876
|
+
/**
|
|
2877
|
+
* @method
|
|
2878
|
+
* @name kucoin#fetchTrades
|
|
2879
|
+
* @description get the list of most recent trades for a particular symbol
|
|
2880
|
+
* @see https://docs.kucoin.com/#get-trade-histories
|
|
2881
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
2882
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
2883
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
2884
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2885
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
2886
|
+
*/
|
|
2887
|
+
await this.loadMarkets();
|
|
2888
|
+
const market = this.market(symbol);
|
|
2889
|
+
const request = {
|
|
2890
|
+
'symbol': market['id'],
|
|
2891
|
+
};
|
|
2892
|
+
// pagination is not supported on the exchange side anymore
|
|
2893
|
+
// if (since !== undefined) {
|
|
2894
|
+
// request['startAt'] = Math.floor (since / 1000);
|
|
2895
|
+
// }
|
|
2896
|
+
// if (limit !== undefined) {
|
|
2897
|
+
// request['pageSize'] = limit;
|
|
2898
|
+
// }
|
|
2899
|
+
const response = await this.publicGetMarketHistories(this.extend(request, params));
|
|
2900
|
+
//
|
|
2901
|
+
// {
|
|
2902
|
+
// "code": "200000",
|
|
2903
|
+
// "data": [
|
|
2904
|
+
// {
|
|
2905
|
+
// "sequence": "1548764654235",
|
|
2906
|
+
// "side": "sell",
|
|
2907
|
+
// "size":"0.6841354",
|
|
2908
|
+
// "price":"0.03202",
|
|
2909
|
+
// "time":1548848575203567174
|
|
2910
|
+
// }
|
|
2911
|
+
// ]
|
|
2912
|
+
// }
|
|
2913
|
+
//
|
|
2914
|
+
const trades = this.safeValue(response, 'data', []);
|
|
2915
|
+
return this.parseTrades(trades, market, since, limit);
|
|
2916
|
+
}
|
|
2917
|
+
parseTrade(trade, market = undefined) {
|
|
2918
|
+
//
|
|
2919
|
+
// fetchTrades (public)
|
|
2920
|
+
//
|
|
2921
|
+
// {
|
|
2922
|
+
// "sequence": "1548764654235",
|
|
2923
|
+
// "side": "sell",
|
|
2924
|
+
// "size":"0.6841354",
|
|
2925
|
+
// "price":"0.03202",
|
|
2926
|
+
// "time":1548848575203567174
|
|
2927
|
+
// }
|
|
2928
|
+
//
|
|
2929
|
+
// {
|
|
2930
|
+
// "sequence": "1568787654360",
|
|
2931
|
+
// "symbol": "BTC-USDT",
|
|
2932
|
+
// "side": "buy",
|
|
2933
|
+
// "size": "0.00536577",
|
|
2934
|
+
// "price": "9345",
|
|
2935
|
+
// "takerOrderId": "5e356c4a9f1a790008f8d921",
|
|
2936
|
+
// "time": "1580559434436443257",
|
|
2937
|
+
// "type": "match",
|
|
2938
|
+
// "makerOrderId": "5e356bffedf0010008fa5d7f",
|
|
2939
|
+
// "tradeId": "5e356c4aeefabd62c62a1ece"
|
|
2940
|
+
// }
|
|
2941
|
+
//
|
|
2942
|
+
// fetchMyTrades (private) v2
|
|
2943
|
+
//
|
|
2944
|
+
// {
|
|
2945
|
+
// "symbol":"BTC-USDT",
|
|
2946
|
+
// "tradeId":"5c35c02709e4f67d5266954e",
|
|
2947
|
+
// "orderId":"5c35c02703aa673ceec2a168",
|
|
2948
|
+
// "counterOrderId":"5c1ab46003aa676e487fa8e3",
|
|
2949
|
+
// "side":"buy",
|
|
2950
|
+
// "liquidity":"taker",
|
|
2951
|
+
// "forceTaker":true,
|
|
2952
|
+
// "price":"0.083",
|
|
2953
|
+
// "size":"0.8424304",
|
|
2954
|
+
// "funds":"0.0699217232",
|
|
2955
|
+
// "fee":"0",
|
|
2956
|
+
// "feeRate":"0",
|
|
2957
|
+
// "feeCurrency":"USDT",
|
|
2958
|
+
// "stop":"",
|
|
2959
|
+
// "type":"limit",
|
|
2960
|
+
// "createdAt":1547026472000
|
|
2961
|
+
// }
|
|
2962
|
+
//
|
|
2963
|
+
// fetchMyTrades v2 alternative format since 2019-05-21 https://github.com/ccxt/ccxt/pull/5162
|
|
2964
|
+
//
|
|
2965
|
+
// {
|
|
2966
|
+
// "symbol": "OPEN-BTC",
|
|
2967
|
+
// "forceTaker": false,
|
|
2968
|
+
// "orderId": "5ce36420054b4663b1fff2c9",
|
|
2969
|
+
// "fee": "0",
|
|
2970
|
+
// "feeCurrency": "",
|
|
2971
|
+
// "type": "",
|
|
2972
|
+
// "feeRate": "0",
|
|
2973
|
+
// "createdAt": 1558417615000,
|
|
2974
|
+
// "size": "12.8206",
|
|
2975
|
+
// "stop": "",
|
|
2976
|
+
// "price": "0",
|
|
2977
|
+
// "funds": "0",
|
|
2978
|
+
// "tradeId": "5ce390cf6e0db23b861c6e80"
|
|
2979
|
+
// }
|
|
2980
|
+
//
|
|
2981
|
+
// fetchMyTrades (private) v1 (historical)
|
|
2982
|
+
//
|
|
2983
|
+
// {
|
|
2984
|
+
// "symbol": "SNOV-ETH",
|
|
2985
|
+
// "dealPrice": "0.0000246",
|
|
2986
|
+
// "dealValue": "0.018942",
|
|
2987
|
+
// "amount": "770",
|
|
2988
|
+
// "fee": "0.00001137",
|
|
2989
|
+
// "side": "sell",
|
|
2990
|
+
// "createdAt": 1540080199
|
|
2991
|
+
// "id":"5c4d389e4c8c60413f78e2e5",
|
|
2992
|
+
// }
|
|
2993
|
+
//
|
|
2994
|
+
const marketId = this.safeString(trade, 'symbol');
|
|
2995
|
+
market = this.safeMarket(marketId, market, '-');
|
|
2996
|
+
const id = this.safeString2(trade, 'tradeId', 'id');
|
|
2997
|
+
const orderId = this.safeString(trade, 'orderId');
|
|
2998
|
+
const takerOrMaker = this.safeString(trade, 'liquidity');
|
|
2999
|
+
let timestamp = this.safeInteger(trade, 'time');
|
|
3000
|
+
if (timestamp !== undefined) {
|
|
3001
|
+
timestamp = this.parseToInt(timestamp / 1000000);
|
|
3002
|
+
}
|
|
3003
|
+
else {
|
|
3004
|
+
timestamp = this.safeInteger(trade, 'createdAt');
|
|
3005
|
+
// if it's a historical v1 trade, the exchange returns timestamp in seconds
|
|
3006
|
+
if (('dealValue' in trade) && (timestamp !== undefined)) {
|
|
3007
|
+
timestamp = timestamp * 1000;
|
|
3008
|
+
}
|
|
3009
|
+
}
|
|
3010
|
+
const priceString = this.safeString2(trade, 'price', 'dealPrice');
|
|
3011
|
+
const amountString = this.safeString2(trade, 'size', 'amount');
|
|
3012
|
+
const side = this.safeString(trade, 'side');
|
|
3013
|
+
let fee = undefined;
|
|
3014
|
+
const feeCostString = this.safeString(trade, 'fee');
|
|
3015
|
+
if (feeCostString !== undefined) {
|
|
3016
|
+
const feeCurrencyId = this.safeString(trade, 'feeCurrency');
|
|
3017
|
+
let feeCurrency = this.safeCurrencyCode(feeCurrencyId);
|
|
3018
|
+
if (feeCurrency === undefined) {
|
|
3019
|
+
feeCurrency = (side === 'sell') ? market['quote'] : market['base'];
|
|
3020
|
+
}
|
|
3021
|
+
fee = {
|
|
3022
|
+
'cost': feeCostString,
|
|
3023
|
+
'currency': feeCurrency,
|
|
3024
|
+
'rate': this.safeString(trade, 'feeRate'),
|
|
3025
|
+
};
|
|
3026
|
+
}
|
|
3027
|
+
let type = this.safeString(trade, 'type');
|
|
3028
|
+
if (type === 'match') {
|
|
3029
|
+
type = undefined;
|
|
3030
|
+
}
|
|
3031
|
+
const costString = this.safeString2(trade, 'funds', 'dealValue');
|
|
3032
|
+
return this.safeTrade({
|
|
3033
|
+
'info': trade,
|
|
3034
|
+
'id': id,
|
|
3035
|
+
'order': orderId,
|
|
3036
|
+
'timestamp': timestamp,
|
|
3037
|
+
'datetime': this.iso8601(timestamp),
|
|
3038
|
+
'symbol': market['symbol'],
|
|
3039
|
+
'type': type,
|
|
3040
|
+
'takerOrMaker': takerOrMaker,
|
|
3041
|
+
'side': side,
|
|
3042
|
+
'price': priceString,
|
|
3043
|
+
'amount': amountString,
|
|
3044
|
+
'cost': costString,
|
|
3045
|
+
'fee': fee,
|
|
3046
|
+
}, market);
|
|
3047
|
+
}
|
|
3048
|
+
async fetchTradingFee(symbol, params = {}) {
|
|
3049
|
+
/**
|
|
3050
|
+
* @method
|
|
3051
|
+
* @name kucoin#fetchTradingFee
|
|
3052
|
+
* @description fetch the trading fees for a market
|
|
3053
|
+
* @see https://docs.kucoin.com/#actual-fee-rate-of-the-trading-pair
|
|
3054
|
+
* @param {string} symbol unified market symbol
|
|
3055
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3056
|
+
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
3057
|
+
*/
|
|
3058
|
+
await this.loadMarkets();
|
|
3059
|
+
const market = this.market(symbol);
|
|
3060
|
+
const request = {
|
|
3061
|
+
'symbols': market['id'],
|
|
3062
|
+
};
|
|
3063
|
+
const response = await this.privateGetTradeFees(this.extend(request, params));
|
|
3064
|
+
//
|
|
3065
|
+
// {
|
|
3066
|
+
// "code": "200000",
|
|
3067
|
+
// "data": [
|
|
3068
|
+
// {
|
|
3069
|
+
// "symbol": "BTC-USDT",
|
|
3070
|
+
// "takerFeeRate": "0.001",
|
|
3071
|
+
// "makerFeeRate": "0.001"
|
|
3072
|
+
// }
|
|
3073
|
+
// ]
|
|
3074
|
+
// }
|
|
3075
|
+
//
|
|
3076
|
+
const data = this.safeValue(response, 'data', []);
|
|
3077
|
+
const first = this.safeValue(data, 0);
|
|
3078
|
+
const marketId = this.safeString(first, 'symbol');
|
|
3079
|
+
return {
|
|
3080
|
+
'info': response,
|
|
3081
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
3082
|
+
'maker': this.safeNumber(first, 'makerFeeRate'),
|
|
3083
|
+
'taker': this.safeNumber(first, 'takerFeeRate'),
|
|
3084
|
+
'percentage': true,
|
|
3085
|
+
'tierBased': true,
|
|
3086
|
+
};
|
|
3087
|
+
}
|
|
3088
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
3089
|
+
/**
|
|
3090
|
+
* @method
|
|
3091
|
+
* @name kucoin#withdraw
|
|
3092
|
+
* @description make a withdrawal
|
|
3093
|
+
* @see https://docs.kucoin.com/#apply-withdraw-2
|
|
3094
|
+
* @param {string} code unified currency code
|
|
3095
|
+
* @param {float} amount the amount to withdraw
|
|
3096
|
+
* @param {string} address the address to withdraw to
|
|
3097
|
+
* @param {string} tag
|
|
3098
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3099
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
3100
|
+
*/
|
|
3101
|
+
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
3102
|
+
await this.loadMarkets();
|
|
3103
|
+
this.checkAddress(address);
|
|
3104
|
+
const currency = this.currency(code);
|
|
3105
|
+
const request = {
|
|
3106
|
+
'currency': currency['id'],
|
|
3107
|
+
'address': address,
|
|
3108
|
+
'amount': amount,
|
|
3109
|
+
// 'memo': tag,
|
|
3110
|
+
// 'isInner': false, // internal transfer or external withdrawal
|
|
3111
|
+
// 'remark': 'optional',
|
|
3112
|
+
// 'chain': 'OMNI', // 'ERC20', 'TRC20', default is ERC20, This only apply for multi-chain currency, and there is no need for single chain currency.
|
|
3113
|
+
};
|
|
3114
|
+
if (tag !== undefined) {
|
|
3115
|
+
request['memo'] = tag;
|
|
3116
|
+
}
|
|
3117
|
+
let networkCode = undefined;
|
|
3118
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
3119
|
+
if (networkCode !== undefined) {
|
|
3120
|
+
request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
|
|
3121
|
+
}
|
|
3122
|
+
let includeFee = undefined;
|
|
3123
|
+
[includeFee, params] = this.handleOptionAndParams(params, 'withdraw', 'includeFee', false);
|
|
3124
|
+
if (includeFee) {
|
|
3125
|
+
request['feeDeductType'] = 'INTERNAL';
|
|
3126
|
+
}
|
|
3127
|
+
const response = await this.privatePostWithdrawals(this.extend(request, params));
|
|
3128
|
+
//
|
|
3129
|
+
// https://github.com/ccxt/ccxt/issues/5558
|
|
3130
|
+
//
|
|
3131
|
+
// {
|
|
3132
|
+
// "code": 200000,
|
|
3133
|
+
// "data": {
|
|
3134
|
+
// "withdrawalId": "5bffb63303aa675e8bbe18f9"
|
|
3135
|
+
// }
|
|
3136
|
+
// }
|
|
3137
|
+
//
|
|
3138
|
+
const data = this.safeValue(response, 'data', {});
|
|
3139
|
+
return this.parseTransaction(data, currency);
|
|
3140
|
+
}
|
|
3141
|
+
parseTransactionStatus(status) {
|
|
3142
|
+
const statuses = {
|
|
3143
|
+
'SUCCESS': 'ok',
|
|
3144
|
+
'PROCESSING': 'pending',
|
|
3145
|
+
'WALLET_PROCESSING': 'pending',
|
|
3146
|
+
'FAILURE': 'failed',
|
|
3147
|
+
};
|
|
3148
|
+
return this.safeString(statuses, status, status);
|
|
3149
|
+
}
|
|
3150
|
+
parseTransaction(transaction, currency = undefined) {
|
|
3151
|
+
//
|
|
3152
|
+
// fetchDeposits
|
|
3153
|
+
//
|
|
3154
|
+
// {
|
|
3155
|
+
// "address": "0x5f047b29041bcfdbf0e4478cdfa753a336ba6989",
|
|
3156
|
+
// "memo": "5c247c8a03aa677cea2a251d",
|
|
3157
|
+
// "amount": 1,
|
|
3158
|
+
// "fee": 0.0001,
|
|
3159
|
+
// "currency": "KCS",
|
|
3160
|
+
// "chain": "",
|
|
3161
|
+
// "isInner": false,
|
|
3162
|
+
// "walletTxId": "5bbb57386d99522d9f954c5a@test004",
|
|
3163
|
+
// "status": "SUCCESS",
|
|
3164
|
+
// "createdAt": 1544178843000,
|
|
3165
|
+
// "updatedAt": 1544178891000
|
|
3166
|
+
// "remark":"foobar"
|
|
3167
|
+
// }
|
|
3168
|
+
//
|
|
3169
|
+
// fetchWithdrawals
|
|
3170
|
+
//
|
|
3171
|
+
// {
|
|
3172
|
+
// "id": "5c2dc64e03aa675aa263f1ac",
|
|
3173
|
+
// "address": "0x5bedb060b8eb8d823e2414d82acce78d38be7fe9",
|
|
3174
|
+
// "memo": "",
|
|
3175
|
+
// "currency": "ETH",
|
|
3176
|
+
// "chain": "",
|
|
3177
|
+
// "amount": 1.0000000,
|
|
3178
|
+
// "fee": 0.0100000,
|
|
3179
|
+
// "walletTxId": "3e2414d82acce78d38be7fe9",
|
|
3180
|
+
// "isInner": false,
|
|
3181
|
+
// "status": "FAILURE",
|
|
3182
|
+
// "createdAt": 1546503758000,
|
|
3183
|
+
// "updatedAt": 1546504603000
|
|
3184
|
+
// "remark":"foobar"
|
|
3185
|
+
// }
|
|
3186
|
+
//
|
|
3187
|
+
// withdraw
|
|
3188
|
+
//
|
|
3189
|
+
// {
|
|
3190
|
+
// "withdrawalId": "5bffb63303aa675e8bbe18f9"
|
|
3191
|
+
// }
|
|
3192
|
+
//
|
|
3193
|
+
const currencyId = this.safeString(transaction, 'currency');
|
|
3194
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
3195
|
+
let address = this.safeString(transaction, 'address');
|
|
3196
|
+
const amount = this.safeString(transaction, 'amount');
|
|
3197
|
+
let txid = this.safeString(transaction, 'walletTxId');
|
|
3198
|
+
if (txid !== undefined) {
|
|
3199
|
+
const txidParts = txid.split('@');
|
|
3200
|
+
const numTxidParts = txidParts.length;
|
|
3201
|
+
if (numTxidParts > 1) {
|
|
3202
|
+
if (address === undefined) {
|
|
3203
|
+
if (txidParts[1].length > 1) {
|
|
3204
|
+
address = txidParts[1];
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
txid = txidParts[0];
|
|
3209
|
+
}
|
|
3210
|
+
let type = (txid === undefined) ? 'withdrawal' : 'deposit';
|
|
3211
|
+
const rawStatus = this.safeString(transaction, 'status');
|
|
3212
|
+
let fee = undefined;
|
|
3213
|
+
const feeCost = this.safeString(transaction, 'fee');
|
|
3214
|
+
if (feeCost !== undefined) {
|
|
3215
|
+
let rate = undefined;
|
|
3216
|
+
if (amount !== undefined) {
|
|
3217
|
+
rate = Precise["default"].stringDiv(feeCost, amount);
|
|
3218
|
+
}
|
|
3219
|
+
fee = {
|
|
3220
|
+
'cost': this.parseNumber(feeCost),
|
|
3221
|
+
'rate': this.parseNumber(rate),
|
|
3222
|
+
'currency': code,
|
|
3223
|
+
};
|
|
3224
|
+
}
|
|
3225
|
+
let timestamp = this.safeInteger2(transaction, 'createdAt', 'createAt');
|
|
3226
|
+
let updated = this.safeInteger(transaction, 'updatedAt');
|
|
3227
|
+
const isV1 = !('createdAt' in transaction);
|
|
3228
|
+
// if it's a v1 structure
|
|
3229
|
+
if (isV1) {
|
|
3230
|
+
type = ('address' in transaction) ? 'withdrawal' : 'deposit';
|
|
3231
|
+
if (timestamp !== undefined) {
|
|
3232
|
+
timestamp = timestamp * 1000;
|
|
3233
|
+
}
|
|
3234
|
+
if (updated !== undefined) {
|
|
3235
|
+
updated = updated * 1000;
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
const internal = this.safeValue(transaction, 'isInner');
|
|
3239
|
+
const tag = this.safeString(transaction, 'memo');
|
|
3240
|
+
return {
|
|
3241
|
+
'info': transaction,
|
|
3242
|
+
'id': this.safeString2(transaction, 'id', 'withdrawalId'),
|
|
3243
|
+
'timestamp': timestamp,
|
|
3244
|
+
'datetime': this.iso8601(timestamp),
|
|
3245
|
+
'network': this.networkIdToCode(this.safeString(transaction, 'chain')),
|
|
3246
|
+
'address': address,
|
|
3247
|
+
'addressTo': address,
|
|
3248
|
+
'addressFrom': undefined,
|
|
3249
|
+
'tag': tag,
|
|
3250
|
+
'tagTo': tag,
|
|
3251
|
+
'tagFrom': undefined,
|
|
3252
|
+
'currency': code,
|
|
3253
|
+
'amount': this.parseNumber(amount),
|
|
3254
|
+
'txid': txid,
|
|
3255
|
+
'type': type,
|
|
3256
|
+
'status': this.parseTransactionStatus(rawStatus),
|
|
3257
|
+
'comment': this.safeString(transaction, 'remark'),
|
|
3258
|
+
'internal': internal,
|
|
3259
|
+
'fee': fee,
|
|
3260
|
+
'updated': updated,
|
|
3261
|
+
};
|
|
3262
|
+
}
|
|
3263
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3264
|
+
/**
|
|
3265
|
+
* @method
|
|
3266
|
+
* @name kucoin#fetchDeposits
|
|
3267
|
+
* @description fetch all deposits made to an account
|
|
3268
|
+
* @see https://docs.kucoin.com/#get-deposit-list
|
|
3269
|
+
* @see https://docs.kucoin.com/#get-v1-historical-deposits-list
|
|
3270
|
+
* @param {string} code unified currency code
|
|
3271
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
3272
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
3273
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3274
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
3275
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
3276
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
3277
|
+
*/
|
|
3278
|
+
await this.loadMarkets();
|
|
3279
|
+
let paginate = false;
|
|
3280
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchDeposits', 'paginate');
|
|
3281
|
+
if (paginate) {
|
|
3282
|
+
return await this.fetchPaginatedCallDynamic('fetchDeposits', code, since, limit, params);
|
|
3283
|
+
}
|
|
3284
|
+
let request = {};
|
|
3285
|
+
let currency = undefined;
|
|
3286
|
+
if (code !== undefined) {
|
|
3287
|
+
currency = this.currency(code);
|
|
3288
|
+
request['currency'] = currency['id'];
|
|
3289
|
+
}
|
|
3290
|
+
if (limit !== undefined) {
|
|
3291
|
+
request['pageSize'] = limit;
|
|
3292
|
+
}
|
|
3293
|
+
[request, params] = this.handleUntilOption('endAt', request, params);
|
|
3294
|
+
let response = undefined;
|
|
3295
|
+
if (since !== undefined && since < 1550448000000) {
|
|
3296
|
+
// if since is earlier than 2019-02-18T00:00:00Z
|
|
3297
|
+
request['startAt'] = this.parseToInt(since / 1000);
|
|
3298
|
+
response = await this.privateGetHistDeposits(this.extend(request, params));
|
|
3299
|
+
}
|
|
3300
|
+
else {
|
|
3301
|
+
if (since !== undefined) {
|
|
3302
|
+
request['startAt'] = since;
|
|
3303
|
+
}
|
|
3304
|
+
response = await this.privateGetDeposits(this.extend(request, params));
|
|
3305
|
+
}
|
|
3306
|
+
//
|
|
3307
|
+
// {
|
|
3308
|
+
// "code": "200000",
|
|
3309
|
+
// "data": {
|
|
3310
|
+
// "currentPage": 1,
|
|
3311
|
+
// "pageSize": 5,
|
|
3312
|
+
// "totalNum": 2,
|
|
3313
|
+
// "totalPage": 1,
|
|
3314
|
+
// "items": [
|
|
3315
|
+
// //--------------------------------------------------
|
|
3316
|
+
// // version 2 deposit response structure
|
|
3317
|
+
// {
|
|
3318
|
+
// "address": "0x5f047b29041bcfdbf0e4478cdfa753a336ba6989",
|
|
3319
|
+
// "memo": "5c247c8a03aa677cea2a251d",
|
|
3320
|
+
// "amount": 1,
|
|
3321
|
+
// "fee": 0.0001,
|
|
3322
|
+
// "currency": "KCS",
|
|
3323
|
+
// "isInner": false,
|
|
3324
|
+
// "walletTxId": "5bbb57386d99522d9f954c5a@test004",
|
|
3325
|
+
// "status": "SUCCESS",
|
|
3326
|
+
// "createdAt": 1544178843000,
|
|
3327
|
+
// "updatedAt": 1544178891000
|
|
3328
|
+
// "remark":"foobar"
|
|
3329
|
+
// },
|
|
3330
|
+
// //--------------------------------------------------
|
|
3331
|
+
// // version 1 (historical) deposit response structure
|
|
3332
|
+
// {
|
|
3333
|
+
// "currency": "BTC",
|
|
3334
|
+
// "createAt": 1528536998,
|
|
3335
|
+
// "amount": "0.03266638",
|
|
3336
|
+
// "walletTxId": "55c643bc2c68d6f17266383ac1be9e454038864b929ae7cee0bc408cc5c869e8@12ffGWmMMD1zA1WbFm7Ho3JZ1w6NYXjpFk@234",
|
|
3337
|
+
// "isInner": false,
|
|
3338
|
+
// "status": "SUCCESS",
|
|
3339
|
+
// }
|
|
3340
|
+
// ]
|
|
3341
|
+
// }
|
|
3342
|
+
// }
|
|
3343
|
+
//
|
|
3344
|
+
const responseData = response['data']['items'];
|
|
3345
|
+
return this.parseTransactions(responseData, currency, since, limit, { 'type': 'deposit' });
|
|
3346
|
+
}
|
|
3347
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3348
|
+
/**
|
|
3349
|
+
* @method
|
|
3350
|
+
* @name kucoin#fetchWithdrawals
|
|
3351
|
+
* @description fetch all withdrawals made from an account
|
|
3352
|
+
* @see https://docs.kucoin.com/#get-withdrawals-list
|
|
3353
|
+
* @see https://docs.kucoin.com/#get-v1-historical-withdrawals-list
|
|
3354
|
+
* @param {string} code unified currency code
|
|
3355
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
3356
|
+
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
3357
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3358
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
3359
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
3360
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
3361
|
+
*/
|
|
3362
|
+
await this.loadMarkets();
|
|
3363
|
+
let paginate = false;
|
|
3364
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchWithdrawals', 'paginate');
|
|
3365
|
+
if (paginate) {
|
|
3366
|
+
return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params);
|
|
3367
|
+
}
|
|
3368
|
+
let request = {};
|
|
3369
|
+
let currency = undefined;
|
|
3370
|
+
if (code !== undefined) {
|
|
3371
|
+
currency = this.currency(code);
|
|
3372
|
+
request['currency'] = currency['id'];
|
|
3373
|
+
}
|
|
3374
|
+
if (limit !== undefined) {
|
|
3375
|
+
request['pageSize'] = limit;
|
|
3376
|
+
}
|
|
3377
|
+
[request, params] = this.handleUntilOption('endAt', request, params);
|
|
3378
|
+
let response = undefined;
|
|
3379
|
+
if (since !== undefined && since < 1550448000000) {
|
|
3380
|
+
// if since is earlier than 2019-02-18T00:00:00Z
|
|
3381
|
+
request['startAt'] = this.parseToInt(since / 1000);
|
|
3382
|
+
response = await this.privateGetHistWithdrawals(this.extend(request, params));
|
|
3383
|
+
}
|
|
3384
|
+
else {
|
|
3385
|
+
if (since !== undefined) {
|
|
3386
|
+
request['startAt'] = since;
|
|
3387
|
+
}
|
|
3388
|
+
response = await this.privateGetWithdrawals(this.extend(request, params));
|
|
3389
|
+
}
|
|
3390
|
+
//
|
|
3391
|
+
// {
|
|
3392
|
+
// "code": "200000",
|
|
3393
|
+
// "data": {
|
|
3394
|
+
// "currentPage": 1,
|
|
3395
|
+
// "pageSize": 5,
|
|
3396
|
+
// "totalNum": 2,
|
|
3397
|
+
// "totalPage": 1,
|
|
3398
|
+
// "items": [
|
|
3399
|
+
// //--------------------------------------------------
|
|
3400
|
+
// // version 2 withdrawal response structure
|
|
3401
|
+
// {
|
|
3402
|
+
// "id": "5c2dc64e03aa675aa263f1ac",
|
|
3403
|
+
// "address": "0x5bedb060b8eb8d823e2414d82acce78d38be7fe9",
|
|
3404
|
+
// "memo": "",
|
|
3405
|
+
// "currency": "ETH",
|
|
3406
|
+
// "amount": 1.0000000,
|
|
3407
|
+
// "fee": 0.0100000,
|
|
3408
|
+
// "walletTxId": "3e2414d82acce78d38be7fe9",
|
|
3409
|
+
// "isInner": false,
|
|
3410
|
+
// "status": "FAILURE",
|
|
3411
|
+
// "createdAt": 1546503758000,
|
|
3412
|
+
// "updatedAt": 1546504603000
|
|
3413
|
+
// },
|
|
3414
|
+
// //--------------------------------------------------
|
|
3415
|
+
// // version 1 (historical) withdrawal response structure
|
|
3416
|
+
// {
|
|
3417
|
+
// "currency": "BTC",
|
|
3418
|
+
// "createAt": 1526723468,
|
|
3419
|
+
// "amount": "0.534",
|
|
3420
|
+
// "address": "33xW37ZSW4tQvg443Pc7NLCAs167Yc2XUV",
|
|
3421
|
+
// "walletTxId": "aeacea864c020acf58e51606169240e96774838dcd4f7ce48acf38e3651323f4",
|
|
3422
|
+
// "isInner": false,
|
|
3423
|
+
// "status": "SUCCESS"
|
|
3424
|
+
// }
|
|
3425
|
+
// ]
|
|
3426
|
+
// }
|
|
3427
|
+
// }
|
|
3428
|
+
//
|
|
3429
|
+
const responseData = response['data']['items'];
|
|
3430
|
+
return this.parseTransactions(responseData, currency, since, limit, { 'type': 'withdrawal' });
|
|
3431
|
+
}
|
|
3432
|
+
parseBalanceHelper(entry) {
|
|
3433
|
+
const account = this.account();
|
|
3434
|
+
account['used'] = this.safeString(entry, 'holdBalance');
|
|
3435
|
+
account['free'] = this.safeString(entry, 'availableBalance');
|
|
3436
|
+
account['total'] = this.safeString(entry, 'totalBalance');
|
|
3437
|
+
const debt = this.safeString(entry, 'liability');
|
|
3438
|
+
const interest = this.safeString(entry, 'interest');
|
|
3439
|
+
account['debt'] = Precise["default"].stringAdd(debt, interest);
|
|
3440
|
+
return account;
|
|
3441
|
+
}
|
|
3442
|
+
async fetchBalance(params = {}) {
|
|
3443
|
+
/**
|
|
3444
|
+
* @method
|
|
3445
|
+
* @name kucoin#fetchBalance
|
|
3446
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
3447
|
+
* @see https://docs.kucoin.com/#list-accounts
|
|
3448
|
+
* @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-list-spot-margin-trade_hf
|
|
3449
|
+
* @see https://docs.kucoin.com/#query-isolated-margin-account-info
|
|
3450
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3451
|
+
* @param {object} [params.marginMode] 'cross' or 'isolated', margin type for fetching margin balance
|
|
3452
|
+
* @param {object} [params.type] extra parameters specific to the exchange API endpoint
|
|
3453
|
+
* @param {object} [params.hf] *default if false* if true, the result includes the balance of the high frequency account
|
|
3454
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
3455
|
+
*/
|
|
3456
|
+
await this.loadMarkets();
|
|
3457
|
+
const code = this.safeString(params, 'code');
|
|
3458
|
+
let currency = undefined;
|
|
3459
|
+
if (code !== undefined) {
|
|
3460
|
+
currency = this.currency(code);
|
|
3461
|
+
}
|
|
3462
|
+
const defaultType = this.safeString2(this.options, 'fetchBalance', 'defaultType', 'spot');
|
|
3463
|
+
const requestedType = this.safeString(params, 'type', defaultType);
|
|
3464
|
+
const accountsByType = this.safeValue(this.options, 'accountsByType');
|
|
3465
|
+
let type = this.safeString(accountsByType, requestedType, requestedType);
|
|
3466
|
+
params = this.omit(params, 'type');
|
|
3467
|
+
const isHf = this.safeValue(params, 'hf', false);
|
|
3468
|
+
if (isHf) {
|
|
3469
|
+
type = 'trade_hf';
|
|
3470
|
+
}
|
|
3471
|
+
params = this.omit(params, 'hf');
|
|
3472
|
+
const [marginMode, query] = this.handleMarginModeAndParams('fetchBalance', params);
|
|
3473
|
+
let response = undefined;
|
|
3474
|
+
const request = {};
|
|
3475
|
+
const isolated = (marginMode === 'isolated') || (type === 'isolated');
|
|
3476
|
+
const cross = (marginMode === 'cross') || (type === 'cross');
|
|
3477
|
+
if (isolated) {
|
|
3478
|
+
if (currency !== undefined) {
|
|
3479
|
+
request['balanceCurrency'] = currency['id'];
|
|
3480
|
+
}
|
|
3481
|
+
response = await this.privateGetIsolatedAccounts(this.extend(request, query));
|
|
3482
|
+
}
|
|
3483
|
+
else if (cross) {
|
|
3484
|
+
response = await this.privateGetMarginAccount(this.extend(request, query));
|
|
3485
|
+
}
|
|
3486
|
+
else {
|
|
3487
|
+
if (currency !== undefined) {
|
|
3488
|
+
request['currency'] = currency['id'];
|
|
3489
|
+
}
|
|
3490
|
+
request['type'] = type;
|
|
3491
|
+
response = await this.privateGetAccounts(this.extend(request, query));
|
|
3492
|
+
}
|
|
3493
|
+
//
|
|
3494
|
+
// Spot and Cross
|
|
3495
|
+
//
|
|
3496
|
+
// {
|
|
3497
|
+
// "code": "200000",
|
|
3498
|
+
// "data": [
|
|
3499
|
+
// {
|
|
3500
|
+
// "balance": "0.00009788",
|
|
3501
|
+
// "available": "0.00009788",
|
|
3502
|
+
// "holds": "0",
|
|
3503
|
+
// "currency": "BTC",
|
|
3504
|
+
// "id": "5c6a4fd399a1d81c4f9cc4d0",
|
|
3505
|
+
// "type": "trade",
|
|
3506
|
+
// },
|
|
3507
|
+
// ]
|
|
3508
|
+
// }
|
|
3509
|
+
//
|
|
3510
|
+
// Isolated
|
|
3511
|
+
//
|
|
3512
|
+
// {
|
|
3513
|
+
// "code": "200000",
|
|
3514
|
+
// "data": {
|
|
3515
|
+
// "totalConversionBalance": "0",
|
|
3516
|
+
// "liabilityConversionBalance": "0",
|
|
3517
|
+
// "assets": [
|
|
3518
|
+
// {
|
|
3519
|
+
// "symbol": "MANA-USDT",
|
|
3520
|
+
// "status": "CLEAR",
|
|
3521
|
+
// "debtRatio": "0",
|
|
3522
|
+
// "baseAsset": {
|
|
3523
|
+
// "currency": "MANA",
|
|
3524
|
+
// "totalBalance": "0",
|
|
3525
|
+
// "holdBalance": "0",
|
|
3526
|
+
// "availableBalance": "0",
|
|
3527
|
+
// "liability": "0",
|
|
3528
|
+
// "interest": "0",
|
|
3529
|
+
// "borrowableAmount": "0"
|
|
3530
|
+
// },
|
|
3531
|
+
// "quoteAsset": {
|
|
3532
|
+
// "currency": "USDT",
|
|
3533
|
+
// "totalBalance": "0",
|
|
3534
|
+
// "holdBalance": "0",
|
|
3535
|
+
// "availableBalance": "0",
|
|
3536
|
+
// "liability": "0",
|
|
3537
|
+
// "interest": "0",
|
|
3538
|
+
// "borrowableAmount": "0"
|
|
3539
|
+
// }
|
|
3540
|
+
// },
|
|
3541
|
+
// ...
|
|
3542
|
+
// ]
|
|
3543
|
+
// }
|
|
3544
|
+
// }
|
|
3545
|
+
//
|
|
3546
|
+
const data = this.safeValue(response, 'data', []);
|
|
3547
|
+
const result = {
|
|
3548
|
+
'info': response,
|
|
3549
|
+
'timestamp': undefined,
|
|
3550
|
+
'datetime': undefined,
|
|
3551
|
+
};
|
|
3552
|
+
if (isolated) {
|
|
3553
|
+
const assets = this.safeValue(data, 'assets', data);
|
|
3554
|
+
for (let i = 0; i < assets.length; i++) {
|
|
3555
|
+
const entry = assets[i];
|
|
3556
|
+
const marketId = this.safeString(entry, 'symbol');
|
|
3557
|
+
const symbol = this.safeSymbol(marketId, undefined, '_');
|
|
3558
|
+
const base = this.safeValue(entry, 'baseAsset', {});
|
|
3559
|
+
const quote = this.safeValue(entry, 'quoteAsset', {});
|
|
3560
|
+
const baseCode = this.safeCurrencyCode(this.safeString(base, 'currency'));
|
|
3561
|
+
const quoteCode = this.safeCurrencyCode(this.safeString(quote, 'currency'));
|
|
3562
|
+
const subResult = {};
|
|
3563
|
+
subResult[baseCode] = this.parseBalanceHelper(base);
|
|
3564
|
+
subResult[quoteCode] = this.parseBalanceHelper(quote);
|
|
3565
|
+
result[symbol] = this.safeBalance(subResult);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
else if (cross) {
|
|
3569
|
+
const accounts = this.safeValue(data, 'accounts', []);
|
|
3570
|
+
for (let i = 0; i < accounts.length; i++) {
|
|
3571
|
+
const balance = accounts[i];
|
|
3572
|
+
const currencyId = this.safeString(balance, 'currency');
|
|
3573
|
+
const codeInner = this.safeCurrencyCode(currencyId);
|
|
3574
|
+
result[codeInner] = this.parseBalanceHelper(balance);
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
else {
|
|
3578
|
+
for (let i = 0; i < data.length; i++) {
|
|
3579
|
+
const balance = data[i];
|
|
3580
|
+
const balanceType = this.safeString(balance, 'type');
|
|
3581
|
+
if (balanceType === type) {
|
|
3582
|
+
const currencyId = this.safeString(balance, 'currency');
|
|
3583
|
+
const codeInner2 = this.safeCurrencyCode(currencyId);
|
|
3584
|
+
const account = this.account();
|
|
3585
|
+
account['total'] = this.safeString(balance, 'balance');
|
|
3586
|
+
account['free'] = this.safeString(balance, 'available');
|
|
3587
|
+
account['used'] = this.safeString(balance, 'holds');
|
|
3588
|
+
result[codeInner2] = account;
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
const returnType = isolated ? result : this.safeBalance(result);
|
|
3593
|
+
return returnType;
|
|
3594
|
+
}
|
|
3595
|
+
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
3596
|
+
/**
|
|
3597
|
+
* @method
|
|
3598
|
+
* @name kucoin#transfer
|
|
3599
|
+
* @description transfer currency internally between wallets on the same account
|
|
3600
|
+
* @see https://docs.kucoin.com/#inner-transfer
|
|
3601
|
+
* @see https://docs.kucoin.com/futures/#transfer-funds-to-kucoin-main-account-2
|
|
3602
|
+
* @see https://docs.kucoin.com/spot-hf/#internal-funds-transfers-in-high-frequency-trading-accounts
|
|
3603
|
+
* @param {string} code unified currency code
|
|
3604
|
+
* @param {float} amount amount to transfer
|
|
3605
|
+
* @param {string} fromAccount account to transfer from
|
|
3606
|
+
* @param {string} toAccount account to transfer to
|
|
3607
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3608
|
+
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
3609
|
+
*/
|
|
3610
|
+
await this.loadMarkets();
|
|
3611
|
+
const currency = this.currency(code);
|
|
3612
|
+
const requestedAmount = this.currencyToPrecision(code, amount);
|
|
3613
|
+
let fromId = this.convertTypeToAccount(fromAccount);
|
|
3614
|
+
let toId = this.convertTypeToAccount(toAccount);
|
|
3615
|
+
const fromIsolated = this.inArray(fromId, this.ids);
|
|
3616
|
+
const toIsolated = this.inArray(toId, this.ids);
|
|
3617
|
+
if (fromId === 'contract') {
|
|
3618
|
+
if (toId !== 'main') {
|
|
3619
|
+
throw new errors.ExchangeError(this.id + ' transfer() only supports transferring from futures account to main account');
|
|
3620
|
+
}
|
|
3621
|
+
const request = {
|
|
3622
|
+
'currency': currency['id'],
|
|
3623
|
+
'amount': requestedAmount,
|
|
3624
|
+
};
|
|
3625
|
+
if (!('bizNo' in params)) {
|
|
3626
|
+
// it doesn't like more than 24 characters
|
|
3627
|
+
request['bizNo'] = this.uuid22();
|
|
3628
|
+
}
|
|
3629
|
+
const response = await this.futuresPrivatePostTransferOut(this.extend(request, params));
|
|
3630
|
+
//
|
|
3631
|
+
// {
|
|
3632
|
+
// "code": "200000",
|
|
3633
|
+
// "data": {
|
|
3634
|
+
// "applyId": "605a87217dff1500063d485d",
|
|
3635
|
+
// "bizNo": "bcd6e5e1291f4905af84dc",
|
|
3636
|
+
// "payAccountType": "CONTRACT",
|
|
3637
|
+
// "payTag": "DEFAULT",
|
|
3638
|
+
// "remark": '',
|
|
3639
|
+
// "recAccountType": "MAIN",
|
|
3640
|
+
// "recTag": "DEFAULT",
|
|
3641
|
+
// "recRemark": '',
|
|
3642
|
+
// "recSystem": "KUCOIN",
|
|
3643
|
+
// "status": "PROCESSING",
|
|
3644
|
+
// "currency": "XBT",
|
|
3645
|
+
// "amount": "0.00001",
|
|
3646
|
+
// "fee": "0",
|
|
3647
|
+
// "sn": "573688685663948",
|
|
3648
|
+
// "reason": '',
|
|
3649
|
+
// "createdAt": 1616545569000,
|
|
3650
|
+
// "updatedAt": 1616545569000
|
|
3651
|
+
// }
|
|
3652
|
+
// }
|
|
3653
|
+
//
|
|
3654
|
+
const data = this.safeValue(response, 'data');
|
|
3655
|
+
return this.parseTransfer(data, currency);
|
|
3656
|
+
}
|
|
3657
|
+
else {
|
|
3658
|
+
const request = {
|
|
3659
|
+
'currency': currency['id'],
|
|
3660
|
+
'amount': requestedAmount,
|
|
3661
|
+
};
|
|
3662
|
+
if (fromIsolated || toIsolated) {
|
|
3663
|
+
if (this.inArray(fromId, this.ids)) {
|
|
3664
|
+
request['fromTag'] = fromId;
|
|
3665
|
+
fromId = 'isolated';
|
|
3666
|
+
}
|
|
3667
|
+
if (this.inArray(toId, this.ids)) {
|
|
3668
|
+
request['toTag'] = toId;
|
|
3669
|
+
toId = 'isolated';
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3672
|
+
request['from'] = fromId;
|
|
3673
|
+
request['to'] = toId;
|
|
3674
|
+
if (!('clientOid' in params)) {
|
|
3675
|
+
request['clientOid'] = this.uuid();
|
|
3676
|
+
}
|
|
3677
|
+
const response = await this.privatePostAccountsInnerTransfer(this.extend(request, params));
|
|
3678
|
+
//
|
|
3679
|
+
// {
|
|
3680
|
+
// "code": "200000",
|
|
3681
|
+
// "data": {
|
|
3682
|
+
// "orderId": "605a6211e657f00006ad0ad6"
|
|
3683
|
+
// }
|
|
3684
|
+
// }
|
|
3685
|
+
//
|
|
3686
|
+
const data = this.safeValue(response, 'data');
|
|
3687
|
+
return this.parseTransfer(data, currency);
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
parseTransfer(transfer, currency = undefined) {
|
|
3691
|
+
//
|
|
3692
|
+
// transfer (spot)
|
|
3693
|
+
//
|
|
3694
|
+
// {
|
|
3695
|
+
// "orderId": "605a6211e657f00006ad0ad6"
|
|
3696
|
+
// }
|
|
3697
|
+
//
|
|
3698
|
+
// {
|
|
3699
|
+
// "code": "200000",
|
|
3700
|
+
// "msg": "Failed to transfer out. The amount exceeds the upper limit"
|
|
3701
|
+
// }
|
|
3702
|
+
//
|
|
3703
|
+
// transfer (futures)
|
|
3704
|
+
//
|
|
3705
|
+
// {
|
|
3706
|
+
// "applyId": "605a87217dff1500063d485d",
|
|
3707
|
+
// "bizNo": "bcd6e5e1291f4905af84dc",
|
|
3708
|
+
// "payAccountType": "CONTRACT",
|
|
3709
|
+
// "payTag": "DEFAULT",
|
|
3710
|
+
// "remark": '',
|
|
3711
|
+
// "recAccountType": "MAIN",
|
|
3712
|
+
// "recTag": "DEFAULT",
|
|
3713
|
+
// "recRemark": '',
|
|
3714
|
+
// "recSystem": "KUCOIN",
|
|
3715
|
+
// "status": "PROCESSING",
|
|
3716
|
+
// "currency": "XBT",
|
|
3717
|
+
// "amount": "0.00001",
|
|
3718
|
+
// "fee": "0",
|
|
3719
|
+
// "sn": "573688685663948",
|
|
3720
|
+
// "reason": '',
|
|
3721
|
+
// "createdAt": 1616545569000,
|
|
3722
|
+
// "updatedAt": 1616545569000
|
|
3723
|
+
// }
|
|
3724
|
+
//
|
|
3725
|
+
const timestamp = this.safeInteger(transfer, 'createdAt');
|
|
3726
|
+
const currencyId = this.safeString(transfer, 'currency');
|
|
3727
|
+
const rawStatus = this.safeString(transfer, 'status');
|
|
3728
|
+
const accountFromRaw = this.safeStringLower(transfer, 'payAccountType');
|
|
3729
|
+
const accountToRaw = this.safeStringLower(transfer, 'recAccountType');
|
|
3730
|
+
const accountsByType = this.safeValue(this.options, 'accountsByType');
|
|
3731
|
+
const accountFrom = this.safeString(accountsByType, accountFromRaw, accountFromRaw);
|
|
3732
|
+
const accountTo = this.safeString(accountsByType, accountToRaw, accountToRaw);
|
|
3733
|
+
return {
|
|
3734
|
+
'id': this.safeString2(transfer, 'applyId', 'orderId'),
|
|
3735
|
+
'currency': this.safeCurrencyCode(currencyId, currency),
|
|
3736
|
+
'timestamp': timestamp,
|
|
3737
|
+
'datetime': this.iso8601(timestamp),
|
|
3738
|
+
'amount': this.safeNumber(transfer, 'amount'),
|
|
3739
|
+
'fromAccount': accountFrom,
|
|
3740
|
+
'toAccount': accountTo,
|
|
3741
|
+
'status': this.parseTransferStatus(rawStatus),
|
|
3742
|
+
'info': transfer,
|
|
3743
|
+
};
|
|
3744
|
+
}
|
|
3745
|
+
parseTransferStatus(status) {
|
|
3746
|
+
const statuses = {
|
|
3747
|
+
'PROCESSING': 'pending',
|
|
3748
|
+
};
|
|
3749
|
+
return this.safeString(statuses, status, status);
|
|
3750
|
+
}
|
|
3751
|
+
parseLedgerEntryType(type) {
|
|
3752
|
+
const types = {
|
|
3753
|
+
'Assets Transferred in After Upgrading': 'transfer',
|
|
3754
|
+
'Deposit': 'transaction',
|
|
3755
|
+
'Withdrawal': 'transaction',
|
|
3756
|
+
'Transfer': 'transfer',
|
|
3757
|
+
'Trade_Exchange': 'trade',
|
|
3758
|
+
// 'Vote for Coin': 'Vote for Coin', // Vote for Coin
|
|
3759
|
+
'KuCoin Bonus': 'bonus',
|
|
3760
|
+
'Referral Bonus': 'referral',
|
|
3761
|
+
'Rewards': 'bonus',
|
|
3762
|
+
// 'Distribution': 'Distribution', // Distribution, such as get GAS by holding NEO
|
|
3763
|
+
'Airdrop/Fork': 'airdrop',
|
|
3764
|
+
'Other rewards': 'bonus',
|
|
3765
|
+
'Fee Rebate': 'rebate',
|
|
3766
|
+
'Buy Crypto': 'trade',
|
|
3767
|
+
'Sell Crypto': 'sell',
|
|
3768
|
+
'Public Offering Purchase': 'trade',
|
|
3769
|
+
// 'Send red envelope': 'Send red envelope', // Send red envelope
|
|
3770
|
+
// 'Open red envelope': 'Open red envelope', // Open red envelope
|
|
3771
|
+
// 'Staking': 'Staking', // Staking
|
|
3772
|
+
// 'LockDrop Vesting': 'LockDrop Vesting', // LockDrop Vesting
|
|
3773
|
+
// 'Staking Profits': 'Staking Profits', // Staking Profits
|
|
3774
|
+
// 'Redemption': 'Redemption', // Redemption
|
|
3775
|
+
'Refunded Fees': 'fee',
|
|
3776
|
+
'KCS Pay Fees': 'fee',
|
|
3777
|
+
'Margin Trade': 'trade',
|
|
3778
|
+
'Loans': 'Loans',
|
|
3779
|
+
// 'Borrowings': 'Borrowings', // Borrowings
|
|
3780
|
+
// 'Debt Repayment': 'Debt Repayment', // Debt Repayment
|
|
3781
|
+
// 'Loans Repaid': 'Loans Repaid', // Loans Repaid
|
|
3782
|
+
// 'Lendings': 'Lendings', // Lendings
|
|
3783
|
+
// 'Pool transactions': 'Pool transactions', // Pool-X transactions
|
|
3784
|
+
'Instant Exchange': 'trade',
|
|
3785
|
+
'Sub-account transfer': 'transfer',
|
|
3786
|
+
'Liquidation Fees': 'fee', // Liquidation Fees
|
|
3787
|
+
// 'Soft Staking Profits': 'Soft Staking Profits', // Soft Staking Profits
|
|
3788
|
+
// 'Voting Earnings': 'Voting Earnings', // Voting Earnings on Pool-X
|
|
3789
|
+
// 'Redemption of Voting': 'Redemption of Voting', // Redemption of Voting on Pool-X
|
|
3790
|
+
// 'Voting': 'Voting', // Voting on Pool-X
|
|
3791
|
+
// 'Convert to KCS': 'Convert to KCS', // Convert to KCS
|
|
3792
|
+
};
|
|
3793
|
+
return this.safeString(types, type, type);
|
|
3794
|
+
}
|
|
3795
|
+
parseLedgerEntry(item, currency = undefined) {
|
|
3796
|
+
//
|
|
3797
|
+
// {
|
|
3798
|
+
// "id": "611a1e7c6a053300067a88d9", //unique key for each ledger entry
|
|
3799
|
+
// "currency": "USDT", //Currency
|
|
3800
|
+
// "amount": "10.00059547", //The total amount of assets (fees included) involved in assets changes such as transaction, withdrawal and bonus distribution.
|
|
3801
|
+
// "fee": "0", //Deposit or withdrawal fee
|
|
3802
|
+
// "balance": "0", //Total assets of a currency remaining funds after transaction
|
|
3803
|
+
// "accountType": "MAIN", //Account Type
|
|
3804
|
+
// "bizType": "Loans Repaid", //business type
|
|
3805
|
+
// "direction": "in", //side, in or out
|
|
3806
|
+
// "createdAt": 1629101692950, //Creation time
|
|
3807
|
+
// "context": "{\"borrowerUserId\":\"601ad03e50dc810006d242ea\",\"loanRepayDetailNo\":\"611a1e7cc913d000066cf7ec\"}" //Business core parameters
|
|
3808
|
+
// }
|
|
3809
|
+
//
|
|
3810
|
+
const id = this.safeString(item, 'id');
|
|
3811
|
+
const currencyId = this.safeString(item, 'currency');
|
|
3812
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
3813
|
+
const amount = this.safeNumber(item, 'amount');
|
|
3814
|
+
const balanceAfter = undefined;
|
|
3815
|
+
// const balanceAfter = this.safeNumber (item, 'balance'); only returns zero string
|
|
3816
|
+
const bizType = this.safeString(item, 'bizType');
|
|
3817
|
+
const type = this.parseLedgerEntryType(bizType);
|
|
3818
|
+
const direction = this.safeString(item, 'direction');
|
|
3819
|
+
const timestamp = this.safeInteger(item, 'createdAt');
|
|
3820
|
+
const datetime = this.iso8601(timestamp);
|
|
3821
|
+
const account = this.safeString(item, 'accountType'); // MAIN, TRADE, MARGIN, or CONTRACT
|
|
3822
|
+
const context = this.safeString(item, 'context'); // contains other information about the ledger entry
|
|
3823
|
+
//
|
|
3824
|
+
// withdrawal transaction
|
|
3825
|
+
//
|
|
3826
|
+
// "{\"orderId\":\"617bb2d09e7b3b000196dac8\",\"txId\":\"0x79bb9855f86b351a45cab4dc69d78ca09586a94c45dde49475722b98f401b054\"}"
|
|
3827
|
+
//
|
|
3828
|
+
// deposit to MAIN, trade via MAIN
|
|
3829
|
+
//
|
|
3830
|
+
// "{\"orderId\":\"617ab9949e7b3b0001948081\",\"txId\":\"0x7a06b16bbd6b03dbc3d96df5683b15229fc35e7184fd7179a5f3a310bd67d1fa@default@0\"}"
|
|
3831
|
+
//
|
|
3832
|
+
// sell trade
|
|
3833
|
+
//
|
|
3834
|
+
// "{\"symbol\":\"ETH-USDT\",\"orderId\":\"617adcd1eb3fa20001dd29a1\",\"tradeId\":\"617adcd12e113d2b91222ff9\"}"
|
|
3835
|
+
//
|
|
3836
|
+
let referenceId = undefined;
|
|
3837
|
+
if (context !== undefined && context !== '') {
|
|
3838
|
+
try {
|
|
3839
|
+
const parsed = JSON.parse(context);
|
|
3840
|
+
const orderId = this.safeString(parsed, 'orderId');
|
|
3841
|
+
const tradeId = this.safeString(parsed, 'tradeId');
|
|
3842
|
+
// transactions only have an orderId but for trades we wish to use tradeId
|
|
3843
|
+
if (tradeId !== undefined) {
|
|
3844
|
+
referenceId = tradeId;
|
|
3845
|
+
}
|
|
3846
|
+
else {
|
|
3847
|
+
referenceId = orderId;
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
catch (exc) {
|
|
3851
|
+
referenceId = context;
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
let fee = undefined;
|
|
3855
|
+
const feeCost = this.safeNumber(item, 'fee');
|
|
3856
|
+
let feeCurrency = undefined;
|
|
3857
|
+
if (feeCost !== 0) {
|
|
3858
|
+
feeCurrency = code;
|
|
3859
|
+
fee = { 'cost': feeCost, 'currency': feeCurrency };
|
|
3860
|
+
}
|
|
3861
|
+
return {
|
|
3862
|
+
'id': id,
|
|
3863
|
+
'direction': direction,
|
|
3864
|
+
'account': account,
|
|
3865
|
+
'referenceId': referenceId,
|
|
3866
|
+
'referenceAccount': account,
|
|
3867
|
+
'type': type,
|
|
3868
|
+
'currency': code,
|
|
3869
|
+
'amount': amount,
|
|
3870
|
+
'timestamp': timestamp,
|
|
3871
|
+
'datetime': datetime,
|
|
3872
|
+
'before': undefined,
|
|
3873
|
+
'after': balanceAfter,
|
|
3874
|
+
'status': undefined,
|
|
3875
|
+
'fee': fee,
|
|
3876
|
+
'info': item,
|
|
3877
|
+
};
|
|
3878
|
+
}
|
|
3879
|
+
async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
3880
|
+
/**
|
|
3881
|
+
* @method
|
|
3882
|
+
* @name kucoin#fetchLedger
|
|
3883
|
+
* @see https://docs.kucoin.com/#get-account-ledgers
|
|
3884
|
+
* @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-trade_hf
|
|
3885
|
+
* @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-margin_hf
|
|
3886
|
+
* @description fetch the history of changes, actions done by the user or operations that altered balance of the user
|
|
3887
|
+
* @param {string} code unified currency code, default is undefined
|
|
3888
|
+
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
|
3889
|
+
* @param {int} [limit] max number of ledger entrys to return, default is undefined
|
|
3890
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3891
|
+
* @param {boolean} [params.hf] default false, when true will fetch ledger entries for the high frequency trading account
|
|
3892
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
3893
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
3894
|
+
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
|
|
3895
|
+
*/
|
|
3896
|
+
await this.loadMarkets();
|
|
3897
|
+
await this.loadAccounts();
|
|
3898
|
+
let paginate = false;
|
|
3899
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
|
|
3900
|
+
const isHf = this.safeValue(params, 'hf');
|
|
3901
|
+
params = this.omit(params, 'hf');
|
|
3902
|
+
if (paginate) {
|
|
3903
|
+
return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
|
|
3904
|
+
}
|
|
3905
|
+
let request = {
|
|
3906
|
+
// 'currency': currency['id'], // can choose up to 10, if not provided returns for all currencies by default
|
|
3907
|
+
// 'direction': 'in', // 'out'
|
|
3908
|
+
// 'bizType': 'DEPOSIT', // DEPOSIT, WITHDRAW, TRANSFER, SUB_TRANSFER,TRADE_EXCHANGE, MARGIN_EXCHANGE, KUCOIN_BONUS (optional)
|
|
3909
|
+
// 'startAt': since,
|
|
3910
|
+
// 'endAt': exchange.milliseconds (),
|
|
3911
|
+
};
|
|
3912
|
+
if (since !== undefined) {
|
|
3913
|
+
request['startAt'] = since;
|
|
3914
|
+
}
|
|
3915
|
+
// atm only single currency retrieval is supported
|
|
3916
|
+
let currency = undefined;
|
|
3917
|
+
if (code !== undefined) {
|
|
3918
|
+
currency = this.currency(code);
|
|
3919
|
+
request['currency'] = currency['id'];
|
|
3920
|
+
}
|
|
3921
|
+
[request, params] = this.handleUntilOption('endAt', request, params);
|
|
3922
|
+
let marginMode = undefined;
|
|
3923
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchLedger', params);
|
|
3924
|
+
let response = undefined;
|
|
3925
|
+
if (isHf) {
|
|
3926
|
+
if (marginMode !== undefined) {
|
|
3927
|
+
response = await this.privateGetHfMarginAccountLedgers(this.extend(request, params));
|
|
3928
|
+
}
|
|
3929
|
+
else {
|
|
3930
|
+
response = await this.privateGetHfAccountsLedgers(this.extend(request, params));
|
|
3931
|
+
}
|
|
3932
|
+
}
|
|
3933
|
+
else {
|
|
3934
|
+
response = await this.privateGetAccountsLedgers(this.extend(request, params));
|
|
3935
|
+
}
|
|
3936
|
+
//
|
|
3937
|
+
// {
|
|
3938
|
+
// "code":"200000",
|
|
3939
|
+
// "data":{
|
|
3940
|
+
// "currentPage":1,
|
|
3941
|
+
// "pageSize":50,
|
|
3942
|
+
// "totalNum":1,
|
|
3943
|
+
// "totalPage":1,
|
|
3944
|
+
// "items":[
|
|
3945
|
+
// {
|
|
3946
|
+
// "id":"617cc528729f5f0001c03ceb",
|
|
3947
|
+
// "currency":"GAS",
|
|
3948
|
+
// "amount":"0.00000339",
|
|
3949
|
+
// "fee":"0",
|
|
3950
|
+
// "balance":"0",
|
|
3951
|
+
// "accountType":"MAIN",
|
|
3952
|
+
// "bizType":"Distribution",
|
|
3953
|
+
// "direction":"in",
|
|
3954
|
+
// "createdAt":1635566888183,
|
|
3955
|
+
// "context":"{\"orderId\":\"617cc47a1c47ed0001ce3606\",\"description\":\"Holding NEO,distribute GAS(2021/10/30)\"}"
|
|
3956
|
+
// }
|
|
3957
|
+
// {
|
|
3958
|
+
// "id": "611a1e7c6a053300067a88d9",//unique key
|
|
3959
|
+
// "currency": "USDT", //Currency
|
|
3960
|
+
// "amount": "10.00059547", //Change amount of the funds
|
|
3961
|
+
// "fee": "0", //Deposit or withdrawal fee
|
|
3962
|
+
// "balance": "0", //Total assets of a currency
|
|
3963
|
+
// "accountType": "MAIN", //Account Type
|
|
3964
|
+
// "bizType": "Loans Repaid", //business type
|
|
3965
|
+
// "direction": "in", //side, in or out
|
|
3966
|
+
// "createdAt": 1629101692950, //Creation time
|
|
3967
|
+
// "context": "{\"borrowerUserId\":\"601ad03e50dc810006d242ea\",\"loanRepayDetailNo\":\"611a1e7cc913d000066cf7ec\"}"
|
|
3968
|
+
// },
|
|
3969
|
+
// ]
|
|
3970
|
+
// }
|
|
3971
|
+
// }
|
|
3972
|
+
//
|
|
3973
|
+
const data = this.safeValue(response, 'data');
|
|
3974
|
+
const items = this.safeValue(data, 'items', data);
|
|
3975
|
+
return this.parseLedger(items, currency, since, limit);
|
|
3976
|
+
}
|
|
3977
|
+
calculateRateLimiterCost(api, method, path, params, config = {}) {
|
|
3978
|
+
const versions = this.safeValue(this.options, 'versions', {});
|
|
3979
|
+
const apiVersions = this.safeValue(versions, api, {});
|
|
3980
|
+
const methodVersions = this.safeValue(apiVersions, method, {});
|
|
3981
|
+
const defaultVersion = this.safeString(methodVersions, path, this.options['version']);
|
|
3982
|
+
const version = this.safeString(params, 'version', defaultVersion);
|
|
3983
|
+
if (version === 'v3' && ('v3' in config)) {
|
|
3984
|
+
return config['v3'];
|
|
3985
|
+
}
|
|
3986
|
+
else if (version === 'v2' && ('v2' in config)) {
|
|
3987
|
+
return config['v2'];
|
|
3988
|
+
}
|
|
3989
|
+
else if (version === 'v1' && ('v1' in config)) {
|
|
3990
|
+
return config['v1'];
|
|
3991
|
+
}
|
|
3992
|
+
return this.safeValue(config, 'cost', 1);
|
|
3993
|
+
}
|
|
3994
|
+
parseBorrowRateHistory(response, code, since, limit) {
|
|
3995
|
+
const result = [];
|
|
3996
|
+
for (let i = 0; i < response.length; i++) {
|
|
3997
|
+
const item = response[i];
|
|
3998
|
+
const borrowRate = this.parseBorrowRate(item);
|
|
3999
|
+
result.push(borrowRate);
|
|
4000
|
+
}
|
|
4001
|
+
const sorted = this.sortBy(result, 'timestamp');
|
|
4002
|
+
return this.filterByCurrencySinceLimit(sorted, code, since, limit);
|
|
4003
|
+
}
|
|
4004
|
+
parseBorrowRate(info, currency = undefined) {
|
|
4005
|
+
//
|
|
4006
|
+
// {
|
|
4007
|
+
// "tradeId": "62db2dcaff219600012b56cd",
|
|
4008
|
+
// "currency": "USDT",
|
|
4009
|
+
// "size": "10",
|
|
4010
|
+
// "dailyIntRate": "0.00003",
|
|
4011
|
+
// "term": 7,
|
|
4012
|
+
// "timestamp": 1658531274508488480
|
|
4013
|
+
// },
|
|
4014
|
+
//
|
|
4015
|
+
const timestampId = this.safeString(info, 'timestamp');
|
|
4016
|
+
const timestamp = Precise["default"].stringMul(timestampId, '0.000001');
|
|
4017
|
+
const currencyId = this.safeString(info, 'currency');
|
|
4018
|
+
return {
|
|
4019
|
+
'currency': this.safeCurrencyCode(currencyId, currency),
|
|
4020
|
+
'rate': this.safeNumber(info, 'dailyIntRate'),
|
|
4021
|
+
'period': 86400000,
|
|
4022
|
+
'timestamp': timestamp,
|
|
4023
|
+
'datetime': this.iso8601(timestamp),
|
|
4024
|
+
'info': info,
|
|
4025
|
+
};
|
|
4026
|
+
}
|
|
4027
|
+
async fetchBorrowInterest(code = undefined, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
4028
|
+
/**
|
|
4029
|
+
* @method
|
|
4030
|
+
* @name kucoin#fetchBorrowInterest
|
|
4031
|
+
* @description fetch the interest owed by the user for borrowing currency for margin trading
|
|
4032
|
+
* @see https://docs.kucoin.com/#get-repay-record
|
|
4033
|
+
* @see https://docs.kucoin.com/#query-isolated-margin-account-info
|
|
4034
|
+
* @param {string} code unified currency code
|
|
4035
|
+
* @param {string} symbol unified market symbol, required for isolated margin
|
|
4036
|
+
* @param {int} [since] the earliest time in ms to fetch borrrow interest for
|
|
4037
|
+
* @param {int} [limit] the maximum number of structures to retrieve
|
|
4038
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
4039
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated' default is 'cross'
|
|
4040
|
+
* @returns {object[]} a list of [borrow interest structures]{@link https://docs.ccxt.com/#/?id=borrow-interest-structure}
|
|
4041
|
+
*/
|
|
4042
|
+
await this.loadMarkets();
|
|
4043
|
+
let marginMode = undefined;
|
|
4044
|
+
[marginMode, params] = this.handleMarginModeAndParams('fetchBorrowInterest', params);
|
|
4045
|
+
if (marginMode === undefined) {
|
|
4046
|
+
marginMode = 'cross'; // cross as default marginMode
|
|
4047
|
+
}
|
|
4048
|
+
const request = {};
|
|
4049
|
+
let response = undefined;
|
|
4050
|
+
if (code !== undefined) {
|
|
4051
|
+
const currency = this.currency(code);
|
|
4052
|
+
request['quoteCurrency'] = currency['id'];
|
|
4053
|
+
}
|
|
4054
|
+
if (marginMode === 'isolated') {
|
|
4055
|
+
response = await this.privateGetIsolatedAccounts(this.extend(request, params));
|
|
4056
|
+
}
|
|
4057
|
+
else {
|
|
4058
|
+
response = await this.privateGetMarginAccounts(this.extend(request, params));
|
|
4059
|
+
}
|
|
4060
|
+
//
|
|
4061
|
+
// Cross
|
|
4062
|
+
//
|
|
4063
|
+
// {
|
|
4064
|
+
// "code": "200000",
|
|
4065
|
+
// "data": {
|
|
4066
|
+
// "totalAssetOfQuoteCurrency": "0",
|
|
4067
|
+
// "totalLiabilityOfQuoteCurrency": "0",
|
|
4068
|
+
// "debtRatio": "0",
|
|
4069
|
+
// "status": "EFFECTIVE",
|
|
4070
|
+
// "accounts": [
|
|
4071
|
+
// {
|
|
4072
|
+
// "currency": "1INCH",
|
|
4073
|
+
// "total": "0",
|
|
4074
|
+
// "available": "0",
|
|
4075
|
+
// "hold": "0",
|
|
4076
|
+
// "liability": "0",
|
|
4077
|
+
// "maxBorrowSize": "0",
|
|
4078
|
+
// "borrowEnabled": true,
|
|
4079
|
+
// "transferInEnabled": true
|
|
4080
|
+
// }
|
|
4081
|
+
// ]
|
|
4082
|
+
// }
|
|
4083
|
+
// }
|
|
4084
|
+
//
|
|
4085
|
+
// Isolated
|
|
4086
|
+
//
|
|
4087
|
+
// {
|
|
4088
|
+
// "code": "200000",
|
|
4089
|
+
// "data": {
|
|
4090
|
+
// "totalConversionBalance": "0.02138647",
|
|
4091
|
+
// "liabilityConversionBalance": "0.01480001",
|
|
4092
|
+
// "assets": [
|
|
4093
|
+
// {
|
|
4094
|
+
// "symbol": "MANA-USDT",
|
|
4095
|
+
// "debtRatio": "0",
|
|
4096
|
+
// "status": "BORROW",
|
|
4097
|
+
// "baseAsset": {
|
|
4098
|
+
// "currency": "MANA",
|
|
4099
|
+
// "borrowEnabled": true,
|
|
4100
|
+
// "repayEnabled": true,
|
|
4101
|
+
// "transferEnabled": true,
|
|
4102
|
+
// "borrowed": "0",
|
|
4103
|
+
// "totalAsset": "0",
|
|
4104
|
+
// "available": "0",
|
|
4105
|
+
// "hold": "0",
|
|
4106
|
+
// "maxBorrowSize": "1000"
|
|
4107
|
+
// },
|
|
4108
|
+
// "quoteAsset": {
|
|
4109
|
+
// "currency": "USDT",
|
|
4110
|
+
// "borrowEnabled": true,
|
|
4111
|
+
// "repayEnabled": true,
|
|
4112
|
+
// "transferEnabled": true,
|
|
4113
|
+
// "borrowed": "0",
|
|
4114
|
+
// "totalAsset": "0",
|
|
4115
|
+
// "available": "0",
|
|
4116
|
+
// "hold": "0",
|
|
4117
|
+
// "maxBorrowSize": "50000"
|
|
4118
|
+
// }
|
|
4119
|
+
// }
|
|
4120
|
+
// ]
|
|
4121
|
+
// }
|
|
4122
|
+
// }
|
|
4123
|
+
//
|
|
4124
|
+
const data = this.safeValue(response, 'data', {});
|
|
4125
|
+
const assets = (marginMode === 'isolated') ? this.safeValue(data, 'assets', []) : this.safeValue(data, 'accounts', []);
|
|
4126
|
+
return this.parseBorrowInterests(assets, undefined);
|
|
4127
|
+
}
|
|
4128
|
+
parseBorrowInterest(info, market = undefined) {
|
|
4129
|
+
//
|
|
4130
|
+
// Cross
|
|
4131
|
+
//
|
|
4132
|
+
// {
|
|
4133
|
+
// "currency": "1INCH",
|
|
4134
|
+
// "total": "0",
|
|
4135
|
+
// "available": "0",
|
|
4136
|
+
// "hold": "0",
|
|
4137
|
+
// "liability": "0",
|
|
4138
|
+
// "maxBorrowSize": "0",
|
|
4139
|
+
// "borrowEnabled": true,
|
|
4140
|
+
// "transferInEnabled": true
|
|
4141
|
+
// }
|
|
4142
|
+
//
|
|
4143
|
+
// Isolated
|
|
4144
|
+
//
|
|
4145
|
+
// {
|
|
4146
|
+
// "symbol": "MANA-USDT",
|
|
4147
|
+
// "debtRatio": "0",
|
|
4148
|
+
// "status": "BORROW",
|
|
4149
|
+
// "baseAsset": {
|
|
4150
|
+
// "currency": "MANA",
|
|
4151
|
+
// "borrowEnabled": true,
|
|
4152
|
+
// "repayEnabled": true,
|
|
4153
|
+
// "transferEnabled": true,
|
|
4154
|
+
// "borrowed": "0",
|
|
4155
|
+
// "totalAsset": "0",
|
|
4156
|
+
// "available": "0",
|
|
4157
|
+
// "hold": "0",
|
|
4158
|
+
// "maxBorrowSize": "1000"
|
|
4159
|
+
// },
|
|
4160
|
+
// "quoteAsset": {
|
|
4161
|
+
// "currency": "USDT",
|
|
4162
|
+
// "borrowEnabled": true,
|
|
4163
|
+
// "repayEnabled": true,
|
|
4164
|
+
// "transferEnabled": true,
|
|
4165
|
+
// "borrowed": "0",
|
|
4166
|
+
// "totalAsset": "0",
|
|
4167
|
+
// "available": "0",
|
|
4168
|
+
// "hold": "0",
|
|
4169
|
+
// "maxBorrowSize": "50000"
|
|
4170
|
+
// }
|
|
4171
|
+
// }
|
|
4172
|
+
//
|
|
4173
|
+
const marketId = this.safeString(info, 'symbol');
|
|
4174
|
+
const marginMode = (marketId === undefined) ? 'cross' : 'isolated';
|
|
4175
|
+
market = this.safeMarket(marketId, market);
|
|
4176
|
+
const symbol = this.safeString(market, 'symbol');
|
|
4177
|
+
const timestamp = this.safeInteger(info, 'createdAt');
|
|
4178
|
+
const isolatedBase = this.safeValue(info, 'baseAsset', {});
|
|
4179
|
+
let amountBorrowed = undefined;
|
|
4180
|
+
let interest = undefined;
|
|
4181
|
+
let currencyId = undefined;
|
|
4182
|
+
if (marginMode === 'isolated') {
|
|
4183
|
+
amountBorrowed = this.safeNumber(isolatedBase, 'liability');
|
|
4184
|
+
interest = this.safeNumber(isolatedBase, 'interest');
|
|
4185
|
+
currencyId = this.safeString(isolatedBase, 'currency');
|
|
4186
|
+
}
|
|
4187
|
+
else {
|
|
4188
|
+
amountBorrowed = this.safeNumber(info, 'liability');
|
|
4189
|
+
interest = this.safeNumber(info, 'accruedInterest');
|
|
4190
|
+
currencyId = this.safeString(info, 'currency');
|
|
4191
|
+
}
|
|
4192
|
+
return {
|
|
4193
|
+
'symbol': symbol,
|
|
4194
|
+
'marginMode': marginMode,
|
|
4195
|
+
'currency': this.safeCurrencyCode(currencyId),
|
|
4196
|
+
'interest': interest,
|
|
4197
|
+
'interestRate': this.safeNumber(info, 'dailyIntRate'),
|
|
4198
|
+
'amountBorrowed': amountBorrowed,
|
|
4199
|
+
'timestamp': timestamp,
|
|
4200
|
+
'datetime': this.iso8601(timestamp),
|
|
4201
|
+
'info': info,
|
|
4202
|
+
};
|
|
4203
|
+
}
|
|
4204
|
+
async borrowCrossMargin(code, amount, params = {}) {
|
|
4205
|
+
/**
|
|
4206
|
+
* @method
|
|
4207
|
+
* @name kucoin#borrowCrossMargin
|
|
4208
|
+
* @description create a loan to borrow margin
|
|
4209
|
+
* @see https://docs.kucoin.com/#1-margin-borrowing
|
|
4210
|
+
* @param {string} code unified currency code of the currency to borrow
|
|
4211
|
+
* @param {float} amount the amount to borrow
|
|
4212
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoints
|
|
4213
|
+
* @param {string} [params.timeInForce] either IOC or FOK
|
|
4214
|
+
* @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
|
|
4215
|
+
*/
|
|
4216
|
+
await this.loadMarkets();
|
|
4217
|
+
const currency = this.currency(code);
|
|
4218
|
+
const request = {
|
|
4219
|
+
'currency': currency['id'],
|
|
4220
|
+
'size': this.currencyToPrecision(code, amount),
|
|
4221
|
+
'timeInForce': 'FOK',
|
|
4222
|
+
};
|
|
4223
|
+
const response = await this.privatePostMarginBorrow(this.extend(request, params));
|
|
4224
|
+
//
|
|
4225
|
+
// {
|
|
4226
|
+
// "success": true,
|
|
4227
|
+
// "code": "200",
|
|
4228
|
+
// "msg": "success",
|
|
4229
|
+
// "retry": false,
|
|
4230
|
+
// "data": {
|
|
4231
|
+
// "orderNo": "5da6dba0f943c0c81f5d5db5",
|
|
4232
|
+
// "actualSize": 10
|
|
4233
|
+
// }
|
|
4234
|
+
// }
|
|
4235
|
+
//
|
|
4236
|
+
const data = this.safeValue(response, 'data', {});
|
|
4237
|
+
return this.parseMarginLoan(data, currency);
|
|
4238
|
+
}
|
|
4239
|
+
async borrowIsolatedMargin(symbol, code, amount, params = {}) {
|
|
4240
|
+
/**
|
|
4241
|
+
* @method
|
|
4242
|
+
* @name kucoin#borrowIsolatedMargin
|
|
4243
|
+
* @description create a loan to borrow margin
|
|
4244
|
+
* @see https://docs.kucoin.com/#1-margin-borrowing
|
|
4245
|
+
* @param {string} symbol unified market symbol, required for isolated margin
|
|
4246
|
+
* @param {string} code unified currency code of the currency to borrow
|
|
4247
|
+
* @param {float} amount the amount to borrow
|
|
4248
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoints
|
|
4249
|
+
* @param {string} [params.timeInForce] either IOC or FOK
|
|
4250
|
+
* @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
|
|
4251
|
+
*/
|
|
4252
|
+
await this.loadMarkets();
|
|
4253
|
+
const market = this.market(symbol);
|
|
4254
|
+
const currency = this.currency(code);
|
|
4255
|
+
const request = {
|
|
4256
|
+
'currency': currency['id'],
|
|
4257
|
+
'size': this.currencyToPrecision(code, amount),
|
|
4258
|
+
'symbol': market['id'],
|
|
4259
|
+
'timeInForce': 'FOK',
|
|
4260
|
+
'isIsolated': true,
|
|
4261
|
+
};
|
|
4262
|
+
const response = await this.privatePostMarginBorrow(this.extend(request, params));
|
|
4263
|
+
//
|
|
4264
|
+
// {
|
|
4265
|
+
// "success": true,
|
|
4266
|
+
// "code": "200",
|
|
4267
|
+
// "msg": "success",
|
|
4268
|
+
// "retry": false,
|
|
4269
|
+
// "data": {
|
|
4270
|
+
// "orderNo": "5da6dba0f943c0c81f5d5db5",
|
|
4271
|
+
// "actualSize": 10
|
|
4272
|
+
// }
|
|
4273
|
+
// }
|
|
4274
|
+
//
|
|
4275
|
+
const data = this.safeValue(response, 'data', {});
|
|
4276
|
+
return this.parseMarginLoan(data, currency);
|
|
4277
|
+
}
|
|
4278
|
+
async repayCrossMargin(code, amount, params = {}) {
|
|
4279
|
+
/**
|
|
4280
|
+
* @method
|
|
4281
|
+
* @name kucoin#repayCrossMargin
|
|
4282
|
+
* @description repay borrowed margin and interest
|
|
4283
|
+
* @see https://docs.kucoin.com/#2-repayment
|
|
4284
|
+
* @param {string} code unified currency code of the currency to repay
|
|
4285
|
+
* @param {float} amount the amount to repay
|
|
4286
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoints
|
|
4287
|
+
* @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
|
|
4288
|
+
*/
|
|
4289
|
+
await this.loadMarkets();
|
|
4290
|
+
const currency = this.currency(code);
|
|
4291
|
+
const request = {
|
|
4292
|
+
'currency': currency['id'],
|
|
4293
|
+
'size': this.currencyToPrecision(code, amount),
|
|
4294
|
+
};
|
|
4295
|
+
const response = await this.privatePostMarginRepay(this.extend(request, params));
|
|
4296
|
+
//
|
|
4297
|
+
// {
|
|
4298
|
+
// "success": true,
|
|
4299
|
+
// "code": "200",
|
|
4300
|
+
// "msg": "success",
|
|
4301
|
+
// "retry": false,
|
|
4302
|
+
// "data": {
|
|
4303
|
+
// "orderNo": "5da6dba0f943c0c81f5d5db5",
|
|
4304
|
+
// "actualSize": 10
|
|
4305
|
+
// }
|
|
4306
|
+
// }
|
|
4307
|
+
//
|
|
4308
|
+
const data = this.safeValue(response, 'data', {});
|
|
4309
|
+
return this.parseMarginLoan(data, currency);
|
|
4310
|
+
}
|
|
4311
|
+
async repayIsolatedMargin(symbol, code, amount, params = {}) {
|
|
4312
|
+
/**
|
|
4313
|
+
* @method
|
|
4314
|
+
* @name kucoin#repayIsolatedMargin
|
|
4315
|
+
* @description repay borrowed margin and interest
|
|
4316
|
+
* @see https://docs.kucoin.com/#2-repayment
|
|
4317
|
+
* @param {string} symbol unified market symbol
|
|
4318
|
+
* @param {string} code unified currency code of the currency to repay
|
|
4319
|
+
* @param {float} amount the amount to repay
|
|
4320
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoints
|
|
4321
|
+
* @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
|
|
4322
|
+
*/
|
|
4323
|
+
await this.loadMarkets();
|
|
4324
|
+
const market = this.market(symbol);
|
|
4325
|
+
const currency = this.currency(code);
|
|
4326
|
+
const request = {
|
|
4327
|
+
'currency': currency['id'],
|
|
4328
|
+
'size': this.currencyToPrecision(code, amount),
|
|
4329
|
+
'symbol': market['id'],
|
|
4330
|
+
'isIsolated': true,
|
|
4331
|
+
};
|
|
4332
|
+
const response = await this.privatePostMarginRepay(this.extend(request, params));
|
|
4333
|
+
//
|
|
4334
|
+
// {
|
|
4335
|
+
// "success": true,
|
|
4336
|
+
// "code": "200",
|
|
4337
|
+
// "msg": "success",
|
|
4338
|
+
// "retry": false,
|
|
4339
|
+
// "data": {
|
|
4340
|
+
// "orderNo": "5da6dba0f943c0c81f5d5db5",
|
|
4341
|
+
// "actualSize": 10
|
|
4342
|
+
// }
|
|
4343
|
+
// }
|
|
4344
|
+
//
|
|
4345
|
+
const data = this.safeValue(response, 'data', {});
|
|
4346
|
+
return this.parseMarginLoan(data, currency);
|
|
4347
|
+
}
|
|
4348
|
+
parseMarginLoan(info, currency = undefined) {
|
|
4349
|
+
//
|
|
4350
|
+
// {
|
|
4351
|
+
// "orderNo": "5da6dba0f943c0c81f5d5db5",
|
|
4352
|
+
// "actualSize": 10
|
|
4353
|
+
// }
|
|
4354
|
+
//
|
|
4355
|
+
const timestamp = this.milliseconds();
|
|
4356
|
+
const currencyId = this.safeString(info, 'currency');
|
|
4357
|
+
return {
|
|
4358
|
+
'id': this.safeString(info, 'orderNo'),
|
|
4359
|
+
'currency': this.safeCurrencyCode(currencyId, currency),
|
|
4360
|
+
'amount': this.safeNumber(info, 'actualSize'),
|
|
4361
|
+
'symbol': undefined,
|
|
4362
|
+
'timestamp': timestamp,
|
|
4363
|
+
'datetime': this.iso8601(timestamp),
|
|
4364
|
+
'info': info,
|
|
4365
|
+
};
|
|
4366
|
+
}
|
|
4367
|
+
async fetchDepositWithdrawFees(codes = undefined, params = {}) {
|
|
4368
|
+
/**
|
|
4369
|
+
* @method
|
|
4370
|
+
* @name kucoin#fetchDepositWithdrawFees
|
|
4371
|
+
* @description fetch deposit and withdraw fees - *IMPORTANT* use fetchDepositWithdrawFee to get more in-depth info
|
|
4372
|
+
* @see https://docs.kucoin.com/#get-currencies
|
|
4373
|
+
* @param {string[]|undefined} codes list of unified currency codes
|
|
4374
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
4375
|
+
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
4376
|
+
*/
|
|
4377
|
+
await this.loadMarkets();
|
|
4378
|
+
const response = await this.publicGetCurrencies(params);
|
|
4379
|
+
//
|
|
4380
|
+
// [
|
|
4381
|
+
// {
|
|
4382
|
+
// "currency": "CSP",
|
|
4383
|
+
// "name": "CSP",
|
|
4384
|
+
// "fullName": "Caspian",
|
|
4385
|
+
// "precision": 8,
|
|
4386
|
+
// "confirms": 12,
|
|
4387
|
+
// "contractAddress": "0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
|
|
4388
|
+
// "withdrawalMinSize": "2000",
|
|
4389
|
+
// "withdrawalMinFee": "1000",
|
|
4390
|
+
// "isWithdrawEnabled": true,
|
|
4391
|
+
// "isDepositEnabled": true,
|
|
4392
|
+
// "isMarginEnabled": false,
|
|
4393
|
+
// "isDebitEnabled": false
|
|
4394
|
+
// },
|
|
4395
|
+
// ]
|
|
4396
|
+
//
|
|
4397
|
+
const data = this.safeValue(response, 'data', []);
|
|
4398
|
+
return this.parseDepositWithdrawFees(data, codes, 'currency');
|
|
4399
|
+
}
|
|
4400
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
4401
|
+
//
|
|
4402
|
+
// the v2 URL is https://openapi-v2.kucoin.com/api/v1/endpoint
|
|
4403
|
+
// ↑ ↑
|
|
4404
|
+
// ↑ ↑
|
|
4405
|
+
//
|
|
4406
|
+
const versions = this.safeValue(this.options, 'versions', {});
|
|
4407
|
+
const apiVersions = this.safeValue(versions, api, {});
|
|
4408
|
+
const methodVersions = this.safeValue(apiVersions, method, {});
|
|
4409
|
+
const defaultVersion = this.safeString(methodVersions, path, this.options['version']);
|
|
4410
|
+
const version = this.safeString(params, 'version', defaultVersion);
|
|
4411
|
+
params = this.omit(params, 'version');
|
|
4412
|
+
let endpoint = '/api/' + version + '/' + this.implodeParams(path, params);
|
|
4413
|
+
if (api === 'webExchange') {
|
|
4414
|
+
endpoint = '/' + this.implodeParams(path, params);
|
|
4415
|
+
}
|
|
4416
|
+
const query = this.omit(params, this.extractParams(path));
|
|
4417
|
+
let endpart = '';
|
|
4418
|
+
headers = (headers !== undefined) ? headers : {};
|
|
4419
|
+
let url = this.urls['api'][api];
|
|
4420
|
+
if (Object.keys(query).length) {
|
|
4421
|
+
if ((method === 'GET') || (method === 'DELETE')) {
|
|
4422
|
+
endpoint += '?' + this.rawencode(query);
|
|
4423
|
+
}
|
|
4424
|
+
else {
|
|
4425
|
+
body = this.json(query);
|
|
4426
|
+
endpart = body;
|
|
4427
|
+
headers['Content-Type'] = 'application/json';
|
|
4428
|
+
}
|
|
4429
|
+
}
|
|
4430
|
+
url = url + endpoint;
|
|
4431
|
+
const isFuturePrivate = (api === 'futuresPrivate');
|
|
4432
|
+
const isPrivate = (api === 'private');
|
|
4433
|
+
if (isPrivate || isFuturePrivate) {
|
|
4434
|
+
this.checkRequiredCredentials();
|
|
4435
|
+
const timestamp = this.nonce().toString();
|
|
4436
|
+
headers = this.extend({
|
|
4437
|
+
'KC-API-KEY-VERSION': '2',
|
|
4438
|
+
'KC-API-KEY': this.apiKey,
|
|
4439
|
+
'KC-API-TIMESTAMP': timestamp,
|
|
4440
|
+
}, headers);
|
|
4441
|
+
const apiKeyVersion = this.safeString(headers, 'KC-API-KEY-VERSION');
|
|
4442
|
+
if (apiKeyVersion === '2') {
|
|
4443
|
+
const passphrase = this.hmac(this.encode(this.password), this.encode(this.secret), sha256.sha256, 'base64');
|
|
4444
|
+
headers['KC-API-PASSPHRASE'] = passphrase;
|
|
4445
|
+
}
|
|
4446
|
+
else {
|
|
4447
|
+
headers['KC-API-PASSPHRASE'] = this.password;
|
|
4448
|
+
}
|
|
4449
|
+
const payload = timestamp + method + endpoint + endpart;
|
|
4450
|
+
const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256.sha256, 'base64');
|
|
4451
|
+
headers['KC-API-SIGN'] = signature;
|
|
4452
|
+
let partner = this.safeValue(this.options, 'partner', {});
|
|
4453
|
+
partner = isFuturePrivate ? this.safeValue(partner, 'future', partner) : this.safeValue(partner, 'spot', partner);
|
|
4454
|
+
const partnerId = this.safeString(partner, 'id');
|
|
4455
|
+
const partnerSecret = this.safeString2(partner, 'secret', 'key');
|
|
4456
|
+
if ((partnerId !== undefined) && (partnerSecret !== undefined)) {
|
|
4457
|
+
const partnerPayload = timestamp + partnerId + this.apiKey;
|
|
4458
|
+
const partnerSignature = this.hmac(this.encode(partnerPayload), this.encode(partnerSecret), sha256.sha256, 'base64');
|
|
4459
|
+
headers['KC-API-PARTNER-SIGN'] = partnerSignature;
|
|
4460
|
+
headers['KC-API-PARTNER'] = partnerId;
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
4464
|
+
}
|
|
4465
|
+
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
4466
|
+
if (!response) {
|
|
4467
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], body, body);
|
|
4468
|
+
return undefined;
|
|
4469
|
+
}
|
|
4470
|
+
//
|
|
4471
|
+
// bad
|
|
4472
|
+
// { "code": "400100", "msg": "validation.createOrder.clientOidIsRequired" }
|
|
4473
|
+
// good
|
|
4474
|
+
// { code: '200000', data: { ... }}
|
|
4475
|
+
//
|
|
4476
|
+
const errorCode = this.safeString(response, 'code');
|
|
4477
|
+
const message = this.safeString2(response, 'msg', 'data', '');
|
|
4478
|
+
const feedback = this.id + ' ' + message;
|
|
4479
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
4480
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
|
|
4481
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], body, feedback);
|
|
4482
|
+
if (errorCode !== '200000' && errorCode !== '200') {
|
|
4483
|
+
throw new errors.ExchangeError(feedback);
|
|
4484
|
+
}
|
|
4485
|
+
return undefined;
|
|
4486
|
+
}
|
|
4487
|
+
}
|
|
4488
|
+
|
|
4489
|
+
module.exports = kucoin;
|