Jarloo

Menu

Vanilla Option Math

Plain vanilla options (ie: European and American) are the most popular types of options around, and if your working with options you probably need to determine the option greeks at some point.

This class calculates Delta, Gamma, Vega, Theta, Rho, and Cost of Carry.

using System;

namespace JarlooOptionMath
{
    public static class VanillaOptionMath
    {
        public enum CallPutFlag { Call, Put }

        /// <summary>
        /// Calculates Delta
        /// Delta is the options sensitivity to small movements in the underlying asset price.
        /// </summary>
        /// <param name="callPut">Call or Put</param>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>
        /// <param name="r">risk free intrest rate</param>
        /// <param name="b">cost of carry rate</param>
        /// <param name="v">volatility</param>
        /// <returns>Delta</returns>
        public static double Delta(CallPutFlag callPut, double S, double X, double T, double r, double b, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            double d1 = D1(b, S, X, T, v);

            double retval = 0;

            if (callPut == CallPutFlag.Call)
            {
                retval = Math.Exp((b - r) * T) * N(d1);
            }
            else
            {
                retval = Math.Exp((b - r) * T) * (N(d1) - 1);
            }

            return retval;
        }

        /// <summary>
        /// Calculates Gamma
        /// Gamma is the delta's sensitivity to a small movement in the underlying asset price.
        /// Gamma is identical for both call and put options.
        /// </summary>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>
        /// <param name="r">risk free intrest rate</param>
        /// <param name="b">cost of carry rate</param>
        /// <param name="v">volatility</param>
        /// <returns>Gamma</returns>
        public static double Gamma(double S, double X, double T, double r, double b, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            double d1 = D1(b, S, X, T, v);

            double retval = (n(d1) * Math.Exp((b - r) * T)) / (S * v * Math.Sqrt(T));

            return retval;
        }

        /// <summary>
        /// Vega
        /// Vega is the option's sensitivity to a small movement in the volatility of the underlying asset.
        /// Vega is equal for put and call options.
        /// </summary>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>
        /// <param name="r">risk free intrest rate</param>
        /// <param name="b">cost of carry rate</param>
        /// <param name="v">volatility</param>
        /// <returns>Vega</returns>
        public static double Vega(double S, double X, double T, double r, double b, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            double d1 = D1(b, S, X, T, v);

            double retval = S * Math.Exp((b - r) * T) * n(d1) * Math.Sqrt(T);

            return retval;
        }

        /// <summary>
        /// Theta
        /// Theta is the option's sensitivity to a small change in time to maturity. As time to maturity decreases
        /// it is normal to express the theta as minus the partial derivative with respect to time.
        /// </summary>
        /// <param name="callPut">Call or Put</param>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>3
        /// <param name="r">risk free intrest rate</param>
        /// <param name="b">cost of carry rate</param>
        /// <param name="v">volatility</param>
        /// <returns>Theta</returns>
        public static double Theta(CallPutFlag callPut, double S, double X, double T, double r, double b, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            double d1 = D1(b, S, X, T, v);
            double d2 = D2(b, S, X, T, v);

            double retval = 0;

            if (callPut == CallPutFlag.Call)
            {
                retval = -S * Math.Exp((b - r) * T) * n(d1) * v / (2 * Math.Sqrt(T)) -
                    (b - r) * S * Math.Exp((b - r) * T) * N(d1) - r * X * Math.Exp(-r * T) * N(d2);
            }
            else
            {
                retval = -S * Math.Exp((b - r) * T) * n(d1) * v / (2 * Math.Sqrt(T)) +
                    (b - r) * S * Math.Exp((b - r) * T) * N(-d1) + r * X * Math.Exp(-r * T) * N(-d2);
            }

            return retval;
        }

        /// <summary>
        /// Rho
        /// Rho is the option's sensitivity to a small change in the risk-free intrest rate
        /// </summary>
        /// <param name="callPut">Call or Put</param>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>
        /// <param name="r">risk free intrest rate</param>
        /// <param name="b">cost of carry rate</param>
        /// <param name="v">volatility</param>
        /// <returns>Rho</returns>
        public static double Rho(CallPutFlag callPut, double S, double X, double T, double r, double b, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            double retval = 0;

            if (callPut == CallPutFlag.Call)
            {
                if (b != 0)
                {
                    double d2 = D2(b, S, X, T, v);
                    retval = T * X * Math.Exp(-r * T) * N(d2);
                }
                else
                {
                    retval = -T;
                }
            }
            else
            {
                if (b != 0)
                {
                    double d2 = D2(b, S, X, T, v);
                    retval = T * X * Math.Exp(-r * T) * N(-d2);
                }
                else
                {
                    retval = -T;
                }
            }

            return retval;
        }

        /// <summary>
        /// Cost of Carry
        /// This is the option's sensitivity to a marginal change in the cost of carry rate.
        /// </summary>
        /// <param name="callPut">Call or Put</param>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>
        /// <param name="r">risk free intrest rate</param>
        /// <param name="b">cost of carry rate</param>
        /// <param name="v">volatility</param>
        /// <returns>Theta</returns>
        public static double CostOfCarry(CallPutFlag callPut, double S, double X, double T, double r, double b, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            double d1 = D1(b, S, X, T, v);
            double retval = 0;

            if (callPut == CallPutFlag.Call)
            {
                retval = T * S * Math.Exp((b - r) * T) * N(d1);
            }
            else
            {
                retval = -T * S * Math.Exp((b - r) * T) * N(-d1);
            }

            return retval;
        }

        public static double n(double x)
        {
            return 1 / Math.Sqrt(2 * Math.PI) * Math.Exp(-Math.Pow(x, 2) / 2);
        }

        /// <summary>
        /// Cumulative Normalized Distributions
        /// </summary>
        /// <param name="x"></param>
        /// <returns>N</returns>
        public static double N(double x)
        {
            //These are mathematical constants for determining Cumulative normalized distributions
            double a1 = 0.31938153;
            double a2 = -0.356563782;
            double a3 = 1.781477937;
            double a4 = -1.821255978;
            double a5 = 1.330274429;

            double k = 1 / (1 + 0.2316419 * x);

            double retval = 1 - n(x) * (a1 * k + a2 * Math.Pow(k, 2) + a3 *
                    Math.Pow(k, 3) + a4 * Math.Pow(k, 4) + a5 * System.Math.Pow(k, 5));

            if (x < 0) retval = 1 - N(-x);

            return retval;
        }

        /// <summary>
        /// Calculates D1
        /// </summary>
        /// <param name="b">cost of carry rate</param>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>
        /// <param name="v">volatility</param>
        /// <returns>D1</returns>
        private static double D1(double b, double S, double X, double T, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            return (Math.Log(S / X) + (b + Math.Pow(v, 2) / 2) * T) / (v * Math.Sqrt(T));
        }

        /// <summary>
        /// Calculates D2
        /// </summary>
        /// <param name="b">cost of carry rate</param>
        /// <param name="S">futures price</param>
        /// <param name="X">strike price</param>
        /// <param name="T">time to maturity</param>
        /// <param name="v">volatility</param>
        /// <returns>D1</returns>
        private static double D2(double b, double S, double X, double T, double v)
        {
            if (S == 0) throw new ArgumentException("S cannot equal zero", "S");
            if (X == 0) throw new ArgumentException("X cannot equal zero", "X");

            double d1 = D1(b, S, X, T, v);

            return d1 - v * Math.Sqrt(T);
        }
    }
}

 

Categories:   Finance

Comments