feat: --fixed Flag — Walk-Forward ohne Grid-Suche (fixe Spec-Default-Parameter)

This commit is contained in:
2026-06-09 22:03:31 +00:00
parent cdf5b133a9
commit 8e838c4a66
2 changed files with 10 additions and 4 deletions

View File

@@ -112,16 +112,17 @@ export function runWalkForward(
dataFrom: number, dataFrom: number,
dataTo: number, dataTo: number,
onProgress?: (msg: string) => void, onProgress?: (msg: string) => void,
grid: StrategyParams[] = PARAM_GRID,
): WalkForwardResult { ): WalkForwardResult {
const windows = buildWindows(dataFrom, dataTo); const windows = buildWindows(dataFrom, dataTo);
const results: WindowResult[] = []; const results: WindowResult[] = [];
for (const [wi, w] of windows.entries()) { for (const [wi, w] of windows.entries()) {
let bestParams = PARAM_GRID[0]; let bestParams = grid[0];
let bestMetrics: Metrics | null = null; let bestMetrics: Metrics | null = null;
let bestEligible = false; 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 r = runBacktest(candles15ByPair, { ...baseCfg, params, tradeFrom: w.trainFrom, tradeTo: w.trainTo });
const m = computeMetrics(r.trades, r.equityCurve, baseCfg.startCapital); const m = computeMetrics(r.trades, r.equityCurve, baseCfg.startCapital);
const eligible = m.trades >= 5; const eligible = m.trades >= 5;

View File

@@ -1,6 +1,7 @@
import { PAIRS, type Candle, type Pair } from '../types'; import { PAIRS, type Candle, type Pair } from '../types';
import { getCandles, getCoverage } from '../market/candle-store'; import { getCandles, getCoverage } from '../market/candle-store';
import { runWalkForward } from '../backtest/walkforward'; import { runWalkForward } from '../backtest/walkforward';
import { DEFAULT_PARAMS } from '../strategy/donchian-trend';
import { DEFAULT_RISK } from '../engine/sizing'; import { DEFAULT_RISK } from '../engine/sizing';
import { DEFAULT_EXEC } from '../engine/portfolio'; import { DEFAULT_EXEC } from '../engine/portfolio';
import { db, sql } from '../db/client'; import { db, sql } from '../db/client';
@@ -20,11 +21,15 @@ for (const pair of PAIRS) {
} }
const allowShort = process.argv.includes('--shorts'); 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 }; 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`); 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 =========='); console.log('\n========== OOS-GESAMTERGEBNIS ==========');
const m = result.oosMetrics; const m = result.oosMetrics;