After two years of in-sample results and some tweaks to the first version of the system, the Fidelity Sector Fund Rotational System is ready to go live.
Based on the analysis I presented in Part 2, I have changed the inputs on system’s variables. Some were changed more than others. The goal was to set the inputs to areas that had proved to be robust over a 20 year time period and over the past 2 years. If one carefully observes the charts I present in Part 2, an educated guess can be made as to what was chosen.
I have also added a new feature which allows the primary variable, the rate-of-change (ROC), to adapt to volatility.
After re-setting the inputs, I ran a final optimization of the primary ranking mechanism, the ROC. I wanted to be sure that I had not curve-fit the system. The results are below.
Click on the graphs to enlarge…
The graph above uses over 20 years worth of data.
There is a large sweet-spot from about 105 to 135 where CAR and Maximum System % Drawdown are both very stable.
The graph above represents about 12 years worth of data.
It too shows a large sweet-spot from about 110 to 145.
These graphs demonstrate that the primary ranking mechanism still offers a large area from which to choose a setting. Warning: because I have made the ROC adaptable to volatility, simply choosing a ROC length from these graphs and using it is likely to generate a different (but still decent) future performance from this system.
I’m going to use 1.1.2000 – 1.27.2012. Starting the system back further yields better results (and you can get an idea of what they would be from previous and current graphs). The last decade or so has really been a brutal time to be in the market. Keep in mind that I can slightly alter a few inputs and make more recent performance look better. That was not my goal. Window dressing a system for the public is tempting but is ultimately ridiculous and maybe even reckless. My goal was to choose robust settings that will perform consistently well in the future, and I feel I have done so.
Equity Curve and Drawdowns:
One must expect performance to be worse and drawdowns to be larger than what they are in backtested historical results. That being said, ROC as a ranking mechanism has been unbelievably stable, as has the sector rotation model. Since I will be trading this on funds meant for retirement, I will be happy with a 10% annual return, and I believe this system will achieve it. Furthermore, it will require very little time to manage, and should have smaller drawdowns than a buy-and-hold strategy.
There are likely further tweaks or even outright changes that I have not considered, or even fathomed. I would appreciate hearing your thoughts if you think I have missed something, or if you just have a neat idea.
I did add Fidelity Bond Funds into the rotation, as suggested by MyBestFunds, but they hurt performance. I believe this is because the system punishes volatility. Since bond funds are typically less volatile than sector funds, the bond funds out-ranked and replaced sector funds from time to time in the rotation. Removing the moving average filter and including the bond funds (in hope they would be picked during bear market phases) only made things worse.
Nice work Mr. Wood. How are you going to automate trading process? As far as I read, you will check the system on a daily basis (and hold funds min. 30 days)?
I’m just going to write the purchase date on the house calendar and forget about it. I’ll run the ranking routine again when it gets near the end of the 30 day hold. Keeping it simple!
It appears you’re exiting your losers before the minimum 30 day hold period.
#bars in largest loss=22
Yep, the backtester counts trading days, not calendar days. If you add 8 days in for Sat. and Sunday, you get 30.
Ah, OK that makes sense. Thanks.
I’m writing a script to do this automatically with Yahoo quotes and send email notice of updates. I’m curious though, did you deal with ROC and volatility in a similar manner as what Michael at MarketSci did to momentum?
Sounds like a neat script. Re Stokes: not sure. Could you direct me to the post where he describes it?
6th para down, begins with “To combat…”
Skid, yes, I dealt with it exactly the same way. That is what I mean when I write that it punishes volatility.
Stokes wrote, “To combat the first issue, rather than buying the sector fund with the highest % gain over the previous 25 days, here we’re buying the one with the highest average daily % return divided by standard deviation of daily returns. Now, less volatile sectors have a chance to get in the game.”
To be clear though, this is relative only to the fund’s ROC.
I am also adjusting the ROC metric to adapt to volatility, which is different and an additional tweak from what Stokes wrote about.
How can we trade this system along with you? Get the code and get amibroker?
Dave, do you have a Fidelity account? I’d be glad to help you with it and provide the signals.
Is this easy to set up with excel? I’ve been wanting to work with fidelity funds for wife’s IRA and ETFs for me.
Duck, I could not set it up in excel. Well, I probably could, but it would not be any fun, at all. Pure drudgery. For you, maybe not so much drudgery.
However, you could set up a very basic ROC momentum ranking system in excel. But once you start adding the volatility measures, it seems to me you sheets would get very complicated. Perhaps I’m wrong.
No, but I have an E-trade account and a Muriel Siebert account that let me buy the Fidelity selects.
Dave, I’ll email you. If you want, you can beta test for me how I might distribute signals and manage other portfolios besides my own.
Sure thing, wood. Thanks. And then I can email you the picture of my electric meter box where comcast grounded their cable line to, when I called them after your fiasco. I think you’ll find it amusing.
Pretty good performance.
Do I understand you correctly, that when there are periods of high overall volatility you do a discrete switch from a longer ROC to the shorter ROC? Or is this on a fund by fund basis? I recall you mentioned having a large drawdown after a large gain; I assume this type of action drives the volatility switch.
Bozo, yes, sort of. The ROC length is constantly adjusting to volatility. Every day it will change. But yes, you have it correct in that higher volatility means a shorter ROC length.
I’m not sure that this at all affects the large drawdown that can come after a surge. I think more than any other factor, luck affects whether or not that happens.
Adjusting the ROC should help most during high volatility, when likely many funds have been punished. Using a long ROC at that point is not helpful because most will be low or negative. However, switching to a shorter ROC should catch those funds early on that have just begun to rebound.
Great stuff. Any chance of getting a copy of the AFL code? I use Amibroker, thanks.
Matt, I would be happy to send you the code for the first version of the system. It did very well in in-sample trading over the last 2 years.
I wish there was away in Amibroker, and maybe there is and someone can point us (and by us I mean me) in the right direction, to allocate equity into a bond fund or a default basket of bond ETFs in lieu of cash. While I agree with your assessment of bonds in your system, I feel like there is no better way to add uncorrelated assets than bonds. And from looking at your chart, I would guess that there is a very high amount of correlation in the Fidelity Funds. In other words, you are almost all in or all out.
My thought for how the trading mechanic would work at least for a backtest is all signals are still in place, but just add a basket of bond funds instead of going into cash, and then sell those funds when you would normally go into a new position. Instead of making the bond funds apply to your trading rules. Does any of that make sense?
Red, it makes sense. There is a way, I’m sure, and I think it involves using watchlists.
PositionScore = IIf(PositionScore < 0 , UseAnotherWatchlist, PositionScore);
Basically, rather than score= no rotate, score= use another watchlist and start over.
Does that make sense?
Perhaps someone on the Yahoo board can help? I would love to work on this with you Red.
Yes and no. First of all how would you just force the buys to occur even if they didn’t meet the buy signal. In other words, you would just want to force the backtest to own a bond fund or a group of bond funds, instead of cash.
Second, how would you force the sell signal, when buy signals returned.
Well, think about it this way.
1.If the positionscore = 0, then any ETF/Fund is sold and it just starts the process over on the bond watchlist rather than the ETF/Fund watchlist. Bonds are purchased.
2. At the end of the minimum hold time, the system ranks the ETFs/Funds. If PositionScore=0, meaning none qualify or the MA filter is still = true, then rather than selling the bonds, it starts the ranking process over on the bond watchlist. Any bonds are rotated or held, as necessary.
3. Eventually, PositionScore will not = 0, meaning the bonds will be sold and the ETF/Funds watchlist will be used to rotate back into ETF/Funds.
Just thinking out loud and fast. Hopefully it is not too muddy.
Wood, This is how PositionScore works in Rotational Systems, but not otherwise. Correct? I have never written a rotational model, so I am unfamiliar with the logic, and I was trying to force the concepts into a non rotational model in my head. However, if that is how PositionScore works in a Rotational System it makes more sense.
And that would only leave us with the problem of finding a bond fund or basket of funds that date back to 2000.
Yes, with rotational trading enabled, a positionscore of 0 means no rotate. If the holdmindays is satisfied, then it sells the position and sits in cash unless the open bond funds are still top ranked.
There are still many problems. I have no idea how to actually code it so that it switches watchlists.
I think it might be interesting to see a simple rotational model simply based upon the x number of funds, especially if you could include bonds, that had been above their MA the longest. For example, always long the five funds that have been above their 100 day MA for the longest period. Of course, this is the opposite you are doing with volatility measures.
Of course, if you examined why this logic is wrong or bad, my apologies in advance for missing it. Not really trying to improve your work, but your indepth studies set my mind to racing.
No, that is a great idea, and I’ve already written the code for it, but never tried it in a rotational strategy. Love it! I will start on it this week.
Woodshedder – thanks again for posting this fantastic work. Redshark’s idea is what I’m not think of. Select from the bond funds when the market filter takes us out of the sector funds. But as discussed, I’m not sure how to test in Amibroker either.
sorry that should have said…. what I’m now thinking of….
I’ll be looking into this bit more in the coming days. Thanks again.
Perhaps we use the moving average filter for this.
If moving average filter = true
then use bond watchlist and start over
Another point, I cannot even find a small handful of bond ETFs that all go back to 2000. Might be some mutual funds though. I would love to know anyone’s input. I have a small list of what I would determine high quality bond ETFs but even the largest do not go back very far.
As you guys go down this avenue – I suggest that you have a quick look at bond/bond fund/etf broader market correlations first. Guessing that you’re aiming for the “inherent” inverse relationship between equities and bonds – which doesn’t exist unless you target government issues (funds/etf) – even something like LQD is a non-starter. Apologies if this comment is off topic.
Berserker, I agree with your sentiment. 2008 LQD didn’t have inverse correlation that many would have looked for like something like TLT did have. However, in the most recent downturn, although small in comparison, LQD did have a small bit of inverse correlation. How that would all fit into a rotational backtest, especially looking to the fact that there is not very much history for these bond ETFs, leads to a lot of uncertainty.
Someone mentioned doing this in Excel a couple of comments above. I’ve been trying that with ETFs instead of Fidelity Funds, but the principle is the same. The reason for doing this in Excel is I actually wanted to start at the very beginning, with autocorrelations, so I would have an intuitive understanding of what was going on. It’s not real difficult, but I’ve got 3 spreadsheets of 3 to 8 MB so far. They get pretty unwieldly, and that’s with just 8 ETFs. And my intuition is still no better than before.
Bozo, thanks for confirming my suspicions. My hat is off to the guys who can code this stuff in Excel. Michael Stokes is one of them. It might be unwieldy, but you absolutely have ultimate control and the ability to make sure that everything is working as intended.
My goal was to create a simple ETF/Mutual Fund rotational model based off Faber’s paper. I started in excel and was able to calculate moving averages, but did not create much more from it. I’ve since lost that file and am starting over.
I’ve flirted with different strategies and tools for using them. Efficient market, different rotational, excel, thought about playing in R, PPT, analyzer XL, Fusion IQ, etc. In the end I realized that I would like to set up something simple that doesn’t require a lot of management of positions (little one is due in 4 weeks) and will allow for lower transaction costs (free mutual funds & ETF’s from Schwab/Fidelity). I don’t have a huge account to invest with (high 5 figures) and would like to allocate 75% or so to this simpler system, with the rest available for other trades.
So now that I’ve vomited a lot of words all over Woodshedder’s blog, I would like to start over. Any advice or tips on how to ‘start from scratch’ would be much appreciated. I’m more than happy to share some of my resources for historical data or pull custom data sets from Bloomberg in return.
I would be happy to help. I have a pretty extensive knowledge in Excel (including knowledge on the Bloomberg Add-In) as well as Amibroker. I feel that you could pretty easily replicate Faber’s work in Excel pretty easily. I could run it in Amibroker and check it against Excel. Maybe you would be interested in seeing that?
I have been without a Bloomberg Terminal for a year and half. Can you tell me if you can pull historical constitutes for specific Indexes. I seem to remember that you could, but cannot remember for certain.
Red and Duck, if you guys want to work together I’ll email both of you each other’s email addresses, assuming that what Duck has provided is correct.
Hey Wood, Just out of curiosity did you try and replicate Faber’s work with a basket of five similar ETFs. I am thinking from playing around with rotational systems and what we discussed before that it seems hard to replicate his results with ETFs. I have managed to get a pretty nice equity curve doing a long/short rotational system with a similar basket of ETFs. Returns are not spectacular, but they are consistent – which as you know has been hard to come by over the past decade or so.
The email address I use for posting is correct. Please share with Red.
I’m pretty sure Bloomberg has a historical membership function. What indices would you like to see? Give me a few days to try and pull.
I’m curious….I have setup a program based on Stokes model using highest average daily % return divided by standard deviation of daily returns and it came up with the following for the top 3 ranked FSF for 30 days ending today: FDCPX, FSDPX, and FSAVX.
Would you share what ROC method turned up? Course, I’d also be interested if the above were what Stokes came up with also…..
Skid, what ROC length are you using? What lookback are you using for the volatility calculation?
No ROC. Those picks were based on Stokes criteria, “buying the one with the highest average daily % return divided by standard deviation of daily returns”
I’m curious what the ROC returned.
Skid, here is how he calc’d it. You have to use a 25 day lookback. Hope this helps!
MarketSci on April 26, 2010 said:
RE to John French: yes sir…just to clarify:
For each sector on each day I…
1. Calculated the (geometric) avg. daily % returns over the previous 25 days.
2. Calculated the std. dev. of daily % returns over the previous 25 days.
3. Divided #1 by #2.
4. Used the highest result as my top sector on that day (which might or might not have been selected depending on whether we were past the 30 day minimum AND in an “uptrend”).
It’s great that you do the testing for 2000-2012 so that you get the worst case scenario for the returns.
However, it may well be that the risk-based return measure – Sharpe ratio and risk adjusted return – are overestimated by focusing on this period.
I ran the original code that you posted a while back.
I noticed that even though you set:
And even though I also set Settings->Trades->Buy and Sell Delay to be 1.
The amibroker backtester is still using the day the signal was generated as the buy price. For example if the system is suppose to buy a fund on day 1, and fund A has the highest score, the backtester logs it being bought at the day 1 price, not the day 2 price which is the price where you would actually be able to purchase it.
Just wondering if you are seeing the same thing in your tests, or maybe you have a solution for this issue.
Thanks for the excellent work.
Woodshedder. Thank you for the fascinating study. I too would appreciate the Amibroker code. I am an ex programmer but new to AFL. Have looked at sector rotation with Fasttack previously.