FixFloatExplainProcessor.java

  1. package org.drip.historical.engine;

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

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

  77. /**
  78.  * <i>FixFloatExplainProcessor</i> contains the Functionality associated with the Horizon Analysis of the Fix
  79.  * Float Swap.
  80.  *
  81.  *  <br><br>
  82.  *  <ul>
  83.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  84.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationSupportLibrary.md">Computation Support</a></li>
  85.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/historical/README.md">Historical State Processing Utilities</a></li>
  86.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/historical/engine/README.md">Product Horizon Change Explain Engine</a></li>
  87.  *  </ul>
  88.  *
  89.  * @author Lakshmi Krishnamurthy
  90.  */

  91. public class FixFloatExplainProcessor extends org.drip.historical.engine.HorizonChangeExplainProcessor {

  92.     /**
  93.      * FixFloatExplainProcessor Constructor
  94.      *
  95.      * @param ffc The Fix Float Component
  96.      * @param iSettleLag The Component's Settle Lag
  97.      * @param strMarketMeasureName The Market Measure Name
  98.      * @param dblMarketMeasureValue The Market Measure Value
  99.      * @param dtFirst First Date
  100.      * @param dtSecond Second Date
  101.      * @param csqcFirst First Market Parameters
  102.      * @param csqcSecond Second Market Parameters
  103.      * @param mapCSQCRollDown Map of the Roll Down Market Parameters
  104.      *
  105.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  106.      */

  107.     public FixFloatExplainProcessor (
  108.         final org.drip.product.rates.FixFloatComponent ffc,
  109.         final int iSettleLag,
  110.         final java.lang.String strMarketMeasureName,
  111.         final double dblMarketMeasureValue,
  112.         final org.drip.analytics.date.JulianDate dtFirst,
  113.         final org.drip.analytics.date.JulianDate dtSecond,
  114.         final org.drip.param.market.CurveSurfaceQuoteContainer csqcFirst,
  115.         final org.drip.param.market.CurveSurfaceQuoteContainer csqcSecond,
  116.         final
  117.             org.drip.analytics.support.CaseInsensitiveHashMap<org.drip.param.market.CurveSurfaceQuoteContainer>
  118.             mapCSQCRollDown)
  119.         throws java.lang.Exception
  120.     {
  121.         super (ffc, iSettleLag, strMarketMeasureName, dblMarketMeasureValue, dtFirst, dtSecond, csqcFirst,
  122.             csqcSecond, mapCSQCRollDown);
  123.     }

  124.     @Override public org.drip.historical.attribution.PositionMarketSnap snapFirstMarketValue()
  125.     {
  126.         org.drip.analytics.date.JulianDate dtFirst = firstDate();

  127.         org.drip.product.rates.FixFloatComponent ffc = (org.drip.product.rates.FixFloatComponent)
  128.             component();

  129.         java.lang.String strPayCurrency = ffc.payCurrency();

  130.         java.util.Map<java.lang.String, java.lang.Double> mapFixFloat = ffc.value
  131.             (org.drip.param.valuation.ValuationParams.Spot (dtFirst.addBusDays (settleLag(),
  132.                 strPayCurrency).julian()), null, firstMarketParameters(), null);

  133.         if (null == mapFixFloat || !mapFixFloat.containsKey ("Accrued") || !mapFixFloat.containsKey
  134.             ("CleanFixedDV01") || !mapFixFloat.containsKey ("CleanFloatingDV01") || !mapFixFloat.containsKey
  135.                 ("CleanPV") || !mapFixFloat.containsKey ("CumulativeCouponAmount") ||
  136.                     !mapFixFloat.containsKey ("CumulativeCouponDCF") || !mapFixFloat.containsKey
  137.                         ("DerivedCleanPV") || !mapFixFloat.containsKey ("DerivedCumulativeCouponAmount") ||
  138.                             !mapFixFloat.containsKey ("DerivedCumulativeCouponDCF") ||
  139.                                 !mapFixFloat.containsKey ("ReferenceCleanPV") || !mapFixFloat.containsKey
  140.                                     ("ReferenceCumulativeCouponAmount") || !mapFixFloat.containsKey
  141.                                         ("ReferenceCumulativeCouponDCF") || !mapFixFloat.containsKey
  142.                                             ("SwapRate"))
  143.             return null;

  144.         double dblCleanPV = mapFixFloat.get ("CleanPV");

  145.         double dblSwapRate = mapFixFloat.get ("SwapRate");

  146.         double dblSwapRateSensitivity = 10000. * mapFixFloat.get ("CleanFixedDV01");

  147.         org.drip.state.identifier.ForwardLabel forwardLabel = ffc.derivedStream().forwardLabel();

  148.         org.drip.historical.engine.MarketMeasureRollDown mmrd = rollDownMeasureMap();

  149.         if (null == mmrd) return null;

  150.         double dblRollDownInnate = mmrd.innate();

  151.         org.drip.analytics.support.CaseInsensitiveHashMap<java.lang.Double> mapHorizonMetric =
  152.             mmrd.horizon();

  153.         try {
  154.             org.drip.historical.attribution.PositionMarketSnap pms = new
  155.                 org.drip.historical.attribution.PositionMarketSnap (dtFirst, dblCleanPV);

  156.             if (!pms.setR1 ("Accrued", mapFixFloat.get ("Accrued"))) return null;

  157.             if (!pms.setR1 ("CleanFixedDV01", dblSwapRateSensitivity)) return null;

  158.             if (!pms.setR1 ("CleanFloatingDV01", 10000. * mapFixFloat.get ("CleanFloatingDV01")))
  159.                 return null;

  160.             if (!pms.setC1 ("CouponCurrency", forwardLabel.currency())) return null;

  161.             if (!pms.setR1 ("CumulativeCouponAmount", mapFixFloat.get ("CumulativeCouponAmount")))
  162.                 return null;

  163.             if (!pms.setR1 ("CumulativeCouponDCF", mapFixFloat.get ("CumulativeCouponDCF"))) return null;

  164.             if (!pms.setR1 ("DerivedCleanPV", mapFixFloat.get ("DerivedCleanPV"))) return null;

  165.             if (!pms.setDate ("EffectiveDate", ffc.effectiveDate())) return null;

  166.             if (!pms.setC1 ("FixedAccrualDayCount", ffc.referenceStream().accrualDC())) return null;

  167.             if (!pms.setR1 ("FixedCoupon", dblSwapRate)) return null;

  168.             if (!pms.setR1 ("FixedCumulativeCouponAmount", mapFixFloat.get
  169.                 ("ReferenceCumulativeCouponAmount")))
  170.                 return null;

  171.             if (!pms.setR1 ("FixedCumulativeCouponDCF", mapFixFloat.get ("ReferenceCumulativeCouponDCF")))
  172.                 return null;

  173.             if (!pms.setC1 ("FloatAccrualDayCount", forwardLabel.floaterIndex().dayCount())) return null;

  174.             if (!pms.setR1 ("FloatCumulativeCouponAmount", mapFixFloat.get
  175.                 ("DerivedCumulativeCouponAmount")))
  176.                 return null;

  177.             if (!pms.setR1 ("FloatCumulativeCouponDCF", mapFixFloat.get ("DerivedCumulativeCouponDCF")))
  178.                 return null;

  179.             if (!pms.setC1 ("FloaterLabel", forwardLabel.fullyQualifiedName())) return null;

  180.             if (!pms.setDate ("MaturityDate", ffc.maturityDate())) return null;

  181.             if (!pms.setC1 ("MaturityTenor", ffc.tenor())) return null;

  182.             if (!pms.setC1 ("PayCurrency", strPayCurrency)) return null;

  183.             if (!pms.setR1 ("ReferenceCleanPV", mapFixFloat.get ("ReferenceCleanPV"))) return null;

  184.             if (!pms.setR1 ("SwapRate", dblSwapRate)) return null;

  185.             if (!pms.setR1 ("SwapRateRollDown", dblRollDownInnate)) return null;

  186.             for (java.lang.String strRollDownTenor : mapHorizonMetric.keySet()) {
  187.                 if (!pms.setR1 ("SwapRateRollDown" + strRollDownTenor, mapHorizonMetric.get
  188.                     (strRollDownTenor)))
  189.                     return null;
  190.             }

  191.             if (!pms.addManifestMeasureSnap ("SwapRate", dblSwapRate, -1. * dblSwapRateSensitivity,
  192.                 dblRollDownInnate))
  193.                 return null;

  194.             return pms;
  195.         } catch (java.lang.Exception e) {
  196.             e.printStackTrace();
  197.         }

  198.         return null;
  199.     }

  200.     @Override public boolean updateFixings()
  201.     {
  202.         org.drip.product.rates.FixFloatComponent ffc = (org.drip.product.rates.FixFloatComponent)
  203.             component();

  204.         org.drip.product.rates.Stream floatingStream = ffc.derivedStream();

  205.         int iDate = secondDate().julian();

  206.         if (iDate > ffc.maturityDate().julian()) return false;

  207.         int iEffectiveDate = ffc.effectiveDate().julian();

  208.         if (iDate <= iEffectiveDate) iDate = iEffectiveDate;

  209.         org.drip.analytics.cashflow.CompositePeriod cpFixing = floatingStream.containingPeriod (iDate);

  210.         if (null == cpFixing) return false;

  211.         org.drip.analytics.cashflow.ComposableUnitPeriod cupEnclosing = cpFixing.enclosingCUP (iDate);

  212.         if (null == cupEnclosing || !(cupEnclosing instanceof
  213.             org.drip.analytics.cashflow.ComposableUnitFloatingPeriod))
  214.             return false;

  215.         org.drip.param.market.CurveSurfaceQuoteContainer csqcFirst = firstMarketParameters();

  216.         org.drip.state.identifier.ForwardLabel forwardLabel = floatingStream.forwardLabel();

  217.         int iFixingDate = ((org.drip.analytics.cashflow.ComposableUnitFloatingPeriod)
  218.             cupEnclosing).referenceIndexPeriod().fixingDate();

  219.         try {
  220.             double dblResetFixingRate = cupEnclosing.baseRate (csqcFirst);

  221.             return csqcFirst.setFixing (iFixingDate, forwardLabel, dblResetFixingRate) &&
  222.                 secondMarketParameters().setFixing (iFixingDate, forwardLabel, dblResetFixingRate);
  223.         } catch (java.lang.Exception e) {
  224.             e.printStackTrace();
  225.         }

  226.         return false;
  227.     }

  228.     @Override public org.drip.historical.attribution.PositionMarketSnap snapSecondMarketValue()
  229.     {
  230.         org.drip.analytics.date.JulianDate dtSecond = secondDate();

  231.         org.drip.product.rates.FixFloatComponent ffc = (org.drip.product.rates.FixFloatComponent)
  232.             component();

  233.         java.util.Map<java.lang.String, java.lang.Double> mapFixFloat = ffc.value
  234.             (org.drip.param.valuation.ValuationParams.Spot (dtSecond.addBusDays (settleLag(),
  235.                 ffc.payCurrency()).julian()), null, secondMarketParameters(), null);

  236.         if (null == mapFixFloat || !mapFixFloat.containsKey ("CleanFixedDV01") || !mapFixFloat.containsKey
  237.             ("CleanPV") || !mapFixFloat.containsKey ("CumulativeCouponAmount") || !mapFixFloat.containsKey
  238.                 ("CumulativeCouponDCF") || !mapFixFloat.containsKey ("DerivedCumulativeCouponAmount") ||
  239.                     !mapFixFloat.containsKey ("DerivedCumulativeCouponDCF") || !mapFixFloat.containsKey
  240.                         ("ReferenceCumulativeCouponAmount") || !mapFixFloat.containsKey
  241.                             ("ReferenceCumulativeCouponDCF") || !mapFixFloat.containsKey ("ResetDate") ||
  242.                                 !mapFixFloat.containsKey ("ResetRate") || !mapFixFloat.containsKey
  243.                                     ("SwapRate"))
  244.             return null;

  245.         double dblSwapRate = mapFixFloat.get ("SwapRate");

  246.         try {
  247.             org.drip.historical.attribution.PositionMarketSnap pms = new
  248.                 org.drip.historical.attribution.PositionMarketSnap (dtSecond, mapFixFloat.get ("CleanPV"));

  249.             if (!pms.setR1 ("CumulativeCouponAmount", mapFixFloat.get ("CumulativeCouponAmount")))
  250.                 return null;

  251.             if (!pms.setR1 ("CumulativeCouponDCF", mapFixFloat.get ("CumulativeCouponDCF"))) return null;

  252.             if (!pms.setR1 ("FixedCumulativeCouponAmount", mapFixFloat.get
  253.                 ("ReferenceCumulativeCouponAmount")))
  254.                 return null;

  255.             if (!pms.setR1 ("FixedCumulativeCouponDCF", mapFixFloat.get ("ReferenceCumulativeCouponDCF")))
  256.                 return null;

  257.             if (!pms.setR1 ("FloatCumulativeCouponAmount", mapFixFloat.get
  258.                 ("DerivedCumulativeCouponAmount")))
  259.                 return null;

  260.             if (!pms.setR1 ("FloatCumulativeCouponDCF", mapFixFloat.get ("DerivedCumulativeCouponDCF")))
  261.                 return null;

  262.             if (!pms.setDate ("ResetDate", new org.drip.analytics.date.JulianDate ((int) (double)
  263.                 mapFixFloat.get ("ResetDate"))))
  264.                 return null;

  265.             if (!pms.setR1 ("ResetRate", mapFixFloat.get ("ResetRate"))) return null;

  266.             if (!pms.setR1 ("SwapRate", dblSwapRate)) return null;

  267.             if (!pms.addManifestMeasureSnap ("SwapRate", dblSwapRate, -10000. * mapFixFloat.get
  268.                 ("CleanFixedDV01"), 0.))
  269.                 return null;

  270.             return pms;
  271.         } catch (java.lang.Exception e) {
  272.             e.printStackTrace();
  273.         }

  274.         return null;
  275.     }

  276.     @Override public org.drip.analytics.support.CaseInsensitiveHashMap<java.lang.Double>
  277.         crossHorizonDifferentialMetrics (
  278.             final org.drip.historical.attribution.PositionMarketSnap pmsFirst,
  279.             final org.drip.historical.attribution.PositionMarketSnap pmsSecond)
  280.     {
  281.         if (null == pmsFirst || null == pmsSecond) return null;

  282.         org.drip.analytics.support.CaseInsensitiveHashMap<java.lang.Double> mapDifferentialMetric = new
  283.             org.drip.analytics.support.CaseInsensitiveHashMap<java.lang.Double>();

  284.         org.drip.analytics.date.JulianDate dtEffective = pmsFirst.date ("EffectiveDate");

  285.         java.lang.String strFixedAccrualDayCount = pmsFirst.c1 ("FixedAccrualDayCount");

  286.         java.lang.String strFloatAccrualDayCount = pmsFirst.c1 ("FloatAccrualDayCount");

  287.         java.lang.String strCalendar = pmsFirst.c1 ("PayCurrency");

  288.         int iDate1M = dtEffective.addTenor ("1M").julian();

  289.         int iDate3M = dtEffective.addTenor ("3M").julian();

  290.         int iEffectiveDate = dtEffective.julian();

  291.         try {
  292.             double dblFixedCumulativeCouponAmount = pmsSecond.r1 ("FixedCumulativeCouponAmount") -
  293.                 pmsFirst.r1 ("FixedCumulativeCouponAmount");

  294.             double dblFixedCumulativeCouponDCF = pmsSecond.r1 ("FixedCumulativeCouponDCF") - pmsFirst.r1
  295.                 ("FixedCumulativeCouponDCF");

  296.             double dblFloatCumulativeCouponAmount = pmsSecond.r1 ("FloatCumulativeCouponAmount") -
  297.                 pmsFirst.r1 ("FloatCumulativeCouponAmount");

  298.             double dblFloatCumulativeCouponDCF = pmsSecond.r1 ("FloatCumulativeCouponDCF") - pmsFirst.r1
  299.                 ("FloatCumulativeCouponDCF");

  300.             mapDifferentialMetric.put ("CumulativeCouponAmount", pmsSecond.r1 ("CumulativeCouponAmount") -
  301.                 pmsFirst.r1 ("CumulativeCouponAmount"));

  302.             mapDifferentialMetric.put ("CumulativeCouponDCF", pmsSecond.r1 ("CumulativeCouponDCF") -
  303.                 pmsFirst.r1 ("CumulativeCouponDCF"));

  304.             mapDifferentialMetric.put ("EffectiveFixedCouponRate", dblFixedCumulativeCouponAmount /
  305.                 dblFixedCumulativeCouponDCF);

  306.             mapDifferentialMetric.put ("EffectiveFloatCouponRate", dblFloatCumulativeCouponAmount /
  307.                 dblFloatCumulativeCouponDCF);

  308.             mapDifferentialMetric.put ("FixedAccrualDCF1M",
  309.                 org.drip.analytics.daycount.Convention.YearFraction (iEffectiveDate, iDate1M,
  310.                     strFixedAccrualDayCount, false, null, strCalendar));

  311.             mapDifferentialMetric.put ("FixedAccrualDCF3M",
  312.                 org.drip.analytics.daycount.Convention.YearFraction (iEffectiveDate, iDate3M,
  313.                     strFixedAccrualDayCount, false, null, strCalendar));

  314.             mapDifferentialMetric.put ("FixedCumulativeCouponAmount", dblFixedCumulativeCouponAmount);

  315.             mapDifferentialMetric.put ("FixedCumulativeCouponDCF", dblFixedCumulativeCouponDCF);

  316.             mapDifferentialMetric.put ("FloatAccrualDCF1M",
  317.                 org.drip.analytics.daycount.Convention.YearFraction (iEffectiveDate, iDate1M,
  318.                     strFloatAccrualDayCount, false, null, strCalendar));

  319.             mapDifferentialMetric.put ("FloatAccrualDCF3M",
  320.                 org.drip.analytics.daycount.Convention.YearFraction (iEffectiveDate, iDate3M,
  321.                     strFloatAccrualDayCount, false, null, strCalendar));

  322.             mapDifferentialMetric.put ("FloatCumulativeCouponAmount", dblFloatCumulativeCouponAmount);

  323.             mapDifferentialMetric.put ("FloatCumulativeCouponDCF", dblFloatCumulativeCouponDCF);

  324.             return mapDifferentialMetric;
  325.         } catch (java.lang.Exception e) {
  326.             e.printStackTrace();
  327.         }

  328.         return null;
  329.     }
  330. }