MultiCurvePayerReceiverAnalysis.java

  1. package org.drip.sample.fixfloatoption;

  2. import java.util.*;

  3. import org.drip.analytics.date.*;
  4. import org.drip.analytics.support.*;
  5. import org.drip.function.r1tor1.FlatUnivariate;
  6. import org.drip.market.otc.*;
  7. import org.drip.param.creator.*;
  8. import org.drip.param.market.CurveSurfaceQuoteContainer;
  9. import org.drip.param.period.*;
  10. import org.drip.param.valuation.*;
  11. import org.drip.product.creator.*;
  12. import org.drip.product.definition.*;
  13. import org.drip.product.option.FixFloatEuropeanOption;
  14. import org.drip.product.params.LastTradingDateSetting;
  15. import org.drip.product.rates.*;
  16. import org.drip.service.env.EnvManager;
  17. import org.drip.spline.basis.PolynomialFunctionSetParams;
  18. import org.drip.spline.stretch.MultiSegmentSequenceBuilder;
  19. import org.drip.state.creator.*;
  20. import org.drip.state.discount.*;
  21. import org.drip.state.forward.ForwardCurve;
  22. import org.drip.state.identifier.*;

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

  26. /*!
  27.  * Copyright (C) 2019 Lakshmi Krishnamurthy
  28.  * Copyright (C) 2018 Lakshmi Krishnamurthy
  29.  * Copyright (C) 2017 Lakshmi Krishnamurthy
  30.  * Copyright (C) 2016 Lakshmi Krishnamurthy
  31.  * Copyright (C) 2015 Lakshmi Krishnamurthy
  32.  * Copyright (C) 2014 Lakshmi Krishnamurthy
  33.  *
  34.  *  This file is part of DROP, an open-source library targeting risk, transaction costs, exposure, margin
  35.  *      calculations, valuation adjustment, and portfolio construction within and across fixed income,
  36.  *      credit, commodity, equity, FX, and structured products.
  37.  *  
  38.  *      https://lakshmidrip.github.io/DROP/
  39.  *  
  40.  *  DROP is composed of three modules:
  41.  *  
  42.  *  - DROP Analytics Core - https://lakshmidrip.github.io/DROP-Analytics-Core/
  43.  *  - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
  44.  *  - DROP Numerical Core - https://lakshmidrip.github.io/DROP-Numerical-Core/
  45.  *
  46.  *  DROP Analytics Core implements libraries for the following:
  47.  *  - Fixed Income Analytics
  48.  *  - Asset Backed Analytics
  49.  *  - XVA Analytics
  50.  *  - Exposure and Margin Analytics
  51.  *
  52.  *  DROP Portfolio Core implements libraries for the following:
  53.  *  - Asset Allocation Analytics
  54.  *  - Transaction Cost Analytics
  55.  *
  56.  *  DROP Numerical Core implements libraries for the following:
  57.  *  - Statistical Learning
  58.  *  - Numerical Optimizer
  59.  *  - Spline Builder
  60.  *  - Algorithm Support
  61.  *
  62.  *  Documentation for DROP is Spread Over:
  63.  *
  64.  *  - Main                     => https://lakshmidrip.github.io/DROP/
  65.  *  - Wiki                     => https://github.com/lakshmiDRIP/DROP/wiki
  66.  *  - GitHub                   => https://github.com/lakshmiDRIP/DROP
  67.  *  - Repo Layout Taxonomy     => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
  68.  *  - Javadoc                  => https://lakshmidrip.github.io/DROP/Javadoc/index.html
  69.  *  - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
  70.  *  - Release Versions         => https://lakshmidrip.github.io/DROP/version.html
  71.  *  - Community Credits        => https://lakshmidrip.github.io/DROP/credits.html
  72.  *  - Issues Catalog           => https://github.com/lakshmiDRIP/DROP/issues
  73.  *  - JUnit                    => https://lakshmidrip.github.io/DROP/junit/index.html
  74.  *  - Jacoco                   => https://lakshmidrip.github.io/DROP/jacoco/index.html
  75.  *
  76.  *  Licensed under the Apache License, Version 2.0 (the "License");
  77.  *      you may not use this file except in compliance with the License.
  78.  *  
  79.  *  You may obtain a copy of the License at
  80.  *      http://www.apache.org/licenses/LICENSE-2.0
  81.  *  
  82.  *  Unless required by applicable law or agreed to in writing, software
  83.  *      distributed under the License is distributed on an "AS IS" BASIS,
  84.  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  85.  *  
  86.  *  See the License for the specific language governing permissions and
  87.  *      limitations under the License.
  88.  */

  89. /**
  90.  * <i>MultiCurvePayerReceiverAnalysis</i> contains the demonstration of the custom volatility-correlation
  91.  * analysis of Multi-Curve Receiver/Payer Fix-Float Swap European Option sample.
  92.  *  
  93.  * <br><br>
  94.  *  <ul>
  95.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/AnalyticsCore.md">Analytics Core Module</a></li>
  96.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics Library</a></li>
  97.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">Sample</a></li>
  98.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/fixfloatoption/README.md">Fix Float Swap European Option Analytics</a></li>
  99.  *  </ul>
  100.  * <br><br>
  101.  *
  102.  * @author Lakshmi Krishnamurthy
  103.  */

  104. public class MultiCurvePayerReceiverAnalysis {

  105.     private static final FixFloatComponent OTCFixFloat (
  106.         final JulianDate dtSpot,
  107.         final String strCurrency,
  108.         final String strMaturityTenor,
  109.         final double dblCoupon)
  110.     {
  111.         FixedFloatSwapConvention ffConv = IBORFixedFloatContainer.ConventionFromJurisdiction (
  112.             strCurrency,
  113.             "ALL",
  114.             strMaturityTenor,
  115.             "MAIN"
  116.         );

  117.         return ffConv.createFixFloatComponent (
  118.             dtSpot,
  119.             strMaturityTenor,
  120.             dblCoupon,
  121.             0.,
  122.             1.
  123.         );
  124.     }

  125.     private static final FloatFloatComponent OTCFloatFloat (
  126.         final JulianDate dtSpot,
  127.         final String strCurrency,
  128.         final String strDerivedTenor,
  129.         final String strMaturityTenor,
  130.         final double dblBasis)
  131.     {
  132.         FloatFloatSwapConvention ffConv = IBORFloatFloatContainer.ConventionFromJurisdiction (strCurrency);

  133.         return ffConv.createFloatFloatComponent (
  134.             dtSpot,
  135.             strDerivedTenor,
  136.             strMaturityTenor,
  137.             dblBasis,
  138.             1.
  139.         );
  140.     }

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

  146.     private static final CalibratableComponent[] DepositInstrumentsFromMaturityDays (
  147.         final JulianDate dtEffective,
  148.         final int[] aiDay,
  149.         final int iNumFutures,
  150.         final String strCurrency)
  151.         throws Exception
  152.     {
  153.         CalibratableComponent[] aCalibComp = new CalibratableComponent[aiDay.length + iNumFutures];

  154.         for (int i = 0; i < aiDay.length; ++i)
  155.             aCalibComp[i] = SingleStreamComponentBuilder.Deposit (
  156.                 dtEffective,
  157.                 dtEffective.addBusDays (
  158.                     aiDay[i],
  159.                     strCurrency
  160.                 ),
  161.                 ForwardLabel.Create (
  162.                     strCurrency,
  163.                     "3M"
  164.                 )
  165.             );

  166.         CalibratableComponent[] aEDF = SingleStreamComponentBuilder.ForwardRateFuturesPack (
  167.             dtEffective,
  168.             iNumFutures,
  169.             strCurrency
  170.         );

  171.         for (int i = aiDay.length; i < aiDay.length + iNumFutures; ++i)
  172.             aCalibComp[i] = aEDF[i - aiDay.length];

  173.         return aCalibComp;
  174.     }

  175.     /*
  176.      * Construct the Array of Swap Instruments from the given set of parameters
  177.      *
  178.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  179.      */

  180.     private static final CalibratableComponent[] SwapInstrumentsFromMaturityTenor (
  181.         final JulianDate dtSpot,
  182.         final String strCurrency,
  183.         final String[] astrMaturityTenor,
  184.         final double[] adblCoupon)
  185.         throws Exception
  186.     {
  187.         FixFloatComponent[] aIRS = new FixFloatComponent[astrMaturityTenor.length];

  188.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  189.             aIRS[i] = OTCFixFloat (
  190.                 dtSpot,
  191.                 strCurrency,
  192.                 astrMaturityTenor[i],
  193.                 adblCoupon[i]
  194.             );

  195.         return aIRS;
  196.     }

  197.     /*
  198.      * Construct the discount curve using the following steps:
  199.      *  - Construct the array of cash instruments and their quotes.
  200.      *  - Construct the array of swap instruments and their quotes.
  201.      *  - Construct a shape preserving and smoothing KLK Hyperbolic Spline from the cash/swap instruments.
  202.      *
  203.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  204.      */

  205.     private static final MergedDiscountForwardCurve MakeDC (
  206.         final JulianDate dtSpot,
  207.         final String strCurrency)
  208.         throws Exception
  209.     {
  210.         /*
  211.          * Construct the array of Deposit instruments and their quotes.
  212.          */

  213.         CalibratableComponent[] aDepositComp = DepositInstrumentsFromMaturityDays (
  214.             dtSpot,
  215.             new int[] {
  216.                 1, 2, 3, 7, 14, 21, 30, 60
  217.             },
  218.             0,
  219.             strCurrency
  220.         );

  221.         double[] adblDepositQuote = new double[] {
  222.             0.01200, 0.01200, 0.01200, 0.01450, 0.01550, 0.01600, 0.01660, 0.01850
  223.         };

  224.         String[] astrDepositManifestMeasure = new String[] {
  225.             "ForwardRate",
  226.             "ForwardRate",
  227.             "ForwardRate",
  228.             "ForwardRate",
  229.             "ForwardRate",
  230.             "ForwardRate",
  231.             "ForwardRate",
  232.             "ForwardRate"
  233.         };

  234.         /*
  235.          * Construct the array of Swap instruments and their quotes.
  236.          */

  237.         double[] adblSwapQuote = new double[] {
  238.             0.02604,    //  4Y
  239.             0.02808,    //  5Y
  240.             0.02983,    //  6Y
  241.             0.03136,    //  7Y
  242.             0.03268,    //  8Y
  243.             0.03383,    //  9Y
  244.             0.03488,    // 10Y
  245.             0.03583,    // 11Y
  246.             0.03668,    // 12Y
  247.             0.03833,    // 15Y
  248.             0.03854,    // 20Y
  249.             0.03672,    // 25Y
  250.             0.03510,    // 30Y
  251.             0.03266,    // 40Y
  252.             0.03145     // 50Y
  253.         };

  254.         String[] astrSwapManifestMeasure = new String[] {
  255.             "SwapRate",    //  4Y
  256.             "SwapRate",    //  5Y
  257.             "SwapRate",    //  6Y
  258.             "SwapRate",    //  7Y
  259.             "SwapRate",    //  8Y
  260.             "SwapRate",    //  9Y
  261.             "SwapRate",    // 10Y
  262.             "SwapRate",    // 11Y
  263.             "SwapRate",    // 12Y
  264.             "SwapRate",    // 15Y
  265.             "SwapRate",    // 20Y
  266.             "SwapRate",    // 25Y
  267.             "SwapRate",    // 30Y
  268.             "SwapRate",    // 40Y
  269.             "SwapRate"     // 50Y
  270.         };

  271.         CalibratableComponent[] aSwapComp = SwapInstrumentsFromMaturityTenor (
  272.             dtSpot,
  273.             strCurrency,
  274.             new java.lang.String[] {
  275.                 "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y", "40Y", "50Y"
  276.             },
  277.             adblSwapQuote
  278.         );

  279.         /*
  280.          * Construct a shape preserving and smoothing KLK Hyperbolic Spline from the cash/swap instruments.
  281.          */

  282.         return ScenarioDiscountCurveBuilder.CubicKLKHyperbolicDFRateShapePreserver (
  283.             "KLK_HYPERBOLIC_SHAPE_TEMPLATE",
  284.             new ValuationParams (
  285.                 dtSpot,
  286.                 dtSpot,
  287.                 "USD"
  288.             ),
  289.             aDepositComp,
  290.             adblDepositQuote,
  291.             astrDepositManifestMeasure,
  292.             aSwapComp,
  293.             adblSwapQuote,
  294.             astrSwapManifestMeasure,
  295.             false
  296.         );
  297.     }

  298.     /*
  299.      * Construct an array of float-float swaps from the corresponding reference (6M) and the derived legs.
  300.      *
  301.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  302.      */

  303.     private static final FloatFloatComponent[] MakexM6MBasisSwap (
  304.         final JulianDate dtSpot,
  305.         final String strCurrency,
  306.         final String[] astrMaturityTenor,
  307.         final int iTenorInMonths)
  308.         throws Exception
  309.     {
  310.         FloatFloatComponent[] aFFC = new FloatFloatComponent[astrMaturityTenor.length];

  311.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  312.             aFFC[i] = OTCFloatFloat (
  313.                 dtSpot,
  314.                 strCurrency,
  315.                 iTenorInMonths + "M",
  316.                 astrMaturityTenor[i],
  317.                 0.
  318.             );

  319.         return aFFC;
  320.     }

  321.     private static final ForwardCurve MakeFC (
  322.         final JulianDate dtSpot,
  323.         final String strCurrency,
  324.         final MergedDiscountForwardCurve dc,
  325.         final int iTenorInMonths,
  326.         final String[] astrxM6MFwdTenor,
  327.         final double[] adblxM6MBasisSwapQuote)
  328.         throws Exception
  329.     {
  330.         /*
  331.          * Construct the 6M-xM float-float basis swap.
  332.          */

  333.         FloatFloatComponent[] aFFC = MakexM6MBasisSwap (
  334.             dtSpot,
  335.             strCurrency,
  336.             astrxM6MFwdTenor,
  337.             iTenorInMonths
  338.         );

  339.         String strBasisTenor = iTenorInMonths + "M";

  340.         ValuationParams valParams = new ValuationParams (
  341.             dtSpot,
  342.             dtSpot,
  343.             strCurrency
  344.         );

  345.         /*
  346.          * Calculate the starting forward rate off of the discount curve.
  347.          */

  348.         double dblStartingFwd = dc.forward (
  349.             dtSpot.julian(),
  350.             dtSpot.addTenor (strBasisTenor).julian()
  351.         );

  352.         /*
  353.          * Set the discount curve based component market parameters.
  354.          */

  355.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  356.             dc,
  357.             null,
  358.             null,
  359.             null,
  360.             null,
  361.             null,
  362.             null
  363.         );

  364.         /*
  365.          * Construct the shape preserving forward curve off of Quartic Polynomial Basis Spline.
  366.          */

  367.         return ScenarioForwardCurveBuilder.ShapePreservingForwardCurve (
  368.             "QUARTIC_FWD" + strBasisTenor,
  369.             ForwardLabel.Create (
  370.                 strCurrency,
  371.                 strBasisTenor
  372.             ),
  373.             valParams,
  374.             null,
  375.             mktParams,
  376.             null,
  377.             MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  378.             new PolynomialFunctionSetParams (5),
  379.             aFFC,
  380.             "DerivedParBasisSpread",
  381.             adblxM6MBasisSwapQuote,
  382.             dblStartingFwd
  383.         );
  384.     }

  385.     private static final Map<String, ForwardCurve> MakeFC (
  386.         final JulianDate dt,
  387.         final String strCurrency,
  388.         final MergedDiscountForwardCurve dc)
  389.         throws Exception
  390.     {
  391.         Map<String, ForwardCurve> mapFC = new HashMap<String, ForwardCurve>();

  392.         /*
  393.          * Build and run the sampling for the 1M-6M Tenor Basis Swap from its instruments and quotes.
  394.          */

  395.         ForwardCurve fc1M = MakeFC (
  396.             dt,
  397.             strCurrency,
  398.             dc,
  399.             1,
  400.             new String[] {
  401.                 "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y"
  402.             },
  403.             new double[] {
  404.                 0.00551,    //  1Y
  405.                 0.00387,    //  2Y
  406.                 0.00298,    //  3Y
  407.                 0.00247,    //  4Y
  408.                 0.00211,    //  5Y
  409.                 0.00185,    //  6Y
  410.                 0.00165,    //  7Y
  411.                 0.00150,    //  8Y
  412.                 0.00137,    //  9Y
  413.                 0.00127,    // 10Y
  414.                 0.00119,    // 11Y
  415.                 0.00112,    // 12Y
  416.                 0.00096,    // 15Y
  417.                 0.00079,    // 20Y
  418.                 0.00069,    // 25Y
  419.                 0.00062     // 30Y
  420.                 }
  421.             );

  422.         mapFC.put (
  423.             "1M",
  424.             fc1M
  425.         );

  426.         /*
  427.          * Build and run the sampling for the 3M-6M Tenor Basis Swap from its instruments and quotes.
  428.          */

  429.         ForwardCurve fc3M = MakeFC (
  430.             dt,
  431.             strCurrency,
  432.             dc,
  433.             3,
  434.             new String[] {
  435.                 "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y"
  436.             },
  437.             new double[] {
  438.                 0.00186,    //  1Y
  439.                 0.00127,    //  2Y
  440.                 0.00097,    //  3Y
  441.                 0.00080,    //  4Y
  442.                 0.00067,    //  5Y
  443.                 0.00058,    //  6Y
  444.                 0.00051,    //  7Y
  445.                 0.00046,    //  8Y
  446.                 0.00042,    //  9Y
  447.                 0.00038,    // 10Y
  448.                 0.00035,    // 11Y
  449.                 0.00033,    // 12Y
  450.                 0.00028,    // 15Y
  451.                 0.00022,    // 20Y
  452.                 0.00020,    // 25Y
  453.                 0.00018     // 30Y
  454.                 }
  455.             );

  456.         mapFC.put (
  457.             "3M",
  458.             fc3M
  459.         );

  460.         /*
  461.          * Build and run the sampling for the 12M-6M Tenor Basis Swap from its instruments and quotes.
  462.          */

  463.         ForwardCurve fc12M = MakeFC (
  464.             dt,
  465.             strCurrency,
  466.             dc,
  467.             12,
  468.             new String[] {
  469.                 "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y",
  470.                 "35Y", "40Y" // Extrapolated
  471.             },
  472.             new double[] {
  473.                 -0.00212,    //  1Y
  474.                 -0.00152,    //  2Y
  475.                 -0.00117,    //  3Y
  476.                 -0.00097,    //  4Y
  477.                 -0.00082,    //  5Y
  478.                 -0.00072,    //  6Y
  479.                 -0.00063,    //  7Y
  480.                 -0.00057,    //  8Y
  481.                 -0.00051,    //  9Y
  482.                 -0.00047,    // 10Y
  483.                 -0.00044,    // 11Y
  484.                 -0.00041,    // 12Y
  485.                 -0.00035,    // 15Y
  486.                 -0.00028,    // 20Y
  487.                 -0.00025,    // 25Y
  488.                 -0.00022,    // 30Y
  489.                 -0.00022,    // 35Y Extrapolated
  490.                 -0.00022,    // 40Y Extrapolated
  491.                 }
  492.             );

  493.         mapFC.put (
  494.             "12M",
  495.             fc12M
  496.         );

  497.         return mapFC;
  498.     }

  499.     private static final FixFloatComponent CreateSTIR (
  500.         final JulianDate dtEffective,
  501.         final String strMaturityTenor,
  502.         final ForwardLabel fri,
  503.         final double dblCoupon,
  504.         final String strCurrency)
  505.         throws Exception
  506.     {
  507.         JulianDate dtMaturity = dtEffective.addTenor (strMaturityTenor);

  508.         int iTenorInMonths = Helper.TenorToMonths (fri.tenor());

  509.         UnitCouponAccrualSetting ucasFixed = new UnitCouponAccrualSetting (
  510.             2,
  511.             "Act/360",
  512.             false,
  513.             "Act/360",
  514.             false,
  515.             strCurrency,
  516.             true,
  517.             CompositePeriodBuilder.ACCRUAL_COMPOUNDING_RULE_GEOMETRIC
  518.         );

  519.         ComposableFloatingUnitSetting cfusFloating = new ComposableFloatingUnitSetting (
  520.             fri.tenor(),
  521.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  522.             null,
  523.             fri,
  524.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  525.             0.
  526.         );

  527.         ComposableFixedUnitSetting cfusFixed = new ComposableFixedUnitSetting (
  528.             "6M",
  529.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  530.             null,
  531.             dblCoupon,
  532.             0.,
  533.             strCurrency
  534.         );

  535.         CompositePeriodSetting cpsFloating = new CompositePeriodSetting (
  536.             12 / iTenorInMonths,
  537.             fri.tenor(),
  538.             strCurrency,
  539.             null,
  540.             -1.,
  541.             null,
  542.             null,
  543.             null,
  544.             null
  545.         );

  546.         CompositePeriodSetting cpsFixed = new CompositePeriodSetting (
  547.             2,
  548.             "6M",
  549.             strCurrency,
  550.             null,
  551.             1.,
  552.             null,
  553.             null,
  554.             null,
  555.             null
  556.         );

  557.         CashSettleParams csp = new CashSettleParams (
  558.             0,
  559.             strCurrency,
  560.             0
  561.         );

  562.         List<Integer> lsFixedStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  563.             dtEffective,
  564.             "6M",
  565.             strMaturityTenor,
  566.             null
  567.         );

  568.         List<Integer> lsFloatingStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  569.             dtEffective,
  570.             fri.tenor(),
  571.             strMaturityTenor,
  572.             null
  573.         );

  574.         Stream floatingStream = new Stream (
  575.             CompositePeriodBuilder.FloatingCompositeUnit (
  576.                 lsFloatingStreamEdgeDate,
  577.                 cpsFloating,
  578.                 cfusFloating
  579.             )
  580.         );

  581.         Stream fixedStream = new Stream (
  582.             CompositePeriodBuilder.FixedCompositeUnit (
  583.                 lsFixedStreamEdgeDate,
  584.                 cpsFixed,
  585.                 ucasFixed,
  586.                 cfusFixed
  587.             )
  588.         );

  589.         FixFloatComponent irs = new FixFloatComponent (
  590.             fixedStream,
  591.             floatingStream,
  592.             csp
  593.         );

  594.         irs.setPrimaryCode ("IRS." + dtMaturity.toString() + "." + strCurrency);

  595.         return irs;
  596.     }

  597.     private static final void VolCorrScenario (
  598.         final FixFloatComponent stir,
  599.         final ValuationParams valParams,
  600.         final CurveSurfaceQuoteContainer mktParams,
  601.         final double dblCustomMetricVolatility,
  602.         final double dblForwardVolatility,
  603.         final double dblFundingVolatility,
  604.         final double dblForwardFundingCorr)
  605.         throws Exception
  606.     {
  607.         String strManifestMeasure = "FairPremium";

  608.         ForwardLabel fri = stir.forwardLabel().get ("DERIVED");

  609.         FundingLabel fundingLabel = FundingLabel.Standard (fri.currency());

  610.         mktParams.setCustomVolatility (
  611.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  612.                 valParams.valueDate(),
  613.                 VolatilityLabel.Standard (CustomLabel.Standard (stir.name() + "_" + strManifestMeasure)),
  614.                 fri.currency(),
  615.                 dblCustomMetricVolatility
  616.             )
  617.         );

  618.         mktParams.setForwardVolatility (
  619.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  620.                 valParams.valueDate(),
  621.                 VolatilityLabel.Standard (fri),
  622.                 fri.currency(),
  623.                 dblForwardVolatility
  624.             )
  625.         );

  626.         mktParams.setFundingVolatility (
  627.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  628.                 valParams.valueDate(),
  629.                 VolatilityLabel.Standard (fundingLabel),
  630.                 fri.currency(),
  631.                 dblFundingVolatility
  632.             )
  633.         );

  634.         mktParams.setForwardFundingCorrelation (
  635.             fri,
  636.             fundingLabel,
  637.             new FlatUnivariate (dblForwardFundingCorr)
  638.         );

  639.         Map<String, Double> mapSTIROutput = stir.value (
  640.             valParams,
  641.             null,
  642.             mktParams,
  643.             null
  644.         );

  645.         double dblStrike = 1.01 * mapSTIROutput.get (strManifestMeasure);

  646.         FixFloatEuropeanOption stirReceiver = new FixFloatEuropeanOption (
  647.             stir.name() + "::RECEIVER_OPT",
  648.             stir,
  649.             strManifestMeasure,
  650.             true,
  651.             dblStrike,
  652.             1.,
  653.             new LastTradingDateSetting (
  654.                 LastTradingDateSetting.MID_CURVE_OPTION_QUARTERLY,
  655.                 "",
  656.                 Integer.MIN_VALUE
  657.             ),
  658.             null
  659.         );

  660.         FixFloatEuropeanOption stirPayer = new FixFloatEuropeanOption (
  661.             stir.name() + "::PAYER_OPT",
  662.             stir,
  663.             strManifestMeasure,
  664.             false,
  665.             dblStrike,
  666.             1.,
  667.             new LastTradingDateSetting (
  668.                 LastTradingDateSetting.MID_CURVE_OPTION_QUARTERLY,
  669.                 "",
  670.                 Integer.MIN_VALUE
  671.             ),
  672.             null
  673.         );

  674.         Map<String, Double> mapSTIRPayerOutput = stirPayer.value (
  675.             valParams,
  676.             null,
  677.             mktParams,
  678.             null
  679.         );

  680.         Map<String, Double> mapSTIRReceiverOutput = stirReceiver.value (
  681.             valParams,
  682.             null,
  683.             mktParams,
  684.             null
  685.         );

  686.         double dblATMSwapRate = mapSTIRPayerOutput.get ("ATMSwapRate");

  687.         double dblManifestMeasureIntrinsic = mapSTIRPayerOutput.get ("ManifestMeasureIntrinsic");

  688.         double dblManifestMeasureIntrinsicValue = mapSTIRPayerOutput.get ("ManifestMeasureIntrinsicValue");

  689.         double dblForwardPayerIntrinsic = mapSTIRPayerOutput.get ("ForwardIntrinsic");

  690.         double dblSpotPayerPrice = mapSTIRPayerOutput.get ("SpotPrice");

  691.         double dblForwardReceiverIntrinsic = mapSTIRReceiverOutput.get ("ForwardIntrinsic");

  692.         double dblSpotReceiverPrice = mapSTIRReceiverOutput.get ("SpotPrice");

  693.         System.out.println ("\t[" +
  694.             org.drip.numerical.common.FormatUtil.FormatDouble (dblCustomMetricVolatility, 2, 0, 100.) + "%," +
  695.             org.drip.numerical.common.FormatUtil.FormatDouble (dblForwardVolatility, 2, 0, 100.) + "%," +
  696.             org.drip.numerical.common.FormatUtil.FormatDouble (dblFundingVolatility, 2, 0, 100.) + "%," +
  697.             org.drip.numerical.common.FormatUtil.FormatDouble (dblForwardFundingCorr, 2, 0, 100.) + "%] =" +
  698.             org.drip.numerical.common.FormatUtil.FormatDouble (dblATMSwapRate, 1, 4, 100.) + "% | " +
  699.             org.drip.numerical.common.FormatUtil.FormatDouble (dblManifestMeasureIntrinsic, 1, 1, 10000.) + " | " +
  700.             org.drip.numerical.common.FormatUtil.FormatDouble (dblManifestMeasureIntrinsicValue, 1, 4, 1.) + " | " +
  701.             org.drip.numerical.common.FormatUtil.FormatDouble (dblForwardPayerIntrinsic, 1, 0, 10000.) + " | " +
  702.             org.drip.numerical.common.FormatUtil.FormatDouble (dblSpotPayerPrice, 1, 4, 1.) + " | " +
  703.             org.drip.numerical.common.FormatUtil.FormatDouble (dblForwardReceiverIntrinsic, 1, 0, 10000.) + " | " +
  704.             org.drip.numerical.common.FormatUtil.FormatDouble (dblSpotReceiverPrice, 1, 4, 1.));
  705.     }

  706.     public static final void main (
  707.         final String[] astrArgs)
  708.         throws Exception
  709.     {
  710.         /*
  711.          * Initialize the Credit Analytics Library
  712.          */

  713.         EnvManager.InitEnv ("");

  714.         String strTenor = "3M";
  715.         String strCurrency = "JPY";

  716.         JulianDate dtToday = DateUtil.Today().addTenorAndAdjust (
  717.             "0D",
  718.             strCurrency
  719.         );

  720.         /*
  721.          * Construct the Discount Curve using its instruments and quotes
  722.          */

  723.         MergedDiscountForwardCurve dc = MakeDC (
  724.             dtToday,
  725.             strCurrency
  726.         );

  727.         Map<String, ForwardCurve> mapFC = MakeFC (
  728.             dtToday,
  729.             strCurrency,
  730.             dc
  731.         );

  732.         ForwardLabel fri = ForwardLabel.Create (
  733.             strCurrency,
  734.             strTenor
  735.         );

  736.         JulianDate dtForward = dtToday.addTenor (strTenor);

  737.         FixFloatComponent stir = CreateSTIR (
  738.             dtForward,
  739.             "5Y",
  740.             fri,
  741.             0.05,
  742.             strCurrency
  743.         );

  744.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  745.             dc,
  746.             mapFC.get (strTenor),
  747.             null,
  748.             null,
  749.             null,
  750.             null,
  751.             null,
  752.             null
  753.         );

  754.         ValuationParams valParams = new ValuationParams (
  755.             dtToday,
  756.             dtToday,
  757.             strCurrency
  758.         );

  759.         double[] adblCustomMetricVolatility = new double[] {0.1, 0.5};
  760.         double[] adblForwardVolatility = new double[] {0.1, 0.2, 0.3, 0.4, 0.5};
  761.         double[] adblFundingVolatility = new double[] {0.10, 0.15, 0.20, 0.25, 0.30};
  762.         double[] adblForwardFundingCorr = new double[] {-0.99, -0.50, 0.00, 0.50, 0.99};

  763.         System.out.println ("\tPrinting the STIR Option Output in Order (Left -> Right):");

  764.         System.out.println ("\t\tATM Swap Rate(%)");

  765.         System.out.println ("\t\tOption Intrinsic (bp)");

  766.         System.out.println ("\t\tOption Intrinsic Value");

  767.         System.out.println ("\t\tForward Intrinsic Payer (bp)");

  768.         System.out.println ("\t\tSpot Payer STIR Option Price");

  769.         System.out.println ("\t\tForward Intrinsic Receiver (bp)");

  770.         System.out.println ("\t\tSpot Receiver STIR Option Price");

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

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

  773.         for (double dblCustomMetricVolatility : adblCustomMetricVolatility) {
  774.             for (double dblForwardVolatility : adblForwardVolatility) {
  775.                 for (double dblFundingVolatility : adblFundingVolatility) {
  776.                     for (double dblForwardFundingCorr : adblForwardFundingCorr)
  777.                         VolCorrScenario (
  778.                             stir,
  779.                             valParams,
  780.                             mktParams,
  781.                             dblCustomMetricVolatility,
  782.                             dblForwardVolatility,
  783.                             dblFundingVolatility,
  784.                             dblForwardFundingCorr
  785.                         );
  786.                 }
  787.             }
  788.         }

  789.         EnvManager.TerminateEnv();
  790.     }
  791. }