ccxt 4.2.17 → 4.2.19

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 (439) hide show
  1. package/README.md +9 -9
  2. package/dist/ccxt.browser.js +48992 -47725
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +12 -1
  5. package/dist/cjs/src/alpaca.js +18 -18
  6. package/dist/cjs/src/ascendex.js +13 -6
  7. package/dist/cjs/src/base/Exchange.js +266 -27
  8. package/dist/cjs/src/bigone.js +434 -168
  9. package/dist/cjs/src/binance.js +163 -34
  10. package/dist/cjs/src/binanceus.js +8 -0
  11. package/dist/cjs/src/bingx.js +183 -41
  12. package/dist/cjs/src/bitfinex.js +2 -3
  13. package/dist/cjs/src/bitget.js +59 -16
  14. package/dist/cjs/src/bitmart.js +5 -5
  15. package/dist/cjs/src/bitmex.js +4 -6
  16. package/dist/cjs/src/bitpanda.js +5 -1991
  17. package/dist/cjs/src/bitstamp.js +8 -0
  18. package/dist/cjs/src/bybit.js +27 -47
  19. package/dist/cjs/src/coinbase.js +176 -26
  20. package/dist/cjs/src/coincheck.js +1 -0
  21. package/dist/cjs/src/coinex.js +3 -0
  22. package/dist/cjs/src/coinlist.js +13 -6
  23. package/dist/cjs/src/coinone.js +2 -2
  24. package/dist/cjs/src/coinsph.js +4 -5
  25. package/dist/cjs/src/delta.js +7 -1
  26. package/dist/cjs/src/deribit.js +17 -4
  27. package/dist/cjs/src/gate.js +151 -169
  28. package/dist/cjs/src/gemini.js +1 -1
  29. package/dist/cjs/src/hitbtc.js +2 -3
  30. package/dist/cjs/src/htx.js +157 -7
  31. package/dist/cjs/src/huobijp.js +2 -3
  32. package/dist/cjs/src/independentreserve.js +7 -5
  33. package/dist/cjs/src/kraken.js +86 -54
  34. package/dist/cjs/src/kucoin.js +5 -0
  35. package/dist/cjs/src/kucoinfutures.js +131 -77
  36. package/dist/cjs/src/lbank.js +60 -33
  37. package/dist/cjs/src/luno.js +84 -2
  38. package/dist/cjs/src/mexc.js +3 -3
  39. package/dist/cjs/src/oceanex.js +1 -1
  40. package/dist/cjs/src/okx.js +23 -11
  41. package/dist/cjs/{js/src/bitpanda.js → src/onetrading.js} +39 -39
  42. package/dist/cjs/src/phemex.js +37 -27
  43. package/dist/cjs/src/poloniexfutures.js +1 -0
  44. package/dist/cjs/src/pro/binance.js +66 -25
  45. package/dist/cjs/src/pro/bitget.js +1 -1
  46. package/dist/cjs/src/pro/bitpanda.js +5 -1330
  47. package/dist/cjs/src/pro/coinbase.js +4 -1
  48. package/dist/cjs/src/pro/coincheck.js +208 -0
  49. package/dist/cjs/src/pro/hitbtc.js +5 -4
  50. package/dist/cjs/src/pro/htx.js +6 -1
  51. package/dist/cjs/src/pro/kraken.js +1 -1
  52. package/dist/cjs/src/pro/krakenfutures.js +7 -1
  53. package/dist/cjs/src/pro/kucoin.js +46 -36
  54. package/dist/cjs/src/pro/kucoinfutures.js +45 -37
  55. package/dist/cjs/src/pro/lbank.js +881 -0
  56. package/dist/cjs/src/pro/okx.js +52 -2
  57. package/dist/cjs/{js/src/pro/bitpanda.js → src/pro/onetrading.js} +4 -7
  58. package/dist/cjs/src/pro/poloniex.js +2 -2
  59. package/dist/cjs/src/pro/poloniexfutures.js +43 -35
  60. package/dist/cjs/src/pro/woo.js +126 -0
  61. package/dist/cjs/src/probit.js +4 -2
  62. package/dist/cjs/src/upbit.js +12 -12
  63. package/dist/cjs/src/wavesexchange.js +1 -1
  64. package/dist/cjs/src/whitebit.js +1 -0
  65. package/dist/cjs/src/woo.js +56 -0
  66. package/js/ccxt.d.ts +14 -2
  67. package/js/ccxt.js +10 -2
  68. package/js/src/abstract/bitpanda.d.ts +4 -4
  69. package/js/src/abstract/bitstamp.d.ts +8 -0
  70. package/js/src/abstract/gate.d.ts +1 -0
  71. package/js/src/abstract/gateio.d.ts +1 -0
  72. package/js/src/abstract/htx.d.ts +3 -0
  73. package/js/src/abstract/huobi.d.ts +3 -0
  74. package/js/src/abstract/luno.d.ts +1 -0
  75. package/js/src/abstract/onetrading.d.ts +38 -0
  76. package/js/src/ascendex.js +2 -0
  77. package/js/src/base/Exchange.d.ts +2 -3
  78. package/js/src/base/Exchange.js +5 -2
  79. package/js/src/binance.js +7 -1
  80. package/js/src/bingx.d.ts +1 -0
  81. package/js/src/bingx.js +26 -0
  82. package/js/src/bitget.js +22 -3
  83. package/js/src/bitpanda.d.ts +2 -72
  84. package/js/src/bitpanda.js +5 -1991
  85. package/js/src/bitstamp.js +8 -0
  86. package/js/src/bybit.js +21 -47
  87. package/js/src/coincheck.js +1 -0
  88. package/js/src/deribit.js +16 -4
  89. package/js/src/gate.d.ts +1 -0
  90. package/js/src/gate.js +50 -110
  91. package/js/src/htx.js +3 -0
  92. package/js/src/kraken.d.ts +1 -0
  93. package/js/src/kraken.js +40 -39
  94. package/js/src/lbank.js +1 -0
  95. package/js/src/luno.d.ts +3 -1
  96. package/js/src/luno.js +84 -2
  97. package/js/src/mexc.js +1 -2
  98. package/js/src/onetrading.d.ts +74 -0
  99. package/js/src/onetrading.js +2003 -0
  100. package/js/src/poloniexfutures.js +1 -0
  101. package/js/src/pro/binance.js +7 -2
  102. package/js/src/pro/bitget.js +1 -1
  103. package/js/src/pro/bitpanda.d.ts +2 -34
  104. package/js/src/pro/bitpanda.js +5 -1330
  105. package/js/src/pro/coincheck.d.ts +12 -0
  106. package/js/src/pro/coincheck.js +209 -0
  107. package/js/src/pro/kucoin.js +43 -35
  108. package/js/src/pro/kucoinfutures.js +45 -37
  109. package/js/src/pro/lbank.d.ts +29 -0
  110. package/js/src/pro/lbank.js +882 -0
  111. package/js/src/pro/onetrading.d.ts +36 -0
  112. package/js/src/pro/onetrading.js +1339 -0
  113. package/js/src/pro/poloniexfutures.js +43 -35
  114. package/js/src/whitebit.js +1 -0
  115. package/package.json +2 -2
  116. package/rollup.config.js +2 -0
  117. package/skip-tests.json +14 -2
  118. package/test-commonjs.cjs +25 -1
  119. package/dist/cjs/js/ccxt.js +0 -476
  120. package/dist/cjs/js/src/abstract/alpaca.js +0 -9
  121. package/dist/cjs/js/src/abstract/ascendex.js +0 -9
  122. package/dist/cjs/js/src/abstract/bigone.js +0 -9
  123. package/dist/cjs/js/src/abstract/binance.js +0 -9
  124. package/dist/cjs/js/src/abstract/bingx.js +0 -9
  125. package/dist/cjs/js/src/abstract/bit2c.js +0 -9
  126. package/dist/cjs/js/src/abstract/bitbank.js +0 -9
  127. package/dist/cjs/js/src/abstract/bitbns.js +0 -9
  128. package/dist/cjs/js/src/abstract/bitfinex.js +0 -9
  129. package/dist/cjs/js/src/abstract/bitfinex2.js +0 -9
  130. package/dist/cjs/js/src/abstract/bitflyer.js +0 -9
  131. package/dist/cjs/js/src/abstract/bitforex.js +0 -9
  132. package/dist/cjs/js/src/abstract/bitget.js +0 -9
  133. package/dist/cjs/js/src/abstract/bithumb.js +0 -9
  134. package/dist/cjs/js/src/abstract/bitmart.js +0 -9
  135. package/dist/cjs/js/src/abstract/bitmex.js +0 -9
  136. package/dist/cjs/js/src/abstract/bitopro.js +0 -9
  137. package/dist/cjs/js/src/abstract/bitpanda.js +0 -9
  138. package/dist/cjs/js/src/abstract/bitrue.js +0 -9
  139. package/dist/cjs/js/src/abstract/bitso.js +0 -9
  140. package/dist/cjs/js/src/abstract/bitstamp.js +0 -9
  141. package/dist/cjs/js/src/abstract/bitteam.js +0 -9
  142. package/dist/cjs/js/src/abstract/bitvavo.js +0 -9
  143. package/dist/cjs/js/src/abstract/bl3p.js +0 -9
  144. package/dist/cjs/js/src/abstract/blockchaincom.js +0 -9
  145. package/dist/cjs/js/src/abstract/btcalpha.js +0 -9
  146. package/dist/cjs/js/src/abstract/btcbox.js +0 -9
  147. package/dist/cjs/js/src/abstract/btcmarkets.js +0 -9
  148. package/dist/cjs/js/src/abstract/btcturk.js +0 -9
  149. package/dist/cjs/js/src/abstract/bybit.js +0 -9
  150. package/dist/cjs/js/src/abstract/cex.js +0 -9
  151. package/dist/cjs/js/src/abstract/coinbase.js +0 -9
  152. package/dist/cjs/js/src/abstract/coinbasepro.js +0 -9
  153. package/dist/cjs/js/src/abstract/coincheck.js +0 -9
  154. package/dist/cjs/js/src/abstract/coinex.js +0 -9
  155. package/dist/cjs/js/src/abstract/coinlist.js +0 -9
  156. package/dist/cjs/js/src/abstract/coinmate.js +0 -9
  157. package/dist/cjs/js/src/abstract/coinone.js +0 -9
  158. package/dist/cjs/js/src/abstract/coinsph.js +0 -9
  159. package/dist/cjs/js/src/abstract/coinspot.js +0 -9
  160. package/dist/cjs/js/src/abstract/cryptocom.js +0 -9
  161. package/dist/cjs/js/src/abstract/currencycom.js +0 -9
  162. package/dist/cjs/js/src/abstract/delta.js +0 -9
  163. package/dist/cjs/js/src/abstract/deribit.js +0 -9
  164. package/dist/cjs/js/src/abstract/digifinex.js +0 -9
  165. package/dist/cjs/js/src/abstract/exmo.js +0 -9
  166. package/dist/cjs/js/src/abstract/gate.js +0 -9
  167. package/dist/cjs/js/src/abstract/gemini.js +0 -9
  168. package/dist/cjs/js/src/abstract/hitbtc.js +0 -9
  169. package/dist/cjs/js/src/abstract/hollaex.js +0 -9
  170. package/dist/cjs/js/src/abstract/htx.js +0 -9
  171. package/dist/cjs/js/src/abstract/huobijp.js +0 -9
  172. package/dist/cjs/js/src/abstract/idex.js +0 -9
  173. package/dist/cjs/js/src/abstract/independentreserve.js +0 -9
  174. package/dist/cjs/js/src/abstract/indodax.js +0 -9
  175. package/dist/cjs/js/src/abstract/kraken.js +0 -9
  176. package/dist/cjs/js/src/abstract/krakenfutures.js +0 -9
  177. package/dist/cjs/js/src/abstract/kucoin.js +0 -9
  178. package/dist/cjs/js/src/abstract/kucoinfutures.js +0 -9
  179. package/dist/cjs/js/src/abstract/kuna.js +0 -9
  180. package/dist/cjs/js/src/abstract/latoken.js +0 -9
  181. package/dist/cjs/js/src/abstract/lbank.js +0 -9
  182. package/dist/cjs/js/src/abstract/luno.js +0 -9
  183. package/dist/cjs/js/src/abstract/lykke.js +0 -9
  184. package/dist/cjs/js/src/abstract/mercado.js +0 -9
  185. package/dist/cjs/js/src/abstract/mexc.js +0 -9
  186. package/dist/cjs/js/src/abstract/ndax.js +0 -9
  187. package/dist/cjs/js/src/abstract/novadax.js +0 -9
  188. package/dist/cjs/js/src/abstract/oceanex.js +0 -9
  189. package/dist/cjs/js/src/abstract/okcoin.js +0 -9
  190. package/dist/cjs/js/src/abstract/okx.js +0 -9
  191. package/dist/cjs/js/src/abstract/p2b.js +0 -9
  192. package/dist/cjs/js/src/abstract/paymium.js +0 -9
  193. package/dist/cjs/js/src/abstract/phemex.js +0 -9
  194. package/dist/cjs/js/src/abstract/poloniex.js +0 -9
  195. package/dist/cjs/js/src/abstract/poloniexfutures.js +0 -9
  196. package/dist/cjs/js/src/abstract/probit.js +0 -9
  197. package/dist/cjs/js/src/abstract/timex.js +0 -9
  198. package/dist/cjs/js/src/abstract/tokocrypto.js +0 -9
  199. package/dist/cjs/js/src/abstract/upbit.js +0 -9
  200. package/dist/cjs/js/src/abstract/wavesexchange.js +0 -9
  201. package/dist/cjs/js/src/abstract/wazirx.js +0 -9
  202. package/dist/cjs/js/src/abstract/whitebit.js +0 -9
  203. package/dist/cjs/js/src/abstract/woo.js +0 -9
  204. package/dist/cjs/js/src/abstract/yobit.js +0 -9
  205. package/dist/cjs/js/src/abstract/zaif.js +0 -9
  206. package/dist/cjs/js/src/abstract/zonda.js +0 -9
  207. package/dist/cjs/js/src/ace.js +0 -1058
  208. package/dist/cjs/js/src/alpaca.js +0 -1125
  209. package/dist/cjs/js/src/ascendex.js +0 -3365
  210. package/dist/cjs/js/src/base/Exchange.js +0 -5257
  211. package/dist/cjs/js/src/base/Precise.js +0 -263
  212. package/dist/cjs/js/src/base/errors.js +0 -299
  213. package/dist/cjs/js/src/base/functions/crypto.js +0 -78
  214. package/dist/cjs/js/src/base/functions/encode.js +0 -44
  215. package/dist/cjs/js/src/base/functions/generic.js +0 -193
  216. package/dist/cjs/js/src/base/functions/misc.js +0 -96
  217. package/dist/cjs/js/src/base/functions/number.js +0 -297
  218. package/dist/cjs/js/src/base/functions/platform.js +0 -28
  219. package/dist/cjs/js/src/base/functions/rsa.js +0 -34
  220. package/dist/cjs/js/src/base/functions/string.js +0 -48
  221. package/dist/cjs/js/src/base/functions/throttle.js +0 -66
  222. package/dist/cjs/js/src/base/functions/time.js +0 -187
  223. package/dist/cjs/js/src/base/functions/totp.js +0 -24
  224. package/dist/cjs/js/src/base/functions/type.js +0 -162
  225. package/dist/cjs/js/src/base/functions.js +0 -157
  226. package/dist/cjs/js/src/base/ws/Cache.js +0 -254
  227. package/dist/cjs/js/src/base/ws/Client.js +0 -299
  228. package/dist/cjs/js/src/base/ws/Future.js +0 -34
  229. package/dist/cjs/js/src/base/ws/OrderBook.js +0 -107
  230. package/dist/cjs/js/src/base/ws/OrderBookSide.js +0 -281
  231. package/dist/cjs/js/src/base/ws/WsClient.js +0 -69
  232. package/dist/cjs/js/src/bequant.js +0 -33
  233. package/dist/cjs/js/src/bigone.js +0 -2213
  234. package/dist/cjs/js/src/binance.js +0 -9845
  235. package/dist/cjs/js/src/binancecoinm.js +0 -45
  236. package/dist/cjs/js/src/binanceus.js +0 -92
  237. package/dist/cjs/js/src/binanceusdm.js +0 -58
  238. package/dist/cjs/js/src/bingx.js +0 -3846
  239. package/dist/cjs/js/src/bit2c.js +0 -916
  240. package/dist/cjs/js/src/bitbank.js +0 -1000
  241. package/dist/cjs/js/src/bitbay.js +0 -17
  242. package/dist/cjs/js/src/bitbns.js +0 -1220
  243. package/dist/cjs/js/src/bitcoincom.js +0 -17
  244. package/dist/cjs/js/src/bitfinex.js +0 -1670
  245. package/dist/cjs/js/src/bitfinex2.js +0 -2990
  246. package/dist/cjs/js/src/bitflyer.js +0 -1045
  247. package/dist/cjs/js/src/bitforex.js +0 -852
  248. package/dist/cjs/js/src/bitget.js +0 -8295
  249. package/dist/cjs/js/src/bithumb.js +0 -1090
  250. package/dist/cjs/js/src/bitmart.js +0 -4454
  251. package/dist/cjs/js/src/bitmex.js +0 -2881
  252. package/dist/cjs/js/src/bitopro.js +0 -1724
  253. package/dist/cjs/js/src/bitrue.js +0 -3253
  254. package/dist/cjs/js/src/bitso.js +0 -1753
  255. package/dist/cjs/js/src/bitstamp.js +0 -2188
  256. package/dist/cjs/js/src/bitteam.js +0 -2309
  257. package/dist/cjs/js/src/bitvavo.js +0 -1968
  258. package/dist/cjs/js/src/bl3p.js +0 -447
  259. package/dist/cjs/js/src/blockchaincom.js +0 -1160
  260. package/dist/cjs/js/src/btcalpha.js +0 -929
  261. package/dist/cjs/js/src/btcbox.js +0 -565
  262. package/dist/cjs/js/src/btcmarkets.js +0 -1237
  263. package/dist/cjs/js/src/btcturk.js +0 -929
  264. package/dist/cjs/js/src/bybit.js +0 -7650
  265. package/dist/cjs/js/src/cex.js +0 -1693
  266. package/dist/cjs/js/src/coinbase.js +0 -3424
  267. package/dist/cjs/js/src/coinbasepro.js +0 -1866
  268. package/dist/cjs/js/src/coincheck.js +0 -843
  269. package/dist/cjs/js/src/coinex.js +0 -5417
  270. package/dist/cjs/js/src/coinlist.js +0 -2337
  271. package/dist/cjs/js/src/coinmate.js +0 -989
  272. package/dist/cjs/js/src/coinone.js +0 -1185
  273. package/dist/cjs/js/src/coinsph.js +0 -1933
  274. package/dist/cjs/js/src/coinspot.js +0 -548
  275. package/dist/cjs/js/src/cryptocom.js +0 -3007
  276. package/dist/cjs/js/src/currencycom.js +0 -2015
  277. package/dist/cjs/js/src/delta.js +0 -3262
  278. package/dist/cjs/js/src/deribit.js +0 -3306
  279. package/dist/cjs/js/src/digifinex.js +0 -4307
  280. package/dist/cjs/js/src/exmo.js +0 -2645
  281. package/dist/cjs/js/src/fmfwio.js +0 -34
  282. package/dist/cjs/js/src/gate.js +0 -7077
  283. package/dist/cjs/js/src/gateio.js +0 -16
  284. package/dist/cjs/js/src/gemini.js +0 -1801
  285. package/dist/cjs/js/src/hitbtc.js +0 -3660
  286. package/dist/cjs/js/src/hitbtc3.js +0 -19
  287. package/dist/cjs/js/src/hollaex.js +0 -1882
  288. package/dist/cjs/js/src/htx.js +0 -9174
  289. package/dist/cjs/js/src/huobi.js +0 -16
  290. package/dist/cjs/js/src/huobijp.js +0 -1918
  291. package/dist/cjs/js/src/idex.js +0 -1770
  292. package/dist/cjs/js/src/independentreserve.js +0 -761
  293. package/dist/cjs/js/src/indodax.js +0 -1069
  294. package/dist/cjs/js/src/kraken.js +0 -2891
  295. package/dist/cjs/js/src/krakenfutures.js +0 -2407
  296. package/dist/cjs/js/src/kucoin.js +0 -4494
  297. package/dist/cjs/js/src/kucoinfutures.js +0 -2529
  298. package/dist/cjs/js/src/kuna.js +0 -1949
  299. package/dist/cjs/js/src/latoken.js +0 -1729
  300. package/dist/cjs/js/src/lbank.js +0 -2851
  301. package/dist/cjs/js/src/luno.js +0 -1044
  302. package/dist/cjs/js/src/lykke.js +0 -1303
  303. package/dist/cjs/js/src/mercado.js +0 -897
  304. package/dist/cjs/js/src/mexc.js +0 -5407
  305. package/dist/cjs/js/src/ndax.js +0 -2450
  306. package/dist/cjs/js/src/novadax.js +0 -1556
  307. package/dist/cjs/js/src/oceanex.js +0 -964
  308. package/dist/cjs/js/src/okcoin.js +0 -3115
  309. package/dist/cjs/js/src/okx.js +0 -7331
  310. package/dist/cjs/js/src/p2b.js +0 -1243
  311. package/dist/cjs/js/src/paymium.js +0 -597
  312. package/dist/cjs/js/src/phemex.js +0 -4725
  313. package/dist/cjs/js/src/poloniex.js +0 -2356
  314. package/dist/cjs/js/src/poloniexfutures.js +0 -1794
  315. package/dist/cjs/js/src/pro/alpaca.js +0 -714
  316. package/dist/cjs/js/src/pro/ascendex.js +0 -957
  317. package/dist/cjs/js/src/pro/bequant.js +0 -33
  318. package/dist/cjs/js/src/pro/binance.js +0 -2796
  319. package/dist/cjs/js/src/pro/binancecoinm.js +0 -23
  320. package/dist/cjs/js/src/pro/binanceus.js +0 -51
  321. package/dist/cjs/js/src/pro/binanceusdm.js +0 -32
  322. package/dist/cjs/js/src/pro/bingx.js +0 -944
  323. package/dist/cjs/js/src/pro/bitcoincom.js +0 -29
  324. package/dist/cjs/js/src/pro/bitfinex.js +0 -672
  325. package/dist/cjs/js/src/pro/bitfinex2.js +0 -1159
  326. package/dist/cjs/js/src/pro/bitget.js +0 -1733
  327. package/dist/cjs/js/src/pro/bitmart.js +0 -1486
  328. package/dist/cjs/js/src/pro/bitmex.js +0 -1576
  329. package/dist/cjs/js/src/pro/bitopro.js +0 -327
  330. package/dist/cjs/js/src/pro/bitrue.js +0 -462
  331. package/dist/cjs/js/src/pro/bitstamp.js +0 -547
  332. package/dist/cjs/js/src/pro/bitvavo.js +0 -704
  333. package/dist/cjs/js/src/pro/blockchaincom.js +0 -794
  334. package/dist/cjs/js/src/pro/bybit.js +0 -1843
  335. package/dist/cjs/js/src/pro/cex.js +0 -1510
  336. package/dist/cjs/js/src/pro/coinbase.js +0 -561
  337. package/dist/cjs/js/src/pro/coinbasepro.js +0 -968
  338. package/dist/cjs/js/src/pro/coinex.js +0 -1095
  339. package/dist/cjs/js/src/pro/cryptocom.js +0 -1020
  340. package/dist/cjs/js/src/pro/currencycom.js +0 -563
  341. package/dist/cjs/js/src/pro/deribit.js +0 -825
  342. package/dist/cjs/js/src/pro/exmo.js +0 -658
  343. package/dist/cjs/js/src/pro/gate.js +0 -1316
  344. package/dist/cjs/js/src/pro/gateio.js +0 -16
  345. package/dist/cjs/js/src/pro/gemini.js +0 -649
  346. package/dist/cjs/js/src/pro/hitbtc.js +0 -1294
  347. package/dist/cjs/js/src/pro/hollaex.js +0 -597
  348. package/dist/cjs/js/src/pro/htx.js +0 -2388
  349. package/dist/cjs/js/src/pro/huobi.js +0 -16
  350. package/dist/cjs/js/src/pro/huobijp.js +0 -606
  351. package/dist/cjs/js/src/pro/idex.js +0 -714
  352. package/dist/cjs/js/src/pro/independentreserve.js +0 -280
  353. package/dist/cjs/js/src/pro/kraken.js +0 -1364
  354. package/dist/cjs/js/src/pro/krakenfutures.js +0 -1506
  355. package/dist/cjs/js/src/pro/kucoin.js +0 -1054
  356. package/dist/cjs/js/src/pro/kucoinfutures.js +0 -981
  357. package/dist/cjs/js/src/pro/luno.js +0 -322
  358. package/dist/cjs/js/src/pro/mexc.js +0 -1170
  359. package/dist/cjs/js/src/pro/ndax.js +0 -545
  360. package/dist/cjs/js/src/pro/okcoin.js +0 -760
  361. package/dist/cjs/js/src/pro/okx.js +0 -1608
  362. package/dist/cjs/js/src/pro/phemex.js +0 -1511
  363. package/dist/cjs/js/src/pro/poloniex.js +0 -1253
  364. package/dist/cjs/js/src/pro/poloniexfutures.js +0 -1014
  365. package/dist/cjs/js/src/pro/probit.js +0 -586
  366. package/dist/cjs/js/src/pro/upbit.js +0 -234
  367. package/dist/cjs/js/src/pro/wazirx.js +0 -776
  368. package/dist/cjs/js/src/pro/whitebit.js +0 -927
  369. package/dist/cjs/js/src/pro/woo.js +0 -895
  370. package/dist/cjs/js/src/probit.js +0 -1867
  371. package/dist/cjs/js/src/static_dependencies/fflake/browser.js +0 -401
  372. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +0 -195
  373. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +0 -308
  374. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +0 -554
  375. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +0 -94
  376. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +0 -70
  377. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +0 -91
  378. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +0 -16
  379. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +0 -1760
  380. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +0 -52
  381. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +0 -81
  382. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +0 -376
  383. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +0 -70
  384. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +0 -1580
  385. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +0 -74
  386. package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +0 -24
  387. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +0 -158
  388. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +0 -429
  389. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +0 -176
  390. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +0 -324
  391. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +0 -163
  392. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +0 -245
  393. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +0 -1018
  394. package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +0 -383
  395. package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +0 -258
  396. package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +0 -53
  397. package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +0 -120
  398. package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +0 -69
  399. package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +0 -7
  400. package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +0 -83
  401. package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +0 -240
  402. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +0 -91
  403. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +0 -130
  404. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +0 -214
  405. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +0 -239
  406. package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +0 -93
  407. package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +0 -354
  408. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +0 -16
  409. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +0 -20
  410. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +0 -30
  411. package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +0 -239
  412. package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +0 -372
  413. package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +0 -273
  414. package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +0 -139
  415. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +0 -14
  416. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +0 -16
  417. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +0 -81
  418. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +0 -292
  419. package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +0 -103
  420. package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +0 -140
  421. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +0 -175
  422. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +0 -95
  423. package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +0 -7
  424. package/dist/cjs/js/src/static_dependencies/scure-base/index.js +0 -383
  425. package/dist/cjs/js/src/timex.js +0 -1562
  426. package/dist/cjs/js/src/tokocrypto.js +0 -2542
  427. package/dist/cjs/js/src/upbit.js +0 -1844
  428. package/dist/cjs/js/src/wavesexchange.js +0 -2607
  429. package/dist/cjs/js/src/wazirx.js +0 -953
  430. package/dist/cjs/js/src/whitebit.js +0 -2309
  431. package/dist/cjs/js/src/woo.js +0 -2769
  432. package/dist/cjs/js/src/yobit.js +0 -1314
  433. package/dist/cjs/js/src/zaif.js +0 -736
  434. package/dist/cjs/js/src/zonda.js +0 -1883
  435. package/dist/cjs/src/abstract/bitpanda.js +0 -9
  436. package/test.ts +0 -0
  437. /package/dist/cjs/{js/src/abstract/ace.js → src/abstract/onetrading.js} +0 -0
  438. /package/dist/cjs/{js/src → src}/pro/coinone.js +0 -0
  439. /package/js/src/abstract/{bitpanda.js → onetrading.js} +0 -0
@@ -1,2796 +0,0 @@
1
- 'use strict';
2
-
3
- var binance$1 = require('../binance.js');
4
- var Precise = require('../base/Precise.js');
5
- var errors = require('../base/errors.js');
6
- var Cache = require('../base/ws/Cache.js');
7
- var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
8
- var rsa = require('../base/functions/rsa.js');
9
- var crypto = require('../base/functions/crypto.js');
10
- var ed25519 = require('../static_dependencies/noble-curves/ed25519.js');
11
-
12
- // ----------------------------------------------------------------------------
13
- // -----------------------------------------------------------------------------
14
- class binance extends binance$1 {
15
- describe() {
16
- return this.deepExtend(super.describe(), {
17
- 'has': {
18
- 'ws': true,
19
- 'watchBalance': true,
20
- 'watchMyTrades': true,
21
- 'watchOHLCV': true,
22
- 'watchOHLCVForSymbols': false,
23
- 'watchOrderBook': true,
24
- 'watchOrderBookForSymbols': true,
25
- 'watchOrders': true,
26
- 'watchOrdersForSymbols': true,
27
- 'watchPositions': true,
28
- 'watchTicker': true,
29
- 'watchTickers': true,
30
- 'watchTrades': true,
31
- 'watchTradesForSymbols': true,
32
- 'createOrderWs': true,
33
- 'editOrderWs': true,
34
- 'cancelOrderWs': true,
35
- 'cancelOrdersWs': false,
36
- 'cancelAllOrdersWs': true,
37
- 'fetchOrderWs': true,
38
- 'fetchOrdersWs': true,
39
- 'fetchBalanceWs': true,
40
- 'fetchMyTradesWs': true,
41
- },
42
- 'urls': {
43
- 'test': {
44
- 'ws': {
45
- 'spot': 'wss://testnet.binance.vision/ws',
46
- 'margin': 'wss://testnet.binance.vision/ws',
47
- 'future': 'wss://stream.binancefuture.com/ws',
48
- 'delivery': 'wss://dstream.binancefuture.com/ws',
49
- 'ws': 'wss://testnet.binance.vision/ws-api/v3',
50
- },
51
- },
52
- 'api': {
53
- 'ws': {
54
- 'spot': 'wss://stream.binance.com/ws',
55
- 'margin': 'wss://stream.binance.com/ws',
56
- 'future': 'wss://fstream.binance.com/ws',
57
- 'delivery': 'wss://dstream.binance.com/ws',
58
- 'ws': 'wss://ws-api.binance.com:443/ws-api/v3',
59
- },
60
- },
61
- },
62
- 'streaming': {
63
- 'keepAlive': 180000,
64
- },
65
- 'options': {
66
- 'returnRateLimits': false,
67
- 'streamLimits': {
68
- 'spot': 50,
69
- 'margin': 50,
70
- 'future': 50,
71
- 'delivery': 50, // max 200
72
- },
73
- 'subscriptionLimitByStream': {
74
- 'spot': 200,
75
- 'margin': 200,
76
- 'future': 200,
77
- 'delivery': 200,
78
- },
79
- 'streamBySubscriptionsHash': {},
80
- 'streamIndex': -1,
81
- // get updates every 1000ms or 100ms
82
- // or every 0ms in real-time for futures
83
- 'watchOrderBookRate': 100,
84
- 'tradesLimit': 1000,
85
- 'ordersLimit': 1000,
86
- 'OHLCVLimit': 1000,
87
- 'requestId': {},
88
- 'watchOrderBookLimit': 1000,
89
- 'watchTrades': {
90
- 'name': 'trade', // 'trade' or 'aggTrade'
91
- },
92
- 'watchTicker': {
93
- 'name': 'ticker', // ticker = 1000ms L1+OHLCV, bookTicker = real-time L1
94
- },
95
- 'watchTickers': {
96
- 'name': 'ticker', // ticker or miniTicker or bookTicker
97
- },
98
- 'watchOHLCV': {
99
- 'name': 'kline', // or indexPriceKline or markPriceKline (coin-m futures)
100
- },
101
- 'watchOrderBook': {
102
- 'maxRetries': 3,
103
- },
104
- 'watchBalance': {
105
- 'fetchBalanceSnapshot': false,
106
- 'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
107
- },
108
- 'watchPositions': {
109
- 'fetchPositionsSnapshot': true,
110
- 'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
111
- },
112
- 'wallet': 'wb',
113
- 'listenKeyRefreshRate': 1200000,
114
- 'ws': {
115
- 'cost': 5,
116
- },
117
- },
118
- });
119
- }
120
- requestId(url) {
121
- const options = this.safeValue(this.options, 'requestId', {});
122
- const previousValue = this.safeInteger(options, url, 0);
123
- const newValue = this.sum(previousValue, 1);
124
- this.options['requestId'][url] = newValue;
125
- return newValue;
126
- }
127
- stream(type, subscriptionHash, numSubscriptions = 1) {
128
- const streamBySubscriptionsHash = this.safeValue(this.options, 'streamBySubscriptionsHash', {});
129
- let stream = this.safeString(streamBySubscriptionsHash, subscriptionHash);
130
- if (stream === undefined) {
131
- let streamIndex = this.safeInteger(this.options, 'streamIndex', -1);
132
- const streamLimits = this.safeValue(this.options, 'streamLimits');
133
- const streamLimit = this.safeInteger(streamLimits, type);
134
- streamIndex = streamIndex + 1;
135
- const normalizedIndex = streamIndex % streamLimit;
136
- this.options['streamIndex'] = streamIndex;
137
- stream = this.numberToString(normalizedIndex);
138
- this.options['streamBySubscriptionsHash'][subscriptionHash] = stream;
139
- const subscriptionsByStreams = this.safeValue(this.options, 'numSubscriptionsByStream');
140
- if (subscriptionsByStreams === undefined) {
141
- this.options['numSubscriptionsByStream'] = {};
142
- }
143
- const subscriptionsByStream = this.safeInteger(this.options['numSubscriptionsByStream'], stream, 0);
144
- const newNumSubscriptions = subscriptionsByStream + numSubscriptions;
145
- const subscriptionLimitByStream = this.safeInteger(this.options, 'subscriptionLimitByStream', 200);
146
- if (newNumSubscriptions > subscriptionLimitByStream) {
147
- throw new errors.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.');
148
- }
149
- this.options['numSubscriptionsByStream'][stream] = subscriptionsByStream + numSubscriptions;
150
- }
151
- return stream;
152
- }
153
- async watchOrderBook(symbol, limit = undefined, params = {}) {
154
- /**
155
- * @method
156
- * @name binance#watchOrderBook
157
- * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
158
- * @param {string} symbol unified symbol of the market to fetch the order book for
159
- * @param {int} [limit] the maximum amount of order book entries to return
160
- * @param {object} [params] extra parameters specific to the exchange API endpoint
161
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
162
- */
163
- //
164
- // todo add support for <levels>-snapshots (depth)
165
- // 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)
166
- // valid <levels> are 5, 10, or 20
167
- //
168
- // default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
169
- //
170
- // notice the differences between trading futures and spot trading
171
- // the algorithms use different urls in step 1
172
- // delta caching and merging also differs in steps 4, 5, 6
173
- //
174
- // spot/margin
175
- // https://binance-docs.github.io/apidocs/spot/en/#how-to-manage-a-local-order-book-correctly
176
- //
177
- // 1. Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth.
178
- // 2. Buffer the events you receive from the stream.
179
- // 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
180
- // 4. Drop any event where u is <= lastUpdateId in the snapshot.
181
- // 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1.
182
- // 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
183
- // 7. The data in each event is the absolute quantity for a price level.
184
- // 8. If the quantity is 0, remove the price level.
185
- // 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
186
- //
187
- // futures
188
- // https://binance-docs.github.io/apidocs/futures/en/#how-to-manage-a-local-order-book-correctly
189
- //
190
- // 1. Open a stream to wss://fstream.binance.com/stream?streams=btcusdt@depth.
191
- // 2. Buffer the events you receive from the stream. For same price, latest received update covers the previous one.
192
- // 3. Get a depth snapshot from https://fapi.binance.com/fapi/v1/depth?symbol=BTCUSDT&limit=1000 .
193
- // 4. Drop any event where u is < lastUpdateId in the snapshot.
194
- // 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
195
- // 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.
196
- // 7. The data in each event is the absolute quantity for a price level.
197
- // 8. If the quantity is 0, remove the price level.
198
- // 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
199
- //
200
- return await this.watchOrderBookForSymbols([symbol], limit, params);
201
- }
202
- async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
203
- /**
204
- * @method
205
- * @name binance#watchOrderBookForSymbols
206
- * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
207
- * @param {string[]} symbols unified array of symbols
208
- * @param {int} [limit] the maximum amount of order book entries to return
209
- * @param {object} [params] extra parameters specific to the exchange API endpoint
210
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
211
- */
212
- await this.loadMarkets();
213
- symbols = this.marketSymbols(symbols, undefined, false, true, true);
214
- const firstMarket = this.market(symbols[0]);
215
- let type = firstMarket['type'];
216
- if (firstMarket['contract']) {
217
- type = firstMarket['linear'] ? 'future' : 'delivery';
218
- }
219
- const name = 'depth';
220
- let streamHash = 'multipleOrderbook';
221
- if (symbols !== undefined) {
222
- const symbolsLength = symbols.length;
223
- if (symbolsLength > 200) {
224
- throw new errors.BadRequest(this.id + ' watchOrderBookForSymbols() accepts 200 symbols at most. To watch more symbols call watchOrderBookForSymbols() multiple times');
225
- }
226
- streamHash += '::' + symbols.join(',');
227
- }
228
- const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
229
- const subParams = [];
230
- const messageHashes = [];
231
- for (let i = 0; i < symbols.length; i++) {
232
- const symbol = symbols[i];
233
- const market = this.market(symbol);
234
- const messageHash = market['lowercaseId'] + '@' + name;
235
- messageHashes.push(messageHash);
236
- const symbolHash = messageHash + '@' + watchOrderBookRate + 'ms';
237
- subParams.push(symbolHash);
238
- }
239
- const messageHashesLength = messageHashes.length;
240
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, messageHashesLength);
241
- const requestId = this.requestId(url);
242
- const request = {
243
- 'method': 'SUBSCRIBE',
244
- 'params': subParams,
245
- 'id': requestId,
246
- };
247
- const subscription = {
248
- 'id': requestId.toString(),
249
- 'name': name,
250
- 'symbols': symbols,
251
- 'method': this.handleOrderBookSubscription,
252
- 'limit': limit,
253
- 'type': type,
254
- 'params': params,
255
- };
256
- const message = this.extend(request, params);
257
- const orderbook = await this.watchMultiple(url, messageHashes, message, messageHashes, subscription);
258
- return orderbook.limit();
259
- }
260
- async fetchOrderBookSnapshot(client, message, subscription) {
261
- const name = this.safeString(subscription, 'name');
262
- const symbol = this.safeString(subscription, 'symbol');
263
- const market = this.market(symbol);
264
- const messageHash = market['lowercaseId'] + '@' + name;
265
- try {
266
- const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
267
- const type = this.safeValue(subscription, 'type');
268
- const limit = this.safeInteger(subscription, 'limit', defaultLimit);
269
- const params = this.safeValue(subscription, 'params');
270
- // 3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 .
271
- // todo: this is a synch blocking call - make it async
272
- // default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
273
- const snapshot = await this.fetchRestOrderBookSafe(symbol, limit, params);
274
- const orderbook = this.safeValue(this.orderbooks, symbol);
275
- if (orderbook === undefined) {
276
- // if the orderbook is dropped before the snapshot is received
277
- return;
278
- }
279
- orderbook.reset(snapshot);
280
- // unroll the accumulated deltas
281
- const messages = orderbook.cache;
282
- for (let i = 0; i < messages.length; i++) {
283
- const messageItem = messages[i];
284
- const U = this.safeInteger(messageItem, 'U');
285
- const u = this.safeInteger(messageItem, 'u');
286
- const pu = this.safeInteger(messageItem, 'pu');
287
- if (type === 'future') {
288
- // 4. Drop any event where u is < lastUpdateId in the snapshot
289
- if (u < orderbook['nonce']) {
290
- continue;
291
- }
292
- // 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
293
- if ((U <= orderbook['nonce']) && (u >= orderbook['nonce']) || (pu === orderbook['nonce'])) {
294
- this.handleOrderBookMessage(client, messageItem, orderbook);
295
- }
296
- }
297
- else {
298
- // 4. Drop any event where u is <= lastUpdateId in the snapshot
299
- if (u <= orderbook['nonce']) {
300
- continue;
301
- }
302
- // 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
303
- if (((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce'])) {
304
- this.handleOrderBookMessage(client, messageItem, orderbook);
305
- }
306
- }
307
- }
308
- this.orderbooks[symbol] = orderbook;
309
- client.resolve(orderbook, messageHash);
310
- }
311
- catch (e) {
312
- delete client.subscriptions[messageHash];
313
- client.reject(e, messageHash);
314
- }
315
- }
316
- handleDelta(bookside, delta) {
317
- const price = this.safeFloat(delta, 0);
318
- const amount = this.safeFloat(delta, 1);
319
- bookside.store(price, amount);
320
- }
321
- handleDeltas(bookside, deltas) {
322
- for (let i = 0; i < deltas.length; i++) {
323
- this.handleDelta(bookside, deltas[i]);
324
- }
325
- }
326
- handleOrderBookMessage(client, message, orderbook) {
327
- const u = this.safeInteger(message, 'u');
328
- this.handleDeltas(orderbook['asks'], this.safeValue(message, 'a', []));
329
- this.handleDeltas(orderbook['bids'], this.safeValue(message, 'b', []));
330
- orderbook['nonce'] = u;
331
- const timestamp = this.safeInteger(message, 'E');
332
- orderbook['timestamp'] = timestamp;
333
- orderbook['datetime'] = this.iso8601(timestamp);
334
- return orderbook;
335
- }
336
- handleOrderBook(client, message) {
337
- //
338
- // initial snapshot is fetched with ccxt's fetchOrderBook
339
- // the feed does not include a snapshot, just the deltas
340
- //
341
- // {
342
- // "e": "depthUpdate", // Event type
343
- // "E": 1577554482280, // Event time
344
- // "s": "BNBBTC", // Symbol
345
- // "U": 157, // First update ID in event
346
- // "u": 160, // Final update ID in event
347
- // "b": [ // bids
348
- // [ "0.0024", "10" ], // price, size
349
- // ],
350
- // "a": [ // asks
351
- // [ "0.0026", "100" ], // price, size
352
- // ]
353
- // }
354
- //
355
- const isTestnetSpot = client.url.indexOf('testnet') > 0;
356
- const isSpotMainNet = client.url.indexOf('/stream.binance.') > 0;
357
- const isSpot = isTestnetSpot || isSpotMainNet;
358
- const marketType = isSpot ? 'spot' : 'contract';
359
- const marketId = this.safeString(message, 's');
360
- const market = this.safeMarket(marketId, undefined, undefined, marketType);
361
- const symbol = market['symbol'];
362
- const name = 'depth';
363
- const messageHash = market['lowercaseId'] + '@' + name;
364
- const orderbook = this.safeValue(this.orderbooks, symbol);
365
- if (orderbook === undefined) {
366
- //
367
- // https://github.com/ccxt/ccxt/issues/6672
368
- //
369
- // Sometimes Binance sends the first delta before the subscription
370
- // confirmation arrives. At that point the orderbook is not
371
- // initialized yet and the snapshot has not been requested yet
372
- // therefore it is safe to drop these premature messages.
373
- //
374
- return;
375
- }
376
- const nonce = this.safeInteger(orderbook, 'nonce');
377
- if (nonce === undefined) {
378
- // 2. Buffer the events you receive from the stream.
379
- orderbook.cache.push(message);
380
- }
381
- else {
382
- try {
383
- const U = this.safeInteger(message, 'U');
384
- const u = this.safeInteger(message, 'u');
385
- const pu = this.safeInteger(message, 'pu');
386
- if (pu === undefined) {
387
- // spot
388
- // 4. Drop any event where u is <= lastUpdateId in the snapshot
389
- if (u > orderbook['nonce']) {
390
- const timestamp = this.safeInteger(orderbook, 'timestamp');
391
- let conditional = undefined;
392
- if (timestamp === undefined) {
393
- // 5. The first processed event should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
394
- conditional = ((U - 1) <= orderbook['nonce']) && ((u - 1) >= orderbook['nonce']);
395
- }
396
- else {
397
- // 6. While listening to the stream, each new event's U should be equal to the previous event's u+1.
398
- conditional = ((U - 1) === orderbook['nonce']);
399
- }
400
- if (conditional) {
401
- this.handleOrderBookMessage(client, message, orderbook);
402
- if (nonce < orderbook['nonce']) {
403
- client.resolve(orderbook, messageHash);
404
- }
405
- }
406
- else {
407
- // todo: client.reject from handleOrderBookMessage properly
408
- throw new errors.ExchangeError(this.id + ' handleOrderBook received an out-of-order nonce');
409
- }
410
- }
411
- }
412
- else {
413
- // future
414
- // 4. Drop any event where u is < lastUpdateId in the snapshot
415
- if (u >= orderbook['nonce']) {
416
- // 5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
417
- // 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
418
- if ((U <= orderbook['nonce']) || (pu === orderbook['nonce'])) {
419
- this.handleOrderBookMessage(client, message, orderbook);
420
- if (nonce <= orderbook['nonce']) {
421
- client.resolve(orderbook, messageHash);
422
- }
423
- }
424
- else {
425
- // todo: client.reject from handleOrderBookMessage properly
426
- throw new errors.ExchangeError(this.id + ' handleOrderBook received an out-of-order nonce');
427
- }
428
- }
429
- }
430
- }
431
- catch (e) {
432
- delete this.orderbooks[symbol];
433
- delete client.subscriptions[messageHash];
434
- client.reject(e, messageHash);
435
- }
436
- }
437
- }
438
- handleOrderBookSubscription(client, message, subscription) {
439
- const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
440
- // const messageHash = this.safeString (subscription, 'messageHash');
441
- const symbolOfSubscription = this.safeString(subscription, 'symbol'); // watchOrderBook
442
- const symbols = this.safeValue(subscription, 'symbols', [symbolOfSubscription]); // watchOrderBookForSymbols
443
- const limit = this.safeInteger(subscription, 'limit', defaultLimit);
444
- // handle list of symbols
445
- for (let i = 0; i < symbols.length; i++) {
446
- const symbol = symbols[i];
447
- if (symbol in this.orderbooks) {
448
- delete this.orderbooks[symbol];
449
- }
450
- this.orderbooks[symbol] = this.orderBook({}, limit);
451
- subscription = this.extend(subscription, { 'symbol': symbol });
452
- // fetch the snapshot in a separate async call
453
- this.spawn(this.fetchOrderBookSnapshot, client, message, subscription);
454
- }
455
- }
456
- handleSubscriptionStatus(client, message) {
457
- //
458
- // {
459
- // "result": null,
460
- // "id": 1574649734450
461
- // }
462
- //
463
- const id = this.safeString(message, 'id');
464
- const subscriptionsById = this.indexBy(client.subscriptions, 'id');
465
- const subscription = this.safeValue(subscriptionsById, id, {});
466
- const method = this.safeValue(subscription, 'method');
467
- if (method !== undefined) {
468
- method.call(this, client, message, subscription);
469
- }
470
- return message;
471
- }
472
- async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
473
- /**
474
- * @method
475
- * @name binance#watchTradesForSymbols
476
- * @description get the list of most recent trades for a list of symbols
477
- * @param {string[]} symbols unified symbol of the market to fetch trades for
478
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
479
- * @param {int} [limit] the maximum amount of trades to fetch
480
- * @param {object} [params] extra parameters specific to the exchange API endpoint
481
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
482
- */
483
- await this.loadMarkets();
484
- symbols = this.marketSymbols(symbols, undefined, false, true, true);
485
- let streamHash = 'multipleTrades';
486
- if (symbols !== undefined) {
487
- const symbolsLength = symbols.length;
488
- if (symbolsLength > 200) {
489
- throw new errors.BadRequest(this.id + ' watchTradesForSymbols() accepts 200 symbols at most. To watch more symbols call watchTradesForSymbols() multiple times');
490
- }
491
- streamHash += '::' + symbols.join(',');
492
- }
493
- const options = this.safeValue(this.options, 'watchTradesForSymbols', {});
494
- const name = this.safeString(options, 'name', 'trade');
495
- const firstMarket = this.market(symbols[0]);
496
- let type = firstMarket['type'];
497
- if (firstMarket['contract']) {
498
- type = firstMarket['linear'] ? 'future' : 'delivery';
499
- }
500
- const subParams = [];
501
- for (let i = 0; i < symbols.length; i++) {
502
- const symbol = symbols[i];
503
- const market = this.market(symbol);
504
- const currentMessageHash = market['lowercaseId'] + '@' + name;
505
- subParams.push(currentMessageHash);
506
- }
507
- const query = this.omit(params, 'type');
508
- const subParamsLength = subParams.length;
509
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, streamHash, subParamsLength);
510
- const requestId = this.requestId(url);
511
- const request = {
512
- 'method': 'SUBSCRIBE',
513
- 'params': subParams,
514
- 'id': requestId,
515
- };
516
- const subscribe = {
517
- 'id': requestId,
518
- };
519
- const trades = await this.watchMultiple(url, subParams, this.extend(request, query), subParams, subscribe);
520
- if (this.newUpdates) {
521
- const first = this.safeValue(trades, 0);
522
- const tradeSymbol = this.safeString(first, 'symbol');
523
- limit = trades.getLimit(tradeSymbol, limit);
524
- }
525
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
526
- }
527
- async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
528
- /**
529
- * @method
530
- * @name binance#watchTrades
531
- * @description get the list of most recent trades for a particular symbol
532
- * @param {string} symbol unified symbol of the market to fetch trades for
533
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
534
- * @param {int} [limit] the maximum amount of trades to fetch
535
- * @param {object} [params] extra parameters specific to the exchange API endpoint
536
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
537
- */
538
- return await this.watchTradesForSymbols([symbol], since, limit, params);
539
- }
540
- parseTrade(trade, market = undefined) {
541
- //
542
- // public watchTrades
543
- //
544
- // {
545
- // "e": "trade", // event type
546
- // "E": 1579481530911, // event time
547
- // "s": "ETHBTC", // symbol
548
- // "t": 158410082, // trade id
549
- // "p": "0.01914100", // price
550
- // "q": "0.00700000", // quantity
551
- // "b": 586187049, // buyer order id
552
- // "a": 586186710, // seller order id
553
- // "T": 1579481530910, // trade time
554
- // "m": false, // is the buyer the market maker
555
- // "M": true // binance docs say it should be ignored
556
- // }
557
- //
558
- // {
559
- // "e": "aggTrade", // Event type
560
- // "E": 123456789, // Event time
561
- // "s": "BNBBTC", // Symbol
562
- // "a": 12345, // Aggregate trade ID
563
- // "p": "0.001", // Price
564
- // "q": "100", // Quantity
565
- // "f": 100, // First trade ID
566
- // "l": 105, // Last trade ID
567
- // "T": 123456785, // Trade time
568
- // "m": true, // Is the buyer the market maker?
569
- // "M": true // Ignore
570
- // }
571
- //
572
- // private watchMyTrades spot
573
- //
574
- // {
575
- // "e": "executionReport",
576
- // "E": 1611063861489,
577
- // "s": "BNBUSDT",
578
- // "c": "m4M6AD5MF3b1ERe65l4SPq",
579
- // "S": "BUY",
580
- // "o": "MARKET",
581
- // "f": "GTC",
582
- // "q": "2.00000000",
583
- // "p": "0.00000000",
584
- // "P": "0.00000000",
585
- // "F": "0.00000000",
586
- // "g": -1,
587
- // "C": '',
588
- // "x": "TRADE",
589
- // "X": "PARTIALLY_FILLED",
590
- // "r": "NONE",
591
- // "i": 1296882607,
592
- // "l": "0.33200000",
593
- // "z": "0.33200000",
594
- // "L": "46.86600000",
595
- // "n": "0.00033200",
596
- // "N": "BNB",
597
- // "T": 1611063861488,
598
- // "t": 109747654,
599
- // "I": 2696953381,
600
- // "w": false,
601
- // "m": false,
602
- // "M": true,
603
- // "O": 1611063861488,
604
- // "Z": "15.55951200",
605
- // "Y": "15.55951200",
606
- // "Q": "0.00000000"
607
- // }
608
- //
609
- // private watchMyTrades future/delivery
610
- //
611
- // {
612
- // "s": "BTCUSDT",
613
- // "c": "pb2jD6ZQHpfzSdUac8VqMK",
614
- // "S": "SELL",
615
- // "o": "MARKET",
616
- // "f": "GTC",
617
- // "q": "0.001",
618
- // "p": "0",
619
- // "ap": "33468.46000",
620
- // "sp": "0",
621
- // "x": "TRADE",
622
- // "X": "FILLED",
623
- // "i": 13351197194,
624
- // "l": "0.001",
625
- // "z": "0.001",
626
- // "L": "33468.46",
627
- // "n": "0.00027086",
628
- // "N": "BNB",
629
- // "T": 1612095165362,
630
- // "t": 458032604,
631
- // "b": "0",
632
- // "a": "0",
633
- // "m": false,
634
- // "R": false,
635
- // "wt": "CONTRACT_PRICE",
636
- // "ot": "MARKET",
637
- // "ps": "BOTH",
638
- // "cp": false,
639
- // "rp": "0.00335000",
640
- // "pP": false,
641
- // "si": 0,
642
- // "ss": 0
643
- // }
644
- //
645
- const executionType = this.safeString(trade, 'x');
646
- const isTradeExecution = (executionType === 'TRADE');
647
- if (!isTradeExecution) {
648
- return super.parseTrade(trade, market);
649
- }
650
- const id = this.safeString2(trade, 't', 'a');
651
- const timestamp = this.safeInteger(trade, 'T');
652
- const price = this.safeString2(trade, 'L', 'p');
653
- let amount = this.safeString(trade, 'q');
654
- if (isTradeExecution) {
655
- amount = this.safeString(trade, 'l', amount);
656
- }
657
- let cost = this.safeString(trade, 'Y');
658
- if (cost === undefined) {
659
- if ((price !== undefined) && (amount !== undefined)) {
660
- cost = Precise["default"].stringMul(price, amount);
661
- }
662
- }
663
- const marketId = this.safeString(trade, 's');
664
- const marketType = ('ps' in trade) ? 'contract' : 'spot';
665
- const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
666
- let side = this.safeStringLower(trade, 'S');
667
- let takerOrMaker = undefined;
668
- const orderId = this.safeString(trade, 'i');
669
- if ('m' in trade) {
670
- if (side === undefined) {
671
- side = trade['m'] ? 'sell' : 'buy'; // this is reversed intentionally
672
- }
673
- takerOrMaker = trade['m'] ? 'maker' : 'taker';
674
- }
675
- let fee = undefined;
676
- const feeCost = this.safeString(trade, 'n');
677
- if (feeCost !== undefined) {
678
- const feeCurrencyId = this.safeString(trade, 'N');
679
- const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
680
- fee = {
681
- 'cost': feeCost,
682
- 'currency': feeCurrencyCode,
683
- };
684
- }
685
- const type = this.safeStringLower(trade, 'o');
686
- return this.safeTrade({
687
- 'info': trade,
688
- 'timestamp': timestamp,
689
- 'datetime': this.iso8601(timestamp),
690
- 'symbol': symbol,
691
- 'id': id,
692
- 'order': orderId,
693
- 'type': type,
694
- 'takerOrMaker': takerOrMaker,
695
- 'side': side,
696
- 'price': price,
697
- 'amount': amount,
698
- 'cost': cost,
699
- 'fee': fee,
700
- });
701
- }
702
- handleTrade(client, message) {
703
- // the trade streams push raw trade information in real-time
704
- // each trade has a unique buyer and seller
705
- const isSpot = ((client.url.indexOf('wss://stream.binance.com') > -1) || (client.url.indexOf('/testnet.binance') > -1));
706
- const marketType = (isSpot) ? 'spot' : 'contract';
707
- const marketId = this.safeString(message, 's');
708
- const market = this.safeMarket(marketId, undefined, undefined, marketType);
709
- const symbol = market['symbol'];
710
- const lowerCaseId = this.safeStringLower(message, 's');
711
- const event = this.safeString(message, 'e');
712
- const messageHash = lowerCaseId + '@' + event;
713
- const trade = this.parseTrade(message, market);
714
- let tradesArray = this.safeValue(this.trades, symbol);
715
- if (tradesArray === undefined) {
716
- const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
717
- tradesArray = new Cache.ArrayCache(limit);
718
- }
719
- tradesArray.append(trade);
720
- this.trades[symbol] = tradesArray;
721
- client.resolve(tradesArray, messageHash);
722
- }
723
- async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
724
- /**
725
- * @method
726
- * @name binance#watchOHLCV
727
- * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
728
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
729
- * @param {string} timeframe the length of time each candle represents
730
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
731
- * @param {int} [limit] the maximum amount of candles to fetch
732
- * @param {object} [params] extra parameters specific to the exchange API endpoint
733
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
734
- */
735
- await this.loadMarkets();
736
- const market = this.market(symbol);
737
- let marketId = market['lowercaseId'];
738
- const interval = this.safeString(this.timeframes, timeframe, timeframe);
739
- const options = this.safeValue(this.options, 'watchOHLCV', {});
740
- const nameOption = this.safeString(options, 'name', 'kline');
741
- const name = this.safeString(params, 'name', nameOption);
742
- if (name === 'indexPriceKline') {
743
- marketId = marketId.replace('_perp', '');
744
- // weird behavior for index price kline we can't use the perp suffix
745
- }
746
- params = this.omit(params, 'name');
747
- const messageHash = marketId + '@' + name + '_' + interval;
748
- let type = market['type'];
749
- if (market['contract']) {
750
- type = market['linear'] ? 'future' : 'delivery';
751
- }
752
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
753
- const requestId = this.requestId(url);
754
- const request = {
755
- 'method': 'SUBSCRIBE',
756
- 'params': [
757
- messageHash,
758
- ],
759
- 'id': requestId,
760
- };
761
- const subscribe = {
762
- 'id': requestId,
763
- };
764
- const ohlcv = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
765
- if (this.newUpdates) {
766
- limit = ohlcv.getLimit(symbol, limit);
767
- }
768
- return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
769
- }
770
- handleOHLCV(client, message) {
771
- //
772
- // {
773
- // "e": "kline",
774
- // "E": 1579482921215,
775
- // "s": "ETHBTC",
776
- // "k": {
777
- // "t": 1579482900000,
778
- // "T": 1579482959999,
779
- // "s": "ETHBTC",
780
- // "i": "1m",
781
- // "f": 158411535,
782
- // "L": 158411550,
783
- // "o": "0.01913200",
784
- // "c": "0.01913500",
785
- // "h": "0.01913700",
786
- // "l": "0.01913200",
787
- // "v": "5.08400000",
788
- // "n": 16,
789
- // "x": false,
790
- // "q": "0.09728060",
791
- // "V": "3.30200000",
792
- // "Q": "0.06318500",
793
- // "B": "0"
794
- // }
795
- // }
796
- //
797
- let event = this.safeString(message, 'e');
798
- const eventMap = {
799
- 'indexPrice_kline': 'indexPriceKline',
800
- 'markPrice_kline': 'markPriceKline',
801
- };
802
- event = this.safeString(eventMap, event, event);
803
- const kline = this.safeValue(message, 'k');
804
- let marketId = this.safeString2(kline, 's', 'ps');
805
- if (event === 'indexPriceKline') {
806
- // indexPriceKline doesn't have the _PERP suffix
807
- marketId = this.safeString(message, 'ps');
808
- }
809
- const lowercaseMarketId = marketId.toLowerCase();
810
- const interval = this.safeString(kline, 'i');
811
- // use a reverse lookup in a static map instead
812
- const timeframe = this.findTimeframe(interval);
813
- const messageHash = lowercaseMarketId + '@' + event + '_' + interval;
814
- const parsed = [
815
- this.safeInteger(kline, 't'),
816
- this.safeFloat(kline, 'o'),
817
- this.safeFloat(kline, 'h'),
818
- this.safeFloat(kline, 'l'),
819
- this.safeFloat(kline, 'c'),
820
- this.safeFloat(kline, 'v'),
821
- ];
822
- const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
823
- const marketType = (isSpot) ? 'spot' : 'contract';
824
- const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
825
- this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
826
- let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
827
- if (stored === undefined) {
828
- const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
829
- stored = new Cache.ArrayCacheByTimestamp(limit);
830
- this.ohlcvs[symbol][timeframe] = stored;
831
- }
832
- stored.append(parsed);
833
- client.resolve(stored, messageHash);
834
- }
835
- async watchTicker(symbol, params = {}) {
836
- /**
837
- * @method
838
- * @name binance#watchTicker
839
- * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
840
- * @param {string} symbol unified symbol of the market to fetch the ticker for
841
- * @param {object} [params] extra parameters specific to the exchange API endpoint
842
- * @param {string} [params.name] stream to use can be ticker or bookTicker
843
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
844
- */
845
- await this.loadMarkets();
846
- const market = this.market(symbol);
847
- const marketId = market['lowercaseId'];
848
- let type = market['type'];
849
- if (market['contract']) {
850
- type = market['linear'] ? 'future' : 'delivery';
851
- }
852
- const options = this.safeValue(this.options, 'watchTicker', {});
853
- let name = this.safeString(options, 'name', 'ticker');
854
- name = this.safeString(params, 'name', name);
855
- params = this.omit(params, 'name');
856
- const messageHash = marketId + '@' + name;
857
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
858
- const requestId = this.requestId(url);
859
- const request = {
860
- 'method': 'SUBSCRIBE',
861
- 'params': [
862
- messageHash,
863
- ],
864
- 'id': requestId,
865
- };
866
- const subscribe = {
867
- 'id': requestId,
868
- };
869
- return await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
870
- }
871
- async watchTickers(symbols = undefined, params = {}) {
872
- /**
873
- * @method
874
- * @name binance#watchTickers
875
- * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
876
- * @param {string[]} symbols unified symbol of the market to fetch the ticker for
877
- * @param {object} [params] extra parameters specific to the exchange API endpoint
878
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
879
- */
880
- await this.loadMarkets();
881
- symbols = this.marketSymbols(symbols, undefined, true, true, true);
882
- const marketIds = this.marketIds(symbols);
883
- let market = undefined;
884
- let type = undefined;
885
- if (symbols !== undefined) {
886
- market = this.market(symbols[0]);
887
- }
888
- [type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
889
- let subType = undefined;
890
- [subType, params] = this.handleSubTypeAndParams('watchTickers', market, params);
891
- if (this.isLinear(type, subType)) {
892
- type = 'future';
893
- }
894
- else if (this.isInverse(type, subType)) {
895
- type = 'delivery';
896
- }
897
- const options = this.safeValue(this.options, 'watchTickers', {});
898
- let name = this.safeString(options, 'name', 'ticker');
899
- name = this.safeString(params, 'name', name);
900
- params = this.omit(params, 'name');
901
- let wsParams = [];
902
- let messageHash = 'tickers';
903
- if (symbols !== undefined) {
904
- messageHash = 'tickers::' + symbols.join(',');
905
- }
906
- if (name === 'bookTicker') {
907
- if (marketIds === undefined) {
908
- throw new errors.ArgumentsRequired(this.id + ' watchTickers() requires symbols for bookTicker');
909
- }
910
- // simulate watchTickers with subscribe multiple individual bookTicker topic
911
- for (let i = 0; i < marketIds.length; i++) {
912
- wsParams.push(marketIds[i].toLowerCase() + '@bookTicker');
913
- }
914
- }
915
- else {
916
- wsParams = [
917
- '!' + name + '@arr',
918
- ];
919
- }
920
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
921
- const requestId = this.requestId(url);
922
- const request = {
923
- 'method': 'SUBSCRIBE',
924
- 'params': wsParams,
925
- 'id': requestId,
926
- };
927
- const subscribe = {
928
- 'id': requestId,
929
- };
930
- const newTickers = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
931
- if (this.newUpdates) {
932
- return newTickers;
933
- }
934
- return this.filterByArray(this.tickers, 'symbol', symbols);
935
- }
936
- parseWsTicker(message, marketType) {
937
- //
938
- // ticker
939
- // {
940
- // "e": "24hrTicker", // event type
941
- // "E": 1579485598569, // event time
942
- // "s": "ETHBTC", // symbol
943
- // "p": "-0.00004000", // price change
944
- // "P": "-0.209", // price change percent
945
- // "w": "0.01920495", // weighted average price
946
- // "x": "0.01916500", // the price of the first trade before the 24hr rolling window
947
- // "c": "0.01912500", // last (closing) price
948
- // "Q": "0.10400000", // last quantity
949
- // "b": "0.01912200", // best bid
950
- // "B": "4.10400000", // best bid quantity
951
- // "a": "0.01912500", // best ask
952
- // "A": "0.00100000", // best ask quantity
953
- // "o": "0.01916500", // open price
954
- // "h": "0.01956500", // high price
955
- // "l": "0.01887700", // low price
956
- // "v": "173518.11900000", // base volume
957
- // "q": "3332.40703994", // quote volume
958
- // "O": 1579399197842, // open time
959
- // "C": 1579485597842, // close time
960
- // "F": 158251292, // first trade id
961
- // "L": 158414513, // last trade id
962
- // "n": 163222, // total number of trades
963
- // }
964
- //
965
- // miniTicker
966
- // {
967
- // "e": "24hrMiniTicker",
968
- // "E": 1671617114585,
969
- // "s": "MOBBUSD",
970
- // "c": "0.95900000",
971
- // "o": "0.91200000",
972
- // "h": "1.04000000",
973
- // "l": "0.89400000",
974
- // "v": "2109995.32000000",
975
- // "q": "2019254.05788000"
976
- // }
977
- //
978
- let event = this.safeString(message, 'e', 'bookTicker');
979
- if (event === '24hrTicker') {
980
- event = 'ticker';
981
- }
982
- let timestamp = undefined;
983
- if (event === 'bookTicker') {
984
- // take the event timestamp, if available, for spot tickers it is not
985
- timestamp = this.safeInteger(message, 'E');
986
- }
987
- else {
988
- // take the timestamp of the closing price for candlestick streams
989
- timestamp = this.safeInteger(message, 'C');
990
- }
991
- const marketId = this.safeString(message, 's');
992
- const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
993
- const market = this.safeMarket(marketId, undefined, undefined, marketType);
994
- const last = this.safeString(message, 'c');
995
- return this.safeTicker({
996
- 'symbol': symbol,
997
- 'timestamp': timestamp,
998
- 'datetime': this.iso8601(timestamp),
999
- 'high': this.safeString(message, 'h'),
1000
- 'low': this.safeString(message, 'l'),
1001
- 'bid': this.safeString(message, 'b'),
1002
- 'bidVolume': this.safeString(message, 'B'),
1003
- 'ask': this.safeString(message, 'a'),
1004
- 'askVolume': this.safeString(message, 'A'),
1005
- 'vwap': this.safeString(message, 'w'),
1006
- 'open': this.safeString(message, 'o'),
1007
- 'close': last,
1008
- 'last': last,
1009
- 'previousClose': this.safeString(message, 'x'),
1010
- 'change': this.safeString(message, 'p'),
1011
- 'percentage': this.safeString(message, 'P'),
1012
- 'average': undefined,
1013
- 'baseVolume': this.safeString(message, 'v'),
1014
- 'quoteVolume': this.safeString(message, 'q'),
1015
- 'info': message,
1016
- }, market);
1017
- }
1018
- handleTicker(client, message) {
1019
- //
1020
- // 24hr rolling window ticker statistics for a single symbol
1021
- // These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs
1022
- // Update Speed 1000ms
1023
- //
1024
- // {
1025
- // "e": "24hrTicker", // event type
1026
- // "E": 1579485598569, // event time
1027
- // "s": "ETHBTC", // symbol
1028
- // "p": "-0.00004000", // price change
1029
- // "P": "-0.209", // price change percent
1030
- // "w": "0.01920495", // weighted average price
1031
- // "x": "0.01916500", // the price of the first trade before the 24hr rolling window
1032
- // "c": "0.01912500", // last (closing) price
1033
- // "Q": "0.10400000", // last quantity
1034
- // "b": "0.01912200", // best bid
1035
- // "B": "4.10400000", // best bid quantity
1036
- // "a": "0.01912500", // best ask
1037
- // "A": "0.00100000", // best ask quantity
1038
- // "o": "0.01916500", // open price
1039
- // "h": "0.01956500", // high price
1040
- // "l": "0.01887700", // low price
1041
- // "v": "173518.11900000", // base volume
1042
- // "q": "3332.40703994", // quote volume
1043
- // "O": 1579399197842, // open time
1044
- // "C": 1579485597842, // close time
1045
- // "F": 158251292, // first trade id
1046
- // "L": 158414513, // last trade id
1047
- // "n": 163222, // total number of trades
1048
- // }
1049
- //
1050
- let event = this.safeString(message, 'e', 'bookTicker');
1051
- if (event === '24hrTicker') {
1052
- event = 'ticker';
1053
- }
1054
- else if (event === '24hrMiniTicker') {
1055
- event = 'miniTicker';
1056
- }
1057
- const wsMarketId = this.safeStringLower(message, 's');
1058
- const messageHash = wsMarketId + '@' + event;
1059
- const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
1060
- const marketType = (isSpot) ? 'spot' : 'contract';
1061
- const result = this.parseWsTicker(message, marketType);
1062
- const symbol = result['symbol'];
1063
- this.tickers[symbol] = result;
1064
- client.resolve(result, messageHash);
1065
- if (event === 'bookTicker') {
1066
- // watch bookTickers
1067
- client.resolve(result, '!' + 'bookTicker@arr');
1068
- const messageHashes = this.findMessageHashes(client, 'tickers::');
1069
- for (let i = 0; i < messageHashes.length; i++) {
1070
- const currentMessageHash = messageHashes[i];
1071
- const parts = currentMessageHash.split('::');
1072
- const symbolsString = parts[1];
1073
- const symbols = symbolsString.split(',');
1074
- if (this.inArray(symbol, symbols)) {
1075
- client.resolve(result, currentMessageHash);
1076
- }
1077
- }
1078
- }
1079
- }
1080
- handleTickers(client, message) {
1081
- const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
1082
- const marketType = (isSpot) ? 'spot' : 'contract';
1083
- let rawTickers = [];
1084
- const newTickers = {};
1085
- if (Array.isArray(message)) {
1086
- rawTickers = message;
1087
- }
1088
- else {
1089
- rawTickers.push(message);
1090
- }
1091
- for (let i = 0; i < rawTickers.length; i++) {
1092
- const ticker = rawTickers[i];
1093
- const result = this.parseWsTicker(ticker, marketType);
1094
- const symbol = result['symbol'];
1095
- this.tickers[symbol] = result;
1096
- newTickers[symbol] = result;
1097
- }
1098
- const messageHashes = this.findMessageHashes(client, 'tickers::');
1099
- for (let i = 0; i < messageHashes.length; i++) {
1100
- const messageHash = messageHashes[i];
1101
- const parts = messageHash.split('::');
1102
- const symbolsString = parts[1];
1103
- const symbols = symbolsString.split(',');
1104
- const tickers = this.filterByArray(newTickers, 'symbol', symbols);
1105
- const tickersSymbols = Object.keys(tickers);
1106
- const numTickers = tickersSymbols.length;
1107
- if (numTickers > 0) {
1108
- client.resolve(tickers, messageHash);
1109
- }
1110
- }
1111
- client.resolve(newTickers, 'tickers');
1112
- }
1113
- signParams(params = {}) {
1114
- this.checkRequiredCredentials();
1115
- let extendedParams = this.extend({
1116
- 'timestamp': this.nonce(),
1117
- 'apiKey': this.apiKey,
1118
- }, params);
1119
- const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
1120
- if (defaultRecvWindow !== undefined) {
1121
- params['recvWindow'] = defaultRecvWindow;
1122
- }
1123
- const recvWindow = this.safeInteger(params, 'recvWindow');
1124
- if (recvWindow !== undefined) {
1125
- params['recvWindow'] = recvWindow;
1126
- }
1127
- extendedParams = this.keysort(extendedParams);
1128
- const query = this.urlencode(extendedParams);
1129
- let signature = undefined;
1130
- if (this.secret.indexOf('PRIVATE KEY') > -1) {
1131
- if (this.secret.length > 120) {
1132
- signature = rsa.rsa(query, this.secret, sha256.sha256);
1133
- }
1134
- else {
1135
- signature = crypto.eddsa(this.encode(query), this.secret, ed25519.ed25519);
1136
- }
1137
- }
1138
- else {
1139
- signature = this.hmac(this.encode(query), this.encode(this.secret), sha256.sha256);
1140
- }
1141
- extendedParams['signature'] = signature;
1142
- return extendedParams;
1143
- }
1144
- async authenticate(params = {}) {
1145
- const time = this.milliseconds();
1146
- let query = undefined;
1147
- let type = undefined;
1148
- [type, query] = this.handleMarketTypeAndParams('authenticate', undefined, params);
1149
- let subType = undefined;
1150
- [subType, query] = this.handleSubTypeAndParams('authenticate', undefined, query);
1151
- if (this.isLinear(type, subType)) {
1152
- type = 'future';
1153
- }
1154
- else if (this.isInverse(type, subType)) {
1155
- type = 'delivery';
1156
- }
1157
- let marginMode = undefined;
1158
- [marginMode, query] = this.handleMarginModeAndParams('authenticate', query);
1159
- const isIsolatedMargin = (marginMode === 'isolated');
1160
- const isCrossMargin = (marginMode === 'cross') || (marginMode === undefined);
1161
- const symbol = this.safeString(query, 'symbol');
1162
- query = this.omit(query, 'symbol');
1163
- const options = this.safeValue(this.options, type, {});
1164
- const lastAuthenticatedTime = this.safeInteger(options, 'lastAuthenticatedTime', 0);
1165
- const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
1166
- const delay = this.sum(listenKeyRefreshRate, 10000);
1167
- if (time - lastAuthenticatedTime > delay) {
1168
- let response = undefined;
1169
- if (type === 'future') {
1170
- response = await this.fapiPrivatePostListenKey(query);
1171
- }
1172
- else if (type === 'delivery') {
1173
- response = await this.dapiPrivatePostListenKey(query);
1174
- }
1175
- else if (type === 'margin' && isCrossMargin) {
1176
- response = await this.sapiPostUserDataStream(query);
1177
- }
1178
- else if (isIsolatedMargin) {
1179
- if (symbol === undefined) {
1180
- throw new errors.ArgumentsRequired(this.id + ' authenticate() requires a symbol argument for isolated margin mode');
1181
- }
1182
- const marketId = this.marketId(symbol);
1183
- query = this.extend(query, { 'symbol': marketId });
1184
- response = await this.sapiPostUserDataStreamIsolated(query);
1185
- }
1186
- else {
1187
- response = await this.publicPostUserDataStream(query);
1188
- }
1189
- this.options[type] = this.extend(options, {
1190
- 'listenKey': this.safeString(response, 'listenKey'),
1191
- 'lastAuthenticatedTime': time,
1192
- });
1193
- this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
1194
- }
1195
- }
1196
- async keepAliveListenKey(params = {}) {
1197
- // https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot
1198
- let type = this.safeString2(this.options, 'defaultType', 'authenticate', 'spot');
1199
- type = this.safeString(params, 'type', type);
1200
- const subTypeInfo = this.handleSubTypeAndParams('keepAliveListenKey', undefined, params);
1201
- const subType = subTypeInfo[0];
1202
- if (this.isLinear(type, subType)) {
1203
- type = 'future';
1204
- }
1205
- else if (this.isInverse(type, subType)) {
1206
- type = 'delivery';
1207
- }
1208
- const options = this.safeValue(this.options, type, {});
1209
- const listenKey = this.safeString(options, 'listenKey');
1210
- if (listenKey === undefined) {
1211
- // A network error happened: we can't renew a listen key that does not exist.
1212
- return;
1213
- }
1214
- const request = {};
1215
- const symbol = this.safeString(params, 'symbol');
1216
- const sendParams = this.omit(params, ['type', 'symbol']);
1217
- const time = this.milliseconds();
1218
- try {
1219
- if (type === 'future') {
1220
- await this.fapiPrivatePutListenKey(this.extend(request, sendParams));
1221
- }
1222
- else if (type === 'delivery') {
1223
- await this.dapiPrivatePutListenKey(this.extend(request, sendParams));
1224
- }
1225
- else {
1226
- request['listenKey'] = listenKey;
1227
- if (type === 'margin') {
1228
- request['symbol'] = symbol;
1229
- await this.sapiPutUserDataStream(this.extend(request, sendParams));
1230
- }
1231
- else {
1232
- await this.publicPutUserDataStream(this.extend(request, sendParams));
1233
- }
1234
- }
1235
- }
1236
- catch (error) {
1237
- const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
1238
- const client = this.client(url);
1239
- const messageHashes = Object.keys(client.futures);
1240
- for (let i = 0; i < messageHashes.length; i++) {
1241
- const messageHash = messageHashes[i];
1242
- client.reject(error, messageHash);
1243
- }
1244
- this.options[type] = this.extend(options, {
1245
- 'listenKey': undefined,
1246
- 'lastAuthenticatedTime': 0,
1247
- });
1248
- return;
1249
- }
1250
- this.options[type] = this.extend(options, {
1251
- 'listenKey': listenKey,
1252
- 'lastAuthenticatedTime': time,
1253
- });
1254
- // whether or not to schedule another listenKey keepAlive request
1255
- const clients = Object.values(this.clients);
1256
- const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
1257
- for (let i = 0; i < clients.length; i++) {
1258
- const client = clients[i];
1259
- const subscriptionKeys = Object.keys(client.subscriptions);
1260
- for (let j = 0; j < subscriptionKeys.length; j++) {
1261
- const subscribeType = subscriptionKeys[j];
1262
- if (subscribeType === type) {
1263
- return this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
1264
- }
1265
- }
1266
- }
1267
- }
1268
- setBalanceCache(client, type) {
1269
- if (type in client.subscriptions) {
1270
- return undefined;
1271
- }
1272
- const options = this.safeValue(this.options, 'watchBalance');
1273
- const fetchBalanceSnapshot = this.safeValue(options, 'fetchBalanceSnapshot', false);
1274
- if (fetchBalanceSnapshot) {
1275
- const messageHash = type + ':fetchBalanceSnapshot';
1276
- if (!(messageHash in client.futures)) {
1277
- client.future(messageHash);
1278
- this.spawn(this.loadBalanceSnapshot, client, messageHash, type);
1279
- }
1280
- }
1281
- else {
1282
- this.balance[type] = {};
1283
- }
1284
- }
1285
- async loadBalanceSnapshot(client, messageHash, type) {
1286
- const response = await this.fetchBalance({ 'type': type });
1287
- this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
1288
- // don't remove the future from the .futures cache
1289
- const future = client.futures[messageHash];
1290
- future.resolve();
1291
- client.resolve(this.balance[type], type + ':balance');
1292
- }
1293
- async fetchBalanceWs(params = {}) {
1294
- /**
1295
- * @method
1296
- * @name binance#fetchBalanceWs
1297
- * @description fetch balance and get the amount of funds available for trading or funds locked in orders
1298
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#account-information-user_data
1299
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1300
- * @param {string|undefined} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot'
1301
- * @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
1302
- * @param {string[]|undefined} [params.symbols] unified market symbols, only used in isolated margin mode
1303
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1304
- */
1305
- await this.loadMarkets();
1306
- const url = this.urls['api']['ws']['ws'];
1307
- const requestId = this.requestId(url);
1308
- const messageHash = requestId.toString();
1309
- let returnRateLimits = false;
1310
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
1311
- const payload = {
1312
- 'returnRateLimits': returnRateLimits,
1313
- };
1314
- const message = {
1315
- 'id': messageHash,
1316
- 'method': 'account.status',
1317
- 'params': this.signParams(this.extend(payload, params)),
1318
- };
1319
- const subscription = {
1320
- 'method': this.handleBalanceWs,
1321
- };
1322
- return await this.watch(url, messageHash, message, messageHash, subscription);
1323
- }
1324
- handleBalanceWs(client, message) {
1325
- //
1326
- // {
1327
- // "id": "605a6d20-6588-4cb9-afa0-b0ab087507ba",
1328
- // "status": 200,
1329
- // "result": {
1330
- // "makerCommission": 15,
1331
- // "takerCommission": 15,
1332
- // "buyerCommission": 0,
1333
- // "sellerCommission": 0,
1334
- // "canTrade": true,
1335
- // "canWithdraw": true,
1336
- // "canDeposit": true,
1337
- // "commissionRates": {
1338
- // "maker": "0.00150000",
1339
- // "taker": "0.00150000",
1340
- // "buyer": "0.00000000",
1341
- // "seller": "0.00000000"
1342
- // },
1343
- // "brokered": false,
1344
- // "requireSelfTradePrevention": false,
1345
- // "updateTime": 1660801833000,
1346
- // "accountType": "SPOT",
1347
- // "balances": [{
1348
- // "asset": "BNB",
1349
- // "free": "0.00000000",
1350
- // "locked": "0.00000000"
1351
- // },
1352
- // {
1353
- // "asset": "BTC",
1354
- // "free": "1.3447112",
1355
- // "locked": "0.08600000"
1356
- // },
1357
- // {
1358
- // "asset": "USDT",
1359
- // "free": "1021.21000000",
1360
- // "locked": "0.00000000"
1361
- // }
1362
- // ],
1363
- // "permissions": [
1364
- // "SPOT"
1365
- // ]
1366
- // }
1367
- // }
1368
- //
1369
- const messageHash = this.safeString(message, 'id');
1370
- const result = this.safeValue(message, 'result', {});
1371
- const parsedBalances = this.parseBalance(result, 'spot');
1372
- client.resolve(parsedBalances, messageHash);
1373
- }
1374
- async watchBalance(params = {}) {
1375
- /**
1376
- * @method
1377
- * @name binance#watchBalance
1378
- * @description watch balance and get the amount of funds available for trading or funds locked in orders
1379
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1380
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1381
- */
1382
- await this.loadMarkets();
1383
- await this.authenticate(params);
1384
- const defaultType = this.safeString(this.options, 'defaultType', 'spot');
1385
- let type = this.safeString(params, 'type', defaultType);
1386
- let subType = undefined;
1387
- [subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
1388
- if (this.isLinear(type, subType)) {
1389
- type = 'future';
1390
- }
1391
- else if (this.isInverse(type, subType)) {
1392
- type = 'delivery';
1393
- }
1394
- const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
1395
- const client = this.client(url);
1396
- this.setBalanceCache(client, type);
1397
- this.setPositionsCache(client, type);
1398
- const options = this.safeValue(this.options, 'watchBalance');
1399
- const fetchBalanceSnapshot = this.safeValue(options, 'fetchBalanceSnapshot', false);
1400
- const awaitBalanceSnapshot = this.safeValue(options, 'awaitBalanceSnapshot', true);
1401
- if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
1402
- await client.future(type + ':fetchBalanceSnapshot');
1403
- }
1404
- const messageHash = type + ':balance';
1405
- const message = undefined;
1406
- return await this.watch(url, messageHash, message, type);
1407
- }
1408
- handleBalance(client, message) {
1409
- //
1410
- // sent upon a balance update not related to orders
1411
- //
1412
- // {
1413
- // "e": "balanceUpdate",
1414
- // "E": 1629352505586,
1415
- // "a": "IOTX",
1416
- // "d": "0.43750000",
1417
- // "T": 1629352505585
1418
- // }
1419
- //
1420
- // sent upon creating or filling an order
1421
- //
1422
- // {
1423
- // "e": "outboundAccountPosition", // Event type
1424
- // "E": 1564034571105, // Event Time
1425
- // "u": 1564034571073, // Time of last account update
1426
- // "B": [ // Balances Array
1427
- // {
1428
- // "a": "ETH", // Asset
1429
- // "f": "10000.000000", // Free
1430
- // "l": "0.000000" // Locked
1431
- // }
1432
- // ]
1433
- // }
1434
- //
1435
- // future/delivery
1436
- //
1437
- // {
1438
- // "e": "ACCOUNT_UPDATE", // Event Type
1439
- // "E": 1564745798939, // Event Time
1440
- // "T": 1564745798938 , // Transaction
1441
- // "i": "SfsR", // Account Alias
1442
- // "a": { // Update Data
1443
- // "m":"ORDER", // Event reason type
1444
- // "B":[ // Balances
1445
- // {
1446
- // "a":"BTC", // Asset
1447
- // "wb":"122624.12345678", // Wallet Balance
1448
- // "cw":"100.12345678" // Cross Wallet Balance
1449
- // },
1450
- // ],
1451
- // "P":[
1452
- // {
1453
- // "s":"BTCUSD_200925", // Symbol
1454
- // "pa":"0", // Position Amount
1455
- // "ep":"0.0", // Entry Price
1456
- // "cr":"200", // (Pre-fee) Accumulated Realized
1457
- // "up":"0", // Unrealized PnL
1458
- // "mt":"isolated", // Margin Type
1459
- // "iw":"0.00000000", // Isolated Wallet (if isolated position)
1460
- // "ps":"BOTH" // Position Side
1461
- // },
1462
- // ]
1463
- // }
1464
- // }
1465
- //
1466
- const wallet = this.safeValue(this.options, 'wallet', 'wb'); // cw for cross wallet
1467
- // each account is connected to a different endpoint
1468
- // and has exactly one subscriptionhash which is the account type
1469
- const subscriptions = Object.keys(client.subscriptions);
1470
- const accountType = subscriptions[0];
1471
- const messageHash = accountType + ':balance';
1472
- if (this.balance[accountType] === undefined) {
1473
- this.balance[accountType] = {};
1474
- }
1475
- this.balance[accountType]['info'] = message;
1476
- const event = this.safeString(message, 'e');
1477
- if (event === 'balanceUpdate') {
1478
- const currencyId = this.safeString(message, 'a');
1479
- const code = this.safeCurrencyCode(currencyId);
1480
- const account = this.account();
1481
- const delta = this.safeString(message, 'd');
1482
- if (code in this.balance[accountType]) {
1483
- let previousValue = this.balance[accountType][code]['free'];
1484
- if (typeof previousValue !== 'string') {
1485
- previousValue = this.numberToString(previousValue);
1486
- }
1487
- account['free'] = Precise["default"].stringAdd(previousValue, delta);
1488
- }
1489
- else {
1490
- account['free'] = delta;
1491
- }
1492
- this.balance[accountType][code] = account;
1493
- }
1494
- else {
1495
- message = this.safeValue(message, 'a', message);
1496
- const B = this.safeValue(message, 'B');
1497
- for (let i = 0; i < B.length; i++) {
1498
- const entry = B[i];
1499
- const currencyId = this.safeString(entry, 'a');
1500
- const code = this.safeCurrencyCode(currencyId);
1501
- const account = this.account();
1502
- account['free'] = this.safeString(entry, 'f');
1503
- account['used'] = this.safeString(entry, 'l');
1504
- account['total'] = this.safeString(entry, wallet);
1505
- this.balance[accountType][code] = account;
1506
- }
1507
- }
1508
- const timestamp = this.safeInteger(message, 'E');
1509
- this.balance[accountType]['timestamp'] = timestamp;
1510
- this.balance[accountType]['datetime'] = this.iso8601(timestamp);
1511
- this.balance[accountType] = this.safeBalance(this.balance[accountType]);
1512
- client.resolve(this.balance[accountType], messageHash);
1513
- }
1514
- checkIsSpot(method, symbol, params = {}) {
1515
- /**
1516
- * @method
1517
- * @ignore
1518
- * @description checks if symbols is a spot market if not throws an error
1519
- * @param {string} method name of the method to be checked
1520
- * @param {string} symbol symbol or marketId of the market to be checked
1521
- */
1522
- if (symbol === undefined) {
1523
- const type = this.safeString(params, 'type', 'spot');
1524
- const defaultType = this.safeString(this.options, 'defaultType', type);
1525
- if (defaultType === 'spot') {
1526
- return;
1527
- }
1528
- throw new errors.BadRequest(this.id + ' ' + method + ' only supports spot markets');
1529
- }
1530
- const market = this.market(symbol);
1531
- if (!market['spot']) {
1532
- throw new errors.BadRequest(this.id + ' ' + method + ' only supports spot markets');
1533
- }
1534
- }
1535
- async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
1536
- /**
1537
- * @method
1538
- * @name binance#createOrderWs
1539
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#place-new-order-trade
1540
- * @description create a trade order
1541
- * @param {string} symbol unified symbol of the market to create an order in
1542
- * @param {string} type 'market' or 'limit'
1543
- * @param {string} side 'buy' or 'sell'
1544
- * @param {float} amount how much of currency you want to trade in units of base currency
1545
- * @param {float|undefined} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1546
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1547
- * @param {boolean} params.test test order, default false
1548
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1549
- */
1550
- await this.loadMarkets();
1551
- this.checkIsSpot('createOrderWs', symbol, params);
1552
- const url = this.urls['api']['ws']['ws'];
1553
- const requestId = this.requestId(url);
1554
- const messageHash = requestId.toString();
1555
- const sor = this.safeValue2(params, 'sor', 'SOR', false);
1556
- params = this.omit(params, 'sor', 'SOR');
1557
- const payload = this.createOrderRequest(symbol, type, side, amount, price, params);
1558
- let returnRateLimits = false;
1559
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'createOrderWs', 'returnRateLimits', false);
1560
- payload['returnRateLimits'] = returnRateLimits;
1561
- const test = this.safeValue(params, 'test', false);
1562
- params = this.omit(params, 'test');
1563
- const message = {
1564
- 'id': messageHash,
1565
- 'method': 'order.place',
1566
- 'params': this.signParams(this.extend(payload, params)),
1567
- };
1568
- if (test) {
1569
- if (sor) {
1570
- message['method'] = 'sor.order.test';
1571
- }
1572
- else {
1573
- message['method'] = 'order.test';
1574
- }
1575
- }
1576
- const subscription = {
1577
- 'method': this.handleOrderWs,
1578
- };
1579
- return await this.watch(url, messageHash, message, messageHash, subscription);
1580
- }
1581
- handleOrderWs(client, message) {
1582
- //
1583
- // {
1584
- // "id": 1,
1585
- // "status": 200,
1586
- // "result": {
1587
- // "symbol": "BTCUSDT",
1588
- // "orderId": 7663053,
1589
- // "orderListId": -1,
1590
- // "clientOrderId": "x-R4BD3S82d8959d0f5114499487a614",
1591
- // "transactTime": 1687642291434,
1592
- // "price": "25000.00000000",
1593
- // "origQty": "0.00100000",
1594
- // "executedQty": "0.00000000",
1595
- // "cummulativeQuoteQty": "0.00000000",
1596
- // "status": "NEW",
1597
- // "timeInForce": "GTC",
1598
- // "type": "LIMIT",
1599
- // "side": "BUY",
1600
- // "workingTime": 1687642291434,
1601
- // "fills": [],
1602
- // "selfTradePreventionMode": "NONE"
1603
- // },
1604
- // "rateLimits": [
1605
- // {
1606
- // "rateLimitType": "ORDERS",
1607
- // "interval": "SECOND",
1608
- // "intervalNum": 10,
1609
- // "limit": 50,
1610
- // "count": 1
1611
- // },
1612
- // {
1613
- // "rateLimitType": "ORDERS",
1614
- // "interval": "DAY",
1615
- // "intervalNum": 1,
1616
- // "limit": 160000,
1617
- // "count": 1
1618
- // },
1619
- // {
1620
- // "rateLimitType": "REQUEST_WEIGHT",
1621
- // "interval": "MINUTE",
1622
- // "intervalNum": 1,
1623
- // "limit": 1200,
1624
- // "count": 12
1625
- // }
1626
- // ]
1627
- // }
1628
- //
1629
- const messageHash = this.safeString(message, 'id');
1630
- const result = this.safeValue(message, 'result', {});
1631
- const order = this.parseOrder(result);
1632
- client.resolve(order, messageHash);
1633
- }
1634
- handleOrdersWs(client, message) {
1635
- //
1636
- // {
1637
- // "id": 1,
1638
- // "status": 200,
1639
- // "result": [{
1640
- // "symbol": "BTCUSDT",
1641
- // "orderId": 7665584,
1642
- // "orderListId": -1,
1643
- // "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
1644
- // "price": "26000.00000000",
1645
- // "origQty": "0.00100000",
1646
- // "executedQty": "0.00000000",
1647
- // "cummulativeQuoteQty": "0.00000000",
1648
- // "status": "NEW",
1649
- // "timeInForce": "GTC",
1650
- // "type": "LIMIT",
1651
- // "side": "BUY",
1652
- // "stopPrice": "0.00000000",
1653
- // "icebergQty": "0.00000000",
1654
- // "time": 1687642884646,
1655
- // "updateTime": 1687642884646,
1656
- // "isWorking": true,
1657
- // "workingTime": 1687642884646,
1658
- // "origQuoteOrderQty": "0.00000000",
1659
- // "selfTradePreventionMode": "NONE"
1660
- // },
1661
- // ...
1662
- // ],
1663
- // "rateLimits": [{
1664
- // "rateLimitType": "REQUEST_WEIGHT",
1665
- // "interval": "MINUTE",
1666
- // "intervalNum": 1,
1667
- // "limit": 1200,
1668
- // "count": 14
1669
- // }]
1670
- // }
1671
- //
1672
- const messageHash = this.safeString(message, 'id');
1673
- const result = this.safeValue(message, 'result', []);
1674
- const orders = this.parseOrders(result);
1675
- client.resolve(orders, messageHash);
1676
- }
1677
- async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
1678
- /**
1679
- * @method
1680
- * @name binance#editOrderWs
1681
- * @description edit a trade order
1682
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#cancel-and-replace-order-trade
1683
- * @param {string} id order id
1684
- * @param {string} symbol unified symbol of the market to create an order in
1685
- * @param {string} type 'market' or 'limit'
1686
- * @param {string} side 'buy' or 'sell'
1687
- * @param {float} amount how much of the currency you want to trade in units of the base currency
1688
- * @param {float|undefined} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1689
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1690
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1691
- */
1692
- await this.loadMarkets();
1693
- this.checkIsSpot('editOrderWs', symbol, params);
1694
- const url = this.urls['api']['ws']['ws'];
1695
- const requestId = this.requestId(url);
1696
- const messageHash = requestId.toString();
1697
- const payload = this.editSpotOrderRequest(id, symbol, type, side, amount, price, params);
1698
- let returnRateLimits = false;
1699
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'editOrderWs', 'returnRateLimits', false);
1700
- payload['returnRateLimits'] = returnRateLimits;
1701
- const message = {
1702
- 'id': messageHash,
1703
- 'method': 'order.cancelReplace',
1704
- 'params': this.signParams(this.extend(payload, params)),
1705
- };
1706
- const subscription = {
1707
- 'method': this.handleEditOrderWs,
1708
- };
1709
- return await this.watch(url, messageHash, message, messageHash, subscription);
1710
- }
1711
- handleEditOrderWs(client, message) {
1712
- //
1713
- // {
1714
- // "id": 1,
1715
- // "status": 200,
1716
- // "result": {
1717
- // "cancelResult": "SUCCESS",
1718
- // "newOrderResult": "SUCCESS",
1719
- // "cancelResponse": {
1720
- // "symbol": "BTCUSDT",
1721
- // "origClientOrderId": "x-R4BD3S82813c5d7ffa594104917de2",
1722
- // "orderId": 7665177,
1723
- // "orderListId": -1,
1724
- // "clientOrderId": "mbrnbQsQhtCXCLY45d5q7S",
1725
- // "price": "26000.00000000",
1726
- // "origQty": "0.00100000",
1727
- // "executedQty": "0.00000000",
1728
- // "cummulativeQuoteQty": "0.00000000",
1729
- // "status": "CANCELED",
1730
- // "timeInForce": "GTC",
1731
- // "type": "LIMIT",
1732
- // "side": "BUY",
1733
- // "selfTradePreventionMode": "NONE"
1734
- // },
1735
- // "newOrderResponse": {
1736
- // "symbol": "BTCUSDT",
1737
- // "orderId": 7665584,
1738
- // "orderListId": -1,
1739
- // "clientOrderId": "x-R4BD3S82b54769abdd3e4b57874c52",
1740
- // "transactTime": 1687642884646,
1741
- // "price": "26000.00000000",
1742
- // "origQty": "0.00100000",
1743
- // "executedQty": "0.00000000",
1744
- // "cummulativeQuoteQty": "0.00000000",
1745
- // "status": "NEW",
1746
- // "timeInForce": "GTC",
1747
- // "type": "LIMIT",
1748
- // "side": "BUY",
1749
- // "workingTime": 1687642884646,
1750
- // "fills": [],
1751
- // "selfTradePreventionMode": "NONE"
1752
- // }
1753
- // },
1754
- // "rateLimits": [{
1755
- // "rateLimitType": "ORDERS",
1756
- // "interval": "SECOND",
1757
- // "intervalNum": 10,
1758
- // "limit": 50,
1759
- // "count": 1
1760
- // },
1761
- // {
1762
- // "rateLimitType": "ORDERS",
1763
- // "interval": "DAY",
1764
- // "intervalNum": 1,
1765
- // "limit": 160000,
1766
- // "count": 3
1767
- // },
1768
- // {
1769
- // "rateLimitType": "REQUEST_WEIGHT",
1770
- // "interval": "MINUTE",
1771
- // "intervalNum": 1,
1772
- // "limit": 1200,
1773
- // "count": 12
1774
- // }
1775
- // ]
1776
- // }
1777
- //
1778
- const messageHash = this.safeString(message, 'id');
1779
- const result = this.safeValue(message, 'result', {});
1780
- const rawOrder = this.safeValue(result, 'newOrderResponse', {});
1781
- const order = this.parseOrder(rawOrder);
1782
- client.resolve(order, messageHash);
1783
- }
1784
- async cancelOrderWs(id, symbol = undefined, params = {}) {
1785
- /**
1786
- * @method
1787
- * @name binance#cancelOrderWs
1788
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#cancel-order-trade
1789
- * @description cancel multiple orders
1790
- * @param {string} id order id
1791
- * @param {string} symbol unified market symbol, default is undefined
1792
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1793
- * @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.
1794
- * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1795
- */
1796
- await this.loadMarkets();
1797
- if (symbol === undefined) {
1798
- throw new errors.BadRequest(this.id + ' cancelOrderWs requires a symbol');
1799
- }
1800
- this.checkIsSpot('cancelOrderWs', symbol, params);
1801
- const url = this.urls['api']['ws']['ws'];
1802
- const requestId = this.requestId(url);
1803
- const messageHash = requestId.toString();
1804
- let returnRateLimits = false;
1805
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelOrderWs', 'returnRateLimits', false);
1806
- const payload = {
1807
- 'symbol': this.marketId(symbol),
1808
- 'returnRateLimits': returnRateLimits,
1809
- };
1810
- const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
1811
- if (clientOrderId !== undefined) {
1812
- payload['origClientOrderId'] = clientOrderId;
1813
- }
1814
- else {
1815
- payload['orderId'] = this.parseToInt(id);
1816
- }
1817
- params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
1818
- const message = {
1819
- 'id': messageHash,
1820
- 'method': 'order.cancel',
1821
- 'params': this.signParams(this.extend(payload, params)),
1822
- };
1823
- const subscription = {
1824
- 'method': this.handleOrderWs,
1825
- };
1826
- return await this.watch(url, messageHash, message, messageHash, subscription);
1827
- }
1828
- async cancelAllOrdersWs(symbol = undefined, params = {}) {
1829
- /**
1830
- * @method
1831
- * @name binance#cancelAllOrdersWs
1832
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#current-open-orders-user_data
1833
- * @description cancel all open orders in a market
1834
- * @param {string} symbol unified market symbol of the market to cancel orders in
1835
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1836
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1837
- */
1838
- await this.loadMarkets();
1839
- const url = this.urls['api']['ws']['ws'];
1840
- const requestId = this.requestId(url);
1841
- const messageHash = requestId.toString();
1842
- let returnRateLimits = false;
1843
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'cancelAllOrdersWs', 'returnRateLimits', false);
1844
- const payload = {
1845
- 'symbol': this.marketId(symbol),
1846
- 'returnRateLimits': returnRateLimits,
1847
- };
1848
- const message = {
1849
- 'id': messageHash,
1850
- 'method': 'order.cancel',
1851
- 'params': this.signParams(this.extend(payload, params)),
1852
- };
1853
- const subscription = {
1854
- 'method': this.handleOrdersWs,
1855
- };
1856
- return await this.watch(url, messageHash, message, messageHash, subscription);
1857
- }
1858
- async fetchOrderWs(id, symbol = undefined, params = {}) {
1859
- /**
1860
- * @method
1861
- * @name binance#fetchOrderWs
1862
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#query-order-user_data
1863
- * @description fetches information on an order made by the user
1864
- * @param {string} symbol unified symbol of the market the order was made in
1865
- * @param {object} params extra parameters specific to the exchange API endpoint
1866
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1867
- */
1868
- await this.loadMarkets();
1869
- if (symbol === undefined) {
1870
- throw new errors.BadRequest(this.id + ' cancelOrderWs requires a symbol');
1871
- }
1872
- this.checkIsSpot('fetchOrderWs', symbol, params);
1873
- const url = this.urls['api']['ws']['ws'];
1874
- const requestId = this.requestId(url);
1875
- const messageHash = requestId.toString();
1876
- let returnRateLimits = false;
1877
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
1878
- const payload = {
1879
- 'symbol': this.marketId(symbol),
1880
- 'returnRateLimits': returnRateLimits,
1881
- };
1882
- const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
1883
- if (clientOrderId !== undefined) {
1884
- payload['origClientOrderId'] = clientOrderId;
1885
- }
1886
- else {
1887
- payload['orderId'] = this.parseToInt(id);
1888
- }
1889
- const message = {
1890
- 'id': messageHash,
1891
- 'method': 'order.status',
1892
- 'params': this.signParams(this.extend(payload, params)),
1893
- };
1894
- const subscription = {
1895
- 'method': this.handleOrderWs,
1896
- };
1897
- return await this.watch(url, messageHash, message, messageHash, subscription);
1898
- }
1899
- async fetchOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1900
- /**
1901
- * @method
1902
- * @name binance#fetchOrdersWs
1903
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#account-order-history-user_data
1904
- * @description fetches information on multiple orders made by the user
1905
- * @param {string} symbol unified market symbol of the market orders were made in
1906
- * @param {int|undefined} [since] the earliest time in ms to fetch orders for
1907
- * @param {int|undefined} [limit] the maximum number of order structures to retrieve
1908
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1909
- * @param {int} [params.orderId] order id to begin at
1910
- * @param {int} [params.startTime] earliest time in ms to retrieve orders for
1911
- * @param {int} [params.endTime] latest time in ms to retrieve orders for
1912
- * @param {int} [params.limit] the maximum number of order structures to retrieve
1913
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1914
- */
1915
- await this.loadMarkets();
1916
- if (symbol === undefined) {
1917
- throw new errors.BadRequest(this.id + ' fetchOrdersWs requires a symbol');
1918
- }
1919
- this.checkIsSpot('fetchOrdersWs', symbol, params);
1920
- const url = this.urls['api']['ws']['ws'];
1921
- const requestId = this.requestId(url);
1922
- const messageHash = requestId.toString();
1923
- let returnRateLimits = false;
1924
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
1925
- const payload = {
1926
- 'symbol': this.marketId(symbol),
1927
- 'returnRateLimits': returnRateLimits,
1928
- };
1929
- const message = {
1930
- 'id': messageHash,
1931
- 'method': 'allOrders',
1932
- 'params': this.signParams(this.extend(payload, params)),
1933
- };
1934
- const subscription = {
1935
- 'method': this.handleOrdersWs,
1936
- };
1937
- const orders = await this.watch(url, messageHash, message, messageHash, subscription);
1938
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
1939
- }
1940
- async fetchOpenOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1941
- /**
1942
- * @method
1943
- * @name binance#fetchOpenOrdersWs
1944
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#current-open-orders-user_data
1945
- * @description fetch all unfilled currently open orders
1946
- * @param {string} symbol unified market symbol
1947
- * @param {int|undefined} [since] the earliest time in ms to fetch open orders for
1948
- * @param {int|undefined} [limit] the maximum number of open orders structures to retrieve
1949
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1950
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1951
- */
1952
- await this.loadMarkets();
1953
- this.checkIsSpot('fetchOpenOrdersWs', symbol);
1954
- const url = this.urls['api']['ws']['ws'];
1955
- const requestId = this.requestId(url);
1956
- const messageHash = requestId.toString();
1957
- let returnRateLimits = false;
1958
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchOrderWs', 'returnRateLimits', false);
1959
- const payload = {
1960
- 'returnRateLimits': returnRateLimits,
1961
- };
1962
- if (symbol !== undefined) {
1963
- payload['symbol'] = this.marketId(symbol);
1964
- }
1965
- const message = {
1966
- 'id': messageHash,
1967
- 'method': 'openOrders.status',
1968
- 'params': this.signParams(this.extend(payload, params)),
1969
- };
1970
- const subscription = {
1971
- 'method': this.handleOrdersWs,
1972
- };
1973
- const orders = await this.watch(url, messageHash, message, messageHash, subscription);
1974
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
1975
- }
1976
- async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1977
- /**
1978
- * @method
1979
- * @name binance#watchOrders
1980
- * @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
1981
- * @description watches information on multiple orders made by the user
1982
- * @param {string} symbol unified market symbol of the market orders were made in
1983
- * @param {int} [since] the earliest time in ms to fetch orders for
1984
- * @param {int} [limit] the maximum number of order structures to retrieve
1985
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1986
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1987
- */
1988
- await this.loadMarkets();
1989
- let messageHash = 'orders';
1990
- let market = undefined;
1991
- if (symbol !== undefined) {
1992
- market = this.market(symbol);
1993
- symbol = market['symbol'];
1994
- messageHash += ':' + symbol;
1995
- }
1996
- let type = undefined;
1997
- [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
1998
- let subType = undefined;
1999
- [subType, params] = this.handleSubTypeAndParams('watchOrders', market, params);
2000
- if (this.isLinear(type, subType)) {
2001
- type = 'future';
2002
- }
2003
- else if (this.isInverse(type, subType)) {
2004
- type = 'delivery';
2005
- }
2006
- params = this.extend(params, { 'type': type, 'symbol': symbol }); // needed inside authenticate for isolated margin
2007
- await this.authenticate(params);
2008
- let urlType = type;
2009
- if (type === 'margin') {
2010
- urlType = 'spot'; // spot-margin shares the same stream as regular spot
2011
- }
2012
- const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
2013
- const client = this.client(url);
2014
- this.setBalanceCache(client, type);
2015
- this.setPositionsCache(client, type);
2016
- const message = undefined;
2017
- const orders = await this.watch(url, messageHash, message, type);
2018
- if (this.newUpdates) {
2019
- limit = orders.getLimit(symbol, limit);
2020
- }
2021
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
2022
- }
2023
- parseWsOrder(order, market = undefined) {
2024
- //
2025
- // spot
2026
- //
2027
- // {
2028
- // "e": "executionReport", // Event type
2029
- // "E": 1499405658658, // Event time
2030
- // "s": "ETHBTC", // Symbol
2031
- // "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
2032
- // "S": "BUY", // Side
2033
- // "o": "LIMIT", // Order type
2034
- // "f": "GTC", // Time in force
2035
- // "q": "1.00000000", // Order quantity
2036
- // "p": "0.10264410", // Order price
2037
- // "P": "0.00000000", // Stop price
2038
- // "F": "0.00000000", // Iceberg quantity
2039
- // "g": -1, // OrderListId
2040
- // "C": null, // Original client order ID; This is the ID of the order being canceled
2041
- // "x": "NEW", // Current execution type
2042
- // "X": "NEW", // Current order status
2043
- // "r": "NONE", // Order reject reason; will be an error code.
2044
- // "i": 4293153, // Order ID
2045
- // "l": "0.00000000", // Last executed quantity
2046
- // "z": "0.00000000", // Cumulative filled quantity
2047
- // "L": "0.00000000", // Last executed price
2048
- // "n": "0", // Commission amount
2049
- // "N": null, // Commission asset
2050
- // "T": 1499405658657, // Transaction time
2051
- // "t": -1, // Trade ID
2052
- // "I": 8641984, // Ignore
2053
- // "w": true, // Is the order on the book?
2054
- // "m": false, // Is this trade the maker side?
2055
- // "M": false, // Ignore
2056
- // "O": 1499405658657, // Order creation time
2057
- // "Z": "0.00000000", // Cumulative quote asset transacted quantity
2058
- // "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
2059
- // "Q": "0.00000000" // Quote Order Qty
2060
- // }
2061
- //
2062
- // future
2063
- //
2064
- // {
2065
- // "s":"BTCUSDT", // Symbol
2066
- // "c":"TEST", // Client Order Id
2067
- // // special client order id:
2068
- // // starts with "autoclose-": liquidation order
2069
- // // "adl_autoclose": ADL auto close order
2070
- // "S":"SELL", // Side
2071
- // "o":"TRAILING_STOP_MARKET", // Order Type
2072
- // "f":"GTC", // Time in Force
2073
- // "q":"0.001", // Original Quantity
2074
- // "p":"0", // Original Price
2075
- // "ap":"0", // Average Price
2076
- // "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
2077
- // "x":"NEW", // Execution Type
2078
- // "X":"NEW", // Order Status
2079
- // "i":8886774, // Order Id
2080
- // "l":"0", // Order Last Filled Quantity
2081
- // "z":"0", // Order Filled Accumulated Quantity
2082
- // "L":"0", // Last Filled Price
2083
- // "N":"USDT", // Commission Asset, will not push if no commission
2084
- // "n":"0", // Commission, will not push if no commission
2085
- // "T":1568879465651, // Order Trade Time
2086
- // "t":0, // Trade Id
2087
- // "b":"0", // Bids Notional
2088
- // "a":"9.91", // Ask Notional
2089
- // "m":false, // Is this trade the maker side?
2090
- // "R":false, // Is this reduce only
2091
- // "wt":"CONTRACT_PRICE", // Stop Price Working Type
2092
- // "ot":"TRAILING_STOP_MARKET", // Original Order Type
2093
- // "ps":"LONG", // Position Side
2094
- // "cp":false, // If Close-All, pushed with conditional order
2095
- // "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
2096
- // "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
2097
- // "rp":"0" // Realized Profit of the trade
2098
- // }
2099
- //
2100
- const executionType = this.safeString(order, 'x');
2101
- const orderId = this.safeString(order, 'i');
2102
- const marketId = this.safeString(order, 's');
2103
- const marketType = ('ps' in order) ? 'contract' : 'spot';
2104
- const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
2105
- let timestamp = this.safeInteger(order, 'O');
2106
- const T = this.safeInteger(order, 'T');
2107
- let lastTradeTimestamp = undefined;
2108
- if (executionType === 'NEW' || executionType === 'AMENDMENT' || executionType === 'CANCELED') {
2109
- if (timestamp === undefined) {
2110
- timestamp = T;
2111
- }
2112
- }
2113
- else if (executionType === 'TRADE') {
2114
- lastTradeTimestamp = T;
2115
- }
2116
- const lastUpdateTimestamp = T;
2117
- let fee = undefined;
2118
- const feeCost = this.safeString(order, 'n');
2119
- if ((feeCost !== undefined) && (Precise["default"].stringGt(feeCost, '0'))) {
2120
- const feeCurrencyId = this.safeString(order, 'N');
2121
- const feeCurrency = this.safeCurrencyCode(feeCurrencyId);
2122
- fee = {
2123
- 'cost': feeCost,
2124
- 'currency': feeCurrency,
2125
- };
2126
- }
2127
- const price = this.safeString(order, 'p');
2128
- const amount = this.safeString(order, 'q');
2129
- const side = this.safeStringLower(order, 'S');
2130
- const type = this.safeStringLower(order, 'o');
2131
- const filled = this.safeString(order, 'z');
2132
- const cost = this.safeString(order, 'Z');
2133
- const average = this.safeString(order, 'ap');
2134
- const rawStatus = this.safeString(order, 'X');
2135
- const status = this.parseOrderStatus(rawStatus);
2136
- const trades = undefined;
2137
- let clientOrderId = this.safeString(order, 'C');
2138
- if ((clientOrderId === undefined) || (clientOrderId.length === 0)) {
2139
- clientOrderId = this.safeString(order, 'c');
2140
- }
2141
- const stopPrice = this.safeString2(order, 'P', 'sp');
2142
- let timeInForce = this.safeString(order, 'f');
2143
- if (timeInForce === 'GTX') {
2144
- // GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
2145
- timeInForce = 'PO';
2146
- }
2147
- return this.safeOrder({
2148
- 'info': order,
2149
- 'symbol': symbol,
2150
- 'id': orderId,
2151
- 'clientOrderId': clientOrderId,
2152
- 'timestamp': timestamp,
2153
- 'datetime': this.iso8601(timestamp),
2154
- 'lastTradeTimestamp': lastTradeTimestamp,
2155
- 'lastUpdateTimestamp': lastUpdateTimestamp,
2156
- 'type': type,
2157
- 'timeInForce': timeInForce,
2158
- 'postOnly': undefined,
2159
- 'reduceOnly': this.safeValue(order, 'R'),
2160
- 'side': side,
2161
- 'price': price,
2162
- 'stopPrice': stopPrice,
2163
- 'triggerPrice': stopPrice,
2164
- 'amount': amount,
2165
- 'cost': cost,
2166
- 'average': average,
2167
- 'filled': filled,
2168
- 'remaining': undefined,
2169
- 'status': status,
2170
- 'fee': fee,
2171
- 'trades': trades,
2172
- });
2173
- }
2174
- handleOrderUpdate(client, message) {
2175
- //
2176
- // spot
2177
- //
2178
- // {
2179
- // "e": "executionReport", // Event type
2180
- // "E": 1499405658658, // Event time
2181
- // "s": "ETHBTC", // Symbol
2182
- // "c": "mUvoqJxFIILMdfAW5iGSOW", // Client order ID
2183
- // "S": "BUY", // Side
2184
- // "o": "LIMIT", // Order type
2185
- // "f": "GTC", // Time in force
2186
- // "q": "1.00000000", // Order quantity
2187
- // "p": "0.10264410", // Order price
2188
- // "P": "0.00000000", // Stop price
2189
- // "F": "0.00000000", // Iceberg quantity
2190
- // "g": -1, // OrderListId
2191
- // "C": null, // Original client order ID; This is the ID of the order being canceled
2192
- // "x": "NEW", // Current execution type
2193
- // "X": "NEW", // Current order status
2194
- // "r": "NONE", // Order reject reason; will be an error code.
2195
- // "i": 4293153, // Order ID
2196
- // "l": "0.00000000", // Last executed quantity
2197
- // "z": "0.00000000", // Cumulative filled quantity
2198
- // "L": "0.00000000", // Last executed price
2199
- // "n": "0", // Commission amount
2200
- // "N": null, // Commission asset
2201
- // "T": 1499405658657, // Transaction time
2202
- // "t": -1, // Trade ID
2203
- // "I": 8641984, // Ignore
2204
- // "w": true, // Is the order on the book?
2205
- // "m": false, // Is this trade the maker side?
2206
- // "M": false, // Ignore
2207
- // "O": 1499405658657, // Order creation time
2208
- // "Z": "0.00000000", // Cumulative quote asset transacted quantity
2209
- // "Y": "0.00000000" // Last quote asset transacted quantity (i.e. lastPrice * lastQty),
2210
- // "Q": "0.00000000" // Quote Order Qty
2211
- // }
2212
- //
2213
- // future
2214
- //
2215
- // {
2216
- // "e":"ORDER_TRADE_UPDATE", // Event Type
2217
- // "E":1568879465651, // Event Time
2218
- // "T":1568879465650, // Trasaction Time
2219
- // "o": {
2220
- // "s":"BTCUSDT", // Symbol
2221
- // "c":"TEST", // Client Order Id
2222
- // // special client order id:
2223
- // // starts with "autoclose-": liquidation order
2224
- // // "adl_autoclose": ADL auto close order
2225
- // "S":"SELL", // Side
2226
- // "o":"TRAILING_STOP_MARKET", // Order Type
2227
- // "f":"GTC", // Time in Force
2228
- // "q":"0.001", // Original Quantity
2229
- // "p":"0", // Original Price
2230
- // "ap":"0", // Average Price
2231
- // "sp":"7103.04", // Stop Price. Please ignore with TRAILING_STOP_MARKET order
2232
- // "x":"NEW", // Execution Type
2233
- // "X":"NEW", // Order Status
2234
- // "i":8886774, // Order Id
2235
- // "l":"0", // Order Last Filled Quantity
2236
- // "z":"0", // Order Filled Accumulated Quantity
2237
- // "L":"0", // Last Filled Price
2238
- // "N":"USDT", // Commission Asset, will not push if no commission
2239
- // "n":"0", // Commission, will not push if no commission
2240
- // "T":1568879465651, // Order Trade Time
2241
- // "t":0, // Trade Id
2242
- // "b":"0", // Bids Notional
2243
- // "a":"9.91", // Ask Notional
2244
- // "m":false, // Is this trade the maker side?
2245
- // "R":false, // Is this reduce only
2246
- // "wt":"CONTRACT_PRICE", // Stop Price Working Type
2247
- // "ot":"TRAILING_STOP_MARKET", // Original Order Type
2248
- // "ps":"LONG", // Position Side
2249
- // "cp":false, // If Close-All, pushed with conditional order
2250
- // "AP":"7476.89", // Activation Price, only puhed with TRAILING_STOP_MARKET order
2251
- // "cr":"5.0", // Callback Rate, only puhed with TRAILING_STOP_MARKET order
2252
- // "rp":"0" // Realized Profit of the trade
2253
- // }
2254
- // }
2255
- //
2256
- const e = this.safeString(message, 'e');
2257
- if (e === 'ORDER_TRADE_UPDATE') {
2258
- message = this.safeValue(message, 'o', message);
2259
- }
2260
- this.handleMyTrade(client, message);
2261
- this.handleOrder(client, message);
2262
- }
2263
- async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
2264
- /**
2265
- * @method
2266
- * @name binance#watchPositions
2267
- * @description watch all open positions
2268
- * @param {string[]|undefined} symbols list of unified market symbols
2269
- * @param {object} params extra parameters specific to the exchange API endpoint
2270
- * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
2271
- */
2272
- await this.loadMarkets();
2273
- await this.authenticate(params);
2274
- let market = undefined;
2275
- let messageHash = '';
2276
- symbols = this.marketSymbols(symbols);
2277
- if (!this.isEmpty(symbols)) {
2278
- market = this.getMarketFromSymbols(symbols);
2279
- messageHash = '::' + symbols.join(',');
2280
- }
2281
- let type = undefined;
2282
- [type, params] = this.handleMarketTypeAndParams('watchPositions', market, params);
2283
- if (type === 'spot' || type === 'margin') {
2284
- type = 'future';
2285
- }
2286
- let subType = undefined;
2287
- [subType, params] = this.handleSubTypeAndParams('watchPositions', market, params);
2288
- if (this.isLinear(type, subType)) {
2289
- type = 'future';
2290
- }
2291
- else if (this.isInverse(type, subType)) {
2292
- type = 'delivery';
2293
- }
2294
- messageHash = type + ':positions' + messageHash;
2295
- const url = this.urls['api']['ws'][type] + '/' + this.options[type]['listenKey'];
2296
- const client = this.client(url);
2297
- this.setBalanceCache(client, type);
2298
- this.setPositionsCache(client, type, symbols);
2299
- const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
2300
- const awaitPositionsSnapshot = this.safeValue('watchPositions', 'awaitPositionsSnapshot', true);
2301
- const cache = this.safeValue(this.positions, type);
2302
- if (fetchPositionsSnapshot && awaitPositionsSnapshot && cache === undefined) {
2303
- const snapshot = await client.future(type + ':fetchPositionsSnapshot');
2304
- return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
2305
- }
2306
- const newPositions = await this.watch(url, messageHash, undefined, type);
2307
- if (this.newUpdates) {
2308
- return newPositions;
2309
- }
2310
- return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
2311
- }
2312
- setPositionsCache(client, type, symbols = undefined) {
2313
- if (type === 'spot') {
2314
- return;
2315
- }
2316
- if (this.positions === undefined) {
2317
- this.positions = {};
2318
- }
2319
- if (type in this.positions) {
2320
- return;
2321
- }
2322
- const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', false);
2323
- if (fetchPositionsSnapshot) {
2324
- const messageHash = type + ':fetchPositionsSnapshot';
2325
- if (!(messageHash in client.futures)) {
2326
- client.future(messageHash);
2327
- this.spawn(this.loadPositionsSnapshot, client, messageHash, type);
2328
- }
2329
- }
2330
- else {
2331
- this.positions[type] = new Cache.ArrayCacheBySymbolBySide();
2332
- }
2333
- }
2334
- async loadPositionsSnapshot(client, messageHash, type) {
2335
- const positions = await this.fetchPositions(undefined, { 'type': type });
2336
- this.positions[type] = new Cache.ArrayCacheBySymbolBySide();
2337
- const cache = this.positions[type];
2338
- for (let i = 0; i < positions.length; i++) {
2339
- const position = positions[i];
2340
- const contracts = this.safeNumber(position, 'contracts', 0);
2341
- if (contracts > 0) {
2342
- cache.append(position);
2343
- }
2344
- }
2345
- // don't remove the future from the .futures cache
2346
- const future = client.futures[messageHash];
2347
- future.resolve(cache);
2348
- client.resolve(cache, type + ':position');
2349
- }
2350
- handlePositions(client, message) {
2351
- //
2352
- // {
2353
- // e: 'ACCOUNT_UPDATE',
2354
- // T: 1667881353112,
2355
- // E: 1667881353115,
2356
- // a: {
2357
- // B: [{
2358
- // a: 'USDT',
2359
- // wb: '1127.95750089',
2360
- // cw: '1040.82091149',
2361
- // bc: '0'
2362
- // }],
2363
- // P: [{
2364
- // s: 'BTCUSDT',
2365
- // pa: '-0.089',
2366
- // ep: '19700.03933',
2367
- // cr: '-1260.24809979',
2368
- // up: '1.53058860',
2369
- // mt: 'isolated',
2370
- // iw: '87.13658940',
2371
- // ps: 'BOTH',
2372
- // ma: 'USDT'
2373
- // }],
2374
- // m: 'ORDER'
2375
- // }
2376
- // }
2377
- //
2378
- // each account is connected to a different endpoint
2379
- // and has exactly one subscriptionhash which is the account type
2380
- const subscriptions = Object.keys(client.subscriptions);
2381
- const accountType = subscriptions[0];
2382
- if (this.positions === undefined) {
2383
- this.positions = {};
2384
- }
2385
- if (!(accountType in this.positions)) {
2386
- this.positions[accountType] = new Cache.ArrayCacheBySymbolBySide();
2387
- }
2388
- const cache = this.positions[accountType];
2389
- const data = this.safeValue(message, 'a', {});
2390
- const rawPositions = this.safeValue(data, 'P', []);
2391
- const newPositions = [];
2392
- for (let i = 0; i < rawPositions.length; i++) {
2393
- const rawPosition = rawPositions[i];
2394
- const position = this.parseWsPosition(rawPosition);
2395
- const timestamp = this.safeInteger(message, 'E');
2396
- position['timestamp'] = timestamp;
2397
- position['datetime'] = this.iso8601(timestamp);
2398
- newPositions.push(position);
2399
- cache.append(position);
2400
- }
2401
- const messageHashes = this.findMessageHashes(client, accountType + ':positions::');
2402
- for (let i = 0; i < messageHashes.length; i++) {
2403
- const messageHash = messageHashes[i];
2404
- const parts = messageHash.split('::');
2405
- const symbolsString = parts[1];
2406
- const symbols = symbolsString.split(',');
2407
- const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
2408
- if (!this.isEmpty(positions)) {
2409
- client.resolve(positions, messageHash);
2410
- }
2411
- }
2412
- client.resolve(newPositions, accountType + ':positions');
2413
- }
2414
- parseWsPosition(position, market = undefined) {
2415
- //
2416
- // {
2417
- // "s": "BTCUSDT", // Symbol
2418
- // "pa": "0", // Position Amount
2419
- // "ep": "0.00000", // Entry Price
2420
- // "cr": "200", // (Pre-fee) Accumulated Realized
2421
- // "up": "0", // Unrealized PnL
2422
- // "mt": "isolated", // Margin Type
2423
- // "iw": "0.00000000", // Isolated Wallet (if isolated position)
2424
- // "ps": "BOTH" // Position Side
2425
- // }
2426
- //
2427
- const marketId = this.safeString(position, 's');
2428
- const positionSide = this.safeStringLower(position, 'ps');
2429
- const hedged = positionSide !== 'both';
2430
- return this.safePosition({
2431
- 'info': position,
2432
- 'id': undefined,
2433
- 'symbol': this.safeSymbol(marketId, undefined, undefined, 'future'),
2434
- 'notional': undefined,
2435
- 'marginMode': this.safeString(position, 'mt'),
2436
- 'liquidationPrice': undefined,
2437
- 'entryPrice': this.safeNumber(position, 'ep'),
2438
- 'unrealizedPnl': this.safeNumber(position, 'up'),
2439
- 'percentage': undefined,
2440
- 'contracts': this.safeNumber(position, 'pa'),
2441
- 'contractSize': undefined,
2442
- 'markPrice': undefined,
2443
- 'side': positionSide,
2444
- 'hedged': hedged,
2445
- 'timestamp': undefined,
2446
- 'datetime': undefined,
2447
- 'maintenanceMargin': undefined,
2448
- 'maintenanceMarginPercentage': undefined,
2449
- 'collateral': undefined,
2450
- 'initialMargin': undefined,
2451
- 'initialMarginPercentage': undefined,
2452
- 'leverage': undefined,
2453
- 'marginRatio': undefined,
2454
- });
2455
- }
2456
- async fetchMyTradesWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2457
- /**
2458
- * @method
2459
- * @name binance#fetchMyTradesWs
2460
- * @see https://binance-docs.github.io/apidocs/websocket_api/en/#account-trade-history-user_data
2461
- * @description fetch all trades made by the user
2462
- * @param {string} symbol unified market symbol
2463
- * @param {int|undefined} [since] the earliest time in ms to fetch trades for
2464
- * @param {int|undefined} [limit] the maximum number of trades structures to retrieve
2465
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2466
- * @param {int} [params.endTime] the latest time in ms to fetch trades for
2467
- * @param {int} [params.fromId] first trade Id to fetch
2468
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
2469
- */
2470
- await this.loadMarkets();
2471
- if (symbol === undefined) {
2472
- throw new errors.BadRequest(this.id + ' fetchMyTradesWs requires a symbol');
2473
- }
2474
- this.checkIsSpot('fetchMyTradesWs', symbol, params);
2475
- const url = this.urls['api']['ws']['ws'];
2476
- const requestId = this.requestId(url);
2477
- const messageHash = requestId.toString();
2478
- let returnRateLimits = false;
2479
- [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchMyTradesWs', 'returnRateLimits', false);
2480
- const payload = {
2481
- 'symbol': this.marketId(symbol),
2482
- 'returnRateLimits': returnRateLimits,
2483
- };
2484
- if (since !== undefined) {
2485
- payload['startTime'] = since;
2486
- }
2487
- if (limit !== undefined) {
2488
- payload['limit'] = limit;
2489
- }
2490
- const fromId = this.safeInteger(params, 'fromId');
2491
- if (fromId !== undefined && since !== undefined) {
2492
- throw new errors.BadRequest(this.id + 'fetchMyTradesWs does not support fetching by both fromId and since parameters at the same time');
2493
- }
2494
- const message = {
2495
- 'id': messageHash,
2496
- 'method': 'myTrades',
2497
- 'params': this.signParams(this.extend(payload, params)),
2498
- };
2499
- const subscription = {
2500
- 'method': this.handleTradesWs,
2501
- };
2502
- const trades = await this.watch(url, messageHash, message, messageHash, subscription);
2503
- return this.filterBySymbolSinceLimit(trades, symbol, since, limit);
2504
- }
2505
- handleTradesWs(client, message) {
2506
- //
2507
- // {
2508
- // "id": "f4ce6a53-a29d-4f70-823b-4ab59391d6e8",
2509
- // "status": 200,
2510
- // "result": [{
2511
- // "symbol": "BTCUSDT",
2512
- // "id": 1650422481,
2513
- // "orderId": 12569099453,
2514
- // "orderListId": -1,
2515
- // "price": "23416.10000000",
2516
- // "qty": "0.00635000",
2517
- // "quoteQty": "148.69223500",
2518
- // "commission": "0.00000000",
2519
- // "commissionAsset": "BNB",
2520
- // "time": 1660801715793,
2521
- // "isBuyer": false,
2522
- // "isMaker": true,
2523
- // "isBestMatch": true
2524
- // },
2525
- // ...
2526
- // ],
2527
- // }
2528
- //
2529
- const messageHash = this.safeString(message, 'id');
2530
- const result = this.safeValue(message, 'result', []);
2531
- const trades = this.parseTrades(result);
2532
- client.resolve(trades, messageHash);
2533
- }
2534
- async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2535
- /**
2536
- * @method
2537
- * @name binance#watchMyTrades
2538
- * @description watches information on multiple trades made by the user
2539
- * @param {string} symbol unified market symbol of the market orders were made in
2540
- * @param {int} [since] the earliest time in ms to fetch orders for
2541
- * @param {int} [limit] the maximum number of order structures to retrieve
2542
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2543
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
2544
- */
2545
- await this.loadMarkets();
2546
- let type = undefined;
2547
- let market = undefined;
2548
- if (symbol !== undefined) {
2549
- market = this.market(symbol);
2550
- symbol = market['symbol'];
2551
- }
2552
- [type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
2553
- let subType = undefined;
2554
- [subType, params] = this.handleSubTypeAndParams('watchMyTrades', market, params);
2555
- if (this.isLinear(type, subType)) {
2556
- type = 'future';
2557
- }
2558
- else if (this.isInverse(type, subType)) {
2559
- type = 'delivery';
2560
- }
2561
- let messageHash = 'myTrades';
2562
- if (symbol !== undefined) {
2563
- symbol = this.symbol(symbol);
2564
- messageHash += ':' + symbol;
2565
- params = this.extend(params, { 'type': market['type'], 'symbol': symbol });
2566
- }
2567
- await this.authenticate(params);
2568
- let urlType = type; // we don't change type because the listening key is different
2569
- if (type === 'margin') {
2570
- urlType = 'spot'; // spot-margin shares the same stream as regular spot
2571
- }
2572
- const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
2573
- const client = this.client(url);
2574
- this.setBalanceCache(client, type);
2575
- this.setPositionsCache(client, type);
2576
- const message = undefined;
2577
- const trades = await this.watch(url, messageHash, message, type);
2578
- if (this.newUpdates) {
2579
- limit = trades.getLimit(symbol, limit);
2580
- }
2581
- return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
2582
- }
2583
- handleMyTrade(client, message) {
2584
- const messageHash = 'myTrades';
2585
- const executionType = this.safeString(message, 'x');
2586
- if (executionType === 'TRADE') {
2587
- const trade = this.parseTrade(message);
2588
- const orderId = this.safeString(trade, 'order');
2589
- let tradeFee = this.safeValue(trade, 'fee');
2590
- tradeFee = this.extend({}, tradeFee);
2591
- const symbol = this.safeString(trade, 'symbol');
2592
- if (orderId !== undefined && tradeFee !== undefined && symbol !== undefined) {
2593
- const cachedOrders = this.orders;
2594
- if (cachedOrders !== undefined) {
2595
- const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
2596
- const order = this.safeValue(orders, orderId);
2597
- if (order !== undefined) {
2598
- // accumulate order fees
2599
- const fees = this.safeValue(order, 'fees');
2600
- const fee = this.safeValue(order, 'fee');
2601
- if (!this.isEmpty(fees)) {
2602
- let insertNewFeeCurrency = true;
2603
- for (let i = 0; i < fees.length; i++) {
2604
- const orderFee = fees[i];
2605
- if (orderFee['currency'] === tradeFee['currency']) {
2606
- const feeCost = this.sum(tradeFee['cost'], orderFee['cost']);
2607
- order['fees'][i]['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
2608
- insertNewFeeCurrency = false;
2609
- break;
2610
- }
2611
- }
2612
- if (insertNewFeeCurrency) {
2613
- order['fees'].push(tradeFee);
2614
- }
2615
- }
2616
- else if (fee !== undefined) {
2617
- if (fee['currency'] === tradeFee['currency']) {
2618
- const feeCost = this.sum(fee['cost'], tradeFee['cost']);
2619
- order['fee']['cost'] = parseFloat(this.currencyToPrecision(tradeFee['currency'], feeCost));
2620
- }
2621
- else if (fee['currency'] === undefined) {
2622
- order['fee'] = tradeFee;
2623
- }
2624
- else {
2625
- order['fees'] = [fee, tradeFee];
2626
- order['fee'] = undefined;
2627
- }
2628
- }
2629
- else {
2630
- order['fee'] = tradeFee;
2631
- }
2632
- // save this trade in the order
2633
- const orderTrades = this.safeValue(order, 'trades', []);
2634
- orderTrades.push(trade);
2635
- order['trades'] = orderTrades;
2636
- // don't append twice cause it breaks newUpdates mode
2637
- // this order already exists in the cache
2638
- }
2639
- }
2640
- }
2641
- if (this.myTrades === undefined) {
2642
- const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
2643
- this.myTrades = new Cache.ArrayCacheBySymbolById(limit);
2644
- }
2645
- const myTrades = this.myTrades;
2646
- myTrades.append(trade);
2647
- client.resolve(this.myTrades, messageHash);
2648
- const messageHashSymbol = messageHash + ':' + symbol;
2649
- client.resolve(this.myTrades, messageHashSymbol);
2650
- }
2651
- }
2652
- handleOrder(client, message) {
2653
- const parsed = this.parseWsOrder(message);
2654
- const symbol = this.safeString(parsed, 'symbol');
2655
- const orderId = this.safeString(parsed, 'id');
2656
- if (symbol !== undefined) {
2657
- if (this.orders === undefined) {
2658
- const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
2659
- this.orders = new Cache.ArrayCacheBySymbolById(limit);
2660
- }
2661
- const cachedOrders = this.orders;
2662
- const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
2663
- const order = this.safeValue(orders, orderId);
2664
- if (order !== undefined) {
2665
- const fee = this.safeValue(order, 'fee');
2666
- if (fee !== undefined) {
2667
- parsed['fee'] = fee;
2668
- }
2669
- const fees = this.safeValue(order, 'fees');
2670
- if (fees !== undefined) {
2671
- parsed['fees'] = fees;
2672
- }
2673
- parsed['trades'] = this.safeValue(order, 'trades');
2674
- const timestamp = this.safeInteger(parsed, 'timestamp');
2675
- if (timestamp === undefined) {
2676
- parsed['timestamp'] = this.safeInteger(order, 'timestamp');
2677
- parsed['datetime'] = this.safeString(order, 'datetime');
2678
- }
2679
- }
2680
- cachedOrders.append(parsed);
2681
- const messageHash = 'orders';
2682
- const symbolSpecificMessageHash = 'orders:' + symbol;
2683
- client.resolve(cachedOrders, messageHash);
2684
- client.resolve(cachedOrders, symbolSpecificMessageHash);
2685
- }
2686
- }
2687
- handleAcountUpdate(client, message) {
2688
- this.handleBalance(client, message);
2689
- this.handlePositions(client, message);
2690
- }
2691
- handleWsError(client, message) {
2692
- //
2693
- // {
2694
- // "error": {
2695
- // "code": 2,
2696
- // "msg": "Invalid request: invalid stream"
2697
- // },
2698
- // "id": 1
2699
- // }
2700
- //
2701
- const id = this.safeString(message, 'id');
2702
- let rejected = false;
2703
- const error = this.safeValue(message, 'error', {});
2704
- const code = this.safeInteger(error, 'code');
2705
- const msg = this.safeString(error, 'msg');
2706
- try {
2707
- this.handleErrors(code, msg, client.url, undefined, undefined, this.json(error), error, undefined, undefined);
2708
- }
2709
- catch (e) {
2710
- rejected = true;
2711
- // private endpoint uses id as messageHash
2712
- client.reject(e, id);
2713
- // public endpoint stores messageHash in subscriptios
2714
- const subscriptionKeys = Object.keys(client.subscriptions);
2715
- for (let i = 0; i < subscriptionKeys.length; i++) {
2716
- const subscriptionHash = subscriptionKeys[i];
2717
- const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
2718
- if (id === subscriptionId) {
2719
- client.reject(e, subscriptionHash);
2720
- }
2721
- }
2722
- }
2723
- if (!rejected) {
2724
- client.reject(message, id);
2725
- }
2726
- // reset connection if 5xx error
2727
- if (this.safeString(code, 0) === '5') {
2728
- client.reset(message);
2729
- }
2730
- }
2731
- handleMessage(client, message) {
2732
- // handle WebSocketAPI
2733
- const status = this.safeString(message, 'status');
2734
- const error = this.safeValue(message, 'error');
2735
- if ((error !== undefined) || (status !== undefined && status !== '200')) {
2736
- return this.handleWsError(client, message);
2737
- }
2738
- const id = this.safeString(message, 'id');
2739
- const subscriptions = this.safeValue(client.subscriptions, id);
2740
- let method = this.safeValue(subscriptions, 'method');
2741
- if (method !== undefined) {
2742
- return method.call(this, client, message);
2743
- }
2744
- // handle other APIs
2745
- const methods = {
2746
- 'depthUpdate': this.handleOrderBook,
2747
- 'trade': this.handleTrade,
2748
- 'aggTrade': this.handleTrade,
2749
- 'kline': this.handleOHLCV,
2750
- 'markPrice_kline': this.handleOHLCV,
2751
- 'indexPrice_kline': this.handleOHLCV,
2752
- '24hrTicker@arr': this.handleTickers,
2753
- '24hrMiniTicker@arr': this.handleTickers,
2754
- '24hrTicker': this.handleTicker,
2755
- '24hrMiniTicker': this.handleTicker,
2756
- 'bookTicker': this.handleTicker,
2757
- 'outboundAccountPosition': this.handleBalance,
2758
- 'balanceUpdate': this.handleBalance,
2759
- 'ACCOUNT_UPDATE': this.handleAcountUpdate,
2760
- 'executionReport': this.handleOrderUpdate,
2761
- 'ORDER_TRADE_UPDATE': this.handleOrderUpdate,
2762
- };
2763
- let event = this.safeString(message, 'e');
2764
- if (Array.isArray(message)) {
2765
- const data = message[0];
2766
- event = this.safeString(data, 'e') + '@arr';
2767
- }
2768
- method = this.safeValue(methods, event);
2769
- if (method === undefined) {
2770
- const requestId = this.safeString(message, 'id');
2771
- if (requestId !== undefined) {
2772
- return this.handleSubscriptionStatus(client, message);
2773
- }
2774
- // special case for the real-time bookTicker, since it comes without an event identifier
2775
- //
2776
- // {
2777
- // "u": 7488717758,
2778
- // "s": "BTCUSDT",
2779
- // "b": "28621.74000000",
2780
- // "B": "1.43278800",
2781
- // "a": "28621.75000000",
2782
- // "A": "2.52500800"
2783
- // }
2784
- //
2785
- if (event === undefined) {
2786
- this.handleTicker(client, message);
2787
- this.handleTickers(client, message);
2788
- }
2789
- }
2790
- else {
2791
- return method.call(this, client, message);
2792
- }
2793
- }
2794
- }
2795
-
2796
- module.exports = binance;