FokkerPlanckGenerator.java

  1. package org.drip.pricer.option;

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

  79. /**
  80.  * <i>FokkerPlanckGenerator</i> holds the base functionality that the performs the PDF evolution oriented
  81.  * Option Pricing.
  82.  *
  83.  *  <br><br>
  84.  *  <ul>
  85.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  86.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  87.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/pricer/README.md">Custom Pricing Algorithms and the Derivative Fokker Planck Trajectory Generators</a></li>
  88.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/pricer/option/README.md">Deterministic/Stochastic Volatility Settings/Greeks</a></li>
  89.  *  </ul>
  90.  * <br><br>
  91.  *
  92.  * @author Lakshmi Krishnamurthy
  93.  */

  94. public abstract class FokkerPlanckGenerator implements org.drip.param.pricer.GenericPricer {

  95.     /**
  96.      * Compute the Expected Payoff of the Option from the Inputs
  97.      *
  98.      * @param dblStrike Option Strike
  99.      * @param dblTimeToExpiry Option Time To Expiry
  100.      * @param dblRiskFreeRate Option Risk Free Rate
  101.      * @param dblUnderlier Option Underlier Value
  102.      * @param bIsPut TRUE - The Option is a Put
  103.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  104.      * @param dblInitialVolatility Option Initial Volatility Value
  105.      * @param bAsPrice TRUE - Return the Discounted Payoff
  106.      *
  107.      * @return The Expected Option Payoff
  108.      *
  109.      * @throws java.lang.Exception Thrown if the Expected Payoff cannot be calculated
  110.      */

  111.     public abstract double payoff (
  112.         final double dblStrike,
  113.         final double dblTimeToExpiry,
  114.         final double dblRiskFreeRate,
  115.         final double dblUnderlier,
  116.         final boolean bIsPut,
  117.         final boolean bIsForward,
  118.         final double dblInitialVolatility,
  119.         final boolean bAsPrice)
  120.         throws java.lang.Exception;

  121.     /**
  122.      * Carry out a Sensitivity Run and generate the Pricing related measure set
  123.      *
  124.      * @param dblStrike Option Strike
  125.      * @param dblTimeToExpiry Option Time To Expiry
  126.      * @param dblRiskFreeRate Option Risk Free Rate
  127.      * @param dblUnderlier Option Underlier Value
  128.      * @param bIsPut TRUE - The Option is a Put
  129.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  130.      * @param dblInitialVolatility Option Initial Volatility Value
  131.      *
  132.      * @return The Greeks Sensitivities Output
  133.      */

  134.     public abstract org.drip.pricer.option.Greeks greeks (
  135.         final double dblStrike,
  136.         final double dblTimeToExpiry,
  137.         final double dblRiskFreeRate,
  138.         final double dblUnderlier,
  139.         final boolean bIsPut,
  140.         final boolean bIsForward,
  141.         final double dblInitialVolatility);

  142.     /**
  143.      * Compute the Expected Payoff of the Option from the Inputs
  144.      *
  145.      * @param iSpotDate Spot Date
  146.      * @param iExpiryDate Expiry Date
  147.      * @param dblStrike Option Strike
  148.      * @param dcFunding The Funding Curve
  149.      * @param dblUnderlier Option Underlier Value
  150.      * @param bIsPut TRUE - The Option is a Put
  151.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  152.      * @param dblInitialVolatility Option Initial Volatility Value
  153.      * @param bAsPrice TRUE - Return the Discounted Payoff
  154.      *
  155.      * @return The Expected Option Payoff
  156.      *
  157.      * @throws java.lang.Exception Thrown if the Expected Payoff cannot be calculated
  158.      */

  159.     public double payoff (
  160.         final int iSpotDate,
  161.         final int iExpiryDate,
  162.         final double dblStrike,
  163.         final org.drip.state.discount.MergedDiscountForwardCurve dcFunding,
  164.         final double dblUnderlier,
  165.         final boolean bIsPut,
  166.         final boolean bIsForward,
  167.         final double dblInitialVolatility,
  168.         final boolean bAsPrice)
  169.         throws java.lang.Exception
  170.     {
  171.         if (iExpiryDate <= iSpotDate || !org.drip.numerical.common.NumberUtil.IsValid (dblStrike) || null ==
  172.             dcFunding || !org.drip.numerical.common.NumberUtil.IsValid (dblInitialVolatility))
  173.             throw new java.lang.Exception ("FokkerPlanckGenerator::payoff => Invalid Inputs");

  174.         return payoff (dblStrike, 1. * (iExpiryDate - iSpotDate) / 365.25, dcFunding.libor (iSpotDate,
  175.             iExpiryDate), dblUnderlier, bIsPut, bIsForward, dblInitialVolatility, bAsPrice);
  176.     }

  177.     /**
  178.      * Compute the Expected Payoff of the Option from the Inputs
  179.      *
  180.      * @param iSpotDate Spot Date
  181.      * @param iExpiryDate Expiry Date
  182.      * @param dblStrike Option Strike
  183.      * @param dcFunding The Funding Curve
  184.      * @param dblUnderlier Option Underlier Value
  185.      * @param bIsPut TRUE - The Option is a Put
  186.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  187.      * @param funcVolatilityR1ToR1 The R^1 To R^1 Volatility Term Structure
  188.      * @param bAsPrice TRUE - Return the Discounted Payoff
  189.      *
  190.      * @return The Expected Option Payoff
  191.      *
  192.      * @throws java.lang.Exception Thrown if the Expected Payoff cannot be calculated
  193.      */

  194.     public double payoff (
  195.         final int iSpotDate,
  196.         final int iExpiryDate,
  197.         final double dblStrike,
  198.         final org.drip.state.discount.MergedDiscountForwardCurve dcFunding,
  199.         final double dblUnderlier,
  200.         final boolean bIsPut,
  201.         final boolean bIsForward,
  202.         final org.drip.function.definition.R1ToR1 funcVolatilityR1ToR1,
  203.         final boolean bAsPrice)
  204.         throws java.lang.Exception
  205.     {
  206.         if (iExpiryDate <= iSpotDate || !org.drip.numerical.common.NumberUtil.IsValid (dblStrike) || null ==
  207.             dcFunding || null == funcVolatilityR1ToR1)
  208.             throw new java.lang.Exception ("FokkerPlanckGenerator::payoff => Invalid Inputs");

  209.         int iDaysToExpiry = iExpiryDate - iSpotDate;

  210.         double dblRiskFreeRate = dcFunding.libor (iSpotDate, iExpiryDate);

  211.         org.drip.function.definition.R1ToR1 funcVarianceR1ToR1 = new org.drip.function.definition.R1ToR1
  212.             (null) {
  213.             @Override public double evaluate (
  214.                 final double dblX)
  215.                 throws java.lang.Exception
  216.             {
  217.                 return funcVolatilityR1ToR1.evaluate (dblX) * funcVolatilityR1ToR1.evaluate (dblX);
  218.             }
  219.         };

  220.         double dblEffectiveVolatility = java.lang.Math.sqrt (funcVarianceR1ToR1.integrate (iSpotDate,
  221.             iExpiryDate) / iDaysToExpiry);

  222.         return payoff (dblStrike, 1. * iDaysToExpiry / 365.25, dblRiskFreeRate, dblUnderlier, bIsPut,
  223.             bIsForward, dblEffectiveVolatility, bAsPrice);
  224.     }

  225.     /**
  226.      * Carry out a Sensitivity Run and generate the Pricing related measure set
  227.      *
  228.      * @param iSpotDate Spot Date
  229.      * @param iExpiryDate Expiry Date
  230.      * @param dblStrike Option Strike
  231.      * @param dcFunding The Funding Curve
  232.      * @param dblUnderlier Option Underlier Value
  233.      * @param bIsPut TRUE - The Option is a Put
  234.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  235.      * @param dblIntegratedSurfaceVariance The Integrated Surface Variance
  236.      *
  237.      * @return The Greeks Output generated from the Sensitivities Run
  238.      */

  239.     public org.drip.pricer.option.Greeks greeks (
  240.         final int iSpotDate,
  241.         final int iExpiryDate,
  242.         final double dblStrike,
  243.         final org.drip.state.discount.MergedDiscountForwardCurve dcFunding,
  244.         final double dblUnderlier,
  245.         final boolean bIsPut,
  246.         final boolean bIsForward,
  247.         final double dblIntegratedSurfaceVariance)
  248.     {
  249.         if (iExpiryDate <= iSpotDate || !org.drip.numerical.common.NumberUtil.IsValid (dblStrike) || null ==
  250.             dcFunding || !org.drip.numerical.common.NumberUtil.IsValid (dblIntegratedSurfaceVariance))
  251.             return null;

  252.         double dblTimeToExpiry = 1. * (iExpiryDate - iSpotDate) / 365.25;

  253.         try {
  254.             return greeks (dblStrike, dblTimeToExpiry, dcFunding.libor (iSpotDate, iExpiryDate),
  255.                 dblUnderlier, bIsPut, bIsForward, java.lang.Math.sqrt (dblIntegratedSurfaceVariance /
  256.                     dblTimeToExpiry));
  257.         } catch (java.lang.Exception e) {
  258.             e.printStackTrace();
  259.         }

  260.         return null;
  261.     }

  262.     /**
  263.      * Carry out a Sensitivity Run and generate the Pricing related measure set
  264.      *
  265.      * @param iSpotDate Spot Date
  266.      * @param iExpiryDate Expiry Date
  267.      * @param dblStrike Option Strike
  268.      * @param dcFunding The Funding Curve
  269.      * @param dblUnderlier Option Underlier Value
  270.      * @param bIsPut TRUE - The Option is a Put
  271.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  272.      * @param funcVolatilityR1ToR1 The R^1 To R^1 Volatility Term Structure
  273.      *
  274.      * @return The Greeks Output generated from the Sensitivities Run
  275.      */

  276.     public org.drip.pricer.option.Greeks greeks (
  277.         final int iSpotDate,
  278.         final int iExpiryDate,
  279.         final double dblStrike,
  280.         final org.drip.state.discount.MergedDiscountForwardCurve dcFunding,
  281.         final double dblUnderlier,
  282.         final boolean bIsPut,
  283.         final boolean bIsForward,
  284.         final org.drip.function.definition.R1ToR1 funcVolatilityR1ToR1)
  285.     {
  286.         if (iExpiryDate <= iSpotDate || !org.drip.numerical.common.NumberUtil.IsValid (dblStrike) || null ==
  287.             dcFunding || null == funcVolatilityR1ToR1)
  288.             return null;

  289.         double dblRiskFreeRate = java.lang.Double.NaN;
  290.         double dblEffectiveVolatility = java.lang.Double.NaN;
  291.         double dblTimeToExpiry = 1. * (iExpiryDate - iSpotDate) / 365.25;

  292.         org.drip.function.definition.R1ToR1 funcVarianceR1ToR1 = new org.drip.function.definition.R1ToR1
  293.             (null) {
  294.             @Override public double evaluate (
  295.                 final double dblX)
  296.                 throws java.lang.Exception
  297.             {
  298.                 return funcVolatilityR1ToR1.evaluate (dblX) * funcVolatilityR1ToR1.evaluate (dblX);
  299.             }
  300.         };

  301.         try {
  302.             dblRiskFreeRate = dcFunding.libor (iSpotDate, iExpiryDate);

  303.             dblEffectiveVolatility = java.lang.Math.sqrt (funcVarianceR1ToR1.integrate (iSpotDate,
  304.                 iExpiryDate) / (365.25 * dblTimeToExpiry));
  305.         } catch (java.lang.Exception e) {
  306.             e.printStackTrace();

  307.             return null;
  308.         }

  309.         return greeks (dblStrike, dblTimeToExpiry, dblRiskFreeRate, dblUnderlier, bIsPut, bIsForward,
  310.             dblEffectiveVolatility);
  311.     }

  312.     /**
  313.      * Imply the Effective Volatility From the Option Price
  314.      *
  315.      * @param dblStrike Strike
  316.      * @param dblTimeToExpiry Time To Expiry
  317.      * @param dblRiskFreeRate Risk Free Rate
  318.      * @param dblUnderlier The Underlier
  319.      * @param bIsPut TRUE - The Option is a Put
  320.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  321.      * @param dblPrice The Price
  322.      *
  323.      * @return The Implied Effective Volatility
  324.      *
  325.      * @throws java.lang.Exception Thrown if the Effective Volatility cannot be implied
  326.      */

  327.     public double impliedVolatilityFromPrice (
  328.         final double dblStrike,
  329.         final double dblTimeToExpiry,
  330.         final double dblRiskFreeRate,
  331.         final double dblUnderlier,
  332.         final boolean bIsPut,
  333.         final boolean bIsForward,
  334.         final double dblPrice)
  335.         throws java.lang.Exception
  336.     {
  337.         org.drip.function.definition.R1ToR1 au = new org.drip.function.definition.R1ToR1 (null) {
  338.             @Override public double evaluate (
  339.                 final double dblSpotVolatility)
  340.                 throws java.lang.Exception
  341.             {
  342.                 return payoff (dblStrike, dblTimeToExpiry, dblRiskFreeRate, dblUnderlier, bIsPut, bIsForward,
  343.                     dblSpotVolatility, true) - dblPrice;
  344.             }
  345.         };

  346.         org.drip.function.r1tor1solver.FixedPointFinderOutput fpop = new
  347.             org.drip.function.r1tor1solver.FixedPointFinderBrent (0., au, true).findRoot();

  348.         if (null == fpop || !fpop.containsRoot())
  349.             throw new java.lang.Exception
  350.                 ("FokkerPlanckGenerator::impliedVolatilityFromPrice => Cannot imply Volatility");

  351.         return java.lang.Math.abs (fpop.getRoot());
  352.     }

  353.     /**
  354.      * Imply the Effective Volatility From the Option Price
  355.      *
  356.      * @param iSpotDate Spot Date
  357.      * @param iExpiryDate Expiry Date
  358.      * @param dblStrike Option Strike
  359.      * @param dcFunding The Funding Curve
  360.      * @param dblUnderlier Option Underlier Value
  361.      * @param bIsPut TRUE - The Option is a Put
  362.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  363.      * @param dblPrice The Price
  364.      *
  365.      * @return The Implied Effective Volatility
  366.      *
  367.      * @throws java.lang.Exception Thrown if the Effective Volatility cannot be implied
  368.      */

  369.     public double impliedVolatilityFromPrice (
  370.         final int iSpotDate,
  371.         final int iExpiryDate,
  372.         final double dblStrike,
  373.         final org.drip.state.discount.MergedDiscountForwardCurve dcFunding,
  374.         final double dblUnderlier,
  375.         final boolean bIsPut,
  376.         final boolean bIsForward,
  377.         final double dblPrice)
  378.         throws java.lang.Exception
  379.     {
  380.         org.drip.function.definition.R1ToR1 au = new org.drip.function.definition.R1ToR1 (null) {
  381.             @Override public double evaluate (
  382.                 final double dblInitialVolatility)
  383.                 throws java.lang.Exception
  384.             {
  385.                 return payoff (iSpotDate, iExpiryDate, dblStrike, dcFunding, dblUnderlier, bIsPut,
  386.                     bIsForward, dblInitialVolatility, true) - dblPrice;
  387.             }
  388.         };

  389.         org.drip.function.r1tor1solver.FixedPointFinderOutput fpop = new
  390.             org.drip.function.r1tor1solver.FixedPointFinderBrent (0., au, true).findRoot();

  391.         if (null == fpop || !fpop.containsRoot())
  392.             throw new java.lang.Exception
  393.                 ("FokkerPlanckGenerator::impliedVolatilityFromPrice => Cannot imply Volatility");

  394.         return java.lang.Math.abs (fpop.getRoot());
  395.     }

  396.     /**
  397.      * Imply the Effective Black-Scholes Volatility From the Option Price
  398.      *
  399.      * @param dblStrike Strike
  400.      * @param dblTimeToExpiry Time To Expiry
  401.      * @param dblRiskFreeRate Risk Free Rate
  402.      * @param dblUnderlier The Underlier
  403.      * @param bIsPut TRUE - The Option is a Put
  404.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  405.      * @param dblPrice The Price
  406.      *
  407.      * @return The Implied Black Scholes Effective Volatility
  408.      *
  409.      * @throws java.lang.Exception Thrown if the Black Scholes Effective Volatility cannot be implied
  410.      */

  411.     public double impliedBlackScholesVolatility (
  412.         final double dblStrike,
  413.         final double dblTimeToExpiry,
  414.         final double dblRiskFreeRate,
  415.         final double dblUnderlier,
  416.         final boolean bIsPut,
  417.         final boolean bIsForward,
  418.         final double dblPrice)
  419.         throws java.lang.Exception
  420.     {
  421.         return new org.drip.pricer.option.BlackScholesAlgorithm().impliedVolatilityFromPrice (dblStrike,
  422.             dblTimeToExpiry, dblRiskFreeRate, dblUnderlier, bIsPut, bIsForward, dblPrice);
  423.     }
  424. }