opencandle 0.11.1 → 0.12.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 (653) hide show
  1. package/README.md +20 -24
  2. package/dist/analysts/contracts.js +0 -1
  3. package/dist/analysts/orchestrator.js +0 -1
  4. package/dist/cli-main.js +13 -7
  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.js +0 -1
  9. package/dist/doctor/cli-command.js +2 -1
  10. package/dist/doctor/render.js +0 -1
  11. package/dist/doctor/report.js +40 -11
  12. package/dist/gui/server/ask-user-bridge.d.ts +19 -0
  13. package/dist/gui/server/ask-user-bridge.js +55 -0
  14. package/dist/gui/server/automation-heartbeat.d.ts +25 -0
  15. package/dist/gui/server/automation-heartbeat.js +61 -0
  16. package/dist/gui/server/background-quotes.d.ts +39 -0
  17. package/dist/gui/server/background-quotes.js +71 -0
  18. package/dist/gui/server/chat-event-adapter.d.ts +16 -0
  19. package/dist/gui/server/chat-event-adapter.js +263 -0
  20. package/dist/gui/server/gui-session-manager.d.ts +2 -0
  21. package/dist/gui/server/gui-session-manager.js +4 -0
  22. package/dist/gui/server/http-routes.d.ts +69 -0
  23. package/dist/gui/server/http-routes.js +1008 -0
  24. package/dist/gui/server/invoke-tool.d.ts +47 -0
  25. package/dist/gui/server/invoke-tool.js +373 -0
  26. package/dist/gui/server/live-chat-event-adapter.d.ts +19 -0
  27. package/dist/gui/server/live-chat-event-adapter.js +206 -0
  28. package/dist/gui/server/local-session-coordinator.d.ts +26 -0
  29. package/dist/gui/server/local-session-coordinator.js +53 -0
  30. package/dist/gui/server/market-state-api.d.ts +138 -0
  31. package/dist/gui/server/market-state-api.js +355 -0
  32. package/dist/gui/server/model-setup.d.ts +64 -0
  33. package/dist/gui/server/model-setup.js +150 -0
  34. package/dist/gui/server/private-api-access.d.ts +6 -0
  35. package/dist/gui/server/private-api-access.js +53 -0
  36. package/dist/gui/server/projector.d.ts +49 -0
  37. package/dist/gui/server/projector.js +296 -0
  38. package/dist/gui/server/prompt-observation.d.ts +8 -0
  39. package/dist/gui/server/prompt-observation.js +43 -0
  40. package/dist/gui/server/quote-snapshot-store.d.ts +14 -0
  41. package/dist/gui/server/quote-snapshot-store.js +49 -0
  42. package/dist/gui/server/server.d.ts +1 -0
  43. package/dist/gui/server/server.js +259 -0
  44. package/dist/gui/server/session-actions.d.ts +60 -0
  45. package/dist/gui/server/session-actions.js +218 -0
  46. package/dist/gui/server/session-entry-wait.d.ts +27 -0
  47. package/dist/gui/server/session-entry-wait.js +129 -0
  48. package/dist/gui/server/session-list.d.ts +2 -0
  49. package/dist/gui/server/session-list.js +11 -0
  50. package/dist/gui/server/shutdown.d.ts +10 -0
  51. package/dist/gui/server/shutdown.js +29 -0
  52. package/dist/gui/server/tool-invoke-ack.d.ts +17 -0
  53. package/dist/gui/server/tool-invoke-ack.js +26 -0
  54. package/dist/gui/server/tool-metadata.d.ts +93 -0
  55. package/dist/gui/server/tool-metadata.js +148 -0
  56. package/dist/gui/server/websocket.d.ts +9 -0
  57. package/dist/gui/server/websocket.js +124 -0
  58. package/dist/gui/server/writer-lock.d.ts +1 -0
  59. package/dist/gui/server/writer-lock.js +1 -0
  60. package/dist/gui/server/ws-hub.d.ts +50 -0
  61. package/dist/gui/server/ws-hub.js +284 -0
  62. package/dist/gui/shared/chat-events.d.ts +174 -0
  63. package/dist/gui/shared/chat-events.js +13 -0
  64. package/dist/gui/shared/event-reducer.d.ts +3 -0
  65. package/dist/gui/shared/event-reducer.js +187 -0
  66. package/dist/index.js +0 -1
  67. package/dist/infra/cache.js +0 -1
  68. package/dist/infra/freshness.js +0 -1
  69. package/dist/infra/http-client.js +1 -2
  70. package/dist/infra/index.js +0 -1
  71. package/dist/infra/market-calendar.js +0 -1
  72. package/dist/infra/native-dependencies.js +0 -1
  73. package/dist/infra/node-version.js +0 -1
  74. package/dist/infra/open-url.js +0 -1
  75. package/dist/infra/opencandle-paths.js +0 -1
  76. package/dist/infra/rate-limiter.js +0 -1
  77. package/dist/market-state/alert-conditions.js +0 -1
  78. package/dist/market-state/alert-runner.d.ts +1 -0
  79. package/dist/market-state/alert-runner.js +5 -4
  80. package/dist/market-state/daily-report.js +0 -1
  81. package/dist/market-state/local-automation-service.js +0 -1
  82. package/dist/market-state/notification-delivery.js +0 -1
  83. package/dist/market-state/resolve-for-mutation.js +0 -1
  84. package/dist/market-state/resolve.js +0 -1
  85. package/dist/market-state/service.d.ts +26 -21
  86. package/dist/market-state/service.js +175 -36
  87. package/dist/market-state/summaries.js +1 -13
  88. package/dist/memory/index.js +0 -1
  89. package/dist/memory/manager.js +0 -1
  90. package/dist/memory/preference-extractor.js +0 -1
  91. package/dist/memory/retrieval.js +0 -1
  92. package/dist/memory/sqlite.js +60 -11
  93. package/dist/memory/storage.js +0 -1
  94. package/dist/memory/tool-defaults.js +0 -1
  95. package/dist/memory/types.js +0 -1
  96. package/dist/monitor.js +0 -1
  97. package/dist/onboarding/connect.js +0 -1
  98. package/dist/onboarding/credential-interceptor.js +0 -1
  99. package/dist/onboarding/degradation-accumulator.js +0 -1
  100. package/dist/onboarding/prompt-user.d.ts +1 -1
  101. package/dist/onboarding/prompt-user.js +0 -1
  102. package/dist/onboarding/provider-status.js +0 -1
  103. package/dist/onboarding/providers.js +0 -1
  104. package/dist/onboarding/state.js +0 -1
  105. package/dist/onboarding/tool-helpers.js +0 -1
  106. package/dist/onboarding/tool-tags.js +0 -1
  107. package/dist/onboarding/validate-model-key.d.ts +17 -0
  108. package/dist/onboarding/validate-model-key.js +54 -0
  109. package/dist/onboarding/validation.js +0 -1
  110. package/dist/pi/opencandle-extension.js +2 -2
  111. package/dist/pi/session-action-dedupe.js +0 -1
  112. package/dist/pi/session-storage.js +0 -1
  113. package/dist/pi/session-writer-lock.js +0 -1
  114. package/dist/pi/session.js +0 -1
  115. package/dist/pi/setup.d.ts +2 -0
  116. package/dist/pi/setup.js +10 -3
  117. package/dist/pi/tool-adapter.js +0 -1
  118. package/dist/pi/tui-session-coordinator.js +0 -1
  119. package/dist/prompts/context-builder.js +1 -2
  120. package/dist/prompts/disclaimer.js +0 -1
  121. package/dist/prompts/policy-cards.js +0 -1
  122. package/dist/prompts/sections.js +0 -1
  123. package/dist/prompts/symbol-preflight.js +0 -1
  124. package/dist/prompts/workflow-prompts.js +0 -1
  125. package/dist/providers/alpha-vantage.js +2 -3
  126. package/dist/providers/coingecko.js +0 -1
  127. package/dist/providers/errors.js +0 -1
  128. package/dist/providers/exa-search.js +11 -10
  129. package/dist/providers/external-tool-command.js +0 -1
  130. package/dist/providers/external-tool-error.js +0 -1
  131. package/dist/providers/fear-greed.js +0 -1
  132. package/dist/providers/finnhub.js +0 -1
  133. package/dist/providers/fred.js +0 -1
  134. package/dist/providers/index.js +0 -1
  135. package/dist/providers/polymarket.js +0 -1
  136. package/dist/providers/provider-credential-error.js +0 -1
  137. package/dist/providers/reddit-cli.js +0 -1
  138. package/dist/providers/reddit.js +0 -1
  139. package/dist/providers/sec-edgar.js +0 -1
  140. package/dist/providers/tradingview.js +1 -2
  141. package/dist/providers/twitter-cli.js +0 -1
  142. package/dist/providers/twitter.js +0 -1
  143. package/dist/providers/web-search.js +15 -12
  144. package/dist/providers/with-fallback.js +0 -1
  145. package/dist/providers/wrap-provider.js +0 -1
  146. package/dist/providers/yahoo-finance.js +67 -4
  147. package/dist/routing/classify-intent.js +0 -1
  148. package/dist/routing/defaults.js +0 -1
  149. package/dist/routing/entity-extractor.js +2 -3
  150. package/dist/routing/fund-symbols.js +0 -1
  151. package/dist/routing/horizon.js +0 -1
  152. package/dist/routing/index.js +0 -1
  153. package/dist/routing/legacy-rule-router.js +0 -1
  154. package/dist/routing/planning.js +0 -1
  155. package/dist/routing/route-manifest.js +0 -1
  156. package/dist/routing/router-llm-client.d.ts +2 -2
  157. package/dist/routing/router-llm-client.js +0 -1
  158. package/dist/routing/router-prompt.js +0 -1
  159. package/dist/routing/router-types.js +0 -1
  160. package/dist/routing/router.js +1 -2
  161. package/dist/routing/slot-resolver.js +0 -1
  162. package/dist/routing/symbol-disambiguator.js +0 -1
  163. package/dist/routing/turn-context.js +0 -1
  164. package/dist/routing/types.js +0 -1
  165. package/dist/runtime/answer-contracts.js +0 -1
  166. package/dist/runtime/artifact-contracts.js +0 -1
  167. package/dist/runtime/evidence.js +0 -1
  168. package/dist/runtime/numeric-claims.js +0 -1
  169. package/dist/runtime/planning-evidence.js +0 -1
  170. package/dist/runtime/prompt-step.js +0 -1
  171. package/dist/runtime/provider-tracker.js +0 -1
  172. package/dist/runtime/run-context.js +0 -1
  173. package/dist/runtime/session-coordinator.js +0 -1
  174. package/dist/runtime/session-title.js +0 -1
  175. package/dist/runtime/tool-defaults-wrapper.js +0 -1
  176. package/dist/runtime/validation.js +0 -1
  177. package/dist/runtime/workflow-events.js +0 -1
  178. package/dist/runtime/workflow-runner.d.ts +1 -0
  179. package/dist/runtime/workflow-runner.js +8 -3
  180. package/dist/runtime/workflow-types.js +0 -1
  181. package/dist/sentiment/adapters/finnhub.js +0 -1
  182. package/dist/sentiment/adapters/reddit.js +0 -1
  183. package/dist/sentiment/adapters/twitter.js +0 -1
  184. package/dist/sentiment/adapters/web.js +0 -1
  185. package/dist/sentiment/index.js +4 -2
  186. package/dist/sentiment/insights.js +0 -1
  187. package/dist/sentiment/keywords.js +0 -1
  188. package/dist/sentiment/pipeline.js +0 -1
  189. package/dist/sentiment/scorer.js +0 -1
  190. package/dist/sentiment/store.js +0 -1
  191. package/dist/sentiment/trends.js +0 -1
  192. package/dist/sentiment/types.js +0 -1
  193. package/dist/system-prompt.js +0 -1
  194. package/dist/tool-kit.js +0 -1
  195. package/dist/tools/fundamentals/company-overview.d.ts +1 -1
  196. package/dist/tools/fundamentals/company-overview.js +2 -1
  197. package/dist/tools/fundamentals/comps.js +6 -4
  198. package/dist/tools/fundamentals/dcf.js +0 -1
  199. package/dist/tools/fundamentals/earnings.d.ts +1 -1
  200. package/dist/tools/fundamentals/earnings.js +2 -1
  201. package/dist/tools/fundamentals/financials.js +2 -1
  202. package/dist/tools/fundamentals/sec-filings.js +0 -1
  203. package/dist/tools/index.d.ts +116 -2
  204. package/dist/tools/index.js +0 -1
  205. package/dist/tools/interaction/ask-user.js +11 -1
  206. package/dist/tools/macro/event-probabilities.js +0 -1
  207. package/dist/tools/macro/fear-greed.d.ts +1 -1
  208. package/dist/tools/macro/fear-greed.js +0 -1
  209. package/dist/tools/macro/fred-data.d.ts +1 -1
  210. package/dist/tools/macro/fred-data.js +2 -1
  211. package/dist/tools/market/crypto-history.js +0 -1
  212. package/dist/tools/market/crypto-price.d.ts +2 -2
  213. package/dist/tools/market/crypto-price.js +0 -1
  214. package/dist/tools/market/screen-stocks.js +0 -1
  215. package/dist/tools/market/search-ticker.js +1 -2
  216. package/dist/tools/market/stock-history.js +0 -1
  217. package/dist/tools/market/stock-quote.d.ts +2 -2
  218. package/dist/tools/market/stock-quote.js +0 -1
  219. package/dist/tools/options/greeks.js +0 -1
  220. package/dist/tools/options/option-chain.d.ts +2 -2
  221. package/dist/tools/options/option-chain.js +0 -1
  222. package/dist/tools/portfolio/alerts.d.ts +2 -1
  223. package/dist/tools/portfolio/alerts.js +228 -2
  224. package/dist/tools/portfolio/correlation.js +23 -5
  225. package/dist/tools/portfolio/daily-report.js +0 -1
  226. package/dist/tools/portfolio/holdings-overlap.js +0 -1
  227. package/dist/tools/portfolio/notifications.js +0 -1
  228. package/dist/tools/portfolio/risk-analysis.d.ts +1 -1
  229. package/dist/tools/portfolio/risk-analysis.js +0 -1
  230. package/dist/tools/portfolio/tracker.d.ts +3 -1
  231. package/dist/tools/portfolio/tracker.js +57 -10
  232. package/dist/tools/portfolio/watchlist.d.ts +3 -6
  233. package/dist/tools/portfolio/watchlist.js +101 -110
  234. package/dist/tools/sentiment/insight-format.js +0 -1
  235. package/dist/tools/sentiment/query-match.js +0 -1
  236. package/dist/tools/sentiment/reddit-sentiment.js +0 -1
  237. package/dist/tools/sentiment/sentiment-summary.js +8 -4
  238. package/dist/tools/sentiment/sentiment-trend.d.ts +5 -1
  239. package/dist/tools/sentiment/sentiment-trend.js +6 -2
  240. package/dist/tools/sentiment/twitter-sentiment.js +0 -1
  241. package/dist/tools/sentiment/untrusted-text.js +0 -1
  242. package/dist/tools/sentiment/web-search.d.ts +1 -1
  243. package/dist/tools/sentiment/web-search.js +0 -1
  244. package/dist/tools/sentiment/web-sentiment.js +0 -1
  245. package/dist/tools/technical/backtest.js +0 -1
  246. package/dist/tools/technical/indicators.js +0 -1
  247. package/dist/types/fundamentals.js +0 -1
  248. package/dist/types/index.js +0 -1
  249. package/dist/types/macro.js +0 -1
  250. package/dist/types/market.d.ts +6 -0
  251. package/dist/types/market.js +0 -1
  252. package/dist/types/options.js +0 -1
  253. package/dist/types/portfolio.js +0 -1
  254. package/dist/types/prediction-markets.js +0 -1
  255. package/dist/types/sentiment.js +0 -1
  256. package/dist/workflows/compare-assets.js +0 -1
  257. package/dist/workflows/index.js +0 -1
  258. package/dist/workflows/options-screener.js +0 -1
  259. package/dist/workflows/portfolio-builder.js +0 -1
  260. package/gui/web/dist/assets/CatalogOverlay-CAc7e3Pf.js +1 -0
  261. package/gui/web/dist/assets/index-BOEKd9wT.css +2 -0
  262. package/gui/web/dist/assets/index-C-H05cQ2.js +65 -0
  263. package/gui/web/dist/index.html +2 -2
  264. package/package.json +11 -12
  265. package/dist/analysts/contracts.js.map +0 -1
  266. package/dist/analysts/orchestrator.js.map +0 -1
  267. package/dist/cli-main.js.map +0 -1
  268. package/dist/cli.js.map +0 -1
  269. package/dist/config.js.map +0 -1
  270. package/dist/doctor/cli-command.js.map +0 -1
  271. package/dist/doctor/render.js.map +0 -1
  272. package/dist/doctor/report.js.map +0 -1
  273. package/dist/index.js.map +0 -1
  274. package/dist/infra/cache.js.map +0 -1
  275. package/dist/infra/freshness.js.map +0 -1
  276. package/dist/infra/http-client.js.map +0 -1
  277. package/dist/infra/index.js.map +0 -1
  278. package/dist/infra/market-calendar.js.map +0 -1
  279. package/dist/infra/native-dependencies.js.map +0 -1
  280. package/dist/infra/node-version.js.map +0 -1
  281. package/dist/infra/open-url.js.map +0 -1
  282. package/dist/infra/opencandle-paths.js.map +0 -1
  283. package/dist/infra/rate-limiter.js.map +0 -1
  284. package/dist/market-state/alert-conditions.js.map +0 -1
  285. package/dist/market-state/alert-runner.js.map +0 -1
  286. package/dist/market-state/daily-report.js.map +0 -1
  287. package/dist/market-state/local-automation-service.js.map +0 -1
  288. package/dist/market-state/notification-delivery.js.map +0 -1
  289. package/dist/market-state/resolve-for-mutation.js.map +0 -1
  290. package/dist/market-state/resolve.js.map +0 -1
  291. package/dist/market-state/service.js.map +0 -1
  292. package/dist/market-state/summaries.js.map +0 -1
  293. package/dist/memory/index.js.map +0 -1
  294. package/dist/memory/manager.js.map +0 -1
  295. package/dist/memory/preference-extractor.js.map +0 -1
  296. package/dist/memory/retrieval.js.map +0 -1
  297. package/dist/memory/sqlite.js.map +0 -1
  298. package/dist/memory/storage.js.map +0 -1
  299. package/dist/memory/tool-defaults.js.map +0 -1
  300. package/dist/memory/types.js.map +0 -1
  301. package/dist/monitor.js.map +0 -1
  302. package/dist/onboarding/connect.js.map +0 -1
  303. package/dist/onboarding/credential-interceptor.js.map +0 -1
  304. package/dist/onboarding/degradation-accumulator.js.map +0 -1
  305. package/dist/onboarding/prompt-user.js.map +0 -1
  306. package/dist/onboarding/provider-status.js.map +0 -1
  307. package/dist/onboarding/providers.js.map +0 -1
  308. package/dist/onboarding/state.js.map +0 -1
  309. package/dist/onboarding/tool-helpers.js.map +0 -1
  310. package/dist/onboarding/tool-tags.js.map +0 -1
  311. package/dist/onboarding/validation.js.map +0 -1
  312. package/dist/pi/opencandle-extension.js.map +0 -1
  313. package/dist/pi/session-action-dedupe.js.map +0 -1
  314. package/dist/pi/session-storage.js.map +0 -1
  315. package/dist/pi/session-writer-lock.js.map +0 -1
  316. package/dist/pi/session.js.map +0 -1
  317. package/dist/pi/setup.js.map +0 -1
  318. package/dist/pi/tool-adapter.js.map +0 -1
  319. package/dist/pi/tui-session-coordinator.js.map +0 -1
  320. package/dist/prompts/context-builder.js.map +0 -1
  321. package/dist/prompts/disclaimer.js.map +0 -1
  322. package/dist/prompts/policy-cards.js.map +0 -1
  323. package/dist/prompts/sections.js.map +0 -1
  324. package/dist/prompts/symbol-preflight.js.map +0 -1
  325. package/dist/prompts/workflow-prompts.js.map +0 -1
  326. package/dist/providers/alpha-vantage.js.map +0 -1
  327. package/dist/providers/coingecko.js.map +0 -1
  328. package/dist/providers/errors.js.map +0 -1
  329. package/dist/providers/exa-search.js.map +0 -1
  330. package/dist/providers/external-tool-command.js.map +0 -1
  331. package/dist/providers/external-tool-error.js.map +0 -1
  332. package/dist/providers/fear-greed.js.map +0 -1
  333. package/dist/providers/finnhub.js.map +0 -1
  334. package/dist/providers/fred.js.map +0 -1
  335. package/dist/providers/index.js.map +0 -1
  336. package/dist/providers/polymarket.js.map +0 -1
  337. package/dist/providers/provider-credential-error.js.map +0 -1
  338. package/dist/providers/reddit-cli.js.map +0 -1
  339. package/dist/providers/reddit.js.map +0 -1
  340. package/dist/providers/sec-edgar.js.map +0 -1
  341. package/dist/providers/tradingview.js.map +0 -1
  342. package/dist/providers/twitter-cli.js.map +0 -1
  343. package/dist/providers/twitter.js.map +0 -1
  344. package/dist/providers/web-search.js.map +0 -1
  345. package/dist/providers/with-fallback.js.map +0 -1
  346. package/dist/providers/wrap-provider.js.map +0 -1
  347. package/dist/providers/yahoo-finance.js.map +0 -1
  348. package/dist/routing/classify-intent.js.map +0 -1
  349. package/dist/routing/defaults.js.map +0 -1
  350. package/dist/routing/entity-extractor.js.map +0 -1
  351. package/dist/routing/fund-symbols.js.map +0 -1
  352. package/dist/routing/horizon.js.map +0 -1
  353. package/dist/routing/index.js.map +0 -1
  354. package/dist/routing/legacy-rule-router.js.map +0 -1
  355. package/dist/routing/planning.js.map +0 -1
  356. package/dist/routing/route-manifest.js.map +0 -1
  357. package/dist/routing/router-llm-client.js.map +0 -1
  358. package/dist/routing/router-prompt.js.map +0 -1
  359. package/dist/routing/router-types.js.map +0 -1
  360. package/dist/routing/router.js.map +0 -1
  361. package/dist/routing/slot-resolver.js.map +0 -1
  362. package/dist/routing/symbol-disambiguator.js.map +0 -1
  363. package/dist/routing/turn-context.js.map +0 -1
  364. package/dist/routing/types.js.map +0 -1
  365. package/dist/runtime/answer-contracts.js.map +0 -1
  366. package/dist/runtime/artifact-contracts.js.map +0 -1
  367. package/dist/runtime/evidence.js.map +0 -1
  368. package/dist/runtime/numeric-claims.js.map +0 -1
  369. package/dist/runtime/planning-evidence.js.map +0 -1
  370. package/dist/runtime/prompt-step.js.map +0 -1
  371. package/dist/runtime/provider-tracker.js.map +0 -1
  372. package/dist/runtime/run-context.js.map +0 -1
  373. package/dist/runtime/session-coordinator.js.map +0 -1
  374. package/dist/runtime/session-title.js.map +0 -1
  375. package/dist/runtime/tool-defaults-wrapper.js.map +0 -1
  376. package/dist/runtime/validation.js.map +0 -1
  377. package/dist/runtime/workflow-events.js.map +0 -1
  378. package/dist/runtime/workflow-runner.js.map +0 -1
  379. package/dist/runtime/workflow-types.js.map +0 -1
  380. package/dist/sentiment/adapters/finnhub.js.map +0 -1
  381. package/dist/sentiment/adapters/reddit.js.map +0 -1
  382. package/dist/sentiment/adapters/twitter.js.map +0 -1
  383. package/dist/sentiment/adapters/web.js.map +0 -1
  384. package/dist/sentiment/index.js.map +0 -1
  385. package/dist/sentiment/insights.js.map +0 -1
  386. package/dist/sentiment/keywords.js.map +0 -1
  387. package/dist/sentiment/pipeline.js.map +0 -1
  388. package/dist/sentiment/scorer.js.map +0 -1
  389. package/dist/sentiment/store.js.map +0 -1
  390. package/dist/sentiment/trends.js.map +0 -1
  391. package/dist/sentiment/types.js.map +0 -1
  392. package/dist/system-prompt.js.map +0 -1
  393. package/dist/tool-kit.js.map +0 -1
  394. package/dist/tools/fundamentals/company-overview.js.map +0 -1
  395. package/dist/tools/fundamentals/comps.js.map +0 -1
  396. package/dist/tools/fundamentals/dcf.js.map +0 -1
  397. package/dist/tools/fundamentals/earnings.js.map +0 -1
  398. package/dist/tools/fundamentals/financials.js.map +0 -1
  399. package/dist/tools/fundamentals/sec-filings.js.map +0 -1
  400. package/dist/tools/index.js.map +0 -1
  401. package/dist/tools/interaction/ask-user.js.map +0 -1
  402. package/dist/tools/macro/event-probabilities.js.map +0 -1
  403. package/dist/tools/macro/fear-greed.js.map +0 -1
  404. package/dist/tools/macro/fred-data.js.map +0 -1
  405. package/dist/tools/market/crypto-history.js.map +0 -1
  406. package/dist/tools/market/crypto-price.js.map +0 -1
  407. package/dist/tools/market/screen-stocks.js.map +0 -1
  408. package/dist/tools/market/search-ticker.js.map +0 -1
  409. package/dist/tools/market/stock-history.js.map +0 -1
  410. package/dist/tools/market/stock-quote.js.map +0 -1
  411. package/dist/tools/options/greeks.js.map +0 -1
  412. package/dist/tools/options/option-chain.js.map +0 -1
  413. package/dist/tools/portfolio/alerts.js.map +0 -1
  414. package/dist/tools/portfolio/correlation.js.map +0 -1
  415. package/dist/tools/portfolio/daily-report.js.map +0 -1
  416. package/dist/tools/portfolio/holdings-overlap.js.map +0 -1
  417. package/dist/tools/portfolio/notifications.js.map +0 -1
  418. package/dist/tools/portfolio/risk-analysis.js.map +0 -1
  419. package/dist/tools/portfolio/tracker.js.map +0 -1
  420. package/dist/tools/portfolio/watchlist.js.map +0 -1
  421. package/dist/tools/sentiment/insight-format.js.map +0 -1
  422. package/dist/tools/sentiment/query-match.js.map +0 -1
  423. package/dist/tools/sentiment/reddit-sentiment.js.map +0 -1
  424. package/dist/tools/sentiment/sentiment-summary.js.map +0 -1
  425. package/dist/tools/sentiment/sentiment-trend.js.map +0 -1
  426. package/dist/tools/sentiment/twitter-sentiment.js.map +0 -1
  427. package/dist/tools/sentiment/untrusted-text.js.map +0 -1
  428. package/dist/tools/sentiment/web-search.js.map +0 -1
  429. package/dist/tools/sentiment/web-sentiment.js.map +0 -1
  430. package/dist/tools/technical/backtest.js.map +0 -1
  431. package/dist/tools/technical/indicators.js.map +0 -1
  432. package/dist/types/fundamentals.js.map +0 -1
  433. package/dist/types/index.js.map +0 -1
  434. package/dist/types/macro.js.map +0 -1
  435. package/dist/types/market.js.map +0 -1
  436. package/dist/types/options.js.map +0 -1
  437. package/dist/types/portfolio.js.map +0 -1
  438. package/dist/types/prediction-markets.js.map +0 -1
  439. package/dist/types/sentiment.js.map +0 -1
  440. package/dist/workflows/compare-assets.js.map +0 -1
  441. package/dist/workflows/index.js.map +0 -1
  442. package/dist/workflows/options-screener.js.map +0 -1
  443. package/dist/workflows/portfolio-builder.js.map +0 -1
  444. package/gui/server/ask-user-bridge.ts +0 -89
  445. package/gui/server/automation-heartbeat.ts +0 -97
  446. package/gui/server/background-quotes.ts +0 -127
  447. package/gui/server/chat-event-adapter.ts +0 -294
  448. package/gui/server/gui-session-manager.ts +0 -5
  449. package/gui/server/http-routes.ts +0 -1201
  450. package/gui/server/invoke-tool.ts +0 -490
  451. package/gui/server/live-chat-event-adapter.ts +0 -243
  452. package/gui/server/local-session-coordinator.ts +0 -97
  453. package/gui/server/market-state-api.ts +0 -331
  454. package/gui/server/model-setup.ts +0 -254
  455. package/gui/server/package.json +0 -5
  456. package/gui/server/private-api-access.ts +0 -62
  457. package/gui/server/projector.ts +0 -392
  458. package/gui/server/prompt-observation.ts +0 -58
  459. package/gui/server/quote-snapshot-store.ts +0 -50
  460. package/gui/server/server.ts +0 -289
  461. package/gui/server/session-actions.ts +0 -323
  462. package/gui/server/session-entry-wait.ts +0 -179
  463. package/gui/server/shutdown.ts +0 -47
  464. package/gui/server/tool-invoke-ack.ts +0 -49
  465. package/gui/server/tool-metadata.ts +0 -167
  466. package/gui/server/websocket.ts +0 -138
  467. package/gui/server/writer-lock.ts +0 -1
  468. package/gui/server/ws-hub.ts +0 -403
  469. package/gui/shared/chat-events.ts +0 -165
  470. package/gui/shared/event-reducer.ts +0 -220
  471. package/gui/web/dist/assets/CatalogOverlay-DZ1niyQm.js +0 -1
  472. package/gui/web/dist/assets/index-D4F9AJnn.css +0 -2
  473. package/gui/web/dist/assets/index-DtqMMBTr.js +0 -65
  474. package/src/analysts/contracts.ts +0 -176
  475. package/src/analysts/orchestrator.ts +0 -244
  476. package/src/cli-main.ts +0 -510
  477. package/src/cli.ts +0 -17
  478. package/src/config.ts +0 -272
  479. package/src/doctor/cli-command.ts +0 -83
  480. package/src/doctor/render.ts +0 -37
  481. package/src/doctor/report.ts +0 -638
  482. package/src/index.ts +0 -5
  483. package/src/infra/cache.ts +0 -127
  484. package/src/infra/freshness.ts +0 -165
  485. package/src/infra/http-client.ts +0 -134
  486. package/src/infra/index.ts +0 -14
  487. package/src/infra/market-calendar.ts +0 -193
  488. package/src/infra/native-dependencies.ts +0 -84
  489. package/src/infra/node-version.ts +0 -23
  490. package/src/infra/open-url.ts +0 -28
  491. package/src/infra/opencandle-paths.ts +0 -53
  492. package/src/infra/rate-limiter.ts +0 -77
  493. package/src/market-state/alert-conditions.ts +0 -82
  494. package/src/market-state/alert-runner.ts +0 -863
  495. package/src/market-state/daily-report.ts +0 -237
  496. package/src/market-state/local-automation-service.ts +0 -162
  497. package/src/market-state/notification-delivery.ts +0 -158
  498. package/src/market-state/resolve-for-mutation.ts +0 -24
  499. package/src/market-state/resolve.ts +0 -112
  500. package/src/market-state/service.ts +0 -2208
  501. package/src/market-state/summaries.ts +0 -75
  502. package/src/memory/index.ts +0 -10
  503. package/src/memory/manager.ts +0 -190
  504. package/src/memory/preference-extractor.ts +0 -106
  505. package/src/memory/retrieval.ts +0 -71
  506. package/src/memory/sqlite.ts +0 -577
  507. package/src/memory/storage.ts +0 -195
  508. package/src/memory/tool-defaults.ts +0 -108
  509. package/src/memory/types.ts +0 -71
  510. package/src/monitor.ts +0 -123
  511. package/src/onboarding/connect.ts +0 -177
  512. package/src/onboarding/credential-interceptor.ts +0 -122
  513. package/src/onboarding/degradation-accumulator.ts +0 -77
  514. package/src/onboarding/prompt-user.ts +0 -85
  515. package/src/onboarding/provider-status.ts +0 -382
  516. package/src/onboarding/providers.ts +0 -442
  517. package/src/onboarding/state.ts +0 -216
  518. package/src/onboarding/tool-helpers.ts +0 -104
  519. package/src/onboarding/tool-tags.ts +0 -244
  520. package/src/onboarding/validation.ts +0 -152
  521. package/src/pi/opencandle-extension.ts +0 -1294
  522. package/src/pi/session-action-dedupe.ts +0 -155
  523. package/src/pi/session-storage.ts +0 -5
  524. package/src/pi/session-writer-lock.ts +0 -426
  525. package/src/pi/session.ts +0 -84
  526. package/src/pi/setup.ts +0 -399
  527. package/src/pi/tool-adapter.ts +0 -49
  528. package/src/pi/tui-session-coordinator.ts +0 -351
  529. package/src/prompts/context-builder.ts +0 -326
  530. package/src/prompts/disclaimer.ts +0 -9
  531. package/src/prompts/policy-cards.ts +0 -228
  532. package/src/prompts/sections.ts +0 -46
  533. package/src/prompts/symbol-preflight.ts +0 -80
  534. package/src/prompts/workflow-prompts.ts +0 -504
  535. package/src/providers/alpha-vantage.ts +0 -340
  536. package/src/providers/coingecko.ts +0 -95
  537. package/src/providers/errors.ts +0 -9
  538. package/src/providers/exa-search.ts +0 -375
  539. package/src/providers/external-tool-command.ts +0 -164
  540. package/src/providers/external-tool-error.ts +0 -20
  541. package/src/providers/fear-greed.ts +0 -45
  542. package/src/providers/finnhub.ts +0 -125
  543. package/src/providers/fred.ts +0 -83
  544. package/src/providers/index.ts +0 -17
  545. package/src/providers/polymarket.ts +0 -214
  546. package/src/providers/provider-credential-error.ts +0 -23
  547. package/src/providers/reddit-cli.ts +0 -286
  548. package/src/providers/reddit.ts +0 -106
  549. package/src/providers/sec-edgar.ts +0 -326
  550. package/src/providers/tradingview.ts +0 -399
  551. package/src/providers/twitter-cli.ts +0 -202
  552. package/src/providers/twitter.ts +0 -102
  553. package/src/providers/web-search.ts +0 -303
  554. package/src/providers/with-fallback.ts +0 -42
  555. package/src/providers/wrap-provider.ts +0 -105
  556. package/src/providers/yahoo-finance.ts +0 -984
  557. package/src/routing/classify-intent.ts +0 -380
  558. package/src/routing/defaults.ts +0 -29
  559. package/src/routing/entity-extractor.ts +0 -557
  560. package/src/routing/fund-symbols.ts +0 -58
  561. package/src/routing/horizon.ts +0 -7
  562. package/src/routing/index.ts +0 -70
  563. package/src/routing/legacy-rule-router.ts +0 -13
  564. package/src/routing/planning.ts +0 -829
  565. package/src/routing/route-manifest.ts +0 -308
  566. package/src/routing/router-llm-client.ts +0 -64
  567. package/src/routing/router-prompt.ts +0 -159
  568. package/src/routing/router-types.ts +0 -84
  569. package/src/routing/router.ts +0 -1332
  570. package/src/routing/slot-resolver.ts +0 -213
  571. package/src/routing/symbol-disambiguator.ts +0 -72
  572. package/src/routing/turn-context.ts +0 -108
  573. package/src/routing/types.ts +0 -77
  574. package/src/runtime/answer-contracts.ts +0 -693
  575. package/src/runtime/artifact-contracts.ts +0 -77
  576. package/src/runtime/evidence.ts +0 -78
  577. package/src/runtime/numeric-claims.ts +0 -108
  578. package/src/runtime/planning-evidence.ts +0 -597
  579. package/src/runtime/prompt-step.ts +0 -185
  580. package/src/runtime/provider-tracker.ts +0 -40
  581. package/src/runtime/run-context.ts +0 -32
  582. package/src/runtime/session-coordinator.ts +0 -1037
  583. package/src/runtime/session-title.ts +0 -60
  584. package/src/runtime/tool-defaults-wrapper.ts +0 -43
  585. package/src/runtime/validation.ts +0 -211
  586. package/src/runtime/workflow-events.ts +0 -77
  587. package/src/runtime/workflow-runner.ts +0 -182
  588. package/src/runtime/workflow-types.ts +0 -105
  589. package/src/sentiment/adapters/finnhub.ts +0 -49
  590. package/src/sentiment/adapters/reddit.ts +0 -65
  591. package/src/sentiment/adapters/twitter.ts +0 -36
  592. package/src/sentiment/adapters/web.ts +0 -44
  593. package/src/sentiment/index.ts +0 -49
  594. package/src/sentiment/insights.ts +0 -269
  595. package/src/sentiment/keywords.ts +0 -31
  596. package/src/sentiment/pipeline.ts +0 -91
  597. package/src/sentiment/scorer.ts +0 -89
  598. package/src/sentiment/store.ts +0 -260
  599. package/src/sentiment/trends.ts +0 -96
  600. package/src/sentiment/types.ts +0 -112
  601. package/src/system-prompt.ts +0 -115
  602. package/src/tool-kit.ts +0 -69
  603. package/src/tools/AGENTS.md +0 -36
  604. package/src/tools/fundamentals/company-overview.ts +0 -64
  605. package/src/tools/fundamentals/comps.ts +0 -180
  606. package/src/tools/fundamentals/dcf.ts +0 -447
  607. package/src/tools/fundamentals/earnings.ts +0 -57
  608. package/src/tools/fundamentals/financials.ts +0 -63
  609. package/src/tools/fundamentals/sec-filings.ts +0 -105
  610. package/src/tools/index.ts +0 -104
  611. package/src/tools/interaction/ask-user.ts +0 -93
  612. package/src/tools/macro/event-probabilities.ts +0 -141
  613. package/src/tools/macro/fear-greed.ts +0 -41
  614. package/src/tools/macro/fred-data.ts +0 -92
  615. package/src/tools/market/crypto-history.ts +0 -72
  616. package/src/tools/market/crypto-price.ts +0 -65
  617. package/src/tools/market/screen-stocks.ts +0 -290
  618. package/src/tools/market/search-ticker.ts +0 -254
  619. package/src/tools/market/stock-history.ts +0 -104
  620. package/src/tools/market/stock-quote.ts +0 -73
  621. package/src/tools/options/greeks.ts +0 -81
  622. package/src/tools/options/option-chain.ts +0 -134
  623. package/src/tools/portfolio/alerts.ts +0 -457
  624. package/src/tools/portfolio/correlation.ts +0 -189
  625. package/src/tools/portfolio/daily-report.ts +0 -107
  626. package/src/tools/portfolio/holdings-overlap.ts +0 -139
  627. package/src/tools/portfolio/notifications.ts +0 -45
  628. package/src/tools/portfolio/risk-analysis.ts +0 -173
  629. package/src/tools/portfolio/tracker.ts +0 -308
  630. package/src/tools/portfolio/watchlist.ts +0 -288
  631. package/src/tools/sentiment/insight-format.ts +0 -50
  632. package/src/tools/sentiment/query-match.ts +0 -117
  633. package/src/tools/sentiment/reddit-sentiment.ts +0 -403
  634. package/src/tools/sentiment/sentiment-summary.ts +0 -383
  635. package/src/tools/sentiment/sentiment-trend.ts +0 -75
  636. package/src/tools/sentiment/twitter-sentiment.ts +0 -287
  637. package/src/tools/sentiment/untrusted-text.ts +0 -21
  638. package/src/tools/sentiment/web-search.ts +0 -186
  639. package/src/tools/sentiment/web-sentiment.ts +0 -96
  640. package/src/tools/technical/backtest.ts +0 -336
  641. package/src/tools/technical/indicators.ts +0 -281
  642. package/src/types/fundamentals.ts +0 -47
  643. package/src/types/index.ts +0 -26
  644. package/src/types/macro.ts +0 -27
  645. package/src/types/market.ts +0 -46
  646. package/src/types/options.ts +0 -53
  647. package/src/types/portfolio.ts +0 -83
  648. package/src/types/prediction-markets.ts +0 -13
  649. package/src/types/sentiment.ts +0 -129
  650. package/src/workflows/compare-assets.ts +0 -89
  651. package/src/workflows/index.ts +0 -3
  652. package/src/workflows/options-screener.ts +0 -125
  653. 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 }>;