{"record":{"id":"0107d5f2f25e0904","repo":"HKUDS/Vibe-Trading","slug":"delay-requires-n-1-lookahead-ban-0107d5","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_037.py","lineNumber":57,"sourceCode":"    'id': 'alpha101_037',\n    'nickname': 'Kakushadze Alpha #37',\n    'theme': ['momentum'],\n    'formula_latex': 'rank(correlation(delay(open-close,1),close,200)) + rank(open-close)',\n    'columns_required': ['open', 'close'],\n    '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': 201,\n    'notes': 'Very long lookback (>= ~100 bars); produces NaN warmup on short panels which may trigger the >95% NaN registry guard.',\n}\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    open_ = panel[\"open\"]\n\n\n    # Helper aliases (local closures keep the file standalone & purity-safe).\n    delay = _delay\n    out = rank(ts_corr(delay(open_ - close, 1), close, 200)) + rank(open_ - close)\n    return out\n","sourceCodeStart":39,"sourceCodeEnd":71,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/zoo/alpha101/alpha_037.py#L39-L71","documentation":"alpha_037.py defines the same guard: _delay raises ValueError when n < 1 because a zero/negative shift would introduce lookahead bias into the computed factor. The check runs unconditionally at the top of the helper.","triggerScenarios":"compute(panel) for alpha #37 passes a non-positive n to _delay — a mistyped constant (0) or a computed offset that collapses to 0 for certain parameter values.","commonSituations":"Editing the delay chain of Alpha#37 (which mixes multiple lags) and getting one argument wrong; parameter sweeps that include degenerate values; copy-paste between alpha files with off-by-one edits.","solutions":["Check each _delay(...) argument in alpha_037.py against the reference formula and fix any 0/negative value","Use the operand directly if the current bar is genuinely wanted","Bound user-supplied parameters: `n = max(1, n)` only if 0 is semantically acceptable as 'no lag'","Add a smoke test over a small OHLCV panel"],"exampleFix":"// before\nsig = _delay(close, 0) - _delay(close, 5)\n// after\nsig = close - _delay(close, 5)","handlingStrategy":"validation","validationCode":"for name, n in {'lag_short': lag_short, 'lag_long': lag_long}.items():\n    if not (isinstance(n, int) and n >= 1):\n        raise ValueError(f\"{name} must be an int >= 1, got {n!r}\")","typeGuard":"def is_valid_delay(n: int) -> bool:\n    return isinstance(n, int) and not isinstance(n, bool) and n >= 1","tryCatchPattern":null,"preventionTips":["Cross-check each lag against the reference Alpha#37 formula","Treat delay 0 as identity and substitute the raw frame","Validate config lags at load time"],"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"}