Excess Returns

perfana.core.returns.excess_returns(ra, rb, freq=None, geometric=True)[source]

An average annualized excess return is convenient for comparing excess returns

Excess returns is calculated by first annualizing the asset returns and benchmark returns stream. See the docs for annualized_returns() for more details. The geometric returns formula is:

\[r_g = \frac{r_a - r_b}{1 + r_b}\]

The arithmetic excess returns formula is:

\[r_g = r_a - r_b\]

Returns calculation will be truncated by the one with the shorter length. Also, annualized returns are calculated by the geometric annualized returns in both cases

Parameters
  • ra (Union[DataFrame, Iterable[Union[int, float]], ndarray, Series]) – The assets returns vector or matrix

  • rb (Union[DataFrame, Iterable[Union[int, float]], ndarray, Series]) – The benchmark returns. If this is a vector and the asset returns is a matrix, then all assets returns (columns) will be compared against this single benchmark. Otherwise, if this is a matrix, then assets will be compared to each individual benchmark (i.e. column for column)

  • freq (Optional[str]) – Frequency of the data. Use one of [daily, weekly, monthly, quarterly, semi-annually, yearly]

  • geometric – If True, calculates the geometric excess returns. Otherwise, calculates the arithmetic excess returns

Returns

Excess returns of each strategy against benchmark

Return type

TimeSeriesData

Examples

>>> from perfana.datasets import load_etf
>>> from perfana.core import excess_returns
# Get returns starting from the date where all etf has data
>>> etf = load_etf().dropna().pa.to_returns().dropna()
>>> excess_returns(etf, etf.VBK)
VBK    0.000000
BND   -0.050737
VTI   -0.009533
VWO   -0.058573
dtype: float64