-
Option Payoffs 4
-
Lecture1.1
-
Lecture1.2
-
Lecture1.3
-
Lecture1.4
-
-
Binomial Model 8
-
Lecture2.1
-
Lecture2.2
-
Lecture2.3
-
Lecture2.4
-
Lecture2.5
-
Lecture2.6
-
Lecture2.7
-
Lecture2.8
-
-
Black-Scholes 6
-
Lecture3.1
-
Lecture3.2
-
Lecture3.3
-
Lecture3.4
-
Lecture3.5
-
Lecture3.6
-
-
Monte Carlo Simulations 3
-
Lecture4.1
-
Lecture4.2
-
Lecture4.3
-
Tree Visualization 1
As a quick refresher…. if we are given an interest rate r (annualized) we can find the compounded return by raising (1+r) to the number of years. For options, however, we use a continuously compounded growth rate. What this achieves is a theoretical interest rate where every second a fraction of money is earned and immediately invested. The formula to determine the compound growth is e (euler’s number) raised to r * t where t is the number or fraction of years. Note the difference in growth for a 10% annual rate vs. a 10% continuously compounded rate.
import numpy as np
import pandas as pd
#Compare what the correct continiously compounded rate is
growth = pd.DataFrame(list(range(31)), columns=['Year'])
growth["Annualized"] = 100 * 1.1 ** growth['Year']
growth["Continuous"] = 100 * np.exp(.1 * growth['Year'])
growth = growth.set_index('Year')
growth.plot(kind='line')
plt.xlabel("T")
plt.ylabel("Investment Value")
plt.title("Annual vs. Continuous Returns")
plt.show()
In a binomial tree, we want to think of a node having two possible paths, one path upwards and one path downwards. What this means is that if a stock has a price of $100, we then are interested in one path where the next time period the price is greater than $100, and another where it is less than $100. Let’s say that we represent the factor of growth as either e raised to 10%, or the inverse (one divided by this number).
#We can think of a factor that is either multiplied as x or 1/x to a value
up = np.exp(.1)
down = 1/up
print(up)
print(down)
If you multiply the growth factors by the starting price (in this case $100), we get a hypothethical up and down price.
#Print the values
print(100 * up)
print(100 * down)
Let’s begin to formalize this. In the first period (meaning that the start is period 0),, our growth rate has two possible paths. We can use a list to represent this idea.
#In the first period, you can either go up or down
print([up, down])
In the next period, we now have two possible paths for each of the prior paths. We could go up-up, up-down, down-up, or down-down for 4 total paths. Let’s represent all four possible paths.
#Then in the second period you can go up or down again meaning 4 combinations
#Notice the middle two are the same, the tree by design leads to t+1 combinations
#instead of 2^t because of this behavior
print([up*up, up*down, down*up, down*down])
You may notice that the inner values up-down and down-up are the same values. This is the magic of the binomial tree. If we allowed for paths to double every single time we would get explosive growth, instead paths can combine back with one and other. It does not matter the order of the up-down movements, all that matters is the total number of either up or down movements.
The following is the combinations of all possible numbers of up and down movements given t number of time periods. You’ll notice that it gives back t+1 possible ending values for the growth in all cases.
#We can represent each unique choice as all combinations of up and down where order does not matter
#This is the same kind of thing that a binomial distribution finds
#Let's see what the options are
up = np.exp(.1)
down = 1/up
t = 1
print([(up ** k) * (down ** (t-k)) for k in range(t+1)])
print()
t = 2
print([(up ** k) * (down ** (t-k)) for k in range(t+1)])
print()
t = 3
print([(up ** k) * (down ** (t-k)) for k in range(t+1)])
print()
If you aren’t familiar with string formatting, the following piece of code: “{:.2f}”.format(x) says to format a string with x in place of the brackets but as a two decimal floating point number. This will be helpful for when we build our trees so that we do not have labels that are too long.
#Remember how to format string representations of numbers
#The following will display a float with 2 decimals
#Also let's add in a starting stock price S
S = 100
up = np.exp(.1)
down = 1/up
for t in range(4):
nodes = [S * (up ** k) * (down ** (t-k)) for k in range(t+1)]
nodes = ["{:.2f}".format(x) for x in nodes]
print(nodes)
It is great to have the formatted numbers, but we also want the time period to be part of the label as well.
#Let's add in the time period to the string
S = 100
up = np.exp(.1)
down = 1/up
for t in range(4):
nodes = [S * (up ** k) * (down ** (t-k)) for k in range(t+1)]
nodes = ["T={}-${:.2f}".format(t, x) for x in nodes]
print(nodes)
Challenge