投资范围包括中国A股市场的股票。投资者在农历正月初一对六个市场指数(包括整个A股市场)进行做多操作,投资组合按市值加权。由于策略每年仅交易一次,因此不会重新调整权重。投资者在农历正月初一买入股票,并在农历月底(28天后)卖出。

策略概述

投资范围包括中国A股市场股票。投资者在农历正月初一时对六个市场指数(包括整个A股市场)进行做多操作。投资组合按市值加权,由于策略每年仅交易一次,因此不会重新调整权重。投资者在农历正月初一买入股票,并在农历月底(28天后)卖出。

策略合理性

此前关于该主题的研究并不全面。Xiaobo Liang、Qianqiu Liu和Allan A. Zebedee(2022年9月)的贡献在于仔细研究了所谓的“农历月效应”,这种效应在中国市场上表现明显,而传统上错误地被称为太阳历的二月和三月效应,因为农历正月通常不会精确地在太阳历月初开始。税损抛售或年末“窗口装饰”假说并不能解释中国市场中的这一效应,这些假说通常被学术界接受为西方市场中的解释。因此,交易量的年末效应、买入比例和日收益率的影响,尤其在小市值公司中尤为显著。此外,在此期间举行的两个重要宏观经济事件:全国人大和政协会议(两会)也对股票表现产生了积极影响。研究者们通过严格的稳健性测试证明,在对外国人开放的B股市场上,这种效应从未出现或表现微弱。

论文来源

One Country, Two Calendars: Lunar January Effect in China’s A-share Stock Market [点击浏览原文]

<摘要>

本文从1995年1月到2019年12月,使用太阳历和农历,研究了中国A股市场的1月效应。与现有文献一致,我们未发现传统的太阳历1月效应;然而,我们观察到在农历中存在显著的1月效应,且在小市值公司中更为强烈。我们展示了税损抛售和“窗口装饰”假说无法解释中国市场的年末效应。相反,交易量和买单的年末效应有助于解释强烈的农历正月效应。作为验证性测试,我们检查了主要由外国投资者构成的B股市场,并未发现农历正月效应的证据。研究结果表明,中国金融市场更符合传统农历而非标准太阳历的周期规律。

回测表现

年化收益率4.46%
波动率5.08%
Beta0.05
夏普比率0.88
索提诺比率-0.091
最大回撤N/A
胜率68%

完整python代码

from AlgorithmImports import *
from data_tools import CustomFeeModel, GregorianLunarDates, ChinaIndexData
# endregion

class LunarMonthlyEffectInChineseStocks(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2000, 1, 1)
        self.SetCash(100000)
        
        self.leverage:int = 5

        self.liquidate_period:int = 28
        self.liquidate_on_date_flag:bool = False
        self.open_date:Union[datetime.date, None] = None
        self.liquidate_date:Union[datetime.date, None] = None

        self.fxi_flag:bool = True

        data = self.AddEquity('FXI', Resolution.Daily) if self.fxi_flag else self.AddData(ChinaIndexData, 'HANG_SENG', Resolution.Daily)
        data.SetFeeModel(CustomFeeModel())
        data.SetLeverage(self.leverage)
        self.china_market:Symbol = data.Symbol

        self.gregorian_dates:Symbol = self.AddData(GregorianLunarDates, 'gregorian_lunar_dates', Resolution.Daily).Symbol

    def OnData(self, data: Slice):
        if self.gregorian_dates in data and data[self.gregorian_dates]:
            date:str = data[self.gregorian_dates].GetProperty('gregorian_date_end_first_lunar_month')
            self.liquidate_date = datetime.strptime(date, '%d.%m.%Y').date()
            self.open_date = self.Time.date()

            if self.Time.year != 2005: # data error prevention
                if self.Securities[self.china_market].Price != 0 and self.Securities[self.china_market].IsTradable:
                    self.SetHoldings(self.china_market, 1)

        if self.Portfolio.Invested:
            if self.liquidate_on_date_flag and self.Time.date() >= self.liquidate_date:
                self.Liquidate()

            elif not self.liquidate_on_date_flag and (self.Time.date() - self.open_date).days >= self.liquidate_period:
                self.Liquidate()

Leave a Reply

Discover more from Quant Buffet

Subscribe now to keep reading and get access to the full archive.

Continue reading