ccxt-ir 4.10.0 → 4.12.0

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 (1059) hide show
  1. package/README.md +4 -4
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +10 -1
  4. package/dist/cjs/src/abstract/bidarz.js +11 -0
  5. package/dist/cjs/src/bidarz.js +337 -0
  6. package/dist/cjs/src/bit24.js +4 -3
  7. package/dist/cjs/src/changefa.js +342 -0
  8. package/dist/cjs/src/ourbit.js +445 -0
  9. package/js/ccxt.d.ts +11 -2
  10. package/js/ccxt.js +8 -2
  11. package/js/src/abstract/bidarz.d.ts +9 -0
  12. package/js/src/abstract/bidarz.js +11 -0
  13. package/js/src/abstract/changefa.d.ts +8 -0
  14. package/js/src/abstract/changefa.js +11 -0
  15. package/js/src/abstract/ourbit.d.ts +10 -0
  16. package/js/src/abstract/ourbit.js +11 -0
  17. package/js/src/bidarz.d.ts +22 -0
  18. package/js/src/bidarz.js +336 -0
  19. package/js/src/bit24.js +4 -3
  20. package/js/src/changefa.d.ts +20 -0
  21. package/js/src/changefa.js +341 -0
  22. package/js/src/ourbit.d.ts +21 -0
  23. package/js/src/ourbit.js +444 -0
  24. package/js/src/src/abantether.d.ts +21 -0
  25. package/js/src/src/abantether.js +353 -0
  26. package/js/src/src/abstract/abantether.d.ts +8 -0
  27. package/js/src/src/abstract/abantether.js +11 -0
  28. package/js/src/src/abstract/afratether.d.ts +9 -0
  29. package/js/src/src/abstract/afratether.js +11 -0
  30. package/js/src/src/abstract/alpaca.d.ts +77 -0
  31. package/js/src/src/abstract/alpaca.js +11 -0
  32. package/js/src/src/abstract/apex.d.ts +34 -0
  33. package/js/src/src/abstract/apex.js +11 -0
  34. package/js/src/src/abstract/arzinja.d.ts +8 -0
  35. package/js/src/src/abstract/arzinja.js +11 -0
  36. package/js/src/src/abstract/arzplus.d.ts +11 -0
  37. package/js/src/src/abstract/arzplus.js +11 -0
  38. package/js/src/src/abstract/ascendex.d.ts +80 -0
  39. package/js/src/src/abstract/ascendex.js +11 -0
  40. package/js/src/src/abstract/asretether.d.ts +8 -0
  41. package/js/src/src/abstract/asretether.js +11 -0
  42. package/js/src/src/abstract/bidarz.d.ts +9 -0
  43. package/js/src/src/abstract/bidarz.js +11 -0
  44. package/js/src/src/abstract/bigone.d.ts +48 -0
  45. package/js/src/src/abstract/bigone.js +11 -0
  46. package/js/src/src/abstract/binance.d.ts +773 -0
  47. package/js/src/src/abstract/binance.js +11 -0
  48. package/js/src/src/abstract/bingx.d.ts +165 -0
  49. package/js/src/src/abstract/bingx.js +11 -0
  50. package/js/src/src/abstract/bit24.d.ts +9 -0
  51. package/js/src/src/abstract/bit24.js +11 -0
  52. package/js/src/src/abstract/bit2c.d.ts +30 -0
  53. package/js/src/src/abstract/bit2c.js +11 -0
  54. package/js/src/src/abstract/bitbank.d.ts +35 -0
  55. package/js/src/src/abstract/bitbank.js +11 -0
  56. package/js/src/src/abstract/bitbarg.d.ts +8 -0
  57. package/js/src/src/abstract/bitbarg.js +11 -0
  58. package/js/src/src/abstract/bitbns.d.ts +43 -0
  59. package/js/src/src/abstract/bitbns.js +11 -0
  60. package/js/src/src/abstract/bitfinex.d.ts +143 -0
  61. package/js/src/src/abstract/bitfinex.js +11 -0
  62. package/js/src/src/abstract/bitflyer.d.ts +42 -0
  63. package/js/src/src/abstract/bitflyer.js +11 -0
  64. package/js/src/src/abstract/bitget.d.ts +578 -0
  65. package/js/src/src/abstract/bitget.js +11 -0
  66. package/js/src/src/abstract/bithumb.d.ts +35 -0
  67. package/js/src/src/abstract/bithumb.js +11 -0
  68. package/js/src/src/abstract/bitimen.d.ts +10 -0
  69. package/js/src/src/abstract/bitimen.js +11 -0
  70. package/js/src/src/abstract/bitir.d.ts +10 -0
  71. package/js/src/src/abstract/bitir.js +11 -0
  72. package/js/src/src/abstract/bitmart.d.ts +120 -0
  73. package/js/src/src/abstract/bitmart.js +11 -0
  74. package/js/src/src/abstract/bitmex.d.ts +100 -0
  75. package/js/src/src/abstract/bitmex.js +11 -0
  76. package/js/src/src/abstract/bitopro.d.ts +33 -0
  77. package/js/src/src/abstract/bitopro.js +11 -0
  78. package/js/src/src/abstract/bitpin.d.ts +11 -0
  79. package/js/src/src/abstract/bitpin.js +11 -0
  80. package/js/src/src/abstract/bitrue.d.ts +75 -0
  81. package/js/src/src/abstract/bitrue.js +11 -0
  82. package/js/src/src/abstract/bitso.d.ts +46 -0
  83. package/js/src/src/abstract/bitso.js +11 -0
  84. package/js/src/src/abstract/bitstamp.d.ts +262 -0
  85. package/js/src/src/abstract/bitstamp.js +11 -0
  86. package/js/src/src/abstract/bitteam.d.ts +32 -0
  87. package/js/src/src/abstract/bitteam.js +11 -0
  88. package/js/src/src/abstract/bittrade.d.ts +117 -0
  89. package/js/src/src/abstract/bittrade.js +11 -0
  90. package/js/src/src/abstract/bitunix.d.ts +9 -0
  91. package/js/src/src/abstract/bitunix.js +11 -0
  92. package/js/src/src/abstract/bitvavo.d.ts +30 -0
  93. package/js/src/src/abstract/bitvavo.js +11 -0
  94. package/js/src/src/abstract/blockchaincom.d.ts +31 -0
  95. package/js/src/src/abstract/blockchaincom.js +11 -0
  96. package/js/src/src/abstract/blofin.d.ts +70 -0
  97. package/js/src/src/abstract/blofin.js +11 -0
  98. package/js/src/src/abstract/btcalpha.d.ts +21 -0
  99. package/js/src/src/abstract/btcalpha.js +11 -0
  100. package/js/src/src/abstract/btcbox.d.ts +18 -0
  101. package/js/src/src/abstract/btcbox.js +11 -0
  102. package/js/src/src/abstract/btcmarkets.d.ts +42 -0
  103. package/js/src/src/abstract/btcmarkets.js +11 -0
  104. package/js/src/src/abstract/btcturk.d.ts +23 -0
  105. package/js/src/src/abstract/btcturk.js +11 -0
  106. package/js/src/src/abstract/bybit.d.ts +316 -0
  107. package/js/src/src/abstract/bybit.js +11 -0
  108. package/js/src/src/abstract/bydfi.d.ts +11 -0
  109. package/js/src/src/abstract/bydfi.js +11 -0
  110. package/js/src/src/abstract/cafearz.d.ts +8 -0
  111. package/js/src/src/abstract/cafearz.js +11 -0
  112. package/js/src/src/abstract/cex.d.ts +35 -0
  113. package/js/src/src/abstract/cex.js +11 -0
  114. package/js/src/src/abstract/coinbase.d.ts +97 -0
  115. package/js/src/src/abstract/coinbase.js +11 -0
  116. package/js/src/src/abstract/coinbaseexchange.d.ts +71 -0
  117. package/js/src/src/abstract/coinbaseexchange.js +11 -0
  118. package/js/src/src/abstract/coinbaseinternational.d.ts +42 -0
  119. package/js/src/src/abstract/coinbaseinternational.js +11 -0
  120. package/js/src/src/abstract/coincatch.d.ts +97 -0
  121. package/js/src/src/abstract/coincatch.js +11 -0
  122. package/js/src/src/abstract/coincheck.d.ts +36 -0
  123. package/js/src/src/abstract/coincheck.js +11 -0
  124. package/js/src/src/abstract/coinex.d.ts +240 -0
  125. package/js/src/src/abstract/coinex.js +11 -0
  126. package/js/src/src/abstract/coinmate.d.ts +65 -0
  127. package/js/src/src/abstract/coinmate.js +11 -0
  128. package/js/src/src/abstract/coinmetro.d.ts +37 -0
  129. package/js/src/src/abstract/coinmetro.js +11 -0
  130. package/js/src/src/abstract/coinone.d.ts +70 -0
  131. package/js/src/src/abstract/coinone.js +11 -0
  132. package/js/src/src/abstract/coinsph.d.ts +57 -0
  133. package/js/src/src/abstract/coinsph.js +11 -0
  134. package/js/src/src/abstract/coinspot.d.ts +31 -0
  135. package/js/src/src/abstract/coinspot.js +11 -0
  136. package/js/src/src/abstract/cryptocom.d.ts +126 -0
  137. package/js/src/src/abstract/cryptocom.js +11 -0
  138. package/js/src/src/abstract/cryptomus.d.ts +23 -0
  139. package/js/src/src/abstract/cryptomus.js +11 -0
  140. package/js/src/src/abstract/defx.d.ts +72 -0
  141. package/js/src/src/abstract/defx.js +11 -0
  142. package/js/src/src/abstract/delta.d.ts +53 -0
  143. package/js/src/src/abstract/delta.js +11 -0
  144. package/js/src/src/abstract/deribit.d.ts +129 -0
  145. package/js/src/src/abstract/deribit.js +11 -0
  146. package/js/src/src/abstract/derive.d.ts +120 -0
  147. package/js/src/src/abstract/derive.js +11 -0
  148. package/js/src/src/abstract/digifinex.d.ts +95 -0
  149. package/js/src/src/abstract/digifinex.js +11 -0
  150. package/js/src/src/abstract/ellipx.d.ts +28 -0
  151. package/js/src/src/abstract/ellipx.js +11 -0
  152. package/js/src/src/abstract/eterex.d.ts +8 -0
  153. package/js/src/src/abstract/eterex.js +11 -0
  154. package/js/src/src/abstract/excoino.d.ts +10 -0
  155. package/js/src/src/abstract/excoino.js +11 -0
  156. package/js/src/src/abstract/exir.d.ts +11 -0
  157. package/js/src/src/abstract/exir.js +11 -0
  158. package/js/src/src/abstract/exmo.d.ts +58 -0
  159. package/js/src/src/abstract/exmo.js +11 -0
  160. package/js/src/src/abstract/exnovin.d.ts +9 -0
  161. package/js/src/src/abstract/exnovin.js +11 -0
  162. package/js/src/src/abstract/farhadexchange.d.ts +8 -0
  163. package/js/src/src/abstract/farhadexchange.js +11 -0
  164. package/js/src/src/abstract/foxbit.d.ts +29 -0
  165. package/js/src/src/abstract/foxbit.js +11 -0
  166. package/js/src/src/abstract/gate.d.ts +287 -0
  167. package/js/src/src/abstract/gate.js +11 -0
  168. package/js/src/src/abstract/gemini.d.ts +62 -0
  169. package/js/src/src/abstract/gemini.js +11 -0
  170. package/js/src/src/abstract/hamtapay.d.ts +9 -0
  171. package/js/src/src/abstract/hamtapay.js +11 -0
  172. package/js/src/src/abstract/hashkey.d.ts +70 -0
  173. package/js/src/src/abstract/hashkey.js +11 -0
  174. package/js/src/src/abstract/hibachi.d.ts +29 -0
  175. package/js/src/src/abstract/hibachi.js +11 -0
  176. package/js/src/src/abstract/hitbtc.d.ts +118 -0
  177. package/js/src/src/abstract/hitbtc.js +11 -0
  178. package/js/src/src/abstract/hitobit.d.ts +11 -0
  179. package/js/src/src/abstract/hitobit.js +11 -0
  180. package/js/src/src/abstract/hollaex.d.ts +36 -0
  181. package/js/src/src/abstract/hollaex.js +11 -0
  182. package/js/src/src/abstract/htx.d.ts +551 -0
  183. package/js/src/src/abstract/htx.js +11 -0
  184. package/js/src/src/abstract/hyperliquid.d.ts +9 -0
  185. package/js/src/src/abstract/hyperliquid.js +11 -0
  186. package/js/src/src/abstract/independentreserve.d.ts +46 -0
  187. package/js/src/src/abstract/independentreserve.js +11 -0
  188. package/js/src/src/abstract/indodax.d.ts +29 -0
  189. package/js/src/src/abstract/indodax.js +11 -0
  190. package/js/src/src/abstract/iranexchange.d.ts +9 -0
  191. package/js/src/src/abstract/iranexchange.js +11 -0
  192. package/js/src/src/abstract/jibitex.d.ts +10 -0
  193. package/js/src/src/abstract/jibitex.js +11 -0
  194. package/js/src/src/abstract/kcex.d.ts +10 -0
  195. package/js/src/src/abstract/kcex.js +11 -0
  196. package/js/src/src/abstract/kifpoolme.d.ts +9 -0
  197. package/js/src/src/abstract/kifpoolme.js +11 -0
  198. package/js/src/src/abstract/kraken.d.ts +61 -0
  199. package/js/src/src/abstract/kraken.js +11 -0
  200. package/js/src/src/abstract/krakenfutures.d.ts +45 -0
  201. package/js/src/src/abstract/krakenfutures.js +11 -0
  202. package/js/src/src/abstract/kucoin.d.ts +227 -0
  203. package/js/src/src/abstract/kucoin.js +11 -0
  204. package/js/src/src/abstract/kucoinfutures.d.ts +254 -0
  205. package/js/src/src/abstract/kucoinfutures.js +11 -0
  206. package/js/src/src/abstract/latoken.d.ts +59 -0
  207. package/js/src/src/abstract/latoken.js +11 -0
  208. package/js/src/src/abstract/lbank.d.ts +65 -0
  209. package/js/src/src/abstract/lbank.js +11 -0
  210. package/js/src/src/abstract/luno.d.ts +41 -0
  211. package/js/src/src/abstract/luno.js +11 -0
  212. package/js/src/src/abstract/mazdax.d.ts +11 -0
  213. package/js/src/src/abstract/mazdax.js +11 -0
  214. package/js/src/src/abstract/mercado.d.ts +28 -0
  215. package/js/src/src/abstract/mercado.js +11 -0
  216. package/js/src/src/abstract/mexc.d.ts +183 -0
  217. package/js/src/src/abstract/mexc.js +11 -0
  218. package/js/src/src/abstract/modetrade.d.ts +122 -0
  219. package/js/src/src/abstract/modetrade.js +11 -0
  220. package/js/src/src/abstract/ndax.d.ts +100 -0
  221. package/js/src/src/abstract/ndax.js +11 -0
  222. package/js/src/src/abstract/nobitex.d.ts +10 -0
  223. package/js/src/src/abstract/nobitex.js +11 -0
  224. package/js/src/src/abstract/novadax.d.ts +32 -0
  225. package/js/src/src/abstract/novadax.js +11 -0
  226. package/js/src/src/abstract/oceanex.d.ts +30 -0
  227. package/js/src/src/abstract/oceanex.js +11 -0
  228. package/js/src/src/abstract/okcoin.d.ts +77 -0
  229. package/js/src/src/abstract/okcoin.js +11 -0
  230. package/js/src/src/abstract/okexchange.d.ts +11 -0
  231. package/js/src/src/abstract/okexchange.js +11 -0
  232. package/js/src/src/abstract/okx.d.ts +352 -0
  233. package/js/src/src/abstract/okx.js +11 -0
  234. package/js/src/src/abstract/ompfinex.d.ts +10 -0
  235. package/js/src/src/abstract/ompfinex.js +11 -0
  236. package/js/src/src/abstract/onetrading.d.ts +26 -0
  237. package/js/src/src/abstract/onetrading.js +11 -0
  238. package/js/src/src/abstract/oxfun.d.ts +37 -0
  239. package/js/src/src/abstract/oxfun.js +11 -0
  240. package/js/src/src/abstract/p2b.d.ts +25 -0
  241. package/js/src/src/abstract/p2b.js +11 -0
  242. package/js/src/src/abstract/paradex.d.ts +66 -0
  243. package/js/src/src/abstract/paradex.js +11 -0
  244. package/js/src/src/abstract/paymium.d.ts +31 -0
  245. package/js/src/src/abstract/paymium.js +11 -0
  246. package/js/src/src/abstract/phemex.d.ts +120 -0
  247. package/js/src/src/abstract/phemex.js +11 -0
  248. package/js/src/src/abstract/pingi.d.ts +9 -0
  249. package/js/src/src/abstract/pingi.js +11 -0
  250. package/js/src/src/abstract/poloniex.d.ts +108 -0
  251. package/js/src/src/abstract/poloniex.js +11 -0
  252. package/js/src/src/abstract/pooleno.d.ts +8 -0
  253. package/js/src/src/abstract/pooleno.js +11 -0
  254. package/js/src/src/abstract/probit.d.ts +26 -0
  255. package/js/src/src/abstract/probit.js +11 -0
  256. package/js/src/src/abstract/raastin.d.ts +11 -0
  257. package/js/src/src/abstract/raastin.js +11 -0
  258. package/js/src/src/abstract/ramzinex.d.ts +10 -0
  259. package/js/src/src/abstract/ramzinex.js +11 -0
  260. package/js/src/src/abstract/sarmayex.d.ts +8 -0
  261. package/js/src/src/abstract/sarmayex.js +11 -0
  262. package/js/src/src/abstract/sarrafex.d.ts +10 -0
  263. package/js/src/src/abstract/sarrafex.js +11 -0
  264. package/js/src/src/abstract/tabdeal.d.ts +10 -0
  265. package/js/src/src/abstract/tabdeal.js +11 -0
  266. package/js/src/src/abstract/tehran_exchange.d.ts +9 -0
  267. package/js/src/src/abstract/tehran_exchange.js +11 -0
  268. package/js/src/src/abstract/tetherland.d.ts +8 -0
  269. package/js/src/src/abstract/tetherland.js +11 -0
  270. package/js/src/src/abstract/timex.d.ts +65 -0
  271. package/js/src/src/abstract/timex.js +11 -0
  272. package/js/src/src/abstract/tokocrypto.d.ts +40 -0
  273. package/js/src/src/abstract/tokocrypto.js +11 -0
  274. package/js/src/src/abstract/toobit.d.ts +10 -0
  275. package/js/src/src/abstract/toobit.js +11 -0
  276. package/js/src/src/abstract/tradeogre.d.ts +21 -0
  277. package/js/src/src/abstract/tradeogre.js +11 -0
  278. package/js/src/src/abstract/twox.d.ts +8 -0
  279. package/js/src/src/abstract/twox.js +11 -0
  280. package/js/src/src/abstract/ubitex.d.ts +10 -0
  281. package/js/src/src/abstract/ubitex.js +11 -0
  282. package/js/src/src/abstract/upbit.d.ts +58 -0
  283. package/js/src/src/abstract/upbit.js +11 -0
  284. package/js/src/src/abstract/vertex.d.ts +22 -0
  285. package/js/src/src/abstract/vertex.js +11 -0
  286. package/js/src/src/abstract/wallex.d.ts +11 -0
  287. package/js/src/src/abstract/wallex.js +11 -0
  288. package/js/src/src/abstract/wavesexchange.d.ts +157 -0
  289. package/js/src/src/abstract/wavesexchange.js +11 -0
  290. package/js/src/src/abstract/whitebit.d.ts +117 -0
  291. package/js/src/src/abstract/whitebit.js +11 -0
  292. package/js/src/src/abstract/woo.d.ts +144 -0
  293. package/js/src/src/abstract/woo.js +11 -0
  294. package/js/src/src/abstract/woofipro.d.ts +122 -0
  295. package/js/src/src/abstract/woofipro.js +11 -0
  296. package/js/src/src/abstract/xt.d.ts +160 -0
  297. package/js/src/src/abstract/xt.js +11 -0
  298. package/js/src/src/abstract/yobit.d.ts +19 -0
  299. package/js/src/src/abstract/yobit.js +11 -0
  300. package/js/src/src/abstract/zaif.d.ts +41 -0
  301. package/js/src/src/abstract/zaif.js +11 -0
  302. package/js/src/src/abstract/zonda.d.ts +56 -0
  303. package/js/src/src/abstract/zonda.js +11 -0
  304. package/js/src/src/afratether.d.ts +21 -0
  305. package/js/src/src/afratether.js +356 -0
  306. package/js/src/src/alpaca.d.ts +332 -0
  307. package/js/src/src/alpaca.js +1908 -0
  308. package/js/src/src/apex.d.ts +333 -0
  309. package/js/src/src/apex.js +1942 -0
  310. package/js/src/src/arzinja.d.ts +21 -0
  311. package/js/src/src/arzinja.js +298 -0
  312. package/js/src/src/arzplus.d.ts +26 -0
  313. package/js/src/src/arzplus.js +581 -0
  314. package/js/src/src/ascendex.d.ts +424 -0
  315. package/js/src/src/ascendex.js +3699 -0
  316. package/js/src/src/asretether.d.ts +21 -0
  317. package/js/src/src/asretether.js +324 -0
  318. package/js/src/src/base/Exchange.d.ts +926 -0
  319. package/js/src/src/base/Exchange.js +7399 -0
  320. package/js/src/src/base/Precise.d.ts +42 -0
  321. package/js/src/src/base/Precise.js +275 -0
  322. package/js/src/src/base/errors.d.ts +168 -0
  323. package/js/src/src/base/errors.js +255 -0
  324. package/js/src/src/base/functions/crypto.d.ts +16 -0
  325. package/js/src/src/base/functions/crypto.js +131 -0
  326. package/js/src/src/base/functions/encode.d.ts +4 -0
  327. package/js/src/src/base/functions/encode.js +32 -0
  328. package/js/src/src/base/functions/generic.d.ts +29 -0
  329. package/js/src/src/base/functions/generic.js +203 -0
  330. package/js/src/src/base/functions/misc.d.ts +9 -0
  331. package/js/src/src/base/functions/misc.js +101 -0
  332. package/js/src/src/base/functions/number.d.ts +27 -0
  333. package/js/src/src/base/functions/number.js +313 -0
  334. package/js/src/src/base/functions/platform.d.ts +7 -0
  335. package/js/src/src/base/functions/platform.js +27 -0
  336. package/js/src/src/base/functions/rsa.d.ts +5 -0
  337. package/js/src/src/base/functions/rsa.js +49 -0
  338. package/js/src/src/base/functions/string.d.ts +7 -0
  339. package/js/src/src/base/functions/string.js +44 -0
  340. package/js/src/src/base/functions/throttle.d.ts +6 -0
  341. package/js/src/src/base/functions/throttle.js +67 -0
  342. package/js/src/src/base/functions/time.d.ts +21 -0
  343. package/js/src/src/base/functions/time.js +171 -0
  344. package/js/src/src/base/functions/totp.d.ts +3 -0
  345. package/js/src/src/base/functions/totp.js +25 -0
  346. package/js/src/src/base/functions/type.d.ts +37 -0
  347. package/js/src/src/base/functions/type.js +179 -0
  348. package/js/src/src/base/functions.d.ts +10 -0
  349. package/js/src/src/base/functions.js +18 -0
  350. package/js/src/src/base/types.d.ts +586 -0
  351. package/js/src/src/base/types.js +7 -0
  352. package/js/src/src/base/ws/Cache.d.ts +27 -0
  353. package/js/src/src/base/ws/Cache.js +260 -0
  354. package/js/src/src/base/ws/Client.d.ts +53 -0
  355. package/js/src/src/base/ws/Client.js +307 -0
  356. package/js/src/src/base/ws/Future.d.ts +8 -0
  357. package/js/src/src/base/ws/Future.js +35 -0
  358. package/js/src/src/base/ws/OrderBook.d.ts +25 -0
  359. package/js/src/src/base/ws/OrderBook.js +130 -0
  360. package/js/src/src/base/ws/OrderBookSide.d.ts +40 -0
  361. package/js/src/src/base/ws/OrderBookSide.js +286 -0
  362. package/js/src/src/base/ws/WsClient.d.ts +11 -0
  363. package/js/src/src/base/ws/WsClient.js +69 -0
  364. package/js/src/src/bequant.d.ts +4 -0
  365. package/js/src/src/bequant.js +35 -0
  366. package/js/src/src/bidarz.d.ts +16 -0
  367. package/js/src/src/bidarz.js +327 -0
  368. package/js/src/src/bigone.d.ts +296 -0
  369. package/js/src/src/bigone.js +2340 -0
  370. package/js/src/src/binance.d.ts +1667 -0
  371. package/js/src/src/binance.js +14400 -0
  372. package/js/src/src/binancecoinm.d.ts +6 -0
  373. package/js/src/src/binancecoinm.js +51 -0
  374. package/js/src/src/binanceus.d.ts +4 -0
  375. package/js/src/src/binanceus.js +225 -0
  376. package/js/src/src/binanceusdm.d.ts +6 -0
  377. package/js/src/src/binanceusdm.js +63 -0
  378. package/js/src/src/bingx.d.ts +778 -0
  379. package/js/src/src/bingx.js +6705 -0
  380. package/js/src/src/bit24.d.ts +24 -0
  381. package/js/src/src/bit24.js +520 -0
  382. package/js/src/src/bit2c.d.ts +146 -0
  383. package/js/src/src/bit2c.js +1029 -0
  384. package/js/src/src/bitbank.d.ts +181 -0
  385. package/js/src/src/bitbank.js +1146 -0
  386. package/js/src/src/bitbarg.d.ts +21 -0
  387. package/js/src/src/bitbarg.js +312 -0
  388. package/js/src/src/bitbns.d.ts +184 -0
  389. package/js/src/src/bitbns.js +1288 -0
  390. package/js/src/src/bitfinex.d.ts +516 -0
  391. package/js/src/src/bitfinex.js +3951 -0
  392. package/js/src/src/bitflyer.d.ts +229 -0
  393. package/js/src/src/bitflyer.js +1209 -0
  394. package/js/src/src/bitget.d.ts +1109 -0
  395. package/js/src/src/bitget.js +11033 -0
  396. package/js/src/src/bithumb.d.ts +165 -0
  397. package/js/src/src/bithumb.js +1257 -0
  398. package/js/src/src/bitimen.d.ts +23 -0
  399. package/js/src/src/bitimen.js +424 -0
  400. package/js/src/src/bitir.d.ts +23 -0
  401. package/js/src/src/bitir.js +521 -0
  402. package/js/src/src/bitmart.d.ts +736 -0
  403. package/js/src/src/bitmart.js +5639 -0
  404. package/js/src/src/bitmex.d.ts +395 -0
  405. package/js/src/src/bitmex.js +3088 -0
  406. package/js/src/src/bitopro.d.ts +295 -0
  407. package/js/src/src/bitopro.js +1892 -0
  408. package/js/src/src/bitpin.d.ts +23 -0
  409. package/js/src/src/bitpin.js +487 -0
  410. package/js/src/src/bitrue.d.ts +384 -0
  411. package/js/src/src/bitrue.js +3382 -0
  412. package/js/src/src/bitso.d.ts +270 -0
  413. package/js/src/src/bitso.js +1881 -0
  414. package/js/src/src/bitstamp.d.ts +355 -0
  415. package/js/src/src/bitstamp.js +2445 -0
  416. package/js/src/src/bitteam.d.ts +229 -0
  417. package/js/src/src/bitteam.js +2420 -0
  418. package/js/src/src/bittrade.d.ts +298 -0
  419. package/js/src/src/bittrade.js +2050 -0
  420. package/js/src/src/bitunix.d.ts +21 -0
  421. package/js/src/src/bitunix.js +326 -0
  422. package/js/src/src/bitvavo.d.ts +311 -0
  423. package/js/src/src/bitvavo.js +2204 -0
  424. package/js/src/src/blockchaincom.d.ts +256 -0
  425. package/js/src/src/blockchaincom.js +1259 -0
  426. package/js/src/src/blofin.d.ts +439 -0
  427. package/js/src/src/blofin.js +2576 -0
  428. package/js/src/src/btcalpha.d.ts +209 -0
  429. package/js/src/src/btcalpha.js +1056 -0
  430. package/js/src/src/btcbox.d.ts +144 -0
  431. package/js/src/src/btcbox.js +834 -0
  432. package/js/src/src/btcmarkets.d.ts +253 -0
  433. package/js/src/src/btcmarkets.js +1418 -0
  434. package/js/src/src/btcturk.d.ts +161 -0
  435. package/js/src/src/btcturk.js +1058 -0
  436. package/js/src/src/bybit.d.ts +1097 -0
  437. package/js/src/src/bybit.js +9382 -0
  438. package/js/src/src/bydfi.d.ts +23 -0
  439. package/js/src/src/bydfi.js +434 -0
  440. package/js/src/src/cafearz.d.ts +21 -0
  441. package/js/src/src/cafearz.js +346 -0
  442. package/js/src/src/cex.d.ts +286 -0
  443. package/js/src/src/cex.js +1799 -0
  444. package/js/src/src/coinbase.d.ts +623 -0
  445. package/js/src/src/coinbase.js +5220 -0
  446. package/js/src/src/coinbaseadvanced.d.ts +4 -0
  447. package/js/src/src/coinbaseadvanced.js +18 -0
  448. package/js/src/src/coinbaseexchange.d.ts +334 -0
  449. package/js/src/src/coinbaseexchange.js +2127 -0
  450. package/js/src/src/coinbaseinternational.d.ts +443 -0
  451. package/js/src/src/coinbaseinternational.js +2336 -0
  452. package/js/src/src/coincatch.d.ts +786 -0
  453. package/js/src/src/coincatch.js +5492 -0
  454. package/js/src/src/coincheck.d.ts +147 -0
  455. package/js/src/src/coincheck.js +962 -0
  456. package/js/src/src/coinex.d.ts +719 -0
  457. package/js/src/src/coinex.js +6166 -0
  458. package/js/src/src/coinmate.d.ts +202 -0
  459. package/js/src/src/coinmate.js +1215 -0
  460. package/js/src/src/coinmetro.d.ts +244 -0
  461. package/js/src/src/coinmetro.js +2024 -0
  462. package/js/src/src/coinone.d.ts +158 -0
  463. package/js/src/src/coinone.js +1278 -0
  464. package/js/src/src/coinsph.d.ts +310 -0
  465. package/js/src/src/coinsph.js +2203 -0
  466. package/js/src/src/coinspot.d.ts +108 -0
  467. package/js/src/src/coinspot.js +653 -0
  468. package/js/src/src/cryptocom.d.ts +463 -0
  469. package/js/src/src/cryptocom.js +3549 -0
  470. package/js/src/src/cryptomus.d.ts +158 -0
  471. package/js/src/src/cryptomus.js +1169 -0
  472. package/js/src/src/defx.d.ts +348 -0
  473. package/js/src/src/defx.js +2139 -0
  474. package/js/src/src/delta.d.ts +407 -0
  475. package/js/src/src/delta.js +3654 -0
  476. package/js/src/src/deribit.d.ts +516 -0
  477. package/js/src/src/deribit.js +3790 -0
  478. package/js/src/src/derive.d.ts +324 -0
  479. package/js/src/src/derive.js +2655 -0
  480. package/js/src/src/digifinex.d.ts +544 -0
  481. package/js/src/src/digifinex.js +4453 -0
  482. package/js/src/src/ellipx.d.ts +237 -0
  483. package/js/src/src/ellipx.js +2071 -0
  484. package/js/src/src/eterex.d.ts +21 -0
  485. package/js/src/src/eterex.js +299 -0
  486. package/js/src/src/excoino.d.ts +23 -0
  487. package/js/src/src/excoino.js +426 -0
  488. package/js/src/src/exir.d.ts +23 -0
  489. package/js/src/src/exir.js +403 -0
  490. package/js/src/src/exmo.d.ts +426 -0
  491. package/js/src/src/exmo.js +2825 -0
  492. package/js/src/src/exnovin.d.ts +22 -0
  493. package/js/src/src/exnovin.js +378 -0
  494. package/js/src/src/farhadexchange.d.ts +21 -0
  495. package/js/src/src/farhadexchange.js +280 -0
  496. package/js/src/src/fmfwio.d.ts +4 -0
  497. package/js/src/src/fmfwio.js +35 -0
  498. package/js/src/src/foxbit.d.ts +352 -0
  499. package/js/src/src/foxbit.js +2016 -0
  500. package/js/src/src/gate.d.ts +1071 -0
  501. package/js/src/src/gate.js +8282 -0
  502. package/js/src/src/gateio.d.ts +4 -0
  503. package/js/src/src/gateio.js +17 -0
  504. package/js/src/src/gemini.d.ts +257 -0
  505. package/js/src/src/gemini.js +2006 -0
  506. package/js/src/src/hamtapay.d.ts +21 -0
  507. package/js/src/src/hamtapay.js +303 -0
  508. package/js/src/src/hashkey.d.ts +628 -0
  509. package/js/src/src/hashkey.js +4363 -0
  510. package/js/src/src/hibachi.d.ts +346 -0
  511. package/js/src/src/hibachi.js +2137 -0
  512. package/js/src/src/hitbtc.d.ts +558 -0
  513. package/js/src/src/hitbtc.js +3847 -0
  514. package/js/src/src/hitobit.d.ts +23 -0
  515. package/js/src/src/hitobit.js +412 -0
  516. package/js/src/src/hollaex.d.ts +305 -0
  517. package/js/src/src/hollaex.js +2046 -0
  518. package/js/src/src/htx.d.ts +961 -0
  519. package/js/src/src/htx.js +9668 -0
  520. package/js/src/src/huobi.d.ts +4 -0
  521. package/js/src/src/huobi.js +17 -0
  522. package/js/src/src/hyperliquid.d.ts +651 -0
  523. package/js/src/src/hyperliquid.js +3937 -0
  524. package/js/src/src/independentreserve.d.ts +169 -0
  525. package/js/src/src/independentreserve.js +1115 -0
  526. package/js/src/src/indodax.d.ts +217 -0
  527. package/js/src/src/indodax.js +1454 -0
  528. package/js/src/src/iranexchange.d.ts +21 -0
  529. package/js/src/src/iranexchange.js +399 -0
  530. package/js/src/src/jibitex.d.ts +23 -0
  531. package/js/src/src/jibitex.js +416 -0
  532. package/js/src/src/kcex.d.ts +21 -0
  533. package/js/src/src/kcex.js +335 -0
  534. package/js/src/src/kifpoolme.d.ts +23 -0
  535. package/js/src/src/kifpoolme.js +410 -0
  536. package/js/src/src/kraken.d.ts +484 -0
  537. package/js/src/src/kraken.js +3518 -0
  538. package/js/src/src/krakenfutures.d.ts +362 -0
  539. package/js/src/src/krakenfutures.js +2885 -0
  540. package/js/src/src/kucoin.d.ts +759 -0
  541. package/js/src/src/kucoin.js +5153 -0
  542. package/js/src/src/kucoinfutures.d.ts +521 -0
  543. package/js/src/src/kucoinfutures.js +3381 -0
  544. package/js/src/src/latoken.d.ts +274 -0
  545. package/js/src/src/latoken.js +1824 -0
  546. package/js/src/src/lbank.d.ts +350 -0
  547. package/js/src/src/lbank.js +3146 -0
  548. package/js/src/src/luno.d.ts +252 -0
  549. package/js/src/src/luno.js +1479 -0
  550. package/js/src/src/mazdax.d.ts +23 -0
  551. package/js/src/src/mazdax.js +534 -0
  552. package/js/src/src/mercado.d.ts +160 -0
  553. package/js/src/src/mercado.js +1011 -0
  554. package/js/src/src/mexc.d.ts +768 -0
  555. package/js/src/src/mexc.js +6102 -0
  556. package/js/src/src/modetrade.d.ts +496 -0
  557. package/js/src/src/modetrade.js +2936 -0
  558. package/js/src/src/myokx.d.ts +4 -0
  559. package/js/src/src/myokx.js +54 -0
  560. package/js/src/src/ndax.d.ts +285 -0
  561. package/js/src/src/ndax.js +2598 -0
  562. package/js/src/src/nobitex.d.ts +23 -0
  563. package/js/src/src/nobitex.js +454 -0
  564. package/js/src/src/novadax.d.ts +279 -0
  565. package/js/src/src/novadax.js +1676 -0
  566. package/js/src/src/oceanex.d.ts +231 -0
  567. package/js/src/src/oceanex.js +1123 -0
  568. package/js/src/src/okcoin.d.ts +346 -0
  569. package/js/src/src/okcoin.js +3211 -0
  570. package/js/src/src/okexchange.d.ts +23 -0
  571. package/js/src/src/okexchange.js +373 -0
  572. package/js/src/src/okx.d.ts +1125 -0
  573. package/js/src/src/okx.js +9009 -0
  574. package/js/src/src/okxus.d.ts +4 -0
  575. package/js/src/src/okxus.js +54 -0
  576. package/js/src/src/ompfinex.d.ts +23 -0
  577. package/js/src/src/ompfinex.js +510 -0
  578. package/js/src/src/onetrading.d.ts +228 -0
  579. package/js/src/src/onetrading.js +1769 -0
  580. package/js/src/src/oxfun.d.ts +442 -0
  581. package/js/src/src/oxfun.js +2920 -0
  582. package/js/src/src/p2b.d.ts +189 -0
  583. package/js/src/src/p2b.js +1344 -0
  584. package/js/src/src/paradex.d.ts +389 -0
  585. package/js/src/src/paradex.js +2607 -0
  586. package/js/src/src/paymium.d.ts +133 -0
  587. package/js/src/src/paymium.js +644 -0
  588. package/js/src/src/phemex.d.ts +497 -0
  589. package/js/src/src/phemex.js +5333 -0
  590. package/js/src/src/pingi.d.ts +22 -0
  591. package/js/src/src/pingi.js +446 -0
  592. package/js/src/src/poloniex.d.ts +441 -0
  593. package/js/src/src/poloniex.js +3681 -0
  594. package/js/src/src/pooleno.d.ts +21 -0
  595. package/js/src/src/pooleno.js +347 -0
  596. package/js/src/src/pro/alpaca.d.ts +95 -0
  597. package/js/src/src/pro/alpaca.js +724 -0
  598. package/js/src/src/pro/apex.d.ts +160 -0
  599. package/js/src/src/pro/apex.js +1044 -0
  600. package/js/src/src/pro/ascendex.d.ts +99 -0
  601. package/js/src/src/pro/ascendex.js +1012 -0
  602. package/js/src/src/pro/bequant.d.ts +4 -0
  603. package/js/src/src/pro/bequant.js +42 -0
  604. package/js/src/src/pro/binance.d.ts +796 -0
  605. package/js/src/src/pro/binance.js +4373 -0
  606. package/js/src/src/pro/binancecoinm.d.ts +4 -0
  607. package/js/src/src/pro/binancecoinm.js +32 -0
  608. package/js/src/src/pro/binanceus.d.ts +4 -0
  609. package/js/src/src/pro/binanceus.js +52 -0
  610. package/js/src/src/pro/binanceusdm.d.ts +4 -0
  611. package/js/src/src/pro/binanceusdm.js +37 -0
  612. package/js/src/src/pro/bingx.d.ts +151 -0
  613. package/js/src/src/pro/bingx.js +1568 -0
  614. package/js/src/src/pro/bitfinex.d.ts +99 -0
  615. package/js/src/src/pro/bitfinex.js +1165 -0
  616. package/js/src/src/pro/bitget.d.ts +257 -0
  617. package/js/src/src/pro/bitget.js +2327 -0
  618. package/js/src/src/pro/bithumb.d.ts +59 -0
  619. package/js/src/src/pro/bithumb.js +395 -0
  620. package/js/src/src/pro/bitmart.d.ts +168 -0
  621. package/js/src/src/pro/bitmart.js +1686 -0
  622. package/js/src/src/pro/bitmex.d.ts +170 -0
  623. package/js/src/src/pro/bitmex.js +1760 -0
  624. package/js/src/src/pro/bitopro.d.ts +69 -0
  625. package/js/src/src/pro/bitopro.js +477 -0
  626. package/js/src/src/pro/bitrue.d.ts +40 -0
  627. package/js/src/src/pro/bitrue.js +461 -0
  628. package/js/src/src/pro/bitstamp.d.ts +53 -0
  629. package/js/src/src/pro/bitstamp.js +587 -0
  630. package/js/src/src/pro/bittrade.d.ts +66 -0
  631. package/js/src/src/pro/bittrade.js +606 -0
  632. package/js/src/src/pro/bitvavo.d.ts +321 -0
  633. package/js/src/src/pro/bitvavo.js +1451 -0
  634. package/js/src/src/pro/blockchaincom.d.ts +89 -0
  635. package/js/src/src/pro/blockchaincom.js +777 -0
  636. package/js/src/src/pro/blofin.d.ts +174 -0
  637. package/js/src/src/pro/blofin.js +743 -0
  638. package/js/src/src/pro/bybit.d.ts +397 -0
  639. package/js/src/src/pro/bybit.js +2519 -0
  640. package/js/src/src/pro/cex.d.ts +220 -0
  641. package/js/src/src/pro/cex.js +1535 -0
  642. package/js/src/src/pro/coinbase.d.ts +119 -0
  643. package/js/src/src/pro/coinbase.js +736 -0
  644. package/js/src/src/pro/coinbaseadvanced.d.ts +4 -0
  645. package/js/src/src/pro/coinbaseadvanced.js +18 -0
  646. package/js/src/src/pro/coinbaseexchange.d.ts +133 -0
  647. package/js/src/src/pro/coinbaseexchange.js +969 -0
  648. package/js/src/src/pro/coinbaseinternational.d.ts +143 -0
  649. package/js/src/src/pro/coinbaseinternational.js +804 -0
  650. package/js/src/src/pro/coincatch.d.ts +207 -0
  651. package/js/src/src/pro/coincatch.js +1562 -0
  652. package/js/src/src/pro/coincheck.d.ts +33 -0
  653. package/js/src/src/pro/coincheck.js +210 -0
  654. package/js/src/src/pro/coinex.d.ts +147 -0
  655. package/js/src/src/pro/coinex.js +1426 -0
  656. package/js/src/src/pro/coinone.d.ts +51 -0
  657. package/js/src/src/pro/coinone.js +413 -0
  658. package/js/src/src/pro/cryptocom.d.ts +300 -0
  659. package/js/src/src/pro/cryptocom.js +1414 -0
  660. package/js/src/src/pro/defx.d.ts +236 -0
  661. package/js/src/src/pro/defx.js +865 -0
  662. package/js/src/src/pro/deribit.d.ts +163 -0
  663. package/js/src/src/pro/deribit.js +1066 -0
  664. package/js/src/src/pro/derive.d.ts +100 -0
  665. package/js/src/src/pro/derive.js +753 -0
  666. package/js/src/src/pro/exmo.d.ts +97 -0
  667. package/js/src/src/pro/exmo.js +903 -0
  668. package/js/src/src/pro/gate.d.ts +360 -0
  669. package/js/src/src/pro/gate.js +2119 -0
  670. package/js/src/src/pro/gateio.d.ts +4 -0
  671. package/js/src/src/pro/gateio.js +17 -0
  672. package/js/src/src/pro/gemini.d.ts +106 -0
  673. package/js/src/src/pro/gemini.js +932 -0
  674. package/js/src/src/pro/hashkey.d.ts +121 -0
  675. package/js/src/src/pro/hashkey.js +843 -0
  676. package/js/src/src/pro/hitbtc.d.ts +235 -0
  677. package/js/src/src/pro/hitbtc.js +1400 -0
  678. package/js/src/src/pro/hollaex.d.ts +77 -0
  679. package/js/src/src/pro/hollaex.js +604 -0
  680. package/js/src/src/pro/htx.d.ts +141 -0
  681. package/js/src/src/pro/htx.js +2415 -0
  682. package/js/src/src/pro/huobi.d.ts +4 -0
  683. package/js/src/src/pro/huobi.js +17 -0
  684. package/js/src/src/pro/hyperliquid.d.ts +218 -0
  685. package/js/src/src/pro/hyperliquid.js +1126 -0
  686. package/js/src/src/pro/independentreserve.d.ts +36 -0
  687. package/js/src/src/pro/independentreserve.js +287 -0
  688. package/js/src/src/pro/kraken.d.ts +233 -0
  689. package/js/src/src/pro/kraken.js +1785 -0
  690. package/js/src/src/pro/krakenfutures.d.ts +178 -0
  691. package/js/src/src/pro/krakenfutures.js +1592 -0
  692. package/js/src/src/pro/kucoin.d.ts +221 -0
  693. package/js/src/src/pro/kucoin.js +1430 -0
  694. package/js/src/src/pro/kucoinfutures.d.ts +205 -0
  695. package/js/src/src/pro/kucoinfutures.js +1295 -0
  696. package/js/src/src/pro/lbank.d.ts +134 -0
  697. package/js/src/src/pro/lbank.js +950 -0
  698. package/js/src/src/pro/luno.d.ts +44 -0
  699. package/js/src/src/pro/luno.js +322 -0
  700. package/js/src/src/pro/mexc.d.ts +210 -0
  701. package/js/src/src/pro/mexc.js +2009 -0
  702. package/js/src/src/pro/modetrade.d.ts +155 -0
  703. package/js/src/src/pro/modetrade.js +1335 -0
  704. package/js/src/src/pro/myokx.d.ts +4 -0
  705. package/js/src/src/pro/myokx.js +39 -0
  706. package/js/src/src/pro/ndax.d.ts +60 -0
  707. package/js/src/src/pro/ndax.js +545 -0
  708. package/js/src/src/pro/okcoin.d.ts +91 -0
  709. package/js/src/src/pro/okcoin.js +763 -0
  710. package/js/src/src/pro/okx.d.ts +408 -0
  711. package/js/src/src/pro/okx.js +2479 -0
  712. package/js/src/src/pro/okxus.d.ts +4 -0
  713. package/js/src/src/pro/okxus.js +39 -0
  714. package/js/src/src/pro/onetrading.d.ts +107 -0
  715. package/js/src/src/pro/onetrading.js +1343 -0
  716. package/js/src/src/pro/oxfun.d.ts +234 -0
  717. package/js/src/src/pro/oxfun.js +1112 -0
  718. package/js/src/src/pro/p2b.d.ts +104 -0
  719. package/js/src/src/pro/p2b.js +506 -0
  720. package/js/src/src/pro/paradex.d.ts +54 -0
  721. package/js/src/src/pro/paradex.js +370 -0
  722. package/js/src/src/pro/phemex.d.ts +129 -0
  723. package/js/src/src/pro/phemex.js +1569 -0
  724. package/js/src/src/pro/poloniex.d.ts +214 -0
  725. package/js/src/src/pro/poloniex.js +1318 -0
  726. package/js/src/src/pro/probit.d.ts +91 -0
  727. package/js/src/src/pro/probit.js +593 -0
  728. package/js/src/src/pro/tradeogre.d.ts +49 -0
  729. package/js/src/src/pro/tradeogre.js +284 -0
  730. package/js/src/src/pro/upbit.d.ts +124 -0
  731. package/js/src/src/pro/upbit.js +689 -0
  732. package/js/src/src/pro/vertex.d.ts +104 -0
  733. package/js/src/src/pro/vertex.js +999 -0
  734. package/js/src/src/pro/whitebit.d.ts +123 -0
  735. package/js/src/src/pro/whitebit.js +971 -0
  736. package/js/src/src/pro/woo.d.ts +161 -0
  737. package/js/src/src/pro/woo.js +1351 -0
  738. package/js/src/src/pro/woofipro.d.ts +155 -0
  739. package/js/src/src/pro/woofipro.js +1335 -0
  740. package/js/src/src/pro/xt.d.ts +165 -0
  741. package/js/src/src/pro/xt.js +1230 -0
  742. package/js/src/src/probit.d.ts +283 -0
  743. package/js/src/src/probit.js +1935 -0
  744. package/js/src/src/protobuf/mexc/compiled.cjs +7186 -0
  745. package/js/src/src/protobuf/mexc/compiled.d.cts +8 -0
  746. package/js/src/src/raastin.d.ts +24 -0
  747. package/js/src/src/raastin.js +494 -0
  748. package/js/src/src/ramzinex.d.ts +23 -0
  749. package/js/src/src/ramzinex.js +510 -0
  750. package/js/src/src/sarmayex.d.ts +21 -0
  751. package/js/src/src/sarmayex.js +376 -0
  752. package/js/src/src/sarrafex.d.ts +23 -0
  753. package/js/src/src/sarrafex.js +501 -0
  754. package/js/src/src/static_dependencies/ethers/abi-coder.d.ts +50 -0
  755. package/js/src/src/static_dependencies/ethers/abi-coder.js +148 -0
  756. package/js/src/src/static_dependencies/ethers/address/address.d.ts +55 -0
  757. package/js/src/src/static_dependencies/ethers/address/address.js +162 -0
  758. package/js/src/src/static_dependencies/ethers/address/checks.d.ts +80 -0
  759. package/js/src/src/static_dependencies/ethers/address/checks.js +119 -0
  760. package/js/src/src/static_dependencies/ethers/address/contract-address.d.ts +47 -0
  761. package/js/src/src/static_dependencies/ethers/address/contract-address.js +73 -0
  762. package/js/src/src/static_dependencies/ethers/address/index.d.ts +48 -0
  763. package/js/src/src/static_dependencies/ethers/address/index.js +24 -0
  764. package/js/src/src/static_dependencies/ethers/bytes32.d.ts +14 -0
  765. package/js/src/src/static_dependencies/ethers/bytes32.js +45 -0
  766. package/js/src/src/static_dependencies/ethers/coders/abstract-coder.d.ts +120 -0
  767. package/js/src/src/static_dependencies/ethers/coders/abstract-coder.js +424 -0
  768. package/js/src/src/static_dependencies/ethers/coders/address.d.ts +12 -0
  769. package/js/src/src/static_dependencies/ethers/coders/address.js +34 -0
  770. package/js/src/src/static_dependencies/ethers/coders/anonymous.d.ts +14 -0
  771. package/js/src/src/static_dependencies/ethers/coders/anonymous.js +27 -0
  772. package/js/src/src/static_dependencies/ethers/coders/array.d.ts +24 -0
  773. package/js/src/src/static_dependencies/ethers/coders/array.js +162 -0
  774. package/js/src/src/static_dependencies/ethers/coders/boolean.d.ts +12 -0
  775. package/js/src/src/static_dependencies/ethers/coders/boolean.js +26 -0
  776. package/js/src/src/static_dependencies/ethers/coders/bytes.d.ts +18 -0
  777. package/js/src/src/static_dependencies/ethers/coders/bytes.js +39 -0
  778. package/js/src/src/static_dependencies/ethers/coders/fixed-bytes.d.ts +14 -0
  779. package/js/src/src/static_dependencies/ethers/coders/fixed-bytes.js +32 -0
  780. package/js/src/src/static_dependencies/ethers/coders/null.d.ts +11 -0
  781. package/js/src/src/static_dependencies/ethers/coders/null.js +29 -0
  782. package/js/src/src/static_dependencies/ethers/coders/number.d.ts +15 -0
  783. package/js/src/src/static_dependencies/ethers/coders/number.js +48 -0
  784. package/js/src/src/static_dependencies/ethers/coders/string.d.ts +12 -0
  785. package/js/src/src/static_dependencies/ethers/coders/string.js +26 -0
  786. package/js/src/src/static_dependencies/ethers/coders/tuple.d.ts +15 -0
  787. package/js/src/src/static_dependencies/ethers/coders/tuple.js +67 -0
  788. package/js/src/src/static_dependencies/ethers/fragments.d.ts +458 -0
  789. package/js/src/src/static_dependencies/ethers/fragments.js +1252 -0
  790. package/js/src/src/static_dependencies/ethers/hash/index.d.ts +10 -0
  791. package/js/src/src/static_dependencies/ethers/hash/index.js +15 -0
  792. package/js/src/src/static_dependencies/ethers/hash/solidity.d.ts +30 -0
  793. package/js/src/src/static_dependencies/ethers/hash/solidity.js +107 -0
  794. package/js/src/src/static_dependencies/ethers/hash/typed-data.d.ts +144 -0
  795. package/js/src/src/static_dependencies/ethers/hash/typed-data.js +490 -0
  796. package/js/src/src/static_dependencies/ethers/index.d.ts +19 -0
  797. package/js/src/src/static_dependencies/ethers/index.js +22 -0
  798. package/js/src/src/static_dependencies/ethers/interface.d.ts +380 -0
  799. package/js/src/src/static_dependencies/ethers/interface.js +990 -0
  800. package/js/src/src/static_dependencies/ethers/typed.d.ts +569 -0
  801. package/js/src/src/static_dependencies/ethers/typed.js +608 -0
  802. package/js/src/src/static_dependencies/ethers/utils/base58.d.ts +22 -0
  803. package/js/src/src/static_dependencies/ethers/utils/base58.js +68 -0
  804. package/js/src/src/static_dependencies/ethers/utils/base64.d.ts +39 -0
  805. package/js/src/src/static_dependencies/ethers/utils/base64.js +58 -0
  806. package/js/src/src/static_dependencies/ethers/utils/data.d.ts +92 -0
  807. package/js/src/src/static_dependencies/ethers/utils/data.js +175 -0
  808. package/js/src/src/static_dependencies/ethers/utils/errors.d.ts +509 -0
  809. package/js/src/src/static_dependencies/ethers/utils/errors.js +227 -0
  810. package/js/src/src/static_dependencies/ethers/utils/events.d.ts +76 -0
  811. package/js/src/src/static_dependencies/ethers/utils/events.js +52 -0
  812. package/js/src/src/static_dependencies/ethers/utils/fixednumber.d.ts +251 -0
  813. package/js/src/src/static_dependencies/ethers/utils/fixednumber.js +529 -0
  814. package/js/src/src/static_dependencies/ethers/utils/index.d.ts +30 -0
  815. package/js/src/src/static_dependencies/ethers/utils/index.js +38 -0
  816. package/js/src/src/static_dependencies/ethers/utils/maths.d.ts +65 -0
  817. package/js/src/src/static_dependencies/ethers/utils/maths.js +220 -0
  818. package/js/src/src/static_dependencies/ethers/utils/properties.d.ts +22 -0
  819. package/js/src/src/static_dependencies/ethers/utils/properties.js +59 -0
  820. package/js/src/src/static_dependencies/ethers/utils/rlp-decode.d.ts +5 -0
  821. package/js/src/src/static_dependencies/ethers/utils/rlp-decode.js +84 -0
  822. package/js/src/src/static_dependencies/ethers/utils/rlp-encode.d.ts +5 -0
  823. package/js/src/src/static_dependencies/ethers/utils/rlp-encode.js +54 -0
  824. package/js/src/src/static_dependencies/ethers/utils/rlp.d.ts +16 -0
  825. package/js/src/src/static_dependencies/ethers/utils/rlp.js +14 -0
  826. package/js/src/src/static_dependencies/ethers/utils/units.d.ts +23 -0
  827. package/js/src/src/static_dependencies/ethers/utils/units.js +88 -0
  828. package/js/src/src/static_dependencies/ethers/utils/utf8.d.ts +95 -0
  829. package/js/src/src/static_dependencies/ethers/utils/utf8.js +225 -0
  830. package/js/src/src/static_dependencies/ethers/utils/uuid.d.ts +7 -0
  831. package/js/src/src/static_dependencies/ethers/utils/uuid.js +35 -0
  832. package/js/src/src/static_dependencies/fflake/browser.d.ts +222 -0
  833. package/js/src/src/static_dependencies/fflake/browser.js +2578 -0
  834. package/js/src/src/static_dependencies/jsencrypt/JSEncrypt.d.ts +116 -0
  835. package/js/src/src/static_dependencies/jsencrypt/JSEncrypt.js +194 -0
  836. package/js/src/src/static_dependencies/jsencrypt/JSEncryptRSAKey.d.ts +142 -0
  837. package/js/src/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +307 -0
  838. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/asn1.d.ts +51 -0
  839. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +565 -0
  840. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/base64.d.ts +5 -0
  841. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
  842. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/hex.d.ts +3 -0
  843. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
  844. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/int10.d.ts +9 -0
  845. package/js/src/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
  846. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/base64.d.ts +3 -0
  847. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +25 -0
  848. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.d.ts +101 -0
  849. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1757 -0
  850. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/prng4.d.ts +10 -0
  851. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +50 -0
  852. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rng.d.ts +3 -0
  853. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +80 -0
  854. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rsa.d.ts +23 -0
  855. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +377 -0
  856. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/util.d.ts +7 -0
  857. package/js/src/src/static_dependencies/jsencrypt/lib/jsbn/util.js +64 -0
  858. package/js/src/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.d.ts +24 -0
  859. package/js/src/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1627 -0
  860. package/js/src/src/static_dependencies/noble-curves/_shortw_utils.d.ts +60 -0
  861. package/js/src/src/static_dependencies/noble-curves/_shortw_utils.js +22 -0
  862. package/js/src/src/static_dependencies/noble-curves/abstract/curve.d.ts +67 -0
  863. package/js/src/src/static_dependencies/noble-curves/abstract/curve.js +157 -0
  864. package/js/src/src/static_dependencies/noble-curves/abstract/edwards.d.ts +79 -0
  865. package/js/src/src/static_dependencies/noble-curves/abstract/edwards.js +432 -0
  866. package/js/src/src/static_dependencies/noble-curves/abstract/hash-to-curve.d.ts +56 -0
  867. package/js/src/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +171 -0
  868. package/js/src/src/static_dependencies/noble-curves/abstract/modular.d.ts +68 -0
  869. package/js/src/src/static_dependencies/noble-curves/abstract/modular.js +351 -0
  870. package/js/src/src/static_dependencies/noble-curves/abstract/montgomery.d.ts +25 -0
  871. package/js/src/src/static_dependencies/noble-curves/abstract/montgomery.js +162 -0
  872. package/js/src/src/static_dependencies/noble-curves/abstract/poseidon.d.ts +29 -0
  873. package/js/src/src/static_dependencies/noble-curves/abstract/poseidon.js +115 -0
  874. package/js/src/src/static_dependencies/noble-curves/abstract/utils.d.ts +53 -0
  875. package/js/src/src/static_dependencies/noble-curves/abstract/utils.js +227 -0
  876. package/js/src/src/static_dependencies/noble-curves/abstract/weierstrass.d.ts +204 -0
  877. package/js/src/src/static_dependencies/noble-curves/abstract/weierstrass.js +1016 -0
  878. package/js/src/src/static_dependencies/noble-curves/ed25519.d.ts +53 -0
  879. package/js/src/src/static_dependencies/noble-curves/ed25519.js +402 -0
  880. package/js/src/src/static_dependencies/noble-curves/p256.d.ts +103 -0
  881. package/js/src/src/static_dependencies/noble-curves/p256.js +47 -0
  882. package/js/src/src/static_dependencies/noble-curves/secp256k1.d.ts +91 -0
  883. package/js/src/src/static_dependencies/noble-curves/secp256k1.js +257 -0
  884. package/js/src/src/static_dependencies/noble-hashes/_assert.d.ts +21 -0
  885. package/js/src/src/static_dependencies/noble-hashes/_assert.js +48 -0
  886. package/js/src/src/static_dependencies/noble-hashes/_sha2.d.ts +23 -0
  887. package/js/src/src/static_dependencies/noble-hashes/_sha2.js +119 -0
  888. package/js/src/src/static_dependencies/noble-hashes/_u64.d.ts +35 -0
  889. package/js/src/src/static_dependencies/noble-hashes/_u64.js +66 -0
  890. package/js/src/src/static_dependencies/noble-hashes/crypto.d.ts +1 -0
  891. package/js/src/src/static_dependencies/noble-hashes/crypto.js +7 -0
  892. package/js/src/src/static_dependencies/noble-hashes/hmac.d.ts +26 -0
  893. package/js/src/src/static_dependencies/noble-hashes/hmac.js +82 -0
  894. package/js/src/src/static_dependencies/noble-hashes/md5.d.ts +18 -0
  895. package/js/src/src/static_dependencies/noble-hashes/md5.js +242 -0
  896. package/js/src/src/static_dependencies/noble-hashes/sha1.d.ts +21 -0
  897. package/js/src/src/static_dependencies/noble-hashes/sha1.js +90 -0
  898. package/js/src/src/static_dependencies/noble-hashes/sha256.d.ts +34 -0
  899. package/js/src/src/static_dependencies/noble-hashes/sha256.js +129 -0
  900. package/js/src/src/static_dependencies/noble-hashes/sha3.d.ts +97 -0
  901. package/js/src/src/static_dependencies/noble-hashes/sha3.js +211 -0
  902. package/js/src/src/static_dependencies/noble-hashes/sha512.d.ts +66 -0
  903. package/js/src/src/static_dependencies/noble-hashes/sha512.js +236 -0
  904. package/js/src/src/static_dependencies/noble-hashes/utils.d.ts +77 -0
  905. package/js/src/src/static_dependencies/noble-hashes/utils.js +147 -0
  906. package/js/src/src/static_dependencies/proxies/agent-base/helpers.d.ts +14 -0
  907. package/js/src/src/static_dependencies/proxies/agent-base/helpers.js +42 -0
  908. package/js/src/src/static_dependencies/proxies/agent-base/index.d.ts +33 -0
  909. package/js/src/src/static_dependencies/proxies/agent-base/index.js +82 -0
  910. package/js/src/src/static_dependencies/proxies/http-proxy-agent/index.d.ts +40 -0
  911. package/js/src/src/static_dependencies/proxies/http-proxy-agent/index.js +119 -0
  912. package/js/src/src/static_dependencies/proxies/https-proxy-agent/index.d.ts +45 -0
  913. package/js/src/src/static_dependencies/proxies/https-proxy-agent/index.js +150 -0
  914. package/js/src/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.d.ts +15 -0
  915. package/js/src/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
  916. package/js/src/src/static_dependencies/qs/formats.cjs +22 -0
  917. package/js/src/src/static_dependencies/qs/formats.d.cts +14 -0
  918. package/js/src/src/static_dependencies/qs/index.cjs +15 -0
  919. package/js/src/src/static_dependencies/qs/index.d.cts +10 -0
  920. package/js/src/src/static_dependencies/qs/parse.cjs +208 -0
  921. package/js/src/src/static_dependencies/qs/parse.d.cts +8 -0
  922. package/js/src/src/static_dependencies/qs/stringify.cjs +192 -0
  923. package/js/src/src/static_dependencies/qs/stringify.d.cts +8 -0
  924. package/js/src/src/static_dependencies/qs/utils.cjs +202 -0
  925. package/js/src/src/static_dependencies/qs/utils.d.cts +15 -0
  926. package/js/src/src/static_dependencies/scure-base/index.d.ts +92 -0
  927. package/js/src/src/static_dependencies/scure-base/index.js +420 -0
  928. package/js/src/src/static_dependencies/scure-starknet/index.d.ts +79 -0
  929. package/js/src/src/static_dependencies/scure-starknet/index.js +323 -0
  930. package/js/src/src/static_dependencies/starknet/constants.d.ts +61 -0
  931. package/js/src/src/static_dependencies/starknet/constants.js +67 -0
  932. package/js/src/src/static_dependencies/starknet/index.d.ts +3 -0
  933. package/js/src/src/static_dependencies/starknet/index.js +9 -0
  934. package/js/src/src/static_dependencies/starknet/types/cairoEnum.d.ts +2 -0
  935. package/js/src/src/static_dependencies/starknet/types/cairoEnum.js +7 -0
  936. package/js/src/src/static_dependencies/starknet/types/calldata.d.ts +19 -0
  937. package/js/src/src/static_dependencies/starknet/types/calldata.js +28 -0
  938. package/js/src/src/static_dependencies/starknet/types/index.d.ts +13 -0
  939. package/js/src/src/static_dependencies/starknet/types/index.js +16 -0
  940. package/js/src/src/static_dependencies/starknet/types/lib/contract/abi.d.ts +71 -0
  941. package/js/src/src/static_dependencies/starknet/types/lib/contract/abi.js +13 -0
  942. package/js/src/src/static_dependencies/starknet/types/lib/contract/index.d.ts +24 -0
  943. package/js/src/src/static_dependencies/starknet/types/lib/contract/index.js +16 -0
  944. package/js/src/src/static_dependencies/starknet/types/lib/contract/legacy.d.ts +33 -0
  945. package/js/src/src/static_dependencies/starknet/types/lib/contract/legacy.js +7 -0
  946. package/js/src/src/static_dependencies/starknet/types/lib/contract/sierra.d.ts +52 -0
  947. package/js/src/src/static_dependencies/starknet/types/lib/contract/sierra.js +7 -0
  948. package/js/src/src/static_dependencies/starknet/types/lib/index.d.ts +248 -0
  949. package/js/src/src/static_dependencies/starknet/types/lib/index.js +52 -0
  950. package/js/src/src/static_dependencies/starknet/types/typedData.d.ts +44 -0
  951. package/js/src/src/static_dependencies/starknet/types/typedData.js +19 -0
  952. package/js/src/src/static_dependencies/starknet/utils/assert.d.ts +7 -0
  953. package/js/src/src/static_dependencies/starknet/utils/assert.js +17 -0
  954. package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/felt.d.ts +6 -0
  955. package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/felt.js +43 -0
  956. package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint256.d.ts +72 -0
  957. package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint256.js +117 -0
  958. package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint512.d.ts +76 -0
  959. package/js/src/src/static_dependencies/starknet/utils/cairoDataTypes/uint512.js +136 -0
  960. package/js/src/src/static_dependencies/starknet/utils/calldata/byteArray.d.ts +32 -0
  961. package/js/src/src/static_dependencies/starknet/utils/calldata/byteArray.js +59 -0
  962. package/js/src/src/static_dependencies/starknet/utils/calldata/cairo.d.ts +183 -0
  963. package/js/src/src/static_dependencies/starknet/utils/calldata/cairo.js +229 -0
  964. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoCustomEnum.d.ts +38 -0
  965. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoCustomEnum.js +57 -0
  966. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoOption.d.ts +35 -0
  967. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoOption.js +64 -0
  968. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoResult.d.ts +34 -0
  969. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/CairoResult.js +63 -0
  970. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/index.d.ts +3 -0
  971. package/js/src/src/static_dependencies/starknet/utils/calldata/enum/index.js +9 -0
  972. package/js/src/src/static_dependencies/starknet/utils/calldata/formatter.d.ts +9 -0
  973. package/js/src/src/static_dependencies/starknet/utils/calldata/formatter.js +67 -0
  974. package/js/src/src/static_dependencies/starknet/utils/calldata/index.d.ts +89 -0
  975. package/js/src/src/static_dependencies/starknet/utils/calldata/index.js +280 -0
  976. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/index.d.ts +5 -0
  977. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/index.js +30 -0
  978. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/interface.d.ts +20 -0
  979. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/interface.js +8 -0
  980. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-0-1.1.0.d.ts +24 -0
  981. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-0-1.1.0.js +36 -0
  982. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-2.0.0.d.ts +23 -0
  983. package/js/src/src/static_dependencies/starknet/utils/calldata/parser/parser-2.0.0.js +40 -0
  984. package/js/src/src/static_dependencies/starknet/utils/calldata/propertyOrder.d.ts +2 -0
  985. package/js/src/src/static_dependencies/starknet/utils/calldata/propertyOrder.js +155 -0
  986. package/js/src/src/static_dependencies/starknet/utils/calldata/requestParser.d.ts +11 -0
  987. package/js/src/src/static_dependencies/starknet/utils/calldata/requestParser.js +248 -0
  988. package/js/src/src/static_dependencies/starknet/utils/calldata/responseParser.d.ts +11 -0
  989. package/js/src/src/static_dependencies/starknet/utils/calldata/responseParser.js +214 -0
  990. package/js/src/src/static_dependencies/starknet/utils/calldata/tuple.d.ts +6 -0
  991. package/js/src/src/static_dependencies/starknet/utils/calldata/tuple.js +113 -0
  992. package/js/src/src/static_dependencies/starknet/utils/calldata/validate.d.ts +6 -0
  993. package/js/src/src/static_dependencies/starknet/utils/calldata/validate.js +208 -0
  994. package/js/src/src/static_dependencies/starknet/utils/encode.d.ts +207 -0
  995. package/js/src/src/static_dependencies/starknet/utils/encode.js +282 -0
  996. package/js/src/src/static_dependencies/starknet/utils/hash/classHash.d.ts +57 -0
  997. package/js/src/src/static_dependencies/starknet/utils/hash/classHash.js +223 -0
  998. package/js/src/src/static_dependencies/starknet/utils/hash/index.d.ts +6 -0
  999. package/js/src/src/static_dependencies/starknet/utils/hash/index.js +13 -0
  1000. package/js/src/src/static_dependencies/starknet/utils/merkle.d.ts +35 -0
  1001. package/js/src/src/static_dependencies/starknet/utils/merkle.js +84 -0
  1002. package/js/src/src/static_dependencies/starknet/utils/num.d.ts +182 -0
  1003. package/js/src/src/static_dependencies/starknet/utils/num.js +244 -0
  1004. package/js/src/src/static_dependencies/starknet/utils/selector.d.ts +48 -0
  1005. package/js/src/src/static_dependencies/starknet/utils/selector.js +85 -0
  1006. package/js/src/src/static_dependencies/starknet/utils/shortString.d.ts +57 -0
  1007. package/js/src/src/static_dependencies/starknet/utils/shortString.js +96 -0
  1008. package/js/src/src/static_dependencies/starknet/utils/typedData.d.ts +54 -0
  1009. package/js/src/src/static_dependencies/starknet/utils/typedData.js +321 -0
  1010. package/js/src/src/static_dependencies/watchable/src/types.d.ts +28 -0
  1011. package/js/src/src/static_dependencies/watchable/src/types.js +8 -0
  1012. package/js/src/src/static_dependencies/watchable/src/unpromise.d.ts +120 -0
  1013. package/js/src/src/static_dependencies/watchable/src/unpromise.js +297 -0
  1014. package/js/src/src/static_dependencies/zklink/zklink-sdk-web.d.ts +1279 -0
  1015. package/js/src/src/static_dependencies/zklink/zklink-sdk-web.js +4282 -0
  1016. package/js/src/src/tabdeal.d.ts +23 -0
  1017. package/js/src/src/tabdeal.js +387 -0
  1018. package/js/src/src/tehran_exchange.d.ts +21 -0
  1019. package/js/src/src/tehran_exchange.js +333 -0
  1020. package/js/src/src/tetherland.d.ts +21 -0
  1021. package/js/src/src/tetherland.js +367 -0
  1022. package/js/src/src/timex.d.ts +247 -0
  1023. package/js/src/src/timex.js +1792 -0
  1024. package/js/src/src/tokocrypto.d.ts +261 -0
  1025. package/js/src/src/tokocrypto.js +2641 -0
  1026. package/js/src/src/toobit.d.ts +22 -0
  1027. package/js/src/src/toobit.js +445 -0
  1028. package/js/src/src/tradeogre.d.ts +149 -0
  1029. package/js/src/src/tradeogre.js +878 -0
  1030. package/js/src/src/twox.d.ts +21 -0
  1031. package/js/src/src/twox.js +371 -0
  1032. package/js/src/src/ubitex.d.ts +23 -0
  1033. package/js/src/src/ubitex.js +433 -0
  1034. package/js/src/src/upbit.d.ts +377 -0
  1035. package/js/src/src/upbit.js +2340 -0
  1036. package/js/src/src/vertex.d.ts +346 -0
  1037. package/js/src/src/vertex.js +3146 -0
  1038. package/js/src/src/wallex.d.ts +23 -0
  1039. package/js/src/src/wallex.js +467 -0
  1040. package/js/src/src/wavesexchange.d.ts +244 -0
  1041. package/js/src/src/wavesexchange.js +2747 -0
  1042. package/js/src/src/whitebit.d.ts +571 -0
  1043. package/js/src/src/whitebit.js +3437 -0
  1044. package/js/src/src/woo.d.ts +727 -0
  1045. package/js/src/src/woo.js +4183 -0
  1046. package/js/src/src/woofipro.d.ts +497 -0
  1047. package/js/src/src/woofipro.js +2941 -0
  1048. package/js/src/src/xt.d.ts +568 -0
  1049. package/js/src/src/xt.js +5184 -0
  1050. package/js/src/src/yobit.d.ts +197 -0
  1051. package/js/src/src/yobit.js +1453 -0
  1052. package/js/src/src/zaif.d.ts +136 -0
  1053. package/js/src/src/zaif.js +821 -0
  1054. package/js/src/src/zonda.d.ts +214 -0
  1055. package/js/src/src/zonda.js +1984 -0
  1056. package/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.d.ts +1 -1
  1057. package/js/src/static_dependencies/starknet/utils/calldata/parser/index.d.ts +1 -1
  1058. package/js/test.js +9 -17
  1059. package/package.json +1 -1
@@ -0,0 +1,4373 @@
1
+ // ----------------------------------------------------------------------------
2
+
3
+ // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+ // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
+
7
+ // ----------------------------------------------------------------------------
8
+ import binanceRest from '../binance.js';
9
+ import { Precise } from '../base/Precise.js';
10
+ import { ChecksumError, ArgumentsRequired, BadRequest, NotSupported } from '../base/errors.js';
11
+ import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide } from '../base/ws/Cache.js';
12
+ import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
13
+ import { rsa } from '../base/functions/rsa.js';
14
+ import { eddsa } from '../base/functions/crypto.js';
15
+ import { ed25519 } from '../static_dependencies/noble-curves/ed25519.js';
16
+ // -----------------------------------------------------------------------------
17
+ export default class binance extends binanceRest {
18
+ describe() {
19
+ const superDescribe = super.describe();
20
+ return this.deepExtend(superDescribe, this.describeData());
21
+ }
22
+ describeData() {
23
+ return {
24
+ 'has': {
25
+ 'ws': true,
26
+ 'watchBalance': true,
27
+ 'watchLiquidations': true,
28
+ 'watchLiquidationsForSymbols': true,
29
+ 'watchMyLiquidations': true,
30
+ 'watchMyLiquidationsForSymbols': true,
31
+ 'watchBidsAsks': true,
32
+ 'watchMyTrades': true,
33
+ 'watchOHLCV': true,
34
+ 'watchOHLCVForSymbols': true,
35
+ 'watchOrderBook': true,
36
+ 'watchOrderBookForSymbols': true,
37
+ 'watchOrders': true,
38
+ 'watchOrdersForSymbols': true,
39
+ 'watchPositions': true,
40
+ 'watchTicker': true,
41
+ 'watchTickers': true,
42
+ 'watchMarkPrices': true,
43
+ 'watchMarkPrice': true,
44
+ 'watchTrades': true,
45
+ 'watchTradesForSymbols': true,
46
+ 'createOrderWs': true,
47
+ 'editOrderWs': true,
48
+ 'cancelOrderWs': true,
49
+ 'cancelOrdersWs': false,
50
+ 'cancelAllOrdersWs': true,
51
+ 'fetchBalanceWs': true,
52
+ 'fetchDepositsWs': false,
53
+ 'fetchMarketsWs': false,
54
+ 'fetchMyTradesWs': true,
55
+ 'fetchOHLCVWs': true,
56
+ 'fetchOrderBookWs': true,
57
+ 'fetchOpenOrdersWs': true,
58
+ 'fetchOrderWs': true,
59
+ 'fetchOrdersWs': true,
60
+ 'fetchPositionWs': true,
61
+ 'fetchPositionForSymbolWs': true,
62
+ 'fetchPositionsWs': true,
63
+ 'fetchTickerWs': true,
64
+ 'fetchTradesWs': true,
65
+ 'fetchTradingFeesWs': false,
66
+ 'fetchWithdrawalsWs': false,
67
+ },
68
+ 'urls': {
69
+ 'test': {
70
+ 'ws': {
71
+ 'spot': 'wss://stream.testnet.binance.vision/ws',
72
+ 'margin': 'wss://stream.testnet.binance.vision/ws',
73
+ 'future': 'wss://fstream.binancefuture.com/ws',
74
+ 'delivery': 'wss://dstream.binancefuture.com/ws',
75
+ 'ws-api': {
76
+ 'spot': 'wss://ws-api.testnet.binance.vision/ws-api/v3',
77
+ 'future': 'wss://testnet.binancefuture.com/ws-fapi/v1',
78
+ 'delivery': 'wss://testnet.binancefuture.com/ws-dapi/v1',
79
+ },
80
+ },
81
+ },
82
+ 'api': {
83
+ 'ws': {
84
+ 'spot': 'wss://stream.binance.com:9443/ws',
85
+ 'margin': 'wss://stream.binance.com:9443/ws',
86
+ 'future': 'wss://fstream.binance.com/ws',
87
+ 'delivery': 'wss://dstream.binance.com/ws',
88
+ 'ws-api': {
89
+ 'spot': 'wss://ws-api.binance.com:443/ws-api/v3',
90
+ 'future': 'wss://ws-fapi.binance.com/ws-fapi/v1',
91
+ 'delivery': 'wss://ws-dapi.binance.com/ws-dapi/v1',
92
+ },
93
+ 'papi': 'wss://fstream.binance.com/pm/ws',
94
+ },
95
+ },
96
+ 'doc': 'https://developers.binance.com/en',
97
+ },
98
+ 'streaming': {
99
+ 'keepAlive': 180000,
100
+ },
101
+ 'options': {
102
+ 'returnRateLimits': false,
103
+ 'streamLimits': {
104
+ 'spot': 50,
105
+ 'margin': 50,
106
+ 'future': 50,
107
+ 'delivery': 50, // max 200
108
+ },
109
+ 'subscriptionLimitByStream': {
110
+ 'spot': 200,
111
+ 'margin': 200,
112
+ 'future': 200,
113
+ 'delivery': 200,
114
+ },
115
+ 'streamBySubscriptionsHash': this.createSafeDictionary(),
116
+ 'streamIndex': -1,
117
+ // get updates every 1000ms or 100ms
118
+ // or every 0ms in real-time for futures
119
+ 'watchOrderBookRate': 100,
120
+ 'liquidationsLimit': 1000,
121
+ 'myLiquidationsLimit': 1000,
122
+ 'tradesLimit': 1000,
123
+ 'ordersLimit': 1000,
124
+ 'OHLCVLimit': 1000,
125
+ 'requestId': this.createSafeDictionary(),
126
+ 'watchOrderBookLimit': 1000,
127
+ 'watchTrades': {
128
+ 'name': 'trade', // 'trade' or 'aggTrade'
129
+ },
130
+ 'watchTicker': {
131
+ 'name': 'ticker', // ticker or miniTicker or ticker_<window_size>
132
+ },
133
+ 'watchTickers': {
134
+ 'name': 'ticker', // ticker or miniTicker or ticker_<window_size>
135
+ },
136
+ 'watchOHLCV': {
137
+ 'name': 'kline', // or indexPriceKline or markPriceKline (coin-m futures)
138
+ },
139
+ 'watchOrderBook': {
140
+ 'maxRetries': 3,
141
+ 'checksum': true,
142
+ },
143
+ 'watchBalance': {
144
+ 'fetchBalanceSnapshot': false,
145
+ 'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
146
+ },
147
+ 'watchLiquidationsForSymbols': {
148
+ 'defaultType': 'swap',
149
+ },
150
+ 'watchPositions': {
151
+ 'fetchPositionsSnapshot': true,
152
+ 'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
153
+ },
154
+ 'wallet': 'wb',
155
+ 'listenKeyRefreshRate': 1200000,
156
+ 'ws': {
157
+ 'cost': 5,
158
+ },
159
+ 'tickerChannelsMap': {
160
+ '24hrTicker': 'ticker',
161
+ '24hrMiniTicker': 'miniTicker',
162
+ 'markPriceUpdate': 'markPrice',
163
+ // rolling window tickers
164
+ '1hTicker': 'ticker_1h',
165
+ '4hTicker': 'ticker_4h',
166
+ '1dTicker': 'ticker_1d',
167
+ 'bookTicker': 'bookTicker',
168
+ },
169
+ },
170
+ };
171
+ }
172
+ requestId(url) {
173
+ const options = this.safeDict(this.options, 'requestId', this.createSafeDictionary());
174
+ const previousValue = this.safeInteger(options, url, 0);
175
+ const newValue = this.sum(previousValue, 1);
176
+ this.options['requestId'][url] = newValue;
177
+ return newValue;
178
+ }
179
+ stream(type, subscriptionHash, numSubscriptions = 1) {
180
+ const streamBySubscriptionsHash = this.safeDict(this.options, 'streamBySubscriptionsHash', this.createSafeDictionary());
181
+ let stream = this.safeString(streamBySubscriptionsHash, subscriptionHash);
182
+ if (stream === undefined) {
183
+ let streamIndex = this.safeInteger(this.options, 'streamIndex', -1);
184
+ const streamLimits = this.safeValue(this.options, 'streamLimits');
185
+ const streamLimit = this.safeInteger(streamLimits, type);
186
+ streamIndex = streamIndex + 1;
187
+ const normalizedIndex = streamIndex % streamLimit;
188
+ this.options['streamIndex'] = streamIndex;
189
+ stream = this.numberToString(normalizedIndex);
190
+ this.options['streamBySubscriptionsHash'][subscriptionHash] = stream;
191
+ const subscriptionsByStreams = this.safeValue(this.options, 'numSubscriptionsByStream');
192
+ if (subscriptionsByStreams === undefined) {
193
+ this.options['numSubscriptionsByStream'] = this.createSafeDictionary();
194
+ }
195
+ const subscriptionsByStream = this.safeInteger(this.options['numSubscriptionsByStream'], stream, 0);
196
+ const newNumSubscriptions = subscriptionsByStream + numSubscriptions;
197
+ const subscriptionLimitByStream = this.safeInteger(this.options['subscriptionLimitByStream'], type, 200);
198
+ if (newNumSubscriptions > subscriptionLimitByStream) {
199
+ throw new BadRequest(this.id + ' reached the limit of subscriptions by stream. Increase the number of streams, or increase the stream limit or subscription limit by stream if the exchange allows.');
200
+ }
201
+ this.options['numSubscriptionsByStream'][stream] = subscriptionsByStream + numSubscriptions;
202
+ }
203
+ return stream;
204
+ }
205
+ /**
206
+ * @method
207
+ * @name binance#watchLiquidations
208
+ * @description watch the public liquidations of a trading pair
209
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Liquidation-Order-Streams
210
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Liquidation-Order-Streams
211
+ * @param {string} symbol unified CCXT market symbol
212
+ * @param {int} [since] the earliest time in ms to fetch liquidations for
213
+ * @param {int} [limit] the maximum number of liquidation structures to retrieve
214
+ * @param {object} [params] exchange specific parameters for the bitmex api endpoint
215
+ * @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
216
+ */
217
+ async watchLiquidations(symbol, since = undefined, limit = undefined, params = {}) {
218
+ return await this.watchLiquidationsForSymbols([symbol], since, limit, params);
219
+ }
220
+ /**
221
+ * @method
222
+ * @name binance#watchLiquidationsForSymbols
223
+ * @description watch the public liquidations of a trading pair
224
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Liquidation-Order-Streams
225
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Liquidation-Order-Streams
226
+ * @param {string[]} symbols list of unified market symbols
227
+ * @param {int} [since] the earliest time in ms to fetch liquidations for
228
+ * @param {int} [limit] the maximum number of liquidation structures to retrieve
229
+ * @param {object} [params] exchange specific parameters for the bitmex api endpoint
230
+ * @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
231
+ */
232
+ async watchLiquidationsForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
233
+ await this.loadMarkets();
234
+ const subscriptionHashes = [];
235
+ const messageHashes = [];
236
+ let streamHash = 'liquidations';
237
+ symbols = this.marketSymbols(symbols, undefined, true, true);
238
+ if (this.isEmpty(symbols)) {
239
+ subscriptionHashes.push('!' + 'forceOrder@arr');
240
+ messageHashes.push('liquidations');
241
+ }
242
+ else {
243
+ for (let i = 0; i < symbols.length; i++) {
244
+ const market = this.market(symbols[i]);
245
+ subscriptionHashes.push(market['lowercaseId'] + '@forceOrder');
246
+ messageHashes.push('liquidations::' + symbols[i]);
247
+ }
248
+ streamHash += '::' + symbols.join(',');
249
+ }
250
+ const firstMarket = this.getMarketFromSymbols(symbols);
251
+ let type = undefined;
252
+ [type, params] = this.handleMarketTypeAndParams('watchLiquidationsForSymbols', firstMarket, params);
253
+ if (type === 'spot') {
254
+ throw new BadRequest(this.id + ' watchLiquidationsForSymbols is not supported for spot symbols');
255
+ }
256
+ let subType = undefined;
257
+ [subType, params] = this.handleSubTypeAndParams('watchLiquidationsForSymbols', firstMarket, params);
258
+ if (this.isLinear(type, subType)) {
259
+ type = 'future';
260
+ }
261
+ else if (this.isInverse(type, subType)) {
262
+ type = 'delivery';
263
+ }
264
+ const numSubscriptions = subscriptionHashes.length;
265
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, numSubscriptions);
266
+ const requestId = this.requestId(url);
267
+ const request = {
268
+ 'method': 'SUBSCRIBE',
269
+ 'params': subscriptionHashes,
270
+ 'id': requestId,
271
+ };
272
+ const subscribe = {
273
+ 'id': requestId,
274
+ };
275
+ const newLiquidations = await this.watchMultiple(url, messageHashes, this.extend(request, params), subscriptionHashes, subscribe);
276
+ if (this.newUpdates) {
277
+ return newLiquidations;
278
+ }
279
+ return this.filterBySymbolsSinceLimit(this.liquidations, symbols, since, limit, true);
280
+ }
281
+ handleLiquidation(client, message) {
282
+ //
283
+ // future
284
+ // {
285
+ // "e":"forceOrder",
286
+ // "E":1698871323061,
287
+ // "o":{
288
+ // "s":"BTCUSDT",
289
+ // "S":"BUY",
290
+ // "o":"LIMIT",
291
+ // "f":"IOC",
292
+ // "q":"1.437",
293
+ // "p":"35100.81",
294
+ // "ap":"34959.70",
295
+ // "X":"FILLED",
296
+ // "l":"1.437",
297
+ // "z":"1.437",
298
+ // "T":1698871323059
299
+ // }
300
+ // }
301
+ // delivery
302
+ // {
303
+ // "e":"forceOrder", // Event Type
304
+ // "E": 1591154240950, // Event Time
305
+ // "o":{
306
+ // "s":"BTCUSD_200925", // Symbol
307
+ // "ps": "BTCUSD", // Pair
308
+ // "S":"SELL", // Side
309
+ // "o":"LIMIT", // Order Type
310
+ // "f":"IOC", // Time in Force
311
+ // "q":"1", // Original Quantity
312
+ // "p":"9425.5", // Price
313
+ // "ap":"9496.5", // Average Price
314
+ // "X":"FILLED", // Order Status
315
+ // "l":"1", // Order Last Filled Quantity
316
+ // "z":"1", // Order Filled Accumulated Quantity
317
+ // "T": 1591154240949, // Order Trade Time
318
+ // }
319
+ // }
320
+ //
321
+ const rawLiquidation = this.safeValue(message, 'o', {});
322
+ const marketId = this.safeString(rawLiquidation, 's');
323
+ const market = this.safeMarket(marketId, undefined, '', 'contract');
324
+ const symbol = market['symbol'];
325
+ const liquidation = this.parseWsLiquidation(rawLiquidation, market);
326
+ let liquidations = this.safeValue(this.liquidations, symbol);
327
+ if (liquidations === undefined) {
328
+ const limit = this.safeInteger(this.options, 'liquidationsLimit', 1000);
329
+ liquidations = new ArrayCache(limit);
330
+ }
331
+ liquidations.append(liquidation);
332
+ this.liquidations[symbol] = liquidations;
333
+ client.resolve([liquidation], 'liquidations');
334
+ client.resolve([liquidation], 'liquidations::' + symbol);
335
+ }
336
+ parseWsLiquidation(liquidation, market = undefined) {
337
+ //
338
+ // future
339
+ // {
340
+ // "s":"BTCUSDT",
341
+ // "S":"BUY",
342
+ // "o":"LIMIT",
343
+ // "f":"IOC",
344
+ // "q":"1.437",
345
+ // "p":"35100.81",
346
+ // "ap":"34959.70",
347
+ // "X":"FILLED",
348
+ // "l":"1.437",
349
+ // "z":"1.437",
350
+ // "T":1698871323059
351
+ // }
352
+ // delivery
353
+ // {
354
+ // "s":"BTCUSD_200925", // Symbol
355
+ // "ps": "BTCUSD", // Pair
356
+ // "S":"SELL", // Side
357
+ // "o":"LIMIT", // Order Type
358
+ // "f":"IOC", // Time in Force
359
+ // "q":"1", // Original Quantity
360
+ // "p":"9425.5", // Price
361
+ // "ap":"9496.5", // Average Price
362
+ // "X":"FILLED", // Order Status
363
+ // "l":"1", // Order Last Filled Quantity
364
+ // "z":"1", // Order Filled Accumulated Quantity
365
+ // "T": 1591154240949, // Order Trade Time
366
+ // }
367
+ // myLiquidation
368
+ // {
369
+ // "s":"BTCUSDT", // Symbol
370
+ // "c":"TEST", // Client Order Id
371
+ // // special client order id:
372
+ // // starts with "autoclose-": liquidation order
373
+ // // "adl_autoclose": ADL auto close order
374
+ // // "settlement_autoclose-": settlement order for delisting or delivery
375
+ // "S":"SELL", // Side
376
+ // "o":"TRAILING_STOP_MARKET", // Order Type
377
+ // "f":"GTC", // Time in Force
378
+ // "q":"0.001", // Original Quantity
379
+ // "p":"0", // Original Price
380
+ // "ap":"0", // Average Price
381
+ // "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
382
+ // "x":"NEW", // Execution Type
383
+ // "X":"NEW", // Order Status
384
+ // "i":8886774, // Order Id
385
+ // "l":"0", // Order Last Filled Quantity
386
+ // "z":"0", // Order Filled Accumulated Quantity
387
+ // "L":"0", // Last Filled Price
388
+ // "N":"USDT", // Commission Asset, will not push if no commission
389
+ // "n":"0", // Commission, will not push if no commission
390
+ // "T":1568879465650, // Order Trade Time
391
+ // "t":0, // Trade Id
392
+ // "b":"0", // Bids Notional
393
+ // "a":"9.91", // Ask Notional
394
+ // "m":false, // Is this trade the maker side?
395
+ // "R":false, // Is this reduce only
396
+ // "wt":"CONTRACT_PRICE", // Stop Price Working Type
397
+ // "ot":"TRAILING_STOP_MARKET",// Original Order Type
398
+ // "ps":"LONG", // Position Side
399
+ // "cp":false, // If Close-All, pushed with conditional order
400
+ // "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
401
+ // "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
402
+ // "pP": false, // If price protection is turned on
403
+ // "si": 0, // ignore
404
+ // "ss": 0, // ignore
405
+ // "rp":"0", // Realized Profit of the trade
406
+ // "V":"EXPIRE_TAKER", // STP mode
407
+ // "pm":"OPPONENT", // Price match mode
408
+ // "gtd":0 // TIF GTD order auto cancel time
409
+ // }
410
+ //
411
+ const marketId = this.safeString(liquidation, 's');
412
+ market = this.safeMarket(marketId, market);
413
+ const timestamp = this.safeInteger(liquidation, 'T');
414
+ return this.safeLiquidation({
415
+ 'info': liquidation,
416
+ 'symbol': this.safeSymbol(marketId, market),
417
+ 'contracts': this.safeNumber(liquidation, 'l'),
418
+ 'contractSize': this.safeNumber(market, 'contractSize'),
419
+ 'price': this.safeNumber(liquidation, 'ap'),
420
+ 'side': this.safeStringLower(liquidation, 'S'),
421
+ 'baseValue': undefined,
422
+ 'quoteValue': undefined,
423
+ 'timestamp': timestamp,
424
+ 'datetime': this.iso8601(timestamp),
425
+ });
426
+ }
427
+ /**
428
+ * @method
429
+ * @name binance#watchMyLiquidations
430
+ * @description watch the private liquidations of a trading pair
431
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Event-Order-Update
432
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/user-data-streams/Event-Order-Update
433
+ * @param {string} symbol unified CCXT market symbol
434
+ * @param {int} [since] the earliest time in ms to fetch liquidations for
435
+ * @param {int} [limit] the maximum number of liquidation structures to retrieve
436
+ * @param {object} [params] exchange specific parameters for the bitmex api endpoint
437
+ * @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
438
+ */
439
+ async watchMyLiquidations(symbol, since = undefined, limit = undefined, params = {}) {
440
+ return this.watchMyLiquidationsForSymbols([symbol], since, limit, params);
441
+ }
442
+ /**
443
+ * @method
444
+ * @name binance#watchMyLiquidationsForSymbols
445
+ * @description watch the private liquidations of a trading pair
446
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Event-Order-Update
447
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/user-data-streams/Event-Order-Update
448
+ * @param {string[]} symbols list of unified market symbols
449
+ * @param {int} [since] the earliest time in ms to fetch liquidations for
450
+ * @param {int} [limit] the maximum number of liquidation structures to retrieve
451
+ * @param {object} [params] exchange specific parameters for the bitmex api endpoint
452
+ * @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
453
+ */
454
+ async watchMyLiquidationsForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
455
+ await this.loadMarkets();
456
+ symbols = this.marketSymbols(symbols, undefined, true, true, true);
457
+ const market = this.getMarketFromSymbols(symbols);
458
+ const messageHashes = ['myLiquidations'];
459
+ if (!this.isEmpty(symbols)) {
460
+ for (let i = 0; i < symbols.length; i++) {
461
+ const symbol = symbols[i];
462
+ messageHashes.push('myLiquidations::' + symbol);
463
+ }
464
+ }
465
+ let type = undefined;
466
+ [type, params] = this.handleMarketTypeAndParams('watchMyLiquidationsForSymbols', market, params);
467
+ let subType = undefined;
468
+ [subType, params] = this.handleSubTypeAndParams('watchMyLiquidationsForSymbols', market, params);
469
+ if (this.isLinear(type, subType)) {
470
+ type = 'future';
471
+ }
472
+ else if (this.isInverse(type, subType)) {
473
+ type = 'delivery';
474
+ }
475
+ await this.authenticate(params);
476
+ const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
477
+ const message = undefined;
478
+ const newLiquidations = await this.watchMultiple(url, messageHashes, message, [type]);
479
+ if (this.newUpdates) {
480
+ return newLiquidations;
481
+ }
482
+ return this.filterBySymbolsSinceLimit(this.liquidations, symbols, since, limit);
483
+ }
484
+ handleMyLiquidation(client, message) {
485
+ //
486
+ // {
487
+ // "s":"BTCUSDT", // Symbol
488
+ // "c":"TEST", // Client Order Id
489
+ // // special client order id:
490
+ // // starts with "autoclose-": liquidation order
491
+ // // "adl_autoclose": ADL auto close order
492
+ // // "settlement_autoclose-": settlement order for delisting or delivery
493
+ // "S":"SELL", // Side
494
+ // "o":"TRAILING_STOP_MARKET", // Order Type
495
+ // "f":"GTC", // Time in Force
496
+ // "q":"0.001", // Original Quantity
497
+ // "p":"0", // Original Price
498
+ // "ap":"0", // Average Price
499
+ // "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
500
+ // "x":"NEW", // Execution Type
501
+ // "X":"NEW", // Order Status
502
+ // "i":8886774, // Order Id
503
+ // "l":"0", // Order Last Filled Quantity
504
+ // "z":"0", // Order Filled Accumulated Quantity
505
+ // "L":"0", // Last Filled Price
506
+ // "N":"USDT", // Commission Asset, will not push if no commission
507
+ // "n":"0", // Commission, will not push if no commission
508
+ // "T":1568879465650, // Order Trade Time
509
+ // "t":0, // Trade Id
510
+ // "b":"0", // Bids Notional
511
+ // "a":"9.91", // Ask Notional
512
+ // "m":false, // Is this trade the maker side?
513
+ // "R":false, // Is this reduce only
514
+ // "wt":"CONTRACT_PRICE", // Stop Price Working Type
515
+ // "ot":"TRAILING_STOP_MARKET",// Original Order Type
516
+ // "ps":"LONG", // Position Side
517
+ // "cp":false, // If Close-All, pushed with conditional order
518
+ // "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
519
+ // "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
520
+ // "pP": false, // If price protection is turned on
521
+ // "si": 0, // ignore
522
+ // "ss": 0, // ignore
523
+ // "rp":"0", // Realized Profit of the trade
524
+ // "V":"EXPIRE_TAKER", // STP mode
525
+ // "pm":"OPPONENT", // Price match mode
526
+ // "gtd":0 // TIF GTD order auto cancel time
527
+ // }
528
+ //
529
+ const orderType = this.safeString(message, 'o');
530
+ if (orderType !== 'LIQUIDATION') {
531
+ return;
532
+ }
533
+ const marketId = this.safeString(message, 's');
534
+ const market = this.safeMarket(marketId);
535
+ const symbol = this.safeSymbol(marketId);
536
+ const liquidation = this.parseWsLiquidation(message, market);
537
+ let myLiquidations = this.safeValue(this.myLiquidations, symbol);
538
+ if (myLiquidations === undefined) {
539
+ const limit = this.safeInteger(this.options, 'myLiquidationsLimit', 1000);
540
+ myLiquidations = new ArrayCache(limit);
541
+ }
542
+ myLiquidations.append(liquidation);
543
+ this.myLiquidations[symbol] = myLiquidations;
544
+ client.resolve([liquidation], 'myLiquidations');
545
+ client.resolve([liquidation], 'myLiquidations::' + symbol);
546
+ }
547
+ /**
548
+ * @method
549
+ * @name binance#watchOrderBook
550
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
551
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
552
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
553
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
554
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
555
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
556
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
557
+ * @param {string} symbol unified symbol of the market to fetch the order book for
558
+ * @param {int} [limit] the maximum amount of order book entries to return
559
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
560
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
561
+ */
562
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
563
+ //
564
+ // todo add support for <levels>-snapshots (depth)
565
+ // https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#partial-book-depth-streams // <symbol>@depth<levels>@100ms or <symbol>@depth<levels> (1000ms)
566
+ // valid <levels> are 5, 10, or 20
567
+ //
568
+ // default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
569
+ //
570
+ // notice the differences between trading futures and spot trading
571
+ // the algorithms use different urls in step 1
572
+ // delta caching and merging also differs in steps 4, 5, 6
573
+ //
574
+ // spot/margin
575
+ // https://binance-docs.github.io/apidocs/spot/en/#how-to-manage-a-local-order-book-correctly
576
+ //
577
+ // 1. Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth.
578
+ // 2. Buffer the events you receive from the stream.
579
+ // 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
580
+ // 4. Drop any event where u is <= lastUpdateId in the snapshot.
581
+ // 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1.
582
+ // 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
583
+ // 7. The data in each event is the absolute quantity for a price level.
584
+ // 8. If the quantity is 0, remove the price level.
585
+ // 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
586
+ //
587
+ // futures
588
+ // https://binance-docs.github.io/apidocs/futures/en/#how-to-manage-a-local-order-book-correctly
589
+ //
590
+ // 1. Open a stream to wss://fstream.binance.com/stream?streams=btcusdt@depth.
591
+ // 2. Buffer the events you receive from the stream. For same price, latest received update covers the previous one.
592
+ // 3. Get a depth snapshot from https://fapi.binance.com/fapi/v1/depth?symbol=BTCUSDT&limit=1000 .
593
+ // 4. Drop any event where u is < lastUpdateId in the snapshot.
594
+ // 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
595
+ // 6. While listening to the stream, each new event's pu should be equal to the previous event's u, otherwise initialize the process from step 3.
596
+ // 7. The data in each event is the absolute quantity for a price level.
597
+ // 8. If the quantity is 0, remove the price level.
598
+ // 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
599
+ //
600
+ return await this.watchOrderBookForSymbols([symbol], limit, params);
601
+ }
602
+ /**
603
+ * @method
604
+ * @name binance#watchOrderBookForSymbols
605
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
606
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
607
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
608
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
609
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
610
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
611
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
612
+ * @param {string[]} symbols unified array of symbols
613
+ * @param {int} [limit] the maximum amount of order book entries to return
614
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
615
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
616
+ */
617
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
618
+ await this.loadMarkets();
619
+ symbols = this.marketSymbols(symbols, undefined, false, true, true);
620
+ const firstMarket = this.market(symbols[0]);
621
+ let type = firstMarket['type'];
622
+ if (firstMarket['contract']) {
623
+ type = firstMarket['linear'] ? 'future' : 'delivery';
624
+ }
625
+ const name = 'depth';
626
+ let streamHash = 'multipleOrderbook';
627
+ if (symbols !== undefined) {
628
+ const symbolsLength = symbols.length;
629
+ if (symbolsLength > 200) {
630
+ throw new BadRequest(this.id + ' watchOrderBookForSymbols() accepts 200 symbols at most. To watch more symbols call watchOrderBookForSymbols() multiple times');
631
+ }
632
+ streamHash += '::' + symbols.join(',');
633
+ }
634
+ const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
635
+ const subParams = [];
636
+ const messageHashes = [];
637
+ for (let i = 0; i < symbols.length; i++) {
638
+ const symbol = symbols[i];
639
+ const market = this.market(symbol);
640
+ messageHashes.push('orderbook::' + symbol);
641
+ const subscriptionHash = market['lowercaseId'] + '@' + name;
642
+ const symbolHash = subscriptionHash + '@' + watchOrderBookRate + 'ms';
643
+ subParams.push(symbolHash);
644
+ }
645
+ const messageHashesLength = messageHashes.length;
646
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, messageHashesLength);
647
+ const requestId = this.requestId(url);
648
+ const request = {
649
+ 'method': 'SUBSCRIBE',
650
+ 'params': subParams,
651
+ 'id': requestId,
652
+ };
653
+ const subscription = {
654
+ 'id': requestId.toString(),
655
+ 'name': name,
656
+ 'symbols': symbols,
657
+ 'method': this.handleOrderBookSubscription,
658
+ 'limit': limit,
659
+ 'type': type,
660
+ 'params': params,
661
+ };
662
+ const orderbook = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscription);
663
+ return orderbook.limit();
664
+ }
665
+ /**
666
+ * @method
667
+ * @name binance#unWatchOrderBookForSymbols
668
+ * @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
669
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
670
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
671
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
672
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
673
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
674
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
675
+ * @param {string[]} symbols unified array of symbols
676
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
677
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
678
+ */
679
+ async unWatchOrderBookForSymbols(symbols, params = {}) {
680
+ await this.loadMarkets();
681
+ symbols = this.marketSymbols(symbols, undefined, false, true, true);
682
+ const firstMarket = this.market(symbols[0]);
683
+ let type = firstMarket['type'];
684
+ if (firstMarket['contract']) {
685
+ type = firstMarket['linear'] ? 'future' : 'delivery';
686
+ }
687
+ const name = 'depth';
688
+ let streamHash = 'multipleOrderbook';
689
+ if (symbols !== undefined) {
690
+ streamHash += '::' + symbols.join(',');
691
+ }
692
+ const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
693
+ const subParams = [];
694
+ const subMessageHashes = [];
695
+ const messageHashes = [];
696
+ for (let i = 0; i < symbols.length; i++) {
697
+ const symbol = symbols[i];
698
+ const market = this.market(symbol);
699
+ subMessageHashes.push('orderbook::' + symbol);
700
+ messageHashes.push('unsubscribe:orderbook:' + symbol);
701
+ const subscriptionHash = market['lowercaseId'] + '@' + name;
702
+ const symbolHash = subscriptionHash + '@' + watchOrderBookRate + 'ms';
703
+ subParams.push(symbolHash);
704
+ }
705
+ const messageHashesLength = subMessageHashes.length;
706
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, messageHashesLength);
707
+ const requestId = this.requestId(url);
708
+ const request = {
709
+ 'method': 'UNSUBSCRIBE',
710
+ 'params': subParams,
711
+ 'id': requestId,
712
+ };
713
+ const subscription = {
714
+ 'unsubscribe': true,
715
+ 'id': requestId.toString(),
716
+ 'symbols': symbols,
717
+ 'subMessageHashes': subMessageHashes,
718
+ 'messageHashes': messageHashes,
719
+ 'topic': 'orderbook',
720
+ };
721
+ return await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscription);
722
+ }
723
+ /**
724
+ * @method
725
+ * @name binance#unWatchOrderBook
726
+ * @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
727
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#partial-book-depth-streams
728
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#diff-depth-stream
729
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
730
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
731
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Partial-Book-Depth-Streams
732
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
733
+ * @param {string} symbol unified array of symbols
734
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
735
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
736
+ */
737
+ async unWatchOrderBook(symbol, params = {}) {
738
+ return await this.unWatchOrderBookForSymbols([symbol], params);
739
+ }
740
+ /**
741
+ * @method
742
+ * @name binance#fetchOrderBookWs
743
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
744
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#order-book
745
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api/Order-Book
746
+ * @param {string} symbol unified symbol of the market to fetch the order book for
747
+ * @param {int} [limit] the maximum amount of order book entries to return
748
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
749
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
750
+ */
751
+ async fetchOrderBookWs(symbol, limit = undefined, params = {}) {
752
+ await this.loadMarkets();
753
+ const market = this.market(symbol);
754
+ const payload = {
755
+ 'symbol': market['id'],
756
+ };
757
+ if (limit !== undefined) {
758
+ payload['limit'] = limit;
759
+ }
760
+ const marketType = this.getMarketType('fetchOrderBookWs', market, params);
761
+ if (marketType !== 'future') {
762
+ throw new BadRequest(this.id + ' fetchOrderBookWs only supports swap markets');
763
+ }
764
+ const url = this.urls['api']['ws']['ws-api'][marketType];
765
+ const requestId = this.requestId(url);
766
+ const messageHash = requestId.toString();
767
+ let returnRateLimits = false;
768
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
769
+ payload['returnRateLimits'] = returnRateLimits;
770
+ params = this.omit(params, 'test');
771
+ const message = {
772
+ 'id': messageHash,
773
+ 'method': 'depth',
774
+ 'params': this.signParams(this.extend(payload, params)),
775
+ };
776
+ const subscription = {
777
+ 'method': this.handleFetchOrderBook,
778
+ };
779
+ const orderbook = await this.watch(url, messageHash, message, messageHash, subscription);
780
+ orderbook['symbol'] = market['symbol'];
781
+ return orderbook;
782
+ }
783
+ handleFetchOrderBook(client, message) {
784
+ //
785
+ // {
786
+ // "id":"51e2affb-0aba-4821-ba75-f2625006eb43",
787
+ // "status":200,
788
+ // "result":{
789
+ // "lastUpdateId":1027024,
790
+ // "E":1589436922972,
791
+ // "T":1589436922959,
792
+ // "bids":[
793
+ // [
794
+ // "4.00000000",
795
+ // "431.00000000"
796
+ // ]
797
+ // ],
798
+ // "asks":[
799
+ // [
800
+ // "4.00000200",
801
+ // "12.00000000"
802
+ // ]
803
+ // ]
804
+ // }
805
+ // }
806
+ //
807
+ const messageHash = this.safeString(message, 'id');
808
+ const result = this.safeDict(message, 'result');
809
+ const timestamp = this.safeInteger(result, 'T');
810
+ const orderbook = this.parseOrderBook(result, undefined, timestamp);
811
+ orderbook['nonce'] = this.safeInteger2(result, 'lastUpdateId', 'u');
812
+ client.resolve(orderbook, messageHash);
813
+ }
814
+ async fetchOrderBookSnapshot(client, message, subscription) {
815
+ const symbol = this.safeString(subscription, 'symbol');
816
+ const messageHash = 'orderbook::' + symbol;
817
+ try {
818
+ const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
819
+ const type = this.safeValue(subscription, 'type');
820
+ const limit = this.safeInteger(subscription, 'limit', defaultLimit);
821
+ const params = this.safeValue(subscription, 'params');
822
+ // 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
823
+ // todo: this is a synch blocking call - make it async
824
+ // default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
825
+ const snapshot = await this.fetchRestOrderBookSafe(symbol, limit, params);
826
+ if (this.safeValue(this.orderbooks, symbol) === undefined) {
827
+ // if the orderbook is dropped before the snapshot is received
828
+ return;
829
+ }
830
+ const orderbook = this.orderbooks[symbol];
831
+ orderbook.reset(snapshot);
832
+ // unroll the accumulated deltas
833
+ const messages = orderbook.cache;
834
+ orderbook.cache = [];
835
+ for (let i = 0; i < messages.length; i++) {
836
+ const messageItem = messages[i];
837
+ const U = this.safeInteger(messageItem, 'U');
838
+ const u = this.safeInteger(messageItem, 'u');
839
+ const pu = this.safeInteger(messageItem, 'pu');
840
+ if (type === 'future') {
841
+ // 4. Drop any event where u is < lastUpdateId in the snapshot
842
+ if (u < orderbook['nonce']) {
843
+ continue;
844
+ }
845
+ // 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
846
+ if ((U <= orderbook['nonce']) && (u >= orderbook['nonce']) || (pu === orderbook['nonce'])) {
847
+ this.handleOrderBookMessage(client, messageItem, orderbook);
848
+ }
849
+ }
850
+ else {
851
+ // 4. Drop any event where u is <= lastUpdateId in the snapshot
852
+ if (u <= orderbook['nonce']) {
853
+ continue;
854
+ }
855
+ // 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
856
+ if (((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce'])) {
857
+ this.handleOrderBookMessage(client, messageItem, orderbook);
858
+ }
859
+ }
860
+ }
861
+ this.orderbooks[symbol] = orderbook;
862
+ client.resolve(orderbook, messageHash);
863
+ }
864
+ catch (e) {
865
+ delete client.subscriptions[messageHash];
866
+ client.reject(e, messageHash);
867
+ }
868
+ }
869
+ handleDelta(bookside, delta) {
870
+ const price = this.safeFloat(delta, 0);
871
+ const amount = this.safeFloat(delta, 1);
872
+ bookside.store(price, amount);
873
+ }
874
+ handleDeltas(bookside, deltas) {
875
+ for (let i = 0; i < deltas.length; i++) {
876
+ this.handleDelta(bookside, deltas[i]);
877
+ }
878
+ }
879
+ handleOrderBookMessage(client, message, orderbook) {
880
+ const u = this.safeInteger(message, 'u');
881
+ this.handleDeltas(orderbook['asks'], this.safeValue(message, 'a', []));
882
+ this.handleDeltas(orderbook['bids'], this.safeValue(message, 'b', []));
883
+ orderbook['nonce'] = u;
884
+ const timestamp = this.safeInteger(message, 'E');
885
+ orderbook['timestamp'] = timestamp;
886
+ orderbook['datetime'] = this.iso8601(timestamp);
887
+ return orderbook;
888
+ }
889
+ handleOrderBook(client, message) {
890
+ //
891
+ // initial snapshot is fetched with ccxt's fetchOrderBook
892
+ // the feed does not include a snapshot, just the deltas
893
+ //
894
+ // {
895
+ // "e": "depthUpdate", // Event type
896
+ // "E": 1577554482280, // Event time
897
+ // "s": "BNBBTC", // Symbol
898
+ // "U": 157, // First update ID in event
899
+ // "u": 160, // Final update ID in event
900
+ // "b": [ // bids
901
+ // [ "0.0024", "10" ], // price, size
902
+ // ],
903
+ // "a": [ // asks
904
+ // [ "0.0026", "100" ], // price, size
905
+ // ]
906
+ // }
907
+ //
908
+ const isSpot = (client.url.indexOf('/stream') > -1);
909
+ const marketType = (isSpot) ? 'spot' : 'contract';
910
+ const marketId = this.safeString(message, 's');
911
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
912
+ const symbol = market['symbol'];
913
+ const messageHash = 'orderbook::' + symbol;
914
+ if (!(symbol in this.orderbooks)) {
915
+ //
916
+ // https://github.com/ccxt/ccxt/issues/6672
917
+ //
918
+ // Sometimes Binance sends the first delta before the subscription
919
+ // confirmation arrives. At that point the orderbook is not
920
+ // initialized yet and the snapshot has not been requested yet
921
+ // therefore it is safe to drop these premature messages.
922
+ //
923
+ return;
924
+ }
925
+ const orderbook = this.orderbooks[symbol];
926
+ const nonce = this.safeInteger(orderbook, 'nonce');
927
+ if (nonce === undefined) {
928
+ // 2. Buffer the events you receive from the stream.
929
+ orderbook.cache.push(message);
930
+ }
931
+ else {
932
+ try {
933
+ const U = this.safeInteger(message, 'U');
934
+ const u = this.safeInteger(message, 'u');
935
+ const pu = this.safeInteger(message, 'pu');
936
+ if (pu === undefined) {
937
+ // spot
938
+ // 4. Drop any event where u is <= lastUpdateId in the snapshot
939
+ if (u > orderbook['nonce']) {
940
+ const timestamp = this.safeInteger(orderbook, 'timestamp');
941
+ let conditional = undefined;
942
+ if (timestamp === undefined) {
943
+ // 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
944
+ conditional = ((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce']);
945
+ }
946
+ else {
947
+ // 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
948
+ conditional = ((U - 1) === orderbook['nonce']);
949
+ }
950
+ if (conditional) {
951
+ this.handleOrderBookMessage(client, message, orderbook);
952
+ if (nonce < orderbook['nonce']) {
953
+ client.resolve(orderbook, messageHash);
954
+ }
955
+ }
956
+ else {
957
+ const checksum = this.handleOption('watchOrderBook', 'checksum', true);
958
+ if (checksum) {
959
+ // todo: client.reject from handleOrderBookMessage properly
960
+ throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
961
+ }
962
+ }
963
+ }
964
+ }
965
+ else {
966
+ // future
967
+ // 4. Drop any event where u is < lastUpdateId in the snapshot
968
+ if (u >= orderbook['nonce']) {
969
+ // 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
970
+ // 6. While listening to the stream, each new event's pu should be equal to the previous event's u, otherwise initialize the process from step 3
971
+ if ((U <= orderbook['nonce']) || (pu === orderbook['nonce'])) {
972
+ this.handleOrderBookMessage(client, message, orderbook);
973
+ if (nonce <= orderbook['nonce']) {
974
+ client.resolve(orderbook, messageHash);
975
+ }
976
+ }
977
+ else {
978
+ const checksum = this.handleOption('watchOrderBook', 'checksum', true);
979
+ if (checksum) {
980
+ // todo: client.reject from handleOrderBookMessage properly
981
+ throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
982
+ }
983
+ }
984
+ }
985
+ }
986
+ }
987
+ catch (e) {
988
+ delete this.orderbooks[symbol];
989
+ delete client.subscriptions[messageHash];
990
+ client.reject(e, messageHash);
991
+ }
992
+ }
993
+ }
994
+ handleOrderBookSubscription(client, message, subscription) {
995
+ const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
996
+ // const messageHash = this.safeString (subscription, 'messageHash');
997
+ const symbolOfSubscription = this.safeString(subscription, 'symbol'); // watchOrderBook
998
+ const symbols = this.safeValue(subscription, 'symbols', [symbolOfSubscription]); // watchOrderBookForSymbols
999
+ const limit = this.safeInteger(subscription, 'limit', defaultLimit);
1000
+ // handle list of symbols
1001
+ for (let i = 0; i < symbols.length; i++) {
1002
+ const symbol = symbols[i];
1003
+ if (symbol in this.orderbooks) {
1004
+ delete this.orderbooks[symbol];
1005
+ }
1006
+ this.orderbooks[symbol] = this.orderBook({}, limit);
1007
+ subscription = this.extend(subscription, { 'symbol': symbol });
1008
+ // fetch the snapshot in a separate async call
1009
+ this.spawn(this.fetchOrderBookSnapshot, client, message, subscription);
1010
+ }
1011
+ }
1012
+ handleSubscriptionStatus(client, message) {
1013
+ //
1014
+ // {
1015
+ // "result": null,
1016
+ // "id": 1574649734450
1017
+ // }
1018
+ //
1019
+ const id = this.safeString(message, 'id');
1020
+ const subscriptionsById = this.indexBy(client.subscriptions, 'id');
1021
+ const subscription = this.safeValue(subscriptionsById, id, {});
1022
+ const method = this.safeValue(subscription, 'method');
1023
+ if (method !== undefined) {
1024
+ method.call(this, client, message, subscription);
1025
+ }
1026
+ const isUnSubMessage = this.safeBool(subscription, 'unsubscribe', false);
1027
+ if (isUnSubMessage) {
1028
+ this.handleUnSubscription(client, subscription);
1029
+ }
1030
+ return message;
1031
+ }
1032
+ handleUnSubscription(client, subscription) {
1033
+ const messageHashes = this.safeList(subscription, 'messageHashes', []);
1034
+ const subMessageHashes = this.safeList(subscription, 'subMessageHashes', []);
1035
+ for (let j = 0; j < messageHashes.length; j++) {
1036
+ const unsubHash = messageHashes[j];
1037
+ const subHash = subMessageHashes[j];
1038
+ this.cleanUnsubscription(client, subHash, unsubHash);
1039
+ }
1040
+ this.cleanCache(subscription);
1041
+ }
1042
+ /**
1043
+ * @method
1044
+ * @name binance#watchTradesForSymbols
1045
+ * @description get the list of most recent trades for a list of symbols
1046
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
1047
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
1048
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1049
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1050
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
1051
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
1052
+ * @param {int} [limit] the maximum amount of trades to fetch
1053
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1054
+ * @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
1055
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1056
+ */
1057
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
1058
+ await this.loadMarkets();
1059
+ symbols = this.marketSymbols(symbols, undefined, false, true, true);
1060
+ let streamHash = 'multipleTrades';
1061
+ if (symbols !== undefined) {
1062
+ const symbolsLength = symbols.length;
1063
+ if (symbolsLength > 200) {
1064
+ throw new BadRequest(this.id + ' watchTradesForSymbols() accepts 200 symbols at most. To watch more symbols call watchTradesForSymbols() multiple times');
1065
+ }
1066
+ streamHash += '::' + symbols.join(',');
1067
+ }
1068
+ let name = undefined;
1069
+ [name, params] = this.handleOptionAndParams(params, 'watchTradesForSymbols', 'name', 'trade');
1070
+ params = this.omit(params, 'callerMethodName');
1071
+ const firstMarket = this.market(symbols[0]);
1072
+ let type = firstMarket['type'];
1073
+ if (firstMarket['contract']) {
1074
+ type = firstMarket['linear'] ? 'future' : 'delivery';
1075
+ }
1076
+ const messageHashes = [];
1077
+ const subParams = [];
1078
+ for (let i = 0; i < symbols.length; i++) {
1079
+ const symbol = symbols[i];
1080
+ const market = this.market(symbol);
1081
+ messageHashes.push('trade::' + symbol);
1082
+ const rawHash = market['lowercaseId'] + '@' + name;
1083
+ subParams.push(rawHash);
1084
+ }
1085
+ const query = this.omit(params, 'type');
1086
+ const subParamsLength = subParams.length;
1087
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, subParamsLength);
1088
+ const requestId = this.requestId(url);
1089
+ const request = {
1090
+ 'method': 'SUBSCRIBE',
1091
+ 'params': subParams,
1092
+ 'id': requestId,
1093
+ };
1094
+ const subscribe = {
1095
+ 'id': requestId,
1096
+ };
1097
+ const trades = await this.watchMultiple(url, messageHashes, this.extend(request, query), messageHashes, subscribe);
1098
+ if (this.newUpdates) {
1099
+ const first = this.safeValue(trades, 0);
1100
+ const tradeSymbol = this.safeString(first, 'symbol');
1101
+ limit = trades.getLimit(tradeSymbol, limit);
1102
+ }
1103
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
1104
+ }
1105
+ /**
1106
+ * @method
1107
+ * @name binance#unWatchTradesForSymbols
1108
+ * @description unsubscribes from the trades channel
1109
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
1110
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
1111
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1112
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1113
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
1114
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1115
+ * @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
1116
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1117
+ */
1118
+ async unWatchTradesForSymbols(symbols, params = {}) {
1119
+ await this.loadMarkets();
1120
+ symbols = this.marketSymbols(symbols, undefined, false, true, true);
1121
+ let streamHash = 'multipleTrades';
1122
+ if (symbols !== undefined) {
1123
+ const symbolsLength = symbols.length;
1124
+ if (symbolsLength > 200) {
1125
+ throw new BadRequest(this.id + ' watchTradesForSymbols() accepts 200 symbols at most. To watch more symbols call watchTradesForSymbols() multiple times');
1126
+ }
1127
+ streamHash += '::' + symbols.join(',');
1128
+ }
1129
+ let name = undefined;
1130
+ [name, params] = this.handleOptionAndParams(params, 'watchTradesForSymbols', 'name', 'trade');
1131
+ params = this.omit(params, 'callerMethodName');
1132
+ const firstMarket = this.market(symbols[0]);
1133
+ let type = firstMarket['type'];
1134
+ if (firstMarket['contract']) {
1135
+ type = firstMarket['linear'] ? 'future' : 'delivery';
1136
+ }
1137
+ const subMessageHashes = [];
1138
+ const subParams = [];
1139
+ const messageHashes = [];
1140
+ for (let i = 0; i < symbols.length; i++) {
1141
+ const symbol = symbols[i];
1142
+ const market = this.market(symbol);
1143
+ subMessageHashes.push('trade::' + symbol);
1144
+ messageHashes.push('unsubscribe:trade:' + symbol);
1145
+ const rawHash = market['lowercaseId'] + '@' + name;
1146
+ subParams.push(rawHash);
1147
+ }
1148
+ const query = this.omit(params, 'type');
1149
+ const subParamsLength = subParams.length;
1150
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, subParamsLength);
1151
+ const requestId = this.requestId(url);
1152
+ const request = {
1153
+ 'method': 'UNSUBSCRIBE',
1154
+ 'params': subParams,
1155
+ 'id': requestId,
1156
+ };
1157
+ const subscription = {
1158
+ 'unsubscribe': true,
1159
+ 'id': requestId.toString(),
1160
+ 'subMessageHashes': subMessageHashes,
1161
+ 'messageHashes': messageHashes,
1162
+ 'symbols': symbols,
1163
+ 'topic': 'trades',
1164
+ };
1165
+ return await this.watchMultiple(url, messageHashes, this.extend(request, query), messageHashes, subscription);
1166
+ }
1167
+ /**
1168
+ * @method
1169
+ * @name binance#unWatchTrades
1170
+ * @description unsubscribes from the trades channel
1171
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
1172
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
1173
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1174
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1175
+ * @param {string} symbol unified symbol of the market to fetch trades for
1176
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1177
+ * @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
1178
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1179
+ */
1180
+ async unWatchTrades(symbol, params = {}) {
1181
+ await this.loadMarkets();
1182
+ return await this.unWatchTradesForSymbols([symbol], params);
1183
+ }
1184
+ /**
1185
+ * @method
1186
+ * @name binance#watchTrades
1187
+ * @description get the list of most recent trades for a particular symbol
1188
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#aggregate-trades
1189
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
1190
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1191
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Aggregate-Trade-Streams
1192
+ * @param {string} symbol unified symbol of the market to fetch trades for
1193
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
1194
+ * @param {int} [limit] the maximum amount of trades to fetch
1195
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1196
+ * @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
1197
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1198
+ */
1199
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1200
+ params['callerMethodName'] = 'watchTrades';
1201
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
1202
+ }
1203
+ parseWsTrade(trade, market = undefined) {
1204
+ //
1205
+ // public watchTrades
1206
+ //
1207
+ // {
1208
+ // "e": "trade", // event type
1209
+ // "E": 1579481530911, // event time
1210
+ // "s": "ETHBTC", // symbol
1211
+ // "t": 158410082, // trade id
1212
+ // "p": "0.01914100", // price
1213
+ // "q": "0.00700000", // quantity
1214
+ // "b": 586187049, // buyer order id
1215
+ // "a": 586186710, // seller order id
1216
+ // "T": 1579481530910, // trade time
1217
+ // "m": false, // is the buyer the market maker
1218
+ // "M": true // binance docs say it should be ignored
1219
+ // }
1220
+ //
1221
+ // {
1222
+ // "e": "aggTrade", // Event type
1223
+ // "E": 123456789, // Event time
1224
+ // "s": "BNBBTC", // Symbol
1225
+ // "a": 12345, // Aggregate trade ID
1226
+ // "p": "0.001", // Price
1227
+ // "q": "100", // Quantity
1228
+ // "f": 100, // First trade ID
1229
+ // "l": 105, // Last trade ID
1230
+ // "T": 123456785, // Trade time
1231
+ // "m": true, // Is the buyer the market maker?
1232
+ // "M": true // Ignore
1233
+ // }
1234
+ //
1235
+ // private watchMyTrades spot
1236
+ //
1237
+ // {
1238
+ // "e": "executionReport",
1239
+ // "E": 1611063861489,
1240
+ // "s": "BNBUSDT",
1241
+ // "c": "m4M6AD5MF3b1ERe65l4SPq",
1242
+ // "S": "BUY",
1243
+ // "o": "MARKET",
1244
+ // "f": "GTC",
1245
+ // "q": "2.00000000",
1246
+ // "p": "0.00000000",
1247
+ // "P": "0.00000000",
1248
+ // "F": "0.00000000",
1249
+ // "g": -1,
1250
+ // "C": '',
1251
+ // "x": "TRADE",
1252
+ // "X": "PARTIALLY_FILLED",
1253
+ // "r": "NONE",
1254
+ // "i": 1296882607,
1255
+ // "l": "0.33200000",
1256
+ // "z": "0.33200000",
1257
+ // "L": "46.86600000",
1258
+ // "n": "0.00033200",
1259
+ // "N": "BNB",
1260
+ // "T": 1611063861488,
1261
+ // "t": 109747654,
1262
+ // "I": 2696953381,
1263
+ // "w": false,
1264
+ // "m": false,
1265
+ // "M": true,
1266
+ // "O": 1611063861488,
1267
+ // "Z": "15.55951200",
1268
+ // "Y": "15.55951200",
1269
+ // "Q": "0.00000000"
1270
+ // }
1271
+ //
1272
+ // private watchMyTrades future/delivery
1273
+ //
1274
+ // {
1275
+ // "s": "BTCUSDT",
1276
+ // "c": "pb2jD6ZQHpfzSdUac8VqMK",
1277
+ // "S": "SELL",
1278
+ // "o": "MARKET",
1279
+ // "f": "GTC",
1280
+ // "q": "0.001",
1281
+ // "p": "0",
1282
+ // "ap": "33468.46000",
1283
+ // "sp": "0",
1284
+ // "x": "TRADE",
1285
+ // "X": "FILLED",
1286
+ // "i": 13351197194,
1287
+ // "l": "0.001",
1288
+ // "z": "0.001",
1289
+ // "L": "33468.46",
1290
+ // "n": "0.00027086",
1291
+ // "N": "BNB",
1292
+ // "T": 1612095165362,
1293
+ // "t": 458032604,
1294
+ // "b": "0",
1295
+ // "a": "0",
1296
+ // "m": false,
1297
+ // "R": false,
1298
+ // "wt": "CONTRACT_PRICE",
1299
+ // "ot": "MARKET",
1300
+ // "ps": "BOTH",
1301
+ // "cp": false,
1302
+ // "rp": "0.00335000",
1303
+ // "pP": false,
1304
+ // "si": 0,
1305
+ // "ss": 0
1306
+ // }
1307
+ //
1308
+ const executionType = this.safeString(trade, 'x');
1309
+ const isTradeExecution = (executionType === 'TRADE');
1310
+ if (!isTradeExecution) {
1311
+ return this.parseTrade(trade, market);
1312
+ }
1313
+ const id = this.safeString2(trade, 't', 'a');
1314
+ const timestamp = this.safeInteger(trade, 'T');
1315
+ const price = this.safeString2(trade, 'L', 'p');
1316
+ let amount = this.safeString(trade, 'q');
1317
+ if (isTradeExecution) {
1318
+ amount = this.safeString(trade, 'l', amount);
1319
+ }
1320
+ let cost = this.safeString(trade, 'Y');
1321
+ if (cost === undefined) {
1322
+ if ((price !== undefined) && (amount !== undefined)) {
1323
+ cost = Precise.stringMul(price, amount);
1324
+ }
1325
+ }
1326
+ const marketId = this.safeString(trade, 's');
1327
+ const marketType = ('ps' in trade) ? 'contract' : 'spot';
1328
+ const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
1329
+ let side = this.safeStringLower(trade, 'S');
1330
+ let takerOrMaker = undefined;
1331
+ const orderId = this.safeString(trade, 'i');
1332
+ if ('m' in trade) {
1333
+ if (side === undefined) {
1334
+ side = trade['m'] ? 'sell' : 'buy'; // this is reversed intentionally
1335
+ }
1336
+ takerOrMaker = trade['m'] ? 'maker' : 'taker';
1337
+ }
1338
+ let fee = undefined;
1339
+ const feeCost = this.safeString(trade, 'n');
1340
+ if (feeCost !== undefined) {
1341
+ const feeCurrencyId = this.safeString(trade, 'N');
1342
+ const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
1343
+ fee = {
1344
+ 'cost': feeCost,
1345
+ 'currency': feeCurrencyCode,
1346
+ };
1347
+ }
1348
+ const type = this.safeStringLower(trade, 'o');
1349
+ return this.safeTrade({
1350
+ 'info': trade,
1351
+ 'timestamp': timestamp,
1352
+ 'datetime': this.iso8601(timestamp),
1353
+ 'symbol': symbol,
1354
+ 'id': id,
1355
+ 'order': orderId,
1356
+ 'type': type,
1357
+ 'takerOrMaker': takerOrMaker,
1358
+ 'side': side,
1359
+ 'price': price,
1360
+ 'amount': amount,
1361
+ 'cost': cost,
1362
+ 'fee': fee,
1363
+ });
1364
+ }
1365
+ handleTrade(client, message) {
1366
+ // the trade streams push raw trade information in real-time
1367
+ // each trade has a unique buyer and seller
1368
+ const isSpot = (client.url.indexOf('/stream') > -1);
1369
+ const marketType = (isSpot) ? 'spot' : 'contract';
1370
+ const marketId = this.safeString(message, 's');
1371
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
1372
+ const symbol = market['symbol'];
1373
+ const messageHash = 'trade::' + symbol;
1374
+ const trade = this.parseWsTrade(message, market);
1375
+ let tradesArray = this.safeValue(this.trades, symbol);
1376
+ if (tradesArray === undefined) {
1377
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
1378
+ tradesArray = new ArrayCache(limit);
1379
+ }
1380
+ tradesArray.append(trade);
1381
+ this.trades[symbol] = tradesArray;
1382
+ client.resolve(tradesArray, messageHash);
1383
+ }
1384
+ /**
1385
+ * @method
1386
+ * @name binance#watchOHLCV
1387
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1388
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
1389
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1390
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1391
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1392
+ * @param {string} timeframe the length of time each candle represents
1393
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
1394
+ * @param {int} [limit] the maximum amount of candles to fetch
1395
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1396
+ * @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
1397
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1398
+ */
1399
+ async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1400
+ await this.loadMarkets();
1401
+ const market = this.market(symbol);
1402
+ symbol = market['symbol'];
1403
+ params['callerMethodName'] = 'watchOHLCV';
1404
+ const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
1405
+ return result[symbol][timeframe];
1406
+ }
1407
+ /**
1408
+ * @method
1409
+ * @name binance#watchOHLCVForSymbols
1410
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1411
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
1412
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1413
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1414
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
1415
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
1416
+ * @param {int} [limit] the maximum amount of candles to fetch
1417
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1418
+ * @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
1419
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1420
+ */
1421
+ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
1422
+ await this.loadMarkets();
1423
+ let klineType = undefined;
1424
+ [klineType, params] = this.handleParamString2(params, 'channel', 'name', 'kline');
1425
+ const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
1426
+ const marketSymbols = this.marketSymbols(symbols, undefined, false, false, true);
1427
+ const firstMarket = this.market(marketSymbols[0]);
1428
+ let type = firstMarket['type'];
1429
+ if (firstMarket['contract']) {
1430
+ type = firstMarket['linear'] ? 'future' : 'delivery';
1431
+ }
1432
+ const isSpot = (type === 'spot');
1433
+ let timezone = undefined;
1434
+ [timezone, params] = this.handleParamString(params, 'timezone', undefined);
1435
+ const isUtc8 = (timezone !== undefined) && ((timezone === '+08:00') || Precise.stringEq(timezone, '8'));
1436
+ const rawHashes = [];
1437
+ const messageHashes = [];
1438
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
1439
+ const symAndTf = symbolsAndTimeframes[i];
1440
+ const symbolString = symAndTf[0];
1441
+ const timeframeString = symAndTf[1];
1442
+ const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
1443
+ const market = this.market(symbolString);
1444
+ let marketId = market['lowercaseId'];
1445
+ if (klineType === 'indexPriceKline') {
1446
+ // weird behavior for index price kline we can't use the perp suffix
1447
+ marketId = marketId.replace('_perp', '');
1448
+ }
1449
+ const shouldUseUTC8 = (isUtc8 && isSpot);
1450
+ const suffix = '@+08:00';
1451
+ const utcSuffix = shouldUseUTC8 ? suffix : '';
1452
+ rawHashes.push(marketId + '@' + klineType + '_' + interval + utcSuffix);
1453
+ messageHashes.push('ohlcv::' + market['symbol'] + '::' + timeframeString);
1454
+ }
1455
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOHLCV');
1456
+ const requestId = this.requestId(url);
1457
+ const request = {
1458
+ 'method': 'SUBSCRIBE',
1459
+ 'params': rawHashes,
1460
+ 'id': requestId,
1461
+ };
1462
+ const subscribe = {
1463
+ 'id': requestId,
1464
+ };
1465
+ params = this.omit(params, 'callerMethodName');
1466
+ const [symbol, timeframe, candles] = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscribe);
1467
+ if (this.newUpdates) {
1468
+ limit = candles.getLimit(symbol, limit);
1469
+ }
1470
+ const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
1471
+ return this.createOHLCVObject(symbol, timeframe, filtered);
1472
+ }
1473
+ /**
1474
+ * @method
1475
+ * @name binance#unWatchOHLCVForSymbols
1476
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1477
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
1478
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1479
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1480
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
1481
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1482
+ * @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
1483
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1484
+ */
1485
+ async unWatchOHLCVForSymbols(symbolsAndTimeframes, params = {}) {
1486
+ await this.loadMarkets();
1487
+ let klineType = undefined;
1488
+ [klineType, params] = this.handleParamString2(params, 'channel', 'name', 'kline');
1489
+ const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
1490
+ const marketSymbols = this.marketSymbols(symbols, undefined, false, false, true);
1491
+ const firstMarket = this.market(marketSymbols[0]);
1492
+ let type = firstMarket['type'];
1493
+ if (firstMarket['contract']) {
1494
+ type = firstMarket['linear'] ? 'future' : 'delivery';
1495
+ }
1496
+ const isSpot = (type === 'spot');
1497
+ let timezone = undefined;
1498
+ [timezone, params] = this.handleParamString(params, 'timezone', undefined);
1499
+ const isUtc8 = (timezone !== undefined) && ((timezone === '+08:00') || Precise.stringEq(timezone, '8'));
1500
+ const rawHashes = [];
1501
+ const subMessageHashes = [];
1502
+ const messageHashes = [];
1503
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
1504
+ const symAndTf = symbolsAndTimeframes[i];
1505
+ const symbolString = symAndTf[0];
1506
+ const timeframeString = symAndTf[1];
1507
+ const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
1508
+ const market = this.market(symbolString);
1509
+ let marketId = market['lowercaseId'];
1510
+ if (klineType === 'indexPriceKline') {
1511
+ // weird behavior for index price kline we can't use the perp suffix
1512
+ marketId = marketId.replace('_perp', '');
1513
+ }
1514
+ const shouldUseUTC8 = (isUtc8 && isSpot);
1515
+ const suffix = '@+08:00';
1516
+ const utcSuffix = shouldUseUTC8 ? suffix : '';
1517
+ rawHashes.push(marketId + '@' + klineType + '_' + interval + utcSuffix);
1518
+ subMessageHashes.push('ohlcv::' + market['symbol'] + '::' + timeframeString);
1519
+ messageHashes.push('unsubscribe::ohlcv::' + market['symbol'] + '::' + timeframeString);
1520
+ }
1521
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOHLCV');
1522
+ const requestId = this.requestId(url);
1523
+ const request = {
1524
+ 'method': 'UNSUBSCRIBE',
1525
+ 'params': rawHashes,
1526
+ 'id': requestId,
1527
+ };
1528
+ const subscribe = {
1529
+ 'unsubscribe': true,
1530
+ 'id': requestId.toString(),
1531
+ 'symbols': symbols,
1532
+ 'symbolsAndTimeframes': symbolsAndTimeframes,
1533
+ 'subMessageHashes': subMessageHashes,
1534
+ 'messageHashes': messageHashes,
1535
+ 'topic': 'ohlcv',
1536
+ };
1537
+ params = this.omit(params, 'callerMethodName');
1538
+ return await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscribe);
1539
+ }
1540
+ /**
1541
+ * @method
1542
+ * @name binance#unWatchOHLCV
1543
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1544
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
1545
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1546
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Kline-Candlestick-Streams
1547
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1548
+ * @param {string} timeframe the length of time each candle represents
1549
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1550
+ * @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
1551
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1552
+ */
1553
+ async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
1554
+ await this.loadMarkets();
1555
+ const market = this.market(symbol);
1556
+ symbol = market['symbol'];
1557
+ params['callerMethodName'] = 'watchOHLCV';
1558
+ return await this.unWatchOHLCVForSymbols([[symbol, timeframe]], params);
1559
+ }
1560
+ handleOHLCV(client, message) {
1561
+ //
1562
+ // {
1563
+ // "e": "kline",
1564
+ // "E": 1579482921215,
1565
+ // "s": "ETHBTC",
1566
+ // "k": {
1567
+ // "t": 1579482900000,
1568
+ // "T": 1579482959999,
1569
+ // "s": "ETHBTC",
1570
+ // "i": "1m",
1571
+ // "f": 158411535,
1572
+ // "L": 158411550,
1573
+ // "o": "0.01913200",
1574
+ // "c": "0.01913500",
1575
+ // "h": "0.01913700",
1576
+ // "l": "0.01913200",
1577
+ // "v": "5.08400000",
1578
+ // "n": 16,
1579
+ // "x": false,
1580
+ // "q": "0.09728060",
1581
+ // "V": "3.30200000",
1582
+ // "Q": "0.06318500",
1583
+ // "B": "0"
1584
+ // }
1585
+ // }
1586
+ //
1587
+ let event = this.safeString(message, 'e');
1588
+ const eventMap = {
1589
+ 'indexPrice_kline': 'indexPriceKline',
1590
+ 'markPrice_kline': 'markPriceKline',
1591
+ };
1592
+ event = this.safeString(eventMap, event, event);
1593
+ const kline = this.safeValue(message, 'k');
1594
+ let marketId = this.safeString2(kline, 's', 'ps');
1595
+ if (event === 'indexPriceKline') {
1596
+ // indexPriceKline doesn't have the _PERP suffix
1597
+ marketId = this.safeString(message, 'ps');
1598
+ }
1599
+ const interval = this.safeString(kline, 'i');
1600
+ // use a reverse lookup in a static map instead
1601
+ const unifiedTimeframe = this.findTimeframe(interval);
1602
+ const parsed = [
1603
+ this.safeInteger(kline, 't'),
1604
+ this.safeFloat(kline, 'o'),
1605
+ this.safeFloat(kline, 'h'),
1606
+ this.safeFloat(kline, 'l'),
1607
+ this.safeFloat(kline, 'c'),
1608
+ this.safeFloat(kline, 'v'),
1609
+ ];
1610
+ const isSpot = (client.url.indexOf('/stream') > -1);
1611
+ const marketType = (isSpot) ? 'spot' : 'contract';
1612
+ const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
1613
+ const messageHash = 'ohlcv::' + symbol + '::' + unifiedTimeframe;
1614
+ this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
1615
+ let stored = this.safeValue(this.ohlcvs[symbol], unifiedTimeframe);
1616
+ if (stored === undefined) {
1617
+ const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
1618
+ stored = new ArrayCacheByTimestamp(limit);
1619
+ this.ohlcvs[symbol][unifiedTimeframe] = stored;
1620
+ }
1621
+ stored.append(parsed);
1622
+ const resolveData = [symbol, unifiedTimeframe, stored];
1623
+ client.resolve(resolveData, messageHash);
1624
+ }
1625
+ /**
1626
+ * @method
1627
+ * @name binance#fetchTickerWs
1628
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1629
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1630
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1631
+ * @param {string} [params.method] method to use can be ticker.price or ticker.book
1632
+ * @param {boolean} [params.returnRateLimits] return the rate limits for the exchange
1633
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1634
+ */
1635
+ async fetchTickerWs(symbol, params = {}) {
1636
+ await this.loadMarkets();
1637
+ const market = this.market(symbol);
1638
+ const payload = {
1639
+ 'symbol': market['id'],
1640
+ };
1641
+ const type = this.getMarketType('fetchTickerWs', market, params);
1642
+ if (type !== 'future') {
1643
+ throw new BadRequest(this.id + ' fetchTickerWs only supports swap markets');
1644
+ }
1645
+ const url = this.urls['api']['ws']['ws-api'][type];
1646
+ const requestId = this.requestId(url);
1647
+ const messageHash = requestId.toString();
1648
+ const subscription = {
1649
+ 'method': this.handleTickerWs,
1650
+ };
1651
+ let returnRateLimits = false;
1652
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchTickerWs', 'returnRateLimits', false);
1653
+ payload['returnRateLimits'] = returnRateLimits;
1654
+ params = this.omit(params, 'test');
1655
+ let method = undefined;
1656
+ [method, params] = this.handleOptionAndParams(params, 'fetchTickerWs', 'method', 'ticker.book');
1657
+ const message = {
1658
+ 'id': messageHash,
1659
+ 'method': method,
1660
+ 'params': this.signParams(this.extend(payload, params)),
1661
+ };
1662
+ const ticker = await this.watch(url, messageHash, message, messageHash, subscription);
1663
+ return ticker;
1664
+ }
1665
+ /**
1666
+ * @method
1667
+ * @name binance#fetchOHLCVWs
1668
+ * @description query historical candlestick data containing the open, high, low, and close price, and the volume of a market
1669
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#klines
1670
+ * @param {string} symbol unified symbol of the market to query OHLCV data for
1671
+ * @param {string} timeframe the length of time each candle represents
1672
+ * @param {int} since timestamp in ms of the earliest candle to fetch
1673
+ * @param {int} limit the maximum amount of candles to fetch
1674
+ * @param {object} params extra parameters specific to the exchange API endpoint
1675
+ * @param {int} params.until timestamp in ms of the earliest candle to fetch
1676
+ *
1677
+ * EXCHANGE SPECIFIC PARAMETERS
1678
+ * @param {string} params.timeZone default=0 (UTC)
1679
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1680
+ */
1681
+ async fetchOHLCVWs(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1682
+ await this.loadMarkets();
1683
+ const market = this.market(symbol);
1684
+ const marketType = this.getMarketType('fetchOHLCVWs', market, params);
1685
+ if (marketType !== 'spot' && marketType !== 'future') {
1686
+ throw new BadRequest(this.id + ' fetchOHLCVWs only supports spot or swap markets');
1687
+ }
1688
+ const url = this.urls['api']['ws']['ws-api'][marketType];
1689
+ const requestId = this.requestId(url);
1690
+ const messageHash = requestId.toString();
1691
+ let returnRateLimits = false;
1692
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOHLCVWs', 'returnRateLimits', false);
1693
+ const payload = {
1694
+ 'symbol': this.marketId(symbol),
1695
+ 'returnRateLimits': returnRateLimits,
1696
+ 'interval': this.timeframes[timeframe],
1697
+ };
1698
+ const until = this.safeInteger(params, 'until');
1699
+ params = this.omit(params, 'until');
1700
+ if (since !== undefined) {
1701
+ payload['startTime'] = since;
1702
+ }
1703
+ if (limit !== undefined) {
1704
+ payload['limit'] = limit;
1705
+ }
1706
+ if (until !== undefined) {
1707
+ payload['endTime'] = until;
1708
+ }
1709
+ const message = {
1710
+ 'id': messageHash,
1711
+ 'method': 'klines',
1712
+ 'params': this.extend(payload, params),
1713
+ };
1714
+ const subscription = {
1715
+ 'method': this.handleFetchOHLCV,
1716
+ };
1717
+ return await this.watch(url, messageHash, message, messageHash, subscription);
1718
+ }
1719
+ handleFetchOHLCV(client, message) {
1720
+ //
1721
+ // {
1722
+ // "id": "1dbbeb56-8eea-466a-8f6e-86bdcfa2fc0b",
1723
+ // "status": 200,
1724
+ // "result": [
1725
+ // [
1726
+ // 1655971200000, // Kline open time
1727
+ // "0.01086000", // Open price
1728
+ // "0.01086600", // High price
1729
+ // "0.01083600", // Low price
1730
+ // "0.01083800", // Close price
1731
+ // "2290.53800000", // Volume
1732
+ // 1655974799999, // Kline close time
1733
+ // "24.85074442", // Quote asset volume
1734
+ // 2283, // Number of trades
1735
+ // "1171.64000000", // Taker buy base asset volume
1736
+ // "12.71225884", // Taker buy quote asset volume
1737
+ // "0" // Unused field, ignore
1738
+ // ]
1739
+ // ],
1740
+ // "rateLimits": [
1741
+ // {
1742
+ // "rateLimitType": "REQUEST_WEIGHT",
1743
+ // "interval": "MINUTE",
1744
+ // "intervalNum": 1,
1745
+ // "limit": 6000,
1746
+ // "count": 2
1747
+ // }
1748
+ // ]
1749
+ // }
1750
+ //
1751
+ const result = this.safeList(message, 'result');
1752
+ const parsed = this.parseOHLCVs(result);
1753
+ // use a reverse lookup in a static map instead
1754
+ const messageHash = this.safeString(message, 'id');
1755
+ client.resolve(parsed, messageHash);
1756
+ }
1757
+ /**
1758
+ * @method
1759
+ * @name binance#watchTicker
1760
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1761
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
1762
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
1763
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1764
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1765
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1766
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1767
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1768
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1769
+ * @param {string} [params.name] stream to use can be ticker or miniTicker
1770
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1771
+ */
1772
+ async watchTicker(symbol, params = {}) {
1773
+ await this.loadMarkets();
1774
+ symbol = this.symbol(symbol);
1775
+ const tickers = await this.watchTickers([symbol], this.extend(params, { 'callerMethodName': 'watchTicker' }));
1776
+ return tickers[symbol];
1777
+ }
1778
+ /**
1779
+ * @method
1780
+ * @name binance#watchMarkPrice
1781
+ * @description watches a mark price for a specific market
1782
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Mark-Price-Stream
1783
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1784
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1785
+ * @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds
1786
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1787
+ */
1788
+ async watchMarkPrice(symbol, params = {}) {
1789
+ await this.loadMarkets();
1790
+ symbol = this.symbol(symbol);
1791
+ const tickers = await this.watchMarkPrices([symbol], this.extend(params, { 'callerMethodName': 'watchMarkPrice' }));
1792
+ return tickers[symbol];
1793
+ }
1794
+ /**
1795
+ * @method
1796
+ * @name binance#watchMarkPrices
1797
+ * @description watches the mark price for all markets
1798
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Mark-Price-Stream-for-All-market
1799
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
1800
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1801
+ * @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds
1802
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1803
+ */
1804
+ async watchMarkPrices(symbols = undefined, params = {}) {
1805
+ let channelName = undefined;
1806
+ // for now watchmarkPrice uses the same messageHash as watchTicker
1807
+ // so it's impossible to watch both at the same time
1808
+ // refactor this to use different messageHashes
1809
+ [channelName, params] = this.handleOptionAndParams(params, 'watchMarkPrices', 'name', 'markPrice');
1810
+ const newTickers = await this.watchMultiTickerHelper('watchMarkPrices', channelName, symbols, params);
1811
+ if (this.newUpdates) {
1812
+ return newTickers;
1813
+ }
1814
+ return this.filterByArray(this.tickers, 'symbol', symbols);
1815
+ }
1816
+ /**
1817
+ * @method
1818
+ * @name binance#watchTickers
1819
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
1820
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
1821
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
1822
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1823
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1824
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1825
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1826
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
1827
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1828
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1829
+ */
1830
+ async watchTickers(symbols = undefined, params = {}) {
1831
+ let channelName = undefined;
1832
+ [channelName, params] = this.handleOptionAndParams(params, 'watchTickers', 'name', 'ticker');
1833
+ if (channelName === 'bookTicker') {
1834
+ throw new BadRequest(this.id + ' deprecation notice - to subscribe for bids-asks, use watch_bids_asks() method instead');
1835
+ }
1836
+ const newTickers = await this.watchMultiTickerHelper('watchTickers', channelName, symbols, params);
1837
+ if (this.newUpdates) {
1838
+ return newTickers;
1839
+ }
1840
+ return this.filterByArray(this.tickers, 'symbol', symbols);
1841
+ }
1842
+ /**
1843
+ * @method
1844
+ * @name binance#unWatchTickers
1845
+ * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
1846
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
1847
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
1848
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1849
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1850
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1851
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1852
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
1853
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1854
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1855
+ */
1856
+ async unWatchTickers(symbols = undefined, params = {}) {
1857
+ let channelName = undefined;
1858
+ [channelName, params] = this.handleOptionAndParams(params, 'watchTickers', 'name', 'ticker');
1859
+ if (channelName === 'bookTicker') {
1860
+ throw new BadRequest(this.id + ' deprecation notice - to subscribe for bids-asks, use watch_bids_asks() method instead');
1861
+ }
1862
+ await this.loadMarkets();
1863
+ const methodName = 'watchTickers';
1864
+ symbols = this.marketSymbols(symbols, undefined, true, false, true);
1865
+ let firstMarket = undefined;
1866
+ let marketType = undefined;
1867
+ const symbolsDefined = (symbols !== undefined);
1868
+ if (symbolsDefined) {
1869
+ firstMarket = this.market(symbols[0]);
1870
+ }
1871
+ [marketType, params] = this.handleMarketTypeAndParams(methodName, firstMarket, params);
1872
+ let subType = undefined;
1873
+ [subType, params] = this.handleSubTypeAndParams(methodName, firstMarket, params);
1874
+ let rawMarketType = undefined;
1875
+ if (this.isLinear(marketType, subType)) {
1876
+ rawMarketType = 'future';
1877
+ }
1878
+ else if (this.isInverse(marketType, subType)) {
1879
+ rawMarketType = 'delivery';
1880
+ }
1881
+ else if (marketType === 'spot') {
1882
+ rawMarketType = marketType;
1883
+ }
1884
+ else {
1885
+ throw new NotSupported(this.id + ' ' + methodName + '() does not support options markets');
1886
+ }
1887
+ const isBidAsk = (channelName === 'bookTicker');
1888
+ const subscriptionArgs = [];
1889
+ const subMessageHashes = [];
1890
+ const messageHashes = [];
1891
+ if (symbolsDefined) {
1892
+ for (let i = 0; i < symbols.length; i++) {
1893
+ const symbol = symbols[i];
1894
+ const market = this.market(symbol);
1895
+ subscriptionArgs.push(market['lowercaseId'] + '@' + channelName);
1896
+ subMessageHashes.push(this.getMessageHash(channelName, market['symbol'], isBidAsk));
1897
+ messageHashes.push('unsubscribe:ticker:' + symbol);
1898
+ }
1899
+ }
1900
+ else {
1901
+ if (isBidAsk) {
1902
+ if (marketType === 'spot') {
1903
+ throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires symbols for this channel for spot markets');
1904
+ }
1905
+ subscriptionArgs.push('!' + channelName);
1906
+ }
1907
+ else {
1908
+ subscriptionArgs.push('!' + channelName + '@arr');
1909
+ }
1910
+ subMessageHashes.push(this.getMessageHash(channelName, undefined, isBidAsk));
1911
+ messageHashes.push('unsubscribe:ticker');
1912
+ }
1913
+ let streamHash = channelName;
1914
+ if (symbolsDefined) {
1915
+ streamHash = channelName + '::' + symbols.join(',');
1916
+ }
1917
+ const url = this.urls['api']['ws'][rawMarketType] + '/' + this.stream(rawMarketType, streamHash);
1918
+ const requestId = this.requestId(url);
1919
+ const request = {
1920
+ 'method': 'UNSUBSCRIBE',
1921
+ 'params': subscriptionArgs,
1922
+ 'id': requestId,
1923
+ };
1924
+ const subscription = {
1925
+ 'unsubscribe': true,
1926
+ 'id': requestId.toString(),
1927
+ 'subMessageHashes': subMessageHashes,
1928
+ 'messageHashes': subMessageHashes,
1929
+ 'symbols': symbols,
1930
+ 'topic': 'ticker',
1931
+ };
1932
+ return await this.watchMultiple(url, subMessageHashes, this.extend(request, params), subMessageHashes, subscription);
1933
+ }
1934
+ /**
1935
+ * @method
1936
+ * @name binance#unWatchTicker
1937
+ * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
1938
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
1939
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#all-market-mini-tickers-stream
1940
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1941
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1942
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Market-Mini-Tickers-Stream
1943
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/Individual-Symbol-Ticker-Streams
1944
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1945
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1946
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1947
+ */
1948
+ async unWatchTicker(symbol, params = {}) {
1949
+ return await this.unWatchTickers([symbol], params);
1950
+ }
1951
+ /**
1952
+ * @method
1953
+ * @name binance#watchBidsAsks
1954
+ * @description watches best bid & ask for symbols
1955
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#symbol-order-book-ticker
1956
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/websocket-market-streams/All-Book-Tickers-Stream
1957
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/All-Book-Tickers-Stream
1958
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
1959
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1960
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1961
+ */
1962
+ async watchBidsAsks(symbols = undefined, params = {}) {
1963
+ await this.loadMarkets();
1964
+ symbols = this.marketSymbols(symbols, undefined, true, false, true);
1965
+ const result = await this.watchMultiTickerHelper('watchBidsAsks', 'bookTicker', symbols, params);
1966
+ if (this.newUpdates) {
1967
+ return result;
1968
+ }
1969
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
1970
+ }
1971
+ async watchMultiTickerHelper(methodName, channelName, symbols = undefined, params = {}) {
1972
+ await this.loadMarkets();
1973
+ symbols = this.marketSymbols(symbols, undefined, true, false, true);
1974
+ const isBidAsk = (channelName === 'bookTicker');
1975
+ const isMarkPrice = (channelName === 'markPrice');
1976
+ const use1sFreq = this.safeBool(params, 'use1sFreq', true);
1977
+ let firstMarket = undefined;
1978
+ let marketType = undefined;
1979
+ const symbolsDefined = (symbols !== undefined);
1980
+ if (symbolsDefined) {
1981
+ firstMarket = this.market(symbols[0]);
1982
+ }
1983
+ const defaultMarket = (isMarkPrice) ? 'swap' : undefined;
1984
+ [marketType, params] = this.handleMarketTypeAndParams(methodName, firstMarket, params, defaultMarket);
1985
+ let subType = undefined;
1986
+ [subType, params] = this.handleSubTypeAndParams(methodName, firstMarket, params);
1987
+ let rawMarketType = undefined;
1988
+ if (this.isLinear(marketType, subType)) {
1989
+ rawMarketType = 'future';
1990
+ }
1991
+ else if (this.isInverse(marketType, subType)) {
1992
+ rawMarketType = 'delivery';
1993
+ }
1994
+ else if (marketType === 'spot') {
1995
+ rawMarketType = marketType;
1996
+ }
1997
+ else {
1998
+ throw new NotSupported(this.id + ' ' + methodName + '() does not support options markets');
1999
+ }
2000
+ const subscriptionArgs = [];
2001
+ const messageHashes = [];
2002
+ let suffix = '';
2003
+ if (isMarkPrice) {
2004
+ suffix = (use1sFreq) ? '@1s' : '';
2005
+ }
2006
+ if (symbolsDefined) {
2007
+ for (let i = 0; i < symbols.length; i++) {
2008
+ const symbol = symbols[i];
2009
+ const market = this.market(symbol);
2010
+ subscriptionArgs.push(market['lowercaseId'] + '@' + channelName + suffix);
2011
+ messageHashes.push(this.getMessageHash(channelName, market['symbol'], isBidAsk));
2012
+ }
2013
+ }
2014
+ else {
2015
+ if (isBidAsk) {
2016
+ if (marketType === 'spot') {
2017
+ throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires symbols for this channel for spot markets');
2018
+ }
2019
+ subscriptionArgs.push('!' + channelName);
2020
+ }
2021
+ else if (isMarkPrice) {
2022
+ subscriptionArgs.push('!' + channelName + '@arr' + suffix);
2023
+ }
2024
+ else {
2025
+ subscriptionArgs.push('!' + channelName + '@arr');
2026
+ }
2027
+ messageHashes.push(this.getMessageHash(channelName, undefined, isBidAsk));
2028
+ }
2029
+ let streamHash = channelName;
2030
+ if (symbolsDefined) {
2031
+ streamHash = channelName + '::' + symbols.join(',');
2032
+ }
2033
+ const url = this.urls['api']['ws'][rawMarketType] + '/' + this.stream(rawMarketType, streamHash);
2034
+ const requestId = this.requestId(url);
2035
+ const request = {
2036
+ 'method': 'SUBSCRIBE',
2037
+ 'params': subscriptionArgs,
2038
+ 'id': requestId,
2039
+ };
2040
+ const subscribe = {
2041
+ 'id': requestId,
2042
+ };
2043
+ const result = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), subscriptionArgs, subscribe);
2044
+ // for efficiency, we have two type of returned structure here - if symbols array was provided, then individual
2045
+ // ticker dict comes in, otherwise all-tickers dict comes in
2046
+ if (!symbolsDefined) {
2047
+ return result;
2048
+ }
2049
+ else {
2050
+ const newDict = {};
2051
+ newDict[result['symbol']] = result;
2052
+ return newDict;
2053
+ }
2054
+ }
2055
+ parseWsTicker(message, marketType) {
2056
+ // markPrice
2057
+ // {
2058
+ // "e": "markPriceUpdate", // Event type
2059
+ // "E": 1562305380000, // Event time
2060
+ // "s": "BTCUSDT", // Symbol
2061
+ // "p": "11794.15000000", // Mark price
2062
+ // "i": "11784.62659091", // Index price
2063
+ // "P": "11784.25641265", // Estimated Settle Price, only useful in the last hour before the settlement starts
2064
+ // "r": "0.00038167", // Funding rate
2065
+ // "T": 1562306400000 // Next funding time
2066
+ // }
2067
+ //
2068
+ // ticker
2069
+ // {
2070
+ // "e": "24hrTicker", // event type
2071
+ // "E": 1579485598569, // event time
2072
+ // "s": "ETHBTC", // symbol
2073
+ // "p": "-0.00004000", // price change
2074
+ // "P": "-0.209", // price change percent
2075
+ // "w": "0.01920495", // weighted average price
2076
+ // "x": "0.01916500", // the price of the first trade before the 24hr rolling window
2077
+ // "c": "0.01912500", // last (closing) price
2078
+ // "Q": "0.10400000", // last quantity
2079
+ // "b": "0.01912200", // best bid
2080
+ // "B": "4.10400000", // best bid quantity
2081
+ // "a": "0.01912500", // best ask
2082
+ // "A": "0.00100000", // best ask quantity
2083
+ // "o": "0.01916500", // open price
2084
+ // "h": "0.01956500", // high price
2085
+ // "l": "0.01887700", // low price
2086
+ // "v": "173518.11900000", // base volume
2087
+ // "q": "3332.40703994", // quote volume
2088
+ // "O": 1579399197842, // open time
2089
+ // "C": 1579485597842, // close time
2090
+ // "F": 158251292, // first trade id
2091
+ // "L": 158414513, // last trade id
2092
+ // "n": 163222, // total number of trades
2093
+ // }
2094
+ //
2095
+ // miniTicker
2096
+ // {
2097
+ // "e": "24hrMiniTicker",
2098
+ // "E": 1671617114585,
2099
+ // "s": "MOBBUSD",
2100
+ // "c": "0.95900000",
2101
+ // "o": "0.91200000",
2102
+ // "h": "1.04000000",
2103
+ // "l": "0.89400000",
2104
+ // "v": "2109995.32000000",
2105
+ // "q": "2019254.05788000"
2106
+ // }
2107
+ // fetchTickerWs
2108
+ // {
2109
+ // "symbol":"BTCUSDT",
2110
+ // "price":"72606.70",
2111
+ // "time":1712526204284
2112
+ // }
2113
+ // fetchTickerWs - ticker.book
2114
+ // {
2115
+ // "lastUpdateId":1027024,
2116
+ // "symbol":"BTCUSDT",
2117
+ // "bidPrice":"4.00000000",
2118
+ // "bidQty":"431.00000000",
2119
+ // "askPrice":"4.00000200",
2120
+ // "askQty":"9.00000000",
2121
+ // "time":1589437530011,
2122
+ // }
2123
+ //
2124
+ const marketId = this.safeString2(message, 's', 'symbol');
2125
+ const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
2126
+ let event = this.safeString(message, 'e', 'bookTicker');
2127
+ if (event === '24hrTicker') {
2128
+ event = 'ticker';
2129
+ }
2130
+ if (event === 'markPriceUpdate') {
2131
+ // handle this separately because some fields clash with the ticker fields
2132
+ return this.safeTicker({
2133
+ 'symbol': symbol,
2134
+ 'timestamp': this.safeInteger(message, 'E'),
2135
+ 'datetime': this.iso8601(this.safeInteger(message, 'E')),
2136
+ 'info': message,
2137
+ 'markPrice': this.safeString(message, 'p'),
2138
+ 'indexPrice': this.safeString(message, 'i'),
2139
+ });
2140
+ }
2141
+ let timestamp = undefined;
2142
+ if (event === 'bookTicker') {
2143
+ // take the event timestamp, if available, for spot tickers it is not
2144
+ timestamp = this.safeInteger2(message, 'E', 'time');
2145
+ }
2146
+ else {
2147
+ // take the timestamp of the closing price for candlestick streams
2148
+ timestamp = this.safeIntegerN(message, ['C', 'E', 'time']);
2149
+ }
2150
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
2151
+ const last = this.safeString2(message, 'c', 'price');
2152
+ return this.safeTicker({
2153
+ 'symbol': symbol,
2154
+ 'timestamp': timestamp,
2155
+ 'datetime': this.iso8601(timestamp),
2156
+ 'high': this.safeString(message, 'h'),
2157
+ 'low': this.safeString(message, 'l'),
2158
+ 'bid': this.safeString2(message, 'b', 'bidPrice'),
2159
+ 'bidVolume': this.safeString2(message, 'B', 'bidQty'),
2160
+ 'ask': this.safeString2(message, 'a', 'askPrice'),
2161
+ 'askVolume': this.safeString2(message, 'A', 'askQty'),
2162
+ 'vwap': this.safeString(message, 'w'),
2163
+ 'open': this.safeString(message, 'o'),
2164
+ 'close': last,
2165
+ 'last': last,
2166
+ 'previousClose': this.safeString(message, 'x'),
2167
+ 'change': this.safeString(message, 'p'),
2168
+ 'percentage': this.safeString(message, 'P'),
2169
+ 'average': undefined,
2170
+ 'baseVolume': this.safeString(message, 'v'),
2171
+ 'quoteVolume': this.safeString(message, 'q'),
2172
+ 'info': message,
2173
+ }, market);
2174
+ }
2175
+ handleTickerWs(client, message) {
2176
+ //
2177
+ // ticker.price
2178
+ // {
2179
+ // "id":"1",
2180
+ // "status":200,
2181
+ // "result":{
2182
+ // "symbol":"BTCUSDT",
2183
+ // "price":"73178.50",
2184
+ // "time":1712527052374
2185
+ // }
2186
+ // }
2187
+ // ticker.book
2188
+ // {
2189
+ // "id":"9d32157c-a556-4d27-9866-66760a174b57",
2190
+ // "status":200,
2191
+ // "result":{
2192
+ // "lastUpdateId":1027024,
2193
+ // "symbol":"BTCUSDT",
2194
+ // "bidPrice":"4.00000000",
2195
+ // "bidQty":"431.00000000",
2196
+ // "askPrice":"4.00000200",
2197
+ // "askQty":"9.00000000",
2198
+ // "time":1589437530011 // Transaction time
2199
+ // }
2200
+ // }
2201
+ //
2202
+ const messageHash = this.safeString(message, 'id');
2203
+ const result = this.safeValue(message, 'result', {});
2204
+ const ticker = this.parseWsTicker(result, 'future');
2205
+ client.resolve(ticker, messageHash);
2206
+ }
2207
+ handleBidsAsks(client, message) {
2208
+ //
2209
+ // arrives one symbol dict or array of symbol dicts
2210
+ //
2211
+ // {
2212
+ // "u": 7488717758,
2213
+ // "s": "BTCUSDT",
2214
+ // "b": "28621.74000000",
2215
+ // "B": "1.43278800",
2216
+ // "a": "28621.75000000",
2217
+ // "A": "2.52500800"
2218
+ // }
2219
+ //
2220
+ this.handleTickersAndBidsAsks(client, message, 'bidasks');
2221
+ }
2222
+ handleTickers(client, message) {
2223
+ //
2224
+ // arrives one symbol dict or array of symbol dicts
2225
+ //
2226
+ // {
2227
+ // "e": "24hrTicker", // event type
2228
+ // "E": 1579485598569, // event time
2229
+ // "s": "ETHBTC", // symbol
2230
+ // "p": "-0.00004000", // price change
2231
+ // "P": "-0.209", // price change percent
2232
+ // "w": "0.01920495", // weighted average price
2233
+ // "x": "0.01916500", // the price of the first trade before the 24hr rolling window
2234
+ // "c": "0.01912500", // last (closing) price
2235
+ // "Q": "0.10400000", // last quantity
2236
+ // "b": "0.01912200", // best bid
2237
+ // "B": "4.10400000", // best bid quantity
2238
+ // "a": "0.01912500", // best ask
2239
+ // "A": "0.00100000", // best ask quantity
2240
+ // "o": "0.01916500", // open price
2241
+ // "h": "0.01956500", // high price
2242
+ // "l": "0.01887700", // low price
2243
+ // "v": "173518.11900000", // base volume
2244
+ // "q": "3332.40703994", // quote volume
2245
+ // "O": 1579399197842, // open time
2246
+ // "C": 1579485597842, // close time
2247
+ // "F": 158251292, // first trade id
2248
+ // "L": 158414513, // last trade id
2249
+ // "n": 163222, // total number of trades
2250
+ // }
2251
+ //
2252
+ this.handleTickersAndBidsAsks(client, message, 'tickers');
2253
+ }
2254
+ handleTickersAndBidsAsks(client, message, methodType) {
2255
+ const isSpot = (client.url.indexOf('/stream') > -1);
2256
+ const marketType = (isSpot) ? 'spot' : 'contract';
2257
+ const isBidAsk = (methodType === 'bidasks');
2258
+ let channelName = undefined;
2259
+ const resolvedMessageHashes = [];
2260
+ let rawTickers = [];
2261
+ const newTickers = {};
2262
+ if (Array.isArray(message)) {
2263
+ rawTickers = message;
2264
+ }
2265
+ else {
2266
+ rawTickers.push(message);
2267
+ }
2268
+ for (let i = 0; i < rawTickers.length; i++) {
2269
+ const ticker = rawTickers[i];
2270
+ let event = this.safeString(ticker, 'e');
2271
+ if (isBidAsk) {
2272
+ event = 'bookTicker'; // as noted in `handleMessage`, bookTicker doesn't have identifier, so manually set here
2273
+ }
2274
+ channelName = this.safeString(this.options['tickerChannelsMap'], event, event);
2275
+ if (channelName === undefined) {
2276
+ continue;
2277
+ }
2278
+ const parsedTicker = this.parseWsTicker(ticker, marketType);
2279
+ const symbol = parsedTicker['symbol'];
2280
+ newTickers[symbol] = parsedTicker;
2281
+ if (isBidAsk) {
2282
+ this.bidsasks[symbol] = parsedTicker;
2283
+ }
2284
+ else {
2285
+ this.tickers[symbol] = parsedTicker;
2286
+ }
2287
+ const messageHash = this.getMessageHash(channelName, symbol, isBidAsk);
2288
+ resolvedMessageHashes.push(messageHash);
2289
+ client.resolve(parsedTicker, messageHash);
2290
+ }
2291
+ // resolve batch endpoint
2292
+ const length = resolvedMessageHashes.length;
2293
+ if (length > 0) {
2294
+ const batchMessageHash = this.getMessageHash(channelName, undefined, isBidAsk);
2295
+ client.resolve(newTickers, batchMessageHash);
2296
+ }
2297
+ }
2298
+ getMessageHash(channelName, symbol, isBidAsk) {
2299
+ const prefix = isBidAsk ? 'bidask' : 'ticker';
2300
+ if (symbol !== undefined) {
2301
+ return prefix + ':' + channelName + '@' + symbol;
2302
+ }
2303
+ else {
2304
+ return prefix + 's' + ':' + channelName;
2305
+ }
2306
+ }
2307
+ signParams(params = {}) {
2308
+ this.checkRequiredCredentials();
2309
+ let extendedParams = this.extend({
2310
+ 'timestamp': this.nonce(),
2311
+ 'apiKey': this.apiKey,
2312
+ }, params);
2313
+ const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
2314
+ if (defaultRecvWindow !== undefined) {
2315
+ params['recvWindow'] = defaultRecvWindow;
2316
+ }
2317
+ const recvWindow = this.safeInteger(params, 'recvWindow');
2318
+ if (recvWindow !== undefined) {
2319
+ params['recvWindow'] = recvWindow;
2320
+ }
2321
+ extendedParams = this.keysort(extendedParams);
2322
+ const query = this.urlencode(extendedParams);
2323
+ let signature = undefined;
2324
+ if (this.secret.indexOf('PRIVATE KEY') > -1) {
2325
+ if (this.secret.length > 120) {
2326
+ signature = rsa(query, this.secret, sha256);
2327
+ }
2328
+ else {
2329
+ signature = eddsa(this.encode(query), this.secret, ed25519);
2330
+ }
2331
+ }
2332
+ else {
2333
+ signature = this.hmac(this.encode(query), this.encode(this.secret), sha256);
2334
+ }
2335
+ extendedParams['signature'] = signature;
2336
+ return extendedParams;
2337
+ }
2338
+ async authenticate(params = {}) {
2339
+ const time = this.milliseconds();
2340
+ let type = undefined;
2341
+ [type, params] = this.handleMarketTypeAndParams('authenticate', undefined, params);
2342
+ let subType = undefined;
2343
+ [subType, params] = this.handleSubTypeAndParams('authenticate', undefined, params);
2344
+ let isPortfolioMargin = undefined;
2345
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'authenticate', 'papi', 'portfolioMargin', false);
2346
+ if (this.isLinear(type, subType)) {
2347
+ type = 'future';
2348
+ }
2349
+ else if (this.isInverse(type, subType)) {
2350
+ type = 'delivery';
2351
+ }
2352
+ let marginMode = undefined;
2353
+ [marginMode, params] = this.handleMarginModeAndParams('authenticate', params);
2354
+ const isIsolatedMargin = (marginMode === 'isolated');
2355
+ const isCrossMargin = (marginMode === 'cross') || (marginMode === undefined);
2356
+ const symbol = this.safeString(params, 'symbol');
2357
+ params = this.omit(params, 'symbol');
2358
+ const options = this.safeValue(this.options, type, {});
2359
+ const lastAuthenticatedTime = this.safeInteger(options, 'lastAuthenticatedTime', 0);
2360
+ const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
2361
+ const delay = this.sum(listenKeyRefreshRate, 10000);
2362
+ if (time - lastAuthenticatedTime > delay) {
2363
+ let response = undefined;
2364
+ if (isPortfolioMargin) {
2365
+ response = await this.papiPostListenKey(params);
2366
+ params = this.extend(params, { 'portfolioMargin': true });
2367
+ }
2368
+ else if (type === 'future') {
2369
+ response = await this.fapiPrivatePostListenKey(params);
2370
+ }
2371
+ else if (type === 'delivery') {
2372
+ response = await this.dapiPrivatePostListenKey(params);
2373
+ }
2374
+ else if (type === 'margin' && isCrossMargin) {
2375
+ response = await this.sapiPostUserDataStream(params);
2376
+ }
2377
+ else if (isIsolatedMargin) {
2378
+ if (symbol === undefined) {
2379
+ throw new ArgumentsRequired(this.id + ' authenticate() requires a symbol argument for isolated margin mode');
2380
+ }
2381
+ const marketId = this.marketId(symbol);
2382
+ params = this.extend(params, { 'symbol': marketId });
2383
+ response = await this.sapiPostUserDataStreamIsolated(params);
2384
+ }
2385
+ else {
2386
+ response = await this.publicPostUserDataStream(params);
2387
+ }
2388
+ this.options[type] = this.extend(options, {
2389
+ 'listenKey': this.safeString(response, 'listenKey'),
2390
+ 'lastAuthenticatedTime': time,
2391
+ });
2392
+ this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
2393
+ }
2394
+ }
2395
+ async keepAliveListenKey(params = {}) {
2396
+ // https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot
2397
+ let type = this.safeString2(this.options, 'defaultType', 'authenticate', 'spot');
2398
+ type = this.safeString(params, 'type', type);
2399
+ let isPortfolioMargin = undefined;
2400
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'keepAliveListenKey', 'papi', 'portfolioMargin', false);
2401
+ const subTypeInfo = this.handleSubTypeAndParams('keepAliveListenKey', undefined, params);
2402
+ const subType = subTypeInfo[0];
2403
+ if (this.isLinear(type, subType)) {
2404
+ type = 'future';
2405
+ }
2406
+ else if (this.isInverse(type, subType)) {
2407
+ type = 'delivery';
2408
+ }
2409
+ const options = this.safeValue(this.options, type, {});
2410
+ const listenKey = this.safeString(options, 'listenKey');
2411
+ if (listenKey === undefined) {
2412
+ // A network error happened: we can't renew a listen key that does not exist.
2413
+ return;
2414
+ }
2415
+ const request = {};
2416
+ const symbol = this.safeString(params, 'symbol');
2417
+ params = this.omit(params, ['type', 'symbol']);
2418
+ const time = this.milliseconds();
2419
+ try {
2420
+ if (isPortfolioMargin) {
2421
+ await this.papiPutListenKey(this.extend(request, params));
2422
+ params = this.extend(params, { 'portfolioMargin': true });
2423
+ }
2424
+ else if (type === 'future') {
2425
+ await this.fapiPrivatePutListenKey(this.extend(request, params));
2426
+ }
2427
+ else if (type === 'delivery') {
2428
+ await this.dapiPrivatePutListenKey(this.extend(request, params));
2429
+ }
2430
+ else {
2431
+ request['listenKey'] = listenKey;
2432
+ if (type === 'margin') {
2433
+ request['symbol'] = symbol;
2434
+ await this.sapiPutUserDataStream(this.extend(request, params));
2435
+ }
2436
+ else {
2437
+ await this.publicPutUserDataStream(this.extend(request, params));
2438
+ }
2439
+ }
2440
+ }
2441
+ catch (error) {
2442
+ let urlType = type;
2443
+ if (isPortfolioMargin) {
2444
+ urlType = 'papi';
2445
+ }
2446
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
2447
+ const client = this.client(url);
2448
+ const messageHashes = Object.keys(client.futures);
2449
+ for (let i = 0; i < messageHashes.length; i++) {
2450
+ const messageHash = messageHashes[i];
2451
+ client.reject(error, messageHash);
2452
+ }
2453
+ this.options[type] = this.extend(options, {
2454
+ 'listenKey': undefined,
2455
+ 'lastAuthenticatedTime': 0,
2456
+ });
2457
+ return;
2458
+ }
2459
+ this.options[type] = this.extend(options, {
2460
+ 'listenKey': listenKey,
2461
+ 'lastAuthenticatedTime': time,
2462
+ });
2463
+ // whether or not to schedule another listenKey keepAlive request
2464
+ const clients = Object.values(this.clients);
2465
+ const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
2466
+ for (let i = 0; i < clients.length; i++) {
2467
+ const client = clients[i];
2468
+ const subscriptionKeys = Object.keys(client.subscriptions);
2469
+ for (let j = 0; j < subscriptionKeys.length; j++) {
2470
+ const subscribeType = subscriptionKeys[j];
2471
+ if (subscribeType === type) {
2472
+ this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
2473
+ return;
2474
+ }
2475
+ }
2476
+ }
2477
+ }
2478
+ setBalanceCache(client, type, isPortfolioMargin = false) {
2479
+ if (type in client.subscriptions) {
2480
+ return;
2481
+ }
2482
+ const options = this.safeValue(this.options, 'watchBalance');
2483
+ const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
2484
+ if (fetchBalanceSnapshot) {
2485
+ const messageHash = type + ':fetchBalanceSnapshot';
2486
+ if (!(messageHash in client.futures)) {
2487
+ client.future(messageHash);
2488
+ this.spawn(this.loadBalanceSnapshot, client, messageHash, type, isPortfolioMargin);
2489
+ }
2490
+ }
2491
+ else {
2492
+ this.balance[type] = {};
2493
+ }
2494
+ }
2495
+ async loadBalanceSnapshot(client, messageHash, type, isPortfolioMargin) {
2496
+ const params = {
2497
+ 'type': type,
2498
+ };
2499
+ if (isPortfolioMargin) {
2500
+ params['portfolioMargin'] = true;
2501
+ }
2502
+ const response = await this.fetchBalance(params);
2503
+ this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
2504
+ // don't remove the future from the .futures cache
2505
+ const future = client.futures[messageHash];
2506
+ future.resolve();
2507
+ client.resolve(this.balance[type], type + ':balance');
2508
+ }
2509
+ /**
2510
+ * @method
2511
+ * @name binance#fetchBalanceWs
2512
+ * @description fetch balance and get the amount of funds available for trading or funds locked in orders
2513
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Futures-Account-Balance
2514
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/account-requests#account-information-user_data
2515
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/account/websocket-api
2516
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2517
+ * @param {string|undefined} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot'
2518
+ * @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
2519
+ * @param {string[]|undefined} [params.symbols] unified market symbols, only used in isolated margin mode
2520
+ * @param {string|undefined} [params.method] method to use. Can be account.balance, account.status, v2/account.balance or v2/account.status
2521
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
2522
+ */
2523
+ async fetchBalanceWs(params = {}) {
2524
+ await this.loadMarkets();
2525
+ const type = this.getMarketType('fetchBalanceWs', undefined, params);
2526
+ if (type !== 'spot' && type !== 'future' && type !== 'delivery') {
2527
+ throw new BadRequest(this.id + ' fetchBalanceWs only supports spot or swap markets');
2528
+ }
2529
+ const url = this.urls['api']['ws']['ws-api'][type];
2530
+ const requestId = this.requestId(url);
2531
+ const messageHash = requestId.toString();
2532
+ let returnRateLimits = false;
2533
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchBalanceWs', 'returnRateLimits', false);
2534
+ const payload = {
2535
+ 'returnRateLimits': returnRateLimits,
2536
+ };
2537
+ let method = undefined;
2538
+ [method, params] = this.handleOptionAndParams(params, 'fetchBalanceWs', 'method', 'account.status');
2539
+ const message = {
2540
+ 'id': messageHash,
2541
+ 'method': method,
2542
+ 'params': this.signParams(this.extend(payload, params)),
2543
+ };
2544
+ const subscription = {
2545
+ 'method': (method === 'account.status') ? this.handleAccountStatusWs : this.handleBalanceWs,
2546
+ };
2547
+ return await this.watch(url, messageHash, message, messageHash, subscription);
2548
+ }
2549
+ handleBalanceWs(client, message) {
2550
+ //
2551
+ //
2552
+ const messageHash = this.safeString(message, 'id');
2553
+ let rawBalance = undefined;
2554
+ if (Array.isArray(message['result'])) {
2555
+ // account.balance
2556
+ rawBalance = this.safeList(message, 'result', []);
2557
+ }
2558
+ else {
2559
+ // account.status
2560
+ const result = this.safeDict(message, 'result', {});
2561
+ rawBalance = this.safeList(result, 'assets', []);
2562
+ }
2563
+ const parsedBalances = this.parseBalanceCustom(rawBalance);
2564
+ client.resolve(parsedBalances, messageHash);
2565
+ }
2566
+ handleAccountStatusWs(client, message) {
2567
+ //
2568
+ // spot
2569
+ // {
2570
+ // "id": "605a6d20-6588-4cb9-afa0-b0ab087507ba",
2571
+ // "status": 200,
2572
+ // "result": {
2573
+ // "makerCommission": 15,
2574
+ // "takerCommission": 15,
2575
+ // "buyerCommission": 0,
2576
+ // "sellerCommission": 0,
2577
+ // "canTrade": true,
2578
+ // "canWithdraw": true,
2579
+ // "canDeposit": true,
2580
+ // "commissionRates": {
2581
+ // "maker": "0.00150000",
2582
+ // "taker": "0.00150000",
2583
+ // "buyer": "0.00000000",
2584
+ // "seller": "0.00000000"
2585
+ // },
2586
+ // "brokered": false,
2587
+ // "requireSelfTradePrevention": false,
2588
+ // "updateTime": 1660801833000,
2589
+ // "accountType": "SPOT",
2590
+ // "balances": [{
2591
+ // "asset": "BNB",
2592
+ // "free": "0.00000000",
2593
+ // "locked": "0.00000000"
2594
+ // },
2595
+ // {
2596
+ // "asset": "BTC",
2597
+ // "free": "1.3447112",
2598
+ // "locked": "0.08600000"
2599
+ // },
2600
+ // {
2601
+ // "asset": "USDT",
2602
+ // "free": "1021.21000000",
2603
+ // "locked": "0.00000000"
2604
+ // }
2605
+ // ],
2606
+ // "permissions": [
2607
+ // "SPOT"
2608
+ // ]
2609
+ // }
2610
+ // }
2611
+ // swap
2612
+ //
2613
+ const messageHash = this.safeString(message, 'id');
2614
+ const result = this.safeDict(message, 'result', {});
2615
+ const parsedBalances = this.parseBalanceCustom(result);
2616
+ client.resolve(parsedBalances, messageHash);
2617
+ }
2618
+ /**
2619
+ * @method
2620
+ * @name binance#fetchPositionWs
2621
+ * @description fetch data on an open position
2622
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Information
2623
+ * @param {string} symbol unified market symbol of the market the position is held in
2624
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2625
+ * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2626
+ */
2627
+ async fetchPositionWs(symbol, params = {}) {
2628
+ return await this.fetchPositionsWs([symbol], params);
2629
+ }
2630
+ /**
2631
+ * @method
2632
+ * @name binance#fetchPositionsWs
2633
+ * @description fetch all open positions
2634
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Information
2635
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Position-Information
2636
+ * @param {string[]} [symbols] list of unified market symbols
2637
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2638
+ * @param {boolean} [params.returnRateLimits] set to true to return rate limit informations, defaults to false.
2639
+ * @param {string|undefined} [params.method] method to use. Can be account.position or v2/account.position
2640
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2641
+ */
2642
+ async fetchPositionsWs(symbols = undefined, params = {}) {
2643
+ await this.loadMarkets();
2644
+ const payload = {};
2645
+ let market = undefined;
2646
+ symbols = this.marketSymbols(symbols, 'swap', true, true, true);
2647
+ if (symbols !== undefined) {
2648
+ const symbolsLength = symbols.length;
2649
+ if (symbolsLength === 1) {
2650
+ market = this.market(symbols[0]);
2651
+ payload['symbol'] = market['id'];
2652
+ }
2653
+ }
2654
+ const type = this.getMarketType('fetchPositionsWs', market, params);
2655
+ if (type !== 'future' && type !== 'delivery') {
2656
+ throw new BadRequest(this.id + ' fetchPositionsWs only supports swap markets');
2657
+ }
2658
+ const url = this.urls['api']['ws']['ws-api'][type];
2659
+ const requestId = this.requestId(url);
2660
+ const messageHash = requestId.toString();
2661
+ let returnRateLimits = false;
2662
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchPositionsWs', 'returnRateLimits', false);
2663
+ payload['returnRateLimits'] = returnRateLimits;
2664
+ let method = undefined;
2665
+ [method, params] = this.handleOptionAndParams(params, 'fetchPositionsWs', 'method', 'account.position');
2666
+ const message = {
2667
+ 'id': messageHash,
2668
+ 'method': method,
2669
+ 'params': this.signParams(this.extend(payload, params)),
2670
+ };
2671
+ const subscription = {
2672
+ 'method': this.handlePositionsWs,
2673
+ };
2674
+ const result = await this.watch(url, messageHash, message, messageHash, subscription);
2675
+ return this.filterByArrayPositions(result, 'symbol', symbols, false);
2676
+ }
2677
+ handlePositionsWs(client, message) {
2678
+ //
2679
+ // {
2680
+ // id: '1',
2681
+ // status: 200,
2682
+ // result: [
2683
+ // {
2684
+ // symbol: 'BTCUSDT',
2685
+ // positionAmt: '-0.014',
2686
+ // entryPrice: '42901.1',
2687
+ // breakEvenPrice: '30138.83333142',
2688
+ // markPrice: '71055.98470333',
2689
+ // unRealizedProfit: '-394.16838584',
2690
+ // liquidationPrice: '137032.02272908',
2691
+ // leverage: '123',
2692
+ // maxNotionalValue: '50000',
2693
+ // marginType: 'cross',
2694
+ // isolatedMargin: '0.00000000',
2695
+ // isAutoAddMargin: 'false',
2696
+ // positionSide: 'BOTH',
2697
+ // notional: '-994.78378584',
2698
+ // isolatedWallet: '0',
2699
+ // updateTime: 1708906343111,
2700
+ // isolated: false,
2701
+ // adlQuantile: 2
2702
+ // },
2703
+ // ...
2704
+ // ]
2705
+ // }
2706
+ //
2707
+ //
2708
+ const messageHash = this.safeString(message, 'id');
2709
+ const result = this.safeList(message, 'result', []);
2710
+ const positions = [];
2711
+ for (let i = 0; i < result.length; i++) {
2712
+ const parsed = this.parsePositionRisk(result[i]);
2713
+ const entryPrice = this.safeString(parsed, 'entryPrice');
2714
+ if ((entryPrice !== '0') && (entryPrice !== '0.0') && (entryPrice !== '0.00000000')) {
2715
+ positions.push(parsed);
2716
+ }
2717
+ }
2718
+ client.resolve(positions, messageHash);
2719
+ }
2720
+ /**
2721
+ * @method
2722
+ * @name binance#watchBalance
2723
+ * @description watch balance and get the amount of funds available for trading or funds locked in orders
2724
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2725
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to watch the balance of a portfolio margin account
2726
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
2727
+ */
2728
+ async watchBalance(params = {}) {
2729
+ await this.loadMarkets();
2730
+ await this.authenticate(params);
2731
+ const defaultType = this.safeString(this.options, 'defaultType', 'spot');
2732
+ let type = this.safeString(params, 'type', defaultType);
2733
+ let subType = undefined;
2734
+ [subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
2735
+ let isPortfolioMargin = undefined;
2736
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchBalance', 'papi', 'portfolioMargin', false);
2737
+ if (this.isLinear(type, subType)) {
2738
+ type = 'future';
2739
+ }
2740
+ else if (this.isInverse(type, subType)) {
2741
+ type = 'delivery';
2742
+ }
2743
+ let urlType = type;
2744
+ if (isPortfolioMargin) {
2745
+ urlType = 'papi';
2746
+ }
2747
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
2748
+ const client = this.client(url);
2749
+ this.setBalanceCache(client, type, isPortfolioMargin);
2750
+ this.setPositionsCache(client, type, undefined, isPortfolioMargin);
2751
+ const options = this.safeDict(this.options, 'watchBalance');
2752
+ const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
2753
+ const awaitBalanceSnapshot = this.safeBool(options, 'awaitBalanceSnapshot', true);
2754
+ if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
2755
+ await client.future(type + ':fetchBalanceSnapshot');
2756
+ }
2757
+ const messageHash = type + ':balance';
2758
+ const message = undefined;
2759
+ return await this.watch(url, messageHash, message, type);
2760
+ }
2761
+ handleBalance(client, message) {
2762
+ //
2763
+ // sent upon a balance update not related to orders
2764
+ //
2765
+ // {
2766
+ // "e": "balanceUpdate",
2767
+ // "E": 1629352505586,
2768
+ // "a": "IOTX",
2769
+ // "d": "0.43750000",
2770
+ // "T": 1629352505585
2771
+ // }
2772
+ //
2773
+ // sent upon creating or filling an order
2774
+ //
2775
+ // {
2776
+ // "e": "outboundAccountPosition", // Event type
2777
+ // "E": 1564034571105, // Event Time
2778
+ // "u": 1564034571073, // Time of last account update
2779
+ // "B": [ // Balances Array
2780
+ // {
2781
+ // "a": "ETH", // Asset
2782
+ // "f": "10000.000000", // Free
2783
+ // "l": "0.000000" // Locked
2784
+ // }
2785
+ // ]
2786
+ // }
2787
+ //
2788
+ // future/delivery
2789
+ //
2790
+ // {
2791
+ // "e": "ACCOUNT_UPDATE", // Event Type
2792
+ // "E": 1564745798939, // Event Time
2793
+ // "T": 1564745798938 , // Transaction
2794
+ // "i": "SfsR", // Account Alias
2795
+ // "a": { // Update Data
2796
+ // "m":"ORDER", // Event reason type
2797
+ // "B":[ // Balances
2798
+ // {
2799
+ // "a":"BTC", // Asset
2800
+ // "wb":"122624.12345678", // Wallet Balance
2801
+ // "cw":"100.12345678" // Cross Wallet Balance
2802
+ // },
2803
+ // ],
2804
+ // "P":[
2805
+ // {
2806
+ // "s":"BTCUSD_200925", // Symbol
2807
+ // "pa":"0", // Position Amount
2808
+ // "ep":"0.0", // Entry Price
2809
+ // "cr":"200", // (Pre-fee) Accumulated Realized
2810
+ // "up":"0", // Unrealized PnL
2811
+ // "mt":"isolated", // Margin Type
2812
+ // "iw":"0.00000000", // Isolated Wallet (if isolated position)
2813
+ // "ps":"BOTH" // Position Side
2814
+ // },
2815
+ // ]
2816
+ // }
2817
+ // }
2818
+ //
2819
+ const wallet = this.safeString(this.options, 'wallet', 'wb'); // cw for cross wallet
2820
+ // each account is connected to a different endpoint
2821
+ // and has exactly one subscriptionhash which is the account type
2822
+ const subscriptions = Object.keys(client.subscriptions);
2823
+ const accountType = subscriptions[0];
2824
+ const messageHash = accountType + ':balance';
2825
+ if (this.balance[accountType] === undefined) {
2826
+ this.balance[accountType] = {};
2827
+ }
2828
+ this.balance[accountType]['info'] = message;
2829
+ const event = this.safeString(message, 'e');
2830
+ if (event === 'balanceUpdate') {
2831
+ const currencyId = this.safeString(message, 'a');
2832
+ const code = this.safeCurrencyCode(currencyId);
2833
+ const account = this.account();
2834
+ const delta = this.safeString(message, 'd');
2835
+ if (code in this.balance[accountType]) {
2836
+ let previousValue = this.balance[accountType][code]['free'];
2837
+ if (typeof previousValue !== 'string') {
2838
+ previousValue = this.numberToString(previousValue);
2839
+ }
2840
+ account['free'] = Precise.stringAdd(previousValue, delta);
2841
+ }
2842
+ else {
2843
+ account['free'] = delta;
2844
+ }
2845
+ this.balance[accountType][code] = account;
2846
+ }
2847
+ else {
2848
+ message = this.safeDict(message, 'a', message);
2849
+ const B = this.safeList(message, 'B');
2850
+ for (let i = 0; i < B.length; i++) {
2851
+ const entry = B[i];
2852
+ const currencyId = this.safeString(entry, 'a');
2853
+ const code = this.safeCurrencyCode(currencyId);
2854
+ const account = this.account();
2855
+ account['free'] = this.safeString(entry, 'f');
2856
+ account['used'] = this.safeString(entry, 'l');
2857
+ account['total'] = this.safeString(entry, wallet);
2858
+ this.balance[accountType][code] = account;
2859
+ }
2860
+ }
2861
+ const timestamp = this.safeInteger(message, 'E');
2862
+ this.balance[accountType]['timestamp'] = timestamp;
2863
+ this.balance[accountType]['datetime'] = this.iso8601(timestamp);
2864
+ this.balance[accountType] = this.safeBalance(this.balance[accountType]);
2865
+ client.resolve(this.balance[accountType], messageHash);
2866
+ }
2867
+ getMarketType(method, market, params = {}) {
2868
+ let type = undefined;
2869
+ [type, params] = this.handleMarketTypeAndParams(method, market, params);
2870
+ let subType = undefined;
2871
+ [subType, params] = this.handleSubTypeAndParams(method, market, params);
2872
+ if (this.isLinear(type, subType)) {
2873
+ type = 'future';
2874
+ }
2875
+ else if (this.isInverse(type, subType)) {
2876
+ type = 'delivery';
2877
+ }
2878
+ return type;
2879
+ }
2880
+ /**
2881
+ * @method
2882
+ * @name binance#createOrderWs
2883
+ * @description create a trade order
2884
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#place-new-order-trade
2885
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/New-Order
2886
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api
2887
+ * @param {string} symbol unified symbol of the market to create an order in
2888
+ * @param {string} type 'market' or 'limit'
2889
+ * @param {string} side 'buy' or 'sell'
2890
+ * @param {float} amount how much of currency you want to trade in units of base currency
2891
+ * @param {float|undefined} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
2892
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2893
+ * @param {boolean} params.test test order, default false
2894
+ * @param {boolean} params.returnRateLimits set to true to return rate limit information, default false
2895
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2896
+ */
2897
+ async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
2898
+ await this.loadMarkets();
2899
+ const market = this.market(symbol);
2900
+ const marketType = this.getMarketType('createOrderWs', market, params);
2901
+ if (marketType !== 'spot' && marketType !== 'future' && marketType !== 'delivery') {
2902
+ throw new BadRequest(this.id + ' createOrderWs only supports spot or swap markets');
2903
+ }
2904
+ const url = this.urls['api']['ws']['ws-api'][marketType];
2905
+ const requestId = this.requestId(url);
2906
+ const messageHash = requestId.toString();
2907
+ const sor = this.safeBool2(params, 'sor', 'SOR', false);
2908
+ params = this.omit(params, 'sor', 'SOR');
2909
+ const payload = this.createOrderRequest(symbol, type, side, amount, price, params);
2910
+ let returnRateLimits = false;
2911
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
2912
+ payload['returnRateLimits'] = returnRateLimits;
2913
+ const test = this.safeBool(params, 'test', false);
2914
+ params = this.omit(params, 'test');
2915
+ const message = {
2916
+ 'id': messageHash,
2917
+ 'method': 'order.place',
2918
+ 'params': this.signParams(this.extend(payload, params)),
2919
+ };
2920
+ if (test) {
2921
+ if (sor) {
2922
+ message['method'] = 'sor.order.test';
2923
+ }
2924
+ else {
2925
+ message['method'] = 'order.test';
2926
+ }
2927
+ }
2928
+ const subscription = {
2929
+ 'method': this.handleOrderWs,
2930
+ };
2931
+ return await this.watch(url, messageHash, message, messageHash, subscription);
2932
+ }
2933
+ handleOrderWs(client, message) {
2934
+ //
2935
+ // {
2936
+ // "id": 1,
2937
+ // "status": 200,
2938
+ // "result": {
2939
+ // "symbol": "BTCUSDT",
2940
+ // "orderId": 7663053,
2941
+ // "orderListId": -1,
2942
+ // "clientOrderId": "x-R4BD3S82d8959d0f5114499487a614",
2943
+ // "transactTime": 1687642291434,
2944
+ // "price": "25000.00000000",
2945
+ // "origQty": "0.00100000",
2946
+ // "executedQty": "0.00000000",
2947
+ // "cummulativeQuoteQty": "0.00000000",
2948
+ // "status": "NEW",
2949
+ // "timeInForce": "GTC",
2950
+ // "type": "LIMIT",
2951
+ // "side": "BUY",
2952
+ // "workingTime": 1687642291434,
2953
+ // "fills": [],
2954
+ // "selfTradePreventionMode": "NONE"
2955
+ // },
2956
+ // "rateLimits": [
2957
+ // {
2958
+ // "rateLimitType": "ORDERS",
2959
+ // "interval": "SECOND",
2960
+ // "intervalNum": 10,
2961
+ // "limit": 50,
2962
+ // "count": 1
2963
+ // },
2964
+ // {
2965
+ // "rateLimitType": "ORDERS",
2966
+ // "interval": "DAY",
2967
+ // "intervalNum": 1,
2968
+ // "limit": 160000,
2969
+ // "count": 1
2970
+ // },
2971
+ // {
2972
+ // "rateLimitType": "REQUEST_WEIGHT",
2973
+ // "interval": "MINUTE",
2974
+ // "intervalNum": 1,
2975
+ // "limit": 1200,
2976
+ // "count": 12
2977
+ // }
2978
+ // ]
2979
+ // }
2980
+ //
2981
+ const messageHash = this.safeString(message, 'id');
2982
+ const result = this.safeDict(message, 'result', {});
2983
+ const order = this.parseOrder(result);
2984
+ client.resolve(order, messageHash);
2985
+ }
2986
+ handleOrdersWs(client, message) {
2987
+ //
2988
+ // {
2989
+ // "id": 1,
2990
+ // "status": 200,
2991
+ // "result": [{
2992
+ // "symbol": "BTCUSDT",
2993
+ // "orderId": 7665584,
2994
+ // "orderListId": -1,
2995
+ // "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
2996
+ // "price": "26000.00000000",
2997
+ // "origQty": "0.00100000",
2998
+ // "executedQty": "0.00000000",
2999
+ // "cummulativeQuoteQty": "0.00000000",
3000
+ // "status": "NEW",
3001
+ // "timeInForce": "GTC",
3002
+ // "type": "LIMIT",
3003
+ // "side": "BUY",
3004
+ // "stopPrice": "0.00000000",
3005
+ // "icebergQty": "0.00000000",
3006
+ // "time": 1687642884646,
3007
+ // "updateTime": 1687642884646,
3008
+ // "isWorking": true,
3009
+ // "workingTime": 1687642884646,
3010
+ // "origQuoteOrderQty": "0.00000000",
3011
+ // "selfTradePreventionMode": "NONE"
3012
+ // },
3013
+ // ...
3014
+ // ],
3015
+ // "rateLimits": [{
3016
+ // "rateLimitType": "REQUEST_WEIGHT",
3017
+ // "interval": "MINUTE",
3018
+ // "intervalNum": 1,
3019
+ // "limit": 1200,
3020
+ // "count": 14
3021
+ // }]
3022
+ // }
3023
+ //
3024
+ const messageHash = this.safeString(message, 'id');
3025
+ const result = this.safeList(message, 'result', []);
3026
+ const orders = this.parseOrders(result);
3027
+ client.resolve(orders, messageHash);
3028
+ }
3029
+ /**
3030
+ * @method
3031
+ * @name binance#editOrderWs
3032
+ * @description edit a trade order
3033
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#cancel-and-replace-order-trade
3034
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Modify-Order
3035
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Modify-Order
3036
+ * @param {string} id order id
3037
+ * @param {string} symbol unified symbol of the market to create an order in
3038
+ * @param {string} type 'market' or 'limit'
3039
+ * @param {string} side 'buy' or 'sell'
3040
+ * @param {float} amount how much of the currency you want to trade in units of the base currency
3041
+ * @param {float|undefined} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
3042
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3043
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3044
+ */
3045
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
3046
+ await this.loadMarkets();
3047
+ const market = this.market(symbol);
3048
+ const marketType = this.getMarketType('editOrderWs', market, params);
3049
+ if (marketType !== 'spot' && marketType !== 'future' && marketType !== 'delivery') {
3050
+ throw new BadRequest(this.id + ' editOrderWs only supports spot or swap markets');
3051
+ }
3052
+ const url = this.urls['api']['ws']['ws-api'][marketType];
3053
+ const requestId = this.requestId(url);
3054
+ const messageHash = requestId.toString();
3055
+ const isSwap = (marketType === 'future' || marketType === 'delivery');
3056
+ let payload = undefined;
3057
+ if (marketType === 'spot') {
3058
+ payload = this.editSpotOrderRequest(id, symbol, type, side, amount, price, params);
3059
+ }
3060
+ else if (isSwap) {
3061
+ payload = this.editContractOrderRequest(id, symbol, type, side, amount, price, params);
3062
+ }
3063
+ let returnRateLimits = false;
3064
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'editOrderWs', 'returnRateLimits', false);
3065
+ payload['returnRateLimits'] = returnRateLimits;
3066
+ const message = {
3067
+ 'id': messageHash,
3068
+ 'method': (isSwap) ? 'order.modify' : 'order.cancelReplace',
3069
+ 'params': this.signParams(this.extend(payload, params)),
3070
+ };
3071
+ const subscription = {
3072
+ 'method': this.handleEditOrderWs,
3073
+ };
3074
+ return await this.watch(url, messageHash, message, messageHash, subscription);
3075
+ }
3076
+ handleEditOrderWs(client, message) {
3077
+ //
3078
+ // spot
3079
+ // {
3080
+ // "id": 1,
3081
+ // "status": 200,
3082
+ // "result": {
3083
+ // "cancelResult": "SUCCESS",
3084
+ // "newOrderResult": "SUCCESS",
3085
+ // "cancelResponse": {
3086
+ // "symbol": "BTCUSDT",
3087
+ // "origClientOrderId": "x-R4BD3S82813c5d7ffa594104917de2",
3088
+ // "orderId": 7665177,
3089
+ // "orderListId": -1,
3090
+ // "clientOrderId": "mbrnbQsQhtCXCLY45d5q7S",
3091
+ // "price": "26000.00000000",
3092
+ // "origQty": "0.00100000",
3093
+ // "executedQty": "0.00000000",
3094
+ // "cummulativeQuoteQty": "0.00000000",
3095
+ // "status": "CANCELED",
3096
+ // "timeInForce": "GTC",
3097
+ // "type": "LIMIT",
3098
+ // "side": "BUY",
3099
+ // "selfTradePreventionMode": "NONE"
3100
+ // },
3101
+ // "newOrderResponse": {
3102
+ // "symbol": "BTCUSDT",
3103
+ // "orderId": 7665584,
3104
+ // "orderListId": -1,
3105
+ // "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
3106
+ // "transactTime": 1687642884646,
3107
+ // "price": "26000.00000000",
3108
+ // "origQty": "0.00100000",
3109
+ // "executedQty": "0.00000000",
3110
+ // "cummulativeQuoteQty": "0.00000000",
3111
+ // "status": "NEW",
3112
+ // "timeInForce": "GTC",
3113
+ // "type": "LIMIT",
3114
+ // "side": "BUY",
3115
+ // "workingTime": 1687642884646,
3116
+ // "fills": [],
3117
+ // "selfTradePreventionMode": "NONE"
3118
+ // }
3119
+ // },
3120
+ // "rateLimits": [{
3121
+ // "rateLimitType": "ORDERS",
3122
+ // "interval": "SECOND",
3123
+ // "intervalNum": 10,
3124
+ // "limit": 50,
3125
+ // "count": 1
3126
+ // },
3127
+ // {
3128
+ // "rateLimitType": "ORDERS",
3129
+ // "interval": "DAY",
3130
+ // "intervalNum": 1,
3131
+ // "limit": 160000,
3132
+ // "count": 3
3133
+ // },
3134
+ // {
3135
+ // "rateLimitType": "REQUEST_WEIGHT",
3136
+ // "interval": "MINUTE",
3137
+ // "intervalNum": 1,
3138
+ // "limit": 1200,
3139
+ // "count": 12
3140
+ // }
3141
+ // ]
3142
+ // }
3143
+ // swap
3144
+ // {
3145
+ // "id":"1",
3146
+ // "status":200,
3147
+ // "result":{
3148
+ // "orderId":667061487,
3149
+ // "symbol":"LTCUSDT",
3150
+ // "status":"NEW",
3151
+ // "clientOrderId":"x-xcKtGhcu91a74c818749ee42c0f70",
3152
+ // "price":"82.00",
3153
+ // "avgPrice":"0.00",
3154
+ // "origQty":"1.000",
3155
+ // "executedQty":"0.000",
3156
+ // "cumQty":"0.000",
3157
+ // "cumQuote":"0.00000",
3158
+ // "timeInForce":"GTC",
3159
+ // "type":"LIMIT",
3160
+ // "reduceOnly":false,
3161
+ // "closePosition":false,
3162
+ // "side":"BUY",
3163
+ // "positionSide":"BOTH",
3164
+ // "stopPrice":"0.00",
3165
+ // "workingType":"CONTRACT_PRICE",
3166
+ // "priceProtect":false,
3167
+ // "origType":"LIMIT",
3168
+ // "priceMatch":"NONE",
3169
+ // "selfTradePreventionMode":"NONE",
3170
+ // "goodTillDate":0,
3171
+ // "updateTime":1712918927511
3172
+ // }
3173
+ // }
3174
+ //
3175
+ const messageHash = this.safeString(message, 'id');
3176
+ const result = this.safeDict(message, 'result', {});
3177
+ const newSpotOrder = this.safeDict(result, 'newOrderResponse');
3178
+ let order = undefined;
3179
+ if (newSpotOrder !== undefined) {
3180
+ order = this.parseOrder(newSpotOrder);
3181
+ }
3182
+ else {
3183
+ order = this.parseOrder(result);
3184
+ }
3185
+ client.resolve(order, messageHash);
3186
+ }
3187
+ /**
3188
+ * @method
3189
+ * @name binance#cancelOrderWs
3190
+ * @description cancel multiple orders
3191
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#cancel-order-trade
3192
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Cancel-Order
3193
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Cancel-Order
3194
+ * @param {string} id order id
3195
+ * @param {string} [symbol] unified market symbol, default is undefined
3196
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3197
+ * @param {string|undefined} [params.cancelRestrictions] Supported values: ONLY_NEW - Cancel will succeed if the order status is NEW. ONLY_PARTIALLY_FILLED - Cancel will succeed if order status is PARTIALLY_FILLED.
3198
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3199
+ */
3200
+ async cancelOrderWs(id, symbol = undefined, params = {}) {
3201
+ await this.loadMarkets();
3202
+ if (symbol === undefined) {
3203
+ throw new BadRequest(this.id + ' cancelOrderWs requires a symbol');
3204
+ }
3205
+ const market = this.market(symbol);
3206
+ const type = this.getMarketType('cancelOrderWs', market, params);
3207
+ const url = this.urls['api']['ws']['ws-api'][type];
3208
+ const requestId = this.requestId(url);
3209
+ const messageHash = requestId.toString();
3210
+ let returnRateLimits = false;
3211
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelOrderWs', 'returnRateLimits', false);
3212
+ const payload = {
3213
+ 'symbol': this.marketId(symbol),
3214
+ 'returnRateLimits': returnRateLimits,
3215
+ };
3216
+ const clientOrderId = this.safeString2(params, 'origClientOrderId', 'clientOrderId');
3217
+ if (clientOrderId !== undefined) {
3218
+ payload['origClientOrderId'] = clientOrderId;
3219
+ }
3220
+ else {
3221
+ payload['orderId'] = this.parseToInt(id);
3222
+ }
3223
+ params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
3224
+ const message = {
3225
+ 'id': messageHash,
3226
+ 'method': 'order.cancel',
3227
+ 'params': this.signParams(this.extend(payload, params)),
3228
+ };
3229
+ const subscription = {
3230
+ 'method': this.handleOrderWs,
3231
+ };
3232
+ return await this.watch(url, messageHash, message, messageHash, subscription);
3233
+ }
3234
+ /**
3235
+ * @method
3236
+ * @name binance#cancelAllOrdersWs
3237
+ * @description cancel all open orders in a market
3238
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#cancel-open-orders-trade
3239
+ * @param {string} [symbol] unified market symbol of the market to cancel orders in
3240
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3241
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3242
+ */
3243
+ async cancelAllOrdersWs(symbol = undefined, params = {}) {
3244
+ await this.loadMarkets();
3245
+ const market = this.market(symbol);
3246
+ const type = this.getMarketType('cancelAllOrdersWs', market, params);
3247
+ if (type !== 'spot' && type !== 'future') {
3248
+ throw new BadRequest(this.id + ' cancelAllOrdersWs only supports spot or swap markets');
3249
+ }
3250
+ const url = this.urls['api']['ws']['ws-api'][type];
3251
+ const requestId = this.requestId(url);
3252
+ const messageHash = requestId.toString();
3253
+ let returnRateLimits = false;
3254
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelAllOrdersWs', 'returnRateLimits', false);
3255
+ const payload = {
3256
+ 'symbol': this.marketId(symbol),
3257
+ 'returnRateLimits': returnRateLimits,
3258
+ };
3259
+ const message = {
3260
+ 'id': messageHash,
3261
+ 'method': 'order.cancel',
3262
+ 'params': this.signParams(this.extend(payload, params)),
3263
+ };
3264
+ const subscription = {
3265
+ 'method': this.handleOrdersWs,
3266
+ };
3267
+ return await this.watch(url, messageHash, message, messageHash, subscription);
3268
+ }
3269
+ /**
3270
+ * @method
3271
+ * @name binance#fetchOrderWs
3272
+ * @description fetches information on an order made by the user
3273
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#query-order-user_data
3274
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Query-Order
3275
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Query-Order
3276
+ * @param {string} id order id
3277
+ * @param {string} [symbol] unified symbol of the market the order was made in
3278
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3279
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3280
+ */
3281
+ async fetchOrderWs(id, symbol = undefined, params = {}) {
3282
+ await this.loadMarkets();
3283
+ if (symbol === undefined) {
3284
+ throw new BadRequest(this.id + ' cancelOrderWs requires a symbol');
3285
+ }
3286
+ const market = this.market(symbol);
3287
+ const type = this.getMarketType('fetchOrderWs', market, params);
3288
+ if (type !== 'spot' && type !== 'future' && type !== 'delivery') {
3289
+ throw new BadRequest(this.id + ' fetchOrderWs only supports spot or swap markets');
3290
+ }
3291
+ const url = this.urls['api']['ws']['ws-api'][type];
3292
+ const requestId = this.requestId(url);
3293
+ const messageHash = requestId.toString();
3294
+ let returnRateLimits = false;
3295
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
3296
+ const payload = {
3297
+ 'symbol': this.marketId(symbol),
3298
+ 'returnRateLimits': returnRateLimits,
3299
+ };
3300
+ const clientOrderId = this.safeString2(params, 'origClientOrderId', 'clientOrderId');
3301
+ if (clientOrderId !== undefined) {
3302
+ payload['origClientOrderId'] = clientOrderId;
3303
+ }
3304
+ else {
3305
+ payload['orderId'] = this.parseToInt(id);
3306
+ }
3307
+ const message = {
3308
+ 'id': messageHash,
3309
+ 'method': 'order.status',
3310
+ 'params': this.signParams(this.extend(payload, params)),
3311
+ };
3312
+ const subscription = {
3313
+ 'method': this.handleOrderWs,
3314
+ };
3315
+ return await this.watch(url, messageHash, message, messageHash, subscription);
3316
+ }
3317
+ /**
3318
+ * @method
3319
+ * @name binance#fetchOrdersWs
3320
+ * @description fetches information on multiple orders made by the user
3321
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#order-lists
3322
+ * @param {string} symbol unified market symbol of the market orders were made in
3323
+ * @param {int|undefined} [since] the earliest time in ms to fetch orders for
3324
+ * @param {int|undefined} [limit] the maximum number of order structures to retrieve
3325
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3326
+ * @param {int} [params.orderId] order id to begin at
3327
+ * @param {int} [params.startTime] earliest time in ms to retrieve orders for
3328
+ * @param {int} [params.endTime] latest time in ms to retrieve orders for
3329
+ * @param {int} [params.limit] the maximum number of order structures to retrieve
3330
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3331
+ */
3332
+ async fetchOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3333
+ await this.loadMarkets();
3334
+ if (symbol === undefined) {
3335
+ throw new BadRequest(this.id + ' fetchOrdersWs requires a symbol');
3336
+ }
3337
+ const market = this.market(symbol);
3338
+ const type = this.getMarketType('fetchOrdersWs', market, params);
3339
+ if (type !== 'spot') {
3340
+ throw new BadRequest(this.id + ' fetchOrdersWs only supports spot markets');
3341
+ }
3342
+ const url = this.urls['api']['ws']['ws-api'][type];
3343
+ const requestId = this.requestId(url);
3344
+ const messageHash = requestId.toString();
3345
+ let returnRateLimits = false;
3346
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
3347
+ const payload = {
3348
+ 'symbol': this.marketId(symbol),
3349
+ 'returnRateLimits': returnRateLimits,
3350
+ };
3351
+ const message = {
3352
+ 'id': messageHash,
3353
+ 'method': 'allOrders',
3354
+ 'params': this.signParams(this.extend(payload, params)),
3355
+ };
3356
+ const subscription = {
3357
+ 'method': this.handleOrdersWs,
3358
+ };
3359
+ const orders = await this.watch(url, messageHash, message, messageHash, subscription);
3360
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
3361
+ }
3362
+ /**
3363
+ * @method
3364
+ * @name binance#fetchClosedOrdersWs
3365
+ * @description fetch closed orders
3366
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#order-lists
3367
+ * @param {string} symbol unified market symbol
3368
+ * @param {int} [since] the earliest time in ms to fetch open orders for
3369
+ * @param {int} [limit] the maximum number of open orders structures to retrieve
3370
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3371
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3372
+ */
3373
+ async fetchClosedOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3374
+ const orders = await this.fetchOrdersWs(symbol, since, limit, params);
3375
+ const closedOrders = [];
3376
+ for (let i = 0; i < orders.length; i++) {
3377
+ const order = orders[i];
3378
+ if (order['status'] === 'closed') {
3379
+ closedOrders.push(order);
3380
+ }
3381
+ }
3382
+ return closedOrders;
3383
+ }
3384
+ /**
3385
+ * @method
3386
+ * @name binance#fetchOpenOrdersWs
3387
+ * @description fetch all unfilled currently open orders
3388
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/trading-requests#current-open-orders-user_data
3389
+ * @param {string} symbol unified market symbol
3390
+ * @param {int|undefined} [since] the earliest time in ms to fetch open orders for
3391
+ * @param {int|undefined} [limit] the maximum number of open orders structures to retrieve
3392
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3393
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3394
+ */
3395
+ async fetchOpenOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3396
+ await this.loadMarkets();
3397
+ const market = this.market(symbol);
3398
+ const type = this.getMarketType('fetchOpenOrdersWs', market, params);
3399
+ if (type !== 'spot' && type !== 'future') {
3400
+ throw new BadRequest(this.id + ' fetchOpenOrdersWs only supports spot or swap markets');
3401
+ }
3402
+ const url = this.urls['api']['ws']['ws-api'][type];
3403
+ const requestId = this.requestId(url);
3404
+ const messageHash = requestId.toString();
3405
+ let returnRateLimits = false;
3406
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
3407
+ const payload = {
3408
+ 'returnRateLimits': returnRateLimits,
3409
+ };
3410
+ if (symbol !== undefined) {
3411
+ payload['symbol'] = this.marketId(symbol);
3412
+ }
3413
+ const message = {
3414
+ 'id': messageHash,
3415
+ 'method': 'openOrders.status',
3416
+ 'params': this.signParams(this.extend(payload, params)),
3417
+ };
3418
+ const subscription = {
3419
+ 'method': this.handleOrdersWs,
3420
+ };
3421
+ const orders = await this.watch(url, messageHash, message, messageHash, subscription);
3422
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
3423
+ }
3424
+ /**
3425
+ * @method
3426
+ * @name binance#watchOrders
3427
+ * @description watches information on multiple orders made by the user
3428
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/user-data-stream#order-update
3429
+ * @see https://developers.binance.com/docs/margin_trading/trade-data-stream/Event-Order-Update
3430
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Event-Order-Update
3431
+ * @param {string} symbol unified market symbol of the market the orders were made in
3432
+ * @param {int} [since] the earliest time in ms to fetch orders for
3433
+ * @param {int} [limit] the maximum number of order structures to retrieve
3434
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3435
+ * @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for spot margin
3436
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to watch portfolio margin account orders
3437
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
3438
+ */
3439
+ async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3440
+ await this.loadMarkets();
3441
+ let messageHash = 'orders';
3442
+ let market = undefined;
3443
+ if (symbol !== undefined) {
3444
+ market = this.market(symbol);
3445
+ symbol = market['symbol'];
3446
+ messageHash += ':' + symbol;
3447
+ }
3448
+ let type = undefined;
3449
+ [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
3450
+ let subType = undefined;
3451
+ [subType, params] = this.handleSubTypeAndParams('watchOrders', market, params);
3452
+ if (this.isLinear(type, subType)) {
3453
+ type = 'future';
3454
+ }
3455
+ else if (this.isInverse(type, subType)) {
3456
+ type = 'delivery';
3457
+ }
3458
+ params = this.extend(params, { 'type': type, 'symbol': symbol }); // needed inside authenticate for isolated margin
3459
+ await this.authenticate(params);
3460
+ let marginMode = undefined;
3461
+ [marginMode, params] = this.handleMarginModeAndParams('watchOrders', params);
3462
+ let urlType = type;
3463
+ if ((type === 'margin') || ((type === 'spot') && (marginMode !== undefined))) {
3464
+ urlType = 'spot'; // spot-margin shares the same stream as regular spot
3465
+ }
3466
+ let isPortfolioMargin = undefined;
3467
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchOrders', 'papi', 'portfolioMargin', false);
3468
+ if (isPortfolioMargin) {
3469
+ urlType = 'papi';
3470
+ }
3471
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
3472
+ const client = this.client(url);
3473
+ this.setBalanceCache(client, type, isPortfolioMargin);
3474
+ this.setPositionsCache(client, type, undefined, isPortfolioMargin);
3475
+ const message = undefined;
3476
+ const orders = await this.watch(url, messageHash, message, type);
3477
+ if (this.newUpdates) {
3478
+ limit = orders.getLimit(symbol, limit);
3479
+ }
3480
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
3481
+ }
3482
+ parseWsOrder(order, market = undefined) {
3483
+ //
3484
+ // spot
3485
+ //
3486
+ // {
3487
+ // "e": "executionReport", // Event type
3488
+ // "E": 1499405658658, // Event time
3489
+ // "s": "ETHBTC", // Symbol
3490
+ // "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
3491
+ // "S": "BUY", // Side
3492
+ // "o": "LIMIT", // Order type
3493
+ // "f": "GTC", // Time in force
3494
+ // "q": "1.00000000", // Order quantity
3495
+ // "p": "0.10264410", // Order price
3496
+ // "P": "0.00000000", // Stop price
3497
+ // "F": "0.00000000", // Iceberg quantity
3498
+ // "g": -1, // OrderListId
3499
+ // "C": null, // Original client order ID; This is the ID of the order being canceled
3500
+ // "x": "NEW", // Current execution type
3501
+ // "X": "NEW", // Current order status
3502
+ // "r": "NONE", // Order reject reason; will be an error code.
3503
+ // "i": 4293153, // Order ID
3504
+ // "l": "0.00000000", // Last executed quantity
3505
+ // "z": "0.00000000", // Cumulative filled quantity
3506
+ // "L": "0.00000000", // Last executed price
3507
+ // "n": "0", // Commission amount
3508
+ // "N": null, // Commission asset
3509
+ // "T": 1499405658657, // Transaction time
3510
+ // "t": -1, // Trade ID
3511
+ // "I": 8641984, // Ignore
3512
+ // "w": true, // Is the order on the book?
3513
+ // "m": false, // Is this trade the maker side?
3514
+ // "M": false, // Ignore
3515
+ // "O": 1499405658657, // Order creation time
3516
+ // "Z": "0.00000000", // Cumulative quote asset transacted quantity
3517
+ // "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
3518
+ // "Q": "0.00000000" // Quote Order Qty
3519
+ // }
3520
+ //
3521
+ // future
3522
+ //
3523
+ // {
3524
+ // "s":"BTCUSDT", // Symbol
3525
+ // "c":"TEST", // Client Order Id
3526
+ // // special client order id:
3527
+ // // starts with "autoclose-": liquidation order
3528
+ // // "adl_autoclose": ADL auto close order
3529
+ // "S":"SELL", // Side
3530
+ // "o":"TRAILING_STOP_MARKET", // Order Type
3531
+ // "f":"GTC", // Time in Force
3532
+ // "q":"0.001", // Original Quantity
3533
+ // "p":"0", // Original Price
3534
+ // "ap":"0", // Average Price
3535
+ // "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
3536
+ // "x":"NEW", // Execution Type
3537
+ // "X":"NEW", // Order Status
3538
+ // "i":8886774, // Order Id
3539
+ // "l":"0", // Order Last Filled Quantity
3540
+ // "z":"0", // Order Filled Accumulated Quantity
3541
+ // "L":"0", // Last Filled Price
3542
+ // "N":"USDT", // Commission Asset, will not push if no commission
3543
+ // "n":"0", // Commission, will not push if no commission
3544
+ // "T":1568879465651, // Order Trade Time
3545
+ // "t":0, // Trade Id
3546
+ // "b":"0", // Bids Notional
3547
+ // "a":"9.91", // Ask Notional
3548
+ // "m":false, // Is this trade the maker side?
3549
+ // "R":false, // Is this reduce only
3550
+ // "wt":"CONTRACT_PRICE", // Stop Price Working Type
3551
+ // "ot":"TRAILING_STOP_MARKET", // Original Order Type
3552
+ // "ps":"LONG", // Position Side
3553
+ // "cp":false, // If Close-All, pushed with conditional order
3554
+ // "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
3555
+ // "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
3556
+ // "rp":"0" // Realized Profit of the trade
3557
+ // }
3558
+ //
3559
+ const executionType = this.safeString(order, 'x');
3560
+ const orderId = this.safeString(order, 'i');
3561
+ const marketId = this.safeString(order, 's');
3562
+ const marketType = ('ps' in order) ? 'contract' : 'spot';
3563
+ const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
3564
+ let timestamp = this.safeInteger(order, 'O');
3565
+ const T = this.safeInteger(order, 'T');
3566
+ let lastTradeTimestamp = undefined;
3567
+ if (executionType === 'NEW' || executionType === 'AMENDMENT' || executionType === 'CANCELED') {
3568
+ if (timestamp === undefined) {
3569
+ timestamp = T;
3570
+ }
3571
+ }
3572
+ else if (executionType === 'TRADE') {
3573
+ lastTradeTimestamp = T;
3574
+ }
3575
+ const lastUpdateTimestamp = T;
3576
+ let fee = undefined;
3577
+ const feeCost = this.safeString(order, 'n');
3578
+ if ((feeCost !== undefined) && (Precise.stringGt(feeCost, '0'))) {
3579
+ const feeCurrencyId = this.safeString(order, 'N');
3580
+ const feeCurrency = this.safeCurrencyCode(feeCurrencyId);
3581
+ fee = {
3582
+ 'cost': feeCost,
3583
+ 'currency': feeCurrency,
3584
+ };
3585
+ }
3586
+ const price = this.safeString(order, 'p');
3587
+ const amount = this.safeString(order, 'q');
3588
+ const side = this.safeStringLower(order, 'S');
3589
+ const type = this.safeStringLower(order, 'o');
3590
+ const filled = this.safeString(order, 'z');
3591
+ const cost = this.safeString(order, 'Z');
3592
+ const average = this.safeString(order, 'ap');
3593
+ const rawStatus = this.safeString(order, 'X');
3594
+ const status = this.parseOrderStatus(rawStatus);
3595
+ const trades = undefined;
3596
+ let clientOrderId = this.safeString(order, 'C');
3597
+ if ((clientOrderId === undefined) || (clientOrderId.length === 0)) {
3598
+ clientOrderId = this.safeString(order, 'c');
3599
+ }
3600
+ const stopPrice = this.safeString2(order, 'P', 'sp');
3601
+ let timeInForce = this.safeString(order, 'f');
3602
+ if (timeInForce === 'GTX') {
3603
+ // GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
3604
+ timeInForce = 'PO';
3605
+ }
3606
+ return this.safeOrder({
3607
+ 'info': order,
3608
+ 'symbol': symbol,
3609
+ 'id': orderId,
3610
+ 'clientOrderId': clientOrderId,
3611
+ 'timestamp': timestamp,
3612
+ 'datetime': this.iso8601(timestamp),
3613
+ 'lastTradeTimestamp': lastTradeTimestamp,
3614
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
3615
+ 'type': type,
3616
+ 'timeInForce': timeInForce,
3617
+ 'postOnly': undefined,
3618
+ 'reduceOnly': this.safeBool(order, 'R'),
3619
+ 'side': side,
3620
+ 'price': price,
3621
+ 'stopPrice': stopPrice,
3622
+ 'triggerPrice': stopPrice,
3623
+ 'amount': amount,
3624
+ 'cost': cost,
3625
+ 'average': average,
3626
+ 'filled': filled,
3627
+ 'remaining': undefined,
3628
+ 'status': status,
3629
+ 'fee': fee,
3630
+ 'trades': trades,
3631
+ });
3632
+ }
3633
+ handleOrderUpdate(client, message) {
3634
+ //
3635
+ // spot
3636
+ //
3637
+ // {
3638
+ // "e": "executionReport", // Event type
3639
+ // "E": 1499405658658, // Event time
3640
+ // "s": "ETHBTC", // Symbol
3641
+ // "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
3642
+ // "S": "BUY", // Side
3643
+ // "o": "LIMIT", // Order type
3644
+ // "f": "GTC", // Time in force
3645
+ // "q": "1.00000000", // Order quantity
3646
+ // "p": "0.10264410", // Order price
3647
+ // "P": "0.00000000", // Stop price
3648
+ // "F": "0.00000000", // Iceberg quantity
3649
+ // "g": -1, // OrderListId
3650
+ // "C": null, // Original client order ID; This is the ID of the order being canceled
3651
+ // "x": "NEW", // Current execution type
3652
+ // "X": "NEW", // Current order status
3653
+ // "r": "NONE", // Order reject reason; will be an error code.
3654
+ // "i": 4293153, // Order ID
3655
+ // "l": "0.00000000", // Last executed quantity
3656
+ // "z": "0.00000000", // Cumulative filled quantity
3657
+ // "L": "0.00000000", // Last executed price
3658
+ // "n": "0", // Commission amount
3659
+ // "N": null, // Commission asset
3660
+ // "T": 1499405658657, // Transaction time
3661
+ // "t": -1, // Trade ID
3662
+ // "I": 8641984, // Ignore
3663
+ // "w": true, // Is the order on the book?
3664
+ // "m": false, // Is this trade the maker side?
3665
+ // "M": false, // Ignore
3666
+ // "O": 1499405658657, // Order creation time
3667
+ // "Z": "0.00000000", // Cumulative quote asset transacted quantity
3668
+ // "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
3669
+ // "Q": "0.00000000" // Quote Order Qty
3670
+ // }
3671
+ //
3672
+ // future
3673
+ //
3674
+ // {
3675
+ // "e":"ORDER_TRADE_UPDATE", // Event Type
3676
+ // "E":1568879465651, // Event Time
3677
+ // "T":1568879465650, // Trasaction Time
3678
+ // "o": {
3679
+ // "s":"BTCUSDT", // Symbol
3680
+ // "c":"TEST", // Client Order Id
3681
+ // // special client order id:
3682
+ // // starts with "autoclose-": liquidation order
3683
+ // // "adl_autoclose": ADL auto close order
3684
+ // "S":"SELL", // Side
3685
+ // "o":"TRAILING_STOP_MARKET", // Order Type
3686
+ // "f":"GTC", // Time in Force
3687
+ // "q":"0.001", // Original Quantity
3688
+ // "p":"0", // Original Price
3689
+ // "ap":"0", // Average Price
3690
+ // "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
3691
+ // "x":"NEW", // Execution Type
3692
+ // "X":"NEW", // Order Status
3693
+ // "i":8886774, // Order Id
3694
+ // "l":"0", // Order Last Filled Quantity
3695
+ // "z":"0", // Order Filled Accumulated Quantity
3696
+ // "L":"0", // Last Filled Price
3697
+ // "N":"USDT", // Commission Asset, will not push if no commission
3698
+ // "n":"0", // Commission, will not push if no commission
3699
+ // "T":1568879465651, // Order Trade Time
3700
+ // "t":0, // Trade Id
3701
+ // "b":"0", // Bids Notional
3702
+ // "a":"9.91", // Ask Notional
3703
+ // "m":false, // Is this trade the maker side?
3704
+ // "R":false, // Is this reduce only
3705
+ // "wt":"CONTRACT_PRICE", // Stop Price Working Type
3706
+ // "ot":"TRAILING_STOP_MARKET", // Original Order Type
3707
+ // "ps":"LONG", // Position Side
3708
+ // "cp":false, // If Close-All, pushed with conditional order
3709
+ // "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
3710
+ // "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
3711
+ // "rp":"0" // Realized Profit of the trade
3712
+ // }
3713
+ // }
3714
+ //
3715
+ const e = this.safeString(message, 'e');
3716
+ if (e === 'ORDER_TRADE_UPDATE') {
3717
+ message = this.safeDict(message, 'o', message);
3718
+ }
3719
+ this.handleMyTrade(client, message);
3720
+ this.handleOrder(client, message);
3721
+ this.handleMyLiquidation(client, message);
3722
+ }
3723
+ /**
3724
+ * @method
3725
+ * @name binance#watchPositions
3726
+ * @description watch all open positions
3727
+ * @param {string[]|undefined} symbols list of unified market symbols
3728
+ * @param {number} [since] since timestamp
3729
+ * @param {number} [limit] limit
3730
+ * @param {object} params extra parameters specific to the exchange API endpoint
3731
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to watch positions in a portfolio margin account
3732
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
3733
+ */
3734
+ async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
3735
+ await this.loadMarkets();
3736
+ let market = undefined;
3737
+ let messageHash = '';
3738
+ symbols = this.marketSymbols(symbols);
3739
+ if (!this.isEmpty(symbols)) {
3740
+ market = this.getMarketFromSymbols(symbols);
3741
+ messageHash = '::' + symbols.join(',');
3742
+ }
3743
+ let type = undefined;
3744
+ [type, params] = this.handleMarketTypeAndParams('watchPositions', market, params);
3745
+ if (type === 'spot' || type === 'margin') {
3746
+ type = 'future';
3747
+ }
3748
+ let subType = undefined;
3749
+ [subType, params] = this.handleSubTypeAndParams('watchPositions', market, params);
3750
+ if (this.isLinear(type, subType)) {
3751
+ type = 'future';
3752
+ }
3753
+ else if (this.isInverse(type, subType)) {
3754
+ type = 'delivery';
3755
+ }
3756
+ const marketTypeObject = {};
3757
+ marketTypeObject['type'] = type;
3758
+ marketTypeObject['subType'] = subType;
3759
+ await this.authenticate(this.extend(marketTypeObject, params));
3760
+ messageHash = type + ':positions' + messageHash;
3761
+ let isPortfolioMargin = undefined;
3762
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchPositions', 'papi', 'portfolioMargin', false);
3763
+ let urlType = type;
3764
+ if (isPortfolioMargin) {
3765
+ urlType = 'papi';
3766
+ }
3767
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
3768
+ const client = this.client(url);
3769
+ this.setBalanceCache(client, type, isPortfolioMargin);
3770
+ this.setPositionsCache(client, type, symbols, isPortfolioMargin);
3771
+ const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
3772
+ const awaitPositionsSnapshot = this.handleOption('watchPositions', 'awaitPositionsSnapshot', true);
3773
+ const cache = this.safeValue(this.positions, type);
3774
+ if (fetchPositionsSnapshot && awaitPositionsSnapshot && cache === undefined) {
3775
+ const snapshot = await client.future(type + ':fetchPositionsSnapshot');
3776
+ return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
3777
+ }
3778
+ const newPositions = await this.watch(url, messageHash, undefined, type);
3779
+ if (this.newUpdates) {
3780
+ return newPositions;
3781
+ }
3782
+ return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
3783
+ }
3784
+ setPositionsCache(client, type, symbols = undefined, isPortfolioMargin = false) {
3785
+ if (type === 'spot') {
3786
+ return;
3787
+ }
3788
+ if (this.positions === undefined) {
3789
+ this.positions = {};
3790
+ }
3791
+ if (type in this.positions) {
3792
+ return;
3793
+ }
3794
+ const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', false);
3795
+ if (fetchPositionsSnapshot) {
3796
+ const messageHash = type + ':fetchPositionsSnapshot';
3797
+ if (!(messageHash in client.futures)) {
3798
+ client.future(messageHash);
3799
+ this.spawn(this.loadPositionsSnapshot, client, messageHash, type, isPortfolioMargin);
3800
+ }
3801
+ }
3802
+ else {
3803
+ this.positions[type] = new ArrayCacheBySymbolBySide();
3804
+ }
3805
+ }
3806
+ async loadPositionsSnapshot(client, messageHash, type, isPortfolioMargin) {
3807
+ const params = {
3808
+ 'type': type,
3809
+ };
3810
+ if (isPortfolioMargin) {
3811
+ params['portfolioMargin'] = true;
3812
+ }
3813
+ const positions = await this.fetchPositions(undefined, params);
3814
+ this.positions[type] = new ArrayCacheBySymbolBySide();
3815
+ const cache = this.positions[type];
3816
+ for (let i = 0; i < positions.length; i++) {
3817
+ const position = positions[i];
3818
+ const contracts = this.safeNumber(position, 'contracts', 0);
3819
+ if (contracts > 0) {
3820
+ cache.append(position);
3821
+ }
3822
+ }
3823
+ // don't remove the future from the .futures cache
3824
+ const future = client.futures[messageHash];
3825
+ future.resolve(cache);
3826
+ client.resolve(cache, type + ':position');
3827
+ }
3828
+ handlePositions(client, message) {
3829
+ //
3830
+ // {
3831
+ // e: 'ACCOUNT_UPDATE',
3832
+ // T: 1667881353112,
3833
+ // E: 1667881353115,
3834
+ // a: {
3835
+ // B: [{
3836
+ // a: 'USDT',
3837
+ // wb: '1127.95750089',
3838
+ // cw: '1040.82091149',
3839
+ // bc: '0'
3840
+ // }],
3841
+ // P: [{
3842
+ // s: 'BTCUSDT',
3843
+ // pa: '-0.089',
3844
+ // ep: '19700.03933',
3845
+ // cr: '-1260.24809979',
3846
+ // up: '1.53058860',
3847
+ // mt: 'isolated',
3848
+ // iw: '87.13658940',
3849
+ // ps: 'BOTH',
3850
+ // ma: 'USDT'
3851
+ // }],
3852
+ // m: 'ORDER'
3853
+ // }
3854
+ // }
3855
+ //
3856
+ // each account is connected to a different endpoint
3857
+ // and has exactly one subscriptionhash which is the account type
3858
+ const subscriptions = Object.keys(client.subscriptions);
3859
+ const accountType = subscriptions[0];
3860
+ if (this.positions === undefined) {
3861
+ this.positions = {};
3862
+ }
3863
+ if (!(accountType in this.positions)) {
3864
+ this.positions[accountType] = new ArrayCacheBySymbolBySide();
3865
+ }
3866
+ const cache = this.positions[accountType];
3867
+ const data = this.safeDict(message, 'a', {});
3868
+ const rawPositions = this.safeList(data, 'P', []);
3869
+ const newPositions = [];
3870
+ for (let i = 0; i < rawPositions.length; i++) {
3871
+ const rawPosition = rawPositions[i];
3872
+ const position = this.parseWsPosition(rawPosition);
3873
+ const timestamp = this.safeInteger(message, 'E');
3874
+ position['timestamp'] = timestamp;
3875
+ position['datetime'] = this.iso8601(timestamp);
3876
+ newPositions.push(position);
3877
+ cache.append(position);
3878
+ }
3879
+ const messageHashes = this.findMessageHashes(client, accountType + ':positions::');
3880
+ for (let i = 0; i < messageHashes.length; i++) {
3881
+ const messageHash = messageHashes[i];
3882
+ const parts = messageHash.split('::');
3883
+ const symbolsString = parts[1];
3884
+ const symbols = symbolsString.split(',');
3885
+ const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
3886
+ if (!this.isEmpty(positions)) {
3887
+ client.resolve(positions, messageHash);
3888
+ }
3889
+ }
3890
+ client.resolve(newPositions, accountType + ':positions');
3891
+ }
3892
+ parseWsPosition(position, market = undefined) {
3893
+ //
3894
+ // {
3895
+ // "s": "BTCUSDT", // Symbol
3896
+ // "pa": "0", // Position Amount
3897
+ // "ep": "0.00000", // Entry Price
3898
+ // "cr": "200", // (Pre-fee) Accumulated Realized
3899
+ // "up": "0", // Unrealized PnL
3900
+ // "mt": "isolated", // Margin Type
3901
+ // "iw": "0.00000000", // Isolated Wallet (if isolated position)
3902
+ // "ps": "BOTH" // Position Side
3903
+ // }
3904
+ //
3905
+ const marketId = this.safeString(position, 's');
3906
+ const contracts = this.safeString(position, 'pa');
3907
+ const contractsAbs = Precise.stringAbs(this.safeString(position, 'pa'));
3908
+ let positionSide = this.safeStringLower(position, 'ps');
3909
+ let hedged = true;
3910
+ if (positionSide === 'both') {
3911
+ hedged = false;
3912
+ if (!Precise.stringEq(contracts, '0')) {
3913
+ if (Precise.stringLt(contracts, '0')) {
3914
+ positionSide = 'short';
3915
+ }
3916
+ else {
3917
+ positionSide = 'long';
3918
+ }
3919
+ }
3920
+ }
3921
+ return this.safePosition({
3922
+ 'info': position,
3923
+ 'id': undefined,
3924
+ 'symbol': this.safeSymbol(marketId, undefined, undefined, 'contract'),
3925
+ 'notional': undefined,
3926
+ 'marginMode': this.safeString(position, 'mt'),
3927
+ 'liquidationPrice': undefined,
3928
+ 'entryPrice': this.safeNumber(position, 'ep'),
3929
+ 'unrealizedPnl': this.safeNumber(position, 'up'),
3930
+ 'percentage': undefined,
3931
+ 'contracts': this.parseNumber(contractsAbs),
3932
+ 'contractSize': undefined,
3933
+ 'markPrice': undefined,
3934
+ 'side': positionSide,
3935
+ 'hedged': hedged,
3936
+ 'timestamp': undefined,
3937
+ 'datetime': undefined,
3938
+ 'maintenanceMargin': undefined,
3939
+ 'maintenanceMarginPercentage': undefined,
3940
+ 'collateral': undefined,
3941
+ 'initialMargin': undefined,
3942
+ 'initialMarginPercentage': undefined,
3943
+ 'leverage': undefined,
3944
+ 'marginRatio': undefined,
3945
+ });
3946
+ }
3947
+ /**
3948
+ * @method
3949
+ * @name binance#fetchMyTradesWs
3950
+ * @description fetch all trades made by the user
3951
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/account-requests#account-trade-history-user_data
3952
+ * @param {string} symbol unified market symbol
3953
+ * @param {int|undefined} [since] the earliest time in ms to fetch trades for
3954
+ * @param {int|undefined} [limit] the maximum number of trades structures to retrieve
3955
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3956
+ * @param {int} [params.endTime] the latest time in ms to fetch trades for
3957
+ * @param {int} [params.fromId] first trade Id to fetch
3958
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
3959
+ */
3960
+ async fetchMyTradesWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3961
+ await this.loadMarkets();
3962
+ if (symbol === undefined) {
3963
+ throw new BadRequest(this.id + ' fetchMyTradesWs requires a symbol');
3964
+ }
3965
+ const market = this.market(symbol);
3966
+ const type = this.getMarketType('fetchMyTradesWs', market, params);
3967
+ if (type !== 'spot' && type !== 'future') {
3968
+ throw new BadRequest(this.id + ' fetchMyTradesWs does not support ' + type + ' markets');
3969
+ }
3970
+ const url = this.urls['api']['ws']['ws-api'][type];
3971
+ const requestId = this.requestId(url);
3972
+ const messageHash = requestId.toString();
3973
+ let returnRateLimits = false;
3974
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchMyTradesWs', 'returnRateLimits', false);
3975
+ const payload = {
3976
+ 'symbol': this.marketId(symbol),
3977
+ 'returnRateLimits': returnRateLimits,
3978
+ };
3979
+ if (since !== undefined) {
3980
+ payload['startTime'] = since;
3981
+ }
3982
+ if (limit !== undefined) {
3983
+ payload['limit'] = limit;
3984
+ }
3985
+ const fromId = this.safeInteger(params, 'fromId');
3986
+ if (fromId !== undefined && since !== undefined) {
3987
+ throw new BadRequest(this.id + ' fetchMyTradesWs does not support fetching by both fromId and since parameters at the same time');
3988
+ }
3989
+ const message = {
3990
+ 'id': messageHash,
3991
+ 'method': 'myTrades',
3992
+ 'params': this.signParams(this.extend(payload, params)),
3993
+ };
3994
+ const subscription = {
3995
+ 'method': this.handleTradesWs,
3996
+ };
3997
+ const trades = await this.watch(url, messageHash, message, messageHash, subscription);
3998
+ return this.filterBySymbolSinceLimit(trades, symbol, since, limit);
3999
+ }
4000
+ /**
4001
+ * @method
4002
+ * @name binance#fetchTradesWs
4003
+ * @description fetch all trades made by the user
4004
+ * @see https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/market-data-requests#recent-trades
4005
+ * @param {string} symbol unified market symbol
4006
+ * @param {int} [since] the earliest time in ms to fetch trades for
4007
+ * @param {int} [limit] the maximum number of trades structures to retrieve, default=500, max=1000
4008
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4009
+ *
4010
+ * EXCHANGE SPECIFIC PARAMETERS
4011
+ * @param {int} [params.fromId] trade ID to begin at
4012
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
4013
+ */
4014
+ async fetchTradesWs(symbol, since = undefined, limit = undefined, params = {}) {
4015
+ await this.loadMarkets();
4016
+ const market = this.market(symbol);
4017
+ const type = this.getMarketType('fetchTradesWs', market, params);
4018
+ if (type !== 'spot' && type !== 'future') {
4019
+ throw new BadRequest(this.id + ' fetchTradesWs does not support ' + type + ' markets');
4020
+ }
4021
+ const url = this.urls['api']['ws']['ws-api'][type];
4022
+ const requestId = this.requestId(url);
4023
+ const messageHash = requestId.toString();
4024
+ let returnRateLimits = false;
4025
+ [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchTradesWs', 'returnRateLimits', false);
4026
+ const payload = {
4027
+ 'symbol': this.marketId(symbol),
4028
+ 'returnRateLimits': returnRateLimits,
4029
+ };
4030
+ if (limit !== undefined) {
4031
+ payload['limit'] = limit;
4032
+ }
4033
+ const message = {
4034
+ 'id': messageHash,
4035
+ 'method': 'trades.historical',
4036
+ 'params': this.extend(payload, params),
4037
+ };
4038
+ const subscription = {
4039
+ 'method': this.handleTradesWs,
4040
+ };
4041
+ const trades = await this.watch(url, messageHash, message, messageHash, subscription);
4042
+ return this.filterBySinceLimit(trades, since, limit);
4043
+ }
4044
+ handleTradesWs(client, message) {
4045
+ //
4046
+ // fetchMyTradesWs
4047
+ //
4048
+ // {
4049
+ // "id": "f4ce6a53-a29d-4f70-823b-4ab59391d6e8",
4050
+ // "status": 200,
4051
+ // "result": [
4052
+ // {
4053
+ // "symbol": "BTCUSDT",
4054
+ // "id": 1650422481,
4055
+ // "orderId": 12569099453,
4056
+ // "orderListId": -1,
4057
+ // "price": "23416.10000000",
4058
+ // "qty": "0.00635000",
4059
+ // "quoteQty": "148.69223500",
4060
+ // "commission": "0.00000000",
4061
+ // "commissionAsset": "BNB",
4062
+ // "time": 1660801715793,
4063
+ // "isBuyer": false,
4064
+ // "isMaker": true,
4065
+ // "isBestMatch": true
4066
+ // },
4067
+ // ...
4068
+ // ],
4069
+ // }
4070
+ //
4071
+ // fetchTradesWs
4072
+ //
4073
+ // {
4074
+ // "id": "f4ce6a53-a29d-4f70-823b-4ab59391d6e8",
4075
+ // "status": 200,
4076
+ // "result": [
4077
+ // {
4078
+ // "id": 0,
4079
+ // "price": "0.00005000",
4080
+ // "qty": "40.00000000",
4081
+ // "quoteQty": "0.00200000",
4082
+ // "time": 1500004800376,
4083
+ // "isBuyerMaker": true,
4084
+ // "isBestMatch": true
4085
+ // }
4086
+ // ...
4087
+ // ],
4088
+ // }
4089
+ //
4090
+ const messageHash = this.safeString(message, 'id');
4091
+ const result = this.safeList(message, 'result', []);
4092
+ const trades = this.parseTrades(result);
4093
+ client.resolve(trades, messageHash);
4094
+ }
4095
+ /**
4096
+ * @method
4097
+ * @name binance#watchMyTrades
4098
+ * @description watches information on multiple trades made by the user
4099
+ * @param {string} symbol unified market symbol of the market orders were made in
4100
+ * @param {int} [since] the earliest time in ms to fetch orders for
4101
+ * @param {int} [limit] the maximum number of order structures to retrieve
4102
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4103
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to watch trades in a portfolio margin account
4104
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
4105
+ */
4106
+ async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
4107
+ await this.loadMarkets();
4108
+ let type = undefined;
4109
+ let market = undefined;
4110
+ if (symbol !== undefined) {
4111
+ market = this.market(symbol);
4112
+ symbol = market['symbol'];
4113
+ }
4114
+ [type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
4115
+ let subType = undefined;
4116
+ [subType, params] = this.handleSubTypeAndParams('watchMyTrades', market, params);
4117
+ if (this.isLinear(type, subType)) {
4118
+ type = 'future';
4119
+ }
4120
+ else if (this.isInverse(type, subType)) {
4121
+ type = 'delivery';
4122
+ }
4123
+ let messageHash = 'myTrades';
4124
+ if (symbol !== undefined) {
4125
+ symbol = this.symbol(symbol);
4126
+ messageHash += ':' + symbol;
4127
+ params = this.extend(params, { 'type': market['type'], 'symbol': symbol });
4128
+ }
4129
+ await this.authenticate(params);
4130
+ let urlType = type; // we don't change type because the listening key is different
4131
+ if (type === 'margin') {
4132
+ urlType = 'spot'; // spot-margin shares the same stream as regular spot
4133
+ }
4134
+ let isPortfolioMargin = undefined;
4135
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchMyTrades', 'papi', 'portfolioMargin', false);
4136
+ if (isPortfolioMargin) {
4137
+ urlType = 'papi';
4138
+ }
4139
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
4140
+ const client = this.client(url);
4141
+ this.setBalanceCache(client, type, isPortfolioMargin);
4142
+ this.setPositionsCache(client, type, undefined, isPortfolioMargin);
4143
+ const message = undefined;
4144
+ const trades = await this.watch(url, messageHash, message, type);
4145
+ if (this.newUpdates) {
4146
+ limit = trades.getLimit(symbol, limit);
4147
+ }
4148
+ return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
4149
+ }
4150
+ handleMyTrade(client, message) {
4151
+ const messageHash = 'myTrades';
4152
+ const executionType = this.safeString(message, 'x');
4153
+ if (executionType === 'TRADE') {
4154
+ const trade = this.parseWsTrade(message);
4155
+ const orderId = this.safeString(trade, 'order');
4156
+ let tradeFee = this.safeDict(trade, 'fee', {});
4157
+ tradeFee = this.extend({}, tradeFee);
4158
+ const symbol = this.safeString(trade, 'symbol');
4159
+ if (orderId !== undefined && tradeFee !== undefined && symbol !== undefined) {
4160
+ const cachedOrders = this.orders;
4161
+ if (cachedOrders !== undefined) {
4162
+ const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
4163
+ const order = this.safeValue(orders, orderId);
4164
+ if (order !== undefined) {
4165
+ // accumulate order fees
4166
+ const fees = this.safeValue(order, 'fees');
4167
+ const fee = this.safeValue(order, 'fee');
4168
+ if (!this.isEmpty(fees)) {
4169
+ let insertNewFeeCurrency = true;
4170
+ for (let i = 0; i < fees.length; i++) {
4171
+ const orderFee = fees[i];
4172
+ if (orderFee['currency'] === tradeFee['currency']) {
4173
+ const feeCost = this.sum(tradeFee['cost'], orderFee['cost']);
4174
+ order['fees'][i]['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
4175
+ insertNewFeeCurrency = false;
4176
+ break;
4177
+ }
4178
+ }
4179
+ if (insertNewFeeCurrency) {
4180
+ order['fees'].push(tradeFee);
4181
+ }
4182
+ }
4183
+ else if (fee !== undefined) {
4184
+ if (fee['currency'] === tradeFee['currency']) {
4185
+ const feeCost = this.sum(fee['cost'], tradeFee['cost']);
4186
+ order['fee']['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
4187
+ }
4188
+ else if (fee['currency'] === undefined) {
4189
+ order['fee'] = tradeFee;
4190
+ }
4191
+ else {
4192
+ order['fees'] = [fee, tradeFee];
4193
+ order['fee'] = undefined;
4194
+ }
4195
+ }
4196
+ else {
4197
+ order['fee'] = tradeFee;
4198
+ }
4199
+ // save this trade in the order
4200
+ const orderTrades = this.safeList(order, 'trades', []);
4201
+ orderTrades.push(trade);
4202
+ order['trades'] = orderTrades;
4203
+ // don't append twice cause it breaks newUpdates mode
4204
+ // this order already exists in the cache
4205
+ }
4206
+ }
4207
+ }
4208
+ if (this.myTrades === undefined) {
4209
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
4210
+ this.myTrades = new ArrayCacheBySymbolById(limit);
4211
+ }
4212
+ const myTrades = this.myTrades;
4213
+ myTrades.append(trade);
4214
+ client.resolve(this.myTrades, messageHash);
4215
+ const messageHashSymbol = messageHash + ':' + symbol;
4216
+ client.resolve(this.myTrades, messageHashSymbol);
4217
+ }
4218
+ }
4219
+ handleOrder(client, message) {
4220
+ const parsed = this.parseWsOrder(message);
4221
+ const symbol = this.safeString(parsed, 'symbol');
4222
+ const orderId = this.safeString(parsed, 'id');
4223
+ if (symbol !== undefined) {
4224
+ if (this.orders === undefined) {
4225
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
4226
+ this.orders = new ArrayCacheBySymbolById(limit);
4227
+ }
4228
+ const cachedOrders = this.orders;
4229
+ const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
4230
+ const order = this.safeValue(orders, orderId);
4231
+ if (order !== undefined) {
4232
+ const fee = this.safeValue(order, 'fee');
4233
+ if (fee !== undefined) {
4234
+ parsed['fee'] = fee;
4235
+ }
4236
+ const fees = this.safeValue(order, 'fees');
4237
+ if (fees !== undefined) {
4238
+ parsed['fees'] = fees;
4239
+ }
4240
+ parsed['trades'] = this.safeValue(order, 'trades');
4241
+ const timestamp = this.safeInteger(parsed, 'timestamp');
4242
+ if (timestamp === undefined) {
4243
+ parsed['timestamp'] = this.safeInteger(order, 'timestamp');
4244
+ parsed['datetime'] = this.safeString(order, 'datetime');
4245
+ }
4246
+ }
4247
+ cachedOrders.append(parsed);
4248
+ const messageHash = 'orders';
4249
+ const symbolSpecificMessageHash = 'orders:' + symbol;
4250
+ client.resolve(cachedOrders, messageHash);
4251
+ client.resolve(cachedOrders, symbolSpecificMessageHash);
4252
+ }
4253
+ }
4254
+ handleAcountUpdate(client, message) {
4255
+ this.handleBalance(client, message);
4256
+ this.handlePositions(client, message);
4257
+ }
4258
+ handleWsError(client, message) {
4259
+ //
4260
+ // {
4261
+ // "error": {
4262
+ // "code": 2,
4263
+ // "msg": "Invalid request: invalid stream"
4264
+ // },
4265
+ // "id": 1
4266
+ // }
4267
+ //
4268
+ const id = this.safeString(message, 'id');
4269
+ let rejected = false;
4270
+ const error = this.safeDict(message, 'error', {});
4271
+ const code = this.safeInteger(error, 'code');
4272
+ const msg = this.safeString(error, 'msg');
4273
+ try {
4274
+ this.handleErrors(code, msg, client.url, '', {}, this.json(error), error, {}, {});
4275
+ }
4276
+ catch (e) {
4277
+ rejected = true;
4278
+ // private endpoint uses id as messageHash
4279
+ client.reject(e, id);
4280
+ // public endpoint stores messageHash in subscriptions
4281
+ const subscriptionKeys = Object.keys(client.subscriptions);
4282
+ for (let i = 0; i < subscriptionKeys.length; i++) {
4283
+ const subscriptionHash = subscriptionKeys[i];
4284
+ const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
4285
+ if (id === subscriptionId) {
4286
+ client.reject(e, subscriptionHash);
4287
+ }
4288
+ }
4289
+ }
4290
+ if (!rejected) {
4291
+ client.reject(message, id);
4292
+ }
4293
+ // reset connection if 5xx error
4294
+ const codeString = this.safeString(error, 'code');
4295
+ if ((codeString !== undefined) && (codeString[0] === '5')) {
4296
+ client.reset(message);
4297
+ }
4298
+ }
4299
+ handleMessage(client, message) {
4300
+ // handle WebSocketAPI
4301
+ const status = this.safeString(message, 'status');
4302
+ const error = this.safeValue(message, 'error');
4303
+ if ((error !== undefined) || (status !== undefined && status !== '200')) {
4304
+ this.handleWsError(client, message);
4305
+ return;
4306
+ }
4307
+ const id = this.safeString(message, 'id');
4308
+ const subscriptions = this.safeValue(client.subscriptions, id);
4309
+ let method = this.safeValue(subscriptions, 'method');
4310
+ if (method !== undefined) {
4311
+ method.call(this, client, message);
4312
+ return;
4313
+ }
4314
+ // handle other APIs
4315
+ const methods = {
4316
+ 'depthUpdate': this.handleOrderBook,
4317
+ 'trade': this.handleTrade,
4318
+ 'aggTrade': this.handleTrade,
4319
+ 'kline': this.handleOHLCV,
4320
+ 'markPrice_kline': this.handleOHLCV,
4321
+ 'indexPrice_kline': this.handleOHLCV,
4322
+ '1hTicker@arr': this.handleTickers,
4323
+ '4hTicker@arr': this.handleTickers,
4324
+ '1dTicker@arr': this.handleTickers,
4325
+ '24hrTicker@arr': this.handleTickers,
4326
+ '24hrMiniTicker@arr': this.handleTickers,
4327
+ '1hTicker': this.handleTickers,
4328
+ '4hTicker': this.handleTickers,
4329
+ '1dTicker': this.handleTickers,
4330
+ '24hrTicker': this.handleTickers,
4331
+ '24hrMiniTicker': this.handleTickers,
4332
+ 'markPriceUpdate': this.handleTickers,
4333
+ 'markPriceUpdate@arr': this.handleTickers,
4334
+ 'bookTicker': this.handleBidsAsks,
4335
+ 'outboundAccountPosition': this.handleBalance,
4336
+ 'balanceUpdate': this.handleBalance,
4337
+ 'ACCOUNT_UPDATE': this.handleAcountUpdate,
4338
+ 'executionReport': this.handleOrderUpdate,
4339
+ 'ORDER_TRADE_UPDATE': this.handleOrderUpdate,
4340
+ 'forceOrder': this.handleLiquidation,
4341
+ };
4342
+ let event = this.safeString(message, 'e');
4343
+ if (Array.isArray(message)) {
4344
+ const data = message[0];
4345
+ event = this.safeString(data, 'e') + '@arr';
4346
+ }
4347
+ method = this.safeValue(methods, event);
4348
+ if (method === undefined) {
4349
+ const requestId = this.safeString(message, 'id');
4350
+ if (requestId !== undefined) {
4351
+ this.handleSubscriptionStatus(client, message);
4352
+ return;
4353
+ }
4354
+ // special case for the real-time bookTicker, since it comes without an event identifier
4355
+ //
4356
+ // {
4357
+ // "u": 7488717758,
4358
+ // "s": "BTCUSDT",
4359
+ // "b": "28621.74000000",
4360
+ // "B": "1.43278800",
4361
+ // "a": "28621.75000000",
4362
+ // "A": "2.52500800"
4363
+ // }
4364
+ //
4365
+ if (event === undefined && ('a' in message) && ('b' in message)) {
4366
+ this.handleBidsAsks(client, message);
4367
+ }
4368
+ }
4369
+ else {
4370
+ method.call(this, client, message);
4371
+ }
4372
+ }
4373
+ }