HKUDS/Vibe-Trading · error · ValueError

factor_panel and forward_returns must be non-empty

Error message

factor_panel and forward_returns must be non-empty

What it means

Both factor_panel and forward_returns must be non-empty DataFrames (dates x assets); an empty input leaves no cross-sections to correlate so the function bails out early.

Source

Thrown at agent/src/quantlib/factormodel.py:778

    Args:
        factor_panel: DataFrame of factor scores (index = dates, columns = assets).
        forward_returns: DataFrame of forward returns (same shape and alignment; should be pre-shifted by caller).
        method: Correlation method, ``'spearman'`` (Rank IC) or ``'pearson'`` (Linear IC).
        min_cross_section: Minimum number of valid assets on a date to compute IC.

    Returns:
        :class:`FactorICResult` containing mean IC, IC IR, t-statistic, p-value,
        higher moments, and full IC time series.

    Raises:
        ValueError: If inputs are empty, share no common dates or assets, or method is unknown.
    """
    if method not in ("spearman", "pearson"):
        raise ValueError(f"method must be 'spearman' or 'pearson', got {method!r}")

    if factor_panel.empty or forward_returns.empty:
        raise ValueError("factor_panel and forward_returns must be non-empty")

    # Align dates and assets
    common_dates = factor_panel.index.intersection(forward_returns.index)
    common_assets = factor_panel.columns.intersection(forward_returns.columns)

    if common_dates.empty or common_assets.empty:
        raise ValueError("No common dates and assets between factor_panel and forward_returns")

    f_sub = factor_panel.loc[common_dates, common_assets]
    r_sub = forward_returns.loc[common_dates, common_assets]

    ic_records: dict[object, float] = {}

    for date in common_dates:
        f_row = f_sub.loc[date].dropna()
        r_row = r_sub.loc[date].dropna()
        shared = f_row.index.intersection(r_row.index)
        if len(shared) < min_cross_section:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Check .empty on both frames before calling
  2. Verify the upstream date/asset query actually returned data
  3. Log shapes of both panels at ingest time

Example fix

# before
ic = factor_ic_analysis(panel, rets)
# after
ic = factor_ic_analysis(panel, rets) if not (panel.empty or rets.empty) else None
Defensive patterns

Strategy: validation

Validate before calling

assert not factor_panel.empty and not forward_returns.empty

Prevention

When it happens

Trigger: factor_panel=pd.DataFrame() or forward_returns sliced to zero rows by a date filter.

Common situations: Empty date-range query upstream; data pull failed silently and returned an empty frame; over-aggressive dropna removed everything.

Related errors


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