Package for deploying lattice models for option pricing
PyOptionTree
PyOptionTree is a package designed for implementing lattice models for option pricing.
The objective of this package is to provide an intuitive and easy-to-implement open-source tool for students, academics and practioners to run theoretical pricing of various simple and exotic options. The early version of the library shall focus on developing the Binomial Tree algorithm for option pricing, taking into account of dividends and various types of options.
Version: v0.2.3.
Table of contents
- Underlying asset price dynamics - Trading days - Dividends and yield treatment - European options - American options - Visualizing the tree - Calibration - Exotic optionsGetting Started
PyOptionTree is currently available on the test environment only. While we are working to push out the project into production, we welcome users to try the test version and provide us feedback on the library.
For test version, one can download the package by:
pip install -i https://test.pypi.org/simple/ PyOptionTree
A quick example
Here is a quick example of setting up the tree model. Here, we will show how one can initialize the underlying asset and plot the binomial tree of the underlying asset price dynamics.
import pyop3
Initialize the binomial tree object
asset1 = pyop3.binomialtree(300, 0.08, 0.3333, sigma = 0.3)
View underlying asset information
asset1.underlyingasset_summary()
The output of the above:
UNDERLYING ASSET SUMMARY
+--------------------------------+
Spot price: $300.00
Time to expiry: 0.3333 years
interest rate: 8.00%
implied vol: 30.00%
No dividend payment expected during the course of the contract.
To retrieve the raw version of the underlying asset price lattice:
# Generate lattice of the underlying asset prices
asset1tree = asset1.underlyingasset_tree()
print(asset1tree)
Output:
[[300. 327.13753696 356.72989363 388.99912921 424.18739004]
[ 0. 275.11364436 300. 327.13753696 356.72989363]
[ 0. 0. 252.29172437 275.11364436 300. ]
[ 0. 0. 0. 231.36298578 252.29172437]
[ 0. 0. 0. 0. 212.17038062]]
The raw version of the underlying asset lattice is convenient for computation, but is hard for users to read. PyOptionTree has a function which allows one to plot the tree:
# Visualize the tree in a graphic for better illustration pyop3.treeplanter.showtree(asset1tree, "Binomial Tree Price Development of Underlying Asset")
Output:

Overview of Binomial tree option pricing models
The Binomial tree algorithm was first introduced by Cox et. al in their 1979 paper "Option Pricing: A Simplified Approach". The tree model, famously known as the Cox-Ross-Rubinstein Tree (or CRR Tree for short) offers readers a simple-to-understand approach to option pricing while adhering to the no-arbitrage condition. Its simplistic and elegant approach may be what caused its to be mistaken as the predecessor of the Black-Scholes model (which was infact founded in 1973) by beginners. It also doesn't help that the CRR Tree is commonly used as the primer to option pricing for most financial mathematics and derivatives courses.
The steps to applying the binomial tree pricing algorithm are fairly straightforward; starting with the spot price $S_0$, to price a European option,
- Define the upward multiplier $u$, which results in a price level $S{(1,2)}^u$ which is higher than $S0$, and the corresponding downward multiplier $d$ to get the lower price level $S_{(1,1)}^d$; these represents the potential upside and downside of the underlying asset, which gives us two states in the next time step
- With $u$ and $d$ defined, calculate the risk neutral probability of an upward movement $p$; $p$ is risk-neutral as the discounted mean of the two states in the next time step will be equal to the current price
- Now work forward into the next $N$ steps; this creates a lattice where each node represents a price level, starting with $S0$, and from each node there exists two branches that lead to two states - one the upside state $S{(i,j)}^u$ and the other the downside state $S_{(i,j)}^d$; $i$ refers to the time step of the node, $j$ refers to the node number in that time step
- Apply the option payoff function at time $T$ on all the terminal states represented by the terminal nodes
- Finally, work backwards by taking the discounted mean of option payoff at the terminal nodes; this will give us the required option value
$$u = e^{\sigma \sqrt{T}}, d = e^{- \sigma \sqrt{T}}, p = \frac{e^{r \Delta t} - d}{u - d}$$
In the same year, Rendleman and Bartter also provided their suggestions of the Binomial tree option pricing algorithm. It looks similar to that of the CRR tree, except that it restricts the risk-neutral probability to $p = 0.5$. This means that the log-tree is no longer symmetrical about the spot price at time 0.
$$p = \frac{1}{2}, u = e^{(r-0.5\sigma^2)\Delta t + \sigma \sqrt{\Delta t}}, d = e^{(r-0.5\sigma^2)\Delta t - \sigma \sqrt{\Delta t}}$$
The RB tree has upward and downward movements similar to the discrete version of the Black-Schole model of asset price dynamic, which takes the form
$$S{t + \Delta t} = S0e^{(r - 0.5 \sigma^2)\Delta t + \sigma (W{t+\Delta t} - Wt)}$$
currently allows implementation of both the CRR tree and the RB tree. In order to support both academic and practical use-cases, has incorporated the following features.
Features
This section documents the features of PyOptionTree, with brief introduction of each features. A comprehensive demonstration of the PyOptionTree may be found in the tutorials here.Underlying asset price dynamics
Similar to the basic approach to binomial tree option pricing, all impementation of option pricing starts with creating the binomial tree to illustrate the underlying asset price dynamics. The below image summarizes the implementation of the PyOptionTree.
- Define expiry and number of discrete steps during the contract lifetime:
- Define type of binomial tree
- Define upward and downward multipliers, $u$ and $d$
- yield rate (dividend yield rate, foreign interest rate)
does not support yield rate; this limits application to strictly equity-liked assets
- This will be part of the improvement pipeline
Trading days
Embedded into the PyOptionTree library and also callable as a function, PyOptionTree offers a simple-to-use solution for calculating the number of trading days between two distinct dates. User simply needs to provide the start date, end date, and a collection of trading holidays for this to work.nbrtradingdays = pyop3.tools.gettradingdays('01-12-2020', '10-01-2021',\
trading_holidays = ['24-12-2020', '25-12-2020',\
'31-12-2020', '01-01-2021'])
print(nbrtradingdays)
Output:
25
Future improvement to the function may include connecting to a reliable trading calendar source to automatically retrieve the trading holidays.
Dividends treatment
PyOptionTree supports inclusion of known dollar dividends (up to only one dividend payment during the option lifetime) and known yield.- Known dollar dividends
or the step which ex-div occurs
- Due to non-recombining nature of the tree for dividends occuring midpoint, an approximation method is introduced to force tree recombination
- Approximation method will be enhanced and improved based on known research papers in future improvement
- Module will be enhanced to accomodate multiple known dollar dividends to account for option on dividend-paying asset with long time-to-expiry
European options
European option pricing is the core of binomial tree model. To initiate the European Option pricing, user needs to initialize the.europeanoption object by passing the .binomialtree object and the strike price.
strike = 300
myeuropeanoption = pyop3.europeanoption(asset1, strike)
PyOptionTree computes option prices with two methods.
- Distinctly calling the
or()
methods to derive call and put values respectively()
and respectively
# To calculate call value, we need to first run the .call() method of the option object
asset1options.call()
print(asset1options.call_value)
Output
23.377924012466476
Do note that the option price above is likely inaccurate as we are using the default number of time steps (4) which is not sufficient to converge to the analytical solution.
- Calculate both call and put option values using the
method()
# Calculate call and put option values using fast method
myeuropeanoption.fastputcall()
Output
{'call': 23.377924012466476, 'put': 15.484427768048135}
American options
Binomial tree option pricing model really shines when it comes to deriving the value of American options. Similar to the European option, user needs to initialize the.americanoption object by passing the .binomialtree object and the strike price.
As American options requires working backwards on every nodes in each time step, there is only one method to calculate call and put options, which is by explicitly calling the () and () methods.
Visualizing the tree
One value PyOptionTree offers its users is that the rendering of the binomial tree can be easily called by using its function.treeplanter.showtree().
User simply needs to pass the numpy array which represents the lattice. The function currently offers some customizations, including setting the title of the plot, changing the node colors, among others.
This function builds on top of
and .pyplot libraries. The function currently does not work with subplots.
Calibration
To enhance usability of PyOptionTree, two calibrations are embedded in the functionalities.- Calibrating to market data
.binomialtree object with the calibrated and
- The calibrated values can be used to price more exotic options
- Deamericanization
Exotic options
Exotic options are currently in the project pipeline and will be released in due time.Advantages of PyOptionTree
- designed to be easy-to-use by users with varied python programming experience
- incorporated concepts based on intensive academic research papers
- structured to accomodate practical implementations
- interoperable with proprietary models via Python
Contributing
We welcome contributions from the community! More will be shared on how contributions to the package can be made.
PyOptionTree is currently maintained by:
- Caden Lee
Getting in touch
If you experience any problem with PyOptionTree, please raise a GitHub issue. You may get in touch with me at: caden.finsinyur@gmail.com