Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Triple MA crossover: great performance (without trading Apple)

As suggested by Alberto Sfolcini in this thread I implemented a triple moving average strategy which I found here. The idea is rather simple, if the current price exceeds the 4, 8 and 21 day moving average, buy and hold for 5 days, then sell.

Despite this being quite simple it works surprisingly well.

Note that there is no Apple in this portfolio. Ideally I think one could just randomly sample a portfolio. That way there would be no survivorship or data snooping bias in the algorithms.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

9 responses

@Thomas - what would like to see for an api call to pick N stocks at random? If N were large, like 500 or 1000, would you still want your algorithm to trade in all the stocks?

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

@fawce: In the simplest case a function get_random_sid(dt) with dt being the time sid must have been traded. To construct a portfolio I would call this in a for loop. An additional feature would be what kind of stock to select, e.g. one from S&P500 etc. Importantly, I think there should be a feature so that I will get the same portfolio in a different backtest of the same algorithm again (in which case I could just provide a seed). So the extended call might look like:

get_random_sid(dt, group='S&P', seed=1234)

I haven't really considered a portfolio that large but I think the use case would be that one just wants to run statistical analysis and identify a few that have a certain property (e.g. the ones that are most cointegrated as done here) and then only trade those.

@Thomas - Very cool algorithm. But I wonder if as a group we are NASDAQ biased, and that this will influence our thinking. I tested your algorithm with less tech-heavy stocks, and things did not work out so well. I chose Comcast (1638), Anheuser Busch (1166), Home Depot (3496), American Express (679) and Abbott Laboratories (62), all of which were in my own portfolio in 2007. These are obviously spread across diverse sectors. Result was -70% return, but it did not run longer than 4 years before exceeding the maximum daily loss. It sounds like there needs to be some correlation between the stocks used in this algorithm in order for it to work, i.e. when the short term average rises above the long term average, it has to mean that that particular security is outperforming its' peers, not the rest of the market. Am I understanding what you're trying to do?

@Ed - I totally agree and was expecting there to be some bias in my portfolio selection that produced this outcome. Thanks for highlighting this fact!

I think you raise a really critical point. How would we as a community remedy this problem of (NASDAQ) bias? One way would be to use random stocks as I proposed above. Another one would be to chose a fairly diverse set of benchmark stocks that we test our algorithms on to be able to compare them across algorithms. This is similar to what the machine learning community is doing where they test the algorithms on some benchmark datasets to make them comparable.

I think there is a minor confusion with the algorithm. Each security is treated independently. So if one crosses its own 3 moving averages a buy order is issued for this stock only. So the same strategy could be applied to an individual stock and I don't expect correlations to play a role.

Certainly this is a momentum based algorithm and as such it will work well on stocks with momentum. This is the polar opposite of mean-reverting strategies (like the pair trading). In fact, a momentum based strategy will do very poorly if the security is mean-reverting because you are buying once the price drifted away from the mean and shortly before it will fall back to its mean. So it would be interesting to see whether my portfolio has more momentum and yours more mean-reverting properties.

@Thomas - I think the idea of a set of benchmark stocks (actually several, for different test types) would be extraordinarily useful, at least for newbies like me who really need some kind of reality check when testing out adventurous (read 'questionable') new algorithms.

I have come quickly to the conclusion that unless one can identify stock behavior/types at a given point in time (e.g. Apple is a momentum stock this year, Home Depot is mean-reverting), and/or when they make the transition from one type to another, the most robust algorithms will somehow need to use elements of both approaches. Of course that will means there is a risk they will not perform well in any situation!

Hi Thomas - How would you use walk-forward optimization to optimize your parameters? i.e. why are you holding for 5 days, etc

Hey Vishal. That's actually a good question. The reason I chose 5 is because the blog post describing the technique said 5 but that's not a satisfying reason.

To fit this in a walk-forward way one might optimize parameters over a year and test on the second, optimize on the third, test on the forth year etc.

The much more difficult question (to me) is whether we can expect optimization algorithms to perform well here. If we restrict ourselves to integer values for the days, everything gradient-based is already out of the picture. Something like Genetic Algorithms perhaps? My gut feeling is that this might also not work so well here (or be overkill). Maybe the simplest and most direct option of using brute-force exploration is the way to go in this case. The answer will probably not be 1000 days so the parameter space is pretty limited. What do you think?

Hi Thomas,

For this problem, you need to take a "stochastic grid-search" style approach, where you take random samples, and then cross your fingers and hope your simulation converges to a solution that maximizes return. :)

That said, I would never trust MA crossover as being the sole candidate for an entry/exit condition. You should couple it with a classifier; define a feature set, an appropriate target (say 2-states, or 5 if you have enough data to avoid the curse of dimensionally). Then train it with either HMM or Logit+L1 (from sklearn) [please feel free to point me to a good/tested/well-documented python/cython implementation of a multi-layed NN, if you know of one]. Then use the classifier with (say) MA crossover to choose your entry condition. You can also do some data snooping with your classifier, by looking for entry conditions that pre-date large-moves.

have you updated this code as it doesn't run as is anymore if you clone it.