{"record":{"id":"69c4619ffce6f796","repo":"HKUDS/Vibe-Trading","slug":"steps-per-year-must-be-1-got-steps-per-year","errorCode":null,"errorMessage":"steps_per_year must be >= 1, got {steps_per_year}","messagePattern":"steps_per_year must be >= 1, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/risk.py","lineNumber":565,"sourceCode":"            Defaults to the 252-day trading year.\n\n    Returns:\n        Price matrix of shape ``(n_paths, n_steps + 1)``. Column 0 is exactly\n        ``s0`` on every path, so ``paths[:, -1] / paths[:, 0] - 1`` is the total\n        return over the whole simulation.\n\n    Raises:\n        ValueError: If ``s0`` is not positive, ``sigma`` is negative, or any of\n            ``n_steps`` / ``n_paths`` / ``steps_per_year`` is below 1.\n    \"\"\"\n    if s0 <= 0.0:\n        raise ValueError(f\"s0 must be > 0, got {s0}\")\n    if sigma < 0.0:\n        raise ValueError(f\"sigma must be >= 0, got {sigma}\")\n    if n_steps < 1 or n_paths < 1:\n        raise ValueError(f\"n_steps and n_paths must be >= 1, got {n_steps} and {n_paths}\")\n    if steps_per_year < 1:\n        raise ValueError(f\"steps_per_year must be >= 1, got {steps_per_year}\")\n\n    dt = 1.0 / steps_per_year\n    rng = np.random.default_rng(seed)\n    shocks = rng.standard_normal((n_paths, n_steps))\n    log_returns = (mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * shocks\n    paths = np.empty((n_paths, n_steps + 1), dtype=float)\n    paths[:, 0] = s0\n    paths[:, 1:] = s0 * np.exp(np.cumsum(log_returns, axis=1))\n    return paths\n\n\ndef analyze_mc_results(paths: np.ndarray, confidence: float = 0.95) -> dict:\n    \"\"\"Summarise the terminal distribution of a simulated price matrix.\n\n    Args:\n        paths: Price matrix of shape ``(n_paths, n_steps + 1)`` as returned by\n            ``monte_carlo_gbm``; column 0 is the starting price.\n        confidence: Confidence level for the VaR/CVaR of the terminal return.","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/risk.py#L547-L583","documentation":"monte_carlo_gbm discretizes time as dt = 1/steps_per_year and needs steps_per_year >= 1 (e.g. 252 for daily, 12 for monthly, 1 for annual). Values below 1 would imply steps longer than a year via division by a fraction, breaking the intended convention, and 0 would divide by zero.","triggerScenarios":"monte_carlo_gbm(..., steps_per_year=0), or passing a fractional/intraday-miscomputed value like steps_per_year=1/252 (inverting the convention, i.e. passing step size instead of frequency).","commonSituations":"Confusing 'step size in years' with 'steps per year' — passing 1/252 instead of 252; deriving the value from an empty trading calendar.","solutions":["Pass the frequency: 252 for daily, 52 weekly, 12 monthly, 1 annual","If you have a step size dt, pass steps_per_year=1/dt (guarding dt > 0)","Validate steps_per_year is an integer >= 1 in config"],"exampleFix":"// before\npaths = monte_carlo_gbm(s0=100, mu=0.05, sigma=0.2, n_steps=252, steps_per_year=1/252)\n// after\npaths = monte_carlo_gbm(s0=100, mu=0.05, sigma=0.2, n_steps=252, steps_per_year=252)","handlingStrategy":"validation","validationCode":"steps_per_year = max(1, int(round(steps_per_year)))","typeGuard":"def is_valid_steps_per_year(x) -> bool:\n    return isinstance(x, (int, float)) and not isinstance(x, bool) and x >= 1","tryCatchPattern":"try:\n    paths = monte_carlo_gbm(..., steps_per_year=spy)\nexcept ValueError as e:\n    if \"steps_per_year\" in str(e):\n        paths = monte_carlo_gbm(..., steps_per_year=int(round(1 / spy)) if 0 < spy < 1 else int(spy))\n    else:\n        raise","preventionTips":["Remember the convention: 252 = daily, 52 = weekly, 12 = monthly","If you hold dt, pass steps_per_year=1/dt","Document units next to config keys"],"tags":["quantlib","risk","monte-carlo","gbm","time-discretization","valueerror"],"backgroundTag":"argument-out-of-range","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}