@run-out Cool. Took your advice! Here's what I ended up with.

First, I wrote a simple CAGR analyzer that anyone can use:

class CAGRAnalyzer(bt.analyzers.Analyzer): """ Analyzer returning CAGR of the portfolio """ def nextstart(self): self.rets = AutoOrderedDict() self.rets.start_value = self.strategy.broker.getvalue() self.rets.start_date = self.strategy.datetime.datetime().date() def stop(self): self.rets.end_value = self.strategy.broker.getvalue() self.rets.end_date = self.strategy.datetime.datetime().date() self.rets.num_years = (self.rets.end_date - self.rets.start_date).days / 365.25 self.rets.cagr = self.calculate_cagr(self.rets.start_value, self.rets.end_value, self.rets.num_years) def calculate_cagr(self, start_value, end_value, num_years): """ The CAGR formula is: EV / BV ^ (1/n) – 1. EV and BV are the ending and beginning values, while n is the number of time periods (usually months or years) for which you are calculating an average. The ^ character means “to the power of”; we take the ratio of EV / BV and raise it to the power of 1/n. Subtracting one (one = 100%) """ return ((end_value / start_value) ** (1 / num_years)) - 1Next, I derived a real CAGR analyzer from it which pulls in a csv file of CPI data and calculates the annualized inflation rate and finally the real CAGR:

class RealCAGRAnalyzer(CAGRAnalyzer): params = (('cpi_data_file_path', None),) """ Analyzer returning the real CAGR (adjusted for inflation using values from a csv passed in with a "date" column and a "us_cpi" column """ def __init__(self): self.cpi_data_file_path = self.params.cpi_data_file_path self.cpi_data = pd.read_csv(self.cpi_data_file_path, parse_dates=['date'], index_col=0) def nextstart(self): super(RealCAGRAnalyzer, self).nextstart() self.rets.start_cpi = self.cpi_data.loc[pd.to_datetime(self.rets.start_date)]['us_cpi'] def stop(self): super(RealCAGRAnalyzer, self).stop() self.rets.end_cpi = self.cpi_data.loc[pd.to_datetime(self.rets.end_date)]['us_cpi'] self.rets.cagr = self.calculate_cagr(self.rets.start_value, self.rets.end_value, self.rets.num_years) self.rets.annualized_inflation_rate = self.calculate_cagr(self.rets.start_cpi, self.rets.end_cpi, self.rets.num_years) self.rets.real_cagr = self.annualized_real_return(self.rets.cagr, self.rets.annualized_inflation_rate) def annualized_real_return(self, nominal_cagr, annualized_inflation_rate): """ Annualized Real Return = ((1 + CAGR / 1 + annualized inflation rate) – 1) X 100 """ return (1 + nominal_cagr) / (1 + annualized_inflation_rate) - 1Though im not an expert in finance, everything looks reasonable:

start_date: 1913-01-31 end_date: 2020-11-30 start_value: $100,000.00 end_value: $38,158,746.88 num_years: 107.83 start_cpi: $9.8 end_cpi: $260.23 cagr: 5.67% annualized_inflation_rate: 3.09% real_cagr: 2.50%Thanks for the help!