EmbeddedOptionSchedule.java

  1. package org.drip.product.params;

  2. /*
  3.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  4.  */

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

  82. /**
  83.  * <i>EmbeddedOptionSchedule</i> is a place holder for the embedded option schedule for the component. It
  84.  * contains the schedule of exercise dates and factors, the exercise notice period, and the option is to call
  85.  * or put. Further, if the option is of the type fix-to-float on exercise, contains the post-exercise floater
  86.  * index and floating spread. If the exercise is not discrete (American option), the exercise dates/factors
  87.  * are discretized according to a pre-specified discretization grid. It exports serialization into and de-
  88.  * serialization out of byte arrays.
  89.  *
  90.  * <br><br>
  91.  *  <ul>
  92.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  93.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  94.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/product/README.md">Product Components/Baskets for Credit, FRA, FX, Govvie, Rates, and Option AssetClasses</a></li>
  95.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/product/params/README.md">Fixed Income Product Customization Parameters</a></li>
  96.  *  </ul>
  97.  * <br><br>
  98.  *
  99.  * @author Lakshmi Krishnamurthy
  100.  */

  101. public class EmbeddedOptionSchedule {
  102.     public static final int CALL_NOTICE_PERIOD_DEFAULT = 30;

  103.     private int _aiDate[] = null;
  104.     private boolean _bIsPut = false;
  105.     private double _adblFactor[] = null;
  106.     private java.lang.String _strFloatIndex = "";
  107.     private boolean _bFixToFloatOnExercise = false;
  108.     private int _iNoticePeriod = CALL_NOTICE_PERIOD_DEFAULT;
  109.     private double _dblFixToFloatSpread = java.lang.Double.NaN;
  110.     private double _dblFixToFloatExerciseDate = java.lang.Double.NaN;

  111.     /**
  112.      * Create the EOS from the dates/factors string arrays
  113.      *
  114.      * @param strDates String representing the date array
  115.      * @param strFactors String representing the factor array
  116.      * @param iNoticePeriod Exercise Notice Period
  117.      * @param bIsPut True (Put), False (Call)
  118.      * @param bIsDiscrete True (Discrete), False (Continuous)
  119.      * @param iScheduleStart Schedule start Date
  120.      * @param bFixToFloatOnExercise True - component becomes a floater on call
  121.      * @param dblFixToFloatExerciseDate Date at which the fix to float conversion happens
  122.      * @param strFloatIndex Floater Rate Index
  123.      * @param dblFixToFloatSpread Floater Spread
  124.      *
  125.      * @return EOS object
  126.      */

  127.     public static final EmbeddedOptionSchedule CreateFromDateFactorSet (
  128.         final java.lang.String strDates,
  129.         final java.lang.String strFactors,
  130.         final int iNoticePeriod,
  131.         final boolean bIsPut,
  132.         final boolean bIsDiscrete,
  133.         final int iScheduleStart,
  134.         final boolean bFixToFloatOnExercise,
  135.         final double dblFixToFloatExerciseDate,
  136.         final java.lang.String strFloatIndex,
  137.         final double dblFixToFloatSpread)
  138.     {
  139.         if (null == strDates || strDates.isEmpty() || null == strFactors || strFactors.isEmpty())
  140.             return null;

  141.         if (bIsDiscrete) {
  142.             try {
  143.                 return new EmbeddedOptionSchedule
  144.                     (org.drip.numerical.common.StringUtil.MakeIntegerArrayFromStringTokenizer (new
  145.                         java.util.StringTokenizer (strDates, ";")),
  146.                             org.drip.numerical.common.StringUtil.MakeDoubleArrayFromStringTokenizer (new
  147.                                 java.util.StringTokenizer (strFactors, ";")), bIsPut, iNoticePeriod,
  148.                                     bFixToFloatOnExercise, dblFixToFloatExerciseDate, strFloatIndex,
  149.                                         dblFixToFloatSpread);
  150.             } catch (java.lang.Exception e) {
  151.                 e.printStackTrace();
  152.             }

  153.             return null;
  154.         }

  155.         return FromAmerican (iScheduleStart,
  156.             org.drip.numerical.common.StringUtil.MakeIntegerArrayFromStringTokenizer (new
  157.                 java.util.StringTokenizer (strDates, ";")),
  158.                     org.drip.numerical.common.StringUtil.MakeDoubleArrayFromStringTokenizer (new
  159.                         java.util.StringTokenizer (strFactors, ";")), bIsPut, iNoticePeriod,
  160.                             bFixToFloatOnExercise, dblFixToFloatExerciseDate, strFloatIndex,
  161.                                 dblFixToFloatSpread);
  162.     }

  163.     /**
  164.      * Create the discretized American EOS schedule from the array of dates and factors
  165.      *
  166.      * @param iValDate Valuation Date - date to which the component is assumed to not have been exercised
  167.      * @param aiDate Array of dates
  168.      * @param adblFactor Matched Array of Factors
  169.      * @param bIsPut True (Put), False (Call)
  170.      * @param iNoticePeriod Exercise Notice Period
  171.      * @param bFixToFloatOnExercise True - component becomes a floater on call
  172.      * @param dblFixToFloatExerciseDate Date at which the fix to float conversion happens
  173.      * @param strFloatIndex Floater Rate Index
  174.      * @param dblFixToFloatSpread Floater Spread
  175.      *
  176.      * @return Discretized EOS
  177.      */

  178.     public static final EmbeddedOptionSchedule FromAmerican (
  179.         final int iValDate,
  180.         final int aiDate[],
  181.         final double adblFactor[],
  182.         final boolean bIsPut,
  183.         final int iNoticePeriod,
  184.         final boolean bFixToFloatOnExercise,
  185.         final double dblFixToFloatExerciseDate,
  186.         final java.lang.String strFloatIndex,
  187.         final double dblFixToFloatSpread)
  188.     {
  189.         return FromAmerican (iValDate, aiDate, adblFactor, bIsPut, iNoticePeriod, 30, bFixToFloatOnExercise,
  190.             dblFixToFloatExerciseDate, strFloatIndex, dblFixToFloatSpread);
  191.     }

  192.     /**
  193.      * Create the discretized American EOS schedule from the array of dates and factors
  194.      *
  195.      * @param iValDate Valuation Date - date to which the component is assumed to not have been exercised
  196.      * @param aiDate Array of dates
  197.      * @param adblFactor Matched Array of Factors
  198.      * @param bIsPut True (Put), False (Call)
  199.      * @param iNoticePeriod Exercise Notice Period
  200.      * @param iCallDiscretization Call Discretization Period Unit
  201.      * @param bFixToFloatOnExercise True - component becomes a floater on call
  202.      * @param dblFixToFloatExerciseDate Date at which the fix to float conversion happens
  203.      * @param strFloatIndex Floater Rate Index
  204.      * @param dblFixToFloatSpread Floater Spread
  205.      *
  206.      * @return Discretized EOS
  207.      */

  208.     public static final EmbeddedOptionSchedule FromAmerican (
  209.         final int iValDate,
  210.         final int aiDate[],
  211.         final double adblFactor[],
  212.         final boolean bIsPut,
  213.         final int iNoticePeriod,
  214.         final int iCallDiscretization,
  215.         final boolean bFixToFloatOnExercise,
  216.         final double dblFixToFloatExerciseDate,
  217.         final java.lang.String strFloatIndex,
  218.         final double dblFixToFloatSpread)
  219.     {
  220.         if (null == aiDate || aiDate.length == 0 || null == adblFactor || adblFactor.length == 0 ||
  221.             aiDate.length != adblFactor.length || 0 >= iCallDiscretization)
  222.             return null;

  223.         int iCallDate = aiDate[0];

  224.         java.util.ArrayList<java.lang.Integer> liCallDates = new java.util.ArrayList<java.lang.Integer>();

  225.         java.util.ArrayList<java.lang.Double> ldblCallFactors = new java.util.ArrayList<java.lang.Double>();

  226.         for (int i = 1; i < aiDate.length; ++i) {
  227.             while (iCallDate <= aiDate[i]) {
  228.                 liCallDates.add (iCallDate);

  229.                 ldblCallFactors.add (adblFactor[i - 1]);

  230.                 iCallDate += iCallDiscretization;
  231.             }
  232.         }

  233.         int[] aiEOSDate = new int[liCallDates.size()];

  234.         int i = 0;

  235.         for (int iEOSDate : liCallDates)
  236.             aiEOSDate[i++] = iEOSDate;

  237.         double[] adblEOSFactor = new double[ldblCallFactors.size()];

  238.         i = 0;

  239.         for (double dblCallFactor : ldblCallFactors)
  240.             adblEOSFactor[i++] = dblCallFactor;

  241.         try {
  242.             return new EmbeddedOptionSchedule (aiEOSDate, adblEOSFactor, bIsPut, iNoticePeriod,
  243.                 bFixToFloatOnExercise, dblFixToFloatExerciseDate, strFloatIndex, dblFixToFloatSpread);
  244.         } catch (java.lang.Exception e) {
  245.             e.printStackTrace();

  246.             return null;
  247.         }
  248.     }

  249.     /**
  250.      * Construct the EOS from the array of dates and factors
  251.      *
  252.      * @param aiDate Array of dates
  253.      * @param adblFactor Matched Array of Factors
  254.      * @param bIsPut True (Put), False (Call)
  255.      * @param iNoticePeriod Exercise Notice Period
  256.      * @param bFixToFloatOnExercise True - component becomes a floater on call
  257.      * @param dblFixToFloatExerciseDate Date at which the fix to float conversion happens
  258.      * @param strFloatIndex Floater Rate Index
  259.      * @param dblFixToFloatSpread Floater Spread
  260.      *
  261.      * @throws java.lang.Exception Thrown if inputs are invalid
  262.      */

  263.     public EmbeddedOptionSchedule (
  264.         final int[] aiDate,
  265.         final double[] adblFactor,
  266.         final boolean bIsPut,
  267.         final int iNoticePeriod,
  268.         final boolean bFixToFloatOnExercise,
  269.         final double dblFixToFloatExerciseDate,
  270.         final java.lang.String strFloatIndex,
  271.         final double dblFixToFloatSpread)
  272.         throws java.lang.Exception
  273.     {
  274.         if (null == aiDate || null == adblFactor || aiDate.length != adblFactor.length)
  275.             throw new java.lang.Exception ("EmbeddedOptionSchedule ctr => Invalid params");

  276.         _aiDate = new int[aiDate.length];
  277.         _adblFactor = new double[adblFactor.length];

  278.         for (int i = 0; i < _aiDate.length; ++i)
  279.             _aiDate[i] = aiDate[i];

  280.         for (int i = 0; i < _adblFactor.length; ++i)
  281.             _adblFactor[i] = adblFactor[i];

  282.         _bIsPut = bIsPut;
  283.         _iNoticePeriod = iNoticePeriod;
  284.         _strFloatIndex = strFloatIndex;
  285.         _dblFixToFloatSpread = dblFixToFloatSpread;
  286.         _bFixToFloatOnExercise = bFixToFloatOnExercise;
  287.         _dblFixToFloatExerciseDate = dblFixToFloatExerciseDate;
  288.     }

  289.     /**
  290.      * Construct a Deep Copy EOS from another EOS
  291.      *
  292.      * @param eosOther The Other EOS
  293.      */

  294.     public EmbeddedOptionSchedule (
  295.         final EmbeddedOptionSchedule eosOther)
  296.     {
  297.         _aiDate = new int[eosOther._aiDate.length];
  298.         _adblFactor = new double[eosOther._adblFactor.length];

  299.         for (int i = 0; i < _aiDate.length; ++i)
  300.             _aiDate[i] = eosOther._aiDate[i];

  301.         for (int i = 0; i < _adblFactor.length; ++i)
  302.             _adblFactor[i] = eosOther._adblFactor[i];

  303.         _bIsPut = eosOther._bIsPut;
  304.         _iNoticePeriod = eosOther._iNoticePeriod;
  305.         _strFloatIndex = eosOther._strFloatIndex;
  306.         _dblFixToFloatSpread = eosOther._dblFixToFloatSpread;
  307.         _bFixToFloatOnExercise = eosOther._bFixToFloatOnExercise;
  308.         _dblFixToFloatExerciseDate = eosOther._dblFixToFloatExerciseDate;
  309.     }

  310.     /**
  311.      * Whether the component is putable or callable
  312.      *
  313.      * @return True (Put), False (Call)
  314.      */

  315.     public boolean isPut()
  316.     {
  317.         return _bIsPut;
  318.     }

  319.     /**
  320.      * Get the array of dates
  321.      *
  322.      * @return The array of dates
  323.      */

  324.     public int[] dates()
  325.     {
  326.         return _aiDate;
  327.     }

  328.     /**
  329.      * Get the array of factors
  330.      *
  331.      * @return The array of factors
  332.      */

  333.     public double[] factors()
  334.     {
  335.         return _adblFactor;
  336.     }

  337.     /**
  338.      * Get the specific indexed factor
  339.      *
  340.      * @param iIndex Factor index
  341.      *
  342.      * @return Factor corresponding to the index
  343.      */

  344.     public double factor (
  345.         final int iIndex)
  346.     {
  347.         return _adblFactor[iIndex];
  348.     }

  349.     /**
  350.      * Retrieve the exercise notice period
  351.      *
  352.      * @return Minimum Exercise Notice Period in Days
  353.      */

  354.     public int exerciseNoticePeriod()
  355.     {
  356.         return _iNoticePeriod;
  357.     }

  358.     /**
  359.      * Return whether the component is fix to float on exercise
  360.      *
  361.      * @return True (component becomes a floater on call), False (component does not change)
  362.      */

  363.     public boolean isFixToFloatOnExercise()
  364.     {
  365.         return _bFixToFloatOnExercise;
  366.     }

  367.     /**
  368.      * Generate the Possible Exercise Dates from the Spot Date and the Notice Period
  369.      *
  370.      * @param iSpotDate The Spot Date
  371.      *
  372.      * @return Array of Possible Exercise Dates from the Spot Date and the Notice Period
  373.      */

  374.     public int[] exerciseDates (
  375.         final int iSpotDate)
  376.     {
  377.         java.util.List<java.lang.Integer> lsDate = new java.util.ArrayList<java.lang.Integer>();

  378.         int iExerciseSize = _aiDate.length;
  379.         int iExerciseCutOff = iSpotDate + _iNoticePeriod;

  380.         for (int i = 0; i < iExerciseSize; ++i) {
  381.             if (_aiDate[i] >= iExerciseCutOff) lsDate.add (_aiDate[i]);
  382.         }

  383.         int iSize = lsDate.size();

  384.         if (0 == iSize) return null;

  385.         int[] aiExerciseDate = new int[iSize];

  386.         for (int i = 0; i < iSize; ++i)
  387.             aiExerciseDate[i] = lsDate.get (i);

  388.         return aiExerciseDate;
  389.     }

  390.     /**
  391.      * Generate the Possible Exercise Factors from the Spot Date and the Notice Period
  392.      *
  393.      * @param iSpotDate The Spot Date
  394.      *
  395.      * @return Array of Possible Exercise Factors from the Spot Date and the Notice Period
  396.      */

  397.     public double[] exerciseFactors (
  398.         final int iSpotDate)
  399.     {
  400.         java.util.List<java.lang.Double> lsFactor = new java.util.ArrayList<java.lang.Double>();

  401.         int iExerciseSize = _aiDate.length;
  402.         int iExerciseCutOff = iSpotDate + _iNoticePeriod;

  403.         for (int i = 0; i < iExerciseSize; ++i) {
  404.             if (_aiDate[i] >= iExerciseCutOff) lsFactor.add (_adblFactor[i]);
  405.         }

  406.         int iSize = lsFactor.size();

  407.         if (0 == iSize) return null;

  408.         double[] aiExerciseFactor = new double[iSize];

  409.         for (int i = 0; i < iSize; ++i)
  410.             aiExerciseFactor[i] = lsFactor.get (i);

  411.         return aiExerciseFactor;
  412.     }

  413.     /**
  414.      * Retrieve the Next Exercise Date, starting from the Spot
  415.      *
  416.      * @param iSpotDate The Spot Date
  417.      *
  418.      * @return Next Exercise Date
  419.      *
  420.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  421.      */

  422.     public int nextDate (
  423.         final int iSpotDate)
  424.         throws java.lang.Exception
  425.     {
  426.         int iExerciseSize = _aiDate.length;

  427.         for (int i = 0; i < iExerciseSize; ++i) {
  428.             if (_aiDate[i] - _iNoticePeriod >= iSpotDate) return _aiDate[i];
  429.         }

  430.         throw new java.lang.Exception ("EmbeddedOptionSchedule::nextDate => Invalid Inputs");
  431.     }

  432.     /**
  433.      * Retrieve the Exercise Factor corresponding to the Next Exercise Date, starting from the Spot
  434.      *
  435.      * @param iSpotDate The Spot Date
  436.      *
  437.      * @return Next Exercise Factor
  438.      *
  439.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  440.      */

  441.     public double nextFactor (
  442.         final int iSpotDate)
  443.         throws java.lang.Exception
  444.     {
  445.         int iExerciseSize = _aiDate.length;

  446.         for (int i = 0; i < iExerciseSize; ++i) {
  447.             if (_aiDate[i] - _iNoticePeriod >= iSpotDate) return _adblFactor[i];
  448.         }

  449.         throw new java.lang.Exception ("EmbeddedOptionSchedule::nextFactor => Invalid Inputs");
  450.     }
  451. }