{"record":{"id":"e3acde98efc4a8be","repo":"HKUDS/Vibe-Trading","slug":"delay-requires-n-1-lookahead-ban-e3acde","errorCode":null,"errorMessage":"delay requires n >= 1 (lookahead ban)","messagePattern":"delay requires n >= 1 \\(lookahead ban\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/zoo/alpha101/alpha_083.py","lineNumber":62,"sourceCode":"    'extras_required': [],\n    'requires_sector': False,\n    'universe': ['equity_us', 'equity_in', 'equity_kr'],\n    'frequency': ['1D'],\n    'decay_horizon': 5,\n    'min_warmup_bars': 7,\n    'notes': '',\n}\n\n\ndef _rolling_sum(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling window sum; warmup -> NaN.\"\"\"\n    return df.rolling(window=n, min_periods=n).sum()\n\n\ndef _delay(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Backward shift by n (lookahead-safe; n>=1 required).\"\"\"\n    if n < 1:\n        raise ValueError(\"delay requires n >= 1 (lookahead ban)\")\n    return df.shift(n)\n\n\ndef compute(panel: dict) -> pd.DataFrame:\n    \"\"\"Compute the alpha on the OHLCV+ panel and return a wide DataFrame.\"\"\"\n    close = panel[\"close\"]\n    high = panel[\"high\"]\n    low = panel[\"low\"]\n    volume = panel[\"volume\"]\n    vwap = panel[\"vwap\"]\n\n\n    # Helper aliases (local closures keep the file standalone & purity-safe).\n    rolling_sum = _rolling_sum\n    delay = _delay\n    rng_avg = safe_div((high - low), rolling_sum(close, 5) / 5.0)\n    num = rank(delay(rng_avg, 2)) * rank(rank(volume))\n    denom = safe_div(rng_avg, vwap - close)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/zoo/alpha101/alpha_083.py#L44-L80","documentation":"In alpha_083.py, _delay enforces the lookahead ban by raising ValueError when n < 1 before df.shift(n). Any lag of 0 or below in the alpha's chain aborts compute immediately with this message.","triggerScenarios":"compute() for alpha #83 passes a non-positive lag to _delay — e.g. `_delay(x, n)` where n was meant to be 1 but typed/configured as 0.","commonSituations":"Porting Alpha#83's weighted-delay formula and dropping a lag; tuning scripts iterating lags from 0; copy-paste from sibling alpha files.","solutions":["Inspect all _delay calls in alpha_083.py; make each argument >= 1","Substitute the raw frame where delay 0 was intended","Constrain lag sweeps to start at 1 (range(1, max_lag + 1))","Add a compute() smoke test"],"exampleFix":"// before\nw = _delay(close, 0) * 0.5 + _delay(close, 1) * 0.5\n// after\nw = close * 0.5 + _delay(close, 1) * 0.5","handlingStrategy":"validation","validationCode":"lags = range(1, max_lag + 1)  # sweeps start at 1, never 0\nassert all(n >= 1 for n in lags)","typeGuard":"def is_valid_delay(n: int) -> bool:\n    return isinstance(n, int) and not isinstance(n, bool) and n >= 1","tryCatchPattern":null,"preventionTips":["Begin lag ranges at 1","Use raw frame for identity lag","Review ported weighted-delay formulas term by term"],"tags":["pandas","alpha101","lookahead-bias","input-validation"],"backgroundTag":"invalid-window-argument","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}