“该策略基于水星逆行周期的市场表现。投资者在水星逆行期结束后一周(滞后五个交易日)回补空单,并做多CSI300指数,持有至下一个逆行期前一日。逆行期开始后一周内做空CSI300,动态再平衡组合,全部资金用于此策略。”

策略概述

该策略推荐的投资标的是CSI300指数,包含了中国证券市场中具有代表性的300只股票(可以使用指数期货、ETF或差价合约进行操作)。(天文信息从Astro Seek网站提取)。滞后1周是指水星逆行期结束后一周的表现。(因此,选择的水星逆行开始和结束日期均滞后五个交易日)。“Post (1)”指的是一个完整的非水星逆行期的表现。

<策略执行>

从水星逆行结束的第二天起,再加五个交易日,回补空单(买回借入的股票),并立即买入(做多)该指数,持有至整个非逆行期结束,即下一次水星逆行周期开始的前一天(这两个时间点均滞后五个交易日),此时再次卖出(并做空)。根据日历,策略动态再平衡,整个投资组合中100%的资金用于该策略。

在水星逆行开始后一周(即五个交易日后),在当天做空CSI300(因此,滞后一周进行逆行期内的做空)。

策略合理性

作者成功构建了行为金融学的桥梁,将这些过度现象与中国股市中高频率的散户参与联系起来。高频率且规律的股票价格下跌与反转现象能够解释中国股市的过度波动性(胡、潘、王,2018)以及过度交易之谜(Odean,1999;Barber和Odean,2000)。水星逆行期间,预计会有更多的卖出行为和明显的损失厌恶心理。投资者的人口特征,如年龄、教育、星座等,也与迷信的金融决策相关。由于缺乏账户级别数据,科学家无法获得具体的个人投资者证据,这可能成为未来研究的重点。更详细的数据可以进一步揭开迷信现象的“黑箱”。

论文来源

A Natural Experiment in the Chinese Stock Market [点击浏览原文]

<摘要>

本文研究了水星逆行这一特殊天文现象对投资者决策的影响,水星逆行意指“一切都出错”。通过对中国股市的自然实验分析,我们发现水星逆行期间股价显著下跌,跌幅约为3.14%,在这些期间结束后股价出现反转。在考虑季节性、日历效应和公司特征后,水星效应依然稳健。我们的机制测试与模型假设一致,表明受到投资者高度关注的股票更容易受到迷信心理的影响。基于我们的发现,开发的迷信对冲策略可以产生年化8.73%的超额回报。

回测表现

年化收益率22.12%
波动率40.28%
Beta0.039
夏普比率0.55
索提诺比率N/A
最大回撤N/A
胜率57%

完整python代码

from AlgorithmImports import *
import data_tools
from pandas.tseries.offsets import BDay
# endregion

class MercuryRetrogradeAstrologyTradingStrategyinChineseMarket(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2000, 1, 1)
        self.SetCash(100000)
        
        self.leverage:int = 5
        self.lag:int = 5
        self.counter:Union[None, int] = None
        self.trade_direction:Union[None, int] = None

        # load custom data
        self.mercury_retrograde_calendar:Symbol = self.AddData(data_tools.MercuryRetrogradeCalendar, 'mercury_retrograde_calendar', Resolution.Daily).Symbol
        self.market:Symbol = self.AddData(data_tools.QuantpediaCSI300, 'CSI_300', Resolution.Daily).Symbol
        self.Securities[self.market].SetLeverage(self.leverage)
        self.Securities[self.market].SetFeeModel(data_tools.CustomFeeModel())

    def OnData(self, data: Slice):
        market_last_update_date:datetime.date = data_tools.QuantpediaCSI300._last_update_date
        calendar_last_update_date:datetime.date = data_tools.MercuryRetrogradeCalendar._last_update_date

        # check if data is still coming
        if self.Securities[self.market].GetLastData() and self.Time.date() >= market_last_update_date \
            or self.Securities[self.mercury_retrograde_calendar].GetLastData() and self.Time.date() >= calendar_last_update_date:
            self.Liquidate()
            return

        if self.counter is not None:
            if self.market in data and data[self.market]:
                self.counter += 1
                if self.counter == self.lag:
                    self.SetHoldings(self.market, self.trade_direction)
                    self.trade_direction = None

        if self.mercury_retrograde_calendar in data and data[self.mercury_retrograde_calendar] and self.Securities[self.market].GetLastData():
            if self.trade_direction is None:
                self.trade_direction = -1 if data[self.mercury_retrograde_calendar].status == 'start' else 1
                self.counter = 0

Leave a Reply

Discover more from Quant Buffet

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

Continue reading