Need code to calculate IV & option greeks

mailboxofrafiq
Hi @rakeshr @sujith or anybody, Can you please help me with code (any programming language) to calculate IV & option greeks? Need these values for my strategy.. I tried various implementation of Black 76 but it is NOT giving values similar to Sensibull :(
  • vaibhavsharma13
    vaibhavsharma13 edited September 2023
    The following code calculates IV which matches NSE website, i have checked it myself. It is written in python:
    import numpy as np
    from scipy.stats import norm
    from scipy.optimize import minimize_scalar
    import pandas as pd
    import pandas_datareader.data as web
    import datetime as dt
    N = norm.cdf


    N = norm.cdf

    # S : current asset price
    # K: strike price of the option
    # r: risk free rate
    # T : time until option expiration
    # σ: annualized volatility of the asset's returns

    def BS_CALL(S, K, T, r, sigma):
    d1 = (np.log(S/K) + (r + sigma**2/2)*T) / (sigma*np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)
    return S * N(d1) - K * np.exp(-r*T)* N(d2)

    def BS_PUT(S, K, T, r, sigma):
    d1 = (np.log(S/K) + (r + sigma**2/2)*T) / (sigma*np.sqrt(T))
    d2 = d1 - sigma* np.sqrt(T)
    return K*np.exp(-r*T)*N(-d2) - S*N(-d1)

    def implied_vol(opt_value, S, K, T, r, type_='call'):
    try:
    def call_obj(sigma):
    return abs(BS_CALL(S, K, T, r, sigma) - opt_value)

    def put_obj(sigma):
    return abs(BS_PUT(S, K, T, r, sigma) - opt_value)

    if type_ == 'call':
    res = minimize_scalar(call_obj, bounds=(0.01,6), method='bounded')
    return res.x
    elif type_ == 'put':
    res = minimize_scalar(put_obj, bounds=(0.01,6),
    method='bounded')
    return res.x
    else:
    raise ValueError("type_ must be 'put' or 'call'")
    except:
    return 0
  • vaibhavsharma13
    For greeks:
    import math
    from scipy.stats import norm

    # S0 = underlying price
    # X = strike price
    # σ = volatility
    # r = continuously compounded risk-free interest rate
    # q = continuously compounded dividend yield
    # t = time to expiration
    # For,
    # σ = Volatility = India VIX has been taken.
    # r = 10% (As per NSE Website, it is fixed.)
    # q = 0.00% (Assumed No Dividend)



    def black_scholes_dexter(S0,X,t,σ="",r=10,q=0.0,td=365):

    # if(σ==""):σ =indiavix()

    S0,X,σ,r,q,t = float(S0),float(X),float(σ/100),float(r/100),float(q/100),float(t/td)
    #https://unofficed.com/black-scholes-model-options-calculator-google-sheet/

    d1 = (math.log(S0/X)+(r-q+0.5*σ**2)*t)/(σ*math.sqrt(t))
    #stackoverflow.com/questions/34258537/python-typeerror-unsupported-operand-types-for-float-and-int

    #stackoverflow.com/questions/809362/how-to-calculate-cumulative-normal-distribution
    Nd1 = (math.exp((-d1**2)/2))/math.sqrt(2*math.pi)
    d2 = d1-σ*math.sqrt(t)
    Nd2 = norm.cdf(d2)
    call_theta =(-((S0*σ*math.exp(-q*t))/(2*math.sqrt(t))*(1/(math.sqrt(2*math.pi)))*math.exp(-(d1*d1)/2))-(r*X*math.exp(-r*t)*norm.cdf(d2))+(q*math.exp(-q*t)*S0*norm.cdf(d1)))/td
    put_theta =(-((S0*σ*math.exp(-q*t))/(2*math.sqrt(t))*(1/(math.sqrt(2*math.pi)))*math.exp(-(d1*d1)/2))+(r*X*math.exp(-r*t)*norm.cdf(-d2))-(q*math.exp(-q*t)*S0*norm.cdf(-d1)))/td
    call_premium =math.exp(-q*t)*S0*norm.cdf(d1)-X*math.exp(-r*t)*norm.cdf(d1-σ*math.sqrt(t))
    put_premium =X*math.exp(-r*t)*norm.cdf(-d2)-math.exp(-q*t)*S0*norm.cdf(-d1)
    call_delta =math.exp(-q*t)*norm.cdf(d1)
    put_delta =math.exp(-q*t)*(norm.cdf(d1)-1)
    gamma =(math.exp(-r*t)/(S0*σ*math.sqrt(t)))*(1/(math.sqrt(2*math.pi)))*math.exp(-(d1*d1)/2)
    vega = ((1/100)*S0*math.exp(-r*t)*math.sqrt(t))*(1/(math.sqrt(2*math.pi))*math.exp(-(d1*d1)/2))
    call_rho =(1/100)*X*t*math.exp(-r*t)*norm.cdf(d2)
    put_rho =(-1/100)*X*t*math.exp(-r*t)*norm.cdf(-d2)

    return call_theta,put_theta,call_premium,put_premium,call_delta,put_delta,gamma,vega,call_rho,put_rho
  • mailboxofrafiq
    Hi @vaibhavsharma13 I gave following input for your IV calculator..
    opt_value = 64.5
    S = 19993.2
    K = 20000
    r = 0.1 #10%/100
    T = 0.008 #3days/365
    sigma = 0.11 #vix/100
    type_ ='call'

    I got output as 0.0838308913230777. But in NSE website iV given as 10.57.. Can you pls help whether my input is wrong?
  • vaibhavsharma13
    vaibhavsharma13 edited September 2023
    @mailboxofrafiq Multiply your output by 100. Your inputs are looking good except use 3/365 for T and use r=0.08 . Also check during live market. Use Time in decimal, for more accuracy, for example if 2 and half days left for market to expires then use 2.5 in place of 3. So T will be 2.5/365.
  • vaibhavsharma13
    @mailboxofrafiq sigma is not required for calculating IV.
Sign In or Register to comment.