Team Ai
Apppublic

arif97/Portfolio-Optimization

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
PortfolioHelperFuncs.py246 linesDownload Raw Back to root
1import streamlit as st2from streamlit_option_menu import option_menu3 4import pandas as pd5import yfinance as yf6import plotly.express as px7import datetime8from datetime import date9import numpy as np10from dataclasses import dataclass11import warnings12 13warnings.filterwarnings('ignore')14np.set_printoptions(suppress=True)15 16 17# Define the commodities and their Yahoo Finance tickers18commodities = {19    'Gold': 'GC=F',20    'Silver': 'SI=F',21    'Crude Oil': 'CL=F',22    'Natural Gas': 'NG=F',23    'Copper': 'HG=F',24    'Platinum': 'PL=F',25    'Paladium': 'PA=F',26    'RBOB Gasoline': 'RB=F',27    'Brent Crude Oil': 'BZ=F',28    'Corn Futures': 'ZC=F',29    'Oat Futures': 'ZO=F',30    'KC HRW Wheat Futures': 'KE=F',31    'Soybean Oil Futures': 'ZL=F',32    'Soybean Futures': 'ZS=F',33    'Live Cattle Futures': 'LE=F',34    'Cocoa': 'CC=F',35    'Coffee': 'KC=F',36    'Cotton': 'CT=F',37    'Sugar': 'SB=F'38}39 40 41# Define the Class Structure42@dataclass43class Data:44    collectedData: pd.DataFrame45    commTickers: dict46    years: int47    upperBoundLimit: float48 49 50 51import plotly.express as px52import pandas as pd53import streamlit as st54 55def plot_optimal_weights(weights: pd.DataFrame, title: str = "Weights Allocation Bar Chart"):56    """57    Plot optimal weights using Plotly and display it on Streamlit.58 59    Parameters:60    - weights: pd.DataFrame containing asset names and their corresponding weights.61    - title: Title of the plot.62    """63    # Ensure the DataFrame has the correct format64    if weights.shape[1] != 2:65        raise ValueError("DataFrame should have two columns: 'Tickers' and 'Weights'.")66    67    # Fill NaN weights with 068    weights['Weights'] = weights['Weights'].fillna(0)69    70    fig = px.bar(weights,71                 x='Tickers',72                 y='Weights',73                 title=title,74                 labels={"Tickers": "Assets", "Weights": "Weights"},75                 template='plotly_dark')76 77    fig.update_layout(78        width=1000,79        height=475,80        xaxis_title="Assets",81        yaxis_title="Weights",82        title_font=dict(size=24, color='white'),83        legend=dict(84            title_font=dict(size=36, color='white'),85            font=dict(size=28, color='white')86        ),87        plot_bgcolor='black',88        paper_bgcolor='black'89    )90 91    fig.update_traces(marker=dict(color='blue', line=dict(color='white', width=1.5)))92    return fig93 94 95 96# Function to retrieve ticker data or Stock Prices from Yahoo Finance97def retrieve_tickers():98    global dt99    if len(st.session_state.dtVariable.commTickers) <= 0:100        return101    startDate = date.today() - datetime.timedelta(days=st.session_state.dtVariable.years * 365)102    endDate = date.today()103    for com, tick in st.session_state.dtVariable.commTickers.items():104        # st.write("Hello",st.session_state.dtVariable.collectedData.columns)105        if com not in st.session_state.dtVariable.collectedData.columns:106            st.session_state.dtVariable.collectedData[com] = yf.download(tickers=tick, start=startDate, end=endDate)['Adj Close']107    st.session_state.dtVariable.collectedData.dropna(inplace=True)108 109 110# Function to Visualize Ticker Data111def visualize(data: pd.DataFrame,112              title: str, hoverLabel: dict, 113              xTitle: str, 114              yTitle: str, 115              legendTitle: str,116              width: int = 1000  # Default width set to 1000, you can adjust as needed117              ):118    # Create interactive plots119    fig = px.line(data,120                   title=title,121                   labels=hoverLabel)122    fig.update_layout(123        width=width,  # Set the width of the plot124        xaxis_title=xTitle,125        yaxis_title=yTitle,126        legend_title_text=legendTitle,127        template='plotly_dark',128        hovermode='x unified',129        plot_bgcolor='black',  # Set plot background color to black130        paper_bgcolor='black',  # Set paper background color to black131        title_font=dict(color='white'),132        legend=dict(133            title_font=dict(color='white'),  # Set legend title color to white134            font=dict(color='white')  # Set legend items color to white135        )  # Set title color to white136    )137    return fig138 139    140# Function to Calculate Key metrics141class KeyMetrics:142    def __init__(self, data, logNormal=False):143        self.data = data144        self.initialWeights = np.array([1/len(self.data.columns) for _ in range(len(self.data.columns))])145        self.logNormal = logNormal146        self.dailyReturns = None147        self.covarianceMatrix = None148        self.variance = None149        self.standardDeviation = None150        self.expectedReturns = None151        self.sharpeRatio = None152        self.negSharpeRatio = None153 154    def calculate_daily_returns(self):155        self.dailyReturns = np.log(self.data / self.data.shift(1)).dropna() if self.logNormal else self.data.pct_change().dropna()156 157    def calculate_covariance(self):158        if self.dailyReturns is None:159            return "Please Calculate Daily Returns First"160        self.covarianceMatrix = self.dailyReturns.cov() * 252161 162    def calculate_standard_deviation(self):163        if self.covarianceMatrix is None:164            return "Please Calculate Covariance Matrix First"165        self.variance = self.initialWeights.T @ self.covarianceMatrix @ self.initialWeights166        self.standardDeviation = np.sqrt(self.variance)167 168    def calculate_expected_return(self):169        if self.standardDeviation is None:170            return "Please Calculate Standard Deviation First"171        self.expectedReturns = np.sum(self.dailyReturns.mean() * self.initialWeights) * 252172 173    def calculate_sharpe_ratio(self, riskFreeRate):174        if self.expectedReturns is None:175            return "Please Calculate Expected Returns First"176        self.sharpeRatio = (self.expectedReturns - riskFreeRate) / self.standardDeviation177 178    def negative_sharpe_ratio(self):179        if self.sharpeRatio is None:180            return "Please Calculate Sharpe Ratio First"181        self.negSharpeRatio = - self.sharpeRatio182 183 184# Navigation Bar185def navigationBar():186    # Use the following link to get whichever icon you'd like:187    # https://getbootstrap.com/188    options = [189        {"label": "Sharpe Ratio Technique", "icon": "bezier"}190    ]191 192 193    selected = option_menu(194        menu_title= None, #"Ask Me Anything",  # Menu title195        options=[option["label"] for option in options],196        icons=[option["icon"] for option in options],197        menu_icon="lightbulb-fill",198        default_index=0,199        orientation="horizontal",200        styles={201            "container": {202                "display": "flex",203                "flex-direction": "column",204                "justify-content": "center",205                "padding": "20px 40px 20px 40px",  # Increased top and bottom padding206                "background-color": "#00E0FF",  # Dark background color207                "border-radius": "20px",208                "width":"100%",209                "box-shadow": "0px 2px 10px rgba(0, 0, 0, 0.2)",  # Shadow effect210                "margin": "auto",  # Center align the navigation bar211                "overflow-x": "auto",  # Allow horizontal scrolling for small screens212            },213            "menu-title": {214                "font-size": "36px",215                "font-weight": "bold",216                "background-color": "#292",217                "color": "#FFFFFF",  # White text color218                "margin-bottom": "20px",  # Spacing below the menu title219            },220            "menu-icon": {221                "color": "#FFD700",  # Golden yellow icon color222                "font-size": "36px",223                "margin-right": "10px",224            },225            "icon": {226                "color": "#FFD700",  # Golden yellow icon color227                "font-size": "36px",228                "margin-right": "10px",229            },230            "nav-link": {231                "font-size": "20px",232                "text-align": "center",233                "color": "#FFFFFF",  # White text color234                "padding": "10px 20px",235                "border-radius": "15px",236                "transition": "background-color 0.3s ease",237 238            },239            "nav-link-selected": {240                "background-color": "#07A2F4",  # Tomato red when selected241                "color": "#FFFFFF",  # White text color when selected242            }243        },244 245    )246    return selected