|
|
"""Financial Analysis Dashboard - Main Application.""" |
|
|
|
|
|
import streamlit as st |
|
|
from dotenv import load_dotenv |
|
|
import os |
|
|
|
|
|
from styles import DARK_THEME_CSS |
|
|
from data import ( |
|
|
load_stock_data, |
|
|
load_company_profile, |
|
|
load_income_statement, |
|
|
calculate_technical_indicators, |
|
|
get_price_metrics, |
|
|
) |
|
|
from charts import ( |
|
|
create_price_chart, |
|
|
create_rsi_chart, |
|
|
create_financial_chart, |
|
|
) |
|
|
from ui import ( |
|
|
display_price_metrics, |
|
|
display_company_info, |
|
|
display_financial_metrics, |
|
|
display_income_statement, |
|
|
display_profitability_metrics, |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
load_dotenv() |
|
|
token = os.getenv("TOKEN") |
|
|
|
|
|
st.set_page_config( |
|
|
page_title="Financial Dashboard", |
|
|
page_icon="π", |
|
|
layout="wide", |
|
|
initial_sidebar_state="expanded", |
|
|
menu_items={ |
|
|
"About": "A professional financial analysis dashboard with technical indicators" |
|
|
} |
|
|
) |
|
|
|
|
|
|
|
|
st.markdown(DARK_THEME_CSS, unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.markdown("# π Financial Analysis Dashboard") |
|
|
st.markdown("Real-time technical analysis with multiple indicators") |
|
|
|
|
|
|
|
|
with st.sidebar: |
|
|
st.markdown("## βοΈ Settings") |
|
|
symbol = st.text_input("Stock Ticker", "AAPL", help="Enter a valid stock ticker symbol").upper() |
|
|
period = st.slider("Indicator Period", 5, 50, 20, help="Period for SMA, EMA, and RSI calculations") |
|
|
|
|
|
st.markdown("---") |
|
|
st.markdown("### About") |
|
|
st.info("This dashboard provides real-time technical analysis with comprehensive financial metrics.") |
|
|
|
|
|
|
|
|
def main(): |
|
|
"""Main application logic.""" |
|
|
if st.button("οΏ½οΏ½ Load Dashboard", key="load_btn", use_container_width=True): |
|
|
try: |
|
|
|
|
|
with st.spinner("Loading data..."): |
|
|
df = load_stock_data(symbol) |
|
|
profile_info = load_company_profile(symbol) |
|
|
income_stmt = load_income_statement(symbol) |
|
|
|
|
|
|
|
|
df = calculate_technical_indicators(df, period) |
|
|
|
|
|
|
|
|
metrics = get_price_metrics(df) |
|
|
display_price_metrics(metrics) |
|
|
|
|
|
|
|
|
display_company_info(profile_info) |
|
|
|
|
|
|
|
|
if not income_stmt.empty: |
|
|
display_financial_metrics(income_stmt) |
|
|
|
|
|
|
|
|
st.markdown('<div class="section-title">π Revenue & Net Income Trend</div>', unsafe_allow_html=True) |
|
|
income_chart_data = income_stmt[['period_ending', 'total_revenue', 'net_income']].dropna() |
|
|
|
|
|
if len(income_chart_data) > 0: |
|
|
fig_financial = create_financial_chart(income_chart_data) |
|
|
st.plotly_chart(fig_financial, use_container_width=True) |
|
|
|
|
|
|
|
|
tab1, tab2, tab3, tab4 = st.tabs([ |
|
|
"π Price & Moving Averages", |
|
|
"π RSI Indicator", |
|
|
"π TradingView", |
|
|
"π Financials" |
|
|
]) |
|
|
|
|
|
|
|
|
with tab1: |
|
|
fig_price = create_price_chart(df, symbol, period) |
|
|
st.plotly_chart(fig_price, use_container_width=True) |
|
|
|
|
|
|
|
|
with tab2: |
|
|
fig_rsi = create_rsi_chart(df, symbol) |
|
|
st.plotly_chart(fig_rsi, use_container_width=True) |
|
|
|
|
|
|
|
|
with tab3: |
|
|
tradingview_html = f""" |
|
|
<div class="tradingview-widget-container"> |
|
|
<div id="tradingview_{symbol}"></div> |
|
|
<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script> |
|
|
<script type="text/javascript"> |
|
|
new TradingView.widget({{ |
|
|
"width": "100%", |
|
|
"height": 600, |
|
|
"symbol": "{symbol}", |
|
|
"interval": "D", |
|
|
"timezone": "Etc/UTC", |
|
|
"theme": "dark", |
|
|
"style": "1", |
|
|
"locale": "en", |
|
|
"enable_publishing": false, |
|
|
"allow_symbol_change": true, |
|
|
"container_id": "tradingview_{symbol}" |
|
|
}}); |
|
|
</script> |
|
|
</div> |
|
|
""" |
|
|
st.components.v1.html(tradingview_html, height=650) |
|
|
|
|
|
|
|
|
with tab4: |
|
|
if not income_stmt.empty: |
|
|
display_income_statement(income_stmt) |
|
|
display_profitability_metrics(income_stmt) |
|
|
|
|
|
except Exception as e: |
|
|
st.error(f"Error loading data for {symbol}: {str(e)}") |
|
|
st.info("Please check the ticker symbol and try again.") |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |
|
|
|