Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
QuantConnect
GitHub Repository: QuantConnect/Research
Path: blob/master/Documentation/Python/Predicting-Future-Prices-With-Keras.ipynb
984 views
Kernel: Python 3

QuantConnect Logo


Predicting Future Prices With Keras

An example of Keras model building, training, saving in the ObjectStore, and loading.

Import Libraries

Let's start by importing the functionality we'll need to build the model and serialize/unserialize the model for saving and loading

from tensorflow.keras import utils from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Flatten from tensorflow.keras.optimizers import RMSprop import json from keras.utils.generic_utils import serialize_keras_object

Gather & Prepare Data

Let's retreive some daily data for the SPY by making a History request.

qb = QuantBook() spy = qb.AddEquity('SPY') history = qb.History(qb.Securities.Keys, 360, Resolution.Daily) spy_hist = history.loc['SPY'] spy_hist

We create a function that prepares our data suitable for training and testing our Model. We use 5 steps of OHLCV data to predict the closing price of the bar right after. By tying this to a function, we increase clarity, as well as reusability, especially if we were to copy it into a class in a .py file.

# function to prepare our data for training our NN def prep_data(data, n_tsteps=5): # n_tsteps is the number of time steps at and before time t we want to use # to predict the close price at time t + 1 # this helps normalizes the data df = data.pct_change()[1:] features = [] labels = [] for i in range(len(df)-n_tsteps): input_data = df.iloc[i:i+n_tsteps].values features.append(input_data) label = df['close'].iloc[i+n_tsteps] labels.append(label) return np.array(features), np.array(labels)

Build the Model (Regression Neural Network)

Let's build the neural network using Keras. We create a function that creates our Model, building up the input and output layers, and the layers Between. We tie this to a function for the same reason mentioned before.

def build_model(): model = Sequential([ # 5 input variables (OHLCV) by 5 time steps Dense(10, input_shape=(5,5), activation='relu'), Dense(10, activation='relu'), # Flatten layer required because input shape is 2D Flatten(), # since we are performing regression, we only need 1 output node Dense(1) ]) model.compile(loss='mse', optimizer=RMSprop(0.001), metrics=['mae', 'mse']) return model

We'll train the neural network by preparing our data with the function we defined earlier and feeding the result into our model

X, y = prep_data(spy_hist) model = build_model() # split data into training/testing sets X_train = X[:300] X_test = X[300:] y_train = y[:300] y_test = y[300:] model.fit(X_train, y_train, epochs=5)

Analyze Performance

We then make predictions on the testing data set. We compare our Predicted Values with the Expected Values by plotting both to see if our Model has predictive power.

y_hat = model.predict(X_test) df = pd.DataFrame({'y': y_test.flatten(), 'y_hat': y_hat.flatten()}) df.plot(title='Model Performance: predicted vs actual %change in closing price')

Save the Model to ObjectStore

We first serialize our model into a JSON string, then we save our model to ObjectStore. This way, the model doesn't need to be retrained, saving time and computational resources.

model_key = 'spy_model' modelStr = json.dumps(serialize_keras_object(model)) qb.ObjectStore.Save(model_key, modelStr)

Load Model from the ObjectStore

Let's first retreive the JSON for the Keras model that we saved in the ObjectStore, then restore our model from this JSON string

if qb.ObjectStore.ContainsKey(model_key): modelStr = qb.ObjectStore.Read(model_key) config = json.loads(modelStr)['config'] loaded_model = Sequential.from_config(config)

To ensure loading the model was successfuly, let's test the model by having it make predictions.

y_hat = loaded_model.predict(X_test) df = pd.DataFrame({'y': y_test.flatten(), 'y_hat': y_hat.flatten()}) df.plot(title='Model Performance: predicted vs actual %change in closing price')

Appendix

Below are some helper methods to manage the ObjectStore keys. We can use these to validate the saving and loading is successful.

def get_ObjectStore_keys(): return [str(j).split(',')[0][1:] for _, j in enumerate(qb.ObjectStore.GetEnumerator())] def clear_ObjectStore(): for key in get_ObjectStore_keys(): qb.ObjectStore.Delete(key)
clear_ObjectStore()