OvernightArithmeticCompoundingConvexity.java

  1. package org.drip.sample.ois;

  2. import java.util.*;

  3. import org.drip.analytics.cashflow.CompositePeriod;
  4. import org.drip.analytics.date.*;
  5. import org.drip.analytics.support.*;
  6. import org.drip.function.r1tor1.*;
  7. import org.drip.market.otc.*;
  8. import org.drip.numerical.common.FormatUtil;
  9. import org.drip.param.creator.*;
  10. import org.drip.param.market.*;
  11. import org.drip.param.period.*;
  12. import org.drip.param.valuation.*;
  13. import org.drip.product.creator.*;
  14. import org.drip.product.definition.CalibratableComponent;
  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.params.*;
  19. import org.drip.spline.stretch.*;
  20. import org.drip.state.creator.*;
  21. import org.drip.state.discount.*;
  22. import org.drip.state.estimator.LatentStateStretchBuilder;
  23. import org.drip.state.identifier.*;
  24. import org.drip.state.inference.*;

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

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

  72. /**
  73.  * OvernightArithmeticCompoundingConvexity contains an assessment of the impact of the Overnight Index
  74.  *  Volatility, the Funding Numeraire Volatility, and the ON Index/Funding Correlation on the Overnight
  75.  *  Floating Stream.
  76.  *
  77.  * @author Lakshmi Krishnamurthy
  78.  */

  79. public class OvernightArithmeticCompoundingConvexity {

  80.     private static final FixFloatComponent OTCOISFixFloat (
  81.         final JulianDate dtSpot,
  82.         final String strCurrency,
  83.         final String strMaturityTenor,
  84.         final double dblCoupon)
  85.     {
  86.         FixedFloatSwapConvention ffConv = OvernightFixedFloatContainer.FundConventionFromJurisdiction (
  87.             strCurrency
  88.         );

  89.         return ffConv.createFixFloatComponent (
  90.             dtSpot,
  91.             strMaturityTenor,
  92.             dblCoupon,
  93.             0.,
  94.             1.
  95.         );
  96.     }

  97.     /*
  98.      * Construct the Array of Deposit Instruments from the given set of parameters
  99.      *
  100.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  101.      */

  102.     private static final SingleStreamComponent[] DepositInstrumentsFromMaturityDays (
  103.         final JulianDate dtEffective,
  104.         final String strCurrency,
  105.         final int[] aiDay)
  106.         throws Exception
  107.     {
  108.         SingleStreamComponent[] aDeposit = new SingleStreamComponent[aiDay.length];

  109.         for (int i = 0; i < aiDay.length; ++i)
  110.             aDeposit[i] = SingleStreamComponentBuilder.Deposit (
  111.                 dtEffective,
  112.                 dtEffective.addBusDays (
  113.                     aiDay[i],
  114.                     strCurrency
  115.                 ),
  116.                 OvernightLabel.Create (
  117.                     strCurrency
  118.                 )
  119.             );

  120.         return aDeposit;
  121.     }

  122.     private static final FixFloatComponent[] OISFromMaturityTenor (
  123.         final JulianDate dtSpot,
  124.         final String strCurrency,
  125.         final String[] astrMaturityTenor,
  126.         final double[] adblCoupon)
  127.         throws Exception
  128.     {
  129.         FixFloatComponent[] aOIS = new FixFloatComponent[astrMaturityTenor.length];

  130.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  131.             aOIS[i] = OTCOISFixFloat (
  132.                 dtSpot,
  133.                 strCurrency,
  134.                 astrMaturityTenor[i],
  135.                 adblCoupon[i]
  136.             );

  137.         return aOIS;
  138.     }

  139.     private static final FixFloatComponent[] OISFuturesFromMaturityTenor (
  140.         final JulianDate dtSpot,
  141.         final String strCurrency,
  142.         final String[] astrStartTenor,
  143.         final String[] astrMaturityTenor,
  144.         final double[] adblCoupon)
  145.         throws Exception
  146.     {
  147.         FixFloatComponent[] aOISFutures = new FixFloatComponent[astrMaturityTenor.length];

  148.         for (int i = 0; i < astrMaturityTenor.length; ++i)
  149.             aOISFutures[i] = OTCOISFixFloat (
  150.                 dtSpot.addTenor (astrStartTenor[i]),
  151.                 strCurrency,
  152.                 astrMaturityTenor[i],
  153.                 adblCoupon[i]
  154.             );

  155.         return aOISFutures;
  156.     }

  157.     private static final MergedDiscountForwardCurve CustomOISCurveBuilderSample (
  158.         final JulianDate dtSpot,
  159.         final String strCurrency)
  160.         throws Exception
  161.     {
  162.         /*
  163.          * Construct the Array of Deposit Instruments and their Quotes from the given set of parameters
  164.          */

  165.         SingleStreamComponent[] aDepositComp = DepositInstrumentsFromMaturityDays (
  166.             dtSpot,
  167.             strCurrency,
  168.             new int[] {
  169.                 1, 2, 3
  170.             }
  171.         );

  172.         double[] adblDepositQuote = new double[] {
  173.             0.0004, 0.0004, 0.0004       // Deposit
  174.         };

  175.         /*
  176.          * Construct the Deposit Instrument Set Stretch Builder
  177.          */

  178.         LatentStateStretchSpec depositStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  179.             "   DEPOSIT   ",
  180.             aDepositComp,
  181.             "ForwardRate",
  182.             adblDepositQuote
  183.         );

  184.         /*
  185.          * Construct the Array of Short End OIS Instruments and their Quotes from the given set of parameters
  186.          */

  187.         double[] adblShortEndOISQuote = new double[] {
  188.             0.00070,    //   1W
  189.             0.00069,    //   2W
  190.             0.00078,    //   3W
  191.             0.00074     //   1M
  192.         };

  193.         CalibratableComponent[] aShortEndOISComp = OISFromMaturityTenor (
  194.             dtSpot,
  195.             strCurrency,
  196.             new java.lang.String[] {
  197.                 "1W", "2W", "3W", "1M"
  198.             },
  199.             adblShortEndOISQuote
  200.         );

  201.         /*
  202.          * Construct the Short End OIS Instrument Set Stretch Builder
  203.          */

  204.         LatentStateStretchSpec oisShortEndStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  205.             "SHORT END OIS",
  206.             aShortEndOISComp,
  207.             "SwapRate",
  208.             adblShortEndOISQuote
  209.         );

  210.         /*
  211.          * Construct the Array of OIS Futures Instruments and their Quotes from the given set of parameters
  212.          */

  213.         double[] adblOISFutureQuote = new double[] {
  214.              0.00046,    //   1M x 1M
  215.              0.00016,    //   2M x 1M
  216.             -0.00007,    //   3M x 1M
  217.             -0.00013,    //   4M x 1M
  218.             -0.00014     //   5M x 1M
  219.         };

  220.         CalibratableComponent[] aOISFutureComp = OISFuturesFromMaturityTenor (
  221.             dtSpot,
  222.             strCurrency,
  223.             new java.lang.String[] {
  224.                 "1M", "2M", "3M", "4M", "5M"
  225.             },
  226.             new java.lang.String[] {
  227.                 "1M", "1M", "1M", "1M", "1M"
  228.             },
  229.             adblOISFutureQuote
  230.         );

  231.         /*
  232.          * Construct the OIS Future Instrument Set Stretch Builder
  233.          */

  234.         LatentStateStretchSpec oisFutureStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  235.             " OIS FUTURE  ",
  236.             aOISFutureComp,
  237.             "SwapRate",
  238.             adblOISFutureQuote
  239.         );

  240.         /*
  241.          * Construct the Array of Long End OIS Instruments and their Quotes from the given set of parameters
  242.          */

  243.         double[] adblLongEndOISQuote = new double[] {
  244.             0.00002,    //  15M
  245.             0.00008,    //  18M
  246.             0.00021,    //  21M
  247.             0.00036,    //   2Y
  248.             0.00127,    //   3Y
  249.             0.00274,    //   4Y
  250.             0.00456,    //   5Y
  251.             0.00647,    //   6Y
  252.             0.00827,    //   7Y
  253.             0.00996,    //   8Y
  254.             0.01147,    //   9Y
  255.             0.01280,    //  10Y
  256.             0.01404,    //  11Y
  257.             0.01516,    //  12Y
  258.             0.01764,    //  15Y
  259.             0.01939,    //  20Y
  260.             0.02003,    //  25Y
  261.             0.02038     //  30Y
  262.         };

  263.         CalibratableComponent[] aLongEndOISComp = OISFromMaturityTenor (
  264.             dtSpot,
  265.             strCurrency,
  266.             new java.lang.String[] {
  267.                 "15M", "18M", "21M", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y"
  268.             },
  269.             adblLongEndOISQuote
  270.         );

  271.         /*
  272.          * Construct the Long End OIS Instrument Set Stretch Builder
  273.          */

  274.         LatentStateStretchSpec oisLongEndStretch = LatentStateStretchBuilder.ForwardFundingStretchSpec (
  275.             "LONG END OIS ",
  276.             aLongEndOISComp,
  277.             "SwapRate",
  278.             adblLongEndOISQuote
  279.         );

  280.         LatentStateStretchSpec[] aStretchSpec = new LatentStateStretchSpec[] {
  281.             depositStretch,
  282.             oisShortEndStretch,
  283.             oisFutureStretch,
  284.             oisLongEndStretch
  285.         };

  286.         /*
  287.          * Set up the Linear Curve Calibrator using the following parameters:
  288.          *  - Cubic Exponential Mixture Basis Spline Set
  289.          *  - Ck = 2, Segment Curvature Penalty = 2
  290.          *  - Quadratic Rational Shape Controller
  291.          *  - Natural Boundary Setting
  292.          */

  293.         LinearLatentStateCalibrator lcc = new LinearLatentStateCalibrator (
  294.             new SegmentCustomBuilderControl (
  295.                 MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
  296.                 new PolynomialFunctionSetParams (4),
  297.                 SegmentInelasticDesignControl.Create (
  298.                     2,
  299.                     2
  300.                 ),
  301.                 new ResponseScalingShapeControl (
  302.                     true,
  303.                     new QuadraticRationalShapeControl (0.)
  304.                 ),
  305.                 null
  306.             ),
  307.             BoundarySettings.NaturalStandard(),
  308.             MultiSegmentSequence.CALIBRATE,
  309.             null,
  310.             null
  311.         );

  312.         /*
  313.          * Construct the Shape Preserving Discount Curve by applying the linear curve calibrator to the array
  314.          *  of Cash and Swap Stretches.
  315.          */

  316.         return ScenarioDiscountCurveBuilder.ShapePreservingDFBuild (
  317.             strCurrency,
  318.             lcc,
  319.             aStretchSpec,
  320.             new ValuationParams (
  321.                 dtSpot,
  322.                 dtSpot,
  323.                 strCurrency
  324.             ),
  325.             null,
  326.             null,
  327.             null,
  328.             1.
  329.         );
  330.     }

  331.     private static final LatentStateFixingsContainer SetFlatOvernightFixings (
  332.         final JulianDate dtStart,
  333.         final JulianDate dtEnd,
  334.         final JulianDate dtValue,
  335.         final ForwardLabel fri,
  336.         final double dblFlatFixing,
  337.         final double dblNotional)
  338.         throws Exception
  339.     {
  340.         LatentStateFixingsContainer lsfc = new LatentStateFixingsContainer();

  341.         JulianDate dt = dtStart.addDays (1);

  342.         while (dt.julian() <= dtEnd.julian()) {
  343.             lsfc.add (
  344.                 dt,
  345.                 fri,
  346.                 dblFlatFixing
  347.             );

  348.             dt = dt.addBusDays (1, "USD");
  349.         }

  350.         return lsfc;
  351.     }

  352.     private static final void SetMarketParams (
  353.         final int iValueDate,
  354.         final CurveSurfaceQuoteContainer mktParams,
  355.         final String strCurrency,
  356.         final ForwardLabel fri,
  357.         final double dblOISVol,
  358.         final double dblUSDFundingVol,
  359.         final double dblUSDFundingUSDOISCorrelation)
  360.         throws Exception
  361.     {
  362.         FundingLabel fundingLabel = FundingLabel.Standard (strCurrency);

  363.         mktParams.setForwardVolatility (
  364.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  365.                 iValueDate,
  366.                 VolatilityLabel.Standard (fri),
  367.                 fri.currency(),
  368.                 dblOISVol
  369.             )
  370.         );

  371.         mktParams.setFundingVolatility (
  372.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  373.                 iValueDate,
  374.                 VolatilityLabel.Standard (fundingLabel),
  375.                 "USD",
  376.                 dblUSDFundingVol
  377.             )
  378.         );


  379.         mktParams.setForwardFundingCorrelation (
  380.             fri,
  381.             fundingLabel,
  382.             new FlatUnivariate (dblUSDFundingUSDOISCorrelation)
  383.         );
  384.     }

  385.     private static final void VolCorrScenario (
  386.         final Stream[] aFloatStream,
  387.         final String strCurrency,
  388.         final ForwardLabel fri,
  389.         final ValuationParams valParams,
  390.         final CurveSurfaceQuoteContainer mktParams,
  391.         final double dblOISVol,
  392.         final double dblUSDFundingVol,
  393.         final double dblUSDFundingUSDOISCorrelation)
  394.         throws Exception
  395.     {
  396.         SetMarketParams (
  397.             valParams.valueDate(),
  398.             mktParams,
  399.             strCurrency,
  400.             fri,
  401.             dblOISVol,
  402.             dblUSDFundingVol,
  403.             dblUSDFundingUSDOISCorrelation
  404.         );

  405.         String strDump = "\t[" +
  406.             FormatUtil.FormatDouble (dblOISVol, 2, 0, 100.) + "%," +
  407.             FormatUtil.FormatDouble (dblUSDFundingVol, 2, 0, 100.) + "%," +
  408.             FormatUtil.FormatDouble (dblUSDFundingUSDOISCorrelation, 2, 0, 100.) + "%] = ";

  409.         for (int i = 0; i < aFloatStream.length; ++i) {
  410.             Map<String, Double> mapValue = aFloatStream[i].value (
  411.                 valParams,
  412.                 null,
  413.                 mktParams,
  414.                 null
  415.             );

  416.             if (0 != i) strDump += " || ";

  417.             strDump +=
  418.                 FormatUtil.FormatDouble (mapValue.get ("UnadjustedFairPremium"), 1, 4, 100.) + "% | " +
  419.                 FormatUtil.FormatDouble (mapValue.get ("CompoundingAdjustmentFactor") - 1, 1, 2, 100.) + "% | " +
  420.                 FormatUtil.FormatDouble (mapValue.get ("CumulativeConvexityAdjustmentFactor") - 1, 1, 2, 100.) + "%";
  421.         }

  422.         System.out.println (strDump);
  423.     }

  424.     public static final void main (
  425.         final String[] astrArgs)
  426.         throws Exception
  427.     {
  428.         /*
  429.          * Initialize the Credit Analytics Library
  430.          */

  431.         EnvManager.InitEnv ("");

  432.         JulianDate dtToday = DateUtil.Today().addTenor ("0D");

  433.         String strCurrency = "USD";

  434.         MergedDiscountForwardCurve dc = CustomOISCurveBuilderSample (
  435.             dtToday,
  436.             strCurrency
  437.         );

  438.         JulianDate dtCustomOISStart = dtToday.subtractTenor ("2M");

  439.         JulianDate dtCustomOISMaturity = dtToday.addTenor ("4M");

  440.         ForwardLabel fri = OvernightLabel.Create (strCurrency);

  441.         ComposableFloatingUnitSetting cfusFloating = new ComposableFloatingUnitSetting (
  442.             "ON",
  443.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_OVERNIGHT,
  444.             null,
  445.             OvernightLabel.Create (
  446.                 strCurrency
  447.             ),
  448.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  449.             0.
  450.         );

  451.         CompositePeriodSetting cpsFloating = new CompositePeriodSetting (
  452.             360,
  453.             "ON",
  454.             strCurrency,
  455.             null,
  456.             -1.,
  457.             null,
  458.             null,
  459.             null,
  460.             null
  461.         );

  462.         List<Integer> lsFloatingStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  463.             dtCustomOISStart,
  464.             "6M",
  465.             "6M",
  466.             null
  467.         );

  468.         List<CompositePeriod> lsCP = CompositePeriodBuilder.FloatingCompositeUnit (
  469.             lsFloatingStreamEdgeDate,
  470.             cpsFloating,
  471.             cfusFloating
  472.         );

  473.         Stream floatStream = new Stream (lsCP);

  474.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  475.             dc,
  476.             null,
  477.             null,
  478.             null,
  479.             null,
  480.             null,
  481.             SetFlatOvernightFixings (
  482.                 dtCustomOISStart,
  483.                 dtCustomOISMaturity,
  484.                 dtToday,
  485.                 fri,
  486.                 0.003,
  487.                 -1.
  488.             )
  489.         );

  490.         ValuationParams valParams = new ValuationParams (
  491.             dtToday,
  492.             dtToday,
  493.             strCurrency
  494.         );

  495.         double[] adblOISVol = new double [] {
  496.             0.1, 0.3, 0.5
  497.         };
  498.         double[] adblUSDFundingVol = new double [] {
  499.             0.1, 0.3, 0.5
  500.         };
  501.         double[] adblUSDFundingUSDOISCorrelation = new double [] {
  502.             -0.3, 0.0, 0.3
  503.         };

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

  505.         System.out.println ("\tInput Order (LHS) L->R:");

  506.         System.out.println ("\t\tOIS Volatility, Funding Volatility, OIS/Funding Correlation\n");

  507.         System.out.println ("\tOutput Order (RHS) L->R:");

  508.         System.out.println ("\t\tUnadjusted Fair Premium, Compounding Adjustment Factor (% - Relative), Convexity Adjustment Factor (% - Relative)\n");

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

  510.         for (double dblOISVol : adblOISVol) {
  511.             for (double dblUSDFundingVol : adblUSDFundingVol) {
  512.                 for (double dblUSDFundingUSDOISCorrelation : adblUSDFundingUSDOISCorrelation)
  513.                     VolCorrScenario (
  514.                         new Stream[] {floatStream},
  515.                         strCurrency,
  516.                         fri,
  517.                         valParams,
  518.                         mktParams,
  519.                         dblOISVol,
  520.                         dblUSDFundingVol,
  521.                         dblUSDFundingUSDOISCorrelation
  522.                     );
  523.             }
  524.         }

  525.         System.out.println ("\t-------------------------------------------------------------------------------------");
  526.     }
  527. }