RegressionSplineCashCurve.java

  1. package org.drip.sample.bond;

  2. import java.util.*;

  3. import org.drip.analytics.cashflow.CompositePeriod;
  4. import org.drip.analytics.date.*;
  5. import org.drip.analytics.daycount.Convention;
  6. import org.drip.analytics.support.Helper;
  7. import org.drip.numerical.common.FormatUtil;
  8. import org.drip.param.creator.MarketParamsBuilder;
  9. import org.drip.param.market.CurveSurfaceQuoteContainer;
  10. import org.drip.param.valuation.ValuationParams;
  11. import org.drip.product.creator.BondBuilder;
  12. import org.drip.product.definition.Bond;
  13. import org.drip.service.env.EnvManager;
  14. import org.drip.spline.basis.PolynomialFunctionSetParams;
  15. import org.drip.spline.grid.OverlappingStretchSpan;
  16. import org.drip.spline.params.*;
  17. import org.drip.spline.stretch.*;
  18. import org.drip.state.curve.DiscountFactorDiscountCurve;
  19. import org.drip.state.discount.MergedDiscountForwardCurve;

  20. /*
  21.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  22.  */

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

  96. /**
  97.  * <i>RegressionSplineCashCurve</i> demonstrates the Functionality behind the Regression Spline based OLS
  98.  * best-fit Construction of a Cash Bond Discount Curve Based on Input Price/Yield.
  99.  *  
  100.  * <br><br>
  101.  *  <ul>
  102.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  103.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  104.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">DROP API Construction and Usage</a></li>
  105.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/bond/README.md">Bullet, EOS Bond Metrics + Curve</a></li>
  106.  *  </ul>
  107.  * <br><br>
  108.  *
  109.  * @author Lakshmi Krishnamurthy
  110.  */

  111. public class RegressionSplineCashCurve {

  112.     static class CashFlowYieldDF {
  113.         double _dblCumulativeCashFlow = java.lang.Double.NaN;
  114.         double _dblDiscountedCumulativeCashFlow = java.lang.Double.NaN;

  115.         CashFlowYieldDF (
  116.             final double dblCashFlow,
  117.             final double dblYieldDF)
  118.         {
  119.             _dblDiscountedCumulativeCashFlow = (_dblCumulativeCashFlow = dblCashFlow) * dblYieldDF;
  120.         }

  121.         void accumulate (
  122.             final double dblCashFlow,
  123.             final double dblYieldDF)
  124.         {
  125.             _dblCumulativeCashFlow += dblCashFlow;
  126.             _dblDiscountedCumulativeCashFlow += dblCashFlow * dblYieldDF;
  127.         }

  128.         double cumulativeCashFlow()
  129.         {
  130.             return _dblCumulativeCashFlow;
  131.         }

  132.         double discountedCumulativeCashFlow()
  133.         {
  134.             return _dblDiscountedCumulativeCashFlow;
  135.         }

  136.         double weightedDF()
  137.         {
  138.             return _dblDiscountedCumulativeCashFlow / _dblCumulativeCashFlow;
  139.         }
  140.     }

  141.     private static final SegmentCustomBuilderControl PolynomialSplineSegmentBuilder()
  142.         throws Exception
  143.     {
  144.         int iCk = 2;
  145.         int iNumPolyBasis = 4;

  146.         SegmentInelasticDesignControl sdic = new SegmentInelasticDesignControl (
  147.             iCk,
  148.             null, // SegmentFlexurePenaltyControl (iLengthPenaltyDerivativeOrder, dblLengthPenaltyAmplitude)
  149.             null  // SegmentFlexurePenaltyControl (iCurvaturePenaltyDerivativeOrder, dblCurvaturePenaltyAmplitude)
  150.         );

  151.         return new SegmentCustomBuilderControl (
  152.             MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  153.             new PolynomialFunctionSetParams (iNumPolyBasis),
  154.             sdic,
  155.             null,
  156.             null
  157.         );
  158.     }

  159.     private static final Bond FixedCouponBond (
  160.         final String strName,
  161.         final JulianDate dtEffective,
  162.         final JulianDate dtMaturity,
  163.         final double dblCoupon,
  164.         final String strCurrency,
  165.         final String strDayCount,
  166.         final int iFreq)
  167.         throws Exception
  168.     {
  169.         return BondBuilder.CreateSimpleFixed (
  170.             strName,
  171.             strCurrency,
  172.             "",
  173.             dblCoupon,
  174.             iFreq,
  175.             strDayCount,
  176.             dtEffective,
  177.             dtMaturity,
  178.             null,
  179.             null
  180.         );
  181.     }

  182.     private static final Bond[] CalibBondSet (
  183.         final String strCurrency,
  184.         final String strDayCount)
  185.         throws Exception
  186.     {
  187.         Bond bond1 = FixedCouponBond (
  188.             "MBONO  8.00  12/17/2015",
  189.             DateUtil.CreateFromYMD (
  190.                 2006,
  191.                 DateUtil.JANUARY,
  192.                 5
  193.             ),
  194.             DateUtil.CreateFromYMD (
  195.                 2015,
  196.                 DateUtil.DECEMBER,
  197.                 17
  198.             ),
  199.             0.08,
  200.             strCurrency,
  201.             strDayCount,
  202.             2
  203.         );

  204.         Bond bond2 = FixedCouponBond (
  205.             "MBONO  6.25  06/16/2016",
  206.             DateUtil.CreateFromYMD (
  207.                 2011,
  208.                 DateUtil.JULY,
  209.                 22
  210.             ),
  211.             DateUtil.CreateFromYMD (
  212.                 2016,
  213.                 DateUtil.JUNE,
  214.                 16
  215.             ),
  216.             0.08,
  217.             strCurrency,
  218.             strDayCount,
  219.             2
  220.         );

  221.         Bond bond3 = FixedCouponBond (
  222.             "MBONO  7.25  12/15/2016",
  223.             DateUtil.CreateFromYMD (
  224.                 2007,
  225.                 DateUtil.FEBRUARY,
  226.                 1
  227.             ),
  228.             DateUtil.CreateFromYMD (
  229.                 2016,
  230.                 DateUtil.DECEMBER,
  231.                 15
  232.             ),
  233.             0.0725,
  234.             strCurrency,
  235.             strDayCount,
  236.             2
  237.         );

  238.         Bond bond4 = FixedCouponBond (
  239.             "MBONO  5.00  06/15/2017",
  240.             DateUtil.CreateFromYMD (
  241.                 2012,
  242.                 DateUtil.JULY,
  243.                 19
  244.             ),
  245.             DateUtil.CreateFromYMD (
  246.                 2017,
  247.                 DateUtil.JUNE,
  248.                 15
  249.             ),
  250.             0.0500,
  251.             strCurrency,
  252.             strDayCount,
  253.             2
  254.         );

  255.         Bond bond5 = FixedCouponBond (
  256.             "MBONO  7.75  12/14/2017",
  257.             DateUtil.CreateFromYMD (
  258.                 2008,
  259.                 DateUtil.JANUARY,
  260.                 31
  261.             ),
  262.             DateUtil.CreateFromYMD (
  263.                 2017,
  264.                 DateUtil.DECEMBER,
  265.                 14
  266.             ),
  267.             0.0775,
  268.             strCurrency,
  269.             strDayCount,
  270.             2
  271.         );

  272.         Bond bond6 = FixedCouponBond (
  273.             "MBONO  4.75  06/14/2018",
  274.             DateUtil.CreateFromYMD (
  275.                 2013,
  276.                 DateUtil.AUGUST,
  277.                 30
  278.             ),
  279.             DateUtil.CreateFromYMD (
  280.                 2018,
  281.                 DateUtil.JUNE,
  282.                 14
  283.             ),
  284.             0.0475,
  285.             strCurrency,
  286.             strDayCount,
  287.             2
  288.         );

  289.         Bond bond7 = FixedCouponBond (
  290.             "MBONO  8.50  12/13/2018",
  291.             DateUtil.CreateFromYMD (
  292.                 2009,
  293.                 DateUtil.FEBRUARY,
  294.                 12
  295.             ),
  296.             DateUtil.CreateFromYMD (
  297.                 2018,
  298.                 DateUtil.DECEMBER,
  299.                 13
  300.             ),
  301.             0.085,
  302.             strCurrency,
  303.             strDayCount,
  304.             2
  305.         );

  306.         Bond bond8 = FixedCouponBond (
  307.             "MBONO  5.00  12/11/2019",
  308.             DateUtil.CreateFromYMD (
  309.                 2014,
  310.                 DateUtil.NOVEMBER,
  311.                 7
  312.             ),
  313.             DateUtil.CreateFromYMD (
  314.                 2019,
  315.                 DateUtil.DECEMBER,
  316.                 11
  317.             ),
  318.             0.05,
  319.             strCurrency,
  320.             strDayCount,
  321.             2
  322.         );

  323.         Bond bond9 = FixedCouponBond (
  324.             "MBONO  8.00  06/11/2020",
  325.             DateUtil.CreateFromYMD (
  326.                 2010,
  327.                 DateUtil.FEBRUARY,
  328.                 25
  329.             ),
  330.             DateUtil.CreateFromYMD (
  331.                 2020,
  332.                 DateUtil.JUNE,
  333.                 11
  334.             ),
  335.             0.08,
  336.             strCurrency,
  337.             strDayCount,
  338.             2
  339.         );

  340.         Bond bond10 = FixedCouponBond (
  341.             "MBONO  6.50  06/10/2021",
  342.             DateUtil.CreateFromYMD (
  343.                 2011,
  344.                 DateUtil.FEBRUARY,
  345.                 3
  346.             ),
  347.             DateUtil.CreateFromYMD (
  348.                 2021,
  349.                 DateUtil.JUNE,
  350.                 10
  351.             ),
  352.             0.065,
  353.             strCurrency,
  354.             strDayCount,
  355.             2
  356.         );

  357.         Bond bond11 = FixedCouponBond (
  358.             "MBONO  6.50  06/09/2022",
  359.             DateUtil.CreateFromYMD (
  360.                 2012,
  361.                 DateUtil.FEBRUARY,
  362.                 15
  363.             ),
  364.             DateUtil.CreateFromYMD (
  365.                 2022,
  366.                 DateUtil.JUNE,
  367.                 9
  368.             ),
  369.             0.065,
  370.             strCurrency,
  371.             strDayCount,
  372.             2
  373.         );

  374.         Bond bond12 = FixedCouponBond (
  375.             "MBONO  8.00  12/07/2023",
  376.             DateUtil.CreateFromYMD (
  377.                 2003,
  378.                 DateUtil.OCTOBER,
  379.                 30
  380.             ),
  381.             DateUtil.CreateFromYMD (
  382.                 2023,
  383.                 DateUtil.DECEMBER,
  384.                 7
  385.             ),
  386.             0.065,
  387.             strCurrency,
  388.             strDayCount,
  389.             2
  390.         );

  391.         Bond bond13 = FixedCouponBond (
  392.             "MBONO 10.00  12/05/2024",
  393.             DateUtil.CreateFromYMD (
  394.                 2005,
  395.                 DateUtil.JANUARY,
  396.                 20
  397.             ),
  398.             DateUtil.CreateFromYMD (
  399.                 2024,
  400.                 DateUtil.DECEMBER,
  401.                 5
  402.             ),
  403.             0.1,
  404.             strCurrency,
  405.             strDayCount,
  406.             2
  407.         );

  408.         Bond bond14 = FixedCouponBond (
  409.             "MBONO  7.50  06/03/2027",
  410.             DateUtil.CreateFromYMD (
  411.                 2007,
  412.                 DateUtil.JANUARY,
  413.                 18
  414.             ),
  415.             DateUtil.CreateFromYMD (
  416.                 2027,
  417.                 DateUtil.JUNE,
  418.                 3
  419.             ),
  420.             0.075,
  421.             strCurrency,
  422.             strDayCount,
  423.             2
  424.         );

  425.         Bond bond15 = FixedCouponBond (
  426.             "MBONO  8.50  05/31/2029",
  427.             DateUtil.CreateFromYMD (
  428.                 2009,
  429.                 DateUtil.JANUARY,
  430.                 15
  431.             ),
  432.             DateUtil.CreateFromYMD (
  433.                 2029,
  434.                 DateUtil.MAY,
  435.                 31
  436.             ),
  437.             0.085,
  438.             strCurrency,
  439.             strDayCount,
  440.             2
  441.         );

  442.         Bond bond16 = FixedCouponBond (
  443.             "MBONO  7.75  05/29/2031",
  444.             DateUtil.CreateFromYMD (
  445.                 2009,
  446.                 DateUtil.SEPTEMBER,
  447.                 11
  448.             ),
  449.             DateUtil.CreateFromYMD (
  450.                 2031,
  451.                 DateUtil.MAY,
  452.                 29
  453.             ),
  454.             0.0775,
  455.             strCurrency,
  456.             strDayCount,
  457.             2
  458.         );

  459.         Bond bond17 = FixedCouponBond (
  460.             "MBONO  7.75  11/23/2034",
  461.             DateUtil.CreateFromYMD (
  462.                 2014,
  463.                 DateUtil.APRIL,
  464.                 11
  465.             ),
  466.             DateUtil.CreateFromYMD (
  467.                 2034,
  468.                 DateUtil.NOVEMBER,
  469.                 23
  470.             ),
  471.             0.0775,
  472.             strCurrency,
  473.             strDayCount,
  474.             2
  475.         );

  476.         Bond bond18 = FixedCouponBond (
  477.             "MBONO 10.00  11/20/2036",
  478.             DateUtil.CreateFromYMD (
  479.                 2006,
  480.                 DateUtil.OCTOBER,
  481.                 26
  482.             ),
  483.             DateUtil.CreateFromYMD (
  484.                 2036,
  485.                 DateUtil.NOVEMBER,
  486.                 20
  487.             ),
  488.             0.1,
  489.             strCurrency,
  490.             strDayCount,
  491.             2
  492.         );

  493.         Bond bond19 = FixedCouponBond (
  494.             "MBONO  8.50  11/18/2038",
  495.             DateUtil.CreateFromYMD (
  496.                 2009,
  497.                 DateUtil.JANUARY,
  498.                 29
  499.             ),
  500.             DateUtil.CreateFromYMD (
  501.                 2038,
  502.                 DateUtil.NOVEMBER,
  503.                 18
  504.             ),
  505.             0.085,
  506.             strCurrency,
  507.             strDayCount,
  508.             2
  509.         );

  510.         Bond bond20 = FixedCouponBond (
  511.             "MBONO  7.75  11/13/2042",
  512.             DateUtil.CreateFromYMD (
  513.                 2012,
  514.                 DateUtil.APRIL,
  515.                 20
  516.             ),
  517.             DateUtil.CreateFromYMD (
  518.                 2042,
  519.                 DateUtil.NOVEMBER,
  520.                 13
  521.             ),
  522.             0.0775,
  523.             strCurrency,
  524.             strDayCount,
  525.             2
  526.         );

  527.         return new Bond[] {
  528.             bond1,
  529.             bond2,
  530.             bond3,
  531.             bond4,
  532.             bond5,
  533.             bond6,
  534.             bond7,
  535.             bond8,
  536.             bond9,
  537.             bond10,
  538.             bond11,
  539.             bond12,
  540.             bond13,
  541.             bond14,
  542.             bond15,
  543.             bond16,
  544.             bond17,
  545.             bond18,
  546.             bond19,
  547.             bond20
  548.         };
  549.     }

  550.     private static final Map<JulianDate, CashFlowYieldDF> BondYieldFlows (
  551.         final Bond[] aBond,
  552.         final double[] adblYield,
  553.         final int iValueDate)
  554.         throws Exception
  555.     {
  556.         Map<JulianDate, CashFlowYieldDF> mapDateYieldDF = new TreeMap<JulianDate, CashFlowYieldDF>();

  557.         ValuationParams valParams = new ValuationParams (
  558.             new JulianDate (iValueDate),
  559.             new JulianDate (iValueDate),
  560.             ""
  561.         );

  562.         for (int i = 0; i < aBond.length; ++i) {
  563.             for (CompositePeriod cp : aBond[i].couponPeriods()) {
  564.                 if (cp.payDate() <= iValueDate) continue;

  565.                 double dblCashFlow = aBond[i].couponMetrics (
  566.                     cp.endDate(),
  567.                     valParams,
  568.                     null
  569.                 ).rate() / aBond[i].freq();

  570.                 double dblYieldDF = Helper.Yield2DF (
  571.                     aBond[i].freq(),
  572.                     adblYield[i],
  573.                     Convention.YearFraction (
  574.                         iValueDate,
  575.                         cp.payDate(),
  576.                         aBond[i].couponDC(),
  577.                         false,
  578.                         null,
  579.                         aBond[i].currency()
  580.                     )
  581.                 );

  582.                 JulianDate dtPay = new JulianDate (cp.payDate());

  583.                 if (mapDateYieldDF.containsKey (dtPay))
  584.                     mapDateYieldDF.get (dtPay).accumulate (
  585.                         dblCashFlow,
  586.                         dblYieldDF
  587.                     );
  588.                 else
  589.                     mapDateYieldDF.put (
  590.                         dtPay,
  591.                         new CashFlowYieldDF (
  592.                             dblCashFlow,
  593.                             dblYieldDF
  594.                         )
  595.                     );
  596.             }

  597.             JulianDate dtMaturity = aBond[i].maturityDate();

  598.             double dblYieldDF = Helper.Yield2DF (
  599.                 aBond[i].freq(),
  600.                 adblYield[i],
  601.                 Convention.YearFraction (
  602.                     iValueDate,
  603.                     dtMaturity.julian(),
  604.                     aBond[i].couponDC(),
  605.                     false,
  606.                     null,
  607.                     aBond[i].currency()
  608.                 )
  609.             );

  610.             if (mapDateYieldDF.containsKey (dtMaturity))
  611.                 mapDateYieldDF.get (dtMaturity).accumulate (
  612.                     1.,
  613.                     dblYieldDF
  614.                 );
  615.             else
  616.                 mapDateYieldDF.put (
  617.                     dtMaturity,
  618.                     new CashFlowYieldDF (
  619.                         1.,
  620.                         dblYieldDF
  621.                     )
  622.                 );
  623.         }

  624.         return mapDateYieldDF;
  625.     }

  626.     private static final StretchBestFitResponse SBFR (
  627.         final Map<JulianDate, CashFlowYieldDF> mapDateYieldDF)
  628.         throws Exception
  629.     {
  630.         int iMapSize = mapDateYieldDF.size();

  631.         int i = 0;
  632.         int[] aiDate = new int[iMapSize];
  633.         double[] adblYieldDF = new double[iMapSize];
  634.         double[] adblWeight = new double[iMapSize];

  635.         for (Map.Entry<JulianDate, CashFlowYieldDF> me : mapDateYieldDF.entrySet()) {
  636.             aiDate[i] = me.getKey().julian();

  637.             adblYieldDF[i] = me.getValue().weightedDF();

  638.             adblWeight[i] = me.getValue().cumulativeCashFlow();

  639.             ++i;
  640.         }

  641.         return StretchBestFitResponse.Create (
  642.             aiDate,
  643.             adblYieldDF,
  644.             adblWeight
  645.         );
  646.     }

  647.     private static final MultiSegmentSequence BondRegressionSplineStretch (
  648.         final JulianDate dtSpot,
  649.         final Bond[] aBondSet,
  650.         final int iNumKnots,
  651.         final Map<JulianDate, CashFlowYieldDF> mapDateDF)
  652.         throws Exception
  653.     {
  654.         SegmentCustomBuilderControl scbc = PolynomialSplineSegmentBuilder();

  655.         double dblXStart = dtSpot.julian();

  656.         double dblXFinish = aBondSet[aBondSet.length - 1].maturityDate().julian();

  657.         double adblX[] = new double[iNumKnots + 2];
  658.         adblX[0] = dblXStart;

  659.         for (int i = 1; i < adblX.length; ++i)
  660.             adblX[i] = adblX[i - 1] + (dblXFinish - dblXStart) / (iNumKnots + 1);

  661.         SegmentCustomBuilderControl[] aSCBC = new SegmentCustomBuilderControl[adblX.length - 1];

  662.         for (int i = 0; i < adblX.length - 1; ++i)
  663.             aSCBC[i] = scbc;

  664.         return MultiSegmentSequenceBuilder.CreateCalibratedStretchEstimator (
  665.             "SPLINE_STRETCH",
  666.             adblX,
  667.             1.,
  668.             null,
  669.             aSCBC,
  670.             SBFR (mapDateDF),
  671.             BoundarySettings.NaturalStandard(),
  672.             MultiSegmentSequence.CALIBRATE
  673.         );
  674.     }

  675.     public static final void main (
  676.         final String[] astrArgs)
  677.         throws Exception
  678.     {
  679.         EnvManager.InitEnv (
  680.             "",
  681.             true
  682.         );

  683.         int iNumKnots = 10;
  684.         String strCurrency = "MXN";
  685.         String strDayCount = "30/360";

  686.         JulianDate dtSpot = DateUtil.CreateFromYMD (
  687.             2015,
  688.             DateUtil.JUNE,
  689.             13
  690.         );

  691.         double[] aCalibYield = new double[] {
  692.             0.0315960,
  693.             0.0354184,
  694.             0.0389543,
  695.             0.0412860,
  696.             0.0435245,
  697.             0.0464521,
  698.             0.0486307,
  699.             0.0524561,
  700.             0.0532168,
  701.             0.0562230,
  702.             0.0585227,
  703.             0.0606205,
  704.             0.0611038,
  705.             0.0637935,
  706.             0.0648727,
  707.             0.0661705,
  708.             0.0673744,
  709.             0.0675774,
  710.             0.0683684,
  711.             0.0684978
  712.         };

  713.         Bond[] aBondSet = CalibBondSet (
  714.             strCurrency,
  715.             strDayCount
  716.         );

  717.         Map<JulianDate, CashFlowYieldDF> mapDateDF = BondYieldFlows (
  718.             aBondSet,
  719.             aCalibYield,
  720.             dtSpot.julian()
  721.         );

  722.         MultiSegmentSequence mss = BondRegressionSplineStretch (
  723.             dtSpot,
  724.             aBondSet,
  725.             iNumKnots,
  726.             mapDateDF
  727.         );

  728.         MergedDiscountForwardCurve dfdc = new DiscountFactorDiscountCurve (
  729.             strCurrency,
  730.             new OverlappingStretchSpan (mss)
  731.         );

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

  733.         System.out.println ("\t|  Curve Stretch [" +
  734.             new JulianDate ((int) mss.getLeftPredictorOrdinateEdge()) + " -> " +
  735.             new JulianDate ((int) mss.getRightPredictorOrdinateEdge()) + "]  |"
  736.         );

  737.         System.out.println ("\t|--------------------------------------------|");

  738.         for (Map.Entry<JulianDate, CashFlowYieldDF> me : mapDateDF.entrySet()) {
  739.             System.out.println (
  740.                 "\t|\t " + me.getKey() + " => " +
  741.                 FormatUtil.FormatDouble (me.getValue().weightedDF(), 1, 4, 1.) + " | " +
  742.                 FormatUtil.FormatDouble (dfdc.df (me.getKey().julian()), 1, 4, 1.) + "     |"
  743.             );
  744.         }

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

  746.         System.out.println ("\t|---------------------------------------------------------------||");

  747.         System.out.println ("\t|     Market Yield vs. Regression Curve                         ||");

  748.         System.out.println ("\t|---------------------------------------------------------------||");

  749.         System.out.println ("\t|     L -> R                                                    ||");

  750.         System.out.println ("\t|           Bond Name                                           ||");

  751.         System.out.println ("\t|           Market Yield                                        ||");

  752.         System.out.println ("\t|           Regressed Yield (Bond Basis)                        ||");

  753.         System.out.println ("\t|           Regressed Yield (Yield Spread)                      ||");

  754.         System.out.println ("\t|           Continuous Zero To Maturity                         ||");

  755.         System.out.println ("\t|---------------------------------------------------------------||");

  756.         ValuationParams valParams = new ValuationParams (
  757.             dtSpot,
  758.             dtSpot,
  759.             ""
  760.         );

  761.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Discount (dfdc);

  762.         for (int i = 0; i < aBondSet.length; ++i) {
  763.             System.out.println (
  764.                 "\t| " + aBondSet[i].name() + " ==> " +
  765.                 FormatUtil.FormatDouble (aCalibYield[i], 1, 2, 100.) + "% | " +
  766.                 FormatUtil.FormatDouble (aBondSet[i].yieldFromBondBasis (
  767.                     valParams,
  768.                     mktParams,
  769.                     null,
  770.                     0.
  771.                 ), 1, 2, 100.) + "% | " +
  772.                 FormatUtil.FormatDouble (aBondSet[i].yieldFromYieldSpread (
  773.                     valParams,
  774.                     mktParams,
  775.                     null,
  776.                     0.
  777.                 ), 1, 2, 100.) + "% | " +
  778.                 FormatUtil.FormatDouble (dfdc.zero (
  779.                     aBondSet[i].maturityDate().julian()
  780.                 ), 1, 2, 100.) + "% || "
  781.             );
  782.         }

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

  784.         EnvManager.TerminateEnv();
  785.     }
  786. }