|
4 | 4 | import threading |
5 | 5 | from datetime import datetime, timezone, timedelta |
6 | 6 | from pathlib import Path |
7 | | -from typing import List, Optional, Any, Dict, Tuple, Callable, Union |
| 7 | +from typing import List, Literal, Optional, Any, Dict, Tuple, Callable, Union |
8 | 8 |
|
9 | 9 | from flask import Flask |
10 | 10 |
|
@@ -985,6 +985,8 @@ def run_vector_backtests( |
985 | 985 | ] = None, |
986 | 986 | backtest_storage_directory: Optional[Union[str, Path]] = None, |
987 | 987 | use_checkpoints: bool = False, |
| 988 | + force_rerun: Union[bool, Literal["stale"]] = False, |
| 989 | + on_checkpoint_match: Literal["skip", "rerun", "warn"] = "skip", |
988 | 990 | batch_size: int = 50, |
989 | 991 | checkpoint_batch_size: int = 25, |
990 | 992 | n_workers: Optional[int] = None, |
@@ -1087,7 +1089,24 @@ def filter_function( |
1087 | 1089 | instead of running a new backtest. This is useful for |
1088 | 1090 | long-running backtests that might take a while to complete. |
1089 | 1091 | When enabled, uses the optimized version with batching and |
1090 | | - optional parallel processing. |
| 1092 | + optional parallel processing. Checkpoints are content-aware: |
| 1093 | + each entry stores a manifest hash that fingerprints the |
| 1094 | + strategy code, parameters, data sources, and date range. |
| 1095 | + Strategies whose hash differs from the stored hash are |
| 1096 | + rerun automatically. |
| 1097 | + force_rerun (Union[bool, Literal["stale"]]): Override checkpoint |
| 1098 | + skipping behaviour. |
| 1099 | +
|
| 1100 | + - False (default): Skip strategies with a matching checkpoint. |
| 1101 | + - "stale": Rerun only strategies whose stored checkpoint hash |
| 1102 | + differs from the current manifest hash. |
| 1103 | + - True: Ignore checkpoints entirely and rerun all strategies. |
| 1104 | + on_checkpoint_match (Literal["skip", "rerun", "warn"]): Behaviour |
| 1105 | + when a strategy's checkpoint matches. |
| 1106 | +
|
| 1107 | + - "skip" (default): Silently skip the strategy. |
| 1108 | + - "warn": Skip but emit a single log line per match batch. |
| 1109 | + - "rerun": Rerun the strategy anyway. |
1091 | 1110 | batch_size (int): Number of strategies to process in each batch |
1092 | 1111 | before memory cleanup. Only used when use_checkpoints=True. |
1093 | 1112 | Default: 100. Higher values use more memory but may be faster. |
@@ -1204,6 +1223,8 @@ def filter_function( |
1204 | 1223 | checkpoint_batch_size=checkpoint_batch_size, |
1205 | 1224 | n_workers=n_workers, |
1206 | 1225 | use_checkpoints=use_checkpoints, |
| 1226 | + force_rerun=force_rerun, |
| 1227 | + on_checkpoint_match=on_checkpoint_match, |
1207 | 1228 | dynamic_position_sizing=dynamic_position_sizing, |
1208 | 1229 | fill_missing_data=fill_missing_data, |
1209 | 1230 | iterative_summary_update=iterative_summary_update, |
@@ -1381,6 +1402,8 @@ def run_backtests( |
1381 | 1402 | metadata: Optional[Dict[str, str]] = None, |
1382 | 1403 | backtest_storage_directory: Optional[Union[str, Path]] = None, |
1383 | 1404 | use_checkpoints: bool = False, |
| 1405 | + force_rerun: Union[bool, Literal["stale"]] = False, |
| 1406 | + on_checkpoint_match: Literal["skip", "rerun", "warn"] = "skip", |
1384 | 1407 | show_progress: bool = False, |
1385 | 1408 | continue_on_error: bool = False, |
1386 | 1409 | window_filter_function: Optional[Callable] = None, |
@@ -1420,7 +1443,16 @@ def run_backtests( |
1420 | 1443 | backtest_storage_directory (Union[str, Path]): Directory to save |
1421 | 1444 | backtests to. |
1422 | 1445 | use_checkpoints (bool): Whether to use checkpointing to resume |
1423 | | - interrupted backtests. |
| 1446 | + interrupted backtests. Checkpoints are content-aware: |
| 1447 | + strategies whose code or parameters have changed since the |
| 1448 | + last run are detected and rerun automatically. |
| 1449 | + force_rerun (Union[bool, Literal["stale"]]): Override checkpoint |
| 1450 | + skipping behaviour. ``False`` (default) skips matched |
| 1451 | + checkpoints, ``"stale"`` reruns only mismatched ones, and |
| 1452 | + ``True`` reruns everything. |
| 1453 | + on_checkpoint_match (Literal["skip", "rerun", "warn"]): Behaviour |
| 1454 | + on a matching checkpoint. ``"skip"`` (default) silently |
| 1455 | + skips, ``"warn"`` skips and logs, ``"rerun"`` reruns anyway. |
1424 | 1456 | show_progress (bool): Whether to show progress bars. |
1425 | 1457 | continue_on_error (bool): Whether to continue on errors. |
1426 | 1458 | window_filter_function: Filter function applied after each |
@@ -1533,6 +1565,8 @@ def run_backtests( |
1533 | 1565 | final_filter_function=final_filter_function, |
1534 | 1566 | backtest_storage_directory=backtest_storage_directory, |
1535 | 1567 | use_checkpoints=use_checkpoints, |
| 1568 | + force_rerun=force_rerun, |
| 1569 | + on_checkpoint_match=on_checkpoint_match, |
1536 | 1570 | batch_size=batch_size, |
1537 | 1571 | checkpoint_batch_size=checkpoint_batch_size, |
1538 | 1572 | fill_missing_data=fill_missing_data, |
|
0 commit comments