NonlinearGovvieCurve.java

  1. package org.drip.sample.govvie;

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

  5. import org.drip.analytics.date.*;
  6. import org.drip.numerical.common.FormatUtil;
  7. import org.drip.param.valuation.*;
  8. import org.drip.product.definition.*;
  9. import org.drip.param.creator.*;
  10. import org.drip.product.creator.*;
  11. import org.drip.service.env.EnvManager;
  12. import org.drip.state.creator.ScenarioDiscountCurveBuilder;
  13. import org.drip.state.discount.MergedDiscountForwardCurve;

  14. /*
  15.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  16.  */

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

  82. /**
  83.  * <i>NonlinearGovvieCurve</i> contains a demo of construction and usage of the non-linear treasury discount
  84.  * curve from government bond inputs. It shows the following:
  85.  *  
  86.  * <br><br>
  87.  *  <ul>
  88.  *      <li>
  89.  *          Create on-the-run TSY bond set.
  90.  *      </li>
  91.  *      <li>
  92.  *          Calibrate a discount curve off of the on-the-run yields and calculate the implied zeroes and
  93.  *              DF's.
  94.  *      </li>
  95.  *      <li>
  96.  *          Price an off-the-run TSY.
  97.  *      </li>
  98.  *  </ul>
  99.  *  
  100.  * <br><br>
  101.  *  <ul>
  102.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/AnalyticsCore.md">Analytics Core Module</a></li>
  103.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics Library</a></li>
  104.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">Sample</a></li>
  105.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/govvie/README.md">Govvie Curve Builder</a></li>
  106.  *  </ul>
  107.  * <br><br>
  108.  *
  109.  * @author Lakshmi Krishnamurthy
  110.  */

  111. public class NonlinearGovvieCurve {

  112.     /*
  113.      * Sample demonstrating creation of simple fixed coupon treasury bond
  114.      *
  115.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  116.      */

  117.     private static final Bond CreateTSYBond (
  118.         final String strName,
  119.         final double dblCoupon,
  120.         final JulianDate dt,
  121.         int iNumYears)
  122.         throws Exception
  123.     {
  124.         return BondBuilder.CreateSimpleFixed (  // Simple Fixed Rate Bond
  125.             strName,                    // Name
  126.             "USD",                      // Fictitious Treasury Curve Name
  127.             "",                         // Empty Credit Curve
  128.             dblCoupon,                  // Bond Coupon
  129.             2,                          // Frequency
  130.             "Act/Act",                  // Day Count
  131.             dt,                         // Effective
  132.             dt.addYears (iNumYears),    // Maturity
  133.             null,                       // Principal Schedule
  134.             null
  135.         );
  136.     }

  137.     /*
  138.      * Sample demonstrating creation of a set of the on-the-run treasury bonds
  139.      *
  140.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  141.      */

  142.     private static final Bond[] CreateOnTheRunTSYBondSet (
  143.         final JulianDate dt,
  144.         final String[] astrTSYBondName,
  145.         final int[] aiMaturityYear,
  146.         final double[] adblCoupon)
  147.         throws Exception
  148.     {
  149.         Bond aTSYBond[] = new Bond[astrTSYBondName.length];

  150.         for (int i = 0; i < astrTSYBondName.length; ++i)
  151.             aTSYBond[i] = CreateTSYBond (
  152.                 astrTSYBondName[i],
  153.                 adblCoupon[i],
  154.                 dt,
  155.                 aiMaturityYear[i]
  156.             );

  157.         return aTSYBond;
  158.     }

  159.     /*
  160.      * Sample demonstrating building of the treasury discount curve based off the on-the run instruments and their yields
  161.      *
  162.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  163.      */

  164.     private static final MergedDiscountForwardCurve BuildOnTheRunTSYDiscountCurve (
  165.         final JulianDate dt,
  166.         final Bond[] aTSYBond,
  167.         final double[] adblCalibYield)
  168.         throws Exception
  169.     {
  170.         String astrCalibMeasure[] = new String[aTSYBond.length];

  171.         for (int i = 0; i < aTSYBond.length; ++i)
  172.             astrCalibMeasure[i] = "Yield";

  173.         return ScenarioDiscountCurveBuilder.NonlinearBuild (
  174.             dt,
  175.             "USD",
  176.             aTSYBond,
  177.             adblCalibYield,
  178.             astrCalibMeasure,
  179.             null
  180.         );
  181.     }

  182.     /*
  183.      * Sample demonstrating calculation of the yields of the input on the run treasury instruments
  184.      *
  185.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  186.      */

  187.     private static final double[] GetOnTheRunYield (
  188.         final JulianDate dt,
  189.         final MergedDiscountForwardCurve dcTSY,
  190.         final Bond[] aTSYBond)
  191.         throws Exception
  192.     {
  193.         double adblYield[] = new double[aTSYBond.length];

  194.         for (int i = 0; i < aTSYBond.length; ++i) {
  195.             double dblPrice = aTSYBond[i].priceFromFundingCurve (
  196.                 new ValuationParams (
  197.                     DateUtil.Today(),
  198.                     DateUtil.Today(),
  199.                     "USD"
  200.                 ),
  201.                 MarketParamsBuilder.Discount (dcTSY),
  202.                 aTSYBond[i].maturityDate().julian(),
  203.                 1.,
  204.                 0.
  205.             );

  206.             System.out.println ("\tPrice[" + aTSYBond[i].name() + "]: " +
  207.                 FormatUtil.FormatDouble (dblPrice, 2, 3, 100.));

  208.             double dblYield = aTSYBond[i].yieldFromPrice (
  209.                 new ValuationParams (
  210.                     DateUtil.Today(),
  211.                     DateUtil.Today(),
  212.                     "USD"
  213.                 ),
  214.                 MarketParamsBuilder.Discount (dcTSY),
  215.                 null,
  216.                 dblPrice
  217.             );

  218.             System.out.println ("\tYield[" + aTSYBond[i].name() + "]: " +
  219.                 FormatUtil.FormatDouble (dblYield, 1, 3, 100.));
  220.         }

  221.         return adblYield;
  222.     }

  223.     /*
  224.      * This sample illustrates the construction and validation of the Treasury Curve API. It demonstrates the
  225.      *  following:
  226.      *  - Create the on-the-run treasury bonds.
  227.      *  - Create the on-the-run treasury discount curve from the treasury bonds.
  228.      *  - Compare the implied and the input yields for the on-the-run's.
  229.      *  - Calculate the yield of an off-the-run instrument off of the on-the-run yield discount curve and
  230.      *      cross verify it with the price.
  231.      *
  232.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  233.      */

  234.     private static final void TreasuryCurveSample()
  235.         throws Exception
  236.     {
  237.         /*
  238.          * Initialize the Credit Analytics Library
  239.          */

  240.         String strConfig = "";

  241.         EnvManager.InitEnv (strConfig);

  242.         /*
  243.          * Define name, maturity, coupon, and the market yield of the input on-the-run treasuries  
  244.          */

  245.         final String[] astrTSYName = new String[] {"TSY2YON", "TSY3YON", "TSY5YON", "TSY7YON", "TSY10YON", "TSY30YON"};
  246.         final int[] aiMaturityYear = new int[] {2, 3, 5, 7, 10, 30};
  247.         final double[] adblCoupon = new double[] {0.0200, 0.0250, 0.0300, 0.0325, 0.0375, 0.0400};
  248.         final double[] adblCalibYield = new double[] {0.0200, 0.0250, 0.0300, 0.0325, 0.0375, 0.0400};

  249.         /*
  250.          * Create the on-the-run treasury bonds
  251.          */

  252.         long lTime = System.nanoTime();

  253.         Bond[] aTSYBond = CreateOnTheRunTSYBondSet (
  254.             DateUtil.Today(),
  255.             astrTSYName,
  256.             aiMaturityYear,
  257.             adblCoupon
  258.         );

  259.         /*
  260.          * Create the on-the-run treasury discount curve
  261.          */

  262.         MergedDiscountForwardCurve dcTSY = BuildOnTheRunTSYDiscountCurve (
  263.             DateUtil.Today(),
  264.             aTSYBond,
  265.             adblCalibYield
  266.         );

  267.         /*
  268.          * Compare the implied discount rate and input yields - in general they DO NOT match
  269.          */

  270.         for (int i = 0; i < astrTSYName.length; ++i) {
  271.             String strTenor = aiMaturityYear[i] + "Y";

  272.             System.out.println ("Zero[" + strTenor + "]: " + dcTSY.zero (strTenor) +
  273.                 "; Yield[" + strTenor + "]: " + adblCalibYield[i]);
  274.         }

  275.         System.out.println ("\n----\n");

  276.         double[] adblYield = GetOnTheRunYield (
  277.             DateUtil.Today(),
  278.             dcTSY,
  279.             aTSYBond
  280.         );

  281.         /*
  282.          * Compare the implied and the input yields for the on-the-run's - they DO match
  283.          */

  284.         for (int i = 0; i < astrTSYName.length; ++i) {
  285.             String strTenor = aiMaturityYear[i] + "Y";

  286.             System.out.println ("CalcYield[" + strTenor + "]: " + adblYield[i] + "; Input[" + strTenor + "]: " + adblCalibYield[i]);
  287.         }

  288.         /*
  289.          * Finally calculate the yield of an off-the-run instrument off of the on-the-run yield discount curve
  290.          */

  291.         /*
  292.          * Construct off-the-run
  293.          */

  294.         int iOffTheRunMaturityYears = 10;

  295.         Bond bondOffTheRun = BondBuilder.CreateSimpleFixed (    // Simple Fixed Rate Bond
  296.             "USD" + iOffTheRunMaturityYears + "YOFF",
  297.             "USD",
  298.             "",
  299.             0.0375,
  300.             2,
  301.             "Act/Act",
  302.             DateUtil.Today(),
  303.             DateUtil.Today().addYears (iOffTheRunMaturityYears),    // off-the-run
  304.             null,
  305.             null
  306.         );

  307.         /*
  308.          * Calculate price for off-the-run
  309.          */

  310.         double dblPrice = bondOffTheRun.priceFromFundingCurve (
  311.             new ValuationParams (
  312.                 DateUtil.Today(),
  313.                 DateUtil.Today(),
  314.                 "USD"
  315.             ),
  316.             MarketParamsBuilder.Discount (dcTSY),
  317.             bondOffTheRun.maturityDate().julian(),
  318.             1.,
  319.             0.
  320.         );

  321.         System.out.println ("\nOff-The-Run Price[" + iOffTheRunMaturityYears + "Y]: " + dblPrice);

  322.         /*
  323.          * Calculate yield for off-the-run
  324.          */

  325.         double dblYieldOffTheRun = bondOffTheRun.yieldFromPrice (
  326.             new ValuationParams (
  327.                 DateUtil.Today(),
  328.                 DateUtil.Today(),
  329.                 "USD"
  330.             ),
  331.             MarketParamsBuilder.Discount (dcTSY),
  332.             null,
  333.             dblPrice
  334.         );

  335.         System.out.println ("\nOff-The-Run Yield[" + iOffTheRunMaturityYears + "Y]: " + dblYieldOffTheRun);

  336.         System.out.println ("\tTime => " + (System.nanoTime() - lTime) * 1.e-06 + " ms");
  337.     }

  338.     public static final void main (
  339.         final String[] astrArgs)
  340.         throws Exception
  341.     {
  342.         TreasuryCurveSample();

  343.         EnvManager.TerminateEnv();
  344.     }
  345. }