ZhuLinsen/daily_stock_analysis · error · ValueError
eval_window_days must be positive
Error message
eval_window_days must be positive
What it means
Backtest engine guard (evaluate path 1, src/core/backtest_engine.py): eval_days = int(config.eval_window_days) must be a positive integer. Zero or negative windows are nonsensical for forward-return evaluation (you cannot measure performance over a non-positive number of bars), so the engine raises rather than producing a degenerate evaluation. Note this is reached only after start_price passed its own validity check.
Source
Thrown at src/core/backtest_engine.py:188
Notes:
- Daily bars cannot determine intraday ordering. If stop-loss and
take-profit are both touched in the same bar, we record
first_hit="ambiguous" and assume stop-loss first for simulated exit.
"""
if start_price is None or start_price <= 0:
return {
"analysis_date": analysis_date,
"operation_advice": operation_advice,
"position_recommendation": cls.infer_position_recommendation(operation_advice),
"direction_expected": cls.infer_direction_expected(operation_advice),
"eval_status": "error",
}
eval_days = int(config.eval_window_days)
if eval_days <= 0:
raise ValueError("eval_window_days must be positive")
if len(forward_bars) < eval_days:
return {
"analysis_date": analysis_date,
"operation_advice": operation_advice,
"position_recommendation": cls.infer_position_recommendation(operation_advice),
"direction_expected": cls.infer_direction_expected(operation_advice),
"eval_status": "insufficient_data",
"eval_window_days": eval_days,
}
window_bars = list(forward_bars[:eval_days])
end_close = window_bars[-1].close
highs = [b.high for b in window_bars if b.high is not None]
lows = [b.low for b in window_bars if b.low is not None]
max_high = max(highs) if highs else None
min_low = min(lows) if lows else None
View on GitHub (pinned to 5159bd72e8)
Solutions
- Set eval_window_days to a positive integer (e.g. 30) in the backtest config / env.
- If the value comes from user input or env, clamp/validate it (>= 1) before constructing the config.
- Re-run the backtest to confirm the evaluation completes.
Example fix
# before config.eval_window_days = 0 # after config.eval_window_days = 30
Defensive patterns
Strategy: validation
Validate before calling
eval_days = int(config.eval_window_days)
if eval_days <= 0:
raise ValueError("eval_window_days must be a positive integer") Type guard
def is_valid_eval_window(value: object) -> bool:
try:
return int(value) > 0 # type: ignore[arg-type]
except (TypeError, ValueError):
return False Prevention
- Validate eval_window_days where config is constructed, not mid-backtest
- Set explicit positive defaults (e.g. 30)
- Fail fast at startup on non-positive backtest config
When it happens
Trigger: A BacktestConfig with eval_window_days = 0, a negative number, or a value that int() truncates to <= 0 (e.g. 0.5). Raised during evaluation of an operation advice with a valid positive start price.
Common situations: Config typo (0 instead of 30); env var EVAL_WINDOW_DAYS set to empty/0; programmatic config where a default was never applied; passing days as float < 1.
Related errors
- invalid_params
- validation_failed
- capability_unsupported
- Responses API surface requires a normalized openai/<model> r
- LLM route aliases cannot mix API surfaces: {sorted(surface_c
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/743f31db631ff6ca.
Report an issue: GitHub.