Back to Community
Adaptive Asset Allocation algorithms

Hi all,

I’ve been playing around with some of the adaptive asset allocation strategies published in the blogosphere and I thought I would publish some of my results, I used the excellent paper, 'Adaptive Asset Allocation: A Primer', as the basis of my analysis and implemented the following algorithms,

  1. Volatility Weighted Momentum (VWM) – implemented as described in Exhibit 4 of ‘Adaptive Asset Allocation a Primer’.
    • Note – results reported with 12-month lookback
  2. Minimum Variance Algorithm (MVA) – as described in this post on the cssanalytics blog.
    • Note – results reported with 12-month lookback
  3. EAA – implemented as described in the paper ‘A Century of Generalized Momentum: From Flexible Asset Allocations (FAA) to Elastic Asset Allocation (EAA)’, by Keller and Butler
    • Note – there is an excellent implementation of this algorithm already on Quantopian here. After I found that I adapted parts of Alex's implementation in my own, hopefully I have given appropriate credit.

Next I implemented a simple equal weight algorithm that rebalances monthly. I use this algorithm as my benchmark.

I tested the above algorithms against the following sets of asset classes,

  1. Asset set #1 – inspired by the N=7 universe discussed in (A Century of Generalized Momentum – Keller/Butler, which introduces the EAA algorithm)
    • SPY (S&P 500 ETF), EFA (Developed world ex US/Canada ETF), EEM (Emerging Market ETF), QQQ (NASDAQ ETF), EWJ (Japan ETF), IEF (US Govt BND ETF)
    • Note – High Yield was removed from the set because I could not find an appropriate ETF in Quantopian that fits into the date frames tested
  2. Asset set #2 – distribution of assets across various equity markets, bonds, and real assets
    • SPY (S&P 500 ETF), EFA (Developed world ex US/Canada ETF), EEM (Emerging Market ETF), IEF (US Bond ETF), GLD (Gold ETF), IYR (US Real Estate)
    • Note, this test was designed to see how the strategies performed with a significant allocation to real assets.
  3. Asset set #3 S&P sectors
    • XLY (US Consumer Discretionary ETF), IYR (US Real Estate ETF), IYG (US Financial Services ETF), XLF (US Financial ETF), XLK (US Technology ETF), XLE (US Energy ETF), XLV (Health Care ETF), XLI (XLI Industrial SPDR Fund), XLP (XLP Consumer Staples SPDR Fund), XLB (XLB Materials SPDR Fund), XLU (XLU Utilities SPRD Fund)
    • Note, this test was designed to see how well the strategies could capture market upside.

Lastly, I ran the tests against 2 time periods, 2005-2015 YTD, and 2010-2015 YTD. The first time period was chosen to show how the algorithms behave over a full market cycle including the 2008 recession. The second time frame was chosen to show how the algorithms performed during the last few years. It is my observation that any market timing algorithm that manages to avoid the core damage of the 2008 recession does well over a 10 year backtest, but often the performance doesn’t hold up particularly well when measured over the last few years.

Here are my results,

VWM (Volatility Weighted Momentum)
Asset set #1
Time Period 1
Total Return = 137.79%, CAGR = 8.26%, Sharpe = 0.81, Sortino = 1.03, Volatility = 0.13, Max DD = 16.60%
Time Period 2
Total Return = 54.60%, CAGR = 7.64%, Sharpe = 0.53, Sortino = 0.65, Volatility = 0.13, Max DD = 15.70%

Asset set #2
Time Period 1
Total Return = 160.80%, CAGR = 9.18%, Sharpe = 1.09, Sortino = 1.48, Volatility = 0.11, Max DD = 14.90%
Time Period 2
Total Return = 44.90%, CAGR = 6.47%, Sharpe = 0.5, Sortino = 0.65, Volatility = 0.11, Max DD = 10.90%

Asset set #3
Time Period 1
Total Return = 156.00%, CAGR = 8.99%, Sharpe = .96, Sortino = 1.22, Volatility = 0.13, Max DD = 17.70%
Time Period 2
Total Return = 101.29%, CAGR = 12.55%, Sharpe = 1.08, Sortino = 1.38, Volatility = 0.14, Max DD = 17.70%

EAA (Elastic Asset Allocation)
Asset set #1
Time Period 1
Total Return = 92.70%, CAGR = 6.19%, Sharpe = 0.4, Sortino = 0.51, Volatility = 0.16, Max DD = 29.80%
Time Period 2
Total Return = 18.20%, CAGR = 2.87%, Sharpe = 0.06, Sortino = 0.08, Volatility = 0.12, Max DD = 14.60%

Asset set #2
Time Period 1
Total Return = 147.50%, CAGR = 8.66%, Sharpe = 0.64, Sortino = 0.82, Volatility = 0.17, Max DD = 37.70%
Time Period 2
Total Return = 35.00%, CAGR = 5.20%, Sharpe = 0.28, Sortino = 0.35, Volatility = 0.13, Max DD = 21.80%

Asset set #3
Time Period 1
Total Return = 142.40%, CAGR = 8.45%, Sharpe = 0.61, Sortino = 0.8, Volatility = 0.18, Max DD = 19.80%
Time Period 2
Total Return = 57.60%, CAGR = 7.99%, Sharpe = 0.47, Sortino = 0.62, Volatility = 0.16, Max DD = 19.80%

EW (Equal Weight - Rebalanced Monthly)
Asset set #1
Time Period 1
Total Return = 87.50%, CAGR =5.93%, Sharpe = 0.32, Sortino = 0.42, Volatility = 0.18, Max DD = 48.80%
Time Period 2
Total Return = 54.90%, CAGR = 7.68% Sharpe = 0.51 ,Sortino = 0.68, Volatility = 0.14, Max DD = 15.00%

Asset set #2
Time Period 1
Total Return = 99.40%, CAGR = 6.53%, Sharpe = 0.41 Sortino = 0.53, Volatility = 0.17 Max DD = 44.10%
Time Period 2
Total Return = 41.00%, CAGR = 5.98%, Sharpe = 0.38, Sortino = 0.52, Volatility = 0.12, Max DD = 13.70%

Asset set #3
Time Period 1
Total Return = 105.10%, CAGR = 6.80%, Sharpe = 0.35, Sortino = 0.43, Volatility = 0.21, Max DD = 58.40%
Time Period 2
Total Return = 101.69%, CAGR = 12.59%, Sharpe = 0.94, Sortino = 1.23, Volatility = 0.16, Max DD = 19.90%

It seems that MVA and the simple VWM algorithms hold up well across all asset groupings and time periods, while somewhat disappointingly EAA does not do as well (perhaps there is an error in my implementation).

Backtests and algos to follow.

9 responses

Here is my implementation of the VWM algorithm.

Clone Algorithm
277
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 564a24777af8221100087d4d
There was a runtime error.

Here is my implementation of the MVA algorithm.

Clone Algorithm
216
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 564a39fdb7ab0810fe763aa1
There was a runtime error.

Here is my implementation of the EAA algorithm.

Clone Algorithm
102
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 564a3a7db7ab0810fe763aaa
There was a runtime error.

Sorry I noticed that I didn't provide results for the MVA algorithm, here they are,

MVA ( Minimum Variance Algorithm)
Asset set #1
Time Period 1
Total Return = 104.30%, CAGR =6.76%, Sharpe = 0.52, Sortino = 0.66, Volatility = 0.14, Max DD = 22.70%
Time Period 2
Total Return = 42.80%, CAGR = 6.21% Sharpe = 0.36 ,Sortino = 0.43, Volatility = 0.14, Max DD = 18.90%

Asset set #2
Time Period 1
Total Return = 252.80%, CAGR = 12.24%, Sharpe = 1.65 Sortino = 2.21, Volatility = 0.13 Max DD = 16.60%
Time Period 2
Total Return = 64.70%, CAGR = 8.80%, Sharpe = 0.77, Sortino = 0.95, Volatility = 0.11, Max DD = 15.00%

Asset set #3
Time Period 1
Total Return = 184.40%, CAGR = 10.05%, Sharpe = 1.09, Sortino = 1.36, Volatility = 0.13, Max DD = 18.10%
Time Period 2
Total Return = 119.90%, CAGR = 14.25%, Sharpe = 1.22, Sortino = 1.54, Volatility = 0.15, Max DD = 18.10%

Cool

thanks your sharing, but these algorithm backtest in minutes and daily mode have some difference.

Hi Novice,

Thanks for pointing this out, I was not aware of the discrepancy in performance between running the algorithms on daily and minute data. The issue is described somewhat in this post,

https://www.quantopian.com/posts/differences-between-minute-and-daily-backtests

However it is not clear to me why a trade that is executed the next day would have such a large positive effect over a trade that is executed the next minute. Shouldn't the overall effect be net neutral, i.e., sometimes the next day price is better than the next minute sometimes it is worse? Perhaps someone from the community can help explain this.

Nevertheless, I did some testing and it seems if you change the starting balance from $1000000 to $10000 the performance goes back (for the most part) to the numbers I originally posted. So it seems this behavior is partly attributable to the way Quantopian simulates order execution.

However it is not clear to me why a trade that is executed the next
day would have such a large positive effect over a trade that is
executed the next minute. Shouldn't the overall effect be net neutral,
i.e., sometimes the next day price is better than the next minute
sometimes it is worse? Perhaps someone from the community can help
explain this.

I had found many algorithm in Quantopian community have the same issue ,
and like you it is not clear to me why a trade that is executed the next day would have such a large positive effect over a trade that is
executed the next minute,
I like the momentum algorithm than others quant algorithm , thanks your sharing.

In your VWM algorithm, what is this code doing exactly?
Can someone explain?

drop first row because it is nan

pct_change =h.iloc[[0,-2]].pct_change()[1:]