OTCInstrumentBuilder.java

  1. package org.drip.service.template;

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

  78. /**
  79.  * <i>OTCInstrumentBuilder</i> contains static Helper API to facilitate Construction of OTC Instruments.
  80.  *
  81.  * <br><br>
  82.  *  <ul>
  83.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  84.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationSupportLibrary.md">Computation Support</a></li>
  85.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/service/README.md">Environment, Product/Definition Containers, and Scenario/State Manipulation APIs</a></li>
  86.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/service/template/README.md">Curve Construction Product Builder Templates</a></li>
  87.  *  </ul>
  88.  * <br><br>
  89.  *
  90.  * @author Lakshmi Krishnamurthy
  91.  */

  92. public class OTCInstrumentBuilder {

  93.     /**
  94.      * Construct an OTC Funding Deposit Instrument from the Spot Date and the Maturity Tenor
  95.      *
  96.      * @param dtSpot The Spot Date
  97.      * @param strCurrency Currency
  98.      * @param strMaturityTenor The Maturity Tenor
  99.      *
  100.      * @return Funding Deposit Instrument Instance from the Spot Date and the corresponding Maturity Tenor
  101.      */

  102.     public static final org.drip.product.rates.SingleStreamComponent FundingDeposit (
  103.         final org.drip.analytics.date.JulianDate dtSpot,
  104.         final java.lang.String strCurrency,
  105.         final java.lang.String strMaturityTenor)
  106.     {
  107.         if (null == dtSpot || null == strCurrency || strCurrency.isEmpty() || null == strMaturityTenor ||
  108.             strMaturityTenor.isEmpty())
  109.             return null;

  110.         org.drip.market.otc.FixedFloatSwapConvention ffsc =
  111.             org.drip.market.otc.IBORFixedFloatContainer.ConventionFromJurisdiction (strCurrency, "ALL",
  112.                 strMaturityTenor, "MAIN");

  113.         if (null == ffsc) return null;

  114.         org.drip.state.identifier.ForwardLabel forwardLabel = ffsc.floatStreamConvention().floaterIndex();

  115.         org.drip.analytics.date.JulianDate dtEffective = dtSpot.addBusDays (0, strCurrency);

  116.         try {
  117.             java.lang.String strFloaterTenor = forwardLabel.tenor();

  118.             org.drip.analytics.date.JulianDate dtMaturity = strMaturityTenor.contains ("D") ? new
  119.                 org.drip.analytics.date.JulianDate (org.drip.analytics.daycount.Convention.AddBusinessDays
  120.                     (dtEffective.julian(), org.drip.analytics.support.Helper.TenorToDays (strMaturityTenor),
  121.                         strCurrency)) : dtEffective.addTenorAndAdjust (strMaturityTenor, strCurrency);

  122.             return new org.drip.product.rates.SingleStreamComponent ("DEPOSIT_" + strMaturityTenor, new
  123.                 org.drip.product.rates.Stream
  124.                     (org.drip.analytics.support.CompositePeriodBuilder.FloatingCompositeUnit
  125.                         (org.drip.analytics.support.CompositePeriodBuilder.EdgePair (dtEffective,
  126.                             dtMaturity), new org.drip.param.period.CompositePeriodSetting
  127.                                 (org.drip.analytics.support.Helper.TenorToFreq (strFloaterTenor),
  128.                                     strFloaterTenor, strCurrency, null, 1., null, null, null, null), new
  129.                                         org.drip.param.period.ComposableFloatingUnitSetting (strFloaterTenor,
  130.                                             org.drip.analytics.support.CompositePeriodBuilder.EDGE_DATE_SEQUENCE_SINGLE,
  131.                 null, org.drip.state.identifier.ForwardLabel.Create (strCurrency, strFloaterTenor),
  132.                     org.drip.analytics.support.CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE, 0.))),
  133.                         null);
  134.         } catch (java.lang.Exception e) {
  135.             e.printStackTrace();
  136.         }

  137.         return null;
  138.     }

  139.     /**
  140.      * Construct an OTC Forward Deposit Instrument from Spot Date and the Maturity Tenor
  141.      *
  142.      * @param dtSpot The Spot Date
  143.      * @param strMaturityTenor The Maturity Tenor
  144.      * @param forwardLabel The Forward Label
  145.      *
  146.      * @return Forward Deposit Instrument Instance from the Spot Date and the corresponding Maturity Tenor
  147.      */

  148.     public static final org.drip.product.rates.SingleStreamComponent ForwardRateDeposit (
  149.         final org.drip.analytics.date.JulianDate dtSpot,
  150.         final java.lang.String strMaturityTenor,
  151.         final org.drip.state.identifier.ForwardLabel forwardLabel)
  152.     {
  153.         if (null == dtSpot || null == forwardLabel) return null;

  154.         java.lang.String strCalendar = forwardLabel.currency();

  155.         org.drip.analytics.date.JulianDate dtEffective = dtSpot.addBusDays (0, strCalendar);

  156.         return org.drip.product.creator.SingleStreamComponentBuilder.Deposit (dtEffective,
  157.             dtEffective.addTenor (strMaturityTenor), forwardLabel);
  158.     }

  159.     /**
  160.      * Construct an OTC Overnight Deposit Instrument from the Spot Date and the Maturity Tenor
  161.      *
  162.      * @param dtSpot The Spot Date
  163.      * @param strCurrency Currency
  164.      * @param strMaturityTenor The Maturity Tenor
  165.      *
  166.      * @return Overnight Deposit Instrument Instance from the Spot Date and the corresponding Maturity Tenor
  167.      */

  168.     public static final org.drip.product.rates.SingleStreamComponent OvernightDeposit (
  169.         final org.drip.analytics.date.JulianDate dtSpot,
  170.         final java.lang.String strCurrency,
  171.         final java.lang.String strMaturityTenor)
  172.     {
  173.         if (null == dtSpot) return null;

  174.         org.drip.state.identifier.OvernightLabel overnightLabel =
  175.             org.drip.state.identifier.OvernightLabel.Create (strCurrency);

  176.         if (null == overnightLabel) return null;

  177.         org.drip.analytics.date.JulianDate dtEffective = dtSpot.addBusDays (0, strCurrency);

  178.         return null == dtEffective ? null : org.drip.product.creator.SingleStreamComponentBuilder.Deposit
  179.             (dtEffective, dtEffective.addTenorAndAdjust (strMaturityTenor, strCurrency),overnightLabel);
  180.     }

  181.     /**
  182.      * Create a Standard FRA from the Spot Date, the Forward Label, and the Strike
  183.      *
  184.      * @param dtSpot Spot Date
  185.      * @param forwardLabel The Forward Label
  186.      * @param strMaturityTenor Maturity Tenor
  187.      * @param dblStrike Futures Strike
  188.      *
  189.      * @return The Standard FRA Instance
  190.      */

  191.     public static final org.drip.product.fra.FRAStandardComponent FRAStandard (
  192.         final org.drip.analytics.date.JulianDate dtSpot,
  193.         final org.drip.state.identifier.ForwardLabel forwardLabel,
  194.         final java.lang.String strMaturityTenor,
  195.         final double dblStrike)
  196.     {
  197.         return null == dtSpot || null == forwardLabel ? null :
  198.             org.drip.product.creator.SingleStreamComponentBuilder.FRAStandard (dtSpot.addBusDays (0,
  199.                 forwardLabel.currency()).addTenor (strMaturityTenor), forwardLabel, dblStrike);
  200.     }

  201.     /**
  202.      * Construct an OTC Standard Fix Float Swap using the specified Input Parameters
  203.      *
  204.      * @param dtSpot The Spot Date
  205.      * @param strCurrency The OTC Currency
  206.      * @param strLocation Location
  207.      * @param strMaturityTenor Maturity Tenor
  208.      * @param strIndex Index
  209.      * @param dblCoupon Coupon
  210.      *
  211.      * @return The OTC Standard Fix Float Swap constructed using the specified Input Parameters
  212.      */

  213.     public static final org.drip.product.rates.FixFloatComponent FixFloatStandard (
  214.         final org.drip.analytics.date.JulianDate dtSpot,
  215.         final java.lang.String strCurrency,
  216.         final java.lang.String strLocation,
  217.         final java.lang.String strMaturityTenor,
  218.         final java.lang.String strIndex,
  219.         final double dblCoupon)
  220.     {
  221.         if (null == dtSpot) return null;

  222.         org.drip.market.otc.FixedFloatSwapConvention ffsc =
  223.             org.drip.market.otc.IBORFixedFloatContainer.ConventionFromJurisdiction (strCurrency, strLocation,
  224.                 strMaturityTenor, strIndex);

  225.         return null == ffsc ? null : ffsc.createFixFloatComponent (dtSpot.addBusDays (0, strCurrency),
  226.             strMaturityTenor, dblCoupon, 0., 1.);
  227.     }

  228.     /**
  229.      * Construct a Standard Fix Float Swap Instances
  230.      *
  231.      * @param dtSpot The Spot Date
  232.      * @param forwardLabel The Forward Label
  233.      * @param strMaturityTenor Maturity Tenor
  234.      *
  235.      * @return A Standard Fix Float Swap Instances
  236.      */

  237.     public static final org.drip.product.rates.FixFloatComponent FixFloatCustom (
  238.         final org.drip.analytics.date.JulianDate dtSpot,
  239.         final org.drip.state.identifier.ForwardLabel forwardLabel,
  240.         final java.lang.String strMaturityTenor)
  241.     {
  242.         if (null == dtSpot || null == forwardLabel) return null;

  243.         java.lang.String strCurrency = forwardLabel.currency();

  244.         java.lang.String strForwardTenor = forwardLabel.tenor();

  245.         int iTenorInMonths = java.lang.Integer.parseInt (strForwardTenor.split ("M")[0]);

  246.         org.drip.analytics.date.JulianDate dtEffective = dtSpot.addBusDays (0, strCurrency).addDays (2);

  247.         org.drip.market.otc.FixedFloatSwapConvention ffsc =
  248.             org.drip.market.otc.IBORFixedFloatContainer.ConventionFromJurisdiction (strCurrency, "ALL",
  249.                 strMaturityTenor, "MAIN");

  250.         if (null == ffsc) return null;

  251.         try {
  252.             org.drip.param.period.ComposableFloatingUnitSetting cfusFloating = new
  253.                 org.drip.param.period.ComposableFloatingUnitSetting (strForwardTenor,
  254.                     org.drip.analytics.support.CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR, null,
  255.                         forwardLabel,
  256.                             org.drip.analytics.support.CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  257.                                 0.);

  258.             org.drip.param.period.CompositePeriodSetting cpsFloating = new
  259.                 org.drip.param.period.CompositePeriodSetting (12 / iTenorInMonths, strForwardTenor,
  260.                     strCurrency, null, -1., null, null, null, null);

  261.             org.drip.product.rates.Stream floatingStream = new org.drip.product.rates.Stream
  262.                 (org.drip.analytics.support.CompositePeriodBuilder.FloatingCompositeUnit
  263.                     (org.drip.analytics.support.CompositePeriodBuilder.RegularEdgeDates (dtEffective,
  264.                         strForwardTenor, strMaturityTenor, null), cpsFloating, cfusFloating));

  265.             org.drip.product.rates.Stream fixedStream = ffsc.fixedStreamConvention().createStream
  266.                 (dtEffective, strMaturityTenor, 0., 1.);

  267.             org.drip.product.rates.FixFloatComponent ffc = new org.drip.product.rates.FixFloatComponent
  268.                 (fixedStream, floatingStream, null);

  269.             ffc.setPrimaryCode ("FixFloat:" + strMaturityTenor);

  270.             return ffc;
  271.         } catch (java.lang.Exception e) {
  272.             e.printStackTrace();
  273.         }

  274.         return null;
  275.     }

  276.     /**
  277.      * Construct an Instance of OTC OIS Fix Float Swap
  278.      *
  279.      * @param dtSpot Spot Date
  280.      * @param strCurrency Currency
  281.      * @param strMaturityTenor The OIS Maturity Tenor
  282.      * @param dblCoupon The Fixed Coupon Rate
  283.      * @param bFund TRUE - Floater Based off of Fund
  284.      *
  285.      * @return Instance of OIS Fix Float Swap
  286.      */

  287.     public static final org.drip.product.rates.FixFloatComponent OISFixFloat (
  288.         final org.drip.analytics.date.JulianDate dtSpot,
  289.         final java.lang.String strCurrency,
  290.         final java.lang.String strMaturityTenor,
  291.         final double dblCoupon,
  292.         final boolean bFund)
  293.     {
  294.         if (null == dtSpot) return null;

  295.         org.drip.market.otc.FixedFloatSwapConvention ffsc = bFund ?
  296.             org.drip.market.otc.OvernightFixedFloatContainer.FundConventionFromJurisdiction (strCurrency) :
  297.                 org.drip.market.otc.OvernightFixedFloatContainer.IndexConventionFromJurisdiction (strCurrency,
  298.                     strMaturityTenor);

  299.         return null == ffsc ? null : ffsc.createFixFloatComponent (dtSpot.addBusDays (0, strCurrency),
  300.             strMaturityTenor, dblCoupon, 0., 1.);
  301.     }

  302.     /**
  303.      * Construct an OTC Float-Float Swap Instance
  304.      *
  305.      * @param dtSpot Spot Date
  306.      * @param strCurrency Currency
  307.      * @param strDerivedTenor Tenor of the Derived Leg
  308.      * @param strMaturityTenor Maturity Tenor of the Float-Float Swap
  309.      * @param dblBasis The Float-Float Swap Basis
  310.      *
  311.      * @return The OTC Float-Float Swap Instance
  312.      */

  313.     public static final org.drip.product.rates.FloatFloatComponent FloatFloat (
  314.         final org.drip.analytics.date.JulianDate dtSpot,
  315.         final java.lang.String strCurrency,
  316.         final java.lang.String strDerivedTenor,
  317.         final java.lang.String strMaturityTenor,
  318.         final double dblBasis)
  319.     {
  320.         if (null == dtSpot) return null;

  321.         org.drip.market.otc.FloatFloatSwapConvention ffsc =
  322.             org.drip.market.otc.IBORFloatFloatContainer.ConventionFromJurisdiction (strCurrency);

  323.         return null == ffsc ? null : ffsc.createFloatFloatComponent (dtSpot.addBusDays (0, strCurrency),
  324.             strDerivedTenor, strMaturityTenor, dblBasis, 1.);
  325.     }

  326.     /**
  327.      * Create an Instance of the OTC CDS.
  328.      *
  329.      * @param dtSpot The Spot Date
  330.      * @param strMaturityTenor Maturity Tenor
  331.      * @param dblCoupon Coupon
  332.      * @param strCurrency Currency
  333.      * @param strCredit Credit Curve
  334.      *
  335.      * @return The OTC CDS Instance
  336.      */

  337.     public static final org.drip.product.definition.CreditDefaultSwap CDS (
  338.         final org.drip.analytics.date.JulianDate dtSpot,
  339.         final java.lang.String strMaturityTenor,
  340.         final double dblCoupon,
  341.         final java.lang.String strCurrency,
  342.         final java.lang.String strCredit)
  343.     {
  344.         if (null == dtSpot || null == strCurrency) return null;

  345.         org.drip.analytics.date.JulianDate dtFirstCoupon = dtSpot.addBusDays (0, strCurrency).nextCreditIMM
  346.             (3);

  347.         return null == dtFirstCoupon ? null : org.drip.product.creator.CDSBuilder.CreateCDS
  348.             (dtFirstCoupon.subtractTenor ("3M"), dtFirstCoupon.addTenor (strMaturityTenor), dblCoupon,
  349.                 strCurrency, "CAD".equalsIgnoreCase (strCurrency) || "EUR".equalsIgnoreCase (strCurrency) ||
  350.                     "GBP".equalsIgnoreCase (strCurrency) || "HKD".equalsIgnoreCase (strCurrency) ||
  351.                         "USD".equalsIgnoreCase (strCurrency) ? 0.40 : 0.25, strCredit, strCurrency, true);
  352.     }

  353.     /**
  354.      * Create an OTC FX Forward Component
  355.      *
  356.      * @param dtSpot Spot Date
  357.      * @param ccyPair Currency Pair
  358.      * @param strMaturityTenor Maturity Tenor
  359.      *
  360.      * @return The OTC FX Forward Component Instance
  361.      */

  362.     public static final org.drip.product.fx.FXForwardComponent FXForward (
  363.         final org.drip.analytics.date.JulianDate dtSpot,
  364.         final org.drip.product.params.CurrencyPair ccyPair,
  365.         final java.lang.String strMaturityTenor)
  366.     {
  367.         if (null == dtSpot || null == ccyPair) return null;

  368.         org.drip.analytics.date.JulianDate dtEffective = dtSpot.addBusDays (0, ccyPair.denomCcy());

  369.         try {
  370.             return new org.drip.product.fx.FXForwardComponent ("FXFWD::" + ccyPair.code() + "::" +
  371.                 strMaturityTenor, ccyPair, dtEffective.julian(), dtEffective.addTenor
  372.                     (strMaturityTenor).julian(), 1., null);
  373.         } catch (java.lang.Exception e) {
  374.             e.printStackTrace();
  375.         }

  376.         return null;
  377.     }

  378.     /**
  379.      * Construct an Array of OTC Funding Deposit Instruments from their corresponding Maturity Tenors
  380.      *
  381.      * @param dtSpot Spot Date
  382.      * @param strCurrency Currency
  383.      * @param astrMaturityTenor Array of Maturity Tenors
  384.      *
  385.      * @return Array of OTC Funding Deposit Instruments from their corresponding Maturity Tenors
  386.      */

  387.     public static final org.drip.product.rates.SingleStreamComponent[] FundingDeposit (
  388.         final org.drip.analytics.date.JulianDate dtSpot,
  389.         final java.lang.String strCurrency,
  390.         final java.lang.String[] astrMaturityTenor)
  391.     {
  392.         if (null == astrMaturityTenor) return null;

  393.         int iNumDeposit = astrMaturityTenor.length;
  394.         org.drip.product.rates.SingleStreamComponent[] aSSCDeposit = new
  395.             org.drip.product.rates.SingleStreamComponent[iNumDeposit];

  396.         if (0 == iNumDeposit) return null;

  397.         for (int i = 0; i < astrMaturityTenor.length; ++i) {
  398.             if (null == (aSSCDeposit[i] = FundingDeposit (dtSpot, strCurrency, astrMaturityTenor[i])))
  399.                 return null;

  400.             aSSCDeposit[i].setPrimaryCode (astrMaturityTenor[i]);
  401.         }

  402.         return aSSCDeposit;
  403.     }

  404.     /**
  405.      * Construct an Array of OTC Funding Deposit and Futures Instruments
  406.      *
  407.      * @param dtSpot Spot Date
  408.      * @param strCurrency Currency
  409.      * @param astrDepositMaturityTenor Array of Deposit Maturity Tenors
  410.      * @param iNumFutures Number of Serial Futures to be included
  411.      *
  412.      * @return Array of OTC Funding Deposit Instruments from their corresponding Maturity Tenors
  413.      */

  414.     public static final org.drip.product.rates.SingleStreamComponent[] FundingDepositFutures (
  415.         final org.drip.analytics.date.JulianDate dtSpot,
  416.         final java.lang.String strCurrency,
  417.         final java.lang.String[] astrDepositMaturityTenor,
  418.         final int iNumFutures)
  419.     {
  420.         if (null == astrDepositMaturityTenor) return null;

  421.         int iNumDeposit = astrDepositMaturityTenor.length;
  422.         org.drip.product.rates.SingleStreamComponent[] aSSCDepositFutures = new
  423.             org.drip.product.rates.SingleStreamComponent[iNumDeposit + iNumFutures];

  424.         if (0 == iNumDeposit) return null;

  425.         for (int i = 0; i < iNumDeposit; ++i) {
  426.             if (null == (aSSCDepositFutures[i] = FundingDeposit (dtSpot, strCurrency,
  427.                 astrDepositMaturityTenor[i])))
  428.                 return null;

  429.             aSSCDepositFutures[i].setPrimaryCode (astrDepositMaturityTenor[i]);
  430.         }

  431.         if (0 == iNumFutures) return aSSCDepositFutures;

  432.         org.drip.product.rates.SingleStreamComponent[] aSSCFutures =
  433.             org.drip.service.template.ExchangeInstrumentBuilder.ForwardRateFuturesPack (dtSpot, iNumFutures,
  434.                 strCurrency);

  435.         if (null == aSSCFutures) return null;

  436.         for (int i = iNumDeposit; i < iNumDeposit + iNumFutures; ++i) {
  437.             if (null == (aSSCDepositFutures[i] = aSSCFutures[i - iNumDeposit])) return null;
  438.         }

  439.         return aSSCDepositFutures;
  440.     }

  441.     /**
  442.      * Construct an Array of OTC Forward Deposit Instruments from the corresponding Maturity Tenors
  443.      *
  444.      * @param dtSpot Spot Date
  445.      * @param astrMaturityTenor Array of Maturity Tenors
  446.      * @param forwardLabel The Forward Label
  447.      *
  448.      * @return Forward Deposit Instrument Instance from the corresponding Maturity Tenor
  449.      */

  450.     public static final org.drip.product.rates.SingleStreamComponent[] ForwardRateDeposit (
  451.         final org.drip.analytics.date.JulianDate dtSpot,
  452.         final java.lang.String[] astrMaturityTenor,
  453.         final org.drip.state.identifier.ForwardLabel forwardLabel)
  454.     {
  455.         if (null == astrMaturityTenor) return null;

  456.         int iNumDeposit = astrMaturityTenor.length;
  457.         org.drip.product.rates.SingleStreamComponent[] aSSCDeposit = new
  458.             org.drip.product.rates.SingleStreamComponent[iNumDeposit];

  459.         if (0 == iNumDeposit) return null;

  460.         for (int i = 0; i < astrMaturityTenor.length; ++i) {
  461.             if (null == (aSSCDeposit[i] = ForwardRateDeposit (dtSpot, astrMaturityTenor[i], forwardLabel)))
  462.                 return null;

  463.             aSSCDeposit[i].setPrimaryCode (astrMaturityTenor[i]);
  464.         }

  465.         return aSSCDeposit;
  466.     }

  467.     /**
  468.      * Construct an Array of OTC Overnight Deposit Instrument from their Maturity Tenors
  469.      *
  470.      * @param dtSpot Spot Date
  471.      * @param strCurrency Currency
  472.      * @param astrMaturityTenor Array of Maturity Tenor
  473.      *
  474.      * @return Array of Overnight Deposit Instrument from their Maturity Tenors
  475.      */

  476.     public static final org.drip.product.rates.SingleStreamComponent[] OvernightDeposit (
  477.         final org.drip.analytics.date.JulianDate dtSpot,
  478.         final java.lang.String strCurrency,
  479.         final java.lang.String[] astrMaturityTenor)
  480.     {
  481.         if (null == astrMaturityTenor) return null;

  482.         int iNumDeposit = astrMaturityTenor.length;
  483.         org.drip.product.rates.SingleStreamComponent[] aSSCDeposit = new
  484.             org.drip.product.rates.SingleStreamComponent[iNumDeposit];

  485.         if (0 == iNumDeposit) return null;

  486.         for (int i = 0; i < iNumDeposit; ++i) {
  487.             if (null == (aSSCDeposit[i] = OvernightDeposit (dtSpot, strCurrency, astrMaturityTenor[i])))
  488.                 return null;
  489.         }
  490.         return aSSCDeposit;
  491.     }

  492.     /**
  493.      * Create an Array of Standard FRAs from the Spot Date, the Forward Label, and the Strike
  494.      *
  495.      * @param dtSpot Spot Date
  496.      * @param forwardLabel The Forward Label
  497.      * @param astrMaturityTenor Array of Maturity Tenors
  498.      * @param adblFRAStrike Array of FRA Strikes
  499.      *
  500.      * @return Array of Standard FRA Instances
  501.      */

  502.     public static final org.drip.product.fra.FRAStandardComponent[] FRAStandard (
  503.         final org.drip.analytics.date.JulianDate dtSpot,
  504.         final org.drip.state.identifier.ForwardLabel forwardLabel,
  505.         final java.lang.String[] astrMaturityTenor,
  506.         final double[] adblFRAStrike)
  507.     {
  508.         if (null == astrMaturityTenor || null == adblFRAStrike) return null;

  509.         int iNumFRA = astrMaturityTenor.length;
  510.         org.drip.product.fra.FRAStandardComponent[] aFRA = new
  511.             org.drip.product.fra.FRAStandardComponent[iNumFRA];

  512.         if (0 == iNumFRA || iNumFRA != adblFRAStrike.length) return null;

  513.         for (int i = 0; i < iNumFRA; ++i) {
  514.             if (null == (aFRA[i] = FRAStandard (dtSpot, forwardLabel, astrMaturityTenor[i],
  515.                 adblFRAStrike[i])))
  516.                 return null;
  517.         }

  518.         return aFRA;
  519.     }

  520.     /**
  521.      * Construct an Array of OTC Fix Float Swaps using the specified Input Parameters
  522.      *
  523.      * @param dtSpot The Spot Date
  524.      * @param strCurrency The OTC Currency
  525.      * @param strLocation Location
  526.      * @param astrMaturityTenor Array of Maturity Tenors
  527.      * @param strIndex Index
  528.      * @param dblCoupon Coupon
  529.      *
  530.      * @return The Array of OTC Fix Float Swaps
  531.      */

  532.     public static final org.drip.product.rates.FixFloatComponent[] FixFloatStandard (
  533.         final org.drip.analytics.date.JulianDate dtSpot,
  534.         final java.lang.String strCurrency,
  535.         final java.lang.String strLocation,
  536.         final java.lang.String[] astrMaturityTenor,
  537.         final java.lang.String strIndex,
  538.         final double dblCoupon)
  539.     {
  540.         if (null == astrMaturityTenor) return null;

  541.         int iNumFixFloat = astrMaturityTenor.length;
  542.         org.drip.product.rates.FixFloatComponent[] aFFC = new
  543.             org.drip.product.rates.FixFloatComponent[iNumFixFloat];

  544.         if (0 == iNumFixFloat) return null;

  545.         for (int i = 0; i < iNumFixFloat; ++i) {
  546.             if (null == (aFFC[i] = FixFloatStandard (dtSpot, strCurrency, strLocation, astrMaturityTenor[i],
  547.                 strIndex, 0.)))
  548.                 return null;
  549.         }

  550.         return aFFC;
  551.     }

  552.     /**
  553.      * Construct an Array of Custom Fix Float Swap Instances
  554.      *
  555.      * @param dtSpot The Spot Date
  556.      * @param forwardLabel The Forward Label
  557.      * @param astrMaturityTenor Array of Maturity Tenors
  558.      *
  559.      * @return Array of Custom Fix Float Swap Instances
  560.      */

  561.     public static final org.drip.product.rates.FixFloatComponent[] FixFloatCustom (
  562.         final org.drip.analytics.date.JulianDate dtSpot,
  563.         final org.drip.state.identifier.ForwardLabel forwardLabel,
  564.         final java.lang.String[] astrMaturityTenor)
  565.     {
  566.         if (null == dtSpot || null == forwardLabel || null == astrMaturityTenor) return null;

  567.         int iNumComp = astrMaturityTenor.length;
  568.         org.drip.param.period.CompositePeriodSetting cpsFloating = null;
  569.         org.drip.param.period.ComposableFloatingUnitSetting cfusFloating = null;
  570.         org.drip.product.rates.FixFloatComponent[] aFFC = new
  571.             org.drip.product.rates.FixFloatComponent[iNumComp];

  572.         if (0 == iNumComp) return null;

  573.         java.lang.String strCurrency = forwardLabel.currency();

  574.         java.lang.String strForwardTenor = forwardLabel.tenor();

  575.         int iTenorInMonths = java.lang.Integer.parseInt (strForwardTenor.split ("M")[0]);

  576.         org.drip.analytics.date.JulianDate dtEffective = dtSpot.addBusDays (0, strCurrency).addDays (2);

  577.         try {
  578.             cfusFloating = new org.drip.param.period.ComposableFloatingUnitSetting (strForwardTenor,
  579.                 org.drip.analytics.support.CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR, null,
  580.                     forwardLabel,
  581.                         org.drip.analytics.support.CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE, 0.);

  582.             cpsFloating = new org.drip.param.period.CompositePeriodSetting (12 / iTenorInMonths,
  583.                 strForwardTenor, strCurrency, null, -1., null, null, null, null);
  584.         } catch (java.lang.Exception e) {
  585.             e.printStackTrace();

  586.             return null;
  587.         }

  588.         for (int i = 0; i < iNumComp; ++i) {
  589.             org.drip.market.otc.FixedFloatSwapConvention ffsc =
  590.                 org.drip.market.otc.IBORFixedFloatContainer.ConventionFromJurisdiction (strCurrency, "ALL",
  591.                     astrMaturityTenor[i], "MAIN");

  592.             if (null == ffsc) return null;

  593.             try {
  594.                 org.drip.product.rates.Stream floatingStream = new org.drip.product.rates.Stream
  595.                     (org.drip.analytics.support.CompositePeriodBuilder.FloatingCompositeUnit
  596.                         (org.drip.analytics.support.CompositePeriodBuilder.RegularEdgeDates (dtEffective,
  597.                             strForwardTenor, astrMaturityTenor[i], null), cpsFloating, cfusFloating));

  598.                 org.drip.product.rates.Stream fixedStream = ffsc.fixedStreamConvention().createStream
  599.                     (dtEffective, astrMaturityTenor[i], 0., 1.);

  600.                 aFFC[i] = new org.drip.product.rates.FixFloatComponent (fixedStream, floatingStream, null);
  601.             } catch (java.lang.Exception e) {
  602.                 e.printStackTrace();

  603.                 return null;
  604.             }

  605.             aFFC[i].setPrimaryCode ("FixFloat:" + astrMaturityTenor[i]);
  606.         }

  607.         return aFFC;
  608.     }

  609.     /**
  610.      * Construct an Array of OTC Fix Float OIS Instances
  611.      *
  612.      * @param dtSpot Spot Date
  613.      * @param strCurrency Currency
  614.      * @param astrMaturityTenor Array of OIS Maturity Tenors
  615.      * @param adblCoupon OIS Fixed Rate Coupon
  616.      * @param bFund TRUE - Floater Based off of Fund
  617.      *
  618.      * @return Array of Fix Float OIS Instances
  619.      */

  620.     public static final org.drip.product.rates.FixFloatComponent[] OISFixFloat (
  621.         final org.drip.analytics.date.JulianDate dtSpot,
  622.         final java.lang.String strCurrency,
  623.         final java.lang.String[] astrMaturityTenor,
  624.         final double[] adblCoupon,
  625.         final boolean bFund)
  626.     {
  627.         if (null == astrMaturityTenor) return null;

  628.         int iNumOIS = astrMaturityTenor.length;
  629.         org.drip.product.rates.FixFloatComponent[] aFixFloatOIS = new
  630.             org.drip.product.rates.FixFloatComponent[iNumOIS];

  631.         if (0 == iNumOIS) return null;

  632.         for (int i = 0; i < iNumOIS; ++i) {
  633.             if (null == (aFixFloatOIS[i] = OISFixFloat (dtSpot, strCurrency, astrMaturityTenor[i],
  634.                 adblCoupon[i], bFund)))
  635.                 return null;
  636.         }

  637.         return aFixFloatOIS;
  638.     }

  639.     /**
  640.      * Construct an Array of OTC OIS Fix-Float Futures
  641.      *
  642.      * @param dtSpot Spot Date
  643.      * @param strCurrency Currency
  644.      * @param astrEffectiveTenor Array of Effective Tenors
  645.      * @param astrMaturityTenor Array of Maturity Tenors
  646.      * @param adblCoupon Array of Coupons
  647.      * @param bFund TRUE - Floater Based off of Fund
  648.      *
  649.      * @return Array of OIS Fix-Float Futures
  650.      */

  651.     public static final org.drip.product.rates.FixFloatComponent[] OISFixFloatFutures (
  652.         final org.drip.analytics.date.JulianDate dtSpot,
  653.         final java.lang.String strCurrency,
  654.         final java.lang.String[] astrEffectiveTenor,
  655.         final java.lang.String[] astrMaturityTenor,
  656.         final double[] adblCoupon,
  657.         final boolean bFund)
  658.     {
  659.         if (null == dtSpot || null == astrEffectiveTenor || null == astrMaturityTenor || null == adblCoupon)
  660.             return null;

  661.         int iNumOISFutures = astrEffectiveTenor.length;
  662.         org.drip.product.rates.FixFloatComponent[] aOISFutures = new
  663.             org.drip.product.rates.FixFloatComponent[iNumOISFutures];

  664.         if (0 == iNumOISFutures || iNumOISFutures != astrMaturityTenor.length || iNumOISFutures !=
  665.             adblCoupon.length)
  666.             return null;

  667.         for (int i = 0; i < iNumOISFutures; ++i) {
  668.             if (null == (aOISFutures[i] = OISFixFloat (dtSpot.addTenor (astrEffectiveTenor[i]), strCurrency,
  669.                 astrMaturityTenor[i], adblCoupon[i], bFund)))
  670.                 return null;
  671.         }

  672.         return aOISFutures;
  673.     }

  674.     /**
  675.      * Construct an Array of OTC Float-Float Swap Instances
  676.      *
  677.      * @param dtSpot Spot Date
  678.      * @param strCurrency Currency
  679.      * @param strDerivedTenor Tenor of the Derived Leg
  680.      * @param astrMaturityTenor Array of the Float-Float Swap Maturity Tenors
  681.      * @param dblBasis The Float-Float Swap Basis
  682.      *
  683.      * @return Array of OTC Float-Float Swap Instances
  684.      */

  685.     public static final org.drip.product.rates.FloatFloatComponent[] FloatFloat (
  686.         final org.drip.analytics.date.JulianDate dtSpot,
  687.         final java.lang.String strCurrency,
  688.         final java.lang.String strDerivedTenor,
  689.         final java.lang.String[] astrMaturityTenor,
  690.         final double dblBasis)
  691.     {
  692.         if (null == astrMaturityTenor) return null;

  693.         org.drip.market.otc.FloatFloatSwapConvention ffsc =
  694.             org.drip.market.otc.IBORFloatFloatContainer.ConventionFromJurisdiction (strCurrency);

  695.         int iNumFFC = astrMaturityTenor.length;
  696.         org.drip.product.rates.FloatFloatComponent[] aFFC = new
  697.             org.drip.product.rates.FloatFloatComponent[iNumFFC];

  698.         if (null == ffsc || 0 == iNumFFC) return null;

  699.         for (int i = 0; i < iNumFFC; ++i) {
  700.             if (null == (aFFC[i] = ffsc.createFloatFloatComponent (dtSpot, strDerivedTenor,
  701.                 astrMaturityTenor[i], dblBasis, 1.)))
  702.                 return null;
  703.         }

  704.         return aFFC;
  705.     }

  706.     /**
  707.      * Create an Array of the OTC CDS Instance.
  708.      *
  709.      * @param dtSpot Spot Date
  710.      * @param astrMaturityTenor Array of Maturity Tenors
  711.      * @param adblCoupon Array of Coupon
  712.      * @param strCurrency Currency
  713.      * @param strCredit Credit Curve
  714.      *
  715.      * @return Array of OTC CDS Instances
  716.      */

  717.     public static final org.drip.product.definition.CreditDefaultSwap[] CDS (
  718.         final org.drip.analytics.date.JulianDate dtSpot,
  719.         final java.lang.String[] astrMaturityTenor,
  720.         final double[] adblCoupon,
  721.         final java.lang.String strCurrency,
  722.         final java.lang.String strCredit)
  723.     {
  724.         if (null == dtSpot || null == strCurrency || null == astrMaturityTenor || null == adblCoupon)
  725.             return null;

  726.         int iNumCDS = astrMaturityTenor.length;
  727.         java.lang.String strCalendar = strCurrency;
  728.         org.drip.product.definition.CreditDefaultSwap[] aCDS = new
  729.             org.drip.product.definition.CreditDefaultSwap[iNumCDS];

  730.         if (0 == iNumCDS || iNumCDS != adblCoupon.length) return null;

  731.         org.drip.analytics.date.JulianDate dtFirstCoupon = dtSpot.addBusDays (0, strCalendar).nextCreditIMM
  732.             (3);

  733.         if (null == dtFirstCoupon) return null;

  734.         org.drip.analytics.date.JulianDate dtEffective = dtFirstCoupon.subtractTenor ("3M");

  735.         if (null == dtEffective) return null;

  736.         double dblRecovery = "CAD".equalsIgnoreCase (strCurrency) || "EUR".equalsIgnoreCase (strCurrency) ||
  737.             "GBP".equalsIgnoreCase (strCurrency) || "HKD".equalsIgnoreCase (strCurrency) ||
  738.                 "USD".equalsIgnoreCase (strCurrency) ? 0.40 : 0.25;

  739.         for (int i = 0; i < iNumCDS; ++i)
  740.             aCDS[i] = org.drip.product.creator.CDSBuilder.CreateCDS (dtEffective, dtFirstCoupon.addTenor
  741.                 (astrMaturityTenor[i]), adblCoupon[i], strCurrency, dblRecovery, strCredit, strCalendar,
  742.                     true);

  743.         return aCDS;
  744.     }

  745.     /**
  746.      * Create an Array of OTC FX Forward Components
  747.      *
  748.      * @param dtSpot Spot Date
  749.      * @param ccyPair Currency Pair
  750.      * @param astrMaturityTenor Array of Maturity Tenors
  751.      *
  752.      * @return Array of OTC FX Forward Component Instances
  753.      */

  754.     public static final org.drip.product.fx.FXForwardComponent[] FXForward (
  755.         final org.drip.analytics.date.JulianDate dtSpot,
  756.         final org.drip.product.params.CurrencyPair ccyPair,
  757.         final java.lang.String[] astrMaturityTenor)
  758.     {
  759.         if (null == astrMaturityTenor) return null;

  760.         int iNumFXComp = astrMaturityTenor.length;
  761.         org.drip.product.fx.FXForwardComponent[] aFXFC = new
  762.             org.drip.product.fx.FXForwardComponent[iNumFXComp];

  763.         if (0 == iNumFXComp) return null;

  764.         for (int i = 0; i < iNumFXComp; ++i)
  765.             aFXFC[i] = FXForward (dtSpot, ccyPair, astrMaturityTenor[i]);

  766.         return aFXFC;
  767.     }

  768.     /**
  769.      * Construct an Instance of the Standard OTC FRA Cap/Floor
  770.      *
  771.      * @param dtSpot Spot Date
  772.      * @param forwardLabel The Forward Label
  773.      * @param strMaturityTenor Cap/Floor Maturity Tenor
  774.      * @param dblStrike Cap/Floor Strike
  775.      * @param bIsCap TRUE - Contract is a Cap
  776.      *
  777.      * @return The Cap/Floor Instance
  778.      */

  779.     public static final org.drip.product.fra.FRAStandardCapFloor CapFloor (
  780.         final org.drip.analytics.date.JulianDate dtSpot,
  781.         final org.drip.state.identifier.ForwardLabel forwardLabel,
  782.         final java.lang.String strMaturityTenor,
  783.         final double dblStrike,
  784.         final boolean bIsCap)
  785.     {
  786.         if (null == dtSpot || null == forwardLabel) return null;

  787.         java.lang.String strForwardTenor = forwardLabel.tenor();

  788.         java.lang.String strCurrency = forwardLabel.currency();

  789.         java.lang.String strCalendar = strCurrency;

  790.         org.drip.analytics.date.JulianDate dtEffective = dtSpot.addBusDays (0, strCalendar);

  791.         try {
  792.             org.drip.param.period.ComposableFloatingUnitSetting cfus = new
  793.                 org.drip.param.period.ComposableFloatingUnitSetting (strForwardTenor,
  794.                     org.drip.analytics.support.CompositePeriodBuilder.EDGE_DATE_SEQUENCE_SINGLE, null,
  795.                         forwardLabel,
  796.                             org.drip.analytics.support.CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  797.                                 0.);

  798.             org.drip.param.period.CompositePeriodSetting cps = new
  799.                 org.drip.param.period.CompositePeriodSetting
  800.                     (org.drip.analytics.support.Helper.TenorToFreq (strForwardTenor),
  801.                         strForwardTenor, strCurrency, null, 1., null, null, null, null);

  802.             org.drip.product.rates.Stream floatStream = new org.drip.product.rates.Stream
  803.                 (org.drip.analytics.support.CompositePeriodBuilder.FloatingCompositeUnit
  804.                     (org.drip.analytics.support.CompositePeriodBuilder.RegularEdgeDates
  805.                         (dtEffective.julian(), strForwardTenor, strMaturityTenor, null), cps, cfus));

  806.             return new org.drip.product.fra.FRAStandardCapFloor (forwardLabel.fullyQualifiedName() + (bIsCap
  807.                 ? "::CAP" : "::FLOOR"), floatStream, "ParForward", bIsCap, dblStrike, new
  808.                     org.drip.product.params.LastTradingDateSetting
  809.                         (org.drip.product.params.LastTradingDateSetting.MID_CURVE_OPTION_QUARTERLY, "",
  810.                             java.lang.Integer.MIN_VALUE), null, new
  811.                                 org.drip.pricer.option.BlackScholesAlgorithm());
  812.         } catch (java.lang.Exception e) {
  813.             e.printStackTrace();
  814.         }

  815.         return null;
  816.     }

  817.     /**
  818.      * Construct an Instance of the Standard OTC FRA Cap/Floor
  819.      *
  820.      * @param dtSpot Spot Date
  821.      * @param forwardLabel The Forward Label
  822.      * @param astrMaturityTenor Array of Cap/Floor Maturity Tenors
  823.      * @param adblStrike Array of Cap/Floor Strikes
  824.      * @param bIsCap TRUE - Contract is a Cap
  825.      *
  826.      * @return The Cap/Floor Instance
  827.      */

  828.     public static final org.drip.product.fra.FRAStandardCapFloor[] CapFloor (
  829.         final org.drip.analytics.date.JulianDate dtSpot,
  830.         final org.drip.state.identifier.ForwardLabel forwardLabel,
  831.         final java.lang.String[] astrMaturityTenor,
  832.         final double[] adblStrike,
  833.         final boolean bIsCap)
  834.     {
  835.         if (null == astrMaturityTenor || null == adblStrike) return null;

  836.         int iNumCapFloor = astrMaturityTenor.length;
  837.         org.drip.product.fra.FRAStandardCapFloor[] aFRACapFloor = new
  838.             org.drip.product.fra.FRAStandardCapFloor[iNumCapFloor];

  839.         if (0 == iNumCapFloor || iNumCapFloor != adblStrike.length) return null;

  840.         for (int i = 0; i < iNumCapFloor; ++i) {
  841.             if (null == (aFRACapFloor[i] = org.drip.service.template.OTCInstrumentBuilder.CapFloor (dtSpot,
  842.                 forwardLabel, astrMaturityTenor[i], adblStrike[i], bIsCap)))
  843.                 return null;
  844.         }

  845.         return aFRACapFloor;
  846.     }
  847. }