Content
# Tanmay Trading System
Personal trading dashboard + CLI for managing two Fidelity brokerage accounts (ROTH IRA + Individual TOD).
**Goal: Bloomberg Terminal-level intelligence with $0 terminal cost** — one command delivers full briefing, lead indicators, pre-earnings decisions, live P&L, numbered action list.
> **Private repo** — `positions.json` contains real financial data and is gitignored.
## 🚀 Quick Start — New Claude Session
Open [`PROMPT.md`](./PROMPT.md) → copy the prompt block → paste into any Claude chat.
Claude reads GitHub + local files → full system context restored in <2 minutes. Works every time.
---
## What It Does
- **Morning briefing CLI** — live prices, RSI, news, pattern detection, probable fill alerts, earnings warnings, action items
- **Probable fill detection** — every morning checks yesterday's OHLC against all open pending orders; alerts you to check Fidelity
- **Watchlist entry tracker** — monitors candidates against live RSI/market conditions; auto-flags when entry conditions flip GREEN
- **Lead indicators engine** — pre-earnings checklist per ticker: Polymarket beat probability, earningswhispers.com, unusual options flow, supply chain upstream signals
- **Dynamic universe scanner** — scans ~350 stocks daily through 180-point algorithm, surfaces candidates, auto-refreshes watchlist
- **Portfolio simulation suite (Deliverables 1–5)** — equity curve, Sharpe, drawdown, OOS validation, stress test, sizing comparison, factor attribution, portfolio risk
- **Claude paper portfolio** — 35-day "Claude vs User" mechanical-vs-discretionary side-by-side experiment with pure system rules
- **Forward log infrastructure** — daily_log.jsonl + signal scorers auto-append every run, silent-gap detection for 60d eval
- **FinancialDatasets.ai MCP integration** — historical point-in-time fundamentals (gated behind validation)
- **Web dashboard** — 13-tab React app with live market data, portfolio tracker, full playbook
- **402 tests passing** (pytest tests/)
---
## Validated Findings (2026-05-12)
- **System edge: MEAN-REVERSION only.** Catches Iran/Hormuz, ABT/SYK oversold setups. NO momentum edge — misses parabolic moves (MU +117%, AMD +47% in 20d). Momentum sleeve deferred to post-July 8 eval.
- **Stress test: DEFENSIVE** in 2008/2020/2022. System absorbs ~50-65% of SPY drawdown across all 3 crises. Pair-with-SPY framing is data-backed.
- **OOS validation FAIL** at 10bps/≥70 — defaults reverted to 50bps/≥50 conservative baseline.
- **MACD is a negative signal** — fires 28% of entries, WR delta -12.5pp. Real discriminators: 52W low + Below200MA + Rel strength.
- **MU $400 hindsight-trap** (definitive): trailing-8% stop would have hit Mar 3 at -9.8% LOSS, then MU went +112% from stop-out. Parabolic-momentum trades with reactive exits in ROTH = stop-loss magnet. TOD Lifetime is the only structure that catches these.
- **47-entry walk-forward backtest** (Feb-Apr 2026): 68% win rate, beat SPY only 45%, mean alpha +1.3%/30d. Real but lumpy edge — diversify across multiple entries with mandatory stops, expect 1-2 of 4 to fail.
---
## How Pending Orders Work
All open orders live in `positions.json` under each position's `pending_orders` array.
Every morning run:
1. Fetches yesterday's OHLC for every position
2. Compares against all open buy limits and stop losses
3. If `yesterday_low ≤ buy_limit` → probable fill alert
4. If `yesterday_low ≤ stop_price` → probable stop trigger alert
5. Prints prominently at top of terminal and in HTML alert bar
You verify in Fidelity → confirm in chat → positions.json updated immediately.
No screenshots. No imports. No guessing.
---
## Lead Indicators — Beat the Street
Bloomberg Terminal costs $24K/year. This system uses free/cheap signals that move **before** price:
| Tier | Signal | Source | Lead Time | Tickers |
|------|--------|--------|-----------|---------|
| 1 | Prediction market beat probability | polymarket.com / kalshi.com | 0-7 days pre-earnings | All |
| 1 | Earnings whisper vs consensus | earningswhispers.com | 1-3 days pre-earnings | All |
| 1 | Unusual options call buying | unusualwhales.com | 1-5 days pre-earnings | All |
| 2 | TSMC monthly revenue | tsmc.com/IR (~10th each month) | 6-8 weeks early | TSM, AMD, NVDA, ASML |
| 2 | Foxconn monthly revenue | foxconn.com/IR (~10th each month) | 6-8 weeks early | AAPL |
| 3 | Sector comp sequencing | Earnings calendar | 2-4 weeks early | All |
| 4 | Insider Form 4 buying | yfinance + Finnhub (SEC Form 4) | 1-3 months early | All |
| 4b | Options P/C flow + gamma walls | yfinance chains (free) | 1-5 days | All |
| 4c | Ticker news sentiment | yfinance headlines, keyword-matched | same-day | All |
| 4d | Macro narrative pulse | newsapi / Finnhub macro feed | same-day | Narrative tickers |
| 5 | Google Trends | trends.google.com | 1-4 weeks early | AAPL, NKE, NVO |
`morning_run.py` automatically surfaces lead indicator reminders when any held position has earnings ≤14 days.
**AMD lesson (May 5 2026):** Polymarket showed 96.4% beat probability. TSMC April revenue had already signaled strong AI demand. AMD +16% next day. These signals were all readable pre-market — now they're in the briefing automatically.
---
## Project Structure
```
trading/
├── api.py # FastAPI backend (port 8000) — token-authenticated mutation endpoints
├── morning_run.py # Thin orchestrator — run() pipeline (was 4440L monolith → 786L)
├── persistence.py # File I/O — positions.json, daily_brief.json, history, trades log
├── data_fetch.py # yfinance helpers, RSI/MACD/BB, earnings detection, news, market indicators
├── positions.py # Position state, P&L, pending-order analysis
├── alerts_check.py # Order fill detection, watchlist evaluation, lead-indicator prompts
├── action_engine.py # generate_action_items_v3 — 6-signal synthesis (used by CLI + HTML + API)
├── html_render.py # tracker.html dashboard generation
├── terminal_ui.py # Rich console renderers (positions table, market indicators, etc.)
├── cli_commands.py # CLI subcommands: cmd_buy/sell/stop/score/positions/scan/news/breadth/server/help
├── score.py # 180-point entry scoring algorithm (scan_mode for universe scanning)
├── spec_score.py # 150-point scorer for startup/penny/pre-FCF stocks — auto-routed by score.py
├── customer_concentration.py # SEC EDGAR 10-K parser — top customer % of revenue, regex + Haiku fallback
├── community_reddit.py # WSB / r/stocks / r/investing mention + sentiment via Haiku — 6h cache
├── community_youtube.py # YouTube Data API v3 — tech-creator allowlist (Lex/MKBHD/Acquired) — 24h cache
├── community_score.py # Combiner: WSB-fade RSI gate + tech-creator early signal — display-only v1
├── innovation_arxiv.py # arXiv research-paper signal — 35-ticker map, 7d cache
├── innovation_score.py # Innovation combiner: paper volume + breadth + frontier-cat match — display-only v1
├── narrative_score.py # Multi-signal combiner with pluggable mode flags (community/innovation/insider/options/wsb)
├── backtest.py # 730d historical validation — 96-ticker default, falling-knife guard testing
├── analyze_blocked.py # Bootstrap-CI hypothesis test for guard effectiveness
├── refactor_validate.py # Structural fingerprint check (replaces text-diff for refactor checkpoints)
├── patterns.py # Chart pattern + indicator detection (8 classical patterns)
├── scan.py # Full US market scanner (legacy)
├── scan_universe.py # Dynamic universe scanner — ~350 stocks, auto-managed watchlist (dual output: regular + spec)
├── breadth.py # Market breadth indicators (% above MA, A/D ratio, VIX regime)
├── dividends.py # Dividend calendar — ex-dates, payouts, yield per position
├── earnings_calendar.py # Earnings proximity — 4-source detection, urgency classification
├── recap.py # Monthly performance summary + all-time stats
├── data_client.py # Market data provider with fallback chain
├── insider.py # SEC Form 4 insider buying tracker — 24hr cache, auto-wired into score.py
├── options_flow.py # Options flow tracker — P/C ratio, gamma walls, unusual calls — 4hr cache
├── news_sentiment.py # Keyword-based news sentiment + macro pulse classifier (no LLM, no API cost)
├── etf_score.py # 5-factor ETF thesis scorer (policy/catalyst/macro/valuation/duration)
├── portfolio_sim.py # Full portfolio simulation — equity curve, Sharpe, drawdown, 4 sizing modes (D1)
├── oos_validation.py # In-sample / out-of-sample Sharpe retention check — caught 10bps/≥70 curve-fit (D1.5)
├── stress_test.py # 2008/2020/2022 crisis windows — system DEFENSIVE in all 3 (D2)
├── sizing_comparison.py # fixed_dollar / fixed_fractional / kelly / vol_targeted side-by-side (D3)
├── factor_attribution.py # OLS + univariate factor analysis — MACD = negative signal finding (D4)
├── portfolio_risk.py # Portfolio-level guardrails — beta/concentration/sector/heat → size multiplier (D5)
├── full_system_backtest.py # ~150pt backtest with historical FCF/D&E — gated behind FD validation
├── validate_financialdatasets.py # Pre-integration validation vs SEC EDGAR ±2%
├── daily_log.py # Per-run state log — silent-gap detection for July 8 forward eval
├── claude_portfolio.py # Paper trading account — pure system rules, 35-day "Claude vs User" experiment
├── playbook.json # Static content: geo/themes/sectors/rules/ETFs
├── positions.json # Live portfolio — source of truth (gitignored)
├── trades_log.json # Trade history (gitignored)
├── portfolio_history.json # Daily equity snapshots (gitignored)
├── insider_cache.json # Insider signal cache — 24hr TTL (gitignored — regenerated daily)
├── options_flow_cache.json # Options flow cache — 4hr TTL (gitignored — regenerated intraday)
├── scan_results.json # Latest scan output (gitignored — regenerated daily)
├── watchlist.json # Auto-managed watchlist (gitignored — regenerated daily)
├── data/edgar_cache/ # SEC 10-K extraction cache — 365-day TTL (gitignored — regenerated on demand)
├── data/fd_cache/ # FinancialDatasets historical fundamentals — forever cache (gitignored)
├── data/community_cache/ # Reddit + YouTube + _forward_log.jsonl (gitignored)
├── data/innovation_cache/ # arXiv + _forward_log.jsonl (gitignored)
├── data/narrative_cache/ # Narrative combiner + _forward_log.jsonl (gitignored)
├── data/simulation/ # D1-D5 output: TRIAGE memo, stress_report, factor_report, sizing_report (gitignored)
├── data/daily_log.jsonl # Per-run state — silent-gap detection (gitignored)
├── data/claude_portfolio.json # Paper trading state (gitignored)
├── data/claude_trades.json # Paper trade log (gitignored)
├── refactor_baseline.json # Structural fingerprint baseline (committed for refactor validation)
├── ROADMAP.md # Single source of truth: shipped/pending/decision log
├── scripts/
│ ├── scan_universe.sh # Bash wrapper for cron
│ └── com.tanmay.trading.scan.plist # launchd job — runs at 8:30 AM MST weekdays
├── SKILL.md # Full trading rules reference
├── CLAUDE.md # Claude Code project instructions
├── SECURITY.md # Security notes
└── frontend/ # React app
└── src/pages/
├── Dashboard.jsx
├── Positions.jsx
├── ActionItems.jsx
├── Performance.jsx
├── Trades.jsx
├── ETFs.jsx
├── Intelligence.jsx
├── Trump.jsx
├── Sectors.jsx
├── Research.jsx
├── Rules.jsx
├── News.jsx
└── Scan.jsx
```
---
## Setup
### Requirements
```bash
pip3 install fastapi uvicorn yfinance ta pandas numpy tabulate rich requests python-dotenv
```
### Environment (`.env` — gitignored)
```
NEWSAPI_KEY=your_key # newsapi.org free tier — macro news
FINNHUB_KEY=your_key # finnhub.io — market data fallback
TWELVEDATA_KEY=your_key # twelvedata.com — fallback
ALPHAVANTAGE_KEY=your_key # alphavantage.co — fallback
TRADING_API_TOKEN=your_token # required for all mutation API endpoints
```
### Run backend
```bash
uvicorn api:app --reload --port 8000
# or: trading server
```
### Run frontend
```bash
cd frontend && npm install && npm run dev
# opens at http://localhost:5173
```
---
## CLI Commands
```bash
# Morning briefing — live prices, fill alerts, news, patterns, action items
trading morning
# Full web server
trading server
# Universe scan — ~350 stocks, saves top 30 to scan_results.json
python3 scan_universe.py
# Quick scan — ~150 stocks
python3 scan_universe.py --quick
# Dividend calendar
python3 dividends.py
# Earnings calendar
python3 earnings_calendar.py
# Monthly recap
python3 recap.py
python3 recap.py --month 4 --year 2026
python3 recap.py --all-time
# Market breadth
python3 breadth.py --quick
# ETF sector thesis score (5-factor, 0-100) — different from stock score
trading etf NUCL
trading etf --sector energy # all energy ETFs ranked
trading etf --sector defense
trading etf --sector ai
trading etf --all # all ETFs in knowledge base
# or direct:
python3 etf_score.py GRID
# Insider buying signals (SEC Form 4 — auto-wired into morning run + score.py)
python3 insider.py # all held tickers, 24hr cache
python3 insider.py NKE RTX NVDA # specific tickers
python3 insider.py --refresh # force refresh all (ignore cache)
# Options flow — P/C ratio, gamma walls, unusual call detection (4hr cache)
python3 options_flow.py # all held tickers
python3 options_flow.py NVDA NKE # specific tickers
python3 options_flow.py --refresh # force refresh
# News sentiment — test keyword classifier on any ticker's cached headlines
# (auto-runs inside morning_run.py — no separate CLI needed)
# news_sentiment.py is a library: classify_ticker_news(), classify_macro_pulse(), explain_big_mover()
# Spec scorer — 150pt algorithm for startup/penny/pre-FCF stocks
python3 spec_score.py BBAI # score single spec ticker
python3 spec_score.py RKLB IONQ LUNR # multiple tickers
# Score router — auto-detects spec vs regular, or force dual output
python3 score.py BBAI # auto-routes to spec_score (small cap, neg FCF)
python3 score.py NVDA # stays on regular 180pt scorer
python3 score.py RKLB --both # dual output: regular (DISQUALIFIED) + spec (STRONG)
python3 score.py RKLB --force-regular # bypass spec router, run 180pt scorer directly
# Customer concentration — SEC EDGAR 10-K top customer extraction
python3 customer_concentration.py BBAI # fetch + cache latest 10-K
python3 customer_concentration.py BBAI --refresh # force re-fetch (bypass 365d cache)
# Community signal — Reddit + YouTube tech-creator coverage + Haiku sentiment
python3 community_score.py NVDA RKLB AMD # Reddit + YouTube combined
python3 community_reddit.py NVDA --refresh # WSB / r/stocks mention search
python3 community_youtube.py NVDA --refresh # tech-creator allowlist match
# Innovation signal — arXiv research output (sparse-by-design, 35 mapped tickers)
python3 innovation_score.py GOOGL IONQ MSFT # paper volume + frontier categories
# Narrative combiner — multi-signal aggregation with pluggable mode flags
python3 narrative_score.py NVDA RKLB GOOGL --no-log # all signals layered
# Backtest — 730d historical validation, falling-knife guard testing
python3 backtest.py --full --lookback 730 --hold 60 --save
# Run test suite (311 tests — score, spec_score, router, customer, news, options, insider, cli, action_engine, community_*, innovation_*, narrative_score)
pytest tests/ -v
# Trade management (token-authenticated)
trading buy ROTH NVDA 5 500.00
trading sell ROTH NVDA 3 550.00
trading stop ROTH NVDA 470.00
trading cash ROTH 10000
```
---
## Automated Daily Scan
`scripts/com.tanmay.trading.scan.plist` — launchd job runs `scan_universe.py` at **8:30 AM MST weekdays**.
Results saved to `scan_results.json` → morning briefing shows "TODAY'S CANDIDATES" section automatically.
Install:
```bash
cp scripts/com.tanmay.trading.scan.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.tanmay.trading.scan.plist
```
---
## 180-Point Entry Algorithm
| Factor | Max Pts |
|--------|---------|
| RSI oversold (< 30 = 25pts, < 40 = 15pts) | 25 |
| MACD histogram improving | 20 |
| BB% oversold (< 20 = 20pts, < 40 = 10pts) | 20 |
| Upside to 52W high | 20 |
| Volume surge (> 1.5x avg) | 10 |
| Dividend yield > 3% | 10 |
| Relative strength vs SPY | 10 |
| Near 52W low | 5 |
| Analyst consensus | 5 |
| Low short interest | 5 |
| Below 200MA (price < 200-day MA) | 10 |
| FCF yield (≥3%=3pts, ≥5%=7pts, ≥8%=10pts) | 10 |
| Macro narrative alignment (1 theme=7, 2+=10) | 10 |
| Insider buying (Form 4 open-market purchase) | 10 |
≥70 = candidate · ≥110 = strong · ≥140 = high conviction
**Auto-disqualifiers:** Earnings < 15 days · D/E > 200 · Negative FCF · Bearish pattern detected
`scan_mode=True` converts FCF/D/E disqualifiers to score penalties for universe-wide scanning.
### Spec Scorer — 150-Point Algorithm (auto-routed for startup/penny/pre-FCF stocks)
Triggered when: `market_cap <$5B AND (negative FCF OR revenue_growth >50% OR price <$10)`
| Factor | Max Pts |
|--------|---------|
| Revenue growth YoY (>100%=25, >50%=20, >25%=15) | 25 |
| Cash runway (>12q=20, >8q=15, >4q=8, <2q=DISQUALIFY) | 20 |
| Gross margin trend (improving 3q=15, flat=8) | 15 |
| Share dilution (<5%=15, <15%=10, >50%=DISQUALIFY) | 15 |
| Insider buying (Form 4 open-market) | 15 |
| Customer concentration (DoD/hyperscaler ≥30%=10) | 10 |
| Short interest squeeze potential | 10 |
| Catalyst proximity (<30d=10, <60d=7, <90d=4) | 10 |
| Volume regime (>$50M/day=10, <$1M=penalty) | 10 |
| Sector tailwind (narrative match=10) | 10 |
| Pattern bonus (bullish reversal=10) | 10 |
≥60 = candidate · ≥90 = strong · ≥110 = high conviction
**Auto-disqualifiers:** Runway <2q · Price <$1 · Dilution >50% · Zero revenue · Earnings <15 days
Optional `next_catalyst` field in positions.json: `{"date": "2026-06-15", "type": "launch", "note": "Neutron Y"}`
---
## 13 Dashboard Pages
| Page | What It Shows |
|------|--------------|
| **Dashboard** | Portfolio totals, top movers, position breakdown |
| **Positions** | All holdings with live P&L, stops, RSI |
| **Actions** | Prioritized action items — buy/sell/hold |
| **Performance** | Equity curve, trade history |
| **Trades** | Full trade log |
| **ETFs** | Watchlist with optional live RSI fetch |
| **Intelligence** | 7 geo situations + 5 mega themes |
| **Trump** | Executive action → trade signal framework |
| **Sectors** | Allocation map, gap analysis, sector rules |
| **Research** | Intel sources by lead time, podcasts, conference calendar |
| **Rules** | 5 position types, morning protocol, investor principles, hard lessons |
| **News** | Live news feed per ticker |
| **Scan** | Universe scan results with score bars + filtering |
---
## Accounts
| Account | Type | Strategy |
|---------|------|----------|
| ROTH IRA (261356922) | Active hybrid trading | Swing (S), Long (L), Income (I) |
| Individual TOD (Z32645136) | Lifetime compounding | Lifetime holds + Spec bets |
> Account numbers and balances live in `positions.json` (gitignored).
---
## Security
- All mutation endpoints (`/api/buy`, `/api/sell`, `/api/stop`, `/api/cash`) require `X-API-Token` header
- `tracker.html` written with `chmod 600` (owner-only)
- `socket.setdefaulttimeout(12)` on all network calls — no hanging
- Sensitive files (`positions.json`, `trades_log.json`, `portfolio_history.json`) gitignored
- Git history permanently cleaned of sensitive data via `git filter-repo`
Connection Info
You Might Also Like
Vibe-Trading
Vibe-Trading: Your Personal Trading Agent
ai-berkshire
Berkshire in the AI Era: A Value Investment Research Framework Based on...
hexstrike-ai
HexStrike AI is an AI-powered MCP cybersecurity automation platform with 150+ tools.
valuecell
Valuecell is a Python project for efficient data management.
tradingview-mcp
AI-assisted TradingView chart analysis — connect Claude Code to your...
tradingview-mcp
TradingView MCP Server offers real-time market analysis for crypto and stocks.