Back

Momentum Strategy with Market Cap and EV/EBITDA

This momentum universe selection strategy is converted from Johnny Wu's EV/EBITDA Value, then momentum. 

In coarse universe selection, the algorithm picked the stocks with fundamental data and excluded the stocks with low price. In fine universe selection, filtered the stocks with the positive EV/EBITDA ratio and high market cap. Here market cap was calculated by using the BasicAverageShares in earnings reports. price per share was extracted from history request. In fine universe selection, self.Porfolio[symbol].Price cannot be used to get the current price as the price data are not subscribed. 

Then the universe was ranked by EV/EBITDA and top 100 stocks were selected. The resulting screen was sorted according to the return of past 200 days. The algorithm picked the top  10 high momentum stocks. The universe is rescreened and rebalanced every month.

The strategy also added a moving average(SPY) market exit towards long-term treasuries TLT to control the downside risk. If the current SPY price is lower than last N-day moving average price, then liquidate all the open positions and buy TLT.

Update Backtest








0

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.


Hi Jing,

    The examples you posted are very helpful. Since I am more interested in intraday trading, could you post some intraday trading example. Such as the one here (by  Chuck Reilly  Dec 4, 2017)

 

 

Many thanks.

Mike

0

Hi Mike,

We don't support sentimental data and the optimization module now. The conversion of this intraday algorithm would be quite different. If there are any other intraday algorithms which can be converted welcome to post it and we'll try to add more examples.

0

I found it's hard to calculate MarketCap. Can Quantconnect just provide a simpler way like 'Fundamentals.market_cap.latest' as Quantopian does? MarketCap can be found on Morningstar's valuation section. Using BasicAverageShares in 3 months is onerous and rough.

0

Awesome! Thank you for sharing, just started with QC and Python and this example is very helpful. Love the monthly frequency too, easier to manage and replicate in real life. I'm going to try this with GLD instead of TLT and GLD/TLT 50/50 to see how those alternatives perform.

Looks like the liquidation to the safe haven fund occurs at the beginning of each month, at first I thought it would need to be monitored daily for the exit strategy, but it looks like that's monthly too. Pretty amazing results, almost to good to be true.

0

Ran it with GLD, not as good as TLT.

0


Is there a reason the resolution for SPY is at minute rather than daily here?:

self.spy = self.AddEquity("SPY", Resolution.Minute).Symbol
 
0

Hi Ton80, "SPY" here is used as the benchmark to fire schedule event functions. Here I request the minute data of SPY as time rules in two functions are specific time within a day.

1

Hi Jing,

Since your time rules are set to the top of the hour, can the SPY resolution be "hour" then?  Also,  is there a performance difference if that line is set to hour versus minute?

Thanks!

0

Hi Jon Quant, "hour" resolution for SPY also works here. There is no performance difference between hour and minute here.

0

Hi Jung Wu

Just a quick question: How did you calculate the market cap?

float(x.EarningReports.BasicAverageShares.ThreeMonths) * hist.loc[str(x.Symbol)]['close'][0] > 2e9]

Is the above it? Can you expalin about this? (what is 2e9?) Thanks.

0

Hi hanbyul_p

Yes this is how I calculate the market cap. Here price per share was extracted from the one-day history request. The price is yesterday's close

yesterday_close = hist.loc[str(x.Symbol)]['close'][0]

In fine universe selection, you cannot use self.Porfolio[symbol].Price as the price data is not subscribed. 2e9 is exponential notation which means I filter stocks with the market cap being greater than 2000000000.

1

Jing Wu, Thanks !

0

Hi Jing,

Tried running this yesterday afternoon through 3/1/2018 and received this error:

0

Hi Jung Wu ,

Nevermind, I had enddate set to 3/2/2018 and I think that caused the error since I was running it on the night of 3/1. To get the trade signals from this strategy do we have to wait until a certain time on the first or the second trading day of the month?

Thanks again!

0

Hi Ton80, this is a monthly rebalance algorithm. The rebalance() function fires at the start of each month. You need to wait until the start of the next month to get the trade signals.  

0

We explore a new method to approximate the market capitalization. The formula is 
market cap = Shares Outstanding * Price = Shares Outstanding * (Earnings Per Share * PE ratio)

In terms of fundamental variables in LEAN, 

  1. Shares outstanding is EarningReports.BasicAverageShares.ThreeMonths.
  2. Earnings Per Share is EarningReports.BasicEPS.TwelveMonths.
  3. PE Ratio is ValuationRatios.PERatio.

Instead of requesting the history close to calculate the Market cap, this method uses the fundamental data directly and could save the memory.

The updated algorithm is attached for this new method.

0


Hi @Jing Wu, I clone your algorithm and do the backtest.
However, I got errors all the time about the order quantity can't be calculated.
How to solve this? Thank you a lot.
 

159 | 05:59:23: Backtest Handled Error: The order quantity for LMT cannot be calculated: Reason: .160 | 05:59:23: Your algorithm messaging has been rate limited to prevent browser flooding.161 | 06:00:48: Backtest Handled Error: The order quantity for LMT cannot be calculated: Reason: .
0

Hi Xi Liu, this error comes from self.Setholdings(symbol, 0). Setting the holding weight to 0 would cause the calculation of order quantity to be zero if there are no holdings for that symbol in your portfolio. This could generate the error message. It is better to use self.Liquidate(symbols) to avoid the error message. These two statements are the same here and will liquidate all holdings and cancel open orders of the specified symbol.

# instead of self.SetHoldings(symbols, 0)
self.Liquidate(symbol)

0


Hi Jing Wu, can I think as:

self.SetHoldings(symbols, 0) & self.Liquidate(symbol) both works, even 'SetHoldings' may send error message?
Thank you!
0

Yes, they both work. We already fixed this problem please see the PR here

https://github.com/QuantConnect/Lean/pull/1665
0

Update Backtest





0

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.


Loading...

This discussion is closed