Why build it
Sentinel started in June 2026 with a look at a copy-trading service that mirrors a portfolio run by Claude. It had about two months of history, price slippage built into how copy-trading works, and fees that eat into small balances. Building a scanner from scratch meant full control over the rules and a clear reason behind every alert.
Ground rules
- Notify only. Sentinel recommends; every trade is placed by hand. The brokerage keys are paper-trading keys, which can’t place real orders.
- Backtest first. Every signal is tested on data it wasn’t tuned on before it gets any weight.
- Explain every call. Each alert shows which triggers fired and why.
Architecture
- Hardware: the same Intel N100 mini PC that runs the rest of the home lab. Everything runs natively, not in Docker, under a service supervisor.
- Engine: Python for the scanner, signals, scoring, verdicts, and backtester, served through FastAPI.
- Dashboard: Next.js and TypeScript, styled after Bloomberg terminals (amber on black).
- Contract: the engine writes to a SQLite database and pushes live updates over a WebSocket; the dashboard only reads. Either side can change without breaking the other.
- Data: Alpaca market data, with yfinance as a backup.
- Rationale: a local AI model, running through Ollama, writes the plain-English explanation.
- Alerts: MQTT messages to Home Assistant, pushed to the phone through the Companion app.
- Build process: about a dozen written build briefs, each carried out by Claude Code on the mini PC over SSH.
V1 features
- Market overview home page: indices, market breadth, top movers, and a system status bar
- Trigger matrix, a weighted score for each stock, and a verdict column
- Automatic support and resistance levels drawn on charts
- Backtest panel and sortable screener tabs
- Market context: seasonal patterns, triple-witching dates (adjusted for holidays), and Fed meeting dates
- A trigger history heatmap for each stock, and a scatter view of opportunities across the universe
- Hover definitions for every signal
What the backtests showed
Signals were tested one at a time, with walk-forward testing across 13 time periods.
- Kept at full weight: relative strength, 12-month momentum, trend above the 200-day average, proximity to the 52-week high, low volatility, and gaps.
- Kept at partial weight: MACD and support/resistance.
- Set to zero (no edge): RSI, volume spikes, breakouts, moving-average crossovers, and squeeze setups.
The only combination that held up was strong 12-month momentum paired with low volatility. It was positive in 10 of 13 periods but beat the S&P 500 in only 3, so its performance depends on market conditions. A filter that only allowed trades while the S&P 500 was above its 200-day average made one bad period worse, not better, and short selling is off by default.
Fixes along the way
- Scoring: the first formula could give a stock a perfect 100 from a single signal. The score now counts how many independent signal families agree, so one family alone caps at 70. The “Broad” tab shows only stocks scoring 75 or higher.
- Dashboard stability: building the dashboard in the same folder as the running copy corrupted it. That’s now a hard rule.
- Data source: when the data source setting was missing at startup, the dashboard quietly showed 40 mock stocks instead of the real universe.
Current work: Radar V2
Radar V2 is in beta. It tracks setups before they trigger:
- Watchlists and price alerts
- Upcoming trades scanner: shows how many of each strategy’s entry conditions are met, and how that changed since the morning check
- Closest gap: the one unmet condition nearest to firing, labeled “nearly there” when it’s very close
- Detail drawer: a breakdown of every entry condition, the last seven checks, and notes
- Manual overrides: promote, flag, or retire a strategy
- Filtering: by sector, with sortable columns, and a flag for stocks covered by more than one strategy
A personal project, not financial advice.