예제 #1
0
        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)));
            }
        }