ccxt 4.2.11 → 4.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/README.md +5 -5
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +1347 -490
  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 +2209 -0
  125. package/dist/cjs/js/src/binance.js +9736 -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 +3807 -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 +8291 -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 +3424 -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 +7072 -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 +9049 -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 +761 -0
  185. package/dist/cjs/js/src/indodax.js +1069 -0
  186. package/dist/cjs/js/src/kraken.js +2857 -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 +2851 -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 +7330 -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 +4722 -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 +1608 -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 +1867 -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 +2765 -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/js/ccxt.d.ts +1 -1
  329. package/js/ccxt.js +1 -1
  330. package/js/src/abstract/bigone.d.ts +18 -0
  331. package/js/src/abstract/binance.d.ts +2 -0
  332. package/js/src/abstract/binancecoinm.d.ts +2 -0
  333. package/js/src/abstract/binanceus.d.ts +2 -0
  334. package/js/src/abstract/binanceusdm.d.ts +2 -0
  335. package/js/src/abstract/bingx.d.ts +2 -0
  336. package/js/src/abstract/bybit.d.ts +1 -0
  337. package/js/src/abstract/gate.d.ts +11 -0
  338. package/js/src/abstract/gateio.d.ts +11 -0
  339. package/js/src/abstract/okx.d.ts +1 -0
  340. package/js/src/alpaca.js +18 -18
  341. package/js/src/base/Exchange.d.ts +5 -1
  342. package/js/src/base/Exchange.js +101 -12
  343. package/js/src/bigone.d.ts +3 -2
  344. package/js/src/bigone.js +429 -167
  345. package/js/src/binance.js +48 -34
  346. package/js/src/bingx.js +115 -38
  347. package/js/src/bitfinex.d.ts +2 -2
  348. package/js/src/bitfinex.js +2 -3
  349. package/js/src/bitget.js +33 -13
  350. package/js/src/bitmart.d.ts +2 -2
  351. package/js/src/bitmart.js +5 -5
  352. package/js/src/bitmex.js +1 -0
  353. package/js/src/bybit.js +2 -0
  354. package/js/src/coinbase.d.ts +26 -3
  355. package/js/src/coinbase.js +176 -26
  356. package/js/src/coinlist.js +3 -4
  357. package/js/src/coinone.js +1 -1
  358. package/js/src/coinsph.js +2 -3
  359. package/js/src/deribit.js +1 -0
  360. package/js/src/gate.d.ts +4 -4
  361. package/js/src/gate.js +96 -59
  362. package/js/src/gemini.js +1 -1
  363. package/js/src/hitbtc.d.ts +4 -4
  364. package/js/src/hitbtc.js +2 -3
  365. package/js/src/htx.d.ts +1 -0
  366. package/js/src/htx.js +29 -7
  367. package/js/src/huobijp.js +2 -3
  368. package/js/src/independentreserve.js +7 -5
  369. package/js/src/kraken.js +3 -6
  370. package/js/src/lbank.js +59 -33
  371. package/js/src/mexc.js +2 -1
  372. package/js/src/oceanex.js +1 -1
  373. package/js/src/okx.js +14 -3
  374. package/js/src/phemex.js +9 -2
  375. package/js/src/pro/binance.d.ts +2 -23
  376. package/js/src/pro/binance.js +58 -22
  377. package/js/src/pro/coinbase.d.ts +2 -2
  378. package/js/src/pro/coinbase.js +4 -1
  379. package/js/src/pro/coinbasepro.d.ts +2 -2
  380. package/js/src/pro/hitbtc.d.ts +2 -2
  381. package/js/src/pro/kraken.js +1 -1
  382. package/js/src/pro/okx.d.ts +1 -0
  383. package/js/src/pro/okx.js +52 -2
  384. package/js/src/pro/poloniex.d.ts +2 -2
  385. package/js/src/probit.js +4 -2
  386. package/js/src/upbit.d.ts +3 -101
  387. package/js/src/upbit.js +12 -12
  388. package/js/src/wavesexchange.js +1 -1
  389. package/js/src/woo.d.ts +2 -0
  390. package/js/src/woo.js +52 -0
  391. package/package.json +1 -1
  392. package/skip-tests.json +5 -0
@@ -0,0 +1,1843 @@
1
+ 'use strict';
2
+
3
+ var bybit$1 = require('../bybit.js');
4
+ var errors = require('../base/errors.js');
5
+ var Cache = require('../base/ws/Cache.js');
6
+ var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
7
+
8
+ // ---------------------------------------------------------------------------
9
+ // ---------------------------------------------------------------------------
10
+ class bybit extends bybit$1 {
11
+ describe() {
12
+ return this.deepExtend(super.describe(), {
13
+ 'has': {
14
+ 'ws': true,
15
+ 'createOrderWs': false,
16
+ 'editOrderWs': false,
17
+ 'fetchOpenOrdersWs': false,
18
+ 'fetchOrderWs': false,
19
+ 'cancelOrderWs': false,
20
+ 'cancelOrdersWs': false,
21
+ 'cancelAllOrdersWs': false,
22
+ 'fetchTradesWs': false,
23
+ 'fetchBalanceWs': false,
24
+ 'watchBalance': true,
25
+ 'watchMyTrades': true,
26
+ 'watchOHLCV': true,
27
+ 'watchOHLCVForSymbols': false,
28
+ 'watchOrderBook': true,
29
+ 'watchOrderBookForSymbols': true,
30
+ 'watchOrders': true,
31
+ 'watchTicker': true,
32
+ 'watchTickers': true,
33
+ 'watchTrades': true,
34
+ 'watchPositions': true,
35
+ 'watchTradesForSymbols': true,
36
+ },
37
+ 'urls': {
38
+ 'api': {
39
+ 'ws': {
40
+ 'public': {
41
+ 'spot': 'wss://stream.{hostname}/v5/public/spot',
42
+ 'inverse': 'wss://stream.{hostname}/v5/public/inverse',
43
+ 'option': 'wss://stream.{hostname}/v5/public/option',
44
+ 'linear': 'wss://stream.{hostname}/v5/public/linear',
45
+ },
46
+ 'private': {
47
+ 'spot': {
48
+ 'unified': 'wss://stream.{hostname}/v5/private',
49
+ 'nonUnified': 'wss://stream.{hostname}/spot/private/v3',
50
+ },
51
+ 'contract': 'wss://stream.{hostname}/v5/private',
52
+ 'usdc': 'wss://stream.{hostname}/trade/option/usdc/private/v1',
53
+ },
54
+ },
55
+ },
56
+ 'test': {
57
+ 'ws': {
58
+ 'public': {
59
+ 'spot': 'wss://stream-testnet.{hostname}/v5/public/spot',
60
+ 'inverse': 'wss://stream-testnet.{hostname}/v5/public/inverse',
61
+ 'linear': 'wss://stream-testnet.{hostname}/v5/public/linear',
62
+ 'option': 'wss://stream-testnet.{hostname}/v5/public/option',
63
+ },
64
+ 'private': {
65
+ 'spot': {
66
+ 'unified': 'wss://stream-testnet.{hostname}/v5/private',
67
+ 'nonUnified': 'wss://stream-testnet.{hostname}/spot/private/v3',
68
+ },
69
+ 'contract': 'wss://stream-testnet.{hostname}/v5/private',
70
+ 'usdc': 'wss://stream-testnet.{hostname}/trade/option/usdc/private/v1',
71
+ },
72
+ },
73
+ },
74
+ },
75
+ 'options': {
76
+ 'watchTicker': {
77
+ 'name': 'tickers', // 'tickers' for 24hr statistical ticker or 'tickers_lt' for leverage token ticker
78
+ },
79
+ 'watchPositions': {
80
+ 'fetchPositionsSnapshot': true,
81
+ 'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
82
+ },
83
+ 'spot': {
84
+ 'timeframes': {
85
+ '1m': '1m',
86
+ '3m': '3m',
87
+ '5m': '5m',
88
+ '15m': '15m',
89
+ '30m': '30m',
90
+ '1h': '1h',
91
+ '2h': '2h',
92
+ '4h': '4h',
93
+ '6h': '6h',
94
+ '12h': '12h',
95
+ '1d': '1d',
96
+ '1w': '1w',
97
+ '1M': '1M',
98
+ },
99
+ },
100
+ 'contract': {
101
+ 'timeframes': {
102
+ '1m': '1',
103
+ '3m': '3',
104
+ '5m': '5',
105
+ '15m': '15',
106
+ '30m': '30',
107
+ '1h': '60',
108
+ '2h': '120',
109
+ '4h': '240',
110
+ '6h': '360',
111
+ '12h': '720',
112
+ '1d': 'D',
113
+ '1w': 'W',
114
+ '1M': 'M',
115
+ },
116
+ },
117
+ },
118
+ 'streaming': {
119
+ 'ping': this.ping,
120
+ 'keepAlive': 20000,
121
+ },
122
+ });
123
+ }
124
+ requestId() {
125
+ const requestId = this.sum(this.safeInteger(this.options, 'requestId', 0), 1);
126
+ this.options['requestId'] = requestId;
127
+ return requestId;
128
+ }
129
+ getUrlByMarketType(symbol = undefined, isPrivate = false, method = undefined, params = {}) {
130
+ const accessibility = isPrivate ? 'private' : 'public';
131
+ let isUsdcSettled = undefined;
132
+ let isSpot = undefined;
133
+ let type = undefined;
134
+ let market = undefined;
135
+ let url = this.urls['api']['ws'];
136
+ if (symbol !== undefined) {
137
+ market = this.market(symbol);
138
+ isUsdcSettled = market['settle'] === 'USDC';
139
+ type = market['type'];
140
+ }
141
+ else {
142
+ [type, params] = this.handleMarketTypeAndParams(method, undefined, params);
143
+ let defaultSettle = this.safeString(this.options, 'defaultSettle');
144
+ defaultSettle = this.safeString2(params, 'settle', 'defaultSettle', defaultSettle);
145
+ isUsdcSettled = (defaultSettle === 'USDC');
146
+ }
147
+ isSpot = (type === 'spot');
148
+ if (isPrivate) {
149
+ url = (isUsdcSettled) ? url[accessibility]['usdc'] : url[accessibility]['contract'];
150
+ }
151
+ else {
152
+ if (isSpot) {
153
+ url = url[accessibility]['spot'];
154
+ }
155
+ else if (type === 'swap') {
156
+ let subType = undefined;
157
+ [subType, params] = this.handleSubTypeAndParams(method, market, params, 'linear');
158
+ url = url[accessibility][subType];
159
+ }
160
+ else {
161
+ // option
162
+ url = url[accessibility]['option'];
163
+ }
164
+ }
165
+ url = this.implodeHostname(url);
166
+ return url;
167
+ }
168
+ cleanParams(params) {
169
+ params = this.omit(params, ['type', 'subType', 'settle', 'defaultSettle', 'unifiedMargin']);
170
+ return params;
171
+ }
172
+ async watchTicker(symbol, params = {}) {
173
+ /**
174
+ * @method
175
+ * @name bybit#watchTicker
176
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
177
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
178
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
179
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
180
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
181
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
182
+ */
183
+ await this.loadMarkets();
184
+ const market = this.market(symbol);
185
+ symbol = market['symbol'];
186
+ const messageHash = 'ticker:' + symbol;
187
+ const url = this.getUrlByMarketType(symbol, false, params);
188
+ params = this.cleanParams(params);
189
+ const options = this.safeValue(this.options, 'watchTicker', {});
190
+ let topic = this.safeString(options, 'name', 'tickers');
191
+ if (!market['spot'] && topic !== 'tickers') {
192
+ throw new errors.BadRequest(this.id + ' watchTicker() only supports name tickers for contract markets');
193
+ }
194
+ topic += '.' + market['id'];
195
+ const topics = [topic];
196
+ return await this.watchTopics(url, [messageHash], topics, params);
197
+ }
198
+ async watchTickers(symbols = undefined, params = {}) {
199
+ /**
200
+ * @method
201
+ * @name bybit#watchTickers
202
+ * @description n watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
203
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
204
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
205
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
206
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
207
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
208
+ */
209
+ await this.loadMarkets();
210
+ symbols = this.marketSymbols(symbols, undefined, false);
211
+ const messageHashes = [];
212
+ const url = this.getUrlByMarketType(symbols[0], false, params);
213
+ params = this.cleanParams(params);
214
+ const options = this.safeValue(this.options, 'watchTickers', {});
215
+ const topic = this.safeString(options, 'name', 'tickers');
216
+ const marketIds = this.marketIds(symbols);
217
+ const topics = [];
218
+ for (let i = 0; i < marketIds.length; i++) {
219
+ const marketId = marketIds[i];
220
+ topics.push(topic + '.' + marketId);
221
+ messageHashes.push('ticker:' + symbols[i]);
222
+ }
223
+ const ticker = await this.watchTopics(url, messageHashes, topics, params);
224
+ if (this.newUpdates) {
225
+ const result = {};
226
+ result[ticker['symbol']] = ticker;
227
+ return result;
228
+ }
229
+ return this.filterByArray(this.tickers, 'symbol', symbols);
230
+ }
231
+ handleTicker(client, message) {
232
+ //
233
+ // linear
234
+ // {
235
+ // "topic": "tickers.BTCUSDT",
236
+ // "type": "snapshot",
237
+ // "data": {
238
+ // "symbol": "BTCUSDT",
239
+ // "tickDirection": "PlusTick",
240
+ // "price24hPcnt": "0.017103",
241
+ // "lastPrice": "17216.00",
242
+ // "prevPrice24h": "16926.50",
243
+ // "highPrice24h": "17281.50",
244
+ // "lowPrice24h": "16915.00",
245
+ // "prevPrice1h": "17238.00",
246
+ // "markPrice": "17217.33",
247
+ // "indexPrice": "17227.36",
248
+ // "openInterest": "68744.761",
249
+ // "openInterestValue": "1183601235.91",
250
+ // "turnover24h": "1570383121.943499",
251
+ // "volume24h": "91705.276",
252
+ // "nextFundingTime": "1673280000000",
253
+ // "fundingRate": "-0.000212",
254
+ // "bid1Price": "17215.50",
255
+ // "bid1Size": "84.489",
256
+ // "ask1Price": "17216.00",
257
+ // "ask1Size": "83.020"
258
+ // },
259
+ // "cs": 24987956059,
260
+ // "ts": 1673272861686
261
+ // }
262
+ //
263
+ // option
264
+ // {
265
+ // "id": "tickers.BTC-6JAN23-17500-C-2480334983-1672917511074",
266
+ // "topic": "tickers.BTC-6JAN23-17500-C",
267
+ // "ts": 1672917511074,
268
+ // "data": {
269
+ // "symbol": "BTC-6JAN23-17500-C",
270
+ // "bidPrice": "0",
271
+ // "bidSize": "0",
272
+ // "bidIv": "0",
273
+ // "askPrice": "10",
274
+ // "askSize": "5.1",
275
+ // "askIv": "0.514",
276
+ // "lastPrice": "10",
277
+ // "highPrice24h": "25",
278
+ // "lowPrice24h": "5",
279
+ // "markPrice": "7.86976724",
280
+ // "indexPrice": "16823.73",
281
+ // "markPriceIv": "0.4896",
282
+ // "underlyingPrice": "16815.1",
283
+ // "openInterest": "49.85",
284
+ // "turnover24h": "446802.8473",
285
+ // "volume24h": "26.55",
286
+ // "totalVolume": "86",
287
+ // "totalTurnover": "1437431",
288
+ // "delta": "0.047831",
289
+ // "gamma": "0.00021453",
290
+ // "vega": "0.81351067",
291
+ // "theta": "-19.9115368",
292
+ // "predictedDeliveryPrice": "0",
293
+ // "change24h": "-0.33333334"
294
+ // },
295
+ // "type": "snapshot"
296
+ // }
297
+ //
298
+ // spot
299
+ // {
300
+ // "topic": "tickers.BTCUSDT",
301
+ // "ts": 1673853746003,
302
+ // "type": "snapshot",
303
+ // "cs": 2588407389,
304
+ // "data": {
305
+ // "symbol": "BTCUSDT",
306
+ // "lastPrice": "21109.77",
307
+ // "highPrice24h": "21426.99",
308
+ // "lowPrice24h": "20575",
309
+ // "prevPrice24h": "20704.93",
310
+ // "volume24h": "6780.866843",
311
+ // "turnover24h": "141946527.22907118",
312
+ // "price24hPcnt": "0.0196",
313
+ // "usdIndexPrice": "21120.2400136"
314
+ // }
315
+ // }
316
+ //
317
+ // lt ticker
318
+ // {
319
+ // "topic": "tickers_lt.EOS3LUSDT",
320
+ // "ts": 1672325446847,
321
+ // "type": "snapshot",
322
+ // "data": {
323
+ // "symbol": "EOS3LUSDT",
324
+ // "lastPrice": "0.41477848043290448",
325
+ // "highPrice24h": "0.435285472510871305",
326
+ // "lowPrice24h": "0.394601507960931382",
327
+ // "prevPrice24h": "0.431502290172376349",
328
+ // "price24hPcnt": "-0.0388"
329
+ // }
330
+ // }
331
+ //
332
+ const topic = this.safeString(message, 'topic', '');
333
+ const updateType = this.safeString(message, 'type', '');
334
+ const data = this.safeValue(message, 'data', {});
335
+ const isSpot = this.safeString(data, 'fundingRate') === undefined;
336
+ const type = isSpot ? 'spot' : 'contract';
337
+ let symbol = undefined;
338
+ let parsed = undefined;
339
+ if ((updateType === 'snapshot') || isSpot) {
340
+ parsed = this.parseTicker(data);
341
+ symbol = parsed['symbol'];
342
+ }
343
+ else if (updateType === 'delta') {
344
+ const topicParts = topic.split('.');
345
+ const topicLength = topicParts.length;
346
+ const marketId = this.safeString(topicParts, topicLength - 1);
347
+ const market = this.safeMarket(marketId, undefined, undefined, type);
348
+ symbol = market['symbol'];
349
+ // update the info in place
350
+ const ticker = this.safeValue(this.tickers, symbol, {});
351
+ const rawTicker = this.safeValue(ticker, 'info', {});
352
+ const merged = this.extend(rawTicker, data);
353
+ parsed = this.parseTicker(merged);
354
+ }
355
+ const timestamp = this.safeInteger(message, 'ts');
356
+ parsed['timestamp'] = timestamp;
357
+ parsed['datetime'] = this.iso8601(timestamp);
358
+ this.tickers[symbol] = parsed;
359
+ const messageHash = 'ticker:' + symbol;
360
+ client.resolve(this.tickers[symbol], messageHash);
361
+ }
362
+ async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
363
+ /**
364
+ * @method
365
+ * @name bybit#watchOHLCV
366
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
367
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/kline
368
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
369
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
370
+ * @param {string} timeframe the length of time each candle represents
371
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
372
+ * @param {int} [limit] the maximum amount of candles to fetch
373
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
374
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
375
+ */
376
+ await this.loadMarkets();
377
+ const market = this.market(symbol);
378
+ symbol = market['symbol'];
379
+ const url = this.getUrlByMarketType(symbol, false, params);
380
+ params = this.cleanParams(params);
381
+ let ohlcv = undefined;
382
+ const timeframeId = this.safeString(this.timeframes, timeframe, timeframe);
383
+ const topics = ['kline.' + timeframeId + '.' + market['id']];
384
+ const messageHash = 'kline' + ':' + timeframeId + ':' + symbol;
385
+ ohlcv = await this.watchTopics(url, [messageHash], topics, params);
386
+ if (this.newUpdates) {
387
+ limit = ohlcv.getLimit(symbol, limit);
388
+ }
389
+ return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
390
+ }
391
+ handleOHLCV(client, message) {
392
+ //
393
+ // {
394
+ // "topic": "kline.5.BTCUSDT",
395
+ // "data": [
396
+ // {
397
+ // "start": 1672324800000,
398
+ // "end": 1672325099999,
399
+ // "interval": "5",
400
+ // "open": "16649.5",
401
+ // "close": "16677",
402
+ // "high": "16677",
403
+ // "low": "16608",
404
+ // "volume": "2.081",
405
+ // "turnover": "34666.4005",
406
+ // "confirm": false,
407
+ // "timestamp": 1672324988882
408
+ // }
409
+ // ],
410
+ // "ts": 1672324988882,
411
+ // "type": "snapshot"
412
+ // }
413
+ //
414
+ const data = this.safeValue(message, 'data', {});
415
+ const topic = this.safeString(message, 'topic');
416
+ const topicParts = topic.split('.');
417
+ const topicLength = topicParts.length;
418
+ const timeframeId = this.safeString(topicParts, 1);
419
+ const timeframe = this.findTimeframe(timeframeId);
420
+ const marketId = this.safeString(topicParts, topicLength - 1);
421
+ const isSpot = client.url.indexOf('spot') > -1;
422
+ const marketType = isSpot ? 'spot' : 'contract';
423
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
424
+ const symbol = market['symbol'];
425
+ const ohlcvsByTimeframe = this.safeValue(this.ohlcvs, symbol);
426
+ if (ohlcvsByTimeframe === undefined) {
427
+ this.ohlcvs[symbol] = {};
428
+ }
429
+ let stored = this.safeValue(ohlcvsByTimeframe, timeframe);
430
+ if (stored === undefined) {
431
+ const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
432
+ stored = new Cache.ArrayCacheByTimestamp(limit);
433
+ this.ohlcvs[symbol][timeframe] = stored;
434
+ }
435
+ for (let i = 0; i < data.length; i++) {
436
+ const parsed = this.parseWsOHLCV(data[i]);
437
+ stored.append(parsed);
438
+ }
439
+ const messageHash = 'kline' + ':' + timeframeId + ':' + symbol;
440
+ client.resolve(stored, messageHash);
441
+ }
442
+ parseWsOHLCV(ohlcv, market = undefined) {
443
+ //
444
+ // {
445
+ // "start": 1670363160000,
446
+ // "end": 1670363219999,
447
+ // "interval": "1",
448
+ // "open": "16987.5",
449
+ // "close": "16987.5",
450
+ // "high": "16988",
451
+ // "low": "16987.5",
452
+ // "volume": "23.511",
453
+ // "turnover": "399396.344",
454
+ // "confirm": false,
455
+ // "timestamp": 1670363219614
456
+ // }
457
+ //
458
+ return [
459
+ this.safeInteger(ohlcv, 'start'),
460
+ this.safeNumber(ohlcv, 'open'),
461
+ this.safeNumber(ohlcv, 'high'),
462
+ this.safeNumber(ohlcv, 'low'),
463
+ this.safeNumber(ohlcv, 'close'),
464
+ this.safeNumber2(ohlcv, 'volume', 'turnover'),
465
+ ];
466
+ }
467
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
468
+ /**
469
+ * @method
470
+ * @name bybit#watchOrderBook
471
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
472
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
473
+ * @param {string} symbol unified symbol of the market to fetch the order book for
474
+ * @param {int} [limit] the maximum amount of order book entries to return.
475
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
476
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
477
+ */
478
+ return await this.watchOrderBookForSymbols([symbol], limit, params);
479
+ }
480
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
481
+ /**
482
+ * @method
483
+ * @name bybit#watchOrderBook
484
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
485
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
486
+ * @param {string[]} symbols unified array of symbols
487
+ * @param {int} [limit] the maximum amount of order book entries to return.
488
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
489
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
490
+ */
491
+ await this.loadMarkets();
492
+ const symbolsLength = symbols.length;
493
+ if (symbolsLength === 0) {
494
+ throw new errors.ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
495
+ }
496
+ symbols = this.marketSymbols(symbols);
497
+ const url = this.getUrlByMarketType(symbols[0], false, params);
498
+ params = this.cleanParams(params);
499
+ const market = this.market(symbols[0]);
500
+ if (limit === undefined) {
501
+ limit = (market['spot']) ? 50 : 500;
502
+ }
503
+ else {
504
+ if (!market['spot']) {
505
+ // bybit only support limit 1, 50, 200, 500 for contract
506
+ if ((limit !== 1) && (limit !== 50) && (limit !== 200) && (limit !== 500)) {
507
+ throw new errors.BadRequest(this.id + ' watchOrderBookForSymbols() can only use limit 1, 50, 200 and 500.');
508
+ }
509
+ }
510
+ }
511
+ const topics = [];
512
+ const messageHashes = [];
513
+ for (let i = 0; i < symbols.length; i++) {
514
+ const symbol = symbols[i];
515
+ const marketId = this.marketId(symbol);
516
+ const topic = 'orderbook.' + limit.toString() + '.' + marketId;
517
+ topics.push(topic);
518
+ const messageHash = 'orderbook:' + symbol;
519
+ messageHashes.push(messageHash);
520
+ }
521
+ const orderbook = await this.watchTopics(url, messageHashes, topics, params);
522
+ return orderbook.limit();
523
+ }
524
+ handleOrderBook(client, message) {
525
+ //
526
+ // {
527
+ // "topic": "orderbook.50.BTCUSDT",
528
+ // "type": "snapshot",
529
+ // "ts": 1672304484978,
530
+ // "data": {
531
+ // "s": "BTCUSDT",
532
+ // "b": [
533
+ // ...,
534
+ // [
535
+ // "16493.50",
536
+ // "0.006"
537
+ // ],
538
+ // [
539
+ // "16493.00",
540
+ // "0.100"
541
+ // ]
542
+ // ],
543
+ // "a": [
544
+ // [
545
+ // "16611.00",
546
+ // "0.029"
547
+ // ],
548
+ // [
549
+ // "16612.00",
550
+ // "0.213"
551
+ // ],
552
+ // ],
553
+ // "u": 18521288,
554
+ // "seq": 7961638724
555
+ // }
556
+ // }
557
+ //
558
+ const isSpot = client.url.indexOf('spot') >= 0;
559
+ const type = this.safeString(message, 'type');
560
+ const isSnapshot = (type === 'snapshot');
561
+ const data = this.safeValue(message, 'data', {});
562
+ const marketId = this.safeString(data, 's');
563
+ const marketType = isSpot ? 'spot' : 'contract';
564
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
565
+ const symbol = market['symbol'];
566
+ const timestamp = this.safeInteger(message, 'ts');
567
+ let orderbook = this.safeValue(this.orderbooks, symbol);
568
+ if (orderbook === undefined) {
569
+ orderbook = this.orderBook();
570
+ }
571
+ if (isSnapshot) {
572
+ const snapshot = this.parseOrderBook(data, symbol, timestamp, 'b', 'a');
573
+ orderbook.reset(snapshot);
574
+ }
575
+ else {
576
+ const asks = this.safeValue(data, 'a', []);
577
+ const bids = this.safeValue(data, 'b', []);
578
+ this.handleDeltas(orderbook['asks'], asks);
579
+ this.handleDeltas(orderbook['bids'], bids);
580
+ orderbook['timestamp'] = timestamp;
581
+ orderbook['datetime'] = this.iso8601(timestamp);
582
+ }
583
+ const messageHash = 'orderbook' + ':' + symbol;
584
+ this.orderbooks[symbol] = orderbook;
585
+ client.resolve(orderbook, messageHash);
586
+ }
587
+ handleDelta(bookside, delta) {
588
+ const bidAsk = this.parseBidAsk(delta, 0, 1);
589
+ bookside.storeArray(bidAsk);
590
+ }
591
+ handleDeltas(bookside, deltas) {
592
+ for (let i = 0; i < deltas.length; i++) {
593
+ this.handleDelta(bookside, deltas[i]);
594
+ }
595
+ }
596
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
597
+ /**
598
+ * @method
599
+ * @name bybit#watchTrades
600
+ * @description watches information on multiple trades made in a market
601
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/trade
602
+ * @param {string} symbol unified market symbol of the market trades were made in
603
+ * @param {int} [since] the earliest time in ms to fetch trades for
604
+ * @param {int} [limit] the maximum number of trade structures to retrieve
605
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
606
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
607
+ */
608
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
609
+ }
610
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
611
+ /**
612
+ * @method
613
+ * @name bybit#watchTradesForSymbols
614
+ * @description get the list of most recent trades for a list of symbols
615
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/trade
616
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
617
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
618
+ * @param {int} [limit] the maximum amount of trades to fetch
619
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
620
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
621
+ */
622
+ await this.loadMarkets();
623
+ symbols = this.marketSymbols(symbols);
624
+ const symbolsLength = symbols.length;
625
+ if (symbolsLength === 0) {
626
+ throw new errors.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
627
+ }
628
+ params = this.cleanParams(params);
629
+ const url = this.getUrlByMarketType(symbols[0], false, params);
630
+ const topics = [];
631
+ const messageHashes = [];
632
+ for (let i = 0; i < symbols.length; i++) {
633
+ const symbol = symbols[i];
634
+ const market = this.market(symbol);
635
+ const topic = 'publicTrade.' + market['id'];
636
+ topics.push(topic);
637
+ const messageHash = 'trade:' + symbol;
638
+ messageHashes.push(messageHash);
639
+ }
640
+ const trades = await this.watchTopics(url, messageHashes, topics, params);
641
+ if (this.newUpdates) {
642
+ const first = this.safeValue(trades, 0);
643
+ const tradeSymbol = this.safeString(first, 'symbol');
644
+ limit = trades.getLimit(tradeSymbol, limit);
645
+ }
646
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
647
+ }
648
+ handleTrades(client, message) {
649
+ //
650
+ // {
651
+ // "topic": "publicTrade.BTCUSDT",
652
+ // "type": "snapshot",
653
+ // "ts": 1672304486868,
654
+ // "data": [
655
+ // {
656
+ // "T": 1672304486865,
657
+ // "s": "BTCUSDT",
658
+ // "S": "Buy",
659
+ // "v": "0.001",
660
+ // "p": "16578.50",
661
+ // "L": "PlusTick",
662
+ // "i": "20f43950-d8dd-5b31-9112-a178eb6023af",
663
+ // "BT": false
664
+ // }
665
+ // ]
666
+ // }
667
+ //
668
+ const data = this.safeValue(message, 'data', {});
669
+ const topic = this.safeString(message, 'topic');
670
+ const trades = data;
671
+ const parts = topic.split('.');
672
+ const isSpot = client.url.indexOf('spot') >= 0;
673
+ const marketType = (isSpot) ? 'spot' : 'contract';
674
+ const marketId = this.safeString(parts, 1);
675
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
676
+ const symbol = market['symbol'];
677
+ let stored = this.safeValue(this.trades, symbol);
678
+ if (stored === undefined) {
679
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
680
+ stored = new Cache.ArrayCache(limit);
681
+ this.trades[symbol] = stored;
682
+ }
683
+ for (let j = 0; j < trades.length; j++) {
684
+ const parsed = this.parseWsTrade(trades[j], market);
685
+ stored.append(parsed);
686
+ }
687
+ const messageHash = 'trade' + ':' + symbol;
688
+ client.resolve(stored, messageHash);
689
+ }
690
+ parseWsTrade(trade, market = undefined) {
691
+ //
692
+ // public
693
+ // {
694
+ // "T": 1672304486865,
695
+ // "s": "BTCUSDT",
696
+ // "S": "Buy",
697
+ // "v": "0.001",
698
+ // "p": "16578.50",
699
+ // "L": "PlusTick",
700
+ // "i": "20f43950-d8dd-5b31-9112-a178eb6023af",
701
+ // "BT": false
702
+ // }
703
+ //
704
+ // spot private
705
+ // {
706
+ // "e": "ticketInfo",
707
+ // "E": "1662348310386",
708
+ // "s": "BTCUSDT",
709
+ // "q": "0.001007",
710
+ // "t": "1662348310373",
711
+ // "p": "19842.02",
712
+ // "T": "2100000000002220938",
713
+ // "o": "1238261807653647872",
714
+ // "c": "spotx008",
715
+ // "O": "1238225004531834368",
716
+ // "a": "533287",
717
+ // "A": "642908",
718
+ // "m": false,
719
+ // "S": "BUY"
720
+ // }
721
+ //
722
+ const id = this.safeStringN(trade, ['i', 'T', 'v']);
723
+ const isContract = ('BT' in trade);
724
+ let marketType = isContract ? 'contract' : 'spot';
725
+ if (market !== undefined) {
726
+ marketType = market['type'];
727
+ }
728
+ const marketId = this.safeString(trade, 's');
729
+ market = this.safeMarket(marketId, market, undefined, marketType);
730
+ const symbol = market['symbol'];
731
+ const timestamp = this.safeInteger2(trade, 't', 'T');
732
+ let side = this.safeStringLower(trade, 'S');
733
+ let takerOrMaker = undefined;
734
+ const m = this.safeValue(trade, 'm');
735
+ if (side === undefined) {
736
+ side = m ? 'buy' : 'sell';
737
+ }
738
+ else {
739
+ // spot private
740
+ takerOrMaker = m;
741
+ }
742
+ const price = this.safeString(trade, 'p');
743
+ const amount = this.safeString2(trade, 'q', 'v');
744
+ const orderId = this.safeString(trade, 'o');
745
+ return this.safeTrade({
746
+ 'id': id,
747
+ 'info': trade,
748
+ 'timestamp': timestamp,
749
+ 'datetime': this.iso8601(timestamp),
750
+ 'symbol': symbol,
751
+ 'order': orderId,
752
+ 'type': undefined,
753
+ 'side': side,
754
+ 'takerOrMaker': takerOrMaker,
755
+ 'price': price,
756
+ 'amount': amount,
757
+ 'cost': undefined,
758
+ 'fee': undefined,
759
+ }, market);
760
+ }
761
+ getPrivateType(url) {
762
+ if (url.indexOf('spot') >= 0) {
763
+ return 'spot';
764
+ }
765
+ else if (url.indexOf('v5/private') >= 0) {
766
+ return 'unified';
767
+ }
768
+ else {
769
+ return 'usdc';
770
+ }
771
+ }
772
+ async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
773
+ /**
774
+ * @method
775
+ * @name bybit#watchMyTrades
776
+ * @description watches information on multiple trades made by the user
777
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/private/execution
778
+ * @param {string} symbol unified market symbol of the market orders were made in
779
+ * @param {int} [since] the earliest time in ms to fetch orders for
780
+ * @param {int} [limit] the maximum number of order structures to retrieve
781
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
782
+ * @param {boolean} [params.unifiedMargin] use unified margin account
783
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
784
+ */
785
+ const method = 'watchMyTrades';
786
+ let messageHash = 'myTrades';
787
+ await this.loadMarkets();
788
+ if (symbol !== undefined) {
789
+ symbol = this.symbol(symbol);
790
+ messageHash += ':' + symbol;
791
+ }
792
+ const url = this.getUrlByMarketType(symbol, true, method, params);
793
+ await this.authenticate(url);
794
+ const topicByMarket = {
795
+ 'spot': 'ticketInfo',
796
+ 'unified': 'execution',
797
+ 'usdc': 'user.openapi.perp.trade',
798
+ };
799
+ const topic = this.safeValue(topicByMarket, this.getPrivateType(url));
800
+ const trades = await this.watchTopics(url, [messageHash], [topic], params);
801
+ if (this.newUpdates) {
802
+ limit = trades.getLimit(symbol, limit);
803
+ }
804
+ return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
805
+ }
806
+ handleMyTrades(client, message) {
807
+ //
808
+ // spot
809
+ // {
810
+ // "type": "snapshot",
811
+ // "topic": "ticketInfo",
812
+ // "ts": "1662348310388",
813
+ // "data": [
814
+ // {
815
+ // "e": "ticketInfo",
816
+ // "E": "1662348310386",
817
+ // "s": "BTCUSDT",
818
+ // "q": "0.001007",
819
+ // "t": "1662348310373",
820
+ // "p": "19842.02",
821
+ // "T": "2100000000002220938",
822
+ // "o": "1238261807653647872",
823
+ // "c": "spotx008",
824
+ // "O": "1238225004531834368",
825
+ // "a": "533287",
826
+ // "A": "642908",
827
+ // "m": false,
828
+ // "S": "BUY"
829
+ // }
830
+ // ]
831
+ // }
832
+ // unified
833
+ // {
834
+ // "id": "592324803b2785-26fa-4214-9963-bdd4727f07be",
835
+ // "topic": "execution",
836
+ // "creationTime": 1672364174455,
837
+ // "data": [
838
+ // {
839
+ // "category": "linear",
840
+ // "symbol": "XRPUSDT",
841
+ // "execFee": "0.005061",
842
+ // "execId": "7e2ae69c-4edf-5800-a352-893d52b446aa",
843
+ // "execPrice": "0.3374",
844
+ // "execQty": "25",
845
+ // "execType": "Trade",
846
+ // "execValue": "8.435",
847
+ // "isMaker": false,
848
+ // "feeRate": "0.0006",
849
+ // "tradeIv": "",
850
+ // "markIv": "",
851
+ // "blockTradeId": "",
852
+ // "markPrice": "0.3391",
853
+ // "indexPrice": "",
854
+ // "underlyingPrice": "",
855
+ // "leavesQty": "0",
856
+ // "orderId": "f6e324ff-99c2-4e89-9739-3086e47f9381",
857
+ // "orderLinkId": "",
858
+ // "orderPrice": "0.3207",
859
+ // "orderQty": "25",
860
+ // "orderType": "Market",
861
+ // "stopOrderType": "UNKNOWN",
862
+ // "side": "Sell",
863
+ // "execTime": "1672364174443",
864
+ // "isLeverage": "0"
865
+ // }
866
+ // ]
867
+ // }
868
+ //
869
+ const topic = this.safeString(message, 'topic');
870
+ const spot = topic === 'ticketInfo';
871
+ let data = this.safeValue(message, 'data', []);
872
+ if (!Array.isArray(data)) {
873
+ data = this.safeValue(data, 'result', []);
874
+ }
875
+ if (this.myTrades === undefined) {
876
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
877
+ this.myTrades = new Cache.ArrayCacheBySymbolById(limit);
878
+ }
879
+ const trades = this.myTrades;
880
+ const symbols = {};
881
+ for (let i = 0; i < data.length; i++) {
882
+ const rawTrade = data[i];
883
+ let parsed = undefined;
884
+ if (spot) {
885
+ parsed = this.parseWsTrade(rawTrade);
886
+ }
887
+ else {
888
+ parsed = this.parseTrade(rawTrade);
889
+ }
890
+ const symbol = parsed['symbol'];
891
+ symbols[symbol] = true;
892
+ trades.append(parsed);
893
+ }
894
+ const keys = Object.keys(symbols);
895
+ for (let i = 0; i < keys.length; i++) {
896
+ const currentMessageHash = 'myTrades:' + keys[i];
897
+ client.resolve(trades, currentMessageHash);
898
+ }
899
+ // non-symbol specific
900
+ const messageHash = 'myTrades';
901
+ client.resolve(trades, messageHash);
902
+ }
903
+ async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
904
+ /**
905
+ * @method
906
+ * @name bybit#watchPositions
907
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/private/position
908
+ * @description watch all open positions
909
+ * @param {string[]|undefined} symbols list of unified market symbols
910
+ * @param {object} params extra parameters specific to the exchange API endpoint
911
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
912
+ */
913
+ await this.loadMarkets();
914
+ const method = 'watchPositions';
915
+ let messageHash = '';
916
+ if (!this.isEmpty(symbols)) {
917
+ symbols = this.marketSymbols(symbols);
918
+ messageHash = '::' + symbols.join(',');
919
+ }
920
+ const firstSymbol = this.safeString(symbols, 0);
921
+ const url = this.getUrlByMarketType(firstSymbol, true, method, params);
922
+ messageHash = 'positions' + messageHash;
923
+ const client = this.client(url);
924
+ await this.authenticate(url);
925
+ this.setPositionsCache(client, symbols);
926
+ const cache = this.positions;
927
+ const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
928
+ const awaitPositionsSnapshot = this.safeValue('watchPositions', 'awaitPositionsSnapshot', true);
929
+ if (fetchPositionsSnapshot && awaitPositionsSnapshot && cache === undefined) {
930
+ const snapshot = await client.future('fetchPositionsSnapshot');
931
+ return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
932
+ }
933
+ const topics = ['position'];
934
+ const newPositions = await this.watchTopics(url, [messageHash], topics, params);
935
+ if (this.newUpdates) {
936
+ return newPositions;
937
+ }
938
+ return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
939
+ }
940
+ setPositionsCache(client, symbols = undefined) {
941
+ if (this.positions !== undefined) {
942
+ return this.positions;
943
+ }
944
+ const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
945
+ if (fetchPositionsSnapshot) {
946
+ const messageHash = 'fetchPositionsSnapshot';
947
+ if (!(messageHash in client.futures)) {
948
+ client.future(messageHash);
949
+ this.spawn(this.loadPositionsSnapshot, client, messageHash);
950
+ }
951
+ }
952
+ else {
953
+ this.positions = new Cache.ArrayCacheBySymbolBySide();
954
+ }
955
+ }
956
+ async loadPositionsSnapshot(client, messageHash) {
957
+ // as only one ws channel gives positions for all types, for snapshot must load all positions
958
+ const fetchFunctions = [
959
+ this.fetchPositions(undefined, { 'type': 'swap', 'subType': 'linear' }),
960
+ this.fetchPositions(undefined, { 'type': 'swap', 'subType': 'inverse' }),
961
+ ];
962
+ const promises = await Promise.all(fetchFunctions);
963
+ this.positions = new Cache.ArrayCacheBySymbolBySide();
964
+ const cache = this.positions;
965
+ for (let i = 0; i < promises.length; i++) {
966
+ const positions = promises[i];
967
+ for (let ii = 0; ii < positions.length; ii++) {
968
+ const position = positions[ii];
969
+ cache.append(position);
970
+ }
971
+ }
972
+ // don't remove the future from the .futures cache
973
+ const future = client.futures[messageHash];
974
+ future.resolve(cache);
975
+ client.resolve(cache, 'position');
976
+ }
977
+ handlePositions(client, message) {
978
+ //
979
+ // {
980
+ // topic: 'position',
981
+ // id: '504b2671629b08e3c4f6960382a59363:3bc4028023786545:0:01',
982
+ // creationTime: 1694566055295,
983
+ // data: [{
984
+ // bustPrice: '15.00',
985
+ // category: 'inverse',
986
+ // createdTime: '1670083436351',
987
+ // cumRealisedPnl: '0.00011988',
988
+ // entryPrice: '19358.58553268',
989
+ // leverage: '10',
990
+ // liqPrice: '15.00',
991
+ // markPrice: '25924.00',
992
+ // positionBalance: '0.0000156',
993
+ // positionIdx: 0,
994
+ // positionMM: '0.001',
995
+ // positionIM: '0.0000015497',
996
+ // positionStatus: 'Normal',
997
+ // positionValue: '0.00015497',
998
+ // riskId: 1,
999
+ // riskLimitValue: '150',
1000
+ // side: 'Buy',
1001
+ // size: '3',
1002
+ // stopLoss: '0.00',
1003
+ // symbol: 'BTCUSD',
1004
+ // takeProfit: '0.00',
1005
+ // tpslMode: 'Full',
1006
+ // tradeMode: 0,
1007
+ // autoAddMargin: 1,
1008
+ // trailingStop: '0.00',
1009
+ // unrealisedPnl: '0.00003925',
1010
+ // updatedTime: '1694566055293',
1011
+ // adlRankIndicator: 3
1012
+ // }]
1013
+ // }
1014
+ //
1015
+ // each account is connected to a different endpoint
1016
+ // and has exactly one subscriptionhash which is the account type
1017
+ if (this.positions === undefined) {
1018
+ this.positions = new Cache.ArrayCacheBySymbolBySide();
1019
+ }
1020
+ const cache = this.positions;
1021
+ const newPositions = [];
1022
+ const rawPositions = this.safeValue(message, 'data', []);
1023
+ for (let i = 0; i < rawPositions.length; i++) {
1024
+ const rawPosition = rawPositions[i];
1025
+ const position = this.parsePosition(rawPosition);
1026
+ newPositions.push(position);
1027
+ cache.append(position);
1028
+ }
1029
+ const messageHashes = this.findMessageHashes(client, 'positions::');
1030
+ for (let i = 0; i < messageHashes.length; i++) {
1031
+ const messageHash = messageHashes[i];
1032
+ const parts = messageHash.split('::');
1033
+ const symbolsString = parts[1];
1034
+ const symbols = symbolsString.split(',');
1035
+ const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
1036
+ if (!this.isEmpty(positions)) {
1037
+ client.resolve(positions, messageHash);
1038
+ }
1039
+ }
1040
+ client.resolve(newPositions, 'positions');
1041
+ }
1042
+ async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1043
+ /**
1044
+ * @method
1045
+ * @name bybit#watchOrders
1046
+ * @description watches information on multiple orders made by the user
1047
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/private/order
1048
+ * @param {string} symbol unified market symbol of the market orders were made in
1049
+ * @param {int} [since] the earliest time in ms to fetch orders for
1050
+ * @param {int} [limit] the maximum number of order structures to retrieve
1051
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1052
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
1053
+ */
1054
+ await this.loadMarkets();
1055
+ const method = 'watchOrders';
1056
+ let messageHash = 'orders';
1057
+ if (symbol !== undefined) {
1058
+ symbol = this.symbol(symbol);
1059
+ messageHash += ':' + symbol;
1060
+ }
1061
+ const url = this.getUrlByMarketType(symbol, true, method, params);
1062
+ await this.authenticate(url);
1063
+ const topicsByMarket = {
1064
+ 'spot': ['order', 'stopOrder'],
1065
+ 'unified': ['order'],
1066
+ 'usdc': ['user.openapi.perp.order'],
1067
+ };
1068
+ const topics = this.safeValue(topicsByMarket, this.getPrivateType(url));
1069
+ const orders = await this.watchTopics(url, [messageHash], topics, params);
1070
+ if (this.newUpdates) {
1071
+ limit = orders.getLimit(symbol, limit);
1072
+ }
1073
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
1074
+ }
1075
+ handleOrder(client, message, subscription = undefined) {
1076
+ //
1077
+ // spot
1078
+ // {
1079
+ // "type": "snapshot",
1080
+ // "topic": "order",
1081
+ // "ts": "1662348310441",
1082
+ // "data": [
1083
+ // {
1084
+ // "e": "order",
1085
+ // "E": "1662348310441",
1086
+ // "s": "BTCUSDT",
1087
+ // "c": "spotx008",
1088
+ // "S": "BUY",
1089
+ // "o": "MARKET_OF_QUOTE",
1090
+ // "f": "GTC",
1091
+ // "q": "20",
1092
+ // "p": "0",
1093
+ // "X": "CANCELED",
1094
+ // "i": "1238261807653647872",
1095
+ // "M": "1238225004531834368",
1096
+ // "l": "0.001007",
1097
+ // "z": "0.001007",
1098
+ // "L": "19842.02",
1099
+ // "n": "0",
1100
+ // "N": "BTC",
1101
+ // "u": true,
1102
+ // "w": true,
1103
+ // "m": false,
1104
+ // "O": "1662348310368",
1105
+ // "Z": "19.98091414",
1106
+ // "A": "0",
1107
+ // "C": false,
1108
+ // "v": "0",
1109
+ // "d": "NO_LIQ",
1110
+ // "t": "2100000000002220938"
1111
+ // }
1112
+ // ]
1113
+ // }
1114
+ // unified
1115
+ // {
1116
+ // "id": "5923240c6880ab-c59f-420b-9adb-3639adc9dd90",
1117
+ // "topic": "order",
1118
+ // "creationTime": 1672364262474,
1119
+ // "data": [
1120
+ // {
1121
+ // "symbol": "ETH-30DEC22-1400-C",
1122
+ // "orderId": "5cf98598-39a7-459e-97bf-76ca765ee020",
1123
+ // "side": "Sell",
1124
+ // "orderType": "Market",
1125
+ // "cancelType": "UNKNOWN",
1126
+ // "price": "72.5",
1127
+ // "qty": "1",
1128
+ // "orderIv": "",
1129
+ // "timeInForce": "IOC",
1130
+ // "orderStatus": "Filled",
1131
+ // "orderLinkId": "",
1132
+ // "lastPriceOnCreated": "",
1133
+ // "reduceOnly": false,
1134
+ // "leavesQty": "",
1135
+ // "leavesValue": "",
1136
+ // "cumExecQty": "1",
1137
+ // "cumExecValue": "75",
1138
+ // "avgPrice": "75",
1139
+ // "blockTradeId": "",
1140
+ // "positionIdx": 0,
1141
+ // "cumExecFee": "0.358635",
1142
+ // "createdTime": "1672364262444",
1143
+ // "updatedTime": "1672364262457",
1144
+ // "rejectReason": "EC_NoError",
1145
+ // "stopOrderType": "",
1146
+ // "triggerPrice": "",
1147
+ // "takeProfit": "",
1148
+ // "stopLoss": "",
1149
+ // "tpTriggerBy": "",
1150
+ // "slTriggerBy": "",
1151
+ // "triggerDirection": 0,
1152
+ // "triggerBy": "",
1153
+ // "closeOnTrigger": false,
1154
+ // "category": "option"
1155
+ // }
1156
+ // ]
1157
+ // }
1158
+ //
1159
+ if (this.orders === undefined) {
1160
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
1161
+ this.orders = new Cache.ArrayCacheBySymbolById(limit);
1162
+ }
1163
+ const orders = this.orders;
1164
+ let rawOrders = this.safeValue(message, 'data', []);
1165
+ const first = this.safeValue(rawOrders, 0, {});
1166
+ const category = this.safeString(first, 'category');
1167
+ const isSpot = category === 'spot';
1168
+ if (!isSpot) {
1169
+ rawOrders = this.safeValue(rawOrders, 'result', rawOrders);
1170
+ }
1171
+ const symbols = {};
1172
+ for (let i = 0; i < rawOrders.length; i++) {
1173
+ let parsed = undefined;
1174
+ if (isSpot) {
1175
+ parsed = this.parseWsSpotOrder(rawOrders[i]);
1176
+ }
1177
+ else {
1178
+ parsed = this.parseOrder(rawOrders[i]);
1179
+ }
1180
+ const symbol = parsed['symbol'];
1181
+ symbols[symbol] = true;
1182
+ orders.append(parsed);
1183
+ }
1184
+ const symbolsArray = Object.keys(symbols);
1185
+ for (let i = 0; i < symbolsArray.length; i++) {
1186
+ const currentMessageHash = 'orders:' + symbolsArray[i];
1187
+ client.resolve(orders, currentMessageHash);
1188
+ }
1189
+ const messageHash = 'orders';
1190
+ client.resolve(orders, messageHash);
1191
+ }
1192
+ parseWsSpotOrder(order, market = undefined) {
1193
+ //
1194
+ // {
1195
+ // "e": "executionReport",
1196
+ // "E": "1653297251061", // timestamp
1197
+ // "s": "LTCUSDT", // symbol
1198
+ // "c": "1653297250740", // user id
1199
+ // "S": "SELL", // side
1200
+ // "o": "MARKET_OF_BASE", // order type
1201
+ // "f": "GTC", // time in force
1202
+ // "q": "0.16233", // quantity
1203
+ // "p": "0", // price
1204
+ // "X": "NEW", // status
1205
+ // "i": "1162336018974750208", // order id
1206
+ // "M": "0",
1207
+ // "l": "0", // last filled
1208
+ // "z": "0", // total filled
1209
+ // "L": "0", // last traded price
1210
+ // "n": "0", // trading fee
1211
+ // "N": '', // fee asset
1212
+ // "u": true,
1213
+ // "w": true,
1214
+ // "m": false, // is limit_maker
1215
+ // "O": "1653297251042", // order creation
1216
+ // "Z": "0", // total filled
1217
+ // "A": "0", // account id
1218
+ // "C": false, // is close
1219
+ // "v": "0", // leverage
1220
+ // "d": "NO_LIQ"
1221
+ // }
1222
+ // v5
1223
+ // {
1224
+ // "category":"spot",
1225
+ // "symbol":"LTCUSDT",
1226
+ // "orderId":"1474764674982492160",
1227
+ // "orderLinkId":"1690541649154749",
1228
+ // "blockTradeId":"",
1229
+ // "side":"Buy",
1230
+ // "positionIdx":0,
1231
+ // "orderStatus":"Cancelled",
1232
+ // "cancelType":"UNKNOWN",
1233
+ // "rejectReason":"EC_NoError",
1234
+ // "timeInForce":"GTC",
1235
+ // "isLeverage":"0",
1236
+ // "price":"0",
1237
+ // "qty":"5.00000",
1238
+ // "avgPrice":"0",
1239
+ // "leavesQty":"0.00000",
1240
+ // "leavesValue":"5.0000000",
1241
+ // "cumExecQty":"0.00000",
1242
+ // "cumExecValue":"0.0000000",
1243
+ // "cumExecFee":"",
1244
+ // "orderType":"Market",
1245
+ // "stopOrderType":"",
1246
+ // "orderIv":"",
1247
+ // "triggerPrice":"0.000",
1248
+ // "takeProfit":"",
1249
+ // "stopLoss":"",
1250
+ // "triggerBy":"",
1251
+ // "tpTriggerBy":"",
1252
+ // "slTriggerBy":"",
1253
+ // "triggerDirection":0,
1254
+ // "placeType":"",
1255
+ // "lastPriceOnCreated":"0.000",
1256
+ // "closeOnTrigger":false,
1257
+ // "reduceOnly":false,
1258
+ // "smpGroup":0,
1259
+ // "smpType":"None",
1260
+ // "smpOrderId":"",
1261
+ // "createdTime":"1690541649160",
1262
+ // "updatedTime":"1690541649168"
1263
+ // }
1264
+ //
1265
+ const id = this.safeString2(order, 'i', 'orderId');
1266
+ const marketId = this.safeString2(order, 's', 'symbol');
1267
+ const symbol = this.safeSymbol(marketId, market, undefined, 'spot');
1268
+ const timestamp = this.safeInteger2(order, 'O', 'createdTime');
1269
+ let price = this.safeString2(order, 'p', 'price');
1270
+ if (price === '0') {
1271
+ price = undefined; // market orders
1272
+ }
1273
+ const filled = this.safeString2(order, 'z', 'cumExecQty');
1274
+ const status = this.parseOrderStatus(this.safeString2(order, 'X', 'orderStatus'));
1275
+ const side = this.safeStringLower2(order, 'S', 'side');
1276
+ const lastTradeTimestamp = this.safeString2(order, 'E', 'updatedTime');
1277
+ const timeInForce = this.safeString2(order, 'f', 'timeInForce');
1278
+ let amount = undefined;
1279
+ const cost = this.safeString2(order, 'Z', 'cumExecValue');
1280
+ let type = this.safeStringLower2(order, 'o', 'orderType');
1281
+ if ((type !== undefined) && (type.indexOf('market') >= 0)) {
1282
+ type = 'market';
1283
+ }
1284
+ if (type === 'market' && side === 'buy') {
1285
+ amount = filled;
1286
+ }
1287
+ else {
1288
+ amount = this.safeString2(order, 'orderQty', 'qty');
1289
+ }
1290
+ let fee = undefined;
1291
+ const feeCost = this.safeString2(order, 'n', 'cumExecFee');
1292
+ if (feeCost !== undefined && feeCost !== '0') {
1293
+ const feeCurrencyId = this.safeString(order, 'N');
1294
+ const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
1295
+ fee = {
1296
+ 'cost': feeCost,
1297
+ 'currency': feeCurrencyCode,
1298
+ };
1299
+ }
1300
+ const triggerPrice = this.omitZero(this.safeString(order, 'triggerPrice'));
1301
+ return this.safeOrder({
1302
+ 'info': order,
1303
+ 'id': id,
1304
+ 'clientOrderId': this.safeString2(order, 'c', 'orderLinkId'),
1305
+ 'timestamp': timestamp,
1306
+ 'datetime': this.iso8601(timestamp),
1307
+ 'lastTradeTimestamp': lastTradeTimestamp,
1308
+ 'symbol': symbol,
1309
+ 'type': type,
1310
+ 'timeInForce': timeInForce,
1311
+ 'postOnly': undefined,
1312
+ 'side': side,
1313
+ 'price': price,
1314
+ 'stopPrice': triggerPrice,
1315
+ 'triggerPrice': triggerPrice,
1316
+ 'takeProfitPrice': this.safeString(order, 'takeProfit'),
1317
+ 'stopLossPrice': this.safeString(order, 'stopLoss'),
1318
+ 'reduceOnly': this.safeValue(order, 'reduceOnly'),
1319
+ 'amount': amount,
1320
+ 'cost': cost,
1321
+ 'average': this.safeString(order, 'avgPrice'),
1322
+ 'filled': filled,
1323
+ 'remaining': undefined,
1324
+ 'status': status,
1325
+ 'fee': fee,
1326
+ }, market);
1327
+ }
1328
+ async watchBalance(params = {}) {
1329
+ /**
1330
+ * @method
1331
+ * @name bybit#watchBalance
1332
+ * @description watch balance and get the amount of funds available for trading or funds locked in orders
1333
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/private/wallet
1334
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1335
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1336
+ */
1337
+ await this.loadMarkets();
1338
+ const method = 'watchBalance';
1339
+ let messageHash = 'balances';
1340
+ let type = undefined;
1341
+ [type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
1342
+ let subType = undefined;
1343
+ [subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
1344
+ const unified = await this.isUnifiedEnabled();
1345
+ const isUnifiedMargin = this.safeValue(unified, 0, false);
1346
+ const isUnifiedAccount = this.safeValue(unified, 1, false);
1347
+ const url = this.getUrlByMarketType(undefined, true, method, params);
1348
+ await this.authenticate(url);
1349
+ const topicByMarket = {
1350
+ 'spot': 'outboundAccountInfo',
1351
+ 'unified': 'wallet',
1352
+ };
1353
+ if (isUnifiedAccount) {
1354
+ // unified account
1355
+ if (subType === 'inverse') {
1356
+ messageHash += ':contract';
1357
+ }
1358
+ else {
1359
+ messageHash += ':unified';
1360
+ }
1361
+ }
1362
+ if (!isUnifiedMargin && !isUnifiedAccount) {
1363
+ // normal account using v5
1364
+ if (type === 'spot') {
1365
+ messageHash += ':spot';
1366
+ }
1367
+ else {
1368
+ messageHash += ':contract';
1369
+ }
1370
+ }
1371
+ if (isUnifiedMargin) {
1372
+ // unified margin account using v5
1373
+ if (type === 'spot') {
1374
+ messageHash += ':spot';
1375
+ }
1376
+ else {
1377
+ if (subType === 'linear') {
1378
+ messageHash += ':unified';
1379
+ }
1380
+ else {
1381
+ messageHash += ':contract';
1382
+ }
1383
+ }
1384
+ }
1385
+ const topics = [this.safeValue(topicByMarket, this.getPrivateType(url))];
1386
+ return await this.watchTopics(url, [messageHash], topics, params);
1387
+ }
1388
+ handleBalance(client, message) {
1389
+ //
1390
+ // spot
1391
+ // {
1392
+ // "type": "snapshot",
1393
+ // "topic": "outboundAccountInfo",
1394
+ // "ts": "1662107217641",
1395
+ // "data": [
1396
+ // {
1397
+ // "e": "outboundAccountInfo",
1398
+ // "E": "1662107217640",
1399
+ // "T": true,
1400
+ // "W": true,
1401
+ // "D": true,
1402
+ // "B": [
1403
+ // {
1404
+ // "a": "USDT",
1405
+ // "f": "176.81254174",
1406
+ // "l": "201.575"
1407
+ // }
1408
+ // ]
1409
+ // }
1410
+ // ]
1411
+ // }
1412
+ // unified
1413
+ // {
1414
+ // "id": "5923242c464be9-25ca-483d-a743-c60101fc656f",
1415
+ // "topic": "wallet",
1416
+ // "creationTime": 1672364262482,
1417
+ // "data": [
1418
+ // {
1419
+ // "accountIMRate": "0.016",
1420
+ // "accountMMRate": "0.003",
1421
+ // "totalEquity": "12837.78330098",
1422
+ // "totalWalletBalance": "12840.4045924",
1423
+ // "totalMarginBalance": "12837.78330188",
1424
+ // "totalAvailableBalance": "12632.05767702",
1425
+ // "totalPerpUPL": "-2.62129051",
1426
+ // "totalInitialMargin": "205.72562486",
1427
+ // "totalMaintenanceMargin": "39.42876721",
1428
+ // "coin": [
1429
+ // {
1430
+ // "coin": "USDC",
1431
+ // "equity": "200.62572554",
1432
+ // "usdValue": "200.62572554",
1433
+ // "walletBalance": "201.34882644",
1434
+ // "availableToWithdraw": "0",
1435
+ // "availableToBorrow": "1500000",
1436
+ // "borrowAmount": "0",
1437
+ // "accruedInterest": "0",
1438
+ // "totalOrderIM": "0",
1439
+ // "totalPositionIM": "202.99874213",
1440
+ // "totalPositionMM": "39.14289747",
1441
+ // "unrealisedPnl": "74.2768991",
1442
+ // "cumRealisedPnl": "-209.1544627",
1443
+ // "bonus": "0"
1444
+ // },
1445
+ // {
1446
+ // "coin": "BTC",
1447
+ // "equity": "0.06488393",
1448
+ // "usdValue": "1023.08402268",
1449
+ // "walletBalance": "0.06488393",
1450
+ // "availableToWithdraw": "0.06488393",
1451
+ // "availableToBorrow": "2.5",
1452
+ // "borrowAmount": "0",
1453
+ // "accruedInterest": "0",
1454
+ // "totalOrderIM": "0",
1455
+ // "totalPositionIM": "0",
1456
+ // "totalPositionMM": "0",
1457
+ // "unrealisedPnl": "0",
1458
+ // "cumRealisedPnl": "0",
1459
+ // "bonus": "0"
1460
+ // },
1461
+ // {
1462
+ // "coin": "ETH",
1463
+ // "equity": "0",
1464
+ // "usdValue": "0",
1465
+ // "walletBalance": "0",
1466
+ // "availableToWithdraw": "0",
1467
+ // "availableToBorrow": "26",
1468
+ // "borrowAmount": "0",
1469
+ // "accruedInterest": "0",
1470
+ // "totalOrderIM": "0",
1471
+ // "totalPositionIM": "0",
1472
+ // "totalPositionMM": "0",
1473
+ // "unrealisedPnl": "0",
1474
+ // "cumRealisedPnl": "0",
1475
+ // "bonus": "0"
1476
+ // },
1477
+ // {
1478
+ // "coin": "USDT",
1479
+ // "equity": "11726.64664904",
1480
+ // "usdValue": "11613.58597018",
1481
+ // "walletBalance": "11728.54414904",
1482
+ // "availableToWithdraw": "11723.92075829",
1483
+ // "availableToBorrow": "2500000",
1484
+ // "borrowAmount": "0",
1485
+ // "accruedInterest": "0",
1486
+ // "totalOrderIM": "0",
1487
+ // "totalPositionIM": "2.72589075",
1488
+ // "totalPositionMM": "0.28576575",
1489
+ // "unrealisedPnl": "-1.8975",
1490
+ // "cumRealisedPnl": "0.64782276",
1491
+ // "bonus": "0"
1492
+ // },
1493
+ // {
1494
+ // "coin": "EOS3L",
1495
+ // "equity": "215.0570412",
1496
+ // "usdValue": "0",
1497
+ // "walletBalance": "215.0570412",
1498
+ // "availableToWithdraw": "215.0570412",
1499
+ // "availableToBorrow": "0",
1500
+ // "borrowAmount": "0",
1501
+ // "accruedInterest": "",
1502
+ // "totalOrderIM": "0",
1503
+ // "totalPositionIM": "0",
1504
+ // "totalPositionMM": "0",
1505
+ // "unrealisedPnl": "0",
1506
+ // "cumRealisedPnl": "0",
1507
+ // "bonus": "0"
1508
+ // },
1509
+ // {
1510
+ // "coin": "BIT",
1511
+ // "equity": "1.82",
1512
+ // "usdValue": "0.48758257",
1513
+ // "walletBalance": "1.82",
1514
+ // "availableToWithdraw": "1.82",
1515
+ // "availableToBorrow": "0",
1516
+ // "borrowAmount": "0",
1517
+ // "accruedInterest": "",
1518
+ // "totalOrderIM": "0",
1519
+ // "totalPositionIM": "0",
1520
+ // "totalPositionMM": "0",
1521
+ // "unrealisedPnl": "0",
1522
+ // "cumRealisedPnl": "0",
1523
+ // "bonus": "0"
1524
+ // }
1525
+ // ],
1526
+ // "accountType": "UNIFIED"
1527
+ // }
1528
+ // ]
1529
+ // }
1530
+ //
1531
+ if (this.balance === undefined) {
1532
+ this.balance = {};
1533
+ }
1534
+ let messageHash = 'balance';
1535
+ const topic = this.safeValue(message, 'topic');
1536
+ let info = undefined;
1537
+ let rawBalances = [];
1538
+ let account = undefined;
1539
+ if (topic === 'outboundAccountInfo') {
1540
+ account = 'spot';
1541
+ const data = this.safeValue(message, 'data', []);
1542
+ for (let i = 0; i < data.length; i++) {
1543
+ const B = this.safeValue(data[i], 'B', []);
1544
+ rawBalances = this.arrayConcat(rawBalances, B);
1545
+ }
1546
+ info = rawBalances;
1547
+ }
1548
+ if (topic === 'wallet') {
1549
+ const data = this.safeValue(message, 'data', {});
1550
+ for (let i = 0; i < data.length; i++) {
1551
+ const result = this.safeValue(data, 0, {});
1552
+ account = this.safeStringLower(result, 'accountType');
1553
+ rawBalances = this.arrayConcat(rawBalances, this.safeValue(result, 'coin', []));
1554
+ }
1555
+ info = data;
1556
+ }
1557
+ for (let i = 0; i < rawBalances.length; i++) {
1558
+ this.parseWsBalance(rawBalances[i], account);
1559
+ }
1560
+ if (account !== undefined) {
1561
+ if (this.safeValue(this.balance, account) === undefined) {
1562
+ this.balance[account] = {};
1563
+ }
1564
+ this.balance[account]['info'] = info;
1565
+ const timestamp = this.safeInteger(message, 'ts');
1566
+ this.balance[account]['timestamp'] = timestamp;
1567
+ this.balance[account]['datetime'] = this.iso8601(timestamp);
1568
+ this.balance[account] = this.safeBalance(this.balance[account]);
1569
+ messageHash = 'balances:' + account;
1570
+ client.resolve(this.balance[account], messageHash);
1571
+ }
1572
+ else {
1573
+ this.balance['info'] = info;
1574
+ const timestamp = this.safeInteger(message, 'ts');
1575
+ this.balance['timestamp'] = timestamp;
1576
+ this.balance['datetime'] = this.iso8601(timestamp);
1577
+ this.balance = this.safeBalance(this.balance);
1578
+ messageHash = 'balances';
1579
+ client.resolve(this.balance, messageHash);
1580
+ }
1581
+ }
1582
+ parseWsBalance(balance, accountType = undefined) {
1583
+ //
1584
+ // spot
1585
+ // {
1586
+ // "a": "USDT",
1587
+ // "f": "176.81254174",
1588
+ // "l": "201.575"
1589
+ // }
1590
+ // unified
1591
+ // {
1592
+ // "coin": "BTC",
1593
+ // "equity": "0.06488393",
1594
+ // "usdValue": "1023.08402268",
1595
+ // "walletBalance": "0.06488393",
1596
+ // "availableToWithdraw": "0.06488393",
1597
+ // "availableToBorrow": "2.5",
1598
+ // "borrowAmount": "0",
1599
+ // "accruedInterest": "0",
1600
+ // "totalOrderIM": "0",
1601
+ // "totalPositionIM": "0",
1602
+ // "totalPositionMM": "0",
1603
+ // "unrealisedPnl": "0",
1604
+ // "cumRealisedPnl": "0",
1605
+ // "bonus": "0"
1606
+ // }
1607
+ //
1608
+ const account = this.account();
1609
+ const currencyId = this.safeString2(balance, 'a', 'coin');
1610
+ const code = this.safeCurrencyCode(currencyId);
1611
+ account['free'] = this.safeStringN(balance, ['availableToWithdraw', 'f', 'free', 'availableToWithdraw']);
1612
+ account['used'] = this.safeString2(balance, 'l', 'locked');
1613
+ account['total'] = this.safeString(balance, 'walletBalance');
1614
+ if (accountType !== undefined) {
1615
+ if (this.safeValue(this.balance, accountType) === undefined) {
1616
+ this.balance[accountType] = {};
1617
+ }
1618
+ this.balance[accountType][code] = account;
1619
+ }
1620
+ else {
1621
+ this.balance[code] = account;
1622
+ }
1623
+ }
1624
+ async watchTopics(url, messageHashes, topics, params = {}) {
1625
+ const request = {
1626
+ 'op': 'subscribe',
1627
+ 'req_id': this.requestId(),
1628
+ 'args': topics,
1629
+ };
1630
+ const message = this.extend(request, params);
1631
+ return await this.watchMultiple(url, messageHashes, message, topics);
1632
+ }
1633
+ async authenticate(url, params = {}) {
1634
+ this.checkRequiredCredentials();
1635
+ const messageHash = 'authenticated';
1636
+ const client = this.client(url);
1637
+ const future = client.future(messageHash);
1638
+ const authenticated = this.safeValue(client.subscriptions, messageHash);
1639
+ if (authenticated === undefined) {
1640
+ const expiresInt = this.milliseconds() + 10000;
1641
+ const expires = expiresInt.toString();
1642
+ const path = 'GET/realtime';
1643
+ const auth = path + expires;
1644
+ const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256, 'hex');
1645
+ const request = {
1646
+ 'op': 'auth',
1647
+ 'args': [
1648
+ this.apiKey, expires, signature,
1649
+ ],
1650
+ };
1651
+ const message = this.extend(request, params);
1652
+ this.watch(url, messageHash, message, messageHash);
1653
+ }
1654
+ return future;
1655
+ }
1656
+ handleErrorMessage(client, message) {
1657
+ //
1658
+ // {
1659
+ // "success": false,
1660
+ // "ret_msg": "error:invalid op",
1661
+ // "conn_id": "5e079fdd-9c7f-404d-9dbf-969d650838b5",
1662
+ // "request": { op: '', args: null }
1663
+ // }
1664
+ //
1665
+ // auth error
1666
+ //
1667
+ // {
1668
+ // "success": false,
1669
+ // "ret_msg": "error:USVC1111",
1670
+ // "conn_id": "e73770fb-a0dc-45bd-8028-140e20958090",
1671
+ // "request": {
1672
+ // "op": "auth",
1673
+ // "args": [
1674
+ // "9rFT6uR4uz9Imkw4Wx",
1675
+ // "1653405853543",
1676
+ // "542e71bd85597b4db0290f0ce2d13ed1fd4bb5df3188716c1e9cc69a879f7889"
1677
+ // ]
1678
+ // }
1679
+ //
1680
+ // { code: '-10009', desc: "Invalid period!" }
1681
+ //
1682
+ const code = this.safeString2(message, 'code', 'ret_code');
1683
+ try {
1684
+ if (code !== undefined) {
1685
+ const feedback = this.id + ' ' + this.json(message);
1686
+ this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
1687
+ }
1688
+ const success = this.safeValue(message, 'success');
1689
+ if (success !== undefined && !success) {
1690
+ const ret_msg = this.safeString(message, 'ret_msg');
1691
+ const request = this.safeValue(message, 'request', {});
1692
+ const op = this.safeString(request, 'op');
1693
+ if (op === 'auth') {
1694
+ throw new errors.AuthenticationError('Authentication failed: ' + ret_msg);
1695
+ }
1696
+ else {
1697
+ throw new errors.ExchangeError(this.id + ' ' + ret_msg);
1698
+ }
1699
+ }
1700
+ return false;
1701
+ }
1702
+ catch (error) {
1703
+ if (error instanceof errors.AuthenticationError) {
1704
+ const messageHash = 'authenticated';
1705
+ client.reject(error, messageHash);
1706
+ if (messageHash in client.subscriptions) {
1707
+ delete client.subscriptions[messageHash];
1708
+ }
1709
+ }
1710
+ else {
1711
+ client.reject(error);
1712
+ }
1713
+ return true;
1714
+ }
1715
+ }
1716
+ handleMessage(client, message) {
1717
+ if (this.handleErrorMessage(client, message)) {
1718
+ return;
1719
+ }
1720
+ // contract pong
1721
+ const ret_msg = this.safeString(message, 'ret_msg');
1722
+ if (ret_msg === 'pong') {
1723
+ this.handlePong(client, message);
1724
+ return;
1725
+ }
1726
+ // spot pong
1727
+ const pong = this.safeInteger(message, 'pong');
1728
+ if (pong !== undefined) {
1729
+ this.handlePong(client, message);
1730
+ return;
1731
+ }
1732
+ // pong
1733
+ const op = this.safeString(message, 'op');
1734
+ if (op === 'pong') {
1735
+ this.handlePong(client, message);
1736
+ return;
1737
+ }
1738
+ const event = this.safeString(message, 'event');
1739
+ if (event === 'sub') {
1740
+ this.handleSubscriptionStatus(client, message);
1741
+ return;
1742
+ }
1743
+ const topic = this.safeString(message, 'topic', '');
1744
+ const methods = {
1745
+ 'orderbook': this.handleOrderBook,
1746
+ 'kline': this.handleOHLCV,
1747
+ 'order': this.handleOrder,
1748
+ 'stopOrder': this.handleOrder,
1749
+ 'ticker': this.handleTicker,
1750
+ 'trade': this.handleTrades,
1751
+ 'publicTrade': this.handleTrades,
1752
+ 'depth': this.handleOrderBook,
1753
+ 'wallet': this.handleBalance,
1754
+ 'outboundAccountInfo': this.handleBalance,
1755
+ 'execution': this.handleMyTrades,
1756
+ 'ticketInfo': this.handleMyTrades,
1757
+ 'user.openapi.perp.trade': this.handleMyTrades,
1758
+ 'position': this.handlePositions,
1759
+ };
1760
+ const exacMethod = this.safeValue(methods, topic);
1761
+ if (exacMethod !== undefined) {
1762
+ exacMethod.call(this, client, message);
1763
+ return;
1764
+ }
1765
+ const keys = Object.keys(methods);
1766
+ for (let i = 0; i < keys.length; i++) {
1767
+ const key = keys[i];
1768
+ if (topic.indexOf(keys[i]) >= 0) {
1769
+ const method = methods[key];
1770
+ method.call(this, client, message);
1771
+ return;
1772
+ }
1773
+ }
1774
+ // unified auth acknowledgement
1775
+ const type = this.safeString(message, 'type');
1776
+ if ((op === 'auth') || (type === 'AUTH_RESP')) {
1777
+ this.handleAuthenticate(client, message);
1778
+ }
1779
+ }
1780
+ ping(client) {
1781
+ return {
1782
+ 'req_id': this.requestId(),
1783
+ 'op': 'ping',
1784
+ };
1785
+ }
1786
+ handlePong(client, message) {
1787
+ //
1788
+ // {
1789
+ // "success": true,
1790
+ // "ret_msg": "pong",
1791
+ // "conn_id": "db3158a0-8960-44b9-a9de-ac350ee13158",
1792
+ // "request": { op: "ping", args: null }
1793
+ // }
1794
+ //
1795
+ // { pong: 1653296711335 }
1796
+ //
1797
+ client.lastPong = this.safeInteger(message, 'pong');
1798
+ return message;
1799
+ }
1800
+ handleAuthenticate(client, message) {
1801
+ //
1802
+ // {
1803
+ // "success": true,
1804
+ // "ret_msg": '',
1805
+ // "op": "auth",
1806
+ // "conn_id": "ce3dpomvha7dha97tvp0-2xh"
1807
+ // }
1808
+ //
1809
+ const success = this.safeValue(message, 'success');
1810
+ const messageHash = 'authenticated';
1811
+ if (success) {
1812
+ const future = this.safeValue(client.futures, messageHash);
1813
+ future.resolve(true);
1814
+ }
1815
+ else {
1816
+ const error = new errors.AuthenticationError(this.id + ' ' + this.json(message));
1817
+ client.reject(error, messageHash);
1818
+ if (messageHash in client.subscriptions) {
1819
+ delete client.subscriptions[messageHash];
1820
+ }
1821
+ }
1822
+ return message;
1823
+ }
1824
+ handleSubscriptionStatus(client, message) {
1825
+ //
1826
+ // {
1827
+ // "topic": "kline",
1828
+ // "event": "sub",
1829
+ // "params": {
1830
+ // "symbol": "LTCUSDT",
1831
+ // "binary": "false",
1832
+ // "klineType": "1m",
1833
+ // "symbolName": "LTCUSDT"
1834
+ // },
1835
+ // "code": "0",
1836
+ // "msg": "Success"
1837
+ // }
1838
+ //
1839
+ return message;
1840
+ }
1841
+ }
1842
+
1843
+ module.exports = bybit;