Spaces:
Sleeping
Sleeping
| # ---------------- APP ---------------- | |
| # This is the main file to run the Gradio application. | |
| # It imports logic from logic.py and configuration from config.py | |
| import gradio as gr | |
| # Import constants needed for the UI | |
| from config import CRISIS_PERIODS, EXAMPLE_PORTFOLIOS, CRISIS_SUMMARY | |
| # Import the main simulation function | |
| from logic import run_crisis_simulation | |
| # --- UI Helper Functions --- | |
| def load_example(example_name): | |
| """Updates ticker and weight textboxes based on selection.""" | |
| portfolio = EXAMPLE_PORTFOLIOS.get(example_name, {"tickers": "", "weights": ""}) | |
| return gr.update(value=portfolio["tickers"]), gr.update(value=portfolio["weights"]) | |
| def update_crisis_summary(crisis_name): | |
| """Updates the crisis summary text when a crisis is selected.""" | |
| summary = CRISIS_SUMMARY.get(crisis_name, "") | |
| if summary: | |
| return f"**Crisis summary:** _{summary}_" | |
| return "" | |
| # ---------------- UI DEFINITION ---------------- | |
| with gr.Blocks(title="Crisis Lens (India)") as demo: | |
| gr.Markdown( | |
| """ | |
| # ๐ฎ๐ณ Crisis Lens โ Indian Stock Stress Simulator | |
| How would your portfolio have performed during a major market crisis? | |
| Select a historical crisis and your portfolio to find out. | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| crisis_dd = gr.Dropdown( | |
| list(CRISIS_PERIODS.keys()), | |
| label="Select Crisis", | |
| value="COVID-19 Crash (India)", | |
| ) | |
| crisis_info = gr.Markdown( | |
| f"**Crisis summary:** _{CRISIS_SUMMARY['COVID-19 Crash (India)']}_", | |
| elem_classes="crisis-summary", | |
| ) | |
| with gr.Column(scale=1): | |
| example_loader_dd = gr.Dropdown( | |
| list(EXAMPLE_PORTFOLIOS.keys()), | |
| label="Load Example Portfolio", | |
| value="Select Example...", # will be overridden by .load() | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("### 1. Define Your Portfolio") | |
| upload_csv = gr.File( | |
| label="Upload Portfolio CSV (Ticker,Weight)", | |
| file_types=[".csv"] | |
| ) | |
| gr.Markdown("...or enter manually below:") | |
| tickers_input = gr.Textbox( | |
| label="Tickers (comma separated)", | |
| value="" | |
| ) | |
| weights_input = gr.Textbox( | |
| label="Weights (comma separated)", | |
| value="" | |
| ) | |
| add_etf_cb = gr.Checkbox( | |
| label="Add 5% NIFTYBEES.NS to portfolio (diversify)", | |
| value=False | |
| ) | |
| gr.Markdown("---") | |
| gr.Markdown("### ๐ค 2. AI Insights (Optional)") | |
| gemini_api_key_in = gr.Textbox( | |
| label="Gemini API Key (optional, not stored)", | |
| placeholder="Paste your Gemini API key here to get AI-generated insights", | |
| type="password", | |
| ) | |
| gemini_extra_prompt_in = gr.Textbox( | |
| label="Extra instructions for AI (optional)", | |
| placeholder="e.g., Focus more on risk, or write in simple language, etc.", | |
| lines=2, | |
| ) | |
| gr.Markdown("---") | |
| run_btn = gr.Button("Run Simulation", variant="primary") | |
| logs_txt = gr.Textbox(label="Status / Logs", interactive=False) | |
| with gr.Column(scale=3): | |
| gr.Markdown("### 3. Analyze the Results") | |
| plot_performance = gr.Plot() | |
| with gr.Row(): | |
| metrics_output = gr.Markdown() | |
| pie_chart = gr.Plot() | |
| with gr.Row(): | |
| sector_plot_output = gr.Plot() | |
| insights_output = gr.Markdown() | |
| gr.Markdown("### ๐ค AI-Generated Insights") | |
| gemini_insights_md = gr.Markdown( | |
| value="*AI insights will appear here after running simulation with a Gemini API key.*" | |
| ) | |
| # ---------------- EVENT HANDLERS ---------------- | |
| crisis_dd.change( | |
| fn=update_crisis_summary, | |
| inputs=[crisis_dd], | |
| outputs=[crisis_info], | |
| ) | |
| example_loader_dd.change( | |
| fn=load_example, | |
| inputs=[example_loader_dd], | |
| outputs=[tickers_input, weights_input], | |
| ) | |
| run_btn.click( | |
| run_crisis_simulation, | |
| inputs=[ | |
| crisis_dd, | |
| upload_csv, | |
| tickers_input, | |
| weights_input, | |
| add_etf_cb, | |
| gemini_api_key_in, | |
| gemini_extra_prompt_in, | |
| ], | |
| outputs=[ | |
| plot_performance, | |
| metrics_output, | |
| sector_plot_output, | |
| insights_output, | |
| pie_chart, | |
| logs_txt, | |
| gemini_insights_md, | |
| ], | |
| ) | |
| def load_default_example(): | |
| default_name = "Large-Cap (Default)" | |
| portfolio = EXAMPLE_PORTFOLIOS.get(default_name, {"tickers": "", "weights": ""}) | |
| summary = CRISIS_SUMMARY.get("COVID-19 Crash (India)", "") | |
| return ( | |
| gr.update(value=default_name), | |
| gr.update(value=portfolio["tickers"]), | |
| gr.update(value=portfolio["weights"]), | |
| f"**Crisis summary:** _{summary}_", | |
| ) | |
| demo.load( | |
| fn=load_default_example, | |
| inputs=None, | |
| outputs=[example_loader_dd, tickers_input, weights_input, crisis_info], | |
| ) | |
| # ---------------- LAUNCH ---------------- | |
| if __name__ == "__main__": | |
| demo.launch(share=True, debug=True) | |