@reefclaw/connect 0.1.10 → 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 (396) hide show
  1. package/assets/bridge/gateway/event-parser.d.ts +6 -1
  2. package/assets/bridge/gateway/event-parser.js +19 -2
  3. package/assets/bridge/gateway/heartbeat-cron.d.ts +27 -0
  4. package/assets/bridge/gateway/heartbeat-cron.js +85 -0
  5. package/assets/bridge/gateway/poller.d.ts +1 -0
  6. package/assets/bridge/gateway/poller.js +14 -2
  7. package/assets/bridge/providers/gateway.d.ts +24 -2
  8. package/assets/bridge/providers/gateway.js +124 -25
  9. package/assets/bridge/setup.js +6 -51
  10. package/assets/shared/signals/conditions/registry.js +11 -2
  11. package/assets/shared/signals/strategy-adapter.js +17 -7
  12. package/assets/skill/SKILL.md +2 -0
  13. package/dist/deps.js +2 -2
  14. package/dist/plugin.js +35 -7
  15. package/package.json +1 -1
  16. package/assets/plugin/audit/mode-transition-audit.d.ts +0 -11
  17. package/assets/plugin/audit/mode-transition-audit.js +0 -29
  18. package/assets/plugin/balance-utils.d.ts +0 -36
  19. package/assets/plugin/balance-utils.js +0 -98
  20. package/assets/plugin/ccxt/binance-ban-gate.d.ts +0 -47
  21. package/assets/plugin/ccxt/binance-ban-gate.js +0 -420
  22. package/assets/plugin/ccxt/binance-private.d.ts +0 -346
  23. package/assets/plugin/ccxt/binance-private.js +0 -1525
  24. package/assets/plugin/ccxt/binance-public.d.ts +0 -34
  25. package/assets/plugin/ccxt/binance-public.js +0 -180
  26. package/assets/plugin/ccxt/intel-public.d.ts +0 -25
  27. package/assets/plugin/ccxt/intel-public.js +0 -80
  28. package/assets/plugin/ccxt/public-market-data-api.d.ts +0 -12
  29. package/assets/plugin/ccxt/public-market-data-api.js +0 -9
  30. package/assets/plugin/config/agent-config-client.d.ts +0 -77
  31. package/assets/plugin/config/agent-config-client.js +0 -188
  32. package/assets/plugin/config/agent-config-poller.d.ts +0 -32
  33. package/assets/plugin/config/agent-config-poller.js +0 -101
  34. package/assets/plugin/config/brackets-config.d.ts +0 -22
  35. package/assets/plugin/config/brackets-config.js +0 -58
  36. package/assets/plugin/config/entitlement-gate.d.ts +0 -51
  37. package/assets/plugin/config/entitlement-gate.js +0 -137
  38. package/assets/plugin/config/gate-store.d.ts +0 -18
  39. package/assets/plugin/config/gate-store.js +0 -61
  40. package/assets/plugin/config/plugin-config-io.d.ts +0 -215
  41. package/assets/plugin/config/plugin-config-io.js +0 -111
  42. package/assets/plugin/config/position-review-config.d.ts +0 -35
  43. package/assets/plugin/config/position-review-config.js +0 -105
  44. package/assets/plugin/config/tool-gate.d.ts +0 -53
  45. package/assets/plugin/config/tool-gate.js +0 -128
  46. package/assets/plugin/config/user-data-stream-config.d.ts +0 -89
  47. package/assets/plugin/config/user-data-stream-config.js +0 -239
  48. package/assets/plugin/connector-supervisor.d.ts +0 -36
  49. package/assets/plugin/connector-supervisor.js +0 -149
  50. package/assets/plugin/exchange-adapter.d.ts +0 -65
  51. package/assets/plugin/exchange-adapter.js +0 -4
  52. package/assets/plugin/index.d.ts +0 -30
  53. package/assets/plugin/index.js +0 -2678
  54. package/assets/plugin/ingest/pending-entry-metadata.d.ts +0 -74
  55. package/assets/plugin/ingest/pending-entry-metadata.js +0 -236
  56. package/assets/plugin/ingest/position-auto-capture.d.ts +0 -103
  57. package/assets/plugin/ingest/position-auto-capture.js +0 -411
  58. package/assets/plugin/ingest/position-decisions-client.d.ts +0 -322
  59. package/assets/plugin/ingest/position-decisions-client.js +0 -296
  60. package/assets/plugin/ingest/readiness-reporter.d.ts +0 -42
  61. package/assets/plugin/ingest/readiness-reporter.js +0 -163
  62. package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +0 -13
  63. package/assets/plugin/ingest/reconcile-db-vs-exchange.js +0 -114
  64. package/assets/plugin/ingest/reconciler-cleanup.d.ts +0 -37
  65. package/assets/plugin/ingest/reconciler-cleanup.js +0 -147
  66. package/assets/plugin/ingest/rest-gap-filler.d.ts +0 -191
  67. package/assets/plugin/ingest/rest-gap-filler.js +0 -565
  68. package/assets/plugin/ingest/touched-symbols-store.d.ts +0 -25
  69. package/assets/plugin/ingest/touched-symbols-store.js +0 -96
  70. package/assets/plugin/ingest/trade-store-client.d.ts +0 -40
  71. package/assets/plugin/ingest/trade-store-client.js +0 -125
  72. package/assets/plugin/ingest/ws-ingest.d.ts +0 -43
  73. package/assets/plugin/ingest/ws-ingest.js +0 -126
  74. package/assets/plugin/learning/setup-family.d.ts +0 -21
  75. package/assets/plugin/learning/setup-family.js +0 -103
  76. package/assets/plugin/lifecycle/install-signal-handlers.d.ts +0 -33
  77. package/assets/plugin/lifecycle/install-signal-handlers.js +0 -112
  78. package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +0 -43
  79. package/assets/plugin/lifecycle/shutdown-coordinator.js +0 -131
  80. package/assets/plugin/lifecycle/trading-operation-lock.d.ts +0 -17
  81. package/assets/plugin/lifecycle/trading-operation-lock.js +0 -14
  82. package/assets/plugin/live/bracket-id.d.ts +0 -26
  83. package/assets/plugin/live/bracket-id.js +0 -112
  84. package/assets/plugin/live/bracket-ledger.d.ts +0 -54
  85. package/assets/plugin/live/bracket-ledger.js +0 -267
  86. package/assets/plugin/live/bracket-manager.d.ts +0 -82
  87. package/assets/plugin/live/bracket-manager.js +0 -478
  88. package/assets/plugin/live/bracket-params.d.ts +0 -22
  89. package/assets/plugin/live/bracket-params.js +0 -124
  90. package/assets/plugin/live/bracket-reconciler.d.ts +0 -95
  91. package/assets/plugin/live/bracket-reconciler.js +0 -573
  92. package/assets/plugin/live/bracket-types.d.ts +0 -102
  93. package/assets/plugin/live/bracket-types.js +0 -8
  94. package/assets/plugin/live/deposit-tracker.d.ts +0 -62
  95. package/assets/plugin/live/deposit-tracker.js +0 -97
  96. package/assets/plugin/live/emergency-controls.d.ts +0 -32
  97. package/assets/plugin/live/emergency-controls.js +0 -226
  98. package/assets/plugin/live/exchange-errors.d.ts +0 -12
  99. package/assets/plugin/live/exchange-errors.js +0 -130
  100. package/assets/plugin/live/exchange-info-cache.d.ts +0 -37
  101. package/assets/plugin/live/exchange-info-cache.js +0 -134
  102. package/assets/plugin/live/fact-subscriber.d.ts +0 -78
  103. package/assets/plugin/live/fact-subscriber.js +0 -182
  104. package/assets/plugin/live/intent-journal.d.ts +0 -42
  105. package/assets/plugin/live/intent-journal.js +0 -122
  106. package/assets/plugin/live/listen-key-manager.d.ts +0 -70
  107. package/assets/plugin/live/listen-key-manager.js +0 -169
  108. package/assets/plugin/live/live-adapter.d.ts +0 -287
  109. package/assets/plugin/live/live-adapter.js +0 -1777
  110. package/assets/plugin/live/live-balance-enricher.d.ts +0 -32
  111. package/assets/plugin/live/live-balance-enricher.js +0 -104
  112. package/assets/plugin/live/live-bracket-api.d.ts +0 -13
  113. package/assets/plugin/live/live-bracket-api.js +0 -20
  114. package/assets/plugin/live/live-state-store.d.ts +0 -194
  115. package/assets/plugin/live/live-state-store.js +0 -450
  116. package/assets/plugin/live/local-signal-service.d.ts +0 -57
  117. package/assets/plugin/live/local-signal-service.js +0 -151
  118. package/assets/plugin/live/local-strategy-evaluator.d.ts +0 -62
  119. package/assets/plugin/live/local-strategy-evaluator.js +0 -131
  120. package/assets/plugin/live/microstructure-assembler.d.ts +0 -54
  121. package/assets/plugin/live/microstructure-assembler.js +0 -148
  122. package/assets/plugin/live/order-poller.d.ts +0 -29
  123. package/assets/plugin/live/order-poller.js +0 -125
  124. package/assets/plugin/live/position-state-store.d.ts +0 -83
  125. package/assets/plugin/live/position-state-store.js +0 -237
  126. package/assets/plugin/live/proposal-decision-listener.d.ts +0 -70
  127. package/assets/plugin/live/proposal-decision-listener.js +0 -292
  128. package/assets/plugin/live/proposal-manager.d.ts +0 -76
  129. package/assets/plugin/live/proposal-manager.js +0 -140
  130. package/assets/plugin/live/rate-limiter.d.ts +0 -47
  131. package/assets/plugin/live/rate-limiter.js +0 -159
  132. package/assets/plugin/live/reconciler.d.ts +0 -39
  133. package/assets/plugin/live/reconciler.js +0 -175
  134. package/assets/plugin/live/setup-buckets.d.ts +0 -7
  135. package/assets/plugin/live/setup-buckets.js +0 -33
  136. package/assets/plugin/live/slippage-tracker.d.ts +0 -45
  137. package/assets/plugin/live/slippage-tracker.js +0 -78
  138. package/assets/plugin/live/stop-watcher.d.ts +0 -60
  139. package/assets/plugin/live/stop-watcher.js +0 -215
  140. package/assets/plugin/live/user-data-active-probe.d.ts +0 -54
  141. package/assets/plugin/live/user-data-active-probe.js +0 -180
  142. package/assets/plugin/live/user-data-stream-controller.d.ts +0 -200
  143. package/assets/plugin/live/user-data-stream-controller.js +0 -579
  144. package/assets/plugin/live/user-data-stream-ws.d.ts +0 -22
  145. package/assets/plugin/live/user-data-stream-ws.js +0 -63
  146. package/assets/plugin/live/user-data-stream.d.ts +0 -243
  147. package/assets/plugin/live/user-data-stream.js +0 -704
  148. package/assets/plugin/logger.d.ts +0 -2
  149. package/assets/plugin/logger.js +0 -2
  150. package/assets/plugin/mfe.d.ts +0 -21
  151. package/assets/plugin/mfe.js +0 -68
  152. package/assets/plugin/onboarding/mode-ladder.d.ts +0 -1
  153. package/assets/plugin/onboarding/mode-ladder.js +0 -3
  154. package/assets/plugin/onboarding/runtime.d.ts +0 -84
  155. package/assets/plugin/onboarding/runtime.js +0 -173
  156. package/assets/plugin/openclaw.plugin.json +0 -92
  157. package/assets/plugin/paper-adapter.d.ts +0 -24
  158. package/assets/plugin/paper-adapter.js +0 -91
  159. package/assets/plugin/persistence/state-manager.d.ts +0 -66
  160. package/assets/plugin/persistence/state-manager.js +0 -222
  161. package/assets/plugin/pinned-plan.d.ts +0 -9
  162. package/assets/plugin/pinned-plan.js +0 -23
  163. package/assets/plugin/portfolio/wave9-admission.d.ts +0 -67
  164. package/assets/plugin/portfolio/wave9-admission.js +0 -262
  165. package/assets/plugin/portfolio/wave9-policy.d.ts +0 -36
  166. package/assets/plugin/portfolio/wave9-policy.js +0 -183
  167. package/assets/plugin/risk/pre-trade-check.d.ts +0 -38
  168. package/assets/plugin/risk/pre-trade-check.js +0 -345
  169. package/assets/plugin/risk/pre-trade-types.d.ts +0 -60
  170. package/assets/plugin/risk/pre-trade-types.js +0 -3
  171. package/assets/plugin/shadow/shadow-tracker.d.ts +0 -36
  172. package/assets/plugin/shadow/shadow-tracker.js +0 -151
  173. package/assets/plugin/shadow/types.d.ts +0 -42
  174. package/assets/plugin/shadow/types.js +0 -20
  175. package/assets/plugin/shared/indicators-extended.d.ts +0 -52
  176. package/assets/plugin/shared/indicators-extended.js +0 -291
  177. package/assets/plugin/shared/indicators.d.ts +0 -15
  178. package/assets/plugin/shared/indicators.js +0 -114
  179. package/assets/plugin/signals/conditions/registry.d.ts +0 -16
  180. package/assets/plugin/signals/conditions/registry.js +0 -1324
  181. package/assets/plugin/signals/conditions/types.d.ts +0 -1
  182. package/assets/plugin/signals/conditions/types.js +0 -4
  183. package/assets/plugin/signals/direction-rules.d.ts +0 -3
  184. package/assets/plugin/signals/direction-rules.js +0 -24
  185. package/assets/plugin/signals/entry-rules.d.ts +0 -6
  186. package/assets/plugin/signals/entry-rules.js +0 -33
  187. package/assets/plugin/signals/serialize-context.d.ts +0 -4
  188. package/assets/plugin/signals/serialize-context.js +0 -39
  189. package/assets/plugin/signals/stop-rules.d.ts +0 -3
  190. package/assets/plugin/signals/stop-rules.js +0 -48
  191. package/assets/plugin/signals/strategy-adapter.d.ts +0 -47
  192. package/assets/plugin/signals/strategy-adapter.js +0 -199
  193. package/assets/plugin/signals/types.d.ts +0 -1
  194. package/assets/plugin/signals/types.js +0 -8
  195. package/assets/plugin/simulator/exchange-simulator.d.ts +0 -93
  196. package/assets/plugin/simulator/exchange-simulator.js +0 -689
  197. package/assets/plugin/simulator/fill-engine.d.ts +0 -53
  198. package/assets/plugin/simulator/fill-engine.js +0 -280
  199. package/assets/plugin/simulator/paper-market-feed.d.ts +0 -26
  200. package/assets/plugin/simulator/paper-market-feed.js +0 -104
  201. package/assets/plugin/simulator/realistic-fills.d.ts +0 -59
  202. package/assets/plugin/simulator/realistic-fills.js +0 -175
  203. package/assets/plugin/simulator/types.d.ts +0 -224
  204. package/assets/plugin/simulator/types.js +0 -43
  205. package/assets/plugin/strategy/builtin-strategies.d.ts +0 -2
  206. package/assets/plugin/strategy/builtin-strategies.js +0 -113
  207. package/assets/plugin/strategy/condition-registry.d.ts +0 -3
  208. package/assets/plugin/strategy/condition-registry.js +0 -153
  209. package/assets/plugin/strategy/evaluator.d.ts +0 -70
  210. package/assets/plugin/strategy/evaluator.js +0 -98
  211. package/assets/plugin/tools/assessment-validation.d.ts +0 -120
  212. package/assets/plugin/tools/assessment-validation.js +0 -415
  213. package/assets/plugin/tools/attach-brackets.d.ts +0 -39
  214. package/assets/plugin/tools/attach-brackets.js +0 -399
  215. package/assets/plugin/tools/audit-bracket-protection.d.ts +0 -49
  216. package/assets/plugin/tools/audit-bracket-protection.js +0 -527
  217. package/assets/plugin/tools/cancel-all-orders.d.ts +0 -9
  218. package/assets/plugin/tools/cancel-all-orders.js +0 -8
  219. package/assets/plugin/tools/cancel-order.d.ts +0 -14
  220. package/assets/plugin/tools/cancel-order.js +0 -60
  221. package/assets/plugin/tools/check-position-health.d.ts +0 -46
  222. package/assets/plugin/tools/check-position-health.js +0 -194
  223. package/assets/plugin/tools/clear-exchange-credentials.d.ts +0 -24
  224. package/assets/plugin/tools/clear-exchange-credentials.js +0 -70
  225. package/assets/plugin/tools/close-position.d.ts +0 -45
  226. package/assets/plugin/tools/close-position.js +0 -722
  227. package/assets/plugin/tools/create-order.d.ts +0 -82
  228. package/assets/plugin/tools/create-order.js +0 -1516
  229. package/assets/plugin/tools/exit-gate.d.ts +0 -58
  230. package/assets/plugin/tools/exit-gate.js +0 -162
  231. package/assets/plugin/tools/fetch-balance.d.ts +0 -5
  232. package/assets/plugin/tools/fetch-balance.js +0 -4
  233. package/assets/plugin/tools/fetch-ohlcv.d.ts +0 -11
  234. package/assets/plugin/tools/fetch-ohlcv.js +0 -8
  235. package/assets/plugin/tools/fetch-open-orders.d.ts +0 -7
  236. package/assets/plugin/tools/fetch-open-orders.js +0 -4
  237. package/assets/plugin/tools/fetch-positions.d.ts +0 -7
  238. package/assets/plugin/tools/fetch-positions.js +0 -4
  239. package/assets/plugin/tools/fetch-ticker.d.ts +0 -11
  240. package/assets/plugin/tools/fetch-ticker.js +0 -5
  241. package/assets/plugin/tools/get-agent-profile.d.ts +0 -4
  242. package/assets/plugin/tools/get-agent-profile.js +0 -6
  243. package/assets/plugin/tools/get-analytics.d.ts +0 -6
  244. package/assets/plugin/tools/get-analytics.js +0 -7
  245. package/assets/plugin/tools/get-backtest.d.ts +0 -12
  246. package/assets/plugin/tools/get-backtest.js +0 -91
  247. package/assets/plugin/tools/get-basis.d.ts +0 -7
  248. package/assets/plugin/tools/get-basis.js +0 -7
  249. package/assets/plugin/tools/get-bracket-config.d.ts +0 -11
  250. package/assets/plugin/tools/get-bracket-config.js +0 -24
  251. package/assets/plugin/tools/get-cascade-risk.d.ts +0 -7
  252. package/assets/plugin/tools/get-cascade-risk.js +0 -8
  253. package/assets/plugin/tools/get-crypto-metrics.d.ts +0 -18
  254. package/assets/plugin/tools/get-crypto-metrics.js +0 -62
  255. package/assets/plugin/tools/get-cvd.d.ts +0 -6
  256. package/assets/plugin/tools/get-cvd.js +0 -6
  257. package/assets/plugin/tools/get-divergences.d.ts +0 -6
  258. package/assets/plugin/tools/get-divergences.js +0 -6
  259. package/assets/plugin/tools/get-funding-context.d.ts +0 -6
  260. package/assets/plugin/tools/get-funding-context.js +0 -16
  261. package/assets/plugin/tools/get-liquidation-levels.d.ts +0 -7
  262. package/assets/plugin/tools/get-liquidation-levels.js +0 -7
  263. package/assets/plugin/tools/get-liquidation-pulse.d.ts +0 -9
  264. package/assets/plugin/tools/get-liquidation-pulse.js +0 -22
  265. package/assets/plugin/tools/get-market-breadth.d.ts +0 -6
  266. package/assets/plugin/tools/get-market-breadth.js +0 -8
  267. package/assets/plugin/tools/get-market-intel.d.ts +0 -19
  268. package/assets/plugin/tools/get-market-intel.js +0 -116
  269. package/assets/plugin/tools/get-market-structure.d.ts +0 -47
  270. package/assets/plugin/tools/get-market-structure.js +0 -198
  271. package/assets/plugin/tools/get-my-mined-patterns.d.ts +0 -20
  272. package/assets/plugin/tools/get-my-mined-patterns.js +0 -61
  273. package/assets/plugin/tools/get-my-proposed-learnings.d.ts +0 -20
  274. package/assets/plugin/tools/get-my-proposed-learnings.js +0 -55
  275. package/assets/plugin/tools/get-my-recent-reviews.d.ts +0 -22
  276. package/assets/plugin/tools/get-my-recent-reviews.js +0 -66
  277. package/assets/plugin/tools/get-orderbook.d.ts +0 -21
  278. package/assets/plugin/tools/get-orderbook.js +0 -32
  279. package/assets/plugin/tools/get-pattern-scan.d.ts +0 -7
  280. package/assets/plugin/tools/get-pattern-scan.js +0 -8
  281. package/assets/plugin/tools/get-regime.d.ts +0 -6
  282. package/assets/plugin/tools/get-regime.js +0 -7
  283. package/assets/plugin/tools/get-relevant-learnings.d.ts +0 -21
  284. package/assets/plugin/tools/get-relevant-learnings.js +0 -65
  285. package/assets/plugin/tools/get-resting-liquidity.d.ts +0 -6
  286. package/assets/plugin/tools/get-resting-liquidity.js +0 -11
  287. package/assets/plugin/tools/get-risk-scenario.d.ts +0 -29
  288. package/assets/plugin/tools/get-risk-scenario.js +0 -47
  289. package/assets/plugin/tools/get-risk-summary.d.ts +0 -51
  290. package/assets/plugin/tools/get-risk-summary.js +0 -118
  291. package/assets/plugin/tools/get-sentiment.d.ts +0 -4
  292. package/assets/plugin/tools/get-sentiment.js +0 -6
  293. package/assets/plugin/tools/get-session-review.d.ts +0 -7
  294. package/assets/plugin/tools/get-session-review.js +0 -8
  295. package/assets/plugin/tools/get-setup-detail.d.ts +0 -7
  296. package/assets/plugin/tools/get-setup-detail.js +0 -311
  297. package/assets/plugin/tools/get-signals.d.ts +0 -15
  298. package/assets/plugin/tools/get-signals.js +0 -54
  299. package/assets/plugin/tools/get-sizing.d.ts +0 -6
  300. package/assets/plugin/tools/get-sizing.js +0 -6
  301. package/assets/plugin/tools/get-trade-feedback.d.ts +0 -7
  302. package/assets/plugin/tools/get-trade-feedback.js +0 -8
  303. package/assets/plugin/tools/get-trade-flow.d.ts +0 -7
  304. package/assets/plugin/tools/get-trade-flow.js +0 -7
  305. package/assets/plugin/tools/get-volume-analysis.d.ts +0 -21
  306. package/assets/plugin/tools/get-volume-analysis.js +0 -74
  307. package/assets/plugin/tools/get-volume-profile.d.ts +0 -7
  308. package/assets/plugin/tools/get-volume-profile.js +0 -7
  309. package/assets/plugin/tools/get-wave9-status.d.ts +0 -127
  310. package/assets/plugin/tools/get-wave9-status.js +0 -796
  311. package/assets/plugin/tools/helpers.d.ts +0 -26
  312. package/assets/plugin/tools/helpers.js +0 -39
  313. package/assets/plugin/tools/intel-api.d.ts +0 -34
  314. package/assets/plugin/tools/intel-api.js +0 -119
  315. package/assets/plugin/tools/intel-cache.d.ts +0 -25
  316. package/assets/plugin/tools/intel-cache.js +0 -148
  317. package/assets/plugin/tools/list-strategies.d.ts +0 -17
  318. package/assets/plugin/tools/list-strategies.js +0 -23
  319. package/assets/plugin/tools/modify-stop.d.ts +0 -21
  320. package/assets/plugin/tools/modify-stop.js +0 -120
  321. package/assets/plugin/tools/modify-target.d.ts +0 -21
  322. package/assets/plugin/tools/modify-target.js +0 -110
  323. package/assets/plugin/tools/propose-learning.d.ts +0 -22
  324. package/assets/plugin/tools/propose-learning.js +0 -65
  325. package/assets/plugin/tools/query-review-outcomes.d.ts +0 -30
  326. package/assets/plugin/tools/query-review-outcomes.js +0 -64
  327. package/assets/plugin/tools/query-trades.d.ts +0 -21
  328. package/assets/plugin/tools/query-trades.js +0 -37
  329. package/assets/plugin/tools/record-position-reviews.d.ts +0 -38
  330. package/assets/plugin/tools/record-position-reviews.js +0 -147
  331. package/assets/plugin/tools/save-strategy.d.ts +0 -16
  332. package/assets/plugin/tools/save-strategy.js +0 -46
  333. package/assets/plugin/tools/scan-pairs.d.ts +0 -18
  334. package/assets/plugin/tools/scan-pairs.js +0 -231
  335. package/assets/plugin/tools/score-setup.d.ts +0 -31
  336. package/assets/plugin/tools/score-setup.js +0 -268
  337. package/assets/plugin/tools/set-bracket-requirement.d.ts +0 -18
  338. package/assets/plugin/tools/set-bracket-requirement.js +0 -81
  339. package/assets/plugin/tools/set-exchange-credentials.d.ts +0 -25
  340. package/assets/plugin/tools/set-exchange-credentials.js +0 -80
  341. package/assets/plugin/tools/set-trading-mode.d.ts +0 -26
  342. package/assets/plugin/tools/set-trading-mode.js +0 -135
  343. package/assets/plugin/tools/test-exchange-credentials.d.ts +0 -16
  344. package/assets/plugin/tools/test-exchange-credentials.js +0 -100
  345. package/assets/plugin/tools/toggle-strategy.d.ts +0 -8
  346. package/assets/plugin/tools/toggle-strategy.js +0 -15
  347. package/assets/plugin/trading-params-cache.d.ts +0 -26
  348. package/assets/plugin/trading-params-cache.js +0 -52
  349. package/assets/plugin/types.d.ts +0 -134
  350. package/assets/plugin/types.js +0 -7
  351. package/assets/plugin/util/plugin-paths.d.ts +0 -3
  352. package/assets/plugin/util/plugin-paths.js +0 -15
  353. package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +0 -116
  354. package/assets/plugin/venues/hyperliquid/hl-balance.js +0 -145
  355. package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +0 -102
  356. package/assets/plugin/venues/hyperliquid/hl-brackets.js +0 -172
  357. package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +0 -22
  358. package/assets/plugin/venues/hyperliquid/hl-cloid.js +0 -82
  359. package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +0 -46
  360. package/assets/plugin/venues/hyperliquid/hl-info-cache.js +0 -125
  361. package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +0 -88
  362. package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +0 -353
  363. package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +0 -61
  364. package/assets/plugin/venues/hyperliquid/hl-precision.js +0 -176
  365. package/assets/plugin/venues/hyperliquid/hl-private.d.ts +0 -88
  366. package/assets/plugin/venues/hyperliquid/hl-private.js +0 -357
  367. package/assets/plugin/venues/hyperliquid/hl-public.d.ts +0 -79
  368. package/assets/plugin/venues/hyperliquid/hl-public.js +0 -429
  369. package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +0 -57
  370. package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +0 -220
  371. package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +0 -90
  372. package/assets/plugin/venues/hyperliquid/hl-user-stream.js +0 -220
  373. package/assets/plugin/venues/registry.d.ts +0 -38
  374. package/assets/plugin/venues/registry.js +0 -46
  375. package/assets/plugin/venues/symbols.d.ts +0 -43
  376. package/assets/plugin/venues/symbols.js +0 -107
  377. package/assets/plugin/wave9/live-account-capture.d.ts +0 -67
  378. package/assets/plugin/wave9/live-account-capture.js +0 -435
  379. package/assets/plugin/wave9/live-autonomous-protection.d.ts +0 -39
  380. package/assets/plugin/wave9/live-autonomous-protection.js +0 -112
  381. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +0 -33
  382. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +0 -115
  383. package/assets/plugin/wave9/live-execution-ledger.d.ts +0 -107
  384. package/assets/plugin/wave9/live-execution-ledger.js +0 -498
  385. package/assets/plugin/wave9/live-position-confirmation.d.ts +0 -18
  386. package/assets/plugin/wave9/live-position-confirmation.js +0 -111
  387. package/assets/plugin/wave9/live-residual-protection.d.ts +0 -18
  388. package/assets/plugin/wave9/live-residual-protection.js +0 -250
  389. package/assets/plugin/wave9/live-startup-reconciliation.d.ts +0 -38
  390. package/assets/plugin/wave9/live-startup-reconciliation.js +0 -454
  391. package/assets/plugin/wave9/live-symbol-ownership.d.ts +0 -20
  392. package/assets/plugin/wave9/live-symbol-ownership.js +0 -132
  393. package/assets/plugin/wave9/paper-admission-guard.d.ts +0 -199
  394. package/assets/plugin/wave9/paper-admission-guard.js +0 -650
  395. package/assets/plugin/wave9/usdm-evidence-provider.d.ts +0 -42
  396. 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,60 +0,0 @@
1
- import { EventEmitter } from 'node:events';
2
- import type { IExchangeAdapter } from '../exchange-adapter.js';
3
- import type { 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
- export type Wave9StopCloseOutcome = {
14
- status: 'flat';
15
- detail: string;
16
- candidateId: string;
17
- symbol: string;
18
- } | {
19
- status: 'protected' | 'manual_intervention';
20
- detail: string;
21
- candidateId: string;
22
- symbol: string;
23
- stopPrice: number;
24
- residualQuantity?: number;
25
- stopClientOrderId?: string;
26
- };
27
- /** Optional durable Wave 9 lifecycle. Generic watcher behavior is unchanged
28
- * when this is absent or the current position has no owned candidate. */
29
- export interface Wave9StopCloseLifecycle {
30
- resolveCandidateId(position: CcxtPosition): Promise<string | undefined> | string | undefined;
31
- settleAfterClose(candidateId: string, symbol: string): Promise<Wave9StopCloseOutcome>;
32
- }
33
- /** Decide whether a position has crossed its stop.
34
- * Exported for direct unit-testing without spinning up a watcher loop. */
35
- export declare function isStopBreached(position: CcxtPosition): boolean;
36
- export declare class PositionWatcher extends EventEmitter {
37
- private interval;
38
- private intervalMs;
39
- private adapter;
40
- private readonly operationLock?;
41
- private wave9CloseLifecycle?;
42
- /** Symbols currently awaiting a close RPC — second trigger in the same tick
43
- * is suppressed so the watcher cannot double-close. Cleared after the close
44
- * call resolves (success or failure). */
45
- private closePending;
46
- /** Symbols we've already logged a breach for this session, to avoid spamming
47
- * the log every tick while the close is in flight. */
48
- private notifiedBreach;
49
- constructor(adapter: IExchangeAdapter, intervalMs?: number, operationLock?: TradingOperationLock);
50
- /** Configure this after the durable execution ledger is ready. Runtime
51
- * lifecycle hooks reapply it to every watcher after reconnect. */
52
- setWave9CloseLifecycle(lifecycle?: Wave9StopCloseLifecycle): void;
53
- start(): void;
54
- stop(): void;
55
- /** Run one check cycle. Exposed for tests (skip setInterval). */
56
- tick(): Promise<void>;
57
- private fireClose;
58
- /** For tests. */
59
- isRunning(): boolean;
60
- }
@@ -1,215 +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
- const close = async () => {
142
- let trustedPosition = position;
143
- // Re-read after acquiring the shared trading boundary. A Wave 9
144
- // reversal or another stop may have flattened the symbol while this
145
- // watcher was queued.
146
- if (this.operationLock) {
147
- const current = await this.adapter.getPositionsOrNull(position.symbol);
148
- if (current === null) {
149
- throw new Error('position recheck unavailable while holding trading operation lock');
150
- }
151
- const latest = current.find((candidate) => candidate.symbol === position.symbol);
152
- if (!latest || !isStopBreached(latest)) {
153
- logger.info(TAG, `${position.symbol} no longer stop-triggered after locked recheck — skipping`);
154
- return 'skipped';
155
- }
156
- trustedPosition = latest;
157
- }
158
- let candidateId;
159
- let ownershipError;
160
- if (this.wave9CloseLifecycle) {
161
- try {
162
- candidateId = await this.wave9CloseLifecycle.resolveCandidateId(trustedPosition);
163
- }
164
- catch (error) {
165
- ownershipError = formatError(error);
166
- }
167
- }
168
- if (ownershipError) {
169
- throw new Error(`Wave 9 ownership resolution failed before stop close submission: ${ownershipError}; ` +
170
- 'IMMEDIATE MANUAL INTERVENTION REQUIRED');
171
- }
172
- await this.adapter.closePosition(trustedPosition.symbol, 'stop_watcher');
173
- if (!candidateId || !this.wave9CloseLifecycle)
174
- return 'closed';
175
- const outcome = await this.wave9CloseLifecycle.settleAfterClose(candidateId, trustedPosition.symbol);
176
- if (outcome.status === 'flat')
177
- return 'closed';
178
- if (outcome.status === 'protected') {
179
- logger.warn(TAG, `Stop close left a Wave 9 residual on ${trustedPosition.symbol}; ` +
180
- `${outcome.detail}. The exact frozen stop is proven and the watcher will retry.`);
181
- this.emit('stop_residual_protected', { ...event, ...outcome });
182
- return 'residual_protected';
183
- }
184
- throw new Error(outcome.detail);
185
- };
186
- try {
187
- const result = this.operationLock
188
- ? await this.operationLock.withSymbolLock(position.symbol, `stop_watcher:${position.symbol}`, close)
189
- : await close();
190
- if (result !== 'closed')
191
- return;
192
- logger.info(TAG, `Auto-closed ${position.symbol} (reason=stop_watcher)`);
193
- this.emit('stop_closed', event);
194
- }
195
- catch (err) {
196
- const msg = formatError(err);
197
- // "No open position" means the LLM or another path already closed it —
198
- // that's a successful no-op, not a failure.
199
- if (msg.includes('No open position')) {
200
- logger.info(TAG, `${position.symbol} already closed by another path — skipping`);
201
- }
202
- else {
203
- logger.error(TAG, `Auto-close failed for ${position.symbol}: ${msg}`);
204
- }
205
- this.emit('stop_failed', { ...event, error: msg });
206
- }
207
- finally {
208
- this.closePending.delete(position.symbol);
209
- }
210
- }
211
- /** For tests. */
212
- isRunning() {
213
- return this.interval !== null;
214
- }
215
- }
@@ -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
- }