ccxt 4.2.11 → 4.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/build.sh +2 -2
- package/dist/ccxt.browser.js +1347 -490
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/_virtual/agent.js +7 -0
- package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
- package/dist/cjs/_virtual/promisify.js +7 -0
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/js/ccxt.js +474 -0
- package/dist/cjs/js/src/abstract/ace.js +9 -0
- package/dist/cjs/js/src/abstract/alpaca.js +9 -0
- package/dist/cjs/js/src/abstract/ascendex.js +9 -0
- package/dist/cjs/js/src/abstract/bigone.js +9 -0
- package/dist/cjs/js/src/abstract/binance.js +9 -0
- package/dist/cjs/js/src/abstract/bingx.js +9 -0
- package/dist/cjs/js/src/abstract/bit2c.js +9 -0
- package/dist/cjs/js/src/abstract/bitbank.js +9 -0
- package/dist/cjs/js/src/abstract/bitbns.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
- package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
- package/dist/cjs/js/src/abstract/bitforex.js +9 -0
- package/dist/cjs/js/src/abstract/bitget.js +9 -0
- package/dist/cjs/js/src/abstract/bithumb.js +9 -0
- package/dist/cjs/js/src/abstract/bitmart.js +9 -0
- package/dist/cjs/js/src/abstract/bitmex.js +9 -0
- package/dist/cjs/js/src/abstract/bitopro.js +9 -0
- package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
- package/dist/cjs/js/src/abstract/bitrue.js +9 -0
- package/dist/cjs/js/src/abstract/bitso.js +9 -0
- package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
- package/dist/cjs/js/src/abstract/bitteam.js +9 -0
- package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
- package/dist/cjs/js/src/abstract/bl3p.js +9 -0
- package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
- package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
- package/dist/cjs/js/src/abstract/btcbox.js +9 -0
- package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
- package/dist/cjs/js/src/abstract/btcturk.js +9 -0
- package/dist/cjs/js/src/abstract/bybit.js +9 -0
- package/dist/cjs/js/src/abstract/cex.js +9 -0
- package/dist/cjs/js/src/abstract/coinbase.js +9 -0
- package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
- package/dist/cjs/js/src/abstract/coincheck.js +9 -0
- package/dist/cjs/js/src/abstract/coinex.js +9 -0
- package/dist/cjs/js/src/abstract/coinlist.js +9 -0
- package/dist/cjs/js/src/abstract/coinmate.js +9 -0
- package/dist/cjs/js/src/abstract/coinone.js +9 -0
- package/dist/cjs/js/src/abstract/coinsph.js +9 -0
- package/dist/cjs/js/src/abstract/coinspot.js +9 -0
- package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
- package/dist/cjs/js/src/abstract/currencycom.js +9 -0
- package/dist/cjs/js/src/abstract/delta.js +9 -0
- package/dist/cjs/js/src/abstract/deribit.js +9 -0
- package/dist/cjs/js/src/abstract/digifinex.js +9 -0
- package/dist/cjs/js/src/abstract/exmo.js +9 -0
- package/dist/cjs/js/src/abstract/gate.js +9 -0
- package/dist/cjs/js/src/abstract/gemini.js +9 -0
- package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
- package/dist/cjs/js/src/abstract/hollaex.js +9 -0
- package/dist/cjs/js/src/abstract/htx.js +9 -0
- package/dist/cjs/js/src/abstract/huobijp.js +9 -0
- package/dist/cjs/js/src/abstract/idex.js +9 -0
- package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
- package/dist/cjs/js/src/abstract/indodax.js +9 -0
- package/dist/cjs/js/src/abstract/kraken.js +9 -0
- package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kucoin.js +9 -0
- package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kuna.js +9 -0
- package/dist/cjs/js/src/abstract/latoken.js +9 -0
- package/dist/cjs/js/src/abstract/lbank.js +9 -0
- package/dist/cjs/js/src/abstract/luno.js +9 -0
- package/dist/cjs/js/src/abstract/lykke.js +9 -0
- package/dist/cjs/js/src/abstract/mercado.js +9 -0
- package/dist/cjs/js/src/abstract/mexc.js +9 -0
- package/dist/cjs/js/src/abstract/ndax.js +9 -0
- package/dist/cjs/js/src/abstract/novadax.js +9 -0
- package/dist/cjs/js/src/abstract/oceanex.js +9 -0
- package/dist/cjs/js/src/abstract/okcoin.js +9 -0
- package/dist/cjs/js/src/abstract/okx.js +9 -0
- package/dist/cjs/js/src/abstract/p2b.js +9 -0
- package/dist/cjs/js/src/abstract/paymium.js +9 -0
- package/dist/cjs/js/src/abstract/phemex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
- package/dist/cjs/js/src/abstract/probit.js +9 -0
- package/dist/cjs/js/src/abstract/timex.js +9 -0
- package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
- package/dist/cjs/js/src/abstract/upbit.js +9 -0
- package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
- package/dist/cjs/js/src/abstract/wazirx.js +9 -0
- package/dist/cjs/js/src/abstract/whitebit.js +9 -0
- package/dist/cjs/js/src/abstract/woo.js +9 -0
- package/dist/cjs/js/src/abstract/yobit.js +9 -0
- package/dist/cjs/js/src/abstract/zaif.js +9 -0
- package/dist/cjs/js/src/abstract/zonda.js +9 -0
- package/dist/cjs/js/src/ace.js +1058 -0
- package/dist/cjs/js/src/alpaca.js +1125 -0
- package/dist/cjs/js/src/ascendex.js +3360 -0
- package/dist/cjs/js/src/base/Exchange.js +5110 -0
- package/dist/cjs/js/src/base/Precise.js +263 -0
- package/dist/cjs/js/src/base/errors.js +299 -0
- package/dist/cjs/js/src/base/functions/crypto.js +78 -0
- package/dist/cjs/js/src/base/functions/encode.js +44 -0
- package/dist/cjs/js/src/base/functions/generic.js +193 -0
- package/dist/cjs/js/src/base/functions/misc.js +96 -0
- package/dist/cjs/js/src/base/functions/number.js +297 -0
- package/dist/cjs/js/src/base/functions/platform.js +28 -0
- package/dist/cjs/js/src/base/functions/rsa.js +34 -0
- package/dist/cjs/js/src/base/functions/string.js +48 -0
- package/dist/cjs/js/src/base/functions/throttle.js +66 -0
- package/dist/cjs/js/src/base/functions/time.js +187 -0
- package/dist/cjs/js/src/base/functions/totp.js +24 -0
- package/dist/cjs/js/src/base/functions/type.js +162 -0
- package/dist/cjs/js/src/base/functions.js +157 -0
- package/dist/cjs/js/src/base/ws/Cache.js +254 -0
- package/dist/cjs/js/src/base/ws/Client.js +299 -0
- package/dist/cjs/js/src/base/ws/Future.js +34 -0
- package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
- package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
- package/dist/cjs/js/src/bequant.js +33 -0
- package/dist/cjs/js/src/bigone.js +2209 -0
- package/dist/cjs/js/src/binance.js +9736 -0
- package/dist/cjs/js/src/binancecoinm.js +45 -0
- package/dist/cjs/js/src/binanceus.js +84 -0
- package/dist/cjs/js/src/binanceusdm.js +58 -0
- package/dist/cjs/js/src/bingx.js +3807 -0
- package/dist/cjs/js/src/bit2c.js +916 -0
- package/dist/cjs/js/src/bitbank.js +1000 -0
- package/dist/cjs/js/src/bitbay.js +17 -0
- package/dist/cjs/js/src/bitbns.js +1220 -0
- package/dist/cjs/js/src/bitcoincom.js +17 -0
- package/dist/cjs/js/src/bitfinex.js +1670 -0
- package/dist/cjs/js/src/bitfinex2.js +2990 -0
- package/dist/cjs/js/src/bitflyer.js +1045 -0
- package/dist/cjs/js/src/bitforex.js +852 -0
- package/dist/cjs/js/src/bitget.js +8291 -0
- package/dist/cjs/js/src/bithumb.js +1090 -0
- package/dist/cjs/js/src/bitmart.js +4454 -0
- package/dist/cjs/js/src/bitmex.js +2884 -0
- package/dist/cjs/js/src/bitopro.js +1724 -0
- package/dist/cjs/js/src/bitpanda.js +2002 -0
- package/dist/cjs/js/src/bitrue.js +3253 -0
- package/dist/cjs/js/src/bitso.js +1753 -0
- package/dist/cjs/js/src/bitstamp.js +2188 -0
- package/dist/cjs/js/src/bitteam.js +2309 -0
- package/dist/cjs/js/src/bitvavo.js +1968 -0
- package/dist/cjs/js/src/bl3p.js +447 -0
- package/dist/cjs/js/src/blockchaincom.js +1160 -0
- package/dist/cjs/js/src/btcalpha.js +929 -0
- package/dist/cjs/js/src/btcbox.js +565 -0
- package/dist/cjs/js/src/btcmarkets.js +1237 -0
- package/dist/cjs/js/src/btcturk.js +929 -0
- package/dist/cjs/js/src/bybit.js +7646 -0
- package/dist/cjs/js/src/cex.js +1693 -0
- package/dist/cjs/js/src/coinbase.js +3424 -0
- package/dist/cjs/js/src/coinbasepro.js +1866 -0
- package/dist/cjs/js/src/coincheck.js +843 -0
- package/dist/cjs/js/src/coinex.js +5414 -0
- package/dist/cjs/js/src/coinlist.js +2329 -0
- package/dist/cjs/js/src/coinmate.js +989 -0
- package/dist/cjs/js/src/coinone.js +1185 -0
- package/dist/cjs/js/src/coinsph.js +1933 -0
- package/dist/cjs/js/src/coinspot.js +548 -0
- package/dist/cjs/js/src/cryptocom.js +3007 -0
- package/dist/cjs/js/src/currencycom.js +2015 -0
- package/dist/cjs/js/src/delta.js +3256 -0
- package/dist/cjs/js/src/deribit.js +3306 -0
- package/dist/cjs/js/src/digifinex.js +4307 -0
- package/dist/cjs/js/src/exmo.js +2645 -0
- package/dist/cjs/js/src/fmfwio.js +34 -0
- package/dist/cjs/js/src/gate.js +7072 -0
- package/dist/cjs/js/src/gateio.js +16 -0
- package/dist/cjs/js/src/gemini.js +1801 -0
- package/dist/cjs/js/src/hitbtc.js +3660 -0
- package/dist/cjs/js/src/hitbtc3.js +19 -0
- package/dist/cjs/js/src/hollaex.js +1882 -0
- package/dist/cjs/js/src/htx.js +9049 -0
- package/dist/cjs/js/src/huobi.js +16 -0
- package/dist/cjs/js/src/huobijp.js +1918 -0
- package/dist/cjs/js/src/idex.js +1770 -0
- package/dist/cjs/js/src/independentreserve.js +761 -0
- package/dist/cjs/js/src/indodax.js +1069 -0
- package/dist/cjs/js/src/kraken.js +2857 -0
- package/dist/cjs/js/src/krakenfutures.js +2407 -0
- package/dist/cjs/js/src/kucoin.js +4489 -0
- package/dist/cjs/js/src/kucoinfutures.js +2475 -0
- package/dist/cjs/js/src/kuna.js +1949 -0
- package/dist/cjs/js/src/latoken.js +1729 -0
- package/dist/cjs/js/src/lbank.js +2851 -0
- package/dist/cjs/js/src/luno.js +1044 -0
- package/dist/cjs/js/src/lykke.js +1303 -0
- package/dist/cjs/js/src/mercado.js +897 -0
- package/dist/cjs/js/src/mexc.js +5407 -0
- package/dist/cjs/js/src/ndax.js +2450 -0
- package/dist/cjs/js/src/novadax.js +1556 -0
- package/dist/cjs/js/src/oceanex.js +964 -0
- package/dist/cjs/js/src/okcoin.js +3115 -0
- package/dist/cjs/js/src/okx.js +7330 -0
- package/dist/cjs/js/src/p2b.js +1243 -0
- package/dist/cjs/js/src/paymium.js +597 -0
- package/dist/cjs/js/src/phemex.js +4722 -0
- package/dist/cjs/js/src/poloniex.js +2356 -0
- package/dist/cjs/js/src/poloniexfutures.js +1794 -0
- package/dist/cjs/js/src/pro/alpaca.js +714 -0
- package/dist/cjs/js/src/pro/ascendex.js +957 -0
- package/dist/cjs/js/src/pro/bequant.js +33 -0
- package/dist/cjs/js/src/pro/binance.js +2796 -0
- package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
- package/dist/cjs/js/src/pro/binanceus.js +51 -0
- package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
- package/dist/cjs/js/src/pro/bingx.js +944 -0
- package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
- package/dist/cjs/js/src/pro/bitfinex.js +672 -0
- package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
- package/dist/cjs/js/src/pro/bitget.js +1733 -0
- package/dist/cjs/js/src/pro/bitmart.js +1486 -0
- package/dist/cjs/js/src/pro/bitmex.js +1576 -0
- package/dist/cjs/js/src/pro/bitopro.js +327 -0
- package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
- package/dist/cjs/js/src/pro/bitrue.js +462 -0
- package/dist/cjs/js/src/pro/bitstamp.js +547 -0
- package/dist/cjs/js/src/pro/bitvavo.js +704 -0
- package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
- package/dist/cjs/js/src/pro/bybit.js +1843 -0
- package/dist/cjs/js/src/pro/cex.js +1510 -0
- package/dist/cjs/js/src/pro/coinbase.js +561 -0
- package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
- package/dist/cjs/js/src/pro/coinex.js +1095 -0
- package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
- package/dist/cjs/js/src/pro/currencycom.js +563 -0
- package/dist/cjs/js/src/pro/deribit.js +825 -0
- package/dist/cjs/js/src/pro/exmo.js +658 -0
- package/dist/cjs/js/src/pro/gate.js +1316 -0
- package/dist/cjs/js/src/pro/gateio.js +16 -0
- package/dist/cjs/js/src/pro/gemini.js +649 -0
- package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
- package/dist/cjs/js/src/pro/hollaex.js +597 -0
- package/dist/cjs/js/src/pro/htx.js +2383 -0
- package/dist/cjs/js/src/pro/huobi.js +16 -0
- package/dist/cjs/js/src/pro/huobijp.js +606 -0
- package/dist/cjs/js/src/pro/idex.js +714 -0
- package/dist/cjs/js/src/pro/independentreserve.js +280 -0
- package/dist/cjs/js/src/pro/kraken.js +1364 -0
- package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
- package/dist/cjs/js/src/pro/kucoin.js +1052 -0
- package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
- package/dist/cjs/js/src/pro/luno.js +322 -0
- package/dist/cjs/js/src/pro/mexc.js +1170 -0
- package/dist/cjs/js/src/pro/ndax.js +545 -0
- package/dist/cjs/js/src/pro/okcoin.js +760 -0
- package/dist/cjs/js/src/pro/okx.js +1608 -0
- package/dist/cjs/js/src/pro/phemex.js +1511 -0
- package/dist/cjs/js/src/pro/poloniex.js +1253 -0
- package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
- package/dist/cjs/js/src/pro/probit.js +586 -0
- package/dist/cjs/js/src/pro/upbit.js +234 -0
- package/dist/cjs/js/src/pro/wazirx.js +776 -0
- package/dist/cjs/js/src/pro/whitebit.js +927 -0
- package/dist/cjs/js/src/pro/woo.js +769 -0
- package/dist/cjs/js/src/probit.js +1867 -0
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
- package/dist/cjs/js/src/timex.js +1562 -0
- package/dist/cjs/js/src/tokocrypto.js +2542 -0
- package/dist/cjs/js/src/upbit.js +1844 -0
- package/dist/cjs/js/src/wavesexchange.js +2607 -0
- package/dist/cjs/js/src/wazirx.js +953 -0
- package/dist/cjs/js/src/whitebit.js +2309 -0
- package/dist/cjs/js/src/woo.js +2765 -0
- package/dist/cjs/js/src/yobit.js +1314 -0
- package/dist/cjs/js/src/zaif.js +736 -0
- package/dist/cjs/js/src/zonda.js +1883 -0
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bigone.d.ts +18 -0
- package/js/src/abstract/binance.d.ts +2 -0
- package/js/src/abstract/binancecoinm.d.ts +2 -0
- package/js/src/abstract/binanceus.d.ts +2 -0
- package/js/src/abstract/binanceusdm.d.ts +2 -0
- package/js/src/abstract/bingx.d.ts +2 -0
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/abstract/gate.d.ts +11 -0
- package/js/src/abstract/gateio.d.ts +11 -0
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/alpaca.js +18 -18
- package/js/src/base/Exchange.d.ts +5 -1
- package/js/src/base/Exchange.js +101 -12
- package/js/src/bigone.d.ts +3 -2
- package/js/src/bigone.js +429 -167
- package/js/src/binance.js +48 -34
- package/js/src/bingx.js +115 -38
- package/js/src/bitfinex.d.ts +2 -2
- package/js/src/bitfinex.js +2 -3
- package/js/src/bitget.js +33 -13
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +5 -5
- package/js/src/bitmex.js +1 -0
- package/js/src/bybit.js +2 -0
- package/js/src/coinbase.d.ts +26 -3
- package/js/src/coinbase.js +176 -26
- package/js/src/coinlist.js +3 -4
- package/js/src/coinone.js +1 -1
- package/js/src/coinsph.js +2 -3
- package/js/src/deribit.js +1 -0
- package/js/src/gate.d.ts +4 -4
- package/js/src/gate.js +96 -59
- package/js/src/gemini.js +1 -1
- package/js/src/hitbtc.d.ts +4 -4
- package/js/src/hitbtc.js +2 -3
- package/js/src/htx.d.ts +1 -0
- package/js/src/htx.js +29 -7
- package/js/src/huobijp.js +2 -3
- package/js/src/independentreserve.js +7 -5
- package/js/src/kraken.js +3 -6
- package/js/src/lbank.js +59 -33
- package/js/src/mexc.js +2 -1
- package/js/src/oceanex.js +1 -1
- package/js/src/okx.js +14 -3
- package/js/src/phemex.js +9 -2
- package/js/src/pro/binance.d.ts +2 -23
- package/js/src/pro/binance.js +58 -22
- package/js/src/pro/coinbase.d.ts +2 -2
- package/js/src/pro/coinbase.js +4 -1
- package/js/src/pro/coinbasepro.d.ts +2 -2
- package/js/src/pro/hitbtc.d.ts +2 -2
- package/js/src/pro/kraken.js +1 -1
- package/js/src/pro/okx.d.ts +1 -0
- package/js/src/pro/okx.js +52 -2
- package/js/src/pro/poloniex.d.ts +2 -2
- package/js/src/probit.js +4 -2
- package/js/src/upbit.d.ts +3 -101
- package/js/src/upbit.js +12 -12
- package/js/src/wavesexchange.js +1 -1
- package/js/src/woo.d.ts +2 -0
- package/js/src/woo.js +52 -0
- package/package.json +1 -1
- package/skip-tests.json +5 -0
|
@@ -0,0 +1,2542 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tokocrypto$1 = require('./abstract/tokocrypto.js');
|
|
4
|
+
var number = require('./base/functions/number.js');
|
|
5
|
+
var errors = require('./base/errors.js');
|
|
6
|
+
var Precise = require('./base/Precise.js');
|
|
7
|
+
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* @class tokocrypto
|
|
13
|
+
* @augments Exchange
|
|
14
|
+
*/
|
|
15
|
+
class tokocrypto extends tokocrypto$1 {
|
|
16
|
+
describe() {
|
|
17
|
+
return this.deepExtend(super.describe(), {
|
|
18
|
+
'id': 'tokocrypto',
|
|
19
|
+
'name': 'Tokocrypto',
|
|
20
|
+
'countries': ['ID'],
|
|
21
|
+
'certified': false,
|
|
22
|
+
'pro': false,
|
|
23
|
+
'version': 'v1',
|
|
24
|
+
// new metainfo interface
|
|
25
|
+
'has': {
|
|
26
|
+
'CORS': undefined,
|
|
27
|
+
'spot': true,
|
|
28
|
+
'margin': true,
|
|
29
|
+
'swap': false,
|
|
30
|
+
'future': false,
|
|
31
|
+
'option': false,
|
|
32
|
+
'addMargin': undefined,
|
|
33
|
+
'borrowMargin': undefined,
|
|
34
|
+
'cancelAllOrders': false,
|
|
35
|
+
'cancelOrder': true,
|
|
36
|
+
'cancelOrders': undefined,
|
|
37
|
+
'createDepositAddress': false,
|
|
38
|
+
'createMarketBuyOrderWithCost': true,
|
|
39
|
+
'createMarketOrderWithCost': false,
|
|
40
|
+
'createMarketSellOrderWithCost': false,
|
|
41
|
+
'createOrder': true,
|
|
42
|
+
'createReduceOnlyOrder': undefined,
|
|
43
|
+
'createStopLimitOrder': true,
|
|
44
|
+
'createStopMarketOrder': true,
|
|
45
|
+
'createStopOrder': true,
|
|
46
|
+
'fetchAccounts': false,
|
|
47
|
+
'fetchBalance': true,
|
|
48
|
+
'fetchBidsAsks': true,
|
|
49
|
+
'fetchBorrowInterest': undefined,
|
|
50
|
+
'fetchBorrowRateHistories': undefined,
|
|
51
|
+
'fetchBorrowRateHistory': undefined,
|
|
52
|
+
'fetchCanceledOrders': false,
|
|
53
|
+
'fetchClosedOrder': false,
|
|
54
|
+
'fetchClosedOrders': 'emulated',
|
|
55
|
+
'fetchCrossBorrowRate': false,
|
|
56
|
+
'fetchCrossBorrowRates': false,
|
|
57
|
+
'fetchCurrencies': false,
|
|
58
|
+
'fetchDeposit': false,
|
|
59
|
+
'fetchDepositAddress': true,
|
|
60
|
+
'fetchDepositAddresses': false,
|
|
61
|
+
'fetchDepositAddressesByNetwork': false,
|
|
62
|
+
'fetchDeposits': true,
|
|
63
|
+
'fetchDepositsWithdrawals': false,
|
|
64
|
+
'fetchFundingHistory': false,
|
|
65
|
+
'fetchFundingRate': false,
|
|
66
|
+
'fetchFundingRateHistory': false,
|
|
67
|
+
'fetchFundingRates': false,
|
|
68
|
+
'fetchIndexOHLCV': false,
|
|
69
|
+
'fetchIsolatedBorrowRate': false,
|
|
70
|
+
'fetchIsolatedBorrowRates': false,
|
|
71
|
+
'fetchL3OrderBook': false,
|
|
72
|
+
'fetchLedger': undefined,
|
|
73
|
+
'fetchLeverage': false,
|
|
74
|
+
'fetchLeverageTiers': false,
|
|
75
|
+
'fetchMarketLeverageTiers': 'emulated',
|
|
76
|
+
'fetchMarkets': true,
|
|
77
|
+
'fetchMarkOHLCV': false,
|
|
78
|
+
'fetchMyTrades': true,
|
|
79
|
+
'fetchOHLCV': true,
|
|
80
|
+
'fetchOpenInterestHistory': false,
|
|
81
|
+
'fetchOpenOrder': false,
|
|
82
|
+
'fetchOpenOrders': true,
|
|
83
|
+
'fetchOrder': true,
|
|
84
|
+
'fetchOrderBook': true,
|
|
85
|
+
'fetchOrderBooks': false,
|
|
86
|
+
'fetchOrders': true,
|
|
87
|
+
'fetchOrderTrades': false,
|
|
88
|
+
'fetchPosition': false,
|
|
89
|
+
'fetchPositions': false,
|
|
90
|
+
'fetchPositionsRisk': false,
|
|
91
|
+
'fetchPremiumIndexOHLCV': false,
|
|
92
|
+
'fetchStatus': false,
|
|
93
|
+
'fetchTicker': false,
|
|
94
|
+
'fetchTickers': false,
|
|
95
|
+
'fetchTime': true,
|
|
96
|
+
'fetchTrades': true,
|
|
97
|
+
'fetchTradingFee': false,
|
|
98
|
+
'fetchTradingFees': false,
|
|
99
|
+
'fetchTradingLimits': false,
|
|
100
|
+
'fetchTransactionFee': false,
|
|
101
|
+
'fetchTransactionFees': false,
|
|
102
|
+
'fetchTransactions': false,
|
|
103
|
+
'fetchTransfers': false,
|
|
104
|
+
'fetchWithdrawal': false,
|
|
105
|
+
'fetchWithdrawals': true,
|
|
106
|
+
'fetchWithdrawalWhitelist': false,
|
|
107
|
+
'reduceMargin': false,
|
|
108
|
+
'repayCrossMargin': false,
|
|
109
|
+
'repayIsolatedMargin': false,
|
|
110
|
+
'setLeverage': false,
|
|
111
|
+
'setMargin': false,
|
|
112
|
+
'setMarginMode': false,
|
|
113
|
+
'setPositionMode': false,
|
|
114
|
+
'signIn': false,
|
|
115
|
+
'transfer': false,
|
|
116
|
+
'withdraw': true,
|
|
117
|
+
},
|
|
118
|
+
'timeframes': {
|
|
119
|
+
'1m': '1m',
|
|
120
|
+
'3m': '3m',
|
|
121
|
+
'5m': '5m',
|
|
122
|
+
'15m': '15m',
|
|
123
|
+
'30m': '30m',
|
|
124
|
+
'1h': '1h',
|
|
125
|
+
'2h': '2h',
|
|
126
|
+
'4h': '4h',
|
|
127
|
+
'6h': '6h',
|
|
128
|
+
'8h': '8h',
|
|
129
|
+
'12h': '12h',
|
|
130
|
+
'1d': '1d',
|
|
131
|
+
'3d': '3d',
|
|
132
|
+
'1w': '1w',
|
|
133
|
+
'1M': '1M',
|
|
134
|
+
},
|
|
135
|
+
'urls': {
|
|
136
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/183870484-d3398d0c-f6a1-4cce-91b8-d58792308716.jpg',
|
|
137
|
+
'api': {
|
|
138
|
+
'rest': {
|
|
139
|
+
'public': 'https://www.tokocrypto.com',
|
|
140
|
+
'binance': 'https://api.binance.com/api/v3',
|
|
141
|
+
'private': 'https://www.tokocrypto.com',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
'www': 'https://tokocrypto.com',
|
|
145
|
+
// 'referral': 'https://www.binance.us/?ref=35005074',
|
|
146
|
+
'doc': 'https://www.tokocrypto.com/apidocs/',
|
|
147
|
+
'fees': 'https://www.tokocrypto.com/fees/newschedule',
|
|
148
|
+
},
|
|
149
|
+
'api': {
|
|
150
|
+
'binance': {
|
|
151
|
+
'get': {
|
|
152
|
+
'ping': 1,
|
|
153
|
+
'time': 1,
|
|
154
|
+
'depth': { 'cost': 1, 'byLimit': [[100, 1], [500, 5], [1000, 10], [5000, 50]] },
|
|
155
|
+
'trades': 1,
|
|
156
|
+
'aggTrades': 1,
|
|
157
|
+
'historicalTrades': 5,
|
|
158
|
+
'klines': 1,
|
|
159
|
+
'ticker/24hr': { 'cost': 1, 'noSymbol': 40 },
|
|
160
|
+
'ticker/price': { 'cost': 1, 'noSymbol': 2 },
|
|
161
|
+
'ticker/bookTicker': { 'cost': 1, 'noSymbol': 2 },
|
|
162
|
+
'exchangeInfo': 10,
|
|
163
|
+
},
|
|
164
|
+
'put': {
|
|
165
|
+
'userDataStream': 1,
|
|
166
|
+
},
|
|
167
|
+
'post': {
|
|
168
|
+
'userDataStream': 1,
|
|
169
|
+
},
|
|
170
|
+
'delete': {
|
|
171
|
+
'userDataStream': 1,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
'public': {
|
|
175
|
+
'get': {
|
|
176
|
+
'open/v1/common/time': 1,
|
|
177
|
+
'open/v1/common/symbols': 1,
|
|
178
|
+
// all the actual symbols are type 1
|
|
179
|
+
'open/v1/market/depth': 1,
|
|
180
|
+
'open/v1/market/trades': 1,
|
|
181
|
+
'open/v1/market/agg-trades': 1,
|
|
182
|
+
'open/v1/market/klines': 1, // when symbol type is not 1
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
'private': {
|
|
186
|
+
'get': {
|
|
187
|
+
'open/v1/orders/detail': 1,
|
|
188
|
+
'open/v1/orders': 1,
|
|
189
|
+
'open/v1/account/spot': 1,
|
|
190
|
+
'open/v1/account/spot/asset': 1,
|
|
191
|
+
'open/v1/orders/trades': 1,
|
|
192
|
+
'open/v1/withdraws': 1,
|
|
193
|
+
'open/v1/deposits': 1,
|
|
194
|
+
'open/v1/deposits/address': 1,
|
|
195
|
+
},
|
|
196
|
+
'post': {
|
|
197
|
+
'open/v1/orders': 1,
|
|
198
|
+
'open/v1/orders/cancel': 1,
|
|
199
|
+
'open/v1/orders/oco': 1,
|
|
200
|
+
'open/v1/withdraws': 1,
|
|
201
|
+
'open/v1/user-data-stream': 1,
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
'fees': {
|
|
206
|
+
'trading': {
|
|
207
|
+
'tierBased': true,
|
|
208
|
+
'percentage': true,
|
|
209
|
+
'taker': this.parseNumber('0.0075'),
|
|
210
|
+
'maker': this.parseNumber('0.0075'), // 0.1% trading fee, zero fees for all trading pairs before November 1
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
'precisionMode': number.DECIMAL_PLACES,
|
|
214
|
+
'options': {
|
|
215
|
+
// 'fetchTradesMethod': 'binanceGetTrades', // binanceGetTrades, binanceGetAggTrades
|
|
216
|
+
'createMarketBuyOrderRequiresPrice': true,
|
|
217
|
+
'defaultTimeInForce': 'GTC',
|
|
218
|
+
// 'defaultType': 'spot', // 'spot', 'future', 'margin', 'delivery'
|
|
219
|
+
'hasAlreadyAuthenticatedSuccessfully': false,
|
|
220
|
+
'warnOnFetchOpenOrdersWithoutSymbol': true,
|
|
221
|
+
// 'fetchPositions': 'positionRisk', // or 'account'
|
|
222
|
+
'recvWindow': 5 * 1000,
|
|
223
|
+
'timeDifference': 0,
|
|
224
|
+
'adjustForTimeDifference': false,
|
|
225
|
+
'newOrderRespType': {
|
|
226
|
+
'market': 'FULL',
|
|
227
|
+
'limit': 'FULL', // we change it from 'ACK' by default to 'FULL' (returns immediately if limit is not hit)
|
|
228
|
+
},
|
|
229
|
+
'quoteOrderQty': false,
|
|
230
|
+
'networks': {
|
|
231
|
+
'ERC20': 'ETH',
|
|
232
|
+
'TRC20': 'TRX',
|
|
233
|
+
'BEP2': 'BNB',
|
|
234
|
+
'BEP20': 'BSC',
|
|
235
|
+
'OMNI': 'OMNI',
|
|
236
|
+
'EOS': 'EOS',
|
|
237
|
+
'SPL': 'SOL',
|
|
238
|
+
},
|
|
239
|
+
'reverseNetworks': {
|
|
240
|
+
'tronscan.org': 'TRC20',
|
|
241
|
+
'etherscan.io': 'ERC20',
|
|
242
|
+
'bscscan.com': 'BSC',
|
|
243
|
+
'explorer.binance.org': 'BEP2',
|
|
244
|
+
'bithomp.com': 'XRP',
|
|
245
|
+
'bloks.io': 'EOS',
|
|
246
|
+
'stellar.expert': 'XLM',
|
|
247
|
+
'blockchair.com/bitcoin': 'BTC',
|
|
248
|
+
'blockchair.com/bitcoin-cash': 'BCH',
|
|
249
|
+
'blockchair.com/ecash': 'XEC',
|
|
250
|
+
'explorer.litecoin.net': 'LTC',
|
|
251
|
+
'explorer.avax.network': 'AVAX',
|
|
252
|
+
'solscan.io': 'SOL',
|
|
253
|
+
'polkadot.subscan.io': 'DOT',
|
|
254
|
+
'dashboard.internetcomputer.org': 'ICP',
|
|
255
|
+
'explorer.chiliz.com': 'CHZ',
|
|
256
|
+
'cardanoscan.io': 'ADA',
|
|
257
|
+
'mainnet.theoan.com': 'AION',
|
|
258
|
+
'algoexplorer.io': 'ALGO',
|
|
259
|
+
'explorer.ambrosus.com': 'AMB',
|
|
260
|
+
'viewblock.io/zilliqa': 'ZIL',
|
|
261
|
+
'viewblock.io/arweave': 'AR',
|
|
262
|
+
'explorer.ark.io': 'ARK',
|
|
263
|
+
'atomscan.com': 'ATOM',
|
|
264
|
+
'www.mintscan.io': 'CTK',
|
|
265
|
+
'explorer.bitcoindiamond.org': 'BCD',
|
|
266
|
+
'btgexplorer.com': 'BTG',
|
|
267
|
+
'bts.ai': 'BTS',
|
|
268
|
+
'explorer.celo.org': 'CELO',
|
|
269
|
+
'explorer.nervos.org': 'CKB',
|
|
270
|
+
'cerebro.cortexlabs.ai': 'CTXC',
|
|
271
|
+
'chainz.cryptoid.info': 'VIA',
|
|
272
|
+
'explorer.dcrdata.org': 'DCR',
|
|
273
|
+
'digiexplorer.info': 'DGB',
|
|
274
|
+
'dock.subscan.io': 'DOCK',
|
|
275
|
+
'dogechain.info': 'DOGE',
|
|
276
|
+
'explorer.elrond.com': 'EGLD',
|
|
277
|
+
'blockscout.com': 'ETC',
|
|
278
|
+
'explore-fetchhub.fetch.ai': 'FET',
|
|
279
|
+
'filfox.info': 'FIL',
|
|
280
|
+
'fio.bloks.io': 'FIO',
|
|
281
|
+
'explorer.firo.org': 'FIRO',
|
|
282
|
+
'neoscan.io': 'NEO',
|
|
283
|
+
'ftmscan.com': 'FTM',
|
|
284
|
+
'explorer.gochain.io': 'GO',
|
|
285
|
+
'block.gxb.io': 'GXS',
|
|
286
|
+
'hash-hash.info': 'HBAR',
|
|
287
|
+
'www.hiveblockexplorer.com': 'HIVE',
|
|
288
|
+
'explorer.helium.com': 'HNT',
|
|
289
|
+
'tracker.icon.foundation': 'ICX',
|
|
290
|
+
'www.iostabc.com': 'IOST',
|
|
291
|
+
'explorer.iota.org': 'IOTA',
|
|
292
|
+
'iotexscan.io': 'IOTX',
|
|
293
|
+
'irishub.iobscan.io': 'IRIS',
|
|
294
|
+
'kava.mintscan.io': 'KAVA',
|
|
295
|
+
'scope.klaytn.com': 'KLAY',
|
|
296
|
+
'kmdexplorer.io': 'KMD',
|
|
297
|
+
'kusama.subscan.io': 'KSM',
|
|
298
|
+
'explorer.lto.network': 'LTO',
|
|
299
|
+
'polygonscan.com': 'POLYGON',
|
|
300
|
+
'explorer.ont.io': 'ONT',
|
|
301
|
+
'minaexplorer.com': 'MINA',
|
|
302
|
+
'nanolooker.com': 'NANO',
|
|
303
|
+
'explorer.nebulas.io': 'NAS',
|
|
304
|
+
'explorer.nbs.plus': 'NBS',
|
|
305
|
+
'explorer.nebl.io': 'NEBL',
|
|
306
|
+
'nulscan.io': 'NULS',
|
|
307
|
+
'nxscan.com': 'NXS',
|
|
308
|
+
'explorer.harmony.one': 'ONE',
|
|
309
|
+
'explorer.poa.network': 'POA',
|
|
310
|
+
'qtum.info': 'QTUM',
|
|
311
|
+
'explorer.rsk.co': 'RSK',
|
|
312
|
+
'www.oasisscan.com': 'ROSE',
|
|
313
|
+
'ravencoin.network': 'RVN',
|
|
314
|
+
'sc.tokenview.com': 'SC',
|
|
315
|
+
'secretnodes.com': 'SCRT',
|
|
316
|
+
'explorer.skycoin.com': 'SKY',
|
|
317
|
+
'steemscan.com': 'STEEM',
|
|
318
|
+
'explorer.stacks.co': 'STX',
|
|
319
|
+
'www.thetascan.io': 'THETA',
|
|
320
|
+
'scan.tomochain.com': 'TOMO',
|
|
321
|
+
'explore.vechain.org': 'VET',
|
|
322
|
+
'explorer.vite.net': 'VITE',
|
|
323
|
+
'www.wanscan.org': 'WAN',
|
|
324
|
+
'wavesexplorer.com': 'WAVES',
|
|
325
|
+
'wax.eosx.io': 'WAXP',
|
|
326
|
+
'waltonchain.pro': 'WTC',
|
|
327
|
+
'chain.nem.ninja': 'XEM',
|
|
328
|
+
'verge-blockchain.info': 'XVG',
|
|
329
|
+
'explorer.yoyow.org': 'YOYOW',
|
|
330
|
+
'explorer.zcha.in': 'ZEC',
|
|
331
|
+
'explorer.zensystem.io': 'ZEN',
|
|
332
|
+
},
|
|
333
|
+
'impliedNetworks': {
|
|
334
|
+
'ETH': { 'ERC20': 'ETH' },
|
|
335
|
+
'TRX': { 'TRC20': 'TRX' },
|
|
336
|
+
},
|
|
337
|
+
'legalMoney': {
|
|
338
|
+
'MXN': true,
|
|
339
|
+
'UGX': true,
|
|
340
|
+
'SEK': true,
|
|
341
|
+
'CHF': true,
|
|
342
|
+
'VND': true,
|
|
343
|
+
'AED': true,
|
|
344
|
+
'DKK': true,
|
|
345
|
+
'KZT': true,
|
|
346
|
+
'HUF': true,
|
|
347
|
+
'PEN': true,
|
|
348
|
+
'PHP': true,
|
|
349
|
+
'USD': true,
|
|
350
|
+
'TRY': true,
|
|
351
|
+
'EUR': true,
|
|
352
|
+
'NGN': true,
|
|
353
|
+
'PLN': true,
|
|
354
|
+
'BRL': true,
|
|
355
|
+
'ZAR': true,
|
|
356
|
+
'KES': true,
|
|
357
|
+
'ARS': true,
|
|
358
|
+
'RUB': true,
|
|
359
|
+
'AUD': true,
|
|
360
|
+
'NOK': true,
|
|
361
|
+
'CZK': true,
|
|
362
|
+
'GBP': true,
|
|
363
|
+
'UAH': true,
|
|
364
|
+
'GHS': true,
|
|
365
|
+
'HKD': true,
|
|
366
|
+
'CAD': true,
|
|
367
|
+
'INR': true,
|
|
368
|
+
'JPY': true,
|
|
369
|
+
'NZD': true,
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
// https://binance-docs.github.io/apidocs/spot/en/#error-codes-2
|
|
373
|
+
'exceptions': {
|
|
374
|
+
'exact': {
|
|
375
|
+
'System is under maintenance.': errors.OnMaintenance,
|
|
376
|
+
'System abnormality': errors.ExchangeError,
|
|
377
|
+
'You are not authorized to execute this request.': errors.PermissionDenied,
|
|
378
|
+
'API key does not exist': errors.AuthenticationError,
|
|
379
|
+
'Order would trigger immediately.': errors.OrderImmediatelyFillable,
|
|
380
|
+
'Stop price would trigger immediately.': errors.OrderImmediatelyFillable,
|
|
381
|
+
'Order would immediately match and take.': errors.OrderImmediatelyFillable,
|
|
382
|
+
'Account has insufficient balance for requested action.': errors.InsufficientFunds,
|
|
383
|
+
'Rest API trading is not enabled.': errors.ExchangeNotAvailable,
|
|
384
|
+
"You don't have permission.": errors.PermissionDenied,
|
|
385
|
+
'Market is closed.': errors.ExchangeNotAvailable,
|
|
386
|
+
'Too many requests. Please try again later.': errors.DDoSProtection,
|
|
387
|
+
'This action disabled is on this account.': errors.AccountSuspended,
|
|
388
|
+
'-1000': errors.ExchangeNotAvailable,
|
|
389
|
+
'-1001': errors.ExchangeNotAvailable,
|
|
390
|
+
'-1002': errors.AuthenticationError,
|
|
391
|
+
'-1003': errors.RateLimitExceeded,
|
|
392
|
+
'-1004': errors.DDoSProtection,
|
|
393
|
+
'-1005': errors.PermissionDenied,
|
|
394
|
+
'-1006': errors.BadResponse,
|
|
395
|
+
'-1007': errors.RequestTimeout,
|
|
396
|
+
'-1010': errors.BadResponse,
|
|
397
|
+
'-1011': errors.PermissionDenied,
|
|
398
|
+
'-1013': errors.InvalidOrder,
|
|
399
|
+
'-1014': errors.InvalidOrder,
|
|
400
|
+
'-1015': errors.RateLimitExceeded,
|
|
401
|
+
'-1016': errors.ExchangeNotAvailable,
|
|
402
|
+
'-1020': errors.BadRequest,
|
|
403
|
+
'-1021': errors.InvalidNonce,
|
|
404
|
+
'-1022': errors.AuthenticationError,
|
|
405
|
+
'-1023': errors.BadRequest,
|
|
406
|
+
'-1099': errors.AuthenticationError,
|
|
407
|
+
'-1100': errors.BadRequest,
|
|
408
|
+
'-1101': errors.BadRequest,
|
|
409
|
+
'-1102': errors.BadRequest,
|
|
410
|
+
'-1103': errors.BadRequest,
|
|
411
|
+
'-1104': errors.BadRequest,
|
|
412
|
+
'-1105': errors.BadRequest,
|
|
413
|
+
'-1106': errors.BadRequest,
|
|
414
|
+
'-1108': errors.BadRequest,
|
|
415
|
+
'-1109': errors.AuthenticationError,
|
|
416
|
+
'-1110': errors.BadRequest,
|
|
417
|
+
'-1111': errors.BadRequest,
|
|
418
|
+
'-1112': errors.InvalidOrder,
|
|
419
|
+
'-1113': errors.BadRequest,
|
|
420
|
+
'-1114': errors.BadRequest,
|
|
421
|
+
'-1115': errors.BadRequest,
|
|
422
|
+
'-1116': errors.BadRequest,
|
|
423
|
+
'-1117': errors.BadRequest,
|
|
424
|
+
'-1118': errors.BadRequest,
|
|
425
|
+
'-1119': errors.BadRequest,
|
|
426
|
+
'-1120': errors.BadRequest,
|
|
427
|
+
'-1121': errors.BadSymbol,
|
|
428
|
+
'-1125': errors.AuthenticationError,
|
|
429
|
+
'-1127': errors.BadRequest,
|
|
430
|
+
'-1128': errors.BadRequest,
|
|
431
|
+
'-1130': errors.BadRequest,
|
|
432
|
+
'-1131': errors.BadRequest,
|
|
433
|
+
'-1136': errors.BadRequest,
|
|
434
|
+
'-2008': errors.AuthenticationError,
|
|
435
|
+
'-2010': errors.ExchangeError,
|
|
436
|
+
'-2011': errors.OrderNotFound,
|
|
437
|
+
'-2013': errors.OrderNotFound,
|
|
438
|
+
'-2014': errors.AuthenticationError,
|
|
439
|
+
'-2015': errors.AuthenticationError,
|
|
440
|
+
'-2016': errors.BadRequest,
|
|
441
|
+
'-2018': errors.InsufficientFunds,
|
|
442
|
+
'-2019': errors.InsufficientFunds,
|
|
443
|
+
'-2020': errors.OrderNotFillable,
|
|
444
|
+
'-2021': errors.OrderImmediatelyFillable,
|
|
445
|
+
'-2022': errors.InvalidOrder,
|
|
446
|
+
'-2023': errors.InsufficientFunds,
|
|
447
|
+
'-2024': errors.InsufficientFunds,
|
|
448
|
+
'-2025': errors.InvalidOrder,
|
|
449
|
+
'-2026': errors.InvalidOrder,
|
|
450
|
+
'-2027': errors.InvalidOrder,
|
|
451
|
+
'-2028': errors.InsufficientFunds,
|
|
452
|
+
'-3000': errors.ExchangeError,
|
|
453
|
+
'-3001': errors.AuthenticationError,
|
|
454
|
+
'-3002': errors.BadSymbol,
|
|
455
|
+
'-3003': errors.BadRequest,
|
|
456
|
+
'-3004': errors.ExchangeError,
|
|
457
|
+
'-3005': errors.InsufficientFunds,
|
|
458
|
+
'-3006': errors.InsufficientFunds,
|
|
459
|
+
'-3007': errors.ExchangeError,
|
|
460
|
+
'-3008': errors.InsufficientFunds,
|
|
461
|
+
'-3009': errors.BadRequest,
|
|
462
|
+
'-3010': errors.ExchangeError,
|
|
463
|
+
'-3011': errors.BadRequest,
|
|
464
|
+
'-3012': errors.ExchangeError,
|
|
465
|
+
'-3013': errors.BadRequest,
|
|
466
|
+
'-3014': errors.AccountSuspended,
|
|
467
|
+
'-3015': errors.ExchangeError,
|
|
468
|
+
'-3016': errors.BadRequest,
|
|
469
|
+
'-3017': errors.ExchangeError,
|
|
470
|
+
'-3018': errors.AccountSuspended,
|
|
471
|
+
'-3019': errors.AccountSuspended,
|
|
472
|
+
'-3020': errors.InsufficientFunds,
|
|
473
|
+
'-3021': errors.BadRequest,
|
|
474
|
+
'-3022': errors.AccountSuspended,
|
|
475
|
+
'-3023': errors.BadRequest,
|
|
476
|
+
'-3024': errors.ExchangeError,
|
|
477
|
+
'-3025': errors.BadRequest,
|
|
478
|
+
'-3026': errors.BadRequest,
|
|
479
|
+
'-3027': errors.BadSymbol,
|
|
480
|
+
'-3028': errors.BadSymbol,
|
|
481
|
+
'-3029': errors.ExchangeError,
|
|
482
|
+
'-3036': errors.AccountSuspended,
|
|
483
|
+
'-3037': errors.ExchangeError,
|
|
484
|
+
'-3038': errors.BadRequest,
|
|
485
|
+
'-3041': errors.InsufficientFunds,
|
|
486
|
+
'-3042': errors.BadRequest,
|
|
487
|
+
'-3043': errors.BadRequest,
|
|
488
|
+
'-3044': errors.DDoSProtection,
|
|
489
|
+
'-3045': errors.ExchangeError,
|
|
490
|
+
'-3999': errors.ExchangeError,
|
|
491
|
+
'-4001': errors.BadRequest,
|
|
492
|
+
'-4002': errors.BadRequest,
|
|
493
|
+
'-4003': errors.BadRequest,
|
|
494
|
+
'-4004': errors.AuthenticationError,
|
|
495
|
+
'-4005': errors.RateLimitExceeded,
|
|
496
|
+
'-4006': errors.BadRequest,
|
|
497
|
+
'-4007': errors.BadRequest,
|
|
498
|
+
'-4008': errors.BadRequest,
|
|
499
|
+
'-4010': errors.BadRequest,
|
|
500
|
+
'-4011': errors.BadRequest,
|
|
501
|
+
'-4012': errors.BadRequest,
|
|
502
|
+
'-4013': errors.AuthenticationError,
|
|
503
|
+
'-4014': errors.PermissionDenied,
|
|
504
|
+
'-4015': errors.ExchangeError,
|
|
505
|
+
'-4016': errors.PermissionDenied,
|
|
506
|
+
'-4017': errors.PermissionDenied,
|
|
507
|
+
'-4018': errors.BadSymbol,
|
|
508
|
+
'-4019': errors.BadSymbol,
|
|
509
|
+
'-4021': errors.BadRequest,
|
|
510
|
+
'-4022': errors.BadRequest,
|
|
511
|
+
'-4023': errors.ExchangeError,
|
|
512
|
+
'-4024': errors.InsufficientFunds,
|
|
513
|
+
'-4025': errors.InsufficientFunds,
|
|
514
|
+
'-4026': errors.InsufficientFunds,
|
|
515
|
+
'-4027': errors.ExchangeError,
|
|
516
|
+
'-4028': errors.BadRequest,
|
|
517
|
+
'-4029': errors.BadRequest,
|
|
518
|
+
'-4030': errors.ExchangeError,
|
|
519
|
+
'-4031': errors.ExchangeError,
|
|
520
|
+
'-4032': errors.ExchangeError,
|
|
521
|
+
'-4033': errors.BadRequest,
|
|
522
|
+
'-4034': errors.ExchangeError,
|
|
523
|
+
'-4035': errors.PermissionDenied,
|
|
524
|
+
'-4036': errors.BadRequest,
|
|
525
|
+
'-4037': errors.ExchangeError,
|
|
526
|
+
'-4038': errors.ExchangeError,
|
|
527
|
+
'-4039': errors.BadRequest,
|
|
528
|
+
'-4040': errors.BadRequest,
|
|
529
|
+
'-4041': errors.ExchangeError,
|
|
530
|
+
'-4042': errors.ExchangeError,
|
|
531
|
+
'-4043': errors.BadRequest,
|
|
532
|
+
'-4044': errors.BadRequest,
|
|
533
|
+
'-4045': errors.ExchangeError,
|
|
534
|
+
'-4046': errors.AuthenticationError,
|
|
535
|
+
'-4047': errors.BadRequest,
|
|
536
|
+
'-5001': errors.BadRequest,
|
|
537
|
+
'-5002': errors.InsufficientFunds,
|
|
538
|
+
'-5003': errors.InsufficientFunds,
|
|
539
|
+
'-5004': errors.BadRequest,
|
|
540
|
+
'-5005': errors.InsufficientFunds,
|
|
541
|
+
'-5006': errors.BadRequest,
|
|
542
|
+
'-5007': errors.BadRequest,
|
|
543
|
+
'-5008': errors.InsufficientFunds,
|
|
544
|
+
'-5009': errors.BadRequest,
|
|
545
|
+
'-5010': errors.ExchangeError,
|
|
546
|
+
'-5011': errors.BadRequest,
|
|
547
|
+
'-5012': errors.ExchangeError,
|
|
548
|
+
'-5013': errors.InsufficientFunds,
|
|
549
|
+
'-5021': errors.BadRequest,
|
|
550
|
+
'-6001': errors.BadRequest,
|
|
551
|
+
'-6003': errors.BadRequest,
|
|
552
|
+
'-6004': errors.ExchangeError,
|
|
553
|
+
'-6005': errors.InvalidOrder,
|
|
554
|
+
'-6006': errors.BadRequest,
|
|
555
|
+
'-6007': errors.BadRequest,
|
|
556
|
+
'-6008': errors.BadRequest,
|
|
557
|
+
'-6009': errors.RateLimitExceeded,
|
|
558
|
+
'-6011': errors.BadRequest,
|
|
559
|
+
'-6012': errors.InsufficientFunds,
|
|
560
|
+
'-6013': errors.ExchangeError,
|
|
561
|
+
'-6014': errors.BadRequest,
|
|
562
|
+
'-6015': errors.BadRequest,
|
|
563
|
+
'-6016': errors.BadRequest,
|
|
564
|
+
'-6017': errors.BadRequest,
|
|
565
|
+
'-6018': errors.BadRequest,
|
|
566
|
+
'-6019': errors.AuthenticationError,
|
|
567
|
+
'-6020': errors.BadRequest,
|
|
568
|
+
'-7001': errors.BadRequest,
|
|
569
|
+
'-7002': errors.BadRequest,
|
|
570
|
+
'-9000': errors.InsufficientFunds,
|
|
571
|
+
'-10017': errors.BadRequest,
|
|
572
|
+
'-11008': errors.InsufficientFunds,
|
|
573
|
+
'-12014': errors.RateLimitExceeded,
|
|
574
|
+
'-13000': errors.BadRequest,
|
|
575
|
+
'-13001': errors.BadRequest,
|
|
576
|
+
'-13002': errors.BadRequest,
|
|
577
|
+
'-13003': errors.BadRequest,
|
|
578
|
+
'-13004': errors.BadRequest,
|
|
579
|
+
'-13005': errors.BadRequest,
|
|
580
|
+
'-13006': errors.InvalidOrder,
|
|
581
|
+
'-13007': errors.AuthenticationError,
|
|
582
|
+
'-21001': errors.BadRequest,
|
|
583
|
+
'-21002': errors.BadRequest,
|
|
584
|
+
'-21003': errors.BadRequest,
|
|
585
|
+
'100001003': errors.BadRequest,
|
|
586
|
+
'2202': errors.InsufficientFunds,
|
|
587
|
+
'3210': errors.InvalidOrder,
|
|
588
|
+
'3203': errors.InvalidOrder,
|
|
589
|
+
'3211': errors.InvalidOrder,
|
|
590
|
+
'3207': errors.InvalidOrder,
|
|
591
|
+
'3218': errors.OrderNotFound, // {"code":3218,"msg":"Order does not exist","timestamp":1662739749275}
|
|
592
|
+
},
|
|
593
|
+
'broad': {
|
|
594
|
+
'has no operation privilege': errors.PermissionDenied,
|
|
595
|
+
'MAX_POSITION': errors.InvalidOrder, // {"code":-2010,"msg":"Filter failure: MAX_POSITION"}
|
|
596
|
+
},
|
|
597
|
+
},
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
nonce() {
|
|
601
|
+
return this.milliseconds() - this.options['timeDifference'];
|
|
602
|
+
}
|
|
603
|
+
async fetchTime(params = {}) {
|
|
604
|
+
/**
|
|
605
|
+
* @method
|
|
606
|
+
* @name tokocrypto#fetchTime
|
|
607
|
+
* @see https://www.tokocrypto.com/apidocs/#check-server-time
|
|
608
|
+
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
609
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
610
|
+
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
611
|
+
*/
|
|
612
|
+
const response = await this.publicGetOpenV1CommonTime(params);
|
|
613
|
+
//
|
|
614
|
+
//
|
|
615
|
+
//
|
|
616
|
+
return this.safeInteger(response, 'serverTime');
|
|
617
|
+
}
|
|
618
|
+
async fetchMarkets(params = {}) {
|
|
619
|
+
/**
|
|
620
|
+
* @method
|
|
621
|
+
* @name tokocrypto#fetchMarkets
|
|
622
|
+
* @see https://www.tokocrypto.com/apidocs/#get-all-supported-trading-symbol
|
|
623
|
+
* @description retrieves data on all markets for tokocrypto
|
|
624
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
625
|
+
* @returns {object[]} an array of objects representing market data
|
|
626
|
+
*/
|
|
627
|
+
const response = await this.publicGetOpenV1CommonSymbols(params);
|
|
628
|
+
//
|
|
629
|
+
// {
|
|
630
|
+
// "code":0,
|
|
631
|
+
// "msg":"Success",
|
|
632
|
+
// "data":{
|
|
633
|
+
// "list":[
|
|
634
|
+
// {
|
|
635
|
+
// "type":1,
|
|
636
|
+
// "symbol":"1INCH_BTC",
|
|
637
|
+
// "baseAsset":"1INCH",
|
|
638
|
+
// "basePrecision":8,
|
|
639
|
+
// "quoteAsset":"BTC",
|
|
640
|
+
// "quotePrecision":8,
|
|
641
|
+
// "filters":[
|
|
642
|
+
// {"filterType":"PRICE_FILTER","minPrice":"0.00000001","maxPrice":"1000.00000000","tickSize":"0.00000001","applyToMarket":false},
|
|
643
|
+
// {"filterType":"PERCENT_PRICE","multiplierUp":5,"multiplierDown":0.2,"avgPriceMins":"5","applyToMarket":false},
|
|
644
|
+
// {"filterType":"LOT_SIZE","minQty":"0.10000000","maxQty":"90000000.00000000","stepSize":"0.10000000","applyToMarket":false},
|
|
645
|
+
// {"filterType":"MIN_NOTIONAL","avgPriceMins":"5","minNotional":"0.00010000","applyToMarket":true},
|
|
646
|
+
// {"filterType":"ICEBERG_PARTS","applyToMarket":false,"limit":"10"},
|
|
647
|
+
// {"filterType":"MARKET_LOT_SIZE","minQty":"0.00000000","maxQty":"79460.14117231","stepSize":"0.00000000","applyToMarket":false},
|
|
648
|
+
// {"filterType":"TRAILING_DELTA","applyToMarket":false},
|
|
649
|
+
// {"filterType":"MAX_NUM_ORDERS","applyToMarket":false},
|
|
650
|
+
// {"filterType":"MAX_NUM_ALGO_ORDERS","applyToMarket":false,"maxNumAlgoOrders":"5"}
|
|
651
|
+
// ],
|
|
652
|
+
// "orderTypes":["LIMIT","LIMIT_MAKER","MARKET","STOP_LOSS_LIMIT","TAKE_PROFIT_LIMIT"],
|
|
653
|
+
// "icebergEnable":1,
|
|
654
|
+
// "ocoEnable":1,
|
|
655
|
+
// "spotTradingEnable":1,
|
|
656
|
+
// "marginTradingEnable":1,
|
|
657
|
+
// "permissions":["SPOT","MARGIN"]
|
|
658
|
+
// },
|
|
659
|
+
// ]
|
|
660
|
+
// },
|
|
661
|
+
// "timestamp":1659492212507
|
|
662
|
+
// }
|
|
663
|
+
//
|
|
664
|
+
if (this.options['adjustForTimeDifference']) {
|
|
665
|
+
await this.loadTimeDifference();
|
|
666
|
+
}
|
|
667
|
+
const data = this.safeValue(response, 'data', {});
|
|
668
|
+
const list = this.safeValue(data, 'list', []);
|
|
669
|
+
const result = [];
|
|
670
|
+
for (let i = 0; i < list.length; i++) {
|
|
671
|
+
const market = list[i];
|
|
672
|
+
const baseId = this.safeString(market, 'baseAsset');
|
|
673
|
+
const quoteId = this.safeString(market, 'quoteAsset');
|
|
674
|
+
const id = this.safeString(market, 'symbol');
|
|
675
|
+
const lowercaseId = this.safeStringLower(market, 'symbol');
|
|
676
|
+
const settleId = this.safeString(market, 'marginAsset');
|
|
677
|
+
const base = this.safeCurrencyCode(baseId);
|
|
678
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
679
|
+
const settle = this.safeCurrencyCode(settleId);
|
|
680
|
+
const symbol = base + '/' + quote;
|
|
681
|
+
const filters = this.safeValue(market, 'filters', []);
|
|
682
|
+
const filtersByType = this.indexBy(filters, 'filterType');
|
|
683
|
+
const status = this.safeString(market, 'spotTradingEnable');
|
|
684
|
+
let active = (status === '1');
|
|
685
|
+
const permissions = this.safeValue(market, 'permissions', []);
|
|
686
|
+
for (let j = 0; j < permissions.length; j++) {
|
|
687
|
+
if (permissions[j] === 'TRD_GRP_003') {
|
|
688
|
+
active = false;
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
const isMarginTradingAllowed = this.safeValue(market, 'isMarginTradingAllowed', false);
|
|
693
|
+
const entry = {
|
|
694
|
+
'id': id,
|
|
695
|
+
'lowercaseId': lowercaseId,
|
|
696
|
+
'symbol': symbol,
|
|
697
|
+
'base': base,
|
|
698
|
+
'quote': quote,
|
|
699
|
+
'settle': settle,
|
|
700
|
+
'baseId': baseId,
|
|
701
|
+
'quoteId': quoteId,
|
|
702
|
+
'settleId': settleId,
|
|
703
|
+
'type': 'spot',
|
|
704
|
+
'spot': true,
|
|
705
|
+
'margin': isMarginTradingAllowed,
|
|
706
|
+
'swap': false,
|
|
707
|
+
'future': false,
|
|
708
|
+
'delivery': false,
|
|
709
|
+
'option': false,
|
|
710
|
+
'active': active,
|
|
711
|
+
'contract': false,
|
|
712
|
+
'linear': undefined,
|
|
713
|
+
'inverse': undefined,
|
|
714
|
+
'contractSize': undefined,
|
|
715
|
+
'expiry': undefined,
|
|
716
|
+
'expiryDatetime': undefined,
|
|
717
|
+
'strike': undefined,
|
|
718
|
+
'optionType': undefined,
|
|
719
|
+
'precision': {
|
|
720
|
+
'amount': this.safeInteger(market, 'quantityPrecision'),
|
|
721
|
+
'price': this.safeInteger(market, 'pricePrecision'),
|
|
722
|
+
'base': this.safeInteger(market, 'baseAssetPrecision'),
|
|
723
|
+
'quote': this.safeInteger(market, 'quotePrecision'),
|
|
724
|
+
},
|
|
725
|
+
'limits': {
|
|
726
|
+
'leverage': {
|
|
727
|
+
'min': undefined,
|
|
728
|
+
'max': undefined,
|
|
729
|
+
},
|
|
730
|
+
'amount': {
|
|
731
|
+
'min': undefined,
|
|
732
|
+
'max': undefined,
|
|
733
|
+
},
|
|
734
|
+
'price': {
|
|
735
|
+
'min': undefined,
|
|
736
|
+
'max': undefined,
|
|
737
|
+
},
|
|
738
|
+
'cost': {
|
|
739
|
+
'min': undefined,
|
|
740
|
+
'max': undefined,
|
|
741
|
+
},
|
|
742
|
+
},
|
|
743
|
+
'created': undefined,
|
|
744
|
+
'info': market,
|
|
745
|
+
};
|
|
746
|
+
if ('PRICE_FILTER' in filtersByType) {
|
|
747
|
+
const filter = this.safeValue(filtersByType, 'PRICE_FILTER', {});
|
|
748
|
+
const tickSize = this.safeString(filter, 'tickSize');
|
|
749
|
+
entry['precision']['price'] = this.precisionFromString(tickSize);
|
|
750
|
+
// PRICE_FILTER reports zero values for maxPrice
|
|
751
|
+
// since they updated filter types in November 2018
|
|
752
|
+
// https://github.com/ccxt/ccxt/issues/4286
|
|
753
|
+
// therefore limits['price']['max'] doesn't have any meaningful value except undefined
|
|
754
|
+
entry['limits']['price'] = {
|
|
755
|
+
'min': this.safeNumber(filter, 'minPrice'),
|
|
756
|
+
'max': this.safeNumber(filter, 'maxPrice'),
|
|
757
|
+
};
|
|
758
|
+
entry['precision']['price'] = this.precisionFromString(filter['tickSize']);
|
|
759
|
+
}
|
|
760
|
+
if ('LOT_SIZE' in filtersByType) {
|
|
761
|
+
const filter = this.safeValue(filtersByType, 'LOT_SIZE', {});
|
|
762
|
+
const stepSize = this.safeString(filter, 'stepSize');
|
|
763
|
+
entry['precision']['amount'] = this.precisionFromString(stepSize);
|
|
764
|
+
entry['limits']['amount'] = {
|
|
765
|
+
'min': this.safeNumber(filter, 'minQty'),
|
|
766
|
+
'max': this.safeNumber(filter, 'maxQty'),
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
if ('MARKET_LOT_SIZE' in filtersByType) {
|
|
770
|
+
const filter = this.safeValue(filtersByType, 'MARKET_LOT_SIZE', {});
|
|
771
|
+
entry['limits']['market'] = {
|
|
772
|
+
'min': this.safeNumber(filter, 'minQty'),
|
|
773
|
+
'max': this.safeNumber(filter, 'maxQty'),
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
if ('MIN_NOTIONAL' in filtersByType) {
|
|
777
|
+
const filter = this.safeValue(filtersByType, 'MIN_NOTIONAL', {});
|
|
778
|
+
entry['limits']['cost']['min'] = this.safeNumber2(filter, 'minNotional', 'notional');
|
|
779
|
+
}
|
|
780
|
+
result.push(entry);
|
|
781
|
+
}
|
|
782
|
+
return result;
|
|
783
|
+
}
|
|
784
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
785
|
+
/**
|
|
786
|
+
* @method
|
|
787
|
+
* @name tokocrypto#fetchOrderBook
|
|
788
|
+
* @see https://www.tokocrypto.com/apidocs/#order-book
|
|
789
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
790
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
791
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
792
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
793
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
794
|
+
*/
|
|
795
|
+
await this.loadMarkets();
|
|
796
|
+
const market = this.market(symbol);
|
|
797
|
+
const request = {};
|
|
798
|
+
if (limit !== undefined) {
|
|
799
|
+
request['limit'] = limit; // default 100, max 5000, see https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#order-book
|
|
800
|
+
}
|
|
801
|
+
let response = undefined;
|
|
802
|
+
if (market['quote'] === 'USDT') {
|
|
803
|
+
request['symbol'] = market['baseId'] + market['quoteId'];
|
|
804
|
+
response = await this.binanceGetDepth(this.extend(request, params));
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
request['symbol'] = market['id'];
|
|
808
|
+
response = await this.publicGetOpenV1MarketDepth(this.extend(request, params));
|
|
809
|
+
}
|
|
810
|
+
//
|
|
811
|
+
// future
|
|
812
|
+
//
|
|
813
|
+
// {
|
|
814
|
+
// "lastUpdateId":333598053905,
|
|
815
|
+
// "E":1618631511986,
|
|
816
|
+
// "T":1618631511964,
|
|
817
|
+
// "bids":[
|
|
818
|
+
// ["2493.56","20.189"],
|
|
819
|
+
// ["2493.54","1.000"],
|
|
820
|
+
// ["2493.51","0.005"]
|
|
821
|
+
// ],
|
|
822
|
+
// "asks":[
|
|
823
|
+
// ["2493.57","0.877"],
|
|
824
|
+
// ["2493.62","0.063"],
|
|
825
|
+
// ["2493.71","12.054"],
|
|
826
|
+
// ]
|
|
827
|
+
// }
|
|
828
|
+
// type not 1
|
|
829
|
+
// {
|
|
830
|
+
// "code":0,
|
|
831
|
+
// "msg":"Success",
|
|
832
|
+
// "data":{
|
|
833
|
+
// "lastUpdateId":3204783,
|
|
834
|
+
// "bids":[],
|
|
835
|
+
// "asks": []
|
|
836
|
+
// },
|
|
837
|
+
// "timestamp":1692262634599
|
|
838
|
+
// }
|
|
839
|
+
const data = this.safeValue(response, 'data', response);
|
|
840
|
+
const timestamp = this.safeInteger2(response, 'T', 'timestamp');
|
|
841
|
+
const orderbook = this.parseOrderBook(data, symbol, timestamp);
|
|
842
|
+
orderbook['nonce'] = this.safeInteger(data, 'lastUpdateId');
|
|
843
|
+
return orderbook;
|
|
844
|
+
}
|
|
845
|
+
parseTrade(trade, market = undefined) {
|
|
846
|
+
//
|
|
847
|
+
// aggregate trades
|
|
848
|
+
// https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list
|
|
849
|
+
//
|
|
850
|
+
// {
|
|
851
|
+
// "a": 26129, // Aggregate tradeId
|
|
852
|
+
// "p": "0.01633102", // Price
|
|
853
|
+
// "q": "4.70443515", // Quantity
|
|
854
|
+
// "f": 27781, // First tradeId
|
|
855
|
+
// "l": 27781, // Last tradeId
|
|
856
|
+
// "T": 1498793709153, // Timestamp
|
|
857
|
+
// "m": true, // Was the buyer the maker?
|
|
858
|
+
// "M": true // Was the trade the best price match?
|
|
859
|
+
// }
|
|
860
|
+
//
|
|
861
|
+
// recent public trades and old public trades
|
|
862
|
+
// https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#recent-trades-list
|
|
863
|
+
// https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#old-trade-lookup-market_data
|
|
864
|
+
//
|
|
865
|
+
// {
|
|
866
|
+
// "id": 28457,
|
|
867
|
+
// "price": "4.00000100",
|
|
868
|
+
// "qty": "12.00000000",
|
|
869
|
+
// "time": 1499865549590,
|
|
870
|
+
// "isBuyerMaker": true,
|
|
871
|
+
// "isBestMatch": true
|
|
872
|
+
// }
|
|
873
|
+
//
|
|
874
|
+
// private trades
|
|
875
|
+
// https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#account-trade-list-user_data
|
|
876
|
+
//
|
|
877
|
+
// {
|
|
878
|
+
// "symbol": "BNBBTC",
|
|
879
|
+
// "id": 28457,
|
|
880
|
+
// "orderId": 100234,
|
|
881
|
+
// "price": "4.00000100",
|
|
882
|
+
// "qty": "12.00000000",
|
|
883
|
+
// "commission": "10.10000000",
|
|
884
|
+
// "commissionAsset": "BNB",
|
|
885
|
+
// "time": 1499865549590,
|
|
886
|
+
// "isBuyer": true,
|
|
887
|
+
// "isMaker": false,
|
|
888
|
+
// "isBestMatch": true
|
|
889
|
+
// }
|
|
890
|
+
//
|
|
891
|
+
// futures trades
|
|
892
|
+
// https://binance-docs.github.io/apidocs/futures/en/#account-trade-list-user_data
|
|
893
|
+
//
|
|
894
|
+
// {
|
|
895
|
+
// "accountId": 20,
|
|
896
|
+
// "buyer": False,
|
|
897
|
+
// "commission": "-0.07819010",
|
|
898
|
+
// "commissionAsset": "USDT",
|
|
899
|
+
// "counterPartyId": 653,
|
|
900
|
+
// "id": 698759,
|
|
901
|
+
// "maker": False,
|
|
902
|
+
// "orderId": 25851813,
|
|
903
|
+
// "price": "7819.01",
|
|
904
|
+
// "qty": "0.002",
|
|
905
|
+
// "quoteQty": "0.01563",
|
|
906
|
+
// "realizedPnl": "-0.91539999",
|
|
907
|
+
// "side": "SELL",
|
|
908
|
+
// "symbol": "BTCUSDT",
|
|
909
|
+
// "time": 1569514978020
|
|
910
|
+
// }
|
|
911
|
+
// {
|
|
912
|
+
// "symbol": "BTCUSDT",
|
|
913
|
+
// "id": 477128891,
|
|
914
|
+
// "orderId": 13809777875,
|
|
915
|
+
// "side": "SELL",
|
|
916
|
+
// "price": "38479.55",
|
|
917
|
+
// "qty": "0.001",
|
|
918
|
+
// "realizedPnl": "-0.00009534",
|
|
919
|
+
// "marginAsset": "USDT",
|
|
920
|
+
// "quoteQty": "38.47955",
|
|
921
|
+
// "commission": "-0.00076959",
|
|
922
|
+
// "commissionAsset": "USDT",
|
|
923
|
+
// "time": 1612733566708,
|
|
924
|
+
// "positionSide": "BOTH",
|
|
925
|
+
// "maker": true,
|
|
926
|
+
// "buyer": false
|
|
927
|
+
// }
|
|
928
|
+
//
|
|
929
|
+
// { respType: FULL }
|
|
930
|
+
//
|
|
931
|
+
// {
|
|
932
|
+
// "price": "4000.00000000",
|
|
933
|
+
// "qty": "1.00000000",
|
|
934
|
+
// "commission": "4.00000000",
|
|
935
|
+
// "commissionAsset": "USDT",
|
|
936
|
+
// "tradeId": "1234",
|
|
937
|
+
// }
|
|
938
|
+
//
|
|
939
|
+
const timestamp = this.safeInteger2(trade, 'T', 'time');
|
|
940
|
+
const price = this.safeString2(trade, 'p', 'price');
|
|
941
|
+
const amount = this.safeString2(trade, 'q', 'qty');
|
|
942
|
+
const cost = this.safeString2(trade, 'quoteQty', 'baseQty'); // inverse futures
|
|
943
|
+
const marketId = this.safeString(trade, 'symbol');
|
|
944
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
945
|
+
let id = this.safeString2(trade, 't', 'a');
|
|
946
|
+
id = this.safeString2(trade, 'id', 'tradeId', id);
|
|
947
|
+
let side = undefined;
|
|
948
|
+
const orderId = this.safeString(trade, 'orderId');
|
|
949
|
+
const buyerMaker = this.safeValue2(trade, 'm', 'isBuyerMaker');
|
|
950
|
+
let takerOrMaker = undefined;
|
|
951
|
+
if (buyerMaker !== undefined) {
|
|
952
|
+
side = buyerMaker ? 'sell' : 'buy'; // this is reversed intentionally
|
|
953
|
+
takerOrMaker = 'taker';
|
|
954
|
+
}
|
|
955
|
+
else if ('side' in trade) {
|
|
956
|
+
side = this.safeStringLower(trade, 'side');
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
if ('isBuyer' in trade) {
|
|
960
|
+
side = trade['isBuyer'] ? 'buy' : 'sell'; // this is a true side
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
let fee = undefined;
|
|
964
|
+
if ('commission' in trade) {
|
|
965
|
+
fee = {
|
|
966
|
+
'cost': this.safeString(trade, 'commission'),
|
|
967
|
+
'currency': this.safeCurrencyCode(this.safeString(trade, 'commissionAsset')),
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
if ('isMaker' in trade) {
|
|
971
|
+
takerOrMaker = trade['isMaker'] ? 'maker' : 'taker';
|
|
972
|
+
}
|
|
973
|
+
if ('maker' in trade) {
|
|
974
|
+
takerOrMaker = trade['maker'] ? 'maker' : 'taker';
|
|
975
|
+
}
|
|
976
|
+
return this.safeTrade({
|
|
977
|
+
'info': trade,
|
|
978
|
+
'timestamp': timestamp,
|
|
979
|
+
'datetime': this.iso8601(timestamp),
|
|
980
|
+
'symbol': symbol,
|
|
981
|
+
'id': id,
|
|
982
|
+
'order': orderId,
|
|
983
|
+
'type': undefined,
|
|
984
|
+
'side': side,
|
|
985
|
+
'takerOrMaker': takerOrMaker,
|
|
986
|
+
'price': price,
|
|
987
|
+
'amount': amount,
|
|
988
|
+
'cost': cost,
|
|
989
|
+
'fee': fee,
|
|
990
|
+
}, market);
|
|
991
|
+
}
|
|
992
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
993
|
+
/**
|
|
994
|
+
* @method
|
|
995
|
+
* @name tokocrypto#fetchTrades
|
|
996
|
+
* @see https://www.tokocrypto.com/apidocs/#recent-trades-list
|
|
997
|
+
* @see https://www.tokocrypto.com/apidocs/#compressedaggregate-trades-list
|
|
998
|
+
* @description get the list of most recent trades for a particular symbol
|
|
999
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1000
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1001
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1002
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1003
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1004
|
+
*/
|
|
1005
|
+
await this.loadMarkets();
|
|
1006
|
+
const market = this.market(symbol);
|
|
1007
|
+
const request = {
|
|
1008
|
+
'symbol': this.getMarketIdByType(market),
|
|
1009
|
+
// 'fromId': 123, // ID to get aggregate trades from INCLUSIVE.
|
|
1010
|
+
// 'startTime': 456, // Timestamp in ms to get aggregate trades from INCLUSIVE.
|
|
1011
|
+
// 'endTime': 789, // Timestamp in ms to get aggregate trades until INCLUSIVE.
|
|
1012
|
+
// 'limit': 500, // default = 500, maximum = 1000
|
|
1013
|
+
};
|
|
1014
|
+
if (market['quote'] !== 'USDT') {
|
|
1015
|
+
if (limit !== undefined) {
|
|
1016
|
+
request['limit'] = limit;
|
|
1017
|
+
}
|
|
1018
|
+
const responseInner = this.publicGetOpenV1MarketTrades(this.extend(request, params));
|
|
1019
|
+
const data = this.safeValue(responseInner, 'data', {});
|
|
1020
|
+
return this.parseTrades(data, market, since, limit);
|
|
1021
|
+
}
|
|
1022
|
+
if (limit !== undefined) {
|
|
1023
|
+
request['limit'] = limit; // default = 500, maximum = 1000
|
|
1024
|
+
}
|
|
1025
|
+
const defaultMethod = 'binanceGetTrades';
|
|
1026
|
+
const method = this.safeString(this.options, 'fetchTradesMethod', defaultMethod);
|
|
1027
|
+
let response = undefined;
|
|
1028
|
+
if ((method === 'binanceGetAggTrades') && (since !== undefined)) {
|
|
1029
|
+
request['startTime'] = since;
|
|
1030
|
+
// https://github.com/ccxt/ccxt/issues/6400
|
|
1031
|
+
// https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list
|
|
1032
|
+
request['endTime'] = this.sum(since, 3600000);
|
|
1033
|
+
response = await this.binanceGetAggTrades(this.extend(request, params));
|
|
1034
|
+
}
|
|
1035
|
+
else {
|
|
1036
|
+
response = await this.binanceGetTrades(this.extend(request, params));
|
|
1037
|
+
}
|
|
1038
|
+
//
|
|
1039
|
+
// Caveats:
|
|
1040
|
+
// - default limit (500) applies only if no other parameters set, trades up
|
|
1041
|
+
// to the maximum limit may be returned to satisfy other parameters
|
|
1042
|
+
// - if both limit and time window is set and time window contains more
|
|
1043
|
+
// trades than the limit then the last trades from the window are returned
|
|
1044
|
+
// - 'tradeId' accepted and returned by this method is "aggregate" trade id
|
|
1045
|
+
// which is different from actual trade id
|
|
1046
|
+
// - setting both fromId and time window results in error
|
|
1047
|
+
//
|
|
1048
|
+
// aggregate trades
|
|
1049
|
+
//
|
|
1050
|
+
// [
|
|
1051
|
+
// {
|
|
1052
|
+
// "a": 26129, // Aggregate tradeId
|
|
1053
|
+
// "p": "0.01633102", // Price
|
|
1054
|
+
// "q": "4.70443515", // Quantity
|
|
1055
|
+
// "f": 27781, // First tradeId
|
|
1056
|
+
// "l": 27781, // Last tradeId
|
|
1057
|
+
// "T": 1498793709153, // Timestamp
|
|
1058
|
+
// "m": true, // Was the buyer the maker?
|
|
1059
|
+
// "M": true // Was the trade the best price match?
|
|
1060
|
+
// }
|
|
1061
|
+
// ]
|
|
1062
|
+
//
|
|
1063
|
+
// recent public trades and historical public trades
|
|
1064
|
+
//
|
|
1065
|
+
// [
|
|
1066
|
+
// {
|
|
1067
|
+
// "id": 28457,
|
|
1068
|
+
// "price": "4.00000100",
|
|
1069
|
+
// "qty": "12.00000000",
|
|
1070
|
+
// "time": 1499865549590,
|
|
1071
|
+
// "isBuyerMaker": true,
|
|
1072
|
+
// "isBestMatch": true
|
|
1073
|
+
// }
|
|
1074
|
+
// ]
|
|
1075
|
+
//
|
|
1076
|
+
return this.parseTrades(response, market, since, limit);
|
|
1077
|
+
}
|
|
1078
|
+
parseTicker(ticker, market = undefined) {
|
|
1079
|
+
//
|
|
1080
|
+
// {
|
|
1081
|
+
// "symbol": "ETHBTC",
|
|
1082
|
+
// "priceChange": "0.00068700",
|
|
1083
|
+
// "priceChangePercent": "2.075",
|
|
1084
|
+
// "weightedAvgPrice": "0.03342681",
|
|
1085
|
+
// "prevClosePrice": "0.03310300",
|
|
1086
|
+
// "lastPrice": "0.03378900",
|
|
1087
|
+
// "lastQty": "0.07700000",
|
|
1088
|
+
// "bidPrice": "0.03378900",
|
|
1089
|
+
// "bidQty": "7.16800000",
|
|
1090
|
+
// "askPrice": "0.03379000",
|
|
1091
|
+
// "askQty": "24.00000000",
|
|
1092
|
+
// "openPrice": "0.03310200",
|
|
1093
|
+
// "highPrice": "0.03388900",
|
|
1094
|
+
// "lowPrice": "0.03306900",
|
|
1095
|
+
// "volume": "205478.41000000",
|
|
1096
|
+
// "quoteVolume": "6868.48826294",
|
|
1097
|
+
// "openTime": 1601469986932,
|
|
1098
|
+
// "closeTime": 1601556386932,
|
|
1099
|
+
// "firstId": 196098772,
|
|
1100
|
+
// "lastId": 196186315,
|
|
1101
|
+
// "count": 87544
|
|
1102
|
+
// }
|
|
1103
|
+
//
|
|
1104
|
+
// coinm
|
|
1105
|
+
// {
|
|
1106
|
+
// "baseVolume": "214549.95171161",
|
|
1107
|
+
// "closeTime": "1621965286847",
|
|
1108
|
+
// "count": "1283779",
|
|
1109
|
+
// "firstId": "152560106",
|
|
1110
|
+
// "highPrice": "39938.3",
|
|
1111
|
+
// "lastId": "153843955",
|
|
1112
|
+
// "lastPrice": "37993.4",
|
|
1113
|
+
// "lastQty": "1",
|
|
1114
|
+
// "lowPrice": "36457.2",
|
|
1115
|
+
// "openPrice": "37783.4",
|
|
1116
|
+
// "openTime": "1621878840000",
|
|
1117
|
+
// "pair": "BTCUSD",
|
|
1118
|
+
// "priceChange": "210.0",
|
|
1119
|
+
// "priceChangePercent": "0.556",
|
|
1120
|
+
// "symbol": "BTCUSD_PERP",
|
|
1121
|
+
// "volume": "81990451",
|
|
1122
|
+
// "weightedAvgPrice": "38215.08713747"
|
|
1123
|
+
// }
|
|
1124
|
+
//
|
|
1125
|
+
const timestamp = this.safeInteger(ticker, 'closeTime');
|
|
1126
|
+
const marketId = this.safeString(ticker, 'symbol');
|
|
1127
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1128
|
+
const last = this.safeString(ticker, 'lastPrice');
|
|
1129
|
+
const isCoinm = ('baseVolume' in ticker);
|
|
1130
|
+
let baseVolume = undefined;
|
|
1131
|
+
let quoteVolume = undefined;
|
|
1132
|
+
if (isCoinm) {
|
|
1133
|
+
baseVolume = this.safeString(ticker, 'baseVolume');
|
|
1134
|
+
quoteVolume = this.safeString(ticker, 'volume');
|
|
1135
|
+
}
|
|
1136
|
+
else {
|
|
1137
|
+
baseVolume = this.safeString(ticker, 'volume');
|
|
1138
|
+
quoteVolume = this.safeString(ticker, 'quoteVolume');
|
|
1139
|
+
}
|
|
1140
|
+
return this.safeTicker({
|
|
1141
|
+
'symbol': symbol,
|
|
1142
|
+
'timestamp': timestamp,
|
|
1143
|
+
'datetime': this.iso8601(timestamp),
|
|
1144
|
+
'high': this.safeString(ticker, 'highPrice'),
|
|
1145
|
+
'low': this.safeString(ticker, 'lowPrice'),
|
|
1146
|
+
'bid': this.safeString(ticker, 'bidPrice'),
|
|
1147
|
+
'bidVolume': this.safeString(ticker, 'bidQty'),
|
|
1148
|
+
'ask': this.safeString(ticker, 'askPrice'),
|
|
1149
|
+
'askVolume': this.safeString(ticker, 'askQty'),
|
|
1150
|
+
'vwap': this.safeString(ticker, 'weightedAvgPrice'),
|
|
1151
|
+
'open': this.safeString(ticker, 'openPrice'),
|
|
1152
|
+
'close': last,
|
|
1153
|
+
'last': last,
|
|
1154
|
+
'previousClose': this.safeString(ticker, 'prevClosePrice'),
|
|
1155
|
+
'change': this.safeString(ticker, 'priceChange'),
|
|
1156
|
+
'percentage': this.safeString(ticker, 'priceChangePercent'),
|
|
1157
|
+
'average': undefined,
|
|
1158
|
+
'baseVolume': baseVolume,
|
|
1159
|
+
'quoteVolume': quoteVolume,
|
|
1160
|
+
'info': ticker,
|
|
1161
|
+
}, market);
|
|
1162
|
+
}
|
|
1163
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
1164
|
+
/**
|
|
1165
|
+
* @method
|
|
1166
|
+
* @name tokocrypto#fetchTickers
|
|
1167
|
+
* @see https://binance-docs.github.io/apidocs/spot/en/#24hr-ticker-price-change-statistics
|
|
1168
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1169
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1170
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1171
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1172
|
+
*/
|
|
1173
|
+
await this.loadMarkets();
|
|
1174
|
+
const response = await this.binanceGetTicker24hr(params);
|
|
1175
|
+
return this.parseTickers(response, symbols);
|
|
1176
|
+
}
|
|
1177
|
+
getMarketIdByType(market) {
|
|
1178
|
+
if (market['quote'] === 'USDT') {
|
|
1179
|
+
return market['baseId'] + market['quoteId'];
|
|
1180
|
+
}
|
|
1181
|
+
return market['id'];
|
|
1182
|
+
}
|
|
1183
|
+
async fetchTicker(symbol, params = {}) {
|
|
1184
|
+
/**
|
|
1185
|
+
* @method
|
|
1186
|
+
* @name tokocrypto#fetchTicker
|
|
1187
|
+
* @see https://binance-docs.github.io/apidocs/spot/en/#24hr-ticker-price-change-statistics
|
|
1188
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1189
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1190
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1191
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1192
|
+
*/
|
|
1193
|
+
await this.loadMarkets();
|
|
1194
|
+
const market = this.market(symbol);
|
|
1195
|
+
const request = {
|
|
1196
|
+
'symbol': market['baseId'] + market['quoteId'],
|
|
1197
|
+
};
|
|
1198
|
+
const response = await this.binanceGetTicker24hr(this.extend(request, params));
|
|
1199
|
+
if (Array.isArray(response)) {
|
|
1200
|
+
const firstTicker = this.safeValue(response, 0, {});
|
|
1201
|
+
return this.parseTicker(firstTicker, market);
|
|
1202
|
+
}
|
|
1203
|
+
return this.parseTicker(response, market);
|
|
1204
|
+
}
|
|
1205
|
+
async fetchBidsAsks(symbols = undefined, params = {}) {
|
|
1206
|
+
/**
|
|
1207
|
+
* @method
|
|
1208
|
+
* @name tokocrypto#fetchBidsAsks
|
|
1209
|
+
* @see https://binance-docs.github.io/apidocs/spot/en/#symbol-order-book-ticker
|
|
1210
|
+
* @description fetches the bid and ask price and volume for multiple markets
|
|
1211
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
|
1212
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1213
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1214
|
+
*/
|
|
1215
|
+
await this.loadMarkets();
|
|
1216
|
+
const response = await this.binanceGetTickerBookTicker(params);
|
|
1217
|
+
return this.parseTickers(response, symbols);
|
|
1218
|
+
}
|
|
1219
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1220
|
+
// when api method = publicGetKlines || fapiPublicGetKlines || dapiPublicGetKlines
|
|
1221
|
+
// [
|
|
1222
|
+
// 1591478520000, // open time
|
|
1223
|
+
// "0.02501300", // open
|
|
1224
|
+
// "0.02501800", // high
|
|
1225
|
+
// "0.02500000", // low
|
|
1226
|
+
// "0.02500000", // close
|
|
1227
|
+
// "22.19000000", // volume
|
|
1228
|
+
// 1591478579999, // close time
|
|
1229
|
+
// "0.55490906", // quote asset volume
|
|
1230
|
+
// 40, // number of trades
|
|
1231
|
+
// "10.92900000", // taker buy base asset volume
|
|
1232
|
+
// "0.27336462", // taker buy quote asset volume
|
|
1233
|
+
// "0" // ignore
|
|
1234
|
+
// ]
|
|
1235
|
+
//
|
|
1236
|
+
// when api method = fapiPublicGetMarkPriceKlines || fapiPublicGetIndexPriceKlines
|
|
1237
|
+
// [
|
|
1238
|
+
// [
|
|
1239
|
+
// 1591256460000, // Open time
|
|
1240
|
+
// "9653.29201333", // Open
|
|
1241
|
+
// "9654.56401333", // High
|
|
1242
|
+
// "9653.07367333", // Low
|
|
1243
|
+
// "9653.07367333", // Close (or latest price)
|
|
1244
|
+
// "0", // Ignore
|
|
1245
|
+
// 1591256519999, // Close time
|
|
1246
|
+
// "0", // Ignore
|
|
1247
|
+
// 60, // Number of bisic data
|
|
1248
|
+
// "0", // Ignore
|
|
1249
|
+
// "0", // Ignore
|
|
1250
|
+
// "0" // Ignore
|
|
1251
|
+
// ]
|
|
1252
|
+
// ]
|
|
1253
|
+
//
|
|
1254
|
+
return [
|
|
1255
|
+
this.safeInteger(ohlcv, 0),
|
|
1256
|
+
this.safeNumber(ohlcv, 1),
|
|
1257
|
+
this.safeNumber(ohlcv, 2),
|
|
1258
|
+
this.safeNumber(ohlcv, 3),
|
|
1259
|
+
this.safeNumber(ohlcv, 4),
|
|
1260
|
+
this.safeNumber(ohlcv, 5),
|
|
1261
|
+
];
|
|
1262
|
+
}
|
|
1263
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1264
|
+
/**
|
|
1265
|
+
* @method
|
|
1266
|
+
* @name tokocrypto#fetchOHLCV
|
|
1267
|
+
* @see https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
|
|
1268
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1269
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1270
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1271
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1272
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1273
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1274
|
+
* @param {string} [params.price] "mark" or "index" for mark price and index price candles
|
|
1275
|
+
* @param {int} [params.until] timestamp in ms of the latest candle to fetch
|
|
1276
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1277
|
+
*/
|
|
1278
|
+
await this.loadMarkets();
|
|
1279
|
+
const market = this.market(symbol);
|
|
1280
|
+
// binance docs say that the default limit 500, max 1500 for futures, max 1000 for spot markets
|
|
1281
|
+
// the reality is that the time range wider than 500 candles won't work right
|
|
1282
|
+
const defaultLimit = 500;
|
|
1283
|
+
const maxLimit = 1500;
|
|
1284
|
+
const price = this.safeString(params, 'price');
|
|
1285
|
+
const until = this.safeInteger(params, 'until');
|
|
1286
|
+
params = this.omit(params, ['price', 'until']);
|
|
1287
|
+
limit = (limit === undefined) ? defaultLimit : Math.min(limit, maxLimit);
|
|
1288
|
+
const request = {
|
|
1289
|
+
'interval': this.safeString(this.timeframes, timeframe, timeframe),
|
|
1290
|
+
'limit': limit,
|
|
1291
|
+
};
|
|
1292
|
+
if (price === 'index') {
|
|
1293
|
+
request['pair'] = market['id']; // Index price takes this argument instead of symbol
|
|
1294
|
+
}
|
|
1295
|
+
else {
|
|
1296
|
+
request['symbol'] = this.getMarketIdByType(market);
|
|
1297
|
+
}
|
|
1298
|
+
// const duration = this.parseTimeframe (timeframe);
|
|
1299
|
+
if (since !== undefined) {
|
|
1300
|
+
request['startTime'] = since;
|
|
1301
|
+
}
|
|
1302
|
+
if (until !== undefined) {
|
|
1303
|
+
request['endTime'] = until;
|
|
1304
|
+
}
|
|
1305
|
+
let response = undefined;
|
|
1306
|
+
if (market['quote'] === 'USDT') {
|
|
1307
|
+
response = await this.binanceGetKlines(this.extend(request, params));
|
|
1308
|
+
}
|
|
1309
|
+
else {
|
|
1310
|
+
response = await this.publicGetOpenV1MarketKlines(this.extend(request, params));
|
|
1311
|
+
}
|
|
1312
|
+
//
|
|
1313
|
+
// [
|
|
1314
|
+
// [1591478520000,"0.02501300","0.02501800","0.02500000","0.02500000","22.19000000",1591478579999,"0.55490906",40,"10.92900000","0.27336462","0"],
|
|
1315
|
+
// [1591478580000,"0.02499600","0.02500900","0.02499400","0.02500300","21.34700000",1591478639999,"0.53370468",24,"7.53800000","0.18850725","0"],
|
|
1316
|
+
// [1591478640000,"0.02500800","0.02501100","0.02500300","0.02500800","154.14200000",1591478699999,"3.85405839",97,"5.32300000","0.13312641","0"],
|
|
1317
|
+
// ]
|
|
1318
|
+
//
|
|
1319
|
+
const data = this.safeValue(response, 'data', response);
|
|
1320
|
+
return this.parseOHLCVs(data, market, timeframe, since, limit);
|
|
1321
|
+
}
|
|
1322
|
+
async fetchBalance(params = {}) {
|
|
1323
|
+
/**
|
|
1324
|
+
* @method
|
|
1325
|
+
* @name tokocrypto#fetchBalance
|
|
1326
|
+
* @see https://www.tokocrypto.com/apidocs/#account-information-signed
|
|
1327
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1328
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1329
|
+
* @param {string} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot'
|
|
1330
|
+
* @param {string} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
|
|
1331
|
+
* @param {string[]|undefined} [params.symbols] unified market symbols, only used in isolated margin mode
|
|
1332
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1333
|
+
*/
|
|
1334
|
+
await this.loadMarkets();
|
|
1335
|
+
const defaultType = this.safeString2(this.options, 'fetchBalance', 'defaultType', 'spot');
|
|
1336
|
+
const type = this.safeString(params, 'type', defaultType);
|
|
1337
|
+
const defaultMarginMode = this.safeString2(this.options, 'marginMode', 'defaultMarginMode');
|
|
1338
|
+
const marginMode = this.safeStringLower(params, 'marginMode', defaultMarginMode);
|
|
1339
|
+
const request = {};
|
|
1340
|
+
const response = await this.privateGetOpenV1AccountSpot(this.extend(request, params));
|
|
1341
|
+
//
|
|
1342
|
+
// spot
|
|
1343
|
+
//
|
|
1344
|
+
// {
|
|
1345
|
+
// "code":0,
|
|
1346
|
+
// "msg":"Success",
|
|
1347
|
+
// "data":{
|
|
1348
|
+
// "makerCommission":"0.00100000",
|
|
1349
|
+
// "takerCommission":"0.00100000",
|
|
1350
|
+
// "buyerCommission":"0.00000000",
|
|
1351
|
+
// "sellerCommission":"0.00000000",
|
|
1352
|
+
// "canTrade":1,
|
|
1353
|
+
// "canWithdraw":1,
|
|
1354
|
+
// "canDeposit":1,
|
|
1355
|
+
// "status":1,
|
|
1356
|
+
// "accountAssets":[
|
|
1357
|
+
// {"asset":"1INCH","free":"0","locked":"0"},
|
|
1358
|
+
// {"asset":"AAVE","free":"0","locked":"0"},
|
|
1359
|
+
// {"asset":"ACA","free":"0","locked":"0"}
|
|
1360
|
+
// ],
|
|
1361
|
+
// },
|
|
1362
|
+
// "timestamp":1659666786943
|
|
1363
|
+
// }
|
|
1364
|
+
//
|
|
1365
|
+
return this.parseBalance(response, type, marginMode);
|
|
1366
|
+
}
|
|
1367
|
+
parseBalance(response, type = undefined, marginMode = undefined) {
|
|
1368
|
+
const timestamp = this.safeInteger(response, 'updateTime');
|
|
1369
|
+
const result = {
|
|
1370
|
+
'info': response,
|
|
1371
|
+
'timestamp': timestamp,
|
|
1372
|
+
'datetime': this.iso8601(timestamp),
|
|
1373
|
+
};
|
|
1374
|
+
const data = this.safeValue(response, 'data', {});
|
|
1375
|
+
const balances = this.safeValue(data, 'accountAssets', []);
|
|
1376
|
+
for (let i = 0; i < balances.length; i++) {
|
|
1377
|
+
const balance = balances[i];
|
|
1378
|
+
const currencyId = this.safeString(balance, 'asset');
|
|
1379
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1380
|
+
const account = this.account();
|
|
1381
|
+
account['free'] = this.safeString(balance, 'free');
|
|
1382
|
+
account['used'] = this.safeString(balance, 'locked');
|
|
1383
|
+
result[code] = account;
|
|
1384
|
+
}
|
|
1385
|
+
return this.safeBalance(result);
|
|
1386
|
+
}
|
|
1387
|
+
parseOrderStatus(status) {
|
|
1388
|
+
const statuses = {
|
|
1389
|
+
'-2': 'open',
|
|
1390
|
+
'0': 'open',
|
|
1391
|
+
'1': 'open',
|
|
1392
|
+
'2': 'closed',
|
|
1393
|
+
'3': 'canceled',
|
|
1394
|
+
'4': 'canceling',
|
|
1395
|
+
'5': 'rejected',
|
|
1396
|
+
'6': 'expired',
|
|
1397
|
+
'NEW': 'open',
|
|
1398
|
+
'PARTIALLY_FILLED': 'open',
|
|
1399
|
+
'FILLED': 'closed',
|
|
1400
|
+
'CANCELED': 'canceled',
|
|
1401
|
+
'PENDING_CANCEL': 'canceling',
|
|
1402
|
+
'REJECTED': 'rejected',
|
|
1403
|
+
'EXPIRED': 'expired',
|
|
1404
|
+
};
|
|
1405
|
+
return this.safeString(statuses, status, status);
|
|
1406
|
+
}
|
|
1407
|
+
parseOrder(order, market = undefined) {
|
|
1408
|
+
//
|
|
1409
|
+
// spot
|
|
1410
|
+
//
|
|
1411
|
+
// {
|
|
1412
|
+
// "symbol": "LTCBTC",
|
|
1413
|
+
// "orderId": 1,
|
|
1414
|
+
// "clientOrderId": "myOrder1",
|
|
1415
|
+
// "price": "0.1",
|
|
1416
|
+
// "origQty": "1.0",
|
|
1417
|
+
// "executedQty": "0.0",
|
|
1418
|
+
// "cummulativeQuoteQty": "0.0",
|
|
1419
|
+
// "status": "NEW",
|
|
1420
|
+
// "timeInForce": "GTC",
|
|
1421
|
+
// "type": "LIMIT",
|
|
1422
|
+
// "side": "BUY",
|
|
1423
|
+
// "stopPrice": "0.0",
|
|
1424
|
+
// "icebergQty": "0.0",
|
|
1425
|
+
// "time": 1499827319559,
|
|
1426
|
+
// "updateTime": 1499827319559,
|
|
1427
|
+
// "isWorking": true
|
|
1428
|
+
// }
|
|
1429
|
+
// createOrder
|
|
1430
|
+
// {
|
|
1431
|
+
// "orderId": "145265071",
|
|
1432
|
+
// "bOrderListId": "0",
|
|
1433
|
+
// "clientId": "49c09c3c2cd54419a59c05441f517b3c",
|
|
1434
|
+
// "bOrderId": "35247529",
|
|
1435
|
+
// "symbol": "USDT_BIDR",
|
|
1436
|
+
// "symbolType": "1",
|
|
1437
|
+
// "side": "0",
|
|
1438
|
+
// "type": "1",
|
|
1439
|
+
// "price": "11915",
|
|
1440
|
+
// "origQty": "2",
|
|
1441
|
+
// "origQuoteQty": "23830.00",
|
|
1442
|
+
// "executedQty": "0.00000000",
|
|
1443
|
+
// "executedPrice": "0",
|
|
1444
|
+
// "executedQuoteQty": "0.00",
|
|
1445
|
+
// "timeInForce": "1",
|
|
1446
|
+
// "stopPrice": "0",
|
|
1447
|
+
// "icebergQty": "0",
|
|
1448
|
+
// "status": "0",
|
|
1449
|
+
// "createTime": "1662711074372"
|
|
1450
|
+
// }
|
|
1451
|
+
//
|
|
1452
|
+
// createOrder with { "newOrderRespType": "FULL" }
|
|
1453
|
+
//
|
|
1454
|
+
// {
|
|
1455
|
+
// "symbol": "BTCUSDT",
|
|
1456
|
+
// "orderId": 5403233939,
|
|
1457
|
+
// "orderListId": -1,
|
|
1458
|
+
// "clientOrderId": "x-R4BD3S825e669e75b6c14f69a2c43e",
|
|
1459
|
+
// "transactTime": 1617151923742,
|
|
1460
|
+
// "price": "0.00000000",
|
|
1461
|
+
// "origQty": "0.00050000",
|
|
1462
|
+
// "executedQty": "0.00050000",
|
|
1463
|
+
// "cummulativeQuoteQty": "29.47081500",
|
|
1464
|
+
// "status": "FILLED",
|
|
1465
|
+
// "timeInForce": "GTC",
|
|
1466
|
+
// "type": "MARKET",
|
|
1467
|
+
// "side": "BUY",
|
|
1468
|
+
// "fills": [
|
|
1469
|
+
// {
|
|
1470
|
+
// "price": "58941.63000000",
|
|
1471
|
+
// "qty": "0.00050000",
|
|
1472
|
+
// "commission": "0.00007050",
|
|
1473
|
+
// "commissionAsset": "BNB",
|
|
1474
|
+
// "tradeId": 737466631
|
|
1475
|
+
// }
|
|
1476
|
+
// ]
|
|
1477
|
+
// }
|
|
1478
|
+
//
|
|
1479
|
+
// delivery
|
|
1480
|
+
//
|
|
1481
|
+
// {
|
|
1482
|
+
// "orderId": "18742727411",
|
|
1483
|
+
// "symbol": "ETHUSD_PERP",
|
|
1484
|
+
// "pair": "ETHUSD",
|
|
1485
|
+
// "status": "FILLED",
|
|
1486
|
+
// "clientOrderId": "x-xcKtGhcu3e2d1503fdd543b3b02419",
|
|
1487
|
+
// "price": "0",
|
|
1488
|
+
// "avgPrice": "4522.14",
|
|
1489
|
+
// "origQty": "1",
|
|
1490
|
+
// "executedQty": "1",
|
|
1491
|
+
// "cumBase": "0.00221134",
|
|
1492
|
+
// "timeInForce": "GTC",
|
|
1493
|
+
// "type": "MARKET",
|
|
1494
|
+
// "reduceOnly": false,
|
|
1495
|
+
// "closePosition": false,
|
|
1496
|
+
// "side": "SELL",
|
|
1497
|
+
// "positionSide": "BOTH",
|
|
1498
|
+
// "stopPrice": "0",
|
|
1499
|
+
// "workingType": "CONTRACT_PRICE",
|
|
1500
|
+
// "priceProtect": false,
|
|
1501
|
+
// "origType": "MARKET",
|
|
1502
|
+
// "time": "1636061952660",
|
|
1503
|
+
// "updateTime": "1636061952660"
|
|
1504
|
+
// }
|
|
1505
|
+
//
|
|
1506
|
+
const status = this.parseOrderStatus(this.safeString(order, 'status'));
|
|
1507
|
+
const marketId = this.safeString(order, 'symbol');
|
|
1508
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1509
|
+
const filled = this.safeString(order, 'executedQty', '0');
|
|
1510
|
+
const timestamp = this.safeInteger(order, 'createTime');
|
|
1511
|
+
const average = this.safeString(order, 'avgPrice');
|
|
1512
|
+
const price = this.safeString2(order, 'price', 'executedPrice');
|
|
1513
|
+
const amount = this.safeString(order, 'origQty');
|
|
1514
|
+
// - Spot/Margin market: cummulativeQuoteQty
|
|
1515
|
+
// Note this is not the actual cost, since Binance futures uses leverage to calculate margins.
|
|
1516
|
+
const cost = this.safeStringN(order, ['cummulativeQuoteQty', 'cumQuote', 'executedQuoteQty', 'cumBase']);
|
|
1517
|
+
const id = this.safeString(order, 'orderId');
|
|
1518
|
+
const type = this.parseOrderType(this.safeStringLower(order, 'type'));
|
|
1519
|
+
let side = this.safeStringLower(order, 'side');
|
|
1520
|
+
if (side === '0') {
|
|
1521
|
+
side = 'buy';
|
|
1522
|
+
}
|
|
1523
|
+
else if (side === '1') {
|
|
1524
|
+
side = 'sell';
|
|
1525
|
+
}
|
|
1526
|
+
const fills = this.safeValue(order, 'fills', []);
|
|
1527
|
+
const clientOrderId = this.safeString2(order, 'clientOrderId', 'clientId');
|
|
1528
|
+
let timeInForce = this.safeString(order, 'timeInForce');
|
|
1529
|
+
if (timeInForce === 'GTX') {
|
|
1530
|
+
// GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
|
|
1531
|
+
timeInForce = 'PO';
|
|
1532
|
+
}
|
|
1533
|
+
const postOnly = (type === 'limit_maker') || (timeInForce === 'PO');
|
|
1534
|
+
const stopPriceString = this.safeString(order, 'stopPrice');
|
|
1535
|
+
const stopPrice = this.parseNumber(this.omitZero(stopPriceString));
|
|
1536
|
+
return this.safeOrder({
|
|
1537
|
+
'info': order,
|
|
1538
|
+
'id': id,
|
|
1539
|
+
'clientOrderId': clientOrderId,
|
|
1540
|
+
'timestamp': timestamp,
|
|
1541
|
+
'datetime': this.iso8601(timestamp),
|
|
1542
|
+
'lastTradeTimestamp': undefined,
|
|
1543
|
+
'symbol': symbol,
|
|
1544
|
+
'type': type,
|
|
1545
|
+
'timeInForce': timeInForce,
|
|
1546
|
+
'postOnly': postOnly,
|
|
1547
|
+
'reduceOnly': this.safeValue(order, 'reduceOnly'),
|
|
1548
|
+
'side': side,
|
|
1549
|
+
'price': price,
|
|
1550
|
+
'stopPrice': stopPrice,
|
|
1551
|
+
'triggerPrice': stopPrice,
|
|
1552
|
+
'amount': amount,
|
|
1553
|
+
'cost': cost,
|
|
1554
|
+
'average': average,
|
|
1555
|
+
'filled': filled,
|
|
1556
|
+
'remaining': undefined,
|
|
1557
|
+
'status': status,
|
|
1558
|
+
'fee': undefined,
|
|
1559
|
+
'trades': fills,
|
|
1560
|
+
}, market);
|
|
1561
|
+
}
|
|
1562
|
+
parseOrderType(status) {
|
|
1563
|
+
const statuses = {
|
|
1564
|
+
'2': 'market',
|
|
1565
|
+
'1': 'limit',
|
|
1566
|
+
'4': 'limit',
|
|
1567
|
+
'7': 'limit',
|
|
1568
|
+
};
|
|
1569
|
+
return this.safeString(statuses, status, status);
|
|
1570
|
+
}
|
|
1571
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1572
|
+
/**
|
|
1573
|
+
* @method
|
|
1574
|
+
* @name tokocrypto#createOrder
|
|
1575
|
+
* @description create a trade order
|
|
1576
|
+
* @see https://www.tokocrypto.com/apidocs/#new-order--signed
|
|
1577
|
+
* @see https://www.tokocrypto.com/apidocs/#account-trade-list-signed
|
|
1578
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1579
|
+
* @param {string} type 'market' or 'limit'
|
|
1580
|
+
* @param {string} side 'buy' or 'sell'
|
|
1581
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1582
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1583
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1584
|
+
* @param {float} [params.triggerPrice] the price at which a trigger order would be triggered
|
|
1585
|
+
* @param {float} [params.cost] for spot market buy orders, the quote quantity that can be used as an alternative for the amount
|
|
1586
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1587
|
+
*/
|
|
1588
|
+
await this.loadMarkets();
|
|
1589
|
+
const market = this.market(symbol);
|
|
1590
|
+
const clientOrderId = this.safeString2(params, 'clientOrderId', 'clientId');
|
|
1591
|
+
const postOnly = this.safeValue(params, 'postOnly', false);
|
|
1592
|
+
// only supported for spot/margin api
|
|
1593
|
+
if (postOnly) {
|
|
1594
|
+
type = 'LIMIT_MAKER';
|
|
1595
|
+
}
|
|
1596
|
+
params = this.omit(params, ['clientId', 'clientOrderId']);
|
|
1597
|
+
const initialUppercaseType = type.toUpperCase();
|
|
1598
|
+
let uppercaseType = initialUppercaseType;
|
|
1599
|
+
const stopPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
|
|
1600
|
+
if (stopPrice !== undefined) {
|
|
1601
|
+
params = this.omit(params, ['triggerPrice', 'stopPrice']);
|
|
1602
|
+
if (uppercaseType === 'MARKET') {
|
|
1603
|
+
uppercaseType = 'STOP_LOSS';
|
|
1604
|
+
}
|
|
1605
|
+
else if (uppercaseType === 'LIMIT') {
|
|
1606
|
+
uppercaseType = 'STOP_LOSS_LIMIT';
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
const validOrderTypes = this.safeValue(market['info'], 'orderTypes');
|
|
1610
|
+
if (!this.inArray(uppercaseType, validOrderTypes)) {
|
|
1611
|
+
if (initialUppercaseType !== uppercaseType) {
|
|
1612
|
+
throw new errors.InvalidOrder(this.id + ' stopPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders');
|
|
1613
|
+
}
|
|
1614
|
+
else {
|
|
1615
|
+
throw new errors.InvalidOrder(this.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market');
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
const reverseOrderTypeMapping = {
|
|
1619
|
+
'LIMIT': 1,
|
|
1620
|
+
'MARKET': 2,
|
|
1621
|
+
'STOP_LOSS': 3,
|
|
1622
|
+
'STOP_LOSS_LIMIT': 4,
|
|
1623
|
+
'TAKE_PROFIT': 5,
|
|
1624
|
+
'TAKE_PROFIT_LIMIT': 6,
|
|
1625
|
+
'LIMIT_MAKER': 7,
|
|
1626
|
+
};
|
|
1627
|
+
const request = {
|
|
1628
|
+
'symbol': market['baseId'] + '_' + market['quoteId'],
|
|
1629
|
+
'type': this.safeString(reverseOrderTypeMapping, uppercaseType),
|
|
1630
|
+
};
|
|
1631
|
+
if (side === 'buy') {
|
|
1632
|
+
request['side'] = 0;
|
|
1633
|
+
}
|
|
1634
|
+
else if (side === 'sell') {
|
|
1635
|
+
request['side'] = 1;
|
|
1636
|
+
}
|
|
1637
|
+
if (clientOrderId === undefined) {
|
|
1638
|
+
const broker = this.safeValue(this.options, 'broker');
|
|
1639
|
+
if (broker !== undefined) {
|
|
1640
|
+
const brokerId = this.safeString(broker, 'marketType');
|
|
1641
|
+
if (brokerId !== undefined) {
|
|
1642
|
+
request['clientId'] = brokerId + this.uuid22();
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
else {
|
|
1647
|
+
request['clientId'] = clientOrderId;
|
|
1648
|
+
}
|
|
1649
|
+
// additional required fields depending on the order type
|
|
1650
|
+
let priceIsRequired = false;
|
|
1651
|
+
let stopPriceIsRequired = false;
|
|
1652
|
+
let quantityIsRequired = false;
|
|
1653
|
+
//
|
|
1654
|
+
// spot/margin
|
|
1655
|
+
//
|
|
1656
|
+
// LIMIT timeInForce, quantity, price
|
|
1657
|
+
// MARKET quantity or quoteOrderQty
|
|
1658
|
+
// STOP_LOSS quantity, stopPrice
|
|
1659
|
+
// STOP_LOSS_LIMIT timeInForce, quantity, price, stopPrice
|
|
1660
|
+
// TAKE_PROFIT quantity, stopPrice
|
|
1661
|
+
// TAKE_PROFIT_LIMIT timeInForce, quantity, price, stopPrice
|
|
1662
|
+
// LIMIT_MAKER quantity, price
|
|
1663
|
+
//
|
|
1664
|
+
if (uppercaseType === 'MARKET') {
|
|
1665
|
+
if (side === 'buy') {
|
|
1666
|
+
const precision = market['precision']['price'];
|
|
1667
|
+
let quoteAmount = undefined;
|
|
1668
|
+
let createMarketBuyOrderRequiresPrice = true;
|
|
1669
|
+
[createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
|
|
1670
|
+
const cost = this.safeNumber2(params, 'cost', 'quoteOrderQty');
|
|
1671
|
+
params = this.omit(params, ['cost', 'quoteOrderQty']);
|
|
1672
|
+
if (cost !== undefined) {
|
|
1673
|
+
quoteAmount = cost;
|
|
1674
|
+
}
|
|
1675
|
+
else if (createMarketBuyOrderRequiresPrice) {
|
|
1676
|
+
if (price === undefined) {
|
|
1677
|
+
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');
|
|
1678
|
+
}
|
|
1679
|
+
else {
|
|
1680
|
+
const amountString = this.numberToString(amount);
|
|
1681
|
+
const priceString = this.numberToString(price);
|
|
1682
|
+
quoteAmount = Precise["default"].stringMul(amountString, priceString);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
else {
|
|
1686
|
+
quoteAmount = amount;
|
|
1687
|
+
}
|
|
1688
|
+
request['quoteOrderQty'] = this.decimalToPrecision(quoteAmount, number.TRUNCATE, precision, this.precisionMode);
|
|
1689
|
+
}
|
|
1690
|
+
else {
|
|
1691
|
+
quantityIsRequired = true;
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
else if (uppercaseType === 'LIMIT') {
|
|
1695
|
+
priceIsRequired = true;
|
|
1696
|
+
quantityIsRequired = true;
|
|
1697
|
+
}
|
|
1698
|
+
else if ((uppercaseType === 'STOP_LOSS') || (uppercaseType === 'TAKE_PROFIT')) {
|
|
1699
|
+
stopPriceIsRequired = true;
|
|
1700
|
+
quantityIsRequired = true;
|
|
1701
|
+
if (market['linear'] || market['inverse']) {
|
|
1702
|
+
priceIsRequired = true;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
else if ((uppercaseType === 'STOP_LOSS_LIMIT') || (uppercaseType === 'TAKE_PROFIT_LIMIT')) {
|
|
1706
|
+
quantityIsRequired = true;
|
|
1707
|
+
stopPriceIsRequired = true;
|
|
1708
|
+
priceIsRequired = true;
|
|
1709
|
+
}
|
|
1710
|
+
else if (uppercaseType === 'LIMIT_MAKER') {
|
|
1711
|
+
priceIsRequired = true;
|
|
1712
|
+
quantityIsRequired = true;
|
|
1713
|
+
}
|
|
1714
|
+
if (quantityIsRequired) {
|
|
1715
|
+
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
1716
|
+
}
|
|
1717
|
+
if (priceIsRequired) {
|
|
1718
|
+
if (price === undefined) {
|
|
1719
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a price argument for a ' + type + ' order');
|
|
1720
|
+
}
|
|
1721
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
1722
|
+
}
|
|
1723
|
+
if (stopPriceIsRequired) {
|
|
1724
|
+
if (stopPrice === undefined) {
|
|
1725
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a stopPrice extra param for a ' + type + ' order');
|
|
1726
|
+
}
|
|
1727
|
+
else {
|
|
1728
|
+
request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
const response = await this.privatePostOpenV1Orders(this.extend(request, params));
|
|
1732
|
+
//
|
|
1733
|
+
// {
|
|
1734
|
+
// "code": 0,
|
|
1735
|
+
// "msg": "Success",
|
|
1736
|
+
// "data": {
|
|
1737
|
+
// "orderId": 145264846,
|
|
1738
|
+
// "bOrderListId": 0,
|
|
1739
|
+
// "clientId": "4ee2ab5e55e74b358eaf98079c670d17",
|
|
1740
|
+
// "bOrderId": 35247499,
|
|
1741
|
+
// "symbol": "USDT_BIDR",
|
|
1742
|
+
// "symbolType": 1,
|
|
1743
|
+
// "side": 0,
|
|
1744
|
+
// "type": 1,
|
|
1745
|
+
// "price": "11915",
|
|
1746
|
+
// "origQty": "2",
|
|
1747
|
+
// "origQuoteQty": "23830.00",
|
|
1748
|
+
// "executedQty": "0.00000000",
|
|
1749
|
+
// "executedPrice": "0",
|
|
1750
|
+
// "executedQuoteQty": "0.00",
|
|
1751
|
+
// "timeInForce": 1,
|
|
1752
|
+
// "stopPrice": 0,
|
|
1753
|
+
// "icebergQty": "0",
|
|
1754
|
+
// "status": 0,
|
|
1755
|
+
// "createTime": 1662710994848
|
|
1756
|
+
// },
|
|
1757
|
+
// "timestamp": 1662710994975
|
|
1758
|
+
// }
|
|
1759
|
+
//
|
|
1760
|
+
const rawOrder = this.safeValue(response, 'data', {});
|
|
1761
|
+
return this.parseOrder(rawOrder, market);
|
|
1762
|
+
}
|
|
1763
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1764
|
+
/**
|
|
1765
|
+
* @method
|
|
1766
|
+
* @name tokocrypto#fetchOrder
|
|
1767
|
+
* @see https://www.tokocrypto.com/apidocs/#all-orders-signed
|
|
1768
|
+
* @description fetches information on an order made by the user
|
|
1769
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
1770
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1771
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1772
|
+
*/
|
|
1773
|
+
const request = {
|
|
1774
|
+
'orderId': id,
|
|
1775
|
+
};
|
|
1776
|
+
const response = await this.privateGetOpenV1Orders(this.extend(request, params));
|
|
1777
|
+
//
|
|
1778
|
+
// {
|
|
1779
|
+
// "code": 0,
|
|
1780
|
+
// "msg": "Success",
|
|
1781
|
+
// "data": {
|
|
1782
|
+
// "list": [{
|
|
1783
|
+
// "orderId": "145221985",
|
|
1784
|
+
// "clientId": "201515331fd64d03aedbe687a38152e3",
|
|
1785
|
+
// "bOrderId": "35239632",
|
|
1786
|
+
// "bOrderListId": "0",
|
|
1787
|
+
// "symbol": "USDT_BIDR",
|
|
1788
|
+
// "symbolType": 1,
|
|
1789
|
+
// "side": 0,
|
|
1790
|
+
// "type": 1,
|
|
1791
|
+
// "price": "11907",
|
|
1792
|
+
// "origQty": "2",
|
|
1793
|
+
// "origQuoteQty": "23814",
|
|
1794
|
+
// "executedQty": "0",
|
|
1795
|
+
// "executedPrice": "0",
|
|
1796
|
+
// "executedQuoteQty": "0",
|
|
1797
|
+
// "timeInForce": 1,
|
|
1798
|
+
// "stopPrice": "0",
|
|
1799
|
+
// "icebergQty": "0",
|
|
1800
|
+
// "status": 0,
|
|
1801
|
+
// "createTime": 1662699360000
|
|
1802
|
+
// }]
|
|
1803
|
+
// },
|
|
1804
|
+
// "timestamp": 1662710056523
|
|
1805
|
+
// }
|
|
1806
|
+
//
|
|
1807
|
+
const data = this.safeValue(response, 'data', {});
|
|
1808
|
+
const list = this.safeValue(data, 'list', []);
|
|
1809
|
+
const rawOrder = this.safeValue(list, 0, {});
|
|
1810
|
+
return this.parseOrder(rawOrder);
|
|
1811
|
+
}
|
|
1812
|
+
async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1813
|
+
/**
|
|
1814
|
+
* @method
|
|
1815
|
+
* @name tokocrypto#fetchOrders
|
|
1816
|
+
* @see https://www.tokocrypto.com/apidocs/#all-orders-signed
|
|
1817
|
+
* @description fetches information on multiple orders made by the user
|
|
1818
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1819
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1820
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1821
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1822
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1823
|
+
*/
|
|
1824
|
+
if (symbol === undefined) {
|
|
1825
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchOrders() requires a symbol argument');
|
|
1826
|
+
}
|
|
1827
|
+
await this.loadMarkets();
|
|
1828
|
+
const market = this.market(symbol);
|
|
1829
|
+
const request = {
|
|
1830
|
+
'symbol': market['id'],
|
|
1831
|
+
// 'type': -1, // -1 = all, 1 = open, 2 = closed
|
|
1832
|
+
// 'side': 1, // or 2
|
|
1833
|
+
// 'startTime': since,
|
|
1834
|
+
// 'endTime': this.milliseconds (),
|
|
1835
|
+
// 'fromId': 'starting order ID', // if defined, the "direct" field becomes mandatory
|
|
1836
|
+
// 'direct': 'prev', // prev, next
|
|
1837
|
+
// 'limit': 500, // default 500, max 1000
|
|
1838
|
+
};
|
|
1839
|
+
if (since !== undefined) {
|
|
1840
|
+
request['startTime'] = since;
|
|
1841
|
+
}
|
|
1842
|
+
if (limit !== undefined) {
|
|
1843
|
+
request['limit'] = limit;
|
|
1844
|
+
}
|
|
1845
|
+
const response = await this.privateGetOpenV1Orders(this.extend(request, params));
|
|
1846
|
+
//
|
|
1847
|
+
// {
|
|
1848
|
+
// "code": 0,
|
|
1849
|
+
// "msg": "success",
|
|
1850
|
+
// "data": {
|
|
1851
|
+
// "list": [
|
|
1852
|
+
// {
|
|
1853
|
+
// "orderId": "4", // order id
|
|
1854
|
+
// "bOrderId": "100001", // binance order id
|
|
1855
|
+
// "bOrderListId": -1, // Unless part of an OCO, the value will always be -1.
|
|
1856
|
+
// "clientId": "1aa4f99ad7bc4fab903395afd25d0597", // client custom order id
|
|
1857
|
+
// "symbol": "ADA_USDT",
|
|
1858
|
+
// "symbolType": 1,
|
|
1859
|
+
// "side": 1,
|
|
1860
|
+
// "type": 1,
|
|
1861
|
+
// "price": "0.1",
|
|
1862
|
+
// "origQty": "10",
|
|
1863
|
+
// "origQuoteQty": "1",
|
|
1864
|
+
// "executedQty": "0",
|
|
1865
|
+
// "executedPrice": "0",
|
|
1866
|
+
// "executedQuoteQty": "0",
|
|
1867
|
+
// "timeInForce": 1,
|
|
1868
|
+
// "stopPrice": "0.0000000000000000",
|
|
1869
|
+
// "icebergQty": "0.0000000000000000",
|
|
1870
|
+
// "status": 0,
|
|
1871
|
+
// "isWorking": 0,
|
|
1872
|
+
// "createTime": 1572692016811
|
|
1873
|
+
// }
|
|
1874
|
+
// ]
|
|
1875
|
+
// },
|
|
1876
|
+
// "timestamp": 1572860756458
|
|
1877
|
+
// }
|
|
1878
|
+
//
|
|
1879
|
+
const data = this.safeValue(response, 'data', {});
|
|
1880
|
+
const orders = this.safeValue(data, 'list', []);
|
|
1881
|
+
return this.parseOrders(orders, market, since, limit);
|
|
1882
|
+
}
|
|
1883
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1884
|
+
/**
|
|
1885
|
+
* @method
|
|
1886
|
+
* @name tokocrypto#fetchOpenOrders
|
|
1887
|
+
* @see https://www.tokocrypto.com/apidocs/#all-orders-signed
|
|
1888
|
+
* @description fetch all unfilled currently open orders
|
|
1889
|
+
* @param {string} symbol unified market symbol
|
|
1890
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
1891
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
1892
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1893
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1894
|
+
*/
|
|
1895
|
+
const request = { 'type': 1 }; // -1 = all, 1 = open, 2 = closed
|
|
1896
|
+
return await this.fetchOrders(symbol, since, limit, this.extend(request, params));
|
|
1897
|
+
}
|
|
1898
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1899
|
+
/**
|
|
1900
|
+
* @method
|
|
1901
|
+
* @name tokocrypto#fetchClosedOrders
|
|
1902
|
+
* @see https://www.tokocrypto.com/apidocs/#all-orders-signed
|
|
1903
|
+
* @description fetches information on multiple closed orders made by the user
|
|
1904
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1905
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1906
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1907
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1908
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1909
|
+
*/
|
|
1910
|
+
const request = { 'type': 2 }; // -1 = all, 1 = open, 2 = closed
|
|
1911
|
+
return await this.fetchOrders(symbol, since, limit, this.extend(request, params));
|
|
1912
|
+
}
|
|
1913
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1914
|
+
/**
|
|
1915
|
+
* @method
|
|
1916
|
+
* @name tokocrypto#cancelOrder
|
|
1917
|
+
* @see https://www.tokocrypto.com/apidocs/#cancel-order-signed
|
|
1918
|
+
* @description cancels an open order
|
|
1919
|
+
* @param {string} id order id
|
|
1920
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
1921
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1922
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1923
|
+
*/
|
|
1924
|
+
const request = {
|
|
1925
|
+
'orderId': id,
|
|
1926
|
+
};
|
|
1927
|
+
const response = await this.privatePostOpenV1OrdersCancel(this.extend(request, params));
|
|
1928
|
+
//
|
|
1929
|
+
// {
|
|
1930
|
+
// "code": 0,
|
|
1931
|
+
// "msg": "Success",
|
|
1932
|
+
// "data": {
|
|
1933
|
+
// "orderId": "145221985",
|
|
1934
|
+
// "bOrderListId": "0",
|
|
1935
|
+
// "clientId": "201515331fd64d03aedbe687a38152e3",
|
|
1936
|
+
// "bOrderId": "35239632",
|
|
1937
|
+
// "symbol": "USDT_BIDR",
|
|
1938
|
+
// "symbolType": 1,
|
|
1939
|
+
// "type": 1,
|
|
1940
|
+
// "side": 0,
|
|
1941
|
+
// "price": "11907.0000000000000000",
|
|
1942
|
+
// "origQty": "2.0000000000000000",
|
|
1943
|
+
// "origQuoteQty": "23814.0000000000000000",
|
|
1944
|
+
// "executedPrice": "0.0000000000000000",
|
|
1945
|
+
// "executedQty": "0.00000000",
|
|
1946
|
+
// "executedQuoteQty": "0.00",
|
|
1947
|
+
// "timeInForce": 1,
|
|
1948
|
+
// "stopPrice": "0.0000000000000000",
|
|
1949
|
+
// "icebergQty": "0.0000000000000000",
|
|
1950
|
+
// "status": 3
|
|
1951
|
+
// },
|
|
1952
|
+
// "timestamp": 1662710683634
|
|
1953
|
+
// }
|
|
1954
|
+
//
|
|
1955
|
+
const rawOrder = this.safeValue(response, 'data', {});
|
|
1956
|
+
return this.parseOrder(rawOrder);
|
|
1957
|
+
}
|
|
1958
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1959
|
+
/**
|
|
1960
|
+
* @method
|
|
1961
|
+
* @name tokocrypto#fetchMyTrades
|
|
1962
|
+
* @see https://www.tokocrypto.com/apidocs/#account-trade-list-signed
|
|
1963
|
+
* @description fetch all trades made by the user
|
|
1964
|
+
* @param {string} symbol unified market symbol
|
|
1965
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1966
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
1967
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1968
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1969
|
+
*/
|
|
1970
|
+
if (symbol === undefined) {
|
|
1971
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
|
|
1972
|
+
}
|
|
1973
|
+
await this.loadMarkets();
|
|
1974
|
+
const market = this.market(symbol);
|
|
1975
|
+
const request = {
|
|
1976
|
+
'symbol': market['id'],
|
|
1977
|
+
};
|
|
1978
|
+
const endTime = this.safeInteger2(params, 'until', 'endTime');
|
|
1979
|
+
if (since !== undefined) {
|
|
1980
|
+
request['startTime'] = since;
|
|
1981
|
+
}
|
|
1982
|
+
if (endTime !== undefined) {
|
|
1983
|
+
request['endTime'] = endTime;
|
|
1984
|
+
params = this.omit(params, ['endTime', 'until']);
|
|
1985
|
+
}
|
|
1986
|
+
if (limit !== undefined) {
|
|
1987
|
+
request['limit'] = limit;
|
|
1988
|
+
}
|
|
1989
|
+
const response = await this.privateGetOpenV1OrdersTrades(this.extend(request, params));
|
|
1990
|
+
//
|
|
1991
|
+
// {
|
|
1992
|
+
// "code": 0,
|
|
1993
|
+
// "msg": "success",
|
|
1994
|
+
// "data": {
|
|
1995
|
+
// "list": [
|
|
1996
|
+
// {
|
|
1997
|
+
// "tradeId": "3",
|
|
1998
|
+
// "orderId": "2",
|
|
1999
|
+
// "symbol": "ADA_USDT",
|
|
2000
|
+
// "price": "0.04398",
|
|
2001
|
+
// "qty": "250",
|
|
2002
|
+
// "quoteQty": "10.995",
|
|
2003
|
+
// "commission": "0.25",
|
|
2004
|
+
// "commissionAsset": "ADA",
|
|
2005
|
+
// "isBuyer": 1,
|
|
2006
|
+
// "isMaker": 0,
|
|
2007
|
+
// "isBestMatch": 1,
|
|
2008
|
+
// "time": "1572920872276"
|
|
2009
|
+
// }
|
|
2010
|
+
// ]
|
|
2011
|
+
// },
|
|
2012
|
+
// "timestamp": 1573723498893
|
|
2013
|
+
// }
|
|
2014
|
+
//
|
|
2015
|
+
const data = this.safeValue(response, 'data', {});
|
|
2016
|
+
const trades = this.safeValue(data, 'list', []);
|
|
2017
|
+
return this.parseTrades(trades, market, since, limit);
|
|
2018
|
+
}
|
|
2019
|
+
async fetchDepositAddress(code, params = {}) {
|
|
2020
|
+
/**
|
|
2021
|
+
* @method
|
|
2022
|
+
* @name tokocrypto#fetchDepositAddress
|
|
2023
|
+
* @see https://www.tokocrypto.com/apidocs/#deposit-address-signed
|
|
2024
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
2025
|
+
* @param {string} code unified currency code
|
|
2026
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2027
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
2028
|
+
*/
|
|
2029
|
+
await this.loadMarkets();
|
|
2030
|
+
const currency = this.currency(code);
|
|
2031
|
+
const request = {
|
|
2032
|
+
'asset': currency['id'],
|
|
2033
|
+
// 'network': 'ETH', // 'BSC', 'XMR', you can get network and isDefault in networkList in the response of sapiGetCapitalConfigDetail
|
|
2034
|
+
};
|
|
2035
|
+
const networks = this.safeValue(this.options, 'networks', {});
|
|
2036
|
+
let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
|
|
2037
|
+
network = this.safeString(networks, network, network); // handle ERC20>ETH alias
|
|
2038
|
+
if (network !== undefined) {
|
|
2039
|
+
request['network'] = network;
|
|
2040
|
+
params = this.omit(params, 'network');
|
|
2041
|
+
}
|
|
2042
|
+
// has support for the 'network' parameter
|
|
2043
|
+
// https://binance-docs.github.io/apidocs/spot/en/#deposit-address-supporting-network-user_data
|
|
2044
|
+
const response = await this.privateGetOpenV1DepositsAddress(this.extend(request, params));
|
|
2045
|
+
//
|
|
2046
|
+
// {
|
|
2047
|
+
// "code":0,
|
|
2048
|
+
// "msg":"Success",
|
|
2049
|
+
// "data":{
|
|
2050
|
+
// "uid":"182395",
|
|
2051
|
+
// "asset":"USDT",
|
|
2052
|
+
// "network":"ETH",
|
|
2053
|
+
// "address":"0x101a925704f6ff13295ab8dd7a60988d116aaedf",
|
|
2054
|
+
// "addressTag":"",
|
|
2055
|
+
// "status":1
|
|
2056
|
+
// },
|
|
2057
|
+
// "timestamp":1660685915746
|
|
2058
|
+
// }
|
|
2059
|
+
//
|
|
2060
|
+
const data = this.safeValue(response, 'data', {});
|
|
2061
|
+
const address = this.safeString(data, 'address');
|
|
2062
|
+
let tag = this.safeString(data, 'addressTag', '');
|
|
2063
|
+
if (tag.length === 0) {
|
|
2064
|
+
tag = undefined;
|
|
2065
|
+
}
|
|
2066
|
+
this.checkAddress(address);
|
|
2067
|
+
return {
|
|
2068
|
+
'currency': code,
|
|
2069
|
+
'address': address,
|
|
2070
|
+
'tag': tag,
|
|
2071
|
+
'network': this.safeString(data, 'network'),
|
|
2072
|
+
'info': response,
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
2075
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2076
|
+
/**
|
|
2077
|
+
* @method
|
|
2078
|
+
* @name tokocrypto#fetchDeposits
|
|
2079
|
+
* @see https://www.tokocrypto.com/apidocs/#deposit-history-signed
|
|
2080
|
+
* @description fetch all deposits made to an account
|
|
2081
|
+
* @param {string} code unified currency code
|
|
2082
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
2083
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
2084
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2085
|
+
* @param {int} [params.until] the latest time in ms to fetch deposits for
|
|
2086
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2087
|
+
*/
|
|
2088
|
+
await this.loadMarkets();
|
|
2089
|
+
let currency = undefined;
|
|
2090
|
+
const request = {};
|
|
2091
|
+
const until = this.safeInteger(params, 'until');
|
|
2092
|
+
if (code !== undefined) {
|
|
2093
|
+
currency = this.currency(code);
|
|
2094
|
+
request['coin'] = currency['id'];
|
|
2095
|
+
}
|
|
2096
|
+
if (since !== undefined) {
|
|
2097
|
+
request['startTime'] = since;
|
|
2098
|
+
// max 3 months range https://github.com/ccxt/ccxt/issues/6495
|
|
2099
|
+
let endTime = this.sum(since, 7776000000);
|
|
2100
|
+
if (until !== undefined) {
|
|
2101
|
+
endTime = Math.min(endTime, until);
|
|
2102
|
+
}
|
|
2103
|
+
request['endTime'] = endTime;
|
|
2104
|
+
}
|
|
2105
|
+
if (limit !== undefined) {
|
|
2106
|
+
request['limit'] = limit;
|
|
2107
|
+
}
|
|
2108
|
+
const response = await this.privateGetOpenV1Deposits(this.extend(request, params));
|
|
2109
|
+
//
|
|
2110
|
+
// {
|
|
2111
|
+
// "code":0,
|
|
2112
|
+
// "msg":"Success",
|
|
2113
|
+
// "data":{
|
|
2114
|
+
// "list":[
|
|
2115
|
+
// {
|
|
2116
|
+
// "id":5167969,
|
|
2117
|
+
// "asset":"BIDR",
|
|
2118
|
+
// "network":"BSC",
|
|
2119
|
+
// "address":"0x101a925704f6ff13295ab8dd7a60988d116aaedf",
|
|
2120
|
+
// "addressTag":"",
|
|
2121
|
+
// "txId":"113409337867",
|
|
2122
|
+
// "amount":"15000",
|
|
2123
|
+
// "transferType":1,
|
|
2124
|
+
// "status":1,
|
|
2125
|
+
// "insertTime":"1659429390000"
|
|
2126
|
+
// },
|
|
2127
|
+
// ]
|
|
2128
|
+
// },
|
|
2129
|
+
// "timestamp":1659758865998
|
|
2130
|
+
// }
|
|
2131
|
+
//
|
|
2132
|
+
const data = this.safeValue(response, 'data', {});
|
|
2133
|
+
const deposits = this.safeValue(data, 'list', []);
|
|
2134
|
+
return this.parseTransactions(deposits, currency, since, limit);
|
|
2135
|
+
}
|
|
2136
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2137
|
+
/**
|
|
2138
|
+
* @method
|
|
2139
|
+
* @name tokocrypto#fetchWithdrawals
|
|
2140
|
+
* @see https://www.tokocrypto.com/apidocs/#withdraw-signed
|
|
2141
|
+
* @description fetch all withdrawals made from an account
|
|
2142
|
+
* @param {string} code unified currency code
|
|
2143
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
2144
|
+
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
2145
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2146
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2147
|
+
*/
|
|
2148
|
+
await this.loadMarkets();
|
|
2149
|
+
const request = {};
|
|
2150
|
+
let currency = undefined;
|
|
2151
|
+
if (code !== undefined) {
|
|
2152
|
+
currency = this.currency(code);
|
|
2153
|
+
request['coin'] = currency['id'];
|
|
2154
|
+
}
|
|
2155
|
+
if (since !== undefined) {
|
|
2156
|
+
request['startTime'] = since;
|
|
2157
|
+
// max 3 months range https://github.com/ccxt/ccxt/issues/6495
|
|
2158
|
+
request['endTime'] = this.sum(since, 7776000000);
|
|
2159
|
+
}
|
|
2160
|
+
if (limit !== undefined) {
|
|
2161
|
+
request['limit'] = limit;
|
|
2162
|
+
}
|
|
2163
|
+
const response = await this.privateGetOpenV1Withdraws(this.extend(request, params));
|
|
2164
|
+
//
|
|
2165
|
+
// {
|
|
2166
|
+
// "code":0,
|
|
2167
|
+
// "msg":"Success",
|
|
2168
|
+
// "data":{
|
|
2169
|
+
// "list":[
|
|
2170
|
+
// {
|
|
2171
|
+
// "id":4245859,
|
|
2172
|
+
// "clientId":"198",
|
|
2173
|
+
// "asset":"BIDR",
|
|
2174
|
+
// "network":"BSC",
|
|
2175
|
+
// "address":"0xff1c75149cc492e7d5566145b859fcafc900b6e9",
|
|
2176
|
+
// "addressTag":"",
|
|
2177
|
+
// "amount":"10000",
|
|
2178
|
+
// "fee":"0",
|
|
2179
|
+
// "txId":"113501794501",
|
|
2180
|
+
// "transferType":1,
|
|
2181
|
+
// "status":10,
|
|
2182
|
+
// "createTime":1659521314413
|
|
2183
|
+
// }
|
|
2184
|
+
// ]
|
|
2185
|
+
// },
|
|
2186
|
+
// "timestamp":1659759062187
|
|
2187
|
+
// }
|
|
2188
|
+
//
|
|
2189
|
+
const data = this.safeValue(response, 'data', {});
|
|
2190
|
+
const withdrawals = this.safeValue(data, 'list', []);
|
|
2191
|
+
return this.parseTransactions(withdrawals, currency, since, limit);
|
|
2192
|
+
}
|
|
2193
|
+
parseTransactionStatusByType(status, type = undefined) {
|
|
2194
|
+
const statusesByType = {
|
|
2195
|
+
'deposit': {
|
|
2196
|
+
'0': 'pending',
|
|
2197
|
+
'1': 'ok',
|
|
2198
|
+
},
|
|
2199
|
+
'withdrawal': {
|
|
2200
|
+
'0': 'pending',
|
|
2201
|
+
'1': 'canceled',
|
|
2202
|
+
'2': 'pending',
|
|
2203
|
+
'3': 'failed',
|
|
2204
|
+
'4': 'pending',
|
|
2205
|
+
'5': 'failed',
|
|
2206
|
+
'10': 'ok', // Completed
|
|
2207
|
+
},
|
|
2208
|
+
};
|
|
2209
|
+
const statuses = this.safeValue(statusesByType, type, {});
|
|
2210
|
+
return this.safeString(statuses, status, status);
|
|
2211
|
+
}
|
|
2212
|
+
parseTransaction(transaction, currency = undefined) {
|
|
2213
|
+
//
|
|
2214
|
+
// fetchDeposits
|
|
2215
|
+
//
|
|
2216
|
+
// {
|
|
2217
|
+
// "id": 5167969,
|
|
2218
|
+
// "asset": "BIDR",
|
|
2219
|
+
// "network": "BSC",
|
|
2220
|
+
// "address": "0x101a925704f6ff13295ab8dd7a60988d116aaedf",
|
|
2221
|
+
// "addressTag": "",
|
|
2222
|
+
// "txId": "113409337867",
|
|
2223
|
+
// "amount": "15000",
|
|
2224
|
+
// "transferType": 1,
|
|
2225
|
+
// "status": 1,
|
|
2226
|
+
// "insertTime": "1659429390000"
|
|
2227
|
+
// }
|
|
2228
|
+
//
|
|
2229
|
+
// fetchWithdrawals
|
|
2230
|
+
//
|
|
2231
|
+
// {
|
|
2232
|
+
// "id": 4245859,
|
|
2233
|
+
// "clientId": "198",
|
|
2234
|
+
// "asset": "BIDR",
|
|
2235
|
+
// "network": "BSC",
|
|
2236
|
+
// "address": "0xff1c75149cc492e7d5566145b859fcafc900b6e9",
|
|
2237
|
+
// "addressTag": "",
|
|
2238
|
+
// "amount": "10000",
|
|
2239
|
+
// "fee": "0",
|
|
2240
|
+
// "txId": "113501794501",
|
|
2241
|
+
// "transferType": 1,
|
|
2242
|
+
// "status": 10,
|
|
2243
|
+
// "createTime": 1659521314413
|
|
2244
|
+
// }
|
|
2245
|
+
//
|
|
2246
|
+
// withdraw
|
|
2247
|
+
//
|
|
2248
|
+
// {
|
|
2249
|
+
// "code": 0,
|
|
2250
|
+
// "msg": "成功",
|
|
2251
|
+
// "data": {
|
|
2252
|
+
// "withdrawId":"12"
|
|
2253
|
+
// },
|
|
2254
|
+
// "timestamp": 1571745049095
|
|
2255
|
+
// }
|
|
2256
|
+
//
|
|
2257
|
+
const address = this.safeString(transaction, 'address');
|
|
2258
|
+
let tag = this.safeString(transaction, 'addressTag'); // set but unused
|
|
2259
|
+
if (tag !== undefined) {
|
|
2260
|
+
if (tag.length < 1) {
|
|
2261
|
+
tag = undefined;
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
let txid = this.safeString(transaction, 'txId');
|
|
2265
|
+
if ((txid !== undefined) && (txid.indexOf('Internal transfer ') >= 0)) {
|
|
2266
|
+
txid = txid.slice(18);
|
|
2267
|
+
}
|
|
2268
|
+
const currencyId = this.safeString2(transaction, 'coin', 'fiatCurrency');
|
|
2269
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
2270
|
+
let timestamp = undefined;
|
|
2271
|
+
const insertTime = this.safeInteger(transaction, 'insertTime');
|
|
2272
|
+
const createTime = this.safeInteger2(transaction, 'createTime', 'timestamp');
|
|
2273
|
+
let type = this.safeString(transaction, 'type');
|
|
2274
|
+
if (type === undefined) {
|
|
2275
|
+
if ((insertTime !== undefined) && (createTime === undefined)) {
|
|
2276
|
+
type = 'deposit';
|
|
2277
|
+
timestamp = insertTime;
|
|
2278
|
+
}
|
|
2279
|
+
else if ((insertTime === undefined) && (createTime !== undefined)) {
|
|
2280
|
+
type = 'withdrawal';
|
|
2281
|
+
timestamp = createTime;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
const feeCost = this.safeNumber2(transaction, 'transactionFee', 'totalFee');
|
|
2285
|
+
const fee = {
|
|
2286
|
+
'currency': undefined,
|
|
2287
|
+
'cost': undefined,
|
|
2288
|
+
'rate': undefined,
|
|
2289
|
+
};
|
|
2290
|
+
if (feeCost !== undefined) {
|
|
2291
|
+
fee['currency'] = code;
|
|
2292
|
+
fee['cost'] = feeCost;
|
|
2293
|
+
}
|
|
2294
|
+
const internalRaw = this.safeInteger(transaction, 'transferType');
|
|
2295
|
+
let internal = false;
|
|
2296
|
+
if (internalRaw !== undefined) {
|
|
2297
|
+
internal = true;
|
|
2298
|
+
}
|
|
2299
|
+
let id = this.safeString(transaction, 'id');
|
|
2300
|
+
if (id === undefined) {
|
|
2301
|
+
const data = this.safeValue(transaction, 'data', {});
|
|
2302
|
+
id = this.safeString(data, 'withdrawId');
|
|
2303
|
+
type = 'withdrawal';
|
|
2304
|
+
}
|
|
2305
|
+
return {
|
|
2306
|
+
'info': transaction,
|
|
2307
|
+
'id': id,
|
|
2308
|
+
'txid': txid,
|
|
2309
|
+
'type': type,
|
|
2310
|
+
'currency': code,
|
|
2311
|
+
'network': this.safeString(transaction, 'network'),
|
|
2312
|
+
'amount': this.safeNumber(transaction, 'amount'),
|
|
2313
|
+
'status': this.parseTransactionStatusByType(this.safeString(transaction, 'status'), type),
|
|
2314
|
+
'timestamp': timestamp,
|
|
2315
|
+
'datetime': this.iso8601(timestamp),
|
|
2316
|
+
'address': address,
|
|
2317
|
+
'addressFrom': undefined,
|
|
2318
|
+
'addressTo': address,
|
|
2319
|
+
'tag': tag,
|
|
2320
|
+
'tagFrom': undefined,
|
|
2321
|
+
'tagTo': tag,
|
|
2322
|
+
'updated': this.safeInteger2(transaction, 'successTime', 'updateTime'),
|
|
2323
|
+
'comment': undefined,
|
|
2324
|
+
'internal': internal,
|
|
2325
|
+
'fee': fee,
|
|
2326
|
+
};
|
|
2327
|
+
}
|
|
2328
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2329
|
+
/**
|
|
2330
|
+
* @method
|
|
2331
|
+
* @name bybit#withdraw
|
|
2332
|
+
* @see https://www.tokocrypto.com/apidocs/#withdraw-signed
|
|
2333
|
+
* @description make a withdrawal
|
|
2334
|
+
* @param {string} code unified currency code
|
|
2335
|
+
* @param {float} amount the amount to withdraw
|
|
2336
|
+
* @param {string} address the address to withdraw to
|
|
2337
|
+
* @param {string} tag
|
|
2338
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2339
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2340
|
+
*/
|
|
2341
|
+
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
2342
|
+
await this.loadMarkets();
|
|
2343
|
+
this.checkAddress(address);
|
|
2344
|
+
const currency = this.currency(code);
|
|
2345
|
+
const request = {
|
|
2346
|
+
'asset': currency['id'],
|
|
2347
|
+
// 'clientId': 'string', // // client's custom id for withdraw order, server does not check it's uniqueness, automatically generated if not sent
|
|
2348
|
+
// 'network': 'string',
|
|
2349
|
+
'address': address,
|
|
2350
|
+
// 'addressTag': 'string', // for coins like XRP, XMR, etc
|
|
2351
|
+
'amount': this.numberToString(amount),
|
|
2352
|
+
};
|
|
2353
|
+
if (tag !== undefined) {
|
|
2354
|
+
request['addressTag'] = tag;
|
|
2355
|
+
}
|
|
2356
|
+
const [networkCode, query] = this.handleNetworkCodeAndParams(params);
|
|
2357
|
+
const networkId = this.networkCodeToId(networkCode);
|
|
2358
|
+
if (networkId !== undefined) {
|
|
2359
|
+
request['network'] = networkId.toUpperCase();
|
|
2360
|
+
}
|
|
2361
|
+
const response = await this.privatePostOpenV1Withdraws(this.extend(request, query));
|
|
2362
|
+
//
|
|
2363
|
+
// {
|
|
2364
|
+
// "code": 0,
|
|
2365
|
+
// "msg": "成功",
|
|
2366
|
+
// "data": {
|
|
2367
|
+
// "withdrawId":"12"
|
|
2368
|
+
// },
|
|
2369
|
+
// "timestamp": 1571745049095
|
|
2370
|
+
// }
|
|
2371
|
+
//
|
|
2372
|
+
return this.parseTransaction(response, currency);
|
|
2373
|
+
}
|
|
2374
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
2375
|
+
if (!(api in this.urls['api']['rest'])) {
|
|
2376
|
+
throw new errors.NotSupported(this.id + ' does not have a testnet/sandbox URL for ' + api + ' endpoints');
|
|
2377
|
+
}
|
|
2378
|
+
let url = this.urls['api']['rest'][api];
|
|
2379
|
+
url += '/' + path;
|
|
2380
|
+
if (api === 'wapi') {
|
|
2381
|
+
url += '.html';
|
|
2382
|
+
}
|
|
2383
|
+
const userDataStream = (path === 'userDataStream') || (path === 'listenKey');
|
|
2384
|
+
if (userDataStream) {
|
|
2385
|
+
if (this.apiKey) {
|
|
2386
|
+
// v1 special case for userDataStream
|
|
2387
|
+
headers = {
|
|
2388
|
+
'X-MBX-APIKEY': this.apiKey,
|
|
2389
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
2390
|
+
};
|
|
2391
|
+
if (method !== 'GET') {
|
|
2392
|
+
body = this.urlencode(params);
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
else {
|
|
2396
|
+
throw new errors.AuthenticationError(this.id + ' userDataStream endpoint requires `apiKey` credential');
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
else if ((api === 'private') || (api === 'sapi' && path !== 'system/status') || (api === 'sapiV3') || (api === 'wapi' && path !== 'systemStatus') || (api === 'dapiPrivate') || (api === 'dapiPrivateV2') || (api === 'fapiPrivate') || (api === 'fapiPrivateV2')) {
|
|
2400
|
+
this.checkRequiredCredentials();
|
|
2401
|
+
let query = undefined;
|
|
2402
|
+
const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
|
|
2403
|
+
const extendedParams = this.extend({
|
|
2404
|
+
'timestamp': this.nonce(),
|
|
2405
|
+
}, params);
|
|
2406
|
+
if (defaultRecvWindow !== undefined) {
|
|
2407
|
+
extendedParams['recvWindow'] = defaultRecvWindow;
|
|
2408
|
+
}
|
|
2409
|
+
const recvWindow = this.safeInteger(params, 'recvWindow');
|
|
2410
|
+
if (recvWindow !== undefined) {
|
|
2411
|
+
extendedParams['recvWindow'] = recvWindow;
|
|
2412
|
+
}
|
|
2413
|
+
if ((api === 'sapi') && (path === 'asset/dust')) {
|
|
2414
|
+
query = this.urlencodeWithArrayRepeat(extendedParams);
|
|
2415
|
+
}
|
|
2416
|
+
else if ((path === 'batchOrders') || (path.indexOf('sub-account') >= 0) || (path === 'capital/withdraw/apply') || (path.indexOf('staking') >= 0)) {
|
|
2417
|
+
query = this.rawencode(extendedParams);
|
|
2418
|
+
}
|
|
2419
|
+
else {
|
|
2420
|
+
query = this.urlencode(extendedParams);
|
|
2421
|
+
}
|
|
2422
|
+
const signature = this.hmac(this.encode(query), this.encode(this.secret), sha256.sha256);
|
|
2423
|
+
query += '&' + 'signature=' + signature;
|
|
2424
|
+
headers = {
|
|
2425
|
+
'X-MBX-APIKEY': this.apiKey,
|
|
2426
|
+
};
|
|
2427
|
+
if ((method === 'GET') || (method === 'DELETE') || (api === 'wapi')) {
|
|
2428
|
+
url += '?' + query;
|
|
2429
|
+
}
|
|
2430
|
+
else {
|
|
2431
|
+
body = query;
|
|
2432
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
else {
|
|
2436
|
+
if (Object.keys(params).length) {
|
|
2437
|
+
url += '?' + this.urlencode(params);
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
2441
|
+
}
|
|
2442
|
+
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
2443
|
+
if ((code === 418) || (code === 429)) {
|
|
2444
|
+
throw new errors.DDoSProtection(this.id + ' ' + code.toString() + ' ' + reason + ' ' + body);
|
|
2445
|
+
}
|
|
2446
|
+
// error response in a form: { "code": -1013, "msg": "Invalid quantity." }
|
|
2447
|
+
// following block cointains legacy checks against message patterns in "msg" property
|
|
2448
|
+
// will switch "code" checks eventually, when we know all of them
|
|
2449
|
+
if (code >= 400) {
|
|
2450
|
+
if (body.indexOf('Price * QTY is zero or less') >= 0) {
|
|
2451
|
+
throw new errors.InvalidOrder(this.id + ' order cost = amount * price is zero or less ' + body);
|
|
2452
|
+
}
|
|
2453
|
+
if (body.indexOf('LOT_SIZE') >= 0) {
|
|
2454
|
+
throw new errors.InvalidOrder(this.id + ' order amount should be evenly divisible by lot size ' + body);
|
|
2455
|
+
}
|
|
2456
|
+
if (body.indexOf('PRICE_FILTER') >= 0) {
|
|
2457
|
+
throw new errors.InvalidOrder(this.id + ' order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid value in general, use this.priceToPrecision (symbol, amount) ' + body);
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
if (response === undefined) {
|
|
2461
|
+
return undefined; // fallback to default error handler
|
|
2462
|
+
}
|
|
2463
|
+
// check success value for wapi endpoints
|
|
2464
|
+
// response in format {'msg': 'The coin does not exist.', 'success': true/false}
|
|
2465
|
+
const success = this.safeValue(response, 'success', true);
|
|
2466
|
+
if (!success) {
|
|
2467
|
+
const messageInner = this.safeString(response, 'msg');
|
|
2468
|
+
let parsedMessage = undefined;
|
|
2469
|
+
if (messageInner !== undefined) {
|
|
2470
|
+
try {
|
|
2471
|
+
parsedMessage = JSON.parse(messageInner);
|
|
2472
|
+
}
|
|
2473
|
+
catch (e) {
|
|
2474
|
+
// do nothing
|
|
2475
|
+
parsedMessage = undefined;
|
|
2476
|
+
}
|
|
2477
|
+
if (parsedMessage !== undefined) {
|
|
2478
|
+
response = parsedMessage;
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
const message = this.safeString(response, 'msg');
|
|
2483
|
+
if (message !== undefined) {
|
|
2484
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, this.id + ' ' + message);
|
|
2485
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, this.id + ' ' + message);
|
|
2486
|
+
}
|
|
2487
|
+
// checks against error codes
|
|
2488
|
+
const error = this.safeString(response, 'code');
|
|
2489
|
+
if (error !== undefined) {
|
|
2490
|
+
// https://github.com/ccxt/ccxt/issues/6501
|
|
2491
|
+
// https://github.com/ccxt/ccxt/issues/7742
|
|
2492
|
+
if ((error === '200') || Precise["default"].stringEquals(error, '0')) {
|
|
2493
|
+
return undefined;
|
|
2494
|
+
}
|
|
2495
|
+
// a workaround for {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."}
|
|
2496
|
+
// despite that their message is very confusing, it is raised by Binance
|
|
2497
|
+
// on a temporary ban, the API key is valid, but disabled for a while
|
|
2498
|
+
if ((error === '-2015') && this.options['hasAlreadyAuthenticatedSuccessfully']) {
|
|
2499
|
+
throw new errors.DDoSProtection(this.id + ' ' + body);
|
|
2500
|
+
}
|
|
2501
|
+
const feedback = this.id + ' ' + body;
|
|
2502
|
+
if (message === 'No need to change margin type.') {
|
|
2503
|
+
// not an error
|
|
2504
|
+
// https://github.com/ccxt/ccxt/issues/11268
|
|
2505
|
+
// https://github.com/ccxt/ccxt/pull/11624
|
|
2506
|
+
// POST https://fapi.binance.com/fapi/v1/marginType 400 Bad Request
|
|
2507
|
+
// binanceusdm {"code":-4046,"msg":"No need to change margin type."}
|
|
2508
|
+
throw new errors.MarginModeAlreadySet(feedback);
|
|
2509
|
+
}
|
|
2510
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], error, feedback);
|
|
2511
|
+
throw new errors.ExchangeError(feedback);
|
|
2512
|
+
}
|
|
2513
|
+
if (!success) {
|
|
2514
|
+
throw new errors.ExchangeError(this.id + ' ' + body);
|
|
2515
|
+
}
|
|
2516
|
+
return undefined;
|
|
2517
|
+
}
|
|
2518
|
+
calculateRateLimiterCost(api, method, path, params, config = {}) {
|
|
2519
|
+
if (('noCoin' in config) && !('coin' in params)) {
|
|
2520
|
+
return config['noCoin'];
|
|
2521
|
+
}
|
|
2522
|
+
else if (('noSymbol' in config) && !('symbol' in params)) {
|
|
2523
|
+
return config['noSymbol'];
|
|
2524
|
+
}
|
|
2525
|
+
else if (('noPoolId' in config) && !('poolId' in params)) {
|
|
2526
|
+
return config['noPoolId'];
|
|
2527
|
+
}
|
|
2528
|
+
else if (('byLimit' in config) && ('limit' in params)) {
|
|
2529
|
+
const limit = params['limit'];
|
|
2530
|
+
const byLimit = config['byLimit'];
|
|
2531
|
+
for (let i = 0; i < byLimit.length; i++) {
|
|
2532
|
+
const entry = byLimit[i];
|
|
2533
|
+
if (limit <= entry[0]) {
|
|
2534
|
+
return entry[1];
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
return this.safeInteger(config, 'cost', 1);
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
module.exports = tokocrypto;
|