opencandle 0.11.1 → 0.13.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 (678) hide show
  1. package/README.md +50 -186
  2. package/dist/analysts/contracts.js +0 -1
  3. package/dist/analysts/orchestrator.js +0 -1
  4. package/dist/cli-main.js +22 -15
  5. package/dist/cli-options.d.ts +4 -0
  6. package/dist/cli-options.js +33 -0
  7. package/dist/cli.js +8 -3
  8. package/dist/config.d.ts +4 -0
  9. package/dist/config.js +1 -1
  10. package/dist/doctor/cli-command.js +9 -5
  11. package/dist/doctor/render.js +0 -1
  12. package/dist/doctor/report.js +53 -11
  13. package/dist/gui/server/ask-user-bridge.d.ts +19 -0
  14. package/dist/gui/server/ask-user-bridge.js +55 -0
  15. package/dist/gui/server/automation-heartbeat.d.ts +25 -0
  16. package/dist/gui/server/automation-heartbeat.js +61 -0
  17. package/dist/gui/server/background-quotes.d.ts +39 -0
  18. package/dist/gui/server/background-quotes.js +71 -0
  19. package/dist/gui/server/chat-event-adapter.d.ts +16 -0
  20. package/dist/gui/server/chat-event-adapter.js +388 -0
  21. package/dist/gui/server/gui-session-manager.d.ts +2 -0
  22. package/dist/gui/server/gui-session-manager.js +4 -0
  23. package/dist/gui/server/history-snapshot-store.d.ts +8 -0
  24. package/dist/gui/server/history-snapshot-store.js +43 -0
  25. package/dist/gui/server/http-routes.d.ts +71 -0
  26. package/dist/gui/server/http-routes.js +1033 -0
  27. package/dist/gui/server/invoke-tool.d.ts +47 -0
  28. package/dist/gui/server/invoke-tool.js +373 -0
  29. package/dist/gui/server/live-chat-event-adapter.d.ts +21 -0
  30. package/dist/gui/server/live-chat-event-adapter.js +224 -0
  31. package/dist/gui/server/local-session-coordinator.d.ts +26 -0
  32. package/dist/gui/server/local-session-coordinator.js +53 -0
  33. package/dist/gui/server/market-indices-api.d.ts +21 -0
  34. package/dist/gui/server/market-indices-api.js +26 -0
  35. package/dist/gui/server/market-indices-snapshot-store.d.ts +12 -0
  36. package/dist/gui/server/market-indices-snapshot-store.js +56 -0
  37. package/dist/gui/server/market-state-api.d.ts +250 -0
  38. package/dist/gui/server/market-state-api.js +597 -0
  39. package/dist/gui/server/model-setup.d.ts +55 -0
  40. package/dist/gui/server/model-setup.js +154 -0
  41. package/dist/gui/server/private-api-access.d.ts +6 -0
  42. package/dist/gui/server/private-api-access.js +53 -0
  43. package/dist/gui/server/projector.d.ts +49 -0
  44. package/dist/gui/server/projector.js +296 -0
  45. package/dist/gui/server/prompt-observation.d.ts +8 -0
  46. package/dist/gui/server/prompt-observation.js +43 -0
  47. package/dist/gui/server/quote-snapshot-store.d.ts +14 -0
  48. package/dist/gui/server/quote-snapshot-store.js +49 -0
  49. package/dist/gui/server/server.d.ts +1 -0
  50. package/dist/gui/server/server.js +262 -0
  51. package/dist/gui/server/session-actions.d.ts +60 -0
  52. package/dist/gui/server/session-actions.js +218 -0
  53. package/dist/gui/server/session-entry-wait.d.ts +27 -0
  54. package/dist/gui/server/session-entry-wait.js +129 -0
  55. package/dist/gui/server/session-list.d.ts +2 -0
  56. package/dist/gui/server/session-list.js +11 -0
  57. package/dist/gui/server/shutdown.d.ts +10 -0
  58. package/dist/gui/server/shutdown.js +29 -0
  59. package/dist/gui/server/tool-invoke-ack.d.ts +17 -0
  60. package/dist/gui/server/tool-invoke-ack.js +26 -0
  61. package/dist/gui/server/tool-metadata.d.ts +93 -0
  62. package/dist/gui/server/tool-metadata.js +148 -0
  63. package/dist/gui/server/websocket.d.ts +9 -0
  64. package/dist/gui/server/websocket.js +124 -0
  65. package/dist/gui/server/writer-lock.d.ts +1 -0
  66. package/dist/gui/server/writer-lock.js +1 -0
  67. package/dist/gui/server/ws-hub.d.ts +50 -0
  68. package/dist/gui/server/ws-hub.js +284 -0
  69. package/dist/gui/shared/chat-events.d.ts +174 -0
  70. package/dist/gui/shared/chat-events.js +13 -0
  71. package/dist/gui/shared/event-reducer.d.ts +3 -0
  72. package/dist/gui/shared/event-reducer.js +187 -0
  73. package/dist/index.js +0 -1
  74. package/dist/infra/cache.d.ts +4 -0
  75. package/dist/infra/cache.js +4 -1
  76. package/dist/infra/freshness.js +0 -1
  77. package/dist/infra/http-client.js +1 -2
  78. package/dist/infra/index.js +0 -1
  79. package/dist/infra/lse-byte-budget.d.ts +10 -0
  80. package/dist/infra/lse-byte-budget.js +47 -0
  81. package/dist/infra/market-calendar.js +0 -1
  82. package/dist/infra/native-dependencies.js +0 -1
  83. package/dist/infra/node-version.js +0 -1
  84. package/dist/infra/open-url.js +0 -1
  85. package/dist/infra/opencandle-paths.js +0 -1
  86. package/dist/infra/rate-limiter.js +1 -1
  87. package/dist/market-state/alert-conditions.js +0 -1
  88. package/dist/market-state/alert-runner.d.ts +1 -0
  89. package/dist/market-state/alert-runner.js +5 -4
  90. package/dist/market-state/daily-report.js +0 -1
  91. package/dist/market-state/local-automation-service.js +0 -1
  92. package/dist/market-state/notification-delivery.js +0 -1
  93. package/dist/market-state/resolve-for-mutation.js +0 -1
  94. package/dist/market-state/resolve.js +0 -1
  95. package/dist/market-state/service.d.ts +26 -21
  96. package/dist/market-state/service.js +175 -36
  97. package/dist/market-state/summaries.js +1 -13
  98. package/dist/memory/index.js +0 -1
  99. package/dist/memory/manager.js +0 -1
  100. package/dist/memory/preference-extractor.js +0 -1
  101. package/dist/memory/retrieval.js +0 -1
  102. package/dist/memory/sqlite.js +60 -11
  103. package/dist/memory/storage.js +0 -1
  104. package/dist/memory/tool-defaults.js +0 -1
  105. package/dist/memory/types.js +0 -1
  106. package/dist/monitor.js +0 -1
  107. package/dist/onboarding/connect.js +0 -1
  108. package/dist/onboarding/credential-interceptor.js +0 -1
  109. package/dist/onboarding/degradation-accumulator.js +0 -1
  110. package/dist/onboarding/prompt-user.d.ts +1 -1
  111. package/dist/onboarding/prompt-user.js +0 -1
  112. package/dist/onboarding/provider-status.js +0 -1
  113. package/dist/onboarding/providers.d.ts +16 -1
  114. package/dist/onboarding/providers.js +20 -1
  115. package/dist/onboarding/state.js +0 -1
  116. package/dist/onboarding/tool-helpers.js +0 -1
  117. package/dist/onboarding/tool-tags.js +0 -1
  118. package/dist/onboarding/validate-model-key.d.ts +17 -0
  119. package/dist/onboarding/validate-model-key.js +86 -0
  120. package/dist/onboarding/validation.js +8 -1
  121. package/dist/pi/opencandle-extension.d.ts +2 -1
  122. package/dist/pi/opencandle-extension.js +4 -4
  123. package/dist/pi/session-action-dedupe.js +0 -1
  124. package/dist/pi/session-storage.js +0 -1
  125. package/dist/pi/session-writer-lock.js +0 -1
  126. package/dist/pi/session.d.ts +2 -3
  127. package/dist/pi/session.js +7 -6
  128. package/dist/pi/setup.d.ts +4 -2
  129. package/dist/pi/setup.js +60 -61
  130. package/dist/pi/tool-adapter.js +0 -1
  131. package/dist/pi/tui-session-coordinator.js +0 -1
  132. package/dist/prompts/context-builder.js +1 -2
  133. package/dist/prompts/disclaimer.js +0 -1
  134. package/dist/prompts/policy-cards.js +0 -1
  135. package/dist/prompts/sections.js +0 -1
  136. package/dist/prompts/symbol-preflight.js +0 -1
  137. package/dist/prompts/workflow-prompts.js +16 -15
  138. package/dist/providers/alpha-vantage.js +2 -3
  139. package/dist/providers/coingecko.js +0 -1
  140. package/dist/providers/errors.js +0 -1
  141. package/dist/providers/exa-search.js +11 -10
  142. package/dist/providers/external-tool-command.js +0 -1
  143. package/dist/providers/external-tool-error.js +0 -1
  144. package/dist/providers/fear-greed.js +0 -1
  145. package/dist/providers/finnhub.js +0 -1
  146. package/dist/providers/fred.js +0 -1
  147. package/dist/providers/index.d.ts +1 -0
  148. package/dist/providers/index.js +1 -1
  149. package/dist/providers/lse.d.ts +35 -0
  150. package/dist/providers/lse.js +284 -0
  151. package/dist/providers/polymarket.js +22 -6
  152. package/dist/providers/provider-credential-error.js +0 -1
  153. package/dist/providers/reddit-cli.js +0 -1
  154. package/dist/providers/reddit.js +0 -1
  155. package/dist/providers/sec-edgar.js +0 -1
  156. package/dist/providers/tradingview.js +1 -2
  157. package/dist/providers/twitter-cli.js +0 -1
  158. package/dist/providers/twitter.js +0 -1
  159. package/dist/providers/web-search.js +15 -12
  160. package/dist/providers/with-fallback.js +0 -1
  161. package/dist/providers/wrap-provider.js +1 -1
  162. package/dist/providers/yahoo-finance.js +68 -4
  163. package/dist/routing/classify-intent.js +0 -1
  164. package/dist/routing/defaults.js +0 -1
  165. package/dist/routing/entity-extractor.js +2 -3
  166. package/dist/routing/fund-symbols.js +0 -1
  167. package/dist/routing/horizon.js +0 -1
  168. package/dist/routing/index.js +0 -1
  169. package/dist/routing/legacy-rule-router.js +0 -1
  170. package/dist/routing/planning.js +0 -1
  171. package/dist/routing/route-manifest.js +1 -1
  172. package/dist/routing/router-llm-client.d.ts +2 -2
  173. package/dist/routing/router-llm-client.js +0 -1
  174. package/dist/routing/router-prompt.js +0 -1
  175. package/dist/routing/router-types.js +0 -1
  176. package/dist/routing/router.js +9 -3
  177. package/dist/routing/slot-resolver.js +0 -1
  178. package/dist/routing/symbol-disambiguator.js +0 -1
  179. package/dist/routing/turn-context.js +0 -1
  180. package/dist/routing/types.js +0 -1
  181. package/dist/runtime/answer-contracts.js +0 -1
  182. package/dist/runtime/artifact-contracts.js +0 -1
  183. package/dist/runtime/evidence.d.ts +1 -0
  184. package/dist/runtime/evidence.js +1 -2
  185. package/dist/runtime/numeric-claims.js +0 -1
  186. package/dist/runtime/planning-evidence.js +0 -1
  187. package/dist/runtime/prompt-step.js +0 -1
  188. package/dist/runtime/provider-tracker.js +0 -1
  189. package/dist/runtime/run-context.js +0 -1
  190. package/dist/runtime/session-coordinator.d.ts +2 -2
  191. package/dist/runtime/session-coordinator.js +2 -3
  192. package/dist/runtime/session-title.js +0 -1
  193. package/dist/runtime/tool-defaults-wrapper.js +0 -1
  194. package/dist/runtime/validation.js +0 -1
  195. package/dist/runtime/workflow-events.js +0 -1
  196. package/dist/runtime/workflow-runner.d.ts +1 -0
  197. package/dist/runtime/workflow-runner.js +8 -3
  198. package/dist/runtime/workflow-types.js +0 -1
  199. package/dist/sentiment/adapters/finnhub.js +0 -1
  200. package/dist/sentiment/adapters/reddit.js +0 -1
  201. package/dist/sentiment/adapters/twitter.js +0 -1
  202. package/dist/sentiment/adapters/web.js +0 -1
  203. package/dist/sentiment/index.js +4 -2
  204. package/dist/sentiment/insights.js +0 -1
  205. package/dist/sentiment/keywords.js +0 -1
  206. package/dist/sentiment/pipeline.js +0 -1
  207. package/dist/sentiment/scorer.js +0 -1
  208. package/dist/sentiment/store.js +0 -1
  209. package/dist/sentiment/trends.js +0 -1
  210. package/dist/sentiment/types.js +0 -1
  211. package/dist/system-prompt.js +0 -1
  212. package/dist/tool-kit.js +0 -1
  213. package/dist/tools/fundamentals/company-overview.d.ts +1 -1
  214. package/dist/tools/fundamentals/company-overview.js +2 -1
  215. package/dist/tools/fundamentals/comps.js +6 -4
  216. package/dist/tools/fundamentals/dcf.js +37 -9
  217. package/dist/tools/fundamentals/earnings.d.ts +1 -1
  218. package/dist/tools/fundamentals/earnings.js +2 -1
  219. package/dist/tools/fundamentals/financials.js +88 -9
  220. package/dist/tools/fundamentals/sec-filings.js +0 -1
  221. package/dist/tools/index.d.ts +121 -2
  222. package/dist/tools/index.js +3 -1
  223. package/dist/tools/interaction/ask-user.js +11 -1
  224. package/dist/tools/macro/event-probabilities.js +0 -1
  225. package/dist/tools/macro/fear-greed.d.ts +1 -1
  226. package/dist/tools/macro/fear-greed.js +0 -1
  227. package/dist/tools/macro/fred-data.d.ts +1 -1
  228. package/dist/tools/macro/fred-data.js +2 -1
  229. package/dist/tools/market/crypto-history.js +0 -1
  230. package/dist/tools/market/crypto-price.d.ts +2 -2
  231. package/dist/tools/market/crypto-price.js +0 -1
  232. package/dist/tools/market/price-comparison.d.ts +30 -0
  233. package/dist/tools/market/price-comparison.js +202 -0
  234. package/dist/tools/market/screen-stocks.js +0 -1
  235. package/dist/tools/market/search-ticker.js +1 -2
  236. package/dist/tools/market/stock-history.d.ts +18 -3
  237. package/dist/tools/market/stock-history.js +132 -18
  238. package/dist/tools/market/stock-quote.d.ts +2 -2
  239. package/dist/tools/market/stock-quote.js +0 -1
  240. package/dist/tools/options/greeks.js +0 -1
  241. package/dist/tools/options/option-chain.d.ts +2 -2
  242. package/dist/tools/options/option-chain.js +0 -1
  243. package/dist/tools/portfolio/alerts.d.ts +2 -1
  244. package/dist/tools/portfolio/alerts.js +228 -2
  245. package/dist/tools/portfolio/correlation.d.ts +1 -1
  246. package/dist/tools/portfolio/correlation.js +23 -5
  247. package/dist/tools/portfolio/daily-report.js +0 -1
  248. package/dist/tools/portfolio/holdings-overlap.js +0 -1
  249. package/dist/tools/portfolio/notifications.js +0 -1
  250. package/dist/tools/portfolio/risk-analysis.d.ts +2 -2
  251. package/dist/tools/portfolio/risk-analysis.js +0 -1
  252. package/dist/tools/portfolio/tracker.d.ts +3 -1
  253. package/dist/tools/portfolio/tracker.js +57 -10
  254. package/dist/tools/portfolio/watchlist.d.ts +3 -6
  255. package/dist/tools/portfolio/watchlist.js +101 -110
  256. package/dist/tools/sentiment/insight-format.js +0 -1
  257. package/dist/tools/sentiment/query-match.js +0 -1
  258. package/dist/tools/sentiment/reddit-sentiment.js +0 -1
  259. package/dist/tools/sentiment/sentiment-summary.js +8 -4
  260. package/dist/tools/sentiment/sentiment-trend.d.ts +5 -1
  261. package/dist/tools/sentiment/sentiment-trend.js +6 -2
  262. package/dist/tools/sentiment/twitter-sentiment.js +0 -1
  263. package/dist/tools/sentiment/untrusted-text.js +0 -1
  264. package/dist/tools/sentiment/web-search.d.ts +1 -1
  265. package/dist/tools/sentiment/web-search.js +0 -1
  266. package/dist/tools/sentiment/web-sentiment.js +0 -1
  267. package/dist/tools/technical/backtest.js +0 -1
  268. package/dist/tools/technical/indicators.js +0 -1
  269. package/dist/types/fundamentals.js +0 -1
  270. package/dist/types/index.js +0 -1
  271. package/dist/types/macro.js +0 -1
  272. package/dist/types/market.d.ts +8 -0
  273. package/dist/types/market.js +0 -1
  274. package/dist/types/options.js +0 -1
  275. package/dist/types/portfolio.js +0 -1
  276. package/dist/types/prediction-markets.js +0 -1
  277. package/dist/types/sentiment.js +0 -1
  278. package/dist/workflows/compare-assets.js +0 -1
  279. package/dist/workflows/index.js +0 -1
  280. package/dist/workflows/options-screener.js +0 -1
  281. package/dist/workflows/portfolio-builder.js +0 -1
  282. package/gui/web/dist/assets/CatalogOverlay-Cy8Fq0fn.js +1 -0
  283. package/gui/web/dist/assets/allocation-donut-DgBRIKCk.js +52 -0
  284. package/gui/web/dist/assets/index-DIlFyIOO.js +66 -0
  285. package/gui/web/dist/assets/index-DS4jESOB.css +2 -0
  286. package/gui/web/dist/assets/market-chart-DammaCjH.js +1 -0
  287. package/gui/web/dist/assets/utils-CnADgYgh.js +1 -0
  288. package/gui/web/dist/index.html +3 -2
  289. package/package.json +23 -26
  290. package/dist/analysts/contracts.js.map +0 -1
  291. package/dist/analysts/orchestrator.js.map +0 -1
  292. package/dist/cli-main.js.map +0 -1
  293. package/dist/cli.js.map +0 -1
  294. package/dist/config.js.map +0 -1
  295. package/dist/doctor/cli-command.js.map +0 -1
  296. package/dist/doctor/render.js.map +0 -1
  297. package/dist/doctor/report.js.map +0 -1
  298. package/dist/index.js.map +0 -1
  299. package/dist/infra/cache.js.map +0 -1
  300. package/dist/infra/freshness.js.map +0 -1
  301. package/dist/infra/http-client.js.map +0 -1
  302. package/dist/infra/index.js.map +0 -1
  303. package/dist/infra/market-calendar.js.map +0 -1
  304. package/dist/infra/native-dependencies.js.map +0 -1
  305. package/dist/infra/node-version.js.map +0 -1
  306. package/dist/infra/open-url.js.map +0 -1
  307. package/dist/infra/opencandle-paths.js.map +0 -1
  308. package/dist/infra/rate-limiter.js.map +0 -1
  309. package/dist/market-state/alert-conditions.js.map +0 -1
  310. package/dist/market-state/alert-runner.js.map +0 -1
  311. package/dist/market-state/daily-report.js.map +0 -1
  312. package/dist/market-state/local-automation-service.js.map +0 -1
  313. package/dist/market-state/notification-delivery.js.map +0 -1
  314. package/dist/market-state/resolve-for-mutation.js.map +0 -1
  315. package/dist/market-state/resolve.js.map +0 -1
  316. package/dist/market-state/service.js.map +0 -1
  317. package/dist/market-state/summaries.js.map +0 -1
  318. package/dist/memory/index.js.map +0 -1
  319. package/dist/memory/manager.js.map +0 -1
  320. package/dist/memory/preference-extractor.js.map +0 -1
  321. package/dist/memory/retrieval.js.map +0 -1
  322. package/dist/memory/sqlite.js.map +0 -1
  323. package/dist/memory/storage.js.map +0 -1
  324. package/dist/memory/tool-defaults.js.map +0 -1
  325. package/dist/memory/types.js.map +0 -1
  326. package/dist/monitor.js.map +0 -1
  327. package/dist/onboarding/connect.js.map +0 -1
  328. package/dist/onboarding/credential-interceptor.js.map +0 -1
  329. package/dist/onboarding/degradation-accumulator.js.map +0 -1
  330. package/dist/onboarding/prompt-user.js.map +0 -1
  331. package/dist/onboarding/provider-status.js.map +0 -1
  332. package/dist/onboarding/providers.js.map +0 -1
  333. package/dist/onboarding/state.js.map +0 -1
  334. package/dist/onboarding/tool-helpers.js.map +0 -1
  335. package/dist/onboarding/tool-tags.js.map +0 -1
  336. package/dist/onboarding/validation.js.map +0 -1
  337. package/dist/pi/opencandle-extension.js.map +0 -1
  338. package/dist/pi/session-action-dedupe.js.map +0 -1
  339. package/dist/pi/session-storage.js.map +0 -1
  340. package/dist/pi/session-writer-lock.js.map +0 -1
  341. package/dist/pi/session.js.map +0 -1
  342. package/dist/pi/setup.js.map +0 -1
  343. package/dist/pi/tool-adapter.js.map +0 -1
  344. package/dist/pi/tui-session-coordinator.js.map +0 -1
  345. package/dist/prompts/context-builder.js.map +0 -1
  346. package/dist/prompts/disclaimer.js.map +0 -1
  347. package/dist/prompts/policy-cards.js.map +0 -1
  348. package/dist/prompts/sections.js.map +0 -1
  349. package/dist/prompts/symbol-preflight.js.map +0 -1
  350. package/dist/prompts/workflow-prompts.js.map +0 -1
  351. package/dist/providers/alpha-vantage.js.map +0 -1
  352. package/dist/providers/coingecko.js.map +0 -1
  353. package/dist/providers/errors.js.map +0 -1
  354. package/dist/providers/exa-search.js.map +0 -1
  355. package/dist/providers/external-tool-command.js.map +0 -1
  356. package/dist/providers/external-tool-error.js.map +0 -1
  357. package/dist/providers/fear-greed.js.map +0 -1
  358. package/dist/providers/finnhub.js.map +0 -1
  359. package/dist/providers/fred.js.map +0 -1
  360. package/dist/providers/index.js.map +0 -1
  361. package/dist/providers/polymarket.js.map +0 -1
  362. package/dist/providers/provider-credential-error.js.map +0 -1
  363. package/dist/providers/reddit-cli.js.map +0 -1
  364. package/dist/providers/reddit.js.map +0 -1
  365. package/dist/providers/sec-edgar.js.map +0 -1
  366. package/dist/providers/tradingview.js.map +0 -1
  367. package/dist/providers/twitter-cli.js.map +0 -1
  368. package/dist/providers/twitter.js.map +0 -1
  369. package/dist/providers/web-search.js.map +0 -1
  370. package/dist/providers/with-fallback.js.map +0 -1
  371. package/dist/providers/wrap-provider.js.map +0 -1
  372. package/dist/providers/yahoo-finance.js.map +0 -1
  373. package/dist/routing/classify-intent.js.map +0 -1
  374. package/dist/routing/defaults.js.map +0 -1
  375. package/dist/routing/entity-extractor.js.map +0 -1
  376. package/dist/routing/fund-symbols.js.map +0 -1
  377. package/dist/routing/horizon.js.map +0 -1
  378. package/dist/routing/index.js.map +0 -1
  379. package/dist/routing/legacy-rule-router.js.map +0 -1
  380. package/dist/routing/planning.js.map +0 -1
  381. package/dist/routing/route-manifest.js.map +0 -1
  382. package/dist/routing/router-llm-client.js.map +0 -1
  383. package/dist/routing/router-prompt.js.map +0 -1
  384. package/dist/routing/router-types.js.map +0 -1
  385. package/dist/routing/router.js.map +0 -1
  386. package/dist/routing/slot-resolver.js.map +0 -1
  387. package/dist/routing/symbol-disambiguator.js.map +0 -1
  388. package/dist/routing/turn-context.js.map +0 -1
  389. package/dist/routing/types.js.map +0 -1
  390. package/dist/runtime/answer-contracts.js.map +0 -1
  391. package/dist/runtime/artifact-contracts.js.map +0 -1
  392. package/dist/runtime/evidence.js.map +0 -1
  393. package/dist/runtime/numeric-claims.js.map +0 -1
  394. package/dist/runtime/planning-evidence.js.map +0 -1
  395. package/dist/runtime/prompt-step.js.map +0 -1
  396. package/dist/runtime/provider-tracker.js.map +0 -1
  397. package/dist/runtime/run-context.js.map +0 -1
  398. package/dist/runtime/session-coordinator.js.map +0 -1
  399. package/dist/runtime/session-title.js.map +0 -1
  400. package/dist/runtime/tool-defaults-wrapper.js.map +0 -1
  401. package/dist/runtime/validation.js.map +0 -1
  402. package/dist/runtime/workflow-events.js.map +0 -1
  403. package/dist/runtime/workflow-runner.js.map +0 -1
  404. package/dist/runtime/workflow-types.js.map +0 -1
  405. package/dist/sentiment/adapters/finnhub.js.map +0 -1
  406. package/dist/sentiment/adapters/reddit.js.map +0 -1
  407. package/dist/sentiment/adapters/twitter.js.map +0 -1
  408. package/dist/sentiment/adapters/web.js.map +0 -1
  409. package/dist/sentiment/index.js.map +0 -1
  410. package/dist/sentiment/insights.js.map +0 -1
  411. package/dist/sentiment/keywords.js.map +0 -1
  412. package/dist/sentiment/pipeline.js.map +0 -1
  413. package/dist/sentiment/scorer.js.map +0 -1
  414. package/dist/sentiment/store.js.map +0 -1
  415. package/dist/sentiment/trends.js.map +0 -1
  416. package/dist/sentiment/types.js.map +0 -1
  417. package/dist/system-prompt.js.map +0 -1
  418. package/dist/tool-kit.js.map +0 -1
  419. package/dist/tools/fundamentals/company-overview.js.map +0 -1
  420. package/dist/tools/fundamentals/comps.js.map +0 -1
  421. package/dist/tools/fundamentals/dcf.js.map +0 -1
  422. package/dist/tools/fundamentals/earnings.js.map +0 -1
  423. package/dist/tools/fundamentals/financials.js.map +0 -1
  424. package/dist/tools/fundamentals/sec-filings.js.map +0 -1
  425. package/dist/tools/index.js.map +0 -1
  426. package/dist/tools/interaction/ask-user.js.map +0 -1
  427. package/dist/tools/macro/event-probabilities.js.map +0 -1
  428. package/dist/tools/macro/fear-greed.js.map +0 -1
  429. package/dist/tools/macro/fred-data.js.map +0 -1
  430. package/dist/tools/market/crypto-history.js.map +0 -1
  431. package/dist/tools/market/crypto-price.js.map +0 -1
  432. package/dist/tools/market/screen-stocks.js.map +0 -1
  433. package/dist/tools/market/search-ticker.js.map +0 -1
  434. package/dist/tools/market/stock-history.js.map +0 -1
  435. package/dist/tools/market/stock-quote.js.map +0 -1
  436. package/dist/tools/options/greeks.js.map +0 -1
  437. package/dist/tools/options/option-chain.js.map +0 -1
  438. package/dist/tools/portfolio/alerts.js.map +0 -1
  439. package/dist/tools/portfolio/correlation.js.map +0 -1
  440. package/dist/tools/portfolio/daily-report.js.map +0 -1
  441. package/dist/tools/portfolio/holdings-overlap.js.map +0 -1
  442. package/dist/tools/portfolio/notifications.js.map +0 -1
  443. package/dist/tools/portfolio/risk-analysis.js.map +0 -1
  444. package/dist/tools/portfolio/tracker.js.map +0 -1
  445. package/dist/tools/portfolio/watchlist.js.map +0 -1
  446. package/dist/tools/sentiment/insight-format.js.map +0 -1
  447. package/dist/tools/sentiment/query-match.js.map +0 -1
  448. package/dist/tools/sentiment/reddit-sentiment.js.map +0 -1
  449. package/dist/tools/sentiment/sentiment-summary.js.map +0 -1
  450. package/dist/tools/sentiment/sentiment-trend.js.map +0 -1
  451. package/dist/tools/sentiment/twitter-sentiment.js.map +0 -1
  452. package/dist/tools/sentiment/untrusted-text.js.map +0 -1
  453. package/dist/tools/sentiment/web-search.js.map +0 -1
  454. package/dist/tools/sentiment/web-sentiment.js.map +0 -1
  455. package/dist/tools/technical/backtest.js.map +0 -1
  456. package/dist/tools/technical/indicators.js.map +0 -1
  457. package/dist/types/fundamentals.js.map +0 -1
  458. package/dist/types/index.js.map +0 -1
  459. package/dist/types/macro.js.map +0 -1
  460. package/dist/types/market.js.map +0 -1
  461. package/dist/types/options.js.map +0 -1
  462. package/dist/types/portfolio.js.map +0 -1
  463. package/dist/types/prediction-markets.js.map +0 -1
  464. package/dist/types/sentiment.js.map +0 -1
  465. package/dist/workflows/compare-assets.js.map +0 -1
  466. package/dist/workflows/index.js.map +0 -1
  467. package/dist/workflows/options-screener.js.map +0 -1
  468. package/dist/workflows/portfolio-builder.js.map +0 -1
  469. package/gui/server/ask-user-bridge.ts +0 -89
  470. package/gui/server/automation-heartbeat.ts +0 -97
  471. package/gui/server/background-quotes.ts +0 -127
  472. package/gui/server/chat-event-adapter.ts +0 -294
  473. package/gui/server/gui-session-manager.ts +0 -5
  474. package/gui/server/http-routes.ts +0 -1201
  475. package/gui/server/invoke-tool.ts +0 -490
  476. package/gui/server/live-chat-event-adapter.ts +0 -243
  477. package/gui/server/local-session-coordinator.ts +0 -97
  478. package/gui/server/market-state-api.ts +0 -331
  479. package/gui/server/model-setup.ts +0 -254
  480. package/gui/server/package.json +0 -5
  481. package/gui/server/private-api-access.ts +0 -62
  482. package/gui/server/projector.ts +0 -392
  483. package/gui/server/prompt-observation.ts +0 -58
  484. package/gui/server/quote-snapshot-store.ts +0 -50
  485. package/gui/server/server.ts +0 -289
  486. package/gui/server/session-actions.ts +0 -323
  487. package/gui/server/session-entry-wait.ts +0 -179
  488. package/gui/server/shutdown.ts +0 -47
  489. package/gui/server/tool-invoke-ack.ts +0 -49
  490. package/gui/server/tool-metadata.ts +0 -167
  491. package/gui/server/websocket.ts +0 -138
  492. package/gui/server/writer-lock.ts +0 -1
  493. package/gui/server/ws-hub.ts +0 -403
  494. package/gui/shared/chat-events.ts +0 -165
  495. package/gui/shared/event-reducer.ts +0 -220
  496. package/gui/web/dist/assets/CatalogOverlay-DZ1niyQm.js +0 -1
  497. package/gui/web/dist/assets/index-D4F9AJnn.css +0 -2
  498. package/gui/web/dist/assets/index-DtqMMBTr.js +0 -65
  499. package/src/analysts/contracts.ts +0 -176
  500. package/src/analysts/orchestrator.ts +0 -244
  501. package/src/cli-main.ts +0 -510
  502. package/src/cli.ts +0 -17
  503. package/src/config.ts +0 -272
  504. package/src/doctor/cli-command.ts +0 -83
  505. package/src/doctor/render.ts +0 -37
  506. package/src/doctor/report.ts +0 -638
  507. package/src/index.ts +0 -5
  508. package/src/infra/cache.ts +0 -127
  509. package/src/infra/freshness.ts +0 -165
  510. package/src/infra/http-client.ts +0 -134
  511. package/src/infra/index.ts +0 -14
  512. package/src/infra/market-calendar.ts +0 -193
  513. package/src/infra/native-dependencies.ts +0 -84
  514. package/src/infra/node-version.ts +0 -23
  515. package/src/infra/open-url.ts +0 -28
  516. package/src/infra/opencandle-paths.ts +0 -53
  517. package/src/infra/rate-limiter.ts +0 -77
  518. package/src/market-state/alert-conditions.ts +0 -82
  519. package/src/market-state/alert-runner.ts +0 -863
  520. package/src/market-state/daily-report.ts +0 -237
  521. package/src/market-state/local-automation-service.ts +0 -162
  522. package/src/market-state/notification-delivery.ts +0 -158
  523. package/src/market-state/resolve-for-mutation.ts +0 -24
  524. package/src/market-state/resolve.ts +0 -112
  525. package/src/market-state/service.ts +0 -2208
  526. package/src/market-state/summaries.ts +0 -75
  527. package/src/memory/index.ts +0 -10
  528. package/src/memory/manager.ts +0 -190
  529. package/src/memory/preference-extractor.ts +0 -106
  530. package/src/memory/retrieval.ts +0 -71
  531. package/src/memory/sqlite.ts +0 -577
  532. package/src/memory/storage.ts +0 -195
  533. package/src/memory/tool-defaults.ts +0 -108
  534. package/src/memory/types.ts +0 -71
  535. package/src/monitor.ts +0 -123
  536. package/src/onboarding/connect.ts +0 -177
  537. package/src/onboarding/credential-interceptor.ts +0 -122
  538. package/src/onboarding/degradation-accumulator.ts +0 -77
  539. package/src/onboarding/prompt-user.ts +0 -85
  540. package/src/onboarding/provider-status.ts +0 -382
  541. package/src/onboarding/providers.ts +0 -442
  542. package/src/onboarding/state.ts +0 -216
  543. package/src/onboarding/tool-helpers.ts +0 -104
  544. package/src/onboarding/tool-tags.ts +0 -244
  545. package/src/onboarding/validation.ts +0 -152
  546. package/src/pi/opencandle-extension.ts +0 -1294
  547. package/src/pi/session-action-dedupe.ts +0 -155
  548. package/src/pi/session-storage.ts +0 -5
  549. package/src/pi/session-writer-lock.ts +0 -426
  550. package/src/pi/session.ts +0 -84
  551. package/src/pi/setup.ts +0 -399
  552. package/src/pi/tool-adapter.ts +0 -49
  553. package/src/pi/tui-session-coordinator.ts +0 -351
  554. package/src/prompts/context-builder.ts +0 -326
  555. package/src/prompts/disclaimer.ts +0 -9
  556. package/src/prompts/policy-cards.ts +0 -228
  557. package/src/prompts/sections.ts +0 -46
  558. package/src/prompts/symbol-preflight.ts +0 -80
  559. package/src/prompts/workflow-prompts.ts +0 -504
  560. package/src/providers/alpha-vantage.ts +0 -340
  561. package/src/providers/coingecko.ts +0 -95
  562. package/src/providers/errors.ts +0 -9
  563. package/src/providers/exa-search.ts +0 -375
  564. package/src/providers/external-tool-command.ts +0 -164
  565. package/src/providers/external-tool-error.ts +0 -20
  566. package/src/providers/fear-greed.ts +0 -45
  567. package/src/providers/finnhub.ts +0 -125
  568. package/src/providers/fred.ts +0 -83
  569. package/src/providers/index.ts +0 -17
  570. package/src/providers/polymarket.ts +0 -214
  571. package/src/providers/provider-credential-error.ts +0 -23
  572. package/src/providers/reddit-cli.ts +0 -286
  573. package/src/providers/reddit.ts +0 -106
  574. package/src/providers/sec-edgar.ts +0 -326
  575. package/src/providers/tradingview.ts +0 -399
  576. package/src/providers/twitter-cli.ts +0 -202
  577. package/src/providers/twitter.ts +0 -102
  578. package/src/providers/web-search.ts +0 -303
  579. package/src/providers/with-fallback.ts +0 -42
  580. package/src/providers/wrap-provider.ts +0 -105
  581. package/src/providers/yahoo-finance.ts +0 -984
  582. package/src/routing/classify-intent.ts +0 -380
  583. package/src/routing/defaults.ts +0 -29
  584. package/src/routing/entity-extractor.ts +0 -557
  585. package/src/routing/fund-symbols.ts +0 -58
  586. package/src/routing/horizon.ts +0 -7
  587. package/src/routing/index.ts +0 -70
  588. package/src/routing/legacy-rule-router.ts +0 -13
  589. package/src/routing/planning.ts +0 -829
  590. package/src/routing/route-manifest.ts +0 -308
  591. package/src/routing/router-llm-client.ts +0 -64
  592. package/src/routing/router-prompt.ts +0 -159
  593. package/src/routing/router-types.ts +0 -84
  594. package/src/routing/router.ts +0 -1332
  595. package/src/routing/slot-resolver.ts +0 -213
  596. package/src/routing/symbol-disambiguator.ts +0 -72
  597. package/src/routing/turn-context.ts +0 -108
  598. package/src/routing/types.ts +0 -77
  599. package/src/runtime/answer-contracts.ts +0 -693
  600. package/src/runtime/artifact-contracts.ts +0 -77
  601. package/src/runtime/evidence.ts +0 -78
  602. package/src/runtime/numeric-claims.ts +0 -108
  603. package/src/runtime/planning-evidence.ts +0 -597
  604. package/src/runtime/prompt-step.ts +0 -185
  605. package/src/runtime/provider-tracker.ts +0 -40
  606. package/src/runtime/run-context.ts +0 -32
  607. package/src/runtime/session-coordinator.ts +0 -1037
  608. package/src/runtime/session-title.ts +0 -60
  609. package/src/runtime/tool-defaults-wrapper.ts +0 -43
  610. package/src/runtime/validation.ts +0 -211
  611. package/src/runtime/workflow-events.ts +0 -77
  612. package/src/runtime/workflow-runner.ts +0 -182
  613. package/src/runtime/workflow-types.ts +0 -105
  614. package/src/sentiment/adapters/finnhub.ts +0 -49
  615. package/src/sentiment/adapters/reddit.ts +0 -65
  616. package/src/sentiment/adapters/twitter.ts +0 -36
  617. package/src/sentiment/adapters/web.ts +0 -44
  618. package/src/sentiment/index.ts +0 -49
  619. package/src/sentiment/insights.ts +0 -269
  620. package/src/sentiment/keywords.ts +0 -31
  621. package/src/sentiment/pipeline.ts +0 -91
  622. package/src/sentiment/scorer.ts +0 -89
  623. package/src/sentiment/store.ts +0 -260
  624. package/src/sentiment/trends.ts +0 -96
  625. package/src/sentiment/types.ts +0 -112
  626. package/src/system-prompt.ts +0 -115
  627. package/src/tool-kit.ts +0 -69
  628. package/src/tools/AGENTS.md +0 -36
  629. package/src/tools/fundamentals/company-overview.ts +0 -64
  630. package/src/tools/fundamentals/comps.ts +0 -180
  631. package/src/tools/fundamentals/dcf.ts +0 -447
  632. package/src/tools/fundamentals/earnings.ts +0 -57
  633. package/src/tools/fundamentals/financials.ts +0 -63
  634. package/src/tools/fundamentals/sec-filings.ts +0 -105
  635. package/src/tools/index.ts +0 -104
  636. package/src/tools/interaction/ask-user.ts +0 -93
  637. package/src/tools/macro/event-probabilities.ts +0 -141
  638. package/src/tools/macro/fear-greed.ts +0 -41
  639. package/src/tools/macro/fred-data.ts +0 -92
  640. package/src/tools/market/crypto-history.ts +0 -72
  641. package/src/tools/market/crypto-price.ts +0 -65
  642. package/src/tools/market/screen-stocks.ts +0 -290
  643. package/src/tools/market/search-ticker.ts +0 -254
  644. package/src/tools/market/stock-history.ts +0 -104
  645. package/src/tools/market/stock-quote.ts +0 -73
  646. package/src/tools/options/greeks.ts +0 -81
  647. package/src/tools/options/option-chain.ts +0 -134
  648. package/src/tools/portfolio/alerts.ts +0 -457
  649. package/src/tools/portfolio/correlation.ts +0 -189
  650. package/src/tools/portfolio/daily-report.ts +0 -107
  651. package/src/tools/portfolio/holdings-overlap.ts +0 -139
  652. package/src/tools/portfolio/notifications.ts +0 -45
  653. package/src/tools/portfolio/risk-analysis.ts +0 -173
  654. package/src/tools/portfolio/tracker.ts +0 -308
  655. package/src/tools/portfolio/watchlist.ts +0 -288
  656. package/src/tools/sentiment/insight-format.ts +0 -50
  657. package/src/tools/sentiment/query-match.ts +0 -117
  658. package/src/tools/sentiment/reddit-sentiment.ts +0 -403
  659. package/src/tools/sentiment/sentiment-summary.ts +0 -383
  660. package/src/tools/sentiment/sentiment-trend.ts +0 -75
  661. package/src/tools/sentiment/twitter-sentiment.ts +0 -287
  662. package/src/tools/sentiment/untrusted-text.ts +0 -21
  663. package/src/tools/sentiment/web-search.ts +0 -186
  664. package/src/tools/sentiment/web-sentiment.ts +0 -96
  665. package/src/tools/technical/backtest.ts +0 -336
  666. package/src/tools/technical/indicators.ts +0 -281
  667. package/src/types/fundamentals.ts +0 -47
  668. package/src/types/index.ts +0 -26
  669. package/src/types/macro.ts +0 -27
  670. package/src/types/market.ts +0 -46
  671. package/src/types/options.ts +0 -53
  672. package/src/types/portfolio.ts +0 -83
  673. package/src/types/prediction-markets.ts +0 -13
  674. package/src/types/sentiment.ts +0 -129
  675. package/src/workflows/compare-assets.ts +0 -89
  676. package/src/workflows/index.ts +0 -3
  677. package/src/workflows/options-screener.ts +0 -125
  678. package/src/workflows/portfolio-builder.ts +0 -63
@@ -1,336 +0,0 @@
1
- import type { AgentTool } from "@earendil-works/pi-agent-core";
2
- import { Type } from "@sinclair/typebox";
3
- import { wrapProvider } from "../../providers/wrap-provider.js";
4
- import { getHistory } from "../../providers/yahoo-finance.js";
5
- import type { OHLCV } from "../../types/market.js";
6
- import { computeRSI, computeSMA } from "./indicators.js";
7
-
8
- export type Strategy = "sma_crossover" | "sma_50_200_crossover" | "rsi_mean_reversion";
9
-
10
- /** Flat per-side transaction cost assumption, in basis points. */
11
- export const DEFAULT_COST_BPS = 5;
12
-
13
- /** What this simulator deliberately does not model. Rendered in tool output. */
14
- export const BACKTEST_LIMITATIONS = [
15
- "Fills are simulated at the next bar's open after a signal; intrabar moves and gaps beyond that open are not modeled",
16
- "Only a flat per-side cost is applied — no slippage model, spreads, or market impact",
17
- "Dividends, taxes, and financing costs are excluded",
18
- "Liquidity is assumed unlimited at the fill price",
19
- ];
20
-
21
- export interface BacktestOptions {
22
- /** Flat per-side cost in basis points applied to every fill. */
23
- costBps?: number;
24
- }
25
-
26
- export interface BacktestTrade {
27
- type: "buy" | "sell";
28
- date: string;
29
- price: number;
30
- pnl?: number;
31
- forced?: boolean;
32
- }
33
-
34
- export interface BacktestResult {
35
- strategy: string;
36
- totalReturn: number;
37
- buyAndHoldReturn: number;
38
- trades: number;
39
- forcedClosures: number;
40
- wins: number;
41
- winRate: number;
42
- maxDrawdown: number;
43
- costBpsPerSide: number;
44
- /** Signal generated on the final bar that has no next open to fill at. */
45
- pendingSignal: { type: "buy" | "sell"; date: string } | null;
46
- tradeLog: BacktestTrade[];
47
- }
48
-
49
- type Signal = "enter" | "exit" | null;
50
-
51
- export function runBacktest(
52
- bars: OHLCV[],
53
- strategy: Strategy,
54
- options?: BacktestOptions,
55
- ): BacktestResult {
56
- const closes = bars.map((b) => b.close);
57
- const costBps = options?.costBps ?? DEFAULT_COST_BPS;
58
-
59
- if (strategy === "sma_crossover" || strategy === "sma_50_200_crossover") {
60
- const [shortWindow, longWindow] = strategy === "sma_crossover" ? [20, 50] : [50, 200];
61
- const shortSma = computeSMA(closes, shortWindow);
62
- const longSma = computeSMA(closes, longWindow);
63
- if (longSma.length === 0) {
64
- return emptyResult(strategy, closes, costBps);
65
- }
66
- const signalAt = (barIdx: number): Signal => {
67
- const sShort = shortSma[barIdx - (shortWindow - 1)];
68
- const sLong = longSma[barIdx - (longWindow - 1)];
69
- if (sShort > sLong) return "enter";
70
- if (sShort < sLong) return "exit";
71
- return null;
72
- };
73
- return simulate(bars, closes, signalAt, longWindow - 1, strategy, costBps);
74
- }
75
-
76
- const rsi = computeRSI(closes, 14);
77
- if (rsi.length === 0) {
78
- return emptyResult("rsi_mean_reversion", closes, costBps);
79
- }
80
- const rsiOffset = 14;
81
- const signalAt = (barIdx: number): Signal => {
82
- const r = rsi[barIdx - rsiOffset];
83
- if (r < 30) return "enter";
84
- if (r > 70) return "exit";
85
- return null;
86
- };
87
- return simulate(bars, closes, signalAt, rsiOffset, "rsi_mean_reversion", costBps);
88
- }
89
-
90
- // Shared fill engine: a signal computed from bar N's close fills at bar N+1's
91
- // open (no same-bar lookahead), with a flat per-side cost on every fill. A
92
- // signal on the final bar is reported as pending instead of a phantom trade.
93
- function simulate(
94
- bars: OHLCV[],
95
- closes: number[],
96
- signalAt: (barIdx: number) => Signal,
97
- startIdx: number,
98
- strategyName: Strategy,
99
- costBps: number,
100
- ): BacktestResult {
101
- const cost = costBps / 10_000;
102
- let position = false;
103
- let entryFill = 0;
104
- let pendingAction: Signal = null;
105
- let pendingSignal: BacktestResult["pendingSignal"] = null;
106
- const tradeLog: BacktestResult["tradeLog"] = [];
107
- let equity = 1.0;
108
- let peak = 1.0;
109
- let maxDd = 0;
110
-
111
- for (let i = startIdx; i < bars.length; i++) {
112
- // Execute the previous bar's signal at this bar's open.
113
- if (pendingAction === "enter" && !position) {
114
- const fillPrice = bars[i].open;
115
- if (fillPrice > 0) {
116
- position = true;
117
- entryFill = fillPrice * (1 + cost);
118
- tradeLog.push({ type: "buy", date: bars[i].date, price: fillPrice });
119
- }
120
- } else if (pendingAction === "exit" && position) {
121
- const fillPrice = bars[i].open;
122
- if (fillPrice > 0 && entryFill > 0) {
123
- const pnl = (fillPrice * (1 - cost) - entryFill) / entryFill;
124
- equity *= 1 + pnl;
125
- tradeLog.push({ type: "sell", date: bars[i].date, price: fillPrice, pnl });
126
- position = false;
127
- }
128
- }
129
- pendingAction = null;
130
-
131
- // Evaluate the signal at this bar's close.
132
- const signal = signalAt(i);
133
- if ((signal === "enter" && !position) || (signal === "exit" && position)) {
134
- if (i + 1 >= bars.length) {
135
- pendingSignal = { type: signal === "enter" ? "buy" : "sell", date: bars[i].date };
136
- } else {
137
- pendingAction = signal;
138
- }
139
- }
140
-
141
- // Track mark-to-market equity for accurate drawdown.
142
- const price = closes[i];
143
- const currentEquity =
144
- position && entryFill > 0 && price > 0
145
- ? equity * (1 + (price - entryFill) / entryFill)
146
- : equity;
147
- if (currentEquity > peak) peak = currentEquity;
148
- const dd = (peak - currentEquity) / peak;
149
- if (dd > maxDd) maxDd = dd;
150
- }
151
-
152
- // Close any open position at the final close for reporting.
153
- if (position && entryFill > 0) {
154
- const lastPrice = closes[closes.length - 1];
155
- if (lastPrice > 0) {
156
- const pnl = (lastPrice * (1 - cost) - entryFill) / entryFill;
157
- equity *= 1 + pnl;
158
- tradeLog.push({
159
- type: "sell",
160
- date: bars[bars.length - 1].date,
161
- price: lastPrice,
162
- pnl,
163
- forced: true,
164
- });
165
- }
166
- }
167
-
168
- return buildResult(strategyName, equity - 1, closes, tradeLog, maxDd, costBps, pendingSignal);
169
- }
170
-
171
- function buildResult(
172
- strategy: string,
173
- totalReturn: number,
174
- closes: number[],
175
- tradeLog: BacktestResult["tradeLog"],
176
- maxDrawdown: number,
177
- costBpsPerSide: number,
178
- pendingSignal: BacktestResult["pendingSignal"],
179
- ): BacktestResult {
180
- const sellTrades = tradeLog.filter(
181
- (t): t is BacktestTrade & { type: "sell"; pnl: number } =>
182
- t.type === "sell" && t.pnl != null && !t.forced,
183
- );
184
- const forcedClosures = tradeLog.filter((t) => t.type === "sell" && t.forced).length;
185
- const wins = sellTrades.filter((t) => t.pnl > 0).length;
186
- const buyAndHoldReturn =
187
- closes.length > 1 && closes[0] > 0 ? (closes[closes.length - 1] - closes[0]) / closes[0] : 0;
188
-
189
- return {
190
- strategy,
191
- totalReturn,
192
- buyAndHoldReturn,
193
- trades: sellTrades.length,
194
- forcedClosures,
195
- wins,
196
- winRate: sellTrades.length > 0 ? wins / sellTrades.length : 0,
197
- maxDrawdown,
198
- costBpsPerSide,
199
- pendingSignal,
200
- tradeLog,
201
- };
202
- }
203
-
204
- function emptyResult(strategy: string, closes: number[], costBpsPerSide: number): BacktestResult {
205
- return {
206
- strategy,
207
- totalReturn: 0,
208
- buyAndHoldReturn:
209
- closes.length > 1 && closes[0] > 0 ? (closes[closes.length - 1] - closes[0]) / closes[0] : 0,
210
- trades: 0,
211
- forcedClosures: 0,
212
- wins: 0,
213
- winRate: 0,
214
- maxDrawdown: 0,
215
- costBpsPerSide,
216
- pendingSignal: null,
217
- tradeLog: [],
218
- };
219
- }
220
-
221
- const params = Type.Object({
222
- symbol: Type.String({ description: "Stock ticker symbol (e.g. AAPL, MSFT, SPY)" }),
223
- strategy: Type.Union(
224
- [
225
- Type.Literal("sma_crossover"),
226
- Type.Literal("sma_50_200_crossover"),
227
- Type.Literal("rsi_mean_reversion"),
228
- ],
229
- {
230
- description:
231
- "Strategy: sma_crossover (buy when SMA20 > SMA50, sell on reverse), sma_50_200_crossover (buy when SMA50 > SMA200, sell on reverse), or rsi_mean_reversion (buy when RSI < 30, sell when RSI > 70)",
232
- },
233
- ),
234
- period: Type.Optional(
235
- Type.Union([Type.Literal("1y"), Type.Literal("2y"), Type.Literal("5y")], {
236
- description: "Historical period to backtest: 1y, 2y, 5y. Default: 2y",
237
- }),
238
- ),
239
- cost_bps: Type.Optional(
240
- Type.Number({
241
- minimum: 0,
242
- maximum: 100,
243
- description: `Flat per-side transaction cost in basis points applied to every fill. Default: ${DEFAULT_COST_BPS}`,
244
- }),
245
- ),
246
- });
247
-
248
- export const backtestTool: AgentTool<typeof params> = {
249
- name: "backtest_strategy",
250
- label: "Backtest Strategy",
251
- description:
252
- "Replay a simple trading strategy against historical daily bars. Signals fill at the next bar's open with a flat per-side cost assumption; dividends, taxes, slippage beyond that cost, and liquidity are not modeled. Supported strategies: SMA crossover (SMA20/SMA50), standard long-term SMA crossover (SMA50/SMA200), and RSI mean-reversion (buy <30, sell >70). Returns total return, win rate, max drawdown, and comparison to buy-and-hold.",
253
- parameters: params,
254
- async execute(_toolCallId, args) {
255
- const symbol = args.symbol.toUpperCase();
256
- const period = args.period ?? "2y";
257
- const historyResult = await wrapProvider("yahoo", () => getHistory(symbol, period, "1d"));
258
- if (historyResult.status === "unavailable") {
259
- return {
260
- content: [
261
- { type: "text", text: `⚠ Backtest unavailable for ${symbol} (${historyResult.reason}).` },
262
- ],
263
- details: null as any,
264
- };
265
- }
266
- const bars = historyResult.data;
267
-
268
- const minBars = requiredBarsForStrategy(args.strategy);
269
- if (bars.length < minBars) {
270
- return {
271
- content: [
272
- {
273
- type: "text",
274
- text: `Insufficient data for backtesting ${symbol} (need ${minBars}+ days, got ${bars.length})`,
275
- },
276
- ],
277
- details: null,
278
- };
279
- }
280
-
281
- const costBps = args.cost_bps ?? DEFAULT_COST_BPS;
282
- const result = runBacktest(bars, args.strategy, { costBps });
283
-
284
- const outperformance = result.totalReturn - result.buyAndHoldReturn;
285
- const lines = [
286
- `**${symbol} Backtest: ${strategyLabel(args.strategy)}** (${bars[0].date} to ${bars[bars.length - 1].date}, ${bars.length} days)`,
287
- ``,
288
- `Strategy Return (net of costs): ${(result.totalReturn * 100).toFixed(2)}%`,
289
- `Buy & Hold Return (gross): ${(result.buyAndHoldReturn * 100).toFixed(2)}%`,
290
- `Outperformance: ${outperformance >= 0 ? "+" : ""}${(outperformance * 100).toFixed(2)}%`,
291
- ``,
292
- `Signal Trades: ${result.trades} | Forced Closures: ${result.forcedClosures} | Wins: ${result.wins} | Win Rate: ${(result.winRate * 100).toFixed(0)}%`,
293
- `Max Drawdown: ${(result.maxDrawdown * 100).toFixed(2)}%`,
294
- ``,
295
- `Execution assumptions: signals fill at the next bar's open with a flat cost of ${costBps} bps per side.`,
296
- ...(result.pendingSignal
297
- ? [
298
- `Note: a ${result.pendingSignal.type} signal fired on the final bar (${result.pendingSignal.date}) and is pending — it has no next open to fill at and is not counted as a signal trade.`,
299
- ]
300
- : []),
301
- ...(result.forcedClosures > 0
302
- ? [
303
- `Note: ${result.forcedClosures} open position${result.forcedClosures === 1 ? " was" : "s were"} liquidated at the final close for return reporting; forced closures are not counted as signal trades.`,
304
- ]
305
- : []),
306
- ``,
307
- result.totalReturn > result.buyAndHoldReturn
308
- ? `In this simulation the strategy outperformed buy-and-hold by ${(outperformance * 100).toFixed(2)}%.`
309
- : `In this simulation buy-and-hold outperformed the strategy by ${(-outperformance * 100).toFixed(2)}%.`,
310
- ``,
311
- `Limitations — this is a strategy replay, not an execution simulation:`,
312
- ...BACKTEST_LIMITATIONS.map((limit) => `- ${limit}`),
313
- ];
314
-
315
- return {
316
- content: [{ type: "text", text: lines.join("\n") }],
317
- details: result,
318
- };
319
- },
320
- };
321
-
322
- function requiredBarsForStrategy(strategy: Strategy): number {
323
- if (strategy === "sma_50_200_crossover") return 200;
324
- return 60;
325
- }
326
-
327
- function strategyLabel(strategy: Strategy): string {
328
- switch (strategy) {
329
- case "sma_crossover":
330
- return "SMA 20/50 Crossover";
331
- case "sma_50_200_crossover":
332
- return "SMA 50/200 Crossover";
333
- case "rsi_mean_reversion":
334
- return "RSI Mean Reversion";
335
- }
336
- }
@@ -1,281 +0,0 @@
1
- import type { AgentTool } from "@earendil-works/pi-agent-core";
2
- import { Type } from "@sinclair/typebox";
3
- import { wrapProvider } from "../../providers/wrap-provider.js";
4
- import { getHistory } from "../../providers/yahoo-finance.js";
5
- import type { OHLCV } from "../../types/market.js";
6
-
7
- // --- Volume-based indicators ---
8
-
9
- export function computeOBV(bars: OHLCV[]): number[] {
10
- const obv: number[] = [0];
11
- for (let i = 1; i < bars.length; i++) {
12
- if (bars[i].close > bars[i - 1].close) {
13
- obv.push(obv[i - 1] + bars[i].volume);
14
- } else if (bars[i].close < bars[i - 1].close) {
15
- obv.push(obv[i - 1] - bars[i].volume);
16
- } else {
17
- obv.push(obv[i - 1]);
18
- }
19
- }
20
- return obv;
21
- }
22
-
23
- export function computeVWAP(bars: OHLCV[]): number[] {
24
- const vwap: number[] = [];
25
- let cumPV = 0;
26
- let cumVol = 0;
27
- for (const bar of bars) {
28
- const tp = (bar.high + bar.low + bar.close) / 3;
29
- cumPV += tp * bar.volume;
30
- cumVol += bar.volume;
31
- vwap.push(cumVol === 0 ? 0 : cumPV / cumVol);
32
- }
33
- return vwap;
34
- }
35
-
36
- const params = Type.Object({
37
- symbol: Type.String({ description: "Stock ticker symbol (e.g. AAPL, MSFT)" }),
38
- range: Type.Optional(
39
- Type.String({ description: "Time range for data: 3mo, 6mo, 1y, 2y. Default: 1y" }),
40
- ),
41
- });
42
-
43
- export const technicalIndicatorsTool: AgentTool<typeof params> = {
44
- name: "get_technical_indicators",
45
- label: "Technical Indicators",
46
- description:
47
- "Compute technical indicators (SMA, EMA, RSI, MACD, Bollinger Bands) from historical price data. All computed locally — no API dependency.",
48
- parameters: params,
49
- async execute(_toolCallId, args) {
50
- const symbol = args.symbol.toUpperCase();
51
- const range = args.range ?? "1y";
52
- const result = await wrapProvider("yahoo", () => getHistory(symbol, range, "1d"));
53
- if (result.status === "unavailable") {
54
- return {
55
- content: [
56
- {
57
- type: "text",
58
- text: `⚠ Technical indicators unavailable for ${symbol} (${result.reason}).`,
59
- },
60
- ],
61
- details: null as any,
62
- };
63
- }
64
- const bars = result.data;
65
- const closes = bars.map((b) => b.close);
66
-
67
- if (closes.length < 26) {
68
- return {
69
- content: [
70
- {
71
- type: "text",
72
- text: `Insufficient data for ${symbol} (need 26+ bars, got ${closes.length})`,
73
- },
74
- ],
75
- details: null,
76
- };
77
- }
78
-
79
- const sma20 = computeSMA(closes, 20);
80
- const sma50 = computeSMA(closes, 50);
81
- const rsi = computeRSI(closes, 14);
82
- const macd = computeMACD(closes);
83
- const bb = computeBollingerBands(closes, 20, 2);
84
- const obv = computeOBV(bars);
85
- const vwap = computeVWAP(bars);
86
-
87
- const latest = closes[closes.length - 1];
88
- const latestRsi = rsi[rsi.length - 1];
89
- const latestMacd = macd[macd.length - 1];
90
- const latestBB = bb[bb.length - 1];
91
- const latestVwap = vwap[vwap.length - 1];
92
- const obvTrend =
93
- obv.length >= 20
94
- ? obv[obv.length - 1] > obv[obv.length - 20]
95
- ? "Rising"
96
- : "Falling"
97
- : "N/A";
98
-
99
- const lines = [
100
- `**${symbol} Technical Analysis** (${bars[0].date} to ${bars[bars.length - 1].date})`,
101
- `Price: $${latest.toFixed(2)}`,
102
- ``,
103
- `SMA(20): $${sma20[sma20.length - 1]?.toFixed(2) ?? "N/A"} | SMA(50): $${sma50[sma50.length - 1]?.toFixed(2) ?? "N/A"}`,
104
- `RSI(14): ${latestRsi?.toFixed(1) ?? "N/A"} ${rsiSignal(latestRsi)}`,
105
- `MACD: ${latestMacd?.macd.toFixed(2) ?? "N/A"} | Signal: ${latestMacd?.signal.toFixed(2) ?? "N/A"} | Histogram: ${latestMacd?.histogram.toFixed(2) ?? "N/A"}`,
106
- `Bollinger Bands: Upper $${latestBB?.upper.toFixed(2) ?? "N/A"} | Mid $${latestBB?.middle.toFixed(2) ?? "N/A"} | Lower $${latestBB?.lower.toFixed(2) ?? "N/A"}`,
107
- `OBV Trend: ${obvTrend} | VWAP (cumulative): $${latestVwap?.toFixed(2) ?? "N/A"}`,
108
- ``,
109
- trendSummary(latest, sma20, sma50, latestRsi, latestMacd, obvTrend, latestVwap),
110
- ];
111
-
112
- return {
113
- content: [{ type: "text", text: lines.join("\n") }],
114
- details: {
115
- symbol,
116
- range,
117
- prices: closes,
118
- dates: bars.map((b) => b.date),
119
- sma20,
120
- sma50,
121
- rsi,
122
- macd,
123
- bb,
124
- obv,
125
- vwap,
126
- },
127
- };
128
- },
129
- };
130
-
131
- // --- Indicator computations (all pure functions) ---
132
-
133
- export function computeSMA(data: number[], period: number): number[] {
134
- const result: number[] = [];
135
- for (let i = period - 1; i < data.length; i++) {
136
- let sum = 0;
137
- for (let j = i - period + 1; j <= i; j++) sum += data[j];
138
- result.push(sum / period);
139
- }
140
- return result;
141
- }
142
-
143
- export function computeEMA(data: number[], period: number): number[] {
144
- const k = 2 / (period + 1);
145
- const result: number[] = [];
146
- // Seed with SMA of first `period` values
147
- let sum = 0;
148
- for (let i = 0; i < period; i++) sum += data[i];
149
- let ema = sum / period;
150
- result.push(ema);
151
- for (let i = period; i < data.length; i++) {
152
- ema = data[i] * k + ema * (1 - k);
153
- result.push(ema);
154
- }
155
- return result;
156
- }
157
-
158
- export function computeRSI(data: number[], period: number = 14): number[] {
159
- const result: number[] = [];
160
- const gains: number[] = [];
161
- const losses: number[] = [];
162
-
163
- for (let i = 1; i < data.length; i++) {
164
- const diff = data[i] - data[i - 1];
165
- gains.push(diff > 0 ? diff : 0);
166
- losses.push(diff < 0 ? -diff : 0);
167
- }
168
-
169
- if (gains.length < period) return result;
170
-
171
- let avgGain = gains.slice(0, period).reduce((a, b) => a + b, 0) / period;
172
- let avgLoss = losses.slice(0, period).reduce((a, b) => a + b, 0) / period;
173
-
174
- const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;
175
- result.push(100 - 100 / (1 + rs));
176
-
177
- for (let i = period; i < gains.length; i++) {
178
- avgGain = (avgGain * (period - 1) + gains[i]) / period;
179
- avgLoss = (avgLoss * (period - 1) + losses[i]) / period;
180
- const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;
181
- result.push(100 - 100 / (1 + rs));
182
- }
183
-
184
- return result;
185
- }
186
-
187
- export function computeMACD(
188
- data: number[],
189
- fastPeriod = 12,
190
- slowPeriod = 26,
191
- signalPeriod = 9,
192
- ): { macd: number; signal: number; histogram: number }[] {
193
- if (data.length < slowPeriod + signalPeriod) return [];
194
-
195
- const emaFast = computeEMA(data, fastPeriod);
196
- const emaSlow = computeEMA(data, slowPeriod);
197
-
198
- // Align: emaFast starts at index fastPeriod-1, emaSlow at slowPeriod-1
199
- const offset = slowPeriod - fastPeriod;
200
- const macdLine: number[] = [];
201
- for (let i = 0; i < emaSlow.length; i++) {
202
- macdLine.push(emaFast[i + offset] - emaSlow[i]);
203
- }
204
-
205
- if (macdLine.length < signalPeriod) return [];
206
-
207
- const signalLine = computeEMA(macdLine, signalPeriod);
208
- const signalOffset = signalPeriod - 1;
209
-
210
- const result: { macd: number; signal: number; histogram: number }[] = [];
211
- for (let i = 0; i < signalLine.length; i++) {
212
- const m = macdLine[i + signalOffset];
213
- const s = signalLine[i];
214
- result.push({ macd: m, signal: s, histogram: m - s });
215
- }
216
-
217
- return result;
218
- }
219
-
220
- export function computeBollingerBands(
221
- data: number[],
222
- period: number = 20,
223
- stdDev: number = 2,
224
- ): { upper: number; middle: number; lower: number }[] {
225
- const result: { upper: number; middle: number; lower: number }[] = [];
226
- for (let i = period - 1; i < data.length; i++) {
227
- const slice = data.slice(i - period + 1, i + 1);
228
- const mean = slice.reduce((a, b) => a + b, 0) / period;
229
- const variance = slice.reduce((a, b) => a + (b - mean) ** 2, 0) / period;
230
- const sd = Math.sqrt(variance);
231
- result.push({
232
- upper: mean + stdDev * sd,
233
- middle: mean,
234
- lower: mean - stdDev * sd,
235
- });
236
- }
237
- return result;
238
- }
239
-
240
- function rsiSignal(rsi: number | undefined): string {
241
- if (rsi == null) return "";
242
- if (rsi >= 70) return "(Overbought)";
243
- if (rsi <= 30) return "(Oversold)";
244
- return "(Neutral)";
245
- }
246
-
247
- function trendSummary(
248
- price: number,
249
- sma20: number[],
250
- sma50: number[],
251
- rsi: number | undefined,
252
- macd: { macd: number; signal: number; histogram: number } | undefined,
253
- obvTrend?: string,
254
- vwap?: number,
255
- ): string {
256
- const signals: string[] = [];
257
-
258
- const latestSma20 = sma20[sma20.length - 1];
259
- const latestSma50 = sma50[sma50.length - 1];
260
-
261
- if (latestSma20 && price > latestSma20) signals.push("Price above SMA(20) — short-term bullish");
262
- if (latestSma20 && price < latestSma20) signals.push("Price below SMA(20) — short-term bearish");
263
- if (latestSma20 && latestSma50 && latestSma20 > latestSma50)
264
- signals.push("Golden cross pattern (SMA20 > SMA50)");
265
- if (latestSma20 && latestSma50 && latestSma20 < latestSma50)
266
- signals.push("Death cross pattern (SMA20 < SMA50)");
267
- if (rsi != null && rsi >= 70) signals.push("RSI overbought — potential reversal");
268
- if (rsi != null && rsi <= 30) signals.push("RSI oversold — potential bounce");
269
- if (macd && macd.histogram > 0) signals.push("MACD bullish (histogram positive)");
270
- if (macd && macd.histogram < 0) signals.push("MACD bearish (histogram negative)");
271
- if (obvTrend === "Rising" && price > (latestSma20 ?? 0))
272
- signals.push("Volume confirming price advance (OBV rising)");
273
- if (obvTrend === "Falling" && price < (latestSma20 ?? Infinity))
274
- signals.push("Volume confirming price decline (OBV falling)");
275
- if (vwap != null && price > vwap)
276
- signals.push("Price above cumulative VWAP — bullish volume-weighted bias");
277
- if (vwap != null && price < vwap)
278
- signals.push("Price below cumulative VWAP — bearish volume-weighted bias");
279
-
280
- return signals.length > 0 ? `Signals: ${signals.join(" | ")}` : "No strong signals";
281
- }
@@ -1,47 +0,0 @@
1
- export interface CompanyOverview {
2
- symbol: string;
3
- name: string;
4
- description: string;
5
- exchange: string;
6
- sector: string;
7
- industry: string;
8
- marketCap: number;
9
- pe: number | null;
10
- forwardPe: number | null;
11
- eps: number | null;
12
- dividendYield: number | null;
13
- beta: number | null;
14
- week52High: number;
15
- week52Low: number;
16
- avgVolume: number;
17
- profitMargin: number | null;
18
- revenueGrowth: number | null;
19
- }
20
-
21
- export interface EarningsData {
22
- symbol: string;
23
- quarterly: Array<{
24
- date: string;
25
- reportedEPS: number;
26
- estimatedEPS: number;
27
- surprise: number;
28
- surprisePercent: number;
29
- }>;
30
- }
31
-
32
- export interface FinancialStatement {
33
- fiscalDate: string;
34
- revenue: number;
35
- grossProfit: number;
36
- operatingIncome: number;
37
- netIncome: number;
38
- eps: number;
39
- totalAssets: number;
40
- totalLiabilities: number;
41
- totalEquity: number;
42
- operatingCashFlow: number;
43
- freeCashFlow: number;
44
- totalDebt?: number;
45
- cashAndEquivalents?: number;
46
- sharesOutstanding?: number;
47
- }
@@ -1,26 +0,0 @@
1
- export type { CompanyOverview, EarningsData, FinancialStatement } from "./fundamentals.js";
2
- export type { FredObservation, FredSeries } from "./macro.js";
3
- export { FRED_SERIES } from "./macro.js";
4
- export type { CryptoPrice, OHLCV, StockQuote } from "./market.js";
5
- export type { Greeks, OptionContract, OptionsChain } from "./options.js";
6
- export type { PortfolioSummary, Position, RiskMetrics, TechnicalIndicators } from "./portfolio.js";
7
- export type { PredictionMarketQuote } from "./prediction-markets.js";
8
- export type {
9
- FearGreedData,
10
- RedditSentimentResult,
11
- WebSearchEnvelope,
12
- WebSearchResult,
13
- } from "./sentiment.js";
14
-
15
- /**
16
- * Handler for `ask_user` tool invocations in non-UI contexts (e.g. test harness).
17
- * When provided to `createOpenCandleSession`, the ask-user tool calls this handler
18
- * instead of `ctx.ui.*` methods.
19
- */
20
- export type AskUserHandler = (params: {
21
- question: string;
22
- questionType: "select" | "text" | "confirm";
23
- options?: string[];
24
- placeholder?: string;
25
- reason?: string;
26
- }) => Promise<{ answer: string | null; cancelled: boolean }>;