Multi-asset algorithmic trading platform · Python + NautilusTrader · solo-built, agent-operated

Nautilus Algo

A trading system that treats finding an edge as a falsification problem.

Nautilus Algo collects chart-pattern signals from vendors and its own scanners, forces every one through the same statistical arming gate, executes them on a paper book, and grades itself every morning with 81 automated health checks. Most of the strategies it has tested did not survive. The machinery that retired them is the product.

mv2a/nautilus-algo
MODE paper PRIMARY Linux host · replica on the GPU host DAY 215 since first paper trade PF 1.55 canonical · 1.13 pct-weighted LIVE TRADING not yet enabled AS OF 2026-09-07

Canonical profit factor

1.55

unique-signal, 249 trades paper

Closed paper trades

351

88 voided, 103 W / 154 L since 2026-02-04

Commits in nine months

2,197

one author, 2025-12-31 to 2026-09-07

Test functions

10.3K

620 files, last full run 10,772 passed / 0 failed

Daily health checks

81

one script, 100 dated standup reports

Strategies retired on evidence

5

RSI(2) 4H, ORB, VWAP, Fibonacci, v2 TP calibration

01 · The project

What it is and what it is for

README.md · CLAUDE.mddocs/MONETIZATION_ROADMAP.md

Nautilus Algo started on 2025-12-31 as a Python port of an MQL5 forex news-straddle strategy called News Surfer. Over nine months and roughly 249,000 lines of Python it became a multi-asset platform: stocks, ETFs, crypto, forex, indices and metals, running on NautilusTrader with a PostgreSQL source of truth, GPU-accelerated validation, a local fine-tuned LLM, a Telegram operator bot and 26 dashboard views.

The stated goal has been the same since January 2026: go live with validated strategies, through a staged capital plan that starts small and scales only on evidence, and later publish a public track record as a signal provider. Neither has happened yet. Every profit factor on this page is a paper-trading number. The only real-money contact so far was a small brokerage exposure in January 2026 that exposed an exit-logic bug, and a funded live broker account that the pipeline has not yet been allowed to trade.

What did happen is the harder part. The project built a validation gate, a measurement apparatus and an operations layer strong enough to catch itself being wrong, repeatedly, and to publish the corrections. Reported profit factor fell from 22 in April to 1.55 in September, not because markets changed but because duplicate fills, phantom entries, double-counted losses and look-ahead bias were found and stripped out one by one.

The system is operated day to day by AI coding agents working inside a constitution (CLAUDE.md) of dated hard-stop rules, a spec pipeline with on-disk approval gates, and a morning standup script whose findings must all be dispositioned before a session may end.

02 · Architecture

From signal to trade to lesson

automation/ · backtesting/scripts/standup_health.py

One loop, seven stages. Signals enter from vendors and scanners, are scored and sized by one graduated armer, traded on a paper book by a five-minute engine, exited by walking real bars, recorded with seventeen outcome dimensions, and fed back into the arming weights. A separate weekly and monthly loop re-validates everything on the GPU and disarms what has decayed.

1 · collect

Signal intake

Autochartist patterns (FX, indices, metals, commodities) via the IC Markets JSON API and Trading Central US-equity patterns, both through a fail-closed UK VPN container. Internal scanners: Fibonacci forward-test, S/R prediction, 15 day-trading detectors.

automation/external_signals · automation/fibonacci · automation/signals/sources
2 · score & arm

Graduated arming

Every source implements one protocol. A six-factor score (pattern history 35%, confluence, regime, R:R, live feedback 20%, LLM 0%) maps to five levels: display, paper, micro 0.25×, small 0.5×, standard 1×. Three blocklists reject before scoring.

automation/signals/arming.py · autochartist_scorer.py · protocols.py
3 · execute

Six execution gates

A 5-minute engine rebuilds its position cache from PostgreSQL, fetches a fresh price, rejects drift over 1%, re-validates TP/SL side, enforces executed R:R ≥ 1.0, dedups and caps concurrency, then routes to a broker adapter. Paper by default.

multi_strategy_engine.py · trades/trade_service.py · brokers/
4 · exit

Bar-walked exits

TP, SL, breakeven and trailing stops are detected by walking daily bars from entry, the same routine the outcome evaluator uses. 120-hour expiry. Voided trades carry one of 13 frozen exit reasons and never enter win/loss math.

trades/trade_monitor.py · trades/trailing_stop.py · void_reasons.py
5 · record

Outcome ledger

PostgreSQL 16 holds trades, all signals in one JSONB table, arming decisions, outcomes and strategy adaptations. Streaming replica on the second host, 6-hourly magic-byte-validated dumps.

automation/database/models.py · migrations/postgres/
6 · learn

Statistical feedback

Rolling per-(source, symbol, direction) hit rates, a 3-stop-losses-in-7-days demotion, Bonferroni-corrected 7d-vs-90d trend tests, regime profiles, and RandomForest factor attribution that may move a weight at most 10 points a week.

automation/intelligence/ · automation/learning/
7 · revalidate

GPU revalidation

Weekly: every armed strategy, 1,000 Monte Carlo permutations, auto-disarm below the 85th percentile. Monthly: the whole population with checkpoint and resume. A missing heartbeat is an error, not a first run.

backtesting/gpu_revalidation.py · monte_carlo.py · scripts/weekly_arm_revalidation.py

Where it runs

Linux hostactive primary
  • Linux. PostgreSQL 16 primary and the trading engine, holder of the PG advisory leader lock.
  • NordVPN container with a dedicated UK egress IP; ac-collector and tc-collector share its network namespace.
  • Jenkins deploy target since 2026-06-22. Qdrant for the Sensei knowledge base.
Windows + WSL2 GPU hostwarm standby
  • Windows 11 + WSL2. RTX 5070 Ti 16 GB for Monte Carlo revalidation and Ollama inference.
  • PostgreSQL streaming replica; engine idles with ENGINE_ENABLED=0 until a confirmed manual promotion.
  • Watchdogs for GPU loss, power posture and WSL boot; recovered by a four-phase post-reboot script.

Both are consumer machines in a home rack. Failover is deliberately manual to avoid a split-brain double fill. Exactly one engine can trade against the primary at a time, and mirrored crontabs run each job once through an active-host guard.

03 · Validation

Nothing trades until it beats chance

backtesting/monte_carlo.pymigrations/backtest_results/005_*.sql

The arming gate is the load-bearing idea. A strategy configuration may only be armed when a corrected Monte Carlo test shows its entry timing beats at least 85% of 1,000 random permutations of its own trades, on at least 20 trades, with a 70/30 walk-forward overfit ratio of 0.8 or better. The same rule is enforced five ways.

CriterionThresholdEnforced by
Monte Carlo percentile≥ 85SQLite trigger prevent_invalid_arming on UPDATE and INSERT; rejects the 50.0 and 0.0 placeholders
Simulations1,000Shared monte_carlo.py with compounding, 0.1% commission per side, seed 42; 10,000 × 5 seeds for server-side arming
Resolved trades≥ 20Trigger + engine filter + weekly cron auto-disarm
Walk-forward overfit ratio≥ 0.870/30 split, validate_armed_configs_lib.py
Where it runsserverDefinition of Done requires pasted SSH output from a real GPURevalidator run; local approximations do not count
Position size by confidenceT3 / T2 / T1MC ≥ 95% trades at 100%; 90 to 95% at 50%; 85 to 90% paper only

Each rule exists because of a dated failure. Five RSI(2) strategies with backtest Sharpe ratios above 24 on fewer than 20 trades collapsed to Sharpe −5 to −38 under proper validation on 2026-01-25. On 2026-04-11 eighteen configurations armed from simplified local detectors all failed when re-run on the server. Two days later a slippage unit bug was found to be charging 5% per trade instead of 0.05%. On 2026-07-16 the entire 13-row armed catalogue on the active host turned out to be test-fixture debris and was purged. The honest count of armed internal strategies today is zero, and the trading book is made entirely of external pattern signals.

Research follows the same discipline. The Fibonacci redesign froze four hypotheses and a control in a YAML file before any backtest ran. When the first sweep produced a profit factor of 172 the harness was debugged, not celebrated: it had look-ahead entry at an unconfirmed pivot and no horizon cap. The corrected control scored PF 0.85. A follow-up study of 99,847 trades across 433 configurations, 71 symbols and 5 timeframes found 2 survivors where about 22 would be expected by chance. The strategy was retired.

04 · Capabilities

Seven subsystems

≈249K lines of Python354 modules in automation/
automation/external_signals · automation/signals

Signal factory

Vendor feeds and in-house detectors are indistinguishable to the armer: one frozen dataclass, one runtime-checked protocol, one registry that throws on non-compliance.

  • Autochartist priors derive from six years and 211,779 vendor patterns; live per-pattern hit rates re-tier weekly and fail open.
  • Seven chart patterns, all metal cross-rates and four (symbol, direction) pairs are hard-blocked; a standup check discovers new 0%-win combos and prints the tuple to add.
  • Trading Central US-equity patterns start at graduated size and cannot be bumped before 30 resolved trades and PF ≥ 1.75.
  • Two-way state machines (market probe, never-winner) arm at zero size so a market can re-earn sizing instead of being blocked forever.
≈60 signals per weekday collected, 2,899 total as of 2026-09-07
automation/multi_strategy_engine.py · automation/trades

Execution engine

A 5,390-line daemon where PostgreSQL is the only truth. Its in-memory positions are rebuilt from the database every cycle and swapped atomically; a failed rebuild skips the cycle and pages Telegram rather than trading on stale state.

  • Six execution-time gates after Spec 011 found fifteen paper trades that "hit take-profit" within six seconds of entry off stale snapshot prices.
  • Realistic-execution correction restated historical paper P&L 42% lower ($20,451 → $11,832) rather than hiding it.
  • Five broker adapters behind one interface: paper, Interactive Brokers, Robinhood, OANDA demo, IBKR demo. Exits route to the broker recorded on the trade.
  • Path-to-live is code: seven stages from PAPER to LIVE_FULL, 30 gate evaluators, a hysteresis promoter, a $500 notional cap and a two-of-two approval before any live stage.
Fail-loud startup: exit 2 without PostgreSQL, exit 3 if another engine holds the leader lock
backtesting/ · scripts/*_revalidation.py

GPU validation lab

81 modules and 41,660 lines that decide which of several hundred strategy × symbol configurations may trade, and keep re-deciding as markets drift.

  • CuPy batch indicators for 100 symbols × 10 years in single array operations; automatic NumPy fallback when the card is over 80% busy.
  • 119 Bollinger strategies × 1,000 Monte Carlo runs in about 13 minutes on the RTX 5070 Ti.
  • Deterministic verdicts: after a seeded test flipped from the 88.8th to the 4.1st percentile on a yfinance download 20 minutes later, the still-forming bar is dropped and symbols with under 90% history are gated.
  • A seeded 500-trade golden ledger in CI replays the 50× slippage bug; if the guard stops biting, the build fails.
Real NautilusTrader engine, proven by tests that check the BacktestEngine is the genuine Cython class
scripts/standup_health.py · automation/oversight · Jenkinsfile

Operations that fail loud

Every outage became an executable check. The standup script grew from 21 checks in February to 81 by September, each with its silent-failure mode and a one-line fix command.

  • Funnel invariants, not bug patches: "fresh pending signals but zero armed in 24 hours" is one check that caught three unrelated root causes.
  • A loop-liveness registry declares every recurring job's artifact and cadence, so a cron never provisioned on a failover host is detected generically.
  • Jenkins refuses to call a deploy successful unless the engine container was actually recreated, is not crash-looping, and PostgreSQL was never touched.
  • Deploying code by rsync is banned after a 35 GB model sync over a phone hotspot and repeated schema drift.
13-stage pipeline · 21-entry crontab registry · 36 registered scheduled tasks visible in Telegram
automation/database · migrations/postgres

Data layer rebuilt under fire

Ten scattered SQLite files became a streaming-replicated PostgreSQL source of truth through flag-gated, parity-verified cutovers, after a filesystem wipe destroyed every scanner database while PostgreSQL survived.

  • Six-step reversible cutover per source: migrate, dual-write, 24-hour parity soak, flip readers, stop writes, delete. Eighteen env flags, 247 new tests.
  • One unified signals table with JSONB metadata and a GIN index; trades and outcomes reference it regardless of source.
  • Backups are validated by size and magic bytes before publication, after a 0-byte dump hid a regression for 67 days.
  • Parquet bar store for about 220 symbols, Dukascopy tick data for news windows, a provider-chain price fetcher that records which feed served each request.
11 PostgreSQL migrations · 17 SQLite migrations · replication lag thresholds checked every standup
automation/ai · automation/sensei · automation/intelligence

An AI layer that earned the bench

A locally fine-tuned Mistral-7B runs on the GPU behind a hard grounding gate: an LLM call without fetched headlines raises an error. The model's measured lift on trade outcomes was 0.84× to 0.92×, so its arming weight is 0% until it clears a 60% accuracy gate on 30 predictions.

  • 907 audited LLM calls between January and July 2026, 98.7% grounding-verified, each written to a JSONL audit trail.
  • Sensei, a Qdrant RAG advisor over 1,116 chunks of the team's own validated and rejected research, answers methodology questions and picks TP/SL methods for unknown patterns.
  • What actually moves weights is classical: z-tests with Bonferroni correction across 121 combos, hysteresis-gated degradation, RandomForest attribution bounded 5 to 50%.
  • The trade reviewer cross-checks Ollama's VRAM claim against nvidia-smi after the runtime was caught reporting GPU use while running on CPU.
Two LoRA fine-tunes: financial-mistral-gpu (fundamentals) and sensei-quant (methodology), 20 minutes on Blackwell
ui/ · agent/src/webhook_server.py · .claude/skills

Operator surfaces

One operator, four channels, wired so the same profit-factor number appears on the dashboard, in Telegram and in the published statement.

  • A Streamlit hub routing 26 views behind an nginx portal; switching to live mode repaints every dashboard red with a fixed "REAL MONEY AT RISK" banner and forces confirmation on live actions.
  • A Telegram bot with 59 commands, from /positions and /armed to /sensei, /ha and an emergency /close_all, plus a /schedule menu generated from the task registry.
  • Machine-generated standup reports every trading day (100 so far), per-source status reports, and 7,376 auto-rendered candlestick charts of armed and resolved signals.
  • Operator workflows are Claude Code skills and hooks, not prose: /standup, /fibo, /autochartist, /profit-factor each run a server-side script on whichever host is active.
05 · Track record

Seven months on paper, honestly

docs/PATH_TO_LIVE/*-standup.mdas of 2026-09-07paper only

The canonical public number is the Spec 024 unique-signal profit factor: voided trades excluded, duplicate re-entries collapsed. It has fallen from 3.9 in April to 1.55 in September. Roughly half of that fall is measurement correction, the other half is genuine underperformance of the low risk-to-reward trades taken before the R:R fix.

Canonical profit factor, as reported by each daily standup

Spec 024 unique-signal basis · 2026-04-17 to 2026-09-07 · gap in May and June: no standup reports were produced during the host outage

Annotation: on 2026-07-22 and 07-24 the void filter was applied to the canonical surface (PRs #158, #164). The flat segment from 08-08 to 08-26 is a period with no closed trades: IC Markets collection had stopped and the engine hung for eleven days on a network call without a timeout, fixed 2026-08-25.

Profit factor by designed risk-to-reward cohort

All closed, non-void paper trades since 2026-02-04

Trades designed with R:R below 2.5 lost money as a group. The cohort designed at 2.5 or better, mostly taken after the arming fix, is profitable at PF 2.09 on 67 trades. The split is by designed ratio, not by date; a few low-R:R trades were still taken in September.

Ledger, 2026-09-07Value
First paper trade2026-02-04
Total / closed / open390 / 351 / 1
Voided (13 exit reasons)88
Wins / losses103 / 154
Win rate40.1%
Avg win / avg loss (raw %)+0.82 / −0.48
PF, percent-weighted1.13
PF, USD-weighted raw1.35
PF, canonical unique-signal1.55
Signal mix, last 50 trades41 AC · 6 TC · 3 FIB

Why three profit factors

The standup prints all three on purpose. The percent-weighted figure treats every trade equally. The USD-weighted figure reflects position sizing. The unique-signal figure additionally collapses the 3.1% of trades that were duplicate re-entries on the same setup, and is the number the signal-provider spec is contractually pinned to. Showing them together makes duplicate and sizing effects visible rather than letting one flattering definition stand alone.

06 · What failed

Each failure became a guard

docs/bugs/ (21) · docs/incidents/ (6)CLAUDE.md hard stops (17)
  • 2026-01-25disarmed
    RSI(2) mean reversion, Sharpe 25

    Five configurations with 86 to 100% win rates on 15 to 19 trades collapsed to Sharpe −5 to −38 when validated. Small samples, no Monte Carlo.

    MC ≥ 85 on 1,000 sims, ≥ 20 trades, enforced by a database trigger.
  • 2026-01-20disarmed
    4-hour RSI(2) + VIX filter

    Average Monte Carlo percentile 30.1 across five symbols, worse than random. The daily version of the same idea passed at the 90th to 97th percentile.

    Timeframe is part of the hypothesis; each is validated separately.
  • 2026-04-09restated
    Instant fills inflated paper P&L by 42%

    Fifteen Fibonacci paper trades closed within six seconds of entry off stale snapshot prices. 45 historical artifacts worth $8,618 were flagged.

    Fresh price at fill, 1% drift rejection, bar-walked exits, five-minute minimum hold.
  • 2026-04-25corrected
    Losses double-counted (Bug A + Bug B)

    An OR between two P&L columns landed trades in both wins and losses, and voided trades were not filtered. 66 reported losses were 35 real ones.

    A CI regex scan for the banned pattern, a runtime assertion, and standup check [16e].
  • 2026-05-12disabled
    Autochartist v2 take-profit calibration

    Tightening targets to 0.75 of historical average win degraded PF from 1.83 to 1.65 over 37 trades. Disabling it produced 14 trades in 48 hours at PF 2.41.

    Default off, requires the exact string "1", pinned by a TDD test.
  • 2026-05-19data lost
    Sixteen silent days, then a wipe

    SSH to the production host broke for about 16 days; 16 nights of 0-byte backups passed an age-only check. Recovery re-registered WSL and erased the database, volumes and 35 GB of models. Five days of trades were never recovered.

    Magic-byte backup validation, restic freshness checks, a second host as streaming replica.
  • 2026-04-16reverted
    Regime gate with +70% PF was look-ahead bias

    Same-day regime classification showed +70%. Shifting by one bar showed −3.9%; a real-bar backtest on 33 symbols showed −7.8%. Reverted the same day.

    Mandatory shift(1) on regime inputs; the lesson is written into the spec.
  • 2026-07-04retired
    Fibonacci retracement strategy

    Headline hit rate 66.9% became 6.0% once entries had to actually touch the level: 276 of 278 recorded wins were phantom fills. Zero of four pre-registered redesign hypotheses cleared the gates.

    Entry-touch gate; continues only as a frozen paper forward-test with auto-retire at PF < 1.0.
  • 2026-07-16revived
    Two learning loops dead for 2.5 months

    After the PostgreSQL cutover, the adaptive-weights cron kept reading an empty SQLite table and "trained" on nothing while standup stayed green. Execution analytics had been an empty list since inception.

    Loop-liveness registry; PG-only migrations must audit every reader and add a PG-over-SQLite test.
  • 2026-08-25fixed
    Eleven-day engine hang

    A market-data call with no timeout froze the engine from 2026-08-14. Collection had also stopped after a broker login-page redesign. No trades closed for 18 days.

    Timeouts on data calls, selector fallback chains, self-diagnosing collector failures.
07 · Timeline

Nine months

git log · CHANGELOG.md1,011 commits in January alone
  1. 2025-12-31First commit: a Python port of the MQL5 News Surfer V2 news-straddle strategy onto NautilusTrader.
  2. 2026-01-05A handful of small real brokerage positions opened by the engine and never closed by it.Exit-logic fix shipped 2026-01-17; live trading gated on paper validation since.
  3. 2026-01-07First GPU revalidation audit: 337 armed strategies tested, 4 passed. Consolidated to 4 armed of 554.
  4. 2026-01-22Full GPU stack on the RTX 5070 Ti: CUDA 12.9 and CuPy built from source for Blackwell.
  5. 2026-01-25RSI(2) Sharpe-25 false positives. The arming hard stop and database trigger are born.
  6. 2026-02-04First paper trade under the arming pipeline. PostgreSQL becomes the source of truth for trades.Day counter on every standup starts here.
  7. 2026-02-06A curl rate-limit false alarm and two days of silently failing crons produce the standup health script.
  8. 2026-03-29Spec-driven workflow introduced: numbered specs, approval markers, a hook that blocks skipped phases.
  9. 2026-04-11Eighteen configurations armed from local approximations all fail on the server. Server-side validation becomes mandatory.Two days later: the 50× slippage unit bug.
  10. 2026-04-15Filesystem wipe destroys every scanner SQLite database; PostgreSQL survives. Spec 026 migrates everything to PG in two weeks with 247 new tests.
  11. 2026-05-19The sixteen-day silent outage ends in a WSL wipe and five days of lost data.
  12. 2026-06-22The Linux host becomes the active primary; leader lock, streaming replica and manual promotion deployed as emergency HA.
  13. 2026-07-04Fibonacci retired after 0 of 4 pre-registered hypotheses pass and a 99,847-trade study finds no edge.
  14. 2026-07-12OANDA Autochartist retired after Auth0 broke; IC Markets Autochartist goes live, and Trading Central US-equity signals arm the next day.
  15. 2026-07-16The 13-row armed internal catalogue turns out to be test-fixture debris. Zero internal strategies armed pending honest revalidation.
  16. 2026-07-17A live UK broker account is funded and cleared. Not yet routed to by the pipeline.
  17. 2026-07-24OANDA order-book and position-book snapshots start landing every 20 minutes: the first order-flow feature source.
  18. 2026-08-14Engine hangs for eleven days on a data call without a timeout; fixed 08-25 along with the collector login redesign.
  19. 2026-09-07Day 215. 2,197 commits. Canonical PF 1.55 on 249 unique paper trades. Still paper.
08 · Engineering practice

The process is code

spec/ · .claude/hooks · tests/
  • Spec gates are files. Approval state lives as .requirements-approved, .design-approved, .tasks-approved and .phase-N-qa-approved markers; a shell hook refuses to run the next phase without them. 40 specs, 16 complete.
  • Per-spec regression packs. pytest --spec 037 runs only that spec's tests; a spec cannot be closed while its pack is missing or red.
  • Guard tests that break the build. A static scan for the banned P&L OR-pattern, a scan for hardcoded model names, and a golden ledger that must fail when a past bug is replayed. Each includes a self-test proving the scanner fires.
  • TDD ordering in the template. Every deliverable expands to [TEST] → [IMPL] → [VERIFY]; phase wrap-up requires zero failures and 80% coverage.
  • Evidence or nothing. The Definition of Done forbids writing DONE or PASSED without pasted command output, and server-side validation must show the SSH hostname.
  • Per-phase QA, not end-of-epic QA. A QA persona that is forbidden from fixing verifies each phase while evidence is fresh.
  • Seven personas with boundaries. Tech lead, quant developer, QA gatekeeper, trader analyst, methodology advisor, day trader, standup expert. The analyst audits the epic tracker and found its math errors.
  • Registry-as-code. Loop liveness, crontab drift, scheduled-task awareness and forward-test picks are each a list in the repo; adding an entry is a one-line reviewed change and the checks iterate the list.
  • Incident → rule → guard → test. Each CLAUDE.md hard stop cites the dated incident, names the safeguard and the test file that pins it.
  • Pre-merge adversarial review. A 15-agent review of the revalidation gate confirmed eight findings by execution; three real defects were caught in the equities spec before merge.
  • Simulated users. Nine Playwright agent specs drive the dashboards as personas with calibrated friction tolerances.
  • Honest documentation drift. The repo records where its own tracker disagrees with itself, which docs are stale, and which spec numbers were used twice.

Where the code lives

Lines of Python by top-level directory, working tree at 2026-07-21, plus test code

09 · Potential

What it could become

spec/021 · spec/024 · spec/039docs/EPIC_TRACKER.md

The platform's asset is not a discovered edge. It is a working, self-auditing pipeline that can test one cheaply and honestly. The value of that shows up in what it can now attempt.

Near term (specs in flight)

  • Let the post-fix cohort mature. 67 trades at PF 2.09 need to reach 30 resolved per source before any sizing bump; the R:R ≥ 1.0 execution floor is now in place.
  • Finish path-to-live phases 4 and 5. Gates, promoter and demo adapters are code-complete with 113 tests; shadow routing into the engine and operator surfaces are not started.
  • Clear the Autochartist backlog. 2,644 signals overdue for outcome evaluation, and a standup section still reading a stale SQLite column.
  • Trading Central graduation. First US single-name equity source; needs 30 resolved trades and PF ≥ 1.75 to earn size.

Strategic

  • Order flow as a feature. Spec 039 already lands OANDA order-book and position-book snapshots every 20 minutes; the roadmap's five market dimensions say order flow is what price-pattern strategies are missing.
  • Re-earn internal strategies honestly. Daily RSI(2) + VIX > 20 on QQQ and SPY validated at the 97th and 90th percentiles; the revalidation loop can re-arm them from a clean catalogue.
  • Adaptive weights with real data. 397 outcome rows and 121 tracked combos; factor attribution engages at 100 joined rows and is now alive again.
  • Re-admit the LLM only on evidence. A codified graduation gate exists; the grounding layer is ready if the model ever clears it.

Monetization paths

  • Live trading in stages. A staged capital plan that scales only on evidence, with a $500 per-order cap and two-of-two approval at the first live stage. A funded live broker account exists.
  • Signal provider (Spec 024). Publish the canonical unique-signal track record to MQL5 or Myfxbook via an MT5 bridge; the number is already contract-pinned. Requirements only, no code yet, and a regulatory memo is a stated prerequisite.
  • Drafted products. A signal-subscription PWA and a friends-and-family investment vault exist as epics; the vault's web app is outside this repo.

Risks, plainly

  • No demonstrated live edge. Paper PF has declined all year; the profitable cohort is 67 trades.
  • Single vendor dependency. One IC Markets login feeds both signal sources; when its portal changed, collection stopped for two weeks.
  • Consumer hardware. Two home machines with a history of BSODs, hibernation, PCIe errors and one full wipe.
  • Documentation lag. The README, roadmap and tracker are months behind the code; the daily standup archive is the reliable record.
  • Regulatory surface. Selling signals from the UK may trigger FCA investment-advice thresholds.