Paper-trading experiment that mirrors Jim Cramer's publicly disclosed stock signals with a virtual $25,000, executed against Alpaca's paper account, dashboarded on Netlify, and benchmarked against just holding SPY at end-of-week.
Governed by
CHARTER_v0.1.md. Read that first. Everything in this codebase enforces the seatbelts in §4. The live-money gate in §7 is not crossable from code.
Cramer Trades/
├── CHARTER_v0.1.md ← the constitution (paper-first, public-only, kill switch, etc.)
├── README.md ← this file
├── .env.example ← env template — fill it in, never commit
├── firebase_rules_snippet.json ← MERGE this into your existing rules (don't replace)
├── backend/
│ ├── config.py ← all tunables; signal sources config-driven
│ ├── signals.py ← Cramer + analyst + congress + 13F pullers (public-only)
│ ├── alpaca_client.py ← paper-only client; asserts paper endpoint
│ ├── strategy.py ← decision engine + seatbelts (charter §4)
│ ├── firebase_client.py ← REST writes under /cramerMirror
│ ├── digest.py ← end-of-day digest + optional email
│ ├── main.py ← FastAPI app + autonomous 4×/hr loop
│ ├── report.py ← end-of-week SPY benchmark
│ └── requirements.txt
└── frontend/
├── index.html ← Netlify dashboard
└── netlify.toml
- Generate Alpaca paper keys at https://app.alpaca.markets/paper/dashboard/overview. Paste the paper key id + secret into your local
.env(copy from.env.example). The system never accepts keys at runtime. - Sign up for the public signal feeds you want enabled:
- StockNewsAPI →
STOCKNEWS_API_KEY(Cramer mentions w/ sentiment). Public API, no paywalled scraping. - Finnhub →
FINNHUB_API_KEY(analyst up/downgrades). Free public tier. - Quiver →
QUIVER_API_KEY(congressional trades). Optional, off by default.
- StockNewsAPI →
- Firebase: open
firebase_rules_snippet.jsonand merge itscramerMirrorblock into your existing rules. Never replace the whole file. - Install + run the backend on the always-on Mac mini:
The autonomous loop starts on app boot and runs every 900,000 ms (4×/hr, charter §2).
cd "Cramer Trades/backend" python3 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt set -a; source ../.env; set +a TZ=America/New_York uvicorn backend.main:app --host 0.0.0.0 --port 8000
- Deploy the dashboard to Netlify: point the site at
frontend/. Editnetlify.tomlto proxy/api/*to your Mac mini tunnel (Cloudflare Tunnel, Tailscale Funnel, ngrok, etc.). In production setwindow.CM_API_BASE = "/api"via a small inline snippet or env-injected build step.
Every 15 minutes (4×/hr cap):
- Pull all enabled public signal sources → normalize into
Signalobjects. - Aggregate per ticker → net BUY/SELL score.
- Evaluate seatbelts against current Alpaca paper account (drawdown, daily-loss, trade-cap).
- If kill switch is up → only sells go through. Buys are skipped and the dashboard shows the reason.
- Otherwise, place up to 5 trades/day, equal-weight ~$2,500 each, capped at 10% of portfolio, only on names ≥ $5 and ≥ 500k avg daily volume.
- Push positions, seatbelt state, signal feed, and trade log to Firebase under
/cramerMirror/.... - At 16:05 ET, write the EOD digest to
digests/{date}and (if SMTP configured) email it.
TZ=America/New_York python -m backend.report --start 2026-05-26 --end 2026-05-30 --out report.jsonOutput states the result plainly. If Cramer Mirror trailed SPY, the verdict says so — that's the whole point of running the experiment.
- Touch the live endpoint.
AlpacaPaperClientraisesPaperGateViolationunlessALPACA_LIVE_GATE_CLEARED=trueANDconfirm_live=Trueare both set. Default is paper. - Short, margin, options, leverage.
submit_market_orderassertsside in ("buy", "sell")only; nothing in the strategy emits anything else. - Trade below the liquidity floor.
_passes_liquidityblocks anything under $5 or under 500k avg volume. - Accept keys at runtime. Everything comes from env. There's no endpoint that takes keys.
- Scrape paywalled sources. All signal pullers point at public APIs only (charter §4.2).
Don't. Not yet. When all four conditions in CHARTER_v0.1.md §7 are met:
- Bump the charter to v0.2 with the new parameters documented.
- Set
ALPACA_LIVE_GATE_CLEARED=truein env. - Update the client construction site to pass
confirm_live=True. - Start with a small live slice of the $25k, not the whole thing.
The code requires both flags simultaneously specifically so a single accidental env flip can't move you live.