Showing preview only (1,600K chars total). Download the full file or copy to clipboard to get everything.
Repository: LiamConnell/deep-algotrading
Branch: master
Commit: 3c13a82910ca
Files: 25
Total size: 1.5 MB
Directory structure:
gitextract__rjh3qrn/
├── .ipynb_checkpoints/
│ └── singlestock_regresion_(1)-checkpoint.ipynb
├── DataFlow_Suite/
│ ├── lstm_exec.py
│ ├── neural_net_exec.py
│ └── rets.pkl
├── LICENSE
├── README.md
└── notebooks/
├── .ipynb_checkpoints/
│ ├── TF-FIN-1-singlestock_regresion-checkpoint.ipynb
│ ├── TF-FIN-2-multistock_regresion-checkpoint.ipynb
│ ├── TF-FIN-3-regression_with_policy_training-checkpoint.ipynb
│ ├── TF-FIN-4-stochastic_gradient_descent-checkpoint.ipynb
│ ├── TF-FIN-5-multi_sampling-checkpoint.ipynb
│ ├── TF-FIN-6-neural_network-checkpoint.ipynb
│ ├── TF-FIN-7-regularization_modular-checkpoint.ipynb
│ ├── Untitled-checkpoint.ipynb
│ └── lstm_(7)-checkpoint.ipynb
├── TF-FIN-1-singlestock_regresion.ipynb
├── TF-FIN-2-multistock_regresion.ipynb
├── TF-FIN-3-regression_with_policy_training.ipynb
├── TF-FIN-4-stochastic_gradient_descent.ipynb
├── TF-FIN-5-multi_sampling.ipynb
├── TF-FIN-6-neural_network.ipynb
├── TF-FIN-7-regularization_modular.ipynb
├── lstm_(7).ipynb
├── policy_net-multisymbol_(july11).ipynb
└── test.pkl
================================================
FILE CONTENTS
================================================
================================================
FILE: .ipynb_checkpoints/singlestock_regresion_(1)-checkpoint.ipynb
================================================
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline\n",
"import matplotlib.pyplot as plt\n",
"import tensorflow as tf\n",
"import numpy as np\n",
"import numpy.random as rng\n",
"import pandas.io.data as web\n",
"import numpy as np\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"#TODO: normalize data, more cost fns, "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_prices(symbol):\n",
" start, end = '2007-05-02', '2016-04-11'\n",
" data = web.DataReader(symbol, 'yahoo', start, end)\n",
" data=pd.DataFrame(data)\n",
" prices=data['Adj Close']\n",
" #prices=np.asarray(list(prices))\n",
" prices=prices.astype(float)\n",
" return prices\n",
"\n",
"def get_returns(prices):\n",
" return (prices-prices.shift(-1))/prices\n",
"\n",
"def sort_data(rets):\n",
" ins = []\n",
" outs = []\n",
" for i in range(len(rets)-100):\n",
" ins.append(rets[i:i+100].tolist())\n",
" outs.append(rets[i+100])\n",
" return np.array(ins), np.array(outs)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"gs = get_prices('GS')\n",
"rets = get_returns(gs)\n",
"ins, outs = sort_data(rets)\n",
"div = int(.8 * ins.shape[0])\n",
"train_ins, train_outs = ins[:div], outs[:div]\n",
"test_ins, test_outs = ins[div:], outs[div:]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"sess = tf.InteractiveSession()"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# we define two placeholders for our input and output\n",
"x = tf.placeholder(tf.float32, [None, 100])\n",
"y_ = tf.placeholder(tf.float32, [None, 1])\n",
"\n",
"# we define trainable variables for our model\n",
"W = tf.Variable(tf.random_normal([100, 1]))\n",
"b = tf.Variable(tf.random_normal([1]))\n",
"\n",
"# we define our model: y = W*x + b\n",
"y = tf.matmul(x, W) + b\n",
"\n",
"# two choices for cost function: cross entropy or mean squared error\n",
"# use MSE for now\n",
"# TODO learn more about cost fns and training steps\n",
"cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))\n",
"train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)\n",
"#MSE:\n",
"cost = tf.reduce_sum(tf.pow(y-y_, 2))/(2*1000)\n",
"optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cost)"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 1000 cost= 0.019055584\n",
"Epoch: 2000 cost= 0.005943393\n",
"Epoch: 3000 cost= 0.002348902\n",
"Epoch: 4000 cost= 0.001233126\n",
"Epoch: 5000 cost= 0.000856721\n",
"Epoch: 6000 cost= 0.000721102\n",
"Epoch: 7000 cost= 0.000669394\n",
"Epoch: 8000 cost= 0.000648663\n",
"Epoch: 9000 cost= 0.000639970\n",
"Epoch: 10000 cost= 0.000636177\n",
"Epoch: 11000 cost= 0.000634464\n",
"Epoch: 12000 cost= 0.000633667\n",
"Epoch: 13000 cost= 0.000633285\n",
"Epoch: 14000 cost= 0.000633100\n",
"Epoch: 15000 cost= 0.000633007\n",
"Epoch: 16000 cost= 0.000632960\n",
"Epoch: 17000 cost= 0.000632936\n",
"Epoch: 18000 cost= 0.000632923\n",
"Epoch: 19000 cost= 0.000632917\n",
"Epoch: 20000 cost= 0.000632913\n"
]
}
],
"source": [
"# initialize variables to random values\n",
"init = tf.initialize_all_variables()\n",
"sess.run(init)\n",
"# run optimizer on entire training data set many times\n",
"for epoch in range(20000):\n",
" sess.run(optimizer, feed_dict={x: train_ins, y_: train_outs.reshape(1,-1).T})\n",
" # every 1000 iterations record progress\n",
" if (epoch+1)%1000== 0:\n",
" c = sess.run(cost, feed_dict={x: train_ins, y_: train_outs.reshape(1,-1).T})\n",
" print(\"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c))"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1121c5fd0>]"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\nRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x111ce6080>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#train results\n",
"predict = y\n",
"p = sess.run(predict, feed_dict={x: train_ins})\n",
"position = 2*((p>0)-.5)\n",
"returns= position.reshape(-1) * train_outs\n",
"plot(np.cumprod(returns+1))"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1123ae860>]"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\nAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1121dc550>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#test results\n",
"predict = y\n",
"p = sess.run(predict, feed_dict={x: test_ins})\n",
"position = 2*((p>0)-.5)\n",
"returns= position.reshape(-1) * test_outs\n",
"plot(np.cumprod(returns+1))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.4.4"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
================================================
FILE: DataFlow_Suite/lstm_exec.py
================================================
import tensorflow as tf
import numpy as np
import numpy.random as rng
import pandas.io.data as web
import numpy as np
import pandas as pd
def get_prices(symbol):
start, end = '2007-05-02', '2016-04-11'
data = web.DataReader(symbol, 'yahoo', start, end)
data=pd.DataFrame(data)
prices=data['Adj Close']
prices=prices.astype(float)
return prices
def get_returns(prices):
return ((prices-prices.shift(-1))/prices)[:-1]
def get_data(list):
l = []
for symbol in list:
rets = get_returns(get_prices(symbol))
l.append(rets)
return np.array(l).T
symbol_list = ['C', 'GS']
rets = get_data(symbol_list)
def lstm_iterator(raw_data, num_steps, data_size):
batch_size=1
raw_data = np.array(raw_data, dtype=np.float32)
data_len = len(raw_data)
batch_len = data_len // batch_size
data = np.zeros([batch_size, batch_len, data_size], dtype=np.float32)
for i in range(batch_size):
data[i] = raw_data[batch_len * i:batch_len * (i + 1),:]
epoch_size = (batch_len - 1) // num_steps
if epoch_size == 0:
raise ValueError("epoch_size == 0, decrease batch_size or num_steps")
for i in range(epoch_size):
x = data[:, i*num_steps:(i+1)*num_steps]
y = data[:, i*num_steps+1:(i+1)*num_steps+1]
yield (x[0], y[0])
class LSTMModel(object):
def __init__(self, num_steps, num_samples):#, config):
symbol_list = ['C', 'GS']
positions = tf.constant([-1,0,1]) #long, neutral or short
num_positions = 3
num_symbols = len(symbol_list)
self.num_samples = num_samples
self.num_steps = num_steps
#n_input = num_symbols * 100
hidden_size=21
n_classes = num_positions * num_symbols
#self.num_steps = tf.placeholder(tf.int64)
# define placeholders
self.inputs_ = tf.placeholder(tf.float32, [None, num_symbols])
self.targets_ = tf.placeholder(tf.float32, [None, num_symbols])
cell = tf.nn.rnn_cell.BasicLSTMCell(hidden_size, forget_bias=0.0, state_is_tuple=True)
#cell = tf.nn.rnn_cell.MultiRNNCell([cell] * config.num_layers)
cell = tf.nn.rnn_cell.InputProjectionWrapper(cell, num_symbols)
cell = tf.nn.rnn_cell.OutputProjectionWrapper(cell, n_classes)
outputs=[]
self.initial_state = cell.zero_state(1, tf.float32)
state = self.initial_state
time_step = 0
'''with tf.variable_scope("RNN"):
def body(x):
inp = self.inputs_[time_step,:]
inp = tf.reshape(inp, [1,-1])
(cell_output, state) = cell(inp, state)
outputs.append(cell_output)
return
def condition(x):
return tf.reduce_sum(x) < 100
tf.while_loop(condition, body, [x])'''
with tf.variable_scope("RNN"):
for time_step in range(self.num_steps): #####num_steps???
if time_step > 0: tf.get_variable_scope().reuse_variables()
inp = self.inputs_[time_step,:]
inp = tf.reshape(inp, [1,-1])
(cell_output, state) = cell(inp, state)
outputs.append(cell_output) #[6,]
self.final_state = state
y = tf.reshape(tf.concat(1, outputs), [-1, n_classes])
# loop through symbol, taking the columns for each symbol's bucket together
pos = {}
sample_n = {}
sample_mask = {}
symbol_returns = {}
relevant_target_column = {}
for i in range(num_symbols):
# isolate the buckets relevant to the symbol and get a softmax as well
symbol_probs = y[:,i*num_positions:(i+1)*num_positions]
symbol_probs_softmax = tf.nn.softmax(symbol_probs) # softmax[i, j] = exp(logits[i, j]) / sum(exp(logits[i]))
# sample probability to chose our policy's action
sample = tf.multinomial(tf.log(symbol_probs_softmax), num_samples)
for sample_iter in range(num_samples):
sample_n[i*num_samples + sample_iter] = sample[:,sample_iter]
pos[i*num_samples + sample_iter] = tf.reshape(sample_n[i*num_samples + sample_iter], [-1]) - 1
symbol_returns[i*num_samples + sample_iter] = tf.mul(
tf.cast(pos[i*num_samples + sample_iter], tf.float32),
self.targets_[:,i])
sample_mask[i*num_samples + sample_iter] = tf.cast(tf.reshape(tf.one_hot(sample_n[i*num_samples + sample_iter], 3), [-1,3]), tf.float32)
relevant_target_column[i*num_samples + sample_iter] = tf.reduce_sum(
symbol_probs * sample_mask[i*num_samples + sample_iter],1)
daily_returns_by_symbol_ = tf.concat(1, [tf.reshape(t, [-1,1]) for t in symbol_returns.values()])
daily_returns_by_symbol = tf.transpose(tf.reshape(daily_returns_by_symbol_, [-1,2,num_samples]), [0,2,1]) #[?,5,2]
daily_returns = tf.reduce_mean(daily_returns_by_symbol, 2) # [?,5]
total_return = tf.reduce_prod(daily_returns+1, 0)
z = tf.ones_like(total_return) * -1
self.total_return = total_return = tf.add(total_return, z)
ann_vol = tf.mul(
tf.sqrt(tf.reduce_mean(tf.pow((daily_returns - tf.reduce_mean(daily_returns, 0)),2),0)) ,
np.sqrt(252)
)
self.sharpe = tf.div(total_return, ann_vol)
#Maybe metric slicing later
#segment_ids = tf.ones_like(daily_returns[:,0])
#partial_prod = tf.segment_prod(daily_returns+1, segment_ids)
training_target_cols = tf.concat(1, [tf.reshape(t, [-1,1]) for t in relevant_target_column.values()])
ones = tf.ones_like(training_target_cols)
gradient_ = tf.nn.sigmoid_cross_entropy_with_logits(training_target_cols, ones)
gradient = tf.transpose(tf.reshape(gradient_, [-1,2,num_samples]), [0,2,1]) #[?,5,2]
#cost = tf.mul(gradient , daily_returns_by_symbol_reshaped)
#cost = tf.mul(gradient , tf.expand_dims(daily_returns, -1))
cost = tf.mul(gradient , tf.expand_dims(total_return, -1))
#cost = tf.mul(gradient , tf.expand_dims(sharpe, -1))
self.optimizer = tf.train.GradientDescentOptimizer(0.0001).minimize(cost)
self.costfn = tf.reduce_mean(cost)
def run_train_results(m, epoch):
state = m.initial_state.eval()
rs = rets[:-200]
full_feed = {m.inputs_: rs[:-1], m.targets_: rs[1:], m.initial_state: state}
t,s, c = session.run([ m.total_return, m.sharpe, m.costfn], feed_dict=full_feed)
t = np.mean(t)
s = np.mean(s)
print("Epoch:", '%04d' % (epoch+1), "cost=",c, "total return=", "{:.9f}".format(t),
"sharpe=", "{:.9f}".format(s))
return t
def run_test_results(m, epoch):
state = m.initial_state.eval()
rs = rets[-200:]
full_feed = {m.inputs_: rs[:-1], m.targets_: rs[1:], m.initial_state: state}
t,s, c = session.run([ m.total_return, m.sharpe, m.costfn], feed_dict=full_feed)
t = np.mean(t)
s = np.mean(s)
print("Epoch:", '%04d' % (epoch+1), "cost=",c, "total return=", "{:.9f}".format(t),
"sharpe=", "{:.9f}".format(s))
return t
def run_epoch(m, epoch):
full_feed = {m.inputs_: rets[:-1], m.targets_: rets[1:]}
state = m.initial_state.eval()
for step, (x, y) in enumerate(lstm_iterator(rets,20,2 )):
#m.num_steps = len(x)
feed_dict = {m.inputs_: x, m.targets_: y, m.initial_state: state}
_ , state = session.run([m.optimizer, m.final_state], feed_dict=feed_dict)
return
results = []
pos_results = []
with tf.Graph().as_default(), tf.Session() as session:
with tf.variable_scope("model", reuse=None):#, initializer=init):
m = LSTMModel(num_steps = 20, num_samples = 5)#, config=config)
with tf.variable_scope("model", reuse=True):#, initializer=init):
mvalid = LSTMModel(num_steps = len(rets[:-200]) -1, num_samples = 1)#, config=config)
with tf.variable_scope("model", reuse=True):#, initializer=init):
mtest = LSTMModel(num_steps = len(rets[-200:]) -1, num_samples = 1)
tf.initialize_all_variables().run()
for epoch in range(10):
run_epoch(m, epoch )
print('getting results...')
trt = run_train_results(mvalid, epoch)
print('trt')
ttt = run_test_results(mtest, epoch)
print('test: ',ttt)
results.append(ttt)
if trt>0:
pos_results.append(ttt)
print(np.mean(results))
print(np.mean(pos_results))
================================================
FILE: DataFlow_Suite/neural_net_exec.py
================================================
#import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import numpy.random as rng
import pandas.io.data as web
import numpy as np
import os
import pandas as pd
# we modify this data organizing slightly to get two symbols
def get_prices(symbol):
start, end = '2007-05-02', '2016-04-11'
data = web.DataReader(symbol, 'yahoo', start, end)
data=pd.DataFrame(data)
prices=data['Adj Close']
prices=prices.astype(float)
return prices
def get_returns(prices):
return ((prices-prices.shift(-1))/prices)[:-1]
def get_data(list):
l = []
for symbol in list:
rets = get_returns(get_prices(symbol))
l.append(rets)
return np.array(l).T
def sort_data(rets):
ins = []
outs = []
for i in range(len(rets)-100):
ins.append(rets[i:i+100].tolist())
outs.append(rets[i+100])
return np.array(ins), np.array(outs)
print('loading data')
symbol_list = ['C', 'GS']
def data_loader_1(symbol_list):
if os.path.exists('rets.pkl'):
rets = pd.read_pickle('rets.pkl')
else:
rets = get_data(symbol_list)
pd.to_pickle(rets, 'rets.pkl')
ins, outs = sort_data(rets)
ins = ins.transpose([0,2,1]).reshape([-1, len(symbol_list) * 100])
div = int(.8 * ins.shape[0])
train_ins, train_outs = ins[:div], outs[:div]
test_ins, test_outs = ins[div:], outs[div:]
#normalize inputs
train_ins, test_ins = train_ins/np.std(ins), test_ins/np.std(ins)
return train_ins, test_ins, train_outs, test_outs
train_ins, test_ins, train_outs, test_outs = data_loader_1(symbol_list)
print('loaded data')
sess = tf.Session()
positions = tf.constant([-1,0,1]) #long, neutral or short
num_positions = 3
num_symbols = len(symbol_list)
num_samples = 10
n_input = num_symbols * 100
n_hidden_1 = 10 # 1st layer number of features
n_hidden_2 = 10 # 2nd layer number of features
n_classes = num_positions * num_symbols # MNIST total classes (0-9 digits)
# define placeholders
x = tf.placeholder(tf.float32, [None, num_symbols * 100])
y_ = tf.placeholder(tf.float32, [None, num_symbols])
weights = {
'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes]))
}
biases = {
'b1': tf.Variable(tf.random_normal([n_hidden_1])),
'b2': tf.Variable(tf.random_normal([n_hidden_2])),
'out': tf.Variable(tf.random_normal([n_classes]))
}
def multilayer_perceptron(x, weights, biases):
# Hidden layer with RELU activation
layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
layer_1 = tf.nn.relu(layer_1)
# Hidden layer with RELU activation
layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])
layer_2 = tf.nn.relu(layer_2)
# Output layer with linear activation
out_layer = tf.matmul(layer_2, weights['out']) + biases['out']
return out_layer
# Construct model
y = multilayer_perceptron(x, weights, biases)
# loop through symbol, taking the columns for each symbol's bucket together
pos = {}
sample_n = {}
sample_mask = {}
symbol_returns = {}
relevant_target_column = {}
for i in range(num_symbols):
# isolate the buckets relevant to the symbol and get a softmax as well
symbol_probs = y[:,i*num_positions:(i+1)*num_positions]
symbol_probs_softmax = tf.nn.softmax(symbol_probs) # softmax[i, j] = exp(logits[i, j]) / sum(exp(logits[i]))
# sample probability to chose our policy's action
sample = tf.multinomial(tf.log(symbol_probs_softmax), num_samples)
for sample_iter in range(num_samples):
sample_n[i*num_samples + sample_iter] = sample[:,sample_iter]
pos[i*num_samples + sample_iter] = tf.reshape(sample_n[i*num_samples + sample_iter], [-1]) - 1
symbol_returns[i*num_samples + sample_iter] = tf.mul(
tf.cast(pos[i*num_samples + sample_iter], np.float32),
y_[:,i])
sample_mask[i*num_samples + sample_iter] = tf.cast(tf.reshape(tf.one_hot(sample_n[i*num_samples + sample_iter], 3), [-1,3]), np.float32)
relevant_target_column[i*num_samples + sample_iter] = tf.reduce_sum(
symbol_probs * sample_mask[i*num_samples + sample_iter],1)
daily_returns_by_symbol_ = tf.concat(1, [tf.reshape(t, [-1,1]) for t in symbol_returns.values()])
daily_returns_by_symbol = tf.transpose(tf.reshape(daily_returns_by_symbol_, [-1,2,num_samples]), [0,2,1]) #[?,5,2]
daily_returns = tf.reduce_mean(daily_returns_by_symbol, 2) # [?,5]
total_return = tf.reduce_prod(daily_returns+1, 0)
z = tf.ones_like(total_return) * -1
total_return = tf.add(total_return, z)
ann_vol = tf.mul(
tf.sqrt(tf.reduce_mean(tf.pow((daily_returns - tf.reduce_mean(daily_returns, 0)),2),0)) ,
np.sqrt(252)
)
sharpe = tf.div(total_return, ann_vol)
#Maybe metric slicing later
#segment_ids = tf.ones_like(daily_returns[:,0])
#partial_prod = tf.segment_prod(daily_returns+1, segment_ids)
training_target_cols = tf.concat(1, [tf.reshape(t, [-1,1]) for t in relevant_target_column.values()])
ones = tf.ones_like(training_target_cols)
gradient_ = tf.nn.sigmoid_cross_entropy_with_logits(training_target_cols, ones)
gradient = tf.transpose(tf.reshape(gradient_, [-1,2,num_samples]), [0,2,1]) #[?,5,2]
#cost = tf.mul(gradient , daily_returns_by_symbol_reshaped)
#cost = tf.mul(gradient , tf.expand_dims(daily_returns, -1))
cost = tf.mul(gradient , tf.expand_dims(total_return, -1))
#cost = tf.mul(gradient , tf.expand_dims(sharpe, -1))
optimizer = tf.train.GradientDescentOptimizer(0.0001).minimize(cost)
costfn = tf.reduce_mean(cost)
def run_training_and_return_test_results():
print('START TRAINING_______________________________')
# initialize variables to random values
init = tf.initialize_all_variables()
sess.run(init)
# run optimizer on entire training data set many times
train_size = train_ins.shape[0]
for epoch in range(20000):
start = rng.randint(train_size-15)
batch_size = rng.randint(2,50)
end = min(train_size, start+batch_size)
sess.run(optimizer, feed_dict={x: train_ins[start:end], y_: train_outs[start:end]})#.reshape(1,-1).T})
# every 1000 iterations record progress
if (epoch+1)%1000== 0:
t,s, c = sess.run([ total_return, sharpe, costfn], feed_dict={x: train_ins, y_: train_outs})#.reshape(1,-1).T})
t = np.mean(t)
s = np.mean(s)
print("Epoch:", '%04d' % (epoch+1), "cost=",c, "total return=", "{:.9f}".format(t),
"sharpe=", "{:.9f}".format(s))
#print(t)
print('DONE TRAINING _______________________________')
d_tr, t_tr = sess.run([daily_returns, total_return], feed_dict={x: train_ins, y_: train_outs})
d_te, t_te = sess.run([daily_returns, total_return], feed_dict={x: test_ins, y_: test_outs})
t_tr = np.mean(t_tr)
t_te = np.mean(t_te)
print("total return train=", "{:.9f}".format(t_tr))
print("total return test=", "{:.9f}".format(t_te))
return t_tr, t_te
results = []
pos_results = []
for i in range(100):
tr, te = run_training_and_return_test_results()
results.append(te)
if tr>0:
pos_results.append(te)
print('iter: ', i)
print(np.mean(results))
print(np.mean(pos_results))
#print('final from net', '%f' %zz)
print(np.mean(results))
print(np.mean(pos_results))
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016 LiamConnell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# A tour through tensorflow with financial data
I present several models ranging in complexity from simple regression to LSTM and policy networks. The series can be used as an educational resource for tensorflow or deep learning, a reference aid, or a source of ideas on how to apply deep learning techniques to problems that are outside of the usual deep learning fields (vision, natural language).
Not all of the examples will work. Some of them are far too simple to even be considered viable trading strategies and are only presented for educational purposes. Others, in the notebook form I present, have not been trained for the proper amount of time. Perhaps with a bit of rented GPU time they will be more promising and I leave that as an excercise for the reader. Hopefully this project inspires some to try using deep learning techniques for some more interesting problems. [Contact me](mailto:ljrconnell@gmail.com) if interested in learning more or if you have suggestions for additions or improvements.
The algorithms increase in complexity and introduce new concepts as they progress:
## Simple Regression [(notebook)][1]
Here we regress the prices from the last 100 days to the next day's price, training *W* and *b* in the equation *y = Wx + b* where *y* is the next day's price, *x* is a vector of dimension 100, *W* is a 100x1 matrix and *b* is a 1x1 matrix. We run the gradient descent algorithm to minimize the mean squared error of the predicted price and the actual next day price. Congratulations, you passed highschool stats. But hopefully this simple and naive example helps demonstrate the idea of a tensor graph, as well as showing a great example of extreme overfitting.
## Simple Regression on Multiple Symbols [(notebook)][2]
Things get a little more interesting as soon as we introduce more than one symbol. What is the best way to model our eventual investment strategy? We start to realize that our model only vaguely implies a policy (investment actions) by predicting the actual movement in price. The implied policy is simple: buy if the the predicted price movement is positive, sell if it is negative. But that doesnt sound realistic at all. How much do we buy? And will optimizing this, even if we are very careful to avoid overfitting, even produce results that allign with our goals? We havent actaully defined our goals explicitly, but for those who are not familiar with investment metrics, common goals include:
+ maximize risk adjusted return (like the [Sharpe](https://en.wikipedia.org/wiki/Sharpe_ratio) ratio)
+ consistency of returns over time
+ low market exposure
+ [long/short equity](http://www.investopedia.com/terms/l/long-shortequity.asp)
If markets were easy to figure out and we could accurately predict the next day's return then it wouldn't matter. Our implied policy would fit with some goals (not long/short equity though) and the strategy would be viable. The reality is that our model cannot accurately predict this, nor will our strategy ever be perfect. Our best case scenario is always just winning slightly more than losing. When operating on these margins it is much more important that we consider the policy explicitly, thus moving to 'Policy Based' deep learning.
## Policy Gradient Training [(notebook)][3]
Our policy will remain simple. We will chose a position, long/neutral/short, for each symbol in our portfolio. But now, instead of letting our estimation of the future return inform our decision, we train our network to choose the best position. Thus, instead of having an *implied* policy, it is *explicit* and *trained* directly.
Even thought the policy is simple in this case, training it is a bit more involved. I did my best to interpret Andrej Karpathy's excelent article on [Reinforcement Learning](http://karpathy.github.io/2016/05/31/rl/) when writing this code. It might be worth reading his explanation, but I'll do my best to summarize what I did.
We update our regression engine so that its output, *y*, is a vector in dimension *[batch_size, number_positions x number_symbols]* (a long, short, neutral bucket for each symbol).
For each symbol in our portfolio, we **sample** the probability distribution of our three position buckets to get our policy decision (a position long/short/neutral), we multiply our decision (element of {-1,0,1}) by the target value to get a daily return for the symbol. Then we add that value for all the symbols to get a full daily return. We can also get other metrics like the total return and sharpe ratio since we actually are feeding this through as a batch (more on that later). As Karpathy points out, we are *only interested in the gradients of the positions we sampled*, so we select the appropriate columns from the output and combine them into a new tensor.
This part of the code was a bit tricky for several reasons. First off, we have a loop through and isolate each symbol since I need one position per symbol. I also am using multinomial probability distributions, so I need to take a softmax of those values. Softmax pushes values so that they sum to 1, and therefore can represent a probability distribution. In pseudocode: `softmax[i, j] = exp(logits[i, j]) / sum(exp(logits[i]))`.
```
for i in range(len(symbol_list)):
symbol_probs = y[:,i*num_positions:(i+1)*num_positions]
symbol_probs_softmax = tf.nn.softmax(symbol_probs)
```
Next, we sample that probability distribution. Even though the code is a nice one-liner due to tensorflow's multinomial function, the function is NOT DIFFERENTIABLE, meaning that we will not be able to "move through" this step durring back propogation. We calcultate the position vector simply by subtracting 1 from the column indices that we got from the sample so that we get and element of {-1,0,1}.
```
pos = {}
for i in range(len(symbol_list)):
# ISOLATE from before
# ...
sample = tf.multinomial(tf.log(symbol_probs_softmax), 1)
pos[i] = tf.reshape(sample, [-1]) - 1 # choose(-1,0,1)
```
Then we multiply that position by the target (future return) for each day. This gives us our return. It already looks like a cost function but remember that it's not differentiable.
```
symbol_returns = {}
for i in range(len(symbol_list)):
# ISOLATE and SAMPLE from before
# ...
symbol_returns[i] = tf.mul(tf.cast(pos[i], float32), y_[:,i])
```
Finally, we isolate the relevant column (the one we chose in our sample) from our probability distribution. The idea isn't very difficult but the code was a bit tough, remember that we are dealing with a whole batch of outputs at a time. This step NEEDS to be differentiable since we will use this tensor to compute our gradients. Unfortunately tensorflow is still developing a function that does it by itself, [here](https://github.com/tensorflow/tensorflow/issues/206) is the discussion. I actually think that my solution is the best and I suggest it in the discussion, but I'm really not an expert at efficient computation. If anyone thinks of a more efficient solution or if tensorflow finishes theirs please let me know.
```
relevant_target_column = {}
for i in range(len(symbol_list)):
# ...
# ...
sample_mask = tf.reshape(tf.one_hot(sample, 3), [-1,3])
relevant_target_column[i] = tf.reduce_sum(symbol_probs_softmax * sample_mask,1)
```
So here is all of that together:
```
# loop through symbols, taking the buckets for one symbol at a time
pos = {}
symbol_returns = {}
relevant_target_column = {}
for i in range(len(symbol_list)):
# ISOLATE the buckets relevant to the symbol and get a softmax as well
symbol_probs = y[:,i*num_positions:(i+1)*num_positions]
symbol_probs_softmax = tf.nn.softmax(symbol_probs)
# SAMPLE probability to chose our policy's action
sample = tf.multinomial(tf.log(symbol_probs_softmax), 1)
pos[i] = tf.reshape(sample, [-1]) - 1 # choose(-1,0,1)
# GET RETURNS by multiplying the policy (position taken) by the target return (y_) for that day
symbol_returns[i] = tf.mul(tf.cast(pos[i], float32), y_[:,i])
# isolate the output probability the selected policy (for use in calculating gradient)
sample_mask = tf.reshape(tf.one_hot(sample, 3), [-1,3])
relevant_target_column[i] = tf.reduce_sum(symbol_probs_softmax * sample_mask,1)
```
So now we have a tensor with the regression's probability for the chosen (sampled) action for each symbol and each day. We also have a few performance metrics like daily and total return to choose from, but they're not differentiable because we sampled the probability so we cant just "gradient descent maximize" the profit...unfortunately. Instead, we find the sigmoid cross entropy (a sort of distance function) between the first table (the probabilities we chose/sampled) and an all-ones tensor of the same shape. We get a table of cross entropies of the same size (number of symbols by batch size) This is basically equivalent to saying, how do I do MORE of what I'm already doing, for every decision that I made.
```
training_target_cols = tf.concat(1, [tf.reshape(t, [-1,1]) for t in relevant_target_column.values()])
ones = tf.ones_like(training_target_cols)
gradient = tf.nn.sigmoid_cross_entropy_with_logits(training_target_cols, ones)
```
Now we dont necessarilly want MORE of what we're doing, but the opposite of it is definitely LESS of it, which is useful. We multiply that tensor by our fitness function (the daily or aggregate return) and we use the gradient descent optimizer to minimize the cost. So you see? If the fitness function is negative, it will train the weights of the regression to NOT do what it just did. Its a pretty cool idea and it can be applied to a lot of problems that are much more interesting. I give some examples in the notebook about which different fitness functions you can apply which I think is better explained by seeing it. Here is that code:
```
cost = tf.mul(gradient , returns) #returns are some reshaped version of symbol_returns (from above)
optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(cost)
```
## Stochastic Gradient Descent [(notebook)][4]
As you saw in the notebook, the policy gradient doesnt train very well when we are grading it on the return over the entire dataset, but it trains very well when it uses each day's return or the position on each symbol every day. This makes sense, if we just take the total return over several years and its slightly positive then we tell our machine to do more of that. That will do almost nothing since so many of those decisions were actually losing money. The problem, as we have it set up now, needs to be broken down into smaller units. Fortunately there is some mathematical proof that this is legal and even faster. Score!
Stochastic Gradient Descent is basically just breaking your data into smaller batches and doing gradient descent on each one. It will have slightly less accurate gradients WRT to the entire dataset's cost function, but since you are able to iterate faster with smaller batches you can run way more of them. There might even be more advantages to SGD that I'm not even mentioning, so you can read the [wikipedia](https://en.wikipedia.org/wiki/Stochastic_gradient_descent) or hear [Andrew Ng](https://www.coursera.org/learn/machine-learning#syllabus) talk about it. Or just use it since it works and its faster. If you're going on a wikipedia learning binge you might as well also learn about [Momentum](https://en.wikipedia.org/wiki/Stochastic_gradient_descent#Momentum) and [Adagrad](https://en.wikipedia.org/wiki/Stochastic_gradient_descent#AdaGrad) which are just variations. The latter two only really useful for people doing much bigger projects. If you are working on a huge project and your twobucksanhour AWS GPU instance is too slow then you should definitely be using them (and not be reading this introductory tutorial). At the higher level, the problem of tuning the optimizer and overall efficiency have been thoroughly [researched](http://www.andrewng.org/portfolio/on-optimization-methods-for-deep-learning/).
## Multi Sampling [(notebook)][5]
Since we are sampling the policy, we can sample repeatedly in order to compute better. Karpathy's article summarizes the math behind this nicely and [this](http://arxiv.org/abs/1506.05254) paper is worth reading. The concept is intuitive and simple, but getting the math to work out and the tensor graph in order is very involved. One realizes that a mastery of numpy and a solid understanding of linear algebra are very important to tensorflow once the problems get...deeper, I guess is the word.
Multi sampling adds a useful computational kick that lets the network train much more efficiently. The results are already impressive. Using batches of less than 75 days and only training on the total return over that timeframe, we are able to "overfit" our network. Keep in mind that all we are doing is telling the network to do more of what it is doing when it does well, and less when it does poorly! Sure, we are still far away from having anything worthwhile out of sample, but that is because we are still using *linear regression*.
By now you are probably either wondering *does this guy even know what deep learning is? I havent seen a single neural network!* or you completely forgot we were still using the same linear regression that 16 year olds learn in math class. Well, we'll get to neural networks next but I wanted to talk about other things before neural networks to show how much tensorflow can be used for before neural networks even get mentioned, and to show how much important math exists in deep learning that has nothing to do with neural networks. Tensorflow makes neural nets so easy that you barely even notice that they're part of the picture and its definitely not worth getting bogged down by their math if you dont have a solid understanding of the math behind cross entropy, policy gradients and the like. They probably even distract from where the true difficulty is. Maybe I'll try to get a regression to play pong so that everyone shuts about neural networks and starts talking about policy learning...
## Neural Networks [(notebook)][6]
So we finanlly get to it. Here's the same thing with a neural network. Its the simplest kind of net that there is but it is still very powerful. Way more powerful that our puny regression ever was becuase it has nonlinearities (RELU layers) between the other layers (which are basically just regressions by themselves). A sequence of linear regressions is still obviously linear<sup>[1](#myfootnote1)</sup>. But if we put a nonlinearity between the layers, then our net can do *anything*. Thats what gets people excited about neural networks, becuase they can hold enourmous amounts of information when trained well. Fortunatly, we just learned a bunch of cool ways to train them in steps 1-5. Now putting in the network is very easy. I really changed nothing except the Variable and the equation really is basically still *y = Wx + b* except non-linear *W*.
The reason I introduced the networks so late is becuase they can be a bit difficult to tune. Chosing the right size of your network and the right training step can be difficult and sometimes it is helpful to start out simple until you have all the bells and whistles in place.
In steps 3-5, we spent a lot of time figuring out tricks to do with the training step, which is a widely researched area at the moment and is probably more relevant to algorithmic trading that anything else. Now we are starting to demonstrate some of the techniques used in the prediction engine (regression before, neural network now). I believe this is a much more researched area and TensorFlow is better equiped for it. Many people describe the types of neural networks that we will learn as cells or *legos*. You dont need to think that much about how it works as long as you know what it does. If you noticed, thats what I did with the neural network. There is a lot more to learn and its worth learning, but when you're actually building with it, you dont think about RELU layers as much as input/output and a black box in the middle. Or at least *I* do...there are a bunch of people in image processing who look inside networks and do [very cool things](https://github.com/google/deepdream).
## Regularization and Modularization [(notebook)][7]
From [Wikipedia][wiki_reg])), "regularization is the introduction of additional information in order to solve an ill-posed problem or to prevent overfitting." For our purposes, it is any technique used to reduce overfitting. One of the simplest yet most important examples is [early stopping][early_stopping], that is, ending gradient descent before there is no significant gain in evaluation performance. The idea is that once the model stops improving, it will start to overfit the training data. Most overfitting can be avoided with just this technique.
We have more overfitting problems. Financial data is very noisey with faint signals that are very complex. Markets are zero sum and there are already an enormous number of very smart people getting paid a very large amount of money to develop trading strategies. There are many different patterns that can be learned but we can assume that all of the simple ones have been found (and therefore traded out of the market). Also, the market structure and properties change with time so even if we found a great pattern for the past five years, it might not work a month from now.
We therefore need even more strategies to prevent overfitting. One strategy is called [L2 regularization](http://www.kdnuggets.com/2015/04/preventing-overfitting-neural-networks.html/2). Basically, we *punish a network for having very large weights* by adding the L2 norm of the weights, *1/2(||W||^2_2)*, times a constant *B* (to determine how much we want to regularize). It allows us to control the level of model complexity.
Another method is called [dropout regularization](http://arxiv.org/abs/1207.0580), a technique developed by Geoffrey Hinton. Overfitting is avoided by randomly ommitting half of the neurons during each training iteration. It sounds kooky but the idea is that it avoids the co-adaptation of features in the neural network, so that recognizing a certain set of features does not imply another set, as is the case in many overtrained nets. This way, each neuron will learn to detect a feature that is generally helpful. In validation and normal use, the neurons are not dropped so as to use all informaation. The technique makes the model more robust, avoids overfitting, and essentially turns your network into an ensemble that reaches consensus. Tensorflow's dropout layer includes the scaling required to safely ensemble when it comes time for validation.
Since we want the same model with two different configurations--one with dropout active and one without--we will now pursue our long-overdue duty of refactoring our code. Although the code is presented in a single notebook, keep in mind that what I am essentially doing is modularizing. I won't claim that I am the most organized with my code, but I tried to keep it consistent with the best practices that I have observed others using with their open projects. Moving forward we will keep this structure becuase it is clearly superior to the organization that I had used before.
## LSTM [(notebook)][8]
My favorite neural network, and a true stepping stone into real deep learning is the long short-term memory network, or LSTM. [Colah](http://colah.github.io/posts/2015-08-Understanding-LSTMs/) wrote an incredibly clear explanation of LSTM and there is really no substitute to reading his post. To describe the setup as briefly as possible, you input the data one timestep at a time to the LSTM cell. And each timestep the cell not only recieves the new input, but it recieves the last timestep's output and what is called the **cell state**, a vector that carries information about what happened in the past. Within the cell you have trained gates (basically small neural nets) that decide, based on the three inputs, what to forget from the past cell state, what to remember (or *add*) to the new state, and what to output this timestep. It is a very powerful tool and fascinating in how [effective it is](http://karpathy.github.io/2015/05/21/rnn-effectiveness/).
I am now pretty far into this series and I have a pretty good idea of where it will go from here. These are the problems that I must tackle in no particular order:
* new policies such as
+ long/short equality amongs two symbols and more
+ spread trading (if that is different from above)
+ minimize correlation/ new risk meaesure that is appropriate for large number of symbols
* migrating to AWS and using GPU computing power
* ensebling large numbers of strategies that are generated with the same code
+ policy grads find local maxima so no reason not to use that to my advantage
* testing suite to be able to test if the strategies are viable objectively
* convolution nets, especially among larger groups of symbols we can expect that some patterns are fractal
* turning it into a more formal project or web app
And of course we can start moving to other sources of data:
* text
* scraping
* games
Stay tuned for some articles that I will write about the algorithms used here and a discussion of the difficulties of using these techniques for algorithmic trading developement.
<a name="myfootnote1">1</a>: I hope you didnt sleep through Linear Algebra class! I owe all my LA skills to [Comrade Otto Bretscher](http://personal.colby.edu/personal/o/obretsch/) of Colby College whose class I did sleep through but whose [text book](https://www.amazon.com/Linear-Algebra-Applications-Otto-Bretscher/dp/0136009263) is worth its weight in gold.
[early_stopping]: https://en.wikipedia.org/wiki/Regularization_(mathematics)#Early_stopping
[wiki_reg]: https://en.wikipedia.org/wiki/Regularization_(mathematics)
[1]: /notebooks/TF-FIN-1-singlestock_regresion.ipynb
[2]: /notebooks/TF-FIN-2-multistock_regresion.ipynb
[3]: /notebooks/TF-FIN-3-regression_with_policy_training.ipynb
[4]: /notebooks/TF-FIN-4-stochastic_gradient_descent.ipynb
[5]: /notebooks/TF-FIN-5-multi_sampling.ipynb
[6]: /notebooks/TF-FIN-6-neural_network.ipynb
[7]: /notebooks/TF-FIN-7-regularization_modular.ipynb
[8]: /notebooks/lstm_(7).ipynb#
================================================
FILE: notebooks/.ipynb_checkpoints/TF-FIN-1-singlestock_regresion-checkpoint.ipynb
================================================
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline\n",
"import matplotlib.pyplot as plt\n",
"import tensorflow as tf\n",
"import numpy as np\n",
"import numpy.random as rng\n",
"import pandas.io.data as web\n",
"import numpy as np\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_prices(symbol):\n",
" start, end = '2007-05-02', '2016-04-11'\n",
" data = web.DataReader(symbol, 'yahoo', start, end)\n",
" data=pd.DataFrame(data)\n",
" prices=data['Adj Close']\n",
" #prices=np.asarray(list(prices))\n",
" prices=prices.astype(float)\n",
" return prices\n",
"\n",
"def get_returns(prices):\n",
" return (prices-prices.shift(-1))/prices\n",
"\n",
"def sort_data(rets):\n",
" ins = []\n",
" outs = []\n",
" for i in range(len(rets)-100):\n",
" ins.append(rets[i:i+100].tolist())\n",
" outs.append(rets[i+100])\n",
" return np.array(ins), np.array(outs)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# separate data into inputs and outputs for training and testing\n",
"gs = get_prices('GS')\n",
"rets = get_returns(gs)\n",
"ins, outs = sort_data(rets)\n",
"div = int(.8 * ins.shape[0])\n",
"train_ins, train_outs = ins[:div], outs[:div]\n",
"test_ins, test_outs = ins[div:], outs[div:]"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"sess = tf.InteractiveSession()"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# we define two placeholders for our input and output\n",
"x = tf.placeholder(tf.float32, [None, 100])\n",
"y_ = tf.placeholder(tf.float32, [None, 1])\n",
"\n",
"# we define trainable variables for our model\n",
"W = tf.Variable(tf.random_normal([100, 1]))\n",
"b = tf.Variable(tf.random_normal([1]))\n",
"\n",
"# we define our model: y = W*x + b\n",
"y = tf.matmul(x, W) + b\n",
"\n",
"#MSE:\n",
"cost = tf.reduce_sum(tf.pow(y-y_, 2))/(2*1000)\n",
"optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cost)"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 1000 cost= 0.019055584\n",
"Epoch: 2000 cost= 0.005943393\n",
"Epoch: 3000 cost= 0.002348902\n",
"Epoch: 4000 cost= 0.001233126\n",
"Epoch: 5000 cost= 0.000856721\n",
"Epoch: 6000 cost= 0.000721102\n",
"Epoch: 7000 cost= 0.000669394\n",
"Epoch: 8000 cost= 0.000648663\n",
"Epoch: 9000 cost= 0.000639970\n",
"Epoch: 10000 cost= 0.000636177\n",
"Epoch: 11000 cost= 0.000634464\n",
"Epoch: 12000 cost= 0.000633667\n",
"Epoch: 13000 cost= 0.000633285\n",
"Epoch: 14000 cost= 0.000633100\n",
"Epoch: 15000 cost= 0.000633007\n",
"Epoch: 16000 cost= 0.000632960\n",
"Epoch: 17000 cost= 0.000632936\n",
"Epoch: 18000 cost= 0.000632923\n",
"Epoch: 19000 cost= 0.000632917\n",
"Epoch: 20000 cost= 0.000632913\n"
]
}
],
"source": [
"# initialize variables to random values\n",
"init = tf.initialize_all_variables()\n",
"sess.run(init)\n",
"# run optimizer on entire training data set many times\n",
"for epoch in range(20000):\n",
" sess.run(optimizer, feed_dict={x: train_ins, y_: train_outs.reshape(1,-1).T})\n",
" # every 1000 iterations record progress\n",
" if (epoch+1)%1000== 0:\n",
" c = sess.run(cost, feed_dict={x: train_ins, y_: train_outs.reshape(1,-1).T})\n",
" print(\"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c))"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1121c5fd0>]"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\nRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x111ce6080>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#train results :)\n",
"predict = y\n",
"p = sess.run(predict, feed_dict={x: train_ins})\n",
"position = 2*((p>0)-.5)\n",
"returns= position.reshape(-1) * train_outs\n",
"plot(np.cumprod(returns+1))"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1123ae860>]"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAEACAYAAAC57G0KAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl41OXV//H3YRWkCJQQtmhAkUVRUFRwDbiBC2rrRmut\n2sdqqz4+9fHn3kI3kdpqtVYfN6pVi3WpFatUpRqtC66AKCCbgCBgBISiVJbcvz/OTGcymcyEZLZM\nPq/r4srMd77znZMxnrnn3JuFEBARkeLTIt8BiIhIdijBi4gUKSV4EZEipQQvIlKklOBFRIqUEryI\nSJFKm+DNbLKZrTGzOXU8PsDMXjezf5vZ/2Y+RBERaYj6tOD/AIxO8fha4BLg1xmJSEREMiJtgg8h\n/BNYn+LxqhDC28DWTAYmIiKNoxq8iEiRUoIXESlSrXL1QmamRW9ERBoghGANeV4mW/BpAwghFNS/\n8ePH5z2GphBTocalmBRTc4irMdK24M1sCnAE0NXMPgbGA60jCftOM+sOvAV0BKrN7FJgUAhhU6Mi\nExGRRkmb4EMI49I8vhooy1hEIiKSEc26k7WioiLfIdRSiDFBYcalmOpHMdVfocbVUNbYGk+9X8gs\n5Oq1RESKhZkRCqCTVURECogSvIhIkVKCFxEpUkrwIiJFSgleRKRIKcGLiBQpJXgRkSKlBC8iUqSU\n4EVEipQSvIhIkVKCFxEpUkrwIiJFSgleRKRIFWWC//DDfEcgIpJ/TSrBhwC//z0sXlz3OZ9/DoMG\nwYYNuYtLRKQQNakE//TTMHEiHHwwnHoqPPpo7XOWL4fqarjuOrjpJr8tItIcpd2yr5Dccgv85jew\nahXMnAnnnQc9ekDr1nDQQX7O8uX+87bboFMnGDYMDj88fzGLiORLk0nwW7fCjBnwyCPQubMfe+MN\nGD8e2rWDv/3Njy1f7km/c2fYf38v5yQm+IED4Xe/g6OOyu3vICKSS02mRDNrFvTpE0vuAOXl8Oqr\nMH06bNrkx5Yvh4sugtdfh759YcmS2teaPx/+679yEraISN40iQS/ciVcfDEcfXTN4336wFdfQdeu\n8Morfmz5cthtN+jY0R//6KOaz4luC7tsWey2iEgxKvgEf9ddcOSRXk6ZNKnmY336gBkcfzzMnesJ\ne84cb7mD/0xM8F98Ae3b+zeBtWtz8zuIiORDQSX4rVu93BLvD3+A88+Hn/8cWiX0GPTpA2VlMHSo\nJ/j77/drDB8eezyxRLNuHXTp4nX6Vauy97uIiORb3jtZ338fpkyB/v1hwQL45S9rlk4WLoSzzoIW\nST6Khg/35D9wIFxyCbzwAtxxR+zcHj3gs8886bdu7ceiCb6kxBP84MHZ/x1FRPLBQo4K0WYWkr1W\nv34wcqQn2+hImA0bvIa+fj3suits3OilmLpUVUG3bp7gR46s+VivXj7apndveO01uPxyaNvWW/6j\nRsE552TudxQRyTQzI4SQIgPWLaclmsWL4aGHYverq71T9NZb4amn4KWXvCW/dKk/vnChfwCkSu7g\nrfFp06CiovZjPXrAJ5/47RkzfHSNSjQi0hzkNMFPnw633x67X1XlLfWddvL7hx8Ou+8eS/CzZ3uC\nr4/Ro5N/EMQn8uh1owk+mvhFRIpR2gRvZpPNbI2ZzUlxzq1mttDMZpvZ0LrOW7bMOz2jywesWOGl\nk3h9+ngiXroUrrkGLrywfr9IXXr0gI8/9teMjqjp3NlLNytWNO7aIiKFrD4t+D8Ao+t60MyOA/YI\nIfQDvg/cUde5y5bB6tUwYIBPNlq50hNtvPJyWLQIHn8cTjmldk19R/Xo4R2wv/qVJ/jevb0FX17u\n8YiIFKu0o2hCCP80s/IUp4wF7o+c+4aZdTKz0hDCmsQT42vr773nI1wSE/wJJ8Bhh3linjixnr9F\nCrvs4j//+ld//Vtv9dUmk02CEhEpJpkYJtkL+Dju/gqgN1ArwS9bFmu9L1gAmzfXLtEMGAC/+IU/\nnom1Ynbf3We6fvCBd8aed54fD8GHT37+uS9KJiJSbDLVyZrYvZl07OXKlZ60993XN+V44QXYe+/a\n511wga8a2bZt4wM76STvzP3Tn3zdmv8EbLF6v4hIMcpEC34lUBZ3v3fkWC2nnz6Bzp195ul991Uw\neHAFY8dmIIJ6OPHE2seiZZohQ3ITg4hIOpWVlVRWVmbkWvWa6BSpwT8VQqg17zPSyXpxCOE4MxsO\n/DaEMDzJef+Z6PT557DXXt6C79+/kb9BI/zwh16Pv/ji/MUgIpJKYyY6pW3Bm9kU4Aigq5l9DIwH\nWgOEEO4MITxjZseZ2SLgC+DcdNfs1MnLNfnWpYvPlhURKUb1GUUzrh7nNMk2cJcuPkZeRKQYFdRq\nkrnWpYsvPiYiUoyU4JXgRaRIKcErwYtIkVKCV4IXkSKlBK8ELyJFqlkn+M6dfZhkuqkAW7bkJh4R\nkUxq1gm+bVto08Y34q7LvHl+XlVV7uISEcmEZp3gwcs0q1fX/fiECf5z7tychCMikjHNPsEffTQ8\n8kjdjy9c6IujzZ+fu5hERDKh2Sf4iy6Ce++t+/Hly+GYY7xUIyLSlDT7BD90KPzrX8mXLPjyS9i0\nyTcgueUWuOmm3McnItJQzT7Bm8Ehh9RcKz7q44+hrMwT/JVXwvXXp+6QFREpJM0+wYMn8IkTvd4e\nb/lyT/CdOsENN8B++8Hzz+cnRhGRHaUEj9fh998f7r47duy//ss7VnfdNXZs0CBYvDj38YmINIQS\nPD7O/dxzfQMS8Jr8vff6/fgE37evNuoWkaZDCT7ioIN8n9gNG2IjZl57zUs0UdEt/kREmgIl+Ig2\nbTyZX3SRJ3uATz+t2YJPluBDgOrq3MUpIlJfSvBxSkpiM1Y7dPCf8Qm+vNwTfHU1TJrkt6+91te0\nee+9nIcrIpJS2i37mpOuXb1jtbQUTj4Z7ryzZommQwffJPz44+HFF319mocegsMPh7/9DfbZJ3+x\ni4gkUgs+TkmJl2VuuQVOO81b5tGWfNS118I778DUqX7ewIHwve/Byy/nJ2YRkbqoBR+na1f/2a0b\n7LUXfPe7tc857TRvwbdrBw88ACeeCJs3w5lnwsEHw3HHwbhxsPvuuY1dRCSRWvBxSkr8Z7du/u/m\nm5Of1769z4A980zYeWf/YJg7Fy65BFatghEj4N13/dxZs+DSS/1DQEQkl9SCjxNN8KWlO/7cvn39\n37hxMGqU1/BvvBGefNLLN8uWwaOPQuvWmY1ZRKQuasHH6doVWrTwNeIb45vfhPPO87VrpkzxCVPV\n1V7CERHJFQvp9qvL1AuZhVy9VkPNnAljxqTeAGRHbNsG//gHHHusj5fv1g1mz4aePTNzfREpfmZG\nCMEa8ly14OMMHOhllUxp1cqTO3jNftgweOutzF1fRCQVJfg4O+0E3/lO9q5/wAHw9tvZu76ISDwl\n+BwaORIee8xLNyIi2aYEn0MVFT5C58EH8x2JiDQHaRO8mY02s/lmttDMrkzyeGcze8LMZpvZG2a2\nV3ZCbfrM4Kqr4NZbvdNVRCSbUiZ4M2sJ3AaMBgYB48xsYMJp1wDvhhD2Bc4GbslGoMXimGN8DZsF\nC7Jz/a1bs3NdEWl60rXgDwQWhRCWhhC2Ag8DJyWcMxB4ESCE8CFQbmYlGY+0SLRo4aN1lizJ3DWv\nusrXsgefRTtzZuauLSJNV7oE3wv4OO7+isixeLOBbwCY2YHAbkDvTAVYjHbbzWe2ZsrUqfDMM/7N\n4J13fLNwEZF0SxXUp1J8A3CLmc0E5gAzge3JTpwwYcJ/bldUVFBRUVGvIItNYxL8IYf45Kmddood\nW7MGXn0Vekc+VquqGh+jiORHZWUllZWVGblWypmsZjYcmBBCGB25fzVQHUKYlOI5HwGDQwibEo4X\n/EzWXHnwQbj6ahgwAO67D3olfieqw5df+uJmCxbAHnt4p+3Wrb6nbGkpnHIK/PGP8OMfw5W1usNF\npCnK5kzWt4F+ZlZuZm2AM4CpCS++S+QxzOx84KXE5C417bYbrFjhK1D+5S/1f97atf7zf/4HfvpT\nX+9m1SpfAmHnnX3zkRNPVAteRFzKBB9C2AZcDDwLzAX+HEKYZ2YXmNkFkdMGAXPMbD5wLHBpNgMu\nBnvsAd27wznneHmlvqIJfvp0mDYN/vAHeOWVWOu9RQs46ij47LOshC0iTUza5YJDCNOAaQnH7oy7\n/TrQP/OhFa8ePbwjdPLkHVubJprgt2yJPe+55zzBf/e7vk59aala8CLiNJM1T1q18mRc18qVixfX\nngwVTfDgj5nFEvzee3vZpmtXteBFxCnB51FpafISzZo1vrn388/DprjejLVrfVOS0lJP5Icd5jX4\n6FaD4I+rBS8ioASfV6WlPinp6KNrHn/wQejUyfd33X//2IfAunVw5JHwrW/BnnvCZZf5KJxzz409\nt6TEz6+uTv6ac+dmbr17ESls2vAjj6LDHqFmOebgg+GKK+Df//blhZ991odSDhrkm4VcfjmsXOkd\ntS1b1r7ugAG+k9TQobFj1dXw97/D//2fz3a9+urs/m4ikhmNGSapPVnzqH372O0vvvBkv3EjzJnj\nG4W0awdjx/qkqGnTfHLT4MF+fqqx80cfDU884XX56B6wH30Exx8PnTs3fktCEWkaVKLJswMO8OGN\n0TLMSy/BQQd5cgf/EHj0UTjwQK/Jd+uW/ppjx8INN8DvfgdLl/qxaF1+/Xp44w3/hiAixU0JPs/e\nfNOTd7QuvnCht7wTjRrlJZdjjkl/zaOPhl/9CmbM8LJOdTV8+qk/Nnw4zJ8Pv/61l4hEpHgpwReA\n7t1jCX79+uQllCuvhBdfjJVc0unVyydBbd7s9fpPP/XtCKdN8+u3aOEdriJSvJTgC0B8gl+3zuvk\niVq3rn9yB0/wq1b57cWLPcH37Omjc/76Vzj9dHjvvcbHLiKFSwm+AHTvHqvBr1+fPMHvqPhO2CVL\nPMFH6/eHHQb77QezZ+/4dUPwmbQiUviU4AtA9+7wySd+O1MJvkcP/1lSEmvBl5bGHh8wIP2uUgsX\n+vry8Z57zlevFJHCpwRfAOLXh89Ugm/TxlvsFRWe4NesqTkCZ489YNGi1Ne46y74xS9qHvv8c/+p\nTUVECp8SfAHo29eTMNTdydoQI0fCCSfA8uW1E3yfPn5827a6nz9rlo/EiZ+EFV0PZ9q0mudmcocq\nEckMJfgCUF7u68Nv25a5FjzAww/DEUd4Il+61F8nqm1bLw0tX578uSF4gt+0yZdFiCb2Tz/1CVnz\n58fOraqCfv3gq68yE7eIZIYSfAFo0yaWbD//PHMJHnzkzOrVntB32aXmY6nKNCtW+FDKSy6B7dt9\nkhV4gh84sObKlu++6ztLZXIjcRFpPC1VUCD69vVhi61be8LPlNat/cOjZ8/aj/XvD/Pm+eSpqir4\n2td8OYQnn4SnnoLRo+H6632v13HjfFJWXQke/MNi4MDMxS4ijaMWfIHYc094/fXMtt6jysr8AyTR\nsGGxjUNOPdVnwG7dCtdeC/feCxddFHts8GD48ENP8IMG1Vxz/t13vb5/zTVw662Zj19EGkYJvkDs\ntx/8+c/e+Zlpu+6aPMEfcIAn+JUrfYGzqiqfLbt8uY+SOfBAP69bN3jgAe9IjW/BL1rkm4y8+iqc\neSa8/z6MHx9b/2b2bC/viEh+qERTIPbf3xPo2Wdn/tqnn+5lmkSDBvn4+1tugZNO8jVrbrvN16vp\n3bvmubvv7iN92raNJfgXXvAEv+uu3sr/8ENfvnjOHO/QPekk+OMf4fDDM/87iUh6asEXiMGDfRu/\nUaMyf+1vfhMOOaT28ZYtfX2aG2/0csyQIV57P+642ud26ODlo65d/dvAxo2+WUmLFr4JyWGH+Xrz\nu+7q3wC+/NI/sNJNphKR7FELvkC0bes7OSVLxNn08597wh42DP71L++UPeus5Of27w/f+IZ/EHXs\nCC+/DHffXXNHqrIyL+8sXOj3leBF8kc7Osl/fPUVTJ/uG4Mks2aNt+BbtvTZt8kmUD34IDzzjJdn\nzj3Xk/+TT+YmfpFi1JgdnVSikf9o27bu5A6+lk10i8Dly73ln7gBSbREM28eHHVU41vw0QlgIrLj\nlOClQWbP9pmuicrKvDN28mS49FLfKrChX9y2b/cO2vvvb1ysIs2VErw0yD77+MSoRGVlPkHq5JO9\n87V9+5qTonbE0097Pf+FFxoXa7zx4+GOOzJ3PZFCphq8ZNXgwV6X33ffHX/uhRf6rN7HHvOx+tag\nKmRNo0b5jNy5c72cBD5pa+PG5HMFRPJNNXgpWL17ex09nRB83Ztosh02DP72Nx/G2bq1j7HPhKVL\n4ZRT4Ec/ih375S99Fq5IsdEwScmqXr289Z3OrFk+yapjR1+tct48Pz5kiLe6X3zRNylpjG3bPJbf\n/z620FqfPj6DuFs3fyx+JyyRpi5tgjez0cBvgZbAPSGESQmPdwUeBLpHrvfrEMJ9mQ9VmqL6JvjH\nHoPTToM77/RJVY8+6p21rVv7uvZTp/r4+2OPjZVWdtQHH3gi79jRZwzfcw+MGeOvt2CBL3m8YIF/\n6xg/3idvffGFD/kUaZJCCHX+w5P6IqAcaA3MAgYmnDMBmBi53RVYC7RKcq0gzc9dd4Vw7rkhzJkT\nwtFHh3DZZTUfX78+hB/9KIRddw1h5swQRo0KoV+/EKqrY+dUVYXQuXMIbduGMHlyw+KYPDkECKGk\nxO+/9VYIAwaEcOGFIUycGELv3v74Cy+EsGWL327TJoQOHUJYtKhhrymSCZHcmTJX1/UvXQ3+QGBR\nCGFpCGEr8DCQ2J5ZBXSM3O4IrA0haOSyAD7M8amnvMyy//5+O96MGXDzzd6yHjIErrsOfvKTmh2q\nXbv6pKk2bWpuNFJfW7bA5Zd7q/3EE/3Yfvv55ipTpsAZZ3j5p2XL2PaG0XMuvRQmToxtVSjSlKQr\n0fQC4nffXAEclHDO3cALZvYJ8DXg9MyFJ01d//5eW+/SxUstt93mybJTJ398zhz41rfgxz/2+yNH\nJr/OjTf6ImgPPJD+NTds8J/RDU7+8Q9P4PHj6Vu0gIsv9mGdffrAb3/rY/cXL4ZVqzy5v/aar7BZ\nWuozfKOrZCYKAd54w+MTKSTpEnx9xjVeA8wKIVSY2e7A82a2bwjhX4knTpgw4T+3KyoqqKio2IFQ\npak644zY7SFDfP34UaO8pX7HHTBpUvoO1BYtYK+90rfg1671Gv0hh8Bzz/nyC5Mm+YYlia67LnZ7\nr738G8aTT3qC79HDv0V06+Zj8VMN8/zgAxgxwl87U/vpSvNVWVlJZWVlRq6VLsGvBMri7pfhrfh4\nBwO/BAghLDazj4D+wNuJF4tP8NI8jRnjyxMfdJAvdAY+Vr4+9tjDh1zGfwOIt3atj7bZYw8v/Wzb\n5q32li3hBz+o3/U//DCW4KN69YJ//9uHb3bsWPt5U6f6z1degbFj6/e7iNQlsfH705/+tMHXSleD\nfxvoZ2blZtYGOAOYmnDOfOAoADMrxZO7dueUpP73f30p4cGDoaTEW/BDh9bvuW3aeAKta+mCa66B\nc87xNXDKyrz8M22a1++ja+ikMmSIt9bfeqtmgjfz9e2XLvXXDsGXQq6u9uUU/vQn/0by8sv1+z1E\nciVlgo90ll4MPAvMBf4cQphnZheY2QWR064HhpnZbGA6cEUIYV02g5amq21bL51s2eKJ/oILfPhj\nfV10Edx+uyfXr77y1nbUzJk+rHG//bxEM326t+iPPbZ+127TxodE3ntvzQQPnuD/+U//AJkxw5dq\nuPlmXz65pASuvhrervWdtaaqKv/QEcmVtP9rhRCmAdMSjt0Zd/sz4MTMhybFygwOPdTHnO/o8gOH\nHuofEs884x2zW7Z4DXz7dv954YVQUeFj27/73dg3hfq66ip4/HGvyccrL/cRN+DfCLp1gyuv9K0K\n777bSzjRNfDrMnmy77v717/uyG8s0nCaySp5ccQRO9ZyjzKDyy7zJQyGDfN9YI85xkfrlJbGFhLr\n0sVr8N/73o5df889Y6Nw4h1wgH9zaNfO6/RPPukdt9df78m+utqHXX7xhc/ETeatt7y0I5IrWmxM\n8mLbNm/1duiw48/dvt03ErnuOl9mYP587yAtK4P4fvzXX/eRMW3aND7e6movz3Tr5iWczz6DzZtr\nxr/33vDQQ3WPuCkv947adXEFzF/9yj/sDkocfCwS0ZjFxtSCl7xo1aphyR28wzS6hPBBB/n9nXaq\nfd6IEQ2PL1GLFr6B+Cef+IdJy5a1499jDy/TJEvwq1f7N4MtWzzJb97s4/N/9jOfyFXXGHuRxtBq\nktKk7bxz8uSeLT17ep0/mYEDvR8gmaee8s7e8nI/5yc/gW9/2zuZP/kEtm7NWsjSjCnBi2TI8OFe\nFkoUAjzyCHzzm76x+cEH+3DLZ5/1juLS0votyCayo1SiEcmQESN85M727TXH3U+a5CWa44+PjRra\nZRfvRwDfwHzZMm/di2SSErxIhnTr5q3xd96BAw+EK67wzthXX/V6e/v2cOqptZ+3225egz/iiJyH\nLEVOJRqRDDrnHB+quWGDD6v88kufINW7d93PKS/X8EnJDrXgRTLo+9/3SVIdOnhN/uGH0z+nd2+f\nhSuSaWrBi2TQ17/uM1UfeyxWY0+nU6fkk6tEGksteJEMGz4cliyp/0zdXXZRgpfsUIIXyYJ27ep/\nrhK8ZItKNCJ5pgQv2aIEL5JnnTppz1fJDiV4kTzb0Rb8+vX6QJD6UYIXybMOHXxlzfquR3PJJb4K\npUg6SvAieWbme71u3Jj+3A0b4C9/Sb+5iAgowYsUhPix8CH4rlLbt8ceX7fONxq59FIYMAAWLcpP\nnNK0KMGLFIBddonV1R95xNesufPO2OO//rUn9qoqmDrVE7z2z5F0lOBFCkB8R+s99/i2hHffHXv8\n00894T/9tC9tsNNOfkwkFSV4kQIQn+BXrPBlDqqqYo+vWQPdu8fu9+8P776b2xil6VGCFykA8TX4\nlSt927+qqlgZZvVqX4o46jvfqVnCEUlGCV6kAERb8Bs3+gbf3btD69awaZM/ntiCP+ssmD5dM2Al\nNSV4kQIQ7WRduRJ69fKhk127+oYhIXiCj2/B77wzDBuWfItAkSgleJECEG3Br1jhCR48wVdVeeJv\n16725uKHHeabiYjURQlepABEa/ArV8Z2f4q24BNb71HDh8Nbb+U2TmlalOBFCkC0Bb9qFfTo4cdK\nSjzBr1pVs/4eVVbmj8X70Y+8Q1YElOBFCkI0wVdV+ebdEGvBf/yxJ/NE3bvXTObV1XDXXT7jVQTq\nkeDNbLSZzTezhWZ2ZZLHLzezmZF/c8xsm5l1yk64IsUp2sn66afecgf/uXp13Qn+61/350QXKVu6\n1Df5Xrs2Z2FLgUuZ4M2sJXAbMBoYBIwzs4Hx54QQfh1CGBpCGApcDVSGELSYqcgOiNbgq6piCX6f\nfWDWrLoTfMuWfu748d7SnzPHjyvBS1S6FvyBwKIQwtIQwlbgYeCkFOd/C5iSqeBEmov4Ek00wR94\noHeiLluWPMGDl2kmToTXXoP33/djSvASlS7B9wI+jru/InKsFjNrDxwLPJ6Z0ESaj2Q1+G7dvGX/\n/POpEzz48sEzZ8LgwUrwEpNu0+0dWa/uROCVVOWZCRMm/Od2RUUFFRUVO3B5keLVrh1s2+bj4KMt\neICzz4af/azuBN+jh5dqFi3y1v6ZZ9Zcw0aansrKSiorKzNyLQsp1hw1s+HAhBDC6Mj9q4HqEMKk\nJOc+Afw5hPBwHdcKqV5LpLkrLfVO1vj/TUKAF1+EUaOSP+fBB+GVV3xG67JlMHky3H8/PPlkbmKW\n7DMzQgjWkOemK9G8DfQzs3IzawOcAUxNEsAuwOGA/qxEGujEE2sfM6s7uYOvSXPFFfDeezBihA+t\nXLTIyzUiKUs0IYRtZnYx8CzQErg3hDDPzC6IPB5dz+5k4NkQwuasRitSxG64wWen7qjddoObboJv\nf9u/AcydC9/7npYTljQlmoy+kEo0IlkXXXVy5529ZPP1r+c7ImmsbJZoRKQJKS2FBQvg8MMhQ/10\n0oQpwYsUmX794IgjvPO1OXnkkeb3O6ejBC9ShA4+GKZNg5/8JN+R5M6UKb4JSry1a2MTwJojJXiR\nIjRsmC869vOfw5Yt+Y4mNxYvhk8+qXnsiSfgm9/0hdiaIyV4kSLUrp1PkGrTxhchK3YhwJIlvp5+\nvHXrvE/i2WfzE1e+KcGLFKkf/xgqKnxcfDGrrobbb4cvvvAEH78Jyrp1MGAA3HJL/uLLJyV4kSK2\nxx7Fn+CXLIGLL/bbs2f7Im1R69fDBRfAm282z41QlOBFiljfvnDppT7CpFgtXgxf+xr84Q+xY9Ga\n+/r1Pi+grMzr89G185sLJXiRInbKKT7D9c9/znck2bNoEYwbB+ecAz17+rFNm/zn+vXQubP/+93v\n4Ic/zFuYeaEEL1LE+vaF3/wG/vGP4m29Ll4Mu+/utydNiu2OBTUT/Hvv+b94K1b4NofFSglepMiV\nlvo68X/5S74jyY7Fi72vAXzxtd69fW19qJngFyzwoaPxK6Z84xteoy/WVVSU4EWagSuvhBtvzO1r\nhuCdm9n20UfQp0/sfnTzFPBRNJ07Q5cuXraJbqoCvv7+7NnQoYMv0laMlOBFmoExY2D5cl+AbMUK\nr1dn28KFcNRR2W8dr17tG59ERUs01dWwcaPvitW5sz9m5q148E7XkhIYMsRX4CxGSvAizUDLljB6\nNDz9tHc23n9/9l9z2TL417+8TBKvqgq+//3MvMa2bX79rl1jx6IbmL/9trfOW7WKJfihQ73VHo1v\n111h0KDMJ/glS+DLLzN7zYZQghdpJk49Fe65Bx57zO9nOwEtX+4/E2fSzp/vO1FlomX/2WeevFvF\n7WwRLdF84xu+TAHEEvzJJ8cWJFu+3NfS33vvWNLPhCef9E7f++7L3DUbSglepJk44QRvyY8Y4Ylt\n1arsvl5dCf6TT2DzZl+7vrHWrPFO5HidOnnZpqoK7r7bj0UT/CmnwD//6R8u0Rb8iBG+5WGmvPAC\ndOxYe9nCew4+AAAOY0lEQVSEfFCCF2kmWrTw4ZL33Qe9etVemCvTli/3RJeY4KMfLIsXp7/GM894\nR2ldkiX4XXaBOXN8NE3Lln6sSxdo3x722iu2ufmyZf5Bt+++HmN0aGWi117zn9FlD9INN33rLRg7\nNvvvb30owYs0Ix07ejmjZ8/cJPhDD03eggevU6dz7bXw0kt1P756dfIEP2tWzZE1PXpAebl3sg4c\n6EMm338f9twTWrf2Vvwpp9RO3u+8A4cc4sl96lTvoE1Vr4+OzDnhhOx/Q6oPJXiRZqhnz+wnoEWL\nfLGzZC34srLUCX7uXPjOd/ycVB9E0S0K45WU+GuWl8eOlZXFNiLv188/AGbN8sQOvpTDvHm135Pf\n/95/zpvnfRedO6fe63bWLH/d/v097tdfr7mEQq4pwYs0Qz17ehLN1hDGqirv6DzyyOQt+EMP9WGU\ndXn5ZU+6GzemT/CJLfjjjvOfiWvAt2njP/fcEx54wEszO+/sxzp18rJVfL/Atm3eYXrUUfDGGx7T\npZd6q74uL73ku2lFvyE98QR8/HHd52ebErxIMzRmjCess87ykSiZ9tZbvulI376e4KMfJBs2+MSk\nI4/0VnFdZs+ObVSyowm+fXsfDnrllcmf06+fX/+kk2oe79695oqTb77pdfyjjoLrr/fEfcgh8MEH\ndccTTfBdu/qH07PP+reYfFGCF2mG9tnHSw2tWsGxx2b++m++6cv2durknbvRsfD//d+eYMeO9eGS\nde20NGuWd4x26LDjCR68Fd+/f/Ln7LOP/7zkkprHS0trtuBffBGOPto7Zteuhcsv94SfanTMG2/4\ndoktWvgInXnzai5fnGtK8CLNVPv2vhFGqlJJQ735JhxwgN8uL4+VaRYt8o7TkhKvZy9bVvu5X33l\nHaBnnQWHHeYJ/m9/g5Eja9ft60rwqfTt698o2reveTyxBb9ggU+COu44H3UTX3pZv95vx39LWLPG\nO2l79/b7zz0Hf/877LTTjsWXSUrwIs3YLrt4rXny5MxtDBKCl2iiLdfyci/LgLd+owlw0KDkZZrn\nn/cZp5MmwZ13ekK96SaYMaP2BtoNSfB1SWzBL1niE5ZatPD6PPi68+DDN3fdFe6910s2v/iFl332\n2cdH6oB/kIwalZnYGkoJXqQZM/OW6BVX+CzXTFi61Ds0o0lxr7285FJd7aNUomu2l5UlL3c8+qjP\nut1pJ/8waN/evxGMHVuzv2D7di+dlJRkJu7u3f3bTLSctHixJ+l4Zv57TZkCxx/vSy6MGePbIz74\nYKz8UyiU4EWauZ49PVE+9VTDr7F5s4/K2bDBNxiJ71isqIDKSh9Z07FjrGRRUhJb2TFq40Yfb376\n6X7fzEfTXH65t5jjE/xnn3mNv3Xrhscdr7TUO0XPPdeXcVi3LvYhFa9nT+/EPfxwuOoq/8YyYoQn\n+COPzEwsmaIEL9LM9ewZW6Drvfe8Bp7K1KkwbVrNY/fe68MOTz3Vrzd5cuyxgw/2MegLF8bKMxBL\n8CtWxEo1jzziHwjxY9tHjIAJE3xkSnyCz2R5JhrnU0/Bq6/C9OleWmqRJENGP5QOPdQ/sJYs8W8d\njz9ee2ROvinBizRzPXv6FPxzz/UkfdZZqc9//HGvjcd77jlPwtu3+8+2bWOP7byzly4ee6xmizia\n4G+6yZ8Tvfa3vpX8dRMTfLJZrI3Rpo3PQP32t328e12jX4YN8xijyyC0bu2/1ymnZC6WTEmb4M1s\ntJnNN7OFZpZ0ZKmZVZjZTDN738wqMx6liGRN794+ff8HP/ChhelWmVy0yIcQbtvm97/6ysd/X3CB\nL7S19961n1NR4UsUDxwYOxZN8C+84Ev7btjgrefRo5O/bteuft7tt/v9d9/NTs37tNO8H2HcuOSP\n33cfPPRQ5l83G1ImeDNrCdwGjAYGAePMbGDCOZ2A3wMnhhD2Bk7NUqwikgXnn+8jVnr29M7DFStq\nn/P++7EldRcu9Fb5jBne+Xnddd7ajV+TPVFFhS/mdf75sWMlJT4W/qOPPNFfeKEv8RsdqZKoa1df\nRCw69f/ll30YZaaNGAE//alPcGrqLKSYq2xmI4DxIYTRkftXAYQQbog754dA9xDCT1K+kFlI9Voi\nkn9r1/rQwMSVFS+/3Kfc33WXfxBce62PYX//fV9t8S9/SV2i+Oorr92fdlrs2LJlXuc+7jiv/a9d\n60MiO3VKfo0FC/wbRu/e3sL++tf9wyZTo2gKlZkRQrCGPDddiaYXEL+SworIsXj9gC5m9qKZvW1m\n32lIICKSf126eOkluqdp1Jo1PsIkmnzPPts7Fpcu9QR/8smpr9u2bc3kDrHEPGqUzwCNjoqpS/Qb\nwpo1Xibq3Ln4k3tjpUvw9Wlytwb2A44DjgV+bGb9GhuYiOSema+RnjjDdPVq37T6Bz/wjtDevb0s\ns2kTHHRQbHLPjmjf3ks9I0f6t4LEmaWJOnXyYYnt2/umHYMH7/hrNjet0jy+EiiLu1+Gt+LjfQx8\nFkLYDGw2s5eBfYFaE6AnRLvKgYqKCiryuQqPiCTVr58Pa4zvwIy24EeOjA0dPP98H0mSbChhfUVn\nrdZHixYwcaKv0PiPfyTvzC0GlZWVVFZWZuRa6WrwrYAPgSOBT4A3gXEhhHlx5wzAO2KPBdoCbwBn\nhBDmJlxLNXiRJmDqVPjZz7xsYuaJtbTUO1kT116vrm5cgm+II47wSVW33FL3kMpikrUafAhhG3Ax\n8CwwF/hzCGGemV1gZhdEzpkP/B14D0/udycmdxFpOk44wUsyZ5/tE5e2bfNZnclGyeQ6uYOXaj77\nzEtDklrKFnxGX0gteJEm47zzfDhi164+YmbixMxskp0Je+/tC3w1l3TSmBZ8uhq8iDRDRx3lpZqp\nU30Kf7t2+Y4o5vHHY7NIJTUleBGp5eSTfaPqESN8obB8bjuXqK6NPKQ2lWhERApYNic6iYhIE6UE\nLyJSpJTgRUSKlBK8iEiRUoIXESlSSvAiIkVKCV5EpEgpwYuIFCkleBGRIqUELyJSpJTgRUSKlBK8\niEiRUoIXESlSSvAiIkVKCV5EpEgpwYuIFCkleBGRIqUELyJSpJTgRUSKlBK8iEiRUoIXESlSSvAi\nIkVKCV5EpEgpwYuIFCkleBGRIpU2wZvZaDObb2YLzezKJI9XmNkGM5sZ+XdddkIVEZEdkTLBm1lL\n4DZgNDAIGGdmA5Oc+lIIYWjk3y+yEGdWVFZW5juEWgoxJijMuBRT/Sim+ivUuBoqXQv+QGBRCGFp\nCGEr8DBwUpLzLOOR5UAh/scsxJigMONSTPWjmOqvUONqqHQJvhfwcdz9FZFj8QJwsJnNNrNnzGxQ\nJgMUEZGGaZXm8VCPa7wLlIUQvjSzMcBfgT0bHZmIiDSKhVB3Djez4cCEEMLoyP2rgeoQwqQUz/kI\n2D+EsC7heH0+LEREJEEIoUFl8HQt+LeBfmZWDnwCnAGMiz/BzEqBT0MIwcwOxD801iVeqKEBiohI\nw6RM8CGEbWZ2MfAs0BK4N4Qwz8wuiDx+J3Aq8AMz2wZ8CZyZ5ZhFRKQeUpZoRESk6cr6TNZ0E6Vy\nycyWmtl7kQlZb0aOdTGz581sgZk9Z2adshzDZDNbY2Zz4o7VGYOZXR157+ab2TE5jGmCma2Im8A2\nJscxlZnZi2b2gZm9b2b/HTmet/cqRUx5e6/MbCcze8PMZpnZXDObGDme77+puuLK699V5HVaRl77\nqcj9vL5XdcSUmfcphJC1f3hZZxFQDrQGZgEDs/maaeL5COiScOxXwBWR21cCN2Q5hsOAocCcdDHg\nk8tmRd678sh72SJHMY0HLktybq5i6g4MidzuAHwIDMzne5Uipny/V+0jP1sBM4BD8/03lSKuvL5X\nkde6DHgImBq5XwjvVWJMGXmfst2Cr+9EqVxK7OwdC9wfuX0/cHI2XzyE8E9gfT1jOAmYEkLYGkJY\niv/HPDBHMUHyCWy5iml1CGFW5PYmYB4+ByNv71WKmCC/79WXkZtt8EbVevL8N5UiLsjje2VmvYHj\ngHvi4sjre1VHTEYG3qdsJ/j6TJTKpQBMN7O3zez8yLHSEMKayO01QGke4qorhp74exaV6/fvEvMJ\nbPfGfW3NeUzmo7iGAm9QIO9VXEwzIofy9l6ZWQszm4W/Hy+GED6gAN6nOuKC/P5d3Qz8P6A67li+\n36tkMQUy8D5lO8EXWg/uISGEocAY4CIzOyz+weDfgfIacz1iyFV8dwB9gCHAKuA3Kc7NWkxm1gF4\nHLg0hPCvGi+ap/cqEtNjkZg2kef3KoRQHUIYAvQGDjezkQmP5+V9ShJXBXl8r8zsBHxI90zqWF4l\n1+9Vipgy8j5lO8GvBMri7pdR89Mnp0IIqyI/q4An8K82a8ysO4CZ9QA+zUNodcWQ+P71jhzLuhDC\npyEC/+oY/RqYs5jMrDWe3B8IIfw1cjiv71VcTA9GYyqE9yoSxwbgaWB/CuhvKi6uYXl+rw4GxppP\nxpwCjDKzB8jve5Uspj9m7H3KRodBXIdAK2Ax3hnQhjx2sgLtga9Fbu8MvAocg3ewXBk5fhVZ7mSN\nvE45tTtZa8VArEOlDf5pvpjI0NYcxNQj7vaPgD/lMia8NfNH4OaE43l7r1LElLf3CugKdIrcbge8\nDByZ77+pFHF1z+ffVdxrHwE8le+/qRQxZeRvKiuBJgQ9Bh9tsAi4OtuvlyKOPpE3ZhbwfjQWoAsw\nHVgAPBf9o8xiHFPwWcFb8P6Jc1PFAFwTee/mA8fmKKbzIonsPWA2vr5QaY5jOhSvSc4CZkb+jc7n\ne1VHTGPy+V4Bg/H1oGZFYvh/6f6uc/Tfr6648vp3FfdaRxAbsZLX9yrutSriYnogE++TJjqJiBQp\nbdknIlKklOBFRIqUEryISJFSghcRKVJK8CIiRUoJXkSkSCnBi4gUKSV4EZEi9f8BHDqCwNx2Tj0A\nAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1121dc550>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#test results :(\n",
"predict = y\n",
"p = sess.run(predict, feed_dict={x: test_ins})\n",
"position = 2*((p>0)-.5)\n",
"returns= position.reshape(-1) * test_outs\n",
"plot(np.cumprod(returns+1))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.4.4"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
================================================
FILE: notebooks/.ipynb_checkpoints/TF-FIN-2-multistock_regresion-checkpoint.ipynb
================================================
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline\n",
"import matplotlib.pyplot as plt\n",
"import tensorflow as tf\n",
"import numpy as np\n",
"import numpy.random as rng\n",
"import pandas.io.data as web\n",
"import numpy as np\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# we modify this data organizing slightly to get two symbols\n",
"def get_prices(symbol):\n",
" start, end = '2007-05-02', '2016-04-11'\n",
" data = web.DataReader(symbol, 'yahoo', start, end)\n",
" data=pd.DataFrame(data)\n",
" prices=data['Adj Close']\n",
" prices=prices.astype(float)\n",
" return prices\n",
"\n",
"def get_returns(prices):\n",
" return ((prices-prices.shift(-1))/prices)[:-1]\n",
" \n",
"def get_data(list):\n",
" l = []\n",
" for symbol in list:\n",
" rets = get_returns(get_prices(symbol))\n",
" l.append(rets)\n",
" return np.array(l).T\n",
"\n",
"def sort_data(rets):\n",
" ins = []\n",
" outs = []\n",
" for i in range(len(rets)-100):\n",
" ins.append(rets[i:i+100].tolist())\n",
" outs.append(rets[i+100])\n",
" return np.array(ins), np.array(outs)\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"symbol_list = ['C', 'GS']\n",
"rets = get_data(symbol_list)\n",
"ins, outs = sort_data(rets)\n",
"ins = ins.transpose([0,2,1]).reshape([-1, len(symbol_list) * 100])\n",
"div = int(.8 * ins.shape[0])\n",
"train_ins, train_outs = ins[:div], outs[:div]\n",
"test_ins, test_outs = ins[div:], outs[div:]"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"sess = tf.InteractiveSession()"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# once again I only make slight modifications\n",
"\n",
"# define placeholders \n",
"x = tf.placeholder(tf.float32, [None, len(symbol_list) * 100])\n",
"y_ = tf.placeholder(tf.float32, [None, len(symbol_list)])\n",
"\n",
"# define trainable variables\n",
"W = tf.Variable(tf.random_normal([len(symbol_list) * 100, len(symbol_list)]))\n",
"b = tf.Variable(tf.random_normal([len(symbol_list)]))\n",
"\n",
"# we define our model: y = W*x + b\n",
"y = tf.matmul(x, W) + b\n",
"\n",
"#MSE:\n",
"cost = tf.reduce_sum(tf.pow(y-y_, 2))/(2*1000)\n",
"optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cost)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 1000 cost= 0.040910859\n",
"Epoch: 2000 cost= 0.020840863\n",
"Epoch: 3000 cost= 0.013389181\n",
"Epoch: 4000 cost= 0.009200850\n",
"Epoch: 5000 cost= 0.006651346\n",
"Epoch: 6000 cost= 0.005042211\n",
"Epoch: 7000 cost= 0.003999272\n",
"Epoch: 8000 cost= 0.003308342\n",
"Epoch: 9000 cost= 0.002842027\n",
"Epoch: 10000 cost= 0.002522263\n",
"Epoch: 11000 cost= 0.002299956\n",
"Epoch: 12000 cost= 0.002143553\n",
"Epoch: 13000 cost= 0.002032371\n",
"Epoch: 14000 cost= 0.001952614\n",
"Epoch: 15000 cost= 0.001894943\n",
"Epoch: 16000 cost= 0.001852949\n",
"Epoch: 17000 cost= 0.001822181\n",
"Epoch: 18000 cost= 0.001799512\n",
"Epoch: 19000 cost= 0.001782728\n",
"Epoch: 20000 cost= 0.001770250\n"
]
}
],
"source": [
"# initialize variables to random values\n",
"init = tf.initialize_all_variables()\n",
"sess.run(init)\n",
"# run optimizer on entire training data set many times\n",
"for epoch in range(20000):\n",
" sess.run(optimizer, feed_dict={x: train_ins, y_: train_outs})#.reshape(1,-1).T})\n",
" # every 1000 iterations record progress\n",
" if (epoch+1)%1000== 0:\n",
" c = sess.run(cost, feed_dict={x: train_ins, y_: train_outs})#.reshape(1,-1).T})\n",
" print(\"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c))"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1109e8860>]"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\nQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x110876eb8>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#train results\n",
"predict = y\n",
"p = sess.run(predict, feed_dict={x: train_ins})\n",
"position = 2*((p>0)-.5)\n",
"returns= position * train_outs\n",
"daily_returns = sum(returns,1)\n",
"plot(np.cumprod(daily_returns+1))"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x110b10e10>]"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1108f6a58>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#test results\n",
"predict = y\n",
"p = sess.run(predict, feed_dict={x: test_ins})\n",
"position = 2*((p>0)-.5)\n",
"returns= position * test_outs\n",
"daily_returns = sum(returns,1)\n",
"plot(np.cumprod(daily_returns+1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.4.4"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
================================================
FILE: notebooks/.ipynb_checkpoints/TF-FIN-3-regression_with_policy_training-checkpoint.ipynb
================================================
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline\n",
"import matplotlib.pyplot as plt\n",
"import tensorflow as tf\n",
"import numpy as np\n",
"import numpy.random as rng\n",
"import pandas.io.data as web\n",
"import numpy as np\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def get_prices(symbol):\n",
" start, end = '2007-05-02', '2016-04-11'\n",
" data = web.DataReader(symbol, 'yahoo', start, end)\n",
" data=pd.DataFrame(data)\n",
" prices=data['Adj Close']\n",
" prices=prices.astype(float)\n",
" return prices\n",
"\n",
"def get_returns(prices):\n",
" return ((prices-prices.shift(-1))/prices)[:-1]\n",
" \n",
"def get_data(list):\n",
" l = []\n",
" for symbol in list:\n",
" rets = get_returns(get_prices(symbol))\n",
" l.append(rets)\n",
" return np.array(l).T\n",
"\n",
"def sort_data(rets):\n",
" ins = []\n",
" outs = []\n",
" for i in range(len(rets)-100):\n",
" ins.append(rets[i:i+100].tolist())\n",
" outs.append(rets[i+100])\n",
" return np.array(ins), np.array(outs)\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"symbol_list = ['C', 'GS']\n",
"rets = get_data(symbol_list)\n",
"ins, outs = sort_data(rets)\n",
"ins = ins.transpose([0,2,1]).reshape([-1, len(symbol_list) * 100])\n",
"div = int(.8 * ins.shape[0])\n",
"train_ins, train_outs = ins[:div], outs[:div]\n",
"test_ins, test_outs = ins[div:], outs[div:]\n",
"\n",
"#normalize inputs (this is new but not specific to PG; you should always normalize inputs)\n",
"train_ins, test_ins = train_ins/np.std(ins), test_ins/np.std(ins)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"sess = tf.InteractiveSession()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"positions = tf.constant([-1,0,1]) #long, neutral or short\n",
"num_positions = 3\n",
"\n",
"x = tf.placeholder(tf.float32, [None, len(symbol_list) * 100])\n",
"y_ = tf.placeholder(tf.float32, [None, len(symbol_list)])\n",
"\n",
"W = tf.Variable(tf.random_normal([len(symbol_list) * 100, num_positions * len(symbol_list)]))\n",
"b = tf.Variable(tf.random_normal([num_positions * len(symbol_list)]))\n",
"\n",
"# we define our model: y = W*x + b\n",
"y = tf.matmul(x, W) + b # y is tensor of shape [num_inputs, num_positions * len(symbol_list)]\n",
"# a row of y will look like [prob_symbol_1_short, prob_symbol_1_neutral, prob_symbol_1_long, prob_symbol_2_short, ...]\n",
"# note that they are not really probabilities because I did not perform a softmax yet\n",
"\n",
"\n",
"# loop through symbols, taking the buckets for one symbol at a time\n",
"pos = {}\n",
"symbol_returns = {}\n",
"relevant_target_column = {}\n",
"for i in range(len(symbol_list)):\n",
" # ISOLATE the buckets relevant to the symbol and get a softmax as well\n",
" symbol_probs = y[:,i*num_positions:(i+1)*num_positions]\n",
" symbol_probs_softmax = tf.nn.softmax(symbol_probs) # softmax[i, j] = exp(logits[i, j]) / sum(exp(logits[i]))\n",
" # SAMPLE probability to chose our policy's action\n",
" sample = tf.multinomial(tf.log(symbol_probs_softmax), 1)\n",
" pos[i] = tf.reshape(sample, [-1]) - 1 # choose(-1,0,1)\n",
" # GET RETURNS by multiplying the policy (position taken) by the target return for that day\n",
" symbol_returns[i] = tf.mul(tf.cast(pos[i], float32), y_[:,i])\n",
" # isolate the output probability the selected policy (for use in calculating gradient)\n",
" # see https://github.com/tensorflow/tensorflow/issues/206 for TF discussion including my solution\n",
" sample_mask = tf.reshape(tf.one_hot(sample, 3), [-1,3])\n",
" relevant_target_column[i] = tf.reduce_sum(symbol_probs_softmax * sample_mask,1)\n",
" \n",
"\n",
"# calculate the PERFORMANCE METRICS for the data chosen\n",
"daily_returns_by_symbol = tf.concat(1, [tf.reshape(t, [-1,1]) for t in symbol_returns.values()]) \n",
"daily_returns = tf.reduce_sum(daily_returns_by_symbol,1)/2\n",
"total_return = tf.reduce_prod(daily_returns + 1)\n",
"ann_vol = tf.mul(\n",
" tf.sqrt(tf.reduce_mean(tf.pow((daily_returns - tf.reduce_mean(daily_returns)),2))) ,\n",
" np.sqrt(252)\n",
" )\n",
"sharpe = total_return / ann_vol\n",
"\n",
"# since we only train the sampled classes, we will combine them so that we can feed them into cross entropy\n",
"training_target_cols = tf.concat(1, [tf.reshape(t, [-1,1]) for t in relevant_target_column.values()])\n",
"# we want to either push the gradient toward our selection or away from it. We use these ones to find the direction\n",
"# of the gradient, which we will then multiply by our fitness function\n",
"ones = tf.ones_like(training_target_cols)\n",
"\n",
"# this isnt actually a gradient, but karpathy sort of calls it one. Since it's a tensor it sort of is a gradient anyway\n",
"gradient = tf.nn.sigmoid_cross_entropy_with_logits(training_target_cols, ones) ####should this be a prob???\n",
"\n",
"# COST\n",
"# how should we do this step? it depends how we want to group our results. Choose your own adventure here by uncommenting a cost fn\n",
"# this is the most obvious: we push each weight to what works or not. Try it out...we're gonna be RICH!!!! oh, wait...\n",
"#cost = tf.mul(gradient , daily_returns_by_symbol)\n",
"# this takes the overall daily return and pushes the weights so that the overall day wins. Again, it overfits enormously\n",
"cost = tf.mul(gradient , tf.reshape(daily_returns,[-1,1]))\n",
"# this multiplies every gradient by the overall return. If the strategy won for the past ten years, we do more of it and vice versa\n",
"#cost = tf.mul(gradient , total_return)\n",
"\n",
"# minimize the cost (push the weights where we want them to go)\n",
"optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(cost)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 1000 cost= 1409.337646484 total return= 1408.337646484\n",
"Epoch: 2000 cost= 10547.202148438 total return= 10546.202148438\n",
"Epoch: 3000 cost= 17355.996093750 total return= 17354.996093750\n",
"Epoch: 4000 cost= 32044.666015625 total return= 32043.666015625\n",
"Epoch: 5000 cost= 51317.105468750 total return= 51316.105468750\n"
]
}
],
"source": [
"init = tf.initialize_all_variables()\n",
"sess.run(init)\n",
"for epoch in range(5000):\n",
" sess.run(optimizer, feed_dict={x: train_ins, y_: train_outs})#.reshape(1,-1).T})\n",
" if (epoch+1)%1000== 0:\n",
" c,t = sess.run([cost, total_return], feed_dict={x: train_ins, y_: train_outs})#.reshape(1,-1).T})\n",
" print(\"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(t), \"total return=\", \"{:.9f}\".format(t-1))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# in sample results\n",
"d, t = sess.run([daily_returns, gradient], feed_dict={x: train_ins, y_: train_outs})"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x110839cf8>]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x110abbe48>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# equity curve\n",
"plot(np.cumprod(d+1))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"#out of sample results\n",
"d, t = sess.run([daily_returns, gradient], feed_dict={x: test_ins, y_: test_outs})"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x11061a940>]"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\nO3eagb2Aw3Ck7YbBpk66148DeDucNoG9oH8A+
gitextract__rjh3qrn/
├── .ipynb_checkpoints/
│ └── singlestock_regresion_(1)-checkpoint.ipynb
├── DataFlow_Suite/
│ ├── lstm_exec.py
│ ├── neural_net_exec.py
│ └── rets.pkl
├── LICENSE
├── README.md
└── notebooks/
├── .ipynb_checkpoints/
│ ├── TF-FIN-1-singlestock_regresion-checkpoint.ipynb
│ ├── TF-FIN-2-multistock_regresion-checkpoint.ipynb
│ ├── TF-FIN-3-regression_with_policy_training-checkpoint.ipynb
│ ├── TF-FIN-4-stochastic_gradient_descent-checkpoint.ipynb
│ ├── TF-FIN-5-multi_sampling-checkpoint.ipynb
│ ├── TF-FIN-6-neural_network-checkpoint.ipynb
│ ├── TF-FIN-7-regularization_modular-checkpoint.ipynb
│ ├── Untitled-checkpoint.ipynb
│ └── lstm_(7)-checkpoint.ipynb
├── TF-FIN-1-singlestock_regresion.ipynb
├── TF-FIN-2-multistock_regresion.ipynb
├── TF-FIN-3-regression_with_policy_training.ipynb
├── TF-FIN-4-stochastic_gradient_descent.ipynb
├── TF-FIN-5-multi_sampling.ipynb
├── TF-FIN-6-neural_network.ipynb
├── TF-FIN-7-regularization_modular.ipynb
├── lstm_(7).ipynb
├── policy_net-multisymbol_(july11).ipynb
└── test.pkl
SYMBOL INDEX (16 symbols across 2 files)
FILE: DataFlow_Suite/lstm_exec.py
function get_prices (line 9) | def get_prices(symbol):
function get_returns (line 17) | def get_returns(prices):
function get_data (line 20) | def get_data(list):
function lstm_iterator (line 30) | def lstm_iterator(raw_data, num_steps, data_size):
class LSTMModel (line 55) | class LSTMModel(object):
method __init__ (line 56) | def __init__(self, num_steps, num_samples):#, config):
function run_train_results (line 175) | def run_train_results(m, epoch):
function run_test_results (line 187) | def run_test_results(m, epoch):
function run_epoch (line 200) | def run_epoch(m, epoch):
FILE: DataFlow_Suite/neural_net_exec.py
function get_prices (line 11) | def get_prices(symbol):
function get_returns (line 19) | def get_returns(prices):
function get_data (line 22) | def get_data(list):
function sort_data (line 29) | def sort_data(rets):
function data_loader_1 (line 39) | def data_loader_1(symbol_list):
function multilayer_perceptron (line 86) | def multilayer_perceptron(x, weights, biases):
function run_training_and_return_test_results (line 161) | def run_training_and_return_test_results():
Condensed preview — 25 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,640K chars).
[
{
"path": ".ipynb_checkpoints/singlestock_regresion_(1)-checkpoint.ipynb",
"chars": 37817,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "DataFlow_Suite/lstm_exec.py",
"chars": 8816,
"preview": "import tensorflow as tf\nimport numpy as np\nimport numpy.random as rng\nimport pandas.io.data as web\nimport numpy as np\nim"
},
{
"path": "DataFlow_Suite/neural_net_exec.py",
"chars": 7575,
"preview": "#import matplotlib.pyplot as plt\nimport tensorflow as tf\nimport numpy as np\nimport numpy.random as rng\nimport pandas.io."
},
{
"path": "LICENSE",
"chars": 1078,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2016 LiamConnell\n\nPermission is hereby granted, free of charge, to any person obtai"
},
{
"path": "README.md",
"chars": 22413,
"preview": "# A tour through tensorflow with financial data\n\nI present several models ranging in complexity from simple regression t"
},
{
"path": "notebooks/.ipynb_checkpoints/TF-FIN-1-singlestock_regresion-checkpoint.ipynb",
"chars": 37222,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/.ipynb_checkpoints/TF-FIN-2-multistock_regresion-checkpoint.ipynb",
"chars": 43109,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 3,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/.ipynb_checkpoints/TF-FIN-3-regression_with_policy_training-checkpoint.ipynb",
"chars": 41925,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/.ipynb_checkpoints/TF-FIN-4-stochastic_gradient_descent-checkpoint.ipynb",
"chars": 46898,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/.ipynb_checkpoints/TF-FIN-5-multi_sampling-checkpoint.ipynb",
"chars": 75761,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/.ipynb_checkpoints/TF-FIN-6-neural_network-checkpoint.ipynb",
"chars": 113169,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/.ipynb_checkpoints/TF-FIN-7-regularization_modular-checkpoint.ipynb",
"chars": 154496,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/.ipynb_checkpoints/Untitled-checkpoint.ipynb",
"chars": 72,
"preview": "{\n \"cells\": [],\n \"metadata\": {},\n \"nbformat\": 4,\n \"nbformat_minor\": 0\n}\n"
},
{
"path": "notebooks/.ipynb_checkpoints/lstm_(7)-checkpoint.ipynb",
"chars": 106314,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/TF-FIN-1-singlestock_regresion.ipynb",
"chars": 42496,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
},
{
"path": "notebooks/TF-FIN-2-multistock_regresion.ipynb",
"chars": 40366,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
},
{
"path": "notebooks/TF-FIN-3-regression_with_policy_training.ipynb",
"chars": 45354,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
},
{
"path": "notebooks/TF-FIN-4-stochastic_gradient_descent.ipynb",
"chars": 46332,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
},
{
"path": "notebooks/TF-FIN-5-multi_sampling.ipynb",
"chars": 87892,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
},
{
"path": "notebooks/TF-FIN-6-neural_network.ipynb",
"chars": 116999,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
},
{
"path": "notebooks/TF-FIN-7-regularization_modular.ipynb",
"chars": 159140,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
},
{
"path": "notebooks/lstm_(7).ipynb",
"chars": 104220,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
},
{
"path": "notebooks/policy_net-multisymbol_(july11).ipynb",
"chars": 255545,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {\n \"collapsed\": false\n },\n \"out"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the LiamConnell/deep-algotrading GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 25 files (1.5 MB), approximately 974.4k tokens, and a symbol index with 16 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.