ProductMargin21.java

  1. package org.drip.sample.simm;

  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.TreeMap;

  7. import org.drip.analytics.support.CaseInsensitiveHashMap;
  8. import org.drip.numerical.common.FormatUtil;
  9. import org.drip.service.env.EnvManager;
  10. import org.drip.simm.estimator.ProductClassMargin;
  11. import org.drip.simm.estimator.ProductClassSensitivity;
  12. import org.drip.simm.estimator.ProductClassSettings;
  13. import org.drip.simm.foundation.MarginEstimationSettings;
  14. import org.drip.simm.fx.FXRiskThresholdContainer21;
  15. import org.drip.simm.margin.RiskClassAggregate;
  16. import org.drip.simm.margin.RiskClassAggregateCR;
  17. import org.drip.simm.margin.RiskClassAggregateIR;
  18. import org.drip.simm.product.BucketSensitivity;
  19. import org.drip.simm.product.BucketSensitivityCR;
  20. import org.drip.simm.product.BucketSensitivityIR;
  21. import org.drip.simm.product.RiskClassSensitivity;
  22. import org.drip.simm.product.RiskClassSensitivityCR;
  23. import org.drip.simm.product.RiskClassSensitivityIR;
  24. import org.drip.simm.product.RiskFactorTenorSensitivity;
  25. import org.drip.simm.product.RiskMeasureSensitivity;
  26. import org.drip.simm.product.RiskMeasureSensitivityCR;
  27. import org.drip.simm.product.RiskMeasureSensitivityIR;

  28. /*
  29.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  30.  */

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

  71. /**
  72.  * ProductMargin21 illustrates the Computation of the ISDA SIMM 2.1 Product Margin for across a Group of Risk
  73.  *  Factor Exposure Sensitivities. The References are:
  74.  *  
  75.  *  - Andersen, L. B. G., M. Pykhtin, and A. Sokol (2017): Credit Exposure in the Presence of Initial Margin,
  76.  *      https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2806156, eSSRN.
  77.  *  
  78.  *  - Albanese, C., S. Caenazzo, and O. Frankel (2017): Regression Sensitivities for Initial Margin
  79.  *      Calculations, https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2763488, eSSRN.
  80.  *  
  81.  *  - Anfuso, F., D. Aziz, P. Giltinan, and K. Loukopoulus (2017): A Sound Modeling and Back-testing
  82.  *      Framework for Forecasting Initial Margin Requirements,
  83.  *      https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2716279, eSSRN.
  84.  *  
  85.  *  - Caspers, P., P. Giltinan, R. Lichters, and N. Nowaczyk (2017): Forecasting Initial Margin Requirements
  86.  *      - A Model Evaluation https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2911167, eSSRN.
  87.  *  
  88.  *  - International Swaps and Derivatives Association (2017): SIMM v2.0 Methodology,
  89.  *      https://www.isda.org/a/oFiDE/isda-simm-v2.pdf.
  90.  *
  91.  * @author Lakshmi Krishnamurthy
  92.  */

  93. public class ProductMargin21
  94. {

  95.     private static final void AddEquityBucketRiskFactorSensitivity (
  96.         final Map<String, Map<String, Double>> bucketRiskFactorSensitivityMap,
  97.         final int bucketIndex,
  98.         final double notional,
  99.         final String[] equityArray)
  100.     {
  101.         Map<String, Double> riskFactorSensitivityMap = new CaseInsensitiveHashMap<Double>();

  102.         for (String equity : equityArray)
  103.         {
  104.             riskFactorSensitivityMap.put (
  105.                 equity,
  106.                 notional * (Math.random() - 0.5)
  107.             );
  108.         }

  109.         bucketRiskFactorSensitivityMap.put (
  110.             "" + bucketIndex,
  111.             riskFactorSensitivityMap
  112.         );
  113.     }

  114.     private static final void AddCommodityBucketRiskFactorSensitivity (
  115.         final Map<String, Map<String, Double>> bucketRiskFactorSensitivityMap,
  116.         final int bucketIndex,
  117.         final double notional,
  118.         final String commodity)
  119.     {
  120.         Map<String, Double> riskFactorSensitivityMap = new CaseInsensitiveHashMap<Double>();

  121.         riskFactorSensitivityMap.put (
  122.             commodity,
  123.             notional * (Math.random() - 0.5)
  124.         );

  125.         bucketRiskFactorSensitivityMap.put (
  126.             "" + bucketIndex,
  127.             riskFactorSensitivityMap
  128.         );
  129.     }

  130.     private static final Map<String, Map<String, Double>> FXCategorySensitivityMap (
  131.         final String[] currencyArray,
  132.         final double notional)
  133.         throws Exception
  134.     {
  135.         Map<String, Map<String, Double>> currencySentivityMap = new TreeMap<String, Map<String, Double>>();

  136.         for (String currency : currencyArray)
  137.         {
  138.             int categoryIndex = FXRiskThresholdContainer21.CurrencyCategory (currency);

  139.             if (currencySentivityMap.containsKey ("" + categoryIndex))
  140.             {
  141.                 Map<String, Double> riskFactorSensitivityMap = currencySentivityMap.get ("" + categoryIndex);

  142.                 riskFactorSensitivityMap.put (
  143.                     currency,
  144.                     notional * (Math.random() - 0.5)
  145.                 );
  146.             }
  147.             else
  148.             {
  149.                 Map<String, Double> riskFactorSensitivityMap = new CaseInsensitiveHashMap<Double>();

  150.                 riskFactorSensitivityMap.put (
  151.                     currency,
  152.                     notional * (Math.random() - 0.5)
  153.                 );

  154.                 currencySentivityMap.put (
  155.                     "" + categoryIndex,
  156.                     riskFactorSensitivityMap
  157.                 );
  158.             }
  159.         }

  160.         return currencySentivityMap;
  161.     }

  162.     private static final RiskFactorTenorSensitivity IRCurveTenorSensitivityMap (
  163.         final double notional)
  164.         throws Exception
  165.     {
  166.         Map<String, Double> tenorSensitivityMap = new HashMap<String, Double>();

  167.         tenorSensitivityMap.put (
  168.             "2W",
  169.             notional * (Math.random() - 0.5)
  170.         );

  171.         tenorSensitivityMap.put (
  172.             "1M",
  173.             notional * (Math.random() - 0.5)
  174.         );

  175.         tenorSensitivityMap.put (
  176.             "3M",
  177.             notional * (Math.random() - 0.5)
  178.         );

  179.         tenorSensitivityMap.put (
  180.             "6M",
  181.             notional * (Math.random() - 0.5)
  182.         );

  183.         tenorSensitivityMap.put (
  184.             "1Y",
  185.             notional * (Math.random() - 0.5)
  186.         );

  187.         tenorSensitivityMap.put (
  188.             "2Y",
  189.             notional * (Math.random() - 0.5)
  190.         );

  191.         tenorSensitivityMap.put (
  192.             "3Y",
  193.             notional * (Math.random() - 0.5)
  194.         );

  195.         tenorSensitivityMap.put (
  196.             "5Y",
  197.             notional * (Math.random() - 0.5)
  198.         );

  199.         tenorSensitivityMap.put (
  200.             "10Y",
  201.             notional * (Math.random() - 0.5)
  202.         );

  203.         tenorSensitivityMap.put (
  204.             "15Y",
  205.             notional * (Math.random() - 0.5)
  206.         );

  207.         tenorSensitivityMap.put (
  208.             "20Y",
  209.             notional * (Math.random() - 0.5)
  210.         );

  211.         tenorSensitivityMap.put (
  212.             "30Y",
  213.             notional * (Math.random() - 0.5)
  214.         );

  215.         return new RiskFactorTenorSensitivity (tenorSensitivityMap);
  216.     }

  217.     private static final void AddCreditTenorSensitivity (
  218.         final Map<String, Double> tenorSensitivityMap,
  219.         final double notional,
  220.         final String tenor)
  221.         throws Exception
  222.     {
  223.         if (tenorSensitivityMap.containsKey (tenor))
  224.         {
  225.             tenorSensitivityMap.put (
  226.                 tenor,
  227.                 tenorSensitivityMap.get (tenor) + notional * (Math.random() - 0.5)
  228.             );
  229.         }
  230.         else
  231.         {
  232.             tenorSensitivityMap.put (
  233.                 tenor,
  234.                 notional * (Math.random() - 0.5)
  235.             );
  236.         }
  237.     }

  238.     private static final RiskFactorTenorSensitivity CreditCurveTenorSensitivityMap (
  239.         final double notional)
  240.         throws Exception
  241.     {
  242.         Map<String, Double> tenorSensitivityMap = new HashMap<String, Double>();

  243.         AddCreditTenorSensitivity (
  244.             tenorSensitivityMap,
  245.             notional,
  246.             "1Y"
  247.         );

  248.         AddCreditTenorSensitivity (
  249.             tenorSensitivityMap,
  250.             notional,
  251.             "2Y"
  252.         );

  253.         AddCreditTenorSensitivity (
  254.             tenorSensitivityMap,
  255.             notional,
  256.             "3Y"
  257.         );

  258.         AddCreditTenorSensitivity (
  259.             tenorSensitivityMap,
  260.             notional,
  261.             "5Y"
  262.         );

  263.         AddCreditTenorSensitivity (
  264.             tenorSensitivityMap,
  265.             notional,
  266.             "10Y"
  267.         );

  268.         return new RiskFactorTenorSensitivity (tenorSensitivityMap);
  269.     }

  270.     private static final Map<String, Map<String, Double>> EquityRiskFactorSensitivityMap (
  271.         final double notional)
  272.         throws Exception
  273.     {
  274.         Map<String, Map<String, Double>> bucketRiskFactorSensitivityMap =
  275.             new TreeMap<String, Map<String, Double>>();

  276.         AddEquityBucketRiskFactorSensitivity (
  277.             bucketRiskFactorSensitivityMap,
  278.             -1,
  279.             notional,
  280.             new String[]
  281.             {
  282.                 "BOEING  ",
  283.                 "LOCKHEED",
  284.                 "RAND    ",
  285.                 "RAYTHEON",
  286.             }
  287.         );

  288.         AddEquityBucketRiskFactorSensitivity (
  289.             bucketRiskFactorSensitivityMap,
  290.             1,
  291.             notional,
  292.             new String[]
  293.             {
  294.                 "ADP     ",
  295.                 "PSEANDG ",
  296.                 "STAPLES ",
  297.                 "U-HAUL  ",
  298.             }
  299.         );

  300.         AddEquityBucketRiskFactorSensitivity (
  301.             bucketRiskFactorSensitivityMap,
  302.             2,
  303.             notional,
  304.             new String[]
  305.             {
  306.                 "CISCO   ",
  307.                 "DEERE   ",
  308.                 "HALIBTN ",
  309.                 "VERIZON ",
  310.             }
  311.         );

  312.         AddEquityBucketRiskFactorSensitivity (
  313.             bucketRiskFactorSensitivityMap,
  314.             3,
  315.             notional,
  316.             new String[]
  317.             {
  318.                 "DUKE    ",
  319.                 "MONSANTO",
  320.                 "MMM     ",
  321.                 "VEDANTA ",
  322.             }
  323.         );

  324.         AddEquityBucketRiskFactorSensitivity (
  325.             bucketRiskFactorSensitivityMap,
  326.             4,
  327.             notional,
  328.             new String[]
  329.             {
  330.                 "AMAZON  ",
  331.                 "GOLDMAN ",
  332.                 "MORGAN  ",
  333.                 "REMAX   ",
  334.             }
  335.         );

  336.         AddEquityBucketRiskFactorSensitivity (
  337.             bucketRiskFactorSensitivityMap,
  338.             5,
  339.             notional,
  340.             new String[]
  341.             {
  342.                 "ALDI    ",
  343.                 "INFOSYS ",
  344.                 "OLLA    ",
  345.                 "RELIANCE",
  346.             }
  347.         );

  348.         AddEquityBucketRiskFactorSensitivity (
  349.             bucketRiskFactorSensitivityMap,
  350.             6,
  351.             notional,
  352.             new String[]
  353.             {
  354.                 "GCC     ",
  355.                 "NOKIA   ",
  356.                 "SIEMENS ",
  357.                 "VODAFONE",
  358.             }
  359.         );

  360.         AddEquityBucketRiskFactorSensitivity (
  361.             bucketRiskFactorSensitivityMap,
  362.             7,
  363.             notional,
  364.             new String[]
  365.             {
  366.                 "ADIDAS  ",
  367.                 "BAYER   ",
  368.                 "BILLERTN",
  369.                 "DE BEER ",
  370.             }
  371.         );

  372.         AddEquityBucketRiskFactorSensitivity (
  373.             bucketRiskFactorSensitivityMap,
  374.             8,
  375.             notional,
  376.             new String[]
  377.             {
  378.                 "NOKIA   ",
  379.                 "NOMURA  ",
  380.                 "QATARSOV",
  381.                 "SOTHEBY ",
  382.             }
  383.         );

  384.         AddEquityBucketRiskFactorSensitivity (
  385.             bucketRiskFactorSensitivityMap,
  386.             9,
  387.             notional,
  388.             new String[]
  389.             {
  390.                 "AUTODESK",
  391.                 "CALYPSO ",
  392.                 "NUMERIX ",
  393.                 "WEBLOGIC",
  394.             }
  395.         );

  396.         AddEquityBucketRiskFactorSensitivity (
  397.             bucketRiskFactorSensitivityMap,
  398.             10,
  399.             notional,
  400.             new String[]
  401.             {
  402.                 "COGNIZAN",
  403.                 "TATAMOTO",
  404.                 "TOBLERON",
  405.                 "TVS     ",
  406.             }
  407.         );

  408.         AddEquityBucketRiskFactorSensitivity (
  409.             bucketRiskFactorSensitivityMap,
  410.             11,
  411.             notional,
  412.             new String[]
  413.             {
  414.                 "DJIA    ",
  415.                 "LEHMAN  ",
  416.                 "RUSSELL ",
  417.                 "SANDP   ",
  418.             }
  419.         );

  420.         AddEquityBucketRiskFactorSensitivity (
  421.             bucketRiskFactorSensitivityMap,
  422.             12,
  423.             notional,
  424.             new String[]
  425.             {
  426.                 "CBOE    ",
  427.                 "CITI    ",
  428.                 "RUSSELL ",
  429.                 "VIX     ",
  430.             }
  431.         );

  432.         return bucketRiskFactorSensitivityMap;
  433.     }

  434.     private static final Map<String, Map<String, Double>> CommodityRiskFactorSensitivityMap (
  435.         final double notional)
  436.         throws Exception
  437.     {
  438.         Map<String, Map<String, Double>> bucketRiskFactorSensitivityMap =
  439.             new HashMap<String, Map<String, Double>>();

  440.         AddCommodityBucketRiskFactorSensitivity (
  441.             bucketRiskFactorSensitivityMap,
  442.             1,
  443.             notional,
  444.             "COAL                          "
  445.         );

  446.         AddCommodityBucketRiskFactorSensitivity (
  447.             bucketRiskFactorSensitivityMap,
  448.             2,
  449.             notional,
  450.             "CRUDE                         "
  451.         );

  452.         AddCommodityBucketRiskFactorSensitivity (
  453.             bucketRiskFactorSensitivityMap,
  454.             3,
  455.             notional,
  456.             "LIGHT ENDS                    "
  457.         );

  458.         AddCommodityBucketRiskFactorSensitivity (
  459.             bucketRiskFactorSensitivityMap,
  460.             4,
  461.             notional,
  462.             "MIDDLE DISTILLATES            "
  463.         );

  464.         AddCommodityBucketRiskFactorSensitivity (
  465.             bucketRiskFactorSensitivityMap,
  466.             5,
  467.             notional,
  468.             "HEAVY DISTILLATES             "
  469.         );

  470.         AddCommodityBucketRiskFactorSensitivity (
  471.             bucketRiskFactorSensitivityMap,
  472.             6,
  473.             notional,
  474.             "NORTH AMERICAN NATURAL GAS    "
  475.         );

  476.         AddCommodityBucketRiskFactorSensitivity (
  477.             bucketRiskFactorSensitivityMap,
  478.             7,
  479.             notional,
  480.             "EUROPEAN NATURAL GAS          "
  481.         );

  482.         AddCommodityBucketRiskFactorSensitivity (
  483.             bucketRiskFactorSensitivityMap,
  484.             8,
  485.             notional,
  486.             "NORTH AMERICAN POWER          "
  487.         );

  488.         AddCommodityBucketRiskFactorSensitivity (
  489.             bucketRiskFactorSensitivityMap,
  490.             9,
  491.             notional,
  492.             "EUROPEAN POWER                "
  493.         );

  494.         AddCommodityBucketRiskFactorSensitivity (
  495.             bucketRiskFactorSensitivityMap,
  496.             10,
  497.             notional,
  498.             "FREIGHT                       "
  499.         );

  500.         AddCommodityBucketRiskFactorSensitivity (
  501.             bucketRiskFactorSensitivityMap,
  502.             11,
  503.             notional,
  504.             "BASE METALS                   "
  505.         );

  506.         AddCommodityBucketRiskFactorSensitivity (
  507.             bucketRiskFactorSensitivityMap,
  508.             12,
  509.             notional,
  510.             "PRECIOUS METALS               "
  511.         );

  512.         AddCommodityBucketRiskFactorSensitivity (
  513.             bucketRiskFactorSensitivityMap,
  514.             13,
  515.             notional,
  516.             "GRAINS                        "
  517.         );

  518.         AddCommodityBucketRiskFactorSensitivity (
  519.             bucketRiskFactorSensitivityMap,
  520.             14,
  521.             notional,
  522.             "SOFTS                         "
  523.         );

  524.         AddCommodityBucketRiskFactorSensitivity (
  525.             bucketRiskFactorSensitivityMap,
  526.             15,
  527.             notional,
  528.             "LIVESTOCK                     "
  529.         );

  530.         AddCommodityBucketRiskFactorSensitivity (
  531.             bucketRiskFactorSensitivityMap,
  532.             16,
  533.             notional,
  534.             "OTHER                         "
  535.         );

  536.         AddCommodityBucketRiskFactorSensitivity (
  537.             bucketRiskFactorSensitivityMap,
  538.             17,
  539.             notional,
  540.             "INDEXES                       "
  541.         );

  542.         return bucketRiskFactorSensitivityMap;
  543.     }

  544.     private static final void AddFXBucketRiskFactorSensitivity (
  545.         final Map<String, Map<String, Double>> bucketRiskFactorSensitivityMap,
  546.         final String bucketKey,
  547.         final double notional,
  548.         final String[] fxPairArray)
  549.     {
  550.         Map<String, Double> riskFactorSensitivityMap = new CaseInsensitiveHashMap<Double>();

  551.         for (String fxPair : fxPairArray)
  552.         {
  553.             riskFactorSensitivityMap.put (
  554.                 fxPair,
  555.                 notional * (Math.random() - 0.5)
  556.             );
  557.         }

  558.         bucketRiskFactorSensitivityMap.put (
  559.             bucketKey,
  560.             riskFactorSensitivityMap
  561.         );
  562.     }

  563.     private static final Map<String, BucketSensitivity> BucketFXVegaSensitivityMap (
  564.         final double notional)
  565.         throws Exception
  566.     {
  567.         Map<String, Map<String, Double>> bucketVegaMap = new TreeMap<String, Map<String, Double>>();

  568.         AddFXBucketRiskFactorSensitivity (
  569.             bucketVegaMap,
  570.             "1__1",
  571.             notional,
  572.             new String[]
  573.             {
  574.                 "USD_EUR",
  575.                 "USD_JPY",
  576.                 "USD_GBP",
  577.                 "USD_AUD",
  578.             }
  579.         );

  580.         AddFXBucketRiskFactorSensitivity (
  581.             bucketVegaMap,
  582.             "1__2",
  583.             notional,
  584.             new String[]
  585.             {
  586.                 "USD_BRL",
  587.                 "USD_CNY",
  588.                 "USD_HKD",
  589.                 "USD_INR",
  590.             }
  591.         );

  592.         AddFXBucketRiskFactorSensitivity (
  593.             bucketVegaMap,
  594.             "2__1",
  595.             notional,
  596.             new String[]
  597.             {
  598.                 "BRL_USD",
  599.                 "CNY_USD",
  600.                 "HKD_USD",
  601.                 "INR_USD",
  602.             }
  603.         );

  604.         AddFXBucketRiskFactorSensitivity (
  605.             bucketVegaMap,
  606.             "2__2",
  607.             notional,
  608.             new String[]
  609.             {
  610.                 "BRL_CNY",
  611.                 "BRL_KDD",
  612.                 "BRL_INR",
  613.                 "BRL_KRW",
  614.             }
  615.         );

  616.         AddFXBucketRiskFactorSensitivity (
  617.             bucketVegaMap,
  618.             "1__3",
  619.             notional,
  620.             new String[]
  621.             {
  622.                 "USD_IDR",
  623.                 "USD_PKR",
  624.                 "USD_SRL",
  625.                 "USD_BNT",
  626.             }
  627.         );

  628.         AddFXBucketRiskFactorSensitivity (
  629.             bucketVegaMap,
  630.             "2__3",
  631.             notional,
  632.             new String[]
  633.             {
  634.                 "BRL_IDR",
  635.                 "BRL_PKR",
  636.                 "BRL_SRL",
  637.                 "BRL_BNT",
  638.             }
  639.         );

  640.         AddFXBucketRiskFactorSensitivity (
  641.             bucketVegaMap,
  642.             "3__1",
  643.             notional,
  644.             new String[]
  645.             {
  646.                 "IDR_USD",
  647.                 "PKR_USD",
  648.                 "SRL_USD",
  649.                 "BNT_USD",
  650.             }
  651.         );

  652.         AddFXBucketRiskFactorSensitivity (
  653.             bucketVegaMap,
  654.             "3__2",
  655.             notional,
  656.             new String[]
  657.             {
  658.                 "IDR_BRL",
  659.                 "PKR_BRL",
  660.                 "SRL_BRL",
  661.                 "BNT_BRL",
  662.             }
  663.         );

  664.         AddFXBucketRiskFactorSensitivity (
  665.             bucketVegaMap,
  666.             "3__3",
  667.             notional,
  668.             new String[]
  669.             {
  670.                 "IDR_PKR",
  671.                 "PKR_SRL",
  672.                 "SRL_IDR",
  673.                 "BNT_SRL",
  674.             }
  675.         );

  676.         Map<String, BucketSensitivity> bucketVegaSensitivityMap = new TreeMap<String, BucketSensitivity>();

  677.         for (Map.Entry<String, Map<String, Double>> bucketVegaMapEntry : bucketVegaMap.entrySet())
  678.         {
  679.             bucketVegaSensitivityMap.put (
  680.                 bucketVegaMapEntry.getKey(),
  681.                 new BucketSensitivity (bucketVegaMapEntry.getValue())
  682.             );
  683.         }

  684.         return bucketVegaSensitivityMap;
  685.     }

  686.     private static final BucketSensitivityIR IRCurrencyBucketSensitivity (
  687.         final String currency,
  688.         final double notional)
  689.         throws Exception
  690.     {
  691.         return new BucketSensitivityIR (
  692.             IRCurveTenorSensitivityMap (notional),
  693.             IRCurveTenorSensitivityMap (notional),
  694.             IRCurveTenorSensitivityMap (notional),
  695.             IRCurveTenorSensitivityMap (notional),
  696.             IRCurveTenorSensitivityMap (notional),
  697.             IRCurveTenorSensitivityMap (notional),
  698.             IRCurveTenorSensitivityMap (notional)
  699.         );
  700.     }

  701.     private static final void CreditComponentRiskFactorTenorSensitivity (
  702.         final Map<String, RiskFactorTenorSensitivity> tenorSensitivityMap,
  703.         final double notional,
  704.         final String componentName)
  705.         throws Exception
  706.     {
  707.         RiskFactorTenorSensitivity ustRiskFactorSensitivity = CreditCurveTenorSensitivityMap (notional);

  708.         tenorSensitivityMap.put (
  709.             componentName,
  710.             ustRiskFactorSensitivity
  711.         );
  712.     }

  713.     private static final RiskClassSensitivity EquitySensitivity (
  714.         final double notional,
  715.         final int vegaDurationDays)
  716.         throws Exception
  717.     {
  718.         Map<String, Map<String, Double>> bucketDeltaMap = EquityRiskFactorSensitivityMap (notional);

  719.         Map<String, BucketSensitivity> bucketDeltaSensitivityMap = new HashMap<String, BucketSensitivity>();

  720.         for (Map.Entry<String, Map<String, Double>> bucketDeltaMapEntry : bucketDeltaMap.entrySet())
  721.         {
  722.             bucketDeltaSensitivityMap.put (
  723.                 bucketDeltaMapEntry.getKey(),
  724.                 new BucketSensitivity (bucketDeltaMapEntry.getValue())
  725.             );
  726.         }

  727.         Map<String, Map<String, Double>> bucketVegaMap = EquityRiskFactorSensitivityMap (notional);

  728.         Map<String, BucketSensitivity> bucketVegaSensitivityMap = new HashMap<String, BucketSensitivity>();

  729.         for (Map.Entry<String, Map<String, Double>> bucketVegaMapEntry : bucketVegaMap.entrySet())
  730.         {
  731.             bucketVegaSensitivityMap.put (
  732.                 bucketVegaMapEntry.getKey(),
  733.                 new BucketSensitivity (bucketVegaMapEntry.getValue())
  734.             );
  735.         }

  736.         return new RiskClassSensitivity (
  737.             new RiskMeasureSensitivity (bucketDeltaSensitivityMap),
  738.             new RiskMeasureSensitivity (bucketVegaSensitivityMap),
  739.             new RiskMeasureSensitivity (bucketVegaSensitivityMap)
  740.         );
  741.     }

  742.     private static final RiskClassSensitivity CommoditySensitivity (
  743.         final double notional,
  744.         final int vegaDurationDays)
  745.         throws Exception
  746.     {
  747.         Map<String, Map<String, Double>> bucketDeltaMap = CommodityRiskFactorSensitivityMap (notional);

  748.         Map<String, BucketSensitivity> bucketDeltaSensitivityMap = new HashMap<String, BucketSensitivity>();

  749.         for (Map.Entry<String, Map<String, Double>> bucketDeltaMapEntry : bucketDeltaMap.entrySet())
  750.         {
  751.             bucketDeltaSensitivityMap.put (
  752.                 bucketDeltaMapEntry.getKey(),
  753.                 new BucketSensitivity (bucketDeltaMapEntry.getValue())
  754.             );
  755.         }

  756.         Map<String, Map<String, Double>> bucketVegaMap = CommodityRiskFactorSensitivityMap (notional);

  757.         Map<String, BucketSensitivity> bucketVegaSensitivityMap = new HashMap<String, BucketSensitivity>();

  758.         for (Map.Entry<String, Map<String, Double>> bucketVegaMapEntry : bucketVegaMap.entrySet())
  759.         {
  760.             bucketVegaSensitivityMap.put (
  761.                 bucketVegaMapEntry.getKey(),
  762.                 new BucketSensitivity (bucketVegaMapEntry.getValue())
  763.             );
  764.         }

  765.         return new RiskClassSensitivity (
  766.             new RiskMeasureSensitivity (bucketDeltaSensitivityMap),
  767.             new RiskMeasureSensitivity (bucketVegaSensitivityMap),
  768.             new RiskMeasureSensitivity (bucketVegaSensitivityMap)
  769.         );
  770.     }

  771.     private static final RiskClassSensitivity FXSensitivity (
  772.         final String[] currencyArray,
  773.         final double notional)
  774.         throws Exception
  775.     {
  776.         Map<String, Map<String, Double>> bucketDeltaMap = FXCategorySensitivityMap (
  777.             currencyArray,
  778.             notional
  779.         );

  780.         Map<String, BucketSensitivity> bucketDeltaSensitivityMap = new TreeMap<String, BucketSensitivity>();

  781.         for (Map.Entry<String, Map<String, Double>> deltaCategoryMapEntry : bucketDeltaMap.entrySet())
  782.         {
  783.             bucketDeltaSensitivityMap.put (
  784.                 deltaCategoryMapEntry.getKey(),
  785.                 new BucketSensitivity (deltaCategoryMapEntry.getValue())
  786.             );
  787.         }

  788.         Map<String, BucketSensitivity> bucketVegaSensitivityMap = BucketFXVegaSensitivityMap (notional);

  789.         return new RiskClassSensitivity (
  790.             new RiskMeasureSensitivity (bucketDeltaSensitivityMap),
  791.             new RiskMeasureSensitivity (bucketVegaSensitivityMap),
  792.             new RiskMeasureSensitivity (bucketVegaSensitivityMap)
  793.         );
  794.     }

  795.     private static final RiskClassSensitivityIR IRSensitivity (
  796.         final String[] currencyArray,
  797.         final double[] notionalArray)
  798.         throws Exception
  799.     {
  800.         Map<String, BucketSensitivityIR> bucketDeltaSensitivityMap = new HashMap<String, BucketSensitivityIR>();

  801.         Map<String, BucketSensitivityIR> bucketVegaSensitivityMap = new HashMap<String, BucketSensitivityIR>();

  802.         for (int currencyIndex = 0; currencyIndex < currencyArray.length; ++currencyIndex)
  803.         {
  804.             bucketDeltaSensitivityMap.put (
  805.                 currencyArray[currencyIndex],
  806.                 IRCurrencyBucketSensitivity (
  807.                     currencyArray[currencyIndex],
  808.                     notionalArray[currencyIndex]
  809.                 )
  810.             );

  811.             bucketVegaSensitivityMap.put (
  812.                 currencyArray[currencyIndex],
  813.                 IRCurrencyBucketSensitivity (
  814.                     currencyArray[currencyIndex],
  815.                     notionalArray[currencyIndex]
  816.                 )
  817.             );
  818.         }

  819.         return new RiskClassSensitivityIR (
  820.             new RiskMeasureSensitivityIR (bucketDeltaSensitivityMap),
  821.             new RiskMeasureSensitivityIR (bucketVegaSensitivityMap),
  822.             new RiskMeasureSensitivityIR (bucketVegaSensitivityMap)
  823.         );
  824.     }

  825.     private static final RiskClassSensitivityCR CreditSensitivity (
  826.         final String[][] bucketComponentGrid,
  827.         final int[] bucketIndexArray,
  828.         final double notional)
  829.         throws Exception
  830.     {
  831.         Map<String, BucketSensitivityCR> bucketDeltaSensitivityMap =
  832.             new HashMap<String, BucketSensitivityCR>();

  833.         Map<String, BucketSensitivityCR> bucketVegaSensitivityMap =
  834.             new HashMap<String, BucketSensitivityCR>();


  835.         for (int bucketIndex : bucketIndexArray)
  836.         {
  837.             Map<String, RiskFactorTenorSensitivity> tenorDeltaSensitivityMap = new
  838.                 CaseInsensitiveHashMap<RiskFactorTenorSensitivity>();

  839.             Map<String, RiskFactorTenorSensitivity> tenorVegaSensitivityMap = new
  840.                 CaseInsensitiveHashMap<RiskFactorTenorSensitivity>();

  841.             for (String componentName : bucketComponentGrid[bucketIndex - 1])
  842.             {
  843.                 CreditComponentRiskFactorTenorSensitivity (
  844.                     tenorDeltaSensitivityMap,
  845.                     notional,
  846.                     componentName
  847.                 );

  848.                 CreditComponentRiskFactorTenorSensitivity (
  849.                     tenorVegaSensitivityMap,
  850.                     notional,
  851.                     componentName
  852.                 );
  853.             }

  854.             bucketDeltaSensitivityMap.put (
  855.                 "" + bucketIndex,
  856.                 new BucketSensitivityCR (tenorDeltaSensitivityMap)
  857.             );

  858.             bucketVegaSensitivityMap.put (
  859.                 "" + bucketIndex,
  860.                 new BucketSensitivityCR (tenorVegaSensitivityMap)
  861.             );
  862.         }

  863.         return new RiskClassSensitivityCR (
  864.             new RiskMeasureSensitivityCR (bucketDeltaSensitivityMap),
  865.             new RiskMeasureSensitivityCR (bucketVegaSensitivityMap),
  866.             new RiskMeasureSensitivityCR (bucketVegaSensitivityMap)
  867.         );
  868.     }

  869.     public static final void main (
  870.         final String[] inputArray)
  871.         throws Exception
  872.     {
  873.         EnvManager.InitEnv ("");

  874.         double notional = 100.;
  875.         int vegaDurationDays = 365;
  876.         String[] fxCurrencyArray = {
  877.             "USD",
  878.             "EUR",
  879.             "CNY",
  880.             "INR",
  881.             "JPY"
  882.         };
  883.         String[] irCurrencyArray = {
  884.             "USD",
  885.             "EUR",
  886.             "CNY",
  887.             "INR",
  888.             "JPY"
  889.         };

  890.         double[] irNotionalArray = {
  891.             100.,
  892.             108.,
  893.             119.,
  894.              49.,
  895.              28.
  896.         };
  897.         int[] crqBucketIndexArray = {
  898.              1,
  899.              2,
  900.              3,
  901.              4,
  902.              5,
  903.              6,
  904.              7,
  905.              8,
  906.              9,
  907.             10,
  908.             11,
  909.             12,
  910.         };
  911.         String[][] crqBucketComponentGrid = {
  912.             {"01a", "01b", "01c", "01d", "01e", "01f"},
  913.             {"02a", "02b", "02c", "02d", "02e", "02f"},
  914.             {"03a", "03b", "03c", "03d", "03e", "03f"},
  915.             {"04a", "04b", "04c", "04d", "04e", "04f"},
  916.             {"05a", "05b", "05c", "05d", "05e", "05f"},
  917.             {"06a", "06b", "06c", "06d", "06e", "06f"},
  918.             {"07a", "07b", "07c", "07d", "07e", "07f"},
  919.             {"08a", "08b", "08c", "08d", "08e", "08f"},
  920.             {"09a", "09b", "09c", "09d", "09e", "09f"},
  921.             {"10a", "10b", "10c", "10d", "10e", "10f"},
  922.             {"11a", "11b", "11c", "11d", "11e", "11f"},
  923.             {"12a", "12b", "12c", "12d", "12e", "12f"},
  924.         };
  925.         int[] crnqBucketIndexArray = {
  926.              1,
  927.              2,
  928.         };
  929.         String[][] crnqBucketComponentGrid = {
  930.             {"01a", "01b", "01c", "01d", "01e", "01f"},
  931.             {"02a", "02b", "02c", "02d", "02e", "02f"},
  932.         };

  933.         List<String> fxCurrencyList = new ArrayList<String>();

  934.         for (String fxCurrency : fxCurrencyArray)
  935.         {
  936.             fxCurrencyList.add (fxCurrency);
  937.         }

  938.         MarginEstimationSettings marginEstimationSettings = MarginEstimationSettings.CornishFischer
  939.             (MarginEstimationSettings.POSITION_PRINCIPAL_COMPONENT_COVARIANCE_ESTIMATOR_ISDA);

  940.         ProductClassSettings productClassSettings = ProductClassSettings.ISDA_21 (
  941.             fxCurrencyList,
  942.             vegaDurationDays
  943.         );

  944.         RiskClassSensitivity equityRiskClassSensitivity = EquitySensitivity (
  945.             notional,
  946.             vegaDurationDays
  947.         );

  948.         RiskClassAggregate equityRiskClassAggregate = equityRiskClassSensitivity.aggregate (
  949.             productClassSettings.equityRiskClassSensitivitySettings(),
  950.             marginEstimationSettings
  951.         );

  952.         RiskClassSensitivity commodityRiskClassSensitivity = CommoditySensitivity (
  953.             notional,
  954.             vegaDurationDays
  955.         );

  956.         RiskClassAggregate commodityRiskClassAggregate = commodityRiskClassSensitivity.aggregate (
  957.             productClassSettings.commodityRiskClassSensitivitySettings(),
  958.             marginEstimationSettings
  959.         );

  960.         RiskClassSensitivity fxRiskClassSensitivity = FXSensitivity (
  961.             fxCurrencyArray,
  962.             notional
  963.         );

  964.         RiskClassAggregate fxRiskClassAggregate = fxRiskClassSensitivity.aggregate (
  965.             productClassSettings.fxRiskClassSensitivitySettings(),
  966.             marginEstimationSettings
  967.         );

  968.         RiskClassSensitivityIR irRiskClassSensitivity = IRSensitivity (
  969.             irCurrencyArray,
  970.             irNotionalArray
  971.         );

  972.         RiskClassAggregateIR irRiskClassAggregate = irRiskClassSensitivity.aggregate (
  973.             productClassSettings.irRiskClassSensitivitySettings(),
  974.             marginEstimationSettings
  975.         );

  976.         RiskClassSensitivityCR crqRiskClassSensitivity = CreditSensitivity (
  977.             crqBucketComponentGrid,
  978.             crqBucketIndexArray,
  979.             notional
  980.         );

  981.         RiskClassAggregateCR crqRiskClassAggregate = crqRiskClassSensitivity.aggregate (
  982.             productClassSettings.creditQualifyingRiskClassSensitivitySettings(),
  983.             marginEstimationSettings
  984.         );

  985.         RiskClassSensitivityCR crnqRiskClassSensitivity = CreditSensitivity (
  986.             crnqBucketComponentGrid,
  987.             crnqBucketIndexArray,
  988.             notional
  989.         );

  990.         RiskClassAggregateCR crnqRiskClassAggregate = crnqRiskClassSensitivity.aggregate (
  991.             productClassSettings.creditNonQualifyingRiskClassSensitivitySettings(),
  992.             marginEstimationSettings
  993.         );

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

  995.         System.out.println ("\t|   SIMM RISK CLASS INITIAL MARGIN    ||");

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

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

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

  999.         System.out.println ("\t|     - RISK FACTOR        =>  MARGIN ||");

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

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

  1002.         System.out.println (
  1003.             "\t| PRODUCT EQUITY MARGIN    => " +
  1004.             FormatUtil.FormatDouble (equityRiskClassAggregate.margin(), 6, 0, 1.) + " ||"
  1005.         );

  1006.         System.out.println (
  1007.             "\t| PRODUCT COMMODITY MARGIN => " +
  1008.             FormatUtil.FormatDouble (commodityRiskClassAggregate.margin(), 6, 0, 1.) + " ||"
  1009.         );

  1010.         System.out.println (
  1011.             "\t| PRODUCT FX MARGIN        => " +
  1012.             FormatUtil.FormatDouble (fxRiskClassAggregate.margin(), 6, 0, 1.) + " ||"
  1013.         );

  1014.         System.out.println (
  1015.             "\t| PRODUCT IR MARGIN        => " +
  1016.             FormatUtil.FormatDouble (irRiskClassAggregate.margin(), 6, 0, 1.) + " ||"
  1017.         );

  1018.         System.out.println (
  1019.             "\t| PRODUCT CRQ MARGIN       => " +
  1020.             FormatUtil.FormatDouble (crqRiskClassAggregate.margin(), 6, 0, 1.) + " ||"
  1021.         );

  1022.         System.out.println (
  1023.             "\t| PRODUCT CRNQ MARGIN      => " +
  1024.             FormatUtil.FormatDouble (crnqRiskClassAggregate.margin(), 6, 0, 1.) + " ||"
  1025.         );

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

  1027.         System.out.println();

  1028.         ProductClassSensitivity productClassSensitivity = new ProductClassSensitivity (
  1029.             equityRiskClassSensitivity,
  1030.             commodityRiskClassSensitivity,
  1031.             fxRiskClassSensitivity,
  1032.             irRiskClassSensitivity,
  1033.             crqRiskClassSensitivity,
  1034.             crnqRiskClassSensitivity
  1035.         );

  1036.         ProductClassMargin productClassMargin = productClassSensitivity.estimate (
  1037.             productClassSettings,
  1038.             marginEstimationSettings
  1039.         );

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

  1041.         System.out.println ("\t|  SIMM PRODUCT CLASS INITIAL MARGIN  ||");

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

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

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

  1045.         System.out.println ("\t|     - RISK FACTOR        =>  MARGIN ||");

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

  1047.         System.out.println (
  1048.             "\t| PRODUCT EQUITY MARGIN    => " +
  1049.             FormatUtil.FormatDouble (
  1050.                 productClassMargin.equityRiskClassAggregate().margin(), 6, 0, 1.
  1051.             ) + " ||"
  1052.         );

  1053.         System.out.println (
  1054.             "\t| PRODUCT COMMODITY MARGIN => " +
  1055.             FormatUtil.FormatDouble (
  1056.                 productClassMargin.commodityRiskClassAggregate().margin(), 6, 0, 1.
  1057.             ) + " ||"
  1058.         );

  1059.         System.out.println (
  1060.             "\t| PRODUCT FX MARGIN        => " +
  1061.             FormatUtil.FormatDouble (
  1062.                 productClassMargin.fxRiskClassAggregate().margin(), 6, 0, 1.
  1063.             ) + " ||"
  1064.         );

  1065.         System.out.println (
  1066.             "\t| PRODUCT IR MARGIN        => " +
  1067.             FormatUtil.FormatDouble (
  1068.                 productClassMargin.irRiskClassAggregate().margin(), 6, 0, 1.
  1069.             ) + " ||"
  1070.         );

  1071.         System.out.println (
  1072.             "\t| PRODUCT CRQ MARGIN       => " +
  1073.             FormatUtil.FormatDouble (
  1074.                 productClassMargin.creditQualifyingRiskClassAggregate().margin(), 6, 0, 1.
  1075.             ) + " ||"
  1076.         );

  1077.         System.out.println (
  1078.             "\t| PRODUCT CRNQ MARGIN      => " +
  1079.             FormatUtil.FormatDouble (
  1080.                 productClassMargin.creditNonQualifyingRiskClassAggregate().margin(), 6, 0, 1.
  1081.             ) + " ||"
  1082.         );

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

  1084.         System.out.println (
  1085.             "\t| PRODUCT TOTAL MARGIN     => " +
  1086.             FormatUtil.FormatDouble (
  1087.                 productClassMargin.total (productClassSettings.labelCorrelation()), 6, 0, 1.
  1088.             ) + " ||"
  1089.         );

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

  1091.         EnvManager.TerminateEnv();
  1092.     }
  1093. }