Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Feature Request: Annual Returns

After running a lot of backtests, I always end up having to calculate annual returns by going to the "returns" tab, and getting all the 12 month returns for December of each year, and then averaging them to get my annual returns.

For me, the "total returns" number is actually meaningless, it should in fact be "Annual Returns" that is displayed. At the very least it should be added alongside the total returns number.

Am I the only person to need this stat?

15 responses

why would you go avg year by year? you could just get the end return and annualize that for the time period. For example your algo returns 20% over 3 years then your annual is just 1.2^(1/3)-1.
This method is more relevant anyway. Say year one you lose 30%, the next year you gain 40%. By your method, your average return is positive 5%, indicating profitability when you are actually down 2% at the end of it all: 100*(1-.3)*(1+.4) = 98

I agree annualized return is a more interesting metric than total return.

To compute the annualized return from total return you have:

1 + R = (1 + r) ^ n

with:

R: total return
r: annualized return
n: number of year

Then r = (1 + R) ^ (1 / n) - 1

These formulae assume I have an accurate measure of "years" which I really don't. I often backtest from date X to date Y - not necessarily a certain number of years. I could calculate what percentage of the year my dates are and then plug it into the formula, but really... I should just be given this stat without all the extra effort of calculating it.

Agree this would be a useful metric to surface in the GUI.

In the meantime I keep an Excel spreadsheet open as a returns calculator which is just a handy thing to have around anyways. 5 rows as follows:

Row 1: "Start Date" = whatever date your backtest starts
Row 2: "End Date" = whatever date your backtest ends
Row 3: "Present Value" which always = $100
Row 4: "Future Value" which equals Row 3 * (1 + backtest return)
Row 5: CAGR which is equal to the following formula: =RATE(YEARFRAC(B1,B2),0,-B3,B4)

That will give you CAGR over any time period since YEARFRAC does the work of figuring out the fractional years over start/end dates for you.

Thanks Matt - I guess everyone has worked around this by creating their own spreadsheets.
Although your method would save me a lot of time, it's still annoying because of the extra effort required (i.e. entering the start date, end date and total returns). I just want it displayed to me as soon as the backtest completes.

Me so greedy :D

Some unsolicited life advice (actually, also investing advice): focus your energy on the things you can control. Ohmmmmmmmmmmm.

As I mention in changing-the-appearance-of-the-backtest-chart
Statistic metrics on the chart not readable and needs to be changed
Components should be those which Quantopian use in contest
lined up in two separate rows one for algo second for market index.
Something like this:

Annualized Return Volatility Max Drawdown Sharpe Calmar Ratio Stability

Algo 46.35% 16.00% 10.10% 3.490 4.589 0.772

Benchmark 18.91% 21.00% 13.60% 1.000 1.391 0.500

If there will be extra space I will add Beta,Ulcer Index, Omega Ratio and Profit Factor and definetly Quantopian Score which will combine all of them.
Same statistic should be in All backtests table and in compere backtests table.

Adding some contest metrics to the UI would make sense for quants and everyone, just incredibly hard to do, the contest metrics are a separate process run independently, it would require a lot of extra processing power.
209 participating in the April contest is only 6 tenths of 1 percent of 35,000 who signed up, haven't had the clarity to buy in yet or kicked the tires and moved on.

One possibility, begin by adding a few:

context.metrics = {  
   frequency: month,  
   Return   : 1,  
   Vlty     : 1,  
   Drwdn    : 1,  
   Sharpe   : 1,  
   Calmer   : 1,  
   Stbty    : 1,  
   Beta     : 1,  
}

In logging:

Return=Price[0]/Price[-N]-1

Annualized Return=(Price[0]/Price[-N])^(n/N)-1

where N is number of bars
n is number of bars in year (252 for daily bar,252*690 for minute bar)

Replacing one formula by other on becktest chart will make happy 35000 who signed up for Quantopian.
Can somebody from Quantopian Engineering stuff prove that this, as Gary states, "incredibly hard to do"?

To my mind it takes couple of minutes for qualified professional.

Vladimir - I don't think by 'hard' Gary means implementation - I think he means maintaining efficiency - although I'm not convinced annual return would have a big impact on efficiency. Maybe adding all contest metrics, but not annual returns just by itself.

Stability calc (will need some dictionary initialization):

    import statsmodels.api as _sm  
    import numpy as _np  
    b['s_timeseries'].append(context.portfolio.portfolio_value)  
    ts = _np.array(b['s_timeseries'])  
    if ts.size < 2:  
        b['stability'] = _np.nan  
    else:  
        X = _sm.add_constant(range(0, ts.size))  
        b['stability'] = (_sm.OLS( ts, X ).fit()).rsquared  
        if chart_stability and not _np.isinf(b['stability']):  
            record(stability = b['stability'])

The reason we have a benchmark is to show/understand how the algorithm is performing relative to the benchmark. The current chart though useful, is not easy to understand this relative performance information. Many algorithms I see track the benchmark, 90% of the time in backtest, and hit a few short months of great performance, resulting in huge performance difference from the benchmark. I would rather have an algorithm that does even a fraction of percent better than than the benchmark, but do it consistently every day, week or month.

So the value I have been most interested in calculating and charting, is the difference in total returns between my algorithm and the benchmark o each day. Haven't found a solution so far.

While at that, it would be nice to track the difference between the trailing X ticks/days/weeks/months of returns between the algorithm and bench.
Haven't been able to calculate that either.

Any ideas?

Saravanan - I think you are giving way too much credit to the benchmark - it's more of a guidance than a standard.
The Beta will tell you how correlated you are with the benchmark - which seems to be what you are after.

Mohammad, i agree its a guidance. But I find very valuable as a base to better on.

Beta helps, But I would really like a visual plot of the 2 values I mention above. In my experience, it helps evaluate my algorithm.
1. Daily difference between total return of the algorithm and the total return of the benchmark
2. The difference between the last X ticks/days/weeks/months of returns of the algorithm Vs the benchmark for the same period.

Can anyone help?

Portfolio CAGR added to PvR tool. It is available as context.cagr
Appreciate having that tested by someone.
Instead of average annual returns, would it be better in the periodic logging (set to twice a year) to show the trailing previous year returns?

And/or with https://www.quantopian.com/posts/elapsed-time-run-info-and-logging-variables-when-backtest-is-done
you can run any code and log any variables periodically including automatically on the last day of the run.