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