# %%time
sampling_date = first_sampling_date
while sampling_date <= last_sampling_date:
    # get samples
    df_historic = data.load_historic(sampling_date=sampling_date,
                                     column="retadj")
    df_historic -= df_rf.loc[df_historic.index].values

    # calculate stats
    df_stats = pd.DataFrame(index=df_historic.columns)
    df_stats["ret_excess"] = (1 + df_historic).prod() - 1
    df_stats["var_annual"] = df_historic.var() * 252

    if sampling_date < last_sampling_date:
        # get excess return samples
        df_future = data.load_future(sampling_date=sampling_date,
                                     column="retadj")
        df_future -= df_rf.loc[df_future.index].values

        # slice expanding window
        df_expanding_estimates = pd.DataFrame(index=df_future.columns)
        for window_length in range(1, 13):
            end_date = sampling_date + relativedelta(months=window_length,
                                                     day=31)
            df_window = df_future[df_future.index <= end_date]

            # calculate stats in window
            df_stats["ret_excess_next{}M".format(
                window_length)] = (1 + df_window).prod() - 1
            df_stats["var_annual_next{}M".format(
                window_length)] = df_window.var() * 252
    data.store(
        data=df_decomposition,
        path="samples/{:%Y-%m-%d}/historic_daily.csv".format(sampling_date),
    )

    # increment monthly end of month
    print("Completed decomposition at {:%Y-%m-%d}".format(sampling_date))
    sampling_date += relativedelta(months=1, day=31)

# ### Forward part as expanding window

# %%time
sampling_date = first_sampling_date
while sampling_date < last_sampling_date:
    # load betas
    df_var = data.load_future(sampling_date=sampling_date, column="var")
    spy_data = df_spy.loc[df_var.index]

    # slice expanding window
    df_expanding_decompositions = pd.DataFrame(index=df_var.unstack().index)
    for window_length in range(1, 13):
        end_date = sampling_date + relativedelta(months=window_length, day=31)
        df_window = df_var[df_var.index <= end_date]
        spy_window = spy_data[spy_data.index <= end_date]
        betas_window = data.load_asset_estimates(
            sampling_date=sampling_date,
            columns=["spy_capm_spy_next{}M".format(window_length)],
        )

        # decompose
        df_decomposition = decompose_variance(df_window, betas_window, spy_window)
    )

    # increment monthly end of month
    print("Completed historic return factor model estimation at {:%Y-%m-%d}".
          format(sampling_date))
    sampling_date += relativedelta(months=1, day=31)

# %% [markdown]
# ### Forward part as expanding window

# %%
# %%time
sampling_date = first_sampling_date
while sampling_date < last_sampling_date:
    # get excess return samples
    df_future = data.load_future(sampling_date=sampling_date, column="retadj")
    df_future -= df_rf.loc[df_future.index].values

    # slice expanding window
    df_expanding_estimates = pd.DataFrame(index=df_future.columns)
    for window_length in range(1, 13):
        if (months_difference(end_date=last_sampling_date,
                              start_date=sampling_date) >= window_length):
            end_date = sampling_date + relativedelta(months=window_length,
                                                     day=31)
            df_window = df_future[df_future.index <= end_date]

            # estimate models in window
            df_estimates, df_residuals = estimate_models(ret_models, df_window)

            # collect