-
Notifications
You must be signed in to change notification settings - Fork 47
/
black_scholes.Rmd
358 lines (231 loc) · 16.5 KB
/
black_scholes.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
---
title: "Black-Scholes Option Valuation"
author: "[GitHub Contributors](https://github.com/FinancialMarkets/5MinuteFinance/graphs/contributors)"
affiliation: "Milken Institute Center for Financial Markets"
date: "08/1/2015"
logo: misq.png
css: 5min_mod.css
output: ioslides_presentation
runtime: shiny
smaller: true
---
## The Black-Scholes World
If we assume that stock options exist in a world where...
- ...the market is complete, meaning given a stock and a bond we can replicate call and put options,
- the risk-free interest rate and stock price volatility are both constant,
- and stock prices follow a lognormal distribution...
...then we can value European Call Options on Non-Dividend Paying Stocks using the Black-Scholes Formula shown on the next slide.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Black-Scholes Formula: $C_0 = S_0N(d_1) - Xe^{-rT}N(d_2)$
<style>
#col {
-moz-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
}
</style>
<!-- <div class ="columns-2"> -->
<div id="col">
*where*
$d_1 = \frac{ln(\frac{S_0}{X}) + (r+\frac{\sigma^2}{2})T}{\sigma\sqrt(T)}$
$d_2 = d_1 - \sigma\sqrt(T)$
- $C_0$ is the value of the call option at time 0.
- $S_0$: the value of the underlying stock at time 0.
- $N()$: the cumulative standard normal density function (NORMSDIST() in Excel)
- $X$: the exercise or strike price.
- $r$: the risk-free interest rate (annualized).
- $T$: the time until option expiration in years.
- $\sigma$: the annualized standard deviations of log returns.
- $e$ and $ln$ are the exponential and natural log functions respectively (EXP() and LN() in Excel).
</div>
<!-- <div class="MIfooter"><img src="mi.png" style="height:50px;"></div> -->
## Where is the Expected Return?
The groundbreaking feature of the Black-Scholes model, as opposed to earlier attempts at option valuation, is that it does not require the stock's expected return as an input.
- This is important, because we don't know the stock's expected return.
- The idea is that we don't need the expected return because we are going to hedge out risk from the stock's returns (whatever they are).
- You can also view the expected return as being already included in the stock's price, which is determined by the stock's level of risk and return.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Intuitive Grasp of the Formula
Looking at the option value formula: $C_0 = S_0N(d_1) - Xe^{-rT}N(d_2)$
You can look at the $N(d)$ terms as the likelihood that the option will be exercised at expiration (that $S_T > X$).
- If both $N(d)$ terms are close to 1, then the option's value is about $S_0 - Xe^{-rT}$ or the present stock price minus the present value of the strike price. This makes sense given that at expiration (if $S_0 > X$) the option pays $S_T - X$.
- If the option has little chance of being exercised (that is, both $N(d)$s are near 0), then the option will have a near \$0 value.
- For other values in the 0 to 1 range, the call value can be viewed as the payoff $S_0 - Xe^{-rT}$ weighted by the probability that the call is exercised.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Black-Scholes App
The following app will calculate the Black-Scholes European call option price for a set of given inputs.
- If the stock pays a dividend, then input the stock's annualized expected dividend yield.
- The calculator will adjust for the dividend by lowering the stock price by the present value of the expected dividend. In other words the stock price used in the formula will be: $S_0e^{-\delta T}$ where $\delta$ is the expected annualized dividend yield. This assumes dividends are paid *continuously* throughout the year. We'll discuss dividend adjustments later in the presentation.
- You can use the app to check your own calculations. To help, you can also choose to see $d1$ and $d2$ to also check those values.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
##
```{r, echo=FALSE, message=FALSE, warning=FALSE}
#{{{
sidebarLayout(
sidebarPanel(
div(style="height: 75px;", numericInput("Stock", "Present Stock Price", min = .01, max = 2000, value = 50, step = .05)),
div(style="height: 75px;", numericInput("Vol", "Annualized Volatility", min = .01, max = 20, value = 0.20, step = .01)),
div(style="height: 75px;", numericInput("Strike", "Strike Price", min = .01, max = 1, value = 52, step = .05)),
div(style="height: 75px;", numericInput("Rf", "Risk Free Rate", min = 0.001, max = 0.5, value = 0.01, step = .001)),
div(style="height: 75px;", numericInput("Time", "Years to Expiration", min = 0.01, max = 50, value = 1, step = .01)),
div(style="height: 75px;", numericInput("Div", "Dividend Yield", min = 0, max = 1, value = 0, step = .01))#,
## div(style="height: 75px;", radioButtons("out", "Value to See", choices = list("Call Price" = 1, "d1" = 2, "d2" = 3), selected = 1))
),
mainPanel(
renderPlot({
stock <- input$Stock
vol <- input$Vol
strike <- input$Strike
rf <- input$Rf
time <- input$Time
div <- input$Div
## adjustment for dividends
stock <- stock * exp(-div * time)
d1 <- (log(stock/strike) + (rf + (vol * vol) / 2) * time) / (vol * sqrt(time))
d2 <- d1 - vol * sqrt(time)
C <- stock * pnorm(d1) - strike * exp(-rf * time) * pnorm(d2)
# if (input$out == 1){
plot(0, ylim = c(0,1), xlim = c(0,1), type = "n", xaxt = "n", yaxt = "n", ylab = "", xlab = "", main = "Black-Scholes Call Option Valuation")
text(x = 0.5, y = 0.5, labels = paste0("Call Premium = $", round(C, 2)), cex = 3)
## text(x = 0.1, y = 0.95, labels = "Call Price", cex = 2)
text(x = 0.5, y = 0.3, labels = paste("d1 = ", round(d1, 5)))
text(x = 0.5, y = 0.2, labels = paste("d2 = ", round(d2, 5)))
# } else {
# if (input$out == 2){
# plot(0, ylim = c(0,1), xlim = c(0,1), type = "n", xaxt = "n", yaxt = "n", ylab = "", xlab = "", main = "Black-Scholes Call Option Valuation")
# text(x = 0.5, y = 0.5, labels = paste(round(d1, 5)), cex = 5)
# text(x = 0.03, y = 0.95, labels = "d1", cex = 2)
# } else {
# plot(0, ylim = c(0,1), xlim = c(0,1), type = "n", xaxt = "n", yaxt = "n", ylab = "", xlab = "", main = "Black-Scholes Call Option Valuation")
# text(x = 0.5, y = 0.5, labels = paste(round(d2, 5)), cex = 5)
# text(x = 0.03, y = 0.95, labels = "d2", cex = 2)
# }
# }
})
)
)
#}}}
```
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## How Do We Calculate the Input Parameters
The present stock price is easily observable, and the exercise price and time to maturity are aspects of the option contract. The parameters which are less easily observed are:
- Risk-free rate
- Dividend yield
- Volatility
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## The Risk Free Rate
The risk free rate should be the annualized continuously-compounded rate on a default free security *with the same maturity* as the expiration data of the option.
- For example, if the option expired in 3 months, you can use the continuously compounded annual rate for a 3-month Treasury Bill.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Dividends and Stock and Option Prices
Remember that a stock price is adjusted downward by the dividend amount when the dividend is paid. For example, say before a \$1 dividend is paid the stock is \$50. Immediately after the dividend is paid the stock's price will be \$49 (otherwise there would be an arbitrage).
- However, stock option contract terms (such as the strike price) are not adjusted for cash dividends, or stock dividends under 10\%.
- So paying dividend reduces the value of a call option and increases the value of a put.
- Note, because firms often increase or decrease their dividend payments, we can only estimate an *expected* dividend yield or payment.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Dividend Adjustments
In the Black-Scholes world (where the option is European) we can reduce the stock price by the present value of all the dividends *during the life of the option*.
- The discounting is done from the ex-dividend date to the present.
- We can use the risk-free rate, though this assumes we are certain about the amount of the dividend payment.
- Note, we only include the dividend to be paid during the life of the option. So if the option expires in a month and the next dividend paid by the stock is in two months, we do *not* include a dividend adjustment.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Volatility
Volatility (the standard deviation of log-returns) is not directly observable, and it is the toughest input to determine. Two common ways to estimate volatility:
- Use historical data
- Extracting volatility from other options
**Important Note:** Volatility is assumed to be constant in the Black-Scholes model. This is why you can estimate volatility over a historical period and use that volatility over a later period. But this assumption was made for mathematical ease, and it is not realistic.
So in the model's world, using historical volatility is fine, even though in the real world it is a poor approach.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Historical Data
We can use historical stock price data to calculate continuously compounded returns (log-returns). We can then take the standard deviation of these returns (using *STDEV()* in Excel, for example) and annualize the standard deviation, affording an estimate of annual volatility.
- To do so, we must choose our sampling frequency (daily, weekly, or monthly prices) and the amount of history to use.
- Daily prices over the last 100 days are commonly used.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Annualizing the Standard Deviation
Once we have the standard deviation of log returns, we must annualize it. To do so we use the equation below, where $\sigma_a$ and $sigma_p$ are the annual and sample period standard deviations:
$\sigma_a = \sigma_p \sqrt{\#\ periods\ in\ a\ year}$
- For example, if we are using 100 days of daily price data, and the standard deviation over those days is 0.05\%, then: $\sigma_a = 0.05\% (252) = 12.6\%$
- Above we assume 252 trading days in a year.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Interactive App
- The following app will calculate annualized historical volatility for any stock and choice of sampling frequency and length of history.
- Change the date range and see if the historical volatility changes -- remember Black-Scholes assumes constant volatility.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
##
```{r, echo=FALSE, message=FALSE, warning=FALSE, error = FALSE}
#{{{
inputPanel(
textInput(inputId = "ticker2", label = "Stock Ticker", value = "XOM"),
dateRangeInput("range", "Date Range", start = "2015-01-05", end = Sys.Date())
)
renderPlot({
devtools::install_github("joshuaulrich/quantmod", ref = "157_yahoo_502")
library(quantmod)
validate(
need(input$ticker2 != "", "Input a valid US stock ticker.")
)
stock2 <- getSymbols(input$ticker2, from = input$range[1], to = input$range[2], auto.assign = FALSE)
returns <- Delt(Ad(stock2), type = 'log')[-1]
annSD <- sd(returns) * sqrt(252) * 100
plot(0, ylim = c(0,1), xlim = c(0,1), type = "n", xaxt = "n", yaxt = "n", ylab = "", xlab = "", main = "Annualized Historical Volatility")
text(x = 0.5, y = 0.5, labels = paste(round(annSD, 2), "%", sep = ""), cex = 5)
})
#}}}
```
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Extracting Volatility from Other Options
We can also extract volatility from similar options and use that number as the volatility for our options.
- This is often referred to as 'calibrating to the market'.
- It has the benefit of being a forward-looking measure, which will take into account market expectations of the volatility from future events. Historical volatility, on the other hand, only looks backwards.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Implied vs Historical Volatility
This distinction is particularly important if there is an event which will take place during the life of the option, which hasn't happened historically.
- Consider, for example, what the consequences might be if you own options expiring in 3 months on Chevron (CVX) and in one month Congress will vote on legislation to allow unfettered exports of crude oil from the U.S. (exports are now substantially limited).
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Implied Volatility
We can extract a volatility estimate from traded options by plugging the option price into the Black-Scholes formula and solving for volatility. This volatility estimate is called the option's 'implied volatility'.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
##
```{r, echo=FALSE, message=FALSE, warning=FALSE}
#{{{
sidebarLayout(
sidebarPanel(
div(style="height: 75px;", numericInput("Stock1", "Present Stock Price", min = .01, max = 2000, value = 50, step = .05)),
div(style="height: 75px;", numericInput("Option1", "Call Option Premium", min = .01, max = 20, value = 2, step = .01)),
div(style="height: 75px;", numericInput("Strike1", "Strike Price", min = .01, max = 1, value = 52, step = .05)),
div(style="height: 75px;", numericInput("Rf1", "Risk Free Rate", min = 0.001, max = 0.5, value = 0.01, step = .001)),
div(style="height: 75px;", numericInput("Time1", "Years to Expiration", min = 0.01, max = 50, value = 1, step = .01)),
div(style="height: 75px;", numericInput("Div1", "Dividend Yield", min = 0, max = 1, value = 0, step = .01))
),
mainPanel(
renderPlot({
stock1 <- input$Stock1
option1 <- input$Option1
strike1 <- input$Strike1
rf1 <- input$Rf1
time1 <- input$Time1
div1 <- input$Div1
## adjustment for dividends
stock1 <- stock1 * exp(-1 * div1 * time1)
call.func <- function(vol){ (stock1 * pnorm((log(stock1/strike1) + (rf1 + (vol * vol) / 2) * time1) / (vol * sqrt(time1))) - strike1 * exp(-rf1 * time1) * pnorm((log(stock1/strike1) + (rf1 + (vol * vol) / 2) * time1) / (vol * sqrt(time1)) - vol * sqrt(time1)) - option1)^2 }
## L-BFGS-B seems to work. Brent did not.
result <- optim(par = 0.1, fn = call.func, method = "L-BFGS-B", lower = 0, upper = 1000)
## already annual
vol.solution <- result$par * 100
plot(0, ylim = c(0,1), xlim = c(0,1), type = "n", xaxt = "n", yaxt = "n", ylab = "", xlab = "", main = "Annualized Implied Volatility")
text(x = 0.5, y = 0.5, labels = paste(round(vol.solution, 2), "%", sep = ""), cex = 5)
})
)
)
#}}}
```
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## But What about Put Options?
So far we have only looked at call options, but can Black-Scholes also value put options?
- Yes, we can write an explicit formula for the Black-Scholes value of a European put option.
- However it is much more convenient to simply use **put-call parity**.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>
## Credits and Collaboration
Click the following links to see the [code](https://github.com/FinancialMarkets/5MinuteFinance/blob/master/Options/black_scholes/black_scholes.Rmd), [authors of this presentation](https://github.com/FinancialMarkets/5MinuteFinance/blame/master/Options/black_scholes/black_scholes.Rmd), and [all the collaborators who have contributed to 5-Minute Finance](https://github.com/FinancialMarkets/5MinuteFinance/graphs/contributors).
If you would like to make any additions or corrections to this presentation, visit our [GitHub repository page](https://github.com/FinancialMarkets/5MinuteFinance#how-to-contribute) to learn more about how to contribute.
<div class="MIfooter"><img src="mi.png" style="height:50px;"></div>