“该策略基于票房收益增长交易CRSP或标普500指数,如果日增长超过15%,则做多,否则做空,反映了娱乐驱动的市场情绪。”

I. 策略概要

该策略使用CRSP等权重指数或标普500指数,并纳入来自Box Office Mojo的票房收益数据。每日票房收益增长(Changebox)计算为当季平均收益或前一周收益的百分比变化。实际上,Changebox计算为第d天和第d-7天的每日收益之差,除以第d-7天的收益。如果Changebox超过15%,则在第d天结束时做多;否则,做空。这种方法利用娱乐业的表现作为投资者情绪的代理,可能影响股票市场回报。

II. 策略合理性

票房收益是可自由支配消费的有效代理,反映了大量人口的消费习惯,2016年有71%的美国人去过电影院。该数据公开可用,并与GDP增长和可支配收入呈正相关,捕捉的是真实消费变化,而不是借入资金的变化。研究表明,票房收益也与行业投资组合回报呈正相关,排除了行业特定的偏差。然而,票房收益对股票回报的预测能力仅限于4天窗口,因此需要高换手率的投资策略,以利用由可自由支配支出趋势驱动的短期市场波动。

III. 来源论文

Is it Time for Popcorn? Daily Box Office Earnings and Aggregate Stock Returns [点击查看论文]

<摘要>

我们定量地衡量了每日消费与股票市场之间的相互作用。我们发现,以剧院票房收益的周期性成分为代表的每日消费,可以在长达五天的时间内显著且积极地预测股票回报。我们还展示了一种使用我们的消费指标的交易策略,该策略以很小的风险产生可观的超额回报。这些发现表明,票房效应是股票市场的一个重要的经济因素。该框架暗示,每日消费携带与价值相关的公共信息,从而导致每日频率的价格反应。

IV. 回测表现

年化回报27.13%
波动率N/A
β值-0.363
夏普比率N/A
索提诺比率-1.486
最大回撤N/A
胜率31%

V. 完整的 Python 代码

from AlgorithmImports import *
#endregion
class DailyBoxOfficeEarningsandAggregateStockReturns(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2010, 1, 1)
        self.SetCash(100000)
        
        self.symbol = self.AddEquity("SPY", Resolution.Daily).Symbol
        
        # Daily box data indexed by date.
        self.daily_box_data = {}
        
        # Import daily box data.
        # Data source: https://www.boxofficemojo.com/daily/2020/?view=year
        daily_box_string_data = self.Download('data.quantpedia.com/backtesting_data/economic/daily_box_earnings.csv')
        lines = daily_box_string_data.split('\r\n')
        for line in lines[1:]:
            split_line = line.split(';')
            date = datetime.strptime(split_line[0], "%Y-%m-%d").date()
            
            if split_line[5] == '-':
                weekly_change = None
            else:
                weekly_change = float(split_line[5])
            
            self.daily_box_data[date] = weekly_change
        
    def OnData(self, data):
        date_to_lookup = (self.Time - timedelta(days = 1)).date()
        
        if date_to_lookup in self.daily_box_data:
            weekly_change = self.daily_box_data[date_to_lookup]
            if weekly_change:
                if weekly_change > 15:
                    self.SetHoldings(self.symbol, 1)
                else:
                    self.SetHoldings(self.symbol, -1)
        else:
            self.Liquidate()

发表评论

了解 Quant Buffet 的更多信息

立即订阅以继续阅读并访问完整档案。

继续阅读