Create an app for stock analysis with mock data. Generate mock daily price data for 5 tech stocks over the past year with standard fields (Open, Close, etc). Features: - Stock selector dropdown - Price trend charts - Basic stats (mean, volatility) - Moving averages - Volume analysis - Stock comparison Interactive elements: - Date range picker - Technical indicators - Chart type toggle Focus on clean visualization of realistic mock data.
To upload files, please first save the app
import streamlit as st
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
from datetime import datetime, timedelta
import random
# Set page config
st.set_page_config(page_title="Stock Analysis Dashboard", layout="wide")
# Import data generation functions
from data_generator import generate_stock_data, calculate_technical_indicators
# Generate mock data for 5 tech stocks
@st.cache_data
def load_stock_data():
stocks = {
'AAPL': {'name': 'Apple Inc.', 'start_price': 150},
'GOOGL': {'name': 'Alphabet Inc.', 'start_price': 2800},
'MSFT': {'name': 'Microsoft Corp.', 'start_price': 330},
'TSLA': {'name': 'Tesla Inc.', 'start_price': 800},
'NVDA': {'name': 'NVIDIA Corp.', 'start_price': 220}
}
all_data = {}
for symbol, info in stocks.items():
data = generate_stock_data(symbol, info['start_price'], info['name'])
all_data[symbol] = calculate_technical_indicators(data)
return all_data
# Load data
stock_data = load_stock_data()
# App title
st.title("📈 Stock Analysis Dashboard")
st.markdown("---")
# Sidebar controls
st.sidebar.header("📊 Analysis Controls")
# Stock selector
selected_stock = st.sidebar.selectbox(
"Select Stock",
options=list(stock_data.keys()),
format_func=lambda x: f"{x} - {stock_data[x]['Name'].iloc[0]}"
)
# Date range picker
df = stock_data[selected_stock]
min_date = df['Date'].min().date()
max_date = df['Date'].max().date()
date_range = st.sidebar.date_input(
"Select Date Range",
value=(min_date, max_date),
min_value=min_date,
max_value=max_date
)
# Chart type toggle
chart_type = st.sidebar.radio(
"Chart Type",
["Candlestick", "Line", "Area"]
)
# Technical indicators
st.sidebar.subheader("Technical Indicators")
show_ma = st.sidebar.checkbox("Moving Averages", value=True)
show_volume = st.sidebar.checkbox("Volume", value=True)
show_rsi = st.sidebar.checkbox("RSI", value=False)
# Stock comparison
st.sidebar.subheader("Stock Comparison")
compare_stocks = st.sidebar.multiselect(
"Compare with other stocks",
options=[s for s in stock_data.keys() if s != selected_stock],
default=[]
)
# Filter data by date range
if len(date_range) == 2:
start_date, end_date = date_range
filtered_df = df[(df['Date'].dt.date >= start_date) & (df['Date'].dt.date <= end_date)]
else:
filtered_df = df
# Main content area
col1, col2 = st.columns([3, 1])
with col1:
# Stock info
current_price = filtered_df['Close'].iloc[-1]
prev_price = filtered_df['Close'].iloc[-2] if len(filtered_df) > 1 else current_price
price_change = current_price - prev_price
price_change_pct = (price_change / prev_price) * 100
st.subheader(f"{selected_stock} - {filtered_df['Name'].iloc[-1]}")
# Price metrics
col_a, col_b, col_c, col_d = st.columns(4)
with col_a:
st.metric("Current Price", f"${current_price:.2f}", f"{price_change:+.2f}")
with col_b:
st.metric("Change %", f"{price_change_pct:+.2f}%")
with col_c:
st.metric("Volume", f"{filtered_df['Volume'].iloc[-1]:,.0f}")
with col_d:
st.metric("Market Cap", f"${filtered_df['Volume'].iloc[-1] * current_price / 1000000:.1f}M")
with col2:
# Basic statistics
st.subheader("📊 Basic Stats")
st.write(f"**Mean Price:** ${filtered_df['Close'].mean():.2f}")
st.write(f"**Volatility:** {filtered_df['Close'].std():.2f}")
st.write(f"**52W High:** ${filtered_df['Close'].max():.2f}")
st.write(f"**52W Low:** ${filtered_df['Close'].min():.2f}")
st.write(f"**Avg Volume:** {filtered_df['Volume'].mean():,.0f}")
# Main chart
st.subheader("📈 Price Chart")
# Create subplots for price and volume
if show_volume:
fig = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.03,
subplot_titles=('Price', 'Volume'),
row_width=[0.2, 0.7]
)
else:
fig = make_subplots(rows=1, cols=1)
# Add price chart
if chart_type == "Candlestick":
fig.add_trace(
go.Candlestick(
x=filtered_df['Date'],
open=filtered_df['Open'],
high=filtered_df['High'],
low=filtered_df['Low'],
close=filtered_df['Close'],
name=selected_stock
),
row=1, col=1
)
elif chart_type == "Line":
fig.add_trace(
go.Scatter(
x=filtered_df['Date'],
y=filtered_df['Close'],
mode='lines',
name=selected_stock,
line=dict(width=2)
),
row=1, col=1
)
else: # Area
fig.add_trace(
go.Scatter(
x=filtered_df['Date'],
y=filtered_df['Close'],
mode='lines',
fill='tonexty',
name=selected_stock,
line=dict(width=1)
),
row=1, col=1
)
# Add moving averages
if show_ma:
fig.add_trace(
go.Scatter(
x=filtered_df['Date'],
y=filtered_df['MA_20'],
mode='lines',
name='MA 20',
line=dict(color='orange', width=1)
),
row=1, col=1
)
fig.add_trace(
go.Scatter(
x=filtered_df['Date'],
y=filtered_df['MA_50'],
mode='lines',
name='MA 50',
line=dict(color='red', width=1)
),
row=1, col=1
)
# Add comparison stocks
for comp_stock in compare_stocks:
comp_df = stock_data[comp_stock]
if len(date_range) == 2:
comp_filtered = comp_df[(comp_df['Date'].dt.date >= start_date) & (comp_df['Date'].dt.date <= end_date)]
else:
comp_filtered = comp_df
# Normalize prices for comparison
base_price = comp_filtered['Close'].iloc[0]
main_base = filtered_df['Close'].iloc[0]
normalized_prices = (comp_filtered['Close'] / base_price) * main_base
fig.add_trace(
go.Scatter(
x=comp_filtered['Date'],
y=normalized_prices,
mode='lines',
name=f"{comp_stock} (normalized)",
line=dict(width=1, dash='dash')
),
row=1, col=1
)
# Add volume chart
if show_volume:
fig.add_trace(
go.Bar(
x=filtered_df['Date'],
y=filtered_df['Volume'],
name='Volume',
marker_color='lightblue',
opacity=0.7
),
row=2, col=1
)
# Update layout
fig.update_layout(
title=f"{selected_stock} Stock Analysis",
xaxis_title="Date",
yaxis_title="Price ($)",
height=600,
showlegend=True,
xaxis_rangeslider_visible=False
)
if show_volume:
fig.update_yaxes(title_text="Volume", row=2, col=1)
st.plotly_chart(fig, use_container_width=True)
# RSI Chart
if show_rsi:
st.subheader("📊 RSI (Relative Strength Index)")
rsi_fig = go.Figure()
rsi_fig.add_trace(
go.Scatter(
x=filtered_df['Date'],
y=filtered_df['RSI'],
mode='lines',
name='RSI',
line=dict(color='purple')
)
)
rsi_fig.add_hline(y=70, line_dash="dash", line_color="red", annotation_text="Overbought (70)")
rsi_fig.add_hline(y=30, line_dash="dash", line_color="green", annotation_text="Oversold (30)")
rsi_fig.update_layout(
title="RSI Indicator",
xaxis_title="Date",
yaxis_title="RSI",
height=300,
yaxis=dict(range=[0, 100])
)
st.plotly_chart(rsi_fig, use_container_width=True)
# Volume Analysis
st.subheader("📊 Volume Analysis")
col1, col2 = st.columns(2)
with col1:
# Volume distribution
vol_fig = px.histogram(
filtered_df,
x='Volume',
nbins=30,
title="Volume Distribution"
)
vol_fig.update_layout(height=300)
st.plotly_chart(vol_fig, use_container_width=True)
with col2:
# Price vs Volume correlation
corr_fig = px.scatter(
filtered_df,
x='Volume',
y='Close',
title="Price vs Volume Correlation",
opacity=0.6
)
corr_fig.update_layout(height=300)
st.plotly_chart(corr_fig, use_container_width=True)
# Data table
st.subheader("📋 Recent Data")
st.dataframe(
filtered_df[['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'MA_20', 'MA_50']].tail(10),
use_container_width=True
)
# Footer
st.markdown("---")
st.markdown("*This dashboard uses mock data for demonstration purposes. Real trading decisions should not be based on this data.*")
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?