From 8e838c4a66d32f4d867a4076656f9caf5332e2aa Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 9 Jun 2026 22:03:31 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20--fixed=20Flag=20=E2=80=94=20Walk-Forwa?= =?UTF-8?q?rd=20ohne=20Grid-Suche=20(fixe=20Spec-Default-Parameter)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/backtest/walkforward.ts | 5 +++-- src/server/scripts/walkforward.ts | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/server/backtest/walkforward.ts b/src/server/backtest/walkforward.ts index 2f3b5be..165aa2c 100644 --- a/src/server/backtest/walkforward.ts +++ b/src/server/backtest/walkforward.ts @@ -112,16 +112,17 @@ export function runWalkForward( dataFrom: number, dataTo: number, onProgress?: (msg: string) => void, + grid: StrategyParams[] = PARAM_GRID, ): WalkForwardResult { const windows = buildWindows(dataFrom, dataTo); const results: WindowResult[] = []; for (const [wi, w] of windows.entries()) { - let bestParams = PARAM_GRID[0]; + let bestParams = grid[0]; let bestMetrics: Metrics | null = null; let bestEligible = false; - for (const params of PARAM_GRID) { + for (const params of grid) { const r = runBacktest(candles15ByPair, { ...baseCfg, params, tradeFrom: w.trainFrom, tradeTo: w.trainTo }); const m = computeMetrics(r.trades, r.equityCurve, baseCfg.startCapital); const eligible = m.trades >= 5; diff --git a/src/server/scripts/walkforward.ts b/src/server/scripts/walkforward.ts index b6f4494..b232bdf 100644 --- a/src/server/scripts/walkforward.ts +++ b/src/server/scripts/walkforward.ts @@ -1,6 +1,7 @@ import { PAIRS, type Candle, type Pair } from '../types'; import { getCandles, getCoverage } from '../market/candle-store'; import { runWalkForward } from '../backtest/walkforward'; +import { DEFAULT_PARAMS } from '../strategy/donchian-trend'; import { DEFAULT_RISK } from '../engine/sizing'; import { DEFAULT_EXEC } from '../engine/portfolio'; import { db, sql } from '../db/client'; @@ -20,11 +21,15 @@ for (const pair of PAIRS) { } const allowShort = process.argv.includes('--shorts'); +// --fixed: keine Grid-Suche — fixe A-priori-Parameter (Spec-Defaults). Kein Overfitting +// durch Parameterwahl möglich; Train-Metriken dienen nur noch der Ratio-Diagnose. +const fixed = process.argv.includes('--fixed'); +const grid = fixed ? [DEFAULT_PARAMS] : undefined; const baseCfg = { startCapital: 1000, risk: DEFAULT_RISK, exec: DEFAULT_EXEC, maxPositions: 4, allowShort }; -console.log(`Shorts: ${allowShort ? 'AN' : 'AUS'}`); +console.log(`Shorts: ${allowShort ? 'AN' : 'AUS'} | Parameter: ${fixed ? 'FIX (Spec-Defaults)' : 'Grid-Suche'}`); console.log(`\nWalk-Forward über ${((dataTo - dataFrom) / 86400000).toFixed(0)} Tage…\n`); -const result = runWalkForward(candles15ByPair, baseCfg, dataFrom, dataTo, (msg) => console.log(msg)); +const result = runWalkForward(candles15ByPair, baseCfg, dataFrom, dataTo, (msg) => console.log(msg), grid); console.log('\n========== OOS-GESAMTERGEBNIS =========='); const m = result.oosMetrics;