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
from plotly.subplots import make_subplots
from datetime import datetime, timedelta
import yfinance as yf
# Page config
st.set_page_config(layout="wide")
# Mock data generation
def generate_mock_stock_data():
stocks = {
'AAPL': {'mean': 150, 'volatility': 0.02},
'GOOGL': {'mean': 2800, 'volatility': 0.025},
'MSFT': {'mean': 280, 'volatility': 0.018},
'AMZN': {'mean': 3300, 'volatility': 0.03},
'META': {'mean': 300, 'volatility': 0.035}
}
end_date = datetime.now()
start_date = end_date - timedelta(days=365)
dates = pd.date_range(start=start_date, end=end_date, freq='D')
all_stocks_data = {}
for ticker, params in stocks.items():
np.random.seed(42) # For reproducibility
# Generate daily returns
daily_returns = np.random.normal(
loc=params['volatility']/np.sqrt(252),
scale=params['volatility'],
size=len(dates)
)
# Generate price path
price = params['mean'] * np.exp(np.cumsum(daily_returns))
# Generate other price components
volume = np.random.lognormal(mean=np.log(1000000), sigma=0.5, size=len(dates))
high = price * (1 + abs(np.random.normal(0, 0.015, size=len(dates))))
low = price * (1 - abs(np.random.normal(0, 0.015, size=len(dates))))
open_price = price * (1 + np.random.normal(0, 0.01, size=len(dates)))
df = pd.DataFrame({
'Date': dates,
'Open': open_price,
'High': high,
'Low': low,
'Close': price,
'Volume': volume.astype(int),
'MA20': pd.Series(price).rolling(window=20).mean(),
'MA50': pd.Series(price).rolling(window=50).mean(),
'MA200': pd.Series(price).rolling(window=200).mean(),
})
df.set_index('Date', inplace=True)
all_stocks_data[ticker] = df
return all_stocks_data
# Load data
@st.cache_data
def load_data():
return generate_mock_stock_data()
stock_data = load_data()
# Sidebar
st.sidebar.title('Stock Analysis')
selected_stock = st.sidebar.selectbox('Select Stock', list(stock_data.keys()))
chart_type = st.sidebar.selectbox('Chart Type', ['Candlestick', 'Line'])
# Date range selector
col1, col2 = st.sidebar.columns(2)
with col1:
start_date = st.date_input('Start Date', stock_data[selected_stock].index.min())
with col2:
end_date = st.date_input('End Date', stock_data[selected_stock].index.max())
# Technical indicators
show_ma = st.sidebar.checkbox('Show Moving Averages', True)
show_volume = st.sidebar.checkbox('Show Volume', True)
# Main content
st.title(f'{selected_stock} Stock Analysis')
# Filter data based on date range
mask = (stock_data[selected_stock].index.date >= start_date) & (stock_data[selected_stock].index.date <= end_date)
df = stock_data[selected_stock][mask]
# Create the main price chart
fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
vertical_spacing=0.03,
row_heights=[0.7, 0.3])
if chart_type == 'Candlestick':
fig.add_trace(
go.Candlestick(
x=df.index,
open=df['Open'],
high=df['High'],
low=df['Low'],
close=df['Close'],
name='OHLC'
),
row=1, col=1
)
else:
fig.add_trace(
go.Scatter(
x=df.index,
y=df['Close'],
name='Close Price',
line=dict(color='blue')
),
row=1, col=1
)
# Add moving averages
if show_ma:
fig.add_trace(go.Scatter(x=df.index, y=df['MA20'], name='MA20', line=dict(color='yellow', width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df.index, y=df['MA50'], name='MA50', line=dict(color='orange', width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df.index, y=df['MA200'], name='MA200', line=dict(color='red', width=1)), row=1, col=1)
# Add volume chart
if show_volume:
fig.add_trace(
go.Bar(x=df.index, y=df['Volume'], name='Volume'),
row=2, col=1
)
# Update layout
fig.update_layout(
height=800,
showlegend=True,
xaxis_rangeslider_visible=False,
title=f'{selected_stock} Stock Price'
)
st.plotly_chart(fig, use_container_width=True)
# Statistics
st.header('Stock Statistics')
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric('Current Price', f"${df['Close'].iloc[-1]:.2f}")
with col2:
st.metric('Average Price', f"${df['Close'].mean():.2f}")
with col3:
daily_returns = df['Close'].pct_change()
volatility = daily_returns.std() * np.sqrt(252) # Annualized volatility
st.metric('Volatility', f"{volatility:.2%}")
with col4:
total_return = (df['Close'].iloc[-1] - df['Close'].iloc[0]) / df['Close'].iloc[0]
st.metric('Total Return', f"{total_return:.2%}")
# Stock comparison
st.header('Stock Comparison')
comparison_stocks = st.multiselect('Compare with', list(stock_data.keys()), default=[list(stock_data.keys())[1]])
if comparison_stocks:
fig_comparison = go.Figure()
# Normalize prices to 100
fig_comparison.add_trace(go.Scatter(
x=df.index,
y=df['Close'] / df['Close'].iloc[0] * 100,
name=selected_stock
))
for comp_stock in comparison_stocks:
comp_df = stock_data[comp_stock][mask]
fig_comparison.add_trace(go.Scatter(
x=comp_df.index,
y=comp_df['Close'] / comp_df['Close'].iloc[0] * 100,
name=comp_stock
))
fig_comparison.update_layout(
title='Price Performance Comparison (Normalized to 100)',
yaxis_title='Normalized Price',
height=500
)
st.plotly_chart(fig_comparison, use_container_width=True)
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?