OvernightFedFundLIBORSwap.java

  1. package org.drip.sample.fedfund;

  2. import java.util.*;

  3. import org.drip.analytics.date.*;
  4. import org.drip.analytics.support.*;
  5. import org.drip.function.r1tor1.QuadraticRationalShapeControl;
  6. import org.drip.market.otc.*;
  7. import org.drip.numerical.common.FormatUtil;
  8. import org.drip.param.creator.*;
  9. import org.drip.param.market.CurveSurfaceQuoteContainer;
  10. import org.drip.param.period.*;
  11. import org.drip.param.valuation.*;
  12. import org.drip.product.creator.SingleStreamComponentBuilder;
  13. import org.drip.product.definition.CalibratableComponent;
  14. import org.drip.product.rates.*;
  15. import org.drip.service.env.EnvManager;
  16. import org.drip.spline.basis.PolynomialFunctionSetParams;
  17. import org.drip.spline.params.*;
  18. import org.drip.spline.stretch.*;
  19. import org.drip.state.creator.*;
  20. import org.drip.state.discount.*;
  21. import org.drip.state.estimator.LatentStateStretchBuilder;
  22. import org.drip.state.forward.ForwardCurve;
  23. import org.drip.state.identifier.*;
  24. import org.drip.state.inference.*;

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

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

  90. /**
  91.  * <i>OvernightFedFundLIBORSwap</i> demonstrates the Construction, the Valuation, and Bloomberg Metrics
  92.  * Analysis for the Composite Fed Fund vs. LIBOR Basis Swaps.
  93.  *  
  94.  * <br><br>
  95.  *  <ul>
  96.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/AnalyticsCore.md">Analytics Core Module</a></li>
  97.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics Library</a></li>
  98.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">Sample</a></li>
  99.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/fedfund/README.md">Fed Fund Analytics</a></li>
  100.  *  </ul>
  101.  * <br><br>
  102.  *
  103.  * @author Lakshmi Krishnamurthy
  104.  */

  105. public class OvernightFedFundLIBORSwap {

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

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

  122.     private static final FixFloatComponent OTCOISFixFloat (
  123.         final JulianDate dtSpot,
  124.         final String strCurrency,
  125.         final String strMaturityTenor,
  126.         final double dblCoupon)
  127.     {
  128.         FixedFloatSwapConvention ffConv = OvernightFixedFloatContainer.FundConventionFromJurisdiction (
  129.             strCurrency
  130.         );

  131.         return ffConv.createFixFloatComponent (
  132.             dtSpot,
  133.             strMaturityTenor,
  134.             dblCoupon,
  135.             0.,
  136.             1.
  137.         );
  138.     }

  139.     /*
  140.      * Construct the Array of Deposit Instruments from the given set of parameters
  141.      *
  142.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  143.      */

  144.     private static final SingleStreamComponent[] DepositInstrumentsFromMaturityDays (
  145.         final JulianDate dtEffective,
  146.         final String strCurrency,
  147.         final int[] aiDay)
  148.         throws Exception
  149.     {
  150.         SingleStreamComponent[] aDeposit = new SingleStreamComponent[aiDay.length];

  151.         for (int i = 0; i < aiDay.length; ++i)
  152.             aDeposit[i] = SingleStreamComponentBuilder.Deposit (
  153.                 dtEffective,
  154.                 dtEffective.addBusDays (
  155.                     aiDay[i],
  156.                     strCurrency
  157.                 ),
  158.                 OvernightLabel.Create (
  159.                     strCurrency
  160.                 )
  161.             );

  162.         return aDeposit;
  163.     }

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

  169.     private static final FixFloatComponent[] OISFromMaturityTenor (
  170.         final JulianDate dtSpot,
  171.         final String strCurrency,
  172.         final String[] astrMaturityTenor,
  173.         final double[] adblCoupon)
  174.         throws Exception
  175.     {
  176.         FixFloatComponent[] aOIS = new FixFloatComponent[astrMaturityTenor.length];

  177.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  178.             aOIS[i] = OTCOISFixFloat (
  179.                 dtSpot,
  180.                 strCurrency,
  181.                 astrMaturityTenor[i],
  182.                 adblCoupon[i]
  183.             );

  184.         return aOIS;
  185.     }

  186.     /*
  187.      * Construct the Array of Overnight Index Future Instruments from the given set of parameters
  188.      *
  189.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  190.      */

  191.     private static final FixFloatComponent[] OISFuturesFromMaturityTenor (
  192.         final JulianDate dtSpot,
  193.         final String strCurrency,
  194.         final String[] astrStartTenor,
  195.         final String[] astrMaturityTenor,
  196.         final double[] adblCoupon)
  197.         throws Exception
  198.     {
  199.         FixFloatComponent[] aOISFutures = new FixFloatComponent[astrMaturityTenor.length];

  200.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  201.             aOISFutures[i] = OTCOISFixFloat (
  202.                 dtSpot.addTenor (astrStartTenor[i]),
  203.                 strCurrency,
  204.                 astrMaturityTenor[i],
  205.                 adblCoupon[i]
  206.             );

  207.         return aOISFutures;
  208.     }

  209.     private static final MergedDiscountForwardCurve OISDiscountCurve (
  210.         final JulianDate dtSpot,
  211.         final String strCurrency,
  212.         final String strHeaderComment)
  213.         throws Exception
  214.     {
  215.         System.out.println ("\n\t----------------------------------------------------------------");

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

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

  218.         /*
  219.          * Construct the Array of Deposit Instruments and their Quotes from the given set of parameters
  220.          */

  221.         SingleStreamComponent[] aDepositComp = DepositInstrumentsFromMaturityDays (
  222.             dtSpot,
  223.             strCurrency,
  224.             new int[] {
  225.                 1, 2, 3
  226.             }
  227.         );

  228.         double[] adblDepositQuote = new double[] {
  229.             0.0004, 0.0004, 0.0004       // Deposit
  230.         };

  231.         /*
  232.          * Construct the Deposit Instrument Set Stretch Builder
  233.          */

  234.         LatentStateStretchSpec depositStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  235.             "   DEPOSIT   ",
  236.             aDepositComp,
  237.             "ForwardRate",
  238.             adblDepositQuote
  239.         );

  240.         /*
  241.          * Construct the Array of Short End OIS Instruments and their Quotes from the given set of parameters
  242.          */

  243.         double[] adblShortEndOISQuote = new double[] {
  244.             0.00070,    //   1W
  245.             0.00069,    //   2W
  246.             0.00078,    //   3W
  247.             0.00074     //   1M
  248.         };

  249.         CalibratableComponent[] aShortEndOISComp = OISFromMaturityTenor (
  250.             dtSpot,
  251.             strCurrency,
  252.             new java.lang.String[] {
  253.                 "1W", "2W", "3W", "1M"
  254.             },
  255.             adblShortEndOISQuote
  256.         );

  257.         /*
  258.          * Construct the Short End OIS Instrument Set Stretch Builder
  259.          */

  260.         LatentStateStretchSpec oisShortEndStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  261.             "SHORT END OIS",
  262.             aShortEndOISComp,
  263.             "SwapRate",
  264.             adblShortEndOISQuote
  265.         );

  266.         /*
  267.          * Construct the Array of OIS Futures Instruments and their Quotes from the given set of parameters
  268.          */

  269.         double[] adblOISFutureQuote = new double[] {
  270.              0.00046,    //   1M x 1M
  271.              0.00016,    //   2M x 1M
  272.             -0.00007,    //   3M x 1M
  273.             -0.00013,    //   4M x 1M
  274.             -0.00014     //   5M x 1M
  275.         };

  276.         CalibratableComponent[] aOISFutureComp = OISFuturesFromMaturityTenor (
  277.             dtSpot,
  278.             strCurrency,
  279.             new java.lang.String[] {
  280.                 "1M", "2M", "3M", "4M", "5M"
  281.             },
  282.             new java.lang.String[] {
  283.                 "1M", "1M", "1M", "1M", "1M"
  284.             },
  285.             adblOISFutureQuote
  286.         );

  287.         /*
  288.          * Construct the OIS Future Instrument Set Stretch Builder
  289.          */

  290.         LatentStateStretchSpec oisFutureStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  291.             " OIS FUTURE  ",
  292.             aOISFutureComp,
  293.             "SwapRate",
  294.             adblOISFutureQuote
  295.         );

  296.         /*
  297.          * Construct the Array of Long End OIS Instruments and their Quotes from the given set of parameters
  298.          */

  299.         double[] adblLongEndOISQuote = new double[] {
  300.             0.00002,    //  15M
  301.             0.00008,    //  18M
  302.             0.00021,    //  21M
  303.             0.00036,    //   2Y
  304.             0.00127,    //   3Y
  305.             0.00274,    //   4Y
  306.             0.00456,    //   5Y
  307.             0.00647,    //   6Y
  308.             0.00827,    //   7Y
  309.             0.00996,    //   8Y
  310.             0.01147,    //   9Y
  311.             0.01280,    //  10Y
  312.             0.01404,    //  11Y
  313.             0.01516,    //  12Y
  314.             0.01764,    //  15Y
  315.             0.01939,    //  20Y
  316.             0.02003,    //  25Y
  317.             0.02038     //  30Y
  318.         };

  319.         CalibratableComponent[] aLongEndOISComp = OISFromMaturityTenor (
  320.             dtSpot,
  321.             strCurrency,
  322.             new java.lang.String[] {
  323.                 "15M", "18M", "21M", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y"
  324.             },
  325.             adblLongEndOISQuote
  326.         );

  327.         /*
  328.          * Construct the Long End OIS Instrument Set Stretch Builder
  329.          */

  330.         LatentStateStretchSpec oisLongEndStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  331.             "LONG END OIS ",
  332.             aLongEndOISComp,
  333.             "SwapRate",
  334.             adblLongEndOISQuote
  335.         );

  336.         LatentStateStretchSpec[] aStretchSpec = new LatentStateStretchSpec[] {
  337.             depositStretch,
  338.             oisShortEndStretch,
  339.             oisFutureStretch,
  340.             oisLongEndStretch
  341.         };

  342.         /*
  343.          * Set up the Linear Curve Calibrator using the following parameters:
  344.          *  - Cubic Exponential Mixture Basis Spline Set
  345.          *  - Ck = 2, Segment Curvature Penalty = 2
  346.          *  - Quadratic Rational Shape Controller
  347.          *  - Natural Boundary Setting
  348.          */

  349.         LinearLatentStateCalibrator lcc = new LinearLatentStateCalibrator (
  350.             new SegmentCustomBuilderControl (
  351.                 MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  352.                 new PolynomialFunctionSetParams (4),
  353.                 SegmentInelasticDesignControl.Create (
  354.                     2,
  355.                     2
  356.                 ),
  357.                 new ResponseScalingShapeControl (
  358.                     true,
  359.                     new QuadraticRationalShapeControl (0.)
  360.                 ),
  361.                 null
  362.             ),
  363.             BoundarySettings.NaturalStandard(),
  364.             MultiSegmentSequence.CALIBRATE,
  365.             null,
  366.             null
  367.         );

  368.         /*
  369.          * Construct the Shape Preserving Discount Curve by applying the linear curve calibrator to the array
  370.          *  of Deposit and Swap Stretches.
  371.          */

  372.         ValuationParams valParams = new ValuationParams (
  373.             dtSpot,
  374.             dtSpot,
  375.             strCurrency
  376.         );

  377.         MergedDiscountForwardCurve dc = ScenarioDiscountCurveBuilder.ShapePreservingDFBuild (
  378.             strCurrency,
  379.             lcc,
  380.             aStretchSpec,
  381.             valParams,
  382.             null,
  383.             null,
  384.             null,
  385.             1.
  386.         );

  387.         CurveSurfaceQuoteContainer csqs = MarketParamsBuilder.Create (
  388.             dc,
  389.             null,
  390.             null,
  391.             null,
  392.             null,
  393.             null,
  394.             null
  395.         );

  396.         /*
  397.          * Cross-Comparison of the Deposit Calibration Instrument "Rate" metric across the different curve
  398.          *  construction methodologies.
  399.          */

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

  401.         System.out.println ("\t     DEPOSIT INSTRUMENTS CALIBRATION RECOVERY");

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

  403.         for (int i = 0; i < aDepositComp.length; ++i)
  404.             System.out.println ("\t[" + aDepositComp[i].effectiveDate() + " => " + aDepositComp[i].maturityDate() + "] = " +
  405.                 FormatUtil.FormatDouble (aDepositComp[i].measureValue (valParams, null, csqs, null, "Rate"), 1, 6, 1.) +
  406.                 " | " + FormatUtil.FormatDouble (adblDepositQuote[i], 1, 6, 1.));

  407.         /*
  408.          * Cross-Comparison of the Short End OIS Calibration Instrument "Rate" metric across the different curve
  409.          *  construction methodologies.
  410.          */

  411.         System.out.println ("\n\t----------------------------------------------------------------");

  412.         System.out.println ("\t     OIS SHORT END INSTRUMENTS CALIBRATION RECOVERY");

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

  414.         for (int i = 0; i < aShortEndOISComp.length; ++i) {
  415.             Map<String, Double> mapCalc = aShortEndOISComp[i].value (
  416.                 valParams,
  417.                 null,
  418.                 csqs,
  419.                 null
  420.             );

  421.             double dblCalibSwapRate = mapCalc.get ("CalibSwapRate");

  422.             double dblFairPremium = mapCalc.get ("FairPremium");

  423.             System.out.println ("\t[" + aShortEndOISComp[i].effectiveDate() + " => " + aShortEndOISComp[i].maturityDate() + "] = " +
  424.                 FormatUtil.FormatDouble (dblCalibSwapRate, 1, 6, 1.) + " | " +
  425.                 FormatUtil.FormatDouble (adblShortEndOISQuote[i], 1, 6, 1.) + " | " +
  426.                 FormatUtil.FormatDouble (dblFairPremium, 1, 6, 1.) + " | " +
  427.                 FormatUtil.FormatDouble (dblFairPremium - dblCalibSwapRate, 1, 2, 10000.)
  428.             );
  429.         }

  430.         /*
  431.          * Cross-Comparison of the OIS Future Calibration Instrument "Rate" metric across the different curve
  432.          *  construction methodologies.
  433.          */

  434.         System.out.println ("\n\t----------------------------------------------------------------");

  435.         System.out.println ("\t     OIS FUTURE INSTRUMENTS CALIBRATION RECOVERY");

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

  437.         for (int i = 0; i < aOISFutureComp.length; ++i) {
  438.             Map<String, Double> mapCalc = aOISFutureComp[i].value (
  439.                 valParams,
  440.                 null,
  441.                 csqs,
  442.                 null
  443.             );

  444.             double dblSwapRate = mapCalc.get ("SwapRate");

  445.             double dblFairPremium = mapCalc.get ("FairPremium");

  446.             System.out.println ("\t[" + aOISFutureComp[i].effectiveDate() + " => " + aOISFutureComp[i].maturityDate() + "] = " +
  447.                 FormatUtil.FormatDouble (dblSwapRate, 1, 6, 1.) + " | " +
  448.                 FormatUtil.FormatDouble (adblOISFutureQuote[i], 1, 6, 1.) + " | " +
  449.                 FormatUtil.FormatDouble (dblFairPremium, 1, 6, 1.) + " | " +
  450.                 FormatUtil.FormatDouble (dblFairPremium - dblSwapRate, 1, 2, 10000.)
  451.             );
  452.         }

  453.         /*
  454.          * Cross-Comparison of the Long End OIS Calibration Instrument "Rate" metric across the different curve
  455.          *  construction methodologies.
  456.          */

  457.         System.out.println ("\n\t----------------------------------------------------------------");

  458.         System.out.println ("\t     OIS LONG END INSTRUMENTS CALIBRATION RECOVERY");

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

  460.         for (int i = 0; i < aLongEndOISComp.length; ++i) {
  461.             Map<String, Double> mapCalc = aLongEndOISComp[i].value (
  462.                 valParams,
  463.                 null,
  464.                 csqs,
  465.                 null
  466.             );

  467.             double dblCalibSwapRate = mapCalc.get ("CalibSwapRate");

  468.             double dblFairPremium = mapCalc.get ("FairPremium");

  469.             System.out.println ("\t[" + aLongEndOISComp[i].effectiveDate() + " => " + aLongEndOISComp[i].maturityDate() + "] = " +
  470.                 FormatUtil.FormatDouble (dblCalibSwapRate, 1, 6, 1.) + " | " +
  471.                 FormatUtil.FormatDouble (adblLongEndOISQuote[i], 1, 6, 1.) + " | " +
  472.                 FormatUtil.FormatDouble (dblFairPremium, 1, 6, 1.) + " | " +
  473.                 FormatUtil.FormatDouble (dblFairPremium - dblCalibSwapRate, 1, 2, 10000.)
  474.             );
  475.         }

  476.         return dc;
  477.     }

  478.     /*
  479.      * Construct an array of float-float swaps from the corresponding reference (6M) and the derived legs.
  480.      *
  481.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  482.      */

  483.     private static final FloatFloatComponent[] MakexM6MBasisSwap (
  484.         final JulianDate dtSpot,
  485.         final String strCurrency,
  486.         final String[] astrMaturityTenor,
  487.         final int iTenorInMonths)
  488.         throws Exception
  489.     {
  490.         FloatFloatComponent[] aFFC = new FloatFloatComponent[astrMaturityTenor.length];

  491.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  492.             aFFC[i] = OTCFloatFloat (
  493.                 dtSpot,
  494.                 strCurrency,
  495.                 iTenorInMonths + "M",
  496.                 astrMaturityTenor[i],
  497.                 0.
  498.             );

  499.         return aFFC;
  500.     }

  501.     private static final ForwardCurve MakexMForwardCurve (
  502.         final JulianDate dtSpot,
  503.         final String strCurrency,
  504.         final MergedDiscountForwardCurve dc,
  505.         final int iTenorInMonths,
  506.         final String[] astrxM6MFwdTenor,
  507.         final String strManifestMeasure,
  508.         final double[] adblxM6MBasisSwapQuote)
  509.         throws Exception
  510.     {
  511.         /*
  512.          * Construct the 6M-xM float-float basis swap.
  513.          */

  514.         FloatFloatComponent[] aFFC = MakexM6MBasisSwap (
  515.             dtSpot,
  516.             strCurrency,
  517.             astrxM6MFwdTenor,
  518.             iTenorInMonths
  519.         );

  520.         String strBasisTenor = iTenorInMonths + "M";

  521.         ValuationParams valParams = new ValuationParams (
  522.             dtSpot,
  523.             dtSpot,
  524.             strCurrency
  525.         );

  526.         /*
  527.          * Calculate the starting forward rate off of the discount curve.
  528.          */

  529.         double dblStartingFwd = dc.forward (
  530.             dtSpot.julian(),
  531.             dtSpot.addTenor (strBasisTenor).julian()
  532.         );

  533.         /*
  534.          * Set the discount curve based component market parameters.
  535.          */

  536.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  537.             dc,
  538.             null,
  539.             null,
  540.             null,
  541.             null,
  542.             null,
  543.             null
  544.         );

  545.         /*
  546.          * Construct the shape preserving forward curve off of Cubic Polynomial Basis Spline.
  547.          */

  548.         return ScenarioForwardCurveBuilder.ShapePreservingForwardCurve (
  549.             "CUBIC_FWD" + strBasisTenor,
  550.             ForwardLabel.Create (
  551.                 strCurrency,
  552.                 strBasisTenor
  553.             ),
  554.             valParams,
  555.             null,
  556.             mktParams,
  557.             null,
  558.             MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  559.             new PolynomialFunctionSetParams (4),
  560.             aFFC,
  561.             strManifestMeasure,
  562.             adblxM6MBasisSwapQuote,
  563.             dblStartingFwd
  564.         );
  565.     }

  566.     private static final FloatFloatComponent[] FedFundLIBORBasisSwap (
  567.         final JulianDate dtEffective,
  568.         final String strCurrency,
  569.         final String[] astrMaturityTenor)
  570.         throws Exception
  571.     {
  572.         FloatFloatComponent[] aFFC = new FloatFloatComponent[astrMaturityTenor.length];

  573.         ComposableFloatingUnitSetting cfusLIBOR = new ComposableFloatingUnitSetting (
  574.             "3M",
  575.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  576.             null,
  577.             ForwardLabel.Standard (strCurrency + "-3M"),
  578.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  579.             0.
  580.         );

  581.         ComposableFloatingUnitSetting cfusFedFund = new ComposableFloatingUnitSetting (
  582.             "ON",
  583.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_OVERNIGHT,
  584.             null,
  585.             OvernightLabel.Create (
  586.                 strCurrency
  587.             ),
  588.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  589.             0.
  590.         );

  591.         CompositePeriodSetting cpsLIBOR = new CompositePeriodSetting (
  592.             4,
  593.             "3M",
  594.             strCurrency,
  595.             null,
  596.             -1.,
  597.             null,
  598.             null,
  599.             null,
  600.             null
  601.         );

  602.         CompositePeriodSetting cpsFedFund = new CompositePeriodSetting (
  603.             360,
  604.             "ON",
  605.             strCurrency,
  606.             null,
  607.             1.,
  608.             null,
  609.             null,
  610.             null,
  611.             null
  612.         );

  613.         CashSettleParams csp = new CashSettleParams (
  614.             0,
  615.             strCurrency,
  616.             0
  617.         );

  618.         for (int i = 0; i < astrMaturityTenor.length; ++i) {
  619.             List<Integer> lsLIBORStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  620.                 dtEffective,
  621.                 "3M",
  622.                 astrMaturityTenor[i],
  623.                 null
  624.             );

  625.             List<Integer> lsFedFundStreamEdgeDate = CompositePeriodBuilder.OvernightEdgeDates (
  626.                 dtEffective,
  627.                 dtEffective.addTenor (astrMaturityTenor[i]),
  628.                 strCurrency
  629.             );

  630.             Stream streamLIBOR = new Stream (
  631.                 CompositePeriodBuilder.FloatingCompositeUnit (
  632.                     lsLIBORStreamEdgeDate,
  633.                     cpsLIBOR,
  634.                     cfusLIBOR
  635.                 )
  636.             );

  637.             Stream streamFedFund = new Stream (
  638.                 CompositePeriodBuilder.FloatingCompositeUnit (
  639.                     lsFedFundStreamEdgeDate,
  640.                     cpsFedFund,
  641.                     cfusFedFund
  642.                 )
  643.             );

  644.             aFFC[i] = new FloatFloatComponent (
  645.                 streamLIBOR,
  646.                 streamFedFund,
  647.                 csp
  648.             );
  649.         }

  650.         return aFFC;
  651.     }

  652.     /*
  653.      * Construct the Array of Overnight Index Instruments from the given set of parameters
  654.      *
  655.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  656.      */

  657.     private static final FixFloatComponent[] SwapInstrumentsFromMaturityTenor (
  658.         final JulianDate dtEffective,
  659.         final String[] astrMaturityTenor,
  660.         final double[] adblCoupon,
  661.         final String strCurrency)
  662.         throws Exception
  663.     {
  664.         FixFloatComponent[] aOIS = new FixFloatComponent[astrMaturityTenor.length];

  665.         UnitCouponAccrualSetting ucasFixed = new UnitCouponAccrualSetting (
  666.             2,
  667.             "Act/360",
  668.             false,
  669.             "Act/360",
  670.             false,
  671.             strCurrency,
  672.             false,
  673.             CompositePeriodBuilder.ACCRUAL_COMPOUNDING_RULE_GEOMETRIC
  674.         );

  675.         CashSettleParams csp = new CashSettleParams (
  676.             0,
  677.             strCurrency,
  678.             0
  679.         );

  680.         for (int i = 0; i < astrMaturityTenor.length; ++i) {
  681.             java.lang.String strFixedTenor = Helper.LEFT_TENOR_LESSER == Helper.TenorCompare (
  682.                 astrMaturityTenor[i],
  683.                 "6M"
  684.             ) ? astrMaturityTenor[i] : "6M";

  685.             java.lang.String strFloatingTenor = Helper.LEFT_TENOR_LESSER == Helper.TenorCompare (
  686.                 astrMaturityTenor[i],
  687.                 "3M"
  688.             ) ? astrMaturityTenor[i] : "3M";

  689.             ComposableFloatingUnitSetting cfusFloating = new ComposableFloatingUnitSetting (
  690.                 "3M",
  691.                 CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  692.                 null,
  693.                 ForwardLabel.Create (
  694.                     strCurrency,
  695.                     "3M"
  696.                 ),
  697.                 CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  698.                 0.
  699.             );

  700.             ComposableFixedUnitSetting cfusFixed = new ComposableFixedUnitSetting (
  701.                 strFixedTenor,
  702.                 CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  703.                 null,
  704.                 adblCoupon[i],
  705.                 0.,
  706.                 strCurrency
  707.             );

  708.             CompositePeriodSetting cpsFloating = new CompositePeriodSetting (
  709.                 4,
  710.                 strFloatingTenor,
  711.                 strCurrency,
  712.                 null,
  713.                 -1.,
  714.                 null,
  715.                 null,
  716.                 null,
  717.                 null
  718.             );

  719.             CompositePeriodSetting cpsFixed = new CompositePeriodSetting (
  720.                 2,
  721.                 strFixedTenor,
  722.                 strCurrency,
  723.                 null,
  724.                 1.,
  725.                 null,
  726.                 null,
  727.                 null,
  728.                 null
  729.             );

  730.             List<Integer> lsFixedStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  731.                 dtEffective,
  732.                 strFixedTenor,
  733.                 astrMaturityTenor[i],
  734.                 null
  735.             );

  736.             List<Integer> lsFloatingStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  737.                 dtEffective,
  738.                 strFloatingTenor,
  739.                 astrMaturityTenor[i],
  740.                 null
  741.             );

  742.             Stream floatingStream = new Stream (
  743.                 CompositePeriodBuilder.FloatingCompositeUnit (
  744.                     lsFloatingStreamEdgeDate,
  745.                     cpsFloating,
  746.                     cfusFloating
  747.                 )
  748.             );

  749.             Stream fixedStream = new Stream (
  750.                 CompositePeriodBuilder.FixedCompositeUnit (
  751.                     lsFixedStreamEdgeDate,
  752.                     cpsFixed,
  753.                     ucasFixed,
  754.                     cfusFixed
  755.                 )
  756.             );

  757.             FixFloatComponent ois = new FixFloatComponent (
  758.                 fixedStream,
  759.                 floatingStream,
  760.                 csp
  761.             );

  762.             ois.setPrimaryCode ("OIS." + astrMaturityTenor[i] + "." + strCurrency);

  763.             aOIS[i] = ois;
  764.         }

  765.         return aOIS;
  766.     }

  767.     public static final void main (
  768.         final String[] astrArgs)
  769.         throws Exception
  770.     {
  771.         /*
  772.          * Initialize the Credit Analytics Library
  773.          */

  774.         EnvManager.InitEnv ("");

  775.         String strCurrency = "USD";

  776.         JulianDate dtToday = DateUtil.CreateFromYMD (
  777.             2012,
  778.             DateUtil.DECEMBER,
  779.             11
  780.         );

  781.         MergedDiscountForwardCurve dcOIS = OISDiscountCurve (
  782.             dtToday,
  783.             strCurrency,
  784.             "OVERNIGHT INDEX RUN RECONCILIATION"
  785.         );

  786.         ForwardCurve fc = MakexMForwardCurve (
  787.             dtToday,
  788.             strCurrency,
  789.             dcOIS,
  790.             3,
  791.             new String[] {
  792.                 "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y"
  793.             },
  794.             "ReferenceParBasisSpread",
  795.             new double[] {
  796.                 0.00186,    //  1Y
  797.                 0.00127,    //  2Y
  798.                 0.00097,    //  3Y
  799.                 0.00080,    //  4Y
  800.                 0.00067,    //  5Y
  801.                 0.00058,    //  6Y
  802.                 0.00051,    //  7Y
  803.                 0.00046,    //  8Y
  804.                 0.00042,    //  9Y
  805.                 0.00038,    // 10Y
  806.                 0.00035,    // 11Y
  807.                 0.00033,    // 12Y
  808.                 0.00028,    // 15Y
  809.                 0.00022,    // 20Y
  810.                 0.00020,    // 25Y
  811.                 0.00018     // 30Y
  812.             }
  813.         );

  814.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  815.             dcOIS,
  816.             null,
  817.             null,
  818.             null,
  819.             null,
  820.             null,
  821.             null
  822.         );

  823.         mktParams.setForwardState (fc);

  824.         String[] astrMaturityTenor = new String[] {
  825.             "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y"
  826.         };

  827.         FloatFloatComponent[] aFedFundLIBORSwap = FedFundLIBORBasisSwap (
  828.             dtToday,
  829.             strCurrency,
  830.             astrMaturityTenor
  831.         );

  832.         FixFloatComponent[] aOIS = OISFromMaturityTenor (
  833.             dtToday,
  834.             strCurrency,
  835.             astrMaturityTenor,
  836.             new double[] {
  837.                 0.00002,
  838.                 0.00036,
  839.                 0.00127,
  840.                 0.00274,
  841.                 0.00456,
  842.                 0.00647,
  843.                 0.00827,
  844.                 0.00996,
  845.                 0.01147,
  846.                 0.01280,
  847.                 0.01404,
  848.                 0.01516,
  849.                 0.01764,
  850.                 0.01939,
  851.                 0.02003,
  852.                 0.02038
  853.             }
  854.         );

  855.         FixFloatComponent[] aIRS = SwapInstrumentsFromMaturityTenor (
  856.             dtToday,
  857.             astrMaturityTenor,
  858.             new double[] {
  859.                 0.00002,
  860.                 0.00036,
  861.                 0.00127,
  862.                 0.00274,
  863.                 0.00456,
  864.                 0.00647,
  865.                 0.00827,
  866.                 0.00996,
  867.                 0.01147,
  868.                 0.01280,
  869.                 0.01404,
  870.                 0.01516,
  871.                 0.01764,
  872.                 0.01939,
  873.                 0.02003,
  874.                 0.02038
  875.             },
  876.             strCurrency
  877.         );

  878.         ValuationParams valParams = new ValuationParams (
  879.             dtToday,
  880.             dtToday,
  881.             strCurrency
  882.         );

  883.         System.out.println ("\n\t--------------------------------------------------------------------------");

  884.         System.out.println ("\t                    FED FUND OIS BASIS COMPARISON");

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

  886.         System.out.println ("\t\tOutput Order[Effective Date - Maturity Date]");

  887.         System.out.println ("\t\t\t IRS Rate (%)");

  888.         System.out.println ("\t\t\t Fed Fund LIBOR Basis (bp)");

  889.         System.out.println ("\t\t\t OIS Rate Uncompounded (%) (Bloomberg 2010 Methodology)");

  890.         System.out.println ("\t\t\t OIS Rate Daily Compounded (%) (Bloomberg 2010 Methodology)");

  891.         System.out.println ("\t\t\t OIS Rate (%) From Full Calibration\n");

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

  893.         for (int i = 0; i < aFedFundLIBORSwap.length; ++i) {
  894.             Map<String, Double> mapOIS = aOIS[i].value (
  895.                 valParams,
  896.                 null,
  897.                 mktParams,
  898.                 null
  899.             );

  900.             Map<String, Double> mapIRS = aIRS[i].value (
  901.                 valParams,
  902.                 null,
  903.                 mktParams,
  904.                 null
  905.             );

  906.             double dblOISRate = mapOIS.get ("SwapRate");

  907.             double dblIRSRate = mapIRS.get ("SwapRate");

  908.             double dblLIBORFedFundBasis = dblIRSRate - dblOISRate;

  909.             System.out.println ("\t[" +
  910.                 aFedFundLIBORSwap[i].effectiveDate() + " - " +
  911.                 aFedFundLIBORSwap[i].maturityDate() + "] => " +
  912.                 FormatUtil.FormatDouble (dblIRSRate, 1, 4, 100.) + "% | " +
  913.                 FormatUtil.FormatDouble (dblLIBORFedFundBasis, 1, 1, 10000.) + " | " +
  914.                 FormatUtil.FormatDouble (Helper.OISFromLIBORSwapFedFundBasis (dblIRSRate, -dblLIBORFedFundBasis), 1, 4, 100.) + "% | " +
  915.                 FormatUtil.FormatDouble (Helper.OISFromLIBORSwapFedFundBasis2 (dblIRSRate, -dblLIBORFedFundBasis), 1, 4, 100.) + "% | " +
  916.                 FormatUtil.FormatDouble (dblOISRate, 1, 4, 100.) + "%"
  917.             );
  918.         }

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

  920.         EnvManager.TerminateEnv();
  921.     }
  922. }