├── 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 |
207 |
208 |
CALL Value
209 |
${call_price:.2f}
210 |
211 |
212 | """, unsafe_allow_html=True) 213 | 214 | with col2: 215 | # Using the custom class for PUT value 216 | st.markdown(f""" 217 |
218 |
219 |
PUT Value
220 |
${put_price:.2f}
221 |
222 |
223 | """, unsafe_allow_html=True) 224 | 225 | st.markdown("") 226 | st.title("Options Price - Interactive Heatmap") 227 | st.info("Explore how option prices fluctuate with varying 'Spot Prices and Volatility' levels using interactive heatmap parameters, all while maintaining a constant 'Strike Price'.") 228 | 229 | # Interactive Sliders and Heatmaps for Call and Put Options 230 | col1, col2 = st.columns([1,1], gap="small") 231 | 232 | with col1: 233 | st.subheader("Call Price Heatmap") 234 | heatmap_fig_call, _ = plot_heatmap(bs_model, spot_range, vol_range, strike) 235 | st.pyplot(heatmap_fig_call) 236 | 237 | with col2: 238 | st.subheader("Put Price Heatmap") 239 | _, heatmap_fig_put = plot_heatmap(bs_model, spot_range, vol_range, strike) 240 | st.pyplot(heatmap_fig_put) 241 | --------------------------------------------------------------------------------