algo_trading_book/PythonCodesAndData/estimateFuturesReturns.py
2025-06-05 08:48:33 +02:00

43 lines
1.3 KiB
Python

# Example 5.3: Estimating Spot and Roll Returns Using the Constant Returns Model
import numpy as np
import pandas as pd
#import matplotlib.pyplot as plt
import statsmodels.api as sm
#import statsmodels.tsa.stattools as ts
#import statsmodels.tsa.vector_ar.vecm as vm
df=pd.read_csv('inputDataDaily_C2_20120813.csv')
df['Date']=pd.to_datetime(df['Date'], format='%Y%m%d').dt.date # remove HH:MM:SS
df.set_index('Date', inplace=True)
# Find spot prices
spot=df['C_Spot']
df.drop('C_Spot', axis=1, inplace=True)
T=sm.add_constant(range(spot.shape[0]))
model=sm.OLS(np.log(spot), T)
res=model.fit() # Note this can deal with NaN in top row
print('Average annualized spot return=', 252*res.params[1])
#Average annualized spot return= 0.02805562210100287
# Fitting gamma to forward curve
gamma=np.full(df.shape[0], np.nan)
for t in range(df.shape[0]):
idx=np.where(np.isfinite(df.iloc[t, :]))[0]
idxDiff = np.roll(idx, -1) - idx
all_ones = all(idxDiff[0:4]==1)
if (len(idx)>=5) and all_ones:
FT=df.iloc[t, idx[:5]]
T=sm.add_constant(range(FT.shape[0]))
model=sm.OLS(np.log(FT.values), T)
res=model.fit()
gamma[t]=-12*res.params[1]
pd.DataFrame(gamma).plot()
print('Average annualized roll return=', np.nanmean(gamma))
# Average annualized roll return= -0.12775650227459556