RelativeValueMeasuresGeneration.java

  1. package org.drip.sample.bond;

  2. /*
  3.  * Credit Product imports
  4.  */

  5. import org.drip.analytics.date.*;
  6. import org.drip.analytics.daycount.Convention;
  7. import org.drip.analytics.support.*;
  8. import org.drip.market.otc.*;
  9. import org.drip.numerical.common.FormatUtil;
  10. import org.drip.param.definition.*;
  11. import org.drip.param.market.*;
  12. import org.drip.param.quote.*;
  13. import org.drip.param.valuation.*;
  14. import org.drip.product.definition.*;
  15. import org.drip.product.govvie.TreasuryComponent;
  16. import org.drip.product.rates.*;
  17. import org.drip.analytics.output.BondRVMeasures;
  18. import org.drip.param.creator.*;
  19. import org.drip.product.creator.*;
  20. import org.drip.product.credit.BondComponent;
  21. import org.drip.service.env.EnvManager;
  22. import org.drip.service.template.TreasuryBuilder;
  23. import org.drip.state.creator.*;
  24. import org.drip.state.discount.MergedDiscountForwardCurve;
  25. import org.drip.state.govvie.GovvieCurve;
  26. import org.drip.state.identifier.ForwardLabel;

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

  102. /**
  103.  * <i>RelativeValueMeasuresGeneration</i> is a Bond RV Measures Generation Sample demonstrating the
  104.  * invocation and usage of Bond RV Measures functionality. It shows the following:
  105.  *
  106.  * <ul>
  107.  *  <li>
  108.  *      Create the discount/treasury curve from rates/treasury instruments.
  109.  *  </li>
  110.  *  <li>
  111.  *      Compute the work-out date given the price.
  112.  *  </li>
  113.  *  <li>
  114.  *      Compute and display the base RV measures to the work-out date.
  115.  *  </li>
  116.  *  <li>
  117.  *      Compute and display the bumped RV measures to the work-out date.
  118.  *  </li>
  119.  * </ul>
  120.  *  
  121.  * <br><br>
  122.  *  <ul>
  123.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  124.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  125.  *      <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>
  126.  *      <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>
  127.  *  </ul>
  128.  * <br><br>
  129.  *
  130.  * @author Lakshmi Krishnamurthy
  131.  */

  132. public class RelativeValueMeasuresGeneration {

  133.     private static final FixFloatComponent OTCIRS (
  134.         final JulianDate dtSpot,
  135.         final String strCurrency,
  136.         final String strMaturityTenor,
  137.         final double dblCoupon)
  138.     {
  139.         FixedFloatSwapConvention ffConv = IBORFixedFloatContainer.ConventionFromJurisdiction (
  140.             strCurrency,
  141.             "ALL",
  142.             strMaturityTenor,
  143.             "MAIN"
  144.         );

  145.         return ffConv.createFixFloatComponent (
  146.             dtSpot,
  147.             strMaturityTenor,
  148.             dblCoupon,
  149.             0.,
  150.             1.
  151.         );
  152.     }

  153.     /*
  154.      * Sample demonstrating creation of a rates curve from instruments
  155.      *
  156.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  157.      */

  158.     private static MergedDiscountForwardCurve BuildRatesCurveFromInstruments (
  159.         final JulianDate dtStart,
  160.         final String[] astrCashTenor,
  161.         final double[] adblCashRate,
  162.         final String[] astrIRSTenor,
  163.         final double[] adblIRSRate,
  164.         final double dblBump,
  165.         final String strCurrency)
  166.         throws Exception
  167.     {
  168.         int iNumDCInstruments = astrCashTenor.length + adblIRSRate.length;
  169.         int aiDate[] = new int[iNumDCInstruments];
  170.         double adblRate[] = new double[iNumDCInstruments];
  171.         String astrCalibMeasure[] = new String[iNumDCInstruments];
  172.         double adblCompCalibValue[] = new double[iNumDCInstruments];
  173.         CalibratableComponent aCompCalib[] = new CalibratableComponent[iNumDCInstruments];

  174.         // Cash Calibration

  175.         JulianDate dtCashEffective = dtStart.addBusDays (
  176.             1,
  177.             strCurrency
  178.         );

  179.         for (int i = 0; i < astrCashTenor.length; ++i) {
  180.             astrCalibMeasure[i] = "Rate";
  181.             adblRate[i] = java.lang.Double.NaN;
  182.             adblCompCalibValue[i] = adblCashRate[i] + dblBump;

  183.             aCompCalib[i] = SingleStreamComponentBuilder.Deposit (
  184.                 dtCashEffective,
  185.                 new JulianDate (aiDate[i] = dtCashEffective.addTenor (astrCashTenor[i]).julian()),
  186.                 ForwardLabel.Create (
  187.                     strCurrency,
  188.                     astrCashTenor[i]
  189.                 )
  190.             );
  191.         }

  192.         // IRS Calibration

  193.         JulianDate dtIRSEffective = dtStart.addBusDays (2, strCurrency);

  194.         for (int i = 0; i < astrIRSTenor.length; ++i) {
  195.             astrCalibMeasure[i + astrCashTenor.length] = "SwapRate";
  196.             adblRate[i + astrCashTenor.length] = java.lang.Double.NaN;
  197.             adblCompCalibValue[i + astrCashTenor.length] = adblIRSRate[i] + dblBump;

  198.             aiDate[i + astrCashTenor.length] = dtIRSEffective.addTenor (astrIRSTenor[i]).julian();

  199.             aCompCalib[i + astrCashTenor.length] = OTCIRS (
  200.                 dtIRSEffective,
  201.                 strCurrency,
  202.                 astrIRSTenor[i],
  203.                 0.
  204.             );
  205.         }

  206.         /*
  207.          * Build the IR curve from the components, their calibration measures, and their calibration quotes.
  208.          */

  209.         return ScenarioDiscountCurveBuilder.NonlinearBuild (
  210.             dtStart,
  211.             strCurrency,
  212.             aCompCalib,
  213.             adblCompCalibValue,
  214.             astrCalibMeasure,
  215.             null
  216.         );
  217.     }

  218.     /*
  219.      * Sample demonstrating creation of a set of the on-the-run treasury bonds
  220.      *
  221.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  222.      */

  223.     private static final TreasuryComponent[] OTRTreasurySet (
  224.         final JulianDate dt,
  225.         final String[] astrTenor,
  226.         final double[] adblCoupon)
  227.         throws Exception
  228.     {
  229.         TreasuryComponent aTreasury[] = new TreasuryComponent[astrTenor.length];

  230.         for (int i = 0; i < astrTenor.length; ++i)
  231.             aTreasury[i] = TreasuryBuilder.FromCode (
  232.                 "UST",
  233.                 dt,
  234.                 dt.addTenor (astrTenor[i]),
  235.                 adblCoupon[i]
  236.             );

  237.         return aTreasury;
  238.     }

  239.     /*
  240.      * Sample demonstrating building of the treasury discount curve based off the on-the run instruments and their yields
  241.      *
  242.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  243.      */

  244.     private static final GovvieCurve BuildOnTheRunGovvieCurve (
  245.         final JulianDate dt,
  246.         final Bond[] aTreasury,
  247.         final double[] adblYield)
  248.         throws Exception
  249.     {
  250.         return ScenarioGovvieCurveBuilder.CubicPolyShapePreserver (
  251.             "UST",
  252.             "UST",
  253.             aTreasury[0].currency(),
  254.             dt.julian(),
  255.             aTreasury,
  256.             adblYield,
  257.             "Yield"
  258.         );
  259.     }

  260.     /*
  261.      * Put together a named map of treasury quotes
  262.      *
  263.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  264.      */

  265.     private static final CaseInsensitiveTreeMap<ProductQuote> MakeTSYQuotes (
  266.         final String[] astrTSYTenor,
  267.         final double[] adblTSYYield)
  268.         throws Exception
  269.     {
  270.         CaseInsensitiveTreeMap<ProductQuote> mTSYQuotes = new CaseInsensitiveTreeMap<ProductQuote>();

  271.         for (int i = 0; i < astrTSYTenor.length; ++i) {
  272.             ProductMultiMeasure cmmq = new ProductMultiMeasure();

  273.             cmmq.addQuote (
  274.                 "Yield",
  275.                 new MultiSided (
  276.                     "mid",
  277.                     adblTSYYield[i],
  278.                     Double.NaN
  279.                 ),
  280.                 true
  281.             );

  282.             mTSYQuotes.put (
  283.                 astrTSYTenor[i] + "ON",
  284.                 cmmq
  285.             );
  286.         }

  287.         return mTSYQuotes;
  288.     }

  289.     /*
  290.      * Print the Bond RV Measures
  291.      *
  292.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  293.      */

  294.     private static final boolean PrintRVMeasures (
  295.         final String strPrefix,
  296.         final BondRVMeasures rv)
  297.     {
  298.         if (null == rv) return false;

  299.         System.out.println (strPrefix + "ASW: " + FormatUtil.FormatDouble (rv.asw(), 0, 0, 10000.));

  300.         System.out.println (strPrefix + "Bond Basis: " + FormatUtil.FormatDouble (rv.bondBasis(), 0, 0, 10000.));

  301.         System.out.println (strPrefix + "Convexity: " + FormatUtil.FormatDouble (rv.convexity(), 0, 2, 1000000.));

  302.         System.out.println (strPrefix + "Credit Basis: " + FormatUtil.FormatDouble (rv.creditBasis(), 0, 0, 10000.));

  303.         System.out.println (strPrefix + "Discount Margin: " + FormatUtil.FormatDouble (rv.discountMargin(), 0, 0, 10000.));

  304.         System.out.println (strPrefix + "G Spread: " + FormatUtil.FormatDouble (rv.gSpread(), 0, 0, 10000.));

  305.         System.out.println (strPrefix + "I Spread: " + FormatUtil.FormatDouble (rv.iSpread(), 0, 0, 10000.));

  306.         System.out.println (strPrefix + "Macaulay Duration: " + FormatUtil.FormatDouble (rv.macaulayDuration(), 0, 2, 1.));

  307.         System.out.println (strPrefix + "Modified Duration: " + FormatUtil.FormatDouble (rv.modifiedDuration(), 0, 2, 10000.));

  308.         System.out.println (strPrefix + "OAS: " + FormatUtil.FormatDouble (rv.oas(), 0, 0, 10000.));

  309.         System.out.println (strPrefix + "PECS: " + FormatUtil.FormatDouble (rv.pecs(), 0, 0, 10000.));

  310.         System.out.println (strPrefix + "Price: " + FormatUtil.FormatDouble (rv.price(), 0, 3, 100.));

  311.         System.out.println (strPrefix + "TSY Spread: " + FormatUtil.FormatDouble (rv.tsySpread(), 0, 0, 10000.));

  312.         try {
  313.             System.out.println (strPrefix + "Workout Date: " + new JulianDate (rv.wi().date()));
  314.         } catch (Exception e) {
  315.             e.printStackTrace();
  316.         }

  317.         System.out.println (strPrefix + "Workout Factor: " + rv.wi().factor());

  318.         System.out.println (strPrefix + "Workout Type: " + rv.wi().type());

  319.         System.out.println (strPrefix + "Workout Yield: " + FormatUtil.FormatDouble (rv.wi().yield(), 0, 3, 100.));

  320.         System.out.println (strPrefix + "Yield01: " + FormatUtil.FormatDouble (rv.yield01(), 0, 2, 10000.));

  321.         System.out.println (strPrefix + "Yield Basis: " + FormatUtil.FormatDouble (rv.bondBasis(), 0, 0, 10000.));

  322.         System.out.println (strPrefix + "Yield Spread: " + FormatUtil.FormatDouble (rv.bondBasis(), 0, 0, 10000.));

  323.         System.out.println (strPrefix + "Z Spread: " + FormatUtil.FormatDouble (rv.zSpread(), 0, 0, 10000.));

  324.         return true;
  325.     }

  326.     /*
  327.      * Sample demonstrating invocation and extraction of RV Measures from a bond
  328.      *
  329.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  330.      */

  331.     private static final void BondRVMeasuresSample()
  332.         throws Exception
  333.     {
  334.         JulianDate dtCurve = DateUtil.CreateFromYMD (
  335.             2013,
  336.             6,
  337.             27
  338.         );

  339.         JulianDate dtSettle = DateUtil.CreateFromYMD (
  340.             2013,
  341.             7,
  342.             1
  343.         );

  344.         /*
  345.          * Create the discount curve from rates instruments.
  346.          */

  347.         String[] astrCashTenor = new String[] {"3M"};
  348.         double[] adblCashRate = new double[] {0.00276};
  349.         String[] astrIRSTenor = new String[] {   "1Y",    "2Y",    "3Y",    "4Y",    "5Y",    "6Y",    "7Y",
  350.                "8Y",    "9Y",   "10Y",   "11Y",   "12Y",   "15Y",   "20Y",   "25Y",   "30Y",   "40Y",   "50Y"};
  351.         double[] adblIRSRate = new double[]  {0.00367, 0.00533, 0.00843, 0.01238, 0.01609, 0.01926, 0.02191,
  352.             0.02406, 0.02588, 0.02741, 0.02870, 0.02982, 0.03208, 0.03372, 0.03445, 0.03484, 0.03501, 0.03484};
  353.         String[] astrTSYTenor = new String[] {
  354.             "1Y", "2Y", "3Y", "5Y", "7Y", "10Y",  "30Y"
  355.         };
  356.         final double[] adblTSYCoupon = new double[] {
  357.             0.0000, 0.00375, 0.00500, 0.0100, 0.01375, 0.01375, 0.02875
  358.         };
  359.         double[] adblTSYYield = new double[] {
  360.             0.00160, 0.00397, 0.00696, 0.01421, 0.01955, 0.02529, 0.03568
  361.         };

  362.         MergedDiscountForwardCurve dc = BuildRatesCurveFromInstruments (
  363.             dtCurve,
  364.             astrCashTenor,
  365.             adblCashRate,
  366.             astrIRSTenor,
  367.             adblIRSRate,
  368.             0.,
  369.             "USD"
  370.         );

  371.         TreasuryComponent[] aTSYBond = OTRTreasurySet (
  372.             dtCurve,
  373.             astrTSYTenor,
  374.             adblTSYCoupon
  375.         );

  376.         /*
  377.          * Create the on-the-run treasury discount curve.
  378.          */

  379.         GovvieCurve gc = BuildOnTheRunGovvieCurve (
  380.             dtCurve,
  381.             aTSYBond,
  382.             adblTSYYield
  383.         );

  384.         BondComponent bond = BondBuilder.CreateSimpleFixed (    // Simple Fixed Rate Bond
  385.             "TEST",         // Name
  386.             "USD",          // Currency
  387.             "",             // Credit Curve - Empty for now
  388.             0.0875,         // Bond Coupon
  389.             2,              // Frequency
  390.             "30/360",       // Day Count
  391.             DateUtil.CreateFromYMD (
  392.                 2010,
  393.                 3,
  394.                 17
  395.             ), // Effective
  396.             DateUtil.CreateFromYMD (
  397.                 2015,
  398.                 4,
  399.                 1
  400.             ),  // Maturity
  401.             null,       // Principal Schedule
  402.             null
  403.         );

  404.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  405.             dc,
  406.             gc,
  407.             null,
  408.             null,
  409.             null,
  410.             MakeTSYQuotes (
  411.                 astrTSYTenor,
  412.                 adblTSYYield
  413.             ),
  414.             null
  415.         );

  416.         ValuationParams valParams = ValuationParams.Spot (
  417.             dtSettle,
  418.             0,
  419.             "",
  420.             Convention.DATE_ROLL_ACTUAL
  421.         );

  422.         double dblPrice = 1.1025;

  423.         /*
  424.          * Compute the work-out date given the price.
  425.          */

  426.         WorkoutInfo wi = bond.exerciseYieldFromPrice (
  427.             valParams,
  428.             mktParams,
  429.             null,
  430.             dblPrice
  431.         );

  432.         /*
  433.          * Compute the base RV measures to the work-out date.
  434.          */

  435.         BondRVMeasures rvm = bond.standardMeasures (
  436.             valParams,
  437.             null,
  438.             mktParams,
  439.             null,
  440.             wi,
  441.             dblPrice
  442.         );

  443.         PrintRVMeasures ("\tBase: ", rvm);

  444.         MergedDiscountForwardCurve dcBumped = BuildRatesCurveFromInstruments (
  445.             dtCurve,
  446.             astrCashTenor,
  447.             adblCashRate,
  448.             astrIRSTenor,
  449.             adblIRSRate,
  450.             0.0001,
  451.             "USD"
  452.         );

  453.         mktParams.setFundingState (dcBumped);

  454.         /*
  455.          * Compute the bumped RV measures to the work-out date.
  456.          */

  457.         org.drip.analytics.output.BondRVMeasures rvmBumped = bond.standardMeasures (
  458.             valParams,
  459.             null,
  460.             mktParams,
  461.             null,
  462.             wi,
  463.             dblPrice
  464.         );

  465.         PrintRVMeasures ("\tBumped: ", rvmBumped);
  466.     }

  467.     public static final void main (
  468.         final String astrArgs[])
  469.         throws Exception
  470.     {
  471.         // String strConfig = "c:\\Lakshmi\\BondAnal\\Config.xml";

  472.         EnvManager.InitEnv (
  473.             "",
  474.             true
  475.         );

  476.         BondRVMeasuresSample();

  477.         EnvManager.TerminateEnv();
  478.     }
  479. }