Etf flow dashboard
To upload files, please first save the app
import streamlit as st
import pandas as pd
import yfinance as yf
import plotly.graph_objects as go
from datetime import datetime, timedelta
st.title("ETF Flow Dashboard")
# Sidebar for user inputs
st.sidebar.header("Settings")
# Define some popular ETFs
etf_dict = {
"SPY": "SPDR S&P 500 ETF",
"QQQ": "Invesco QQQ Trust",
"IWM": "iShares Russell 2000 ETF",
"EEM": "iShares MSCI Emerging Markets ETF",
"VTI": "Vanguard Total Stock Market ETF",
"GLD": "SPDR Gold Shares",
"TLT": "iShares 20+ Year Treasury Bond ETF"
}
# Let user select ETFs
selected_etfs = st.sidebar.multiselect(
"Select ETFs to analyze",
options=list(etf_dict.keys()),
default=["SPY", "QQQ"],
format_func=lambda x: f"{x} - {etf_dict[x]}"
)
# Date range selector
end_date = datetime.now()
start_date = end_date - timedelta(days=365)
date_range = st.sidebar.date_input(
"Select Date Range",
value=(start_date, end_date),
max_value=end_date
)
if len(date_range) == 2:
start_date, end_date = date_range
else:
st.error("Please select both start and end date")
st.stop()
# Download and process data
@st.cache_data(ttl=3600) # Cache for 1 hour
def get_etf_data(ticker, start, end):
etf = yf.Ticker(ticker)
hist = etf.history(start=start, end=end)
hist['Volume_Price'] = hist['Volume'] * hist['Close']
return hist
if selected_etfs:
# Create tabs for different views
tab1, tab2, tab3 = st.tabs(["Price Performance", "Volume Analysis", "Flow Comparison"])
# Get data for all selected ETFs
etf_data = {}
for etf in selected_etfs:
etf_data[etf] = get_etf_data(etf, start_date, end_date)
with tab1:
st.subheader("Price Performance")
fig = go.Figure()
for etf in selected_etfs:
normalized_price = etf_data[etf]['Close'] / etf_data[etf]['Close'].iloc[0] * 100
fig.add_trace(go.Scatter(
x=normalized_price.index,
y=normalized_price,
name=f"{etf} ({etf_dict[etf]})",
mode='lines'
))
fig.update_layout(
title="Normalized Price Performance (Base=100)",
xaxis_title="Date",
yaxis_title="Price (Normalized)",
height=600
)
st.plotly_chart(fig, use_container_width=True)
with tab2:
st.subheader("Volume Analysis")
fig = go.Figure()
for etf in selected_etfs:
volume_ma = etf_data[etf]['Volume'].rolling(window=20).mean()
fig.add_trace(go.Scatter(
x=volume_ma.index,
y=volume_ma,
name=f"{etf} - 20D MA Volume",
mode='lines'
))
fig.update_layout(
title="20-Day Moving Average Volume",
xaxis_title="Date",
yaxis_title="Volume",
height=600
)
st.plotly_chart(fig, use_container_width=True)
with tab3:
st.subheader("Flow Comparison")
fig = go.Figure()
for etf in selected_etfs:
volume_price = etf_data[etf]['Volume_Price'].rolling(window=5).mean()
fig.add_trace(go.Scatter(
x=volume_price.index,
y=volume_price,
name=f"{etf} - Dollar Volume Flow",
mode='lines'
))
fig.update_layout(
title="5-Day Moving Average Dollar Volume Flow",
xaxis_title="Date",
yaxis_title="Dollar Volume (Price × Volume)",
height=600
)
st.plotly_chart(fig, use_container_width=True)
# Summary metrics
st.subheader("Summary Metrics")
metrics_df = pd.DataFrame()
for etf in selected_etfs:
data = etf_data[etf]
total_return = (data['Close'].iloc[-1] / data['Close'].iloc[0] - 1) * 100
avg_daily_volume = data['Volume'].mean()
avg_dollar_volume = data['Volume_Price'].mean()
metrics_df.loc[etf, 'Total Return (%)'] = f"{total_return:.2f}%"
metrics_df.loc[etf, 'Avg Daily Volume'] = f"{avg_daily_volume:,.0f}"
metrics_df.loc[etf, 'Avg Daily Dollar Volume ($)'] = f"${avg_dollar_volume:,.2f}"
st.dataframe(metrics_df)
else:
st.warning("Please select at least one ETF from the sidebar.")
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?