AndersenPykhtinSokolEnsemble.java

  1. package org.drip.exposure.regressiontrade;

  2. /*
  3.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  4.  */

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

  75. /**
  76.  * <i>AndersenPykhtinSokolEnsemble</i> adjusts the Variation Margin, computes Path-wise Local Volatility, and
  77.  * eventually estimates the Path-wise Unadjusted Variation Margin across the Suite of Simulated Paths. The
  78.  * References are:
  79.  *  
  80.  * <br><br>
  81.  *      <ul>
  82.  *          <li>
  83.  *              Andersen, L. B. G., M. Pykhtin, and A. Sokol (2017): Re-thinking Margin Period of Risk
  84.  *                  https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2902737 <b>eSSRN</b>
  85.  *          </li>
  86.  *          <li>
  87.  *              Andersen, L. B. G., M. Pykhtin, and A. Sokol (2017): Credit Exposure in the Presence of
  88.  *                  Initial Margin https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2806156 <b>eSSRN</b>
  89.  *          </li>
  90.  *          <li>
  91.  *              Albanese, C., and L. Andersen (2014): Accounting for OTC Derivatives: Funding Adjustments and
  92.  *                  the Re-Hypothecation Option https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2482955
  93.  *                  <b>eSSRN</b>
  94.  *          </li>
  95.  *          <li>
  96.  *              Burgard, C., and M. Kjaer (2017): Derivatives Funding, Netting, and Accounting
  97.  *                  https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2534011 <b>eSSRN</b>
  98.  *          </li>
  99.  *          <li>
  100.  *              Pykhtin, M. (2009): Modeling Counter-party Credit Exposure in the Presence of Margin
  101.  *                  Agreements http://www.risk-europe.com/protected/michael-pykhtin.pdf
  102.  *          </li>
  103.  *      </ul>
  104.  *
  105.  *  <br><br>
  106.  *  <ul>
  107.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/PortfolioCore.md">Portfolio Core Module</a></li>
  108.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ExposureAnalyticsLibrary.md">Exposure Analytics</a></li>
  109.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/exposure/README.md">Exposure Group Level Collateralized/Uncollateralized Exposure</a></li>
  110.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/exposure/regressiontrade/README.md">Exposure Regression under Margin and Trade Payments</a></li>
  111.  *  </ul>
  112.  *
  113.  * @author Lakshmi Krishnamurthy
  114.  */

  115. public class AndersenPykhtinSokolEnsemble
  116. {
  117.     private int[] _sparseExposureDateArray = null;
  118.     private org.drip.exposure.universe.MarketPath[] _marketPathArray = null;
  119.     private org.drip.exposure.mpor.VariationMarginTradePaymentVertex _marginTradePaymentGenerator = null;

  120.     /**
  121.      * AndersenPykhtinSokolEnsemble Constructor
  122.      *
  123.      * @param marginTradePaymentGenerator The Variation Margin Estimate and the Trade Payment Generator
  124.      * @param marketPathArray Array of Market Paths
  125.      * @param sparseExposureDateArray Array of Sparse Exposure Dates
  126.      *
  127.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  128.      */

  129.     public AndersenPykhtinSokolEnsemble (
  130.         final org.drip.exposure.mpor.VariationMarginTradePaymentVertex marginTradePaymentGenerator,
  131.         final org.drip.exposure.universe.MarketPath[] marketPathArray,
  132.         final int[] sparseExposureDateArray)
  133.         throws java.lang.Exception
  134.     {
  135.         if (null == (_marginTradePaymentGenerator = marginTradePaymentGenerator) ||
  136.             null == (_marketPathArray = marketPathArray) ||
  137.             null == (_sparseExposureDateArray = sparseExposureDateArray))
  138.         {
  139.             throw new java.lang.Exception ("AndersenPykhtinSokolEnsemble => Invalid Inputs");
  140.         }

  141.         int pathCount = _marketPathArray.length;
  142.         int sparseExposureDateCount = _sparseExposureDateArray.length;

  143.         if (0 == pathCount || 0 == sparseExposureDateCount)
  144.         {
  145.             throw new java.lang.Exception ("AndersenPykhtinSokolEnsemble => Invalid Inputs");
  146.         }

  147.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  148.         {
  149.             if (null == _marketPathArray[pathIndex])
  150.             {
  151.                 throw new java.lang.Exception ("AndersenPykhtinSokolEnsemble => Invalid Inputs");
  152.             }
  153.         }
  154.     }

  155.     /**
  156.      * Retrieve the Path-wise Variation Margin/Trade Payment Generator
  157.      *
  158.      * @return The Path-wise Variation Margin/Trade Payment Generator
  159.      */

  160.     public org.drip.exposure.mpor.VariationMarginTradePaymentVertex marginTradePaymentGenerator()
  161.     {
  162.         return _marginTradePaymentGenerator;
  163.     }

  164.     /**
  165.      * Retrieve the Array of Market Paths
  166.      *
  167.      * @return The Array of Market Paths
  168.      */

  169.     public org.drip.exposure.universe.MarketPath[] marketPathArray()
  170.     {
  171.         return _marketPathArray;
  172.     }

  173.     /**
  174.      * Retrieve the Array of Sparse Exposure Dates
  175.      *
  176.      * @return The Array of Sparse Exposure Dates
  177.      */

  178.     public int[] sparseExposureDateArray()
  179.     {
  180.         return _sparseExposureDateArray;
  181.     }

  182.     /**
  183.      * Retrieve the Number of Simulation Paths
  184.      *
  185.      * @return The Number of Simulation Paths
  186.      */

  187.     public int pathCount()
  188.     {
  189.         return _marketPathArray.length;
  190.     }

  191.     /**
  192.      * Retrieve the Number of Sparse Exposure Dates
  193.      *
  194.      * @return The Number of Sparse Exposure Dates
  195.      */

  196.     public int sparseExposureDateCount()
  197.     {
  198.         return _sparseExposureDateArray.length;
  199.     }

  200.     /**
  201.      * Generate the Path-wise Adjusted Variation Margin Estimator
  202.      *
  203.      * @return The Path-wise Adjusted Variation Margin Estimator
  204.      */

  205.     public org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimator[]
  206.         pathAdjustedVariationMarginEstimator()
  207.     {
  208.         int pathCount = _marketPathArray.length;
  209.         org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimator[]
  210.             adjustedVariationMarginEstimatorArray = new
  211.                 org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimator[pathCount];

  212.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  213.         {
  214.             try
  215.             {
  216.                 adjustedVariationMarginEstimatorArray[pathIndex] = new
  217.                     org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimator (
  218.                         _marginTradePaymentGenerator,
  219.                         _marketPathArray[pathIndex]
  220.                     );
  221.             }
  222.             catch (java.lang.Exception e)
  223.             {
  224.                 e.printStackTrace();

  225.                 return null;
  226.             }
  227.         }

  228.         return adjustedVariationMarginEstimatorArray;
  229.     }

  230.     /**
  231.      * Generate the Path-wise Adjusted Variation Margin Estimate
  232.      *
  233.      * @return The Path-wise Adjusted Variation Margin Estimate
  234.      */

  235.     public org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimate[]
  236.         pathAdjustedVariationMarginEstimate()
  237.     {
  238.         int pathCount = _marketPathArray.length;
  239.         org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimate[]
  240.             adjustedVariationMarginEstimateArray = new
  241.                 org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimate[pathCount];

  242.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  243.         {
  244.             try
  245.             {
  246.                 adjustedVariationMarginEstimateArray[pathIndex] = new
  247.                     org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimator (
  248.                         _marginTradePaymentGenerator,
  249.                         _marketPathArray[pathIndex]
  250.                     ).adjustedVariationMarginEstimate (_sparseExposureDateArray);
  251.             }
  252.             catch (java.lang.Exception e)
  253.             {
  254.                 e.printStackTrace();

  255.                 return null;
  256.             }
  257.         }

  258.         return adjustedVariationMarginEstimateArray;
  259.     }

  260.     /**
  261.      * Generate the Ensemble Adjusted Variation Margin Dynamics
  262.      *
  263.      * @return The Ensemble Adjusted Variation Margin Dynamics
  264.      */

  265.     public org.drip.exposure.regressiontrade.AdjustedVariationMarginDynamics
  266.         ensembleAdjustedVariationMarginDynamics()
  267.     {
  268.         int pathCount = _marketPathArray.length;
  269.         org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimate[]
  270.             adjustedVariationMarginEstimateArray = new
  271.                 org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimate[pathCount];

  272.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  273.         {
  274.             try
  275.             {
  276.                 adjustedVariationMarginEstimateArray[pathIndex] = new
  277.                     org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimator (
  278.                         _marginTradePaymentGenerator,
  279.                         _marketPathArray[pathIndex]
  280.                     ).adjustedVariationMarginEstimate (_sparseExposureDateArray);
  281.             }
  282.             catch (java.lang.Exception e)
  283.             {
  284.                 e.printStackTrace();

  285.                 return null;
  286.             }
  287.         }

  288.         try
  289.         {
  290.             return new org.drip.exposure.regressiontrade.AdjustedVariationMarginDynamics
  291.                 (adjustedVariationMarginEstimateArray);
  292.         }
  293.         catch (java.lang.Exception e)
  294.         {
  295.             e.printStackTrace();
  296.         }

  297.         return null;
  298.     }

  299.     /**
  300.      * Generate the Ensemble Pillar Dynamics Array
  301.      *
  302.      * @return The Ensemble Pillar Dynamics Array
  303.      */

  304.     public org.drip.exposure.regression.PykhtinPillarDynamics[] ensemblePillarDynamics()
  305.     {
  306.         org.drip.exposure.regressiontrade.AdjustedVariationMarginDynamics adjustedVariationMarginDynamics =
  307.             ensembleAdjustedVariationMarginDynamics();

  308.         return null == adjustedVariationMarginDynamics ? null :
  309.             adjustedVariationMarginDynamics.pillarDynamics();
  310.     }

  311.     /**
  312.      * Generate the Path-wise Dense Variation Margin Array
  313.      *
  314.      * @param localVolatilityGenerationControl Local Volatility Generation Control
  315.      * @param wanderEnsemble The Wander Ensemble
  316.      *
  317.      * @return The Path-wise Dense Variation Margin Array
  318.      */

  319.     public double[][] denseVariationMargin (
  320.         final org.drip.exposure.regression.LocalVolatilityGenerationControl localVolatilityGenerationControl,
  321.         final double[][] wanderEnsemble)
  322.     {
  323.         if (null == wanderEnsemble)
  324.         {
  325.             return null;
  326.         }

  327.         int pathCount = _marketPathArray.length;
  328.         double[][] denseVariationMargin = new double[pathCount][];
  329.         int sparseExposureDateCount = _sparseExposureDateArray.length;
  330.         org.drip.function.definition.R1ToR1[] sparseLocalVolatilityArray = new
  331.             org.drip.function.definition.R1ToR1[sparseExposureDateCount];

  332.         if (pathCount != wanderEnsemble.length)
  333.         {
  334.             return null;
  335.         }

  336.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  337.         {
  338.             if (null == wanderEnsemble[pathIndex] || 0 == wanderEnsemble[pathIndex].length ||
  339.                 !org.drip.numerical.common.NumberUtil.IsValid (wanderEnsemble[pathIndex]))
  340.             {
  341.                 return null;
  342.             }
  343.         }

  344.         org.drip.exposure.regressiontrade.AdjustedVariationMarginDynamics adjustedVariationMarginDynamics =
  345.             ensembleAdjustedVariationMarginDynamics();

  346.         org.drip.exposure.regression.PykhtinPillarDynamics[] pillarDynamicsArray =
  347.             adjustedVariationMarginDynamics.pillarDynamics();

  348.         for (int sparseExposureDateIndex = 0;
  349.             sparseExposureDateIndex < sparseExposureDateCount;
  350.             ++sparseExposureDateIndex)
  351.         {
  352.             sparseLocalVolatilityArray[sparseExposureDateIndex] =
  353.                 pillarDynamicsArray[sparseExposureDateIndex].localVolatilityR1ToR1
  354.                     (localVolatilityGenerationControl);
  355.         }

  356.         org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimate[]
  357.             pathAdjustedVariationMarginEstimateArray =
  358.                 adjustedVariationMarginDynamics.adjustedVariationMarginEstimateArray();

  359.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  360.         {
  361.             try
  362.             {
  363.                 denseVariationMargin[pathIndex] = new
  364.                     org.drip.exposure.regression.AndersenPykhtinSokolStretch (
  365.                         _sparseExposureDateArray,
  366.                         pathAdjustedVariationMarginEstimateArray[pathIndex].adjustedVariationMarginEstimateArray(),
  367.                         sparseLocalVolatilityArray,
  368.                         pathAdjustedVariationMarginEstimateArray[pathIndex].denseTradePaymentArray()
  369.                     ).denseExposure (wanderEnsemble[pathIndex]);
  370.             }
  371.             catch (java.lang.Exception e)
  372.             {
  373.                 e.printStackTrace();
  374.             }
  375.         }

  376.         return denseVariationMargin;
  377.     }

  378.     /**
  379.      * Generate the Dense Variation Margin Trajectory
  380.      *
  381.      * @param localVolatilityGenerationControl Local Volatility Generation Control
  382.      * @param wanderEnsemble The Wander Ensemble
  383.      *
  384.      * @return The Dense Variation Margin Trajectory
  385.      */

  386.     public org.drip.exposure.regressiontrade.AndersenPykhtinSokolTrajectory[] denseTrajectory (
  387.         final org.drip.exposure.regression.LocalVolatilityGenerationControl localVolatilityGenerationControl,
  388.         final double[][] wanderEnsemble)
  389.     {
  390.         if (null == wanderEnsemble)
  391.         {
  392.             return null;
  393.         }

  394.         int pathCount = _marketPathArray.length;
  395.         int denseExposureStartDate = _sparseExposureDateArray[0];
  396.         int sparseExposureDateCount = _sparseExposureDateArray.length;
  397.         int denseExposureEndDate = _sparseExposureDateArray[sparseExposureDateCount - 1];
  398.         org.drip.function.definition.R1ToR1[] sparseLocalVolatilityArray = new
  399.             org.drip.function.definition.R1ToR1[sparseExposureDateCount];
  400.         org.drip.exposure.regressiontrade.AndersenPykhtinSokolTrajectory[]
  401.             andersenPykhtinSokolTrajectoryArray = new
  402.                 org.drip.exposure.regressiontrade.AndersenPykhtinSokolTrajectory[pathCount];

  403.         if (pathCount != wanderEnsemble.length)
  404.         {
  405.             return null;
  406.         }

  407.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  408.         {
  409.             if (null == wanderEnsemble[pathIndex] || 0 == wanderEnsemble[pathIndex].length ||
  410.                 !org.drip.numerical.common.NumberUtil.IsValid (wanderEnsemble[pathIndex]))
  411.             {
  412.                 return null;
  413.             }
  414.         }

  415.         org.drip.exposure.regressiontrade.AdjustedVariationMarginDynamics adjustedVariationMarginDynamics =
  416.             ensembleAdjustedVariationMarginDynamics();

  417.         org.drip.exposure.regression.PykhtinPillarDynamics[] pillarDynamicsArray =
  418.             adjustedVariationMarginDynamics.pillarDynamics();

  419.         for (int sparseExposureDateIndex = 0;
  420.             sparseExposureDateIndex < sparseExposureDateCount;
  421.             ++sparseExposureDateIndex)
  422.         {
  423.             sparseLocalVolatilityArray[sparseExposureDateIndex] =
  424.                 pillarDynamicsArray[sparseExposureDateIndex].localVolatilityR1ToR1
  425.                     (localVolatilityGenerationControl);
  426.         }

  427.         org.drip.exposure.regressiontrade.AdjustedVariationMarginEstimate[]
  428.             pathAdjustedVariationMarginEstimateArray =
  429.                 adjustedVariationMarginDynamics.adjustedVariationMarginEstimateArray();

  430.         for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex)
  431.         {
  432.             java.util.Map<java.lang.Integer, java.lang.Double> variationMarginEstimateTrajectory = new
  433.                 java.util.HashMap<java.lang.Integer, java.lang.Double>();

  434.             try
  435.             {
  436.                 org.drip.exposure.mpor.TradePayment[] tradePaymentTrajectory =
  437.                     pathAdjustedVariationMarginEstimateArray[pathIndex].denseTradePaymentArray();

  438.                 double[] denseExposureArray = new org.drip.exposure.regression.AndersenPykhtinSokolStretch (
  439.                     _sparseExposureDateArray,
  440.                     pathAdjustedVariationMarginEstimateArray[pathIndex].adjustedVariationMarginEstimateArray(),
  441.                     sparseLocalVolatilityArray,
  442.                     tradePaymentTrajectory
  443.                 ).denseExposure (wanderEnsemble[pathIndex]);

  444.                 for (int denseExposureDate = denseExposureStartDate;
  445.                     denseExposureDate <= denseExposureEndDate;
  446.                     ++denseExposureDate)
  447.                 {
  448.                     variationMarginEstimateTrajectory.put (
  449.                         denseExposureDate,
  450.                         denseExposureArray[denseExposureDate - denseExposureStartDate]
  451.                     );
  452.                 }

  453.                 andersenPykhtinSokolTrajectoryArray[pathIndex] = new
  454.                     org.drip.exposure.regressiontrade.AndersenPykhtinSokolTrajectory (
  455.                     variationMarginEstimateTrajectory,
  456.                     tradePaymentTrajectory
  457.                 );
  458.             }
  459.             catch (java.lang.Exception e)
  460.             {
  461.                 e.printStackTrace();
  462.             }
  463.         }

  464.         return andersenPykhtinSokolTrajectoryArray;
  465.     }
  466. }