Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/cached-venv/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ runs:
using: composite
steps:
- name: Cache virtual environment
uses: actions/cache@v2
uses: actions/cache@v4
env:
cache-name: cache-venv-1
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ __pycache__
dist
run_check
*.old
runpdoc.bat
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# CHANGELOG

## 1.4.3 (2025-04-14)

- Updated docstrings.
- Added documentation with `pdoc`.
- Changed __init__.py for compatibility with `pdoc` autodocumentation.
- Removed `BaseLeg` from models.py.
- Changed `StrategyType` to `StrategyLegType` in models.py for clarity.
- Removed "normal" as an alias for "black-scholes" to avoid confusion with Bachelier model.
- Updated Readme.md.

## 1.4.2 (2025-01-25)

- Removed `expected_profit` and `expected_loss` calculation from `_get_pop_bs` in support.py; implementation was not correct, giving wrong results when compared with Monte Carlo simulations
Expand Down
66 changes: 8 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
![OptionLab](optionlab.png)

# OptionLab

This package is a lightweight library written entirely in Python, designed to provide
quick evaluation of option strategies.
quick evaluation of option strategy ideas.

The code produces various outputs, including the profit/loss profile of the strategy on
a user-defined target date, the range of stock prices for which the strategy is
Expand All @@ -10,22 +12,16 @@ each leg of the strategy using the Black-Sholes model, the resulting debit or cr
trading account, the maximum and minimum returns within a specified lower and higher price
range of the underlying asset, and an estimate of the strategy's probability of profit.

The probability of profit (PoP) on the user-defined target date for the strategy is calculated
by default using the Black-Scholes model. Alternatively, the user can provide an array of
underlying asset prices following a distribution other than the normal (e.g. Laplace) or
model other than the Black-Scholes model (e.g. Heston model) that will be used in the calculations.

Despite the code having been developed with option strategies in mind, it can also be
used for strategies that combine options with stocks and/or take into account the
profits or losses of closed trades.

If you have any questions, corrections, comments or suggestions, just
[drop a message](mailto:[email protected]).

You can also reach me on [Linkedin](https://www.linkedin.com/in/roberto-gomes-phd-8a718317b/) or
follow me on [X](https://x.com/rgaveiga). When I have some free time, which is rare, I publish articles
on [Medium](https://medium.com/@rgaveiga).

If you want to support this and other open source projects that I maintain, become a
[sponsor on Github](https://github.com/sponsors/rgaveiga).

## Installation

The easiest way to install **OptionLab** is using **pip**:
Expand All @@ -34,55 +30,9 @@ The easiest way to install **OptionLab** is using **pip**:
pip install optionlab
```

## Basic usage

The evaluation of a strategy is done by calling the `run_strategy` function provided by
the library. This function receives the input data either as a Python dictionary or an
`Inputs` object. For example, let's say we wanted to calculate the probability of profit
for naked calls on Apple stocks with maturity on December 17, 2021. The strategy setup
consisted of selling 100 175.00 strike calls for 1.15 each on November 22, 2021.

```python
input_data = {
"stock_price": 164.04,
"start_date": "2021-11-22",
"target_date": "2021-12-17",
"volatility": 0.272,
"interest_rate": 0.0002,
"min_stock": 120,
"max_stock": 200,
"strategy": [
{
"type": "call",
"strike": 175.0,
"premium": 1.15,
"n": 100,
"action":"sell"
}
],
}
```

After defining the input data as a Python dictionary, we pass it to the `run_strategy`
function as shown below:

```python
from optionlab import run_strategy, plot_pl

out = run_strategy(input_data)

print(out)

plot_pl(out)
```

The variable `out` is an `Outputs` object that contains the results from the
calculations. By calling `print` with `out` as an argument, these results are
displayed on screen. The `plot_pl` function, in turn, takes an `Outputs` object as
its argument and plots the profit/loss diagram for the strategy.
## Documentation

Usage examples for a number of popular options trading strategies can be found in the
Jupyter notebooks in the **examples** directory.
You can access the API documentation for **OptionLab** on the [project's GitHub Pages site](https://rgaveiga.github.io/optionlab).

## Contributions

Expand Down
7 changes: 7 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=./optionlab.html"/>
</head>
</html>
675 changes: 675 additions & 0 deletions docs/optionlab.html

Large diffs are not rendered by default.

Binary file added docs/optionlab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,608 changes: 1,608 additions & 0 deletions docs/optionlab/black_scholes.html

Large diffs are not rendered by default.

764 changes: 764 additions & 0 deletions docs/optionlab/engine.html

Large diffs are not rendered by default.

3,837 changes: 3,837 additions & 0 deletions docs/optionlab/models.html

Large diffs are not rendered by default.

Binary file added docs/optionlab/optionlab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
640 changes: 640 additions & 0 deletions docs/optionlab/plot.html

Large diffs are not rendered by default.

434 changes: 434 additions & 0 deletions docs/optionlab/price_array.html

Large diffs are not rendered by default.

1,219 changes: 1,219 additions & 0 deletions docs/optionlab/support.html

Large diffs are not rendered by default.

542 changes: 542 additions & 0 deletions docs/optionlab/utils.html

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions docs/search.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/black_scholes_calculator.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"output_type": "stream",
"text": [
"Python version: 3.11.9 | packaged by Anaconda, Inc. | (main, Apr 19 2024, 16:40:41) [MSC v.1916 64 bit (AMD64)]\n",
"OptionLab version: 1.4.2\n"
"OptionLab version: 1.4.3\n"
]
}
],
Expand Down Expand Up @@ -106,7 +106,7 @@
"output_type": "stream",
"text": [
"CPU times: total: 0 ns\n",
"Wall time: 0 ns\n"
"Wall time: 4 ms\n"
]
}
],
Expand Down
6 changes: 3 additions & 3 deletions examples/calendar_spread.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"output_type": "stream",
"text": [
"Python version: 3.11.9 | packaged by Anaconda, Inc. | (main, Apr 19 2024, 16:40:41) [MSC v.1916 64 bit (AMD64)]\n",
"OptionLab version: 1.4.2\n"
"OptionLab version: 1.4.3\n"
]
}
],
Expand Down Expand Up @@ -119,8 +119,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: total: 406 ms\n",
"Wall time: 492 ms\n"
"CPU times: total: 375 ms\n",
"Wall time: 485 ms\n"
]
}
],
Expand Down
12 changes: 6 additions & 6 deletions examples/call_spread.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: total: 29.4 s\n",
"Wall time: 30.4 s\n"
"CPU times: total: 39.8 s\n",
"Wall time: 42.4 s\n"
]
}
],
Expand Down Expand Up @@ -269,7 +269,7 @@
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1d2b13e4b50>]"
"[<matplotlib.lines.Line2D at 0x1d7a0247250>]"
]
},
"execution_count": 9,
Expand Down Expand Up @@ -383,8 +383,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: total: 29.6 s\n",
"Wall time: 30.9 s\n"
"CPU times: total: 39.5 s\n",
"Wall time: 42.3 s\n"
]
}
],
Expand Down Expand Up @@ -488,7 +488,7 @@
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1d2b35ec450>]"
"[<matplotlib.lines.Line2D at 0x1d7a2447bd0>]"
]
},
"execution_count": 15,
Expand Down
8 changes: 4 additions & 4 deletions examples/covered_call.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"output_type": "stream",
"text": [
"Python version: 3.11.9 | packaged by Anaconda, Inc. | (main, Apr 19 2024, 16:40:41) [MSC v.1916 64 bit (AMD64)]\n",
"OptionLab version: 1.4.2\n"
"OptionLab version: 1.4.3\n"
]
}
],
Expand Down Expand Up @@ -119,8 +119,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: total: 203 ms\n",
"Wall time: 205 ms\n"
"CPU times: total: 281 ms\n",
"Wall time: 258 ms\n"
]
}
],
Expand All @@ -142,7 +142,7 @@
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x2e55fd93910>"
"<matplotlib.legend.Legend at 0x1e0346f7f90>"
]
},
"execution_count": 5,
Expand Down
6 changes: 3 additions & 3 deletions examples/naked_call.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"output_type": "stream",
"text": [
"Python version: 3.11.9 | packaged by Anaconda, Inc. | (main, Apr 19 2024, 16:40:41) [MSC v.1916 64 bit (AMD64)]\n",
"OptionLab version: 1.4.2\n"
"OptionLab version: 1.4.3\n"
]
}
],
Expand Down Expand Up @@ -116,8 +116,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: total: 141 ms\n",
"Wall time: 125 ms\n"
"CPU times: total: 328 ms\n",
"Wall time: 338 ms\n"
]
}
],
Expand Down
Binary file added optionlab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading