CrossFloatCrossFloat.java

  1. package org.drip.sample.cross;

  2. import java.util.*;

  3. import org.drip.analytics.date.JulianDate;
  4. import org.drip.analytics.support.*;
  5. import org.drip.function.r1tor1.FlatUnivariate;
  6. import org.drip.numerical.common.*;
  7. import org.drip.param.market.CurveSurfaceQuoteContainer;
  8. import org.drip.param.period.*;
  9. import org.drip.param.valuation.*;
  10. import org.drip.product.params.*;
  11. import org.drip.product.rates.*;
  12. import org.drip.service.env.EnvManager;
  13. import org.drip.state.creator.*;
  14. import org.drip.state.discount.*;
  15. import org.drip.state.forward.ForwardCurve;
  16. import org.drip.state.identifier.*;

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

  94. /**
  95.  * <i>CrossFloatCrossFloat</i> demonstrates the construction, usage, and eventual valuation of the
  96.  * Mark-to-market float-float swap with a 3M EUR Floater leg that pays in USD, and a 6M EUR Floater leg that
  97.  * pays in USD. Comparison is done across MTM and non-MTM fixed Leg Counterparts.
  98.  *  
  99.  * <br><br>
  100.  *  <ul>
  101.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  102.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  103.  *      <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>
  104.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/cross/README.md">Single/Dual Stream XCCY Component</a></li>
  105.  *  </ul>
  106.  * <br><br>
  107.  *
  108.  * @author Lakshmi Krishnamurthy
  109.  */

  110. public class CrossFloatCrossFloat {

  111.     private static final FloatFloatComponent MakeFloatFloatSwap (
  112.         final JulianDate dtEffective,
  113.         final boolean bFXMTM,
  114.         final String strPayCurrency,
  115.         final String strCouponCurrency,
  116.         final String strMaturityTenor,
  117.         final int iTenorInMonthsReference,
  118.         final int iTenorInMonthsDerived)
  119.         throws Exception
  120.     {
  121.         ComposableFloatingUnitSetting cfusReference = new ComposableFloatingUnitSetting (
  122.             iTenorInMonthsReference + "M",
  123.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  124.             null,
  125.             ForwardLabel.Create (
  126.                 strCouponCurrency,
  127.                 iTenorInMonthsReference + "M"
  128.             ),
  129.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  130.             0.
  131.         );

  132.         ComposableFloatingUnitSetting cfusDerived = new ComposableFloatingUnitSetting (
  133.             iTenorInMonthsDerived + "M",
  134.             CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
  135.             null,
  136.             ForwardLabel.Create (
  137.                 strCouponCurrency,
  138.                 iTenorInMonthsDerived + "M"
  139.             ),
  140.             CompositePeriodBuilder.REFERENCE_PERIOD_IN_ADVANCE,
  141.             0.
  142.         );

  143.         CompositePeriodSetting cpsReference = new CompositePeriodSetting (
  144.             12 / iTenorInMonthsReference,
  145.             iTenorInMonthsReference + "M",
  146.             strPayCurrency,
  147.             null,
  148.             -1.,
  149.             null,
  150.             null,
  151.             bFXMTM ? null : new FixingSetting (
  152.                 FixingSetting.FIXING_PRESET_STATIC,
  153.                 null,
  154.                 dtEffective.julian()
  155.             ),
  156.             null
  157.         );

  158.         CompositePeriodSetting cpsDerived = new CompositePeriodSetting (
  159.             12 / iTenorInMonthsDerived,
  160.             iTenorInMonthsDerived + "M",
  161.             strPayCurrency,
  162.             null,
  163.             1.,
  164.             null,
  165.             null,
  166.             bFXMTM ? null : new FixingSetting (
  167.                 FixingSetting.FIXING_PRESET_STATIC,
  168.                 null,
  169.                 dtEffective.julian()
  170.             ),
  171.             null
  172.         );

  173.         List<Integer> lsReferenceStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  174.             dtEffective,
  175.             iTenorInMonthsReference + "M",
  176.             strMaturityTenor,
  177.             null
  178.         );

  179.         List<Integer> lsDerivedStreamEdgeDate = CompositePeriodBuilder.RegularEdgeDates (
  180.             dtEffective,
  181.             iTenorInMonthsDerived + "M",
  182.             strMaturityTenor,
  183.             null
  184.         );

  185.         Stream referenceStream = new Stream (
  186.             CompositePeriodBuilder.FloatingCompositeUnit (
  187.                 lsReferenceStreamEdgeDate,
  188.                 cpsReference,
  189.                 cfusReference
  190.             )
  191.         );

  192.         Stream derivedStream = new Stream (
  193.             CompositePeriodBuilder.FloatingCompositeUnit (
  194.                 lsDerivedStreamEdgeDate,
  195.                 cpsDerived,
  196.                 cfusDerived
  197.             )
  198.         );

  199.         CashSettleParams csp = new CashSettleParams (
  200.             0,
  201.             strPayCurrency,
  202.             0
  203.         );

  204.         return new FloatFloatComponent (
  205.             referenceStream,
  206.             derivedStream,
  207.             csp
  208.         );
  209.     }

  210.     public static final void main (
  211.         final String[] astrArgs)
  212.         throws Exception
  213.     {
  214.         double dblUSDFundingRate = 0.02;
  215.         double dblEUR3MForwardRate = 0.02;
  216.         double dblEUR6MForwardRate = 0.025;
  217.         double dblUSDEURFXRate = 1. / 1.35;

  218.         double dblUSDFundingVol = 0.3;
  219.         double dblEURForward3MVol = 0.3;
  220.         double dblEURForward6MVol = 0.3;
  221.         double dblUSDEURFXVol = 0.3;

  222.         double dblEUR3MUSDEURFXCorr = 0.1;
  223.         double dblEUR6MUSDEURFXCorr = 0.1;
  224.         double dblUSDFundingEUR3MCorr = 0.1;
  225.         double dblUSDFundingEUR6MCorr = 0.1;
  226.         double dblUSDFundingUSDEURFXCorr = 0.1;

  227.         /*
  228.          * Initialize the Credit Analytics Library
  229.          */

  230.         EnvManager.InitEnv ("");

  231.         JulianDate dtToday = org.drip.analytics.date.DateUtil.Today();

  232.         ValuationParams valParams = new ValuationParams (
  233.             dtToday,
  234.             dtToday,
  235.             "EUR"
  236.         );

  237.         MergedDiscountForwardCurve dcUSDFunding = ScenarioDiscountCurveBuilder.ExponentiallyCompoundedFlatRate (
  238.             dtToday,
  239.             "USD",
  240.             dblUSDFundingRate
  241.         );

  242.         ForwardLabel friEUR3M = ForwardLabel.Create (
  243.             "EUR",
  244.             "3M"
  245.         );

  246.         ForwardCurve fcEUR3M = ScenarioForwardCurveBuilder.FlatForwardForwardCurve (
  247.             dtToday,
  248.             friEUR3M,
  249.             dblEUR3MForwardRate
  250.         );

  251.         ForwardLabel friEUR6M = ForwardLabel.Create (
  252.             "EUR",
  253.             "6M"
  254.         );

  255.         ForwardCurve fcEUR6M = ScenarioForwardCurveBuilder.FlatForwardForwardCurve (
  256.             dtToday,
  257.             friEUR6M,
  258.             dblEUR6MForwardRate
  259.         );

  260.         CurrencyPair cp = CurrencyPair.FromCode ("USD/EUR");

  261.         FloatFloatComponent floatFloatMTM = MakeFloatFloatSwap (
  262.             dtToday,
  263.             true,
  264.             "USD",
  265.             "EUR",
  266.             "2Y",
  267.             6,
  268.             3
  269.         );

  270.         floatFloatMTM.setPrimaryCode ("EUR__USD__MTM::FLOAT::3M::6M::2Y");

  271.         FloatFloatComponent floatFloatNonMTM = MakeFloatFloatSwap (
  272.             dtToday,
  273.             false,
  274.             "USD",
  275.             "EUR",
  276.             "2Y",
  277.             6,
  278.             3
  279.         );

  280.         floatFloatNonMTM.setPrimaryCode ("EUR__USD__NONMTM::FLOAT::3M::6M::2Y");

  281.         FXLabel fxLabel = FXLabel.Standard (cp);

  282.         FundingLabel fundingLabelUSD = org.drip.state.identifier.FundingLabel.Standard ("USD");

  283.         CurveSurfaceQuoteContainer mktParams = new CurveSurfaceQuoteContainer();

  284.         mktParams.setFixing (
  285.             dtToday,
  286.             fxLabel,
  287.             dblUSDEURFXRate
  288.         );

  289.         mktParams.setForwardState (fcEUR3M);

  290.         mktParams.setForwardState (fcEUR6M);

  291.         mktParams.setFundingState (dcUSDFunding);

  292.         mktParams.setFXState (
  293.             ScenarioFXCurveBuilder.CubicPolynomialCurve (
  294.                 fxLabel.fullyQualifiedName(),
  295.                 dtToday,
  296.                 cp,
  297.                 new String[] {"10Y"},
  298.                 new double[] {dblUSDEURFXRate},
  299.                 dblUSDEURFXRate
  300.             )
  301.         );

  302.         mktParams.setForwardVolatility (
  303.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  304.                 valParams.valueDate(),
  305.                 VolatilityLabel.Standard (friEUR3M),
  306.                 "EUR",
  307.                 dblEURForward3MVol
  308.             )
  309.         );

  310.         mktParams.setForwardVolatility (
  311.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  312.                 valParams.valueDate(),
  313.                 VolatilityLabel.Standard (friEUR6M),
  314.                 "EUR",
  315.                 dblEURForward6MVol
  316.             )
  317.         );

  318.         mktParams.setForwardVolatility (
  319.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  320.                 valParams.valueDate(),
  321.                 VolatilityLabel.Standard (fundingLabelUSD),
  322.                 "USD",
  323.                 dblUSDFundingVol
  324.             )
  325.         );

  326.         mktParams.setFXVolatility (
  327.             ScenarioDeterministicVolatilityBuilder.FlatForward (
  328.                 valParams.valueDate(),
  329.                 VolatilityLabel.Standard (fxLabel),
  330.                 "USD",
  331.                 dblUSDEURFXVol
  332.             )
  333.         );

  334.         mktParams.setForwardFundingCorrelation (
  335.             friEUR3M,
  336.             fundingLabelUSD,
  337.             new FlatUnivariate (dblUSDFundingEUR3MCorr)
  338.         );

  339.         mktParams.setForwardFundingCorrelation (
  340.             friEUR6M,
  341.             fundingLabelUSD,
  342.             new FlatUnivariate (dblUSDFundingEUR6MCorr)
  343.         );

  344.         mktParams.setForwardFXCorrelation (
  345.             friEUR3M,
  346.             fxLabel,
  347.             new FlatUnivariate (dblEUR3MUSDEURFXCorr)
  348.         );

  349.         mktParams.setForwardFXCorrelation (
  350.             friEUR6M,
  351.             fxLabel,
  352.             new FlatUnivariate (dblEUR6MUSDEURFXCorr)
  353.         );

  354.         mktParams.setFundingFXCorrelation (
  355.             fundingLabelUSD,
  356.             fxLabel,
  357.             new FlatUnivariate (dblUSDFundingUSDEURFXCorr)
  358.         );

  359.         CaseInsensitiveTreeMap<Double> mapMTMOutput = floatFloatMTM.value (
  360.             valParams,
  361.             null,
  362.             mktParams,
  363.             null
  364.         );

  365.         CaseInsensitiveTreeMap<Double> mapNonMTMOutput = floatFloatNonMTM.value (
  366.             valParams,
  367.             null,
  368.             mktParams,
  369.             null
  370.         );

  371.         for (Map.Entry<String, Double> me : mapMTMOutput.entrySet()) {
  372.             String strKey = me.getKey();

  373.             if (null != me.getValue() && null != mapNonMTMOutput.get (strKey)) {
  374.                 double dblMTMMeasure = me.getValue();

  375.                 double dblNonMTMMeasure = mapNonMTMOutput.get (strKey);

  376.                 String strReconcile = NumberUtil.WithinTolerance (
  377.                     dblMTMMeasure,
  378.                     dblNonMTMMeasure,
  379.                     1.e-08,
  380.                     1.e-04
  381.                 ) ? "RECONCILES" : "DOES NOT RECONCILE";

  382.                 System.out.println ("\t" +
  383.                     FormatUtil.FormatDouble (dblMTMMeasure, 1, 8, 1.) + " | " +
  384.                     FormatUtil.FormatDouble (dblNonMTMMeasure, 1, 8, 1.) + " | " +
  385.                     strReconcile + " <= " + strKey);
  386.             }
  387.         }

  388.         EnvManager.TerminateEnv();
  389.     }
  390. }