ccxt 4.2.11 → 4.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/build.sh +2 -2
- package/dist/ccxt.browser.js +640 -261
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/_virtual/agent.js +7 -0
- package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
- package/dist/cjs/_virtual/promisify.js +7 -0
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/js/ccxt.js +474 -0
- package/dist/cjs/js/src/abstract/ace.js +9 -0
- package/dist/cjs/js/src/abstract/alpaca.js +9 -0
- package/dist/cjs/js/src/abstract/ascendex.js +9 -0
- package/dist/cjs/js/src/abstract/bigone.js +9 -0
- package/dist/cjs/js/src/abstract/binance.js +9 -0
- package/dist/cjs/js/src/abstract/bingx.js +9 -0
- package/dist/cjs/js/src/abstract/bit2c.js +9 -0
- package/dist/cjs/js/src/abstract/bitbank.js +9 -0
- package/dist/cjs/js/src/abstract/bitbns.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
- package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
- package/dist/cjs/js/src/abstract/bitforex.js +9 -0
- package/dist/cjs/js/src/abstract/bitget.js +9 -0
- package/dist/cjs/js/src/abstract/bithumb.js +9 -0
- package/dist/cjs/js/src/abstract/bitmart.js +9 -0
- package/dist/cjs/js/src/abstract/bitmex.js +9 -0
- package/dist/cjs/js/src/abstract/bitopro.js +9 -0
- package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
- package/dist/cjs/js/src/abstract/bitrue.js +9 -0
- package/dist/cjs/js/src/abstract/bitso.js +9 -0
- package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
- package/dist/cjs/js/src/abstract/bitteam.js +9 -0
- package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
- package/dist/cjs/js/src/abstract/bl3p.js +9 -0
- package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
- package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
- package/dist/cjs/js/src/abstract/btcbox.js +9 -0
- package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
- package/dist/cjs/js/src/abstract/btcturk.js +9 -0
- package/dist/cjs/js/src/abstract/bybit.js +9 -0
- package/dist/cjs/js/src/abstract/cex.js +9 -0
- package/dist/cjs/js/src/abstract/coinbase.js +9 -0
- package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
- package/dist/cjs/js/src/abstract/coincheck.js +9 -0
- package/dist/cjs/js/src/abstract/coinex.js +9 -0
- package/dist/cjs/js/src/abstract/coinlist.js +9 -0
- package/dist/cjs/js/src/abstract/coinmate.js +9 -0
- package/dist/cjs/js/src/abstract/coinone.js +9 -0
- package/dist/cjs/js/src/abstract/coinsph.js +9 -0
- package/dist/cjs/js/src/abstract/coinspot.js +9 -0
- package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
- package/dist/cjs/js/src/abstract/currencycom.js +9 -0
- package/dist/cjs/js/src/abstract/delta.js +9 -0
- package/dist/cjs/js/src/abstract/deribit.js +9 -0
- package/dist/cjs/js/src/abstract/digifinex.js +9 -0
- package/dist/cjs/js/src/abstract/exmo.js +9 -0
- package/dist/cjs/js/src/abstract/gate.js +9 -0
- package/dist/cjs/js/src/abstract/gemini.js +9 -0
- package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
- package/dist/cjs/js/src/abstract/hollaex.js +9 -0
- package/dist/cjs/js/src/abstract/htx.js +9 -0
- package/dist/cjs/js/src/abstract/huobijp.js +9 -0
- package/dist/cjs/js/src/abstract/idex.js +9 -0
- package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
- package/dist/cjs/js/src/abstract/indodax.js +9 -0
- package/dist/cjs/js/src/abstract/kraken.js +9 -0
- package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kucoin.js +9 -0
- package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kuna.js +9 -0
- package/dist/cjs/js/src/abstract/latoken.js +9 -0
- package/dist/cjs/js/src/abstract/lbank.js +9 -0
- package/dist/cjs/js/src/abstract/luno.js +9 -0
- package/dist/cjs/js/src/abstract/lykke.js +9 -0
- package/dist/cjs/js/src/abstract/mercado.js +9 -0
- package/dist/cjs/js/src/abstract/mexc.js +9 -0
- package/dist/cjs/js/src/abstract/ndax.js +9 -0
- package/dist/cjs/js/src/abstract/novadax.js +9 -0
- package/dist/cjs/js/src/abstract/oceanex.js +9 -0
- package/dist/cjs/js/src/abstract/okcoin.js +9 -0
- package/dist/cjs/js/src/abstract/okx.js +9 -0
- package/dist/cjs/js/src/abstract/p2b.js +9 -0
- package/dist/cjs/js/src/abstract/paymium.js +9 -0
- package/dist/cjs/js/src/abstract/phemex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
- package/dist/cjs/js/src/abstract/probit.js +9 -0
- package/dist/cjs/js/src/abstract/timex.js +9 -0
- package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
- package/dist/cjs/js/src/abstract/upbit.js +9 -0
- package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
- package/dist/cjs/js/src/abstract/wazirx.js +9 -0
- package/dist/cjs/js/src/abstract/whitebit.js +9 -0
- package/dist/cjs/js/src/abstract/woo.js +9 -0
- package/dist/cjs/js/src/abstract/yobit.js +9 -0
- package/dist/cjs/js/src/abstract/zaif.js +9 -0
- package/dist/cjs/js/src/abstract/zonda.js +9 -0
- package/dist/cjs/js/src/ace.js +1058 -0
- package/dist/cjs/js/src/alpaca.js +1125 -0
- package/dist/cjs/js/src/ascendex.js +3360 -0
- package/dist/cjs/js/src/base/Exchange.js +5110 -0
- package/dist/cjs/js/src/base/Precise.js +263 -0
- package/dist/cjs/js/src/base/errors.js +299 -0
- package/dist/cjs/js/src/base/functions/crypto.js +78 -0
- package/dist/cjs/js/src/base/functions/encode.js +44 -0
- package/dist/cjs/js/src/base/functions/generic.js +193 -0
- package/dist/cjs/js/src/base/functions/misc.js +96 -0
- package/dist/cjs/js/src/base/functions/number.js +297 -0
- package/dist/cjs/js/src/base/functions/platform.js +28 -0
- package/dist/cjs/js/src/base/functions/rsa.js +34 -0
- package/dist/cjs/js/src/base/functions/string.js +48 -0
- package/dist/cjs/js/src/base/functions/throttle.js +66 -0
- package/dist/cjs/js/src/base/functions/time.js +187 -0
- package/dist/cjs/js/src/base/functions/totp.js +24 -0
- package/dist/cjs/js/src/base/functions/type.js +162 -0
- package/dist/cjs/js/src/base/functions.js +157 -0
- package/dist/cjs/js/src/base/ws/Cache.js +254 -0
- package/dist/cjs/js/src/base/ws/Client.js +299 -0
- package/dist/cjs/js/src/base/ws/Future.js +34 -0
- package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
- package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
- package/dist/cjs/js/src/bequant.js +33 -0
- package/dist/cjs/js/src/bigone.js +2142 -0
- package/dist/cjs/js/src/binance.js +9729 -0
- package/dist/cjs/js/src/binancecoinm.js +45 -0
- package/dist/cjs/js/src/binanceus.js +84 -0
- package/dist/cjs/js/src/binanceusdm.js +58 -0
- package/dist/cjs/js/src/bingx.js +3737 -0
- package/dist/cjs/js/src/bit2c.js +916 -0
- package/dist/cjs/js/src/bitbank.js +1000 -0
- package/dist/cjs/js/src/bitbay.js +17 -0
- package/dist/cjs/js/src/bitbns.js +1220 -0
- package/dist/cjs/js/src/bitcoincom.js +17 -0
- package/dist/cjs/js/src/bitfinex.js +1670 -0
- package/dist/cjs/js/src/bitfinex2.js +2990 -0
- package/dist/cjs/js/src/bitflyer.js +1045 -0
- package/dist/cjs/js/src/bitforex.js +852 -0
- package/dist/cjs/js/src/bitget.js +8284 -0
- package/dist/cjs/js/src/bithumb.js +1090 -0
- package/dist/cjs/js/src/bitmart.js +4454 -0
- package/dist/cjs/js/src/bitmex.js +2884 -0
- package/dist/cjs/js/src/bitopro.js +1724 -0
- package/dist/cjs/js/src/bitpanda.js +2002 -0
- package/dist/cjs/js/src/bitrue.js +3253 -0
- package/dist/cjs/js/src/bitso.js +1753 -0
- package/dist/cjs/js/src/bitstamp.js +2188 -0
- package/dist/cjs/js/src/bitteam.js +2309 -0
- package/dist/cjs/js/src/bitvavo.js +1968 -0
- package/dist/cjs/js/src/bl3p.js +447 -0
- package/dist/cjs/js/src/blockchaincom.js +1160 -0
- package/dist/cjs/js/src/btcalpha.js +929 -0
- package/dist/cjs/js/src/btcbox.js +565 -0
- package/dist/cjs/js/src/btcmarkets.js +1237 -0
- package/dist/cjs/js/src/btcturk.js +929 -0
- package/dist/cjs/js/src/bybit.js +7646 -0
- package/dist/cjs/js/src/cex.js +1693 -0
- package/dist/cjs/js/src/coinbase.js +3274 -0
- package/dist/cjs/js/src/coinbasepro.js +1866 -0
- package/dist/cjs/js/src/coincheck.js +843 -0
- package/dist/cjs/js/src/coinex.js +5414 -0
- package/dist/cjs/js/src/coinlist.js +2329 -0
- package/dist/cjs/js/src/coinmate.js +989 -0
- package/dist/cjs/js/src/coinone.js +1185 -0
- package/dist/cjs/js/src/coinsph.js +1933 -0
- package/dist/cjs/js/src/coinspot.js +548 -0
- package/dist/cjs/js/src/cryptocom.js +3007 -0
- package/dist/cjs/js/src/currencycom.js +2015 -0
- package/dist/cjs/js/src/delta.js +3256 -0
- package/dist/cjs/js/src/deribit.js +3306 -0
- package/dist/cjs/js/src/digifinex.js +4307 -0
- package/dist/cjs/js/src/exmo.js +2645 -0
- package/dist/cjs/js/src/fmfwio.js +34 -0
- package/dist/cjs/js/src/gate.js +7054 -0
- package/dist/cjs/js/src/gateio.js +16 -0
- package/dist/cjs/js/src/gemini.js +1801 -0
- package/dist/cjs/js/src/hitbtc.js +3660 -0
- package/dist/cjs/js/src/hitbtc3.js +19 -0
- package/dist/cjs/js/src/hollaex.js +1882 -0
- package/dist/cjs/js/src/htx.js +9024 -0
- package/dist/cjs/js/src/huobi.js +16 -0
- package/dist/cjs/js/src/huobijp.js +1918 -0
- package/dist/cjs/js/src/idex.js +1770 -0
- package/dist/cjs/js/src/independentreserve.js +759 -0
- package/dist/cjs/js/src/indodax.js +1069 -0
- package/dist/cjs/js/src/kraken.js +2861 -0
- package/dist/cjs/js/src/krakenfutures.js +2407 -0
- package/dist/cjs/js/src/kucoin.js +4489 -0
- package/dist/cjs/js/src/kucoinfutures.js +2475 -0
- package/dist/cjs/js/src/kuna.js +1949 -0
- package/dist/cjs/js/src/latoken.js +1729 -0
- package/dist/cjs/js/src/lbank.js +2825 -0
- package/dist/cjs/js/src/luno.js +1044 -0
- package/dist/cjs/js/src/lykke.js +1303 -0
- package/dist/cjs/js/src/mercado.js +897 -0
- package/dist/cjs/js/src/mexc.js +5407 -0
- package/dist/cjs/js/src/ndax.js +2450 -0
- package/dist/cjs/js/src/novadax.js +1556 -0
- package/dist/cjs/js/src/oceanex.js +964 -0
- package/dist/cjs/js/src/okcoin.js +3115 -0
- package/dist/cjs/js/src/okx.js +7329 -0
- package/dist/cjs/js/src/p2b.js +1243 -0
- package/dist/cjs/js/src/paymium.js +597 -0
- package/dist/cjs/js/src/phemex.js +4715 -0
- package/dist/cjs/js/src/poloniex.js +2356 -0
- package/dist/cjs/js/src/poloniexfutures.js +1794 -0
- package/dist/cjs/js/src/pro/alpaca.js +714 -0
- package/dist/cjs/js/src/pro/ascendex.js +957 -0
- package/dist/cjs/js/src/pro/bequant.js +33 -0
- package/dist/cjs/js/src/pro/binance.js +2796 -0
- package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
- package/dist/cjs/js/src/pro/binanceus.js +51 -0
- package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
- package/dist/cjs/js/src/pro/bingx.js +944 -0
- package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
- package/dist/cjs/js/src/pro/bitfinex.js +672 -0
- package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
- package/dist/cjs/js/src/pro/bitget.js +1733 -0
- package/dist/cjs/js/src/pro/bitmart.js +1486 -0
- package/dist/cjs/js/src/pro/bitmex.js +1576 -0
- package/dist/cjs/js/src/pro/bitopro.js +327 -0
- package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
- package/dist/cjs/js/src/pro/bitrue.js +462 -0
- package/dist/cjs/js/src/pro/bitstamp.js +547 -0
- package/dist/cjs/js/src/pro/bitvavo.js +704 -0
- package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
- package/dist/cjs/js/src/pro/bybit.js +1843 -0
- package/dist/cjs/js/src/pro/cex.js +1510 -0
- package/dist/cjs/js/src/pro/coinbase.js +561 -0
- package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
- package/dist/cjs/js/src/pro/coinex.js +1095 -0
- package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
- package/dist/cjs/js/src/pro/currencycom.js +563 -0
- package/dist/cjs/js/src/pro/deribit.js +825 -0
- package/dist/cjs/js/src/pro/exmo.js +658 -0
- package/dist/cjs/js/src/pro/gate.js +1316 -0
- package/dist/cjs/js/src/pro/gateio.js +16 -0
- package/dist/cjs/js/src/pro/gemini.js +649 -0
- package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
- package/dist/cjs/js/src/pro/hollaex.js +597 -0
- package/dist/cjs/js/src/pro/htx.js +2383 -0
- package/dist/cjs/js/src/pro/huobi.js +16 -0
- package/dist/cjs/js/src/pro/huobijp.js +606 -0
- package/dist/cjs/js/src/pro/idex.js +714 -0
- package/dist/cjs/js/src/pro/independentreserve.js +280 -0
- package/dist/cjs/js/src/pro/kraken.js +1364 -0
- package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
- package/dist/cjs/js/src/pro/kucoin.js +1052 -0
- package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
- package/dist/cjs/js/src/pro/luno.js +322 -0
- package/dist/cjs/js/src/pro/mexc.js +1170 -0
- package/dist/cjs/js/src/pro/ndax.js +545 -0
- package/dist/cjs/js/src/pro/okcoin.js +760 -0
- package/dist/cjs/js/src/pro/okx.js +1558 -0
- package/dist/cjs/js/src/pro/phemex.js +1511 -0
- package/dist/cjs/js/src/pro/poloniex.js +1253 -0
- package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
- package/dist/cjs/js/src/pro/probit.js +586 -0
- package/dist/cjs/js/src/pro/upbit.js +234 -0
- package/dist/cjs/js/src/pro/wazirx.js +776 -0
- package/dist/cjs/js/src/pro/whitebit.js +927 -0
- package/dist/cjs/js/src/pro/woo.js +769 -0
- package/dist/cjs/js/src/probit.js +1865 -0
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
- package/dist/cjs/js/src/timex.js +1562 -0
- package/dist/cjs/js/src/tokocrypto.js +2542 -0
- package/dist/cjs/js/src/upbit.js +1844 -0
- package/dist/cjs/js/src/wavesexchange.js +2607 -0
- package/dist/cjs/js/src/wazirx.js +953 -0
- package/dist/cjs/js/src/whitebit.js +2309 -0
- package/dist/cjs/js/src/woo.js +2715 -0
- package/dist/cjs/js/src/yobit.js +1314 -0
- package/dist/cjs/js/src/zaif.js +736 -0
- package/dist/cjs/js/src/zonda.js +1883 -0
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bigone.d.ts +18 -0
- package/js/src/abstract/binance.d.ts +2 -0
- package/js/src/abstract/binancecoinm.d.ts +2 -0
- package/js/src/abstract/binanceus.d.ts +2 -0
- package/js/src/abstract/binanceusdm.d.ts +2 -0
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/abstract/gate.d.ts +11 -0
- package/js/src/abstract/gateio.d.ts +11 -0
- package/js/src/alpaca.js +18 -18
- package/js/src/base/Exchange.d.ts +5 -1
- package/js/src/base/Exchange.js +101 -12
- package/js/src/bigone.d.ts +1 -2
- package/js/src/bigone.js +340 -145
- package/js/src/binance.js +15 -8
- package/js/src/bingx.js +9 -2
- package/js/src/bitfinex.d.ts +2 -2
- package/js/src/bitfinex.js +2 -3
- package/js/src/bitget.js +21 -8
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +3 -3
- package/js/src/bitmex.js +1 -0
- package/js/src/bybit.js +2 -0
- package/js/src/coinlist.js +2 -3
- package/js/src/coinsph.js +2 -3
- package/js/src/deribit.js +1 -0
- package/js/src/gate.d.ts +4 -4
- package/js/src/gate.js +22 -3
- package/js/src/hitbtc.d.ts +4 -4
- package/js/src/hitbtc.js +2 -3
- package/js/src/htx.js +4 -7
- package/js/src/huobijp.js +2 -3
- package/js/src/kraken.js +1 -0
- package/js/src/mexc.js +2 -1
- package/js/src/okx.js +13 -3
- package/js/src/pro/binance.d.ts +2 -23
- package/js/src/pro/binance.js +58 -22
- package/js/src/pro/coinbase.d.ts +2 -2
- package/js/src/pro/coinbase.js +4 -1
- package/js/src/pro/coinbasepro.d.ts +2 -2
- package/js/src/pro/hitbtc.d.ts +2 -2
- package/js/src/pro/poloniex.d.ts +2 -2
- package/js/src/upbit.d.ts +3 -101
- package/js/src/upbit.js +12 -12
- package/js/src/woo.js +2 -0
- package/package.json +1 -1
- package/skip-tests.json +5 -0
|
@@ -0,0 +1,1844 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var upbit$1 = require('./abstract/upbit.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 sha512 = require('./static_dependencies/noble-hashes/sha512.js');
|
|
8
|
+
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
|
|
9
|
+
var rsa = require('./base/functions/rsa.js');
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/**
|
|
14
|
+
* @class upbit
|
|
15
|
+
* @augments Exchange
|
|
16
|
+
*/
|
|
17
|
+
class upbit extends upbit$1 {
|
|
18
|
+
describe() {
|
|
19
|
+
return this.deepExtend(super.describe(), {
|
|
20
|
+
'id': 'upbit',
|
|
21
|
+
'name': 'Upbit',
|
|
22
|
+
'countries': ['KR'],
|
|
23
|
+
'version': 'v1',
|
|
24
|
+
'rateLimit': 1000,
|
|
25
|
+
'pro': true,
|
|
26
|
+
// new metainfo interface
|
|
27
|
+
'has': {
|
|
28
|
+
'CORS': true,
|
|
29
|
+
'spot': true,
|
|
30
|
+
'margin': undefined,
|
|
31
|
+
'swap': false,
|
|
32
|
+
'future': false,
|
|
33
|
+
'option': false,
|
|
34
|
+
'cancelOrder': true,
|
|
35
|
+
'createDepositAddress': true,
|
|
36
|
+
'createMarketBuyOrderWithCost': true,
|
|
37
|
+
'createMarketOrder': true,
|
|
38
|
+
'createMarketOrderWithCost': false,
|
|
39
|
+
'createMarketSellOrderWithCost': false,
|
|
40
|
+
'createOrder': true,
|
|
41
|
+
'fetchBalance': true,
|
|
42
|
+
'fetchCanceledOrders': true,
|
|
43
|
+
'fetchClosedOrders': true,
|
|
44
|
+
'fetchDepositAddress': true,
|
|
45
|
+
'fetchDepositAddresses': true,
|
|
46
|
+
'fetchDeposits': true,
|
|
47
|
+
'fetchFundingHistory': false,
|
|
48
|
+
'fetchFundingRate': false,
|
|
49
|
+
'fetchFundingRateHistory': false,
|
|
50
|
+
'fetchFundingRates': false,
|
|
51
|
+
'fetchIndexOHLCV': false,
|
|
52
|
+
'fetchMarginMode': false,
|
|
53
|
+
'fetchMarkets': true,
|
|
54
|
+
'fetchMarkOHLCV': false,
|
|
55
|
+
'fetchMyTrades': false,
|
|
56
|
+
'fetchOHLCV': true,
|
|
57
|
+
'fetchOpenInterestHistory': false,
|
|
58
|
+
'fetchOpenOrders': true,
|
|
59
|
+
'fetchOrder': true,
|
|
60
|
+
'fetchOrderBook': true,
|
|
61
|
+
'fetchOrderBooks': true,
|
|
62
|
+
'fetchOrders': false,
|
|
63
|
+
'fetchPositionMode': false,
|
|
64
|
+
'fetchPremiumIndexOHLCV': false,
|
|
65
|
+
'fetchTicker': true,
|
|
66
|
+
'fetchTickers': true,
|
|
67
|
+
'fetchTrades': true,
|
|
68
|
+
'fetchTradingFee': true,
|
|
69
|
+
'fetchTradingFees': false,
|
|
70
|
+
'fetchTransactions': false,
|
|
71
|
+
'fetchWithdrawals': true,
|
|
72
|
+
'transfer': false,
|
|
73
|
+
'withdraw': true,
|
|
74
|
+
},
|
|
75
|
+
'timeframes': {
|
|
76
|
+
'1m': 'minutes',
|
|
77
|
+
'3m': 'minutes',
|
|
78
|
+
'5m': 'minutes',
|
|
79
|
+
'15m': 'minutes',
|
|
80
|
+
'30m': 'minutes',
|
|
81
|
+
'1h': 'minutes',
|
|
82
|
+
'4h': 'minutes',
|
|
83
|
+
'1d': 'days',
|
|
84
|
+
'1w': 'weeks',
|
|
85
|
+
'1M': 'months',
|
|
86
|
+
},
|
|
87
|
+
'hostname': 'api.upbit.com',
|
|
88
|
+
'urls': {
|
|
89
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/49245610-eeaabe00-f423-11e8-9cba-4b0aed794799.jpg',
|
|
90
|
+
'api': {
|
|
91
|
+
'public': 'https://{hostname}',
|
|
92
|
+
'private': 'https://{hostname}',
|
|
93
|
+
},
|
|
94
|
+
'www': 'https://upbit.com',
|
|
95
|
+
'doc': 'https://docs.upbit.com/docs/%EC%9A%94%EC%B2%AD-%EC%88%98-%EC%A0%9C%ED%95%9C',
|
|
96
|
+
'fees': 'https://upbit.com/service_center/guide',
|
|
97
|
+
},
|
|
98
|
+
'api': {
|
|
99
|
+
'public': {
|
|
100
|
+
'get': [
|
|
101
|
+
'market/all',
|
|
102
|
+
'candles/{timeframe}',
|
|
103
|
+
'candles/{timeframe}/{unit}',
|
|
104
|
+
'candles/minutes/{unit}',
|
|
105
|
+
'candles/minutes/1',
|
|
106
|
+
'candles/minutes/3',
|
|
107
|
+
'candles/minutes/5',
|
|
108
|
+
'candles/minutes/15',
|
|
109
|
+
'candles/minutes/30',
|
|
110
|
+
'candles/minutes/60',
|
|
111
|
+
'candles/minutes/240',
|
|
112
|
+
'candles/days',
|
|
113
|
+
'candles/weeks',
|
|
114
|
+
'candles/months',
|
|
115
|
+
'trades/ticks',
|
|
116
|
+
'ticker',
|
|
117
|
+
'orderbook',
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
'private': {
|
|
121
|
+
'get': [
|
|
122
|
+
'accounts',
|
|
123
|
+
'orders/chance',
|
|
124
|
+
'order',
|
|
125
|
+
'orders',
|
|
126
|
+
'withdraws',
|
|
127
|
+
'withdraw',
|
|
128
|
+
'withdraws/chance',
|
|
129
|
+
'deposits',
|
|
130
|
+
'deposit',
|
|
131
|
+
'deposits/coin_addresses',
|
|
132
|
+
'deposits/coin_address',
|
|
133
|
+
],
|
|
134
|
+
'post': [
|
|
135
|
+
'orders',
|
|
136
|
+
'withdraws/coin',
|
|
137
|
+
'withdraws/krw',
|
|
138
|
+
'deposits/generate_coin_address',
|
|
139
|
+
],
|
|
140
|
+
'delete': [
|
|
141
|
+
'order',
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
'fees': {
|
|
146
|
+
'trading': {
|
|
147
|
+
'tierBased': false,
|
|
148
|
+
'percentage': true,
|
|
149
|
+
'maker': this.parseNumber('0.0025'),
|
|
150
|
+
'taker': this.parseNumber('0.0025'),
|
|
151
|
+
},
|
|
152
|
+
'funding': {
|
|
153
|
+
'tierBased': false,
|
|
154
|
+
'percentage': false,
|
|
155
|
+
'withdraw': {},
|
|
156
|
+
'deposit': {},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
'precisionMode': number.TICK_SIZE,
|
|
160
|
+
'exceptions': {
|
|
161
|
+
'exact': {
|
|
162
|
+
'This key has expired.': errors.AuthenticationError,
|
|
163
|
+
'Missing request parameter error. Check the required parameters!': errors.BadRequest,
|
|
164
|
+
'side is missing, side does not have a valid value': errors.InvalidOrder,
|
|
165
|
+
},
|
|
166
|
+
'broad': {
|
|
167
|
+
'thirdparty_agreement_required': errors.PermissionDenied,
|
|
168
|
+
'out_of_scope': errors.PermissionDenied,
|
|
169
|
+
'order_not_found': errors.OrderNotFound,
|
|
170
|
+
'insufficient_funds': errors.InsufficientFunds,
|
|
171
|
+
'invalid_access_key': errors.AuthenticationError,
|
|
172
|
+
'jwt_verification': errors.AuthenticationError,
|
|
173
|
+
'create_ask_error': errors.ExchangeError,
|
|
174
|
+
'create_bid_error': errors.ExchangeError,
|
|
175
|
+
'volume_too_large': errors.InvalidOrder,
|
|
176
|
+
'invalid_funds': errors.InvalidOrder,
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
'options': {
|
|
180
|
+
'createMarketBuyOrderRequiresPrice': true,
|
|
181
|
+
'fetchTickersMaxLength': 4096,
|
|
182
|
+
'fetchOrderBooksMaxLength': 4096,
|
|
183
|
+
'tradingFeesByQuoteCurrency': {
|
|
184
|
+
'KRW': 0.0005,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
'commonCurrencies': {
|
|
188
|
+
'TON': 'Tokamak Network',
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
async fetchCurrency(code, params = {}) {
|
|
193
|
+
// this method is for retrieving funding fees and limits per currency
|
|
194
|
+
// it requires private access and API keys properly set up
|
|
195
|
+
await this.loadMarkets();
|
|
196
|
+
const currency = this.currency(code);
|
|
197
|
+
return await this.fetchCurrencyById(currency['id'], params);
|
|
198
|
+
}
|
|
199
|
+
async fetchCurrencyById(id, params = {}) {
|
|
200
|
+
// this method is for retrieving funding fees and limits per currency
|
|
201
|
+
// it requires private access and API keys properly set up
|
|
202
|
+
const request = {
|
|
203
|
+
'currency': id,
|
|
204
|
+
};
|
|
205
|
+
const response = await this.privateGetWithdrawsChance(this.extend(request, params));
|
|
206
|
+
//
|
|
207
|
+
// {
|
|
208
|
+
// "member_level": {
|
|
209
|
+
// "security_level": 3,
|
|
210
|
+
// "fee_level": 0,
|
|
211
|
+
// "email_verified": true,
|
|
212
|
+
// "identity_auth_verified": true,
|
|
213
|
+
// "bank_account_verified": true,
|
|
214
|
+
// "kakao_pay_auth_verified": false,
|
|
215
|
+
// "locked": false,
|
|
216
|
+
// "wallet_locked": false
|
|
217
|
+
// },
|
|
218
|
+
// "currency": {
|
|
219
|
+
// "code": "BTC",
|
|
220
|
+
// "withdraw_fee": "0.0005",
|
|
221
|
+
// "is_coin": true,
|
|
222
|
+
// "wallet_state": "working",
|
|
223
|
+
// "wallet_support": [ "deposit", "withdraw" ]
|
|
224
|
+
// },
|
|
225
|
+
// "account": {
|
|
226
|
+
// "currency": "BTC",
|
|
227
|
+
// "balance": "10.0",
|
|
228
|
+
// "locked": "0.0",
|
|
229
|
+
// "avg_krw_buy_price": "8042000",
|
|
230
|
+
// "modified": false
|
|
231
|
+
// },
|
|
232
|
+
// "withdraw_limit": {
|
|
233
|
+
// "currency": "BTC",
|
|
234
|
+
// "minimum": null,
|
|
235
|
+
// "onetime": null,
|
|
236
|
+
// "daily": "10.0",
|
|
237
|
+
// "remaining_daily": "10.0",
|
|
238
|
+
// "remaining_daily_krw": "0.0",
|
|
239
|
+
// "fixed": null,
|
|
240
|
+
// "can_withdraw": true
|
|
241
|
+
// }
|
|
242
|
+
// }
|
|
243
|
+
//
|
|
244
|
+
const memberInfo = this.safeValue(response, 'member_level', {});
|
|
245
|
+
const currencyInfo = this.safeValue(response, 'currency', {});
|
|
246
|
+
const withdrawLimits = this.safeValue(response, 'withdraw_limit', {});
|
|
247
|
+
const canWithdraw = this.safeValue(withdrawLimits, 'can_withdraw');
|
|
248
|
+
const walletState = this.safeString(currencyInfo, 'wallet_state');
|
|
249
|
+
const walletLocked = this.safeValue(memberInfo, 'wallet_locked');
|
|
250
|
+
const locked = this.safeValue(memberInfo, 'locked');
|
|
251
|
+
let active = true;
|
|
252
|
+
if ((canWithdraw !== undefined) && !canWithdraw) {
|
|
253
|
+
active = false;
|
|
254
|
+
}
|
|
255
|
+
else if (walletState !== 'working') {
|
|
256
|
+
active = false;
|
|
257
|
+
}
|
|
258
|
+
else if ((walletLocked !== undefined) && walletLocked) {
|
|
259
|
+
active = false;
|
|
260
|
+
}
|
|
261
|
+
else if ((locked !== undefined) && locked) {
|
|
262
|
+
active = false;
|
|
263
|
+
}
|
|
264
|
+
const maxOnetimeWithdrawal = this.safeString(withdrawLimits, 'onetime');
|
|
265
|
+
const maxDailyWithdrawal = this.safeString(withdrawLimits, 'daily', maxOnetimeWithdrawal);
|
|
266
|
+
const remainingDailyWithdrawal = this.safeString(withdrawLimits, 'remaining_daily', maxDailyWithdrawal);
|
|
267
|
+
let maxWithdrawLimit = undefined;
|
|
268
|
+
if (Precise["default"].stringGt(remainingDailyWithdrawal, '0')) {
|
|
269
|
+
maxWithdrawLimit = remainingDailyWithdrawal;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
maxWithdrawLimit = maxDailyWithdrawal;
|
|
273
|
+
}
|
|
274
|
+
const currencyId = this.safeString(currencyInfo, 'code');
|
|
275
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
276
|
+
return {
|
|
277
|
+
'info': response,
|
|
278
|
+
'id': currencyId,
|
|
279
|
+
'code': code,
|
|
280
|
+
'name': code,
|
|
281
|
+
'active': active,
|
|
282
|
+
'fee': this.safeNumber(currencyInfo, 'withdraw_fee'),
|
|
283
|
+
'precision': undefined,
|
|
284
|
+
'limits': {
|
|
285
|
+
'withdraw': {
|
|
286
|
+
'min': this.safeNumber(withdrawLimits, 'minimum'),
|
|
287
|
+
'max': this.parseNumber(maxWithdrawLimit),
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
async fetchMarket(symbol, params = {}) {
|
|
293
|
+
// this method is for retrieving trading fees and limits per market
|
|
294
|
+
// it requires private access and API keys properly set up
|
|
295
|
+
await this.loadMarkets();
|
|
296
|
+
const market = this.market(symbol);
|
|
297
|
+
return await this.fetchMarketById(market['id'], params);
|
|
298
|
+
}
|
|
299
|
+
async fetchMarketById(id, params = {}) {
|
|
300
|
+
// this method is for retrieving trading fees and limits per market
|
|
301
|
+
// it requires private access and API keys properly set up
|
|
302
|
+
const request = {
|
|
303
|
+
'market': id,
|
|
304
|
+
};
|
|
305
|
+
const response = await this.privateGetOrdersChance(this.extend(request, params));
|
|
306
|
+
//
|
|
307
|
+
// {
|
|
308
|
+
// "bid_fee": "0.0015",
|
|
309
|
+
// "ask_fee": "0.0015",
|
|
310
|
+
// "market": {
|
|
311
|
+
// "id": "KRW-BTC",
|
|
312
|
+
// "name": "BTC/KRW",
|
|
313
|
+
// "order_types": [ "limit" ],
|
|
314
|
+
// "order_sides": [ "ask", "bid" ],
|
|
315
|
+
// "bid": { "currency": "KRW", "price_unit": null, "min_total": 1000 },
|
|
316
|
+
// "ask": { "currency": "BTC", "price_unit": null, "min_total": 1000 },
|
|
317
|
+
// "max_total": "100000000.0",
|
|
318
|
+
// "state": "active",
|
|
319
|
+
// },
|
|
320
|
+
// "bid_account": {
|
|
321
|
+
// "currency": "KRW",
|
|
322
|
+
// "balance": "0.0",
|
|
323
|
+
// "locked": "0.0",
|
|
324
|
+
// "avg_buy_price": "0",
|
|
325
|
+
// "avg_buy_price_modified": false,
|
|
326
|
+
// "unit_currency": "KRW",
|
|
327
|
+
// },
|
|
328
|
+
// "ask_account": {
|
|
329
|
+
// "currency": "BTC",
|
|
330
|
+
// "balance": "10.0",
|
|
331
|
+
// "locked": "0.0",
|
|
332
|
+
// "avg_buy_price": "8042000",
|
|
333
|
+
// "avg_buy_price_modified": false,
|
|
334
|
+
// "unit_currency": "KRW",
|
|
335
|
+
// }
|
|
336
|
+
// }
|
|
337
|
+
//
|
|
338
|
+
const marketInfo = this.safeValue(response, 'market');
|
|
339
|
+
const bid = this.safeValue(marketInfo, 'bid');
|
|
340
|
+
const ask = this.safeValue(marketInfo, 'ask');
|
|
341
|
+
const marketId = this.safeString(marketInfo, 'id');
|
|
342
|
+
const baseId = this.safeString(ask, 'currency');
|
|
343
|
+
const quoteId = this.safeString(bid, 'currency');
|
|
344
|
+
const base = this.safeCurrencyCode(baseId);
|
|
345
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
346
|
+
const state = this.safeString(marketInfo, 'state');
|
|
347
|
+
const bidFee = this.safeString(response, 'bid_fee');
|
|
348
|
+
const askFee = this.safeString(response, 'ask_fee');
|
|
349
|
+
const fee = this.parseNumber(Precise["default"].stringMax(bidFee, askFee));
|
|
350
|
+
return this.safeMarketStructure({
|
|
351
|
+
'id': marketId,
|
|
352
|
+
'symbol': base + '/' + quote,
|
|
353
|
+
'base': base,
|
|
354
|
+
'quote': quote,
|
|
355
|
+
'settle': undefined,
|
|
356
|
+
'baseId': baseId,
|
|
357
|
+
'quoteId': quoteId,
|
|
358
|
+
'settleId': undefined,
|
|
359
|
+
'type': 'spot',
|
|
360
|
+
'spot': true,
|
|
361
|
+
'margin': false,
|
|
362
|
+
'swap': false,
|
|
363
|
+
'future': false,
|
|
364
|
+
'option': false,
|
|
365
|
+
'active': (state === 'active'),
|
|
366
|
+
'contract': false,
|
|
367
|
+
'linear': undefined,
|
|
368
|
+
'inverse': undefined,
|
|
369
|
+
'taker': fee,
|
|
370
|
+
'maker': fee,
|
|
371
|
+
'contractSize': undefined,
|
|
372
|
+
'expiry': undefined,
|
|
373
|
+
'expiryDatetime': undefined,
|
|
374
|
+
'strike': undefined,
|
|
375
|
+
'optionType': undefined,
|
|
376
|
+
'precision': {
|
|
377
|
+
'amount': this.parseNumber('1e-8'),
|
|
378
|
+
'price': this.parseNumber('1e-8'),
|
|
379
|
+
},
|
|
380
|
+
'limits': {
|
|
381
|
+
'leverage': {
|
|
382
|
+
'min': undefined,
|
|
383
|
+
'max': undefined,
|
|
384
|
+
},
|
|
385
|
+
'amount': {
|
|
386
|
+
'min': this.safeNumber(ask, 'min_total'),
|
|
387
|
+
'max': undefined,
|
|
388
|
+
},
|
|
389
|
+
'price': {
|
|
390
|
+
'min': undefined,
|
|
391
|
+
'max': undefined,
|
|
392
|
+
},
|
|
393
|
+
'cost': {
|
|
394
|
+
'min': this.safeNumber(bid, 'min_total'),
|
|
395
|
+
'max': this.safeNumber(marketInfo, 'max_total'),
|
|
396
|
+
},
|
|
397
|
+
'info': response,
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
async fetchMarkets(params = {}) {
|
|
402
|
+
/**
|
|
403
|
+
* @method
|
|
404
|
+
* @name upbit#fetchMarkets
|
|
405
|
+
* @see https://docs.upbit.com/reference/%EB%A7%88%EC%BC%93-%EC%BD%94%EB%93%9C-%EC%A1%B0%ED%9A%8C
|
|
406
|
+
* @description retrieves data on all markets for upbit
|
|
407
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
408
|
+
* @returns {object[]} an array of objects representing market data
|
|
409
|
+
*/
|
|
410
|
+
const response = await this.publicGetMarketAll(params);
|
|
411
|
+
//
|
|
412
|
+
// [
|
|
413
|
+
// {
|
|
414
|
+
// "market": "KRW-BTC",
|
|
415
|
+
// "korean_name": "비트코인",
|
|
416
|
+
// "english_name": "Bitcoin"
|
|
417
|
+
// },
|
|
418
|
+
// ...,
|
|
419
|
+
// ]
|
|
420
|
+
//
|
|
421
|
+
return this.parseMarkets(response);
|
|
422
|
+
}
|
|
423
|
+
parseMarket(market) {
|
|
424
|
+
const id = this.safeString(market, 'market');
|
|
425
|
+
const [quoteId, baseId] = id.split('-');
|
|
426
|
+
const base = this.safeCurrencyCode(baseId);
|
|
427
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
428
|
+
return this.safeMarketStructure({
|
|
429
|
+
'id': id,
|
|
430
|
+
'symbol': base + '/' + quote,
|
|
431
|
+
'base': base,
|
|
432
|
+
'quote': quote,
|
|
433
|
+
'settle': undefined,
|
|
434
|
+
'baseId': baseId,
|
|
435
|
+
'quoteId': quoteId,
|
|
436
|
+
'settleId': undefined,
|
|
437
|
+
'type': 'spot',
|
|
438
|
+
'spot': true,
|
|
439
|
+
'margin': false,
|
|
440
|
+
'swap': false,
|
|
441
|
+
'future': false,
|
|
442
|
+
'option': false,
|
|
443
|
+
'active': true,
|
|
444
|
+
'contract': false,
|
|
445
|
+
'linear': undefined,
|
|
446
|
+
'inverse': undefined,
|
|
447
|
+
'taker': this.safeNumber(this.options['tradingFeesByQuoteCurrency'], quote, this.fees['trading']['taker']),
|
|
448
|
+
'maker': this.safeNumber(this.options['tradingFeesByQuoteCurrency'], quote, this.fees['trading']['maker']),
|
|
449
|
+
'contractSize': undefined,
|
|
450
|
+
'expiry': undefined,
|
|
451
|
+
'expiryDatetime': undefined,
|
|
452
|
+
'strike': undefined,
|
|
453
|
+
'optionType': undefined,
|
|
454
|
+
'precision': {
|
|
455
|
+
'price': this.parseNumber('1e-8'),
|
|
456
|
+
'amount': this.parseNumber('1e-8'),
|
|
457
|
+
},
|
|
458
|
+
'limits': {
|
|
459
|
+
'leverage': {
|
|
460
|
+
'min': undefined,
|
|
461
|
+
'max': undefined,
|
|
462
|
+
},
|
|
463
|
+
'amount': {
|
|
464
|
+
'min': undefined,
|
|
465
|
+
'max': undefined,
|
|
466
|
+
},
|
|
467
|
+
'price': {
|
|
468
|
+
'min': undefined,
|
|
469
|
+
'max': undefined,
|
|
470
|
+
},
|
|
471
|
+
'cost': {
|
|
472
|
+
'min': undefined,
|
|
473
|
+
'max': undefined,
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
'created': undefined,
|
|
477
|
+
'info': market,
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
parseBalance(response) {
|
|
481
|
+
const result = {
|
|
482
|
+
'info': response,
|
|
483
|
+
'timestamp': undefined,
|
|
484
|
+
'datetime': undefined,
|
|
485
|
+
};
|
|
486
|
+
for (let i = 0; i < response.length; i++) {
|
|
487
|
+
const balance = response[i];
|
|
488
|
+
const currencyId = this.safeString(balance, 'currency');
|
|
489
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
490
|
+
const account = this.account();
|
|
491
|
+
account['free'] = this.safeString(balance, 'balance');
|
|
492
|
+
account['used'] = this.safeString(balance, 'locked');
|
|
493
|
+
result[code] = account;
|
|
494
|
+
}
|
|
495
|
+
return this.safeBalance(result);
|
|
496
|
+
}
|
|
497
|
+
async fetchBalance(params = {}) {
|
|
498
|
+
/**
|
|
499
|
+
* @method
|
|
500
|
+
* @name upbit#fetchBalance
|
|
501
|
+
* @see https://docs.upbit.com/reference/%EC%A0%84%EC%B2%B4-%EA%B3%84%EC%A2%8C-%EC%A1%B0%ED%9A%8C
|
|
502
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
503
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
504
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
505
|
+
*/
|
|
506
|
+
await this.loadMarkets();
|
|
507
|
+
const response = await this.privateGetAccounts(params);
|
|
508
|
+
//
|
|
509
|
+
// [ { currency: "BTC",
|
|
510
|
+
// "balance": "0.005",
|
|
511
|
+
// "locked": "0.0",
|
|
512
|
+
// "avg_krw_buy_price": "7446000",
|
|
513
|
+
// "modified": false },
|
|
514
|
+
// { currency: "ETH",
|
|
515
|
+
// "balance": "0.1",
|
|
516
|
+
// "locked": "0.0",
|
|
517
|
+
// "avg_krw_buy_price": "250000",
|
|
518
|
+
// "modified": false } ]
|
|
519
|
+
//
|
|
520
|
+
return this.parseBalance(response);
|
|
521
|
+
}
|
|
522
|
+
async fetchOrderBooks(symbols = undefined, limit = undefined, params = {}) {
|
|
523
|
+
/**
|
|
524
|
+
* @method
|
|
525
|
+
* @name upbit#fetchOrderBooks
|
|
526
|
+
* @see https://docs.upbit.com/reference/%ED%98%B8%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
|
|
527
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data for multiple markets
|
|
528
|
+
* @param {string[]|undefined} symbols list of unified market symbols, all symbols fetched if undefined, default is undefined
|
|
529
|
+
* @param {int} [limit] not used by upbit fetchOrderBooks ()
|
|
530
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
531
|
+
* @returns {object} a dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbol
|
|
532
|
+
*/
|
|
533
|
+
await this.loadMarkets();
|
|
534
|
+
let ids = undefined;
|
|
535
|
+
if (symbols === undefined) {
|
|
536
|
+
ids = this.ids.join(',');
|
|
537
|
+
// max URL length is 2083 symbols, including http schema, hostname, tld, etc...
|
|
538
|
+
if (ids.length > this.options['fetchOrderBooksMaxLength']) {
|
|
539
|
+
const numIds = this.ids.length;
|
|
540
|
+
throw new errors.ExchangeError(this.id + ' fetchOrderBooks() has ' + numIds.toString() + ' symbols (' + ids.length.toString() + ' characters) exceeding max URL length (' + this.options['fetchOrderBooksMaxLength'].toString() + ' characters), you are required to specify a list of symbols in the first argument to fetchOrderBooks');
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
ids = this.marketIds(symbols);
|
|
545
|
+
ids = ids.join(',');
|
|
546
|
+
}
|
|
547
|
+
const request = {
|
|
548
|
+
'markets': ids,
|
|
549
|
+
};
|
|
550
|
+
const response = await this.publicGetOrderbook(this.extend(request, params));
|
|
551
|
+
//
|
|
552
|
+
// [ { market: "BTC-ETH",
|
|
553
|
+
// "timestamp": 1542899030043,
|
|
554
|
+
// "total_ask_size": 109.57065201,
|
|
555
|
+
// "total_bid_size": 125.74430631,
|
|
556
|
+
// "orderbook_units": [ { ask_price: 0.02926679,
|
|
557
|
+
// "bid_price": 0.02919904,
|
|
558
|
+
// "ask_size": 4.20293961,
|
|
559
|
+
// "bid_size": 11.65043576 },
|
|
560
|
+
// ...,
|
|
561
|
+
// { ask_price: 0.02938209,
|
|
562
|
+
// "bid_price": 0.0291231,
|
|
563
|
+
// "ask_size": 0.05135782,
|
|
564
|
+
// "bid_size": 13.5595 } ] },
|
|
565
|
+
// { market: "KRW-BTC",
|
|
566
|
+
// "timestamp": 1542899034662,
|
|
567
|
+
// "total_ask_size": 12.89790974,
|
|
568
|
+
// "total_bid_size": 4.88395783,
|
|
569
|
+
// "orderbook_units": [ { ask_price: 5164000,
|
|
570
|
+
// "bid_price": 5162000,
|
|
571
|
+
// "ask_size": 2.57606495,
|
|
572
|
+
// "bid_size": 0.214 },
|
|
573
|
+
// ...,
|
|
574
|
+
// { ask_price: 5176000,
|
|
575
|
+
// "bid_price": 5152000,
|
|
576
|
+
// "ask_size": 2.752,
|
|
577
|
+
// "bid_size": 0.4650305 } ] } ]
|
|
578
|
+
//
|
|
579
|
+
const result = {};
|
|
580
|
+
for (let i = 0; i < response.length; i++) {
|
|
581
|
+
const orderbook = response[i];
|
|
582
|
+
const marketId = this.safeString(orderbook, 'market');
|
|
583
|
+
const symbol = this.safeSymbol(marketId, undefined, '-');
|
|
584
|
+
const timestamp = this.safeInteger(orderbook, 'timestamp');
|
|
585
|
+
result[symbol] = {
|
|
586
|
+
'symbol': symbol,
|
|
587
|
+
'bids': this.sortBy(this.parseBidsAsks(orderbook['orderbook_units'], 'bid_price', 'bid_size'), 0, true),
|
|
588
|
+
'asks': this.sortBy(this.parseBidsAsks(orderbook['orderbook_units'], 'ask_price', 'ask_size'), 0),
|
|
589
|
+
'timestamp': timestamp,
|
|
590
|
+
'datetime': this.iso8601(timestamp),
|
|
591
|
+
'nonce': undefined,
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
return result;
|
|
595
|
+
}
|
|
596
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
597
|
+
/**
|
|
598
|
+
* @method
|
|
599
|
+
* @name upbit#fetchOrderBook
|
|
600
|
+
* @see https://docs.upbit.com/reference/%ED%98%B8%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
|
|
601
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
602
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
603
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
604
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
605
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
606
|
+
*/
|
|
607
|
+
const orderbooks = await this.fetchOrderBooks([symbol], limit, params);
|
|
608
|
+
return this.safeValue(orderbooks, symbol);
|
|
609
|
+
}
|
|
610
|
+
parseTicker(ticker, market = undefined) {
|
|
611
|
+
//
|
|
612
|
+
// { market: "BTC-ETH",
|
|
613
|
+
// "trade_date": "20181122",
|
|
614
|
+
// "trade_time": "104543",
|
|
615
|
+
// "trade_date_kst": "20181122",
|
|
616
|
+
// "trade_time_kst": "194543",
|
|
617
|
+
// "trade_timestamp": 1542883543097,
|
|
618
|
+
// "opening_price": 0.02976455,
|
|
619
|
+
// "high_price": 0.02992577,
|
|
620
|
+
// "low_price": 0.02934283,
|
|
621
|
+
// "trade_price": 0.02947773,
|
|
622
|
+
// "prev_closing_price": 0.02966,
|
|
623
|
+
// "change": "FALL",
|
|
624
|
+
// "change_price": 0.00018227,
|
|
625
|
+
// "change_rate": 0.0061453136,
|
|
626
|
+
// "signed_change_price": -0.00018227,
|
|
627
|
+
// "signed_change_rate": -0.0061453136,
|
|
628
|
+
// "trade_volume": 1.00000005,
|
|
629
|
+
// "acc_trade_price": 100.95825586,
|
|
630
|
+
// "acc_trade_price_24h": 289.58650166,
|
|
631
|
+
// "acc_trade_volume": 3409.85311036,
|
|
632
|
+
// "acc_trade_volume_24h": 9754.40510513,
|
|
633
|
+
// "highest_52_week_price": 0.12345678,
|
|
634
|
+
// "highest_52_week_date": "2018-02-01",
|
|
635
|
+
// "lowest_52_week_price": 0.023936,
|
|
636
|
+
// "lowest_52_week_date": "2017-12-08",
|
|
637
|
+
// "timestamp": 1542883543813 }
|
|
638
|
+
//
|
|
639
|
+
const timestamp = this.safeInteger(ticker, 'trade_timestamp');
|
|
640
|
+
const marketId = this.safeString2(ticker, 'market', 'code');
|
|
641
|
+
market = this.safeMarket(marketId, market, '-');
|
|
642
|
+
const last = this.safeString(ticker, 'trade_price');
|
|
643
|
+
return this.safeTicker({
|
|
644
|
+
'symbol': market['symbol'],
|
|
645
|
+
'timestamp': timestamp,
|
|
646
|
+
'datetime': this.iso8601(timestamp),
|
|
647
|
+
'high': this.safeString(ticker, 'high_price'),
|
|
648
|
+
'low': this.safeString(ticker, 'low_price'),
|
|
649
|
+
'bid': undefined,
|
|
650
|
+
'bidVolume': undefined,
|
|
651
|
+
'ask': undefined,
|
|
652
|
+
'askVolume': undefined,
|
|
653
|
+
'vwap': undefined,
|
|
654
|
+
'open': this.safeString(ticker, 'opening_price'),
|
|
655
|
+
'close': last,
|
|
656
|
+
'last': last,
|
|
657
|
+
'previousClose': this.safeString(ticker, 'prev_closing_price'),
|
|
658
|
+
'change': this.safeString(ticker, 'signed_change_price'),
|
|
659
|
+
'percentage': this.safeString(ticker, 'signed_change_rate'),
|
|
660
|
+
'average': undefined,
|
|
661
|
+
'baseVolume': this.safeString(ticker, 'acc_trade_volume_24h'),
|
|
662
|
+
'quoteVolume': this.safeString(ticker, 'acc_trade_price_24h'),
|
|
663
|
+
'info': ticker,
|
|
664
|
+
}, market);
|
|
665
|
+
}
|
|
666
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
667
|
+
/**
|
|
668
|
+
* @method
|
|
669
|
+
* @name upbit#fetchTickers
|
|
670
|
+
* @see https://docs.upbit.com/reference/ticker%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4
|
|
671
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
672
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
673
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
674
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
675
|
+
*/
|
|
676
|
+
await this.loadMarkets();
|
|
677
|
+
symbols = this.marketSymbols(symbols);
|
|
678
|
+
let ids = undefined;
|
|
679
|
+
if (symbols === undefined) {
|
|
680
|
+
ids = this.ids.join(',');
|
|
681
|
+
// max URL length is 2083 symbols, including http schema, hostname, tld, etc...
|
|
682
|
+
if (ids.length > this.options['fetchTickersMaxLength']) {
|
|
683
|
+
const numIds = this.ids.length;
|
|
684
|
+
throw new errors.ExchangeError(this.id + ' fetchTickers() has ' + numIds.toString() + ' symbols exceeding max URL length, you are required to specify a list of symbols in the first argument to fetchTickers');
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
ids = this.marketIds(symbols);
|
|
689
|
+
ids = ids.join(',');
|
|
690
|
+
}
|
|
691
|
+
const request = {
|
|
692
|
+
'markets': ids,
|
|
693
|
+
};
|
|
694
|
+
const response = await this.publicGetTicker(this.extend(request, params));
|
|
695
|
+
//
|
|
696
|
+
// [ { market: "BTC-ETH",
|
|
697
|
+
// "trade_date": "20181122",
|
|
698
|
+
// "trade_time": "104543",
|
|
699
|
+
// "trade_date_kst": "20181122",
|
|
700
|
+
// "trade_time_kst": "194543",
|
|
701
|
+
// "trade_timestamp": 1542883543097,
|
|
702
|
+
// "opening_price": 0.02976455,
|
|
703
|
+
// "high_price": 0.02992577,
|
|
704
|
+
// "low_price": 0.02934283,
|
|
705
|
+
// "trade_price": 0.02947773,
|
|
706
|
+
// "prev_closing_price": 0.02966,
|
|
707
|
+
// "change": "FALL",
|
|
708
|
+
// "change_price": 0.00018227,
|
|
709
|
+
// "change_rate": 0.0061453136,
|
|
710
|
+
// "signed_change_price": -0.00018227,
|
|
711
|
+
// "signed_change_rate": -0.0061453136,
|
|
712
|
+
// "trade_volume": 1.00000005,
|
|
713
|
+
// "acc_trade_price": 100.95825586,
|
|
714
|
+
// "acc_trade_price_24h": 289.58650166,
|
|
715
|
+
// "acc_trade_volume": 3409.85311036,
|
|
716
|
+
// "acc_trade_volume_24h": 9754.40510513,
|
|
717
|
+
// "highest_52_week_price": 0.12345678,
|
|
718
|
+
// "highest_52_week_date": "2018-02-01",
|
|
719
|
+
// "lowest_52_week_price": 0.023936,
|
|
720
|
+
// "lowest_52_week_date": "2017-12-08",
|
|
721
|
+
// "timestamp": 1542883543813 } ]
|
|
722
|
+
//
|
|
723
|
+
const result = {};
|
|
724
|
+
for (let t = 0; t < response.length; t++) {
|
|
725
|
+
const ticker = this.parseTicker(response[t]);
|
|
726
|
+
const symbol = ticker['symbol'];
|
|
727
|
+
result[symbol] = ticker;
|
|
728
|
+
}
|
|
729
|
+
return this.filterByArrayTickers(result, 'symbol', symbols);
|
|
730
|
+
}
|
|
731
|
+
async fetchTicker(symbol, params = {}) {
|
|
732
|
+
/**
|
|
733
|
+
* @method
|
|
734
|
+
* @name upbit#fetchTicker
|
|
735
|
+
* @see https://docs.upbit.com/reference/ticker%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4
|
|
736
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
737
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
738
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
739
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
740
|
+
*/
|
|
741
|
+
const tickers = await this.fetchTickers([symbol], params);
|
|
742
|
+
return this.safeValue(tickers, symbol);
|
|
743
|
+
}
|
|
744
|
+
parseTrade(trade, market = undefined) {
|
|
745
|
+
//
|
|
746
|
+
// fetchTrades
|
|
747
|
+
//
|
|
748
|
+
// { market: "BTC-ETH",
|
|
749
|
+
// "trade_date_utc": "2018-11-22",
|
|
750
|
+
// "trade_time_utc": "13:55:24",
|
|
751
|
+
// "timestamp": 1542894924397,
|
|
752
|
+
// "trade_price": 0.02914289,
|
|
753
|
+
// "trade_volume": 0.20074397,
|
|
754
|
+
// "prev_closing_price": 0.02966,
|
|
755
|
+
// "change_price": -0.00051711,
|
|
756
|
+
// "ask_bid": "ASK",
|
|
757
|
+
// "sequential_id": 15428949259430000 }
|
|
758
|
+
//
|
|
759
|
+
// fetchOrder trades
|
|
760
|
+
//
|
|
761
|
+
// {
|
|
762
|
+
// "market": "KRW-BTC",
|
|
763
|
+
// "uuid": "78162304-1a4d-4524-b9e6-c9a9e14d76c3",
|
|
764
|
+
// "price": "101000.0",
|
|
765
|
+
// "volume": "0.77368323",
|
|
766
|
+
// "funds": "78142.00623",
|
|
767
|
+
// "ask_fee": "117.213009345",
|
|
768
|
+
// "bid_fee": "117.213009345",
|
|
769
|
+
// "created_at": "2018-04-05T14:09:15+09:00",
|
|
770
|
+
// "side": "bid",
|
|
771
|
+
// }
|
|
772
|
+
//
|
|
773
|
+
const id = this.safeString2(trade, 'sequential_id', 'uuid');
|
|
774
|
+
const orderId = undefined;
|
|
775
|
+
let timestamp = this.safeInteger(trade, 'timestamp');
|
|
776
|
+
if (timestamp === undefined) {
|
|
777
|
+
timestamp = this.parse8601(this.safeString(trade, 'created_at'));
|
|
778
|
+
}
|
|
779
|
+
let side = undefined;
|
|
780
|
+
const askOrBid = this.safeStringLower2(trade, 'ask_bid', 'side');
|
|
781
|
+
if (askOrBid === 'ask') {
|
|
782
|
+
side = 'sell';
|
|
783
|
+
}
|
|
784
|
+
else if (askOrBid === 'bid') {
|
|
785
|
+
side = 'buy';
|
|
786
|
+
}
|
|
787
|
+
const cost = this.safeString(trade, 'funds');
|
|
788
|
+
const price = this.safeString2(trade, 'trade_price', 'price');
|
|
789
|
+
const amount = this.safeString2(trade, 'trade_volume', 'volume');
|
|
790
|
+
const marketId = this.safeString2(trade, 'market', 'code');
|
|
791
|
+
market = this.safeMarket(marketId, market, '-');
|
|
792
|
+
let fee = undefined;
|
|
793
|
+
const feeCost = this.safeString(trade, askOrBid + '_fee');
|
|
794
|
+
if (feeCost !== undefined) {
|
|
795
|
+
fee = {
|
|
796
|
+
'currency': market['quote'],
|
|
797
|
+
'cost': feeCost,
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
return this.safeTrade({
|
|
801
|
+
'id': id,
|
|
802
|
+
'info': trade,
|
|
803
|
+
'order': orderId,
|
|
804
|
+
'timestamp': timestamp,
|
|
805
|
+
'datetime': this.iso8601(timestamp),
|
|
806
|
+
'symbol': market['symbol'],
|
|
807
|
+
'type': undefined,
|
|
808
|
+
'side': side,
|
|
809
|
+
'takerOrMaker': undefined,
|
|
810
|
+
'price': price,
|
|
811
|
+
'amount': amount,
|
|
812
|
+
'cost': cost,
|
|
813
|
+
'fee': fee,
|
|
814
|
+
}, market);
|
|
815
|
+
}
|
|
816
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
817
|
+
/**
|
|
818
|
+
* @method
|
|
819
|
+
* @name upbit#fetchTrades
|
|
820
|
+
* @see https://docs.upbit.com/reference/%EC%B5%9C%EA%B7%BC-%EC%B2%B4%EA%B2%B0-%EB%82%B4%EC%97%AD
|
|
821
|
+
* @description get the list of most recent trades for a particular symbol
|
|
822
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
823
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
824
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
825
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
826
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
827
|
+
*/
|
|
828
|
+
await this.loadMarkets();
|
|
829
|
+
const market = this.market(symbol);
|
|
830
|
+
if (limit === undefined) {
|
|
831
|
+
limit = 200;
|
|
832
|
+
}
|
|
833
|
+
const request = {
|
|
834
|
+
'market': market['id'],
|
|
835
|
+
'count': limit,
|
|
836
|
+
};
|
|
837
|
+
const response = await this.publicGetTradesTicks(this.extend(request, params));
|
|
838
|
+
//
|
|
839
|
+
// [ { market: "BTC-ETH",
|
|
840
|
+
// "trade_date_utc": "2018-11-22",
|
|
841
|
+
// "trade_time_utc": "13:55:24",
|
|
842
|
+
// "timestamp": 1542894924397,
|
|
843
|
+
// "trade_price": 0.02914289,
|
|
844
|
+
// "trade_volume": 0.20074397,
|
|
845
|
+
// "prev_closing_price": 0.02966,
|
|
846
|
+
// "change_price": -0.00051711,
|
|
847
|
+
// "ask_bid": "ASK",
|
|
848
|
+
// "sequential_id": 15428949259430000 },
|
|
849
|
+
// { market: "BTC-ETH",
|
|
850
|
+
// "trade_date_utc": "2018-11-22",
|
|
851
|
+
// "trade_time_utc": "13:03:10",
|
|
852
|
+
// "timestamp": 1542891790123,
|
|
853
|
+
// "trade_price": 0.02917,
|
|
854
|
+
// "trade_volume": 7.392,
|
|
855
|
+
// "prev_closing_price": 0.02966,
|
|
856
|
+
// "change_price": -0.00049,
|
|
857
|
+
// "ask_bid": "ASK",
|
|
858
|
+
// "sequential_id": 15428917910540000 } ]
|
|
859
|
+
//
|
|
860
|
+
return this.parseTrades(response, market, since, limit);
|
|
861
|
+
}
|
|
862
|
+
async fetchTradingFee(symbol, params = {}) {
|
|
863
|
+
/**
|
|
864
|
+
* @method
|
|
865
|
+
* @name upbit#fetchTradingFee
|
|
866
|
+
* @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EA%B0%80%EB%8A%A5-%EC%A0%95%EB%B3%B4
|
|
867
|
+
* @description fetch the trading fees for a market
|
|
868
|
+
* @param {string} symbol unified market symbol
|
|
869
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
870
|
+
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
871
|
+
*/
|
|
872
|
+
await this.loadMarkets();
|
|
873
|
+
const market = this.market(symbol);
|
|
874
|
+
const request = {
|
|
875
|
+
'market': market['id'],
|
|
876
|
+
};
|
|
877
|
+
const response = await this.privateGetOrdersChance(this.extend(request, params));
|
|
878
|
+
//
|
|
879
|
+
// {
|
|
880
|
+
// "bid_fee": "0.0005",
|
|
881
|
+
// "ask_fee": "0.0005",
|
|
882
|
+
// "maker_bid_fee": "0.0005",
|
|
883
|
+
// "maker_ask_fee": "0.0005",
|
|
884
|
+
// "market": {
|
|
885
|
+
// "id": "KRW-BTC",
|
|
886
|
+
// "name": "BTC/KRW",
|
|
887
|
+
// "order_types": [ "limit" ],
|
|
888
|
+
// "order_sides": [ "ask", "bid" ],
|
|
889
|
+
// "bid": { "currency": "KRW", "price_unit": null, "min_total": 5000 },
|
|
890
|
+
// "ask": { "currency": "BTC", "price_unit": null, "min_total": 5000 },
|
|
891
|
+
// "max_total": "1000000000.0",
|
|
892
|
+
// "state": "active"
|
|
893
|
+
// },
|
|
894
|
+
// "bid_account": {
|
|
895
|
+
// "currency": "KRW",
|
|
896
|
+
// "balance": "0.34202414",
|
|
897
|
+
// "locked": "4999.99999922",
|
|
898
|
+
// "avg_buy_price": "0",
|
|
899
|
+
// "avg_buy_price_modified": true,
|
|
900
|
+
// "unit_currency": "KRW"
|
|
901
|
+
// },
|
|
902
|
+
// "ask_account": {
|
|
903
|
+
// "currency": "BTC",
|
|
904
|
+
// "balance": "0.00048",
|
|
905
|
+
// "locked": "0.0",
|
|
906
|
+
// "avg_buy_price": "20870000",
|
|
907
|
+
// "avg_buy_price_modified": false,
|
|
908
|
+
// "unit_currency": "KRW"
|
|
909
|
+
// }
|
|
910
|
+
// }
|
|
911
|
+
//
|
|
912
|
+
const askFee = this.safeString(response, 'ask_fee');
|
|
913
|
+
const bidFee = this.safeString(response, 'bid_fee');
|
|
914
|
+
const taker = Precise["default"].stringMax(askFee, bidFee);
|
|
915
|
+
const makerAskFee = this.safeString(response, 'maker_ask_fee');
|
|
916
|
+
const makerBidFee = this.safeString(response, 'maker_bid_fee');
|
|
917
|
+
const maker = Precise["default"].stringMax(makerAskFee, makerBidFee);
|
|
918
|
+
return {
|
|
919
|
+
'info': response,
|
|
920
|
+
'symbol': symbol,
|
|
921
|
+
'maker': this.parseNumber(maker),
|
|
922
|
+
'taker': this.parseNumber(taker),
|
|
923
|
+
'percentage': true,
|
|
924
|
+
'tierBased': false,
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
928
|
+
//
|
|
929
|
+
// {
|
|
930
|
+
// "market": "BTC-ETH",
|
|
931
|
+
// "candle_date_time_utc": "2018-11-22T13:47:00",
|
|
932
|
+
// "candle_date_time_kst": "2018-11-22T22:47:00",
|
|
933
|
+
// "opening_price": 0.02915963,
|
|
934
|
+
// "high_price": 0.02915963,
|
|
935
|
+
// "low_price": 0.02915448,
|
|
936
|
+
// "trade_price": 0.02915448,
|
|
937
|
+
// "timestamp": 1542894473674,
|
|
938
|
+
// "candle_acc_trade_price": 0.0981629437535248,
|
|
939
|
+
// "candle_acc_trade_volume": 3.36693173,
|
|
940
|
+
// "unit": 1
|
|
941
|
+
// }
|
|
942
|
+
//
|
|
943
|
+
return [
|
|
944
|
+
this.parse8601(this.safeString(ohlcv, 'candle_date_time_utc')),
|
|
945
|
+
this.safeNumber(ohlcv, 'opening_price'),
|
|
946
|
+
this.safeNumber(ohlcv, 'high_price'),
|
|
947
|
+
this.safeNumber(ohlcv, 'low_price'),
|
|
948
|
+
this.safeNumber(ohlcv, 'trade_price'),
|
|
949
|
+
this.safeNumber(ohlcv, 'candle_acc_trade_volume'), // base volume
|
|
950
|
+
];
|
|
951
|
+
}
|
|
952
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
953
|
+
/**
|
|
954
|
+
* @method
|
|
955
|
+
* @name upbit#fetchOHLCV
|
|
956
|
+
* @see https://docs.upbit.com/reference/%EB%B6%84minute-%EC%BA%94%EB%93%A4-1
|
|
957
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
958
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
959
|
+
* @param {string} timeframe the length of time each candle represents
|
|
960
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
961
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
962
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
963
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
964
|
+
*/
|
|
965
|
+
await this.loadMarkets();
|
|
966
|
+
const market = this.market(symbol);
|
|
967
|
+
const timeframePeriod = this.parseTimeframe(timeframe);
|
|
968
|
+
const timeframeValue = this.safeString(this.timeframes, timeframe, timeframe);
|
|
969
|
+
if (limit === undefined) {
|
|
970
|
+
limit = 200;
|
|
971
|
+
}
|
|
972
|
+
const request = {
|
|
973
|
+
'market': market['id'],
|
|
974
|
+
'timeframe': timeframeValue,
|
|
975
|
+
'count': limit,
|
|
976
|
+
};
|
|
977
|
+
let response = undefined;
|
|
978
|
+
if (since !== undefined) {
|
|
979
|
+
// convert `since` to `to` value
|
|
980
|
+
request['to'] = this.iso8601(this.sum(since, timeframePeriod * limit * 1000));
|
|
981
|
+
}
|
|
982
|
+
if (timeframeValue === 'minutes') {
|
|
983
|
+
const numMinutes = Math.round(timeframePeriod / 60);
|
|
984
|
+
request['unit'] = numMinutes;
|
|
985
|
+
response = await this.publicGetCandlesTimeframeUnit(this.extend(request, params));
|
|
986
|
+
}
|
|
987
|
+
else {
|
|
988
|
+
response = await this.publicGetCandlesTimeframe(this.extend(request, params));
|
|
989
|
+
}
|
|
990
|
+
//
|
|
991
|
+
// [
|
|
992
|
+
// {
|
|
993
|
+
// "market": "BTC-ETH",
|
|
994
|
+
// "candle_date_time_utc": "2018-11-22T13:47:00",
|
|
995
|
+
// "candle_date_time_kst": "2018-11-22T22:47:00",
|
|
996
|
+
// "opening_price": 0.02915963,
|
|
997
|
+
// "high_price": 0.02915963,
|
|
998
|
+
// "low_price": 0.02915448,
|
|
999
|
+
// "trade_price": 0.02915448,
|
|
1000
|
+
// "timestamp": 1542894473674,
|
|
1001
|
+
// "candle_acc_trade_price": 0.0981629437535248,
|
|
1002
|
+
// "candle_acc_trade_volume": 3.36693173,
|
|
1003
|
+
// "unit": 1
|
|
1004
|
+
// },
|
|
1005
|
+
// {
|
|
1006
|
+
// "market": "BTC-ETH",
|
|
1007
|
+
// "candle_date_time_utc": "2018-11-22T10:06:00",
|
|
1008
|
+
// "candle_date_time_kst": "2018-11-22T19:06:00",
|
|
1009
|
+
// "opening_price": 0.0294,
|
|
1010
|
+
// "high_price": 0.02940882,
|
|
1011
|
+
// "low_price": 0.02934283,
|
|
1012
|
+
// "trade_price": 0.02937354,
|
|
1013
|
+
// "timestamp": 1542881219276,
|
|
1014
|
+
// "candle_acc_trade_price": 0.0762597110943884,
|
|
1015
|
+
// "candle_acc_trade_volume": 2.5949617,
|
|
1016
|
+
// "unit": 1
|
|
1017
|
+
// }
|
|
1018
|
+
// ]
|
|
1019
|
+
//
|
|
1020
|
+
return this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
1021
|
+
}
|
|
1022
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1023
|
+
/**
|
|
1024
|
+
* @method
|
|
1025
|
+
* @name upbit#createOrder
|
|
1026
|
+
* @description create a trade order
|
|
1027
|
+
* @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8%ED%95%98%EA%B8%B0
|
|
1028
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1029
|
+
* @param {string} type 'market' or 'limit'
|
|
1030
|
+
* @param {string} side 'buy' or 'sell'
|
|
1031
|
+
* @param {float} amount how much you want to trade in units of the base currency
|
|
1032
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1033
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1034
|
+
* @param {float} [params.cost] for market buy orders, the quote quantity that can be used as an alternative for the amount
|
|
1035
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1036
|
+
*/
|
|
1037
|
+
await this.loadMarkets();
|
|
1038
|
+
const market = this.market(symbol);
|
|
1039
|
+
let orderSide = undefined;
|
|
1040
|
+
if (side === 'buy') {
|
|
1041
|
+
orderSide = 'bid';
|
|
1042
|
+
}
|
|
1043
|
+
else if (side === 'sell') {
|
|
1044
|
+
orderSide = 'ask';
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() allows buy or sell side only!');
|
|
1048
|
+
}
|
|
1049
|
+
const request = {
|
|
1050
|
+
'market': market['id'],
|
|
1051
|
+
'side': orderSide,
|
|
1052
|
+
};
|
|
1053
|
+
if (type === 'limit') {
|
|
1054
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
1055
|
+
}
|
|
1056
|
+
if ((type === 'market') && (side === 'buy')) {
|
|
1057
|
+
// for market buy it requires the amount of quote currency to spend
|
|
1058
|
+
let quoteAmount = undefined;
|
|
1059
|
+
let createMarketBuyOrderRequiresPrice = true;
|
|
1060
|
+
[createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
|
|
1061
|
+
const cost = this.safeNumber(params, 'cost');
|
|
1062
|
+
params = this.omit(params, 'cost');
|
|
1063
|
+
if (cost !== undefined) {
|
|
1064
|
+
quoteAmount = this.costToPrecision(symbol, cost);
|
|
1065
|
+
}
|
|
1066
|
+
else if (createMarketBuyOrderRequiresPrice) {
|
|
1067
|
+
if (price === undefined) {
|
|
1068
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend (quote quantity) in the amount argument');
|
|
1069
|
+
}
|
|
1070
|
+
else {
|
|
1071
|
+
const amountString = this.numberToString(amount);
|
|
1072
|
+
const priceString = this.numberToString(price);
|
|
1073
|
+
const costRequest = Precise["default"].stringMul(amountString, priceString);
|
|
1074
|
+
quoteAmount = this.costToPrecision(symbol, costRequest);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
else {
|
|
1078
|
+
quoteAmount = this.costToPrecision(symbol, amount);
|
|
1079
|
+
}
|
|
1080
|
+
request['ord_type'] = 'price';
|
|
1081
|
+
request['price'] = quoteAmount;
|
|
1082
|
+
}
|
|
1083
|
+
else {
|
|
1084
|
+
request['ord_type'] = type;
|
|
1085
|
+
request['volume'] = this.amountToPrecision(symbol, amount);
|
|
1086
|
+
}
|
|
1087
|
+
const clientOrderId = this.safeString2(params, 'clientOrderId', 'identifier');
|
|
1088
|
+
if (clientOrderId !== undefined) {
|
|
1089
|
+
request['identifier'] = clientOrderId;
|
|
1090
|
+
}
|
|
1091
|
+
params = this.omit(params, ['clientOrderId', 'identifier']);
|
|
1092
|
+
const response = await this.privatePostOrders(this.extend(request, params));
|
|
1093
|
+
//
|
|
1094
|
+
// {
|
|
1095
|
+
// "uuid": "cdd92199-2897-4e14-9448-f923320408ad",
|
|
1096
|
+
// "side": "bid",
|
|
1097
|
+
// "ord_type": "limit",
|
|
1098
|
+
// "price": "100.0",
|
|
1099
|
+
// "avg_price": "0.0",
|
|
1100
|
+
// "state": "wait",
|
|
1101
|
+
// "market": "KRW-BTC",
|
|
1102
|
+
// "created_at": "2018-04-10T15:42:23+09:00",
|
|
1103
|
+
// "volume": "0.01",
|
|
1104
|
+
// "remaining_volume": "0.01",
|
|
1105
|
+
// "reserved_fee": "0.0015",
|
|
1106
|
+
// "remaining_fee": "0.0015",
|
|
1107
|
+
// "paid_fee": "0.0",
|
|
1108
|
+
// "locked": "1.0015",
|
|
1109
|
+
// "executed_volume": "0.0",
|
|
1110
|
+
// "trades_count": 0
|
|
1111
|
+
// }
|
|
1112
|
+
//
|
|
1113
|
+
return this.parseOrder(response);
|
|
1114
|
+
}
|
|
1115
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1116
|
+
/**
|
|
1117
|
+
* @method
|
|
1118
|
+
* @name upbit#cancelOrder
|
|
1119
|
+
* @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EC%B7%A8%EC%86%8C
|
|
1120
|
+
* @description cancels an open order
|
|
1121
|
+
* @param {string} id order id
|
|
1122
|
+
* @param {string} symbol not used by upbit cancelOrder ()
|
|
1123
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1124
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1125
|
+
*/
|
|
1126
|
+
await this.loadMarkets();
|
|
1127
|
+
const request = {
|
|
1128
|
+
'uuid': id,
|
|
1129
|
+
};
|
|
1130
|
+
const response = await this.privateDeleteOrder(this.extend(request, params));
|
|
1131
|
+
//
|
|
1132
|
+
// {
|
|
1133
|
+
// "uuid": "cdd92199-2897-4e14-9448-f923320408ad",
|
|
1134
|
+
// "side": "bid",
|
|
1135
|
+
// "ord_type": "limit",
|
|
1136
|
+
// "price": "100.0",
|
|
1137
|
+
// "state": "wait",
|
|
1138
|
+
// "market": "KRW-BTC",
|
|
1139
|
+
// "created_at": "2018-04-10T15:42:23+09:00",
|
|
1140
|
+
// "volume": "0.01",
|
|
1141
|
+
// "remaining_volume": "0.01",
|
|
1142
|
+
// "reserved_fee": "0.0015",
|
|
1143
|
+
// "remaining_fee": "0.0015",
|
|
1144
|
+
// "paid_fee": "0.0",
|
|
1145
|
+
// "locked": "1.0015",
|
|
1146
|
+
// "executed_volume": "0.0",
|
|
1147
|
+
// "trades_count": 0
|
|
1148
|
+
// }
|
|
1149
|
+
//
|
|
1150
|
+
return this.parseOrder(response);
|
|
1151
|
+
}
|
|
1152
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1153
|
+
/**
|
|
1154
|
+
* @method
|
|
1155
|
+
* @name upbit#fetchDeposits
|
|
1156
|
+
* @see https://docs.upbit.com/reference/%EC%9E%85%EA%B8%88-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%9A%8C
|
|
1157
|
+
* @description fetch all deposits made to an account
|
|
1158
|
+
* @param {string} code unified currency code
|
|
1159
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
1160
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
1161
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1162
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1163
|
+
*/
|
|
1164
|
+
await this.loadMarkets();
|
|
1165
|
+
const request = {
|
|
1166
|
+
// 'page': 1,
|
|
1167
|
+
// 'order_by': 'asc', // 'desc'
|
|
1168
|
+
};
|
|
1169
|
+
let currency = undefined;
|
|
1170
|
+
if (code !== undefined) {
|
|
1171
|
+
currency = this.currency(code);
|
|
1172
|
+
request['currency'] = currency['id'];
|
|
1173
|
+
}
|
|
1174
|
+
if (limit !== undefined) {
|
|
1175
|
+
request['limit'] = limit; // default is 100
|
|
1176
|
+
}
|
|
1177
|
+
const response = await this.privateGetDeposits(this.extend(request, params));
|
|
1178
|
+
//
|
|
1179
|
+
// [
|
|
1180
|
+
// {
|
|
1181
|
+
// "type": "deposit",
|
|
1182
|
+
// "uuid": "94332e99-3a87-4a35-ad98-28b0c969f830",
|
|
1183
|
+
// "currency": "KRW",
|
|
1184
|
+
// "txid": "9e37c537-6849-4c8b-a134-57313f5dfc5a",
|
|
1185
|
+
// "state": "ACCEPTED",
|
|
1186
|
+
// "created_at": "2017-12-08T15:38:02+09:00",
|
|
1187
|
+
// "done_at": "2017-12-08T15:38:02+09:00",
|
|
1188
|
+
// "amount": "100000.0",
|
|
1189
|
+
// "fee": "0.0"
|
|
1190
|
+
// },
|
|
1191
|
+
// ...,
|
|
1192
|
+
// ]
|
|
1193
|
+
//
|
|
1194
|
+
return this.parseTransactions(response, currency, since, limit);
|
|
1195
|
+
}
|
|
1196
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1197
|
+
/**
|
|
1198
|
+
* @method
|
|
1199
|
+
* @name upbit#fetchWithdrawals
|
|
1200
|
+
* @see https://docs.upbit.com/reference/%EC%A0%84%EC%B2%B4-%EC%B6%9C%EA%B8%88-%EC%A1%B0%ED%9A%8C
|
|
1201
|
+
* @description fetch all withdrawals made from an account
|
|
1202
|
+
* @param {string} code unified currency code
|
|
1203
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
1204
|
+
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
1205
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1206
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1207
|
+
*/
|
|
1208
|
+
await this.loadMarkets();
|
|
1209
|
+
const request = {
|
|
1210
|
+
// 'state': 'submitting', // 'submitted', 'almost_accepted', 'rejected', 'accepted', 'processing', 'done', 'canceled'
|
|
1211
|
+
};
|
|
1212
|
+
let currency = undefined;
|
|
1213
|
+
if (code !== undefined) {
|
|
1214
|
+
currency = this.currency(code);
|
|
1215
|
+
request['currency'] = currency['id'];
|
|
1216
|
+
}
|
|
1217
|
+
if (limit !== undefined) {
|
|
1218
|
+
request['limit'] = limit; // default is 100
|
|
1219
|
+
}
|
|
1220
|
+
const response = await this.privateGetWithdraws(this.extend(request, params));
|
|
1221
|
+
//
|
|
1222
|
+
// [
|
|
1223
|
+
// {
|
|
1224
|
+
// "type": "withdraw",
|
|
1225
|
+
// "uuid": "9f432943-54e0-40b7-825f-b6fec8b42b79",
|
|
1226
|
+
// "currency": "BTC",
|
|
1227
|
+
// "txid": null,
|
|
1228
|
+
// "state": "processing",
|
|
1229
|
+
// "created_at": "2018-04-13T11:24:01+09:00",
|
|
1230
|
+
// "done_at": null,
|
|
1231
|
+
// "amount": "0.01",
|
|
1232
|
+
// "fee": "0.0",
|
|
1233
|
+
// "krw_amount": "80420.0"
|
|
1234
|
+
// },
|
|
1235
|
+
// ...,
|
|
1236
|
+
// ]
|
|
1237
|
+
//
|
|
1238
|
+
return this.parseTransactions(response, currency, since, limit);
|
|
1239
|
+
}
|
|
1240
|
+
parseTransactionStatus(status) {
|
|
1241
|
+
const statuses = {
|
|
1242
|
+
'submitting': 'pending',
|
|
1243
|
+
'submitted': 'pending',
|
|
1244
|
+
'almost_accepted': 'pending',
|
|
1245
|
+
'rejected': 'failed',
|
|
1246
|
+
'accepted': 'pending',
|
|
1247
|
+
'processing': 'pending',
|
|
1248
|
+
'done': 'ok',
|
|
1249
|
+
'canceled': 'canceled', // 취소됨
|
|
1250
|
+
};
|
|
1251
|
+
return this.safeString(statuses, status, status);
|
|
1252
|
+
}
|
|
1253
|
+
parseTransaction(transaction, currency = undefined) {
|
|
1254
|
+
//
|
|
1255
|
+
// fetchDeposits
|
|
1256
|
+
//
|
|
1257
|
+
// {
|
|
1258
|
+
// "type": "deposit",
|
|
1259
|
+
// "uuid": "94332e99-3a87-4a35-ad98-28b0c969f830",
|
|
1260
|
+
// "currency": "KRW",
|
|
1261
|
+
// "txid": "9e37c537-6849-4c8b-a134-57313f5dfc5a",
|
|
1262
|
+
// "state": "ACCEPTED",
|
|
1263
|
+
// "created_at": "2017-12-08T15:38:02+09:00",
|
|
1264
|
+
// "done_at": "2017-12-08T15:38:02+09:00",
|
|
1265
|
+
// "amount": "100000.0",
|
|
1266
|
+
// "fee": "0.0"
|
|
1267
|
+
// }
|
|
1268
|
+
//
|
|
1269
|
+
// fetchWithdrawals
|
|
1270
|
+
//
|
|
1271
|
+
// {
|
|
1272
|
+
// "type": "withdraw",
|
|
1273
|
+
// "uuid": "9f432943-54e0-40b7-825f-b6fec8b42b79",
|
|
1274
|
+
// "currency": "BTC",
|
|
1275
|
+
// "txid": "cd81e9b45df8da29f936836e58c907a106057e454a45767a7b06fcb19b966bba",
|
|
1276
|
+
// "state": "processing",
|
|
1277
|
+
// "created_at": "2018-04-13T11:24:01+09:00",
|
|
1278
|
+
// "done_at": null,
|
|
1279
|
+
// "amount": "0.01",
|
|
1280
|
+
// "fee": "0.0",
|
|
1281
|
+
// "krw_amount": "80420.0"
|
|
1282
|
+
// }
|
|
1283
|
+
//
|
|
1284
|
+
const id = this.safeString(transaction, 'uuid');
|
|
1285
|
+
const amount = this.safeNumber(transaction, 'amount');
|
|
1286
|
+
const address = undefined; // not present in the data structure received from the exchange
|
|
1287
|
+
const tag = undefined; // not present in the data structure received from the exchange
|
|
1288
|
+
const txid = this.safeString(transaction, 'txid');
|
|
1289
|
+
const updatedRaw = this.safeString(transaction, 'done_at');
|
|
1290
|
+
const updated = this.parse8601(updatedRaw);
|
|
1291
|
+
const timestamp = this.parse8601(this.safeString(transaction, 'created_at', updatedRaw));
|
|
1292
|
+
let type = this.safeString(transaction, 'type');
|
|
1293
|
+
if (type === 'withdraw') {
|
|
1294
|
+
type = 'withdrawal';
|
|
1295
|
+
}
|
|
1296
|
+
const currencyId = this.safeString(transaction, 'currency');
|
|
1297
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1298
|
+
const status = this.parseTransactionStatus(this.safeStringLower(transaction, 'state'));
|
|
1299
|
+
const feeCost = this.safeNumber(transaction, 'fee');
|
|
1300
|
+
return {
|
|
1301
|
+
'info': transaction,
|
|
1302
|
+
'id': id,
|
|
1303
|
+
'currency': code,
|
|
1304
|
+
'amount': amount,
|
|
1305
|
+
'network': undefined,
|
|
1306
|
+
'address': address,
|
|
1307
|
+
'addressTo': undefined,
|
|
1308
|
+
'addressFrom': undefined,
|
|
1309
|
+
'tag': tag,
|
|
1310
|
+
'tagTo': undefined,
|
|
1311
|
+
'tagFrom': undefined,
|
|
1312
|
+
'status': status,
|
|
1313
|
+
'type': type,
|
|
1314
|
+
'updated': updated,
|
|
1315
|
+
'txid': txid,
|
|
1316
|
+
'timestamp': timestamp,
|
|
1317
|
+
'datetime': this.iso8601(timestamp),
|
|
1318
|
+
'internal': undefined,
|
|
1319
|
+
'comment': undefined,
|
|
1320
|
+
'fee': {
|
|
1321
|
+
'currency': code,
|
|
1322
|
+
'cost': feeCost,
|
|
1323
|
+
},
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
parseOrderStatus(status) {
|
|
1327
|
+
const statuses = {
|
|
1328
|
+
'wait': 'open',
|
|
1329
|
+
'done': 'closed',
|
|
1330
|
+
'cancel': 'canceled',
|
|
1331
|
+
};
|
|
1332
|
+
return this.safeString(statuses, status, status);
|
|
1333
|
+
}
|
|
1334
|
+
parseOrder(order, market = undefined) {
|
|
1335
|
+
//
|
|
1336
|
+
// {
|
|
1337
|
+
// "uuid": "a08f09b1-1718-42e2-9358-f0e5e083d3ee",
|
|
1338
|
+
// "side": "bid",
|
|
1339
|
+
// "ord_type": "limit",
|
|
1340
|
+
// "price": "17417000.0",
|
|
1341
|
+
// "state": "done",
|
|
1342
|
+
// "market": "KRW-BTC",
|
|
1343
|
+
// "created_at": "2018-04-05T14:09:14+09:00",
|
|
1344
|
+
// "volume": "1.0",
|
|
1345
|
+
// "remaining_volume": "0.0",
|
|
1346
|
+
// "reserved_fee": "26125.5",
|
|
1347
|
+
// "remaining_fee": "25974.0",
|
|
1348
|
+
// "paid_fee": "151.5",
|
|
1349
|
+
// "locked": "17341974.0",
|
|
1350
|
+
// "executed_volume": "1.0",
|
|
1351
|
+
// "trades_count": 2,
|
|
1352
|
+
// "trades": [
|
|
1353
|
+
// {
|
|
1354
|
+
// "market": "KRW-BTC",
|
|
1355
|
+
// "uuid": "78162304-1a4d-4524-b9e6-c9a9e14d76c3",
|
|
1356
|
+
// "price": "101000.0",
|
|
1357
|
+
// "volume": "0.77368323",
|
|
1358
|
+
// "funds": "78142.00623",
|
|
1359
|
+
// "ask_fee": "117.213009345",
|
|
1360
|
+
// "bid_fee": "117.213009345",
|
|
1361
|
+
// "created_at": "2018-04-05T14:09:15+09:00",
|
|
1362
|
+
// "side": "bid",
|
|
1363
|
+
// },
|
|
1364
|
+
// {
|
|
1365
|
+
// "market": "KRW-BTC",
|
|
1366
|
+
// "uuid": "f73da467-c42f-407d-92fa-e10d86450a20",
|
|
1367
|
+
// "price": "101000.0",
|
|
1368
|
+
// "volume": "0.22631677",
|
|
1369
|
+
// "funds": "22857.99377",
|
|
1370
|
+
// "ask_fee": "34.286990655", // missing in market orders
|
|
1371
|
+
// "bid_fee": "34.286990655", // missing in market orders
|
|
1372
|
+
// "created_at": "2018-04-05T14:09:15+09:00", // missing in market orders
|
|
1373
|
+
// "side": "bid",
|
|
1374
|
+
// },
|
|
1375
|
+
// ],
|
|
1376
|
+
// }
|
|
1377
|
+
//
|
|
1378
|
+
const id = this.safeString(order, 'uuid');
|
|
1379
|
+
let side = this.safeString(order, 'side');
|
|
1380
|
+
if (side === 'bid') {
|
|
1381
|
+
side = 'buy';
|
|
1382
|
+
}
|
|
1383
|
+
else {
|
|
1384
|
+
side = 'sell';
|
|
1385
|
+
}
|
|
1386
|
+
let type = this.safeString(order, 'ord_type');
|
|
1387
|
+
const timestamp = this.parse8601(this.safeString(order, 'created_at'));
|
|
1388
|
+
const status = this.parseOrderStatus(this.safeString(order, 'state'));
|
|
1389
|
+
let lastTradeTimestamp = undefined;
|
|
1390
|
+
let price = this.safeString(order, 'price');
|
|
1391
|
+
const amount = this.safeString(order, 'volume');
|
|
1392
|
+
const remaining = this.safeString(order, 'remaining_volume');
|
|
1393
|
+
const filled = this.safeString(order, 'executed_volume');
|
|
1394
|
+
let cost = undefined;
|
|
1395
|
+
if (type === 'price') {
|
|
1396
|
+
type = 'market';
|
|
1397
|
+
cost = price;
|
|
1398
|
+
price = undefined;
|
|
1399
|
+
}
|
|
1400
|
+
let average = undefined;
|
|
1401
|
+
let fee = undefined;
|
|
1402
|
+
let feeCost = this.safeString(order, 'paid_fee');
|
|
1403
|
+
const marketId = this.safeString(order, 'market');
|
|
1404
|
+
market = this.safeMarket(marketId, market);
|
|
1405
|
+
let trades = this.safeValue(order, 'trades', []);
|
|
1406
|
+
trades = this.parseTrades(trades, market, undefined, undefined, {
|
|
1407
|
+
'order': id,
|
|
1408
|
+
'type': type,
|
|
1409
|
+
});
|
|
1410
|
+
const numTrades = trades.length;
|
|
1411
|
+
if (numTrades > 0) {
|
|
1412
|
+
// the timestamp in fetchOrder trades is missing
|
|
1413
|
+
lastTradeTimestamp = trades[numTrades - 1]['timestamp'];
|
|
1414
|
+
let getFeesFromTrades = false;
|
|
1415
|
+
if (feeCost === undefined) {
|
|
1416
|
+
getFeesFromTrades = true;
|
|
1417
|
+
feeCost = '0';
|
|
1418
|
+
}
|
|
1419
|
+
cost = '0';
|
|
1420
|
+
for (let i = 0; i < numTrades; i++) {
|
|
1421
|
+
const trade = trades[i];
|
|
1422
|
+
cost = Precise["default"].stringAdd(cost, this.safeString(trade, 'cost'));
|
|
1423
|
+
if (getFeesFromTrades) {
|
|
1424
|
+
const tradeFee = this.safeValue(trades[i], 'fee', {});
|
|
1425
|
+
const tradeFeeCost = this.safeString(tradeFee, 'cost');
|
|
1426
|
+
if (tradeFeeCost !== undefined) {
|
|
1427
|
+
feeCost = Precise["default"].stringAdd(feeCost, tradeFeeCost);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
average = Precise["default"].stringDiv(cost, filled);
|
|
1432
|
+
}
|
|
1433
|
+
if (feeCost !== undefined) {
|
|
1434
|
+
fee = {
|
|
1435
|
+
'currency': market['quote'],
|
|
1436
|
+
'cost': feeCost,
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
return this.safeOrder({
|
|
1440
|
+
'info': order,
|
|
1441
|
+
'id': id,
|
|
1442
|
+
'clientOrderId': undefined,
|
|
1443
|
+
'timestamp': timestamp,
|
|
1444
|
+
'datetime': this.iso8601(timestamp),
|
|
1445
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
|
1446
|
+
'symbol': market['symbol'],
|
|
1447
|
+
'type': type,
|
|
1448
|
+
'timeInForce': undefined,
|
|
1449
|
+
'postOnly': undefined,
|
|
1450
|
+
'side': side,
|
|
1451
|
+
'price': price,
|
|
1452
|
+
'stopPrice': undefined,
|
|
1453
|
+
'triggerPrice': undefined,
|
|
1454
|
+
'cost': this.parseNumber(cost),
|
|
1455
|
+
'average': this.parseNumber(average),
|
|
1456
|
+
'amount': amount,
|
|
1457
|
+
'filled': filled,
|
|
1458
|
+
'remaining': remaining,
|
|
1459
|
+
'status': status,
|
|
1460
|
+
'fee': fee,
|
|
1461
|
+
'trades': trades,
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
async fetchOrdersByState(state, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1465
|
+
await this.loadMarkets();
|
|
1466
|
+
const request = {
|
|
1467
|
+
// 'market': this.marketId (symbol),
|
|
1468
|
+
'state': state,
|
|
1469
|
+
// 'page': 1,
|
|
1470
|
+
// 'order_by': 'asc',
|
|
1471
|
+
};
|
|
1472
|
+
let market = undefined;
|
|
1473
|
+
if (symbol !== undefined) {
|
|
1474
|
+
market = this.market(symbol);
|
|
1475
|
+
request['market'] = market['id'];
|
|
1476
|
+
}
|
|
1477
|
+
const response = await this.privateGetOrders(this.extend(request, params));
|
|
1478
|
+
//
|
|
1479
|
+
// [
|
|
1480
|
+
// {
|
|
1481
|
+
// "uuid": "a08f09b1-1718-42e2-9358-f0e5e083d3ee",
|
|
1482
|
+
// "side": "bid",
|
|
1483
|
+
// "ord_type": "limit",
|
|
1484
|
+
// "price": "17417000.0",
|
|
1485
|
+
// "state": "done",
|
|
1486
|
+
// "market": "KRW-BTC",
|
|
1487
|
+
// "created_at": "2018-04-05T14:09:14+09:00",
|
|
1488
|
+
// "volume": "1.0",
|
|
1489
|
+
// "remaining_volume": "0.0",
|
|
1490
|
+
// "reserved_fee": "26125.5",
|
|
1491
|
+
// "remaining_fee": "25974.0",
|
|
1492
|
+
// "paid_fee": "151.5",
|
|
1493
|
+
// "locked": "17341974.0",
|
|
1494
|
+
// "executed_volume": "1.0",
|
|
1495
|
+
// "trades_count":2
|
|
1496
|
+
// },
|
|
1497
|
+
// ]
|
|
1498
|
+
//
|
|
1499
|
+
return this.parseOrders(response, market, since, limit);
|
|
1500
|
+
}
|
|
1501
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1502
|
+
/**
|
|
1503
|
+
* @method
|
|
1504
|
+
* @name upbit#fetchOpenOrders
|
|
1505
|
+
* @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%9A%8C
|
|
1506
|
+
* @description fetch all unfilled currently open orders
|
|
1507
|
+
* @param {string} symbol unified market symbol
|
|
1508
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
1509
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
1510
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1511
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1512
|
+
*/
|
|
1513
|
+
return await this.fetchOrdersByState('wait', symbol, since, limit, params);
|
|
1514
|
+
}
|
|
1515
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1516
|
+
/**
|
|
1517
|
+
* @method
|
|
1518
|
+
* @name upbit#fetchClosedOrders
|
|
1519
|
+
* @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%9A%8C
|
|
1520
|
+
* @description fetches information on multiple closed orders made by the user
|
|
1521
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1522
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1523
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1524
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1525
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1526
|
+
*/
|
|
1527
|
+
return await this.fetchOrdersByState('done', symbol, since, limit, params);
|
|
1528
|
+
}
|
|
1529
|
+
async fetchCanceledOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1530
|
+
/**
|
|
1531
|
+
* @method
|
|
1532
|
+
* @name upbit#fetchCanceledOrders
|
|
1533
|
+
* @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%9A%8C
|
|
1534
|
+
* @description fetches information on multiple canceled orders made by the user
|
|
1535
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1536
|
+
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
|
1537
|
+
* @param {int} [limit] max number of orders to return, default is undefined
|
|
1538
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1539
|
+
* @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1540
|
+
*/
|
|
1541
|
+
return await this.fetchOrdersByState('cancel', symbol, since, limit, params);
|
|
1542
|
+
}
|
|
1543
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1544
|
+
/**
|
|
1545
|
+
* @method
|
|
1546
|
+
* @name upbit#fetchOrder
|
|
1547
|
+
* @see https://docs.upbit.com/reference/%EA%B0%9C%EB%B3%84-%EC%A3%BC%EB%AC%B8-%EC%A1%B0%ED%9A%8C
|
|
1548
|
+
* @description fetches information on an order made by the user
|
|
1549
|
+
* @param {string} symbol not used by upbit fetchOrder
|
|
1550
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1551
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1552
|
+
*/
|
|
1553
|
+
await this.loadMarkets();
|
|
1554
|
+
const request = {
|
|
1555
|
+
'uuid': id,
|
|
1556
|
+
};
|
|
1557
|
+
const response = await this.privateGetOrder(this.extend(request, params));
|
|
1558
|
+
//
|
|
1559
|
+
// {
|
|
1560
|
+
// "uuid": "a08f09b1-1718-42e2-9358-f0e5e083d3ee",
|
|
1561
|
+
// "side": "bid",
|
|
1562
|
+
// "ord_type": "limit",
|
|
1563
|
+
// "price": "17417000.0",
|
|
1564
|
+
// "state": "done",
|
|
1565
|
+
// "market": "KRW-BTC",
|
|
1566
|
+
// "created_at": "2018-04-05T14:09:14+09:00",
|
|
1567
|
+
// "volume": "1.0",
|
|
1568
|
+
// "remaining_volume": "0.0",
|
|
1569
|
+
// "reserved_fee": "26125.5",
|
|
1570
|
+
// "remaining_fee": "25974.0",
|
|
1571
|
+
// "paid_fee": "151.5",
|
|
1572
|
+
// "locked": "17341974.0",
|
|
1573
|
+
// "executed_volume": "1.0",
|
|
1574
|
+
// "trades_count": 2,
|
|
1575
|
+
// "trades": [
|
|
1576
|
+
// {
|
|
1577
|
+
// "market": "KRW-BTC",
|
|
1578
|
+
// "uuid": "78162304-1a4d-4524-b9e6-c9a9e14d76c3",
|
|
1579
|
+
// "price": "101000.0",
|
|
1580
|
+
// "volume": "0.77368323",
|
|
1581
|
+
// "funds": "78142.00623",
|
|
1582
|
+
// "ask_fee": "117.213009345",
|
|
1583
|
+
// "bid_fee": "117.213009345",
|
|
1584
|
+
// "created_at": "2018-04-05T14:09:15+09:00",
|
|
1585
|
+
// "side": "bid"
|
|
1586
|
+
// },
|
|
1587
|
+
// {
|
|
1588
|
+
// "market": "KRW-BTC",
|
|
1589
|
+
// "uuid": "f73da467-c42f-407d-92fa-e10d86450a20",
|
|
1590
|
+
// "price": "101000.0",
|
|
1591
|
+
// "volume": "0.22631677",
|
|
1592
|
+
// "funds": "22857.99377",
|
|
1593
|
+
// "ask_fee": "34.286990655",
|
|
1594
|
+
// "bid_fee": "34.286990655",
|
|
1595
|
+
// "created_at": "2018-04-05T14:09:15+09:00",
|
|
1596
|
+
// "side": "bid"
|
|
1597
|
+
// }
|
|
1598
|
+
// ]
|
|
1599
|
+
// }
|
|
1600
|
+
//
|
|
1601
|
+
return this.parseOrder(response);
|
|
1602
|
+
}
|
|
1603
|
+
async fetchDepositAddresses(codes = undefined, params = {}) {
|
|
1604
|
+
/**
|
|
1605
|
+
* @method
|
|
1606
|
+
* @name upbit#fetchDepositAddresses
|
|
1607
|
+
* @see https://docs.upbit.com/reference/%EC%A0%84%EC%B2%B4-%EC%9E%85%EA%B8%88-%EC%A3%BC%EC%86%8C-%EC%A1%B0%ED%9A%8C
|
|
1608
|
+
* @description fetch deposit addresses for multiple currencies and chain types
|
|
1609
|
+
* @param {string[]|undefined} codes list of unified currency codes, default is undefined
|
|
1610
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1611
|
+
* @returns {object} a list of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1612
|
+
*/
|
|
1613
|
+
await this.loadMarkets();
|
|
1614
|
+
const response = await this.privateGetDepositsCoinAddresses(params);
|
|
1615
|
+
//
|
|
1616
|
+
// [
|
|
1617
|
+
// {
|
|
1618
|
+
// "currency": "BTC",
|
|
1619
|
+
// "deposit_address": "3EusRwybuZUhVDeHL7gh3HSLmbhLcy7NqD",
|
|
1620
|
+
// "secondary_address": null
|
|
1621
|
+
// },
|
|
1622
|
+
// {
|
|
1623
|
+
// "currency": "ETH",
|
|
1624
|
+
// "deposit_address": "0x0d73e0a482b8cf568976d2e8688f4a899d29301c",
|
|
1625
|
+
// "secondary_address": null
|
|
1626
|
+
// },
|
|
1627
|
+
// {
|
|
1628
|
+
// "currency": "XRP",
|
|
1629
|
+
// "deposit_address": "rN9qNpgnBaZwqCg8CvUZRPqCcPPY7wfWep",
|
|
1630
|
+
// "secondary_address": "3057887915"
|
|
1631
|
+
// }
|
|
1632
|
+
// ]
|
|
1633
|
+
//
|
|
1634
|
+
return this.parseDepositAddresses(response, codes);
|
|
1635
|
+
}
|
|
1636
|
+
parseDepositAddress(depositAddress, currency = undefined) {
|
|
1637
|
+
//
|
|
1638
|
+
// {
|
|
1639
|
+
// "currency": "BTC",
|
|
1640
|
+
// "deposit_address": "3EusRwybuZUhVDeHL7gh3HSLmbhLcy7NqD",
|
|
1641
|
+
// "secondary_address": null
|
|
1642
|
+
// }
|
|
1643
|
+
//
|
|
1644
|
+
const address = this.safeString(depositAddress, 'deposit_address');
|
|
1645
|
+
const tag = this.safeString(depositAddress, 'secondary_address');
|
|
1646
|
+
const currencyId = this.safeString(depositAddress, 'currency');
|
|
1647
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1648
|
+
this.checkAddress(address);
|
|
1649
|
+
return {
|
|
1650
|
+
'currency': code,
|
|
1651
|
+
'address': address,
|
|
1652
|
+
'tag': tag,
|
|
1653
|
+
'network': undefined,
|
|
1654
|
+
'info': depositAddress,
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
async fetchDepositAddress(code, params = {}) {
|
|
1658
|
+
/**
|
|
1659
|
+
* @method
|
|
1660
|
+
* @name upbit#fetchDepositAddress
|
|
1661
|
+
* @see https://docs.upbit.com/reference/%EC%A0%84%EC%B2%B4-%EC%9E%85%EA%B8%88-%EC%A3%BC%EC%86%8C-%EC%A1%B0%ED%9A%8C
|
|
1662
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
1663
|
+
* @param {string} code unified currency code
|
|
1664
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
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 response = await this.privateGetDepositsCoinAddress(this.extend({
|
|
1670
|
+
'currency': currency['id'],
|
|
1671
|
+
}, params));
|
|
1672
|
+
//
|
|
1673
|
+
// {
|
|
1674
|
+
// "currency": "BTC",
|
|
1675
|
+
// "deposit_address": "3EusRwybuZUhVDeHL7gh3HSLmbhLcy7NqD",
|
|
1676
|
+
// "secondary_address": null
|
|
1677
|
+
// }
|
|
1678
|
+
//
|
|
1679
|
+
return this.parseDepositAddress(response);
|
|
1680
|
+
}
|
|
1681
|
+
async createDepositAddress(code, params = {}) {
|
|
1682
|
+
/**
|
|
1683
|
+
* @method
|
|
1684
|
+
* @name upbit#createDepositAddress
|
|
1685
|
+
* @see https://docs.upbit.com/reference/%EC%9E%85%EA%B8%88-%EC%A3%BC%EC%86%8C-%EC%83%9D%EC%84%B1-%EC%9A%94%EC%B2%AD
|
|
1686
|
+
* @description create a currency deposit address
|
|
1687
|
+
* @param {string} code unified currency code of the currency for the deposit address
|
|
1688
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1689
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1690
|
+
*/
|
|
1691
|
+
await this.loadMarkets();
|
|
1692
|
+
const currency = this.currency(code);
|
|
1693
|
+
const request = {
|
|
1694
|
+
'currency': currency['id'],
|
|
1695
|
+
};
|
|
1696
|
+
// https://github.com/ccxt/ccxt/issues/6452
|
|
1697
|
+
const response = await this.privatePostDepositsGenerateCoinAddress(this.extend(request, params));
|
|
1698
|
+
//
|
|
1699
|
+
// https://docs.upbit.com/v1.0/reference#%EC%9E%85%EA%B8%88-%EC%A3%BC%EC%86%8C-%EC%83%9D%EC%84%B1-%EC%9A%94%EC%B2%AD
|
|
1700
|
+
// can be any of the two responses:
|
|
1701
|
+
//
|
|
1702
|
+
// {
|
|
1703
|
+
// "success" : true,
|
|
1704
|
+
// "message" : "Creating BTC deposit address."
|
|
1705
|
+
// }
|
|
1706
|
+
//
|
|
1707
|
+
// {
|
|
1708
|
+
// "currency": "BTC",
|
|
1709
|
+
// "deposit_address": "3EusRwybuZUhVDeHL7gh3HSLmbhLcy7NqD",
|
|
1710
|
+
// "secondary_address": null
|
|
1711
|
+
// }
|
|
1712
|
+
//
|
|
1713
|
+
const message = this.safeString(response, 'message');
|
|
1714
|
+
if (message !== undefined) {
|
|
1715
|
+
throw new errors.AddressPending(this.id + ' is generating ' + code + ' deposit address, call fetchDepositAddress or createDepositAddress one more time later to retrieve the generated address');
|
|
1716
|
+
}
|
|
1717
|
+
return this.parseDepositAddress(response);
|
|
1718
|
+
}
|
|
1719
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
1720
|
+
/**
|
|
1721
|
+
* @method
|
|
1722
|
+
* @name upbit#withdraw
|
|
1723
|
+
* @see https://docs.upbit.com/reference/디지털자산-출금하기
|
|
1724
|
+
* @see https://docs.upbit.com/reference/%EC%9B%90%ED%99%94-%EC%B6%9C%EA%B8%88%ED%95%98%EA%B8%B0
|
|
1725
|
+
* @description make a withdrawal
|
|
1726
|
+
* @param {string} code unified currency code
|
|
1727
|
+
* @param {float} amount the amount to withdraw
|
|
1728
|
+
* @param {string} address the address to withdraw to
|
|
1729
|
+
* @param {string} tag
|
|
1730
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1731
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1732
|
+
*/
|
|
1733
|
+
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
1734
|
+
await this.loadMarkets();
|
|
1735
|
+
const currency = this.currency(code);
|
|
1736
|
+
const request = {
|
|
1737
|
+
'amount': amount,
|
|
1738
|
+
};
|
|
1739
|
+
let response = undefined;
|
|
1740
|
+
if (code !== 'KRW') {
|
|
1741
|
+
this.checkAddress(address);
|
|
1742
|
+
// 2023-05-23 Change to required parameters for digital assets
|
|
1743
|
+
const network = this.safeStringUpper2(params, 'network', 'net_type');
|
|
1744
|
+
if (network === undefined) {
|
|
1745
|
+
throw new errors.ArgumentsRequired(this.id + ' withdraw() requires a network argument');
|
|
1746
|
+
}
|
|
1747
|
+
params = this.omit(params, ['network']);
|
|
1748
|
+
request['net_type'] = network;
|
|
1749
|
+
request['currency'] = currency['id'];
|
|
1750
|
+
request['address'] = address;
|
|
1751
|
+
if (tag !== undefined) {
|
|
1752
|
+
request['secondary_address'] = tag;
|
|
1753
|
+
}
|
|
1754
|
+
params = this.omit(params, 'network');
|
|
1755
|
+
response = await this.privatePostWithdrawsCoin(this.extend(request, params));
|
|
1756
|
+
}
|
|
1757
|
+
else {
|
|
1758
|
+
response = await this.privatePostWithdrawsKrw(this.extend(request, params));
|
|
1759
|
+
}
|
|
1760
|
+
//
|
|
1761
|
+
// {
|
|
1762
|
+
// "type": "withdraw",
|
|
1763
|
+
// "uuid": "9f432943-54e0-40b7-825f-b6fec8b42b79",
|
|
1764
|
+
// "currency": "BTC",
|
|
1765
|
+
// "txid": "ebe6937b-130e-4066-8ac6-4b0e67f28adc",
|
|
1766
|
+
// "state": "processing",
|
|
1767
|
+
// "created_at": "2018-04-13T11:24:01+09:00",
|
|
1768
|
+
// "done_at": null,
|
|
1769
|
+
// "amount": "0.01",
|
|
1770
|
+
// "fee": "0.0",
|
|
1771
|
+
// "krw_amount": "80420.0"
|
|
1772
|
+
// }
|
|
1773
|
+
//
|
|
1774
|
+
return this.parseTransaction(response);
|
|
1775
|
+
}
|
|
1776
|
+
nonce() {
|
|
1777
|
+
return this.milliseconds();
|
|
1778
|
+
}
|
|
1779
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
1780
|
+
let url = this.implodeParams(this.urls['api'][api], {
|
|
1781
|
+
'hostname': this.hostname,
|
|
1782
|
+
});
|
|
1783
|
+
url += '/' + this.version + '/' + this.implodeParams(path, params);
|
|
1784
|
+
const query = this.omit(params, this.extractParams(path));
|
|
1785
|
+
if (method !== 'POST') {
|
|
1786
|
+
if (Object.keys(query).length) {
|
|
1787
|
+
url += '?' + this.urlencode(query);
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
if (api === 'private') {
|
|
1791
|
+
this.checkRequiredCredentials();
|
|
1792
|
+
const nonce = this.nonce();
|
|
1793
|
+
const request = {
|
|
1794
|
+
'access_key': this.apiKey,
|
|
1795
|
+
'nonce': nonce,
|
|
1796
|
+
};
|
|
1797
|
+
if (Object.keys(query).length) {
|
|
1798
|
+
const auth = this.urlencode(query);
|
|
1799
|
+
const hash = this.hash(this.encode(auth), sha512.sha512);
|
|
1800
|
+
request['query_hash'] = hash;
|
|
1801
|
+
request['query_hash_alg'] = 'SHA512';
|
|
1802
|
+
}
|
|
1803
|
+
const token = rsa.jwt(request, this.encode(this.secret), sha256.sha256);
|
|
1804
|
+
headers = {
|
|
1805
|
+
'Authorization': 'Bearer ' + token,
|
|
1806
|
+
};
|
|
1807
|
+
if ((method !== 'GET') && (method !== 'DELETE')) {
|
|
1808
|
+
body = this.json(params);
|
|
1809
|
+
headers['Content-Type'] = 'application/json';
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
1813
|
+
}
|
|
1814
|
+
handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
1815
|
+
if (response === undefined) {
|
|
1816
|
+
return undefined; // fallback to default error handler
|
|
1817
|
+
}
|
|
1818
|
+
//
|
|
1819
|
+
// { 'error': { 'message': "Missing request parameter error. Check the required parameters!", 'name': 400 } },
|
|
1820
|
+
// { 'error': { 'message': "side is missing, side does not have a valid value", 'name': "validation_error" } },
|
|
1821
|
+
// { 'error': { 'message': "개인정보 제 3자 제공 동의가 필요합니다.", 'name': "thirdparty_agreement_required" } },
|
|
1822
|
+
// { 'error': { 'message': "권한이 부족합니다.", 'name': "out_of_scope" } },
|
|
1823
|
+
// { 'error': { 'message': "주문을 찾지 못했습니다.", 'name': "order_not_found" } },
|
|
1824
|
+
// { 'error': { 'message': "주문가능한 금액(ETH)이 부족합니다.", 'name': "insufficient_funds_ask" } },
|
|
1825
|
+
// { 'error': { 'message': "주문가능한 금액(BTC)이 부족합니다.", 'name': "insufficient_funds_bid" } },
|
|
1826
|
+
// { 'error': { 'message': "잘못된 엑세스 키입니다.", 'name': "invalid_access_key" } },
|
|
1827
|
+
// { 'error': { 'message': "Jwt 토큰 검증에 실패했습니다.", 'name': "jwt_verification" } }
|
|
1828
|
+
//
|
|
1829
|
+
const error = this.safeValue(response, 'error');
|
|
1830
|
+
if (error !== undefined) {
|
|
1831
|
+
const message = this.safeString(error, 'message');
|
|
1832
|
+
const name = this.safeString(error, 'name');
|
|
1833
|
+
const feedback = this.id + ' ' + body;
|
|
1834
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
1835
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], name, feedback);
|
|
1836
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
1837
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], name, feedback);
|
|
1838
|
+
throw new errors.ExchangeError(feedback); // unknown message
|
|
1839
|
+
}
|
|
1840
|
+
return undefined;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
module.exports = upbit;
|