Automated equities trading system built on Alpaca's API. Combines mean-reversion technicals, AI sentiment analysis, insider trading signals, and momentum detection with conviction-based position sizing and sector exposure guards.
An autonomous strategy agent (Claude Opus 4.6 via OpenRouter) reviews performance weekly, runs shadow experiments, and deploys validated improvements — all within hardcoded safety rails.
# Install dependencies (requires Python 3.14+)
uv sync
# Copy and fill in your API keys
cp .env.example .envRequired .env keys:
ALPACA_API_KEY/ALPACA_SECRET_KEY— from AlpacaALPACA_PAPER=true— paper trading (setfalsefor live)
Optional .env keys:
OPENROUTER_API_KEY— enables AI sentiment analysis + autonomous strategy agentFINNHUB_API_KEY— enables insider trading + earnings signals (cached, rate-limited)TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID— enables Telegram notifications
# Verify connection
uv run python scripts/portfolio.py
# Backtest mean-reversion on SPY (past year)
uv run python scripts/backtest.py --symbol SPY --days 365
# Full system backtest with trailing stops, Sharpe, drawdown
uv run python scripts/full_backtest.py
# Watchlist scan (dry run)
uv run python scripts/scan_with_sentiment.py
# Watchlist scan (execute trades)
uv run python scripts/scan_with_sentiment.py --execute
# Market-wide screener — find biggest dips across ~1,900 liquid common stocks (filtered from 12K+ assets)
uv run python scripts/screener.py --min-dip -8.0
# Auto-trade top screener picks
uv run python scripts/screener_trade.py --min-dip -7.0 --max-trades 8 --execute
# Momentum auto-trade
uv run python scripts/momentum_trade.py --min-momentum 10.0 --max-trades 5 --execute
# Manage exits for open positions
uv run python scripts/position_manager.py --execute --check-sentiment
# Launch web dashboard
uv run python scripts/dashboard.py
# Run tests
uv run python -m pytest tests/
# Strategy agent (dry run — no API key needed)
uv run python scripts/strategy_agent.py --mode weekly --dry-runAutomated via GitHub Actions (.github/workflows/daily-trading.yml), runs Mon-Fri at 6:45 AM and 12:45 PM PT:
- Position manager — manage exits for all open positions
- Screener auto-trade — find biggest dips market-wide, trade top picks
- Watchlist scan — 3-layer composite analysis on core watchlist
- Momentum auto-trade — trend-following entries on surging stocks
- Portfolio + performance — summary and signal accuracy report
- Strategy agent — lightweight event check for acute problems
An autonomous agent (scripts/strategy_agent.py) that self-improves the trading system using Claude Opus 4.6 via OpenRouter.
Weekly review (Saturdays via .github/workflows/strategy-review.yml):
- Reads performance data, changelog, and experiment results
- Diagnoses problems using structured reasoning (observe, compare, diagnose, validate, act)
- Validates changes via walk-forward backtesting with holdout Sharpe validation
- Deploys code changes or creates shadow experiments
- Max 2 deploys/week, 14-day cooling period per file
Event check (after each daily pipeline run):
- Checks for acute problems (consecutive stop-losses, drawdown spikes, low win rates)
- Evaluates active shadow experiments
- Can pause strategies (auto-expires in 3 days) but saves bigger changes for weekly review
Safety rails (hardcoded in scripts/agent_tools.py — agent cannot modify):
- Minimum sample sizes enforced (50 trades for parameters, 30 for filters)
- All tests must pass before any deploy
- Position size capped at 5% of equity
- Max-loss stop cannot be disabled
- Automatic rollback on test failure
client.py Alpaca client factory
strategies/
mean_reversion.py SMA-based mean reversion + weekly confirmation
sentiment.py AI sentiment on news (OpenRouter, Alpaca News API)
insider.py Finnhub insider trading + earnings (cached, rate-limited)
fundamentals.py Fundamental analysis (health screen + DCF + analyst estimates)
momentum.py 10d/50d momentum + volume surge
config.py Watchlist + per-stock thresholds
sizing.py Conviction-based position sizing
volatility.py ATR-based volatility for threshold normalization
sector.py Sector exposure + correlation guard (126 tickers)
signal_scorer.py Empirical signal scoring (bucket win rates)
constants.py Tunable strategy parameters (agent-modifiable)
enums.py Shared enums (Action, InsiderRecommendation, FundamentalsRecommendation)
cooldown.py Re-entry cooldown after stop-loss exits
equity_tracker.py Live equity curve tracking with drawdown and rolling Sharpe
log.py Structured logging factory (get_logger with alpaca. namespace)
regime.py Market regime detection (normal/elevated/crisis via SPY)
resilience.py API retry decorator with exponential backoff + circuit breaker
risk_guard.py Portfolio-level kill switch (daily loss + drawdown)
state_db.py SQLite trading state persistence
stop_orders.py ATR-scaled stop-loss order lifecycle
weekly_trend.py Weekly SMA trend filter (blocks severe downtrends)
scripts/
scan_with_sentiment.py 3-layer composite signal + sizing + sector guard
screener.py Market-wide screener (~1,900 liquid common stocks from 12K+ assets)
screener_trade.py Auto-trade top screener picks
momentum_trade.py Auto-trade momentum picks
position_manager.py Exit manager (trailing stop, take-profit, breakeven, cooldown)
portfolio.py CLI account dashboard
dashboard.py Flask web dashboard (port 8050)
performance.py Signal accuracy analysis
trade_logger.py CSV logging (auto-migrating headers)
notify.py macOS + Telegram notifications
backtest.py Single-ticker backtesting
full_backtest.py Full system backtest (Sharpe, drawdown)
pipeline_backtest.py Pipeline backtest with all features
param_sweep.py Parameter grid search + sensitivity analysis
strategy_agent.py Autonomous strategy agent (weekly review + event check)
agent_tools.py Agent tool definitions + safety-hardcoded dispatch
agent_reads.py Agent read/compute tools (side-effect-free observations)
agent_writes.py Agent write/deploy tools (state-mutating operations)
shadow_evaluator.py Shadow experiment evaluation
dashboard_data.py Dashboard data loading and performance computation
daily_metrics.py Daily performance metrics snapshot
drift_monitor.py Backtest-to-live drift detection with alerting
walkforward.py Walk-forward backtesting validation
daily_run.sh Local pipeline automation
account_status.py Quick account connection check
run_strategy.py Single-ticker mean-reversion analysis
momentum_screener.py Market-wide momentum screener
data/ Trading state (signals.csv, trades.csv, metrics.json)
data/agent/ Agent state (changelog, experiments, overrides)
tests/ 1,163 tests across 56 test files
# Run all tests
uv run python -m pytest tests/
# Run with verbose output
uv run python -m pytest tests/ -v
# Run a specific test file
uv run python -m pytest tests/test_agent_tools.py -vCI runs automatically on push to main and on pull requests.
- Python 3.14+ (see
pyproject.toml) - uv for dependency management
- macOS or Linux (Windows untested)
- Alpaca paper trading account (free) -- sign up at alpaca.markets
- Network access to Alpaca API, Finnhub, OpenRouter, SEC EDGAR, yfinance
- Long-only -- no short selling or options
- US equities only -- no crypto, forex, or international markets
- Single account -- no multi-account or multi-portfolio support
- PDT rules apply -- 3 day trades per 5 business days for margin accounts under $25K
- Paper trading by default -- live trading requires explicitly setting
ALPACA_PAPER=false - No real-time streaming trades -- pipeline runs on a schedule (2x/day via cron or GitHub Actions)
See RUNBOOK.md for detailed operational guidance covering 10+ failure scenarios.
Quick fixes:
- "Circuit breaker tripped" -- API failures exceeded threshold. Wait 5 minutes for auto-recovery, or remove
data/circuit_breaker.flagmanually. - "PDT limit reached" -- Day trade count at maximum. The system skips new entries automatically. Wait for older day trades to roll off (5 business days).
- "Risk guard halt" -- Daily loss or drawdown limit hit. New entries blocked until the next trading day.
- Tests fail on import -- Run
uv syncto install dependencies. - Database locked -- SQLite WAL mode handles this automatically on the next connection. If persistent, check for zombie processes.
- Missing CSV data -- The system recreates CSVs with correct headers on the next write. No manual action needed.
| Service | Free Tier | Used By |
|---|---|---|
| Alpaca | Free for paper trading | All trade scripts, data, position manager |
| Finnhub | 60 calls/min (system uses 30) | strategies/insider.py (4h in-memory cache) |
| OpenRouter | Pay-per-use (~$0.01-0.05/sentiment call) | strategies/sentiment.py, scripts/strategy_agent.py |
| SEC EDGAR | 10 req/sec (no key required) | strategies/fundamentals.py (SQLite persistent cache) |
| yfinance | Unofficial, ~2K req/hr | strategies/fundamentals.py (24h in-memory cache) |
Backtest results are not a guarantee of future performance.
- Minimum Sharpe ratio: 0.3 (enforced by strategy agent before any deploy)
- Max drawdown threshold: 8% (risk guard automatically halts new entries)
- Win rate: varies by strategy, market conditions, and signal layer combination
This project is provided as-is for educational and personal use. No license file has been added yet -- all rights reserved by the author until a license is explicitly chosen.