Adding ML and quant tools
This commit is contained in:
+303
@@ -0,0 +1,303 @@
|
||||
import os
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from pandas.plotting import autocorrelation_plot
|
||||
from statsmodels.tsa.arima_model import ARIMA
|
||||
|
||||
from keras.models import Sequential
|
||||
from keras.layers import LSTM, Dense
|
||||
|
||||
from sklearn.preprocessing import MinMaxScaler, normalize
|
||||
from sklearn.linear_model import LinearRegression, Ridge
|
||||
from sklearn.metrics import mean_squared_error
|
||||
from sklearn.tree import DecisionTreeRegressor
|
||||
from sklearn.ensemble import (AdaBoostRegressor, BaggingRegressor,
|
||||
ExtraTreesRegressor, GradientBoostingRegressor,
|
||||
RandomForestRegressor)
|
||||
|
||||
import tensorflow as tf
|
||||
from tensorflow.contrib import rnn
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
file = 'history/AUD_JPY_D.csv'
|
||||
folder = 'history/'
|
||||
|
||||
def walk_folder(folder):
|
||||
|
||||
all_files = list()
|
||||
for files in os.walk(folder):
|
||||
for f in files[2]:
|
||||
f = os.path.join(folder, f)
|
||||
all_files.append(f)
|
||||
|
||||
return all_files
|
||||
|
||||
# TODO: test this some more, it works with Keras and sklearn; but had trouble with TF.
|
||||
def split_data(X, y, n, split, o):
|
||||
|
||||
m = int(n * split)
|
||||
X_train, X_test = X[0:m], X[m:n-o]
|
||||
y_train, y_test = y[o:m+o], y[m+o:n]
|
||||
|
||||
return X_train, X_test, y_train, y_test
|
||||
|
||||
def tf_nn_research(file, epochs=10, split=0.6, o=1):
|
||||
# import data and clean it for processing
|
||||
df = pd.read_csv(file)
|
||||
df = df[['Close', 'Open','High', 'Low']]
|
||||
n = df.shape[0]
|
||||
p = df.shape[1]
|
||||
data = df.values
|
||||
# Training and test data; split_data doesn't work too well with TF atm
|
||||
train_start = 0
|
||||
train_end = int(0.6*n)
|
||||
test_start = train_end + 1
|
||||
test_end = n
|
||||
data_train = data[np.arange(train_start, train_end), :]
|
||||
data_test = data[np.arange(test_start, test_end), :]
|
||||
# Scale data
|
||||
scaler = MinMaxScaler(feature_range=(-1, 1))
|
||||
scaler.fit(data_train)
|
||||
data_train = scaler.transform(data_train)
|
||||
data_test = scaler.transform(data_test)
|
||||
# Build X and y
|
||||
X_train = data_train[:, 1:]
|
||||
y_train = data_train[:, 0]
|
||||
X_test = data_test[:, 1:]
|
||||
y_test = data_test[:, 0]
|
||||
# length of training data
|
||||
m = X_train.shape[1]
|
||||
# neurons in each layer
|
||||
neurons_1 = 1024
|
||||
neurons_2 = 512
|
||||
neurons_3 = 256
|
||||
neurons_4 = 128
|
||||
# session
|
||||
sess = tf.InteractiveSession()
|
||||
# Placeholders
|
||||
X = tf.placeholder(dtype=tf.float32, shape=[None, m])
|
||||
Y = tf.placeholder(dtype=tf.float32, shape=[None])
|
||||
# initializers
|
||||
sigma = 1
|
||||
W = tf.variance_scaling_initializer(mode="fan_avg", distribution="uniform", scale=sigma)
|
||||
b = tf.zeros_initializer()
|
||||
# hidden weights
|
||||
W_hidden_1 = tf.Variable(W([m, neurons_1]))
|
||||
b_hidden_1 = tf.Variable(b([neurons_1]))
|
||||
W_hidden_2 = tf.Variable(W([neurons_1, neurons_2]))
|
||||
b_hidden_2 = tf.Variable(b([neurons_2]))
|
||||
W_hidden_3 = tf.Variable(W([neurons_2, neurons_3]))
|
||||
b_hidden_3 = tf.Variable(b([neurons_3]))
|
||||
W_hidden_4 = tf.Variable(W([neurons_3, neurons_4]))
|
||||
b_hidden_4 = tf.Variable(b([neurons_4]))
|
||||
# output weights
|
||||
W_out = tf.Variable(W([neurons_4, 1]))
|
||||
b_out = tf.Variable(b([1]))
|
||||
# hidden layers
|
||||
hidden_1 = tf.nn.relu(tf.add(tf.matmul(X, W_hidden_1), b_hidden_1))
|
||||
hidden_2 = tf.nn.relu(tf.add(tf.matmul(hidden_1, W_hidden_2), b_hidden_2))
|
||||
hidden_3 = tf.nn.relu(tf.add(tf.matmul(hidden_2, W_hidden_3), b_hidden_3))
|
||||
hidden_4 = tf.nn.relu(tf.add(tf.matmul(hidden_3, W_hidden_4), b_hidden_4))
|
||||
# transpose the output layer
|
||||
out = tf.transpose(tf.add(tf.matmul(hidden_4, W_out), b_out))
|
||||
# cost function
|
||||
mse = tf.reduce_mean(tf.squared_difference(out, Y))
|
||||
# optimizer
|
||||
opt = tf.train.AdamOptimizer().minimize(mse)
|
||||
# init
|
||||
sess.run(tf.global_variables_initializer())
|
||||
# start plot
|
||||
plt.ion()
|
||||
fig = plt.figure()
|
||||
ax1 = fig.add_subplot(111)
|
||||
line1, = ax1.plot(y_test)
|
||||
line2, = ax1.plot(y_test * 0.5)
|
||||
plt.show()
|
||||
# fit neural net
|
||||
batch_size = 1
|
||||
mse_train = []
|
||||
mse_test = []
|
||||
# run the network
|
||||
for e in range(epochs):
|
||||
# shuffle training data
|
||||
shuffle_indices = np.random.permutation(np.arange(len(y_train)))
|
||||
X_train = X_train[shuffle_indices]
|
||||
y_train = y_train[shuffle_indices]
|
||||
# Minibatch training
|
||||
for i in range(0, len(y_train) // batch_size):
|
||||
start = i * batch_size
|
||||
batch_x = X_train[start:start + batch_size]
|
||||
batch_y = y_train[start:start + batch_size]
|
||||
# run optimizer with batch
|
||||
sess.run(opt, feed_dict={X: batch_x, Y: batch_y})
|
||||
# show progress
|
||||
if np.mod(i, 50) == 0:
|
||||
# MSE train and test
|
||||
mse_train.append(sess.run(mse, feed_dict={X: X_train, Y: y_train}))
|
||||
mse_test.append(sess.run(mse, feed_dict={X: X_test, Y: y_test}))
|
||||
print('MSE Train: ', mse_train[-1])
|
||||
print('MSE Test: ', mse_test[-1])
|
||||
# prediction
|
||||
pred = sess.run(out, feed_dict={X: X_test})
|
||||
line2.set_ydata(pred)
|
||||
plt.title('Epoch ' + str(e) + ', Batch ' + str(i))
|
||||
plt.pause(0.10)
|
||||
plt.savefig('graphs/%s_%s.png' %(str(e), str(i)))
|
||||
|
||||
# Xcols=20 returns better results than Xcols=1, with o=5
|
||||
# Xcols=20 and o=1 returns 90-95% accuracy for every model
|
||||
def ensemble_research(file, split=0.6, o=5, Xcols=1):
|
||||
"""Xcols == 1 or 20; 1 for 'Open' or 20 for all input values"""
|
||||
# import, split, and prepare data
|
||||
df = pd.read_csv(file)
|
||||
n = len(df)
|
||||
if Xcols == 1:
|
||||
y = df['Close'].values.reshape(n, 1)
|
||||
X = df['Open'].values.reshape(n, 1)
|
||||
X_train, X_test, y_train, y_test = split_data(X, y, n, split, o)
|
||||
elif Xcols == 20:
|
||||
y = df['Close'].values
|
||||
a = df['Close'].mean()
|
||||
df.fillna(a, inplace=True)
|
||||
for col in df.columns:
|
||||
if 'Unnamed' in col:
|
||||
df.drop(col, axis=1, inplace=True)
|
||||
df.drop('Close', axis=1, inplace=True)
|
||||
X = df[df.columns.tolist()].values
|
||||
X_train, X_test, y_train, y_test = split_data(X, y, n, split, o)
|
||||
|
||||
# instantiate the models to be explored
|
||||
models = [AdaBoostRegressor(),
|
||||
BaggingRegressor(),
|
||||
DecisionTreeRegressor(),
|
||||
ExtraTreesRegressor(),
|
||||
GradientBoostingRegressor(),
|
||||
RandomForestRegressor()]
|
||||
|
||||
# set and run models
|
||||
scores = list()
|
||||
for model in models:
|
||||
model.fit(X_train, y_train)
|
||||
yhat = model.predict(X_test)
|
||||
score = model.score(X_test, y_test)
|
||||
scores.append(score)
|
||||
plt.plot(yhat, label='predictions')
|
||||
plt.plot(y_test, label='real data')
|
||||
plt.title(str(score))
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
# multivariate LSTM in Keras (OHL, plus technical indicators; 20 columns in total)
|
||||
def LSTMulti_research(file, o=5, split=0.6, show_loss=False):
|
||||
# import and clean the dataframe as needed, filling in any missing data
|
||||
df = pd.read_csv(file)
|
||||
n = len(df)
|
||||
y = df['Close'].values
|
||||
a = df['Close'].mean()
|
||||
df.fillna(a, inplace=True)
|
||||
for col in df.columns:
|
||||
if "Unnamed" in col:
|
||||
df.drop(col, axis=1, inplace=True)
|
||||
df.drop('Close', axis=1, inplace=True)
|
||||
X = df[df.columns.tolist()].values
|
||||
# split data and reshape input values
|
||||
X_train, X_test, y_train, y_test = split_data(X,y,n,split,o)
|
||||
X_train = np.reshape(X_train, (X_train.shape[0], 1, X_train.shape[1]))
|
||||
X_test = np.reshape(X_test, (X_test.shape[0], 1, X_test.shape[1]))
|
||||
|
||||
model = Sequential()
|
||||
model.add(LSTM(20, input_shape=(1,20,), activation='linear'))
|
||||
model.add(Dense(1))
|
||||
model.compile(loss='mse', optimizer='adam')
|
||||
history = model.fit(X_train, y_train, epochs=50, batch_size=1,
|
||||
validation_data=(X_test, y_test), verbose=2, shuffle=False)
|
||||
score = model.evaluate(X_test, y_test)#history['']
|
||||
if show_loss == True:
|
||||
plt.plot(history.history['loss'], label='train')
|
||||
plt.plot(history.history['val_loss'], label='test')
|
||||
plt.title('LSTMulti Score' + str(score))
|
||||
plt.legend()
|
||||
plt.show()
|
||||
else:
|
||||
plt.plot(y_test, label='prices')
|
||||
plt.plot(model.predict(X_test), label='predictions')
|
||||
plt.title('LSTMulti Score ' + str(score))
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
def plot_Ridge(file, o=5, split=0.6):
|
||||
df = pd.read_csv(file)
|
||||
n = len(df)
|
||||
X = df['Open'].values.reshape(n,1)
|
||||
y = df['Close'].values.reshape(n,1)
|
||||
X_train, X_test, y_train, y_test = split_data(X, y, n, split, o)
|
||||
|
||||
model = Ridge()
|
||||
model.fit(X_train, y_train)
|
||||
predictions = model.predict(X_test)
|
||||
score = model.score(X_test, y_test)
|
||||
print("Model score: %.2f" % score)
|
||||
|
||||
plt.plot([x for x in range(len(X_test))], predictions, label='predictions')
|
||||
plt.plot([x for x in range(len(X_test))], y_test, label='actual data')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
def plot_LinearRegression(file, o=5, split=0.6):
|
||||
# o == offset, how far away is the prediction we want to make?
|
||||
# changing o from 5 to 1 improves prediction accuract from 81% to 94%
|
||||
df = pd.read_csv(file)
|
||||
n = len(df)
|
||||
# convert pd.Series to np.ndarrays now for manipulation
|
||||
X = df['Open'].values.reshape(n,1)
|
||||
y = df['Close'].values.reshape(n,1)
|
||||
|
||||
# slight offset, X[t] is used to 'predict' y[t+o]
|
||||
X_train, X_test, y_train, y_test = split_data(X,y,n,split,o)
|
||||
|
||||
# check to make sure the two sets of arrays match in length
|
||||
print("Training sizes: X: %.2f, y: %.2f" % (X_train.shape[0], y_train.shape[0]))
|
||||
print("Test sizes: X: %.2f, y: %.2f" % (X_test.shape[0], y_test.shape[0]))
|
||||
|
||||
model = LinearRegression()
|
||||
model.fit(X_train, y_train)
|
||||
predictions = model.predict(X_test)
|
||||
score = model.score(X_test, y_test)
|
||||
print("Model score: ", score)
|
||||
plt.plot([x for x in range(len(X_test))], predictions, label='predictions')
|
||||
plt.plot([y for y in range(len(y_test))], y_test, label='real data')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
#arima_research(file, 'Close', 5, 1, 1) # best fit
|
||||
def arima_research(file, series, p, d, q):
|
||||
# prepare data
|
||||
df = pd.read_csv(file)
|
||||
X = df[series].values
|
||||
size = int(len(X) * 0.6)
|
||||
train, test = X[:size], X[size:]
|
||||
history = [x for x in train]
|
||||
predictions = list()
|
||||
|
||||
# fit the model and make predictions
|
||||
for t in range(len(test)):
|
||||
model = ARIMA(history, order=(p,d,q))
|
||||
model_fit = model.fit(disp=0)
|
||||
#print(model_fit.summary())
|
||||
output = model_fit.forecast()
|
||||
yhat = output[0]
|
||||
predictions.append(yhat)
|
||||
obs = test[t]
|
||||
history.append(obs)
|
||||
err = abs(yhat - obs)
|
||||
print("Predicted: %.3f, Expected: %.3f, Error: %.3f" % (yhat, obs, err))
|
||||
|
||||
# print summary and graph results
|
||||
error = mean_squared_error(test, predictions)
|
||||
print("Test MSE: %.3f" % (error))
|
||||
plt.plot(test, label='actual prices')
|
||||
plt.plot(predictions, label='predicted prices')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
Reference in New Issue
Block a user