Stocks on the Move / Equity Momentum


I've started trying to implement Andrea's Clenow's 'Stocks on the Move' strategy from his book on QC. You can find an implementation of it on Quantopian here (I know there is another official thread but this is the one I followed) -

I've put where I'm at so far below. One concern I have is QC's ability to handle generating an indicator & filtering on ~700 or so securities (after coarse). The tests alone are currently quite slow but I feel I might not be doing things the most efficient way (I am using self.History query to retrieve historical data per asset to calculate the indicator).

I havn't gone too far into it yet & have only written some skeleton code but I know here are the issues I have for now:
1) Passing the self.History data to the regression_slope function to calculate the indicator

2) Returning the indicator in the dictionary, sorting, then taking the top values for trading & putting them into the self.rebal_list dictionary

3) Updating ATR for the remaining securities in self.rebal_list & sending orders based on the position sizing formula

Any help appreciated, I also figured someone might have already coded this strategy here. I will continue to work on it in the next few days as well.

Update Backtest

Latest Code Below.

Still need to get the indicator working.



I see you are updating the indicator, but it is not initialized in init. Here is a simple version of a per asset custom rolling metric class just to show some basic OOP. I will post a second backtest soon for the above code.


So I had some trouble interpreting what the code was doing or wanted to do. I made a bunch of changes but the objectives are prob far off. I would still check out my edits as they address many different issues and maybe start from there.
Coarse was always firing before rebalanced, so things were a month off(trading started in Feb, even when use of day==1 was replaced to be made more general). That was really weird behavior to fix and I'm unsure how it would have worked in live vs backtest(may need to use self.StartTime vs self.Time?). Either way I forced the reblanace to occur after coarse had a quarterly update. That needs to be further investigated though as the coarse/reblanace are now a day late

I added the class for slope as you were calculating it before. I am unsure how ATR was being used( did not go over the Q post, sorry took a bit of time to get the code to follow the comments as is). But you can re-add ATR(add a self.indicator_atr diction just like for the r2 one or simiilar).

I also added OnSecuritiesChanged to manage indicators to ensure they are initialized and removed appropriately.


Oh sorry, you will need to change UpdateIndicators in the above example to fire at the end of day, not the start. As the value desired to update is the Close price.


As per slack discussion, here is quick example of a change that adds a check to the use of History to ensure 'close' exists in the returned dataframe's columns(yah get funny stuff when casting a wide net via coarse). If not, the value remains None until updates have filled the historical window. A None check is performed when unpacking the indicator symbol/values in order to rank in the rebalannce logic.


I've also attempted to implement this strategy, I'm sure my version isn't perfect but it's also something worth giving a look, cheers! 


Hi Derek Tishler

I have been playing around with the code & having some issues with adding an ATR indicator for position sizing. I added a dictionary to keep a portfolio of symbols & added the indicator symbol class. The issues I've been having are:

1) Updating the dictionary on line 137 which is subsequently used in lines 161-162 & 179-180.

2) I dont see the cutoff being used anywhere in the filtering (self.number_stocks = 5. Should line 121 be changed from [::-1] to [:-self.number_stocks] to do this? Just checking you havn't sneakily done it somewhere else.

Sry about previous comment, not sure what happened there....


Ok, I've fixed this now.


Leigham Springer Sutton : Where can I find your version of the algorithm? 


What slack are you guys apart of? is it open to join?


Also, looking at logs when running this, I see a bunch of order issues, QC keeps mentioning margin calls. Comparing to the Quantopian version this shows it crashing 100% during 08' probably all the silly margin calls. 


tried turning it off with 

  1. self.Portfolio.MarginCallModel = MarginCallModel.Null 
Doesn't seem to work, tried different variations, still hit margin calls, and blows you up during 08, i think the default is set to 2X lev, maybe changing it to 1X will help? 

Update Backtest


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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


This discussion is closed