quantlab.runs.backtest_stats.win_rates#
- quantlab.runs.backtest_stats.win_rates(returns, rebalances, *, ranges, benchmark_returns=None)[source]#
Return the share of holding periods and of months the strategy won, in percent.
A holding period runs from the fill bar of one decided rebalance (the bar after it) up to the bar before the next one’s, whether or not its orders filled; a delisting settlement or a held bar starts none, and the bars before the first fill bar hold nothing and are left out. A month is a calendar month of the bar labels. Each period’s per-bar returns inside
rangesare compounded; the strategy wins a period when its return beats the benchmark’s, or, without a benchmark, when it is positive. A bar where either return is NaN, or at or below -100% (a value that reached zero, whose log return does not exist), is left out, and a slice with no period gives NaN.- Parameters:
- returnsxarray.DataArray
The strategy’s per-bar returns on a
timestampaxis.- rebalancesarray_like of datetime64
The bars of the decided rebalances (the rebalance record’s
decidedbars); each starts a period on the bar after it.- rangessequence of (str, str)
Inclusive bar-label ranges of the slice; bars outside them are left out.
- benchmark_returnsxarray.DataArray, optional
The benchmark’s per-bar returns on the same bars. Without it a period is won when its return is positive.
- Returns:
- dict
Rebalance Win Rate [%]andMonthly Win Rate [%], with `` vs Benchmark`` before `` [%]`` whenbenchmark_returnsis given.
Examples
Decided on bars 0 and 2, so the periods are bars 1 to 2 (lost) and bars 3 to 4 (won):
>>> bars = pd.bdate_range("2024-01-01", periods=5) >>> returns = xr.DataArray([0.0, 0.01, -0.02, 0.01, 0.01], dims="timestamp", coords={"timestamp": bars}) >>> win_rates(returns, bars[[0, 2]].values, ranges=[("2024-01-01", "2024-01-05")]) {'Rebalance Win Rate [%]': 50.0, 'Monthly Win Rate [%]': 100.0}