FRAStandardCapFloor.java

  1. package org.drip.product.fra;

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

  79. /**
  80.  * <i>FRAStandardCapFloor</i> implements the Caps and Floors on the Standard FRA.
  81.  *
  82.  *  <br><br>
  83.  *  <ul>
  84.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  85.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  86.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/product/README.md">Product Components/Baskets for Credit, FRA, FX, Govvie, Rates, and Option AssetClasses</a></li>
  87.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/product/fra/README.md">Standard/Market FRAs - Caps/Floors</a></li>
  88.  *  </ul>
  89.  * <br><br>
  90.  *
  91.  * @author Lakshmi Krishnamurthy
  92.  */

  93. public class FRAStandardCapFloor extends org.drip.product.option.OptionComponent
  94. {
  95.     private boolean _bIsCap = false;
  96.     private double _dblStrike = java.lang.Double.NaN;
  97.     private org.drip.product.rates.Stream _stream = null;

  98.     private java.util.List<org.drip.product.fra.FRAStandardCapFloorlet> _lsFRACapFloorlet = new
  99.         java.util.ArrayList<org.drip.product.fra.FRAStandardCapFloorlet>();

  100.     /**
  101.      * FRAStandardCapFloor constructor
  102.      *
  103.      * @param strName Name of the Cap/Floor Instance
  104.      * @param stream The Underlying Stream
  105.      * @param strManifestMeasure Measure of the Underlying Component
  106.      * @param bIsCap Is the FRA Option a Cap? TRUE - YES
  107.      * @param dblStrike Strike of the Underlying Component's Measure
  108.      * @param ltds Last Trading Date Setting
  109.      * @param csp Cash Settle Parameters
  110.      * @param fpg The Fokker Planck Pricer Instance
  111.      *
  112.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  113.      */

  114.     public FRAStandardCapFloor (
  115.         final java.lang.String strName,
  116.         final org.drip.product.rates.Stream stream,
  117.         final java.lang.String strManifestMeasure,
  118.         final boolean bIsCap,
  119.         final double dblStrike,
  120.         final org.drip.product.params.LastTradingDateSetting ltds,
  121.         final org.drip.param.valuation.CashSettleParams csp,
  122.         final org.drip.pricer.option.FokkerPlanckGenerator fpg)
  123.         throws java.lang.Exception
  124.     {
  125.         super (strName, org.drip.product.creator.SingleStreamComponentBuilder.FRAStandard
  126.             (stream.effective(), stream.forwardLabel(), dblStrike), strManifestMeasure, dblStrike,
  127.                 stream.initialNotional(), ltds, csp);

  128.         if (null == (_stream = stream) || !org.drip.numerical.common.NumberUtil.IsValid (_dblStrike = dblStrike))
  129.             throw new java.lang.Exception ("FRAStandardCapFloor Constructor => Invalid Inputs");

  130.         _bIsCap = bIsCap;

  131.         org.drip.state.identifier.ForwardLabel fri = _stream.forwardLabel();

  132.         if (null == fri)
  133.             throw new java.lang.Exception ("FRAStandardCapFloor Constructor => Invalid Floater Index");

  134.         for (org.drip.analytics.cashflow.CompositePeriod period : _stream.periods()) {
  135.             org.drip.product.fra.FRAStandardComponent fra =
  136.                 org.drip.product.creator.SingleStreamComponentBuilder.FRAStandard (new
  137.                     org.drip.analytics.date.JulianDate (period.startDate()), fri, _dblStrike);

  138.             _lsFRACapFloorlet.add (new org.drip.product.fra.FRAStandardCapFloorlet (fra.name() + "::LET",
  139.                 fra, strManifestMeasure, _bIsCap, _dblStrike, _stream.notional (period.startDate()), ltds,
  140.                     fpg, csp));
  141.         }
  142.     }

  143.     @Override public org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> value (
  144.         final org.drip.param.valuation.ValuationParams valParams,
  145.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  146.         final org.drip.param.market.CurveSurfaceQuoteContainer csqs,
  147.         final org.drip.param.valuation.ValuationCustomizationParams vcp)
  148.     {
  149.         double dblPV = 0.;
  150.         double dblPrice = 0.;
  151.         double dblUpfront = 0.;
  152.         org.drip.function.r1tor1solver.FixedPointFinderOutput fpfo = null;

  153.         long lStart = System.nanoTime();

  154.         final int iValueDate = valParams.valueDate();

  155.         org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapStreamResult = _stream.value
  156.             (valParams, pricerParams, csqs, vcp);

  157.         for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : _lsFRACapFloorlet) {
  158.             org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapFRAResult = fracfl.value
  159.                 (valParams, pricerParams, csqs, vcp);

  160.             if (null == mapFRAResult) continue;

  161.             if (mapFRAResult.containsKey ("Price")) dblPrice += mapFRAResult.get ("Price");

  162.             if (mapFRAResult.containsKey ("PV")) dblPV += mapFRAResult.get ("PV");

  163.             if (mapFRAResult.containsKey ("Upfront")) dblUpfront += mapFRAResult.get ("Upfront");
  164.         }

  165.         org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapResult = new
  166.             org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double>();

  167.         mapResult.put ("ATMFairPremium", mapStreamResult.get ("FairPremium"));

  168.         mapResult.put ("Price", dblPrice);

  169.         mapResult.put ("PV", dblPV);

  170.         mapResult.put ("Upfront", dblUpfront);

  171.         org.drip.function.definition.R1ToR1 funcVolPricer = new org.drip.function.definition.R1ToR1 (null) {
  172.             @Override public double evaluate (
  173.                 final double dblVolatility)
  174.                 throws java.lang.Exception
  175.             {
  176.                 double dblCapFloorletPrice = 0.;

  177.                 for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : _lsFRACapFloorlet) {
  178.                     int iExerciseDate = fracfl.exerciseDate().julian();

  179.                     if (iExerciseDate <= iValueDate) continue;

  180.                     dblCapFloorletPrice += fracfl.price (valParams, pricerParams, csqs, vcp, dblVolatility);
  181.                 }

  182.                 return dblCapFloorletPrice;
  183.             }
  184.         };

  185.         try {
  186.             fpfo = (new org.drip.function.r1tor1solver.FixedPointFinderBracketing (dblPrice, funcVolPricer,
  187.                 null, org.drip.function.r1tor1solver.VariateIteratorPrimitive.BISECTION, false)).findRoot
  188.                     (org.drip.function.r1tor1solver.InitializationHeuristics.FromHardSearchEdges (0.0001,
  189.                         5.));
  190.         } catch (java.lang.Exception e) {
  191.             e.printStackTrace();

  192.             return mapResult;
  193.         }

  194.         mapResult.put ("CalcTime", (System.nanoTime() - lStart) * 1.e-09);

  195.         if (null != fpfo && fpfo.containsRoot())
  196.             mapResult.put ("FlatVolatility", fpfo.getRoot());
  197.         else
  198.             mapResult.put ("FlatVolatility", java.lang.Double.NaN);

  199.         return mapResult;
  200.     }

  201.     @Override public java.util.Set<java.lang.String> measureNames()
  202.     {
  203.         java.util.Set<java.lang.String> setstrMeasureNames = new java.util.TreeSet<java.lang.String>();

  204.         setstrMeasureNames.add ("ATMFairPremium");

  205.         setstrMeasureNames.add ("CalcTime");

  206.         setstrMeasureNames.add ("FlatVolatility");

  207.         setstrMeasureNames.add ("Price");

  208.         setstrMeasureNames.add ("PV");

  209.         setstrMeasureNames.add ("Upfront");

  210.         return setstrMeasureNames;
  211.     }

  212.     @Override public double pv (
  213.         final org.drip.param.valuation.ValuationParams valParams,
  214.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  215.         final org.drip.param.market.CurveSurfaceQuoteContainer csqc,
  216.         final org.drip.param.valuation.ValuationCustomizationParams vcp)
  217.         throws java.lang.Exception
  218.     {
  219.         double dblPV = 0.;

  220.         for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : _lsFRACapFloorlet)
  221.             dblPV += fracfl.pv (valParams, pricerParams, csqc, vcp);

  222.         return dblPV;
  223.     }

  224.     /**
  225.      * Retrieve the Stream Instance Underlying the Cap
  226.      *
  227.      * @return The Stream Instance Underlying the Cap
  228.      */

  229.     public org.drip.product.rates.Stream stream()
  230.     {
  231.         return _stream;
  232.     }

  233.     /**
  234.      * Indicate if this is a Cap or Floor
  235.      *
  236.      * @return TRUE - The Product is a Cap
  237.      */

  238.     public boolean isCap()
  239.     {
  240.         return _bIsCap;
  241.     }

  242.     /**
  243.      * Retrieve the List of the Underlying Caplets/Floorlets
  244.      *
  245.      * @return The List of the Underlying Caplets/Floorlets
  246.      */

  247.     public java.util.List<org.drip.product.fra.FRAStandardCapFloorlet> capFloorlets()
  248.     {
  249.         return _lsFRACapFloorlet;
  250.     }

  251.     /**
  252.      * Compute the ATM Cap/Floor Price from the Flat Volatility
  253.      *
  254.      * @param valParams The Valuation Parameters
  255.      * @param pricerParams The Pricer Parameters
  256.      * @param csqs The Market Parameters
  257.      * @param vcp The Valuation Customization Parameters
  258.      * @param dblFlatVolatility The Flat Volatility
  259.      *
  260.      * @return The Cap/Floor ATM Price
  261.      *
  262.      * @throws java.lang.Exception Thrown if the ATM Price cannot be calculated
  263.      */

  264.     public double atmPriceFromVolatility (
  265.         final org.drip.param.valuation.ValuationParams valParams,
  266.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  267.         final org.drip.param.market.CurveSurfaceQuoteContainer csqs,
  268.         final org.drip.param.valuation.ValuationCustomizationParams vcp,
  269.         final double dblFlatVolatility)
  270.         throws java.lang.Exception
  271.     {
  272.         if (null == valParams || !org.drip.numerical.common.NumberUtil.IsValid (dblFlatVolatility))
  273.             throw new java.lang.Exception ("FRAStandardCapFloor::atmPriceFromVolatility => Invalid Inputs");

  274.         int iValueDate = valParams.valueDate();

  275.         double dblPrice = 0.;

  276.         org.drip.product.fra.FRAStandardCapFloorlet fraLeading = _lsFRACapFloorlet.get (0);

  277.         java.lang.String strManifestMeasure = fraLeading.manifestMeasure();

  278.         org.drip.pricer.option.FokkerPlanckGenerator fpg = fraLeading.pricer();

  279.         org.drip.product.params.LastTradingDateSetting ltds = fraLeading.lastTradingDateSetting();

  280.         org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapStreamResult = _stream.value
  281.             (valParams, pricerParams, csqs, vcp);

  282.         if (null == mapStreamResult || !mapStreamResult.containsKey ("FairPremium"))
  283.             throw new java.lang.Exception
  284.                 ("FRAStandardCapFloor::atmPriceFromVolatility => Cannot calculate Fair Premium");

  285.         double dblCapATMFairPremium = mapStreamResult.get ("FairPremium");

  286.         org.drip.state.identifier.ForwardLabel forwardLabel = _stream.forwardLabel();

  287.         java.util.List<org.drip.product.fra.FRAStandardCapFloorlet> lsATMFRACapFloorlet = new
  288.             java.util.ArrayList<org.drip.product.fra.FRAStandardCapFloorlet>();

  289.         for (org.drip.analytics.cashflow.CompositePeriod period : _stream.periods()) {
  290.             org.drip.product.fra.FRAStandardComponent fra =
  291.                 org.drip.product.creator.SingleStreamComponentBuilder.FRAStandard (new
  292.                     org.drip.analytics.date.JulianDate (period.startDate()), forwardLabel,
  293.                         dblCapATMFairPremium);

  294.             lsATMFRACapFloorlet.add (new org.drip.product.fra.FRAStandardCapFloorlet (fra.name() + "::LET",
  295.                 fra, strManifestMeasure, _bIsCap, dblCapATMFairPremium, _stream.notional
  296.                     (period.startDate()), ltds, fpg, cashSettleParams()));
  297.         }

  298.         for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : lsATMFRACapFloorlet) {
  299.             org.drip.analytics.date.JulianDate dtExercise = fracfl.exerciseDate();

  300.             int iExerciseDate = dtExercise.julian();

  301.             if (iExerciseDate <= iValueDate) continue;

  302.             dblPrice += fracfl.price (valParams, pricerParams, csqs, vcp, dblFlatVolatility);
  303.         }

  304.         return dblPrice;
  305.     }

  306.     /**
  307.      * Imply the Flat Cap/Floor Volatility from the Calibration ATM Price
  308.      *
  309.      * @param valParams The Valuation Parameters
  310.      * @param pricerParams The Pricer Parameters
  311.      * @param csqs The Market Parameters
  312.      * @param vcp The Valuation Customization Parameters
  313.      * @param dblCalibPrice The Calibration Price
  314.      *
  315.      * @return The Cap/Floor Flat Volatility
  316.      *
  317.      * @throws java.lang.Exception Thrown if the Flat Volatility cannot be calculated
  318.      */

  319.     public double volatilityFromATMPrice (
  320.         final org.drip.param.valuation.ValuationParams valParams,
  321.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  322.         final org.drip.param.market.CurveSurfaceQuoteContainer csqs,
  323.         final org.drip.param.valuation.ValuationCustomizationParams vcp,
  324.         final double dblCalibPrice)
  325.         throws java.lang.Exception
  326.     {
  327.         if (null == valParams || !org.drip.numerical.common.NumberUtil.IsValid (dblCalibPrice))
  328.             throw new java.lang.Exception ("FRAStandardCapFloor::volatilityFromATMPrice => Invalid Inputs");

  329.         org.drip.function.definition.R1ToR1 funcVolPricer = new org.drip.function.definition.R1ToR1 (null) {
  330.             @Override public double evaluate (
  331.                 final double dblVolatility)
  332.                 throws java.lang.Exception
  333.             {
  334.                 return atmPriceFromVolatility (valParams, pricerParams, csqs, vcp, dblVolatility);
  335.             }
  336.         };

  337.         org.drip.function.r1tor1solver.FixedPointFinderOutput fpfo = (new
  338.             org.drip.function.r1tor1solver.FixedPointFinderBracketing (dblCalibPrice, funcVolPricer, null,
  339.                 org.drip.function.r1tor1solver.VariateIteratorPrimitive.BISECTION, false)).findRoot
  340.                     (org.drip.function.r1tor1solver.InitializationHeuristics.FromHardSearchEdges (0.0001,
  341.                         5.));

  342.         if (null == fpfo || !fpfo.containsRoot())
  343.             throw new java.lang.Exception
  344.                 ("FRAStandardCapFloor::volatilityFromATMPrice => Cannot imply Flat Vol");

  345.         return fpfo.getRoot();
  346.     }

  347.     /**
  348.      * Compute the Cap/Floor Price from the Flat Volatility
  349.      *
  350.      * @param valParams The Valuation Parameters
  351.      * @param pricerParams The Pricer Parameters
  352.      * @param csqs The Market Parameters
  353.      * @param vcp The Valuation Customization Parameters
  354.      * @param dblFlatVolatility The Flat Volatility
  355.      *
  356.      * @return The Cap/Floor Price
  357.      *
  358.      * @throws java.lang.Exception Thrown if the Price cannot be calculated
  359.      */

  360.     public double priceFromFlatVolatility (
  361.         final org.drip.param.valuation.ValuationParams valParams,
  362.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  363.         final org.drip.param.market.CurveSurfaceQuoteContainer csqs,
  364.         final org.drip.param.valuation.ValuationCustomizationParams vcp,
  365.         final double dblFlatVolatility)
  366.         throws java.lang.Exception
  367.     {
  368.         if (null == valParams || !org.drip.numerical.common.NumberUtil.IsValid (dblFlatVolatility))
  369.             throw new java.lang.Exception ("FRAStandardCapFloor::priceFromFlatVolatility => Invalid Inputs");

  370.         int iValueDate = valParams.valueDate();

  371.         double dblPrice = 0.;

  372.         for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : _lsFRACapFloorlet) {
  373.             org.drip.analytics.date.JulianDate dtExercise = fracfl.exerciseDate();

  374.             int iExerciseDate = dtExercise.julian();

  375.             if (iExerciseDate <= iValueDate) continue;

  376.             dblPrice += fracfl.price (valParams, pricerParams, csqs, vcp, dblFlatVolatility);
  377.         }

  378.         return dblPrice;
  379.     }

  380.     /**
  381.      * Imply the Flat Cap/Floor Volatility from the Calibration Price
  382.      *
  383.      * @param valParams The Valuation Parameters
  384.      * @param pricerParams The Pricer Parameters
  385.      * @param csqs The Market Parameters
  386.      * @param vcp The Valuation Customization Parameters
  387.      * @param dblCalibPrice The Calibration Price
  388.      *
  389.      * @return The Cap/Floor Flat Volatility
  390.      *
  391.      * @throws java.lang.Exception Thrown if the Price cannot be calculated
  392.      */

  393.     public double flatVolatilityFromPrice (
  394.         final org.drip.param.valuation.ValuationParams valParams,
  395.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  396.         final org.drip.param.market.CurveSurfaceQuoteContainer csqs,
  397.         final org.drip.param.valuation.ValuationCustomizationParams vcp,
  398.         final double dblCalibPrice)
  399.         throws java.lang.Exception
  400.     {
  401.         if (null == valParams || !org.drip.numerical.common.NumberUtil.IsValid (dblCalibPrice))
  402.             throw new java.lang.Exception ("FRAStandardCapFloor::flatVolatilityFromPrice => Invalid Inputs");

  403.         org.drip.function.definition.R1ToR1 funcVolPricer = new org.drip.function.definition.R1ToR1 (null) {
  404.             @Override public double evaluate (
  405.                 final double dblVolatility)
  406.                 throws java.lang.Exception
  407.             {
  408.                 return priceFromFlatVolatility (valParams, pricerParams, csqs, vcp, dblVolatility);
  409.             }
  410.         };

  411.         org.drip.function.r1tor1solver.FixedPointFinderOutput fpfo = (new
  412.             org.drip.function.r1tor1solver.FixedPointFinderBracketing (dblCalibPrice, funcVolPricer, null,
  413.                 org.drip.function.r1tor1solver.VariateIteratorPrimitive.BISECTION, false)).findRoot
  414.                     (org.drip.function.r1tor1solver.InitializationHeuristics.FromHardSearchEdges (0.0001,
  415.                         5.));

  416.         if (null == fpfo || !fpfo.containsRoot())
  417.             throw new java.lang.Exception
  418.                 ("FRAStandardCapFloor::flatVolatilityFromPrice => Cannot imply Flat Vol");

  419.         return fpfo.getRoot();
  420.     }

  421.     /**
  422.      * Strip the Piece-wise Constant Forward Rate Volatility of the Unmarked Segment of the Volatility Term
  423.      *  Structure
  424.      *
  425.      * @param valParams The Valuation Parameters
  426.      * @param pricerParams The pricer Parameters
  427.      * @param csqs The Market Parameters
  428.      * @param vcp The Valuation Customization Parameters
  429.      * @param dblCapVolatility The Flat Cap Volatility
  430.      * @param mapDateVol The Date/Volatility Map
  431.      *
  432.      * @return TRUE - The Forward Rate Volatility of the Unmarked Segment of the Volatility Term Structure
  433.      *  successfully implied
  434.      */

  435.     public boolean stripPiecewiseForwardVolatility (
  436.         final org.drip.param.valuation.ValuationParams valParams,
  437.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  438.         final org.drip.param.market.CurveSurfaceQuoteContainer csqs,
  439.         final org.drip.param.valuation.ValuationCustomizationParams vcp,
  440.         final double dblCapVolatility,
  441.         final java.util.Map<org.drip.analytics.date.JulianDate, java.lang.Double> mapDateVol)
  442.     {
  443.         if (null == valParams || null == mapDateVol) return false;

  444.         int iIndex = 0;
  445.         double dblPreceedingCapFloorletPV = 0.;
  446.         double dblCapPrice = java.lang.Double.NaN;
  447.         org.drip.function.r1tor1solver.FixedPointFinderOutput fpfo = null;

  448.         try {
  449.             dblCapPrice = priceFromFlatVolatility (valParams, pricerParams, csqs, vcp, dblCapVolatility);
  450.         } catch (java.lang.Exception e) {
  451.             e.printStackTrace();

  452.             return false;
  453.         }

  454.         final int iValueDate = valParams.valueDate();

  455.         final java.util.List<java.lang.Integer> lsCalibCapFloorletIndex = new
  456.             java.util.ArrayList<java.lang.Integer>();

  457.         for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : _lsFRACapFloorlet) {
  458.             org.drip.analytics.date.JulianDate dtExercise = fracfl.exerciseDate();

  459.             int iExerciseDate = dtExercise.julian();

  460.             if (iExerciseDate <= iValueDate) continue;

  461.             if (mapDateVol.containsKey (dtExercise)) {
  462.                 double dblExerciseVolatility = mapDateVol.get (dtExercise);

  463.                 org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapCapFloorlet =
  464.                     fracfl.valueFromSurfaceVariance (valParams, pricerParams, csqs, vcp,
  465.                         dblExerciseVolatility * dblExerciseVolatility * (iExerciseDate - iValueDate) /
  466.                             365.25);

  467.                 if (null == mapCapFloorlet || !mapCapFloorlet.containsKey ("Price")) return false;

  468.                 dblPreceedingCapFloorletPV += mapCapFloorlet.get ("Price");
  469.             } else
  470.                 lsCalibCapFloorletIndex.add (iIndex);

  471.             ++iIndex;
  472.         }

  473.         org.drip.function.definition.R1ToR1 funcVolPricer = new org.drip.function.definition.R1ToR1 (null) {
  474.             @Override public double evaluate (
  475.                 final double dblVolatility)
  476.                 throws java.lang.Exception
  477.             {
  478.                 int iIndex = 0;
  479.                 double dblSucceedingCapFloorletPV = 0.;

  480.                 for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : _lsFRACapFloorlet) {
  481.                     int iExerciseDate = fracfl.exerciseDate().julian();

  482.                     if (iExerciseDate <= iValueDate) continue;

  483.                     if (lsCalibCapFloorletIndex.contains (iIndex)) {
  484.                         java.util.Map<java.lang.String, java.lang.Double> mapOutput =
  485.                             fracfl.valueFromSurfaceVariance (valParams, pricerParams, csqs, vcp,
  486.                                 dblVolatility * dblVolatility * (iExerciseDate - iValueDate) / 365.25);
  487.    
  488.                         if (null == mapOutput || !mapOutput.containsKey ("Price"))
  489.                             throw new java.lang.Exception
  490.                                 ("FRAStandardCapFloor::implyVolatility => Cannot generate Calibration Measure");
  491.    
  492.                         dblSucceedingCapFloorletPV += mapOutput.get ("Price");
  493.                     }

  494.                     ++iIndex;
  495.                 }

  496.                 return dblSucceedingCapFloorletPV;
  497.             }
  498.         };

  499.         try {
  500.             fpfo = (new org.drip.function.r1tor1solver.FixedPointFinderBracketing (dblCapPrice -
  501.                 dblPreceedingCapFloorletPV, funcVolPricer, null,
  502.                     org.drip.function.r1tor1solver.VariateIteratorPrimitive.BISECTION, false)).findRoot
  503.                         (org.drip.function.r1tor1solver.InitializationHeuristics.FromHardSearchEdges (0.0001,
  504.                             5.));
  505.         } catch (java.lang.Exception e) {
  506.             e.printStackTrace();
  507.         }

  508.         if (null == fpfo || !fpfo.containsRoot()) return false;

  509.         double dblVolatility = fpfo.getRoot();

  510.         iIndex = 0;

  511.         for (org.drip.product.fra.FRAStandardCapFloorlet fracfl : _lsFRACapFloorlet) {
  512.             if (lsCalibCapFloorletIndex.contains (iIndex))
  513.                 mapDateVol.put (fracfl.exerciseDate(), dblVolatility);

  514.             ++iIndex;
  515.         }

  516.         return true;
  517.     }

  518.     @Override public org.drip.state.estimator.PredictorResponseWeightConstraint volatilityPRWC (
  519.         final org.drip.param.valuation.ValuationParams valParams,
  520.         final org.drip.param.pricer.CreditPricerParams pricerParams,
  521.         final org.drip.param.market.CurveSurfaceQuoteContainer csqs,
  522.         final org.drip.param.valuation.ValuationCustomizationParams vcp,
  523.         final org.drip.product.calib.ProductQuoteSet pqs)
  524.     {
  525.         if (null == pqs || null == valParams || !(pqs instanceof
  526.             org.drip.product.calib.VolatilityProductQuoteSet))
  527.             return null;

  528.         if (valParams.valueDate() > maturityDate().julian()) return null;

  529.         double dblOptionPV = 0.;
  530.         org.drip.product.calib.VolatilityProductQuoteSet vpqs =
  531.             (org.drip.product.calib.VolatilityProductQuoteSet) pqs;

  532.         if (!vpqs.containsOptionPV()) return null;

  533.         try {
  534.             dblOptionPV = vpqs.optionPV();
  535.         } catch (java.lang.Exception e) {
  536.             e.printStackTrace();

  537.             return null;
  538.         }

  539.         org.drip.state.estimator.PredictorResponseWeightConstraint prwc = new
  540.             org.drip.state.estimator.PredictorResponseWeightConstraint();

  541.         for (org.drip.product.fra.FRAStandardCapFloorlet frascf : _lsFRACapFloorlet) {
  542.             org.drip.state.estimator.PredictorResponseWeightConstraint prwcFRASCF = frascf.volatilityPRWC
  543.                 (valParams, pricerParams, csqs, vcp, pqs);

  544.             if (null == prwcFRASCF || !prwc.absorb (prwcFRASCF)) return null;
  545.         }

  546.         return !prwc.updateValue (dblOptionPV) || !prwc.updateDValueDManifestMeasure ("OptionPV", 1.) ? null
  547.             : prwc;
  548.     }
  549. }