Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repo Overhaul: Updated the strike price range and deploying instructions with Docker #13

Merged
merged 20 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8789ce1
updated dockerfile
shreyashguptas Aug 26, 2024
d79e20d
updated streamlit app to be able to calculate
shreyashguptas Aug 26, 2024
120d34c
Replacing all .py files with one .ipynb file
shreyashguptas Aug 26, 2024
f6320ab
pip upgrading from 21.1.3 to 24.2
shreyashguptas Aug 26, 2024
cf844e0
Prepping jupyter notebook and installing jupyter notebook kernel
shreyashguptas Aug 26, 2024
e218356
adding build and run commands to dockerfile
shreyashguptas Aug 26, 2024
3d6acff
updating code to fix Ticker fetch
shreyashguptas Aug 26, 2024
da75de6
Deleting venv and ipynb because streamlit needs .py
shreyashguptas Aug 26, 2024
e71224e
refactoring and still working on fixing the ticker issue
shreyashguptas Aug 26, 2024
4d8773c
Removing unnecessary comments and updating to Close price from Adj Cl…
shreyashguptas Aug 26, 2024
719f089
updating streamlit app for better error management
shreyashguptas Aug 29, 2024
113b9ff
Descriptions to each variable + fetching current asset price for bett…
shreyashguptas Aug 29, 2024
8418efb
updating streamlit version
shreyashguptas Aug 29, 2024
0d8880b
adding code that shows the calculation steps
shreyashguptas Aug 29, 2024
1aec5d3
rolling back on streamlit version
shreyashguptas Aug 29, 2024
e5dac9b
updating readme
shreyashguptas Aug 30, 2024
046c248
refactoring the Readme for better readability
shreyashguptas Aug 30, 2024
bbc9a15
removing the calculation showing step
shreyashguptas Aug 30, 2024
911adcd
updating working gif of all models
shreyashguptas Aug 30, 2024
270fec9
adding google cloud support
shreyashguptas Aug 30, 2024
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
Binary file added .DS_Store
Binary file not shown.
13 changes: 10 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
FROM python:3.7
FROM python:3.9

COPY . /app

WORKDIR /app

RUN pip install -r Requirements.txt
RUN pip install --no-cache-dir -U pip && \
pip install --no-cache-dir -r Requirements.txt

EXPOSE 8080

CMD streamlit run --server.port 8080 --server.enableCORS false streamlit_app.py
CMD ["streamlit", "run", "--server.port", "8080", "--server.address", "0.0.0.0", "streamlit_app.py"]

# build command
# docker build -t options-pricing:latest .

# run command
# docker run -p 8080:8080 options-pricing:latest
156 changes: 85 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,102 +1,116 @@
# Option Pricing Models

## Introduction
This repository represents simple web app for calculating option prices (European Options). It uses three different methods for option pricing:
1. Black-Scholes model
2. Monte Carlo simulation
3. Binomial model
## Introduction
This repository contains a simple web app for calculating European option prices using three different methods:

Each model has various parameters that user needs to import:
1. Black-Scholes model
2. Monte Carlo simulation
3. Binomial model

- Ticker
- Strike price
- Expiry date
- Risk-free rate
- Volatility
The app is implemented in Python 3.9 and uses the Streamlit library for visualization.

Option pricing models are implemented in [Python 3.7](https://www.python.org/downloads/release/python-377/). Latest spot price, for specified ticker, is fetched from Yahoo Finance API using [pandas-datareader](https://pandas-datareader.readthedocs.io/en/latest/). Visualization of the models through simple web app is implemented using [streamlit](https://www.streamlit.io/) library.
## Option Pricing Methods

When data is fetched from Yahoo Finance API using pandas-datareader, it's cached with [request-cache](https://github.com/reclosedev/requests-cache) library is sqlite db, so any subsequent testing and changes in model parameters with same underlying instrument won't result in duplicated request for fethcing already fetched data.
### 1. Black-Scholes Model
A mathematical model used to calculate the theoretical price of European-style options, based on factors like current stock price, strike price, time to expiration, risk-free rate, and volatility.

This implementation was done as project work on the course [Special Functions (Applied Mathematics)](https://www.etf.bg.ac.rs/en/fis/karton_predmeta/13M081SPEF-2013) on Master's degree in Software Engineering.
### 2. Monte Carlo Simulation
A probabilistic method that uses random sampling to estimate option prices by simulating multiple possible price paths of the underlying asset.

## Streamlit web app
### 3. Binomial Model
A discrete-time model that represents the evolution of the underlying asset's price as a binomial tree, allowing for the calculation of option prices at different time steps.

1. Black-Scholes model
![black-scholes-demo](./demo/streamlit-webapp-BS.gif)
## Features

2. Monte Carlo Option Pricing
![monte-carlo-demo](./demo/streamlit-webapp-MC.gif)
- Fetches latest stock price data from Yahoo Finance API using pandas-datareader
- Caches data using requests-cache to avoid duplicate API calls
- Allows users to input various parameters:
- Strike price
- Risk-free rate (%)
- Sigma (Volatility) (%)
- Exercise date
- Calculates option prices based on user inputs
- Provides a user-friendly interface for testing different scenarios

3. Binomial model
![binomial-tree-demo](./demo/streamlit-webapp-BC.gif)
## Project Structure

- `demo/`: Contains GIF files demonstrating the Streamlit app
- `option_pricing/`: Python package containing model implementations
- `streamlit_app.py`: Main script for the Streamlit web app
- `Requirements.txt`: List of required Python packages
- `Dockerfile`: Configuration for running the app in a Docker container

## Project structure
In this repository you will find:
## How to Run the App

- demo directory - contains .gif files as example of streamlit app.
- option_pricing package - python package where models are implemented.
- option_pricing_test.py script - example code for testing option pricing models (without webapp).
- streamlit_app.py script - web app for testing models using streamlit library.
- Requirements.txt file - python pip package requirements.
- Dockerfile file - for running containerized streamlit web app.
- app.yaml file - for deploying dockerized app on GCP(Google Cloud Platform).
### Using Docker Locally
The easiest way to run the app is using Docker. Make sure you have Docker installed on your machine before proceeding.

1. Navigate to the repository directory in your terminal.

## How to run code?
You can use simple streamlit web app to test option pricing models either by manually setting up python environment and running streamlit app or by running docker container.
2. Build the Docker image:
```
docker build -t options-pricing:latest .
```

### **1. Running docker container**
Dockerfile has exposed 8080 (default web browser port), so when you deploy it to some cloud provider, it would be automatically possible to access your recently deployed webb app through browser.
3. Verify the image was built successfully:
```
docker image ls
```

***1.1 Running docker container locally***
First you will need to build the docker image (this may take a while, because it's downloading all the python libraries from Requirements.txt file) and specify tag e.g. option-pricing:initial:
`docker build -t option-pricing:initial .`
4. Run the Docker container:
```
docker run -p 8080:8080 options-pricing:latest
```

When image is built, you can execute following command, that lists all docker images, to check if image was successfully build:
`docker image ls`
5. Access the app in your web browser at:
```
http://0.0.0.0:8080/
```

Now, you can run docker container with following command:
`docker run -p 8080:8080 option-pricing:initial`
### Using Google Cloud

When you see output in command line that streamlit app is running on port 8080, you can access it with browser:
`http://localhost:8080/`
To deploy the Docker container to Google Cloud Platform (GCP), follow these steps:

1. Prerequisites:
- Have a Google account
- Create a project on Google Cloud Console
- Set up billing for your project (be aware of GCP's pricing structure)
- Install and set up Google Cloud SDK

***1.2 Deploying docker container to Google Cloud Platform***
Before you deploy to GCP, please make sure you have google acount, created project on Google Developer Console, set up the billing method (please make sure you understand how Google is charging for hosting!) and downloaded [Google Cloud SDK](https://cloud.google.com/sdk/docs/quickstarts).
2. Verify and set your GCP project:
- Check the current project:
```
gcloud config get-value project
```
- Set a different project if needed:
```
gcloud config set project YOUR_PROJECT_NAME
```

To chech which project (one from list of projects created on Google Developer Console) is currently used with Google Cloud SDK, use:
`gcloud config get-value project`
3. Deploy the application:
- Run the following command (uses the app.yaml file in your project):
```
gcloud app deploy
```
- Select the nearest server location when prompted
- Wait for the deployment process to complete

To chage/set project use:
`gcloud config set project project-name`
4. Access your web app:
- After deployment, you'll receive a URL for your app
- The URL format will be: https://YOUR_PROJECT_NAME.REGION.r.appspot.com/
- You can also find this URL in the Google Cloud Console

When you have correct project in use for Cloud SDK, now you can deploy it using following command (it will use .yaml file from project structure as instructiong on how to deploy it):
`gcloud app deploy`
After choosing neared physical server to host your app, you will have to wait a bit for whole process to finish. Once everything is over, you will be prompted with a link to your web app (you can check that on Developer console as well).
Link for your webb app will be something like this: `https://project-name.ey.r.appspot.com/`.
Note: Ensure you understand GCP's pricing before deploying to avoid unexpected charges.

### **2. Running streamlit app locally with python**
It is recommended that you create new [virtual environment](https://docs.python.org/3.7/tutorial/venv.html):
`python3 -m venv option-pricing`
## Streamlit Web App Demonstrations

Then you would need to activate that newly created python environment:

* On Windows:
`option-pricing\Scripts\activate.bat`
* On Linux:
`source option-pricing/bin/activate`

Once you have your python environment activated, first you would need to download all necessary python modules with pip. There is Requirements.txt file in scr directory. You can use the following command to automatically download all dependencies:
`pip install -r Requirements.txt`

When the download is completed, you can run streamlit app with:
`streamlit run streamlit_app.py`



### Black-Scholes Model
![black-scholes-demo](media/Black_Scholes_Model.gif)

### Monte Carlo Option Pricing
![monte-carlo-demo](media/Monte_Carlo_Option_Pricing.gif)

### Binomial Model
![binomial-tree-demo](media/Binomial_Model.gif)

By following these instructions, you can easily set up and explore the option pricing models using the Streamlit web app. Feel free to experiment with different parameters and see how they affect the calculated option prices.
25 changes: 6 additions & 19 deletions Requirements.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
certifi==2020.6.20
chardet==3.0.4
cycler==0.10.0
idna==2.10
kiwisolver==1.2.0
lxml==4.5.2
matplotlib==3.2.2
numpy==1.19.0
pandas==1.0.5
pandas-datareader==0.9.0
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2020.1
requests==2.24.0
requests-cache==0.5.2
scipy==1.5.1
six==1.15.0
streamlit==0.62.1
urllib3==1.25.9
streamlit==1.29.0
matplotlib==3.7.4
numpy==1.26.2
pandas==2.1.4
scipy==1.11.4
yfinance==0.2.31
Binary file removed demo/streamlit-webapp-BC.gif
Binary file not shown.
Binary file removed demo/streamlit-webapp-BS.gif
Binary file not shown.
Binary file removed demo/streamlit-webapp-MC.gif
Binary file not shown.
Binary file added media/Binomial_Model.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/Black_Scholes_Model.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/Monte_Carlo_Option_Pricing.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions option_pricing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class BlackScholesModel:
# ... (existing code) ...

def get_calculation_steps(self):
steps = {
"Input Parameters": {
"Spot Price": self.S,
"Strike Price": self.K,
"Time to Maturity (days)": self.T,
"Risk-free Rate": self.r,
"Volatility": self.sigma
},
"Intermediate Calculations": {
"d1": self.d1,
"d2": self.d2,
"N(d1)": self.N_d1,
"N(d2)": self.N_d2,
"N(-d1)": self.N_minus_d1,
"N(-d2)": self.N_minus_d2
},
"Final Calculations": {
"Call Option Price": self.call_price,
"Put Option Price": self.put_price
}
}
return steps

# Similarly, add get_calculation_steps() methods to MonteCarloPricing and BinomialTreeModel classes
12 changes: 7 additions & 5 deletions option_pricing/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enum import Enum
from abc import ABC, abstractclassmethod
from abc import ABC, abstractmethod

class OPTION_TYPE(Enum):
CALL_OPTION = 'Call Option'
Expand All @@ -17,12 +17,14 @@ def calculate_option_price(self, option_type):
else:
return -1

@abstractclassmethod
def _calculate_call_option_price(self):
@classmethod
@abstractmethod
def _calculate_call_option_price(cls):
"""Calculates option price for call option."""
pass

@abstractclassmethod
def _calculate_put_option_price(self):
@classmethod
@abstractmethod
def _calculate_put_option_price(cls):
"""Calculates option price for put option."""
pass
Loading