(`/experiments/${encodeURIComponent(id)}`);
if (!detail) notFound();
const result = detail.result as BacktestResult | null;
const isBacktest = Boolean(result && Array.isArray(result.equity_curve));
if (!isBacktest) {
return (
归档 {id} 的类型是「{experimentKindLabel(detail.kind)}」,它的结果结构里没有净值 /
因子曲线(这些曲线只在回测归档里)。这不是错误,只是曲线放大页不适用于该类型。
打开归档详情
);
}
const res = result as BacktestResult;
const options = optionsFor(res);
const want = sp?.s ?? options[0]?.key ?? "equity";
const current = options.find((o) => o.key === want) ?? options[0];
const factorKey = current?.key.startsWith("factor:") ? current.key.slice("factor:".length) : null;
const symKey = current?.key.startsWith("sym:") ? current.key.slice("sym:".length) : null;
let series = equitySeries(res);
let markers = portfolioMarkers(
res.fills,
new Set(res.equity_curve.map((p) => p.date))
);
let formatKey: LwFormatKey = "num";
let note = "组合净值(元):每日收盘后按持仓市值结算;▲ 绿 = 当日有买入成交,▼ 红 = 当日有卖出成交。";
let zeroLine = false;
if (factorKey) {
const curve = (res.factor_curves ?? []).find((f) => f.name === factorKey);
if (curve) {
const idx = (res.factor_curves ?? []).findIndex((f) => f.name === factorKey);
series = [factorSeries(curve, idx)];
formatKey = factorFormatKey(curve);
note = factorCurveNote(curve);
// 因子曲线上的买卖点:把组合的成交日标在因子曲线上,直接看「买卖发生在什么水平」
markers = portfolioMarkers(res.fills, new Set(curve.points.map((p) => p.date)));
}
} else if (symKey) {
const curve = (res.symbol_curves ?? []).find((c) => c.symbol === symKey);
if (curve) {
series = symbolSeries(curve);
markers = symbolMarkers(curve);
formatKey = "pct2";
note =
`${curve.symbol} 持仓期间的累计收益率(%,以建仓日收盘为 0% 基准,按日复利),` +
"只在该股持仓的交易日落点;买卖点为实际成交。";
zeroLine = true;
}
} else if (current?.key === "drawdown") {
series = drawdownSeries(res);
markers = [];
formatKey = "pct2";
note = "回撤(%):净值相对历史最高点的跌幅,越负越深。";
zeroLine = true;
} else if (current?.key === "monthly") {
series = monthlySeries(res);
markers = [];
formatKey = "pct2";
note = "月度收益(%):每个月末相对上月末的净值变化。";
zeroLine = true;
}
const seriesLabel = series[0]?.label ?? current?.label ?? "曲线";
return (
<>
曲线放大
{experimentKindLabel(detail.kind)}
{id}
{detail.created_at ? (
归档于 {String(detail.created_at).slice(0, 19).replace("T", " ")}
) : null}
打开归档详情
{options.map((o) => (
{o.label}
))}
{series[0]?.data.length ?? 0} 个点
{markers.length ? ` · ${markers.length} 个买卖标注` : ""}
}
>
{note} 拖动 / 滚轮可缩放,双击图例可临时隐藏曲线;地址栏 URL 可直接分享或收藏
(换设备打开还原同一张图,因为数据来自归档快照)。
{res.summary ? (
区间 {res.summary.start} ~{" "}
{res.summary.end}
总收益{" "}
= 0 ? "tone-pos" : "tone-neg"}>
{res.summary.total_return_pct.toFixed(2)}%
年化 {res.summary.annual_return_pct.toFixed(2)}%
Sharpe {res.summary.sharpe.toFixed(3)}
最大回撤 {res.summary.max_drawdown_pct.toFixed(2)}%
期末权益 {fmtNum(res.summary.final_equity)}
共 {res.summary.total_trades} 笔成交
) : null}
>
);
}