Quant BuffetRelax, Not Over Thinking

S&P 100 Long Strategy During Option Expiry Week

Log in to collect

Academic paper

Stock Returns and Option Activity over the Option-Expiration Week for S&P 100 Stocks

AuthorsChris T. Stivers; Licheng Sun

Institute
  • University of Louisville Hospital
  • ?University of Louisville
  • GHDominion University College
  • Old Dominion University

Strategy in a nutshell

Investors choose stocks from the S&P 100 index as his/her investment universe (stocks could be easily tracked via ETF or index fund). He/she then goes long S&P 100 stocks during the option-expiration week and stays in cash during other days.

Economic rationale

Academic research suggests that intra-month weekly patterns in call-related activity contribute to patterns in weekly average equity returns. Hedge rebalancing by option market makers in the largest stocks with the most actively traded options is the main reason for the abnormal stock’s returns. During option-expiration weeks, a sizable reduction occurs in option-open interest as the near-term options approach expiration and then expire. A reduction in call-open interest should be associated with a reduction in the net long call position of market makers. This implies a decrease in the short-stock positions being held by market makers to delta hedge their long call holdings.

Backtest performance

Annualised return9.3%
Volatility8.7%
Beta0.128
Sharpe ratio0.119
Sortino ratio0.056
Maximum drawdown15.1%
Win rate61%

Full Python code

from AlgoLib import *

class OptionExpirationWeekEffect(XXX):

def Initialize(self):
self.SetStartDate(2010, 1, 1)
self.SetCash(10000)

self.symbol = self.AddEquity("OEF", Resolution.Minute).Symbol

option = self.AddOption("OEF")
option.SetFilter(-3, 3, timedelta(0), timedelta(days = 60))       

self.SetBenchmark("OEF")
self.near_expiry = datetime.min

self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Monday), self.TimeRules.AfterMarketOpen(self.symbol, 1), self.Rebalance)

def OnData(self, slice):
if self.Time.date() == self.near_expiry.date():
    self.Liquidate()

def Rebalance(self):
calendar = self.TradingCalendar.GetDaysByType(TradingDayType.OptionExpiration, self.Time, self.EndDate)
expiries = [i.Date for i in calendar]
if len(expiries) == 0: return

self.near_expiry = expiries[0]

if (self.near_expiry - self.Time).days <= 5:
    self.SetHoldings(self.symbol, 1)