luciablancar/BackTestingVaRLuci
0
1import gradio as gr2import numpy as np3import matplotlib.pyplot as plt4import pandas as pd5 6# Set style for light purple theme7plt.style.use('default')8 9def backtest_var(portfolio_value, num_test_days, seed_value):10 # Set seed for reproducibility11 np.random.seed(seed_value)12 13 # 1. GENERATE HISTORICAL RETURN DATA (100 days)14 returns = np.random.normal(0.001, 0.02, 100)15 16 # 2. CALCULATE VaR 95%17 var_95 = np.percentile(returns, 5)18 var_rp = var_95 * portfolio_value19 20 # 3. BACKTESTING21 future_returns = np.random.normal(0.001, 0.02, num_test_days)22 exceptions = future_returns < var_9523 num_exceptions = np.sum(exceptions)24 expected_exceptions = 0.05 * num_test_days25 26 # 4. CREATE VISUALIZATION WITH LIGHT PURPLE COLORS27 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))28 29 # Plot 1: Backtesting Results30 colors = ['#E6E6FA' if not exc else '#9370DB' for exc in exceptions]31 ax1.bar(range(num_test_days), future_returns * 100, color=colors, edgecolor='#8A2BE2')32 ax1.axhline(y=var_95 * 100, color='#8B008B', linestyle='--', linewidth=2, 33 label=f'VaR 95% ({var_95*100:.2f}%)')34 ax1.axhline(y=0, color='black', linestyle='-', alpha=0.3)35 ax1.set_title('Backtesting VaR 95%', fontsize=16, color='#4B0082', pad=20)36 ax1.set_ylabel('Return (%)', color='#4B0082', fontsize=12)37 ax1.set_xlabel('Day', color='#4B0082', fontsize=12)38 ax1.legend(fontsize=11)39 ax1.grid(True, alpha=0.3)40 ax1.tick_params(axis='both', which='major', labelsize=10)41 42 # Plot 2: Exception Analysis43 categories = ['Actual Exceptions', 'Expected Exceptions']44 values = [num_exceptions, expected_exceptions]45 colors_bar = ['#9370DB', '#D8BFD8']46 ax2.bar(categories, values, color=colors_bar, edgecolor='#8A2BE2')47 ax2.set_title('Exception Analysis', fontsize=16, color='#4B0082', pad=20)48 ax2.set_ylabel('Number of Days', color='#4B0082', fontsize=12)49 ax2.tick_params(axis='x', rotation=0, labelsize=11)50 51 # Add values on top of bars52 for i, v in enumerate(values):53 ax2.text(i, v + 0.1, f'{v:.1f}', ha='center', va='bottom', fontweight='bold', fontsize=12)54 55 plt.tight_layout()56 57 # 5. GENERATE RESULTS REPORT58 result_text = f"""59 ๐ **BACKTESTING VaR RESULTS**60 61 **VaR 95% Model:**62 - **1-day VaR:** {var_95*100:.2f}%63 - **In Rupiah:** Rp {var_rp:,.0f}64 65 **Backtesting Period:** {num_test_days} days66 **Number of Exceptions:** {num_exceptions} days67 **Expected Exceptions:** {expected_exceptions:.1f} days68 69 **๐ Interpretation:**70 """71 72 if abs(num_exceptions - expected_exceptions) <= 1:73 result_text += "โ
**Model ACCURATE** - Exception rate as expected"74 elif num_exceptions > expected_exceptions:75 result_text += "โ ๏ธ **Model TOO OPTIMISTIC** - Too many exceptions"76 else:77 result_text += "๐ฐ **Model CONSERVATIVE** - Lower exception rate than expected"78 79 return fig, result_text80 81# CUSTOM CSS FOR LIGHT PURPLE THEME82custom_css = """83.gr-box {84 border: 1px solid #D8BFD8 !important;85}86.gr-button {87 background: linear-gradient(45deg, #9370DB, #8A2BE2) !important;88 color: white !important;89 border: none !important;90 font-weight: bold !important;91}92.gr-button:hover {93 background: linear-gradient(45deg, #8A2BE2, #9370DB) !important;94 transform: scale(1.05) !important;95 transition: 0.3s !important;96}97h1 {98 color: #4B0082 !important;99 text-align: center !important;100}101.container {102 max-width: 100% !important;103}104"""105 106# CREATE GRADIO INTERFACE107with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple"), css=custom_css) as demo:108 gr.Markdown(109 """110 # ๐ VaR Backtesting Simulator111 112 **Interactive simulator to test the accuracy of Value at Risk (VaR) models**113 """)114 115 # SIMULATOR CONTROLS SECTION116 with gr.Row():117 with gr.Column(scale=1):118 gr.Markdown("### โ๏ธ Simulation Parameters")119 portfolio = gr.Number(120 label="Portfolio Value (Rp)",121 value=1000000000,122 minimum=100000000,123 info="Enter your portfolio value in Rupiah"124 )125 test_days = gr.Slider(126 label="Backtesting Days",127 minimum=10,128 maximum=100,129 value=25,130 step=5,131 info="Number of days to test the VaR model"132 )133 seed = gr.Number(134 label="Random Seed",135 value=42,136 info="For reproducible results"137 )138 btn = gr.Button("๐ Run Backtesting", variant="primary", size="lg")139 140 with gr.Column(scale=1):141 gr.Markdown("### ๐ Quick Results")142 result = gr.Markdown(143 label="Analysis Results",144 value="*Configure parameters and click 'Run Backtesting' to see results here*"145 )146 147 # GUIDANCE SECTION148 gr.Markdown("---")149 with gr.Row():150 with gr.Column():151 gr.Markdown(152 """153 ### ๐ก How to Read the Results:154 - **Dark purple bars**: Days where loss exceeded VaR (exceptions)155 - **Dashed line**: VaR 95% level 156 - **Actual vs Expected**: Compare actual vs theoretical exception counts157 - **Accurate model**: Actual exceptions โ Expected exceptions158 - **Optimistic model**: Actual exceptions > Expected exceptions159 - **Conservative model**: Actual exceptions < Expected exceptions160 """161 )162 163 # BACKTESTING RESULTS SECTION - FULL WIDTH BELOW164 gr.Markdown("---")165 gr.Markdown("## ๐ Backtesting Results Visualization")166 plot = gr.Plot(label="Backtesting Analysis", show_label=True)167 168 btn.click(169 fn=backtest_var,170 inputs=[portfolio, test_days, seed],171 outputs=[plot, result]172 )173 174# LAUNCH APPLICATION175if __name__ == "__main__":176 demo.launch()