This code is forecasting then number of mortgage contract, but it is grouping by weeks, I need it to be divided proportionally on each day of week, by the proprtions according to the last year before forecast import pandas as pd import numpy as np from prophet import Prophet import optuna import matplotlib.pyplot as plt

------------------------------------------------------------------
1. Load your data (ds = date, y = daily contract count)
------------------------------------------------------------------
Example data (replace with your actual data)
df['ds'] = pd.to_datetime(df['ds'])

------------------------------------------------------------------
2. Keep only business days (drop Sat/Sun)
------------------------------------------------------------------
df = df[df['ds'].dt.weekday < 5].reset_index(drop=True)

------------------------------------------------------------------
3. Aggregate daily data into weekly sums
------------------------------------------------------------------
Add a 'week_start' column (Monday of each week)
df['week_start'] = df['ds'] - pd.to_timedelta(df['ds'].dt.weekday, unit='D')

Group by week_start and sum the 'y' values
weekly_df = df.groupby('week_start').agg({'y': 'sum'}).reset_index() weekly_df.columns = ['ds', 'y'] # Prophet expects 'ds' and 'y'

------------------------------------------------------------------
4. Train / test split -> last 52 weeks as hold-out
------------------------------------------------------------------
HOLDOUT_WEEKS = 52 train_df = weekly_df.iloc[:-HOLDOUT_WEEKS] test_df = weekly_df.iloc[-HOLDOUT_WEEKS:]

------------------------------------------------------------------
5. SMAPE helper
------------------------------------------------------------------
def smape(y_true, y_pred): y_true, y_pred = np.array(y_true), np.array(y_pred) return 100 * np.mean(2 * np.abs(y_pred - y_true) / (np.abs(y_true) + np.abs(y_pred) + 1e-8))

------------------------------------------------------------------
6. Optuna objective
------------------------------------------------------------------
def objective(trial): params = { 'changepoint_prior_scale': trial.suggest_float('changepoint_prior_scale', 0.001, 0.5, log=True), 'seasonality_prior_scale': trial.suggest_float('seasonality_prior_scale', 0.01, 10, log=True), 'changepoint_range': trial.suggest_float('changepoint_range', 0.8, 0.95), 'n_changepoints': trial.suggest_int('n_changepoints', 10, 30), # Fewer changepoints for weekly data 'seasonality_mode': trial.suggest_categorical('seasonality_mode', ['additive', 'multiplicative']), 'interval_width': trial.suggest_float('interval_width', 0.90, 0.95) }

m = Prophet(
    daily_seasonality=False,
    weekly_seasonality=False,  # Disable weekly seasonality (data is already weekly)
    yearly_seasonality=True,
    **params
)
m.fit(train_df)

# Forecast exactly the test period
future = pd.DataFrame({'ds': test_df['ds']})
fcst = m.predict(future)

# Align and compute SMAPE
merged = pd.merge(test_df, fcst[['ds', 'yhat']], on='ds', how='inner')
return smape(merged['y'], merged['yhat'])
------------------------------------------------------------------
7. Run Bayesian optimisation
------------------------------------------------------------------
study = optuna.create_study(direction='minimize') study.optimize(objective, n_trials=30, show_progress_bar=True)

print("Best SMAPE:", round(study.best_value, 2)) print("Best params:", study.best_params)

------------------------------------------------------------------
8. Final model on best parameters
------------------------------------------------------------------
best = study.best_params m_final = Prophet( daily_seasonality=False, weekly_seasonality=False, # Disable weekly seasonality (data is weekly) yearly_seasonality=True, **best ) m_final.fit(train_df)

future = pd.DataFrame({'ds': test_df['ds']}) fcst = m_final.predict(future)

merged = pd.merge(test_df, fcst[['ds', 'yhat', 'yhat_lower', 'yhat_upper']], on='ds')

fcst_backtest_CNT = merged.drop('y', axis = 1)