Reports
Three HTML files, each answering a different question. One of them is the file you hand to a human before money is involved — and it is also the slowest to build, for a good reason.
The three deliverables
| File | Generated by | Question it answers |
|---|---|---|
report.html |
report_m5.py |
How did each individual feature set do, and how does the book look? |
tail_holdout_report.html |
report_tail.py |
What happened on the unseen tail, warm versus cold? |
report_m5_performance.html |
broker_run_report.py |
The delivery report. Everything needed to judge the strategy, in one file. |
report_m5.py --symbol XAUUSD --tf M5 --port all9
report_tail.py --symbol XAUUSD --tf M5 --tail 2500
broker_run_report.py --symbol XAUUSD --tf M5 --tail 2500
The per-set report
report_m5.py is the analysis view of the run.
equity_*.csv files.union_features field.
The --port flag selects which portfolio folder to highlight — pass
all9 to centre the nine-slot book.
The tail-holdout report
report_tail.py presents the warm/cold comparison from Step 5.
It reads tail_report.json from
<root>/<folder>/tail<tail>_<mode>/, so both modes
must have been run for the full comparison.
The delivery report
broker_run_report.py produces the one to hand to a human. It is the
slowest to build, and deliberately so.
Sections
Why the 24h comparison re-runs the model
A slot blocked during its off-hours window does not simply skip those trades — it also stays flat through them, which means it is available to take a different trade later. The whole subsequent trade sequence diverges. Filtering a list of trades cannot reproduce a sequence that was never generated.
So the report performs an exact replay: one forward pass per slot for
each hour configuration, using the replay machinery in
lr_hours_engine.py. It is slower, and it is the honest comparison.
How the exact replay is possible at all
It rests on a structural property of the engine, stated earlier in The LR Engine: the hour filter gates entries only. Training reads its own separate mask, and online learning uses the bar's own forward return rather than position P&L.
The consequence is that the weight trajectory is identical for every hour subset. The model learns the same things regardless of which hours it is allowed to trade. So a single pass that records raw entry signals yields every possible hour-subset result exactly, with no re-training — and that is what makes the comparison both exhaustive and fast enough to include in a report.
b < last_exit) or if its
hour is not allowed. Exits resolve stop before target intrabar, matching
the engine's conservative assumption. An unresolved position closes on the last bar at
close with reason "EOData". The replay is validated against real
hour-filtered backtests during development — it reports
EXACT MATCH when the maximum absolute difference is under $0.01, and
*** MISMATCH — do not use *** otherwise.
The Reports page
Which report answers which question
| You want to know… | Read |
|---|---|
| Which feature sets contributed most? | report.html — per-set table. |
| Is the book concentrated in one slot? | report.html or the delivery report's per-slot section. |
| Did the strategy survive unseen data? | tail_holdout_report.html. |
| Does the session filter actually help? | Delivery report, section 5 — the exact replay. |
| What cost assumption is baked in? | Delivery report, section 1 — median spread and cost basis. |
| Should I trade this? | Delivery report — read section 5 then section 6, in that order. |
A suggested reading order for the delivery report
Checkpoint
- All three reports generated without error.
- You have read the cost basis and accepted the spread assumption.
- You have read the 24h-vs-window replay and decided which build to ship.
- You have read the holdout and it is either positive, or you have consciously accepted a warm-only edge.
- The delivery report is archived alongside the data it describes.
| Symptom | Cause | Fix |
|---|---|---|
| Report shows no data / empty sections | The upstream artefacts are missing — the report reads summaries, not in-memory state. | Confirm the search, build and holdout all ran for this symbol and timeframe. |
| Report takes a very long time | The delivery report's exact replay re-runs one forward pass per slot per hour configuration. | Expected. Use the lighter reports while iterating; build the delivery report when you are ready to decide. |
| Numbers differ from what I saw in the app | Either the report is older than the run, or you are comparing in-sample against tail figures. | Regenerate, and check which section you are reading. |
| Excel or the browser shows an old version | Aggressive caching of a local file. | Hard-refresh (Ctrl+F5), or archive the file with a dated name. |
What now?
The pipeline is complete. You have a compiled EA, a holdout result, and reports that describe both. If the holdout is positive in both modes, the next step is forward-testing on a demo account — because a single tail window is one market regime, not a guarantee.