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_builder()
        {
            DirectIborCapletFloorletVolatilityDefinition test = DirectIborCapletFloorletVolatilityDefinition.builder().name(NAME).index(USD_LIBOR_3M).dayCount(ACT_ACT_ISDA).lambdaExpiry(LAMBDA_EXPIRY).lambdaStrike(LAMBDA_STRIKE).interpolator(INTERPOLATOR).shiftCurve(SHIFT_CURVE).build();

            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_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);
        }
Example #7
0
 public override bool Equals(object obj)
 {
     if (obj == this)
     {
         return(true);
     }
     if (obj != null && obj.GetType() == this.GetType())
     {
         DirectIborCapletFloorletVolatilityDefinition other = (DirectIborCapletFloorletVolatilityDefinition)obj;
         return(JodaBeanUtils.equal(name, other.name) && JodaBeanUtils.equal(index, other.index) && JodaBeanUtils.equal(dayCount, other.dayCount) && JodaBeanUtils.equal(lambdaExpiry, other.lambdaExpiry) && JodaBeanUtils.equal(lambdaStrike, other.lambdaStrike) && JodaBeanUtils.equal(interpolator, other.interpolator) && JodaBeanUtils.equal(shiftCurve, other.shiftCurve));
     }
     return(false);
 }
        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);
        }
Example #11
0
        //-------------------------------------------------------------------------
        public override IborCapletFloorletVolatilityCalibrationResult calibrate(IborCapletFloorletVolatilityDefinition definition, ZonedDateTime calibrationDateTime, RawOptionData capFloorData, RatesProvider ratesProvider)
        {
            ArgChecker.isTrue(ratesProvider.ValuationDate.Equals(calibrationDateTime.toLocalDate()), "valuationDate of ratesProvider should be coherent to calibrationDateTime");
            ArgChecker.isTrue(definition is DirectIborCapletFloorletVolatilityDefinition, "definition should be DirectIborCapletFloorletVolatilityDefinition");
            DirectIborCapletFloorletVolatilityDefinition directDefinition = (DirectIborCapletFloorletVolatilityDefinition)definition;
            // unpack cap data, create node caps
            IborIndex index           = directDefinition.Index;
            LocalDate calibrationDate = calibrationDateTime.toLocalDate();
            LocalDate baseDate        = index.EffectiveDateOffset.adjust(calibrationDate, ReferenceData);
            LocalDate startDate       = baseDate.plus(index.Tenor);

            System.Func <Surface, IborCapletFloorletVolatilities> volatilitiesFunction = this.volatilitiesFunction(directDefinition, calibrationDateTime, capFloorData);
            SurfaceMetadata metadata   = directDefinition.createMetadata(capFloorData);
            IList <Period>  expiries   = capFloorData.Expiries;
            DoubleArray     strikes    = capFloorData.Strikes;
            int             nExpiries  = expiries.Count;
            IList <double>  timeList   = new List <double>();
            IList <double>  strikeList = new List <double>();
            IList <double>  volList    = new List <double>();
            IList <ResolvedIborCapFloorLeg> capList = new List <ResolvedIborCapFloorLeg>();
            IList <double> priceList   = new List <double>();
            IList <double> errorList   = new List <double>();
            DoubleMatrix   errorMatrix = capFloorData.Error.orElse(DoubleMatrix.filled(nExpiries, strikes.size(), 1d));

            int[] startIndex = new int[nExpiries + 1];
            for (int i = 0; i < nExpiries; ++i)
            {
                LocalDate   endDate           = baseDate.plus(expiries[i]);
                DoubleArray volatilityForTime = capFloorData.Data.row(i);
                DoubleArray errorForTime      = errorMatrix.row(i);
                reduceRawData(directDefinition, ratesProvider, capFloorData.Strikes, volatilityForTime, errorForTime, startDate, endDate, metadata, volatilitiesFunction, timeList, strikeList, volList, capList, priceList, errorList);
                startIndex[i + 1] = volList.Count;
                ArgChecker.isTrue(startIndex[i + 1] > startIndex[i], "no valid option data for {}", expiries[i]);
            }
            // create caplet nodes and initial caplet vol surface
            ResolvedIborCapFloorLeg cap = capList[capList.Count - 1];
            int         nCaplets        = cap.CapletFloorletPeriods.size();
            DoubleArray capletExpiries  = DoubleArray.of(nCaplets, n => directDefinition.DayCount.relativeYearFraction(calibrationDate, cap.CapletFloorletPeriods.get(n).FixingDateTime.toLocalDate()));
            Triple <DoubleArray, DoubleArray, DoubleArray> capletNodes;
            DoubleArray initialVols = DoubleArray.copyOf(volList);

            if (directDefinition.ShiftCurve.Present)
            {
                metadata = Surfaces.blackVolatilityByExpiryStrike(directDefinition.Name.Name, directDefinition.DayCount);
                Curve shiftCurve = directDefinition.ShiftCurve.get();
                if (capFloorData.DataType.Equals(NORMAL_VOLATILITY))
                {
                    initialVols = DoubleArray.of(capList.Count, n => volList[n] / (ratesProvider.iborIndexRates(index).rate(capList[n].FinalPeriod.IborRate.Observation) + shiftCurve.yValue(timeList[n])));
                }
                InterpolatedNodalSurface capVolSurface = InterpolatedNodalSurface.of(metadata, DoubleArray.copyOf(timeList), DoubleArray.copyOf(strikeList), initialVols, INTERPOLATOR);
                capletNodes          = createCapletNodes(capVolSurface, capletExpiries, strikes, directDefinition.ShiftCurve.get());
                volatilitiesFunction = createShiftedBlackVolatilitiesFunction(index, calibrationDateTime, shiftCurve);
            }
            else
            {
                InterpolatedNodalSurface capVolSurface = InterpolatedNodalSurface.of(metadata, DoubleArray.copyOf(timeList), DoubleArray.copyOf(strikeList), initialVols, INTERPOLATOR);
                capletNodes = createCapletNodes(capVolSurface, capletExpiries, strikes);
            }
            InterpolatedNodalSurface baseSurface   = InterpolatedNodalSurface.of(metadata, capletNodes.First, capletNodes.Second, capletNodes.Third, INTERPOLATOR);
            DoubleMatrix             penaltyMatrix = directDefinition.computePenaltyMatrix(strikes, capletExpiries);
            // solve least square
            LeastSquareResults       res        = solver.solve(DoubleArray.copyOf(priceList), DoubleArray.copyOf(errorList), getPriceFunction(capList, ratesProvider, volatilitiesFunction, baseSurface), getJacobianFunction(capList, ratesProvider, volatilitiesFunction, baseSurface), capletNodes.Third, penaltyMatrix, POSITIVE);
            InterpolatedNodalSurface resSurface = InterpolatedNodalSurface.of(metadata, capletNodes.First, capletNodes.Second, res.FitParameters, directDefinition.Interpolator);

            return(IborCapletFloorletVolatilityCalibrationResult.ofLeastSquare(volatilitiesFunction(resSurface), res.ChiSq));
        }