CCBSDiscountCurve.java

  1. package org.drip.sample.dual;

  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.numerical.differentiation.WengertJacobian;
  8. import org.drip.param.market.CurveSurfaceQuoteContainer;
  9. import org.drip.param.period.*;
  10. import org.drip.param.valuation.*;
  11. import org.drip.product.definition.CalibratableComponent;
  12. import org.drip.product.fx.ComponentPair;
  13. import org.drip.product.params.*;
  14. import org.drip.product.rates.*;
  15. import org.drip.spline.params.SegmentCustomBuilderControl;
  16. import org.drip.spline.stretch.*;
  17. import org.drip.state.creator.*;
  18. import org.drip.state.discount.*;
  19. import org.drip.state.estimator.*;
  20. import org.drip.state.forward.ForwardCurve;
  21. import org.drip.state.identifier.*;
  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) 2020 Lakshmi Krishnamurthy
  28.  * Copyright (C) 2019 Lakshmi Krishnamurthy
  29.  * Copyright (C) 2018 Lakshmi Krishnamurthy
  30.  * Copyright (C) 2017 Lakshmi Krishnamurthy
  31.  * Copyright (C) 2016 Lakshmi Krishnamurthy
  32.  * Copyright (C) 2015 Lakshmi Krishnamurthy
  33.  * Copyright (C) 2014 Lakshmi Krishnamurthy
  34.  *
  35.  *  This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics,
  36.  *      asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment
  37.  *      analytics, and portfolio construction analytics within and across fixed income, credit, commodity,
  38.  *      equity, FX, and structured products. It also includes auxiliary libraries for algorithm support,
  39.  *      numerical analysis, numerical optimization, spline builder, model validation, statistical learning,
  40.  *      and computational support.
  41.  *  
  42.  *      https://lakshmidrip.github.io/DROP/
  43.  *  
  44.  *  DROP is composed of three modules:
  45.  *  
  46.  *  - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/
  47.  *  - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
  48.  *  - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/
  49.  *
  50.  *  DROP Product Core implements libraries for the following:
  51.  *  - Fixed Income Analytics
  52.  *  - Loan Analytics
  53.  *  - Transaction Cost Analytics
  54.  *
  55.  *  DROP Portfolio Core implements libraries for the following:
  56.  *  - Asset Allocation Analytics
  57.  *  - Asset Liability Management Analytics
  58.  *  - Capital Estimation Analytics
  59.  *  - Exposure Analytics
  60.  *  - Margin Analytics
  61.  *  - XVA Analytics
  62.  *
  63.  *  DROP Computational Core implements libraries for the following:
  64.  *  - Algorithm Support
  65.  *  - Computation Support
  66.  *  - Function Analysis
  67.  *  - Model Validation
  68.  *  - Numerical Analysis
  69.  *  - Numerical Optimizer
  70.  *  - Spline Builder
  71.  *  - Statistical Learning
  72.  *
  73.  *  Documentation for DROP is Spread Over:
  74.  *
  75.  *  - Main                     => https://lakshmidrip.github.io/DROP/
  76.  *  - Wiki                     => https://github.com/lakshmiDRIP/DROP/wiki
  77.  *  - GitHub                   => https://github.com/lakshmiDRIP/DROP
  78.  *  - Repo Layout Taxonomy     => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
  79.  *  - Javadoc                  => https://lakshmidrip.github.io/DROP/Javadoc/index.html
  80.  *  - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
  81.  *  - Release Versions         => https://lakshmidrip.github.io/DROP/version.html
  82.  *  - Community Credits        => https://lakshmidrip.github.io/DROP/credits.html
  83.  *  - Issues Catalog           => https://github.com/lakshmiDRIP/DROP/issues
  84.  *  - JUnit                    => https://lakshmidrip.github.io/DROP/junit/index.html
  85.  *  - Jacoco                   => https://lakshmidrip.github.io/DROP/jacoco/index.html
  86.  *
  87.  *  Licensed under the Apache License, Version 2.0 (the "License");
  88.  *      you may not use this file except in compliance with the License.
  89.  *  
  90.  *  You may obtain a copy of the License at
  91.  *      http://www.apache.org/licenses/LICENSE-2.0
  92.  *  
  93.  *  Unless required by applicable law or agreed to in writing, software
  94.  *      distributed under the License is distributed on an "AS IS" BASIS,
  95.  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  96.  *  
  97.  *  See the License for the specific language governing permissions and
  98.  *      limitations under the License.
  99.  */

  100. /**
  101.  * <i>CCBSDiscountCurve</i> demonstrates the setup and construction of the Forward Curve from the CCBS
  102.  * Quotes.
  103.  *
  104.  * <br><br>
  105.  *  <ul>
  106.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  107.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  108.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">DROP API Construction and Usage</a></li>
  109.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/cross/README.md">G7 Standard Cross Currency Swap</a></li>
  110.  *  </ul>
  111.  * <br><br>
  112.  *
  113.  * @author Lakshmi Krishnamurthy
  114.  */

  115. public class CCBSDiscountCurve {

  116.     /*
  117.      * Construct an array of float-float swaps from the corresponding reference (6M) and the derived legs.
  118.      *
  119.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  120.      */

  121.     private static final FloatFloatComponent[] MakexM6MBasisSwap (
  122.         final JulianDate dtEffective,
  123.         final String strPayCurrency,
  124.         final String strCouponCurrency,
  125.         final double dblNotional,
  126.         final String[] astrMaturityTenor,
  127.         final int iTenorInMonths)
  128.         throws Exception
  129.     {
  130.         FloatFloatComponent[] aFFC = new FloatFloatComponent[astrMaturityTenor.length];

  131.         ComposableFloatingUnitSetting cfusReference = new ComposableFloatingUnitSetting (
  132.             "6M",
  133.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  134.             null,
  135.             ForwardLabel.Create (
  136.                 strCouponCurrency,
  137.                 "6M"
  138.             ),
  139.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  140.             0.
  141.         );

  142.         ComposableFloatingUnitSetting cfusDerived = new ComposableFloatingUnitSetting (
  143.             iTenorInMonths + "M",
  144.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  145.             null,
  146.             ForwardLabel.Create (
  147.                 strCouponCurrency,
  148.                 iTenorInMonths + "M"
  149.             ),
  150.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  151.             0.
  152.         );

  153.         CompositePeriodSetting cpsReference = new CompositePeriodSetting (
  154.             2,
  155.             "6M",
  156.             strPayCurrency,
  157.             null,
  158.             -1. * dblNotional,
  159.             null,
  160.             null,
  161.             strPayCurrency.equalsIgnoreCase (strCouponCurrency) ? null :
  162.                 new FixingSetting (
  163.                     FixingSetting.FIXING_PRESET_STATIC,
  164.                     null,
  165.                     dtEffective.julian()
  166.                 ),
  167.             null
  168.         );

  169.         CompositePeriodSetting cpsDerived = new CompositePeriodSetting (
  170.             12 / iTenorInMonths,
  171.             iTenorInMonths + "M",
  172.             strPayCurrency,
  173.             null,
  174.             1. * dblNotional,
  175.             null,
  176.             null,
  177.             strPayCurrency.equalsIgnoreCase (strCouponCurrency) ? null :
  178.                 new FixingSetting (
  179.                     FixingSetting.FIXING_PRESET_STATIC,
  180.                     null,
  181.                     dtEffective.julian()
  182.                 ),
  183.             null
  184.         );

  185.         CashSettleParams csp = new CashSettleParams (
  186.             0,
  187.             strPayCurrency,
  188.             0
  189.         );

  190.         for (int i = 0; i < astrMaturityTenor.length; ++i) {
  191.             List<Integer> lsReferenceStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  192.                 dtEffective,
  193.                 "6M",
  194.                 astrMaturityTenor[i],
  195.                 null
  196.             );

  197.             List<Integer> lsDerivedStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  198.                 dtEffective,
  199.                 iTenorInMonths + "M",
  200.                 astrMaturityTenor[i],
  201.                 null
  202.             );

  203.             Stream referenceStream = new Stream (
  204.                 CompositePeriodBuilder.FloatingCompositeUnit (
  205.                     lsReferenceStreamEdgeDate,
  206.                     cpsReference,
  207.                     cfusReference
  208.                 )
  209.             );

  210.             Stream derivedStream = new Stream (
  211.                 CompositePeriodBuilder.FloatingCompositeUnit (
  212.                     lsDerivedStreamEdgeDate,
  213.                     cpsDerived,
  214.                     cfusDerived
  215.                 )
  216.             );

  217.             aFFC[i] = new FloatFloatComponent (
  218.                 referenceStream,
  219.                 derivedStream,
  220.                 csp
  221.             );

  222.             aFFC[i].setPrimaryCode (referenceStream.name() + "||" + derivedStream.name());
  223.         }

  224.         return aFFC;
  225.     }

  226.     private static final FixFloatComponent OTCIRS (
  227.         final JulianDate dtSpot,
  228.         final String strCurrency,
  229.         final String strMaturityTenor,
  230.         final double dblCoupon)
  231.     {
  232.         FixedFloatSwapConvention ffConv = IBORFixedFloatContainer.ConventionFromJurisdiction (
  233.             strCurrency,
  234.             "ALL",
  235.             strMaturityTenor,
  236.             "MAIN"
  237.         );

  238.         return ffConv.createFixFloatComponent (
  239.             dtSpot,
  240.             strMaturityTenor,
  241.             dblCoupon,
  242.             0.,
  243.             1.
  244.         );
  245.     }

  246.     /*
  247.      * Construct the Array of Swap Instruments from the given set of parameters
  248.      *
  249.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  250.      */

  251.     private static final FixFloatComponent[] MakeIRS (
  252.         final JulianDate dtEffective,
  253.         final String strCurrency,
  254.         final String[] astrTenor)
  255.         throws Exception
  256.     {
  257.         FixFloatComponent[] aCalibComp = new FixFloatComponent[astrTenor.length];

  258.         for (int i = 0; i < astrTenor.length; ++i)
  259.             aCalibComp[i] = OTCIRS (
  260.                 dtEffective,
  261.                 strCurrency,
  262.                 astrTenor[i],
  263.                 0.
  264.             );

  265.         return aCalibComp;
  266.     }

  267.     private static final ComponentPair[] MakeCCSP (
  268.         final JulianDate dtValue,
  269.         final String strReferenceCurrency,
  270.         final String strDerivedCurrency,
  271.         final String[] astrTenor,
  272.         final int iTenorInMonths)
  273.         throws Exception
  274.     {
  275.         FloatFloatComponent[] aFFCReference = MakexM6MBasisSwap (
  276.             dtValue,
  277.             strReferenceCurrency,
  278.             strReferenceCurrency,
  279.             1.,
  280.             astrTenor,
  281.             3
  282.         );

  283.         FixFloatComponent[] aIRS = MakeIRS (
  284.             dtValue,
  285.             strDerivedCurrency,
  286.             astrTenor
  287.         );

  288.         ComponentPair[] aCCSP = new ComponentPair[astrTenor.length];

  289.         for (int i = 0; i < aCCSP.length; ++i)
  290.             aCCSP[i] = new ComponentPair (
  291.                 "EURUSD_" + astrTenor[i],
  292.                 aFFCReference[i],
  293.                 aIRS[i],
  294.                 null
  295.             );

  296.         return aCCSP;
  297.     }

  298.     private static final void TenorJack (
  299.         final JulianDate dtStart,
  300.         final String strTenor,
  301.         final String strManifestMeasure,
  302.         final MergedDiscountForwardCurve dc)
  303.         throws Exception
  304.     {
  305.         String strCurrency = dc.currency();

  306.         CalibratableComponent irsBespoke = OTCIRS (
  307.             dtStart,
  308.             strCurrency,
  309.             strTenor,
  310.             0.
  311.         );

  312.         WengertJacobian wjDFQuoteBespokeMat = dc.jackDDFDManifestMeasure (
  313.             irsBespoke.maturityDate(),
  314.             strManifestMeasure
  315.         );

  316.         System.out.println ("\t" + strTenor + " => " + wjDFQuoteBespokeMat.displayString());
  317.     }

  318.     public static final void MakeDiscountCurve (
  319.         final String strReferenceCurrency,
  320.         final String strDerivedCurrency,
  321.         final JulianDate dtValue,
  322.         final MergedDiscountForwardCurve dcReference,
  323.         final ForwardCurve fc6MReference,
  324.         final ForwardCurve fc3MReference,
  325.         final double dblRefDerFX,
  326.         final SegmentCustomBuilderControl scbc,
  327.         final String[] astrTenor,
  328.         final double[] adblCrossCurrencyBasis,
  329.         final double[] adblSwapRate,
  330.         final boolean bBasisOnDerivedLeg)
  331.         throws Exception
  332.     {
  333.         ComponentPair[] aCCSP = MakeCCSP (
  334.             dtValue,
  335.             strReferenceCurrency,
  336.             strDerivedCurrency,
  337.             astrTenor,
  338.             3
  339.         );

  340.         CurveSurfaceQuoteContainer mktParams = new CurveSurfaceQuoteContainer();

  341.         mktParams.setFundingState (dcReference);

  342.         mktParams.setForwardState (fc3MReference);

  343.         mktParams.setForwardState (fc6MReference);

  344.         CurrencyPair cp = CurrencyPair.FromCode (strDerivedCurrency + "/" + strReferenceCurrency);

  345.         FXLabel fxLabel = FXLabel.Standard (cp);

  346.         mktParams.setFXState (
  347.             ScenarioFXCurveBuilder.CubicPolynomialCurve (
  348.                 fxLabel.fullyQualifiedName(),
  349.                 dtValue,
  350.                 cp,
  351.                 new String[] {"10Y"},
  352.                 new double[] {dblRefDerFX},
  353.                 dblRefDerFX
  354.             )
  355.         );

  356.         mktParams.setFixing (
  357.             aCCSP[0].effective(),
  358.             fxLabel,
  359.             dblRefDerFX
  360.         );

  361.         ValuationParams valParams = new ValuationParams (
  362.             dtValue,
  363.             dtValue,
  364.             strReferenceCurrency
  365.         );

  366.         LinearLatentStateCalibrator llsc = new LinearLatentStateCalibrator (
  367.             scbc,
  368.             BoundarySettings.NaturalStandard(),
  369.             MultiSegmentSequence.CALIBRATE,
  370.             null,
  371.             null
  372.         );

  373.         LatentStateStretchSpec stretchSpec = LatentStateStretchBuilder.ComponentPairDiscountStretch (
  374.             "FIXFLOAT",
  375.             aCCSP,
  376.             valParams,
  377.             mktParams,
  378.             adblCrossCurrencyBasis,
  379.             adblSwapRate,
  380.             bBasisOnDerivedLeg
  381.         );

  382.         MergedDiscountForwardCurve dcDerived = ScenarioDiscountCurveBuilder.ShapePreservingDFBuild (
  383.             strDerivedCurrency,
  384.             llsc,
  385.             new LatentStateStretchSpec[] {stretchSpec},
  386.             valParams,
  387.             null,
  388.             null,
  389.             null,
  390.             1.
  391.         );

  392.         mktParams.setFundingState (dcDerived);

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

  394.         if (bBasisOnDerivedLeg)
  395.             System.out.println ("\t     IRS INSTRUMENTS QUOTE REVISION FROM CCBS DERIVED BASIS INPUTS");
  396.         else
  397.             System.out.println ("\t     IRS INSTRUMENTS QUOTE REVISION FROM CCBS REFERENCE BASIS INPUTS");

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

  399.         for (int i = 0; i < aCCSP.length; ++i) {
  400.             CalibratableComponent rcDerived = aCCSP[i].derivedComponent();

  401.             CaseInsensitiveTreeMap<Double> mapOP = aCCSP[i].value (
  402.                 valParams,
  403.                 null,
  404.                 mktParams,
  405.                 null
  406.             );

  407.             double dblCalibSwapRate = mapOP.get (rcDerived.name() + "[SwapRate]");

  408.             System.out.println ("\t[" + rcDerived.effectiveDate() + " - " + rcDerived.maturityDate() + "] = " +
  409.                 FormatUtil.FormatDouble (dblCalibSwapRate, 1, 3, 100.) +
  410.                     "% | " + FormatUtil.FormatDouble (adblSwapRate[i], 1, 3, 100.) + "% | " +
  411.                         FormatUtil.FormatDouble (adblSwapRate[i] - dblCalibSwapRate, 2, 0, 10000.) + " | " +
  412.                             FormatUtil.FormatDouble (dcDerived.df (rcDerived.maturityDate()), 1, 4, 1.));
  413.         }

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

  415.         if (bBasisOnDerivedLeg)
  416.             System.out.println ("\t     CCBS DERIVED BASIS TENOR JACOBIAN");
  417.         else
  418.             System.out.println ("\t     CCBS REFERENCE BASIS TENOR JACOBIAN");

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

  420.         for (int i = 0; i < aCCSP.length; ++i)
  421.             TenorJack (
  422.                 dtValue,
  423.                 astrTenor[i],
  424.                 "PV",
  425.                 dcDerived
  426.             );
  427.     }
  428. }