Skip to content

Instantly share code, notes, and snippets.

@marcosan93
Created October 18, 2021 18:36
Show Gist options
  • Select an option

  • Save marcosan93/d61687132302d63efdc6778fc63e0ef4 to your computer and use it in GitHub Desktop.

Select an option

Save marcosan93/d61687132302d63efdc6778fc63e0ef4 to your computer and use it in GitHub Desktop.
def fitModel(new_df):
"""
Fits model to new data and returns the fitted model to be used for predictions.
"""
# Column name
col_name = new_df.columns[-1]
# Variables
X = new_df.drop(col_name, axis=1)
y = new_df[[col_name]]
# Model object
reg = LinearRegression()
# Fitting
reg.fit(X, y)
return reg
def getPosition(val, short=True):
"""
Returns positions with optional short strategy.
"""
if val>0:
return 1
elif val<0 and short:
return -1
else:
return 0
def linRegModelBT(ticker, days_to_backtest, days_to_train, api_key, short=True, inverse_strat=False):
"""
Backtests Linear Regression Model based on the given crypto ticker. Range of backtest
is dependent on days_to_backtest. Training data is dependen on days_to_train.
Option to short in this strategy is provided as well as inversing the strategy.
"""
# Getting Data
df = getCryptoPrice(
api_key=api_key,
ticker=ticker,
n_days=days_to_backtest+days_to_train
)
# Creating a DF for predictions
pred_df = pd.DataFrame()
# Iterating through the DF starting from the least amount of days to train on
for i in tqdm(range(days_to_train, len(df)+1)):
# Training DF
train_df = df[i-days_to_train:i]
# Tranforming the Training DF
t_df, last_val = transformData(train_df)
# Fitting to model
model = fitModel(t_df)
# Making prediction for the very next day
pred = pd.DataFrame(
model.predict(last_val),
index=last_val.index+pd.offsets.Day(1),
columns=["prediction"]
)
# Appending the prediction to the dataframe
pred_df = pred_df.append(pred)
# Getting log returns from the original DF
pred_df['log_returns'] = df['Open'].tail(len(pred_df)).apply(np.log).diff()
# Getting positions and compensating for lookahead bias
pred_df['positions'] = pred_df['prediction'].apply(
lambda x: getPosition(x, short=short)
).shift(1)
# Inversing the strategy if selected
if inverse_strat:
pred_df['positions'] = pred_df['positions'].apply(
lambda x: -(x)
)
# Dropping any Nans
pred_df.dropna(inplace=True)
# Performing the backtest
returns = pred_df['positions'] * pred_df['log_returns']
# Inversing the log returns and getting daily portfolio balance
performance = returns.cumsum().apply(np.exp)
return performance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment