【发布时间】:2020-05-03 19:21:42
【问题描述】:
我正在尝试使用 javascript 计算隐含波动率,我有以下代码
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;
}
它适用于大多数行使价,但有时我会得到 Infinity 或 - Infinity 作为输出。
当我跑步时
var ceiv = 100.0*implicit_volatility(0, 624.65, 12352.35, 11750, 0.069, 0, 0.03287671232876712)
返回无穷大
但其他执行价格给出了正确的 IV,例如如果我运行
var ceiv = 100.0* implied_volatility(0, 1521.75,31590, 30100, 0.069, 0, 0.0136986301369863)
它给出了 19.08
这是参数
implied_volatility(callput, optionprice,spotprice, strikeprice, riskfreeinterest/100, dividend, daytoexpireinyear)
【问题讨论】:
-
好的,我对金融算法的理解不够深入,但是从代码的角度来看,代码的
if(actualCost > expectedCost)分支和/或blackScholes算法有问题。您的代码 always 进入actualCost > expectedCost情况,这是因为actualCost(blackScholes的结果 always 相同。唯一改变的变量(并且有任何相关性)是estimate,但是,它取决于low,而low永远不会改变自己。因此,实际上,这是使用相同的数字运行计算并产生相同的结果100次。 -
我不确定这应该如何工作,但我怀疑进入
blackSchole的其他值应该改变或者至少应该改变estimate,所以方式它的计算会有所不同。同样,不确定,但希望这能让您了解要查看的内容。 -
嘿伙计们,我更新了我的代码,除了有时,这个代码运行良好。请检查代码,谢谢。
-
哦,所以您在我们为您调试的同时使用问题区域逐步更新代码?这不是 Stack Overflow 应该如何工作的。请在发布之前花点时间调试您的代码。此外,“除了有时是完美的”是(1)不完美,(2)不是一个清晰的问题描述。
-
过去两周我都在尽我所能,但我无处可去。
标签: javascript algorithm quantitative-finance algorithmic-trading trading