ccxt 4.2.11 → 4.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/build.sh +2 -2
- package/dist/ccxt.browser.js +640 -261
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/_virtual/agent.js +7 -0
- package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
- package/dist/cjs/_virtual/promisify.js +7 -0
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/js/ccxt.js +474 -0
- package/dist/cjs/js/src/abstract/ace.js +9 -0
- package/dist/cjs/js/src/abstract/alpaca.js +9 -0
- package/dist/cjs/js/src/abstract/ascendex.js +9 -0
- package/dist/cjs/js/src/abstract/bigone.js +9 -0
- package/dist/cjs/js/src/abstract/binance.js +9 -0
- package/dist/cjs/js/src/abstract/bingx.js +9 -0
- package/dist/cjs/js/src/abstract/bit2c.js +9 -0
- package/dist/cjs/js/src/abstract/bitbank.js +9 -0
- package/dist/cjs/js/src/abstract/bitbns.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
- package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
- package/dist/cjs/js/src/abstract/bitforex.js +9 -0
- package/dist/cjs/js/src/abstract/bitget.js +9 -0
- package/dist/cjs/js/src/abstract/bithumb.js +9 -0
- package/dist/cjs/js/src/abstract/bitmart.js +9 -0
- package/dist/cjs/js/src/abstract/bitmex.js +9 -0
- package/dist/cjs/js/src/abstract/bitopro.js +9 -0
- package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
- package/dist/cjs/js/src/abstract/bitrue.js +9 -0
- package/dist/cjs/js/src/abstract/bitso.js +9 -0
- package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
- package/dist/cjs/js/src/abstract/bitteam.js +9 -0
- package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
- package/dist/cjs/js/src/abstract/bl3p.js +9 -0
- package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
- package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
- package/dist/cjs/js/src/abstract/btcbox.js +9 -0
- package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
- package/dist/cjs/js/src/abstract/btcturk.js +9 -0
- package/dist/cjs/js/src/abstract/bybit.js +9 -0
- package/dist/cjs/js/src/abstract/cex.js +9 -0
- package/dist/cjs/js/src/abstract/coinbase.js +9 -0
- package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
- package/dist/cjs/js/src/abstract/coincheck.js +9 -0
- package/dist/cjs/js/src/abstract/coinex.js +9 -0
- package/dist/cjs/js/src/abstract/coinlist.js +9 -0
- package/dist/cjs/js/src/abstract/coinmate.js +9 -0
- package/dist/cjs/js/src/abstract/coinone.js +9 -0
- package/dist/cjs/js/src/abstract/coinsph.js +9 -0
- package/dist/cjs/js/src/abstract/coinspot.js +9 -0
- package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
- package/dist/cjs/js/src/abstract/currencycom.js +9 -0
- package/dist/cjs/js/src/abstract/delta.js +9 -0
- package/dist/cjs/js/src/abstract/deribit.js +9 -0
- package/dist/cjs/js/src/abstract/digifinex.js +9 -0
- package/dist/cjs/js/src/abstract/exmo.js +9 -0
- package/dist/cjs/js/src/abstract/gate.js +9 -0
- package/dist/cjs/js/src/abstract/gemini.js +9 -0
- package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
- package/dist/cjs/js/src/abstract/hollaex.js +9 -0
- package/dist/cjs/js/src/abstract/htx.js +9 -0
- package/dist/cjs/js/src/abstract/huobijp.js +9 -0
- package/dist/cjs/js/src/abstract/idex.js +9 -0
- package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
- package/dist/cjs/js/src/abstract/indodax.js +9 -0
- package/dist/cjs/js/src/abstract/kraken.js +9 -0
- package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kucoin.js +9 -0
- package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kuna.js +9 -0
- package/dist/cjs/js/src/abstract/latoken.js +9 -0
- package/dist/cjs/js/src/abstract/lbank.js +9 -0
- package/dist/cjs/js/src/abstract/luno.js +9 -0
- package/dist/cjs/js/src/abstract/lykke.js +9 -0
- package/dist/cjs/js/src/abstract/mercado.js +9 -0
- package/dist/cjs/js/src/abstract/mexc.js +9 -0
- package/dist/cjs/js/src/abstract/ndax.js +9 -0
- package/dist/cjs/js/src/abstract/novadax.js +9 -0
- package/dist/cjs/js/src/abstract/oceanex.js +9 -0
- package/dist/cjs/js/src/abstract/okcoin.js +9 -0
- package/dist/cjs/js/src/abstract/okx.js +9 -0
- package/dist/cjs/js/src/abstract/p2b.js +9 -0
- package/dist/cjs/js/src/abstract/paymium.js +9 -0
- package/dist/cjs/js/src/abstract/phemex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
- package/dist/cjs/js/src/abstract/probit.js +9 -0
- package/dist/cjs/js/src/abstract/timex.js +9 -0
- package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
- package/dist/cjs/js/src/abstract/upbit.js +9 -0
- package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
- package/dist/cjs/js/src/abstract/wazirx.js +9 -0
- package/dist/cjs/js/src/abstract/whitebit.js +9 -0
- package/dist/cjs/js/src/abstract/woo.js +9 -0
- package/dist/cjs/js/src/abstract/yobit.js +9 -0
- package/dist/cjs/js/src/abstract/zaif.js +9 -0
- package/dist/cjs/js/src/abstract/zonda.js +9 -0
- package/dist/cjs/js/src/ace.js +1058 -0
- package/dist/cjs/js/src/alpaca.js +1125 -0
- package/dist/cjs/js/src/ascendex.js +3360 -0
- package/dist/cjs/js/src/base/Exchange.js +5110 -0
- package/dist/cjs/js/src/base/Precise.js +263 -0
- package/dist/cjs/js/src/base/errors.js +299 -0
- package/dist/cjs/js/src/base/functions/crypto.js +78 -0
- package/dist/cjs/js/src/base/functions/encode.js +44 -0
- package/dist/cjs/js/src/base/functions/generic.js +193 -0
- package/dist/cjs/js/src/base/functions/misc.js +96 -0
- package/dist/cjs/js/src/base/functions/number.js +297 -0
- package/dist/cjs/js/src/base/functions/platform.js +28 -0
- package/dist/cjs/js/src/base/functions/rsa.js +34 -0
- package/dist/cjs/js/src/base/functions/string.js +48 -0
- package/dist/cjs/js/src/base/functions/throttle.js +66 -0
- package/dist/cjs/js/src/base/functions/time.js +187 -0
- package/dist/cjs/js/src/base/functions/totp.js +24 -0
- package/dist/cjs/js/src/base/functions/type.js +162 -0
- package/dist/cjs/js/src/base/functions.js +157 -0
- package/dist/cjs/js/src/base/ws/Cache.js +254 -0
- package/dist/cjs/js/src/base/ws/Client.js +299 -0
- package/dist/cjs/js/src/base/ws/Future.js +34 -0
- package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
- package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
- package/dist/cjs/js/src/bequant.js +33 -0
- package/dist/cjs/js/src/bigone.js +2142 -0
- package/dist/cjs/js/src/binance.js +9729 -0
- package/dist/cjs/js/src/binancecoinm.js +45 -0
- package/dist/cjs/js/src/binanceus.js +84 -0
- package/dist/cjs/js/src/binanceusdm.js +58 -0
- package/dist/cjs/js/src/bingx.js +3737 -0
- package/dist/cjs/js/src/bit2c.js +916 -0
- package/dist/cjs/js/src/bitbank.js +1000 -0
- package/dist/cjs/js/src/bitbay.js +17 -0
- package/dist/cjs/js/src/bitbns.js +1220 -0
- package/dist/cjs/js/src/bitcoincom.js +17 -0
- package/dist/cjs/js/src/bitfinex.js +1670 -0
- package/dist/cjs/js/src/bitfinex2.js +2990 -0
- package/dist/cjs/js/src/bitflyer.js +1045 -0
- package/dist/cjs/js/src/bitforex.js +852 -0
- package/dist/cjs/js/src/bitget.js +8284 -0
- package/dist/cjs/js/src/bithumb.js +1090 -0
- package/dist/cjs/js/src/bitmart.js +4454 -0
- package/dist/cjs/js/src/bitmex.js +2884 -0
- package/dist/cjs/js/src/bitopro.js +1724 -0
- package/dist/cjs/js/src/bitpanda.js +2002 -0
- package/dist/cjs/js/src/bitrue.js +3253 -0
- package/dist/cjs/js/src/bitso.js +1753 -0
- package/dist/cjs/js/src/bitstamp.js +2188 -0
- package/dist/cjs/js/src/bitteam.js +2309 -0
- package/dist/cjs/js/src/bitvavo.js +1968 -0
- package/dist/cjs/js/src/bl3p.js +447 -0
- package/dist/cjs/js/src/blockchaincom.js +1160 -0
- package/dist/cjs/js/src/btcalpha.js +929 -0
- package/dist/cjs/js/src/btcbox.js +565 -0
- package/dist/cjs/js/src/btcmarkets.js +1237 -0
- package/dist/cjs/js/src/btcturk.js +929 -0
- package/dist/cjs/js/src/bybit.js +7646 -0
- package/dist/cjs/js/src/cex.js +1693 -0
- package/dist/cjs/js/src/coinbase.js +3274 -0
- package/dist/cjs/js/src/coinbasepro.js +1866 -0
- package/dist/cjs/js/src/coincheck.js +843 -0
- package/dist/cjs/js/src/coinex.js +5414 -0
- package/dist/cjs/js/src/coinlist.js +2329 -0
- package/dist/cjs/js/src/coinmate.js +989 -0
- package/dist/cjs/js/src/coinone.js +1185 -0
- package/dist/cjs/js/src/coinsph.js +1933 -0
- package/dist/cjs/js/src/coinspot.js +548 -0
- package/dist/cjs/js/src/cryptocom.js +3007 -0
- package/dist/cjs/js/src/currencycom.js +2015 -0
- package/dist/cjs/js/src/delta.js +3256 -0
- package/dist/cjs/js/src/deribit.js +3306 -0
- package/dist/cjs/js/src/digifinex.js +4307 -0
- package/dist/cjs/js/src/exmo.js +2645 -0
- package/dist/cjs/js/src/fmfwio.js +34 -0
- package/dist/cjs/js/src/gate.js +7054 -0
- package/dist/cjs/js/src/gateio.js +16 -0
- package/dist/cjs/js/src/gemini.js +1801 -0
- package/dist/cjs/js/src/hitbtc.js +3660 -0
- package/dist/cjs/js/src/hitbtc3.js +19 -0
- package/dist/cjs/js/src/hollaex.js +1882 -0
- package/dist/cjs/js/src/htx.js +9024 -0
- package/dist/cjs/js/src/huobi.js +16 -0
- package/dist/cjs/js/src/huobijp.js +1918 -0
- package/dist/cjs/js/src/idex.js +1770 -0
- package/dist/cjs/js/src/independentreserve.js +759 -0
- package/dist/cjs/js/src/indodax.js +1069 -0
- package/dist/cjs/js/src/kraken.js +2861 -0
- package/dist/cjs/js/src/krakenfutures.js +2407 -0
- package/dist/cjs/js/src/kucoin.js +4489 -0
- package/dist/cjs/js/src/kucoinfutures.js +2475 -0
- package/dist/cjs/js/src/kuna.js +1949 -0
- package/dist/cjs/js/src/latoken.js +1729 -0
- package/dist/cjs/js/src/lbank.js +2825 -0
- package/dist/cjs/js/src/luno.js +1044 -0
- package/dist/cjs/js/src/lykke.js +1303 -0
- package/dist/cjs/js/src/mercado.js +897 -0
- package/dist/cjs/js/src/mexc.js +5407 -0
- package/dist/cjs/js/src/ndax.js +2450 -0
- package/dist/cjs/js/src/novadax.js +1556 -0
- package/dist/cjs/js/src/oceanex.js +964 -0
- package/dist/cjs/js/src/okcoin.js +3115 -0
- package/dist/cjs/js/src/okx.js +7329 -0
- package/dist/cjs/js/src/p2b.js +1243 -0
- package/dist/cjs/js/src/paymium.js +597 -0
- package/dist/cjs/js/src/phemex.js +4715 -0
- package/dist/cjs/js/src/poloniex.js +2356 -0
- package/dist/cjs/js/src/poloniexfutures.js +1794 -0
- package/dist/cjs/js/src/pro/alpaca.js +714 -0
- package/dist/cjs/js/src/pro/ascendex.js +957 -0
- package/dist/cjs/js/src/pro/bequant.js +33 -0
- package/dist/cjs/js/src/pro/binance.js +2796 -0
- package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
- package/dist/cjs/js/src/pro/binanceus.js +51 -0
- package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
- package/dist/cjs/js/src/pro/bingx.js +944 -0
- package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
- package/dist/cjs/js/src/pro/bitfinex.js +672 -0
- package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
- package/dist/cjs/js/src/pro/bitget.js +1733 -0
- package/dist/cjs/js/src/pro/bitmart.js +1486 -0
- package/dist/cjs/js/src/pro/bitmex.js +1576 -0
- package/dist/cjs/js/src/pro/bitopro.js +327 -0
- package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
- package/dist/cjs/js/src/pro/bitrue.js +462 -0
- package/dist/cjs/js/src/pro/bitstamp.js +547 -0
- package/dist/cjs/js/src/pro/bitvavo.js +704 -0
- package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
- package/dist/cjs/js/src/pro/bybit.js +1843 -0
- package/dist/cjs/js/src/pro/cex.js +1510 -0
- package/dist/cjs/js/src/pro/coinbase.js +561 -0
- package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
- package/dist/cjs/js/src/pro/coinex.js +1095 -0
- package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
- package/dist/cjs/js/src/pro/currencycom.js +563 -0
- package/dist/cjs/js/src/pro/deribit.js +825 -0
- package/dist/cjs/js/src/pro/exmo.js +658 -0
- package/dist/cjs/js/src/pro/gate.js +1316 -0
- package/dist/cjs/js/src/pro/gateio.js +16 -0
- package/dist/cjs/js/src/pro/gemini.js +649 -0
- package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
- package/dist/cjs/js/src/pro/hollaex.js +597 -0
- package/dist/cjs/js/src/pro/htx.js +2383 -0
- package/dist/cjs/js/src/pro/huobi.js +16 -0
- package/dist/cjs/js/src/pro/huobijp.js +606 -0
- package/dist/cjs/js/src/pro/idex.js +714 -0
- package/dist/cjs/js/src/pro/independentreserve.js +280 -0
- package/dist/cjs/js/src/pro/kraken.js +1364 -0
- package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
- package/dist/cjs/js/src/pro/kucoin.js +1052 -0
- package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
- package/dist/cjs/js/src/pro/luno.js +322 -0
- package/dist/cjs/js/src/pro/mexc.js +1170 -0
- package/dist/cjs/js/src/pro/ndax.js +545 -0
- package/dist/cjs/js/src/pro/okcoin.js +760 -0
- package/dist/cjs/js/src/pro/okx.js +1558 -0
- package/dist/cjs/js/src/pro/phemex.js +1511 -0
- package/dist/cjs/js/src/pro/poloniex.js +1253 -0
- package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
- package/dist/cjs/js/src/pro/probit.js +586 -0
- package/dist/cjs/js/src/pro/upbit.js +234 -0
- package/dist/cjs/js/src/pro/wazirx.js +776 -0
- package/dist/cjs/js/src/pro/whitebit.js +927 -0
- package/dist/cjs/js/src/pro/woo.js +769 -0
- package/dist/cjs/js/src/probit.js +1865 -0
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
- package/dist/cjs/js/src/timex.js +1562 -0
- package/dist/cjs/js/src/tokocrypto.js +2542 -0
- package/dist/cjs/js/src/upbit.js +1844 -0
- package/dist/cjs/js/src/wavesexchange.js +2607 -0
- package/dist/cjs/js/src/wazirx.js +953 -0
- package/dist/cjs/js/src/whitebit.js +2309 -0
- package/dist/cjs/js/src/woo.js +2715 -0
- package/dist/cjs/js/src/yobit.js +1314 -0
- package/dist/cjs/js/src/zaif.js +736 -0
- package/dist/cjs/js/src/zonda.js +1883 -0
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bigone.d.ts +18 -0
- package/js/src/abstract/binance.d.ts +2 -0
- package/js/src/abstract/binancecoinm.d.ts +2 -0
- package/js/src/abstract/binanceus.d.ts +2 -0
- package/js/src/abstract/binanceusdm.d.ts +2 -0
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/abstract/gate.d.ts +11 -0
- package/js/src/abstract/gateio.d.ts +11 -0
- package/js/src/alpaca.js +18 -18
- package/js/src/base/Exchange.d.ts +5 -1
- package/js/src/base/Exchange.js +101 -12
- package/js/src/bigone.d.ts +1 -2
- package/js/src/bigone.js +340 -145
- package/js/src/binance.js +15 -8
- package/js/src/bingx.js +9 -2
- package/js/src/bitfinex.d.ts +2 -2
- package/js/src/bitfinex.js +2 -3
- package/js/src/bitget.js +21 -8
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +3 -3
- package/js/src/bitmex.js +1 -0
- package/js/src/bybit.js +2 -0
- package/js/src/coinlist.js +2 -3
- package/js/src/coinsph.js +2 -3
- package/js/src/deribit.js +1 -0
- package/js/src/gate.d.ts +4 -4
- package/js/src/gate.js +22 -3
- package/js/src/hitbtc.d.ts +4 -4
- package/js/src/hitbtc.js +2 -3
- package/js/src/htx.js +4 -7
- package/js/src/huobijp.js +2 -3
- package/js/src/kraken.js +1 -0
- package/js/src/mexc.js +2 -1
- package/js/src/okx.js +13 -3
- package/js/src/pro/binance.d.ts +2 -23
- package/js/src/pro/binance.js +58 -22
- package/js/src/pro/coinbase.d.ts +2 -2
- package/js/src/pro/coinbase.js +4 -1
- package/js/src/pro/coinbasepro.d.ts +2 -2
- package/js/src/pro/hitbtc.d.ts +2 -2
- package/js/src/pro/poloniex.d.ts +2 -2
- package/js/src/upbit.d.ts +3 -101
- package/js/src/upbit.js +12 -12
- package/js/src/woo.js +2 -0
- package/package.json +1 -1
- package/skip-tests.json +5 -0
|
@@ -0,0 +1,2407 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var krakenfutures$1 = require('./abstract/krakenfutures.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
|
+
var sha512 = require('./static_dependencies/noble-hashes/sha512.js');
|
|
9
|
+
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* @class krakenfutures
|
|
14
|
+
* @augments Exchange
|
|
15
|
+
*/
|
|
16
|
+
class krakenfutures extends krakenfutures$1 {
|
|
17
|
+
describe() {
|
|
18
|
+
return this.deepExtend(super.describe(), {
|
|
19
|
+
'id': 'krakenfutures',
|
|
20
|
+
'name': 'Kraken Futures',
|
|
21
|
+
'countries': ['US'],
|
|
22
|
+
'version': 'v3',
|
|
23
|
+
'userAgent': undefined,
|
|
24
|
+
'rateLimit': 600,
|
|
25
|
+
'pro': true,
|
|
26
|
+
'has': {
|
|
27
|
+
'CORS': undefined,
|
|
28
|
+
'spot': false,
|
|
29
|
+
'margin': false,
|
|
30
|
+
'swap': true,
|
|
31
|
+
'future': true,
|
|
32
|
+
'option': false,
|
|
33
|
+
'cancelAllOrders': true,
|
|
34
|
+
'cancelOrder': true,
|
|
35
|
+
'cancelOrders': true,
|
|
36
|
+
'createMarketOrder': false,
|
|
37
|
+
'createOrder': true,
|
|
38
|
+
'editOrder': true,
|
|
39
|
+
'fetchBalance': true,
|
|
40
|
+
'fetchBorrowRateHistories': false,
|
|
41
|
+
'fetchBorrowRateHistory': false,
|
|
42
|
+
'fetchClosedOrders': undefined,
|
|
43
|
+
'fetchCrossBorrowRate': false,
|
|
44
|
+
'fetchCrossBorrowRates': false,
|
|
45
|
+
'fetchFundingHistory': undefined,
|
|
46
|
+
'fetchFundingRate': 'emulated',
|
|
47
|
+
'fetchFundingRateHistory': true,
|
|
48
|
+
'fetchFundingRates': true,
|
|
49
|
+
'fetchIndexOHLCV': false,
|
|
50
|
+
'fetchIsolatedBorrowRate': false,
|
|
51
|
+
'fetchIsolatedBorrowRates': false,
|
|
52
|
+
'fetchIsolatedPositions': false,
|
|
53
|
+
'fetchLeverage': true,
|
|
54
|
+
'fetchLeverageTiers': true,
|
|
55
|
+
'fetchMarketLeverageTiers': 'emulated',
|
|
56
|
+
'fetchMarkets': true,
|
|
57
|
+
'fetchMarkOHLCV': true,
|
|
58
|
+
'fetchMyTrades': true,
|
|
59
|
+
'fetchOHLCV': true,
|
|
60
|
+
'fetchOpenOrders': true,
|
|
61
|
+
'fetchOrder': false,
|
|
62
|
+
'fetchOrderBook': true,
|
|
63
|
+
'fetchOrders': false,
|
|
64
|
+
'fetchPositions': true,
|
|
65
|
+
'fetchPremiumIndexOHLCV': false,
|
|
66
|
+
'fetchTickers': true,
|
|
67
|
+
'fetchTrades': true,
|
|
68
|
+
'setLeverage': true,
|
|
69
|
+
'setMarginMode': false,
|
|
70
|
+
'transfer': true,
|
|
71
|
+
},
|
|
72
|
+
'urls': {
|
|
73
|
+
'test': {
|
|
74
|
+
'public': 'https://demo-futures.kraken.com/derivatives/api/',
|
|
75
|
+
'private': 'https://demo-futures.kraken.com/derivatives/api/',
|
|
76
|
+
'charts': 'https://demo-futures.kraken.com/api/charts/',
|
|
77
|
+
'www': 'https://demo-futures.kraken.com',
|
|
78
|
+
},
|
|
79
|
+
'logo': 'https://user-images.githubusercontent.com/24300605/81436764-b22fd580-9172-11ea-9703-742783e6376d.jpg',
|
|
80
|
+
'api': {
|
|
81
|
+
'charts': 'https://futures.kraken.com/api/charts/',
|
|
82
|
+
'history': 'https://futures.kraken.com/api/history/',
|
|
83
|
+
'feeschedules': 'https://futures.kraken.com/api/feeschedules/',
|
|
84
|
+
'public': 'https://futures.kraken.com/derivatives/api/',
|
|
85
|
+
'private': 'https://futures.kraken.com/derivatives/api/',
|
|
86
|
+
},
|
|
87
|
+
'www': 'https://futures.kraken.com/',
|
|
88
|
+
'doc': [
|
|
89
|
+
'https://docs.futures.kraken.com/#introduction',
|
|
90
|
+
],
|
|
91
|
+
'fees': 'https://support.kraken.com/hc/en-us/articles/360022835771-Transaction-fees-and-rebates-for-Kraken-Futures',
|
|
92
|
+
'referral': undefined,
|
|
93
|
+
},
|
|
94
|
+
'api': {
|
|
95
|
+
'public': {
|
|
96
|
+
'get': [
|
|
97
|
+
'feeschedules',
|
|
98
|
+
'instruments',
|
|
99
|
+
'orderbook',
|
|
100
|
+
'tickers',
|
|
101
|
+
'history',
|
|
102
|
+
'historicalfundingrates',
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
'private': {
|
|
106
|
+
'get': [
|
|
107
|
+
'feeschedules/volumes',
|
|
108
|
+
'openpositions',
|
|
109
|
+
'notifications',
|
|
110
|
+
'accounts',
|
|
111
|
+
'openorders',
|
|
112
|
+
'recentorders',
|
|
113
|
+
'fills',
|
|
114
|
+
'transfers',
|
|
115
|
+
'leveragepreferences',
|
|
116
|
+
'pnlpreferences',
|
|
117
|
+
],
|
|
118
|
+
'post': [
|
|
119
|
+
'sendorder',
|
|
120
|
+
'editorder',
|
|
121
|
+
'cancelorder',
|
|
122
|
+
'transfer',
|
|
123
|
+
'batchorder',
|
|
124
|
+
'cancelallorders',
|
|
125
|
+
'cancelallordersafter',
|
|
126
|
+
'withdrawal', // for futures wallet -> kraken spot wallet
|
|
127
|
+
],
|
|
128
|
+
'put': [
|
|
129
|
+
'leveragepreferences',
|
|
130
|
+
'pnlpreferences',
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
'charts': {
|
|
134
|
+
'get': [
|
|
135
|
+
'{price_type}/{symbol}/{interval}',
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
'history': {
|
|
139
|
+
'get': [
|
|
140
|
+
'orders',
|
|
141
|
+
'executions',
|
|
142
|
+
'triggers',
|
|
143
|
+
'accountlogcsv',
|
|
144
|
+
'market/{symbol}/orders',
|
|
145
|
+
'market/{symbol}/executions',
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
'fees': {
|
|
150
|
+
'trading': {
|
|
151
|
+
'tierBased': false,
|
|
152
|
+
'percentage': true,
|
|
153
|
+
'maker': this.parseNumber('-0.0002'),
|
|
154
|
+
'taker': this.parseNumber('0.00075'),
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
'exceptions': {
|
|
158
|
+
'exact': {
|
|
159
|
+
'apiLimitExceeded': errors.RateLimitExceeded,
|
|
160
|
+
'marketUnavailable': errors.ContractUnavailable,
|
|
161
|
+
'requiredArgumentMissing': errors.BadRequest,
|
|
162
|
+
'unavailable': errors.ExchangeNotAvailable,
|
|
163
|
+
'authenticationError': errors.AuthenticationError,
|
|
164
|
+
'accountInactive': errors.ExchangeError,
|
|
165
|
+
'invalidAccount': errors.BadRequest,
|
|
166
|
+
'invalidAmount': errors.BadRequest,
|
|
167
|
+
'insufficientFunds': errors.InsufficientFunds,
|
|
168
|
+
'Bad Request': errors.BadRequest,
|
|
169
|
+
'Unavailable': errors.InsufficientFunds,
|
|
170
|
+
'invalidUnit': errors.BadRequest,
|
|
171
|
+
'Json Parse Error': errors.ExchangeError,
|
|
172
|
+
'nonceBelowThreshold': errors.InvalidNonce,
|
|
173
|
+
'nonceDuplicate': errors.InvalidNonce,
|
|
174
|
+
'notFound': errors.BadRequest,
|
|
175
|
+
'Server Error': errors.ExchangeError,
|
|
176
|
+
'unknownError': errors.ExchangeError,
|
|
177
|
+
},
|
|
178
|
+
'broad': {
|
|
179
|
+
'invalidArgument': errors.BadRequest,
|
|
180
|
+
'nonceBelowThreshold': errors.InvalidNonce,
|
|
181
|
+
'nonceDuplicate': errors.InvalidNonce,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
'precisionMode': number.TICK_SIZE,
|
|
185
|
+
'options': {
|
|
186
|
+
'access': {
|
|
187
|
+
'history': {
|
|
188
|
+
'GET': {
|
|
189
|
+
'orders': 'private',
|
|
190
|
+
'executions': 'private',
|
|
191
|
+
'triggers': 'private',
|
|
192
|
+
'accountlogcsv': 'private',
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
'settlementCurrencies': {
|
|
197
|
+
'flex': ['USDT', 'BTC', 'USD', 'GBP', 'EUR', 'USDC'],
|
|
198
|
+
},
|
|
199
|
+
'symbol': {
|
|
200
|
+
'quoteIds': ['USD', 'XBT'],
|
|
201
|
+
'reversed': false,
|
|
202
|
+
},
|
|
203
|
+
'versions': {
|
|
204
|
+
'public': {
|
|
205
|
+
'GET': {
|
|
206
|
+
'historicalfundingrates': 'v4',
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
'charts': {
|
|
210
|
+
'GET': {
|
|
211
|
+
'{price_type}/{symbol}/{interval}': 'v1',
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
'history': {
|
|
215
|
+
'GET': {
|
|
216
|
+
'orders': 'v2',
|
|
217
|
+
'executions': 'v2',
|
|
218
|
+
'triggers': 'v2',
|
|
219
|
+
'accountlogcsv': 'v2',
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
'timeframes': {
|
|
225
|
+
'1m': '1m',
|
|
226
|
+
'5m': '5m',
|
|
227
|
+
'15m': '15m',
|
|
228
|
+
'30m': '30m',
|
|
229
|
+
'1h': '1h',
|
|
230
|
+
'4h': '4h',
|
|
231
|
+
'12h': '12h',
|
|
232
|
+
'1d': '1d',
|
|
233
|
+
'1w': '1w',
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
async fetchMarkets(params = {}) {
|
|
238
|
+
/**
|
|
239
|
+
* @method
|
|
240
|
+
* @name krakenfutures#fetchMarkets
|
|
241
|
+
* @description Fetches the available trading markets from the exchange, Multi-collateral markets are returned as linear markets, but can be settled in multiple currencies
|
|
242
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-instrument-details-get-instruments
|
|
243
|
+
* @param {object} [params] exchange specific params
|
|
244
|
+
* @returns An array of market structures
|
|
245
|
+
*/
|
|
246
|
+
const response = await this.publicGetInstruments(params);
|
|
247
|
+
//
|
|
248
|
+
// {
|
|
249
|
+
// "result": "success",
|
|
250
|
+
// "instruments": [
|
|
251
|
+
// {
|
|
252
|
+
// "symbol": "fi_ethusd_180928",
|
|
253
|
+
// "type": "futures_inverse", // futures_vanilla // spot index
|
|
254
|
+
// "underlying": "rr_ethusd",
|
|
255
|
+
// "lastTradingTime": "2018-09-28T15:00:00.000Z",
|
|
256
|
+
// "tickSize": 0.1,
|
|
257
|
+
// "contractSize": 1,
|
|
258
|
+
// "tradeable": true,
|
|
259
|
+
// "marginLevels": [
|
|
260
|
+
// {
|
|
261
|
+
// "contracts":0,
|
|
262
|
+
// "initialMargin":0.02,
|
|
263
|
+
// "maintenanceMargin":0.01
|
|
264
|
+
// },
|
|
265
|
+
// {
|
|
266
|
+
// "contracts":250000,
|
|
267
|
+
// "initialMargin":0.04,
|
|
268
|
+
// "maintenanceMargin":0.02
|
|
269
|
+
// },
|
|
270
|
+
// ...
|
|
271
|
+
// ],
|
|
272
|
+
// "isin": "GB00JVMLMP88",
|
|
273
|
+
// "retailMarginLevels": [
|
|
274
|
+
// {
|
|
275
|
+
// "contracts": 0,
|
|
276
|
+
// "initialMargin": 0.5,
|
|
277
|
+
// "maintenanceMargin": 0.25
|
|
278
|
+
// }
|
|
279
|
+
// ],
|
|
280
|
+
// "tags": [],
|
|
281
|
+
// },
|
|
282
|
+
// {
|
|
283
|
+
// "symbol": "in_xbtusd",
|
|
284
|
+
// "type": "spot index",
|
|
285
|
+
// "tradeable":false
|
|
286
|
+
// }
|
|
287
|
+
// ]
|
|
288
|
+
// "serverTime": "2018-07-19T11:32:39.433Z"
|
|
289
|
+
// }
|
|
290
|
+
//
|
|
291
|
+
const instruments = this.safeValue(response, 'instruments', []);
|
|
292
|
+
const result = [];
|
|
293
|
+
for (let i = 0; i < instruments.length; i++) {
|
|
294
|
+
const market = instruments[i];
|
|
295
|
+
const id = this.safeString(market, 'symbol');
|
|
296
|
+
const marketType = this.safeString(market, 'type');
|
|
297
|
+
let type = undefined;
|
|
298
|
+
const index = (marketType.indexOf(' index') >= 0);
|
|
299
|
+
let linear = undefined;
|
|
300
|
+
let inverse = undefined;
|
|
301
|
+
let expiry = undefined;
|
|
302
|
+
if (!index) {
|
|
303
|
+
linear = (marketType.indexOf('_vanilla') >= 0);
|
|
304
|
+
inverse = !linear;
|
|
305
|
+
const settleTime = this.safeString(market, 'lastTradingTime');
|
|
306
|
+
type = (settleTime === undefined) ? 'swap' : 'future';
|
|
307
|
+
expiry = this.parse8601(settleTime);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
type = 'index';
|
|
311
|
+
}
|
|
312
|
+
const swap = (type === 'swap');
|
|
313
|
+
const future = (type === 'future');
|
|
314
|
+
let symbol = id;
|
|
315
|
+
const split = id.split('_');
|
|
316
|
+
const splitMarket = this.safeString(split, 1);
|
|
317
|
+
const baseId = splitMarket.slice(0, splitMarket.length - 3);
|
|
318
|
+
const quoteId = 'usd'; // always USD
|
|
319
|
+
const base = this.safeCurrencyCode(baseId);
|
|
320
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
321
|
+
// swap == perpetual
|
|
322
|
+
let settle = undefined;
|
|
323
|
+
let settleId = undefined;
|
|
324
|
+
const amountPrecision = this.parseNumber(this.parsePrecision(this.safeString(market, 'contractValueTradePrecision', '0')));
|
|
325
|
+
const pricePrecision = this.safeNumber(market, 'tickSize');
|
|
326
|
+
const contract = (swap || future || index);
|
|
327
|
+
const swapOrFutures = (swap || future);
|
|
328
|
+
if (swapOrFutures) {
|
|
329
|
+
const exchangeType = this.safeString(market, 'type');
|
|
330
|
+
if (exchangeType === 'futures_inverse') {
|
|
331
|
+
settle = base;
|
|
332
|
+
settleId = baseId;
|
|
333
|
+
inverse = true;
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
settle = quote;
|
|
337
|
+
settleId = quoteId;
|
|
338
|
+
inverse = false;
|
|
339
|
+
}
|
|
340
|
+
linear = !inverse;
|
|
341
|
+
symbol = base + '/' + quote + ':' + settle;
|
|
342
|
+
if (future) {
|
|
343
|
+
symbol = symbol + '-' + this.yymmdd(expiry);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
result.push({
|
|
347
|
+
'id': id,
|
|
348
|
+
'symbol': symbol,
|
|
349
|
+
'base': base,
|
|
350
|
+
'quote': quote,
|
|
351
|
+
'settle': settle,
|
|
352
|
+
'baseId': baseId,
|
|
353
|
+
'quoteId': quoteId,
|
|
354
|
+
'settleId': settleId,
|
|
355
|
+
'type': type,
|
|
356
|
+
'spot': false,
|
|
357
|
+
'margin': false,
|
|
358
|
+
'swap': swap,
|
|
359
|
+
'future': future,
|
|
360
|
+
'option': false,
|
|
361
|
+
'index': index,
|
|
362
|
+
'active': undefined,
|
|
363
|
+
'contract': contract,
|
|
364
|
+
'linear': linear,
|
|
365
|
+
'inverse': inverse,
|
|
366
|
+
'contractSize': this.safeNumber(market, 'contractSize'),
|
|
367
|
+
'maintenanceMarginRate': undefined,
|
|
368
|
+
'expiry': expiry,
|
|
369
|
+
'expiryDatetime': this.iso8601(expiry),
|
|
370
|
+
'strike': undefined,
|
|
371
|
+
'optionType': undefined,
|
|
372
|
+
'precision': {
|
|
373
|
+
'amount': amountPrecision,
|
|
374
|
+
'price': pricePrecision,
|
|
375
|
+
},
|
|
376
|
+
'limits': {
|
|
377
|
+
'leverage': {
|
|
378
|
+
'min': undefined,
|
|
379
|
+
'max': undefined,
|
|
380
|
+
},
|
|
381
|
+
'amount': {
|
|
382
|
+
'min': undefined,
|
|
383
|
+
'max': undefined,
|
|
384
|
+
},
|
|
385
|
+
'price': {
|
|
386
|
+
'min': undefined,
|
|
387
|
+
'max': undefined,
|
|
388
|
+
},
|
|
389
|
+
'cost': {
|
|
390
|
+
'min': undefined,
|
|
391
|
+
'max': undefined,
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
'created': this.parse8601(this.safeString(market, 'openingDate')),
|
|
395
|
+
'info': market,
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
const settlementCurrencies = this.options['settlementCurrencies']['flex'];
|
|
399
|
+
const currencies = [];
|
|
400
|
+
for (let i = 0; i < settlementCurrencies.length; i++) {
|
|
401
|
+
const code = settlementCurrencies[i];
|
|
402
|
+
currencies.push({
|
|
403
|
+
'id': code.toLowerCase(),
|
|
404
|
+
'numericId': undefined,
|
|
405
|
+
'code': code,
|
|
406
|
+
'precision': undefined,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
this.currencies = this.deepExtend(currencies, this.currencies);
|
|
410
|
+
return result;
|
|
411
|
+
}
|
|
412
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
413
|
+
/**
|
|
414
|
+
* @method
|
|
415
|
+
* @name krakenfutures#fetchOrderBook
|
|
416
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-orderbook
|
|
417
|
+
* @description Fetches a list of open orders in a market
|
|
418
|
+
* @param {string} symbol Unified market symbol
|
|
419
|
+
* @param {int} [limit] Not used by krakenfutures
|
|
420
|
+
* @param {object} [params] exchange specific params
|
|
421
|
+
* @returns An [order book structure]{@link https://docs.ccxt.com/#/?id=order-book-structure}
|
|
422
|
+
*/
|
|
423
|
+
await this.loadMarkets();
|
|
424
|
+
const market = this.market(symbol);
|
|
425
|
+
const request = {
|
|
426
|
+
'symbol': market['id'],
|
|
427
|
+
};
|
|
428
|
+
const response = await this.publicGetOrderbook(this.extend(request, params));
|
|
429
|
+
//
|
|
430
|
+
// {
|
|
431
|
+
// "result": "success",
|
|
432
|
+
// "serverTime": "2016-02-25T09:45:53.818Z",
|
|
433
|
+
// "orderBook": {
|
|
434
|
+
// "bids": [
|
|
435
|
+
// [
|
|
436
|
+
// 4213,
|
|
437
|
+
// 2000,
|
|
438
|
+
// ],
|
|
439
|
+
// [
|
|
440
|
+
// 4210,
|
|
441
|
+
// 4000,
|
|
442
|
+
// ],
|
|
443
|
+
// ...
|
|
444
|
+
// ],
|
|
445
|
+
// "asks": [
|
|
446
|
+
// [
|
|
447
|
+
// 4218,
|
|
448
|
+
// 4000,
|
|
449
|
+
// ],
|
|
450
|
+
// [
|
|
451
|
+
// 4220,
|
|
452
|
+
// 5000,
|
|
453
|
+
// ],
|
|
454
|
+
// ...
|
|
455
|
+
// ],
|
|
456
|
+
// },
|
|
457
|
+
// }
|
|
458
|
+
//
|
|
459
|
+
const timestamp = this.parse8601(response['serverTime']);
|
|
460
|
+
return this.parseOrderBook(response['orderBook'], symbol, timestamp);
|
|
461
|
+
}
|
|
462
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
463
|
+
/**
|
|
464
|
+
* @method
|
|
465
|
+
* @name krakenfutures#fetchTickers
|
|
466
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
467
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-tickers
|
|
468
|
+
* @param {string[]} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
469
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
470
|
+
* @returns {object} an array of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
471
|
+
*/
|
|
472
|
+
await this.loadMarkets();
|
|
473
|
+
const response = await this.publicGetTickers(params);
|
|
474
|
+
//
|
|
475
|
+
// {
|
|
476
|
+
// "result": "success",
|
|
477
|
+
// "tickers": [
|
|
478
|
+
// {
|
|
479
|
+
// "tag": 'semiannual', // 'month', 'quarter', "perpetual", "semiannual",
|
|
480
|
+
// "pair": "ETH:USD",
|
|
481
|
+
// "symbol": "fi_ethusd_220624",
|
|
482
|
+
// "markPrice": "2925.72",
|
|
483
|
+
// "bid": "2923.8",
|
|
484
|
+
// "bidSize": "16804",
|
|
485
|
+
// "ask": "2928.65",
|
|
486
|
+
// "askSize": "1339",
|
|
487
|
+
// "vol24h": "860493",
|
|
488
|
+
// "openInterest": "3023363.00000000",
|
|
489
|
+
// "open24h": "3021.25",
|
|
490
|
+
// "indexPrice": "2893.71",
|
|
491
|
+
// "last": "2942.25",
|
|
492
|
+
// "lastTime": "2022-02-18T14:08:15.578Z",
|
|
493
|
+
// "lastSize": "151",
|
|
494
|
+
// "suspended": false
|
|
495
|
+
// },
|
|
496
|
+
// {
|
|
497
|
+
// "symbol": "in_xbtusd", // "rr_xbtusd",
|
|
498
|
+
// "last": "40411",
|
|
499
|
+
// "lastTime": "2022-02-18T14:16:28.000Z"
|
|
500
|
+
// },
|
|
501
|
+
// ...
|
|
502
|
+
// ],
|
|
503
|
+
// "serverTime": "2022-02-18T14:16:29.440Z"
|
|
504
|
+
// }
|
|
505
|
+
//
|
|
506
|
+
const tickers = this.safeValue(response, 'tickers');
|
|
507
|
+
return this.parseTickers(tickers, symbols);
|
|
508
|
+
}
|
|
509
|
+
parseTicker(ticker, market = undefined) {
|
|
510
|
+
//
|
|
511
|
+
// {
|
|
512
|
+
// "tag": 'semiannual', // 'month', 'quarter', "perpetual", "semiannual",
|
|
513
|
+
// "pair": "ETH:USD",
|
|
514
|
+
// "symbol": "fi_ethusd_220624",
|
|
515
|
+
// "markPrice": "2925.72",
|
|
516
|
+
// "bid": "2923.8",
|
|
517
|
+
// "bidSize": "16804",
|
|
518
|
+
// "ask": "2928.65",
|
|
519
|
+
// "askSize": "1339",
|
|
520
|
+
// "vol24h": "860493",
|
|
521
|
+
// "openInterest": "3023363.00000000",
|
|
522
|
+
// "open24h": "3021.25",
|
|
523
|
+
// "indexPrice": "2893.71",
|
|
524
|
+
// "last": "2942.25",
|
|
525
|
+
// "lastTime": "2022-02-18T14:08:15.578Z",
|
|
526
|
+
// "lastSize": "151",
|
|
527
|
+
// "suspended": false
|
|
528
|
+
// }
|
|
529
|
+
//
|
|
530
|
+
// {
|
|
531
|
+
// "symbol": "in_xbtusd", // "rr_xbtusd",
|
|
532
|
+
// "last": "40411",
|
|
533
|
+
// "lastTime": "2022-02-18T14:16:28.000Z"
|
|
534
|
+
// }
|
|
535
|
+
//
|
|
536
|
+
const marketId = this.safeString(ticker, 'symbol');
|
|
537
|
+
market = this.safeMarket(marketId, market);
|
|
538
|
+
const symbol = market['symbol'];
|
|
539
|
+
const timestamp = this.parse8601(this.safeString(ticker, 'lastTime'));
|
|
540
|
+
const open = this.safeString(ticker, 'open24h');
|
|
541
|
+
const last = this.safeString(ticker, 'last');
|
|
542
|
+
const change = Precise["default"].stringSub(last, open);
|
|
543
|
+
const percentage = Precise["default"].stringMul(Precise["default"].stringDiv(change, open), '100');
|
|
544
|
+
const average = Precise["default"].stringDiv(Precise["default"].stringAdd(open, last), '2');
|
|
545
|
+
const volume = this.safeString(ticker, 'vol24h');
|
|
546
|
+
let baseVolume = undefined;
|
|
547
|
+
let quoteVolume = undefined;
|
|
548
|
+
const isIndex = this.safeValue(market, 'index', false);
|
|
549
|
+
if (!isIndex) {
|
|
550
|
+
if (market['linear']) {
|
|
551
|
+
baseVolume = volume;
|
|
552
|
+
}
|
|
553
|
+
else if (market['inverse']) {
|
|
554
|
+
quoteVolume = volume;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return this.safeTicker({
|
|
558
|
+
'symbol': symbol,
|
|
559
|
+
'timestamp': timestamp,
|
|
560
|
+
'datetime': this.iso8601(timestamp),
|
|
561
|
+
'high': undefined,
|
|
562
|
+
'low': undefined,
|
|
563
|
+
'bid': this.safeString(ticker, 'bid'),
|
|
564
|
+
'bidVolume': this.safeString(ticker, 'bidSize'),
|
|
565
|
+
'ask': this.safeString(ticker, 'ask'),
|
|
566
|
+
'askVolume': this.safeString(ticker, 'askSize'),
|
|
567
|
+
'vwap': undefined,
|
|
568
|
+
'open': open,
|
|
569
|
+
'close': last,
|
|
570
|
+
'last': last,
|
|
571
|
+
'previousClose': undefined,
|
|
572
|
+
'change': change,
|
|
573
|
+
'percentage': percentage,
|
|
574
|
+
'average': average,
|
|
575
|
+
'baseVolume': baseVolume,
|
|
576
|
+
'quoteVolume': quoteVolume,
|
|
577
|
+
'info': ticker,
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
581
|
+
/**
|
|
582
|
+
* @method
|
|
583
|
+
* @name kraken#fetchOHLCV
|
|
584
|
+
* @see https://docs.futures.kraken.com/#http-api-charts-candles
|
|
585
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
586
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
587
|
+
* @param {string} timeframe the length of time each candle represents
|
|
588
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
589
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
590
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
591
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
592
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
593
|
+
*/
|
|
594
|
+
await this.loadMarkets();
|
|
595
|
+
const market = this.market(symbol);
|
|
596
|
+
let paginate = false;
|
|
597
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
|
|
598
|
+
if (paginate) {
|
|
599
|
+
return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 5000);
|
|
600
|
+
}
|
|
601
|
+
const request = {
|
|
602
|
+
'symbol': market['id'],
|
|
603
|
+
'price_type': this.safeString(params, 'price', 'trade'),
|
|
604
|
+
'interval': this.timeframes[timeframe],
|
|
605
|
+
};
|
|
606
|
+
params = this.omit(params, 'price');
|
|
607
|
+
if (since !== undefined) {
|
|
608
|
+
const duration = this.parseTimeframe(timeframe);
|
|
609
|
+
request['from'] = this.parseToInt(since / 1000);
|
|
610
|
+
if (limit === undefined) {
|
|
611
|
+
limit = 5000;
|
|
612
|
+
}
|
|
613
|
+
else if (limit > 5000) {
|
|
614
|
+
throw new errors.BadRequest(this.id + ' fetchOHLCV() limit cannot exceed 5000');
|
|
615
|
+
}
|
|
616
|
+
const toTimestamp = this.sum(request['from'], limit * duration - 1);
|
|
617
|
+
const currentTimestamp = this.seconds();
|
|
618
|
+
request['to'] = Math.min(toTimestamp, currentTimestamp);
|
|
619
|
+
}
|
|
620
|
+
else if (limit !== undefined) {
|
|
621
|
+
if (limit > 5000) {
|
|
622
|
+
throw new errors.BadRequest(this.id + ' fetchOHLCV() limit cannot exceed 5000');
|
|
623
|
+
}
|
|
624
|
+
const duration = this.parseTimeframe(timeframe);
|
|
625
|
+
request['to'] = this.seconds();
|
|
626
|
+
request['from'] = this.parseToInt(request['to'] - (duration * limit));
|
|
627
|
+
}
|
|
628
|
+
const response = await this.chartsGetPriceTypeSymbolInterval(this.extend(request, params));
|
|
629
|
+
//
|
|
630
|
+
// {
|
|
631
|
+
// "candles": [
|
|
632
|
+
// {
|
|
633
|
+
// "time": 1645198500000,
|
|
634
|
+
// "open": "309.15000000000",
|
|
635
|
+
// "high": "309.15000000000",
|
|
636
|
+
// "low": "308.70000000000",
|
|
637
|
+
// "close": "308.85000000000",
|
|
638
|
+
// "volume": 0
|
|
639
|
+
// }
|
|
640
|
+
// ],
|
|
641
|
+
// "more_candles": true
|
|
642
|
+
// }
|
|
643
|
+
//
|
|
644
|
+
const candles = this.safeValue(response, 'candles');
|
|
645
|
+
return this.parseOHLCVs(candles, market, timeframe, since, limit);
|
|
646
|
+
}
|
|
647
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
648
|
+
//
|
|
649
|
+
// {
|
|
650
|
+
// "time": 1645198500000,
|
|
651
|
+
// "open": "309.15000000000",
|
|
652
|
+
// "high": "309.15000000000",
|
|
653
|
+
// "low": "308.70000000000",
|
|
654
|
+
// "close": "308.85000000000",
|
|
655
|
+
// "volume": 0
|
|
656
|
+
// }
|
|
657
|
+
//
|
|
658
|
+
return [
|
|
659
|
+
this.safeInteger(ohlcv, 'time'),
|
|
660
|
+
this.safeNumber(ohlcv, 'open'),
|
|
661
|
+
this.safeNumber(ohlcv, 'high'),
|
|
662
|
+
this.safeNumber(ohlcv, 'low'),
|
|
663
|
+
this.safeNumber(ohlcv, 'close'),
|
|
664
|
+
this.safeNumber(ohlcv, 'volume'), // trading volume, undefined for mark or index price
|
|
665
|
+
];
|
|
666
|
+
}
|
|
667
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
668
|
+
/**
|
|
669
|
+
* @method
|
|
670
|
+
* @name krakenfutures#fetchTrades
|
|
671
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-trade-history
|
|
672
|
+
* @description Fetch a history of filled trades that this account has made
|
|
673
|
+
* @param {string} symbol Unified CCXT market symbol
|
|
674
|
+
* @param {int} [since] Timestamp in ms of earliest trade. Not used by krakenfutures except in combination with params.until
|
|
675
|
+
* @param {int} [limit] Total number of trades, cannot exceed 100
|
|
676
|
+
* @param {object} [params] Exchange specific params
|
|
677
|
+
* @param {int} [params.until] Timestamp in ms of latest trade
|
|
678
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
679
|
+
* @returns An array of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
680
|
+
*/
|
|
681
|
+
await this.loadMarkets();
|
|
682
|
+
let paginate = false;
|
|
683
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchTrades', 'paginate');
|
|
684
|
+
if (paginate) {
|
|
685
|
+
return await this.fetchPaginatedCallDynamic('fetchTrades', symbol, since, limit, params);
|
|
686
|
+
}
|
|
687
|
+
const market = this.market(symbol);
|
|
688
|
+
const request = {
|
|
689
|
+
'symbol': market['id'],
|
|
690
|
+
};
|
|
691
|
+
const until = this.safeInteger(params, 'until');
|
|
692
|
+
if (until !== undefined) {
|
|
693
|
+
request['lastTime'] = this.iso8601(until);
|
|
694
|
+
}
|
|
695
|
+
//
|
|
696
|
+
// {
|
|
697
|
+
// "result": "success",
|
|
698
|
+
// "history": [
|
|
699
|
+
// {
|
|
700
|
+
// "time": "2022-03-18T04:55:37.692Z",
|
|
701
|
+
// "trade_id": 100,
|
|
702
|
+
// "price": 0.7921,
|
|
703
|
+
// "size": 1068,
|
|
704
|
+
// "side": "sell",
|
|
705
|
+
// "type": "fill",
|
|
706
|
+
// "uid": "6c5da0b0-f1a8-483f-921f-466eb0388265"
|
|
707
|
+
// },
|
|
708
|
+
// ...
|
|
709
|
+
// ],
|
|
710
|
+
// "serverTime": "2022-03-18T06:39:18.056Z"
|
|
711
|
+
// }
|
|
712
|
+
//
|
|
713
|
+
const response = await this.publicGetHistory(this.extend(request, params));
|
|
714
|
+
const history = this.safeValue(response, 'history');
|
|
715
|
+
return this.parseTrades(history, market, since, limit);
|
|
716
|
+
}
|
|
717
|
+
parseTrade(trade, market = undefined) {
|
|
718
|
+
//
|
|
719
|
+
// fetchTrades (public)
|
|
720
|
+
//
|
|
721
|
+
// {
|
|
722
|
+
// "time": "2019-02-14T09:25:33.920Z",
|
|
723
|
+
// "trade_id": 100,
|
|
724
|
+
// "price": 3574,
|
|
725
|
+
// "size": 100,
|
|
726
|
+
// "side": "buy",
|
|
727
|
+
// "type": "fill" // fill, liquidation, assignment, termination
|
|
728
|
+
// "uid": "11c3d82c-9e70-4fe9-8115-f643f1b162d4"
|
|
729
|
+
// }
|
|
730
|
+
//
|
|
731
|
+
// fetchMyTrades (private)
|
|
732
|
+
//
|
|
733
|
+
// {
|
|
734
|
+
// "fillTime": "2016-02-25T09:47:01.000Z",
|
|
735
|
+
// "order_id": "c18f0c17-9971-40e6-8e5b-10df05d422f0",
|
|
736
|
+
// "fill_id": "522d4e08-96e7-4b44-9694-bfaea8fe215e",
|
|
737
|
+
// "cliOrdId": "d427f920-ec55-4c18-ba95-5fe241513b30", // OPTIONAL
|
|
738
|
+
// "symbol": "fi_xbtusd_180615",
|
|
739
|
+
// "side": "buy",
|
|
740
|
+
// "size": 2000,
|
|
741
|
+
// "price": 4255,
|
|
742
|
+
// "fillType": "maker" // taker, takerAfterEdit, maker, liquidation, assignee
|
|
743
|
+
// }
|
|
744
|
+
//
|
|
745
|
+
// execution report (createOrder, editOrder)
|
|
746
|
+
//
|
|
747
|
+
// {
|
|
748
|
+
// "executionId": "e1ec9f63-2338-4c44-b40a-43486c6732d7",
|
|
749
|
+
// "price": 7244.5,
|
|
750
|
+
// "amount": 10,
|
|
751
|
+
// "orderPriorEdit": null,
|
|
752
|
+
// "orderPriorExecution": {
|
|
753
|
+
// "orderId": "61ca5732-3478-42fe-8362-abbfd9465294",
|
|
754
|
+
// "cliOrdId": null,
|
|
755
|
+
// "type": "lmt",
|
|
756
|
+
// "symbol": "pi_xbtusd",
|
|
757
|
+
// "side": "buy",
|
|
758
|
+
// "quantity": 10,
|
|
759
|
+
// "filled": 0,
|
|
760
|
+
// "limitPrice": 7500,
|
|
761
|
+
// "reduceOnly": false,
|
|
762
|
+
// "timestamp": "2019-12-11T17:17:33.888Z",
|
|
763
|
+
// "lastUpdateTimestamp": "2019-12-11T17:17:33.888Z"
|
|
764
|
+
// },
|
|
765
|
+
// "takerReducedQuantity": null,
|
|
766
|
+
// "type": "EXECUTION"
|
|
767
|
+
// }
|
|
768
|
+
//
|
|
769
|
+
const timestamp = this.parse8601(this.safeString2(trade, 'time', 'fillTime'));
|
|
770
|
+
const price = this.safeString(trade, 'price');
|
|
771
|
+
const amount = this.safeString2(trade, 'size', 'amount', '0.0');
|
|
772
|
+
let id = this.safeString2(trade, 'uid', 'fill_id');
|
|
773
|
+
if (id === undefined) {
|
|
774
|
+
id = this.safeString(trade, 'executionId');
|
|
775
|
+
}
|
|
776
|
+
let order = this.safeString(trade, 'order_id');
|
|
777
|
+
let symbolId = this.safeString(trade, 'symbol');
|
|
778
|
+
let side = this.safeString(trade, 'side');
|
|
779
|
+
let type = undefined;
|
|
780
|
+
const priorEdit = this.safeValue(trade, 'orderPriorEdit');
|
|
781
|
+
const priorExecution = this.safeValue(trade, 'orderPriorExecution');
|
|
782
|
+
if (priorExecution !== undefined) {
|
|
783
|
+
order = this.safeString(priorExecution, 'orderId');
|
|
784
|
+
symbolId = this.safeString(priorExecution, 'symbol');
|
|
785
|
+
side = this.safeString(priorExecution, 'side');
|
|
786
|
+
type = this.safeString(priorExecution, 'type');
|
|
787
|
+
}
|
|
788
|
+
else if (priorEdit !== undefined) {
|
|
789
|
+
order = this.safeString(priorEdit, 'orderId');
|
|
790
|
+
symbolId = this.safeString(priorEdit, 'symbol');
|
|
791
|
+
side = this.safeString(priorEdit, 'type');
|
|
792
|
+
type = this.safeString(priorEdit, 'type');
|
|
793
|
+
}
|
|
794
|
+
if (type !== undefined) {
|
|
795
|
+
type = this.parseOrderType(type);
|
|
796
|
+
}
|
|
797
|
+
let symbol = undefined;
|
|
798
|
+
if (symbolId !== undefined) {
|
|
799
|
+
market = this.safeValue(this.markets_by_id, symbolId);
|
|
800
|
+
if (market === undefined) {
|
|
801
|
+
symbol = symbolId;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
symbol = this.safeString(market, 'symbol', symbol);
|
|
805
|
+
let cost = undefined;
|
|
806
|
+
if ((amount !== undefined) && (price !== undefined) && (market !== undefined)) {
|
|
807
|
+
const linear = this.safeValue(market, 'linear');
|
|
808
|
+
if (linear) {
|
|
809
|
+
cost = Precise["default"].stringMul(amount, price); // in quote
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
cost = Precise["default"].stringDiv(amount, price); // in base
|
|
813
|
+
}
|
|
814
|
+
const contractSize = this.safeString(market, 'contractSize');
|
|
815
|
+
cost = Precise["default"].stringMul(cost, contractSize);
|
|
816
|
+
}
|
|
817
|
+
let takerOrMaker = undefined;
|
|
818
|
+
const fillType = this.safeString(trade, 'fillType');
|
|
819
|
+
if (fillType !== undefined) {
|
|
820
|
+
if (fillType.indexOf('taker') >= 0) {
|
|
821
|
+
takerOrMaker = 'taker';
|
|
822
|
+
}
|
|
823
|
+
else if (fillType.indexOf('maker') >= 0) {
|
|
824
|
+
takerOrMaker = 'maker';
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return this.safeTrade({
|
|
828
|
+
'info': trade,
|
|
829
|
+
'id': id,
|
|
830
|
+
'timestamp': timestamp,
|
|
831
|
+
'datetime': this.iso8601(timestamp),
|
|
832
|
+
'symbol': symbol,
|
|
833
|
+
'order': order,
|
|
834
|
+
'type': type,
|
|
835
|
+
'side': side,
|
|
836
|
+
'takerOrMaker': takerOrMaker,
|
|
837
|
+
'price': price,
|
|
838
|
+
'amount': amount,
|
|
839
|
+
'cost': cost,
|
|
840
|
+
'fee': undefined,
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
844
|
+
const market = this.market(symbol);
|
|
845
|
+
type = this.safeString(params, 'orderType', type);
|
|
846
|
+
const timeInForce = this.safeString(params, 'timeInForce');
|
|
847
|
+
let postOnly = false;
|
|
848
|
+
[postOnly, params] = this.handlePostOnly(type === 'market', type === 'post', params);
|
|
849
|
+
if (postOnly) {
|
|
850
|
+
type = 'post';
|
|
851
|
+
}
|
|
852
|
+
else if (timeInForce === 'ioc') {
|
|
853
|
+
type = 'ioc';
|
|
854
|
+
}
|
|
855
|
+
else if (type === 'limit') {
|
|
856
|
+
type = 'lmt';
|
|
857
|
+
}
|
|
858
|
+
else if (type === 'market') {
|
|
859
|
+
type = 'mkt';
|
|
860
|
+
}
|
|
861
|
+
const request = {
|
|
862
|
+
'symbol': market['id'],
|
|
863
|
+
'side': side,
|
|
864
|
+
'size': amount,
|
|
865
|
+
};
|
|
866
|
+
const clientOrderId = this.safeString2(params, 'clientOrderId', 'cliOrdId');
|
|
867
|
+
if (clientOrderId !== undefined) {
|
|
868
|
+
request['cliOrdId'] = clientOrderId;
|
|
869
|
+
}
|
|
870
|
+
const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
871
|
+
const isTriggerOrder = triggerPrice !== undefined;
|
|
872
|
+
const stopLossTriggerPrice = this.safeString(params, 'stopLossPrice');
|
|
873
|
+
const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
|
|
874
|
+
const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
|
|
875
|
+
const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
|
|
876
|
+
const isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder || isTakeProfitTriggerOrder;
|
|
877
|
+
const triggerSignal = this.safeString(params, 'triggerSignal', 'last');
|
|
878
|
+
let reduceOnly = this.safeValue(params, 'reduceOnly');
|
|
879
|
+
if (isStopLossOrTakeProfitTrigger || isTriggerOrder) {
|
|
880
|
+
request['triggerSignal'] = triggerSignal;
|
|
881
|
+
}
|
|
882
|
+
if (isTriggerOrder) {
|
|
883
|
+
type = 'stp';
|
|
884
|
+
request['stopPrice'] = this.priceToPrecision(symbol, triggerPrice);
|
|
885
|
+
}
|
|
886
|
+
else if (isStopLossOrTakeProfitTrigger) {
|
|
887
|
+
reduceOnly = true;
|
|
888
|
+
if (isStopLossTriggerOrder) {
|
|
889
|
+
type = 'stp';
|
|
890
|
+
request['stopPrice'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
|
|
891
|
+
}
|
|
892
|
+
else if (isTakeProfitTriggerOrder) {
|
|
893
|
+
type = 'take_profit';
|
|
894
|
+
request['stopPrice'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
if (reduceOnly) {
|
|
898
|
+
request['reduceOnly'] = true;
|
|
899
|
+
}
|
|
900
|
+
request['orderType'] = type;
|
|
901
|
+
if (price !== undefined) {
|
|
902
|
+
request['limitPrice'] = price;
|
|
903
|
+
}
|
|
904
|
+
params = this.omit(params, ['clientOrderId', 'timeInForce', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
|
|
905
|
+
return this.extend(request, params);
|
|
906
|
+
}
|
|
907
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
908
|
+
/**
|
|
909
|
+
* @method
|
|
910
|
+
* @name krakenfutures#createOrder
|
|
911
|
+
* @description Create an order on the exchange
|
|
912
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-send-order
|
|
913
|
+
* @param {string} symbol unified market symbol
|
|
914
|
+
* @param {string} type 'limit' or 'market'
|
|
915
|
+
* @param {string} side 'buy' or 'sell'
|
|
916
|
+
* @param {float} amount number of contracts
|
|
917
|
+
* @param {float} [price] limit order price
|
|
918
|
+
* @param {bool} [params.reduceOnly] set as true if you wish the order to only reduce an existing position, any order which increases an existing position will be rejected, default is false
|
|
919
|
+
* @param {bool} [params.postOnly] set as true if you wish to make a postOnly order, default is false
|
|
920
|
+
* @param {string} [params.clientOrderId] UUID The order identity that is specified from the user, It must be globally unique
|
|
921
|
+
* @param {float} [params.triggerPrice] the price that a stop order is triggered at
|
|
922
|
+
* @param {float} [params.stopLossPrice] the price that a stop loss order is triggered at
|
|
923
|
+
* @param {float} [params.takeProfitPrice] the price that a take profit order is triggered at
|
|
924
|
+
* @param {string} [params.triggerSignal] for triggerPrice, stopLossPrice and takeProfitPrice orders, the trigger price type, 'last', 'mark' or 'index', default is 'last'
|
|
925
|
+
*/
|
|
926
|
+
await this.loadMarkets();
|
|
927
|
+
const market = this.market(symbol);
|
|
928
|
+
const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
929
|
+
const response = await this.privatePostSendorder(orderRequest);
|
|
930
|
+
//
|
|
931
|
+
// {
|
|
932
|
+
// "result": "success",
|
|
933
|
+
// "sendStatus": {
|
|
934
|
+
// "order_id": "salf320-e337-47ac-b345-30sdfsalj",
|
|
935
|
+
// "status": "placed",
|
|
936
|
+
// "receivedTime": "2022-02-28T19:32:17.122Z",
|
|
937
|
+
// "orderEvents": [
|
|
938
|
+
// {
|
|
939
|
+
// "order": {
|
|
940
|
+
// "orderId": "salf320-e337-47ac-b345-30sdfsalj",
|
|
941
|
+
// "cliOrdId": null,
|
|
942
|
+
// "type": "lmt",
|
|
943
|
+
// "symbol": "pi_xrpusd",
|
|
944
|
+
// "side": "buy",
|
|
945
|
+
// "quantity": 1,
|
|
946
|
+
// "filled": 0,
|
|
947
|
+
// "limitPrice": 0.7,
|
|
948
|
+
// "reduceOnly": false,
|
|
949
|
+
// "timestamp": "2022-02-28T19:32:17.122Z",
|
|
950
|
+
// "lastUpdateTimestamp": "2022-02-28T19:32:17.122Z"
|
|
951
|
+
// },
|
|
952
|
+
// "reducedQuantity": null,
|
|
953
|
+
// "type": "PLACE"
|
|
954
|
+
// }
|
|
955
|
+
// ]
|
|
956
|
+
// },
|
|
957
|
+
// "serverTime": "2022-02-28T19:32:17.122Z"
|
|
958
|
+
// }
|
|
959
|
+
//
|
|
960
|
+
const sendStatus = this.safeValue(response, 'sendStatus');
|
|
961
|
+
const status = this.safeString(sendStatus, 'status');
|
|
962
|
+
this.verifyOrderActionSuccess(status, 'createOrder', ['filled']);
|
|
963
|
+
return this.parseOrder(sendStatus, market);
|
|
964
|
+
}
|
|
965
|
+
async createOrders(orders, params = {}) {
|
|
966
|
+
/**
|
|
967
|
+
* @method
|
|
968
|
+
* @name krakenfutures#createOrders
|
|
969
|
+
* @description create a list of trade orders
|
|
970
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-batch-order-management
|
|
971
|
+
* @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
|
972
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
973
|
+
*/
|
|
974
|
+
await this.loadMarkets();
|
|
975
|
+
const ordersRequests = [];
|
|
976
|
+
for (let i = 0; i < orders.length; i++) {
|
|
977
|
+
const rawOrder = orders[i];
|
|
978
|
+
const marketId = this.safeString(rawOrder, 'symbol');
|
|
979
|
+
const type = this.safeString(rawOrder, 'type');
|
|
980
|
+
const side = this.safeString(rawOrder, 'side');
|
|
981
|
+
const amount = this.safeValue(rawOrder, 'amount');
|
|
982
|
+
const price = this.safeValue(rawOrder, 'price');
|
|
983
|
+
const orderParams = this.safeValue(rawOrder, 'params', {});
|
|
984
|
+
const extendedParams = this.extend(orderParams, params); // the request does not accept extra params since it's a list, so we're extending each order with the common params
|
|
985
|
+
if (!('order_tag' in extendedParams)) {
|
|
986
|
+
// order tag is mandatory so we will generate one if not provided
|
|
987
|
+
extendedParams['order_tag'] = this.sum(i, 1).toString(); // sequential counter
|
|
988
|
+
}
|
|
989
|
+
extendedParams['order'] = 'send';
|
|
990
|
+
const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, extendedParams);
|
|
991
|
+
ordersRequests.push(orderRequest);
|
|
992
|
+
}
|
|
993
|
+
const request = {
|
|
994
|
+
'batchOrder': ordersRequests,
|
|
995
|
+
};
|
|
996
|
+
const response = await this.privatePostBatchorder(this.extend(request, params));
|
|
997
|
+
//
|
|
998
|
+
// {
|
|
999
|
+
// "result": "success",
|
|
1000
|
+
// "serverTime": "2023-10-24T08:40:57.339Z",
|
|
1001
|
+
// "batchStatus": [
|
|
1002
|
+
// {
|
|
1003
|
+
// "status": "requiredArgumentMissing",
|
|
1004
|
+
// "orderEvents": []
|
|
1005
|
+
// },
|
|
1006
|
+
// {
|
|
1007
|
+
// "status": "requiredArgumentMissing",
|
|
1008
|
+
// "orderEvents": []
|
|
1009
|
+
// }
|
|
1010
|
+
// ]
|
|
1011
|
+
// }
|
|
1012
|
+
//
|
|
1013
|
+
const data = this.safeValue(response, 'batchStatus', []);
|
|
1014
|
+
return this.parseOrders(data);
|
|
1015
|
+
}
|
|
1016
|
+
async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
1017
|
+
/**
|
|
1018
|
+
* @method
|
|
1019
|
+
* @name krakenfutures#editOrder
|
|
1020
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-edit-order
|
|
1021
|
+
* @description Edit an open order on the exchange
|
|
1022
|
+
* @param {string} id order id
|
|
1023
|
+
* @param {string} symbol Not used by Krakenfutures
|
|
1024
|
+
* @param {string} type Not used by Krakenfutures
|
|
1025
|
+
* @param {string} side Not used by Krakenfutures
|
|
1026
|
+
* @param {float} amount Order size
|
|
1027
|
+
* @param {float} [price] Price to fill order at
|
|
1028
|
+
* @param {object} [params] Exchange specific params
|
|
1029
|
+
* @returns An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1030
|
+
*/
|
|
1031
|
+
await this.loadMarkets();
|
|
1032
|
+
const request = {
|
|
1033
|
+
'orderId': id,
|
|
1034
|
+
};
|
|
1035
|
+
if (amount !== undefined) {
|
|
1036
|
+
request['size'] = amount;
|
|
1037
|
+
}
|
|
1038
|
+
if (price !== undefined) {
|
|
1039
|
+
request['limitPrice'] = price;
|
|
1040
|
+
}
|
|
1041
|
+
const response = await this.privatePostEditorder(this.extend(request, params));
|
|
1042
|
+
const status = this.safeString(response['editStatus'], 'status');
|
|
1043
|
+
this.verifyOrderActionSuccess(status, 'editOrder', ['filled']);
|
|
1044
|
+
const order = this.parseOrder(response['editStatus']);
|
|
1045
|
+
order['info'] = response;
|
|
1046
|
+
return order;
|
|
1047
|
+
}
|
|
1048
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1049
|
+
/**
|
|
1050
|
+
* @method
|
|
1051
|
+
* @name krakenfutures#cancelOrder
|
|
1052
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-cancel-order
|
|
1053
|
+
* @description Cancel an open order on the exchange
|
|
1054
|
+
* @param {string} id Order id
|
|
1055
|
+
* @param {string} symbol Not used by Krakenfutures
|
|
1056
|
+
* @param {object} [params] Exchange specific params
|
|
1057
|
+
* @returns An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1058
|
+
*/
|
|
1059
|
+
await this.loadMarkets();
|
|
1060
|
+
const response = await this.privatePostCancelorder(this.extend({ 'order_id': id }, params));
|
|
1061
|
+
const status = this.safeString(this.safeValue(response, 'cancelStatus', {}), 'status');
|
|
1062
|
+
this.verifyOrderActionSuccess(status, 'cancelOrder');
|
|
1063
|
+
let order = {};
|
|
1064
|
+
if ('cancelStatus' in response) {
|
|
1065
|
+
order = this.parseOrder(response['cancelStatus']);
|
|
1066
|
+
}
|
|
1067
|
+
return this.extend({ 'info': response }, order);
|
|
1068
|
+
}
|
|
1069
|
+
async cancelOrders(ids, symbol = undefined, params = {}) {
|
|
1070
|
+
/**
|
|
1071
|
+
* @method
|
|
1072
|
+
* @name krakenfutures#cancelOrders
|
|
1073
|
+
* @description cancel multiple orders
|
|
1074
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-batch-order-management
|
|
1075
|
+
* @param {string[]} ids order ids
|
|
1076
|
+
* @param {string} [symbol] unified market symbol
|
|
1077
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1078
|
+
*
|
|
1079
|
+
* EXCHANGE SPECIFIC PARAMETERS
|
|
1080
|
+
* @param {string[]} [params.clientOrderIds] max length 10 e.g. ["my_id_1","my_id_2"]
|
|
1081
|
+
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1082
|
+
*/
|
|
1083
|
+
await this.loadMarkets();
|
|
1084
|
+
const orders = [];
|
|
1085
|
+
const clientOrderIds = this.safeValue(params, 'clientOrderIds', []);
|
|
1086
|
+
const clientOrderIdsLength = clientOrderIds.length;
|
|
1087
|
+
if (clientOrderIdsLength > 0) {
|
|
1088
|
+
for (let i = 0; i < clientOrderIds.length; i++) {
|
|
1089
|
+
orders.push({ 'order': 'cancel', 'cliOrdId': clientOrderIds[i] });
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
else {
|
|
1093
|
+
for (let i = 0; i < ids.length; i++) {
|
|
1094
|
+
orders.push({ 'order': 'cancel', 'order_id': ids[i] });
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
const request = {
|
|
1098
|
+
'batchOrder': orders,
|
|
1099
|
+
};
|
|
1100
|
+
const response = await this.privatePostBatchorder(this.extend(request, params));
|
|
1101
|
+
// {
|
|
1102
|
+
// "result": "success",
|
|
1103
|
+
// "serverTime": "2023-10-23T16:36:51.327Z",
|
|
1104
|
+
// "batchStatus": [
|
|
1105
|
+
// {
|
|
1106
|
+
// "status": "cancelled",
|
|
1107
|
+
// "order_id": "101c2327-f12e-45f2-8445-7502b87afc0b",
|
|
1108
|
+
// "orderEvents": [
|
|
1109
|
+
// {
|
|
1110
|
+
// "uid": "101c2327-f12e-45f2-8445-7502b87afc0b",
|
|
1111
|
+
// "order": {
|
|
1112
|
+
// "orderId": "101c2327-f12e-45f2-8445-7502b87afc0b",
|
|
1113
|
+
// "cliOrdId": null,
|
|
1114
|
+
// "type": "lmt",
|
|
1115
|
+
// "symbol": "PF_LTCUSD",
|
|
1116
|
+
// "side": "buy",
|
|
1117
|
+
// "quantity": "0.10000000000",
|
|
1118
|
+
// "filled": "0E-11",
|
|
1119
|
+
// "limitPrice": "50.00000000000",
|
|
1120
|
+
// "reduceOnly": false,
|
|
1121
|
+
// "timestamp": "2023-10-20T10:29:13.005Z",
|
|
1122
|
+
// "lastUpdateTimestamp": "2023-10-20T10:29:13.005Z"
|
|
1123
|
+
// },
|
|
1124
|
+
// "type": "CANCEL"
|
|
1125
|
+
// }
|
|
1126
|
+
// ]
|
|
1127
|
+
// }
|
|
1128
|
+
// ]
|
|
1129
|
+
// }
|
|
1130
|
+
const batchStatus = this.safeValue(response, 'batchStatus', []);
|
|
1131
|
+
return this.parseOrders(batchStatus);
|
|
1132
|
+
}
|
|
1133
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
1134
|
+
/**
|
|
1135
|
+
* @method
|
|
1136
|
+
* @name krakenfutures#cancelAllOrders
|
|
1137
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-cancel-all-orders
|
|
1138
|
+
* @description Cancels all orders on the exchange, including trigger orders
|
|
1139
|
+
* @param {str} symbol Unified market symbol
|
|
1140
|
+
* @param {dict} [params] Exchange specific params
|
|
1141
|
+
* @returns Response from exchange api
|
|
1142
|
+
*/
|
|
1143
|
+
const request = {};
|
|
1144
|
+
if (symbol !== undefined) {
|
|
1145
|
+
request['symbol'] = this.marketId(symbol);
|
|
1146
|
+
}
|
|
1147
|
+
const response = await this.privatePostCancelallorders(this.extend(request, params));
|
|
1148
|
+
return response;
|
|
1149
|
+
}
|
|
1150
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1151
|
+
/**
|
|
1152
|
+
* @method
|
|
1153
|
+
* @name krakenfutures#fetchOpenOrders
|
|
1154
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-get-open-orders
|
|
1155
|
+
* @description Gets all open orders, including trigger orders, for an account from the exchange api
|
|
1156
|
+
* @param {string} symbol Unified market symbol
|
|
1157
|
+
* @param {int} [since] Timestamp (ms) of earliest order. (Not used by kraken api but filtered internally by CCXT)
|
|
1158
|
+
* @param {int} [limit] How many orders to return. (Not used by kraken api but filtered internally by CCXT)
|
|
1159
|
+
* @param {object} [params] Exchange specific parameters
|
|
1160
|
+
* @returns An array of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1161
|
+
*/
|
|
1162
|
+
await this.loadMarkets();
|
|
1163
|
+
let market = undefined;
|
|
1164
|
+
if (symbol !== undefined) {
|
|
1165
|
+
market = this.market(symbol);
|
|
1166
|
+
}
|
|
1167
|
+
const response = await this.privateGetOpenorders(params);
|
|
1168
|
+
const orders = this.safeValue(response, 'openOrders', []);
|
|
1169
|
+
return this.parseOrders(orders, market, since, limit);
|
|
1170
|
+
}
|
|
1171
|
+
parseOrderType(orderType) {
|
|
1172
|
+
const map = {
|
|
1173
|
+
'lmt': 'limit',
|
|
1174
|
+
'mkt': 'market',
|
|
1175
|
+
'post': 'limit',
|
|
1176
|
+
'ioc': 'market',
|
|
1177
|
+
};
|
|
1178
|
+
return this.safeString(map, orderType, orderType);
|
|
1179
|
+
}
|
|
1180
|
+
verifyOrderActionSuccess(status, method, omit = []) {
|
|
1181
|
+
const errors$1 = {
|
|
1182
|
+
'invalidOrderType': errors.InvalidOrder,
|
|
1183
|
+
'invalidSide': errors.InvalidOrder,
|
|
1184
|
+
'invalidSize': errors.InvalidOrder,
|
|
1185
|
+
'invalidPrice': errors.InvalidOrder,
|
|
1186
|
+
'insufficientAvailableFunds': errors.InsufficientFunds,
|
|
1187
|
+
'selfFill': errors.ExchangeError,
|
|
1188
|
+
'tooManySmallOrders': errors.ExchangeError,
|
|
1189
|
+
'maxPositionViolation': errors.BadRequest,
|
|
1190
|
+
'marketSuspended': errors.ExchangeNotAvailable,
|
|
1191
|
+
'marketInactive': errors.ExchangeNotAvailable,
|
|
1192
|
+
'clientOrderIdAlreadyExist': errors.DuplicateOrderId,
|
|
1193
|
+
'clientOrderIdTooLong': errors.BadRequest,
|
|
1194
|
+
'outsidePriceCollar': errors.InvalidOrder,
|
|
1195
|
+
'postWouldExecute': errors.OrderImmediatelyFillable,
|
|
1196
|
+
'iocWouldNotExecute': errors.OrderNotFillable,
|
|
1197
|
+
'wouldNotReducePosition': errors.ExchangeError,
|
|
1198
|
+
'orderForEditNotFound': errors.OrderNotFound,
|
|
1199
|
+
'orderForEditNotAStop': errors.InvalidOrder,
|
|
1200
|
+
'filled': errors.OrderNotFound,
|
|
1201
|
+
'notFound': errors.OrderNotFound,
|
|
1202
|
+
};
|
|
1203
|
+
if ((status in errors$1) && !this.inArray(status, omit)) {
|
|
1204
|
+
throw new errors$1[status](this.id + ': ' + method + ' failed due to ' + status);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
parseOrderStatus(status) {
|
|
1208
|
+
const statuses = {
|
|
1209
|
+
'placed': 'open',
|
|
1210
|
+
'cancelled': 'canceled',
|
|
1211
|
+
'invalidOrderType': 'rejected',
|
|
1212
|
+
'invalidSide': 'rejected',
|
|
1213
|
+
'invalidSize': 'rejected',
|
|
1214
|
+
'invalidPrice': 'rejected',
|
|
1215
|
+
'insufficientAvailableFunds': 'rejected',
|
|
1216
|
+
'selfFill': 'rejected',
|
|
1217
|
+
'tooManySmallOrders': 'rejected',
|
|
1218
|
+
'maxPositionViolation': 'rejected',
|
|
1219
|
+
'marketSuspended': 'rejected',
|
|
1220
|
+
'marketInactive': 'rejected',
|
|
1221
|
+
'clientOrderIdAlreadyExist': 'rejected',
|
|
1222
|
+
'clientOrderIdTooLong': 'rejected',
|
|
1223
|
+
'outsidePriceCollar': 'rejected',
|
|
1224
|
+
// Should the next two be 'expired' ?
|
|
1225
|
+
'postWouldExecute': 'rejected',
|
|
1226
|
+
'iocWouldNotExecute': 'rejected',
|
|
1227
|
+
'wouldNotReducePosition': 'rejected',
|
|
1228
|
+
'edited': 'open',
|
|
1229
|
+
'orderForEditNotFound': 'rejected',
|
|
1230
|
+
'orderForEditNotAStop': 'rejected',
|
|
1231
|
+
'filled': 'closed',
|
|
1232
|
+
'notFound': 'rejected',
|
|
1233
|
+
'untouched': 'open',
|
|
1234
|
+
'partiallyFilled': 'open', // the size of the order is partially but not entirely filled
|
|
1235
|
+
};
|
|
1236
|
+
return this.safeString(statuses, status, status);
|
|
1237
|
+
}
|
|
1238
|
+
parseOrder(order, market = undefined) {
|
|
1239
|
+
//
|
|
1240
|
+
// LIMIT
|
|
1241
|
+
//
|
|
1242
|
+
// {
|
|
1243
|
+
// "order_id": "179f9af8-e45e-469d-b3e9-2fd4675cb7d0",
|
|
1244
|
+
// "status": "placed",
|
|
1245
|
+
// "receivedTime": "2019-09-05T16:33:50.734Z",
|
|
1246
|
+
// "orderEvents": [
|
|
1247
|
+
// {
|
|
1248
|
+
// "uid": "614a5298-0071-450f-83c6-0617ce8c6bc4",
|
|
1249
|
+
// "order": {
|
|
1250
|
+
// "orderId": "179f9af8-e45e-469d-b3e9-2fd4675cb7d0",
|
|
1251
|
+
// "cliOrdId": null,
|
|
1252
|
+
// "type": "lmt",
|
|
1253
|
+
// "symbol": "pi_xbtusd",
|
|
1254
|
+
// "side": "buy",
|
|
1255
|
+
// "quantity": 10000,
|
|
1256
|
+
// "filled": 0,
|
|
1257
|
+
// "limitPrice": 9400,
|
|
1258
|
+
// "reduceOnly": false,
|
|
1259
|
+
// "timestamp": "2019-09-05T16:33:50.734Z",
|
|
1260
|
+
// "lastUpdateTimestamp": "2019-09-05T16:33:50.734Z"
|
|
1261
|
+
// },
|
|
1262
|
+
// "reducedQuantity": null,
|
|
1263
|
+
// "reason": "WOULD_NOT_REDUCE_POSITION", // REJECTED
|
|
1264
|
+
// "type": "PLACE"
|
|
1265
|
+
// }
|
|
1266
|
+
// ]
|
|
1267
|
+
// }
|
|
1268
|
+
//
|
|
1269
|
+
// CONDITIONAL
|
|
1270
|
+
//
|
|
1271
|
+
// {
|
|
1272
|
+
// "order_id": "1abfd3c6-af93-4b30-91cc-e4a93797f3f5",
|
|
1273
|
+
// "status": "placed",
|
|
1274
|
+
// "receivedTime": "2019-12-05T10:20:50.701Z",
|
|
1275
|
+
// "orderEvents": [
|
|
1276
|
+
// {
|
|
1277
|
+
// "orderTrigger": {
|
|
1278
|
+
// "uid": "1abfd3c6-af93-4b30-91cc-e4a93797f3f5",
|
|
1279
|
+
// "clientId":null,
|
|
1280
|
+
// "type": "lmt", // "ioc" if stop market
|
|
1281
|
+
// "symbol": "pi_xbtusd",
|
|
1282
|
+
// "side": "buy",
|
|
1283
|
+
// "quantity":10,
|
|
1284
|
+
// "limitPrice":15000,
|
|
1285
|
+
// "triggerPrice":9500,
|
|
1286
|
+
// "triggerSide": "trigger_below",
|
|
1287
|
+
// "triggerSignal": "mark_price",
|
|
1288
|
+
// "reduceOnly":false,
|
|
1289
|
+
// "timestamp": "2019-12-05T10:20:50.701Z",
|
|
1290
|
+
// "lastUpdateTimestamp": "2019-12-05T10:20:50.701Z"
|
|
1291
|
+
// },
|
|
1292
|
+
// "type": "PLACE"
|
|
1293
|
+
// }
|
|
1294
|
+
// ]
|
|
1295
|
+
// }
|
|
1296
|
+
//
|
|
1297
|
+
// EXECUTION
|
|
1298
|
+
//
|
|
1299
|
+
// {
|
|
1300
|
+
// "order_id": "61ca5732-3478-42fe-8362-abbfd9465294",
|
|
1301
|
+
// "status": "placed",
|
|
1302
|
+
// "receivedTime": "2019-12-11T17:17:33.888Z",
|
|
1303
|
+
// "orderEvents": [
|
|
1304
|
+
// {
|
|
1305
|
+
// "executionId": "e1ec9f63-2338-4c44-b40a-43486c6732d7",
|
|
1306
|
+
// "price": 7244.5,
|
|
1307
|
+
// "amount": 10,
|
|
1308
|
+
// "orderPriorEdit": null,
|
|
1309
|
+
// "orderPriorExecution": {
|
|
1310
|
+
// "orderId": "61ca5732-3478-42fe-8362-abbfd9465294",
|
|
1311
|
+
// "cliOrdId": null,
|
|
1312
|
+
// "type": "lmt",
|
|
1313
|
+
// "symbol": "pi_xbtusd",
|
|
1314
|
+
// "side": "buy",
|
|
1315
|
+
// "quantity": 10,
|
|
1316
|
+
// "filled": 0,
|
|
1317
|
+
// "limitPrice": 7500,
|
|
1318
|
+
// "reduceOnly": false,
|
|
1319
|
+
// "timestamp": "2019-12-11T17:17:33.888Z",
|
|
1320
|
+
// "lastUpdateTimestamp": "2019-12-11T17:17:33.888Z"
|
|
1321
|
+
// },
|
|
1322
|
+
// "takerReducedQuantity": null,
|
|
1323
|
+
// "type": "EXECUTION"
|
|
1324
|
+
// }
|
|
1325
|
+
// ]
|
|
1326
|
+
// }
|
|
1327
|
+
//
|
|
1328
|
+
// EDIT ORDER
|
|
1329
|
+
//
|
|
1330
|
+
// {
|
|
1331
|
+
// "status": "edited",
|
|
1332
|
+
// "orderId": "022774bc-2c4a-4f26-9317-436c8d85746d",
|
|
1333
|
+
// "receivedTime": "2019-09-05T16:47:47.521Z",
|
|
1334
|
+
// "orderEvents": [
|
|
1335
|
+
// {
|
|
1336
|
+
// "old": {
|
|
1337
|
+
// "orderId": "022774bc-2c4a-4f26-9317-436c8d85746d",
|
|
1338
|
+
// "cliOrdId":null,
|
|
1339
|
+
// "type": "lmt",
|
|
1340
|
+
// "symbol": "pi_xbtusd",
|
|
1341
|
+
// "side": "buy",
|
|
1342
|
+
// "quantity":1000,
|
|
1343
|
+
// "filled":0,
|
|
1344
|
+
// "limitPrice":9400.0,
|
|
1345
|
+
// "reduceOnly":false,
|
|
1346
|
+
// "timestamp": "2019-09-05T16:41:35.173Z",
|
|
1347
|
+
// "lastUpdateTimestamp": "2019-09-05T16:41:35.173Z"
|
|
1348
|
+
// },
|
|
1349
|
+
// "new": {
|
|
1350
|
+
// "orderId": "022774bc-2c4a-4f26-9317-436c8d85746d",
|
|
1351
|
+
// "cliOrdId": null,
|
|
1352
|
+
// "type": "lmt",
|
|
1353
|
+
// "symbol": "pi_xbtusd",
|
|
1354
|
+
// "side": "buy",
|
|
1355
|
+
// "quantity": 1501,
|
|
1356
|
+
// "filled": 0,
|
|
1357
|
+
// "limitPrice": 7200,
|
|
1358
|
+
// "reduceOnly": false,
|
|
1359
|
+
// "timestamp": "2019-09-05T16:41:35.173Z",
|
|
1360
|
+
// "lastUpdateTimestamp": "2019-09-05T16:47:47.519Z"
|
|
1361
|
+
// },
|
|
1362
|
+
// "reducedQuantity": null,
|
|
1363
|
+
// "type": "EDIT"
|
|
1364
|
+
// }
|
|
1365
|
+
// ]
|
|
1366
|
+
// }
|
|
1367
|
+
//
|
|
1368
|
+
// CANCEL ORDER
|
|
1369
|
+
//
|
|
1370
|
+
// {
|
|
1371
|
+
// "status": "cancelled",
|
|
1372
|
+
// "orderEvents": [
|
|
1373
|
+
// {
|
|
1374
|
+
// "uid": "85c40002-3f20-4e87-9302-262626c3531b",
|
|
1375
|
+
// "order": {
|
|
1376
|
+
// "orderId": "85c40002-3f20-4e87-9302-262626c3531b",
|
|
1377
|
+
// "cliOrdId": null,
|
|
1378
|
+
// "type": "lmt",
|
|
1379
|
+
// "symbol": "pi_xbtusd",
|
|
1380
|
+
// "side": "buy",
|
|
1381
|
+
// "quantity": 1000,
|
|
1382
|
+
// "filled": 0,
|
|
1383
|
+
// "limitPrice": 10144,
|
|
1384
|
+
// "stopPrice": null,
|
|
1385
|
+
// "reduceOnly": false,
|
|
1386
|
+
// "timestamp": "2019-08-01T15:26:27.790Z"
|
|
1387
|
+
// },
|
|
1388
|
+
// "type": "CANCEL"
|
|
1389
|
+
// }
|
|
1390
|
+
// ]
|
|
1391
|
+
// }
|
|
1392
|
+
//
|
|
1393
|
+
// FETCH OPEN ORDERS
|
|
1394
|
+
//
|
|
1395
|
+
// {
|
|
1396
|
+
// "order_id": "59302619-41d2-4f0b-941f-7e7914760ad3",
|
|
1397
|
+
// "symbol": "pi_xbtusd",
|
|
1398
|
+
// "side": "sell",
|
|
1399
|
+
// "orderType": "lmt",
|
|
1400
|
+
// "limitPrice": 10640,
|
|
1401
|
+
// "unfilledSize": 304,
|
|
1402
|
+
// "receivedTime": "2019-09-05T17:01:17.410Z",
|
|
1403
|
+
// "status": "untouched",
|
|
1404
|
+
// "filledSize": 0,
|
|
1405
|
+
// "reduceOnly": true,
|
|
1406
|
+
// "lastUpdateTime": "2019-09-05T17:01:17.410Z"
|
|
1407
|
+
// }
|
|
1408
|
+
//
|
|
1409
|
+
// createOrders error
|
|
1410
|
+
// {
|
|
1411
|
+
// "status": "requiredArgumentMissing",
|
|
1412
|
+
// "orderEvents": []
|
|
1413
|
+
// }
|
|
1414
|
+
//
|
|
1415
|
+
const orderEvents = this.safeValue(order, 'orderEvents', []);
|
|
1416
|
+
const errorStatus = this.safeString(order, 'status');
|
|
1417
|
+
const orderEventsLength = orderEvents.length;
|
|
1418
|
+
if (('orderEvents' in order) && (errorStatus !== undefined) && (orderEventsLength === 0)) {
|
|
1419
|
+
// creteOrders error response
|
|
1420
|
+
return this.safeOrder({ 'info': order, 'status': 'rejected' });
|
|
1421
|
+
}
|
|
1422
|
+
let details = undefined;
|
|
1423
|
+
let isPrior = false;
|
|
1424
|
+
let fixed = false;
|
|
1425
|
+
let statusId = undefined;
|
|
1426
|
+
let price = undefined;
|
|
1427
|
+
let trades = [];
|
|
1428
|
+
if (orderEventsLength) {
|
|
1429
|
+
const executions = [];
|
|
1430
|
+
for (let i = 0; i < orderEvents.length; i++) {
|
|
1431
|
+
const item = orderEvents[i];
|
|
1432
|
+
if (this.safeString(item, 'type') === 'EXECUTION') {
|
|
1433
|
+
executions.push(item);
|
|
1434
|
+
}
|
|
1435
|
+
// Final order (after placement / editing / execution / canceling)
|
|
1436
|
+
const orderTrigger = this.safeValue(item, 'orderTrigger');
|
|
1437
|
+
details = this.safeValue2(item, 'new', 'order', orderTrigger);
|
|
1438
|
+
if (details !== undefined) {
|
|
1439
|
+
isPrior = false;
|
|
1440
|
+
fixed = true;
|
|
1441
|
+
}
|
|
1442
|
+
else if (!fixed) {
|
|
1443
|
+
const orderPriorExecution = this.safeValue(item, 'orderPriorExecution');
|
|
1444
|
+
details = this.safeValue2(item, 'orderPriorExecution', 'orderPriorEdit');
|
|
1445
|
+
price = this.safeString(orderPriorExecution, 'limitPrice');
|
|
1446
|
+
if (details !== undefined) {
|
|
1447
|
+
isPrior = true;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
trades = this.parseTrades(executions);
|
|
1452
|
+
statusId = this.safeString(order, 'status');
|
|
1453
|
+
}
|
|
1454
|
+
if (details === undefined) {
|
|
1455
|
+
details = order;
|
|
1456
|
+
}
|
|
1457
|
+
if (statusId === undefined) {
|
|
1458
|
+
statusId = this.safeString(details, 'status');
|
|
1459
|
+
}
|
|
1460
|
+
// This may be incorrectly marked as "open" if only execution report is given,
|
|
1461
|
+
// but will be fixed below
|
|
1462
|
+
let status = this.parseOrderStatus(statusId);
|
|
1463
|
+
let isClosed = this.inArray(status, ['canceled', 'rejected', 'closed']);
|
|
1464
|
+
const marketId = this.safeString(details, 'symbol');
|
|
1465
|
+
market = this.safeMarket(marketId, market);
|
|
1466
|
+
const timestamp = this.parse8601(this.safeString2(details, 'timestamp', 'receivedTime'));
|
|
1467
|
+
const lastUpdateTimestamp = this.parse8601(this.safeString(details, 'lastUpdateTime'));
|
|
1468
|
+
if (price === undefined) {
|
|
1469
|
+
price = this.safeString(details, 'limitPrice');
|
|
1470
|
+
}
|
|
1471
|
+
let amount = this.safeString(details, 'quantity');
|
|
1472
|
+
let filled = this.safeString2(details, 'filledSize', 'filled', '0.0');
|
|
1473
|
+
let remaining = this.safeString(details, 'unfilledSize');
|
|
1474
|
+
let average = undefined;
|
|
1475
|
+
let filled2 = '0.0';
|
|
1476
|
+
if (trades.length) {
|
|
1477
|
+
let vwapSum = '0.0';
|
|
1478
|
+
for (let i = 0; i < trades.length; i++) {
|
|
1479
|
+
const trade = trades[i];
|
|
1480
|
+
const tradeAmount = this.safeString(trade, 'amount');
|
|
1481
|
+
const tradePrice = this.safeString(trade, 'price');
|
|
1482
|
+
filled2 = Precise["default"].stringAdd(filled2, tradeAmount);
|
|
1483
|
+
vwapSum = Precise["default"].stringAdd(vwapSum, Precise["default"].stringMul(tradeAmount, tradePrice));
|
|
1484
|
+
}
|
|
1485
|
+
average = Precise["default"].stringDiv(vwapSum, filled2);
|
|
1486
|
+
if ((amount !== undefined) && (!isClosed) && isPrior && Precise["default"].stringGe(filled2, amount)) {
|
|
1487
|
+
status = 'closed';
|
|
1488
|
+
isClosed = true;
|
|
1489
|
+
}
|
|
1490
|
+
if (isPrior) {
|
|
1491
|
+
filled = Precise["default"].stringAdd(filled, filled2);
|
|
1492
|
+
}
|
|
1493
|
+
else {
|
|
1494
|
+
filled = Precise["default"].stringMax(filled, filled2);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (remaining === undefined) {
|
|
1498
|
+
if (isPrior) {
|
|
1499
|
+
if (amount !== undefined) {
|
|
1500
|
+
// remaining amount before execution minus executed amount
|
|
1501
|
+
remaining = Precise["default"].stringSub(amount, filled2);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
else {
|
|
1505
|
+
remaining = amount;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
// if fetchOpenOrders are parsed
|
|
1509
|
+
if ((amount === undefined) && (!isPrior) && (remaining !== undefined)) {
|
|
1510
|
+
amount = Precise["default"].stringAdd(filled, remaining);
|
|
1511
|
+
}
|
|
1512
|
+
let cost = undefined;
|
|
1513
|
+
if ((filled !== undefined) && (market !== undefined)) {
|
|
1514
|
+
const whichPrice = (average !== undefined) ? average : price;
|
|
1515
|
+
if (whichPrice !== undefined) {
|
|
1516
|
+
if (market['linear']) {
|
|
1517
|
+
cost = Precise["default"].stringMul(filled, whichPrice); // in quote
|
|
1518
|
+
}
|
|
1519
|
+
else {
|
|
1520
|
+
cost = Precise["default"].stringDiv(filled, whichPrice); // in base
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
let id = this.safeString2(order, 'order_id', 'orderId');
|
|
1525
|
+
if (id === undefined) {
|
|
1526
|
+
id = this.safeString2(details, 'orderId', 'uid');
|
|
1527
|
+
}
|
|
1528
|
+
const type = this.safeStringLower2(details, 'type', 'orderType');
|
|
1529
|
+
let timeInForce = 'gtc';
|
|
1530
|
+
if (type === 'ioc' || this.parseOrderType(type) === 'market') {
|
|
1531
|
+
timeInForce = 'ioc';
|
|
1532
|
+
}
|
|
1533
|
+
return this.safeOrder({
|
|
1534
|
+
'info': order,
|
|
1535
|
+
'id': id,
|
|
1536
|
+
'clientOrderId': this.safeStringN(details, ['clientOrderId', 'clientId', 'cliOrdId']),
|
|
1537
|
+
'timestamp': timestamp,
|
|
1538
|
+
'datetime': this.iso8601(timestamp),
|
|
1539
|
+
'lastTradeTimestamp': undefined,
|
|
1540
|
+
'lastUpdateTimestamp': lastUpdateTimestamp,
|
|
1541
|
+
'symbol': this.safeString(market, 'symbol'),
|
|
1542
|
+
'type': this.parseOrderType(type),
|
|
1543
|
+
'timeInForce': timeInForce,
|
|
1544
|
+
'postOnly': type === 'post',
|
|
1545
|
+
'reduceOnly': this.safeValue(details, 'reduceOnly'),
|
|
1546
|
+
'side': this.safeString(details, 'side'),
|
|
1547
|
+
'price': price,
|
|
1548
|
+
'stopPrice': this.safeString(details, 'triggerPrice'),
|
|
1549
|
+
'triggerPrice': this.safeString(details, 'triggerPrice'),
|
|
1550
|
+
'amount': amount,
|
|
1551
|
+
'cost': cost,
|
|
1552
|
+
'average': average,
|
|
1553
|
+
'filled': filled,
|
|
1554
|
+
'remaining': remaining,
|
|
1555
|
+
'status': status,
|
|
1556
|
+
'fee': undefined,
|
|
1557
|
+
'fees': undefined,
|
|
1558
|
+
'trades': trades,
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1562
|
+
/**
|
|
1563
|
+
* @method
|
|
1564
|
+
* @name krakenfutures#fetchMyTrades
|
|
1565
|
+
* @description fetch all trades made by the user
|
|
1566
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-historical-data-get-your-fills
|
|
1567
|
+
* @param {string} symbol unified market symbol
|
|
1568
|
+
* @param {int} [since] *not used by the api* the earliest time in ms to fetch trades for
|
|
1569
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
1570
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1571
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
1572
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1573
|
+
*/
|
|
1574
|
+
await this.loadMarkets();
|
|
1575
|
+
let market = undefined;
|
|
1576
|
+
if (symbol !== undefined) {
|
|
1577
|
+
market = this.market(symbol);
|
|
1578
|
+
}
|
|
1579
|
+
const response = await this.privateGetFills(params);
|
|
1580
|
+
//
|
|
1581
|
+
// {
|
|
1582
|
+
// "result": "success",
|
|
1583
|
+
// "serverTime": "2016-02-25T09:45:53.818Z",
|
|
1584
|
+
// "fills": [
|
|
1585
|
+
// {
|
|
1586
|
+
// "fillTime": "2016-02-25T09:47:01.000Z",
|
|
1587
|
+
// "order_id": "c18f0c17-9971-40e6-8e5b-10df05d422f0",
|
|
1588
|
+
// "fill_id": "522d4e08-96e7-4b44-9694-bfaea8fe215e",
|
|
1589
|
+
// "cliOrdId": "d427f920-ec55-4c18-ba95-5fe241513b30", // EXTRA
|
|
1590
|
+
// "symbol": "fi_xbtusd_180615",
|
|
1591
|
+
// "side": "buy",
|
|
1592
|
+
// "size": 2000,
|
|
1593
|
+
// "price": 4255,
|
|
1594
|
+
// "fillType": "maker"
|
|
1595
|
+
// },
|
|
1596
|
+
// ...
|
|
1597
|
+
// ]
|
|
1598
|
+
// }
|
|
1599
|
+
//
|
|
1600
|
+
return this.parseTrades(response['fills'], market, since, limit);
|
|
1601
|
+
}
|
|
1602
|
+
async fetchBalance(params = {}) {
|
|
1603
|
+
/**
|
|
1604
|
+
* @method
|
|
1605
|
+
* @name krakenfutures#fetchBalance
|
|
1606
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-account-information-get-wallets
|
|
1607
|
+
* @description Fetch the balance for a sub-account, all sub-account balances are inside 'info' in the response
|
|
1608
|
+
* @param {object} [params] Exchange specific parameters
|
|
1609
|
+
* @param {string} [params.type] The sub-account type to query the balance of, possible values include 'flex', 'cash'/'main'/'funding', or a market symbol * defaults to 'flex' *
|
|
1610
|
+
* @param {string} [params.symbol] A unified market symbol, when assigned the balance for a trading market that matches the symbol is returned
|
|
1611
|
+
* @returns A [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1612
|
+
*/
|
|
1613
|
+
await this.loadMarkets();
|
|
1614
|
+
let type = this.safeString2(params, 'type', 'account');
|
|
1615
|
+
let symbol = this.safeString(params, 'symbol');
|
|
1616
|
+
params = this.omit(params, ['type', 'account', 'symbol']);
|
|
1617
|
+
const response = await this.privateGetAccounts(params);
|
|
1618
|
+
//
|
|
1619
|
+
// {
|
|
1620
|
+
// "result": "success",
|
|
1621
|
+
// "accounts": {
|
|
1622
|
+
// "fi_xbtusd": {
|
|
1623
|
+
// "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" },
|
|
1624
|
+
// "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" },
|
|
1625
|
+
// "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" },
|
|
1626
|
+
// "balances": { xbt: "0.0" },
|
|
1627
|
+
// "currency": "xbt",
|
|
1628
|
+
// "type": "marginAccount"
|
|
1629
|
+
// },
|
|
1630
|
+
// "cash": {
|
|
1631
|
+
// "balances": {
|
|
1632
|
+
// "eur": "0.0",
|
|
1633
|
+
// "gbp": "0.0",
|
|
1634
|
+
// "bch": "0.0",
|
|
1635
|
+
// "xrp": "2.20188538338",
|
|
1636
|
+
// "usd": "0.0",
|
|
1637
|
+
// "eth": "0.0",
|
|
1638
|
+
// "usdt": "0.0",
|
|
1639
|
+
// "ltc": "0.0",
|
|
1640
|
+
// "usdc": "0.0",
|
|
1641
|
+
// "xbt": "0.0"
|
|
1642
|
+
// },
|
|
1643
|
+
// "type": "cashAccount"
|
|
1644
|
+
// },
|
|
1645
|
+
// "fv_xrpxbt": {
|
|
1646
|
+
// "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" },
|
|
1647
|
+
// "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" },
|
|
1648
|
+
// "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" },
|
|
1649
|
+
// "balances": { xbt: "0.0" },
|
|
1650
|
+
// "currency": "xbt",
|
|
1651
|
+
// "type": "marginAccount"
|
|
1652
|
+
// },
|
|
1653
|
+
// "fi_xrpusd": {
|
|
1654
|
+
// "auxiliary": { usd: "0", pv: '11.0', pnl: '0.0', af: '11.0', funding: "0.0" },
|
|
1655
|
+
// "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" },
|
|
1656
|
+
// "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" },
|
|
1657
|
+
// "balances": { xrp: "11.0" },
|
|
1658
|
+
// "currency": "xrp",
|
|
1659
|
+
// "type": "marginAccount"
|
|
1660
|
+
// },
|
|
1661
|
+
// "fi_ethusd": {
|
|
1662
|
+
// "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" },
|
|
1663
|
+
// "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" },
|
|
1664
|
+
// "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" },
|
|
1665
|
+
// "balances": { eth: "0.0" },
|
|
1666
|
+
// "currency": "eth",
|
|
1667
|
+
// "type": "marginAccount"
|
|
1668
|
+
// },
|
|
1669
|
+
// "fi_ltcusd": {
|
|
1670
|
+
// "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" },
|
|
1671
|
+
// "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" },
|
|
1672
|
+
// "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" },
|
|
1673
|
+
// "balances": { ltc: "0.0" },
|
|
1674
|
+
// "currency": "ltc",
|
|
1675
|
+
// "type": "marginAccount"
|
|
1676
|
+
// },
|
|
1677
|
+
// "fi_bchusd": {
|
|
1678
|
+
// "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" },
|
|
1679
|
+
// "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" },
|
|
1680
|
+
// "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" },
|
|
1681
|
+
// "balances": { bch: "0.0" },
|
|
1682
|
+
// "currency": "bch",
|
|
1683
|
+
// "type": "marginAccount"
|
|
1684
|
+
// },
|
|
1685
|
+
// "flex": {
|
|
1686
|
+
// "currencies": {},
|
|
1687
|
+
// "initialMargin": "0.0",
|
|
1688
|
+
// "initialMarginWithOrders": "0.0",
|
|
1689
|
+
// "maintenanceMargin": "0.0",
|
|
1690
|
+
// "balanceValue": "0.0",
|
|
1691
|
+
// "portfolioValue": "0.0",
|
|
1692
|
+
// "collateralValue": "0.0",
|
|
1693
|
+
// "pnl": "0.0",
|
|
1694
|
+
// "unrealizedFunding": "0.0",
|
|
1695
|
+
// "totalUnrealized": "0.0",
|
|
1696
|
+
// "totalUnrealizedAsMargin": "0.0",
|
|
1697
|
+
// "availableMargin": "0.0",
|
|
1698
|
+
// "marginEquity": "0.0",
|
|
1699
|
+
// "type": "multiCollateralMarginAccount"
|
|
1700
|
+
// }
|
|
1701
|
+
// },
|
|
1702
|
+
// "serverTime": "2022-04-12T07:48:07.475Z"
|
|
1703
|
+
// }
|
|
1704
|
+
//
|
|
1705
|
+
const datetime = this.safeString(response, 'serverTime');
|
|
1706
|
+
if (type === 'marginAccount' || type === 'margin') {
|
|
1707
|
+
if (symbol === undefined) {
|
|
1708
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchBalance requires symbol argument for margin accounts');
|
|
1709
|
+
}
|
|
1710
|
+
type = symbol;
|
|
1711
|
+
}
|
|
1712
|
+
if (type === undefined) {
|
|
1713
|
+
type = (symbol === undefined) ? 'flex' : symbol;
|
|
1714
|
+
}
|
|
1715
|
+
const accountName = this.parseAccount(type);
|
|
1716
|
+
const accounts = this.safeValue(response, 'accounts');
|
|
1717
|
+
const account = this.safeValue(accounts, accountName);
|
|
1718
|
+
if (account === undefined) {
|
|
1719
|
+
type = (type === undefined) ? '' : type;
|
|
1720
|
+
symbol = (symbol === undefined) ? '' : symbol;
|
|
1721
|
+
throw new errors.BadRequest(this.id + ' fetchBalance has no account for ' + type);
|
|
1722
|
+
}
|
|
1723
|
+
const balance = this.parseBalance(account);
|
|
1724
|
+
balance['info'] = response;
|
|
1725
|
+
balance['timestamp'] = this.parse8601(datetime);
|
|
1726
|
+
balance['datetime'] = datetime;
|
|
1727
|
+
return balance;
|
|
1728
|
+
}
|
|
1729
|
+
parseBalance(response) {
|
|
1730
|
+
//
|
|
1731
|
+
// cashAccount
|
|
1732
|
+
//
|
|
1733
|
+
// {
|
|
1734
|
+
// "balances": {
|
|
1735
|
+
// "eur": "0.0",
|
|
1736
|
+
// "gbp": "0.0",
|
|
1737
|
+
// "bch": "0.0",
|
|
1738
|
+
// "xrp": "2.20188538338",
|
|
1739
|
+
// "usd": "0.0",
|
|
1740
|
+
// "eth": "0.0",
|
|
1741
|
+
// "usdt": "0.0",
|
|
1742
|
+
// "ltc": "0.0",
|
|
1743
|
+
// "usdc": "0.0",
|
|
1744
|
+
// "xbt": "0.0"
|
|
1745
|
+
// },
|
|
1746
|
+
// "type": "cashAccount"
|
|
1747
|
+
// }
|
|
1748
|
+
//
|
|
1749
|
+
// marginAccount e,g, fi_xrpusd
|
|
1750
|
+
//
|
|
1751
|
+
// {
|
|
1752
|
+
// "auxiliary": {
|
|
1753
|
+
// "usd": "0",
|
|
1754
|
+
// "pv": "11.0",
|
|
1755
|
+
// "pnl": "0.0",
|
|
1756
|
+
// "af": "11.0",
|
|
1757
|
+
// "funding": "0.0"
|
|
1758
|
+
// },
|
|
1759
|
+
// "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" },
|
|
1760
|
+
// "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" },
|
|
1761
|
+
// "balances": { xrp: "11.0" },
|
|
1762
|
+
// "currency": "xrp",
|
|
1763
|
+
// "type": "marginAccount"
|
|
1764
|
+
// }
|
|
1765
|
+
//
|
|
1766
|
+
// flex/multiCollateralMarginAccount
|
|
1767
|
+
//
|
|
1768
|
+
// {
|
|
1769
|
+
// "currencies": {
|
|
1770
|
+
// "USDT": {
|
|
1771
|
+
// "quantity": "1",
|
|
1772
|
+
// "value": "1.0001",
|
|
1773
|
+
// "collateral": "0.9477197625",
|
|
1774
|
+
// "available": "1.0"
|
|
1775
|
+
// }
|
|
1776
|
+
// },
|
|
1777
|
+
// "initialMargin": "0.0",
|
|
1778
|
+
// "initialMarginWithOrders": "0.0",
|
|
1779
|
+
// "maintenanceMargin": "0.0",
|
|
1780
|
+
// "balanceValue": "1.0",
|
|
1781
|
+
// "portfolioValue": "1.0",
|
|
1782
|
+
// "collateralValue": "0.95",
|
|
1783
|
+
// "pnl": "0.0",
|
|
1784
|
+
// "unrealizedFunding": "0.0",
|
|
1785
|
+
// "totalUnrealized": "0.0",
|
|
1786
|
+
// "totalUnrealizedAsMargin": "0.0",
|
|
1787
|
+
// "availableMargin": "0.95",
|
|
1788
|
+
// "marginEquity": "0.95",
|
|
1789
|
+
// "type": "multiCollateralMarginAccount"
|
|
1790
|
+
// }
|
|
1791
|
+
//
|
|
1792
|
+
const accountType = this.safeString2(response, 'accountType', 'type');
|
|
1793
|
+
const isFlex = (accountType === 'multiCollateralMarginAccount');
|
|
1794
|
+
const isCash = (accountType === 'cashAccount');
|
|
1795
|
+
const balances = this.safeValue2(response, 'balances', 'currencies', {});
|
|
1796
|
+
const result = {};
|
|
1797
|
+
const currencyIds = Object.keys(balances);
|
|
1798
|
+
for (let i = 0; i < currencyIds.length; i++) {
|
|
1799
|
+
const currencyId = currencyIds[i];
|
|
1800
|
+
const balance = balances[currencyId];
|
|
1801
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
1802
|
+
const splitCode = code.split('_');
|
|
1803
|
+
const codeLength = splitCode.length;
|
|
1804
|
+
if (codeLength > 1) {
|
|
1805
|
+
continue; // Removes contract codes like PI_XRPUSD
|
|
1806
|
+
}
|
|
1807
|
+
const account = this.account();
|
|
1808
|
+
if (isFlex) {
|
|
1809
|
+
account['total'] = this.safeString(balance, 'quantity');
|
|
1810
|
+
account['free'] = this.safeString(balance, 'available');
|
|
1811
|
+
}
|
|
1812
|
+
else if (isCash) {
|
|
1813
|
+
account['used'] = '0.0';
|
|
1814
|
+
account['total'] = balance;
|
|
1815
|
+
}
|
|
1816
|
+
else {
|
|
1817
|
+
const auxiliary = this.safeValue(response, 'auxiliary');
|
|
1818
|
+
account['free'] = this.safeString(auxiliary, 'af');
|
|
1819
|
+
account['total'] = this.safeString(auxiliary, 'pv');
|
|
1820
|
+
}
|
|
1821
|
+
result[code] = account;
|
|
1822
|
+
}
|
|
1823
|
+
return this.safeBalance(result);
|
|
1824
|
+
}
|
|
1825
|
+
async fetchFundingRates(symbols = undefined, params = {}) {
|
|
1826
|
+
/**
|
|
1827
|
+
* @method
|
|
1828
|
+
* @name krakenfutures#fetchFundingRates
|
|
1829
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-tickers
|
|
1830
|
+
* @description fetch the current funding rates
|
|
1831
|
+
* @param {string[]} symbols unified market symbols
|
|
1832
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1833
|
+
* @returns {Order[]} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
1834
|
+
*/
|
|
1835
|
+
await this.loadMarkets();
|
|
1836
|
+
const marketIds = this.marketIds(symbols);
|
|
1837
|
+
const response = await this.publicGetTickers(params);
|
|
1838
|
+
const tickers = this.safeValue(response, 'tickers');
|
|
1839
|
+
const fundingRates = [];
|
|
1840
|
+
for (let i = 0; i < tickers.length; i++) {
|
|
1841
|
+
const entry = tickers[i];
|
|
1842
|
+
const entry_symbol = this.safeValue(entry, 'symbol');
|
|
1843
|
+
if (marketIds !== undefined) {
|
|
1844
|
+
if (!this.inArray(entry_symbol, marketIds)) {
|
|
1845
|
+
continue;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
const market = this.safeMarket(entry_symbol);
|
|
1849
|
+
const parsed = this.parseFundingRate(entry, market);
|
|
1850
|
+
fundingRates.push(parsed);
|
|
1851
|
+
}
|
|
1852
|
+
return this.indexBy(fundingRates, 'symbol');
|
|
1853
|
+
}
|
|
1854
|
+
parseFundingRate(ticker, market = undefined) {
|
|
1855
|
+
//
|
|
1856
|
+
// {"ask": 26.283,
|
|
1857
|
+
// "askSize": 4.6,
|
|
1858
|
+
// "bid": 26.201,
|
|
1859
|
+
// "bidSize": 190,
|
|
1860
|
+
// "fundingRate": -0.000944642727438883,
|
|
1861
|
+
// "fundingRatePrediction": -0.000872671532340275,
|
|
1862
|
+
// "indexPrice": 26.253,
|
|
1863
|
+
// "last": 26.3,
|
|
1864
|
+
// "lastSize": 0.1,
|
|
1865
|
+
// "lastTime": "2023-06-11T18:55:28.958Z",
|
|
1866
|
+
// "markPrice": 26.239,
|
|
1867
|
+
// "open24h": 26.3,
|
|
1868
|
+
// "openInterest": 641.1,
|
|
1869
|
+
// "pair": "COMP:USD",
|
|
1870
|
+
// "postOnly": False,
|
|
1871
|
+
// "suspended": False,
|
|
1872
|
+
// "symbol": "pf_compusd",
|
|
1873
|
+
// "tag": "perpetual",
|
|
1874
|
+
// "vol24h": 0.1,
|
|
1875
|
+
// "volumeQuote": 2.63}
|
|
1876
|
+
//
|
|
1877
|
+
const fundingRateMultiplier = '8'; // https://support.kraken.com/hc/en-us/articles/9618146737172-Perpetual-Contracts-Funding-Rate-Method-Prior-to-September-29-2022
|
|
1878
|
+
const marketId = this.safeString(ticker, 'symbol');
|
|
1879
|
+
const symbol = this.symbol(marketId);
|
|
1880
|
+
const timestamp = this.parse8601(this.safeString(ticker, 'lastTime'));
|
|
1881
|
+
const indexPrice = this.safeNumber(ticker, 'indexPrice');
|
|
1882
|
+
const markPriceString = this.safeString(ticker, 'markPrice');
|
|
1883
|
+
const markPrice = this.parseNumber(markPriceString);
|
|
1884
|
+
const fundingRateString = this.safeString(ticker, 'fundingRate');
|
|
1885
|
+
const fundingRateResult = Precise["default"].stringDiv(Precise["default"].stringMul(fundingRateString, fundingRateMultiplier), markPriceString);
|
|
1886
|
+
const fundingRate = this.parseNumber(fundingRateResult);
|
|
1887
|
+
const nextFundingRateString = this.safeString(ticker, 'fundingRatePrediction');
|
|
1888
|
+
const nextFundingRateResult = Precise["default"].stringDiv(Precise["default"].stringMul(nextFundingRateString, fundingRateMultiplier), markPriceString);
|
|
1889
|
+
const nextFundingRate = this.parseNumber(nextFundingRateResult);
|
|
1890
|
+
return {
|
|
1891
|
+
'info': ticker,
|
|
1892
|
+
'symbol': symbol,
|
|
1893
|
+
'markPrice': markPrice,
|
|
1894
|
+
'indexPrice': indexPrice,
|
|
1895
|
+
'interestRate': undefined,
|
|
1896
|
+
'estimatedSettlePrice': undefined,
|
|
1897
|
+
'timestamp': timestamp,
|
|
1898
|
+
'datetime': this.iso8601(timestamp),
|
|
1899
|
+
'fundingRate': fundingRate,
|
|
1900
|
+
'fundingTimestamp': undefined,
|
|
1901
|
+
'fundingDatetime': undefined,
|
|
1902
|
+
'nextFundingRate': nextFundingRate,
|
|
1903
|
+
'nextFundingTimestamp': undefined,
|
|
1904
|
+
'nextFundingDatetime': undefined,
|
|
1905
|
+
'previousFundingRate': undefined,
|
|
1906
|
+
'previousFundingTimestamp': undefined,
|
|
1907
|
+
'previousFundingDatetime': undefined,
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1911
|
+
/**
|
|
1912
|
+
* @method
|
|
1913
|
+
* @name krakenfutures#fetchFundingRateHistory
|
|
1914
|
+
* @description fetches historical funding rate prices
|
|
1915
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-historical-funding-rates-historical-funding-rates
|
|
1916
|
+
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
1917
|
+
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
1918
|
+
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
|
1919
|
+
* @param {object} [params] extra parameters specific to the api endpoint
|
|
1920
|
+
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
|
|
1921
|
+
*/
|
|
1922
|
+
if (symbol === undefined) {
|
|
1923
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
|
|
1924
|
+
}
|
|
1925
|
+
await this.loadMarkets();
|
|
1926
|
+
const market = this.market(symbol);
|
|
1927
|
+
if (!market['swap']) {
|
|
1928
|
+
throw new errors.BadRequest(this.id + ' fetchFundingRateHistory() supports swap contracts only');
|
|
1929
|
+
}
|
|
1930
|
+
const request = {
|
|
1931
|
+
'symbol': market['id'].toUpperCase(),
|
|
1932
|
+
};
|
|
1933
|
+
const response = await this.publicGetHistoricalfundingrates(this.extend(request, params));
|
|
1934
|
+
//
|
|
1935
|
+
// {
|
|
1936
|
+
// "rates": [
|
|
1937
|
+
// {
|
|
1938
|
+
// "timestamp": '2018-08-31T16:00:00.000Z',
|
|
1939
|
+
// "fundingRate": '2.18900669884E-7',
|
|
1940
|
+
// "relativeFundingRate": '0.000060779960000000'
|
|
1941
|
+
// },
|
|
1942
|
+
// ...
|
|
1943
|
+
// ]
|
|
1944
|
+
// }
|
|
1945
|
+
//
|
|
1946
|
+
const rates = this.safeValue(response, 'rates');
|
|
1947
|
+
const result = [];
|
|
1948
|
+
for (let i = 0; i < rates.length; i++) {
|
|
1949
|
+
const item = rates[i];
|
|
1950
|
+
const datetime = this.safeString(item, 'timestamp');
|
|
1951
|
+
result.push({
|
|
1952
|
+
'info': item,
|
|
1953
|
+
'symbol': symbol,
|
|
1954
|
+
'fundingRate': this.safeNumber(item, 'relativeFundingRate'),
|
|
1955
|
+
'timestamp': this.parse8601(datetime),
|
|
1956
|
+
'datetime': datetime,
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
const sorted = this.sortBy(result, 'timestamp');
|
|
1960
|
+
return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
|
|
1961
|
+
}
|
|
1962
|
+
async fetchPositions(symbols = undefined, params = {}) {
|
|
1963
|
+
/**
|
|
1964
|
+
* @method
|
|
1965
|
+
* @name krakenfutures#fetchPositions
|
|
1966
|
+
* @see https://docs.futures.kraken.com/#websocket-api-private-feeds-open-positions
|
|
1967
|
+
* @description Fetches current contract trading positions
|
|
1968
|
+
* @param {string[]} symbols List of unified symbols
|
|
1969
|
+
* @param {object} [params] Not used by krakenfutures
|
|
1970
|
+
* @returns Parsed exchange response for positions
|
|
1971
|
+
*/
|
|
1972
|
+
await this.loadMarkets();
|
|
1973
|
+
const request = {};
|
|
1974
|
+
const response = await this.privateGetOpenpositions(request);
|
|
1975
|
+
//
|
|
1976
|
+
// {
|
|
1977
|
+
// "result": "success",
|
|
1978
|
+
// "openPositions": [
|
|
1979
|
+
// {
|
|
1980
|
+
// "side": "long",
|
|
1981
|
+
// "symbol": "pi_xrpusd",
|
|
1982
|
+
// "price": "0.7533",
|
|
1983
|
+
// "fillTime": "2022-03-03T22:51:16.566Z",
|
|
1984
|
+
// "size": "230",
|
|
1985
|
+
// "unrealizedFunding": "-0.001878596918214635"
|
|
1986
|
+
// }
|
|
1987
|
+
// ],
|
|
1988
|
+
// "serverTime": "2022-03-03T22:51:16.566Z"
|
|
1989
|
+
// }
|
|
1990
|
+
//
|
|
1991
|
+
const result = this.parsePositions(response);
|
|
1992
|
+
return this.filterByArrayPositions(result, 'symbol', symbols, false);
|
|
1993
|
+
}
|
|
1994
|
+
parsePositions(response, symbols = undefined, params = {}) {
|
|
1995
|
+
const result = [];
|
|
1996
|
+
const positions = this.safeValue(response, 'openPositions');
|
|
1997
|
+
for (let i = 0; i < positions.length; i++) {
|
|
1998
|
+
const position = this.parsePosition(positions[i]);
|
|
1999
|
+
result.push(position);
|
|
2000
|
+
}
|
|
2001
|
+
return result;
|
|
2002
|
+
}
|
|
2003
|
+
parsePosition(position, market = undefined) {
|
|
2004
|
+
// cross
|
|
2005
|
+
// {
|
|
2006
|
+
// "side": "long",
|
|
2007
|
+
// "symbol": "pi_xrpusd",
|
|
2008
|
+
// "price": "0.7533",
|
|
2009
|
+
// "fillTime": "2022-03-03T22:51:16.566Z",
|
|
2010
|
+
// "size": "230",
|
|
2011
|
+
// "unrealizedFunding": "-0.001878596918214635"
|
|
2012
|
+
// }
|
|
2013
|
+
//
|
|
2014
|
+
// isolated
|
|
2015
|
+
// {
|
|
2016
|
+
// "side":"long",
|
|
2017
|
+
// "symbol":"pf_ftmusd",
|
|
2018
|
+
// "price":"0.4921",
|
|
2019
|
+
// "fillTime":"2023-02-22T11:37:16.685Z",
|
|
2020
|
+
// "size":"1",
|
|
2021
|
+
// "unrealizedFunding":"-8.155240068885155E-8",
|
|
2022
|
+
// "pnlCurrency":"USD",
|
|
2023
|
+
// "maxFixedLeverage":"1.0"
|
|
2024
|
+
// }
|
|
2025
|
+
//
|
|
2026
|
+
const leverage = this.safeNumber(position, 'maxFixedLeverage');
|
|
2027
|
+
let marginType = 'cross';
|
|
2028
|
+
if (leverage !== undefined) {
|
|
2029
|
+
marginType = 'isolated';
|
|
2030
|
+
}
|
|
2031
|
+
const datetime = this.safeString(position, 'fillTime');
|
|
2032
|
+
const marketId = this.safeString(position, 'symbol');
|
|
2033
|
+
market = this.safeMarket(marketId, market);
|
|
2034
|
+
return {
|
|
2035
|
+
'info': position,
|
|
2036
|
+
'symbol': market['symbol'],
|
|
2037
|
+
'timestamp': this.parse8601(datetime),
|
|
2038
|
+
'datetime': datetime,
|
|
2039
|
+
'initialMargin': undefined,
|
|
2040
|
+
'initialMarginPercentage': undefined,
|
|
2041
|
+
'maintenanceMargin': undefined,
|
|
2042
|
+
'maintenanceMarginPercentage': undefined,
|
|
2043
|
+
'entryPrice': this.safeNumber(position, 'price'),
|
|
2044
|
+
'notional': undefined,
|
|
2045
|
+
'leverage': leverage,
|
|
2046
|
+
'unrealizedPnl': undefined,
|
|
2047
|
+
'contracts': this.safeNumber(position, 'size'),
|
|
2048
|
+
'contractSize': this.safeNumber(market, 'contractSize'),
|
|
2049
|
+
'marginRatio': undefined,
|
|
2050
|
+
'liquidationPrice': undefined,
|
|
2051
|
+
'markPrice': undefined,
|
|
2052
|
+
'collateral': undefined,
|
|
2053
|
+
'marginType': marginType,
|
|
2054
|
+
'side': this.safeString(position, 'side'),
|
|
2055
|
+
'percentage': undefined,
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
async fetchLeverageTiers(symbols = undefined, params = {}) {
|
|
2059
|
+
/**
|
|
2060
|
+
* @method
|
|
2061
|
+
* @name krakenfutures#fetchLeverageTiers
|
|
2062
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-instrument-details-get-instruments
|
|
2063
|
+
* @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
|
|
2064
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
2065
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2066
|
+
* @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols
|
|
2067
|
+
*/
|
|
2068
|
+
await this.loadMarkets();
|
|
2069
|
+
const response = await this.publicGetInstruments(params);
|
|
2070
|
+
//
|
|
2071
|
+
// {
|
|
2072
|
+
// "result": "success",
|
|
2073
|
+
// "instruments": [
|
|
2074
|
+
// {
|
|
2075
|
+
// "symbol": "fi_ethusd_180928",
|
|
2076
|
+
// "type": "futures_inverse", // futures_vanilla // spot index
|
|
2077
|
+
// "underlying": "rr_ethusd",
|
|
2078
|
+
// "lastTradingTime": "2018-09-28T15:00:00.000Z",
|
|
2079
|
+
// "tickSize": 0.1,
|
|
2080
|
+
// "contractSize": 1,
|
|
2081
|
+
// "tradeable": true,
|
|
2082
|
+
// "marginLevels": [
|
|
2083
|
+
// {
|
|
2084
|
+
// "contracts":0,
|
|
2085
|
+
// "initialMargin":0.02,
|
|
2086
|
+
// "maintenanceMargin":0.01
|
|
2087
|
+
// },
|
|
2088
|
+
// {
|
|
2089
|
+
// "contracts":250000,
|
|
2090
|
+
// "initialMargin":0.04,
|
|
2091
|
+
// "maintenanceMargin":0.02
|
|
2092
|
+
// },
|
|
2093
|
+
// ...
|
|
2094
|
+
// ],
|
|
2095
|
+
// "isin": "GB00JVMLMP88",
|
|
2096
|
+
// "retailMarginLevels": [
|
|
2097
|
+
// {
|
|
2098
|
+
// "contracts": 0,
|
|
2099
|
+
// "initialMargin": 0.5,
|
|
2100
|
+
// "maintenanceMargin": 0.25
|
|
2101
|
+
// }
|
|
2102
|
+
// ],
|
|
2103
|
+
// "tags": [],
|
|
2104
|
+
// },
|
|
2105
|
+
// {
|
|
2106
|
+
// "symbol": "in_xbtusd",
|
|
2107
|
+
// "type": "spot index",
|
|
2108
|
+
// "tradeable":false
|
|
2109
|
+
// }
|
|
2110
|
+
// ]
|
|
2111
|
+
// "serverTime": "2018-07-19T11:32:39.433Z"
|
|
2112
|
+
// }
|
|
2113
|
+
//
|
|
2114
|
+
const data = this.safeValue(response, 'instruments');
|
|
2115
|
+
return this.parseLeverageTiers(data, symbols, 'symbol');
|
|
2116
|
+
}
|
|
2117
|
+
parseMarketLeverageTiers(info, market = undefined) {
|
|
2118
|
+
/**
|
|
2119
|
+
* @method
|
|
2120
|
+
* @ignore
|
|
2121
|
+
* @param info Exchange market response for 1 market
|
|
2122
|
+
* @param market CCXT market
|
|
2123
|
+
*/
|
|
2124
|
+
//
|
|
2125
|
+
// {
|
|
2126
|
+
// "symbol": "fi_ethusd_180928",
|
|
2127
|
+
// "type": "futures_inverse", // futures_vanilla // spot index
|
|
2128
|
+
// "underlying": "rr_ethusd",
|
|
2129
|
+
// "lastTradingTime": "2018-09-28T15:00:00.000Z",
|
|
2130
|
+
// "tickSize": 0.1,
|
|
2131
|
+
// "contractSize": 1,
|
|
2132
|
+
// "tradeable": true,
|
|
2133
|
+
// "marginLevels": [
|
|
2134
|
+
// {
|
|
2135
|
+
// "contracts":0,
|
|
2136
|
+
// "initialMargin":0.02,
|
|
2137
|
+
// "maintenanceMargin":0.01
|
|
2138
|
+
// },
|
|
2139
|
+
// {
|
|
2140
|
+
// "contracts":250000,
|
|
2141
|
+
// "initialMargin":0.04,
|
|
2142
|
+
// "maintenanceMargin":0.02
|
|
2143
|
+
// },
|
|
2144
|
+
// ...
|
|
2145
|
+
// ],
|
|
2146
|
+
// "isin": "GB00JVMLMP88",
|
|
2147
|
+
// "retailMarginLevels": [
|
|
2148
|
+
// {
|
|
2149
|
+
// "contracts": 0,
|
|
2150
|
+
// "initialMargin": 0.5,
|
|
2151
|
+
// "maintenanceMargin": 0.25
|
|
2152
|
+
// }
|
|
2153
|
+
// ],
|
|
2154
|
+
// "tags": [],
|
|
2155
|
+
// }
|
|
2156
|
+
//
|
|
2157
|
+
const marginLevels = this.safeValue(info, 'marginLevels');
|
|
2158
|
+
const id = this.safeString(info, 'symbol');
|
|
2159
|
+
market = this.safeMarket(id, market);
|
|
2160
|
+
const tiers = [];
|
|
2161
|
+
for (let i = 0; i < marginLevels.length; i++) {
|
|
2162
|
+
const tier = marginLevels[i];
|
|
2163
|
+
const initialMargin = this.safeString(tier, 'initialMargin');
|
|
2164
|
+
const notionalFloor = this.safeNumber(tier, 'contracts');
|
|
2165
|
+
if (i !== 0) {
|
|
2166
|
+
const tiersLength = tiers.length;
|
|
2167
|
+
const previousTier = tiers[tiersLength - 1];
|
|
2168
|
+
previousTier['notionalCap'] = notionalFloor;
|
|
2169
|
+
}
|
|
2170
|
+
tiers.push({
|
|
2171
|
+
'tier': this.sum(i, 1),
|
|
2172
|
+
'currency': market['quote'],
|
|
2173
|
+
'notionalFloor': notionalFloor,
|
|
2174
|
+
'notionalCap': undefined,
|
|
2175
|
+
'maintenanceMarginRate': this.safeNumber(tier, 'maintenanceMargin'),
|
|
2176
|
+
'maxLeverage': this.parseNumber(Precise["default"].stringDiv('1', initialMargin)),
|
|
2177
|
+
'info': tier,
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
return tiers;
|
|
2181
|
+
}
|
|
2182
|
+
parseTransfer(transfer, currency = undefined) {
|
|
2183
|
+
//
|
|
2184
|
+
// transfer
|
|
2185
|
+
//
|
|
2186
|
+
// {
|
|
2187
|
+
// "result": "success",
|
|
2188
|
+
// "serverTime": "2022-04-12T01:22:53.420Z"
|
|
2189
|
+
// }
|
|
2190
|
+
//
|
|
2191
|
+
const datetime = this.safeString(transfer, 'serverTime');
|
|
2192
|
+
return {
|
|
2193
|
+
'info': transfer,
|
|
2194
|
+
'id': undefined,
|
|
2195
|
+
'timestamp': this.parse8601(datetime),
|
|
2196
|
+
'datetime': datetime,
|
|
2197
|
+
'currency': this.safeString(currency, 'code'),
|
|
2198
|
+
'amount': undefined,
|
|
2199
|
+
'fromAccount': undefined,
|
|
2200
|
+
'toAccount': undefined,
|
|
2201
|
+
'status': this.safeString(transfer, 'result'),
|
|
2202
|
+
};
|
|
2203
|
+
}
|
|
2204
|
+
parseAccount(account) {
|
|
2205
|
+
const accountByType = {
|
|
2206
|
+
'main': 'cash',
|
|
2207
|
+
'funding': 'cash',
|
|
2208
|
+
'future': 'cash',
|
|
2209
|
+
'futures': 'cash',
|
|
2210
|
+
'cashAccount': 'cash',
|
|
2211
|
+
'multiCollateralMarginAccount': 'flex',
|
|
2212
|
+
'multiCollateral': 'flex',
|
|
2213
|
+
'multiCollateralMargin': 'flex',
|
|
2214
|
+
};
|
|
2215
|
+
if (account in accountByType) {
|
|
2216
|
+
return accountByType[account];
|
|
2217
|
+
}
|
|
2218
|
+
else if (account in this.markets) {
|
|
2219
|
+
const market = this.market(account);
|
|
2220
|
+
const marketId = market['id'];
|
|
2221
|
+
const splitId = marketId.split('_');
|
|
2222
|
+
if (market['inverse']) {
|
|
2223
|
+
return 'fi_' + this.safeString(splitId, 1);
|
|
2224
|
+
}
|
|
2225
|
+
else {
|
|
2226
|
+
return 'fv_' + this.safeString(splitId, 1);
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
else {
|
|
2230
|
+
return account;
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
async transferOut(code, amount, params = {}) {
|
|
2234
|
+
/**
|
|
2235
|
+
* @description transfer from futures wallet to spot wallet
|
|
2236
|
+
* @param {str} code Unified currency code
|
|
2237
|
+
* @param {float} amount Size of the transfer
|
|
2238
|
+
* @param {dict} [params] Exchange specific parameters
|
|
2239
|
+
* @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
2240
|
+
*/
|
|
2241
|
+
return await this.transfer(code, amount, 'future', 'spot', params);
|
|
2242
|
+
}
|
|
2243
|
+
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
2244
|
+
/**
|
|
2245
|
+
* @method
|
|
2246
|
+
* @name krakenfutures#transfer
|
|
2247
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-transfers-initiate-wallet-transfer
|
|
2248
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-transfers-initiate-withdrawal-to-spot-wallet
|
|
2249
|
+
* @description transfers currencies between sub-accounts
|
|
2250
|
+
* @param {string} code Unified currency code
|
|
2251
|
+
* @param {float} amount Size of the transfer
|
|
2252
|
+
* @param {string} fromAccount 'main'/'funding'/'future', 'flex', or a unified market symbol
|
|
2253
|
+
* @param {string} toAccount 'main'/'funding', 'flex', 'spot' or a unified market symbol
|
|
2254
|
+
* @param {object} [params] Exchange specific parameters
|
|
2255
|
+
* @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
2256
|
+
*/
|
|
2257
|
+
await this.loadMarkets();
|
|
2258
|
+
const currency = this.currency(code);
|
|
2259
|
+
if (fromAccount === 'spot') {
|
|
2260
|
+
throw new errors.BadRequest(this.id + ' transfer does not yet support transfers from spot');
|
|
2261
|
+
}
|
|
2262
|
+
const request = {
|
|
2263
|
+
'amount': amount,
|
|
2264
|
+
};
|
|
2265
|
+
let response = undefined;
|
|
2266
|
+
if (toAccount === 'spot') {
|
|
2267
|
+
if (this.parseAccount(fromAccount) !== 'cash') {
|
|
2268
|
+
throw new errors.BadRequest(this.id + ' transfer cannot transfer from ' + fromAccount + ' to ' + toAccount);
|
|
2269
|
+
}
|
|
2270
|
+
request['currency'] = currency['id'];
|
|
2271
|
+
response = await this.privatePostWithdrawal(this.extend(request, params));
|
|
2272
|
+
}
|
|
2273
|
+
else {
|
|
2274
|
+
request['fromAccount'] = this.parseAccount(fromAccount);
|
|
2275
|
+
request['toAccount'] = this.parseAccount(toAccount);
|
|
2276
|
+
request['unit'] = currency['id'];
|
|
2277
|
+
response = await this.privatePostTransfer(this.extend(request, params));
|
|
2278
|
+
}
|
|
2279
|
+
//
|
|
2280
|
+
// {
|
|
2281
|
+
// "result": "success",
|
|
2282
|
+
// "serverTime": "2022-04-12T01:22:53.420Z"
|
|
2283
|
+
// }
|
|
2284
|
+
//
|
|
2285
|
+
const transfer = this.parseTransfer(response, currency);
|
|
2286
|
+
return this.extend(transfer, {
|
|
2287
|
+
'amount': amount,
|
|
2288
|
+
'fromAccount': fromAccount,
|
|
2289
|
+
'toAccount': toAccount,
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
async setLeverage(leverage, symbol = undefined, params = {}) {
|
|
2293
|
+
/**
|
|
2294
|
+
* @method
|
|
2295
|
+
* @name krakenfutures#setLeverage
|
|
2296
|
+
* @description set the level of leverage for a market
|
|
2297
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-multi-collateral-set-the-leverage-setting-for-a-market
|
|
2298
|
+
* @param {float} leverage the rate of leverage
|
|
2299
|
+
* @param {string} symbol unified market symbol
|
|
2300
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2301
|
+
* @returns {object} response from the exchange
|
|
2302
|
+
*/
|
|
2303
|
+
if (symbol === undefined) {
|
|
2304
|
+
throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
|
|
2305
|
+
}
|
|
2306
|
+
await this.loadMarkets();
|
|
2307
|
+
const request = {
|
|
2308
|
+
'maxLeverage': leverage,
|
|
2309
|
+
'symbol': this.marketId(symbol).toUpperCase(),
|
|
2310
|
+
};
|
|
2311
|
+
//
|
|
2312
|
+
// { result: "success", serverTime: "2023-08-01T09:40:32.345Z" }
|
|
2313
|
+
//
|
|
2314
|
+
return await this.privatePutLeveragepreferences(this.extend(request, params));
|
|
2315
|
+
}
|
|
2316
|
+
async fetchLeverage(symbol = undefined, params = {}) {
|
|
2317
|
+
/**
|
|
2318
|
+
* @method
|
|
2319
|
+
* @name krakenfutures#fetchLeverage
|
|
2320
|
+
* @description fetch the set leverage for a market
|
|
2321
|
+
* @see https://docs.futures.kraken.com/#http-api-trading-v3-api-multi-collateral-get-the-leverage-setting-for-a-market
|
|
2322
|
+
* @param {string} symbol unified market symbol
|
|
2323
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2324
|
+
* @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
|
|
2325
|
+
*/
|
|
2326
|
+
if (symbol === undefined) {
|
|
2327
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchLeverage() requires a symbol argument');
|
|
2328
|
+
}
|
|
2329
|
+
await this.loadMarkets();
|
|
2330
|
+
const request = {
|
|
2331
|
+
'symbol': this.marketId(symbol).toUpperCase(),
|
|
2332
|
+
};
|
|
2333
|
+
//
|
|
2334
|
+
// {
|
|
2335
|
+
// "result": "success",
|
|
2336
|
+
// "serverTime": "2023-08-01T09:54:08.900Z",
|
|
2337
|
+
// "leveragePreferences": [ { symbol: "PF_LTCUSD", maxLeverage: "5.00" } ]
|
|
2338
|
+
// }
|
|
2339
|
+
//
|
|
2340
|
+
return await this.privateGetLeveragepreferences(this.extend(request, params));
|
|
2341
|
+
}
|
|
2342
|
+
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
2343
|
+
if (response === undefined) {
|
|
2344
|
+
return undefined;
|
|
2345
|
+
}
|
|
2346
|
+
if (code === 429) {
|
|
2347
|
+
throw new errors.DDoSProtection(this.id + ' ' + body);
|
|
2348
|
+
}
|
|
2349
|
+
const errors$1 = this.safeValue(response, 'errors');
|
|
2350
|
+
const firstError = this.safeValue(errors$1, 0);
|
|
2351
|
+
const firtErrorMessage = this.safeString(firstError, 'message');
|
|
2352
|
+
const message = this.safeString(response, 'error', firtErrorMessage);
|
|
2353
|
+
if (message === undefined) {
|
|
2354
|
+
return undefined;
|
|
2355
|
+
}
|
|
2356
|
+
const feedback = this.id + ' ' + body;
|
|
2357
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
2358
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
2359
|
+
if (code === 400) {
|
|
2360
|
+
throw new errors.BadRequest(feedback);
|
|
2361
|
+
}
|
|
2362
|
+
throw new errors.ExchangeError(feedback); // unknown message
|
|
2363
|
+
}
|
|
2364
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
2365
|
+
const apiVersions = this.safeValue(this.options['versions'], api, {});
|
|
2366
|
+
const methodVersions = this.safeValue(apiVersions, method, {});
|
|
2367
|
+
const defaultVersion = this.safeString(methodVersions, path, this.version);
|
|
2368
|
+
const version = this.safeString(params, 'version', defaultVersion);
|
|
2369
|
+
params = this.omit(params, 'version');
|
|
2370
|
+
const apiAccess = this.safeValue(this.options['access'], api, {});
|
|
2371
|
+
const methodAccess = this.safeValue(apiAccess, method, {});
|
|
2372
|
+
const access = this.safeString(methodAccess, path, 'public');
|
|
2373
|
+
const endpoint = version + '/' + this.implodeParams(path, params);
|
|
2374
|
+
params = this.omit(params, this.extractParams(path));
|
|
2375
|
+
let query = endpoint;
|
|
2376
|
+
let postData = '';
|
|
2377
|
+
if (path === 'batchorder') {
|
|
2378
|
+
postData = 'json=' + this.json(params);
|
|
2379
|
+
body = postData;
|
|
2380
|
+
}
|
|
2381
|
+
else if (Object.keys(params).length) {
|
|
2382
|
+
postData = this.urlencode(params);
|
|
2383
|
+
query += '?' + postData;
|
|
2384
|
+
}
|
|
2385
|
+
const url = this.urls['api'][api] + query;
|
|
2386
|
+
if (api === 'private' || access === 'private') {
|
|
2387
|
+
this.checkRequiredCredentials();
|
|
2388
|
+
let auth = postData + '/api/';
|
|
2389
|
+
if (api !== 'private') {
|
|
2390
|
+
auth += api + '/';
|
|
2391
|
+
}
|
|
2392
|
+
auth += endpoint; // 1
|
|
2393
|
+
const hash = this.hash(this.encode(auth), sha256.sha256, 'binary'); // 2
|
|
2394
|
+
const secret = this.base64ToBinary(this.secret); // 3
|
|
2395
|
+
const signature = this.hmac(hash, secret, sha512.sha512, 'base64'); // 4-5
|
|
2396
|
+
headers = {
|
|
2397
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
2398
|
+
'Accept': 'application/json',
|
|
2399
|
+
'APIKey': this.apiKey,
|
|
2400
|
+
'Authent': signature,
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
module.exports = krakenfutures;
|