예제 #1
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void test()
        public virtual void test()
        {
            assertEquals(DATA.Alpha, ALPHA, 0);
            assertEquals(DATA.Beta, BETA, 0);
            assertEquals(DATA.Nu, NU, 0);
            assertEquals(DATA.Rho, RHO, 0);
            assertEquals(DATA.getParameter(0), ALPHA, 0);
            assertEquals(DATA.getParameter(1), BETA, 0);
            assertEquals(DATA.getParameter(2), RHO, 0);
            assertEquals(DATA.getParameter(3), NU, 0);
            assertEquals(DATA.NumberOfParameters, 4);
            SabrFormulaData other = SabrFormulaData.of(new double[] { ALPHA, BETA, RHO, NU });

            assertEquals(other, DATA);
            assertEquals(other.GetHashCode(), DATA.GetHashCode());

            other = other.with(0, ALPHA - 0.01);
            assertFalse(other.Equals(DATA));
            other = SabrFormulaData.of(ALPHA, BETA * 0.5, RHO, NU);
            assertFalse(other.Equals(DATA));
            other = SabrFormulaData.of(ALPHA, BETA, RHO, NU * 0.5);
            assertFalse(other.Equals(DATA));
            other = SabrFormulaData.of(ALPHA, BETA, RHO * 0.5, NU);
            assertFalse(other.Equals(DATA));
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void testATMSmoothness()
        public virtual void testATMSmoothness()
        {
            double timeToExpiry = 1;
            double alpha        = 0.05;
            double beta         = 0.5;
            double nu           = 0.50;
            double rho          = -0.25;
            int    nbPoints     = 100;
            double forward      = 0.05;

            double[] sabrVolatilty = new double[2 * nbPoints + 1];
            double   range         = 5E-9;

            double[] strike = new double[2 * nbPoints + 1];
            for (int looppts = -nbPoints; looppts <= nbPoints; looppts++)
            {
                strike[looppts + nbPoints] = forward + ((double)looppts) / nbPoints * range;
                SabrFormulaData SabrData = SabrFormulaData.of(alpha, beta, rho, nu);
                sabrVolatilty[looppts + nbPoints] = FUNCTION.volatility(forward, strike[looppts + nbPoints], timeToExpiry, SabrData);
            }
            for (int looppts = -nbPoints; looppts < nbPoints; looppts++)
            {
                assertTrue(Math.Abs(sabrVolatilty[looppts + nbPoints + 1] - sabrVolatilty[looppts + nbPoints]) / (strike[looppts + nbPoints + 1] - strike[looppts + nbPoints]) < 20.0);
            }
        }
예제 #3
0
        //-------------------------------------------------------------------------
        public virtual void coverage()
        {
            coverImmutableBean(DATA);
            SabrFormulaData another = SabrFormulaData.of(1.2, 0.4, 0.0, 0.2);

            coverBeanEquals(DATA, another);
        }
        /// <summary>
        /// The limit for $rhp \to 1$ when $z \geq 1$ does not exists. Returning an illegal argument.
        /// </summary>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void test_rho_close_to_1_large()
        public virtual void test_rho_close_to_1_large()
        {
            double          rhoEps = 1.e-5;
            double          rhoIn  = 1.0 - 0.5 * rhoEps;
            SabrFormulaData dataIn = SabrFormulaData.of(ALPHA, BETA, rhoIn, NU);

            assertThrowsIllegalArg(() => FUNCTION.volatility(10 * F, STRIKE_ITM, T, dataIn));
            assertThrowsIllegalArg(() => FUNCTION.volatilityAdjoint(10 * F, STRIKE_ITM, T, dataIn));
        }
        /// <summary>
        /// Check that $\rho \simeq 1$ case is smoothly connected with a general case, i.e.,
        /// comparing the approximated computation and full computation around the cutoff, which is currently $\rho = 1.0 - 1.0e-5$
        /// </summary>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void test_rho_close_to_1()
        public virtual void test_rho_close_to_1()
        {
            double rhoEps = 1.e-5;
            // rhoIn is larger than the cutoff,
            // thus vol and sensitivities are computed by approximation formulas which are regular in the limit rho -> 1.
            double rhoIn = 1.0 - 0.5 * rhoEps;
            double rho1  = 1.0d;
            // rhoOut is smaller than the cutoff, thus vol and sensitivities are computed by full formula.
            double          rhoOut  = 1.0 - 1.5 * rhoEps;
            SabrFormulaData data1   = SabrFormulaData.of(ALPHA, BETA, rho1, NU);
            SabrFormulaData dataIn  = SabrFormulaData.of(ALPHA, BETA, rhoIn, NU);
            SabrFormulaData dataOut = SabrFormulaData.of(ALPHA, BETA, rhoOut, NU);

            /*
             * z<1 case, i.e., finite values in the rho->1 limit
             */
            double volatilityOut = FUNCTION.volatility(F, STRIKE_OTM, T, dataOut);

            double[] adjointOut     = toArray(FUNCTION.volatilityAdjoint(F, STRIKE_OTM, T, dataOut));
            double[] volatilityDOut = new double[6];
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] volatilityD2Out = new double[2][2];
            double[][] volatilityD2Out = RectangularArrays.ReturnRectangularDoubleArray(2, 2);
            double     volatility2Out  = FUNCTION.volatilityAdjoint2(F, STRIKE_OTM, T, dataOut, volatilityDOut, volatilityD2Out);

            double volatilityIn = FUNCTION.volatility(F, STRIKE_OTM, T, dataIn);

            double[] adjointIn     = toArray(FUNCTION.volatilityAdjoint(F, STRIKE_OTM, T, dataIn));
            double[] volatilityDIn = new double[6];
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] volatilityD2In = new double[2][2];
            double[][] volatilityD2In = RectangularArrays.ReturnRectangularDoubleArray(2, 2);
            double     volatility2In  = FUNCTION.volatilityAdjoint2(F, STRIKE_OTM, T, dataIn, volatilityDIn, volatilityD2In);

            double volatility1 = FUNCTION.volatility(F, STRIKE_OTM, T, data1);

            assertEquals(volatilityOut, volatility1, TOLERANCE_VOL_LIMIT);
            assertEquals(volatilityOut, volatilityIn, TOLERANCE_VOL_LIMIT);
            assertEquals(volatility2Out, volatility2In, TOLERANCE_VOL_LIMIT);
            for (int i = 0; i < adjointOut.Length; ++i)
            {
                double @ref = adjointOut[i];
                assertEquals(adjointOut[i], adjointIn[i], Math.Max(Math.Abs(@ref), 1.0) * 1.e-3);
            }
            for (int i = 0; i < volatilityDOut.Length; ++i)
            {
                double @ref = volatilityDOut[i];
                assertEquals(volatilityDOut[i], volatilityDIn[i], Math.Max(Math.Abs(@ref), 1.0) * 1.e-3);
            }
        }
        //TODO write a fuzzer that hits SABR with random parameters
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(enabled = false) public void testRandomParameters()
        public virtual void testRandomParameters()
        {
            double eps = 1e-5;
            double tol = 1e-3;

            for (int count = 0; count < 100; count++)
            {
                double          alpha = Math.Exp(NORMAL.nextRandom() * 0.2 - 2);
                double          beta  = GlobalRandom.NextDouble; //TODO Uniform numbers in distribution
                double          nu    = Math.Exp(NORMAL.nextRandom() * 0.3 - 1);
                double          rho   = 2 * GlobalRandom.NextDouble - 1;
                SabrFormulaData data  = SabrFormulaData.of(alpha, beta, rho, nu);
                testVolatilityAdjoint(F, CALL_ATM, data, eps, tol);
                testVolatilityAdjoint(F, CALL_ITM, data, eps, tol);
                testVolatilityAdjoint(F, CALL_OTM, data, eps, tol);
            }
        }
        /// <summary>
        /// Calculate the true SABR delta and gamma and compare with that found by finite difference
        /// </summary>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(enabled = false) public void testGreeks()
        public virtual void testGreeks()
        {
            double           eps             = 1e-3;
            double           f               = 1.2;
            double           k               = 1.4;
            double           t               = 5.0;
            double           alpha           = 0.3;
            double           beta            = 0.6;
            double           rho             = -0.4;
            double           nu              = 0.4;
            SabrFormulaData  sabrData        = SabrFormulaData.of(alpha, beta, rho, nu);
            ValueDerivatives adj             = FUNCTION.volatilityAdjoint(f, k, t, sabrData);
            double           bsDelta         = BlackFormulaRepository.delta(f, k, t, adj.Value, true);
            double           bsVega          = BlackFormulaRepository.vega(f, k, t, adj.Value);
            double           volForwardSense = adj.getDerivative(1);
            double           delta           = bsDelta + bsVega * volForwardSense;

            SabrFormulaData data      = SabrFormulaData.of(alpha, beta, rho, nu);
            double          volUp     = FUNCTION.volatility(f + eps, k, t, data);
            double          volDown   = FUNCTION.volatility(f - eps, k, t, data);
            double          priceUp   = BlackFormulaRepository.price(f + eps, k, t, volUp, true);
            double          price     = BlackFormulaRepository.price(f, k, t, adj.Value, true);
            double          priceDown = BlackFormulaRepository.price(f - eps, k, t, volDown, true);
            double          fdDelta   = (priceUp - priceDown) / 2 / eps;

            assertEquals(fdDelta, delta, 1e-6);

            double bsVanna = BlackFormulaRepository.vanna(f, k, t, adj.Value);
            double bsGamma = BlackFormulaRepository.gamma(f, k, t, adj.Value);

            double[] volD1 = new double[5];
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] volD2 = new double[2][2];
            double[][] volD2 = RectangularArrays.ReturnRectangularDoubleArray(2, 2);
            FUNCTION.volatilityAdjoint2(f, k, t, sabrData, volD1, volD2);
            double d2Sigmad2Fwd = volD2[0][0];
            double gamma        = bsGamma + 2 * bsVanna * adj.getDerivative(1) + bsVega * d2Sigmad2Fwd;
            double fdGamma      = (priceUp + priceDown - 2 * price) / eps / eps;

            double d2Sigmad2FwdFD = (volUp + volDown - 2 * adj.Value) / eps / eps;

            assertEquals(d2Sigmad2FwdFD, d2Sigmad2Fwd, 1e-4);

            assertEquals(fdGamma, gamma, 1e-2);
        }
예제 #8
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void testHighRho()
        public virtual void testHighRho()
        {
            assertThrowsIllegalArg(() => SabrFormulaData.of(ALPHA, BETA, RHO + 10, NU));
        }
예제 #9
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void testNegativeNu()
        public virtual void testNegativeNu()
        {
            assertThrowsIllegalArg(() => SabrFormulaData.of(ALPHA, BETA, RHO, -NU));
        }
예제 #10
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void testWrongParameterLength()
        public virtual void testWrongParameterLength()
        {
            assertThrowsIllegalArg(() => SabrFormulaData.of(new double[] { ALPHA, BETA, RHO, NU, 0.1 }));
        }