ccxt 4.2.11 → 4.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/build.sh +2 -2
- package/dist/ccxt.browser.js +1347 -490
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/_virtual/agent.js +7 -0
- package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
- package/dist/cjs/_virtual/promisify.js +7 -0
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/js/ccxt.js +474 -0
- package/dist/cjs/js/src/abstract/ace.js +9 -0
- package/dist/cjs/js/src/abstract/alpaca.js +9 -0
- package/dist/cjs/js/src/abstract/ascendex.js +9 -0
- package/dist/cjs/js/src/abstract/bigone.js +9 -0
- package/dist/cjs/js/src/abstract/binance.js +9 -0
- package/dist/cjs/js/src/abstract/bingx.js +9 -0
- package/dist/cjs/js/src/abstract/bit2c.js +9 -0
- package/dist/cjs/js/src/abstract/bitbank.js +9 -0
- package/dist/cjs/js/src/abstract/bitbns.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
- package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
- package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
- package/dist/cjs/js/src/abstract/bitforex.js +9 -0
- package/dist/cjs/js/src/abstract/bitget.js +9 -0
- package/dist/cjs/js/src/abstract/bithumb.js +9 -0
- package/dist/cjs/js/src/abstract/bitmart.js +9 -0
- package/dist/cjs/js/src/abstract/bitmex.js +9 -0
- package/dist/cjs/js/src/abstract/bitopro.js +9 -0
- package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
- package/dist/cjs/js/src/abstract/bitrue.js +9 -0
- package/dist/cjs/js/src/abstract/bitso.js +9 -0
- package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
- package/dist/cjs/js/src/abstract/bitteam.js +9 -0
- package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
- package/dist/cjs/js/src/abstract/bl3p.js +9 -0
- package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
- package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
- package/dist/cjs/js/src/abstract/btcbox.js +9 -0
- package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
- package/dist/cjs/js/src/abstract/btcturk.js +9 -0
- package/dist/cjs/js/src/abstract/bybit.js +9 -0
- package/dist/cjs/js/src/abstract/cex.js +9 -0
- package/dist/cjs/js/src/abstract/coinbase.js +9 -0
- package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
- package/dist/cjs/js/src/abstract/coincheck.js +9 -0
- package/dist/cjs/js/src/abstract/coinex.js +9 -0
- package/dist/cjs/js/src/abstract/coinlist.js +9 -0
- package/dist/cjs/js/src/abstract/coinmate.js +9 -0
- package/dist/cjs/js/src/abstract/coinone.js +9 -0
- package/dist/cjs/js/src/abstract/coinsph.js +9 -0
- package/dist/cjs/js/src/abstract/coinspot.js +9 -0
- package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
- package/dist/cjs/js/src/abstract/currencycom.js +9 -0
- package/dist/cjs/js/src/abstract/delta.js +9 -0
- package/dist/cjs/js/src/abstract/deribit.js +9 -0
- package/dist/cjs/js/src/abstract/digifinex.js +9 -0
- package/dist/cjs/js/src/abstract/exmo.js +9 -0
- package/dist/cjs/js/src/abstract/gate.js +9 -0
- package/dist/cjs/js/src/abstract/gemini.js +9 -0
- package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
- package/dist/cjs/js/src/abstract/hollaex.js +9 -0
- package/dist/cjs/js/src/abstract/htx.js +9 -0
- package/dist/cjs/js/src/abstract/huobijp.js +9 -0
- package/dist/cjs/js/src/abstract/idex.js +9 -0
- package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
- package/dist/cjs/js/src/abstract/indodax.js +9 -0
- package/dist/cjs/js/src/abstract/kraken.js +9 -0
- package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kucoin.js +9 -0
- package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
- package/dist/cjs/js/src/abstract/kuna.js +9 -0
- package/dist/cjs/js/src/abstract/latoken.js +9 -0
- package/dist/cjs/js/src/abstract/lbank.js +9 -0
- package/dist/cjs/js/src/abstract/luno.js +9 -0
- package/dist/cjs/js/src/abstract/lykke.js +9 -0
- package/dist/cjs/js/src/abstract/mercado.js +9 -0
- package/dist/cjs/js/src/abstract/mexc.js +9 -0
- package/dist/cjs/js/src/abstract/ndax.js +9 -0
- package/dist/cjs/js/src/abstract/novadax.js +9 -0
- package/dist/cjs/js/src/abstract/oceanex.js +9 -0
- package/dist/cjs/js/src/abstract/okcoin.js +9 -0
- package/dist/cjs/js/src/abstract/okx.js +9 -0
- package/dist/cjs/js/src/abstract/p2b.js +9 -0
- package/dist/cjs/js/src/abstract/paymium.js +9 -0
- package/dist/cjs/js/src/abstract/phemex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniex.js +9 -0
- package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
- package/dist/cjs/js/src/abstract/probit.js +9 -0
- package/dist/cjs/js/src/abstract/timex.js +9 -0
- package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
- package/dist/cjs/js/src/abstract/upbit.js +9 -0
- package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
- package/dist/cjs/js/src/abstract/wazirx.js +9 -0
- package/dist/cjs/js/src/abstract/whitebit.js +9 -0
- package/dist/cjs/js/src/abstract/woo.js +9 -0
- package/dist/cjs/js/src/abstract/yobit.js +9 -0
- package/dist/cjs/js/src/abstract/zaif.js +9 -0
- package/dist/cjs/js/src/abstract/zonda.js +9 -0
- package/dist/cjs/js/src/ace.js +1058 -0
- package/dist/cjs/js/src/alpaca.js +1125 -0
- package/dist/cjs/js/src/ascendex.js +3360 -0
- package/dist/cjs/js/src/base/Exchange.js +5110 -0
- package/dist/cjs/js/src/base/Precise.js +263 -0
- package/dist/cjs/js/src/base/errors.js +299 -0
- package/dist/cjs/js/src/base/functions/crypto.js +78 -0
- package/dist/cjs/js/src/base/functions/encode.js +44 -0
- package/dist/cjs/js/src/base/functions/generic.js +193 -0
- package/dist/cjs/js/src/base/functions/misc.js +96 -0
- package/dist/cjs/js/src/base/functions/number.js +297 -0
- package/dist/cjs/js/src/base/functions/platform.js +28 -0
- package/dist/cjs/js/src/base/functions/rsa.js +34 -0
- package/dist/cjs/js/src/base/functions/string.js +48 -0
- package/dist/cjs/js/src/base/functions/throttle.js +66 -0
- package/dist/cjs/js/src/base/functions/time.js +187 -0
- package/dist/cjs/js/src/base/functions/totp.js +24 -0
- package/dist/cjs/js/src/base/functions/type.js +162 -0
- package/dist/cjs/js/src/base/functions.js +157 -0
- package/dist/cjs/js/src/base/ws/Cache.js +254 -0
- package/dist/cjs/js/src/base/ws/Client.js +299 -0
- package/dist/cjs/js/src/base/ws/Future.js +34 -0
- package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
- package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
- package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
- package/dist/cjs/js/src/bequant.js +33 -0
- package/dist/cjs/js/src/bigone.js +2209 -0
- package/dist/cjs/js/src/binance.js +9736 -0
- package/dist/cjs/js/src/binancecoinm.js +45 -0
- package/dist/cjs/js/src/binanceus.js +84 -0
- package/dist/cjs/js/src/binanceusdm.js +58 -0
- package/dist/cjs/js/src/bingx.js +3807 -0
- package/dist/cjs/js/src/bit2c.js +916 -0
- package/dist/cjs/js/src/bitbank.js +1000 -0
- package/dist/cjs/js/src/bitbay.js +17 -0
- package/dist/cjs/js/src/bitbns.js +1220 -0
- package/dist/cjs/js/src/bitcoincom.js +17 -0
- package/dist/cjs/js/src/bitfinex.js +1670 -0
- package/dist/cjs/js/src/bitfinex2.js +2990 -0
- package/dist/cjs/js/src/bitflyer.js +1045 -0
- package/dist/cjs/js/src/bitforex.js +852 -0
- package/dist/cjs/js/src/bitget.js +8291 -0
- package/dist/cjs/js/src/bithumb.js +1090 -0
- package/dist/cjs/js/src/bitmart.js +4454 -0
- package/dist/cjs/js/src/bitmex.js +2884 -0
- package/dist/cjs/js/src/bitopro.js +1724 -0
- package/dist/cjs/js/src/bitpanda.js +2002 -0
- package/dist/cjs/js/src/bitrue.js +3253 -0
- package/dist/cjs/js/src/bitso.js +1753 -0
- package/dist/cjs/js/src/bitstamp.js +2188 -0
- package/dist/cjs/js/src/bitteam.js +2309 -0
- package/dist/cjs/js/src/bitvavo.js +1968 -0
- package/dist/cjs/js/src/bl3p.js +447 -0
- package/dist/cjs/js/src/blockchaincom.js +1160 -0
- package/dist/cjs/js/src/btcalpha.js +929 -0
- package/dist/cjs/js/src/btcbox.js +565 -0
- package/dist/cjs/js/src/btcmarkets.js +1237 -0
- package/dist/cjs/js/src/btcturk.js +929 -0
- package/dist/cjs/js/src/bybit.js +7646 -0
- package/dist/cjs/js/src/cex.js +1693 -0
- package/dist/cjs/js/src/coinbase.js +3424 -0
- package/dist/cjs/js/src/coinbasepro.js +1866 -0
- package/dist/cjs/js/src/coincheck.js +843 -0
- package/dist/cjs/js/src/coinex.js +5414 -0
- package/dist/cjs/js/src/coinlist.js +2329 -0
- package/dist/cjs/js/src/coinmate.js +989 -0
- package/dist/cjs/js/src/coinone.js +1185 -0
- package/dist/cjs/js/src/coinsph.js +1933 -0
- package/dist/cjs/js/src/coinspot.js +548 -0
- package/dist/cjs/js/src/cryptocom.js +3007 -0
- package/dist/cjs/js/src/currencycom.js +2015 -0
- package/dist/cjs/js/src/delta.js +3256 -0
- package/dist/cjs/js/src/deribit.js +3306 -0
- package/dist/cjs/js/src/digifinex.js +4307 -0
- package/dist/cjs/js/src/exmo.js +2645 -0
- package/dist/cjs/js/src/fmfwio.js +34 -0
- package/dist/cjs/js/src/gate.js +7072 -0
- package/dist/cjs/js/src/gateio.js +16 -0
- package/dist/cjs/js/src/gemini.js +1801 -0
- package/dist/cjs/js/src/hitbtc.js +3660 -0
- package/dist/cjs/js/src/hitbtc3.js +19 -0
- package/dist/cjs/js/src/hollaex.js +1882 -0
- package/dist/cjs/js/src/htx.js +9049 -0
- package/dist/cjs/js/src/huobi.js +16 -0
- package/dist/cjs/js/src/huobijp.js +1918 -0
- package/dist/cjs/js/src/idex.js +1770 -0
- package/dist/cjs/js/src/independentreserve.js +761 -0
- package/dist/cjs/js/src/indodax.js +1069 -0
- package/dist/cjs/js/src/kraken.js +2857 -0
- package/dist/cjs/js/src/krakenfutures.js +2407 -0
- package/dist/cjs/js/src/kucoin.js +4489 -0
- package/dist/cjs/js/src/kucoinfutures.js +2475 -0
- package/dist/cjs/js/src/kuna.js +1949 -0
- package/dist/cjs/js/src/latoken.js +1729 -0
- package/dist/cjs/js/src/lbank.js +2851 -0
- package/dist/cjs/js/src/luno.js +1044 -0
- package/dist/cjs/js/src/lykke.js +1303 -0
- package/dist/cjs/js/src/mercado.js +897 -0
- package/dist/cjs/js/src/mexc.js +5407 -0
- package/dist/cjs/js/src/ndax.js +2450 -0
- package/dist/cjs/js/src/novadax.js +1556 -0
- package/dist/cjs/js/src/oceanex.js +964 -0
- package/dist/cjs/js/src/okcoin.js +3115 -0
- package/dist/cjs/js/src/okx.js +7330 -0
- package/dist/cjs/js/src/p2b.js +1243 -0
- package/dist/cjs/js/src/paymium.js +597 -0
- package/dist/cjs/js/src/phemex.js +4722 -0
- package/dist/cjs/js/src/poloniex.js +2356 -0
- package/dist/cjs/js/src/poloniexfutures.js +1794 -0
- package/dist/cjs/js/src/pro/alpaca.js +714 -0
- package/dist/cjs/js/src/pro/ascendex.js +957 -0
- package/dist/cjs/js/src/pro/bequant.js +33 -0
- package/dist/cjs/js/src/pro/binance.js +2796 -0
- package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
- package/dist/cjs/js/src/pro/binanceus.js +51 -0
- package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
- package/dist/cjs/js/src/pro/bingx.js +944 -0
- package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
- package/dist/cjs/js/src/pro/bitfinex.js +672 -0
- package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
- package/dist/cjs/js/src/pro/bitget.js +1733 -0
- package/dist/cjs/js/src/pro/bitmart.js +1486 -0
- package/dist/cjs/js/src/pro/bitmex.js +1576 -0
- package/dist/cjs/js/src/pro/bitopro.js +327 -0
- package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
- package/dist/cjs/js/src/pro/bitrue.js +462 -0
- package/dist/cjs/js/src/pro/bitstamp.js +547 -0
- package/dist/cjs/js/src/pro/bitvavo.js +704 -0
- package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
- package/dist/cjs/js/src/pro/bybit.js +1843 -0
- package/dist/cjs/js/src/pro/cex.js +1510 -0
- package/dist/cjs/js/src/pro/coinbase.js +561 -0
- package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
- package/dist/cjs/js/src/pro/coinex.js +1095 -0
- package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
- package/dist/cjs/js/src/pro/currencycom.js +563 -0
- package/dist/cjs/js/src/pro/deribit.js +825 -0
- package/dist/cjs/js/src/pro/exmo.js +658 -0
- package/dist/cjs/js/src/pro/gate.js +1316 -0
- package/dist/cjs/js/src/pro/gateio.js +16 -0
- package/dist/cjs/js/src/pro/gemini.js +649 -0
- package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
- package/dist/cjs/js/src/pro/hollaex.js +597 -0
- package/dist/cjs/js/src/pro/htx.js +2383 -0
- package/dist/cjs/js/src/pro/huobi.js +16 -0
- package/dist/cjs/js/src/pro/huobijp.js +606 -0
- package/dist/cjs/js/src/pro/idex.js +714 -0
- package/dist/cjs/js/src/pro/independentreserve.js +280 -0
- package/dist/cjs/js/src/pro/kraken.js +1364 -0
- package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
- package/dist/cjs/js/src/pro/kucoin.js +1052 -0
- package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
- package/dist/cjs/js/src/pro/luno.js +322 -0
- package/dist/cjs/js/src/pro/mexc.js +1170 -0
- package/dist/cjs/js/src/pro/ndax.js +545 -0
- package/dist/cjs/js/src/pro/okcoin.js +760 -0
- package/dist/cjs/js/src/pro/okx.js +1608 -0
- package/dist/cjs/js/src/pro/phemex.js +1511 -0
- package/dist/cjs/js/src/pro/poloniex.js +1253 -0
- package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
- package/dist/cjs/js/src/pro/probit.js +586 -0
- package/dist/cjs/js/src/pro/upbit.js +234 -0
- package/dist/cjs/js/src/pro/wazirx.js +776 -0
- package/dist/cjs/js/src/pro/whitebit.js +927 -0
- package/dist/cjs/js/src/pro/woo.js +769 -0
- package/dist/cjs/js/src/probit.js +1867 -0
- package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
- package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
- package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
- package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
- package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
- package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
- package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
- package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
- package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
- package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
- package/dist/cjs/js/src/timex.js +1562 -0
- package/dist/cjs/js/src/tokocrypto.js +2542 -0
- package/dist/cjs/js/src/upbit.js +1844 -0
- package/dist/cjs/js/src/wavesexchange.js +2607 -0
- package/dist/cjs/js/src/wazirx.js +953 -0
- package/dist/cjs/js/src/whitebit.js +2309 -0
- package/dist/cjs/js/src/woo.js +2765 -0
- package/dist/cjs/js/src/yobit.js +1314 -0
- package/dist/cjs/js/src/zaif.js +736 -0
- package/dist/cjs/js/src/zonda.js +1883 -0
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bigone.d.ts +18 -0
- package/js/src/abstract/binance.d.ts +2 -0
- package/js/src/abstract/binancecoinm.d.ts +2 -0
- package/js/src/abstract/binanceus.d.ts +2 -0
- package/js/src/abstract/binanceusdm.d.ts +2 -0
- package/js/src/abstract/bingx.d.ts +2 -0
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/abstract/gate.d.ts +11 -0
- package/js/src/abstract/gateio.d.ts +11 -0
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/alpaca.js +18 -18
- package/js/src/base/Exchange.d.ts +5 -1
- package/js/src/base/Exchange.js +101 -12
- package/js/src/bigone.d.ts +3 -2
- package/js/src/bigone.js +429 -167
- package/js/src/binance.js +48 -34
- package/js/src/bingx.js +115 -38
- package/js/src/bitfinex.d.ts +2 -2
- package/js/src/bitfinex.js +2 -3
- package/js/src/bitget.js +33 -13
- package/js/src/bitmart.d.ts +2 -2
- package/js/src/bitmart.js +5 -5
- package/js/src/bitmex.js +1 -0
- package/js/src/bybit.js +2 -0
- package/js/src/coinbase.d.ts +26 -3
- package/js/src/coinbase.js +176 -26
- package/js/src/coinlist.js +3 -4
- package/js/src/coinone.js +1 -1
- package/js/src/coinsph.js +2 -3
- package/js/src/deribit.js +1 -0
- package/js/src/gate.d.ts +4 -4
- package/js/src/gate.js +96 -59
- package/js/src/gemini.js +1 -1
- package/js/src/hitbtc.d.ts +4 -4
- package/js/src/hitbtc.js +2 -3
- package/js/src/htx.d.ts +1 -0
- package/js/src/htx.js +29 -7
- package/js/src/huobijp.js +2 -3
- package/js/src/independentreserve.js +7 -5
- package/js/src/kraken.js +3 -6
- package/js/src/lbank.js +59 -33
- package/js/src/mexc.js +2 -1
- package/js/src/oceanex.js +1 -1
- package/js/src/okx.js +14 -3
- package/js/src/phemex.js +9 -2
- package/js/src/pro/binance.d.ts +2 -23
- package/js/src/pro/binance.js +58 -22
- package/js/src/pro/coinbase.d.ts +2 -2
- package/js/src/pro/coinbase.js +4 -1
- package/js/src/pro/coinbasepro.d.ts +2 -2
- package/js/src/pro/hitbtc.d.ts +2 -2
- package/js/src/pro/kraken.js +1 -1
- package/js/src/pro/okx.d.ts +1 -0
- package/js/src/pro/okx.js +52 -2
- package/js/src/pro/poloniex.d.ts +2 -2
- package/js/src/probit.js +4 -2
- package/js/src/upbit.d.ts +3 -101
- package/js/src/upbit.js +12 -12
- package/js/src/wavesexchange.js +1 -1
- package/js/src/woo.d.ts +2 -0
- package/js/src/woo.js +52 -0
- package/package.json +1 -1
- package/skip-tests.json +5 -0
|
@@ -0,0 +1,2990 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('./base/errors.js');
|
|
4
|
+
var Precise = require('./base/Precise.js');
|
|
5
|
+
var bitfinex2$1 = require('./abstract/bitfinex2.js');
|
|
6
|
+
var number = require('./base/functions/number.js');
|
|
7
|
+
var sha512 = require('./static_dependencies/noble-hashes/sha512.js');
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* @class bitfinex2
|
|
13
|
+
* @augments Exchange
|
|
14
|
+
*/
|
|
15
|
+
class bitfinex2 extends bitfinex2$1 {
|
|
16
|
+
describe() {
|
|
17
|
+
return this.deepExtend(super.describe(), {
|
|
18
|
+
'id': 'bitfinex2',
|
|
19
|
+
'name': 'Bitfinex',
|
|
20
|
+
'countries': ['VG'],
|
|
21
|
+
'version': 'v2',
|
|
22
|
+
'certified': false,
|
|
23
|
+
'pro': true,
|
|
24
|
+
// new metainfo interface
|
|
25
|
+
'has': {
|
|
26
|
+
'CORS': undefined,
|
|
27
|
+
'spot': true,
|
|
28
|
+
'margin': undefined,
|
|
29
|
+
'swap': undefined,
|
|
30
|
+
'future': undefined,
|
|
31
|
+
'option': undefined,
|
|
32
|
+
'cancelAllOrders': true,
|
|
33
|
+
'cancelOrder': true,
|
|
34
|
+
'createDepositAddress': true,
|
|
35
|
+
'createLimitOrder': true,
|
|
36
|
+
'createMarketOrder': true,
|
|
37
|
+
'createOrder': true,
|
|
38
|
+
'createStopLimitOrder': true,
|
|
39
|
+
'createStopMarketOrder': true,
|
|
40
|
+
'createStopOrder': true,
|
|
41
|
+
'editOrder': false,
|
|
42
|
+
'fetchBalance': true,
|
|
43
|
+
'fetchClosedOrder': true,
|
|
44
|
+
'fetchClosedOrders': true,
|
|
45
|
+
'fetchCurrencies': true,
|
|
46
|
+
'fetchDepositAddress': true,
|
|
47
|
+
'fetchDepositsWithdrawals': true,
|
|
48
|
+
'fetchFundingRate': true,
|
|
49
|
+
'fetchFundingRateHistory': true,
|
|
50
|
+
'fetchFundingRates': true,
|
|
51
|
+
'fetchIndexOHLCV': false,
|
|
52
|
+
'fetchLedger': true,
|
|
53
|
+
'fetchMarginMode': false,
|
|
54
|
+
'fetchMarkOHLCV': false,
|
|
55
|
+
'fetchMyTrades': true,
|
|
56
|
+
'fetchOHLCV': true,
|
|
57
|
+
'fetchOpenOrder': true,
|
|
58
|
+
'fetchOpenOrders': true,
|
|
59
|
+
'fetchOrder': true,
|
|
60
|
+
'fetchOrderTrades': true,
|
|
61
|
+
'fetchPositionMode': false,
|
|
62
|
+
'fetchStatus': true,
|
|
63
|
+
'fetchTickers': true,
|
|
64
|
+
'fetchTime': false,
|
|
65
|
+
'fetchTradingFee': false,
|
|
66
|
+
'fetchTradingFees': true,
|
|
67
|
+
'fetchTransactionFees': undefined,
|
|
68
|
+
'fetchTransactions': 'emulated',
|
|
69
|
+
'withdraw': true,
|
|
70
|
+
},
|
|
71
|
+
'timeframes': {
|
|
72
|
+
'1m': '1m',
|
|
73
|
+
'5m': '5m',
|
|
74
|
+
'15m': '15m',
|
|
75
|
+
'30m': '30m',
|
|
76
|
+
'1h': '1h',
|
|
77
|
+
'3h': '3h',
|
|
78
|
+
'4h': '4h',
|
|
79
|
+
'6h': '6h',
|
|
80
|
+
'12h': '12h',
|
|
81
|
+
'1d': '1D',
|
|
82
|
+
'1w': '7D',
|
|
83
|
+
'2w': '14D',
|
|
84
|
+
'1M': '1M',
|
|
85
|
+
},
|
|
86
|
+
// cheapest endpoint is 240 requests per minute => ~ 4 requests per second => ( 1000ms / 4 ) = 250ms between requests on average
|
|
87
|
+
'rateLimit': 250,
|
|
88
|
+
'urls': {
|
|
89
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/27766244-e328a50c-5ed2-11e7-947b-041416579bb3.jpg',
|
|
90
|
+
'api': {
|
|
91
|
+
'v1': 'https://api.bitfinex.com',
|
|
92
|
+
'public': 'https://api-pub.bitfinex.com',
|
|
93
|
+
'private': 'https://api.bitfinex.com',
|
|
94
|
+
},
|
|
95
|
+
'www': 'https://www.bitfinex.com',
|
|
96
|
+
'doc': [
|
|
97
|
+
'https://docs.bitfinex.com/v2/docs/',
|
|
98
|
+
'https://github.com/bitfinexcom/bitfinex-api-node',
|
|
99
|
+
],
|
|
100
|
+
'fees': 'https://www.bitfinex.com/fees',
|
|
101
|
+
},
|
|
102
|
+
'api': {
|
|
103
|
+
'public': {
|
|
104
|
+
'get': {
|
|
105
|
+
'conf/{config}': 2.66,
|
|
106
|
+
'conf/pub:{action}:{object}': 2.66,
|
|
107
|
+
'conf/pub:{action}:{object}:{detail}': 2.66,
|
|
108
|
+
'conf/pub:map:{object}': 2.66,
|
|
109
|
+
'conf/pub:map:{object}:{detail}': 2.66,
|
|
110
|
+
'conf/pub:map:currency:{detail}': 2.66,
|
|
111
|
+
'conf/pub:map:currency:sym': 2.66,
|
|
112
|
+
'conf/pub:map:currency:label': 2.66,
|
|
113
|
+
'conf/pub:map:currency:unit': 2.66,
|
|
114
|
+
'conf/pub:map:currency:undl': 2.66,
|
|
115
|
+
'conf/pub:map:currency:pool': 2.66,
|
|
116
|
+
'conf/pub:map:currency:explorer': 2.66,
|
|
117
|
+
'conf/pub:map:currency:tx:fee': 2.66,
|
|
118
|
+
'conf/pub:map:tx:method': 2.66,
|
|
119
|
+
'conf/pub:list:{object}': 2.66,
|
|
120
|
+
'conf/pub:list:{object}:{detail}': 2.66,
|
|
121
|
+
'conf/pub:list:currency': 2.66,
|
|
122
|
+
'conf/pub:list:pair:exchange': 2.66,
|
|
123
|
+
'conf/pub:list:pair:margin': 2.66,
|
|
124
|
+
'conf/pub:list:pair:futures': 2.66,
|
|
125
|
+
'conf/pub:list:competitions': 2.66,
|
|
126
|
+
'conf/pub:info:{object}': 2.66,
|
|
127
|
+
'conf/pub:info:{object}:{detail}': 2.66,
|
|
128
|
+
'conf/pub:info:pair': 2.66,
|
|
129
|
+
'conf/pub:info:pair:futures': 2.66,
|
|
130
|
+
'conf/pub:info:tx:status': 2.66,
|
|
131
|
+
'conf/pub:fees': 2.66,
|
|
132
|
+
'platform/status': 8,
|
|
133
|
+
'tickers': 2.66,
|
|
134
|
+
'ticker/{symbol}': 2.66,
|
|
135
|
+
'tickers/hist': 2.66,
|
|
136
|
+
'trades/{symbol}/hist': 2.66,
|
|
137
|
+
'book/{symbol}/{precision}': 1,
|
|
138
|
+
'book/{symbol}/P0': 1,
|
|
139
|
+
'book/{symbol}/P1': 1,
|
|
140
|
+
'book/{symbol}/P2': 1,
|
|
141
|
+
'book/{symbol}/P3': 1,
|
|
142
|
+
'book/{symbol}/R0': 1,
|
|
143
|
+
'stats1/{key}:{size}:{symbol}:{side}/{section}': 2.66,
|
|
144
|
+
'stats1/{key}:{size}:{symbol}:{side}/last': 2.66,
|
|
145
|
+
'stats1/{key}:{size}:{symbol}:{side}/hist': 2.66,
|
|
146
|
+
'stats1/{key}:{size}:{symbol}/{section}': 2.66,
|
|
147
|
+
'stats1/{key}:{size}:{symbol}/last': 2.66,
|
|
148
|
+
'stats1/{key}:{size}:{symbol}/hist': 2.66,
|
|
149
|
+
'stats1/{key}:{size}:{symbol}:long/last': 2.66,
|
|
150
|
+
'stats1/{key}:{size}:{symbol}:long/hist': 2.66,
|
|
151
|
+
'stats1/{key}:{size}:{symbol}:short/last': 2.66,
|
|
152
|
+
'stats1/{key}:{size}:{symbol}:short/hist': 2.66,
|
|
153
|
+
'candles/trade:{timeframe}:{symbol}:{period}/{section}': 2.66,
|
|
154
|
+
'candles/trade:{timeframe}:{symbol}/{section}': 2.66,
|
|
155
|
+
'candles/trade:{timeframe}:{symbol}/last': 2.66,
|
|
156
|
+
'candles/trade:{timeframe}:{symbol}/hist': 2.66,
|
|
157
|
+
'status/{type}': 2.66,
|
|
158
|
+
'status/deriv': 2.66,
|
|
159
|
+
'status/deriv/{symbol}/hist': 2.66,
|
|
160
|
+
'liquidations/hist': 80,
|
|
161
|
+
'rankings/{key}:{timeframe}:{symbol}/{section}': 2.66,
|
|
162
|
+
'rankings/{key}:{timeframe}:{symbol}/hist': 2.66,
|
|
163
|
+
'pulse/hist': 2.66,
|
|
164
|
+
'pulse/profile/{nickname}': 2.66,
|
|
165
|
+
'funding/stats/{symbol}/hist': 10, // ratelimit not in docs
|
|
166
|
+
},
|
|
167
|
+
'post': {
|
|
168
|
+
'calc/trade/avg': 2.66,
|
|
169
|
+
'calc/fx': 2.66,
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
'private': {
|
|
173
|
+
'post': {
|
|
174
|
+
// 'auth/r/orders/{symbol}/new', // outdated
|
|
175
|
+
// 'auth/r/stats/perf:{timeframe}/hist', // outdated
|
|
176
|
+
'auth/r/wallets': 2.66,
|
|
177
|
+
'auth/r/wallets/hist': 2.66,
|
|
178
|
+
'auth/r/orders': 2.66,
|
|
179
|
+
'auth/r/orders/{symbol}': 2.66,
|
|
180
|
+
'auth/w/order/submit': 2.66,
|
|
181
|
+
'auth/w/order/update': 2.66,
|
|
182
|
+
'auth/w/order/cancel': 2.66,
|
|
183
|
+
'auth/w/order/multi': 2.66,
|
|
184
|
+
'auth/w/order/cancel/multi': 2.66,
|
|
185
|
+
'auth/r/orders/{symbol}/hist': 2.66,
|
|
186
|
+
'auth/r/orders/hist': 2.66,
|
|
187
|
+
'auth/r/order/{symbol}:{id}/trades': 2.66,
|
|
188
|
+
'auth/r/trades/{symbol}/hist': 2.66,
|
|
189
|
+
'auth/r/trades/hist': 2.66,
|
|
190
|
+
'auth/r/ledgers/{currency}/hist': 2.66,
|
|
191
|
+
'auth/r/ledgers/hist': 2.66,
|
|
192
|
+
'auth/r/info/margin/{key}': 2.66,
|
|
193
|
+
'auth/r/info/margin/base': 2.66,
|
|
194
|
+
'auth/r/info/margin/sym_all': 2.66,
|
|
195
|
+
'auth/r/positions': 2.66,
|
|
196
|
+
'auth/w/position/claim': 2.66,
|
|
197
|
+
'auth/w/position/increase:': 2.66,
|
|
198
|
+
'auth/r/position/increase/info': 2.66,
|
|
199
|
+
'auth/r/positions/hist': 2.66,
|
|
200
|
+
'auth/r/positions/audit': 2.66,
|
|
201
|
+
'auth/r/positions/snap': 2.66,
|
|
202
|
+
'auth/w/deriv/collateral/set': 2.66,
|
|
203
|
+
'auth/w/deriv/collateral/limits': 2.66,
|
|
204
|
+
'auth/r/funding/offers': 2.66,
|
|
205
|
+
'auth/r/funding/offers/{symbol}': 2.66,
|
|
206
|
+
'auth/w/funding/offer/submit': 2.66,
|
|
207
|
+
'auth/w/funding/offer/cancel': 2.66,
|
|
208
|
+
'auth/w/funding/offer/cancel/all': 2.66,
|
|
209
|
+
'auth/w/funding/close': 2.66,
|
|
210
|
+
'auth/w/funding/auto': 2.66,
|
|
211
|
+
'auth/w/funding/keep': 2.66,
|
|
212
|
+
'auth/r/funding/offers/{symbol}/hist': 2.66,
|
|
213
|
+
'auth/r/funding/offers/hist': 2.66,
|
|
214
|
+
'auth/r/funding/loans': 2.66,
|
|
215
|
+
'auth/r/funding/loans/hist': 2.66,
|
|
216
|
+
'auth/r/funding/loans/{symbol}': 2.66,
|
|
217
|
+
'auth/r/funding/loans/{symbol}/hist': 2.66,
|
|
218
|
+
'auth/r/funding/credits': 2.66,
|
|
219
|
+
'auth/r/funding/credits/hist': 2.66,
|
|
220
|
+
'auth/r/funding/credits/{symbol}': 2.66,
|
|
221
|
+
'auth/r/funding/credits/{symbol}/hist': 2.66,
|
|
222
|
+
'auth/r/funding/trades/{symbol}/hist': 2.66,
|
|
223
|
+
'auth/r/funding/trades/hist': 2.66,
|
|
224
|
+
'auth/r/info/funding/{key}': 2.66,
|
|
225
|
+
'auth/r/info/user': 2.66,
|
|
226
|
+
'auth/r/summary': 2.66,
|
|
227
|
+
'auth/r/logins/hist': 2.66,
|
|
228
|
+
'auth/r/permissions': 2.66,
|
|
229
|
+
'auth/w/token': 2.66,
|
|
230
|
+
'auth/r/audit/hist': 2.66,
|
|
231
|
+
'auth/w/transfer': 2.66,
|
|
232
|
+
'auth/w/deposit/address': 24,
|
|
233
|
+
'auth/w/deposit/invoice': 24,
|
|
234
|
+
'auth/w/withdraw': 24,
|
|
235
|
+
'auth/r/movements/{currency}/hist': 2.66,
|
|
236
|
+
'auth/r/movements/hist': 2.66,
|
|
237
|
+
'auth/r/alerts': 5.33,
|
|
238
|
+
'auth/w/alert/set': 2.66,
|
|
239
|
+
'auth/w/alert/price:{symbol}:{price}/del': 2.66,
|
|
240
|
+
'auth/w/alert/{type}:{symbol}:{price}/del': 2.66,
|
|
241
|
+
'auth/calc/order/avail': 2.66,
|
|
242
|
+
'auth/w/settings/set': 2.66,
|
|
243
|
+
'auth/r/settings': 2.66,
|
|
244
|
+
'auth/w/settings/del': 2.66,
|
|
245
|
+
'auth/r/pulse/hist': 2.66,
|
|
246
|
+
'auth/w/pulse/add': 16,
|
|
247
|
+
'auth/w/pulse/del': 2.66,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
'fees': {
|
|
252
|
+
'trading': {
|
|
253
|
+
'feeSide': 'get',
|
|
254
|
+
'percentage': true,
|
|
255
|
+
'tierBased': true,
|
|
256
|
+
'maker': this.parseNumber('0.001'),
|
|
257
|
+
'taker': this.parseNumber('0.002'),
|
|
258
|
+
'tiers': {
|
|
259
|
+
'taker': [
|
|
260
|
+
[this.parseNumber('0'), this.parseNumber('0.002')],
|
|
261
|
+
[this.parseNumber('500000'), this.parseNumber('0.002')],
|
|
262
|
+
[this.parseNumber('1000000'), this.parseNumber('0.002')],
|
|
263
|
+
[this.parseNumber('2500000'), this.parseNumber('0.002')],
|
|
264
|
+
[this.parseNumber('5000000'), this.parseNumber('0.002')],
|
|
265
|
+
[this.parseNumber('7500000'), this.parseNumber('0.002')],
|
|
266
|
+
[this.parseNumber('10000000'), this.parseNumber('0.0018')],
|
|
267
|
+
[this.parseNumber('15000000'), this.parseNumber('0.0016')],
|
|
268
|
+
[this.parseNumber('20000000'), this.parseNumber('0.0014')],
|
|
269
|
+
[this.parseNumber('25000000'), this.parseNumber('0.0012')],
|
|
270
|
+
[this.parseNumber('30000000'), this.parseNumber('0.001')],
|
|
271
|
+
],
|
|
272
|
+
'maker': [
|
|
273
|
+
[this.parseNumber('0'), this.parseNumber('0.001')],
|
|
274
|
+
[this.parseNumber('500000'), this.parseNumber('0.0008')],
|
|
275
|
+
[this.parseNumber('1000000'), this.parseNumber('0.0006')],
|
|
276
|
+
[this.parseNumber('2500000'), this.parseNumber('0.0004')],
|
|
277
|
+
[this.parseNumber('5000000'), this.parseNumber('0.0002')],
|
|
278
|
+
[this.parseNumber('7500000'), this.parseNumber('0')],
|
|
279
|
+
[this.parseNumber('10000000'), this.parseNumber('0')],
|
|
280
|
+
[this.parseNumber('15000000'), this.parseNumber('0')],
|
|
281
|
+
[this.parseNumber('20000000'), this.parseNumber('0')],
|
|
282
|
+
[this.parseNumber('25000000'), this.parseNumber('0')],
|
|
283
|
+
[this.parseNumber('30000000'), this.parseNumber('0')],
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
'funding': {
|
|
288
|
+
'withdraw': {},
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
'precisionMode': number.SIGNIFICANT_DIGITS,
|
|
292
|
+
'options': {
|
|
293
|
+
'precision': 'R0',
|
|
294
|
+
// convert 'EXCHANGE MARKET' to lowercase 'market'
|
|
295
|
+
// convert 'EXCHANGE LIMIT' to lowercase 'limit'
|
|
296
|
+
// everything else remains uppercase
|
|
297
|
+
'exchangeTypes': {
|
|
298
|
+
// 'MARKET': undefined,
|
|
299
|
+
'EXCHANGE MARKET': 'market',
|
|
300
|
+
// 'LIMIT': undefined,
|
|
301
|
+
'EXCHANGE LIMIT': 'limit',
|
|
302
|
+
// 'STOP': undefined,
|
|
303
|
+
'EXCHANGE STOP': 'market',
|
|
304
|
+
// 'TRAILING STOP': undefined,
|
|
305
|
+
// 'EXCHANGE TRAILING STOP': undefined,
|
|
306
|
+
// 'FOK': undefined,
|
|
307
|
+
'EXCHANGE FOK': 'limit',
|
|
308
|
+
// 'STOP LIMIT': undefined,
|
|
309
|
+
'EXCHANGE STOP LIMIT': 'limit',
|
|
310
|
+
// 'IOC': undefined,
|
|
311
|
+
'EXCHANGE IOC': 'limit',
|
|
312
|
+
},
|
|
313
|
+
// convert 'market' to 'EXCHANGE MARKET'
|
|
314
|
+
// convert 'limit' 'EXCHANGE LIMIT'
|
|
315
|
+
// everything else remains as is
|
|
316
|
+
'orderTypes': {
|
|
317
|
+
'market': 'EXCHANGE MARKET',
|
|
318
|
+
'limit': 'EXCHANGE LIMIT',
|
|
319
|
+
},
|
|
320
|
+
'fiat': {
|
|
321
|
+
'USD': 'USD',
|
|
322
|
+
'EUR': 'EUR',
|
|
323
|
+
'JPY': 'JPY',
|
|
324
|
+
'GBP': 'GBP',
|
|
325
|
+
'CHN': 'CHN',
|
|
326
|
+
},
|
|
327
|
+
// actually the correct names unlike the v1
|
|
328
|
+
// we don't want to extend this with accountsByType in v1
|
|
329
|
+
'v2AccountsByType': {
|
|
330
|
+
'spot': 'exchange',
|
|
331
|
+
'exchange': 'exchange',
|
|
332
|
+
'funding': 'funding',
|
|
333
|
+
'margin': 'margin',
|
|
334
|
+
'derivatives': 'margin',
|
|
335
|
+
'future': 'margin',
|
|
336
|
+
},
|
|
337
|
+
'withdraw': {
|
|
338
|
+
'includeFee': false,
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
'exceptions': {
|
|
342
|
+
'exact': {
|
|
343
|
+
'11010': errors.RateLimitExceeded,
|
|
344
|
+
'10001': errors.PermissionDenied,
|
|
345
|
+
'10020': errors.BadRequest,
|
|
346
|
+
'10100': errors.AuthenticationError,
|
|
347
|
+
'10114': errors.InvalidNonce,
|
|
348
|
+
'20060': errors.OnMaintenance,
|
|
349
|
+
// {"code":503,"error":"temporarily_unavailable","error_description":"Sorry, the service is temporarily unavailable. See https://www.bitfinex.com/ for more info."}
|
|
350
|
+
'temporarily_unavailable': errors.ExchangeNotAvailable,
|
|
351
|
+
},
|
|
352
|
+
'broad': {
|
|
353
|
+
'address': errors.InvalidAddress,
|
|
354
|
+
'available balance is only': errors.InsufficientFunds,
|
|
355
|
+
'not enough exchange balance': errors.InsufficientFunds,
|
|
356
|
+
'Order not found': errors.OrderNotFound,
|
|
357
|
+
'symbol: invalid': errors.BadSymbol,
|
|
358
|
+
'Invalid order': errors.InvalidOrder,
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
'commonCurrencies': {
|
|
362
|
+
'UST': 'USDT',
|
|
363
|
+
'EUTF0': 'EURT',
|
|
364
|
+
'USTF0': 'USDT',
|
|
365
|
+
'ALG': 'ALGO',
|
|
366
|
+
'AMP': 'AMPL',
|
|
367
|
+
'ATO': 'ATOM',
|
|
368
|
+
'BCHABC': 'XEC',
|
|
369
|
+
'BCHN': 'BCH',
|
|
370
|
+
'DAT': 'DATA',
|
|
371
|
+
'DOG': 'MDOGE',
|
|
372
|
+
'DSH': 'DASH',
|
|
373
|
+
'EDO': 'PNT',
|
|
374
|
+
'EUS': 'EURS',
|
|
375
|
+
'EUT': 'EURT',
|
|
376
|
+
'IDX': 'ID',
|
|
377
|
+
'IOT': 'IOTA',
|
|
378
|
+
'IQX': 'IQ',
|
|
379
|
+
'LUNA': 'LUNC',
|
|
380
|
+
'LUNA2': 'LUNA',
|
|
381
|
+
'MNA': 'MANA',
|
|
382
|
+
'ORS': 'ORS Group',
|
|
383
|
+
'PAS': 'PASS',
|
|
384
|
+
'QSH': 'QASH',
|
|
385
|
+
'QTM': 'QTUM',
|
|
386
|
+
'RBT': 'RBTC',
|
|
387
|
+
'SNG': 'SNGLS',
|
|
388
|
+
'STJ': 'STORJ',
|
|
389
|
+
'TERRAUST': 'USTC',
|
|
390
|
+
'TSD': 'TUSD',
|
|
391
|
+
'YGG': 'YEED',
|
|
392
|
+
'YYW': 'YOYOW',
|
|
393
|
+
'UDC': 'USDC',
|
|
394
|
+
'VSY': 'VSYS',
|
|
395
|
+
'WAX': 'WAXP',
|
|
396
|
+
'XCH': 'XCHF',
|
|
397
|
+
'ZBT': 'ZB',
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
isFiat(code) {
|
|
402
|
+
return (code in this.options['fiat']);
|
|
403
|
+
}
|
|
404
|
+
getCurrencyId(code) {
|
|
405
|
+
return 'f' + code;
|
|
406
|
+
}
|
|
407
|
+
getCurrencyName(code) {
|
|
408
|
+
// temporary fix for transpiler recognition, even though this is in parent class
|
|
409
|
+
if (code in this.options['currencyNames']) {
|
|
410
|
+
return this.options['currencyNames'][code];
|
|
411
|
+
}
|
|
412
|
+
throw new errors.NotSupported(this.id + ' ' + code + ' not supported for withdrawal');
|
|
413
|
+
}
|
|
414
|
+
amountToPrecision(symbol, amount) {
|
|
415
|
+
// https://docs.bitfinex.com/docs/introduction#amount-precision
|
|
416
|
+
// The amount field allows up to 8 decimals.
|
|
417
|
+
// Anything exceeding this will be rounded to the 8th decimal.
|
|
418
|
+
symbol = this.safeSymbol(symbol);
|
|
419
|
+
return this.decimalToPrecision(amount, number.TRUNCATE, this.markets[symbol]['precision']['amount'], number.DECIMAL_PLACES);
|
|
420
|
+
}
|
|
421
|
+
priceToPrecision(symbol, price) {
|
|
422
|
+
symbol = this.safeSymbol(symbol);
|
|
423
|
+
price = this.decimalToPrecision(price, number.ROUND, this.markets[symbol]['precision']['price'], this.precisionMode);
|
|
424
|
+
// https://docs.bitfinex.com/docs/introduction#price-precision
|
|
425
|
+
// The precision level of all trading prices is based on significant figures.
|
|
426
|
+
// All pairs on Bitfinex use up to 5 significant digits and up to 8 decimals (e.g. 1.2345, 123.45, 1234.5, 0.00012345).
|
|
427
|
+
// Prices submit with a precision larger than 5 will be cut by the API.
|
|
428
|
+
return this.decimalToPrecision(price, number.TRUNCATE, 8, number.DECIMAL_PLACES);
|
|
429
|
+
}
|
|
430
|
+
async fetchStatus(params = {}) {
|
|
431
|
+
/**
|
|
432
|
+
* @method
|
|
433
|
+
* @name bitfinex2#fetchStatus
|
|
434
|
+
* @description the latest known information on the availability of the exchange API
|
|
435
|
+
* @see https://docs.bitfinex.com/reference/rest-public-platform-status
|
|
436
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
437
|
+
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
|
|
438
|
+
*/
|
|
439
|
+
//
|
|
440
|
+
// [1] // operative
|
|
441
|
+
// [0] // maintenance
|
|
442
|
+
//
|
|
443
|
+
const response = await this.publicGetPlatformStatus(params);
|
|
444
|
+
const statusRaw = this.safeString(response, 0);
|
|
445
|
+
return {
|
|
446
|
+
'status': this.safeString({ '0': 'maintenance', '1': 'ok' }, statusRaw, statusRaw),
|
|
447
|
+
'updated': undefined,
|
|
448
|
+
'eta': undefined,
|
|
449
|
+
'url': undefined,
|
|
450
|
+
'info': response,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
async fetchMarkets(params = {}) {
|
|
454
|
+
/**
|
|
455
|
+
* @method
|
|
456
|
+
* @name bitfinex2#fetchMarkets
|
|
457
|
+
* @description retrieves data on all markets for bitfinex2
|
|
458
|
+
* @see https://docs.bitfinex.com/reference/rest-public-conf
|
|
459
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
460
|
+
* @returns {object[]} an array of objects representing market data
|
|
461
|
+
*/
|
|
462
|
+
let spotMarketsInfo = await this.publicGetConfPubInfoPair(params);
|
|
463
|
+
let futuresMarketsInfo = await this.publicGetConfPubInfoPairFutures(params);
|
|
464
|
+
spotMarketsInfo = this.safeValue(spotMarketsInfo, 0, []);
|
|
465
|
+
futuresMarketsInfo = this.safeValue(futuresMarketsInfo, 0, []);
|
|
466
|
+
const markets = this.arrayConcat(spotMarketsInfo, futuresMarketsInfo);
|
|
467
|
+
let marginIds = await this.publicGetConfPubListPairMargin(params);
|
|
468
|
+
marginIds = this.safeValue(marginIds, 0, []);
|
|
469
|
+
//
|
|
470
|
+
// [
|
|
471
|
+
// "1INCH:USD",
|
|
472
|
+
// [
|
|
473
|
+
// null,
|
|
474
|
+
// null,
|
|
475
|
+
// null,
|
|
476
|
+
// "2.0",
|
|
477
|
+
// "100000.0",
|
|
478
|
+
// null,
|
|
479
|
+
// null,
|
|
480
|
+
// null,
|
|
481
|
+
// null,
|
|
482
|
+
// null,
|
|
483
|
+
// null,
|
|
484
|
+
// null
|
|
485
|
+
// ]
|
|
486
|
+
// ]
|
|
487
|
+
//
|
|
488
|
+
const result = [];
|
|
489
|
+
for (let i = 0; i < markets.length; i++) {
|
|
490
|
+
const pair = markets[i];
|
|
491
|
+
const id = this.safeStringUpper(pair, 0);
|
|
492
|
+
const market = this.safeValue(pair, 1, {});
|
|
493
|
+
let spot = true;
|
|
494
|
+
if (id.indexOf('F0') >= 0) {
|
|
495
|
+
spot = false;
|
|
496
|
+
}
|
|
497
|
+
const swap = !spot;
|
|
498
|
+
let baseId = undefined;
|
|
499
|
+
let quoteId = undefined;
|
|
500
|
+
if (id.indexOf(':') >= 0) {
|
|
501
|
+
const parts = id.split(':');
|
|
502
|
+
baseId = parts[0];
|
|
503
|
+
quoteId = parts[1];
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
baseId = id.slice(0, 3);
|
|
507
|
+
quoteId = id.slice(3, 6);
|
|
508
|
+
}
|
|
509
|
+
let base = this.safeCurrencyCode(baseId);
|
|
510
|
+
let quote = this.safeCurrencyCode(quoteId);
|
|
511
|
+
const splitBase = base.split('F0');
|
|
512
|
+
const splitQuote = quote.split('F0');
|
|
513
|
+
base = this.safeString(splitBase, 0);
|
|
514
|
+
quote = this.safeString(splitQuote, 0);
|
|
515
|
+
let symbol = base + '/' + quote;
|
|
516
|
+
baseId = this.getCurrencyId(baseId);
|
|
517
|
+
quoteId = this.getCurrencyId(quoteId);
|
|
518
|
+
let settle = undefined;
|
|
519
|
+
let settleId = undefined;
|
|
520
|
+
if (swap) {
|
|
521
|
+
settle = quote;
|
|
522
|
+
settleId = quote;
|
|
523
|
+
symbol = symbol + ':' + settle;
|
|
524
|
+
}
|
|
525
|
+
const minOrderSizeString = this.safeString(market, 3);
|
|
526
|
+
const maxOrderSizeString = this.safeString(market, 4);
|
|
527
|
+
let margin = false;
|
|
528
|
+
if (spot && this.inArray(id, marginIds)) {
|
|
529
|
+
margin = true;
|
|
530
|
+
}
|
|
531
|
+
result.push({
|
|
532
|
+
'id': 't' + id,
|
|
533
|
+
'symbol': symbol,
|
|
534
|
+
'base': base,
|
|
535
|
+
'quote': quote,
|
|
536
|
+
'settle': settle,
|
|
537
|
+
'baseId': baseId,
|
|
538
|
+
'quoteId': quoteId,
|
|
539
|
+
'settleId': settleId,
|
|
540
|
+
'type': spot ? 'spot' : 'swap',
|
|
541
|
+
'spot': spot,
|
|
542
|
+
'margin': margin,
|
|
543
|
+
'swap': swap,
|
|
544
|
+
'future': false,
|
|
545
|
+
'option': false,
|
|
546
|
+
'active': true,
|
|
547
|
+
'contract': swap,
|
|
548
|
+
'linear': swap ? true : undefined,
|
|
549
|
+
'inverse': swap ? false : undefined,
|
|
550
|
+
'contractSize': swap ? this.parseNumber('1') : undefined,
|
|
551
|
+
'expiry': undefined,
|
|
552
|
+
'expiryDatetime': undefined,
|
|
553
|
+
'strike': undefined,
|
|
554
|
+
'optionType': undefined,
|
|
555
|
+
'precision': {
|
|
556
|
+
'amount': parseInt('8'),
|
|
557
|
+
'price': parseInt('5'),
|
|
558
|
+
},
|
|
559
|
+
'limits': {
|
|
560
|
+
'leverage': {
|
|
561
|
+
'min': undefined,
|
|
562
|
+
'max': undefined,
|
|
563
|
+
},
|
|
564
|
+
'amount': {
|
|
565
|
+
'min': this.parseNumber(minOrderSizeString),
|
|
566
|
+
'max': this.parseNumber(maxOrderSizeString),
|
|
567
|
+
},
|
|
568
|
+
'price': {
|
|
569
|
+
'min': this.parseNumber('1e-8'),
|
|
570
|
+
'max': undefined,
|
|
571
|
+
},
|
|
572
|
+
'cost': {
|
|
573
|
+
'min': undefined,
|
|
574
|
+
'max': undefined,
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
'created': undefined,
|
|
578
|
+
'info': market,
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
return result;
|
|
582
|
+
}
|
|
583
|
+
async fetchCurrencies(params = {}) {
|
|
584
|
+
/**
|
|
585
|
+
* @method
|
|
586
|
+
* @name bitfinex2#fetchCurrencies
|
|
587
|
+
* @description fetches all available currencies on an exchange
|
|
588
|
+
* @see https://docs.bitfinex.com/reference/rest-public-conf
|
|
589
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
590
|
+
* @returns {object} an associative dictionary of currencies
|
|
591
|
+
*/
|
|
592
|
+
const labels = [
|
|
593
|
+
'pub:list:currency',
|
|
594
|
+
'pub:map:currency:sym',
|
|
595
|
+
'pub:map:currency:label',
|
|
596
|
+
'pub:map:currency:unit',
|
|
597
|
+
'pub:map:currency:undl',
|
|
598
|
+
'pub:map:currency:pool',
|
|
599
|
+
'pub:map:currency:explorer',
|
|
600
|
+
'pub:map:currency:tx:fee',
|
|
601
|
+
'pub:map:tx:method', // maps withdrawal/deposit methods to their API symbols
|
|
602
|
+
];
|
|
603
|
+
const config = labels.join(',');
|
|
604
|
+
const request = {
|
|
605
|
+
'config': config,
|
|
606
|
+
};
|
|
607
|
+
const response = await this.publicGetConfConfig(this.extend(request, params));
|
|
608
|
+
//
|
|
609
|
+
// [
|
|
610
|
+
//
|
|
611
|
+
// a list of symbols
|
|
612
|
+
// ["AAA","ABS","ADA"],
|
|
613
|
+
//
|
|
614
|
+
// // sym
|
|
615
|
+
// // maps symbols to their API symbols, BAB > BCH
|
|
616
|
+
// [
|
|
617
|
+
// [ "BAB", "BCH" ],
|
|
618
|
+
// [ "CNHT", "CNHt" ],
|
|
619
|
+
// [ "DSH", "DASH" ],
|
|
620
|
+
// [ "IOT", "IOTA" ],
|
|
621
|
+
// [ "LES", "LEO-EOS" ],
|
|
622
|
+
// [ "LET", "LEO-ERC20" ],
|
|
623
|
+
// [ "STJ", "STORJ" ],
|
|
624
|
+
// [ "TSD", "TUSD" ],
|
|
625
|
+
// [ "UDC", "USDC" ],
|
|
626
|
+
// [ "USK", "USDK" ],
|
|
627
|
+
// [ "UST", "USDt" ],
|
|
628
|
+
// [ "USTF0", "USDt0" ],
|
|
629
|
+
// [ "XCH", "XCHF" ],
|
|
630
|
+
// [ "YYW", "YOYOW" ],
|
|
631
|
+
// // ...
|
|
632
|
+
// ],
|
|
633
|
+
// // label
|
|
634
|
+
// // verbose friendly names, BNT > Bancor
|
|
635
|
+
// [
|
|
636
|
+
// [ "BAB", "Bitcoin Cash" ],
|
|
637
|
+
// [ "BCH", "Bitcoin Cash" ],
|
|
638
|
+
// [ "LEO", "Unus Sed LEO" ],
|
|
639
|
+
// [ "LES", "Unus Sed LEO (EOS)" ],
|
|
640
|
+
// [ "LET", "Unus Sed LEO (ERC20)" ],
|
|
641
|
+
// // ...
|
|
642
|
+
// ],
|
|
643
|
+
// // unit
|
|
644
|
+
// // maps symbols to unit of measure where applicable
|
|
645
|
+
// [
|
|
646
|
+
// [ "IOT", "Mi|MegaIOTA" ],
|
|
647
|
+
// ],
|
|
648
|
+
// // undl
|
|
649
|
+
// // maps derivatives symbols to their underlying currency
|
|
650
|
+
// [
|
|
651
|
+
// [ "USTF0", "UST" ],
|
|
652
|
+
// [ "BTCF0", "BTC" ],
|
|
653
|
+
// [ "ETHF0", "ETH" ],
|
|
654
|
+
// ],
|
|
655
|
+
// // pool
|
|
656
|
+
// // maps symbols to underlying network/protocol they operate on
|
|
657
|
+
// [
|
|
658
|
+
// [ 'SAN', 'ETH' ], [ 'OMG', 'ETH' ], [ 'AVT', 'ETH' ], [ "EDO", "ETH" ],
|
|
659
|
+
// [ 'ESS', 'ETH' ], [ 'ATD', 'EOS' ], [ 'ADD', 'EOS' ], [ "MTO", "EOS" ],
|
|
660
|
+
// [ 'PNK', 'ETH' ], [ 'BAB', 'BCH' ], [ 'WLO', 'XLM' ], [ "VLD", "ETH" ],
|
|
661
|
+
// [ 'BTT', 'TRX' ], [ 'IMP', 'ETH' ], [ 'SCR', 'ETH' ], [ "GNO", "ETH" ],
|
|
662
|
+
// // ...
|
|
663
|
+
// ],
|
|
664
|
+
// // explorer
|
|
665
|
+
// // maps symbols to their recognised block explorer URLs
|
|
666
|
+
// [
|
|
667
|
+
// [
|
|
668
|
+
// "AIO",
|
|
669
|
+
// [
|
|
670
|
+
// "https://mainnet.aion.network",
|
|
671
|
+
// "https://mainnet.aion.network/#/account/VAL",
|
|
672
|
+
// "https://mainnet.aion.network/#/transaction/VAL"
|
|
673
|
+
// ]
|
|
674
|
+
// ],
|
|
675
|
+
// // ...
|
|
676
|
+
// ],
|
|
677
|
+
// // fee
|
|
678
|
+
// // maps currencies to their withdrawal fees
|
|
679
|
+
// [
|
|
680
|
+
// ["AAA",[0,0]],
|
|
681
|
+
// ["ABS",[0,131.3]],
|
|
682
|
+
// ["ADA",[0,0.3]],
|
|
683
|
+
// ],
|
|
684
|
+
// ]
|
|
685
|
+
//
|
|
686
|
+
const indexed = {
|
|
687
|
+
'sym': this.indexBy(this.safeValue(response, 1, []), 0),
|
|
688
|
+
'label': this.indexBy(this.safeValue(response, 2, []), 0),
|
|
689
|
+
'unit': this.indexBy(this.safeValue(response, 3, []), 0),
|
|
690
|
+
'undl': this.indexBy(this.safeValue(response, 4, []), 0),
|
|
691
|
+
'pool': this.indexBy(this.safeValue(response, 5, []), 0),
|
|
692
|
+
'explorer': this.indexBy(this.safeValue(response, 6, []), 0),
|
|
693
|
+
'fees': this.indexBy(this.safeValue(response, 7, []), 0),
|
|
694
|
+
};
|
|
695
|
+
const ids = this.safeValue(response, 0, []);
|
|
696
|
+
const result = {};
|
|
697
|
+
for (let i = 0; i < ids.length; i++) {
|
|
698
|
+
const id = ids[i];
|
|
699
|
+
if (id.indexOf('F0') >= 0) {
|
|
700
|
+
// we get a lot of F0 currencies, skip those
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
const code = this.safeCurrencyCode(id);
|
|
704
|
+
const label = this.safeValue(indexed['label'], id, []);
|
|
705
|
+
const name = this.safeString(label, 1);
|
|
706
|
+
const pool = this.safeValue(indexed['pool'], id, []);
|
|
707
|
+
const rawType = this.safeString(pool, 1);
|
|
708
|
+
const type = (rawType === undefined) ? 'other' : 'crypto';
|
|
709
|
+
const feeValues = this.safeValue(indexed['fees'], id, []);
|
|
710
|
+
const fees = this.safeValue(feeValues, 1, []);
|
|
711
|
+
const fee = this.safeNumber(fees, 1);
|
|
712
|
+
const undl = this.safeValue(indexed['undl'], id, []);
|
|
713
|
+
const precision = '8'; // default precision, todo: fix "magic constants"
|
|
714
|
+
const fid = 'f' + id;
|
|
715
|
+
result[code] = {
|
|
716
|
+
'id': fid,
|
|
717
|
+
'uppercaseId': id,
|
|
718
|
+
'code': code,
|
|
719
|
+
'info': [id, label, pool, feeValues, undl],
|
|
720
|
+
'type': type,
|
|
721
|
+
'name': name,
|
|
722
|
+
'active': true,
|
|
723
|
+
'deposit': undefined,
|
|
724
|
+
'withdraw': undefined,
|
|
725
|
+
'fee': fee,
|
|
726
|
+
'precision': parseInt(precision),
|
|
727
|
+
'limits': {
|
|
728
|
+
'amount': {
|
|
729
|
+
'min': this.parseNumber(this.parsePrecision(precision)),
|
|
730
|
+
'max': undefined,
|
|
731
|
+
},
|
|
732
|
+
'withdraw': {
|
|
733
|
+
'min': fee,
|
|
734
|
+
'max': undefined,
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
'networks': {},
|
|
738
|
+
};
|
|
739
|
+
const networks = {};
|
|
740
|
+
const currencyNetworks = this.safeValue(response, 8, []);
|
|
741
|
+
const cleanId = id.replace('F0', '');
|
|
742
|
+
for (let j = 0; j < currencyNetworks.length; j++) {
|
|
743
|
+
const pair = currencyNetworks[j];
|
|
744
|
+
const networkId = this.safeString(pair, 0);
|
|
745
|
+
const currencyId = this.safeString(this.safeValue(pair, 1, []), 0);
|
|
746
|
+
if (currencyId === cleanId) {
|
|
747
|
+
const network = this.safeNetwork(networkId);
|
|
748
|
+
networks[network] = {
|
|
749
|
+
'info': networkId,
|
|
750
|
+
'id': networkId.toLowerCase(),
|
|
751
|
+
'network': networkId,
|
|
752
|
+
'active': undefined,
|
|
753
|
+
'deposit': undefined,
|
|
754
|
+
'withdraw': undefined,
|
|
755
|
+
'fee': undefined,
|
|
756
|
+
'precision': undefined,
|
|
757
|
+
'limits': {
|
|
758
|
+
'withdraw': {
|
|
759
|
+
'min': undefined,
|
|
760
|
+
'max': undefined,
|
|
761
|
+
},
|
|
762
|
+
},
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
const keysNetworks = Object.keys(networks);
|
|
767
|
+
const networksLength = keysNetworks.length;
|
|
768
|
+
if (networksLength > 0) {
|
|
769
|
+
result[code]['networks'] = networks;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return result;
|
|
773
|
+
}
|
|
774
|
+
safeNetwork(networkId) {
|
|
775
|
+
const networksById = {
|
|
776
|
+
'BITCOIN': 'BTC',
|
|
777
|
+
'LITECOIN': 'LTC',
|
|
778
|
+
'ETHEREUM': 'ERC20',
|
|
779
|
+
'TETHERUSE': 'ERC20',
|
|
780
|
+
'TETHERUSO': 'OMNI',
|
|
781
|
+
'TETHERUSL': 'LIQUID',
|
|
782
|
+
'TETHERUSX': 'TRC20',
|
|
783
|
+
'TETHERUSS': 'EOS',
|
|
784
|
+
'TETHERUSDTAVAX': 'AVAX',
|
|
785
|
+
'TETHERUSDTSOL': 'SOL',
|
|
786
|
+
'TETHERUSDTALG': 'ALGO',
|
|
787
|
+
'TETHERUSDTBCH': 'BCH',
|
|
788
|
+
'TETHERUSDTKSM': 'KSM',
|
|
789
|
+
'TETHERUSDTDVF': 'DVF',
|
|
790
|
+
'TETHERUSDTOMG': 'OMG',
|
|
791
|
+
};
|
|
792
|
+
return this.safeString(networksById, networkId, networkId);
|
|
793
|
+
}
|
|
794
|
+
async fetchBalance(params = {}) {
|
|
795
|
+
/**
|
|
796
|
+
* @method
|
|
797
|
+
* @name bitfinex2#fetchBalance
|
|
798
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
799
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-wallets
|
|
800
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
801
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
802
|
+
*/
|
|
803
|
+
// this api call does not return the 'used' amount - use the v1 version instead (which also returns zero balances)
|
|
804
|
+
// there is a difference between this and the v1 api, namely trading wallet is called margin in v2
|
|
805
|
+
await this.loadMarkets();
|
|
806
|
+
const accountsByType = this.safeValue(this.options, 'v2AccountsByType', {});
|
|
807
|
+
const requestedType = this.safeString(params, 'type', 'exchange');
|
|
808
|
+
const accountType = this.safeString(accountsByType, requestedType, requestedType);
|
|
809
|
+
if (accountType === undefined) {
|
|
810
|
+
const keys = Object.keys(accountsByType);
|
|
811
|
+
throw new errors.ExchangeError(this.id + ' fetchBalance() type parameter must be one of ' + keys.join(', '));
|
|
812
|
+
}
|
|
813
|
+
const isDerivative = requestedType === 'derivatives';
|
|
814
|
+
const query = this.omit(params, 'type');
|
|
815
|
+
const response = await this.privatePostAuthRWallets(query);
|
|
816
|
+
const result = { 'info': response };
|
|
817
|
+
for (let i = 0; i < response.length; i++) {
|
|
818
|
+
const balance = response[i];
|
|
819
|
+
const type = this.safeString(balance, 0);
|
|
820
|
+
const currencyId = this.safeStringLower(balance, 1, '');
|
|
821
|
+
const start = currencyId.length - 2;
|
|
822
|
+
const isDerivativeCode = currencyId.slice(start) === 'f0';
|
|
823
|
+
// this will only filter the derivative codes if the requestedType is 'derivatives'
|
|
824
|
+
const derivativeCondition = (!isDerivative || isDerivativeCode);
|
|
825
|
+
if ((accountType === type) && derivativeCondition) {
|
|
826
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
827
|
+
const account = this.account();
|
|
828
|
+
account['total'] = this.safeString(balance, 2);
|
|
829
|
+
account['free'] = this.safeString(balance, 4);
|
|
830
|
+
result[code] = account;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
return this.safeBalance(result);
|
|
834
|
+
}
|
|
835
|
+
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
836
|
+
/**
|
|
837
|
+
* @method
|
|
838
|
+
* @name bitfinex2#transfer
|
|
839
|
+
* @description transfer currency internally between wallets on the same account
|
|
840
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-transfer
|
|
841
|
+
* @param {string} code unified currency code
|
|
842
|
+
* @param {float} amount amount to transfer
|
|
843
|
+
* @param {string} fromAccount account to transfer from
|
|
844
|
+
* @param {string} toAccount account to transfer to
|
|
845
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
846
|
+
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
847
|
+
*/
|
|
848
|
+
// transferring between derivatives wallet and regular wallet is not documented in their API
|
|
849
|
+
// however we support it in CCXT (from just looking at web inspector)
|
|
850
|
+
await this.loadMarkets();
|
|
851
|
+
const accountsByType = this.safeValue(this.options, 'v2AccountsByType', {});
|
|
852
|
+
const fromId = this.safeString(accountsByType, fromAccount);
|
|
853
|
+
if (fromId === undefined) {
|
|
854
|
+
const keys = Object.keys(accountsByType);
|
|
855
|
+
throw new errors.ArgumentsRequired(this.id + ' transfer() fromAccount must be one of ' + keys.join(', '));
|
|
856
|
+
}
|
|
857
|
+
const toId = this.safeString(accountsByType, toAccount);
|
|
858
|
+
if (toId === undefined) {
|
|
859
|
+
const keys = Object.keys(accountsByType);
|
|
860
|
+
throw new errors.ArgumentsRequired(this.id + ' transfer() toAccount must be one of ' + keys.join(', '));
|
|
861
|
+
}
|
|
862
|
+
const currency = this.currency(code);
|
|
863
|
+
const fromCurrencyId = this.convertDerivativesId(currency, fromAccount);
|
|
864
|
+
const toCurrencyId = this.convertDerivativesId(currency, toAccount);
|
|
865
|
+
const requestedAmount = this.currencyToPrecision(code, amount);
|
|
866
|
+
// this request is slightly different from v1 fromAccount -> from
|
|
867
|
+
const request = {
|
|
868
|
+
'amount': requestedAmount,
|
|
869
|
+
'currency': fromCurrencyId,
|
|
870
|
+
'currency_to': toCurrencyId,
|
|
871
|
+
'from': fromId,
|
|
872
|
+
'to': toId,
|
|
873
|
+
};
|
|
874
|
+
const response = await this.privatePostAuthWTransfer(this.extend(request, params));
|
|
875
|
+
//
|
|
876
|
+
// [
|
|
877
|
+
// 1616451183763,
|
|
878
|
+
// "acc_tf",
|
|
879
|
+
// null,
|
|
880
|
+
// null,
|
|
881
|
+
// [
|
|
882
|
+
// 1616451183763,
|
|
883
|
+
// "exchange",
|
|
884
|
+
// "margin",
|
|
885
|
+
// null,
|
|
886
|
+
// "UST",
|
|
887
|
+
// "UST",
|
|
888
|
+
// null,
|
|
889
|
+
// 1
|
|
890
|
+
// ],
|
|
891
|
+
// null,
|
|
892
|
+
// "SUCCESS",
|
|
893
|
+
// "1.0 Tether USDt transfered from Exchange to Margin"
|
|
894
|
+
// ]
|
|
895
|
+
//
|
|
896
|
+
const error = this.safeString(response, 0);
|
|
897
|
+
if (error === 'error') {
|
|
898
|
+
const message = this.safeString(response, 2, '');
|
|
899
|
+
// same message as in v1
|
|
900
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, this.id + ' ' + message);
|
|
901
|
+
throw new errors.ExchangeError(this.id + ' ' + message);
|
|
902
|
+
}
|
|
903
|
+
return this.parseTransfer(response, currency);
|
|
904
|
+
}
|
|
905
|
+
parseTransfer(transfer, currency = undefined) {
|
|
906
|
+
//
|
|
907
|
+
// transfer
|
|
908
|
+
//
|
|
909
|
+
// [
|
|
910
|
+
// 1616451183763,
|
|
911
|
+
// "acc_tf",
|
|
912
|
+
// null,
|
|
913
|
+
// null,
|
|
914
|
+
// [
|
|
915
|
+
// 1616451183763,
|
|
916
|
+
// "exchange",
|
|
917
|
+
// "margin",
|
|
918
|
+
// null,
|
|
919
|
+
// "UST",
|
|
920
|
+
// "UST",
|
|
921
|
+
// null,
|
|
922
|
+
// 1
|
|
923
|
+
// ],
|
|
924
|
+
// null,
|
|
925
|
+
// "SUCCESS",
|
|
926
|
+
// "1.0 Tether USDt transfered from Exchange to Margin"
|
|
927
|
+
// ]
|
|
928
|
+
//
|
|
929
|
+
const timestamp = this.safeInteger(transfer, 0);
|
|
930
|
+
const info = this.safeValue(transfer, 4);
|
|
931
|
+
const fromAccount = this.safeString(info, 1);
|
|
932
|
+
const toAccount = this.safeString(info, 2);
|
|
933
|
+
const currencyId = this.safeString(info, 5);
|
|
934
|
+
const status = this.safeString(transfer, 6);
|
|
935
|
+
return {
|
|
936
|
+
'id': undefined,
|
|
937
|
+
'timestamp': timestamp,
|
|
938
|
+
'datetime': this.iso8601(timestamp),
|
|
939
|
+
'status': this.parseTransferStatus(status),
|
|
940
|
+
'amount': this.safeNumber(info, 7),
|
|
941
|
+
'currency': this.safeCurrencyCode(currencyId, currency),
|
|
942
|
+
'fromAccount': fromAccount,
|
|
943
|
+
'toAccount': toAccount,
|
|
944
|
+
'info': transfer,
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
parseTransferStatus(status) {
|
|
948
|
+
const statuses = {
|
|
949
|
+
'SUCCESS': 'ok',
|
|
950
|
+
'ERROR': 'failed',
|
|
951
|
+
'FAILURE': 'failed',
|
|
952
|
+
};
|
|
953
|
+
return this.safeString(statuses, status, status);
|
|
954
|
+
}
|
|
955
|
+
convertDerivativesId(currency, type) {
|
|
956
|
+
// there is a difference between this and the v1 api, namely trading wallet is called margin in v2
|
|
957
|
+
// {
|
|
958
|
+
// "id": "fUSTF0",
|
|
959
|
+
// "code": "USTF0",
|
|
960
|
+
// "info": [ 'USTF0', [], [], [], [ "USTF0", "UST" ] ],
|
|
961
|
+
const info = this.safeValue(currency, 'info');
|
|
962
|
+
const transferId = this.safeString(info, 0);
|
|
963
|
+
const underlying = this.safeValue(info, 4, []);
|
|
964
|
+
let currencyId = undefined;
|
|
965
|
+
if (type === 'derivatives') {
|
|
966
|
+
currencyId = this.safeString(underlying, 0, transferId);
|
|
967
|
+
const start = currencyId.length - 2;
|
|
968
|
+
const isDerivativeCode = currencyId.slice(start) === 'F0';
|
|
969
|
+
if (!isDerivativeCode) {
|
|
970
|
+
currencyId = currencyId + 'F0';
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
else if (type !== 'margin') {
|
|
974
|
+
currencyId = this.safeString(underlying, 1, transferId);
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
currencyId = transferId;
|
|
978
|
+
}
|
|
979
|
+
return currencyId;
|
|
980
|
+
}
|
|
981
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
982
|
+
/**
|
|
983
|
+
* @method
|
|
984
|
+
* @name bitfinex2#fetchOrderBook
|
|
985
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
986
|
+
* @see https://docs.bitfinex.com/reference/rest-public-book
|
|
987
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
988
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
989
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
990
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
991
|
+
*/
|
|
992
|
+
await this.loadMarkets();
|
|
993
|
+
const precision = this.safeValue(this.options, 'precision', 'R0');
|
|
994
|
+
const market = this.market(symbol);
|
|
995
|
+
const request = {
|
|
996
|
+
'symbol': market['id'],
|
|
997
|
+
'precision': precision,
|
|
998
|
+
};
|
|
999
|
+
if (limit !== undefined) {
|
|
1000
|
+
request['len'] = limit; // 25 or 100
|
|
1001
|
+
}
|
|
1002
|
+
const fullRequest = this.extend(request, params);
|
|
1003
|
+
const orderbook = await this.publicGetBookSymbolPrecision(fullRequest);
|
|
1004
|
+
const timestamp = this.milliseconds();
|
|
1005
|
+
const result = {
|
|
1006
|
+
'symbol': market['symbol'],
|
|
1007
|
+
'bids': [],
|
|
1008
|
+
'asks': [],
|
|
1009
|
+
'timestamp': timestamp,
|
|
1010
|
+
'datetime': this.iso8601(timestamp),
|
|
1011
|
+
'nonce': undefined,
|
|
1012
|
+
};
|
|
1013
|
+
const priceIndex = (fullRequest['precision'] === 'R0') ? 1 : 0;
|
|
1014
|
+
for (let i = 0; i < orderbook.length; i++) {
|
|
1015
|
+
const order = orderbook[i];
|
|
1016
|
+
const price = this.safeNumber(order, priceIndex);
|
|
1017
|
+
const signedAmount = this.safeString(order, 2);
|
|
1018
|
+
const amount = Precise["default"].stringAbs(signedAmount);
|
|
1019
|
+
const side = Precise["default"].stringGt(signedAmount, '0') ? 'bids' : 'asks';
|
|
1020
|
+
result[side].push([price, this.parseNumber(amount)]);
|
|
1021
|
+
}
|
|
1022
|
+
result['bids'] = this.sortBy(result['bids'], 0, true);
|
|
1023
|
+
result['asks'] = this.sortBy(result['asks'], 0);
|
|
1024
|
+
return result;
|
|
1025
|
+
}
|
|
1026
|
+
parseTicker(ticker, market = undefined) {
|
|
1027
|
+
//
|
|
1028
|
+
// on trading pairs (ex. tBTCUSD)
|
|
1029
|
+
//
|
|
1030
|
+
// [
|
|
1031
|
+
// SYMBOL,
|
|
1032
|
+
// BID,
|
|
1033
|
+
// BID_SIZE,
|
|
1034
|
+
// ASK,
|
|
1035
|
+
// ASK_SIZE,
|
|
1036
|
+
// DAILY_CHANGE,
|
|
1037
|
+
// DAILY_CHANGE_RELATIVE,
|
|
1038
|
+
// LAST_PRICE,
|
|
1039
|
+
// VOLUME,
|
|
1040
|
+
// HIGH,
|
|
1041
|
+
// LOW
|
|
1042
|
+
// ]
|
|
1043
|
+
//
|
|
1044
|
+
// on funding currencies (ex. fUSD)
|
|
1045
|
+
//
|
|
1046
|
+
// [
|
|
1047
|
+
// SYMBOL,
|
|
1048
|
+
// FRR,
|
|
1049
|
+
// BID,
|
|
1050
|
+
// BID_PERIOD,
|
|
1051
|
+
// BID_SIZE,
|
|
1052
|
+
// ASK,
|
|
1053
|
+
// ASK_PERIOD,
|
|
1054
|
+
// ASK_SIZE,
|
|
1055
|
+
// DAILY_CHANGE,
|
|
1056
|
+
// DAILY_CHANGE_RELATIVE,
|
|
1057
|
+
// LAST_PRICE,
|
|
1058
|
+
// VOLUME,
|
|
1059
|
+
// HIGH,
|
|
1060
|
+
// LOW,
|
|
1061
|
+
// _PLACEHOLDER,
|
|
1062
|
+
// _PLACEHOLDER,
|
|
1063
|
+
// FRR_AMOUNT_AVAILABLE
|
|
1064
|
+
// ]
|
|
1065
|
+
//
|
|
1066
|
+
const symbol = this.safeSymbol(undefined, market);
|
|
1067
|
+
const length = ticker.length;
|
|
1068
|
+
const last = this.safeString(ticker, length - 4);
|
|
1069
|
+
const percentage = this.safeString(ticker, length - 5);
|
|
1070
|
+
return this.safeTicker({
|
|
1071
|
+
'symbol': symbol,
|
|
1072
|
+
'timestamp': undefined,
|
|
1073
|
+
'datetime': undefined,
|
|
1074
|
+
'high': this.safeString(ticker, length - 2),
|
|
1075
|
+
'low': this.safeString(ticker, length - 1),
|
|
1076
|
+
'bid': this.safeString(ticker, length - 10),
|
|
1077
|
+
'bidVolume': this.safeString(ticker, length - 9),
|
|
1078
|
+
'ask': this.safeString(ticker, length - 8),
|
|
1079
|
+
'askVolume': this.safeString(ticker, length - 7),
|
|
1080
|
+
'vwap': undefined,
|
|
1081
|
+
'open': undefined,
|
|
1082
|
+
'close': last,
|
|
1083
|
+
'last': last,
|
|
1084
|
+
'previousClose': undefined,
|
|
1085
|
+
'change': this.safeString(ticker, length - 6),
|
|
1086
|
+
'percentage': Precise["default"].stringMul(percentage, '100'),
|
|
1087
|
+
'average': undefined,
|
|
1088
|
+
'baseVolume': this.safeString(ticker, length - 3),
|
|
1089
|
+
'quoteVolume': undefined,
|
|
1090
|
+
'info': ticker,
|
|
1091
|
+
}, market);
|
|
1092
|
+
}
|
|
1093
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
1094
|
+
/**
|
|
1095
|
+
* @method
|
|
1096
|
+
* @name bitfinex2#fetchTickers
|
|
1097
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1098
|
+
* @see https://docs.bitfinex.com/reference/rest-public-tickers
|
|
1099
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1100
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1101
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1102
|
+
*/
|
|
1103
|
+
await this.loadMarkets();
|
|
1104
|
+
symbols = this.marketSymbols(symbols);
|
|
1105
|
+
const request = {};
|
|
1106
|
+
if (symbols !== undefined) {
|
|
1107
|
+
const ids = this.marketIds(symbols);
|
|
1108
|
+
request['symbols'] = ids.join(',');
|
|
1109
|
+
}
|
|
1110
|
+
else {
|
|
1111
|
+
request['symbols'] = 'ALL';
|
|
1112
|
+
}
|
|
1113
|
+
const tickers = await this.publicGetTickers(this.extend(request, params));
|
|
1114
|
+
//
|
|
1115
|
+
// [
|
|
1116
|
+
// // on trading pairs (ex. tBTCUSD)
|
|
1117
|
+
// [
|
|
1118
|
+
// SYMBOL,
|
|
1119
|
+
// BID,
|
|
1120
|
+
// BID_SIZE,
|
|
1121
|
+
// ASK,
|
|
1122
|
+
// ASK_SIZE,
|
|
1123
|
+
// DAILY_CHANGE,
|
|
1124
|
+
// DAILY_CHANGE_RELATIVE,
|
|
1125
|
+
// LAST_PRICE,
|
|
1126
|
+
// VOLUME,
|
|
1127
|
+
// HIGH,
|
|
1128
|
+
// LOW
|
|
1129
|
+
// ],
|
|
1130
|
+
// // on funding currencies (ex. fUSD)
|
|
1131
|
+
// [
|
|
1132
|
+
// SYMBOL,
|
|
1133
|
+
// FRR,
|
|
1134
|
+
// BID,
|
|
1135
|
+
// BID_PERIOD,
|
|
1136
|
+
// BID_SIZE,
|
|
1137
|
+
// ASK,
|
|
1138
|
+
// ASK_PERIOD,
|
|
1139
|
+
// ASK_SIZE,
|
|
1140
|
+
// DAILY_CHANGE,
|
|
1141
|
+
// DAILY_CHANGE_RELATIVE,
|
|
1142
|
+
// LAST_PRICE,
|
|
1143
|
+
// VOLUME,
|
|
1144
|
+
// HIGH,
|
|
1145
|
+
// LOW,
|
|
1146
|
+
// _PLACEHOLDER,
|
|
1147
|
+
// _PLACEHOLDER,
|
|
1148
|
+
// FRR_AMOUNT_AVAILABLE
|
|
1149
|
+
// ],
|
|
1150
|
+
// ...
|
|
1151
|
+
// ]
|
|
1152
|
+
//
|
|
1153
|
+
const result = {};
|
|
1154
|
+
for (let i = 0; i < tickers.length; i++) {
|
|
1155
|
+
const ticker = tickers[i];
|
|
1156
|
+
const marketId = this.safeString(ticker, 0);
|
|
1157
|
+
const market = this.safeMarket(marketId);
|
|
1158
|
+
const symbol = market['symbol'];
|
|
1159
|
+
result[symbol] = this.parseTicker(ticker, market);
|
|
1160
|
+
}
|
|
1161
|
+
return this.filterByArrayTickers(result, 'symbol', symbols);
|
|
1162
|
+
}
|
|
1163
|
+
async fetchTicker(symbol, params = {}) {
|
|
1164
|
+
/**
|
|
1165
|
+
* @method
|
|
1166
|
+
* @name bitfinex2#fetchTicker
|
|
1167
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1168
|
+
* @see https://docs.bitfinex.com/reference/rest-public-ticker
|
|
1169
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1170
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1171
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1172
|
+
*/
|
|
1173
|
+
await this.loadMarkets();
|
|
1174
|
+
const market = this.market(symbol);
|
|
1175
|
+
const request = {
|
|
1176
|
+
'symbol': market['id'],
|
|
1177
|
+
};
|
|
1178
|
+
const ticker = await this.publicGetTickerSymbol(this.extend(request, params));
|
|
1179
|
+
return this.parseTicker(ticker, market);
|
|
1180
|
+
}
|
|
1181
|
+
parseTrade(trade, market = undefined) {
|
|
1182
|
+
//
|
|
1183
|
+
// fetchTrades (public)
|
|
1184
|
+
//
|
|
1185
|
+
// [
|
|
1186
|
+
// ID,
|
|
1187
|
+
// MTS, // timestamp
|
|
1188
|
+
// AMOUNT,
|
|
1189
|
+
// PRICE
|
|
1190
|
+
// ]
|
|
1191
|
+
//
|
|
1192
|
+
// fetchMyTrades (private)
|
|
1193
|
+
//
|
|
1194
|
+
// [
|
|
1195
|
+
// ID,
|
|
1196
|
+
// PAIR,
|
|
1197
|
+
// MTS_CREATE,
|
|
1198
|
+
// ORDER_ID,
|
|
1199
|
+
// EXEC_AMOUNT,
|
|
1200
|
+
// EXEC_PRICE,
|
|
1201
|
+
// ORDER_TYPE,
|
|
1202
|
+
// ORDER_PRICE,
|
|
1203
|
+
// MAKER,
|
|
1204
|
+
// FEE,
|
|
1205
|
+
// FEE_CURRENCY,
|
|
1206
|
+
// ...
|
|
1207
|
+
// ]
|
|
1208
|
+
//
|
|
1209
|
+
const tradeLength = trade.length;
|
|
1210
|
+
const isPrivate = (tradeLength > 5);
|
|
1211
|
+
const id = this.safeString(trade, 0);
|
|
1212
|
+
const amountIndex = isPrivate ? 4 : 2;
|
|
1213
|
+
let side = undefined;
|
|
1214
|
+
let amountString = this.safeString(trade, amountIndex);
|
|
1215
|
+
const priceIndex = isPrivate ? 5 : 3;
|
|
1216
|
+
const priceString = this.safeString(trade, priceIndex);
|
|
1217
|
+
if (amountString[0] === '-') {
|
|
1218
|
+
side = 'sell';
|
|
1219
|
+
amountString = Precise["default"].stringAbs(amountString);
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
side = 'buy';
|
|
1223
|
+
}
|
|
1224
|
+
let orderId = undefined;
|
|
1225
|
+
let takerOrMaker = undefined;
|
|
1226
|
+
let type = undefined;
|
|
1227
|
+
let fee = undefined;
|
|
1228
|
+
let symbol = this.safeSymbol(undefined, market);
|
|
1229
|
+
const timestampIndex = isPrivate ? 2 : 1;
|
|
1230
|
+
const timestamp = this.safeInteger(trade, timestampIndex);
|
|
1231
|
+
if (isPrivate) {
|
|
1232
|
+
const marketId = trade[1];
|
|
1233
|
+
symbol = this.safeSymbol(marketId);
|
|
1234
|
+
orderId = this.safeString(trade, 3);
|
|
1235
|
+
const maker = this.safeInteger(trade, 8);
|
|
1236
|
+
takerOrMaker = (maker === 1) ? 'maker' : 'taker';
|
|
1237
|
+
let feeCostString = this.safeString(trade, 9);
|
|
1238
|
+
feeCostString = Precise["default"].stringNeg(feeCostString);
|
|
1239
|
+
const feeCurrencyId = this.safeString(trade, 10);
|
|
1240
|
+
const feeCurrency = this.safeCurrencyCode(feeCurrencyId);
|
|
1241
|
+
fee = {
|
|
1242
|
+
'cost': feeCostString,
|
|
1243
|
+
'currency': feeCurrency,
|
|
1244
|
+
};
|
|
1245
|
+
const orderType = trade[6];
|
|
1246
|
+
type = this.safeString(this.options['exchangeTypes'], orderType);
|
|
1247
|
+
}
|
|
1248
|
+
return this.safeTrade({
|
|
1249
|
+
'id': id,
|
|
1250
|
+
'timestamp': timestamp,
|
|
1251
|
+
'datetime': this.iso8601(timestamp),
|
|
1252
|
+
'symbol': symbol,
|
|
1253
|
+
'order': orderId,
|
|
1254
|
+
'side': side,
|
|
1255
|
+
'type': type,
|
|
1256
|
+
'takerOrMaker': takerOrMaker,
|
|
1257
|
+
'price': priceString,
|
|
1258
|
+
'amount': amountString,
|
|
1259
|
+
'cost': undefined,
|
|
1260
|
+
'fee': fee,
|
|
1261
|
+
'info': trade,
|
|
1262
|
+
}, market);
|
|
1263
|
+
}
|
|
1264
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1265
|
+
/**
|
|
1266
|
+
* @method
|
|
1267
|
+
* @name bitfinex2#fetchTrades
|
|
1268
|
+
* @description get the list of most recent trades for a particular symbol
|
|
1269
|
+
* @see https://docs.bitfinex.com/reference/rest-public-trades
|
|
1270
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1271
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1272
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1273
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1274
|
+
* @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)
|
|
1275
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
1276
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1277
|
+
*/
|
|
1278
|
+
await this.loadMarkets();
|
|
1279
|
+
let paginate = false;
|
|
1280
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchTrades', 'paginate');
|
|
1281
|
+
if (paginate) {
|
|
1282
|
+
return await this.fetchPaginatedCallDynamic('fetchTrades', symbol, since, limit, params, 10000);
|
|
1283
|
+
}
|
|
1284
|
+
const market = this.market(symbol);
|
|
1285
|
+
let sort = '-1';
|
|
1286
|
+
let request = {
|
|
1287
|
+
'symbol': market['id'],
|
|
1288
|
+
};
|
|
1289
|
+
if (since !== undefined) {
|
|
1290
|
+
request['start'] = since;
|
|
1291
|
+
sort = '1';
|
|
1292
|
+
}
|
|
1293
|
+
if (limit !== undefined) {
|
|
1294
|
+
request['limit'] = Math.min(limit, 10000); // default 120, max 10000
|
|
1295
|
+
}
|
|
1296
|
+
request['sort'] = sort;
|
|
1297
|
+
[request, params] = this.handleUntilOption('end', request, params);
|
|
1298
|
+
const response = await this.publicGetTradesSymbolHist(this.extend(request, params));
|
|
1299
|
+
//
|
|
1300
|
+
// [
|
|
1301
|
+
// [
|
|
1302
|
+
// ID,
|
|
1303
|
+
// MTS, // timestamp
|
|
1304
|
+
// AMOUNT,
|
|
1305
|
+
// PRICE
|
|
1306
|
+
// ]
|
|
1307
|
+
// ]
|
|
1308
|
+
//
|
|
1309
|
+
const trades = this.sortBy(response, 1);
|
|
1310
|
+
return this.parseTrades(trades, market, undefined, limit);
|
|
1311
|
+
}
|
|
1312
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = 100, params = {}) {
|
|
1313
|
+
/**
|
|
1314
|
+
* @method
|
|
1315
|
+
* @name bitfinex2#fetchOHLCV
|
|
1316
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1317
|
+
* @see https://docs.bitfinex.com/reference/rest-public-candles
|
|
1318
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1319
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1320
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1321
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1322
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1323
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1324
|
+
* @param {int} [params.until] timestamp in ms of the latest candle to fetch
|
|
1325
|
+
* @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)
|
|
1326
|
+
*/
|
|
1327
|
+
await this.loadMarkets();
|
|
1328
|
+
let paginate = false;
|
|
1329
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
|
|
1330
|
+
if (paginate) {
|
|
1331
|
+
return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 10000);
|
|
1332
|
+
}
|
|
1333
|
+
const market = this.market(symbol);
|
|
1334
|
+
if (limit === undefined) {
|
|
1335
|
+
limit = 10000; // default 100, max 5000
|
|
1336
|
+
}
|
|
1337
|
+
let request = {
|
|
1338
|
+
'symbol': market['id'],
|
|
1339
|
+
'timeframe': this.safeString(this.timeframes, timeframe, timeframe),
|
|
1340
|
+
'sort': 1,
|
|
1341
|
+
'start': since,
|
|
1342
|
+
'limit': limit,
|
|
1343
|
+
};
|
|
1344
|
+
[request, params] = this.handleUntilOption('end', request, params);
|
|
1345
|
+
const response = await this.publicGetCandlesTradeTimeframeSymbolHist(this.extend(request, params));
|
|
1346
|
+
//
|
|
1347
|
+
// [
|
|
1348
|
+
// [1591503840000,0.025069,0.025068,0.025069,0.025068,1.97828998],
|
|
1349
|
+
// [1591504500000,0.025065,0.025065,0.025065,0.025065,1.0164],
|
|
1350
|
+
// [1591504620000,0.025062,0.025062,0.025062,0.025062,0.5],
|
|
1351
|
+
// ]
|
|
1352
|
+
//
|
|
1353
|
+
return this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
1354
|
+
}
|
|
1355
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1356
|
+
//
|
|
1357
|
+
// [
|
|
1358
|
+
// 1457539800000,
|
|
1359
|
+
// 0.02594,
|
|
1360
|
+
// 0.02594,
|
|
1361
|
+
// 0.02594,
|
|
1362
|
+
// 0.02594,
|
|
1363
|
+
// 0.1
|
|
1364
|
+
// ]
|
|
1365
|
+
//
|
|
1366
|
+
return [
|
|
1367
|
+
this.safeInteger(ohlcv, 0),
|
|
1368
|
+
this.safeNumber(ohlcv, 1),
|
|
1369
|
+
this.safeNumber(ohlcv, 3),
|
|
1370
|
+
this.safeNumber(ohlcv, 4),
|
|
1371
|
+
this.safeNumber(ohlcv, 2),
|
|
1372
|
+
this.safeNumber(ohlcv, 5),
|
|
1373
|
+
];
|
|
1374
|
+
}
|
|
1375
|
+
parseOrderStatus(status) {
|
|
1376
|
+
if (status === undefined) {
|
|
1377
|
+
return status;
|
|
1378
|
+
}
|
|
1379
|
+
const parts = status.split(' ');
|
|
1380
|
+
const state = this.safeString(parts, 0);
|
|
1381
|
+
const statuses = {
|
|
1382
|
+
'ACTIVE': 'open',
|
|
1383
|
+
'PARTIALLY': 'open',
|
|
1384
|
+
'EXECUTED': 'closed',
|
|
1385
|
+
'CANCELED': 'canceled',
|
|
1386
|
+
'INSUFFICIENT': 'canceled',
|
|
1387
|
+
'POSTONLY CANCELED': 'canceled',
|
|
1388
|
+
'RSN_DUST': 'rejected',
|
|
1389
|
+
'RSN_PAUSE': 'rejected',
|
|
1390
|
+
'IOC CANCELED': 'canceled',
|
|
1391
|
+
'FILLORKILL CANCELED': 'canceled',
|
|
1392
|
+
};
|
|
1393
|
+
return this.safeString(statuses, state, status);
|
|
1394
|
+
}
|
|
1395
|
+
parseOrderFlags(flags) {
|
|
1396
|
+
// flags can be added to each other...
|
|
1397
|
+
const flagValues = {
|
|
1398
|
+
'1024': ['reduceOnly'],
|
|
1399
|
+
'4096': ['postOnly'],
|
|
1400
|
+
'5120': ['reduceOnly', 'postOnly'],
|
|
1401
|
+
// '64': 'hidden', // The hidden order option ensures an order does not appear in the order book
|
|
1402
|
+
// '512': 'close', // Close position if position present.
|
|
1403
|
+
// '16384': 'OCO', // The one cancels other order option allows you to place a pair of orders stipulating that if one order is executed fully or partially, then the other is automatically canceled.
|
|
1404
|
+
// '524288': 'No Var Rates' // Excludes variable rate funding offers from matching against this order, if on margin
|
|
1405
|
+
};
|
|
1406
|
+
return this.safeValue(flagValues, flags, undefined);
|
|
1407
|
+
}
|
|
1408
|
+
parseTimeInForce(orderType) {
|
|
1409
|
+
const orderTypes = {
|
|
1410
|
+
'EXCHANGE IOC': 'IOC',
|
|
1411
|
+
'EXCHANGE FOK': 'FOK',
|
|
1412
|
+
'IOC': 'IOC',
|
|
1413
|
+
'FOK': 'FOK', // Margin
|
|
1414
|
+
};
|
|
1415
|
+
return this.safeString(orderTypes, orderType, 'GTC');
|
|
1416
|
+
}
|
|
1417
|
+
parseOrder(order, market = undefined) {
|
|
1418
|
+
const id = this.safeString(order, 0);
|
|
1419
|
+
const marketId = this.safeString(order, 3);
|
|
1420
|
+
const symbol = this.safeSymbol(marketId);
|
|
1421
|
+
// https://github.com/ccxt/ccxt/issues/6686
|
|
1422
|
+
// const timestamp = this.safeTimestamp (order, 5);
|
|
1423
|
+
const timestamp = this.safeInteger(order, 5);
|
|
1424
|
+
const remaining = Precise["default"].stringAbs(this.safeString(order, 6));
|
|
1425
|
+
const signedAmount = this.safeString(order, 7);
|
|
1426
|
+
const amount = Precise["default"].stringAbs(signedAmount);
|
|
1427
|
+
const side = Precise["default"].stringLt(signedAmount, '0') ? 'sell' : 'buy';
|
|
1428
|
+
const orderType = this.safeString(order, 8);
|
|
1429
|
+
const type = this.safeString(this.safeValue(this.options, 'exchangeTypes'), orderType);
|
|
1430
|
+
const timeInForce = this.parseTimeInForce(orderType);
|
|
1431
|
+
const rawFlags = this.safeString(order, 12);
|
|
1432
|
+
const flags = this.parseOrderFlags(rawFlags);
|
|
1433
|
+
let postOnly = false;
|
|
1434
|
+
if (flags !== undefined) {
|
|
1435
|
+
for (let i = 0; i < flags.length; i++) {
|
|
1436
|
+
if (flags[i] === 'postOnly') {
|
|
1437
|
+
postOnly = true;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
let price = this.safeString(order, 16);
|
|
1442
|
+
let stopPrice = undefined;
|
|
1443
|
+
if ((orderType === 'EXCHANGE STOP') || (orderType === 'EXCHANGE STOP LIMIT')) {
|
|
1444
|
+
price = undefined;
|
|
1445
|
+
stopPrice = this.safeString(order, 16);
|
|
1446
|
+
if (orderType === 'EXCHANGE STOP LIMIT') {
|
|
1447
|
+
price = this.safeString(order, 19);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
let status = undefined;
|
|
1451
|
+
const statusString = this.safeString(order, 13);
|
|
1452
|
+
if (statusString !== undefined) {
|
|
1453
|
+
const parts = statusString.split(' @ ');
|
|
1454
|
+
status = this.parseOrderStatus(this.safeString(parts, 0));
|
|
1455
|
+
}
|
|
1456
|
+
const average = this.safeString(order, 17);
|
|
1457
|
+
const clientOrderId = this.safeString(order, 2);
|
|
1458
|
+
return this.safeOrder({
|
|
1459
|
+
'info': order,
|
|
1460
|
+
'id': id,
|
|
1461
|
+
'clientOrderId': clientOrderId,
|
|
1462
|
+
'timestamp': timestamp,
|
|
1463
|
+
'datetime': this.iso8601(timestamp),
|
|
1464
|
+
'lastTradeTimestamp': undefined,
|
|
1465
|
+
'symbol': symbol,
|
|
1466
|
+
'type': type,
|
|
1467
|
+
'timeInForce': timeInForce,
|
|
1468
|
+
'postOnly': postOnly,
|
|
1469
|
+
'side': side,
|
|
1470
|
+
'price': price,
|
|
1471
|
+
'stopPrice': stopPrice,
|
|
1472
|
+
'triggerPrice': stopPrice,
|
|
1473
|
+
'amount': amount,
|
|
1474
|
+
'cost': undefined,
|
|
1475
|
+
'average': average,
|
|
1476
|
+
'filled': undefined,
|
|
1477
|
+
'remaining': remaining,
|
|
1478
|
+
'status': status,
|
|
1479
|
+
'fee': undefined,
|
|
1480
|
+
'trades': undefined,
|
|
1481
|
+
}, market);
|
|
1482
|
+
}
|
|
1483
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1484
|
+
/**
|
|
1485
|
+
* @method
|
|
1486
|
+
* @name bitfinex2#createOrder
|
|
1487
|
+
* @description Create an order on the exchange
|
|
1488
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-submit-order
|
|
1489
|
+
* @param {string} symbol Unified CCXT market symbol
|
|
1490
|
+
* @param {string} type 'limit' or 'market'
|
|
1491
|
+
* @param {string} side 'buy' or 'sell'
|
|
1492
|
+
* @param {float} amount the amount of currency to trade
|
|
1493
|
+
* @param {float} [price] price of order
|
|
1494
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1495
|
+
* @param {float} [params.stopPrice] The price at which a trigger order is triggered at
|
|
1496
|
+
* @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
|
|
1497
|
+
* @param {bool} params.postOnly
|
|
1498
|
+
* @param {bool} [params.reduceOnly] Ensures that the executed order does not flip the opened position.
|
|
1499
|
+
* @param {int} [params.flags] additional order parameters: 4096 (Post Only), 1024 (Reduce Only), 16384 (OCO), 64 (Hidden), 512 (Close), 524288 (No Var Rates)
|
|
1500
|
+
* @param {int} [params.lev] leverage for a derivative order, supported by derivative symbol orders only. The value should be between 1 and 100 inclusive.
|
|
1501
|
+
* @param {string} [params.price_traling] The trailing price for a trailing stop order
|
|
1502
|
+
* @param {string} [params.price_aux_limit] Order price for stop limit orders
|
|
1503
|
+
* @param {string} [params.price_oco_stop] OCO stop price
|
|
1504
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1505
|
+
*/
|
|
1506
|
+
await this.loadMarkets();
|
|
1507
|
+
const market = this.market(symbol);
|
|
1508
|
+
// order types "limit" and "market" immediatley parsed "EXCHANGE LIMIT" and "EXCHANGE MARKET"
|
|
1509
|
+
// note: same order types exist for margin orders without the EXCHANGE prefix
|
|
1510
|
+
const orderTypes = this.safeValue(this.options, 'orderTypes', {});
|
|
1511
|
+
let orderType = type.toUpperCase();
|
|
1512
|
+
if (market['spot']) {
|
|
1513
|
+
// although they claim that type needs to be 'exchange limit' or 'exchange market'
|
|
1514
|
+
// in fact that's not the case for swap markets
|
|
1515
|
+
orderType = this.safeStringUpper(orderTypes, type, type);
|
|
1516
|
+
}
|
|
1517
|
+
const stopPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
|
|
1518
|
+
const timeInForce = this.safeString(params, 'timeInForce');
|
|
1519
|
+
const postOnlyParam = this.safeValue(params, 'postOnly', false);
|
|
1520
|
+
const reduceOnly = this.safeValue(params, 'reduceOnly', false);
|
|
1521
|
+
const clientOrderId = this.safeValue2(params, 'cid', 'clientOrderId');
|
|
1522
|
+
params = this.omit(params, ['triggerPrice', 'stopPrice', 'timeInForce', 'postOnly', 'reduceOnly', 'price_aux_limit']);
|
|
1523
|
+
let amountString = this.amountToPrecision(symbol, amount);
|
|
1524
|
+
amountString = (side === 'buy') ? amountString : Precise["default"].stringNeg(amountString);
|
|
1525
|
+
const request = {
|
|
1526
|
+
// 'gid': 0123456789, // int32, optional group id for the order
|
|
1527
|
+
// 'cid': 0123456789, // int32 client order id
|
|
1528
|
+
'type': orderType,
|
|
1529
|
+
'symbol': market['id'],
|
|
1530
|
+
// 'price': this.numberToString (price),
|
|
1531
|
+
'amount': amountString,
|
|
1532
|
+
// 'flags': 0, // int32, https://docs.bitfinex.com/v2/docs/flag-values
|
|
1533
|
+
// 'lev': 10, // leverage for a derivative orders, the value should be between 1 and 100 inclusive, optional, 10 by default
|
|
1534
|
+
// 'price_trailing': this.numberToString (priceTrailing),
|
|
1535
|
+
// 'price_aux_limit': this.numberToString (stopPrice),
|
|
1536
|
+
// 'price_oco_stop': this.numberToString (ocoStopPrice),
|
|
1537
|
+
// 'tif': '2020-01-01 10:45:23', // datetime for automatic order cancellation
|
|
1538
|
+
// 'meta': {
|
|
1539
|
+
// 'aff_code': 'AFF_CODE_HERE'
|
|
1540
|
+
// },
|
|
1541
|
+
};
|
|
1542
|
+
const stopLimit = ((orderType === 'EXCHANGE STOP LIMIT') || ((orderType === 'EXCHANGE LIMIT') && (stopPrice !== undefined)));
|
|
1543
|
+
const exchangeStop = (orderType === 'EXCHANGE STOP');
|
|
1544
|
+
const exchangeMarket = (orderType === 'EXCHANGE MARKET');
|
|
1545
|
+
const stopMarket = (exchangeStop || (exchangeMarket && (stopPrice !== undefined)));
|
|
1546
|
+
const ioc = ((orderType === 'EXCHANGE IOC') || (timeInForce === 'IOC'));
|
|
1547
|
+
const fok = ((orderType === 'EXCHANGE FOK') || (timeInForce === 'FOK'));
|
|
1548
|
+
const postOnly = (postOnlyParam || (timeInForce === 'PO'));
|
|
1549
|
+
if ((ioc || fok) && (price === undefined)) {
|
|
1550
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() requires a price argument with IOC and FOK orders');
|
|
1551
|
+
}
|
|
1552
|
+
if ((ioc || fok) && exchangeMarket) {
|
|
1553
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() does not allow market IOC and FOK orders');
|
|
1554
|
+
}
|
|
1555
|
+
if ((orderType !== 'MARKET') && (!exchangeMarket) && (!exchangeStop)) {
|
|
1556
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
1557
|
+
}
|
|
1558
|
+
if (stopLimit || stopMarket) {
|
|
1559
|
+
// request['price'] is taken as stopPrice for stop orders
|
|
1560
|
+
request['price'] = this.priceToPrecision(symbol, stopPrice);
|
|
1561
|
+
if (stopMarket) {
|
|
1562
|
+
request['type'] = 'EXCHANGE STOP';
|
|
1563
|
+
}
|
|
1564
|
+
else if (stopLimit) {
|
|
1565
|
+
request['type'] = 'EXCHANGE STOP LIMIT';
|
|
1566
|
+
request['price_aux_limit'] = this.priceToPrecision(symbol, price);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
if (ioc) {
|
|
1570
|
+
request['type'] = 'EXCHANGE IOC';
|
|
1571
|
+
}
|
|
1572
|
+
else if (fok) {
|
|
1573
|
+
request['type'] = 'EXCHANGE FOK';
|
|
1574
|
+
}
|
|
1575
|
+
// flag values may be summed to combine flags
|
|
1576
|
+
let flags = 0;
|
|
1577
|
+
if (postOnly) {
|
|
1578
|
+
flags = this.sum(flags, 4096);
|
|
1579
|
+
}
|
|
1580
|
+
if (reduceOnly) {
|
|
1581
|
+
flags = this.sum(flags, 1024);
|
|
1582
|
+
}
|
|
1583
|
+
if (flags !== 0) {
|
|
1584
|
+
request['flags'] = flags;
|
|
1585
|
+
}
|
|
1586
|
+
if (clientOrderId !== undefined) {
|
|
1587
|
+
request['cid'] = clientOrderId;
|
|
1588
|
+
params = this.omit(params, ['cid', 'clientOrderId']);
|
|
1589
|
+
}
|
|
1590
|
+
const response = await this.privatePostAuthWOrderSubmit(this.extend(request, params));
|
|
1591
|
+
//
|
|
1592
|
+
// [
|
|
1593
|
+
// 1653325121, // Timestamp in milliseconds
|
|
1594
|
+
// "on-req", // Purpose of notification ('on-req', 'oc-req', "uca", 'fon-req', "foc-req")
|
|
1595
|
+
// null, // unique ID of the message
|
|
1596
|
+
// null,
|
|
1597
|
+
// [
|
|
1598
|
+
// [
|
|
1599
|
+
// 95412102131, // Order ID
|
|
1600
|
+
// null, // Group ID
|
|
1601
|
+
// 1653325121798, // Client Order ID
|
|
1602
|
+
// "tDOGE:UST", // Market ID
|
|
1603
|
+
// 1653325121798, // Millisecond timestamp of creation
|
|
1604
|
+
// 1653325121798, // Millisecond timestamp of update
|
|
1605
|
+
// -10, // Amount (Positive means buy, negative means sell)
|
|
1606
|
+
// -10, // Original amount
|
|
1607
|
+
// "EXCHANGE LIMIT", // Type of the order: LIMIT, EXCHANGE LIMIT, MARKET, EXCHANGE MARKET, STOP, EXCHANGE STOP, STOP LIMIT, EXCHANGE STOP LIMIT, TRAILING STOP, EXCHANGE TRAILING STOP, FOK, EXCHANGE FOK, IOC, EXCHANGE IOC.
|
|
1608
|
+
// null, // Previous order type (stop-limit orders are converted to limit orders so for them previous type is always STOP)
|
|
1609
|
+
// null, // Millisecond timestamp of Time-In-Force: automatic order cancellation
|
|
1610
|
+
// null, // _PLACEHOLDER
|
|
1611
|
+
// 4096, // Flags, see parseOrderFlags()
|
|
1612
|
+
// "ACTIVE", // Order Status, see parseOrderStatus()
|
|
1613
|
+
// null, // _PLACEHOLDER
|
|
1614
|
+
// null, // _PLACEHOLDER
|
|
1615
|
+
// 0.071, // Price (Stop Price for stop-limit orders, Limit Price for limit orders)
|
|
1616
|
+
// 0, // Average Price
|
|
1617
|
+
// 0, // Trailing Price
|
|
1618
|
+
// 0, // Auxiliary Limit price (for STOP LIMIT)
|
|
1619
|
+
// null, // _PLACEHOLDER
|
|
1620
|
+
// null, // _PLACEHOLDER
|
|
1621
|
+
// null, // _PLACEHOLDER
|
|
1622
|
+
// 0, // Hidden (0 if false, 1 if true)
|
|
1623
|
+
// 0, // Placed ID (If another order caused this order to be placed (OCO) this will be that other order's ID)
|
|
1624
|
+
// null, // _PLACEHOLDER
|
|
1625
|
+
// null, // _PLACEHOLDER
|
|
1626
|
+
// null, // _PLACEHOLDER
|
|
1627
|
+
// "API>BFX", // Routing, indicates origin of action: BFX, ETHFX, API>BFX, API>ETHFX
|
|
1628
|
+
// null, // _PLACEHOLDER
|
|
1629
|
+
// null, // _PLACEHOLDER
|
|
1630
|
+
// {"$F7":1} // additional meta information about the order ( $F7 = IS_POST_ONLY (0 if false, 1 if true), $F33 = Leverage (int))
|
|
1631
|
+
// ]
|
|
1632
|
+
// ],
|
|
1633
|
+
// null, // CODE (work in progress)
|
|
1634
|
+
// "SUCCESS", // Status of the request
|
|
1635
|
+
// "Submitting 1 orders." // Message
|
|
1636
|
+
// ]
|
|
1637
|
+
//
|
|
1638
|
+
const status = this.safeString(response, 6);
|
|
1639
|
+
if (status !== 'SUCCESS') {
|
|
1640
|
+
const errorCode = response[5];
|
|
1641
|
+
const errorText = response[7];
|
|
1642
|
+
throw new errors.ExchangeError(this.id + ' ' + response[6] + ': ' + errorText + ' (#' + errorCode + ')');
|
|
1643
|
+
}
|
|
1644
|
+
const orders = this.safeValue(response, 4, []);
|
|
1645
|
+
const order = this.safeValue(orders, 0);
|
|
1646
|
+
return this.parseOrder(order, market);
|
|
1647
|
+
}
|
|
1648
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
1649
|
+
/**
|
|
1650
|
+
* @method
|
|
1651
|
+
* @name bitfinex2#cancelAllOrders
|
|
1652
|
+
* @description cancel all open orders
|
|
1653
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-cancel-orders-multiple
|
|
1654
|
+
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
1655
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1656
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1657
|
+
*/
|
|
1658
|
+
const request = {
|
|
1659
|
+
'all': 1,
|
|
1660
|
+
};
|
|
1661
|
+
const response = await this.privatePostAuthWOrderCancelMulti(this.extend(request, params));
|
|
1662
|
+
const orders = this.safeValue(response, 4, []);
|
|
1663
|
+
return this.parseOrders(orders);
|
|
1664
|
+
}
|
|
1665
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1666
|
+
/**
|
|
1667
|
+
* @method
|
|
1668
|
+
* @name bitfinex2#cancelOrder
|
|
1669
|
+
* @description cancels an open order
|
|
1670
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-cancel-order
|
|
1671
|
+
* @param {string} id order id
|
|
1672
|
+
* @param {string} symbol Not used by bitfinex2 cancelOrder ()
|
|
1673
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1674
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1675
|
+
*/
|
|
1676
|
+
const cid = this.safeValue2(params, 'cid', 'clientOrderId'); // client order id
|
|
1677
|
+
let request = undefined;
|
|
1678
|
+
if (cid !== undefined) {
|
|
1679
|
+
const cidDate = this.safeValue(params, 'cidDate'); // client order id date
|
|
1680
|
+
if (cidDate === undefined) {
|
|
1681
|
+
throw new errors.InvalidOrder(this.id + " canceling an order by clientOrderId ('cid') requires both 'cid' and 'cid_date' ('YYYY-MM-DD')");
|
|
1682
|
+
}
|
|
1683
|
+
request = {
|
|
1684
|
+
'cid': cid,
|
|
1685
|
+
'cid_date': cidDate,
|
|
1686
|
+
};
|
|
1687
|
+
params = this.omit(params, ['cid', 'clientOrderId']);
|
|
1688
|
+
}
|
|
1689
|
+
else {
|
|
1690
|
+
request = {
|
|
1691
|
+
'id': parseInt(id),
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
const response = await this.privatePostAuthWOrderCancel(this.extend(request, params));
|
|
1695
|
+
const order = this.safeValue(response, 4);
|
|
1696
|
+
return this.parseOrder(order);
|
|
1697
|
+
}
|
|
1698
|
+
async fetchOpenOrder(id, symbol = undefined, params = {}) {
|
|
1699
|
+
/**
|
|
1700
|
+
* @method
|
|
1701
|
+
* @name bitfinex2#fetchOpenOrder
|
|
1702
|
+
* @description fetch an open order by it's id
|
|
1703
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders
|
|
1704
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol
|
|
1705
|
+
* @param {string} id order id
|
|
1706
|
+
* @param {string} symbol unified market symbol, default is undefined
|
|
1707
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1708
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1709
|
+
*/
|
|
1710
|
+
const request = {
|
|
1711
|
+
'id': [parseInt(id)],
|
|
1712
|
+
};
|
|
1713
|
+
const orders = await this.fetchOpenOrders(symbol, undefined, undefined, this.extend(request, params));
|
|
1714
|
+
const order = this.safeValue(orders, 0);
|
|
1715
|
+
if (order === undefined) {
|
|
1716
|
+
throw new errors.OrderNotFound(this.id + ' order ' + id + ' not found');
|
|
1717
|
+
}
|
|
1718
|
+
return order;
|
|
1719
|
+
}
|
|
1720
|
+
async fetchClosedOrder(id, symbol = undefined, params = {}) {
|
|
1721
|
+
/**
|
|
1722
|
+
* @method
|
|
1723
|
+
* @name bitfinex2#fetchClosedOrder
|
|
1724
|
+
* @description fetch an open order by it's id
|
|
1725
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders
|
|
1726
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol
|
|
1727
|
+
* @param {string} id order id
|
|
1728
|
+
* @param {string} symbol unified market symbol, default is undefined
|
|
1729
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1730
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1731
|
+
*/
|
|
1732
|
+
const request = {
|
|
1733
|
+
'id': [parseInt(id)],
|
|
1734
|
+
};
|
|
1735
|
+
const orders = await this.fetchClosedOrders(symbol, undefined, undefined, this.extend(request, params));
|
|
1736
|
+
const order = this.safeValue(orders, 0);
|
|
1737
|
+
if (order === undefined) {
|
|
1738
|
+
throw new errors.OrderNotFound(this.id + ' order ' + id + ' not found');
|
|
1739
|
+
}
|
|
1740
|
+
return order;
|
|
1741
|
+
}
|
|
1742
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1743
|
+
/**
|
|
1744
|
+
* @method
|
|
1745
|
+
* @name bitfinex2#fetchOpenOrders
|
|
1746
|
+
* @description fetch all unfilled currently open orders
|
|
1747
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders
|
|
1748
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol
|
|
1749
|
+
* @param {string} symbol unified market symbol
|
|
1750
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
1751
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
1752
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1753
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1754
|
+
*/
|
|
1755
|
+
await this.loadMarkets();
|
|
1756
|
+
const request = {};
|
|
1757
|
+
let market = undefined;
|
|
1758
|
+
let response = undefined;
|
|
1759
|
+
if (symbol === undefined) {
|
|
1760
|
+
response = await this.privatePostAuthROrders(this.extend(request, params));
|
|
1761
|
+
}
|
|
1762
|
+
else {
|
|
1763
|
+
market = this.market(symbol);
|
|
1764
|
+
request['symbol'] = market['id'];
|
|
1765
|
+
response = await this.privatePostAuthROrdersSymbol(this.extend(request, params));
|
|
1766
|
+
}
|
|
1767
|
+
//
|
|
1768
|
+
// [
|
|
1769
|
+
// [
|
|
1770
|
+
// 95408916206, // Order ID
|
|
1771
|
+
// null, // Group Order ID
|
|
1772
|
+
// 1653322349926, // Client Order ID
|
|
1773
|
+
// "tDOGE:UST", // Market ID
|
|
1774
|
+
// 1653322349926, // Created Timestamp in milliseconds
|
|
1775
|
+
// 1653322349927, // Updated Timestamp in milliseconds
|
|
1776
|
+
// -10, // Amount remaining (Positive means buy, negative means sell)
|
|
1777
|
+
// -10, // Original amount
|
|
1778
|
+
// "EXCHANGE LIMIT", // Order type
|
|
1779
|
+
// null, // Previous Order Type
|
|
1780
|
+
// null, // _PLACEHOLDER
|
|
1781
|
+
// null, // _PLACEHOLDER
|
|
1782
|
+
// 0, // Flags, see parseOrderFlags()
|
|
1783
|
+
// "ACTIVE", // Order Status, see parseOrderStatus()
|
|
1784
|
+
// null, // _PLACEHOLDER
|
|
1785
|
+
// null, // _PLACEHOLDER
|
|
1786
|
+
// 0.11, // Price
|
|
1787
|
+
// 0, // Average Price
|
|
1788
|
+
// 0, // Trailing Price
|
|
1789
|
+
// 0, // Auxiliary Limit price (for STOP LIMIT)
|
|
1790
|
+
// null, // _PLACEHOLDER
|
|
1791
|
+
// null, // _PLACEHOLDER
|
|
1792
|
+
// null, // _PLACEHOLDER
|
|
1793
|
+
// 0, // Hidden (0 if false, 1 if true)
|
|
1794
|
+
// 0, // Placed ID (If another order caused this order to be placed (OCO) this will be that other order's ID)
|
|
1795
|
+
// null, // _PLACEHOLDER
|
|
1796
|
+
// null, // _PLACEHOLDER
|
|
1797
|
+
// null, // _PLACEHOLDER
|
|
1798
|
+
// "API>BFX", // Routing, indicates origin of action: BFX, ETHFX, API>BFX, API>ETHFX
|
|
1799
|
+
// null, // _PLACEHOLDER
|
|
1800
|
+
// null, // _PLACEHOLDER
|
|
1801
|
+
// {"$F7":1} // additional meta information about the order ( $F7 = IS_POST_ONLY (0 if false, 1 if true), $F33 = Leverage (int))
|
|
1802
|
+
// ],
|
|
1803
|
+
// ]
|
|
1804
|
+
//
|
|
1805
|
+
return this.parseOrders(response, market, since, limit);
|
|
1806
|
+
}
|
|
1807
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1808
|
+
/**
|
|
1809
|
+
* @method
|
|
1810
|
+
* @name bitfinex2#fetchClosedOrders
|
|
1811
|
+
* @description fetches information on multiple closed orders made by the user
|
|
1812
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders
|
|
1813
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol
|
|
1814
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1815
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1816
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1817
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1818
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
1819
|
+
* @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)
|
|
1820
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1821
|
+
*/
|
|
1822
|
+
// returns the most recent closed or canceled orders up to circa two weeks ago
|
|
1823
|
+
await this.loadMarkets();
|
|
1824
|
+
let paginate = false;
|
|
1825
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'paginate');
|
|
1826
|
+
if (paginate) {
|
|
1827
|
+
return await this.fetchPaginatedCallDynamic('fetchClosedOrders', symbol, since, limit, params);
|
|
1828
|
+
}
|
|
1829
|
+
let request = {};
|
|
1830
|
+
if (since !== undefined) {
|
|
1831
|
+
request['start'] = since;
|
|
1832
|
+
}
|
|
1833
|
+
if (limit !== undefined) {
|
|
1834
|
+
request['limit'] = limit; // default 25, max 2500
|
|
1835
|
+
}
|
|
1836
|
+
[request, params] = this.handleUntilOption('end', request, params);
|
|
1837
|
+
let market = undefined;
|
|
1838
|
+
let response = undefined;
|
|
1839
|
+
if (symbol === undefined) {
|
|
1840
|
+
response = await this.privatePostAuthROrdersHist(this.extend(request, params));
|
|
1841
|
+
}
|
|
1842
|
+
else {
|
|
1843
|
+
market = this.market(symbol);
|
|
1844
|
+
request['symbol'] = market['id'];
|
|
1845
|
+
response = await this.privatePostAuthROrdersSymbolHist(this.extend(request, params));
|
|
1846
|
+
}
|
|
1847
|
+
//
|
|
1848
|
+
// [
|
|
1849
|
+
// [
|
|
1850
|
+
// 95412102131, // Order ID
|
|
1851
|
+
// null, // Group Order ID
|
|
1852
|
+
// 1653325121798, // Client Order ID
|
|
1853
|
+
// "tDOGE:UST", // Market ID
|
|
1854
|
+
// 1653325122000, // Created Timestamp in milliseconds
|
|
1855
|
+
// 1653325122000, // Updated Timestamp in milliseconds
|
|
1856
|
+
// -10, // Amount remaining (Positive means buy, negative means sell)
|
|
1857
|
+
// -10, // Original amount
|
|
1858
|
+
// "EXCHANGE LIMIT", // Order type
|
|
1859
|
+
// null, // Previous Order Type
|
|
1860
|
+
// null, // Millisecond timestamp of Time-In-Force: automatic order cancellation
|
|
1861
|
+
// null, // _PLACEHOLDER
|
|
1862
|
+
// "4096", // Flags, see parseOrderFlags()
|
|
1863
|
+
// "POSTONLY CANCELED", // Order Status, see parseOrderStatus()
|
|
1864
|
+
// null, // _PLACEHOLDER
|
|
1865
|
+
// null, // _PLACEHOLDER
|
|
1866
|
+
// 0.071, // Price
|
|
1867
|
+
// 0, // Average Price
|
|
1868
|
+
// 0, // Trailing Price
|
|
1869
|
+
// 0, // Auxiliary Limit price (for STOP LIMIT)
|
|
1870
|
+
// null, // _PLACEHOLDER
|
|
1871
|
+
// null, // _PLACEHOLDER
|
|
1872
|
+
// null, // _PLACEHOLDER
|
|
1873
|
+
// 0, // Notify (0 if false, 1 if true)
|
|
1874
|
+
// 0, // Hidden (0 if false, 1 if true)
|
|
1875
|
+
// null, // Placed ID (If another order caused this order to be placed (OCO) this will be that other order's ID)
|
|
1876
|
+
// null, // _PLACEHOLDER
|
|
1877
|
+
// null, // _PLACEHOLDER
|
|
1878
|
+
// "API>BFX", // Routing, indicates origin of action: BFX, ETHFX, API>BFX, API>ETHFX
|
|
1879
|
+
// null, // _PLACEHOLDER
|
|
1880
|
+
// null, // _PLACEHOLDER
|
|
1881
|
+
// {"_$F7":1} // additional meta information about the order ( _$F7 = IS_POST_ONLY (0 if false, 1 if true), _$F33 = Leverage (int))
|
|
1882
|
+
// ]
|
|
1883
|
+
// ]
|
|
1884
|
+
//
|
|
1885
|
+
return this.parseOrders(response, market, since, limit);
|
|
1886
|
+
}
|
|
1887
|
+
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1888
|
+
/**
|
|
1889
|
+
* @method
|
|
1890
|
+
* @name bitfinex2#fetchOrderTrades
|
|
1891
|
+
* @description fetch all the trades made from a single order
|
|
1892
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-order-trades
|
|
1893
|
+
* @param {string} id order id
|
|
1894
|
+
* @param {string} symbol unified market symbol
|
|
1895
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1896
|
+
* @param {int} [limit] the maximum number of trades to retrieve
|
|
1897
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1898
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1899
|
+
*/
|
|
1900
|
+
if (symbol === undefined) {
|
|
1901
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchOrderTrades() requires a symbol argument');
|
|
1902
|
+
}
|
|
1903
|
+
await this.loadMarkets();
|
|
1904
|
+
const market = this.market(symbol);
|
|
1905
|
+
const orderId = parseInt(id);
|
|
1906
|
+
const request = {
|
|
1907
|
+
'id': orderId,
|
|
1908
|
+
'symbol': market['id'],
|
|
1909
|
+
};
|
|
1910
|
+
// valid for trades upto 10 days old
|
|
1911
|
+
const response = await this.privatePostAuthROrderSymbolIdTrades(this.extend(request, params));
|
|
1912
|
+
return this.parseTrades(response, market, since, limit);
|
|
1913
|
+
}
|
|
1914
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1915
|
+
/**
|
|
1916
|
+
* @method
|
|
1917
|
+
* @name bitfinex2#fetchMyTrades
|
|
1918
|
+
* @description fetch all trades made by the user
|
|
1919
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-trades
|
|
1920
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-trades-by-symbol
|
|
1921
|
+
* @param {string} symbol unified market symbol
|
|
1922
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1923
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
1924
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1925
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1926
|
+
*/
|
|
1927
|
+
await this.loadMarkets();
|
|
1928
|
+
let market = undefined;
|
|
1929
|
+
const request = {
|
|
1930
|
+
'end': this.milliseconds(),
|
|
1931
|
+
};
|
|
1932
|
+
if (since !== undefined) {
|
|
1933
|
+
request['start'] = since;
|
|
1934
|
+
}
|
|
1935
|
+
if (limit !== undefined) {
|
|
1936
|
+
request['limit'] = limit; // default 25, max 1000
|
|
1937
|
+
}
|
|
1938
|
+
let response = undefined;
|
|
1939
|
+
if (symbol !== undefined) {
|
|
1940
|
+
market = this.market(symbol);
|
|
1941
|
+
request['symbol'] = market['id'];
|
|
1942
|
+
response = await this.privatePostAuthRTradesSymbolHist(this.extend(request, params));
|
|
1943
|
+
}
|
|
1944
|
+
else {
|
|
1945
|
+
response = await this.privatePostAuthRTradesHist(this.extend(request, params));
|
|
1946
|
+
}
|
|
1947
|
+
return this.parseTrades(response, market, since, limit);
|
|
1948
|
+
}
|
|
1949
|
+
async createDepositAddress(code, params = {}) {
|
|
1950
|
+
/**
|
|
1951
|
+
* @method
|
|
1952
|
+
* @name bitfinex2#createDepositAddress
|
|
1953
|
+
* @description create a currency deposit address
|
|
1954
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-deposit-address
|
|
1955
|
+
* @param {string} code unified currency code of the currency for the deposit address
|
|
1956
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1957
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1958
|
+
*/
|
|
1959
|
+
await this.loadMarkets();
|
|
1960
|
+
const request = {
|
|
1961
|
+
'op_renew': 1,
|
|
1962
|
+
};
|
|
1963
|
+
return await this.fetchDepositAddress(code, this.extend(request, params));
|
|
1964
|
+
}
|
|
1965
|
+
async fetchDepositAddress(code, params = {}) {
|
|
1966
|
+
/**
|
|
1967
|
+
* @method
|
|
1968
|
+
* @name bitfinex2#fetchDepositAddress
|
|
1969
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
1970
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-deposit-address
|
|
1971
|
+
* @param {string} code unified currency code
|
|
1972
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1973
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1974
|
+
*/
|
|
1975
|
+
await this.loadMarkets();
|
|
1976
|
+
const currency = this.currency(code);
|
|
1977
|
+
// if not provided explicitly we will try to match using the currency name
|
|
1978
|
+
const network = this.safeString(params, 'network', code);
|
|
1979
|
+
const currencyNetworks = this.safeValue(currency, 'networks', {});
|
|
1980
|
+
const currencyNetwork = this.safeValue(currencyNetworks, network);
|
|
1981
|
+
const networkId = this.safeString(currencyNetwork, 'id');
|
|
1982
|
+
if (networkId === undefined) {
|
|
1983
|
+
throw new errors.ArgumentsRequired(this.id + " fetchDepositAddress() could not find a network for '" + code + "'. You can specify it by providing the 'network' value inside params");
|
|
1984
|
+
}
|
|
1985
|
+
const wallet = this.safeString(params, 'wallet', 'exchange'); // 'exchange', 'margin', 'funding' and also old labels 'exchange', 'trading', 'deposit', respectively
|
|
1986
|
+
params = this.omit(params, 'network', 'wallet');
|
|
1987
|
+
const request = {
|
|
1988
|
+
'method': networkId,
|
|
1989
|
+
'wallet': wallet,
|
|
1990
|
+
'op_renew': 0, // a value of 1 will generate a new address
|
|
1991
|
+
};
|
|
1992
|
+
const response = await this.privatePostAuthWDepositAddress(this.extend(request, params));
|
|
1993
|
+
//
|
|
1994
|
+
// [
|
|
1995
|
+
// 1582269616687, // MTS Millisecond Time Stamp of the update
|
|
1996
|
+
// "acc_dep", // TYPE Purpose of notification "acc_dep" for account deposit
|
|
1997
|
+
// null, // MESSAGE_ID unique ID of the message
|
|
1998
|
+
// null, // not documented
|
|
1999
|
+
// [
|
|
2000
|
+
// null, // PLACEHOLDER
|
|
2001
|
+
// "BITCOIN", // METHOD Method of deposit
|
|
2002
|
+
// "BTC", // CURRENCY_CODE Currency code of new address
|
|
2003
|
+
// null, // PLACEHOLDER
|
|
2004
|
+
// "1BC9PZqpUmjyEB54uggn8TFKj49zSDYzqG", // ADDRESS
|
|
2005
|
+
// null, // POOL_ADDRESS
|
|
2006
|
+
// ],
|
|
2007
|
+
// null, // CODE null or integer work in progress
|
|
2008
|
+
// "SUCCESS", // STATUS Status of the notification, SUCCESS, ERROR, FAILURE
|
|
2009
|
+
// "success", // TEXT Text of the notification
|
|
2010
|
+
// ]
|
|
2011
|
+
//
|
|
2012
|
+
const result = this.safeValue(response, 4, []);
|
|
2013
|
+
const poolAddress = this.safeString(result, 5);
|
|
2014
|
+
const address = (poolAddress === undefined) ? this.safeString(result, 4) : poolAddress;
|
|
2015
|
+
const tag = (poolAddress === undefined) ? undefined : this.safeString(result, 4);
|
|
2016
|
+
this.checkAddress(address);
|
|
2017
|
+
return {
|
|
2018
|
+
'currency': code,
|
|
2019
|
+
'address': address,
|
|
2020
|
+
'tag': tag,
|
|
2021
|
+
'network': undefined,
|
|
2022
|
+
'info': response,
|
|
2023
|
+
};
|
|
2024
|
+
}
|
|
2025
|
+
parseTransactionStatus(status) {
|
|
2026
|
+
const statuses = {
|
|
2027
|
+
'SUCCESS': 'ok',
|
|
2028
|
+
'COMPLETED': 'ok',
|
|
2029
|
+
'ERROR': 'failed',
|
|
2030
|
+
'FAILURE': 'failed',
|
|
2031
|
+
'CANCELED': 'canceled',
|
|
2032
|
+
'PENDING APPROVAL': 'pending',
|
|
2033
|
+
'PENDING': 'pending',
|
|
2034
|
+
'PENDING REVIEW': 'pending',
|
|
2035
|
+
'PENDING CANCELLATION': 'pending',
|
|
2036
|
+
'SENDING': 'pending',
|
|
2037
|
+
'USER APPROVED': 'pending',
|
|
2038
|
+
};
|
|
2039
|
+
return this.safeString(statuses, status, status);
|
|
2040
|
+
}
|
|
2041
|
+
parseTransaction(transaction, currency = undefined) {
|
|
2042
|
+
//
|
|
2043
|
+
// withdraw
|
|
2044
|
+
//
|
|
2045
|
+
// [
|
|
2046
|
+
// 1582271520931, // MTS Millisecond Time Stamp of the update
|
|
2047
|
+
// "acc_wd-req", // TYPE Purpose of notification "acc_wd-req" account withdrawal request
|
|
2048
|
+
// null, // MESSAGE_ID unique ID of the message
|
|
2049
|
+
// null, // not documented
|
|
2050
|
+
// [
|
|
2051
|
+
// 0, // WITHDRAWAL_ID Unique Withdrawal ID
|
|
2052
|
+
// null, // PLACEHOLDER
|
|
2053
|
+
// "bitcoin", // METHOD Method of withdrawal
|
|
2054
|
+
// null, // PAYMENT_ID Payment ID if relevant
|
|
2055
|
+
// "exchange", // WALLET Sending wallet
|
|
2056
|
+
// 1, // AMOUNT Amount of Withdrawal less fee
|
|
2057
|
+
// null, // PLACEHOLDER
|
|
2058
|
+
// null, // PLACEHOLDER
|
|
2059
|
+
// 0.0004, // WITHDRAWAL_FEE Fee on withdrawal
|
|
2060
|
+
// ],
|
|
2061
|
+
// null, // CODE null or integer Work in progress
|
|
2062
|
+
// "SUCCESS", // STATUS Status of the notification, it may vary over time SUCCESS, ERROR, FAILURE
|
|
2063
|
+
// "Invalid bitcoin address (abcdef)", // TEXT Text of the notification
|
|
2064
|
+
// ]
|
|
2065
|
+
//
|
|
2066
|
+
// fetchDepositsWithdrawals
|
|
2067
|
+
//
|
|
2068
|
+
// [
|
|
2069
|
+
// 13293039, // ID
|
|
2070
|
+
// "ETH", // CURRENCY
|
|
2071
|
+
// "ETHEREUM", // CURRENCY_NAME
|
|
2072
|
+
// null,
|
|
2073
|
+
// null,
|
|
2074
|
+
// 1574175052000, // MTS_STARTED
|
|
2075
|
+
// 1574181326000, // MTS_UPDATED
|
|
2076
|
+
// null,
|
|
2077
|
+
// null,
|
|
2078
|
+
// "CANCELED", // STATUS
|
|
2079
|
+
// null,
|
|
2080
|
+
// null,
|
|
2081
|
+
// -0.24, // AMOUNT, negative for withdrawals
|
|
2082
|
+
// -0.00135, // FEES
|
|
2083
|
+
// null,
|
|
2084
|
+
// null,
|
|
2085
|
+
// "0x38110e0Fc932CB2BE...........", // DESTINATION_ADDRESS
|
|
2086
|
+
// null,
|
|
2087
|
+
// null,
|
|
2088
|
+
// null,
|
|
2089
|
+
// "0x523ec8945500.....................................", // TRANSACTION_ID
|
|
2090
|
+
// "Purchase of 100 pizzas", // WITHDRAW_TRANSACTION_NOTE, might also be: null
|
|
2091
|
+
// ]
|
|
2092
|
+
//
|
|
2093
|
+
const transactionLength = transaction.length;
|
|
2094
|
+
let timestamp = undefined;
|
|
2095
|
+
let updated = undefined;
|
|
2096
|
+
let code = undefined;
|
|
2097
|
+
let amount = undefined;
|
|
2098
|
+
let id = undefined;
|
|
2099
|
+
let status = undefined;
|
|
2100
|
+
let tag = undefined;
|
|
2101
|
+
let type = undefined;
|
|
2102
|
+
let feeCost = undefined;
|
|
2103
|
+
let txid = undefined;
|
|
2104
|
+
let addressTo = undefined;
|
|
2105
|
+
let network = undefined;
|
|
2106
|
+
let comment = undefined;
|
|
2107
|
+
if (transactionLength === 8) {
|
|
2108
|
+
const data = this.safeValue(transaction, 4, []);
|
|
2109
|
+
timestamp = this.safeInteger(transaction, 0);
|
|
2110
|
+
if (currency !== undefined) {
|
|
2111
|
+
code = currency['code'];
|
|
2112
|
+
}
|
|
2113
|
+
feeCost = this.safeString(data, 8);
|
|
2114
|
+
if (feeCost !== undefined) {
|
|
2115
|
+
feeCost = Precise["default"].stringAbs(feeCost);
|
|
2116
|
+
}
|
|
2117
|
+
amount = this.safeNumber(data, 5);
|
|
2118
|
+
id = this.safeString(data, 0);
|
|
2119
|
+
status = 'ok';
|
|
2120
|
+
if (id === 0) {
|
|
2121
|
+
id = undefined;
|
|
2122
|
+
status = 'failed';
|
|
2123
|
+
}
|
|
2124
|
+
tag = this.safeString(data, 3);
|
|
2125
|
+
type = 'withdrawal';
|
|
2126
|
+
}
|
|
2127
|
+
else if (transactionLength === 22) {
|
|
2128
|
+
id = this.safeString(transaction, 0);
|
|
2129
|
+
const currencyId = this.safeString(transaction, 1);
|
|
2130
|
+
code = this.safeCurrencyCode(currencyId, currency);
|
|
2131
|
+
const networkId = this.safeString(transaction, 2);
|
|
2132
|
+
network = this.safeNetwork(networkId);
|
|
2133
|
+
timestamp = this.safeInteger(transaction, 5);
|
|
2134
|
+
updated = this.safeInteger(transaction, 6);
|
|
2135
|
+
status = this.parseTransactionStatus(this.safeString(transaction, 9));
|
|
2136
|
+
const signedAmount = this.safeString(transaction, 12);
|
|
2137
|
+
amount = Precise["default"].stringAbs(signedAmount);
|
|
2138
|
+
if (signedAmount !== undefined) {
|
|
2139
|
+
if (Precise["default"].stringLt(signedAmount, '0')) {
|
|
2140
|
+
type = 'withdrawal';
|
|
2141
|
+
}
|
|
2142
|
+
else {
|
|
2143
|
+
type = 'deposit';
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
feeCost = this.safeString(transaction, 13);
|
|
2147
|
+
if (feeCost !== undefined) {
|
|
2148
|
+
feeCost = Precise["default"].stringAbs(feeCost);
|
|
2149
|
+
}
|
|
2150
|
+
addressTo = this.safeString(transaction, 16);
|
|
2151
|
+
txid = this.safeString(transaction, 20);
|
|
2152
|
+
comment = this.safeString(transaction, 21);
|
|
2153
|
+
}
|
|
2154
|
+
return {
|
|
2155
|
+
'info': transaction,
|
|
2156
|
+
'id': id,
|
|
2157
|
+
'txid': txid,
|
|
2158
|
+
'type': type,
|
|
2159
|
+
'currency': code,
|
|
2160
|
+
'network': network,
|
|
2161
|
+
'amount': this.parseNumber(amount),
|
|
2162
|
+
'status': status,
|
|
2163
|
+
'timestamp': timestamp,
|
|
2164
|
+
'datetime': this.iso8601(timestamp),
|
|
2165
|
+
'address': addressTo,
|
|
2166
|
+
'addressFrom': undefined,
|
|
2167
|
+
'addressTo': addressTo,
|
|
2168
|
+
'tag': tag,
|
|
2169
|
+
'tagFrom': undefined,
|
|
2170
|
+
'tagTo': tag,
|
|
2171
|
+
'updated': updated,
|
|
2172
|
+
'comment': comment,
|
|
2173
|
+
'internal': undefined,
|
|
2174
|
+
'fee': {
|
|
2175
|
+
'currency': code,
|
|
2176
|
+
'cost': this.parseNumber(feeCost),
|
|
2177
|
+
'rate': undefined,
|
|
2178
|
+
},
|
|
2179
|
+
};
|
|
2180
|
+
}
|
|
2181
|
+
async fetchTradingFees(params = {}) {
|
|
2182
|
+
/**
|
|
2183
|
+
* @method
|
|
2184
|
+
* @name bitfinex2#fetchTradingFees
|
|
2185
|
+
* @description fetch the trading fees for multiple markets
|
|
2186
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-summary
|
|
2187
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2188
|
+
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
2189
|
+
*/
|
|
2190
|
+
await this.loadMarkets();
|
|
2191
|
+
const response = await this.privatePostAuthRSummary(params);
|
|
2192
|
+
//
|
|
2193
|
+
// Response Spec:
|
|
2194
|
+
// [
|
|
2195
|
+
// PLACEHOLDER,
|
|
2196
|
+
// PLACEHOLDER,
|
|
2197
|
+
// PLACEHOLDER,
|
|
2198
|
+
// PLACEHOLDER,
|
|
2199
|
+
// [
|
|
2200
|
+
// [
|
|
2201
|
+
// MAKER_FEE,
|
|
2202
|
+
// MAKER_FEE,
|
|
2203
|
+
// MAKER_FEE,
|
|
2204
|
+
// PLACEHOLDER,
|
|
2205
|
+
// PLACEHOLDER,
|
|
2206
|
+
// DERIV_REBATE
|
|
2207
|
+
// ],
|
|
2208
|
+
// [
|
|
2209
|
+
// TAKER_FEE_TO_CRYPTO,
|
|
2210
|
+
// TAKER_FEE_TO_STABLE,
|
|
2211
|
+
// TAKER_FEE_TO_FIAT,
|
|
2212
|
+
// PLACEHOLDER,
|
|
2213
|
+
// PLACEHOLDER,
|
|
2214
|
+
// DERIV_TAKER_FEE
|
|
2215
|
+
// ]
|
|
2216
|
+
// ],
|
|
2217
|
+
// PLACEHOLDER,
|
|
2218
|
+
// PLACEHOLDER,
|
|
2219
|
+
// PLACEHOLDER,
|
|
2220
|
+
// PLACEHOLDER,
|
|
2221
|
+
// {
|
|
2222
|
+
// LEO_LEV,
|
|
2223
|
+
// LEO_AMOUNT_AVG
|
|
2224
|
+
// }
|
|
2225
|
+
// ]
|
|
2226
|
+
//
|
|
2227
|
+
// Example response:
|
|
2228
|
+
//
|
|
2229
|
+
// [
|
|
2230
|
+
// null,
|
|
2231
|
+
// null,
|
|
2232
|
+
// null,
|
|
2233
|
+
// null,
|
|
2234
|
+
// [
|
|
2235
|
+
// [ 0.001, 0.001, 0.001, null, null, 0.0002 ],
|
|
2236
|
+
// [ 0.002, 0.002, 0.002, null, null, 0.00065 ]
|
|
2237
|
+
// ],
|
|
2238
|
+
// [
|
|
2239
|
+
// [
|
|
2240
|
+
// {
|
|
2241
|
+
// "curr": "Total (USD)",
|
|
2242
|
+
// "vol": "0",
|
|
2243
|
+
// "vol_safe": "0",
|
|
2244
|
+
// "vol_maker": "0",
|
|
2245
|
+
// "vol_BFX": "0",
|
|
2246
|
+
// "vol_BFX_safe": "0",
|
|
2247
|
+
// "vol_BFX_maker": "0"
|
|
2248
|
+
// }
|
|
2249
|
+
// ],
|
|
2250
|
+
// {},
|
|
2251
|
+
// 0
|
|
2252
|
+
// ],
|
|
2253
|
+
// [ null, {}, 0 ],
|
|
2254
|
+
// null,
|
|
2255
|
+
// null,
|
|
2256
|
+
// { leo_lev: "0", leo_amount_avg: "0" }
|
|
2257
|
+
// ]
|
|
2258
|
+
//
|
|
2259
|
+
const result = {};
|
|
2260
|
+
const fiat = this.safeValue(this.options, 'fiat', {});
|
|
2261
|
+
const feeData = this.safeValue(response, 4, []);
|
|
2262
|
+
const makerData = this.safeValue(feeData, 0, []);
|
|
2263
|
+
const takerData = this.safeValue(feeData, 1, []);
|
|
2264
|
+
const makerFee = this.safeNumber(makerData, 0);
|
|
2265
|
+
const makerFeeFiat = this.safeNumber(makerData, 2);
|
|
2266
|
+
const makerFeeDeriv = this.safeNumber(makerData, 5);
|
|
2267
|
+
const takerFee = this.safeNumber(takerData, 0);
|
|
2268
|
+
const takerFeeFiat = this.safeNumber(takerData, 2);
|
|
2269
|
+
const takerFeeDeriv = this.safeNumber(takerData, 5);
|
|
2270
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
|
2271
|
+
const symbol = this.symbols[i];
|
|
2272
|
+
const market = this.market(symbol);
|
|
2273
|
+
const fee = {
|
|
2274
|
+
'info': response,
|
|
2275
|
+
'symbol': symbol,
|
|
2276
|
+
'percentage': true,
|
|
2277
|
+
'tierBased': true,
|
|
2278
|
+
};
|
|
2279
|
+
if (market['quote'] in fiat) {
|
|
2280
|
+
fee['maker'] = makerFeeFiat;
|
|
2281
|
+
fee['taker'] = takerFeeFiat;
|
|
2282
|
+
}
|
|
2283
|
+
else if (market['contract']) {
|
|
2284
|
+
fee['maker'] = makerFeeDeriv;
|
|
2285
|
+
fee['taker'] = takerFeeDeriv;
|
|
2286
|
+
}
|
|
2287
|
+
else { // TODO check if stable coin
|
|
2288
|
+
fee['maker'] = makerFee;
|
|
2289
|
+
fee['taker'] = takerFee;
|
|
2290
|
+
}
|
|
2291
|
+
result[symbol] = fee;
|
|
2292
|
+
}
|
|
2293
|
+
return result;
|
|
2294
|
+
}
|
|
2295
|
+
async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2296
|
+
/**
|
|
2297
|
+
* @method
|
|
2298
|
+
* @name bitfinex2#fetchDepositsWithdrawals
|
|
2299
|
+
* @description fetch history of deposits and withdrawals
|
|
2300
|
+
* @see https://docs.bitfinex.com/reference/movement-info
|
|
2301
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-movements
|
|
2302
|
+
* @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
|
|
2303
|
+
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
|
2304
|
+
* @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
|
|
2305
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2306
|
+
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2307
|
+
*/
|
|
2308
|
+
await this.loadMarkets();
|
|
2309
|
+
let currency = undefined;
|
|
2310
|
+
const request = {};
|
|
2311
|
+
if (since !== undefined) {
|
|
2312
|
+
request['start'] = since;
|
|
2313
|
+
}
|
|
2314
|
+
if (limit !== undefined) {
|
|
2315
|
+
request['limit'] = limit; // max 1000
|
|
2316
|
+
}
|
|
2317
|
+
let response = undefined;
|
|
2318
|
+
if (code !== undefined) {
|
|
2319
|
+
currency = this.currency(code);
|
|
2320
|
+
request['currency'] = currency['uppercaseId'];
|
|
2321
|
+
response = await this.privatePostAuthRMovementsCurrencyHist(this.extend(request, params));
|
|
2322
|
+
}
|
|
2323
|
+
else {
|
|
2324
|
+
response = await this.privatePostAuthRMovementsHist(this.extend(request, params));
|
|
2325
|
+
}
|
|
2326
|
+
//
|
|
2327
|
+
// [
|
|
2328
|
+
// [
|
|
2329
|
+
// 13293039, // ID
|
|
2330
|
+
// "ETH", // CURRENCY
|
|
2331
|
+
// "ETHEREUM", // CURRENCY_NAME
|
|
2332
|
+
// null,
|
|
2333
|
+
// null,
|
|
2334
|
+
// 1574175052000, // MTS_STARTED
|
|
2335
|
+
// 1574181326000, // MTS_UPDATED
|
|
2336
|
+
// null,
|
|
2337
|
+
// null,
|
|
2338
|
+
// "CANCELED", // STATUS
|
|
2339
|
+
// null,
|
|
2340
|
+
// null,
|
|
2341
|
+
// -0.24, // AMOUNT, negative for withdrawals
|
|
2342
|
+
// -0.00135, // FEES
|
|
2343
|
+
// null,
|
|
2344
|
+
// null,
|
|
2345
|
+
// "0x38110e0Fc932CB2BE...........", // DESTINATION_ADDRESS
|
|
2346
|
+
// null,
|
|
2347
|
+
// null,
|
|
2348
|
+
// null,
|
|
2349
|
+
// "0x523ec8945500.....................................", // TRANSACTION_ID
|
|
2350
|
+
// "Purchase of 100 pizzas", // WITHDRAW_TRANSACTION_NOTE, might also be: null
|
|
2351
|
+
// ]
|
|
2352
|
+
// ]
|
|
2353
|
+
//
|
|
2354
|
+
return this.parseTransactions(response, currency, since, limit);
|
|
2355
|
+
}
|
|
2356
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2357
|
+
/**
|
|
2358
|
+
* @method
|
|
2359
|
+
* @name bitfinex2#withdraw
|
|
2360
|
+
* @description make a withdrawal
|
|
2361
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-withdraw
|
|
2362
|
+
* @param {string} code unified currency code
|
|
2363
|
+
* @param {float} amount the amount to withdraw
|
|
2364
|
+
* @param {string} address the address to withdraw to
|
|
2365
|
+
* @param {string} tag
|
|
2366
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2367
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2368
|
+
*/
|
|
2369
|
+
this.checkAddress(address);
|
|
2370
|
+
await this.loadMarkets();
|
|
2371
|
+
const currency = this.currency(code);
|
|
2372
|
+
// if not provided explicitly we will try to match using the currency name
|
|
2373
|
+
const network = this.safeString(params, 'network', code);
|
|
2374
|
+
params = this.omit(params, 'network');
|
|
2375
|
+
const currencyNetworks = this.safeValue(currency, 'networks', {});
|
|
2376
|
+
const currencyNetwork = this.safeValue(currencyNetworks, network);
|
|
2377
|
+
const networkId = this.safeString(currencyNetwork, 'id');
|
|
2378
|
+
if (networkId === undefined) {
|
|
2379
|
+
throw new errors.ArgumentsRequired(this.id + " withdraw() could not find a network for '" + code + "'. You can specify it by providing the 'network' value inside params");
|
|
2380
|
+
}
|
|
2381
|
+
const wallet = this.safeString(params, 'wallet', 'exchange'); // 'exchange', 'margin', 'funding' and also old labels 'exchange', 'trading', 'deposit', respectively
|
|
2382
|
+
params = this.omit(params, 'network', 'wallet');
|
|
2383
|
+
const request = {
|
|
2384
|
+
'method': networkId,
|
|
2385
|
+
'wallet': wallet,
|
|
2386
|
+
'amount': this.numberToString(amount),
|
|
2387
|
+
'address': address,
|
|
2388
|
+
};
|
|
2389
|
+
if (tag !== undefined) {
|
|
2390
|
+
request['payment_id'] = tag;
|
|
2391
|
+
}
|
|
2392
|
+
const withdrawOptions = this.safeValue(this.options, 'withdraw', {});
|
|
2393
|
+
const includeFee = this.safeValue(withdrawOptions, 'includeFee', false);
|
|
2394
|
+
if (includeFee) {
|
|
2395
|
+
request['fee_deduct'] = 1;
|
|
2396
|
+
}
|
|
2397
|
+
const response = await this.privatePostAuthWWithdraw(this.extend(request, params));
|
|
2398
|
+
//
|
|
2399
|
+
// [
|
|
2400
|
+
// 1582271520931, // MTS Millisecond Time Stamp of the update
|
|
2401
|
+
// "acc_wd-req", // TYPE Purpose of notification "acc_wd-req" account withdrawal request
|
|
2402
|
+
// null, // MESSAGE_ID unique ID of the message
|
|
2403
|
+
// null, // not documented
|
|
2404
|
+
// [
|
|
2405
|
+
// 0, // WITHDRAWAL_ID Unique Withdrawal ID
|
|
2406
|
+
// null, // PLACEHOLDER
|
|
2407
|
+
// "bitcoin", // METHOD Method of withdrawal
|
|
2408
|
+
// null, // PAYMENT_ID Payment ID if relevant
|
|
2409
|
+
// "exchange", // WALLET Sending wallet
|
|
2410
|
+
// 1, // AMOUNT Amount of Withdrawal less fee
|
|
2411
|
+
// null, // PLACEHOLDER
|
|
2412
|
+
// null, // PLACEHOLDER
|
|
2413
|
+
// 0.0004, // WITHDRAWAL_FEE Fee on withdrawal
|
|
2414
|
+
// ],
|
|
2415
|
+
// null, // CODE null or integer Work in progress
|
|
2416
|
+
// "SUCCESS", // STATUS Status of the notification, it may vary over time SUCCESS, ERROR, FAILURE
|
|
2417
|
+
// "Invalid bitcoin address (abcdef)", // TEXT Text of the notification
|
|
2418
|
+
// ]
|
|
2419
|
+
//
|
|
2420
|
+
// in case of failure:
|
|
2421
|
+
//
|
|
2422
|
+
// [
|
|
2423
|
+
// "error",
|
|
2424
|
+
// 10001,
|
|
2425
|
+
// "Momentary balance check. Please wait few seconds and try the transfer again."
|
|
2426
|
+
// ]
|
|
2427
|
+
//
|
|
2428
|
+
const statusMessage = this.safeString(response, 0);
|
|
2429
|
+
if (statusMessage === 'error') {
|
|
2430
|
+
const feedback = this.id + ' ' + response;
|
|
2431
|
+
const message = this.safeString(response, 2, '');
|
|
2432
|
+
// same message as in v1
|
|
2433
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
2434
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
2435
|
+
throw new errors.ExchangeError(feedback); // unknown message
|
|
2436
|
+
}
|
|
2437
|
+
const text = this.safeString(response, 7);
|
|
2438
|
+
if (text !== 'success') {
|
|
2439
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], text, text);
|
|
2440
|
+
}
|
|
2441
|
+
const transaction = this.parseTransaction(response, currency);
|
|
2442
|
+
return this.extend(transaction, {
|
|
2443
|
+
'address': address,
|
|
2444
|
+
});
|
|
2445
|
+
}
|
|
2446
|
+
async fetchPositions(symbols = undefined, params = {}) {
|
|
2447
|
+
/**
|
|
2448
|
+
* @method
|
|
2449
|
+
* @name bitfinex2#fetchPositions
|
|
2450
|
+
* @description fetch all open positions
|
|
2451
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-positions
|
|
2452
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
2453
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2454
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2455
|
+
*/
|
|
2456
|
+
await this.loadMarkets();
|
|
2457
|
+
symbols = this.marketSymbols(symbols);
|
|
2458
|
+
const response = await this.privatePostAuthRPositions(params);
|
|
2459
|
+
//
|
|
2460
|
+
// [
|
|
2461
|
+
// [
|
|
2462
|
+
// "tBTCUSD", // SYMBOL
|
|
2463
|
+
// "ACTIVE", // STATUS
|
|
2464
|
+
// 0.0195, // AMOUNT
|
|
2465
|
+
// 8565.0267019, // BASE_PRICE
|
|
2466
|
+
// 0, // MARGIN_FUNDING
|
|
2467
|
+
// 0, // MARGIN_FUNDING_TYPE
|
|
2468
|
+
// -0.33455568705000516, // PL
|
|
2469
|
+
// -0.0003117550117425625, // PL_PERC
|
|
2470
|
+
// 7045.876419249083, // PRICE_LIQ
|
|
2471
|
+
// 3.0673001895895604, // LEVERAGE
|
|
2472
|
+
// null, // _PLACEHOLDER
|
|
2473
|
+
// 142355652, // POSITION_ID
|
|
2474
|
+
// 1574002216000, // MTS_CREATE
|
|
2475
|
+
// 1574002216000, // MTS_UPDATE
|
|
2476
|
+
// null, // _PLACEHOLDER
|
|
2477
|
+
// 0, // TYPE
|
|
2478
|
+
// null, // _PLACEHOLDER
|
|
2479
|
+
// 0, // COLLATERAL
|
|
2480
|
+
// 0, // COLLATERAL_MIN
|
|
2481
|
+
// // META
|
|
2482
|
+
// {
|
|
2483
|
+
// "reason":"TRADE",
|
|
2484
|
+
// "order_id":34271018124,
|
|
2485
|
+
// "liq_stage":null,
|
|
2486
|
+
// "trade_price":"8565.0267019",
|
|
2487
|
+
// "trade_amount":"0.0195",
|
|
2488
|
+
// "order_id_oppo":34277498022
|
|
2489
|
+
// }
|
|
2490
|
+
// ]
|
|
2491
|
+
// ]
|
|
2492
|
+
//
|
|
2493
|
+
return this.parsePositions(response, symbols);
|
|
2494
|
+
}
|
|
2495
|
+
parsePosition(position, market = undefined) {
|
|
2496
|
+
//
|
|
2497
|
+
// [
|
|
2498
|
+
// "tBTCUSD", // SYMBOL
|
|
2499
|
+
// "ACTIVE", // STATUS
|
|
2500
|
+
// 0.0195, // AMOUNT
|
|
2501
|
+
// 8565.0267019, // BASE_PRICE
|
|
2502
|
+
// 0, // MARGIN_FUNDING
|
|
2503
|
+
// 0, // MARGIN_FUNDING_TYPE
|
|
2504
|
+
// -0.33455568705000516, // PL
|
|
2505
|
+
// -0.0003117550117425625, // PL_PERC
|
|
2506
|
+
// 7045.876419249083, // PRICE_LIQ
|
|
2507
|
+
// 3.0673001895895604, // LEVERAGE
|
|
2508
|
+
// null, // _PLACEHOLDER
|
|
2509
|
+
// 142355652, // POSITION_ID
|
|
2510
|
+
// 1574002216000, // MTS_CREATE
|
|
2511
|
+
// 1574002216000, // MTS_UPDATE
|
|
2512
|
+
// null, // _PLACEHOLDER
|
|
2513
|
+
// 0, // TYPE
|
|
2514
|
+
// null, // _PLACEHOLDER
|
|
2515
|
+
// 0, // COLLATERAL
|
|
2516
|
+
// 0, // COLLATERAL_MIN
|
|
2517
|
+
// // META
|
|
2518
|
+
// {
|
|
2519
|
+
// "reason": "TRADE",
|
|
2520
|
+
// "order_id": 34271018124,
|
|
2521
|
+
// "liq_stage": null,
|
|
2522
|
+
// "trade_price": "8565.0267019",
|
|
2523
|
+
// "trade_amount": "0.0195",
|
|
2524
|
+
// "order_id_oppo": 34277498022
|
|
2525
|
+
// }
|
|
2526
|
+
// ]
|
|
2527
|
+
//
|
|
2528
|
+
const marketId = this.safeString(position, 0);
|
|
2529
|
+
const amount = this.safeString(position, 2);
|
|
2530
|
+
const timestamp = this.safeInteger(position, 12);
|
|
2531
|
+
const meta = this.safeString(position, 19);
|
|
2532
|
+
const tradePrice = this.safeString(meta, 'trade_price');
|
|
2533
|
+
const tradeAmount = this.safeString(meta, 'trade_amount');
|
|
2534
|
+
return this.safePosition({
|
|
2535
|
+
'info': position,
|
|
2536
|
+
'id': this.safeString(position, 11),
|
|
2537
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
2538
|
+
'notional': this.parseNumber(amount),
|
|
2539
|
+
'marginMode': 'isolated',
|
|
2540
|
+
'liquidationPrice': this.safeNumber(position, 8),
|
|
2541
|
+
'entryPrice': this.safeNumber(position, 3),
|
|
2542
|
+
'unrealizedPnl': this.safeNumber(position, 6),
|
|
2543
|
+
'percentage': this.safeNumber(position, 7),
|
|
2544
|
+
'contracts': undefined,
|
|
2545
|
+
'contractSize': undefined,
|
|
2546
|
+
'markPrice': undefined,
|
|
2547
|
+
'lastPrice': undefined,
|
|
2548
|
+
'side': Precise["default"].stringGt(amount, '0') ? 'long' : 'short',
|
|
2549
|
+
'hedged': undefined,
|
|
2550
|
+
'timestamp': timestamp,
|
|
2551
|
+
'datetime': this.iso8601(timestamp),
|
|
2552
|
+
'lastUpdateTimestamp': this.safeInteger(position, 13),
|
|
2553
|
+
'maintenanceMargin': this.safeNumber(position, 18),
|
|
2554
|
+
'maintenanceMarginPercentage': undefined,
|
|
2555
|
+
'collateral': this.safeNumber(position, 17),
|
|
2556
|
+
'initialMargin': this.parseNumber(Precise["default"].stringMul(tradeAmount, tradePrice)),
|
|
2557
|
+
'initialMarginPercentage': undefined,
|
|
2558
|
+
'leverage': this.safeNumber(position, 9),
|
|
2559
|
+
'marginRatio': undefined,
|
|
2560
|
+
'stopLossPrice': undefined,
|
|
2561
|
+
'takeProfitPrice': undefined,
|
|
2562
|
+
});
|
|
2563
|
+
}
|
|
2564
|
+
nonce() {
|
|
2565
|
+
return this.milliseconds();
|
|
2566
|
+
}
|
|
2567
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
2568
|
+
let request = '/' + this.implodeParams(path, params);
|
|
2569
|
+
const query = this.omit(params, this.extractParams(path));
|
|
2570
|
+
if (api === 'v1') {
|
|
2571
|
+
request = api + request;
|
|
2572
|
+
}
|
|
2573
|
+
else {
|
|
2574
|
+
request = this.version + request;
|
|
2575
|
+
}
|
|
2576
|
+
let url = this.urls['api'][api] + '/' + request;
|
|
2577
|
+
if (api === 'public') {
|
|
2578
|
+
if (Object.keys(query).length) {
|
|
2579
|
+
url += '?' + this.urlencode(query);
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
if (api === 'private') {
|
|
2583
|
+
this.checkRequiredCredentials();
|
|
2584
|
+
const nonce = this.nonce().toString();
|
|
2585
|
+
body = this.json(query);
|
|
2586
|
+
const auth = '/api/' + request + nonce + body;
|
|
2587
|
+
const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha512.sha384);
|
|
2588
|
+
headers = {
|
|
2589
|
+
'bfx-nonce': nonce,
|
|
2590
|
+
'bfx-apikey': this.apiKey,
|
|
2591
|
+
'bfx-signature': signature,
|
|
2592
|
+
'Content-Type': 'application/json',
|
|
2593
|
+
};
|
|
2594
|
+
}
|
|
2595
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
2596
|
+
}
|
|
2597
|
+
handleErrors(statusCode, statusText, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
2598
|
+
// ["error", 11010, "ratelimit: error"]
|
|
2599
|
+
if (response !== undefined) {
|
|
2600
|
+
if (!Array.isArray(response)) {
|
|
2601
|
+
const message = this.safeString2(response, 'message', 'error');
|
|
2602
|
+
const feedback = this.id + ' ' + body;
|
|
2603
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
2604
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
2605
|
+
throw new errors.ExchangeError(this.id + ' ' + body);
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
else if (response === '') {
|
|
2609
|
+
throw new errors.ExchangeError(this.id + ' returned empty response');
|
|
2610
|
+
}
|
|
2611
|
+
if (statusCode === 429) {
|
|
2612
|
+
throw new errors.RateLimitExceeded(this.id + ' ' + body);
|
|
2613
|
+
}
|
|
2614
|
+
if (statusCode === 500) {
|
|
2615
|
+
// See https://docs.bitfinex.com/docs/abbreviations-glossary#section-errorinfo-codes
|
|
2616
|
+
const errorCode = this.safeString(response, 1, '');
|
|
2617
|
+
const errorText = this.safeString(response, 2, '');
|
|
2618
|
+
const feedback = this.id + ' ' + errorText;
|
|
2619
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], errorText, feedback);
|
|
2620
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
|
|
2621
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], errorText, feedback);
|
|
2622
|
+
throw new errors.ExchangeError(this.id + ' ' + errorText + ' (#' + errorCode + ')');
|
|
2623
|
+
}
|
|
2624
|
+
return response;
|
|
2625
|
+
}
|
|
2626
|
+
parseLedgerEntryType(type) {
|
|
2627
|
+
if (type === undefined) {
|
|
2628
|
+
return undefined;
|
|
2629
|
+
}
|
|
2630
|
+
else if (type.indexOf('fee') >= 0 || type.indexOf('charged') >= 0) {
|
|
2631
|
+
return 'fee';
|
|
2632
|
+
}
|
|
2633
|
+
else if (type.indexOf('rebate') >= 0) {
|
|
2634
|
+
return 'rebate';
|
|
2635
|
+
}
|
|
2636
|
+
else if (type.indexOf('deposit') >= 0 || type.indexOf('withdrawal') >= 0) {
|
|
2637
|
+
return 'transaction';
|
|
2638
|
+
}
|
|
2639
|
+
else if (type.indexOf('transfer') >= 0) {
|
|
2640
|
+
return 'transfer';
|
|
2641
|
+
}
|
|
2642
|
+
else if (type.indexOf('payment') >= 0) {
|
|
2643
|
+
return 'payout';
|
|
2644
|
+
}
|
|
2645
|
+
else if (type.indexOf('exchange') >= 0 || type.indexOf('position') >= 0) {
|
|
2646
|
+
return 'trade';
|
|
2647
|
+
}
|
|
2648
|
+
else {
|
|
2649
|
+
return type;
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
parseLedgerEntry(item, currency = undefined) {
|
|
2653
|
+
//
|
|
2654
|
+
// [
|
|
2655
|
+
// [
|
|
2656
|
+
// 2531822314, // ID: Ledger identifier
|
|
2657
|
+
// "USD", // CURRENCY: The symbol of the currency (ex. "BTC")
|
|
2658
|
+
// null, // PLACEHOLDER
|
|
2659
|
+
// 1573521810000, // MTS: Timestamp in milliseconds
|
|
2660
|
+
// null, // PLACEHOLDER
|
|
2661
|
+
// 0.01644445, // AMOUNT: Amount of funds moved
|
|
2662
|
+
// 0, // BALANCE: New balance
|
|
2663
|
+
// null, // PLACEHOLDER
|
|
2664
|
+
// "Settlement @ 185.79 on wallet margin" // DESCRIPTION: Description of ledger transaction
|
|
2665
|
+
// ]
|
|
2666
|
+
// ]
|
|
2667
|
+
//
|
|
2668
|
+
let type = undefined;
|
|
2669
|
+
const id = this.safeString(item, 0);
|
|
2670
|
+
const currencyId = this.safeString(item, 1);
|
|
2671
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
2672
|
+
const timestamp = this.safeInteger(item, 3);
|
|
2673
|
+
const amount = this.safeNumber(item, 5);
|
|
2674
|
+
const after = this.safeNumber(item, 6);
|
|
2675
|
+
const description = this.safeString(item, 8);
|
|
2676
|
+
if (description !== undefined) {
|
|
2677
|
+
const parts = description.split(' @ ');
|
|
2678
|
+
const first = this.safeStringLower(parts, 0);
|
|
2679
|
+
type = this.parseLedgerEntryType(first);
|
|
2680
|
+
}
|
|
2681
|
+
return {
|
|
2682
|
+
'id': id,
|
|
2683
|
+
'direction': undefined,
|
|
2684
|
+
'account': undefined,
|
|
2685
|
+
'referenceId': id,
|
|
2686
|
+
'referenceAccount': undefined,
|
|
2687
|
+
'type': type,
|
|
2688
|
+
'currency': code,
|
|
2689
|
+
'amount': amount,
|
|
2690
|
+
'timestamp': timestamp,
|
|
2691
|
+
'datetime': this.iso8601(timestamp),
|
|
2692
|
+
'before': undefined,
|
|
2693
|
+
'after': after,
|
|
2694
|
+
'status': undefined,
|
|
2695
|
+
'fee': undefined,
|
|
2696
|
+
'info': item,
|
|
2697
|
+
};
|
|
2698
|
+
}
|
|
2699
|
+
async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2700
|
+
/**
|
|
2701
|
+
* @method
|
|
2702
|
+
* @name bitfinex2#fetchLedger
|
|
2703
|
+
* @description fetch the history of changes, actions done by the user or operations that altered balance of the user
|
|
2704
|
+
* @see https://docs.bitfinex.com/reference/rest-auth-ledgers
|
|
2705
|
+
* @param {string} code unified currency code, default is undefined
|
|
2706
|
+
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
|
2707
|
+
* @param {int} [limit] max number of ledger entrys to return, default is undefined
|
|
2708
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2709
|
+
* @param {int} [params.until] timestamp in ms of the latest ledger entry
|
|
2710
|
+
* @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)
|
|
2711
|
+
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
|
|
2712
|
+
*/
|
|
2713
|
+
await this.loadMarkets();
|
|
2714
|
+
await this.loadMarkets();
|
|
2715
|
+
let paginate = false;
|
|
2716
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
|
|
2717
|
+
if (paginate) {
|
|
2718
|
+
return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params, 2500);
|
|
2719
|
+
}
|
|
2720
|
+
let currency = undefined;
|
|
2721
|
+
let request = {};
|
|
2722
|
+
if (since !== undefined) {
|
|
2723
|
+
request['start'] = since;
|
|
2724
|
+
}
|
|
2725
|
+
if (limit !== undefined) {
|
|
2726
|
+
request['limit'] = limit; // max 2500
|
|
2727
|
+
}
|
|
2728
|
+
[request, params] = this.handleUntilOption('end', request, params);
|
|
2729
|
+
let response = undefined;
|
|
2730
|
+
if (code !== undefined) {
|
|
2731
|
+
currency = this.currency(code);
|
|
2732
|
+
request['currency'] = currency['uppercaseId'];
|
|
2733
|
+
response = await this.privatePostAuthRLedgersCurrencyHist(this.extend(request, params));
|
|
2734
|
+
}
|
|
2735
|
+
else {
|
|
2736
|
+
response = await this.privatePostAuthRLedgersHist(this.extend(request, params));
|
|
2737
|
+
}
|
|
2738
|
+
//
|
|
2739
|
+
// [
|
|
2740
|
+
// [
|
|
2741
|
+
// 2531822314, // ID: Ledger identifier
|
|
2742
|
+
// "USD", // CURRENCY: The symbol of the currency (ex. "BTC")
|
|
2743
|
+
// null, // PLACEHOLDER
|
|
2744
|
+
// 1573521810000, // MTS: Timestamp in milliseconds
|
|
2745
|
+
// null, // PLACEHOLDER
|
|
2746
|
+
// 0.01644445, // AMOUNT: Amount of funds moved
|
|
2747
|
+
// 0, // BALANCE: New balance
|
|
2748
|
+
// null, // PLACEHOLDER
|
|
2749
|
+
// "Settlement @ 185.79 on wallet margin" // DESCRIPTION: Description of ledger transaction
|
|
2750
|
+
// ]
|
|
2751
|
+
// ]
|
|
2752
|
+
//
|
|
2753
|
+
return this.parseLedger(response, currency, since, limit);
|
|
2754
|
+
}
|
|
2755
|
+
async fetchFundingRate(symbol, params = {}) {
|
|
2756
|
+
/**
|
|
2757
|
+
* @method
|
|
2758
|
+
* @name bitfine#fetchFundingRate
|
|
2759
|
+
* @description fetch the current funding rate
|
|
2760
|
+
* @see https://docs.bitfinex.com/reference/rest-public-derivatives-status
|
|
2761
|
+
* @param {string} symbol unified market symbol
|
|
2762
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2763
|
+
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
2764
|
+
*/
|
|
2765
|
+
return this.fetchFundingRates([symbol], params);
|
|
2766
|
+
}
|
|
2767
|
+
async fetchFundingRates(symbols = undefined, params = {}) {
|
|
2768
|
+
/**
|
|
2769
|
+
* @method
|
|
2770
|
+
* @name bitfine#fetchFundingRate
|
|
2771
|
+
* @description fetch the current funding rate
|
|
2772
|
+
* @see https://docs.bitfinex.com/reference/rest-public-derivatives-status
|
|
2773
|
+
* @param {string[]} symbols list of unified market symbols
|
|
2774
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2775
|
+
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
2776
|
+
*/
|
|
2777
|
+
if (symbols === undefined) {
|
|
2778
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchFundingRates() requires a symbols argument');
|
|
2779
|
+
}
|
|
2780
|
+
await this.loadMarkets();
|
|
2781
|
+
const marketIds = this.marketIds(symbols);
|
|
2782
|
+
const request = {
|
|
2783
|
+
'keys': marketIds.join(','),
|
|
2784
|
+
};
|
|
2785
|
+
const response = await this.publicGetStatusDeriv(this.extend(request, params));
|
|
2786
|
+
//
|
|
2787
|
+
// [
|
|
2788
|
+
// [
|
|
2789
|
+
// "tBTCF0:USTF0",
|
|
2790
|
+
// 1691165059000,
|
|
2791
|
+
// null,
|
|
2792
|
+
// 29297.851276225,
|
|
2793
|
+
// 29277.5,
|
|
2794
|
+
// null,
|
|
2795
|
+
// 36950860.76010306,
|
|
2796
|
+
// null,
|
|
2797
|
+
// 1691193600000,
|
|
2798
|
+
// 0.00000527,
|
|
2799
|
+
// 82,
|
|
2800
|
+
// null,
|
|
2801
|
+
// 0.00014548,
|
|
2802
|
+
// null,
|
|
2803
|
+
// null,
|
|
2804
|
+
// 29278.8925,
|
|
2805
|
+
// null,
|
|
2806
|
+
// null,
|
|
2807
|
+
// 9636.07644994,
|
|
2808
|
+
// null,
|
|
2809
|
+
// null,
|
|
2810
|
+
// null,
|
|
2811
|
+
// 0.0005,
|
|
2812
|
+
// 0.0025
|
|
2813
|
+
// ]
|
|
2814
|
+
// ]
|
|
2815
|
+
//
|
|
2816
|
+
return this.parseFundingRates(response);
|
|
2817
|
+
}
|
|
2818
|
+
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2819
|
+
/**
|
|
2820
|
+
* @method
|
|
2821
|
+
* @name bitfine#fetchFundingRateHistory
|
|
2822
|
+
* @description fetches historical funding rate prices
|
|
2823
|
+
* @see https://docs.bitfinex.com/reference/rest-public-derivatives-status-history
|
|
2824
|
+
* @param {string} symbol unified market symbol
|
|
2825
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2826
|
+
* @param {int} [params.until] timestamp in ms of the latest funding rate
|
|
2827
|
+
* @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)
|
|
2828
|
+
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
2829
|
+
*/
|
|
2830
|
+
if (symbol === undefined) {
|
|
2831
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
|
|
2832
|
+
}
|
|
2833
|
+
await this.loadMarkets();
|
|
2834
|
+
let paginate = false;
|
|
2835
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
|
|
2836
|
+
if (paginate) {
|
|
2837
|
+
return await this.fetchPaginatedCallDeterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 5000);
|
|
2838
|
+
}
|
|
2839
|
+
const market = this.market(symbol);
|
|
2840
|
+
let request = {
|
|
2841
|
+
'symbol': market['id'],
|
|
2842
|
+
};
|
|
2843
|
+
if (since !== undefined) {
|
|
2844
|
+
request['start'] = since;
|
|
2845
|
+
}
|
|
2846
|
+
[request, params] = this.handleUntilOption('end', request, params);
|
|
2847
|
+
const response = await this.publicGetStatusDerivSymbolHist(this.extend(request, params));
|
|
2848
|
+
//
|
|
2849
|
+
// [
|
|
2850
|
+
// [
|
|
2851
|
+
// "tBTCF0:USTF0",
|
|
2852
|
+
// 1691165059000,
|
|
2853
|
+
// null,
|
|
2854
|
+
// 29297.851276225,
|
|
2855
|
+
// 29277.5,
|
|
2856
|
+
// null,
|
|
2857
|
+
// 36950860.76010306,
|
|
2858
|
+
// null,
|
|
2859
|
+
// 1691193600000,
|
|
2860
|
+
// 0.00000527,
|
|
2861
|
+
// 82,
|
|
2862
|
+
// null,
|
|
2863
|
+
// 0.00014548,
|
|
2864
|
+
// null,
|
|
2865
|
+
// null,
|
|
2866
|
+
// 29278.8925,
|
|
2867
|
+
// null,
|
|
2868
|
+
// null,
|
|
2869
|
+
// 9636.07644994,
|
|
2870
|
+
// null,
|
|
2871
|
+
// null,
|
|
2872
|
+
// null,
|
|
2873
|
+
// 0.0005,
|
|
2874
|
+
// 0.0025
|
|
2875
|
+
// ]
|
|
2876
|
+
// ]
|
|
2877
|
+
//
|
|
2878
|
+
const rates = [];
|
|
2879
|
+
for (let i = 0; i < response.length; i++) {
|
|
2880
|
+
const fr = response[i];
|
|
2881
|
+
const rate = this.parseFundingRateHistory(fr, market);
|
|
2882
|
+
rates.push(rate);
|
|
2883
|
+
}
|
|
2884
|
+
return this.filterBySymbolSinceLimit(rates, symbol, since, limit);
|
|
2885
|
+
}
|
|
2886
|
+
parseFundingRate(contract, market = undefined) {
|
|
2887
|
+
//
|
|
2888
|
+
// [
|
|
2889
|
+
// "tBTCF0:USTF0",
|
|
2890
|
+
// 1691165059000,
|
|
2891
|
+
// null,
|
|
2892
|
+
// 29297.851276225,
|
|
2893
|
+
// 29277.5,
|
|
2894
|
+
// null,
|
|
2895
|
+
// 36950860.76010306,
|
|
2896
|
+
// null,
|
|
2897
|
+
// 1691193600000,
|
|
2898
|
+
// 0.00000527,
|
|
2899
|
+
// 82,
|
|
2900
|
+
// null,
|
|
2901
|
+
// 0.00014548,
|
|
2902
|
+
// null,
|
|
2903
|
+
// null,
|
|
2904
|
+
// 29278.8925,
|
|
2905
|
+
// null,
|
|
2906
|
+
// null,
|
|
2907
|
+
// 9636.07644994,
|
|
2908
|
+
// null,
|
|
2909
|
+
// null,
|
|
2910
|
+
// null,
|
|
2911
|
+
// 0.0005,
|
|
2912
|
+
// 0.0025
|
|
2913
|
+
// ]
|
|
2914
|
+
//
|
|
2915
|
+
const marketId = this.safeString(contract, 0);
|
|
2916
|
+
const timestamp = this.safeInteger(contract, 1);
|
|
2917
|
+
const nextFundingTimestamp = this.safeInteger(contract, 8);
|
|
2918
|
+
return {
|
|
2919
|
+
'info': contract,
|
|
2920
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
2921
|
+
'markPrice': this.safeNumber(contract, 15),
|
|
2922
|
+
'indexPrice': this.safeNumber(contract, 3),
|
|
2923
|
+
'interestRate': undefined,
|
|
2924
|
+
'estimatedSettlePrice': undefined,
|
|
2925
|
+
'timestamp': timestamp,
|
|
2926
|
+
'datetime': this.iso8601(timestamp),
|
|
2927
|
+
'fundingRate': this.safeNumber(contract, 12),
|
|
2928
|
+
'fundingTimestamp': undefined,
|
|
2929
|
+
'fundingDatetime': undefined,
|
|
2930
|
+
'nextFundingRate': this.safeNumber(contract, 9),
|
|
2931
|
+
'nextFundingTimestamp': nextFundingTimestamp,
|
|
2932
|
+
'nextFundingDatetime': this.iso8601(nextFundingTimestamp),
|
|
2933
|
+
'previousFundingRate': undefined,
|
|
2934
|
+
'previousFundingTimestamp': undefined,
|
|
2935
|
+
'previousFundingDatetime': undefined,
|
|
2936
|
+
};
|
|
2937
|
+
}
|
|
2938
|
+
parseFundingRateHistory(contract, market = undefined) {
|
|
2939
|
+
//
|
|
2940
|
+
// [
|
|
2941
|
+
// 1691165494000,
|
|
2942
|
+
// null,
|
|
2943
|
+
// 29278.95838065,
|
|
2944
|
+
// 29260.5,
|
|
2945
|
+
// null,
|
|
2946
|
+
// 36950860.76010305,
|
|
2947
|
+
// null,
|
|
2948
|
+
// 1691193600000,
|
|
2949
|
+
// 0.00001449,
|
|
2950
|
+
// 222,
|
|
2951
|
+
// null,
|
|
2952
|
+
// 0.00014548,
|
|
2953
|
+
// null,
|
|
2954
|
+
// null,
|
|
2955
|
+
// 29260.005,
|
|
2956
|
+
// null,
|
|
2957
|
+
// null,
|
|
2958
|
+
// 9635.86484562,
|
|
2959
|
+
// null,
|
|
2960
|
+
// null,
|
|
2961
|
+
// null,
|
|
2962
|
+
// 0.0005,
|
|
2963
|
+
// 0.0025
|
|
2964
|
+
// ]
|
|
2965
|
+
//
|
|
2966
|
+
const timestamp = this.safeInteger(contract, 0);
|
|
2967
|
+
const nextFundingTimestamp = this.safeInteger(contract, 7);
|
|
2968
|
+
return {
|
|
2969
|
+
'info': contract,
|
|
2970
|
+
'symbol': this.safeSymbol(undefined, market),
|
|
2971
|
+
'markPrice': this.safeNumber(contract, 14),
|
|
2972
|
+
'indexPrice': this.safeNumber(contract, 2),
|
|
2973
|
+
'interestRate': undefined,
|
|
2974
|
+
'estimatedSettlePrice': undefined,
|
|
2975
|
+
'timestamp': timestamp,
|
|
2976
|
+
'datetime': this.iso8601(timestamp),
|
|
2977
|
+
'fundingRate': this.safeNumber(contract, 11),
|
|
2978
|
+
'fundingTimestamp': undefined,
|
|
2979
|
+
'fundingDatetime': undefined,
|
|
2980
|
+
'nextFundingRate': this.safeNumber(contract, 8),
|
|
2981
|
+
'nextFundingTimestamp': nextFundingTimestamp,
|
|
2982
|
+
'nextFundingDatetime': this.iso8601(nextFundingTimestamp),
|
|
2983
|
+
'previousFundingRate': undefined,
|
|
2984
|
+
'previousFundingTimestamp': undefined,
|
|
2985
|
+
'previousFundingDatetime': undefined,
|
|
2986
|
+
};
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2990
|
+
module.exports = bitfinex2;
|