简体   繁体   中英

Calculate Implied volatility in javascript

I am trying to calculate implied volatility using javascript , I have following code

function pdf_stdgauss(x) {
    return Math.exp(-x * x / 2.0) / Math.sqrt(2.0 * Math.PI);
}

function cdf_stdgauss(x) {
    var t = 1.0 / (1.0 + 0.2316419 * (x < 0 ? -x : x));
    var b1 = 0.319381530;
    var b2 = -0.356563782;
    var b3 = 1.781477937;
    var b4 = -1.821255978;
    var b5 = 1.330274429;
    var a = t * (b1 + t * (b2 + t * (b3 + t * (b4 + t * b5))));
    return (x < 0 ? a * pdf_stdgauss(x) : (1.0 - a * pdf_stdgauss(x)));
}



function ecp(s, x, rfi, dvd, sigma, t) {
    var sst = sigma * Math.sqrt(t);
    var d1 = (Math.log(s / x) + (rfi - dvd + sigma * sigma / 2.0) * t) / sst;
    var d2 = d1 - sst;
    var Nd1 = cdf_stdgauss(d1);
    var Nd2 = cdf_stdgauss(d2);
    var pd1 = pdf_stdgauss(d1);
    var pd2 = pdf_stdgauss(d2);
    var erfi = Math.exp(-rfi * t);
    var edvd = Math.exp(-dvd * t);
    var c = s * edvd * Nd1 - x * erfi * Nd2;
    var p = c + x * erfi - s * edvd;
    var cdelta = edvd * Nd1;
    var pdelta = cdelta - edvd;
    var gamma = edvd * pd1 / (s * sst);
    var ctheta = dvd * s * edvd * Nd1 - rfi * x * erfi * Nd2 - 0.5 * sigma * sigma * s * s * gamma;
    var ptheta = ctheta + rfi * x * erfi - dvd * s * edvd;
    var vega = s * edvd * pd1 * Math.sqrt(t);
    var crho = x * erfi * Nd2 * t;
    var prho = x * erfi * (Nd2 - 1.0) * t;
    var cdvd = -s * edvd * Nd1 * t;
    var pdvd = s * edvd * (1.0 - Nd1) * t;
    return [c, cdelta, gamma, ctheta, vega, crho, cdvd, p, pdelta, gamma, ptheta, vega, prho, pdvd];
}

function implied_volatility(i, p, s, x, rfi, dvd, t) {
    var cv = function(sigma) {
        var sst = sigma * Math.sqrt(t);
        var d1 = (Math.log(s / x) + (rfi - dvd + sigma * sigma / 2.0) * t) / sst;
        var d2 = d1 - sst;
        var Nd1 = cdf_stdgauss(d1);
        var Nd2 = cdf_stdgauss(d2);



        if (i == 7) {
            Nd1 = Nd1 - 1.0;
            Nd2 = Nd2 - 1.0;
        }
        return s * Math.exp(-dvd * t) * Nd1 - x * Math.exp(-rfi * t) * Nd2 - p;
    };
    var cvp = function(sigma) {
        var sst = sigma * Math.sqrt(t);
        var d1 = (Math.log(s / x) + (rfi - dvd + sigma * sigma / 2.0) * t) / sst;
        return s * Math.exp(-dvd * t) * pdf_stdgauss(d1) * Math.sqrt(t);
    };
    return newt_root(0.2, cv, cvp, 0.000001);
}

function newt_root(x, f, fp, tol) {
    var x0;
    for (x0 = x; Math.abs(f(x0)) > tol; x0 -= f(x0) / fp(x0));
    return x0;
}

var dayselect = 23;
var monthselect = 1;
var yearselect = 2020;


function calculate_time2expire() {
    var today = new Date();
    var eday = parseInt(dayselect);
    var emonth = parseInt(monthselect);
    var edate = new Date(yearselect, emonth - 1, eday);
    var days = Math.ceil((edate.getTime() - today.getTime()) / 86400000);
    return days / 365.0;
}

It is working most of the strike prices, but sometimes I get Infinity or - Infinity as output.

When I run

var ceiv = 100.0* implied_volatility(0, 624.65, 12352.35, 11750, 0.069, 0, 0.03287671232876712)

It is returning infinity

But others strike prices are giving correct IV , For example If i run

var ceiv = 100.0* implied_volatility(0, 1521.75,31590, 30100, 0.069, 0, 0.0136986301369863)

It gives 19.08

Here is parameter

implied_volatility(callput, optionprice,spotprice, strikeprice, riskfreeinterest/100, dividend, daytoexpireinyear)

Your result is basically 0.1 * 0.5^100, which is from calling estimate = (estimate - low) / 2 + low 100 times. Your initial estimation is 0.1 resulting in a very w in blackScholes and this will cause the probability returned from stdNormCDF having w as a part of the input to always be 1. So, the price will not change even during the iterations when estimation is becoming even smaller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM