Spaces:
Build error
Build error
| # Imports | |
| import numpy as np | |
| from scipy.stats import norm | |
| from .Base import OptionPricingModel | |
| class BinomialTreeModel(OptionPricingModel): | |
| """ | |
| Class implementing calculation for European option price using BOPM (Binomial Option Pricing Model). | |
| It caclulates option prices in discrete time (lattice based), in specified number of time points between date of valuation and exercise date. | |
| This pricing model has three steps: | |
| - Price tree generation | |
| - Calculation of option value at each final node | |
| - Sequential calculation of the option value at each preceding node | |
| """ | |
| def __init__(self, underlying_spot_price, strike_price, days_to_maturity, risk_free_rate, sigma, number_of_time_steps): | |
| """ | |
| Initializes variables used in Black-Scholes formula . | |
| underlying_spot_price: current stock or other underlying spot price | |
| strike_price: strike price for option cotract | |
| days_to_maturity: option contract maturity/exercise date | |
| risk_free_rate: returns on risk-free assets (assumed to be constant until expiry date) | |
| sigma: volatility of the underlying asset (standard deviation of asset's log returns) | |
| number_of_time_steps: number of time periods between the valuation date and exercise date | |
| """ | |
| self.S = underlying_spot_price | |
| self.K = strike_price | |
| self.T = days_to_maturity / 365 | |
| self.r = risk_free_rate | |
| self.sigma = sigma | |
| self.number_of_time_steps = number_of_time_steps | |
| def _calculate_call_option_price(self): | |
| """Calculates price for call option according to the Binomial formula.""" | |
| # Delta t, up and down factors | |
| dT = self.T / self.number_of_time_steps | |
| u = np.exp(self.sigma * np.sqrt(dT)) | |
| d = 1.0 / u | |
| # Price vector initialization | |
| V = np.zeros(self.number_of_time_steps + 1) | |
| # Underlying asset prices at different time points | |
| S_T = np.array( [(self.S * u**j * d**(self.number_of_time_steps - j)) for j in range(self.number_of_time_steps + 1)]) | |
| a = np.exp(self.r * dT) # risk free compounded return | |
| p = (a - d) / (u - d) # risk neutral up probability | |
| q = 1.0 - p # risk neutral down probability | |
| V[:] = np.maximum(S_T - self.K, 0.0) | |
| # Overriding option price | |
| for i in range(self.number_of_time_steps - 1, -1, -1): | |
| V[:-1] = np.exp(-self.r * dT) * (p * V[1:] + q * V[:-1]) | |
| return V[0] | |
| def _calculate_put_option_price(self): | |
| """Calculates price for put option according to the Binomial formula.""" | |
| # Delta t, up and down factors | |
| dT = self.T / self.number_of_time_steps | |
| u = np.exp(self.sigma * np.sqrt(dT)) | |
| d = 1.0 / u | |
| # Price vector initialization | |
| V = np.zeros(self.number_of_time_steps + 1) | |
| # Underlying asset prices at different time points | |
| S_T = np.array( [(self.S * u**j * d**(self.number_of_time_steps - j)) for j in range(self.number_of_time_steps + 1)]) | |
| a = np.exp(self.r * dT) # risk free compounded return | |
| p = (a - d) / (u - d) # risk neutral up probability | |
| q = 1.0 - p # risk neutral down probability | |
| V[:] = np.maximum(self.K - S_T, 0.0) | |
| # Overriding option price | |
| for i in range(self.number_of_time_steps - 1, -1, -1): | |
| V[:-1] = np.exp(-self.r * dT) * (p * V[1:] + q * V[:-1]) | |
| return V[0] |