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,2884 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var bitmex$1 = require('./abstract/bitmex.js');
|
|
4
|
+
var number = require('./base/functions/number.js');
|
|
5
|
+
var errors = require('./base/errors.js');
|
|
6
|
+
var Precise = require('./base/Precise.js');
|
|
7
|
+
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* @class bitmex
|
|
13
|
+
* @augments Exchange
|
|
14
|
+
*/
|
|
15
|
+
class bitmex extends bitmex$1 {
|
|
16
|
+
describe() {
|
|
17
|
+
return this.deepExtend(super.describe(), {
|
|
18
|
+
'id': 'bitmex',
|
|
19
|
+
'name': 'BitMEX',
|
|
20
|
+
'countries': ['SC'],
|
|
21
|
+
'version': 'v1',
|
|
22
|
+
'userAgent': undefined,
|
|
23
|
+
// cheapest endpoints are 10 requests per second (trading)
|
|
24
|
+
// 10 per second => rateLimit = 1000ms / 10 = 100ms
|
|
25
|
+
// 120 per minute => 2 per second => weight = 5 (authenticated)
|
|
26
|
+
// 30 per minute => 0.5 per second => weight = 20 (unauthenticated)
|
|
27
|
+
'rateLimit': 100,
|
|
28
|
+
'certified': true,
|
|
29
|
+
'pro': true,
|
|
30
|
+
'has': {
|
|
31
|
+
'CORS': undefined,
|
|
32
|
+
'spot': true,
|
|
33
|
+
'margin': false,
|
|
34
|
+
'swap': true,
|
|
35
|
+
'future': true,
|
|
36
|
+
'option': false,
|
|
37
|
+
'addMargin': undefined,
|
|
38
|
+
'cancelAllOrders': true,
|
|
39
|
+
'cancelOrder': true,
|
|
40
|
+
'cancelOrders': true,
|
|
41
|
+
'closeAllPositions': false,
|
|
42
|
+
'closePosition': true,
|
|
43
|
+
'createOrder': true,
|
|
44
|
+
'createReduceOnlyOrder': true,
|
|
45
|
+
'createTrailingAmountOrder': true,
|
|
46
|
+
'editOrder': true,
|
|
47
|
+
'fetchBalance': true,
|
|
48
|
+
'fetchClosedOrders': true,
|
|
49
|
+
'fetchCurrencies': true,
|
|
50
|
+
'fetchDepositAddress': true,
|
|
51
|
+
'fetchDepositAddresses': false,
|
|
52
|
+
'fetchDepositAddressesByNetwork': false,
|
|
53
|
+
'fetchDepositsWithdrawals': 'emulated',
|
|
54
|
+
'fetchDepositWithdrawFee': 'emulated',
|
|
55
|
+
'fetchDepositWithdrawFees': true,
|
|
56
|
+
'fetchFundingHistory': false,
|
|
57
|
+
'fetchFundingRate': false,
|
|
58
|
+
'fetchFundingRateHistory': true,
|
|
59
|
+
'fetchFundingRates': true,
|
|
60
|
+
'fetchIndexOHLCV': false,
|
|
61
|
+
'fetchLedger': true,
|
|
62
|
+
'fetchLeverage': false,
|
|
63
|
+
'fetchLeverageTiers': false,
|
|
64
|
+
'fetchLiquidations': true,
|
|
65
|
+
'fetchMarketLeverageTiers': false,
|
|
66
|
+
'fetchMarkets': true,
|
|
67
|
+
'fetchMarkOHLCV': false,
|
|
68
|
+
'fetchMyLiquidations': false,
|
|
69
|
+
'fetchMyTrades': true,
|
|
70
|
+
'fetchOHLCV': true,
|
|
71
|
+
'fetchOpenOrders': true,
|
|
72
|
+
'fetchOrder': true,
|
|
73
|
+
'fetchOrderBook': true,
|
|
74
|
+
'fetchOrders': true,
|
|
75
|
+
'fetchPosition': false,
|
|
76
|
+
'fetchPositions': true,
|
|
77
|
+
'fetchPositionsRisk': false,
|
|
78
|
+
'fetchPremiumIndexOHLCV': false,
|
|
79
|
+
'fetchTicker': true,
|
|
80
|
+
'fetchTickers': true,
|
|
81
|
+
'fetchTrades': true,
|
|
82
|
+
'fetchTransactions': 'emulated',
|
|
83
|
+
'fetchTransfer': false,
|
|
84
|
+
'fetchTransfers': false,
|
|
85
|
+
'reduceMargin': undefined,
|
|
86
|
+
'setLeverage': true,
|
|
87
|
+
'setMargin': undefined,
|
|
88
|
+
'setMarginMode': true,
|
|
89
|
+
'setPositionMode': false,
|
|
90
|
+
'transfer': false,
|
|
91
|
+
'withdraw': true,
|
|
92
|
+
},
|
|
93
|
+
'timeframes': {
|
|
94
|
+
'1m': '1m',
|
|
95
|
+
'5m': '5m',
|
|
96
|
+
'1h': '1h',
|
|
97
|
+
'1d': '1d',
|
|
98
|
+
},
|
|
99
|
+
'urls': {
|
|
100
|
+
'test': {
|
|
101
|
+
'public': 'https://testnet.bitmex.com',
|
|
102
|
+
'private': 'https://testnet.bitmex.com',
|
|
103
|
+
},
|
|
104
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/27766319-f653c6e6-5ed4-11e7-933d-f0bc3699ae8f.jpg',
|
|
105
|
+
'api': {
|
|
106
|
+
'public': 'https://www.bitmex.com',
|
|
107
|
+
'private': 'https://www.bitmex.com',
|
|
108
|
+
},
|
|
109
|
+
'www': 'https://www.bitmex.com',
|
|
110
|
+
'doc': [
|
|
111
|
+
'https://www.bitmex.com/app/apiOverview',
|
|
112
|
+
'https://github.com/BitMEX/api-connectors/tree/master/official-http',
|
|
113
|
+
],
|
|
114
|
+
'fees': 'https://www.bitmex.com/app/fees',
|
|
115
|
+
'referral': 'https://www.bitmex.com/register/upZpOX',
|
|
116
|
+
},
|
|
117
|
+
'api': {
|
|
118
|
+
'public': {
|
|
119
|
+
'get': {
|
|
120
|
+
'announcement': 5,
|
|
121
|
+
'announcement/urgent': 5,
|
|
122
|
+
'chat': 5,
|
|
123
|
+
'chat/channels': 5,
|
|
124
|
+
'chat/connected': 5,
|
|
125
|
+
'chat/pinned': 5,
|
|
126
|
+
'funding': 5,
|
|
127
|
+
'guild': 5,
|
|
128
|
+
'instrument': 5,
|
|
129
|
+
'instrument/active': 5,
|
|
130
|
+
'instrument/activeAndIndices': 5,
|
|
131
|
+
'instrument/activeIntervals': 5,
|
|
132
|
+
'instrument/compositeIndex': 5,
|
|
133
|
+
'instrument/indices': 5,
|
|
134
|
+
'instrument/usdVolume': 5,
|
|
135
|
+
'insurance': 5,
|
|
136
|
+
'leaderboard': 5,
|
|
137
|
+
'liquidation': 5,
|
|
138
|
+
'orderBook/L2': 5,
|
|
139
|
+
'porl/nonce': 5,
|
|
140
|
+
'quote': 5,
|
|
141
|
+
'quote/bucketed': 5,
|
|
142
|
+
'schema': 5,
|
|
143
|
+
'schema/websocketHelp': 5,
|
|
144
|
+
'settlement': 5,
|
|
145
|
+
'stats': 5,
|
|
146
|
+
'stats/history': 5,
|
|
147
|
+
'stats/historyUSD': 5,
|
|
148
|
+
'trade': 5,
|
|
149
|
+
'trade/bucketed': 5,
|
|
150
|
+
'wallet/assets': 5,
|
|
151
|
+
'wallet/networks': 5,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
'private': {
|
|
155
|
+
'get': {
|
|
156
|
+
'address': 5,
|
|
157
|
+
'apiKey': 5,
|
|
158
|
+
'execution': 5,
|
|
159
|
+
'execution/tradeHistory': 5,
|
|
160
|
+
'globalNotification': 5,
|
|
161
|
+
'leaderboard/name': 5,
|
|
162
|
+
'order': 5,
|
|
163
|
+
'porl/snapshots': 5,
|
|
164
|
+
'position': 5,
|
|
165
|
+
'user': 5,
|
|
166
|
+
'user/affiliateStatus': 5,
|
|
167
|
+
'user/checkReferralCode': 5,
|
|
168
|
+
'user/commission': 5,
|
|
169
|
+
'user/csa': 5,
|
|
170
|
+
'user/depositAddress': 5,
|
|
171
|
+
'user/executionHistory': 5,
|
|
172
|
+
'user/getWalletTransferAccounts': 5,
|
|
173
|
+
'user/margin': 5,
|
|
174
|
+
'user/quoteFillRatio': 5,
|
|
175
|
+
'user/quoteValueRatio': 5,
|
|
176
|
+
'user/staking': 5,
|
|
177
|
+
'user/staking/instruments': 5,
|
|
178
|
+
'user/staking/tiers': 5,
|
|
179
|
+
'user/tradingVolume': 5,
|
|
180
|
+
'user/unstakingRequests': 5,
|
|
181
|
+
'user/wallet': 5,
|
|
182
|
+
'user/walletHistory': 5,
|
|
183
|
+
'user/walletSummary': 5,
|
|
184
|
+
'userAffiliates': 5,
|
|
185
|
+
'userEvent': 5,
|
|
186
|
+
},
|
|
187
|
+
'post': {
|
|
188
|
+
'address': 5,
|
|
189
|
+
'chat': 5,
|
|
190
|
+
'guild': 5,
|
|
191
|
+
'guild/archive': 5,
|
|
192
|
+
'guild/join': 5,
|
|
193
|
+
'guild/kick': 5,
|
|
194
|
+
'guild/leave': 5,
|
|
195
|
+
'guild/sharesTrades': 5,
|
|
196
|
+
'order': 1,
|
|
197
|
+
'order/cancelAllAfter': 5,
|
|
198
|
+
'order/closePosition': 5,
|
|
199
|
+
'position/isolate': 1,
|
|
200
|
+
'position/leverage': 1,
|
|
201
|
+
'position/riskLimit': 5,
|
|
202
|
+
'position/transferMargin': 1,
|
|
203
|
+
'user/addSubaccount': 5,
|
|
204
|
+
'user/cancelWithdrawal': 5,
|
|
205
|
+
'user/communicationToken': 5,
|
|
206
|
+
'user/confirmEmail': 5,
|
|
207
|
+
'user/confirmWithdrawal': 5,
|
|
208
|
+
'user/logout': 5,
|
|
209
|
+
'user/preferences': 5,
|
|
210
|
+
'user/requestWithdrawal': 5,
|
|
211
|
+
'user/unstakingRequests': 5,
|
|
212
|
+
'user/updateSubaccount': 5,
|
|
213
|
+
'user/walletTransfer': 5,
|
|
214
|
+
},
|
|
215
|
+
'put': {
|
|
216
|
+
'guild': 5,
|
|
217
|
+
'order': 1,
|
|
218
|
+
},
|
|
219
|
+
'delete': {
|
|
220
|
+
'order': 1,
|
|
221
|
+
'order/all': 1,
|
|
222
|
+
'user/unstakingRequests': 5,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
'exceptions': {
|
|
227
|
+
'exact': {
|
|
228
|
+
'Invalid API Key.': errors.AuthenticationError,
|
|
229
|
+
'This key is disabled.': errors.PermissionDenied,
|
|
230
|
+
'Access Denied': errors.PermissionDenied,
|
|
231
|
+
'Duplicate clOrdID': errors.InvalidOrder,
|
|
232
|
+
'orderQty is invalid': errors.InvalidOrder,
|
|
233
|
+
'Invalid price': errors.InvalidOrder,
|
|
234
|
+
'Invalid stopPx for ordType': errors.InvalidOrder,
|
|
235
|
+
},
|
|
236
|
+
'broad': {
|
|
237
|
+
'Signature not valid': errors.AuthenticationError,
|
|
238
|
+
'overloaded': errors.ExchangeNotAvailable,
|
|
239
|
+
'Account has insufficient Available Balance': errors.InsufficientFunds,
|
|
240
|
+
'Service unavailable': errors.ExchangeNotAvailable,
|
|
241
|
+
'Server Error': errors.ExchangeError,
|
|
242
|
+
'Unable to cancel order due to existing state': errors.InvalidOrder,
|
|
243
|
+
'We require all new traders to verify': errors.PermissionDenied, // {"message":"We require all new traders to verify their identity before their first deposit. Please visit bitmex.com/verify to complete the process.","name":"HTTPError"}
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
'precisionMode': number.TICK_SIZE,
|
|
247
|
+
'options': {
|
|
248
|
+
// https://blog.bitmex.com/api_announcement/deprecation-of-api-nonce-header/
|
|
249
|
+
// https://github.com/ccxt/ccxt/issues/4789
|
|
250
|
+
'api-expires': 5,
|
|
251
|
+
'fetchOHLCVOpenTimestamp': true,
|
|
252
|
+
'oldPrecision': false,
|
|
253
|
+
'networks': {
|
|
254
|
+
'BTC': 'btc',
|
|
255
|
+
'ERC20': 'eth',
|
|
256
|
+
'BEP20': 'bsc',
|
|
257
|
+
'TRC20': 'tron',
|
|
258
|
+
'AVAXC': 'avax',
|
|
259
|
+
'NEAR': 'near',
|
|
260
|
+
'XTZ': 'xtz',
|
|
261
|
+
'DOT': 'dot',
|
|
262
|
+
'SOL': 'sol',
|
|
263
|
+
'ADA': 'ada',
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
'commonCurrencies': {
|
|
267
|
+
'USDt': 'USDT',
|
|
268
|
+
'XBt': 'BTC',
|
|
269
|
+
'XBT': 'BTC',
|
|
270
|
+
'Gwei': 'ETH',
|
|
271
|
+
'GWEI': 'ETH',
|
|
272
|
+
'LAMP': 'SOL',
|
|
273
|
+
'LAMp': 'SOL',
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
async fetchCurrencies(params = {}) {
|
|
278
|
+
/**
|
|
279
|
+
* @method
|
|
280
|
+
* @name bitmex#fetchCurrencies
|
|
281
|
+
* @description fetches all available currencies on an exchange
|
|
282
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
283
|
+
* @returns {object} an associative dictionary of currencies
|
|
284
|
+
*/
|
|
285
|
+
const response = await this.publicGetWalletAssets(params);
|
|
286
|
+
//
|
|
287
|
+
// {
|
|
288
|
+
// "XBt": {
|
|
289
|
+
// "asset": "XBT",
|
|
290
|
+
// "currency": "XBt",
|
|
291
|
+
// "majorCurrency": "XBT",
|
|
292
|
+
// "name": "Bitcoin",
|
|
293
|
+
// "currencyType": "Crypto",
|
|
294
|
+
// "scale": "8",
|
|
295
|
+
// // "mediumPrecision": "8",
|
|
296
|
+
// // "shorterPrecision": "4",
|
|
297
|
+
// // "symbol": "₿",
|
|
298
|
+
// // "weight": "1",
|
|
299
|
+
// // "tickLog": "0",
|
|
300
|
+
// "enabled": true,
|
|
301
|
+
// "isMarginCurrency": true,
|
|
302
|
+
// "minDepositAmount": "10000",
|
|
303
|
+
// "minWithdrawalAmount": "1000",
|
|
304
|
+
// "maxWithdrawalAmount": "100000000000000",
|
|
305
|
+
// "networks": [
|
|
306
|
+
// {
|
|
307
|
+
// "asset": "btc",
|
|
308
|
+
// "tokenAddress": "",
|
|
309
|
+
// "depositEnabled": true,
|
|
310
|
+
// "withdrawalEnabled": true,
|
|
311
|
+
// "withdrawalFee": "20000",
|
|
312
|
+
// "minFee": "20000",
|
|
313
|
+
// "maxFee": "10000000"
|
|
314
|
+
// }
|
|
315
|
+
// ]
|
|
316
|
+
// },
|
|
317
|
+
// }
|
|
318
|
+
//
|
|
319
|
+
const result = {};
|
|
320
|
+
for (let i = 0; i < response.length; i++) {
|
|
321
|
+
const currency = response[i];
|
|
322
|
+
const asset = this.safeString(currency, 'asset');
|
|
323
|
+
const code = this.safeCurrencyCode(asset);
|
|
324
|
+
const id = this.safeString(currency, 'currency');
|
|
325
|
+
const name = this.safeString(currency, 'name');
|
|
326
|
+
const chains = this.safeValue(currency, 'networks', []);
|
|
327
|
+
let depositEnabled = false;
|
|
328
|
+
let withdrawEnabled = false;
|
|
329
|
+
const networks = {};
|
|
330
|
+
const scale = this.safeString(currency, 'scale');
|
|
331
|
+
const precisionString = this.parsePrecision(scale);
|
|
332
|
+
const precision = this.parseNumber(precisionString);
|
|
333
|
+
for (let j = 0; j < chains.length; j++) {
|
|
334
|
+
const chain = chains[j];
|
|
335
|
+
const networkId = this.safeString(chain, 'asset');
|
|
336
|
+
const network = this.networkIdToCode(networkId);
|
|
337
|
+
const withdrawalFeeRaw = this.safeString(chain, 'withdrawalFee');
|
|
338
|
+
const withdrawalFee = this.parseNumber(Precise["default"].stringMul(withdrawalFeeRaw, precisionString));
|
|
339
|
+
const isDepositEnabled = this.safeValue(chain, 'depositEnabled', false);
|
|
340
|
+
const isWithdrawEnabled = this.safeValue(chain, 'withdrawalEnabled', false);
|
|
341
|
+
const active = (isDepositEnabled && isWithdrawEnabled);
|
|
342
|
+
if (isDepositEnabled) {
|
|
343
|
+
depositEnabled = true;
|
|
344
|
+
}
|
|
345
|
+
if (isWithdrawEnabled) {
|
|
346
|
+
withdrawEnabled = true;
|
|
347
|
+
}
|
|
348
|
+
networks[network] = {
|
|
349
|
+
'info': chain,
|
|
350
|
+
'id': networkId,
|
|
351
|
+
'network': network,
|
|
352
|
+
'active': active,
|
|
353
|
+
'deposit': isDepositEnabled,
|
|
354
|
+
'withdraw': isWithdrawEnabled,
|
|
355
|
+
'fee': withdrawalFee,
|
|
356
|
+
'precision': undefined,
|
|
357
|
+
'limits': {
|
|
358
|
+
'withdraw': {
|
|
359
|
+
'min': undefined,
|
|
360
|
+
'max': undefined,
|
|
361
|
+
},
|
|
362
|
+
'deposit': {
|
|
363
|
+
'min': undefined,
|
|
364
|
+
'max': undefined,
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
const currencyEnabled = this.safeValue(currency, 'enabled');
|
|
370
|
+
const currencyActive = currencyEnabled || (depositEnabled || withdrawEnabled);
|
|
371
|
+
const minWithdrawalString = this.safeString(currency, 'minWithdrawalAmount');
|
|
372
|
+
const minWithdrawal = this.parseNumber(Precise["default"].stringMul(minWithdrawalString, precisionString));
|
|
373
|
+
const maxWithdrawalString = this.safeString(currency, 'maxWithdrawalAmount');
|
|
374
|
+
const maxWithdrawal = this.parseNumber(Precise["default"].stringMul(maxWithdrawalString, precisionString));
|
|
375
|
+
const minDepositString = this.safeString(currency, 'minDepositAmount');
|
|
376
|
+
const minDeposit = this.parseNumber(Precise["default"].stringMul(minDepositString, precisionString));
|
|
377
|
+
result[code] = {
|
|
378
|
+
'id': id,
|
|
379
|
+
'code': code,
|
|
380
|
+
'info': currency,
|
|
381
|
+
'name': name,
|
|
382
|
+
'active': currencyActive,
|
|
383
|
+
'deposit': depositEnabled,
|
|
384
|
+
'withdraw': withdrawEnabled,
|
|
385
|
+
'fee': undefined,
|
|
386
|
+
'precision': precision,
|
|
387
|
+
'limits': {
|
|
388
|
+
'amount': {
|
|
389
|
+
'min': undefined,
|
|
390
|
+
'max': undefined,
|
|
391
|
+
},
|
|
392
|
+
'withdraw': {
|
|
393
|
+
'min': minWithdrawal,
|
|
394
|
+
'max': maxWithdrawal,
|
|
395
|
+
},
|
|
396
|
+
'deposit': {
|
|
397
|
+
'min': minDeposit,
|
|
398
|
+
'max': undefined,
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
'networks': networks,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
return result;
|
|
405
|
+
}
|
|
406
|
+
convertFromRealAmount(code, amount) {
|
|
407
|
+
const currency = this.currency(code);
|
|
408
|
+
const precision = this.safeString(currency, 'precision');
|
|
409
|
+
const amountString = this.numberToString(amount);
|
|
410
|
+
const finalAmount = Precise["default"].stringDiv(amountString, precision);
|
|
411
|
+
return this.parseNumber(finalAmount);
|
|
412
|
+
}
|
|
413
|
+
convertToRealAmount(code, amount) {
|
|
414
|
+
if (code === undefined) {
|
|
415
|
+
return amount;
|
|
416
|
+
}
|
|
417
|
+
else if (amount === undefined) {
|
|
418
|
+
return undefined;
|
|
419
|
+
}
|
|
420
|
+
const currency = this.currency(code);
|
|
421
|
+
const precision = this.safeString(currency, 'precision');
|
|
422
|
+
return Precise["default"].stringMul(amount, precision);
|
|
423
|
+
}
|
|
424
|
+
amountToPrecision(symbol, amount) {
|
|
425
|
+
symbol = this.safeSymbol(symbol);
|
|
426
|
+
const market = this.market(symbol);
|
|
427
|
+
const oldPrecision = this.safeValue(this.options, 'oldPrecision');
|
|
428
|
+
if (market['spot'] && !oldPrecision) {
|
|
429
|
+
amount = this.convertFromRealAmount(market['base'], amount);
|
|
430
|
+
}
|
|
431
|
+
return super.amountToPrecision(symbol, amount);
|
|
432
|
+
}
|
|
433
|
+
convertFromRawQuantity(symbol, rawQuantity, currencySide = 'base') {
|
|
434
|
+
if (this.safeValue(this.options, 'oldPrecision')) {
|
|
435
|
+
return this.parseNumber(rawQuantity);
|
|
436
|
+
}
|
|
437
|
+
symbol = this.safeSymbol(symbol);
|
|
438
|
+
const marketExists = this.inArray(symbol, this.symbols);
|
|
439
|
+
if (!marketExists) {
|
|
440
|
+
return this.parseNumber(rawQuantity);
|
|
441
|
+
}
|
|
442
|
+
const market = this.market(symbol);
|
|
443
|
+
if (market['spot']) {
|
|
444
|
+
return this.parseNumber(this.convertToRealAmount(market[currencySide], rawQuantity));
|
|
445
|
+
}
|
|
446
|
+
return this.parseNumber(rawQuantity);
|
|
447
|
+
}
|
|
448
|
+
convertFromRawCost(symbol, rawQuantity) {
|
|
449
|
+
return this.convertFromRawQuantity(symbol, rawQuantity, 'quote');
|
|
450
|
+
}
|
|
451
|
+
async fetchMarkets(params = {}) {
|
|
452
|
+
/**
|
|
453
|
+
* @method
|
|
454
|
+
* @name bitmex#fetchMarkets
|
|
455
|
+
* @description retrieves data on all markets for bitmex
|
|
456
|
+
* @see https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_getActive
|
|
457
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
458
|
+
* @returns {object[]} an array of objects representing market data
|
|
459
|
+
*/
|
|
460
|
+
const response = await this.publicGetInstrumentActive(params);
|
|
461
|
+
//
|
|
462
|
+
// [
|
|
463
|
+
// {
|
|
464
|
+
// "symbol": "LTCUSDT",
|
|
465
|
+
// "rootSymbol": "LTC",
|
|
466
|
+
// "state": "Open",
|
|
467
|
+
// "typ": "FFWCSX",
|
|
468
|
+
// "listing": "2021-11-10T04:00:00.000Z",
|
|
469
|
+
// "front": "2021-11-10T04:00:00.000Z",
|
|
470
|
+
// "expiry": null,
|
|
471
|
+
// "settle": null,
|
|
472
|
+
// "listedSettle": null,
|
|
473
|
+
// "relistInterval": null,
|
|
474
|
+
// "inverseLeg": "",
|
|
475
|
+
// "sellLeg": "",
|
|
476
|
+
// "buyLeg": "",
|
|
477
|
+
// "optionStrikePcnt": null,
|
|
478
|
+
// "optionStrikeRound": null,
|
|
479
|
+
// "optionStrikePrice": null,
|
|
480
|
+
// "optionMultiplier": null,
|
|
481
|
+
// "positionCurrency": "LTC", // can be empty for spot markets
|
|
482
|
+
// "underlying": "LTC",
|
|
483
|
+
// "quoteCurrency": "USDT",
|
|
484
|
+
// "underlyingSymbol": "LTCT=", // can be empty for spot markets
|
|
485
|
+
// "reference": "BMEX",
|
|
486
|
+
// "referenceSymbol": ".BLTCT", // can be empty for spot markets
|
|
487
|
+
// "calcInterval": null,
|
|
488
|
+
// "publishInterval": null,
|
|
489
|
+
// "publishTime": null,
|
|
490
|
+
// "maxOrderQty": 1000000000,
|
|
491
|
+
// "maxPrice": 1000000,
|
|
492
|
+
// "lotSize": 1000,
|
|
493
|
+
// "tickSize": 0.01,
|
|
494
|
+
// "multiplier": 100,
|
|
495
|
+
// "settlCurrency": "USDt", // can be empty for spot markets
|
|
496
|
+
// "underlyingToPositionMultiplier": 10000,
|
|
497
|
+
// "underlyingToSettleMultiplier": null,
|
|
498
|
+
// "quoteToSettleMultiplier": 1000000,
|
|
499
|
+
// "isQuanto": false,
|
|
500
|
+
// "isInverse": false,
|
|
501
|
+
// "initMargin": 0.03,
|
|
502
|
+
// "maintMargin": 0.015,
|
|
503
|
+
// "riskLimit": 1000000000000, // can be null for spot markets
|
|
504
|
+
// "riskStep": 1000000000000, // can be null for spot markets
|
|
505
|
+
// "limit": null,
|
|
506
|
+
// "capped": false,
|
|
507
|
+
// "taxed": true,
|
|
508
|
+
// "deleverage": true,
|
|
509
|
+
// "makerFee": -0.0001,
|
|
510
|
+
// "takerFee": 0.0005,
|
|
511
|
+
// "settlementFee": 0,
|
|
512
|
+
// "insuranceFee": 0,
|
|
513
|
+
// "fundingBaseSymbol": ".LTCBON8H", // can be empty for spot markets
|
|
514
|
+
// "fundingQuoteSymbol": ".USDTBON8H", // can be empty for spot markets
|
|
515
|
+
// "fundingPremiumSymbol": ".LTCUSDTPI8H", // can be empty for spot markets
|
|
516
|
+
// "fundingTimestamp": "2022-01-14T20:00:00.000Z",
|
|
517
|
+
// "fundingInterval": "2000-01-01T08:00:00.000Z",
|
|
518
|
+
// "fundingRate": 0.0001,
|
|
519
|
+
// "indicativeFundingRate": 0.0001,
|
|
520
|
+
// "rebalanceTimestamp": null,
|
|
521
|
+
// "rebalanceInterval": null,
|
|
522
|
+
// "openingTimestamp": "2022-01-14T17:00:00.000Z",
|
|
523
|
+
// "closingTimestamp": "2022-01-14T18:00:00.000Z",
|
|
524
|
+
// "sessionInterval": "2000-01-01T01:00:00.000Z",
|
|
525
|
+
// "prevClosePrice": 138.511,
|
|
526
|
+
// "limitDownPrice": null,
|
|
527
|
+
// "limitUpPrice": null,
|
|
528
|
+
// "bankruptLimitDownPrice": null,
|
|
529
|
+
// "bankruptLimitUpPrice": null,
|
|
530
|
+
// "prevTotalVolume": 12699024000,
|
|
531
|
+
// "totalVolume": 12702160000,
|
|
532
|
+
// "volume": 3136000,
|
|
533
|
+
// "volume24h": 114251000,
|
|
534
|
+
// "prevTotalTurnover": 232418052349000,
|
|
535
|
+
// "totalTurnover": 232463353260000,
|
|
536
|
+
// "turnover": 45300911000,
|
|
537
|
+
// "turnover24h": 1604331340000,
|
|
538
|
+
// "homeNotional24h": 11425.1,
|
|
539
|
+
// "foreignNotional24h": 1604331.3400000003,
|
|
540
|
+
// "prevPrice24h": 135.48,
|
|
541
|
+
// "vwap": 140.42165,
|
|
542
|
+
// "highPrice": 146.42,
|
|
543
|
+
// "lowPrice": 135.08,
|
|
544
|
+
// "lastPrice": 144.36,
|
|
545
|
+
// "lastPriceProtected": 144.36,
|
|
546
|
+
// "lastTickDirection": "MinusTick",
|
|
547
|
+
// "lastChangePcnt": 0.0655,
|
|
548
|
+
// "bidPrice": 143.75,
|
|
549
|
+
// "midPrice": 143.855,
|
|
550
|
+
// "askPrice": 143.96,
|
|
551
|
+
// "impactBidPrice": 143.75,
|
|
552
|
+
// "impactMidPrice": 143.855,
|
|
553
|
+
// "impactAskPrice": 143.96,
|
|
554
|
+
// "hasLiquidity": true,
|
|
555
|
+
// "openInterest": 38103000,
|
|
556
|
+
// "openValue": 547963053300,
|
|
557
|
+
// "fairMethod": "FundingRate",
|
|
558
|
+
// "fairBasisRate": 0.1095,
|
|
559
|
+
// "fairBasis": 0.004,
|
|
560
|
+
// "fairPrice": 143.811,
|
|
561
|
+
// "markMethod": "FairPrice",
|
|
562
|
+
// "markPrice": 143.811,
|
|
563
|
+
// "indicativeTaxRate": null,
|
|
564
|
+
// "indicativeSettlePrice": 143.807,
|
|
565
|
+
// "optionUnderlyingPrice": null,
|
|
566
|
+
// "settledPriceAdjustmentRate": null,
|
|
567
|
+
// "settledPrice": null,
|
|
568
|
+
// "timestamp": "2022-01-14T17:49:55.000Z"
|
|
569
|
+
// }
|
|
570
|
+
// ]
|
|
571
|
+
//
|
|
572
|
+
return this.parseMarkets(response);
|
|
573
|
+
}
|
|
574
|
+
parseMarket(market) {
|
|
575
|
+
const id = this.safeString(market, 'symbol');
|
|
576
|
+
let baseId = this.safeString(market, 'underlying');
|
|
577
|
+
let quoteId = this.safeString(market, 'quoteCurrency');
|
|
578
|
+
const settleId = this.safeString(market, 'settlCurrency');
|
|
579
|
+
const settle = this.safeCurrencyCode(settleId);
|
|
580
|
+
// 'positionCurrency' may be empty ("", as Bitmex currently returns for ETHUSD)
|
|
581
|
+
// so let's take the settlCurrency first and then adjust if needed
|
|
582
|
+
const typ = this.safeString(market, 'typ'); // type definitions at: https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_get
|
|
583
|
+
let type;
|
|
584
|
+
let swap = false;
|
|
585
|
+
let spot = false;
|
|
586
|
+
let future = false;
|
|
587
|
+
if (typ === 'FFWCSX') {
|
|
588
|
+
type = 'swap';
|
|
589
|
+
swap = true;
|
|
590
|
+
}
|
|
591
|
+
else if (typ === 'IFXXXP') {
|
|
592
|
+
type = 'spot';
|
|
593
|
+
spot = true;
|
|
594
|
+
}
|
|
595
|
+
else if (typ === 'FFCCSX') {
|
|
596
|
+
type = 'future';
|
|
597
|
+
future = true;
|
|
598
|
+
}
|
|
599
|
+
else if (typ === 'FFICSX') {
|
|
600
|
+
// prediction markets (without any volume)
|
|
601
|
+
quoteId = baseId;
|
|
602
|
+
baseId = this.safeString(market, 'rootSymbol');
|
|
603
|
+
type = 'future';
|
|
604
|
+
future = true;
|
|
605
|
+
}
|
|
606
|
+
const base = this.safeCurrencyCode(baseId);
|
|
607
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
608
|
+
const contract = swap || future;
|
|
609
|
+
let contractSize = undefined;
|
|
610
|
+
const isInverse = this.safeValue(market, 'isInverse'); // this is true when BASE and SETTLE are same, i.e. BTC/XXX:BTC
|
|
611
|
+
const isQuanto = this.safeValue(market, 'isQuanto'); // this is true when BASE and SETTLE are different, i.e. AXS/XXX:BTC
|
|
612
|
+
const linear = contract ? (!isInverse && !isQuanto) : undefined;
|
|
613
|
+
const status = this.safeString(market, 'state');
|
|
614
|
+
const active = status !== 'Unlisted';
|
|
615
|
+
let expiry = undefined;
|
|
616
|
+
let expiryDatetime = undefined;
|
|
617
|
+
let symbol = undefined;
|
|
618
|
+
if (spot) {
|
|
619
|
+
symbol = base + '/' + quote;
|
|
620
|
+
}
|
|
621
|
+
else if (contract) {
|
|
622
|
+
symbol = base + '/' + quote + ':' + settle;
|
|
623
|
+
if (linear) {
|
|
624
|
+
const multiplierString = this.safeString2(market, 'underlyingToPositionMultiplier', 'underlyingToSettleMultiplier');
|
|
625
|
+
contractSize = this.parseNumber(Precise["default"].stringDiv('1', multiplierString));
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
const multiplierString = Precise["default"].stringAbs(this.safeString(market, 'multiplier'));
|
|
629
|
+
contractSize = this.parseNumber(multiplierString);
|
|
630
|
+
}
|
|
631
|
+
if (future) {
|
|
632
|
+
expiryDatetime = this.safeString(market, 'expiry');
|
|
633
|
+
expiry = this.parse8601(expiryDatetime);
|
|
634
|
+
symbol = symbol + '-' + this.yymmdd(expiry);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
// for index/exotic markets, default to id
|
|
639
|
+
symbol = id;
|
|
640
|
+
}
|
|
641
|
+
const positionId = this.safeString2(market, 'positionCurrency', 'underlying');
|
|
642
|
+
const position = this.safeCurrencyCode(positionId);
|
|
643
|
+
const positionIsQuote = (position === quote);
|
|
644
|
+
const maxOrderQty = this.safeNumber(market, 'maxOrderQty');
|
|
645
|
+
const initMargin = this.safeString(market, 'initMargin', '1');
|
|
646
|
+
const maxLeverage = this.parseNumber(Precise["default"].stringDiv('1', initMargin));
|
|
647
|
+
return {
|
|
648
|
+
'id': id,
|
|
649
|
+
'symbol': symbol,
|
|
650
|
+
'base': base,
|
|
651
|
+
'quote': quote,
|
|
652
|
+
'settle': settle,
|
|
653
|
+
'baseId': baseId,
|
|
654
|
+
'quoteId': quoteId,
|
|
655
|
+
'settleId': settleId,
|
|
656
|
+
'type': type,
|
|
657
|
+
'spot': spot,
|
|
658
|
+
'margin': false,
|
|
659
|
+
'swap': swap,
|
|
660
|
+
'future': future,
|
|
661
|
+
'option': false,
|
|
662
|
+
'active': active,
|
|
663
|
+
'contract': contract,
|
|
664
|
+
'linear': linear,
|
|
665
|
+
'inverse': isInverse,
|
|
666
|
+
'quanto': isQuanto,
|
|
667
|
+
'taker': this.safeNumber(market, 'takerFee'),
|
|
668
|
+
'maker': this.safeNumber(market, 'makerFee'),
|
|
669
|
+
'contractSize': contractSize,
|
|
670
|
+
'expiry': expiry,
|
|
671
|
+
'expiryDatetime': expiryDatetime,
|
|
672
|
+
'strike': this.safeNumber(market, 'optionStrikePrice'),
|
|
673
|
+
'optionType': undefined,
|
|
674
|
+
'precision': {
|
|
675
|
+
'amount': this.safeNumber(market, 'lotSize'),
|
|
676
|
+
'price': this.safeNumber(market, 'tickSize'),
|
|
677
|
+
},
|
|
678
|
+
'limits': {
|
|
679
|
+
'leverage': {
|
|
680
|
+
'min': contract ? this.parseNumber('1') : undefined,
|
|
681
|
+
'max': contract ? maxLeverage : undefined,
|
|
682
|
+
},
|
|
683
|
+
'amount': {
|
|
684
|
+
'min': undefined,
|
|
685
|
+
'max': positionIsQuote ? undefined : maxOrderQty,
|
|
686
|
+
},
|
|
687
|
+
'price': {
|
|
688
|
+
'min': undefined,
|
|
689
|
+
'max': this.safeNumber(market, 'maxPrice'),
|
|
690
|
+
},
|
|
691
|
+
'cost': {
|
|
692
|
+
'min': undefined,
|
|
693
|
+
'max': positionIsQuote ? maxOrderQty : undefined,
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
'created': this.parse8601(this.safeString(market, 'listing')),
|
|
697
|
+
'info': market,
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
parseBalance(response) {
|
|
701
|
+
//
|
|
702
|
+
// [
|
|
703
|
+
// {
|
|
704
|
+
// "account":1455728,
|
|
705
|
+
// "currency":"XBt",
|
|
706
|
+
// "riskLimit":1000000000000,
|
|
707
|
+
// "prevState":"",
|
|
708
|
+
// "state":"",
|
|
709
|
+
// "action":"",
|
|
710
|
+
// "amount":263542,
|
|
711
|
+
// "pendingCredit":0,
|
|
712
|
+
// "pendingDebit":0,
|
|
713
|
+
// "confirmedDebit":0,
|
|
714
|
+
// "prevRealisedPnl":0,
|
|
715
|
+
// "prevUnrealisedPnl":0,
|
|
716
|
+
// "grossComm":0,
|
|
717
|
+
// "grossOpenCost":0,
|
|
718
|
+
// "grossOpenPremium":0,
|
|
719
|
+
// "grossExecCost":0,
|
|
720
|
+
// "grossMarkValue":0,
|
|
721
|
+
// "riskValue":0,
|
|
722
|
+
// "taxableMargin":0,
|
|
723
|
+
// "initMargin":0,
|
|
724
|
+
// "maintMargin":0,
|
|
725
|
+
// "sessionMargin":0,
|
|
726
|
+
// "targetExcessMargin":0,
|
|
727
|
+
// "varMargin":0,
|
|
728
|
+
// "realisedPnl":0,
|
|
729
|
+
// "unrealisedPnl":0,
|
|
730
|
+
// "indicativeTax":0,
|
|
731
|
+
// "unrealisedProfit":0,
|
|
732
|
+
// "syntheticMargin":null,
|
|
733
|
+
// "walletBalance":263542,
|
|
734
|
+
// "marginBalance":263542,
|
|
735
|
+
// "marginBalancePcnt":1,
|
|
736
|
+
// "marginLeverage":0,
|
|
737
|
+
// "marginUsedPcnt":0,
|
|
738
|
+
// "excessMargin":263542,
|
|
739
|
+
// "excessMarginPcnt":1,
|
|
740
|
+
// "availableMargin":263542,
|
|
741
|
+
// "withdrawableMargin":263542,
|
|
742
|
+
// "timestamp":"2020-08-03T12:01:01.246Z",
|
|
743
|
+
// "grossLastValue":0,
|
|
744
|
+
// "commission":null
|
|
745
|
+
// }
|
|
746
|
+
// ]
|
|
747
|
+
//
|
|
748
|
+
const result = { 'info': response };
|
|
749
|
+
for (let i = 0; i < response.length; i++) {
|
|
750
|
+
const balance = response[i];
|
|
751
|
+
const currencyId = this.safeString(balance, 'currency');
|
|
752
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
753
|
+
const account = this.account();
|
|
754
|
+
const free = this.safeString(balance, 'availableMargin');
|
|
755
|
+
const total = this.safeString(balance, 'marginBalance');
|
|
756
|
+
account['free'] = this.convertToRealAmount(code, free);
|
|
757
|
+
account['total'] = this.convertToRealAmount(code, total);
|
|
758
|
+
result[code] = account;
|
|
759
|
+
}
|
|
760
|
+
return this.safeBalance(result);
|
|
761
|
+
}
|
|
762
|
+
async fetchBalance(params = {}) {
|
|
763
|
+
/**
|
|
764
|
+
* @method
|
|
765
|
+
* @name bitmex#fetchBalance
|
|
766
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
767
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
768
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
769
|
+
*/
|
|
770
|
+
await this.loadMarkets();
|
|
771
|
+
const request = {
|
|
772
|
+
'currency': 'all',
|
|
773
|
+
};
|
|
774
|
+
const response = await this.privateGetUserMargin(this.extend(request, params));
|
|
775
|
+
//
|
|
776
|
+
// [
|
|
777
|
+
// {
|
|
778
|
+
// "account":1455728,
|
|
779
|
+
// "currency":"XBt",
|
|
780
|
+
// "riskLimit":1000000000000,
|
|
781
|
+
// "prevState":"",
|
|
782
|
+
// "state":"",
|
|
783
|
+
// "action":"",
|
|
784
|
+
// "amount":263542,
|
|
785
|
+
// "pendingCredit":0,
|
|
786
|
+
// "pendingDebit":0,
|
|
787
|
+
// "confirmedDebit":0,
|
|
788
|
+
// "prevRealisedPnl":0,
|
|
789
|
+
// "prevUnrealisedPnl":0,
|
|
790
|
+
// "grossComm":0,
|
|
791
|
+
// "grossOpenCost":0,
|
|
792
|
+
// "grossOpenPremium":0,
|
|
793
|
+
// "grossExecCost":0,
|
|
794
|
+
// "grossMarkValue":0,
|
|
795
|
+
// "riskValue":0,
|
|
796
|
+
// "taxableMargin":0,
|
|
797
|
+
// "initMargin":0,
|
|
798
|
+
// "maintMargin":0,
|
|
799
|
+
// "sessionMargin":0,
|
|
800
|
+
// "targetExcessMargin":0,
|
|
801
|
+
// "varMargin":0,
|
|
802
|
+
// "realisedPnl":0,
|
|
803
|
+
// "unrealisedPnl":0,
|
|
804
|
+
// "indicativeTax":0,
|
|
805
|
+
// "unrealisedProfit":0,
|
|
806
|
+
// "syntheticMargin":null,
|
|
807
|
+
// "walletBalance":263542,
|
|
808
|
+
// "marginBalance":263542,
|
|
809
|
+
// "marginBalancePcnt":1,
|
|
810
|
+
// "marginLeverage":0,
|
|
811
|
+
// "marginUsedPcnt":0,
|
|
812
|
+
// "excessMargin":263542,
|
|
813
|
+
// "excessMarginPcnt":1,
|
|
814
|
+
// "availableMargin":263542,
|
|
815
|
+
// "withdrawableMargin":263542,
|
|
816
|
+
// "timestamp":"2020-08-03T12:01:01.246Z",
|
|
817
|
+
// "grossLastValue":0,
|
|
818
|
+
// "commission":null
|
|
819
|
+
// }
|
|
820
|
+
// ]
|
|
821
|
+
//
|
|
822
|
+
return this.parseBalance(response);
|
|
823
|
+
}
|
|
824
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
825
|
+
/**
|
|
826
|
+
* @method
|
|
827
|
+
* @name bitmex#fetchOrderBook
|
|
828
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
829
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
830
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
831
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
832
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
833
|
+
*/
|
|
834
|
+
await this.loadMarkets();
|
|
835
|
+
const market = this.market(symbol);
|
|
836
|
+
const request = {
|
|
837
|
+
'symbol': market['id'],
|
|
838
|
+
};
|
|
839
|
+
if (limit !== undefined) {
|
|
840
|
+
request['depth'] = limit;
|
|
841
|
+
}
|
|
842
|
+
const response = await this.publicGetOrderBookL2(this.extend(request, params));
|
|
843
|
+
const result = {
|
|
844
|
+
'symbol': symbol,
|
|
845
|
+
'bids': [],
|
|
846
|
+
'asks': [],
|
|
847
|
+
'timestamp': undefined,
|
|
848
|
+
'datetime': undefined,
|
|
849
|
+
'nonce': undefined,
|
|
850
|
+
};
|
|
851
|
+
for (let i = 0; i < response.length; i++) {
|
|
852
|
+
const order = response[i];
|
|
853
|
+
const side = (order['side'] === 'Sell') ? 'asks' : 'bids';
|
|
854
|
+
const amount = this.convertFromRawQuantity(symbol, this.safeString(order, 'size'));
|
|
855
|
+
const price = this.safeNumber(order, 'price');
|
|
856
|
+
// https://github.com/ccxt/ccxt/issues/4926
|
|
857
|
+
// https://github.com/ccxt/ccxt/issues/4927
|
|
858
|
+
// the exchange sometimes returns null price in the orderbook
|
|
859
|
+
if (price !== undefined) {
|
|
860
|
+
result[side].push([price, amount]);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
result['bids'] = this.sortBy(result['bids'], 0, true);
|
|
864
|
+
result['asks'] = this.sortBy(result['asks'], 0);
|
|
865
|
+
return result;
|
|
866
|
+
}
|
|
867
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
868
|
+
/**
|
|
869
|
+
* @method
|
|
870
|
+
* @name bitmex#fetchOrder
|
|
871
|
+
* @description fetches information on an order made by the user
|
|
872
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
873
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
874
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
875
|
+
*/
|
|
876
|
+
const filter = {
|
|
877
|
+
'filter': {
|
|
878
|
+
'orderID': id,
|
|
879
|
+
},
|
|
880
|
+
};
|
|
881
|
+
const response = await this.fetchOrders(symbol, undefined, undefined, this.deepExtend(filter, params));
|
|
882
|
+
const numResults = response.length;
|
|
883
|
+
if (numResults === 1) {
|
|
884
|
+
return response[0];
|
|
885
|
+
}
|
|
886
|
+
throw new errors.OrderNotFound(this.id + ': The order ' + id + ' not found.');
|
|
887
|
+
}
|
|
888
|
+
async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
889
|
+
/**
|
|
890
|
+
* @method
|
|
891
|
+
* @name bitmex#fetchOrders
|
|
892
|
+
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_getOrders
|
|
893
|
+
* @description fetches information on multiple orders made by the user
|
|
894
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
895
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
896
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
897
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
898
|
+
* @param {int} [params.until] the earliest time in ms to fetch orders for
|
|
899
|
+
* @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)
|
|
900
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
901
|
+
*/
|
|
902
|
+
await this.loadMarkets();
|
|
903
|
+
let paginate = false;
|
|
904
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOrders', 'paginate');
|
|
905
|
+
if (paginate) {
|
|
906
|
+
return await this.fetchPaginatedCallDynamic('fetchOrders', symbol, since, limit, params, 100);
|
|
907
|
+
}
|
|
908
|
+
let market = undefined;
|
|
909
|
+
let request = {};
|
|
910
|
+
if (symbol !== undefined) {
|
|
911
|
+
market = this.market(symbol);
|
|
912
|
+
request['symbol'] = market['id'];
|
|
913
|
+
}
|
|
914
|
+
if (since !== undefined) {
|
|
915
|
+
request['startTime'] = this.iso8601(since);
|
|
916
|
+
}
|
|
917
|
+
if (limit !== undefined) {
|
|
918
|
+
request['count'] = limit;
|
|
919
|
+
}
|
|
920
|
+
const until = this.safeInteger2(params, 'until', 'endTime');
|
|
921
|
+
if (until !== undefined) {
|
|
922
|
+
params = this.omit(params, ['until']);
|
|
923
|
+
request['endTime'] = this.iso8601(until);
|
|
924
|
+
}
|
|
925
|
+
request = this.deepExtend(request, params);
|
|
926
|
+
// why the hassle? urlencode in python is kinda broken for nested dicts.
|
|
927
|
+
// E.g. self.urlencode({"filter": {"open": True}}) will return "filter={'open':+True}"
|
|
928
|
+
// Bitmex doesn't like that. Hence resorting to this hack.
|
|
929
|
+
if ('filter' in request) {
|
|
930
|
+
request['filter'] = this.json(request['filter']);
|
|
931
|
+
}
|
|
932
|
+
const response = await this.privateGetOrder(request);
|
|
933
|
+
return this.parseOrders(response, market, since, limit);
|
|
934
|
+
}
|
|
935
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
936
|
+
/**
|
|
937
|
+
* @method
|
|
938
|
+
* @name bitmex#fetchOpenOrders
|
|
939
|
+
* @description fetch all unfilled currently open orders
|
|
940
|
+
* @param {string} symbol unified market symbol
|
|
941
|
+
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
942
|
+
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
943
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
944
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
945
|
+
*/
|
|
946
|
+
const request = {
|
|
947
|
+
'filter': {
|
|
948
|
+
'open': true,
|
|
949
|
+
},
|
|
950
|
+
};
|
|
951
|
+
return await this.fetchOrders(symbol, since, limit, this.deepExtend(request, params));
|
|
952
|
+
}
|
|
953
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
954
|
+
/**
|
|
955
|
+
* @method
|
|
956
|
+
* @name bitmex#fetchClosedOrders
|
|
957
|
+
* @description fetches information on multiple closed orders made by the user
|
|
958
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
959
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
960
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
961
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
962
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
963
|
+
*/
|
|
964
|
+
// Bitmex barfs if you set 'open': false in the filter...
|
|
965
|
+
const orders = await this.fetchOrders(symbol, since, limit, params);
|
|
966
|
+
return this.filterByArray(orders, 'status', ['closed', 'canceled'], false);
|
|
967
|
+
}
|
|
968
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
969
|
+
/**
|
|
970
|
+
* @method
|
|
971
|
+
* @name bitmex#fetchMyTrades
|
|
972
|
+
* @see https://www.bitmex.com/api/explorer/#!/Execution/Execution_getTradeHistory
|
|
973
|
+
* @description fetch all trades made by the user
|
|
974
|
+
* @param {string} symbol unified market symbol
|
|
975
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
976
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
977
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
978
|
+
* @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)
|
|
979
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
980
|
+
*/
|
|
981
|
+
await this.loadMarkets();
|
|
982
|
+
let paginate = false;
|
|
983
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'paginate');
|
|
984
|
+
if (paginate) {
|
|
985
|
+
return await this.fetchPaginatedCallDynamic('fetchMyTrades', symbol, since, limit, params, 100);
|
|
986
|
+
}
|
|
987
|
+
let market = undefined;
|
|
988
|
+
let request = {};
|
|
989
|
+
if (symbol !== undefined) {
|
|
990
|
+
market = this.market(symbol);
|
|
991
|
+
request['symbol'] = market['id'];
|
|
992
|
+
}
|
|
993
|
+
if (since !== undefined) {
|
|
994
|
+
request['startTime'] = this.iso8601(since);
|
|
995
|
+
}
|
|
996
|
+
if (limit !== undefined) {
|
|
997
|
+
request['count'] = limit;
|
|
998
|
+
}
|
|
999
|
+
const until = this.safeInteger2(params, 'until', 'endTime');
|
|
1000
|
+
if (until !== undefined) {
|
|
1001
|
+
params = this.omit(params, ['until']);
|
|
1002
|
+
request['endTime'] = this.iso8601(until);
|
|
1003
|
+
}
|
|
1004
|
+
request = this.deepExtend(request, params);
|
|
1005
|
+
// why the hassle? urlencode in python is kinda broken for nested dicts.
|
|
1006
|
+
// E.g. self.urlencode({"filter": {"open": True}}) will return "filter={'open':+True}"
|
|
1007
|
+
// Bitmex doesn't like that. Hence resorting to this hack.
|
|
1008
|
+
if ('filter' in request) {
|
|
1009
|
+
request['filter'] = this.json(request['filter']);
|
|
1010
|
+
}
|
|
1011
|
+
const response = await this.privateGetExecutionTradeHistory(request);
|
|
1012
|
+
//
|
|
1013
|
+
// [
|
|
1014
|
+
// {
|
|
1015
|
+
// "execID": "string",
|
|
1016
|
+
// "orderID": "string",
|
|
1017
|
+
// "clOrdID": "string",
|
|
1018
|
+
// "clOrdLinkID": "string",
|
|
1019
|
+
// "account": 0,
|
|
1020
|
+
// "symbol": "string",
|
|
1021
|
+
// "side": "string",
|
|
1022
|
+
// "lastQty": 0,
|
|
1023
|
+
// "lastPx": 0,
|
|
1024
|
+
// "underlyingLastPx": 0,
|
|
1025
|
+
// "lastMkt": "string",
|
|
1026
|
+
// "lastLiquidityInd": "string",
|
|
1027
|
+
// "simpleOrderQty": 0,
|
|
1028
|
+
// "orderQty": 0,
|
|
1029
|
+
// "price": 0,
|
|
1030
|
+
// "displayQty": 0,
|
|
1031
|
+
// "stopPx": 0,
|
|
1032
|
+
// "pegOffsetValue": 0,
|
|
1033
|
+
// "pegPriceType": "string",
|
|
1034
|
+
// "currency": "string",
|
|
1035
|
+
// "settlCurrency": "string",
|
|
1036
|
+
// "execType": "string",
|
|
1037
|
+
// "ordType": "string",
|
|
1038
|
+
// "timeInForce": "string",
|
|
1039
|
+
// "execInst": "string",
|
|
1040
|
+
// "contingencyType": "string",
|
|
1041
|
+
// "exDestination": "string",
|
|
1042
|
+
// "ordStatus": "string",
|
|
1043
|
+
// "triggered": "string",
|
|
1044
|
+
// "workingIndicator": true,
|
|
1045
|
+
// "ordRejReason": "string",
|
|
1046
|
+
// "simpleLeavesQty": 0,
|
|
1047
|
+
// "leavesQty": 0,
|
|
1048
|
+
// "simpleCumQty": 0,
|
|
1049
|
+
// "cumQty": 0,
|
|
1050
|
+
// "avgPx": 0,
|
|
1051
|
+
// "commission": 0,
|
|
1052
|
+
// "tradePublishIndicator": "string",
|
|
1053
|
+
// "multiLegReportingType": "string",
|
|
1054
|
+
// "text": "string",
|
|
1055
|
+
// "trdMatchID": "string",
|
|
1056
|
+
// "execCost": 0,
|
|
1057
|
+
// "execComm": 0,
|
|
1058
|
+
// "homeNotional": 0,
|
|
1059
|
+
// "foreignNotional": 0,
|
|
1060
|
+
// "transactTime": "2019-03-05T12:47:02.762Z",
|
|
1061
|
+
// "timestamp": "2019-03-05T12:47:02.762Z"
|
|
1062
|
+
// }
|
|
1063
|
+
// ]
|
|
1064
|
+
//
|
|
1065
|
+
return this.parseTrades(response, market, since, limit);
|
|
1066
|
+
}
|
|
1067
|
+
parseLedgerEntryType(type) {
|
|
1068
|
+
const types = {
|
|
1069
|
+
'Withdrawal': 'transaction',
|
|
1070
|
+
'RealisedPNL': 'margin',
|
|
1071
|
+
'UnrealisedPNL': 'margin',
|
|
1072
|
+
'Deposit': 'transaction',
|
|
1073
|
+
'Transfer': 'transfer',
|
|
1074
|
+
'AffiliatePayout': 'referral',
|
|
1075
|
+
'SpotTrade': 'trade',
|
|
1076
|
+
};
|
|
1077
|
+
return this.safeString(types, type, type);
|
|
1078
|
+
}
|
|
1079
|
+
parseLedgerEntry(item, currency = undefined) {
|
|
1080
|
+
//
|
|
1081
|
+
// {
|
|
1082
|
+
// "transactID": "69573da3-7744-5467-3207-89fd6efe7a47",
|
|
1083
|
+
// "account": 24321,
|
|
1084
|
+
// "currency": "XBt",
|
|
1085
|
+
// "transactType": "Withdrawal", // "AffiliatePayout", "Transfer", "Deposit", "RealisedPNL", ...
|
|
1086
|
+
// "amount": -1000000,
|
|
1087
|
+
// "fee": 300000,
|
|
1088
|
+
// "transactStatus": "Completed", // "Canceled", ...
|
|
1089
|
+
// "address": "1Ex4fkF4NhQaQdRWNoYpqiPbDBbq18Kdd9",
|
|
1090
|
+
// "tx": "3BMEX91ZhhKoWtsH9QRb5dNXnmnGpiEetA",
|
|
1091
|
+
// "text": "",
|
|
1092
|
+
// "transactTime": "2017-03-21T20:05:14.388Z",
|
|
1093
|
+
// "walletBalance": 0, // balance after
|
|
1094
|
+
// "marginBalance": null,
|
|
1095
|
+
// "timestamp": "2017-03-22T13:09:23.514Z"
|
|
1096
|
+
// }
|
|
1097
|
+
//
|
|
1098
|
+
// ButMEX returns the unrealized pnl from the wallet history endpoint.
|
|
1099
|
+
// The unrealized pnl transaction has an empty timestamp.
|
|
1100
|
+
// It is not related to historical pnl it has status set to "Pending".
|
|
1101
|
+
// Therefore it's not a part of the history at all.
|
|
1102
|
+
// https://github.com/ccxt/ccxt/issues/6047
|
|
1103
|
+
//
|
|
1104
|
+
// {
|
|
1105
|
+
// "transactID":"00000000-0000-0000-0000-000000000000",
|
|
1106
|
+
// "account":121210,
|
|
1107
|
+
// "currency":"XBt",
|
|
1108
|
+
// "transactType":"UnrealisedPNL",
|
|
1109
|
+
// "amount":-5508,
|
|
1110
|
+
// "fee":0,
|
|
1111
|
+
// "transactStatus":"Pending",
|
|
1112
|
+
// "address":"XBTUSD",
|
|
1113
|
+
// "tx":"",
|
|
1114
|
+
// "text":"",
|
|
1115
|
+
// "transactTime":null, # ←---------------------------- null
|
|
1116
|
+
// "walletBalance":139198767,
|
|
1117
|
+
// "marginBalance":139193259,
|
|
1118
|
+
// "timestamp":null # ←---------------------------- null
|
|
1119
|
+
// }
|
|
1120
|
+
//
|
|
1121
|
+
const id = this.safeString(item, 'transactID');
|
|
1122
|
+
const account = this.safeString(item, 'account');
|
|
1123
|
+
const referenceId = this.safeString(item, 'tx');
|
|
1124
|
+
const referenceAccount = undefined;
|
|
1125
|
+
const type = this.parseLedgerEntryType(this.safeString(item, 'transactType'));
|
|
1126
|
+
const currencyId = this.safeString(item, 'currency');
|
|
1127
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
1128
|
+
const amountString = this.safeString(item, 'amount');
|
|
1129
|
+
let amount = this.convertToRealAmount(code, amountString);
|
|
1130
|
+
let timestamp = this.parse8601(this.safeString(item, 'transactTime'));
|
|
1131
|
+
if (timestamp === undefined) {
|
|
1132
|
+
// https://github.com/ccxt/ccxt/issues/6047
|
|
1133
|
+
// set the timestamp to zero, 1970 Jan 1 00:00:00
|
|
1134
|
+
// for unrealized pnl and other transactions without a timestamp
|
|
1135
|
+
timestamp = 0; // see comments above
|
|
1136
|
+
}
|
|
1137
|
+
let feeCost = this.safeString(item, 'fee');
|
|
1138
|
+
if (feeCost !== undefined) {
|
|
1139
|
+
feeCost = this.convertToRealAmount(code, feeCost);
|
|
1140
|
+
}
|
|
1141
|
+
const fee = {
|
|
1142
|
+
'cost': this.parseNumber(feeCost),
|
|
1143
|
+
'currency': code,
|
|
1144
|
+
};
|
|
1145
|
+
let after = this.safeString(item, 'walletBalance');
|
|
1146
|
+
if (after !== undefined) {
|
|
1147
|
+
after = this.convertToRealAmount(code, after);
|
|
1148
|
+
}
|
|
1149
|
+
const before = this.parseNumber(Precise["default"].stringSub(this.numberToString(after), this.numberToString(amount)));
|
|
1150
|
+
let direction = undefined;
|
|
1151
|
+
if (Precise["default"].stringLt(amountString, '0')) {
|
|
1152
|
+
direction = 'out';
|
|
1153
|
+
amount = this.convertToRealAmount(code, Precise["default"].stringAbs(amountString));
|
|
1154
|
+
}
|
|
1155
|
+
else {
|
|
1156
|
+
direction = 'in';
|
|
1157
|
+
}
|
|
1158
|
+
const status = this.parseTransactionStatus(this.safeString(item, 'transactStatus'));
|
|
1159
|
+
return {
|
|
1160
|
+
'id': id,
|
|
1161
|
+
'info': item,
|
|
1162
|
+
'timestamp': timestamp,
|
|
1163
|
+
'datetime': this.iso8601(timestamp),
|
|
1164
|
+
'direction': direction,
|
|
1165
|
+
'account': account,
|
|
1166
|
+
'referenceId': referenceId,
|
|
1167
|
+
'referenceAccount': referenceAccount,
|
|
1168
|
+
'type': type,
|
|
1169
|
+
'currency': code,
|
|
1170
|
+
'amount': amount,
|
|
1171
|
+
'before': before,
|
|
1172
|
+
'after': this.parseNumber(after),
|
|
1173
|
+
'status': status,
|
|
1174
|
+
'fee': fee,
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1178
|
+
/**
|
|
1179
|
+
* @method
|
|
1180
|
+
* @name bitmex#fetchLedger
|
|
1181
|
+
* @description fetch the history of changes, actions done by the user or operations that altered balance of the user
|
|
1182
|
+
* @param {string} code unified currency code, default is undefined
|
|
1183
|
+
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
|
1184
|
+
* @param {int} [limit] max number of ledger entrys to return, default is undefined
|
|
1185
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1186
|
+
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
|
|
1187
|
+
*/
|
|
1188
|
+
await this.loadMarkets();
|
|
1189
|
+
const request = {
|
|
1190
|
+
// 'start': 123,
|
|
1191
|
+
};
|
|
1192
|
+
//
|
|
1193
|
+
// if (since !== undefined) {
|
|
1194
|
+
// // date-based pagination not supported
|
|
1195
|
+
// }
|
|
1196
|
+
//
|
|
1197
|
+
if (limit !== undefined) {
|
|
1198
|
+
request['count'] = limit;
|
|
1199
|
+
}
|
|
1200
|
+
let currency = undefined;
|
|
1201
|
+
if (code !== undefined) {
|
|
1202
|
+
currency = this.currency(code);
|
|
1203
|
+
request['currency'] = currency['id'];
|
|
1204
|
+
}
|
|
1205
|
+
const response = await this.privateGetUserWalletHistory(this.extend(request, params));
|
|
1206
|
+
//
|
|
1207
|
+
// [
|
|
1208
|
+
// {
|
|
1209
|
+
// "transactID": "69573da3-7744-5467-3207-89fd6efe7a47",
|
|
1210
|
+
// "account": 24321,
|
|
1211
|
+
// "currency": "XBt",
|
|
1212
|
+
// "transactType": "Withdrawal", // "AffiliatePayout", "Transfer", "Deposit", "RealisedPNL", ...
|
|
1213
|
+
// "amount": -1000000,
|
|
1214
|
+
// "fee": 300000,
|
|
1215
|
+
// "transactStatus": "Completed", // "Canceled", ...
|
|
1216
|
+
// "address": "1Ex4fkF4NhQaQdRWNoYpqiPbDBbq18Kdd9",
|
|
1217
|
+
// "tx": "3BMEX91ZhhKoWtsH9QRb5dNXnmnGpiEetA",
|
|
1218
|
+
// "text": "",
|
|
1219
|
+
// "transactTime": "2017-03-21T20:05:14.388Z",
|
|
1220
|
+
// "walletBalance": 0, // balance after
|
|
1221
|
+
// "marginBalance": null,
|
|
1222
|
+
// "timestamp": "2017-03-22T13:09:23.514Z"
|
|
1223
|
+
// }
|
|
1224
|
+
// ]
|
|
1225
|
+
//
|
|
1226
|
+
return this.parseLedger(response, currency, since, limit);
|
|
1227
|
+
}
|
|
1228
|
+
async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1229
|
+
/**
|
|
1230
|
+
* @method
|
|
1231
|
+
* @name bitmex#fetchDepositsWithdrawals
|
|
1232
|
+
* @description fetch history of deposits and withdrawals
|
|
1233
|
+
* @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
|
|
1234
|
+
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
|
1235
|
+
* @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
|
|
1236
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1237
|
+
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1238
|
+
*/
|
|
1239
|
+
await this.loadMarkets();
|
|
1240
|
+
const request = {
|
|
1241
|
+
'currency': 'all',
|
|
1242
|
+
// 'start': 123,
|
|
1243
|
+
};
|
|
1244
|
+
//
|
|
1245
|
+
// if (since !== undefined) {
|
|
1246
|
+
// // date-based pagination not supported
|
|
1247
|
+
// }
|
|
1248
|
+
//
|
|
1249
|
+
let currency = undefined;
|
|
1250
|
+
if (code !== undefined) {
|
|
1251
|
+
currency = this.currency(code);
|
|
1252
|
+
request['currency'] = currency['id'];
|
|
1253
|
+
}
|
|
1254
|
+
if (limit !== undefined) {
|
|
1255
|
+
request['count'] = limit;
|
|
1256
|
+
}
|
|
1257
|
+
const response = await this.privateGetUserWalletHistory(this.extend(request, params));
|
|
1258
|
+
const transactions = this.filterByArray(response, 'transactType', ['Withdrawal', 'Deposit'], false);
|
|
1259
|
+
return this.parseTransactions(transactions, currency, since, limit);
|
|
1260
|
+
}
|
|
1261
|
+
parseTransactionStatus(status) {
|
|
1262
|
+
const statuses = {
|
|
1263
|
+
'Confirmed': 'pending',
|
|
1264
|
+
'Canceled': 'canceled',
|
|
1265
|
+
'Completed': 'ok',
|
|
1266
|
+
'Pending': 'pending',
|
|
1267
|
+
};
|
|
1268
|
+
return this.safeString(statuses, status, status);
|
|
1269
|
+
}
|
|
1270
|
+
parseTransaction(transaction, currency = undefined) {
|
|
1271
|
+
//
|
|
1272
|
+
// {
|
|
1273
|
+
// "transactID": "ffe699c2-95ee-4c13-91f9-0faf41daec25",
|
|
1274
|
+
// "account": 123456,
|
|
1275
|
+
// "currency": "XBt",
|
|
1276
|
+
// "network":'', // "tron" for USDt, etc...
|
|
1277
|
+
// "transactType": "Withdrawal",
|
|
1278
|
+
// "amount": -100100000,
|
|
1279
|
+
// "fee": 100000,
|
|
1280
|
+
// "transactStatus": "Completed",
|
|
1281
|
+
// "address": "385cR5DM96n1HvBDMzLHPYcw89fZAXULJP",
|
|
1282
|
+
// "tx": "3BMEXabcdefghijklmnopqrstuvwxyz123",
|
|
1283
|
+
// "text": '',
|
|
1284
|
+
// "transactTime": "2019-01-02T01:00:00.000Z",
|
|
1285
|
+
// "walletBalance": 99900000, // this field might be inexistent
|
|
1286
|
+
// "marginBalance": None, // this field might be inexistent
|
|
1287
|
+
// "timestamp": "2019-01-02T13:00:00.000Z"
|
|
1288
|
+
// }
|
|
1289
|
+
//
|
|
1290
|
+
const currencyId = this.safeString(transaction, 'currency');
|
|
1291
|
+
currency = this.safeCurrency(currencyId, currency);
|
|
1292
|
+
// For deposits, transactTime == timestamp
|
|
1293
|
+
// For withdrawals, transactTime is submission, timestamp is processed
|
|
1294
|
+
const transactTime = this.parse8601(this.safeString(transaction, 'transactTime'));
|
|
1295
|
+
const timestamp = this.parse8601(this.safeString(transaction, 'timestamp'));
|
|
1296
|
+
const type = this.safeStringLower(transaction, 'transactType');
|
|
1297
|
+
// Deposits have no from address or to address, withdrawals have both
|
|
1298
|
+
let address = undefined;
|
|
1299
|
+
let addressFrom = undefined;
|
|
1300
|
+
let addressTo = undefined;
|
|
1301
|
+
if (type === 'withdrawal') {
|
|
1302
|
+
address = this.safeString(transaction, 'address');
|
|
1303
|
+
addressFrom = this.safeString(transaction, 'tx');
|
|
1304
|
+
addressTo = address;
|
|
1305
|
+
}
|
|
1306
|
+
else if (type === 'deposit') {
|
|
1307
|
+
addressTo = this.safeString(transaction, 'address');
|
|
1308
|
+
addressFrom = this.safeString(transaction, 'tx');
|
|
1309
|
+
}
|
|
1310
|
+
const amountString = this.safeString(transaction, 'amount');
|
|
1311
|
+
const amountStringAbs = Precise["default"].stringAbs(amountString);
|
|
1312
|
+
const amount = this.convertToRealAmount(currency['code'], amountStringAbs);
|
|
1313
|
+
const feeCostString = this.safeString(transaction, 'fee');
|
|
1314
|
+
const feeCost = this.convertToRealAmount(currency['code'], feeCostString);
|
|
1315
|
+
let status = this.safeString(transaction, 'transactStatus');
|
|
1316
|
+
if (status !== undefined) {
|
|
1317
|
+
status = this.parseTransactionStatus(status);
|
|
1318
|
+
}
|
|
1319
|
+
return {
|
|
1320
|
+
'info': transaction,
|
|
1321
|
+
'id': this.safeString(transaction, 'transactID'),
|
|
1322
|
+
'txid': this.safeString(transaction, 'tx'),
|
|
1323
|
+
'type': type,
|
|
1324
|
+
'currency': currency['code'],
|
|
1325
|
+
'network': this.networkIdToCode(this.safeString(transaction, 'network'), currency['code']),
|
|
1326
|
+
'amount': this.parseNumber(amount),
|
|
1327
|
+
'status': status,
|
|
1328
|
+
'timestamp': transactTime,
|
|
1329
|
+
'datetime': this.iso8601(transactTime),
|
|
1330
|
+
'address': address,
|
|
1331
|
+
'addressFrom': addressFrom,
|
|
1332
|
+
'addressTo': addressTo,
|
|
1333
|
+
'tag': undefined,
|
|
1334
|
+
'tagFrom': undefined,
|
|
1335
|
+
'tagTo': undefined,
|
|
1336
|
+
'updated': timestamp,
|
|
1337
|
+
'internal': undefined,
|
|
1338
|
+
'comment': undefined,
|
|
1339
|
+
'fee': {
|
|
1340
|
+
'currency': currency['code'],
|
|
1341
|
+
'cost': this.parseNumber(feeCost),
|
|
1342
|
+
'rate': undefined,
|
|
1343
|
+
},
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
async fetchTicker(symbol, params = {}) {
|
|
1347
|
+
/**
|
|
1348
|
+
* @method
|
|
1349
|
+
* @name bitmex#fetchTicker
|
|
1350
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1351
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
1352
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1353
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1354
|
+
*/
|
|
1355
|
+
await this.loadMarkets();
|
|
1356
|
+
const market = this.market(symbol);
|
|
1357
|
+
const request = {
|
|
1358
|
+
'symbol': market['id'],
|
|
1359
|
+
};
|
|
1360
|
+
const response = await this.publicGetInstrument(this.extend(request, params));
|
|
1361
|
+
const ticker = this.safeValue(response, 0);
|
|
1362
|
+
if (ticker === undefined) {
|
|
1363
|
+
throw new errors.BadSymbol(this.id + ' fetchTicker() symbol ' + symbol + ' not found');
|
|
1364
|
+
}
|
|
1365
|
+
return this.parseTicker(ticker, market);
|
|
1366
|
+
}
|
|
1367
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
1368
|
+
/**
|
|
1369
|
+
* @method
|
|
1370
|
+
* @name bitmex#fetchTickers
|
|
1371
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1372
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1373
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1374
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
1375
|
+
*/
|
|
1376
|
+
await this.loadMarkets();
|
|
1377
|
+
symbols = this.marketSymbols(symbols);
|
|
1378
|
+
const response = await this.publicGetInstrumentActiveAndIndices(params);
|
|
1379
|
+
// same response as under "fetchMarkets"
|
|
1380
|
+
const result = {};
|
|
1381
|
+
for (let i = 0; i < response.length; i++) {
|
|
1382
|
+
const ticker = this.parseTicker(response[i]);
|
|
1383
|
+
const symbol = this.safeString(ticker, 'symbol');
|
|
1384
|
+
if (symbol !== undefined) {
|
|
1385
|
+
result[symbol] = ticker;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
return this.filterByArrayTickers(result, 'symbol', symbols);
|
|
1389
|
+
}
|
|
1390
|
+
parseTicker(ticker, market = undefined) {
|
|
1391
|
+
// see response sample under "fetchMarkets" because same endpoint is being used here
|
|
1392
|
+
const marketId = this.safeString(ticker, 'symbol');
|
|
1393
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1394
|
+
const timestamp = this.parse8601(this.safeString(ticker, 'timestamp'));
|
|
1395
|
+
const open = this.safeString(ticker, 'prevPrice24h');
|
|
1396
|
+
const last = this.safeString(ticker, 'lastPrice');
|
|
1397
|
+
return this.safeTicker({
|
|
1398
|
+
'symbol': symbol,
|
|
1399
|
+
'timestamp': timestamp,
|
|
1400
|
+
'datetime': this.iso8601(timestamp),
|
|
1401
|
+
'high': this.safeString(ticker, 'highPrice'),
|
|
1402
|
+
'low': this.safeString(ticker, 'lowPrice'),
|
|
1403
|
+
'bid': this.safeString(ticker, 'bidPrice'),
|
|
1404
|
+
'bidVolume': undefined,
|
|
1405
|
+
'ask': this.safeString(ticker, 'askPrice'),
|
|
1406
|
+
'askVolume': undefined,
|
|
1407
|
+
'vwap': this.safeString(ticker, 'vwap'),
|
|
1408
|
+
'open': open,
|
|
1409
|
+
'close': last,
|
|
1410
|
+
'last': last,
|
|
1411
|
+
'previousClose': undefined,
|
|
1412
|
+
'change': undefined,
|
|
1413
|
+
'percentage': undefined,
|
|
1414
|
+
'average': undefined,
|
|
1415
|
+
'baseVolume': this.safeString(ticker, 'homeNotional24h'),
|
|
1416
|
+
'quoteVolume': this.safeString(ticker, 'foreignNotional24h'),
|
|
1417
|
+
'info': ticker,
|
|
1418
|
+
}, market);
|
|
1419
|
+
}
|
|
1420
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1421
|
+
//
|
|
1422
|
+
// {
|
|
1423
|
+
// "timestamp":"2015-09-25T13:38:00.000Z",
|
|
1424
|
+
// "symbol":"XBTUSD",
|
|
1425
|
+
// "open":237.45,
|
|
1426
|
+
// "high":237.45,
|
|
1427
|
+
// "low":237.45,
|
|
1428
|
+
// "close":237.45,
|
|
1429
|
+
// "trades":0,
|
|
1430
|
+
// "volume":0,
|
|
1431
|
+
// "vwap":null,
|
|
1432
|
+
// "lastSize":null,
|
|
1433
|
+
// "turnover":0,
|
|
1434
|
+
// "homeNotional":0,
|
|
1435
|
+
// "foreignNotional":0
|
|
1436
|
+
// }
|
|
1437
|
+
//
|
|
1438
|
+
const marketId = this.safeString(ohlcv, 'symbol');
|
|
1439
|
+
market = this.safeMarket(marketId, market);
|
|
1440
|
+
const volume = this.convertFromRawQuantity(market['symbol'], this.safeString(ohlcv, 'volume'));
|
|
1441
|
+
return [
|
|
1442
|
+
this.parse8601(this.safeString(ohlcv, 'timestamp')),
|
|
1443
|
+
this.safeNumber(ohlcv, 'open'),
|
|
1444
|
+
this.safeNumber(ohlcv, 'high'),
|
|
1445
|
+
this.safeNumber(ohlcv, 'low'),
|
|
1446
|
+
this.safeNumber(ohlcv, 'close'),
|
|
1447
|
+
volume,
|
|
1448
|
+
];
|
|
1449
|
+
}
|
|
1450
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1451
|
+
/**
|
|
1452
|
+
* @method
|
|
1453
|
+
* @name bitmex#fetchOHLCV
|
|
1454
|
+
* @see https://www.bitmex.com/api/explorer/#!/Trade/Trade_getBucketed
|
|
1455
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1456
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1457
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1458
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1459
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1460
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1461
|
+
* @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)
|
|
1462
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1463
|
+
*/
|
|
1464
|
+
await this.loadMarkets();
|
|
1465
|
+
let paginate = false;
|
|
1466
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
|
|
1467
|
+
if (paginate) {
|
|
1468
|
+
return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params);
|
|
1469
|
+
}
|
|
1470
|
+
// send JSON key/value pairs, such as {"key": "value"}
|
|
1471
|
+
// filter by individual fields and do advanced queries on timestamps
|
|
1472
|
+
// let filter = { 'key': 'value' };
|
|
1473
|
+
// send a bare series (e.g. XBU) to nearest expiring contract in that series
|
|
1474
|
+
// you can also send a timeframe, e.g. XBU:monthly
|
|
1475
|
+
// timeframes: daily, weekly, monthly, quarterly, and biquarterly
|
|
1476
|
+
const market = this.market(symbol);
|
|
1477
|
+
const request = {
|
|
1478
|
+
'symbol': market['id'],
|
|
1479
|
+
'binSize': this.safeString(this.timeframes, timeframe, timeframe),
|
|
1480
|
+
'partial': true, // true == include yet-incomplete current bins
|
|
1481
|
+
// 'filter': filter, // filter by individual fields and do advanced queries
|
|
1482
|
+
// 'columns': [], // will return all columns if omitted
|
|
1483
|
+
// 'start': 0, // starting point for results (wtf?)
|
|
1484
|
+
// 'reverse': false, // true == newest first
|
|
1485
|
+
// 'endTime': '', // ending date filter for results
|
|
1486
|
+
};
|
|
1487
|
+
if (limit !== undefined) {
|
|
1488
|
+
request['count'] = limit; // default 100, max 500
|
|
1489
|
+
}
|
|
1490
|
+
const until = this.safeInteger2(params, 'until', 'endTime');
|
|
1491
|
+
if (until !== undefined) {
|
|
1492
|
+
params = this.omit(params, ['until']);
|
|
1493
|
+
request['endTime'] = this.iso8601(until);
|
|
1494
|
+
}
|
|
1495
|
+
const duration = this.parseTimeframe(timeframe) * 1000;
|
|
1496
|
+
const fetchOHLCVOpenTimestamp = this.safeValue(this.options, 'fetchOHLCVOpenTimestamp', true);
|
|
1497
|
+
// if since is not set, they will return candles starting from 2017-01-01
|
|
1498
|
+
if (since !== undefined) {
|
|
1499
|
+
let timestamp = since;
|
|
1500
|
+
if (fetchOHLCVOpenTimestamp) {
|
|
1501
|
+
timestamp = this.sum(timestamp, duration);
|
|
1502
|
+
}
|
|
1503
|
+
const ymdhms = this.ymdhms(timestamp);
|
|
1504
|
+
request['startTime'] = ymdhms; // starting date filter for results
|
|
1505
|
+
}
|
|
1506
|
+
else {
|
|
1507
|
+
request['reverse'] = true;
|
|
1508
|
+
}
|
|
1509
|
+
const response = await this.publicGetTradeBucketed(this.extend(request, params));
|
|
1510
|
+
//
|
|
1511
|
+
// [
|
|
1512
|
+
// {"timestamp":"2015-09-25T13:38:00.000Z","symbol":"XBTUSD","open":237.45,"high":237.45,"low":237.45,"close":237.45,"trades":0,"volume":0,"vwap":null,"lastSize":null,"turnover":0,"homeNotional":0,"foreignNotional":0},
|
|
1513
|
+
// {"timestamp":"2015-09-25T13:39:00.000Z","symbol":"XBTUSD","open":237.45,"high":237.45,"low":237.45,"close":237.45,"trades":0,"volume":0,"vwap":null,"lastSize":null,"turnover":0,"homeNotional":0,"foreignNotional":0},
|
|
1514
|
+
// {"timestamp":"2015-09-25T13:40:00.000Z","symbol":"XBTUSD","open":237.45,"high":237.45,"low":237.45,"close":237.45,"trades":0,"volume":0,"vwap":null,"lastSize":null,"turnover":0,"homeNotional":0,"foreignNotional":0}
|
|
1515
|
+
// ]
|
|
1516
|
+
//
|
|
1517
|
+
const result = this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
1518
|
+
if (fetchOHLCVOpenTimestamp) {
|
|
1519
|
+
// bitmex returns the candle's close timestamp - https://github.com/ccxt/ccxt/issues/4446
|
|
1520
|
+
// we can emulate the open timestamp by shifting all the timestamps one place
|
|
1521
|
+
// so the previous close becomes the current open, and we drop the first candle
|
|
1522
|
+
for (let i = 0; i < result.length; i++) {
|
|
1523
|
+
result[i][0] = result[i][0] - duration;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
return result;
|
|
1527
|
+
}
|
|
1528
|
+
parseTrade(trade, market = undefined) {
|
|
1529
|
+
//
|
|
1530
|
+
// fetchTrades (public)
|
|
1531
|
+
//
|
|
1532
|
+
// {
|
|
1533
|
+
// "timestamp": "2018-08-28T00:00:02.735Z",
|
|
1534
|
+
// "symbol": "XBTUSD",
|
|
1535
|
+
// "side": "Buy",
|
|
1536
|
+
// "size": 2000,
|
|
1537
|
+
// "price": 6906.5,
|
|
1538
|
+
// "tickDirection": "PlusTick",
|
|
1539
|
+
// "trdMatchID": "b9a42432-0a46-6a2f-5ecc-c32e9ca4baf8",
|
|
1540
|
+
// "grossValue": 28958000,
|
|
1541
|
+
// "homeNotional": 0.28958,
|
|
1542
|
+
// "foreignNotional": 2000
|
|
1543
|
+
// }
|
|
1544
|
+
//
|
|
1545
|
+
// fetchMyTrades (private)
|
|
1546
|
+
//
|
|
1547
|
+
// {
|
|
1548
|
+
// "execID": "string",
|
|
1549
|
+
// "orderID": "string",
|
|
1550
|
+
// "clOrdID": "string",
|
|
1551
|
+
// "clOrdLinkID": "string",
|
|
1552
|
+
// "account": 0,
|
|
1553
|
+
// "symbol": "string",
|
|
1554
|
+
// "side": "string",
|
|
1555
|
+
// "lastQty": 0,
|
|
1556
|
+
// "lastPx": 0,
|
|
1557
|
+
// "underlyingLastPx": 0,
|
|
1558
|
+
// "lastMkt": "string",
|
|
1559
|
+
// "lastLiquidityInd": "string",
|
|
1560
|
+
// "simpleOrderQty": 0,
|
|
1561
|
+
// "orderQty": 0,
|
|
1562
|
+
// "price": 0,
|
|
1563
|
+
// "displayQty": 0,
|
|
1564
|
+
// "stopPx": 0,
|
|
1565
|
+
// "pegOffsetValue": 0,
|
|
1566
|
+
// "pegPriceType": "string",
|
|
1567
|
+
// "currency": "string",
|
|
1568
|
+
// "settlCurrency": "string",
|
|
1569
|
+
// "execType": "string",
|
|
1570
|
+
// "ordType": "string",
|
|
1571
|
+
// "timeInForce": "string",
|
|
1572
|
+
// "execInst": "string",
|
|
1573
|
+
// "contingencyType": "string",
|
|
1574
|
+
// "exDestination": "string",
|
|
1575
|
+
// "ordStatus": "string",
|
|
1576
|
+
// "triggered": "string",
|
|
1577
|
+
// "workingIndicator": true,
|
|
1578
|
+
// "ordRejReason": "string",
|
|
1579
|
+
// "simpleLeavesQty": 0,
|
|
1580
|
+
// "leavesQty": 0,
|
|
1581
|
+
// "simpleCumQty": 0,
|
|
1582
|
+
// "cumQty": 0,
|
|
1583
|
+
// "avgPx": 0,
|
|
1584
|
+
// "commission": 0,
|
|
1585
|
+
// "tradePublishIndicator": "string",
|
|
1586
|
+
// "multiLegReportingType": "string",
|
|
1587
|
+
// "text": "string",
|
|
1588
|
+
// "trdMatchID": "string",
|
|
1589
|
+
// "execCost": 0,
|
|
1590
|
+
// "execComm": 0,
|
|
1591
|
+
// "homeNotional": 0,
|
|
1592
|
+
// "foreignNotional": 0,
|
|
1593
|
+
// "transactTime": "2019-03-05T12:47:02.762Z",
|
|
1594
|
+
// "timestamp": "2019-03-05T12:47:02.762Z"
|
|
1595
|
+
// }
|
|
1596
|
+
//
|
|
1597
|
+
const marketId = this.safeString(trade, 'symbol');
|
|
1598
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1599
|
+
const timestamp = this.parse8601(this.safeString(trade, 'timestamp'));
|
|
1600
|
+
const priceString = this.safeString2(trade, 'avgPx', 'price');
|
|
1601
|
+
const amountString = this.convertFromRawQuantity(symbol, this.safeString2(trade, 'size', 'lastQty'));
|
|
1602
|
+
const execCost = this.numberToString(this.convertFromRawCost(symbol, this.safeString(trade, 'execCost')));
|
|
1603
|
+
const id = this.safeString(trade, 'trdMatchID');
|
|
1604
|
+
const order = this.safeString(trade, 'orderID');
|
|
1605
|
+
const side = this.safeStringLower(trade, 'side');
|
|
1606
|
+
// price * amount doesn't work for all symbols (e.g. XBT, ETH)
|
|
1607
|
+
let fee = undefined;
|
|
1608
|
+
const feeCostString = this.numberToString(this.convertFromRawCost(symbol, this.safeString(trade, 'execComm')));
|
|
1609
|
+
if (feeCostString !== undefined) {
|
|
1610
|
+
const currencyId = this.safeString2(trade, 'settlCurrency', 'currency');
|
|
1611
|
+
fee = {
|
|
1612
|
+
'cost': feeCostString,
|
|
1613
|
+
'currency': this.safeCurrencyCode(currencyId),
|
|
1614
|
+
'rate': this.safeString(trade, 'commission'),
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
// Trade or Funding
|
|
1618
|
+
const execType = this.safeString(trade, 'execType');
|
|
1619
|
+
let takerOrMaker = undefined;
|
|
1620
|
+
if (feeCostString !== undefined && execType === 'Trade') {
|
|
1621
|
+
takerOrMaker = Precise["default"].stringLt(feeCostString, '0') ? 'maker' : 'taker';
|
|
1622
|
+
}
|
|
1623
|
+
const type = this.safeStringLower(trade, 'ordType');
|
|
1624
|
+
return this.safeTrade({
|
|
1625
|
+
'info': trade,
|
|
1626
|
+
'timestamp': timestamp,
|
|
1627
|
+
'datetime': this.iso8601(timestamp),
|
|
1628
|
+
'symbol': symbol,
|
|
1629
|
+
'id': id,
|
|
1630
|
+
'order': order,
|
|
1631
|
+
'type': type,
|
|
1632
|
+
'takerOrMaker': takerOrMaker,
|
|
1633
|
+
'side': side,
|
|
1634
|
+
'price': priceString,
|
|
1635
|
+
'cost': Precise["default"].stringAbs(execCost),
|
|
1636
|
+
'amount': amountString,
|
|
1637
|
+
'fee': fee,
|
|
1638
|
+
}, market);
|
|
1639
|
+
}
|
|
1640
|
+
parseOrderStatus(status) {
|
|
1641
|
+
const statuses = {
|
|
1642
|
+
'New': 'open',
|
|
1643
|
+
'PartiallyFilled': 'open',
|
|
1644
|
+
'Filled': 'closed',
|
|
1645
|
+
'DoneForDay': 'open',
|
|
1646
|
+
'Canceled': 'canceled',
|
|
1647
|
+
'PendingCancel': 'open',
|
|
1648
|
+
'PendingNew': 'open',
|
|
1649
|
+
'Rejected': 'rejected',
|
|
1650
|
+
'Expired': 'expired',
|
|
1651
|
+
'Stopped': 'open',
|
|
1652
|
+
'Untriggered': 'open',
|
|
1653
|
+
'Triggered': 'open',
|
|
1654
|
+
};
|
|
1655
|
+
return this.safeString(statuses, status, status);
|
|
1656
|
+
}
|
|
1657
|
+
parseTimeInForce(timeInForce) {
|
|
1658
|
+
const timeInForces = {
|
|
1659
|
+
'Day': 'Day',
|
|
1660
|
+
'GoodTillCancel': 'GTC',
|
|
1661
|
+
'ImmediateOrCancel': 'IOC',
|
|
1662
|
+
'FillOrKill': 'FOK',
|
|
1663
|
+
};
|
|
1664
|
+
return this.safeString(timeInForces, timeInForce, timeInForce);
|
|
1665
|
+
}
|
|
1666
|
+
parseOrder(order, market = undefined) {
|
|
1667
|
+
//
|
|
1668
|
+
// {
|
|
1669
|
+
// "orderID":"56222c7a-9956-413a-82cf-99f4812c214b",
|
|
1670
|
+
// "clOrdID":"",
|
|
1671
|
+
// "clOrdLinkID":"",
|
|
1672
|
+
// "account":1455728,
|
|
1673
|
+
// "symbol":"XBTUSD",
|
|
1674
|
+
// "side":"Sell",
|
|
1675
|
+
// "simpleOrderQty":null,
|
|
1676
|
+
// "orderQty":1,
|
|
1677
|
+
// "price":40000,
|
|
1678
|
+
// "displayQty":null,
|
|
1679
|
+
// "stopPx":null,
|
|
1680
|
+
// "pegOffsetValue":null,
|
|
1681
|
+
// "pegPriceType":"",
|
|
1682
|
+
// "currency":"USD",
|
|
1683
|
+
// "settlCurrency":"XBt",
|
|
1684
|
+
// "ordType":"Limit",
|
|
1685
|
+
// "timeInForce":"GoodTillCancel",
|
|
1686
|
+
// "execInst":"",
|
|
1687
|
+
// "contingencyType":"",
|
|
1688
|
+
// "exDestination":"XBME",
|
|
1689
|
+
// "ordStatus":"New",
|
|
1690
|
+
// "triggered":"",
|
|
1691
|
+
// "workingIndicator":true,
|
|
1692
|
+
// "ordRejReason":"",
|
|
1693
|
+
// "simpleLeavesQty":null,
|
|
1694
|
+
// "leavesQty":1,
|
|
1695
|
+
// "simpleCumQty":null,
|
|
1696
|
+
// "cumQty":0,
|
|
1697
|
+
// "avgPx":null,
|
|
1698
|
+
// "multiLegReportingType":"SingleSecurity",
|
|
1699
|
+
// "text":"Submitted via API.",
|
|
1700
|
+
// "transactTime":"2021-01-02T21:38:49.246Z",
|
|
1701
|
+
// "timestamp":"2021-01-02T21:38:49.246Z"
|
|
1702
|
+
// }
|
|
1703
|
+
//
|
|
1704
|
+
const marketId = this.safeString(order, 'symbol');
|
|
1705
|
+
market = this.safeMarket(marketId, market);
|
|
1706
|
+
const symbol = market['symbol'];
|
|
1707
|
+
const qty = this.safeString(order, 'orderQty');
|
|
1708
|
+
let cost = undefined;
|
|
1709
|
+
let amount = undefined;
|
|
1710
|
+
let isInverse = false;
|
|
1711
|
+
if (marketId === undefined) {
|
|
1712
|
+
const defaultSubType = this.safeString(this.options, 'defaultSubType', 'linear');
|
|
1713
|
+
isInverse = (defaultSubType === 'inverse');
|
|
1714
|
+
}
|
|
1715
|
+
else {
|
|
1716
|
+
isInverse = this.safeValue(market, 'inverse', false);
|
|
1717
|
+
}
|
|
1718
|
+
if (isInverse) {
|
|
1719
|
+
cost = this.convertFromRawQuantity(symbol, qty);
|
|
1720
|
+
}
|
|
1721
|
+
else {
|
|
1722
|
+
amount = this.convertFromRawQuantity(symbol, qty);
|
|
1723
|
+
}
|
|
1724
|
+
const average = this.safeString(order, 'avgPx');
|
|
1725
|
+
let filled = undefined;
|
|
1726
|
+
const cumQty = this.numberToString(this.convertFromRawQuantity(symbol, this.safeString(order, 'cumQty')));
|
|
1727
|
+
if (isInverse) {
|
|
1728
|
+
filled = Precise["default"].stringDiv(cumQty, average);
|
|
1729
|
+
}
|
|
1730
|
+
else {
|
|
1731
|
+
filled = cumQty;
|
|
1732
|
+
}
|
|
1733
|
+
const execInst = this.safeString(order, 'execInst');
|
|
1734
|
+
let postOnly = undefined;
|
|
1735
|
+
if (execInst !== undefined) {
|
|
1736
|
+
postOnly = (execInst === 'ParticipateDoNotInitiate');
|
|
1737
|
+
}
|
|
1738
|
+
const timestamp = this.parse8601(this.safeString(order, 'timestamp'));
|
|
1739
|
+
const stopPrice = this.safeNumber(order, 'stopPx');
|
|
1740
|
+
const remaining = this.safeString(order, 'leavesQty');
|
|
1741
|
+
return this.safeOrder({
|
|
1742
|
+
'info': order,
|
|
1743
|
+
'id': this.safeString(order, 'orderID'),
|
|
1744
|
+
'clientOrderId': this.safeString(order, 'clOrdID'),
|
|
1745
|
+
'timestamp': timestamp,
|
|
1746
|
+
'datetime': this.iso8601(timestamp),
|
|
1747
|
+
'lastTradeTimestamp': this.parse8601(this.safeString(order, 'transactTime')),
|
|
1748
|
+
'symbol': symbol,
|
|
1749
|
+
'type': this.safeStringLower(order, 'ordType'),
|
|
1750
|
+
'timeInForce': this.parseTimeInForce(this.safeString(order, 'timeInForce')),
|
|
1751
|
+
'postOnly': postOnly,
|
|
1752
|
+
'side': this.safeStringLower(order, 'side'),
|
|
1753
|
+
'price': this.safeString(order, 'price'),
|
|
1754
|
+
'stopPrice': stopPrice,
|
|
1755
|
+
'triggerPrice': stopPrice,
|
|
1756
|
+
'amount': amount,
|
|
1757
|
+
'cost': cost,
|
|
1758
|
+
'average': average,
|
|
1759
|
+
'filled': filled,
|
|
1760
|
+
'remaining': this.convertFromRawQuantity(symbol, remaining),
|
|
1761
|
+
'status': this.parseOrderStatus(this.safeString(order, 'ordStatus')),
|
|
1762
|
+
'fee': undefined,
|
|
1763
|
+
'trades': undefined,
|
|
1764
|
+
}, market);
|
|
1765
|
+
}
|
|
1766
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
1767
|
+
/**
|
|
1768
|
+
* @method
|
|
1769
|
+
* @name bitmex#fetchTrades
|
|
1770
|
+
* @see https://www.bitmex.com/api/explorer/#!/Trade/Trade_get
|
|
1771
|
+
* @description get the list of most recent trades for a particular symbol
|
|
1772
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1773
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1774
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1775
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1776
|
+
* @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)
|
|
1777
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1778
|
+
*/
|
|
1779
|
+
await this.loadMarkets();
|
|
1780
|
+
let paginate = false;
|
|
1781
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchTrades', 'paginate');
|
|
1782
|
+
if (paginate) {
|
|
1783
|
+
return await this.fetchPaginatedCallDynamic('fetchTrades', symbol, since, limit, params);
|
|
1784
|
+
}
|
|
1785
|
+
const market = this.market(symbol);
|
|
1786
|
+
const request = {
|
|
1787
|
+
'symbol': market['id'],
|
|
1788
|
+
};
|
|
1789
|
+
if (since !== undefined) {
|
|
1790
|
+
request['startTime'] = this.iso8601(since);
|
|
1791
|
+
}
|
|
1792
|
+
else {
|
|
1793
|
+
// by default reverse=false, i.e. trades are fetched since the time of market inception (year 2015 for XBTUSD)
|
|
1794
|
+
request['reverse'] = true;
|
|
1795
|
+
}
|
|
1796
|
+
if (limit !== undefined) {
|
|
1797
|
+
request['count'] = Math.min(limit, 1000); // api maximum 1000
|
|
1798
|
+
}
|
|
1799
|
+
const until = this.safeInteger2(params, 'until', 'endTime');
|
|
1800
|
+
if (until !== undefined) {
|
|
1801
|
+
params = this.omit(params, ['until']);
|
|
1802
|
+
request['endTime'] = this.iso8601(until);
|
|
1803
|
+
}
|
|
1804
|
+
const response = await this.publicGetTrade(this.extend(request, params));
|
|
1805
|
+
//
|
|
1806
|
+
// [
|
|
1807
|
+
// {
|
|
1808
|
+
// "timestamp": "2018-08-28T00:00:02.735Z",
|
|
1809
|
+
// "symbol": "XBTUSD",
|
|
1810
|
+
// "side": "Buy",
|
|
1811
|
+
// "size": 2000,
|
|
1812
|
+
// "price": 6906.5,
|
|
1813
|
+
// "tickDirection": "PlusTick",
|
|
1814
|
+
// "trdMatchID": "b9a42432-0a46-6a2f-5ecc-c32e9ca4baf8",
|
|
1815
|
+
// "grossValue": 28958000,
|
|
1816
|
+
// "homeNotional": 0.28958,
|
|
1817
|
+
// "foreignNotional": 2000
|
|
1818
|
+
// },
|
|
1819
|
+
// {
|
|
1820
|
+
// "timestamp": "2018-08-28T00:00:03.778Z",
|
|
1821
|
+
// "symbol": "XBTUSD",
|
|
1822
|
+
// "side": "Sell",
|
|
1823
|
+
// "size": 1000,
|
|
1824
|
+
// "price": 6906,
|
|
1825
|
+
// "tickDirection": "MinusTick",
|
|
1826
|
+
// "trdMatchID": "0d4f1682-5270-a800-569b-4a0eb92db97c",
|
|
1827
|
+
// "grossValue": 14480000,
|
|
1828
|
+
// "homeNotional": 0.1448,
|
|
1829
|
+
// "foreignNotional": 1000
|
|
1830
|
+
// },
|
|
1831
|
+
// ]
|
|
1832
|
+
//
|
|
1833
|
+
return this.parseTrades(response, market, since, limit);
|
|
1834
|
+
}
|
|
1835
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1836
|
+
/**
|
|
1837
|
+
* @method
|
|
1838
|
+
* @name bitmex#createOrder
|
|
1839
|
+
* @description create a trade order
|
|
1840
|
+
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_new
|
|
1841
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1842
|
+
* @param {string} type 'market' or 'limit'
|
|
1843
|
+
* @param {string} side 'buy' or 'sell'
|
|
1844
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1845
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1846
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1847
|
+
* @param {object} [params.triggerPrice] the price at which a trigger order is triggered at
|
|
1848
|
+
* @param {object} [params.triggerDirection] the direction whenever the trigger happens with relation to price - 'above' or 'below'
|
|
1849
|
+
* @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
|
|
1850
|
+
* @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
|
|
1851
|
+
*/
|
|
1852
|
+
await this.loadMarkets();
|
|
1853
|
+
const market = this.market(symbol);
|
|
1854
|
+
let orderType = this.capitalize(type);
|
|
1855
|
+
const reduceOnly = this.safeValue(params, 'reduceOnly');
|
|
1856
|
+
if (reduceOnly !== undefined) {
|
|
1857
|
+
if ((!market['swap']) && (!market['future'])) {
|
|
1858
|
+
throw new errors.InvalidOrder(this.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap and future markets only');
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
const brokerId = this.safeString(this.options, 'brokerId', 'CCXT');
|
|
1862
|
+
const qty = this.parseToInt(this.amountToPrecision(symbol, amount));
|
|
1863
|
+
const request = {
|
|
1864
|
+
'symbol': market['id'],
|
|
1865
|
+
'side': this.capitalize(side),
|
|
1866
|
+
'orderQty': qty,
|
|
1867
|
+
'ordType': orderType,
|
|
1868
|
+
'text': brokerId,
|
|
1869
|
+
};
|
|
1870
|
+
// support for unified trigger format
|
|
1871
|
+
const triggerPrice = this.safeNumberN(params, ['triggerPrice', 'stopPx', 'stopPrice']);
|
|
1872
|
+
let trailingAmount = this.safeString2(params, 'trailingAmount', 'pegOffsetValue');
|
|
1873
|
+
const isTriggerOrder = triggerPrice !== undefined;
|
|
1874
|
+
const isTrailingAmountOrder = trailingAmount !== undefined;
|
|
1875
|
+
if (isTriggerOrder || isTrailingAmountOrder) {
|
|
1876
|
+
const triggerDirection = this.safeString(params, 'triggerDirection');
|
|
1877
|
+
const triggerAbove = (triggerDirection === 'above');
|
|
1878
|
+
if ((type === 'limit') || (type === 'market')) {
|
|
1879
|
+
this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
|
|
1880
|
+
}
|
|
1881
|
+
if (type === 'limit') {
|
|
1882
|
+
if (side === 'buy') {
|
|
1883
|
+
orderType = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
|
|
1884
|
+
}
|
|
1885
|
+
else {
|
|
1886
|
+
orderType = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
else if (type === 'market') {
|
|
1890
|
+
if (side === 'buy') {
|
|
1891
|
+
orderType = triggerAbove ? 'Stop' : 'MarketIfTouched';
|
|
1892
|
+
}
|
|
1893
|
+
else {
|
|
1894
|
+
orderType = triggerAbove ? 'MarketIfTouched' : 'Stop';
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
if (isTrailingAmountOrder) {
|
|
1898
|
+
const isStopSellOrder = (side === 'sell') && ((orderType === 'Stop') || (orderType === 'StopLimit'));
|
|
1899
|
+
const isBuyIfTouchedOrder = (side === 'buy') && ((orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched'));
|
|
1900
|
+
if (isStopSellOrder || isBuyIfTouchedOrder) {
|
|
1901
|
+
trailingAmount = '-' + trailingAmount;
|
|
1902
|
+
}
|
|
1903
|
+
request['pegOffsetValue'] = this.parseToNumeric(trailingAmount);
|
|
1904
|
+
request['pegPriceType'] = 'TrailingStopPeg';
|
|
1905
|
+
}
|
|
1906
|
+
else {
|
|
1907
|
+
if (triggerPrice === undefined) {
|
|
1908
|
+
// if exchange specific trigger types were provided
|
|
1909
|
+
throw new errors.ArgumentsRequired(this.id + ' createOrder() requires a triggerPrice (stopPx|stopPrice) parameter for the ' + orderType + ' order type');
|
|
1910
|
+
}
|
|
1911
|
+
request['stopPx'] = this.parseToNumeric(this.priceToPrecision(symbol, triggerPrice));
|
|
1912
|
+
}
|
|
1913
|
+
request['ordType'] = orderType;
|
|
1914
|
+
params = this.omit(params, ['triggerPrice', 'stopPrice', 'stopPx', 'triggerDirection', 'trailingAmount']);
|
|
1915
|
+
}
|
|
1916
|
+
if ((orderType === 'Limit') || (orderType === 'StopLimit') || (orderType === 'LimitIfTouched')) {
|
|
1917
|
+
request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
|
|
1918
|
+
}
|
|
1919
|
+
const clientOrderId = this.safeString2(params, 'clOrdID', 'clientOrderId');
|
|
1920
|
+
if (clientOrderId !== undefined) {
|
|
1921
|
+
request['clOrdID'] = clientOrderId;
|
|
1922
|
+
params = this.omit(params, ['clOrdID', 'clientOrderId']);
|
|
1923
|
+
}
|
|
1924
|
+
const response = await this.privatePostOrder(this.extend(request, params));
|
|
1925
|
+
return this.parseOrder(response, market);
|
|
1926
|
+
}
|
|
1927
|
+
async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
1928
|
+
await this.loadMarkets();
|
|
1929
|
+
const request = {};
|
|
1930
|
+
let trailingAmount = this.safeString2(params, 'trailingAmount', 'pegOffsetValue');
|
|
1931
|
+
const isTrailingAmountOrder = trailingAmount !== undefined;
|
|
1932
|
+
if (isTrailingAmountOrder) {
|
|
1933
|
+
const triggerDirection = this.safeString(params, 'triggerDirection');
|
|
1934
|
+
const triggerAbove = (triggerDirection === 'above');
|
|
1935
|
+
if ((type === 'limit') || (type === 'market')) {
|
|
1936
|
+
this.checkRequiredArgument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below']);
|
|
1937
|
+
}
|
|
1938
|
+
let orderType = undefined;
|
|
1939
|
+
if (type === 'limit') {
|
|
1940
|
+
if (side === 'buy') {
|
|
1941
|
+
orderType = triggerAbove ? 'StopLimit' : 'LimitIfTouched';
|
|
1942
|
+
}
|
|
1943
|
+
else {
|
|
1944
|
+
orderType = triggerAbove ? 'LimitIfTouched' : 'StopLimit';
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
else if (type === 'market') {
|
|
1948
|
+
if (side === 'buy') {
|
|
1949
|
+
orderType = triggerAbove ? 'Stop' : 'MarketIfTouched';
|
|
1950
|
+
}
|
|
1951
|
+
else {
|
|
1952
|
+
orderType = triggerAbove ? 'MarketIfTouched' : 'Stop';
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
const isStopSellOrder = (side === 'sell') && ((orderType === 'Stop') || (orderType === 'StopLimit'));
|
|
1956
|
+
const isBuyIfTouchedOrder = (side === 'buy') && ((orderType === 'MarketIfTouched') || (orderType === 'LimitIfTouched'));
|
|
1957
|
+
if (isStopSellOrder || isBuyIfTouchedOrder) {
|
|
1958
|
+
trailingAmount = '-' + trailingAmount;
|
|
1959
|
+
}
|
|
1960
|
+
request['pegOffsetValue'] = this.parseToNumeric(trailingAmount);
|
|
1961
|
+
params = this.omit(params, ['triggerDirection', 'trailingAmount']);
|
|
1962
|
+
}
|
|
1963
|
+
const origClOrdID = this.safeString2(params, 'origClOrdID', 'clientOrderId');
|
|
1964
|
+
if (origClOrdID !== undefined) {
|
|
1965
|
+
request['origClOrdID'] = origClOrdID;
|
|
1966
|
+
const clientOrderId = this.safeString(params, 'clOrdID', 'clientOrderId');
|
|
1967
|
+
if (clientOrderId !== undefined) {
|
|
1968
|
+
request['clOrdID'] = clientOrderId;
|
|
1969
|
+
}
|
|
1970
|
+
params = this.omit(params, ['origClOrdID', 'clOrdID', 'clientOrderId']);
|
|
1971
|
+
}
|
|
1972
|
+
else {
|
|
1973
|
+
request['orderID'] = id;
|
|
1974
|
+
}
|
|
1975
|
+
if (amount !== undefined) {
|
|
1976
|
+
const qty = this.parseToInt(this.amountToPrecision(symbol, amount));
|
|
1977
|
+
request['orderQty'] = qty;
|
|
1978
|
+
}
|
|
1979
|
+
if (price !== undefined) {
|
|
1980
|
+
request['price'] = price;
|
|
1981
|
+
}
|
|
1982
|
+
const brokerId = this.safeString(this.options, 'brokerId', 'CCXT');
|
|
1983
|
+
request['text'] = brokerId;
|
|
1984
|
+
const response = await this.privatePutOrder(this.extend(request, params));
|
|
1985
|
+
return this.parseOrder(response);
|
|
1986
|
+
}
|
|
1987
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1988
|
+
/**
|
|
1989
|
+
* @method
|
|
1990
|
+
* @name bitmex#cancelOrder
|
|
1991
|
+
* @description cancels an open order
|
|
1992
|
+
* @param {string} id order id
|
|
1993
|
+
* @param {string} symbol not used by bitmex cancelOrder ()
|
|
1994
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1995
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1996
|
+
*/
|
|
1997
|
+
await this.loadMarkets();
|
|
1998
|
+
// https://github.com/ccxt/ccxt/issues/6507
|
|
1999
|
+
const clientOrderId = this.safeValue2(params, 'clOrdID', 'clientOrderId');
|
|
2000
|
+
const request = {};
|
|
2001
|
+
if (clientOrderId === undefined) {
|
|
2002
|
+
request['orderID'] = id;
|
|
2003
|
+
}
|
|
2004
|
+
else {
|
|
2005
|
+
request['clOrdID'] = clientOrderId;
|
|
2006
|
+
params = this.omit(params, ['clOrdID', 'clientOrderId']);
|
|
2007
|
+
}
|
|
2008
|
+
const response = await this.privateDeleteOrder(this.extend(request, params));
|
|
2009
|
+
const order = this.safeValue(response, 0, {});
|
|
2010
|
+
const error = this.safeString(order, 'error');
|
|
2011
|
+
if (error !== undefined) {
|
|
2012
|
+
if (error.indexOf('Unable to cancel order due to existing state') >= 0) {
|
|
2013
|
+
throw new errors.OrderNotFound(this.id + ' cancelOrder() failed: ' + error);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
return this.parseOrder(order);
|
|
2017
|
+
}
|
|
2018
|
+
async cancelOrders(ids, symbol = undefined, params = {}) {
|
|
2019
|
+
/**
|
|
2020
|
+
* @method
|
|
2021
|
+
* @name bitmex#cancelOrders
|
|
2022
|
+
* @description cancel multiple orders
|
|
2023
|
+
* @param {string[]} ids order ids
|
|
2024
|
+
* @param {string} symbol not used by bitmex cancelOrders ()
|
|
2025
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2026
|
+
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2027
|
+
*/
|
|
2028
|
+
// return await this.cancelOrder (ids, symbol, params);
|
|
2029
|
+
await this.loadMarkets();
|
|
2030
|
+
// https://github.com/ccxt/ccxt/issues/6507
|
|
2031
|
+
const clientOrderId = this.safeValue2(params, 'clOrdID', 'clientOrderId');
|
|
2032
|
+
const request = {};
|
|
2033
|
+
if (clientOrderId === undefined) {
|
|
2034
|
+
request['orderID'] = ids;
|
|
2035
|
+
}
|
|
2036
|
+
else {
|
|
2037
|
+
request['clOrdID'] = clientOrderId;
|
|
2038
|
+
params = this.omit(params, ['clOrdID', 'clientOrderId']);
|
|
2039
|
+
}
|
|
2040
|
+
const response = await this.privateDeleteOrder(this.extend(request, params));
|
|
2041
|
+
return this.parseOrders(response);
|
|
2042
|
+
}
|
|
2043
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
2044
|
+
/**
|
|
2045
|
+
* @method
|
|
2046
|
+
* @name bitmex#cancelAllOrders
|
|
2047
|
+
* @description cancel all open orders
|
|
2048
|
+
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
2049
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2050
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2051
|
+
*/
|
|
2052
|
+
await this.loadMarkets();
|
|
2053
|
+
const request = {};
|
|
2054
|
+
let market = undefined;
|
|
2055
|
+
if (symbol !== undefined) {
|
|
2056
|
+
market = this.market(symbol);
|
|
2057
|
+
request['symbol'] = market['id'];
|
|
2058
|
+
}
|
|
2059
|
+
const response = await this.privateDeleteOrderAll(this.extend(request, params));
|
|
2060
|
+
//
|
|
2061
|
+
// [
|
|
2062
|
+
// {
|
|
2063
|
+
// "orderID": "string",
|
|
2064
|
+
// "clOrdID": "string",
|
|
2065
|
+
// "clOrdLinkID": "string",
|
|
2066
|
+
// "account": 0,
|
|
2067
|
+
// "symbol": "string",
|
|
2068
|
+
// "side": "string",
|
|
2069
|
+
// "simpleOrderQty": 0,
|
|
2070
|
+
// "orderQty": 0,
|
|
2071
|
+
// "price": 0,
|
|
2072
|
+
// "displayQty": 0,
|
|
2073
|
+
// "stopPx": 0,
|
|
2074
|
+
// "pegOffsetValue": 0,
|
|
2075
|
+
// "pegPriceType": "string",
|
|
2076
|
+
// "currency": "string",
|
|
2077
|
+
// "settlCurrency": "string",
|
|
2078
|
+
// "ordType": "string",
|
|
2079
|
+
// "timeInForce": "string",
|
|
2080
|
+
// "execInst": "string",
|
|
2081
|
+
// "contingencyType": "string",
|
|
2082
|
+
// "exDestination": "string",
|
|
2083
|
+
// "ordStatus": "string",
|
|
2084
|
+
// "triggered": "string",
|
|
2085
|
+
// "workingIndicator": true,
|
|
2086
|
+
// "ordRejReason": "string",
|
|
2087
|
+
// "simpleLeavesQty": 0,
|
|
2088
|
+
// "leavesQty": 0,
|
|
2089
|
+
// "simpleCumQty": 0,
|
|
2090
|
+
// "cumQty": 0,
|
|
2091
|
+
// "avgPx": 0,
|
|
2092
|
+
// "multiLegReportingType": "string",
|
|
2093
|
+
// "text": "string",
|
|
2094
|
+
// "transactTime": "2020-06-01T09:36:35.290Z",
|
|
2095
|
+
// "timestamp": "2020-06-01T09:36:35.290Z"
|
|
2096
|
+
// }
|
|
2097
|
+
// ]
|
|
2098
|
+
//
|
|
2099
|
+
return this.parseOrders(response, market);
|
|
2100
|
+
}
|
|
2101
|
+
async fetchPositions(symbols = undefined, params = {}) {
|
|
2102
|
+
/**
|
|
2103
|
+
* @method
|
|
2104
|
+
* @name bitmex#fetchPositions
|
|
2105
|
+
* @description fetch all open positions
|
|
2106
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
2107
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2108
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2109
|
+
*/
|
|
2110
|
+
await this.loadMarkets();
|
|
2111
|
+
const response = await this.privateGetPosition(params);
|
|
2112
|
+
//
|
|
2113
|
+
// [
|
|
2114
|
+
// {
|
|
2115
|
+
// "account": 0,
|
|
2116
|
+
// "symbol": "string",
|
|
2117
|
+
// "currency": "string",
|
|
2118
|
+
// "underlying": "string",
|
|
2119
|
+
// "quoteCurrency": "string",
|
|
2120
|
+
// "commission": 0,
|
|
2121
|
+
// "initMarginReq": 0,
|
|
2122
|
+
// "maintMarginReq": 0,
|
|
2123
|
+
// "riskLimit": 0,
|
|
2124
|
+
// "leverage": 0,
|
|
2125
|
+
// "crossMargin": true,
|
|
2126
|
+
// "deleveragePercentile": 0,
|
|
2127
|
+
// "rebalancedPnl": 0,
|
|
2128
|
+
// "prevRealisedPnl": 0,
|
|
2129
|
+
// "prevUnrealisedPnl": 0,
|
|
2130
|
+
// "prevClosePrice": 0,
|
|
2131
|
+
// "openingTimestamp": "2020-11-09T06:53:59.892Z",
|
|
2132
|
+
// "openingQty": 0,
|
|
2133
|
+
// "openingCost": 0,
|
|
2134
|
+
// "openingComm": 0,
|
|
2135
|
+
// "openOrderBuyQty": 0,
|
|
2136
|
+
// "openOrderBuyCost": 0,
|
|
2137
|
+
// "openOrderBuyPremium": 0,
|
|
2138
|
+
// "openOrderSellQty": 0,
|
|
2139
|
+
// "openOrderSellCost": 0,
|
|
2140
|
+
// "openOrderSellPremium": 0,
|
|
2141
|
+
// "execBuyQty": 0,
|
|
2142
|
+
// "execBuyCost": 0,
|
|
2143
|
+
// "execSellQty": 0,
|
|
2144
|
+
// "execSellCost": 0,
|
|
2145
|
+
// "execQty": 0,
|
|
2146
|
+
// "execCost": 0,
|
|
2147
|
+
// "execComm": 0,
|
|
2148
|
+
// "currentTimestamp": "2020-11-09T06:53:59.893Z",
|
|
2149
|
+
// "currentQty": 0,
|
|
2150
|
+
// "currentCost": 0,
|
|
2151
|
+
// "currentComm": 0,
|
|
2152
|
+
// "realisedCost": 0,
|
|
2153
|
+
// "unrealisedCost": 0,
|
|
2154
|
+
// "grossOpenCost": 0,
|
|
2155
|
+
// "grossOpenPremium": 0,
|
|
2156
|
+
// "grossExecCost": 0,
|
|
2157
|
+
// "isOpen": true,
|
|
2158
|
+
// "markPrice": 0,
|
|
2159
|
+
// "markValue": 0,
|
|
2160
|
+
// "riskValue": 0,
|
|
2161
|
+
// "homeNotional": 0,
|
|
2162
|
+
// "foreignNotional": 0,
|
|
2163
|
+
// "posState": "string",
|
|
2164
|
+
// "posCost": 0,
|
|
2165
|
+
// "posCost2": 0,
|
|
2166
|
+
// "posCross": 0,
|
|
2167
|
+
// "posInit": 0,
|
|
2168
|
+
// "posComm": 0,
|
|
2169
|
+
// "posLoss": 0,
|
|
2170
|
+
// "posMargin": 0,
|
|
2171
|
+
// "posMaint": 0,
|
|
2172
|
+
// "posAllowance": 0,
|
|
2173
|
+
// "taxableMargin": 0,
|
|
2174
|
+
// "initMargin": 0,
|
|
2175
|
+
// "maintMargin": 0,
|
|
2176
|
+
// "sessionMargin": 0,
|
|
2177
|
+
// "targetExcessMargin": 0,
|
|
2178
|
+
// "varMargin": 0,
|
|
2179
|
+
// "realisedGrossPnl": 0,
|
|
2180
|
+
// "realisedTax": 0,
|
|
2181
|
+
// "realisedPnl": 0,
|
|
2182
|
+
// "unrealisedGrossPnl": 0,
|
|
2183
|
+
// "longBankrupt": 0,
|
|
2184
|
+
// "shortBankrupt": 0,
|
|
2185
|
+
// "taxBase": 0,
|
|
2186
|
+
// "indicativeTaxRate": 0,
|
|
2187
|
+
// "indicativeTax": 0,
|
|
2188
|
+
// "unrealisedTax": 0,
|
|
2189
|
+
// "unrealisedPnl": 0,
|
|
2190
|
+
// "unrealisedPnlPcnt": 0,
|
|
2191
|
+
// "unrealisedRoePcnt": 0,
|
|
2192
|
+
// "simpleQty": 0,
|
|
2193
|
+
// "simpleCost": 0,
|
|
2194
|
+
// "simpleValue": 0,
|
|
2195
|
+
// "simplePnl": 0,
|
|
2196
|
+
// "simplePnlPcnt": 0,
|
|
2197
|
+
// "avgCostPrice": 0,
|
|
2198
|
+
// "avgEntryPrice": 0,
|
|
2199
|
+
// "breakEvenPrice": 0,
|
|
2200
|
+
// "marginCallPrice": 0,
|
|
2201
|
+
// "liquidationPrice": 0,
|
|
2202
|
+
// "bankruptPrice": 0,
|
|
2203
|
+
// "timestamp": "2020-11-09T06:53:59.894Z",
|
|
2204
|
+
// "lastPrice": 0,
|
|
2205
|
+
// "lastValue": 0
|
|
2206
|
+
// }
|
|
2207
|
+
// ]
|
|
2208
|
+
//
|
|
2209
|
+
const results = this.parsePositions(response, symbols);
|
|
2210
|
+
return this.filterByArrayPositions(results, 'symbol', symbols, false);
|
|
2211
|
+
}
|
|
2212
|
+
parsePosition(position, market = undefined) {
|
|
2213
|
+
//
|
|
2214
|
+
// {
|
|
2215
|
+
// "account": 9371654,
|
|
2216
|
+
// "symbol": "ETHUSDT",
|
|
2217
|
+
// "currency": "USDt",
|
|
2218
|
+
// "underlying": "ETH",
|
|
2219
|
+
// "quoteCurrency": "USDT",
|
|
2220
|
+
// "commission": 0.00075,
|
|
2221
|
+
// "initMarginReq": 0.3333333333333333,
|
|
2222
|
+
// "maintMarginReq": 0.01,
|
|
2223
|
+
// "riskLimit": 1000000000000,
|
|
2224
|
+
// "leverage": 3,
|
|
2225
|
+
// "crossMargin": false,
|
|
2226
|
+
// "deleveragePercentile": 1,
|
|
2227
|
+
// "rebalancedPnl": 0,
|
|
2228
|
+
// "prevRealisedPnl": 0,
|
|
2229
|
+
// "prevUnrealisedPnl": 0,
|
|
2230
|
+
// "prevClosePrice": 2053.738,
|
|
2231
|
+
// "openingTimestamp": "2022-05-21T04:00:00.000Z",
|
|
2232
|
+
// "openingQty": 0,
|
|
2233
|
+
// "openingCost": 0,
|
|
2234
|
+
// "openingComm": 0,
|
|
2235
|
+
// "openOrderBuyQty": 0,
|
|
2236
|
+
// "openOrderBuyCost": 0,
|
|
2237
|
+
// "openOrderBuyPremium": 0,
|
|
2238
|
+
// "openOrderSellQty": 0,
|
|
2239
|
+
// "openOrderSellCost": 0,
|
|
2240
|
+
// "openOrderSellPremium": 0,
|
|
2241
|
+
// "execBuyQty": 2000,
|
|
2242
|
+
// "execBuyCost": 39260000,
|
|
2243
|
+
// "execSellQty": 0,
|
|
2244
|
+
// "execSellCost": 0,
|
|
2245
|
+
// "execQty": 2000,
|
|
2246
|
+
// "execCost": 39260000,
|
|
2247
|
+
// "execComm": 26500,
|
|
2248
|
+
// "currentTimestamp": "2022-05-21T04:35:16.397Z",
|
|
2249
|
+
// "currentQty": 2000,
|
|
2250
|
+
// "currentCost": 39260000,
|
|
2251
|
+
// "currentComm": 26500,
|
|
2252
|
+
// "realisedCost": 0,
|
|
2253
|
+
// "unrealisedCost": 39260000,
|
|
2254
|
+
// "grossOpenCost": 0,
|
|
2255
|
+
// "grossOpenPremium": 0,
|
|
2256
|
+
// "grossExecCost": 39260000,
|
|
2257
|
+
// "isOpen": true,
|
|
2258
|
+
// "markPrice": 1964.195,
|
|
2259
|
+
// "markValue": 39283900,
|
|
2260
|
+
// "riskValue": 39283900,
|
|
2261
|
+
// "homeNotional": 0.02,
|
|
2262
|
+
// "foreignNotional": -39.2839,
|
|
2263
|
+
// "posState": "",
|
|
2264
|
+
// "posCost": 39260000,
|
|
2265
|
+
// "posCost2": 39260000,
|
|
2266
|
+
// "posCross": 0,
|
|
2267
|
+
// "posInit": 13086667,
|
|
2268
|
+
// "posComm": 39261,
|
|
2269
|
+
// "posLoss": 0,
|
|
2270
|
+
// "posMargin": 13125928,
|
|
2271
|
+
// "posMaint": 435787,
|
|
2272
|
+
// "posAllowance": 0,
|
|
2273
|
+
// "taxableMargin": 0,
|
|
2274
|
+
// "initMargin": 0,
|
|
2275
|
+
// "maintMargin": 13149828,
|
|
2276
|
+
// "sessionMargin": 0,
|
|
2277
|
+
// "targetExcessMargin": 0,
|
|
2278
|
+
// "varMargin": 0,
|
|
2279
|
+
// "realisedGrossPnl": 0,
|
|
2280
|
+
// "realisedTax": 0,
|
|
2281
|
+
// "realisedPnl": -26500,
|
|
2282
|
+
// "unrealisedGrossPnl": 23900,
|
|
2283
|
+
// "longBankrupt": 0,
|
|
2284
|
+
// "shortBankrupt": 0,
|
|
2285
|
+
// "taxBase": 0,
|
|
2286
|
+
// "indicativeTaxRate": null,
|
|
2287
|
+
// "indicativeTax": 0,
|
|
2288
|
+
// "unrealisedTax": 0,
|
|
2289
|
+
// "unrealisedPnl": 23900,
|
|
2290
|
+
// "unrealisedPnlPcnt": 0.0006,
|
|
2291
|
+
// "unrealisedRoePcnt": 0.0018,
|
|
2292
|
+
// "simpleQty": null,
|
|
2293
|
+
// "simpleCost": null,
|
|
2294
|
+
// "simpleValue": null,
|
|
2295
|
+
// "simplePnl": null,
|
|
2296
|
+
// "simplePnlPcnt": null,
|
|
2297
|
+
// "avgCostPrice": 1963,
|
|
2298
|
+
// "avgEntryPrice": 1963,
|
|
2299
|
+
// "breakEvenPrice": 1964.35,
|
|
2300
|
+
// "marginCallPrice": 1328.5,
|
|
2301
|
+
// "liquidationPrice": 1328.5,
|
|
2302
|
+
// "bankruptPrice": 1308.7,
|
|
2303
|
+
// "timestamp": "2022-05-21T04:35:16.397Z",
|
|
2304
|
+
// "lastPrice": 1964.195,
|
|
2305
|
+
// "lastValue": 39283900
|
|
2306
|
+
// }
|
|
2307
|
+
//
|
|
2308
|
+
market = this.safeMarket(this.safeString(position, 'symbol'), market);
|
|
2309
|
+
const symbol = market['symbol'];
|
|
2310
|
+
const datetime = this.safeString(position, 'timestamp');
|
|
2311
|
+
const crossMargin = this.safeValue(position, 'crossMargin');
|
|
2312
|
+
const marginMode = (crossMargin === true) ? 'cross' : 'isolated';
|
|
2313
|
+
const notionalString = Precise["default"].stringAbs(this.safeString2(position, 'foreignNotional', 'homeNotional'));
|
|
2314
|
+
const settleCurrencyCode = this.safeString(market, 'settle');
|
|
2315
|
+
const maintenanceMargin = this.convertToRealAmount(settleCurrencyCode, this.safeString(position, 'maintMargin'));
|
|
2316
|
+
const unrealisedPnl = this.convertToRealAmount(settleCurrencyCode, this.safeString(position, 'unrealisedPnl'));
|
|
2317
|
+
const contracts = this.parseNumber(Precise["default"].stringAbs(this.safeString(position, 'currentQty')));
|
|
2318
|
+
const contractSize = this.safeNumber(market, 'contractSize');
|
|
2319
|
+
let side = undefined;
|
|
2320
|
+
const homeNotional = this.safeString(position, 'homeNotional');
|
|
2321
|
+
if (homeNotional !== undefined) {
|
|
2322
|
+
if (homeNotional[0] === '-') {
|
|
2323
|
+
side = 'short';
|
|
2324
|
+
}
|
|
2325
|
+
else {
|
|
2326
|
+
side = 'long';
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
return this.safePosition({
|
|
2330
|
+
'info': position,
|
|
2331
|
+
'id': this.safeString(position, 'account'),
|
|
2332
|
+
'symbol': symbol,
|
|
2333
|
+
'timestamp': this.parse8601(datetime),
|
|
2334
|
+
'datetime': datetime,
|
|
2335
|
+
'lastUpdateTimestamp': undefined,
|
|
2336
|
+
'hedged': undefined,
|
|
2337
|
+
'side': side,
|
|
2338
|
+
'contracts': contracts,
|
|
2339
|
+
'contractSize': contractSize,
|
|
2340
|
+
'entryPrice': this.safeNumber(position, 'avgEntryPrice'),
|
|
2341
|
+
'markPrice': this.safeNumber(position, 'markPrice'),
|
|
2342
|
+
'lastPrice': undefined,
|
|
2343
|
+
'notional': this.parseNumber(notionalString),
|
|
2344
|
+
'leverage': this.safeNumber(position, 'leverage'),
|
|
2345
|
+
'collateral': undefined,
|
|
2346
|
+
'initialMargin': this.safeNumber(position, 'initMargin'),
|
|
2347
|
+
'initialMarginPercentage': this.safeNumber(position, 'initMarginReq'),
|
|
2348
|
+
'maintenanceMargin': maintenanceMargin,
|
|
2349
|
+
'maintenanceMarginPercentage': this.safeNumber(position, 'maintMarginReq'),
|
|
2350
|
+
'unrealizedPnl': unrealisedPnl,
|
|
2351
|
+
'liquidationPrice': this.safeNumber(position, 'liquidationPrice'),
|
|
2352
|
+
'marginMode': marginMode,
|
|
2353
|
+
'marginRatio': undefined,
|
|
2354
|
+
'percentage': this.safeNumber(position, 'unrealisedPnlPcnt'),
|
|
2355
|
+
'stopLossPrice': undefined,
|
|
2356
|
+
'takeProfitPrice': undefined,
|
|
2357
|
+
});
|
|
2358
|
+
}
|
|
2359
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2360
|
+
/**
|
|
2361
|
+
* @method
|
|
2362
|
+
* @name bitmex#withdraw
|
|
2363
|
+
* @description make a withdrawal
|
|
2364
|
+
* @param {string} code unified currency code
|
|
2365
|
+
* @param {float} amount the amount to withdraw
|
|
2366
|
+
* @param {string} address the address to withdraw to
|
|
2367
|
+
* @param {string} tag
|
|
2368
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2369
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2370
|
+
*/
|
|
2371
|
+
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
2372
|
+
this.checkAddress(address);
|
|
2373
|
+
await this.loadMarkets();
|
|
2374
|
+
const currency = this.currency(code);
|
|
2375
|
+
const qty = this.convertFromRealAmount(code, amount);
|
|
2376
|
+
let networkCode = undefined;
|
|
2377
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
2378
|
+
const request = {
|
|
2379
|
+
'currency': currency['id'],
|
|
2380
|
+
'amount': qty,
|
|
2381
|
+
'address': address,
|
|
2382
|
+
'network': this.networkCodeToId(networkCode, currency['code']),
|
|
2383
|
+
// 'otpToken': '123456', // requires if two-factor auth (OTP) is enabled
|
|
2384
|
+
// 'fee': 0.001, // bitcoin network fee
|
|
2385
|
+
};
|
|
2386
|
+
const response = await this.privatePostUserRequestWithdrawal(this.extend(request, params));
|
|
2387
|
+
//
|
|
2388
|
+
// {
|
|
2389
|
+
// "transactID": "3aece414-bb29-76c8-6c6d-16a477a51a1e",
|
|
2390
|
+
// "account": 1403035,
|
|
2391
|
+
// "currency": "USDt",
|
|
2392
|
+
// "network": "tron",
|
|
2393
|
+
// "transactType": "Withdrawal",
|
|
2394
|
+
// "amount": -11000000,
|
|
2395
|
+
// "fee": 1000000,
|
|
2396
|
+
// "transactStatus": "Pending",
|
|
2397
|
+
// "address": "TAf5JxcAQQsC2Nm2zu21XE2iDtnisxPo1x",
|
|
2398
|
+
// "tx": "",
|
|
2399
|
+
// "text": "",
|
|
2400
|
+
// "transactTime": "2022-12-16T07:37:06.500Z",
|
|
2401
|
+
// "timestamp": "2022-12-16T07:37:06.500Z",
|
|
2402
|
+
// }
|
|
2403
|
+
//
|
|
2404
|
+
return this.parseTransaction(response, currency);
|
|
2405
|
+
}
|
|
2406
|
+
async fetchFundingRates(symbols = undefined, params = {}) {
|
|
2407
|
+
/**
|
|
2408
|
+
* @method
|
|
2409
|
+
* @name bitmex#fetchFundingRates
|
|
2410
|
+
* @description fetch the funding rate for multiple markets
|
|
2411
|
+
* @param {string[]|undefined} symbols list of unified market symbols
|
|
2412
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2413
|
+
* @returns {object} a dictionary of [funding rates structures]{@link https://docs.ccxt.com/#/?id=funding-rates-structure}, indexe by market symbols
|
|
2414
|
+
*/
|
|
2415
|
+
await this.loadMarkets();
|
|
2416
|
+
const response = await this.publicGetInstrumentActiveAndIndices(params);
|
|
2417
|
+
// same response as under "fetchMarkets"
|
|
2418
|
+
const filteredResponse = [];
|
|
2419
|
+
for (let i = 0; i < response.length; i++) {
|
|
2420
|
+
const item = response[i];
|
|
2421
|
+
const marketId = this.safeString(item, 'symbol');
|
|
2422
|
+
const market = this.safeMarket(marketId);
|
|
2423
|
+
const swap = this.safeValue(market, 'swap', false);
|
|
2424
|
+
if (swap) {
|
|
2425
|
+
filteredResponse.push(item);
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
symbols = this.marketSymbols(symbols);
|
|
2429
|
+
const result = this.parseFundingRates(filteredResponse);
|
|
2430
|
+
return this.filterByArray(result, 'symbol', symbols);
|
|
2431
|
+
}
|
|
2432
|
+
parseFundingRate(contract, market = undefined) {
|
|
2433
|
+
// see response sample under "fetchMarkets" because same endpoint is being used here
|
|
2434
|
+
const datetime = this.safeString(contract, 'timestamp');
|
|
2435
|
+
const marketId = this.safeString(contract, 'symbol');
|
|
2436
|
+
const fundingDatetime = this.safeString(contract, 'fundingTimestamp');
|
|
2437
|
+
return {
|
|
2438
|
+
'info': contract,
|
|
2439
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
2440
|
+
'markPrice': this.safeNumber(contract, 'markPrice'),
|
|
2441
|
+
'indexPrice': undefined,
|
|
2442
|
+
'interestRate': undefined,
|
|
2443
|
+
'estimatedSettlePrice': this.safeNumber(contract, 'indicativeSettlePrice'),
|
|
2444
|
+
'timestamp': this.parse8601(datetime),
|
|
2445
|
+
'datetime': datetime,
|
|
2446
|
+
'fundingRate': this.safeNumber(contract, 'fundingRate'),
|
|
2447
|
+
'fundingTimestamp': this.iso8601(fundingDatetime),
|
|
2448
|
+
'fundingDatetime': fundingDatetime,
|
|
2449
|
+
'nextFundingRate': this.safeNumber(contract, 'indicativeFundingRate'),
|
|
2450
|
+
'nextFundingTimestamp': undefined,
|
|
2451
|
+
'nextFundingDatetime': undefined,
|
|
2452
|
+
'previousFundingRate': undefined,
|
|
2453
|
+
'previousFundingTimestamp': undefined,
|
|
2454
|
+
'previousFundingDatetime': undefined,
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2458
|
+
/**
|
|
2459
|
+
* @method
|
|
2460
|
+
* @name bitmex#fetchFundingRateHistory
|
|
2461
|
+
* @description Fetches the history of funding rates
|
|
2462
|
+
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
2463
|
+
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
2464
|
+
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
|
2465
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2466
|
+
* @param {int} [params.until] timestamp in ms for ending date filter
|
|
2467
|
+
* @param {bool} [params.reverse] if true, will sort results newest first
|
|
2468
|
+
* @param {int} [params.start] starting point for results
|
|
2469
|
+
* @param {string} [params.columns] array of column names to fetch in info, if omitted, will return all columns
|
|
2470
|
+
* @param {string} [params.filter] generic table filter, send json key/value pairs, such as {"key": "value"}, you can key on individual fields, and do more advanced querying on timestamps, see the [timestamp docs]{@link https://www.bitmex.com/app/restAPI#Timestamp-Filters} for more details
|
|
2471
|
+
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
|
|
2472
|
+
*/
|
|
2473
|
+
await this.loadMarkets();
|
|
2474
|
+
const request = {};
|
|
2475
|
+
let market = undefined;
|
|
2476
|
+
if (symbol in this.currencies) {
|
|
2477
|
+
const code = this.currency(symbol);
|
|
2478
|
+
request['symbol'] = code['id'];
|
|
2479
|
+
}
|
|
2480
|
+
else if (symbol !== undefined) {
|
|
2481
|
+
const splitSymbol = symbol.split(':');
|
|
2482
|
+
const splitSymbolLength = splitSymbol.length;
|
|
2483
|
+
const timeframes = ['nearest', 'daily', 'weekly', 'monthly', 'quarterly', 'biquarterly', 'perpetual'];
|
|
2484
|
+
if ((splitSymbolLength > 1) && this.inArray(splitSymbol[1], timeframes)) {
|
|
2485
|
+
const code = this.currency(splitSymbol[0]);
|
|
2486
|
+
symbol = code['id'] + ':' + splitSymbol[1];
|
|
2487
|
+
request['symbol'] = symbol;
|
|
2488
|
+
}
|
|
2489
|
+
else {
|
|
2490
|
+
market = this.market(symbol);
|
|
2491
|
+
request['symbol'] = market['id'];
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
if (since !== undefined) {
|
|
2495
|
+
request['startTime'] = this.iso8601(since);
|
|
2496
|
+
}
|
|
2497
|
+
if (limit !== undefined) {
|
|
2498
|
+
request['count'] = limit;
|
|
2499
|
+
}
|
|
2500
|
+
const until = this.safeInteger2(params, 'until', 'till');
|
|
2501
|
+
params = this.omit(params, ['until', 'till']);
|
|
2502
|
+
if (until !== undefined) {
|
|
2503
|
+
request['endTime'] = this.iso8601(until);
|
|
2504
|
+
}
|
|
2505
|
+
request['reverse'] = true;
|
|
2506
|
+
const response = await this.publicGetFunding(this.extend(request, params));
|
|
2507
|
+
//
|
|
2508
|
+
// [
|
|
2509
|
+
// {
|
|
2510
|
+
// "timestamp": "2016-05-07T12:00:00.000Z",
|
|
2511
|
+
// "symbol": "ETHXBT",
|
|
2512
|
+
// "fundingInterval": "2000-01-02T00:00:00.000Z",
|
|
2513
|
+
// "fundingRate": 0.0010890000000000001,
|
|
2514
|
+
// "fundingRateDaily": 0.0010890000000000001
|
|
2515
|
+
// }
|
|
2516
|
+
// ]
|
|
2517
|
+
//
|
|
2518
|
+
return this.parseFundingRateHistories(response, market, since, limit);
|
|
2519
|
+
}
|
|
2520
|
+
parseFundingRateHistory(info, market = undefined) {
|
|
2521
|
+
//
|
|
2522
|
+
// {
|
|
2523
|
+
// "timestamp": "2016-05-07T12:00:00.000Z",
|
|
2524
|
+
// "symbol": "ETHXBT",
|
|
2525
|
+
// "fundingInterval": "2000-01-02T00:00:00.000Z",
|
|
2526
|
+
// "fundingRate": 0.0010890000000000001,
|
|
2527
|
+
// "fundingRateDaily": 0.0010890000000000001
|
|
2528
|
+
// }
|
|
2529
|
+
//
|
|
2530
|
+
const marketId = this.safeString(info, 'symbol');
|
|
2531
|
+
const datetime = this.safeString(info, 'timestamp');
|
|
2532
|
+
return {
|
|
2533
|
+
'info': info,
|
|
2534
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
2535
|
+
'fundingRate': this.safeNumber(info, 'fundingRate'),
|
|
2536
|
+
'timestamp': this.parse8601(datetime),
|
|
2537
|
+
'datetime': datetime,
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
async setLeverage(leverage, symbol = undefined, params = {}) {
|
|
2541
|
+
/**
|
|
2542
|
+
* @method
|
|
2543
|
+
* @name bitmex#setLeverage
|
|
2544
|
+
* @description set the level of leverage for a market
|
|
2545
|
+
* @param {float} leverage the rate of leverage
|
|
2546
|
+
* @param {string} symbol unified market symbol
|
|
2547
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2548
|
+
* @returns {object} response from the exchange
|
|
2549
|
+
*/
|
|
2550
|
+
if (symbol === undefined) {
|
|
2551
|
+
throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
|
|
2552
|
+
}
|
|
2553
|
+
if ((leverage < 0.01) || (leverage > 100)) {
|
|
2554
|
+
throw new errors.BadRequest(this.id + ' leverage should be between 0.01 and 100');
|
|
2555
|
+
}
|
|
2556
|
+
await this.loadMarkets();
|
|
2557
|
+
const market = this.market(symbol);
|
|
2558
|
+
if (market['type'] !== 'swap' && market['type'] !== 'future') {
|
|
2559
|
+
throw new errors.BadSymbol(this.id + ' setLeverage() supports future and swap contracts only');
|
|
2560
|
+
}
|
|
2561
|
+
const request = {
|
|
2562
|
+
'symbol': market['id'],
|
|
2563
|
+
'leverage': leverage,
|
|
2564
|
+
};
|
|
2565
|
+
return await this.privatePostPositionLeverage(this.extend(request, params));
|
|
2566
|
+
}
|
|
2567
|
+
async setMarginMode(marginMode, symbol = undefined, params = {}) {
|
|
2568
|
+
/**
|
|
2569
|
+
* @method
|
|
2570
|
+
* @name bitmex#setMarginMode
|
|
2571
|
+
* @description set margin mode to 'cross' or 'isolated'
|
|
2572
|
+
* @param {string} marginMode 'cross' or 'isolated'
|
|
2573
|
+
* @param {string} symbol unified market symbol
|
|
2574
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2575
|
+
* @returns {object} response from the exchange
|
|
2576
|
+
*/
|
|
2577
|
+
if (symbol === undefined) {
|
|
2578
|
+
throw new errors.ArgumentsRequired(this.id + ' setMarginMode() requires a symbol argument');
|
|
2579
|
+
}
|
|
2580
|
+
marginMode = marginMode.toLowerCase();
|
|
2581
|
+
if (marginMode !== 'isolated' && marginMode !== 'cross') {
|
|
2582
|
+
throw new errors.BadRequest(this.id + ' setMarginMode() marginMode argument should be isolated or cross');
|
|
2583
|
+
}
|
|
2584
|
+
await this.loadMarkets();
|
|
2585
|
+
const market = this.market(symbol);
|
|
2586
|
+
if ((market['type'] !== 'swap') && (market['type'] !== 'future')) {
|
|
2587
|
+
throw new errors.BadSymbol(this.id + ' setMarginMode() supports swap and future contracts only');
|
|
2588
|
+
}
|
|
2589
|
+
const enabled = (marginMode === 'cross') ? false : true;
|
|
2590
|
+
const request = {
|
|
2591
|
+
'symbol': market['id'],
|
|
2592
|
+
'enabled': enabled,
|
|
2593
|
+
};
|
|
2594
|
+
return await this.privatePostPositionIsolate(this.extend(request, params));
|
|
2595
|
+
}
|
|
2596
|
+
async fetchDepositAddress(code, params = {}) {
|
|
2597
|
+
/**
|
|
2598
|
+
* @method
|
|
2599
|
+
* @name bitmex#fetchDepositAddress
|
|
2600
|
+
* @description fetch the deposit address for a currency associated with this account
|
|
2601
|
+
* @see https://www.bitmex.com/api/explorer/#!/User/User_getDepositAddress
|
|
2602
|
+
* @param {string} code unified currency code
|
|
2603
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2604
|
+
* @param {string} [params.network] deposit chain, can view all chains via this.publicGetWalletAssets, default is eth, unless the currency has a default chain within this.options['networks']
|
|
2605
|
+
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
2606
|
+
*/
|
|
2607
|
+
await this.loadMarkets();
|
|
2608
|
+
let networkCode = undefined;
|
|
2609
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
2610
|
+
if (networkCode === undefined) {
|
|
2611
|
+
throw new errors.ArgumentsRequired(this.id + ' fetchDepositAddress requires params["network"]');
|
|
2612
|
+
}
|
|
2613
|
+
const currency = this.currency(code);
|
|
2614
|
+
let currencyId = currency['id'];
|
|
2615
|
+
const idLength = currencyId.length;
|
|
2616
|
+
currencyId = currencyId.slice(0, idLength - 1) + currencyId.slice(idLength - 1, idLength).toLowerCase(); // make the last letter lowercase
|
|
2617
|
+
params = this.omit(params, 'network');
|
|
2618
|
+
const request = {
|
|
2619
|
+
'currency': currencyId,
|
|
2620
|
+
'network': this.networkCodeToId(networkCode, currency['code']),
|
|
2621
|
+
};
|
|
2622
|
+
const response = await this.privateGetUserDepositAddress(this.extend(request, params));
|
|
2623
|
+
//
|
|
2624
|
+
// '"bc1qmex3puyrzn2gduqcnlu70c2uscpyaa9nm2l2j9le2lt2wkgmw33sy7ndjg"'
|
|
2625
|
+
//
|
|
2626
|
+
return {
|
|
2627
|
+
'currency': code,
|
|
2628
|
+
'address': response.replace('"', '').replace('"', ''),
|
|
2629
|
+
'tag': undefined,
|
|
2630
|
+
'network': networkCode,
|
|
2631
|
+
'info': response,
|
|
2632
|
+
};
|
|
2633
|
+
}
|
|
2634
|
+
parseDepositWithdrawFee(fee, currency = undefined) {
|
|
2635
|
+
//
|
|
2636
|
+
// {
|
|
2637
|
+
// "asset": "XBT",
|
|
2638
|
+
// "currency": "XBt",
|
|
2639
|
+
// "majorCurrency": "XBT",
|
|
2640
|
+
// "name": "Bitcoin",
|
|
2641
|
+
// "currencyType": "Crypto",
|
|
2642
|
+
// "scale": "8",
|
|
2643
|
+
// "enabled": true,
|
|
2644
|
+
// "isMarginCurrency": true,
|
|
2645
|
+
// "minDepositAmount": "10000",
|
|
2646
|
+
// "minWithdrawalAmount": "1000",
|
|
2647
|
+
// "maxWithdrawalAmount": "100000000000000",
|
|
2648
|
+
// "networks": [
|
|
2649
|
+
// {
|
|
2650
|
+
// "asset": "btc",
|
|
2651
|
+
// "tokenAddress": '',
|
|
2652
|
+
// "depositEnabled": true,
|
|
2653
|
+
// "withdrawalEnabled": true,
|
|
2654
|
+
// "withdrawalFee": "20000",
|
|
2655
|
+
// "minFee": "20000",
|
|
2656
|
+
// "maxFee": "10000000"
|
|
2657
|
+
// }
|
|
2658
|
+
// ]
|
|
2659
|
+
// }
|
|
2660
|
+
//
|
|
2661
|
+
const networks = this.safeValue(fee, 'networks', []);
|
|
2662
|
+
const networksLength = networks.length;
|
|
2663
|
+
const result = {
|
|
2664
|
+
'info': fee,
|
|
2665
|
+
'withdraw': {
|
|
2666
|
+
'fee': undefined,
|
|
2667
|
+
'percentage': undefined,
|
|
2668
|
+
},
|
|
2669
|
+
'deposit': {
|
|
2670
|
+
'fee': undefined,
|
|
2671
|
+
'percentage': undefined,
|
|
2672
|
+
},
|
|
2673
|
+
'networks': {},
|
|
2674
|
+
};
|
|
2675
|
+
if (networksLength !== 0) {
|
|
2676
|
+
const scale = this.safeString(fee, 'scale');
|
|
2677
|
+
const precision = this.parsePrecision(scale);
|
|
2678
|
+
for (let i = 0; i < networksLength; i++) {
|
|
2679
|
+
const network = networks[i];
|
|
2680
|
+
const networkId = this.safeString(network, 'asset');
|
|
2681
|
+
const currencyCode = this.safeString(currency, 'code');
|
|
2682
|
+
const networkCode = this.networkIdToCode(networkId, currencyCode);
|
|
2683
|
+
const withdrawalFeeId = this.safeString(network, 'withdrawalFee');
|
|
2684
|
+
const withdrawalFee = this.parseNumber(Precise["default"].stringMul(withdrawalFeeId, precision));
|
|
2685
|
+
result['networks'][networkCode] = {
|
|
2686
|
+
'deposit': { 'fee': undefined, 'percentage': undefined },
|
|
2687
|
+
'withdraw': { 'fee': withdrawalFee, 'percentage': false },
|
|
2688
|
+
};
|
|
2689
|
+
if (networksLength === 1) {
|
|
2690
|
+
result['withdraw']['fee'] = withdrawalFee;
|
|
2691
|
+
result['withdraw']['percentage'] = false;
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
return result;
|
|
2696
|
+
}
|
|
2697
|
+
async fetchDepositWithdrawFees(codes = undefined, params = {}) {
|
|
2698
|
+
/**
|
|
2699
|
+
* @method
|
|
2700
|
+
* @name bitmex#fetchDepositWithdrawFees
|
|
2701
|
+
* @description fetch deposit and withdraw fees
|
|
2702
|
+
* @see https://www.bitmex.com/api/explorer/#!/Wallet/Wallet_getAssetsConfig
|
|
2703
|
+
* @param {string[]|undefined} codes list of unified currency codes
|
|
2704
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2705
|
+
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
2706
|
+
*/
|
|
2707
|
+
await this.loadMarkets();
|
|
2708
|
+
const assets = await this.publicGetWalletAssets(params);
|
|
2709
|
+
//
|
|
2710
|
+
// [
|
|
2711
|
+
// {
|
|
2712
|
+
// "asset": "XBT",
|
|
2713
|
+
// "currency": "XBt",
|
|
2714
|
+
// "majorCurrency": "XBT",
|
|
2715
|
+
// "name": "Bitcoin",
|
|
2716
|
+
// "currencyType": "Crypto",
|
|
2717
|
+
// "scale": "8",
|
|
2718
|
+
// "enabled": true,
|
|
2719
|
+
// "isMarginCurrency": true,
|
|
2720
|
+
// "minDepositAmount": "10000",
|
|
2721
|
+
// "minWithdrawalAmount": "1000",
|
|
2722
|
+
// "maxWithdrawalAmount": "100000000000000",
|
|
2723
|
+
// "networks": [
|
|
2724
|
+
// {
|
|
2725
|
+
// "asset": "btc",
|
|
2726
|
+
// "tokenAddress": '',
|
|
2727
|
+
// "depositEnabled": true,
|
|
2728
|
+
// "withdrawalEnabled": true,
|
|
2729
|
+
// "withdrawalFee": "20000",
|
|
2730
|
+
// "minFee": "20000",
|
|
2731
|
+
// "maxFee": "10000000"
|
|
2732
|
+
// }
|
|
2733
|
+
// ]
|
|
2734
|
+
// },
|
|
2735
|
+
// ...
|
|
2736
|
+
// ]
|
|
2737
|
+
//
|
|
2738
|
+
return this.parseDepositWithdrawFees(assets, codes, 'asset');
|
|
2739
|
+
}
|
|
2740
|
+
calculateRateLimiterCost(api, method, path, params, config = {}) {
|
|
2741
|
+
const isAuthenticated = this.checkRequiredCredentials(false);
|
|
2742
|
+
const cost = this.safeValue(config, 'cost', 1);
|
|
2743
|
+
if (cost !== 1) { // trading endpoints
|
|
2744
|
+
if (isAuthenticated) {
|
|
2745
|
+
return cost;
|
|
2746
|
+
}
|
|
2747
|
+
else {
|
|
2748
|
+
return 20;
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
return cost;
|
|
2752
|
+
}
|
|
2753
|
+
async fetchLiquidations(symbol, since = undefined, limit = undefined, params = {}) {
|
|
2754
|
+
/**
|
|
2755
|
+
* @method
|
|
2756
|
+
* @name bitmex#fetchLiquidations
|
|
2757
|
+
* @description retrieves the public liquidations of a trading pair
|
|
2758
|
+
* @see https://www.bitmex.com/api/explorer/#!/Liquidation/Liquidation_get
|
|
2759
|
+
* @param {string} symbol unified CCXT market symbol
|
|
2760
|
+
* @param {int} [since] the earliest time in ms to fetch liquidations for
|
|
2761
|
+
* @param {int} [limit] the maximum number of liquidation structures to retrieve
|
|
2762
|
+
* @param {object} [params] exchange specific parameters for the bitmex api endpoint
|
|
2763
|
+
* @param {int} [params.until] timestamp in ms of the latest liquidation
|
|
2764
|
+
* @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)
|
|
2765
|
+
* @returns {object} an array of [liquidation structures]{@link https://docs.ccxt.com/#/?id=liquidation-structure}
|
|
2766
|
+
*/
|
|
2767
|
+
await this.loadMarkets();
|
|
2768
|
+
let paginate = false;
|
|
2769
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchLiquidations', 'paginate');
|
|
2770
|
+
if (paginate) {
|
|
2771
|
+
return await this.fetchPaginatedCallDynamic('fetchLiquidations', symbol, since, limit, params);
|
|
2772
|
+
}
|
|
2773
|
+
const market = this.market(symbol);
|
|
2774
|
+
let request = {
|
|
2775
|
+
'symbol': market['id'],
|
|
2776
|
+
};
|
|
2777
|
+
if (since !== undefined) {
|
|
2778
|
+
request['startTime'] = since;
|
|
2779
|
+
}
|
|
2780
|
+
if (limit !== undefined) {
|
|
2781
|
+
request['count'] = limit;
|
|
2782
|
+
}
|
|
2783
|
+
[request, params] = this.handleUntilOption('endTime', request, params);
|
|
2784
|
+
const response = await this.publicGetLiquidation(this.extend(request, params));
|
|
2785
|
+
//
|
|
2786
|
+
// [
|
|
2787
|
+
// {
|
|
2788
|
+
// "orderID": "string",
|
|
2789
|
+
// "symbol": "string",
|
|
2790
|
+
// "side": "string",
|
|
2791
|
+
// "price": 0,
|
|
2792
|
+
// "leavesQty": 0
|
|
2793
|
+
// }
|
|
2794
|
+
// ]
|
|
2795
|
+
//
|
|
2796
|
+
return this.parseLiquidations(response, market, since, limit);
|
|
2797
|
+
}
|
|
2798
|
+
parseLiquidation(liquidation, market = undefined) {
|
|
2799
|
+
//
|
|
2800
|
+
// {
|
|
2801
|
+
// "orderID": "string",
|
|
2802
|
+
// "symbol": "string",
|
|
2803
|
+
// "side": "string",
|
|
2804
|
+
// "price": 0,
|
|
2805
|
+
// "leavesQty": 0
|
|
2806
|
+
// }
|
|
2807
|
+
//
|
|
2808
|
+
const marketId = this.safeString(liquidation, 'symbol');
|
|
2809
|
+
return this.safeLiquidation({
|
|
2810
|
+
'info': liquidation,
|
|
2811
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
2812
|
+
'contracts': undefined,
|
|
2813
|
+
'contractSize': this.safeNumber(market, 'contractSize'),
|
|
2814
|
+
'price': this.safeNumber(liquidation, 'price'),
|
|
2815
|
+
'baseValue': undefined,
|
|
2816
|
+
'quoteValue': undefined,
|
|
2817
|
+
'timestamp': undefined,
|
|
2818
|
+
'datetime': undefined,
|
|
2819
|
+
});
|
|
2820
|
+
}
|
|
2821
|
+
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
2822
|
+
if (response === undefined) {
|
|
2823
|
+
return undefined;
|
|
2824
|
+
}
|
|
2825
|
+
if (code === 429) {
|
|
2826
|
+
throw new errors.DDoSProtection(this.id + ' ' + body);
|
|
2827
|
+
}
|
|
2828
|
+
if (code >= 400) {
|
|
2829
|
+
const error = this.safeValue(response, 'error', {});
|
|
2830
|
+
const message = this.safeString(error, 'message');
|
|
2831
|
+
const feedback = this.id + ' ' + body;
|
|
2832
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
2833
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
2834
|
+
if (code === 400) {
|
|
2835
|
+
throw new errors.BadRequest(feedback);
|
|
2836
|
+
}
|
|
2837
|
+
throw new errors.ExchangeError(feedback); // unknown message
|
|
2838
|
+
}
|
|
2839
|
+
return undefined;
|
|
2840
|
+
}
|
|
2841
|
+
nonce() {
|
|
2842
|
+
return this.milliseconds();
|
|
2843
|
+
}
|
|
2844
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
2845
|
+
let query = '/api/' + this.version + '/' + path;
|
|
2846
|
+
if (method === 'GET') {
|
|
2847
|
+
if (Object.keys(params).length) {
|
|
2848
|
+
query += '?' + this.urlencode(params);
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
else {
|
|
2852
|
+
const format = this.safeString(params, '_format');
|
|
2853
|
+
if (format !== undefined) {
|
|
2854
|
+
query += '?' + this.urlencode({ '_format': format });
|
|
2855
|
+
params = this.omit(params, '_format');
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
const url = this.urls['api'][api] + query;
|
|
2859
|
+
const isAuthenticated = this.checkRequiredCredentials(false);
|
|
2860
|
+
if (api === 'private' || (api === 'public' && isAuthenticated)) {
|
|
2861
|
+
this.checkRequiredCredentials();
|
|
2862
|
+
let auth = method + query;
|
|
2863
|
+
let expires = this.safeInteger(this.options, 'api-expires');
|
|
2864
|
+
headers = {
|
|
2865
|
+
'Content-Type': 'application/json',
|
|
2866
|
+
'api-key': this.apiKey,
|
|
2867
|
+
};
|
|
2868
|
+
expires = this.sum(this.seconds(), expires);
|
|
2869
|
+
const stringExpires = expires.toString();
|
|
2870
|
+
auth += stringExpires;
|
|
2871
|
+
headers['api-expires'] = stringExpires;
|
|
2872
|
+
if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
|
|
2873
|
+
if (Object.keys(params).length) {
|
|
2874
|
+
body = this.json(params);
|
|
2875
|
+
auth += body;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
headers['api-signature'] = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256);
|
|
2879
|
+
}
|
|
2880
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2883
|
+
|
|
2884
|
+
module.exports = bitmex;
|