What is being built, for whom
A fully systematic monthly equity screener for a single user (Ola) running a £2,000 ring-fenced Trading 212 SIPP. It selects 12 UK/US stocks by frozen value/quality/momentum rules, prints an order sheet, and produces a monthly report (“the Paper”). Execution is manual in the T212 app: no SIPP API exists, and the no-override rule wants human hands on the orders anyway.
The year-one product is the record, not the P&L: proof the system ran exactly as written, every month, with every deviation impossible or logged.
Goals & success criteria
| Horizon | Goal | Measured by |
|---|---|---|
| Build → 1 Aug 2026 | M1–M6 complete, tests green, dry run eyeballed | pytest suite · Ola sign-off on the M6 funnel + sheet |
| Phase A (cycles 1–3) | 3 clean paper cycles | full screen → sheet → Paper monthly, £0 at risk |
| Phase B (£1,000) | compliance intact | every sheet order executed, nothing added, fills logged |
| Phase C (£2,000) | entered only after 6 compliant live cycles | violations.md still empty |
| 2029 verdict | beat WLDS net of costs over 36 live months, or retire | the Paper’s cumulative record, reviewed per market regime |
Constraints: constitutional, not negotiable
The sheet is executed as printed
Nothing skipped, nothing added, no “just this once”. Temptations get written down, not acted on.
£2,000 maximum, ever
Top-ups only on a pre-written schedule; an unscheduled deposit after a red month is itself a violation.
§4 untouchable until 2027-07-22
Checksummed; the one pre-Cycle-1 calibration pass (data-field substitutions only) was used and closed: see docs/field-mapping.md.
£0 budget · no look-ahead · fail closed
Free sources only in Phase A. Screens use only data timestamped on or before the screen date, enforced at the fetch layer. Missing data excludes a name, never passes it. Same inputs → same sheet, always.
Functional requirements by milestone
| # | Deliverable | Accepted when | Status |
|---|---|---|---|
| M1 | Config loader + checksum alarm; TV/YF clients; snapshot archiver; field mapping | tamper test red/green; live pulls verified | DONE |
| M2 | §4.1–4.4 gates as pure functions; edge fixtures; honest dry run | two external reviews taken; calibration approved by Ola | DONE |
| M3 | Composite ranking; hold buffer (≤25 AND >200-DMA); portfolio state machine | boundary fixtures green; three-round external review; penny-exact reconciliation | DONE |
| M4 | Order-sheet generator + fills logger; funnel with reason-code counts; md + HTML | two-round external review; crash-safe fills ordering | DONE |
| M5 | The Paper from the template, incl. weather block | golden-file match; weather provably isolated; compliance both directions | DONE |
| M6 | Full dry run on live data → Cycle 1 | Ola eyeballs funnel + sheet; final calibration checksum recorded only after · Saturday leg complete 25 Jul; Monday leg, sign-off, checksum remain | IN PROGRESS |
Outputs & consumption
Canonical record: reports/YYYY-MM/funnel.md · order-sheet.md · paper.md: plain markdown, git-diffable; the audit trail. Human surface: each cycle also renders as HTML pages in this site’s style: funnel with reason-code counts, the order sheet, the Paper, and per-stock cards (business one-liner + the exact per-gate numbers).
Hosting: the repo lives at a private GitHub remote; the site deploys to Vercel so screen Saturdays are phone-readable. The deployment must be access-protected: it contains a live personal portfolio. The publish pipeline is a small M6-era task, never allowed to delay a milestone. Scheduling: the Saturday screen may fire automatically; the in-app availability check and Monday execution remain human by construction.
Non-goals
No watchlists, ideas, or discretionary tooling. No chart or technical-analysis inputs. No backtest research: backtests only ever verify machinery, never justify parameters. No intramonth monitoring or alerts. No paid data in Phase A. No performance-chasing UI: the Paper reports; it does not tempt.
Open items
| FINAL calibration checksum: recorded once, after Ola eyeballs the M6 dry-run outputs | M6 gate |
| NASDAQ:IMPP EV/EBIT: rehearsal verdict — not a data quirk. Net cash ≈ market cap, so EV collapses to ~$0.2m vs $57.7m EBIT (EV/EBIT 0.0039, value rank 100). Awaiting owner verdict before the final checksum | M6 |
| Negative-EV ranking behaviour: recorded in docs/amendments.md, watch only | 2027 window |