Last active
May 5, 2024 04:54
-
-
Save ycytai/dfa19662a2df5528d4660ef2fba2ee67 to your computer and use it in GitHub Desktop.
This file contains 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 characters
from enum import Enum | |
import numpy as np | |
import scipy.stats as st | |
class OptionType(str, Enum): | |
call = 'Call' | |
put = 'Put' | |
class Option: | |
def __init__( | |
self, option_type: OptionType, s:float, k:float, v:float, | |
t:float, r:float, q:float | None = None | |
) -> None: | |
""" | |
Parameters: | |
option_type: option type, use 'call' or 'put' | |
s: spot price | |
k: strike price | |
r: interest rate | |
v: volatility | |
t: maturity(year) | |
q: yield rate | |
""" | |
self.spot = s | |
self.strike = k | |
self.volatility = v | |
self.maturity = t | |
self.rate = r | |
self.yield_rate = q | |
self.option_type = option_type | |
@property | |
def delta(self) -> float: | |
if self.option_type == OptionType.call: | |
return st.norm.cdf(self.d1) | |
if self.option_type == OptionType.put: | |
return st.norm.cdf(self.d1) - 1 | |
@property | |
def gamma(self) -> float: | |
return st.norm.pdf(self.d1) / (self.spot * self.volatility * (self.maturity**0.5)) | |
@property | |
def theta(self): | |
if self.option_type == OptionType.call: | |
return - (self.spot * st.norm.pdf(self.d1) * self.volatility) / (2 * self.maturity**0.5) \ | |
- (self.rate * self.strike * np.exp(-self.rate * self.maturity) * st.norm.cdf(self.d2)) | |
if self.option_type == OptionType.put: | |
return - (self.spot * st.norm.pdf(self.d1) * self.volatility) / (2 * self.maturity**0.5) \ | |
+ (self.rate * self.strike * np.exp(-self.rate * self.maturity) * st.norm.cdf(-self.d2)) | |
@property | |
def vega(self) -> float: | |
return self.spot * self.maturity**0.5 * st.norm.pdf(self.d1) | |
@property | |
def rho(self) -> float: | |
if self.option_type == OptionType.call: | |
return self.strike * self.maturity * np.exp(-self.rate * self.maturity) * st.norm.cdf(self.d2) | |
if self.option_type == OptionType.put: | |
return -self.strike * self.maturity * np.exp(-self.rate * self.maturity) * st.norm.cdf(-self.d2) | |
@property | |
def d1(self) -> float: | |
var = self.rate - self.yield_rate if self.yield_rate else self.rate | |
return (np.log(self.spot / self.strike) + ((var + self.volatility**2 / 2) * self.maturity)) \ | |
/ (self.volatility * self.maturity**0.5) | |
@property | |
def d2(self) -> float: | |
return self.d1 - (self.volatility*self.maturity**0.5) | |
def change_spot_price_to(self, price:float): | |
self.spot = price | |
@property | |
def greeks(self) -> dict[str, float]: | |
return { | |
'delta': self.delta, | |
'gamma': self.gamma, | |
'theta': self.theta, | |
'vega': self.vega, | |
'rho': self.rho | |
} | |
@property | |
def summary(self) -> str: | |
return f'{self.strike} {self.option_type.value}' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment