#!/usr/bin/env python3 """ FRED ML - Enterprise Economic Analytics Platform Professional think tank interface for comprehensive economic data analysis """ import streamlit as st import pandas as pd import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots import boto3 import json from datetime import datetime, timedelta import requests import os import sys from typing import Dict, List, Optional from pathlib import Path # Add src to path for analytics modules sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src')) # Import analytics modules try: from src.analysis.comprehensive_analytics import ComprehensiveAnalytics from src.core.enhanced_fred_client import EnhancedFREDClient from config.settings import FRED_API_KEY ANALYTICS_AVAILABLE = True except ImportError: ANALYTICS_AVAILABLE = False st.warning("Advanced analytics modules not available. Running in basic mode.") # Page configuration st.set_page_config( page_title="FRED ML - Economic Analytics Platform", page_icon="🏛️", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for enterprise styling st.markdown(""" """, unsafe_allow_html=True) # Initialize AWS clients @st.cache_resource def init_aws_clients(): """Initialize AWS clients for S3 and Lambda""" try: s3_client = boto3.client('s3') lambda_client = boto3.client('lambda') return s3_client, lambda_client except Exception as e: st.error(f"Failed to initialize AWS clients: {e}") return None, None # Load configuration @st.cache_data def load_config(): """Load application configuration""" return { 's3_bucket': os.getenv('S3_BUCKET', 'fredmlv1'), 'lambda_function': os.getenv('LAMBDA_FUNCTION', 'fred-ml-processor'), 'api_endpoint': os.getenv('API_ENDPOINT', 'http://localhost:8000') } def get_available_reports(s3_client, bucket_name: str) -> List[Dict]: """Get list of available reports from S3""" try: response = s3_client.list_objects_v2( Bucket=bucket_name, Prefix='reports/' ) reports = [] if 'Contents' in response: for obj in response['Contents']: if obj['Key'].endswith('.json'): reports.append({ 'key': obj['Key'], 'last_modified': obj['LastModified'], 'size': obj['Size'] }) return sorted(reports, key=lambda x: x['last_modified'], reverse=True) except Exception as e: st.error(f"Failed to load reports: {e}") return [] def get_report_data(s3_client, bucket_name: str, report_key: str) -> Optional[Dict]: """Get report data from S3""" try: response = s3_client.get_object(Bucket=bucket_name, Key=report_key) data = json.loads(response['Body'].read().decode('utf-8')) return data except Exception as e: st.error(f"Failed to load report data: {e}") return None def trigger_lambda_analysis(lambda_client, function_name: str, payload: Dict) -> bool: """Trigger Lambda function for analysis""" try: response = lambda_client.invoke( FunctionName=function_name, InvocationType='Event', # Asynchronous Payload=json.dumps(payload) ) return response['StatusCode'] == 202 except Exception as e: st.error(f"Failed to trigger analysis: {e}") return False def create_time_series_plot(df: pd.DataFrame, title: str = "Economic Indicators"): """Create interactive time series plot""" fig = go.Figure() colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b'] for i, column in enumerate(df.columns): if column != 'Date': fig.add_trace( go.Scatter( x=df.index, y=df[column], mode='lines', name=column, line=dict(width=2, color=colors[i % len(colors)]), hovertemplate='%{x}
%{y:.2f}' ) ) fig.update_layout( title=dict(text=title, x=0.5, font=dict(size=20)), xaxis_title="Date", yaxis_title="Value", hovermode='x unified', height=500, plot_bgcolor='white', paper_bgcolor='white', font=dict(size=12) ) return fig def create_correlation_heatmap(df: pd.DataFrame): """Create correlation heatmap""" corr_matrix = df.corr() fig = px.imshow( corr_matrix, text_auto=True, aspect="auto", title="Correlation Matrix", color_continuous_scale='RdBu_r', center=0 ) fig.update_layout( title=dict(x=0.5, font=dict(size=20)), height=500, plot_bgcolor='white', paper_bgcolor='white' ) return fig def create_forecast_plot(historical_data, forecast_data, title="Forecast"): """Create forecast plot with confidence intervals""" fig = go.Figure() # Historical data fig.add_trace(go.Scatter( x=historical_data.index, y=historical_data.values, mode='lines', name='Historical', line=dict(color='#1f77b4', width=2) )) # Forecast if 'forecast' in forecast_data: forecast_values = forecast_data['forecast'] forecast_index = pd.date_range( start=historical_data.index[-1] + pd.DateOffset(months=3), periods=len(forecast_values), freq='Q' ) fig.add_trace(go.Scatter( x=forecast_index, y=forecast_values, mode='lines', name='Forecast', line=dict(color='#ff7f0e', width=2, dash='dash') )) # Confidence intervals if 'confidence_intervals' in forecast_data: ci = forecast_data['confidence_intervals'] if 'lower' in ci.columns and 'upper' in ci.columns: fig.add_trace(go.Scatter( x=forecast_index, y=ci['upper'], mode='lines', name='Upper CI', line=dict(color='rgba(255,127,14,0.3)', width=1), showlegend=False )) fig.add_trace(go.Scatter( x=forecast_index, y=ci['lower'], mode='lines', fill='tonexty', name='Confidence Interval', line=dict(color='rgba(255,127,14,0.3)', width=1) )) fig.update_layout( title=dict(text=title, x=0.5, font=dict(size=20)), xaxis_title="Date", yaxis_title="Value", height=500, plot_bgcolor='white', paper_bgcolor='white' ) return fig def main(): """Main Streamlit application""" # Initialize AWS clients s3_client, lambda_client = init_aws_clients() config = load_config() # Sidebar with st.sidebar: st.markdown("""

🏛️ FRED ML

Economic Analytics Platform

""", unsafe_allow_html=True) st.markdown("---") # Navigation page = st.selectbox( "Navigation", ["📊 Executive Dashboard", "🔮 Advanced Analytics", "📈 Economic Indicators", "📋 Reports & Insights", "⚙️ Configuration"] ) if page == "📊 Executive Dashboard": show_executive_dashboard(s3_client, config) elif page == "🔮 Advanced Analytics": show_advanced_analytics_page(config) elif page == "📈 Economic Indicators": show_indicators_page(s3_client, config) elif page == "📋 Reports & Insights": show_reports_page(s3_client, config) elif page == "⚙️ Configuration": show_configuration_page(config) def show_executive_dashboard(s3_client, config): """Show executive dashboard with key metrics""" st.markdown("""

📊 Executive Dashboard

Comprehensive Economic Analytics & Insights

""", unsafe_allow_html=True) # Key metrics row col1, col2, col3, col4 = st.columns(4) with col1: st.markdown("""

📈 GDP Growth

2.1%

Q4 2024

""", unsafe_allow_html=True) with col2: st.markdown("""

🏭 Industrial Production

+0.8%

Monthly Change

""", unsafe_allow_html=True) with col3: st.markdown("""

💰 Inflation Rate

3.2%

Annual Rate

""", unsafe_allow_html=True) with col4: st.markdown("""

💼 Unemployment

3.7%

Current Rate

""", unsafe_allow_html=True) # Recent analysis section st.markdown("""

📊 Recent Analysis

""", unsafe_allow_html=True) # Get latest report reports = get_available_reports(s3_client, config['s3_bucket']) if reports: latest_report = reports[0] report_data = get_report_data(s3_client, config['s3_bucket'], latest_report['key']) if report_data: # Show latest data visualization if 'data' in report_data and report_data['data']: df = pd.DataFrame(report_data['data']) df['Date'] = pd.to_datetime(df['Date']) df.set_index('Date', inplace=True) col1, col2 = st.columns(2) with col1: st.markdown("""

Economic Indicators Trend

""", unsafe_allow_html=True) fig = create_time_series_plot(df) st.plotly_chart(fig, use_container_width=True) with col2: st.markdown("""

Correlation Analysis

""", unsafe_allow_html=True) corr_fig = create_correlation_heatmap(df) st.plotly_chart(corr_fig, use_container_width=True) else: st.warning("No report data available") else: st.info("No reports available. Run an analysis to generate reports.") def show_advanced_analytics_page(config): """Show advanced analytics page with comprehensive analysis capabilities""" st.markdown("""

🔮 Advanced Analytics

Comprehensive Economic Modeling & Forecasting

""", unsafe_allow_html=True) if not ANALYTICS_AVAILABLE: st.error("Advanced analytics modules not available. Please install required dependencies.") return # Analysis configuration st.markdown("""

📋 Analysis Configuration

""", unsafe_allow_html=True) col1, col2 = st.columns(2) with col1: # Economic indicators selection indicators = [ "GDPC1", "INDPRO", "RSAFS", "CPIAUCSL", "FEDFUNDS", "DGS10", "TCU", "PAYEMS", "PCE", "M2SL", "DEXUSEU", "UNRATE" ] selected_indicators = st.multiselect( "Select Economic Indicators", indicators, default=["GDPC1", "INDPRO", "RSAFS"] ) # Date range end_date = datetime.now() start_date = end_date - timedelta(days=365*5) # 5 years start_date_input = st.date_input( "Start Date", value=start_date, max_value=end_date ) end_date_input = st.date_input( "End Date", value=end_date, max_value=end_date ) with col2: # Analysis options forecast_periods = st.slider( "Forecast Periods", min_value=1, max_value=12, value=4, help="Number of periods to forecast" ) include_visualizations = st.checkbox( "Generate Visualizations", value=True, help="Create charts and graphs" ) analysis_type = st.selectbox( "Analysis Type", ["Comprehensive", "Forecasting Only", "Segmentation Only", "Statistical Only"], help="Type of analysis to perform" ) # Run analysis button if st.button("🚀 Run Advanced Analysis", type="primary"): if not selected_indicators: st.error("Please select at least one economic indicator.") return if not FRED_API_KEY: st.error("FRED API key not configured. Please set FRED_API_KEY environment variable.") return # Show progress with st.spinner("Running comprehensive analysis..."): try: # Initialize analytics analytics = ComprehensiveAnalytics(FRED_API_KEY, output_dir="data/exports/streamlit") # Run analysis results = analytics.run_complete_analysis( indicators=selected_indicators, start_date=start_date_input.strftime('%Y-%m-%d'), end_date=end_date_input.strftime('%Y-%m-%d'), forecast_periods=forecast_periods, include_visualizations=include_visualizations ) st.success("✅ Analysis completed successfully!") # Display results display_analysis_results(results) except Exception as e: st.error(f"❌ Analysis failed: {e}") def display_analysis_results(results): """Display comprehensive analysis results""" st.markdown("""

📊 Analysis Results

""", unsafe_allow_html=True) # Create tabs for different result types tab1, tab2, tab3, tab4 = st.tabs(["🔮 Forecasting", "🎯 Segmentation", "📈 Statistical", "💡 Insights"]) with tab1: if 'forecasting' in results: st.subheader("Forecasting Results") forecasting_results = results['forecasting'] for indicator, result in forecasting_results.items(): if 'error' not in result: backtest = result.get('backtest', {}) if 'error' not in backtest: mape = backtest.get('mape', 0) rmse = backtest.get('rmse', 0) col1, col2 = st.columns(2) with col1: st.metric(f"{indicator} MAPE", f"{mape:.2f}%") with col2: st.metric(f"{indicator} RMSE", f"{rmse:.4f}") with tab2: if 'segmentation' in results: st.subheader("Segmentation Results") segmentation_results = results['segmentation'] if 'time_period_clusters' in segmentation_results: time_clusters = segmentation_results['time_period_clusters'] if 'error' not in time_clusters: n_clusters = time_clusters.get('n_clusters', 0) st.info(f"Time periods clustered into {n_clusters} economic regimes") if 'series_clusters' in segmentation_results: series_clusters = segmentation_results['series_clusters'] if 'error' not in series_clusters: n_clusters = series_clusters.get('n_clusters', 0) st.info(f"Economic series clustered into {n_clusters} groups") with tab3: if 'statistical_modeling' in results: st.subheader("Statistical Analysis Results") stat_results = results['statistical_modeling'] if 'correlation' in stat_results: corr_results = stat_results['correlation'] significant_correlations = corr_results.get('significant_correlations', []) st.info(f"Found {len(significant_correlations)} significant correlations") with tab4: if 'insights' in results: st.subheader("Key Insights") insights = results['insights'] for finding in insights.get('key_findings', []): st.write(f"• {finding}") def show_indicators_page(s3_client, config): """Show economic indicators page""" st.markdown("""

📈 Economic Indicators

Real-time Economic Data & Analysis

""", unsafe_allow_html=True) # Indicators overview indicators_info = { "GDPC1": {"name": "Real GDP", "description": "Real Gross Domestic Product", "frequency": "Quarterly"}, "INDPRO": {"name": "Industrial Production", "description": "Industrial Production Index", "frequency": "Monthly"}, "RSAFS": {"name": "Retail Sales", "description": "Retail Sales", "frequency": "Monthly"}, "CPIAUCSL": {"name": "Consumer Price Index", "description": "Inflation measure", "frequency": "Monthly"}, "FEDFUNDS": {"name": "Federal Funds Rate", "description": "Target interest rate", "frequency": "Daily"}, "DGS10": {"name": "10-Year Treasury", "description": "Government bond yield", "frequency": "Daily"} } # Display indicators in cards cols = st.columns(3) for i, (code, info) in enumerate(indicators_info.items()): with cols[i % 3]: st.markdown(f"""

{info['name']}

Code: {code}

Frequency: {info['frequency']}

{info['description']}

""", unsafe_allow_html=True) def show_reports_page(s3_client, config): """Show reports and insights page""" st.markdown("""

📋 Reports & Insights

Comprehensive Analysis Reports

""", unsafe_allow_html=True) # Get available reports reports = get_available_reports(s3_client, config['s3_bucket']) if reports: st.subheader("Available Reports") for report in reports[:5]: # Show last 5 reports with st.expander(f"Report: {report['key']} - {report['last_modified'].strftime('%Y-%m-%d %H:%M')}"): report_data = get_report_data(s3_client, config['s3_bucket'], report['key']) if report_data: st.json(report_data) else: st.info("No reports available. Run an analysis to generate reports.") def show_configuration_page(config): """Show configuration page""" st.markdown("""

⚙️ Configuration

System Settings & Configuration

""", unsafe_allow_html=True) st.subheader("System Configuration") col1, col2 = st.columns(2) with col1: st.write("**AWS Configuration**") st.write(f"S3 Bucket: {config['s3_bucket']}") st.write(f"Lambda Function: {config['lambda_function']}") with col2: st.write("**API Configuration**") st.write(f"API Endpoint: {config['api_endpoint']}") st.write(f"Analytics Available: {ANALYTICS_AVAILABLE}") if __name__ == "__main__": main()