quantlab.runs.backtest_stats.relative_stats#
- quantlab.runs.backtest_stats.relative_stats(returns, benchmark_returns, *, bar_interval, year_freq, ranges)[source]#
Return a strategy’s statistics relative to its benchmark over
ranges.These are the rows of the
relativeblocks ofmetrics.json(withwin_ratesagainst the benchmark). Both series are cut torangesand the bars where either is NaN are dropped. The relative NAV compounds(1 + r) / (1 + b)bar by bar (rthe strategy’s return,bthe benchmark’s); over a whole window it equals the strategy’s value divided by the benchmark’s, the excess-return curve the report draws.annisyear_freq / bar_interval, and every key ending in[%]is in percent:Strategy Total Return [%]/Benchmark Total Return [%]: compounded returns of each series;Excess Return [%]: relative NAV at the end minus 1, the geometric excess;Annualized Excess Return [%]: the same compounded to one year;Total Return Difference [%]: the arithmetic difference of the two total returns;Excess Max Drawdown [%]: the deepest fall of the relative NAV from its running peak (starting at 1), negative or 0;Tracking Error [%]: standard deviation (ddof 1) ofr - btimessqrt(ann);Information Ratio: mean ofr - btimesannover the tracking error;BetaandCorrelationofronb, andCAPM Alpha [%], the annualized interceptmean(r) - beta * mean(b);Win Rate vs Benchmark [%]: share of bars withr > b;Bars: number of bars used.
A statistic that is undefined (fewer than two bars, a flat benchmark, zero tracking error) is NaN.
- Parameters:
- returns, benchmark_returnsxarray.DataArray
Per-bar returns of the strategy and the benchmark, on the same
timestampaxis.- bar_interval
The bar spacing, anything
pd.Timedeltaaccepts.- year_freqpd.Timedelta
One year, as
year_freqreturns it.- rangessequence of (str, str)
Inclusive bar-label ranges of the slice.
- Returns:
- dict
Thirteen rows, in the order listed above.
- Raises:
- ValueError
If the two series are not on the same bars.
Examples
>>> bars = pd.bdate_range("2024-01-01", periods=3) >>> strategy = xr.DataArray([0.02, -0.01, 0.03], dims="timestamp", coords={"timestamp": bars}) >>> benchmark = xr.DataArray([0.01, 0.0, 0.01], dims="timestamp", coords={"timestamp": bars}) >>> stats = relative_stats( ... strategy, benchmark, bar_interval="1D", ... year_freq=year_freq("1D", 252, 390), ranges=[("2024-01-01", "2024-01-03")], ... ) >>> round(stats["Total Return Difference [%]"], 4), stats["Bars"] (1.9994, 3) >>> round(stats["Win Rate vs Benchmark [%]"], 2) 66.67