Created
October 18, 2021 18:36
-
-
Save marcosan93/d61687132302d63efdc6778fc63e0ef4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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