0% found this document useful (0 votes)
35 views9 pages

Assignment 2 Computational Part

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views9 pages

Assignment 2 Computational Part

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

9/10/24, 8:21 p.m.

FM 9587 Rodrigo Gonzalez Assignment 2

FM 9578 Assignment 2- week 3


Unit 1: Computational Finance - week 2

Rodrigo Ernesto Gonzalez Eslava


In [1]: ##Activate the next line in case you don't have yahooquery installed
#pip install yahooquery
import pandas as pd
import numpy as np
import seaborn as sns
import glob
import os
import [Link] as plt
import [Link] as px
from yahooquery import Ticker
import warnings
import statistics
import math
[Link]('ignore')

pd.set_option('display.max_columns', 500)
%matplotlib inline

data_path = [Link]()+'\\'
files = [Link](data_path)
data_path
#files

Out[1]: 'C:\\Users\\Usuario\\Documents\\2024\\Western\\Fall\\Mathematics of Financial Opti


ons\\Assignment 2\\'

First let's get the data from yahoo finance

In [10]: name='^GSPTSE'
tickers=[name]
folder= data_path

nosuccess=[]
for ticker in tickers:
print('Working on: ', ticker)
try:
dfprice=Ticker(ticker)
df=[Link](period='5y',interval='1d')
thefile=folder+ticker+'.csv'
df.to_csv(thefile)
print(ticker+' has been saved to: '+folder)
except FileNotFoundError:
[Link](ticker)

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 1/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

print('Found no price for: ' +ticker)


continue
tickers=[name]
folder= data_path

Working on: ^GSPTSE


^GSPTSE has been saved to: C:\Users\Usuario\Documents\2024\Western\Fall\Mathematics
of Financial Options\Assignment 2\

First view to the data

In [39]: #We're reading the data extracted from yahoo finance


raw_data = pd.read_csv(data_path + name +'.csv')
raw_data.head(100)

Out[39]: symbol date open high low close volume

2019-
0 ^GSPTSE 16347.299805 16409.099609 16308.700195 16379.900391 168389300 1
10-09

2019-
1 ^GSPTSE 16375.400391 16444.400391 16358.099609 16422.699219 186014600 1
10-10

2019-
2 ^GSPTSE 16487.199219 16516.699219 16413.400391 16415.199219 200746600 1
10-11

2019-
3 ^GSPTSE 16433.699219 16510.699219 16417.800781 16418.400391 212333000 1
10-15

2019-
4 ^GSPTSE 16435.099609 16445.599609 16408.699219 16427.199219 165968300 1
10-16

... ... ... ... ... ... ... ...

2020-
95 ^GSPTSE 17140.900391 17304.599609 17029.900391 17041.900391 303632000 1
02-26

2020-
96 ^GSPTSE 16803.400391 16816.199219 16456.800781 16717.400391 232685900 1
02-27

2020-
97 ^GSPTSE 16184.400391 16276.900391 15896.400391 16263.099609 590219300 1
02-28

2020-
98 ^GSPTSE 16325.000000 16566.699219 16166.299805 16553.300781 374721500 1
03-02

2020-
99 ^GSPTSE 16674.900391 16798.199219 16378.299805 16423.599609 393127900 1
03-03

100 rows × 8 columns

In [40]: raw_data.isnull().[Link]()

Out[40]: False

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 2/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

In [41]: [Link](raw_data).count()

Out[41]: symbol 1256


date 1256
open 1256
high 1256
low 1256
close 1256
volume 1256
adjclose 1256
dtype: int64

In [42]: raw_data.info()

<class '[Link]'>
RangeIndex: 1256 entries, 0 to 1255
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 symbol 1256 non-null object
1 date 1256 non-null object
2 open 1256 non-null float64
3 high 1256 non-null float64
4 low 1256 non-null float64
5 close 1256 non-null float64
6 volume 1256 non-null int64
7 adjclose 1256 non-null float64
dtypes: float64(5), int64(1), object(2)
memory usage: 78.6+ KB

As we can see there are no missing values on the original data

Next, we will extract the "adjclose" column

In [51]: data=[Link](raw_data[['date','adjclose']])
[Link]=['date', 'adjclose']
[Link](1255, inplace= True)
data

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 3/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

Out[51]: date adjclose

0 2019-10-09 16379.900391

1 2019-10-10 16422.699219

2 2019-10-11 16415.199219

3 2019-10-15 16418.400391

4 2019-10-16 16427.199219

... ... ...

1250 2024-10-02 24001.599609

1251 2024-10-03 23968.500000

1252 2024-10-04 24162.800781

1253 2024-10-07 24102.699219

1254 2024-10-08 24072.500000

1255 rows × 2 columns

In [53]: # Calculate the weekly 3-day Moving Average


data['3d avg'] = data['adjclose'].rolling(3).mean()
[Link](value=data['3d avg'][2], inplace=True)
data['weekly 3d avg'] = data['3d avg'].rolling(5).mean()
[Link](value=data['weekly 3d avg'][4], inplace=True)

data

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 4/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

Out[53]: date adjclose 3d avg weekly 3d avg

0 2019-10-09 16379.900391 16405.932943 16411.366276

1 2019-10-10 16422.699219 16405.932943 16411.366276

2 2019-10-11 16415.199219 16405.932943 16411.366276

3 2019-10-15 16418.400391 16418.766276 16411.366276

4 2019-10-16 16427.199219 16420.266276 16411.366276

... ... ... ... ...

1250 2024-10-02 24001.599609 24012.000000 23987.107031

1251 2024-10-03 23968.500000 24001.366536 23994.586979

1252 2024-10-04 24162.800781 24044.300130 24010.346875

1253 2024-10-07 24102.699219 24078.000000 24026.546745

1254 2024-10-08 24072.500000 24112.666667 24049.666667

1255 rows × 4 columns

Now let's make a series for the log returns

In [58]: data['log_ret'] = [Link](data['weekly 3d avg']/data['weekly 3d avg'].shift(1))


[Link](value=0, inplace=True)
data

Out[58]: date adjclose 3d avg weekly 3d avg log_ret

0 2019-10-09 16379.900391 16405.932943 16411.366276 0.000000

1 2019-10-10 16422.699219 16405.932943 16411.366276 0.000000

2 2019-10-11 16415.199219 16405.932943 16411.366276 0.000000

3 2019-10-15 16418.400391 16418.766276 16411.366276 0.000000

4 2019-10-16 16427.199219 16420.266276 16411.366276 0.000000

... ... ... ... ... ...

1250 2024-10-02 24001.599609 24012.000000 23987.107031 0.000787

1251 2024-10-03 23968.500000 24001.366536 23994.586979 0.000312

1252 2024-10-04 24162.800781 24044.300130 24010.346875 0.000657

1253 2024-10-07 24102.699219 24078.000000 24026.546745 0.000674

1254 2024-10-08 24072.500000 24112.666667 24049.666667 0.000962

1255 rows × 5 columns

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 5/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

Now let´s compute the mean and standar deviation

In [79]: print(f"The mean of the log returns is: {sum(data['log_ret'])/(len(data['log_ret'])

The mean of the log returns is: 0.00030474240515029357

In [68]: print("The standard deviation of the log returns is: " + str([Link](data[

The standard deviation of the log returns is: 0.004565571240670406

Now let´s find the annualized values for the mean and standard deviation (drift and volatility)

In [70]: print("The annualized mean of the log returns is: " + str((252/1254)*sum(data['log_

The annualized mean of the log returns is: 0.07679508609787399

In [74]: print("The annualized standard deviation of the log returns is: " + str(([Link]

The annualized standard deviation of the log returns is: 0.0724761965745751

Bonus
Ussing the code seen in the python labs

Writing the StockOption base class

In [81]: import math

"""
Stores common attributes of a stock option
"""
class StockOption(object):
def __init__(
self, S0, K, r=0.05, T=1, N=2, pu=0, pd=0,
div=0, sigma=0, is_put=False, is_am=False):
"""
Initialize the stock option base class.
Defaults to European call unless specified.

:param S0: initial stock price


:param K: strike price
:param r: risk-free interest rate
:param T: time to maturity
:param N: number of time steps
:param pu: probability at up state [Su-S0/S0] % increase rate
:param pd: probability at down state [Sd-S0/S0] % decrease rate
:param div: Dividend yield
:param is_put: True for a put option,
False for a call option
:param is_am: True for an American option,
False for a European option
"""
self.S0 = S0
self.K = K

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 6/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

self.r = r
self.T = T
self.N = max(1, N)
[Link] = [] # Declare the stock prices tree

""" Optional parameters used by derived classes """


[Link], [Link] = pu, pd
[Link] = div
[Link] = sigma
self.is_call = not is_put
self.is_european = not is_am

@property
def dt(self):
""" Single time step, in years """
return self.T/float(self.N)

@property
def df(self):
""" The discount factor """
return [Link](-([Link])*[Link])

A class for European options using a binomial tree

In [82]: import math


import numpy as np
from decimal import Decimal

"""
Price a European option by the binomial tree model
"""
class BinomialEuropeanOption(StockOption):

def setup_parameters(self):
# Required calculations for the model
self.M = self.N+1 # Number of terminal nodes of tree
self.u = 1+[Link] # Expected value in the up state
self.d = [Link] # Expected value in the down state
[Link] = ([Link](
([Link])*[Link])-self.d)/(self.u-self.d)
[Link] = [Link] # Probability up is qu and down dq

def init_stock_price_tree(self):
# Initialize terminal price nodes to zeros
[Link] = [Link](self.M)

# Calculate expected stock prices for each node


for i in range(self.M):
[Link][i] = self.S0 * \
(self.u**(self.N-i)) * (self.d**i)

def init_payoffs_tree(self):
"""
Returns the payoffs when the option
expires at terminal nodes

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 7/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

"""
if self.is_call:
return [Link](0, [Link]-self.K)
else:
return [Link](0, [Link])

def traverse_tree(self, payoffs):


"""
Starting from the time the option expires, traverse
backwards and calculate discounted payoffs at each node
"""
for i in range(self.N):
payoffs = (payoffs[:-1]*[Link] +
payoffs[1:]*[Link])*[Link]

return payoffs

def begin_tree_traversal(self):
payoffs = self.init_payoffs_tree()
return self.traverse_tree(payoffs)

def price(self):
""" Entry point of the pricing implementation """
self.setup_parameters()
self.init_stock_price_tree()
payoffs = self.begin_tree_traversal()

# Option value converges to first node


return payoffs[0]

Using the values for the problems in this assignment

In [87]: eu_option = BinomialEuropeanOption(


80, 80, r=0.05, T=4/12, N=1, pu=0.0625, pd=0.0625, is_put=True)
print('European put option price for the exercise 1 is:', eu_option.price())

European put option price for the exercise 1 is: 1.7975367874187467

In [90]: eu_option = BinomialEuropeanOption(


40, 40, r=0.079210509, T=3/12, N=1, pu=0.125, pd=0.125, is_put=True)
print('European put option price for the exercise 2 is:', eu_option.price())

European put option price for the exercise 2 is: 2.0588235304304368

In [93]: eu_option = BinomialEuropeanOption(


50, 51, r=0.05, T=6/12, N=2, pu=0.06, pd=0.05, is_put=False)
print('European call option price for the exercise 3 is:', eu_option.price())

European call option price for the exercise 3 is: 1.6350711385184167

In [95]: eu_option = BinomialEuropeanOption(


50, 51, r=0.05, T=6/12, N=2, pu=0.06, pd=0.05, is_put=True)
print('European put option price for the exercise 4 is:', eu_option.price())

European put option price for the exercise 4 is: 1.37587665196338

In [103… (78*[Link](0.3*[Link](1/6))-80)/80

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 8/9
9/10/24, 8:21 p.m. FM 9587 Rodrigo Gonzalez Assignment 2

Out[103… 0.10203302569827084

In [109… (80-78*[Link](-0.3*[Link](1/6)))/78*[Link](-0.3*[Link](1/6))

Out[109… 0.12466934483941076

In [112… eu_option = BinomialEuropeanOption(


78, 80, r=0.03, T=2/12, N=2, pu=0.10203302569827084, pd=00.12466934483941076, i
print('European call option price for the exercise 5 is:', eu_option.price())

European call option price for the exercise 5 is: 4.611917044425747

localhost:8985/doc/tree/Documents/2024/Western/Fall/Mathematics of Financial Options/Assignment 2/FM 9587 Rodrigo Gonzalez Assignment [Link] 9/9

You might also like