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,3115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var okcoin$1 = require('./abstract/okcoin.js');
|
|
4
|
+
var errors = require('./base/errors.js');
|
|
5
|
+
var Precise = require('./base/Precise.js');
|
|
6
|
+
var number = require('./base/functions/number.js');
|
|
7
|
+
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* @class okcoin
|
|
13
|
+
* @augments Exchange
|
|
14
|
+
*/
|
|
15
|
+
class okcoin extends okcoin$1 {
|
|
16
|
+
describe() {
|
|
17
|
+
return this.deepExtend(super.describe(), {
|
|
18
|
+
'id': 'okcoin',
|
|
19
|
+
'name': 'OKCoin',
|
|
20
|
+
'countries': ['CN', 'US'],
|
|
21
|
+
'version': 'v5',
|
|
22
|
+
// cheapest endpoint is 100 requests per 2 seconds
|
|
23
|
+
// 50 requests per second => 1000 / 50 = 20ms
|
|
24
|
+
'rateLimit': 20,
|
|
25
|
+
'pro': true,
|
|
26
|
+
'has': {
|
|
27
|
+
'CORS': undefined,
|
|
28
|
+
'spot': true,
|
|
29
|
+
'margin': false,
|
|
30
|
+
'swap': false,
|
|
31
|
+
'future': true,
|
|
32
|
+
'option': undefined,
|
|
33
|
+
'cancelOrder': true,
|
|
34
|
+
'createMarketBuyOrderWithCost': true,
|
|
35
|
+
'createMarketOrderWithCost': false,
|
|
36
|
+
'createMarketSellOrderWithCost': false,
|
|
37
|
+
'createOrder': true,
|
|
38
|
+
'fetchBalance': true,
|
|
39
|
+
'fetchBorrowInterest': false,
|
|
40
|
+
'fetchBorrowRate': false,
|
|
41
|
+
'fetchBorrowRateHistories': false,
|
|
42
|
+
'fetchBorrowRateHistory': false,
|
|
43
|
+
'fetchBorrowRates': false,
|
|
44
|
+
'fetchBorrowRatesPerSymbol': false,
|
|
45
|
+
'fetchClosedOrders': true,
|
|
46
|
+
'fetchCurrencies': true,
|
|
47
|
+
'fetchDepositAddress': true,
|
|
48
|
+
'fetchDeposits': true,
|
|
49
|
+
'fetchLedger': true,
|
|
50
|
+
'fetchMarkets': true,
|
|
51
|
+
'fetchMyTrades': true,
|
|
52
|
+
'fetchOHLCV': true,
|
|
53
|
+
'fetchOpenOrders': true,
|
|
54
|
+
'fetchOrder': true,
|
|
55
|
+
'fetchOrderBook': true,
|
|
56
|
+
'fetchOrders': undefined,
|
|
57
|
+
'fetchOrderTrades': true,
|
|
58
|
+
'fetchPosition': false,
|
|
59
|
+
'fetchPositions': false,
|
|
60
|
+
'fetchTicker': true,
|
|
61
|
+
'fetchTickers': true,
|
|
62
|
+
'fetchTime': true,
|
|
63
|
+
'fetchTrades': true,
|
|
64
|
+
'fetchTransactions': undefined,
|
|
65
|
+
'fetchWithdrawals': true,
|
|
66
|
+
'reduceMargin': false,
|
|
67
|
+
'repayCrossMargin': false,
|
|
68
|
+
'repayIsolatedMargin': false,
|
|
69
|
+
'setMargin': false,
|
|
70
|
+
'transfer': true,
|
|
71
|
+
'withdraw': true,
|
|
72
|
+
},
|
|
73
|
+
'timeframes': {
|
|
74
|
+
'1m': '1m',
|
|
75
|
+
'3m': '3m',
|
|
76
|
+
'5m': '5m',
|
|
77
|
+
'15m': '15m',
|
|
78
|
+
'30m': '30m',
|
|
79
|
+
'1h': '1H',
|
|
80
|
+
'2h': '2H',
|
|
81
|
+
'4h': '4H',
|
|
82
|
+
'6h': '6H',
|
|
83
|
+
'12h': '12H',
|
|
84
|
+
'1d': '1D',
|
|
85
|
+
'1w': '1W',
|
|
86
|
+
'1M': '1M',
|
|
87
|
+
'3M': '3M',
|
|
88
|
+
},
|
|
89
|
+
'hostname': 'okcoin.com',
|
|
90
|
+
'urls': {
|
|
91
|
+
'logo': 'https://user-images.githubusercontent.com/51840849/87295551-102fbf00-c50e-11ea-90a9-462eebba5829.jpg',
|
|
92
|
+
'api': {
|
|
93
|
+
'rest': 'https://www.{hostname}',
|
|
94
|
+
},
|
|
95
|
+
'www': 'https://www.okcoin.com',
|
|
96
|
+
'doc': 'https://www.okcoin.com/docs/en/',
|
|
97
|
+
'fees': 'https://www.okcoin.com/coin-fees',
|
|
98
|
+
'referral': 'https://www.okcoin.com/account/register?flag=activity&channelId=600001513',
|
|
99
|
+
'test': {
|
|
100
|
+
'rest': 'https://testnet.okex.com',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
'api': {
|
|
104
|
+
'public': {
|
|
105
|
+
'get': {
|
|
106
|
+
'market/tickers': 1,
|
|
107
|
+
'market/ticker': 1,
|
|
108
|
+
'market/books': 1 / 2,
|
|
109
|
+
'market/candles': 1 / 2,
|
|
110
|
+
'market/history-candles': 1 / 2,
|
|
111
|
+
'market/trades': 1 / 5,
|
|
112
|
+
'market/history-trades': 2,
|
|
113
|
+
'market/platform-24-volume': 10,
|
|
114
|
+
'market/open-oracle': 50,
|
|
115
|
+
'market/exchange-rate': 20,
|
|
116
|
+
'public/instruments': 1,
|
|
117
|
+
'public/time': 2,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
'private': {
|
|
121
|
+
'get': {
|
|
122
|
+
// trade
|
|
123
|
+
'trade/order': 1 / 3,
|
|
124
|
+
'trade/orders-pending': 1 / 3,
|
|
125
|
+
'trade/orders-history': 1 / 2,
|
|
126
|
+
'trade/orders-history-archive': 1 / 2,
|
|
127
|
+
'trade/fills': 1 / 3,
|
|
128
|
+
'trade/fills-history': 2.2,
|
|
129
|
+
'trade/fills-archive': 2,
|
|
130
|
+
'trade/order-algo': 1,
|
|
131
|
+
'trade/orders-algo-pending': 1,
|
|
132
|
+
'trade/orders-algo-history': 1,
|
|
133
|
+
// rfq
|
|
134
|
+
'otc/rfq/trade': 4,
|
|
135
|
+
'otc/rfq/history': 4,
|
|
136
|
+
// account
|
|
137
|
+
'account/balance': 2,
|
|
138
|
+
'account/bills': 5 / 3,
|
|
139
|
+
'account/bills-archive': 5 / 3,
|
|
140
|
+
'account/config': 4,
|
|
141
|
+
'account/max-size': 4,
|
|
142
|
+
'account/max-avail-size': 4,
|
|
143
|
+
'account/trade-fee': 4,
|
|
144
|
+
'account/max-withdrawal': 4,
|
|
145
|
+
// funding or assets
|
|
146
|
+
'asset/currencies': 5 / 3,
|
|
147
|
+
'asset/balances': 5 / 3,
|
|
148
|
+
'asset/asset-valuation': 10,
|
|
149
|
+
'asset/transfer-state': 10,
|
|
150
|
+
'asset/bills': 5 / 3,
|
|
151
|
+
'asset/deposit-lightning': 5,
|
|
152
|
+
'asset/deposit-address': 5 / 3,
|
|
153
|
+
'asset/deposit-history': 5 / 3,
|
|
154
|
+
'asset/withdrawal-history': 5 / 3,
|
|
155
|
+
'asset/deposit-withdraw-status': 20,
|
|
156
|
+
// fiat
|
|
157
|
+
'fiat/deposit-history': 5 / 3,
|
|
158
|
+
'fiat-withdraw-history': 5 / 3,
|
|
159
|
+
'fiat-channel': 5 / 3,
|
|
160
|
+
// sub-account
|
|
161
|
+
'users/subaccount/list': 10,
|
|
162
|
+
'users/subaccount/apiKey': 10,
|
|
163
|
+
'account/subaccount/balances': 10,
|
|
164
|
+
'asset/subaccount/balances': 10,
|
|
165
|
+
'asset/subaccount/bills': 10,
|
|
166
|
+
},
|
|
167
|
+
'post': {
|
|
168
|
+
// trade
|
|
169
|
+
'trade/order': 1 / 3,
|
|
170
|
+
'trade/batch-orders': 1 / 15,
|
|
171
|
+
'trade/cancel-order': 1 / 3,
|
|
172
|
+
'trade/cancel-batch-orders': 1 / 15,
|
|
173
|
+
'trade/amend-order': 1 / 3,
|
|
174
|
+
'trade/amend-batch-orders': 1 / 150,
|
|
175
|
+
'trade/order-algo': 1,
|
|
176
|
+
'trade/cancel-algos': 1,
|
|
177
|
+
'trade/cancel-advance-algos': 1,
|
|
178
|
+
// rfq
|
|
179
|
+
'otc/rfq/quote': 4,
|
|
180
|
+
'otc/rfq/trade': 4,
|
|
181
|
+
// funding
|
|
182
|
+
'asset/transfer': 4,
|
|
183
|
+
'asset/withdrawal': 4,
|
|
184
|
+
'asset/withdrawal-lightning': 4,
|
|
185
|
+
'asset/withdrawal-cancel': 4,
|
|
186
|
+
// fiat
|
|
187
|
+
'fiat/deposit': 5 / 3,
|
|
188
|
+
'fiat/cancel-deposit': 5 / 3,
|
|
189
|
+
'fiat/withdrawal': 5 / 3,
|
|
190
|
+
'fiat/cancel-withdrawal': 5 / 3,
|
|
191
|
+
// sub-account
|
|
192
|
+
'asset/subaccount/transfer': 10,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
'fees': {
|
|
197
|
+
'trading': {
|
|
198
|
+
'taker': 0.002,
|
|
199
|
+
'maker': 0.001,
|
|
200
|
+
},
|
|
201
|
+
'spot': {
|
|
202
|
+
'taker': 0.0015,
|
|
203
|
+
'maker': 0.0010,
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
'requiredCredentials': {
|
|
207
|
+
'apiKey': true,
|
|
208
|
+
'secret': true,
|
|
209
|
+
'password': true,
|
|
210
|
+
},
|
|
211
|
+
'exceptions': {
|
|
212
|
+
'exact': {
|
|
213
|
+
// Public error codes from 50000-53999
|
|
214
|
+
// General Class
|
|
215
|
+
'1': errors.ExchangeError,
|
|
216
|
+
'2': errors.ExchangeError,
|
|
217
|
+
'50000': errors.BadRequest,
|
|
218
|
+
'50001': errors.OnMaintenance,
|
|
219
|
+
'50002': errors.BadRequest,
|
|
220
|
+
'50004': errors.RequestTimeout,
|
|
221
|
+
'50005': errors.ExchangeNotAvailable,
|
|
222
|
+
'50006': errors.BadRequest,
|
|
223
|
+
'50007': errors.AccountSuspended,
|
|
224
|
+
'50008': errors.AuthenticationError,
|
|
225
|
+
'50009': errors.AccountSuspended,
|
|
226
|
+
'50010': errors.ExchangeError,
|
|
227
|
+
'50011': errors.RateLimitExceeded,
|
|
228
|
+
'50012': errors.ExchangeError,
|
|
229
|
+
'50013': errors.ExchangeNotAvailable,
|
|
230
|
+
'50014': errors.BadRequest,
|
|
231
|
+
'50015': errors.ExchangeError,
|
|
232
|
+
'50016': errors.ExchangeError,
|
|
233
|
+
'50017': errors.ExchangeError,
|
|
234
|
+
'50018': errors.ExchangeError,
|
|
235
|
+
'50019': errors.ExchangeError,
|
|
236
|
+
'50020': errors.ExchangeError,
|
|
237
|
+
'50021': errors.ExchangeError,
|
|
238
|
+
'50022': errors.ExchangeError,
|
|
239
|
+
'50023': errors.ExchangeError,
|
|
240
|
+
'50024': errors.BadRequest,
|
|
241
|
+
'50025': errors.ExchangeError,
|
|
242
|
+
'50026': errors.ExchangeNotAvailable,
|
|
243
|
+
'50027': errors.PermissionDenied,
|
|
244
|
+
'50028': errors.ExchangeError,
|
|
245
|
+
'50044': errors.BadRequest,
|
|
246
|
+
// API Class
|
|
247
|
+
'50100': errors.ExchangeError,
|
|
248
|
+
'50101': errors.AuthenticationError,
|
|
249
|
+
'50102': errors.InvalidNonce,
|
|
250
|
+
'50103': errors.AuthenticationError,
|
|
251
|
+
'50104': errors.AuthenticationError,
|
|
252
|
+
'50105': errors.AuthenticationError,
|
|
253
|
+
'50106': errors.AuthenticationError,
|
|
254
|
+
'50107': errors.AuthenticationError,
|
|
255
|
+
'50108': errors.ExchangeError,
|
|
256
|
+
'50109': errors.ExchangeError,
|
|
257
|
+
'50110': errors.PermissionDenied,
|
|
258
|
+
'50111': errors.AuthenticationError,
|
|
259
|
+
'50112': errors.AuthenticationError,
|
|
260
|
+
'50113': errors.AuthenticationError,
|
|
261
|
+
'50114': errors.AuthenticationError,
|
|
262
|
+
'50115': errors.BadRequest,
|
|
263
|
+
// Trade Class
|
|
264
|
+
'51000': errors.BadRequest,
|
|
265
|
+
'51001': errors.BadSymbol,
|
|
266
|
+
'51002': errors.BadSymbol,
|
|
267
|
+
'51003': errors.BadRequest,
|
|
268
|
+
'51004': errors.InvalidOrder,
|
|
269
|
+
'51005': errors.InvalidOrder,
|
|
270
|
+
'51006': errors.InvalidOrder,
|
|
271
|
+
'51007': errors.InvalidOrder,
|
|
272
|
+
'51008': errors.InsufficientFunds,
|
|
273
|
+
'51009': errors.AccountSuspended,
|
|
274
|
+
'51010': errors.AccountNotEnabled,
|
|
275
|
+
'51011': errors.InvalidOrder,
|
|
276
|
+
'51012': errors.BadSymbol,
|
|
277
|
+
'51014': errors.BadSymbol,
|
|
278
|
+
'51015': errors.BadSymbol,
|
|
279
|
+
'51016': errors.InvalidOrder,
|
|
280
|
+
'51017': errors.ExchangeError,
|
|
281
|
+
'51018': errors.ExchangeError,
|
|
282
|
+
'51019': errors.ExchangeError,
|
|
283
|
+
'51020': errors.InvalidOrder,
|
|
284
|
+
'51023': errors.ExchangeError,
|
|
285
|
+
'51024': errors.AccountSuspended,
|
|
286
|
+
'51025': errors.ExchangeError,
|
|
287
|
+
'51026': errors.BadSymbol,
|
|
288
|
+
'51046': errors.InvalidOrder,
|
|
289
|
+
'51047': errors.InvalidOrder,
|
|
290
|
+
'51031': errors.InvalidOrder,
|
|
291
|
+
'51100': errors.InvalidOrder,
|
|
292
|
+
'51102': errors.InvalidOrder,
|
|
293
|
+
'51103': errors.InvalidOrder,
|
|
294
|
+
'51108': errors.InvalidOrder,
|
|
295
|
+
'51109': errors.InvalidOrder,
|
|
296
|
+
'51110': errors.InvalidOrder,
|
|
297
|
+
'51111': errors.BadRequest,
|
|
298
|
+
'51112': errors.InvalidOrder,
|
|
299
|
+
'51113': errors.RateLimitExceeded,
|
|
300
|
+
'51115': errors.InvalidOrder,
|
|
301
|
+
'51116': errors.InvalidOrder,
|
|
302
|
+
'51117': errors.InvalidOrder,
|
|
303
|
+
'51118': errors.InvalidOrder,
|
|
304
|
+
'51119': errors.InsufficientFunds,
|
|
305
|
+
'51120': errors.InvalidOrder,
|
|
306
|
+
'51121': errors.InvalidOrder,
|
|
307
|
+
'51122': errors.InvalidOrder,
|
|
308
|
+
'51124': errors.InvalidOrder,
|
|
309
|
+
'51125': errors.InvalidOrder,
|
|
310
|
+
'51126': errors.InvalidOrder,
|
|
311
|
+
'51127': errors.InsufficientFunds,
|
|
312
|
+
'51128': errors.InvalidOrder,
|
|
313
|
+
'51129': errors.InvalidOrder,
|
|
314
|
+
'51130': errors.BadSymbol,
|
|
315
|
+
'51131': errors.InsufficientFunds,
|
|
316
|
+
'51132': errors.InvalidOrder,
|
|
317
|
+
'51133': errors.InvalidOrder,
|
|
318
|
+
'51134': errors.InvalidOrder,
|
|
319
|
+
'51135': errors.InvalidOrder,
|
|
320
|
+
'51136': errors.InvalidOrder,
|
|
321
|
+
'51137': errors.InvalidOrder,
|
|
322
|
+
'51138': errors.InvalidOrder,
|
|
323
|
+
'51139': errors.InvalidOrder,
|
|
324
|
+
'51156': errors.BadRequest,
|
|
325
|
+
'51159': errors.BadRequest,
|
|
326
|
+
'51162': errors.InvalidOrder,
|
|
327
|
+
'51163': errors.InvalidOrder,
|
|
328
|
+
'51166': errors.InvalidOrder,
|
|
329
|
+
'51174': errors.InvalidOrder,
|
|
330
|
+
'51201': errors.InvalidOrder,
|
|
331
|
+
'51202': errors.InvalidOrder,
|
|
332
|
+
'51203': errors.InvalidOrder,
|
|
333
|
+
'51204': errors.InvalidOrder,
|
|
334
|
+
'51205': errors.InvalidOrder,
|
|
335
|
+
'51250': errors.InvalidOrder,
|
|
336
|
+
'51251': errors.InvalidOrder,
|
|
337
|
+
'51252': errors.InvalidOrder,
|
|
338
|
+
'51253': errors.InvalidOrder,
|
|
339
|
+
'51254': errors.InvalidOrder,
|
|
340
|
+
'51255': errors.InvalidOrder,
|
|
341
|
+
'51256': errors.InvalidOrder,
|
|
342
|
+
'51257': errors.InvalidOrder,
|
|
343
|
+
'51258': errors.InvalidOrder,
|
|
344
|
+
'51259': errors.InvalidOrder,
|
|
345
|
+
'51260': errors.InvalidOrder,
|
|
346
|
+
'51261': errors.InvalidOrder,
|
|
347
|
+
'51262': errors.InvalidOrder,
|
|
348
|
+
'51263': errors.InvalidOrder,
|
|
349
|
+
'51264': errors.InvalidOrder,
|
|
350
|
+
'51265': errors.InvalidOrder,
|
|
351
|
+
'51267': errors.InvalidOrder,
|
|
352
|
+
'51268': errors.InvalidOrder,
|
|
353
|
+
'51269': errors.InvalidOrder,
|
|
354
|
+
'51270': errors.InvalidOrder,
|
|
355
|
+
'51271': errors.InvalidOrder,
|
|
356
|
+
'51272': errors.InvalidOrder,
|
|
357
|
+
'51273': errors.InvalidOrder,
|
|
358
|
+
'51274': errors.InvalidOrder,
|
|
359
|
+
'51275': errors.InvalidOrder,
|
|
360
|
+
'51276': errors.InvalidOrder,
|
|
361
|
+
'51277': errors.InvalidOrder,
|
|
362
|
+
'51278': errors.InvalidOrder,
|
|
363
|
+
'51279': errors.InvalidOrder,
|
|
364
|
+
'51280': errors.InvalidOrder,
|
|
365
|
+
'51321': errors.InvalidOrder,
|
|
366
|
+
'51322': errors.InvalidOrder,
|
|
367
|
+
'51323': errors.BadRequest,
|
|
368
|
+
'51324': errors.BadRequest,
|
|
369
|
+
'51325': errors.InvalidOrder,
|
|
370
|
+
'51327': errors.InvalidOrder,
|
|
371
|
+
'51328': errors.InvalidOrder,
|
|
372
|
+
'51329': errors.InvalidOrder,
|
|
373
|
+
'51330': errors.InvalidOrder,
|
|
374
|
+
'51400': errors.OrderNotFound,
|
|
375
|
+
'51401': errors.OrderNotFound,
|
|
376
|
+
'51402': errors.OrderNotFound,
|
|
377
|
+
'51403': errors.InvalidOrder,
|
|
378
|
+
'51404': errors.InvalidOrder,
|
|
379
|
+
'51405': errors.ExchangeError,
|
|
380
|
+
'51406': errors.ExchangeError,
|
|
381
|
+
'51407': errors.BadRequest,
|
|
382
|
+
'51408': errors.ExchangeError,
|
|
383
|
+
'51409': errors.ExchangeError,
|
|
384
|
+
'51410': errors.CancelPending,
|
|
385
|
+
'51500': errors.ExchangeError,
|
|
386
|
+
'51501': errors.ExchangeError,
|
|
387
|
+
'51502': errors.InsufficientFunds,
|
|
388
|
+
'51503': errors.ExchangeError,
|
|
389
|
+
'51506': errors.ExchangeError,
|
|
390
|
+
'51508': errors.ExchangeError,
|
|
391
|
+
'51509': errors.ExchangeError,
|
|
392
|
+
'51510': errors.ExchangeError,
|
|
393
|
+
'51511': errors.ExchangeError,
|
|
394
|
+
'51600': errors.ExchangeError,
|
|
395
|
+
'51601': errors.ExchangeError,
|
|
396
|
+
'51602': errors.ExchangeError,
|
|
397
|
+
'51603': errors.OrderNotFound,
|
|
398
|
+
'51732': errors.AuthenticationError,
|
|
399
|
+
'51733': errors.AuthenticationError,
|
|
400
|
+
'51734': errors.AuthenticationError,
|
|
401
|
+
'51735': errors.ExchangeError,
|
|
402
|
+
'51736': errors.InsufficientFunds,
|
|
403
|
+
// Data class
|
|
404
|
+
'52000': errors.ExchangeError,
|
|
405
|
+
// SPOT/MARGIN error codes 54000-54999
|
|
406
|
+
'54000': errors.ExchangeError,
|
|
407
|
+
'54001': errors.ExchangeError,
|
|
408
|
+
// FUNDING error codes 58000-58999
|
|
409
|
+
'58000': errors.ExchangeError,
|
|
410
|
+
'58001': errors.AuthenticationError,
|
|
411
|
+
'58002': errors.PermissionDenied,
|
|
412
|
+
'58003': errors.ExchangeError,
|
|
413
|
+
'58004': errors.AccountSuspended,
|
|
414
|
+
'58005': errors.ExchangeError,
|
|
415
|
+
'58006': errors.ExchangeError,
|
|
416
|
+
'58007': errors.ExchangeError,
|
|
417
|
+
'58100': errors.ExchangeError,
|
|
418
|
+
'58101': errors.AccountSuspended,
|
|
419
|
+
'58102': errors.RateLimitExceeded,
|
|
420
|
+
'58103': errors.ExchangeError,
|
|
421
|
+
'58104': errors.ExchangeError,
|
|
422
|
+
'58105': errors.ExchangeError,
|
|
423
|
+
'58106': errors.ExchangeError,
|
|
424
|
+
'58107': errors.ExchangeError,
|
|
425
|
+
'58108': errors.ExchangeError,
|
|
426
|
+
'58109': errors.ExchangeError,
|
|
427
|
+
'58110': errors.ExchangeError,
|
|
428
|
+
'58111': errors.ExchangeError,
|
|
429
|
+
'58112': errors.ExchangeError,
|
|
430
|
+
'58114': errors.ExchangeError,
|
|
431
|
+
'58115': errors.ExchangeError,
|
|
432
|
+
'58116': errors.ExchangeError,
|
|
433
|
+
'58117': errors.ExchangeError,
|
|
434
|
+
'58125': errors.BadRequest,
|
|
435
|
+
'58126': errors.BadRequest,
|
|
436
|
+
'58127': errors.BadRequest,
|
|
437
|
+
'58128': errors.BadRequest,
|
|
438
|
+
'58200': errors.ExchangeError,
|
|
439
|
+
'58201': errors.ExchangeError,
|
|
440
|
+
'58202': errors.ExchangeError,
|
|
441
|
+
'58203': errors.InvalidAddress,
|
|
442
|
+
'58204': errors.AccountSuspended,
|
|
443
|
+
'58205': errors.ExchangeError,
|
|
444
|
+
'58206': errors.ExchangeError,
|
|
445
|
+
'58207': errors.InvalidAddress,
|
|
446
|
+
'58208': errors.ExchangeError,
|
|
447
|
+
'58209': errors.ExchangeError,
|
|
448
|
+
'58210': errors.ExchangeError,
|
|
449
|
+
'58211': errors.ExchangeError,
|
|
450
|
+
'58212': errors.ExchangeError,
|
|
451
|
+
'58213': errors.AuthenticationError,
|
|
452
|
+
'58221': errors.BadRequest,
|
|
453
|
+
'58222': errors.BadRequest,
|
|
454
|
+
'58224': errors.BadRequest,
|
|
455
|
+
'58227': errors.BadRequest,
|
|
456
|
+
'58228': errors.BadRequest,
|
|
457
|
+
'58229': errors.InsufficientFunds,
|
|
458
|
+
'58300': errors.ExchangeError,
|
|
459
|
+
'58350': errors.InsufficientFunds,
|
|
460
|
+
// Account error codes 59000-59999
|
|
461
|
+
'59000': errors.ExchangeError,
|
|
462
|
+
'59001': errors.ExchangeError,
|
|
463
|
+
'59100': errors.ExchangeError,
|
|
464
|
+
'59101': errors.ExchangeError,
|
|
465
|
+
'59102': errors.ExchangeError,
|
|
466
|
+
'59103': errors.InsufficientFunds,
|
|
467
|
+
'59104': errors.ExchangeError,
|
|
468
|
+
'59105': errors.ExchangeError,
|
|
469
|
+
'59106': errors.ExchangeError,
|
|
470
|
+
'59107': errors.ExchangeError,
|
|
471
|
+
'59108': errors.InsufficientFunds,
|
|
472
|
+
'59109': errors.ExchangeError,
|
|
473
|
+
'59128': errors.InvalidOrder,
|
|
474
|
+
'59200': errors.InsufficientFunds,
|
|
475
|
+
'59201': errors.InsufficientFunds,
|
|
476
|
+
'59216': errors.BadRequest,
|
|
477
|
+
'59300': errors.ExchangeError,
|
|
478
|
+
'59301': errors.ExchangeError,
|
|
479
|
+
'59313': errors.ExchangeError,
|
|
480
|
+
'59401': errors.ExchangeError,
|
|
481
|
+
'59500': errors.ExchangeError,
|
|
482
|
+
'59501': errors.ExchangeError,
|
|
483
|
+
'59502': errors.ExchangeError,
|
|
484
|
+
'59503': errors.ExchangeError,
|
|
485
|
+
'59504': errors.ExchangeError,
|
|
486
|
+
'59505': errors.ExchangeError,
|
|
487
|
+
'59506': errors.ExchangeError,
|
|
488
|
+
'59507': errors.ExchangeError,
|
|
489
|
+
'59508': errors.AccountSuspended,
|
|
490
|
+
// WebSocket error Codes from 60000-63999
|
|
491
|
+
'60001': errors.AuthenticationError,
|
|
492
|
+
'60002': errors.AuthenticationError,
|
|
493
|
+
'60003': errors.AuthenticationError,
|
|
494
|
+
'60004': errors.AuthenticationError,
|
|
495
|
+
'60005': errors.AuthenticationError,
|
|
496
|
+
'60006': errors.InvalidNonce,
|
|
497
|
+
'60007': errors.AuthenticationError,
|
|
498
|
+
'60008': errors.AuthenticationError,
|
|
499
|
+
'60009': errors.AuthenticationError,
|
|
500
|
+
'60010': errors.AuthenticationError,
|
|
501
|
+
'60011': errors.AuthenticationError,
|
|
502
|
+
'60012': errors.BadRequest,
|
|
503
|
+
'60013': errors.BadRequest,
|
|
504
|
+
'60014': errors.RateLimitExceeded,
|
|
505
|
+
'60015': errors.NetworkError,
|
|
506
|
+
'60016': errors.ExchangeNotAvailable,
|
|
507
|
+
'60017': errors.BadRequest,
|
|
508
|
+
'60018': errors.BadRequest,
|
|
509
|
+
'60019': errors.BadRequest,
|
|
510
|
+
'63999': errors.ExchangeError,
|
|
511
|
+
'70010': errors.BadRequest,
|
|
512
|
+
'70013': errors.BadRequest,
|
|
513
|
+
'70016': errors.BadRequest, // Please specify your instrument settings for at least one instType.
|
|
514
|
+
},
|
|
515
|
+
'broad': {
|
|
516
|
+
'Internal Server Error': errors.ExchangeNotAvailable,
|
|
517
|
+
'server error': errors.ExchangeNotAvailable, // {"code":500,"data":{},"detailMsg":"","error_code":"500","error_message":"server error 1236805249","msg":"server error 1236805249"}
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
'precisionMode': number.TICK_SIZE,
|
|
521
|
+
'options': {
|
|
522
|
+
'fetchOHLCV': {
|
|
523
|
+
'type': 'Candles', // Candles or HistoryCandles
|
|
524
|
+
},
|
|
525
|
+
'createMarketBuyOrderRequiresPrice': true,
|
|
526
|
+
'fetchMarkets': ['spot'],
|
|
527
|
+
'defaultType': 'spot',
|
|
528
|
+
'accountsByType': {
|
|
529
|
+
'classic': '1',
|
|
530
|
+
'spot': '1',
|
|
531
|
+
'funding': '6',
|
|
532
|
+
'main': '6',
|
|
533
|
+
'unified': '18',
|
|
534
|
+
},
|
|
535
|
+
'accountsById': {
|
|
536
|
+
'1': 'spot',
|
|
537
|
+
'6': 'funding',
|
|
538
|
+
'18': 'unified',
|
|
539
|
+
},
|
|
540
|
+
'auth': {
|
|
541
|
+
'time': 'public',
|
|
542
|
+
'currencies': 'private',
|
|
543
|
+
'instruments': 'public',
|
|
544
|
+
'rate': 'public',
|
|
545
|
+
'{instrument_id}/constituents': 'public',
|
|
546
|
+
},
|
|
547
|
+
'warnOnFetchCurrenciesWithoutAuthorization': false,
|
|
548
|
+
'defaultNetwork': 'ERC20',
|
|
549
|
+
'networks': {
|
|
550
|
+
'ERC20': 'Ethereum',
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
'commonCurrencies': {
|
|
554
|
+
// OKEX refers to ERC20 version of Aeternity (AEToken)
|
|
555
|
+
'AE': 'AET',
|
|
556
|
+
'BOX': 'DefiBox',
|
|
557
|
+
'HOT': 'Hydro Protocol',
|
|
558
|
+
'HSR': 'HC',
|
|
559
|
+
'MAG': 'Maggie',
|
|
560
|
+
'SBTC': 'Super Bitcoin',
|
|
561
|
+
'TRADE': 'Unitrade',
|
|
562
|
+
'YOYO': 'YOYOW',
|
|
563
|
+
'WIN': 'WinToken', // https://github.com/ccxt/ccxt/issues/5701
|
|
564
|
+
},
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
async fetchTime(params = {}) {
|
|
568
|
+
/**
|
|
569
|
+
* @method
|
|
570
|
+
* @name okcoin#fetchTime
|
|
571
|
+
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
572
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
573
|
+
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
574
|
+
*/
|
|
575
|
+
const response = await this.publicGetPublicTime(params);
|
|
576
|
+
//
|
|
577
|
+
// {
|
|
578
|
+
// "iso": "2015-01-07T23:47:25.201Z",
|
|
579
|
+
// "epoch": 1420674445.201
|
|
580
|
+
// }
|
|
581
|
+
//
|
|
582
|
+
return this.parse8601(this.safeString(response, 'iso'));
|
|
583
|
+
}
|
|
584
|
+
async fetchMarkets(params = {}) {
|
|
585
|
+
/**
|
|
586
|
+
* @method
|
|
587
|
+
* @name okcoin#fetchMarkets
|
|
588
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-public-data-get-instruments
|
|
589
|
+
* @description retrieves data on all markets for okcoin
|
|
590
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
591
|
+
* @returns {object[]} an array of objects representing market data
|
|
592
|
+
*/
|
|
593
|
+
const request = {
|
|
594
|
+
'instType': 'SPOT',
|
|
595
|
+
};
|
|
596
|
+
const response = await this.publicGetPublicInstruments(this.extend(request, params));
|
|
597
|
+
const markets = this.safeValue(response, 'data', []);
|
|
598
|
+
return this.parseMarkets(markets);
|
|
599
|
+
}
|
|
600
|
+
parseMarket(market) {
|
|
601
|
+
//
|
|
602
|
+
// spot markets
|
|
603
|
+
//
|
|
604
|
+
// {
|
|
605
|
+
// "base_currency": "EOS",
|
|
606
|
+
// "instrument_id": "EOS-OKB",
|
|
607
|
+
// "min_size": "0.01",
|
|
608
|
+
// "quote_currency": "OKB",
|
|
609
|
+
// "size_increment": "0.000001",
|
|
610
|
+
// "tick_size": "0.0001"
|
|
611
|
+
// }
|
|
612
|
+
//
|
|
613
|
+
const id = this.safeString(market, 'instId');
|
|
614
|
+
let type = this.safeStringLower(market, 'instType');
|
|
615
|
+
if (type === 'futures') {
|
|
616
|
+
type = 'future';
|
|
617
|
+
}
|
|
618
|
+
const spot = (type === 'spot');
|
|
619
|
+
const future = (type === 'future');
|
|
620
|
+
const swap = (type === 'swap');
|
|
621
|
+
const option = (type === 'option');
|
|
622
|
+
const contract = swap || future || option;
|
|
623
|
+
const baseId = this.safeString(market, 'baseCcy');
|
|
624
|
+
const quoteId = this.safeString(market, 'quoteCcy');
|
|
625
|
+
const base = this.safeCurrencyCode(baseId);
|
|
626
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
627
|
+
const symbol = base + '/' + quote;
|
|
628
|
+
const tickSize = this.safeString(market, 'tickSz');
|
|
629
|
+
const fees = this.safeValue2(this.fees, type, 'trading', {});
|
|
630
|
+
let maxLeverage = this.safeString(market, 'lever', '1');
|
|
631
|
+
maxLeverage = Precise["default"].stringMax(maxLeverage, '1');
|
|
632
|
+
const maxSpotCost = this.safeNumber(market, 'maxMktSz');
|
|
633
|
+
return this.extend(fees, {
|
|
634
|
+
'id': id,
|
|
635
|
+
'symbol': symbol,
|
|
636
|
+
'base': base,
|
|
637
|
+
'quote': quote,
|
|
638
|
+
'settle': undefined,
|
|
639
|
+
'baseId': baseId,
|
|
640
|
+
'quoteId': quoteId,
|
|
641
|
+
'settleId': undefined,
|
|
642
|
+
'type': type,
|
|
643
|
+
'spot': spot,
|
|
644
|
+
'margin': spot && (Precise["default"].stringGt(maxLeverage, '1')),
|
|
645
|
+
'swap': false,
|
|
646
|
+
'future': false,
|
|
647
|
+
'option': false,
|
|
648
|
+
'active': true,
|
|
649
|
+
'contract': false,
|
|
650
|
+
'linear': undefined,
|
|
651
|
+
'inverse': undefined,
|
|
652
|
+
'contractSize': contract ? this.safeNumber(market, 'ctVal') : undefined,
|
|
653
|
+
'expiry': undefined,
|
|
654
|
+
'expiryDatetime': undefined,
|
|
655
|
+
'strike': undefined,
|
|
656
|
+
'optionType': undefined,
|
|
657
|
+
'created': this.safeInteger(market, 'listTime'),
|
|
658
|
+
'precision': {
|
|
659
|
+
'amount': this.safeNumber(market, 'lotSz'),
|
|
660
|
+
'price': this.parseNumber(tickSize),
|
|
661
|
+
},
|
|
662
|
+
'limits': {
|
|
663
|
+
'leverage': {
|
|
664
|
+
'min': this.parseNumber('1'),
|
|
665
|
+
'max': this.parseNumber(maxLeverage),
|
|
666
|
+
},
|
|
667
|
+
'amount': {
|
|
668
|
+
'min': this.safeNumber(market, 'minSz'),
|
|
669
|
+
'max': undefined,
|
|
670
|
+
},
|
|
671
|
+
'price': {
|
|
672
|
+
'min': undefined,
|
|
673
|
+
'max': undefined,
|
|
674
|
+
},
|
|
675
|
+
'cost': {
|
|
676
|
+
'min': undefined,
|
|
677
|
+
'max': contract ? undefined : maxSpotCost,
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
'info': market,
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
safeNetwork(networkId) {
|
|
684
|
+
const networksById = {
|
|
685
|
+
'Bitcoin': 'BTC',
|
|
686
|
+
'Omni': 'OMNI',
|
|
687
|
+
'TRON': 'TRC20',
|
|
688
|
+
};
|
|
689
|
+
return this.safeString(networksById, networkId, networkId);
|
|
690
|
+
}
|
|
691
|
+
async fetchCurrencies(params = {}) {
|
|
692
|
+
/**
|
|
693
|
+
* @method
|
|
694
|
+
* @name okcoin#fetchCurrencies
|
|
695
|
+
* @description fetches all available currencies on an exchange
|
|
696
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
697
|
+
* @returns {object} an associative dictionary of currencies
|
|
698
|
+
*/
|
|
699
|
+
if (!this.checkRequiredCredentials(false)) {
|
|
700
|
+
if (this.options['warnOnFetchCurrenciesWithoutAuthorization']) {
|
|
701
|
+
throw new errors.ExchangeError(this.id + ' fetchCurrencies() is a private API endpoint that requires authentication with API keys. Set the API keys on the exchange instance or exchange.options["warnOnFetchCurrenciesWithoutAuthorization"] = false to suppress this warning message.');
|
|
702
|
+
}
|
|
703
|
+
return undefined;
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
const response = await this.privateGetAssetCurrencies(params);
|
|
707
|
+
const data = this.safeValue(response, 'data', []);
|
|
708
|
+
const result = {};
|
|
709
|
+
const dataByCurrencyId = this.groupBy(data, 'ccy');
|
|
710
|
+
const currencyIds = Object.keys(dataByCurrencyId);
|
|
711
|
+
for (let i = 0; i < currencyIds.length; i++) {
|
|
712
|
+
const currencyId = currencyIds[i];
|
|
713
|
+
const currency = this.safeCurrency(currencyId);
|
|
714
|
+
const code = currency['code'];
|
|
715
|
+
const chains = dataByCurrencyId[currencyId];
|
|
716
|
+
const networks = {};
|
|
717
|
+
let currencyActive = false;
|
|
718
|
+
let depositEnabled = false;
|
|
719
|
+
let withdrawEnabled = false;
|
|
720
|
+
let maxPrecision = undefined;
|
|
721
|
+
for (let j = 0; j < chains.length; j++) {
|
|
722
|
+
const chain = chains[j];
|
|
723
|
+
const canDeposit = this.safeValue(chain, 'canDep');
|
|
724
|
+
depositEnabled = (canDeposit) ? canDeposit : depositEnabled;
|
|
725
|
+
const canWithdraw = this.safeValue(chain, 'canWd');
|
|
726
|
+
withdrawEnabled = (canWithdraw) ? canWithdraw : withdrawEnabled;
|
|
727
|
+
const canInternal = this.safeValue(chain, 'canInternal');
|
|
728
|
+
const active = (canDeposit && canWithdraw && canInternal) ? true : false;
|
|
729
|
+
currencyActive = (active) ? active : currencyActive;
|
|
730
|
+
const networkId = this.safeString(chain, 'chain');
|
|
731
|
+
if ((networkId !== undefined) && (networkId.indexOf('-') >= 0)) {
|
|
732
|
+
const parts = networkId.split('-');
|
|
733
|
+
const chainPart = this.safeString(parts, 1, networkId);
|
|
734
|
+
const networkCode = this.safeNetwork(chainPart);
|
|
735
|
+
const precision = this.parsePrecision(this.safeString(chain, 'wdTickSz'));
|
|
736
|
+
if (maxPrecision === undefined) {
|
|
737
|
+
maxPrecision = precision;
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
maxPrecision = Precise["default"].stringMin(maxPrecision, precision);
|
|
741
|
+
}
|
|
742
|
+
networks[networkCode] = {
|
|
743
|
+
'id': networkId,
|
|
744
|
+
'network': networkCode,
|
|
745
|
+
'active': active,
|
|
746
|
+
'deposit': canDeposit,
|
|
747
|
+
'withdraw': canWithdraw,
|
|
748
|
+
'fee': this.safeNumber(chain, 'minFee'),
|
|
749
|
+
'precision': this.parseNumber(precision),
|
|
750
|
+
'limits': {
|
|
751
|
+
'withdraw': {
|
|
752
|
+
'min': this.safeNumber(chain, 'minWd'),
|
|
753
|
+
'max': this.safeNumber(chain, 'maxWd'),
|
|
754
|
+
},
|
|
755
|
+
},
|
|
756
|
+
'info': chain,
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
const firstChain = this.safeValue(chains, 0);
|
|
761
|
+
result[code] = {
|
|
762
|
+
'info': chains,
|
|
763
|
+
'code': code,
|
|
764
|
+
'id': currencyId,
|
|
765
|
+
'name': this.safeString(firstChain, 'name'),
|
|
766
|
+
'active': currencyActive,
|
|
767
|
+
'deposit': depositEnabled,
|
|
768
|
+
'withdraw': withdrawEnabled,
|
|
769
|
+
'fee': undefined,
|
|
770
|
+
'precision': this.parseNumber(maxPrecision),
|
|
771
|
+
'limits': {
|
|
772
|
+
'amount': {
|
|
773
|
+
'min': undefined,
|
|
774
|
+
'max': undefined,
|
|
775
|
+
},
|
|
776
|
+
},
|
|
777
|
+
'networks': networks,
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
return result;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
784
|
+
/**
|
|
785
|
+
* @method
|
|
786
|
+
* @name okcoin#fetchOrderBook
|
|
787
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-order-book
|
|
788
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
789
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
790
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
791
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
792
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
793
|
+
*/
|
|
794
|
+
await this.loadMarkets();
|
|
795
|
+
const market = this.market(symbol);
|
|
796
|
+
const request = {
|
|
797
|
+
'instId': market['id'],
|
|
798
|
+
};
|
|
799
|
+
limit = (limit === undefined) ? 20 : limit;
|
|
800
|
+
if (limit !== undefined) {
|
|
801
|
+
request['sz'] = limit; // max 400
|
|
802
|
+
}
|
|
803
|
+
const response = await this.publicGetMarketBooks(this.extend(request, params));
|
|
804
|
+
//
|
|
805
|
+
// {
|
|
806
|
+
// "code": "0",
|
|
807
|
+
// "msg": "",
|
|
808
|
+
// "data": [
|
|
809
|
+
// {
|
|
810
|
+
// "asks": [
|
|
811
|
+
// ["0.07228","4.211619","0","2"], // price, amount, liquidated orders, total open orders
|
|
812
|
+
// ["0.0723","299.880364","0","2"],
|
|
813
|
+
// ["0.07231","3.72832","0","1"],
|
|
814
|
+
// ],
|
|
815
|
+
// "bids": [
|
|
816
|
+
// ["0.07221","18.5","0","1"],
|
|
817
|
+
// ["0.0722","18.5","0","1"],
|
|
818
|
+
// ["0.07219","0.505407","0","1"],
|
|
819
|
+
// ],
|
|
820
|
+
// "ts": "1621438475342"
|
|
821
|
+
// }
|
|
822
|
+
// ]
|
|
823
|
+
// }
|
|
824
|
+
//
|
|
825
|
+
const data = this.safeValue(response, 'data', []);
|
|
826
|
+
const first = this.safeValue(data, 0, {});
|
|
827
|
+
const timestamp = this.safeInteger(first, 'ts');
|
|
828
|
+
return this.parseOrderBook(first, symbol, timestamp);
|
|
829
|
+
}
|
|
830
|
+
parseTicker(ticker, market = undefined) {
|
|
831
|
+
//
|
|
832
|
+
// {
|
|
833
|
+
// "instType": "SPOT",
|
|
834
|
+
// "instId": "ETH-BTC",
|
|
835
|
+
// "last": "0.07319",
|
|
836
|
+
// "lastSz": "0.044378",
|
|
837
|
+
// "askPx": "0.07322",
|
|
838
|
+
// "askSz": "4.2",
|
|
839
|
+
// "bidPx": "0.0732",
|
|
840
|
+
// "bidSz": "6.050058",
|
|
841
|
+
// "open24h": "0.07801",
|
|
842
|
+
// "high24h": "0.07975",
|
|
843
|
+
// "low24h": "0.06019",
|
|
844
|
+
// "volCcy24h": "11788.887619",
|
|
845
|
+
// "vol24h": "167493.829229",
|
|
846
|
+
// "ts": "1621440583784",
|
|
847
|
+
// "sodUtc0": "0.07872",
|
|
848
|
+
// "sodUtc8": "0.07345"
|
|
849
|
+
// }
|
|
850
|
+
//
|
|
851
|
+
const timestamp = this.safeInteger(ticker, 'ts');
|
|
852
|
+
const marketId = this.safeString(ticker, 'instId');
|
|
853
|
+
market = this.safeMarket(marketId, market, '-');
|
|
854
|
+
const symbol = market['symbol'];
|
|
855
|
+
const last = this.safeString(ticker, 'last');
|
|
856
|
+
const open = this.safeString(ticker, 'open24h');
|
|
857
|
+
const spot = this.safeValue(market, 'spot', false);
|
|
858
|
+
const quoteVolume = spot ? this.safeString(ticker, 'volCcy24h') : undefined;
|
|
859
|
+
const baseVolume = this.safeString(ticker, 'vol24h');
|
|
860
|
+
const high = this.safeString(ticker, 'high24h');
|
|
861
|
+
const low = this.safeString(ticker, 'low24h');
|
|
862
|
+
return this.safeTicker({
|
|
863
|
+
'symbol': symbol,
|
|
864
|
+
'timestamp': timestamp,
|
|
865
|
+
'datetime': this.iso8601(timestamp),
|
|
866
|
+
'high': high,
|
|
867
|
+
'low': low,
|
|
868
|
+
'bid': this.safeString(ticker, 'bidPx'),
|
|
869
|
+
'bidVolume': this.safeString(ticker, 'bidSz'),
|
|
870
|
+
'ask': this.safeString(ticker, 'askPx'),
|
|
871
|
+
'askVolume': this.safeString(ticker, 'askSz'),
|
|
872
|
+
'vwap': undefined,
|
|
873
|
+
'open': open,
|
|
874
|
+
'close': last,
|
|
875
|
+
'last': last,
|
|
876
|
+
'previousClose': undefined,
|
|
877
|
+
'change': undefined,
|
|
878
|
+
'percentage': undefined,
|
|
879
|
+
'average': undefined,
|
|
880
|
+
'baseVolume': baseVolume,
|
|
881
|
+
'quoteVolume': quoteVolume,
|
|
882
|
+
'info': ticker,
|
|
883
|
+
}, market);
|
|
884
|
+
}
|
|
885
|
+
async fetchTicker(symbol, params = {}) {
|
|
886
|
+
/**
|
|
887
|
+
* @method
|
|
888
|
+
* @name okcoin#fetchTicker
|
|
889
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-ticker
|
|
890
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
891
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
892
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
893
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
894
|
+
*/
|
|
895
|
+
await this.loadMarkets();
|
|
896
|
+
const market = this.market(symbol);
|
|
897
|
+
const request = {
|
|
898
|
+
'instId': market['id'],
|
|
899
|
+
};
|
|
900
|
+
const response = await this.publicGetMarketTicker(this.extend(request, params));
|
|
901
|
+
const data = this.safeValue(response, 'data', []);
|
|
902
|
+
const first = this.safeValue(data, 0, {});
|
|
903
|
+
//
|
|
904
|
+
// {
|
|
905
|
+
// "code": "0",
|
|
906
|
+
// "msg": "",
|
|
907
|
+
// "data": [
|
|
908
|
+
// {
|
|
909
|
+
// "instType": "SPOT",
|
|
910
|
+
// "instId": "ETH-BTC",
|
|
911
|
+
// "last": "0.07319",
|
|
912
|
+
// "lastSz": "0.044378",
|
|
913
|
+
// "askPx": "0.07322",
|
|
914
|
+
// "askSz": "4.2",
|
|
915
|
+
// "bidPx": "0.0732",
|
|
916
|
+
// "bidSz": "6.050058",
|
|
917
|
+
// "open24h": "0.07801",
|
|
918
|
+
// "high24h": "0.07975",
|
|
919
|
+
// "low24h": "0.06019",
|
|
920
|
+
// "volCcy24h": "11788.887619",
|
|
921
|
+
// "vol24h": "167493.829229",
|
|
922
|
+
// "ts": "1621440583784",
|
|
923
|
+
// "sodUtc0": "0.07872",
|
|
924
|
+
// "sodUtc8": "0.07345"
|
|
925
|
+
// }
|
|
926
|
+
// ]
|
|
927
|
+
// }
|
|
928
|
+
//
|
|
929
|
+
return this.parseTicker(first, market);
|
|
930
|
+
}
|
|
931
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
932
|
+
/**
|
|
933
|
+
* @method
|
|
934
|
+
* @name okcoin#fetchTickers
|
|
935
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-tickers
|
|
936
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
937
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
938
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
939
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
940
|
+
*/
|
|
941
|
+
symbols = this.marketSymbols(symbols);
|
|
942
|
+
const request = {
|
|
943
|
+
'instType': 'SPOT',
|
|
944
|
+
};
|
|
945
|
+
const response = await this.publicGetMarketTickers(this.extend(request, params));
|
|
946
|
+
const data = this.safeValue(response, 'data', []);
|
|
947
|
+
return this.parseTickers(data, symbols, params);
|
|
948
|
+
}
|
|
949
|
+
parseTrade(trade, market = undefined) {
|
|
950
|
+
//
|
|
951
|
+
// public fetchTrades
|
|
952
|
+
//
|
|
953
|
+
// {
|
|
954
|
+
// "instId": "ETH-BTC",
|
|
955
|
+
// "side": "sell",
|
|
956
|
+
// "sz": "0.119501",
|
|
957
|
+
// "px": "0.07065",
|
|
958
|
+
// "tradeId": "15826757",
|
|
959
|
+
// "ts": "1621446178316"
|
|
960
|
+
// }
|
|
961
|
+
//
|
|
962
|
+
// private fetchMyTrades
|
|
963
|
+
//
|
|
964
|
+
// {
|
|
965
|
+
// "side": "buy",
|
|
966
|
+
// "fillSz": "0.007533",
|
|
967
|
+
// "fillPx": "2654.98",
|
|
968
|
+
// "fee": "-0.000007533",
|
|
969
|
+
// "ordId": "317321390244397056",
|
|
970
|
+
// "instType": "SPOT",
|
|
971
|
+
// "instId": "ETH-USDT",
|
|
972
|
+
// "clOrdId": "",
|
|
973
|
+
// "posSide": "net",
|
|
974
|
+
// "billId": "317321390265368576",
|
|
975
|
+
// "tag": "0",
|
|
976
|
+
// "execType": "T",
|
|
977
|
+
// "tradeId": "107601752",
|
|
978
|
+
// "feeCcy": "ETH",
|
|
979
|
+
// "ts": "1621927314985"
|
|
980
|
+
// }
|
|
981
|
+
//
|
|
982
|
+
const id = this.safeString(trade, 'tradeId');
|
|
983
|
+
const marketId = this.safeString(trade, 'instId');
|
|
984
|
+
market = this.safeMarket(marketId, market, '-');
|
|
985
|
+
const symbol = market['symbol'];
|
|
986
|
+
const timestamp = this.safeInteger(trade, 'ts');
|
|
987
|
+
const price = this.safeString2(trade, 'fillPx', 'px');
|
|
988
|
+
const amount = this.safeString2(trade, 'fillSz', 'sz');
|
|
989
|
+
const side = this.safeString(trade, 'side');
|
|
990
|
+
const orderId = this.safeString(trade, 'ordId');
|
|
991
|
+
const feeCostString = this.safeString(trade, 'fee');
|
|
992
|
+
let fee = undefined;
|
|
993
|
+
if (feeCostString !== undefined) {
|
|
994
|
+
const feeCostSigned = Precise["default"].stringNeg(feeCostString);
|
|
995
|
+
const feeCurrencyId = this.safeString(trade, 'feeCcy');
|
|
996
|
+
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
997
|
+
fee = {
|
|
998
|
+
'cost': feeCostSigned,
|
|
999
|
+
'currency': feeCurrencyCode,
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
let takerOrMaker = this.safeString(trade, 'execType');
|
|
1003
|
+
if (takerOrMaker === 'T') {
|
|
1004
|
+
takerOrMaker = 'taker';
|
|
1005
|
+
}
|
|
1006
|
+
else if (takerOrMaker === 'M') {
|
|
1007
|
+
takerOrMaker = 'maker';
|
|
1008
|
+
}
|
|
1009
|
+
return this.safeTrade({
|
|
1010
|
+
'info': trade,
|
|
1011
|
+
'timestamp': timestamp,
|
|
1012
|
+
'datetime': this.iso8601(timestamp),
|
|
1013
|
+
'symbol': symbol,
|
|
1014
|
+
'id': id,
|
|
1015
|
+
'order': orderId,
|
|
1016
|
+
'type': undefined,
|
|
1017
|
+
'takerOrMaker': takerOrMaker,
|
|
1018
|
+
'side': side,
|
|
1019
|
+
'price': price,
|
|
1020
|
+
'amount': amount,
|
|
1021
|
+
'cost': undefined,
|
|
1022
|
+
'fee': fee,
|
|
1023
|
+
}, market);
|
|
1024
|
+
}
|
|
1025
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1026
|
+
/**
|
|
1027
|
+
* @method
|
|
1028
|
+
* @name okcoin#fetchTrades
|
|
1029
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-trades
|
|
1030
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-trades-history
|
|
1031
|
+
* @description get the list of most recent trades for a particular symbol
|
|
1032
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1033
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1034
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1035
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1036
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1037
|
+
*/
|
|
1038
|
+
await this.loadMarkets();
|
|
1039
|
+
const market = this.market(symbol);
|
|
1040
|
+
if ((limit === undefined) || (limit > 100)) {
|
|
1041
|
+
limit = 100; // maximum = default = 100
|
|
1042
|
+
}
|
|
1043
|
+
const request = {
|
|
1044
|
+
'instId': market['id'],
|
|
1045
|
+
};
|
|
1046
|
+
let method = undefined;
|
|
1047
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchTrades', 'method', 'publicGetMarketTrades');
|
|
1048
|
+
let response = undefined;
|
|
1049
|
+
if (method === 'publicGetMarketTrades') {
|
|
1050
|
+
response = await this.publicGetMarketTrades(this.extend(request, params));
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
response = await this.publicGetMarketHistoryTrades(this.extend(request, params));
|
|
1054
|
+
}
|
|
1055
|
+
const data = this.safeValue(response, 'data', []);
|
|
1056
|
+
return this.parseTrades(data, market, since, limit);
|
|
1057
|
+
}
|
|
1058
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1059
|
+
//
|
|
1060
|
+
// [
|
|
1061
|
+
// "1678928760000", // timestamp
|
|
1062
|
+
// "24341.4", // open
|
|
1063
|
+
// "24344", // high
|
|
1064
|
+
// "24313.2", // low
|
|
1065
|
+
// "24323", // close
|
|
1066
|
+
// "628", // contract volume
|
|
1067
|
+
// "2.5819", // base volume
|
|
1068
|
+
// "62800", // quote volume
|
|
1069
|
+
// "0" // candlestick state
|
|
1070
|
+
// ]
|
|
1071
|
+
//
|
|
1072
|
+
return [
|
|
1073
|
+
this.safeInteger(ohlcv, 0),
|
|
1074
|
+
this.safeNumber(ohlcv, 1),
|
|
1075
|
+
this.safeNumber(ohlcv, 2),
|
|
1076
|
+
this.safeNumber(ohlcv, 3),
|
|
1077
|
+
this.safeNumber(ohlcv, 4),
|
|
1078
|
+
this.safeNumber(ohlcv, 5),
|
|
1079
|
+
];
|
|
1080
|
+
}
|
|
1081
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1082
|
+
/**
|
|
1083
|
+
* @method
|
|
1084
|
+
* @name okcoin#fetchOHLCV
|
|
1085
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-candlesticks
|
|
1086
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-candlesticks-history
|
|
1087
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1088
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1089
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1090
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1091
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1092
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1093
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1094
|
+
*/
|
|
1095
|
+
await this.loadMarkets();
|
|
1096
|
+
const market = this.market(symbol);
|
|
1097
|
+
const duration = this.parseTimeframe(timeframe);
|
|
1098
|
+
const options = this.safeValue(this.options, 'fetchOHLCV', {});
|
|
1099
|
+
let bar = this.safeString(this.timeframes, timeframe, timeframe);
|
|
1100
|
+
const timezone = this.safeString(options, 'timezone', 'UTC');
|
|
1101
|
+
if ((timezone === 'UTC') && (duration >= 21600)) { // if utc and timeframe >= 6h
|
|
1102
|
+
bar += timezone.toLowerCase();
|
|
1103
|
+
}
|
|
1104
|
+
const request = {
|
|
1105
|
+
'instId': market['id'],
|
|
1106
|
+
'bar': bar,
|
|
1107
|
+
'limit': limit,
|
|
1108
|
+
};
|
|
1109
|
+
let method = undefined;
|
|
1110
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'method', 'publicGetMarketCandles');
|
|
1111
|
+
let response = undefined;
|
|
1112
|
+
if (method === 'publicGetMarketCandles') {
|
|
1113
|
+
response = await this.publicGetMarketCandles(this.extend(request, params));
|
|
1114
|
+
}
|
|
1115
|
+
else {
|
|
1116
|
+
response = await this.publicGetMarketHistoryCandles(this.extend(request, params));
|
|
1117
|
+
}
|
|
1118
|
+
const data = this.safeValue(response, 'data', []);
|
|
1119
|
+
return this.parseOHLCVs(data, market, timeframe, since, limit);
|
|
1120
|
+
}
|
|
1121
|
+
parseAccountBalance(response) {
|
|
1122
|
+
//
|
|
1123
|
+
// account
|
|
1124
|
+
//
|
|
1125
|
+
// [
|
|
1126
|
+
// {
|
|
1127
|
+
// "balance": 0,
|
|
1128
|
+
// "available": 0,
|
|
1129
|
+
// "currency": "BTC",
|
|
1130
|
+
// "hold": 0
|
|
1131
|
+
// },
|
|
1132
|
+
// {
|
|
1133
|
+
// "balance": 0,
|
|
1134
|
+
// "available": 0,
|
|
1135
|
+
// "currency": "ETH",
|
|
1136
|
+
// "hold": 0
|
|
1137
|
+
// }
|
|
1138
|
+
// ]
|
|
1139
|
+
//
|
|
1140
|
+
// spot
|
|
1141
|
+
//
|
|
1142
|
+
// [
|
|
1143
|
+
// {
|
|
1144
|
+
// "frozen": "0",
|
|
1145
|
+
// "hold": "0",
|
|
1146
|
+
// "id": "2149632",
|
|
1147
|
+
// "currency": "BTC",
|
|
1148
|
+
// "balance": "0.0000000497717339",
|
|
1149
|
+
// "available": "0.0000000497717339",
|
|
1150
|
+
// "holds": "0"
|
|
1151
|
+
// },
|
|
1152
|
+
// {
|
|
1153
|
+
// "frozen": "0",
|
|
1154
|
+
// "hold": "0",
|
|
1155
|
+
// "id": "2149632",
|
|
1156
|
+
// "currency": "ICN",
|
|
1157
|
+
// "balance": "0.00000000925",
|
|
1158
|
+
// "available": "0.00000000925",
|
|
1159
|
+
// "holds": "0"
|
|
1160
|
+
// }
|
|
1161
|
+
// ]
|
|
1162
|
+
//
|
|
1163
|
+
const result = {
|
|
1164
|
+
'info': response,
|
|
1165
|
+
'timestamp': undefined,
|
|
1166
|
+
'datetime': undefined,
|
|
1167
|
+
};
|
|
1168
|
+
for (let i = 0; i < response.length; i++) {
|
|
1169
|
+
const balance = response[i];
|
|
1170
|
+
const currencyId = this.safeString(balance, 'currency');
|
|
1171
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1172
|
+
const account = this.account();
|
|
1173
|
+
account['total'] = this.safeString(balance, 'balance');
|
|
1174
|
+
account['used'] = this.safeString(balance, 'hold');
|
|
1175
|
+
account['free'] = this.safeString(balance, 'available');
|
|
1176
|
+
result[code] = account;
|
|
1177
|
+
}
|
|
1178
|
+
return this.safeBalance(result);
|
|
1179
|
+
}
|
|
1180
|
+
async fetchBalance(params = {}) {
|
|
1181
|
+
/**
|
|
1182
|
+
* @method
|
|
1183
|
+
* @name okcoin#fetchBalance
|
|
1184
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1185
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1186
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1187
|
+
*/
|
|
1188
|
+
await this.loadMarkets();
|
|
1189
|
+
const [marketType, query] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
|
|
1190
|
+
const request = {
|
|
1191
|
+
// 'ccy': 'BTC,ETH', // comma-separated list of currency ids
|
|
1192
|
+
};
|
|
1193
|
+
let response = undefined;
|
|
1194
|
+
if (marketType === 'funding') {
|
|
1195
|
+
response = await this.privateGetAssetBalances(this.extend(request, query));
|
|
1196
|
+
}
|
|
1197
|
+
else {
|
|
1198
|
+
response = await this.privateGetAccountBalance(this.extend(request, query));
|
|
1199
|
+
}
|
|
1200
|
+
//
|
|
1201
|
+
// {
|
|
1202
|
+
// "code": "0",
|
|
1203
|
+
// "data": [
|
|
1204
|
+
// {
|
|
1205
|
+
// "category": "1",
|
|
1206
|
+
// "delivery": "",
|
|
1207
|
+
// "exercise": "",
|
|
1208
|
+
// "instType": "SPOT",
|
|
1209
|
+
// "level": "Lv1",
|
|
1210
|
+
// "maker": "-0.0008",
|
|
1211
|
+
// "taker": "-0.001",
|
|
1212
|
+
// "ts": "1639043138472"
|
|
1213
|
+
// }
|
|
1214
|
+
// ],
|
|
1215
|
+
// "msg": ""
|
|
1216
|
+
// }
|
|
1217
|
+
//
|
|
1218
|
+
if (marketType === 'funding') {
|
|
1219
|
+
return this.parseFundingBalance(response);
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
return this.parseTradingBalance(response);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
parseTradingBalance(response) {
|
|
1226
|
+
const result = { 'info': response };
|
|
1227
|
+
const data = this.safeValue(response, 'data', []);
|
|
1228
|
+
const first = this.safeValue(data, 0, {});
|
|
1229
|
+
const timestamp = this.safeInteger(first, 'uTime');
|
|
1230
|
+
const details = this.safeValue(first, 'details', []);
|
|
1231
|
+
for (let i = 0; i < details.length; i++) {
|
|
1232
|
+
const balance = details[i];
|
|
1233
|
+
const currencyId = this.safeString(balance, 'ccy');
|
|
1234
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1235
|
+
const account = this.account();
|
|
1236
|
+
// it may be incorrect to use total, free and used for swap accounts
|
|
1237
|
+
const eq = this.safeString(balance, 'eq');
|
|
1238
|
+
const availEq = this.safeString(balance, 'availEq');
|
|
1239
|
+
if ((eq === undefined) || (availEq === undefined)) {
|
|
1240
|
+
account['free'] = this.safeString(balance, 'availBal');
|
|
1241
|
+
account['used'] = this.safeString(balance, 'frozenBal');
|
|
1242
|
+
}
|
|
1243
|
+
else {
|
|
1244
|
+
account['total'] = eq;
|
|
1245
|
+
account['free'] = availEq;
|
|
1246
|
+
}
|
|
1247
|
+
result[code] = account;
|
|
1248
|
+
}
|
|
1249
|
+
result['timestamp'] = timestamp;
|
|
1250
|
+
result['datetime'] = this.iso8601(timestamp);
|
|
1251
|
+
return this.safeBalance(result);
|
|
1252
|
+
}
|
|
1253
|
+
parseFundingBalance(response) {
|
|
1254
|
+
const result = { 'info': response };
|
|
1255
|
+
const data = this.safeValue(response, 'data', []);
|
|
1256
|
+
for (let i = 0; i < data.length; i++) {
|
|
1257
|
+
const balance = data[i];
|
|
1258
|
+
const currencyId = this.safeString(balance, 'ccy');
|
|
1259
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1260
|
+
const account = this.account();
|
|
1261
|
+
// it may be incorrect to use total, free and used for swap accounts
|
|
1262
|
+
account['total'] = this.safeString(balance, 'bal');
|
|
1263
|
+
account['free'] = this.safeString(balance, 'availBal');
|
|
1264
|
+
account['used'] = this.safeString(balance, 'frozenBal');
|
|
1265
|
+
result[code] = account;
|
|
1266
|
+
}
|
|
1267
|
+
return this.safeBalance(result);
|
|
1268
|
+
}
|
|
1269
|
+
async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
|
|
1270
|
+
/**
|
|
1271
|
+
* @method
|
|
1272
|
+
* @name okcoin#createMarketBuyOrderWithCost
|
|
1273
|
+
* @description create a market buy order by providing the symbol and cost
|
|
1274
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-order
|
|
1275
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1276
|
+
* @param {float} cost how much you want to trade in units of the quote currency
|
|
1277
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1278
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1279
|
+
*/
|
|
1280
|
+
await this.loadMarkets();
|
|
1281
|
+
const market = this.market(symbol);
|
|
1282
|
+
if (!market['spot']) {
|
|
1283
|
+
throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
|
|
1284
|
+
}
|
|
1285
|
+
params['createMarketBuyOrderRequiresPrice'] = false;
|
|
1286
|
+
params['tgtCcy'] = 'quote_ccy';
|
|
1287
|
+
return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
|
|
1288
|
+
}
|
|
1289
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1290
|
+
/**
|
|
1291
|
+
* @method
|
|
1292
|
+
* @name okcoin#createOrder
|
|
1293
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-order
|
|
1294
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-algo-order
|
|
1295
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-multiple-orders
|
|
1296
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
|
|
1297
|
+
* @description create a trade order
|
|
1298
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1299
|
+
* @param {string} type 'market' or 'limit'
|
|
1300
|
+
* @param {string} side 'buy' or 'sell'
|
|
1301
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1302
|
+
* @param {float} price the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1303
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1304
|
+
* @param {bool} [params.reduceOnly] MARGIN orders only, or swap/future orders in net mode
|
|
1305
|
+
* @param {bool} [params.postOnly] true to place a post only order
|
|
1306
|
+
* @param {float} [params.triggerPrice] conditional orders only, the price at which the order is to be triggered
|
|
1307
|
+
* @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered (perpetual swap markets only)
|
|
1308
|
+
* @param {float} [params.takeProfit.triggerPrice] take profit trigger price
|
|
1309
|
+
* @param {float} [params.takeProfit.price] used for take profit limit orders, not used for take profit market price orders
|
|
1310
|
+
* @param {string} [params.takeProfit.type] 'market' or 'limit' used to specify the take profit price type
|
|
1311
|
+
* @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered (perpetual swap markets only)
|
|
1312
|
+
* @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
|
|
1313
|
+
* @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders
|
|
1314
|
+
* @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type
|
|
1315
|
+
* @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
|
|
1316
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1317
|
+
*/
|
|
1318
|
+
await this.loadMarkets();
|
|
1319
|
+
const market = this.market(symbol);
|
|
1320
|
+
let request = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
1321
|
+
let method = this.safeString(this.options, 'createOrder', 'privatePostTradeBatchOrders');
|
|
1322
|
+
const requestOrdType = this.safeString(request, 'ordType');
|
|
1323
|
+
if ((requestOrdType === 'trigger') || (requestOrdType === 'conditional') || (type === 'oco') || (type === 'move_order_stop') || (type === 'iceberg') || (type === 'twap')) {
|
|
1324
|
+
method = 'privatePostTradeOrderAlgo';
|
|
1325
|
+
}
|
|
1326
|
+
if (method === 'privatePostTradeBatchOrders') {
|
|
1327
|
+
// keep the request body the same
|
|
1328
|
+
// submit a single order in an array to the batch order endpoint
|
|
1329
|
+
// because it has a lower ratelimit
|
|
1330
|
+
request = [request];
|
|
1331
|
+
}
|
|
1332
|
+
let response = undefined;
|
|
1333
|
+
if (method === 'privatePostTradeOrder') {
|
|
1334
|
+
response = await this.privatePostTradeOrder(request);
|
|
1335
|
+
}
|
|
1336
|
+
else if (method === 'privatePostTradeOrderAlgo') {
|
|
1337
|
+
response = await this.privatePostTradeOrderAlgo(request);
|
|
1338
|
+
}
|
|
1339
|
+
else if (method === 'privatePostTradeBatchOrders') {
|
|
1340
|
+
response = await this.privatePostTradeBatchOrders(request);
|
|
1341
|
+
}
|
|
1342
|
+
else {
|
|
1343
|
+
throw new errors.ExchangeError(this.id + ' createOrder() this.options["createOrder"] must be either privatePostTradeBatchOrders or privatePostTradeOrder or privatePostTradeOrderAlgo');
|
|
1344
|
+
}
|
|
1345
|
+
const data = this.safeValue(response, 'data', []);
|
|
1346
|
+
const first = this.safeValue(data, 0);
|
|
1347
|
+
const order = this.parseOrder(first, market);
|
|
1348
|
+
order['type'] = type;
|
|
1349
|
+
order['side'] = side;
|
|
1350
|
+
return order;
|
|
1351
|
+
}
|
|
1352
|
+
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1353
|
+
const market = this.market(symbol);
|
|
1354
|
+
const request = {
|
|
1355
|
+
'instId': market['id'],
|
|
1356
|
+
// 'ccy': currency['id'], // only applicable to cross MARGIN orders in single-currency margin
|
|
1357
|
+
// 'clOrdId': clientOrderId, // up to 32 characters, must be unique
|
|
1358
|
+
// 'tag': tag, // up to 8 characters
|
|
1359
|
+
'side': side,
|
|
1360
|
+
// 'posSide': 'long', // long, short, // required in the long/short mode, and can only be long or short (only for future or swap)
|
|
1361
|
+
'ordType': type,
|
|
1362
|
+
// 'ordType': type, // privatePostTradeOrder: market, limit, post_only, fok, ioc, optimal_limit_ioc
|
|
1363
|
+
// 'ordType': type, // privatePostTradeOrderAlgo: conditional, oco, trigger, move_order_stop, iceberg, twap
|
|
1364
|
+
// 'sz': this.amountToPrecision (symbol, amount),
|
|
1365
|
+
// 'px': this.priceToPrecision (symbol, price), // limit orders only
|
|
1366
|
+
// 'reduceOnly': false,
|
|
1367
|
+
//
|
|
1368
|
+
// 'triggerPx': 10, // stopPrice (trigger orders)
|
|
1369
|
+
// 'orderPx': 10, // Order price if -1, the order will be executed at the market price. (trigger orders)
|
|
1370
|
+
// 'triggerPxType': 'last', // Conditional default is last, mark or index (trigger orders)
|
|
1371
|
+
//
|
|
1372
|
+
// 'tpTriggerPx': 10, // takeProfitPrice (conditional orders)
|
|
1373
|
+
// 'tpTriggerPxType': 'last', // Conditional default is last, mark or index (conditional orders)
|
|
1374
|
+
// 'tpOrdPx': 10, // Order price for Take-Profit orders, if -1 will be executed at market price (conditional orders)
|
|
1375
|
+
//
|
|
1376
|
+
// 'slTriggerPx': 10, // stopLossPrice (conditional orders)
|
|
1377
|
+
// 'slTriggerPxType': 'last', // Conditional default is last, mark or index (conditional orders)
|
|
1378
|
+
// 'slOrdPx': 10, // Order price for Stop-Loss orders, if -1 will be executed at market price (conditional orders)
|
|
1379
|
+
};
|
|
1380
|
+
const triggerPrice = this.safeValueN(params, ['triggerPrice', 'stopPrice', 'triggerPx']);
|
|
1381
|
+
const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
|
|
1382
|
+
const takeProfitPrice = this.safeValue2(params, 'takeProfitPrice', 'tpTriggerPx');
|
|
1383
|
+
const tpOrdPx = this.safeValue(params, 'tpOrdPx', price);
|
|
1384
|
+
const tpTriggerPxType = this.safeString(params, 'tpTriggerPxType', 'last');
|
|
1385
|
+
const stopLossPrice = this.safeValue2(params, 'stopLossPrice', 'slTriggerPx');
|
|
1386
|
+
const slOrdPx = this.safeValue(params, 'slOrdPx', price);
|
|
1387
|
+
const slTriggerPxType = this.safeString(params, 'slTriggerPxType', 'last');
|
|
1388
|
+
const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
|
|
1389
|
+
const stopLoss = this.safeValue(params, 'stopLoss');
|
|
1390
|
+
const stopLossDefined = (stopLoss !== undefined);
|
|
1391
|
+
const takeProfit = this.safeValue(params, 'takeProfit');
|
|
1392
|
+
const takeProfitDefined = (takeProfit !== undefined);
|
|
1393
|
+
const defaultMarginMode = this.safeString2(this.options, 'defaultMarginMode', 'marginMode', 'cross');
|
|
1394
|
+
let marginMode = this.safeString2(params, 'marginMode', 'tdMode'); // cross or isolated, tdMode not ommited so as to be extended into the request
|
|
1395
|
+
let margin = false;
|
|
1396
|
+
if ((marginMode !== undefined) && (marginMode !== 'cash')) {
|
|
1397
|
+
margin = true;
|
|
1398
|
+
}
|
|
1399
|
+
else {
|
|
1400
|
+
marginMode = defaultMarginMode;
|
|
1401
|
+
margin = this.safeValue(params, 'margin', false);
|
|
1402
|
+
}
|
|
1403
|
+
if (margin) {
|
|
1404
|
+
const defaultCurrency = (side === 'buy') ? market['quote'] : market['base'];
|
|
1405
|
+
const currency = this.safeString(params, 'ccy', defaultCurrency);
|
|
1406
|
+
request['ccy'] = this.safeCurrencyCode(currency);
|
|
1407
|
+
}
|
|
1408
|
+
const tradeMode = margin ? marginMode : 'cash';
|
|
1409
|
+
request['tdMode'] = tradeMode;
|
|
1410
|
+
const isMarketOrder = type === 'market';
|
|
1411
|
+
let postOnly = false;
|
|
1412
|
+
[postOnly, params] = this.handlePostOnly(isMarketOrder, type === 'post_only', params);
|
|
1413
|
+
params = this.omit(params, ['currency', 'ccy', 'marginMode', 'timeInForce', 'stopPrice', 'triggerPrice', 'clientOrderId', 'stopLossPrice', 'takeProfitPrice', 'slOrdPx', 'tpOrdPx', 'margin', 'stopLoss', 'takeProfit']);
|
|
1414
|
+
const ioc = (timeInForce === 'IOC') || (type === 'ioc');
|
|
1415
|
+
const fok = (timeInForce === 'FOK') || (type === 'fok');
|
|
1416
|
+
const trigger = (triggerPrice !== undefined) || (type === 'trigger');
|
|
1417
|
+
const conditional = (stopLossPrice !== undefined) || (takeProfitPrice !== undefined) || (type === 'conditional');
|
|
1418
|
+
const marketIOC = (isMarketOrder && ioc) || (type === 'optimal_limit_ioc');
|
|
1419
|
+
const defaultTgtCcy = this.safeString(this.options, 'tgtCcy', 'base_ccy');
|
|
1420
|
+
const tgtCcy = this.safeString(params, 'tgtCcy', defaultTgtCcy);
|
|
1421
|
+
if ((!margin)) {
|
|
1422
|
+
request['tgtCcy'] = tgtCcy;
|
|
1423
|
+
}
|
|
1424
|
+
if (isMarketOrder || marketIOC) {
|
|
1425
|
+
request['ordType'] = 'market';
|
|
1426
|
+
if (side === 'buy') {
|
|
1427
|
+
// spot market buy: "sz" can refer either to base currency units or to quote currency units
|
|
1428
|
+
// see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order
|
|
1429
|
+
if (tgtCcy === 'quote_ccy') {
|
|
1430
|
+
// quote_ccy: sz refers to units of quote currency
|
|
1431
|
+
let quoteAmount = undefined;
|
|
1432
|
+
let createMarketBuyOrderRequiresPrice = true;
|
|
1433
|
+
[createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
|
|
1434
|
+
const cost = this.safeNumber2(params, 'cost', 'sz');
|
|
1435
|
+
params = this.omit(params, ['cost', 'sz']);
|
|
1436
|
+
if (cost !== undefined) {
|
|
1437
|
+
quoteAmount = this.costToPrecision(symbol, cost);
|
|
1438
|
+
}
|
|
1439
|
+
else if (createMarketBuyOrderRequiresPrice) {
|
|
1440
|
+
if (price === undefined) {
|
|
1441
|
+
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');
|
|
1442
|
+
}
|
|
1443
|
+
else {
|
|
1444
|
+
const amountString = this.numberToString(amount);
|
|
1445
|
+
const priceString = this.numberToString(price);
|
|
1446
|
+
const costRequest = Precise["default"].stringMul(amountString, priceString);
|
|
1447
|
+
quoteAmount = this.costToPrecision(symbol, costRequest);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
else {
|
|
1451
|
+
quoteAmount = this.costToPrecision(symbol, amount);
|
|
1452
|
+
}
|
|
1453
|
+
request['sz'] = quoteAmount;
|
|
1454
|
+
}
|
|
1455
|
+
else {
|
|
1456
|
+
request['sz'] = this.amountToPrecision(symbol, amount);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
else {
|
|
1460
|
+
request['sz'] = this.amountToPrecision(symbol, amount);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
else {
|
|
1464
|
+
request['sz'] = this.amountToPrecision(symbol, amount);
|
|
1465
|
+
if ((!trigger) && (!conditional)) {
|
|
1466
|
+
request['px'] = this.priceToPrecision(symbol, price);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
if (postOnly) {
|
|
1470
|
+
request['ordType'] = 'post_only';
|
|
1471
|
+
}
|
|
1472
|
+
else if (ioc && !marketIOC) {
|
|
1473
|
+
request['ordType'] = 'ioc';
|
|
1474
|
+
}
|
|
1475
|
+
else if (fok) {
|
|
1476
|
+
request['ordType'] = 'fok';
|
|
1477
|
+
}
|
|
1478
|
+
else if (stopLossDefined || takeProfitDefined) {
|
|
1479
|
+
if (stopLossDefined) {
|
|
1480
|
+
const stopLossTriggerPrice = this.safeValueN(stopLoss, ['triggerPrice', 'stopPrice', 'slTriggerPx']);
|
|
1481
|
+
if (stopLossTriggerPrice === undefined) {
|
|
1482
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"], or params["stopLoss"]["stopPrice"], or params["stopLoss"]["slTriggerPx"] for a stop loss order');
|
|
1483
|
+
}
|
|
1484
|
+
request['slTriggerPx'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
|
|
1485
|
+
const stopLossLimitPrice = this.safeValueN(stopLoss, ['price', 'stopLossPrice', 'slOrdPx']);
|
|
1486
|
+
const stopLossOrderType = this.safeString(stopLoss, 'type');
|
|
1487
|
+
if (stopLossOrderType !== undefined) {
|
|
1488
|
+
const stopLossLimitOrderType = (stopLossOrderType === 'limit');
|
|
1489
|
+
const stopLossMarketOrderType = (stopLossOrderType === 'market');
|
|
1490
|
+
if ((!stopLossLimitOrderType) && (!stopLossMarketOrderType)) {
|
|
1491
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() params["stopLoss"]["type"] must be either "limit" or "market"');
|
|
1492
|
+
}
|
|
1493
|
+
else if (stopLossLimitOrderType) {
|
|
1494
|
+
if (stopLossLimitPrice === undefined) {
|
|
1495
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a limit price in params["stopLoss"]["price"] or params["stopLoss"]["slOrdPx"] for a stop loss limit order');
|
|
1496
|
+
}
|
|
1497
|
+
else {
|
|
1498
|
+
request['slOrdPx'] = this.priceToPrecision(symbol, stopLossLimitPrice);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
else if (stopLossOrderType === 'market') {
|
|
1502
|
+
request['slOrdPx'] = '-1';
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
else if (stopLossLimitPrice !== undefined) {
|
|
1506
|
+
request['slOrdPx'] = this.priceToPrecision(symbol, stopLossLimitPrice); // limit sl order
|
|
1507
|
+
}
|
|
1508
|
+
else {
|
|
1509
|
+
request['slOrdPx'] = '-1'; // market sl order
|
|
1510
|
+
}
|
|
1511
|
+
const stopLossTriggerPriceType = this.safeString2(stopLoss, 'triggerPriceType', 'slTriggerPxType', 'last');
|
|
1512
|
+
if (stopLossTriggerPriceType !== undefined) {
|
|
1513
|
+
if ((stopLossTriggerPriceType !== 'last') && (stopLossTriggerPriceType !== 'index') && (stopLossTriggerPriceType !== 'mark')) {
|
|
1514
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() stop loss trigger price type must be one of "last", "index" or "mark"');
|
|
1515
|
+
}
|
|
1516
|
+
request['slTriggerPxType'] = stopLossTriggerPriceType;
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
if (takeProfitDefined) {
|
|
1520
|
+
const takeProfitTriggerPrice = this.safeValueN(takeProfit, ['triggerPrice', 'stopPrice', 'tpTriggerPx']);
|
|
1521
|
+
if (takeProfitTriggerPrice === undefined) {
|
|
1522
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"], or params["takeProfit"]["stopPrice"], or params["takeProfit"]["tpTriggerPx"] for a take profit order');
|
|
1523
|
+
}
|
|
1524
|
+
request['tpTriggerPx'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
|
|
1525
|
+
const takeProfitLimitPrice = this.safeValueN(takeProfit, ['price', 'takeProfitPrice', 'tpOrdPx']);
|
|
1526
|
+
const takeProfitOrderType = this.safeString(takeProfit, 'type');
|
|
1527
|
+
if (takeProfitOrderType !== undefined) {
|
|
1528
|
+
const takeProfitLimitOrderType = (takeProfitOrderType === 'limit');
|
|
1529
|
+
const takeProfitMarketOrderType = (takeProfitOrderType === 'market');
|
|
1530
|
+
if ((!takeProfitLimitOrderType) && (!takeProfitMarketOrderType)) {
|
|
1531
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() params["takeProfit"]["type"] must be either "limit" or "market"');
|
|
1532
|
+
}
|
|
1533
|
+
else if (takeProfitLimitOrderType) {
|
|
1534
|
+
if (takeProfitLimitPrice === undefined) {
|
|
1535
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a limit price in params["takeProfit"]["price"] or params["takeProfit"]["tpOrdPx"] for a take profit limit order');
|
|
1536
|
+
}
|
|
1537
|
+
else {
|
|
1538
|
+
request['tpOrdPx'] = this.priceToPrecision(symbol, takeProfitLimitPrice);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
else if (takeProfitOrderType === 'market') {
|
|
1542
|
+
request['tpOrdPx'] = '-1';
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
else if (takeProfitLimitPrice !== undefined) {
|
|
1546
|
+
request['tpOrdPx'] = this.priceToPrecision(symbol, takeProfitLimitPrice); // limit tp order
|
|
1547
|
+
}
|
|
1548
|
+
else {
|
|
1549
|
+
request['tpOrdPx'] = '-1'; // market tp order
|
|
1550
|
+
}
|
|
1551
|
+
const takeProfitTriggerPriceType = this.safeString2(takeProfit, 'triggerPriceType', 'tpTriggerPxType', 'last');
|
|
1552
|
+
if (takeProfitTriggerPriceType !== undefined) {
|
|
1553
|
+
if ((takeProfitTriggerPriceType !== 'last') && (takeProfitTriggerPriceType !== 'index') && (takeProfitTriggerPriceType !== 'mark')) {
|
|
1554
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() take profit trigger price type must be one of "last", "index" or "mark"');
|
|
1555
|
+
}
|
|
1556
|
+
request['tpTriggerPxType'] = takeProfitTriggerPriceType;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
else if (trigger) {
|
|
1561
|
+
request['ordType'] = 'trigger';
|
|
1562
|
+
request['triggerPx'] = this.priceToPrecision(symbol, triggerPrice);
|
|
1563
|
+
request['orderPx'] = isMarketOrder ? '-1' : this.priceToPrecision(symbol, price);
|
|
1564
|
+
}
|
|
1565
|
+
else if (conditional) {
|
|
1566
|
+
request['ordType'] = 'conditional';
|
|
1567
|
+
const twoWayCondition = ((takeProfitPrice !== undefined) && (stopLossPrice !== undefined));
|
|
1568
|
+
// if TP and SL are sent together
|
|
1569
|
+
// as ordType 'conditional' only stop-loss order will be applied
|
|
1570
|
+
if (twoWayCondition) {
|
|
1571
|
+
request['ordType'] = 'oco';
|
|
1572
|
+
}
|
|
1573
|
+
if (takeProfitPrice !== undefined) {
|
|
1574
|
+
request['tpTriggerPx'] = this.priceToPrecision(symbol, takeProfitPrice);
|
|
1575
|
+
request['tpOrdPx'] = (tpOrdPx === undefined) ? '-1' : this.priceToPrecision(symbol, tpOrdPx);
|
|
1576
|
+
request['tpTriggerPxType'] = tpTriggerPxType;
|
|
1577
|
+
}
|
|
1578
|
+
if (stopLossPrice !== undefined) {
|
|
1579
|
+
request['slTriggerPx'] = this.priceToPrecision(symbol, stopLossPrice);
|
|
1580
|
+
request['slOrdPx'] = (slOrdPx === undefined) ? '-1' : this.priceToPrecision(symbol, slOrdPx);
|
|
1581
|
+
request['slTriggerPxType'] = slTriggerPxType;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
if (clientOrderId === undefined) {
|
|
1585
|
+
const brokerId = this.safeString(this.options, 'brokerId');
|
|
1586
|
+
if (brokerId !== undefined) {
|
|
1587
|
+
request['clOrdId'] = brokerId + this.uuid16();
|
|
1588
|
+
request['tag'] = brokerId;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
else {
|
|
1592
|
+
request['clOrdId'] = clientOrderId;
|
|
1593
|
+
params = this.omit(params, ['clOrdId', 'clientOrderId']);
|
|
1594
|
+
}
|
|
1595
|
+
return this.extend(request, params);
|
|
1596
|
+
}
|
|
1597
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1598
|
+
/**
|
|
1599
|
+
* @method
|
|
1600
|
+
* @name okcoin#cancelOrder
|
|
1601
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-order
|
|
1602
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-algo-order
|
|
1603
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
|
|
1604
|
+
* @description cancels an open order
|
|
1605
|
+
* @param {string} id order id
|
|
1606
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
1607
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1608
|
+
* @param {bool} [params.stop] True if cancel trigger or conditional orders
|
|
1609
|
+
* @param {bool} [params.advanced] True if canceling advanced orders only
|
|
1610
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1611
|
+
*/
|
|
1612
|
+
if (symbol === undefined) {
|
|
1613
|
+
throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
|
|
1614
|
+
}
|
|
1615
|
+
await this.loadMarkets();
|
|
1616
|
+
const stop = this.safeValue2(params, 'stop', 'trigger');
|
|
1617
|
+
const advanced = this.safeValue(params, 'advanced');
|
|
1618
|
+
if (stop || advanced) {
|
|
1619
|
+
const orderInner = await this.cancelOrders([id], symbol, params);
|
|
1620
|
+
return this.safeValue(orderInner, 0);
|
|
1621
|
+
}
|
|
1622
|
+
const market = this.market(symbol);
|
|
1623
|
+
const request = {
|
|
1624
|
+
'instId': market['id'],
|
|
1625
|
+
// 'ordId': id, // either ordId or clOrdId is required
|
|
1626
|
+
// 'clOrdId': clientOrderId,
|
|
1627
|
+
};
|
|
1628
|
+
const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
|
|
1629
|
+
if (clientOrderId !== undefined) {
|
|
1630
|
+
request['clOrdId'] = clientOrderId;
|
|
1631
|
+
}
|
|
1632
|
+
else {
|
|
1633
|
+
request['ordId'] = id.toString();
|
|
1634
|
+
}
|
|
1635
|
+
const query = this.omit(params, ['clOrdId', 'clientOrderId']);
|
|
1636
|
+
const response = await this.privatePostTradeCancelOrder(this.extend(request, query));
|
|
1637
|
+
// {"code":"0","data":[{"clOrdId":"","ordId":"317251910906576896","sCode":"0","sMsg":""}],"msg":""}
|
|
1638
|
+
const data = this.safeValue(response, 'data', []);
|
|
1639
|
+
const order = this.safeValue(data, 0);
|
|
1640
|
+
return this.parseOrder(order, market);
|
|
1641
|
+
}
|
|
1642
|
+
parseIds(ids) {
|
|
1643
|
+
/**
|
|
1644
|
+
* @ignore
|
|
1645
|
+
* @method
|
|
1646
|
+
* @name okx#parseIds
|
|
1647
|
+
* @param {string[]|string} ids order ids
|
|
1648
|
+
* @returns {string[]} list of order ids
|
|
1649
|
+
*/
|
|
1650
|
+
if (typeof ids === 'string') {
|
|
1651
|
+
return ids.split(',');
|
|
1652
|
+
}
|
|
1653
|
+
else {
|
|
1654
|
+
return ids;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
async cancelOrders(ids, symbol = undefined, params = {}) {
|
|
1658
|
+
/**
|
|
1659
|
+
* @method
|
|
1660
|
+
* @name okcoin#cancelOrders
|
|
1661
|
+
* @description cancel multiple orders
|
|
1662
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-multiple-orders
|
|
1663
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-algo-order
|
|
1664
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
|
|
1665
|
+
* @param {string[]} ids order ids
|
|
1666
|
+
* @param {string} symbol unified market symbol
|
|
1667
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1668
|
+
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1669
|
+
*/
|
|
1670
|
+
if (symbol === undefined) {
|
|
1671
|
+
throw new errors.ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
|
|
1672
|
+
}
|
|
1673
|
+
await this.loadMarkets();
|
|
1674
|
+
const stop = this.safeValue2(params, 'stop', 'trigger');
|
|
1675
|
+
const advanced = this.safeValue(params, 'advanced');
|
|
1676
|
+
params = this.omit(params, ['stop', 'trigger', 'advanced']);
|
|
1677
|
+
const market = this.market(symbol);
|
|
1678
|
+
const request = [];
|
|
1679
|
+
const clientOrderIds = this.parseIds(this.safeValue2(params, 'clOrdId', 'clientOrderId'));
|
|
1680
|
+
const algoIds = this.parseIds(this.safeValue(params, 'algoId'));
|
|
1681
|
+
if (clientOrderIds === undefined) {
|
|
1682
|
+
ids = this.parseIds(ids);
|
|
1683
|
+
if (algoIds !== undefined) {
|
|
1684
|
+
for (let i = 0; i < algoIds.length; i++) {
|
|
1685
|
+
request.push({
|
|
1686
|
+
'algoId': algoIds[i],
|
|
1687
|
+
'instId': market['id'],
|
|
1688
|
+
});
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
for (let i = 0; i < ids.length; i++) {
|
|
1692
|
+
if (stop || advanced) {
|
|
1693
|
+
request.push({
|
|
1694
|
+
'algoId': ids[i],
|
|
1695
|
+
'instId': market['id'],
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
else {
|
|
1699
|
+
request.push({
|
|
1700
|
+
'ordId': ids[i],
|
|
1701
|
+
'instId': market['id'],
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
else {
|
|
1707
|
+
for (let i = 0; i < clientOrderIds.length; i++) {
|
|
1708
|
+
request.push({
|
|
1709
|
+
'instId': market['id'],
|
|
1710
|
+
'clOrdId': clientOrderIds[i],
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
let response = undefined;
|
|
1715
|
+
if (stop) {
|
|
1716
|
+
response = await this.privatePostTradeCancelAlgos(request);
|
|
1717
|
+
}
|
|
1718
|
+
else if (advanced) {
|
|
1719
|
+
response = await this.privatePostTradeCancelAdvanceAlgos(request);
|
|
1720
|
+
}
|
|
1721
|
+
else {
|
|
1722
|
+
response = await this.privatePostTradeCancelBatchOrders(request); // * dont extend with params, otherwise ARRAY will be turned into OBJECT
|
|
1723
|
+
}
|
|
1724
|
+
//
|
|
1725
|
+
// {
|
|
1726
|
+
// "code": "0",
|
|
1727
|
+
// "data": [
|
|
1728
|
+
// {
|
|
1729
|
+
// "clOrdId": "e123456789ec4dBC1123456ba123b45e",
|
|
1730
|
+
// "ordId": "405071912345641543",
|
|
1731
|
+
// "sCode": "0",
|
|
1732
|
+
// "sMsg": ""
|
|
1733
|
+
// },
|
|
1734
|
+
// ...
|
|
1735
|
+
// ],
|
|
1736
|
+
// "msg": ""
|
|
1737
|
+
// }
|
|
1738
|
+
//
|
|
1739
|
+
//
|
|
1740
|
+
const ordersData = this.safeValue(response, 'data', []);
|
|
1741
|
+
return this.parseOrders(ordersData, market, undefined, undefined, params);
|
|
1742
|
+
}
|
|
1743
|
+
parseOrderStatus(status) {
|
|
1744
|
+
const statuses = {
|
|
1745
|
+
'canceled': 'canceled',
|
|
1746
|
+
'live': 'open',
|
|
1747
|
+
'partially_filled': 'open',
|
|
1748
|
+
'filled': 'closed',
|
|
1749
|
+
'effective': 'closed',
|
|
1750
|
+
};
|
|
1751
|
+
return this.safeString(statuses, status, status);
|
|
1752
|
+
}
|
|
1753
|
+
parseOrder(order, market = undefined) {
|
|
1754
|
+
//
|
|
1755
|
+
// createOrder
|
|
1756
|
+
//
|
|
1757
|
+
// {
|
|
1758
|
+
// "clOrdId": "oktswap6",
|
|
1759
|
+
// "ordId": "312269865356374016",
|
|
1760
|
+
// "tag": "",
|
|
1761
|
+
// "sCode": "0",
|
|
1762
|
+
// "sMsg": ""
|
|
1763
|
+
// }
|
|
1764
|
+
//
|
|
1765
|
+
// editOrder
|
|
1766
|
+
//
|
|
1767
|
+
// {
|
|
1768
|
+
// "clOrdId": "e847386590ce4dBCc1a045253497a547",
|
|
1769
|
+
// "ordId": "559176536793178112",
|
|
1770
|
+
// "reqId": "",
|
|
1771
|
+
// "sCode": "0",
|
|
1772
|
+
// "sMsg": ""
|
|
1773
|
+
// }
|
|
1774
|
+
//
|
|
1775
|
+
// Spot and Swap fetchOrder, fetchOpenOrders
|
|
1776
|
+
//
|
|
1777
|
+
// {
|
|
1778
|
+
// "accFillSz": "0",
|
|
1779
|
+
// "avgPx": "",
|
|
1780
|
+
// "cTime": "1621910749815",
|
|
1781
|
+
// "category": "normal",
|
|
1782
|
+
// "ccy": "",
|
|
1783
|
+
// "clOrdId": "",
|
|
1784
|
+
// "fee": "0",
|
|
1785
|
+
// "feeCcy": "ETH",
|
|
1786
|
+
// "fillPx": "",
|
|
1787
|
+
// "fillSz": "0",
|
|
1788
|
+
// "fillTime": "",
|
|
1789
|
+
// "instId": "ETH-USDT",
|
|
1790
|
+
// "instType": "SPOT",
|
|
1791
|
+
// "lever": "",
|
|
1792
|
+
// "ordId": "317251910906576896",
|
|
1793
|
+
// "ordType": "limit",
|
|
1794
|
+
// "pnl": "0",
|
|
1795
|
+
// "posSide": "net",
|
|
1796
|
+
// "px": "2000",
|
|
1797
|
+
// "rebate": "0",
|
|
1798
|
+
// "rebateCcy": "USDT",
|
|
1799
|
+
// "side": "buy",
|
|
1800
|
+
// "slOrdPx": "",
|
|
1801
|
+
// "slTriggerPx": "",
|
|
1802
|
+
// "state": "live",
|
|
1803
|
+
// "sz": "0.001",
|
|
1804
|
+
// "tag": "",
|
|
1805
|
+
// "tdMode": "cash",
|
|
1806
|
+
// "tpOrdPx": "",
|
|
1807
|
+
// "tpTriggerPx": "",
|
|
1808
|
+
// "tradeId": "",
|
|
1809
|
+
// "uTime": "1621910749815"
|
|
1810
|
+
// }
|
|
1811
|
+
//
|
|
1812
|
+
// Algo Order fetchOpenOrders, fetchCanceledOrders, fetchClosedOrders
|
|
1813
|
+
//
|
|
1814
|
+
// {
|
|
1815
|
+
// "activePx": "",
|
|
1816
|
+
// "activePxType": "",
|
|
1817
|
+
// "actualPx": "",
|
|
1818
|
+
// "actualSide": "buy",
|
|
1819
|
+
// "actualSz": "0",
|
|
1820
|
+
// "algoId": "431375349042380800",
|
|
1821
|
+
// "cTime": "1649119897778",
|
|
1822
|
+
// "callbackRatio": "",
|
|
1823
|
+
// "callbackSpread": "",
|
|
1824
|
+
// "ccy": "",
|
|
1825
|
+
// "ctVal": "0.01",
|
|
1826
|
+
// "instId": "BTC-USDT-SWAP",
|
|
1827
|
+
// "instType": "SWAP",
|
|
1828
|
+
// "last": "46538.9",
|
|
1829
|
+
// "lever": "125",
|
|
1830
|
+
// "moveTriggerPx": "",
|
|
1831
|
+
// "notionalUsd": "467.059",
|
|
1832
|
+
// "ordId": "",
|
|
1833
|
+
// "ordPx": "50000",
|
|
1834
|
+
// "ordType": "trigger",
|
|
1835
|
+
// "posSide": "long",
|
|
1836
|
+
// "pxLimit": "",
|
|
1837
|
+
// "pxSpread": "",
|
|
1838
|
+
// "pxVar": "",
|
|
1839
|
+
// "side": "buy",
|
|
1840
|
+
// "slOrdPx": "",
|
|
1841
|
+
// "slTriggerPx": "",
|
|
1842
|
+
// "slTriggerPxType": "",
|
|
1843
|
+
// "state": "live",
|
|
1844
|
+
// "sz": "1",
|
|
1845
|
+
// "szLimit": "",
|
|
1846
|
+
// "tag": "",
|
|
1847
|
+
// "tdMode": "isolated",
|
|
1848
|
+
// "tgtCcy": "",
|
|
1849
|
+
// "timeInterval": "",
|
|
1850
|
+
// "tpOrdPx": "",
|
|
1851
|
+
// "tpTriggerPx": "",
|
|
1852
|
+
// "tpTriggerPxType": "",
|
|
1853
|
+
// "triggerPx": "50000",
|
|
1854
|
+
// "triggerPxType": "last",
|
|
1855
|
+
// "triggerTime": "",
|
|
1856
|
+
// "uly": "BTC-USDT"
|
|
1857
|
+
// }
|
|
1858
|
+
//
|
|
1859
|
+
const id = this.safeString2(order, 'algoId', 'ordId');
|
|
1860
|
+
const timestamp = this.safeInteger(order, 'cTime');
|
|
1861
|
+
const lastUpdateTimestamp = this.safeInteger(order, 'uTime');
|
|
1862
|
+
const lastTradeTimestamp = this.safeInteger(order, 'fillTime');
|
|
1863
|
+
const side = this.safeString(order, 'side');
|
|
1864
|
+
let type = this.safeString(order, 'ordType');
|
|
1865
|
+
let postOnly = undefined;
|
|
1866
|
+
let timeInForce = undefined;
|
|
1867
|
+
if (type === 'post_only') {
|
|
1868
|
+
postOnly = true;
|
|
1869
|
+
type = 'limit';
|
|
1870
|
+
}
|
|
1871
|
+
else if (type === 'fok') {
|
|
1872
|
+
timeInForce = 'FOK';
|
|
1873
|
+
type = 'limit';
|
|
1874
|
+
}
|
|
1875
|
+
else if (type === 'ioc') {
|
|
1876
|
+
timeInForce = 'IOC';
|
|
1877
|
+
type = 'limit';
|
|
1878
|
+
}
|
|
1879
|
+
const marketId = this.safeString(order, 'instId');
|
|
1880
|
+
market = this.safeMarket(marketId, market);
|
|
1881
|
+
const symbol = this.safeSymbol(marketId, market, '-');
|
|
1882
|
+
const filled = this.safeString(order, 'accFillSz');
|
|
1883
|
+
const price = this.safeString2(order, 'px', 'ordPx');
|
|
1884
|
+
const average = this.safeString(order, 'avgPx');
|
|
1885
|
+
const status = this.parseOrderStatus(this.safeString(order, 'state'));
|
|
1886
|
+
const feeCostString = this.safeString(order, 'fee');
|
|
1887
|
+
let amount = undefined;
|
|
1888
|
+
let cost = undefined;
|
|
1889
|
+
// spot market buy: "sz" can refer either to base currency units or to quote currency units
|
|
1890
|
+
// see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order
|
|
1891
|
+
const defaultTgtCcy = this.safeString(this.options, 'tgtCcy', 'base_ccy');
|
|
1892
|
+
const tgtCcy = this.safeString(order, 'tgtCcy', defaultTgtCcy);
|
|
1893
|
+
if ((side === 'buy') && (type === 'market') && (tgtCcy === 'quote_ccy')) {
|
|
1894
|
+
// "sz" refers to the cost
|
|
1895
|
+
cost = this.safeString(order, 'sz');
|
|
1896
|
+
}
|
|
1897
|
+
else {
|
|
1898
|
+
// "sz" refers to the trade currency amount
|
|
1899
|
+
amount = this.safeString(order, 'sz');
|
|
1900
|
+
}
|
|
1901
|
+
let fee = undefined;
|
|
1902
|
+
if (feeCostString !== undefined) {
|
|
1903
|
+
const feeCostSigned = Precise["default"].stringNeg(feeCostString);
|
|
1904
|
+
const feeCurrencyId = this.safeString(order, 'feeCcy');
|
|
1905
|
+
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
1906
|
+
fee = {
|
|
1907
|
+
'cost': this.parseNumber(feeCostSigned),
|
|
1908
|
+
'currency': feeCurrencyCode,
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
let clientOrderId = this.safeString(order, 'clOrdId');
|
|
1912
|
+
if ((clientOrderId !== undefined) && (clientOrderId.length < 1)) {
|
|
1913
|
+
clientOrderId = undefined; // fix empty clientOrderId string
|
|
1914
|
+
}
|
|
1915
|
+
const stopLossPrice = this.safeNumber2(order, 'slTriggerPx', 'slOrdPx');
|
|
1916
|
+
const takeProfitPrice = this.safeNumber2(order, 'tpTriggerPx', 'tpOrdPx');
|
|
1917
|
+
const stopPrice = this.safeNumberN(order, ['triggerPx', 'moveTriggerPx']);
|
|
1918
|
+
const reduceOnlyRaw = this.safeString(order, 'reduceOnly');
|
|
1919
|
+
let reduceOnly = false;
|
|
1920
|
+
if (reduceOnly !== undefined) {
|
|
1921
|
+
reduceOnly = (reduceOnlyRaw === 'true');
|
|
1922
|
+
}
|
|
1923
|
+
return this.safeOrder({
|
|
1924
|
+
'info': order,
|
|
1925
|
+
'id': id,
|
|
1926
|
+
'clientOrderId': clientOrderId,
|
|
1927
|
+
'timestamp': timestamp,
|
|
1928
|
+
'datetime': this.iso8601(timestamp),
|
|
1929
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
|
1930
|
+
'lastUpdateTimestamp': lastUpdateTimestamp,
|
|
1931
|
+
'symbol': symbol,
|
|
1932
|
+
'type': type,
|
|
1933
|
+
'timeInForce': timeInForce,
|
|
1934
|
+
'postOnly': postOnly,
|
|
1935
|
+
'side': side,
|
|
1936
|
+
'price': price,
|
|
1937
|
+
'stopLossPrice': stopLossPrice,
|
|
1938
|
+
'takeProfitPrice': takeProfitPrice,
|
|
1939
|
+
'stopPrice': stopPrice,
|
|
1940
|
+
'triggerPrice': stopPrice,
|
|
1941
|
+
'average': average,
|
|
1942
|
+
'cost': cost,
|
|
1943
|
+
'amount': amount,
|
|
1944
|
+
'filled': filled,
|
|
1945
|
+
'remaining': undefined,
|
|
1946
|
+
'status': status,
|
|
1947
|
+
'fee': fee,
|
|
1948
|
+
'trades': undefined,
|
|
1949
|
+
'reduceOnly': reduceOnly,
|
|
1950
|
+
}, market);
|
|
1951
|
+
}
|
|
1952
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1953
|
+
/**
|
|
1954
|
+
* @method
|
|
1955
|
+
* @name okcoin#fetchOrder
|
|
1956
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-details
|
|
1957
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-list
|
|
1958
|
+
* @description fetches information on an order made by the user
|
|
1959
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
1960
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1961
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1962
|
+
*/
|
|
1963
|
+
if (symbol === undefined) {
|
|
1964
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
|
|
1965
|
+
}
|
|
1966
|
+
await this.loadMarkets();
|
|
1967
|
+
const market = this.market(symbol);
|
|
1968
|
+
const request = {
|
|
1969
|
+
'instId': market['id'],
|
|
1970
|
+
// 'clOrdId': 'abcdef12345', // optional, [a-z0-9]{1,32}
|
|
1971
|
+
// 'ordId': id,
|
|
1972
|
+
};
|
|
1973
|
+
const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
|
|
1974
|
+
const stop = this.safeValue2(params, 'stop', 'trigger');
|
|
1975
|
+
if (stop) {
|
|
1976
|
+
if (clientOrderId !== undefined) {
|
|
1977
|
+
request['algoClOrdId'] = clientOrderId;
|
|
1978
|
+
}
|
|
1979
|
+
else {
|
|
1980
|
+
request['algoId'] = id;
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
else {
|
|
1984
|
+
if (clientOrderId !== undefined) {
|
|
1985
|
+
request['clOrdId'] = clientOrderId;
|
|
1986
|
+
}
|
|
1987
|
+
else {
|
|
1988
|
+
request['ordId'] = id;
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
const query = this.omit(params, ['clientOrderId', 'stop', 'trigger']);
|
|
1992
|
+
let response = undefined;
|
|
1993
|
+
if (stop) {
|
|
1994
|
+
response = await this.privateGetTradeOrderAlgo(this.extend(request, query));
|
|
1995
|
+
}
|
|
1996
|
+
else {
|
|
1997
|
+
response = await this.privateGetTradeOrder(this.extend(request, query));
|
|
1998
|
+
}
|
|
1999
|
+
const data = this.safeValue(response, 'data', []);
|
|
2000
|
+
const order = this.safeValue(data, 0);
|
|
2001
|
+
return this.parseOrder(order);
|
|
2002
|
+
}
|
|
2003
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2004
|
+
/**
|
|
2005
|
+
* @method
|
|
2006
|
+
* @name okcoin#fetchOpenOrders
|
|
2007
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-list
|
|
2008
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-list
|
|
2009
|
+
* @description fetch all unfilled currently open orders
|
|
2010
|
+
* @param {string} symbol unified market symbol
|
|
2011
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
2012
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
2013
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2014
|
+
* @param {bool} [params.stop] True if fetching trigger or conditional orders
|
|
2015
|
+
* @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
|
|
2016
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2017
|
+
*/
|
|
2018
|
+
await this.loadMarkets();
|
|
2019
|
+
const request = {
|
|
2020
|
+
// 'instId': market['id'],
|
|
2021
|
+
// 'ordType': 'limit', // market, limit, post_only, fok, ioc, comma-separated, stop orders: conditional, oco, trigger, move_order_stop, iceberg, or twap
|
|
2022
|
+
// 'state': 'live', // live, partially_filled
|
|
2023
|
+
// 'after': orderId,
|
|
2024
|
+
// 'before': orderId,
|
|
2025
|
+
// 'limit': limit, // default 100, max 100
|
|
2026
|
+
};
|
|
2027
|
+
let market = undefined;
|
|
2028
|
+
if (symbol !== undefined) {
|
|
2029
|
+
market = this.market(symbol);
|
|
2030
|
+
request['instId'] = market['id'];
|
|
2031
|
+
}
|
|
2032
|
+
if (limit !== undefined) {
|
|
2033
|
+
request['limit'] = limit; // default 100, max 100
|
|
2034
|
+
}
|
|
2035
|
+
const ordType = this.safeString(params, 'ordType');
|
|
2036
|
+
const stop = this.safeValue(params, 'stop') || (this.safeString(params, 'ordType') !== undefined);
|
|
2037
|
+
if (stop && (ordType === undefined)) {
|
|
2038
|
+
request['ordType'] = 'trigger'; // default to trigger
|
|
2039
|
+
}
|
|
2040
|
+
params = this.omit(params, ['stop']);
|
|
2041
|
+
let response = undefined;
|
|
2042
|
+
if (stop) {
|
|
2043
|
+
response = await this.privateGetTradeOrdersAlgoPending(this.extend(request, params));
|
|
2044
|
+
}
|
|
2045
|
+
else {
|
|
2046
|
+
response = await this.privateGetTradeOrdersPending(this.extend(request, params));
|
|
2047
|
+
}
|
|
2048
|
+
const data = this.safeValue(response, 'data', []);
|
|
2049
|
+
return this.parseOrders(data, market, since, limit);
|
|
2050
|
+
}
|
|
2051
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2052
|
+
/**
|
|
2053
|
+
* @method
|
|
2054
|
+
* @name okcoin#fetchClosedOrders
|
|
2055
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-history
|
|
2056
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-history-last-3-months
|
|
2057
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-history-last-7-days
|
|
2058
|
+
* @description fetches information on multiple closed orders made by the user
|
|
2059
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
2060
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2061
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
2062
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2063
|
+
* @param {bool} [params.stop] True if fetching trigger or conditional orders
|
|
2064
|
+
* @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
|
|
2065
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2066
|
+
*/
|
|
2067
|
+
await this.loadMarkets();
|
|
2068
|
+
const request = {
|
|
2069
|
+
'instType': 'SPOT',
|
|
2070
|
+
};
|
|
2071
|
+
let market = undefined;
|
|
2072
|
+
if (symbol !== undefined) {
|
|
2073
|
+
market = this.market(symbol);
|
|
2074
|
+
request['instId'] = market['id'];
|
|
2075
|
+
}
|
|
2076
|
+
const ordType = this.safeString(params, 'ordType');
|
|
2077
|
+
const stop = this.safeValue(params, 'stop') || (this.safeString(params, 'ordType') !== undefined);
|
|
2078
|
+
if (stop && (ordType === undefined)) {
|
|
2079
|
+
request['ordType'] = 'trigger'; // default to trigger
|
|
2080
|
+
}
|
|
2081
|
+
params = this.omit(params, ['stop']);
|
|
2082
|
+
let response = undefined;
|
|
2083
|
+
if (stop) {
|
|
2084
|
+
response = await this.privateGetTradeOrdersAlgoHistory(this.extend(request, params));
|
|
2085
|
+
}
|
|
2086
|
+
else {
|
|
2087
|
+
let method = undefined;
|
|
2088
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'method', 'privateGetTradeOrdersHistory');
|
|
2089
|
+
if (method === 'privateGetTradeOrdersHistory') {
|
|
2090
|
+
response = await this.privateGetTradeOrdersHistory(this.extend(request, params));
|
|
2091
|
+
}
|
|
2092
|
+
else {
|
|
2093
|
+
response = await this.privateGetTradeOrdersHistoryArchive(this.extend(request, params));
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
// {
|
|
2097
|
+
// "code": "0",
|
|
2098
|
+
// "data": [
|
|
2099
|
+
// {
|
|
2100
|
+
// "accFillSz": "0",
|
|
2101
|
+
// "avgPx": "",
|
|
2102
|
+
// "cTime": "1621910749815",
|
|
2103
|
+
// "category": "normal",
|
|
2104
|
+
// "ccy": "",
|
|
2105
|
+
// "clOrdId": "",
|
|
2106
|
+
// "fee": "0",
|
|
2107
|
+
// "feeCcy": "ETH",
|
|
2108
|
+
// "fillPx": "",
|
|
2109
|
+
// "fillSz": "0",
|
|
2110
|
+
// "fillTime": "",
|
|
2111
|
+
// "instId": "ETH-USDT",
|
|
2112
|
+
// "instType": "SPOT",
|
|
2113
|
+
// "lever": "",
|
|
2114
|
+
// "ordId": "317251910906576896",
|
|
2115
|
+
// "ordType": "limit",
|
|
2116
|
+
// "pnl": "0",
|
|
2117
|
+
// "posSide": "net",
|
|
2118
|
+
// "px":"20 00",
|
|
2119
|
+
// "rebate": "0",
|
|
2120
|
+
// "rebateCcy": "USDT",
|
|
2121
|
+
// "side": "buy",
|
|
2122
|
+
// "slOrdPx": "",
|
|
2123
|
+
// "slTriggerPx": "",
|
|
2124
|
+
// "state": "live",
|
|
2125
|
+
// "sz":"0. 001",
|
|
2126
|
+
// "tag": "",
|
|
2127
|
+
// "tdMode": "cash",
|
|
2128
|
+
// "tpOrdPx": "",
|
|
2129
|
+
// "tpTriggerPx": "",
|
|
2130
|
+
// "tradeId": "",
|
|
2131
|
+
// "uTime": "1621910749815"
|
|
2132
|
+
// }
|
|
2133
|
+
// ],
|
|
2134
|
+
// "msg":""
|
|
2135
|
+
// }
|
|
2136
|
+
//
|
|
2137
|
+
const data = this.safeValue(response, 'data', []);
|
|
2138
|
+
return this.parseOrders(data, market, since, limit);
|
|
2139
|
+
}
|
|
2140
|
+
parseDepositAddress(depositAddress, currency = undefined) {
|
|
2141
|
+
//
|
|
2142
|
+
// {
|
|
2143
|
+
// "addr": "okbtothemoon",
|
|
2144
|
+
// "memo": "971668", // may be missing
|
|
2145
|
+
// "tag":"52055", // may be missing
|
|
2146
|
+
// "pmtId": "", // may be missing
|
|
2147
|
+
// "ccy": "BTC",
|
|
2148
|
+
// "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account
|
|
2149
|
+
// "selected": true
|
|
2150
|
+
// }
|
|
2151
|
+
//
|
|
2152
|
+
// {
|
|
2153
|
+
// "ccy":"usdt-erc20",
|
|
2154
|
+
// "to":"6",
|
|
2155
|
+
// "addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa",
|
|
2156
|
+
// "selected":true
|
|
2157
|
+
// }
|
|
2158
|
+
//
|
|
2159
|
+
// {
|
|
2160
|
+
// "chain": "ETH-OKExChain",
|
|
2161
|
+
// "addrEx": { "comment": "6040348" }, // some currencies like TON may have this field,
|
|
2162
|
+
// "ctAddr": "72315c",
|
|
2163
|
+
// "ccy": "ETH",
|
|
2164
|
+
// "to": "6",
|
|
2165
|
+
// "addr": "0x1c9f2244d1ccaa060bd536827c18925db10db102",
|
|
2166
|
+
// "selected": true
|
|
2167
|
+
// }
|
|
2168
|
+
//
|
|
2169
|
+
const address = this.safeString(depositAddress, 'addr');
|
|
2170
|
+
let tag = this.safeStringN(depositAddress, ['tag', 'pmtId', 'memo']);
|
|
2171
|
+
if (tag === undefined) {
|
|
2172
|
+
const addrEx = this.safeValue(depositAddress, 'addrEx', {});
|
|
2173
|
+
tag = this.safeString(addrEx, 'comment');
|
|
2174
|
+
}
|
|
2175
|
+
const currencyId = this.safeString(depositAddress, 'ccy');
|
|
2176
|
+
currency = this.safeCurrency(currencyId, currency);
|
|
2177
|
+
const code = currency['code'];
|
|
2178
|
+
const chain = this.safeString(depositAddress, 'chain');
|
|
2179
|
+
const networkId = chain.replace(currencyId + '-', '');
|
|
2180
|
+
const network = this.networkIdToCode(networkId);
|
|
2181
|
+
// inconsistent naming responses from exchange
|
|
2182
|
+
// with respect to network naming provided in currency info vs address chain-names and ids
|
|
2183
|
+
//
|
|
2184
|
+
// response from address endpoint:
|
|
2185
|
+
// {
|
|
2186
|
+
// "chain": "USDT-Polygon",
|
|
2187
|
+
// "ctAddr": "",
|
|
2188
|
+
// "ccy": "USDT",
|
|
2189
|
+
// "to":"6" ,
|
|
2190
|
+
// "addr": "0x1903441e386cc49d937f6302955b5feb4286dcfa",
|
|
2191
|
+
// "selected": true
|
|
2192
|
+
// }
|
|
2193
|
+
// network information from currency['networks'] field:
|
|
2194
|
+
// Polygon: {
|
|
2195
|
+
// "info": {
|
|
2196
|
+
// "canDep": false,
|
|
2197
|
+
// "canInternal": false,
|
|
2198
|
+
// "canWd": false,
|
|
2199
|
+
// "ccy": "USDT",
|
|
2200
|
+
// "chain": "USDT-Polygon-Bridge",
|
|
2201
|
+
// "mainNet": false,
|
|
2202
|
+
// "maxFee": "26.879528",
|
|
2203
|
+
// "minFee": "13.439764",
|
|
2204
|
+
// "minWd": "0.001",
|
|
2205
|
+
// "name": ''
|
|
2206
|
+
// },
|
|
2207
|
+
// "id": "USDT-Polygon-Bridge",
|
|
2208
|
+
// "network": "Polygon",
|
|
2209
|
+
// "active": false,
|
|
2210
|
+
// "deposit": false,
|
|
2211
|
+
// "withdraw": false,
|
|
2212
|
+
// "fee": 13.439764,
|
|
2213
|
+
// "precision": undefined,
|
|
2214
|
+
// "limits": {
|
|
2215
|
+
// "withdraw": {
|
|
2216
|
+
// "min": 0.001,
|
|
2217
|
+
// "max": undefined
|
|
2218
|
+
// }
|
|
2219
|
+
// }
|
|
2220
|
+
// },
|
|
2221
|
+
//
|
|
2222
|
+
this.checkAddress(address);
|
|
2223
|
+
return {
|
|
2224
|
+
'currency': code,
|
|
2225
|
+
'address': address,
|
|
2226
|
+
'tag': tag,
|
|
2227
|
+
'network': network,
|
|
2228
|
+
'info': depositAddress,
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2231
|
+
async fetchDepositAddress(code, params = {}) {
|
|
2232
|
+
/**
|
|
2233
|
+
* @method
|
|
2234
|
+
* @name okx#fetchDepositAddress
|
|
2235
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
2236
|
+
* @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
|
|
2237
|
+
* @param {string} code unified currency code
|
|
2238
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2239
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
2240
|
+
*/
|
|
2241
|
+
await this.loadMarkets();
|
|
2242
|
+
const defaultNetwork = this.safeString(this.options, 'defaultNetwork', 'ERC20');
|
|
2243
|
+
const networkId = this.safeString(params, 'network', defaultNetwork);
|
|
2244
|
+
const networkCode = this.networkIdToCode(networkId);
|
|
2245
|
+
params = this.omit(params, 'network');
|
|
2246
|
+
const response = await this.fetchDepositAddressesByNetwork(code, params);
|
|
2247
|
+
const result = this.safeValue(response, networkCode);
|
|
2248
|
+
if (result === undefined) {
|
|
2249
|
+
throw new errors.InvalidAddress(this.id + ' fetchDepositAddress() cannot find ' + networkCode + ' deposit address for ' + code);
|
|
2250
|
+
}
|
|
2251
|
+
return result;
|
|
2252
|
+
}
|
|
2253
|
+
async fetchDepositAddressesByNetwork(code, params = {}) {
|
|
2254
|
+
/**
|
|
2255
|
+
* @method
|
|
2256
|
+
* @name okx#fetchDepositAddressesByNetwork
|
|
2257
|
+
* @description fetch a dictionary of addresses for a currency, indexed by network
|
|
2258
|
+
* @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
|
|
2259
|
+
* @param {string} code unified currency code of the currency for the deposit address
|
|
2260
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2261
|
+
* @returns {object} a dictionary of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure} indexed by the network
|
|
2262
|
+
*/
|
|
2263
|
+
await this.loadMarkets();
|
|
2264
|
+
const currency = this.currency(code);
|
|
2265
|
+
const request = {
|
|
2266
|
+
'ccy': currency['id'],
|
|
2267
|
+
};
|
|
2268
|
+
const response = await this.privateGetAssetDepositAddress(this.extend(request, params));
|
|
2269
|
+
//
|
|
2270
|
+
// {
|
|
2271
|
+
// "code": "0",
|
|
2272
|
+
// "msg": "",
|
|
2273
|
+
// "data": [
|
|
2274
|
+
// {
|
|
2275
|
+
// "addr": "okbtothemoon",
|
|
2276
|
+
// "memo": "971668", // may be missing
|
|
2277
|
+
// "tag":"52055", // may be missing
|
|
2278
|
+
// "pmtId": "", // may be missing
|
|
2279
|
+
// "ccy": "BTC",
|
|
2280
|
+
// "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account
|
|
2281
|
+
// "selected": true
|
|
2282
|
+
// },
|
|
2283
|
+
// // {"ccy":"usdt-erc20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
|
|
2284
|
+
// // {"ccy":"usdt-trc20","to":"6","addr":"TRrd5SiSZrfQVRKm4e9SRSbn2LNTYqCjqx","selected":true},
|
|
2285
|
+
// // {"ccy":"usdt_okexchain","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
|
|
2286
|
+
// // {"ccy":"usdt_kip20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
|
|
2287
|
+
// ]
|
|
2288
|
+
// }
|
|
2289
|
+
//
|
|
2290
|
+
const data = this.safeValue(response, 'data', []);
|
|
2291
|
+
const filtered = this.filterBy(data, 'selected', true);
|
|
2292
|
+
const parsed = this.parseDepositAddresses(filtered, [currency['code']], false);
|
|
2293
|
+
return this.indexBy(parsed, 'network');
|
|
2294
|
+
}
|
|
2295
|
+
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
2296
|
+
/**
|
|
2297
|
+
* @method
|
|
2298
|
+
* @name okcoin#transfer
|
|
2299
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-funds-transfer
|
|
2300
|
+
* @description transfer currency internally between wallets on the same account
|
|
2301
|
+
* @param {string} code unified currency code
|
|
2302
|
+
* @param {float} amount amount to transfer
|
|
2303
|
+
* @param {string} fromAccount account to transfer from
|
|
2304
|
+
* @param {string} toAccount account to transfer to
|
|
2305
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2306
|
+
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
2307
|
+
*/
|
|
2308
|
+
await this.loadMarkets();
|
|
2309
|
+
const currency = this.currency(code);
|
|
2310
|
+
const accountsByType = this.safeValue(this.options, 'accountsByType', {});
|
|
2311
|
+
const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
|
|
2312
|
+
const toId = this.safeString(accountsByType, toAccount, toAccount);
|
|
2313
|
+
const request = {
|
|
2314
|
+
'ccy': currency['id'],
|
|
2315
|
+
'amt': this.currencyToPrecision(code, amount),
|
|
2316
|
+
'type': '0',
|
|
2317
|
+
'from': fromId,
|
|
2318
|
+
'to': toId, // beneficiary account, 6: Funding account, 18: Trading account
|
|
2319
|
+
// 'subAcct': 'sub-account-name', // optional, only required when type is 1, 2 or 4
|
|
2320
|
+
// 'loanTrans': false, // Whether or not borrowed coins can be transferred out under Multi-currency margin and Portfolio margin. The default is false
|
|
2321
|
+
// 'clientId': 'client-supplied id', // A combination of case-sensitive alphanumerics, all numbers, or all letters of up to 32 characters
|
|
2322
|
+
// 'omitPosRisk': false, // Ignore position risk. Default is false. Applicable to Portfolio margin
|
|
2323
|
+
};
|
|
2324
|
+
if (fromId === 'master') {
|
|
2325
|
+
request['type'] = '1';
|
|
2326
|
+
request['subAcct'] = toId;
|
|
2327
|
+
request['from'] = this.safeString(params, 'from', '6');
|
|
2328
|
+
request['to'] = this.safeString(params, 'to', '6');
|
|
2329
|
+
}
|
|
2330
|
+
else if (toId === 'master') {
|
|
2331
|
+
request['type'] = '2';
|
|
2332
|
+
request['subAcct'] = fromId;
|
|
2333
|
+
request['from'] = this.safeString(params, 'from', '6');
|
|
2334
|
+
request['to'] = this.safeString(params, 'to', '6');
|
|
2335
|
+
}
|
|
2336
|
+
const response = await this.privatePostAssetTransfer(this.extend(request, params));
|
|
2337
|
+
//
|
|
2338
|
+
// {
|
|
2339
|
+
// "code": "0",
|
|
2340
|
+
// "msg": "",
|
|
2341
|
+
// "data": [
|
|
2342
|
+
// {
|
|
2343
|
+
// "transId": "754147",
|
|
2344
|
+
// "ccy": "USDT",
|
|
2345
|
+
// "from": "6",
|
|
2346
|
+
// "amt": "0.1",
|
|
2347
|
+
// "to": "18"
|
|
2348
|
+
// }
|
|
2349
|
+
// ]
|
|
2350
|
+
// }
|
|
2351
|
+
//
|
|
2352
|
+
const data = this.safeValue(response, 'data', []);
|
|
2353
|
+
const rawTransfer = this.safeValue(data, 0, {});
|
|
2354
|
+
return this.parseTransfer(rawTransfer, currency);
|
|
2355
|
+
}
|
|
2356
|
+
parseTransfer(transfer, currency = undefined) {
|
|
2357
|
+
//
|
|
2358
|
+
// transfer
|
|
2359
|
+
//
|
|
2360
|
+
// {
|
|
2361
|
+
// "transId": "754147",
|
|
2362
|
+
// "ccy": "USDT",
|
|
2363
|
+
// "from": "6",
|
|
2364
|
+
// "amt": "0.1",
|
|
2365
|
+
// "to": "18"
|
|
2366
|
+
// }
|
|
2367
|
+
//
|
|
2368
|
+
// fetchTransfer
|
|
2369
|
+
//
|
|
2370
|
+
// {
|
|
2371
|
+
// "amt": "5",
|
|
2372
|
+
// "ccy": "USDT",
|
|
2373
|
+
// "from": "18",
|
|
2374
|
+
// "instId": "",
|
|
2375
|
+
// "state": "success",
|
|
2376
|
+
// "subAcct": "",
|
|
2377
|
+
// "to": "6",
|
|
2378
|
+
// "toInstId": "",
|
|
2379
|
+
// "transId": "464424732",
|
|
2380
|
+
// "type": "0"
|
|
2381
|
+
// }
|
|
2382
|
+
//
|
|
2383
|
+
// fetchTransfers
|
|
2384
|
+
//
|
|
2385
|
+
// {
|
|
2386
|
+
// "bal": "70.6874353780312913",
|
|
2387
|
+
// "balChg": "-4.0000000000000000", // negative means "to funding", positive meand "from funding"
|
|
2388
|
+
// "billId": "588900695232225299",
|
|
2389
|
+
// "ccy": "USDT",
|
|
2390
|
+
// "execType": "",
|
|
2391
|
+
// "fee": "",
|
|
2392
|
+
// "from": "18",
|
|
2393
|
+
// "instId": "",
|
|
2394
|
+
// "instType": "",
|
|
2395
|
+
// "mgnMode": "",
|
|
2396
|
+
// "notes": "To Funding Account",
|
|
2397
|
+
// "ordId": "",
|
|
2398
|
+
// "pnl": "",
|
|
2399
|
+
// "posBal": "",
|
|
2400
|
+
// "posBalChg": "",
|
|
2401
|
+
// "price": "0",
|
|
2402
|
+
// "subType": "12",
|
|
2403
|
+
// "sz": "-4",
|
|
2404
|
+
// "to": "6",
|
|
2405
|
+
// "ts": "1686676866989",
|
|
2406
|
+
// "type": "1"
|
|
2407
|
+
// }
|
|
2408
|
+
//
|
|
2409
|
+
const id = this.safeString2(transfer, 'transId', 'billId');
|
|
2410
|
+
const currencyId = this.safeString(transfer, 'ccy');
|
|
2411
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
2412
|
+
let amount = this.safeNumber(transfer, 'amt');
|
|
2413
|
+
const fromAccountId = this.safeString(transfer, 'from');
|
|
2414
|
+
const toAccountId = this.safeString(transfer, 'to');
|
|
2415
|
+
const accountsById = this.safeValue(this.options, 'accountsById', {});
|
|
2416
|
+
const timestamp = this.safeInteger(transfer, 'ts', this.milliseconds());
|
|
2417
|
+
const balanceChange = this.safeString(transfer, 'sz');
|
|
2418
|
+
if (balanceChange !== undefined) {
|
|
2419
|
+
amount = this.parseNumber(Precise["default"].stringAbs(balanceChange));
|
|
2420
|
+
}
|
|
2421
|
+
return {
|
|
2422
|
+
'info': transfer,
|
|
2423
|
+
'id': id,
|
|
2424
|
+
'timestamp': timestamp,
|
|
2425
|
+
'datetime': this.iso8601(timestamp),
|
|
2426
|
+
'currency': code,
|
|
2427
|
+
'amount': amount,
|
|
2428
|
+
'fromAccount': this.safeString(accountsById, fromAccountId),
|
|
2429
|
+
'toAccount': this.safeString(accountsById, toAccountId),
|
|
2430
|
+
'status': this.parseTransferStatus(this.safeString(transfer, 'state')),
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2433
|
+
parseTransferStatus(status) {
|
|
2434
|
+
const statuses = {
|
|
2435
|
+
'success': 'ok',
|
|
2436
|
+
};
|
|
2437
|
+
return this.safeString(statuses, status, status);
|
|
2438
|
+
}
|
|
2439
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2440
|
+
/**
|
|
2441
|
+
* @method
|
|
2442
|
+
* @name okcoin#withdraw
|
|
2443
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-withdrawal
|
|
2444
|
+
* @description make a withdrawal
|
|
2445
|
+
* @param {string} code unified currency code
|
|
2446
|
+
* @param {float} amount the amount to withdraw
|
|
2447
|
+
* @param {string} address the address to withdraw to
|
|
2448
|
+
* @param {string} tag
|
|
2449
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2450
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2451
|
+
*/
|
|
2452
|
+
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
2453
|
+
this.checkAddress(address);
|
|
2454
|
+
await this.loadMarkets();
|
|
2455
|
+
const currency = this.currency(code);
|
|
2456
|
+
if ((tag !== undefined) && (tag.length > 0)) {
|
|
2457
|
+
address = address + ':' + tag;
|
|
2458
|
+
}
|
|
2459
|
+
const request = {
|
|
2460
|
+
'ccy': currency['id'],
|
|
2461
|
+
'toAddr': address,
|
|
2462
|
+
'dest': '4',
|
|
2463
|
+
'amt': this.numberToString(amount),
|
|
2464
|
+
};
|
|
2465
|
+
let network = this.safeString(params, 'network'); // this line allows the user to specify either ERC20 or ETH
|
|
2466
|
+
if (network !== undefined) {
|
|
2467
|
+
const networks = this.safeValue(this.options, 'networks', {});
|
|
2468
|
+
network = this.safeString(networks, network.toUpperCase(), network); // handle ETH>ERC20 alias
|
|
2469
|
+
request['chain'] = currency['id'] + '-' + network;
|
|
2470
|
+
params = this.omit(params, 'network');
|
|
2471
|
+
}
|
|
2472
|
+
let fee = this.safeString(params, 'fee');
|
|
2473
|
+
if (fee === undefined) {
|
|
2474
|
+
const targetNetwork = this.safeValue(currency['networks'], this.networkIdToCode(network), {});
|
|
2475
|
+
fee = this.safeString(targetNetwork, 'fee');
|
|
2476
|
+
if (fee === undefined) {
|
|
2477
|
+
throw new errors.ArgumentsRequired(this.id + ' withdraw() requires a "fee" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set "0". Withdrawing to external digital asset address requires network transaction fee.');
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
request['fee'] = this.numberToString(fee); // withdrawals to OKCoin or OKX are fee-free, please set 0
|
|
2481
|
+
const response = await this.privatePostAssetWithdrawal(this.extend(request, params));
|
|
2482
|
+
//
|
|
2483
|
+
// {
|
|
2484
|
+
// "code": "0",
|
|
2485
|
+
// "msg": "",
|
|
2486
|
+
// "data": [
|
|
2487
|
+
// {
|
|
2488
|
+
// "amt": "0.1",
|
|
2489
|
+
// "wdId": "67485",
|
|
2490
|
+
// "ccy": "BTC"
|
|
2491
|
+
// }
|
|
2492
|
+
// ]
|
|
2493
|
+
// }
|
|
2494
|
+
//
|
|
2495
|
+
const data = this.safeValue(response, 'data', []);
|
|
2496
|
+
const transaction = this.safeValue(data, 0);
|
|
2497
|
+
return this.parseTransaction(transaction, currency);
|
|
2498
|
+
}
|
|
2499
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2500
|
+
/**
|
|
2501
|
+
* @method
|
|
2502
|
+
* @name okcoin#fetchDeposits
|
|
2503
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-get-deposit-history
|
|
2504
|
+
* @description fetch all deposits made to an account
|
|
2505
|
+
* @param {string} code unified currency code
|
|
2506
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
2507
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
2508
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2509
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2510
|
+
*/
|
|
2511
|
+
await this.loadMarkets();
|
|
2512
|
+
let request = {
|
|
2513
|
+
// 'ccy': currency['id'],
|
|
2514
|
+
// 'state': 2, // 0 waiting for confirmation, 1 deposit credited, 2 deposit successful
|
|
2515
|
+
// 'after': since,
|
|
2516
|
+
// 'before' this.milliseconds (),
|
|
2517
|
+
// 'limit': limit, // default 100, max 100
|
|
2518
|
+
};
|
|
2519
|
+
let currency = undefined;
|
|
2520
|
+
if (code !== undefined) {
|
|
2521
|
+
currency = this.currency(code);
|
|
2522
|
+
request['ccy'] = currency['id'];
|
|
2523
|
+
}
|
|
2524
|
+
if (since !== undefined) {
|
|
2525
|
+
request['before'] = Math.max(since - 1, 0);
|
|
2526
|
+
}
|
|
2527
|
+
if (limit !== undefined) {
|
|
2528
|
+
request['limit'] = limit; // default 100, max 100
|
|
2529
|
+
}
|
|
2530
|
+
[request, params] = this.handleUntilOption('after', request, params);
|
|
2531
|
+
const response = await this.privateGetAssetDepositHistory(this.extend(request, params));
|
|
2532
|
+
//
|
|
2533
|
+
// {
|
|
2534
|
+
// "code": "0",
|
|
2535
|
+
// "msg": "",
|
|
2536
|
+
// "data": [
|
|
2537
|
+
// {
|
|
2538
|
+
// "amt": "0.01044408",
|
|
2539
|
+
// "txId": "1915737_3_0_0_asset",
|
|
2540
|
+
// "ccy": "BTC",
|
|
2541
|
+
// "from": "13801825426",
|
|
2542
|
+
// "to": "",
|
|
2543
|
+
// "ts": "1597026383085",
|
|
2544
|
+
// "state": "2",
|
|
2545
|
+
// "depId": "4703879"
|
|
2546
|
+
// },
|
|
2547
|
+
// {
|
|
2548
|
+
// "amt": "491.6784211",
|
|
2549
|
+
// "txId": "1744594_3_184_0_asset",
|
|
2550
|
+
// "ccy": "OKB",
|
|
2551
|
+
// "from": "",
|
|
2552
|
+
// "to": "",
|
|
2553
|
+
// "ts": "1597026383085",
|
|
2554
|
+
// "state": "2",
|
|
2555
|
+
// "depId": "4703809"
|
|
2556
|
+
// },
|
|
2557
|
+
// {
|
|
2558
|
+
// "amt": "223.18782496",
|
|
2559
|
+
// "txId": "6d892c669225b1092c780bf0da0c6f912fc7dc8f6b8cc53b003288624c",
|
|
2560
|
+
// "ccy": "USDT",
|
|
2561
|
+
// "from": "",
|
|
2562
|
+
// "to": "39kK4XvgEuM7rX9frgyHoZkWqx4iKu1spD",
|
|
2563
|
+
// "ts": "1597026383085",
|
|
2564
|
+
// "state": "2",
|
|
2565
|
+
// "depId": "4703779"
|
|
2566
|
+
// }
|
|
2567
|
+
// ]
|
|
2568
|
+
// }
|
|
2569
|
+
//
|
|
2570
|
+
const data = this.safeValue(response, 'data', []);
|
|
2571
|
+
return this.parseTransactions(data, currency, since, limit, params);
|
|
2572
|
+
}
|
|
2573
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2574
|
+
/**
|
|
2575
|
+
* @method
|
|
2576
|
+
* @name okcoin#fetchWithdrawals
|
|
2577
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
|
|
2578
|
+
* @description fetch all withdrawals made from an account
|
|
2579
|
+
* @param {string} code unified currency code
|
|
2580
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
2581
|
+
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
2582
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2583
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2584
|
+
*/
|
|
2585
|
+
await this.loadMarkets();
|
|
2586
|
+
let request = {
|
|
2587
|
+
// 'ccy': currency['id'],
|
|
2588
|
+
// 'state': 2, // -3: pending cancel, -2 canceled, -1 failed, 0, pending, 1 sending, 2 sent, 3 awaiting email verification, 4 awaiting manual verification, 5 awaiting identity verification
|
|
2589
|
+
// 'after': since,
|
|
2590
|
+
// 'before': this.milliseconds (),
|
|
2591
|
+
// 'limit': limit, // default 100, max 100
|
|
2592
|
+
};
|
|
2593
|
+
let currency = undefined;
|
|
2594
|
+
if (code !== undefined) {
|
|
2595
|
+
currency = this.currency(code);
|
|
2596
|
+
request['ccy'] = currency['id'];
|
|
2597
|
+
}
|
|
2598
|
+
if (since !== undefined) {
|
|
2599
|
+
request['before'] = Math.max(since - 1, 0);
|
|
2600
|
+
}
|
|
2601
|
+
if (limit !== undefined) {
|
|
2602
|
+
request['limit'] = limit; // default 100, max 100
|
|
2603
|
+
}
|
|
2604
|
+
[request, params] = this.handleUntilOption('after', request, params);
|
|
2605
|
+
const response = await this.privateGetAssetWithdrawalHistory(this.extend(request, params));
|
|
2606
|
+
//
|
|
2607
|
+
// {
|
|
2608
|
+
// "code": "0",
|
|
2609
|
+
// "msg": "",
|
|
2610
|
+
// "data": [
|
|
2611
|
+
// {
|
|
2612
|
+
// "amt": "0.094",
|
|
2613
|
+
// "wdId": "4703879",
|
|
2614
|
+
// "fee": "0.01000000eth",
|
|
2615
|
+
// "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85",
|
|
2616
|
+
// "ccy": "ETH",
|
|
2617
|
+
// "from": "13426335357",
|
|
2618
|
+
// "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519",
|
|
2619
|
+
// "ts": "1597026383085",
|
|
2620
|
+
// "state": "2"
|
|
2621
|
+
// },
|
|
2622
|
+
// {
|
|
2623
|
+
// "amt": "0.01",
|
|
2624
|
+
// "wdId": "4703879",
|
|
2625
|
+
// "fee": "0.00000000btc",
|
|
2626
|
+
// "txId": "",
|
|
2627
|
+
// "ccy": "BTC",
|
|
2628
|
+
// "from": "13426335357",
|
|
2629
|
+
// "to": "13426335357",
|
|
2630
|
+
// "ts": "1597026383085",
|
|
2631
|
+
// "state": "2"
|
|
2632
|
+
// }
|
|
2633
|
+
// ]
|
|
2634
|
+
// }
|
|
2635
|
+
//
|
|
2636
|
+
const data = this.safeValue(response, 'data', []);
|
|
2637
|
+
return this.parseTransactions(data, currency, since, limit, params);
|
|
2638
|
+
}
|
|
2639
|
+
parseTransactionStatus(status) {
|
|
2640
|
+
//
|
|
2641
|
+
// deposit statuses
|
|
2642
|
+
//
|
|
2643
|
+
// {
|
|
2644
|
+
// "0": "waiting for confirmation",
|
|
2645
|
+
// "1": "confirmation account",
|
|
2646
|
+
// "2": "recharge success"
|
|
2647
|
+
// }
|
|
2648
|
+
//
|
|
2649
|
+
// withdrawal statues
|
|
2650
|
+
//
|
|
2651
|
+
// {
|
|
2652
|
+
// '-3': "pending cancel",
|
|
2653
|
+
// "-2": "cancelled",
|
|
2654
|
+
// "-1": "failed",
|
|
2655
|
+
// "0": "pending",
|
|
2656
|
+
// "1": "sending",
|
|
2657
|
+
// "2": "sent",
|
|
2658
|
+
// "3": "email confirmation",
|
|
2659
|
+
// "4": "manual confirmation",
|
|
2660
|
+
// "5": "awaiting identity confirmation"
|
|
2661
|
+
// }
|
|
2662
|
+
//
|
|
2663
|
+
const statuses = {
|
|
2664
|
+
'-3': 'pending',
|
|
2665
|
+
'-2': 'canceled',
|
|
2666
|
+
'-1': 'failed',
|
|
2667
|
+
'0': 'pending',
|
|
2668
|
+
'1': 'pending',
|
|
2669
|
+
'2': 'ok',
|
|
2670
|
+
'3': 'pending',
|
|
2671
|
+
'4': 'pending',
|
|
2672
|
+
'5': 'pending',
|
|
2673
|
+
};
|
|
2674
|
+
return this.safeString(statuses, status, status);
|
|
2675
|
+
}
|
|
2676
|
+
parseTransaction(transaction, currency = undefined) {
|
|
2677
|
+
//
|
|
2678
|
+
// withdraw
|
|
2679
|
+
//
|
|
2680
|
+
// {
|
|
2681
|
+
// "amt": "0.1",
|
|
2682
|
+
// "wdId": "67485",
|
|
2683
|
+
// "ccy": "BTC"
|
|
2684
|
+
// }
|
|
2685
|
+
//
|
|
2686
|
+
// fetchWithdrawals
|
|
2687
|
+
//
|
|
2688
|
+
// {
|
|
2689
|
+
// "amt": "0.094",
|
|
2690
|
+
// "wdId": "4703879",
|
|
2691
|
+
// "fee": "0.01000000eth",
|
|
2692
|
+
// "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85",
|
|
2693
|
+
// "ccy": "ETH",
|
|
2694
|
+
// "from": "13426335357",
|
|
2695
|
+
// "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519",
|
|
2696
|
+
// "tag",
|
|
2697
|
+
// "pmtId",
|
|
2698
|
+
// "memo",
|
|
2699
|
+
// "ts": "1597026383085",
|
|
2700
|
+
// "state": "2"
|
|
2701
|
+
// }
|
|
2702
|
+
//
|
|
2703
|
+
// fetchDeposits
|
|
2704
|
+
//
|
|
2705
|
+
// {
|
|
2706
|
+
// "amt": "0.01044408",
|
|
2707
|
+
// "txId": "1915737_3_0_0_asset",
|
|
2708
|
+
// "ccy": "BTC",
|
|
2709
|
+
// "from": "13801825426",
|
|
2710
|
+
// "to": "",
|
|
2711
|
+
// "ts": "1597026383085",
|
|
2712
|
+
// "state": "2",
|
|
2713
|
+
// "depId": "4703879"
|
|
2714
|
+
// }
|
|
2715
|
+
//
|
|
2716
|
+
let type = undefined;
|
|
2717
|
+
let id = undefined;
|
|
2718
|
+
const withdrawalId = this.safeString(transaction, 'wdId');
|
|
2719
|
+
const addressFrom = this.safeString(transaction, 'from');
|
|
2720
|
+
const addressTo = this.safeString(transaction, 'to');
|
|
2721
|
+
const address = addressTo;
|
|
2722
|
+
let tagTo = this.safeString2(transaction, 'tag', 'memo');
|
|
2723
|
+
tagTo = this.safeString2(transaction, 'pmtId', tagTo);
|
|
2724
|
+
if (withdrawalId !== undefined) {
|
|
2725
|
+
type = 'withdrawal';
|
|
2726
|
+
id = withdrawalId;
|
|
2727
|
+
}
|
|
2728
|
+
else {
|
|
2729
|
+
// the payment_id will appear on new deposits but appears to be removed from the response after 2 months
|
|
2730
|
+
id = this.safeString(transaction, 'depId');
|
|
2731
|
+
type = 'deposit';
|
|
2732
|
+
}
|
|
2733
|
+
const currencyId = this.safeString(transaction, 'ccy');
|
|
2734
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
2735
|
+
const amount = this.safeNumber(transaction, 'amt');
|
|
2736
|
+
const status = this.parseTransactionStatus(this.safeString(transaction, 'state'));
|
|
2737
|
+
const txid = this.safeString(transaction, 'txId');
|
|
2738
|
+
const timestamp = this.safeInteger(transaction, 'ts');
|
|
2739
|
+
let feeCost = undefined;
|
|
2740
|
+
if (type === 'deposit') {
|
|
2741
|
+
feeCost = 0;
|
|
2742
|
+
}
|
|
2743
|
+
else {
|
|
2744
|
+
feeCost = this.safeNumber(transaction, 'fee');
|
|
2745
|
+
}
|
|
2746
|
+
// todo parse tags
|
|
2747
|
+
return {
|
|
2748
|
+
'info': transaction,
|
|
2749
|
+
'id': id,
|
|
2750
|
+
'currency': code,
|
|
2751
|
+
'amount': amount,
|
|
2752
|
+
'network': undefined,
|
|
2753
|
+
'addressFrom': addressFrom,
|
|
2754
|
+
'addressTo': addressTo,
|
|
2755
|
+
'address': address,
|
|
2756
|
+
'tagFrom': undefined,
|
|
2757
|
+
'tagTo': tagTo,
|
|
2758
|
+
'tag': tagTo,
|
|
2759
|
+
'status': status,
|
|
2760
|
+
'type': type,
|
|
2761
|
+
'updated': undefined,
|
|
2762
|
+
'txid': txid,
|
|
2763
|
+
'timestamp': timestamp,
|
|
2764
|
+
'datetime': this.iso8601(timestamp),
|
|
2765
|
+
'comment': undefined,
|
|
2766
|
+
'internal': undefined,
|
|
2767
|
+
'fee': {
|
|
2768
|
+
'currency': code,
|
|
2769
|
+
'cost': feeCost,
|
|
2770
|
+
},
|
|
2771
|
+
};
|
|
2772
|
+
}
|
|
2773
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2774
|
+
/**
|
|
2775
|
+
* @method
|
|
2776
|
+
* @name okcoin#fetchMyTrades
|
|
2777
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-days
|
|
2778
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-months
|
|
2779
|
+
* @description fetch all trades made by the user
|
|
2780
|
+
* @param {string} symbol unified market symbol
|
|
2781
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
2782
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
2783
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2784
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2785
|
+
*/
|
|
2786
|
+
await this.loadMarkets();
|
|
2787
|
+
const request = {
|
|
2788
|
+
'instType': 'SPOT',
|
|
2789
|
+
};
|
|
2790
|
+
if ((limit !== undefined) && (limit > 100)) {
|
|
2791
|
+
limit = 100;
|
|
2792
|
+
}
|
|
2793
|
+
let market = undefined;
|
|
2794
|
+
if (symbol !== undefined) {
|
|
2795
|
+
market = this.market(symbol);
|
|
2796
|
+
request['instId'] = market['id'];
|
|
2797
|
+
}
|
|
2798
|
+
let method = undefined;
|
|
2799
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'method', 'privateGetTradeFillsHistory');
|
|
2800
|
+
let response = undefined;
|
|
2801
|
+
if (method === 'privateGetTradeFillsHistory') {
|
|
2802
|
+
response = await this.privateGetTradeFillsHistory(this.extend(request, params));
|
|
2803
|
+
}
|
|
2804
|
+
else {
|
|
2805
|
+
response = await this.privateGetTradeFills(this.extend(request, params));
|
|
2806
|
+
}
|
|
2807
|
+
const data = this.safeValue(response, 'data', []);
|
|
2808
|
+
return this.parseTrades(data, market, since, limit);
|
|
2809
|
+
}
|
|
2810
|
+
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2811
|
+
/**
|
|
2812
|
+
* @method
|
|
2813
|
+
* @name okcoin#fetchOrderTrades
|
|
2814
|
+
* @description fetch all the trades made from a single order
|
|
2815
|
+
* @param {string} id order id
|
|
2816
|
+
* @param {string} symbol unified market symbol
|
|
2817
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
2818
|
+
* @param {int} [limit] the maximum number of trades to retrieve
|
|
2819
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2820
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
2821
|
+
*/
|
|
2822
|
+
const request = {
|
|
2823
|
+
// 'instrument_id': market['id'],
|
|
2824
|
+
'order_id': id,
|
|
2825
|
+
// 'after': '1', // return the page after the specified page number
|
|
2826
|
+
// 'before': '1', // return the page before the specified page number
|
|
2827
|
+
// 'limit': limit, // optional, number of results per request, default = maximum = 100
|
|
2828
|
+
};
|
|
2829
|
+
return await this.fetchMyTrades(symbol, since, limit, this.extend(request, params));
|
|
2830
|
+
}
|
|
2831
|
+
async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2832
|
+
/**
|
|
2833
|
+
* @method
|
|
2834
|
+
* @name okcoin#fetchLedger
|
|
2835
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-asset-bills-details
|
|
2836
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
|
|
2837
|
+
* @see https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
|
|
2838
|
+
* @description fetch the history of changes, actions done by the user or operations that altered balance of the user
|
|
2839
|
+
* @param {string} code unified currency code, default is undefined
|
|
2840
|
+
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
|
2841
|
+
* @param {int} [limit] max number of ledger entrys to return, default is undefined
|
|
2842
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2843
|
+
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
|
|
2844
|
+
*/
|
|
2845
|
+
await this.loadMarkets();
|
|
2846
|
+
let method = undefined;
|
|
2847
|
+
[method, params] = this.handleOptionAndParams(params, 'fetchLedger', 'method', 'privateGetAccountBills');
|
|
2848
|
+
let request = {
|
|
2849
|
+
// 'instType': undefined, // 'SPOT', 'MARGIN', 'SWAP', 'FUTURES", 'OPTION'
|
|
2850
|
+
// 'ccy': undefined, // currency['id'],
|
|
2851
|
+
// 'ctType': undefined, // 'linear', 'inverse', only applicable to FUTURES/SWAP
|
|
2852
|
+
// 'type': varies depending the 'method' endpoint :
|
|
2853
|
+
// - https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
|
|
2854
|
+
// - https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details
|
|
2855
|
+
// - https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
|
|
2856
|
+
// 'after': 'id', // return records earlier than the requested bill id
|
|
2857
|
+
// 'before': 'id', // return records newer than the requested bill id
|
|
2858
|
+
// 'limit': 100, // default 100, max 100
|
|
2859
|
+
};
|
|
2860
|
+
if (limit !== undefined) {
|
|
2861
|
+
request['limit'] = limit;
|
|
2862
|
+
}
|
|
2863
|
+
let currency = undefined;
|
|
2864
|
+
if (code !== undefined) {
|
|
2865
|
+
currency = this.currency(code);
|
|
2866
|
+
request['ccy'] = currency['id'];
|
|
2867
|
+
}
|
|
2868
|
+
[request, params] = this.handleUntilOption('end', request, params);
|
|
2869
|
+
let response = undefined;
|
|
2870
|
+
if (method === 'privateGetAccountBillsArchive') {
|
|
2871
|
+
response = await this.privateGetAccountBillsArchive(this.extend(request, params));
|
|
2872
|
+
}
|
|
2873
|
+
else if (method === 'privateGetAssetBills') {
|
|
2874
|
+
response = await this.privateGetAssetBills(this.extend(request, params));
|
|
2875
|
+
}
|
|
2876
|
+
else {
|
|
2877
|
+
response = await this.privateGetAccountBills(this.extend(request, params));
|
|
2878
|
+
}
|
|
2879
|
+
//
|
|
2880
|
+
// privateGetAccountBills, privateGetAccountBillsArchive
|
|
2881
|
+
//
|
|
2882
|
+
// {
|
|
2883
|
+
// "code": "0",
|
|
2884
|
+
// "msg": "",
|
|
2885
|
+
// "data": [
|
|
2886
|
+
// {
|
|
2887
|
+
// "bal": "0.0000819307998198",
|
|
2888
|
+
// "balChg": "-664.2679586599999802",
|
|
2889
|
+
// "billId": "310394313544966151",
|
|
2890
|
+
// "ccy": "USDT",
|
|
2891
|
+
// "fee": "0",
|
|
2892
|
+
// "from": "",
|
|
2893
|
+
// "instId": "LTC-USDT",
|
|
2894
|
+
// "instType": "SPOT",
|
|
2895
|
+
// "mgnMode": "cross",
|
|
2896
|
+
// "notes": "",
|
|
2897
|
+
// "ordId": "310394313519800320",
|
|
2898
|
+
// "pnl": "0",
|
|
2899
|
+
// "posBal": "0",
|
|
2900
|
+
// "posBalChg": "0",
|
|
2901
|
+
// "subType": "2",
|
|
2902
|
+
// "sz": "664.26795866",
|
|
2903
|
+
// "to": "",
|
|
2904
|
+
// "ts": "1620275771196",
|
|
2905
|
+
// "type": "2"
|
|
2906
|
+
// }
|
|
2907
|
+
// ]
|
|
2908
|
+
// }
|
|
2909
|
+
//
|
|
2910
|
+
// privateGetAssetBills
|
|
2911
|
+
//
|
|
2912
|
+
// {
|
|
2913
|
+
// "code": "0",
|
|
2914
|
+
// "msg": "",
|
|
2915
|
+
// "data": [
|
|
2916
|
+
// {
|
|
2917
|
+
// "billId": "12344",
|
|
2918
|
+
// "ccy": "BTC",
|
|
2919
|
+
// "balChg": "2",
|
|
2920
|
+
// "bal": "12",
|
|
2921
|
+
// "type": "1",
|
|
2922
|
+
// "ts": "1597026383085"
|
|
2923
|
+
// }
|
|
2924
|
+
// ]
|
|
2925
|
+
// }
|
|
2926
|
+
//
|
|
2927
|
+
const data = this.safeValue(response, 'data', []);
|
|
2928
|
+
return this.parseLedger(data, currency, since, limit);
|
|
2929
|
+
}
|
|
2930
|
+
parseLedgerEntryType(type) {
|
|
2931
|
+
const types = {
|
|
2932
|
+
'1': 'transfer',
|
|
2933
|
+
'2': 'trade',
|
|
2934
|
+
'3': 'trade',
|
|
2935
|
+
'4': 'rebate',
|
|
2936
|
+
'5': 'trade',
|
|
2937
|
+
'6': 'transfer',
|
|
2938
|
+
'7': 'trade',
|
|
2939
|
+
'8': 'fee',
|
|
2940
|
+
'9': 'trade',
|
|
2941
|
+
'10': 'trade',
|
|
2942
|
+
'11': 'trade', // system token conversion
|
|
2943
|
+
};
|
|
2944
|
+
return this.safeString(types, type, type);
|
|
2945
|
+
}
|
|
2946
|
+
parseLedgerEntry(item, currency = undefined) {
|
|
2947
|
+
//
|
|
2948
|
+
// privateGetAccountBills, privateGetAccountBillsArchive
|
|
2949
|
+
//
|
|
2950
|
+
// {
|
|
2951
|
+
// "bal": "0.0000819307998198",
|
|
2952
|
+
// "balChg": "-664.2679586599999802",
|
|
2953
|
+
// "billId": "310394313544966151",
|
|
2954
|
+
// "ccy": "USDT",
|
|
2955
|
+
// "fee": "0",
|
|
2956
|
+
// "from": "",
|
|
2957
|
+
// "instId": "LTC-USDT",
|
|
2958
|
+
// "instType": "SPOT",
|
|
2959
|
+
// "mgnMode": "cross",
|
|
2960
|
+
// "notes": "",
|
|
2961
|
+
// "ordId": "310394313519800320",
|
|
2962
|
+
// "pnl": "0",
|
|
2963
|
+
// "posBal": "0",
|
|
2964
|
+
// "posBalChg": "0",
|
|
2965
|
+
// "subType": "2",
|
|
2966
|
+
// "sz": "664.26795866",
|
|
2967
|
+
// "to": "",
|
|
2968
|
+
// "ts": "1620275771196",
|
|
2969
|
+
// "type": "2"
|
|
2970
|
+
// }
|
|
2971
|
+
//
|
|
2972
|
+
// privateGetAssetBills
|
|
2973
|
+
//
|
|
2974
|
+
// {
|
|
2975
|
+
// "billId": "12344",
|
|
2976
|
+
// "ccy": "BTC",
|
|
2977
|
+
// "balChg": "2",
|
|
2978
|
+
// "bal": "12",
|
|
2979
|
+
// "type": "1",
|
|
2980
|
+
// "ts": "1597026383085"
|
|
2981
|
+
// }
|
|
2982
|
+
//
|
|
2983
|
+
const id = this.safeString(item, 'billId');
|
|
2984
|
+
const account = undefined;
|
|
2985
|
+
const referenceId = this.safeString(item, 'ordId');
|
|
2986
|
+
const referenceAccount = undefined;
|
|
2987
|
+
const type = this.parseLedgerEntryType(this.safeString(item, 'type'));
|
|
2988
|
+
const code = this.safeCurrencyCode(this.safeString(item, 'ccy'), currency);
|
|
2989
|
+
const amountString = this.safeString(item, 'balChg');
|
|
2990
|
+
const amount = this.parseNumber(amountString);
|
|
2991
|
+
const timestamp = this.safeInteger(item, 'ts');
|
|
2992
|
+
const feeCostString = this.safeString(item, 'fee');
|
|
2993
|
+
let fee = undefined;
|
|
2994
|
+
if (feeCostString !== undefined) {
|
|
2995
|
+
fee = {
|
|
2996
|
+
'cost': this.parseNumber(Precise["default"].stringNeg(feeCostString)),
|
|
2997
|
+
'currency': code,
|
|
2998
|
+
};
|
|
2999
|
+
}
|
|
3000
|
+
const before = undefined;
|
|
3001
|
+
const afterString = this.safeString(item, 'bal');
|
|
3002
|
+
const after = this.parseNumber(afterString);
|
|
3003
|
+
const status = 'ok';
|
|
3004
|
+
const marketId = this.safeString(item, 'instId');
|
|
3005
|
+
const symbol = this.safeSymbol(marketId, undefined, '-');
|
|
3006
|
+
return {
|
|
3007
|
+
'id': id,
|
|
3008
|
+
'info': item,
|
|
3009
|
+
'timestamp': timestamp,
|
|
3010
|
+
'datetime': this.iso8601(timestamp),
|
|
3011
|
+
'account': account,
|
|
3012
|
+
'referenceId': referenceId,
|
|
3013
|
+
'referenceAccount': referenceAccount,
|
|
3014
|
+
'type': type,
|
|
3015
|
+
'currency': code,
|
|
3016
|
+
'symbol': symbol,
|
|
3017
|
+
'amount': amount,
|
|
3018
|
+
'before': before,
|
|
3019
|
+
'after': after,
|
|
3020
|
+
'status': status,
|
|
3021
|
+
'fee': fee,
|
|
3022
|
+
};
|
|
3023
|
+
}
|
|
3024
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
3025
|
+
const isArray = Array.isArray(params);
|
|
3026
|
+
const request = '/api/' + this.version + '/' + this.implodeParams(path, params);
|
|
3027
|
+
const query = this.omit(params, this.extractParams(path));
|
|
3028
|
+
let url = this.implodeHostname(this.urls['api']['rest']) + request;
|
|
3029
|
+
if (api === 'public') {
|
|
3030
|
+
if (Object.keys(query).length) {
|
|
3031
|
+
url += '?' + this.urlencode(query);
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
else if (api === 'private') {
|
|
3035
|
+
this.checkRequiredCredentials();
|
|
3036
|
+
const timestamp = this.iso8601(this.milliseconds());
|
|
3037
|
+
headers = {
|
|
3038
|
+
'OK-ACCESS-KEY': this.apiKey,
|
|
3039
|
+
'OK-ACCESS-PASSPHRASE': this.password,
|
|
3040
|
+
'OK-ACCESS-TIMESTAMP': timestamp,
|
|
3041
|
+
// 'OK-FROM': '',
|
|
3042
|
+
// 'OK-TO': '',
|
|
3043
|
+
// 'OK-LIMIT': '',
|
|
3044
|
+
};
|
|
3045
|
+
let auth = timestamp + method + request;
|
|
3046
|
+
if (method === 'GET') {
|
|
3047
|
+
if (Object.keys(query).length) {
|
|
3048
|
+
const urlencodedQuery = '?' + this.urlencode(query);
|
|
3049
|
+
url += urlencodedQuery;
|
|
3050
|
+
auth += urlencodedQuery;
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
else {
|
|
3054
|
+
if (isArray || Object.keys(query).length) {
|
|
3055
|
+
body = this.json(query);
|
|
3056
|
+
auth += body;
|
|
3057
|
+
}
|
|
3058
|
+
headers['Content-Type'] = 'application/json';
|
|
3059
|
+
}
|
|
3060
|
+
const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256, 'base64');
|
|
3061
|
+
headers['OK-ACCESS-SIGN'] = signature;
|
|
3062
|
+
}
|
|
3063
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
3064
|
+
}
|
|
3065
|
+
parseBalanceByType(type, response) {
|
|
3066
|
+
if (type === 'funding') {
|
|
3067
|
+
return this.parseFundingBalance(response);
|
|
3068
|
+
}
|
|
3069
|
+
else {
|
|
3070
|
+
return this.parseTradingBalance(response);
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
3074
|
+
if (!response) {
|
|
3075
|
+
return undefined; // fallback to default error handler
|
|
3076
|
+
}
|
|
3077
|
+
//
|
|
3078
|
+
// {
|
|
3079
|
+
// "code": "1",
|
|
3080
|
+
// "data": [
|
|
3081
|
+
// {
|
|
3082
|
+
// "clOrdId": "",
|
|
3083
|
+
// "ordId": "",
|
|
3084
|
+
// "sCode": "51119",
|
|
3085
|
+
// "sMsg": "Order placement failed due to insufficient balance. ",
|
|
3086
|
+
// "tag": ""
|
|
3087
|
+
// }
|
|
3088
|
+
// ],
|
|
3089
|
+
// "msg": ""
|
|
3090
|
+
// },
|
|
3091
|
+
// {
|
|
3092
|
+
// "code": "58001",
|
|
3093
|
+
// "data": [],
|
|
3094
|
+
// "msg": "Incorrect trade password"
|
|
3095
|
+
// }
|
|
3096
|
+
//
|
|
3097
|
+
const code = this.safeString(response, 'code');
|
|
3098
|
+
if (code !== '0') {
|
|
3099
|
+
const feedback = this.id + ' ' + body;
|
|
3100
|
+
const data = this.safeValue(response, 'data', []);
|
|
3101
|
+
for (let i = 0; i < data.length; i++) {
|
|
3102
|
+
const error = data[i];
|
|
3103
|
+
const errorCode = this.safeString(error, 'sCode');
|
|
3104
|
+
const message = this.safeString(error, 'sMsg');
|
|
3105
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
|
|
3106
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
3107
|
+
}
|
|
3108
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
|
|
3109
|
+
throw new errors.ExchangeError(feedback); // unknown message
|
|
3110
|
+
}
|
|
3111
|
+
return undefined;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3115
|
+
module.exports = okcoin;
|