@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,78 +0,0 @@
1
- // Slippage tracker — records expected vs actual fill price for every live order.
2
- // Computes slippage in basis points and tracks statistics per symbol.
3
- import { logger } from '../logger.js';
4
- const TAG = 'slippage';
5
- export class SlippageTracker {
6
- records = [];
7
- maxRecords;
8
- constructor(maxRecords = 1000) {
9
- this.maxRecords = maxRecords;
10
- }
11
- /** Record a fill with slippage measurement. */
12
- recordFill(params) {
13
- // Slippage: positive means worse execution for the order side
14
- // For buy: actual > expected = positive slippage (paid more)
15
- // For sell: actual < expected = positive slippage (received less)
16
- let slippageBps;
17
- if (params.side === 'buy') {
18
- slippageBps = ((params.actualPrice - params.expectedPrice) / params.expectedPrice) * 10_000;
19
- }
20
- else {
21
- slippageBps = ((params.expectedPrice - params.actualPrice) / params.expectedPrice) * 10_000;
22
- }
23
- const record = {
24
- ...params,
25
- slippageBps,
26
- timestamp: Date.now(),
27
- };
28
- this.records.push(record);
29
- // Circular buffer
30
- if (this.records.length > this.maxRecords) {
31
- this.records.shift();
32
- }
33
- logger.info(TAG, `${params.symbol} ${params.side}: expected=${params.expectedPrice}, actual=${params.actualPrice}, slippage=${slippageBps.toFixed(2)}bps`);
34
- return record;
35
- }
36
- /** Get average slippage in bps for a symbol. */
37
- getAverageSlippage(symbol) {
38
- const relevant = symbol
39
- ? this.records.filter(r => r.symbol === symbol)
40
- : this.records;
41
- if (relevant.length === 0)
42
- return 0;
43
- return relevant.reduce((s, r) => s + r.slippageBps, 0) / relevant.length;
44
- }
45
- /** Get slippage stats summary. */
46
- getStats(symbol) {
47
- const relevant = symbol
48
- ? this.records.filter(r => r.symbol === symbol)
49
- : this.records;
50
- if (relevant.length === 0) {
51
- return { count: 0, avgBps: 0, maxBps: 0, minBps: 0, p95Bps: 0, totalCost: 0 };
52
- }
53
- const bps = relevant.map(r => r.slippageBps).sort((a, b) => a - b);
54
- const p95Idx = Math.floor(bps.length * 0.95);
55
- return {
56
- count: relevant.length,
57
- avgBps: bps.reduce((s, v) => s + v, 0) / bps.length,
58
- maxBps: bps[bps.length - 1],
59
- minBps: bps[0],
60
- p95Bps: bps[p95Idx],
61
- totalCost: relevant.reduce((s, r) => {
62
- // Cost of slippage = (actualPrice - expectedPrice) * amount
63
- const diff = r.side === 'buy'
64
- ? (r.actualPrice - r.expectedPrice)
65
- : (r.expectedPrice - r.actualPrice);
66
- return s + diff * r.amount;
67
- }, 0),
68
- };
69
- }
70
- /** Get recent records (last N). */
71
- getRecent(count = 10) {
72
- return this.records.slice(-count);
73
- }
74
- /** Get all records for a symbol. */
75
- getRecordsForSymbol(symbol) {
76
- return this.records.filter(r => r.symbol === symbol);
77
- }
78
- }
@@ -1,67 +0,0 @@
1
- import { EventEmitter } from 'node:events';
2
- import type { IExchangeAdapter } from '../exchange-adapter.js';
3
- import type { CcxtOrder, CcxtPosition } from '../types.js';
4
- import type { TradingOperationLock } from '../lifecycle/trading-operation-lock.js';
5
- export declare const DEFAULT_INTERVAL_MS = 10000;
6
- export interface StopTriggeredEvent {
7
- symbol: string;
8
- side: 'long' | 'short';
9
- stopPrice: number;
10
- markPrice: number;
11
- quantity: number;
12
- }
13
- /** Emitted with 'stop_closed' — carries the executed close order so listeners
14
- * (the journal auto-capture wiring in index.ts) can record the close with the
15
- * real fill. Without this, watcher closes bypassed the Position Decision
16
- * Journal entirely and left phantom-open journal positions (issue #199). */
17
- export interface StopClosedEvent extends StopTriggeredEvent {
18
- order?: CcxtOrder;
19
- }
20
- export type Wave9StopCloseOutcome = {
21
- status: 'flat';
22
- detail: string;
23
- candidateId: string;
24
- symbol: string;
25
- } | {
26
- status: 'protected' | 'manual_intervention';
27
- detail: string;
28
- candidateId: string;
29
- symbol: string;
30
- stopPrice: number;
31
- residualQuantity?: number;
32
- stopClientOrderId?: string;
33
- };
34
- /** Optional durable Wave 9 lifecycle. Generic watcher behavior is unchanged
35
- * when this is absent or the current position has no owned candidate. */
36
- export interface Wave9StopCloseLifecycle {
37
- resolveCandidateId(position: CcxtPosition): Promise<string | undefined> | string | undefined;
38
- settleAfterClose(candidateId: string, symbol: string): Promise<Wave9StopCloseOutcome>;
39
- }
40
- /** Decide whether a position has crossed its stop.
41
- * Exported for direct unit-testing without spinning up a watcher loop. */
42
- export declare function isStopBreached(position: CcxtPosition): boolean;
43
- export declare class PositionWatcher extends EventEmitter {
44
- private interval;
45
- private intervalMs;
46
- private adapter;
47
- private readonly operationLock?;
48
- private wave9CloseLifecycle?;
49
- /** Symbols currently awaiting a close RPC — second trigger in the same tick
50
- * is suppressed so the watcher cannot double-close. Cleared after the close
51
- * call resolves (success or failure). */
52
- private closePending;
53
- /** Symbols we've already logged a breach for this session, to avoid spamming
54
- * the log every tick while the close is in flight. */
55
- private notifiedBreach;
56
- constructor(adapter: IExchangeAdapter, intervalMs?: number, operationLock?: TradingOperationLock);
57
- /** Configure this after the durable execution ledger is ready. Runtime
58
- * lifecycle hooks reapply it to every watcher after reconnect. */
59
- setWave9CloseLifecycle(lifecycle?: Wave9StopCloseLifecycle): void;
60
- start(): void;
61
- stop(): void;
62
- /** Run one check cycle. Exposed for tests (skip setInterval). */
63
- tick(): Promise<void>;
64
- private fireClose;
65
- /** For tests. */
66
- isRunning(): boolean;
67
- }
@@ -1,218 +0,0 @@
1
- // Stop watcher — polls open positions and auto-closes any that have crossed
2
- // their metadata stopPrice, independent of the LLM agent.
3
- //
4
- // Policy vs enforcement split:
5
- // - The LLM owns POLICY: it sets stopPrice at entry and may update it at
6
- // any time (move to breakeven, trail, widen, or remove entirely by
7
- // clearing it). The watcher just reads whatever stopPrice currently is.
8
- // - The watcher owns ENFORCEMENT: if mark crosses stopPrice, it fires a
9
- // market close immediately rather than waiting for the agent's next
10
- // 15-min heartbeat. This closes the exit-latency gap the LLM-centric
11
- // model would otherwise leave open.
12
- //
13
- // Scope:
14
- // - Works in paper mode (PaperAdapter.getPositions returns CcxtPosition with
15
- // stopPrice populated from position metadata).
16
- // - In live mode LiveAdapter does NOT track per-position metadata, so
17
- // getPositions returns positions without stopPrice and the watcher
18
- // naturally skips them. Wiring live-mode metadata is a separate change
19
- // for when live trading turns on.
20
- import { EventEmitter } from 'node:events';
21
- import { logger, formatError } from '../logger.js';
22
- const TAG = 'stop-watcher';
23
- // 2026-05-15 EFFICIENCY_QUICK_WINS Change 1: 3s → 10s. The watcher was
24
- // designed when it was the ONLY stop-enforcement mechanism; with exchange-
25
- // native brackets (live in enforce mode) it is now belt-and-suspenders, so
26
- // 10s latency to catch a watcher-triggered close is fine — Binance fires the
27
- // bracket stop in ms regardless. Saves ~70 weight/min (100→30). Operator can
28
- // revert with zero deploy via plugin-config.json `stopWatcher.intervalMs`.
29
- // See docs/EFFICIENCY_QUICK_WINS_PLAN.md + the Binance ban-gate context.
30
- export const DEFAULT_INTERVAL_MS = 10_000;
31
- /** Decide whether a position has crossed its stop.
32
- * Exported for direct unit-testing without spinning up a watcher loop. */
33
- export function isStopBreached(position) {
34
- const stop = position.stopPrice;
35
- if (stop === undefined || stop === null || !Number.isFinite(stop) || stop <= 0) {
36
- return false;
37
- }
38
- const mark = position.markPrice;
39
- if (!Number.isFinite(mark) || mark <= 0) {
40
- return false;
41
- }
42
- return position.side === 'long' ? mark <= stop : mark >= stop;
43
- }
44
- export class PositionWatcher extends EventEmitter {
45
- interval = null;
46
- intervalMs;
47
- adapter;
48
- operationLock;
49
- wave9CloseLifecycle;
50
- /** Symbols currently awaiting a close RPC — second trigger in the same tick
51
- * is suppressed so the watcher cannot double-close. Cleared after the close
52
- * call resolves (success or failure). */
53
- closePending = new Set();
54
- /** Symbols we've already logged a breach for this session, to avoid spamming
55
- * the log every tick while the close is in flight. */
56
- notifiedBreach = new Set();
57
- constructor(adapter, intervalMs = DEFAULT_INTERVAL_MS, operationLock) {
58
- super();
59
- this.adapter = adapter;
60
- this.intervalMs = intervalMs;
61
- this.operationLock = operationLock;
62
- }
63
- /** Configure this after the durable execution ledger is ready. Runtime
64
- * lifecycle hooks reapply it to every watcher after reconnect. */
65
- setWave9CloseLifecycle(lifecycle) {
66
- this.wave9CloseLifecycle = lifecycle;
67
- }
68
- start() {
69
- if (this.interval) {
70
- logger.warn(TAG, 'Already running');
71
- return;
72
- }
73
- logger.info(TAG, `Starting stop watcher (interval: ${this.intervalMs}ms)`);
74
- this.interval = setInterval(() => {
75
- void this.tick();
76
- }, this.intervalMs);
77
- }
78
- stop() {
79
- if (this.interval) {
80
- clearInterval(this.interval);
81
- this.interval = null;
82
- }
83
- this.closePending.clear();
84
- this.notifiedBreach.clear();
85
- logger.info(TAG, 'Stopped');
86
- }
87
- /** Run one check cycle. Exposed for tests (skip setInterval). */
88
- async tick() {
89
- let positions;
90
- try {
91
- positions = await this.adapter.getPositionsOrNull();
92
- }
93
- catch (err) {
94
- logger.warn(TAG, `getPositions failed: ${formatError(err)}`);
95
- return;
96
- }
97
- if (positions === null) {
98
- // Fetch failed (429 / weight-paced / transient) — position state is
99
- // UNKNOWN, not "flat". Skip this tick WITHOUT touching notifiedBreach /
100
- // closePending: a null-collapse to [] would wipe the in-flight close
101
- // guard (openSymbols below would be empty, clearing every closePending
102
- // entry) and let the NEXT tick fire a SECOND close on a position whose
103
- // close is already in flight. State repairs on the next successful tick.
104
- logger.warn(TAG, 'getPositions unavailable (null) — skipping tick, preserving in-flight close guards');
105
- return;
106
- }
107
- // Clear notification flags for any symbol no longer holding a position,
108
- // so a re-entered position later gets a fresh log line on re-breach.
109
- const openSymbols = new Set(positions.map(p => p.symbol));
110
- for (const sym of this.notifiedBreach) {
111
- if (!openSymbols.has(sym))
112
- this.notifiedBreach.delete(sym);
113
- }
114
- for (const sym of this.closePending) {
115
- if (!openSymbols.has(sym))
116
- this.closePending.delete(sym);
117
- }
118
- for (const position of positions) {
119
- if (!isStopBreached(position))
120
- continue;
121
- if (this.closePending.has(position.symbol))
122
- continue;
123
- if (!this.notifiedBreach.has(position.symbol)) {
124
- logger.warn(TAG, `STOP BREACHED: ${position.symbol} ${position.side} mark=${position.markPrice} stop=${position.stopPrice} — auto-closing`);
125
- this.notifiedBreach.add(position.symbol);
126
- }
127
- this.closePending.add(position.symbol);
128
- // Fire-and-forget per symbol so one slow close doesn't stall the tick.
129
- void this.fireClose(position);
130
- }
131
- }
132
- async fireClose(position) {
133
- const event = {
134
- symbol: position.symbol,
135
- side: position.side,
136
- stopPrice: position.stopPrice ?? 0,
137
- markPrice: position.markPrice,
138
- quantity: position.contracts,
139
- };
140
- this.emit('stop_triggered', event);
141
- // Captured close order for the 'stop_closed' event — set inside close()
142
- // (which may run under the symbol lock) and read after it resolves.
143
- let closeOrder;
144
- const close = async () => {
145
- let trustedPosition = position;
146
- // Re-read after acquiring the shared trading boundary. A Wave 9
147
- // reversal or another stop may have flattened the symbol while this
148
- // watcher was queued.
149
- if (this.operationLock) {
150
- const current = await this.adapter.getPositionsOrNull(position.symbol);
151
- if (current === null) {
152
- throw new Error('position recheck unavailable while holding trading operation lock');
153
- }
154
- const latest = current.find((candidate) => candidate.symbol === position.symbol);
155
- if (!latest || !isStopBreached(latest)) {
156
- logger.info(TAG, `${position.symbol} no longer stop-triggered after locked recheck — skipping`);
157
- return 'skipped';
158
- }
159
- trustedPosition = latest;
160
- }
161
- let candidateId;
162
- let ownershipError;
163
- if (this.wave9CloseLifecycle) {
164
- try {
165
- candidateId = await this.wave9CloseLifecycle.resolveCandidateId(trustedPosition);
166
- }
167
- catch (error) {
168
- ownershipError = formatError(error);
169
- }
170
- }
171
- if (ownershipError) {
172
- throw new Error(`Wave 9 ownership resolution failed before stop close submission: ${ownershipError}; ` +
173
- 'IMMEDIATE MANUAL INTERVENTION REQUIRED');
174
- }
175
- closeOrder = await this.adapter.closePosition(trustedPosition.symbol, 'stop_watcher');
176
- if (!candidateId || !this.wave9CloseLifecycle)
177
- return 'closed';
178
- const outcome = await this.wave9CloseLifecycle.settleAfterClose(candidateId, trustedPosition.symbol);
179
- if (outcome.status === 'flat')
180
- return 'closed';
181
- if (outcome.status === 'protected') {
182
- logger.warn(TAG, `Stop close left a Wave 9 residual on ${trustedPosition.symbol}; ` +
183
- `${outcome.detail}. The exact frozen stop is proven and the watcher will retry.`);
184
- this.emit('stop_residual_protected', { ...event, ...outcome });
185
- return 'residual_protected';
186
- }
187
- throw new Error(outcome.detail);
188
- };
189
- try {
190
- const result = this.operationLock
191
- ? await this.operationLock.withSymbolLock(position.symbol, `stop_watcher:${position.symbol}`, close)
192
- : await close();
193
- if (result !== 'closed')
194
- return;
195
- logger.info(TAG, `Auto-closed ${position.symbol} (reason=stop_watcher)`);
196
- this.emit('stop_closed', { ...event, order: closeOrder });
197
- }
198
- catch (err) {
199
- const msg = formatError(err);
200
- // "No open position" means the LLM or another path already closed it —
201
- // that's a successful no-op, not a failure.
202
- if (msg.includes('No open position')) {
203
- logger.info(TAG, `${position.symbol} already closed by another path — skipping`);
204
- }
205
- else {
206
- logger.error(TAG, `Auto-close failed for ${position.symbol}: ${msg}`);
207
- }
208
- this.emit('stop_failed', { ...event, error: msg });
209
- }
210
- finally {
211
- this.closePending.delete(position.symbol);
212
- }
213
- }
214
- /** For tests. */
215
- isRunning() {
216
- return this.interval !== null;
217
- }
218
- }
@@ -1,54 +0,0 @@
1
- import type { BinancePrivateApi } from '../ccxt/binance-private.js';
2
- import type { UserDataStream } from './user-data-stream.js';
3
- import type { LiveStateStore } from './live-state-store.js';
4
- export interface UserDataActiveProbeOptions {
5
- api: BinancePrivateApi;
6
- stream: UserDataStream;
7
- store: LiveStateStore;
8
- /** How often to run the probe. Default 60_000 (60s). Pass 0 to disable. */
9
- intervalMs?: number;
10
- /** Subtracted from `lastEventAt` when computing `since` so we don't miss
11
- * trades whose timestamp landed in the same millisecond as our last
12
- * frame. Default 1_000 (1 s). */
13
- safetyBufferMs?: number;
14
- /** For unit tests — injected timers + clock. */
15
- timers?: {
16
- setInterval?: (fn: () => void, ms: number) => ReturnType<typeof setInterval>;
17
- clearInterval?: (h: ReturnType<typeof setInterval>) => void;
18
- };
19
- /** For unit tests — injected clock used only for log timestamps. */
20
- now?: () => number;
21
- }
22
- export interface UserDataActiveProbeHealth {
23
- probesRun: number;
24
- reconnectsTriggered: number;
25
- errorCount: number;
26
- lastReconnectReason: string | null;
27
- lastReconnectAt: number | null;
28
- }
29
- export declare class UserDataActiveProbe {
30
- private readonly api;
31
- private readonly stream;
32
- private readonly store;
33
- private readonly intervalMs;
34
- private readonly safetyBufferMs;
35
- private readonly setIntervalFn;
36
- private readonly clearIntervalFn;
37
- private readonly now;
38
- private timer;
39
- private running;
40
- private inFlight;
41
- private probesRun;
42
- private reconnectsTriggered;
43
- private errorCount;
44
- private lastReconnectReason;
45
- private lastReconnectAt;
46
- constructor(opts: UserDataActiveProbeOptions);
47
- start(): void;
48
- stop(): void;
49
- getHealth(): UserDataActiveProbeHealth;
50
- /** Testing hook — runs one probe pass synchronously (well, async, but
51
- * awaitable). Production uses the interval-driven path; tests can drive
52
- * this directly without touching fake timers. */
53
- runProbe(): Promise<void>;
54
- }
@@ -1,180 +0,0 @@
1
- // UserDataActiveProbe — proactive REST probe that catches "WS silently
2
- // stopped delivering" before the staleness watchdog does.
3
- //
4
- // WHY THIS EXISTS
5
- // ---------------
6
- // On 2026-04-25 we observed the prod user-data stream go silent for 15
7
- // minutes at a stretch while a real bracket-stop fill happened on Binance.
8
- // The socket stayed "open" at the OS level (no FIN, no error), the listenKey
9
- // keep-alive succeeded, but no frames arrived. The 15-min staleness watchdog
10
- // caught it eventually, but in that window the local store still showed an
11
- // already-closed position as live. Either alone — adaptive watchdog OR active
12
- // probe — narrows the window; together they close it.
13
- //
14
- // WHAT IT DOES
15
- // ------------
16
- // Every `intervalMs` (default 60s):
17
- // 1. If the stream isn't connected, skip — reconnect logic owns recovery.
18
- // 2. Read symbols from `store.getPositions()` — only positions where a
19
- // missed fill matters (a closed position is a non-event).
20
- // 3. For each symbol, call `api.fetchMyTrades(symbol, since=lastEventAt - 1s)`.
21
- // 4. If any returned trade has `timestamp > lastEventAt`, the WS missed
22
- // a fill: log the trade id + symbol and call `stream.requestReconnect`.
23
- // 5. Stop after the first detection — reconnect will trigger snapshot +
24
- // gap-fill, and another probe pass on the next tick covers anything new.
25
- //
26
- // WHAT IT DOES NOT DO
27
- // -------------------
28
- // - Does NOT ingest the trade itself. Reconnect → resyncRequired → gap-filler
29
- // handles ingest with `source='rest_reconcile'`. Single-responsibility.
30
- // - Does NOT touch LiveStateStore. Reconnect snapshot reseeds it.
31
- // - Does NOT run on flat accounts. With no open positions there's nothing to
32
- // protect — the watchdog's looser idle threshold is appropriate.
33
- //
34
- // COST
35
- // ----
36
- // `fetchMyTrades` is weight 5 per symbol per call on Binance Futures. With
37
- // ~5 open positions on a typical account, that's 25 weight/min — well below
38
- // the 2400/min budget.
39
- import { logger, formatError } from '../logger.js';
40
- const TAG = 'user-data-active-probe';
41
- /** CCXT unified symbol → API form. The reconciler stores `BTC/USDT` (no suffix);
42
- * CCXT's fetchMyTrades takes either form, but we re-attach the settle suffix
43
- * to be explicit. */
44
- function toApiSymbol(s) {
45
- if (!s)
46
- return s;
47
- if (s.includes(':'))
48
- return s;
49
- const parts = s.split('/');
50
- return parts.length === 2 ? `${s}:${parts[1]}` : s;
51
- }
52
- export class UserDataActiveProbe {
53
- api;
54
- stream;
55
- store;
56
- intervalMs;
57
- safetyBufferMs;
58
- setIntervalFn;
59
- clearIntervalFn;
60
- now;
61
- timer = null;
62
- running = false;
63
- inFlight = false;
64
- probesRun = 0;
65
- reconnectsTriggered = 0;
66
- errorCount = 0;
67
- lastReconnectReason = null;
68
- lastReconnectAt = null;
69
- constructor(opts) {
70
- this.api = opts.api;
71
- this.stream = opts.stream;
72
- this.store = opts.store;
73
- this.intervalMs = opts.intervalMs ?? 60_000;
74
- this.safetyBufferMs = opts.safetyBufferMs ?? 1_000;
75
- this.setIntervalFn = opts.timers?.setInterval ?? ((fn, ms) => setInterval(fn, ms));
76
- this.clearIntervalFn = opts.timers?.clearInterval ?? ((h) => clearInterval(h));
77
- this.now = opts.now ?? (() => Date.now());
78
- }
79
- start() {
80
- if (this.running)
81
- return;
82
- if (this.intervalMs <= 0) {
83
- logger.info(TAG, 'disabled (intervalMs=0)');
84
- return;
85
- }
86
- this.running = true;
87
- this.timer = this.setIntervalFn(() => {
88
- void this.runProbe().catch((err) => {
89
- this.errorCount++;
90
- logger.warn(TAG, `probe pass threw: ${formatError(err)} — continuing`);
91
- });
92
- }, this.intervalMs);
93
- logger.info(TAG, `started (intervalMs=${this.intervalMs}, safetyBufferMs=${this.safetyBufferMs})`);
94
- }
95
- stop() {
96
- if (!this.running)
97
- return;
98
- if (this.timer) {
99
- this.clearIntervalFn(this.timer);
100
- this.timer = null;
101
- }
102
- this.running = false;
103
- logger.info(TAG, 'stopped');
104
- }
105
- getHealth() {
106
- return {
107
- probesRun: this.probesRun,
108
- reconnectsTriggered: this.reconnectsTriggered,
109
- errorCount: this.errorCount,
110
- lastReconnectReason: this.lastReconnectReason,
111
- lastReconnectAt: this.lastReconnectAt,
112
- };
113
- }
114
- /** Testing hook — runs one probe pass synchronously (well, async, but
115
- * awaitable). Production uses the interval-driven path; tests can drive
116
- * this directly without touching fake timers. */
117
- async runProbe() {
118
- if (!this.running && this.timer === null) {
119
- // Allow direct invocation in tests even when start() wasn't called.
120
- }
121
- if (this.inFlight)
122
- return;
123
- this.inFlight = true;
124
- this.probesRun++;
125
- try {
126
- if (!this.stream.isConnected())
127
- return;
128
- const health = this.stream.getHealth();
129
- const lastEventAt = health.lastEventAt;
130
- if (lastEventAt == null)
131
- return; // Never received an event; nothing to compare against.
132
- const positions = this.store.getPositions().filter((p) => p && p.contracts > 0);
133
- if (positions.length === 0)
134
- return;
135
- const symbols = Array.from(new Set(positions.map((p) => p.symbol).filter(Boolean)));
136
- const since = lastEventAt - this.safetyBufferMs;
137
- for (const symbol of symbols) {
138
- let trades;
139
- try {
140
- trades = await this.api.fetchMyTrades(toApiSymbol(symbol), since, 50);
141
- }
142
- catch (err) {
143
- this.errorCount++;
144
- logger.warn(TAG, `fetchMyTrades(${symbol}) threw: ${formatError(err)}`);
145
- continue;
146
- }
147
- if (!Array.isArray(trades) || trades.length === 0)
148
- continue;
149
- let newest = null;
150
- for (const t of trades) {
151
- if (!t || typeof t !== 'object')
152
- continue;
153
- const rec = t;
154
- const ts = typeof rec.timestamp === 'number' ? rec.timestamp : 0;
155
- if (ts <= lastEventAt)
156
- continue;
157
- const id = typeof rec.id === 'string' ? rec.id : String(rec.id ?? '?');
158
- if (!newest || ts > newest.timestamp) {
159
- newest = { id, timestamp: ts };
160
- }
161
- }
162
- if (newest) {
163
- const lagMs = this.now() - newest.timestamp;
164
- const reason = `active_probe_silent_stream`;
165
- logger.error(TAG, `silent-stream detected: ${symbol} trade id=${newest.id} t=${new Date(newest.timestamp).toISOString()} ` +
166
- `> lastEventAt=${new Date(lastEventAt).toISOString()} (lagMs=${lagMs}) — forcing reconnect`);
167
- this.reconnectsTriggered++;
168
- this.lastReconnectReason = `${reason}:${symbol}`;
169
- this.lastReconnectAt = this.now();
170
- this.stream.requestReconnect(reason);
171
- // One reconnect per pass — don't fire repeatedly across symbols.
172
- return;
173
- }
174
- }
175
- }
176
- finally {
177
- this.inFlight = false;
178
- }
179
- }
180
- }