Every moving part of the trading desk.
Written for an experienced trader judging whether this is a sound platform: the data feeds, the deterministic ensemble, the custom signal, the scheduled legs, money management, the protection stack, the self-learning loop, execution, the data model — and an honest assessment of where the edge is and isn't proven.
Paper-only. Fully built, deployed, and running on a simulated (paper) account. Autonomous live trading is refused in code; a live book stays behind an explicit flag plus a per-order confirm. This is an engineering and risk-architecture demonstration, not investment advice or a live-money track record.
An autonomous equities advisor reads ~100 large-cap US names across five timeframes, scores each with a deterministic ensemble of four indicators (three standard plus one custom "gravity" model), folds the timeframes into one regime-aware call, sizes the trade through a risk-posture money manager, runs a layered protection stack, and places paper orders through an accountable signal → decision → order provenance chain. A separate LLM analyst leg reads news and SEC fundamentals for event-driven trades, and a daily Donchian swing sleeve runs the one edge the team's own walk-forward actually validated. Every night it scores which signals predicted and re-weights them. No randomness on the technical path: same bars in, same decision out.
Feeds in, accountable orders out.
Deterministic decision engine and an optional LLM analyst both feed one money manager, behind a protection stack, into a paper broker — every step written to a Postgres ledger that also feeds the overnight learner.
Free-tier market data, keyless fundamentals.
All market data is free-tier Alpaca IEX plus keyless SEC EDGAR — the single most consequential limitation for validation (see the assessment).
| Feed | Provides | Cadence / limit |
|---|---|---|
| Price bars | OHLC closes at 5Min / 1Hour / 1Day / 1Week / 3Month, split & dividend adjusted | One batched request per timeframe for the whole universe |
| Latest trade | Last IEX trade price — entry/exit reference, prediction resolution | Per symbol |
| News | Symbol-tagged headlines + summaries | Freshness window: 20 min (research) / 3 min (fast) |
| Clock + calendar | Session detection, weekend/holiday aware | Cached per day |
| Fundamentals | SEC EDGAR XBRL — latest-annual revenue + net income → YoY growth, net margin | Keyless; ticker→CIK map cached |
| World intelligence | Per-ticker sentiment, insider & congress buy/sell, short interest, mention velocity, event flags | 30-day lookback, continuously refreshed |
IEX is a single (~2–3% of consolidated volume) feed, not SIP — fine for a daily/regime strategy, not a microstructure-grade feed, and the system says so.
Six legs on a per-user cron.
All are per-user Redis cron schedules on the shared agent scheduler, running in the controller with no user session. Only the research/fast legs call an LLM; everything else is pure deterministic code.
| Leg | Cron | Trades? | What it does |
|---|---|---|---|
| Autopilot | every 5m | yes | MTF scan → exits, rotation, conviction-sized entries |
| Research | every 15m | yes | News (≤20 min) + EDGAR → LLM analyst → sized trade |
| Fast | every 2m | yes | Same, but only ≤3-min-old headlines |
| Swing | daily | yes | Daily Donchian breakout/exit on commodity-trend ETFs, held across days |
| Assess | every 2h | no | Writes next-session predictions + a ranked plan |
| Review | 06:30 UTC | no | Resolves matured predictions → learns per-signal mass |
One autopilot fire, step by step
Reconcile → guard equity → protective exits → multi-timeframe scan → gated, conviction-sized entries → persist provenance. The validated edge — a daily Donchian trend sleeve on commodity ETFs — runs as a separate, deliberately low-churn leg.
Four indicators, one reproducible vote.
All four are pure functions of a close series; an indicator returns nothing when it has no opinion, so it only votes when it fires. Three are textbook; "gravity" is the custom one.
| Indicator | Type | Fires when | Notes |
|---|---|---|---|
| momentum | trend | always (close vs SMA20) | The always-on trend vote; fast-scaling |
| donchian | breakout | close breaks prior 20-bar high/low | Classic channel breakout; flat 0.7 confidence, no volume filter |
| meanrev | mean-reversion | RSI-14 < 35 or > 65 | Bespoke simple-average RSI |
| gravity | custom composite | net displacement clears a threshold | Trend + index pull + vol-shock + contrarian mean-reversion, each fading on its own half-life |
A single confidence-weighted vote: each firing indicator casts ±1 × its confidence × its overnight-learned weight; the normalized signed agreement decides buy / hold / sell with a dead-band that resolves weak agreement to hold. The weight is the learned "mass" (default 1.0 = raw engine).
The regime gate is the primary risk control.
Each name is scored by the same ensemble at five timeframes, combined with fixed weights that favour the longer, higher-conviction trends. A buy is allowed only when the weekly/quarterly regime is not bearish — the bot never fights the higher timeframe.
Combined score must clear ±0.2 or it's a hold; the regime must agree. A held name decisively selling on both 5Min and 1Hour is protectively exited even when the regime is still up.
A risk posture sets every dial.
A pure, deterministic layer above signal generation. All caps are of account equity. The deployed active posture is a "many small positions, minimize downside, high turnover" mandate.
| Posture | Per name | Max names | Stop | Take-profit | Daily-loss halt | Max drawdown |
|---|---|---|---|---|---|---|
| conservative | 3% | 12 | 5% | 12% | 2% | 8% |
| balanced (code default) | 5% | 16 | 9% | 20% | 4% | 12% |
| aggressive | 10% | 12 | 15% | 35% | 7% | 25% |
| active (deployed) | 3% | 32 | 5% | 8% | 3% | 10% |
Sizing scales position by conviction and normalizes high-volatility names down (with a floor). Exits run in priority order each fire: hard stop / take-profit → trailing → cap-trim → short-TF breakdown → rotation bench.
Eight independent layers, in escalation order.
The daily-loss halt (intraday open P&L, resets) and the drawdown breaker (a persistent equity high-water-mark in its own table) are distinct, and both halt new entries only — exits always run.
It re-weights its own signals nightly.
The overnight review resolves matured predictions and tunes each indicator's weight by its predictive edge — shrunk toward 1.0 by sample size so a lucky handful can't over-tilt. No data → mass 1.0 → raw engine.
An indicator is only learned from after a minimum sample count. The system is honest that today this learns direction hit-rate, not P&L expectancy — an opt-in expectancy mode is wired but off by default.
No order without a logged reason.
Every order is required by the route to carry a persisted decision, which references a signal — the signal → decision → order invariant. The broker adapter only executes; justification is enforced upstream.
Paper and live are separate adapter instances pointed at physically different accounts — not a flag. Idempotent client order ids prevent double-placement; off-hours orders convert to marketable limits.
The honest part.
The engineering is sound and the risk framework is genuinely defensive. The alpha is unproven. We'd rather say that plainly than oversell it.
Deterministic, reproducible, auditable — every order chains back to a logged signal and rationale. A real, multi-layer risk architecture, not cosmetic. Production-grade provenance, dual-book separation, and idempotency. Sensible self-tuning weights. And intellectual honesty about edge: the team carved the one validated trend edge into its own low-churn sleeve rather than pretending the intraday autopilot is the proven money-maker.
Validated only on ~7 months of free daily history, one regime, no slippage or commission — a logic/risk sanity check, not an edge claim. The deployed active posture was the worst performer in that single window (turnover eats the edge). Learning targets hit-rate, not expectancy. Confidence scales aren't calibrated across indicators. Breakouts have no volume confirmation.
Bottom line. Treat it as a well-built, well-guarded paper research platform, not a validated money-maker. The concrete unlock is a paid multi-regime history feed to honestly test cost-aware, expectancy-based performance. Fixes for the expectancy and recency gaps are already wired as opt-in flags, off by default, so the assessment above stands until they're enabled.
Want to walk the code?
Happy to go feed-by-feed, indicator-by-indicator, or through the provenance chain and the ledger schema.