import streamlit as st import yfinance as yf import numpy as np import pandas as pd from plotly.subplots import make_subplots import plotly.graph_objects as go def analyze_and_visualize_straddle(ticker, strike_call, strike_put, premium_call, premium_put): """ This function is used to analyze a given ticker and visualize the payoffs for both long and short straddle strategies. Parameters: - ticker: Symbol of the underlying asset as is on Yahoo Finance. - strike_call: Strike price for the call option. - strike_put: Strike price for the put option. - premium_call: Premium paid for the call option. - premium_put: Premium paid for the put option. """ ## Downloading historical data df = yf.download(ticker, multi_level_index=False, auto_adjust=False) # Computing returns df['Returns'] = df['Adj Close'].pct_change() # Computing annualized volatility df['Vol'] = df['Returns'].rolling(20).std() * np.sqrt(252) df.dropna(axis = 0, inplace = True) # Removing null values # Generating array of equally-spaced points representing the quantiles to be calculated (from 0% to 100%) quantiles = np.quantile(df['Vol'], np.linspace(0,1,11)) # Using quantilies to categorize and label the annualized volatility values quantile_labels = pd.cut(df['Vol'], bins = quantiles, labels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # Adding categorical labels to the dataframe df['Vol_Rank'] = quantile_labels # Plotting data fig = make_subplots(rows = 3, cols = 1, horizontal_spacing=0.2, row_heights=[.60, .20, .20], shared_xaxes=True) # First row --> Closing Price fig.add_trace(go.Scatter( x = df.index, y = df['Adj Close'], name = 'Closing Price' ), row = 1, col = 1) # Second row --> Annualized Volatility fig.add_trace(go.Scatter( x = df.index, y = df['Vol'], name = 'Annualized Volatility' ), row = 2, col = 1) # Third row --> Volatility rank fig.add_trace(go.Scatter( x = df.index, y = df['Vol_Rank'], name = 'Volatility Rank' ), row = 3, col = 1) # Defining subplots layout fig.update_layout(title = {'text': f'{ticker} Closing Price & Volatility'}, template = 'plotly_white', height = 900, width = 950, showlegend=False, hovermode='x unified') # Defining layout of y-axes across subplots fig.update_yaxes(title_text = 'Closing Price ($)', row = 1) fig.update_yaxes(title_text = 'Annualized Volatility', row = 2) fig.update_yaxes(title_text = 'Volatility Rank', row = 3) # Generating an array of possible prices the underlying asset might fall into stock_prices = np.linspace(0.79 * min(strike_put, strike_call), 1.19 * max(strike_put, strike_call), 100).round(2) # Computing payoffs # Payoffs for holding long call and put options long_call_payoff = np.maximum(stock_prices - strike_call, 0) - premium_call long_put_payoff = np.maximum(strike_put - stock_prices, 0) - premium_put # Payoffs for holding short positions in call and put options short_call_payoff = -long_call_payoff short_put_payoff = -long_put_payoff # Combined payoffs for both long and short positions combined_long_payoff = long_call_payoff + long_put_payoff combined_short_payoff = short_call_payoff + short_put_payoff # Computing profit and loss for long straddle profit_long = np.maximum(combined_long_payoff, 0) loss_long = np.minimum(combined_long_payoff, 0) # Computing profit and loss for short straddle loss_short = np.minimum(combined_short_payoff, 0) profit_short = np.maximum(combined_short_payoff, 0) # Creating subplots fig2 = make_subplots( rows=2, cols=1, horizontal_spacing=0.2, row_heights=[0.5, 0.5], shared_xaxes=False, shared_yaxes=False ) # Adding Long Straddle traces fig2.add_trace( go.Scatter(x=stock_prices, y=long_call_payoff, mode='lines', line=dict(color='grey', dash='dash'), name='Long Call', hovertemplate='%{y:.2f}'), row=1, col=1 ) fig2.add_trace( go.Scatter(x=stock_prices, y=long_put_payoff, mode='lines', line=dict(color='grey', dash='dash'), name='Long Put', hovertemplate='%{y:.2f}'), row=1, col=1 ) # Adding Short Straddle traces fig2.add_trace( go.Scatter(x=stock_prices, y=short_call_payoff, mode='lines', line=dict(color='grey', dash='dash'), name='Short Call', hovertemplate='%{y:.2f}'), row=2, col=1 ) fig2.add_trace( go.Scatter(x=stock_prices, y=short_put_payoff, mode='lines', line=dict(color='grey', dash='dash'), name='Short Put', hovertemplate='%{y:.2f}'), row=2, col=1 ) # Adding the payoff lines for Long Straddle fig2.add_trace( go.Scatter(x=stock_prices, y=profit_long, mode='lines', line=dict(color='black', dash='solid'), name='Profit', hovertemplate='%{y:.2f}', fill='tozeroy', fillcolor='rgba(0, 255, 0, 0.5)'), row=1, col=1 ) fig2.add_trace( go.Scatter(x=stock_prices, y=loss_long, mode='lines', line=dict(color='black', dash='solid'), name='Loss', hovertemplate='%{y:.2f}', fill='tozeroy', fillcolor='rgba(255, 0, 0, 0.5)'), row=1, col=1 ) # Adding the payoff lines for Long Straddle fig2.add_trace( go.Scatter(x=stock_prices, y=loss_short, mode='lines', line=dict(color='black', dash='solid'), name = 'Loss', hovertemplate='%{y:.2f}', fill='tozeroy', fillcolor='rgba(255, 0, 0, 0.5)'), row=2, col=1 ) fig2.add_trace( go.Scatter(x=stock_prices, y=profit_short, mode='lines', line=dict(color='black', dash='solid'), name = 'Profit', hovertemplate='%{y:.2f}', fill='tozeroy', fillcolor='rgba(0, 255, 0, 0.5)'), row=2, col=1 ) # Defining layout fig2.update_layout( title={'text': f'{ticker} Long & Short Straddle'}, template='plotly_white', height=1000, width=750, showlegend=False, hovermode='x unified') # Defining y-axes and x-axes tiles across rows fig2.update_yaxes(title_text='Long Payoff ($)', row=1) fig2.update_yaxes(title_text='Short Payoff ($)', row=2) fig2.update_xaxes(title_text = 'Underlying Asset Price at Expiration', row=1) fig2.update_xaxes(title_text = 'Underlying Asset Price at Expiration', row=2) # Displaying plots return fig, fig2 st.set_page_config(page_title="Long and Short Straddle", page_icon=":chart_with_upwards_trend", layout="wide", initial_sidebar_state="expanded", #theme={"base":"light"} ) title = '