FRAStdCapMonteCarlo.java

  1. package org.drip.sample.capfloor;

  2. import java.util.*;

  3. import org.drip.analytics.date.JulianDate;
  4. import org.drip.analytics.definition.MarketSurface;
  5. import org.drip.analytics.support.CompositePeriodBuilder;
  6. import org.drip.dynamics.lmm.*;
  7. import org.drip.function.r1tor1.QuadraticRationalShapeControl;
  8. import org.drip.numerical.common.FormatUtil;
  9. import org.drip.param.creator.*;
  10. import org.drip.param.market.CurveSurfaceQuoteContainer;
  11. import org.drip.param.period.*;
  12. import org.drip.param.valuation.*;
  13. import org.drip.pricer.option.BlackScholesAlgorithm;
  14. import org.drip.product.creator.SingleStreamComponentBuilder;
  15. import org.drip.product.fra.*;
  16. import org.drip.product.params.LastTradingDateSetting;
  17. import org.drip.product.rates.*;
  18. import org.drip.sequence.random.*;
  19. import org.drip.service.env.EnvManager;
  20. import org.drip.spline.basis.PolynomialFunctionSetParams;
  21. import org.drip.spline.grid.OverlappingStretchSpan;
  22. import org.drip.spline.params.*;
  23. import org.drip.spline.stretch.*;
  24. import org.drip.state.creator.*;
  25. import org.drip.state.curve.BasisSplineForwardRate;
  26. import org.drip.state.discount.*;
  27. import org.drip.state.estimator.LatentStateStretchBuilder;
  28. import org.drip.state.forward.ForwardCurve;
  29. import org.drip.state.identifier.*;
  30. import org.drip.state.inference.*;

  31. /*
  32.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  33.  */

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

  107. /**
  108.  * <i>FRAStdCapMonteCarlo</i> demonstrates the steps associated with a LMM-Based Monte-Carlo pricing of a FRA
  109.  * Cap. The References are:
  110.  *
  111.  * <br><br>
  112.  *  <ul>
  113.  *      <li>
  114.  *          Brace, A., D. Gatarek, and M. Musiela (1997): The Market Model of Interest Rate Dynamics
  115.  *              <i>Mathematical Finance</i> <b>7 (2)</b> 127-155
  116.  *      </li>
  117.  *      <li>
  118.  *          Goldys, B., M. Musiela, and D. Sondermann (1994): <i>Log-normality of Rates and Term Structure
  119.  *              Models</i> <b>The University of New South Wales</b>
  120.  *      </li>
  121.  *      <li>
  122.  *          Musiela, M. (1994): <i>Nominal Annual Rates and Log-normal Volatility Structure</i> <b>The
  123.  *              University of New South Wales</b>
  124.  *      </li>
  125.  *  </ul>
  126.  *  
  127.  * <br><br>
  128.  *  <ul>
  129.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  130.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  131.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">DROP API Construction and Usage</a></li>
  132.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/capfloor/README.md">FRA Standard Cap Floor Valuation</a></li>
  133.  *  </ul>
  134.  * <br><br>
  135.  *
  136.  * @author Lakshmi Krishnamurthy
  137.  */

  138. public class FRAStdCapMonteCarlo {

  139.     /*
  140.      * Construct the Array of Deposit Instruments from the given set of parameters
  141.      *
  142.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  143.      */

  144.     private static final SingleStreamComponent[] DepositInstrumentsFromMaturityDays (
  145.         final JulianDate dtEffective,
  146.         final String strCurrency,
  147.         final int[] aiDay)
  148.         throws Exception
  149.     {
  150.         SingleStreamComponent[] aDeposit = new SingleStreamComponent[aiDay.length];

  151.         ComposableFloatingUnitSetting cfus = new ComposableFloatingUnitSetting (
  152.             "3M",
  153.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_SINGLE,
  154.             null,
  155.             ForwardLabel.Create (
  156.                 strCurrency,
  157.                 "3M"
  158.             ),
  159.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  160.             0.
  161.         );

  162.         CompositePeriodSetting cps = new CompositePeriodSetting (
  163.             4,
  164.             "3M",
  165.             strCurrency,
  166.             null,
  167.             1.,
  168.             null,
  169.             null,
  170.             null,
  171.             null
  172.         );

  173.         CashSettleParams csp = new CashSettleParams (
  174.             0,
  175.             strCurrency,
  176.             0
  177.         );

  178.         for (int i = 0; i < aiDay.length; ++i) {
  179.             aDeposit[i] = new SingleStreamComponent (
  180.                 "DEPOSIT_" + aiDay[i],
  181.                 new Stream (
  182.                     CompositePeriodBuilder.FloatingCompositeUnit (
  183.                         CompositePeriodBuilder.EdgePair (
  184.                             dtEffective,
  185.                             dtEffective.addBusDays (
  186.                                 aiDay[i],
  187.                                 strCurrency
  188.                             )
  189.                         ),
  190.                         cps,
  191.                         cfus
  192.                     )
  193.                 ),
  194.                 csp
  195.             );

  196.             aDeposit[i].setPrimaryCode (aiDay[i] + "D");
  197.         }

  198.         return aDeposit;
  199.     }

  200.     /*
  201.      * Construct the Swap Instrument from the given set of parameters
  202.      *
  203.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  204.      */

  205.     private static final FixFloatComponent SwapInstrumentFromMaturityTenor (
  206.         final JulianDate dtEffective,
  207.         final String strCurrency,
  208.         final double dblFixedCoupon,
  209.         final String strMaturityTenor)
  210.         throws Exception
  211.     {
  212.         UnitCouponAccrualSetting ucasFixed = new UnitCouponAccrualSetting (
  213.             4,
  214.             "Act/360",
  215.             false,
  216.             "Act/360",
  217.             false,
  218.             strCurrency,
  219.             true,
  220.             CompositePeriodBuilder.ACCRUAL_COMPOUNDING_RULE_GEOMETRIC
  221.         );

  222.         ComposableFloatingUnitSetting cfusFloating = new ComposableFloatingUnitSetting (
  223.             "3M",
  224.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  225.             null,
  226.             ForwardLabel.Create (
  227.                 strCurrency,
  228.                 "3M"
  229.             ),
  230.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  231.             0.
  232.         );

  233.         ComposableFixedUnitSetting cfusFixed = new ComposableFixedUnitSetting (
  234.             "3M",
  235.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  236.             null,
  237.             dblFixedCoupon,
  238.             0.,
  239.             strCurrency
  240.         );

  241.         CompositePeriodSetting cpsFloating = new CompositePeriodSetting (
  242.             4,
  243.             "3M",
  244.             strCurrency,
  245.             null,
  246.             -1.,
  247.             null,
  248.             null,
  249.             null,
  250.             null
  251.         );

  252.         CompositePeriodSetting cpsFixed = new CompositePeriodSetting (
  253.             4,
  254.             "3M",
  255.             strCurrency,
  256.             null,
  257.             1.,
  258.             null,
  259.             null,
  260.             null,
  261.             null
  262.         );

  263.         CashSettleParams csp = new CashSettleParams (
  264.             0,
  265.             strCurrency,
  266.             0
  267.         );

  268.         List<Integer> lsFixedStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  269.             dtEffective,
  270.             "3M",
  271.             strMaturityTenor,
  272.             null
  273.         );

  274.         List<Integer> lsFloatingStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  275.             dtEffective,
  276.             "3M",
  277.             strMaturityTenor,
  278.             null
  279.         );

  280.         Stream floatingStream = new Stream (
  281.             CompositePeriodBuilder.FloatingCompositeUnit (
  282.                 lsFloatingStreamEdgeDate,
  283.                 cpsFloating,
  284.                 cfusFloating
  285.             )
  286.         );

  287.         Stream fixedStream = new Stream (
  288.             CompositePeriodBuilder.FixedCompositeUnit (
  289.                 lsFixedStreamEdgeDate,
  290.                 cpsFixed,
  291.                 ucasFixed,
  292.                 cfusFixed
  293.             )
  294.         );

  295.         FixFloatComponent irs = new FixFloatComponent (
  296.             fixedStream,
  297.             floatingStream,
  298.             csp
  299.         );

  300.         irs.setPrimaryCode ("IRS." + strMaturityTenor + "." + strCurrency);

  301.         return irs;
  302.     }

  303.     /*
  304.      * Construct the Array of Swap Instruments from the given set of parameters
  305.      *
  306.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  307.      */

  308.     private static final FixFloatComponent[] SwapInstrumentsFromMaturityTenor (
  309.         final JulianDate dtEffective,
  310.         final String strCurrency,
  311.         final String[] astrMaturityTenor)
  312.         throws Exception
  313.     {
  314.         FixFloatComponent[] aIRS = new FixFloatComponent[astrMaturityTenor.length];

  315.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  316.             aIRS[i] = SwapInstrumentFromMaturityTenor (
  317.                 dtEffective,
  318.                 strCurrency,
  319.                 0.,
  320.                 astrMaturityTenor[i]
  321.             );

  322.         return aIRS;
  323.     }

  324.     /*
  325.      * This sample demonstrates discount curve calibration and input instrument calibration quote recovery.
  326.      *  It shows the following:
  327.      *  - Construct the Array of Cash/Swap Instruments and their Quotes from the given set of parameters.
  328.      *  - Construct the Cash/Swap Instrument Set Stretch Builder.
  329.      *  - Set up the Linear Curve Calibrator using the following parameters:
  330.      *      - Cubic Exponential Mixture Basis Spline Set
  331.      *      - Ck = 2, Segment Curvature Penalty = 2
  332.      *      - Quadratic Rational Shape Controller
  333.      *      - Natural Boundary Setting
  334.      *  - Construct the Shape Preserving Discount Curve by applying the linear curve calibrator to the array
  335.      *      of Cash and Swap Stretches.
  336.      *  - Cross-Comparison of the Cash/Swap Calibration Instrument "Rate" metric across the different curve
  337.      *      construction methodologies.
  338.      *
  339.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  340.      */

  341.     private static final MergedDiscountForwardCurve OTCInstrumentCurve (
  342.         final JulianDate dtSpot,
  343.         final String strCurrency)
  344.         throws Exception
  345.     {
  346.         /*
  347.          * Construct the Array of Deposit Instruments and their Quotes from the given set of parameters
  348.          */

  349.         SingleStreamComponent[] aDepositComp = DepositInstrumentsFromMaturityDays (
  350.             dtSpot,
  351.             strCurrency,
  352.             new int[] {
  353.                 1, 2, 7, 14, 30, 60
  354.             }
  355.         );

  356.         double[] adblDepositQuote = new double[] {
  357.             0.0013, 0.0017, 0.0017, 0.0018, 0.0020, 0.0023
  358.         };

  359.         /*
  360.          * Construct the Deposit Instrument Set Stretch Builder
  361.          */

  362.         LatentStateStretchSpec depositStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  363.             "DEPOSIT",
  364.             aDepositComp,
  365.             "ForwardRate",
  366.             adblDepositQuote
  367.         );

  368.         /*
  369.          * Construct the Array of EDF Instruments and their Quotes from the given set of parameters
  370.          */

  371.         SingleStreamComponent[] aEDFComp = SingleStreamComponentBuilder.ForwardRateFuturesPack (
  372.             dtSpot,
  373.             8,
  374.             strCurrency
  375.         );

  376.         double[] adblEDFQuote = new double[] {
  377.             0.0027, 0.0032, 0.0041, 0.0054, 0.0077, 0.0104, 0.0134, 0.0160
  378.         };

  379.         /*
  380.          * Construct the EDF Instrument Set Stretch Builder
  381.          */

  382.         LatentStateStretchSpec edfStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  383.             "EDF",
  384.             aEDFComp,
  385.             "ForwardRate",
  386.             adblEDFQuote
  387.         );

  388.         /*
  389.          * Construct the Array of Swap Instruments and their Quotes from the given set of parameters
  390.          */

  391.         FixFloatComponent[] aSwapComp = SwapInstrumentsFromMaturityTenor (
  392.             dtSpot,
  393.             strCurrency,
  394.             new java.lang.String[] {
  395.                 "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y", "40Y", "50Y"
  396.             }
  397.         );

  398.         double[] adblSwapQuote = new double[] {
  399.             0.0166, 0.0206, 0.0241, 0.0269, 0.0292, 0.0311, 0.0326, 0.0340, 0.0351, 0.0375, 0.0393, 0.0402, 0.0407, 0.0409, 0.0409
  400.         };

  401.         /*
  402.          * Construct the Swap Instrument Set Stretch Builder
  403.          */

  404.         LatentStateStretchSpec swapStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  405.             "SWAP",
  406.             aSwapComp,
  407.             "SwapRate",
  408.             adblSwapQuote
  409.         );

  410.         LatentStateStretchSpec[] aStretchSpec = new LatentStateStretchSpec[] {
  411.             depositStretch,
  412.             edfStretch,
  413.             swapStretch
  414.         };

  415.         /*
  416.          * Set up the Linear Curve Calibrator using the following parameters:
  417.          *  - Cubic Exponential Mixture Basis Spline Set
  418.          *  - Ck = 2, Segment Curvature Penalty = 2
  419.          *  - Quadratic Rational Shape Controller
  420.          *  - Natural Boundary Setting
  421.          */

  422.         LinearLatentStateCalibrator lcc = new LinearLatentStateCalibrator (
  423.             new SegmentCustomBuilderControl (
  424.                 MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  425.                 new PolynomialFunctionSetParams (4),
  426.                 SegmentInelasticDesignControl.Create (
  427.                     2,
  428.                     2
  429.                 ),
  430.                 new ResponseScalingShapeControl (
  431.                     true,
  432.                     new QuadraticRationalShapeControl (0.)
  433.                 ),
  434.                 null
  435.             ),
  436.             BoundarySettings.NaturalStandard(),
  437.             MultiSegmentSequence.CALIBRATE,
  438.             null,
  439.             null
  440.         );

  441.         ValuationParams valParams = new ValuationParams (
  442.             dtSpot,
  443.             dtSpot,
  444.             strCurrency
  445.         );

  446.         /*
  447.          * Construct the Shape Preserving Discount Curve by applying the linear curve calibrator to the array
  448.          *  of Deposit, Futures, and Swap Stretches.
  449.          */

  450.         MergedDiscountForwardCurve dc = ScenarioDiscountCurveBuilder.ShapePreservingDFBuild (
  451.             strCurrency,
  452.             lcc,
  453.             aStretchSpec,
  454.             valParams,
  455.             null,
  456.             null,
  457.             null,
  458.             1.
  459.         );

  460.         CurveSurfaceQuoteContainer csqs = MarketParamsBuilder.Create (
  461.             dc,
  462.             null,
  463.             null,
  464.             null,
  465.             null,
  466.             null,
  467.             null
  468.         );

  469.         /*
  470.          * Cross-Comparison of the Deposit Calibration Instrument "Rate" metric across the different curve
  471.          *  construction methodologies.
  472.          */

  473.         System.out.println ("\n\t----------------------------------------------------------------");

  474.         System.out.println ("\t     DEPOSIT INSTRUMENTS CALIBRATION RECOVERY");

  475.         System.out.println ("\t----------------------------------------------------------------");

  476.         for (int i = 0; i < aDepositComp.length; ++i)
  477.             System.out.println ("\t[" + aDepositComp[i].maturityDate() + "] = " +
  478.                 FormatUtil.FormatDouble (aDepositComp[i].measureValue (valParams, null, csqs,
  479.                     null, "Rate"), 1, 6, 1.) + " | " + FormatUtil.FormatDouble (adblDepositQuote[i], 1, 6, 1.));

  480.         /*
  481.          * Cross-Comparison of the EDF Calibration Instrument "Rate" metric across the different curve
  482.          *  construction methodologies.
  483.          */

  484.         System.out.println ("\n\t----------------------------------------------------------------");

  485.         System.out.println ("\t     EDF INSTRUMENTS CALIBRATION RECOVERY");

  486.         System.out.println ("\t----------------------------------------------------------------");

  487.         for (int i = 0; i < aEDFComp.length; ++i)
  488.             System.out.println ("\t[" + aEDFComp[i].maturityDate() + "] = " +
  489.                 FormatUtil.FormatDouble (aEDFComp[i].measureValue (valParams, null, csqs, null, "Rate"), 1, 6, 1.)
  490.                     + " | " + FormatUtil.FormatDouble (adblEDFQuote[i], 1, 6, 1.));

  491.         /*
  492.          * Cross-Comparison of the Swap Calibration Instrument "Rate" metric across the different curve
  493.          *  construction methodologies.
  494.          */

  495.         System.out.println ("\n\t----------------------------------------------------------------");

  496.         System.out.println ("\t     SWAP INSTRUMENTS CALIBRATION RECOVERY");

  497.         System.out.println ("\t----------------------------------------------------------------");

  498.         for (int i = 0; i < aSwapComp.length; ++i)
  499.             System.out.println ("\t[" + aSwapComp[i].maturityDate() + "] = " +
  500.                 FormatUtil.FormatDouble (aSwapComp[i].measureValue (valParams, null, csqs, null, "CalibSwapRate"), 1, 6, 1.)
  501.                     + " | " + FormatUtil.FormatDouble (adblSwapQuote[i], 1, 6, 1.) + " | " +
  502.                         FormatUtil.FormatDouble (aSwapComp[i].measureValue (valParams, null, csqs, null, "FairPremium"), 1, 6, 1.));

  503.         return dc;
  504.     }

  505.     private static final ForwardCurve LIBORSpan (
  506.         final MergedDiscountForwardCurve dc,
  507.         final ForwardLabel forwardLabel,
  508.         final SegmentCustomBuilderControl scbc,
  509.         final JulianDate dtView,
  510.         final int iNumForwardTenor)
  511.         throws Exception
  512.     {
  513.         double[] adblDate = new double[iNumForwardTenor + 1];
  514.         double[] adblLIBOR = new double[iNumForwardTenor + 1];
  515.         SegmentCustomBuilderControl[] aSCBC = new SegmentCustomBuilderControl[iNumForwardTenor];

  516.         JulianDate dtForward = dtView.subtractTenor (forwardLabel.tenor());

  517.         for (int i = 0; i <= iNumForwardTenor; ++i) {
  518.             if (iNumForwardTenor != i) aSCBC[i] = scbc;

  519.             adblDate[i] = dtForward.julian();

  520.             adblLIBOR[i] = dc.libor (dtForward, forwardLabel.tenor());

  521.             dtForward = dtForward.addTenor (forwardLabel.tenor());
  522.         }

  523.         return new BasisSplineForwardRate (
  524.             forwardLabel,
  525.             new OverlappingStretchSpan (
  526.                 MultiSegmentSequenceBuilder.CreateCalibratedStretchEstimator (
  527.                     "SPOT_QM_LIBOR",
  528.                     adblDate,
  529.                     adblLIBOR,
  530.                     aSCBC,
  531.                     null,
  532.                     BoundarySettings.NaturalStandard(),
  533.                     MultiSegmentSequence.CALIBRATE
  534.                 )
  535.             )
  536.         );
  537.     }

  538.     private static final MarketSurface FlatVolatilitySurface (
  539.         final JulianDate dtStart,
  540.         final String strCurrency,
  541.         final double dblFlatVol)
  542.         throws Exception
  543.     {
  544.         return ScenarioMarketSurfaceBuilder.CustomSplineWireSurface (
  545.             "VIEW_TARGET_VOLATILITY_SURFACE",
  546.             dtStart,
  547.             strCurrency,
  548.             new double[] {
  549.                 dtStart.julian(),
  550.                 dtStart.addYears (2).julian(),
  551.                 dtStart.addYears (4).julian(),
  552.                 dtStart.addYears (6).julian(),
  553.                 dtStart.addYears (8).julian(),
  554.                 dtStart.addYears (10).julian()
  555.             },
  556.             new double[] {
  557.                 dtStart.julian(),
  558.                 dtStart.addYears (2).julian(),
  559.                 dtStart.addYears (4).julian(),
  560.                 dtStart.addYears (6).julian(),
  561.                 dtStart.addYears (8).julian(),
  562.                 dtStart.addYears (10).julian()
  563.             },
  564.             new double[][] {
  565.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  566.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  567.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  568.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  569.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  570.                 {dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol, dblFlatVol},
  571.             },
  572.             new SegmentCustomBuilderControl (
  573.                 MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  574.                 new PolynomialFunctionSetParams (4),
  575.                 SegmentInelasticDesignControl.Create (
  576.                     2,
  577.                     2
  578.                 ),
  579.                 null,
  580.                 null
  581.             ),
  582.             new SegmentCustomBuilderControl (
  583.                 MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  584.                 new PolynomialFunctionSetParams (4),
  585.                 SegmentInelasticDesignControl.Create (
  586.                     2,
  587.                     2
  588.                 ),
  589.                 null,
  590.                 null
  591.             )
  592.         );
  593.     }

  594.     private static final LognormalLIBORVolatility LLVInstance (
  595.         final int iSpotDate,
  596.         final ForwardLabel forwardLabel,
  597.         final MarketSurface[] aMS,
  598.         final double[][] aadblCorrelation,
  599.         final int iNumFactor)
  600.         throws Exception
  601.     {
  602.         UnivariateSequenceGenerator[] aUSG = new UnivariateSequenceGenerator[aMS.length];

  603.         for (int i = 0; i < aUSG.length; ++i)
  604.             aUSG[i] = new BoxMullerGaussian (
  605.                 0.,
  606.                 1.
  607.             );

  608.         return new LognormalLIBORVolatility (
  609.             iSpotDate,
  610.             forwardLabel,
  611.             aMS,
  612.             new PrincipalFactorSequenceGenerator (
  613.                 aUSG,
  614.                 aadblCorrelation,
  615.                 iNumFactor
  616.             )
  617.         );
  618.     }

  619.     public static final void main (
  620.         final String[] astrArgs)
  621.         throws Exception
  622.     {
  623.         EnvManager.InitEnv ("");

  624.         String strForwardTenor = "3M";
  625.         String strViewTenor = "6M";
  626.         String strSimulationTenor = "6M";
  627.         String strMaturityTenor = "5Y";
  628.         String strCurrency = "USD";
  629.         double dblFlatVol1 = 0.35;
  630.         double dblFlatVol2 = 0.42;
  631.         double dblFlatVol3 = 0.27;
  632.         int iNumForwardTenor = 30;
  633.         int iNumFactor = 2;
  634.         int iNumRun = 100;
  635.         double dblStrike = 0.02;
  636.         String strManifestMeasure = "ParForward";

  637.         double[][] aadblCorrelation = new double[][] {
  638.             {1.0, 0.1, 0.2},
  639.             {0.1, 1.0, 0.2},
  640.             {0.2, 0.1, 1.0}
  641.         };

  642.         SegmentCustomBuilderControl scbc = new SegmentCustomBuilderControl (
  643.             MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  644.             new PolynomialFunctionSetParams (4),
  645.             SegmentInelasticDesignControl.Create (
  646.                 2,
  647.                 2
  648.             ),
  649.             new ResponseScalingShapeControl (
  650.                 true,
  651.                 new QuadraticRationalShapeControl (1.)
  652.             ),
  653.             null
  654.         );

  655.         JulianDate dtSpot = org.drip.analytics.date.DateUtil.Today();

  656.         MarketSurface[] aMS = new MarketSurface[] {
  657.             FlatVolatilitySurface (
  658.                 dtSpot,
  659.                 strCurrency,
  660.                 dblFlatVol1
  661.             ),
  662.             FlatVolatilitySurface (
  663.                 dtSpot,
  664.                 strCurrency,
  665.                 dblFlatVol2
  666.             ),
  667.             FlatVolatilitySurface (
  668.                 dtSpot,
  669.                 strCurrency,
  670.                 dblFlatVol3
  671.             )
  672.         };

  673.         FundingLabel fundingLabel = FundingLabel.Standard (
  674.             strCurrency
  675.         );

  676.         ForwardLabel forwardLabel = ForwardLabel.Create (
  677.             strCurrency,
  678.             strForwardTenor
  679.         );

  680.         JulianDate dtView = dtSpot.addTenor (
  681.             strViewTenor
  682.         );

  683.         JulianDate dtSimulationEnd = dtSpot.addTenor (
  684.             strSimulationTenor
  685.         );

  686.         MergedDiscountForwardCurve dc = OTCInstrumentCurve (
  687.             dtSpot,
  688.             strCurrency
  689.         );

  690.         ForwardCurve fc = LIBORSpan (
  691.             dc,
  692.             forwardLabel,
  693.             scbc,
  694.             dtView,
  695.             iNumForwardTenor
  696.         );

  697.         LognormalLIBORCurveEvolver llce = LognormalLIBORCurveEvolver.Create (
  698.             fundingLabel,
  699.             forwardLabel,
  700.             iNumForwardTenor,
  701.             scbc
  702.         );

  703.         BGMCurveUpdate bgmInitial = BGMCurveUpdate.Create (
  704.             fundingLabel,
  705.             forwardLabel,
  706.             dtSpot.julian(),
  707.             dtSpot.julian(),
  708.             fc,
  709.             null,
  710.             dc,
  711.             null,
  712.             null,
  713.             null,
  714.             null,
  715.             null,
  716.             LLVInstance (
  717.                 dtSpot.julian(),
  718.                 forwardLabel,
  719.                 aMS,
  720.                 aadblCorrelation,
  721.                 iNumFactor
  722.             )
  723.         );

  724.         ForwardCurve[] aFCLIBOR = llce.simulateTerminalLatentState (
  725.             dtSpot.julian(),
  726.             dtSimulationEnd.julian(),
  727.             1,
  728.             dtView.julian(),
  729.             bgmInitial,
  730.             iNumRun
  731.         );

  732.         ComposableFloatingUnitSetting cfus = new ComposableFloatingUnitSetting (
  733.             strForwardTenor,
  734.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_SINGLE,
  735.             null,
  736.             forwardLabel,
  737.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  738.             0.
  739.         );

  740.         CompositePeriodSetting cps = new CompositePeriodSetting (
  741.             4,
  742.             strForwardTenor,
  743.             strCurrency,
  744.             null,
  745.             1.,
  746.             null,
  747.             null,
  748.             null,
  749.             null
  750.         );

  751.         Stream floatStream = new Stream (
  752.             CompositePeriodBuilder.FloatingCompositeUnit (
  753.                 CompositePeriodBuilder.RegularEdgeDates (
  754.                     dtView.julian(),
  755.                     strForwardTenor,
  756.                     strMaturityTenor,
  757.                     null
  758.                 ),
  759.                 cps,
  760.                 cfus
  761.             )
  762.         );

  763.         FRAStandardCapFloor fraCap = new FRAStandardCapFloor (
  764.             "FRA_CAP",
  765.             floatStream,
  766.             strManifestMeasure,
  767.             true,
  768.             dblStrike,
  769.             new LastTradingDateSetting (
  770.                 LastTradingDateSetting.MID_CURVE_OPTION_QUARTERLY,
  771.                 "",
  772.                 Integer.MIN_VALUE
  773.             ),
  774.             null,
  775.             new BlackScholesAlgorithm()
  776.         );

  777.         List<FRAStandardCapFloorlet> lsCapFloorlet = fraCap.capFloorlets();

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

  779.         System.out.println ("\t||           DATES           => CAP LEEFT | FLR LFT ||");

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

  781.         ValuationParams valParamsEnd = new ValuationParams (
  782.             dtSimulationEnd,
  783.             dtSimulationEnd,
  784.             strCurrency
  785.         );

  786.         double dblCapLift = 0.;
  787.         double dblFloorLift = 0.;

  788.         for (int i = 0; i < iNumRun; ++i) {
  789.             CurveSurfaceQuoteContainer csqsScen = MarketParamsBuilder.DiscountForward (
  790.                 dc,
  791.                 aFCLIBOR[i]
  792.             );

  793.             for (FRAStandardCapFloorlet fraCaplet : lsCapFloorlet) {
  794.                 FRAStandardComponent fra = fraCaplet.fra();

  795.                 Map<String, Double> mapScenFRAOutput = fra.value (
  796.                     valParamsEnd,
  797.                     null,
  798.                     csqsScen,
  799.                     null
  800.                 );

  801.                 double dblScenarioCapLift = mapScenFRAOutput.get ("CapLift");

  802.                 double dblScenarioFloorLift = mapScenFRAOutput.get ("FloorLift");

  803.                 dblCapLift += dblScenarioCapLift;
  804.                 dblFloorLift += dblScenarioFloorLift;

  805.                 System.out.println ("\t|| [" +
  806.                     fra.effectiveDate() + " - " + fra.maturityDate() + "] => " +
  807.                     FormatUtil.FormatDouble (dblScenarioCapLift, 1, 5, 1.) + " | " +
  808.                     FormatUtil.FormatDouble (dblScenarioFloorLift, 1, 5, 1.) + " ||"
  809.                 );
  810.             }
  811.         }

  812.         dblCapLift = dblCapLift / iNumRun;
  813.         dblFloorLift = dblFloorLift / iNumRun;

  814.         double dblTermnalDF = dc.df (dtSimulationEnd);

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

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

  817.         System.out.println ("\t\t|| Cap Lift   : " + FormatUtil.FormatDouble (dblCapLift, 1, 5, 1.) + " ||");

  818.         System.out.println ("\t\t|| Floor Lift : " + FormatUtil.FormatDouble (dblFloorLift, 1, 5, 1.) + " ||");

  819.         System.out.println ("\t\t|| Cap PV     : " + FormatUtil.FormatDouble (dblCapLift * dblTermnalDF, 1, 5, 1.) + " ||");

  820.         System.out.println ("\t\t|| Floor PV   : " + FormatUtil.FormatDouble (dblFloorLift * dblTermnalDF, 1, 5, 1.) + " ||");

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

  822.         EnvManager.TerminateEnv();
  823.     }
  824. }