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
- Use mode="sum" for simple (non-compounded) excess returns, which is qlib's typical report format.
- Use mode="product" when r is a ratio series that should compound (e.g. (1+r).cumprod() semantics).
- 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
- Expose only a validated mode parameter in your own API wrappers.
- Use 'sum' for qlib excess-return reports; 'product' for compounded ratios.
- Spellcheck config keys before passing them through.
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
- at least one of `N` and `freq` should exist
- indicator_analysis method {method} is not supported!
- {freq} is not supported in NumpyQuote
- {method} is not supported
- Invalid Qlib configuration (note: the global config has alre
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/5f6380c213ee0c88.
Report an issue: GitHub.