This algorithm is converted from Rob Reider Enhancing Short-Term Mean-Reversion Strategies.
Universe selection is implemented each month. In coarse universe selection, stocks with the price lower than 5 or without fundamental will be dropped. Then the top 50 stocks ranked by the dollar are selected. Fine universe selection picks the stocks with the positive EV to EBITDA in those top 50.
Those stocks are sorted into quintiles based on five-day returns(here mean reversion period is 5 days). The long and short stocks are filtered by the extreme momentum. The equally weighted portfolio is rebalanced daily at the close. Stocks were liquidated when they dropped out of the extreme quintile.
There are three enhancements in this algorithm:
- skip the most recent day when computing the five-day mean reversion return.(compute returns from five days ago up to the previous day’s close)
- Trade the stock with low volatility (volatility is sorted into trisection to filter the low volatility stock)
- The velocity of the benchmark is used to control the leverage (The algorithm is long unless SPY has a low enough velocity) - enhancement from Jacob Shrum
The cumulative return over the entire backtesting period from 2006 to present was about 680% and the Sharpe Ratio was 0.674.
Edvinas Jablonskis
self.existing_longs = 0 self.existing_shorts = 0
Hello, I have tried using these lines of code in my own algorithm, but they dont do anything when i use them. They are meant to close any longs or shorts right?
Jing Wu
Hi edvinas_jablonskis, I try to use self.existing_longs and self.existing_shorts here to record the number of existing positions. If you want to close the positions, you could use
self.Liquidate()
This will close all open positions in your portfolio. If you want to distinguish between long and short positions
# long position if self.Portfolio[symbol].Quantity > 0: self.Liquidate(symbol) # short position elif self.Portfolio[symbol].Quantity < 0: self.Liquidate(symbol)
Edvinas Jablonskis
That does exactly what i want it to do. Thank you so much!
Wei Chian Ong
When I clone the notebook and try to run a backtest, it continually seems to be stopping mid 2011, even though I have set self.SetEndDate(2018,1,27). Any ideas why this might be happening?
I actually tried to attach a backtest to show the problem, but unfortunately everytime I attach a backtest, the browser window crashes, sorry about that.
Jing Wu
Hi Wei Chian Ong,
I cloned the algorithm and it works fine. Please see the algorithm below
Donkey Trader
Jing Wu
I am testing the algorithm Live on IB but when it places orders it shows as "Invalid".
I did not change the code, unless I need to add something before running it live?
Time,Symbol,Price,Quantity,Type,Status,Value,Tag 2018-05-31T15:00:01.391282Z,IBM,0,42,Market,7,0, 2018-05-31T15:00:06.156856Z,DIS,0,60,Market,7,0, 2018-05-31T15:00:11.000032Z,JNJ,0,49,Market,7,0,
Jing Wu
Donkey Trader, please add OnOrderEvent to check the details of the invalid order
def OnOrderEvent(self, orderEvent):
  if orderEvent.Status == OrderStatus.Invalid:
    self.Log(str(orderEvent))
Donkey Trader
Ok, thank you
Wei Chian Ong
Thanks for your reply Jing. I tried again with the newly posted algorithm and it stopped this time as well, but this time I got a log message saying I had exceeded 10,000 orders and that for unlimited orders I need to upgrade my account, so I have my answer, thank you.
Donkey Trader
I still cannot get the strategy to trade on IB live. Apart from the invalid order in the log, this is the other error I get:
Brokerage Info: System.Net.Sockets.SocketException (0x80004005): Connection refused. at System.Net.Sockets.TcpClient.Connect (System.Net.IPAddress[] ipAddresses, System.Int32 port) [0x000e9] in <59be416de143456b88b9988284f43350>:0 . at System.Net.Sockets.TcpClient.Connect (System.String hostname, System.Int32 port) [0x00007] in <59be416de143456b88b9988284f43350>:0 . at System.Net.Sockets.TcpClient..ctor (System.String hostname, System.Int32 port) [0x00006] in <59be416de143456b88b9988284f43350>:0 . at IBApi.EClientSocket.createClientStream (System.String host, System.Int32 port) [0x00001] in <157d4e40593a4bff95e01b0ef064385d>:0 . at IBApi.EClientSocket.eConnect (System.String host, System.Int32 port, System.Int32 clientId, System.Boolean extraAuth) [0x00034] in <157d4e40593a4bff95e01b0ef064385d>:0
Donkey Trader
Jing Wu let me know if I can do anything to get it to work....
Gilbert Gong
Jing Wu thanks so much for implementing this algorithm. Could you explain what this portion does?
# request the history of benchmark
pri = self.History(["SPY"], 200, Resolution.Daily)
pos_one = (pri.loc["SPY"]['close'][-1])
pos_six = (pri.loc["SPY"]['close'][-75:].mean())
# calculate velocity of the benchmark
velocity_stop = (pos_one - pos_six)/100.0
SPY_Velocity = velocity_stop
Does it compare.... yesterday's close, against the close 75 days ago? Or the mean of closes over the last 75 days?
Apollos Hill
I just read this. i'm late to the party. but wouldn't you want to rebalance bi weekly or once a month not every day? the transaction fees would eat up the capital.
Stephen Hyer
2018-09-29 12:07:21 Brokerage Info: System.Net.Sockets.SocketException (0x80004005): Connection refused. at System.Net.Sockets.TcpClient.Connect (System.Net.IPAddress[] ipAddresses, System.Int32 port) [0x000e9] in <59be416de143456b88b9988284f43350>:0 . at System.Net.Sockets.TcpClient.Connect (System.String hostname, System.Int32 port) [0x00007] in <59be416de143456b88b9988284f43350>:0 . at System.Net.Sockets.TcpClient..ctor (System.String hostname, System.Int32 port) [0x00006] in <59be416de143456b88b9988284f43350>:0 . at IBApi.EClientSocket.createClientStream (System.String host, System.Int32 port) [0x00001] in <157d4e40593a4bff95e01b0ef064385d>:0 . at IBApi.EClientSocket.eConnect (System.String host, System.Int32 port, System.Int32 clientId, System.Boolean extraAuth) [0x00034] in <157d4e40593a4bff95e01b0ef064385d>:0
This error is filling my logs every 2 minutes, 5 times each 2 min interavl. Is this affecting my performance, and if so how do I troubleshoot this. I've read elsewhere this is intended(?) and if that is the case is there a way for me to clean my logs and allow this operation to happen in the background? Any help would be greatly appreciated.
Jing Wu
Hi Stephen, this is just a notice and we automatically reconnect. There is nothing to be concerned about. If the algorithm disconnects for more than 15minutes we stop it from running and send you an email. We log those message to let users know what is happening. They can not be removed.
Kevin Yuan
Hi Jing,
I cloned your code but it takes me 160000+ seconds but still haven't been able to pass the compilation.
Could you help to check why ?
Thanks.
Alexandre Catarino
Hi Kevin Yuan, I have just run Jing's algorithm successfully without a long wait.
You were probably experiencing some issues in the server that your backtests were deployed.
Sorry about the inconvenience.
Zicai Feng
Hi Jin, Alexander
I cloned Jin's backtest (the one here in this discussion, dated May 2018). But the result look quite different (compounded return of 11% vs 20%), and that is based on exactly the same code. Has there been any change in the assumptions in some of the modules since 2018? (eg trading cost assumption?)
Zicai Feng
In addition to cloning the exact codes (above), I have made another attempt in which I changed all of the Resolution.Minute to Resolution.Daily. Obviously the result is quite different. Can you explain how they are different in the context?Â
1) Eg in the function "Long", by changing the resolution from minute to daliy, does that mean the trade is filled at the begining/end of the daily bar?Â
2) In the (original) initiatization function, the SPY resolution is minute where as the universe resolution is daily. What would be the conceptual difference when SPY resolution is daily instead?
3) just to double check, say in the function "get_prices", this event is actioned say at 10am, it asks for a historical list of daily closing data. Does that list include today's daily bar? or today's daily bar is not ready yet till close? or a partial daily bar where the OHLC are computed using data from 9.30am to 9.59999am?
many thanks
Derek Melchin
Hi Zicai,
The algorithm above uses adjusted prices when determining trades and position sizing. This may be leading to different portfolio holdings from the original backtest.
#1 When using daily data, orders are filled at the opening auction price of the following bar. Since this algorithm is using a universe selection method, we should not call `self.AddEquity` outside of the Initialize method. The security subscriptions are managed automatically by the universe selection model.
#2 In this case, since the algorithm uses intraday Scheduled Events, we need to use minute resolution.
#3 If we request historical bars at 10am, there will not be a bar returned for the current day.
Best,
Derek Melchin
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.
Jing Wu
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.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!