import math
import datetime
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from common import normalize_data, plot_stock_vs_volume, load_data

# chosen stock
chosen_stock = 'EQIX'
sequence_length = 40 # days

# train, valid, test size
size_train = 80 # 80%
size_valid = 10 # 10%
size_test = 10 # 10%

curr_dir = os.path.dirname(__file__)
work_dir = os.path.join(curr_dir, '..')
data_dir = os.path.join(work_dir, 'data-stock-nyse')

# csv to read
csv_path = os.path.join(data_dir, 'prices-split-adjusted.csv')

# read data
df = pd.read_csv(csv_path, index_col=0)
print(df.head())
print(df.tail())

## try to plot
# plot_stock_vs_volume(df=df, stock_name=chosen_stock)
# plt.show()

# choose one stock, drop label and volume, left only
# open close low high
df_stock = df[df['symbol'] == chosen_stock].copy()
df_stock.drop(['symbol'], axis=1, inplace=True)
df_stock.drop(['volume'], axis=1, inplace=True)

# normalize
df_normalized = normalize_data(df_stock, list(df_stock.columns)) 

# create train and test data
(x_train, y_train), (x_valid, y_valid), (x_test, y_test) = load_data(df_normalized, sequence_length)

# machine learning part (RNN)
index_in_epoch = 0
perm_array  = np.arange(x_train.shape[0])
np.random.shuffle(perm_array)

# function to get the next batch
def get_next_batch(batch_size):
    global index_in_epoch, x_train, perm_array   
    start = index_in_epoch
    index_in_epoch += batch_size
    
    if index_in_epoch > x_train.shape[0]:
        np.random.shuffle(perm_array) # shuffle permutation array
        start = 0 # start next epoch
        index_in_epoch = batch_size
        
    end = index_in_epoch
    return x_train[perm_array[start:end]], y_train[perm_array[start:end]]

# parameters
n_steps = sequence_length-1 
n_inputs = 4 
n_neurons = 200 
n_outputs = 4
n_layers = 2
learning_rate = 0.001
batch_size = 50
n_epochs = 100 
train_set_size = x_train.shape[0]
test_set_size = x_test.shape[0]

tf.reset_default_graph()

X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_outputs])

# use Basic RNN Cell
layers = [tf.contrib.rnn.BasicRNNCell(num_units=n_neurons, activation=tf.nn.elu)
          for layer in range(n_layers)]
                                                                     
multi_layer_cell = tf.contrib.rnn.MultiRNNCell(layers)
rnn_outputs, states = tf.nn.dynamic_rnn(multi_layer_cell, X, dtype=tf.float32)

stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_neurons]) 
stacked_outputs = tf.layers.dense(stacked_rnn_outputs, n_outputs)
outputs = tf.reshape(stacked_outputs, [-1, n_steps, n_outputs])
outputs = outputs[:,n_steps-1,:] # keep only last output of sequence
                                              
loss = tf.reduce_mean(tf.square(outputs - y)) # loss function = mean squared error 
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) 
training_op = optimizer.minimize(loss)
                                              
# run graph
with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer())
    for iteration in range(int(n_epochs*train_set_size/batch_size)):
        x_batch, y_batch = get_next_batch(batch_size) # fetch the next training batch 
        sess.run(training_op, feed_dict={X: x_batch, y: y_batch}) 
        if iteration % int(5*train_set_size/batch_size) == 0:
            mse_train = loss.eval(feed_dict={X: x_train, y: y_train}) 
            mse_valid = loss.eval(feed_dict={X: x_valid, y: y_valid}) 
            print('%.2f epochs: MSE train/valid = %.6f/%.6f'%(
                iteration*batch_size/train_set_size, mse_train, mse_valid))

    y_train_pred = sess.run(outputs, feed_dict={X: x_train})
    y_valid_pred = sess.run(outputs, feed_dict={X: x_valid})
    y_test_pred = sess.run(outputs, feed_dict={X: x_test})


## PREDICTION
ft = 0 # 0 = open, 1 = close, 2 = highest, 3 = lowest

## show predictions
plt.figure(figsize=(15, 5))
plt.subplot(1,2,1)

plt.plot(np.arange(y_train.shape[0]), y_train[:,ft], color='blue', label='train target')

plt.plot(np.arange(y_train.shape[0], y_train.shape[0]+y_valid.shape[0]), y_valid[:,ft],
         color='gray', label='valid target')

plt.plot(np.arange(y_train.shape[0]+y_valid.shape[0],
                   y_train.shape[0]+y_valid.shape[0]+y_test.shape[0]),
         y_test[:,ft], color='black', label='test target')

plt.plot(np.arange(y_train_pred.shape[0]),y_train_pred[:,ft], color='red',
         label='train prediction')

plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0]+y_valid_pred.shape[0]),
         y_valid_pred[:,ft], color='orange', label='valid prediction')

plt.plot(np.arange(y_train_pred.shape[0]+y_valid_pred.shape[0],
                   y_train_pred.shape[0]+y_valid_pred.shape[0]+y_test_pred.shape[0]),
         y_test_pred[:,ft], color='green', label='test prediction')

plt.title('past and future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')

plt.subplot(1,2,2)

plt.plot(np.arange(y_train.shape[0], y_train.shape[0]+y_test.shape[0]),
         y_test[:,ft], color='black', label='test target')

plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0]+y_test_pred.shape[0]),
         y_test_pred[:,ft], color='green', label='test prediction')

plt.title('future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')

corr_price_development_train = np.sum(np.equal(np.sign(y_train[:,1]-y_train[:,0]),
            np.sign(y_train_pred[:,1]-y_train_pred[:,0])).astype(int)) / y_train.shape[0]
corr_price_development_valid = np.sum(np.equal(np.sign(y_valid[:,1]-y_valid[:,0]),
            np.sign(y_valid_pred[:,1]-y_valid_pred[:,0])).astype(int)) / y_valid.shape[0]
corr_price_development_test = np.sum(np.equal(np.sign(y_test[:,1]-y_test[:,0]),
            np.sign(y_test_pred[:,1]-y_test_pred[:,0])).astype(int)) / y_test.shape[0]

print('correct sign prediction for close - open price for train/valid/test: %.2f/%.2f/%.2f'%(
    corr_price_development_train, corr_price_development_valid, corr_price_development_test))

plt.show()
f633bfb899682e9aca4597092b0953b4d9511ad1
<mask token>


def get_next_batch(batch_size):
    global index_in_epoch, x_train, perm_array
    start = index_in_epoch
    index_in_epoch += batch_size
    if index_in_epoch > x_train.shape[0]:
        np.random.shuffle(perm_array)
        start = 0
        index_in_epoch = batch_size
    end = index_in_epoch
    return x_train[perm_array[start:end]], y_train[perm_array[start:end]]


<mask token>

<mask token>
print(df.head())
print(df.tail())
<mask token>
df_stock.drop(['symbol'], axis=1, inplace=True)
df_stock.drop(['volume'], axis=1, inplace=True)
<mask token>
np.random.shuffle(perm_array)


def get_next_batch(batch_size):
    global index_in_epoch, x_train, perm_array
    start = index_in_epoch
    index_in_epoch += batch_size
    if index_in_epoch > x_train.shape[0]:
        np.random.shuffle(perm_array)
        start = 0
        index_in_epoch = batch_size
    end = index_in_epoch
    return x_train[perm_array[start:end]], y_train[perm_array[start:end]]


<mask token>
tf.reset_default_graph()
<mask token>
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for iteration in range(int(n_epochs * train_set_size / batch_size)):
        x_batch, y_batch = get_next_batch(batch_size)
        sess.run(training_op, feed_dict={X: x_batch, y: y_batch})
        if iteration % int(5 * train_set_size / batch_size) == 0:
            mse_train = loss.eval(feed_dict={X: x_train, y: y_train})
            mse_valid = loss.eval(feed_dict={X: x_valid, y: y_valid})
            print('%.2f epochs: MSE train/valid = %.6f/%.6f' % (iteration *
                batch_size / train_set_size, mse_train, mse_valid))
    y_train_pred = sess.run(outputs, feed_dict={X: x_train})
    y_valid_pred = sess.run(outputs, feed_dict={X: x_valid})
    y_test_pred = sess.run(outputs, feed_dict={X: x_test})
<mask token>
plt.figure(figsize=(15, 5))
plt.subplot(1, 2, 1)
plt.plot(np.arange(y_train.shape[0]), y_train[:, ft], color='blue', label=
    'train target')
plt.plot(np.arange(y_train.shape[0], y_train.shape[0] + y_valid.shape[0]),
    y_valid[:, ft], color='gray', label='valid target')
plt.plot(np.arange(y_train.shape[0] + y_valid.shape[0], y_train.shape[0] +
    y_valid.shape[0] + y_test.shape[0]), y_test[:, ft], color='black',
    label='test target')
plt.plot(np.arange(y_train_pred.shape[0]), y_train_pred[:, ft], color='red',
    label='train prediction')
plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0] +
    y_valid_pred.shape[0]), y_valid_pred[:, ft], color='orange', label=
    'valid prediction')
plt.plot(np.arange(y_train_pred.shape[0] + y_valid_pred.shape[0], 
    y_train_pred.shape[0] + y_valid_pred.shape[0] + y_test_pred.shape[0]),
    y_test_pred[:, ft], color='green', label='test prediction')
plt.title('past and future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')
plt.subplot(1, 2, 2)
plt.plot(np.arange(y_train.shape[0], y_train.shape[0] + y_test.shape[0]),
    y_test[:, ft], color='black', label='test target')
plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0] +
    y_test_pred.shape[0]), y_test_pred[:, ft], color='green', label=
    'test prediction')
plt.title('future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')
<mask token>
print(
    'correct sign prediction for close - open price for train/valid/test: %.2f/%.2f/%.2f'
     % (corr_price_development_train, corr_price_development_valid,
    corr_price_development_test))
plt.show()

<mask token>
chosen_stock = 'EQIX'
sequence_length = 40
size_train = 80
size_valid = 10
size_test = 10
curr_dir = os.path.dirname(__file__)
work_dir = os.path.join(curr_dir, '..')
data_dir = os.path.join(work_dir, 'data-stock-nyse')
csv_path = os.path.join(data_dir, 'prices-split-adjusted.csv')
df = pd.read_csv(csv_path, index_col=0)
print(df.head())
print(df.tail())
df_stock = df[df['symbol'] == chosen_stock].copy()
df_stock.drop(['symbol'], axis=1, inplace=True)
df_stock.drop(['volume'], axis=1, inplace=True)
df_normalized = normalize_data(df_stock, list(df_stock.columns))
(x_train, y_train), (x_valid, y_valid), (x_test, y_test) = load_data(
    df_normalized, sequence_length)
index_in_epoch = 0
perm_array = np.arange(x_train.shape[0])
np.random.shuffle(perm_array)


def get_next_batch(batch_size):
    global index_in_epoch, x_train, perm_array
    start = index_in_epoch
    index_in_epoch += batch_size
    if index_in_epoch > x_train.shape[0]:
        np.random.shuffle(perm_array)
        start = 0
        index_in_epoch = batch_size
    end = index_in_epoch
    return x_train[perm_array[start:end]], y_train[perm_array[start:end]]


n_steps = sequence_length - 1
n_inputs = 4
n_neurons = 200
n_outputs = 4
n_layers = 2
learning_rate = 0.001
batch_size = 50
n_epochs = 100
train_set_size = x_train.shape[0]
test_set_size = x_test.shape[0]
tf.reset_default_graph()
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_outputs])
layers = [tf.contrib.rnn.BasicRNNCell(num_units=n_neurons, activation=tf.nn
    .elu) for layer in range(n_layers)]
multi_layer_cell = tf.contrib.rnn.MultiRNNCell(layers)
rnn_outputs, states = tf.nn.dynamic_rnn(multi_layer_cell, X, dtype=tf.float32)
stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_neurons])
stacked_outputs = tf.layers.dense(stacked_rnn_outputs, n_outputs)
outputs = tf.reshape(stacked_outputs, [-1, n_steps, n_outputs])
outputs = outputs[:, n_steps - 1, :]
loss = tf.reduce_mean(tf.square(outputs - y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for iteration in range(int(n_epochs * train_set_size / batch_size)):
        x_batch, y_batch = get_next_batch(batch_size)
        sess.run(training_op, feed_dict={X: x_batch, y: y_batch})
        if iteration % int(5 * train_set_size / batch_size) == 0:
            mse_train = loss.eval(feed_dict={X: x_train, y: y_train})
            mse_valid = loss.eval(feed_dict={X: x_valid, y: y_valid})
            print('%.2f epochs: MSE train/valid = %.6f/%.6f' % (iteration *
                batch_size / train_set_size, mse_train, mse_valid))
    y_train_pred = sess.run(outputs, feed_dict={X: x_train})
    y_valid_pred = sess.run(outputs, feed_dict={X: x_valid})
    y_test_pred = sess.run(outputs, feed_dict={X: x_test})
ft = 0
plt.figure(figsize=(15, 5))
plt.subplot(1, 2, 1)
plt.plot(np.arange(y_train.shape[0]), y_train[:, ft], color='blue', label=
    'train target')
plt.plot(np.arange(y_train.shape[0], y_train.shape[0] + y_valid.shape[0]),
    y_valid[:, ft], color='gray', label='valid target')
plt.plot(np.arange(y_train.shape[0] + y_valid.shape[0], y_train.shape[0] +
    y_valid.shape[0] + y_test.shape[0]), y_test[:, ft], color='black',
    label='test target')
plt.plot(np.arange(y_train_pred.shape[0]), y_train_pred[:, ft], color='red',
    label='train prediction')
plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0] +
    y_valid_pred.shape[0]), y_valid_pred[:, ft], color='orange', label=
    'valid prediction')
plt.plot(np.arange(y_train_pred.shape[0] + y_valid_pred.shape[0], 
    y_train_pred.shape[0] + y_valid_pred.shape[0] + y_test_pred.shape[0]),
    y_test_pred[:, ft], color='green', label='test prediction')
plt.title('past and future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')
plt.subplot(1, 2, 2)
plt.plot(np.arange(y_train.shape[0], y_train.shape[0] + y_test.shape[0]),
    y_test[:, ft], color='black', label='test target')
plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0] +
    y_test_pred.shape[0]), y_test_pred[:, ft], color='green', label=
    'test prediction')
plt.title('future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')
corr_price_development_train = np.sum(np.equal(np.sign(y_train[:, 1] -
    y_train[:, 0]), np.sign(y_train_pred[:, 1] - y_train_pred[:, 0])).
    astype(int)) / y_train.shape[0]
corr_price_development_valid = np.sum(np.equal(np.sign(y_valid[:, 1] -
    y_valid[:, 0]), np.sign(y_valid_pred[:, 1] - y_valid_pred[:, 0])).
    astype(int)) / y_valid.shape[0]
corr_price_development_test = np.sum(np.equal(np.sign(y_test[:, 1] - y_test
    [:, 0]), np.sign(y_test_pred[:, 1] - y_test_pred[:, 0])).astype(int)
    ) / y_test.shape[0]
print(
    'correct sign prediction for close - open price for train/valid/test: %.2f/%.2f/%.2f'
     % (corr_price_development_train, corr_price_development_valid,
    corr_price_development_test))
plt.show()

import math
import datetime
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from common import normalize_data, plot_stock_vs_volume, load_data
chosen_stock = 'EQIX'
sequence_length = 40
size_train = 80
size_valid = 10
size_test = 10
curr_dir = os.path.dirname(__file__)
work_dir = os.path.join(curr_dir, '..')
data_dir = os.path.join(work_dir, 'data-stock-nyse')
csv_path = os.path.join(data_dir, 'prices-split-adjusted.csv')
df = pd.read_csv(csv_path, index_col=0)
print(df.head())
print(df.tail())
df_stock = df[df['symbol'] == chosen_stock].copy()
df_stock.drop(['symbol'], axis=1, inplace=True)
df_stock.drop(['volume'], axis=1, inplace=True)
df_normalized = normalize_data(df_stock, list(df_stock.columns))
(x_train, y_train), (x_valid, y_valid), (x_test, y_test) = load_data(
    df_normalized, sequence_length)
index_in_epoch = 0
perm_array = np.arange(x_train.shape[0])
np.random.shuffle(perm_array)


def get_next_batch(batch_size):
    global index_in_epoch, x_train, perm_array
    start = index_in_epoch
    index_in_epoch += batch_size
    if index_in_epoch > x_train.shape[0]:
        np.random.shuffle(perm_array)
        start = 0
        index_in_epoch = batch_size
    end = index_in_epoch
    return x_train[perm_array[start:end]], y_train[perm_array[start:end]]


n_steps = sequence_length - 1
n_inputs = 4
n_neurons = 200
n_outputs = 4
n_layers = 2
learning_rate = 0.001
batch_size = 50
n_epochs = 100
train_set_size = x_train.shape[0]
test_set_size = x_test.shape[0]
tf.reset_default_graph()
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_outputs])
layers = [tf.contrib.rnn.BasicRNNCell(num_units=n_neurons, activation=tf.nn
    .elu) for layer in range(n_layers)]
multi_layer_cell = tf.contrib.rnn.MultiRNNCell(layers)
rnn_outputs, states = tf.nn.dynamic_rnn(multi_layer_cell, X, dtype=tf.float32)
stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_neurons])
stacked_outputs = tf.layers.dense(stacked_rnn_outputs, n_outputs)
outputs = tf.reshape(stacked_outputs, [-1, n_steps, n_outputs])
outputs = outputs[:, n_steps - 1, :]
loss = tf.reduce_mean(tf.square(outputs - y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for iteration in range(int(n_epochs * train_set_size / batch_size)):
        x_batch, y_batch = get_next_batch(batch_size)
        sess.run(training_op, feed_dict={X: x_batch, y: y_batch})
        if iteration % int(5 * train_set_size / batch_size) == 0:
            mse_train = loss.eval(feed_dict={X: x_train, y: y_train})
            mse_valid = loss.eval(feed_dict={X: x_valid, y: y_valid})
            print('%.2f epochs: MSE train/valid = %.6f/%.6f' % (iteration *
                batch_size / train_set_size, mse_train, mse_valid))
    y_train_pred = sess.run(outputs, feed_dict={X: x_train})
    y_valid_pred = sess.run(outputs, feed_dict={X: x_valid})
    y_test_pred = sess.run(outputs, feed_dict={X: x_test})
ft = 0
plt.figure(figsize=(15, 5))
plt.subplot(1, 2, 1)
plt.plot(np.arange(y_train.shape[0]), y_train[:, ft], color='blue', label=
    'train target')
plt.plot(np.arange(y_train.shape[0], y_train.shape[0] + y_valid.shape[0]),
    y_valid[:, ft], color='gray', label='valid target')
plt.plot(np.arange(y_train.shape[0] + y_valid.shape[0], y_train.shape[0] +
    y_valid.shape[0] + y_test.shape[0]), y_test[:, ft], color='black',
    label='test target')
plt.plot(np.arange(y_train_pred.shape[0]), y_train_pred[:, ft], color='red',
    label='train prediction')
plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0] +
    y_valid_pred.shape[0]), y_valid_pred[:, ft], color='orange', label=
    'valid prediction')
plt.plot(np.arange(y_train_pred.shape[0] + y_valid_pred.shape[0], 
    y_train_pred.shape[0] + y_valid_pred.shape[0] + y_test_pred.shape[0]),
    y_test_pred[:, ft], color='green', label='test prediction')
plt.title('past and future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')
plt.subplot(1, 2, 2)
plt.plot(np.arange(y_train.shape[0], y_train.shape[0] + y_test.shape[0]),
    y_test[:, ft], color='black', label='test target')
plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0] +
    y_test_pred.shape[0]), y_test_pred[:, ft], color='green', label=
    'test prediction')
plt.title('future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')
corr_price_development_train = np.sum(np.equal(np.sign(y_train[:, 1] -
    y_train[:, 0]), np.sign(y_train_pred[:, 1] - y_train_pred[:, 0])).
    astype(int)) / y_train.shape[0]
corr_price_development_valid = np.sum(np.equal(np.sign(y_valid[:, 1] -
    y_valid[:, 0]), np.sign(y_valid_pred[:, 1] - y_valid_pred[:, 0])).
    astype(int)) / y_valid.shape[0]
corr_price_development_test = np.sum(np.equal(np.sign(y_test[:, 1] - y_test
    [:, 0]), np.sign(y_test_pred[:, 1] - y_test_pred[:, 0])).astype(int)
    ) / y_test.shape[0]
print(
    'correct sign prediction for close - open price for train/valid/test: %.2f/%.2f/%.2f'
     % (corr_price_development_train, corr_price_development_valid,
    corr_price_development_test))
plt.show()

import math
import datetime
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from common import normalize_data, plot_stock_vs_volume, load_data

# chosen stock
chosen_stock = 'EQIX'
sequence_length = 40 # days

# train, valid, test size
size_train = 80 # 80%
size_valid = 10 # 10%
size_test = 10 # 10%

curr_dir = os.path.dirname(__file__)
work_dir = os.path.join(curr_dir, '..')
data_dir = os.path.join(work_dir, 'data-stock-nyse')

# csv to read
csv_path = os.path.join(data_dir, 'prices-split-adjusted.csv')

# read data
df = pd.read_csv(csv_path, index_col=0)
print(df.head())
print(df.tail())

## try to plot
# plot_stock_vs_volume(df=df, stock_name=chosen_stock)
# plt.show()

# choose one stock, drop label and volume, left only
# open close low high
df_stock = df[df['symbol'] == chosen_stock].copy()
df_stock.drop(['symbol'], axis=1, inplace=True)
df_stock.drop(['volume'], axis=1, inplace=True)

# normalize
df_normalized = normalize_data(df_stock, list(df_stock.columns)) 

# create train and test data
(x_train, y_train), (x_valid, y_valid), (x_test, y_test) = load_data(df_normalized, sequence_length)

# machine learning part (RNN)
index_in_epoch = 0
perm_array  = np.arange(x_train.shape[0])
np.random.shuffle(perm_array)

# function to get the next batch
def get_next_batch(batch_size):
    global index_in_epoch, x_train, perm_array   
    start = index_in_epoch
    index_in_epoch += batch_size
    
    if index_in_epoch > x_train.shape[0]:
        np.random.shuffle(perm_array) # shuffle permutation array
        start = 0 # start next epoch
        index_in_epoch = batch_size
        
    end = index_in_epoch
    return x_train[perm_array[start:end]], y_train[perm_array[start:end]]

# parameters
n_steps = sequence_length-1 
n_inputs = 4 
n_neurons = 200 
n_outputs = 4
n_layers = 2
learning_rate = 0.001
batch_size = 50
n_epochs = 100 
train_set_size = x_train.shape[0]
test_set_size = x_test.shape[0]

tf.reset_default_graph()

X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_outputs])

# use Basic RNN Cell
layers = [tf.contrib.rnn.BasicRNNCell(num_units=n_neurons, activation=tf.nn.elu)
          for layer in range(n_layers)]
                                                                     
multi_layer_cell = tf.contrib.rnn.MultiRNNCell(layers)
rnn_outputs, states = tf.nn.dynamic_rnn(multi_layer_cell, X, dtype=tf.float32)

stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_neurons]) 
stacked_outputs = tf.layers.dense(stacked_rnn_outputs, n_outputs)
outputs = tf.reshape(stacked_outputs, [-1, n_steps, n_outputs])
outputs = outputs[:,n_steps-1,:] # keep only last output of sequence
                                              
loss = tf.reduce_mean(tf.square(outputs - y)) # loss function = mean squared error 
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) 
training_op = optimizer.minimize(loss)
                                              
# run graph
with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer())
    for iteration in range(int(n_epochs*train_set_size/batch_size)):
        x_batch, y_batch = get_next_batch(batch_size) # fetch the next training batch 
        sess.run(training_op, feed_dict={X: x_batch, y: y_batch}) 
        if iteration % int(5*train_set_size/batch_size) == 0:
            mse_train = loss.eval(feed_dict={X: x_train, y: y_train}) 
            mse_valid = loss.eval(feed_dict={X: x_valid, y: y_valid}) 
            print('%.2f epochs: MSE train/valid = %.6f/%.6f'%(
                iteration*batch_size/train_set_size, mse_train, mse_valid))

    y_train_pred = sess.run(outputs, feed_dict={X: x_train})
    y_valid_pred = sess.run(outputs, feed_dict={X: x_valid})
    y_test_pred = sess.run(outputs, feed_dict={X: x_test})


## PREDICTION
ft = 0 # 0 = open, 1 = close, 2 = highest, 3 = lowest

## show predictions
plt.figure(figsize=(15, 5))
plt.subplot(1,2,1)

plt.plot(np.arange(y_train.shape[0]), y_train[:,ft], color='blue', label='train target')

plt.plot(np.arange(y_train.shape[0], y_train.shape[0]+y_valid.shape[0]), y_valid[:,ft],
         color='gray', label='valid target')

plt.plot(np.arange(y_train.shape[0]+y_valid.shape[0],
                   y_train.shape[0]+y_valid.shape[0]+y_test.shape[0]),
         y_test[:,ft], color='black', label='test target')

plt.plot(np.arange(y_train_pred.shape[0]),y_train_pred[:,ft], color='red',
         label='train prediction')

plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0]+y_valid_pred.shape[0]),
         y_valid_pred[:,ft], color='orange', label='valid prediction')

plt.plot(np.arange(y_train_pred.shape[0]+y_valid_pred.shape[0],
                   y_train_pred.shape[0]+y_valid_pred.shape[0]+y_test_pred.shape[0]),
         y_test_pred[:,ft], color='green', label='test prediction')

plt.title('past and future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')

plt.subplot(1,2,2)

plt.plot(np.arange(y_train.shape[0], y_train.shape[0]+y_test.shape[0]),
         y_test[:,ft], color='black', label='test target')

plt.plot(np.arange(y_train_pred.shape[0], y_train_pred.shape[0]+y_test_pred.shape[0]),
         y_test_pred[:,ft], color='green', label='test prediction')

plt.title('future stock prices')
plt.xlabel('time [days]')
plt.ylabel('normalized price')
plt.legend(loc='best')

corr_price_development_train = np.sum(np.equal(np.sign(y_train[:,1]-y_train[:,0]),
            np.sign(y_train_pred[:,1]-y_train_pred[:,0])).astype(int)) / y_train.shape[0]
corr_price_development_valid = np.sum(np.equal(np.sign(y_valid[:,1]-y_valid[:,0]),
            np.sign(y_valid_pred[:,1]-y_valid_pred[:,0])).astype(int)) / y_valid.shape[0]
corr_price_development_test = np.sum(np.equal(np.sign(y_test[:,1]-y_test[:,0]),
            np.sign(y_test_pred[:,1]-y_test_pred[:,0])).astype(int)) / y_test.shape[0]

print('correct sign prediction for close - open price for train/valid/test: %.2f/%.2f/%.2f'%(
    corr_price_development_train, corr_price_development_valid, corr_price_development_test))

plt.show()