IBORCurve.java

  1. package org.drip.sample.forward;

  2. import java.util.List;

  3. import org.drip.analytics.date.JulianDate;
  4. import org.drip.analytics.support.*;
  5. import org.drip.market.otc.*;
  6. import org.drip.numerical.common.FormatUtil;
  7. import org.drip.param.creator.*;
  8. import org.drip.param.market.CurveSurfaceQuoteContainer;
  9. import org.drip.param.period.*;
  10. import org.drip.param.valuation.*;
  11. import org.drip.product.creator.SingleStreamComponentBuilder;
  12. import org.drip.product.fra.FRAStandardComponent;
  13. import org.drip.product.fx.ComponentPair;
  14. import org.drip.product.rates.*;
  15. import org.drip.spline.params.*;
  16. import org.drip.spline.stretch.*;
  17. import org.drip.state.creator.ScenarioForwardCurveBuilder;
  18. import org.drip.state.discount.*;
  19. import org.drip.state.estimator.LatentStateStretchBuilder;
  20. import org.drip.state.forward.ForwardCurve;
  21. import org.drip.state.identifier.ForwardLabel;
  22. import org.drip.state.inference.*;

  23. /*
  24.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  25.  */

  26. /*!
  27.  * Copyright (C) 2019 Lakshmi Krishnamurthy
  28.  * Copyright (C) 2018 Lakshmi Krishnamurthy
  29.  * Copyright (C) 2017 Lakshmi Krishnamurthy
  30.  * Copyright (C) 2016 Lakshmi Krishnamurthy
  31.  * Copyright (C) 2015 Lakshmi Krishnamurthy
  32.  * Copyright (C) 2014 Lakshmi Krishnamurthy
  33.  *
  34.  *  This file is part of DROP, an open-source library targeting risk, transaction costs, exposure, margin
  35.  *      calculations, valuation adjustment, and portfolio construction within and across fixed income,
  36.  *      credit, commodity, equity, FX, and structured products.
  37.  *  
  38.  *      https://lakshmidrip.github.io/DROP/
  39.  *  
  40.  *  DROP is composed of three modules:
  41.  *  
  42.  *  - DROP Analytics Core - https://lakshmidrip.github.io/DROP-Analytics-Core/
  43.  *  - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
  44.  *  - DROP Numerical Core - https://lakshmidrip.github.io/DROP-Numerical-Core/
  45.  *
  46.  *  DROP Analytics Core implements libraries for the following:
  47.  *  - Fixed Income Analytics
  48.  *  - Asset Backed Analytics
  49.  *  - XVA Analytics
  50.  *  - Exposure and Margin Analytics
  51.  *
  52.  *  DROP Portfolio Core implements libraries for the following:
  53.  *  - Asset Allocation Analytics
  54.  *  - Transaction Cost Analytics
  55.  *
  56.  *  DROP Numerical Core implements libraries for the following:
  57.  *  - Statistical Learning
  58.  *  - Numerical Optimizer
  59.  *  - Spline Builder
  60.  *  - Algorithm Support
  61.  *
  62.  *  Documentation for DROP is Spread Over:
  63.  *
  64.  *  - Main                     => https://lakshmidrip.github.io/DROP/
  65.  *  - Wiki                     => https://github.com/lakshmiDRIP/DROP/wiki
  66.  *  - GitHub                   => https://github.com/lakshmiDRIP/DROP
  67.  *  - Repo Layout Taxonomy     => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
  68.  *  - Javadoc                  => https://lakshmidrip.github.io/DROP/Javadoc/index.html
  69.  *  - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
  70.  *  - Release Versions         => https://lakshmidrip.github.io/DROP/version.html
  71.  *  - Community Credits        => https://lakshmidrip.github.io/DROP/credits.html
  72.  *  - Issues Catalog           => https://github.com/lakshmiDRIP/DROP/issues
  73.  *  - JUnit                    => https://lakshmidrip.github.io/DROP/junit/index.html
  74.  *  - Jacoco                   => https://lakshmidrip.github.io/DROP/jacoco/index.html
  75.  *
  76.  *  Licensed under the Apache License, Version 2.0 (the "License");
  77.  *      you may not use this file except in compliance with the License.
  78.  *  
  79.  *  You may obtain a copy of the License at
  80.  *      http://www.apache.org/licenses/LICENSE-2.0
  81.  *  
  82.  *  Unless required by applicable law or agreed to in writing, software
  83.  *      distributed under the License is distributed on an "AS IS" BASIS,
  84.  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  85.  *  
  86.  *  See the License for the specific language governing permissions and
  87.  *      limitations under the License.
  88.  */

  89. /**
  90.  * <i>IBORCurve</i> illustrates the Construction and Usage of the IBOR Forward Curve.
  91.  *  
  92.  * <br><br>
  93.  *  <ul>
  94.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/AnalyticsCore.md">Analytics Core Module</a></li>
  95.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics Library</a></li>
  96.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">Sample</a></li>
  97.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/forward/README.md">Forward Rate Curve Construction</a></li>
  98.  *  </ul>
  99.  * <br><br>
  100.  *
  101.  * @author Lakshmi Krishnamurthy
  102.  */

  103. public class IBORCurve {

  104.     private static final FloatFloatComponent OTCFloatFloat (
  105.         final JulianDate dtSpot,
  106.         final String strCurrency,
  107.         final String strDerivedTenor,
  108.         final String strMaturityTenor,
  109.         final double dblBasis)
  110.     {
  111.         FloatFloatSwapConvention ffConv = IBORFloatFloatContainer.ConventionFromJurisdiction (strCurrency);

  112.         return ffConv.createFloatFloatComponent (
  113.             dtSpot,
  114.             strDerivedTenor,
  115.             strMaturityTenor,
  116.             dblBasis,
  117.             1.
  118.         );
  119.     }

  120.     private static final FixFloatComponent OTCIRS (
  121.         final JulianDate dtSpot,
  122.         final String strCurrency,
  123.         final String strLocation,
  124.         final String strMaturityTenor,
  125.         final String strIndex,
  126.         final double dblCoupon)
  127.     {
  128.         FixedFloatSwapConvention ffConv = IBORFixedFloatContainer.ConventionFromJurisdiction (
  129.             strCurrency,
  130.             strLocation,
  131.             strMaturityTenor,
  132.             strIndex
  133.         );

  134.         return ffConv.createFixFloatComponent (
  135.             dtSpot,
  136.             strMaturityTenor,
  137.             dblCoupon,
  138.             0.,
  139.             1.
  140.         );
  141.     }

  142.     private static final ComponentPair OTCComponentPair (
  143.         final JulianDate dtSpot,
  144.         final String strCurrency,
  145.         final String strDerivedTenor,
  146.         final String strMaturityTenor,
  147.         final double dblReferenceFixedCoupon,
  148.         final double dblDerivedFixedCoupon,
  149.         final double dblBasis)
  150.     {
  151.         FloatFloatSwapConvention ffConv = IBORFloatFloatContainer.ConventionFromJurisdiction (strCurrency);

  152.         return ffConv.createFixFloatComponentPair (
  153.             dtSpot,
  154.             strDerivedTenor,
  155.             strMaturityTenor,
  156.             dblReferenceFixedCoupon,
  157.             dblDerivedFixedCoupon,
  158.             dblBasis,
  159.             1.
  160.         );
  161.     }

  162.     /*
  163.      * Construct the Array of Deposit Instruments from the given set of parameters
  164.      *
  165.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  166.      */

  167.     private static final SingleStreamComponent[] DepositFromMaturityDays (
  168.         final JulianDate dtEffective,
  169.         final String[] astrMaturityTenor,
  170.         final ForwardLabel fri)
  171.         throws Exception
  172.     {
  173.         if (null == astrMaturityTenor || 0 == astrMaturityTenor.length) return null;

  174.         SingleStreamComponent[] aDeposit = new SingleStreamComponent[astrMaturityTenor.length];

  175.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  176.             aDeposit[i] = SingleStreamComponentBuilder.Deposit (
  177.                 dtEffective,
  178.                 dtEffective.addTenor (astrMaturityTenor[i]),
  179.                 fri
  180.             );

  181.         return aDeposit;
  182.     }

  183.     /*
  184.      * Construct the Array of FRA from the given set of parameters
  185.      *
  186.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  187.      */

  188.     private static final FRAStandardComponent[] FRAFromMaturityDays (
  189.         final JulianDate dtEffective,
  190.         final ForwardLabel fri,
  191.         final String[] astrMaturityTenor,
  192.         final double[] adblFRAStrike)
  193.         throws Exception
  194.     {
  195.         if (null == astrMaturityTenor || null == adblFRAStrike || 0 == astrMaturityTenor.length) return null;

  196.         FRAStandardComponent[] aFRA = new FRAStandardComponent[astrMaturityTenor.length];

  197.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  198.             aFRA[i] = SingleStreamComponentBuilder.FRAStandard (
  199.                 dtEffective.addTenor (astrMaturityTenor[i]),
  200.                 fri,
  201.                 adblFRAStrike[i]
  202.             );

  203.         return aFRA;
  204.     }

  205.     private static final FixFloatComponent[] FixFloatSwap2 (
  206.         final JulianDate dtEffective,
  207.         final ForwardLabel fri,
  208.         final String[] astrMaturityTenor)
  209.         throws Exception
  210.     {
  211.         if (null == astrMaturityTenor || 0 == astrMaturityTenor.length) return null;

  212.         FixFloatComponent[] aFixFloat = new FixFloatComponent[astrMaturityTenor.length];

  213.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  214.             aFixFloat[i] = OTCIRS (
  215.                 dtEffective,
  216.                 fri.currency(),
  217.                 "ALL",
  218.                 astrMaturityTenor[i],
  219.                 "MAIN",
  220.                 0.
  221.             );

  222.         return aFixFloat;
  223.     }

  224.     private static final FixFloatComponent[] FixFloatSwap (
  225.         final JulianDate dtValue,
  226.         final ForwardLabel fri,
  227.         final String[] astrMaturityTenor)
  228.         throws Exception
  229.     {
  230.         if (null == astrMaturityTenor || 0 == astrMaturityTenor.length) return null;

  231.         JulianDate dtEffective = dtValue.addDays (2);

  232.         String strCurrency = fri.currency();

  233.         FixFloatComponent[] aFFC = new FixFloatComponent[astrMaturityTenor.length];

  234.         int iTenorInMonths = Integer.parseInt (fri.tenor().split ("M")[0]);

  235.         UnitCouponAccrualSetting ucasFixed = new UnitCouponAccrualSetting (
  236.             1,
  237.             "Act/360",
  238.             false,
  239.             "Act/360",
  240.             false,
  241.             strCurrency,
  242.             true,
  243.             CompositePeriodBuilder.ACCRUAL_COMPOUNDING_RULE_GEOMETRIC
  244.         );

  245.         ComposableFloatingUnitSetting cfusFloating = new ComposableFloatingUnitSetting (
  246.             fri.tenor(),
  247.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  248.             null,
  249.             fri,
  250.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  251.             0.
  252.         );

  253.         CompositePeriodSetting cpsFloating = new CompositePeriodSetting (
  254.             12 / iTenorInMonths,
  255.             fri.tenor(),
  256.             strCurrency,
  257.             null,
  258.             -1.,
  259.             null,
  260.             null,
  261.             null,
  262.             null
  263.         );

  264.         CashSettleParams csp = new CashSettleParams (
  265.             0,
  266.             strCurrency,
  267.             0
  268.         );

  269.         for (int i = 0; i < astrMaturityTenor.length; ++i) {
  270.             int iTenorCompare = Helper.TenorCompare (
  271.                 astrMaturityTenor[i],
  272.                 "6M"
  273.             );

  274.             String strFixedTenor = Helper.LEFT_TENOR_LESSER == iTenorCompare ? astrMaturityTenor[i] : "6M";

  275.             ComposableFixedUnitSetting cfusFixed = new ComposableFixedUnitSetting (
  276.                 strFixedTenor,
  277.                 CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  278.                 null,
  279.                 0.,
  280.                 0.,
  281.                 strCurrency
  282.             );

  283.             CompositePeriodSetting cpsFixed = new CompositePeriodSetting (
  284.                 1,
  285.                 strFixedTenor,
  286.                 strCurrency,
  287.                 null,
  288.                 1.,
  289.                 null,
  290.                 null,
  291.                 null,
  292.                 null
  293.             );

  294.             List<Integer> lsFixedStreamEdgeDate = CompositePeriodBuilder.BackwardEdgeDates (
  295.                 dtEffective,
  296.                 dtEffective.addTenor (astrMaturityTenor[i]),
  297.                 "1Y",
  298.                 null,
  299.                 CompositePeriodBuilder.SHORT_STUB
  300.             );

  301.             List<Integer> lsFloatingStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  302.                 dtEffective,
  303.                 fri.tenor(),
  304.                 astrMaturityTenor[i],
  305.                 null
  306.             );

  307.             Stream floatingStream = new Stream (
  308.                 CompositePeriodBuilder.FloatingCompositeUnit (
  309.                     lsFloatingStreamEdgeDate,
  310.                     cpsFloating,
  311.                     cfusFloating
  312.                 )
  313.             );

  314.             Stream fixedStream = new Stream (
  315.                 CompositePeriodBuilder.FixedCompositeUnit (
  316.                     lsFixedStreamEdgeDate,
  317.                     cpsFixed,
  318.                     ucasFixed,
  319.                     cfusFixed
  320.                 )
  321.             );

  322.             aFFC[i] = new FixFloatComponent (
  323.                 fixedStream,
  324.                 floatingStream,
  325.                 csp
  326.             );

  327.             aFFC[i].setPrimaryCode ("FixFloat:" + astrMaturityTenor[i]);
  328.         }

  329.         return aFFC;
  330.     }

  331.     /*
  332.      * Construct an array of float-float swaps from the corresponding reference (6M) and the derived legs.
  333.      *
  334.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  335.      */

  336.     private static final FloatFloatComponent[] FloatFloatSwap (
  337.         final JulianDate dtSpot,
  338.         final ForwardLabel fri,
  339.         final String[] astrMaturityTenor)
  340.         throws Exception
  341.     {
  342.         if (null == astrMaturityTenor || 0 == astrMaturityTenor.length) return null;

  343.         FloatFloatComponent[] aFFC = new FloatFloatComponent[astrMaturityTenor.length];

  344.         int iTenorInMonths = Integer.parseInt (fri.tenor().split ("M")[0]);

  345.         String strCurrency = fri.currency();

  346.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  347.             aFFC[i] = OTCFloatFloat (
  348.                 dtSpot,
  349.                 strCurrency,
  350.                 iTenorInMonths + "M",
  351.                 astrMaturityTenor[i],
  352.                 0.
  353.             );

  354.         return aFFC;
  355.     }

  356.     /*
  357.      * Construct an array of fix-float component pairs from the corresponding reference (6M) and the derived legs.
  358.      *
  359.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  360.      */

  361.     private static final ComponentPair[] FixFloatComponentPair (
  362.         final JulianDate dtSpot,
  363.         final CurveSurfaceQuoteContainer csqs,
  364.         final ForwardLabel friDerived,
  365.         final String[] astrMaturityTenor)
  366.         throws Exception
  367.     {
  368.         if (null == astrMaturityTenor || 0 == astrMaturityTenor.length) return null;

  369.         ComponentPair[] aFFCP = new ComponentPair[astrMaturityTenor.length];

  370.         ValuationParams valParams = new ValuationParams (
  371.             dtSpot,
  372.             dtSpot,
  373.             friDerived.currency()
  374.         );

  375.         for (int i = 0; i < astrMaturityTenor.length; ++i) {
  376.             ComponentPair cp = OTCComponentPair (
  377.                 dtSpot,
  378.                 friDerived.currency(),
  379.                 friDerived.tenor(),
  380.                 astrMaturityTenor[i],
  381.                 0.,
  382.                 0.,
  383.                 0.
  384.             );

  385.             double dblReferenceFixedCoupon = cp.referenceComponent().measureValue (
  386.                 valParams,
  387.                 null,
  388.                 csqs,
  389.                 null,
  390.                 "FairPremium"
  391.             );

  392.             double dblDerivedFixedCoupon = cp.derivedComponent().measureValue (
  393.                 valParams,
  394.                 null,
  395.                 csqs,
  396.                 null,
  397.                 "FairPremium"
  398.             );

  399.             aFFCP[i] = OTCComponentPair (
  400.                 dtSpot,
  401.                 friDerived.currency(),
  402.                 friDerived.tenor(),
  403.                 astrMaturityTenor[i],
  404.                 dblReferenceFixedCoupon,
  405.                 dblDerivedFixedCoupon,
  406.                 0.
  407.             );
  408.         }

  409.         return aFFCP;
  410.     }

  411.     public static final ForwardCurve CustomIBORBuilderSample (
  412.         final MergedDiscountForwardCurve dc,
  413.         final ForwardCurve fcReference,
  414.         final ForwardLabel fri,
  415.         final SegmentCustomBuilderControl scbc,
  416.         final String[] astrDepositTenor,
  417.         final double[] adblDepositQuote,
  418.         final String strDepositCalibMeasure,
  419.         final String[] astrFRATenor,
  420.         final double[] adblFRAQuote,
  421.         final String strFRACalibMeasure,
  422.         final String[] astrFixFloatTenor,
  423.         final double[] adblFixFloatQuote,
  424.         final String strFixFloatCalibMeasure,
  425.         final String[] astrFloatFloatTenor,
  426.         final double[] adblFloatFloatQuote,
  427.         final String strFloatFloatCalibMeasure,
  428.         final String[] astrSyntheticFloatFloatTenor,
  429.         final double[] adblSyntheticFloatFloatQuote,
  430.         final String strSyntheticFloatFloatCalibMeasure,
  431.         final String strHeaderComment,
  432.         final boolean bPrintMetric)
  433.         throws Exception
  434.     {
  435.         if (bPrintMetric) {
  436.             System.out.println ("\n\t----------------------------------------------------------------");

  437.             System.out.println ("\t     " + strHeaderComment);

  438.             System.out.println ("\t----------------------------------------------------------------");
  439.         }

  440.         JulianDate dtValue = dc.epoch();

  441.         SingleStreamComponent[] aDeposit = DepositFromMaturityDays (
  442.             dtValue,
  443.             astrDepositTenor,
  444.             fri
  445.         );

  446.         /*
  447.          * Construct the Deposit Instrument Set Stretch Builder
  448.          */

  449.         LatentStateStretchSpec depositStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  450.             "DEPOSIT",
  451.             aDeposit,
  452.             strDepositCalibMeasure,
  453.             adblDepositQuote
  454.         );

  455.         FRAStandardComponent[] aFRA = FRAFromMaturityDays (
  456.             dtValue,
  457.             fri,
  458.             astrFRATenor,
  459.             adblFRAQuote
  460.         );

  461.         /*
  462.          * Construct the FRA Instrument Set Stretch Builder
  463.          */

  464.         LatentStateStretchSpec fraStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  465.             "FRA",
  466.             aFRA,
  467.             strFRACalibMeasure,
  468.             adblFRAQuote
  469.         );

  470.         FixFloatComponent[] aFixFloat = FixFloatSwap2 (
  471.             dtValue,
  472.             fri,
  473.             astrFixFloatTenor
  474.         );

  475.         /*
  476.          * Construct the Fix-Float Component Set Stretch Builder
  477.          */

  478.         LatentStateStretchSpec fixFloatStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  479.             "FIXFLOAT",
  480.             aFixFloat,
  481.             strFixFloatCalibMeasure,
  482.             adblFixFloatQuote
  483.         );

  484.         FloatFloatComponent[] aFloatFloat = FloatFloatSwap (
  485.             dtValue,
  486.             fri,
  487.             astrFloatFloatTenor
  488.         );

  489.         /*
  490.          * Construct the Float-Float Component Set Stretch Builder
  491.          */

  492.         LatentStateStretchSpec floatFloatStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  493.             "FLOATFLOAT",
  494.             aFloatFloat,
  495.             strFloatFloatCalibMeasure,
  496.             adblFloatFloatQuote
  497.         );

  498.         FloatFloatComponent[] aSyntheticFloatFloat = FloatFloatSwap (
  499.             dtValue,
  500.             fri,
  501.             astrSyntheticFloatFloatTenor
  502.         );

  503.         /*
  504.          * Construct the Synthetic Float-Float Component Set Stretch Builder
  505.          */

  506.         LatentStateStretchSpec syntheticFloatFloatStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  507.             "SYNTHETICFLOATFLOAT",
  508.             aSyntheticFloatFloat,
  509.             strSyntheticFloatFloatCalibMeasure,
  510.             adblSyntheticFloatFloatQuote
  511.         );

  512.         LatentStateStretchSpec[] aStretchSpec = new LatentStateStretchSpec[] {
  513.             depositStretch,
  514.             fraStretch,
  515.             fixFloatStretch,
  516.             floatFloatStretch,
  517.             syntheticFloatFloatStretch
  518.         };

  519.         /*
  520.          * Set up the Linear Curve Calibrator using the following parameters:
  521.          *  - Cubic Exponential Mixture Basis Spline Set
  522.          *  - Ck = 2, Segment Curvature Penalty = 2
  523.          *  - Quadratic Rational Shape Controller
  524.          *  - Natural Boundary Setting
  525.          */

  526.         LinearLatentStateCalibrator lcc = new LinearLatentStateCalibrator (
  527.             scbc,
  528.             BoundarySettings.NaturalStandard(),
  529.             MultiSegmentSequence.CALIBRATE,
  530.             null,
  531.             null
  532.         );

  533.         ValuationParams valParams = new ValuationParams (
  534.             dtValue,
  535.             dtValue,
  536.             fri.currency()
  537.         );

  538.         /*
  539.          * Set the discount curve based component market parameters.
  540.          */

  541.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  542.             dc,
  543.             fcReference,
  544.             null,
  545.             null,
  546.             null,
  547.             null,
  548.             null,
  549.             null
  550.         );

  551.         /*
  552.          * Construct the Shape Preserving Forward Curve by applying the linear curve calibrator to the array
  553.          *  of Deposit and Swap Stretches.
  554.          */

  555.         ForwardCurve fcDerived = ScenarioForwardCurveBuilder.ShapePreservingForwardCurve (
  556.             lcc,
  557.             aStretchSpec,
  558.             fri,
  559.             valParams,
  560.             null,
  561.             mktParams,
  562.             null,
  563.             null == adblDepositQuote || 0 == adblDepositQuote.length ? adblFRAQuote[0] : adblDepositQuote[0]
  564.         );

  565.         /*
  566.          * Set the discount curve + cubic polynomial forward curve based component market parameters.
  567.          */

  568.         mktParams.setForwardState (fcDerived);

  569.         if (bPrintMetric) {
  570.             /*
  571.              * Cross-Comparison of the Deposit Calibration Instrument "Forward" metric.
  572.              */

  573.             if (null != aDeposit && null != adblDepositQuote) {
  574.                 System.out.println ("\t----------------------------------------------------------------");

  575.                 System.out.println ("\t     DEPOSIT INSTRUMENTS QUOTE RECOVERY");

  576.                 System.out.println ("\t----------------------------------------------------------------");

  577.                 for (int i = 0; i < aDeposit.length; ++i)
  578.                     System.out.println ("\t[" + aDeposit[i].effectiveDate() + " - " + aDeposit[i].maturityDate() + "] = " +
  579.                         FormatUtil.FormatDouble (aDeposit[i].measureValue (valParams, null, mktParams, null, strDepositCalibMeasure), 1, 6, 1.) +
  580.                             " | " + FormatUtil.FormatDouble (adblDepositQuote[i], 1, 6, 1.) + " | " +
  581.                                 FormatUtil.FormatDouble (fcDerived.forward (aDeposit[i].maturityDate()), 1, 4, 100.) + "%");
  582.             }

  583.             /*
  584.              * Cross-Comparison of the FRA Calibration Instrument "Forward" metric.
  585.              */

  586.             if (null != aFRA && null != adblFRAQuote) {
  587.                 System.out.println ("\t----------------------------------------------------------------");

  588.                 System.out.println ("\t     FRA INSTRUMENTS QUOTE RECOVERY");

  589.                 System.out.println ("\t----------------------------------------------------------------");

  590.                 for (int i = 0; i < aFRA.length; ++i)
  591.                     System.out.println ("\t[" + aFRA[i].effectiveDate() + " - " + aFRA[i].maturityDate() + "] = " +
  592.                         FormatUtil.FormatDouble (aFRA[i].measureValue (valParams, null, mktParams, null, strFRACalibMeasure), 1, 6, 1.) +
  593.                             " | " + FormatUtil.FormatDouble (adblFRAQuote[i], 1, 6, 1.) + " | " +
  594.                                 FormatUtil.FormatDouble (fcDerived.forward (aFRA[i].maturityDate()), 1, 4, 100.) + "%");
  595.             }

  596.             /*
  597.              * Cross-Comparison of the Fix-Float Calibration Instrument "DerivedParBasisSpread" metric.
  598.              */

  599.             if (null != aFixFloat && null != adblFixFloatQuote) {
  600.                 System.out.println ("\t----------------------------------------------------------------");

  601.                 System.out.println ("\t     FIX-FLOAT INSTRUMENTS QUOTE RECOVERY");

  602.                 System.out.println ("\t----------------------------------------------------------------");

  603.                 for (int i = 0; i < aFixFloat.length; ++i)
  604.                     System.out.println ("\t[" + aFixFloat[i].effectiveDate() + " - " + aFixFloat[i].maturityDate() + "] = " +
  605.                         FormatUtil.FormatDouble (aFixFloat[i].measureValue (valParams, null, mktParams, null, strFixFloatCalibMeasure), 1, 4, 100.) +
  606.                             "% | " + FormatUtil.FormatDouble (adblFixFloatQuote[i], 1, 4, 100.) + "% | " +
  607.                                 FormatUtil.FormatDouble (fcDerived.forward (aFixFloat[i].maturityDate()), 1, 4, 100.) + "%");
  608.             }

  609.             /*
  610.              * Cross-Comparison of the Float-Float Calibration Instrument "DerivedParBasisSpread" metric.
  611.              */

  612.             if (null != aFloatFloat && null != adblFloatFloatQuote) {
  613.                 System.out.println ("\t----------------------------------------------------------------");

  614.                 System.out.println ("\t     FLOAT-FLOAT INSTRUMENTS QUOTE RECOVERY");

  615.                 System.out.println ("\t----------------------------------------------------------------");

  616.                 for (int i = 0; i < aFloatFloat.length; ++i)
  617.                     System.out.println ("\t[" + aFloatFloat[i].effectiveDate() + " - " + aFloatFloat[i].maturityDate() + "] = " +
  618.                         FormatUtil.FormatDouble (aFloatFloat[i].measureValue (valParams, null, mktParams, null, strFloatFloatCalibMeasure), 1, 2, 1.) +
  619.                             " | " + FormatUtil.FormatDouble (adblFloatFloatQuote[i], 1, 2, 10000.) + " | " +
  620.                                 FormatUtil.FormatDouble (fcDerived.forward (aFloatFloat[i].maturityDate()), 1, 4, 100.) + "%");
  621.             }

  622.             /*
  623.              * Cross-Comparison of the Synthetic Float-Float Calibration Instrument "DerivedParBasisSpread" metric.
  624.              */

  625.             if (null != aSyntheticFloatFloat && null != adblSyntheticFloatFloatQuote) {
  626.                 System.out.println ("\t----------------------------------------------------------------");

  627.                 System.out.println ("\t     SYNTHETIC FLOAT-FLOAT INSTRUMENTS QUOTE RECOVERY");

  628.                 System.out.println ("\t----------------------------------------------------------------");

  629.                 for (int i = 0; i < aSyntheticFloatFloat.length; ++i)
  630.                     System.out.println ("\t[" + aSyntheticFloatFloat[i].effectiveDate() + " - " + aSyntheticFloatFloat[i].maturityDate() + "] = " +
  631.                         FormatUtil.FormatDouble (aSyntheticFloatFloat[i].measureValue (valParams, null, mktParams, null, strSyntheticFloatFloatCalibMeasure), 1, 2, 1.) +
  632.                             " | " + FormatUtil.FormatDouble (adblSyntheticFloatFloatQuote[i], 1, 2, 10000.) + " | " +
  633.                                 FormatUtil.FormatDouble (fcDerived.forward (aSyntheticFloatFloat[i].maturityDate()), 1, 4, 100.) + "%");
  634.             }
  635.         }

  636.         return fcDerived;
  637.     }

  638.     public static final ForwardCurve CustomIBORBuilderSample2 (
  639.         final MergedDiscountForwardCurve dc,
  640.         final ForwardCurve fcReference,
  641.         final ForwardLabel fri,
  642.         final SegmentCustomBuilderControl scbc,
  643.         final String[] astrDepositTenor,
  644.         final double[] adblDepositQuote,
  645.         final String strDepositCalibMeasure,
  646.         final String[] astrFRATenor,
  647.         final double[] adblFRAQuote,
  648.         final String strFRACalibMeasure,
  649.         final String[] astrFixFloatTenor,
  650.         final double[] adblFixFloatQuote,
  651.         final String strFixFloatCalibMeasure,
  652.         final String[] astrComponentPairTenor,
  653.         final double[] adblComponentPairQuote,
  654.         final String strComponentPairCalibMeasure,
  655.         final String[] astrSyntheticComponentPairTenor,
  656.         final double[] adblSyntheticComponentPairQuote,
  657.         final String strSyntheticComponentPairCalibMeasure,
  658.         final String strHeaderComment,
  659.         final boolean bPrintMetric)
  660.         throws Exception
  661.     {
  662.         if (bPrintMetric) {
  663.             System.out.println ("\n\t----------------------------------------------------------------");

  664.             System.out.println ("\t     " + strHeaderComment);

  665.             System.out.println ("\t----------------------------------------------------------------");
  666.         }

  667.         JulianDate dtValue = dc.epoch();

  668.         ValuationParams valParams = new ValuationParams (
  669.             dtValue,
  670.             dtValue,
  671.             fri.currency()
  672.         );

  673.         /*
  674.          * Set the discount curve based component market parameters.
  675.          */

  676.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  677.             dc,
  678.             fcReference,
  679.             null,
  680.             null,
  681.             null,
  682.             null,
  683.             null,
  684.             null
  685.         );

  686.         SingleStreamComponent[] aDeposit = DepositFromMaturityDays (
  687.             dtValue,
  688.             astrDepositTenor,
  689.             fri
  690.         );

  691.         /*
  692.          * Construct the Deposit Instrument Set Stretch Builder
  693.          */

  694.         LatentStateStretchSpec depositStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  695.             "DEPOSIT",
  696.             aDeposit,
  697.             strDepositCalibMeasure,
  698.             adblDepositQuote
  699.         );

  700.         FRAStandardComponent[] aFRA = FRAFromMaturityDays (
  701.             dtValue,
  702.             fri,
  703.             astrFRATenor,
  704.             adblFRAQuote
  705.         );

  706.         /*
  707.          * Construct the FRA Instrument Set Stretch Builder
  708.          */

  709.         LatentStateStretchSpec fraStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  710.             "FRA",
  711.             aFRA,
  712.             strFRACalibMeasure,
  713.             adblFRAQuote
  714.         );

  715.         FixFloatComponent[] aFixFloat = FixFloatSwap (
  716.             dtValue,
  717.             fri,
  718.             astrFixFloatTenor
  719.         );

  720.         /*
  721.          * Construct the Fix-Float Component Set Stretch Builder
  722.          */

  723.         LatentStateStretchSpec fixFloatStretch = LatentStateStretchBuilder.ForwardStretchSpec (
  724.             "FIXFLOAT",
  725.             aFixFloat,
  726.             strFixFloatCalibMeasure,
  727.             adblFixFloatQuote
  728.         );

  729.         org.drip.product.fx.ComponentPair[] aComponentPair = FixFloatComponentPair (
  730.             dtValue,
  731.             mktParams,
  732.             fri,
  733.             astrComponentPairTenor
  734.         );

  735.         /*
  736.          * Construct the Float-Float Component Set Stretch Builder
  737.          */

  738.         LatentStateStretchSpec fixFloatCPStretch = LatentStateStretchBuilder.ComponentPairForwardStretch (
  739.             "FIXFLOATCP",
  740.             aComponentPair,
  741.             valParams,
  742.             mktParams,
  743.             adblComponentPairQuote,
  744.             true,
  745.             true
  746.         );

  747.         org.drip.product.fx.ComponentPair[] aSyntheticComponentPair = FixFloatComponentPair (
  748.             dtValue,
  749.             mktParams,
  750.             fri,
  751.             astrSyntheticComponentPairTenor
  752.         );

  753.         /*
  754.          * Construct the Synthetic Fix-Float Component Set Stretch Builder
  755.          */

  756.         LatentStateStretchSpec syntheticFixFloatCPStretch = LatentStateStretchBuilder.ComponentPairForwardStretch (
  757.             "SYNTHETICFIXFLOATCP",
  758.             aSyntheticComponentPair,
  759.             valParams,
  760.             mktParams,
  761.             adblSyntheticComponentPairQuote,
  762.             true,
  763.             true
  764.         );

  765.         LatentStateStretchSpec[] aStretchSpec = new LatentStateStretchSpec[] {
  766.             depositStretch,
  767.             fraStretch,
  768.             fixFloatStretch,
  769.             fixFloatCPStretch,
  770.             syntheticFixFloatCPStretch
  771.         };

  772.         /*
  773.          * Set up the Linear Curve Calibrator using the following parameters:
  774.          *  - Cubic Exponential Mixture Basis Spline Set
  775.          *  - Ck = 2, Segment Curvature Penalty = 2
  776.          *  - Quadratic Rational Shape Controller
  777.          *  - Natural Boundary Setting
  778.          */

  779.         LinearLatentStateCalibrator lcc = new LinearLatentStateCalibrator (
  780.             scbc,
  781.             BoundarySettings.NaturalStandard(),
  782.             MultiSegmentSequence.CALIBRATE,
  783.             null,
  784.             null
  785.         );

  786.         /*
  787.          * Construct the Shape Preserving Forward Curve by applying the linear curve calibrator to the array
  788.          *  of Deposit and Swap Stretches.
  789.          */

  790.         ForwardCurve fcDerived = ScenarioForwardCurveBuilder.ShapePreservingForwardCurve (
  791.             lcc,
  792.             aStretchSpec,
  793.             fri,
  794.             valParams,
  795.             null,
  796.             mktParams,
  797.             null,
  798.             null == adblDepositQuote || 0 == adblDepositQuote.length ? adblFRAQuote[0] : adblDepositQuote[0]
  799.         );

  800.         /*
  801.          * Set the discount curve + cubic polynomial forward curve based component market parameters.
  802.          */

  803.         mktParams.setForwardState (fcDerived);

  804.         if (bPrintMetric) {
  805.             /*
  806.              * Cross-Comparison of the Deposit Calibration Instrument "Forward" metric.
  807.              */

  808.             if (null != aDeposit && null != adblDepositQuote) {
  809.                 System.out.println ("\t----------------------------------------------------------------");

  810.                 System.out.println ("\t     DEPOSIT INSTRUMENTS QUOTE RECOVERY");

  811.                 System.out.println ("\t----------------------------------------------------------------");

  812.                 for (int i = 0; i < aDeposit.length; ++i)
  813.                     System.out.println ("\t[" + aDeposit[i].effectiveDate() + " - " + aDeposit[i].maturityDate() + "] = " +
  814.                         FormatUtil.FormatDouble (aDeposit[i].measureValue (valParams, null, mktParams, null, strDepositCalibMeasure), 1, 6, 1.) +
  815.                             " | " + FormatUtil.FormatDouble (adblDepositQuote[i], 1, 6, 1.) + " | " +
  816.                                 FormatUtil.FormatDouble (fcDerived.forward (aDeposit[i].maturityDate()), 1, 4, 100.) + "%");
  817.             }

  818.             /*
  819.              * Cross-Comparison of the FRA Calibration Instrument "Forward" metric.
  820.              */

  821.             if (null != aFRA && null != adblFRAQuote) {
  822.                 System.out.println ("\t----------------------------------------------------------------");

  823.                 System.out.println ("\t     FRA INSTRUMENTS QUOTE RECOVERY");

  824.                 System.out.println ("\t----------------------------------------------------------------");

  825.                 for (int i = 0; i < aFRA.length; ++i)
  826.                     System.out.println ("\t[" + aFRA[i].effectiveDate() + " - " + aFRA[i].maturityDate() + "] = " +
  827.                         FormatUtil.FormatDouble (aFRA[i].measureValue (valParams, null, mktParams, null, strFRACalibMeasure), 1, 6, 1.) +
  828.                             " | " + FormatUtil.FormatDouble (adblFRAQuote[i], 1, 6, 1.) + " | " +
  829.                                 FormatUtil.FormatDouble (fcDerived.forward (aFRA[i].maturityDate()), 1, 4, 100.) + "%");
  830.             }

  831.             /*
  832.              * Cross-Comparison of the Fix-Float Calibration Instrument "DerivedParBasisSpread" metric.
  833.              */

  834.             if (null != aFixFloat && null != adblFixFloatQuote) {
  835.                 System.out.println ("\t----------------------------------------------------------------");

  836.                 System.out.println ("\t     FIX-FLOAT INSTRUMENTS QUOTE RECOVERY");

  837.                 System.out.println ("\t----------------------------------------------------------------");

  838.                 for (int i = 0; i < aFixFloat.length; ++i)
  839.                     System.out.println ("\t[" + aFixFloat[i].effectiveDate() + " - " + aFixFloat[i].maturityDate() + "] = " +
  840.                         FormatUtil.FormatDouble (aFixFloat[i].measureValue (valParams, null, mktParams, null, strFixFloatCalibMeasure), 1, 2, 100.) +
  841.                             "% | " + FormatUtil.FormatDouble (adblFixFloatQuote[i], 1, 2, 100.) + "% | " +
  842.                                 FormatUtil.FormatDouble (fcDerived.forward (aFixFloat[i].maturityDate()), 1, 4, 100.) + "%");
  843.             }

  844.             /*
  845.              * Cross-Comparison of the Fix-Float Component Pair "DerivedParBasisSpread" metric.
  846.              */

  847.             if (null != aComponentPair && null != adblComponentPairQuote) {
  848.                 System.out.println ("\t----------------------------------------------------------------");

  849.                 System.out.println ("\t     FIX-FLOAT COMPONENT PAIR QUOTE RECOVERY");

  850.                 System.out.println ("\t----------------------------------------------------------------");

  851.                 for (int i = 0; i < aComponentPair.length; ++i)
  852.                     System.out.println ("\t[" + aComponentPair[i].effective() + " - " + aComponentPair[i].maturity() + "] = " +
  853.                         FormatUtil.FormatDouble (aComponentPair[i].measureValue (valParams, null, mktParams, null, strComponentPairCalibMeasure), 1, 2, 1.) +
  854.                             " | " + FormatUtil.FormatDouble (adblComponentPairQuote[i], 1, 2, 10000.) + " | " +
  855.                                 FormatUtil.FormatDouble (fcDerived.forward (aComponentPair[i].maturity()), 1, 4, 100.) + "%");
  856.             }

  857.             /*
  858.              * Cross-Comparison of the Synthetic Float-Float Component Pair "DerivedParBasisSpread" metric.
  859.              */

  860.             if (null != aSyntheticComponentPair && null != adblSyntheticComponentPairQuote) {
  861.                 System.out.println ("\t----------------------------------------------------------------");

  862.                 System.out.println ("\t     SYNTHETIC FIX-FLOAT COMPONENT PAIR QUOTE RECOVERY");

  863.                 System.out.println ("\t----------------------------------------------------------------");

  864.                 for (int i = 0; i < aSyntheticComponentPair.length; ++i)
  865.                     System.out.println ("\t[" + aSyntheticComponentPair[i].effective() + " - " + aSyntheticComponentPair[i].maturity() + "] = " +
  866.                         FormatUtil.FormatDouble (aSyntheticComponentPair[i].measureValue (valParams, null, mktParams, null, strSyntheticComponentPairCalibMeasure), 1, 2, 1.) +
  867.                             " | " + FormatUtil.FormatDouble (adblSyntheticComponentPairQuote[i], 1, 2, 10000.) + " | " +
  868.                                 FormatUtil.FormatDouble (fcDerived.forward (aSyntheticComponentPair[i].maturity()), 1, 4, 100.) + "%");
  869.             }
  870.         }

  871.         return fcDerived;
  872.     }

  873.     private static final void ForwardJack (
  874.         final JulianDate dt,
  875.         final ForwardCurve fc,
  876.         final String strStartDateTenor,
  877.         final String strManifestMeasure)
  878.     {
  879.         JulianDate dtJack = dt.addTenor (strStartDateTenor);

  880.         System.out.println ("\t" +
  881.             dtJack + " | " +
  882.             strStartDateTenor + ": " +
  883.             fc.jackDForwardDManifestMeasure (
  884.                 strManifestMeasure,
  885.                 dtJack).displayString()
  886.             );
  887.     }

  888.     public static final void ForwardJack (
  889.         final JulianDate dt,
  890.         final String strHeaderComment,
  891.         final ForwardCurve fc,
  892.         final String strManifestMeasure)
  893.     {
  894.         System.out.println ("\n\t----------------------------------------------------------------");

  895.         System.out.println ("\t" + strHeaderComment);

  896.         System.out.println ("\t----------------------------------------------------------------");

  897.         ForwardJack (dt, fc, "1Y", strManifestMeasure);

  898.         ForwardJack (dt, fc, "2Y", strManifestMeasure);

  899.         ForwardJack (dt, fc, "3Y", strManifestMeasure);

  900.         ForwardJack (dt, fc, "5Y", strManifestMeasure);

  901.         ForwardJack (dt, fc, "7Y", strManifestMeasure);
  902.     }
  903. }