<jupyter_start><jupyter_text>Black Scholes ModelThe Black Scholes model is considered to be one of the best ways of determining fair prices of options. It requires five variables: the strike price of an option, the current stock price, the time to expiration, the risk-free rate, and the volatility. Black and Scholes componets- C = call option price- N = CDF of the normal distribution- St= spot price of an asset- K = strike price- r = risk-free interest rate- t = time to maturity- σ = volatility of the asset Black and Scholes assumption:- It works on European options that can only be exercised at expiration.- No dividends paid out during the option’s life.- No transaction and commissions costs in buying the option.- The returns on the underlying are normally distributed.<jupyter_code>from math import log, sqrt, pi, exp
from scipy.stats import norm
from datetime import datetime, date
import numpy as np
import pandas as pd
from pandas import DataFrame

#Define d1 and d2 funcion of Black and Scholes 
def d1(S,K,T,r,sigma):
    return(log(S/K)+(r+sigma**2/2.)*T)/(sigma*sqrt(T))
def d2(S,K,T,r,sigma):
    return d1(S,K,T,r,sigma)-sigma*sqrt(T)

#calculating call option
def bs_call(S, K, T, r, sigma):
    return S*norm.cdf(d1(S,K,T,r,sigma))-K*exp(-r*T)*norm.cdf(d2(S,K,T,r,sigma))

#calculating put option
def bs_put(S,K,T,r,sigma):
    return K*exp(-r*T)-S+bs_call(S,K,T,r,sigma)<jupyter_output><empty_output><jupyter_text>Collecting the DataFor us to test the formula on a stock we need to get the historical data for that specific stock and the other inputs related to the stock. We will be using Yahoo Finance and the pandas library to get this data.<jupyter_code>from datetime import datetime, date
import numpy as np
import pandas as pd
import pandas_datareader.data as web

stock = 'SPY'
expiry = '12-18-2022'
strike_price = 370

today = datetime.now()
one_year_ago = today.replace(year=today.year-1)

df = web.DataReader(stock, 'yahoo', one_year_ago, today)

df = df.sort_values(by="Date")
df = df.dropna()
df = df.assign(close_day_before=df.Close.shift(1))
df['returns'] = ((df.Close - df.close_day_before)/df.close_day_before)

sigma = np.sqrt(252) * df['returns'].std()
uty = (web.DataReader(
    "^TNX", 'yahoo', today.replace(day=today.day-1), today)['Close'].iloc[-1])/100
lcp = df['Close'].iloc[-1]
t = (datetime.strptime(expiry, "%m-%d-%Y") - datetime.utcnow()).days / 365

print('The Option Price is: ', bs_call(lcp, strike_price, t, uty, sigma))


def call_implied_volatility(Price, S, K, T, r):
    sigma = 0.001
    while sigma < 1:
        Price_implied = S * \
            norm.cdf(d1(S, K, T, r, sigma))-K*exp(-r*T) * \
            norm.cdf(d2(S, K, T, r, sigma))
        if Price-(Price_implied) < 0.001:
            return sigma
        sigma += 0.001
    return "Not Found"

def put_implied_volatility(Price, S, K, T, r):
    sigma = 0.001
    while sigma < 1:
        Price_implied = K*exp(-r*T)-S+bs_call(S, K, T, r, sigma)
        if Price-(Price_implied) < 0.001:
            return sigma
        sigma += 0.001
    return "Not Found"

print("Implied Volatility: " +
      str(100 * call_implied_volatility(bs_call(lcp, strike_price, t, uty, sigma,), lcp, strike_price, t, uty,)) + " %")<jupyter_output><empty_output><jupyter_text>Implied volatilityThe implied volatility is key when measuring whether options prices are cheap or expensive. It allows traders to determine what they think the future volatility is likely to be. It is recommended to buy when the implied volatility is at its lowest as that generally means that their prices are discounted. This is because options that have high levels of implied volatility will result in high-priced option premiums. On the opposite side, when implied volatility is low, this means that the market’s expectations and demand for the option is decreasing, therefore causing prices to decrease. Greeks - Delta: the sensitivity of an option’s price changes relative to the changes in the underlying asset’s price.- Gamma: the delta’s change relative to the changes in the price of the underlying asset.- Vega: the sensitivity of an option price relative to the volatility of the underlying asset.- Theta: the sensitivity of the option price relative to the option’s time to maturity.- Rho: the sensitivity of the option price relative to interest rates. Implied Volatility and the GreeksImplied Volatility is defined as the expected future volatility of the stock over the life of the option. It is directly influenced by the supply and demand of the underlying option and the market’s expectation of the stock price’s direction. It could be calculated by solving the Black Scholes equation backwards for the volatility starting with the option trading price.<jupyter_code>from math import log, sqrt, pi, exp
from scipy.stats import norm
from datetime import datetime, date
import numpy as np
import pandas as pd
import pandas_datareader.data as web

#calculating greeks for call options:
def call_delta(S,K,T,r,sigma):
    return norm.cdf(d1(S,K,T,r,sigma))
def call_gamma(S,K,T,r,sigma):
    return norm.pdf(d1(S,K,T,r,sigma))/(S*sigma*sqrt(T))
def call_vega(S,K,T,r,sigma):
    return 0.01*(S*norm.pdf(d1(S,K,T,r,sigma))*sqrt(T))
def call_theta(S,K,T,r,sigma):
    return 0.01*(-(S*norm.pdf(d1(S,K,T,r,sigma))*sigma)/(2*sqrt(T)) - r*K*exp(-r*T)*norm.cdf(d2(S,K,T,r,sigma)))
def call_rho(S,K,T,r,sigma):
    return 0.01*(K*T*exp(-r*T)*norm.cdf(d2(S,K,T,r,sigma)))

#creating greeks for put optios
def put_delta(S,K,T,r,sigma):
    return -norm.cdf(-d1(S,K,T,r,sigma))
def put_gamma(S,K,T,r,sigma):
    return norm.pdf(d1(S,K,T,r,sigma))/(S*sigma*sqrt(T))
def put_vega(S,K,T,r,sigma):
    return 0.01*(S*norm.pdf(d1(S,K,T,r,sigma))*sqrt(T))
def put_theta(S,K,T,r,sigma):
    return 0.01*(-(S*norm.pdf(d1(S,K,T,r,sigma))*sigma)/(2*sqrt(T)) + r*K*exp(-r*T)*norm.cdf(-d2(S,K,T,r,sigma)))
def put_rho(S,K,T,r,sigma):
    return 0.01*(-K*T*exp(-r*T)*norm.cdf(-d2(S,K,T,r,sigma)))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12527105921601334, 'fraction_numerical': 0.016180150125104254, 'mean_word_length': 4.635338345864661, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '32640', 'license': 'MIT', 'n_tokens_mistral': 2166, 'n_tokens_neox': 2019, 'n_words': 675, 'path': '2022/Python-for-finance/Section 19/Black Scholes Model.ipynb', 'repo_name': 'millennialseb/EDU_python', 'size': '5995'}