Introduction
The momentum effect is a classic anomaly that says what was strongly going up in the past will probably continue to go up in the near future. The calculation performed uses the rate of change in price movements. We see this effect in REITs through studies where REITs with the highest annual past performance beat lower performing trusts. This strategy will take a long position in companies with the strongest momentum and rebalance quarterly.
Method
The first step is coarse and fine universe selection. During coarse selection, we create an investment universe of stocks that have prices greater than $1, contain fundamental data and do not have a very low trading volume for liquidity purposes. During the fine selection, we take all available REITs by using the Morningstar field IsREIT
.
In the fine selection, we also calculate each REIT's past 11-month return one-month lagged and rank them. This is used to determine the top tercile of portfolio.
def coarse_selection_function(self, coarse):
if self.quarterly_rebalance:
self.filtered_coarse = [x.symbol for x in coarse if (float(x.price) > 1)
and (x.has_fundamental_data)
and float(x.volume) > 10000]
return self.filtered_coarse
else:
return []
def fine_selection_function(self, fine):
if self.quarterly_rebalance:
fine = [x for x in fine if (x.company_reference.is_r_e_i_t == 1)]
start = self.time-timedelta(days = 365)
end = self.time-timedelta(days = 30)
for x in fine:
hist = self.history([x.symbol],start,end,Resolution.DAILY)
if not hist.empty:
start_price = hist["close"].iloc[0]
end_price = hist["close"].iloc[-1]
x.momentum = (end_price-start_price)/start_price
fine = [x for x in fine if hasattr(x, 'momentum')]
sorted_filter = sorted(fine, key=lambda x: x.momentum)
self.filtered_fine = [i.symbol for i in sorted_filter]
return self.filtered_fine
else:
return []
In OnData(), we buy the stocks in the best performing tercile for three months and the portfolio is rebalanced every three months by a Scheduled Event.
def on_data(self, data):
if not self.quarterly_rebalance: return
if self.filtered_fine:
portfolio_size = int(len(self.filtered_fine)/3)
long_stocks = self.filtered_fine[-portfolio_size:]
stocks_invested = [x.key for x in self.portfolio]
for i in stocks_invested:
if i not in long_stocks:
self.liquidate(i)
elif i in long_stocks:
self.set_holdings(i, 1/(portfolio_size))
self.quarterly_rebalance = False
self.filtered_fine = False
Derek Melchin
See the attached backtest for an updated version of the algorithm in PEP8 style.
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.
Gurumeher Sawhney
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!