コード例 #1
0
 /// <summary>
 /// Greeks against finite difference approximation.
 /// </summary>
 public virtual void greekfdTest()
 {
     foreach (SimpleConstantContinuousBarrier barrier in BARRIERS)
     {
         ValueDerivatives computed = PRICER.priceAdjoint(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier);
         double           spotUp   = PRICER.price(SPOT + EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier);
         double           spotDw   = PRICER.price(SPOT - EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier);
         double           rateUp   = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM + EPS_FD, VOLATILITY, barrier);
         double           rateDw   = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM - EPS_FD, VOLATILITY, barrier);
         double           costUp   = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY + EPS_FD, RATE_DOM, VOLATILITY, barrier);
         double           costDw   = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY - EPS_FD, RATE_DOM, VOLATILITY, barrier);
         double           volUp    = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY + EPS_FD, barrier);
         double           volDw    = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY - EPS_FD, barrier);
         double           timeUp   = PRICER.price(SPOT, EXPIRY_TIME + EPS_FD, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier);
         double           timeDw   = PRICER.price(SPOT, EXPIRY_TIME - EPS_FD, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier);
         ValueDerivatives spotUp1  = PRICER.priceAdjoint(SPOT + EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier);
         ValueDerivatives spotDw1  = PRICER.priceAdjoint(SPOT - EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier);
         assertEquals(computed.getDerivative(0), 0.5 * (spotUp - spotDw) / EPS_FD, EPS_FD);
         assertEquals(computed.getDerivative(1), 0.5 * (rateUp - rateDw) / EPS_FD, EPS_FD);
         assertEquals(computed.getDerivative(2), 0.5 * (costUp - costDw) / EPS_FD, EPS_FD);
         assertEquals(computed.getDerivative(3), 0.5 * (volUp - volDw) / EPS_FD, EPS_FD);
         assertEquals(computed.getDerivative(4), 0.5 * (timeUp - timeDw) / EPS_FD, EPS_FD);
         assertEquals(computed.getDerivative(5), 0.5 * (spotUp1.getDerivative(0) - spotDw1.getDerivative(0)) / EPS_FD, EPS_FD);
     }
 }
コード例 #2
0
        /// <summary>
        /// Regression to 2.x, including rebate.
        /// </summary>
        public virtual void adjointPriceRegression()
        {
            BlackOneTouchCashPriceFormulaRepository rebate = new BlackOneTouchCashPriceFormulaRepository();

            double[]   priceDIExp       = new double[] { 6.625939880275156, 8.17524397035564, 3.51889794875554, 16.046696834562567, 10.70082805329517, 4.016261046580751 };
            double[]   priceDOExp       = new double[] { 16.801234633074746, 1.2809481492685348, 11.695029389570358, 1.9796398042263066, 21.122005303422565, 1.2480461457697478 };
            double[]   priceUIExp       = new double[] { 21.738904060619003, 5.660922675994705, 13.534230659666587, 12.751249399664466, 30.003917380997216, 2.454685902906281 };
            double[]   priceUOExp       = new double[] { 1.8022701280119453, 3.909269118910516, 1.7936963539403596, 5.389086914405454, 1.9329156510015661, 2.9236209647252656 };
            double[][] derivativesDIExp = new double[][]
            {
                new double[] { -0.256723218835973, -0.21326378136855229, -23.23617273082793, 53.887600866294676, 58.707263782832555 },
                new double[] { -0.22502757956883834, 0.3356609584177749, -28.669348717959508, -89.71793740640288, 57.79705127007245 },
                new double[] { -0.13240455064001755, -0.10777900727966121, -12.34024486138928, 37.506678277403935, 41.63892946136302 },
                new double[] { -0.42819609658445323, 0.441145732506666, -56.273347803397485, -151.04122279937647, 78.46755307304 },
                new double[] { -0.38528948548712183, -0.33466444779640325, -37.52619152936393, 62.57455743118484, 68.36140924884158 },
                new double[] { -0.10797845731130963, 0.21426029198992397, -14.08442230033797, -47.32420873845068, 39.147069642753685 }
            };
            double[][] derivativesDOExp = new double[][]
            {
                new double[] { 0.925317598744783, -0.2806575880039709, -55.697543854725964, 194.462195344832, 3.192368381065041 },
                new double[] { -0.03864414399539151, 0.009587256919136517, -1.270237829323396, -5.21052475720073, 4.102580893825152 },
                new double[] { 0.6324628371075294, -0.22479677856150546, -37.79085149394349, 148.7848961295844, 31.79584488974962 },
                new double[] { -0.004011720421074989, 0.06544806636160204, -3.7204441809560977, -5.9454611683655045, -5.032778721927358 },
                new double[] { 1.1693201681318741, -0.29024484492310754, -70.84983552060324, 228.28109929421754, -24.681781274058867 },
                new double[] { -0.04025696351697804, 0.0, -1.1548554608892951, -5.098392910877228, 4.53255833202904 }
            };
            double[][] derivativesUIExp = new double[][]
            {
                new double[] { 0.6472001227436213, -0.49131423321491496, -76.23506081532145, 247.30828672024398, 60.930906232993976 },
                new double[] { 0.15101969748879138, 0.2734357730161942, -19.852002808967725, -65.3919684893132, 53.213862714176926 },
                new double[] { 0.4769152573039112, -0.33257578584116665, -47.46250751883076, 185.24241099218733, 72.3408333224538 },
                new double[] { 0.28724757364329634, 0.43217422038994247, -44.716710223480845, -110.92464376467034, 67.97645289437169 },
                new double[] { 0.7893004079366213, -0.6080809040345517, -105.21921711692173, 290.19622455207696, 44.461552265540746 },
                new double[] { 0.06323542648613031, 0.15666910219655739, -8.608213577315155, -34.903930997004814, 34.230011428672505 }
            };
            double[][] derivativesUOExp = new double[][]
            {
                new double[] { 0.03976906121488867, -0.0026071361576082536, -0.590128468837802, 1.9384002530437727, 0.40226173936432547 },
                new double[] { -0.3963166170033215, 0.07181244232071722, -7.979056436920486, -28.639602912129345, 8.119305258181384 },
                new double[] { 0.041517833213300284, 0.0, -0.5600615351073366, 1.946054176962064, 0.5274768371195269 },
                new double[] { -0.7010805865991248, 0.07441957847832553, -13.168554459478084, -45.16514944091054, 4.891857265201665 },
                new double[] { 0.013105078757830808, -0.016828388684959006, -1.0482826316507563, 1.5563229354864467, -1.3483884822973111 },
                new double[] { -0.19309604326471816, 0.05759118979336658, -4.522536882517435, -16.621779890162028, 8.88315235457093 }
            };

            EuropeanVanillaOption[] options = new EuropeanVanillaOption[] { EuropeanVanillaOption.of(STRIKE_MID, EXPIRY_TIME, PutCall.CALL), EuropeanVanillaOption.of(STRIKE_MID, EXPIRY_TIME, PutCall.PUT), EuropeanVanillaOption.of(STRIKE_HIGH, EXPIRY_TIME, PutCall.CALL), EuropeanVanillaOption.of(STRIKE_HIGH, EXPIRY_TIME, PutCall.PUT), EuropeanVanillaOption.of(STRIKE_LOW, EXPIRY_TIME, PutCall.CALL), EuropeanVanillaOption.of(STRIKE_LOW, EXPIRY_TIME, PutCall.PUT) };
            int n = options.Length;

            for (int j = 0; j < n; ++j)
            {
                // down-in
                double           priceDINew        = BARRIER_PRICER.price(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_DOWN_IN);
                ValueDerivatives priceDIAdjointNew = BARRIER_PRICER.priceAdjoint(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_DOWN_IN);
                double           priceDIRb         = rebate.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_DOWN_OUT);
                ValueDerivatives priceDIAdjointRb  = rebate.priceAdjoint(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_DOWN_OUT);
                assertRelative(priceDIExp[j], priceDINew + priceDIRb * REBATE);
                assertRelative(priceDIExp[j], priceDIAdjointNew.Value + priceDIAdjointRb.Value * REBATE);
                // down-out
                double           priceDONew        = BARRIER_PRICER.price(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_DOWN_OUT);
                ValueDerivatives priceDOAdjointNew = BARRIER_PRICER.priceAdjoint(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_DOWN_OUT);
                double           priceDORb         = rebate.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_DOWN_IN);
                ValueDerivatives priceDOAdjointRb  = rebate.priceAdjoint(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_DOWN_IN);
                assertRelative(priceDOExp[j], priceDONew + priceDORb * REBATE);
                assertRelative(priceDOExp[j], priceDOAdjointNew.Value + priceDOAdjointRb.Value * REBATE);
                // up-in
                double           priceUINew        = BARRIER_PRICER.price(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_UP_IN);
                ValueDerivatives priceUIAdjointNew = BARRIER_PRICER.priceAdjoint(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_UP_IN);
                double           priceUIRb         = rebate.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_UP_OUT);
                ValueDerivatives priceUIAdjointRb  = rebate.priceAdjoint(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_UP_OUT);
                assertRelative(priceUIExp[j], priceUINew + priceUIRb * REBATE);
                assertRelative(priceUIExp[j], priceUIAdjointNew.Value + priceUIAdjointRb.Value * REBATE);
                // up-out
                double           priceUONew        = BARRIER_PRICER.price(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_UP_OUT);
                ValueDerivatives priceUOAdjointNew = BARRIER_PRICER.priceAdjoint(SPOT, options[j].Strike, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, options[j].Call, BARRIER_UP_OUT);
                double           priceUORb         = rebate.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_UP_IN);
                ValueDerivatives priceUOAdjointRb  = rebate.priceAdjoint(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_UP_IN);
                assertRelative(priceUOExp[j], priceUONew + priceUORb * REBATE);
                assertRelative(priceUOExp[j], priceUOAdjointNew.Value + priceUOAdjointRb.Value * REBATE);
                // derivatives
                for (int i = 0; i < 5; ++i)
                {
                    int    k        = i == 0 ? i : i - 1;
                    double rebateDI = i == 1 ? 0d : priceDIAdjointRb.getDerivative(k);
                    double rebateDO = i == 1 ? 0d : priceDOAdjointRb.getDerivative(k);
                    double rebateUI = i == 1 ? 0d : priceUIAdjointRb.getDerivative(k);
                    double rebateUO = i == 1 ? 0d : priceUOAdjointRb.getDerivative(k);
                    assertRelative(derivativesDIExp[j][i], priceDIAdjointNew.getDerivative(i) + REBATE * rebateDI);
                    assertRelative(derivativesDOExp[j][i], priceDOAdjointNew.getDerivative(i) + REBATE * rebateDO);
                    assertRelative(derivativesUIExp[j][i], priceUIAdjointNew.getDerivative(i) + REBATE * rebateUI);
                    assertRelative(derivativesUOExp[j][i], priceUOAdjointNew.getDerivative(i) + REBATE * rebateUO);
                }
            }
        }