Closed windowshopr closed 5 years ago
@windowshopr thanks for filing this issue. I just executed the code once again, which is working fine. I've uploaded the updated codes (mostly tested on TensorFlow 1.8 about 3 months ago, though) as Notebook in each chapter.
But you're right sometimes Yahoo-finance doesn't work. However, I don't have have any workaround here because I'm pretty overloaded at the moment.
Please try running the corresponding Notebook file and let me know it went.
Thanks for the suggestion! This repository was the first one I came across in the Packt Publishing suite haha. I will give the notebook a shot and if there are any issues, I will report back. Maybe this weekend when I get some time, I'll see if I can tweak the existing code to pull the historical data from another source and make a pull request, so that both options could be available.
Thanks!
@rezacsedu The notebook worked great. I've made some modifications to convert the .npy to a .csv file and using that for the simulations, but not before running a wavelet transform to denoise the stock data (although probably not super applicable here, it is a feature that I'll want to use in future use). I will also be updating where the historical data is sourced from someday.
I've attached my edited code below here just for reference. One question I did have, could you explain the (avg, std) that gets printed at the end? Is the avg the average ending portfolio size out of all 100 simulations, and what would the std deviation depict? Just a newbie question. Thanks!
import warnings
warnings.filterwarnings("ignore")
from yahoo_finance import Share
from matplotlib import pyplot as plt
import numpy as np
import random
import tensorflow as tf
import random
import pywt
from numpy import genfromtxt
class DecisionPolicy:
def select_action(self, current_state, step):
pass
def update_q(self, state, action, reward, next_state):
pass
class RandomDecisionPolicy(DecisionPolicy):
def __init__(self, actions):
self.actions = actions
def select_action(self, current_state, step):
action = self.actions[random.randint(0, len(self.actions) - 1)]
return action
class QLearningDecisionPolicy(DecisionPolicy):
def __init__(self, actions, input_dim):
self.epsilon = 0.5
self.gamma = 0.001
self.actions = actions
output_dim = len(actions)
h1_dim = 200
self.x = tf.placeholder(tf.float32, [None, input_dim])
self.y = tf.placeholder(tf.float32, [output_dim])
W1 = tf.Variable(tf.random_normal([input_dim, h1_dim]))
b1 = tf.Variable(tf.constant(0.1, shape=[h1_dim]))
h1 = tf.nn.relu(tf.matmul(self.x, W1) + b1)
W2 = tf.Variable(tf.random_normal([h1_dim, output_dim]))
b2 = tf.Variable(tf.constant(0.1, shape=[output_dim]))
self.q = tf.nn.relu(tf.matmul(h1, W2) + b2)
loss = tf.square(self.y - self.q)
self.train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
self.sess = tf.Session()
self.sess.run(tf.initialize_all_variables())
def select_action(self, current_state, step):
threshold = min(self.epsilon, step / 1000.)
if random.random() < threshold:
# Exploit best option with probability epsilon
action_q_vals = self.sess.run(self.q, feed_dict={self.x: current_state})
action_idx = np.argmax(action_q_vals) # TODO: replace w/ tensorflow's argmax
action = self.actions[action_idx]
else:
# Explore random option with probability 1 - epsilon
action = self.actions[random.randint(0, len(self.actions) - 1)]
return action
def update_q(self, state, action, reward, next_state):
action_q_vals = self.sess.run(self.q, feed_dict={self.x: state})
next_action_q_vals = self.sess.run(self.q, feed_dict={self.x: next_state})
next_action_idx = np.argmax(next_action_q_vals)
action_q_vals[0, next_action_idx] = reward + self.gamma * next_action_q_vals[0, next_action_idx]
action_q_vals = np.squeeze(np.asarray(action_q_vals))
self.sess.run(self.train_op, feed_dict={self.x: state, self.y: action_q_vals})
def run_simulation(policy, initial_budget, initial_num_stocks, my_data, hist, debug=False):
budget = initial_budget
num_stocks = initial_num_stocks
share_value = 0
transitions = list()
for i in range(len(my_data) - hist - 1):
if i % 100 == 0:
print('progress {:.2f}%'.format(float(100*i) / (len(my_data) - hist - 1)))
current_state = np.asmatrix(np.hstack((my_data[i:i+hist], budget, num_stocks)))
current_portfolio = budget + num_stocks * share_value
action = policy.select_action(current_state, i)
share_value = float(my_data[i + hist + 1])
if action == 'Buy' and budget >= share_value:
budget -= share_value
num_stocks += 1
elif action == 'Sell' and num_stocks > 0:
budget += share_value
num_stocks -= 1
else:
action = 'Hold'
new_portfolio = budget + num_stocks * share_value
reward = new_portfolio - current_portfolio
next_state = np.asmatrix(np.hstack((my_data[i+1:i+hist+1], budget, num_stocks)))
transitions.append((current_state, action, reward, next_state))
policy.update_q(current_state, action, reward, next_state)
portfolio = budget + num_stocks * share_value
if debug:
print('${}\t{} shares'.format(budget, num_stocks))
return portfolio
def run_simulations(policy, budget, num_stocks, my_data, hist):
num_tries = 100
final_portfolios = list()
for i in range(num_tries):
final_portfolio = run_simulation(policy, budget, num_stocks, my_data, hist)
final_portfolios.append(final_portfolio)
avg, std = np.mean(final_portfolios), np.std(final_portfolios)
return avg, std
def get_prices(share_symbol, start_date, end_date, cache_filename):
try:
stock_prices = np.load(cache_filename)
except IOError:
share = Share(share_symbol)
stock_hist = share.get_historical(start_date, end_date)
stock_prices = [stock_price['Open'] for stock_price in stock_hist]
np.save(cache_filename, stock_prices)
return stock_prices
def plot_prices(my_data):
plt.title('Opening stock prices')
plt.xlabel('day')
plt.ylabel('price ($)')
plt.plot(my_data)
plt.savefig('my_data.png')
if __name__ == '__main__':
prices = get_prices('MSFT', '2000-07-01', '2017-07-01', r'C:\Users\windowshopr\Desktop\Python Scripts\Stock Market Prediction\Predictive Analytics with TensorFlow\Chapter11\resource\stock_prices.npy')
# Perform wavelet transform to preprocess stock data
x = np.array(prices)
(ca, cd) = pywt.dwt(x, "haar")
cat = pywt.threshold(ca, np.std(ca), mode="soft")
cdt = pywt.threshold(cd, np.std(cd), mode="soft")
tx = pywt.idwt(cat, cdt, "haar")
# Save data as .csv file to use for simulation
np.savetxt('stock_prices.csv', tx, delimiter=",", fmt="%s")
my_data = genfromtxt('stock_prices.csv', delimiter=',')
plot_prices(my_data)
actions = ['Buy', 'Sell', 'Hold']
hist = 200
policy = RandomDecisionPolicy(actions)
budget = 1000.0
num_stocks = 0
avg, std = run_simulations(policy, budget, num_stocks, my_data, hist)
print(avg, std)
Wondering if your code will be updated to a new historical data gathering tool as yahoo-finance doesn't work anymore? Maybe iexfinance or Alpha Vantage. And could the predictive model use .csv files instead of .npy? Thanks! Great work!