Apple’s maximum pain

Category : Uncategorized

Apple’s maximum pain

We make a few assumptions:

  1. Options are written more by market makers,
  2. Market makers carry inventory and rebalance,
  3. Rebalancing of options are related to the underlying asset’s trade.

As options’ expiration nears, there is an optimal (underlying asset) price point for which option payout to option holders is minimum. This optimal point it referred to as maximum pain.

As underlying asset price increases, call options’ payout increases. As it decreases, put options’ payout increases. Thus, maximum point is the optimal (minimum) payout.

*
clear all
cd "/users/mfd/desktop"

fetchyahoooptions AAPL, m(2014-01-18)
keep if day(Maturity)==18

sort Strike Type

gen strike=.
gen payout=.

local top=round(Price[1]*1.15,2.5)
local bottom=round(Price[1]*0.85,2.5)

local counter=0
forval aa=`bottom'(2.5)`top' {
	local counter=`counter'+1
	qui {
		replace Price=`aa'
		gen Payout= max(Price-Strike,0) * Open_Interest * 100 if Type=="Call"
		replace Payout= max(Strike - Price,0) * Open_Interest * 100 if Type=="Put"
		summ Payout
		drop Payout
		replace strike=`aa' in `counter'
		replace payout=r(sum)/1000000 in `counter'
	}
}

keep strike payout
drop if strike==.
format %10.2fc strike payout
format %16.2fc strike payout

twoway (line payout strike), xlabel(#30, angle(vertical))
outsheet using "1401_AAPL_maxpain.csv", replace
*


Sample outcome:
Screen Shot 2013-06-19 at 12.02.22 AM

Maximum pain is 455. If this theory is correct, we should see 455 by June 22, 2013. We should at least see a price increase from todays 431.77 level towards 455.

maximum_pain

*
clear all
cd "/users/mfd/desktop"

fetchyahoooptions AAPL, m(2014-01-18 2014-02-10 2014-03-10 2014-04-10 2014-05-10 2014-06-10 2014-07-10 2014-08-10 2014-09-10 2014-10-10 2014-11-10 2014-12-10)
sort Maturity Strike Type

levelsof Maturity, local(dates)
foreach aa of local dates {
	local bb : di %td `aa'
	gen strike_`aa'=.
	label variable strike_`aa' "Strike `bb'"
	gen payout_`aa'=.
	label variable payout_`aa' "Payout `bb'"
}

local counter=0
forval aa=480(2.5)600 {
	local counter=`counter'+1
	qui {
		replace Price=`aa'
		gen Payout= max(Price-Strike,0) * Open_Interest * 100 if Type=="Call"
		replace Payout= max(Strike - Price,0) * Open_Interest * 100 if Type=="Put"

		foreach cc of local dates {
			summ Payout if Maturity==`cc'
			replace strike_`cc'=`aa' in `counter'
			replace payout_`cc'=r(sum)/1000000 in `counter'
		}

		drop Payout
	}
}

keep strike* payout*

foreach aa of local dates {
	format payout_`aa' %6.2fc
	egen payout_`aa'_2=min(payout_`aa')
	replace payout_`aa'=. if payout_`aa'!=payout_`aa'_2
	replace strike_`aa'=. if payout_`aa'==.
	drop payout_`aa'_2
}

keep strike* payout*
collapse (firstnm) strike* payout*
xpose, clear varname
gen type="strike" if substr(_varname,1,1)=="s"
replace type="payout" if substr(_varname,1,1)=="p"
replace _varname=subinstr(_varname,"strike_","",.)
replace _varname=subinstr(_varname,"payout_","",.)
destring _varname, replace force
format %td _varname
rename _varname Maturity
rename v1 Max_Pain_Strike
order Maturity

save temp.dta, replace
keep if type=="strike"
drop type
sort Maturity
save temp_strike.dta, replace

use temp.dta, clear
keep if type=="payout"
drop type
rename Max_Pain_Strike Max_Pain_Payout
sort Maturity
merge Maturity using temp_strike.dta
order Maturity Max_Pain_Strike Max_Pain_Payout
drop _merge
sort Maturity
erase temp.dta
erase temp_strike.dta

format %8.2fc Max_Pain_Strike
format %10.2fc Max_Pain_Payout

outsheet using "140113_AAPL_max_pain.csv", replace
*


*
clear all
cd "/users/mfd/desktop"

fetchyahoooptions AAPL, m(2014-01-18 2014-02-10 2014-03-10 2014-04-10 2014-05-10 2014-06-10 2014-07-10 2014-08-10 2014-09-10 2014-10-10 2014-11-10 2014-12-10)
sort Maturity Strike Type

levelsof Maturity, local(dates)
foreach aa of local dates {
	local bb : di %td `aa'
	gen strike_`aa'=.
	label variable strike_`aa' "Strike `bb'"
	gen payout_`aa'=.
	label variable payout_`aa' "Payout `bb'"
}

local counter=0
forval aa=480(2.5)600 {
	local counter=`counter'+1
	qui {
		replace Price=`aa'
		gen Payout= max(Price-Strike,0) * Open_Interest * 100 if Type=="Call"
		replace Payout= max(Strike - Price,0) * Open_Interest * 100 if Type=="Put"

		foreach cc of local dates {
			summ Payout if Maturity==`cc'
			replace strike_`cc'=`aa' in `counter'
			replace payout_`cc'=r(sum)/1000000 in `counter'
		}

		drop Payout
	}
}

keep strike* payout*

foreach aa of local dates {
	egen payout_`aa'_2=min(payout_`aa')
	gen payout_`aa'_dist=((payout_`aa'-payout_`aa'_2)/payout_`aa'_2)*100
	drop payout_`aa'_2
	format payout_`aa' %6.2fc
	format payout_`aa'_dist %5.2fc
	order strike_`aa' payout_`aa' payout_`aa'_dist, last
}
*


Data
January 8, 2014 at 12:21AM CST: 140107_AAPL_max_pain
January 8, 2014 at 4:02PM CST: 140108_AAPL_max_pain
January 13, 2014 at 8:27PM CST: 140113_AAPL_max_pain
January 15, 2014 at 6:48AM CST: 140115_AAPL_max_pain
January 15, 2014 at 10:44AM CST: 140115b_AAPL_max_pain
January 15, 2014 at 4:52PM CST: 140115c_AAPL_max_pain
January 15, 2014 at 11:16PM CST: 140115d_AAPL_max_pain
January 16, 2014 at 8:22PM CST: 140116_AAPL_max_pain