Fix stale copy, dedupe Exit columns, document local report review
Follow-ups from review of the Track Record slim: - BacktestPanel: drop the stale "tracking check" sentence from the "How this is measured" explainer — that check moved to the maintenance disclosure last commit, so it no longer describes anything in this block. - MyTradesPanel: rename the two identically-labelled "Exit" columns to "Exit Px" (exit price) and "Reason" (close_reason) so they're not confusable. - README: add "Reading a local backtest report" under Local Backtest Snapshots — a section->decision map for reports/backtest-*.json. The strategy-tuning tables removed from the deployed page (sweep, gate_ablation, time_exit_sweep, signal_eval, strategy_variants) now live only in the local report, so this keeps "research lives local" from meaning the decision knowledge evaporates. tsc -b && vite build pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -307,6 +307,28 @@ metrics. Keep the SSH tunnel open only while creating the snapshot; the backtest
|
|||||||
run itself is local/offline. `backtest_snapshots/` and generated backtest reports
|
run itself is local/offline. `backtest_snapshots/` and generated backtest reports
|
||||||
are git-ignored.
|
are git-ignored.
|
||||||
|
|
||||||
|
### Reading a local backtest report
|
||||||
|
|
||||||
|
The deployed **Signals → Track Record** page is deliberately trimmed to validation
|
||||||
|
(portfolio monitor vs SPY, realized paper trades) and how-to-trade. The
|
||||||
|
strategy-tuning tables that used to live there now live **only** in the local
|
||||||
|
report — inspect these `reports/backtest-<timestamp>.json` sections and produce the
|
||||||
|
matching decision. Every change still goes through the factor harness first (see
|
||||||
|
**The iron rule for strategy changes** above).
|
||||||
|
|
||||||
|
| Report section | What to read | Decision it drives |
|
||||||
|
|---|---|---|
|
||||||
|
| `overall_qualified` vs `overall_all` | Is qualified net expectancy above the all-setups baseline? | Sanity — is the gate adding anything at all |
|
||||||
|
| `sweep` | Net avg R and trade count at each residual-momentum cutoff | Where to set the momentum percentile (Admin → Settings → Activation) |
|
||||||
|
| `gate_ablation` | Net expectancy with each floor removed | Drop a floor only if removing it doesn't hurt net expectancy |
|
||||||
|
| `time_exit_sweep` | Net avg R / net R-per-day by hold length | Whether a fixed time exit beats the promoted ATR trail |
|
||||||
|
| `portfolio_monitor`, `portfolio_sim`, `strategy_variants` | CAGR, Sharpe, max drawdown, per-year returns | Promote a strategy only if it beats the current baseline on CAGR/Sharpe/DD |
|
||||||
|
| `signal_eval` | Mean IC, t-stat, IC>0 %, `reliable` | Iron rule: wire a new factor in only if \|IC\| ≳ 0.03 with a consistent sign and `reliable: true` |
|
||||||
|
| `recommendation`, `research_recommendation` | The report's own headline read | A starting point, not a substitute for the sections above |
|
||||||
|
|
||||||
|
`recommendation` is the one section surfaced on the deployed page ("What this
|
||||||
|
backtest recommends"); everything else in this table is intentionally local-only.
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
Configure in `.env` (copy from `.env.example`):
|
Configure in `.env` (copy from `.env.example`):
|
||||||
|
|||||||
@@ -180,8 +180,7 @@ export function BacktestPanel() {
|
|||||||
rebuilt using only data up to that day (no lookahead) and the following ~30 trading days decide
|
rebuilt using only data up to that day (no lookahead) and the following ~30 trading days decide
|
||||||
its outcome — then simulates one capital-constrained book against the S&P 500. Sentiment and
|
its outcome — then simulates one capital-constrained book against the S&P 500. Sentiment and
|
||||||
fundamentals are held neutral (no point-in-time history). ~6 months is roughly one market regime,
|
fundamentals are held neutral (no point-in-time history). ~6 months is roughly one market regime,
|
||||||
so read it as directional. The <em>tracking</em> check compares the backtest's qualified
|
so read it as directional.
|
||||||
expectancy with what live qualified setups have actually realized once matured.
|
|
||||||
</p>
|
</p>
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
<Button onClick={() => run.mutate()} loading={run.isPending} className="shrink-0">
|
<Button onClick={() => run.mutate()} loading={run.isPending} className="shrink-0">
|
||||||
|
|||||||
@@ -93,11 +93,11 @@ export function MyTradesPanel() {
|
|||||||
<th className="px-4 py-2.5">Ticker</th>
|
<th className="px-4 py-2.5">Ticker</th>
|
||||||
<th className="px-4 py-2.5">Dir</th>
|
<th className="px-4 py-2.5">Dir</th>
|
||||||
<th className="px-4 py-2.5 text-right">Entry</th>
|
<th className="px-4 py-2.5 text-right">Entry</th>
|
||||||
<th className="px-4 py-2.5 text-right">Exit</th>
|
<th className="px-4 py-2.5 text-right">Exit Px</th>
|
||||||
<th className="px-4 py-2.5 text-right">P&L</th>
|
<th className="px-4 py-2.5 text-right">P&L</th>
|
||||||
<th className="px-4 py-2.5 text-right">R</th>
|
<th className="px-4 py-2.5 text-right">R</th>
|
||||||
<th className="px-4 py-2.5 text-right">Alpha</th>
|
<th className="px-4 py-2.5 text-right">Alpha</th>
|
||||||
<th className="px-4 py-2.5">Exit</th>
|
<th className="px-4 py-2.5">Reason</th>
|
||||||
<th className="px-4 py-2.5 text-right">Closed</th>
|
<th className="px-4 py-2.5 text-right">Closed</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user