Daily Box Office Earnings and Aggregate Stock Returns
Log in to collectAcademic paper
Is it Time for Popcorn? Daily Box Office Earnings and Aggregate Stock Returns
Seda Oz; Steve Fortin
- CAUniversity of Waterloo
- ?University of Waterloo - School of Accounting and Finance
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.
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.
Backtest performance
Annualised return27.13%
Beta-0.363
Sortino ratio-1.486
Win rate31%
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()