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 pandas as pd
import numpy as np
class StockAnalyzer:
def __init__(self, stock_data):
self.stock_data = stock_data
def calculate_basic_stats(self, df):
"""Calculate basic statistics for a stock dataframe"""
stats = {
'Current Price': df['Close'].iloc[-1],
'Mean Price': df['Close'].mean(),
'Median Price': df['Close'].median(),
'Max Price': df['Close'].max(),
'Min Price': df['Close'].min(),
'Price Range': df['Close'].max() - df['Close'].min(),
'Total Return (%)': ((df['Close'].iloc[-1] / df['Close'].iloc[0]) - 1) * 100,
'Avg Daily Volume': df['Volume'].mean()
}
# Round numerical values
for key, value in stats.items():
if isinstance(value, (int, float)):
if 'Volume' in key:
stats[key] = f"{value:,.0f}"
elif '%' in key:
stats[key] = f"{value:.2f}%"
else:
stats[key] = f"${value:.2f}"
return stats
def calculate_risk_metrics(self, df):
"""Calculate risk metrics for a stock dataframe"""
# Calculate daily returns
df_copy = df.copy()
df_copy['Daily_Return'] = df_copy['Close'].pct_change()
# Remove NaN values
returns = df_copy['Daily_Return'].dropna()
if len(returns) == 0:
return {}
# Calculate metrics
volatility = returns.std() * np.sqrt(252) * 100 # Annualized volatility
sharpe_ratio = (returns.mean() * 252) / (returns.std() * np.sqrt(252)) if returns.std() != 0 else 0
# Value at Risk (5%)
var_5 = np.percentile(returns, 5) * 100
# Maximum drawdown
cumulative = (1 + returns).cumprod()
running_max = cumulative.expanding().max()
drawdowns = (cumulative - running_max) / running_max
max_drawdown = drawdowns.min() * 100
risk_metrics = {
'Volatility (%)': f"{volatility:.2f}%",
'Sharpe Ratio': f"{sharpe_ratio:.2f}",
'VaR (5%)': f"{var_5:.2f}%",
'Max Drawdown (%)': f"{max_drawdown:.2f}%",
'Beta': self._calculate_beta(returns),
'Avg Daily Return (%)': f"{returns.mean() * 100:.3f}%"
}
return risk_metrics
def _calculate_beta(self, returns):
"""Calculate beta relative to market (using average of other stocks as proxy)"""
try:
# Use AAPL as market proxy (simple approach)
market_data = self.stock_data.get('AAPL')
if market_data is not None and len(market_data) > 1:
market_returns = market_data['Close'].pct_change().dropna()
# Align the series
min_len = min(len(returns), len(market_returns))
if min_len > 10: # Need sufficient data points
returns_aligned = returns.iloc[-min_len:]
market_aligned = market_returns.iloc[-min_len:]
# Calculate beta
covariance = np.cov(returns_aligned, market_aligned)[0, 1]
market_variance = np.var(market_aligned)
if market_variance != 0:
beta = covariance / market_variance
return f"{beta:.2f}"
return "N/A"
except:
return "N/A"
def calculate_moving_average(self, series, window):
"""Calculate moving average"""
return series.rolling(window=window).mean()
def calculate_rsi(self, prices, period=14):
"""Calculate Relative Strength Index"""
delta = prices.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
def calculate_bollinger_bands(self, prices, window=20, num_std=2):
"""Calculate Bollinger Bands"""
rolling_mean = prices.rolling(window=window).mean()
rolling_std = prices.rolling(window=window).std()
upper_band = rolling_mean + (rolling_std * num_std)
lower_band = rolling_mean - (rolling_std * num_std)
return {
'upper': upper_band,
'middle': rolling_mean,
'lower': lower_band
}
def calculate_correlation_matrix(self, stocks, start_date, end_date):
"""Calculate correlation matrix for selected stocks"""
correlation_data = {}
for stock in stocks:
if stock in self.stock_data:
df = self.stock_data[stock]
df_filtered = df[(df['Date'] >= pd.to_datetime(start_date)) &
(df['Date'] <= pd.to_datetime(end_date))]
if not df_filtered.empty:
correlation_data[stock] = df_filtered.set_index('Date')['Close']
if correlation_data:
corr_df = pd.DataFrame(correlation_data)
return corr_df.corr()
return pd.DataFrame()
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?