public virtual void relative() { IList <LabelDateParameterMetadata> nodeMetadata = ImmutableList.of(LabelDateParameterMetadata.of(date(2011, 3, 8), TNR_1M), LabelDateParameterMetadata.of(date(2011, 5, 8), TNR_3M), LabelDateParameterMetadata.of(date(2011, 8, 8), TNR_6M)); // This should create 4 scenarios. Scenario zero has no shifts and scenario 3 doesn't have shifts on all nodes PointShifts shift = PointShifts.builder(ShiftType.RELATIVE).addShift(1, TNR_1W, 0.1).addShift(1, TNR_1M, 0.2).addShift(1, TNR_3M, 0.3).addShift(2, TNR_1M, 0.4).addShift(2, TNR_3M, 0.5).addShift(2, TNR_6M, 0.6).addShift(3, TNR_3M, 0.7).build(); Curve curve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("curve"), DayCounts.ACT_365F, nodeMetadata), DoubleArray.of(1, 2, 3), DoubleArray.of(5, 6, 7), INTERPOLATOR); MarketDataBox <ParameterizedData> shiftedCurveBox = shift.applyTo(MarketDataBox.ofSingleValue(curve), REF_DATA); Curve scenario1Curve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("curve"), DayCounts.ACT_365F, nodeMetadata), DoubleArray.of(1, 2, 3), DoubleArray.of(6, 7.8, 7), INTERPOLATOR); Curve scenario2Curve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("curve"), DayCounts.ACT_365F, nodeMetadata), DoubleArray.of(1, 2, 3), DoubleArray.of(7, 9, 11.2), INTERPOLATOR); Curve scenario3Curve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("curve"), DayCounts.ACT_365F, nodeMetadata), DoubleArray.of(1, 2, 3), DoubleArray.of(5, 10.2, 7), INTERPOLATOR); // Scenario zero has no perturbations so the expected curve is the same as the input IList <Curve> expectedCurves = ImmutableList.of(curve, scenario1Curve, scenario2Curve, scenario3Curve); for (int scenarioIndex = 0; scenarioIndex < 4; scenarioIndex++) { // Check every point from 0 to 4 in steps of 0.1 is the same on the bumped curve and the expected curve for (int xIndex = 0; xIndex <= 40; xIndex++) { double xValue = xIndex * 0.1; Curve expectedCurve = expectedCurves[scenarioIndex]; Curve shiftedCurve = (Curve)shiftedCurveBox.getValue(scenarioIndex); double shiftedY = shiftedCurve.yValue(xValue); double expectedY = expectedCurve.yValue(xValue); assertThat(shiftedY).overridingErrorMessage("Curve differed in scenario %d at x value %f, expected %f, actual %f", scenarioIndex, xValue, expectedY, shiftedY).isEqualTo(expectedY); } } }
static DiscountingNotionalExchangePricerTest() { DoubleArray time_gbp = DoubleArray.of(0.0, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0); DoubleArray rate_gbp = DoubleArray.of(0.0160, 0.0135, 0.0160, 0.0185, 0.0185, 0.0195, 0.0200, 0.0210); DISCOUNT_CURVE_GBP = InterpolatedNodalCurve.of(Curves.zeroRates("GBP-Discount", ACT_ACT_ISDA), time_gbp, rate_gbp, INTERPOLATOR); }
public virtual void test_parameterSensitivity_withSpread_full() { int periodPerYear = 2; double spread = 0.0011; // 11 bp ZeroRatePeriodicDiscountFactors test = ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, CURVE); double sensiValue = 25d; ZeroRateSensitivity point = test.zeroRatePointSensitivityWithSpread(DATE_AFTER, spread, PERIODIC, periodPerYear); point = point.multipliedBy(sensiValue); CurrencyParameterSensitivities sensiObject = test.parameterSensitivity(point); assertEquals(sensiObject.Sensitivities.size(), 1); DoubleArray sensi0 = sensiObject.Sensitivities.get(0).Sensitivity; double shift = 1.0E-6; for (int i = 0; i < X.size(); i++) { DoubleArray yP = Y.with(i, Y.get(i) + shift); InterpolatedNodalCurve curveP = InterpolatedNodalCurve.of(META_ZERO_PERIODIC, X, yP, INTERPOLATOR); double dfP = ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, curveP).discountFactorWithSpread(DATE_AFTER, spread, PERIODIC, periodPerYear); DoubleArray yM = Y.with(i, Y.get(i) - shift); InterpolatedNodalCurve curveM = InterpolatedNodalCurve.of(META_ZERO_PERIODIC, X, yM, INTERPOLATOR); double dfM = ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, curveM).discountFactorWithSpread(DATE_AFTER, spread, PERIODIC, periodPerYear); assertEquals(sensi0.get(i), sensiValue * (dfP - dfM) / (2 * shift), TOLERANCE_DELTA_FD, "With spread - " + i); } }
static BondFuturesJpyEnd2EndTest() { for (int i = 0; i < NB_UND_BONDS; ++i) { PeriodicSchedule periodSchedule = PeriodicSchedule.of(START_DATE[i], MATURITY_DATE[i], Frequency.P6M, BUSINESS_ADJUST, StubConvention.SHORT_INITIAL, false); FixedCouponBond product = FixedCouponBond.builder().securityId(SecurityId.of(BOND_SECURITY_ID[i])).dayCount(DAY_COUNT).fixedRate(UND_RATES[i] * ONE_PERCENT).legalEntityId(ISSUER_ID).currency(JPY).notional(NOTIONAL).accrualSchedule(periodSchedule).settlementDateOffset(SETTLEMENT_DAYS).yieldConvention(YIELD_CONVENTION).build(); UND_BOND[i] = product; } UND_BOND_SEP = new FixedCouponBond[NB_UND_BONDS - 2]; Array.Copy(UND_BOND, 2, UND_BOND_SEP, 0, NB_UND_BONDS - 2); UND_BOND_JUN = new FixedCouponBond[NB_UND_BONDS - 1]; Array.Copy(UND_BOND, 1, UND_BOND_JUN, 0, NB_UND_BONDS - 1); double[] timeIssuer = new double[] { 0.25136612021857924, 0.4972677595628415, 1.0139980537465378, 2.013998053746538, 2.857833670184894, 3.857833670184894, 4.860655737704918, 5.857833670184894, 7.104409012650647, 7.857833670184894, 8.857923497267759, 9.863313122239688, 14.857833670184894, 19.857833670184895, 29.857833670184895, 39.11262819073284 }; double[] rateIssuer = new double[] { -0.0013117084834668065, -0.0010851901424876163, -0.0020906775838723216, -0.0022137102045172784, -0.0022695678374162888, -0.0023424568490920798, -0.0021603059162879916, -0.0021667343131861225, -0.0018285921969274823, -0.001355094018965514, -6.763044056712535E-4, 1.9555294306801752E-4, 0.003944125562941363, 0.008054233458390252, 0.012276105941434846, 0.013537766297065804 }; double[] timeRepo = new double[] { 0.00273224043715847, 0.01912568306010929, 0.040983606557377046, 0.05737704918032787, 0.07923497267759563, 0.2459016393442623, 0.4972677595628415, 1.0002994236095515 }; double[] rateRepo = new double[] { 2.599662058772748E-4, -8.403529976927196E-4, -0.0010105103936934236, -0.0011506617573950931, -0.0012708071334455143, -0.00146106683851595, -0.0014710815100096722, -0.001481096281798276 }; CurveMetadata metaIssuer = Curves.zeroRates(ISSUER_CURVE_NAME, ACT_ACT_ISDA); InterpolatedNodalCurve curveIssuer = InterpolatedNodalCurve.of(metaIssuer, DoubleArray.copyOf(timeIssuer), DoubleArray.copyOf(rateIssuer), INTERPOLATOR); DiscountFactors dscIssuer = ZeroRateDiscountFactors.of(JPY, VALUATION, curveIssuer); CurveMetadata metaRepo = Curves.zeroRates(REPO_CURVE_NAME, ACT_ACT_ISDA); InterpolatedNodalCurve curve = InterpolatedNodalCurve.of(metaRepo, DoubleArray.copyOf(timeRepo), DoubleArray.copyOf(rateRepo), INTERPOLATOR); DiscountFactors dscRepo = ZeroRateDiscountFactors.of(JPY, VALUATION, curve); LED_PROVIDER = ImmutableLegalEntityDiscountingProvider.builder().issuerCurves(ImmutableMap.of(Pair.of(GROUP_ISSUER, JPY), dscIssuer)).issuerCurveGroups(ImmutableMap.of(ISSUER_ID, GROUP_ISSUER)).repoCurves(ImmutableMap.of(Pair.of(GROUP_REPO, JPY), dscRepo)).repoCurveGroups(ImmutableMap.of(ISSUER_ID, GROUP_REPO)).build(); }
public virtual void test_loadAllDates() { LocalDate sampleDate = ALL_DATES[3]; // 2017-04-21 ImmutableList <LocalDate> expDates = ImmutableList.of(LocalDate.of(2017, 0x7, 21), LocalDate.of(2017, 10, 0x7), LocalDate.of(2018, 4, 13), LocalDate.of(2019, 4, 12), LocalDate.of(2020, 3, 20), LocalDate.of(2021, 3, 19), LocalDate.of(2022, 3, 19), LocalDate.of(2023, 3, 17), LocalDate.of(2024, 6, 17), LocalDate.of(2025, 3, 18), LocalDate.of(2026, 3, 20), LocalDate.of(2027, 3, 20), LocalDate.of(2031, 12, 19), LocalDate.of(2037, 3, 17), LocalDate.of(2047, 3, 17), LocalDate.of(2056, 3, 17)); ImmutableList <string> expTenors = ImmutableList.of("3M", "6M", "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "15Y", "20Y", "30Y", "40Y"); RepoGroup repoGroup = RepoGroup.of("JP-REPO"); DoubleArray expRepoXValues = DoubleArray.of(3, n => ACT_365F.relativeYearFraction(sampleDate, expDates.get(n))); DoubleArray expRepoYValues = DoubleArray.of(-0.0019521, -0.0016021, -0.0022521); ImmutableList <LabelDateParameterMetadata> expRepoMetadata = IntStream.range(0, 3).mapToObj(n => LabelDateParameterMetadata.of(expDates.get(n), expTenors.get(n))).collect(Guavate.toImmutableList()); LegalEntityGroup legalEntityGroup = LegalEntityGroup.of("JP-GOVT"); DoubleArray expIssuerXValues = DoubleArray.of(expDates.size(), n => ACT_365F.relativeYearFraction(sampleDate, expDates.get(n))); DoubleArray expIssuerYValues = DoubleArray.of(-0.0019511690511744527, -0.001497422302092893, -0.0021798583657932176, -0.002215700360912938, -0.0021722324679574866, -0.001922059591219172, -0.0015461646763548528, -0.0014835851245462084, -0.001118669580570464, -5.476767138782941E-4, -2.2155596172855965E-4, 2.0333291172821893E-5, 0.00284500423293463, 0.005876533417933958, 0.007957581583531789, 0.009134630405512047); ImmutableList <LabelDateParameterMetadata> expIssuerMetadata = IntStream.range(0, expDates.size()).mapToObj(n => LabelDateParameterMetadata.of(expDates.get(n), expTenors.get(n))).collect(Guavate.toImmutableList()); ImmutableListMultimap <LocalDate, LegalEntityCurveGroup> allCurves = LegalEntityRatesCurvesCsvLoader.loadAllDates(ResourceLocator.of(GROUPS), ResourceLocator.of(SETTINGS), ImmutableList.of(ResourceLocator.of(CURVES_1), ResourceLocator.of(CURVES_2))); //JAVA TO C# CONVERTER TODO TASK: There is no .NET equivalent to the java.util.Collection 'containsAll' method: assertTrue(allCurves.Keys.containsAll(ALL_DATES)); ImmutableList <LegalEntityCurveGroup> groups = allCurves.get(sampleDate); assertEquals(groups.size(), 2); // group 0 LegalEntityCurveGroup group0 = groups.get(0); assertEquals(group0.Name, CurveGroupName.of("Default1")); // repo assertEquals(group0.RepoCurves.size(), 1); Curve repoCurve = group0.RepoCurves.get(Pair.of(repoGroup, JPY)); InterpolatedNodalCurve expectedRepoCurve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("JP-REPO-1"), ACT_365F, expRepoMetadata), expRepoXValues, expRepoYValues, CurveInterpolators.LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT); assertEquals(repoCurve, expectedRepoCurve); // issuer assertEquals(group0.IssuerCurves.size(), 2); Curve issuerCurve = group0.IssuerCurves.get(Pair.of(legalEntityGroup, JPY)); InterpolatedNodalCurve expectedIssuerCurve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("JP-GOVT-1"), ACT_365F, expIssuerMetadata), expIssuerXValues, expIssuerYValues, CurveInterpolators.LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT); assertEquals(issuerCurve, expectedIssuerCurve); Curve usIssuerCurve = group0.IssuerCurves.get(Pair.of(LegalEntityGroup.of("US-GOVT"), USD)); expectedIssuerCurve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("US-GOVT"), ACT_360, expIssuerMetadata), DoubleArray.of(expDates.size(), n => ACT_360.relativeYearFraction(sampleDate, expDates.get(n))), expIssuerYValues, CurveInterpolators.NATURAL_SPLINE, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT); assertEquals(usIssuerCurve, expectedIssuerCurve); // group 1 LegalEntityCurveGroup group1 = groups.get(1); assertEquals(group1.Name, CurveGroupName.of("Default2")); // repo repoCurve = group1.RepoCurves.get(Pair.of(repoGroup, JPY)); expectedRepoCurve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("JP-REPO-2"), ACT_365F, expRepoMetadata), expRepoXValues, expRepoYValues, CurveInterpolators.DOUBLE_QUADRATIC, CurveExtrapolators.LINEAR, CurveExtrapolators.LINEAR); assertEquals(repoCurve, expectedRepoCurve); // issuer assertEquals(group1.IssuerCurves.size(), 1); issuerCurve = group1.IssuerCurves.get(Pair.of(legalEntityGroup, JPY)); expectedIssuerCurve = InterpolatedNodalCurve.of(Curves.zeroRates(CurveName.of("JP-GOVT-2"), ACT_365F, expIssuerMetadata), expIssuerXValues, expIssuerYValues, CurveInterpolators.DOUBLE_QUADRATIC, CurveExtrapolators.LINEAR, CurveExtrapolators.LINEAR); assertEquals(issuerCurve, expectedIssuerCurve); }
static DiscountingFraProductPricerTest() { CurveInterpolator interp = CurveInterpolators.DOUBLE_QUADRATIC; DoubleArray time_gbp = DoubleArray.of(0.0, 0.1, 0.25, 0.5, 0.75, 1.0, 2.0); DoubleArray rate_gbp = DoubleArray.of(0.0160, 0.0165, 0.0155, 0.0155, 0.0155, 0.0150, 0.014); InterpolatedNodalCurve dscCurve = InterpolatedNodalCurve.of(Curves.zeroRates("GBP-Discount", DAY_COUNT), time_gbp, rate_gbp, interp); DoubleArray time_index = DoubleArray.of(0.0, 0.25, 0.5, 1.0); DoubleArray rate_index = DoubleArray.of(0.0180, 0.0180, 0.0175, 0.0165); InterpolatedNodalCurve indexCurve = InterpolatedNodalCurve.of(Curves.zeroRates("GBP-GBPIBOR3M", DAY_COUNT), time_index, rate_index, interp); IMM_PROV = ImmutableRatesProvider.builder(VAL_DATE).discountCurve(GBP, dscCurve).iborIndexCurve(GBP_LIBOR_3M, indexCurve).build(); }
public virtual void test_of_badCurve() { InterpolatedNodalCurve notYearFraction = InterpolatedNodalCurve.of(Curves.prices(NAME), DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); InterpolatedNodalCurve notDiscountFactor = InterpolatedNodalCurve.of(Curves.zeroRates(NAME, ACT_365F), DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); CurveMetadata noDayCountMetadata = DefaultCurveMetadata.builder().curveName(NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.DISCOUNT_FACTOR).build(); InterpolatedNodalCurve notDayCount = InterpolatedNodalCurve.of(noDayCountMetadata, DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); assertThrowsIllegalArg(() => SimpleDiscountFactors.of(GBP, DATE_VAL, notYearFraction)); assertThrowsIllegalArg(() => SimpleDiscountFactors.of(GBP, DATE_VAL, notDiscountFactor)); assertThrowsIllegalArg(() => SimpleDiscountFactors.of(GBP, DATE_VAL, notDayCount)); }
//------------------------------------------------------------------------- public virtual void coverage() { SabrIborCapletFloorletVolatilityCalibrationDefinition test1 = SabrIborCapletFloorletVolatilityCalibrationDefinition.ofFixedBeta(NAME, USD_LIBOR_3M, ACT_365F, BETA_RHO, ALPHA_KNOTS, BETA_RHO_KNOTS, NU_KNOTS, DOUBLE_QUADRATIC, FLAT, LINEAR, HAGAN); coverImmutableBean(test1); Curve betaCurve = InterpolatedNodalCurve.of(Curves.sabrParameterByExpiry(NAME.Name + "-Beta", ACT_365F, SABR_BETA), DoubleArray.of(2d, 5d), DoubleArray.of(0.5, 0.8), CurveInterpolators.PCHIP); Curve shiftCurve = ConstantCurve.of("shift curve", 0.03d); DoubleArray initial = DoubleArray.of(0.34, 0.5, -0.22, 1.2); ImmutableList <DoubleArray> knots = ImmutableList.of(ALPHA_KNOTS, DoubleArray.of(), BETA_RHO_KNOTS, DoubleArray.of(1.1)); SabrIborCapletFloorletVolatilityCalibrationDefinition test2 = SabrIborCapletFloorletVolatilityCalibrationDefinition.builder().betaCurve(betaCurve).dayCount(ACT_360).extrapolatorLeft(LINEAR).extrapolatorRight(FLAT).interpolator(PCHIP).index(GBP_LIBOR_3M).initialParameters(initial).name(IborCapletFloorletVolatilitiesName.of("other")).parameterCurveNodes(knots).sabrVolatilityFormula(HAGAN).shiftCurve(shiftCurve).build(); coverBeanEquals(test1, test2); }
public virtual void test_of() { IsdaCreditCurveDefinition test = IsdaCreditCurveDefinition.of(NAME, USD, CURVE_VALUATION_DATE, ACT_ACT_ISDA, NODES, true, false); assertEquals(test.Currency, USD); assertEquals(test.CurveNodes, NODES); assertEquals(test.CurveValuationDate, CURVE_VALUATION_DATE); assertEquals(test.DayCount, ACT_ACT_ISDA); assertEquals(test.ComputeJacobian, true); assertEquals(test.StoreNodeTrade, false); DoubleArray time = DoubleArray.of(1, 2, 3); DoubleArray rate = DoubleArray.of(0.01, 0.014, 0.02); InterpolatedNodalCurve expectedCurve = InterpolatedNodalCurve.of(Curves.zeroRates(NAME, ACT_ACT_ISDA), time, rate, CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR); assertEquals(test.curve(time, rate), expectedCurve); }
public virtual void test_of_fail() { DefaultCurveMetadata metadata = DefaultCurveMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).curveName("yieldUsd").build(); InterpolatedNodalCurve curveNoDcc = InterpolatedNodalCurve.of(metadata, TIME, RATE, CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR); assertThrowsIllegalArg(() => IsdaCreditDiscountFactors.of(USD, VALUATION, curveNoDcc)); InterpolatedNodalCurve curveWrongLeft = InterpolatedNodalCurve.of(METADATA, TIME, RATE, CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.PRODUCT_LINEAR, CurveExtrapolators.PRODUCT_LINEAR); assertThrowsIllegalArg(() => IsdaCreditDiscountFactors.of(USD, VALUATION, curveWrongLeft)); InterpolatedNodalCurve curveWrongInterp = InterpolatedNodalCurve.of(METADATA, TIME, RATE, CurveInterpolators.NATURAL_SPLINE, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR); assertThrowsIllegalArg(() => IsdaCreditDiscountFactors.of(USD, VALUATION, curveWrongInterp)); InterpolatedNodalCurve curveWrongRight = InterpolatedNodalCurve.of(METADATA, TIME, RATE, CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT); assertThrowsIllegalArg(() => IsdaCreditDiscountFactors.of(USD, VALUATION, curveWrongRight)); }
//------------------------------------------------------------------------- internal static ScenarioMarketData marketData(CurveName curveName) { DoubleMatrix jacobian = DoubleMatrix.ofUnsafe(new double[][] { new double[] { 0.985d, 0.01d, 0d }, new double[] { 0.01d, 0.98d, 0.01d }, new double[] { 0.005d, 0.01d, 0.99d } }); JacobianCalibrationMatrix jcm = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(curveName, 3)), jacobian); DoubleArray time = DoubleArray.of(0.1, 0.25, 0.5d); DoubleArray rate = DoubleArray.of(0.01, 0.015, 0.008d); Curve curve = InterpolatedNodalCurve.of(Curves.zeroRates(curveName, ACT_360).withInfo(CurveInfoType.JACOBIAN, jcm), time, rate, NATURAL_SPLINE); TestMarketDataMap md = new TestMarketDataMap(VAL_DATE, ImmutableMap.of(FORWARD_CURVE_ID, curve, QUOTE_KEY, MARKET_PRICE), ImmutableMap.of()); return(md); }
public virtual void test_of_badCurve() { InterpolatedNodalCurve notYearFraction = InterpolatedNodalCurve.of(Curves.prices(NAME), DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); InterpolatedNodalCurve notZeroRate = InterpolatedNodalCurve.of(Curves.discountFactors(NAME, ACT_365F), DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); CurveMetadata noDayCountMetadata = DefaultCurveMetadata.builder().curveName(NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).addInfo(CurveInfoType.COMPOUNDING_PER_YEAR, 4).build(); InterpolatedNodalCurve notDayCount = InterpolatedNodalCurve.of(noDayCountMetadata, DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); CurveMetadata metaNoCompoundPerYear = DefaultCurveMetadata.builder().curveName(NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).dayCount(ACT_365F).build(); InterpolatedNodalCurve notCompoundPerYear = InterpolatedNodalCurve.of(metaNoCompoundPerYear, DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); CurveMetadata metaNegativeNb = DefaultCurveMetadata.builder().curveName(NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).dayCount(ACT_365F).addInfo(CurveInfoType.COMPOUNDING_PER_YEAR, -1).build(); InterpolatedNodalCurve curveNegativeNb = InterpolatedNodalCurve.of(metaNegativeNb, DoubleArray.of(0, 10), DoubleArray.of(1, 2), INTERPOLATOR); assertThrowsIllegalArg(() => ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, notYearFraction)); assertThrowsIllegalArg(() => ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, notZeroRate)); assertThrowsIllegalArg(() => ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, notDayCount)); assertThrowsIllegalArg(() => ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, notCompoundPerYear)); assertThrowsIllegalArg(() => ZeroRatePeriodicDiscountFactors.of(GBP, DATE_VAL, curveNegativeNb)); }
public virtual void test_build_fail() { Curve betaCurve = InterpolatedNodalCurve.of(Curves.sabrParameterByExpiry(NAME.Name + "-Beta", ACT_365F, SABR_BETA), DoubleArray.of(2d, 5d), DoubleArray.of(0.5, 0.8), CurveInterpolators.PCHIP); Curve rhoCurve = InterpolatedNodalCurve.of(Curves.sabrParameterByExpiry(NAME.Name + "-Rho", ACT_365F, SABR_RHO), DoubleArray.of(2d, 5d), DoubleArray.of(0.5, 0.8), CurveInterpolators.PCHIP); Curve shiftCurve = ConstantCurve.of("shift curve", 0.03d); DoubleArray initial = DoubleArray.of(0.34, 0.5, -0.22, 1.2); ImmutableList <DoubleArray> knotsEmptyBeta = ImmutableList.of(ALPHA_KNOTS, DoubleArray.of(), BETA_RHO_KNOTS, NU_KNOTS); ImmutableList <DoubleArray> knotsEmptyRho = ImmutableList.of(ALPHA_KNOTS, BETA_RHO_KNOTS, DoubleArray.of(), NU_KNOTS); // beta, rho not set assertThrowsIllegalArg(() => SabrIborCapletFloorletVolatilityCalibrationDefinition.builder().dayCount(ACT_365F).extrapolatorLeft(FLAT).extrapolatorRight(FLAT).interpolator(DOUBLE_QUADRATIC).index(USD_LIBOR_3M).initialParameters(initial).name(NAME).parameterCurveNodes(knotsEmptyBeta).sabrVolatilityFormula(HAGAN).shiftCurve(shiftCurve).build()); // beta set, but rho knots not defined assertThrowsIllegalArg(() => SabrIborCapletFloorletVolatilityCalibrationDefinition.builder().dayCount(ACT_365F).betaCurve(betaCurve).extrapolatorLeft(FLAT).extrapolatorRight(FLAT).interpolator(DOUBLE_QUADRATIC).index(USD_LIBOR_3M).initialParameters(initial).name(NAME).parameterCurveNodes(knotsEmptyRho).sabrVolatilityFormula(HAGAN).shiftCurve(shiftCurve).build()); // beta rho set assertThrowsIllegalArg(() => SabrIborCapletFloorletVolatilityCalibrationDefinition.builder().dayCount(ACT_365F).betaCurve(betaCurve).rhoCurve(rhoCurve).extrapolatorLeft(FLAT).extrapolatorRight(FLAT).interpolator(DOUBLE_QUADRATIC).index(USD_LIBOR_3M).initialParameters(initial).name(NAME).parameterCurveNodes(knotsEmptyBeta).sabrVolatilityFormula(HAGAN).shiftCurve(shiftCurve).build()); // wrong initial value array size assertThrowsIllegalArg(() => SabrIborCapletFloorletVolatilityCalibrationDefinition.builder().dayCount(ACT_365F).betaCurve(betaCurve).extrapolatorLeft(FLAT).extrapolatorRight(FLAT).interpolator(DOUBLE_QUADRATIC).index(USD_LIBOR_3M).initialParameters(DoubleArray.of(0.34, 0.5, -0.22)).name(NAME).parameterCurveNodes(knotsEmptyBeta).sabrVolatilityFormula(HAGAN).shiftCurve(shiftCurve).build()); assertThrowsIllegalArg(() => SabrIborCapletFloorletVolatilityCalibrationDefinition.builder().dayCount(ACT_365F).betaCurve(betaCurve).extrapolatorLeft(FLAT).extrapolatorRight(FLAT).interpolator(DOUBLE_QUADRATIC).index(USD_LIBOR_3M).initialParameters(initial).name(NAME).parameterCurveNodes(ImmutableList.of(ALPHA_KNOTS, BETA_RHO_KNOTS, NU_KNOTS)).sabrVolatilityFormula(HAGAN).shiftCurve(shiftCurve).build()); }
public virtual void test_builder() { Curve betaCurve = InterpolatedNodalCurve.of(Curves.sabrParameterByExpiry(NAME.Name + "-Beta", ACT_365F, SABR_BETA), DoubleArray.of(2d, 5d), DoubleArray.of(0.5, 0.8), CurveInterpolators.PCHIP); Curve shiftCurve = ConstantCurve.of("shift curve", 0.03d); DoubleArray initial = DoubleArray.of(0.34, 0.5, -0.22, 1.2); ImmutableList <DoubleArray> knots = ImmutableList.of(ALPHA_KNOTS, DoubleArray.of(), BETA_RHO_KNOTS, NU_KNOTS); SabrIborCapletFloorletVolatilityCalibrationDefinition test = SabrIborCapletFloorletVolatilityCalibrationDefinition.builder().betaCurve(betaCurve).dayCount(ACT_365F).extrapolatorLeft(FLAT).extrapolatorRight(FLAT).interpolator(DOUBLE_QUADRATIC).index(USD_LIBOR_3M).initialParameters(initial).name(NAME).parameterCurveNodes(knots).sabrVolatilityFormula(HAGAN).shiftCurve(shiftCurve).build(); assertEquals(test.BetaCurve.get(), betaCurve); assertEquals(test.DayCount, ACT_365F); assertEquals(test.ExtrapolatorLeft, FLAT); assertEquals(test.ExtrapolatorRight, FLAT); assertEquals(test.Index, USD_LIBOR_3M); assertEquals(test.InitialParameters, initial); assertEquals(test.Interpolator, DOUBLE_QUADRATIC); assertEquals(test.Name, NAME); assertFalse(test.RhoCurve.Present); assertEquals(test.SabrVolatilityFormula, HAGAN); assertEquals(test.ShiftCurve, shiftCurve); }
/// <summary> /// Test parameter sensitivity with finite difference sensitivity calculator. No cutoff period. </summary> public virtual void rateChfNoCutOffParameterSensitivity() { LocalDate[] valuationDate = new LocalDate[] { date(2015, 1, 1), date(2015, 1, 8) }; DoubleArray time = DoubleArray.of(0.0, 0.5, 1.0, 2.0, 5.0, 10.0); DoubleArray rate = DoubleArray.of(0.0100, 0.0110, 0.0115, 0.0130, 0.0135, 0.0135); for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) { Curve onCurve = InterpolatedNodalCurve.of(Curves.zeroRates("ON", ACT_ACT_ISDA), time, rate, INTERPOLATOR); ImmutableRatesProvider prov = ImmutableRatesProvider.builder(valuationDate[loopvaldate]).overnightIndexCurve(CHF_TOIS, onCurve, TIME_SERIES).build(); OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(CHF_TOIS, START_DATE, END_DATE, 0, REF_DATA); ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT; PointSensitivityBuilder sensitivityBuilderComputed = obsFn.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov); CurrencyParameterSensitivities parameterSensitivityComputed = prov.parameterSensitivity(sensitivityBuilderComputed.build()); CurrencyParameterSensitivities parameterSensitivityExpected = CAL_FD.sensitivity(prov, (p) => CurrencyAmount.of(CHF_TOIS.Currency, obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, (p)))); assertTrue(parameterSensitivityComputed.equalWithTolerance(parameterSensitivityExpected, EPS_FD * 10.0)); } }
public virtual void test_createSabrParameterCurve() { DoubleArray nuKnots = DoubleArray.of(5.0); SabrIborCapletFloorletVolatilityCalibrationDefinition fixedBeta = SabrIborCapletFloorletVolatilityCalibrationDefinition.ofFixedBeta(NAME, USD_LIBOR_3M, ACT_365F, BETA_RHO, ALPHA_KNOTS, BETA_RHO_KNOTS, nuKnots, DOUBLE_QUADRATIC, FLAT, LINEAR, HAGAN); SabrIborCapletFloorletVolatilityCalibrationDefinition fixedRho = SabrIborCapletFloorletVolatilityCalibrationDefinition.ofFixedRho(NAME, USD_LIBOR_3M, ACT_365F, BETA_RHO, ALPHA_KNOTS, BETA_RHO_KNOTS, nuKnots, DOUBLE_QUADRATIC, FLAT, LINEAR, HAGAN); ImmutableList <CurveMetadata> metadata = fixedBeta.createSabrParameterMetadata(); DoubleArray newValues = DoubleArray.of(0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.05); DoubleArray newValues1 = DoubleArray.of(0.01, 0.01, 0.01, 0.01, 0.01, 0.01); DoubleArray newValues2 = DoubleArray.of(0.02, 0.02, 0.02); DoubleArray newValues3 = DoubleArray.of(0.05); IList <Curve> computedFixedBeta = fixedBeta.createSabrParameterCurve(metadata, newValues); IList <Curve> computedFixedRho = fixedRho.createSabrParameterCurve(metadata, newValues); Curve curveAlpha = InterpolatedNodalCurve.of(metadata.get(0), ALPHA_KNOTS, newValues1, DOUBLE_QUADRATIC, FLAT, LINEAR); Curve curveBeta = InterpolatedNodalCurve.of(metadata.get(1), BETA_RHO_KNOTS, newValues2, DOUBLE_QUADRATIC, FLAT, LINEAR); Curve curveRho = InterpolatedNodalCurve.of(metadata.get(2), BETA_RHO_KNOTS, newValues2, DOUBLE_QUADRATIC, FLAT, LINEAR); Curve curveNu = ConstantNodalCurve.of(metadata.get(3), nuKnots.get(0), newValues3.get(0)); assertEquals(computedFixedBeta, ImmutableList.of(curveAlpha, fixedBeta.BetaCurve.get(), curveRho, curveNu)); assertEquals(computedFixedRho, ImmutableList.of(curveAlpha, curveBeta, fixedRho.RhoCurve.get(), curveNu)); }
//------------------------------------------------------------------------- internal static ScenarioMarketData marketData() { CurveParameterSize issuerSize = CurveParameterSize.of(ISSUER_CURVE_ID.CurveName, 3); CurveParameterSize repoSize = CurveParameterSize.of(REPO_CURVE_ID.CurveName, 2); JacobianCalibrationMatrix issuerMatrix = JacobianCalibrationMatrix.of(ImmutableList.of(issuerSize, repoSize), DoubleMatrix.copyOf(new double[][] { new double[] { 0.95, 0.03, 0.01, 0.006, 0.004 }, new double[] { 0.03, 0.95, 0.01, 0.005, 0.005 }, new double[] { 0.03, 0.01, 0.95, 0.002, 0.008 } })); JacobianCalibrationMatrix repoMatrix = JacobianCalibrationMatrix.of(ImmutableList.of(issuerSize, repoSize), DoubleMatrix.copyOf(new double[][] { new double[] { 0.003, 0.003, 0.004, 0.97, 0.02 }, new double[] { 0.003, 0.006, 0.001, 0.05, 0.94 } })); CurveMetadata issuerMetadata = Curves.zeroRates(ISSUER_CURVE_ID.CurveName, ACT_360).withInfo(CurveInfoType.JACOBIAN, issuerMatrix); CurveMetadata repoMetadata = Curves.zeroRates(REPO_CURVE_ID.CurveName, ACT_360).withInfo(CurveInfoType.JACOBIAN, repoMatrix); Curve issuerCurve = InterpolatedNodalCurve.of(issuerMetadata, DoubleArray.of(1.0, 5.0, 10.0), DoubleArray.of(0.02, 0.04, 0.01), CurveInterpolators.LINEAR); Curve repoCurve = InterpolatedNodalCurve.of(repoMetadata, DoubleArray.of(0.5, 3.0), DoubleArray.of(0.005, 0.008), CurveInterpolators.LINEAR); return(new TestMarketDataMap(VALUATION_DATE, ImmutableMap.of(REPO_CURVE_ID, repoCurve, ISSUER_CURVE_ID, issuerCurve), ImmutableMap.of())); }
public virtual void pointAndParameterPriceIndex() { double eps = 1.0e-13; LocalDate valuationDate = LocalDate.of(2014, 1, 22); DoubleArray x = DoubleArray.of(0.5, 1.0, 2.0); DoubleArray y = DoubleArray.of(224.2, 262.6, 277.5); CurveInterpolator interp = CurveInterpolators.NATURAL_CUBIC_SPLINE; string curveName = "GB_RPI_CURVE"; InterpolatedNodalCurve interpCurve = InterpolatedNodalCurve.of(Curves.prices(curveName), x, y, interp); ImmutableRatesProvider provider = ImmutableRatesProvider.builder(VAL_DATE).priceIndexCurve(GB_RPI, interpCurve).timeSeries(GB_RPI, LocalDateDoubleTimeSeries.of(date(2013, 11, 30), 200)).build(); double pointSensiValue = 2.5; YearMonth refMonth = YearMonth.from(valuationDate.plusMonths(9)); InflationRateSensitivity pointSensi = InflationRateSensitivity.of(PriceIndexObservation.of(GB_RPI, refMonth), pointSensiValue); CurrencyParameterSensitivities computed = provider.parameterSensitivity(pointSensi.build()); DoubleArray sensiComputed = computed.Sensitivities.get(0).Sensitivity; InflationRateSensitivity pointSensi1 = InflationRateSensitivity.of(PriceIndexObservation.of(GB_RPI, refMonth), 1); DoubleArray sensiExpectedUnit = provider.priceIndexValues(GB_RPI).parameterSensitivity(pointSensi1).Sensitivities.get(0).Sensitivity; assertTrue(sensiComputed.equalWithTolerance(sensiExpectedUnit.multipliedBy(pointSensiValue), eps)); }
/// <summary> /// Creates an instance from year fraction and zero rate values. /// </summary> /// <param name="currency"> the currency </param> /// <param name="valuationDate"> the valuation date </param> /// <param name="curveName"> the curve name </param> /// <param name="yearFractions"> the year fractions </param> /// <param name="zeroRates"> the zero rates </param> /// <param name="dayCount"> the day count </param> /// <returns> the instance </returns> public static IsdaCreditDiscountFactors of(Currency currency, LocalDate valuationDate, CurveName curveName, DoubleArray yearFractions, DoubleArray zeroRates, DayCount dayCount) { ArgChecker.notNull(yearFractions, "yearFractions"); ArgChecker.notNull(zeroRates, "zeroRates"); DefaultCurveMetadata metadata = DefaultCurveMetadata.builder().xValueType(YEAR_FRACTION).yValueType(ZERO_RATE).curveName(curveName).dayCount(dayCount).build(); NodalCurve curve = (yearFractions.size() == 1 && zeroRates.size() == 1) ? ConstantNodalCurve.of(metadata, yearFractions.get(0), zeroRates.get(0)) : InterpolatedNodalCurve.of(metadata, yearFractions, zeroRates, CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR); return(new IsdaCreditDiscountFactors(currency, valuationDate, curve)); }
//------------------------------------------------------------------------- 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 SabrIborCapletFloorletVolatilityBootstrapDefinition, "definition should be SabrIborCapletFloorletVolatilityBootstrapDefinition"); SabrIborCapletFloorletVolatilityBootstrapDefinition bsDefinition = (SabrIborCapletFloorletVolatilityBootstrapDefinition)definition; IborIndex index = bsDefinition.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(bsDefinition, calibrationDateTime, capFloorData); SurfaceMetadata metaData = bsDefinition.createMetadata(capFloorData); IList <Period> expiries = capFloorData.Expiries; int nExpiries = expiries.Count; DoubleArray strikes = capFloorData.Strikes; DoubleMatrix errorsMatrix = capFloorData.Error.orElse(DoubleMatrix.filled(nExpiries, strikes.size(), 1d)); 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>(); int[] startIndex = new int[nExpiries + 1]; for (int i = 0; i < nExpiries; ++i) { LocalDate endDate = baseDate.plus(expiries[i]); DoubleArray volatilityData = capFloorData.Data.row(i); DoubleArray errors = errorsMatrix.row(i); reduceRawData(bsDefinition, ratesProvider, strikes, volatilityData, errors, 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]); } IList <CurveMetadata> metadataList = bsDefinition.createSabrParameterMetadata(); DoubleArray timeToExpiries = DoubleArray.of(nExpiries, i => timeList[startIndex[i]]); BitArray @fixed = new BitArray(); bool betaFix = false; Curve betaCurve; Curve rhoCurve; if (bsDefinition.BetaCurve.Present) { betaFix = true; @fixed.Set(1, true); betaCurve = bsDefinition.BetaCurve.get(); rhoCurve = InterpolatedNodalCurve.of(metadataList[2], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight); } else { @fixed.Set(2, true); betaCurve = InterpolatedNodalCurve.of(metadataList[1], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight); rhoCurve = bsDefinition.RhoCurve.get(); } InterpolatedNodalCurve alphaCurve = InterpolatedNodalCurve.of(metadataList[0], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight); InterpolatedNodalCurve nuCurve = InterpolatedNodalCurve.of(metadataList[3], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight); Curve shiftCurve = bsDefinition.ShiftCurve; SabrParameters sabrParams = SabrParameters.of(alphaCurve, betaCurve, rhoCurve, nuCurve, shiftCurve, bsDefinition.SabrVolatilityFormula); SabrParametersIborCapletFloorletVolatilities vols = SabrParametersIborCapletFloorletVolatilities.of(bsDefinition.Name, index, calibrationDateTime, sabrParams); double totalChiSq = 0d; ZonedDateTime prevExpiry = calibrationDateTime.minusDays(1L); // included if calibrationDateTime == fixingDateTime for (int i = 0; i < nExpiries; ++i) { DoubleArray start = computeInitialValues(ratesProvider, betaCurve, shiftCurve, timeList, volList, capList, startIndex, i, betaFix, capFloorData.DataType); UncoupledParameterTransforms transform = new UncoupledParameterTransforms(start, TRANSFORMS, @fixed); int nCaplets = startIndex[i + 1] - startIndex[i]; int currentStart = startIndex[i]; System.Func <DoubleArray, DoubleArray> valueFunction = createPriceFunction(ratesProvider, vols, prevExpiry, capList, priceList, startIndex, nExpiries, i, nCaplets, betaFix); System.Func <DoubleArray, DoubleMatrix> jacobianFunction = createJacobianFunction(ratesProvider, vols, prevExpiry, capList, priceList, index.Currency, startIndex, nExpiries, i, nCaplets, betaFix); NonLinearTransformFunction transFunc = new NonLinearTransformFunction(valueFunction, jacobianFunction, transform); DoubleArray adjustedPrices = this.adjustedPrices(ratesProvider, vols, prevExpiry, capList, priceList, startIndex, i, nCaplets); DoubleArray errors = DoubleArray.of(nCaplets, n => errorList[currentStart + n]); LeastSquareResults res = solver.solve(adjustedPrices, errors, transFunc.FittingFunction, transFunc.FittingJacobian, transform.transform(start)); LeastSquareResultsWithTransform resTransform = new LeastSquareResultsWithTransform(res, transform); vols = updateParameters(vols, nExpiries, i, betaFix, resTransform.ModelParameters); totalChiSq += res.ChiSq; prevExpiry = capList[startIndex[i + 1] - 1].FinalFixingDateTime; } return(IborCapletFloorletVolatilityCalibrationResult.ofLeastSquare(vols, totalChiSq)); }
//------------------------------------------------------------------------- public override NodalCurve calibrate(IList <ResolvedCdsTrade> calibrationCDSs, DoubleArray premiums, DoubleArray pointsUpfront, CurveName name, LocalDate valuationDate, CreditDiscountFactors discountFactors, RecoveryRates recoveryRates, ReferenceData refData) { int n = calibrationCDSs.Count; double[] guess = new double[n]; double[] t = new double[n]; double[] lgd = new double[n]; for (int i = 0; i < n; i++) { LocalDate endDate = calibrationCDSs[i].Product.ProtectionEndDate; t[i] = discountFactors.relativeYearFraction(endDate); lgd[i] = 1d - recoveryRates.recoveryRate(endDate); guess[i] = (premiums.get(i) + pointsUpfront.get(i) / t[i]) / lgd[i]; } DoubleArray times = DoubleArray.ofUnsafe(t); CurveMetadata baseMetadata = DefaultCurveMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).curveName(name).dayCount(discountFactors.DayCount).build(); NodalCurve creditCurve = n == 1 ? ConstantNodalCurve.of(baseMetadata, t[0], guess[0]) : InterpolatedNodalCurve.of(baseMetadata, times, DoubleArray.ofUnsafe(guess), CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR); for (int i = 0; i < n; i++) { System.Func <double, double> func = getPriceFunction(i, calibrationCDSs[i], premiums.get(i), pointsUpfront.get(i), valuationDate, creditCurve, discountFactors, recoveryRates, refData); double[] bracket = BRACKER.getBracketedPoints(func, 0.8 * guess[i], 1.25 * guess[i], 0.0, double.PositiveInfinity); double zeroRate = bracket[0] > bracket[1] ? ROOTFINDER.getRoot(func, bracket[1], bracket[0]) : ROOTFINDER.getRoot(func, bracket[0], bracket[1]); //Negative guess handled creditCurve = creditCurve.withParameter(i, zeroRate); } return(creditCurve); }
//------------------------------------------------------------------------- public override NodalCurve calibrate(IList <ResolvedCdsTrade> calibrationCDSs, DoubleArray flactionalSpreads, DoubleArray pointsUpfront, CurveName name, LocalDate valuationDate, CreditDiscountFactors discountFactors, RecoveryRates recoveryRates, ReferenceData refData) { int n = calibrationCDSs.Count; double[] guess = new double[n]; double[] t = new double[n]; double[] lgd = new double[n]; for (int i = 0; i < n; i++) { LocalDate endDate = calibrationCDSs[i].Product.ProtectionEndDate; t[i] = discountFactors.relativeYearFraction(endDate); lgd[i] = 1d - recoveryRates.recoveryRate(endDate); guess[i] = (flactionalSpreads.get(i) + pointsUpfront.get(i) / t[i]) / lgd[i]; } DoubleArray times = DoubleArray.ofUnsafe(t); CurveMetadata baseMetadata = DefaultCurveMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).curveName(name).dayCount(discountFactors.DayCount).build(); NodalCurve creditCurve = n == 1 ? ConstantNodalCurve.of(baseMetadata, t[0], guess[0]) : InterpolatedNodalCurve.of(baseMetadata, times, DoubleArray.ofUnsafe(guess), CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR); for (int i = 0; i < n; i++) { ResolvedCds cds = calibrationCDSs[i].Product; LocalDate stepinDate = cds.StepinDateOffset.adjust(valuationDate, refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); LocalDate settlementDate = calibrationCDSs[i].Info.SettlementDate.orElse(cds.SettlementDateOffset.adjust(valuationDate, refData)); double accrued = cds.accruedYearFraction(stepinDate); Pricer pricer = new Pricer(this, cds, discountFactors, times, flactionalSpreads.get(i), pointsUpfront.get(i), lgd[i], stepinDate, effectiveStartDate, settlementDate, accrued); System.Func <double, double> func = pricer.getPointFunction(i, creditCurve); switch (ArbitrageHandling) { case IGNORE: { try { double[] bracket = BRACKETER.getBracketedPoints(func, 0.8 * guess[i], 1.25 * guess[i], double.NegativeInfinity, double.PositiveInfinity); double zeroRate = bracket[0] > bracket[1] ? ROOTFINDER.getRoot(func, bracket[1], bracket[0]) : ROOTFINDER.getRoot(func, bracket[0], bracket[1]); //Negative guess handled creditCurve = creditCurve.withParameter(i, zeroRate); } //JAVA TO C# CONVERTER WARNING: 'final' catch parameters are not available in C#: //ORIGINAL LINE: catch (final com.opengamma.strata.math.MathException e) catch (MathException e) { //handling bracketing failure due to small survival probability if (Math.Abs(func(creditCurve.YValues.get(i - 1))) < 1.e-12) { creditCurve = creditCurve.withParameter(i, creditCurve.YValues.get(i - 1)); } else { throw new MathException(e); } } break; } case FAIL: { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double minValue = i == 0 ? 0d : creditCurve.getYValues().get(i - 1) * creditCurve.getXValues().get(i - 1) / creditCurve.getXValues().get(i); double minValue = i == 0 ? 0d : creditCurve.YValues.get(i - 1) * creditCurve.XValues.get(i - 1) / creditCurve.XValues.get(i); if (i > 0 && func(minValue) > 0.0) { //can never fail on the first spread //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder(); if (pointsUpfront.get(i) == 0.0) { msg.Append("The par spread of " + flactionalSpreads.get(i) + " at index " + i); } else { msg.Append("The premium of " + flactionalSpreads.get(i) + "and points up-front of " + pointsUpfront.get(i) + " at index " + i); } msg.Append(" is an arbitrage; cannot fit a curve with positive forward hazard rate. "); throw new System.ArgumentException(msg.ToString()); } guess[i] = Math.Max(minValue, guess[i]); double[] bracket = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, double.PositiveInfinity); double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]).Value; creditCurve = creditCurve.withParameter(i, zeroRate); break; } case ZERO_HAZARD_RATE: { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double minValue = i == 0 ? 0.0 : creditCurve.getYValues().get(i - 1) * creditCurve.getXValues().get(i - 1) / creditCurve.getXValues().get(i); double minValue = i == 0 ? 0.0 : creditCurve.YValues.get(i - 1) * creditCurve.XValues.get(i - 1) / creditCurve.XValues.get(i); if (i > 0 && func(minValue) > 0.0) { //can never fail on the first spread creditCurve = creditCurve.withParameter(i, minValue); } else { guess[i] = Math.Max(minValue, guess[i]); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double[] bracket = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, Double.POSITIVE_INFINITY); double[] bracket = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, double.PositiveInfinity); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]); double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]).Value; creditCurve = creditCurve.withParameter(i, zeroRate); } break; } default: throw new System.ArgumentException("unknown case " + ArbitrageHandling); } } return(creditCurve); }