CompositePeriodBuilder.java

  1. package org.drip.analytics.support;

  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>CompositePeriodBuilder</i> exposes the composite period construction functionality.
  81.  *
  82.  *  <br><br>
  83.  *  <ul>
  84.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  85.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  86.  *      <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>
  87.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/analytics/support/README.md">Assorted Support and Helper Utilities</a></li>
  88.  *  </ul>
  89.  *
  90.  * @author Lakshmi Krishnamurthy
  91.  */

  92. public class CompositePeriodBuilder {

  93.     /**
  94.      * Edge Date Generation Sequence - Forward
  95.      */

  96.     public static final int EDGE_DATE_SEQUENCE_FORWARD = 0;

  97.     /**
  98.      * Edge Date Generation Sequence - Reverse
  99.      */

  100.     public static final int EDGE_DATE_SEQUENCE_REVERSE = 1;

  101.     /**
  102.      * Edge Date Generation Sequence - Regular
  103.      */

  104.     public static final int EDGE_DATE_SEQUENCE_REGULAR = 2;

  105.     /**
  106.      * Edge Date Generation Sequence - Overnight
  107.      */

  108.     public static final int EDGE_DATE_SEQUENCE_OVERNIGHT = 4;

  109.     /**
  110.      * Edge Date Generation Sequence - Single Edge Date Pair Between Dates
  111.      */

  112.     public static final int EDGE_DATE_SEQUENCE_SINGLE = 8;

  113.     /**
  114.      * Period Set Generation Customization - Short Stub (i.e., No adjustment on either end)
  115.      */

  116.     public static final int SHORT_STUB = 0;

  117.     /**
  118.      * Period Set Generation Customization - Merge the front periods to produce a long front
  119.      */

  120.     public static final int FULL_FRONT_PERIOD = 1;

  121.     /**
  122.      * Period Set Generation Customization - Long Stub (if present) belongs to the front/back end depending
  123.      *  upon backwards/forwards generation scheme
  124.      */

  125.     public static final int LONG_STUB = 2;

  126.     /**
  127.      * Reference Period Fixing is IN-ARREARS (i.e., displaced one period to the right) of the Coupon Period
  128.      */

  129.     public static final int REFERENCE_PERIOD_IN_ARREARS = 0;

  130.     /**
  131.      * Reference Period Fixing is IN-ADVANCE (i.e., the same as that) of the Coupon Period
  132.      */

  133.     public static final int REFERENCE_PERIOD_IN_ADVANCE = 1;

  134.     /**
  135.      * Accrual Compounding Rule - Arithmetic
  136.      */

  137.     public static final int ACCRUAL_COMPOUNDING_RULE_ARITHMETIC = 1;

  138.     /**
  139.      * Accrual Compounding Rule - Geometric
  140.      */

  141.     public static final int ACCRUAL_COMPOUNDING_RULE_GEOMETRIC = 2;

  142.     private static final int DAPAdjust (
  143.         final int iDate,
  144.         final org.drip.analytics.daycount.DateAdjustParams dap)
  145.     {
  146.         if (null == dap) return iDate;

  147.         try {
  148.             return dap.roll (iDate);
  149.         } catch (java.lang.Exception e) {
  150.             e.printStackTrace();
  151.         }

  152.         return iDate;
  153.     }

  154.     /**
  155.      * Verify if the Specified Accrual Compounding Rule is a Valid One
  156.      *
  157.      * @param iAccrualCompoundingRule The Accrual Compounding Rule
  158.      *
  159.      * @return TRUE - The Accrual Compounding Rule is valid
  160.      */

  161.     public static final boolean ValidateCompoundingRule (
  162.         final int iAccrualCompoundingRule)
  163.     {
  164.         return ACCRUAL_COMPOUNDING_RULE_ARITHMETIC == iAccrualCompoundingRule ||
  165.             ACCRUAL_COMPOUNDING_RULE_GEOMETRIC == iAccrualCompoundingRule;
  166.     }

  167.     /**
  168.      * Generate a list of period edge dates forward from the start.
  169.      *
  170.      * @param dtEffective Effective date
  171.      * @param dtMaturity Maturity date
  172.      * @param strTenor Period Tenor
  173.      * @param dap Inner Date Adjustment Parameters
  174.      * @param iPSEC Period Set Edge Customizer Setting
  175.      *
  176.      * @return List of Period Edge Dates
  177.      */

  178.     public static final java.util.List<java.lang.Integer> ForwardEdgeDates (
  179.         final org.drip.analytics.date.JulianDate dtEffective,
  180.         final org.drip.analytics.date.JulianDate dtMaturity,
  181.         final java.lang.String strTenor,
  182.         final org.drip.analytics.daycount.DateAdjustParams dap,
  183.         final int iPSEC)
  184.     {
  185.         if (null == dtEffective || null == dtMaturity || null == strTenor || strTenor.isEmpty()) return null;

  186.         java.lang.String strPeriodRollTenor = "";
  187.         org.drip.analytics.date.JulianDate dtEdge = dtEffective;

  188.         int iMaturityDate = dtMaturity.julian();

  189.         int iEdgeDate = dtEdge.julian();

  190.         if (iEdgeDate >= iMaturityDate) return null;

  191.         java.util.List<java.lang.Integer> lsEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  192.         while (iEdgeDate < iMaturityDate) {
  193.             lsEdgeDate.add (iEdgeDate);

  194.             strPeriodRollTenor = org.drip.analytics.support.Helper.AggregateTenor
  195.                 (strPeriodRollTenor, strTenor);

  196.             if (null == (dtEdge = dtMaturity.addTenor (strPeriodRollTenor))) return null;

  197.             iEdgeDate = dtEdge.julian();
  198.         }

  199.         if (iEdgeDate > iMaturityDate) {
  200.             if (SHORT_STUB == iPSEC)
  201.                 lsEdgeDate.add (iMaturityDate);
  202.             else if (LONG_STUB == iPSEC) {
  203.                 if (1 != lsEdgeDate.size()) lsEdgeDate.remove (lsEdgeDate.size() - 1);

  204.                 lsEdgeDate.add (iMaturityDate);
  205.             }
  206.         } else if (iEdgeDate == iMaturityDate)
  207.             lsEdgeDate.add (iMaturityDate);

  208.         java.util.List<java.lang.Integer> lsAdjustedEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  209.         lsAdjustedEdgeDate.add (lsEdgeDate.get (0));

  210.         int iNumDate = lsEdgeDate.size();

  211.         for (int i = 1; i < iNumDate - 1; ++i)
  212.             lsAdjustedEdgeDate.add (DAPAdjust (lsEdgeDate.get (i), dap));

  213.         lsAdjustedEdgeDate.add (lsEdgeDate.get (iNumDate - 1));

  214.         if (1 == lsAdjustedEdgeDate.size()) lsAdjustedEdgeDate.add (1, iMaturityDate);

  215.         return lsAdjustedEdgeDate;
  216.     }

  217.     /**
  218.      * Generate a list of period edge dates backward from the end.
  219.      *
  220.      * @param dtEffective Effective date
  221.      * @param dtMaturity Maturity date
  222.      * @param strTenor Period Tenor
  223.      * @param dap Inner Date Adjustment Parameters
  224.      * @param iPSEC Period Set Edge Customizer Setting
  225.      *
  226.      * @return List of Period Edge Dates
  227.      */

  228.     public static final java.util.List<java.lang.Integer> BackwardEdgeDates (
  229.         final org.drip.analytics.date.JulianDate dtEffective,
  230.         final org.drip.analytics.date.JulianDate dtMaturity,
  231.         final java.lang.String strTenor,
  232.         final org.drip.analytics.daycount.DateAdjustParams dap,
  233.         final int iPSEC)
  234.     {
  235.         if (null == dtEffective || null == dtMaturity || null == strTenor || strTenor.isEmpty()) return null;

  236.         int iEffectiveDate = dtEffective.julian();

  237.         java.lang.String strPeriodRollTenor = "";
  238.         org.drip.analytics.date.JulianDate dtEdge = dtMaturity;

  239.         int iEdgeDate = dtEdge.julian();

  240.         if (iEffectiveDate >= iEdgeDate) return null;

  241.         java.util.List<java.lang.Integer> lsEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  242.         while (iEdgeDate > iEffectiveDate) {
  243.             lsEdgeDate.add (0, iEdgeDate);

  244.             strPeriodRollTenor = org.drip.analytics.support.Helper.AggregateTenor (strPeriodRollTenor,
  245.                 strTenor);

  246.             if (null == (dtEdge = dtMaturity.subtractTenor (strPeriodRollTenor))) return null;

  247.             iEdgeDate = dtEdge.julian();
  248.         }

  249.         if (iEdgeDate < iEffectiveDate) {
  250.             if (SHORT_STUB == iPSEC)
  251.                 lsEdgeDate.add (0, iEffectiveDate);
  252.             else if (FULL_FRONT_PERIOD == iPSEC)
  253.                 lsEdgeDate.add (0, iEdgeDate);
  254.             else if (LONG_STUB == iPSEC) {
  255.                 if (1 != lsEdgeDate.size()) lsEdgeDate.remove (0);

  256.                 lsEdgeDate.add (0, iEffectiveDate);
  257.             }
  258.         } else if (dtEdge.julian() == iEffectiveDate)
  259.             lsEdgeDate.add (0, iEffectiveDate);

  260.         java.util.List<java.lang.Integer> lsAdjustedEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  261.         lsAdjustedEdgeDate.add (lsEdgeDate.get (0));

  262.         int iNumDate = lsEdgeDate.size();

  263.         for (int i = 1; i < iNumDate - 1; ++i)
  264.             lsAdjustedEdgeDate.add (DAPAdjust (lsEdgeDate.get (i), dap));

  265.         lsAdjustedEdgeDate.add (lsEdgeDate.get (iNumDate - 1));

  266.         return lsAdjustedEdgeDate;
  267.     }

  268.     /**
  269.      * Generate a list of regular period edge dates forward from the start.
  270.      *
  271.      * @param dtEffective Effective date
  272.      * @param strPeriodTenor Period Tenor
  273.      * @param strMaturityTenor Period Tenor
  274.      * @param dap Inner Date Adjustment Parameters
  275.      *
  276.      * @return List of Period Edge Dates
  277.      */

  278.     public static final java.util.List<java.lang.Integer> RegularEdgeDates (
  279.         final org.drip.analytics.date.JulianDate dtEffective,
  280.         final java.lang.String strPeriodTenor,
  281.         final java.lang.String strMaturityTenor,
  282.         final org.drip.analytics.daycount.DateAdjustParams dap)
  283.     {
  284.         if (null == dtEffective || null == strPeriodTenor || strPeriodTenor.isEmpty() || null ==
  285.             strMaturityTenor || strMaturityTenor.isEmpty())
  286.             return null;

  287.         int iPeriodTenorMonth = -1;
  288.         int iMaturityTenorMonth = -1;
  289.         int iPeriodMaturityTenorComparison = -1;

  290.         int iMaturityDate = dtEffective.addTenor (strMaturityTenor).julian();

  291.         java.util.List<java.lang.Integer> lsEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  292.         try {
  293.             iPeriodMaturityTenorComparison = org.drip.analytics.support.Helper.TenorCompare (strPeriodTenor,
  294.                 strMaturityTenor);
  295.         } catch (java.lang.Exception e) {
  296.             e.printStackTrace();

  297.             return null;
  298.         }

  299.         if (org.drip.analytics.support.Helper.LEFT_TENOR_EQUALS == iPeriodMaturityTenorComparison ||
  300.             org.drip.analytics.support.Helper.LEFT_TENOR_GREATER == iPeriodMaturityTenorComparison) {
  301.             lsEdgeDate.add (dtEffective.julian());

  302.             lsEdgeDate.add (iMaturityDate);

  303.             return lsEdgeDate;
  304.         }

  305.         try {
  306.             iPeriodTenorMonth = org.drip.analytics.support.Helper.TenorToMonths (strPeriodTenor);

  307.             iMaturityTenorMonth = org.drip.analytics.support.Helper.TenorToMonths (strMaturityTenor);
  308.         } catch (java.lang.Exception e) {
  309.             e.printStackTrace();

  310.             return null;
  311.         }

  312.         org.drip.analytics.date.JulianDate dtEdge = dtEffective;
  313.         int iNumPeriod = iMaturityTenorMonth / iPeriodTenorMonth;

  314.         lsEdgeDate.add (dtEdge.julian());

  315.         for (int i = 0; i < iNumPeriod; ++i) {
  316.             dtEdge = dtEdge.addTenor (strPeriodTenor);

  317.             int iEdgeDate = dtEdge.julian();

  318.             if (iEdgeDate < iMaturityDate) lsEdgeDate.add (DAPAdjust (iEdgeDate, dap));
  319.         }

  320.         lsEdgeDate.add (iMaturityDate);

  321.         return lsEdgeDate;
  322.     }

  323.     /**
  324.      * Generate a list of regular period edge dates forward from the start.
  325.      *
  326.      * @param iStartDate Start Date
  327.      * @param iEndDate End Date
  328.      * @param strPeriodTenor Period Tenor
  329.      * @param dap Inner Date Adjustment Parameters
  330.      *
  331.      * @return List of Period Edge Dates
  332.      */

  333.     public static final java.util.List<java.lang.Integer> RegularEdgeDates (
  334.         final int iStartDate,
  335.         final int iEndDate,
  336.         final java.lang.String strPeriodTenor,
  337.         final org.drip.analytics.daycount.DateAdjustParams dap)
  338.     {
  339.         if (iStartDate >= iEndDate || null == strPeriodTenor || strPeriodTenor.isEmpty()) return null;

  340.         java.util.List<java.lang.Integer> lsEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  341.         int iEdgeDate = iStartDate;

  342.         org.drip.analytics.date.JulianDate dtEdge = new org.drip.analytics.date.JulianDate (iStartDate);

  343.         while (iEdgeDate < iEndDate) {
  344.             int iAdjustedEdgeDate = DAPAdjust (iEdgeDate, dap);

  345.             if (!lsEdgeDate.contains (iAdjustedEdgeDate)) lsEdgeDate.add (iAdjustedEdgeDate);

  346.             if (null == (dtEdge = dtEdge.addTenor (strPeriodTenor))) return null;

  347.             iEdgeDate = dtEdge.julian();
  348.         }

  349.         if (!lsEdgeDate.contains (iEndDate)) lsEdgeDate.add (iEndDate);

  350.         return lsEdgeDate;
  351.     }

  352.     /**
  353.      * Generate a list of the IMM period edge dates forward from the spot date.
  354.      *
  355.      * @param dtSpot Spot Date
  356.      * @param iRollMonths Number of Months to Roll to the Next IMM Date
  357.      * @param strPeriodTenor Period Tenor
  358.      * @param strMaturityTenor Period Tenor
  359.      * @param dap Inner Date Adjustment Parameters
  360.      *
  361.      * @return List of IMM Period Edge Dates
  362.      */

  363.     public static final java.util.List<java.lang.Integer> IMMEdgeDates (
  364.         final org.drip.analytics.date.JulianDate dtSpot,
  365.         final int iRollMonths,
  366.         final java.lang.String strPeriodTenor,
  367.         final java.lang.String strMaturityTenor,
  368.         final org.drip.analytics.daycount.DateAdjustParams dap)
  369.     {
  370.         if (null == dtSpot) return null;

  371.         try {
  372.             return RegularEdgeDates (dtSpot.nextRatesFuturesIMM (iRollMonths), strPeriodTenor,
  373.                 strMaturityTenor, dap);
  374.         } catch (java.lang.Exception e) {
  375.             e.printStackTrace();
  376.         }

  377.         return null;
  378.     }

  379.     /**
  380.      * Generate the List of Overnight Edge Dates between the specified dates, using the specified Calendar
  381.      *
  382.      * @param dtStart Start Date
  383.      * @param dtEnd End Date
  384.      * @param strCalendar Calendar
  385.      *
  386.      * @return List of Overnight Edge Dates
  387.      */

  388.     public static final java.util.List<java.lang.Integer> OvernightEdgeDates (
  389.         final org.drip.analytics.date.JulianDate dtStart,
  390.         final org.drip.analytics.date.JulianDate dtEnd,
  391.         final java.lang.String strCalendar)
  392.     {
  393.         if (null == dtStart || null == dtEnd) return null;

  394.         org.drip.analytics.date.JulianDate dtEdge = dtStart;

  395.         int iEndDate = dtEnd.julian();

  396.         int iEdgeDate = dtEdge.julian();

  397.         if (iEndDate <= iEdgeDate) return null;

  398.         java.util.List<java.lang.Integer> lsOvernightEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  399.         while (iEdgeDate < iEndDate) {
  400.             lsOvernightEdgeDate.add (iEdgeDate);

  401.             if (null == (dtEdge = dtEdge.addBusDays (1, strCalendar))) return null;

  402.             iEdgeDate = dtEdge.julian();
  403.         }

  404.         lsOvernightEdgeDate.add (iEndDate);

  405.         return lsOvernightEdgeDate;
  406.     }

  407.     /**
  408.      * Generate a single Spanning Edge Pair between the specified dates, using the specified Calendar
  409.      *
  410.      * @param dtStart Start Date
  411.      * @param dtEnd End Date
  412.      *
  413.      * @return List Containing the Pair
  414.      */

  415.     public static final java.util.List<java.lang.Integer> EdgePair (
  416.         final org.drip.analytics.date.JulianDate dtStart,
  417.         final org.drip.analytics.date.JulianDate dtEnd)
  418.     {
  419.         if (null == dtStart || null == dtEnd) return null;

  420.         int iEndDate = dtEnd.julian();

  421.         int iStartDate = dtStart.julian();

  422.         if (iEndDate <= iStartDate) return null;

  423.         java.util.List<java.lang.Integer> lsOvernightEdgeDate = new java.util.ArrayList<java.lang.Integer>();

  424.         lsOvernightEdgeDate.add (iStartDate);

  425.         lsOvernightEdgeDate.add (iEndDate);

  426.         return lsOvernightEdgeDate;
  427.     }

  428.     /**
  429.      * Construct a Reference Period using the Start/End Dates, the Floater Label, and the Reference Period
  430.      *  Arrears Type
  431.      *
  432.      * @param dtStart Start Date
  433.      * @param dtEnd End Date
  434.      * @param floaterLabel Floater Label
  435.      * @param iReferencePeriodArrearsType Reference Period Arrears Type
  436.      *
  437.      * @return The Reference Period
  438.      */

  439.     public static final org.drip.analytics.cashflow.ReferenceIndexPeriod ReferencePeriod (
  440.         final org.drip.analytics.date.JulianDate dtStart,
  441.         final org.drip.analytics.date.JulianDate dtEnd,
  442.         final org.drip.state.identifier.FloaterLabel floaterLabel,
  443.         final int iReferencePeriodArrearsType)
  444.     {
  445.         if (null == dtStart || null == dtEnd || null == floaterLabel) return null;

  446.         java.lang.String strForwardTenor = "";

  447.         if (floaterLabel instanceof org.drip.state.identifier.ForwardLabel)
  448.             strForwardTenor = floaterLabel.tenor();
  449.         else if (floaterLabel instanceof org.drip.state.identifier.OTCFixFloatLabel)
  450.             strForwardTenor = ((org.drip.state.identifier.OTCFixFloatLabel) floaterLabel).fixFloatTenor();

  451.         try {
  452.             return org.drip.analytics.cashflow.ReferenceIndexPeriod.Standard (
  453.                 REFERENCE_PERIOD_IN_ARREARS == iReferencePeriodArrearsType ? dtStart.addTenor
  454.                     (strForwardTenor).julian() : dtStart.julian(),
  455.                 REFERENCE_PERIOD_IN_ARREARS == iReferencePeriodArrearsType ? dtEnd.addTenor
  456.                     (strForwardTenor).julian() : dtEnd.julian(),
  457.                 floaterLabel
  458.             );
  459.         } catch (java.lang.Exception e) {
  460.             e.printStackTrace();
  461.         }

  462.         return null;
  463.     }

  464.     /**
  465.      * Generate a list of period edge dates forward from the start.
  466.      *
  467.      * @param iEffective Effective Date
  468.      * @param iMaturity Maturity Date
  469.      * @param strTenor Period Tenor
  470.      * @param dap Inner Date Adjustment Parameters
  471.      * @param iPSEC Period Set Edge Customizer Setting
  472.      *
  473.      * @return List of Period Edge Dates
  474.      */

  475.     public static final java.util.List<java.lang.Integer> ForwardEdgeDates (
  476.         final int iEffective,
  477.         final int iMaturity,
  478.         final java.lang.String strTenor,
  479.         final org.drip.analytics.daycount.DateAdjustParams dap,
  480.         final int iPSEC)
  481.     {
  482.         return ForwardEdgeDates (new org.drip.analytics.date.JulianDate (iEffective), new
  483.             org.drip.analytics.date.JulianDate (iMaturity), strTenor, dap, iPSEC);
  484.     }

  485.     /**
  486.      * Generate a list of period edge dates backward from the end.
  487.      *
  488.      * @param iEffective Effective Date
  489.      * @param iMaturity Maturity Date
  490.      * @param strTenor Period Tenor
  491.      * @param dap Inner Date Adjustment Parameters
  492.      * @param iPSEC Period Set Edge Customizer Setting
  493.      *
  494.      * @return List of Period Edge Dates
  495.      */

  496.     public static final java.util.List<java.lang.Integer> BackwardEdgeDates (
  497.         final int iEffective,
  498.         final int iMaturity,
  499.         final java.lang.String strTenor,
  500.         final org.drip.analytics.daycount.DateAdjustParams dap,
  501.         final int iPSEC)
  502.     {
  503.         return BackwardEdgeDates (new org.drip.analytics.date.JulianDate (iEffective), new
  504.             org.drip.analytics.date.JulianDate (iMaturity), strTenor, dap, iPSEC);
  505.     }

  506.     /**
  507.      * Generate a list of regular period edge dates forward from the start.
  508.      *
  509.      * @param iEffective Effective Date
  510.      * @param strPeriodTenor Period Tenor
  511.      * @param strMaturityTenor Period Tenor
  512.      * @param dap Inner Date Adjustment Parameters
  513.      *
  514.      * @return List of Period Edge Dates
  515.      */

  516.     public static final java.util.List<java.lang.Integer> RegularEdgeDates (
  517.         final int iEffective,
  518.         final java.lang.String strPeriodTenor,
  519.         final java.lang.String strMaturityTenor,
  520.         final org.drip.analytics.daycount.DateAdjustParams dap)
  521.     {
  522.         return RegularEdgeDates (new org.drip.analytics.date.JulianDate (iEffective), strPeriodTenor,
  523.             strMaturityTenor, dap);
  524.     }

  525.     /**
  526.      * Generate the List of Overnight Edge Dates between the specified dates, using the specified Calendar
  527.      *
  528.      * @param iStartDate Start Date
  529.      * @param iEndDate End Date
  530.      * @param strCalendar Calendar
  531.      *
  532.      * @return List of Overnight Edge Dates
  533.      */

  534.     public static final java.util.List<java.lang.Integer> OvernightEdgeDates (
  535.         final int iStartDate,
  536.         final int iEndDate,
  537.         final java.lang.String strCalendar)
  538.     {
  539.         return OvernightEdgeDates (new org.drip.analytics.date.JulianDate (iStartDate), new
  540.             org.drip.analytics.date.JulianDate (iEndDate), strCalendar);
  541.     }

  542.     /**
  543.      * Construct a Reference Index Period using the Start/End Dates, the Floater Label, and the Reference
  544.      *  Period Arrears Type
  545.      *
  546.      * @param iStartDate Start Date
  547.      * @param iEndDate End Date
  548.      * @param floaterLabel Floater Label
  549.      * @param iReferencePeriodArrearsType Reference Period Arrears Type
  550.      *
  551.      * @return The Reference Period
  552.      */

  553.     public static final org.drip.analytics.cashflow.ReferenceIndexPeriod ReferencePeriod (
  554.         final int iStartDate,
  555.         final int iEndDate,
  556.         final org.drip.state.identifier.FloaterLabel floaterLabel,
  557.         final int iReferencePeriodArrearsType)
  558.     {
  559.         return ReferencePeriod (
  560.             new org.drip.analytics.date.JulianDate (iStartDate),
  561.             new org.drip.analytics.date.JulianDate (iEndDate),
  562.             floaterLabel,
  563.             iReferencePeriodArrearsType
  564.         );
  565.     }

  566.     /**
  567.      * Retrieve the List of Edge Dates across all Units
  568.      *
  569.      * @param iUnitPeriodStartDate Unit Period Start Date
  570.      * @param iUnitPeriodEndDate Unit Period End Date
  571.      * @param strCalendar Unit Date Generation Calendar
  572.      * @param cubs Composable Unit Builder Setting
  573.      *
  574.      * @return List of Edge Dates across all Units
  575.      */

  576.     public static final java.util.List<java.lang.Integer> UnitDateEdges (
  577.         final int iUnitPeriodStartDate,
  578.         final int iUnitPeriodEndDate,
  579.         final java.lang.String strCalendar,
  580.         final org.drip.param.period.ComposableUnitBuilderSetting cubs)
  581.     {
  582.         if (null == cubs) return null;

  583.         int iEdgeDateSequenceScheme = cubs.edgeDateSequenceScheme();

  584.         if (EDGE_DATE_SEQUENCE_SINGLE == iEdgeDateSequenceScheme) {
  585.             if (iUnitPeriodStartDate >= iUnitPeriodEndDate) return null;

  586.             java.util.List<java.lang.Integer> lsEdgeDates = new java.util.ArrayList<java.lang.Integer>();

  587.             lsEdgeDates.add (iUnitPeriodStartDate);

  588.             lsEdgeDates.add (iUnitPeriodEndDate);

  589.             return lsEdgeDates;
  590.         }

  591.         if (EDGE_DATE_SEQUENCE_REGULAR == iEdgeDateSequenceScheme)
  592.             return RegularEdgeDates (iUnitPeriodStartDate, iUnitPeriodEndDate, cubs.tenor(), cubs.dapEdge());

  593.         if (EDGE_DATE_SEQUENCE_OVERNIGHT == iEdgeDateSequenceScheme)
  594.             return OvernightEdgeDates (iUnitPeriodStartDate, iUnitPeriodEndDate, strCalendar);

  595.         return null;
  596.     }

  597.     /**
  598.      * Construct the List of Composable Fixed Units from the inputs
  599.      *
  600.      * @param iUnitPeriodStartDate Unit Period Start Date
  601.      * @param iUnitPeriodEndDate Unit Period End Date
  602.      * @param ucas Unit Coupon/Accrual Setting
  603.      * @param cfus Composable Fixed Unit Setting
  604.      *
  605.      * @return The List of Composable Floating Units
  606.      */

  607.     public static final java.util.List<org.drip.analytics.cashflow.ComposableUnitPeriod> FixedUnits (
  608.         final int iUnitPeriodStartDate,
  609.         final int iUnitPeriodEndDate,
  610.         final org.drip.param.period.UnitCouponAccrualSetting ucas,
  611.         final org.drip.param.period.ComposableFixedUnitSetting cfus)
  612.     {
  613.         if (null == cfus) return null;

  614.         java.util.List<java.lang.Integer> lsUnitEdgeDate = UnitDateEdges (iUnitPeriodStartDate,
  615.             iUnitPeriodEndDate, ucas.calendar(), cfus);

  616.         if (null == lsUnitEdgeDate) return null;

  617.         int iNumDate = lsUnitEdgeDate.size();

  618.         if (2 > iNumDate) return null;

  619.         java.util.List<org.drip.analytics.cashflow.ComposableUnitPeriod> lsCUP = new
  620.             java.util.ArrayList<org.drip.analytics.cashflow.ComposableUnitPeriod>();

  621.         for (int i = 1; i < iNumDate; ++i) {
  622.             try {
  623.                 lsCUP.add (new org.drip.analytics.cashflow.ComposableUnitFixedPeriod (lsUnitEdgeDate.get
  624.                     (i - 1), lsUnitEdgeDate.get (i), ucas, cfus));
  625.             } catch (java.lang.Exception e) {
  626.                 e.printStackTrace();

  627.                 return null;
  628.             }
  629.         }

  630.         return lsCUP;
  631.     }

  632.     /**
  633.      * Construct the List of Composable Floating Units from the inputs
  634.      *
  635.      * @param iUnitPeriodStartDate Unit Period Start Date
  636.      * @param iUnitPeriodEndDate Unit Period End Date
  637.      * @param cfus Composable Floating Unit Setting
  638.      *
  639.      * @return The List of Composable Floating Units
  640.      */

  641.     public static final java.util.List<org.drip.analytics.cashflow.ComposableUnitPeriod> FloatingUnits (
  642.         final int iUnitPeriodStartDate,
  643.         final int iUnitPeriodEndDate,
  644.         final org.drip.param.period.ComposableFloatingUnitSetting cfus)
  645.     {
  646.         if (null == cfus) return null;

  647.         org.drip.state.identifier.FloaterLabel floaterLabel = cfus.floaterLabel();

  648.         java.lang.String strCalendar = floaterLabel.floaterIndex().calendar();

  649.         java.util.List<java.lang.Integer> lsUnitEdgeDate = UnitDateEdges (iUnitPeriodStartDate,
  650.             iUnitPeriodEndDate, strCalendar, cfus);

  651.         if (null == lsUnitEdgeDate) return null;

  652.         int iNumDate = lsUnitEdgeDate.size();

  653.         if (2 > iNumDate) return null;

  654.         java.util.List<org.drip.analytics.cashflow.ComposableUnitPeriod> lsCUP = new
  655.             java.util.ArrayList<org.drip.analytics.cashflow.ComposableUnitPeriod>();

  656.         double dblSpread = cfus.spread();

  657.         java.lang.String strUnitTenor = cfus.tenor();

  658.         java.lang.String strForwardTenor = floaterLabel.tenor();

  659.         int iReferencePeriodArrearsType = cfus.referencePeriodArrearsType();

  660.         boolean bComposableForwardPeriodsMatch = cfus.tenor().equalsIgnoreCase (strForwardTenor);

  661.         for (int i = 1; i < iNumDate; ++i) {
  662.             int iUnitStartDate = lsUnitEdgeDate.get (i - 1);

  663.             int iUnitEndDate = lsUnitEdgeDate.get (i);

  664.             int iReferencePeriodEndDate = iUnitEndDate;

  665.             int iReferencePeriodStartDate = bComposableForwardPeriodsMatch ? iUnitStartDate : new
  666.                 org.drip.analytics.date.JulianDate (iUnitEndDate).subtractTenorAndAdjust (strForwardTenor,
  667.                     strCalendar).julian();

  668.             try {
  669.                 lsCUP.add (
  670.                     new org.drip.analytics.cashflow.ComposableUnitFloatingPeriod (
  671.                         iUnitStartDate,
  672.                         iUnitEndDate,
  673.                         strUnitTenor,
  674.                         ReferencePeriod (
  675.                             iReferencePeriodStartDate,
  676.                             iReferencePeriodEndDate,
  677.                             floaterLabel,
  678.                             iReferencePeriodArrearsType
  679.                         ),
  680.                         dblSpread
  681.                     )
  682.                 );
  683.             } catch (java.lang.Exception e) {
  684.                 e.printStackTrace();

  685.                 return null;
  686.             }
  687.         }

  688.         return lsCUP;
  689.     }

  690.     /**
  691.      * Construct the List of Composite Fixed Periods from the corresponding Composable Fixed Period Units
  692.      *
  693.      * @param lsCompositeEdgeDate The Composite Period Edge Dates
  694.      * @param cps Composite Period Setting Instance
  695.      * @param ucas Unit Coupon/Accrual Setting
  696.      * @param cfus Composable Fixed Unit Setting
  697.      *
  698.      * @return List of Composite Fixed Periods
  699.      */

  700.     public static final java.util.List<org.drip.analytics.cashflow.CompositePeriod> FixedCompositeUnit (
  701.         final java.util.List<java.lang.Integer> lsCompositeEdgeDate,
  702.         final org.drip.param.period.CompositePeriodSetting cps,
  703.         final org.drip.param.period.UnitCouponAccrualSetting ucas,
  704.         final org.drip.param.period.ComposableFixedUnitSetting cfus)
  705.     {
  706.         if (null == lsCompositeEdgeDate) return null;

  707.         int iNumEdge = lsCompositeEdgeDate.size();

  708.         if (2 > iNumEdge) return null;

  709.         java.util.List<org.drip.analytics.cashflow.CompositePeriod> lsCFP = new
  710.             java.util.ArrayList<org.drip.analytics.cashflow.CompositePeriod>();

  711.         for (int i = 1; i < iNumEdge; ++i) {
  712.             try {
  713.                 lsCFP.add (new org.drip.analytics.cashflow.CompositeFixedPeriod (cps, FixedUnits
  714.                     (lsCompositeEdgeDate.get (i - 1), lsCompositeEdgeDate.get (i), ucas, cfus)));
  715.             } catch (java.lang.Exception e) {
  716.                 e.printStackTrace();

  717.                 return null;
  718.             }
  719.         }

  720.         return lsCFP;
  721.     }

  722.     /**
  723.      * Construct the List of Composite Floating Period from the corresponding Composable Floating Period
  724.      *  Units
  725.      *
  726.      * @param lsCompositeEdgeDate The Composite Period Edge Dates
  727.      * @param cps Composite Period Setting Instance
  728.      * @param cfus Composable Floating Unit Setting
  729.      *
  730.      * @return List of Composite Floating Periods
  731.      */

  732.     public static final java.util.List<org.drip.analytics.cashflow.CompositePeriod> FloatingCompositeUnit (
  733.         final java.util.List<java.lang.Integer> lsCompositeEdgeDate,
  734.         final org.drip.param.period.CompositePeriodSetting cps,
  735.         final org.drip.param.period.ComposableFloatingUnitSetting cfus)
  736.     {
  737.         if (null == lsCompositeEdgeDate) return null;

  738.         int iNumEdge = lsCompositeEdgeDate.size();

  739.         if (2 > iNumEdge) return null;

  740.         java.util.List<org.drip.analytics.cashflow.CompositePeriod> lsCFP = new
  741.             java.util.ArrayList<org.drip.analytics.cashflow.CompositePeriod>();

  742.         for (int i = 1; i < iNumEdge; ++i) {
  743.             try {
  744.                 lsCFP.add (new org.drip.analytics.cashflow.CompositeFloatingPeriod (cps, FloatingUnits
  745.                     (lsCompositeEdgeDate.get (i - 1), lsCompositeEdgeDate.get (i), cfus)));
  746.             } catch (java.lang.Exception e) {
  747.                 e.printStackTrace();

  748.                 return null;
  749.             }
  750.         }

  751.         return lsCFP;
  752.     }
  753. }