PrincipalComponentDynamics.java

  1. package org.drip.sample.hjm;

  2. import org.drip.analytics.date.*;
  3. import org.drip.analytics.definition.MarketSurface;
  4. import org.drip.dynamics.hjm.*;
  5. import org.drip.function.definition.R1ToR1;
  6. import org.drip.function.r1tor1.FlatUnivariate;
  7. import org.drip.numerical.common.FormatUtil;
  8. import org.drip.sequence.random.*;
  9. import org.drip.service.env.EnvManager;
  10. import org.drip.spline.basis.PolynomialFunctionSetParams;
  11. import org.drip.spline.params.*;
  12. import org.drip.spline.stretch.MultiSegmentSequenceBuilder;
  13. import org.drip.state.creator.ScenarioMarketSurfaceBuilder;
  14. import org.drip.state.identifier.*;

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

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

  80. /**
  81.  * <i>PrincipalComponentDynamics</i> demonstrates the Construction and Usage of the PCA-Based Multi-Factor
  82.  * Gaussian Model Dynamics for the Evolution of the Instantaneous Forward Rate, the Price, and the Short
  83.  * Rate.
  84.  *  
  85.  * <br><br>
  86.  *  <ul>
  87.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/AnalyticsCore.md">Analytics Core Module</a></li>
  88.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics Library</a></li>
  89.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">Sample</a></li>
  90.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/hjm/README.md">Generic HJM Evolution</a></li>
  91.  *  </ul>
  92.  * <br><br>
  93.  *
  94.  * @author Lakshmi Krishnamurthy
  95.  */

  96. public class PrincipalComponentDynamics {

  97.     private static final MarketSurface FlatVolatilitySurface (
  98.         final JulianDate dtStart,
  99.         final String strCurrency,
  100.         final double dblFlatVol)
  101.         throws Exception
  102.     {
  103.         return ScenarioMarketSurfaceBuilder.CustomSplineWireSurface (
  104.             "VIEW_TARGET_VOLATILITY_SURFACE",
  105.             dtStart,
  106.             strCurrency,
  107.             new double[] {
  108.                 dtStart.julian(),
  109.                 dtStart.addYears (2).julian(),
  110.                 dtStart.addYears (4).julian(),
  111.                 dtStart.addYears (6).julian(),
  112.                 dtStart.addYears (8).julian(),
  113.                 dtStart.addYears (10).julian()
  114.             },
  115.             new double[] {
  116.                 dtStart.julian(),
  117.                 dtStart.addYears (2).julian(),
  118.                 dtStart.addYears (4).julian(),
  119.                 dtStart.addYears (6).julian(),
  120.                 dtStart.addYears (8).julian(),
  121.                 dtStart.addYears (10).julian()
  122.             },
  123.             new double[][] {
  124.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  125.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  126.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  127.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  128.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  129.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  130.             },
  131.             new SegmentCustomBuilderControl (
  132.                 MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  133.                 new PolynomialFunctionSetParams (4),
  134.                 SegmentInelasticDesignControl.Create (
  135.                     2,
  136.                     2
  137.                 ),
  138.                 null,
  139.                 null
  140.             ),
  141.             new SegmentCustomBuilderControl (
  142.                 MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  143.                 new PolynomialFunctionSetParams (4),
  144.                 SegmentInelasticDesignControl.Create (
  145.                     2,
  146.                     2
  147.                 ),
  148.                 null,
  149.                 null
  150.             )
  151.         );
  152.     }

  153.     private static final MultiFactorStateEvolver HJMInstance (
  154.         final JulianDate dtStart,
  155.         final String strCurrency,
  156.         final MarketSurface mktSurfFlatVol1,
  157.         final MarketSurface mktSurfFlatVol2,
  158.         final MarketSurface mktSurfFlatVol3,
  159.         final R1ToR1 auForwardRate,
  160.         final int iNumFactor)
  161.         throws Exception
  162.     {
  163.         MultiFactorVolatility mfv = new MultiFactorVolatility (
  164.             new MarketSurface[] {
  165.                 mktSurfFlatVol1,
  166.                 mktSurfFlatVol2,
  167.                 mktSurfFlatVol3
  168.             },
  169.             new PrincipalFactorSequenceGenerator (
  170.                 new UnivariateSequenceGenerator[] {
  171.                     new BoxMullerGaussian (
  172.                         0.,
  173.                         1.
  174.                     ),
  175.                     new BoxMullerGaussian (
  176.                         0.,
  177.                         1.
  178.                     ),
  179.                     new BoxMullerGaussian (
  180.                         0.,
  181.                         1.
  182.                     )
  183.                 },
  184.                 new double[][] {
  185.                     {1.0, 0.1, 0.2},
  186.                     {0.1, 1.0, 0.2},
  187.                     {0.2, 0.1, 1.0}
  188.                 },
  189.                 iNumFactor
  190.             )
  191.         );

  192.         return new MultiFactorStateEvolver (
  193.             FundingLabel.Standard (strCurrency),
  194.             ForwardLabel.Create (
  195.                 strCurrency,
  196.                 "6M"
  197.             ),
  198.             mfv,
  199.             auForwardRate
  200.         );
  201.     }

  202.     private static final void Evolve (
  203.         final MultiFactorStateEvolver hjm,
  204.         final JulianDate dtStart,
  205.         final String strCurrency,
  206.         final String strViewTenor,
  207.         final String strTargetTenor,
  208.         final double dblStartingForwardRate,
  209.         final double dblStartingPrice)
  210.         throws Exception
  211.     {
  212.         int iViewDate = dtStart.addTenor (strViewTenor).julian();

  213.         int iTargetDate = dtStart.addTenor (strTargetTenor).julian();

  214.         int iDayStep = 2;
  215.         JulianDate dtSpot = dtStart;
  216.         double dblPrice = dblStartingPrice;
  217.         double dblShortRate = dblStartingForwardRate;
  218.         double dblLIBORForwardRate = dblStartingForwardRate;
  219.         double dblInstantaneousForwardRate = dblStartingForwardRate;
  220.         double dblContinuouslyCompoundedShortRate = dblStartingForwardRate;
  221.         double dblShiftedLIBORForwardRate = dblStartingForwardRate + (365.25 / (iTargetDate - iViewDate));

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

  223.         System.out.println ("\t|                                                                                                                               ||");

  224.         System.out.println ("\t|    Multi-Factor PCA-Based Gaussian HJM Run                                                                                    ||");

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

  226.         System.out.println ("\t|                                                                                                                               ||");

  227.         System.out.println ("\t|        Number of Prinicipal Components: " + hjm.mfv().msg().numFactor() + "                                                                                     ||");

  228.         System.out.println ("\t|                                                                                                                               ||");

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

  230.         System.out.println ("\t|            Date                                                                                                               ||");

  231.         System.out.println ("\t|            Instantaneous Forward Rate (%)                                                                                     ||");

  232.         System.out.println ("\t|            Instantaneous Forward Rate - Change (%)                                                                            ||");

  233.         System.out.println ("\t|            LIBOR Forward Rate (%)                                                                                             ||");

  234.         System.out.println ("\t|            LIBOR Forward Rate - Change (%)                                                                                    ||");

  235.         System.out.println ("\t|            Shifted LIBOR Forward Rate (%)                                                                                     ||");

  236.         System.out.println ("\t|            Shifted LIBOR Forward Rate - Change (%)                                                                            ||");

  237.         System.out.println ("\t|            Short Rate (%)                                                                                                     ||");

  238.         System.out.println ("\t|            Short Rate - Change (%)                                                                                            ||");

  239.         System.out.println ("\t|            Continuously Compounded Short Rate (%)                                                                             ||");

  240.         System.out.println ("\t|            Continuously Compounded Short Rate - Change (%)                                                                    ||");

  241.         System.out.println ("\t|            Price                                                                                                              ||");

  242.         System.out.println ("\t|            Price - Change                                                                                                     ||");

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

  244.         while (dtSpot.julian() < iViewDate) {
  245.             int iSpotDate = dtSpot.julian();

  246.             double dblIFRIncrement = hjm.instantaneousForwardRateIncrement (
  247.                 iViewDate,
  248.                 iTargetDate,
  249.                 iDayStep
  250.             );

  251.             dblInstantaneousForwardRate += dblIFRIncrement;

  252.             double dblLIBORForwardRateIncrement = hjm.liborForwardRateIncrement (
  253.                 iSpotDate,
  254.                 iViewDate,
  255.                 iTargetDate,
  256.                 dblLIBORForwardRate,
  257.                 iDayStep
  258.             );

  259.             dblLIBORForwardRate += dblLIBORForwardRateIncrement;

  260.             double dblShiftedLIBORForwardRateIncrement = hjm.shiftedLIBORForwardIncrement (
  261.                 iSpotDate,
  262.                 iViewDate,
  263.                 iTargetDate,
  264.                 dblShiftedLIBORForwardRate,
  265.                 iDayStep
  266.             );

  267.             dblShiftedLIBORForwardRate += dblShiftedLIBORForwardRateIncrement;

  268.             double dblShortRateIncrement = hjm.shortRateIncrement (
  269.                 iSpotDate,
  270.                 iViewDate,
  271.                 iDayStep
  272.             );

  273.             dblShortRate += dblShortRateIncrement;

  274.             double dblProportionalPriceIncrement = hjm.proportionalPriceIncrement (
  275.                 iSpotDate,
  276.                 iViewDate,
  277.                 dblShortRate,
  278.                 iDayStep
  279.             );

  280.             dblPrice *= (1. + dblProportionalPriceIncrement);

  281.             double dblContinuouslyCompoundedShortRateIncrement = hjm.compoundedShortRateIncrement (
  282.                 iSpotDate,
  283.                 iViewDate,
  284.                 iTargetDate,
  285.                 dblContinuouslyCompoundedShortRate,
  286.                 dblShortRate,
  287.                 iDayStep
  288.             );

  289.             dblContinuouslyCompoundedShortRate += dblContinuouslyCompoundedShortRateIncrement;

  290.             System.out.println ("\t| [" + dtSpot + "] = " +
  291.                 FormatUtil.FormatDouble (dblInstantaneousForwardRate, 1, 2, 100.) + "% | " +
  292.                 FormatUtil.FormatDouble (dblIFRIncrement, 1, 2, 100.) + "% || " +
  293.                 FormatUtil.FormatDouble (dblLIBORForwardRate, 1, 2, 100.) + "% | " +
  294.                 FormatUtil.FormatDouble (dblLIBORForwardRateIncrement, 1, 2, 100.) + "% || " +
  295.                 FormatUtil.FormatDouble (dblShiftedLIBORForwardRate, 1, 4, 1.) + " | " +
  296.                 FormatUtil.FormatDouble (dblShiftedLIBORForwardRateIncrement, 1, 2, 100.) + "% || " +
  297.                 FormatUtil.FormatDouble (dblShortRate, 1, 2, 100.) + "% | " +
  298.                 FormatUtil.FormatDouble (dblShortRateIncrement, 1, 2, 100.) + "% || " +
  299.                 FormatUtil.FormatDouble (dblContinuouslyCompoundedShortRate, 1, 2, 100.) + "% | " +
  300.                 FormatUtil.FormatDouble (dblContinuouslyCompoundedShortRateIncrement, 1, 2, 100.) + "% || " +
  301.                 FormatUtil.FormatDouble (dblPrice, 2, 2, 100.) + " | " +
  302.                 FormatUtil.FormatDouble (dblProportionalPriceIncrement, 1, 2, 100.) + " || "
  303.             );

  304.             dtSpot = dtSpot.addBusDays (iDayStep, strCurrency);
  305.         }

  306.         System.out.println ("\t|-------------------------------------------------------------------------------------------------------------------------------||");
  307.     }

  308.     public static final void main (
  309.         final String[] astrArgs)
  310.         throws Exception
  311.     {
  312.         EnvManager.InitEnv ("");

  313.         String strCurrency = "USD";

  314.         JulianDate dtSpot = DateUtil.Today();

  315.         double dblFlatVol1 = 0.01;
  316.         double dblFlatVol2 = 0.02;
  317.         double dblFlatVol3 = 0.03;
  318.         double dblFlatForwardRate = 0.05;
  319.         double dblStartingPrice = 0.9875;

  320.         MarketSurface mktSurfFlatVol1 = FlatVolatilitySurface (
  321.             dtSpot,
  322.             strCurrency,
  323.             dblFlatVol1
  324.         );

  325.         MarketSurface mktSurfFlatVol2 = FlatVolatilitySurface (
  326.             dtSpot,
  327.             strCurrency,
  328.             dblFlatVol2
  329.         );

  330.         MarketSurface mktSurfFlatVol3 = FlatVolatilitySurface (
  331.             dtSpot,
  332.             strCurrency,
  333.             dblFlatVol3
  334.         );

  335.         int[] aiNumFactor = new int[] {
  336.             1, 2, 3
  337.         };

  338.         for (int iNumFactor : aiNumFactor) {
  339.             MultiFactorStateEvolver hjm = HJMInstance (
  340.                 dtSpot,
  341.                 strCurrency,
  342.                 mktSurfFlatVol1,
  343.                 mktSurfFlatVol2,
  344.                 mktSurfFlatVol3,
  345.                 new FlatUnivariate (dblFlatForwardRate),
  346.                 iNumFactor
  347.             );

  348.             Evolve (
  349.                 hjm,
  350.                 dtSpot,
  351.                 strCurrency,
  352.                 "3M",
  353.                 "6M",
  354.                 dblFlatForwardRate,
  355.                 dblStartingPrice
  356.             );
  357.         }

  358.         EnvManager.TerminateEnv();
  359.     }
  360. }