public virtual void recovery_test_shiftedBlack()
        {
            double        lambdaT    = 0.07;
            double        lambdaK    = 0.07;
            double        error      = 1.0e-5;
            ConstantCurve shiftCurve = ConstantCurve.of("Black shift", 0.02);
            DirectIborCapletFloorletVolatilityDefinition definition = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, lambdaT, lambdaK, INTERPOLATOR, shiftCurve);
            ImmutableList <Period> maturities  = createBlackMaturities();
            DoubleArray            strikes     = createBlackStrikes();
            DoubleMatrix           errorMatrix = DoubleMatrix.filled(maturities.size(), strikes.size(), error);
            RawOptionData          data        = RawOptionData.of(maturities, strikes, STRIKE, createFullBlackDataMatrix(), errorMatrix, BLACK_VOLATILITY);
            IborCapletFloorletVolatilityCalibrationResult          res     = CALIBRATOR.calibrate(definition, CALIBRATION_TIME, data, RATES_PROVIDER);
            ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities resVols = (ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities)res.Volatilities;

            for (int i = 0; i < NUM_BLACK_STRIKES; ++i)
            {
                Pair <IList <ResolvedIborCapFloorLeg>, IList <double> > capsAndVols = getCapsBlackVols(i);
                IList <ResolvedIborCapFloorLeg> caps = capsAndVols.First;
                IList <double> vols  = capsAndVols.Second;
                int            nCaps = caps.Count;
                for (int j = 0; j < nCaps; ++j)
                {
                    ConstantSurface volSurface = ConstantSurface.of(Surfaces.blackVolatilityByExpiryStrike("test", ACT_ACT_ISDA), vols[j]);
                    BlackIborCapletFloorletExpiryStrikeVolatilities constVol = BlackIborCapletFloorletExpiryStrikeVolatilities.of(USD_LIBOR_3M, CALIBRATION_TIME, volSurface);
                    double priceOrg   = LEG_PRICER_BLACK.presentValue(caps[j], RATES_PROVIDER, constVol).Amount;
                    double priceCalib = LEG_PRICER_BLACK.presentValue(caps[j], RATES_PROVIDER, resVols).Amount;
                    assertEquals(priceOrg, priceCalib, Math.Max(priceOrg, 1d) * TOL);
                }
            }
            assertTrue(res.ChiSquare > 0d);
            assertEquals(resVols.Index, USD_LIBOR_3M);
            assertEquals(resVols.Name, definition.Name);
            assertEquals(resVols.ValuationDateTime, CALIBRATION_TIME);
            assertEquals(resVols.ShiftCurve, definition.ShiftCurve.get());
        }
        public virtual void recovery_test_normal()
        {
            double lambdaT = 0.07;
            double lambdaK = 0.07;
            double error   = 1.0e-5;
            DirectIborCapletFloorletVolatilityDefinition definition = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, lambdaT, lambdaK, INTERPOLATOR);
            ImmutableList <Period> maturities  = createNormalMaturities();
            DoubleArray            strikes     = createNormalStrikes();
            DoubleMatrix           errorMatrix = DoubleMatrix.filled(maturities.size(), strikes.size(), error);
            RawOptionData          data        = RawOptionData.of(maturities, strikes, STRIKE, createFullNormalDataMatrix(), errorMatrix, NORMAL_VOLATILITY);
            IborCapletFloorletVolatilityCalibrationResult    res    = CALIBRATOR.calibrate(definition, CALIBRATION_TIME, data, RATES_PROVIDER);
            NormalIborCapletFloorletExpiryStrikeVolatilities resVol = (NormalIborCapletFloorletExpiryStrikeVolatilities)res.Volatilities;

            for (int i = 0; i < strikes.size(); ++i)
            {
                Pair <IList <ResolvedIborCapFloorLeg>, IList <double> > capsAndVols = getCapsNormalVols(i);
                IList <ResolvedIborCapFloorLeg> caps = capsAndVols.First;
                IList <double> vols  = capsAndVols.Second;
                int            nCaps = caps.Count;
                for (int j = 0; j < nCaps; ++j)
                {
                    ConstantSurface volSurface = ConstantSurface.of(Surfaces.normalVolatilityByExpiryStrike("test", ACT_ACT_ISDA), vols[j]);
                    NormalIborCapletFloorletExpiryStrikeVolatilities constVol = NormalIborCapletFloorletExpiryStrikeVolatilities.of(USD_LIBOR_3M, CALIBRATION_TIME, volSurface);
                    double priceOrg   = LEG_PRICER_NORMAL.presentValue(caps[j], RATES_PROVIDER, constVol).Amount;
                    double priceCalib = LEG_PRICER_NORMAL.presentValue(caps[j], RATES_PROVIDER, resVol).Amount;
                    assertEquals(priceOrg, priceCalib, Math.Max(priceOrg, 1d) * TOL);
                }
            }
        }
        public virtual void test_createMetadata()
        {
            DirectIborCapletFloorletVolatilityDefinition @base = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, LAMBDA_EXPIRY, LAMBDA_STRIKE, INTERPOLATOR);

            assertEquals(@base.createMetadata(SAMPLE_BLACK), Surfaces.blackVolatilityByExpiryStrike(NAME.Name, ACT_ACT_ISDA));
            assertEquals(@base.createMetadata(SAMPLE_NORMAL), Surfaces.normalVolatilityByExpiryStrike(NAME.Name, ACT_ACT_ISDA));
            assertThrowsIllegalArg(() => @base.createMetadata(RawOptionData.of(EXPIRIES, STRIKES, STRIKE, DATA, ValueType.PRICE)));
        }
        //-------------------------------------------------------------------------
        public virtual void coverage()
        {
            DirectIborCapletFloorletVolatilityDefinition test1 = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, LAMBDA_EXPIRY, LAMBDA_STRIKE, INTERPOLATOR, SHIFT_CURVE);

            coverImmutableBean(test1);
            DirectIborCapletFloorletVolatilityDefinition test2 = DirectIborCapletFloorletVolatilityDefinition.of(IborCapletFloorletVolatilitiesName.of("other"), GBP_LIBOR_3M, ACT_365F, 0.01, 0.02, GridSurfaceInterpolator.of(CurveInterpolators.LINEAR, CurveInterpolators.LINEAR));

            coverBeanEquals(test1, test2);
        }
        public virtual void test_of_shift()
        {
            DirectIborCapletFloorletVolatilityDefinition test = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, LAMBDA_EXPIRY, LAMBDA_STRIKE, INTERPOLATOR, SHIFT_CURVE);

            assertEquals(test.DayCount, ACT_ACT_ISDA);
            assertEquals(test.Index, USD_LIBOR_3M);
            assertEquals(test.Interpolator, INTERPOLATOR);
            assertEquals(test.LambdaExpiry, LAMBDA_EXPIRY);
            assertEquals(test.LambdaStrike, LAMBDA_STRIKE);
            assertEquals(test.Name, NAME);
            assertEquals(test.ShiftCurve.get(), SHIFT_CURVE);
        }
        public virtual void test_computePenaltyMatrix()
        {
            DirectIborCapletFloorletVolatilityDefinition @base = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, LAMBDA_EXPIRY, LAMBDA_STRIKE, INTERPOLATOR);
            DoubleArray strikes1  = DoubleArray.of(0.1);
            DoubleArray expiries1 = DoubleArray.of(1d, 2d, 5d);

            assertThrowsIllegalArg(() => @base.computePenaltyMatrix(strikes1, expiries1));
            DoubleArray strikes2  = DoubleArray.of(0.01, 0.05, 0.1);
            DoubleArray expiries2 = DoubleArray.of(2d);

            assertThrowsIllegalArg(() => @base.computePenaltyMatrix(strikes2, expiries2));
            DoubleArray  strikes3  = DoubleArray.of(0.05, 0.1, 0.15);
            DoubleArray  expiries3 = DoubleArray.of(1d, 2d, 5d);
            DoubleMatrix computed  = @base.computePenaltyMatrix(strikes3, expiries3);
            DoubleMatrix expected  = PenaltyMatrixGenerator.getPenaltyMatrix(new double[][] { expiries3.toArray(), strikes3.toArray() }, new int[] { 2, 2 }, new double[] { LAMBDA_EXPIRY, LAMBDA_STRIKE });

            assertEquals(computed, expected);
        }
        public virtual void recovery_test_normalFlat()
        {
            double lambdaT = 0.01;
            double lambdaK = 0.01;
            double error   = 1.0e-3;
            DirectIborCapletFloorletVolatilityDefinition definition = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, lambdaT, lambdaK, INTERPOLATOR);
            ImmutableList <Period> maturities  = createBlackMaturities();
            DoubleArray            strikes     = createBlackStrikes();
            DoubleMatrix           errorMatrix = DoubleMatrix.filled(maturities.size(), strikes.size(), error);
            RawOptionData          data        = RawOptionData.of(maturities, strikes, STRIKE, createFullFlatBlackDataMatrix(), errorMatrix, NORMAL_VOLATILITY);
            IborCapletFloorletVolatilityCalibrationResult    res    = CALIBRATOR.calibrate(definition, CALIBRATION_TIME, data, RATES_PROVIDER);
            NormalIborCapletFloorletExpiryStrikeVolatilities resVol = (NormalIborCapletFloorletExpiryStrikeVolatilities)res.Volatilities;
            Surface resSurface = resVol.Surface;
            int     nParams    = resSurface.ParameterCount;

            for (int i = 0; i < nParams; ++i)
            {
                assertEquals(resSurface.getParameter(i), 0.5, 1.0e-12);
            }
        }
        public virtual void test_serialization()
        {
            DirectIborCapletFloorletVolatilityDefinition test = DirectIborCapletFloorletVolatilityDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, LAMBDA_EXPIRY, LAMBDA_STRIKE, INTERPOLATOR, SHIFT_CURVE);

            assertSerialization(test);
        }