added 4 characters in body
Source Link
Nishant
  • 111
  • 2
public double BlackScholes(boolean callFlag, double S, double K, double T, double r, double v)
{
    //S is underlyng spot price
    //K is the strike price
    //T is time left to expiry
    // r is the risk free rate
    // v is volatility
    //callFlag is true for Call Option, false for put

    double d1, d2;

    d1=(log(S/K)+(r+v*v/2)*T)/(v* sqrt(T));
    d2=d1-v* sqrt(T);

    if (callFlag){
        return S*CND(d1)-K* exp(-r*T)*CND(d2);
    }else{
        return K* exp(-r*T)*CND(-d2)-S*CND(-d1);
    }
}

// The cumulative normal distribution function
public double CND(double X)
{
    double L, K, w ;
    double a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937, a4 = -1.821255978, a5 = 1.330274429;

    L = Math.abs(X);
    K = 1.0 / (1.0 + 0.2316419 * L);
    w = 1.0 - 1.0 / sqrt(2.0 * Math.PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3
            * Math.pow(K,3) + a4 * Math.pow(K,4) + a5 * Math.pow(K,5));

    if (X < 0.0)
    {
        w= 1.0 - w;
    }
    return w;
}


public double implVolNR(double S, double K, double r, double time, double option_price, boolean callFlag) {
    if (option_price < 0.99 * (S - K * exp(-time * r))) { // check for arbitrage violations. Option price is too low if this happens
        return 0.0;
    }
    final int MAX_ITERATIONS = 100;
    final double ACCURACY = 1.0e-2;
    double t_sqrt = Math.sqrt(time);
    double sigma = (option_price / S) / (0.398 * t_sqrt); // find initial value
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        double price = BlackScholes(callFlag, S, K, time, r, sigma); 



        //option_price call black scholes(S,K,r,sigma,time);
        double diff = option_price - price;
        if (Math.abs(diff) < ACCURACY) return sigma;
        double d1 = (log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
        double vega = S * t_sqrt * CND(d1);
        sigma = sigma + diff / vega;
    }
    return Double.NaN; // return error values
}
public double BlackScholes(boolean callFlag, double S, double K, double T, double r, double v)
{
    //S is underlyng spot price
    //K is the strike price
    //T is time left to expiry
    // r is the risk free rate
    // v is volatility
    //callFlag is true for Call Option, false for put

    double d1, d2;

    d1=(log(S/K)+(r+v*v/2)*T)/(v* sqrt(T));
    d2=d1-v* sqrt(T);

    if (callFlag){
        return S*CND(d1)-K* exp(-r*T)*CND(d2);
    }else{
        return K* exp(-r*T)*CND(-d2)-S*CND(-d1);
    }
}

// The cumulative normal distribution function
public double CND(double X)
{
    double L, K, w ;
    double a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937, a4 = -1.821255978, a5 = 1.330274429;

    L = Math.abs(X);
    K = 1.0 / (1.0 + 0.2316419 * L);
    w = 1.0 - 1.0 / sqrt(2.0 * Math.PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3
            * Math.pow(K,3) + a4 * Math.pow(K,4) + a5 * Math.pow(K,5));

    if (X < 0.0)
    {
        w= 1.0 - w;
    }
    return w;
}


public double implVolNR(double S, double K, double r, double time, double option_price, boolean callFlag) {
    if (option_price < 0.99 * (S - K * exp(-time * r))) { // check for arbitrage violations. Option price is too low if this happens
        return 0.0;
    }
    final int MAX_ITERATIONS = 100;
    final double ACCURACY = 1.0e-2;
    double t_sqrt = Math.sqrt(time);
    double sigma = (option_price / S) / (0.398 * t_sqrt); // find initial value
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        double price = BlackScholes(callFlag, S, K, time, r, sigma);
        //option_price call black scholes(S,K,r,sigma,time);
        double diff = option_price - price;
        if (Math.abs(diff) < ACCURACY) return sigma;
        double d1 = (log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
        double vega = S * t_sqrt * CND(d1);
        sigma = sigma + diff / vega;
    }
    return Double.NaN; // return error values
}
public double BlackScholes(boolean callFlag, double S, double K, double T, double r, double v)
{
    //S is underlyng spot price
    //K is the strike price
    //T is time left to expiry
    // r is the risk free rate
    // v is volatility
    //callFlag is true for Call Option, false for put

    double d1, d2;

    d1=(log(S/K)+(r+v*v/2)*T)/(v* sqrt(T));
    d2=d1-v* sqrt(T);

    if (callFlag){
        return S*CND(d1)-K* exp(-r*T)*CND(d2);
    }else{
        return K* exp(-r*T)*CND(-d2)-S*CND(-d1);
    }
}

// The cumulative normal distribution function
public double CND(double X)
{
    double L, K, w ;
    double a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937, a4 = -1.821255978, a5 = 1.330274429;

    L = Math.abs(X);
    K = 1.0 / (1.0 + 0.2316419 * L);
    w = 1.0 - 1.0 / sqrt(2.0 * Math.PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3
            * Math.pow(K,3) + a4 * Math.pow(K,4) + a5 * Math.pow(K,5));

    if (X < 0.0)
    {
        w= 1.0 - w;
    }
    return w;
}


public double implVolNR(double S, double K, double r, double time, double option_price, boolean callFlag) {
    if (option_price < 0.99 * (S - K * exp(-time * r))) { // check for arbitrage violations. Option price is too low if this happens
        return 0.0;
    }
    final int MAX_ITERATIONS = 100;
    final double ACCURACY = 1.0e-2;
    double t_sqrt = Math.sqrt(time);
    double sigma = (option_price / S) / (0.398 * t_sqrt); // find initial value
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        double price = BlackScholes(callFlag, S, K,time, r,sigma); 



        //option_price call black scholes(S,K,r,sigma,time);
        double diff = option_price - price;
        if (Math.abs(diff) < ACCURACY) return sigma;
        double d1 = (log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
        double vega = S * t_sqrt * CND(d1);
        sigma = sigma + diff / vega;
    }
    return Double.NaN; // return error values
}
added 1 character in body
Source Link
Nishant
  • 111
  • 2
public double BlackScholes(boolean callFlag, double S, double K, double T, double r, double v)
{
    //S is underlyng spot price
    //K is the strike price
    //T is time left to expiry
    // r is the risk free rate
    // v is volatility
    //callFlag is true for Call Option, false for put

    double d1, d2;

    d1=(log(S/K)+(r+v*v/2)*T)/(v* sqrt(T));
    d2=d1-v* sqrt(T);

    if (callFlag){
        return S*CND(d1)-K* exp(-r*T)*CND(d2);
    }else{
        return K* exp(-r*T)*CND(-d2)-S*CND(-d1);
    }
}

// The cumulative normal distribution function
public double CND(double X)
{
    double L, K, w ;
    double a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937, a4 = -1.821255978, a5 = 1.330274429;

    L = Math.abs(X);
    K = 1.0 / (1.0 + 0.2316419 * L);
    w = 1.0 - 1.0 / sqrt(2.0 * Math.PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3
            * Math.pow(K,3) + a4 * Math.pow(K,4) + a5 * Math.pow(K,5));

    if (X < 0.0)
    {
        w= 1.0 - w;
    }
    return w;
}


public double implVolNR(double S, double K, double r, double time, double option_price, boolean callFlag) {
    if (option_price < 0.99 * (S - K * exp(-time * r))) { // check for arbitrage violations. Option price is too low if this happens
        return 0.0;
    }
    final int MAX_ITERATIONS = 100;
    final double ACCURACY = 1.0e5;0e-2;
    double t_sqrt = Math.sqrt(time);
    double sigma = (option_price / S) / (0.398 * t_sqrt); // find initial value
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        double price = BlackScholes(callFlag, S, K, time, r, sigma);
        //option_price call black scholes(S,K,r,sigma,time);
        double diff = option_price - price;
        if (Math.abs(diff) < ACCURACY) return sigma;
        double d1 = (log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
        double vega = S * t_sqrt * CND(d1);
        sigma = sigma + diff / vega;
    }
    return Double.NaN; // return error values
}
public double BlackScholes(boolean callFlag, double S, double K, double T, double r, double v)
{
    //S is underlyng spot price
    //K is the strike price
    //T is time left to expiry
    // r is the risk free rate
    // v is volatility
    //callFlag is true for Call Option, false for put

    double d1, d2;

    d1=(log(S/K)+(r+v*v/2)*T)/(v* sqrt(T));
    d2=d1-v* sqrt(T);

    if (callFlag){
        return S*CND(d1)-K* exp(-r*T)*CND(d2);
    }else{
        return K* exp(-r*T)*CND(-d2)-S*CND(-d1);
    }
}

// The cumulative normal distribution function
public double CND(double X)
{
    double L, K, w ;
    double a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937, a4 = -1.821255978, a5 = 1.330274429;

    L = Math.abs(X);
    K = 1.0 / (1.0 + 0.2316419 * L);
    w = 1.0 - 1.0 / sqrt(2.0 * Math.PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3
            * Math.pow(K,3) + a4 * Math.pow(K,4) + a5 * Math.pow(K,5));

    if (X < 0.0)
    {
        w= 1.0 - w;
    }
    return w;
}


public double implVolNR(double S, double K, double r, double time, double option_price, boolean callFlag) {
    if (option_price < 0.99 * (S - K * exp(-time * r))) { // check for arbitrage violations. Option price is too low if this happens
        return 0.0;
    }
    final int MAX_ITERATIONS = 100;
    final double ACCURACY = 1.0e5;
    double t_sqrt = Math.sqrt(time);
    double sigma = (option_price / S) / (0.398 * t_sqrt); // find initial value
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        double price = BlackScholes(callFlag, S, K, time, r, sigma);
        //option_price call black scholes(S,K,r,sigma,time);
        double diff = option_price - price;
        if (Math.abs(diff) < ACCURACY) return sigma;
        double d1 = (log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
        double vega = S * t_sqrt * CND(d1);
        sigma = sigma + diff / vega;
    }
    return Double.NaN; // return error values
}
public double BlackScholes(boolean callFlag, double S, double K, double T, double r, double v)
{
    //S is underlyng spot price
    //K is the strike price
    //T is time left to expiry
    // r is the risk free rate
    // v is volatility
    //callFlag is true for Call Option, false for put

    double d1, d2;

    d1=(log(S/K)+(r+v*v/2)*T)/(v* sqrt(T));
    d2=d1-v* sqrt(T);

    if (callFlag){
        return S*CND(d1)-K* exp(-r*T)*CND(d2);
    }else{
        return K* exp(-r*T)*CND(-d2)-S*CND(-d1);
    }
}

// The cumulative normal distribution function
public double CND(double X)
{
    double L, K, w ;
    double a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937, a4 = -1.821255978, a5 = 1.330274429;

    L = Math.abs(X);
    K = 1.0 / (1.0 + 0.2316419 * L);
    w = 1.0 - 1.0 / sqrt(2.0 * Math.PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3
            * Math.pow(K,3) + a4 * Math.pow(K,4) + a5 * Math.pow(K,5));

    if (X < 0.0)
    {
        w= 1.0 - w;
    }
    return w;
}


public double implVolNR(double S, double K, double r, double time, double option_price, boolean callFlag) {
    if (option_price < 0.99 * (S - K * exp(-time * r))) { // check for arbitrage violations. Option price is too low if this happens
        return 0.0;
    }
    final int MAX_ITERATIONS = 100;
    final double ACCURACY = 1.0e-2;
    double t_sqrt = Math.sqrt(time);
    double sigma = (option_price / S) / (0.398 * t_sqrt); // find initial value
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        double price = BlackScholes(callFlag, S, K, time, r, sigma);
        //option_price call black scholes(S,K,r,sigma,time);
        double diff = option_price - price;
        if (Math.abs(diff) < ACCURACY) return sigma;
        double d1 = (log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
        double vega = S * t_sqrt * CND(d1);
        sigma = sigma + diff / vega;
    }
    return Double.NaN; // return error values
}
Source Link
Nishant
  • 111
  • 2

For Java, combining @vjond answer (as the initial starting estimate for implied Volatility), with a basic Cumulative Density Function for Normal distribution (CDN), and the Black Scholes Model applied to Newton Raphson, below is a basic Implied Volatility calculation for Java :

For the NR code (C), plz refer http://finance.bi.no/~bernt/gcc_prog/recipes/recipes.pdf

For the Black Scholes price calculator (Java and other languages) and Cumulative Density function, please refer http://www.espenhaug.com/black_scholes.html


public double BlackScholes(boolean callFlag, double S, double K, double T, double r, double v)
{
    //S is underlyng spot price
    //K is the strike price
    //T is time left to expiry
    // r is the risk free rate
    // v is volatility
    //callFlag is true for Call Option, false for put

    double d1, d2;

    d1=(log(S/K)+(r+v*v/2)*T)/(v* sqrt(T));
    d2=d1-v* sqrt(T);

    if (callFlag){
        return S*CND(d1)-K* exp(-r*T)*CND(d2);
    }else{
        return K* exp(-r*T)*CND(-d2)-S*CND(-d1);
    }
}

// The cumulative normal distribution function
public double CND(double X)
{
    double L, K, w ;
    double a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937, a4 = -1.821255978, a5 = 1.330274429;

    L = Math.abs(X);
    K = 1.0 / (1.0 + 0.2316419 * L);
    w = 1.0 - 1.0 / sqrt(2.0 * Math.PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3
            * Math.pow(K,3) + a4 * Math.pow(K,4) + a5 * Math.pow(K,5));

    if (X < 0.0)
    {
        w= 1.0 - w;
    }
    return w;
}


public double implVolNR(double S, double K, double r, double time, double option_price, boolean callFlag) {
    if (option_price < 0.99 * (S - K * exp(-time * r))) { // check for arbitrage violations. Option price is too low if this happens
        return 0.0;
    }
    final int MAX_ITERATIONS = 100;
    final double ACCURACY = 1.0e5;
    double t_sqrt = Math.sqrt(time);
    double sigma = (option_price / S) / (0.398 * t_sqrt); // find initial value
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        double price = BlackScholes(callFlag, S, K, time, r, sigma);
        //option_price call black scholes(S,K,r,sigma,time);
        double diff = option_price - price;
        if (Math.abs(diff) < ACCURACY) return sigma;
        double d1 = (log(S / K) + r * time) / (sigma * t_sqrt) + 0.5 * sigma * t_sqrt;
        double vega = S * t_sqrt * CND(d1);
        sigma = sigma + diff / vega;
    }
    return Double.NaN; // return error values
}