@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,163 +0,0 @@
1
- // Agent-readiness reporter — runs connect-phase health checks ON the trader's
2
- // host and POSTs a self-describing report to the webapp, so a silently-broken
3
- // agent (geo-blocked by Binance, clock-skewed, no tools) surfaces a plain-English
4
- // dashboard alert instead of a false green. Advisory only: it NEVER blocks
5
- // trading or the safety floor. See docs/AGENT_READINESS_GATE_PLAN.md (Phase 1).
6
- //
7
- // No token → no-op (nothing to authenticate; matches the config poller). A
8
- // module-level singleton guard mirrors `pluginInitialised` in index.ts — OpenClaw
9
- // calls register() multiple times per process and we must never spawn a second
10
- // timer. The interval is unref()'d so it never holds the process open.
11
- import { makeReadinessCheck, deriveOverallReadiness, } from '@reefclaw/shared';
12
- import { logger, formatError } from '../logger.js';
13
- const TAG = 'readiness';
14
- const DEFAULT_INTERVAL_MS = 300_000; // 5 min — geo/clock state changes rarely.
15
- const MIN_INTERVAL_MS = 60_000;
16
- /** Best-effort display fact; kept in sync with the register() banner in index.ts. */
17
- const PLUGIN_VERSION = '3.8.0';
18
- function resolveIntervalMs(explicit) {
19
- if (explicit && explicit > 0)
20
- return Math.max(MIN_INTERVAL_MS, explicit);
21
- const raw = Number(process.env.RC_READINESS_INTERVAL_MS);
22
- if (!Number.isFinite(raw) || raw <= 0)
23
- return DEFAULT_INTERVAL_MS;
24
- return Math.max(MIN_INTERVAL_MS, raw);
25
- }
26
- /** Run every connect-phase check once and assemble the report. Exported for
27
- * unit tests.
28
- *
29
- * `bootWarmup` marks the FIRST cycle, which fires during gateway boot while
30
- * the event loop is congested (WS start, snapshot, seed all racing). That
31
- * delay between the probe's server-time response and the local `Date.now()`
32
- * read inflates the apparent clock drift — observed −4112ms at boot
33
- * self-correcting to −108ms on the next 5-min cycle. During warm-up a
34
- * warn/fail drift is reported 'unknown' (not amber/red) so the readiness
35
- * banner doesn't cry-wolf for ~5 min after every restart; a genuinely
36
- * skewed clock still surfaces on cycle 2. */
37
- export async function collectReadiness(opts, bootWarmup = false) {
38
- const now = Date.now();
39
- const checks = [];
40
- // The venue decides which reachability check this report carries; the copy
41
- // for both ids lives in shared/src/readiness.ts. Clock drift comes from the
42
- // same probe on both venues (Binance fapi serverTime / Hyperliquid
43
- // exchangeStatus.time — live-verified 2026-07-11).
44
- const reachId = opts.venue === 'hyperliquid' ? 'hyperliquid_reachable' : 'binance_reachable';
45
- // plugin_loaded — trivially true (this code runs inside the loaded plugin),
46
- // but a positive row is what proves the report path is alive at all.
47
- checks.push(makeReadinessCheck('plugin_loaded', 'pass', { checkedAt: now }));
48
- // tools_registered
49
- checks.push(makeReadinessCheck('tools_registered', opts.toolCount > 0 ? 'pass' : 'fail', {
50
- detail: `${opts.toolCount} tools`,
51
- checkedAt: now,
52
- }));
53
- // venue reachability (+ clock drift from the same probe response)
54
- const probe = await opts.publicApi.probeReachability();
55
- if (probe.outcome === 'reachable') {
56
- checks.push(makeReadinessCheck(reachId, 'pass', { checkedAt: now }));
57
- const drift = probe.driftMs;
58
- if (drift == null) {
59
- checks.push(makeReadinessCheck('clock_in_sync', 'unknown', { checkedAt: now }));
60
- }
61
- else {
62
- const abs = Math.abs(drift);
63
- const rawStatus = abs <= 1000 ? 'pass' : abs <= 5000 ? 'warn' : 'fail';
64
- // Boot warm-up: a non-pass reading on the first cycle is untrustworthy
65
- // (event-loop congestion inflates the measured drift) — report 'unknown'
66
- // and let the next cycle confirm, rather than flash the banner amber/red.
67
- const status = bootWarmup && rawStatus !== 'pass' ? 'unknown' : rawStatus;
68
- checks.push(makeReadinessCheck('clock_in_sync', status, {
69
- detail: bootWarmup && rawStatus !== 'pass'
70
- ? `drift ${Math.round(drift)}ms (boot warm-up — rechecking)`
71
- : `drift ${Math.round(drift)}ms`,
72
- checkedAt: now,
73
- }));
74
- }
75
- }
76
- else if (probe.outcome === 'geo_blocked') {
77
- checks.push(makeReadinessCheck(reachId, 'fail', {
78
- detail: opts.venue === 'binance' ? 'HTTP 451' : 'blocked (HTTP 451/403)',
79
- checkedAt: now,
80
- }));
81
- checks.push(makeReadinessCheck('clock_in_sync', 'unknown', { checkedAt: now }));
82
- }
83
- else if (probe.outcome === 'unreachable') {
84
- // Network/DNS/timeout — could be transient, so warn (amber) rather than
85
- // asserting a definitive failure. A persistent problem stays amber across
86
- // re-checks; only the geo-block is a hard red.
87
- checks.push(makeReadinessCheck(reachId, 'warn', { detail: 'unreachable', checkedAt: now }));
88
- checks.push(makeReadinessCheck('clock_in_sync', 'unknown', { checkedAt: now }));
89
- }
90
- else {
91
- // 'unknown' — the ban/weight gate paused the probe; don't assert anything.
92
- checks.push(makeReadinessCheck(reachId, 'unknown', { checkedAt: now }));
93
- checks.push(makeReadinessCheck('clock_in_sync', 'unknown', { checkedAt: now }));
94
- }
95
- return {
96
- schemaVersion: 1,
97
- generatedAt: now,
98
- overall: deriveOverallReadiness(checks),
99
- checks,
100
- agent: { pluginVersion: PLUGIN_VERSION, toolCount: opts.toolCount, venue: opts.venue },
101
- };
102
- }
103
- async function postReadiness(apiBaseUrl, token, report, fetchImpl, timeoutMs) {
104
- const url = `${apiBaseUrl.replace(/\/+$/, '')}/api/internal/agent-readiness`;
105
- const ac = new AbortController();
106
- const tid = setTimeout(() => ac.abort(), timeoutMs);
107
- try {
108
- const res = await fetchImpl(url, {
109
- method: 'POST',
110
- headers: {
111
- 'content-type': 'application/json',
112
- authorization: `Bearer ${token}`,
113
- },
114
- body: JSON.stringify(report),
115
- signal: ac.signal,
116
- });
117
- if (res.status < 200 || res.status >= 300) {
118
- logger.warn(TAG, `POST ${url} → ${res.status}`);
119
- }
120
- }
121
- catch (err) {
122
- logger.warn(TAG, `readiness POST failed: ${formatError(err)}`);
123
- }
124
- finally {
125
- clearTimeout(tid);
126
- }
127
- }
128
- let reporterStarted = false;
129
- /** Test-only — reset the singleton guard between unit tests. */
130
- export function __resetReadinessReporterForTests() {
131
- reporterStarted = false;
132
- }
133
- /** Fire the readiness report once at boot then on an unref'd interval. */
134
- export function startReadinessReporter(opts) {
135
- if (reporterStarted)
136
- return;
137
- if (!opts.token || !opts.token.trim()) {
138
- logger.info(TAG, 'no connection token — readiness reporting disabled');
139
- return;
140
- }
141
- reporterStarted = true;
142
- const fetchImpl = opts.fetchImpl ?? fetch;
143
- const intervalMs = resolveIntervalMs(opts.intervalMs);
144
- const timeoutMs = opts.requestTimeoutMs ?? 10_000;
145
- const cycle = async (bootWarmup) => {
146
- try {
147
- const report = await collectReadiness({ venue: opts.venue, publicApi: opts.publicApi, toolCount: opts.toolCount }, bootWarmup);
148
- await postReadiness(opts.apiBaseUrl, opts.token, report, fetchImpl, timeoutMs);
149
- if (report.overall === 'fail') {
150
- const failing = report.checks.filter((c) => c.status === 'fail').map((c) => c.id).join(', ');
151
- logger.warn(TAG, `readiness FAIL: ${failing}`);
152
- }
153
- }
154
- catch (err) {
155
- logger.warn(TAG, `readiness cycle failed: ${formatError(err)}`);
156
- }
157
- };
158
- // First fire is the boot cycle (warm-up); the interval cycles are steady-state.
159
- void cycle(true);
160
- const timer = setInterval(() => void cycle(false), intervalMs);
161
- timer.unref();
162
- logger.info(TAG, `readiness reporter started (interval ${Math.round(intervalMs / 1000)}s)`);
163
- }
@@ -1,13 +0,0 @@
1
- import type { PositionDecisionsClient } from './position-decisions-client.js';
2
- export interface DbVsExchangeContext {
3
- decisionsClient?: PositionDecisionsClient;
4
- userId?: string;
5
- }
6
- /**
7
- * Close webapp `positions` rows that are status='open' but absent from the
8
- * (trusted) exchange snapshot. Returns the number of synthetic closes posted.
9
- *
10
- * @param exchangeSymbols symbols from a TRUSTED snapshot (getPositionsOrNull()
11
- * !== null). Pass only when the fetch genuinely succeeded.
12
- */
13
- export declare function reconcileDbOpenVsExchange(ctx: DbVsExchangeContext, exchangeSymbols: Iterable<string>, nowMs?: number): Promise<number>;
@@ -1,114 +0,0 @@
1
- // DB-authoritative orphan close (Increment 0 of the durable orphan-position fix).
2
- //
3
- // The problem the existing backstops can't solve: a position closed on the
4
- // exchange (bracket SL/TP fill or manual close) while the gateway was DOWN, or
5
- // whose state-store entry was already wiped, leaves webapp `positions.status`
6
- // stuck 'open' forever. reconcileStateStoreOnStartup can't help — it iterates
7
- // only LOCAL state-store entries (a wiped entry is invisible) and passes
8
- // lastContracts:0 (which trips the fillSize>0 guard, so it never posts a close).
9
- //
10
- // This pass is DB-authoritative: it asks the webapp for the open set (keyed by
11
- // the DB row id, not local state), diffs against the EXCHANGE TRUTH snapshot,
12
- // and posts a synthetic close for any open DB row whose symbol is absent from
13
- // the exchange. Keying off the DB row id means a missing webappPositionId /
14
- // wiped state-store / untracked contracts can't defeat it for the common
15
- // one-row-per-symbol case.
16
- //
17
- // Known limitations (all fail SAFE — only false-negatives, never a wrong close):
18
- // - Diff is symbol-membership only. If a symbol has BOTH a genuine orphan and
19
- // a freshly re-opened live position (two open rows, same symbol, different
20
- // positionOpenAt), the symbol is on the exchange so NEITHER is closed — the
21
- // orphan persists until the next boot when that symbol is flat. A later
22
- // increment can make this count-aware (close the M−N oldest-by-openedAt when
23
- // the DB has M open rows but the exchange has N<M for the symbol).
24
- // - First-writer-wins on position_closes UNIQUE(position_id): if a real
25
- // close_position's journal POST is still retrying at boot, a synthetic close
26
- // can land first and the accurate PnL becomes a no-op. Synthetic rows are
27
- // tagged (metadata.synthetic) so a later increment could upgrade them.
28
- // - closeAt is stamped at boot, not the real (earlier) exchange close time, so
29
- // time-in-position analytics on these rows are approximate. Tagged synthetic.
30
- //
31
- // Safety (mandatory): the caller MUST pass a TRUSTED exchange snapshot
32
- // (getPositionsOrNull() !== null). A failed REST fetch collapses to [] in
33
- // getPositions(), which would make EVERY open row look orphaned — never run
34
- // this pass off an untrusted/empty-on-error snapshot.
35
- //
36
- // Idempotency: position_closes is UNIQUE(position_id) with onConflictDoNothing,
37
- // and the parent status flip is idempotent — a real close_position (exact PnL)
38
- // that lands first always wins the UNIQUE. closeReason='reconciler_observed_flat'
39
- // + metadata.synthetic=true tags these for KPI exclusion.
40
- import { logger } from '../logger.js';
41
- const TAG = 'reconcile-db-vs-exchange';
42
- /** Canonicalise a symbol to its settle-suffix-free form (BTC/USDT:USDT → BTC/USDT). */
43
- function canonical(symbol) {
44
- return symbol.split(':')[0];
45
- }
46
- /**
47
- * Close webapp `positions` rows that are status='open' but absent from the
48
- * (trusted) exchange snapshot. Returns the number of synthetic closes posted.
49
- *
50
- * @param exchangeSymbols symbols from a TRUSTED snapshot (getPositionsOrNull()
51
- * !== null). Pass only when the fetch genuinely succeeded.
52
- */
53
- export async function reconcileDbOpenVsExchange(ctx, exchangeSymbols, nowMs = Date.now()) {
54
- if (!ctx.decisionsClient || !ctx.userId)
55
- return 0;
56
- const resp = await ctx.decisionsClient.getOpenPositions(ctx.userId);
57
- if (!resp) {
58
- // null = fetch failed (network / terminal). NEVER treat as "no open rows"
59
- // (null≠empty) — skip; the next boot / periodic sweep retries.
60
- logger.warn(TAG, 'DB open-positions fetch returned null — skipping reconcile (will retry)');
61
- return 0;
62
- }
63
- if (resp.positions.length === 0)
64
- return 0;
65
- const exchangeSet = new Set();
66
- for (const s of exchangeSymbols)
67
- exchangeSet.add(canonical(s));
68
- const orphans = resp.positions.filter((p) => !exchangeSet.has(canonical(p.symbol)));
69
- if (orphans.length === 0) {
70
- logger.info(TAG, `DB reconcile: all ${resp.positions.length} open row(s) present on exchange`);
71
- return 0;
72
- }
73
- logger.warn(TAG, `DB reconcile: ${orphans.length} open DB row(s) absent from exchange — closing: ${orphans.map((o) => o.symbol).join(', ')}`);
74
- let posted = 0;
75
- for (const o of orphans) {
76
- if (!(o.remainingSize > 0) || !(o.entryPrice > 0)) {
77
- logger.warn(TAG, `${o.symbol}: bad size/price from DB (size=${o.remainingSize}, entry=${o.entryPrice}) — skipping close`);
78
- continue;
79
- }
80
- const close = {
81
- positionId: o.id,
82
- closeAt: nowMs,
83
- closeReason: 'reconciler_observed_flat',
84
- closeAssessment: {
85
- source: 'db_exchange_sweep_boot',
86
- synthetic: true,
87
- note: 'Position open in DB but absent from the exchange snapshot. It was ' +
88
- 'closed on-exchange via a path that bypassed close_position (bracket ' +
89
- 'SL/TP fill or manual close). Synthetic close; PnL/R/MFE recomputed ' +
90
- 'server-side from the entry + last review.',
91
- openedAtMs: o.openedAt,
92
- },
93
- // Synthetic-but-neutral context. Tagged so KPI aggregation can exclude it.
94
- scorecardVerdict: 'unknown',
95
- confluenceScore: 0,
96
- regime: 'UNKNOWN',
97
- regimeConfidence: 0,
98
- // The true exit price wasn't captured; use the entry so the server-side
99
- // recompute yields ~0 realized PnL (honest "unknown") rather than a
100
- // fabricated number. R/MFE/give-back come from the last review row.
101
- fillPrice: o.entryPrice,
102
- fillSize: o.remainingSize,
103
- realizedPnl: 0,
104
- realizedR: 0,
105
- mfeRAtClose: 0,
106
- giveBackPctAtClose: 0,
107
- metadata: { synthetic: true, source: 'boot_reconcile' },
108
- };
109
- ctx.decisionsClient.postClose(ctx.userId, close);
110
- posted++;
111
- logger.info(TAG, `synthetic close posted ${o.symbol} (positionId=${o.id.slice(0, 8)}…, size=${o.remainingSize})`);
112
- }
113
- return posted;
114
- }
@@ -1,37 +0,0 @@
1
- import type { PositionDecisionsClient } from './position-decisions-client.js';
2
- import type { PositionStateStore } from '../live/position-state-store.js';
3
- export interface ReconcilerCleanupContext {
4
- decisionsClient?: PositionDecisionsClient;
5
- stateStore?: PositionStateStore;
6
- userId?: string;
7
- /** Last-price fetcher. Plugin-side passes a closure over
8
- * `adapter.getLastPrice`. Tests inject a mock. Returning `null` skips
9
- * the webapp close post (state-store still cleaned). */
10
- lastPriceFn?: (symbol: string) => Promise<number | null>;
11
- }
12
- export interface CloseObservedArgs {
13
- /** Symbol observed flat. Either canonical (`BTC/USDT`) or settle-suffix
14
- * (`BTC/USDT:USDT`) form — state-store normalises internally. */
15
- symbol: string;
16
- /** Last contracts seen by reconciler before exchange showed flat. Used as
17
- * fillSize on the synthetic close payload. */
18
- lastContracts: number;
19
- /** Epoch ms — when reconciler observed the close. Defaults to Date.now(). */
20
- observedAtMs?: number;
21
- }
22
- export declare function onReconcilerObservedClose(ctx: ReconcilerCleanupContext, args: CloseObservedArgs): Promise<void>;
23
- /** Startup-time reconciliation between state-store and exchange truth.
24
- *
25
- * Why this exists: the in-memory reconciler only emits `closed` drifts on
26
- * the exact transition "was on exchange last poll, gone now". State-store
27
- * entries that persist across a close-bypass that happened BEFORE the plugin
28
- * started are invisible to that loop — they sit in `position-state.json`
29
- * forever and the next entry on the same symbol gets mistaken for a scale-in.
30
- *
31
- * This pass runs once at boot, after the live adapter is initialised:
32
- * for every state-store entry, if the symbol isn't on the current exchange
33
- * snapshot, fire the same cleanup as the runtime hook would.
34
- *
35
- * Returns the count of entries cleaned (for log + telemetry).
36
- */
37
- export declare function reconcileStateStoreOnStartup(ctx: ReconcilerCleanupContext, exchangeSymbols: Iterable<string>): Promise<number>;
@@ -1,147 +0,0 @@
1
- // Reconciler-driven cleanup for the close-bypass-leaks-state class-of-bug.
2
- //
3
- // Background: when a position closes via any path other than close_position()
4
- // — i.e., bracket SL/TP fill, opposite-side market order, or external close on
5
- // the exchange UI — onClosePositionFilled never runs. Two pieces of state leak:
6
- //
7
- // 1. webapp `positions.status` stays 'open' indefinitely (until a manual
8
- // `scripts/reconcile-open-positions.py` sweep).
9
- // 2. `position-state.json` keeps the entry with its stale `webappPositionId`.
10
- // The next entry on the same symbol is then mistaken for a scale-in and
11
- // reviews silently drop because the cached id no longer maps to a live
12
- // DB row.
13
- //
14
- // All three close-bypass paths converge on the same observable: the next
15
- // reconciler tick (60 s cadence) sees the symbol gone from `getPositions()`
16
- // and emits a `drift_detected` event with `type='closed'`. We hook there.
17
- //
18
- // Two-phase cleanup:
19
- // Phase 1 — synthetic close to webapp (best-effort): if the state-store
20
- // entry has a `webappPositionId` and we can fetch a last price,
21
- // POST `/api/internal/position-closes` with a stub close payload
22
- // tagged `closeReason='reconciler_observed_flat'`. Webapp
23
- // recomputes realized PnL/R/MFE server-side from positionEntries +
24
- // last review (the same path the close auto-capture uses).
25
- // Phase 2 — state-store cleanup (unconditional): drop the entry. This is
26
- // the more important half — it prevents the next entry on the
27
- // same symbol from being mistaken for a scale-in.
28
- //
29
- // Idempotency:
30
- // - webapp endpoint dedups via UNIQUE on position_id (onConflictDoNothing).
31
- // - state-store remove is a no-op if the entry is already gone.
32
- // Re-firing on subsequent reconciler ticks is safe.
33
- //
34
- // Failure mode tradeoff: when no last-price is reachable, we skip the webapp
35
- // post but still clean state-store. The DB row stays 'open' until manual
36
- // reconcile (existing operator workflow). State-store cleanup alone closes
37
- // the next-entry-mistaken-for-scale-in failure mode, which is the harder one
38
- // to recover from.
39
- import { logger } from '../logger.js';
40
- const TAG = 'reconciler-cleanup';
41
- export async function onReconcilerObservedClose(ctx, args) {
42
- if (!ctx.stateStore)
43
- return;
44
- const entry = ctx.stateStore.get(args.symbol);
45
- if (!entry) {
46
- // Already clean. Could happen if close_position fired between the WS
47
- // close fill and this reconciler tick — onClosePositionFilled removed the
48
- // entry first. Silent no-op.
49
- return;
50
- }
51
- const webappPositionId = entry.webappPositionId;
52
- const observedAtMs = args.observedAtMs ?? Date.now();
53
- if (webappPositionId && ctx.decisionsClient && ctx.userId) {
54
- let lastPrice = null;
55
- if (ctx.lastPriceFn) {
56
- try {
57
- lastPrice = await ctx.lastPriceFn(args.symbol);
58
- }
59
- catch (err) {
60
- logger.warn(TAG, `lastPriceFn(${args.symbol}) threw: ${err instanceof Error ? err.message : String(err)} — synthetic close will be skipped`);
61
- }
62
- }
63
- const fillSize = Math.abs(args.lastContracts);
64
- if (lastPrice !== null && lastPrice > 0 && fillSize > 0) {
65
- const close = {
66
- positionId: webappPositionId,
67
- closeAt: observedAtMs,
68
- closeReason: 'reconciler_observed_flat',
69
- closeAssessment: {
70
- note: 'Position observed flat on exchange via reconciler. Close path ' +
71
- 'bypassed close_position (likely bracket SL/TP fill, opposite-side ' +
72
- 'market order, or external close). Synthetic close row.',
73
- observedAtMs,
74
- lastContracts: args.lastContracts,
75
- },
76
- scorecardVerdict: 'NO_GO',
77
- confluenceScore: 0,
78
- regime: 'unknown',
79
- regimeConfidence: 0.5,
80
- fillPrice: lastPrice,
81
- fillSize,
82
- // Webapp recomputes these server-side from positionEntries + last
83
- // review when all four arrive as zero (same code path the close
84
- // auto-capture uses).
85
- realizedPnl: 0,
86
- realizedR: 0,
87
- mfeRAtClose: 0,
88
- giveBackPctAtClose: 0,
89
- };
90
- ctx.decisionsClient.postClose(ctx.userId, close);
91
- logger.info(TAG, `synthetic close posted ${args.symbol} ` +
92
- `(positionId=${webappPositionId.slice(0, 8)}…, ` +
93
- `price=${lastPrice}, size=${fillSize})`);
94
- }
95
- else {
96
- logger.warn(TAG, `${args.symbol}: cannot post synthetic close ` +
97
- `(lastPrice=${lastPrice ?? 'null'}, size=${fillSize}); ` +
98
- `state-store entry will still be cleaned. DB row may stay ` +
99
- `status='open' until reconcile-open-positions.py runs.`);
100
- }
101
- }
102
- else if (!webappPositionId) {
103
- logger.info(TAG, `${args.symbol}: orphan entry (no webappPositionId, parent row never created) — cleaning state-store only`);
104
- }
105
- ctx.stateStore.remove(args.symbol);
106
- }
107
- /** Startup-time reconciliation between state-store and exchange truth.
108
- *
109
- * Why this exists: the in-memory reconciler only emits `closed` drifts on
110
- * the exact transition "was on exchange last poll, gone now". State-store
111
- * entries that persist across a close-bypass that happened BEFORE the plugin
112
- * started are invisible to that loop — they sit in `position-state.json`
113
- * forever and the next entry on the same symbol gets mistaken for a scale-in.
114
- *
115
- * This pass runs once at boot, after the live adapter is initialised:
116
- * for every state-store entry, if the symbol isn't on the current exchange
117
- * snapshot, fire the same cleanup as the runtime hook would.
118
- *
119
- * Returns the count of entries cleaned (for log + telemetry).
120
- */
121
- export async function reconcileStateStoreOnStartup(ctx, exchangeSymbols) {
122
- if (!ctx.stateStore)
123
- return 0;
124
- // Normalise the exchange symbol list — state-store stores canonical form.
125
- const exchangeSet = new Set();
126
- for (const sym of exchangeSymbols) {
127
- exchangeSet.add(sym.split(':')[0]);
128
- }
129
- const stale = ctx.stateStore.getAll().filter((e) => !exchangeSet.has(e.symbol));
130
- if (stale.length === 0) {
131
- logger.info(TAG, `startup reconcile: state-store clean (${ctx.stateStore.size()} entries match exchange)`);
132
- return 0;
133
- }
134
- logger.warn(TAG, `startup reconcile: ${stale.length} stale state-store entr${stale.length === 1 ? 'y' : 'ies'} ` +
135
- `not on exchange — cleaning: ${stale.map((e) => e.symbol).join(', ')}`);
136
- for (const entry of stale) {
137
- await onReconcilerObservedClose(ctx, {
138
- symbol: entry.symbol,
139
- // We don't know the closing size — pass 0 so the synthetic close
140
- // post is skipped (size validation in cleanup). State-store entry
141
- // is still removed. Operator runs reconcile-open-positions.py to
142
- // close any matching DB rows.
143
- lastContracts: 0,
144
- });
145
- }
146
- return stale.length;
147
- }