import streamlit as st from streamlit_option_menu import option_menu import pandas as pd import yfinance as yf import plotly.express as px import datetime from datetime import date import numpy as np from dataclasses import dataclass import warnings warnings.filterwarnings('ignore') np.set_printoptions(suppress=True) # Define the commodities and their Yahoo Finance tickers commodities = { 'Gold': 'GC=F', 'Silver': 'SI=F', 'Crude Oil': 'CL=F', 'Natural Gas': 'NG=F', 'Copper': 'HG=F', 'Platinum': 'PL=F', 'Paladium': 'PA=F', 'RBOB Gasoline': 'RB=F', 'Brent Crude Oil': 'BZ=F', 'Corn Futures': 'ZC=F', 'Oat Futures': 'ZO=F', 'KC HRW Wheat Futures': 'KE=F', 'Soybean Oil Futures': 'ZL=F', 'Soybean Futures': 'ZS=F', 'Live Cattle Futures': 'LE=F', 'Cocoa': 'CC=F', 'Coffee': 'KC=F', 'Cotton': 'CT=F', 'Sugar': 'SB=F' } # Define the Class Structure @dataclass class Data: collectedData: pd.DataFrame commTickers: dict years: int upperBoundLimit: float import plotly.express as px import pandas as pd import streamlit as st def plot_optimal_weights(weights: pd.DataFrame, title: str = "Weights Allocation Bar Chart"): """ Plot optimal weights using Plotly and display it on Streamlit. Parameters: - weights: pd.DataFrame containing asset names and their corresponding weights. - title: Title of the plot. """ # Ensure the DataFrame has the correct format if weights.shape[1] != 2: raise ValueError("DataFrame should have two columns: 'Tickers' and 'Weights'.") # Fill NaN weights with 0 weights['Weights'] = weights['Weights'].fillna(0) fig = px.bar(weights, x='Tickers', y='Weights', title=title, labels={"Tickers": "Assets", "Weights": "Weights"}, template='plotly_dark') fig.update_layout( width=1000, height=475, xaxis_title="Assets", yaxis_title="Weights", title_font=dict(size=24, color='white'), legend=dict( title_font=dict(size=36, color='white'), font=dict(size=28, color='white') ), plot_bgcolor='black', paper_bgcolor='black' ) fig.update_traces(marker=dict(color='blue', line=dict(color='white', width=1.5))) return fig # Function to retrieve ticker data or Stock Prices from Yahoo Finance def retrieve_tickers(): global dt if len(st.session_state.dtVariable.commTickers) <= 0: return startDate = date.today() - datetime.timedelta(days=st.session_state.dtVariable.years * 365) endDate = date.today() for com, tick in st.session_state.dtVariable.commTickers.items(): # st.write("Hello",st.session_state.dtVariable.collectedData.columns) if com not in st.session_state.dtVariable.collectedData.columns: st.session_state.dtVariable.collectedData[com] = yf.download(tickers=tick, start=startDate, end=endDate)['Adj Close'] st.session_state.dtVariable.collectedData.dropna(inplace=True) # Function to Visualize Ticker Data def visualize(data: pd.DataFrame, title: str, hoverLabel: dict, xTitle: str, yTitle: str, legendTitle: str, width: int = 1000 # Default width set to 1000, you can adjust as needed ): # Create interactive plots fig = px.line(data, title=title, labels=hoverLabel) fig.update_layout( width=width, # Set the width of the plot xaxis_title=xTitle, yaxis_title=yTitle, legend_title_text=legendTitle, template='plotly_dark', hovermode='x unified', plot_bgcolor='black', # Set plot background color to black paper_bgcolor='black', # Set paper background color to black title_font=dict(color='white'), legend=dict( title_font=dict(color='white'), # Set legend title color to white font=dict(color='white') # Set legend items color to white ) # Set title color to white ) return fig # Function to Calculate Key metrics class KeyMetrics: def __init__(self, data, logNormal=False): self.data = data self.initialWeights = np.array([1/len(self.data.columns) for _ in range(len(self.data.columns))]) self.logNormal = logNormal self.dailyReturns = None self.covarianceMatrix = None self.variance = None self.standardDeviation = None self.expectedReturns = None self.sharpeRatio = None self.negSharpeRatio = None def calculate_daily_returns(self): self.dailyReturns = np.log(self.data / self.data.shift(1)).dropna() if self.logNormal else self.data.pct_change().dropna() def calculate_covariance(self): if self.dailyReturns is None: return "Please Calculate Daily Returns First" self.covarianceMatrix = self.dailyReturns.cov() * 252 def calculate_standard_deviation(self): if self.covarianceMatrix is None: return "Please Calculate Covariance Matrix First" self.variance = self.initialWeights.T @ self.covarianceMatrix @ self.initialWeights self.standardDeviation = np.sqrt(self.variance) def calculate_expected_return(self): if self.standardDeviation is None: return "Please Calculate Standard Deviation First" self.expectedReturns = np.sum(self.dailyReturns.mean() * self.initialWeights) * 252 def calculate_sharpe_ratio(self, riskFreeRate): if self.expectedReturns is None: return "Please Calculate Expected Returns First" self.sharpeRatio = (self.expectedReturns - riskFreeRate) / self.standardDeviation def negative_sharpe_ratio(self): if self.sharpeRatio is None: return "Please Calculate Sharpe Ratio First" self.negSharpeRatio = - self.sharpeRatio # Navigation Bar def navigationBar(): # Use the following link to get whichever icon you'd like: # https://getbootstrap.com/ options = [ {"label": "Sharpe Ratio Technique", "icon": "bezier"} ] selected = option_menu( menu_title= None, #"Ask Me Anything", # Menu title options=[option["label"] for option in options], icons=[option["icon"] for option in options], menu_icon="lightbulb-fill", default_index=0, orientation="horizontal", styles={ "container": { "display": "flex", "flex-direction": "column", "justify-content": "center", "padding": "20px 40px 20px 40px", # Increased top and bottom padding "background-color": "#00E0FF", # Dark background color "border-radius": "20px", "width":"100%", "box-shadow": "0px 2px 10px rgba(0, 0, 0, 0.2)", # Shadow effect "margin": "auto", # Center align the navigation bar "overflow-x": "auto", # Allow horizontal scrolling for small screens }, "menu-title": { "font-size": "36px", "font-weight": "bold", "background-color": "#292", "color": "#FFFFFF", # White text color "margin-bottom": "20px", # Spacing below the menu title }, "menu-icon": { "color": "#FFD700", # Golden yellow icon color "font-size": "36px", "margin-right": "10px", }, "icon": { "color": "#FFD700", # Golden yellow icon color "font-size": "36px", "margin-right": "10px", }, "nav-link": { "font-size": "20px", "text-align": "center", "color": "#FFFFFF", # White text color "padding": "10px 20px", "border-radius": "15px", "transition": "background-color 0.3s ease", }, "nav-link-selected": { "background-color": "#07A2F4", # Tomato red when selected "color": "#FFFFFF", # White text color when selected } }, ) return selected