diff --git a/algosystem/validation/domain/statistics/walkforward.py b/algosystem/validation/domain/statistics/walkforward.py index 35d76e3..f3ba26d 100644 --- a/algosystem/validation/domain/statistics/walkforward.py +++ b/algosystem/validation/domain/statistics/walkforward.py @@ -123,7 +123,7 @@ def walk_forward_analysis( n = len(returns) keys = sorted(param_grid.keys()) values = [param_grid[k] for k in keys] - param_list = [dict(zip(keys, combo)) for combo in itertools.product(*values)] + param_list = [dict(zip(keys, combo, strict=True)) for combo in itertools.product(*values)] # Compute fold boundaries # Each fold: [fold_start, fold_end) with IS = first is_ratio, OOS = rest diff --git a/algosystem/validation/domain/strategy.py b/algosystem/validation/domain/strategy.py index 35c66b6..ac163b4 100644 --- a/algosystem/validation/domain/strategy.py +++ b/algosystem/validation/domain/strategy.py @@ -96,7 +96,7 @@ def combinations(self) -> Iterator[ParameterSet]: keys = [name for name, _ in self._items] value_lists = [values for _, values in self._items] for combo in itertools.product(*value_lists): - yield ParameterSet(zip(keys, combo)) + yield ParameterSet(zip(keys, combo, strict=True)) def to_dict(self) -> dict[str, list[object]]: """Return a mutable dict copy preserving stable parameter order.""" diff --git a/algosystem/validation/infrastructure/matplotlib_charts.py b/algosystem/validation/infrastructure/matplotlib_charts.py index 09584cc..c85f95c 100644 --- a/algosystem/validation/infrastructure/matplotlib_charts.py +++ b/algosystem/validation/infrastructure/matplotlib_charts.py @@ -141,7 +141,7 @@ def draw(plt): if show_individual: for points in slices.values(): points.sort() - xs, ys = zip(*points) + xs, ys = zip(*points, strict=True) ax.plot(xs, ys, color="grey", alpha=0.15, linewidth=0.7, zorder=1) value_sharpes = {value: [] for value in values} @@ -154,8 +154,8 @@ def draw(plt): ax.fill_between( xs_mean, - [mean - std for mean, std in zip(means, stds)], - [mean + std for mean, std in zip(means, stds)], + [mean - std for mean, std in zip(means, stds, strict=True)], + [mean + std for mean, std in zip(means, stds, strict=True)], alpha=0.25, color="steelblue", zorder=2, diff --git a/pyproject.toml b/pyproject.toml index 3fe13c3..fe643df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ isort = "^5.13.2" mypy = "^1.8.0" pytest-cov = "^5.0.0" backoff = "^1.2.1" -ruff = "^0.11.10" +ruff = ">=0.11.10,<0.17.0" import-linter = "^2.3.0" [tool.poetry.group.docs] diff --git a/tests/validation/application/test_bruteforce.py b/tests/validation/application/test_bruteforce.py index 01a1c26..ca3d087 100644 --- a/tests/validation/application/test_bruteforce.py +++ b/tests/validation/application/test_bruteforce.py @@ -30,7 +30,7 @@ def test_full_crossvalidation(self): # Brute-force: re-run all passes manually keys = sorted(param_grid.keys()) values = [param_grid[k] for k in keys] - plist = [dict(zip(keys, combo)) for combo in itertools.product(*values)] + plist = [dict(zip(keys, combo, strict=True)) for combo in itertools.product(*values)] n_params = len(plist) master_rng = np.random.default_rng(55) diff --git a/tests/validation/infrastructure/test_strategies.py b/tests/validation/infrastructure/test_strategies.py index 8aebdaf..3be326b 100644 --- a/tests/validation/infrastructure/test_strategies.py +++ b/tests/validation/infrastructure/test_strategies.py @@ -128,7 +128,8 @@ def test_trending_persists_oos(self): grid = {"lookback": [5, 10, 20, 40], "threshold": [0.0, 0.001]} keys = sorted(grid.keys()) - plist = [dict(zip(keys, c)) for c in itertools.product(*[grid[k] for k in keys])] + combos = itertools.product(*[grid[k] for k in keys]) + plist = [dict(zip(keys, c, strict=True)) for c in combos] is_sharpes = [momentum_backtest(p, is_data) for p in plist] best_idx = np.argmax(is_sharpes)