From 3eb6b7b62bb49a06715d393b89bf9df56489c57a Mon Sep 17 00:00:00 2001 From: "Bobby (aider)" Date: Mon, 17 Feb 2025 15:13:13 -0800 Subject: [PATCH] feat: Enhance Monte Carlo simulation plot with improved visualization and styling --- src/pages/analysis/monte_carlo_page.py | 80 +++++++++++++++++++++----- 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/src/pages/analysis/monte_carlo_page.py b/src/pages/analysis/monte_carlo_page.py index 443ea74..65441ed 100644 --- a/src/pages/analysis/monte_carlo_page.py +++ b/src/pages/analysis/monte_carlo_page.py @@ -77,39 +77,91 @@ def create_simulation_plot(paths: np.ndarray, dates: pd.DatetimeIndex, row_heights=[0.7, 0.3] ) + # Plot all simulation paths with low opacity + for i in range(paths.shape[1]): + fig.add_trace( + go.Scatter( + x=dates, + y=paths[:, i], + name=f'Simulation {i+1}', + line=dict(color='orange', width=0.1, opacity=0.1), + showlegend=False + ), + row=1, col=1 + ) + # Plot confidence intervals percentiles = np.percentile(paths, [5, 25, 50, 75, 95], axis=1) - # Add price paths + # Add upper bound (blue) fig.add_trace( - go.Scatter(x=dates, y=percentiles[2], name='Median Path', - line=dict(color='blue', width=2)), row=1, col=1) + go.Scatter( + x=dates, + y=percentiles[4], + name='Upper 95% Confidence', + line=dict(color='blue', width=2) + ), + row=1, col=1 + ) - # Add confidence intervals + # Add lower bound (red) fig.add_trace( - go.Scatter(x=dates, y=percentiles[4], name='95% Confidence', - line=dict(color='rgba(0,100,80,0.2)', width=0)), row=1, col=1) + go.Scatter( + x=dates, + y=percentiles[0], + name='Lower 95% Confidence', + line=dict(color='red', width=2) + ), + row=1, col=1 + ) + + # Add median path fig.add_trace( - go.Scatter(x=dates, y=percentiles[0], name='95% Confidence', - fill='tonexty', line=dict(color='rgba(0,100,80,0.2)', width=0)), - row=1, col=1) + go.Scatter( + x=dates, + y=percentiles[2], + name='Median Path', + line=dict(color='white', width=2) + ), + row=1, col=1 + ) # Add starting price line fig.add_trace( - go.Scatter(x=dates, y=[last_price] * len(dates), name='Current Price', - line=dict(color='red', dash='dash')), row=1, col=1) + go.Scatter( + x=dates, + y=[last_price] * len(dates), + name='Current Price', + line=dict(color='green', dash='dash', width=2) + ), + row=1, col=1 + ) # Add histogram of final prices fig.add_trace( - go.Histogram(x=paths[-1], name='Final Price Distribution', - nbinsx=50), row=2, col=1) + go.Histogram( + x=paths[-1], + name='Final Price Distribution', + nbinsx=50, + marker_color='orange' + ), + row=2, col=1 + ) + # Update layout fig.update_layout( title=f'Monte Carlo Simulation - {ticker}', showlegend=True, - height=800 + height=800, + template='plotly_dark', # Dark theme for better visibility + plot_bgcolor='rgba(0,0,0,0)', # Transparent background + paper_bgcolor='rgba(0,0,0,0)' ) + # Update axes + fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.2)') + fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.2)') + return fig def monte_carlo_page():