Spaces:
Sleeping
Sleeping
File size: 4,206 Bytes
d79bff2 60b5e0e d79bff2 60b5e0e d79bff2 6993a9d c3b67d5 d79bff2 6993a9d c3b67d5 60b5e0e c3b67d5 d79bff2 c3b67d5 fa28d11 6993a9d d79bff2 fa28d11 d79bff2 60b5e0e fa28d11 60b5e0e d79bff2 60b5e0e d79bff2 60b5e0e d79bff2 60b5e0e 6993a9d 60b5e0e 6993a9d 60b5e0e 58ddaed 60b5e0e d79bff2 60b5e0e d79bff2 60b5e0e d79bff2 60b5e0e d79bff2 60b5e0e d79bff2 6993a9d 60b5e0e d79bff2 60b5e0e 6993a9d 60b5e0e d79bff2 41d6b54 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
import gradio as gr
import pandas as pd
import numpy as np
import plotly.graph_objects as go
CSV_URL = "https://gardenstatemls.stats.showingtime.com/infoserv/s-v1/kpou-Asg"
def monte_carlo_combined_plot(T=1.0, steps=120, n_paths=500):
try:
# Load and clean data
df = pd.read_csv(CSV_URL, skiprows=9)
df = df.dropna(axis=1, how='all')
df = df.iloc[:, :2]
df.columns = ['Date', 'Median Sales Price']
df['Median Sales Price'] = pd.to_numeric(df['Median Sales Price'].replace('[\$,]', '', regex=True), errors='coerce')
df['Date'] = pd.to_datetime(df['Date'], errors='coerce')
df = df.dropna(subset=['Date', 'Median Sales Price']).sort_values(by='Date')
prices = df['Median Sales Price'].values
if len(prices) < 2:
raise ValueError("Not enough valid price data after cleaning.")
returns = np.diff(np.log(prices))
mu = np.mean(returns) * 12
sigma = np.std(returns) * np.sqrt(12)
S0 = prices[-1]
dt = T / steps
paths = np.zeros((steps + 1, n_paths))
paths[0] = S0
for t in range(1, steps + 1):
rand = np.random.normal(0, 1, n_paths)
paths[t] = paths[t - 1] * np.exp((mu - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * rand)
forecast_dates = pd.date_range(start=df['Date'].iloc[-1], periods=steps+1, freq='MS')[1:]
# Combine history and forecast for unified plot
fig = go.Figure()
# Plot historical
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['Median Sales Price'],
mode='lines+markers',
name='Historical',
line=dict(width=3)
))
# Plot Monte Carlo paths
for i in range(n_paths):
full_x = pd.concat([pd.Series([df['Date'].iloc[-1]]), pd.Series(forecast_dates)])
full_y = np.concatenate([[S0], paths[1:, i]])
fig.add_trace(go.Scatter(
x=full_x,
y=full_y,
mode='lines',
line=dict(width=1),
showlegend=False,
opacity=0.3
))
# Plot mean and median path
mean_path = paths.mean(axis=1)
median_path = np.median(paths, axis=1)
future_dates_full = pd.concat([pd.Series([df['Date'].iloc[-1]]), pd.Series(forecast_dates)])
fig.add_trace(go.Scatter(x=future_dates_full, y=mean_path, name='Mean Forecast', line=dict(width=3, dash='dash')))
fig.add_trace(go.Scatter(x=future_dates_full, y=median_path, name='Median Forecast', line=dict(width=3, dash='dot')))
fig.update_layout(
title="π‘ Garden State MLS: Historical + Monte Carlo Forecast",
xaxis_title="Date",
yaxis_title="Median Sales Price ($)",
height=700,
template='plotly_white'
)
summary = f"""
**Simulation Summary**
- Starting Price: ${S0:,.2f}
- Simulated {n_paths} paths over {T:.1f} years
- Annual Drift (ΞΌ): {mu * 100:.2f}%
- Annual Volatility (Ο): {sigma * 100:.2f}%
"""
return fig, summary
except Exception as e:
fig = go.Figure()
fig.update_layout(title="Error", annotations=[{
"text": str(e),
"xref": "paper",
"yref": "paper",
"showarrow": False,
"font": {"size": 16}
}])
return fig, f"Error: {e}"
# Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("## π Garden State MLS Forecast: Historical + Monte Carlo Simulation")
with gr.Row():
years = gr.Slider(0.1, 10.0, value=1.0, step=0.1, label="Forecast Horizon (Years)")
steps = gr.Slider(12, 240, value=120, step=12, label="Time Steps")
paths = gr.Slider(10, 2000, value=500, step=10, label="Number of Simulated Paths")
run_button = gr.Button("Run Simulation")
plot = gr.Plot(label="π Combined Historical + Forecast Plot")
summary = gr.Markdown(label="π Simulation Summary")
run_button.click(monte_carlo_combined_plot, inputs=[years, steps, paths], outputs=[plot, summary])
demo.launch() |