# PHASES.md --- ## πŸ“ Roadmap Status & Realignment β€” June 2026 Cross-reference: **PRODUCT.md** (P0–P3 priorities) and **FREE-DATA-STACK.md** ($0 data architecture). CLAUDE.md "Status Update" has the full shipped list. ### Done ahead of schedule (was "future", now shipped) | Originally planned as | What actually shipped | Status | |---|---|---| | Phase 12 (news webhooks, ~$200/mo) | **Free-tier news pipeline**: EDGAR + PR-wire pollers β†’ filter/dedupe/classify β†’ SQLite; in-server scheduler + cron runner; `/api/news/*` | βœ… Free version shipped. Paid webhook spine = drop-in upgrade (same queue) | | Phase 14 (real-time monitor + Discord) | **Daily change digest**: snapshot diff + catalyst join β†’ Discord (forum-aware). EOD, not intraday | βœ… EOD version shipped. Real-time price feed still future | | Phase 10.9 (dip opportunity monitor) | **πŸ’Ž Quality dips filter**: quality-gate PASS + 10%+ off 52W high, in the STOCK table | βœ… v1 shipped. Dedicated daily monitor + dip attribution still future | | Phase 10.5d tearsheet (partial) | **Ticker modal**: profile, 1D–5Y chart w/ crosshair, analyst target bar, news | βœ… Covers chart/profile/targets/news. Peer comparison + what-ifs pending | | 10.5e backtest (foundation) | **Signal snapshot ledger** + `/api/screen/history/:ticker` | βœ… Data accumulating; dashboard pending | | (unplanned) | Market Pulse band, sector drill-down panel, advice layer, turnaround watch, data sentinel, verdict tiers, regime hysteresis | βœ… | ### Still at Phase-7 state (not touched this sprint) **Portfolio**, **Market Calls**, **Safe Buys** pages β€” work as before, none of the new intelligence (advice layer, snapshots, news) is wired into them yet. ### Realigned order of future work 1. **Finish Phase 10.5** β€” P/E+ROE+52W columns, P/E/ROE range filters, peer-comparison + what-if sections in the ticker modal (items listed in CLAUDE.md) 2. **Phase 10.6 β€” Portfolio integration** ← biggest gap now: wire signals/advice/snapshots/news into the Portfolio page ("you own this, verdict changed, here's why") 3. **Safe Buys upgrade (10.9 v2)** β€” rebuild the Safe Buys page on quality-dips + snapshot history + news attribution 4. **10.8a β€” earnings dates in the ticker modal** (Finnhub free tier, per FREE-DATA-STACK Β§1.5) 5. **10.5e β€” decision log + backtest dashboard** (once the ledger has ~3 months of data) 6. **Phase 11 β€” auth** (already partially present: JWT login/watchlist exist) β†’ then paid upgrades: **Phase 12** webhook spine, **Phase 13** prompt caching, **Phase 14** real-time monitor --- Complete roadmap for market-screener evolution from Phase 9 through Phase 16+. ## Phase 9 β€” Subdomain Restructure: Server Layer Organization **Goal:** Reorganize `server/` from flat layer-based structure to domain-driven structure. **Timeline:** 3 weeks. ### 9a β€” Create shared infrastructure layer Create `server/domains/shared/` hierarchy: ``` server/domains/shared/ β”œβ”€β”€ entities/ (models + their types together) β”‚ β”œβ”€β”€ Asset.ts β”‚ β”œβ”€β”€ Stock.ts β”‚ β”œβ”€β”€ Etf.ts β”‚ β”œβ”€β”€ Bond.ts β”‚ └── index.ts β”œβ”€β”€ adapters/ (external API wrappers, renamed from "clients") β”‚ β”œβ”€β”€ YahooFinanceAdapter.ts β”‚ β”œβ”€β”€ AnthropicAdapter.ts β”‚ β”œβ”€β”€ SimpleFINAdapter.ts β”‚ └── index.ts β”œβ”€β”€ services/ (cross-domain services) β”‚ β”œβ”€β”€ BenchmarkProvider.ts β”‚ β”œβ”€β”€ CatalystAnalyst.ts β”‚ β”œβ”€β”€ LLMAnalyst.ts β”‚ └── index.ts β”œβ”€β”€ scoring/ (rules + regime management) β”‚ β”œβ”€β”€ ScoringConfig.ts β”‚ β”œβ”€β”€ GateValidator.ts β”‚ β”œβ”€β”€ MarketRegime.ts β”‚ └── index.ts β”œβ”€β”€ persistence/ (SQLite stores) β”‚ β”œβ”€β”€ MarketCallStore.ts β”‚ β”œβ”€β”€ PortfolioStore.ts β”‚ └── index.ts β”œβ”€β”€ types/ (all domain types) β”‚ β”œβ”€β”€ asset.model.ts β”‚ β”œβ”€β”€ finance.model.ts β”‚ β”œβ”€β”€ market.model.ts β”‚ β”œβ”€β”€ [...other models] β”‚ └── index.ts β”œβ”€β”€ config/ β”‚ └── constants.ts β”œβ”€β”€ utils/ β”‚ β”œβ”€β”€ logger.ts β”‚ β”œβ”€β”€ Chunker.ts β”‚ └── index.ts β”œβ”€β”€ db/ β”‚ └── index.ts β”œβ”€β”€ schemas.ts └── index.ts ``` ### 9b β€” Extract screener domain ``` server/domains/screener/ β”œβ”€β”€ ScreenerController.ts β”œβ”€β”€ ScreenerEngine.ts β”œβ”€β”€ PersonalFinanceAnalyzer.ts β”œβ”€β”€ scorers/ β”‚ β”œβ”€β”€ StockScorer.ts β”‚ β”œβ”€β”€ EtfScorer.ts β”‚ β”œβ”€β”€ BondScorer.ts β”‚ └── index.ts β”œβ”€β”€ transform/ β”‚ β”œβ”€β”€ DataMapper.ts β”‚ β”œβ”€β”€ RuleMerger.ts β”‚ └── index.ts └── index.ts ``` ### 9c β€” Extract portfolio domain ``` server/domains/portfolio/ β”œβ”€β”€ PortfolioController.ts β”œβ”€β”€ PortfolioAdvisor.ts β”œβ”€β”€ persistence/ β”‚ └── PortfolioStore.ts └── index.ts ``` ### 9d β€” Extract calls domain ``` server/domains/calls/ β”œβ”€β”€ CallsController.ts β”œβ”€β”€ CalendarService.ts β”œβ”€β”€ persistence/ β”‚ └── MarketCallStore.ts └── index.ts ``` ### 9e β€” Extract finance domain ``` server/domains/finance/ β”œβ”€β”€ FinanceController.ts └── index.ts ``` ### 9f β€” Clean up old directories Remove: `server/controllers/`, `server/services/`, `server/repositories/`, `server/clients/`, `server/models/`, `server/scorers/`, `server/config/`, `server/types/`, `server/utils/` ### 9g β€” Update documentation in CLAUDE.md Update "Server layer map" section with new domain structure. ### 9h β€” Smoke test all routes Create integration smoke test verifying all major routes work after restructure. --- ## Phase 10 β€” UI Component Restructure & Clarity **Goal:** Mirror Phase 9 server restructure at UI layer. Organize components by domain. **Timeline:** 1 week. ### 10a β€” Create component hierarchy ``` ui/src/lib/components/ β”œβ”€β”€ shared/ β”‚ β”œβ”€β”€ Spinner.svelte β”‚ β”œβ”€β”€ VerdictPill.svelte β”‚ β”œβ”€β”€ SignalBadge.svelte β”‚ └── index.ts β”œβ”€β”€ screener/ β”‚ β”œβ”€β”€ AssetTable.svelte β”‚ β”œβ”€β”€ AnalysisSidebar.svelte β”‚ └── index.ts β”œβ”€β”€ portfolio/ β”‚ β”œβ”€β”€ AddHoldingForm.svelte β”‚ β”œβ”€β”€ AdviceTable.svelte β”‚ └── index.ts └── calls/ β”œβ”€β”€ CallForm.svelte β”œβ”€β”€ CallCard.svelte └── index.ts ``` ### 10b β€” Split utils and types ``` lib/utils/ β”œβ”€β”€ formatting.ts β”œβ”€β”€ sorting.ts β”œβ”€β”€ verdicts.ts └── index.ts lib/types/ β”œβ”€β”€ ui.types.ts β”œβ”€β”€ portfolio.types.ts └── index.ts ``` ### 10c β€” Update all imports in routes + stores ### 10d β€” Extract reusable layout components ### 10e β€” UI Phase 10 complete --- ## Phase 10.5 β€” Professional-Grade Screener UI (Institutional Research Tool) **Goal:** Build professional screener interface showing complete investment research capabilities. **Timeline:** 4-6 weeks (after Phase 10). ### 10.5a β€” Three-Layer Layout ``` Sidebar (280px) | Main Table (flex) | Tearsheet Panel (420px) ────────────────┼──────────────────┼────────────────────── Advanced β”‚ Compact table β”‚ Forensic detail filters β”‚ 10 columns only β”‚ Full metrics (left) β”‚ β”‚ Peer comparison β”‚ Scannable β”‚ Decision framework Quick presets β”‚ minimal β”‚ Risk breakdown β”‚ β”‚ (right side-panel) ``` ### 10.5b β€” Sidebar: Advanced Filtering - Preset buttons: All, Strong Buy, Buy, Hold, Avoid - Custom filters: P/E Range, ROE Min, Dip %, D/E Max - Quick presets: "Value Trap Screen", "Growth at Fair Price", "Dip Opportunity" ### 10.5c β€” Main Table: Minimal, Scannable 10 columns: Ticker | Price | Verdict | Score | P/E | ROE | 52W | DCF | Flags | Menu - Sortable, sticky header - Monospace numbers (professional) - Color-coded metrics - Click row β†’ opens tearsheet ### 10.5d β€” Tearsheet Panel: Professional Research Right-side slide-in (420px) with sections: 1. Core Metrics (4-grid, color-coded cards) 2. Valuation Context (comparison table) 3. Decision Framework (gate-by-gate breakdown) 4. Risk Breakdown (ranked, quantified) 5. Threshold Sensitivity (what-if scenarios) 6. Peer Comparison 7. CTA Row (Add to Watchlist, Decision Log) ### 10.5e β€” Decision Logging & Backtest - Save thesis + entry date/price - Track 30/60/90 day outcomes - Simple review modal ("did thesis play out?") - Backtest dashboard (win rate by signal type) ### 10.5f β€” Implementation (Phased) - Week 1-2: Core UI (sidebar, table, tearsheet basic) - Week 2-3: Tearsheet sections (all 7 sections) - Week 3-4: Interactivity (sorting, filters, animation) - Week 4-5: Decision logging - Week 5-6: Backtest dashboard (optional) --- ## Phase 10.6 β€” Portfolio Integration: Market Analysis β†’ Action **Goal:** Connect screener signals + market context to portfolio decisions. ### 10.6a β€” Market-Aware Position Sizing Auto-calculate recommended position size based on: - Stock verdict - Market regime - Sector momentum - Portfolio allocation Display: "Recommended: 2-4% of portfolio" or "$2,000-$4,000" ### 10.6b β€” Portfolio Dashboard: Integrated View Single screen showing: 1. Holdings + P&L 2. Allocation vs Target 3. Market Context 4. Screener Signals 5. Recommended Action ### 10.6c β€” Screener-Portfolio Bridge Add "Your Holdings" column in screener showing: - "You own 2% | +$1,000 gain" - Verdict changes - Thesis change alerts ### 10.6d β€” Thesis Journal (Simplified) When adding position: 1. Why I'm buying (pick ONE reason) 2. What I'll watch (pick 1-2 metrics) 3. Review date (auto 30 days) ### 10.6e β€” Rebalancing Advisor Monitor allocation vs target. When screener verdict changes on existing holding, suggest action. --- ## Phase 10.7 β€” Newbie UX: Progressive Disclosure **Goal:** Professional tool with newbie-friendly interface. Same power, different experience. ### 10.7a β€” Screener Entry: Strategy-Based Instead of filters, ask: "What are you looking for?" Options: - β—‹ Solid companies at good prices (Balanced) - β—‹ Hot stocks with momentum (Momentum) - β—‹ Beaten-down bargains (Value) - β—‹ Let me customize filters (Advanced) ### 10.7b β€” Table View: Plain Language Explanations Minimal table: Ticker | Price | Verdict | Why? ℹ️ Clicking "ℹ️" shows plain-language explanation with reasons, scores, and what it means. ### 10.7c β€” Buy Decision Helper Calculate recommended position size automatically. Show: - Star rating (intuitive) - Concrete dollars (not abstract %) - Clear "safe" path highlighted ### 10.7d β€” Portfolio Status View (Not Analysis) Show status + guidance, not complex metrics: - Visual breakdown (bars) - What it means - Concrete actions (sell, buy, do nothing) ### 10.7e β€” Market Context: Status Light + Impact Use traffic light system: - 🟒 Good / ⚠️ Mixed / πŸ”΄ Bad - Plain explanation of why - Impact on YOUR portfolio ### 10.7f β€” Thesis Logging: Simple Checklist Pick ONE reason + 1-2 metrics to watch. Built-in review schedule. ### 10.7g β€” After Buying: 30-Day Check-In Auto-reminder after 30 days showing: - How metrics moved vs prediction - Thesis status (working / shaken / broken) - Next action ### 10.7h β€” Newbie Mode vs Pro Mode (Toggle) **Newbie Mode:** Simplified screener, plain language, auto position sizing, status lights, guided workflows **Pro Mode:** Full filter control, all metrics, raw data, advanced analysis, complete transparency --- ## Phase 10.8 β€” Earnings Calendar: Context, Not Destination **Goal:** Integrate earnings data contextually, NOT as standalone tab. ### 10.8a β€” Earnings in Screener Tearsheet (Primary) ``` UPCOMING EVENTS: β”œβ”€β”€ Earnings: July 30, 2026 (18 days away) β”‚ β”œβ”€β”€ EPS estimate: $6.50 β”‚ β”œβ”€β”€ Historical beat rate: 65% β”‚ β”œβ”€β”€ Avg price move on earnings: +3% (beat), -2% (miss) β”‚ └── Timing decision: "Buy now before earnings?" or "Wait?" β”‚ β”œβ”€β”€ Ex-dividend: June 15 (6 days away) β”‚ └── Dividend: $0.24/share β”‚ └── Analyst call: Post-earnings July 30 ``` ### 10.8b β€” Earnings in Portfolio (Secondary) Portfolio holdings view shows upcoming events for YOUR positions with thesis-specific tracking. ### 10.8c β€” Earnings Discovery Widget (Optional, Tertiary) Light calendar feature in screener header (NOT main nav): ``` πŸ“… 25 earnings this week in your screened results └── [View by day] [View by verdict] ``` ### 10.8d β€” What NOT to Build ❌ **Standalone "Calendar" nav tab** β€” creates bloat, out-of-context data, redundant. ### 10.8e β€” Earnings in Thesis Journal Earnings become key tracking metric when user logs thesis. ### 10.8f β€” Design Note: Revisit Earnings Display Format **⚠️ DESIGN REVIEW NEEDED:** Consider consistency across three locations, visual hierarchy differences, and mobile responsiveness before finalizing visual design. --- ## Phase 10.9 β€” Strong Buys: Professional Dip Opportunity Monitor > **June 2026:** v1 SHIPPED as the πŸ’Ž Quality dips filter (quality-gate PASS + 10%+ off 52W high). Remaining: dedicated daily monitor, dip-reason attribution, configurable universe/thresholds. **Goal:** Flag quality stocks when they drop 5%+ from 52W high, with market analysis of why. ### 10.9a β€” Data Structure | Field | Source | Purpose | |-------|--------|---------| | Ticker | Yahoo Finance | Stock identifier | | Current Price | Yahoo Finance daily fetch | Entry price today | | 52W High | Yahoo Finance | Reference for dip % | | Dip % | Calculated | Triggers display if β‰₯5% | | Screener Verdict | ScreenerEngine | Quality ranking | | Dip Reason | Market Analysis | Macro vs company issue | | Market Context | Daily fetched | Why dropped? Temporary? | | Your Play | LLM analysis | Buy dip or wait? | | Recommended Action | Position sizing | "Add 2-4% to portfolio" | ### 10.9b β€” Fetching Mechanism (Daily) 1. Get "Too Big to Fail" universe (~150 stocks: mega-cap + large-cap + watchlist) 2. Fetch prices + 52W high (one Yahoo batch call) 3. Filter dips β‰₯5% from 52W high 4. Run screener on dipped stocks 5. Analyze why dipped (macro vs company) 6. Combine + cache (TTL 24 hours) 7. API serves from cache ### 10.9c β€” UI: Tabular Display of Dip Opportunities | Ticker | Price | Dip % | Verdict | Why It Dipped | Your Play | Action | |--------|-------|-------|---------|---------------|-----------|--------| | AAPL | $189.50 | -9.76% | Strong Buy (8.2) | Fed rates high (macro, not company) | Buy dip. iPhone intact. | [+2-4%] | | JPM | $215.30 | -7.2% | Strong Buy (7.8) | Sector rotation (capital away) | Defensive play. Undervalued. | [+3%] | - Sortable by: Dip %, Verdict, Your Play - Click row β†’ full tearsheet - Daily refresh - Threshold configurable: 5% (default) β†’ 10% β†’ 15% ### 10.9d β€” Configuration (User Control) ``` Settings > Strong Buys Monitor: Stock Universe: β˜‘ Mega-cap (10) β˜‘ Large-cap (50) β˜‘ My Watchlist (custom) Dip Threshold: β—‹ 5% (Aggressive) β—‹ 10% (Balanced) β—‹ 15% (Conservative) Update Frequency: β—‹ Daily morning (9:30 AM) ● Daily EOD (4:00 PM) ``` ### 10.9e β€” Design Note: Revisit Tabular Format **⚠️ DESIGN REVIEW NEEDED:** Consider: 1. **Card-based alternative** (cleaner, easier scan) vs current **compact table** 2. **Hybrid approach** (desktop table + mobile cards) Recommendation: Implement Phase 10.9a, gather user feedback, adjust design. --- ## Phase 10.5j β€” Comprehensive Free Data Stack (Zero Cost, Zero Redundancy) **Philosophy:** Professional-grade screener using only FREE sources. No $99-$200/mo subscriptions. Each source has ONE clear job (no duplication). ### Data Sources | Source | Cost | Job | Why | |--------|------|-----|-----| | Yahoo Finance (YahooFinanceClient) | $0 | Core metrics (P/E, ROE, FCF, D/E, analyst ratings) | Already integrated. No alternatives needed. | | yfinance | $0 | Per-ticker enrichment (news, earnings dates, dividends) | Wraps Yahoo, optimized for news extraction. | | Finnhub FREE | $0 | Earnings calendar + estimates only | Reliable future events (3-month lookahead). | | Alpha Vantage FREE | $0 | Market context + sentiment (macro-focused) | Sector trends, Fed decisions, keyword search. | | API Ninjas FREE | $0 | Earnings backup only (redundancy layer) | Fallback if Finnhub hits rate limits. | | Your LLM (Claude) | ~$50/mo | Intelligence layer (turns data into insights) | Sentiment analysis, decision framework, thesis validation. | **Total:** ~$50/mo (just LLM), vs $300-400/mo for Bloomberg/FactSet. ### Data Flow in Tearsheet 1. User screens stocks β†’ ScreenerEngine uses YahooFinanceClient 2. Metrics cached in memory/state (no extra calls) 3. User clicks row β†’ Tearsheet opens 4. Fetch per-ticker enrichment on-demand (yfinance, Finnhub, Alpha Vantage β€” parallel) 5. Process with LLM (if enabled) for sentiment + decision framework 6. Display complete tearsheet ### Integration Timeline - **Week 1:** Add yfinance news enrichment - **Week 2:** Add Finnhub earnings calendar - **Week 3:** Add Alpha Vantage market context - **Week 4:** Add API Ninjas as backup - **Week 5:** Wire everything into tearsheet - **Week 6:** Add LLM enrichment (optional) ### Why This Approach βœ… **Zero Cost:** $0/month (all sources FREE) βœ… **Zero Redundancy:** Each source has ONE job, no overlap βœ… **Professional Grade:** Layered sources like institutional traders use βœ… **Reliability:** Redundancy where it matters (earnings calendar via Finnhub + API Ninjas backup) βœ… **Intelligent:** Your LLM adds 10x value without additional data cost ### Rate Limits & Sustainability - Yahoo Finance: No official limits (proven in production) - yfinance: No limits (wraps Yahoo) - Finnhub FREE: 60 calls/minute (sufficient for 250 stocks) - Alpha Vantage FREE: 5 calls/minute (one daily call, easily manageable) - API Ninjas: 100 calls/month (backup only, minimal usage) --- ## Phase 11 β€” Day Trading: Authentication & Authorization **Goal:** Add multi-user support with JWT auth, role-based access control, and portfolio isolation. **Timeline:** 2-3 weeks. ### Why Auth is First Can't test multi-user portfolios, public + private access, Discord notifications with user context, or trade journal attribution without auth. ### 11a β€” Create auth domain ``` server/domains/auth/ β”œβ”€β”€ AuthController.ts β”œβ”€β”€ AuthService.ts β”œβ”€β”€ JWTStrategy.ts β”œβ”€β”€ RBACGuard.ts β”œβ”€β”€ persistence/ β”‚ └── UserStore.ts └── types/ └── auth.model.ts ``` ### 11b β€” Database schema changes ```sql CREATE TABLE users ( id TEXT PRIMARY KEY, email TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, role TEXT DEFAULT 'viewer' CHECK (role IN ('trader', 'viewer', 'admin')), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, last_login DATETIME ); ALTER TABLE holdings ADD COLUMN user_id TEXT NOT NULL REFERENCES users(id); ALTER TABLE market_calls ADD COLUMN created_by TEXT REFERENCES users(id); ``` ### 11c β€” Middleware + route protection Apply RBACGuard to protected routes. JWT secret from env var. ### 11d β€” UI auth layer Add `routes/auth/login/` and `routes/auth/register/`. Create `lib/stores/auth.store.svelte.ts` for currentUser, JWT, login/logout. --- ## Phase 12 β€” Day Trading: News Webhooks > **June 2026:** Free-tier equivalent SHIPPED (`server/domains/news/` β€” EDGAR + PR-wire pollers, same queue design). This phase now = adding the paid Polygon/Finnhub real-time spine as another producer. See FREE-DATA-STACK.md. **Goal:** Ingest real-time market news via Polygon.io webhooks. **Timeline:** 2-3 weeks. ### Why Webhooks Come Second News feeds everything downstream: Safe Buys monitor, LLM analysis, price dips. ### 12a β€” Create news domain ``` server/domains/news/ β”œβ”€β”€ NewsController.ts β”œβ”€β”€ WebhookHandler.ts β”œβ”€β”€ NewsStore.ts β”œβ”€β”€ NewsQueue.ts (BullMQ worker) β”œβ”€β”€ persistence/ β”‚ └── NewsArticleStore.ts └── types/ └── news.model.ts ``` ### 12b β€” Database schema ```sql CREATE TABLE news_articles ( id TEXT PRIMARY KEY, ticker TEXT NOT NULL, headline TEXT NOT NULL, body TEXT, source TEXT, url TEXT, sentiment TEXT, published_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_news_ticker_date ON news_articles(ticker, published_at DESC); ``` ### 12c β€” Set up Polygon.io webhook 1. Subscribe to Polygon news API (~$200/mo) 2. Register webhook: `https://yourapp.com/webhooks/news` 3. Validate signature (Polygon sends HMAC) 4. Queue article for async processing ### 12d β€” Async processing with BullMQ Queue processes articles: 1. Store in DB 2. Trigger LLM analysis if key tickers mentioned 3. Notify subscribers (Discord, etc) --- ## Phase 13 β€” Day Trading: Prompt Caching & LLM Optimization **Goal:** Reduce LLM costs by 90% using Anthropic prompt caching. **Timeline:** 2-3 weeks. ### 13a β€” Create llm domain ``` server/domains/llm/ β”œβ”€β”€ LLMRouter.ts β”œβ”€β”€ PromptCache.ts β”œβ”€β”€ LLMAnalyst.ts (refactored) β”œβ”€β”€ persistence/ β”‚ β”œβ”€β”€ AnalysisStore.ts β”‚ └── CacheStore.ts └── types/ └── llm.model.ts ``` ### 13b β€” Database schema ```sql CREATE TABLE llm_analysis ( id TEXT PRIMARY KEY, ticker TEXT NOT NULL, analysis_result TEXT NOT NULL, model_used TEXT DEFAULT 'claude-opus', tokens_used INTEGER, cache_hit BOOLEAN DEFAULT false, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` ### 13c β€” Implement Anthropic prompt caching Add `cache_control: { type: 'ephemeral' }` to system prompt message block. Use `anthropic-beta: prompt-caching-2024-07-31` header. ### 13d β€” LLM Router for cost optimization Route to cheaper models (Sonnet) when cost-sensitive. Fallback to OpenAI if rate-limited. --- ## Phase 14 β€” Day Trading: Safe Buys Monitor with Discord Alerts > **June 2026:** EOD version SHIPPED (`server/domains/digest/` β€” daily signal-flip digest with catalysts β†’ Discord). This phase now = real-time price feed + intraday dip alerts. **Goal:** Monitor safe-buy stocks in real-time, detect 5%+ dips, notify via Discord. **Timeline:** 3-4 weeks. ### 14a β€” Create trading domain ``` server/domains/trading/ β”œβ”€β”€ TradingController.ts β”œβ”€β”€ DipDetector.ts β”œβ”€β”€ PriceMonitor.ts β”œβ”€β”€ DiscordNotifier.ts β”œβ”€β”€ persistence/ β”‚ β”œβ”€β”€ PriceSnapshotStore.ts β”‚ └── TradeSignalStore.ts └── types/ └── trading.model.ts ``` ### 14b β€” Database schema ```sql CREATE TABLE price_snapshots ( id TEXT PRIMARY KEY, ticker TEXT NOT NULL, price REAL NOT NULL, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, source TEXT, dip_detected BOOLEAN DEFAULT false ); CREATE TABLE trading_signals ( id TEXT PRIMARY KEY, ticker TEXT NOT NULL, signal_type TEXT CHECK (signal_type IN ('strong_buy', 'dip', 'warning')), entry_price REAL, detected_at DATETIME DEFAULT CURRENT_TIMESTAMP, notified BOOLEAN DEFAULT false, outcome TEXT ); ``` ### 14c β€” Real-time price polling Check watched tickers every 5 seconds. Filter dips β‰₯5%. Process via DipDetector. ### 14d β€” Discord notifications Send rich embeds with: - πŸ”΄ 5% Dip Detected: TICKER - Price fell from $X to $Y (-%Z) - LLM sentiment + recommendation - Risks --- ## Phase 15 β€” Day Trading: Trade Journal & Performance Tracking **Goal:** Log every decision, track outcomes, measure strategy performance. **Timeline:** 1-2 weeks. ### 15a β€” Database schema ```sql CREATE TABLE trade_journal ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES users(id), ticker TEXT NOT NULL, signal TEXT, entry_price REAL NOT NULL, entry_date DATETIME DEFAULT CURRENT_TIMESTAMP, exit_price REAL, exit_date DATETIME, outcome TEXT CHECK (outcome IN ('win', 'loss', 'pending')), pnl REAL, reason TEXT, notes TEXT ); CREATE INDEX idx_journal_user ON trade_journal(user_id, entry_date DESC); ``` ### 15b β€” Trade stats dashboard Compute daily aggregates: - Total trades, wins, losses - Win rate, total P&L - Average win/loss, best/worst signal ### 15c β€” UI: Trade Stats Dashboard Display stats + trade history with filtering. --- ## Phase 16 β€” Multi-LLM Support (Optional) **Goal:** Support Claude, OpenAI, optionally Llama for cost optimization. **Timeline:** 2-3 weeks (do after Phase 14). ### Minimal implementation ```typescript const MODELS = { 'claude-opus': { cost: 0.015, speed: 'slow', quality: 'best' }, 'claude-sonnet': { cost: 0.003, speed: 'fast', quality: 'good' }, 'gpt-4': { cost: 0.03, speed: 'medium', quality: 'excellent' }, }; async analyze(ticker: string, preferredModel?: string) { const model = preferredModel || 'claude-sonnet'; return await routers[model].analyze(ticker); } ``` --- ## Production Readiness Checklist **Before going live:** - [ ] Environment variables locked down (.env.production, no secrets in code) - [ ] Database: Migrate SQLite β†’ Postgres if expect >10 concurrent users - [ ] Job Queue: Set up BullMQ with Redis - [ ] Logging: Add structured logging (Winston, Pino) to track LLM calls + costs - [ ] Rate Limiting: Enabled on all public endpoints (@fastify/rate-limit) - [ ] Discord Webhook: Test alerts with real market data - [ ] Auth: JWT secret rotated, session timeout 1h - [ ] SSL/TLS: HTTPS enforced - [ ] Monitoring: Alerts for job backlog, API latency, cache hit rate, webhook failures - [ ] Alpaca price feed staleness: Should be <5s **Cost estimation (steady state):** | Service | Cost | Notes | |---------|------|-------| | Polygon.io (real-time news + quotes) | $200 | Required for webhooks | | Anthropic Claude API (w/ prompt caching) | $50–100 | Most cached; 90% cost reduction | | OpenAI API (fallback, optional) | $50 | Only if GPT-4 fallback added | | Alpaca/Interactive Brokers | $30–100 | Depends on which feed | | BullMQ (Redis queue, if scaled) | $0–30 | Free if self-hosted | | **Total** | **~$330–450/month** | Scales well (no per-user seat cost) | --- ## Final Architecture Summary | Layer | Tech | Status | |-------|------|--------| | **Auth** | JWT + RBAC | Phase 11 (weeks 1-2) | | **Data** | SQLite β†’ Postgres if 1000+ users | Phase 11 | | **News** | Polygon.io webhooks | Phase 12 (weeks 3-4) | | **LLM** | Anthropic + OpenAI w/ prompt caching | Phase 13-14 (weeks 5-6) | | **Trading** | Real-time price monitoring + Discord | Phase 14 (weeks 7-10) | | **Tracking** | Trade journal + stats | Phase 15 (weeks 11-12) | | **UI** | Svelte 5 + Phase 10 structure | Phase 10 (weeks 1-5 parallel) | **Total time to "trading ready":** 12-16 weeks solo, 8 weeks with 1-2 junior devs. **Go-live target:** Q3 2026 (July–September). --- ## Postgres Migration Path (When Needed) If you grow to 10+ active traders: 1. Create Postgres RDS instance (AWS: ~$15/mo, db.t3.micro) 2. Update connection string to point to Postgres 3. Run schema dump SQLite β†’ Postgres 4. Test on staging first 5. Blue-green deploy: run both DBs in parallel for 1 day, switch, keep SQLite as backup **Time:** 2–4 hours. No code changes needed. --- ## Frequently Asked Questions **Q: How many traders can this system handle?** A: - **10–50 traders:** Single instance. Costs ~$450/mo. - **50–500 traders:** Add Postgres + Redis queue. Costs ~$1000/mo. - **500+ traders:** Add Kubernetes + load balancing. Costs ~$5000+/mo. **Q: What if Polygon.io goes down?** A: Have fallback plan: 1. Switch to Finnhub webhooks (similar API, different provider) 2. Or fall back to polling (5s instead of real-time, less expensive) 3. Add circuit breaker: if Polygon fails for >5 min, automatically switch **Q: Can I trade with real money?** A: Yes, but: 1. Start with **paper trading** (Alpaca's paper account, no real money) 2. Test for 2+ weeks on real market conditions 3. Once you hit 55%+ win rate on paper, go live with small position sizes 4. Scale up gradually (1% β†’ 5% β†’ 10%) 5. Always have manual kill-switch **Q: Should I use local LLM training?** A: Not yet. Only consider if: - You have 6+ months of clean trade data - Your LLM bill is >$1000/mo - You have $20K+ to spend on GPU infrastructure For now, optimize prompts instead. Good prompt beats fine-tuned model. --- ## Future Enhancements (Unscheduled) ### FE-1 β€” Pinned Stocks Watchlist **Concept:** User can pin any stock from the screener table. Pinned stocks appear in a persistent sidebar or dedicated panel showing: - Minimal summary: ticker, current price, signal badge, score - Price-since-pin sparkline β€” a small inline chart showing how price moved from the day the stock was pinned to today - Quick unpin button **Data requirements:** - Store `{ ticker, pinnedAt, pinnedPrice }` in SQLite (`pinned_stocks` table) - Fetch daily OHLC history from Yahoo Finance for the period `pinnedAt β†’ now` to power the sparkline - API: `GET /api/pins` (list), `POST /api/pins` (add), `DELETE /api/pins/:ticker` (remove), `GET /api/pins/:ticker/history` (OHLC since pin) **UI notes:** - Pin button (πŸ“Œ) appears on hover of each summary row in the screener table - Pinned panel can live in a collapsible drawer at the bottom, or a fixed right sidebar - Sparkline: use a lightweight SVG path (no charting library needed); green if price above pin price, red if below - On click of the sparkline, open a larger chart modal (Phase FE-1b β€” can use TradingView widget or Chart.js) **Why deferred:** Requires persistent per-user state (needs Phase 11 auth to be meaningful across sessions). Build after Phase 11. --- ### FE-2 β€” Column Header Tooltips ("Why does this matter?") **Concept:** Clicking a column header in the screener summary row opens a small popover explaining: - What the metric measures - What a good vs bad value looks like - How the screener uses it in scoring This turns the table into a learning tool β€” users understand *why* P/E or ROE matters, not just what the number is. **Suggested content per column:** | Header | What to explain | |--------|----------------| | **Score** | Weighted sum of all factor scores. >6 = quality, <4 = weak. Gates must pass first β€” score only fires if gates are cleared. | | **Signal** | Compares two scoring lenses (Mkt-Adjusted vs Graham). Strong Buy = passes both. Momentum = passes inflated only. | | **P/E** | Price-to-earnings. Lower = cheaper relative to earnings. Gate: <15x (Graham) or 30x warrants scrutiny unless high growth. | | **PEG** | P/E Γ· growth rate. Normalises valuation for growth. <1.0 = paying less than growth justifies. Lynch's standard. | | **ROE%** | Return on equity β€” how efficiently the company uses shareholder money. >15% is healthy; >30% is exceptional. Weighted 3Γ— in scoring. | | **OpMgn%** | Operating margin β€” profit per dollar of revenue before interest and tax. Measures business efficiency. | | **FCF%** | Free cash flow yield β€” cash the business actually generates relative to price. Negative = cash-burning; gate fails. | | **D/E** | Debt-to-equity. Measures leverage. Gate: <1.5Γ— (general), <2.0Γ— (tech). Higher than 2Γ— raises distress risk. | | **52W Chg** | Total price return over last 52 weeks. Positive momentum is healthy; >+50% may signal overextension. | | **From High** | % below the 52-week high. -5% to -15% is a typical dip zone; ≀-30% triggers a risk flag. | | **Analyst** | Yahoo consensus (1=Strong Buy, 5=Strong Sell). Requires β‰₯3 analysts to fire. ≀2.0 adds points; >4.0 subtracts. | | **DCF Safety** | Margin of safety from a two-stage DCF model. Positive = stock appears undervalued vs intrinsic value. Only fires when FCF > 0. | | **Cap** | Market cap tier: Mega (>$200B), Large ($10B+), Mid ($2B+), Small ($300M+), Micro (<$300M). Smaller = higher risk + volatility. | | **Style** | Growth classification from revenue + earnings growth rate. High Growth = β‰₯15% revenue growth. Value = low growth + β‰₯3% yield. | **Implementation approach:** - Add `data-tip` attribute to each `` in `AssetTable.svelte` - On click, show a positioned `
` anchored to the header - Dismiss on outside click or Escape - No library needed β€” pure Svelte `$state` + CSS positioning - Mobile: tip opens as a bottom sheet modal **Why not `title` attribute?** `title` tooltips are unstyled, non-interactive, and don't work on touch. A custom popover lets you format the content properly and include a "Good range" callout. **Why deferred:** Nice-to-have educational feature. Build after the core screener UI (Phase 10.5) is stable.