HKUDS/Vibe-Trading · error · ValueError

delay requires n >= 1 (lookahead ban)

Error message

delay requires n >= 1 (lookahead ban)

What it means

The _delay helper in alpha_032.py enforces the lookahead ban: shifting a DataFrame by n < 1 would reference the current or a future row, so it raises ValueError('delay requires n >= 1 (lookahead ban)') before df.shift(n). This is a hard precondition, not a runtime data issue.

Source

Thrown at agent/src/factors/zoo/alpha101/alpha_032.py:62

    'extras_required': [],
    'requires_sector': False,
    'universe': ['equity_us', 'equity_in', 'equity_kr'],
    'frequency': ['1D'],
    'decay_horizon': 5,
    'min_warmup_bars': 235,
    'notes': 'Very long lookback (>= ~100 bars); produces NaN warmup on short panels which may trigger the >95% NaN registry guard.',
}


def _rolling_sum(df: pd.DataFrame, n: int) -> pd.DataFrame:
    """Rolling window sum; warmup -> NaN."""
    return df.rolling(window=n, min_periods=n).sum()


def _delay(df: pd.DataFrame, n: int) -> pd.DataFrame:
    """Backward shift by n (lookahead-safe; n>=1 required)."""
    if n < 1:
        raise ValueError("delay requires n >= 1 (lookahead ban)")
    return df.shift(n)


def compute(panel: dict) -> pd.DataFrame:
    """Compute the alpha on the OHLCV+ panel and return a wide DataFrame."""
    close = panel["close"]
    vwap = panel["vwap"]


    # Helper aliases (local closures keep the file standalone & purity-safe).
    rolling_sum = _rolling_sum
    delay = _delay
    out = scale(rolling_sum(close, 7) / 7.0 - close) + 20.0 * scale(ts_corr(vwap, delay(close, 5), 230))
    return out

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Inspect every _delay call in alpha_032.py and ensure each argument is an int >= 1
  2. Replace any _delay(x, 0) with plain `x` (the identity the formula intends)
  3. Guard parameterized values at compute() entry: `if n < 1: raise ValueError(...)` with a config-specific message
  4. Add a unit test asserting compute() works on a small synthetic panel

Example fix

// before
cond = _delay(close, 0) > _delay(close, 1)
// after
cond = close > _delay(close, 1)
Defensive patterns

Strategy: validation

Validate before calling

LAGS = {'d1': 1, 'd2': 5}
assert all(v >= 1 for v in LAGS.values()), f"invalid lags: {LAGS}"
# then use _delay(df, LAGS['d1']) etc.

Type guard

def is_valid_delay(n: int) -> bool:
    return isinstance(n, int) and not isinstance(n, bool) and n >= 1

Prevention

When it happens

Trigger: compute(panel) for alpha #32 calls _delay with n <= 0 — typically a mistyped constant or a computed window (e.g. `_delay(x, d - 1)` with d == 1) inside the alpha's formula chain.

Common situations: Porting Alpha#32's definition where a delay argument is derived arithmetically; refactoring shared helpers and accidentally changing the delay argument; config-driven window parameters set to 0.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/0da6ccc223ce783a. Report an issue: GitHub.