feat: add selectable daily backtest cadence
This commit is contained in:
@@ -32,7 +32,10 @@ def _parse_args() -> argparse.Namespace:
|
||||
parser.add_argument(
|
||||
"--out",
|
||||
default=None,
|
||||
help="JSON report path. Defaults to reports/backtest-<timestamp>.json.",
|
||||
help=(
|
||||
"JSON report path. Defaults to "
|
||||
"reports/backtest-<cadence>-<timestamp>.json."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--workers",
|
||||
@@ -55,6 +58,15 @@ def _parse_args() -> argparse.Namespace:
|
||||
"structural_sr is a comparison-only chart-S/R model."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cadence",
|
||||
choices=("weekly", "daily"),
|
||||
default="weekly",
|
||||
help=(
|
||||
"Entry replay cadence. Weekly is the resource-safe production default; "
|
||||
"daily performs roughly five times as many setup evaluations."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--holdout-split",
|
||||
default=None,
|
||||
@@ -63,9 +75,9 @@ def _parse_args() -> argparse.Namespace:
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def _default_output_path() -> Path:
|
||||
def _default_output_path(cadence: str) -> Path:
|
||||
stamp = datetime.now().strftime("%Y%m%d-%H%M%S")
|
||||
return Path("reports") / f"backtest-{stamp}.json"
|
||||
return Path("reports") / f"backtest-{cadence}-{stamp}.json"
|
||||
|
||||
|
||||
def _pct(value: Any) -> str:
|
||||
@@ -93,6 +105,7 @@ def _print_summary(report: dict) -> None:
|
||||
|
||||
print("")
|
||||
print("Backtest summary")
|
||||
print(f" entry cadence: {(report.get('params') or {}).get('entry_cadence', 'weekly')}")
|
||||
print(f" candidates: {report.get('candidates')}")
|
||||
print(f" qualified: {report.get('qualified')}")
|
||||
print(f" all setups net avg R: {_r(all_setups.get('net_avg_r'))}")
|
||||
@@ -183,7 +196,7 @@ async def _main() -> None:
|
||||
if args.workers is not None:
|
||||
settings.backtest_workers = args.workers
|
||||
|
||||
output = Path(args.out) if args.out else _default_output_path()
|
||||
output = Path(args.out) if args.out else _default_output_path(args.cadence)
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
engine = create_async_engine(_sqlite_url(snapshot), pool_pre_ping=True)
|
||||
@@ -208,6 +221,7 @@ async def _main() -> None:
|
||||
db,
|
||||
progress_cb=progress,
|
||||
target_model=args.target_model,
|
||||
cadence=args.cadence,
|
||||
)
|
||||
finally:
|
||||
await engine.dispose()
|
||||
|
||||
Reference in New Issue
Block a user