在月末前1天(有些研究建议4天)买入SPY ETF,并在新月第3个交易日收盘时卖出。

策略概述

该策略要求投资者在每月结束前1天(或4天)买入SPY ETF,该ETF追踪标普500指数的表现,并在新月第3个交易日收盘时卖出。该方法旨在利用月末和月初期间市场情绪和流动性的预期变化,从这些可预测的模式中获取短期收益。策略依赖于精准的买卖时机,以捕捉股票市场的微小、定期波动,而非长期投资,可能为投资者提供比传统策略更具优势的回报。

策略合理性

月末效应(Turn of the Month Effect),即在月末期间股票回报较高的现象,仍是学术界的一个谜团。这种现象在小盘股、大盘股等不同类型的股票中都普遍存在,不仅限于年末或季度末的交易期,且全球30个市场都观察到了这一模式。这挑战了该效应来源于风险提升或利率变化的理论。Ogden(1990)曾提出这一现象可能与收入分配的时间点有关,投资者在月底将资金投入市场,推高了股价,但这一理论受到了质疑。McConnell和Xu的研究表明,这种异常现象没有明确的解释。一些学者认为,该现象与月度养老金资金流动以及交易模型的重新平衡有关,可能会放大这一效应。然而,采用这一策略需要谨慎,因为日历效应可能会随着时间的推移而减弱或出现不可预测的变化。

论文来源

Equity Returns at the Turn of the Month [点击浏览原文]

<摘要>

月末效应在美国股票市场中首次由Lakonishok和Smidt(1988)通过对1897-1986年间的道琼斯工业平均指数进行研究发现。根据这一效应,从月末最后一个交易日开始到三天后的股票回报明显高于其他时期。使用CRSP的每日回报数据,我们发现月末效应在1987-2005年的时间段内依然存在:在这19年(以及1897-2005年总计109年的时间段)内,几乎所有的超额市场回报都发生在这4天的月末期间。在每月的其他16个交易日内,投资者平均没有获得市场风险的回报。我们还发现,月末效应并不仅限于小盘股或低价股;也不限于12月-1月的年末月初效应;不局限于季度末;不仅存在于美国;并且不是由于传统意义上的市场风险:月末期间的回报标准差并不高于其他时期。股市回报中的这一持续性现象对“理性”与“行为”资产定价模型都提出了挑战。

回测表现

年化收益率7.2%
波动率6.9%
Beta0.202
夏普比率0.013
索提诺比率0.007
最大回撤24.6%
胜率57%

完整python代码

from AlgoLib import *

class MonthlyMarketTiming(XXX):

    def Initialize(self):
        self.SetStartDate(1998, 1, 1)  # Set the start date
        self.SetCash(100000)  # Set the initial capital
        
        self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol  # Add SPY ETF
        
        self.readyToSell = False  # Flag to trigger selling
        self.tradeDaysCount = 0  # Count trade days since buying
        
        # Schedule the buy action at the month's end
        self.Schedule.On(self.DateRules.MonthEnd(self.spy), self.TimeRules.AfterMarketOpen(self.spy), self.EnterPosition)
        # Schedule the sell action 3 trading days after the start of the month
        self.Schedule.On(self.DateRules.MonthStart(self.spy), self.TimeRules.AfterMarketOpen(self.spy), self.InitiateSell)
    
    def EnterPosition(self):
        self.SetHoldings(self.spy, 1)  # Invest all in SPY
    
    def InitiateSell(self):
        self.readyToSell = True  # Set flag to start counting days to sell
        
    def OnData(self, data):
        if self.readyToSell:
            self.tradeDaysCount += 1  # Increment the day count
            if self.tradeDaysCount == 3:  # On the third day, sell
                self.Liquidate(self.spy)  # Sell all SPY shares
                self.readyToSell = False  # Reset the flag
                self.tradeDaysCount = 0  # Reset the day count

Leave a Reply

Discover more from Quant Buffet

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

Continue reading