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.
  • vivek_agg
    vivek_agg edited August 2
    Hi @vaibhavsharma13
    These greeks values seems theoretical as it takes input of Strike price, spot price, IV, rate and dividend yield.
    Based on these values, we calculate theoretical options values too, but they are different then the market values of the options.
    How can I calculate greek values based on the actual options values.

    This site https://tradingblock.com/calculators/option-greeks-calculator calculates option greeks with input of actual option values too.

    Please help.

    Thanks
    Vivek
  • vaibhavsharma13
    @vivek_agg Calculation of Greeks doesn't require option value; only calculation of IV requires option value. First you need to calculate IV and then put that IV in the formula to calculate Greeks.
  • vivek_agg
    Thanks @vaibhavsharma13 .
    I am currently using IndiaVIX for IV.
    How can we calculate the IV for the option?
  • vaibhavsharma13
    I have written IV formula above in Python
  • vivek_agg
    Hi @vaibhavsharma13
    I tried calculating the IV for the option NIFTY2581424400CE today.
    The input is option_value = 170, S=24432, K = 24400, T = 7, type = 'call', r=7
    The result is 5.99999499338889
    On groww website, it was showing iv value of 10.65 for this option NIFTY2581424400CE
    This is significant difference.
    Pls suggest, what I am doing wrong.
    Regards
    Vivek
  • vivek_agg
    vivek_agg edited August 7
    On debugging, it is showing success. I tried with r=10 also, but same result.
  • vaibhavsharma13
    @vivek_agg time will be 7/365 instead of 7.
  • vivek_agg
    @vaibhavsharma13 , in function for greeks calculation, you are already dividing days by 365. Below code line is there in the function:
    S0,X,σ,r,q,t = float(S0),float(X),float(σ/100),float(r/100),float(q/100),float(t/td)
    Here, td is 365, the default input parameter.
    def black_scholes_dexter(kite, S0,X,t,σ="",r=10,q=0.0,td=365):
Sign In or Register to comment.