|
import streamlit as st |
|
from datetime import date |
|
from functions import perform_portfolio_analysis, portfolio_vs_benchmark, portfolio_returns |
|
|
|
def build_ui(): |
|
""" |
|
This function builds the Streamlit UI for the portfolio management app. |
|
""" |
|
|
|
|
|
title = '<h1 style="font-family:Didot; font-size: 64px; text-align:left">PortfolioPro</h1>' |
|
st.markdown(title, unsafe_allow_html=True) |
|
|
|
text = """ |
|
<p style="font-size: 18px; text-align: left;"> |
|
<br>Welcome to <b>PortfolioPro</b>, an intuitive app that streamlines your investment portfolio management. |
|
Effortlessly monitor your assets, benchmark against market standards, and discover valuable insights with just a few clicks. |
|
Here's what you can do: |
|
<br><br> |
|
β’ Enter the ticker symbols exactly as they appear on Yahoo Finance and the total amount invested for each security in your portfolio.<br><br> |
|
β’ Set a benchmark to compare your portfolio's performance against market indices or other chosen standards.<br><br> |
|
β’ Select the start and end dates for the period you wish to analyze and gain historical insights. <br> |
|
Note: The app cannot analyze dates before a company's IPO or use non-business days as your <i>start</i> or <i>end</i> dates.<br><br> |
|
β’ Click "Run Analysis" to visualize historical returns, obtain volatility metrics, and unveil the allocation percentages of your portfolio. |
|
<br><br> |
|
Empower your investment strategy with cutting-edge financial APIs and visualization tools. |
|
<br>Start making informed decisions to elevate your financial future today. |
|
<br><br><br> |
|
Demo video: <a href="https://www.youtube.com/watch?v=7MuQ4G6tq_I">PortfolioPro - Demo</a> |
|
<br><br> |
|
Kaggle Notebook: <a href="https://www.kaggle.com/code/lusfernandotorres/building-an-investment-portfolio-management-app">Building an Investment Portfolio Management App π° - by @lusfernandotorres</a> |
|
<br><br> |
|
</p> |
|
""" |
|
st.markdown(text, unsafe_allow_html=True) |
|
|
|
|
|
if 'num_pairs' not in st.session_state: |
|
st.session_state['num_pairs'] = 1 |
|
|
|
def add_input_pair(): |
|
st.session_state['num_pairs'] += 1 |
|
|
|
tickers_and_values = {} |
|
for n in range(st.session_state['num_pairs']): |
|
col1, col2 = st.columns(2) |
|
with col1: |
|
ticker = st.text_input(f"Ticker {n+1}", key=f"ticker_{n+1}", placeholder="Enter the symbol for a security.") |
|
with col2: |
|
value = st.number_input(f"Value Invested in Ticker {n+1} ($)", min_value=0.0, format="%.2f", key=f"value_{n+1}") |
|
tickers_and_values[ticker] = value |
|
|
|
st.button("Add Another Ticker", on_click=add_input_pair) |
|
|
|
|
|
benchmark = st.text_input("Benchmark", placeholder="Enter the symbol for a benchmark.") |
|
|
|
|
|
col1, col2 = st.columns(2) |
|
with col1: |
|
start_date = st.date_input("Start Date", value=date.today().replace(year=date.today().year - 1), min_value=date(1900, 1, 1)) |
|
with col2: |
|
end_date = st.date_input("End Date", value=date.today(), min_value=date(1900, 1, 1)) |
|
|
|
|
|
if st.button("Run Analysis"): |
|
tickers_and_values = {k: v for k,v in tickers_and_values.items() if k and v > 0} |
|
|
|
if not benchmark: |
|
st.error("Please enter a benchmark ticker before running the analysis.") |
|
elif not tickers_and_values: |
|
st.error("Please add at least one ticker with a non-zero investment value before running the analysis.") |
|
else: |
|
start_date_str=start_date.strftime('%Y-%m-%d') |
|
end_date_str=end_date.strftime('%Y-%m-%d') |
|
|
|
status, result = portfolio_returns(tickers_and_values, start_date_str, end_date_str, benchmark) |
|
|
|
if status == "error": |
|
st.error(result) |
|
else: |
|
fig, fig1, fig2 = result |
|
|
|
if fig is not None: |
|
st.plotly_chart(fig) |
|
if fig1 is not None: |
|
st.plotly_chart(fig1) |
|
if fig2 is not None: |
|
st.plotly_chart(fig2) |
|
|
|
|
|
signature_html = """ |
|
<hr style="border: 0; height: 1px; border-top: 0.85px solid #b2b2b2"> |
|
<div style="text-align: left; color: #8d8d8d; padding-left: 15px; font-size: 14.25px;"> |
|
Luis Fernando Torres, 2024<br><br> |
|
Let's connect!π<br> |
|
<a href="https://www.linkedin.com/in/luuisotorres/" target="_blank">LinkedIn</a> β’ |
|
<a href="https://medium.com/@luuisotorres" target="_blank">Medium</a> β’ |
|
<a href="https://www.kaggle.com/lusfernandotorres" target="_blank">Kaggle</a><br><br> |
|
</div> |
|
<div style="text-align: center; margin-top: 50px; color: #8d8d8d; padding-left: 15px; font-size: 14.25px;"> |
|
<b>Like my content? Feel free to <a href="https://www.buymeacoffee.com/luuisotorres" target="_blank">Buy Me a Coffee β</a></b> |
|
</div> |
|
<div style="text-align: center; margin-top: 80px; color: #8d8d8d; padding-left: 15px; font-size: 14.25px;"> |
|
<b><a href="https://luuisotorres.github.io/" target="_blank">https://luuisotorres.github.io/</a></b> |
|
</div> |
|
""" |
|
st.markdown(signature_html, unsafe_allow_html=True) |