SWPMOIS.java

  1. package org.drip.sample.bloomberg;

  2. import org.drip.analytics.cashflow.*;
  3. import org.drip.analytics.date.*;
  4. import org.drip.analytics.support.*;
  5. import org.drip.market.otc.*;
  6. import org.drip.numerical.common.FormatUtil;
  7. import org.drip.param.creator.*;
  8. import org.drip.param.market.*;
  9. import org.drip.param.valuation.*;
  10. import org.drip.product.creator.*;
  11. import org.drip.product.definition.*;
  12. import org.drip.product.rates.*;
  13. import org.drip.service.env.EnvManager;
  14. import org.drip.state.creator.ScenarioDiscountCurveBuilder;
  15. import org.drip.state.discount.MergedDiscountForwardCurve;
  16. import org.drip.state.identifier.ForwardLabel;

  17. /*
  18.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  19.  */

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

  95. /**
  96.  * <i>SWPMOIS</i> contains the sample demonstrating the replication of Bloomberg's SWPM OIS functionality.
  97.  *  
  98.  * <br><br>
  99.  *  <ul>
  100.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  101.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  102.  *      <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>
  103.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/bloomberg/README.md">Bloomberg CDSO CDSW SWPM YAS</a></li>
  104.  *  </ul>
  105.  * <br><br>
  106.  *
  107.  * @author Lakshmi Krishnamurthy
  108.  */

  109. public class SWPMOIS {
  110.     private static final String FIELD_SEPARATOR = "    ";

  111.     /*
  112.      * Construct the Array of Deposit Instruments from the given set of parameters
  113.      *
  114.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  115.      */

  116.     private static final CalibratableComponent[] DepositInstrumentsFromMaturityDays (
  117.         final JulianDate dtEffective,
  118.         final int[] aiDay,
  119.         final int iNumFuture,
  120.         final String strCurrency)
  121.         throws Exception
  122.     {
  123.         CalibratableComponent[] aCalibComp = new CalibratableComponent[aiDay.length + iNumFuture];

  124.         for (int i = 0; i < aiDay.length; ++i)
  125.             aCalibComp[i] = SingleStreamComponentBuilder.Deposit (
  126.                 dtEffective,
  127.                 dtEffective.addBusDays (
  128.                     aiDay[i],
  129.                     strCurrency
  130.                 ),
  131.                 ForwardLabel.Create (
  132.                     strCurrency,
  133.                     aiDay[i] + "D"
  134.                 )
  135.             );

  136.         CalibratableComponent[] aEDF = SingleStreamComponentBuilder.ForwardRateFuturesPack (
  137.             dtEffective,
  138.             iNumFuture,
  139.             strCurrency
  140.         );

  141.         for (int i = aiDay.length; i < aiDay.length + iNumFuture; ++i)
  142.             aCalibComp[i] = aEDF[i - aiDay.length];

  143.         return aCalibComp;
  144.     }

  145.     private static final FixFloatComponent OTCIRS (
  146.         final JulianDate dtSpot,
  147.         final String strCurrency,
  148.         final String strMaturityTenor,
  149.         final double dblCoupon)
  150.     {
  151.         FixedFloatSwapConvention ffConv = IBORFixedFloatContainer.ConventionFromJurisdiction (
  152.             strCurrency,
  153.             "ALL",
  154.             strMaturityTenor,
  155.             "MAIN"
  156.         );

  157.         return ffConv.createFixFloatComponent (
  158.             dtSpot,
  159.             strMaturityTenor,
  160.             dblCoupon,
  161.             0.,
  162.             1.
  163.         );
  164.     }

  165.     /*
  166.      * Construct the Array of Swap Instruments from the given set of parameters
  167.      *
  168.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  169.      */

  170.     private static final CalibratableComponent[] SwapInstrumentsFromMaturityTenor (
  171.         final JulianDate dtEffective,
  172.         final String strCurrency,
  173.         final String[] astrTenor,
  174.         final double[] adblCoupon)
  175.         throws Exception
  176.     {
  177.         CalibratableComponent[] aCalibComp = new CalibratableComponent[astrTenor.length];

  178.         for (int i = 0; i < astrTenor.length; ++i)
  179.             aCalibComp[i] = OTCIRS (
  180.                 dtEffective,
  181.                 strCurrency,
  182.                 astrTenor[i],
  183.                 adblCoupon[i]
  184.             );

  185.         return aCalibComp;
  186.     }

  187.     /*
  188.      * Construct the discount curve using the following steps:
  189.      *  - Construct the array of cash instruments and their quotes.
  190.      *  - Construct the array of swap instruments and their quotes.
  191.      *  - Construct a shape preserving and smoothing KLK Hyperbolic Spline from the cash/swap instruments.
  192.      *
  193.      *      USE WITH CARE: This sample ignores errors and does not handle exceptions.
  194.      */

  195.     private static final MergedDiscountForwardCurve MakeDC (
  196.         final JulianDate dtSpot,
  197.         final String strCurrency,
  198.         final double dblBump)
  199.         throws Exception
  200.     {
  201.         /*
  202.          * Construct the array of Deposit instruments and their quotes.
  203.          */

  204.         CalibratableComponent[] aDepositComp = DepositInstrumentsFromMaturityDays (
  205.             dtSpot,
  206.             new int[] {},
  207.             0,
  208.             strCurrency
  209.         );

  210.         double[] adblDepositQuote = new double[] {}; // Futures

  211.         /*
  212.          * Construct the array of Swap instruments and their quotes.
  213.          */

  214.         double[] adblSwapQuote = new double[] {
  215.             0.0009875 + dblBump,   //  9M
  216.             0.00122 + dblBump,     //  1Y
  217.             0.00223 + dblBump,     // 18M
  218.             0.00383 + dblBump,     //  2Y
  219.             0.00827 + dblBump,     //  3Y
  220.             0.01245 + dblBump,     //  4Y
  221.             0.01605 + dblBump,     //  5Y
  222.             0.02597 + dblBump      // 10Y
  223.         };

  224.         String[] astrSwapManifestMeasure = new String[] {
  225.             "SwapRate",     //  9M
  226.             "SwapRate",     //  1Y
  227.             "SwapRate",     // 18M
  228.             "SwapRate",     //  2Y
  229.             "SwapRate",     //  3Y
  230.             "SwapRate",     //  4Y
  231.             "SwapRate",     //  5Y
  232.             "SwapRate"      // 10Y
  233.         };

  234.         CalibratableComponent[] aSwapComp = SwapInstrumentsFromMaturityTenor (
  235.             dtSpot,
  236.             strCurrency,
  237.             new java.lang.String[] {
  238.                 "9M", "1Y", "18M", "2Y", "3Y", "4Y", "5Y", "10Y"
  239.             },
  240.             new double[] {
  241.                 0.0009875, 0.00122, 0.00223, 0.00383, 0.00827, 0.01245, 0.01605, 0.02597
  242.             }
  243.         );

  244.         /*
  245.          * Construct a shape preserving and smoothing KLK Hyperbolic Spline from the cash/swap instruments.
  246.          */

  247.         return ScenarioDiscountCurveBuilder.CubicKLKHyperbolicDFRateShapePreserver (
  248.             "KLK_HYPERBOLIC_SHAPE_TEMPLATE",
  249.             new ValuationParams (
  250.                 dtSpot,
  251.                 dtSpot,
  252.                 "USD"
  253.             ),
  254.             aDepositComp,
  255.             adblDepositQuote,
  256.             null,
  257.             aSwapComp,
  258.             adblSwapQuote,
  259.             astrSwapManifestMeasure,
  260.             true
  261.         );
  262.     }

  263.     public static void main (
  264.         final String[] astrArgs)
  265.         throws Exception
  266.     {
  267.         EnvManager.InitEnv (
  268.             "",
  269.             true
  270.         );

  271.         JulianDate dtValue = DateUtil.Today();

  272.         JulianDate dtSettle = dtValue.addBusDays (
  273.             2,
  274.             "USD"
  275.         );

  276.         System.out.println ("\n---- Valuation Details ----\n");

  277.         System.out.println ("Trade Date  : " + dtValue);

  278.         System.out.println ("Settle Date : " + dtSettle);

  279.         double dblCoupon = 0.0187;
  280.         double dblFixing = 0.00087;
  281.         double dblNotional = 10.e+06;

  282.         /*
  283.          * Model the discount curve instrument quotes. Best pulled from Curves #42 in the BBG SWPM "Curves" tab
  284.          */

  285.         /*
  286.          * Build the Discount Curve
  287.          */

  288.         MergedDiscountForwardCurve dc = MakeDC (
  289.             dtValue,
  290.             "USD",
  291.             0.
  292.         );

  293.         JulianDate dtEffective = dtValue.addBusDays (
  294.             2,
  295.             "USD"
  296.         );

  297.         JulianDate dtMaturity = dtEffective.addTenor ("5Y");

  298.         /*
  299.          * Build the Fixed Receive Stream
  300.          */

  301.         FixFloatComponent swap = OTCIRS (
  302.             dtEffective,
  303.             "USD",
  304.             "5Y",
  305.             0.
  306.         );

  307.         System.out.println ("\n---- Swap Details ----\n");

  308.         System.out.println ("Effective: " + dtEffective);

  309.         System.out.println ("Maturity:  " + dtMaturity);

  310.         /*
  311.          * Set up the base market parameters, including base discount curves and the base fixings
  312.          */

  313.         LatentStateFixingsContainer lsfc = new LatentStateFixingsContainer();

  314.         ComposableUnitFloatingPeriod cufs = ((ComposableUnitFloatingPeriod) (swap.derivedStream().periods().get (0).periods().get (0)));

  315.         lsfc.add (
  316.             cufs.referenceIndexPeriod().fixingDate(),
  317.             swap.derivedStream().forwardLabel(),
  318.             dblFixing
  319.         );

  320.         CurveSurfaceQuoteContainer mktParams = MarketParamsBuilder.Create (
  321.             dc,
  322.             null,
  323.             null,
  324.             null,
  325.             null,
  326.             null,
  327.             lsfc
  328.         );

  329.         /*
  330.          * Set up the valuation parameters
  331.          */

  332.         ValuationParams valParams = new ValuationParams (
  333.             dtValue,
  334.             dtSettle,
  335.             "USD"
  336.         );

  337.         /*
  338.          * Generate the base scenario measures for the swap
  339.          */

  340.         CaseInsensitiveTreeMap<Double> mapSwapCalc = swap.value (
  341.             valParams,
  342.             null,
  343.             mktParams,
  344.             null
  345.         );

  346.         double dblBasePV = mapSwapCalc.get ("PV");

  347.         double dblBaseFixedDV01 = mapSwapCalc.get ("FixedDV01");

  348.         System.out.println ("\n---- Swap Output Measures ----\n");

  349.         System.out.println ("Mkt Val      : " + FormatUtil.FormatDouble (dblBasePV, 0, 0, dblNotional));

  350.         System.out.println ("Par Cpn      : " + FormatUtil.FormatDouble (mapSwapCalc.get ("FairPremium"), 1, 5, 100.));

  351.         System.out.println ("Fixed DV01   : " + FormatUtil.FormatDouble (dblBaseFixedDV01, 0, 0, dblNotional));

  352.         /*
  353.          * Set up the fixings bumped market parameters - these use base discount curve and the bumped fixing
  354.          */

  355.         lsfc.add (
  356.             cufs.referenceIndexPeriod().fixingDate(),
  357.             swap.derivedStream().forwardLabel(),
  358.             dblFixing + 0.0001
  359.         );

  360.         CurveSurfaceQuoteContainer mktParamsFixingsBumped = MarketParamsBuilder.Create (
  361.             dc,
  362.             null,
  363.             null,
  364.             null,
  365.             null,
  366.             null,
  367.             lsfc
  368.         );

  369.         /*
  370.          * Generate the fixing bumped scenario measures for the swap
  371.          */

  372.         CaseInsensitiveTreeMap<Double> mapSwapFixingsBumpedCalc = swap.value (
  373.             valParams,
  374.             null,
  375.             mktParamsFixingsBumped,
  376.             null
  377.         );

  378.         double dblFixingsDV01 = mapSwapFixingsBumpedCalc.get ("PV") - dblBasePV;

  379.         System.out.println ("Fixings DV01 : " + FormatUtil.FormatDouble (dblFixingsDV01, 0, 0, dblNotional));

  380.         System.out.println ("Total DV01   : " + FormatUtil.FormatDouble (dblBaseFixedDV01 + dblFixingsDV01, 0, 0, dblNotional));

  381.         /*
  382.          * Set up the rate flat bumped market parameters - these use the bumped base discount curve and the base fixing
  383.          */

  384.         MergedDiscountForwardCurve dcBumped = MakeDC (
  385.             dtValue,
  386.             "USD",
  387.             -0.0001
  388.         );

  389.         lsfc.add (
  390.             dtEffective,
  391.             swap.derivedStream().forwardLabel(),
  392.             dblFixing - 0.0001
  393.         );

  394.         CurveSurfaceQuoteContainer mktParamsRateBumped = MarketParamsBuilder.Create (
  395.             dcBumped,
  396.             null,
  397.             null,
  398.             null,
  399.             null,
  400.             null,
  401.             lsfc
  402.         );

  403.         /*
  404.          * Generate the rate flat bumped scenario measures for the swap
  405.          */

  406.         CaseInsensitiveTreeMap<Double> mapSwapRateBumpedCalc = swap.value (
  407.             valParams,
  408.             null,
  409.             mktParamsRateBumped,
  410.             null
  411.         );

  412.         System.out.println ("PV01         : " + FormatUtil.FormatDouble (mapSwapRateBumpedCalc.get ("PV") - dblBasePV, 0, 0, dblNotional));

  413.         /*
  414.          * Generate the Swap's fixed cash flows
  415.          */

  416.         System.out.println ("\n---- Fixed Cashflow ----\n");

  417.         for (CompositePeriod p : swap.referenceStream().cashFlowPeriod())
  418.             System.out.println (
  419.                 DateUtil.YYYYMMDD (p.payDate()) + FIELD_SEPARATOR +
  420.                 DateUtil.YYYYMMDD (p.startDate()) + FIELD_SEPARATOR +
  421.                 DateUtil.YYYYMMDD (p.endDate()) + FIELD_SEPARATOR +
  422.                 FormatUtil.FormatDouble (p.couponDCF() * 360, 0, 0, 1.) + FIELD_SEPARATOR +
  423.                 FormatUtil.FormatDouble (p.couponDCF(), 0, 2, dblCoupon * dblNotional) + FIELD_SEPARATOR +
  424.                 FormatUtil.FormatDouble (dc.df (p.payDate()), 1, 4, 1.)
  425.             );

  426.         /*
  427.          * Generate the Swap's floating cash flows
  428.          */

  429.         System.out.println ("\n---- Floating Cashflow ----\n");

  430.         for (CompositePeriod p : swap.derivedStream().cashFlowPeriod())
  431.             System.out.println (
  432.                 DateUtil.YYYYMMDD (p.payDate()) + FIELD_SEPARATOR +
  433.                 DateUtil.YYYYMMDD (p.startDate()) + FIELD_SEPARATOR +
  434.                 DateUtil.YYYYMMDD (p.endDate()) + FIELD_SEPARATOR +
  435.                 FormatUtil.FormatDouble (p.couponDCF() * 360, 0, 0, 1.) + FIELD_SEPARATOR +
  436.                 FormatUtil.FormatDouble (dc.df (p.payDate()), 1, 4, 1.)
  437.             );

  438.         EnvManager.TerminateEnv();
  439.     }
  440. }