Last active
July 20, 2021 17:12
-
-
Save gnm3000/2bbbe4ef63a4f7fda7ab7b15777da0ac to your computer and use it in GitHub Desktop.
Revisions
-
gnm3000 revised this gist
Jul 20, 2021 . 1 changed file with 65 additions and 28 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,26 +1,28 @@ from math import sqrt, exp import pydotplus as pydot import numpy as np class Call(object): def __init__(self, S0, K, rate, sigma, n_periods, tyears): self.S0 = S0 # Today's stock price self.K = K # Strike Price self.rate = rate self.sigma = sigma self.tyears = tyears self.n_periods = n_periods self.up_factor = exp(self.sigma * sqrt(self.tyears / self.n_periods)) self.down_factor = 1 / self.up_factor self.tree = self.option_tree() self.option_price = self.tree["option_tree"][0][0] def option_tree(self): p = (np.exp(self.rate * self.tyears / self.n_periods) - self.down_factor) / (self.up_factor - self.down_factor) # Option Payoff contingent_payoff = lambda st, k: max(st - k, 0) contingent_payoff = np.vectorize(contingent_payoff) # Creating the branches at different times of the tree. Each branch is the possible martingale price # of the stock at time t stock_price_tree = [] for i in range(1,self.n_periods+1): @@ -29,36 +31,71 @@ def option_tree(self): for j in range(i+1): up_factor_repeat = i-j down_factor_repeat = j values = np.append(np.repeat(self.up_factor, up_factor_repeat), np.repeat(self.down_factor, down_factor_repeat)) stock_price = values.prod() * self.S0 period_prices.append(stock_price) stock_price_tree.append(period_prices) # Getting the payoff of the call at the end of the tree payoffs = contingent_payoff(stock_price_tree[self.n_periods-1], self.K).tolist() option_prices = [payoffs] # Contingent option price at period n-1 branch_n = payoffs # brach at n-1 for t in range(self.n_periods): branch_nm1 = [] for i in range(len(branch_n)-1): #cu: Contingent price at time n if price rises #cd: Contingent price at time n if price decreases cu, cd = np.array(branch_n)[[i, i+1]] price = np.exp(-self.rate * self.tyears / self.n_periods)*(p*cu + (1-p)*cd) branch_nm1.append(price) option_prices.append(branch_nm1) branch_n = branch_nm1 option_prices = option_prices[::-1] stock_price_tree.insert(0, [self.S0]) return {"stock_tree": stock_price_tree, "option_tree": option_prices} def graph_tree(self, file_name = ""): option_prices = self.tree["option_tree"] stock_price_tree = self.tree["stock_tree"] graph = pydot.Dot(graph_type='digraph', rankdir='LR') branch = 0 counter = 1 for i, prices in enumerate(option_prices[:-1]): next_prices = option_prices[i+1] for np, c_price in enumerate(prices): c_price = str(round(c_price,2)) nprice1 = str(round(next_prices[np], 2)) nprice2 = str(round(next_prices[np+1], 2)) increment = len(prices)-1 from_branch, to_branch1, to_branch2 = branch, counter + increment, counter + increment + 1 #print(from_branch,"->",to_branch1, to_branch2) up_price = round(stock_price_tree[i][np] * self.up_factor, 2) down_price = round(stock_price_tree[i][np] * self.down_factor, 2) edge = pydot.Edge(from_branch, to_branch1, label = str(up_price)); graph.add_edge(edge) edge = pydot.Edge(from_branch, to_branch2, label = str(down_price)); graph.add_edge(edge) node = pydot.Node(to_branch1, label = str(nprice1)); graph.add_node(node) node = pydot.Node(to_branch2, label = str(nprice2)); graph.add_node(node) counter += 1 branch += 1 c0 = round(self.option_price, 2) node = pydot.Node("0", label = str(c0)); graph.add_node(node) graph.write_png(file_name) a=Call(S0=100,K=90,rate=0.001,sigma=0.001,n_periods=1,tyears=0.01) print(a.option_tree()) a.graph_tree(file_name="filename.png") -
gnm3000 created this gist
Jul 20, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,64 @@ import numpy as np from numpy import exp,sqrt class Call(object): def __init__(self, S0, K, rate, sigma, n_periods, tyears): self.S0 = S0 self.K = K self.rate = rate self.sigma = sigma self.tyears = tyears self.n_periods = n_periods self.up_factor = exp(self.sigma * sqrt(self.tyears / self.n_periods)) self.down_factor = 1 / self.up_factor def option_tree(self): num = (np.exp(self.rate * self.tyears / self.n_periods) - self.down_factor) den = (self.up_factor - self.down_factor) p = num / den # Option Payoff contingent_payoff = lambda st, k: max(st - k, 0) contingent_payoff = np.vectorize(contingent_payoff) # Creating the branches at different times of the tree. # Each branch is the possible martingale price # of the stock at time t stock_price_tree = [] for i in range(1,self.n_periods+1): # Number of prices per period period_prices = [] for j in range(i+1): up_factor_repeat = i-j down_factor_repeat = j values = np.append(np.repeat(self.up_factor, up_factor_repeat), np.repeat(self.down_factor, down_factor_repeat)) stock_price = values.prod() * self.S0 period_prices.append(stock_price) stock_price_tree.append(period_prices) # Getting the payoff of the call at the end of the tree payoffs = contingent_payoff(stock_price_tree[self.n_periods-1], self.K).tolist() option_prices = [payoffs] # Contingent option price at period n-1 branch_n = payoffs # brach at n-1 for t in range(self.n_periods): branch_nm1 = [] for i in range(len(branch_n)-1): #cu: Contingent price at time n if price rises #cd: Contingent price at time n if price decreases cu, cd = np.array(branch_n)[[i, i+1]] price = np.exp(-self.rate * self.tyears / self.n_periods)*(p*cu + (1-p)*cd) branch_nm1.append(price) option_prices.append(branch_nm1) branch_n = branch_nm1 option_prices = option_prices[::-1] stock_price_tree.insert(0, [self.S0]) return {"stock_tree": stock_price_tree, "option_tree": option_prices} a=Call(S0=100,K=90,rate=0.001,sigma=0.001,n_periods=1,tyears=0.01) print(a.option_tree())