microsoft/qlib · error · ValueError

risk_analysis accumulation mode {mode} is not supported. Exp

Error message

risk_analysis accumulation mode {mode} is not supported. Expected `sum` or `product`.

What it means

risk_analysis computes cumulative statistics in one of two accumulation modes: 'sum' (simple returns summed) or 'product' (compound growth via (1+r).cumprod()). Any other value of mode falls through to this ValueError, because annualized return and max drawdown formulas differ between the two and no default is assumed.

Source

Thrown at qlib/contrib/evaluate.py:82

    if mode == "sum":
        mean = r.mean()
        std = r.std(ddof=1)
        annualized_return = mean * N
        max_drawdown = (r.cumsum() - r.cumsum().cummax()).min()
    elif mode == "product":
        cumulative_curve = (1 + r).cumprod()
        # geometric mean (compound annual growth rate)
        mean = cumulative_curve.iloc[-1] ** (1 / len(r)) - 1
        # volatility of log returns
        std = np.log(1 + r).std(ddof=1)

        cumulative_return = cumulative_curve.iloc[-1] - 1
        annualized_return = (1 + cumulative_return) ** (N / len(r)) - 1
        # max percentage drawdown from peak cumulative product
        max_drawdown = (cumulative_curve / cumulative_curve.cummax() - 1).min()
    else:
        raise ValueError(f"risk_analysis accumulation mode {mode} is not supported. Expected `sum` or `product`.")

    information_ratio = mean / std * np.sqrt(N)
    data = {
        "mean": mean,
        "std": std,
        "annualized_return": annualized_return,
        "information_ratio": information_ratio,
        "max_drawdown": max_drawdown,
    }
    res = pd.Series(data).to_frame("risk")
    return res


def indicator_analysis(df, method="mean"):
    """analyze statistical time-series indicators of trading

    Parameters
    ----------

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use mode="sum" for simple (non-compounded) excess returns, which is qlib's typical report format.
  2. Use mode="product" when r is a ratio series that should compound (e.g. (1+r).cumprod() semantics).
  3. Check the exact spelling and casing of the mode string before the call.

Example fix

// before
res = risk_analysis(r, N=250, mode="cumprod")

// after
res = risk_analysis(r, N=250, mode="product")
Defensive patterns

Strategy: validation

Validate before calling

mode = "sum" if mode not in ("sum", "product") else mode
risk_analysis(r, N=N, mode=mode)

Type guard

def is_valid_mode(mode) -> bool:
    return mode in ("sum", "product")

Try / catch

try:
    risk_analysis(r, N=N, mode=mode)
except ValueError as e:
    if "accumulation mode" in str(e):
        raise ValueError(f"mode must be 'sum' or 'product', got {mode!r}") from e
    raise

Prevention

When it happens

Trigger: Calling risk_analysis(r, mode='cumprod') or any mode string other than exactly 'sum' or 'product' (case-sensitive).

Common situations: Typo in mode ('Product', 'sums', 'compound'); older code/notebooks using a mode name from a previous qlib API; passing None explicitly.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/5f6380c213ee0c88. Report an issue: GitHub.