Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| from datetime import datetime, timedelta | |
| import json | |
| # Custom CSS with Tailwind-like utilities | |
| def load_css(): | |
| st.markdown(""" | |
| <style> | |
| /* Tailwind-inspired utilities */ | |
| .dashboard-card { | |
| background-color: white; | |
| border-radius: 0.5rem; | |
| padding: 1.5rem; | |
| box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); | |
| margin-bottom: 1rem; | |
| } | |
| .metric-card { | |
| background-color: #f8fafc; | |
| border-radius: 0.375rem; | |
| padding: 1rem; | |
| margin: 0.5rem 0; | |
| border: 1px solid #e2e8f0; | |
| } | |
| .metric-title { | |
| color: #64748b; | |
| font-size: 0.875rem; | |
| font-weight: 500; | |
| margin-bottom: 0.5rem; | |
| } | |
| .metric-value { | |
| color: #1e293b; | |
| font-size: 1.5rem; | |
| font-weight: 600; | |
| } | |
| .risk-high { | |
| color: #dc2626; | |
| } | |
| .risk-moderate { | |
| color: #d97706; | |
| } | |
| .risk-low { | |
| color: #059669; | |
| } | |
| /* Custom Streamlit modifications */ | |
| .stApp { | |
| background-color: #f1f5f9; | |
| } | |
| .css-1d391kg { | |
| padding: 1rem 1rem; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| class FinancialDashboard: | |
| def __init__(self): | |
| self.risk_analyzer = FinancialRiskAnalyzer() | |
| load_css() | |
| def run(self): | |
| st.set_page_config( | |
| page_title="Financial Risk Analysis Dashboard", | |
| page_icon="π", | |
| layout="wide" | |
| ) | |
| # Sidebar | |
| self.create_sidebar() | |
| # Main dashboard | |
| st.title("π Financial Risk Analysis Dashboard") | |
| # Load sample or uploaded data | |
| financial_data = self.load_financial_data() | |
| if financial_data: | |
| # Generate risk report | |
| risk_report = self.risk_analyzer.generate_risk_report(financial_data) | |
| # Display dashboard components | |
| self.display_risk_summary(risk_report) | |
| self.display_detailed_metrics(risk_report) | |
| self.display_risk_charts(financial_data, risk_report) | |
| self.display_recommendations(risk_report) | |
| def create_sidebar(self): | |
| with st.sidebar: | |
| st.title("Controls & Filters") | |
| # Date range selector | |
| st.subheader("Date Range") | |
| start_date = st.date_input( | |
| "Start Date", | |
| datetime.now() - timedelta(days=30) | |
| ) | |
| end_date = st.date_input( | |
| "End Date", | |
| datetime.now() | |
| ) | |
| # Risk threshold adjustments | |
| st.subheader("Risk Thresholds") | |
| leverage_threshold = st.slider( | |
| "Leverage Ratio Threshold", | |
| min_value=10.0, | |
| max_value=50.0, | |
| value=30.0 | |
| ) | |
| npl_threshold = st.slider( | |
| "NPL Ratio Threshold (%)", | |
| min_value=1.0, | |
| max_value=10.0, | |
| value=5.0 | |
| ) / 100 | |
| # Export options | |
| st.subheader("Export Options") | |
| if st.button("Export Report (PDF)"): | |
| st.info("Generating PDF report...") | |
| # Add PDF export functionality | |
| if st.button("Export Data (Excel)"): | |
| st.info("Generating Excel file...") | |
| # Add Excel export functionality | |
| def load_financial_data(self): | |
| # File upload option | |
| uploaded_file = st.file_uploader( | |
| "Upload financial data (JSON/CSV)", | |
| type=["json", "csv"] | |
| ) | |
| if uploaded_file: | |
| try: | |
| if uploaded_file.type == "application/json": | |
| return json.load(uploaded_file) | |
| else: | |
| df = pd.read_csv(uploaded_file) | |
| return df.to_dict() | |
| except Exception as e: | |
| st.error(f"Error loading file: {str(e)}") | |
| return None | |
| # Use sample data if no file uploaded | |
| return self.get_sample_data() | |
| def display_risk_summary(self, risk_report): | |
| st.subheader("Risk Summary") | |
| # Create three columns for key metrics | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| self.metric_card( | |
| "Overall Risk Level", | |
| risk_report['risk_level'], | |
| self.get_risk_color(risk_report['risk_level']) | |
| ) | |
| with col2: | |
| self.metric_card( | |
| "Risk Score", | |
| f"{risk_report['risk_score']:.2f}", | |
| self.get_risk_color(risk_report['risk_level']) | |
| ) | |
| with col3: | |
| self.metric_card( | |
| "Total Alerts", | |
| len(risk_report['risk_alerts']), | |
| "risk-moderate" if len(risk_report['risk_alerts']) > 0 else "risk-low" | |
| ) | |
| # Risk Alerts | |
| if risk_report['risk_alerts']: | |
| st.markdown("### β οΈ Risk Alerts") | |
| for alert in risk_report['risk_alerts']: | |
| st.warning(alert) | |
| def display_detailed_metrics(self, risk_report): | |
| st.subheader("Detailed Metrics") | |
| # Create tabs for different metric categories | |
| tabs = st.tabs([ | |
| "Basic Ratios", | |
| "Funding Risk", | |
| "Asset Quality", | |
| "Market Risk", | |
| "Operational Risk" | |
| ]) | |
| # Basic Ratios Tab | |
| with tabs[0]: | |
| metrics = risk_report['detailed_metrics']['basic_ratios'] | |
| self.create_metrics_grid(metrics) | |
| # Funding Risk Tab | |
| with tabs[1]: | |
| metrics = risk_report['detailed_metrics']['funding_risks'] | |
| self.create_metrics_grid(metrics) | |
| # Asset Quality Tab | |
| with tabs[2]: | |
| metrics = risk_report['detailed_metrics']['asset_risks'] | |
| self.create_metrics_grid(metrics) | |
| # Market Risk Tab | |
| with tabs[3]: | |
| metrics = risk_report['detailed_metrics']['market_risks'] | |
| self.create_metrics_grid(metrics) | |
| # Operational Risk Tab | |
| with tabs[4]: | |
| metrics = risk_report['detailed_metrics']['operational_risks'] | |
| self.create_metrics_grid(metrics) | |
| def display_risk_charts(self, financial_data, risk_report): | |
| st.subheader("Risk Analysis Charts") | |
| # Create two columns for charts | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| # Radar chart for key risk indicators | |
| self.create_radar_chart(risk_report) | |
| with col2: | |
| # Time series chart for trending metrics | |
| self.create_trend_chart(financial_data) | |
| # Additional charts in new row | |
| col3, col4 = st.columns(2) | |
| with col3: | |
| # Asset composition pie chart | |
| self.create_asset_composition_chart(financial_data) | |
| with col4: | |
| # Funding structure chart | |
| self.create_funding_structure_chart(financial_data) | |
| def display_recommendations(self, risk_report): | |
| st.subheader("Recommendations & Actions") | |
| # Generate recommendations based on risk levels | |
| recommendations = self.generate_recommendations(risk_report) | |
| for category, rec_list in recommendations.items(): | |
| with st.expander(f"π {category}"): | |
| for rec in rec_list: | |
| st.markdown(f"- {rec}") | |
| def metric_card(self, title, value, risk_class): | |
| st.markdown(f""" | |
| <div class="metric-card"> | |
| <div class="metric-title">{title}</div> | |
| <div class="metric-value {risk_class}">{value}</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| def create_metrics_grid(self, metrics): | |
| cols = st.columns(2) | |
| for idx, (metric, value) in enumerate(metrics.items()): | |
| with cols[idx % 2]: | |
| self.metric_card( | |
| self.format_metric_name(metric), | |
| f"{value:.2%}" if isinstance(value, float) else value, | |
| self.get_metric_risk_color(metric, value) | |
| ) | |
| def create_radar_chart(self, risk_report): | |
| # Extract key risk indicators | |
| metrics = risk_report['detailed_metrics']['basic_ratios'] | |
| fig = go.Figure() | |
| categories = list(metrics.keys()) | |
| values = list(metrics.values()) | |
| fig.add_trace(go.Scatterpolar( | |
| r=values, | |
| theta=categories, | |
| fill='toself', | |
| name='Current' | |
| )) | |
| fig.update_layout( | |
| polar=dict( | |
| radialaxis=dict( | |
| visible=True, | |
| range=[0, 1] | |
| ) | |
| ), | |
| showlegend=False | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| def create_trend_chart(self, financial_data): | |
| # Create sample trend data | |
| dates = pd.date_range(end=datetime.now(), periods=30, freq='D') | |
| trend_data = pd.DataFrame({ | |
| 'Date': dates, | |
| 'Risk Score': np.random.uniform(2, 6, 30) | |
| }) | |
| fig = px.line( | |
| trend_data, | |
| x='Date', | |
| y='Risk Score', | |
| title='Risk Score Trend' | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| def create_asset_composition_chart(self, financial_data): | |
| # Extract asset composition | |
| assets = { | |
| 'Corporate Loans': financial_data.get('corporate_loans', 0), | |
| 'Retail Loans': financial_data.get('retail_loans', 0), | |
| 'Securities': financial_data.get('securities', 0), | |
| 'Interbank Assets': financial_data.get('interbank_assets', 0) | |
| } | |
| fig = px.pie( | |
| values=list(assets.values()), | |
| names=list(assets.keys()), | |
| title='Asset Composition' | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| def create_funding_structure_chart(self, financial_data): | |
| # Extract funding structure | |
| funding = { | |
| 'Retail Deposits': financial_data.get('retail_deposits', 0), | |
| 'Corporate Deposits': financial_data.get('corporate_deposits', 0), | |
| 'Wholesale Funding': financial_data.get('wholesale_funding', 0), | |
| 'Interbank Borrowing': financial_data.get('interbank_borrowing', 0) | |
| } | |
| fig = px.bar( | |
| x=list(funding.keys()), | |
| y=list(funding.values()), | |
| title='Funding Structure' | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| def get_risk_color(risk_level): | |
| colors = { | |
| 'CRITICAL': 'risk-high', | |
| 'HIGH': 'risk-high', | |
| 'MODERATE': 'risk-moderate', | |
| 'LOW': 'risk-low' | |
| } | |
| return colors.get(risk_level, 'risk-low') | |
| def get_metric_risk_color(metric, value): | |
| # Add logic to determine color based on metric type and value | |
| return 'risk-moderate' | |
| def format_metric_name(metric): | |
| return metric.replace('_', ' ').title() | |
| def generate_recommendations(risk_report): | |
| recommendations = { | |
| 'Immediate Actions': [ | |
| 'Review and adjust leverage levels', | |
| 'Strengthen liquidity buffers', | |
| 'Enhance risk monitoring systems' | |
| ], | |
| 'Medium-term Improvements': [ | |
| 'Develop comprehensive risk management framework', | |
| 'Implement stress testing scenarios', | |
| 'Review counterparty exposure limits' | |
| ], | |
| 'Long-term Strategy': [ | |
| 'Diversify funding sources', | |
| 'Strengthen capital adequacy', | |
| 'Enhance risk reporting systems' | |
| ] | |
| } | |
| return recommendations | |
| def get_sample_data(): | |
| return { | |
| 'total_debt': 500000000, | |
| 'equity': 150000000, | |
| 'non_performing_loans': 25000000, | |
| 'total_loans': 400000000, | |
| 'loan_loss_provisions': 15000000, | |
| 'total_assets': 700000000, | |
| 'current_assets': 200000000, | |
| 'current_liabilities': 180000000, | |
| 'total_capital': 120000000, | |
| 'risk_weighted_assets': 500000000, | |
| 'short_term_funding': 300000000, | |
| 'total_funding': 600000000, | |
| 'wholesale_funding': 200000000, | |
| 'retail_deposits': 250000000, | |
| 'corporate_deposits': 150000000, | |
| 'interbank_borrowing': 100000000, | |
| 'long_term_funding': 200000000, | |
| 'level_3_assets': 50000000, | |
| 'derivative_notional': 400000000, | |
| 'contingent_liabilities': 80000000, | |
| 'undrawn_commitments': 120000000, | |
| 'var_99': 10000000, | |
| 'interest_rate_gap': 30000000, | |
| 'net_forex_position': 15000000, | |
| 'market_correlation': 0.6, | |
| 'process_risk_score': 0.04, | |
| 'system_risk_score': 0.03, | |
| 'compliance_risk_score': 0.02, | |
| 'fraud_risk_score': 0.03, | |
| 'collateral_coverage': 0.85, | |
| 'current_npl': 25000000, | |
| 'previous_npl': 20000000, | |
| 'corporate_loans': 200000000, | |
| 'retail_loans': 150000000, | |
| 'securities': 100000000, | |
| 'interbank_assets': 50000000 | |
| } | |
| # Main app file (app.py) | |
| def main(): | |
| dashboard = FinancialDashboard() | |
| dashboard.run() | |
| if __name__ == "__main__": | |
| main() |