{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load Packages and Extra Functions"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"printyellow (generic function with 1 method)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using Printf, Distributions, OffsetArrays, FiniteDiff\n",
"\n",
"#using FiniteDiff: finite_difference_derivative as derivative #could do this instead\n",
"\n",
"include(\"jlFiles/OptionsCalculations.jl\")\n",
"include(\"jlFiles/printmat.jl\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"using Plots\n",
"#pyplot(size=(600,400))\n",
"gr(size=(480,320))\n",
"default(fmt = :svg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Black-Scholes Model\n",
"\n",
"The next cell calculates call `C` and put prices `P` from the Black-Scholes formula.\n",
"\n",
"The key parameters are:\n",
"`(S,K,m,y,σ) = (current undelying price, strike price,time to expiration,interest rate, volatility)`"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"call price at K=42: 2.893 \n",
"\n",
"put price at K=42: 1.856 \n",
"\n"
]
}
],
"source": [
"(S,K,m,y,σ) = (42,42,0.5,0.05,0.2)\n",
"\n",
"C = OptionBlackSPs(S,K,m,y,σ)\n",
"printlnPs(\"call price at K=$K: \",C,\"\\n\")\n",
"\n",
"P = OptionBlackSPs(S,K,m,y,σ,0,true)\n",
"printlnPs(\"put price at K=$K: \",P,\"\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Task 1\n",
"\n",
"For a range of different prices of the underlying asset `S=30:60`, calculate the call and put prices and plot them (with `S` on the hoizontal axis)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"S_range = range(30.0,60,step=1) #different spot prices\n",
"C_S_range = OptionBlackSPs.(S_range,K,m,y,σ)\n",
"P_S_range = OptionBlackSPs.(S_range,K,m,y,σ,0,true)\n",
"\n",
"p1 = plot( S_range,[C_S_range P_S_range],\n",
" linecolor = [:red :blue],\n",
" label = [\"call\" \"put\"],\n",
" title = \"Black-Scholes call option price, K = $K\",\n",
" xlabel = \"current asset price\",\n",
" ylabel = \"option price\" )\n",
"display(p1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Binomial Option Pricing Model\n",
"\n",
"The next cell contains functions to implement a binomial option pricing model for European style (exercise at expiration only) and American style (exercise any day) options. We use the CRR (Cox-Ross-Rubinstein) parameterisation.\n",
"\n",
"The key parameters are the same as before, but also `n` which is the number of time steps used in the calculations (which defaults to 250)."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"BOPM_American (generic function with 3 methods)"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"\"\"\n",
"CRRparams(σ,m,n,y)\n",
"\n",
" BOPM parameters according to CRR\n",
"\"\"\"\n",
"function CRRparams(σ,m,y,n)\n",
" h = m/n #time step size (in years)\n",
" u = exp(σ*sqrt(h)) #up move\n",
" d = exp(-σ*sqrt(h)) #down move\n",
" p = (exp(y*h) - d)/(u-d) #rn prob of up move\n",
" return h,u,d,p\n",
"end \n",
"\n",
"function BOPM_European(S,K,m,y,σ,isPut=false,n=250)\n",
" (h,u,d,p) = CRRparams(σ,m,y,n)\n",
" STree = BuildSTree(S,n,u,d)\n",
" price = EuOptionPrice(STree,K,y,h,p,isPut)[0][]\n",
" return price\n",
"end\n",
"\n",
"function BOPM_American(S,K,m,y,σ,isPut=false,n=250)\n",
" (h,u,d,p) = CRRparams(σ,m,y,n)\n",
" STree = BuildSTree(S,n,u,d)\n",
" price = AmOptionPrice(STree,K,y,h,p,isPut)[1][0][1]\n",
" return price\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"call (Eu) 2.891\n",
"put (Eu) 1.854\n",
"call (Am) 2.891\n",
"put (Am) 1.954\n",
"\n",
"\u001b[31m\u001b[1mNotice that c_e=c_a but that p_a>=p_e\u001b[22m\u001b[39m\n"
]
}
],
"source": [
"c_e = BOPM_European(S,K,m,y,σ,false) #call price, European style\n",
"p_e = BOPM_European(S,K,m,y,σ,true) #put price, European\n",
"\n",
"c_a = BOPM_American(S,K,m,y,σ,false) #call, American\n",
"p_a = BOPM_American(S,K,m,y,σ,true) #put, American\n",
"\n",
"printmat([c_e,p_e,c_a,p_a],rowNames=[\"call (Eu)\",\"put (Eu)\",\"call (Am)\",\"put (Am)\"])\n",
"\n",
"printred(\"Notice that c_e=c_a but that p_a>=p_e\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Task 2\n",
"\n",
"Redo the calculation of p_e and p_a for `S=30:60` and plot the prices."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"p_e = BOPM_European.(S_range,K,m,y,σ,true)\n",
"p_a = BOPM_American.(S_range,K,m,y,σ,true)\n",
"\n",
"p1 = plot( S_range,[p_e p_a],\n",
" linecolor = [:red :blue],\n",
" label = [\"European\" \"American\"],\n",
" title = \"BOPM put option prices, K=$K\",\n",
" xlabel = \"current asset price\",\n",
" ylabel = \"option price\" )\n",
"display(p1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Delta\n",
"\n",
"To hedge an option contract (eg. if we are short one option contract), we buy $\\Delta$ units of the underlying asset, where $\\Delta$ is the partial derivative of the option price with respect to the price of the underlying asset.\n",
"\n",
"Calculate $\\Delta$ for both the European and American puts, using the BOPM function. Do the calculation for each value in `S_range` and plot the results.\n",
"\n",
"To calculate the derivatives we use \n",
"`FiniteDiff.finite_difference_derivative(the function,an S value)`"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"L = length(S_range)\n",
"(Δp_e,Δp_a) = [fill(NaN,L) for _=1:2]\n",
"for i = 1:L\n",
" Δp_e[i] = FiniteDiff.finite_difference_derivative( z->BOPM_European(z,K,m,y,σ,true),S_range[i] )\n",
" Δp_a[i] = FiniteDiff.finite_difference_derivative( z->BOPM_American(z,K,m,y,σ,true),S_range[i] )\n",
"end\n",
"\n",
" #this would also work, no need for a loop\n",
" #FiniteDiff.finite_difference_derivative( z->BOPM_European.(z,K,m,y,σ,true),S_range,Val{:central} )"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"p1 = plot( S_range,[Δp_e Δp_a],\n",
" linecolor = [:red :blue],\n",
" label = [\"European\" \"American\"],\n",
" title = \"Δ of BOPM put option prices, K=$K\",\n",
" xlabel = \"current asset price\",\n",
" ylabel = \"Δ\" )\n",
"display(p1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"@webio": {
"lastCommId": null,
"lastKernelId": null
},
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Julia 1.7.0",
"language": "julia",
"name": "julia-1.7"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}