2025-05-13 09:11:14
This post is part of a larger series on Option Pricing with Python. In order to get the best out of this article, you should be able to tick the following boxes:
Later articles will build production-ready Finite Difference and Monte Carlo solvers to solve more complicated derivatives.
Python has a reputation primarily as a scripting language, functioning as "glue" between other codebases. The QuantStart team, however, believe that with tools such as Numpy and SciPy it is perfectly capable of being utilised to price options. However, it is yet another language to learn - so why should you invest the time? We have listed the primary benefits below:
The articles to follow will concentrate on simplicity, rather than optimisation. We will follow Daniel Duffy's philosophy of "First we get it working, then we get it right, then we optimise it". To this end, we will initially be focusing on clear and explicit syntax. It should be obvious how we have gone from an algorithm to its implementation, with the minimum of head-scratching. After we have code working, we can make sure it is producing the correct values. Finally, we can optimise it and put it into production.
It has already been outlined that the reader is to be familiar with the Black-Scholes formula for the pricing of European Vanilla Calls and Puts. For completeness, the price of a European Vanilla Call, C(S,t) is given below, where S is the underlying asset, K is the strike price, r
is the risk-free rate, T is the time to maturity and
With
Thanks to Put-Call Parity, we are also able to price a European Vanilla Put P(S,t) with the following formula:
The remaining function we have yet to describe is N. This is the cumulative distribution function of the standard normal distribution. The formula for N is given by:
In addition, we would like to have closed form solutions for the "Greeks", which are the option price sensitivities to the underlying variables and parameters. For this reason we also need the formula for the probability density function of the standard normal distribution which is given below:
Our task is now to utilise Python to implement these functions and provide us with values for the closed-form solution to the price of a European Vanilla Call or Put with their associated sensitivities.
Open a new Python file in your favourite IDE and name it statistics.py. We require some mathematical functions so we will use the math library and import the natural logarithm, the exponential function and the mathematical constant
from math import exp, log, pi
The first function to define is the standard normal distribution probability density function:
def norm_pdf(x):
"""
Standard normal probability density function
"""
return (1.0/((2*pi)**0.5))*exp(-0.5*x*x)
This function is fairly self-explanatory. The next function to code up is the CDF of the normal distribution. However, it contains an integral with
def norm_cdf(x):
"""
An approximation to the cumulative distribution
function for the standard normal distribution:
N(x) = \frac{1}{sqrt(2*\pi)} \int^x_{-\infty} e^{-\frac{1}{2}s^2} ds
"""
k = 1.0/(1.0+0.2316419*x)
k_sum = k * (0.319381530 + k * (-0.356563782 + \
k * (1.781477937 + k * (-1.821255978 + 1.330274429 * k))))
if x >= 0.0:
return (1.0 - (1.0 / ((2 * pi)**0.5)) * exp(-0.5 * x * x) * k_sum)
else:
return 1.0 - norm_cdf(-x)
Notice that this function calls itself if x is negative.
We now have the two statistical functions necessary for calculating the closed-form options prices for European vanilla calls and puts.
We need to create a second file, which we will call closed_form.py. It should reside in the same file directory as the statistics.py file in order for the following import syntax to work correctly:
from math import exp, log, sqrt
from statistics import norm_pdf, norm_cfd
Referring back to the Black-Scholes formula for the price of a call, C(S,t), we can see that it requires two separate functions named
def d_j(j, S, K, r, v, T):
"""
d_j = \frac{log(\frac{S}{K})+(r+(-1)^{j-1} \frac{1}{2}v^2)T}{v sqrt(T)}
"""
return (log(S/K) + (r + ((-1)**(j-1))*0.5*v*v)*T)/(v*(T**0.5))
All that remains now is to code up the functions for C(S,t) and P(S,t). The Python code for C(S,t) is provided below:
def vanilla_call_price(S, K, r, v, T):
"""
Price of a European call option struck at K, with
spot S, constant rate r, constant vol v (over the
life of the option) and time to maturity T
"""
return S * norm_cdf(d_j(1, S, K, r, v, T)) - \
K*exp(-r*T) * norm_cdf(d_j(2, S, K, r, v, T))
Finally, the code for P(S,t):
def vanilla_put_price(S, K, r, v, T):
"""
Price of a European put option struck at K, with
spot S, constant rate r, constant vol v (over the
life of the option) and time to maturity T
"""
return -S * norm_cdf(-d_j(1, S, K, r, v, T)) + \
K*exp(-r*T) * norm_cdf(-d_j(2, S, K, r, v, T))
This concludes the coding of formulae for the statistical distribution functions in statistics.py and the vanilla call option prices in closed_form.py. At this stage it is prudent to check that the formulae produce the correct results and satisfy the known bounds on the prices (such as Put-Call Parity). That will be the subject of a future article.
Reference: European Vanilla Call-Put Option Pricing with Python
From https://www.quantstart.com/articles/European-Vanilla-Call-Put-Option-Pricing-with-Python/
2025-01-10 10:12:01
2024-05-31 03:06:49
2024-05-28 03:09:25
There are many other interesting articles, try selecting them from below.
2024-01-11 04:45:59
2023-10-10 11:38:54
2023-11-21 09:27:00
2024-03-19 09:28:34
2024-04-23 05:12:21
2023-09-06 11:48:34
2025-04-17 06:40:38
2024-11-06 11:24:26