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.

def coarse_selection_function(self, coarse):
    if self.monthly_rebalance:
        self.coarse = True
        coarse = [x for x in coarse if (x.adjusted_price > 10)]
        top_dollar_volume = sorted(coarse, key=lambda x: x.dollar_volume, reverse=True)[:1000]
        return [i.symbol for i in top_dollar_volume]
    else:
        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.

def fine_selection_function(self, fine):
    if self.monthly_rebalance:
        fine =[i for i in fine if i.earning_reports.basic_average_shares.three_months>0
                              and i.earning_reports.basic_e_p_s.twelve_months>0
                              and i.valuation_ratios.pe_ratio>0]
        sorted_market_cap = sorted(fine, key = lambda x:x.market_cap, reverse=True)
        symbols = [i.symbol for i in sorted_market_cap]
        self.top_market_cap = symbols[:10]
        self.bottom_market_cap = symbols[-10:]
        return self.top_market_cap + self.bottom_market_cap
    else:
        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.

def on_data(self, data):
    if not (self.monthly_rebalance and self.coarse): return
    self.coarse = False
    self.monthly_rebalance = False
    stocks_invested = [x.key for x in self.portfolio if x.value.INVESTED]
    # invest in small cap stocks at the beginning of each January
    if self.time.month == 1:
        # liquidate stocks not in the small-cap group
        for i in stocks_invested:
            if i not in self.bottom_market_cap:
                self.liquidate(i)
        weight = 1/len(self.bottom_market_cap)
        for i in self.bottom_market_cap:
            self.set_holdings(i, weight)
    # invest in large cap stocks for rest of the year
    else:
        # liquidate stocks not in the large-cap group
        for i in stocks_invested:
            if i not in self.top_market_cap:
                self.liquidate(i)
        weight = 1/len(self.top_market_cap)
        for i in self.top_market_cap:
            self.set_holdings(i, weight)


Reference

  1. Quantpedia - January Effect in Stocks