ComposableUnitFloatingPeriod.java

  1. package org.drip.analytics.cashflow;

  2. /*
  3.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  4.  */

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

  79. /**
  80.  * <i>ComposableUnitFloatingPeriod</i> contains the Floating Cash Flow Periods' Composable Period Details.
  81.  * Currently it holds the Accrual Start Date, the Accrual End Date, the Fixing Date, the Spread over the
  82.  * Index, and the corresponding Reference Index Period.
  83.  *
  84.  *  <br><br>
  85.  *  <ul>
  86.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  87.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  88.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/analytics/README.md">Date, Cash Flow, and Cash Flow Period Measure Generation Utilities</a></li>
  89.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/analytics/cashflow/README.md">Unit and Composite Cash Flow Periods</a></li>
  90.  *  </ul>
  91.  *
  92.  * @author Lakshmi Krishnamurthy
  93.  */

  94. public class ComposableUnitFloatingPeriod extends org.drip.analytics.cashflow.ComposableUnitPeriod {
  95.     private double _dblSpread = java.lang.Double.NaN;
  96.     private org.drip.analytics.cashflow.ReferenceIndexPeriod _rip = null;

  97.     private org.drip.analytics.date.JulianDate lookBackProjectionDate (
  98.         final org.drip.param.market.CurveSurfaceQuoteContainer csqc,
  99.         final org.drip.state.identifier.ForwardLabel forwardLabel,
  100.         final org.drip.market.definition.OvernightIndex oi)
  101.     {
  102.         int iSkipBackDay = 0;
  103.         org.drip.analytics.date.JulianDate dtFixing = null;

  104.         org.drip.market.definition.FloaterIndex floaterIndex = forwardLabel.floaterIndex();

  105.         int iLookBackProjectionWindow = oi.publicationLag();

  106.         try {
  107.             dtFixing = new org.drip.analytics.date.JulianDate (_rip.fixingDate());

  108.             while (iSkipBackDay <= iLookBackProjectionWindow) {
  109.                 if (
  110.                     csqc.available (
  111.                         dtFixing,
  112.                         forwardLabel
  113.                     )
  114.                 )
  115.                 return dtFixing;

  116.                 if (null == (dtFixing = dtFixing.subtractBusDays (
  117.                     1,
  118.                     floaterIndex.calendar()
  119.                 )))
  120.                     return null;

  121.                 iSkipBackDay += 1;
  122.             }
  123.         } catch (java.lang.Exception e) {
  124.             e.printStackTrace();
  125.         }

  126.         return null;
  127.     }

  128.     private double baseForwardRate (
  129.         final org.drip.param.market.CurveSurfaceQuoteContainer csqc,
  130.         final org.drip.state.identifier.ForwardLabel forwardLabel)
  131.         throws java.lang.Exception
  132.     {
  133.         org.drip.market.definition.FloaterIndex floaterIndex = forwardLabel.floaterIndex();

  134.         if (!(floaterIndex instanceof org.drip.market.definition.OvernightIndex)) {
  135.             int iFixingDate = _rip.fixingDate();

  136.             if (
  137.                 csqc.available (
  138.                     iFixingDate,
  139.                     forwardLabel
  140.                 )
  141.             )
  142.                 return csqc.fixing (
  143.                     iFixingDate,
  144.                     forwardLabel
  145.                 );
  146.         } else {
  147.             org.drip.analytics.date.JulianDate dtValidFixing = lookBackProjectionDate (
  148.                 csqc,
  149.                 forwardLabel,
  150.                 (org.drip.market.definition.OvernightIndex) floaterIndex
  151.             );

  152.             if (null != dtValidFixing)
  153.                 return csqc.fixing (
  154.                     dtValidFixing,
  155.                     forwardLabel
  156.                 );
  157.         }

  158.         int iReferencePeriodEndDate = _rip.endDate();

  159.         org.drip.state.forward.ForwardRateEstimator fre = csqc.forwardState (forwardLabel);

  160.         if (null != fre) return fre.forward (iReferencePeriodEndDate);

  161.         java.lang.String strForwardCurrency = forwardLabel.currency();

  162.         org.drip.state.discount.MergedDiscountForwardCurve dcFunding = csqc.fundingState
  163.             (org.drip.state.identifier.FundingLabel.Standard (strForwardCurrency));

  164.         if (null == dcFunding)
  165.             throw new java.lang.Exception
  166.                 ("ComposableUnitFloatingPeriod::baseForwardRate => Cannot locate Funding Curve " +
  167.                     strForwardCurrency);

  168.         int iEpochDate = dcFunding.epoch().julian();

  169.         int iReferencePeriodStartDate = _rip.startDate();

  170.         iReferencePeriodStartDate = iReferencePeriodStartDate > iEpochDate ? iReferencePeriodStartDate :
  171.             iEpochDate;

  172.         return dcFunding.libor (
  173.             iReferencePeriodStartDate,
  174.             iReferencePeriodEndDate,
  175.             org.drip.analytics.daycount.Convention.YearFraction (
  176.                 iReferencePeriodStartDate,
  177.                 iReferencePeriodEndDate,
  178.                 floaterIndex.dayCount(),
  179.                 false,
  180.                 null,
  181.                 floaterIndex.calendar()
  182.             )
  183.         );
  184.     }

  185.     private double baseOTCFixFloatRate (
  186.         final org.drip.param.market.CurveSurfaceQuoteContainer csqc,
  187.         final org.drip.state.identifier.OTCFixFloatLabel otcFixFloatLabel)
  188.         throws java.lang.Exception
  189.     {
  190.         int iFixingDate = _rip.fixingDate();

  191.         if (csqc.available (
  192.             iFixingDate,
  193.             otcFixFloatLabel
  194.         ))
  195.             return csqc.fixing (
  196.                 iFixingDate,
  197.                 otcFixFloatLabel
  198.             );

  199.         java.lang.String strCurrency = otcFixFloatLabel.currency();

  200.         java.lang.String strOTCFixFloatMaturity = otcFixFloatLabel.fixFloatTenor();

  201.         org.drip.state.discount.MergedDiscountForwardCurve dcFunding = csqc.fundingState
  202.             (org.drip.state.identifier.FundingLabel.Standard (strCurrency));

  203.         if (null == dcFunding)
  204.             throw new java.lang.Exception
  205.                 ("ComposableUnitFloatingPeriod::baseOTCFixFloatRate => Cannot locate Funding Curve " +
  206.                     strCurrency);

  207.         org.drip.market.otc.FixedFloatSwapConvention ffsc =
  208.             org.drip.market.otc.IBORFixedFloatContainer.ConventionFromJurisdiction (
  209.                 strCurrency,
  210.                 "ALL",
  211.                 strOTCFixFloatMaturity,
  212.                 "MAIN"
  213.             );

  214.         if (null == ffsc)
  215.             throw new java.lang.Exception
  216.                 ("ComposableUnitFloatingPeriod::baseOTCFixFloatRate => Cannot locate Fix Float Convention!");

  217.         int iReferencePeriodStartDate = _rip.startDate();

  218.         org.drip.product.rates.FixFloatComponent ffc = ffsc.createFixFloatComponent (
  219.             new org.drip.analytics.date.JulianDate (iReferencePeriodStartDate),
  220.             strOTCFixFloatMaturity,
  221.             0.,
  222.             0.,
  223.             1.
  224.         );

  225.         if (null == ffc)
  226.             throw new java.lang.Exception
  227.                 ("ComposableUnitFloatingPeriod::baseOTCFixFloatRate => Cannot create Fix Float Component!");

  228.         java.util.Map<java.lang.String, java.lang.Double> mapFFCOutput = ffc.value (
  229.             org.drip.param.valuation.ValuationParams.Spot (iReferencePeriodStartDate),
  230.             null,
  231.             org.drip.param.creator.MarketParamsBuilder.Create (
  232.                 dcFunding,
  233.                 null,
  234.                 null,
  235.                 null,
  236.                 null,
  237.                 null,
  238.                 null
  239.             ),
  240.             null
  241.         );

  242.         if (null == mapFFCOutput || !mapFFCOutput.containsKey ("SwapRate"))
  243.             throw new java.lang.Exception
  244.                 ("ComposableUnitFloatingPeriod::baseOTCFixFloatRate => Cannot calculate Swap Rate!");

  245.         return mapFFCOutput.get ("SwapRate");
  246.     }

  247.     /**
  248.      * The ComposableUnitFloatingPeriod Constructor
  249.      *
  250.      * @param iStartDate Accrual Start Date
  251.      * @param iEndDate Accrual End Date
  252.      * @param strTenor The Composable Period Tenor
  253.      * @param rip The Reference Index Period
  254.      * @param dblSpread The Floater Spread
  255.      *
  256.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  257.      */

  258.     public ComposableUnitFloatingPeriod (
  259.         final int iStartDate,
  260.         final int iEndDate,
  261.         final java.lang.String strTenor,
  262.         final org.drip.analytics.cashflow.ReferenceIndexPeriod rip,
  263.         final double dblSpread)
  264.         throws java.lang.Exception
  265.     {
  266.         super (
  267.             iStartDate,
  268.             iEndDate,
  269.             strTenor,
  270.             rip.floaterLabel().ucas()
  271.         );

  272.         if (!org.drip.numerical.common.NumberUtil.IsValid (_dblSpread = dblSpread))
  273.             throw new java.lang.Exception ("ComposableUnitFloatingPeriod Constructor => Invalid Inputs");

  274.         _rip = rip;
  275.     }

  276.     /**
  277.      * Retrieve the Reference Rate for the Floating Period
  278.      *
  279.      * @param csqc The Market Curve and Surface
  280.      *
  281.      * @return The Reference Rate for the Floating Period
  282.      *
  283.      * @throws java.lang.Exception Thrown if the inputs are invalid
  284.      */

  285.     @Override public double baseRate (
  286.         final org.drip.param.market.CurveSurfaceQuoteContainer csqc)
  287.         throws java.lang.Exception
  288.     {
  289.         if (null == csqc) return java.lang.Double.NaN;

  290.         org.drip.state.identifier.FloaterLabel floaterLabel = _rip.floaterLabel();

  291.         if (floaterLabel instanceof org.drip.state.identifier.ForwardLabel)
  292.             return baseForwardRate (
  293.                 csqc,
  294.                 (org.drip.state.identifier.ForwardLabel) _rip.floaterLabel()
  295.             );

  296.         if (floaterLabel instanceof org.drip.state.identifier.OTCFixFloatLabel)
  297.             return baseOTCFixFloatRate (
  298.                 csqc,
  299.                 (org.drip.state.identifier.OTCFixFloatLabel) _rip.floaterLabel()
  300.             );

  301.         throw new java.lang.Exception
  302.             ("ComposableUnitFloatingPeriod::baseRate => Unknown Reference Period Index");
  303.     }

  304.     @Override public double basis()
  305.     {
  306.         return _dblSpread;
  307.     }

  308.     @Override public java.lang.String couponCurrency()
  309.     {
  310.         return _rip.floaterLabel().currency();
  311.     }

  312.     /**
  313.      * Retrieve the Reference Index Period
  314.      *
  315.      * @return The Reference Index Period
  316.      */

  317.     public org.drip.analytics.cashflow.ReferenceIndexPeriod referenceIndexPeriod()
  318.     {
  319.         return _rip;
  320.     }
  321. }