The strategy trades CRSP or S&P 500 based on box office earnings growth, going long if daily growth exceeds 15% and short otherwise, reflecting entertainment-driven market sentiment.

I. STRATEGY IN A NUTSHELL

Uses box office earnings growth to trade stocks. If weekly earnings rise >15%, go long; otherwise, go short. Leverages consumer sentiment as a short-term market signal.

II. ECONOMIC RATIONALE

Box office reflects discretionary spending and GDP-linked consumption. Strong earnings indicate positive investor sentiment; weak earnings signal caution. Predictive effect lasts about 4 days, requiring high-turnover trading.

III. SOURCE PAPER

Is it Time for Popcorn? Daily Box Office Earnings and Aggregate Stock Returns [Click to Open PDF]

Seda Oz, University of Waterloo – School of Accounting and Finance; Steve Fortin, University of Waterloo – School of Accounting and Finance

<Abstract>

We quantitatively measure the interactions between daily consumption and the stock market. We find that daily consumption, proxied by the cyclical component of theatrical box office earnings, can significantly and positively predict stock returns for up to five days. We also demonstrate a trading strategy using our consumption measures that yield non-trivial excess returns with little risk. These findings suggest that the box office effect is an economically important factor for equities. The framework implies that daily consumption carries value-relevant public information, which leads to price reaction at a daily frequency.

IV. BACKTEST PERFORMANCE

Annualised Return27.13%
VolatilityN/A
Beta-0.363
Sharpe RatioN/A
Sortino Ratio-1.486
Maximum DrawdownN/A
Win Rate31%

V. FULL PYTHON CODE

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()

VI. BACKTEST PERFORMANCE

Leave a Reply

Discover more from Quant Buffet

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

Continue reading