ccxt 4.2.10 → 4.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/README.md +5 -5
  2. package/build.sh +4 -4
  3. package/dist/ccxt.browser.js +695 -282
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/_virtual/agent.js +7 -0
  6. package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
  7. package/dist/cjs/_virtual/promisify.js +7 -0
  8. package/dist/cjs/ccxt.js +1 -1
  9. package/dist/cjs/js/ccxt.js +474 -0
  10. package/dist/cjs/js/src/abstract/ace.js +9 -0
  11. package/dist/cjs/js/src/abstract/alpaca.js +9 -0
  12. package/dist/cjs/js/src/abstract/ascendex.js +9 -0
  13. package/dist/cjs/js/src/abstract/bigone.js +9 -0
  14. package/dist/cjs/js/src/abstract/binance.js +9 -0
  15. package/dist/cjs/js/src/abstract/bingx.js +9 -0
  16. package/dist/cjs/js/src/abstract/bit2c.js +9 -0
  17. package/dist/cjs/js/src/abstract/bitbank.js +9 -0
  18. package/dist/cjs/js/src/abstract/bitbns.js +9 -0
  19. package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
  20. package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
  21. package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
  22. package/dist/cjs/js/src/abstract/bitforex.js +9 -0
  23. package/dist/cjs/js/src/abstract/bitget.js +9 -0
  24. package/dist/cjs/js/src/abstract/bithumb.js +9 -0
  25. package/dist/cjs/js/src/abstract/bitmart.js +9 -0
  26. package/dist/cjs/js/src/abstract/bitmex.js +9 -0
  27. package/dist/cjs/js/src/abstract/bitopro.js +9 -0
  28. package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
  29. package/dist/cjs/js/src/abstract/bitrue.js +9 -0
  30. package/dist/cjs/js/src/abstract/bitso.js +9 -0
  31. package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
  32. package/dist/cjs/js/src/abstract/bitteam.js +9 -0
  33. package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
  34. package/dist/cjs/js/src/abstract/bl3p.js +9 -0
  35. package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
  36. package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
  37. package/dist/cjs/js/src/abstract/btcbox.js +9 -0
  38. package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
  39. package/dist/cjs/js/src/abstract/btcturk.js +9 -0
  40. package/dist/cjs/js/src/abstract/bybit.js +9 -0
  41. package/dist/cjs/js/src/abstract/cex.js +9 -0
  42. package/dist/cjs/js/src/abstract/coinbase.js +9 -0
  43. package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
  44. package/dist/cjs/js/src/abstract/coincheck.js +9 -0
  45. package/dist/cjs/js/src/abstract/coinex.js +9 -0
  46. package/dist/cjs/js/src/abstract/coinlist.js +9 -0
  47. package/dist/cjs/js/src/abstract/coinmate.js +9 -0
  48. package/dist/cjs/js/src/abstract/coinone.js +9 -0
  49. package/dist/cjs/js/src/abstract/coinsph.js +9 -0
  50. package/dist/cjs/js/src/abstract/coinspot.js +9 -0
  51. package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
  52. package/dist/cjs/js/src/abstract/currencycom.js +9 -0
  53. package/dist/cjs/js/src/abstract/delta.js +9 -0
  54. package/dist/cjs/js/src/abstract/deribit.js +9 -0
  55. package/dist/cjs/js/src/abstract/digifinex.js +9 -0
  56. package/dist/cjs/js/src/abstract/exmo.js +9 -0
  57. package/dist/cjs/js/src/abstract/gate.js +9 -0
  58. package/dist/cjs/js/src/abstract/gemini.js +9 -0
  59. package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
  60. package/dist/cjs/js/src/abstract/hollaex.js +9 -0
  61. package/dist/cjs/js/src/abstract/htx.js +9 -0
  62. package/dist/cjs/js/src/abstract/huobijp.js +9 -0
  63. package/dist/cjs/js/src/abstract/idex.js +9 -0
  64. package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
  65. package/dist/cjs/js/src/abstract/indodax.js +9 -0
  66. package/dist/cjs/js/src/abstract/kraken.js +9 -0
  67. package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
  68. package/dist/cjs/js/src/abstract/kucoin.js +9 -0
  69. package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
  70. package/dist/cjs/js/src/abstract/kuna.js +9 -0
  71. package/dist/cjs/js/src/abstract/latoken.js +9 -0
  72. package/dist/cjs/js/src/abstract/lbank.js +9 -0
  73. package/dist/cjs/js/src/abstract/luno.js +9 -0
  74. package/dist/cjs/js/src/abstract/lykke.js +9 -0
  75. package/dist/cjs/js/src/abstract/mercado.js +9 -0
  76. package/dist/cjs/js/src/abstract/mexc.js +9 -0
  77. package/dist/cjs/js/src/abstract/ndax.js +9 -0
  78. package/dist/cjs/js/src/abstract/novadax.js +9 -0
  79. package/dist/cjs/js/src/abstract/oceanex.js +9 -0
  80. package/dist/cjs/js/src/abstract/okcoin.js +9 -0
  81. package/dist/cjs/js/src/abstract/okx.js +9 -0
  82. package/dist/cjs/js/src/abstract/p2b.js +9 -0
  83. package/dist/cjs/js/src/abstract/paymium.js +9 -0
  84. package/dist/cjs/js/src/abstract/phemex.js +9 -0
  85. package/dist/cjs/js/src/abstract/poloniex.js +9 -0
  86. package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
  87. package/dist/cjs/js/src/abstract/probit.js +9 -0
  88. package/dist/cjs/js/src/abstract/timex.js +9 -0
  89. package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
  90. package/dist/cjs/js/src/abstract/upbit.js +9 -0
  91. package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
  92. package/dist/cjs/js/src/abstract/wazirx.js +9 -0
  93. package/dist/cjs/js/src/abstract/whitebit.js +9 -0
  94. package/dist/cjs/js/src/abstract/woo.js +9 -0
  95. package/dist/cjs/js/src/abstract/yobit.js +9 -0
  96. package/dist/cjs/js/src/abstract/zaif.js +9 -0
  97. package/dist/cjs/js/src/abstract/zonda.js +9 -0
  98. package/dist/cjs/js/src/ace.js +1058 -0
  99. package/dist/cjs/js/src/alpaca.js +1125 -0
  100. package/dist/cjs/js/src/ascendex.js +3360 -0
  101. package/dist/cjs/js/src/base/Exchange.js +5110 -0
  102. package/dist/cjs/js/src/base/Precise.js +263 -0
  103. package/dist/cjs/js/src/base/errors.js +299 -0
  104. package/dist/cjs/js/src/base/functions/crypto.js +78 -0
  105. package/dist/cjs/js/src/base/functions/encode.js +44 -0
  106. package/dist/cjs/js/src/base/functions/generic.js +193 -0
  107. package/dist/cjs/js/src/base/functions/misc.js +96 -0
  108. package/dist/cjs/js/src/base/functions/number.js +297 -0
  109. package/dist/cjs/js/src/base/functions/platform.js +28 -0
  110. package/dist/cjs/js/src/base/functions/rsa.js +34 -0
  111. package/dist/cjs/js/src/base/functions/string.js +48 -0
  112. package/dist/cjs/js/src/base/functions/throttle.js +66 -0
  113. package/dist/cjs/js/src/base/functions/time.js +187 -0
  114. package/dist/cjs/js/src/base/functions/totp.js +24 -0
  115. package/dist/cjs/js/src/base/functions/type.js +162 -0
  116. package/dist/cjs/js/src/base/functions.js +157 -0
  117. package/dist/cjs/js/src/base/ws/Cache.js +254 -0
  118. package/dist/cjs/js/src/base/ws/Client.js +299 -0
  119. package/dist/cjs/js/src/base/ws/Future.js +34 -0
  120. package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
  121. package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
  122. package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
  123. package/dist/cjs/js/src/bequant.js +33 -0
  124. package/dist/cjs/js/src/bigone.js +2142 -0
  125. package/dist/cjs/js/src/binance.js +9729 -0
  126. package/dist/cjs/js/src/binancecoinm.js +45 -0
  127. package/dist/cjs/js/src/binanceus.js +84 -0
  128. package/dist/cjs/js/src/binanceusdm.js +58 -0
  129. package/dist/cjs/js/src/bingx.js +3737 -0
  130. package/dist/cjs/js/src/bit2c.js +916 -0
  131. package/dist/cjs/js/src/bitbank.js +1000 -0
  132. package/dist/cjs/js/src/bitbay.js +17 -0
  133. package/dist/cjs/js/src/bitbns.js +1220 -0
  134. package/dist/cjs/js/src/bitcoincom.js +17 -0
  135. package/dist/cjs/js/src/bitfinex.js +1670 -0
  136. package/dist/cjs/js/src/bitfinex2.js +2990 -0
  137. package/dist/cjs/js/src/bitflyer.js +1045 -0
  138. package/dist/cjs/js/src/bitforex.js +852 -0
  139. package/dist/cjs/js/src/bitget.js +8284 -0
  140. package/dist/cjs/js/src/bithumb.js +1090 -0
  141. package/dist/cjs/js/src/bitmart.js +4454 -0
  142. package/dist/cjs/js/src/bitmex.js +2884 -0
  143. package/dist/cjs/js/src/bitopro.js +1724 -0
  144. package/dist/cjs/js/src/bitpanda.js +2002 -0
  145. package/dist/cjs/js/src/bitrue.js +3253 -0
  146. package/dist/cjs/js/src/bitso.js +1753 -0
  147. package/dist/cjs/js/src/bitstamp.js +2188 -0
  148. package/dist/cjs/js/src/bitteam.js +2309 -0
  149. package/dist/cjs/js/src/bitvavo.js +1968 -0
  150. package/dist/cjs/js/src/bl3p.js +447 -0
  151. package/dist/cjs/js/src/blockchaincom.js +1160 -0
  152. package/dist/cjs/js/src/btcalpha.js +929 -0
  153. package/dist/cjs/js/src/btcbox.js +565 -0
  154. package/dist/cjs/js/src/btcmarkets.js +1237 -0
  155. package/dist/cjs/js/src/btcturk.js +929 -0
  156. package/dist/cjs/js/src/bybit.js +7646 -0
  157. package/dist/cjs/js/src/cex.js +1693 -0
  158. package/dist/cjs/js/src/coinbase.js +3274 -0
  159. package/dist/cjs/js/src/coinbasepro.js +1866 -0
  160. package/dist/cjs/js/src/coincheck.js +843 -0
  161. package/dist/cjs/js/src/coinex.js +5414 -0
  162. package/dist/cjs/js/src/coinlist.js +2329 -0
  163. package/dist/cjs/js/src/coinmate.js +989 -0
  164. package/dist/cjs/js/src/coinone.js +1185 -0
  165. package/dist/cjs/js/src/coinsph.js +1933 -0
  166. package/dist/cjs/js/src/coinspot.js +548 -0
  167. package/dist/cjs/js/src/cryptocom.js +3007 -0
  168. package/dist/cjs/js/src/currencycom.js +2015 -0
  169. package/dist/cjs/js/src/delta.js +3256 -0
  170. package/dist/cjs/js/src/deribit.js +3306 -0
  171. package/dist/cjs/js/src/digifinex.js +4307 -0
  172. package/dist/cjs/js/src/exmo.js +2645 -0
  173. package/dist/cjs/js/src/fmfwio.js +34 -0
  174. package/dist/cjs/js/src/gate.js +7054 -0
  175. package/dist/cjs/js/src/gateio.js +16 -0
  176. package/dist/cjs/js/src/gemini.js +1801 -0
  177. package/dist/cjs/js/src/hitbtc.js +3660 -0
  178. package/dist/cjs/js/src/hitbtc3.js +19 -0
  179. package/dist/cjs/js/src/hollaex.js +1882 -0
  180. package/dist/cjs/js/src/htx.js +9024 -0
  181. package/dist/cjs/js/src/huobi.js +16 -0
  182. package/dist/cjs/js/src/huobijp.js +1918 -0
  183. package/dist/cjs/js/src/idex.js +1770 -0
  184. package/dist/cjs/js/src/independentreserve.js +759 -0
  185. package/dist/cjs/js/src/indodax.js +1069 -0
  186. package/dist/cjs/js/src/kraken.js +2861 -0
  187. package/dist/cjs/js/src/krakenfutures.js +2407 -0
  188. package/dist/cjs/js/src/kucoin.js +4489 -0
  189. package/dist/cjs/js/src/kucoinfutures.js +2475 -0
  190. package/dist/cjs/js/src/kuna.js +1949 -0
  191. package/dist/cjs/js/src/latoken.js +1729 -0
  192. package/dist/cjs/js/src/lbank.js +2825 -0
  193. package/dist/cjs/js/src/luno.js +1044 -0
  194. package/dist/cjs/js/src/lykke.js +1303 -0
  195. package/dist/cjs/js/src/mercado.js +897 -0
  196. package/dist/cjs/js/src/mexc.js +5407 -0
  197. package/dist/cjs/js/src/ndax.js +2450 -0
  198. package/dist/cjs/js/src/novadax.js +1556 -0
  199. package/dist/cjs/js/src/oceanex.js +964 -0
  200. package/dist/cjs/js/src/okcoin.js +3115 -0
  201. package/dist/cjs/js/src/okx.js +7329 -0
  202. package/dist/cjs/js/src/p2b.js +1243 -0
  203. package/dist/cjs/js/src/paymium.js +597 -0
  204. package/dist/cjs/js/src/phemex.js +4715 -0
  205. package/dist/cjs/js/src/poloniex.js +2356 -0
  206. package/dist/cjs/js/src/poloniexfutures.js +1794 -0
  207. package/dist/cjs/js/src/pro/alpaca.js +714 -0
  208. package/dist/cjs/js/src/pro/ascendex.js +957 -0
  209. package/dist/cjs/js/src/pro/bequant.js +33 -0
  210. package/dist/cjs/js/src/pro/binance.js +2796 -0
  211. package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
  212. package/dist/cjs/js/src/pro/binanceus.js +51 -0
  213. package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
  214. package/dist/cjs/js/src/pro/bingx.js +944 -0
  215. package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
  216. package/dist/cjs/js/src/pro/bitfinex.js +672 -0
  217. package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
  218. package/dist/cjs/js/src/pro/bitget.js +1733 -0
  219. package/dist/cjs/js/src/pro/bitmart.js +1486 -0
  220. package/dist/cjs/js/src/pro/bitmex.js +1576 -0
  221. package/dist/cjs/js/src/pro/bitopro.js +327 -0
  222. package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
  223. package/dist/cjs/js/src/pro/bitrue.js +462 -0
  224. package/dist/cjs/js/src/pro/bitstamp.js +547 -0
  225. package/dist/cjs/js/src/pro/bitvavo.js +704 -0
  226. package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
  227. package/dist/cjs/js/src/pro/bybit.js +1843 -0
  228. package/dist/cjs/js/src/pro/cex.js +1510 -0
  229. package/dist/cjs/js/src/pro/coinbase.js +561 -0
  230. package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
  231. package/dist/cjs/js/src/pro/coinex.js +1095 -0
  232. package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
  233. package/dist/cjs/js/src/pro/currencycom.js +563 -0
  234. package/dist/cjs/js/src/pro/deribit.js +825 -0
  235. package/dist/cjs/js/src/pro/exmo.js +658 -0
  236. package/dist/cjs/js/src/pro/gate.js +1316 -0
  237. package/dist/cjs/js/src/pro/gateio.js +16 -0
  238. package/dist/cjs/js/src/pro/gemini.js +649 -0
  239. package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
  240. package/dist/cjs/js/src/pro/hollaex.js +597 -0
  241. package/dist/cjs/js/src/pro/htx.js +2383 -0
  242. package/dist/cjs/js/src/pro/huobi.js +16 -0
  243. package/dist/cjs/js/src/pro/huobijp.js +606 -0
  244. package/dist/cjs/js/src/pro/idex.js +714 -0
  245. package/dist/cjs/js/src/pro/independentreserve.js +280 -0
  246. package/dist/cjs/js/src/pro/kraken.js +1364 -0
  247. package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
  248. package/dist/cjs/js/src/pro/kucoin.js +1052 -0
  249. package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
  250. package/dist/cjs/js/src/pro/luno.js +322 -0
  251. package/dist/cjs/js/src/pro/mexc.js +1170 -0
  252. package/dist/cjs/js/src/pro/ndax.js +545 -0
  253. package/dist/cjs/js/src/pro/okcoin.js +760 -0
  254. package/dist/cjs/js/src/pro/okx.js +1558 -0
  255. package/dist/cjs/js/src/pro/phemex.js +1511 -0
  256. package/dist/cjs/js/src/pro/poloniex.js +1253 -0
  257. package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
  258. package/dist/cjs/js/src/pro/probit.js +586 -0
  259. package/dist/cjs/js/src/pro/upbit.js +234 -0
  260. package/dist/cjs/js/src/pro/wazirx.js +776 -0
  261. package/dist/cjs/js/src/pro/whitebit.js +927 -0
  262. package/dist/cjs/js/src/pro/woo.js +769 -0
  263. package/dist/cjs/js/src/probit.js +1865 -0
  264. package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
  265. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
  266. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
  267. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
  268. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
  269. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
  270. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
  271. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
  272. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
  273. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
  274. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
  275. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
  276. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
  277. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
  278. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
  279. package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
  280. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
  281. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
  282. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
  283. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
  284. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
  285. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
  286. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
  287. package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
  288. package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
  289. package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
  290. package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
  291. package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
  292. package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
  293. package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
  294. package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
  295. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
  296. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
  297. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
  298. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
  299. package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
  300. package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
  301. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
  302. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
  303. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
  304. package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
  305. package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
  306. package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
  307. package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
  308. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
  309. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
  310. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
  311. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
  312. package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
  313. package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
  314. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
  315. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
  316. package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
  317. package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
  318. package/dist/cjs/js/src/timex.js +1562 -0
  319. package/dist/cjs/js/src/tokocrypto.js +2542 -0
  320. package/dist/cjs/js/src/upbit.js +1844 -0
  321. package/dist/cjs/js/src/wavesexchange.js +2607 -0
  322. package/dist/cjs/js/src/wazirx.js +953 -0
  323. package/dist/cjs/js/src/whitebit.js +2309 -0
  324. package/dist/cjs/js/src/woo.js +2715 -0
  325. package/dist/cjs/js/src/yobit.js +1314 -0
  326. package/dist/cjs/js/src/zaif.js +736 -0
  327. package/dist/cjs/js/src/zonda.js +1883 -0
  328. package/dist/cjs/src/base/Exchange.js +11 -0
  329. package/dist/cjs/src/bingx.js +0 -10
  330. package/dist/cjs/src/bitget.js +14 -5
  331. package/dist/cjs/src/bybit.js +1 -1
  332. package/dist/cjs/src/kucoin.js +29 -5
  333. package/js/ccxt.d.ts +1 -1
  334. package/js/ccxt.js +1 -1
  335. package/js/src/abstract/bigone.d.ts +18 -0
  336. package/js/src/abstract/binance.d.ts +2 -0
  337. package/js/src/abstract/binancecoinm.d.ts +2 -0
  338. package/js/src/abstract/binanceus.d.ts +2 -0
  339. package/js/src/abstract/binanceusdm.d.ts +2 -0
  340. package/js/src/abstract/bybit.d.ts +1 -0
  341. package/js/src/abstract/gate.d.ts +11 -0
  342. package/js/src/abstract/gateio.d.ts +11 -0
  343. package/js/src/alpaca.js +18 -18
  344. package/js/src/base/Exchange.d.ts +6 -1
  345. package/js/src/base/Exchange.js +112 -12
  346. package/js/src/bigone.d.ts +1 -2
  347. package/js/src/bigone.js +340 -145
  348. package/js/src/binance.js +15 -8
  349. package/js/src/bingx.d.ts +0 -1
  350. package/js/src/bingx.js +9 -12
  351. package/js/src/bitfinex.d.ts +2 -2
  352. package/js/src/bitfinex.js +2 -3
  353. package/js/src/bitget.js +35 -13
  354. package/js/src/bitmart.d.ts +2 -2
  355. package/js/src/bitmart.js +3 -3
  356. package/js/src/bitmex.js +1 -0
  357. package/js/src/bybit.js +3 -1
  358. package/js/src/coinlist.js +2 -3
  359. package/js/src/coinsph.js +2 -3
  360. package/js/src/deribit.js +1 -0
  361. package/js/src/gate.d.ts +4 -4
  362. package/js/src/gate.js +22 -3
  363. package/js/src/hitbtc.d.ts +4 -4
  364. package/js/src/hitbtc.js +2 -3
  365. package/js/src/htx.js +4 -7
  366. package/js/src/huobijp.js +2 -3
  367. package/js/src/kraken.js +1 -0
  368. package/js/src/kucoin.js +29 -5
  369. package/js/src/mexc.js +2 -1
  370. package/js/src/okx.js +13 -3
  371. package/js/src/pro/binance.d.ts +2 -23
  372. package/js/src/pro/binance.js +58 -22
  373. package/js/src/pro/coinbase.d.ts +2 -2
  374. package/js/src/pro/coinbase.js +4 -1
  375. package/js/src/pro/coinbasepro.d.ts +2 -2
  376. package/js/src/pro/hitbtc.d.ts +2 -2
  377. package/js/src/pro/poloniex.d.ts +2 -2
  378. package/js/src/upbit.d.ts +3 -101
  379. package/js/src/upbit.js +12 -12
  380. package/js/src/woo.js +2 -0
  381. package/package.json +11 -11
  382. package/skip-tests.json +5 -0
  383. package/tests-manager.sh +2 -2
@@ -0,0 +1,3660 @@
1
+ 'use strict';
2
+
3
+ var hitbtc$1 = require('./abstract/hitbtc.js');
4
+ var number = require('./base/functions/number.js');
5
+ var Precise = require('./base/Precise.js');
6
+ var errors = require('./base/errors.js');
7
+ var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
8
+
9
+ /**
10
+ * @class hitbtc
11
+ * @augments Exchange
12
+ */
13
+ class hitbtc extends hitbtc$1 {
14
+ describe() {
15
+ return this.deepExtend(super.describe(), {
16
+ 'id': 'hitbtc',
17
+ 'name': 'HitBTC',
18
+ 'countries': ['HK'],
19
+ // 300 requests per second => 1000ms / 300 = 3.333 (Trading: placing, replacing, deleting)
20
+ // 30 requests per second => ( 1000ms / rateLimit ) / 30 = cost = 10 (Market Data and other Public Requests)
21
+ // 20 requests per second => ( 1000ms / rateLimit ) / 20 = cost = 15 (All Other)
22
+ 'rateLimit': 3.333,
23
+ 'version': '3',
24
+ 'has': {
25
+ 'CORS': false,
26
+ 'spot': true,
27
+ 'margin': true,
28
+ 'swap': true,
29
+ 'future': false,
30
+ 'option': undefined,
31
+ 'addMargin': true,
32
+ 'cancelAllOrders': true,
33
+ 'cancelOrder': true,
34
+ 'closePosition': false,
35
+ 'createDepositAddress': true,
36
+ 'createOrder': true,
37
+ 'createPostOnlyOrder': true,
38
+ 'createReduceOnlyOrder': true,
39
+ 'createStopLimitOrder': true,
40
+ 'createStopMarketOrder': true,
41
+ 'createStopOrder': true,
42
+ 'editOrder': true,
43
+ 'fetchAccounts': false,
44
+ 'fetchBalance': true,
45
+ 'fetchBorrowRateHistories': undefined,
46
+ 'fetchBorrowRateHistory': undefined,
47
+ 'fetchClosedOrders': true,
48
+ 'fetchCrossBorrowRate': false,
49
+ 'fetchCrossBorrowRates': false,
50
+ 'fetchCurrencies': true,
51
+ 'fetchDepositAddress': true,
52
+ 'fetchDeposits': true,
53
+ 'fetchDepositsWithdrawals': true,
54
+ 'fetchDepositWithdrawFee': 'emulated',
55
+ 'fetchDepositWithdrawFees': true,
56
+ 'fetchFundingHistory': undefined,
57
+ 'fetchFundingRate': true,
58
+ 'fetchFundingRateHistory': true,
59
+ 'fetchFundingRates': true,
60
+ 'fetchIndexOHLCV': true,
61
+ 'fetchIsolatedBorrowRate': false,
62
+ 'fetchIsolatedBorrowRates': false,
63
+ 'fetchLeverage': true,
64
+ 'fetchLeverageTiers': undefined,
65
+ 'fetchLiquidations': false,
66
+ 'fetchMarginMode': true,
67
+ 'fetchMarketLeverageTiers': false,
68
+ 'fetchMarkets': true,
69
+ 'fetchMarkOHLCV': true,
70
+ 'fetchMyLiquidations': false,
71
+ 'fetchMyTrades': true,
72
+ 'fetchOHLCV': true,
73
+ 'fetchOpenInterest': true,
74
+ 'fetchOpenInterestHistory': false,
75
+ 'fetchOpenOrder': true,
76
+ 'fetchOpenOrders': true,
77
+ 'fetchOrder': true,
78
+ 'fetchOrderBook': true,
79
+ 'fetchOrderBooks': true,
80
+ 'fetchOrders': false,
81
+ 'fetchOrderTrades': true,
82
+ 'fetchPosition': true,
83
+ 'fetchPositions': true,
84
+ 'fetchPremiumIndexOHLCV': true,
85
+ 'fetchTicker': true,
86
+ 'fetchTickers': true,
87
+ 'fetchTrades': true,
88
+ 'fetchTradingFee': true,
89
+ 'fetchTradingFees': true,
90
+ 'fetchTransactions': 'emulated',
91
+ 'fetchWithdrawals': true,
92
+ 'reduceMargin': true,
93
+ 'setLeverage': true,
94
+ 'setMargin': false,
95
+ 'setMarginMode': false,
96
+ 'setPositionMode': false,
97
+ 'transfer': true,
98
+ 'withdraw': true,
99
+ },
100
+ 'precisionMode': number.TICK_SIZE,
101
+ 'urls': {
102
+ 'logo': 'https://user-images.githubusercontent.com/1294454/27766555-8eaec20e-5edc-11e7-9c5b-6dc69fc42f5e.jpg',
103
+ 'test': {
104
+ 'public': 'https://api.demo.hitbtc.com/api/3',
105
+ 'private': 'https://api.demo.hitbtc.com/api/3',
106
+ },
107
+ 'api': {
108
+ 'public': 'https://api.hitbtc.com/api/3',
109
+ 'private': 'https://api.hitbtc.com/api/3',
110
+ },
111
+ 'www': 'https://hitbtc.com',
112
+ 'referral': 'https://hitbtc.com/?ref_id=5a5d39a65d466',
113
+ 'doc': [
114
+ 'https://api.hitbtc.com',
115
+ 'https://github.com/hitbtc-com/hitbtc-api/blob/master/APIv2.md',
116
+ ],
117
+ 'fees': [
118
+ 'https://hitbtc.com/fees-and-limits',
119
+ 'https://support.hitbtc.com/hc/en-us/articles/115005148605-Fees-and-limits',
120
+ ],
121
+ },
122
+ 'api': {
123
+ 'public': {
124
+ 'get': {
125
+ 'public/currency': 10,
126
+ 'public/currency/{currency}': 10,
127
+ 'public/symbol': 10,
128
+ 'public/symbol/{symbol}': 10,
129
+ 'public/ticker': 10,
130
+ 'public/ticker/{symbol}': 10,
131
+ 'public/price/rate': 10,
132
+ 'public/price/history': 10,
133
+ 'public/price/ticker': 10,
134
+ 'public/price/ticker/{symbol}': 10,
135
+ 'public/trades': 10,
136
+ 'public/trades/{symbol}': 10,
137
+ 'public/orderbook': 10,
138
+ 'public/orderbook/{symbol}': 10,
139
+ 'public/candles': 10,
140
+ 'public/candles/{symbol}': 10,
141
+ 'public/futures/info': 10,
142
+ 'public/futures/info/{symbol}': 10,
143
+ 'public/futures/history/funding': 10,
144
+ 'public/futures/history/funding/{symbol}': 10,
145
+ 'public/futures/candles/index_price': 10,
146
+ 'public/futures/candles/index_price/{symbol}': 10,
147
+ 'public/futures/candles/mark_price': 10,
148
+ 'public/futures/candles/mark_price/{symbol}': 10,
149
+ 'public/futures/candles/premium_index': 10,
150
+ 'public/futures/candles/premium_index/{symbol}': 10,
151
+ 'public/futures/candles/open_interest': 10,
152
+ 'public/futures/candles/open_interest/{symbol}': 10,
153
+ },
154
+ },
155
+ 'private': {
156
+ 'get': {
157
+ 'spot/balance': 15,
158
+ 'spot/balance/{currency}': 15,
159
+ 'spot/order': 1,
160
+ 'spot/order/{client_order_id}': 1,
161
+ 'spot/fee': 15,
162
+ 'spot/fee/{symbol}': 15,
163
+ 'spot/history/order': 15,
164
+ 'spot/history/trade': 15,
165
+ 'margin/account': 1,
166
+ 'margin/account/isolated/{symbol}': 1,
167
+ 'margin/account/cross/{currency}': 1,
168
+ 'margin/order': 1,
169
+ 'margin/order/{client_order_id}': 1,
170
+ 'margin/config': 15,
171
+ 'margin/history/order': 15,
172
+ 'margin/history/trade': 15,
173
+ 'margin/history/positions': 15,
174
+ 'margin/history/clearing': 15,
175
+ 'futures/balance': 15,
176
+ 'futures/balance/{currency}': 15,
177
+ 'futures/account': 1,
178
+ 'futures/account/isolated/{symbol}': 1,
179
+ 'futures/order': 1,
180
+ 'futures/order/{client_order_id}': 1,
181
+ 'futures/config': 15,
182
+ 'futures/fee': 15,
183
+ 'futures/fee/{symbol}': 15,
184
+ 'futures/history/order': 15,
185
+ 'futures/history/trade': 15,
186
+ 'futures/history/positions': 15,
187
+ 'futures/history/clearing': 15,
188
+ 'wallet/balance': 30,
189
+ 'wallet/balance/{currency}': 30,
190
+ 'wallet/crypto/address': 30,
191
+ 'wallet/crypto/address/recent-deposit': 30,
192
+ 'wallet/crypto/address/recent-withdraw': 30,
193
+ 'wallet/crypto/address/check-mine': 30,
194
+ 'wallet/transactions': 30,
195
+ 'wallet/transactions/{tx_id}': 30,
196
+ 'wallet/crypto/fee/estimate': 30,
197
+ 'wallet/airdrops': 30,
198
+ 'wallet/amount-locks': 30,
199
+ 'sub-account': 15,
200
+ 'sub-account/acl': 15,
201
+ 'sub-account/balance/{subAccID}': 15,
202
+ 'sub-account/crypto/address/{subAccID}/{currency}': 15,
203
+ },
204
+ 'post': {
205
+ 'spot/order': 1,
206
+ 'spot/order/list': 1,
207
+ 'margin/order': 1,
208
+ 'margin/order/list': 1,
209
+ 'futures/order': 1,
210
+ 'futures/order/list': 1,
211
+ 'wallet/crypto/address': 30,
212
+ 'wallet/crypto/withdraw': 30,
213
+ 'wallet/convert': 30,
214
+ 'wallet/transfer': 30,
215
+ 'wallet/internal/withdraw': 30,
216
+ 'wallet/crypto/check-offchain-available': 30,
217
+ 'wallet/crypto/fees/estimate': 30,
218
+ 'wallet/airdrops/{id}/claim': 30,
219
+ 'sub-account/freeze': 15,
220
+ 'sub-account/activate': 15,
221
+ 'sub-account/transfer': 15,
222
+ 'sub-account/acl': 15,
223
+ },
224
+ 'patch': {
225
+ 'spot/order/{client_order_id}': 1,
226
+ 'margin/order/{client_order_id}': 1,
227
+ 'futures/order/{client_order_id}': 1,
228
+ },
229
+ 'delete': {
230
+ 'spot/order': 1,
231
+ 'spot/order/{client_order_id}': 1,
232
+ 'margin/position': 1,
233
+ 'margin/position/isolated/{symbol}': 1,
234
+ 'margin/order': 1,
235
+ 'margin/order/{client_order_id}': 1,
236
+ 'futures/position': 1,
237
+ 'futures/position/{margin_mode}/{symbol}': 1,
238
+ 'futures/order': 1,
239
+ 'futures/order/{client_order_id}': 1,
240
+ 'wallet/crypto/withdraw/{id}': 30,
241
+ },
242
+ 'put': {
243
+ 'margin/account/isolated/{symbol}': 1,
244
+ 'futures/account/isolated/{symbol}': 1,
245
+ 'wallet/crypto/withdraw/{id}': 30,
246
+ },
247
+ },
248
+ },
249
+ 'fees': {
250
+ 'trading': {
251
+ 'tierBased': true,
252
+ 'percentage': true,
253
+ 'taker': this.parseNumber('0.0009'),
254
+ 'maker': this.parseNumber('0.0009'),
255
+ 'tiers': {
256
+ 'maker': [
257
+ [this.parseNumber('0'), this.parseNumber('0.0009')],
258
+ [this.parseNumber('10'), this.parseNumber('0.0007')],
259
+ [this.parseNumber('100'), this.parseNumber('0.0006')],
260
+ [this.parseNumber('500'), this.parseNumber('0.0005')],
261
+ [this.parseNumber('1000'), this.parseNumber('0.0003')],
262
+ [this.parseNumber('5000'), this.parseNumber('0.0002')],
263
+ [this.parseNumber('10000'), this.parseNumber('0.0001')],
264
+ [this.parseNumber('20000'), this.parseNumber('0')],
265
+ [this.parseNumber('50000'), this.parseNumber('-0.0001')],
266
+ [this.parseNumber('100000'), this.parseNumber('-0.0001')],
267
+ ],
268
+ 'taker': [
269
+ [this.parseNumber('0'), this.parseNumber('0.0009')],
270
+ [this.parseNumber('10'), this.parseNumber('0.0008')],
271
+ [this.parseNumber('100'), this.parseNumber('0.0007')],
272
+ [this.parseNumber('500'), this.parseNumber('0.0007')],
273
+ [this.parseNumber('1000'), this.parseNumber('0.0006')],
274
+ [this.parseNumber('5000'), this.parseNumber('0.0006')],
275
+ [this.parseNumber('10000'), this.parseNumber('0.0005')],
276
+ [this.parseNumber('20000'), this.parseNumber('0.0004')],
277
+ [this.parseNumber('50000'), this.parseNumber('0.0003')],
278
+ [this.parseNumber('100000'), this.parseNumber('0.0002')],
279
+ ],
280
+ },
281
+ },
282
+ },
283
+ 'timeframes': {
284
+ '1m': 'M1',
285
+ '3m': 'M3',
286
+ '5m': 'M5',
287
+ '15m': 'M15',
288
+ '30m': 'M30',
289
+ '1h': 'H1',
290
+ '4h': 'H4',
291
+ '1d': 'D1',
292
+ '1w': 'D7',
293
+ '1M': '1M',
294
+ },
295
+ 'exceptions': {
296
+ 'exact': {
297
+ '429': errors.RateLimitExceeded,
298
+ '500': errors.ExchangeError,
299
+ '503': errors.ExchangeNotAvailable,
300
+ '504': errors.ExchangeNotAvailable,
301
+ '600': errors.PermissionDenied,
302
+ '800': errors.ExchangeError,
303
+ '1002': errors.AuthenticationError,
304
+ '1003': errors.PermissionDenied,
305
+ '1004': errors.AuthenticationError,
306
+ '1005': errors.AuthenticationError,
307
+ '2001': errors.BadSymbol,
308
+ '2002': errors.BadRequest,
309
+ '2003': errors.BadRequest,
310
+ '2010': errors.BadRequest,
311
+ '2011': errors.BadRequest,
312
+ '2012': errors.BadRequest,
313
+ '2020': errors.BadRequest,
314
+ '2022': errors.BadRequest,
315
+ '10001': errors.BadRequest,
316
+ '10021': errors.AccountSuspended,
317
+ '10022': errors.BadRequest,
318
+ '20001': errors.InsufficientFunds,
319
+ '20002': errors.OrderNotFound,
320
+ '20003': errors.ExchangeError,
321
+ '20004': errors.ExchangeError,
322
+ '20005': errors.ExchangeError,
323
+ '20006': errors.ExchangeError,
324
+ '20007': errors.ExchangeError,
325
+ '20008': errors.InvalidOrder,
326
+ '20009': errors.InvalidOrder,
327
+ '20010': errors.OnMaintenance,
328
+ '20011': errors.ExchangeError,
329
+ '20012': errors.ExchangeError,
330
+ '20014': errors.ExchangeError,
331
+ '20016': errors.ExchangeError,
332
+ '20031': errors.ExchangeError,
333
+ '20032': errors.ExchangeError,
334
+ '20033': errors.ExchangeError,
335
+ '20034': errors.ExchangeError,
336
+ '20040': errors.ExchangeError,
337
+ '20041': errors.ExchangeError,
338
+ '20042': errors.ExchangeError,
339
+ '20043': errors.ExchangeError,
340
+ '20044': errors.PermissionDenied,
341
+ '20045': errors.InvalidOrder,
342
+ '20080': errors.ExchangeError,
343
+ '21001': errors.ExchangeError,
344
+ '21003': errors.AccountSuspended,
345
+ '21004': errors.AccountSuspended,
346
+ },
347
+ 'broad': {},
348
+ },
349
+ 'options': {
350
+ 'defaultNetwork': 'ERC20',
351
+ 'defaultNetworks': {
352
+ 'ETH': 'ETH',
353
+ 'USDT': 'TRC20',
354
+ },
355
+ 'networks': {
356
+ // mainnet network ids are in lowercase for BTC & ETH
357
+ 'BTC': 'btc',
358
+ 'OMNI': 'BTC',
359
+ 'ETH': 'eth',
360
+ 'ERC20': 'ETH',
361
+ 'ETC': 'ETC',
362
+ 'BEP20': 'BSC',
363
+ 'TRC20': 'TRX',
364
+ // '': 'UGT',
365
+ 'NEAR': 'NEAR',
366
+ // '': 'LWF',
367
+ 'DGB': 'DGB',
368
+ // '': 'YOYOW',
369
+ 'AE': 'AE',
370
+ // 'BCHABC': 'BCHABC',
371
+ // '': 'BCI',
372
+ // 'BYTECOIN': 'bcn',
373
+ 'AR': 'AR',
374
+ // '': 'HPC',
375
+ 'ADA': 'ADA',
376
+ // 'BELDEX': 'BDX',
377
+ // 'ARDOR': 'ARDR',
378
+ // 'NEBLIO': 'NEBL',
379
+ // '': 'DIM',
380
+ 'CHZ': 'CHZ',
381
+ // '': 'BET',
382
+ // '': '8BT',
383
+ 'ABBC': 'ABBC',
384
+ // '': 'ABTC',
385
+ // 'ACHAIN': 'ACT',
386
+ // '': 'ADK',
387
+ // '': 'AEON',
388
+ 'ALGO': 'ALGO',
389
+ // 'AMBROSUS': 'AMB',
390
+ // '': 'APL',
391
+ 'APT': 'APT',
392
+ // '': 'ARK',
393
+ // 'PIRATECHAIN': 'ARRR',
394
+ // '': 'ASP',
395
+ // '': 'ATB',
396
+ 'ATOM': 'ATOM',
397
+ 'AVAXC': 'AVAC',
398
+ 'AVAXX': 'AVAX',
399
+ // '': 'AYA',
400
+ // '': 'B2G',
401
+ // '': 'B2X',
402
+ // '': 'BANANO',
403
+ // '': 'BCCF',
404
+ 'BSV': 'BCHSV',
405
+ 'BEP2': 'BNB',
406
+ // 'BOSON': 'BOS',
407
+ // '': 'BRL', // brazilian real
408
+ // '': 'BST',
409
+ // 'BITCOINADDITION': 'BTCADD',
410
+ // '': 'BTCP',
411
+ // 'SUPERBTC': 'SBTC',
412
+ // 'BITCOINVAULT': 'BTCV',
413
+ // 'BITCOINGOLD': 'BTG',
414
+ // 'BITCOINDIAMOND': 'BCD',
415
+ // 'BITCONNECT': 'BCC',
416
+ // '': 'BTM',
417
+ // 'BITSHARES_OLD': 'BTS',
418
+ // '': 'BTX',
419
+ // '': 'BWI',
420
+ 'CELO': 'CELO',
421
+ // '': 'CENNZ',
422
+ // '': 'CHX',
423
+ 'CKB': 'CKB',
424
+ // 'CALLISTO': 'CLO',
425
+ // '': 'CLR',
426
+ // '': 'CNX',
427
+ // '': 'CRS',
428
+ // '': 'CSOV',
429
+ 'CTXC': 'CTXC',
430
+ // '': 'CURE',
431
+ // 'CONSTELLATION': 'DAG',
432
+ // '': 'DAPS',
433
+ 'DASH': 'DASH',
434
+ // '': 'DBIX',
435
+ 'DCR': 'DCR',
436
+ // '': 'DCT',
437
+ // '': 'DDR',
438
+ // '': 'DNA',
439
+ 'DOGE': 'doge',
440
+ // 'POLKADOT': 'DOT',
441
+ // '': 'NEWDOT', POLKADOT NEW
442
+ // '': 'dsh',
443
+ // '': 'ECA',
444
+ // '': 'ECOIN',
445
+ // '': 'EEX',
446
+ 'EGLD': 'EGLD',
447
+ // '': 'ELE',
448
+ // 'ELECTRONEUM': 'Electroneum',
449
+ // '': 'ELM',
450
+ // '': 'EMC',
451
+ 'EOS': 'EOS',
452
+ // 'AERGO': 'ERG',
453
+ 'ETHW': 'ETHW',
454
+ // 'ETHERLITE': 'ETL',
455
+ // '': 'ETP', // metaverse etp
456
+ // '': 'EUNO',
457
+ 'EVER': 'EVER',
458
+ // '': 'EXP',
459
+ // '': 'fcn',
460
+ 'FET': 'FET',
461
+ 'FIL': 'FIL',
462
+ // '': 'FIRO',
463
+ 'FLOW': 'FLOW',
464
+ // '': 'G999',
465
+ // '': 'GAME',
466
+ // '': 'GASP',
467
+ // '': 'GBX',
468
+ // '': 'GHOST',
469
+ // '': 'GLEEC',
470
+ 'GLMR': 'GLMR',
471
+ // '': 'GMD',
472
+ // '': 'GRAPH',
473
+ 'GRIN': 'GRIN',
474
+ 'HBAR': 'HBAR',
475
+ // '': 'HDG',
476
+ 'HIVE': 'HIVE',
477
+ // 'HARBOR': 'HRB',
478
+ // '': 'HSR',
479
+ // '': 'HTML',
480
+ 'HYDRA': 'HYDRA',
481
+ 'ICP': 'ICP',
482
+ 'ICX': 'ICX',
483
+ // '': 'IML',
484
+ 'IOST': 'IOST',
485
+ 'IOTA': 'IOTA',
486
+ 'IOTX': 'IOTX',
487
+ // '': 'IQ',
488
+ 'KAVA': 'KAVA',
489
+ 'KLAY': 'KIM',
490
+ 'KOMODO': 'KMD',
491
+ // '': 'KRM',
492
+ 'KSM': 'KSM',
493
+ // '': 'LAVA',
494
+ // 'LITECOINCASH': 'LCC',
495
+ 'LSK': 'LSK',
496
+ // '': 'LOC',
497
+ 'LTC': 'ltc',
498
+ // '': 'LTNM',
499
+ // 'TERRACLASSIC': 'LUNA',
500
+ // 'TERRA': 'LUNANEW',
501
+ // '': 'MAN',
502
+ // '': 'MESH',
503
+ 'MINA': 'MINA',
504
+ // '': 'MNX',
505
+ // 'MOBILECOIN': 'MOB',
506
+ 'MOVR': 'MOVR',
507
+ // '': 'MPK',
508
+ // '': 'MRV',
509
+ 'NANO': 'NANO',
510
+ // '': 'NAV',
511
+ 'NEO': 'NEO',
512
+ // 'NIMIQ': 'NIM',
513
+ // '': 'NJBC',
514
+ // '': 'NKN',
515
+ // '': 'NLC2',
516
+ // '': 'NOF',
517
+ // 'ENERGI': 'NRG',
518
+ // '': 'nxt',
519
+ // '': 'ODN',
520
+ 'ONE': 'ONE',
521
+ // 'ONTOLOGYGAS': 'ONG',
522
+ 'ONT': 'ONT',
523
+ 'OPTIMISM': 'OP',
524
+ // '': 'PAD',
525
+ // '': 'PART',
526
+ // '': 'PBKX',
527
+ // '': 'PLC',
528
+ 'PLCU': 'PLCU',
529
+ // '': 'PLI',
530
+ // '': 'POA',
531
+ 'MATIC': 'POLYGON',
532
+ // '': 'PPC',
533
+ // '': 'PQT',
534
+ // '': 'PROC',
535
+ // 'PASTEL': 'PSL',
536
+ // '': 'qcn',
537
+ 'QTUM': 'QTUM',
538
+ // '': 'RCOIN',
539
+ 'REI': 'REI',
540
+ // '': 'RIF',
541
+ // '': 'ROOTS',
542
+ 'OASIS': 'ROSE',
543
+ // '': 'RPX',
544
+ // '': 'RUB',
545
+ 'RVN': 'RVN',
546
+ // '': 'SBD',
547
+ 'SC': 'SC',
548
+ 'SCRT': 'SCRT',
549
+ // '': 'SLX',
550
+ // 'SMARTMESH': 'SMART',
551
+ // '': 'SMT',
552
+ // '': 'SNM',
553
+ 'SOL': 'SOL',
554
+ // '': 'SRX',
555
+ // '': 'STAK',
556
+ 'STEEM': 'STEEM',
557
+ // 'STRATIS': 'STRAT',
558
+ // '': 'TCN',
559
+ // '': 'TENT',
560
+ 'THETA': 'Theta',
561
+ // '': 'TIV',
562
+ // '': 'TNC',
563
+ // 'TON': 'TONCOIN',
564
+ 'TRUE': 'TRUE',
565
+ // '': 'TRY', // turkish lira
566
+ // '': 'UNO',
567
+ // '': 'USNOTA',
568
+ // '': 'VEO',
569
+ 'VET': 'VET',
570
+ // '': 'VITAE',
571
+ // 'VELAS': 'VLX',
572
+ 'VSYS': 'VSYS',
573
+ // '': 'VTC',
574
+ 'WAVES': 'WAVES',
575
+ 'WAX': 'WAX',
576
+ // '': 'WEALTH',
577
+ // 'WALTONCHAIN': 'WTC',
578
+ // '': 'WTT',
579
+ 'XCH': 'XCH',
580
+ // '': 'XDC', // xinfin?
581
+ // '': 'xdn',
582
+ // '': 'XDNCO',
583
+ // '': 'XDNICCO',
584
+ 'XEC': 'XEC',
585
+ 'NEM': 'XEM',
586
+ // 'HAVEN': 'XHV',
587
+ // '': 'XLC',
588
+ 'XLM': 'XLM',
589
+ // '': 'XMO',
590
+ 'XMR': 'xmr',
591
+ // 'MONEROCLASSIC': 'XMC',
592
+ // '': 'XNS',
593
+ // '': 'XPRM',
594
+ // '': 'XRC',
595
+ 'XRD': 'XRD',
596
+ 'XRP': 'XRP',
597
+ 'XTZ': 'XTZ',
598
+ 'XVG': 'XVG',
599
+ 'XYM': 'XYM',
600
+ 'ZEC': 'ZEC',
601
+ 'ZEN': 'ZEN',
602
+ 'ZIL': 'ZIL',
603
+ // '': 'ZYN',
604
+ },
605
+ 'accountsByType': {
606
+ 'spot': 'spot',
607
+ 'funding': 'wallet',
608
+ 'future': 'derivatives',
609
+ },
610
+ 'withdraw': {
611
+ 'includeFee': false,
612
+ },
613
+ },
614
+ 'commonCurrencies': {
615
+ 'AUTO': 'Cube',
616
+ 'BCC': 'BCC',
617
+ 'BDP': 'BidiPass',
618
+ 'BET': 'DAO.Casino',
619
+ 'BIT': 'BitRewards',
620
+ 'BOX': 'BOX Token',
621
+ 'CPT': 'Cryptaur',
622
+ 'GET': 'Themis',
623
+ 'GMT': 'GMT Token',
624
+ 'HSR': 'HC',
625
+ 'IQ': 'IQ.Cash',
626
+ 'LNC': 'LinkerCoin',
627
+ 'PLA': 'PlayChip',
628
+ 'PNT': 'Penta',
629
+ 'SBTC': 'Super Bitcoin',
630
+ 'STEPN': 'GMT',
631
+ 'STX': 'STOX',
632
+ 'TV': 'Tokenville',
633
+ 'XMT': 'MTL',
634
+ 'XPNT': 'PNT',
635
+ },
636
+ });
637
+ }
638
+ nonce() {
639
+ return this.milliseconds();
640
+ }
641
+ async fetchMarkets(params = {}) {
642
+ /**
643
+ * @method
644
+ * @name hitbtc#fetchMarkets
645
+ * @description retrieves data on all markets for hitbtc
646
+ * @see https://api.hitbtc.com/#symbols
647
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
648
+ * @returns {object[]} an array of objects representing market data
649
+ */
650
+ const response = await this.publicGetPublicSymbol(params);
651
+ //
652
+ // {
653
+ // "AAVEUSDT_PERP":{
654
+ // "type":"futures",
655
+ // "expiry":null,
656
+ // "underlying":"AAVE",
657
+ // "base_currency":null,
658
+ // "quote_currency":"USDT",
659
+ // "quantity_increment":"0.01",
660
+ // "tick_size":"0.001",
661
+ // "take_rate":"0.0005",
662
+ // "make_rate":"0.0002",
663
+ // "fee_currency":"USDT",
664
+ // "margin_trading":true,
665
+ // "max_initial_leverage":"50.00"
666
+ // },
667
+ // "MANAUSDT":{
668
+ // "type":"spot",
669
+ // "base_currency":"MANA",
670
+ // "quote_currency":"USDT",
671
+ // "quantity_increment":"1",
672
+ // "tick_size":"0.0000001",
673
+ // "take_rate":"0.0025",
674
+ // "make_rate":"0.001",
675
+ // "fee_currency":"USDT",
676
+ // "margin_trading":true,
677
+ // "max_initial_leverage":"5.00"
678
+ // },
679
+ // }
680
+ //
681
+ const result = [];
682
+ const ids = Object.keys(response);
683
+ for (let i = 0; i < ids.length; i++) {
684
+ const id = ids[i];
685
+ if (id.endsWith('_BQX')) {
686
+ continue; // seems like an invalid symbol and if we try to access it individually we get: {"timestamp":"2023-09-02T14:38:20.351Z","error":{"description":"Try get /public/symbol, to get list of all available symbols.","code":2001,"message":"No such symbol: EOSUSD_BQX"},"path":"/api/3/public/symbol/EOSUSD_BQX","requestId":"e1e9fce6-16374591"}
687
+ }
688
+ const market = this.safeValue(response, id);
689
+ const marketType = this.safeString(market, 'type');
690
+ const expiry = this.safeInteger(market, 'expiry');
691
+ const contract = (marketType === 'futures');
692
+ const spot = (marketType === 'spot');
693
+ const marginTrading = this.safeValue(market, 'margin_trading', false);
694
+ const margin = spot && marginTrading;
695
+ const future = (expiry !== undefined);
696
+ const swap = (contract && !future);
697
+ const option = false;
698
+ const baseId = this.safeString2(market, 'base_currency', 'underlying');
699
+ const quoteId = this.safeString(market, 'quote_currency');
700
+ const feeCurrencyId = this.safeString(market, 'fee_currency');
701
+ const base = this.safeCurrencyCode(baseId);
702
+ const quote = this.safeCurrencyCode(quoteId);
703
+ const feeCurrency = this.safeCurrencyCode(feeCurrencyId);
704
+ let settleId = undefined;
705
+ let settle = undefined;
706
+ let symbol = base + '/' + quote;
707
+ let type = 'spot';
708
+ let contractSize = undefined;
709
+ let linear = undefined;
710
+ let inverse = undefined;
711
+ if (contract) {
712
+ contractSize = this.parseNumber('1');
713
+ settleId = feeCurrencyId;
714
+ settle = this.safeCurrencyCode(settleId);
715
+ linear = ((quote !== undefined) && (quote === settle));
716
+ inverse = !linear;
717
+ symbol = symbol + ':' + settle;
718
+ if (future) {
719
+ symbol = symbol + '-' + expiry;
720
+ type = 'future';
721
+ }
722
+ else {
723
+ type = 'swap';
724
+ }
725
+ }
726
+ const lotString = this.safeString(market, 'quantity_increment');
727
+ const stepString = this.safeString(market, 'tick_size');
728
+ const lot = this.parseNumber(lotString);
729
+ const step = this.parseNumber(stepString);
730
+ result.push({
731
+ 'id': id,
732
+ 'symbol': symbol,
733
+ 'base': base,
734
+ 'quote': quote,
735
+ 'settle': settle,
736
+ 'baseId': baseId,
737
+ 'quoteId': quoteId,
738
+ 'settleId': settleId,
739
+ 'type': type,
740
+ 'spot': spot,
741
+ 'margin': margin,
742
+ 'swap': swap,
743
+ 'future': future,
744
+ 'option': option,
745
+ 'active': true,
746
+ 'contract': contract,
747
+ 'linear': linear,
748
+ 'inverse': inverse,
749
+ 'taker': this.safeNumber(market, 'take_rate'),
750
+ 'maker': this.safeNumber(market, 'make_rate'),
751
+ 'contractSize': contractSize,
752
+ 'expiry': expiry,
753
+ 'expiryDatetime': undefined,
754
+ 'strike': undefined,
755
+ 'optionType': undefined,
756
+ 'feeCurrency': feeCurrency,
757
+ 'precision': {
758
+ 'amount': lot,
759
+ 'price': step,
760
+ },
761
+ 'limits': {
762
+ 'leverage': {
763
+ 'min': this.parseNumber('1'),
764
+ 'max': this.safeNumber(market, 'max_initial_leverage', 1),
765
+ },
766
+ 'amount': {
767
+ 'min': lot,
768
+ 'max': undefined,
769
+ },
770
+ 'price': {
771
+ 'min': step,
772
+ 'max': undefined,
773
+ },
774
+ 'cost': {
775
+ 'min': this.parseNumber(Precise["default"].stringMul(lotString, stepString)),
776
+ 'max': undefined,
777
+ },
778
+ },
779
+ 'created': undefined,
780
+ 'info': market,
781
+ });
782
+ }
783
+ return result;
784
+ }
785
+ async fetchCurrencies(params = {}) {
786
+ /**
787
+ * @method
788
+ * @name hitbtc#fetchCurrencies
789
+ * @description fetches all available currencies on an exchange
790
+ * @see https://api.hitbtc.com/#currencies
791
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
792
+ * @returns {object} an associative dictionary of currencies
793
+ */
794
+ const response = await this.publicGetPublicCurrency(params);
795
+ //
796
+ // {
797
+ // "WEALTH": {
798
+ // "full_name": "ConnectWealth",
799
+ // "payin_enabled": false,
800
+ // "payout_enabled": false,
801
+ // "transfer_enabled": true,
802
+ // "precision_transfer": "0.001",
803
+ // "networks": [
804
+ // {
805
+ // "network": "ETH",
806
+ // "protocol": "ERC20",
807
+ // "default": true,
808
+ // "payin_enabled": false,
809
+ // "payout_enabled": false,
810
+ // "precision_payout": "0.001",
811
+ // "payout_fee": "0.016800000000",
812
+ // "payout_is_payment_id": false,
813
+ // "payin_payment_id": false,
814
+ // "payin_confirmations": "2"
815
+ // }
816
+ // ]
817
+ // }
818
+ // }
819
+ //
820
+ const result = {};
821
+ const currencies = Object.keys(response);
822
+ for (let i = 0; i < currencies.length; i++) {
823
+ const currencyId = currencies[i];
824
+ const code = this.safeCurrencyCode(currencyId);
825
+ const entry = response[currencyId];
826
+ const name = this.safeString(entry, 'full_name');
827
+ const precision = this.safeNumber(entry, 'precision_transfer');
828
+ const payinEnabled = this.safeValue(entry, 'payin_enabled', false);
829
+ const payoutEnabled = this.safeValue(entry, 'payout_enabled', false);
830
+ const transferEnabled = this.safeValue(entry, 'transfer_enabled', false);
831
+ const active = payinEnabled && payoutEnabled && transferEnabled;
832
+ const rawNetworks = this.safeValue(entry, 'networks', []);
833
+ const networks = {};
834
+ let fee = undefined;
835
+ let depositEnabled = undefined;
836
+ let withdrawEnabled = undefined;
837
+ for (let j = 0; j < rawNetworks.length; j++) {
838
+ const rawNetwork = rawNetworks[j];
839
+ const networkId = this.safeString2(rawNetwork, 'protocol', 'network');
840
+ const network = this.safeNetwork(networkId);
841
+ fee = this.safeNumber(rawNetwork, 'payout_fee');
842
+ const networkPrecision = this.safeNumber(rawNetwork, 'precision_payout');
843
+ const payinEnabledNetwork = this.safeValue(entry, 'payin_enabled', false);
844
+ const payoutEnabledNetwork = this.safeValue(entry, 'payout_enabled', false);
845
+ const activeNetwork = payinEnabledNetwork && payoutEnabledNetwork;
846
+ if (payinEnabledNetwork && !depositEnabled) {
847
+ depositEnabled = true;
848
+ }
849
+ else if (!payinEnabledNetwork) {
850
+ depositEnabled = false;
851
+ }
852
+ if (payoutEnabledNetwork && !withdrawEnabled) {
853
+ withdrawEnabled = true;
854
+ }
855
+ else if (!payoutEnabledNetwork) {
856
+ withdrawEnabled = false;
857
+ }
858
+ networks[network] = {
859
+ 'info': rawNetwork,
860
+ 'id': networkId,
861
+ 'network': network,
862
+ 'fee': fee,
863
+ 'active': activeNetwork,
864
+ 'deposit': payinEnabledNetwork,
865
+ 'withdraw': payoutEnabledNetwork,
866
+ 'precision': networkPrecision,
867
+ 'limits': {
868
+ 'withdraw': {
869
+ 'min': undefined,
870
+ 'max': undefined,
871
+ },
872
+ },
873
+ };
874
+ }
875
+ const networksKeys = Object.keys(networks);
876
+ const networksLength = networksKeys.length;
877
+ result[code] = {
878
+ 'info': entry,
879
+ 'code': code,
880
+ 'id': currencyId,
881
+ 'precision': precision,
882
+ 'name': name,
883
+ 'active': active,
884
+ 'deposit': depositEnabled,
885
+ 'withdraw': withdrawEnabled,
886
+ 'networks': networks,
887
+ 'fee': (networksLength <= 1) ? fee : undefined,
888
+ 'limits': {
889
+ 'amount': {
890
+ 'min': undefined,
891
+ 'max': undefined,
892
+ },
893
+ },
894
+ };
895
+ }
896
+ return result;
897
+ }
898
+ safeNetwork(networkId) {
899
+ if (networkId === undefined) {
900
+ return undefined;
901
+ }
902
+ else {
903
+ return networkId.toUpperCase();
904
+ }
905
+ }
906
+ async createDepositAddress(code, params = {}) {
907
+ /**
908
+ * @method
909
+ * @name hitbtc#createDepositAddress
910
+ * @description create a currency deposit address
911
+ * @see https://api.hitbtc.com/#generate-deposit-crypto-address
912
+ * @param {string} code unified currency code of the currency for the deposit address
913
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
914
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
915
+ */
916
+ await this.loadMarkets();
917
+ const currency = this.currency(code);
918
+ const request = {
919
+ 'currency': currency['id'],
920
+ };
921
+ const network = this.safeStringUpper(params, 'network');
922
+ if ((network !== undefined) && (code === 'USDT')) {
923
+ const networks = this.safeValue(this.options, 'networks');
924
+ const parsedNetwork = this.safeString(networks, network);
925
+ if (parsedNetwork !== undefined) {
926
+ request['currency'] = parsedNetwork;
927
+ }
928
+ params = this.omit(params, 'network');
929
+ }
930
+ const response = await this.privatePostWalletCryptoAddress(this.extend(request, params));
931
+ //
932
+ // {"currency":"ETH","address":"0xd0d9aea60c41988c3e68417e2616065617b7afd3"}
933
+ //
934
+ const currencyId = this.safeString(response, 'currency');
935
+ return {
936
+ 'currency': this.safeCurrencyCode(currencyId),
937
+ 'address': this.safeString(response, 'address'),
938
+ 'tag': this.safeString(response, 'payment_id'),
939
+ 'network': undefined,
940
+ 'info': response,
941
+ };
942
+ }
943
+ async fetchDepositAddress(code, params = {}) {
944
+ /**
945
+ * @method
946
+ * @name hitbtc#fetchDepositAddress
947
+ * @description fetch the deposit address for a currency associated with this account
948
+ * @see https://api.hitbtc.com/#get-deposit-crypto-address
949
+ * @param {string} code unified currency code
950
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
951
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
952
+ */
953
+ await this.loadMarkets();
954
+ const currency = this.currency(code);
955
+ const request = {
956
+ 'currency': currency['id'],
957
+ };
958
+ const network = this.safeStringUpper(params, 'network');
959
+ if ((network !== undefined) && (code === 'USDT')) {
960
+ const networks = this.safeValue(this.options, 'networks');
961
+ const parsedNetwork = this.safeString(networks, network);
962
+ if (parsedNetwork !== undefined) {
963
+ request['currency'] = parsedNetwork;
964
+ }
965
+ params = this.omit(params, 'network');
966
+ }
967
+ const response = await this.privateGetWalletCryptoAddress(this.extend(request, params));
968
+ //
969
+ // [{"currency":"ETH","address":"0xd0d9aea60c41988c3e68417e2616065617b7afd3"}]
970
+ //
971
+ const firstAddress = this.safeValue(response, 0);
972
+ const address = this.safeString(firstAddress, 'address');
973
+ const currencyId = this.safeString(firstAddress, 'currency');
974
+ const tag = this.safeString(firstAddress, 'payment_id');
975
+ const parsedCode = this.safeCurrencyCode(currencyId);
976
+ return {
977
+ 'info': response,
978
+ 'address': address,
979
+ 'tag': tag,
980
+ 'code': parsedCode,
981
+ 'currency': parsedCode,
982
+ 'network': undefined,
983
+ };
984
+ }
985
+ parseBalance(response) {
986
+ const result = { 'info': response };
987
+ for (let i = 0; i < response.length; i++) {
988
+ const entry = response[i];
989
+ const currencyId = this.safeString(entry, 'currency');
990
+ const code = this.safeCurrencyCode(currencyId);
991
+ const account = this.account();
992
+ account['free'] = this.safeString(entry, 'available');
993
+ account['used'] = this.safeString(entry, 'reserved');
994
+ result[code] = account;
995
+ }
996
+ return this.safeBalance(result);
997
+ }
998
+ async fetchBalance(params = {}) {
999
+ /**
1000
+ * @method
1001
+ * @name hitbtc#fetchBalance
1002
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
1003
+ * @see https://api.hitbtc.com/#wallet-balance
1004
+ * @see https://api.hitbtc.com/#get-spot-trading-balance
1005
+ * @see https://api.hitbtc.com/#get-trading-balance
1006
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1007
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1008
+ */
1009
+ const type = this.safeStringLower(params, 'type', 'spot');
1010
+ params = this.omit(params, ['type']);
1011
+ const accountsByType = this.safeValue(this.options, 'accountsByType', {});
1012
+ const account = this.safeString(accountsByType, type, type);
1013
+ let response = undefined;
1014
+ if (account === 'wallet') {
1015
+ response = await this.privateGetWalletBalance(params);
1016
+ }
1017
+ else if (account === 'spot') {
1018
+ response = await this.privateGetSpotBalance(params);
1019
+ }
1020
+ else if (account === 'derivatives') {
1021
+ response = await this.privateGetFuturesBalance(params);
1022
+ }
1023
+ else {
1024
+ const keys = Object.keys(accountsByType);
1025
+ throw new errors.BadRequest(this.id + ' fetchBalance() type parameter must be one of ' + keys.join(', '));
1026
+ }
1027
+ //
1028
+ // [
1029
+ // {
1030
+ // "currency": "PAXG",
1031
+ // "available": "0",
1032
+ // "reserved": "0",
1033
+ // "reserved_margin": "0",
1034
+ // },
1035
+ // ...
1036
+ // ]
1037
+ //
1038
+ return this.parseBalance(response);
1039
+ }
1040
+ async fetchTicker(symbol, params = {}) {
1041
+ /**
1042
+ * @method
1043
+ * @name hitbtc#fetchTicker
1044
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1045
+ * @see https://api.hitbtc.com/#tickers
1046
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1047
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1048
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1049
+ */
1050
+ await this.loadMarkets();
1051
+ const market = this.market(symbol);
1052
+ const request = {
1053
+ 'symbol': market['id'],
1054
+ };
1055
+ const response = await this.publicGetPublicTickerSymbol(this.extend(request, params));
1056
+ //
1057
+ // {
1058
+ // "ask": "0.020572",
1059
+ // "bid": "0.020566",
1060
+ // "last": "0.020574",
1061
+ // "low": "0.020388",
1062
+ // "high": "0.021084",
1063
+ // "open": "0.020913",
1064
+ // "volume": "138444.3666",
1065
+ // "volume_quote": "2853.6874972480",
1066
+ // "timestamp": "2021-06-02T17:52:36.731Z"
1067
+ // }
1068
+ //
1069
+ return this.parseTicker(response, market);
1070
+ }
1071
+ async fetchTickers(symbols = undefined, params = {}) {
1072
+ /**
1073
+ * @method
1074
+ * @name hitbtc#fetchTickers
1075
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1076
+ * @see https://api.hitbtc.com/#tickers
1077
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1078
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1079
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1080
+ */
1081
+ await this.loadMarkets();
1082
+ symbols = this.marketSymbols(symbols);
1083
+ const request = {};
1084
+ if (symbols !== undefined) {
1085
+ const marketIds = this.marketIds(symbols);
1086
+ const delimited = marketIds.join(',');
1087
+ request['symbols'] = delimited;
1088
+ }
1089
+ const response = await this.publicGetPublicTicker(this.extend(request, params));
1090
+ //
1091
+ // {
1092
+ // "BTCUSDT": {
1093
+ // "ask": "63049.06",
1094
+ // "bid": "63046.41",
1095
+ // "last": "63048.36",
1096
+ // "low": "62010.00",
1097
+ // "high": "66657.99",
1098
+ // "open": "64839.75",
1099
+ // "volume": "15272.13278",
1100
+ // "volume_quote": "976312127.6277998",
1101
+ // "timestamp": "2021-10-22T04:25:47.573Z"
1102
+ // }
1103
+ // }
1104
+ //
1105
+ const result = {};
1106
+ const keys = Object.keys(response);
1107
+ for (let i = 0; i < keys.length; i++) {
1108
+ const marketId = keys[i];
1109
+ const market = this.safeMarket(marketId);
1110
+ const symbol = market['symbol'];
1111
+ const entry = response[marketId];
1112
+ result[symbol] = this.parseTicker(entry, market);
1113
+ }
1114
+ return this.filterByArrayTickers(result, 'symbol', symbols);
1115
+ }
1116
+ parseTicker(ticker, market = undefined) {
1117
+ //
1118
+ // {
1119
+ // "ask": "62756.01",
1120
+ // "bid": "62754.09",
1121
+ // "last": "62755.87",
1122
+ // "low": "62010.00",
1123
+ // "high": "66657.99",
1124
+ // "open": "65089.27",
1125
+ // "volume": "16719.50366",
1126
+ // "volume_quote": "1063422878.8156828",
1127
+ // "timestamp": "2021-10-22T07:29:14.585Z"
1128
+ // }
1129
+ //
1130
+ const timestamp = this.parse8601(ticker['timestamp']);
1131
+ const symbol = this.safeSymbol(undefined, market);
1132
+ const baseVolume = this.safeString(ticker, 'volume');
1133
+ const quoteVolume = this.safeString(ticker, 'volume_quote');
1134
+ const open = this.safeString(ticker, 'open');
1135
+ const last = this.safeString(ticker, 'last');
1136
+ return this.safeTicker({
1137
+ 'symbol': symbol,
1138
+ 'timestamp': timestamp,
1139
+ 'datetime': this.iso8601(timestamp),
1140
+ 'high': this.safeString(ticker, 'high'),
1141
+ 'low': this.safeString(ticker, 'low'),
1142
+ 'bid': this.safeString(ticker, 'bid'),
1143
+ 'bidVolume': undefined,
1144
+ 'ask': this.safeString(ticker, 'ask'),
1145
+ 'askVolume': undefined,
1146
+ 'vwap': undefined,
1147
+ 'open': open,
1148
+ 'close': last,
1149
+ 'last': last,
1150
+ 'previousClose': undefined,
1151
+ 'change': undefined,
1152
+ 'percentage': undefined,
1153
+ 'average': undefined,
1154
+ 'baseVolume': baseVolume,
1155
+ 'quoteVolume': quoteVolume,
1156
+ 'info': ticker,
1157
+ }, market);
1158
+ }
1159
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1160
+ /**
1161
+ * @method
1162
+ * @name hitbtc#fetchTrades
1163
+ * @description get the list of most recent trades for a particular symbol
1164
+ * @see https://api.hitbtc.com/#trades
1165
+ * @param {string} symbol unified symbol of the market to fetch trades for
1166
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
1167
+ * @param {int} [limit] the maximum amount of trades to fetch
1168
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1169
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1170
+ */
1171
+ await this.loadMarkets();
1172
+ let market = undefined;
1173
+ const request = {};
1174
+ if (limit !== undefined) {
1175
+ request['limit'] = Math.min(limit, 1000);
1176
+ }
1177
+ if (since !== undefined) {
1178
+ request['from'] = since;
1179
+ }
1180
+ let response = undefined;
1181
+ if (symbol !== undefined) {
1182
+ market = this.market(symbol);
1183
+ request['symbol'] = market['id'];
1184
+ response = await this.publicGetPublicTradesSymbol(this.extend(request, params));
1185
+ }
1186
+ else {
1187
+ response = await this.publicGetPublicTrades(this.extend(request, params));
1188
+ }
1189
+ if (symbol !== undefined) {
1190
+ return this.parseTrades(response, market);
1191
+ }
1192
+ let trades = [];
1193
+ const marketIds = Object.keys(response);
1194
+ for (let i = 0; i < marketIds.length; i++) {
1195
+ const marketId = marketIds[i];
1196
+ const marketInner = this.market(marketId);
1197
+ const rawTrades = response[marketId];
1198
+ const parsed = this.parseTrades(rawTrades, marketInner);
1199
+ trades = this.arrayConcat(trades, parsed);
1200
+ }
1201
+ return trades;
1202
+ }
1203
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1204
+ /**
1205
+ * @method
1206
+ * @name hitbtc#fetchMyTrades
1207
+ * @description fetch all trades made by the user
1208
+ * @see https://api.hitbtc.com/#spot-trades-history
1209
+ * @see https://api.hitbtc.com/#futures-trades-history
1210
+ * @see https://api.hitbtc.com/#margin-trades-history
1211
+ * @param {string} symbol unified market symbol
1212
+ * @param {int} [since] the earliest time in ms to fetch trades for
1213
+ * @param {int} [limit] the maximum number of trades structures to retrieve
1214
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1215
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
1216
+ * @param {bool} [params.margin] true for fetching margin trades
1217
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1218
+ */
1219
+ await this.loadMarkets();
1220
+ let market = undefined;
1221
+ const request = {};
1222
+ if (symbol !== undefined) {
1223
+ market = this.market(symbol);
1224
+ request['symbol'] = market['id'];
1225
+ }
1226
+ if (limit !== undefined) {
1227
+ request['limit'] = limit;
1228
+ }
1229
+ if (since !== undefined) {
1230
+ request['from'] = since;
1231
+ }
1232
+ let marketType = undefined;
1233
+ let marginMode = undefined;
1234
+ let response = undefined;
1235
+ [marketType, params] = this.handleMarketTypeAndParams('fetchMyTrades', market, params);
1236
+ [marginMode, params] = this.handleMarginModeAndParams('fetchMyTrades', params);
1237
+ params = this.omit(params, ['marginMode', 'margin']);
1238
+ if (marginMode !== undefined) {
1239
+ response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
1240
+ }
1241
+ else {
1242
+ if (marketType === 'spot') {
1243
+ response = await this.privateGetSpotHistoryTrade(this.extend(request, params));
1244
+ }
1245
+ else if (marketType === 'swap') {
1246
+ response = await this.privateGetFuturesHistoryTrade(this.extend(request, params));
1247
+ }
1248
+ else if (marketType === 'margin') {
1249
+ response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
1250
+ }
1251
+ else {
1252
+ throw new errors.NotSupported(this.id + ' fetchMyTrades() not support this market type');
1253
+ }
1254
+ }
1255
+ return this.parseTrades(response, market, since, limit);
1256
+ }
1257
+ parseTrade(trade, market = undefined) {
1258
+ //
1259
+ // createOrder (market)
1260
+ //
1261
+ // {
1262
+ // "id": "1569252895",
1263
+ // "position_id": "0",
1264
+ // "quantity": "10",
1265
+ // "price": "0.03919424",
1266
+ // "fee": "0.000979856000",
1267
+ // "timestamp": "2022-01-25T19:38:36.153Z",
1268
+ // "taker": true
1269
+ // }
1270
+ //
1271
+ // fetchTrades
1272
+ //
1273
+ // {
1274
+ // "id": 974786185,
1275
+ // "price": "0.032462",
1276
+ // "qty": "0.3673",
1277
+ // "side": "buy",
1278
+ // "timestamp": "2020-10-16T12:57:39.846Z"
1279
+ // }
1280
+ //
1281
+ // fetchMyTrades spot
1282
+ //
1283
+ // {
1284
+ // "id": 277210397,
1285
+ // "clientOrderId": "6e102f3e7f3f4e04aeeb1cdc95592f1a",
1286
+ // "orderId": 28102855393,
1287
+ // "symbol": "ETHBTC",
1288
+ // "side": "sell",
1289
+ // "quantity": "0.002",
1290
+ // "price": "0.073365",
1291
+ // "fee": "0.000000147",
1292
+ // "timestamp": "2018-04-28T18:39:55.345Z",
1293
+ // "taker": true
1294
+ // }
1295
+ //
1296
+ // fetchMyTrades swap and margin
1297
+ //
1298
+ // {
1299
+ // "id": 4718564,
1300
+ // "order_id": 58730811958,
1301
+ // "client_order_id": "475c47d97f867f09726186eb22b4c3d4",
1302
+ // "symbol": "BTCUSDT_PERP",
1303
+ // "side": "sell",
1304
+ // "quantity": "0.0001",
1305
+ // "price": "41118.51",
1306
+ // "fee": "0.002055925500",
1307
+ // "timestamp": "2022-03-17T05:23:17.795Z",
1308
+ // "taker": true,
1309
+ // "position_id": 2350122,
1310
+ // "pnl": "0.002255000000",
1311
+ // "liquidation": false
1312
+ // }
1313
+ //
1314
+ const timestamp = this.parse8601(trade['timestamp']);
1315
+ const marketId = this.safeString(trade, 'symbol');
1316
+ market = this.safeMarket(marketId, market);
1317
+ const symbol = market['symbol'];
1318
+ let fee = undefined;
1319
+ const feeCostString = this.safeString(trade, 'fee');
1320
+ const taker = this.safeValue(trade, 'taker');
1321
+ let takerOrMaker = undefined;
1322
+ if (taker !== undefined) {
1323
+ takerOrMaker = taker ? 'taker' : 'maker';
1324
+ }
1325
+ else {
1326
+ takerOrMaker = 'taker'; // the only case when `taker` field is missing, is public fetchTrades and it must be taker
1327
+ }
1328
+ if (feeCostString !== undefined) {
1329
+ const info = this.safeValue(market, 'info', {});
1330
+ const feeCurrency = this.safeString(info, 'fee_currency');
1331
+ const feeCurrencyCode = this.safeCurrencyCode(feeCurrency);
1332
+ fee = {
1333
+ 'cost': feeCostString,
1334
+ 'currency': feeCurrencyCode,
1335
+ };
1336
+ }
1337
+ // we use clientOrderId as the order id with this exchange intentionally
1338
+ // because most of their endpoints will require clientOrderId
1339
+ // explained here: https://github.com/ccxt/ccxt/issues/5674
1340
+ const orderId = this.safeString2(trade, 'clientOrderId', 'client_order_id');
1341
+ const priceString = this.safeString(trade, 'price');
1342
+ const amountString = this.safeString2(trade, 'quantity', 'qty');
1343
+ const side = this.safeString(trade, 'side');
1344
+ const id = this.safeString(trade, 'id');
1345
+ return this.safeTrade({
1346
+ 'info': trade,
1347
+ 'id': id,
1348
+ 'order': orderId,
1349
+ 'timestamp': timestamp,
1350
+ 'datetime': this.iso8601(timestamp),
1351
+ 'symbol': symbol,
1352
+ 'type': undefined,
1353
+ 'side': side,
1354
+ 'takerOrMaker': takerOrMaker,
1355
+ 'price': priceString,
1356
+ 'amount': amountString,
1357
+ 'cost': undefined,
1358
+ 'fee': fee,
1359
+ }, market);
1360
+ }
1361
+ async fetchTransactionsHelper(types, code, since, limit, params) {
1362
+ await this.loadMarkets();
1363
+ const request = {
1364
+ 'types': types,
1365
+ };
1366
+ let currency = undefined;
1367
+ if (code !== undefined) {
1368
+ currency = this.currency(code);
1369
+ request['currencies'] = currency['id'];
1370
+ }
1371
+ if (since !== undefined) {
1372
+ request['from'] = this.iso8601(since);
1373
+ }
1374
+ if (limit !== undefined) {
1375
+ request['limit'] = limit;
1376
+ }
1377
+ const response = await this.privateGetWalletTransactions(this.extend(request, params));
1378
+ //
1379
+ // [
1380
+ // {
1381
+ // "id": "101609495",
1382
+ // "created_at": "2018-03-06T22:05:06.507Z",
1383
+ // "updated_at": "2018-03-06T22:11:45.03Z",
1384
+ // "status": "SUCCESS",
1385
+ // "type": "DEPOSIT",
1386
+ // "subtype": "BLOCKCHAIN",
1387
+ // "native": {
1388
+ // "tx_id": "e20b0965-4024-44d0-b63f-7fb8996a6706",
1389
+ // "index": "881652766",
1390
+ // "currency": "ETH",
1391
+ // "amount": "0.01418088",
1392
+ // "hash": "d95dbbff3f9234114f1211ab0ba2a94f03f394866fd5749d74a1edab80e6c5d3",
1393
+ // "address": "0xd9259302c32c0a0295d86a39185c9e14f6ba0a0d",
1394
+ // "confirmations": "20",
1395
+ // "senders": [
1396
+ // "0x243bec9256c9a3469da22103891465b47583d9f1"
1397
+ // ]
1398
+ // }
1399
+ // }
1400
+ // ]
1401
+ //
1402
+ return this.parseTransactions(response, currency, since, limit, params);
1403
+ }
1404
+ parseTransactionStatus(status) {
1405
+ const statuses = {
1406
+ 'PENDING': 'pending',
1407
+ 'FAILED': 'failed',
1408
+ 'SUCCESS': 'ok',
1409
+ };
1410
+ return this.safeString(statuses, status, status);
1411
+ }
1412
+ parseTransactionType(type) {
1413
+ const types = {
1414
+ 'DEPOSIT': 'deposit',
1415
+ 'WITHDRAW': 'withdrawal',
1416
+ };
1417
+ return this.safeString(types, type, type);
1418
+ }
1419
+ parseTransaction(transaction, currency = undefined) {
1420
+ //
1421
+ // transaction
1422
+ //
1423
+ // {
1424
+ // "id": "101609495",
1425
+ // "created_at": "2018-03-06T22:05:06.507Z",
1426
+ // "updated_at": "2018-03-06T22:11:45.03Z",
1427
+ // "status": "SUCCESS",
1428
+ // "type": "DEPOSIT", // DEPOSIT, WITHDRAW, ..
1429
+ // "subtype": "BLOCKCHAIN",
1430
+ // "native": {
1431
+ // "tx_id": "e20b0965-4024-44d0-b63f-7fb8996a6706",
1432
+ // "index": "881652766",
1433
+ // "currency": "ETH",
1434
+ // "amount": "0.01418088",
1435
+ // "hash": "d95dbbff3f9234114f1211ab0ba2a94f03f394866fd5749d74a1edab80e6c5d3",
1436
+ // "address": "0xd9259302c32c0a0295d86a39185c9e14f6ba0a0d",
1437
+ // "confirmations": "20",
1438
+ // "senders": [
1439
+ // "0x243bec9256c9a3469da22103891465b47583d9f1"
1440
+ // ],
1441
+ // "fee": "1.22" // only for WITHDRAW
1442
+ // }
1443
+ // }
1444
+ //
1445
+ // withdraw
1446
+ //
1447
+ // {
1448
+ // "id":"084cfcd5-06b9-4826-882e-fdb75ec3625d"
1449
+ // }
1450
+ //
1451
+ const id = this.safeString(transaction, 'id');
1452
+ const timestamp = this.parse8601(this.safeString(transaction, 'created_at'));
1453
+ const updated = this.parse8601(this.safeString(transaction, 'updated_at'));
1454
+ const type = this.parseTransactionType(this.safeString(transaction, 'type'));
1455
+ const status = this.parseTransactionStatus(this.safeString(transaction, 'status'));
1456
+ const native = this.safeValue(transaction, 'native', {});
1457
+ const currencyId = this.safeString(native, 'currency');
1458
+ const code = this.safeCurrencyCode(currencyId);
1459
+ const txhash = this.safeString(native, 'hash');
1460
+ const address = this.safeString(native, 'address');
1461
+ const addressTo = address;
1462
+ const tag = this.safeString(native, 'payment_id');
1463
+ const tagTo = tag;
1464
+ const sender = this.safeValue(native, 'senders');
1465
+ const addressFrom = this.safeString(sender, 0);
1466
+ const amount = this.safeNumber(native, 'amount');
1467
+ const subType = this.safeString(transaction, 'subtype');
1468
+ const internal = subType === 'OFFCHAIN';
1469
+ // https://api.hitbtc.com/#check-if-offchain-is-available
1470
+ const fee = {
1471
+ 'currency': undefined,
1472
+ 'cost': undefined,
1473
+ 'rate': undefined,
1474
+ };
1475
+ const feeCost = this.safeNumber(native, 'fee');
1476
+ if (feeCost !== undefined) {
1477
+ fee['currency'] = code;
1478
+ fee['cost'] = feeCost;
1479
+ }
1480
+ return {
1481
+ 'info': transaction,
1482
+ 'id': id,
1483
+ 'txid': txhash,
1484
+ 'type': type,
1485
+ 'currency': code,
1486
+ 'network': undefined,
1487
+ 'amount': amount,
1488
+ 'status': status,
1489
+ 'timestamp': timestamp,
1490
+ 'datetime': this.iso8601(timestamp),
1491
+ 'address': address,
1492
+ 'addressFrom': addressFrom,
1493
+ 'addressTo': addressTo,
1494
+ 'tag': tag,
1495
+ 'tagFrom': undefined,
1496
+ 'tagTo': tagTo,
1497
+ 'updated': updated,
1498
+ 'comment': undefined,
1499
+ 'internal': internal,
1500
+ 'fee': fee,
1501
+ };
1502
+ }
1503
+ async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
1504
+ /**
1505
+ * @method
1506
+ * @name hitbtc#fetchDepositsWithdrawals
1507
+ * @description fetch history of deposits and withdrawals
1508
+ * @see https://api.hitbtc.com/#get-transactions-history
1509
+ * @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
1510
+ * @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
1511
+ * @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
1512
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1513
+ * @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1514
+ */
1515
+ return await this.fetchTransactionsHelper('DEPOSIT,WITHDRAW', code, since, limit, params);
1516
+ }
1517
+ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
1518
+ /**
1519
+ * @method
1520
+ * @name hitbtc#fetchDeposits
1521
+ * @description fetch all deposits made to an account
1522
+ * @see https://api.hitbtc.com/#get-transactions-history
1523
+ * @param {string} code unified currency code
1524
+ * @param {int} [since] the earliest time in ms to fetch deposits for
1525
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
1526
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1527
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1528
+ */
1529
+ return await this.fetchTransactionsHelper('DEPOSIT', code, since, limit, params);
1530
+ }
1531
+ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
1532
+ /**
1533
+ * @method
1534
+ * @name hitbtc#fetchWithdrawals
1535
+ * @description fetch all withdrawals made from an account
1536
+ * @see https://api.hitbtc.com/#get-transactions-history
1537
+ * @param {string} code unified currency code
1538
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
1539
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
1540
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1541
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1542
+ */
1543
+ return await this.fetchTransactionsHelper('WITHDRAW', code, since, limit, params);
1544
+ }
1545
+ async fetchOrderBooks(symbols = undefined, limit = undefined, params = {}) {
1546
+ /**
1547
+ * @method
1548
+ * @name hitbtc#fetchOrderBooks
1549
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data for multiple markets
1550
+ * @see https://api.hitbtc.com/#order-books
1551
+ * @param {string[]|undefined} symbols list of unified market symbols, all symbols fetched if undefined, default is undefined
1552
+ * @param {int} [limit] max number of entries per orderbook to return, default is undefined
1553
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1554
+ * @returns {object} a dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbol
1555
+ */
1556
+ await this.loadMarkets();
1557
+ const request = {};
1558
+ if (symbols !== undefined) {
1559
+ const marketIdsInner = this.marketIds(symbols);
1560
+ request['symbols'] = marketIdsInner.join(',');
1561
+ }
1562
+ if (limit !== undefined) {
1563
+ request['depth'] = limit;
1564
+ }
1565
+ const response = await this.publicGetPublicOrderbook(this.extend(request, params));
1566
+ const result = {};
1567
+ const marketIds = Object.keys(response);
1568
+ for (let i = 0; i < marketIds.length; i++) {
1569
+ const marketId = marketIds[i];
1570
+ const orderbook = response[marketId];
1571
+ const symbol = this.safeSymbol(marketId);
1572
+ const timestamp = this.parse8601(this.safeString(orderbook, 'timestamp'));
1573
+ result[symbol] = this.parseOrderBook(response[marketId], symbol, timestamp, 'bid', 'ask');
1574
+ }
1575
+ return result;
1576
+ }
1577
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
1578
+ /**
1579
+ * @method
1580
+ * @name hitbtc#fetchOrderBook
1581
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
1582
+ * @see https://api.hitbtc.com/#order-books
1583
+ * @param {string} symbol unified symbol of the market to fetch the order book for
1584
+ * @param {int} [limit] the maximum amount of order book entries to return
1585
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1586
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
1587
+ */
1588
+ await this.loadMarkets();
1589
+ const market = this.market(symbol);
1590
+ const request = {
1591
+ 'symbol': market['id'],
1592
+ };
1593
+ if (limit !== undefined) {
1594
+ request['depth'] = limit;
1595
+ }
1596
+ const response = await this.publicGetPublicOrderbookSymbol(this.extend(request, params));
1597
+ const timestamp = this.parse8601(this.safeString(response, 'timestamp'));
1598
+ return this.parseOrderBook(response, symbol, timestamp, 'bid', 'ask');
1599
+ }
1600
+ parseTradingFee(fee, market = undefined) {
1601
+ //
1602
+ // {
1603
+ // "symbol":"ARVUSDT", // returned from fetchTradingFees only
1604
+ // "take_rate":"0.0009",
1605
+ // "make_rate":"0.0009"
1606
+ // }
1607
+ //
1608
+ const taker = this.safeNumber(fee, 'take_rate');
1609
+ const maker = this.safeNumber(fee, 'make_rate');
1610
+ const marketId = this.safeString(fee, 'symbol');
1611
+ const symbol = this.safeSymbol(marketId, market);
1612
+ return {
1613
+ 'info': fee,
1614
+ 'symbol': symbol,
1615
+ 'taker': taker,
1616
+ 'maker': maker,
1617
+ };
1618
+ }
1619
+ async fetchTradingFee(symbol, params = {}) {
1620
+ /**
1621
+ * @method
1622
+ * @name hitbtc#fetchTradingFee
1623
+ * @description fetch the trading fees for a market
1624
+ * @see https://api.hitbtc.com/#get-trading-commission
1625
+ * @see https://api.hitbtc.com/#get-trading-commission-2
1626
+ * @param {string} symbol unified market symbol
1627
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1628
+ * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
1629
+ */
1630
+ await this.loadMarkets();
1631
+ const market = this.market(symbol);
1632
+ const request = {
1633
+ 'symbol': market['id'],
1634
+ };
1635
+ let response = undefined;
1636
+ if (market['type'] === 'spot') {
1637
+ response = await this.privateGetSpotFeeSymbol(this.extend(request, params));
1638
+ }
1639
+ else if (market['type'] === 'swap') {
1640
+ response = await this.privateGetFuturesFeeSymbol(this.extend(request, params));
1641
+ }
1642
+ else {
1643
+ throw new errors.NotSupported(this.id + ' fetchTradingFee() not support this market type');
1644
+ }
1645
+ //
1646
+ // {
1647
+ // "take_rate":"0.0009",
1648
+ // "make_rate":"0.0009"
1649
+ // }
1650
+ //
1651
+ return this.parseTradingFee(response, market);
1652
+ }
1653
+ async fetchTradingFees(params = {}) {
1654
+ /**
1655
+ * @method
1656
+ * @name hitbtc#fetchTradingFees
1657
+ * @description fetch the trading fees for multiple markets
1658
+ * @see https://api.hitbtc.com/#get-all-trading-commissions
1659
+ * @see https://api.hitbtc.com/#get-all-trading-commissions-2
1660
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1661
+ * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
1662
+ */
1663
+ await this.loadMarkets();
1664
+ const [marketType, query] = this.handleMarketTypeAndParams('fetchTradingFees', undefined, params);
1665
+ let response = undefined;
1666
+ if (marketType === 'spot') {
1667
+ response = await this.privateGetSpotFee(query);
1668
+ }
1669
+ else if (marketType === 'swap') {
1670
+ response = await this.privateGetFuturesFee(query);
1671
+ }
1672
+ else {
1673
+ throw new errors.NotSupported(this.id + ' fetchTradingFees() not support this market type');
1674
+ }
1675
+ //
1676
+ // [
1677
+ // {
1678
+ // "symbol":"ARVUSDT",
1679
+ // "take_rate":"0.0009",
1680
+ // "make_rate":"0.0009"
1681
+ // }
1682
+ // ]
1683
+ //
1684
+ const result = {};
1685
+ for (let i = 0; i < response.length; i++) {
1686
+ const fee = this.parseTradingFee(response[i]);
1687
+ const symbol = fee['symbol'];
1688
+ result[symbol] = fee;
1689
+ }
1690
+ return result;
1691
+ }
1692
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1693
+ /**
1694
+ * @method
1695
+ * @name hitbtc#fetchOHLCV
1696
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1697
+ * @see https://api.hitbtc.com/#candles
1698
+ * @see https://api.hitbtc.com/#futures-index-price-candles
1699
+ * @see https://api.hitbtc.com/#futures-mark-price-candles
1700
+ * @see https://api.hitbtc.com/#futures-premium-index-candles
1701
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1702
+ * @param {string} timeframe the length of time each candle represents
1703
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
1704
+ * @param {int} [limit] the maximum amount of candles to fetch
1705
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1706
+ * @param {int} [params.until] timestamp in ms of the latest funding rate
1707
+ * @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)
1708
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1709
+ */
1710
+ await this.loadMarkets();
1711
+ let paginate = false;
1712
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
1713
+ if (paginate) {
1714
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000);
1715
+ }
1716
+ const market = this.market(symbol);
1717
+ let request = {
1718
+ 'symbol': market['id'],
1719
+ 'period': this.safeString(this.timeframes, timeframe, timeframe),
1720
+ };
1721
+ [request, params] = this.handleUntilOption('till', request, params);
1722
+ if (since !== undefined) {
1723
+ request['from'] = this.iso8601(since);
1724
+ }
1725
+ if (limit !== undefined) {
1726
+ request['limit'] = limit;
1727
+ }
1728
+ const price = this.safeString(params, 'price');
1729
+ params = this.omit(params, 'price');
1730
+ let response = undefined;
1731
+ if (price === 'mark') {
1732
+ response = await this.publicGetPublicFuturesCandlesMarkPriceSymbol(this.extend(request, params));
1733
+ }
1734
+ else if (price === 'index') {
1735
+ response = await this.publicGetPublicFuturesCandlesIndexPriceSymbol(this.extend(request, params));
1736
+ }
1737
+ else if (price === 'premiumIndex') {
1738
+ response = await this.publicGetPublicFuturesCandlesPremiumIndexSymbol(this.extend(request, params));
1739
+ }
1740
+ else {
1741
+ response = await this.publicGetPublicCandlesSymbol(this.extend(request, params));
1742
+ }
1743
+ //
1744
+ // Spot and Swap
1745
+ //
1746
+ // [
1747
+ // {
1748
+ // "timestamp": "2021-10-25T07:38:00.000Z",
1749
+ // "open": "4173.391",
1750
+ // "close": "4170.923",
1751
+ // "min": "4170.923",
1752
+ // "max": "4173.986",
1753
+ // "volume": "0.1879",
1754
+ // "volume_quote": "784.2517846"
1755
+ // }
1756
+ // ]
1757
+ //
1758
+ // Mark, Index and Premium Index
1759
+ //
1760
+ // [
1761
+ // {
1762
+ // "timestamp": "2022-04-01T01:28:00.000Z",
1763
+ // "open": "45146.39",
1764
+ // "close": "45219.43",
1765
+ // "min": "45146.39",
1766
+ // "max": "45219.43"
1767
+ // },
1768
+ // ]
1769
+ //
1770
+ return this.parseOHLCVs(response, market, timeframe, since, limit);
1771
+ }
1772
+ parseOHLCV(ohlcv, market = undefined) {
1773
+ //
1774
+ // Spot and Swap
1775
+ //
1776
+ // {
1777
+ // "timestamp":"2015-08-20T19:01:00.000Z",
1778
+ // "open":"0.006",
1779
+ // "close":"0.006",
1780
+ // "min":"0.006",
1781
+ // "max":"0.006",
1782
+ // "volume":"0.003",
1783
+ // "volume_quote":"0.000018"
1784
+ // }
1785
+ //
1786
+ // Mark, Index and Premium Index
1787
+ //
1788
+ // {
1789
+ // "timestamp": "2022-04-01T01:28:00.000Z",
1790
+ // "open": "45146.39",
1791
+ // "close": "45219.43",
1792
+ // "min": "45146.39",
1793
+ // "max": "45219.43"
1794
+ // },
1795
+ //
1796
+ return [
1797
+ this.parse8601(this.safeString(ohlcv, 'timestamp')),
1798
+ this.safeNumber(ohlcv, 'open'),
1799
+ this.safeNumber(ohlcv, 'max'),
1800
+ this.safeNumber(ohlcv, 'min'),
1801
+ this.safeNumber(ohlcv, 'close'),
1802
+ this.safeNumber(ohlcv, 'volume'),
1803
+ ];
1804
+ }
1805
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1806
+ /**
1807
+ * @method
1808
+ * @name hitbtc#fetchClosedOrders
1809
+ * @description fetches information on multiple closed orders made by the user
1810
+ * @see https://api.hitbtc.com/#spot-orders-history
1811
+ * @see https://api.hitbtc.com/#futures-orders-history
1812
+ * @see https://api.hitbtc.com/#margin-orders-history
1813
+ * @param {string} symbol unified market symbol of the market orders were made in
1814
+ * @param {int} [since] the earliest time in ms to fetch orders for
1815
+ * @param {int} [limit] the maximum number of order structures to retrieve
1816
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1817
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
1818
+ * @param {bool} [params.margin] true for fetching margin orders
1819
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1820
+ */
1821
+ await this.loadMarkets();
1822
+ let market = undefined;
1823
+ const request = {};
1824
+ if (symbol !== undefined) {
1825
+ market = this.market(symbol);
1826
+ request['symbol'] = market['id'];
1827
+ }
1828
+ if (since !== undefined) {
1829
+ request['from'] = this.iso8601(since);
1830
+ }
1831
+ if (limit !== undefined) {
1832
+ request['limit'] = limit;
1833
+ }
1834
+ let marketType = undefined;
1835
+ let marginMode = undefined;
1836
+ [marketType, params] = this.handleMarketTypeAndParams('fetchClosedOrders', market, params);
1837
+ [marginMode, params] = this.handleMarginModeAndParams('fetchClosedOrders', params);
1838
+ params = this.omit(params, ['marginMode', 'margin']);
1839
+ let response = undefined;
1840
+ if (marginMode !== undefined) {
1841
+ response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
1842
+ }
1843
+ else {
1844
+ if (marketType === 'spot') {
1845
+ response = await this.privateGetSpotHistoryOrder(this.extend(request, params));
1846
+ }
1847
+ else if (marketType === 'swap') {
1848
+ response = await this.privateGetFuturesHistoryOrder(this.extend(request, params));
1849
+ }
1850
+ else if (marketType === 'margin') {
1851
+ response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
1852
+ }
1853
+ else {
1854
+ throw new errors.NotSupported(this.id + ' fetchClosedOrders() not support this market type');
1855
+ }
1856
+ }
1857
+ const parsed = this.parseOrders(response, market, since, limit);
1858
+ return this.filterByArray(parsed, 'status', ['closed', 'canceled'], false);
1859
+ }
1860
+ async fetchOrder(id, symbol = undefined, params = {}) {
1861
+ /**
1862
+ * @method
1863
+ * @name hitbtc#fetchOrder
1864
+ * @description fetches information on an order made by the user
1865
+ * @see https://api.hitbtc.com/#spot-orders-history
1866
+ * @see https://api.hitbtc.com/#futures-orders-history
1867
+ * @see https://api.hitbtc.com/#margin-orders-history
1868
+ * @param {string} symbol unified symbol of the market the order was made in
1869
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1870
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
1871
+ * @param {bool} [params.margin] true for fetching a margin order
1872
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1873
+ */
1874
+ await this.loadMarkets();
1875
+ let market = undefined;
1876
+ if (symbol !== undefined) {
1877
+ market = this.market(symbol);
1878
+ }
1879
+ const request = {
1880
+ 'client_order_id': id,
1881
+ };
1882
+ let marketType = undefined;
1883
+ let marginMode = undefined;
1884
+ [marketType, params] = this.handleMarketTypeAndParams('fetchOrder', market, params);
1885
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrder', params);
1886
+ params = this.omit(params, ['marginMode', 'margin']);
1887
+ let response = undefined;
1888
+ if (marginMode !== undefined) {
1889
+ response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
1890
+ }
1891
+ else {
1892
+ if (marketType === 'spot') {
1893
+ response = await this.privateGetSpotHistoryOrder(this.extend(request, params));
1894
+ }
1895
+ else if (marketType === 'swap') {
1896
+ response = await this.privateGetFuturesHistoryOrder(this.extend(request, params));
1897
+ }
1898
+ else if (marketType === 'margin') {
1899
+ response = await this.privateGetMarginHistoryOrder(this.extend(request, params));
1900
+ }
1901
+ else {
1902
+ throw new errors.NotSupported(this.id + ' fetchOrder() not support this market type');
1903
+ }
1904
+ }
1905
+ //
1906
+ // [
1907
+ // {
1908
+ // "id": "685965182082",
1909
+ // "client_order_id": "B3CBm9uGg9oYQlw96bBSEt38-6gbgBO0",
1910
+ // "symbol": "BTCUSDT",
1911
+ // "side": "buy",
1912
+ // "status": "new",
1913
+ // "type": "limit",
1914
+ // "time_in_force": "GTC",
1915
+ // "quantity": "0.00010",
1916
+ // "quantity_cumulative": "0",
1917
+ // "price": "50000.00",
1918
+ // "price_average": "0",
1919
+ // "created_at": "2021-10-26T11:40:09.287Z",
1920
+ // "updated_at": "2021-10-26T11:40:09.287Z"
1921
+ // }
1922
+ // ]
1923
+ //
1924
+ const order = this.safeValue(response, 0);
1925
+ return this.parseOrder(order, market);
1926
+ }
1927
+ async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1928
+ /**
1929
+ * @method
1930
+ * @name hitbtc#fetchOrderTrades
1931
+ * @description fetch all the trades made from a single order
1932
+ * @see https://api.hitbtc.com/#spot-trades-history
1933
+ * @see https://api.hitbtc.com/#futures-trades-history
1934
+ * @see https://api.hitbtc.com/#margin-trades-history
1935
+ * @param {string} id order id
1936
+ * @param {string} symbol unified market symbol
1937
+ * @param {int} [since] the earliest time in ms to fetch trades for
1938
+ * @param {int} [limit] the maximum number of trades to retrieve
1939
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1940
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
1941
+ * @param {bool} [params.margin] true for fetching margin trades
1942
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1943
+ */
1944
+ await this.loadMarkets();
1945
+ let market = undefined;
1946
+ if (symbol !== undefined) {
1947
+ market = this.market(symbol);
1948
+ }
1949
+ const request = {
1950
+ 'order_id': id, // exchange assigned order id as oppose to the client order id
1951
+ };
1952
+ let marketType = undefined;
1953
+ let marginMode = undefined;
1954
+ [marketType, params] = this.handleMarketTypeAndParams('fetchOrderTrades', market, params);
1955
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrderTrades', params);
1956
+ params = this.omit(params, ['marginMode', 'margin']);
1957
+ let response = undefined;
1958
+ if (marginMode !== undefined) {
1959
+ response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
1960
+ }
1961
+ else {
1962
+ if (marketType === 'spot') {
1963
+ response = await this.privateGetSpotHistoryTrade(this.extend(request, params));
1964
+ }
1965
+ else if (marketType === 'swap') {
1966
+ response = await this.privateGetFuturesHistoryTrade(this.extend(request, params));
1967
+ }
1968
+ else if (marketType === 'margin') {
1969
+ response = await this.privateGetMarginHistoryTrade(this.extend(request, params));
1970
+ }
1971
+ else {
1972
+ throw new errors.NotSupported(this.id + ' fetchOrderTrades() not support this market type');
1973
+ }
1974
+ }
1975
+ //
1976
+ // Spot
1977
+ //
1978
+ // [
1979
+ // {
1980
+ // "id": 1393448977,
1981
+ // "order_id": 653496804534,
1982
+ // "client_order_id": "065f6f0ff9d54547848454182263d7b4",
1983
+ // "symbol": "DICEETH",
1984
+ // "side": "buy",
1985
+ // "quantity": "1.4",
1986
+ // "price": "0.00261455",
1987
+ // "fee": "0.000003294333",
1988
+ // "timestamp": "2021-09-19T05:35:56.601Z",
1989
+ // "taker": true
1990
+ // }
1991
+ // ]
1992
+ //
1993
+ // Swap and Margin
1994
+ //
1995
+ // [
1996
+ // {
1997
+ // "id": 4718551,
1998
+ // "order_id": 58730748700,
1999
+ // "client_order_id": "dcbcd8549e3445ee922665946002ef67",
2000
+ // "symbol": "BTCUSDT_PERP",
2001
+ // "side": "buy",
2002
+ // "quantity": "0.0001",
2003
+ // "price": "41095.96",
2004
+ // "fee": "0.002054798000",
2005
+ // "timestamp": "2022-03-17T05:23:02.217Z",
2006
+ // "taker": true,
2007
+ // "position_id": 2350122,
2008
+ // "pnl": "0",
2009
+ // "liquidation": false
2010
+ // }
2011
+ // ]
2012
+ //
2013
+ return this.parseTrades(response, market, since, limit);
2014
+ }
2015
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2016
+ /**
2017
+ * @method
2018
+ * @name hitbtc#fetchOpenOrders
2019
+ * @description fetch all unfilled currently open orders
2020
+ * @see https://api.hitbtc.com/#get-all-active-spot-orders
2021
+ * @see https://api.hitbtc.com/#get-active-futures-orders
2022
+ * @see https://api.hitbtc.com/#get-active-margin-orders
2023
+ * @param {string} symbol unified market symbol
2024
+ * @param {int} [since] the earliest time in ms to fetch open orders for
2025
+ * @param {int} [limit] the maximum number of open orders structures to retrieve
2026
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2027
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
2028
+ * @param {bool} [params.margin] true for fetching open margin orders
2029
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2030
+ */
2031
+ await this.loadMarkets();
2032
+ let market = undefined;
2033
+ const request = {};
2034
+ if (symbol !== undefined) {
2035
+ market = this.market(symbol);
2036
+ request['symbol'] = market['id'];
2037
+ }
2038
+ let marketType = undefined;
2039
+ let marginMode = undefined;
2040
+ [marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
2041
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOpenOrders', params);
2042
+ params = this.omit(params, ['marginMode', 'margin']);
2043
+ let response = undefined;
2044
+ if (marginMode !== undefined) {
2045
+ response = await this.privateGetMarginOrder(this.extend(request, params));
2046
+ }
2047
+ else {
2048
+ if (marketType === 'spot') {
2049
+ response = await this.privateGetSpotOrder(this.extend(request, params));
2050
+ }
2051
+ else if (marketType === 'swap') {
2052
+ response = await this.privateGetFuturesOrder(this.extend(request, params));
2053
+ }
2054
+ else if (marketType === 'margin') {
2055
+ response = await this.privateGetMarginOrder(this.extend(request, params));
2056
+ }
2057
+ else {
2058
+ throw new errors.NotSupported(this.id + ' fetchOpenOrders() not support this market type');
2059
+ }
2060
+ }
2061
+ //
2062
+ // [
2063
+ // {
2064
+ // "id": "488953123149",
2065
+ // "client_order_id": "103ad305301e4c3590045b13de15b36e",
2066
+ // "symbol": "BTCUSDT",
2067
+ // "side": "buy",
2068
+ // "status": "new",
2069
+ // "type": "limit",
2070
+ // "time_in_force": "GTC",
2071
+ // "quantity": "0.00001",
2072
+ // "quantity_cumulative": "0",
2073
+ // "price": "0.01",
2074
+ // "post_only": false,
2075
+ // "created_at": "2021-04-13T13:06:16.567Z",
2076
+ // "updated_at": "2021-04-13T13:06:16.567Z"
2077
+ // }
2078
+ // ]
2079
+ //
2080
+ return this.parseOrders(response, market, since, limit);
2081
+ }
2082
+ async fetchOpenOrder(id, symbol = undefined, params = {}) {
2083
+ /**
2084
+ * @method
2085
+ * @name hitbtc#fetchOpenOrder
2086
+ * @description fetch an open order by it's id
2087
+ * @see https://api.hitbtc.com/#get-active-spot-order
2088
+ * @see https://api.hitbtc.com/#get-active-futures-order
2089
+ * @see https://api.hitbtc.com/#get-active-margin-order
2090
+ * @param {string} id order id
2091
+ * @param {string} symbol unified market symbol, default is undefined
2092
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2093
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
2094
+ * @param {bool} [params.margin] true for fetching an open margin order
2095
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2096
+ */
2097
+ await this.loadMarkets();
2098
+ let market = undefined;
2099
+ if (symbol !== undefined) {
2100
+ market = this.market(symbol);
2101
+ }
2102
+ const request = {
2103
+ 'client_order_id': id,
2104
+ };
2105
+ let marketType = undefined;
2106
+ let marginMode = undefined;
2107
+ [marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrder', market, params);
2108
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOpenOrder', params);
2109
+ params = this.omit(params, ['marginMode', 'margin']);
2110
+ let response = undefined;
2111
+ if (marginMode !== undefined) {
2112
+ response = await this.privateGetMarginOrderClientOrderId(this.extend(request, params));
2113
+ }
2114
+ else {
2115
+ if (marketType === 'spot') {
2116
+ response = await this.privateGetSpotOrderClientOrderId(this.extend(request, params));
2117
+ }
2118
+ else if (marketType === 'swap') {
2119
+ response = await this.privateGetFuturesOrderClientOrderId(this.extend(request, params));
2120
+ }
2121
+ else if (marketType === 'margin') {
2122
+ response = await this.privateGetMarginOrderClientOrderId(this.extend(request, params));
2123
+ }
2124
+ else {
2125
+ throw new errors.NotSupported(this.id + ' fetchOpenOrder() not support this market type');
2126
+ }
2127
+ }
2128
+ return this.parseOrder(response, market);
2129
+ }
2130
+ async cancelAllOrders(symbol = undefined, params = {}) {
2131
+ /**
2132
+ * @method
2133
+ * @name hitbtc#cancelAllOrders
2134
+ * @description cancel all open orders
2135
+ * @see https://api.hitbtc.com/#cancel-all-spot-orders
2136
+ * @see https://api.hitbtc.com/#cancel-futures-orders
2137
+ * @see https://api.hitbtc.com/#cancel-all-margin-orders
2138
+ * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
2139
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2140
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
2141
+ * @param {bool} [params.margin] true for canceling margin orders
2142
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2143
+ */
2144
+ await this.loadMarkets();
2145
+ let market = undefined;
2146
+ const request = {};
2147
+ if (symbol !== undefined) {
2148
+ market = this.market(symbol);
2149
+ request['symbol'] = market['id'];
2150
+ }
2151
+ let marketType = undefined;
2152
+ let marginMode = undefined;
2153
+ [marketType, params] = this.handleMarketTypeAndParams('cancelAllOrders', market, params);
2154
+ [marginMode, params] = this.handleMarginModeAndParams('cancelAllOrders', params);
2155
+ params = this.omit(params, ['marginMode', 'margin']);
2156
+ let response = undefined;
2157
+ if (marginMode !== undefined) {
2158
+ response = await this.privateDeleteMarginOrder(this.extend(request, params));
2159
+ }
2160
+ else {
2161
+ if (marketType === 'spot') {
2162
+ response = await this.privateDeleteSpotOrder(this.extend(request, params));
2163
+ }
2164
+ else if (marketType === 'swap') {
2165
+ response = await this.privateDeleteFuturesOrder(this.extend(request, params));
2166
+ }
2167
+ else if (marketType === 'margin') {
2168
+ response = await this.privateDeleteMarginOrder(this.extend(request, params));
2169
+ }
2170
+ else {
2171
+ throw new errors.NotSupported(this.id + ' cancelAllOrders() not support this market type');
2172
+ }
2173
+ }
2174
+ return this.parseOrders(response, market);
2175
+ }
2176
+ async cancelOrder(id, symbol = undefined, params = {}) {
2177
+ /**
2178
+ * @method
2179
+ * @name hitbtc#cancelOrder
2180
+ * @description cancels an open order
2181
+ * @see https://api.hitbtc.com/#cancel-spot-order
2182
+ * @see https://api.hitbtc.com/#cancel-futures-order
2183
+ * @see https://api.hitbtc.com/#cancel-margin-order
2184
+ * @param {string} id order id
2185
+ * @param {string} symbol unified symbol of the market the order was made in
2186
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2187
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported
2188
+ * @param {bool} [params.margin] true for canceling a margin order
2189
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2190
+ */
2191
+ await this.loadMarkets();
2192
+ let market = undefined;
2193
+ const request = {
2194
+ 'client_order_id': id,
2195
+ };
2196
+ if (symbol !== undefined) {
2197
+ market = this.market(symbol);
2198
+ }
2199
+ let marketType = undefined;
2200
+ let marginMode = undefined;
2201
+ [marketType, params] = this.handleMarketTypeAndParams('cancelOrder', market, params);
2202
+ [marginMode, params] = this.handleMarginModeAndParams('cancelOrder', params);
2203
+ params = this.omit(params, ['marginMode', 'margin']);
2204
+ let response = undefined;
2205
+ if (marginMode !== undefined) {
2206
+ response = await this.privateDeleteMarginOrderClientOrderId(this.extend(request, params));
2207
+ }
2208
+ else {
2209
+ if (marketType === 'spot') {
2210
+ response = await this.privateDeleteSpotOrderClientOrderId(this.extend(request, params));
2211
+ }
2212
+ else if (marketType === 'swap') {
2213
+ response = await this.privateDeleteFuturesOrderClientOrderId(this.extend(request, params));
2214
+ }
2215
+ else if (marketType === 'margin') {
2216
+ response = await this.privateDeleteMarginOrderClientOrderId(this.extend(request, params));
2217
+ }
2218
+ else {
2219
+ throw new errors.NotSupported(this.id + ' cancelOrder() not support this market type');
2220
+ }
2221
+ }
2222
+ return this.parseOrder(response, market);
2223
+ }
2224
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
2225
+ await this.loadMarkets();
2226
+ let market = undefined;
2227
+ const request = {
2228
+ 'client_order_id': id,
2229
+ 'quantity': this.amountToPrecision(symbol, amount),
2230
+ };
2231
+ if ((type === 'limit') || (type === 'stopLimit')) {
2232
+ if (price === undefined) {
2233
+ throw new errors.ExchangeError(this.id + ' editOrder() limit order requires price');
2234
+ }
2235
+ request['price'] = this.priceToPrecision(symbol, price);
2236
+ }
2237
+ if (symbol !== undefined) {
2238
+ market = this.market(symbol);
2239
+ }
2240
+ let marketType = undefined;
2241
+ let marginMode = undefined;
2242
+ [marketType, params] = this.handleMarketTypeAndParams('editOrder', market, params);
2243
+ [marginMode, params] = this.handleMarginModeAndParams('editOrder', params);
2244
+ params = this.omit(params, ['marginMode', 'margin']);
2245
+ let response = undefined;
2246
+ if (marginMode !== undefined) {
2247
+ response = await this.privatePatchMarginOrderClientOrderId(this.extend(request, params));
2248
+ }
2249
+ else {
2250
+ if (marketType === 'spot') {
2251
+ response = await this.privatePatchSpotOrderClientOrderId(this.extend(request, params));
2252
+ }
2253
+ else if (marketType === 'swap') {
2254
+ response = await this.privatePatchFuturesOrderClientOrderId(this.extend(request, params));
2255
+ }
2256
+ else if (marketType === 'margin') {
2257
+ response = await this.privatePatchMarginOrderClientOrderId(this.extend(request, params));
2258
+ }
2259
+ else {
2260
+ throw new errors.NotSupported(this.id + ' editOrder() not support this market type');
2261
+ }
2262
+ }
2263
+ return this.parseOrder(response, market);
2264
+ }
2265
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
2266
+ /**
2267
+ * @method
2268
+ * @name hitbtc#createOrder
2269
+ * @description create a trade order
2270
+ * @see https://api.hitbtc.com/#create-new-spot-order
2271
+ * @see https://api.hitbtc.com/#create-margin-order
2272
+ * @see https://api.hitbtc.com/#create-futures-order
2273
+ * @param {string} symbol unified symbol of the market to create an order in
2274
+ * @param {string} type 'market' or 'limit'
2275
+ * @param {string} side 'buy' or 'sell'
2276
+ * @param {float} amount how much of currency you want to trade in units of base currency
2277
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
2278
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2279
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported for spot-margin, swap supports both, default is 'cross'
2280
+ * @param {bool} [params.margin] true for creating a margin order
2281
+ * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
2282
+ * @param {bool} [params.postOnly] if true, the order will only be posted to the order book and not executed immediately
2283
+ * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", "Day", "GTD"
2284
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2285
+ */
2286
+ await this.loadMarkets();
2287
+ const market = this.market(symbol);
2288
+ let request = undefined;
2289
+ let marketType = undefined;
2290
+ [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
2291
+ let marginMode = undefined;
2292
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
2293
+ [request, params] = this.createOrderRequest(market, marketType, type, side, amount, price, marginMode, params);
2294
+ let response = undefined;
2295
+ if (marketType === 'swap') {
2296
+ response = await this.privatePostFuturesOrder(this.extend(request, params));
2297
+ }
2298
+ else if ((marketType === 'margin') || (marginMode !== undefined)) {
2299
+ response = await this.privatePostMarginOrder(this.extend(request, params));
2300
+ }
2301
+ else {
2302
+ response = await this.privatePostSpotOrder(this.extend(request, params));
2303
+ }
2304
+ return this.parseOrder(response, market);
2305
+ }
2306
+ createOrderRequest(market, marketType, type, side, amount, price = undefined, marginMode = undefined, params = {}) {
2307
+ const isLimit = (type === 'limit');
2308
+ const reduceOnly = this.safeValue(params, 'reduceOnly');
2309
+ const timeInForce = this.safeString(params, 'timeInForce');
2310
+ const triggerPrice = this.safeNumberN(params, ['triggerPrice', 'stopPrice', 'stop_price']);
2311
+ const isPostOnly = this.isPostOnly(type === 'market', undefined, params);
2312
+ const request = {
2313
+ 'type': type,
2314
+ 'side': side,
2315
+ 'quantity': this.amountToPrecision(market['symbol'], amount),
2316
+ 'symbol': market['id'],
2317
+ // 'client_order_id': 'r42gdPjNMZN-H_xs8RKl2wljg_dfgdg4', // Optional
2318
+ // 'time_in_force': 'GTC', // Optional GTC, IOC, FOK, Day, GTD
2319
+ // 'price': this.priceToPrecision (symbol, price), // Required if type is limit, stopLimit, or takeProfitLimit
2320
+ // 'stop_price': this.safeNumber (params, 'stop_price'), // Required if type is stopLimit, stopMarket, takeProfitLimit, takeProfitMarket
2321
+ // 'expire_time': '2021-06-15T17:01:05.092Z', // Required if timeInForce is GTD
2322
+ // 'strict_validate': false,
2323
+ // 'post_only': false, // Optional
2324
+ // 'reduce_only': false, // Optional
2325
+ // 'display_quantity': '0', // Optional
2326
+ // 'take_rate': 0.001, // Optional
2327
+ // 'make_rate': 0.001, // Optional
2328
+ };
2329
+ if (reduceOnly !== undefined) {
2330
+ if ((market['type'] !== 'swap') && (market['type'] !== 'margin')) {
2331
+ throw new errors.InvalidOrder(this.id + ' createOrder() does not support reduce_only for ' + market['type'] + ' orders, reduce_only orders are supported for swap and margin markets only');
2332
+ }
2333
+ }
2334
+ if (reduceOnly === true) {
2335
+ request['reduce_only'] = reduceOnly;
2336
+ }
2337
+ if (isPostOnly) {
2338
+ request['post_only'] = true;
2339
+ }
2340
+ if (timeInForce !== undefined) {
2341
+ request['time_in_force'] = timeInForce;
2342
+ }
2343
+ if (isLimit || (type === 'stopLimit') || (type === 'takeProfitLimit')) {
2344
+ if (price === undefined) {
2345
+ throw new errors.ExchangeError(this.id + ' createOrder() requires a price argument for limit orders');
2346
+ }
2347
+ request['price'] = this.priceToPrecision(market['symbol'], price);
2348
+ }
2349
+ if ((timeInForce === 'GTD')) {
2350
+ const expireTime = this.safeString(params, 'expire_time');
2351
+ if (expireTime === undefined) {
2352
+ throw new errors.ExchangeError(this.id + ' createOrder() requires an expire_time parameter for a GTD order');
2353
+ }
2354
+ }
2355
+ if (triggerPrice !== undefined) {
2356
+ request['stop_price'] = this.priceToPrecision(market['symbol'], triggerPrice);
2357
+ if (isLimit) {
2358
+ request['type'] = 'stopLimit';
2359
+ }
2360
+ else if (type === 'market') {
2361
+ request['type'] = 'stopMarket';
2362
+ }
2363
+ }
2364
+ else if ((type === 'stopLimit') || (type === 'stopMarket') || (type === 'takeProfitLimit') || (type === 'takeProfitMarket')) {
2365
+ throw new errors.ExchangeError(this.id + ' createOrder() requires a stopPrice parameter for stop-loss and take-profit orders');
2366
+ }
2367
+ params = this.omit(params, ['triggerPrice', 'timeInForce', 'stopPrice', 'stop_price', 'reduceOnly', 'postOnly']);
2368
+ if (marketType === 'swap') {
2369
+ // set default margin mode to cross
2370
+ if (marginMode === undefined) {
2371
+ marginMode = 'cross';
2372
+ }
2373
+ request['margin_mode'] = marginMode;
2374
+ }
2375
+ return [request, params];
2376
+ }
2377
+ parseOrderStatus(status) {
2378
+ const statuses = {
2379
+ 'new': 'open',
2380
+ 'suspended': 'open',
2381
+ 'partiallyFilled': 'open',
2382
+ 'filled': 'closed',
2383
+ 'canceled': 'canceled',
2384
+ 'expired': 'failed',
2385
+ };
2386
+ return this.safeString(statuses, status, status);
2387
+ }
2388
+ parseOrder(order, market = undefined) {
2389
+ //
2390
+ // limit
2391
+ // {
2392
+ // "id": 488953123149,
2393
+ // "client_order_id": "103ad305301e4c3590045b13de15b36e",
2394
+ // "symbol": "BTCUSDT",
2395
+ // "side": "buy",
2396
+ // "status": "new",
2397
+ // "type": "limit",
2398
+ // "time_in_force": "GTC",
2399
+ // "quantity": "0.00001",
2400
+ // "quantity_cumulative": "0",
2401
+ // "price": "0.01",
2402
+ // "price_average": "0.01",
2403
+ // "post_only": false,
2404
+ // "created_at": "2021-04-13T13:06:16.567Z",
2405
+ // "updated_at": "2021-04-13T13:06:16.567Z"
2406
+ // }
2407
+ //
2408
+ // market
2409
+ // {
2410
+ // "id": "685877626834",
2411
+ // "client_order_id": "Yshl7G-EjaREyXQYaGbsmdtVbW-nzQwu",
2412
+ // "symbol": "BTCUSDT",
2413
+ // "side": "buy",
2414
+ // "status": "filled",
2415
+ // "type": "market",
2416
+ // "time_in_force": "GTC",
2417
+ // "quantity": "0.00010",
2418
+ // "quantity_cumulative": "0.00010",
2419
+ // "post_only": false,
2420
+ // "created_at": "2021-10-26T08:55:55.1Z",
2421
+ // "updated_at": "2021-10-26T08:55:55.1Z",
2422
+ // "trades": [
2423
+ // {
2424
+ // "id": "1437229630",
2425
+ // "position_id": "0",
2426
+ // "quantity": "0.00010",
2427
+ // "price": "62884.78",
2428
+ // "fee": "0.005659630200",
2429
+ // "timestamp": "2021-10-26T08:55:55.1Z",
2430
+ // "taker": true
2431
+ // }
2432
+ // ]
2433
+ // }
2434
+ //
2435
+ // swap and margin
2436
+ //
2437
+ // {
2438
+ // "id": 58418961892,
2439
+ // "client_order_id": "r42gdPjNMZN-H_xs8RKl2wljg_dfgdg4",
2440
+ // "symbol": "BTCUSDT_PERP",
2441
+ // "side": "buy",
2442
+ // "status": "new",
2443
+ // "type": "limit",
2444
+ // "time_in_force": "GTC",
2445
+ // "quantity": "0.0005",
2446
+ // "quantity_cumulative": "0",
2447
+ // "price": "30000.00",
2448
+ // "post_only": false,
2449
+ // "reduce_only": false,
2450
+ // "created_at": "2022-03-16T08:16:53.039Z",
2451
+ // "updated_at": "2022-03-16T08:16:53.039Z"
2452
+ // }
2453
+ //
2454
+ const id = this.safeString(order, 'client_order_id');
2455
+ // we use clientOrderId as the order id with this exchange intentionally
2456
+ // because most of their endpoints will require clientOrderId
2457
+ // explained here: https://github.com/ccxt/ccxt/issues/5674
2458
+ const side = this.safeString(order, 'side');
2459
+ const type = this.safeString(order, 'type');
2460
+ const amount = this.safeString(order, 'quantity');
2461
+ const price = this.safeString(order, 'price');
2462
+ const average = this.safeString(order, 'price_average');
2463
+ const created = this.safeString(order, 'created_at');
2464
+ const timestamp = this.parse8601(created);
2465
+ const updated = this.safeString(order, 'updated_at');
2466
+ let lastTradeTimestamp = undefined;
2467
+ if (updated !== created) {
2468
+ lastTradeTimestamp = this.parse8601(updated);
2469
+ }
2470
+ const filled = this.safeString(order, 'quantity_cumulative');
2471
+ const status = this.parseOrderStatus(this.safeString(order, 'status'));
2472
+ const marketId = this.safeString(order, 'symbol');
2473
+ market = this.safeMarket(marketId, market);
2474
+ const symbol = market['symbol'];
2475
+ const postOnly = this.safeValue(order, 'post_only');
2476
+ const timeInForce = this.safeString(order, 'time_in_force');
2477
+ const rawTrades = this.safeValue(order, 'trades');
2478
+ const stopPrice = this.safeString(order, 'stop_price');
2479
+ return this.safeOrder({
2480
+ 'info': order,
2481
+ 'id': id,
2482
+ 'clientOrderId': id,
2483
+ 'timestamp': timestamp,
2484
+ 'datetime': this.iso8601(timestamp),
2485
+ 'lastTradeTimestamp': lastTradeTimestamp,
2486
+ 'lastUpdateTimestamp': lastTradeTimestamp,
2487
+ 'symbol': symbol,
2488
+ 'price': price,
2489
+ 'amount': amount,
2490
+ 'type': type,
2491
+ 'side': side,
2492
+ 'timeInForce': timeInForce,
2493
+ 'postOnly': postOnly,
2494
+ 'reduceOnly': this.safeValue(order, 'reduce_only'),
2495
+ 'filled': filled,
2496
+ 'remaining': undefined,
2497
+ 'cost': undefined,
2498
+ 'status': status,
2499
+ 'average': average,
2500
+ 'trades': rawTrades,
2501
+ 'fee': undefined,
2502
+ 'stopPrice': stopPrice,
2503
+ 'triggerPrice': stopPrice,
2504
+ 'takeProfitPrice': undefined,
2505
+ 'stopLossPrice': undefined,
2506
+ }, market);
2507
+ }
2508
+ async fetchMarginMode(symbol = undefined, params = {}) {
2509
+ /**
2510
+ * @method
2511
+ * @name hitbtc#fetchMarginMode
2512
+ * @description fetches margin mode of the user
2513
+ * @see https://api.hitbtc.com/#get-margin-position-parameters
2514
+ * @see https://api.hitbtc.com/#get-futures-position-parameters
2515
+ * @param {string} symbol unified symbol of the market the order was made in
2516
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2517
+ * @returns {object} Struct of MarginMode
2518
+ */
2519
+ await this.loadMarkets();
2520
+ let market = undefined;
2521
+ if (symbol !== undefined) {
2522
+ market = this.market(symbol);
2523
+ }
2524
+ let marketType = undefined;
2525
+ [marketType, params] = this.handleMarketTypeAndParams('fetchMarginMode', market, params);
2526
+ let response = undefined;
2527
+ if (marketType === 'margin') {
2528
+ response = await this.privateGetMarginConfig(params);
2529
+ }
2530
+ else if (marketType === 'swap') {
2531
+ response = await this.privateGetFuturesConfig(params);
2532
+ }
2533
+ else {
2534
+ throw new errors.BadSymbol(this.id + ' fetchMarginMode() supports swap contracts and margin only');
2535
+ }
2536
+ //
2537
+ // margin
2538
+ // {
2539
+ // "config": [{
2540
+ // "symbol": "BTCUSD",
2541
+ // "margin_call_leverage_mul": "1.50",
2542
+ // "liquidation_leverage_mul": "2.00",
2543
+ // "max_initial_leverage": "10.00",
2544
+ // "margin_mode": "Isolated",
2545
+ // "force_close_fee": "0.05",
2546
+ // "enabled": true,
2547
+ // "active": true,
2548
+ // "limit_base": "50000.00",
2549
+ // "limit_power": "2.2",
2550
+ // "unlimited_threshold": "10.0"
2551
+ // }]
2552
+ // }
2553
+ //
2554
+ // swap
2555
+ // {
2556
+ // "config": [{
2557
+ // "symbol": "BTCUSD_PERP",
2558
+ // "margin_call_leverage_mul": "1.20",
2559
+ // "liquidation_leverage_mul": "2.00",
2560
+ // "max_initial_leverage": "100.00",
2561
+ // "margin_mode": "Isolated",
2562
+ // "force_close_fee": "0.001",
2563
+ // "enabled": true,
2564
+ // "active": false,
2565
+ // "limit_base": "5000000.000000000000",
2566
+ // "limit_power": "1.25",
2567
+ // "unlimited_threshold": "2.00"
2568
+ // }]
2569
+ // }
2570
+ //
2571
+ const config = this.safeValue(response, 'config', []);
2572
+ const marginModes = [];
2573
+ for (let i = 0; i < config.length; i++) {
2574
+ const data = this.safeValue(config, i);
2575
+ const marketId = this.safeString(data, 'symbol');
2576
+ const marketInner = this.safeMarket(marketId);
2577
+ marginModes.push({
2578
+ 'info': data,
2579
+ 'symbol': this.safeString(marketInner, 'symbol'),
2580
+ 'marginMode': this.safeStringLower(data, 'margin_mode'),
2581
+ });
2582
+ }
2583
+ const filteredMargin = this.filterBySymbol(marginModes, symbol);
2584
+ return this.safeValue(filteredMargin, 0);
2585
+ }
2586
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
2587
+ /**
2588
+ * @method
2589
+ * @name hitbtc#transfer
2590
+ * @description transfer currency internally between wallets on the same account
2591
+ * @see https://api.hitbtc.com/#transfer-between-wallet-and-exchange
2592
+ * @param {string} code unified currency code
2593
+ * @param {float} amount amount to transfer
2594
+ * @param {string} fromAccount account to transfer from
2595
+ * @param {string} toAccount account to transfer to
2596
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2597
+ * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2598
+ */
2599
+ // account can be "spot", "wallet", or "derivatives"
2600
+ await this.loadMarkets();
2601
+ const currency = this.currency(code);
2602
+ const requestAmount = this.currencyToPrecision(code, amount);
2603
+ const accountsByType = this.safeValue(this.options, 'accountsByType', {});
2604
+ fromAccount = fromAccount.toLowerCase();
2605
+ toAccount = toAccount.toLowerCase();
2606
+ const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
2607
+ const toId = this.safeString(accountsByType, toAccount, toAccount);
2608
+ if (fromId === toId) {
2609
+ throw new errors.BadRequest(this.id + ' transfer() fromAccount and toAccount arguments cannot be the same account');
2610
+ }
2611
+ const request = {
2612
+ 'currency': currency['id'],
2613
+ 'amount': requestAmount,
2614
+ 'source': fromId,
2615
+ 'destination': toId,
2616
+ };
2617
+ const response = await this.privatePostWalletTransfer(this.extend(request, params));
2618
+ //
2619
+ // [
2620
+ // "2db6ebab-fb26-4537-9ef8-1a689472d236"
2621
+ // ]
2622
+ //
2623
+ return this.parseTransfer(response, currency);
2624
+ }
2625
+ parseTransfer(transfer, currency = undefined) {
2626
+ //
2627
+ // transfer
2628
+ //
2629
+ // [
2630
+ // "2db6ebab-fb26-4537-9ef8-1a689472d236"
2631
+ // ]
2632
+ //
2633
+ return {
2634
+ 'id': this.safeString(transfer, 0),
2635
+ 'timestamp': undefined,
2636
+ 'datetime': undefined,
2637
+ 'currency': this.safeCurrencyCode(undefined, currency),
2638
+ 'amount': undefined,
2639
+ 'fromAccount': undefined,
2640
+ 'toAccount': undefined,
2641
+ 'status': undefined,
2642
+ 'info': transfer,
2643
+ };
2644
+ }
2645
+ async convertCurrencyNetwork(code, amount, fromNetwork, toNetwork, params) {
2646
+ await this.loadMarkets();
2647
+ if (code !== 'USDT') {
2648
+ throw new errors.ExchangeError(this.id + ' convertCurrencyNetwork() only supports USDT currently');
2649
+ }
2650
+ const networks = this.safeValue(this.options, 'networks', {});
2651
+ fromNetwork = fromNetwork.toUpperCase();
2652
+ toNetwork = toNetwork.toUpperCase();
2653
+ fromNetwork = this.safeString(networks, fromNetwork); // handle ETH>ERC20 alias
2654
+ toNetwork = this.safeString(networks, toNetwork); // handle ETH>ERC20 alias
2655
+ if (fromNetwork === toNetwork) {
2656
+ throw new errors.BadRequest(this.id + ' convertCurrencyNetwork() fromNetwork cannot be the same as toNetwork');
2657
+ }
2658
+ if ((fromNetwork === undefined) || (toNetwork === undefined)) {
2659
+ const keys = Object.keys(networks);
2660
+ throw new errors.ArgumentsRequired(this.id + ' convertCurrencyNetwork() requires a fromNetwork parameter and a toNetwork parameter, supported networks are ' + keys.join(', '));
2661
+ }
2662
+ const request = {
2663
+ 'from_currency': fromNetwork,
2664
+ 'to_currency': toNetwork,
2665
+ 'amount': this.currencyToPrecision(code, amount),
2666
+ };
2667
+ const response = await this.privatePostWalletConvert(this.extend(request, params));
2668
+ // {"result":["587a1868-e62d-4d8e-b27c-dbdb2ee96149","e168df74-c041-41f2-b76c-e43e4fed5bc7"]}
2669
+ return {
2670
+ 'info': response,
2671
+ };
2672
+ }
2673
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
2674
+ /**
2675
+ * @method
2676
+ * @name hitbtc#withdraw
2677
+ * @description make a withdrawal
2678
+ * @see https://api.hitbtc.com/#withdraw-crypto
2679
+ * @param {string} code unified currency code
2680
+ * @param {float} amount the amount to withdraw
2681
+ * @param {string} address the address to withdraw to
2682
+ * @param {string} tag
2683
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2684
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2685
+ */
2686
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
2687
+ await this.loadMarkets();
2688
+ this.checkAddress(address);
2689
+ const currency = this.currency(code);
2690
+ const request = {
2691
+ 'currency': currency['id'],
2692
+ 'amount': amount,
2693
+ 'address': address,
2694
+ };
2695
+ if (tag !== undefined) {
2696
+ request['payment_id'] = tag;
2697
+ }
2698
+ const networks = this.safeValue(this.options, 'networks', {});
2699
+ const network = this.safeStringUpper(params, 'network');
2700
+ if ((network !== undefined) && (code === 'USDT')) {
2701
+ const parsedNetwork = this.safeString(networks, network);
2702
+ if (parsedNetwork !== undefined) {
2703
+ request['currency'] = parsedNetwork;
2704
+ }
2705
+ params = this.omit(params, 'network');
2706
+ }
2707
+ const withdrawOptions = this.safeValue(this.options, 'withdraw', {});
2708
+ const includeFee = this.safeValue(withdrawOptions, 'includeFee', false);
2709
+ if (includeFee) {
2710
+ request['include_fee'] = true;
2711
+ }
2712
+ const response = await this.privatePostWalletCryptoWithdraw(this.extend(request, params));
2713
+ //
2714
+ // {
2715
+ // "id":"084cfcd5-06b9-4826-882e-fdb75ec3625d"
2716
+ // }
2717
+ //
2718
+ return this.parseTransaction(response, currency);
2719
+ }
2720
+ async fetchFundingRates(symbols = undefined, params = {}) {
2721
+ /**
2722
+ * @method
2723
+ * @name hitbtc#fetchFundingRates
2724
+ * @description fetches funding rates for multiple markets
2725
+ * @see https://api.hitbtc.com/#futures-info
2726
+ * @param {string[]} symbols unified symbols of the markets to fetch the funding rates for, all market funding rates are returned if not assigned
2727
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2728
+ * @returns {object} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
2729
+ */
2730
+ await this.loadMarkets();
2731
+ let market = undefined;
2732
+ const request = {};
2733
+ if (symbols !== undefined) {
2734
+ symbols = this.marketSymbols(symbols);
2735
+ market = this.market(symbols[0]);
2736
+ const queryMarketIds = this.marketIds(symbols);
2737
+ request['symbols'] = queryMarketIds.join(',');
2738
+ }
2739
+ let type = undefined;
2740
+ [type, params] = this.handleMarketTypeAndParams('fetchFundingRates', market, params);
2741
+ if (type !== 'swap') {
2742
+ throw new errors.NotSupported(this.id + ' fetchFundingRates() does not support ' + type + ' markets');
2743
+ }
2744
+ const response = await this.publicGetPublicFuturesInfo(this.extend(request, params));
2745
+ //
2746
+ // {
2747
+ // "BTCUSDT_PERP": {
2748
+ // "contract_type": "perpetual",
2749
+ // "mark_price": "30897.68",
2750
+ // "index_price": "30895.29",
2751
+ // "funding_rate": "0.0001",
2752
+ // "open_interest": "93.7128",
2753
+ // "next_funding_time": "2021-07-21T16:00:00.000Z",
2754
+ // "indicative_funding_rate": "0.0001",
2755
+ // "premium_index": "0.000047541807127312",
2756
+ // "avg_premium_index": "0.000087063368020112",
2757
+ // "interest_rate": "0.0001",
2758
+ // "timestamp": "2021-07-21T09:48:37.235Z"
2759
+ // }
2760
+ // }
2761
+ //
2762
+ const marketIds = Object.keys(response);
2763
+ const fundingRates = {};
2764
+ for (let i = 0; i < marketIds.length; i++) {
2765
+ const marketId = this.safeString(marketIds, i);
2766
+ const rawFundingRate = this.safeValue(response, marketId);
2767
+ const marketInner = this.market(marketId);
2768
+ const symbol = marketInner['symbol'];
2769
+ const fundingRate = this.parseFundingRate(rawFundingRate, marketInner);
2770
+ fundingRates[symbol] = fundingRate;
2771
+ }
2772
+ return this.filterByArray(fundingRates, 'symbol', symbols);
2773
+ }
2774
+ async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2775
+ /**
2776
+ * @method
2777
+ * @name hitbtc#fetchFundingRateHistory
2778
+ * @see https://api.hitbtc.com/#funding-history
2779
+ * @description fetches historical funding rate prices
2780
+ * @param {string} symbol unified symbol of the market to fetch the funding rate history for
2781
+ * @param {int} [since] timestamp in ms of the earliest funding rate to fetch
2782
+ * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
2783
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2784
+ * @param {int} [params.until] timestamp in ms of the latest funding rate
2785
+ * @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)
2786
+ * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
2787
+ */
2788
+ await this.loadMarkets();
2789
+ let paginate = false;
2790
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
2791
+ if (paginate) {
2792
+ return await this.fetchPaginatedCallDeterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 1000);
2793
+ }
2794
+ let market = undefined;
2795
+ let request = {
2796
+ // all arguments are optional
2797
+ // 'symbols': Comma separated list of symbol codes,
2798
+ // 'sort': 'DESC' or 'ASC'
2799
+ // 'from': 'Datetime or Number',
2800
+ // 'till': 'Datetime or Number',
2801
+ // 'limit': 100,
2802
+ // 'offset': 0,
2803
+ };
2804
+ [request, params] = this.handleUntilOption('till', request, params);
2805
+ if (symbol !== undefined) {
2806
+ market = this.market(symbol);
2807
+ symbol = market['symbol'];
2808
+ request['symbols'] = market['id'];
2809
+ }
2810
+ if (since !== undefined) {
2811
+ request['from'] = since;
2812
+ }
2813
+ if (limit !== undefined) {
2814
+ request['limit'] = limit;
2815
+ }
2816
+ const response = await this.publicGetPublicFuturesHistoryFunding(this.extend(request, params));
2817
+ //
2818
+ // {
2819
+ // "BTCUSDT_PERP": [
2820
+ // {
2821
+ // "timestamp": "2021-07-29T16:00:00.271Z",
2822
+ // "funding_rate": "0.0001",
2823
+ // "avg_premium_index": "0.000061858585213222",
2824
+ // "next_funding_time": "2021-07-30T00:00:00.000Z",
2825
+ // "interest_rate": "0.0001"
2826
+ // },
2827
+ // ...
2828
+ // ],
2829
+ // ...
2830
+ // }
2831
+ //
2832
+ const contracts = Object.keys(response);
2833
+ const rates = [];
2834
+ for (let i = 0; i < contracts.length; i++) {
2835
+ const marketId = contracts[i];
2836
+ const marketInner = this.safeMarket(marketId);
2837
+ const fundingRateData = response[marketId];
2838
+ for (let j = 0; j < fundingRateData.length; j++) {
2839
+ const entry = fundingRateData[j];
2840
+ const symbolInner = this.safeSymbol(marketInner['symbol']);
2841
+ const fundingRate = this.safeNumber(entry, 'funding_rate');
2842
+ const datetime = this.safeString(entry, 'timestamp');
2843
+ rates.push({
2844
+ 'info': entry,
2845
+ 'symbol': symbolInner,
2846
+ 'fundingRate': fundingRate,
2847
+ 'timestamp': this.parse8601(datetime),
2848
+ 'datetime': datetime,
2849
+ });
2850
+ }
2851
+ }
2852
+ const sorted = this.sortBy(rates, 'timestamp');
2853
+ return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
2854
+ }
2855
+ async fetchPositions(symbols = undefined, params = {}) {
2856
+ /**
2857
+ * @method
2858
+ * @name hitbtc#fetchPositions
2859
+ * @description fetch all open positions
2860
+ * @see https://api.hitbtc.com/#get-futures-margin-accounts
2861
+ * @see https://api.hitbtc.com/#get-all-margin-accounts
2862
+ * @param {string[]|undefined} symbols not used by hitbtc fetchPositions ()
2863
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2864
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to spot-margin endpoint if this is set
2865
+ * @param {bool} [params.margin] true for fetching spot-margin positions
2866
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2867
+ */
2868
+ await this.loadMarkets();
2869
+ const request = {};
2870
+ let marketType = undefined;
2871
+ let marginMode = undefined;
2872
+ [marketType, params] = this.handleMarketTypeAndParams('fetchPositions', undefined, params);
2873
+ if (marketType === 'spot') {
2874
+ marketType = 'swap';
2875
+ }
2876
+ [marginMode, params] = this.handleMarginModeAndParams('fetchPositions', params);
2877
+ params = this.omit(params, ['marginMode', 'margin']);
2878
+ let response = undefined;
2879
+ if (marginMode !== undefined) {
2880
+ response = await this.privateGetMarginAccount(this.extend(request, params));
2881
+ }
2882
+ else {
2883
+ if (marketType === 'swap') {
2884
+ response = await this.privateGetFuturesAccount(this.extend(request, params));
2885
+ }
2886
+ else if (marketType === 'margin') {
2887
+ response = await this.privateGetMarginAccount(this.extend(request, params));
2888
+ }
2889
+ else {
2890
+ throw new errors.NotSupported(this.id + ' fetchPositions() not support this market type');
2891
+ }
2892
+ }
2893
+ //
2894
+ // [
2895
+ // {
2896
+ // "symbol": "ETHUSDT_PERP",
2897
+ // "type": "isolated",
2898
+ // "leverage": "10.00",
2899
+ // "created_at": "2022-03-19T07:54:35.24Z",
2900
+ // "updated_at": "2022-03-19T07:54:58.922Z",
2901
+ // currencies": [
2902
+ // {
2903
+ // "code": "USDT",
2904
+ // "margin_balance": "7.478100643043",
2905
+ // "reserved_orders": "0",
2906
+ // "reserved_positions": "0.303530761300"
2907
+ // }
2908
+ // ],
2909
+ // "positions": [
2910
+ // {
2911
+ // "id": 2470568,
2912
+ // "symbol": "ETHUSDT_PERP",
2913
+ // "quantity": "0.001",
2914
+ // "price_entry": "2927.509",
2915
+ // "price_margin_call": "0",
2916
+ // "price_liquidation": "0",
2917
+ // "pnl": "0",
2918
+ // "created_at": "2022-03-19T07:54:35.24Z",
2919
+ // "updated_at": "2022-03-19T07:54:58.922Z"
2920
+ // }
2921
+ // ]
2922
+ // },
2923
+ // ]
2924
+ //
2925
+ const result = [];
2926
+ for (let i = 0; i < response.length; i++) {
2927
+ result.push(this.parsePosition(response[i]));
2928
+ }
2929
+ return result;
2930
+ }
2931
+ async fetchPosition(symbol, params = {}) {
2932
+ /**
2933
+ * @method
2934
+ * @name hitbtc#fetchPosition
2935
+ * @description fetch data on a single open contract trade position
2936
+ * @see https://api.hitbtc.com/#get-futures-margin-account
2937
+ * @see https://api.hitbtc.com/#get-isolated-margin-account
2938
+ * @param {string} symbol unified market symbol of the market the position is held in, default is undefined
2939
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2940
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to spot-margin endpoint if this is set
2941
+ * @param {bool} [params.margin] true for fetching a spot-margin position
2942
+ * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2943
+ */
2944
+ await this.loadMarkets();
2945
+ const market = this.market(symbol);
2946
+ const request = {
2947
+ 'symbol': market['id'],
2948
+ };
2949
+ let marketType = undefined;
2950
+ let marginMode = undefined;
2951
+ [marketType, params] = this.handleMarketTypeAndParams('fetchPosition', undefined, params);
2952
+ [marginMode, params] = this.handleMarginModeAndParams('fetchPosition', params);
2953
+ params = this.omit(params, ['marginMode', 'margin']);
2954
+ let response = undefined;
2955
+ if (marginMode !== undefined) {
2956
+ response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
2957
+ }
2958
+ else {
2959
+ if (marketType === 'swap') {
2960
+ response = await this.privateGetFuturesAccountIsolatedSymbol(this.extend(request, params));
2961
+ }
2962
+ else if (marketType === 'margin') {
2963
+ response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
2964
+ }
2965
+ else {
2966
+ throw new errors.NotSupported(this.id + ' fetchPosition() not support this market type');
2967
+ }
2968
+ }
2969
+ //
2970
+ // [
2971
+ // {
2972
+ // "symbol": "ETHUSDT_PERP",
2973
+ // "type": "isolated",
2974
+ // "leverage": "10.00",
2975
+ // "created_at": "2022-03-19T07:54:35.24Z",
2976
+ // "updated_at": "2022-03-19T07:54:58.922Z",
2977
+ // currencies": [
2978
+ // {
2979
+ // "code": "USDT",
2980
+ // "margin_balance": "7.478100643043",
2981
+ // "reserved_orders": "0",
2982
+ // "reserved_positions": "0.303530761300"
2983
+ // }
2984
+ // ],
2985
+ // "positions": [
2986
+ // {
2987
+ // "id": 2470568,
2988
+ // "symbol": "ETHUSDT_PERP",
2989
+ // "quantity": "0.001",
2990
+ // "price_entry": "2927.509",
2991
+ // "price_margin_call": "0",
2992
+ // "price_liquidation": "0",
2993
+ // "pnl": "0",
2994
+ // "created_at": "2022-03-19T07:54:35.24Z",
2995
+ // "updated_at": "2022-03-19T07:54:58.922Z"
2996
+ // }
2997
+ // ]
2998
+ // },
2999
+ // ]
3000
+ //
3001
+ return this.parsePosition(response, market);
3002
+ }
3003
+ parsePosition(position, market = undefined) {
3004
+ //
3005
+ // [
3006
+ // {
3007
+ // "symbol": "ETHUSDT_PERP",
3008
+ // "type": "isolated",
3009
+ // "leverage": "10.00",
3010
+ // "created_at": "2022-03-19T07:54:35.24Z",
3011
+ // "updated_at": "2022-03-19T07:54:58.922Z",
3012
+ // currencies": [
3013
+ // {
3014
+ // "code": "USDT",
3015
+ // "margin_balance": "7.478100643043",
3016
+ // "reserved_orders": "0",
3017
+ // "reserved_positions": "0.303530761300"
3018
+ // }
3019
+ // ],
3020
+ // "positions": [
3021
+ // {
3022
+ // "id": 2470568,
3023
+ // "symbol": "ETHUSDT_PERP",
3024
+ // "quantity": "0.001",
3025
+ // "price_entry": "2927.509",
3026
+ // "price_margin_call": "0",
3027
+ // "price_liquidation": "0",
3028
+ // "pnl": "0",
3029
+ // "created_at": "2022-03-19T07:54:35.24Z",
3030
+ // "updated_at": "2022-03-19T07:54:58.922Z"
3031
+ // }
3032
+ // ]
3033
+ // },
3034
+ // ]
3035
+ //
3036
+ const marginMode = this.safeString(position, 'type');
3037
+ const leverage = this.safeNumber(position, 'leverage');
3038
+ const datetime = this.safeString(position, 'updated_at');
3039
+ const positions = this.safeValue(position, 'positions', []);
3040
+ let liquidationPrice = undefined;
3041
+ let entryPrice = undefined;
3042
+ let contracts = undefined;
3043
+ for (let i = 0; i < positions.length; i++) {
3044
+ const entry = positions[i];
3045
+ liquidationPrice = this.safeNumber(entry, 'price_liquidation');
3046
+ entryPrice = this.safeNumber(entry, 'price_entry');
3047
+ contracts = this.safeNumber(entry, 'quantity');
3048
+ }
3049
+ const currencies = this.safeValue(position, 'currencies', []);
3050
+ let collateral = undefined;
3051
+ for (let i = 0; i < currencies.length; i++) {
3052
+ const entry = currencies[i];
3053
+ collateral = this.safeNumber(entry, 'margin_balance');
3054
+ }
3055
+ const marketId = this.safeString(position, 'symbol');
3056
+ market = this.safeMarket(marketId, market);
3057
+ const symbol = market['symbol'];
3058
+ return this.safePosition({
3059
+ 'info': position,
3060
+ 'id': undefined,
3061
+ 'symbol': symbol,
3062
+ 'notional': undefined,
3063
+ 'marginMode': marginMode,
3064
+ 'marginType': marginMode,
3065
+ 'liquidationPrice': liquidationPrice,
3066
+ 'entryPrice': entryPrice,
3067
+ 'unrealizedPnl': undefined,
3068
+ 'percentage': undefined,
3069
+ 'contracts': contracts,
3070
+ 'contractSize': undefined,
3071
+ 'markPrice': undefined,
3072
+ 'lastPrice': undefined,
3073
+ 'side': undefined,
3074
+ 'hedged': undefined,
3075
+ 'timestamp': this.parse8601(datetime),
3076
+ 'datetime': datetime,
3077
+ 'lastUpdateTimestamp': undefined,
3078
+ 'maintenanceMargin': undefined,
3079
+ 'maintenanceMarginPercentage': undefined,
3080
+ 'collateral': collateral,
3081
+ 'initialMargin': undefined,
3082
+ 'initialMarginPercentage': undefined,
3083
+ 'leverage': leverage,
3084
+ 'marginRatio': undefined,
3085
+ 'stopLossPrice': undefined,
3086
+ 'takeProfitPrice': undefined,
3087
+ });
3088
+ }
3089
+ parseOpenInterest(interest, market = undefined) {
3090
+ //
3091
+ // {
3092
+ // "contract_type": "perpetual",
3093
+ // "mark_price": "42307.43",
3094
+ // "index_price": "42303.27",
3095
+ // "funding_rate": "0.0001",
3096
+ // "open_interest": "30.9826",
3097
+ // "next_funding_time": "2022-03-22T16:00:00.000Z",
3098
+ // "indicative_funding_rate": "0.0001",
3099
+ // "premium_index": "0",
3100
+ // "avg_premium_index": "0.000029587712038098",
3101
+ // "interest_rate": "0.0001",
3102
+ // "timestamp": "2022-03-22T08:08:26.687Z"
3103
+ // }
3104
+ //
3105
+ const datetime = this.safeString(interest, 'timestamp');
3106
+ const value = this.safeNumber(interest, 'open_interest');
3107
+ return this.safeOpenInterest({
3108
+ 'symbol': market['symbol'],
3109
+ 'openInterestAmount': undefined,
3110
+ 'openInterestValue': value,
3111
+ 'timestamp': this.parse8601(datetime),
3112
+ 'datetime': datetime,
3113
+ 'info': interest,
3114
+ }, market);
3115
+ }
3116
+ async fetchOpenInterest(symbol, params = {}) {
3117
+ /**
3118
+ * @method
3119
+ * @name hitbtc#fetchOpenInterest
3120
+ * @description Retrieves the open interest of a derivative trading pair
3121
+ * @see https://api.hitbtc.com/#futures-info
3122
+ * @param {string} symbol Unified CCXT market symbol
3123
+ * @param {object} [params] exchange specific parameters
3124
+ * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=interest-history-structure}
3125
+ */
3126
+ await this.loadMarkets();
3127
+ const market = this.market(symbol);
3128
+ if (!market['swap']) {
3129
+ throw new errors.BadSymbol(this.id + ' fetchOpenInterest() supports swap contracts only');
3130
+ }
3131
+ const request = {
3132
+ 'symbol': market['id'],
3133
+ };
3134
+ const response = await this.publicGetPublicFuturesInfoSymbol(this.extend(request, params));
3135
+ //
3136
+ // {
3137
+ // "contract_type": "perpetual",
3138
+ // "mark_price": "42307.43",
3139
+ // "index_price": "42303.27",
3140
+ // "funding_rate": "0.0001",
3141
+ // "open_interest": "30.9826",
3142
+ // "next_funding_time": "2022-03-22T16:00:00.000Z",
3143
+ // "indicative_funding_rate": "0.0001",
3144
+ // "premium_index": "0",
3145
+ // "avg_premium_index": "0.000029587712038098",
3146
+ // "interest_rate": "0.0001",
3147
+ // "timestamp": "2022-03-22T08:08:26.687Z"
3148
+ // }
3149
+ //
3150
+ return this.parseOpenInterest(response, market);
3151
+ }
3152
+ async fetchFundingRate(symbol, params = {}) {
3153
+ /**
3154
+ * @method
3155
+ * @name hitbtc#fetchFundingRate
3156
+ * @description fetch the current funding rate
3157
+ * @see https://api.hitbtc.com/#futures-info
3158
+ * @param {string} symbol unified market symbol
3159
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3160
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
3161
+ */
3162
+ await this.loadMarkets();
3163
+ const market = this.market(symbol);
3164
+ if (!market['swap']) {
3165
+ throw new errors.BadSymbol(this.id + ' fetchFundingRate() supports swap contracts only');
3166
+ }
3167
+ const request = {
3168
+ 'symbol': market['id'],
3169
+ };
3170
+ const response = await this.publicGetPublicFuturesInfoSymbol(this.extend(request, params));
3171
+ //
3172
+ // {
3173
+ // "contract_type": "perpetual",
3174
+ // "mark_price": "42307.43",
3175
+ // "index_price": "42303.27",
3176
+ // "funding_rate": "0.0001",
3177
+ // "open_interest": "30.9826",
3178
+ // "next_funding_time": "2022-03-22T16:00:00.000Z",
3179
+ // "indicative_funding_rate": "0.0001",
3180
+ // "premium_index": "0",
3181
+ // "avg_premium_index": "0.000029587712038098",
3182
+ // "interest_rate": "0.0001",
3183
+ // "timestamp": "2022-03-22T08:08:26.687Z"
3184
+ // }
3185
+ //
3186
+ return this.parseFundingRate(response, market);
3187
+ }
3188
+ parseFundingRate(contract, market = undefined) {
3189
+ //
3190
+ // {
3191
+ // "contract_type": "perpetual",
3192
+ // "mark_price": "42307.43",
3193
+ // "index_price": "42303.27",
3194
+ // "funding_rate": "0.0001",
3195
+ // "open_interest": "30.9826",
3196
+ // "next_funding_time": "2022-03-22T16:00:00.000Z",
3197
+ // "indicative_funding_rate": "0.0001",
3198
+ // "premium_index": "0",
3199
+ // "avg_premium_index": "0.000029587712038098",
3200
+ // "interest_rate": "0.0001",
3201
+ // "timestamp": "2022-03-22T08:08:26.687Z"
3202
+ // }
3203
+ //
3204
+ const fundingDateTime = this.safeString(contract, 'next_funding_time');
3205
+ const datetime = this.safeString(contract, 'timestamp');
3206
+ return {
3207
+ 'info': contract,
3208
+ 'symbol': this.safeSymbol(undefined, market),
3209
+ 'markPrice': this.safeNumber(contract, 'mark_price'),
3210
+ 'indexPrice': this.safeNumber(contract, 'index_price'),
3211
+ 'interestRate': this.safeNumber(contract, 'interest_rate'),
3212
+ 'estimatedSettlePrice': undefined,
3213
+ 'timestamp': this.parse8601(datetime),
3214
+ 'datetime': datetime,
3215
+ 'fundingRate': this.safeNumber(contract, 'funding_rate'),
3216
+ 'fundingTimestamp': this.parse8601(fundingDateTime),
3217
+ 'fundingDatetime': fundingDateTime,
3218
+ 'nextFundingRate': this.safeNumber(contract, 'indicative_funding_rate'),
3219
+ 'nextFundingTimestamp': undefined,
3220
+ 'nextFundingDatetime': undefined,
3221
+ 'previousFundingRate': undefined,
3222
+ 'previousFundingTimestamp': undefined,
3223
+ 'previousFundingDatetime': undefined,
3224
+ };
3225
+ }
3226
+ async modifyMarginHelper(symbol, amount, type, params = {}) {
3227
+ await this.loadMarkets();
3228
+ const market = this.market(symbol);
3229
+ const leverage = this.safeString(params, 'leverage');
3230
+ if (market['type'] === 'swap') {
3231
+ if (leverage === undefined) {
3232
+ throw new errors.ArgumentsRequired(this.id + ' modifyMarginHelper() requires a leverage parameter for swap markets');
3233
+ }
3234
+ }
3235
+ if (amount !== 0) {
3236
+ amount = this.amountToPrecision(symbol, amount);
3237
+ }
3238
+ else {
3239
+ amount = '0';
3240
+ }
3241
+ const request = {
3242
+ 'symbol': market['id'],
3243
+ 'margin_balance': amount, // swap and margin
3244
+ // "leverage": "10", // swap only required
3245
+ // "strict_validate": false, // swap and margin
3246
+ };
3247
+ if (leverage !== undefined) {
3248
+ request['leverage'] = leverage;
3249
+ }
3250
+ let marketType = undefined;
3251
+ let marginMode = undefined;
3252
+ [marketType, params] = this.handleMarketTypeAndParams('modifyMarginHelper', market, params);
3253
+ [marginMode, params] = this.handleMarginModeAndParams('modifyMarginHelper', params);
3254
+ params = this.omit(params, ['marginMode', 'margin']);
3255
+ let response = undefined;
3256
+ if (marginMode !== undefined) {
3257
+ response = await this.privatePutMarginAccountIsolatedSymbol(this.extend(request, params));
3258
+ }
3259
+ else {
3260
+ if (marketType === 'swap') {
3261
+ response = await this.privatePutFuturesAccountIsolatedSymbol(this.extend(request, params));
3262
+ }
3263
+ else if (marketType === 'margin') {
3264
+ response = await this.privatePutMarginAccountIsolatedSymbol(this.extend(request, params));
3265
+ }
3266
+ else {
3267
+ throw new errors.NotSupported(this.id + ' modifyMarginHelper() not support this market type');
3268
+ }
3269
+ }
3270
+ //
3271
+ // {
3272
+ // "symbol": "BTCUSDT_PERP",
3273
+ // "type": "isolated",
3274
+ // "leverage": "8.00",
3275
+ // "created_at": "2022-03-30T23:34:27.161Z",
3276
+ // "updated_at": "2022-03-30T23:34:27.161Z",
3277
+ // "currencies": [
3278
+ // {
3279
+ // "code": "USDT",
3280
+ // "margin_balance": "7.000000000000",
3281
+ // "reserved_orders": "0",
3282
+ // "reserved_positions": "0"
3283
+ // }
3284
+ // ],
3285
+ // "positions": null
3286
+ // }
3287
+ //
3288
+ return this.extend(this.parseMarginModification(response, market), {
3289
+ 'amount': this.parseNumber(amount),
3290
+ 'type': type,
3291
+ });
3292
+ }
3293
+ parseMarginModification(data, market = undefined) {
3294
+ const currencies = this.safeValue(data, 'currencies', []);
3295
+ const currencyInfo = this.safeValue(currencies, 0);
3296
+ return {
3297
+ 'info': data,
3298
+ 'type': undefined,
3299
+ 'amount': undefined,
3300
+ 'code': this.safeString(currencyInfo, 'code'),
3301
+ 'symbol': market['symbol'],
3302
+ 'status': undefined,
3303
+ };
3304
+ }
3305
+ async reduceMargin(symbol, amount, params = {}) {
3306
+ /**
3307
+ * @method
3308
+ * @name hitbtc#reduceMargin
3309
+ * @description remove margin from a position
3310
+ * @see https://api.hitbtc.com/#create-update-margin-account-2
3311
+ * @see https://api.hitbtc.com/#create-update-margin-account
3312
+ * @param {string} symbol unified market symbol
3313
+ * @param {float} amount the amount of margin to remove
3314
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3315
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to the spot-margin endpoint if this is set
3316
+ * @param {bool} [params.margin] true for reducing spot-margin
3317
+ * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=reduce-margin-structure}
3318
+ */
3319
+ if (amount !== 0) {
3320
+ throw new errors.BadRequest(this.id + ' reduceMargin() on hitbtc requires the amount to be 0 and that will remove the entire margin amount');
3321
+ }
3322
+ return await this.modifyMarginHelper(symbol, amount, 'reduce', params);
3323
+ }
3324
+ async addMargin(symbol, amount, params = {}) {
3325
+ /**
3326
+ * @method
3327
+ * @name hitbtc#addMargin
3328
+ * @description add margin
3329
+ * @see https://api.hitbtc.com/#create-update-margin-account-2
3330
+ * @see https://api.hitbtc.com/#create-update-margin-account
3331
+ * @param {string} symbol unified market symbol
3332
+ * @param {float} amount amount of margin to add
3333
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3334
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to the spot-margin endpoint if this is set
3335
+ * @param {bool} [params.margin] true for adding spot-margin
3336
+ * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure}
3337
+ */
3338
+ return await this.modifyMarginHelper(symbol, amount, 'add', params);
3339
+ }
3340
+ async fetchLeverage(symbol, params = {}) {
3341
+ /**
3342
+ * @method
3343
+ * @name hitbtc#fetchLeverage
3344
+ * @description fetch the set leverage for a market
3345
+ * @see https://api.hitbtc.com/#get-futures-margin-account
3346
+ * @see https://api.hitbtc.com/#get-isolated-margin-account
3347
+ * @param {string} symbol unified market symbol
3348
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3349
+ * @param {string} [params.marginMode] 'cross' or 'isolated' only 'isolated' is supported, defaults to the spot-margin endpoint if this is set
3350
+ * @param {bool} [params.margin] true for fetching spot-margin leverage
3351
+ * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
3352
+ */
3353
+ await this.loadMarkets();
3354
+ const market = this.market(symbol);
3355
+ const request = {
3356
+ 'symbol': market['id'],
3357
+ };
3358
+ let marginMode = undefined;
3359
+ [marginMode, params] = this.handleMarginModeAndParams('fetchLeverage', params);
3360
+ params = this.omit(params, ['marginMode', 'margin']);
3361
+ let response = undefined;
3362
+ if (marginMode !== undefined) {
3363
+ response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
3364
+ }
3365
+ else {
3366
+ if (market['type'] === 'spot') {
3367
+ response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
3368
+ }
3369
+ else if (market['type'] === 'swap') {
3370
+ response = await this.privateGetFuturesAccountIsolatedSymbol(this.extend(request, params));
3371
+ }
3372
+ else if (market['type'] === 'margin') {
3373
+ response = await this.privateGetMarginAccountIsolatedSymbol(this.extend(request, params));
3374
+ }
3375
+ else {
3376
+ throw new errors.NotSupported(this.id + ' fetchLeverage() not support this market type');
3377
+ }
3378
+ }
3379
+ //
3380
+ // {
3381
+ // "symbol": "BTCUSDT",
3382
+ // "type": "isolated",
3383
+ // "leverage": "12.00",
3384
+ // "created_at": "2022-03-29T22:31:29.067Z",
3385
+ // "updated_at": "2022-03-30T00:00:00.125Z",
3386
+ // "currencies": [
3387
+ // {
3388
+ // "code": "USDT",
3389
+ // "margin_balance": "20.824360374174",
3390
+ // "reserved_orders": "0",
3391
+ // "reserved_positions": "0.973330435000"
3392
+ // }
3393
+ // ],
3394
+ // "positions": [
3395
+ // {
3396
+ // "id": 631301,
3397
+ // "symbol": "BTCUSDT",
3398
+ // "quantity": "0.00022",
3399
+ // "price_entry": "47425.57",
3400
+ // "price_margin_call": "",
3401
+ // "price_liquidation": "0",
3402
+ // "pnl": "0",
3403
+ // "created_at": "2022-03-29T22:31:29.067Z",
3404
+ // "updated_at": "2022-03-30T00:00:00.125Z"
3405
+ // }
3406
+ // ]
3407
+ // }
3408
+ //
3409
+ return this.safeNumber(response, 'leverage');
3410
+ }
3411
+ async setLeverage(leverage, symbol = undefined, params = {}) {
3412
+ /**
3413
+ * @method
3414
+ * @name hitbtc#setLeverage
3415
+ * @description set the level of leverage for a market
3416
+ * @see https://api.hitbtc.com/#create-update-margin-account-2
3417
+ * @param {float} leverage the rate of leverage
3418
+ * @param {string} symbol unified market symbol
3419
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3420
+ * @returns {object} response from the exchange
3421
+ */
3422
+ if (symbol === undefined) {
3423
+ throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
3424
+ }
3425
+ await this.loadMarkets();
3426
+ if (params['margin_balance'] === undefined) {
3427
+ throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a margin_balance parameter that will transfer margin to the specified trading pair');
3428
+ }
3429
+ const market = this.market(symbol);
3430
+ const amount = this.safeNumber(params, 'margin_balance');
3431
+ const maxLeverage = this.safeInteger(market['limits']['leverage'], 'max', 50);
3432
+ if (market['type'] !== 'swap') {
3433
+ throw new errors.BadSymbol(this.id + ' setLeverage() supports swap contracts only');
3434
+ }
3435
+ if ((leverage < 1) || (leverage > maxLeverage)) {
3436
+ throw new errors.BadRequest(this.id + ' setLeverage() leverage should be between 1 and ' + maxLeverage.toString() + ' for ' + symbol);
3437
+ }
3438
+ const request = {
3439
+ 'symbol': market['id'],
3440
+ 'leverage': leverage.toString(),
3441
+ 'margin_balance': this.amountToPrecision(symbol, amount),
3442
+ // 'strict_validate': false,
3443
+ };
3444
+ return await this.privatePutFuturesAccountIsolatedSymbol(this.extend(request, params));
3445
+ }
3446
+ async fetchDepositWithdrawFees(codes = undefined, params = {}) {
3447
+ /**
3448
+ * @method
3449
+ * @name hitbtc#fetchDepositWithdrawFees
3450
+ * @description fetch deposit and withdraw fees
3451
+ * @see https://api.hitbtc.com/#currencies
3452
+ * @param {string[]|undefined} codes list of unified currency codes
3453
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3454
+ * @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
3455
+ */
3456
+ await this.loadMarkets();
3457
+ const response = await this.publicGetPublicCurrency(params);
3458
+ //
3459
+ // {
3460
+ // "WEALTH": {
3461
+ // "full_name": "ConnectWealth",
3462
+ // "payin_enabled": false,
3463
+ // "payout_enabled": false,
3464
+ // "transfer_enabled": true,
3465
+ // "precision_transfer": "0.001",
3466
+ // "networks": [
3467
+ // {
3468
+ // "network": "ETH",
3469
+ // "protocol": "ERC20",
3470
+ // "default": true,
3471
+ // "payin_enabled": false,
3472
+ // "payout_enabled": false,
3473
+ // "precision_payout": "0.001",
3474
+ // "payout_fee": "0.016800000000",
3475
+ // "payout_is_payment_id": false,
3476
+ // "payin_payment_id": false,
3477
+ // "payin_confirmations": "2"
3478
+ // }
3479
+ // ]
3480
+ // }
3481
+ // }
3482
+ //
3483
+ return this.parseDepositWithdrawFees(response, codes);
3484
+ }
3485
+ parseDepositWithdrawFee(fee, currency = undefined) {
3486
+ //
3487
+ // {
3488
+ // "full_name": "ConnectWealth",
3489
+ // "payin_enabled": false,
3490
+ // "payout_enabled": false,
3491
+ // "transfer_enabled": true,
3492
+ // "precision_transfer": "0.001",
3493
+ // "networks": [
3494
+ // {
3495
+ // "network": "ETH",
3496
+ // "protocol": "ERC20",
3497
+ // "default": true,
3498
+ // "payin_enabled": false,
3499
+ // "payout_enabled": false,
3500
+ // "precision_payout": "0.001",
3501
+ // "payout_fee": "0.016800000000",
3502
+ // "payout_is_payment_id": false,
3503
+ // "payin_payment_id": false,
3504
+ // "payin_confirmations": "2"
3505
+ // }
3506
+ // ]
3507
+ // }
3508
+ //
3509
+ const networks = this.safeValue(fee, 'networks', []);
3510
+ const result = this.depositWithdrawFee(fee);
3511
+ for (let j = 0; j < networks.length; j++) {
3512
+ const networkEntry = networks[j];
3513
+ const networkId = this.safeString(networkEntry, 'network');
3514
+ const networkCode = this.networkIdToCode(networkId);
3515
+ const withdrawFee = this.safeNumber(networkEntry, 'payout_fee');
3516
+ const isDefault = this.safeValue(networkEntry, 'default');
3517
+ const withdrawResult = {
3518
+ 'fee': withdrawFee,
3519
+ 'percentage': (withdrawFee !== undefined) ? false : undefined,
3520
+ };
3521
+ if (isDefault === true) {
3522
+ result['withdraw'] = withdrawResult;
3523
+ }
3524
+ result['networks'][networkCode] = {
3525
+ 'withdraw': withdrawResult,
3526
+ 'deposit': {
3527
+ 'fee': undefined,
3528
+ 'percentage': undefined,
3529
+ },
3530
+ };
3531
+ }
3532
+ return result;
3533
+ }
3534
+ async closePosition(symbol, side = undefined, params = {}) {
3535
+ /**
3536
+ * @method
3537
+ * @name hitbtc#closePosition
3538
+ * @description closes open positions for a market
3539
+ * @see https://api.hitbtc.com/#close-all-futures-margin-positions
3540
+ * @param {object} [params] extra parameters specific to the okx api endpoint
3541
+ * @param {string} [params.symbol] *required* unified market symbol
3542
+ * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'cross'
3543
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3544
+ */
3545
+ await this.loadMarkets();
3546
+ let marginMode = undefined;
3547
+ [marginMode, params] = this.handleMarginModeAndParams('closePosition', params, 'cross');
3548
+ const market = this.market(symbol);
3549
+ const request = {
3550
+ 'symbol': market['id'],
3551
+ 'margin_mode': marginMode,
3552
+ };
3553
+ const response = await this.privateDeleteFuturesPositionMarginModeSymbol(this.extend(request, params));
3554
+ //
3555
+ // {
3556
+ // "id":"202471640",
3557
+ // "symbol":"TRXUSDT_PERP",
3558
+ // "margin_mode":"Cross",
3559
+ // "leverage":"1.00",
3560
+ // "quantity":"0",
3561
+ // "price_entry":"0",
3562
+ // "price_margin_call":"0",
3563
+ // "price_liquidation":"0",
3564
+ // "pnl":"0.001234100000",
3565
+ // "created_at":"2023-10-29T14:46:13.235Z",
3566
+ // "updated_at":"2023-12-19T09:34:40.014Z"
3567
+ // }
3568
+ //
3569
+ return this.parseOrder(response, market);
3570
+ }
3571
+ handleMarginModeAndParams(methodName, params = {}, defaultValue = undefined) {
3572
+ /**
3573
+ * @ignore
3574
+ * @method
3575
+ * @description marginMode specified by params["marginMode"], this.options["marginMode"], this.options["defaultMarginMode"], params["margin"] = true or this.options["defaultType"] = 'margin'
3576
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3577
+ * @returns {Array} the marginMode in lowercase
3578
+ */
3579
+ const defaultType = this.safeString(this.options, 'defaultType');
3580
+ const isMargin = this.safeValue(params, 'margin', false);
3581
+ let marginMode = undefined;
3582
+ [marginMode, params] = super.handleMarginModeAndParams(methodName, params, defaultValue);
3583
+ if (marginMode === undefined) {
3584
+ if ((defaultType === 'margin') || (isMargin === true)) {
3585
+ marginMode = 'isolated';
3586
+ }
3587
+ }
3588
+ return [marginMode, params];
3589
+ }
3590
+ handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3591
+ //
3592
+ // {
3593
+ // "error": {
3594
+ // "code": 20001,
3595
+ // "message": "Insufficient funds",
3596
+ // "description": "Check that the funds are sufficient, given commissions"
3597
+ // }
3598
+ // }
3599
+ //
3600
+ // {
3601
+ // "error": {
3602
+ // "code": "600",
3603
+ // "message": "Action not allowed"
3604
+ // }
3605
+ // }
3606
+ //
3607
+ const error = this.safeValue(response, 'error');
3608
+ const errorCode = this.safeString(error, 'code');
3609
+ if (errorCode !== undefined) {
3610
+ const feedback = this.id + ' ' + body;
3611
+ const message = this.safeString2(error, 'message', 'description');
3612
+ this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
3613
+ this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
3614
+ throw new errors.ExchangeError(feedback);
3615
+ }
3616
+ return undefined;
3617
+ }
3618
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3619
+ const query = this.omit(params, this.extractParams(path));
3620
+ const implodedPath = this.implodeParams(path, params);
3621
+ let url = this.urls['api'][api] + '/' + implodedPath;
3622
+ let getRequest = undefined;
3623
+ const keys = Object.keys(query);
3624
+ const queryLength = keys.length;
3625
+ headers = {
3626
+ 'Content-Type': 'application/json',
3627
+ };
3628
+ if (method === 'GET') {
3629
+ if (queryLength) {
3630
+ getRequest = '?' + this.urlencode(query);
3631
+ url = url + getRequest;
3632
+ }
3633
+ }
3634
+ else {
3635
+ body = this.json(params);
3636
+ }
3637
+ if (api === 'private') {
3638
+ this.checkRequiredCredentials();
3639
+ const timestamp = this.nonce().toString();
3640
+ const payload = [method, '/api/3/' + implodedPath];
3641
+ if (method === 'GET') {
3642
+ if (getRequest !== undefined) {
3643
+ payload.push(getRequest);
3644
+ }
3645
+ }
3646
+ else {
3647
+ payload.push(body);
3648
+ }
3649
+ payload.push(timestamp);
3650
+ const payloadString = payload.join('');
3651
+ const signature = this.hmac(this.encode(payloadString), this.encode(this.secret), sha256.sha256, 'hex');
3652
+ const secondPayload = this.apiKey + ':' + signature + ':' + timestamp;
3653
+ const encoded = this.stringToBase64(secondPayload);
3654
+ headers['Authorization'] = 'HS256 ' + encoded;
3655
+ }
3656
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3657
+ }
3658
+ }
3659
+
3660
+ module.exports = hitbtc;