{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#iPython Cookbook - Analytic Pricing\n", ">A collection of various analytic pricing formulas, to be added to as and when needed" ] }, { "cell_type": "code", "execution_count": 148, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Black Scholes Pricing - Simple\n", "### European Call Option\n", "In the below formula, $K$ is the option strike, and $T$ its maturity (in years). $df$ and $F$ are the discount factor to maturity and the forward at maturity respectively (in absence of dividends / foreign interest $df\\times F$ equals the spot price), and $\\sigma$ is the annualised volatility (eg 0.2 for 20%)\n", "\n", "$$\n", "\\begin{eqnarray}\n", "\\mathrm{Call}(K,T; df,F,\\sigma) &=& df \\times (F N(d_1) - K N(d_2)) \\\\\n", "d_1 &=& \\frac{\\ln (F/K) + 0.5 \\sigma^2 T}{\\sigma \\sqrt{T}} \\\\\n", "d_2 &=& \\frac{\\ln (F/K) - 0.5 \\sigma^2 T}{\\sigma \\sqrt{T}}\n", "\\end{eqnarray}\n", "$$\n" ] }, { "cell_type": "code", "execution_count": 149, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.987761167674492" ] }, "execution_count": 149, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.stats import norm\n", "\n", "def bscall(strike=100,mat=1,fwd=100,sig=0.1,df=1):\n", " lnfs = log(1.0*fwd/strike)\n", " sig2t = sig*sig*mat\n", " sigsqrt = sig*sqrt(mat)\n", " d1 = (lnfs + 0.5 * sig2t) / sigsqrt\n", " d2 = (lnfs - 0.5 * sig2t) / sigsqrt\n", " fv = fwd * norm.cdf (d1) - strike * norm.cdf (d2)\n", " return df * fv\n", "\n", "bscall(fwd=100, strike=100, sig=0.1, mat=1, df=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### European Put Option\n", "In the below formula, $K$ is the option strike, and $T$ its maturity (in years). $df$ and $F$ are the discount factor to maturity and the forward at maturity respectively (in absence of dividends / foreign interest $df\\times F$ equals the spot price), and $\\sigma$ is the annualised volatility (eg 0.2 for 20%)\n", "\n", "$$\n", "\\begin{eqnarray}\n", "\\mathrm{Put}(K,T; df,F,\\sigma) &=& df \\times (K N(-d_2) - F N(-d_1)) \\\\\n", "d_1 &=& \\frac{\\ln (F/K) + 0.5 \\sigma^2 T}{\\sigma \\sqrt{T}} \\\\\n", "d_2 &=& \\frac{\\ln (F/K) - 0.5 \\sigma^2 T}{\\sigma \\sqrt{T}}\n", "\\end{eqnarray}\n", "$$" ] }, { "cell_type": "code", "execution_count": 150, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.987761167674492" ] }, "execution_count": 150, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.stats import norm\n", "\n", "def bsput(strike=100,mat=1,fwd=100,sig=0.1,df=1):\n", " lnfs = log(1.0*fwd/strike)\n", " sig2t = sig*sig*mat\n", " sigsqrt = sig*sqrt(mat)\n", " d1 = (lnfs + 0.5 * sig2t) / sigsqrt\n", " d2 = (lnfs - 0.5 * sig2t) / sigsqrt\n", " fv = strike * norm.cdf (-d2) - fwd * norm.cdf (-d1)\n", " return df * fv\n", "\n", "bsput(fwd=100, strike=100, sig=0.1, mat=1, df=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### European Digital\n", "The standard European digital call option pays one unit of the currency if and only if the spot price at expiry as above the strike $K$, ie the payoff is a step function. The price is given by the following formula ($d_2$ is defined as above)\n", "$$\n", "\\mathrm{DCall}(K,T;df,F,\\sigma)=df\\times N(d_2)\n", "$$\n", "The price for a digitial put is $df\\times(1-N(d_2))$" ] }, { "cell_type": "code", "execution_count": 151, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(0.48006119416162751, 0.51993880583837249)" ] }, "execution_count": 151, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.stats import norm\n", "\n", "def bsdcall(strike=100,mat=1,fwd=100,sig=0.1,df=1):\n", " lnfs = log(1.0*fwd/strike)\n", " sig2t = sig*sig*mat\n", " sigsqrt = sig*sqrt(mat)\n", " d2 = (lnfs - 0.5 * sig2t) / sigsqrt\n", " fv = norm.cdf(d2)\n", " return df * fv\n", "\n", "def bsdput(strike=100,mat=1,fwd=100,sig=0.1,df=1):\n", " lnfs = log(1.0*fwd/strike)\n", " sig2t = sig*sig*mat\n", " sigsqrt = sig*sqrt(mat)\n", " d2 = (lnfs - 0.5 * sig2t) / sigsqrt\n", " fv = 1.0 - norm.cdf(d2)\n", " return df * fv\n", "\n", "bsdcall(fwd=100, strike=100, sig=0.1, mat=1, df=1), bsdput(fwd=100, strike=100, sig=0.1, mat=1, df=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The reverse European digital call option pays one unit of the underlying asset if and only if the spot price at expiry as above the strike $K$. The price is given by the following formula ($d_1$ is defined as above)\n", "$$\n", "\\mathrm{RDCall}(K,T;df,F,\\sigma)=df\\times F \\times N(d_1)\n", "$$\n", "The price for the corresponding put is as above. Note that in the absence of dividends / foreign interest $df\\times F=S$" ] }, { "cell_type": "code", "execution_count": 152, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(51.993880583837246, 48.006119416162754)" ] }, "execution_count": 152, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.stats import norm\n", "\n", "def bsdrcall(strike=100,mat=1,fwd=100,sig=0.1,df=1):\n", " lnfs = log(1.0*fwd/strike)\n", " sig2t = sig*sig*mat\n", " sigsqrt = sig*sqrt(mat)\n", " d1 = (lnfs + 0.5 * sig2t) / sigsqrt\n", " fv = fwd * norm.cdf (d1)\n", " return df * fv\n", "\n", "def bsdrput(strike=100,mat=1,fwd=100,sig=0.1,df=1):\n", " lnfs = log(1.0*fwd/strike)\n", " sig2t = sig*sig*mat\n", " sigsqrt = sig*sqrt(mat)\n", " d1 = (lnfs + 0.5 * sig2t) / sigsqrt\n", " fv = fwd * (1.0 - norm.cdf (d1))\n", " return df * fv\n", "\n", "bsdrcall(fwd=100, strike=100, sig=0.1, mat=1, df=1), bsdrput(fwd=100, strike=100, sig=0.1, mat=1, df=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Licence and version\n", "*Copyright Stefan Loesch / oditorium 2014; all rights reserved*\n", "\n", "License: [AGPL v3.0](https://github.com/oditorium/blog/blob/master/LICENSE)" ] }, { "cell_type": "code", "execution_count": 160, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.4.0 (default, Apr 11 2014, 13:05:11) \n", "[GCC 4.8.2]\n" ] } ], "source": [ "import sys\n", "print(sys.version)" ] }, { "cell_type": "code", "execution_count": 160, "metadata": { "collapsed": false }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }