EuropeanCallPut.java

  1. package org.drip.product.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>EuropeanCallPut</i> implements a simple European Call/Put Option, and its Black Scholes Price.
  81.  *
  82.  * <br><br>
  83.  *  <ul>
  84.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  85.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  86.  *      <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>
  87.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/product/option/README.md">Options on Fixed Income Components</a></li>
  88.  *  </ul>
  89.  * <br><br>
  90.  *
  91.  * @author Lakshmi Krishnamurthy
  92.  */

  93. public class EuropeanCallPut {
  94.     private double _dblStrike = java.lang.Double.NaN;
  95.     private org.drip.analytics.date.JulianDate _dtMaturity = null;

  96.     /**
  97.      * EuropeanCallPut constructor
  98.      *
  99.      * @param dtMaturity Option Maturity
  100.      * @param dblStrike Option Strike
  101.      *
  102.      * @throws java.lang.Exception Thrown if Inputs are Invalid
  103.      */

  104.     public EuropeanCallPut (
  105.         final org.drip.analytics.date.JulianDate dtMaturity,
  106.         final double dblStrike)
  107.         throws java.lang.Exception
  108.     {
  109.         if (null == (_dtMaturity = dtMaturity) || !org.drip.numerical.common.NumberUtil.IsValid (_dblStrike =
  110.             dblStrike) || 0. >= _dblStrike)
  111.             throw new java.lang.Exception ("EuropeanCallPut ctr: Invalid Inputs");
  112.     }

  113.     /**
  114.      * Retrieve the Option Maturity
  115.      *
  116.      * @return The Option Maturity
  117.      */

  118.     public org.drip.analytics.date.JulianDate maturity()
  119.     {
  120.         return _dtMaturity;
  121.     }

  122.     /**
  123.      * Retrieve the Option Strike
  124.      *
  125.      * @return The Option Strike
  126.      */

  127.     public double strike()
  128.     {
  129.         return _dblStrike;
  130.     }

  131.     /**
  132.      * Generate the Measure Set for the Option
  133.      *
  134.      * @param valParams The Valuation Parameters
  135.      * @param dblUnderlier The Underlier
  136.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  137.      * @param dc Discount Curve
  138.      * @param auVolatility The Option Volatility Function
  139.      * @param fpg The Fokker Planck-based Option Pricer
  140.      *
  141.      * @return The Map of the Measures
  142.      */

  143.     public org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> value (
  144.         final org.drip.param.valuation.ValuationParams valParams,
  145.         final double dblUnderlier,
  146.         final boolean bIsForward,
  147.         final org.drip.state.discount.MergedDiscountForwardCurve dc,
  148.         final org.drip.function.definition.R1ToR1 auVolatility,
  149.         final org.drip.pricer.option.FokkerPlanckGenerator fpg)
  150.     {
  151.         if (null == valParams || null == dc || null == auVolatility || null == fpg) return null;

  152.         int iValueDate = valParams.valueDate();

  153.         int iMaturityDate = _dtMaturity.julian();

  154.         if (iValueDate >= iMaturityDate) return null;

  155.         long lStartTime = System.nanoTime();

  156.         double dblRiskFreeRate = java.lang.Double.NaN;
  157.         double dblTTE = (iMaturityDate - iValueDate) / 365.25;
  158.         double dblImpliedPutVolatility = java.lang.Double.NaN;
  159.         double dblImpliedCallVolatility = java.lang.Double.NaN;
  160.         double dblTimeAveragedVolatility = java.lang.Double.NaN;
  161.         double dblBlackScholesPutVolatility = java.lang.Double.NaN;
  162.         double dblBlackScholesCallVolatility = java.lang.Double.NaN;

  163.         try {
  164.             dblRiskFreeRate = dc.zero (iMaturityDate);

  165.             dblTimeAveragedVolatility = auVolatility.integrate (iValueDate, iMaturityDate) / (iMaturityDate -
  166.                 iValueDate);
  167.         } catch (java.lang.Exception e) {
  168.             e.printStackTrace();

  169.             return null;
  170.         }

  171.         org.drip.pricer.option.Greeks callGreeks = fpg.greeks (_dblStrike, dblTTE, dblRiskFreeRate,
  172.             dblUnderlier, false, bIsForward, dblTimeAveragedVolatility);

  173.         org.drip.pricer.option.PutGreeks putGreeks = (org.drip.pricer.option.PutGreeks) fpg.greeks
  174.             (_dblStrike, dblTTE, dblRiskFreeRate, dblUnderlier, true, bIsForward, dblTimeAveragedVolatility);

  175.         if (null == callGreeks || null == putGreeks) return null;

  176.         double dblCallPrice = callGreeks.price();

  177.         double dblPutPrice = putGreeks.price();

  178.         try {
  179.             dblBlackScholesCallVolatility = fpg.impliedBlackScholesVolatility (_dblStrike, dblTTE,
  180.                 dblRiskFreeRate, dblUnderlier, false, bIsForward, dblCallPrice);

  181.             dblBlackScholesPutVolatility = fpg.impliedBlackScholesVolatility (_dblStrike, dblTTE,
  182.                 dblRiskFreeRate, dblUnderlier, true, bIsForward, dblPutPrice);

  183.             dblImpliedCallVolatility = fpg.impliedVolatilityFromPrice (_dblStrike, dblTTE, dblRiskFreeRate,
  184.                 dblUnderlier, false, bIsForward, dblCallPrice);

  185.             dblImpliedPutVolatility = fpg.impliedVolatilityFromPrice (_dblStrike, dblTTE, dblRiskFreeRate,
  186.                 dblUnderlier, true, bIsForward, dblPutPrice);
  187.         } catch (java.lang.Exception e) {
  188.             e.printStackTrace();

  189.             return null;
  190.         }

  191.         org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapMeasure = new
  192.             org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double>();

  193.         mapMeasure.put ("BlackScholesCallVolatility", dblBlackScholesCallVolatility);

  194.         mapMeasure.put ("BlackScholesPutVolatility", dblBlackScholesPutVolatility);

  195.         mapMeasure.put ("CalcTime", (System.nanoTime() - lStartTime) * 1.e-09);

  196.         mapMeasure.put ("CallCharm", callGreeks.charm());

  197.         mapMeasure.put ("CallColor", callGreeks.color());

  198.         mapMeasure.put ("CallDelta", callGreeks.delta());

  199.         mapMeasure.put ("CallGamma", callGreeks.gamma());

  200.         mapMeasure.put ("CallPrice", callGreeks.price());

  201.         mapMeasure.put ("CallProb1", callGreeks.prob1());

  202.         mapMeasure.put ("CallProb2", callGreeks.prob2());

  203.         mapMeasure.put ("CallRho", callGreeks.rho());

  204.         mapMeasure.put ("CallSpeed", callGreeks.speed());

  205.         mapMeasure.put ("CallTheta", callGreeks.theta());

  206.         mapMeasure.put ("CallUltima", callGreeks.ultima());

  207.         mapMeasure.put ("CallVanna", callGreeks.vanna());

  208.         mapMeasure.put ("CallVega", callGreeks.vega());

  209.         mapMeasure.put ("CallVeta", callGreeks.veta());

  210.         mapMeasure.put ("CallVomma", callGreeks.vomma());

  211.         mapMeasure.put ("DF", callGreeks.df());

  212.         mapMeasure.put ("EffectiveVolatility", callGreeks.effectiveVolatility());

  213.         mapMeasure.put ("ImpliedCallVolatility", dblImpliedCallVolatility);

  214.         mapMeasure.put ("ImpliedPutVolatility", dblImpliedPutVolatility);

  215.         mapMeasure.put ("PutCharm", putGreeks.charm());

  216.         mapMeasure.put ("PutColor", putGreeks.color());

  217.         mapMeasure.put ("PutDelta", putGreeks.delta());

  218.         mapMeasure.put ("PutGamma", putGreeks.gamma());

  219.         mapMeasure.put ("PutPrice", putGreeks.price());

  220.         mapMeasure.put ("PutPriceFromParity", putGreeks.putPriceFromParity());

  221.         mapMeasure.put ("PutProb1", putGreeks.prob1());

  222.         mapMeasure.put ("PutProb2", putGreeks.prob2());

  223.         mapMeasure.put ("PutRho", putGreeks.rho());

  224.         mapMeasure.put ("PutSpeed", putGreeks.speed());

  225.         mapMeasure.put ("PutTheta", putGreeks.theta());

  226.         mapMeasure.put ("PutUltima", putGreeks.ultima());

  227.         mapMeasure.put ("PutVanna", putGreeks.vanna());

  228.         mapMeasure.put ("PutVega", putGreeks.vega());

  229.         mapMeasure.put ("PutVeta", putGreeks.veta());

  230.         mapMeasure.put ("PutVomma", putGreeks.vomma());

  231.         mapMeasure.put ("TTE", dblTTE);

  232.         return mapMeasure;
  233.     }

  234.     /**
  235.      * Imply the Option Volatility given the Call Price
  236.      *
  237.      * @param valParams The Valuation Parameters
  238.      * @param dblUnderlier The Underlier
  239.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  240.      * @param dc Discount Curve
  241.      * @param dblCallPrice The Option Call Price
  242.      *
  243.      * @return The Option's Implied Volatility
  244.      *
  245.      * @throws java.lang.Exception Thrown if Inputs are Invalid
  246.      */

  247.     public double implyVolatilityFromCallPrice (
  248.         final org.drip.param.valuation.ValuationParams valParams,
  249.         final double dblUnderlier,
  250.         final boolean bIsForward,
  251.         final org.drip.state.discount.MergedDiscountForwardCurve dc,
  252.         final double dblCallPrice)
  253.         throws java.lang.Exception
  254.     {
  255.         if (null == valParams || null == dc)
  256.             throw new java.lang.Exception ("EuropeanCallPut::implyVolatilityFromCallPrice => Invalid Inputs");

  257.         int iValueDate = valParams.valueDate();

  258.         int iMaturityDate = _dtMaturity.julian();

  259.         if (iValueDate >= iMaturityDate)
  260.             throw new java.lang.Exception ("EuropeanCallPut::implyVolatilityFromCallPrice => Invalid Inputs");

  261.         double dblTTE = 1. * (iMaturityDate - iValueDate) / 365.25;

  262.         return new org.drip.pricer.option.BlackScholesAlgorithm().impliedVolatilityFromPrice (_dblStrike,
  263.             dblTTE, dc.zero (iMaturityDate), dblUnderlier, false, bIsForward, dblCallPrice);
  264.     }

  265.     /**
  266.      * Imply the Option Volatility given the Put Price
  267.      *
  268.      * @param valParams The Valuation Parameters
  269.      * @param dblUnderlier The Underlier
  270.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  271.      * @param dc Discount Curve
  272.      * @param dblPutPrice The Option Put Price
  273.      *
  274.      * @return The Option's Implied Volatility
  275.      *
  276.      * @throws java.lang.Exception Thrown if Inputs are Invalid
  277.      */

  278.     public double implyVolatilityFromPutPrice (
  279.         final org.drip.param.valuation.ValuationParams valParams,
  280.         final double dblUnderlier,
  281.         final boolean bIsForward,
  282.         final org.drip.state.discount.MergedDiscountForwardCurve dc,
  283.         final double dblPutPrice)
  284.         throws java.lang.Exception
  285.     {
  286.         if (null == valParams || null == dc)
  287.             throw new java.lang.Exception ("EuropeanCallPut::implyVolatilityFromPutPrice => Invalid Inputs");

  288.         int iValueDate = valParams.valueDate();

  289.         int iMaturityDate = _dtMaturity.julian();

  290.         if (iValueDate >= iMaturityDate)
  291.             throw new java.lang.Exception ("EuropeanCallPut::implyVolatilityFromPutPrice => Invalid Inputs");

  292.         double dblTTE = 1. * (iMaturityDate - iValueDate) / 365.25;

  293.         return new org.drip.pricer.option.BlackScholesAlgorithm().impliedVolatilityFromPrice (_dblStrike,
  294.             dblTTE, dc.zero (iMaturityDate), dblUnderlier, true, bIsForward, dblPutPrice);
  295.     }

  296.     /**
  297.      * Retrieve the Set of the Measure Names
  298.      *
  299.      * @return The Set of the Measure Names
  300.      */

  301.     public java.util.Set<java.lang.String> getMeasureNames()
  302.     {
  303.         java.util.Set<java.lang.String> setstrMeasureNames = new java.util.TreeSet<java.lang.String>();

  304.         setstrMeasureNames.add ("BlackScholesCallVolatility");

  305.         setstrMeasureNames.add ("BlackScholesPutVolatility");

  306.         setstrMeasureNames.add ("CalcTime");

  307.         setstrMeasureNames.add ("CallCharm");

  308.         setstrMeasureNames.add ("CallColor");

  309.         setstrMeasureNames.add ("CallDelta");

  310.         setstrMeasureNames.add ("CallGamma");

  311.         setstrMeasureNames.add ("CallPrice");

  312.         setstrMeasureNames.add ("CallProb1");

  313.         setstrMeasureNames.add ("CallProb2");

  314.         setstrMeasureNames.add ("CallRho");

  315.         setstrMeasureNames.add ("CallSpeed");

  316.         setstrMeasureNames.add ("CallTheta");

  317.         setstrMeasureNames.add ("CallUltima");

  318.         setstrMeasureNames.add ("CallVanna");

  319.         setstrMeasureNames.add ("CallVega");

  320.         setstrMeasureNames.add ("CallVeta");

  321.         setstrMeasureNames.add ("CallVomma");

  322.         setstrMeasureNames.add ("DF");

  323.         setstrMeasureNames.add ("EffectiveVolatility");

  324.         setstrMeasureNames.add ("ImpliedCallVolatility");

  325.         setstrMeasureNames.add ("ImpliedPutVolatility");

  326.         setstrMeasureNames.add ("PutCharm");

  327.         setstrMeasureNames.add ("PutColor");

  328.         setstrMeasureNames.add ("PutDelta");

  329.         setstrMeasureNames.add ("PutGamma");

  330.         setstrMeasureNames.add ("PutPrice");

  331.         setstrMeasureNames.add ("PutPriceFromParity");

  332.         setstrMeasureNames.add ("PutProb1");

  333.         setstrMeasureNames.add ("PutProb2");

  334.         setstrMeasureNames.add ("PutRho");

  335.         setstrMeasureNames.add ("PutSpeed");

  336.         setstrMeasureNames.add ("PutTheta");

  337.         setstrMeasureNames.add ("PutUltima");

  338.         setstrMeasureNames.add ("PutVanna");

  339.         setstrMeasureNames.add ("PutVega");

  340.         setstrMeasureNames.add ("PutVeta");

  341.         setstrMeasureNames.add ("PutVomma");

  342.         setstrMeasureNames.add ("TTE");

  343.         return setstrMeasureNames;
  344.     }
  345. }