ZeroThresholdNettingReceivableStochastic.java

  1. package org.drip.sample.xvabasel;

  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.crng.RandomNumberGenerator;
  8. import org.drip.measure.discrete.CorrelatedPathVertexDimension;
  9. import org.drip.measure.dynamics.*;
  10. import org.drip.measure.process.DiffusionEvolver;
  11. import org.drip.measure.realization.*;
  12. import org.drip.measure.statistics.UnivariateDiscreteThin;
  13. import org.drip.numerical.common.FormatUtil;
  14. import org.drip.numerical.linearalgebra.Matrix;
  15. import org.drip.service.env.EnvManager;
  16. import org.drip.state.identifier.OTCFixFloatLabel;
  17. import org.drip.xva.basel.*;
  18. import org.drip.xva.gross.*;
  19. import org.drip.xva.netting.CollateralGroupPath;
  20. import org.drip.xva.proto.*;
  21. import org.drip.xva.settings.*;
  22. import org.drip.xva.strategy.*;
  23. import org.drip.xva.vertex.AlbaneseAndersen;

  24. /*
  25.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  26.  */

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

  68. /**
  69.  * ZeroThresholdNettingReceivableStochastic examines the Basel BCBS 2012 OTC Accounting Impact to a
  70.  *  Portfolio of 10 Swaps resulting from the Addition of a New Swap - Comparison via both FVA/FDA and FCA/FBA
  71.  *  Schemes. Simulation is carried out under the following Criteria:
  72.  *  
  73.  *    - Collateralization Status - Fully Collateralized (Zero Threshold)
  74.  *    - Aggregation Unit         - Netting Group
  75.  *    - Added Swap Type          - Negative Upfront Swap (Receivable)
  76.  *    - Market Dynamics          - Fully Stochastic (Correlated Market Evolution)
  77.  *  
  78.  *  
  79.  *  The References are:
  80.  *  
  81.  *  - Burgard, C., and M. Kjaer (2014): PDE Representations of Derivatives with Bilateral Counter-party Risk
  82.  *      and Funding Costs, Journal of Credit Risk, 7 (3) 1-19.
  83.  *  
  84.  *  - Burgard, C., and M. Kjaer (2014): In the Balance, Risk, 24 (11) 72-75.
  85.  *  
  86.  *  - Gregory, J. (2009): Being Two-faced over Counter-party Credit Risk, Risk 20 (2) 86-90.
  87.  *  
  88.  *  - Li, B., and Y. Tang (2007): Quantitative Analysis, Derivatives Modeling, and Trading Strategies in the
  89.  *      Presence of Counter-party Credit Risk for the Fixed Income Market, World Scientific Publishing,
  90.  *      Singapore.
  91.  *
  92.  *  - Piterbarg, V. (2010): Funding Beyond Discounting: Collateral Agreements and Derivatives Pricing, Risk
  93.  *      21 (2) 97-102.
  94.  *
  95.  * @author Lakshmi Krishnamurthy
  96.  */

  97. public class ZeroThresholdNettingReceivableStochastic {

  98.     private static final double[] NumeraireValueRealization (
  99.         final DiffusionEvolver deNumeraireValue,
  100.         final double dblNumeraireValueInitial,
  101.         final double dblTime,
  102.         final double dblTimeWidth,
  103.         final double[] adblRandom,
  104.         final int iNumStep)
  105.         throws Exception
  106.     {
  107.         double[] adblNumeraireValue = new double[iNumStep + 1];
  108.         double[] adblTimeWidth = new double[iNumStep];

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

  111.         JumpDiffusionEdge[] aJDE = deNumeraireValue.incrementSequence (
  112.             new JumpDiffusionVertex (
  113.                 dblTime,
  114.                 dblNumeraireValueInitial,
  115.                 0.,
  116.                 false
  117.             ),
  118.             JumpDiffusionEdgeUnit.Diffusion (
  119.                 adblTimeWidth,
  120.                 adblRandom
  121.             ),
  122.             dblTimeWidth
  123.         );

  124.         for (int j = 1; j <= iNumStep; ++j)
  125.             adblNumeraireValue[j] = aJDE[j - 1].finish();

  126.         return adblNumeraireValue;
  127.     }

  128.     private static final double[] VertexNumeraireRealization (
  129.         final DiffusionEvolver deNumeraireValue,
  130.         final double dblNumeraireValueInitial,
  131.         final double dblTime,
  132.         final double dblTimeWidth,
  133.         final double[] adblRandom,
  134.         final int iNumStep)
  135.         throws Exception
  136.     {
  137.         double[] adblNumeraireValue = new double[iNumStep + 1];
  138.         double[] adblTimeWidth = new double[iNumStep];

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

  141.         JumpDiffusionVertex[] aJDV = deNumeraireValue.vertexSequenceReverse (
  142.             new JumpDiffusionVertex (
  143.                 dblTime,
  144.                 dblNumeraireValueInitial,
  145.                 0.,
  146.                 false
  147.             ),
  148.             JumpDiffusionEdgeUnit.Diffusion (
  149.                 adblTimeWidth,
  150.                 adblRandom
  151.             ),
  152.             adblTimeWidth
  153.         );

  154.         for (int j = 0; j <= iNumStep; ++j)
  155.             adblNumeraireValue[j] = aJDV[j].value();

  156.         return adblNumeraireValue;
  157.     }

  158.     private static final double[] ATMSwapRateOffsetRealization (
  159.         final DiffusionEvolver deATMSwapRateOffset,
  160.         final double dblATMSwapRateOffsetInitial,
  161.         final double[] adblRandom,
  162.         final double dblTime,
  163.         final double dblTimeWidth,
  164.         final int iNumStep)
  165.         throws Exception
  166.     {
  167.         double[] adblATMSwapRateOffset = new double[iNumStep + 1];
  168.         adblATMSwapRateOffset[0] = dblATMSwapRateOffsetInitial;
  169.         double[] adblTimeWidth = new double[iNumStep];

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

  172.         JumpDiffusionEdge[] aJDE = deATMSwapRateOffset.incrementSequence (
  173.             new JumpDiffusionVertex (
  174.                 dblTime,
  175.                 dblATMSwapRateOffsetInitial,
  176.                 0.,
  177.                 false
  178.             ),
  179.             JumpDiffusionEdgeUnit.Diffusion (
  180.                 adblTimeWidth,
  181.                 adblRandom
  182.             ),
  183.             dblTimeWidth
  184.         );

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

  187.         return adblATMSwapRateOffset;
  188.     }

  189.     private static final double[] SwapPortfolioValueRealization (
  190.         final DiffusionEvolver deATMSwapRate,
  191.         final double dblATMSwapRateStart,
  192.         final double[] adblRandom,
  193.         final int iNumStep,
  194.         final double dblTime,
  195.         final double dblTimeWidth,
  196.         final double dblTimeMaturity,
  197.         final double dblSwapNotional)
  198.         throws Exception
  199.     {
  200.         double[] adblSwapPortfolioValueRealization = new double[iNumStep + 1];
  201.         int iMaturityStep = (int) (dblTimeMaturity / dblTimeWidth);

  202.         for (int i = 0; i < iNumStep; ++i)
  203.             adblSwapPortfolioValueRealization[i] = 0.;

  204.         double[] adblATMSwapRateOffsetRealization = ATMSwapRateOffsetRealization (
  205.             deATMSwapRate,
  206.             dblATMSwapRateStart,
  207.             adblRandom,
  208.             dblTime,
  209.             dblTimeWidth,
  210.             iNumStep
  211.         );

  212.         for (int j = 0; j <= iNumStep; ++j)
  213.             adblSwapPortfolioValueRealization[j] = j > iMaturityStep ? 0. :
  214.                 dblSwapNotional * dblTimeWidth * (iMaturityStep - j) * adblATMSwapRateOffsetRealization[j];

  215.         return adblSwapPortfolioValueRealization;
  216.     }

  217.     private static final double[][] Path (
  218.         final double[][] aadblCorrelation,
  219.         final int iNumVertex)
  220.         throws Exception
  221.     {
  222.         CorrelatedPathVertexDimension cpvd = new CorrelatedPathVertexDimension (
  223.             new RandomNumberGenerator(),
  224.             aadblCorrelation,
  225.             iNumVertex,
  226.             1,
  227.             false,
  228.             null
  229.         );

  230.         return cpvd.multiPathVertexRd()[0].flatform();
  231.     }

  232.     private static final ExposureAdjustmentAggregator[] Mix (
  233.         final double dblTimeMaturity1,
  234.         final double dblATMSwapRateOffsetStart1,
  235.         final double dblSwapNotional1,
  236.         final double dblTimeMaturity2,
  237.         final double dblATMSwapRateOffsetStart2,
  238.         final double dblSwapNotional2)
  239.         throws Exception
  240.     {
  241.         int iNumStep = 10;
  242.         int iNumPath = 60000;
  243.         int iNumVertex = 10;
  244.         double dblTime = 5.;
  245.         double dblATMSwapRateOffsetDrift = 0.0;
  246.         double dblATMSwapRateOffsetVolatility = 0.25;
  247.         double dblOvernightNumeraireDrift = -0.004;
  248.         double dblOvernightNumeraireVolatility = 0.02;
  249.         double dblOvernightNumeraireInitial = 1.;
  250.         double dblCSADrift = -0.01;
  251.         double dblCSAVolatility = 0.05;
  252.         double dblCSAInitial = 1.;
  253.         double dblBankHazardRateDrift = 0.002;
  254.         double dblBankHazardRateVolatility = 0.20;
  255.         double dblBankHazardRateInitial = 0.015;
  256.         double dblBankRecoveryRateDrift = 0.002;
  257.         double dblBankRecoveryRateVolatility = 0.02;
  258.         double dblBankRecoveryRateInitial = 0.40;
  259.         double dblCounterPartyHazardRateDrift = 0.002;
  260.         double dblCounterPartyHazardRateVolatility = 0.30;
  261.         double dblCounterPartyHazardRateInitial = 0.030;
  262.         double dblCounterPartyRecoveryRateDrift = 0.002;
  263.         double dblCounterPartyRecoveryRateVolatility = 0.02;
  264.         double dblCounterPartyRecoveryRateInitial = 0.30;
  265.         double dblBankFundingSpreadDrift = 0.00002;
  266.         double dblBankFundingSpreadVolatility = 0.002;
  267.         double dblCounterPartyFundingSpreadDrift = 0.000022;
  268.         double dblCounterPartyFundingSpreadVolatility = 0.0022;
  269.         double dblBankThreshold = 0.;
  270.         double dblCounterPartyThreshold = 0.;

  271.         double[][] aadblCorrelation = new double[][] {
  272.             {1.00,  0.00,  0.03,  0.07,  0.04,  0.05,  0.08,  0.00,  0.00},  // PORTFOLIO
  273.             {0.00,  1.00,  0.00,  0.00,  0.00,  0.00,  0.00,  0.00,  1.00},  // OVERNIGHT
  274.             {0.03,  0.00,  1.00,  0.26,  0.33,  0.21,  0.35,  0.13,  0.00},  // CSA
  275.             {0.07,  0.00,  0.26,  1.00,  0.45, -0.17,  0.07,  0.77,  0.00},  // BANK HAZARD
  276.             {0.04,  0.00,  0.33,  0.45,  1.00, -0.22, -0.54,  0.58,  0.00},  // COUNTER PARTY HAZARD
  277.             {0.05,  0.00,  0.21, -0.17, -0.22,  1.00,  0.47, -0.23,  0.00},  // BANK RECOVERY
  278.             {0.08,  0.00,  0.35,  0.07, -0.54,  0.47,  1.00,  0.01,  0.00},  // COUNTER PARTY RECOVERY
  279.             {0.00,  0.00,  0.13,  0.77,  0.58, -0.23,  0.01,  1.00,  0.00},  // BANK FUNDING SPREAD
  280.             {0.00,  0.00,  0.00,  0.00,  0.00,  0.00,  0.00,  0.00,  1.00}   // COUNTER PARTY FUNDING SPREAD
  281.         };

  282.         PositionGroupSpecification positionGroupSpecification = PositionGroupSpecification.FixedThreshold (
  283.             "FIXEDTHRESHOLD",
  284.             dblCounterPartyThreshold,
  285.             dblBankThreshold,
  286.             PositionReplicationScheme.ALBANESE_ANDERSEN_VERTEX,
  287.             BrokenDateScheme.LINEAR_TIME,
  288.             0.,
  289.             CloseOutScheme.ISDA_92
  290.         );

  291.         JulianDate dtSpot = DateUtil.Today();

  292.         double dblTimeWidth = dblTime / iNumStep;
  293.         JulianDate[] adtVertex = new JulianDate[iNumStep + 1];
  294.         double[][] aadblPortfolio1Value = new double[iNumPath][iNumStep + 1];
  295.         double[][] aadblPortfolio2Value = new double[iNumPath][iNumStep + 1];
  296.         MonoPathExposureAdjustment[] aCPGPGround = new MonoPathExposureAdjustment[iNumPath];
  297.         MonoPathExposureAdjustment[] aCPGPExtended = new MonoPathExposureAdjustment[iNumPath];
  298.         double dblBankFundingSpreadInitial = dblBankHazardRateInitial / (1. - dblBankRecoveryRateInitial);
  299.         double dblCounterPartyFundingSpreadInitial = dblCounterPartyHazardRateInitial / (1. - dblCounterPartyRecoveryRateInitial);

  300.         DiffusionEvolver deATMSwapRateOffset = new DiffusionEvolver (
  301.             DiffusionEvaluatorLinear.Standard (
  302.                 dblATMSwapRateOffsetDrift,
  303.                 dblATMSwapRateOffsetVolatility
  304.             )
  305.         );

  306.         DiffusionEvolver deOvernightNumeraire = new DiffusionEvolver (
  307.             DiffusionEvaluatorLogarithmic.Standard (
  308.                 dblOvernightNumeraireDrift,
  309.                 dblOvernightNumeraireVolatility
  310.             )
  311.         );

  312.         DiffusionEvolver deCSA = new DiffusionEvolver (
  313.             DiffusionEvaluatorLogarithmic.Standard (
  314.                 dblCSADrift,
  315.                 dblCSAVolatility
  316.             )
  317.         );

  318.         DiffusionEvolver deBankHazardRate = new DiffusionEvolver (
  319.             DiffusionEvaluatorLogarithmic.Standard (
  320.                 dblBankHazardRateDrift,
  321.                 dblBankHazardRateVolatility
  322.             )
  323.         );

  324.         DiffusionEvolver deBankRecoveryRate = new DiffusionEvolver (
  325.             DiffusionEvaluatorLogarithmic.Standard (
  326.                 dblBankRecoveryRateDrift,
  327.                 dblBankRecoveryRateVolatility
  328.             )
  329.         );

  330.         DiffusionEvolver deCounterPartyHazardRate = new DiffusionEvolver (
  331.             DiffusionEvaluatorLogarithmic.Standard (
  332.                 dblCounterPartyHazardRateDrift,
  333.                 dblCounterPartyHazardRateVolatility
  334.             )
  335.         );

  336.         DiffusionEvolver deCounterPartyRecoveryRate = new DiffusionEvolver (
  337.             DiffusionEvaluatorLogarithmic.Standard (
  338.                 dblCounterPartyRecoveryRateDrift,
  339.                 dblCounterPartyRecoveryRateVolatility
  340.             )
  341.         );

  342.         DiffusionEvolver deBankFundingSpread = new DiffusionEvolver (
  343.             DiffusionEvaluatorLinear.Standard (
  344.                 dblBankFundingSpreadDrift,
  345.                 dblBankFundingSpreadVolatility
  346.             )
  347.         );

  348.         DiffusionEvolver deCounterPartyFundingSpread = new DiffusionEvolver (
  349.             DiffusionEvaluatorLinear.Standard (
  350.                 dblCounterPartyFundingSpreadDrift,
  351.                 dblCounterPartyFundingSpreadVolatility
  352.             )
  353.         );

  354.         for (int i = 0; i < iNumPath; ++i) {
  355.             double[][] aadblNumeraire = Matrix.Transpose (
  356.                 Path (
  357.                     aadblCorrelation,
  358.                     iNumVertex
  359.                 )
  360.             );

  361.             aadblPortfolio1Value[i] = SwapPortfolioValueRealization (
  362.                 deATMSwapRateOffset,
  363.                 dblATMSwapRateOffsetStart1,
  364.                 aadblNumeraire[0],
  365.                 iNumVertex,
  366.                 dblTime,
  367.                 dblTimeWidth,
  368.                 dblTimeMaturity1,
  369.                 dblSwapNotional1
  370.             );

  371.             aadblPortfolio2Value[i] = SwapPortfolioValueRealization (
  372.                 deATMSwapRateOffset,
  373.                 dblATMSwapRateOffsetStart2,
  374.                 aadblNumeraire[0],
  375.                 iNumVertex,
  376.                 dblTime,
  377.                 dblTimeWidth,
  378.                 dblTimeMaturity2,
  379.                 dblSwapNotional2
  380.             );

  381.             double[] adblOvernightNumeraire = VertexNumeraireRealization (
  382.                 deOvernightNumeraire,
  383.                 dblOvernightNumeraireInitial,
  384.                 dblTime,
  385.                 dblTimeWidth,
  386.                 aadblNumeraire[1],
  387.                 iNumStep
  388.             );

  389.             double[] adblCSA = VertexNumeraireRealization (
  390.                 deCSA,
  391.                 dblCSAInitial,
  392.                 dblTime,
  393.                 dblTimeWidth,
  394.                 aadblNumeraire[2],
  395.                 iNumStep
  396.             );

  397.             double[] adblBankHazardRate = NumeraireValueRealization (
  398.                 deBankHazardRate,
  399.                 dblBankHazardRateInitial,
  400.                 dblTime,
  401.                 dblTimeWidth,
  402.                 aadblNumeraire[3],
  403.                 iNumStep
  404.             );

  405.             double[] adblCounterPartyHazardRate = NumeraireValueRealization (
  406.                 deCounterPartyHazardRate,
  407.                 dblCounterPartyHazardRateInitial,
  408.                 dblTime,
  409.                 dblTimeWidth,
  410.                 aadblNumeraire[4],
  411.                 iNumStep
  412.             );

  413.             double[] adblBankRecoveryRate = NumeraireValueRealization (
  414.                 deBankRecoveryRate,
  415.                 dblBankRecoveryRateInitial,
  416.                 dblTime,
  417.                 dblTimeWidth,
  418.                 aadblNumeraire[5],
  419.                 iNumStep
  420.             );

  421.             double[] adblCounterPartyRecoveryRate = NumeraireValueRealization (
  422.                 deCounterPartyRecoveryRate,
  423.                 dblCounterPartyRecoveryRateInitial,
  424.                 dblTime,
  425.                 dblTimeWidth,
  426.                 aadblNumeraire[6],
  427.                 iNumStep
  428.             );

  429.             double[] adblBankFundingSpread = NumeraireValueRealization (
  430.                 deBankFundingSpread,
  431.                 dblBankFundingSpreadInitial,
  432.                 dblTime,
  433.                 dblTimeWidth,
  434.                 aadblNumeraire[7],
  435.                 iNumStep
  436.             );

  437.             double[] adblCounterPartyFundingSpread = NumeraireValueRealization (
  438.                 deCounterPartyFundingSpread,
  439.                 dblCounterPartyFundingSpreadInitial,
  440.                 dblTime,
  441.                 dblTimeWidth,
  442.                 aadblNumeraire[8],
  443.                 iNumStep
  444.             );

  445.             JulianDate dtStart = dtSpot;
  446.             MarketVertex[] aNV = new MarketVertex [iNumStep + 1];
  447.             double dblValueStart1 = dblTime * dblATMSwapRateOffsetStart1;
  448.             double dblValueStart2 = dblTime * dblATMSwapRateOffsetStart2;
  449.             AlbaneseAndersen[] aCGV1 = new AlbaneseAndersen[iNumStep + 1];
  450.             AlbaneseAndersen[] aCGV2 = new AlbaneseAndersen[iNumStep + 1];

  451.             for (int j = 0; j <= iNumStep; ++j) {
  452.                 JulianDate dtEnd = (adtVertex[j] = dtSpot.addMonths (6 * j + 6));

  453.                 double dblCollateralBalance1 = 0.;
  454.                 double dblCollateralBalance2 = 0.;
  455.                 double dblValueEnd1 = aadblPortfolio1Value[i][j];
  456.                 double dblValueEnd2 = aadblPortfolio2Value[i][j];

  457.                 if (0 != j) {
  458.                     CollateralAmountEstimator cae1 = new CollateralAmountEstimator (
  459.                         positionGroupSpecification,
  460.                         new BrokenDateInterpolatorLinearT (
  461.                             dtStart.julian(),
  462.                             dtEnd.julian(),
  463.                             dblValueStart1,
  464.                             dblValueEnd1
  465.                         ),
  466.                         Double.NaN
  467.                     );

  468.                     dblCollateralBalance1 = cae1.postingRequirement (dtEnd);

  469.                     CollateralAmountEstimator cae2 = new CollateralAmountEstimator (
  470.                         positionGroupSpecification,
  471.                         new BrokenDateInterpolatorLinearT (
  472.                             dtStart.julian(),
  473.                             dtEnd.julian(),
  474.                             dblValueStart2,
  475.                             dblValueEnd2
  476.                         ),
  477.                         Double.NaN
  478.                     );

  479.                     dblCollateralBalance2 = cae2.postingRequirement (dtEnd);
  480.                 }

  481.                 LatentStateVertexContainer latentStateVertexContainer = new LatentStateVertexContainer();

  482.                 latentStateVertexContainer.add (
  483.                     OTCFixFloatLabel.Standard ("USD-3M-10Y"),
  484.                     Double.NaN
  485.                 );

  486.                 aNV[j] = MarketVertex.Nodal (
  487.                     adtVertex[j] = dtSpot.addMonths (6 * j),
  488.                     dblOvernightNumeraireDrift,
  489.                     adblOvernightNumeraire[j],
  490.                     dblCSADrift,
  491.                     adblCSA[j],
  492.                     new MarketVertexEntity (
  493.                         Math.exp (-0.5 * adblBankHazardRate[j] * j),
  494.                         adblBankHazardRate[j],
  495.                         adblBankRecoveryRate[j],
  496.                         adblBankFundingSpread[j],
  497.                         Math.exp (-0.5 * adblBankHazardRate[j] * (1. - adblBankRecoveryRate[j]) * iNumStep),
  498.                         Double.NaN,
  499.                         Double.NaN,
  500.                         Double.NaN
  501.                     ),
  502.                     new MarketVertexEntity (
  503.                         Math.exp (-0.5 * adblCounterPartyHazardRate[j] * j),
  504.                         adblCounterPartyHazardRate[j],
  505.                         adblCounterPartyRecoveryRate[j],
  506.                         adblCounterPartyFundingSpread[j],
  507.                         Math.exp (-0.5 * adblCounterPartyHazardRate[j] * (1. - adblCounterPartyRecoveryRate[j]) * iNumStep),
  508.                         Double.NaN,
  509.                         Double.NaN,
  510.                         Double.NaN
  511.                     ),
  512.                     latentStateVertexContainer
  513.                 );

  514.                 aCGV1[j] = new AlbaneseAndersen (
  515.                     adtVertex[j],
  516.                     aadblPortfolio1Value[i][j],
  517.                     0.,
  518.                     dblCollateralBalance1
  519.                 );

  520.                 aCGV2[j] = new AlbaneseAndersen (
  521.                     adtVertex[j],
  522.                     aadblPortfolio2Value[i][j],
  523.                     0.,
  524.                     dblCollateralBalance2
  525.                 );
  526.             }

  527.             MarketPath np = MarketPath.FromMarketVertexArray (aNV);

  528.             CollateralGroupPath[] aCGP1 = new CollateralGroupPath[] {
  529.                 new CollateralGroupPath (
  530.                     aCGV1,
  531.                     np
  532.                 )
  533.             };

  534.             CollateralGroupPath[] aCGP2 = new CollateralGroupPath[] {
  535.                 new CollateralGroupPath (
  536.                     aCGV2,
  537.                     np
  538.                 )
  539.             };

  540.             aCPGPGround[i] = new MonoPathExposureAdjustment (
  541.                 new AlbaneseAndersenFundingGroupPath[] {
  542.                     new AlbaneseAndersenFundingGroupPath (
  543.                         new AlbaneseAndersenNettingGroupPath[] {
  544.                             new AlbaneseAndersenNettingGroupPath (
  545.                                 aCGP1,
  546.                                 np
  547.                             )
  548.                         },
  549.                         np
  550.                     )
  551.                 }
  552.             );

  553.             aCPGPExtended[i] = new MonoPathExposureAdjustment (
  554.                 new AlbaneseAndersenFundingGroupPath[] {
  555.                     new AlbaneseAndersenFundingGroupPath (
  556.                         new AlbaneseAndersenNettingGroupPath[] {
  557.                             new AlbaneseAndersenNettingGroupPath (
  558.                                 aCGP1,
  559.                                 np
  560.                             ),
  561.                             new AlbaneseAndersenNettingGroupPath (
  562.                                 aCGP2,
  563.                                 np
  564.                             )
  565.                         },
  566.                         np
  567.                     )
  568.                 }
  569.             );
  570.         }

  571.         return new ExposureAdjustmentAggregator[] {
  572.             new ExposureAdjustmentAggregator (aCPGPGround),
  573.             new ExposureAdjustmentAggregator (aCPGPExtended)
  574.         };
  575.     }

  576.     private static final void CPGDDump (
  577.         final String strHeader,
  578.         final ExposureAdjustmentDigest ead)
  579.         throws Exception
  580.     {
  581.         System.out.println();

  582.         UnivariateDiscreteThin udtUCOLVA = ead.ucolva();

  583.         UnivariateDiscreteThin udtFTDCOLVA = ead.ftdcolva();

  584.         UnivariateDiscreteThin udtUCVA = ead.ucva();

  585.         UnivariateDiscreteThin udtFTDCVA = ead.ftdcva();

  586.         UnivariateDiscreteThin udtCVACL = ead.cvacl();

  587.         UnivariateDiscreteThin udtCVA = ead.cva();

  588.         UnivariateDiscreteThin udtDVA = ead.dva();

  589.         UnivariateDiscreteThin udtFVA = ead.fva();

  590.         UnivariateDiscreteThin udtFDA = ead.fda();

  591.         UnivariateDiscreteThin udtFCA = ead.fca();

  592.         UnivariateDiscreteThin udtFBA = ead.fba();

  593.         UnivariateDiscreteThin udtSFVA = ead.sfva();

  594.         System.out.println (
  595.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  596.         );

  597.         System.out.println (strHeader);

  598.         System.out.println (
  599.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  600.         );

  601.         System.out.println (
  602.             "\t||  OODLE  => UCOLVA  | FTDCOLVA |  UCVA   | FTDCVA  |  CVACL  |   CVA   |   DVA   |   FVA   |   FDA   |   FCA   |   FBA   |   SFVA  ||"
  603.         );

  604.         System.out.println (
  605.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  606.         );

  607.         System.out.println (
  608.             "\t|| Average => " +
  609.             FormatUtil.FormatDouble (udtUCOLVA.average(), 2, 2, 1.) + "  |  " +
  610.             FormatUtil.FormatDouble (udtFTDCOLVA.average(), 2, 2, 1.) + "  | " +
  611.             FormatUtil.FormatDouble (udtUCVA.average(), 2, 2, 1.) + "  | " +
  612.             FormatUtil.FormatDouble (udtFTDCVA.average(), 2, 2, 1.) + "  | " +
  613.             FormatUtil.FormatDouble (udtCVACL.average(), 2, 2, 1.) + "  | " +
  614.             FormatUtil.FormatDouble (udtCVA.average(), 2, 2, 1.) + "  | " +
  615.             FormatUtil.FormatDouble (udtDVA.average(), 2, 2, 1.) + "  | " +
  616.             FormatUtil.FormatDouble (udtFVA.average(), 2, 2, 1.) + "  | " +
  617.             FormatUtil.FormatDouble (udtFDA.average(), 2, 2, 1.) + "  | " +
  618.             FormatUtil.FormatDouble (udtFCA.average(), 2, 2, 1.) + "  | " +
  619.             FormatUtil.FormatDouble (udtFBA.average(), 2, 2, 1.) + "  | " +
  620.             FormatUtil.FormatDouble (udtSFVA.average(), 2, 2, 1.) + "  ||"
  621.         );

  622.         System.out.println (
  623.             "\t|| Minimum => " +
  624.             FormatUtil.FormatDouble (udtUCOLVA.minimum(), 2, 2, 1.) + "  |  " +
  625.             FormatUtil.FormatDouble (udtFTDCOLVA.minimum(), 2, 2, 1.) + "  | " +
  626.             FormatUtil.FormatDouble (udtUCVA.minimum(), 2, 2, 1.) + "  | " +
  627.             FormatUtil.FormatDouble (udtFTDCVA.minimum(), 2, 2, 1.) + "  | " +
  628.             FormatUtil.FormatDouble (udtCVACL.minimum(), 2, 2, 1.) + "  | " +
  629.             FormatUtil.FormatDouble (udtCVA.minimum(), 2, 2, 1.) + "  | " +
  630.             FormatUtil.FormatDouble (udtDVA.minimum(), 2, 2, 1.) + "  | " +
  631.             FormatUtil.FormatDouble (udtFVA.minimum(), 2, 2, 1.) + "  | " +
  632.             FormatUtil.FormatDouble (udtFDA.minimum(), 2, 2, 1.) + "  | " +
  633.             FormatUtil.FormatDouble (udtFCA.minimum(), 2, 2, 1.) + "  | " +
  634.             FormatUtil.FormatDouble (udtFBA.minimum(), 2, 2, 1.) + "  | " +
  635.             FormatUtil.FormatDouble (udtSFVA.minimum(), 2, 2, 1.) + "  ||"
  636.         );

  637.         System.out.println (
  638.             "\t|| Maximum => " +
  639.             FormatUtil.FormatDouble (udtUCOLVA.maximum(), 2, 2, 1.) + "  |  " +
  640.             FormatUtil.FormatDouble (udtFTDCOLVA.maximum(), 2, 2, 1.) + "  | " +
  641.             FormatUtil.FormatDouble (udtUCVA.maximum(), 2, 2, 1.) + "  | " +
  642.             FormatUtil.FormatDouble (udtFTDCVA.maximum(), 2, 2, 1.) + "  | " +
  643.             FormatUtil.FormatDouble (udtCVACL.maximum(), 2, 2, 1.) + "  | " +
  644.             FormatUtil.FormatDouble (udtCVA.maximum(), 2, 2, 1.) + "  | " +
  645.             FormatUtil.FormatDouble (udtDVA.maximum(), 2, 2, 1.) + "  | " +
  646.             FormatUtil.FormatDouble (udtFVA.maximum(), 2, 2, 1.) + "  | " +
  647.             FormatUtil.FormatDouble (udtFDA.maximum(), 2, 2, 1.) + "  | " +
  648.             FormatUtil.FormatDouble (udtFCA.maximum(), 2, 2, 1.) + "  | " +
  649.             FormatUtil.FormatDouble (udtFBA.maximum(), 2, 2, 1.) + "  | " +
  650.             FormatUtil.FormatDouble (udtSFVA.maximum(), 2, 2, 1.) + "  ||"
  651.         );

  652.         System.out.println (
  653.             "\t||  Error  => " +
  654.             FormatUtil.FormatDouble (udtUCOLVA.error(), 2, 2, 1.) + "  |  " +
  655.             FormatUtil.FormatDouble (udtFTDCOLVA.error(), 2, 2, 1.) + "  | " +
  656.             FormatUtil.FormatDouble (udtUCVA.error(), 2, 2, 1.) + "  | " +
  657.             FormatUtil.FormatDouble (udtFTDCVA.error(), 2, 2, 1.) + "  | " +
  658.             FormatUtil.FormatDouble (udtCVACL.error(), 2, 2, 1.) + "  | " +
  659.             FormatUtil.FormatDouble (udtCVA.error(), 2, 2, 1.) + "  | " +
  660.             FormatUtil.FormatDouble (udtDVA.error(), 2, 2, 1.) + "  | " +
  661.             FormatUtil.FormatDouble (udtFVA.error(), 2, 2, 1.) + "  | " +
  662.             FormatUtil.FormatDouble (udtFDA.error(), 2, 2, 1.) + "  | " +
  663.             FormatUtil.FormatDouble (udtFCA.error(), 2, 2, 1.) + "  | " +
  664.             FormatUtil.FormatDouble (udtFBA.error(), 2, 2, 1.) + "  | " +
  665.             FormatUtil.FormatDouble (udtSFVA.error(), 2, 2, 1.) + "  ||"
  666.         );

  667.         System.out.println (
  668.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  669.         );
  670.     }

  671.     private static final void CPGDDiffDump (
  672.         final String strHeader,
  673.         final ExposureAdjustmentDigest eadGround,
  674.         final ExposureAdjustmentDigest eadExpanded)
  675.         throws Exception
  676.     {
  677.         System.out.println();

  678.         System.out.println (
  679.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  680.         );

  681.         System.out.println (strHeader);

  682.         System.out.println (
  683.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  684.         );

  685.         System.out.println (
  686.             "\t||  OODLE  => UCOLVA  | FTDCOLVA |  UCVA   | FTDCVA  |  CVACL  |   CVA   |   DVA   |   FVA   |   FDA   |   FCA   |   FBA   |   SFVA  ||"
  687.         );

  688.         System.out.println (
  689.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  690.         );

  691.         System.out.println (
  692.             "\t|| Average => " +
  693.             FormatUtil.FormatDouble (eadExpanded.ucolva().average() - eadGround.ucolva().average(), 3, 1, 10000.) + "  |  " +
  694.             FormatUtil.FormatDouble (eadExpanded.ftdcolva().average() - eadGround.ftdcolva().average(), 3, 1, 10000.) + "  | " +
  695.             FormatUtil.FormatDouble (eadExpanded.ucva().average() - eadGround.ucva().average(), 3, 1, 10000.) + "  | " +
  696.             FormatUtil.FormatDouble (eadExpanded.ftdcva().average() - eadGround.ftdcva().average(), 3, 1, 10000.) + "  | " +
  697.             FormatUtil.FormatDouble (eadExpanded.cvacl().average() - eadGround.cvacl().average(), 3, 1, 10000.) + "  | " +
  698.             FormatUtil.FormatDouble (eadExpanded.cva().average() - eadGround.cva().average(), 3, 1, 10000.) + "  | " +
  699.             FormatUtil.FormatDouble (eadExpanded.dva().average() - eadGround.dva().average(), 3, 1, 10000.) + "  | " +
  700.             FormatUtil.FormatDouble (eadExpanded.fva().average() - eadGround.fva().average(), 3, 1, 10000.) + "  | " +
  701.             FormatUtil.FormatDouble (eadExpanded.fda().average() - eadGround.fda().average(), 3, 1, 10000.) + "  | " +
  702.             FormatUtil.FormatDouble (eadExpanded.fca().average() - eadGround.fca().average(), 3, 1, 10000.) + "  | " +
  703.             FormatUtil.FormatDouble (eadExpanded.fba().average() - eadGround.fba().average(), 3, 1, 10000.) + "  | " +
  704.             FormatUtil.FormatDouble (eadExpanded.sfva().average() - eadGround.sfva().average(), 3, 1, 10000.) + "  ||"
  705.         );

  706.         System.out.println (
  707.             "\t||-----------------------------------------------------------------------------------------------------------------------------------||"
  708.         );
  709.     }

  710.     private static final void BaselAccountingMetrics (
  711.         final String strHeader,
  712.         final ExposureAdjustmentAggregator cpgaGround,
  713.         final ExposureAdjustmentAggregator cpgaExpanded)
  714.         throws Exception
  715.     {
  716.         OTCAccountingModus oasFCAFBA = new OTCAccountingModusFCAFBA (cpgaGround);

  717.         OTCAccountingModus oasFVAFDA = new OTCAccountingModusFVAFDA (cpgaGround);

  718.         OTCAccountingPolicy oapFCAFBA = oasFCAFBA.feePolicy (cpgaExpanded);

  719.         OTCAccountingPolicy oapFVAFDA = oasFVAFDA.feePolicy (cpgaExpanded);

  720.         System.out.println();

  721.         System.out.println (
  722.             "\t||---------------------------------------------------------------------||"
  723.         );

  724.         System.out.println (strHeader);

  725.         System.out.println (
  726.             "\t||---------------------------------------------------------------------||"
  727.         );

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

  731.         System.out.println (
  732.             "\t||         - Accounting Type (FCA/FBA vs. FVA/FDA)                     ||"
  733.         );

  734.         System.out.println (
  735.             "\t||         - Contra Asset Adjustment                                   ||"
  736.         );

  737.         System.out.println (
  738.             "\t||         - Contra Liability Adjustment                               ||"
  739.         );

  740.         System.out.println (
  741.             "\t||         - FTP (Funding Transfer Pricing) (bp)                       ||"
  742.         );

  743.         System.out.println (
  744.             "\t||         - CET1 (Common Equity Tier I) Change (bp)                   ||"
  745.         );

  746.         System.out.println (
  747.             "\t||         - CL (Contra Liability) Change (bp)                         ||"
  748.         );

  749.         System.out.println (
  750.             "\t||         - PFV (Porfolio Value) Change (Income) (bp)                 ||"
  751.         );

  752.         System.out.println (
  753.             "\t||---------------------------------------------------------------------||"
  754.         );

  755.         System.out.println ("\t|| FCA/FBA Accounting => " +
  756.             FormatUtil.FormatDouble (oasFCAFBA.contraAssetAdjustment(), 1, 4, 1.) + " | " +
  757.             FormatUtil.FormatDouble (oasFCAFBA.contraLiabilityAdjustment(), 1, 4, 1.) + " | " +
  758.             FormatUtil.FormatDouble (oapFCAFBA.fundingTransferPricing(), 3, 0, 10000.) + " | " +
  759.             FormatUtil.FormatDouble (oapFCAFBA.cet1Change(), 3, 0, 10000.) + " | " +
  760.             FormatUtil.FormatDouble (oapFCAFBA.contraLiabilityChange(), 3, 0, 10000.) + " | " +
  761.             FormatUtil.FormatDouble (oapFCAFBA.portfolioValueChange(), 3, 0, 10000.) + " || "
  762.         );

  763.         System.out.println ("\t|| FVA/FDA Accounting => " +
  764.             FormatUtil.FormatDouble (oasFVAFDA.contraAssetAdjustment(), 1, 4, 1.) + " | " +
  765.             FormatUtil.FormatDouble (oasFVAFDA.contraLiabilityAdjustment(), 1, 4, 1.) + " | " +
  766.             FormatUtil.FormatDouble (oapFVAFDA.fundingTransferPricing(), 3, 0, 10000.) + " | " +
  767.             FormatUtil.FormatDouble (oapFVAFDA.cet1Change(), 3, 0, 10000.) + " | " +
  768.             FormatUtil.FormatDouble (oapFVAFDA.contraLiabilityChange(), 3, 0, 10000.) + " | " +
  769.             FormatUtil.FormatDouble (oapFVAFDA.portfolioValueChange(), 3, 0, 10000.) + " || "
  770.         );

  771.         System.out.println (
  772.             "\t||---------------------------------------------------------------------||"
  773.         );

  774.         System.out.println();
  775.     }

  776.     public static final void main (
  777.         final String[] astrArgs)
  778.         throws Exception
  779.     {
  780.         EnvManager.InitEnv ("");

  781.         ExposureAdjustmentAggregator[] aCPGA = Mix (
  782.             5.,
  783.             0.,
  784.             100.,
  785.             5.,
  786.             -0.05,
  787.             1.
  788.         );

  789.         ExposureAdjustmentAggregator cpgaGround = aCPGA[0];
  790.         ExposureAdjustmentAggregator cpgaExtended = aCPGA[1];

  791.         ExposureAdjustmentDigest cpgdGround = cpgaGround.digest();

  792.         ExposureAdjustmentDigest cpgdExtended = cpgaExtended.digest();

  793.         CPGDDump (
  794.             "\t||                                                  GROUND BOOK ADJUSTMENT METRICS                                                   ||",
  795.             cpgdGround
  796.         );

  797.         CPGDDump (
  798.             "\t||                                                 EXTENDED BOOK ADJUSTMENT METRICS                                                  ||",
  799.             cpgdExtended
  800.         );

  801.         CPGDDiffDump (
  802.             "\t||                                             TRADE INCREMENT ADJUSTMENT METRICS (bp)                                               ||",
  803.             cpgdGround,
  804.             cpgdExtended
  805.         );

  806.         BaselAccountingMetrics (
  807.             "\t||           ALBANESE & ANDERSEN (2015) BCBS OTC ACCOUNTING            ||",
  808.             cpgaGround,
  809.             cpgaExtended
  810.         );

  811.         EnvManager.TerminateEnv();
  812.     }
  813. }