private double A(double eta) { bool differentStartOfLookback = lookbackPeriodStartTime() != residualTime(); double carry = riskFreeRate() - dividendYield(); double vol = volatility(); double x = 2.0 * carry / (vol * vol); double s = underlying() / strike(); double ls = Math.Log(s); double d1 = ls / stdDeviation() + 0.5 * (x + 1.0) * stdDeviation(); double d2 = d1 - stdDeviation(); double e1 = 0, e2 = 0; if (differentStartOfLookback) { e1 = (carry + vol * vol / 2) * (residualTime() - lookbackPeriodStartTime()) / (vol * Math.Sqrt(residualTime() - lookbackPeriodStartTime())); e2 = e1 - vol * Math.Sqrt(residualTime() - lookbackPeriodStartTime()); } double f1 = (ls + (carry + vol * vol / 2) * lookbackPeriodStartTime()) / (vol * Math.Sqrt(lookbackPeriodStartTime())); double f2 = f1 - vol * Math.Sqrt(lookbackPeriodStartTime()); double n1 = f_.value(eta * d1); double n2 = f_.value(eta * d2); BivariateCumulativeNormalDistributionWe04DP cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(-1), cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(0), cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(0); if (differentStartOfLookback) { cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(lookbackPeriodStartTime() / residualTime())); cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(Math.Sqrt(1 - lookbackPeriodStartTime() / residualTime())); cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(1 - lookbackPeriodStartTime() / residualTime())); } double n3 = cnbn1.value(eta * (d1 - x * stdDeviation()), eta * (-f1 + 2.0 * carry * Math.Sqrt(lookbackPeriodStartTime()) / vol)); double n4 = cnbn2.value(eta * e1, eta * d1); double n5 = cnbn3.value(-eta * e1, eta * d1); double n6 = cnbn1.value(eta * f2, -eta * d2); double n7 = f_.value(eta * f1); double n8 = f_.value(-eta * e2); double pow_s = Math.Pow(s, -x); double carryDiscount = Math.Exp(-carry * (residualTime() - lookbackPeriodStartTime())); return(eta * (underlying() * dividendDiscount() * n1 - strike() * riskFreeDiscount() * n2 + underlying() * riskFreeDiscount() / x * (-pow_s * n3 + dividendDiscount() / riskFreeDiscount() * n4) - underlying() * dividendDiscount() * n5 - strike() * riskFreeDiscount() * n6 + carryDiscount * dividendDiscount() * (1 - 0.5 * vol * vol / carry) * underlying() * n7 * n8)); }
private double A(double eta) { bool fullLookbackPeriod = lookbackPeriodEndTime() == residualTime(); double carry = riskFreeRate() - dividendYield(); double vol = volatility(); double x = 2.0 * carry / (vol * vol); double s = underlying() / minmax(); double ls = Math.Log(s); double d1 = ls / stdDeviation() + 0.5 * (x + 1.0) * stdDeviation(); double d2 = d1 - stdDeviation(); double e1 = 0, e2 = 0; if (!fullLookbackPeriod) { e1 = (carry + vol * vol / 2) * (residualTime() - lookbackPeriodEndTime()) / (vol * Math.Sqrt(residualTime() - lookbackPeriodEndTime())); e2 = e1 - vol * Math.Sqrt(residualTime() - lookbackPeriodEndTime()); } double f1 = (ls + (carry + vol * vol / 2) * lookbackPeriodEndTime()) / (vol * Math.Sqrt(lookbackPeriodEndTime())); double f2 = f1 - vol * Math.Sqrt(lookbackPeriodEndTime()); double l1 = Math.Log(lambda()) / vol; double g1 = l1 / Math.Sqrt(residualTime()); double g2 = 0; if (!fullLookbackPeriod) { g2 = l1 / Math.Sqrt(residualTime() - lookbackPeriodEndTime()); } double n1 = f_.value(eta * (d1 - g1)); double n2 = f_.value(eta * (d2 - g1)); BivariateCumulativeNormalDistributionWe04DP cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(1), cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(0), cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(-1); if (!fullLookbackPeriod) { cnbn1 = new BivariateCumulativeNormalDistributionWe04DP(Math.Sqrt(lookbackPeriodEndTime() / residualTime())); cnbn2 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(1 - lookbackPeriodEndTime() / residualTime())); cnbn3 = new BivariateCumulativeNormalDistributionWe04DP(-Math.Sqrt(lookbackPeriodEndTime() / residualTime())); } double n3 = cnbn1.value(eta * (-f1 + 2.0 * carry * Math.Sqrt(lookbackPeriodEndTime()) / vol), eta * (-d1 + x * stdDeviation() - g1)); double n4 = 0, n5 = 0, n6 = 0, n7 = 0; if (!fullLookbackPeriod) { n4 = cnbn2.value(-eta * (d1 + g1), eta * (e1 + g2)); n5 = cnbn2.value(-eta * (d1 - g1), eta * (e1 - g2)); n6 = cnbn3.value(eta * -f2, eta * (d2 - g1)); n7 = f_.value(eta * (e2 - g2)); } else { n4 = f_.value(-eta * (d1 + g1)); } double n8 = f_.value(-eta * f1); double pow_s = Math.Pow(s, -x); double pow_l = Math.Pow(lambda(), x); if (!fullLookbackPeriod) { return(eta * (underlying() * dividendDiscount() * n1 - lambda() * minmax() * riskFreeDiscount() * n2 + underlying() * riskFreeDiscount() * lambda() / x * (pow_s * n3 - dividendDiscount() / riskFreeDiscount() * pow_l * n4) + underlying() * dividendDiscount() * n5 + riskFreeDiscount() * lambda() * minmax() * n6 - Math.Exp(-carry * (residualTime() - lookbackPeriodEndTime())) * dividendDiscount() * (1 + 0.5 * vol * vol / carry) * lambda() * underlying() * n7 * n8)); } else { //Simpler calculation return(eta * (underlying() * dividendDiscount() * n1 - lambda() * minmax() * riskFreeDiscount() * n2 + underlying() * riskFreeDiscount() * lambda() / x * (pow_s * n3 - dividendDiscount() / riskFreeDiscount() * pow_l * n4))); } }