finds.backtesting.backtest
Evaluate backtests, event studies and risk premiums
Walk-forward portfolio rebalances Backtest: Sharpe ratio, appraisal ratio, …
Copyright 2022, Terence Lim
MIT License
- class finds.backtesting.backtest.BackTest(sql: SQL, bench: Benchmarks, rf: Series, max_date: int, table: str = 'backtests', verbose: int = 1)[source]
Bases:
object
Base class for computing portfolio backtest returns
- Parameters:
sql – Database connection to store results
bench – Structured dataset to retrieve riskfree and benchmark returns
rf – Column name of riskfree rate in benchmark dataset
max_date – Last date of any backtest
table – Name of table in user database to store results in
Notes
If backtest dates appears to be monthly frequency, monthly risk free rates will be retrieved and used rather than compounding from daily (reduce precision errors). Assumes that monthly risk free rates also available through {bench}, with name suffixed by “(mo)”.
Examples:
>>> backtest = BackTest(user, bench, 'RF', 20200930)
- __call__(stocks: Stocks, holdings: Dict[int, Series], label: str, overlap: int = 0) DataFrame [source]
Compute holding returns and rebalance statistics
- Parameters:
stocks – Structured data set with stocks data
holdings – Sequence of holdings keyed by rebalance date Each Series is indexed by permno, with weights in column Last item (can be empty) is dropped for calculating returns
label – Name to save this backtest
overlap – Number of months to smooth overlapping holdings
- Returns:
DataFrame of holdings returns after every rebalance data
Notes
if CRSP (i.e. ‘delist’ table exists and using monthly), include dlst returns
- fit(benchnames: List[str], beg: int = 0, end: int = 0, haclags: int = 1) DataFrame [source]
Compute performance attribution against benchmarks
- Parameters:
benchnames – Names of benchmark returns to compute attribution against
beg – date range of returns
end – date range of returns
haclags – number of Newey-West lags for robustcov statistics
- Returns:
DataFrame of excess returns performance following each rebalance date
Annualized (dict) performance ratios:
‘excess’: annualized excess (of portfolio weight*riskfree) return
‘sharpe’: annualized sharpe ratio
‘alpha’: annualized alpha
‘appraisal’: annualized appraisal ratio
‘welch-t’: t-stat for structural break after 2002
‘welch-p’: p-value for structural break after 2002
‘turnover’: annualized total turnover rate
‘buys’: annualized buy rate
‘sells’: annualized sell rate
- get_series(field: str = 'ret', start: int = 19000000, end: int = 0) DataFrame [source]
Retrieve saved backtest as a series
- plot(label: str = '', num: int = 1, flip: bool | None = False, drawdown: bool = False, figsize: Tuple[float, float] = (10, 5), marker: str | None = '', fontsize: int = 9)[source]
Plot time series of excess vs benchmark returns
- Parameters:
num – Figure number to use in plt
label – legend label
flip – Whether to flip returns. If None, then auto-detect
drawdown – To plot peak and trough points of maximum drawdown