@reefclaw/connect 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/assets/bridge/gateway/heartbeat-cron.d.ts +27 -0
  2. package/assets/bridge/gateway/heartbeat-cron.js +85 -0
  3. package/assets/bridge/providers/gateway.d.ts +2 -0
  4. package/assets/bridge/providers/gateway.js +57 -16
  5. package/assets/bridge/setup.js +6 -51
  6. package/dist/deps.js +2 -2
  7. package/dist/plugin.js +35 -7
  8. package/package.json +1 -1
  9. package/assets/plugin/audit/mode-transition-audit.d.ts +0 -11
  10. package/assets/plugin/audit/mode-transition-audit.js +0 -29
  11. package/assets/plugin/balance-utils.d.ts +0 -36
  12. package/assets/plugin/balance-utils.js +0 -98
  13. package/assets/plugin/ccxt/binance-ban-gate.d.ts +0 -47
  14. package/assets/plugin/ccxt/binance-ban-gate.js +0 -420
  15. package/assets/plugin/ccxt/binance-private.d.ts +0 -346
  16. package/assets/plugin/ccxt/binance-private.js +0 -1525
  17. package/assets/plugin/ccxt/binance-public.d.ts +0 -34
  18. package/assets/plugin/ccxt/binance-public.js +0 -180
  19. package/assets/plugin/ccxt/intel-public.d.ts +0 -25
  20. package/assets/plugin/ccxt/intel-public.js +0 -80
  21. package/assets/plugin/ccxt/public-market-data-api.d.ts +0 -26
  22. package/assets/plugin/ccxt/public-market-data-api.js +0 -23
  23. package/assets/plugin/config/agent-config-client.d.ts +0 -77
  24. package/assets/plugin/config/agent-config-client.js +0 -188
  25. package/assets/plugin/config/agent-config-poller.d.ts +0 -32
  26. package/assets/plugin/config/agent-config-poller.js +0 -101
  27. package/assets/plugin/config/brackets-config.d.ts +0 -22
  28. package/assets/plugin/config/brackets-config.js +0 -58
  29. package/assets/plugin/config/entitlement-gate.d.ts +0 -51
  30. package/assets/plugin/config/entitlement-gate.js +0 -137
  31. package/assets/plugin/config/gate-store.d.ts +0 -18
  32. package/assets/plugin/config/gate-store.js +0 -61
  33. package/assets/plugin/config/plugin-config-io.d.ts +0 -222
  34. package/assets/plugin/config/plugin-config-io.js +0 -126
  35. package/assets/plugin/config/position-review-config.d.ts +0 -35
  36. package/assets/plugin/config/position-review-config.js +0 -105
  37. package/assets/plugin/config/tool-gate.d.ts +0 -53
  38. package/assets/plugin/config/tool-gate.js +0 -128
  39. package/assets/plugin/config/user-data-stream-config.d.ts +0 -89
  40. package/assets/plugin/config/user-data-stream-config.js +0 -239
  41. package/assets/plugin/connector-supervisor.d.ts +0 -36
  42. package/assets/plugin/connector-supervisor.js +0 -149
  43. package/assets/plugin/exchange-adapter.d.ts +0 -65
  44. package/assets/plugin/exchange-adapter.js +0 -4
  45. package/assets/plugin/index.d.ts +0 -30
  46. package/assets/plugin/index.js +0 -2756
  47. package/assets/plugin/ingest/pending-entry-metadata.d.ts +0 -74
  48. package/assets/plugin/ingest/pending-entry-metadata.js +0 -236
  49. package/assets/plugin/ingest/position-auto-capture.d.ts +0 -171
  50. package/assets/plugin/ingest/position-auto-capture.js +0 -709
  51. package/assets/plugin/ingest/position-decisions-client.d.ts +0 -327
  52. package/assets/plugin/ingest/position-decisions-client.js +0 -306
  53. package/assets/plugin/ingest/readiness-reporter.d.ts +0 -42
  54. package/assets/plugin/ingest/readiness-reporter.js +0 -163
  55. package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +0 -51
  56. package/assets/plugin/ingest/reconcile-db-vs-exchange.js +0 -170
  57. package/assets/plugin/ingest/reconciler-cleanup.d.ts +0 -37
  58. package/assets/plugin/ingest/reconciler-cleanup.js +0 -147
  59. package/assets/plugin/ingest/rest-gap-filler.d.ts +0 -191
  60. package/assets/plugin/ingest/rest-gap-filler.js +0 -565
  61. package/assets/plugin/ingest/touched-symbols-store.d.ts +0 -25
  62. package/assets/plugin/ingest/touched-symbols-store.js +0 -96
  63. package/assets/plugin/ingest/trade-store-client.d.ts +0 -40
  64. package/assets/plugin/ingest/trade-store-client.js +0 -125
  65. package/assets/plugin/ingest/ws-ingest.d.ts +0 -43
  66. package/assets/plugin/ingest/ws-ingest.js +0 -126
  67. package/assets/plugin/learning/setup-family.d.ts +0 -21
  68. package/assets/plugin/learning/setup-family.js +0 -103
  69. package/assets/plugin/lifecycle/install-signal-handlers.d.ts +0 -33
  70. package/assets/plugin/lifecycle/install-signal-handlers.js +0 -112
  71. package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +0 -43
  72. package/assets/plugin/lifecycle/shutdown-coordinator.js +0 -131
  73. package/assets/plugin/lifecycle/trading-operation-lock.d.ts +0 -17
  74. package/assets/plugin/lifecycle/trading-operation-lock.js +0 -14
  75. package/assets/plugin/live/bracket-id.d.ts +0 -26
  76. package/assets/plugin/live/bracket-id.js +0 -112
  77. package/assets/plugin/live/bracket-ledger.d.ts +0 -54
  78. package/assets/plugin/live/bracket-ledger.js +0 -267
  79. package/assets/plugin/live/bracket-manager.d.ts +0 -82
  80. package/assets/plugin/live/bracket-manager.js +0 -478
  81. package/assets/plugin/live/bracket-params.d.ts +0 -22
  82. package/assets/plugin/live/bracket-params.js +0 -124
  83. package/assets/plugin/live/bracket-reconciler.d.ts +0 -95
  84. package/assets/plugin/live/bracket-reconciler.js +0 -573
  85. package/assets/plugin/live/bracket-types.d.ts +0 -102
  86. package/assets/plugin/live/bracket-types.js +0 -8
  87. package/assets/plugin/live/deposit-tracker.d.ts +0 -62
  88. package/assets/plugin/live/deposit-tracker.js +0 -97
  89. package/assets/plugin/live/emergency-controls.d.ts +0 -32
  90. package/assets/plugin/live/emergency-controls.js +0 -226
  91. package/assets/plugin/live/exchange-errors.d.ts +0 -12
  92. package/assets/plugin/live/exchange-errors.js +0 -130
  93. package/assets/plugin/live/exchange-info-cache.d.ts +0 -37
  94. package/assets/plugin/live/exchange-info-cache.js +0 -134
  95. package/assets/plugin/live/fact-subscriber.d.ts +0 -78
  96. package/assets/plugin/live/fact-subscriber.js +0 -182
  97. package/assets/plugin/live/fill-price.d.ts +0 -13
  98. package/assets/plugin/live/fill-price.js +0 -37
  99. package/assets/plugin/live/intent-journal.d.ts +0 -42
  100. package/assets/plugin/live/intent-journal.js +0 -122
  101. package/assets/plugin/live/listen-key-manager.d.ts +0 -70
  102. package/assets/plugin/live/listen-key-manager.js +0 -169
  103. package/assets/plugin/live/live-adapter.d.ts +0 -319
  104. package/assets/plugin/live/live-adapter.js +0 -1906
  105. package/assets/plugin/live/live-balance-enricher.d.ts +0 -32
  106. package/assets/plugin/live/live-balance-enricher.js +0 -104
  107. package/assets/plugin/live/live-bracket-api.d.ts +0 -13
  108. package/assets/plugin/live/live-bracket-api.js +0 -20
  109. package/assets/plugin/live/live-state-store.d.ts +0 -194
  110. package/assets/plugin/live/live-state-store.js +0 -450
  111. package/assets/plugin/live/local-signal-service.d.ts +0 -57
  112. package/assets/plugin/live/local-signal-service.js +0 -151
  113. package/assets/plugin/live/local-strategy-evaluator.d.ts +0 -62
  114. package/assets/plugin/live/local-strategy-evaluator.js +0 -131
  115. package/assets/plugin/live/microstructure-assembler.d.ts +0 -54
  116. package/assets/plugin/live/microstructure-assembler.js +0 -148
  117. package/assets/plugin/live/order-poller.d.ts +0 -29
  118. package/assets/plugin/live/order-poller.js +0 -125
  119. package/assets/plugin/live/position-state-store.d.ts +0 -87
  120. package/assets/plugin/live/position-state-store.js +0 -237
  121. package/assets/plugin/live/proposal-decision-listener.d.ts +0 -70
  122. package/assets/plugin/live/proposal-decision-listener.js +0 -292
  123. package/assets/plugin/live/proposal-manager.d.ts +0 -76
  124. package/assets/plugin/live/proposal-manager.js +0 -140
  125. package/assets/plugin/live/rate-limiter.d.ts +0 -47
  126. package/assets/plugin/live/rate-limiter.js +0 -159
  127. package/assets/plugin/live/reconciler.d.ts +0 -39
  128. package/assets/plugin/live/reconciler.js +0 -175
  129. package/assets/plugin/live/setup-buckets.d.ts +0 -7
  130. package/assets/plugin/live/setup-buckets.js +0 -33
  131. package/assets/plugin/live/slippage-tracker.d.ts +0 -45
  132. package/assets/plugin/live/slippage-tracker.js +0 -78
  133. package/assets/plugin/live/stop-watcher.d.ts +0 -67
  134. package/assets/plugin/live/stop-watcher.js +0 -218
  135. package/assets/plugin/live/user-data-active-probe.d.ts +0 -54
  136. package/assets/plugin/live/user-data-active-probe.js +0 -180
  137. package/assets/plugin/live/user-data-stream-controller.d.ts +0 -200
  138. package/assets/plugin/live/user-data-stream-controller.js +0 -579
  139. package/assets/plugin/live/user-data-stream-ws.d.ts +0 -22
  140. package/assets/plugin/live/user-data-stream-ws.js +0 -63
  141. package/assets/plugin/live/user-data-stream.d.ts +0 -243
  142. package/assets/plugin/live/user-data-stream.js +0 -704
  143. package/assets/plugin/logger.d.ts +0 -2
  144. package/assets/plugin/logger.js +0 -2
  145. package/assets/plugin/mfe.d.ts +0 -21
  146. package/assets/plugin/mfe.js +0 -68
  147. package/assets/plugin/onboarding/mode-ladder.d.ts +0 -1
  148. package/assets/plugin/onboarding/mode-ladder.js +0 -3
  149. package/assets/plugin/onboarding/runtime.d.ts +0 -90
  150. package/assets/plugin/onboarding/runtime.js +0 -184
  151. package/assets/plugin/openclaw.plugin.json +0 -92
  152. package/assets/plugin/paper-adapter.d.ts +0 -24
  153. package/assets/plugin/paper-adapter.js +0 -91
  154. package/assets/plugin/persistence/state-manager.d.ts +0 -66
  155. package/assets/plugin/persistence/state-manager.js +0 -222
  156. package/assets/plugin/pinned-plan.d.ts +0 -9
  157. package/assets/plugin/pinned-plan.js +0 -23
  158. package/assets/plugin/portfolio/reentry-tracker.d.ts +0 -36
  159. package/assets/plugin/portfolio/reentry-tracker.js +0 -127
  160. package/assets/plugin/portfolio/wave9-admission.d.ts +0 -67
  161. package/assets/plugin/portfolio/wave9-admission.js +0 -262
  162. package/assets/plugin/portfolio/wave9-policy.d.ts +0 -36
  163. package/assets/plugin/portfolio/wave9-policy.js +0 -183
  164. package/assets/plugin/risk/pre-trade-check.d.ts +0 -38
  165. package/assets/plugin/risk/pre-trade-check.js +0 -345
  166. package/assets/plugin/risk/pre-trade-types.d.ts +0 -60
  167. package/assets/plugin/risk/pre-trade-types.js +0 -3
  168. package/assets/plugin/shadow/shadow-tracker.d.ts +0 -36
  169. package/assets/plugin/shadow/shadow-tracker.js +0 -151
  170. package/assets/plugin/shadow/types.d.ts +0 -42
  171. package/assets/plugin/shadow/types.js +0 -20
  172. package/assets/plugin/shared/indicators-extended.d.ts +0 -52
  173. package/assets/plugin/shared/indicators-extended.js +0 -291
  174. package/assets/plugin/shared/indicators.d.ts +0 -15
  175. package/assets/plugin/shared/indicators.js +0 -114
  176. package/assets/plugin/signals/conditions/registry.d.ts +0 -16
  177. package/assets/plugin/signals/conditions/registry.js +0 -1333
  178. package/assets/plugin/signals/conditions/types.d.ts +0 -1
  179. package/assets/plugin/signals/conditions/types.js +0 -4
  180. package/assets/plugin/signals/direction-rules.d.ts +0 -3
  181. package/assets/plugin/signals/direction-rules.js +0 -24
  182. package/assets/plugin/signals/entry-rules.d.ts +0 -6
  183. package/assets/plugin/signals/entry-rules.js +0 -33
  184. package/assets/plugin/signals/serialize-context.d.ts +0 -4
  185. package/assets/plugin/signals/serialize-context.js +0 -39
  186. package/assets/plugin/signals/stop-rules.d.ts +0 -3
  187. package/assets/plugin/signals/stop-rules.js +0 -48
  188. package/assets/plugin/signals/strategy-adapter.d.ts +0 -47
  189. package/assets/plugin/signals/strategy-adapter.js +0 -209
  190. package/assets/plugin/signals/types.d.ts +0 -1
  191. package/assets/plugin/signals/types.js +0 -8
  192. package/assets/plugin/simulator/exchange-simulator.d.ts +0 -105
  193. package/assets/plugin/simulator/exchange-simulator.js +0 -759
  194. package/assets/plugin/simulator/fill-engine.d.ts +0 -53
  195. package/assets/plugin/simulator/fill-engine.js +0 -280
  196. package/assets/plugin/simulator/paper-market-feed.d.ts +0 -26
  197. package/assets/plugin/simulator/paper-market-feed.js +0 -104
  198. package/assets/plugin/simulator/realistic-fills.d.ts +0 -59
  199. package/assets/plugin/simulator/realistic-fills.js +0 -175
  200. package/assets/plugin/simulator/types.d.ts +0 -228
  201. package/assets/plugin/simulator/types.js +0 -43
  202. package/assets/plugin/strategy/builtin-strategies.d.ts +0 -2
  203. package/assets/plugin/strategy/builtin-strategies.js +0 -113
  204. package/assets/plugin/strategy/condition-registry.d.ts +0 -3
  205. package/assets/plugin/strategy/condition-registry.js +0 -153
  206. package/assets/plugin/strategy/evaluator.d.ts +0 -70
  207. package/assets/plugin/strategy/evaluator.js +0 -98
  208. package/assets/plugin/tools/assessment-validation.d.ts +0 -141
  209. package/assets/plugin/tools/assessment-validation.js +0 -473
  210. package/assets/plugin/tools/attach-brackets.d.ts +0 -39
  211. package/assets/plugin/tools/attach-brackets.js +0 -564
  212. package/assets/plugin/tools/audit-bracket-protection.d.ts +0 -49
  213. package/assets/plugin/tools/audit-bracket-protection.js +0 -683
  214. package/assets/plugin/tools/bracket-control.d.ts +0 -12
  215. package/assets/plugin/tools/bracket-control.js +0 -35
  216. package/assets/plugin/tools/cancel-all-orders.d.ts +0 -9
  217. package/assets/plugin/tools/cancel-all-orders.js +0 -8
  218. package/assets/plugin/tools/cancel-order.d.ts +0 -14
  219. package/assets/plugin/tools/cancel-order.js +0 -60
  220. package/assets/plugin/tools/check-position-health.d.ts +0 -46
  221. package/assets/plugin/tools/check-position-health.js +0 -194
  222. package/assets/plugin/tools/clear-exchange-credentials.d.ts +0 -24
  223. package/assets/plugin/tools/clear-exchange-credentials.js +0 -70
  224. package/assets/plugin/tools/close-position.d.ts +0 -45
  225. package/assets/plugin/tools/close-position.js +0 -722
  226. package/assets/plugin/tools/create-order.d.ts +0 -82
  227. package/assets/plugin/tools/create-order.js +0 -1544
  228. package/assets/plugin/tools/exit-gate.d.ts +0 -58
  229. package/assets/plugin/tools/exit-gate.js +0 -162
  230. package/assets/plugin/tools/fetch-balance.d.ts +0 -5
  231. package/assets/plugin/tools/fetch-balance.js +0 -4
  232. package/assets/plugin/tools/fetch-ohlcv.d.ts +0 -11
  233. package/assets/plugin/tools/fetch-ohlcv.js +0 -8
  234. package/assets/plugin/tools/fetch-open-orders.d.ts +0 -7
  235. package/assets/plugin/tools/fetch-open-orders.js +0 -4
  236. package/assets/plugin/tools/fetch-positions.d.ts +0 -7
  237. package/assets/plugin/tools/fetch-positions.js +0 -4
  238. package/assets/plugin/tools/fetch-ticker.d.ts +0 -11
  239. package/assets/plugin/tools/fetch-ticker.js +0 -5
  240. package/assets/plugin/tools/get-agent-profile.d.ts +0 -4
  241. package/assets/plugin/tools/get-agent-profile.js +0 -6
  242. package/assets/plugin/tools/get-analytics.d.ts +0 -6
  243. package/assets/plugin/tools/get-analytics.js +0 -7
  244. package/assets/plugin/tools/get-backtest.d.ts +0 -12
  245. package/assets/plugin/tools/get-backtest.js +0 -91
  246. package/assets/plugin/tools/get-basis.d.ts +0 -7
  247. package/assets/plugin/tools/get-basis.js +0 -7
  248. package/assets/plugin/tools/get-bracket-config.d.ts +0 -11
  249. package/assets/plugin/tools/get-bracket-config.js +0 -24
  250. package/assets/plugin/tools/get-cascade-risk.d.ts +0 -7
  251. package/assets/plugin/tools/get-cascade-risk.js +0 -8
  252. package/assets/plugin/tools/get-crypto-metrics.d.ts +0 -18
  253. package/assets/plugin/tools/get-crypto-metrics.js +0 -62
  254. package/assets/plugin/tools/get-cvd.d.ts +0 -6
  255. package/assets/plugin/tools/get-cvd.js +0 -6
  256. package/assets/plugin/tools/get-divergences.d.ts +0 -6
  257. package/assets/plugin/tools/get-divergences.js +0 -6
  258. package/assets/plugin/tools/get-funding-context.d.ts +0 -6
  259. package/assets/plugin/tools/get-funding-context.js +0 -16
  260. package/assets/plugin/tools/get-liquidation-levels.d.ts +0 -7
  261. package/assets/plugin/tools/get-liquidation-levels.js +0 -7
  262. package/assets/plugin/tools/get-liquidation-pulse.d.ts +0 -9
  263. package/assets/plugin/tools/get-liquidation-pulse.js +0 -22
  264. package/assets/plugin/tools/get-market-breadth.d.ts +0 -6
  265. package/assets/plugin/tools/get-market-breadth.js +0 -8
  266. package/assets/plugin/tools/get-market-intel.d.ts +0 -19
  267. package/assets/plugin/tools/get-market-intel.js +0 -116
  268. package/assets/plugin/tools/get-market-structure.d.ts +0 -47
  269. package/assets/plugin/tools/get-market-structure.js +0 -198
  270. package/assets/plugin/tools/get-my-mined-patterns.d.ts +0 -20
  271. package/assets/plugin/tools/get-my-mined-patterns.js +0 -61
  272. package/assets/plugin/tools/get-my-proposed-learnings.d.ts +0 -20
  273. package/assets/plugin/tools/get-my-proposed-learnings.js +0 -55
  274. package/assets/plugin/tools/get-my-recent-reviews.d.ts +0 -22
  275. package/assets/plugin/tools/get-my-recent-reviews.js +0 -66
  276. package/assets/plugin/tools/get-orderbook.d.ts +0 -21
  277. package/assets/plugin/tools/get-orderbook.js +0 -32
  278. package/assets/plugin/tools/get-pattern-scan.d.ts +0 -7
  279. package/assets/plugin/tools/get-pattern-scan.js +0 -8
  280. package/assets/plugin/tools/get-regime.d.ts +0 -6
  281. package/assets/plugin/tools/get-regime.js +0 -7
  282. package/assets/plugin/tools/get-relevant-learnings.d.ts +0 -21
  283. package/assets/plugin/tools/get-relevant-learnings.js +0 -65
  284. package/assets/plugin/tools/get-resting-liquidity.d.ts +0 -6
  285. package/assets/plugin/tools/get-resting-liquidity.js +0 -11
  286. package/assets/plugin/tools/get-risk-scenario.d.ts +0 -29
  287. package/assets/plugin/tools/get-risk-scenario.js +0 -47
  288. package/assets/plugin/tools/get-risk-summary.d.ts +0 -51
  289. package/assets/plugin/tools/get-risk-summary.js +0 -118
  290. package/assets/plugin/tools/get-sentiment.d.ts +0 -4
  291. package/assets/plugin/tools/get-sentiment.js +0 -6
  292. package/assets/plugin/tools/get-session-review.d.ts +0 -7
  293. package/assets/plugin/tools/get-session-review.js +0 -8
  294. package/assets/plugin/tools/get-setup-detail.d.ts +0 -7
  295. package/assets/plugin/tools/get-setup-detail.js +0 -322
  296. package/assets/plugin/tools/get-signals.d.ts +0 -15
  297. package/assets/plugin/tools/get-signals.js +0 -54
  298. package/assets/plugin/tools/get-sizing.d.ts +0 -6
  299. package/assets/plugin/tools/get-sizing.js +0 -6
  300. package/assets/plugin/tools/get-trade-feedback.d.ts +0 -7
  301. package/assets/plugin/tools/get-trade-feedback.js +0 -8
  302. package/assets/plugin/tools/get-trade-flow.d.ts +0 -7
  303. package/assets/plugin/tools/get-trade-flow.js +0 -7
  304. package/assets/plugin/tools/get-volume-analysis.d.ts +0 -21
  305. package/assets/plugin/tools/get-volume-analysis.js +0 -74
  306. package/assets/plugin/tools/get-volume-profile.d.ts +0 -7
  307. package/assets/plugin/tools/get-volume-profile.js +0 -7
  308. package/assets/plugin/tools/get-wave9-status.d.ts +0 -127
  309. package/assets/plugin/tools/get-wave9-status.js +0 -796
  310. package/assets/plugin/tools/helpers.d.ts +0 -26
  311. package/assets/plugin/tools/helpers.js +0 -39
  312. package/assets/plugin/tools/intel-api.d.ts +0 -34
  313. package/assets/plugin/tools/intel-api.js +0 -119
  314. package/assets/plugin/tools/intel-cache.d.ts +0 -25
  315. package/assets/plugin/tools/intel-cache.js +0 -148
  316. package/assets/plugin/tools/list-strategies.d.ts +0 -17
  317. package/assets/plugin/tools/list-strategies.js +0 -23
  318. package/assets/plugin/tools/modify-stop.d.ts +0 -21
  319. package/assets/plugin/tools/modify-stop.js +0 -120
  320. package/assets/plugin/tools/modify-target.d.ts +0 -21
  321. package/assets/plugin/tools/modify-target.js +0 -110
  322. package/assets/plugin/tools/propose-learning.d.ts +0 -22
  323. package/assets/plugin/tools/propose-learning.js +0 -65
  324. package/assets/plugin/tools/query-review-outcomes.d.ts +0 -30
  325. package/assets/plugin/tools/query-review-outcomes.js +0 -64
  326. package/assets/plugin/tools/query-trades.d.ts +0 -21
  327. package/assets/plugin/tools/query-trades.js +0 -37
  328. package/assets/plugin/tools/record-position-reviews.d.ts +0 -38
  329. package/assets/plugin/tools/record-position-reviews.js +0 -147
  330. package/assets/plugin/tools/save-strategy.d.ts +0 -16
  331. package/assets/plugin/tools/save-strategy.js +0 -46
  332. package/assets/plugin/tools/scan-pairs.d.ts +0 -22
  333. package/assets/plugin/tools/scan-pairs.js +0 -234
  334. package/assets/plugin/tools/score-setup.d.ts +0 -31
  335. package/assets/plugin/tools/score-setup.js +0 -268
  336. package/assets/plugin/tools/set-bracket-requirement.d.ts +0 -18
  337. package/assets/plugin/tools/set-bracket-requirement.js +0 -81
  338. package/assets/plugin/tools/set-exchange-credentials.d.ts +0 -25
  339. package/assets/plugin/tools/set-exchange-credentials.js +0 -80
  340. package/assets/plugin/tools/set-trading-mode.d.ts +0 -26
  341. package/assets/plugin/tools/set-trading-mode.js +0 -135
  342. package/assets/plugin/tools/test-exchange-credentials.d.ts +0 -16
  343. package/assets/plugin/tools/test-exchange-credentials.js +0 -100
  344. package/assets/plugin/tools/toggle-strategy.d.ts +0 -8
  345. package/assets/plugin/tools/toggle-strategy.js +0 -15
  346. package/assets/plugin/trading-params-cache.d.ts +0 -26
  347. package/assets/plugin/trading-params-cache.js +0 -52
  348. package/assets/plugin/types.d.ts +0 -134
  349. package/assets/plugin/types.js +0 -7
  350. package/assets/plugin/util/plugin-paths.d.ts +0 -3
  351. package/assets/plugin/util/plugin-paths.js +0 -15
  352. package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +0 -116
  353. package/assets/plugin/venues/hyperliquid/hl-balance.js +0 -145
  354. package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.d.ts +0 -123
  355. package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.js +0 -533
  356. package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +0 -102
  357. package/assets/plugin/venues/hyperliquid/hl-brackets.js +0 -172
  358. package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +0 -22
  359. package/assets/plugin/venues/hyperliquid/hl-cloid.js +0 -82
  360. package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +0 -46
  361. package/assets/plugin/venues/hyperliquid/hl-info-cache.js +0 -125
  362. package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +0 -146
  363. package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +0 -728
  364. package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +0 -61
  365. package/assets/plugin/venues/hyperliquid/hl-precision.js +0 -176
  366. package/assets/plugin/venues/hyperliquid/hl-private.d.ts +0 -88
  367. package/assets/plugin/venues/hyperliquid/hl-private.js +0 -357
  368. package/assets/plugin/venues/hyperliquid/hl-public.d.ts +0 -79
  369. package/assets/plugin/venues/hyperliquid/hl-public.js +0 -436
  370. package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +0 -57
  371. package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +0 -220
  372. package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +0 -90
  373. package/assets/plugin/venues/hyperliquid/hl-user-stream.js +0 -220
  374. package/assets/plugin/venues/registry.d.ts +0 -38
  375. package/assets/plugin/venues/registry.js +0 -46
  376. package/assets/plugin/venues/symbols.d.ts +0 -43
  377. package/assets/plugin/venues/symbols.js +0 -107
  378. package/assets/plugin/wave9/live-account-capture.d.ts +0 -67
  379. package/assets/plugin/wave9/live-account-capture.js +0 -435
  380. package/assets/plugin/wave9/live-autonomous-protection.d.ts +0 -39
  381. package/assets/plugin/wave9/live-autonomous-protection.js +0 -112
  382. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +0 -33
  383. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +0 -115
  384. package/assets/plugin/wave9/live-execution-ledger.d.ts +0 -107
  385. package/assets/plugin/wave9/live-execution-ledger.js +0 -498
  386. package/assets/plugin/wave9/live-position-confirmation.d.ts +0 -18
  387. package/assets/plugin/wave9/live-position-confirmation.js +0 -111
  388. package/assets/plugin/wave9/live-residual-protection.d.ts +0 -18
  389. package/assets/plugin/wave9/live-residual-protection.js +0 -250
  390. package/assets/plugin/wave9/live-startup-reconciliation.d.ts +0 -38
  391. package/assets/plugin/wave9/live-startup-reconciliation.js +0 -454
  392. package/assets/plugin/wave9/live-symbol-ownership.d.ts +0 -20
  393. package/assets/plugin/wave9/live-symbol-ownership.js +0 -132
  394. package/assets/plugin/wave9/paper-admission-guard.d.ts +0 -199
  395. package/assets/plugin/wave9/paper-admission-guard.js +0 -650
  396. package/assets/plugin/wave9/usdm-evidence-provider.d.ts +0 -42
  397. package/assets/plugin/wave9/usdm-evidence-provider.js +0 -133
@@ -1,704 +0,0 @@
1
- // UserDataStream — the authenticated Binance Futures user-data WebSocket.
2
- //
3
- // What it does:
4
- // 1. Mints a listenKey (via ListenKeyManager) and opens a WebSocket to
5
- // `wss://fstream.binance.com/private/ws/<listenKey>` (testnet: `stream.binancefuture.com`).
6
- // 2. Parses incoming frames into typed events (ACCOUNT_UPDATE,
7
- // ORDER_TRADE_UPDATE, ALGO_UPDATE, MARGIN_CALL, ACCOUNT_CONFIG_UPDATE,
8
- // listenKeyExpired).
9
- // 3. Emits those events for the parent (typically LiveStateStore +
10
- // LiveAdapter) to apply.
11
- // 4. Handles reconnects with exponential backoff + jitter, staleness
12
- // watchdog, graduated alert thresholds, and listenKey rotation.
13
- //
14
- // What it does NOT do:
15
- // - No state management. The store (`LiveStateStore`) applies events.
16
- // - No REST snapshot logic. The parent calls its own REST on
17
- // `'reconnect'` / `'connected'` so the store can re-seed.
18
- // - No 60s reconciler. That lives separately (see PositionReconciler).
19
- //
20
- // Testability:
21
- // - `webSocketFactory` is injectable → tests use a mock WebSocket.
22
- // - `timers` is injectable → fake-timer tests drive backoff + watchdog.
23
- // - `listenKeyManager` is injectable → tests don't hit the network.
24
- //
25
- // Rule of thumb: this class is a thin, well-logged translator from Binance
26
- // framing to our domain events. All business logic belongs upstream.
27
- import { EventEmitter } from 'node:events';
28
- import { ListenKeyManager } from './listen-key-manager.js';
29
- import { logger, formatError } from '../logger.js';
30
- const TAG = 'user-data-stream';
31
- const REAL_TIMERS = {
32
- setTimeout: (fn, ms) => setTimeout(fn, ms),
33
- clearTimeout: (h) => clearTimeout(h),
34
- setInterval: (fn, ms) => setInterval(fn, ms),
35
- clearInterval: (h) => clearInterval(h),
36
- now: () => Date.now(),
37
- random: () => Math.random(),
38
- };
39
- // ---- The class ----
40
- export class UserDataStream extends EventEmitter {
41
- api;
42
- opts;
43
- webSocketFactory;
44
- timers;
45
- listenKeyManager;
46
- translateSymbol;
47
- ws = null;
48
- status = 'stopped';
49
- reconnectTimer = null;
50
- watchdogInterval = null;
51
- lastEventAt = null;
52
- lastFrameAt = null;
53
- lastConnectedAt = null;
54
- consecutiveReconnects = 0;
55
- totalReconnects = 0;
56
- stopRequested = false;
57
- firstConnect = true;
58
- /** First-N raw ALGO_UPDATE payloads logged at INFO so operators can verify
59
- * the parser against real Binance traffic without scraping the WS at
60
- * TRACE. Capped to avoid log volume; resets per process restart. */
61
- algoUpdateRawLogged = 0;
62
- static ALGO_UPDATE_RAW_LOG_CAP = 20;
63
- constructor(api, options) {
64
- super();
65
- this.api = api;
66
- this.opts = {
67
- wsBaseUrl: options.wsBaseUrl,
68
- reconnectBaseMs: options.reconnectBaseMs ?? 1_000,
69
- reconnectCapMs: options.reconnectCapMs ?? 60_000,
70
- reconnectJitterPct: options.reconnectJitterPct ?? 0.2,
71
- staleEventWatchdogMs: options.staleEventWatchdogMs ?? 6 * 60_000,
72
- warnThreshold: options.warnThreshold ?? 3,
73
- errorThreshold: options.errorThreshold ?? 10,
74
- fatalThreshold: options.fatalThreshold ?? 30,
75
- };
76
- this.webSocketFactory = options.webSocketFactory;
77
- this.timers = {
78
- setTimeout: options.timers?.setTimeout ?? REAL_TIMERS.setTimeout,
79
- clearTimeout: options.timers?.clearTimeout ?? REAL_TIMERS.clearTimeout,
80
- setInterval: options.timers?.setInterval ?? REAL_TIMERS.setInterval,
81
- clearInterval: options.timers?.clearInterval ?? REAL_TIMERS.clearInterval,
82
- now: options.timers?.now ?? REAL_TIMERS.now,
83
- random: options.timers?.random ?? REAL_TIMERS.random,
84
- };
85
- const makeListenKeyMgr = options.listenKeyManagerFactory
86
- ?? ((a, o) => new ListenKeyManager(a, o));
87
- this.listenKeyManager = makeListenKeyMgr(api, options.listenKey);
88
- this.translateSymbol = options.symbolTranslator
89
- ?? ((id) => api.symbolFromMarketId(id));
90
- this.listenKeyManager.on('keyKeepAliveFailed', (reason) => {
91
- logger.warn(TAG, `listenKey keep-alive failed — forcing reconnect: ${reason}`);
92
- // Forcing a reconnect will re-mint a fresh key as part of start().
93
- this.forceReconnect('listen_key_keepalive_failed');
94
- });
95
- }
96
- /** Start the stream. Idempotent — returns immediately if already running. */
97
- async start() {
98
- if (this.status !== 'stopped') {
99
- logger.warn(TAG, `start() called while status=${this.status} — ignored`);
100
- return;
101
- }
102
- this.stopRequested = false;
103
- this.consecutiveReconnects = 0;
104
- this.firstConnect = true;
105
- await this.openConnection();
106
- this.startWatchdog();
107
- }
108
- /** Graceful stop. Closes WS + stops listenKey. Idempotent. */
109
- async stop() {
110
- this.stopRequested = true;
111
- this.clearReconnectTimer();
112
- this.stopWatchdog();
113
- if (this.ws) {
114
- try {
115
- this.ws.close(1000, 'client shutdown');
116
- }
117
- catch { /* best-effort */ }
118
- this.ws = null;
119
- }
120
- try {
121
- await this.listenKeyManager.stop();
122
- }
123
- catch (err) {
124
- logger.warn(TAG, `listenKey stop failed (non-fatal): ${formatError(err)}`);
125
- }
126
- this.setStatus('stopped');
127
- }
128
- /** Current health snapshot for observability. */
129
- getHealth() {
130
- return {
131
- status: this.status,
132
- currentListenKey: this.listenKeyManager.getKey(),
133
- lastEventAt: this.lastEventAt,
134
- lastFrameAt: this.lastFrameAt,
135
- lastConnectedAt: this.lastConnectedAt,
136
- consecutiveReconnectAttempts: this.consecutiveReconnects,
137
- totalReconnects: this.totalReconnects,
138
- };
139
- }
140
- /** Whether the stream is currently open. Convenience for tests + callers. */
141
- isConnected() {
142
- return this.status === 'open';
143
- }
144
- // ---- Internal: connection lifecycle ----
145
- async openConnection() {
146
- if (this.stopRequested)
147
- return;
148
- this.setStatus('connecting');
149
- let key;
150
- try {
151
- key = await this.listenKeyManager.start();
152
- }
153
- catch (err) {
154
- logger.error(TAG, `listenKey mint failed: ${formatError(err)}`);
155
- this.scheduleReconnect('listen_key_mint_failed');
156
- return;
157
- }
158
- const url = `${this.opts.wsBaseUrl}/${key}`;
159
- logger.info(TAG, `Opening WS to ${this.opts.wsBaseUrl}/<listenKey> (hash=${hash8(key)})`);
160
- let socket;
161
- try {
162
- socket = this.webSocketFactory(url);
163
- }
164
- catch (err) {
165
- logger.error(TAG, `webSocketFactory threw: ${formatError(err)}`);
166
- this.scheduleReconnect('ws_factory_failed');
167
- return;
168
- }
169
- this.ws = socket;
170
- this.attachWsHandlers(socket);
171
- }
172
- attachWsHandlers(socket) {
173
- socket.on('open', () => {
174
- if (this.ws !== socket)
175
- return; // stale
176
- this.lastConnectedAt = this.timers.now();
177
- this.lastEventAt = this.lastConnectedAt;
178
- this.lastFrameAt = this.lastConnectedAt;
179
- this.consecutiveReconnects = 0;
180
- this.setStatus('open');
181
- logger.info(TAG, 'WS connected');
182
- this.emit('connected');
183
- if (!this.firstConnect) {
184
- this.emit('resyncRequired', 'reconnect');
185
- }
186
- this.firstConnect = false;
187
- });
188
- socket.on('message', (data) => {
189
- if (this.ws !== socket)
190
- return;
191
- const now = this.timers.now();
192
- this.lastEventAt = now; // data event — drives the active probe's freshness check
193
- this.lastFrameAt = now; // any frame — drives the dead-socket watchdog
194
- this.handleFrame(data);
195
- });
196
- socket.on('ping', (payload) => {
197
- if (this.ws !== socket)
198
- return;
199
- // Server ping = liveness signal even on a fully-idle account. Binance
200
- // documents these every 3 min on the user-data stream, so counting them
201
- // toward `lastFrameAt` keeps the watchdog quiet between data frames.
202
- // Note: `lastEventAt` is intentionally NOT updated — pings carry no data
203
- // so the active REST probe still sees them as silence (correct, the probe
204
- // is checking for missed FILLS not missed liveness).
205
- this.lastFrameAt = this.timers.now();
206
- // Most `ws` clients pong automatically; in case a custom factory doesn't,
207
- // reply here. Binance closes the socket if no pong arrives within 10 min.
208
- try {
209
- socket.pong?.(payload);
210
- }
211
- catch { /* best-effort */ }
212
- });
213
- socket.on('pong', () => {
214
- if (this.ws !== socket)
215
- return;
216
- // Server-sent pong (in response to a client-initiated ping if any). Same
217
- // liveness role as `ping` above. Kept for observability symmetry.
218
- this.lastFrameAt = this.timers.now();
219
- });
220
- socket.on('error', (err) => {
221
- if (this.ws !== socket)
222
- return;
223
- logger.warn(TAG, `WS error: ${formatError(err)}`);
224
- // 'close' will follow. Don't schedule reconnect here to avoid double-firing.
225
- });
226
- socket.on('close', (code, reason) => {
227
- if (this.ws !== socket)
228
- return;
229
- let reasonStr;
230
- if (reason == null)
231
- reasonStr = '';
232
- else if (typeof reason === 'string')
233
- reasonStr = reason;
234
- else
235
- reasonStr = reason.toString('utf-8');
236
- logger.warn(TAG, `WS closed code=${code ?? '?'} reason=${reasonStr || '(none)'}`);
237
- this.ws = null;
238
- // Stop the keep-alive loop WITHOUT DELETEing the key; the next connect
239
- // re-POSTs. Binance's re-POST returns the SAME active key (doc-verified),
240
- // so the previous un-awaited DELETE here could land AFTER the reconnect's
241
- // POST and invalidate the key the fresh socket just authenticated with.
242
- // The graceful path (stop() below / UserDataStream.stop()) still DELETEs —
243
- // no reconnect follows there.
244
- this.listenKeyManager.stopKeepAlive();
245
- if (this.stopRequested) {
246
- this.setStatus('stopped');
247
- this.emit('disconnected', reasonStr || 'client stop', false);
248
- return;
249
- }
250
- this.emit('disconnected', reasonStr || `code=${code ?? '?'}`, true);
251
- this.scheduleReconnect(reasonStr || 'ws_close');
252
- });
253
- }
254
- handleFrame(raw) {
255
- let parsed;
256
- try {
257
- const text = typeof raw === 'string' ? raw : raw.toString('utf-8');
258
- parsed = JSON.parse(text);
259
- }
260
- catch (err) {
261
- logger.warn(TAG, `frame parse failed (ignored): ${formatError(err)}`);
262
- return;
263
- }
264
- if (!parsed || typeof parsed !== 'object')
265
- return;
266
- const obj = parsed;
267
- const eventType = typeof obj.e === 'string' ? obj.e : null;
268
- if (!eventType) {
269
- // Binance occasionally sends pong-like keepalive frames w/o 'e'. Swallow.
270
- return;
271
- }
272
- try {
273
- switch (eventType) {
274
- case 'ACCOUNT_UPDATE': {
275
- const ev = parseAccountUpdate(obj, this.translateSymbol);
276
- if (ev)
277
- this.emit('accountUpdate', ev);
278
- break;
279
- }
280
- case 'ORDER_TRADE_UPDATE': {
281
- const ev = parseOrderUpdate(obj, this.translateSymbol);
282
- if (ev)
283
- this.emit('orderUpdate', ev);
284
- break;
285
- }
286
- case 'ALGO_UPDATE': {
287
- // Binance fires this for STOP_MARKET / TAKE_PROFIT_MARKET /
288
- // TRAILING_STOP_MARKET conditional orders. Pre-2026-05-15 we
289
- // swallowed this at the default branch — that left the plugin
290
- // blind to exchange-side bracket cancellation, which is the
291
- // root cause of the bracket-spiral class of bug. We now parse +
292
- // emit; the downstream listener (controller + LiveAdapter) is
293
- // responsible for the action.
294
- const ev = parseAlgoUpdate(obj, this.translateSymbol);
295
- if (ev) {
296
- if (this.algoUpdateRawLogged < UserDataStream.ALGO_UPDATE_RAW_LOG_CAP) {
297
- // Capped to avoid flooding the journal under heavy bracket
298
- // traffic. Operators read these first-N samples once after
299
- // deploy to verify the parser matches Binance's actual shape.
300
- logger.info(TAG, `ALGO_UPDATE raw (${this.algoUpdateRawLogged + 1}/` +
301
- `${UserDataStream.ALGO_UPDATE_RAW_LOG_CAP}): ${JSON.stringify(obj)}`);
302
- this.algoUpdateRawLogged++;
303
- }
304
- this.emit('algoUpdate', ev);
305
- }
306
- break;
307
- }
308
- case 'TRADE_LITE': {
309
- // Binance's newer lightweight fill notification (late-2024 addition).
310
- // Same information as ORDER_TRADE_UPDATE but sent earlier for lower
311
- // fill-latency. ORDER_TRADE_UPDATE follows with the canonical state
312
- // transition, so we deliberately don't double-apply — TRADE_LITE is
313
- // informational here. Log at debug-ish level (info) so operators
314
- // can confirm Binance is sending it.
315
- logger.info(TAG, 'TRADE_LITE received (canonical state follows in ORDER_TRADE_UPDATE)');
316
- break;
317
- }
318
- case 'MARGIN_CALL': {
319
- const ev = parseMarginCall(obj, this.translateSymbol);
320
- if (ev)
321
- this.emit('marginCall', ev);
322
- break;
323
- }
324
- case 'ACCOUNT_CONFIG_UPDATE': {
325
- const ev = parseAccountConfigUpdate(obj, this.translateSymbol);
326
- if (ev)
327
- this.emit('accountConfigUpdate', ev);
328
- break;
329
- }
330
- case 'listenKeyExpired': {
331
- logger.warn(TAG, 'listenKey expired notice from Binance — forcing reconnect');
332
- this.emit('listenKeyExpired');
333
- this.forceReconnect('listen_key_expired');
334
- break;
335
- }
336
- default:
337
- // Unknown event type. Binance adds new types over time; swallow at
338
- // WARN so we notice but don't crash.
339
- logger.warn(TAG, `unknown event type=${eventType} — swallowed`);
340
- }
341
- }
342
- catch (err) {
343
- logger.warn(TAG, `event handler for ${eventType} threw: ${formatError(err)}`);
344
- }
345
- }
346
- // ---- Internal: reconnect + watchdog ----
347
- scheduleReconnect(reason) {
348
- this.clearReconnectTimer();
349
- if (this.stopRequested)
350
- return;
351
- this.consecutiveReconnects += 1;
352
- this.totalReconnects += 1;
353
- // Graduated alerts — easier to tune alerting later.
354
- if (this.consecutiveReconnects >= this.opts.fatalThreshold) {
355
- logger.error(TAG, `RECONNECT-FATAL attempt=${this.consecutiveReconnects} reason=${reason}`);
356
- }
357
- else if (this.consecutiveReconnects >= this.opts.errorThreshold) {
358
- logger.error(TAG, `RECONNECT-ERROR attempt=${this.consecutiveReconnects} reason=${reason}`);
359
- }
360
- else if (this.consecutiveReconnects >= this.opts.warnThreshold) {
361
- logger.warn(TAG, `RECONNECT-WARN attempt=${this.consecutiveReconnects} reason=${reason}`);
362
- }
363
- const delay = this.computeBackoffMs(this.consecutiveReconnects);
364
- logger.info(TAG, `reconnect attempt=${this.consecutiveReconnects} delayMs=${delay} reason=${reason}`);
365
- this.setStatus('reconnecting');
366
- this.emit('reconnecting', this.consecutiveReconnects, delay);
367
- this.reconnectTimer = this.timers.setTimeout(() => {
368
- this.reconnectTimer = null;
369
- void this.openConnection();
370
- }, delay);
371
- }
372
- computeBackoffMs(attempt) {
373
- // Exponential: base * 2^(attempt-1). Capped. Then ± jitterPct.
374
- const exp = this.opts.reconnectBaseMs * 2 ** Math.min(attempt - 1, 20);
375
- const capped = Math.min(exp, this.opts.reconnectCapMs);
376
- const jitterRange = capped * this.opts.reconnectJitterPct;
377
- const jitter = (this.timers.random() * 2 - 1) * jitterRange;
378
- return Math.max(0, Math.round(capped + jitter));
379
- }
380
- clearReconnectTimer() {
381
- if (this.reconnectTimer) {
382
- this.timers.clearTimeout(this.reconnectTimer);
383
- this.reconnectTimer = null;
384
- }
385
- }
386
- /** Force a reconnect now — used when the server tells us the key expired
387
- * or when the listenKey keep-alive loop gives up.
388
- *
389
- * Invariant: the close handler is responsible for clearing `this.ws`,
390
- * stopping the listenKey loop, and scheduling the reconnect. We only
391
- * trigger close() here and let the handler run. If there's no socket to
392
- * close (manager dropped out-of-band), we schedule directly. */
393
- forceReconnect(reason) {
394
- if (this.stopRequested)
395
- return;
396
- if (this.ws) {
397
- // The socket is PRESUMED DEAD here (staleness watchdog fired, listenKey
398
- // expired, keep-alive gave up, or the active REST probe asked for a
399
- // resync). Prefer terminate() over close(): `ws.close(4001)` starts a
400
- // closing HANDSHAKE and the `ws` library waits up to ~30s for the
401
- // server's reciprocal close frame before it emits 'close' — on a truly
402
- // dead TCP path that stalls the whole reconnect for the timeout.
403
- // terminate() drops the socket immediately (emits 'close' with code
404
- // 1006), so the reconnect fires right away. Same reasoning as the
405
- // intel-side routed-WS watchdog (binance-routed-ws.ts:
406
- // `ws.terminate()`). Fall back to close() when the socket doesn't
407
- // expose terminate() (a browser/test socket without it).
408
- const sock = this.ws;
409
- try {
410
- if (typeof sock.terminate === 'function')
411
- sock.terminate();
412
- else
413
- sock.close(4001, reason);
414
- }
415
- catch { /* best-effort — the 'close' handler still runs cleanup once */ }
416
- // Do NOT null this.ws here — the close handler needs it to pass the
417
- // `ws === socket` identity check and run cleanup exactly once.
418
- return;
419
- }
420
- // No socket in hand — schedule reconnect directly.
421
- if (this.status !== 'reconnecting') {
422
- this.scheduleReconnect(reason);
423
- }
424
- }
425
- startWatchdog() {
426
- // Fire the check every 30s — a 6-min threshold doesn't need finer
427
- // resolution, and a less chatty interval cuts log noise during the steady
428
- // state where the watchdog should never fire.
429
- this.stopWatchdog();
430
- this.watchdogInterval = this.timers.setInterval(() => {
431
- if (this.status !== 'open' || this.stopRequested)
432
- return;
433
- const now = this.timers.now();
434
- // Compare against `lastFrameAt` — the most recent INCOMING FRAME of any
435
- // kind, including server pings (every 3 min on the Binance user-data
436
- // stream). The earlier design compared against `lastEventAt` (message
437
- // frames only) and false-fired ~200×/day on idle accounts because
438
- // Binance pushes no message frames between events on a quiet position.
439
- const last = this.lastFrameAt ?? this.lastConnectedAt ?? now;
440
- const idle = now - last;
441
- if (idle > this.opts.staleEventWatchdogMs) {
442
- logger.warn(TAG, `staleness watchdog fired: idleMs=${idle} > ${this.opts.staleEventWatchdogMs} (no frames — likely dead socket)`);
443
- this.emit('staleForcedReconnect', idle);
444
- this.forceReconnect('stale_event_watchdog');
445
- }
446
- }, 30_000);
447
- }
448
- /** External trigger for a reconnect — used by the active REST probe when
449
- * it detects a fill that the WS missed. Same plumbing as the watchdog
450
- * path; the close handler runs the reconnect schedule. */
451
- requestReconnect(reason) {
452
- this.forceReconnect(reason);
453
- }
454
- stopWatchdog() {
455
- if (this.watchdogInterval) {
456
- this.timers.clearInterval(this.watchdogInterval);
457
- this.watchdogInterval = null;
458
- }
459
- }
460
- setStatus(next) {
461
- this.status = next;
462
- }
463
- }
464
- // ---- Frame parsers ----
465
- function num(v) {
466
- if (typeof v === 'number' && Number.isFinite(v))
467
- return v;
468
- if (typeof v === 'string') {
469
- const n = Number(v);
470
- if (Number.isFinite(n))
471
- return n;
472
- }
473
- return 0;
474
- }
475
- function str(v) {
476
- return typeof v === 'string' ? v : String(v ?? '');
477
- }
478
- function optStr(v) {
479
- if (v == null)
480
- return undefined;
481
- return typeof v === 'string' ? v : String(v);
482
- }
483
- const IDENTITY = (s) => s;
484
- export function parseAccountUpdate(obj, translateSymbol = IDENTITY) {
485
- const a = obj.a;
486
- if (!a)
487
- return null;
488
- const positionsRaw = Array.isArray(a.P) ? a.P : [];
489
- const balancesRaw = Array.isArray(a.B) ? a.B : [];
490
- const positions = positionsRaw.map((p) => {
491
- const qtySigned = num(p.pa);
492
- const positionSide = str(p.ps);
493
- // In one-way mode, side is derived from the sign of pa.
494
- // In hedge mode, ps is LONG or SHORT directly.
495
- let side;
496
- if (positionSide === 'LONG')
497
- side = qtySigned > 0 ? 'long' : 'flat';
498
- else if (positionSide === 'SHORT')
499
- side = qtySigned < 0 ? 'short' : 'flat';
500
- else {
501
- if (qtySigned > 0)
502
- side = 'long';
503
- else if (qtySigned < 0)
504
- side = 'short';
505
- else
506
- side = 'flat';
507
- }
508
- const mtRaw = str(p.mt).toLowerCase();
509
- const marginType = mtRaw === 'isolated' ? 'isolated' : 'cross';
510
- return {
511
- symbol: translateSymbol(str(p.s)),
512
- side,
513
- quantity: Math.abs(qtySigned),
514
- entryPrice: num(p.ep),
515
- unrealizedPnl: num(p.up),
516
- marginType,
517
- positionSide,
518
- };
519
- });
520
- const balances = balancesRaw.map((b) => ({
521
- asset: str(b.a),
522
- walletBalance: num(b.wb),
523
- crossWallet: num(b.cw),
524
- balanceChange: num(b.bc),
525
- }));
526
- return {
527
- eventTime: num(obj.E),
528
- transactionTime: num(obj.T),
529
- reason: str(a.m),
530
- positions,
531
- balances,
532
- };
533
- }
534
- export function parseOrderUpdate(obj, translateSymbol = IDENTITY) {
535
- const o = obj.o;
536
- if (!o)
537
- return null;
538
- const orderStatus = str(o.X);
539
- let status;
540
- switch (orderStatus) {
541
- case 'NEW':
542
- case 'PARTIALLY_FILLED':
543
- status = 'open';
544
- break;
545
- case 'FILLED':
546
- status = 'closed';
547
- break;
548
- case 'CANCELED':
549
- case 'EXPIRED':
550
- case 'REJECTED':
551
- case 'EXPIRED_IN_MATCH':
552
- status = 'canceled';
553
- break;
554
- default:
555
- status = 'open';
556
- }
557
- const typeRaw = str(o.o).toUpperCase();
558
- let type;
559
- switch (typeRaw) {
560
- case 'LIMIT':
561
- type = 'limit';
562
- break;
563
- case 'MARKET':
564
- type = 'market';
565
- break;
566
- case 'STOP_MARKET':
567
- type = 'stop_market';
568
- break;
569
- case 'TAKE_PROFIT_MARKET':
570
- type = 'take_profit_market';
571
- break;
572
- default: type = 'other';
573
- }
574
- const sideRaw = str(o.S).toUpperCase();
575
- const side = sideRaw === 'SELL' ? 'sell' : 'buy';
576
- const origPrice = o.p != null && str(o.p) !== '' ? num(o.p) : null;
577
- const avgPrice = o.ap != null && num(o.ap) > 0 ? num(o.ap) : null;
578
- const lastFillPrice = o.L != null && num(o.L) > 0 ? num(o.L) : null;
579
- // Audit-trail fields. `o.t` is Binance's stable trade id, present only on
580
- // executionType='TRADE' (fill events); for NEW / CANCELED / EXPIRED it's
581
- // either absent or 0. We store null in those cases so callers don't
582
- // accidentally upsert with a meaningless id.
583
- const tradeIdRaw = o.t;
584
- const tradeId = tradeIdRaw != null && str(tradeIdRaw) !== '' && str(tradeIdRaw) !== '0'
585
- ? str(tradeIdRaw)
586
- : null;
587
- return {
588
- eventTime: num(obj.E),
589
- transactionTime: num(obj.T),
590
- symbol: translateSymbol(str(o.s)),
591
- orderId: str(o.i),
592
- clientOrderId: optStr(o.c),
593
- side,
594
- type,
595
- status,
596
- executionType: str(o.x),
597
- origQuantity: num(o.q),
598
- cumulativeFilled: num(o.z),
599
- lastFilledQty: num(o.l),
600
- avgPrice,
601
- origPrice,
602
- lastFillPrice,
603
- commission: num(o.n),
604
- commissionAsset: str(o.N),
605
- timeInForce: str(o.f),
606
- tradeId,
607
- reduceOnly: o.R === true,
608
- maker: o.m === true,
609
- realizedPnl: num(o.rp),
610
- };
611
- }
612
- export function parseMarginCall(obj, translateSymbol = IDENTITY) {
613
- const positionsRaw = Array.isArray(obj.p) ? obj.p : [];
614
- return {
615
- eventTime: num(obj.E),
616
- crossWallet: num(obj.cw),
617
- positions: positionsRaw.map((p) => ({
618
- symbol: translateSymbol(str(p.s)),
619
- positionSide: str(p.ps),
620
- positionAmt: num(p.pa),
621
- marginType: str(p.mt).toLowerCase() === 'isolated' ? 'isolated' : 'cross',
622
- isolatedWallet: num(p.iw),
623
- markPrice: num(p.mp),
624
- unrealizedPnl: num(p.up),
625
- maintMargin: num(p.mm),
626
- })),
627
- };
628
- }
629
- export function parseAlgoUpdate(obj, translateSymbol = IDENTITY) {
630
- // Field shape verified 2026-05-15 against the authoritative Binance doc
631
- // (developers.binance.com → USD-M Futures → User Data Streams → Event
632
- // Algo Order Update) AND a raw prod ALGO_UPDATE capture. The earlier
633
- // implementation guessed `ao`/`a` wrapper + `c`/`sp`/`as`/`r` keys — ALL
634
- // wrong; it parsed nothing. Binance wraps the algo-order detail under `o`:
635
- // { "e":"ALGO_UPDATE","T","E","o":{ caid, aid, at, o, s, S, ps, f, q,
636
- // X, ai, ap, aq, act, tp, p, V, wt, pm, cp, pP, R, tt, gtd, rm } }
637
- // where (doc-exact):
638
- // caid = Client Algo Id aid = Algo Id s = Symbol
639
- // S = Side o = Order Type X = Algo Status
640
- // tp = Trigger Price q = Quantity R = Reduce Only
641
- // f = Time In Force V = STP Mode rm = Failure Reason
642
- // ai = Order Id (matching-engine order id, NOT the algo id)
643
- const o = obj.o;
644
- if (!o)
645
- return null;
646
- const rawSym = optStr(o.s);
647
- if (!rawSym)
648
- return null;
649
- const sideRaw = str(o.S).toUpperCase();
650
- const side = sideRaw === 'SELL' ? 'sell' : 'buy';
651
- // Algo Status `X`: NEW / TRIGGERING / TRIGGERED / FINISHED / CANCELED /
652
- // REJECTED / EXPIRED. Semantics that matter downstream (doc-confirmed):
653
- // CANCELED = MANUALLY canceled (an explicit cancelOrder from us)
654
- // EXPIRED = SYSTEM-canceled (e.g. GTE_GTC conditional + position closed
655
- // → Binance auto-cancels the surviving sibling). EXPECTED.
656
- const statusRaw = str(o.X).toUpperCase();
657
- // Trigger price is `tp` (doc-exact). `p` is the (limit) order price, 0 for
658
- // market-type triggers.
659
- const trigRaw = o.tp;
660
- const triggerPrice = trigRaw != null && num(trigRaw) > 0 ? num(trigRaw) : null;
661
- return {
662
- eventTime: num(obj.E),
663
- transactionTime: num(obj.T),
664
- symbol: translateSymbol(rawSym),
665
- algoId: str(o.aid ?? ''),
666
- clientAlgoId: optStr(o.caid) ?? null,
667
- side,
668
- orderType: str(o.o ?? '').toUpperCase(),
669
- status: statusRaw,
670
- triggerPrice,
671
- quantity: num(o.q),
672
- reduceOnly: o.R === true,
673
- // `rm` = Failure Reason (doc-exact). Present on REJECTED/EXPIRED.
674
- reason: optStr(o.rm),
675
- raw: obj,
676
- };
677
- }
678
- export function parseAccountConfigUpdate(obj, translateSymbol = IDENTITY) {
679
- const ac = obj.ac; // leverage
680
- const ai = obj.ai; // multi-asset mode
681
- if (ac) {
682
- const rawSym = optStr(ac.s);
683
- return {
684
- eventTime: num(obj.E),
685
- kind: 'leverage',
686
- symbol: rawSym ? translateSymbol(rawSym) : undefined,
687
- leverage: num(ac.l),
688
- };
689
- }
690
- if (ai) {
691
- return {
692
- eventTime: num(obj.E),
693
- kind: 'multi_asset_mode',
694
- multiAssetMode: Boolean(ai.j),
695
- };
696
- }
697
- return {
698
- eventTime: num(obj.E),
699
- kind: 'other',
700
- };
701
- }
702
- function hash8(key) {
703
- return key.length > 8 ? key.slice(0, 8) : '(short)';
704
- }