public static double BSImpVolBisec(string cpflg, double S, double x, double T, double r, double b, double cm, double epsilon) { double vLow, vHigh, vi; double cLow, cHigh; double counter; vLow = 0.005; vHigh = 4; cLow = BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vLow); cHigh = BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vHigh); counter = 0; vi = vLow + (cm - cLow) * (vHigh - vLow) / (cHigh - cLow); while (Math.Abs(cm - BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vi)) > epsilon) { counter = counter + 1; if (counter == 100) { return(double.NaN); } if (BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vi) < cm) { vLow = vi; } else { vHigh = vi; } cLow = BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vLow); cHigh = BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vHigh); vi = vLow + (cm - cLow) * (vHigh - vLow) / (cHigh - cLow); } return(vi); }
public static double BSImpVolNR(string cpflg, double S, double x, double T, double r, double b, double cm, double epsilon) { double vi, ci; double vegai; double minDiff; //Manaster and Koehler seed value (vi) vi = Math.Sqrt(Math.Abs(Math.Log(S / x) + r * T) * 2 / T); ci = BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vi); vegai = BlackScholesMethod.Vega(S, x, T, r, b, vi); minDiff = Math.Abs(cm - ci); while (Math.Abs(cm - ci) >= epsilon && Math.Abs(cm - ci) <= minDiff) { vi = vi - (ci - cm) / vegai; ci = BlackScholesMethod.BlackScholes(cpflg, S, x, T, r, b, vi); vegai = BlackScholesMethod.Vega(S, x, T, r, b, vi); minDiff = Math.Abs(cm - ci); } if (Math.Abs(cm - ci) < epsilon) { return(vi); } else { return(double.NaN); } }
public static double BSAmericanCallApprox2002(double S, double X, double T, double r, double b, double v) { double option_price = double.NaN; double t1 = 0.5 * (Math.Sqrt(5) - 1) * T; if (b >= r)//Never optimal to exercise before maturity { option_price = BlackScholesMethod.BlackScholes("c", S, X, T, r, b, v); } else { double beta = (0.5 - b / (v * v)) + Math.Sqrt(Math.Pow((b / (v * v) - 0.5), 2) + 2 * r / (v * v)); double binfinity = beta / (beta - 1) * X; double b0 = Math.Max(X, r / (r - b) * X); double ht1 = -(b * t1 + 2 * v * Math.Sqrt(t1)) * X * X / ((binfinity - b0) * b0); double ht2 = -(b * T + 2 * v * Math.Sqrt(T)) * X * X / ((binfinity - b0) * b0); double I1 = b0 + (binfinity - b0) * (1 - Math.Exp(ht1)); double I2 = b0 + (binfinity - b0) * (1 - Math.Exp(ht2)); double alfa1 = (I1 - X) * Math.Pow(I1, -beta); double alfa2 = (I2 - X) * Math.Pow(I2, -beta); if (S >= I2) { option_price = S - X; } else { option_price = alfa2 * Math.Pow(S, beta) - alfa2 * phi(S, t1, beta, I2, I2, r, b, v) + phi(S, t1, 1, I2, I2, r, b, v) - phi(S, t1, 1, I1, I2, r, b, v) - X * phi(S, t1, 0, I2, I2, r, b, v) + X * phi(S, t1, 0, I1, I2, r, b, v) + alfa1 * phi(S, t1, beta, I1, I2, r, b, v) - alfa1 * ksi(S, T, beta, I1, I2, I1, t1, r, b, v) + ksi(S, T, 1, I1, I2, I1, t1, r, b, v) - ksi(S, T, 1, X, I2, I1, t1, r, b, v) - X * ksi(S, T, 0, I1, I2, I1, t1, r, b, v) + X * ksi(S, T, 0, X, I2, I1, t1, r, b, v); } } return(option_price); }
public static double ForwardStart(string cpflg, double S0, double t, double T, double r, double b, double vol, double a) { double return_value = double.NaN; return_value = DoubleExponentialTransformation.Integrate((y) => { return(Normal.PDF(0, 1, y) * BlackScholesMethod.BlackScholes(cpflg, S0 * Math.Exp((b - 0.5 * vol * vol) * t + y * vol * Math.Sqrt(t)), Math.Max(S0 * Math.Exp((b - 0.5 * vol * vol) * t + y * vol * Math.Sqrt(t)) + a, 0), T - t, r, b, vol)); }, -200, 200, 1e-4); return(return_value); }
public static double DiscreteAsianHHM(string cpflg, double S, double SA, double X, double t1, double T, double n, double m, double r, double b, double v) { double d1, d2, h, EA, EA2, vA, OptionValue, SA1, X1, price; SA1 = SA; X1 = X; h = (T - t1) / (n - 1); if (b == 0) { EA = S; } else { EA = S / n * Exp(b * t1) * (1 - Exp(b * h * n)) / (1 - Exp(b * h)); } if (m > 0) { if (SA > n / m * X) { if (cpflg == "p") { price = 0; return(price); } else if (cpflg == "c") { SA = SA * m / n + EA * (n - m) / n; price = (SA - X) * Exp(-r * T); return(price); } SA = SA1; } } if (m == n - 1) { X = n * X - (n - 1) * SA; price = BlackScholesMethod.BlackScholes(cpflg, S, X, T, r, b, v) * 1 / n; X = X1; SA = SA1; return(price); } if (b == 0) { EA2 = S * S * Exp(v * v * t1) / (n * n) * ((1 - Exp(v * v * h * n)) / (1 - Exp(v * v * h)) + 2 / (1 - Exp(v * v * h)) * (n - (1 - Exp(v * v * h * n)))); } else { EA2 = S * S * Exp((2 * b + v * v) * t1) / (n * n) * ((1 - Exp((2 * b + v * v) * h * n)) / (1 - Exp((2 * b + v * v) * h)) + 2 / (1 - Exp((b + v * v) * h)) * ((1 - Exp(b * h * n)) / (1 - Exp(b * h)) - (1 - Exp((2 * b + v * v) * h * n)) / (1 - Exp((2 * b + v * v) * h)))); } vA = Sqr((Log(EA2) - 2 * Log(EA)) / T); OptionValue = 0; if (m > 0) { X = n / (n - m) * X - m / (n - m) * SA; } d1 = (Log(EA / X) + vA * vA / 2 * T) / (vA * Sqr(T)); d2 = d1 - vA * Sqr(T); if (cpflg == "c") { OptionValue = Exp(-r * T) * (EA * CND(d1) - X * CND(d2)); } else if (cpflg == "p") { OptionValue = Exp(-r * T) * (X * CND(-d2) - EA * CND(-d1)); } price = OptionValue * (n - m) / n; return(price); }
public static double SoftBarrierOption(string tpflag, double S, double X, double L, double U, double T, double r, double b, double vol) { int eta; double price = double.NaN; string OutInFlag; string CallPutFlag; OutInFlag = tpflag.Substring(1, 2); CallPutFlag = tpflag.Substring(0, 1); if (OutInFlag == "di" | OutInFlag == "ui") { if (CallPutFlag == "c") { eta = 1; } else { eta = -1; } double mu = (b + vol * vol / 2) / vol / vol; double lambda1 = Exp(-0.5 * vol * vol * T * (mu + 0.5) * (mu - 0.5)); double lambda2 = Exp(-0.5 * vol * vol * T * (mu - 0.5) * (mu - 1.5)); double d1 = Log(U * U / S / X) / vol / Sqr(T) + mu * vol * Sqr(T); double d2 = d1 - (mu + 0.5) * vol * Sqr(T); double d3 = Log(U * U / S / X) / vol / Sqr(T) + (mu - 1) * vol * Sqr(T); double d4 = d1 - (mu - 0.5) * vol * Sqr(T); double e1 = Log(L * L / S / X) / vol / Sqr(T) + mu * vol * Sqr(T); double e2 = e1 - (mu + 0.5) * vol * Sqr(T); double e3 = Log(L * L / S / X) / vol / Sqr(T) + (mu - 1) * vol * Sqr(T); double e4 = e3 - (mu - 0.5) * vol * Sqr(T); price = (eta * S * Exp((b - r) * T) * Math.Pow(S, -2 * mu) * Math.Pow(S * X, 0.5 + mu) / (2 * mu + 1) * (Math.Pow(U * U / S / X, mu + 0.5 ) * CND(eta * d1) - lambda1 * CND(eta * d2) - Math.Pow(L * L / S / X, mu + 0.5) * CND(eta * e1) + lambda1 * CND(eta * e2)) - eta * X * Exp(-r * T) * Math.Pow(S, -2 * mu + 2) * Math.Pow(S * X, -0.5 + mu) / (2 * mu - 1) * (Math.Pow(U * U / S / X, mu - 0.5 ) * CND(eta * d3) - lambda2 * CND(eta * d4) - Math.Pow(L * L / S / X, mu - 0.5) * CND(eta * e3) + lambda2 * CND(eta * e4))) / (U - L); return(price); } else if (OutInFlag == "do" | OutInFlag == "uo") { if (CallPutFlag == "c") { eta = 1; } else { eta = -1; } double mu = (b + vol * vol / 2) / vol / vol; double lambda1 = Exp(-0.5 * vol * vol * T * (mu + 0.5) * (mu - 0.5)); double lambda2 = Exp(-0.5 * vol * vol * T * (mu - 0.5) * (mu - 1.5)); double d1 = Log(U * U / S / X) / vol / Sqr(T) + mu * vol * Sqr(T); double d2 = d1 - (mu + 0.5) * vol * Sqr(T); double d3 = Log(U * U / S / X) / vol / Sqr(T) + (mu - 1) * vol * Sqr(T); double d4 = d1 - (mu - 0.5) * vol * Sqr(T); double e1 = Log(L * L / S / X) / vol / Sqr(T) + mu * vol * Sqr(T); double e2 = e1 - (mu + 0.5) * vol * Sqr(T); double e3 = Log(L * L / S / X) / vol / Sqr(T) + (mu - 1) * vol * Sqr(T); double e4 = e3 - (mu - 0.5) * vol * Sqr(T); price = BlackScholesMethod.BlackScholes(CallPutFlag, S, X, T, r, b, vol) - (eta * S * Exp((b - r) * T) * Math.Pow(S, -2 * mu) * Math.Pow(S * X, 0.5 + mu) / (2 * mu + 1) * (Math.Pow(U * U / S / X, mu + 0.5 ) * CND(eta * d1) - lambda1 * CND(eta * d2) - Math.Pow(L * L / S / X, mu + 0.5) * CND(eta * e1) + lambda1 * CND(eta * e2)) - eta * X * Exp(-r * T) * Math.Pow(S, -2 * mu + 2) * Math.Pow(S * X, -0.5 + mu) / (2 * mu - 1) * (Math.Pow(U * U / S / X, mu - 0.5 ) * CND(eta * d3) - lambda2 * CND(eta * d4) - Math.Pow(L * L / S / X, mu - 0.5) * CND(eta * e3) + lambda2 * CND(eta * e4))) / (U - L); return(price); } return(price); }
public static double DoubleBarrier(string TypeFlag, double S, double X, double l, double U, double T, double r, double b, double v, double delta1, double delta2) { double E, F, Sum1, Sum2, d1, d2, d3, d4, mu1, mu2, mu3, OutValue, price; OutValue = 0; price = double.NaN; F = U * Exp(delta1 * T); E = l * Exp(delta2 * T); Sum1 = 0; Sum2 = 0; if (TypeFlag == "co" | TypeFlag == "ci") { for (int n = -5; n < 5; n++) { d1 = (Log(S * Math.Pow(U, 2 * n) / (X * Math.Pow(l, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); d2 = (Log(S * Math.Pow(U, 2 * n) / (F * Math.Pow(l, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); d3 = (Log(Math.Pow(l, 2 * n + 2) / (X * S * Math.Pow(U, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); d4 = (Log(Math.Pow(l, 2 * n + 2) / (F * S * Math.Pow(U, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); mu1 = 2 * (b - delta2 - n * (delta1 - delta2)) / (v * v) + 1; mu2 = 2 * n * (delta1 - delta2) / (v * v); mu3 = 2 * (b - delta2 + n * (delta1 - delta2)) / (v * v) + 1; Sum1 = Sum1 + Math.Pow((Math.Pow(U, n) / Math.Pow(l, n)), mu1) * Math.Pow(l / S, mu2) * (CND(d1) - CND(d2)) - (Math.Pow(Math.Pow(l, n + 1) / (Math.Pow(U, n) * S), mu3)) * (CND(d3) - CND(d4)); Sum2 = Sum2 + Math.Pow((Math.Pow(U, n) / Math.Pow(l, n)), (mu1 - 2)) * Math.Pow(l / S, mu2) * (CND(d1 - v * Sqr(T)) - CND(d2 - v * Sqr(T))) - (Math.Pow(Math.Pow(l, n + 1) / (Math.Pow(U, n) * S), mu3 - 2) * (CND(d3 - v * Sqr(T)) - CND(d4 - v * Sqr(T)))); } OutValue = S * Exp((b - r) * T) * Sum1 - X * Exp(-r * T) * Sum2; } else if (TypeFlag == "po" | TypeFlag == "pi") { for (int n = -5; n < 5; n++) { d1 = (Log(S * Math.Pow(U, 2 * n) / (E * Math.Pow(l, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); d2 = (Log(S * Math.Pow(U, 2 * n) / (X * Math.Pow(l, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); d3 = (Log(Math.Pow(l, 2 * n + 2) / (E * S * Math.Pow(U, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); d4 = (Log(Math.Pow(l, 2 * n + 2) / (X * S * Math.Pow(U, 2 * n))) + (b + v * v / 2) * T) / (v * Sqr(T)); mu1 = 2 * (b - delta2 - n * (delta1 - delta2)) / (v * v) + 1; mu2 = 2 * n * (delta1 - delta2) / (v * v); mu3 = 2 * (b - delta2 + n * (delta1 - delta2)) / (v * v) + 1; Sum1 = Sum1 + Math.Pow((Math.Pow(U, n) / Math.Pow(l, n)), mu1) * Math.Pow(l / S, mu2) * (CND(d1) - CND(d2)) - (Math.Pow(Math.Pow(l, n + 1) / (Math.Pow(U, n) * S), mu3)) * (CND(d3) - CND(d4)); Sum2 = Sum2 + Math.Pow((Math.Pow(U, n) / Math.Pow(l, n)), (mu1 - 2)) * Math.Pow(l / S, mu2) * (CND(d1 - v * Sqr(T)) - CND(d2 - v * Sqr(T))) - (Math.Pow(Math.Pow(l, n + 1) / (Math.Pow(U, n) * S), mu3 - 2) * (CND(d3 - v * Sqr(T)) - CND(d4 - v * Sqr(T)))); } OutValue = X * Exp(-r * T) * Sum2 - S * Exp((b - r) * T) * Sum1; } if (TypeFlag == "co" | TypeFlag == "po") { price = OutValue; } else if (TypeFlag == "ci") { price = BlackScholesMethod.BlackScholes("c", S, X, T, r, b, v) - OutValue; } else if (TypeFlag == "pi") { price = BlackScholesMethod.BlackScholes("p", S, X, T, r, b, v) - OutValue; } return(price); }