├── requirements.txt
├── .streamlit
└── config.toml
├── README.md
├── BlackScholes.py
└── streamlit_app.py
/requirements.txt:
--------------------------------------------------------------------------------
1 | streamlit
2 | pandas
3 | numpy
4 | scipy
5 | plotly
6 | matplotlib
7 | seaborn
8 |
--------------------------------------------------------------------------------
/.streamlit/config.toml:
--------------------------------------------------------------------------------
1 | [theme]
2 | primaryColor = "#FF4B4B"
3 | # backgroundColor = "#10344b"
4 | backgroundColor = "#0E1117"
5 | # secondaryBackgroundColor = "#154360"
6 | secondaryBackgroundColor = "#262730"
7 | textColor = "#FAFAFA"
8 | font = "sans serif"
9 |
10 | [server]
11 | enableStaticServing = true
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Black-Scholes Pricing Model
2 |
3 | This repository provides an interactive Black-Scholes Pricing Model dashboard that helps in visualizing option prices under varying conditions. The dashboard is designed to be user-friendly and interactive, allowing users to explore how changes in spot price, volatility, and other parameters influence the value of options.
4 |
5 | https://blackschole.streamlit.app/
6 |
7 | ## 🚀 Features:
8 |
9 | 1. **Options Pricing Visualization**:
10 | - Displays both Call and Put option prices using an interactive heatmap.
11 | - The heatmap dynamically updates as you adjust parameters like Spot Price, Volatility, and Time to Maturity.
12 |
13 | 2. **Interactive Dashboard**:
14 | - The dashboard allows real-time updates to the Black-Scholes model parameters.
15 | - Users can input different values for the Spot Price, Volatility, Strike Price, Time to Maturity, and Risk-Free Interest Rate to observe how these factors influence option prices.
16 | - Both Call and Put option prices are calculated and displayed for immediate comparison.
17 |
18 | 3. **Customizable Parameters**:
19 | - Set custom ranges for Spot Price and Volatility to generate a comprehensive view of option prices under different market conditions.
20 |
21 | ## 🔧 Dependencies:
22 |
23 | - `yfinance`: To fetch current asset prices.
24 | - `numpy`: For numerical operations.
25 | - `matplotlib`: For heatmap visualization.
26 |
27 |
28 |
--------------------------------------------------------------------------------
/BlackScholes.py:
--------------------------------------------------------------------------------
1 | from numpy import exp, sqrt, log
2 | from scipy.stats import norm
3 |
4 |
5 | class BlackScholes:
6 | def __init__(
7 | self,
8 | time_to_maturity: float,
9 | strike: float,
10 | current_price: float,
11 | volatility: float,
12 | interest_rate: float,
13 | ):
14 | self.time_to_maturity = time_to_maturity
15 | self.strike = strike
16 | self.current_price = current_price
17 | self.volatility = volatility
18 | self.interest_rate = interest_rate
19 |
20 | def run(
21 | self,
22 | ):
23 | time_to_maturity = self.time_to_maturity
24 | strike = self.strike
25 | current_price = self.current_price
26 | volatility = self.volatility
27 | interest_rate = self.interest_rate
28 |
29 | d1 = (
30 | log(current_price / strike) +
31 | (interest_rate + 0.5 * volatility ** 2) * time_to_maturity
32 | ) / (
33 | volatility * sqrt(time_to_maturity)
34 | )
35 | d2 = d1 - volatility * sqrt(time_to_maturity)
36 |
37 | call_price = current_price * norm.cdf(d1) - (
38 | strike * exp(-(interest_rate * time_to_maturity)) * norm.cdf(d2)
39 | )
40 | put_price = (
41 | strike * exp(-(interest_rate * time_to_maturity)) * norm.cdf(-d2)
42 | ) - current_price * norm.cdf(-d1)
43 |
44 | self.call_price = call_price
45 | self.put_price = put_price
46 |
47 | # GREEKS
48 | # Delta
49 | self.call_delta = norm.cdf(d1)
50 | self.put_delta = 1 - norm.cdf(d1)
51 |
52 | # Gamma
53 | self.call_gamma = norm.pdf(d1) / (
54 | strike * volatility * sqrt(time_to_maturity)
55 | )
56 | self.put_gamma = self.call_gamma
57 |
58 |
59 | if __name__ == "__main__":
60 | time_to_maturity = 2
61 | strike = 90
62 | current_price = 100
63 | volatility = 0.2
64 | interest_rate = 0.05
65 |
66 | # Black Scholes
67 | BS = BlackScholes(
68 | time_to_maturity=time_to_maturity,
69 | strike=strike,
70 | current_price=current_price,
71 | volatility=volatility,
72 | interest_rate=interest_rate)
73 | BS.run()
--------------------------------------------------------------------------------
/streamlit_app.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | import pandas as pd
3 | import numpy as np
4 | from scipy.stats import norm
5 | import plotly.graph_objects as go
6 | from numpy import log, sqrt, exp # Make sure to import these
7 | import matplotlib.pyplot as plt
8 | import seaborn as sns
9 |
10 | #######################
11 | # Page configuration
12 | st.set_page_config(
13 | page_title="Black-Scholes Option Pricing Model",
14 | page_icon="📊",
15 | layout="wide",
16 | initial_sidebar_state="expanded")
17 |
18 |
19 | # Custom CSS to inject into Streamlit
20 | st.markdown("""
21 |
60 | """, unsafe_allow_html=True)
61 |
62 | # (Include the BlackScholes class definition here)
63 |
64 | class BlackScholes:
65 | def __init__(
66 | self,
67 | time_to_maturity: float,
68 | strike: float,
69 | current_price: float,
70 | volatility: float,
71 | interest_rate: float,
72 | ):
73 | self.time_to_maturity = time_to_maturity
74 | self.strike = strike
75 | self.current_price = current_price
76 | self.volatility = volatility
77 | self.interest_rate = interest_rate
78 |
79 | def calculate_prices(
80 | self,
81 | ):
82 | time_to_maturity = self.time_to_maturity
83 | strike = self.strike
84 | current_price = self.current_price
85 | volatility = self.volatility
86 | interest_rate = self.interest_rate
87 |
88 | d1 = (
89 | log(current_price / strike) +
90 | (interest_rate + 0.5 * volatility ** 2) * time_to_maturity
91 | ) / (
92 | volatility * sqrt(time_to_maturity)
93 | )
94 | d2 = d1 - volatility * sqrt(time_to_maturity)
95 |
96 | call_price = current_price * norm.cdf(d1) - (
97 | strike * exp(-(interest_rate * time_to_maturity)) * norm.cdf(d2)
98 | )
99 | put_price = (
100 | strike * exp(-(interest_rate * time_to_maturity)) * norm.cdf(-d2)
101 | ) - current_price * norm.cdf(-d1)
102 |
103 | self.call_price = call_price
104 | self.put_price = put_price
105 |
106 | # GREEKS
107 | # Delta
108 | self.call_delta = norm.cdf(d1)
109 | self.put_delta = 1 - norm.cdf(d1)
110 |
111 | # Gamma
112 | self.call_gamma = norm.pdf(d1) / (
113 | strike * volatility * sqrt(time_to_maturity)
114 | )
115 | self.put_gamma = self.call_gamma
116 |
117 | return call_price, put_price
118 |
119 | # Function to generate heatmaps
120 | # ... your existing imports and BlackScholes class definition ...
121 |
122 |
123 | # Sidebar for User Inputs
124 | with st.sidebar:
125 | st.title("📊 Black-Scholes Model")
126 | st.write("`Created by:`")
127 | linkedin_url = "https://www.linkedin.com/in/mprudhvi/"
128 | st.markdown(f'
`Prudhvi Reddy, Muppala`', unsafe_allow_html=True)
129 |
130 | current_price = st.number_input("Current Asset Price", value=100.0)
131 | strike = st.number_input("Strike Price", value=100.0)
132 | time_to_maturity = st.number_input("Time to Maturity (Years)", value=1.0)
133 | volatility = st.number_input("Volatility (σ)", value=0.2)
134 | interest_rate = st.number_input("Risk-Free Interest Rate", value=0.05)
135 |
136 | st.markdown("---")
137 | calculate_btn = st.button('Heatmap Parameters')
138 | spot_min = st.number_input('Min Spot Price', min_value=0.01, value=current_price*0.8, step=0.01)
139 | spot_max = st.number_input('Max Spot Price', min_value=0.01, value=current_price*1.2, step=0.01)
140 | vol_min = st.slider('Min Volatility for Heatmap', min_value=0.01, max_value=1.0, value=volatility*0.5, step=0.01)
141 | vol_max = st.slider('Max Volatility for Heatmap', min_value=0.01, max_value=1.0, value=volatility*1.5, step=0.01)
142 |
143 | spot_range = np.linspace(spot_min, spot_max, 10)
144 | vol_range = np.linspace(vol_min, vol_max, 10)
145 |
146 |
147 |
148 | def plot_heatmap(bs_model, spot_range, vol_range, strike):
149 | call_prices = np.zeros((len(vol_range), len(spot_range)))
150 | put_prices = np.zeros((len(vol_range), len(spot_range)))
151 |
152 | for i, vol in enumerate(vol_range):
153 | for j, spot in enumerate(spot_range):
154 | bs_temp = BlackScholes(
155 | time_to_maturity=bs_model.time_to_maturity,
156 | strike=strike,
157 | current_price=spot,
158 | volatility=vol,
159 | interest_rate=bs_model.interest_rate
160 | )
161 | bs_temp.calculate_prices()
162 | call_prices[i, j] = bs_temp.call_price
163 | put_prices[i, j] = bs_temp.put_price
164 |
165 | # Plotting Call Price Heatmap
166 | fig_call, ax_call = plt.subplots(figsize=(10, 8))
167 | sns.heatmap(call_prices, xticklabels=np.round(spot_range, 2), yticklabels=np.round(vol_range, 2), annot=True, fmt=".2f", cmap="viridis", ax=ax_call)
168 | ax_call.set_title('CALL')
169 | ax_call.set_xlabel('Spot Price')
170 | ax_call.set_ylabel('Volatility')
171 |
172 | # Plotting Put Price Heatmap
173 | fig_put, ax_put = plt.subplots(figsize=(10, 8))
174 | sns.heatmap(put_prices, xticklabels=np.round(spot_range, 2), yticklabels=np.round(vol_range, 2), annot=True, fmt=".2f", cmap="viridis", ax=ax_put)
175 | ax_put.set_title('PUT')
176 | ax_put.set_xlabel('Spot Price')
177 | ax_put.set_ylabel('Volatility')
178 |
179 | return fig_call, fig_put
180 |
181 |
182 | # Main Page for Output Display
183 | st.title("Black-Scholes Pricing Model")
184 |
185 | # Table of Inputs
186 | input_data = {
187 | "Current Asset Price": [current_price],
188 | "Strike Price": [strike],
189 | "Time to Maturity (Years)": [time_to_maturity],
190 | "Volatility (σ)": [volatility],
191 | "Risk-Free Interest Rate": [interest_rate],
192 | }
193 | input_df = pd.DataFrame(input_data)
194 | st.table(input_df)
195 |
196 | # Calculate Call and Put values
197 | bs_model = BlackScholes(time_to_maturity, strike, current_price, volatility, interest_rate)
198 | call_price, put_price = bs_model.calculate_prices()
199 |
200 | # Display Call and Put Values in colored tables
201 | col1, col2 = st.columns([1,1], gap="small")
202 |
203 | with col1:
204 | # Using the custom class for CALL value
205 | st.markdown(f"""
206 |