Spaces:
Sleeping
Sleeping
import pandas as pd | |
import streamlit as st | |
from utilities.py.data_management import CompData, PortfolioOptimizer | |
from utilities.py.ui_elements import UserInput | |
from utilities.py import plots, summary_tables | |
class CapiPortApp: | |
def __init__(self, company_df): | |
""" | |
Class for composing the apps UI on a high level. Is meant to provide a readable overview, of what happens inside the app, without being concerned with unnecessary details. | |
Uppon initializing the composer fetches the data within the apps source code (for now) and let's a dedicated class handle the raw data. | |
""" | |
self.comp_data = CompData(company_df) | |
# get all the necessary ui elements | |
self.user_input = UserInput(self.comp_data) | |
def render_user_input(self): | |
self.user_input.company_selection() | |
self.user_input.opt_method_selection() | |
self.user_input.start_date() | |
self.user_input.initial_investment() | |
def render_results(self): | |
""" | |
CAUTION: the composer assumes, that the user has given all the necessary data. | |
NECESSARY DATA: | |
- at least two companies | |
- an optimization method | |
- a start date | |
- initial investment | |
Check the conditions the necessary conditions beforehand :) | |
""" | |
# fetch user input | |
user_input_data = self.user_input.get_user_input_data() | |
# optimize the chosen portfolio according to the specifications | |
portfolio_opt = PortfolioOptimizer(self.comp_data, | |
self.user_input.get_selected_comp_ids(), | |
user_input_data.start_date) | |
company_asset_weights = portfolio_opt.optimize(user_input_data.opt_method, | |
user_input_data.ef_parameter) | |
# show first the stock data... | |
st.dataframe(portfolio_opt.stock_data, use_container_width=True) | |
# print disclaimer | |
first_date_available = portfolio_opt.stock_data.index[0] | |
opt_header = f"Used {user_input_data.opt_method}" if user_input_data.ef_parameter is None else f"Used {user_input_data.opt_method} with {user_input_data.ef_parameter}" | |
st.write( | |
f"Note: Due to unavailability of full data, this Analysis uses data from the date: {first_date_available}") | |
st.write(opt_header) | |
# show asset weights, portfolio performance and the pie chart | |
st.dataframe(company_asset_weights, use_container_width=True) | |
st.dataframe(portfolio_opt.get_portfolio_performance(), | |
use_container_width=True) | |
plots.pie_chart_company_asset_weights(company_asset_weights) | |
# summarize the resulting data | |
portfolio_returns = portfolio_opt.get_portfolio_returns() | |
annual_portfolio_returns = portfolio_opt.get_annual_portfolio_returns() | |
cumulative_returns = (portfolio_returns + | |
1).cumprod() * user_input_data.init_invest | |
# render the tabs | |
tab1, tab2, tab3 = st.tabs( | |
["Plots", "Annual Returns", "Montly Returns"]) | |
with tab1: | |
plots.plot_annual_returns(annual_portfolio_returns) | |
plots.plot_cummulative_returns(cumulative_returns) | |
with tab2: | |
annual_portfolio_returns = summary_tables.annual_returns_dataframe( | |
annual_portfolio_returns | |
) | |
annual_cumulative_returns = ( | |
summary_tables.annual_cumulative_returns_dataframe( | |
cumulative_returns) | |
) | |
annual_stock_returns = summary_tables.company_wise_annual_return( | |
portfolio_opt.stock_data_returns, company_asset_weights | |
) | |
merged_annual_returns_data = pd.merge( | |
annual_portfolio_returns, | |
annual_cumulative_returns, | |
on="Year", | |
suffixes=("_portfolio", "_cumulative"), | |
) | |
merged_annual_returns_data = pd.merge( | |
merged_annual_returns_data, annual_stock_returns, on="Year" | |
) | |
st.write("Annual Returns") | |
st.dataframe(merged_annual_returns_data, use_container_width=True) | |
with tab3: | |
monthly_portfolio_return = summary_tables.monthly_returns_dataframe( | |
portfolio_returns | |
) | |
monthly_stock_return = summary_tables.company_wise_monthly_return( | |
portfolio_opt.stock_data_returns, company_asset_weights | |
) | |
monthly_cumulative_returns = ( | |
summary_tables.monthly_cumulative_returns_dataframe( | |
cumulative_returns) | |
) | |
merged_monthly_returns_data = pd.merge( | |
monthly_portfolio_return, | |
monthly_cumulative_returns, | |
on=["Year", "Month"], | |
how="inner", | |
) | |
merged_monthly_returns_data = pd.merge( | |
merged_monthly_returns_data, | |
monthly_stock_return, | |
on=["Year", "Month"], | |
how="inner", | |
) | |
st.write("Montly Return") | |
st.dataframe(merged_monthly_returns_data, use_container_width=True) | |