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)); }
/// <summary> /// Start from a generic zero-coupon curve. Compute the (inverse) Jacobian matrix using linear projection to a small /// number of points and the Jacobian utility. Compare the direct Jacobian obtained by calibrating a curve /// based on the trades with market quotes computed from the zero-coupon curve. /// </summary> public virtual void with_rebucketing_one_curve() { /* Create trades */ IList <ResolvedTrade> trades = new List <ResolvedTrade>(); IList <LocalDate> nodeDates = new List <LocalDate>(); double[] marketQuotes = new double[TENORS_STD_1.Length]; for (int looptenor = 0; looptenor < TENORS_STD_1.Length; looptenor++) { ResolvedSwapTrade t0 = EUR_FIXED_1Y_EURIBOR_6M.createTrade(VALUATION_DATE, TENORS_STD_1[looptenor], BuySell.BUY, 1.0, 0.0, REF_DATA).resolve(REF_DATA); marketQuotes[looptenor] = MARKET_QUOTE.value(t0, MULTICURVE_EUR_SINGLE_INPUT); ResolvedSwapTrade t = EUR_FIXED_1Y_EURIBOR_6M.createTrade(VALUATION_DATE, TENORS_STD_1[looptenor], BuySell.BUY, 1.0, marketQuotes[looptenor], REF_DATA).resolve(REF_DATA); nodeDates.Add(t.Product.EndDate); trades.Add(t); } System.Func <ResolvedTrade, CurrencyParameterSensitivities> sensitivityFunction = (t) => CurveSensitivityUtils.linearRebucketing(MULTICURVE_EUR_SINGLE_INPUT.parameterSensitivity(PRICER_SWAP_PRODUCT.parRateSensitivity(((ResolvedSwapTrade)t).Product, MULTICURVE_EUR_SINGLE_INPUT).build()), nodeDates, VALUATION_DATE); /* Market quotes for comparison */ IDictionary <QuoteId, double> mqCmp = new Dictionary <QuoteId, double>(); for (int looptenor = 0; looptenor < TENORS_STD_1.Length; looptenor++) { mqCmp[QuoteId.of(StandardId.of(OG_TICKER, TICKERS_STD_1[looptenor]))] = marketQuotes[looptenor]; } ImmutableMarketData marketQuotesObject = ImmutableMarketData.of(VALUATION_DATE, mqCmp); RatesProvider multicurveCmp = CALIBRATOR.calibrate(GROUPS_IN_1, marketQuotesObject, REF_DATA); /* Comparison */ DoubleMatrix jiComputed = CurveSensitivityUtils.jacobianFromMarketQuoteSensitivities(LIST_CURVE_NAMES_1, trades, sensitivityFunction); DoubleMatrix jiExpected = multicurveCmp.findData(EUR_SINGLE_NAME).get().Metadata.findInfo(CurveInfoType.JACOBIAN).get().JacobianMatrix; assertEquals(jiComputed.rowCount(), jiExpected.rowCount()); assertEquals(jiComputed.columnCount(), jiExpected.columnCount()); for (int i = 0; i < jiComputed.rowCount(); i++) { for (int j = 0; j < jiComputed.columnCount(); j++) { assertEquals(jiComputed.get(i, j), jiExpected.get(i, j), TOLERANCE_JAC_APPROX); // The comparison is not perfect due to the incoherences introduced by the re-bucketing } } }
private static Pair <MultiCurrencyAmount[], CurrencyParameterSensitivities[]> computation(IDictionary <CurveGroupName, RatesCurveGroupDefinition> configs, ResolvedSwapTrade[] swaps) { int nbSwaps = swaps.Length; /* Calibrate curves */ ImmutableRatesProvider multicurve = CALIBRATOR.calibrate(configs[CONFIG_NAME], MARKET_QUOTES, REF_DATA); /* Computes PV and bucketed PV01 */ MultiCurrencyAmount[] pv = new MultiCurrencyAmount[nbSwaps]; CurrencyParameterSensitivities[] mqs = new CurrencyParameterSensitivities[nbSwaps]; for (int loopswap = 0; loopswap < nbSwaps; loopswap++) { pv[loopswap] = PRICER_SWAP.presentValue(swaps[loopswap], multicurve); PointSensitivities pts = PRICER_SWAP.presentValueSensitivity(swaps[loopswap], multicurve); CurrencyParameterSensitivities ps = multicurve.parameterSensitivity(pts); mqs[loopswap] = MQC.sensitivity(ps, multicurve); } return(Pair.of(pv, mqs)); }
private const double BP1 = 1.0E-4; // Scaling by 1 bp. public static void Main(string[] arg) { /* Load the curve configurations from csv files */ IList <IDictionary <CurveGroupName, RatesCurveGroupDefinition> > configs = new List <IDictionary <CurveGroupName, RatesCurveGroupDefinition> >(); for (int loopconfig = 0; loopconfig < NB_SETTINGS; loopconfig++) { configs.Add(RatesCalibrationCsvLoader.load(GROUP_RESOURCE, SETTINGS_RESOURCE[loopconfig], NODES_RESOURCE)); } /* Construct a swap */ ResolvedSwapTrade swap = GBP_FIXED_6M_LIBOR_6M.createTrade(VALUATION_DATE, SWAP_PERIOD_TO_START, Tenor.of(SWAP_TENOR), BuySell.BUY, SWAP_NOTIONAL, SWAP_COUPON, REF_DATA).resolve(REF_DATA); /* Calibrate curves */ ImmutableRatesProvider[] multicurve = new ImmutableRatesProvider[3]; for (int loopconfig = 0; loopconfig < NB_SETTINGS; loopconfig++) { multicurve[loopconfig] = CALIBRATOR.calibrate(configs[loopconfig][CONFIG_NAME], MARKET_QUOTES, REF_DATA); } /* Computes PV and bucketed PV01 */ MultiCurrencyAmount[] pv = new MultiCurrencyAmount[NB_SETTINGS]; CurrencyParameterSensitivities[] mqs = new CurrencyParameterSensitivities[NB_SETTINGS]; for (int loopconfig = 0; loopconfig < NB_SETTINGS; loopconfig++) { pv[loopconfig] = PRICER_SWAP.presentValue(swap, multicurve[loopconfig]); PointSensitivities pts = PRICER_SWAP.presentValueSensitivity(swap, multicurve[loopconfig]); CurrencyParameterSensitivities ps = multicurve[loopconfig].parameterSensitivity(pts); mqs[loopconfig] = MQC.sensitivity(ps, multicurve[loopconfig]); } /* Export to csv files. */ for (int loopconfig = 0; loopconfig < NB_SETTINGS; loopconfig++) { ExportUtils.export(mqs[loopconfig], BP1, PATH_RESULTS + CONFIG_STR + SETTINGS_SUFFIX[loopconfig] + "-mqs" + SUFFIX_CSV); ExportUtils.export(pv[loopconfig], PATH_RESULTS + CONFIG_STR + SETTINGS_SUFFIX[loopconfig] + "-pv" + SUFFIX_CSV); } Console.WriteLine("Calibration and export finished: " + CONFIG_STR); }
private const double BP1 = 1.0E-4; // Scaling by 1 bp. public static void Main(string[] arg) { /* Load the curve configurations from csv files */ IDictionary <CurveGroupName, RatesCurveGroupDefinition> configs = RatesCalibrationCsvLoader.load(GROUP_RESOURCE, SETTINGS_RESOURCE, NODES_RESOURCE); /* Calibrate curves */ ImmutableRatesProvider multicurve = CALIBRATOR.calibrate(configs[CONFIG_NAME], MARKET_QUOTES, REF_DATA); /* Construct a swap */ ResolvedSwapTrade swap = GBP_FIXED_6M_LIBOR_6M.createTrade(VALUATION_DATE, SWAP_PERIOD_TO_START, Tenor.of(SWAP_TENOR), BuySell.BUY, SWAP_NOTIONAL, SWAP_COUPON, REF_DATA).resolve(REF_DATA); /* Computes PV and bucketed PV01 */ MultiCurrencyAmount pv = PRICER_SWAP.presentValue(swap, multicurve); PointSensitivities pts = PRICER_SWAP.presentValueSensitivity(swap, multicurve); CurrencyParameterSensitivities ps = multicurve.parameterSensitivity(pts); CurrencyParameterSensitivities mqs = MQC.sensitivity(ps, multicurve); /* Export to csv files. */ ExportUtils.export(mqs, BP1, PATH_RESULTS + CONFIG_STR + "-delta" + SUFFIX_CSV); ExportUtils.export(pv, PATH_RESULTS + CONFIG_STR + "-pv" + SUFFIX_CSV); Console.WriteLine("Calibration and export finished: " + CONFIG_STR); }
//------------------------------------------------------------------------- /// <summary> /// Runs the calibration of SABR on swaptions and print on the console the present value, bucketed PV01 and /// the bucketed Vega of a 18M x 4Y swaption. /// </summary> /// <param name="args"> -s to use the spares data </param> public static void Main(string[] args) { long start, end; // Swaption description BuySell payer = BuySell.BUY; Period expiry = Period.ofMonths(18); double notional = 1_000_000; double strike = 0.0100; Tenor tenor = Tenor.TENOR_4Y; LocalDate expiryDate = EUR_FIXED_1Y_EURIBOR_6M.FloatingLeg.StartDateBusinessDayAdjustment.adjust(CALIBRATION_DATE.plus(expiry), REF_DATA); SwapTrade underlying = EUR_FIXED_1Y_EURIBOR_6M.createTrade(expiryDate, tenor, payer, notional, strike, REF_DATA); Swaption swaption = Swaption.builder().expiryDate(AdjustableDate.of(expiryDate)).expiryTime(LocalTime.of(11, 0x0)).expiryZone(ZoneId.of("Europe/Berlin")).underlying(underlying.Product).longShort(LongShort.LONG).swaptionSettlement(PhysicalSwaptionSettlement.DEFAULT).build(); ResolvedSwaption resolvedSwaption = swaption.resolve(REF_DATA); // select data TenorRawOptionData data = DATA_FULL; if (args.Length > 0) { if (args[0].Equals("-s")) { data = DATA_SPARSE; } } start = DateTimeHelper.CurrentUnixTimeMillis(); // Curve calibration RatesProvider multicurve = CALIBRATOR.calibrate(CONFIGS, MARKET_QUOTES, REF_DATA); end = DateTimeHelper.CurrentUnixTimeMillis(); Console.WriteLine("Curve calibration time: " + (end - start) + " ms."); // SABR calibration start = DateTimeHelper.CurrentUnixTimeMillis(); double beta = 0.50; SurfaceMetadata betaMetadata = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).zValueType(ValueType.SABR_BETA).surfaceName("Beta").build(); Surface betaSurface = ConstantSurface.of(betaMetadata, beta); double shift = 0.0300; Surface shiftSurface = ConstantSurface.of("SABR-Shift", shift); SabrParametersSwaptionVolatilities sabr = SABR_CALIBRATION.calibrateWithFixedBetaAndShift(DEFINITION, CALIBRATION_TIME, data, multicurve, betaSurface, shiftSurface); end = DateTimeHelper.CurrentUnixTimeMillis(); Console.WriteLine("SABR calibration time: " + (end - start) + " ms."); // Price and risk Console.WriteLine("Risk measures: "); start = DateTimeHelper.CurrentUnixTimeMillis(); CurrencyAmount pv = SWAPTION_PRICER.presentValue(resolvedSwaption, multicurve, sabr); Console.WriteLine(" |-> PV: " + pv.ToString()); PointSensitivities deltaPts = SWAPTION_PRICER.presentValueSensitivityRatesStickyModel(resolvedSwaption, multicurve, sabr).build(); CurrencyParameterSensitivities deltaBucketed = multicurve.parameterSensitivity(deltaPts); Console.WriteLine(" |-> Delta bucketed: " + deltaBucketed.ToString()); PointSensitivities vegaPts = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(resolvedSwaption, multicurve, sabr).build(); Console.WriteLine(" |-> Vega point: " + vegaPts.ToString()); CurrencyParameterSensitivities vegaBucketed = sabr.parameterSensitivity(vegaPts); for (int i = 0; i < vegaBucketed.size(); i++) { Console.WriteLine(" |-> Vega bucketed: " + vegaBucketed.Sensitivities.get(i)); } end = DateTimeHelper.CurrentUnixTimeMillis(); Console.WriteLine("PV and risk time: " + (end - start) + " ms."); }