@reefclaw/openclaw-plugin 0.1.0

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 (371) hide show
  1. package/.gitignore +8 -0
  2. package/audit/mode-transition-audit.d.ts +11 -0
  3. package/audit/mode-transition-audit.js +29 -0
  4. package/balance-utils.d.ts +36 -0
  5. package/balance-utils.js +98 -0
  6. package/bridge/bridge.d.ts +109 -0
  7. package/bridge/bridge.js +1036 -0
  8. package/bridge/config.d.ts +43 -0
  9. package/bridge/config.js +176 -0
  10. package/bridge/connector.d.ts +52 -0
  11. package/bridge/connector.js +293 -0
  12. package/bridge/event-replay-buffer.d.ts +43 -0
  13. package/bridge/event-replay-buffer.js +109 -0
  14. package/bridge/gateway/event-parser.d.ts +209 -0
  15. package/bridge/gateway/event-parser.js +793 -0
  16. package/bridge/gateway/gateway-config.d.ts +39 -0
  17. package/bridge/gateway/gateway-config.js +86 -0
  18. package/bridge/gateway/gateway-http-client.d.ts +50 -0
  19. package/bridge/gateway/gateway-http-client.js +165 -0
  20. package/bridge/gateway/gateway-ws-client.d.ts +116 -0
  21. package/bridge/gateway/gateway-ws-client.js +417 -0
  22. package/bridge/gateway/poller.d.ts +146 -0
  23. package/bridge/gateway/poller.js +505 -0
  24. package/bridge/gateway/tool-discovery.d.ts +25 -0
  25. package/bridge/gateway/tool-discovery.js +198 -0
  26. package/bridge/index.d.ts +2 -0
  27. package/bridge/index.js +253 -0
  28. package/bridge/logger.d.ts +2 -0
  29. package/bridge/logger.js +2 -0
  30. package/bridge/provider.d.ts +156 -0
  31. package/bridge/provider.js +2 -0
  32. package/bridge/providers/emergency-commands.d.ts +54 -0
  33. package/bridge/providers/emergency-commands.js +235 -0
  34. package/bridge/providers/gateway.d.ts +322 -0
  35. package/bridge/providers/gateway.js +2302 -0
  36. package/bridge/providers/mock.d.ts +37 -0
  37. package/bridge/providers/mock.js +385 -0
  38. package/bridge/providers/onboarding-commands.d.ts +83 -0
  39. package/bridge/providers/onboarding-commands.js +213 -0
  40. package/bridge/providers/risk-calculator.d.ts +96 -0
  41. package/bridge/providers/risk-calculator.js +369 -0
  42. package/bridge/setup.d.ts +32 -0
  43. package/bridge/setup.js +226 -0
  44. package/bridge/types.d.ts +584 -0
  45. package/bridge/types.js +50 -0
  46. package/bridge/utils/reconnect.d.ts +6 -0
  47. package/bridge/utils/reconnect.js +6 -0
  48. package/bridge/utils/skill-signing.d.ts +51 -0
  49. package/bridge/utils/skill-signing.js +138 -0
  50. package/bridge/utils/skill-version.d.ts +17 -0
  51. package/bridge/utils/skill-version.js +74 -0
  52. package/ccxt/binance-ban-gate.d.ts +47 -0
  53. package/ccxt/binance-ban-gate.js +409 -0
  54. package/ccxt/binance-private.d.ts +325 -0
  55. package/ccxt/binance-private.js +1415 -0
  56. package/ccxt/binance-public.d.ts +18 -0
  57. package/ccxt/binance-public.js +147 -0
  58. package/config/agent-config-client.d.ts +55 -0
  59. package/config/agent-config-client.js +145 -0
  60. package/config/agent-config-poller.d.ts +25 -0
  61. package/config/agent-config-poller.js +100 -0
  62. package/config/brackets-config.d.ts +22 -0
  63. package/config/brackets-config.js +58 -0
  64. package/config/gate-store.d.ts +18 -0
  65. package/config/gate-store.js +61 -0
  66. package/config/plugin-config-io.d.ts +181 -0
  67. package/config/plugin-config-io.js +84 -0
  68. package/config/position-review-config.d.ts +35 -0
  69. package/config/position-review-config.js +105 -0
  70. package/config/tool-gate.d.ts +53 -0
  71. package/config/tool-gate.js +125 -0
  72. package/config/user-data-stream-config.d.ts +85 -0
  73. package/config/user-data-stream-config.js +224 -0
  74. package/connector-supervisor.d.ts +36 -0
  75. package/connector-supervisor.js +149 -0
  76. package/exchange-adapter.d.ts +49 -0
  77. package/exchange-adapter.js +4 -0
  78. package/index.d.ts +30 -0
  79. package/index.js +2030 -0
  80. package/ingest/pending-entry-metadata.d.ts +52 -0
  81. package/ingest/pending-entry-metadata.js +182 -0
  82. package/ingest/position-auto-capture.d.ts +98 -0
  83. package/ingest/position-auto-capture.js +394 -0
  84. package/ingest/position-decisions-client.d.ts +318 -0
  85. package/ingest/position-decisions-client.js +296 -0
  86. package/ingest/reconcile-db-vs-exchange.d.ts +13 -0
  87. package/ingest/reconcile-db-vs-exchange.js +114 -0
  88. package/ingest/reconciler-cleanup.d.ts +37 -0
  89. package/ingest/reconciler-cleanup.js +147 -0
  90. package/ingest/rest-gap-filler.d.ts +191 -0
  91. package/ingest/rest-gap-filler.js +565 -0
  92. package/ingest/touched-symbols-store.d.ts +25 -0
  93. package/ingest/touched-symbols-store.js +96 -0
  94. package/ingest/trade-store-client.d.ts +40 -0
  95. package/ingest/trade-store-client.js +125 -0
  96. package/ingest/ws-ingest.d.ts +43 -0
  97. package/ingest/ws-ingest.js +126 -0
  98. package/learning/setup-family.d.ts +21 -0
  99. package/learning/setup-family.js +103 -0
  100. package/lifecycle/install-signal-handlers.d.ts +33 -0
  101. package/lifecycle/install-signal-handlers.js +112 -0
  102. package/lifecycle/shutdown-coordinator.d.ts +43 -0
  103. package/lifecycle/shutdown-coordinator.js +131 -0
  104. package/live/bracket-id.d.ts +18 -0
  105. package/live/bracket-id.js +81 -0
  106. package/live/bracket-ledger.d.ts +54 -0
  107. package/live/bracket-ledger.js +267 -0
  108. package/live/bracket-manager.d.ts +82 -0
  109. package/live/bracket-manager.js +478 -0
  110. package/live/bracket-params.d.ts +22 -0
  111. package/live/bracket-params.js +124 -0
  112. package/live/bracket-reconciler.d.ts +95 -0
  113. package/live/bracket-reconciler.js +573 -0
  114. package/live/bracket-types.d.ts +102 -0
  115. package/live/bracket-types.js +8 -0
  116. package/live/deposit-tracker.d.ts +62 -0
  117. package/live/deposit-tracker.js +97 -0
  118. package/live/emergency-controls.d.ts +32 -0
  119. package/live/emergency-controls.js +226 -0
  120. package/live/exchange-errors.d.ts +12 -0
  121. package/live/exchange-errors.js +130 -0
  122. package/live/exchange-info-cache.d.ts +35 -0
  123. package/live/exchange-info-cache.js +119 -0
  124. package/live/fact-subscriber.d.ts +78 -0
  125. package/live/fact-subscriber.js +182 -0
  126. package/live/intent-journal.d.ts +42 -0
  127. package/live/intent-journal.js +122 -0
  128. package/live/listen-key-manager.d.ts +70 -0
  129. package/live/listen-key-manager.js +169 -0
  130. package/live/live-adapter.d.ts +264 -0
  131. package/live/live-adapter.js +1665 -0
  132. package/live/live-balance-enricher.d.ts +32 -0
  133. package/live/live-balance-enricher.js +104 -0
  134. package/live/live-bracket-api.d.ts +13 -0
  135. package/live/live-bracket-api.js +20 -0
  136. package/live/live-state-store.d.ts +194 -0
  137. package/live/live-state-store.js +450 -0
  138. package/live/local-signal-service.d.ts +57 -0
  139. package/live/local-signal-service.js +146 -0
  140. package/live/local-strategy-evaluator.d.ts +62 -0
  141. package/live/local-strategy-evaluator.js +127 -0
  142. package/live/microstructure-assembler.d.ts +54 -0
  143. package/live/microstructure-assembler.js +148 -0
  144. package/live/order-poller.d.ts +29 -0
  145. package/live/order-poller.js +125 -0
  146. package/live/position-state-store.d.ts +83 -0
  147. package/live/position-state-store.js +237 -0
  148. package/live/proposal-decision-listener.d.ts +64 -0
  149. package/live/proposal-decision-listener.js +288 -0
  150. package/live/proposal-manager.d.ts +76 -0
  151. package/live/proposal-manager.js +140 -0
  152. package/live/rate-limiter.d.ts +47 -0
  153. package/live/rate-limiter.js +159 -0
  154. package/live/reconciler.d.ts +39 -0
  155. package/live/reconciler.js +175 -0
  156. package/live/setup-buckets.d.ts +7 -0
  157. package/live/setup-buckets.js +33 -0
  158. package/live/slippage-tracker.d.ts +45 -0
  159. package/live/slippage-tracker.js +78 -0
  160. package/live/stop-watcher.d.ts +34 -0
  161. package/live/stop-watcher.js +158 -0
  162. package/live/user-data-active-probe.d.ts +54 -0
  163. package/live/user-data-active-probe.js +180 -0
  164. package/live/user-data-stream-controller.d.ts +200 -0
  165. package/live/user-data-stream-controller.js +579 -0
  166. package/live/user-data-stream-ws.d.ts +22 -0
  167. package/live/user-data-stream-ws.js +63 -0
  168. package/live/user-data-stream.d.ts +243 -0
  169. package/live/user-data-stream.js +704 -0
  170. package/logger.d.ts +2 -0
  171. package/logger.js +2 -0
  172. package/mfe.d.ts +21 -0
  173. package/mfe.js +68 -0
  174. package/onboarding/mode-ladder.d.ts +1 -0
  175. package/onboarding/mode-ladder.js +3 -0
  176. package/onboarding/runtime.d.ts +71 -0
  177. package/onboarding/runtime.js +153 -0
  178. package/openclaw.plugin.json +94 -0
  179. package/package.json +27 -0
  180. package/paper-adapter.d.ts +24 -0
  181. package/paper-adapter.js +91 -0
  182. package/persistence/state-manager.d.ts +42 -0
  183. package/persistence/state-manager.js +164 -0
  184. package/pinned-plan.d.ts +9 -0
  185. package/pinned-plan.js +23 -0
  186. package/risk/pre-trade-check.d.ts +38 -0
  187. package/risk/pre-trade-check.js +345 -0
  188. package/risk/pre-trade-types.d.ts +60 -0
  189. package/risk/pre-trade-types.js +3 -0
  190. package/scripts/assemble.mjs +114 -0
  191. package/shadow/shadow-tracker.d.ts +36 -0
  192. package/shadow/shadow-tracker.js +151 -0
  193. package/shadow/types.d.ts +42 -0
  194. package/shadow/types.js +20 -0
  195. package/shared/indicators-extended.d.ts +52 -0
  196. package/shared/indicators-extended.js +291 -0
  197. package/shared/indicators.d.ts +15 -0
  198. package/shared/indicators.js +114 -0
  199. package/signals/conditions/registry.d.ts +16 -0
  200. package/signals/conditions/registry.js +1274 -0
  201. package/signals/conditions/types.d.ts +1 -0
  202. package/signals/conditions/types.js +4 -0
  203. package/signals/direction-rules.d.ts +3 -0
  204. package/signals/direction-rules.js +24 -0
  205. package/signals/entry-rules.d.ts +6 -0
  206. package/signals/entry-rules.js +33 -0
  207. package/signals/serialize-context.d.ts +4 -0
  208. package/signals/serialize-context.js +39 -0
  209. package/signals/stop-rules.d.ts +3 -0
  210. package/signals/stop-rules.js +48 -0
  211. package/signals/strategy-adapter.d.ts +14 -0
  212. package/signals/strategy-adapter.js +122 -0
  213. package/signals/types.d.ts +1 -0
  214. package/signals/types.js +8 -0
  215. package/simulator/exchange-simulator.d.ts +93 -0
  216. package/simulator/exchange-simulator.js +684 -0
  217. package/simulator/fill-engine.d.ts +53 -0
  218. package/simulator/fill-engine.js +276 -0
  219. package/simulator/paper-market-feed.d.ts +26 -0
  220. package/simulator/paper-market-feed.js +104 -0
  221. package/simulator/realistic-fills.d.ts +59 -0
  222. package/simulator/realistic-fills.js +175 -0
  223. package/simulator/types.d.ts +219 -0
  224. package/simulator/types.js +43 -0
  225. package/skills/reefclaw/SKILL.md +97 -0
  226. package/strategy/builtin-strategies.d.ts +2 -0
  227. package/strategy/builtin-strategies.js +109 -0
  228. package/strategy/condition-registry.d.ts +3 -0
  229. package/strategy/condition-registry.js +153 -0
  230. package/strategy/evaluator.d.ts +67 -0
  231. package/strategy/evaluator.js +93 -0
  232. package/tools/assessment-validation.d.ts +118 -0
  233. package/tools/assessment-validation.js +415 -0
  234. package/tools/attach-brackets.d.ts +34 -0
  235. package/tools/attach-brackets.js +363 -0
  236. package/tools/audit-bracket-protection.d.ts +49 -0
  237. package/tools/audit-bracket-protection.js +527 -0
  238. package/tools/cancel-all-orders.d.ts +7 -0
  239. package/tools/cancel-all-orders.js +5 -0
  240. package/tools/cancel-order.d.ts +10 -0
  241. package/tools/cancel-order.js +14 -0
  242. package/tools/check-position-health.d.ts +46 -0
  243. package/tools/check-position-health.js +194 -0
  244. package/tools/clear-exchange-credentials.d.ts +24 -0
  245. package/tools/clear-exchange-credentials.js +70 -0
  246. package/tools/close-position.d.ts +22 -0
  247. package/tools/close-position.js +449 -0
  248. package/tools/create-order.d.ts +54 -0
  249. package/tools/create-order.js +338 -0
  250. package/tools/exit-gate.d.ts +58 -0
  251. package/tools/exit-gate.js +162 -0
  252. package/tools/fetch-balance.d.ts +5 -0
  253. package/tools/fetch-balance.js +4 -0
  254. package/tools/fetch-ohlcv.d.ts +11 -0
  255. package/tools/fetch-ohlcv.js +8 -0
  256. package/tools/fetch-open-orders.d.ts +7 -0
  257. package/tools/fetch-open-orders.js +4 -0
  258. package/tools/fetch-positions.d.ts +7 -0
  259. package/tools/fetch-positions.js +4 -0
  260. package/tools/fetch-ticker.d.ts +11 -0
  261. package/tools/fetch-ticker.js +5 -0
  262. package/tools/get-agent-profile.d.ts +4 -0
  263. package/tools/get-agent-profile.js +6 -0
  264. package/tools/get-analytics.d.ts +6 -0
  265. package/tools/get-analytics.js +7 -0
  266. package/tools/get-backtest.d.ts +12 -0
  267. package/tools/get-backtest.js +91 -0
  268. package/tools/get-basis.d.ts +7 -0
  269. package/tools/get-basis.js +7 -0
  270. package/tools/get-bracket-config.d.ts +11 -0
  271. package/tools/get-bracket-config.js +24 -0
  272. package/tools/get-cascade-risk.d.ts +7 -0
  273. package/tools/get-cascade-risk.js +8 -0
  274. package/tools/get-crypto-metrics.d.ts +18 -0
  275. package/tools/get-crypto-metrics.js +45 -0
  276. package/tools/get-cvd.d.ts +6 -0
  277. package/tools/get-cvd.js +6 -0
  278. package/tools/get-divergences.d.ts +6 -0
  279. package/tools/get-divergences.js +6 -0
  280. package/tools/get-funding-context.d.ts +6 -0
  281. package/tools/get-funding-context.js +16 -0
  282. package/tools/get-liquidation-levels.d.ts +7 -0
  283. package/tools/get-liquidation-levels.js +7 -0
  284. package/tools/get-liquidation-pulse.d.ts +9 -0
  285. package/tools/get-liquidation-pulse.js +22 -0
  286. package/tools/get-market-breadth.d.ts +6 -0
  287. package/tools/get-market-breadth.js +8 -0
  288. package/tools/get-market-intel.d.ts +19 -0
  289. package/tools/get-market-intel.js +116 -0
  290. package/tools/get-market-structure.d.ts +47 -0
  291. package/tools/get-market-structure.js +198 -0
  292. package/tools/get-my-mined-patterns.d.ts +20 -0
  293. package/tools/get-my-mined-patterns.js +61 -0
  294. package/tools/get-my-proposed-learnings.d.ts +20 -0
  295. package/tools/get-my-proposed-learnings.js +55 -0
  296. package/tools/get-my-recent-reviews.d.ts +22 -0
  297. package/tools/get-my-recent-reviews.js +66 -0
  298. package/tools/get-orderbook.d.ts +21 -0
  299. package/tools/get-orderbook.js +32 -0
  300. package/tools/get-pattern-scan.d.ts +7 -0
  301. package/tools/get-pattern-scan.js +8 -0
  302. package/tools/get-regime.d.ts +6 -0
  303. package/tools/get-regime.js +7 -0
  304. package/tools/get-relevant-learnings.d.ts +21 -0
  305. package/tools/get-relevant-learnings.js +65 -0
  306. package/tools/get-resting-liquidity.d.ts +6 -0
  307. package/tools/get-resting-liquidity.js +11 -0
  308. package/tools/get-risk-scenario.d.ts +29 -0
  309. package/tools/get-risk-scenario.js +47 -0
  310. package/tools/get-risk-summary.d.ts +51 -0
  311. package/tools/get-risk-summary.js +118 -0
  312. package/tools/get-sentiment.d.ts +4 -0
  313. package/tools/get-sentiment.js +6 -0
  314. package/tools/get-session-review.d.ts +7 -0
  315. package/tools/get-session-review.js +8 -0
  316. package/tools/get-setup-detail.d.ts +7 -0
  317. package/tools/get-setup-detail.js +303 -0
  318. package/tools/get-signals.d.ts +15 -0
  319. package/tools/get-signals.js +54 -0
  320. package/tools/get-sizing.d.ts +6 -0
  321. package/tools/get-sizing.js +6 -0
  322. package/tools/get-trade-feedback.d.ts +7 -0
  323. package/tools/get-trade-feedback.js +8 -0
  324. package/tools/get-trade-flow.d.ts +7 -0
  325. package/tools/get-trade-flow.js +7 -0
  326. package/tools/get-volume-analysis.d.ts +21 -0
  327. package/tools/get-volume-analysis.js +74 -0
  328. package/tools/get-volume-profile.d.ts +7 -0
  329. package/tools/get-volume-profile.js +7 -0
  330. package/tools/helpers.d.ts +25 -0
  331. package/tools/helpers.js +38 -0
  332. package/tools/intel-api.d.ts +14 -0
  333. package/tools/intel-api.js +52 -0
  334. package/tools/intel-cache.d.ts +25 -0
  335. package/tools/intel-cache.js +133 -0
  336. package/tools/list-strategies.d.ts +7 -0
  337. package/tools/list-strategies.js +6 -0
  338. package/tools/modify-stop.d.ts +17 -0
  339. package/tools/modify-stop.js +81 -0
  340. package/tools/modify-target.d.ts +17 -0
  341. package/tools/modify-target.js +71 -0
  342. package/tools/propose-learning.d.ts +22 -0
  343. package/tools/propose-learning.js +65 -0
  344. package/tools/query-review-outcomes.d.ts +30 -0
  345. package/tools/query-review-outcomes.js +64 -0
  346. package/tools/query-trades.d.ts +21 -0
  347. package/tools/query-trades.js +37 -0
  348. package/tools/record-position-reviews.d.ts +38 -0
  349. package/tools/record-position-reviews.js +147 -0
  350. package/tools/save-strategy.d.ts +16 -0
  351. package/tools/save-strategy.js +46 -0
  352. package/tools/scan-pairs.d.ts +18 -0
  353. package/tools/scan-pairs.js +220 -0
  354. package/tools/score-setup.d.ts +31 -0
  355. package/tools/score-setup.js +268 -0
  356. package/tools/set-bracket-requirement.d.ts +18 -0
  357. package/tools/set-bracket-requirement.js +81 -0
  358. package/tools/set-exchange-credentials.d.ts +25 -0
  359. package/tools/set-exchange-credentials.js +80 -0
  360. package/tools/set-trading-mode.d.ts +26 -0
  361. package/tools/set-trading-mode.js +135 -0
  362. package/tools/test-exchange-credentials.d.ts +16 -0
  363. package/tools/test-exchange-credentials.js +100 -0
  364. package/tools/toggle-strategy.d.ts +8 -0
  365. package/tools/toggle-strategy.js +8 -0
  366. package/trading-params-cache.d.ts +26 -0
  367. package/trading-params-cache.js +52 -0
  368. package/types.d.ts +110 -0
  369. package/types.js +7 -0
  370. package/util/plugin-paths.d.ts +3 -0
  371. package/util/plugin-paths.js +15 -0
@@ -0,0 +1 @@
1
+ export type { ConditionResult, ConditionContext, ConditionFn, ConditionConfig, EntryRuleConfig, StopRuleConfig, DirectionRule, PrimaryTimeframe, StrategyConfig, } from '@reefclaw/shared';
@@ -0,0 +1,4 @@
1
+ // Re-export shim — see ../types.ts. The condition + strategy-config contracts
2
+ // the generated registry/rules import from `./types.js`. Canonical definitions
3
+ // live in @reefclaw/shared (type-only → erased at runtime).
4
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { MarketContext, Direction } from './types.js';
2
+ import type { ConditionContext, DirectionRule } from './conditions/types.js';
3
+ export declare function resolveDirection(rule: DirectionRule, ctx: MarketContext, condCtx: ConditionContext): Direction | null;
@@ -0,0 +1,24 @@
1
+ // ⚠️ GENERATED FILE — DO NOT EDIT.
2
+ // Canonical source of truth: shared/src/signals/direction-rules.ts
3
+ // Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
4
+ //
5
+ // This copy exists because this package builds with tsc and deploys as a
6
+ // self-contained tree that strips workspace deps, so it cannot import
7
+ // @reefclaw/shared runtime code across the deploy boundary.
8
+ export function resolveDirection(rule, ctx, condCtx) {
9
+ switch (rule) {
10
+ case 'from_regime':
11
+ return ctx.regime === 'TREND_UP' ? 'LONG' : ctx.regime === 'TREND_DOWN' ? 'SHORT' : null;
12
+ case 'from_sweep':
13
+ return condCtx.sweptDirection ?? null;
14
+ case 'from_funding':
15
+ // funding_extreme condition sets sweptDirection to the contra direction
16
+ return condCtx.sweptDirection ?? null;
17
+ case 'fixed_long':
18
+ return 'LONG';
19
+ case 'fixed_short':
20
+ return 'SHORT';
21
+ default:
22
+ return null;
23
+ }
24
+ }
@@ -0,0 +1,6 @@
1
+ import type { MarketContext, Direction } from './types.js';
2
+ import type { EntryRuleConfig, ConditionContext } from './conditions/types.js';
3
+ export declare function computeEntry(rule: EntryRuleConfig, ctx: MarketContext, direction: Direction, condCtx: ConditionContext): {
4
+ low: number;
5
+ high: number;
6
+ };
@@ -0,0 +1,33 @@
1
+ // ⚠️ GENERATED FILE — DO NOT EDIT.
2
+ // Canonical source of truth: shared/src/signals/entry-rules.ts
3
+ // Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
4
+ //
5
+ // This copy exists because this package builds with tsc and deploys as a
6
+ // self-contained tree that strips workspace deps, so it cannot import
7
+ // @reefclaw/shared runtime code across the deploy boundary.
8
+ // Entry zone calculation for declarative strategies.
9
+ import { computeEMA } from '../shared/indicators.js';
10
+ export function computeEntry(rule, ctx, direction, condCtx) {
11
+ switch (rule.type) {
12
+ case 'ema_offset': {
13
+ const period = rule.params.period ?? 21;
14
+ const atrFraction = (rule.params.atrFraction ?? 0.3) * ctx.atr14;
15
+ const ema = condCtx.ema21 && period === 21
16
+ ? condCtx.ema21
17
+ : computeEMA(ctx.ohlcv1h.map(b => b.close), period);
18
+ return { low: ema - atrFraction, high: ema + atrFraction };
19
+ }
20
+ case 'sweep_range': {
21
+ const sweepLevel = condCtx.sweepLevel ?? ctx.currentPrice;
22
+ return direction === 'LONG'
23
+ ? { low: sweepLevel, high: ctx.currentPrice }
24
+ : { low: ctx.currentPrice, high: sweepLevel };
25
+ }
26
+ case 'atr_offset': {
27
+ const atrFraction = (rule.params.atrFraction ?? 0.2) * ctx.atr14;
28
+ return { low: ctx.currentPrice - atrFraction, high: ctx.currentPrice + atrFraction };
29
+ }
30
+ default:
31
+ return { low: ctx.currentPrice - ctx.atr14 * 0.3, high: ctx.currentPrice + ctx.atr14 * 0.3 };
32
+ }
33
+ }
@@ -0,0 +1,4 @@
1
+ import type { MarketContext } from './types.js';
2
+ export declare function serializeContext(ctx: MarketContext): string;
3
+ /** Parse a streamed context and rehydrate every Date field. Throws on bad JSON. */
4
+ export declare function deserializeContext(raw: string): MarketContext;
@@ -0,0 +1,39 @@
1
+ // ⚠️ GENERATED FILE — DO NOT EDIT.
2
+ // Canonical source of truth: shared/src/signals/serialize-context.ts
3
+ // Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
4
+ //
5
+ // This copy exists because this package builds with tsc and deploys as a
6
+ // self-contained tree that strips workspace deps, so it cannot import
7
+ // @reefclaw/shared runtime code across the deploy boundary.
8
+ export function serializeContext(ctx) {
9
+ return JSON.stringify(ctx);
10
+ }
11
+ function reviveBars(bars) {
12
+ if (!Array.isArray(bars))
13
+ return undefined;
14
+ return bars.map((b) => ({ ...b, time: new Date(b.time) }));
15
+ }
16
+ /** Parse a streamed context and rehydrate every Date field. Throws on bad JSON. */
17
+ export function deserializeContext(raw) {
18
+ const o = JSON.parse(raw);
19
+ o.timestamp = new Date(o.timestamp);
20
+ const oh1 = reviveBars(o.ohlcv1h);
21
+ if (oh1)
22
+ o.ohlcv1h = oh1;
23
+ const oh5 = reviveBars(o.ohlcv5m);
24
+ if (oh5)
25
+ o.ohlcv5m = oh5;
26
+ const oh4 = reviveBars(o.ohlcv4h);
27
+ if (oh4)
28
+ o.ohlcv4h = oh4;
29
+ const oh1d = reviveBars(o.ohlcv1d);
30
+ if (oh1d)
31
+ o.ohlcv1d = oh1d;
32
+ if (Array.isArray(o.tradeFlow)) {
33
+ o.tradeFlow = o.tradeFlow.map((t) => ({ ...t, bucket: new Date(t.bucket) }));
34
+ }
35
+ if (o.globalContext?.btcRsi14_1d_at) {
36
+ o.globalContext.btcRsi14_1d_at = new Date(o.globalContext.btcRsi14_1d_at);
37
+ }
38
+ return o;
39
+ }
@@ -0,0 +1,3 @@
1
+ import type { MarketContext, Direction } from './types.js';
2
+ import type { StopRuleConfig, ConditionContext } from './conditions/types.js';
3
+ export declare function computeStop(rule: StopRuleConfig, ctx: MarketContext, direction: Direction, condCtx: ConditionContext): number;
@@ -0,0 +1,48 @@
1
+ // ⚠️ GENERATED FILE — DO NOT EDIT.
2
+ // Canonical source of truth: shared/src/signals/stop-rules.ts
3
+ // Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
4
+ //
5
+ // This copy exists because this package builds with tsc and deploys as a
6
+ // self-contained tree that strips workspace deps, so it cannot import
7
+ // @reefclaw/shared runtime code across the deploy boundary.
8
+ // Stop level calculation for declarative strategies.
9
+ import { findSwingPoints } from '../shared/indicators.js';
10
+ export function computeStop(rule, ctx, direction, condCtx) {
11
+ switch (rule.type) {
12
+ case 'swing_atr': {
13
+ const swingCount = rule.params.swingCount ?? 3;
14
+ const atrFraction = (rule.params.atrFraction ?? 0.3) * ctx.atr14;
15
+ const fallbackAtrMult = rule.params.fallbackAtrMultiple ?? 2;
16
+ const swings = findSwingPoints(ctx.ohlcv1h.slice(-48), 3);
17
+ if (direction === 'LONG') {
18
+ return swings.lows.length > 0
19
+ ? Math.min(...swings.lows.slice(-swingCount)) - atrFraction
20
+ : ctx.currentPrice - ctx.atr14 * fallbackAtrMult;
21
+ }
22
+ else {
23
+ return swings.highs.length > 0
24
+ ? Math.max(...swings.highs.slice(-swingCount)) + atrFraction
25
+ : ctx.currentPrice + ctx.atr14 * fallbackAtrMult;
26
+ }
27
+ }
28
+ case 'recent_extreme_atr': {
29
+ const atrFraction = (rule.params.atrFraction ?? 0.5) * ctx.atr14;
30
+ if (direction === 'LONG') {
31
+ return (condCtx.recentLow ?? ctx.currentPrice - ctx.atr14) - atrFraction;
32
+ }
33
+ else {
34
+ return (condCtx.recentHigh ?? ctx.currentPrice + ctx.atr14) + atrFraction;
35
+ }
36
+ }
37
+ case 'fixed_atr': {
38
+ const atrMultiple = rule.params.atrMultiple ?? 1.5;
39
+ return direction === 'LONG'
40
+ ? ctx.currentPrice - ctx.atr14 * atrMultiple
41
+ : ctx.currentPrice + ctx.atr14 * atrMultiple;
42
+ }
43
+ default:
44
+ return direction === 'LONG'
45
+ ? ctx.currentPrice - ctx.atr14 * 2
46
+ : ctx.currentPrice + ctx.atr14 * 2;
47
+ }
48
+ }
@@ -0,0 +1,14 @@
1
+ import type { StrategyDefinition } from './types.js';
2
+ import type { StrategyConfig } from './conditions/types.js';
3
+ export declare function clearStrategyGatingState(): void;
4
+ /**
5
+ * Convert a declarative StrategyConfig into a StrategyDefinition
6
+ * that the signal engine and backtest engine can evaluate.
7
+ *
8
+ * `gateNamespace` scopes the module-global HTF tick-gate to the calling tenant
9
+ * (pass the strategy-cache key — `global` for the background pass, the user key
10
+ * for a per-user pass). Omit it for single-tenant callers (backtests, the
11
+ * plugin's local evaluator) — they keep the original un-namespaced gate key,
12
+ * so their behaviour is byte-identical.
13
+ */
14
+ export declare function adaptStrategy(config: StrategyConfig, gateNamespace?: string): StrategyDefinition;
@@ -0,0 +1,122 @@
1
+ // ⚠️ GENERATED FILE — DO NOT EDIT.
2
+ // Canonical source of truth: shared/src/signals/strategy-adapter.ts
3
+ // Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
4
+ //
5
+ // This copy exists because this package builds with tsc and deploys as a
6
+ // self-contained tree that strips workspace deps, so it cannot import
7
+ // @reefclaw/shared runtime code across the deploy boundary.
8
+ import { evaluateConditions } from './conditions/registry.js';
9
+ import { resolveDirection } from './direction-rules.js';
10
+ import { computeEntry } from './entry-rules.js';
11
+ import { computeStop } from './stop-rules.js';
12
+ /**
13
+ * Higher-timeframe tick gating state, keyed by
14
+ * `${gateNamespace}\x1f${strategyName}:${symbol}`.
15
+ *
16
+ * Lives at module scope because the strategy cache (strategy-store.ts) builds
17
+ * a fresh adapter every 60s, so closure-based state would reset constantly
18
+ * and 1d-primary strategies would re-evaluate on every tick instead of once
19
+ * per closed bar. Module-level state survives the cache refresh.
20
+ *
21
+ * ★ Multi-tenant: because the map is module-global, the key MUST carry a
22
+ * per-tenant `gateNamespace` (the caller's strategy-cache key — `global` vs a
23
+ * per-user key). Without it, two tenants running same-named strategies on the
24
+ * same symbol shared ONE gate: whichever evaluated first marked the bar
25
+ * consumed and the other tenant's strategy was silently SKIPPED until the next
26
+ * primary-timeframe bar closed (a full day for a 1d strategy). A `\x1f` (unit
27
+ * separator, never present in a UUID / strategy name / symbol) joins the
28
+ * namespace so distinct tenants can never collide.
29
+ *
30
+ * Backtests should call `clearStrategyGatingState()` between runs to avoid
31
+ * leakage across tests / sequential backtests.
32
+ */
33
+ const lastEvaluatedBarTime = new Map();
34
+ export function clearStrategyGatingState() {
35
+ lastEvaluatedBarTime.clear();
36
+ }
37
+ function pickTimeframeBars(ctx, tf) {
38
+ if (tf === '1d')
39
+ return ctx.ohlcv1d ?? [];
40
+ if (tf === '4h')
41
+ return ctx.ohlcv4h ?? [];
42
+ return ctx.ohlcv1h;
43
+ }
44
+ /** Empty no-signal evaluation — used when gating skips a strategy. */
45
+ const SKIPPED = { direction: null, conditions: [], trade: undefined };
46
+ /**
47
+ * Convert a declarative StrategyConfig into a StrategyDefinition
48
+ * that the signal engine and backtest engine can evaluate.
49
+ *
50
+ * `gateNamespace` scopes the module-global HTF tick-gate to the calling tenant
51
+ * (pass the strategy-cache key — `global` for the background pass, the user key
52
+ * for a per-user pass). Omit it for single-tenant callers (backtests, the
53
+ * plugin's local evaluator) — they keep the original un-namespaced gate key,
54
+ * so their behaviour is byte-identical.
55
+ */
56
+ export function adaptStrategy(config, gateNamespace) {
57
+ return {
58
+ name: config.name,
59
+ regimeWhitelist: config.regimeWhitelist,
60
+ minConfidence: config.minConfidence,
61
+ async evaluate(ctx) {
62
+ // ─── Tick gating ───────────────────────────────────────────────
63
+ // Only re-evaluate when a new bar of the strategy's primary
64
+ // timeframe has closed since the last evaluation for this
65
+ // strategy/symbol pair. Defaults to '1h' so existing strategies
66
+ // are unaffected.
67
+ const tf = config.primaryTimeframe ?? '1h';
68
+ const tfBars = pickTimeframeBars(ctx, tf);
69
+ if (tfBars.length === 0)
70
+ return SKIPPED;
71
+ const latestBarTime = tfBars[tfBars.length - 1].time.getTime();
72
+ // Namespaced per tenant (see lastEvaluatedBarTime doc) so same-named
73
+ // strategies across tenants never share a gate. Un-namespaced when
74
+ // gateNamespace is omitted — byte-identical to the original key.
75
+ const gateKey = gateNamespace
76
+ ? `${gateNamespace}\x1f${config.name}:${ctx.symbol}`
77
+ : `${config.name}:${ctx.symbol}`;
78
+ const lastBarTime = lastEvaluatedBarTime.get(gateKey);
79
+ if (lastBarTime !== undefined && latestBarTime === lastBarTime) {
80
+ return SKIPPED;
81
+ }
82
+ lastEvaluatedBarTime.set(gateKey, latestBarTime);
83
+ // ─── SkipIf gates ──────────────────────────────────────────────
84
+ // Portfolio-wide / cross-symbol filters. If any are met the
85
+ // strategy is skipped this tick. Evaluated before main conditions
86
+ // so the bulk of the work is short-circuited.
87
+ if (config.skipIf && config.skipIf.length > 0) {
88
+ const { conditions: skipResults } = evaluateConditions(config.skipIf, ctx, null);
89
+ if (skipResults.some(c => c.met))
90
+ return SKIPPED;
91
+ }
92
+ // Pass 1: evaluate conditions with direction = null
93
+ const { conditions: pass1, condCtx } = evaluateConditions(config.conditions, ctx, null);
94
+ // Determine direction
95
+ const direction = resolveDirection(config.directionRule, ctx, condCtx);
96
+ // Pass 2: re-evaluate direction-sensitive conditions now that we know direction
97
+ // (orderbook_imbalance and funding_contrarian behave differently per direction)
98
+ const directionSensitive = new Set(['orderbook_imbalance', 'funding_contrarian', 'funding_extreme_skip', 'funding_position_ok', 'return_momentum']);
99
+ const hasDirSensitive = config.conditions.some(c => directionSensitive.has(c.type));
100
+ let finalConditions = pass1;
101
+ if (direction && hasDirSensitive) {
102
+ const { conditions: pass2 } = evaluateConditions(config.conditions, ctx, direction);
103
+ // Merge: use pass2 results for direction-sensitive, pass1 for others
104
+ finalConditions = pass1.map((c, i) => directionSensitive.has(config.conditions[i].type) ? pass2[i] : c);
105
+ }
106
+ const allMet = finalConditions.every(c => c.met);
107
+ let trade;
108
+ if (allMet && direction) {
109
+ const entryZone = computeEntry(config.entryRule, ctx, direction, condCtx);
110
+ const stopLevel = computeStop(config.stopRule, ctx, direction, condCtx);
111
+ const risk = direction === 'LONG'
112
+ ? ctx.currentPrice - stopLevel
113
+ : stopLevel - ctx.currentPrice;
114
+ const targets = config.targetRMultiples.map(rm => direction === 'LONG'
115
+ ? ctx.currentPrice + risk * rm
116
+ : ctx.currentPrice - risk * rm);
117
+ trade = { entryZone, stopLevel, targets };
118
+ }
119
+ return { direction, conditions: finalConditions, trade };
120
+ },
121
+ };
122
+ }
@@ -0,0 +1 @@
1
+ export type { Direction, OhlcvBar, TradeFlowBucket, GlobalMarketContext, MarketContext, SignalCondition, StrategyEvaluation, StrategyDefinition, SignalEvent, StrategyState, SignalSnapshot, } from '@reefclaw/shared';
@@ -0,0 +1,8 @@
1
+ // Re-export shim for the plugin-side strategy evaluator (facts-out).
2
+ //
3
+ // The generated eval-core copies (registry, strategy-adapter, direction/entry/
4
+ // stop-rules) import their types from `./types.js`. The canonical definitions
5
+ // live in @reefclaw/shared (type-only → erased at runtime), so this shim makes
6
+ // those relative imports resolve inside the plugin tree without pulling any
7
+ // runtime dependency into the emitted JS. See docs/FACTS_OUT_ARCHITECTURE.md.
8
+ export {};
@@ -0,0 +1,93 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { SimulatorState, OrderBookDepth, SimulationConfig, ExecutionStats, PositionMetadata, CloseReason } from './types.js';
3
+ import type { CcxtOrder, CcxtBalance, CcxtPosition, CcxtTicker } from '../types.js';
4
+ export declare class ExchangeSimulator extends EventEmitter {
5
+ private state;
6
+ private lastTicker;
7
+ private lastOrderBook;
8
+ private simulationConfig;
9
+ /** Metadata for pending limit orders, keyed by order ID. Cleaned up on fill/cancel. */
10
+ private pendingOrderMetadata;
11
+ private cachedVolFactor;
12
+ private baselineAtr;
13
+ private atrSampleCount;
14
+ private readonly startupTime;
15
+ private readonly hadPositionsAtStartup;
16
+ private static readonly STARTUP_LOCKOUT_MS;
17
+ constructor(initialState: SimulatorState, config?: SimulationConfig);
18
+ getSimulationConfig(): SimulationConfig;
19
+ setVolFactor(factor: number): void;
20
+ getVolFactor(): number;
21
+ /** Update baseline ATR using exponential moving average of samples. */
22
+ updateBaselineAtr(atr14: number): void;
23
+ getBaselineAtr(): number;
24
+ /**
25
+ * Returns today's session-start NAV, lazily seeding it from current equity
26
+ * if unset or stale (different UTC day). This is the plugin-side anchor used
27
+ * by the pre-trade risk gate; a stale/missing anchor silently disables the
28
+ * drawdown zones, so callers must never see a zero.
29
+ */
30
+ getSessionStartNav(): number;
31
+ setSessionStartNav(nav: number): void;
32
+ /** Seed sessionStartNav from current equity on the first check of each UTC day.
33
+ * Safe to call repeatedly — no-op once the anchor matches today's date. */
34
+ private ensureSessionAnchor;
35
+ /** Mark-to-market equity = walletTotal + for each open position, the
36
+ * collateral locked at entry + current unrealized P&L. Paper simulator is
37
+ * SPOT-collateral style: the full entry notional was deducted from wallet
38
+ * on open and is released on close, so we must add it back here. */
39
+ computeEquity(): number;
40
+ private getQuoteCurrency;
41
+ getBalance(): CcxtBalance;
42
+ getPositions(symbol?: string): CcxtPosition[];
43
+ getOpenOrders(symbol?: string): CcxtOrder[];
44
+ /** Get cumulative execution quality stats. */
45
+ getExecutionStats(): ExecutionStats | undefined;
46
+ /** Cache the latest order book snapshot for a symbol. */
47
+ updateOrderBook(symbol: string, orderbook: OrderBookDepth): void;
48
+ getLastOrderBook(symbol: string): OrderBookDepth | undefined;
49
+ createOrder(symbol: string, side: 'buy' | 'sell', type: 'market' | 'limit', amount: number, price?: number, metadata?: PositionMetadata): CcxtOrder;
50
+ cancelOrder(orderId: string): CcxtOrder;
51
+ cancelAllOrders(symbol?: string): CcxtOrder[];
52
+ closePosition(symbol: string, closeReason?: CloseReason): CcxtOrder;
53
+ /** Paper-only: move an open position's MUTABLE protective levels (stopPrice /
54
+ * targetPrice) in place and persist, WITHOUT the close+reopen round-trip
55
+ * (which pays an extra taker fee and resets the R/MFE denominators). The
56
+ * frozen originalStopPrice / originalEntryPrice are intentionally left
57
+ * untouched so R-multiples stay anchored at entry. The paper stop-watcher
58
+ * and getPositions both read metadata.stopPrice, so a moved stop takes
59
+ * effect on the next watcher tick. Throws if there is no open position. (M9) */
60
+ updatePositionMetadata(symbol: string, patch: {
61
+ stopPrice?: number;
62
+ targetPrice?: number;
63
+ }): void;
64
+ updateTicker(ticker: CcxtTicker): void;
65
+ getLastTicker(symbol: string): CcxtTicker | undefined;
66
+ /** Walk every position for `symbol` and refresh MFE / give-back from the
67
+ * latest mark. Idempotent — pure update of `metadata.mfePeakPrice` (only
68
+ * ratchets favourably) plus derived `mfeR` and `giveBackRatio`. Safe to
69
+ * call before any positions exist (no-op). */
70
+ private refreshMfeForSymbol;
71
+ /** Replace internal state with a fresh copy from disk.
72
+ * Used by the gateway process to pick up state saved by the agent process.
73
+ *
74
+ * Non-destructive for the MFE ratchet (M3): the disk copy can lag the live
75
+ * peak (refreshMfeForSymbol ratchets every tick; persistence coalesces), so
76
+ * a wholesale swap would discard it. For each position present in BOTH
77
+ * snapshots (same symbol+side+openedAt) we carry over the MORE-favourable
78
+ * monotone peak and recompute mfeR/giveBackRatio from the current mark, so a
79
+ * reload never regresses the agent's give-back signal. */
80
+ replaceState(newState: SimulatorState): void;
81
+ getState(): SimulatorState;
82
+ private shouldFillLimit;
83
+ private executeMarketFill;
84
+ private executeLimitFill;
85
+ /** Apply a fill result: update positions, record trade, track stats, emit state change. */
86
+ private applyFillResult;
87
+ private updatePosition;
88
+ private addTrade;
89
+ /** Update cumulative execution stats from a fill's execution quality. */
90
+ private updateExecutionStats;
91
+ private emitStateChanged;
92
+ private toCcxtOrder;
93
+ }