//------------------------------------------------------------------------- // Check market data computation public virtual void market_data() { RatesCurveGroupDefinition group = GROUPS_SYN_EUR; RatesProvider multicurveTsLarge = MULTICURVE_INPUT_EUR_TSEMPTY.toBuilder().timeSeries(TS_LARGE).build(); MarketData madTsEmpty = CALIBRATOR_SYNTHETIC.marketData(group, MULTICURVE_INPUT_EUR_TSEMPTY, REF_DATA); MarketData madTsLarge = CALIBRATOR_SYNTHETIC.marketData(group, multicurveTsLarge, REF_DATA); assertEquals(madTsEmpty.ValuationDate, VALUATION_DATE); foreach (CurveDefinition entry in group.CurveDefinitions) { ImmutableList <CurveNode> nodes = entry.Nodes; foreach (CurveNode node in nodes) { ResolvedTrade tradeTsEmpty = node.resolvedTrade(1d, madTsEmpty, REF_DATA); double mqTsEmpty = MQ_MEASURES.value(tradeTsEmpty, MULTICURVE_INPUT_EUR_TSEMPTY); assertEquals(mqTsEmpty, (double?)madTsEmpty.getValue(node.requirements().GetEnumerator().next()), TOLERANCE_MQ); ResolvedTrade tradeTsLarge = node.resolvedTrade(1d, madTsLarge, REF_DATA); double mqTsLarge = MQ_MEASURES.value(tradeTsLarge, multicurveTsLarge); assertEquals(mqTsLarge, (double?)madTsLarge.getValue(node.requirements().GetEnumerator().next()), TOLERANCE_MQ); // Market Quote for Fixed v ibor swaps should have changed with the fixing if ((tradeTsLarge is ResolvedSwapTrade) && (((ResolvedSwapTrade)tradeTsLarge)).Product.getLegs(SwapLegType.IBOR).size() == 1) { assertTrue(Math.Abs(mqTsEmpty - mqTsLarge) > TOLERANCE_MQ); } } } assertEquals(madTsEmpty.TimeSeriesIds, ImmutableSet.of()); assertEquals(madTsLarge.TimeSeriesIds, ImmutableSet.of(IndexQuoteId.of(EUR_EURIBOR_3M), IndexQuoteId.of(EUR_EURIBOR_6M))); }
public virtual void test_combinedWith_sameCurveNamesClash() { RatesCurveGroupDefinition base1 = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addCurve(CURVE_DEFN1, GBP, GBP_LIBOR_1M, GBP_LIBOR_3M).addForwardCurve(CURVE_DEFN_I, GB_RPI).build(); RatesCurveGroupDefinition base2 = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("TestX")).addCurve(CURVE_DEFN1B, GBP, GBP_LIBOR_6M).build(); assertThrowsIllegalArg(() => base1.combinedWith(base2)); }
/// <summary> /// Test that inputs are correctly built from market data. /// </summary> public virtual void build() { FraCurveNode node1x4 = fraNode(1, "a"); FraCurveNode node2x5 = fraNode(2, "b"); FraCurveNode node3x6 = fraNode(3, "c"); InterpolatedNodalCurveDefinition curveDefn = InterpolatedNodalCurveDefinition.builder().name(CurveName.of("curve")).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).dayCount(DayCounts.ACT_ACT_ISDA).interpolator(CurveInterpolators.DOUBLE_QUADRATIC).extrapolatorLeft(CurveExtrapolators.FLAT).extrapolatorRight(CurveExtrapolators.FLAT).nodes(node1x4, node2x5, node3x6).build(); RatesCurveGroupDefinition groupDefn = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("curve group")).addDiscountCurve(curveDefn, Currency.USD).build(); MarketDataConfig marketDataConfig = MarketDataConfig.builder().add(groupDefn.Name, groupDefn).build(); QuoteId idA = QuoteId.of(StandardId.of("test", "a")); QuoteId idB = QuoteId.of(StandardId.of("test", "b")); QuoteId idC = QuoteId.of(StandardId.of("test", "c")); ScenarioMarketData marketData = ImmutableScenarioMarketData.builder(VAL_DATE).addValue(idA, 1d).addValue(idB, 2d).addValue(idC, 3d).build(); RatesCurveInputsMarketDataFunction marketDataFunction = new RatesCurveInputsMarketDataFunction(); RatesCurveInputsId curveInputsId = RatesCurveInputsId.of(groupDefn.Name, curveDefn.Name, ObservableSource.NONE); MarketDataBox <RatesCurveInputs> result = marketDataFunction.build(curveInputsId, marketDataConfig, marketData, REF_DATA); RatesCurveInputs curveInputs = result.SingleValue; assertThat(curveInputs.MarketData.get(idA)).isEqualTo(1d); assertThat(curveInputs.MarketData.get(idB)).isEqualTo(2d); assertThat(curveInputs.MarketData.get(idC)).isEqualTo(3d); IList <ParameterMetadata> expectedMetadata = ImmutableList.of(node1x4.metadata(VAL_DATE, REF_DATA), node2x5.metadata(VAL_DATE, REF_DATA), node3x6.metadata(VAL_DATE, REF_DATA)); assertThat(curveInputs.CurveMetadata.ParameterMetadata).hasValue(expectedMetadata); }
/// <summary> /// Creates a curve group using a curve group definition and a list of existing curves. /// <para> /// If there are curves named in the definition which are not present in the curves the group is built using /// whatever curves are available. /// </para> /// <para> /// If there are multiple curves with the same name in the curves one of them is arbitrarily chosen. /// </para> /// <para> /// Multiple curves with the same name are allowed to support the use case where the list contains the same /// curve multiple times. This means the caller doesn't have to filter the input curves to remove duplicates. /// /// </para> /// </summary> /// <param name="curveGroupDefinition"> the definition of a curve group </param> /// <param name="curves"> some curves </param> /// <returns> a curve group built from the definition and the list of curves </returns> public static RatesCurveGroup ofCurves <T1>(RatesCurveGroupDefinition curveGroupDefinition, ICollection <T1> curves) where T1 : Curve { IDictionary <Currency, Curve> discountCurves = new Dictionary <Currency, Curve>(); IDictionary <Index, Curve> forwardCurves = new Dictionary <Index, Curve>(); IDictionary <CurveName, Curve> curveMap = curves.ToDictionary(curve => curve.Metadata.CurveName, curve => curve, (curve1, curve2) => curve1); foreach (RatesCurveGroupEntry entry in curveGroupDefinition.Entries) { CurveName curveName = entry.CurveName; Curve curve = curveMap[curveName]; if (curve == null) { log.debug("No curve found named '{}' when building curve group '{}'", curveName, curveGroupDefinition.Name); continue; } foreach (Currency currency in entry.DiscountCurrencies) { discountCurves[currency] = curve; } foreach (Index index in entry.Indices) { forwardCurves[index] = curve; } } return(RatesCurveGroup.of(curveGroupDefinition.Name, discountCurves, forwardCurves)); }
public static RatesCurveGroupDefinition config(Period[] dscOisTenors, string[] dscIdValues, Period[] fwd3FraTenors, Period[] fwd3IrsTenors, string[] fwd3IdValues, Period[] fwd6FraTenors, Period[] fwd6IrsTenors, string[] fwd6IdValues) { CurveNode[] dscNodes = new CurveNode[dscOisTenors.Length]; for (int i = 0; i < dscOisTenors.Length; i++) { dscNodes[i] = FixedOvernightSwapCurveNode.of(FixedOvernightSwapTemplate.of(Period.ZERO, Tenor.of(dscOisTenors[i]), EUR_FIXED_1Y_EONIA_OIS), QuoteId.of(StandardId.of(SCHEME, dscIdValues[i]))); } CurveNode[] fwd3Nodes = new CurveNode[fwd3IdValues.Length]; fwd3Nodes[0] = IborFixingDepositCurveNode.of(IborFixingDepositTemplate.of(EUR_EURIBOR_3M), QuoteId.of(StandardId.of(SCHEME, fwd3IdValues[0]))); for (int i = 0; i < fwd3FraTenors.Length; i++) { fwd3Nodes[i + 1] = FraCurveNode.of(FraTemplate.of(fwd3FraTenors[i], EUR_EURIBOR_3M), QuoteId.of(StandardId.of(SCHEME, fwd3IdValues[i + 1]))); } for (int i = 0; i < fwd3IrsTenors.Length; i++) { fwd3Nodes[i + 1 + fwd3FraTenors.Length] = FixedIborSwapCurveNode.of(FixedIborSwapTemplate.of(Period.ZERO, Tenor.of(fwd3IrsTenors[i]), EUR_FIXED_1Y_EURIBOR_3M), QuoteId.of(StandardId.of(SCHEME, fwd3IdValues[i + 1 + fwd3FraTenors.Length]))); } CurveNode[] fwd6Nodes = new CurveNode[fwd6IdValues.Length]; fwd6Nodes[0] = IborFixingDepositCurveNode.of(IborFixingDepositTemplate.of(EUR_EURIBOR_6M), QuoteId.of(StandardId.of(SCHEME, fwd6IdValues[0]))); for (int i = 0; i < fwd6FraTenors.Length; i++) { fwd6Nodes[i + 1] = FraCurveNode.of(FraTemplate.of(fwd6FraTenors[i], EUR_EURIBOR_6M), QuoteId.of(StandardId.of(SCHEME, fwd6IdValues[i + 1]))); } for (int i = 0; i < fwd6IrsTenors.Length; i++) { fwd6Nodes[i + 1 + fwd6FraTenors.Length] = FixedIborSwapCurveNode.of(FixedIborSwapTemplate.of(Period.ZERO, Tenor.of(fwd6IrsTenors[i]), EUR_FIXED_1Y_EURIBOR_6M), QuoteId.of(StandardId.of(SCHEME, fwd6IdValues[i + 1 + fwd6FraTenors.Length]))); } InterpolatedNodalCurveDefinition DSC_CURVE_DEFN = InterpolatedNodalCurveDefinition.builder().name(DSCON_CURVE_NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).dayCount(CURVE_DC).interpolator(INTERPOLATOR_LINEAR).extrapolatorLeft(EXTRAPOLATOR_FLAT).extrapolatorRight(EXTRAPOLATOR_FLAT).nodes(dscNodes).build(); InterpolatedNodalCurveDefinition FWD3_CURVE_DEFN = InterpolatedNodalCurveDefinition.builder().name(FWD3_CURVE_NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).dayCount(CURVE_DC).interpolator(INTERPOLATOR_LINEAR).extrapolatorLeft(EXTRAPOLATOR_FLAT).extrapolatorRight(EXTRAPOLATOR_FLAT).nodes(fwd3Nodes).build(); InterpolatedNodalCurveDefinition FWD6_CURVE_DEFN = InterpolatedNodalCurveDefinition.builder().name(FWD6_CURVE_NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).dayCount(CURVE_DC).interpolator(INTERPOLATOR_LINEAR).extrapolatorLeft(EXTRAPOLATOR_FLAT).extrapolatorRight(EXTRAPOLATOR_FLAT).nodes(fwd6Nodes).build(); return(RatesCurveGroupDefinition.builder().name(CURVE_GROUP_NAME).addCurve(DSC_CURVE_DEFN, EUR, EUR_EONIA).addForwardCurve(FWD3_CURVE_DEFN, EUR_EURIBOR_3M).addForwardCurve(FWD6_CURVE_DEFN, EUR_EURIBOR_6M).build()); }
private RatesCurveGroup buildGroup(RatesCurveGroupDefinition groupDefn, RatesCurveCalibrator calibrator, MarketData marketData, ReferenceData refData) { // perform the calibration ImmutableRatesProvider calibratedProvider = calibrator.calibrate(groupDefn, marketData, refData); return(RatesCurveGroup.of(groupDefn.Name, calibratedProvider.DiscountCurves, calibratedProvider.IndexCurves)); }
public virtual void test_bind_no_seasonality() { RatesCurveGroupDefinition test = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addCurve(CURVE_DEFN1, GBP, GBP_LIBOR_1M, GBP_LIBOR_3M).addForwardCurve(CURVE_DEFN_I, GB_RPI).build(); LocalDate valuationDate = LocalDate.of(2015, 11, 10); LocalDate lastFixingDate = LocalDate.of(2015, 10, 31); LocalDate otherFixingDate = LocalDate.of(2015, 9, 30); double lastFixingValue = 234.56; IDictionary <Index, LocalDateDoubleTimeSeries> map = ImmutableMap.of(GB_RPI, LocalDateDoubleTimeSeries.builder().put(lastFixingDate, 234.56).put(otherFixingDate, lastFixingValue - 1).build()); RatesCurveGroupDefinition testBound = test.bindTimeSeries(valuationDate, map); IList <CurveDefinition> list = testBound.CurveDefinitions; assertEquals(list.Count, 2); assertTrue(list[0] is InterpolatedNodalCurveDefinition); assertTrue(list[1] is InflationNodalCurveDefinition); InflationNodalCurveDefinition seasonDef = (InflationNodalCurveDefinition)list[1]; assertEquals(seasonDef.CurveWithoutFixingDefinition, CURVE_DEFN_I); assertEquals(seasonDef.LastFixingMonth, YearMonth.from(lastFixingDate)); assertEquals(seasonDef.LastFixingValue, lastFixingValue); assertEquals(seasonDef.Name, CURVE_NAME_I); assertEquals(seasonDef.YValueType, ValueType.PRICE_INDEX); // Check the default assertTrue(seasonDef.SeasonalityDefinition.SeasonalityMonthOnMonth.equalWithTolerance(DoubleArray.filled(12, 1d), 1.0E-10)); assertEquals(seasonDef.SeasonalityDefinition.AdjustmentType, ShiftType.SCALED); }
//------------------------------------------------------------------------- private void assertDefinition(RatesCurveGroupDefinition defn) { assertEquals(defn.Name, CurveGroupName.of("Default")); assertEquals(defn.Entries.size(), 3); assertEquals(defn.SeasonalityDefinitions.size(), 1); assertEquals(defn.SeasonalityDefinitions.get(CurveName.of("USD-CPI")).AdjustmentType, ShiftType.SCALED); RatesCurveGroupEntry entry0 = findEntry(defn, "USD-Disc"); RatesCurveGroupEntry entry1 = findEntry(defn, "USD-3ML"); RatesCurveGroupEntry entry2 = findEntry(defn, "USD-CPI"); CurveDefinition defn0 = defn.findCurveDefinition(entry0.CurveName).get(); CurveDefinition defn1 = defn.findCurveDefinition(entry1.CurveName).get(); CurveDefinition defn2 = defn.findCurveDefinition(entry2.CurveName).get(); assertEquals(entry0.DiscountCurrencies, ImmutableSet.of(Currency.USD)); assertEquals(entry0.Indices, ImmutableSet.of()); assertEquals(defn0.Name, CurveName.of("USD-Disc")); assertEquals(defn0.YValueType, ValueType.ZERO_RATE); assertEquals(defn0.ParameterCount, 17); assertEquals(entry1.DiscountCurrencies, ImmutableSet.of()); assertEquals(entry1.Indices, ImmutableSet.of(IborIndices.USD_LIBOR_3M)); assertEquals(defn1.Name, CurveName.of("USD-3ML")); assertEquals(defn1.YValueType, ValueType.ZERO_RATE); assertEquals(defn1.ParameterCount, 27); assertEquals(entry2.DiscountCurrencies, ImmutableSet.of()); assertEquals(entry2.Indices, ImmutableSet.of(PriceIndices.US_CPI_U)); assertEquals(defn2.Name, CurveName.of("USD-CPI")); assertEquals(defn2.YValueType, ValueType.PRICE_INDEX); assertEquals(defn2.ParameterCount, 2); }
/// <summary> /// End-to-end test for curve calibration and round-tripping that uses the <seealso cref="MarketDataFactory"/> /// to calibrate a curve and calculate PVs for the instruments at the curve nodes. /// /// This tests the full pipeline of market data functions: /// - Par rates /// - Curve group (including calibration) /// - Individual curves /// - Discount factors /// </summary> public virtual void roundTripFraAndFixedFloatSwap() { // Configuration and market data for the curve --------------------------------- string fra3x6 = "fra3x6"; string fra6x9 = "fra6x9"; string swap1y = "swap1y"; string swap2y = "swap2y"; string swap3y = "swap3y"; FraCurveNode fra3x6Node = fraNode(3, fra3x6); FraCurveNode fra6x9Node = fraNode(6, fra6x9); FixedIborSwapCurveNode swap1yNode = fixedIborSwapNode(Tenor.TENOR_1Y, swap1y); FixedIborSwapCurveNode swap2yNode = fixedIborSwapNode(Tenor.TENOR_2Y, swap2y); FixedIborSwapCurveNode swap3yNode = fixedIborSwapNode(Tenor.TENOR_3Y, swap3y); IDictionary <ObservableId, double> parRateData = ImmutableMap.builder <ObservableId, double>().put(id(fra3x6), 0.0037).put(id(fra6x9), 0.0054).put(id(swap1y), 0.005).put(id(swap2y), 0.0087).put(id(swap3y), 0.012).build(); LocalDate valuationDate = date(2011, 3, 8); // Build the trades from the node instruments MarketData quotes = ImmutableMarketData.of(valuationDate, parRateData); Trade fra3x6Trade = fra3x6Node.trade(1d, quotes, REF_DATA); Trade fra6x9Trade = fra6x9Node.trade(1d, quotes, REF_DATA); Trade swap1yTrade = swap1yNode.trade(1d, quotes, REF_DATA); Trade swap2yTrade = swap2yNode.trade(1d, quotes, REF_DATA); Trade swap3yTrade = swap3yNode.trade(1d, quotes, REF_DATA); IList <Trade> trades = ImmutableList.of(fra3x6Trade, fra6x9Trade, swap1yTrade, swap2yTrade, swap3yTrade); IList <CurveNode> nodes = ImmutableList.of(fra3x6Node, fra6x9Node, swap1yNode, swap2yNode, swap3yNode); CurveGroupName groupName = CurveGroupName.of("Curve Group"); CurveName curveName = CurveName.of("FRA and Fixed-Float Swap Curve"); InterpolatedNodalCurveDefinition curveDefn = InterpolatedNodalCurveDefinition.builder().name(curveName).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).dayCount(DayCounts.ACT_ACT_ISDA).nodes(nodes).interpolator(CurveInterpolators.DOUBLE_QUADRATIC).extrapolatorLeft(CurveExtrapolators.FLAT).extrapolatorRight(CurveExtrapolators.FLAT).build(); RatesCurveGroupDefinition groupDefn = RatesCurveGroupDefinition.builder().name(groupName).addCurve(curveDefn, Currency.USD, IborIndices.USD_LIBOR_3M).build(); MarketDataConfig marketDataConfig = MarketDataConfig.builder().add(groupName, groupDefn).build(); // Rules for market data and calculations --------------------------------- RatesMarketDataLookup ratesLookup = RatesMarketDataLookup.of(groupDefn); CalculationRules calculationRules = CalculationRules.of(functions(), Currency.USD, ratesLookup); // Calculate the results and check the PVs for the node instruments are zero ---------------------- IList <Column> columns = ImmutableList.of(Column.of(Measures.PRESENT_VALUE)); MarketData knownMarketData = MarketData.of(date(2011, 3, 8), parRateData); // using the direct executor means there is no need to close/shutdown the runner CalculationTasks tasks = CalculationTasks.of(calculationRules, trades, columns, REF_DATA); MarketDataRequirements reqs = tasks.requirements(REF_DATA); MarketData enhancedMarketData = marketDataFactory().create(reqs, marketDataConfig, knownMarketData, REF_DATA); CalculationTaskRunner runner = CalculationTaskRunner.of(MoreExecutors.newDirectExecutorService()); Results results = runner.calculate(tasks, enhancedMarketData, REF_DATA); results.Cells.ForEach(this.checkPvIsZero); }
public virtual void test_withName() { RatesCurveGroupDefinition test = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addDiscountCurve(CURVE_DEFN1, GBP).build(); RatesCurveGroupDefinition expected = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("NewName")).addDiscountCurve(CURVE_DEFN1, GBP).build(); RatesCurveGroupDefinition withNewName = test.withName(CurveGroupName.of("NewName")); assertEquals(withNewName, expected); }
public virtual void test_ofCurves_duplicateCurveName() { RatesCurveGroupDefinition definition = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("group")).addForwardCurve(IBOR_NAME, USD_LIBOR_1M, USD_LIBOR_2M).build(); RatesCurveGroup group = RatesCurveGroup.ofCurves(definition, IBOR_CURVE, IBOR_CURVE); assertThat(group.findForwardCurve(USD_LIBOR_1M)).hasValue(IBOR_CURVE); assertThat(group.findForwardCurve(USD_LIBOR_2M)).hasValue(IBOR_CURVE); }
//------------------------------------------------------------------------- /// <summary> /// Calibrates synthetic curves from the configuration of the new curves and an existing rates provider. /// </summary> /// <param name="group"> the curve group definition for the synthetic curves and instruments </param> /// <param name="inputProvider"> the input rates provider </param> /// <param name="refData"> the reference data, used to resolve the trades </param> /// <returns> the rates provider </returns> public ImmutableRatesProvider calibrate(RatesCurveGroupDefinition group, RatesProvider inputProvider, ReferenceData refData) { // Computes the synthetic market quotes MarketData marketQuotesSy = marketData(group, inputProvider, refData); // Calibrate to the synthetic instrument with the synthetic quotes return(calibrator.calibrate(group, marketQuotesSy, refData)); }
public virtual void test_combinedWith_differentCurveNames() { RatesCurveGroupDefinition base1 = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addCurve(CURVE_DEFN1, GBP, GBP_LIBOR_1M, GBP_LIBOR_3M).addForwardCurve(CURVE_DEFN_I, GB_RPI).build(); RatesCurveGroupDefinition base2 = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("TestX")).addForwardCurve(CURVE_DEFN2, GBP_LIBOR_6M).build(); RatesCurveGroupDefinition expected = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addCurve(CURVE_DEFN1, GBP, GBP_LIBOR_1M, GBP_LIBOR_3M).addForwardCurve(CURVE_DEFN_I, GB_RPI).addForwardCurve(CURVE_DEFN2, GBP_LIBOR_6M).build(); assertEquals(base1.combinedWith(base2), expected); }
//------------------------------------------------------------------------- /// <summary> /// Calibrates a single curve group, containing one or more curves. /// <para> /// The calibration is defined using <seealso cref="RatesCurveGroupDefinition"/>. /// Observable market data, time-series and FX are also needed to complete the calibration. /// The valuation date is defined by the market data. /// </para> /// <para> /// The Jacobian matrices are computed and stored in curve metadata. /// /// </para> /// </summary> /// <param name="curveGroupDefn"> the curve group definition </param> /// <param name="marketData"> the market data required to build a trade for the instrument, including time-series </param> /// <param name="refData"> the reference data, used to resolve the trades </param> /// <returns> the rates provider resulting from the calibration </returns> public ImmutableRatesProvider calibrate(RatesCurveGroupDefinition curveGroupDefn, MarketData marketData, ReferenceData refData) { //JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter: IDictionary <Index, LocalDateDoubleTimeSeries> timeSeries = marketData.TimeSeriesIds.Where(typeof(IndexQuoteId).isInstance).Select(typeof(IndexQuoteId).cast).collect(toImmutableMap(id => id.Index, id => marketData.getTimeSeries(id))); ImmutableRatesProvider knownData = ImmutableRatesProvider.builder(marketData.ValuationDate).fxRateProvider(MarketDataFxRateProvider.of(marketData)).timeSeries(timeSeries).build(); return(calibrate(ImmutableList.of(curveGroupDefn), knownData, marketData, refData)); }
//------------------------------------------------------------------------- public virtual void test_metadata() { RatesCurveGroupDefinition test = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addCurve(CURVE_DEFN1, GBP, GBP_LIBOR_1M, GBP_LIBOR_3M).build(); LocalDate valuationDate = date(2015, 6, 30); CurveMetadata meta = CURVE_DEFN1.metadata(valuationDate, REF_DATA); assertEquals(test.metadata(valuationDate, REF_DATA), ImmutableList.of(meta)); }
//------------------------------------------------------------------------- public virtual void coverage() { RatesCurveGroupDefinition test = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addDiscountCurve(CURVE_DEFN1, GBP).build(); coverImmutableBean(test); RatesCurveGroupDefinition test2 = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test2")).addForwardCurve(CURVE_DEFN2, GBP_LIBOR_1M).build(); coverBeanEquals(test, test2); }
/// <summary> /// Test that requirements are empty if the curve group config exists but not the curve /// </summary> public virtual void requirementsMissingCurveDefinition() { RatesCurveInputsMarketDataFunction marketDataFunction = new RatesCurveInputsMarketDataFunction(); RatesCurveInputsId curveInputsId = RatesCurveInputsId.of(CurveGroupName.of("curve group"), CurveName.of("curve"), ObservableSource.NONE); RatesCurveGroupDefinition groupDefn = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("curve group")).build(); MarketDataConfig marketDataConfig = MarketDataConfig.builder().add(groupDefn.Name, groupDefn).build(); MarketDataRequirements requirements = marketDataFunction.requirements(curveInputsId, marketDataConfig); assertThat(requirements.Observables).Empty; }
/// <summary> /// Test that a failure is returned if there is config for the curve group but it doesn't contain the named curve. /// </summary> public virtual void buildMissingCurveDefinition() { RatesCurveInputsMarketDataFunction marketDataFunction = new RatesCurveInputsMarketDataFunction(); RatesCurveInputsId curveInputsId = RatesCurveInputsId.of(CurveGroupName.of("curve group"), CurveName.of("curve"), ObservableSource.NONE); RatesCurveGroupDefinition groupDefn = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("curve group")).build(); MarketDataConfig marketDataConfig = MarketDataConfig.builder().add(groupDefn.Name, groupDefn).build(); ScenarioMarketData emptyData = ScenarioMarketData.empty(); assertThrows(() => marketDataFunction.build(curveInputsId, marketDataConfig, emptyData, REF_DATA), typeof(System.ArgumentException), "No curve named .*"); }
public virtual void test_builder3() { RatesCurveGroupDefinition test = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addDiscountCurve(CURVE_NAME1, GBP).addForwardCurve(CURVE_NAME1, GBP_SONIA).addForwardCurve(CURVE_NAME1, GBP_LIBOR_1W).addForwardCurve(CURVE_NAME2, GBP_LIBOR_1M, GBP_LIBOR_3M).build(); assertEquals(test.Name, CurveGroupName.of("Test")); assertEquals(test.Entries, ImmutableList.of(ENTRY1, ENTRY2)); assertEquals(test.findEntry(CurveName.of("Test")), ENTRY1); assertEquals(test.findEntry(CurveName.of("Test2")), ENTRY2); assertEquals(test.findEntry(CurveName.of("Rubbish")), null); }
public virtual void test_builder4() { RatesCurveGroupDefinition test = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addCurve(CURVE_NAME1, GBP, GBP_LIBOR_1M, GBP_LIBOR_3M).build(); assertEquals(test.Name, CurveGroupName.of("Test")); assertEquals(test.Entries, ImmutableList.of(ENTRY3)); assertEquals(test.findEntry(CurveName.of("Test")), ENTRY3); assertEquals(test.findEntry(CurveName.of("Test2")), null); assertEquals(test.findEntry(CurveName.of("Rubbish")), null); }
public virtual void test_ofCurves() { RatesCurveGroupDefinition definition = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("group")).addCurve(DISCOUNT_NAME, GBP, GBP_LIBOR_1M).addForwardCurve(IBOR_NAME, USD_LIBOR_1M, USD_LIBOR_2M).addForwardCurve(OVERNIGHT_NAME, EUR_EONIA).build(); RatesCurveGroup group = RatesCurveGroup.ofCurves(definition, DISCOUNT_CURVE, OVERNIGHT_CURVE, IBOR_CURVE); assertThat(group.findDiscountCurve(GBP)).hasValue(DISCOUNT_CURVE); assertThat(group.findForwardCurve(USD_LIBOR_1M)).hasValue(IBOR_CURVE); assertThat(group.findForwardCurve(USD_LIBOR_2M)).hasValue(IBOR_CURVE); assertThat(group.findForwardCurve(EUR_EONIA)).hasValue(OVERNIGHT_CURVE); }
//------------------------------------------------------------------------- public virtual void test_loadCurveGroupDefinition() { IList <RatesCurveGroupDefinition> defns = RatesCurveGroupDefinitionCsvLoader.loadCurveGroupDefinitions(ResourceLocator.of(GROUPS_1)); assertEquals(defns.Count, 1); RatesCurveGroupDefinition defn = defns[0]; assertEquals(defn.Entries.get(0), RatesCurveGroupEntry.builder().curveName(CurveName.of("USD-Disc")).discountCurrencies(USD).build()); assertEquals(defn.Entries.get(1), RatesCurveGroupEntry.builder().curveName(CurveName.of("USD-3ML")).indices(USD_LIBOR_3M).build()); }
// calibrates when there is a single group private MarketDataBox <RatesCurveGroup> buildSingleCurveGroup(RatesCurveGroupDefinition configuredGroup, RatesCurveCalibrator calibrator, LocalDate valuationDate, IList <MarketDataBox <RatesCurveInputs> > inputBoxes, IDictionary <ObservableId, LocalDateDoubleTimeSeries> fixings, ReferenceData refData) { RatesCurveGroupDefinition filteredGroup = configuredGroup.filtered(valuationDate, refData); //JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter: //JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter: IList <RatesCurveInputs> inputs = inputBoxes.Select(MarketDataBox::getSingleValue).collect(toImmutableList()); MarketData inputValues = inputsByKey(valuationDate, inputs, fixings); RatesCurveGroup curveGroup = buildGroup(filteredGroup, calibrator, inputValues, refData); return(MarketDataBox.ofSingleValue(curveGroup)); }
//------------------------------------------------------------------------- public virtual MarketDataRequirements requirements(RatesCurveGroupId id, MarketDataConfig marketDataConfig) { RatesCurveGroupDefinition groupDefn = marketDataConfig.get(typeof(RatesCurveGroupDefinition), id.CurveGroupName); // request input data for any curves that need market data // no input data is requested if the curve definition contains all the market data needed to build the curve //JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter: IList <RatesCurveInputsId> curveInputsIds = groupDefn.CurveDefinitions.Where(defn => requiresMarketData(defn)).Select(defn => defn.Name).Select(curveName => RatesCurveInputsId.of(groupDefn.Name, curveName, id.ObservableSource)).collect(toImmutableList()); IList <ObservableId> timeSeriesIds = groupDefn.Entries.stream().flatMap(entry => entry.Indices.stream()).distinct().map(index => IndexQuoteId.of(index)).collect(toImmutableList()); return(MarketDataRequirements.builder().addValues(curveInputsIds).addTimeSeries(timeSeriesIds).build()); }
public virtual MarketDataBox <RatesCurveGroup> build(RatesCurveGroupId id, MarketDataConfig marketDataConfig, ScenarioMarketData marketData, ReferenceData refData) { // create the calibrator, using the configured RootFinderConfig if found RootFinderConfig rfc = marketDataConfig.find(typeof(RootFinderConfig)).orElse(RootFinderConfig.standard()); RatesCurveCalibrator calibrator = RatesCurveCalibrator.of(rfc.AbsoluteTolerance, rfc.RelativeTolerance, rfc.MaximumSteps, calibrationMeasures); // calibrate CurveGroupName groupName = id.CurveGroupName; RatesCurveGroupDefinition configuredDefn = marketDataConfig.get(typeof(RatesCurveGroupDefinition), groupName); return(buildCurveGroup(configuredDefn, calibrator, marketData, refData, id.ObservableSource)); }
// Check synthetic calibration in case no definitions public virtual void calibrate_noDefinitions() { RatesCurveGroupDefinition empty = RatesCurveGroupDefinition.of(CurveGroupName.of("Group"), ImmutableList.of(), ImmutableList.of()); MarketData mad = CALIBRATOR_SYNTHETIC.marketData(empty, MULTICURVE_INPUT_EUR_TSLARGE, REF_DATA); RatesProvider multicurveSyn = CALIBRATOR_SYNTHETIC.calibrate(empty, MULTICURVE_INPUT_EUR_TSLARGE, REF_DATA); assertEquals(multicurveSyn.DiscountCurrencies, ImmutableSet.of()); assertEquals(multicurveSyn.IborIndices, ImmutableSet.of()); assertEquals(multicurveSyn.OvernightIndices, ImmutableSet.of()); assertEquals(multicurveSyn.PriceIndices, ImmutableSet.of()); assertEquals(mad.TimeSeriesIds, ImmutableSet.of()); }
//------------------------------------------------------------------------- public virtual void test_tradesInitialGuesses() { RatesCurveGroupDefinition test = RatesCurveGroupDefinition.builder().name(CurveGroupName.of("Test")).addCurve(CURVE_DEFN1, GBP, GBP_LIBOR_1M, GBP_LIBOR_3M).build(); MarketData marketData = ImmutableMarketData.of(date(2015, 6, 30), ImmutableMap.of(GBP_LIBOR_1M_ID, 0.5d, GBP_LIBOR_3M_ID, 1.5d)); Trade trade1 = NODE1.trade(1d, marketData, REF_DATA); Trade trade2 = NODE2.trade(1d, marketData, REF_DATA); assertEquals(test.TotalParameterCount, 2); assertEquals(test.resolvedTrades(marketData, REF_DATA), ImmutableList.of(trade1, trade2)); assertEquals(test.initialGuesses(marketData), ImmutableList.of(0.5d, 1.5d)); }
public MarketDataRequirements requirements(RatesCurveInputsId id, MarketDataConfig marketDataConfig) { RatesCurveGroupDefinition groupConfig = marketDataConfig.get(typeof(RatesCurveGroupDefinition), id.CurveGroupName); Optional <CurveDefinition> optionalDefinition = groupConfig.findCurveDefinition(id.CurveName); if (!optionalDefinition.Present) { return(MarketDataRequirements.empty()); } CurveDefinition definition = optionalDefinition.get(); return(MarketDataRequirements.builder().addValues(nodeRequirements(ImmutableList.of(definition))).build()); }
/// <summary> /// Calibrates a list of curve groups, each containing one or more curves. /// <para> /// The calibration is defined using a list of <seealso cref="RatesCurveGroupDefinition"/>. /// Observable market data and existing known data are also needed to complete the calibration. /// </para> /// <para> /// A curve must only exist in one group. /// /// </para> /// </summary> /// <param name="allGroupsDefn"> the curve group definitions </param> /// <param name="knownData"> the starting data for the calibration </param> /// <param name="marketData"> the market data required to build a trade for the instrument </param> /// <param name="refData"> the reference data, used to resolve the trades </param> /// <returns> the rates provider resulting from the calibration </returns> public ImmutableRatesProvider calibrate(IList <RatesCurveGroupDefinition> allGroupsDefn, ImmutableRatesProvider knownData, MarketData marketData, ReferenceData refData) { // this method effectively takes one CurveGroupDefinition // the list is a split of the definition, not multiple independent definitions if (!knownData.ValuationDate.Equals(marketData.ValuationDate)) { throw new System.ArgumentException(Messages.format("Valuation dates do not match: {} and {}", knownData.ValuationDate, marketData.ValuationDate)); } // perform calibration one group at a time, building up the result by mutating these variables ImmutableRatesProvider providerCombined = knownData; ImmutableList <CurveParameterSize> orderPrev = ImmutableList.of(); ImmutableMap <CurveName, JacobianCalibrationMatrix> jacobians = ImmutableMap.of(); foreach (RatesCurveGroupDefinition groupDefn in allGroupsDefn) { if (groupDefn.Entries.Empty) { continue; } RatesCurveGroupDefinition groupDefnBound = groupDefn.bindTimeSeries(knownData.ValuationDate, knownData.TimeSeries); // combine all data in the group into flat lists ImmutableList <ResolvedTrade> trades = groupDefnBound.resolvedTrades(marketData, refData); ImmutableList <double> initialGuesses = groupDefnBound.initialGuesses(marketData); ImmutableList <CurveParameterSize> orderGroup = toOrder(groupDefnBound); ImmutableList <CurveParameterSize> orderPrevAndGroup = ImmutableList.builder <CurveParameterSize>().addAll(orderPrev).addAll(orderGroup).build(); // calibrate RatesProviderGenerator providerGenerator = ImmutableRatesProviderGenerator.of(providerCombined, groupDefnBound, refData); DoubleArray calibratedGroupParams = calibrateGroup(providerGenerator, trades, initialGuesses, orderGroup); ImmutableRatesProvider calibratedProvider = providerGenerator.generate(calibratedGroupParams); // use calibration to build Jacobian matrices if (groupDefnBound.ComputeJacobian) { jacobians = updateJacobiansForGroup(calibratedProvider, trades, orderGroup, orderPrev, orderPrevAndGroup, jacobians); } ImmutableMap <CurveName, DoubleArray> sensitivityToMarketQuote = ImmutableMap.of(); if (groupDefnBound.ComputePvSensitivityToMarketQuote) { ImmutableRatesProvider providerWithJacobian = providerGenerator.generate(calibratedGroupParams, jacobians); sensitivityToMarketQuote = sensitivityToMarketQuoteForGroup(providerWithJacobian, trades, orderGroup); } orderPrev = orderPrevAndGroup; // use Jacobians to build output curves providerCombined = providerGenerator.generate(calibratedGroupParams, jacobians, sensitivityToMarketQuote); } // return the calibrated provider return(providerCombined); }
// obtains the data and calculates the grid of results private static void calculate(CalculationRunner runner) { // the trades that will have measures calculated IList <Trade> trades = createSwapTrades(); // the columns, specifying the measures to be calculated IList <Column> columns = ImmutableList.of(Column.of(Measures.PRESENT_VALUE), Column.of(Measures.PAR_RATE), Column.of(Measures.PV01_MARKET_QUOTE_BUCKETED), Column.of(Measures.PV01_CALIBRATED_BUCKETED)); // load quotes ImmutableMap <QuoteId, double> quotesCcp1 = QuotesCsvLoader.load(VAL_DATE, QUOTES_RESOURCE_CCP1); ImmutableMap <QuoteId, double> quotesCcp2 = QuotesCsvLoader.load(VAL_DATE, QUOTES_RESOURCE_CCP2); // load fixings ImmutableMap <ObservableId, LocalDateDoubleTimeSeries> fixings = FixingSeriesCsvLoader.load(FIXINGS_RESOURCE); // create the market data MarketData marketData = ImmutableMarketData.builder(VAL_DATE).addValueMap(quotesCcp1).addValueMap(quotesCcp2).addTimeSeriesMap(fixings).build(); // the reference data, such as holidays and securities ReferenceData refData = ReferenceData.standard(); // load the curve definition IDictionary <CurveGroupName, RatesCurveGroupDefinition> defnsCcp1 = RatesCalibrationCsvLoader.load(GROUPS_RESOURCE_CCP1, SETTINGS_RESOURCE_CCP1, CALIBRATION_RESOURCE_CCP1); IDictionary <CurveGroupName, RatesCurveGroupDefinition> defnsCcp2 = RatesCalibrationCsvLoader.load(GROUPS_RESOURCE_CCP2, SETTINGS_RESOURCE_CCP2, CALIBRATION_RESOURCE_CCP2); RatesCurveGroupDefinition curveGroupDefinitionCcp1 = defnsCcp1[CURVE_GROUP_NAME_CCP1].filtered(VAL_DATE, refData); RatesCurveGroupDefinition curveGroupDefinitionCcp2 = defnsCcp2[CURVE_GROUP_NAME_CCP2].filtered(VAL_DATE, refData); // the configuration that defines how to create the curves when a curve group is requested MarketDataConfig marketDataConfig = MarketDataConfig.builder().add(CURVE_GROUP_NAME_CCP1, curveGroupDefinitionCcp1).add(CURVE_GROUP_NAME_CCP2, curveGroupDefinitionCcp2).build(); // the complete set of rules for calculating measures CalculationFunctions functions = StandardComponents.calculationFunctions(); RatesMarketDataLookup ratesLookupCcp1 = RatesMarketDataLookup.of(curveGroupDefinitionCcp1); RatesMarketDataLookup ratesLookupCcp2 = RatesMarketDataLookup.of(curveGroupDefinitionCcp2); // choose RatesMarketDataLookup instance based on counterparty TradeCounterpartyCalculationParameter perCounterparty = TradeCounterpartyCalculationParameter.of(ImmutableMap.of(CCP1_ID, ratesLookupCcp1, CCP2_ID, ratesLookupCcp2), ratesLookupCcp1); CalculationRules rules = CalculationRules.of(functions, perCounterparty); // calibrate the curves and calculate the results MarketDataRequirements reqs = MarketDataRequirements.of(rules, trades, columns, refData); MarketData calibratedMarketData = marketDataFactory().create(reqs, marketDataConfig, marketData, refData); Results results = runner.calculate(rules, trades, columns, calibratedMarketData, refData); // use the report runner to transform the engine results into a trade report ReportCalculationResults calculationResults = ReportCalculationResults.of(VAL_DATE, trades, columns, results, functions, refData); TradeReportTemplate reportTemplate = ExampleData.loadTradeReportTemplate("swap-report-template2"); TradeReport tradeReport = TradeReport.of(calculationResults, reportTemplate); tradeReport.writeAsciiTable(System.out); }