sanz Bute 2 Sek Opn Valo em Pr: ar by es Unger Maan
Jacob Linger s2rotiowers About [ ) Signin
‘This is your last free member-only story this month. Sign up for Medium ang get an extra one
Building a Stock Option
Valuation Model with Python:
Partll
Part ll: Generating probability distributions of payoffsPhoto by MB. Mon Unsplash
In Bart, [went over how we could use the ysioc_fin module to access
stock and option pricing data, and we generated payoffs under different
scenarios.
exsnedien cone contbubineckophonhatenmthwtprtrpcHG2i 60 ae‘moot ‘sng Se pte aan Maclin Per
‘What we aim to do now is figure out an expected payoff.
by ns ner aan
Expected Payoff = > P(a
In our case, the expected payoff of an option contract is the sum of each
payoff times the probability of reaching that payoff.
For example, in part I we showed the various payoffs for an AT&T option
under scenarios ranging from a-50% price drop to a +50% price gain:
's for T200918C00022000
1500
1000
By wil
Moxinedin coicblngerbulie-tckopon basen ntact oorpaesIQZ4606 wenx Open ator oan Py
40 -20 0 20 40
Price % Change from start date to expiration
Payoff
500
If we now generate the probability of each price % change, we can then
compute the sum of the payoff and probability vectors to gain our expected
payoff.
Generating a Probability Distribution of Price
Changes
Stocks can move up and down. Predicting the price of a stock in a week is
theoretically impossible (without inside information). Yet, we can have
some idea about the relative probabilities of how a stock might move.
For example, if Procter & Gamble’s stock is trading at $135, and rarely ever
fluctuates below $110 or above $150, then itis very unlikely that it will be
Mosman iiecblngerbaline-tckoponsabatenntantorpaesiQZ4406 we$160 in a week.
ns Open Vato se nn Pr:
by ea
While we might not be able to use a stock's historical price data to predict its
price, we can use it to generate a distribution of potential price changes
based on past experience.
Hnporting required modules:
import pandas 33 pd
import nunpy as np
import matpiotiin.pyplot as plt
import random
import datetine
def delta dist (sicker, duration, sample_size):
stock = get_data(ticker) .close
Gates > list (stock. index)
duration = int (duration)
sample_size = int (sample_size)
deltas = 11
for in range (sampie size}:
ty:
x = random.randint (0, (sample_size ~ 1))
start = stockix]
stop = stock[x + duration]
Gifterence percent = (stop - start) /start
el tas append (ai ference percent)
except:
pass
return deltas
Mosman iiecblngerbaline-tckoponsabatenntantorpaesiQZ4406‘moot ‘tang Se pte aan Maclin Per Pa ab Lig Ma
Inthe code above, de1ta_ais=;) will take ina stock ticker, duration (time
period to estimate price change over), and sample_size.
Suppose we ran deits diet ( ‘aaex’ , 24, 1000) . This function would
choose 1000 random days to pull price info on Apple's stock. It will then
find the difference between the stock price of that day and 14 days ahead
for each day sampled. Iuse a txy and exces within the loop in case one of
the days sampled happened to be within the last 14 days (in which case it
could not calculate the difference, since 14 days ahead of it would be in the
future).
As shown above, we want to find probabilities over each 1% interval.
‘Therefore, we want to bin the results that geits_cist() returns:
def binned (dit ts)
for bin in range (10 fneeds to be 101
n= (pia ~ 50)*9.01
ween bins (k)
count = list (Filter (between bins, diffs))
anount = len(count) /len (diffs) dane
s -append (anount)
return (bins)
Mosman iiecblngerbaline-tckoponsabatenntantorpaesiQZ4406 we‘moot ‘sng Se pte aan Maclin Per
Using pincea i) , we can count up the frequency of times a price change falls
by ns ner aan
within each 1% interval,
Let's use Apple as an example:
fexaupie + sawpis stze 200
ges = delta dist(*AAPL', 14, 20
binned changes = binned (changes)
xaxie = np.arange(-50, 51, 1)
plt bar (axis, binned chang
pltixlabel ('stock
Pitvylabel (* Prob:
plt.titve( "AAPL: Probability pistribution- 14 day price change (Sample
Size=200) ')7
pll.savelig('ARZ_prices.png', dpi = 800)
This will generate the probability distribution of a 14 day price change
using a sample of 200 random days in which Apple was on the market:
AAPL: Probability Distribution- 14 day price change(Sample Si
ner] |
Mosman coiciblngerbutinpe-chpin abatanantantorpaesIQZ8 806 we‘moot ‘uss Se pte ear Maclin Per Pa ab Lig Ma
40 -20 0 20 40
‘Stock Price % Change
Here is what it looks like when we adjust the sample size to 9000 da
robability Distribution- 14 day price change(Sample Size=9000
0.04
Zon
E
i
Mosman iciblngerbutinpemckopon sabatanntatorpaesiQZ6s0b woe‘moot ‘tang Se pte aor Maclin Per Pa ab Lig Man
E002
0.01
0.00
40 -20 0 20 40
‘Stock Price % Change
And here is what it looks like when we look at average prices over 3 years,
rather than two weeks:
robability Distribution- 3 Year Price Change
0.010
0.008
= Alli
Moxinedin icnblngerbutine-tckoplo basen nnsantherpasIQZ4 406 woe40 -20 0 20 40
‘Stock Price % Change
‘As you might expect, the probability of larger price swings is much greater
over longer time periods.
Applying Price Change Probabi
Dataset
The options a¢ dataset from Part I contains options expiring on September
18th. Therefore, it would be useful to know the amount of time between
that expiration date and today.
ies to our Options
Todo this, we use the datetine module and subtract today’s date from the
expiration. We then create a dictionary containing each ticker as a key
along with a list containing the probability distribution from [-50% ,
+50%).
fGenerate time lapse between coday and expiration of options
Mosman iiecblngerbaline-tckoponsabatenntantorpaesiQZ4406 sone‘moot ‘sng Se pte aan Mactan Per
eimedate_until_exp ~ datetine.strptine (expiration, "$5 46, 4¥") —
gatetine.toaay 0)
igre
fconvert day nunber to integer:
time_until exp = int (timedate until. exp.days)
scenario tickers = list (set (options df.Ticker))
nunper_of_tickers = len(scenario tickers)
simulators = 2000
fdsct_of stuff will contain each ticker key corresponding to the 107
values of its distribution of price changes [-508, 508)
dict_of_probs = dict ()
for Stock in scenario tickers:
changes = delta aiat(stock, time untii exp, simlations)
distribution List = binned{ehanges)
dict_of probs.update {stock : distribution List)
‘To test that our code worked, let's sce a random example taken from
dict_of_probs.
Werity it works with example
x axis = ap.arange (750, 51, 1)
exarple = random.randint (0, sunber_of tickers - 1)
plt-bar(x axis, dict_of_probs{scenario_tickers{exanpiel!)
Mosman iiecblngerbaline-tckoponsabatenntantorpaesiQZ4406 tne‘moot ‘sng Se pte aan Masel Per Pa cab Lig Man
pltxlabel ("stock Price * Change!)
pltsylabel ("Probability")
pitstitte(str(tine until exp) +" day average $ price change for " +
Str (scenazic ticksis /exampl=]))
plt.savefig ("price exanple.pag', dpi = 800)
31 day average % price change for CRM
-20 0 20
‘Stock Price % Change
Moxinedin icnblngerbutine-tckoponsabatanntantorpaesIQZ4406 sanesoca autig ot pn ea aw Pier: ab cb ng
Success! At this point, we have both a straightforward method to generate
our payoff distribution and a dictionary containing the average % price
change distribution for each stock ticker.
Calculating Expected Payoffs
Photo by Sharon McCutcheon on Unsolash
exsnedien conte contbutinesickophonhatenmttwtprterpcHG2i60 we‘nanos surg Suen tater Ma yer Par ye
Suppose that the price of Apple stock has a 10% probability of increasing by
1% in two weeks. Let’s say you see an options contract with a 2-week
expiration that generates $20 in profit if Apple is up 1%. Therefore, the
expected payoff of that contract on the [0 1%] interval would be $20 * 0.1
= $2.
If you did this for every 1% interval of that contract (which we will assume
is from -50% to +50%), and sum up the results, then you would have the
overall expected payoff of the contract.
This is what we will do for every contract within our cptions_¢.
cun( ap.array (peobs) * np.array(payof!s) }
Moxinedin iciblngerbutine-ickoponsabasanntanthorpaesIQ24606‘moot ‘sng Se pte iar Maca Per
options _af("FxpectedPay"] ~ ExpectedPay
At this point, we now have our expected payoff for each options contract.
Let's see how the payoffs look:
plt-hist (ExpectedPay, bins = 40, cange=(-2000, 2000))
pit ixlabel ("Total Expected Gain/Loss of Contract in 3")
pit-ylabel ("Prequency")
Plt title ("Frequency of Expected Gains and Losses"):
Plt-savetig(payotte.eng', dei = 800)
Frequency of Expected Gains and Losses
1600
1400
1200
800
Frequency
600
400
Mosman iiciblngerbuline-tckopon abatanntantoerpaesiQZ4406 see‘moot ‘sng Se pte aan Mactan Pier
me ae
°
2000 -1500 -1000 -500 0 500 1000 1500 2000
Total Expected Gain/Loss of Contract in $
You will notice that most options have an expected payoff around $0. This
makes sense since the contract is hedging risk among buyer and seller.
Remember that an option is a zero-sum game. If I purchase a call option
(providing me the right to buy at the strike price), then someone else has
purchased a put option (they sell me the stock at that strike price if
exercise it).
‘Therefore, an efficient market would bring the expected value of most
contracts to zero (as buyers and sellers are not going to get ripped off).
Still, we can notice that there are contracts on the right tail that could
possibly provide profitable investments.
In practice, this dataset can provide some insight into options worth looking
ttounen cmiguchenblinr ssh pila nt wtnytengt teeswanaeet Surg Supt ttre Ptr Pry ec Lier Maan
more into. The payoffs calculated should not be used to make investment
decisions, and those looking to trade options should do further research
into why those expected payoffs are as high/low as they are.
One other significant point not yet discussed is that many of these
‘profitable’ contracts might appear so due to low liquidity. That is, the
volune and oven Taterest could both be very low, suggesting no one is
actually trading based on what the Bid-Ask spread that we use.
With that being said, I plan to further tweak this model to provide more
insight into valuing options with different expirations and to account for
low liquidity issues.
(htpsuolab resaarch gooola.comsisvconomstonosialecaS04f3e7 3sa04%484b3026180 1872 VuntledDipyr
‘Stock Options Evaluation Model: PART |
in [ 1: srpaceaces ano rormerrins
taporting required aodutes
Simoort vandas a5 0d
Mosman ciiciblngerbatine-tckoponsaasannaatyhorpaSI28 606 sme‘moot ‘2s Se pte aan Maclin Per Pa ab Lig Ma
iinport numpy 35 np
mort satplotlib-pyplot as pit
{import random
eon copy inport copy
rip install requests hen
ip install yahoo Fin
‘ron yahoo_fin.stock info import *
‘fron yahoo_fin.options import
import sath
from datetine inport date
‘fron datetine inport dacetine
‘load_ext google.colab.data_table
iunidod ext google.colab,data table #to disable
In [ 1: sGeneraving S&P 500 ist of Stocks
(Options Python DataScence France Programming