CPGACollateralized.java

  1. package org.drip.sample.xvadigest;

  2. import org.drip.analytics.date.*;
  3. import org.drip.exposure.evolver.LatentStateVertexContainer;
  4. import org.drip.exposure.mpor.CollateralAmountEstimator;
  5. import org.drip.exposure.universe.*;
  6. import org.drip.measure.bridge.BrokenDateInterpolatorLinearT;
  7. import org.drip.measure.discrete.SequenceGenerator;
  8. import org.drip.measure.dynamics.DiffusionEvaluatorLinear;
  9. import org.drip.measure.process.DiffusionEvolver;
  10. import org.drip.measure.realization.*;
  11. import org.drip.measure.statistics.UnivariateDiscreteThin;
  12. import org.drip.numerical.common.FormatUtil;
  13. import org.drip.service.env.EnvManager;
  14. import org.drip.state.identifier.OTCFixFloatLabel;
  15. import org.drip.xva.gross.*;
  16. import org.drip.xva.netting.CollateralGroupPath;
  17. import org.drip.xva.proto.*;
  18. import org.drip.xva.settings.*;
  19. import org.drip.xva.strategy.*;
  20. import org.drip.xva.vertex.AlbaneseAndersen;

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

  24. /*!
  25.  * Copyright (C) 2018 Lakshmi Krishnamurthy
  26.  * Copyright (C) 2017 Lakshmi Krishnamurthy
  27.  *
  28.  *  This file is part of DRIP, a free-software/open-source library for buy/side financial/trading model
  29.  *      libraries targeting analysts and developers
  30.  *      https://lakshmidrip.github.io/DRIP/
  31.  *  
  32.  *  DRIP is composed of four main libraries:
  33.  *  
  34.  *  - DRIP Fixed Income - https://lakshmidrip.github.io/DRIP-Fixed-Income/
  35.  *  - DRIP Asset Allocation - https://lakshmidrip.github.io/DRIP-Asset-Allocation/
  36.  *  - DRIP Numerical Optimizer - https://lakshmidrip.github.io/DRIP-Numerical-Optimizer/
  37.  *  - DRIP Statistical Learning - https://lakshmidrip.github.io/DRIP-Statistical-Learning/
  38.  *
  39.  *  - DRIP Fixed Income: Library for Instrument/Trading Conventions, Treasury Futures/Options,
  40.  *      Funding/Forward/Overnight Curves, Multi-Curve Construction/Valuation, Collateral Valuation and XVA
  41.  *      Metric Generation, Calibration and Hedge Attributions, Statistical Curve Construction, Bond RV
  42.  *      Metrics, Stochastic Evolution and Option Pricing, Interest Rate Dynamics and Option Pricing, LMM
  43.  *      Extensions/Calibrations/Greeks, Algorithmic Differentiation, and Asset Backed Models and Analytics.
  44.  *
  45.  *  - DRIP Asset Allocation: Library for model libraries for MPT framework, Black Litterman Strategy
  46.  *      Incorporator, Holdings Constraint, and Transaction Costs.
  47.  *
  48.  *  - DRIP Numerical Optimizer: Library for Numerical Optimization and Spline Functionality.
  49.  *
  50.  *  - DRIP Statistical Learning: Library for Statistical Evaluation and Machine Learning.
  51.  *
  52.  *  Licensed under the Apache License, Version 2.0 (the "License");
  53.  *      you may not use this file except in compliance with the License.
  54.  *  
  55.  *  You may obtain a copy of the License at
  56.  *      http://www.apache.org/licenses/LICENSE-2.0
  57.  *  
  58.  *  Unless required by applicable law or agreed to in writing, software
  59.  *      distributed under the License is distributed on an "AS IS" BASIS,
  60.  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  61.  *  
  62.  *  See the License for the specific language governing permissions and
  63.  *      limitations under the License.
  64.  */

  65. /**
  66.  * CPGACollateralized illustrates the Counter Party Aggregation over Netting Groups based Collateralized
  67.  *  Collateral Groups with several Fix-Float Swaps. The References are:
  68.  *  
  69.  *  - Burgard, C., and M. Kjaer (2014): PDE Representations of Derivatives with Bilateral Counter-party Risk
  70.  *      and Funding Costs, Journal of Credit Risk, 7 (3) 1-19.
  71.  *  
  72.  *  - Burgard, C., and M. Kjaer (2014): In the Balance, Risk, 24 (11) 72-75.
  73.  *  
  74.  *  - Gregory, J. (2009): Being Two-faced over Counter-party Credit Risk, Risk 20 (2) 86-90.
  75.  *  
  76.  *  - Li, B., and Y. Tang (2007): Quantitative Analysis, Derivatives Modeling, and Trading Strategies in the
  77.  *      Presence of Counter-party Credit Risk for the Fixed Income Market, World Scientific Publishing,
  78.  *      Singapore.
  79.  *
  80.  *  - Piterbarg, V. (2010): Funding Beyond Discounting: Collateral Agreements and Derivatives Pricing, Risk
  81.  *      21 (2) 97-102.
  82.  *
  83.  * @author Lakshmi Krishnamurthy
  84.  */

  85. public class CPGACollateralized {

  86.     private static final double[] ATMSwapRateOffsetRealization (
  87.         final DiffusionEvolver deATMSwapRateOffset,
  88.         final double dblATMSwapRateOffsetInitial,
  89.         final double dblTime,
  90.         final double dblTimeWidth,
  91.         final int iNumStep)
  92.         throws Exception
  93.     {
  94.         double[] adblATMSwapRateOffset = new double[iNumStep + 1];
  95.         adblATMSwapRateOffset[0] = dblATMSwapRateOffsetInitial;
  96.         double[] adblTimeWidth = new double[iNumStep];

  97.         for (int i = 0; i < iNumStep; ++i)
  98.             adblTimeWidth[i] = dblTimeWidth;

  99.         JumpDiffusionEdge[] aJDE = deATMSwapRateOffset.incrementSequence (
  100.             new JumpDiffusionVertex (
  101.                 dblTime,
  102.                 dblATMSwapRateOffsetInitial,
  103.                 0.,
  104.                 false
  105.             ),
  106.             JumpDiffusionEdgeUnit.Diffusion (
  107.                 adblTimeWidth,
  108.                 SequenceGenerator.Gaussian (iNumStep)
  109.             ),
  110.             dblTimeWidth
  111.         );

  112.         for (int j = 1; j <= iNumStep; ++j)
  113.             adblATMSwapRateOffset[j] = aJDE[j - 1].finish();

  114.         return adblATMSwapRateOffset;
  115.     }

  116.     private static final double[] SwapPortfolioValueRealization (
  117.         final DiffusionEvolver deATMSwapRate,
  118.         final double dblATMSwapRateStart,
  119.         final int iNumStep,
  120.         final double dblTime,
  121.         final double dblTimeWidth,
  122.         final int iNumSwap)
  123.         throws Exception
  124.     {
  125.         double[] adblSwapPortfolioValueRealization = new double[iNumStep + 1];

  126.         for (int i = 0; i < iNumStep; ++i)
  127.             adblSwapPortfolioValueRealization[i] = 0.;

  128.         for (int i = 0; i < iNumSwap; ++i) {
  129.             double[] adblATMSwapRateOffsetRealization = ATMSwapRateOffsetRealization (
  130.                 deATMSwapRate,
  131.                 dblATMSwapRateStart,
  132.                 dblTime,
  133.                 dblTimeWidth,
  134.                 iNumStep
  135.             );

  136.             for (int j = 0; j <= iNumStep; ++j)
  137.                 adblSwapPortfolioValueRealization[j] += dblTimeWidth * (iNumStep - j) * adblATMSwapRateOffsetRealization[j];
  138.         }

  139.         return adblSwapPortfolioValueRealization;
  140.     }

  141.     private static final double[][] SwapPortfolioValueRealization (
  142.         final DiffusionEvolver deATMSwapRate,
  143.         final double dblSwapPortfolioValueStart,
  144.         final int iNumStep,
  145.         final double dblTime,
  146.         final double dblTimeWidth,
  147.         final int iNumSwap,
  148.         final int iNumSimulation)
  149.         throws Exception
  150.     {
  151.         double[][] aadblSwapPortfolioValueRealization = new double[iNumSimulation][];

  152.         for (int i = 0; i < iNumSimulation; ++i)
  153.             aadblSwapPortfolioValueRealization[i] = SwapPortfolioValueRealization (
  154.                 deATMSwapRate,
  155.                 dblSwapPortfolioValueStart,
  156.                 iNumStep,
  157.                 dblTime,
  158.                 dblTimeWidth,
  159.                 iNumSwap
  160.             );

  161.         return aadblSwapPortfolioValueRealization;
  162.     }

  163.     private static final void UDTDump (
  164.         final String strHeader,
  165.         final JulianDate[] adtVertexNode,
  166.         final UnivariateDiscreteThin[] aUDT)
  167.         throws Exception
  168.     {
  169.         System.out.println ("\t|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|");

  170.         System.out.println (strHeader);

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

  172.         String strDump = "\t|       DATE      =>" ;

  173.         for (int i = 0; i < adtVertexNode.length; ++i)
  174.             strDump = strDump + " " + adtVertexNode[i] + "  |";

  175.         System.out.println (strDump);

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

  177.          strDump = "\t|     AVERAGE     =>";

  178.         for (int j = 0; j < aUDT.length; ++j)
  179.             strDump = strDump + "   " + FormatUtil.FormatDouble (aUDT[j].average(), 2, 4, 1.) + "   |";

  180.         System.out.println (strDump);

  181.         strDump = "\t|     MAXIMUM     =>";

  182.         for (int j = 0; j < aUDT.length; ++j)
  183.             strDump = strDump + "   " + FormatUtil.FormatDouble (aUDT[j].maximum(), 2, 4, 1.) + "   |";

  184.         System.out.println (strDump);

  185.         strDump = "\t|     MINIMUM     =>";

  186.         for (int j = 0; j < aUDT.length; ++j)
  187.             strDump = strDump + "   " + FormatUtil.FormatDouble (aUDT[j].minimum(), 2, 4, 1.) + "   |";

  188.         System.out.println (strDump);

  189.         strDump = "\t|      ERROR      =>";

  190.         for (int j = 0; j < aUDT.length; ++j)
  191.             strDump = strDump + "   " + FormatUtil.FormatDouble (aUDT[j].error(), 2, 4, 1.) + "   |";

  192.         System.out.println (strDump);

  193.         System.out.println ("\t|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|");
  194.     }

  195.     private static final void UDTDump (
  196.         final String strHeader,
  197.         final UnivariateDiscreteThin udt)
  198.         throws Exception
  199.     {
  200.         System.out.println (
  201.             strHeader +
  202.             FormatUtil.FormatDouble (udt.average(), 3, 2, 100.) + "% | " +
  203.             FormatUtil.FormatDouble (udt.maximum(), 3, 2, 100.) + "% | " +
  204.             FormatUtil.FormatDouble (udt.minimum(), 3, 2, 100.) + "% | " +
  205.             FormatUtil.FormatDouble (udt.error(), 3, 2, 100.) + "% ||"
  206.         );
  207.     }

  208.     public static final void main (
  209.         final String[] astrArgs)
  210.         throws Exception
  211.     {
  212.         EnvManager.InitEnv ("");

  213.         int iNumStep = 10;
  214.         int iNumSwap = 10;
  215.         double dblTime = 5.;
  216.         int iNumPath = 10000;
  217.         double dblATMSwapRateStart = 0.;
  218.         double dblATMSwapRateDrift = 0.0;
  219.         double dblATMSwapRateVolatility = 0.25;
  220.         double dblOvernightNumeraireDrift = 0.004;
  221.         double dblCSADrift = 0.01;
  222.         double dblBankHazardRate = 0.015;
  223.         double dblBankRecoveryRate = 0.40;
  224.         double dblCounterPartyHazardRate = 0.030;
  225.         double dblCounterPartyRecoveryRate = 0.30;
  226.         double dblBankThreshold = -0.1;
  227.         double dblCounterPartyThreshold = 0.1;

  228.         JulianDate dtSpot = DateUtil.Today();

  229.         double dblTimeWidth = dblTime / iNumStep;
  230.         MarketVertex[] aMV = new MarketVertex[iNumStep + 1];
  231.         JulianDate[] adtVertex = new JulianDate[iNumStep + 1];
  232.         double dblBankFundingSpread = dblBankHazardRate / (1. - dblBankRecoveryRate);
  233.         MonoPathExposureAdjustment[] aMPEA = new MonoPathExposureAdjustment[iNumPath];
  234.         double dblCounterPartyFundingSpread = dblCounterPartyHazardRate / (1. - dblCounterPartyRecoveryRate);

  235.         PositionGroupSpecification positionGroupSpecification = PositionGroupSpecification.FixedThreshold (
  236.             "FIXEDTHRESHOLD",
  237.             dblCounterPartyThreshold,
  238.             dblBankThreshold,
  239.             PositionReplicationScheme.ALBANESE_ANDERSEN_VERTEX,
  240.             BrokenDateScheme.LINEAR_TIME,
  241.             0.,
  242.             CloseOutScheme.ISDA_92
  243.         );

  244.         double[][] aadblSwapPortfolioValueRealization = SwapPortfolioValueRealization (
  245.             new DiffusionEvolver (
  246.                 DiffusionEvaluatorLinear.Standard (
  247.                     dblATMSwapRateDrift,
  248.                     dblATMSwapRateVolatility
  249.                 )
  250.             ),
  251.             dblATMSwapRateStart,
  252.             iNumStep,
  253.             dblTime,
  254.             dblTimeWidth,
  255.             iNumSwap,
  256.             iNumPath
  257.         );

  258.         for (int i = 0; i <= iNumStep; ++i)
  259.         {
  260.             LatentStateVertexContainer latentStateVertexContainer = new LatentStateVertexContainer();

  261.             latentStateVertexContainer.add (
  262.                 OTCFixFloatLabel.Standard ("USD-3M-10Y"),
  263.                 Double.NaN
  264.             );

  265.             aMV[i] = MarketVertex.Nodal (
  266.                 adtVertex[i] = dtSpot.addMonths (6 * i),
  267.                 dblOvernightNumeraireDrift,
  268.                 Math.exp (-0.5 * dblOvernightNumeraireDrift * (iNumStep - i)),
  269.                 dblCSADrift,
  270.                 Math.exp (-0.5 * dblCSADrift * (iNumStep - i)),
  271.                 new MarketVertexEntity (
  272.                     Math.exp (-0.5 * dblBankHazardRate * i),
  273.                     dblBankHazardRate,
  274.                     dblBankRecoveryRate,
  275.                     dblBankFundingSpread,
  276.                     Math.exp (-0.5 * dblBankHazardRate * (1. - dblBankRecoveryRate) * (iNumStep - i)),
  277.                     Double.NaN,
  278.                     Double.NaN,
  279.                     Double.NaN
  280.                 ),
  281.                 new MarketVertexEntity (
  282.                     Math.exp (-0.5 * dblCounterPartyHazardRate * i),
  283.                     dblCounterPartyHazardRate,
  284.                     dblCounterPartyRecoveryRate,
  285.                     dblCounterPartyFundingSpread,
  286.                     Math.exp (-0.5 * dblCounterPartyHazardRate * (1. - dblCounterPartyRecoveryRate) * (iNumStep - i)),
  287.                     Double.NaN,
  288.                     Double.NaN,
  289.                     Double.NaN
  290.                 ),
  291.                 latentStateVertexContainer
  292.             );
  293.         }

  294.         MarketPath mp = MarketPath.FromMarketVertexArray (aMV);

  295.         for (int i = 0; i < iNumPath; ++i) {
  296.             JulianDate dtStart = dtSpot;
  297.             double dblValueStart = dblTime * dblATMSwapRateStart;
  298.             AlbaneseAndersen[] aHGVR = new AlbaneseAndersen[iNumStep + 1];

  299.             for (int j = 0; j <= iNumStep; ++j) {
  300.                 JulianDate dtEnd = adtVertex[j];
  301.                 double dblCollateralBalance = 0.;
  302.                 double dblValueEnd = aadblSwapPortfolioValueRealization[i][j];

  303.                 if (0 != j) {
  304.                     CollateralAmountEstimator hae = new CollateralAmountEstimator (
  305.                         positionGroupSpecification,
  306.                         new BrokenDateInterpolatorLinearT (
  307.                             dtStart.julian(),
  308.                             dtEnd.julian(),
  309.                             dblValueStart,
  310.                             dblValueEnd
  311.                         ),
  312.                         Double.NaN
  313.                     );

  314.                     dblCollateralBalance = hae.postingRequirement (dtEnd);
  315.                 }

  316.                 aHGVR[j] = new AlbaneseAndersen (
  317.                     adtVertex[j],
  318.                     aadblSwapPortfolioValueRealization[i][j],
  319.                     0.,
  320.                     dblCollateralBalance
  321.                 );

  322.                 dtStart = dtEnd;
  323.                 dblValueStart = dblValueEnd;
  324.             }

  325.             CollateralGroupPath[] aHGP = new CollateralGroupPath[] {
  326.                 new CollateralGroupPath (
  327.                     aHGVR,
  328.                     mp
  329.                 )
  330.             };

  331.             aMPEA[i] = new MonoPathExposureAdjustment (
  332.                 new AlbaneseAndersenFundingGroupPath[] {
  333.                     new AlbaneseAndersenFundingGroupPath (
  334.                         new AlbaneseAndersenNettingGroupPath[] {
  335.                             new AlbaneseAndersenNettingGroupPath (
  336.                                 aHGP,
  337.                                 mp
  338.                             )
  339.                         },
  340.                         mp
  341.                     )
  342.                 }
  343.             );
  344.         }

  345.         ExposureAdjustmentAggregator eaa = new ExposureAdjustmentAggregator (aMPEA);

  346.         ExposureAdjustmentDigest ead = eaa.digest();

  347.         System.out.println();

  348.         UDTDump (
  349.             "\t|                                                                                COLLATERALIZED EXPOSURE                                                                                |",
  350.             eaa.vertexDates(),
  351.             ead.collateralizedExposure()
  352.         );

  353.         UDTDump (
  354.             "\t|                                                                               UNCOLLATERALIZED EXPOSURE                                                                               |",
  355.             eaa.vertexDates(),
  356.             ead.uncollateralizedExposure()
  357.         );

  358.         UDTDump (
  359.             "\t|                                                                                COLLATERALIZED EXPOSURE PV                                                                             |",
  360.             eaa.vertexDates(),
  361.             ead.collateralizedExposurePV()
  362.         );

  363.         UDTDump (
  364.             "\t|                                                                               UNCOLLATERALIZED EXPOSURE PV                                                                            |",
  365.             eaa.vertexDates(),
  366.             ead.uncollateralizedExposurePV()
  367.         );

  368.         UDTDump (
  369.             "\t|                                                                            COLLATERALIZED POSITIVE EXPOSURE PV                                                                        |",
  370.             eaa.vertexDates(),
  371.             ead.collateralizedPositiveExposure()
  372.         );

  373.         UDTDump (
  374.             "\t|                                                                           UNCOLLATERALIZED POSITIVE EXPOSURE PV                                                                       |",
  375.             eaa.vertexDates(),
  376.             ead.uncollateralizedPositiveExposure()
  377.         );

  378.         UDTDump (
  379.             "\t|                                                                            COLLATERALIZED NEGATIVE EXPOSURE PV                                                                        |",
  380.             eaa.vertexDates(),
  381.             ead.collateralizedNegativeExposure()
  382.         );

  383.         UDTDump (
  384.             "\t|                                                                           UNCOLLATERALIZED NEGATIVE EXPOSURE PV                                                                       |",
  385.             eaa.vertexDates(),
  386.             ead.uncollateralizedNegativeExposure()
  387.         );

  388.         System.out.println();

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

  390.         System.out.println ("\t||  UCVA CVA FTDCVA DVA FCA UNIVARIATE THIN STATISTICS ||");

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

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

  393.         System.out.println ("\t||            - Path Average                           ||");

  394.         System.out.println ("\t||            - Path Maximum                           ||");

  395.         System.out.println ("\t||            - Path Minimum                           ||");

  396.         System.out.println ("\t||            - Monte Carlo Error                      ||");

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

  398.         UDTDump (
  399.             "\t||  UCVA  => ",
  400.             ead.ucva()
  401.         );

  402.         UDTDump (
  403.             "\t|| FTDCVA => ",
  404.             ead.ftdcva()
  405.         );

  406.         UDTDump (
  407.             "\t||   CVA  => ",
  408.             ead.cva()
  409.         );

  410.         UDTDump (
  411.             "\t||  CVACL => ",
  412.             ead.cvacl()
  413.         );

  414.         UDTDump (
  415.             "\t||   DVA  => ",
  416.             ead.dva()
  417.         );

  418.         UDTDump (
  419.             "\t||   FVA  => ",
  420.             ead.fva()
  421.         );

  422.         UDTDump (
  423.             "\t||   FDA  => ",
  424.             ead.fda()
  425.         );

  426.         UDTDump (
  427.             "\t||   FCA  => ",
  428.             ead.fca()
  429.         );

  430.         UDTDump (
  431.             "\t||   FBA  => ",
  432.             ead.fba()
  433.         );

  434.         UDTDump (
  435.             "\t||  SFVA  => ",
  436.             ead.sfva()
  437.         );

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

  439.         UDTDump (
  440.             "\t||  Total => ",
  441.             ead.totalVA()
  442.         );

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

  444.         System.out.println();

  445.         EnvManager.TerminateEnv();
  446.     }
  447. }