fix(backtest): flag a lookback the recommendation was not computed on

Selecting a different window or a comparison strategy silently made the tiles
stop matching the recommendation below, which is baked into the report and
cannot follow a dropdown. On load they now agree by construction; moving off
that basis says so.

Also: an absent production row produced no headline and no benchmark, but any
passing gate finding still rendered a green "no warnings" chip — a success badge
for missing data, directly beside "this report predates the portfolio monitor".
Missing baseline now reads "baseline unavailable".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 08:03:12 +02:00
co-authored by Claude Opus 5
parent 11dffcd695
commit 21a5fc8a52
4 changed files with 54 additions and 2 deletions
@@ -42,8 +42,19 @@ export function BacktestPanel() {
const monitor = report?.portfolio_monitor ?? null;
const activeStrategy =
selectedStrategy || monitor?.production_strategy || monitor?.strategies[0]?.strategy || '';
// Default to the window the recommendation was computed on, so the tiles and
// the recommendation never open showing different numbers. They used to: the
// backend preferred "all" while this defaulted to "3y". The 3y fallback is
// only for reports predating basis_lookback.
const basisLookback = report?.recommendation?.basis_lookback ?? null;
const activeLookback =
selectedLookback || (monitor?.lookbacks.some((l) => l.lookback === '3y') ? '3y' : monitor?.lookbacks[0]?.lookback) || '';
selectedLookback ||
(basisLookback && monitor?.lookbacks.some((l) => l.lookback === basisLookback)
? basisLookback
: monitor?.lookbacks.some((l) => l.lookback === '3y')
? '3y'
: monitor?.lookbacks[0]?.lookback) ||
'';
const monitorRun = useMemo(
() =>
monitor?.runs.find((row) => row.strategy === activeStrategy && row.lookback === activeLookback) ??
@@ -175,6 +186,9 @@ export function BacktestPanel() {
activeLookback={activeLookback}
onStrategyChange={setSelectedStrategy}
onLookbackChange={setSelectedLookback}
basisLookback={basisLookback}
basisLookbackLabel={report.recommendation?.basis_lookback_label ?? null}
productionStrategy={monitor?.production_strategy ?? null}
/>
{report.recommendation && (
@@ -81,7 +81,16 @@ export function BacktestRecommendationCard({
<div className="glass border border-blue-400/20 p-4">
<div className="flex flex-wrap items-center justify-between gap-2">
<p className="section-index">What this backtest recommends</p>
{warningCount > 0 ? (
{/* No headline means the backend found no production monitor row, so
nothing here describes the production book. Zero keyword warnings
is then absence of data, not a clean bill of health — a green chip
beside "this report predates the portfolio monitor" would be a
success badge for missing data. */}
{!recommendation.headline ? (
<span className="rounded-full border border-white/15 bg-white/[0.05] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-gray-400">
baseline unavailable
</span>
) : warningCount > 0 ? (
<span className="rounded-full border border-amber-400/40 bg-amber-400/10 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-amber-300">
{warningCount} warning{warningCount > 1 ? 's' : ''}
</span>
@@ -30,6 +30,9 @@ export function PortfolioMonitorPanel({
activeLookback,
onStrategyChange,
onLookbackChange,
basisLookback = null,
basisLookbackLabel = null,
productionStrategy = null,
}: {
monitor: BacktestPortfolioMonitor | null | undefined;
monitorRun: BacktestPortfolioMonitorRun | null | undefined;
@@ -37,6 +40,10 @@ export function PortfolioMonitorPanel({
activeLookback: string;
onStrategyChange: (v: string) => void;
onLookbackChange: (v: string) => void;
/** The window the recommendation below was computed on. */
basisLookback?: string | null;
basisLookbackLabel?: string | null;
productionStrategy?: string | null;
}) {
if (!monitor || !monitorRun) {
return (
@@ -90,6 +97,21 @@ export function PortfolioMonitorPanel({
</div>
</div>
{/* The recommendation below is baked into the report and cannot follow a
dropdown. On load the two agree by construction; say so plainly the
moment a selection moves off that basis. */}
{((basisLookback && activeLookback !== basisLookback) ||
(productionStrategy && activeStrategy !== productionStrategy)) && (
<p className="text-[11px] text-amber-300/80">
Showing{' '}
{productionStrategy && activeStrategy !== productionStrategy
? 'a comparison strategy'
: 'a different window'}
. The recommendation below is computed on the production strategy over{' '}
{basisLookbackLabel ?? basisLookback} these tiles will not match it.
</p>
)}
{/* Tier 1 — what the book returned. */}
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
<StatTile
+7
View File
@@ -336,6 +336,13 @@ export interface BacktestCurvePoint {
export interface BacktestRecommendation {
headline: string | null;
items: { topic: string; text: string }[];
/**
* The monitor lookback every production/benchmark figure was read from. The
* page defaults its selector to this so the tiles and the recommendation
* cannot open on different windows. Absent on reports predating the field.
*/
basis_lookback?: string | null;
basis_lookback_label?: string | null;
note?: string;
}