{% extends "base.html" %} {% block title %}Forecasting Lab{% endblock %} {% block page_title %}Forecasting Lab{% endblock %} {% block content %}
New Forecast
Select the business metric you want to predict.
Prophet handles seasonality best. Moving Average is simplest.
How far into the future to predict. Longer horizons = less accuracy.
{% if view_forecast and summary %}
Forecast Details
{% if view_forecast.accuracy_mae is not none %} {% endif %} {% if view_forecast.accuracy_rmse is not none %} {% endif %} {% if view_forecast.accuracy_mape is not none %} {% endif %}
Type {{ forecast_labels.get(view_forecast.forecast_type, view_forecast.forecast_type)|replace('_', ' ')|title }}
Method {{ view_forecast.method|replace('_', ' ')|title }}
Horizon {{ view_forecast.horizon_days }} days
Status {{ view_forecast.status|title }}
MAE {{ "%.2f"|format(view_forecast.accuracy_mae) }}
RMSE {{ "%.2f"|format(view_forecast.accuracy_rmse) }}
MAPE {{ "%.2f"|format(view_forecast.accuracy_mape) }}%
Analysis & Recommendation

{{ summary.direction_icon }} {{ summary.trend|title }} Trend Detected

{{ summary.recommendation }}

Based on {{ results|length }} data points using {{ view_forecast.method|replace('_', ' ')|title }}.
{% endif %}
{% if view_forecast and results %}
Start Value
{{ (currency_symbol + "{:,.0f}".format(summary.first_value)) if summary else 'N/A' }}
Day 1 projection
End Value
{{ (currency_symbol + "{:,.0f}".format(summary.last_value)) if summary else 'N/A' }}
Final projection
Total Change
{% if summary %} {% if summary.change >= 0 %}+{% else %}-{% endif %}{{ currency_symbol }}{{ "{:,.0f}".format(summary.change|abs) }} {% else %} N/A {% endif %}
{{ "{:+.1f}%".format(summary.change_pct) if summary else '' }}
Volatility
{{ "{:.1f}%".format(summary.volatility) if summary else 'N/A' }}
Max swing range
Forecast Visualization
Confidence Band
Forecast Line (Best Estimate)
Upper Bound (Optimistic)
Lower Bound (Conservative)
Projected Values
{% for r in results %} {% endfor %}
Date Forecast Lower Bound Upper Bound Range Width
{{ r.date.strftime('%Y-%m-%d') }} {{ currency_symbol }}{{ "{:,.0f}".format(r.value) }} {{ currency_symbol }}{{ "{:,.0f}".format(r.lower_bound) if r.lower_bound else '—' }} {{ currency_symbol }}{{ "{:,.0f}".format(r.upper_bound) if r.upper_bound else '—' }} {% if r.lower_bound and r.upper_bound %} {% set width = r.upper_bound - r.lower_bound %} {% set pct = (width / r.value * 100) if r.value != 0 else 0 %} {{ "{:.1f}%".format(pct) }} {% else %} {% endif %}
Range width indicates model uncertainty. Narrow = high confidence, Wide = more uncertainty.
{% endif %}
Recent Forecasts
{% if forecasts|length > 0 %} {{ forecasts|length }} total {% endif %}
{% if forecasts %}
{% for fc in forecasts %} {% endfor %}
Name Type Method Horizon Status Actions
{{ fc.name }} {{ forecast_labels.get(fc.forecast_type, fc.forecast_type)|replace('_', ' ')|title }} {{ fc.method|replace('_', ' ')|title }} {{ fc.horizon_days }}d {{ fc.status|title }} View
{% else %}

No forecasts yet

Create your first forecast using the form on the left.

{% endif %}
{% endblock %} {% block extra_js %} {% if view_forecast and results %} {% endif %} {% endblock %}