NonlinearCurveMeasures.java

  1. package org.drip.sample.funding;

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

  5. import org.drip.analytics.date.JulianDate;
  6. import org.drip.analytics.support.*;
  7. import org.drip.market.otc.*;
  8. import org.drip.numerical.common.FormatUtil;
  9. import org.drip.numerical.differentiation.WengertJacobian;
  10. import org.drip.param.period.*;
  11. import org.drip.param.valuation.*;
  12. import org.drip.product.creator.*;
  13. import org.drip.product.definition.*;
  14. import org.drip.product.rates.*;
  15. import org.drip.param.creator.*;
  16. import org.drip.service.env.EnvManager;
  17. import org.drip.state.creator.ScenarioDiscountCurveBuilder;
  18. import org.drip.state.discount.MergedDiscountForwardCurve;
  19. import org.drip.state.identifier.ForwardLabel;

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

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

  88. /**
  89.  * <i>NonlinearCurveMeasures</i> contains a demo of the Non-linear Rates Analytics API Usage. It shows the
  90.  * following:
  91.  *  
  92.  * <br><br>
  93.  *  <ul>
  94.  *      <li>
  95.  *          Build a discount curve using: cash instruments only, EDF instruments only, IRS instruments only,
  96.  *              or all of them strung together.
  97.  *      </li>
  98.  *      <li>
  99.  *          Re-calculate the component input measure quotes from the calibrated discount curve object.
  100.  *      </li>
  101.  *      <li>
  102.  *          Compute the PVDF Wengert Jacobian across all the instruments used in the curve construction.
  103.  *      </li>
  104.  *  </ul>
  105.  *  
  106.  * <br><br>
  107.  *  <ul>
  108.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/AnalyticsCore.md">Analytics Core Module</a></li>
  109.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics Library</a></li>
  110.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">Sample</a></li>
  111.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/funding/README.md">Funding Curve Builder</a></li>
  112.  *  </ul>
  113.  * <br><br>
  114.  *
  115.  * @author Lakshmi Krishnamurthy
  116.  */

  117. public class NonlinearCurveMeasures {

  118.     private static final FixFloatComponent OTCIRS (
  119.         final JulianDate dtSpot,
  120.         final String strCurrency,
  121.         final String strMaturityTenor,
  122.         final double dblCoupon)
  123.     {
  124.         FixedFloatSwapConvention ffConv = IBORFixedFloatContainer.ConventionFromJurisdiction (
  125.             strCurrency,
  126.             "ALL",
  127.             strMaturityTenor,
  128.             "MAIN"
  129.         );

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

  138.     /*
  139.      * Sample API demonstrating the creation of the discount curve from the rates input instruments
  140.      *
  141.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  142.      */

  143.     public static void DiscountCurveFromRatesInstruments()
  144.         throws Exception
  145.     {
  146.         int NUM_DC_INSTR = 30;
  147.         double adblRate[] = new double[NUM_DC_INSTR];
  148.         int aiMaturityDate[] = new int[NUM_DC_INSTR];
  149.         String astrCalibMeasure[] = new String[NUM_DC_INSTR];
  150.         double adblCompCalibValue[] = new double[NUM_DC_INSTR];
  151.         CalibratableComponent aCompCalib[] = new CalibratableComponent[NUM_DC_INSTR];

  152.         JulianDate dtStart = org.drip.analytics.date.DateUtil.CreateFromYMD (
  153.             2011,
  154.             4,
  155.             6
  156.         );

  157.         // First 7 instruments - cash calibration

  158.         JulianDate dtCashEffective = dtStart.addBusDays (1, "USD");

  159.         aiMaturityDate[0] = dtCashEffective.addBusDays (1, "USD").julian(); // ON

  160.         aiMaturityDate[1] = dtCashEffective.addBusDays (2, "USD").julian(); // 1D (TN)

  161.         aiMaturityDate[2] = dtCashEffective.addBusDays (7, "USD").julian(); // 1W

  162.         aiMaturityDate[3] = dtCashEffective.addBusDays (14, "USD").julian(); // 2W

  163.         aiMaturityDate[4] = dtCashEffective.addBusDays (30, "USD").julian(); // 1M

  164.         aiMaturityDate[5] = dtCashEffective.addBusDays (60, "USD").julian(); // 2M

  165.         aiMaturityDate[6] = dtCashEffective.addBusDays (90, "USD").julian(); // 3M

  166.         /*
  167.          * Cash Rate Quotes
  168.          */

  169.         adblCompCalibValue[0] = .0013;
  170.         adblCompCalibValue[1] = .0017;
  171.         adblCompCalibValue[2] = .0017;
  172.         adblCompCalibValue[3] = .0018;
  173.         adblCompCalibValue[4] = .0020;
  174.         adblCompCalibValue[5] = .0023;
  175.         adblCompCalibValue[6] = .0026;

  176.         ComposableFloatingUnitSetting cfus = new ComposableFloatingUnitSetting (
  177.             "3M",
  178.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_SINGLE,
  179.             null,
  180.             ForwardLabel.Create (
  181.                 "USD",
  182.                 "3M"
  183.             ),
  184.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  185.             0.
  186.         );

  187.         CompositePeriodSetting cps = new CompositePeriodSetting (
  188.             4,
  189.             "3M",
  190.             "USD",
  191.             null,
  192.             1.,
  193.             null,
  194.             null,
  195.             null,
  196.             null
  197.         );

  198.         CashSettleParams csp = new CashSettleParams (
  199.             0,
  200.             "USD",
  201.             0
  202.         );

  203.         for (int i = 0; i < 7; ++i) {
  204.             adblRate[i] = 0.01;
  205.             astrCalibMeasure[i] = "Rate";

  206.             aCompCalib[i] = SingleStreamComponentBuilder.Deposit (
  207.                 dtCashEffective, // Effective
  208.                 new JulianDate (aiMaturityDate[i]).addBusDays (
  209.                     2,
  210.                     "USD"
  211.                 ), // Maturity
  212.                 ForwardLabel.Create (
  213.                     "USD",
  214.                     "3M"
  215.                 )
  216.             );

  217.             aCompCalib[i] = new SingleStreamComponent (
  218.                 "DEPOSIT_" + aiMaturityDate[i],
  219.                 new Stream (
  220.                     CompositePeriodBuilder.FloatingCompositeUnit (
  221.                         CompositePeriodBuilder.EdgePair (
  222.                             dtStart,
  223.                             new JulianDate (aiMaturityDate[i]).addBusDays (
  224.                                 2,
  225.                                 "USD"
  226.                             )
  227.                         ),
  228.                         cps,
  229.                         cfus
  230.                     )
  231.                 ),
  232.                 csp
  233.             );

  234.             aCompCalib[i].setPrimaryCode (aCompCalib[i].name());
  235.         }

  236.         // Next 8 instruments - EDF calibration

  237.         adblCompCalibValue[7] = .0027;
  238.         adblCompCalibValue[8] = .0032;
  239.         adblCompCalibValue[9] = .0041;
  240.         adblCompCalibValue[10] = .0054;
  241.         adblCompCalibValue[11] = .0077;
  242.         adblCompCalibValue[12] = .0104;
  243.         adblCompCalibValue[13] = .0134;
  244.         adblCompCalibValue[14] = .0160;

  245.         CalibratableComponent[] aEDF = SingleStreamComponentBuilder.ForwardRateFuturesPack (
  246.             dtStart,
  247.             8,
  248.             "USD"
  249.         );

  250.         for (int i = 0; i < 8; ++i) {
  251.             adblRate[i + 7] = 0.01;
  252.             aCompCalib[i + 7] = aEDF[i];
  253.             astrCalibMeasure[i + 7] = "Rate";

  254.             aiMaturityDate[i + 7] = aEDF[i].maturityDate().julian();
  255.         }

  256.         // Final 15 instruments - IRS calibration

  257.         JulianDate dtIRSEffective = dtStart.addBusDays (
  258.             2,
  259.             "USD"
  260.         );

  261.         String[] astrIRSTenor = new String[] {
  262.             "4Y",
  263.             "5Y",
  264.             "6Y",
  265.             "7Y",
  266.             "8Y",
  267.             "9Y",
  268.             "10Y",
  269.             "11Y",
  270.             "12Y",
  271.             "15Y",
  272.             "20Y",
  273.             "25Y",
  274.             "30Y",
  275.             "40Y",
  276.             "50Y",
  277.         };

  278.         aiMaturityDate[15] = dtIRSEffective.addTenor (astrIRSTenor[0]).julian();

  279.         aiMaturityDate[16] = dtIRSEffective.addTenor (astrIRSTenor[1]).julian();

  280.         aiMaturityDate[17] = dtIRSEffective.addTenor (astrIRSTenor[2]).julian();

  281.         aiMaturityDate[18] = dtIRSEffective.addTenor (astrIRSTenor[3]).julian();

  282.         aiMaturityDate[19] = dtIRSEffective.addTenor (astrIRSTenor[4]).julian();

  283.         aiMaturityDate[20] = dtIRSEffective.addTenor (astrIRSTenor[5]).julian();

  284.         aiMaturityDate[21] = dtIRSEffective.addTenor (astrIRSTenor[6]).julian();

  285.         aiMaturityDate[22] = dtIRSEffective.addTenor (astrIRSTenor[7]).julian();

  286.         aiMaturityDate[23] = dtIRSEffective.addTenor (astrIRSTenor[8]).julian();

  287.         aiMaturityDate[24] = dtIRSEffective.addTenor (astrIRSTenor[9]).julian();

  288.         aiMaturityDate[25] = dtIRSEffective.addTenor (astrIRSTenor[10]).julian();

  289.         aiMaturityDate[26] = dtIRSEffective.addTenor (astrIRSTenor[11]).julian();

  290.         aiMaturityDate[27] = dtIRSEffective.addTenor (astrIRSTenor[12]).julian();

  291.         aiMaturityDate[28] = dtIRSEffective.addTenor (astrIRSTenor[13]).julian();

  292.         aiMaturityDate[29] = dtIRSEffective.addTenor (astrIRSTenor[14]).julian();

  293.         adblCompCalibValue[15] = .0166;
  294.         adblCompCalibValue[16] = .0206;
  295.         adblCompCalibValue[17] = .0241;
  296.         adblCompCalibValue[18] = .0269;
  297.         adblCompCalibValue[19] = .0292;
  298.         adblCompCalibValue[20] = .0311;
  299.         adblCompCalibValue[21] = .0326;
  300.         adblCompCalibValue[22] = .0340;
  301.         adblCompCalibValue[23] = .0351;
  302.         adblCompCalibValue[24] = .0375;
  303.         adblCompCalibValue[25] = .0393;
  304.         adblCompCalibValue[26] = .0402;
  305.         adblCompCalibValue[27] = .0407;
  306.         adblCompCalibValue[28] = .0409;
  307.         adblCompCalibValue[29] = .0409;

  308.         for (int i = 0; i < 15; ++i) {
  309.             astrCalibMeasure[i + 15] = "Rate";
  310.             adblRate[i + 15] = 0.01;

  311.             aCompCalib[i + 15] = OTCIRS (
  312.                 dtIRSEffective,
  313.                 "USD",
  314.                 astrIRSTenor[i],
  315.                 0.
  316.             );
  317.         }

  318.         /*
  319.          * Build the IR curve from the components, their calibration measures, and their calibration quotes.
  320.          */

  321.         MergedDiscountForwardCurve dc = ScenarioDiscountCurveBuilder.NonlinearBuild (
  322.             dtStart,
  323.             "USD",
  324.             aCompCalib,
  325.             adblCompCalibValue,
  326.             astrCalibMeasure,
  327.             null
  328.         );

  329.         /*
  330.          * Re-calculate the component input measure quotes from the calibrated discount curve object
  331.          */

  332.         for (int i = 0; i < aCompCalib.length; ++i)
  333.             System.out.println (astrCalibMeasure[i] + "[" + i + "] = " +
  334.                 FormatUtil.FormatDouble (aCompCalib[i].measureValue (new ValuationParams (dtStart, dtStart, "USD"), null,
  335.                     MarketParamsBuilder.Create (dc, null, null, null, null, null, null),
  336.                         null, astrCalibMeasure[i]), 1, 5, 1.) + " | " + FormatUtil.FormatDouble (adblCompCalibValue[i], 1, 5, 1.));

  337.         for (int i = 0; i < aCompCalib.length; ++i) {
  338.             WengertJacobian wjComp = aCompCalib[i].jackDDirtyPVDManifestMeasure (
  339.                 new ValuationParams (
  340.                     dtStart,
  341.                     dtStart,
  342.                     "USD"
  343.                 ),
  344.                 null,
  345.                 MarketParamsBuilder.Create (
  346.                     dc,
  347.                     null,
  348.                     null,
  349.                     null,
  350.                     null,
  351.                     null,
  352.                     null
  353.                 ),
  354.                 null
  355.             );

  356.             System.out.println ("PV/DF Micro Jack[" + aCompCalib[i].name() + "]=" +
  357.                 (null == wjComp ? null : wjComp.displayString()));
  358.         }
  359.     }

  360.     public static final void main (
  361.         final String astrArgs[])
  362.         throws Exception
  363.     {
  364.         String strConfig = "";

  365.         EnvManager.InitEnv (strConfig);

  366.         long lStart = System.nanoTime();

  367.         DiscountCurveFromRatesInstruments();

  368.         System.out.println ("Time Taken: " + ((int)(1.e-09 * (System.nanoTime() - lStart))) + " sec");

  369.         EnvManager.TerminateEnv();
  370.     }
  371. }