Introduction

The January effect is a calendar anomaly saying that small-cap stocks returns in January are especially strong. The most common explanation of this phenomenon is that individual investors, who are income tax-sensitive and who disproportionately hold small stocks, sell stocks for tax reasons at year end and reinvest during the first month of the year. In this algorithm, we will explore the January effect in the stock market.

Method

The investment universe consists of US-listed companies. A minimum stock price filter is used to avoid penny stocks. To avoid stocks that are not liquid enough, we select 1,000 stocks with the highest dollar volume.

  1. def coarse_selection_function(self, coarse):
  2. if self.monthly_rebalance:
  3. self.coarse = True
  4. coarse = [x for x in coarse if (x.adjusted_price > 10)]
  5. top_dollar_volume = sorted(coarse, key=lambda x: x.dollar_volume, reverse=True)[:1000]
  6. return [i.symbol for i in top_dollar_volume]
  7. else:
  8. return []

In the FineSelectionFunction, we sort the stocks by their market capitalization. The top 10 stocks are selected as the large-cap group and the bottom 10 stocks belong to the small-cap group.

  1. def fine_selection_function(self, fine):
  2. if self.monthly_rebalance:
  3. fine =[i for i in fine if i.earning_reports.basic_average_shares.three_months>0
  4. and i.earning_reports.basic_e_p_s.twelve_months>0
  5. and i.valuation_ratios.pe_ratio>0]
  6. sorted_market_cap = sorted(fine, key = lambda x:x.market_cap, reverse=True)
  7. symbols = [i.symbol for i in sorted_market_cap]
  8. self.top_market_cap = symbols[:10]
  9. self.bottom_market_cap = symbols[-10:]
  10. return self.top_market_cap + self.bottom_market_cap
  11. else:
  12. return []

The algorithm invests into small-cap stocks at the beginning of each January and stays invested in large-cap stocks for rest of the year. The portfolio is rebalanced every month.

  1. def on_data(self, data):
  2. if not (self.monthly_rebalance and self.coarse): return
  3. self.coarse = False
  4. self.monthly_rebalance = False
  5. stocks_invested = [x.key for x in self.portfolio if x.value.INVESTED]
  6. # invest in small cap stocks at the beginning of each January
  7. if self.time.month == 1:
  8. # liquidate stocks not in the small-cap group
  9. for i in stocks_invested:
  10. if i not in self.bottom_market_cap:
  11. self.liquidate(i)
  12. weight = 1/len(self.bottom_market_cap)
  13. for i in self.bottom_market_cap:
  14. self.set_holdings(i, weight)
  15. # invest in large cap stocks for rest of the year
  16. else:
  17. # liquidate stocks not in the large-cap group
  18. for i in stocks_invested:
  19. if i not in self.top_market_cap:
  20. self.liquidate(i)
  21. weight = 1/len(self.top_market_cap)
  22. for i in self.top_market_cap:
  23. self.set_holdings(i, weight)
+ Expand


Reference

  1. Quantpedia - January Effect in Stocks

Author

Jing Wu

August 2018