├── trading_bot ├── __init__.py ├── ops.py ├── utils.py ├── methods.py └── agent.py ├── extra └── visualization.png ├── models ├── model_dqn_GOOG_50 ├── model_t-dqn_GOOG_10 └── model_double-dqn_GOOG_50 ├── requirements.txt ├── pyproject.toml ├── LICENSE ├── .gitignore ├── eval.py ├── train.py ├── README.md ├── data ├── AAPL_2018.csv ├── GOOG_2018.csv └── GOOG_2019.csv └── visualize.ipynb /trading_bot/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extra/visualization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pskrunner14/trading-bot/HEAD/extra/visualization.png -------------------------------------------------------------------------------- /models/model_dqn_GOOG_50: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pskrunner14/trading-bot/HEAD/models/model_dqn_GOOG_50 -------------------------------------------------------------------------------- /models/model_t-dqn_GOOG_10: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pskrunner14/trading-bot/HEAD/models/model_t-dqn_GOOG_10 -------------------------------------------------------------------------------- /models/model_double-dqn_GOOG_50: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pskrunner14/trading-bot/HEAD/models/model_double-dqn_GOOG_50 -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | keras==2.3.1 2 | tensorflow==1.14.0 3 | pandas==0.24.2 4 | numpy==1.16.1 5 | tqdm==4.24.0 6 | docopt==0.6.2 7 | coloredlogs==10.0 8 | jupyterlab==1.0.1 9 | altair==4.0.0 10 | seaborn==0.9.0 11 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "trading_bot" 3 | version = "0.0.1" 4 | description = "Automated Stock Trading via Deep Q-Learning" 5 | authors = [] 6 | 7 | [tool.poetry.dependencies] 8 | python = "~3.6" 9 | keras = "2.3.1" 10 | tensorflow = "1.14.0" 11 | pandas = "^0.24.2" 12 | numpy = "^1.16.1" 13 | tqdm = "^4.24.0" 14 | docopt = "^0.6.2" 15 | coloredlogs = "^10.0" 16 | jupyterlab = "^1.0.1" 17 | altair = "^4.0.0" 18 | seaborn = "^0.9.0" 19 | -------------------------------------------------------------------------------- /trading_bot/ops.py: -------------------------------------------------------------------------------- 1 | import os 2 | import math 3 | import logging 4 | 5 | import numpy as np 6 | 7 | 8 | def sigmoid(x): 9 | """Performs sigmoid operation 10 | """ 11 | try: 12 | if x < 0: 13 | return 1 - 1 / (1 + math.exp(x)) 14 | return 1 / (1 + math.exp(-x)) 15 | except Exception as err: 16 | print("Error in sigmoid: " + err) 17 | 18 | 19 | def get_state(data, t, n_days): 20 | """Returns an n-day state representation ending at time t 21 | """ 22 | d = t - n_days + 1 23 | block = data[d: t + 1] if d >= 0 else -d * [data[0]] + data[0: t + 1] # pad with t0 24 | res = [] 25 | for i in range(n_days - 1): 26 | res.append(sigmoid(block[i + 1] - block[i])) 27 | return np.array([res]) 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Prabhsimran Singh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /trading_bot/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import math 3 | import logging 4 | 5 | import pandas as pd 6 | import numpy as np 7 | 8 | import keras.backend as K 9 | 10 | 11 | # Formats Position 12 | format_position = lambda price: ('-$' if price < 0 else '+$') + '{0:.2f}'.format(abs(price)) 13 | 14 | 15 | # Formats Currency 16 | format_currency = lambda price: '${0:.2f}'.format(abs(price)) 17 | 18 | 19 | def show_train_result(result, val_position, initial_offset): 20 | """ Displays training results 21 | """ 22 | if val_position == initial_offset or val_position == 0.0: 23 | logging.info('Episode {}/{} - Train Position: {} Val Position: USELESS Train Loss: {:.4f}' 24 | .format(result[0], result[1], format_position(result[2]), result[3])) 25 | else: 26 | logging.info('Episode {}/{} - Train Position: {} Val Position: {} Train Loss: {:.4f})' 27 | .format(result[0], result[1], format_position(result[2]), format_position(val_position), result[3],)) 28 | 29 | 30 | def show_eval_result(model_name, profit, initial_offset): 31 | """ Displays eval results 32 | """ 33 | if profit == initial_offset or profit == 0.0: 34 | logging.info('{}: USELESS\n'.format(model_name)) 35 | else: 36 | logging.info('{}: {}\n'.format(model_name, format_position(profit))) 37 | 38 | 39 | def get_stock_data(stock_file): 40 | """Reads stock data from csv file 41 | """ 42 | df = pd.read_csv(stock_file) 43 | return list(df['Adj Close']) 44 | 45 | 46 | def switch_k_backend_device(): 47 | """ Switches `keras` backend from GPU to CPU if required. 48 | 49 | Faster computation on CPU (if using tensorflow-gpu). 50 | """ 51 | if K.backend() == "tensorflow": 52 | logging.debug("switching to TensorFlow for CPU") 53 | os.environ["CUDA_VISIBLE_DEVICES"] = "-1" 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | # vscode config 107 | .vscode 108 | 109 | # poetry stuff 110 | poetry.lock 111 | -------------------------------------------------------------------------------- /eval.py: -------------------------------------------------------------------------------- 1 | """ 2 | Script for evaluating Stock Trading Bot. 3 | 4 | Usage: 5 | eval.py [--window-size=] [--model-name=] [--debug] 6 | 7 | Options: 8 | --window-size= Size of the n-day window stock data representation used as the feature vector. [default: 10] 9 | --model-name= Name of the pretrained model to use (will eval all models in `models/` if unspecified). 10 | --debug Specifies whether to use verbose logs during eval operation. 11 | """ 12 | 13 | import os 14 | import coloredlogs 15 | 16 | from docopt import docopt 17 | 18 | from trading_bot.agent import Agent 19 | from trading_bot.methods import evaluate_model 20 | from trading_bot.utils import ( 21 | get_stock_data, 22 | format_currency, 23 | format_position, 24 | show_eval_result, 25 | switch_k_backend_device 26 | ) 27 | 28 | 29 | def main(eval_stock, window_size, model_name, debug): 30 | """ Evaluates the stock trading bot. 31 | Please see https://arxiv.org/abs/1312.5602 for more details. 32 | 33 | Args: [python eval.py --help] 34 | """ 35 | data = get_stock_data(eval_stock) 36 | initial_offset = data[1] - data[0] 37 | 38 | # Single Model Evaluation 39 | if model_name is not None: 40 | agent = Agent(window_size, pretrained=True, model_name=model_name) 41 | profit, _ = evaluate_model(agent, data, window_size, debug) 42 | show_eval_result(model_name, profit, initial_offset) 43 | 44 | # Multiple Model Evaluation 45 | else: 46 | for model in os.listdir("models"): 47 | if os.path.isfile(os.path.join("models", model)): 48 | agent = Agent(window_size, pretrained=True, model_name=model) 49 | profit = evaluate_model(agent, data, window_size, debug) 50 | show_eval_result(model, profit, initial_offset) 51 | del agent 52 | 53 | 54 | if __name__ == "__main__": 55 | args = docopt(__doc__) 56 | 57 | eval_stock = args[""] 58 | window_size = int(args["--window-size"]) 59 | model_name = args["--model-name"] 60 | debug = args["--debug"] 61 | 62 | coloredlogs.install(level="DEBUG") 63 | switch_k_backend_device() 64 | 65 | try: 66 | main(eval_stock, window_size, model_name, debug) 67 | except KeyboardInterrupt: 68 | print("Aborted") 69 | -------------------------------------------------------------------------------- /trading_bot/methods.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | 4 | import numpy as np 5 | 6 | from tqdm import tqdm 7 | 8 | from .utils import ( 9 | format_currency, 10 | format_position 11 | ) 12 | from .ops import ( 13 | get_state 14 | ) 15 | 16 | 17 | def train_model(agent, episode, data, ep_count=100, batch_size=32, window_size=10): 18 | total_profit = 0 19 | data_length = len(data) - 1 20 | 21 | agent.inventory = [] 22 | avg_loss = [] 23 | 24 | state = get_state(data, 0, window_size + 1) 25 | 26 | for t in tqdm(range(data_length), total=data_length, leave=True, desc='Episode {}/{}'.format(episode, ep_count)): 27 | reward = 0 28 | next_state = get_state(data, t + 1, window_size + 1) 29 | 30 | # select an action 31 | action = agent.act(state) 32 | 33 | # BUY 34 | if action == 1: 35 | agent.inventory.append(data[t]) 36 | 37 | # SELL 38 | elif action == 2 and len(agent.inventory) > 0: 39 | bought_price = agent.inventory.pop(0) 40 | delta = data[t] - bought_price 41 | reward = delta #max(delta, 0) 42 | total_profit += delta 43 | 44 | # HOLD 45 | else: 46 | pass 47 | 48 | done = (t == data_length - 1) 49 | agent.remember(state, action, reward, next_state, done) 50 | 51 | if len(agent.memory) > batch_size: 52 | loss = agent.train_experience_replay(batch_size) 53 | avg_loss.append(loss) 54 | 55 | state = next_state 56 | 57 | if episode % 10 == 0: 58 | agent.save(episode) 59 | 60 | return (episode, ep_count, total_profit, np.mean(np.array(avg_loss))) 61 | 62 | 63 | def evaluate_model(agent, data, window_size, debug): 64 | total_profit = 0 65 | data_length = len(data) - 1 66 | 67 | history = [] 68 | agent.inventory = [] 69 | 70 | state = get_state(data, 0, window_size + 1) 71 | 72 | for t in range(data_length): 73 | reward = 0 74 | next_state = get_state(data, t + 1, window_size + 1) 75 | 76 | # select an action 77 | action = agent.act(state, is_eval=True) 78 | 79 | # BUY 80 | if action == 1: 81 | agent.inventory.append(data[t]) 82 | 83 | history.append((data[t], "BUY")) 84 | if debug: 85 | logging.debug("Buy at: {}".format(format_currency(data[t]))) 86 | 87 | # SELL 88 | elif action == 2 and len(agent.inventory) > 0: 89 | bought_price = agent.inventory.pop(0) 90 | delta = data[t] - bought_price 91 | reward = delta #max(delta, 0) 92 | total_profit += delta 93 | 94 | history.append((data[t], "SELL")) 95 | if debug: 96 | logging.debug("Sell at: {} | Position: {}".format( 97 | format_currency(data[t]), format_position(data[t] - bought_price))) 98 | # HOLD 99 | else: 100 | history.append((data[t], "HOLD")) 101 | 102 | done = (t == data_length - 1) 103 | agent.memory.append((state, action, reward, next_state, done)) 104 | 105 | state = next_state 106 | if done: 107 | return total_profit, history 108 | -------------------------------------------------------------------------------- /train.py: -------------------------------------------------------------------------------- 1 | """ 2 | Script for training Stock Trading Bot. 3 | 4 | Usage: 5 | train.py [--strategy=] 6 | [--window-size=] [--batch-size=] 7 | [--episode-count=] [--model-name=] 8 | [--pretrained] [--debug] 9 | 10 | Options: 11 | --strategy= Q-learning strategy to use for training the network. Options: 12 | `dqn` i.e. Vanilla DQN, 13 | `t-dqn` i.e. DQN with fixed target distribution, 14 | `double-dqn` i.e. DQN with separate network for value estimation. [default: t-dqn] 15 | --window-size= Size of the n-day window stock data representation 16 | used as the feature vector. [default: 10] 17 | --batch-size= Number of samples to train on in one mini-batch 18 | during training. [default: 32] 19 | --episode-count= Number of trading episodes to use for training. [default: 50] 20 | --model-name= Name of the pretrained model to use. [default: model_debug] 21 | --pretrained Specifies whether to continue training a previously 22 | trained model (reads `model-name`). 23 | --debug Specifies whether to use verbose logs during eval operation. 24 | """ 25 | 26 | import logging 27 | import coloredlogs 28 | 29 | from docopt import docopt 30 | 31 | from trading_bot.agent import Agent 32 | from trading_bot.methods import train_model, evaluate_model 33 | from trading_bot.utils import ( 34 | get_stock_data, 35 | format_currency, 36 | format_position, 37 | show_train_result, 38 | switch_k_backend_device 39 | ) 40 | 41 | 42 | def main(train_stock, val_stock, window_size, batch_size, ep_count, 43 | strategy="t-dqn", model_name="model_debug", pretrained=False, 44 | debug=False): 45 | """ Trains the stock trading bot using Deep Q-Learning. 46 | Please see https://arxiv.org/abs/1312.5602 for more details. 47 | 48 | Args: [python train.py --help] 49 | """ 50 | agent = Agent(window_size, strategy=strategy, pretrained=pretrained, model_name=model_name) 51 | 52 | train_data = get_stock_data(train_stock) 53 | val_data = get_stock_data(val_stock) 54 | 55 | initial_offset = val_data[1] - val_data[0] 56 | 57 | for episode in range(1, ep_count + 1): 58 | train_result = train_model(agent, episode, train_data, ep_count=ep_count, 59 | batch_size=batch_size, window_size=window_size) 60 | val_result, _ = evaluate_model(agent, val_data, window_size, debug) 61 | show_train_result(train_result, val_result, initial_offset) 62 | 63 | 64 | if __name__ == "__main__": 65 | args = docopt(__doc__) 66 | 67 | train_stock = args[""] 68 | val_stock = args[""] 69 | strategy = args["--strategy"] 70 | window_size = int(args["--window-size"]) 71 | batch_size = int(args["--batch-size"]) 72 | ep_count = int(args["--episode-count"]) 73 | model_name = args["--model-name"] 74 | pretrained = args["--pretrained"] 75 | debug = args["--debug"] 76 | 77 | coloredlogs.install(level="DEBUG") 78 | switch_k_backend_device() 79 | 80 | try: 81 | main(train_stock, val_stock, window_size, batch_size, 82 | ep_count, strategy=strategy, model_name=model_name, 83 | pretrained=pretrained, debug=debug) 84 | except KeyboardInterrupt: 85 | print("Aborted!") 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | This project implements a Stock Trading Bot, trained using Deep Reinforcement Learning, specifically Deep Q-learning. Implementation is kept simple and as close as possible to the algorithm discussed in the paper, for learning purposes. 4 | 5 | ## Introduction 6 | 7 | Generally, Reinforcement Learning is a family of machine learning techniques that allow us to create intelligent agents that learn from the environment by interacting with it, as they learn an optimal policy by trial and error. This is especially useful in many real world tasks where supervised learning might not be the best approach due to various reasons like nature of task itself, lack of appropriate labelled data, etc. 8 | 9 | The important idea here is that this technique can be applied to any real world task that can be described loosely as a Markovian process. 10 | 11 | ## Approach 12 | 13 | This work uses a Model-free Reinforcement Learning technique called Deep Q-Learning (neural variant of Q-Learning). 14 | At any given time (episode), an agent abserves it's current state (n-day window stock price representation), selects and performs an action (buy/sell/hold), observes a subsequent state, receives some reward signal (difference in portfolio position) and lastly adjusts it's parameters based on the gradient of the loss computed. 15 | 16 | There have been several improvements to the Q-learning algorithm over the years, and a few have been implemented in this project: 17 | 18 | - [x] Vanilla DQN 19 | - [x] DQN with fixed target distribution 20 | - [x] Double DQN 21 | - [ ] Prioritized Experience Replay 22 | - [ ] Dueling Network Architectures 23 | 24 | ## Results 25 | 26 | Trained on `GOOG` 2010-17 stock data, tested on 2019 with a profit of $1141.45 (validated on 2018 with profit of $863.41): 27 | 28 | ![Google Stock Trading episode](./extra/visualization.png) 29 | 30 | You can obtain similar visualizations of your model evaluations using the [notebook](./visualize.ipynb) provided. 31 | 32 | ## Some Caveats 33 | 34 | - At any given state, the agent can only decide to buy/sell one stock at a time. This is done to keep things as simple as possible as the problem of deciding how much stock to buy/sell is one of portfolio redistribution. 35 | - The n-day window feature representation is a vector of subsequent differences in Adjusted Closing price of the stock we're trading followed by a sigmoid operation, done in order to normalize the values to the range [0, 1]. 36 | - Training is prefferably done on CPU due to it's sequential manner, after each episode of trading we replay the experience (1 epoch over a small minibatch) and update model parameters. 37 | 38 | ## Data 39 | 40 | You can download Historical Financial data from [Yahoo! Finance](https://ca.finance.yahoo.com/) for training, or even use some sample datasets already present under `data/`. 41 | 42 | ## Getting Started 43 | 44 | In order to use this project, you'll need to install the required python packages: 45 | 46 | ```bash 47 | pip3 install -r requirements.txt 48 | ``` 49 | 50 | Now you can open up a terminal and start training the agent: 51 | 52 | ```bash 53 | python3 train.py data/GOOG.csv data/GOOG_2018.csv --strategy t-dqn 54 | ``` 55 | 56 | Once you're done training, run the evaluation script and let the agent make trading decisions: 57 | 58 | ```bash 59 | python3 eval.py data/GOOG_2019.csv --model-name model_GOOG_50 --debug 60 | ``` 61 | 62 | Now you are all set up! 63 | 64 | ## Acknowledgements 65 | 66 | - [@keon](https://github.com/keon) for [deep-q-learning](https://github.com/keon/deep-q-learning) 67 | - [@edwardhdlu](https://github.com/edwardhdlu) for [q-trader](https://github.com/edwardhdlu/q-trader) 68 | 69 | ## References 70 | 71 | - [Playing Atari with Deep Reinforcement Learning](https://arxiv.org/abs/1312.5602) 72 | - [Human Level Control Through Deep Reinforcement Learning](https://deepmind.com/research/publications/human-level-control-through-deep-reinforcement-learning/) 73 | - [Deep Reinforcement Learning with Double Q-Learning](https://arxiv.org/abs/1509.06461) 74 | - [Prioritized Experience Replay](https://arxiv.org/abs/1511.05952) 75 | - [Dueling Network Architectures for Deep Reinforcement Learning](https://arxiv.org/abs/1511.06581) -------------------------------------------------------------------------------- /trading_bot/agent.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from collections import deque 4 | 5 | import numpy as np 6 | import tensorflow as tf 7 | import keras.backend as K 8 | 9 | from keras.models import Sequential 10 | from keras.models import load_model, clone_model 11 | from keras.layers import Dense 12 | from keras.optimizers import Adam 13 | 14 | 15 | def huber_loss(y_true, y_pred, clip_delta=1.0): 16 | """Huber loss - Custom Loss Function for Q Learning 17 | 18 | Links: https://en.wikipedia.org/wiki/Huber_loss 19 | https://jaromiru.com/2017/05/27/on-using-huber-loss-in-deep-q-learning/ 20 | """ 21 | error = y_true - y_pred 22 | cond = K.abs(error) <= clip_delta 23 | squared_loss = 0.5 * K.square(error) 24 | quadratic_loss = 0.5 * K.square(clip_delta) + clip_delta * (K.abs(error) - clip_delta) 25 | return K.mean(tf.where(cond, squared_loss, quadratic_loss)) 26 | 27 | 28 | class Agent: 29 | """ Stock Trading Bot """ 30 | 31 | def __init__(self, state_size, strategy="t-dqn", reset_every=1000, pretrained=False, model_name=None): 32 | self.strategy = strategy 33 | 34 | # agent config 35 | self.state_size = state_size # normalized previous days 36 | self.action_size = 3 # [sit, buy, sell] 37 | self.model_name = model_name 38 | self.inventory = [] 39 | self.memory = deque(maxlen=10000) 40 | self.first_iter = True 41 | 42 | # model config 43 | self.model_name = model_name 44 | self.gamma = 0.95 # affinity for long term reward 45 | self.epsilon = 1.0 46 | self.epsilon_min = 0.01 47 | self.epsilon_decay = 0.995 48 | self.learning_rate = 0.001 49 | self.loss = huber_loss 50 | self.custom_objects = {"huber_loss": huber_loss} # important for loading the model from memory 51 | self.optimizer = Adam(lr=self.learning_rate) 52 | 53 | if pretrained and self.model_name is not None: 54 | self.model = self.load() 55 | else: 56 | self.model = self._model() 57 | 58 | # strategy config 59 | if self.strategy in ["t-dqn", "double-dqn"]: 60 | self.n_iter = 1 61 | self.reset_every = reset_every 62 | 63 | # target network 64 | self.target_model = clone_model(self.model) 65 | self.target_model.set_weights(self.model.get_weights()) 66 | 67 | def _model(self): 68 | """Creates the model 69 | """ 70 | model = Sequential() 71 | model.add(Dense(units=128, activation="relu", input_dim=self.state_size)) 72 | model.add(Dense(units=256, activation="relu")) 73 | model.add(Dense(units=256, activation="relu")) 74 | model.add(Dense(units=128, activation="relu")) 75 | model.add(Dense(units=self.action_size)) 76 | 77 | model.compile(loss=self.loss, optimizer=self.optimizer) 78 | return model 79 | 80 | def remember(self, state, action, reward, next_state, done): 81 | """Adds relevant data to memory 82 | """ 83 | self.memory.append((state, action, reward, next_state, done)) 84 | 85 | def act(self, state, is_eval=False): 86 | """Take action from given possible set of actions 87 | """ 88 | # take random action in order to diversify experience at the beginning 89 | if not is_eval and random.random() <= self.epsilon: 90 | return random.randrange(self.action_size) 91 | 92 | if self.first_iter: 93 | self.first_iter = False 94 | return 1 # make a definite buy on the first iter 95 | 96 | action_probs = self.model.predict(state) 97 | return np.argmax(action_probs[0]) 98 | 99 | def train_experience_replay(self, batch_size): 100 | """Train on previous experiences in memory 101 | """ 102 | mini_batch = random.sample(self.memory, batch_size) 103 | X_train, y_train = [], [] 104 | 105 | # DQN 106 | if self.strategy == "dqn": 107 | for state, action, reward, next_state, done in mini_batch: 108 | if done: 109 | target = reward 110 | else: 111 | # approximate deep q-learning equation 112 | target = reward + self.gamma * np.amax(self.model.predict(next_state)[0]) 113 | 114 | # estimate q-values based on current state 115 | q_values = self.model.predict(state) 116 | # update the target for current action based on discounted reward 117 | q_values[0][action] = target 118 | 119 | X_train.append(state[0]) 120 | y_train.append(q_values[0]) 121 | 122 | # DQN with fixed targets 123 | elif self.strategy == "t-dqn": 124 | if self.n_iter % self.reset_every == 0: 125 | # reset target model weights 126 | self.target_model.set_weights(self.model.get_weights()) 127 | 128 | for state, action, reward, next_state, done in mini_batch: 129 | if done: 130 | target = reward 131 | else: 132 | # approximate deep q-learning equation with fixed targets 133 | target = reward + self.gamma * np.amax(self.target_model.predict(next_state)[0]) 134 | 135 | # estimate q-values based on current state 136 | q_values = self.model.predict(state) 137 | # update the target for current action based on discounted reward 138 | q_values[0][action] = target 139 | 140 | X_train.append(state[0]) 141 | y_train.append(q_values[0]) 142 | 143 | # Double DQN 144 | elif self.strategy == "double-dqn": 145 | if self.n_iter % self.reset_every == 0: 146 | # reset target model weights 147 | self.target_model.set_weights(self.model.get_weights()) 148 | 149 | for state, action, reward, next_state, done in mini_batch: 150 | if done: 151 | target = reward 152 | else: 153 | # approximate double deep q-learning equation 154 | target = reward + self.gamma * self.target_model.predict(next_state)[0][np.argmax(self.model.predict(next_state)[0])] 155 | 156 | # estimate q-values based on current state 157 | q_values = self.model.predict(state) 158 | # update the target for current action based on discounted reward 159 | q_values[0][action] = target 160 | 161 | X_train.append(state[0]) 162 | y_train.append(q_values[0]) 163 | 164 | else: 165 | raise NotImplementedError() 166 | 167 | # update q-function parameters based on huber loss gradient 168 | loss = self.model.fit( 169 | np.array(X_train), np.array(y_train), 170 | epochs=1, verbose=0 171 | ).history["loss"][0] 172 | 173 | # as the training goes on we want the agent to 174 | # make less random and more optimal decisions 175 | if self.epsilon > self.epsilon_min: 176 | self.epsilon *= self.epsilon_decay 177 | 178 | return loss 179 | 180 | def save(self, episode): 181 | self.model.save("models/{}_{}".format(self.model_name, episode)) 182 | 183 | def load(self): 184 | return load_model("models/" + self.model_name, custom_objects=self.custom_objects) 185 | -------------------------------------------------------------------------------- /data/AAPL_2018.csv: -------------------------------------------------------------------------------- 1 | Date,Open,High,Low,Close,Adj Close,Volume 2 | 2017-08-10,159.899994,160.000000,154.630005,155.320007,153.006531,40804300 3 | 2017-08-11,156.600006,158.570007,156.070007,157.479996,155.134338,26257100 4 | 2017-08-14,159.320007,160.210007,158.750000,159.850006,157.469070,22122700 5 | 2017-08-15,160.660004,162.199997,160.139999,161.600006,159.192978,29465500 6 | 2017-08-16,161.940002,162.509995,160.149994,160.949997,158.552673,27671600 7 | 2017-08-17,160.520004,160.710007,157.839996,157.860001,155.508698,27940600 8 | 2017-08-18,157.860001,159.500000,156.720001,157.500000,155.154068,27428100 9 | 2017-08-21,157.500000,157.889999,155.110001,157.210007,154.868378,26368500 10 | 2017-08-22,158.229996,160.000000,158.020004,159.779999,157.400101,21604600 11 | 2017-08-23,159.070007,160.470001,158.880005,159.979996,157.597107,19399100 12 | 2017-08-24,160.429993,160.740005,158.550003,159.270004,156.897690,19818900 13 | 2017-08-25,159.649994,160.559998,159.270004,159.860001,157.478897,25480100 14 | 2017-08-28,160.139999,162.000000,159.929993,161.470001,159.064911,25966000 15 | 2017-08-29,160.100006,163.119995,160.000000,162.910004,160.483490,29516900 16 | 2017-08-30,163.800003,163.889999,162.610001,163.350006,160.916916,27269600 17 | 2017-08-31,163.639999,164.520004,163.479996,164.000000,161.557236,26785100 18 | 2017-09-01,164.800003,164.940002,163.630005,164.050003,161.606491,16591100 19 | 2017-09-05,163.750000,164.250000,160.559998,162.080002,159.665848,29468500 20 | 2017-09-06,162.710007,162.990005,160.520004,161.910004,159.498367,21651700 21 | 2017-09-07,162.089996,162.240005,160.360001,161.259995,158.858032,21928500 22 | 2017-09-08,160.860001,161.149994,158.529999,158.630005,156.267227,28611500 23 | 2017-09-11,160.500000,162.050003,159.889999,161.500000,159.094467,31085900 24 | 2017-09-12,162.610001,163.960007,158.770004,160.860001,158.464020,71714000 25 | 2017-09-13,159.869995,159.960007,157.910004,159.649994,157.272018,44907400 26 | 2017-09-14,158.990005,159.399994,158.089996,158.279999,155.922440,23760700 27 | 2017-09-15,158.470001,160.970001,158.000000,159.880005,157.498611,49114600 28 | 2017-09-18,160.110001,160.500000,158.000000,158.669998,156.306625,28269400 29 | 2017-09-19,159.509995,159.770004,158.440002,158.729996,156.365723,20810600 30 | 2017-09-20,157.899994,158.259995,153.830002,156.070007,153.745377,52951400 31 | 2017-09-21,155.800003,155.800003,152.750000,153.389999,151.105270,37511700 32 | 2017-09-22,151.539993,152.270004,150.559998,151.889999,149.627625,46645400 33 | 2017-09-25,149.990005,151.830002,149.160004,150.550003,148.307571,44387300 34 | 2017-09-26,151.779999,153.919998,151.690002,153.139999,150.859009,36660000 35 | 2017-09-27,153.800003,154.720001,153.539993,154.229996,151.932770,25504200 36 | 2017-09-28,153.889999,154.279999,152.699997,153.279999,150.996918,22005500 37 | 2017-09-29,153.210007,154.130005,152.000000,154.119995,151.824387,26299800 38 | 2017-10-02,154.259995,154.449997,152.720001,153.809998,151.519028,18698800 39 | 2017-10-03,154.009995,155.089996,153.910004,154.479996,152.179031,16230300 40 | 2017-10-04,153.630005,153.860001,152.460007,153.479996,151.193924,20163800 41 | 2017-10-05,154.179993,155.440002,154.050003,155.389999,153.075470,21283800 42 | 2017-10-06,154.970001,155.490005,154.559998,155.300003,152.986816,17407600 43 | 2017-10-09,155.809998,156.729996,155.490005,155.839996,153.518768,16262900 44 | 2017-10-10,156.059998,158.000000,155.100006,155.899994,153.577866,15617000 45 | 2017-10-11,155.970001,156.979996,155.750000,156.550003,154.218216,16905600 46 | 2017-10-12,156.350006,157.369995,155.729996,156.000000,153.676392,16125100 47 | 2017-10-13,156.729996,157.279999,156.410004,156.990005,154.651642,16394200 48 | 2017-10-16,157.899994,160.000000,157.649994,159.880005,157.498611,24121500 49 | 2017-10-17,159.779999,160.869995,159.229996,160.470001,158.079819,18997300 50 | 2017-10-18,160.419998,160.710007,159.600006,159.759995,157.380386,16374200 51 | 2017-10-19,156.750000,157.080002,155.020004,155.979996,153.656693,42584200 52 | 2017-10-20,156.610001,157.750000,155.960007,156.250000,153.922668,23974100 53 | 2017-10-23,156.889999,157.690002,155.500000,156.169998,153.843857,21984300 54 | 2017-10-24,156.289993,157.419998,156.199997,157.100006,154.760010,17757200 55 | 2017-10-25,156.910004,157.550003,155.270004,156.410004,154.080307,21207100 56 | 2017-10-26,157.229996,157.830002,156.779999,157.410004,155.065399,17000500 57 | 2017-10-27,159.289993,163.600006,158.699997,163.050003,160.621384,44454200 58 | 2017-10-30,163.889999,168.070007,163.720001,166.720001,164.236725,44700800 59 | 2017-10-31,167.899994,169.649994,166.940002,169.039993,166.522171,36046800 60 | 2017-11-01,169.869995,169.940002,165.610001,166.889999,164.404190,33637800 61 | 2017-11-02,166.600006,168.500000,165.279999,168.110001,165.606018,41393400 62 | 2017-11-03,174.000000,174.259995,171.119995,172.500000,169.930634,59398600 63 | 2017-11-06,172.369995,174.990005,171.720001,174.250000,171.654556,35026300 64 | 2017-11-07,173.910004,175.250000,173.600006,174.809998,172.206223,24361500 65 | 2017-11-08,174.660004,176.240005,174.330002,176.240005,173.614929,24409500 66 | 2017-11-09,175.110001,176.100006,173.139999,175.880005,173.260300,29482600 67 | 2017-11-10,175.110001,175.380005,174.270004,174.669998,172.686859,25145500 68 | 2017-11-13,173.500000,174.500000,173.399994,173.970001,171.994812,16982100 69 | 2017-11-14,173.039993,173.479996,171.179993,171.339996,169.394669,24782500 70 | 2017-11-15,169.970001,170.320007,168.380005,169.080002,167.160339,29158100 71 | 2017-11-16,171.179993,171.869995,170.300003,171.100006,169.157410,23637500 72 | 2017-11-17,171.039993,171.389999,169.639999,170.149994,168.218185,21899500 73 | 2017-11-20,170.289993,170.559998,169.559998,169.979996,168.050110,16262400 74 | 2017-11-21,170.779999,173.699997,170.779999,173.139999,171.174255,25131300 75 | 2017-11-22,173.360001,175.000000,173.050003,174.960007,172.973587,25588900 76 | 2017-11-24,175.100006,175.500000,174.649994,174.970001,172.983475,14026700 77 | 2017-11-27,175.050003,175.080002,173.339996,174.089996,172.113464,20716800 78 | 2017-11-28,174.300003,174.869995,171.860001,173.070007,171.105042,26428800 79 | 2017-11-29,172.630005,172.919998,167.160004,169.479996,167.555801,41666400 80 | 2017-11-30,170.429993,172.139999,168.440002,171.850006,169.898895,41527200 81 | 2017-12-01,169.949997,171.669998,168.500000,171.050003,169.107971,39759300 82 | 2017-12-04,172.479996,172.619995,169.630005,169.800003,167.872177,32542400 83 | 2017-12-05,169.059998,171.520004,168.399994,169.639999,167.713974,27350200 84 | 2017-12-06,167.500000,170.199997,166.460007,169.009995,167.091141,28560000 85 | 2017-12-07,169.029999,170.440002,168.910004,169.320007,167.397629,25673300 86 | 2017-12-08,170.490005,171.000000,168.820007,169.369995,167.447037,23355200 87 | 2017-12-11,169.199997,172.889999,168.789993,172.669998,170.709595,35273800 88 | 2017-12-12,172.149994,172.389999,171.460007,171.699997,169.750595,19409200 89 | 2017-12-13,172.500000,173.539993,172.000000,172.270004,170.314117,23818400 90 | 2017-12-14,172.399994,173.130005,171.649994,172.220001,170.264694,20476500 91 | 2017-12-15,173.630005,174.169998,172.460007,173.970001,171.994812,40169300 92 | 2017-12-18,174.880005,177.199997,174.860001,176.419998,174.417007,29421100 93 | 2017-12-19,175.029999,175.389999,174.089996,174.539993,172.558350,27436400 94 | 2017-12-20,174.869995,175.419998,173.250000,174.350006,172.370514,23475600 95 | 2017-12-21,174.169998,176.020004,174.100006,175.009995,173.023026,20949900 96 | 2017-12-22,174.679993,175.419998,174.500000,175.009995,173.023026,16349400 97 | 2017-12-26,170.800003,171.470001,169.679993,170.570007,168.633423,33185500 98 | 2017-12-27,170.100006,170.779999,169.710007,170.600006,168.663101,21498200 99 | 2017-12-28,171.000000,171.850006,170.479996,171.080002,169.137650,16480200 100 | 2017-12-29,170.520004,170.589996,169.220001,169.229996,167.308640,25999900 101 | 2018-01-02,170.160004,172.300003,169.259995,172.259995,170.304230,25555900 102 | 2018-01-03,172.529999,174.550003,171.960007,172.229996,170.274567,29517900 103 | 2018-01-04,172.539993,173.470001,172.080002,173.029999,171.065506,22434600 104 | 2018-01-05,173.440002,175.369995,173.050003,175.000000,173.013123,23660000 105 | 2018-01-08,174.350006,175.610001,173.929993,174.350006,172.370514,20567800 106 | 2018-01-09,174.550003,175.059998,173.410004,174.330002,172.350739,21584000 107 | 2018-01-10,173.160004,174.300003,173.000000,174.289993,172.311188,23959900 108 | 2018-01-11,174.589996,175.490005,174.490005,175.279999,173.289948,18667700 109 | 2018-01-12,176.179993,177.360001,175.649994,177.089996,175.079391,25418100 110 | 2018-01-16,177.899994,179.389999,176.139999,176.190002,174.189636,29565900 111 | 2018-01-17,176.149994,179.250000,175.070007,179.100006,177.066589,33888500 112 | 2018-01-18,179.369995,180.100006,178.250000,179.259995,177.224762,31193400 113 | 2018-01-19,178.610001,179.580002,177.410004,178.460007,176.433853,32425100 114 | 2018-01-22,177.300003,177.779999,176.600006,177.000000,174.990433,27108600 115 | 2018-01-23,177.300003,179.440002,176.820007,177.039993,175.029968,32689100 116 | 2018-01-24,177.250000,177.300003,173.199997,174.220001,172.241974,51105100 117 | 2018-01-25,174.509995,174.949997,170.529999,171.110001,169.167297,41529000 118 | 2018-01-26,172.000000,172.000000,170.059998,171.509995,169.562744,39143000 119 | 2018-01-29,170.160004,170.160004,167.070007,167.960007,166.053055,50640400 120 | 2018-01-30,165.529999,167.369995,164.699997,166.970001,165.074295,46048200 121 | 2018-01-31,166.869995,168.440002,166.500000,167.429993,165.529068,32478900 122 | 2018-02-01,167.169998,168.619995,166.759995,167.779999,165.875092,47230800 123 | 2018-02-02,166.000000,166.800003,160.100006,160.500000,158.677750,86593800 124 | 2018-02-05,159.100006,163.880005,156.000000,156.490005,154.713287,72738500 125 | 2018-02-06,154.830002,163.720001,154.000000,163.029999,161.179016,68243800 126 | 2018-02-07,163.089996,163.399994,159.070007,159.539993,157.728638,51608600 127 | 2018-02-08,160.289993,161.000000,155.029999,155.149994,153.388489,54390500 128 | 2018-02-09,157.070007,157.889999,150.240005,156.410004,155.264664,70672600 129 | 2018-02-12,158.500000,163.889999,157.509995,162.710007,161.518524,60819500 130 | 2018-02-13,161.949997,164.750000,161.649994,164.339996,163.136581,32549200 131 | 2018-02-14,163.039993,167.539993,162.880005,167.369995,166.144394,40644900 132 | 2018-02-15,169.789993,173.089996,169.000000,172.990005,171.723251,51147200 133 | 2018-02-16,172.360001,174.820007,171.770004,172.429993,171.167343,40176100 134 | 2018-02-20,172.050003,174.259995,171.419998,171.850006,170.591599,33930500 135 | 2018-02-21,172.830002,174.119995,171.009995,171.070007,169.817307,37471600 136 | 2018-02-22,171.800003,173.949997,171.710007,172.500000,171.236832,30991900 137 | 2018-02-23,173.669998,175.649994,173.539993,175.500000,174.214859,33812400 138 | 2018-02-26,176.350006,179.389999,176.210007,178.970001,177.659454,38162200 139 | 2018-02-27,179.100006,180.479996,178.160004,178.389999,177.083710,38928100 140 | 2018-02-28,179.259995,180.619995,178.050003,178.119995,176.815674,37782100 141 | 2018-03-01,178.539993,179.779999,172.660004,175.000000,173.718521,48802000 142 | 2018-03-02,172.800003,176.300003,172.449997,176.210007,174.919678,38454000 143 | 2018-03-05,175.210007,177.740005,174.520004,176.820007,175.525208,28401400 144 | 2018-03-06,177.910004,178.250000,176.130005,176.669998,175.376297,23788500 145 | 2018-03-07,174.940002,175.850006,174.270004,175.029999,173.748306,31703500 146 | 2018-03-08,175.479996,177.119995,175.070007,176.940002,175.644318,23774100 147 | 2018-03-09,177.960007,180.000000,177.389999,179.979996,178.662048,32185200 148 | 2018-03-12,180.289993,182.389999,180.210007,181.720001,180.389313,32207100 149 | 2018-03-13,182.589996,183.500000,179.240005,179.970001,178.652130,31693500 150 | 2018-03-14,180.320007,180.520004,177.809998,178.440002,177.133331,29368400 151 | 2018-03-15,178.500000,180.240005,178.070007,178.649994,177.341782,22743800 152 | 2018-03-16,178.649994,179.119995,177.619995,178.020004,176.716415,39404700 153 | 2018-03-19,177.320007,177.470001,173.660004,175.300003,174.016342,33446800 154 | 2018-03-20,175.240005,176.800003,174.940002,175.240005,173.956772,19649400 155 | 2018-03-21,175.039993,175.089996,171.259995,171.270004,170.015839,37054900 156 | 2018-03-22,170.000000,172.679993,168.600006,168.850006,167.613556,41490800 157 | 2018-03-23,168.389999,169.919998,164.940002,164.940002,163.732193,41028800 158 | 2018-03-26,168.070007,173.100006,166.440002,172.770004,171.504868,37541200 159 | 2018-03-27,173.679993,175.149994,166.919998,168.339996,167.107300,40922600 160 | 2018-03-28,167.250000,170.020004,165.190002,166.479996,165.260910,41668500 161 | 2018-03-29,167.809998,171.750000,166.899994,167.779999,166.551392,38398500 162 | 2018-04-02,166.639999,168.940002,164.470001,166.679993,165.459442,37586800 163 | 2018-04-03,167.639999,168.750000,164.880005,168.389999,167.156921,30278000 164 | 2018-04-04,164.880005,172.009995,164.770004,171.610001,170.353363,34605500 165 | 2018-04-05,172.580002,174.229996,172.080002,172.800003,171.534637,26933200 166 | 2018-04-06,170.970001,172.479996,168.199997,168.380005,167.147018,35005300 167 | 2018-04-09,169.880005,173.089996,169.850006,170.050003,168.804779,29017700 168 | 2018-04-10,173.000000,174.000000,171.529999,173.250000,171.981339,28408600 169 | 2018-04-11,172.229996,173.919998,171.699997,172.440002,171.177277,22431600 170 | 2018-04-12,173.410004,175.000000,173.039993,174.139999,172.864822,22889300 171 | 2018-04-13,174.779999,175.839996,173.850006,174.729996,173.450500,25124300 172 | 2018-04-16,175.029999,176.190002,174.830002,175.820007,174.532532,21578400 173 | 2018-04-17,176.490005,178.940002,176.410004,178.240005,176.934799,26605400 174 | 2018-04-18,177.809998,178.820007,176.880005,177.839996,176.537720,20754500 175 | 2018-04-19,173.759995,175.389999,172.660004,172.800003,171.534637,34808800 176 | 2018-04-20,170.600006,171.220001,165.429993,165.720001,164.506470,65491100 177 | 2018-04-23,166.830002,166.919998,164.089996,165.240005,164.029999,36515500 178 | 2018-04-24,165.669998,166.330002,161.220001,162.940002,161.746841,33692000 179 | 2018-04-25,162.619995,165.419998,162.410004,163.649994,162.451630,28382100 180 | 2018-04-26,164.119995,165.729996,163.369995,164.220001,163.017471,27963000 181 | 2018-04-27,164.000000,164.330002,160.630005,162.320007,161.131378,35655800 182 | 2018-04-30,162.130005,167.259995,161.839996,165.259995,164.049835,42427400 183 | 2018-05-01,166.410004,169.199997,165.270004,169.100006,167.861725,53569400 184 | 2018-05-02,175.229996,177.750000,173.800003,176.570007,175.277039,66539400 185 | 2018-05-03,175.880005,177.500000,174.440002,176.889999,175.594681,34068200 186 | 2018-05-04,178.250000,184.250000,178.169998,183.830002,182.483856,56201300 187 | 2018-05-07,185.179993,187.669998,184.750000,185.160004,183.804123,42451400 188 | 2018-05-08,184.990005,186.220001,183.669998,186.050003,184.687607,28402800 189 | 2018-05-09,186.550003,187.399994,185.220001,187.360001,185.988022,23211200 190 | 2018-05-10,187.740005,190.369995,187.649994,190.039993,188.648392,27989300 191 | 2018-05-11,189.490005,190.059998,187.449997,188.589996,187.930908,26212200 192 | 2018-05-14,189.009995,189.529999,187.860001,188.149994,187.492432,20778800 193 | 2018-05-15,186.779999,187.070007,185.100006,186.440002,185.788422,23695200 194 | 2018-05-16,186.070007,188.460007,186.000000,188.179993,187.522324,19183100 195 | 2018-05-17,188.000000,188.910004,186.360001,186.990005,186.336502,17294000 196 | 2018-05-18,187.190002,187.809998,186.130005,186.309998,185.658875,18297700 197 | 2018-05-21,188.000000,189.270004,186.910004,187.630005,186.974258,18400800 198 | 2018-05-22,188.380005,188.880005,186.779999,187.160004,186.505905,15240700 199 | 2018-05-23,186.350006,188.500000,185.759995,188.360001,187.701706,19467900 200 | 2018-05-24,188.770004,188.839996,186.210007,188.149994,187.492432,20401000 201 | 2018-05-25,188.229996,189.649994,187.649994,188.580002,187.920944,17461000 202 | 2018-05-29,187.600006,188.750000,186.869995,187.899994,187.243317,22369000 203 | 2018-05-30,187.720001,188.000000,186.779999,187.500000,186.844711,18690500 204 | 2018-05-31,187.220001,188.229996,186.139999,186.869995,186.216904,27482800 205 | 2018-06-01,187.990005,190.259995,187.750000,190.240005,189.575150,23250400 206 | 2018-06-04,191.639999,193.419998,191.350006,191.830002,191.159576,26132000 207 | 2018-06-05,193.070007,193.940002,192.360001,193.309998,192.634399,21566000 208 | 2018-06-06,193.630005,194.080002,191.919998,193.979996,193.302063,20933600 209 | 2018-06-07,194.139999,194.199997,192.339996,193.460007,192.783890,21347200 210 | 2018-06-08,191.169998,192.000000,189.770004,191.699997,191.030029,26656800 211 | 2018-06-11,191.350006,191.970001,190.210007,191.229996,190.561676,18308500 212 | 2018-06-12,191.389999,192.610001,191.149994,192.279999,191.608002,16911100 213 | 2018-06-13,192.419998,192.880005,190.440002,190.699997,190.033524,21638400 214 | 2018-06-14,191.550003,191.570007,190.220001,190.800003,190.133179,21610100 215 | 2018-06-15,190.029999,190.160004,188.259995,188.839996,188.180023,61719200 216 | 2018-06-18,187.880005,189.220001,187.199997,188.740005,188.080383,18484900 217 | 2018-06-19,185.139999,186.330002,183.449997,185.690002,185.041046,33578500 218 | 2018-06-20,186.350006,187.199997,185.729996,186.500000,185.848206,20628700 219 | 2018-06-21,187.250000,188.350006,184.940002,185.460007,184.811844,25711900 220 | 2018-06-22,186.119995,186.149994,184.699997,184.919998,184.273727,27200400 221 | 2018-06-25,183.399994,184.919998,180.729996,182.169998,181.533340,31663100 222 | 2018-06-26,182.990005,186.529999,182.539993,184.429993,183.785431,24569200 223 | 2018-06-27,185.229996,187.279999,184.029999,184.160004,183.516388,25285300 224 | 2018-06-28,184.100006,186.210007,183.800003,185.500000,184.851700,17365200 225 | 2018-06-29,186.289993,187.190002,182.910004,185.110001,184.463074,22737700 226 | 2018-07-02,183.820007,187.300003,183.419998,187.179993,186.525818,17731300 227 | 2018-07-03,187.789993,187.949997,183.539993,183.919998,183.277222,13954800 228 | 2018-07-05,185.259995,186.410004,184.279999,185.399994,184.752045,16604200 229 | 2018-07-06,185.419998,188.429993,185.199997,187.970001,187.313080,17485200 230 | 2018-07-09,189.500000,190.679993,189.300003,190.580002,189.913956,19756600 231 | 2018-07-10,190.710007,191.279999,190.179993,190.350006,189.684753,15939100 232 | 2018-07-11,188.500000,189.779999,187.610001,187.880005,187.223389,18831500 233 | 2018-07-12,189.529999,191.410004,189.309998,191.029999,190.362381,18041100 234 | 2018-07-13,191.080002,191.839996,190.899994,191.330002,190.661331,12513900 235 | 2018-07-16,191.520004,192.649994,190.419998,190.910004,190.242798,15043100 236 | 2018-07-17,189.750000,191.869995,189.199997,191.449997,190.780899,15534500 237 | 2018-07-18,191.779999,191.800003,189.929993,190.399994,189.734573,16393400 238 | 2018-07-19,189.690002,192.550003,189.690002,191.880005,191.209412,20286800 239 | 2018-07-20,191.779999,192.429993,190.169998,191.440002,190.770950,20676200 240 | 2018-07-23,190.679993,191.960007,189.559998,191.610001,190.940353,15989400 241 | 2018-07-24,192.449997,193.660004,192.050003,193.000000,192.325485,18697900 242 | 2018-07-25,193.059998,194.850006,192.429993,194.820007,194.139145,16709900 243 | 2018-07-26,194.610001,195.960007,193.610001,194.210007,193.531265,19076000 244 | 2018-07-27,194.990005,195.190002,190.100006,190.979996,190.312546,24024000 245 | 2018-07-30,191.899994,192.199997,189.070007,189.910004,189.246292,21029500 246 | 2018-07-31,190.300003,192.139999,189.339996,190.289993,189.624954,39373000 247 | 2018-08-01,199.130005,201.759995,197.309998,201.500000,200.795792,67935700 248 | 2018-08-02,200.580002,208.380005,200.350006,207.389999,206.665207,62404000 249 | 2018-08-03,207.029999,208.740005,205.479996,207.990005,207.263107,33447400 250 | 2018-08-06,208.000000,209.250000,207.070007,209.070007,208.339340,25425400 251 | 2018-08-07,209.320007,209.500000,206.759995,207.110001,206.386185,25587400 252 | 2018-08-08,206.050003,207.809998,204.520004,207.250000,206.525696,22525500 253 | 2018-08-09,207.279999,209.779999,207.199997,208.880005,208.149994,23469200 254 | 2018-08-10,207.360001,209.100006,206.669998,207.529999,207.529999,24600100 -------------------------------------------------------------------------------- /data/GOOG_2018.csv: -------------------------------------------------------------------------------- 1 | Date,Open,High,Low,Close,Adj Close,Volume 2 | 2017-08-10,935.000000,936.299988,921.780029,923.590027,923.590027,2707400 3 | 2017-08-11,923.710022,933.359985,921.219971,930.090027,930.090027,1616700 4 | 2017-08-14,939.070007,941.039978,934.489990,938.929993,938.929993,1148500 5 | 2017-08-15,941.030029,943.070007,936.640015,938.080017,938.080017,1106500 6 | 2017-08-16,941.250000,949.900024,940.039978,944.270020,944.270020,1345300 7 | 2017-08-17,942.950012,943.809998,927.640015,927.659973,927.659973,1695700 8 | 2017-08-18,926.979980,931.020020,923.450012,926.179993,926.179993,1337400 9 | 2017-08-21,925.770020,928.250000,918.599976,920.869995,920.869995,1301200 10 | 2017-08-22,926.960022,941.960022,926.169983,940.400024,940.400024,1775100 11 | 2017-08-23,937.000000,945.429993,935.239990,942.580017,942.580017,1134500 12 | 2017-08-24,943.710022,946.309998,930.739990,936.890015,936.890015,1294600 13 | 2017-08-25,939.210022,940.729980,930.099976,930.500000,930.500000,1187300 14 | 2017-08-28,931.880005,934.849976,926.109985,928.130005,928.130005,1049400 15 | 2017-08-29,919.950012,938.190002,919.309998,935.750000,935.750000,1158600 16 | 2017-08-30,935.669983,945.859985,934.049988,943.630005,943.630005,1120300 17 | 2017-08-31,946.299988,957.200012,946.250000,955.239990,955.239990,1693300 18 | 2017-09-01,957.469971,958.330017,950.280029,951.989990,951.989990,1042900 19 | 2017-09-05,946.859985,951.390015,935.599976,941.479980,941.479980,1457400 20 | 2017-09-06,943.869995,944.500000,932.679993,942.020020,942.020020,1391500 21 | 2017-09-07,944.250000,950.500000,937.530029,949.890015,949.890015,1116600 22 | 2017-09-08,949.700012,950.700012,940.010010,941.409973,941.409973,999900 23 | 2017-09-11,947.200012,952.679993,941.000000,943.289978,943.289978,1337400 24 | 2017-09-12,946.919983,948.090027,937.500000,946.650024,946.650024,1284800 25 | 2017-09-13,945.500000,952.849976,944.739990,950.440002,950.440002,1095400 26 | 2017-09-14,946.000000,948.030029,938.359985,940.130005,940.130005,1427400 27 | 2017-09-15,940.090027,941.750000,931.250000,935.289978,935.289978,1994300 28 | 2017-09-18,935.010010,936.859985,925.400024,929.750000,929.750000,1473700 29 | 2017-09-19,933.409973,937.940002,926.659973,936.859985,936.859985,1242700 30 | 2017-09-20,937.729980,950.000000,937.500000,947.539978,947.539978,2004000 31 | 2017-09-21,948.130005,952.799988,939.380005,947.549988,947.549988,1370700 32 | 2017-09-22,942.770020,950.000000,940.840027,943.260010,943.260010,1074800 33 | 2017-09-25,939.450012,939.750000,924.510010,934.280029,934.280029,1873400 34 | 2017-09-26,936.690002,944.080017,935.119995,937.429993,937.429993,1672700 35 | 2017-09-27,942.739990,965.429993,941.950012,959.900024,959.900024,2334600 36 | 2017-09-28,956.250000,966.179993,955.549988,964.809998,964.809998,1400900 37 | 2017-09-29,966.000000,975.809998,966.000000,973.719971,973.719971,2031100 38 | 2017-10-02,975.650024,977.739990,961.950012,967.469971,967.469971,1539100 39 | 2017-10-03,967.559998,972.440002,962.710022,972.080017,972.080017,1083300 40 | 2017-10-04,971.760010,974.400024,965.609985,966.780029,966.780029,1057800 41 | 2017-10-05,972.789978,986.510010,970.270020,985.190002,985.190002,1780900 42 | 2017-10-06,980.000000,994.260010,978.510010,993.640015,993.640015,1553000 43 | 2017-10-09,995.000000,1000.460022,991.500000,992.309998,992.309998,1295500 44 | 2017-10-10,995.299988,997.469971,981.109985,987.799988,987.799988,1163400 45 | 2017-10-11,989.039978,1007.570007,987.940002,1005.650024,1005.650024,1815000 46 | 2017-10-12,1003.840027,1011.539978,1001.099976,1005.650024,1005.650024,1530700 47 | 2017-10-13,1009.109985,1014.760010,1007.059998,1007.869995,1007.869995,1327600 48 | 2017-10-16,1009.630005,1012.000000,1001.520020,1009.349976,1009.349976,1071000 49 | 2017-10-17,1007.440002,1014.559998,1006.049988,1011.000000,1011.000000,1013000 50 | 2017-10-18,1011.049988,1016.309998,1005.320007,1012.739990,1012.739990,1279800 51 | 2017-10-19,1004.750000,1007.320007,997.299988,1001.840027,1001.840027,1714200 52 | 2017-10-20,1007.049988,1008.650024,1002.270020,1005.070007,1005.070007,1606000 53 | 2017-10-23,1005.179993,1005.789978,983.099976,985.539978,985.539978,1639300 54 | 2017-10-24,986.500000,989.260010,977.080017,988.489990,988.489990,1445100 55 | 2017-10-25,986.270020,994.429993,977.719971,991.460022,991.460022,1528700 56 | 2017-10-26,998.469971,1006.510010,990.469971,991.419983,991.419983,2369800 57 | 2017-10-27,1030.989990,1063.619995,1026.849976,1033.670044,1033.670044,5184100 58 | 2017-10-30,1029.160034,1039.829956,1022.330017,1033.130005,1033.130005,2340200 59 | 2017-10-31,1033.000000,1041.000000,1026.300049,1033.040039,1033.040039,1516300 60 | 2017-11-01,1036.319946,1047.859985,1034.000000,1042.599976,1042.599976,2163100 61 | 2017-11-02,1039.989990,1045.520020,1028.660034,1042.969971,1042.969971,1334700 62 | 2017-11-03,1042.750000,1050.660034,1037.650024,1049.989990,1049.989990,1388500 63 | 2017-11-06,1049.099976,1052.589966,1042.000000,1042.680054,1042.680054,914700 64 | 2017-11-07,1049.650024,1053.410034,1043.000000,1052.390015,1052.390015,1305200 65 | 2017-11-08,1050.050049,1062.689941,1047.050049,1058.290039,1058.290039,1213800 66 | 2017-11-09,1048.000000,1050.880005,1035.849976,1047.719971,1047.719971,1794600 67 | 2017-11-10,1043.869995,1046.630005,1041.219971,1044.150024,1044.150024,972100 68 | 2017-11-13,1040.800049,1048.739990,1039.260010,1041.199951,1041.199951,940700 69 | 2017-11-14,1037.719971,1042.300049,1029.329956,1041.640015,1041.640015,1050600 70 | 2017-11-15,1035.000000,1039.630005,1030.760010,1036.410034,1036.410034,905300 71 | 2017-11-16,1038.750000,1051.760010,1038.000000,1048.469971,1048.469971,1188400 72 | 2017-11-17,1049.800049,1051.000000,1033.729980,1035.890015,1035.890015,1335600 73 | 2017-11-20,1036.000000,1038.699951,1032.680054,1034.660034,1034.660034,876300 74 | 2017-11-21,1040.040039,1050.390015,1039.140015,1050.300049,1050.300049,1110300 75 | 2017-11-22,1051.160034,1055.430054,1047.250000,1051.920044,1051.920044,726900 76 | 2017-11-24,1054.390015,1060.069946,1051.920044,1056.520020,1056.520020,824600 77 | 2017-11-27,1058.569946,1073.040039,1054.770020,1072.010010,1072.010010,1771500 78 | 2017-11-28,1073.989990,1080.000000,1054.540039,1063.290039,1063.290039,1821200 79 | 2017-11-29,1056.180054,1058.770020,1029.650024,1037.380005,1037.380005,2793300 80 | 2017-11-30,1039.939941,1044.140015,1030.069946,1036.170044,1036.170044,2254600 81 | 2017-12-01,1030.410034,1037.239990,1016.900024,1025.069946,1025.069946,1888100 82 | 2017-12-04,1027.800049,1031.339966,1009.219971,1011.869995,1011.869995,1938900 83 | 2017-12-05,1010.989990,1036.680054,1002.320007,1019.599976,1019.599976,1949900 84 | 2017-12-06,1016.520020,1039.579956,1015.309998,1032.719971,1032.719971,1435500 85 | 2017-12-07,1036.069946,1048.920044,1035.359985,1044.569946,1044.569946,1543300 86 | 2017-12-08,1051.810059,1056.420044,1045.859985,1049.380005,1049.380005,1558500 87 | 2017-12-11,1051.109985,1056.000000,1044.119995,1051.969971,1051.969971,1162700 88 | 2017-12-12,1050.000000,1062.500000,1044.869995,1048.770020,1048.770020,1694100 89 | 2017-12-13,1052.079956,1055.479980,1046.579956,1051.390015,1051.390015,1384000 90 | 2017-12-14,1055.489990,1067.079956,1053.599976,1057.469971,1057.469971,1548100 91 | 2017-12-15,1063.780029,1075.250000,1060.089966,1072.000000,1072.000000,3188000 92 | 2017-12-18,1076.449951,1086.489990,1070.369995,1085.089966,1085.089966,1514600 93 | 2017-12-19,1083.020020,1084.969971,1072.270020,1079.780029,1079.780029,1317500 94 | 2017-12-20,1080.920044,1081.229980,1068.599976,1073.560059,1073.560059,1436400 95 | 2017-12-21,1075.390015,1077.520020,1069.000000,1070.849976,1070.849976,1282000 96 | 2017-12-22,1070.000000,1071.719971,1067.640015,1068.859985,1068.859985,889400 97 | 2017-12-26,1068.640015,1068.859985,1058.640015,1065.849976,1065.849976,918800 98 | 2017-12-27,1066.599976,1068.270020,1058.380005,1060.199951,1060.199951,1116200 99 | 2017-12-28,1062.250000,1064.839966,1053.380005,1055.949951,1055.949951,994200 100 | 2017-12-29,1055.489990,1058.050049,1052.699951,1053.400024,1053.400024,1180300 101 | 2018-01-02,1053.020020,1075.979980,1053.020020,1073.209961,1073.209961,1588300 102 | 2018-01-03,1073.930054,1096.099976,1073.430054,1091.520020,1091.520020,1565900 103 | 2018-01-04,1097.089966,1104.079956,1094.260010,1095.760010,1095.760010,1302600 104 | 2018-01-05,1103.449951,1113.579956,1101.800049,1110.290039,1110.290039,1512500 105 | 2018-01-08,1111.000000,1119.160034,1110.000000,1114.209961,1114.209961,1232200 106 | 2018-01-09,1118.439941,1118.439941,1108.199951,1112.790039,1112.790039,1340400 107 | 2018-01-10,1107.000000,1112.780029,1103.979980,1110.140015,1110.140015,1036700 108 | 2018-01-11,1112.310059,1114.849976,1106.479980,1112.050049,1112.050049,1121200 109 | 2018-01-12,1110.099976,1131.300049,1108.010010,1130.650024,1130.650024,1929300 110 | 2018-01-16,1140.310059,1148.880005,1126.660034,1130.699951,1130.699951,1823100 111 | 2018-01-17,1136.359985,1139.319946,1123.489990,1139.099976,1139.099976,1386400 112 | 2018-01-18,1139.349976,1140.589966,1124.459961,1135.969971,1135.969971,1374900 113 | 2018-01-19,1138.030029,1143.780029,1132.500000,1143.500000,1143.500000,1527600 114 | 2018-01-22,1143.819946,1166.880005,1141.819946,1164.160034,1164.160034,1477500 115 | 2018-01-23,1170.619995,1178.510010,1167.250000,1176.170044,1176.170044,1956900 116 | 2018-01-24,1184.979980,1187.050049,1167.400024,1171.290039,1171.290039,1856400 117 | 2018-01-25,1180.709961,1185.000000,1171.839966,1182.140015,1182.140015,1499200 118 | 2018-01-26,1187.530029,1187.560059,1168.030029,1187.560059,1187.560059,2108500 119 | 2018-01-29,1188.000000,1198.000000,1184.060059,1186.479980,1186.479980,1574700 120 | 2018-01-30,1177.719971,1187.930054,1174.510010,1177.369995,1177.369995,1866900 121 | 2018-01-31,1183.810059,1186.319946,1172.099976,1182.219971,1182.219971,1801100 122 | 2018-02-01,1175.989990,1187.449951,1169.359985,1181.589966,1181.589966,3675700 123 | 2018-02-02,1127.420044,1131.300049,1111.170044,1119.199951,1119.199951,5892100 124 | 2018-02-05,1100.609985,1114.989990,1056.739990,1062.390015,1062.390015,4177500 125 | 2018-02-06,1033.979980,1087.380005,1030.010010,1084.430054,1084.430054,3831500 126 | 2018-02-07,1084.969971,1086.530029,1054.619995,1055.410034,1055.410034,2597100 127 | 2018-02-08,1059.869995,1063.930054,1004.700012,1007.710022,1007.710022,3339600 128 | 2018-02-09,1025.880005,1051.719971,997.000000,1046.270020,1046.270020,4918000 129 | 2018-02-12,1056.670044,1065.569946,1045.489990,1054.560059,1054.560059,2812000 130 | 2018-02-13,1050.000000,1061.219971,1046.920044,1054.140015,1054.140015,1579300 131 | 2018-02-14,1054.319946,1075.469971,1049.800049,1072.699951,1072.699951,2065200 132 | 2018-02-15,1083.449951,1094.099976,1067.229980,1091.359985,1091.359985,1869800 133 | 2018-02-16,1093.380005,1108.310059,1091.550049,1095.500000,1095.500000,1997400 134 | 2018-02-20,1092.760010,1116.290039,1090.000000,1103.589966,1103.589966,1687700 135 | 2018-02-21,1109.099976,1136.199951,1107.510010,1113.750000,1113.750000,2074300 136 | 2018-02-22,1119.170044,1125.459961,1105.150024,1109.900024,1109.900024,1400500 137 | 2018-02-23,1118.660034,1129.000000,1108.439941,1128.089966,1128.089966,1264600 138 | 2018-02-26,1131.859985,1144.199951,1129.339966,1143.699951,1143.699951,1545600 139 | 2018-02-27,1143.699951,1144.250000,1116.790039,1117.510010,1117.510010,2148200 140 | 2018-02-28,1122.000000,1127.650024,1103.000000,1103.920044,1103.920044,2464600 141 | 2018-03-01,1109.540039,1111.270020,1067.290039,1071.410034,1071.410034,2766900 142 | 2018-03-02,1057.979980,1086.890015,1050.109985,1084.140015,1084.140015,2508100 143 | 2018-03-05,1078.130005,1101.180054,1072.270020,1094.760010,1094.760010,1432400 144 | 2018-03-06,1102.099976,1105.630005,1094.500000,1100.900024,1100.900024,1169100 145 | 2018-03-07,1092.819946,1116.199951,1089.910034,1115.040039,1115.040039,1537400 146 | 2018-03-08,1117.199951,1131.439941,1117.199951,1129.380005,1129.380005,1693100 147 | 2018-03-09,1139.500000,1161.000000,1134.290039,1160.839966,1160.839966,2133100 148 | 2018-03-12,1165.050049,1178.160034,1159.199951,1165.930054,1165.930054,2215300 149 | 2018-03-13,1171.829956,1178.000000,1134.569946,1139.910034,1139.910034,2157000 150 | 2018-03-14,1145.800049,1159.760010,1142.349976,1148.890015,1148.890015,2093500 151 | 2018-03-15,1149.569946,1162.500000,1135.660034,1150.609985,1150.609985,1669100 152 | 2018-03-16,1155.349976,1156.810059,1131.359985,1134.420044,1134.420044,2932800 153 | 2018-03-19,1117.760010,1119.369995,1088.920044,1100.069946,1100.069946,3182800 154 | 2018-03-20,1098.400024,1105.550049,1082.420044,1095.800049,1095.800049,2729900 155 | 2018-03-21,1092.569946,1108.699951,1087.209961,1094.000000,1094.000000,2244900 156 | 2018-03-22,1080.010010,1083.920044,1049.640015,1053.150024,1053.150024,3465600 157 | 2018-03-23,1051.369995,1066.780029,1024.869995,1026.550049,1026.550049,2494000 158 | 2018-03-26,1050.599976,1059.270020,1010.580017,1054.089966,1054.089966,3299200 159 | 2018-03-27,1063.900024,1064.540039,997.619995,1006.940002,1006.940002,3040800 160 | 2018-03-28,1001.909973,1024.989990,984.000000,1005.179993,1005.179993,3884900 161 | 2018-03-29,1011.210022,1048.050049,1004.039978,1037.140015,1037.140015,3466900 162 | 2018-04-02,1027.619995,1039.530029,994.250000,1012.630005,1012.630005,3253400 163 | 2018-04-03,1016.150024,1025.000000,997.250000,1018.679993,1018.679993,2566100 164 | 2018-04-04,998.229980,1032.739990,996.510010,1029.709961,1029.709961,2536200 165 | 2018-04-05,1046.390015,1046.709961,1024.000000,1032.640015,1032.640015,1791800 166 | 2018-04-06,1023.099976,1036.000000,1006.250000,1009.950012,1009.950012,2006700 167 | 2018-04-09,1020.039978,1044.589966,1019.200012,1020.090027,1020.090027,1661000 168 | 2018-04-10,1030.260010,1041.209961,1015.409973,1036.500000,1036.500000,1831000 169 | 2018-04-11,1032.000000,1035.869995,1019.200012,1025.060059,1025.060059,1703000 170 | 2018-04-12,1031.469971,1044.650024,1026.050049,1037.290039,1037.290039,1644800 171 | 2018-04-13,1046.890015,1052.979980,1030.150024,1036.040039,1036.040039,1270500 172 | 2018-04-16,1045.550049,1051.430054,1033.920044,1046.099976,1046.099976,1488800 173 | 2018-04-17,1061.199951,1085.000000,1057.089966,1079.359985,1079.359985,2729200 174 | 2018-04-18,1079.010010,1082.000000,1070.520020,1075.390015,1075.390015,1556300 175 | 2018-04-19,1069.020020,1097.510010,1069.020020,1089.449951,1089.449951,1994200 176 | 2018-04-20,1084.270020,1094.750000,1072.099976,1077.319946,1077.319946,2121700 177 | 2018-04-23,1082.979980,1088.000000,1066.680054,1073.810059,1073.810059,3479500 178 | 2018-04-24,1059.199951,1064.489990,1012.859985,1022.640015,1022.640015,6411000 179 | 2018-04-25,1029.750000,1036.069946,1017.010010,1022.989990,1022.989990,2893000 180 | 2018-04-26,1033.219971,1052.020020,1020.450012,1043.310059,1043.310059,2546300 181 | 2018-04-27,1045.540039,1051.699951,1027.589966,1031.449951,1031.449951,2037300 182 | 2018-04-30,1034.420044,1038.369995,1018.299988,1018.580017,1018.580017,1724600 183 | 2018-05-01,1016.299988,1041.729980,1010.609985,1040.750000,1040.750000,1766300 184 | 2018-05-02,1034.000000,1043.979980,1023.159973,1026.050049,1026.050049,1734900 185 | 2018-05-03,1025.369995,1030.689941,1007.890015,1026.300049,1026.300049,1964100 186 | 2018-05-04,1019.609985,1051.880005,1018.049988,1051.000000,1051.000000,1844600 187 | 2018-05-07,1053.890015,1065.000000,1050.270020,1059.459961,1059.459961,1720000 188 | 2018-05-08,1064.619995,1065.229980,1051.640015,1058.589966,1058.589966,1301500 189 | 2018-05-09,1064.099976,1094.000000,1062.109985,1088.949951,1088.949951,2358000 190 | 2018-05-10,1095.000000,1109.410034,1093.880005,1105.469971,1105.469971,1820700 191 | 2018-05-11,1100.410034,1109.010010,1097.219971,1103.380005,1103.380005,1525200 192 | 2018-05-14,1105.569946,1118.150024,1104.800049,1106.599976,1106.599976,1966900 193 | 2018-05-15,1096.900024,1099.119995,1078.780029,1084.869995,1084.869995,1786900 194 | 2018-05-16,1085.089966,1094.380005,1081.630005,1084.089966,1084.089966,1281400 195 | 2018-05-17,1081.459961,1091.000000,1076.420044,1081.260010,1081.260010,1286900 196 | 2018-05-18,1066.000000,1073.729980,1064.680054,1069.640015,1069.640015,1774100 197 | 2018-05-21,1079.000000,1093.300049,1078.000000,1084.010010,1084.010010,1259000 198 | 2018-05-22,1089.800049,1091.800049,1072.260010,1075.310059,1075.310059,1111300 199 | 2018-05-23,1070.000000,1088.000000,1066.959961,1085.959961,1085.959961,1154800 200 | 2018-05-24,1086.900024,1087.119995,1072.300049,1085.449951,1085.449951,1023200 201 | 2018-05-25,1086.550049,1089.569946,1082.599976,1084.079956,1084.079956,1111200 202 | 2018-05-29,1076.000000,1081.339966,1063.079956,1068.069946,1068.069946,1793600 203 | 2018-05-30,1073.479980,1078.989990,1066.550049,1077.469971,1077.469971,1434300 204 | 2018-05-31,1082.000000,1110.000000,1078.000000,1100.000000,1100.000000,3968400 205 | 2018-06-01,1112.869995,1138.160034,1112.010010,1135.000000,1135.000000,3150700 206 | 2018-06-04,1138.500000,1157.859985,1137.000000,1153.040039,1153.040039,2233600 207 | 2018-06-05,1154.660034,1161.099976,1147.459961,1151.020020,1151.020020,1648200 208 | 2018-06-06,1152.770020,1154.709961,1136.319946,1146.949951,1146.949951,1746700 209 | 2018-06-07,1144.579956,1145.869995,1126.119995,1134.420044,1134.420044,1805400 210 | 2018-06-08,1131.209961,1138.780029,1123.229980,1132.709961,1132.709961,1364200 211 | 2018-06-11,1132.939941,1147.739990,1131.400024,1140.900024,1140.900024,1239800 212 | 2018-06-12,1141.020020,1148.750000,1141.020020,1148.189941,1148.189941,1304600 213 | 2018-06-13,1152.280029,1155.640015,1143.380005,1144.229980,1144.229980,1715100 214 | 2018-06-14,1152.209961,1165.989990,1150.599976,1160.109985,1160.109985,1771100 215 | 2018-06-15,1159.920044,1163.910034,1153.689941,1159.270020,1159.270020,2221900 216 | 2018-06-18,1152.689941,1184.130005,1151.000000,1183.579956,1183.579956,1651900 217 | 2018-06-19,1170.109985,1182.810059,1161.609985,1178.689941,1178.689941,2364100 218 | 2018-06-20,1183.300049,1201.489990,1182.030029,1184.069946,1184.069946,2584300 219 | 2018-06-21,1185.510010,1190.329956,1163.479980,1169.439941,1169.439941,2248300 220 | 2018-06-22,1171.489990,1175.000000,1159.650024,1169.290039,1169.290039,1711000 221 | 2018-06-25,1155.000000,1155.989990,1119.900024,1139.280029,1139.280029,2884100 222 | 2018-06-26,1144.140015,1146.869995,1129.000000,1132.619995,1132.619995,1734400 223 | 2018-06-27,1136.000000,1146.209961,1116.699951,1116.939941,1116.939941,1726900 224 | 2018-06-28,1112.390015,1134.000000,1106.069946,1126.780029,1126.780029,1486300 225 | 2018-06-29,1132.310059,1141.359985,1127.020020,1129.189941,1129.189941,1578100 226 | 2018-07-02,1115.349976,1142.989990,1106.599976,1142.109985,1142.109985,1160800 227 | 2018-07-03,1149.420044,1149.910034,1114.430054,1116.280029,1116.280029,822400 228 | 2018-07-05,1124.599976,1144.140015,1123.119995,1141.290039,1141.290039,1429700 229 | 2018-07-06,1141.770020,1156.199951,1137.239990,1155.079956,1155.079956,1091000 230 | 2018-07-09,1160.000000,1167.930054,1157.229980,1167.280029,1167.280029,1079200 231 | 2018-07-10,1169.989990,1173.500000,1162.560059,1167.140015,1167.140015,1066700 232 | 2018-07-11,1155.619995,1180.439941,1155.369995,1171.459961,1171.459961,1662600 233 | 2018-07-12,1174.859985,1201.989990,1173.099976,1201.260010,1201.260010,2207400 234 | 2018-07-13,1202.800049,1210.439941,1195.290039,1204.420044,1204.420044,1630600 235 | 2018-07-16,1203.810059,1208.709961,1193.400024,1196.510010,1196.510010,1339200 236 | 2018-07-17,1182.739990,1218.760010,1182.000000,1213.079956,1213.079956,2008100 237 | 2018-07-18,1208.530029,1221.589966,1204.560059,1212.910034,1212.910034,1947400 238 | 2018-07-19,1206.650024,1216.479980,1197.729980,1199.099976,1199.099976,1916900 239 | 2018-07-20,1199.239990,1210.770020,1196.589966,1197.880005,1197.880005,1896900 240 | 2018-07-23,1195.660034,1215.099976,1192.010010,1211.000000,1211.000000,3272300 241 | 2018-07-24,1271.000000,1275.000000,1244.140015,1258.150024,1258.150024,5380000 242 | 2018-07-25,1252.619995,1278.239990,1249.050049,1275.939941,1275.939941,2555200 243 | 2018-07-26,1267.180054,1287.400024,1263.000000,1285.500000,1285.500000,2734300 244 | 2018-07-27,1289.119995,1291.439941,1244.489990,1252.890015,1252.890015,2418100 245 | 2018-07-30,1245.050049,1252.890015,1224.170044,1230.040039,1230.040039,2194800 246 | 2018-07-31,1231.709961,1241.209961,1216.189941,1227.219971,1227.219971,1969100 247 | 2018-08-01,1239.109985,1245.900024,1224.939941,1232.989990,1232.989990,1849700 248 | 2018-08-02,1218.500000,1244.410034,1218.060059,1241.130005,1241.130005,1735200 249 | 2018-08-03,1245.180054,1246.520020,1229.420044,1238.160034,1238.160034,1063200 250 | 2018-08-06,1241.609985,1242.459961,1230.530029,1237.670044,1237.670044,1105700 251 | 2018-08-07,1252.010010,1266.079956,1251.800049,1255.839966,1255.839966,2125300 252 | 2018-08-08,1256.719971,1271.719971,1252.119995,1261.329956,1261.329956,1717200 253 | 2018-08-09,1262.729980,1271.959961,1260.099976,1264.459961,1264.459961,1365700 254 | 2018-08-10,1259.180054,1261.199951,1247.160034,1252.510010,1252.510010,1330100 -------------------------------------------------------------------------------- /data/GOOG_2019.csv: -------------------------------------------------------------------------------- 1 | Date,Open,High,Low,Close,Adj Close,Volume 2 | 2019-01-02,1016.570007,1052.319946,1015.710022,1045.849976,1045.849976,1532600 3 | 2019-01-03,1041.000000,1056.979980,1014.070007,1016.059998,1016.059998,1841100 4 | 2019-01-04,1032.589966,1070.839966,1027.417969,1070.709961,1070.709961,2093900 5 | 2019-01-07,1071.500000,1074.000000,1054.760010,1068.390015,1068.390015,1981900 6 | 2019-01-08,1076.109985,1084.560059,1060.530029,1076.280029,1076.280029,1764900 7 | 2019-01-09,1081.650024,1082.630005,1066.400024,1074.660034,1074.660034,1199300 8 | 2019-01-10,1067.660034,1071.150024,1057.709961,1070.329956,1070.329956,1456400 9 | 2019-01-11,1063.180054,1063.775024,1048.479980,1057.189941,1057.189941,1520800 10 | 2019-01-14,1046.920044,1051.530029,1041.255005,1044.689941,1044.689941,1144300 11 | 2019-01-15,1050.170044,1080.050049,1047.339966,1077.150024,1077.150024,1463600 12 | 2019-01-16,1080.000000,1092.375000,1079.339966,1080.969971,1080.969971,1331800 13 | 2019-01-17,1079.469971,1091.800049,1073.500000,1089.900024,1089.900024,1242700 14 | 2019-01-18,1100.000000,1108.352051,1090.900024,1098.260010,1098.260010,1955600 15 | 2019-01-22,1088.000000,1091.510010,1063.469971,1070.520020,1070.520020,1613500 16 | 2019-01-23,1077.349976,1084.930054,1059.750000,1075.569946,1075.569946,967000 17 | 2019-01-24,1076.479980,1079.474976,1060.699951,1073.900024,1073.900024,1361300 18 | 2019-01-25,1085.000000,1094.000000,1081.819946,1090.989990,1090.989990,1119100 19 | 2019-01-28,1080.109985,1083.000000,1063.800049,1070.079956,1070.079956,1284300 20 | 2019-01-29,1072.680054,1075.150024,1055.864990,1060.619995,1060.619995,1021800 21 | 2019-01-30,1068.430054,1091.000000,1066.849976,1089.060059,1089.060059,1279800 22 | 2019-01-31,1103.000000,1117.329956,1095.410034,1116.369995,1116.369995,1538300 23 | 2019-02-01,1112.400024,1125.000000,1104.890015,1110.750000,1110.750000,1462200 24 | 2019-02-04,1112.660034,1132.800049,1109.020020,1132.800049,1132.800049,2576500 25 | 2019-02-05,1124.839966,1146.849976,1117.248047,1145.989990,1145.989990,3552200 26 | 2019-02-06,1139.569946,1147.000000,1112.770020,1115.229980,1115.229980,2105600 27 | 2019-02-07,1104.160034,1104.839966,1086.000000,1098.709961,1098.709961,2044800 28 | 2019-02-08,1087.000000,1098.910034,1086.550049,1095.060059,1095.060059,1075800 29 | 2019-02-11,1096.949951,1105.944946,1092.859985,1095.010010,1095.010010,1065200 30 | 2019-02-12,1106.800049,1125.295044,1105.849976,1121.369995,1121.369995,1609100 31 | 2019-02-13,1124.989990,1134.729980,1118.500000,1120.160034,1120.160034,1049800 32 | 2019-02-14,1118.050049,1128.229980,1110.444946,1121.670044,1121.670044,947600 33 | 2019-02-15,1130.079956,1131.670044,1110.650024,1113.650024,1113.650024,1449800 34 | 2019-02-19,1110.000000,1121.890015,1110.000000,1118.560059,1118.560059,1046400 35 | 2019-02-20,1119.989990,1123.410034,1105.280029,1113.800049,1113.800049,1087800 36 | 2019-02-21,1110.839966,1111.939941,1092.520020,1096.969971,1096.969971,1415100 37 | 2019-02-22,1100.900024,1111.239990,1095.599976,1110.369995,1110.369995,1049500 38 | 2019-02-25,1116.000000,1118.540039,1107.270020,1109.400024,1109.400024,1413100 39 | 2019-02-26,1105.750000,1119.510010,1099.920044,1115.130005,1115.130005,1471300 40 | 2019-02-27,1106.949951,1117.979980,1101.000000,1116.050049,1116.050049,968400 41 | 2019-02-28,1111.300049,1127.650024,1111.010010,1119.920044,1119.920044,1542500 42 | 2019-03-01,1124.900024,1142.969971,1124.750000,1140.989990,1140.989990,1450300 43 | 2019-03-04,1146.989990,1158.280029,1130.689941,1147.800049,1147.800049,1446000 44 | 2019-03-05,1150.060059,1169.609985,1146.194946,1162.030029,1162.030029,1443200 45 | 2019-03-06,1162.489990,1167.566040,1155.489990,1157.859985,1157.859985,1099300 46 | 2019-03-07,1155.719971,1156.755005,1134.910034,1143.300049,1143.300049,1166600 47 | 2019-03-08,1126.729980,1147.079956,1123.300049,1142.319946,1142.319946,1212400 48 | 2019-03-11,1144.449951,1176.189941,1144.449951,1175.760010,1175.760010,1719200 49 | 2019-03-12,1178.260010,1200.000000,1178.260010,1193.199951,1193.199951,2013100 50 | 2019-03-13,1200.645020,1200.930054,1191.939941,1193.319946,1193.319946,1435900 51 | 2019-03-14,1194.510010,1197.880005,1184.479980,1185.550049,1185.550049,1172800 52 | 2019-03-15,1193.380005,1196.569946,1182.609985,1184.459961,1184.459961,2461800 53 | 2019-03-18,1183.300049,1190.000000,1177.421021,1184.260010,1184.260010,1292600 54 | 2019-03-19,1188.810059,1200.000000,1185.869995,1198.849976,1198.849976,1520700 55 | 2019-03-20,1197.349976,1227.140015,1196.170044,1223.969971,1223.969971,2227400 56 | 2019-03-21,1216.000000,1231.790039,1213.150024,1231.540039,1231.540039,1204000 57 | 2019-03-22,1226.319946,1230.000000,1202.824951,1205.500000,1205.500000,1714200 58 | 2019-03-25,1196.930054,1206.397949,1187.040039,1193.000000,1193.000000,1496800 59 | 2019-03-26,1198.530029,1202.829956,1176.719971,1184.619995,1184.619995,1901200 60 | 2019-03-27,1185.500000,1187.558960,1159.369995,1173.020020,1173.020020,1400200 61 | 2019-03-28,1171.540039,1171.564941,1159.431030,1168.489990,1168.489990,1012400 62 | 2019-03-29,1174.900024,1178.989990,1162.880005,1173.310059,1173.310059,1269900 63 | 2019-04-01,1184.099976,1196.660034,1182.000000,1194.430054,1194.430054,1252500 64 | 2019-04-02,1195.319946,1201.349976,1185.709961,1200.489990,1200.489990,827900 65 | 2019-04-03,1207.479980,1216.300049,1200.500000,1205.920044,1205.920044,1017800 66 | 2019-04-04,1205.939941,1215.670044,1204.130005,1215.000000,1215.000000,950000 67 | 2019-04-05,1214.989990,1216.219971,1205.030029,1207.150024,1207.150024,907200 68 | 2019-04-08,1207.890015,1208.689941,1199.859985,1203.839966,1203.839966,860200 69 | 2019-04-09,1196.000000,1202.290039,1193.079956,1197.250000,1197.250000,876400 70 | 2019-04-10,1200.680054,1203.785034,1196.435059,1202.160034,1202.160034,724600 71 | 2019-04-11,1203.959961,1207.959961,1200.130005,1204.619995,1204.619995,710200 72 | 2019-04-12,1210.000000,1218.349976,1208.109985,1217.869995,1217.869995,933400 73 | 2019-04-15,1218.000000,1224.199951,1209.109985,1221.099976,1221.099976,1187400 74 | 2019-04-16,1225.000000,1230.819946,1220.119995,1227.130005,1227.130005,856300 75 | 2019-04-17,1233.000000,1240.560059,1227.819946,1236.339966,1236.339966,1221900 76 | 2019-04-18,1239.180054,1242.000000,1234.609985,1236.369995,1236.369995,1331800 77 | 2019-04-22,1235.989990,1249.089966,1228.310059,1248.839966,1248.839966,807300 78 | 2019-04-23,1250.689941,1269.000000,1246.380005,1264.550049,1264.550049,1319900 79 | 2019-04-24,1264.119995,1268.010010,1255.000000,1256.000000,1256.000000,1018800 80 | 2019-04-25,1264.770020,1267.407959,1252.030029,1263.449951,1263.449951,1107300 81 | 2019-04-26,1269.000000,1273.069946,1260.319946,1272.180054,1272.180054,1241400 82 | 2019-04-29,1274.000000,1289.270020,1266.295044,1287.579956,1287.579956,2499400 83 | 2019-04-30,1185.000000,1192.810059,1175.000000,1188.479980,1188.479980,6207000 84 | 2019-05-01,1188.050049,1188.050049,1167.180054,1168.079956,1168.079956,2639200 85 | 2019-05-02,1167.760010,1174.189941,1155.001953,1162.609985,1162.609985,1944800 86 | 2019-05-03,1173.650024,1186.800049,1169.000000,1185.400024,1185.400024,1980700 87 | 2019-05-06,1166.260010,1190.849976,1166.260010,1189.390015,1189.390015,1563900 88 | 2019-05-07,1180.469971,1190.439941,1161.040039,1174.099976,1174.099976,1551400 89 | 2019-05-08,1172.010010,1180.423950,1165.739990,1166.270020,1166.270020,1309300 90 | 2019-05-09,1159.030029,1169.660034,1150.849976,1162.380005,1162.380005,1185700 91 | 2019-05-10,1163.589966,1172.599976,1142.500000,1164.270020,1164.270020,1314500 92 | 2019-05-13,1141.959961,1147.939941,1122.109985,1132.030029,1132.030029,1860600 93 | 2019-05-14,1137.209961,1140.420044,1119.550049,1120.439941,1120.439941,1836600 94 | 2019-05-15,1117.869995,1171.329956,1116.666016,1164.209961,1164.209961,2289300 95 | 2019-05-16,1164.510010,1188.160034,1162.839966,1178.979980,1178.979980,1531400 96 | 2019-05-17,1168.469971,1180.150024,1160.010010,1162.300049,1162.300049,1208600 97 | 2019-05-20,1144.500000,1146.796997,1131.442993,1138.849976,1138.849976,1353300 98 | 2019-05-21,1148.489990,1152.708008,1137.939941,1149.630005,1149.630005,1159800 99 | 2019-05-22,1146.750000,1158.520020,1145.890015,1151.420044,1151.420044,914500 100 | 2019-05-23,1140.500000,1145.973022,1129.223999,1140.770020,1140.770020,1198900 101 | 2019-05-24,1147.359985,1149.765015,1131.660034,1133.469971,1133.469971,1112000 102 | 2019-05-28,1134.000000,1151.587036,1133.119995,1134.150024,1134.150024,1365000 103 | 2019-05-29,1127.520020,1129.099976,1108.219971,1116.459961,1116.459961,1538200 104 | 2019-05-30,1115.540039,1123.130005,1112.119995,1117.949951,1117.949951,951900 105 | 2019-05-31,1101.290039,1109.599976,1100.180054,1103.630005,1103.630005,1507800 106 | 2019-06-03,1065.500000,1065.500000,1025.000000,1036.229980,1036.229980,5130600 107 | 2019-06-04,1042.900024,1056.050049,1033.689941,1053.050049,1053.050049,2833500 108 | 2019-06-05,1051.540039,1053.550049,1030.489990,1042.219971,1042.219971,2168400 109 | 2019-06-06,1044.989990,1047.489990,1033.699951,1044.339966,1044.339966,1703200 110 | 2019-06-07,1050.630005,1070.920044,1048.400024,1066.040039,1066.040039,1802400 111 | 2019-06-10,1072.979980,1092.660034,1072.322021,1080.380005,1080.380005,1464200 112 | 2019-06-11,1093.979980,1101.989990,1077.603027,1078.719971,1078.719971,1436700 113 | 2019-06-12,1078.000000,1080.930054,1067.540039,1077.030029,1077.030029,1061000 114 | 2019-06-13,1083.640015,1094.170044,1080.150024,1088.770020,1088.770020,1057700 115 | 2019-06-14,1086.420044,1092.689941,1080.171997,1085.349976,1085.349976,1111500 116 | 2019-06-17,1086.280029,1099.180054,1086.280029,1092.500000,1092.500000,941600 117 | 2019-06-18,1109.689941,1116.390015,1098.989990,1103.599976,1103.599976,1386700 118 | 2019-06-19,1105.599976,1107.000000,1093.479980,1102.329956,1102.329956,1338800 119 | 2019-06-20,1119.989990,1120.119995,1104.739990,1111.420044,1111.420044,1262000 120 | 2019-06-21,1109.239990,1124.109985,1108.079956,1121.880005,1121.880005,1947600 121 | 2019-06-24,1119.609985,1122.000000,1111.010010,1115.520020,1115.520020,1395600 122 | 2019-06-25,1112.660034,1114.349976,1083.800049,1086.349976,1086.349976,1546900 123 | 2019-06-26,1086.500000,1092.969971,1072.239990,1079.800049,1079.800049,1810900 124 | 2019-06-27,1084.000000,1087.099976,1075.290039,1076.010010,1076.010010,1004300 125 | 2019-06-28,1076.390015,1081.000000,1073.369995,1080.910034,1080.910034,1693200 126 | 2019-07-01,1098.000000,1107.579956,1093.703003,1097.949951,1097.949951,1436300 127 | 2019-07-02,1102.239990,1111.770020,1098.170044,1111.250000,1111.250000,991600 128 | 2019-07-03,1117.410034,1126.760010,1113.859985,1121.579956,1121.579956,767000 129 | 2019-07-05,1117.800049,1132.880005,1116.140015,1131.589966,1131.589966,1264300 130 | 2019-07-08,1125.170044,1125.979980,1111.209961,1116.349976,1116.349976,1236400 131 | 2019-07-09,1111.800049,1128.025024,1107.170044,1124.829956,1124.829956,1330400 132 | 2019-07-10,1131.219971,1142.050049,1130.969971,1140.479980,1140.479980,1208800 133 | 2019-07-11,1143.250000,1153.069946,1139.579956,1144.209961,1144.209961,1195500 134 | 2019-07-12,1143.989990,1147.339966,1138.780029,1144.900024,1144.900024,864000 135 | 2019-07-15,1146.859985,1150.819946,1139.400024,1150.339966,1150.339966,903800 136 | 2019-07-16,1146.000000,1158.579956,1145.000000,1153.579956,1153.579956,1238800 137 | 2019-07-17,1150.969971,1158.359985,1145.770020,1146.349976,1146.349976,1170000 138 | 2019-07-18,1141.739990,1147.604980,1132.729980,1146.329956,1146.329956,1291300 139 | 2019-07-19,1148.189941,1151.140015,1129.619995,1130.099976,1130.099976,1647200 140 | 2019-07-22,1133.449951,1139.250000,1124.239990,1138.069946,1138.069946,1301500 141 | 2019-07-23,1144.000000,1146.900024,1131.800049,1146.209961,1146.209961,1093700 142 | 2019-07-24,1131.900024,1144.000000,1126.989990,1137.810059,1137.810059,1589800 143 | 2019-07-25,1137.819946,1141.699951,1120.920044,1132.119995,1132.119995,2209800 144 | 2019-07-26,1224.040039,1265.550049,1224.000000,1250.410034,1250.410034,4805800 145 | 2019-07-29,1241.050049,1247.369995,1228.229980,1239.410034,1239.410034,2223700 146 | 2019-07-30,1225.410034,1234.869995,1223.300049,1225.140015,1225.140015,1453300 147 | 2019-07-31,1223.000000,1234.000000,1207.764038,1216.680054,1216.680054,1725500 148 | 2019-08-01,1214.030029,1234.109985,1205.719971,1209.010010,1209.010010,1698500 149 | 2019-08-02,1200.739990,1206.900024,1188.939941,1193.989990,1193.989990,1645100 150 | 2019-08-05,1170.040039,1175.239990,1140.140015,1152.319946,1152.319946,2597500 151 | 2019-08-06,1163.310059,1179.959961,1160.000000,1169.949951,1169.949951,1709400 152 | 2019-08-07,1156.000000,1178.444946,1149.624023,1173.989990,1173.989990,1444300 153 | 2019-08-08,1182.829956,1205.010010,1173.020020,1204.800049,1204.800049,1468000 154 | 2019-08-09,1197.989990,1203.880005,1183.603027,1188.010010,1188.010010,1065700 155 | 2019-08-12,1179.209961,1184.959961,1167.671997,1174.709961,1174.709961,1003000 156 | 2019-08-13,1171.459961,1204.780029,1171.459961,1197.270020,1197.270020,1294400 157 | 2019-08-14,1176.310059,1182.300049,1160.540039,1164.290039,1164.290039,1578700 158 | 2019-08-15,1163.500000,1175.839966,1162.109985,1167.260010,1167.260010,1218700 159 | 2019-08-16,1179.550049,1182.719971,1171.810059,1177.599976,1177.599976,1313300 160 | 2019-08-19,1190.089966,1206.989990,1190.089966,1198.449951,1198.449951,1231600 161 | 2019-08-20,1195.250000,1196.060059,1182.109985,1182.689941,1182.689941,915500 162 | 2019-08-21,1193.150024,1199.000000,1187.430054,1191.250000,1191.250000,740700 163 | 2019-08-22,1194.069946,1198.011963,1178.579956,1189.530029,1189.530029,947500 164 | 2019-08-23,1181.989990,1194.079956,1147.750000,1151.290039,1151.290039,1687000 165 | 2019-08-26,1157.260010,1169.469971,1152.959961,1168.890015,1168.890015,1226100 166 | 2019-08-27,1180.530029,1182.400024,1161.449951,1167.839966,1167.839966,1077200 167 | 2019-08-28,1161.709961,1176.420044,1157.300049,1171.020020,1171.020020,802000 168 | 2019-08-29,1181.119995,1196.060059,1181.119995,1192.849976,1192.849976,1088400 169 | 2019-08-30,1198.500000,1198.500000,1183.802979,1188.099976,1188.099976,1129800 170 | 2019-09-03,1177.030029,1186.890015,1163.199951,1168.390015,1168.390015,1479900 171 | 2019-09-04,1176.709961,1183.479980,1171.000000,1181.410034,1181.410034,1068900 172 | 2019-09-05,1191.530029,1213.040039,1191.530029,1211.380005,1211.380005,1408100 173 | 2019-09-06,1208.130005,1212.015015,1202.521973,1204.930054,1204.930054,1072100 174 | 2019-09-09,1204.000000,1220.000000,1192.619995,1204.410034,1204.410034,1471900 175 | 2019-09-10,1195.150024,1210.000000,1194.579956,1206.000000,1206.000000,1260100 176 | 2019-09-11,1203.410034,1222.599976,1202.199951,1220.170044,1220.170044,1307000 177 | 2019-09-12,1224.300049,1241.859985,1223.020020,1234.250000,1234.250000,1725900 178 | 2019-09-13,1231.349976,1240.880005,1227.010010,1239.560059,1239.560059,1301400 179 | 2019-09-16,1229.520020,1239.560059,1225.609985,1231.300049,1231.300049,1053300 180 | 2019-09-17,1230.400024,1235.000000,1223.689941,1229.150024,1229.150024,955100 181 | 2019-09-18,1227.510010,1235.609985,1216.530029,1232.410034,1232.410034,1135100 182 | 2019-09-19,1232.060059,1244.439941,1232.020020,1238.709961,1238.709961,996000 183 | 2019-09-20,1233.119995,1243.319946,1223.079956,1229.930054,1229.930054,2270000 184 | 2019-09-23,1226.000000,1239.089966,1224.170044,1234.030029,1234.030029,1062400 185 | 2019-09-24,1240.000000,1246.739990,1210.680054,1218.760010,1218.760010,1583200 186 | 2019-09-25,1215.819946,1248.300049,1210.089966,1246.520020,1246.520020,1453000 187 | 2019-09-26,1241.959961,1245.000000,1232.267944,1241.390015,1241.390015,1538000 188 | 2019-09-27,1243.010010,1244.020020,1214.449951,1225.089966,1225.089966,1353900 189 | 2019-09-30,1220.969971,1226.000000,1212.300049,1219.000000,1219.000000,1404100 190 | 2019-10-01,1219.000000,1231.229980,1203.579956,1205.099976,1205.099976,1273500 191 | 2019-10-02,1196.979980,1196.979980,1171.290039,1176.630005,1176.630005,1615100 192 | 2019-10-03,1180.000000,1189.060059,1162.430054,1187.829956,1187.829956,1621200 193 | 2019-10-04,1191.890015,1211.439941,1189.170044,1209.000000,1209.000000,1162400 194 | 2019-10-07,1204.400024,1218.203979,1203.750000,1207.680054,1207.680054,842900 195 | 2019-10-08,1197.589966,1206.079956,1189.010010,1189.130005,1189.130005,1039300 196 | 2019-10-09,1199.349976,1208.349976,1197.630005,1202.310059,1202.310059,867700 197 | 2019-10-10,1198.579956,1215.000000,1197.339966,1208.670044,1208.670044,846600 198 | 2019-10-11,1222.209961,1228.390015,1213.739990,1215.449951,1215.449951,1272700 199 | 2019-10-14,1212.339966,1226.329956,1211.760010,1217.140015,1217.140015,867500 200 | 2019-10-15,1220.400024,1247.329956,1220.400024,1243.010010,1243.010010,1381700 201 | 2019-10-16,1241.170044,1254.739990,1238.449951,1243.640015,1243.640015,1094600 202 | 2019-10-17,1250.930054,1263.324951,1249.939941,1253.069946,1253.069946,952400 203 | 2019-10-18,1253.459961,1258.890015,1241.079956,1245.489990,1245.489990,1352800 204 | 2019-10-21,1252.260010,1254.629028,1240.599976,1246.150024,1246.150024,1027200 205 | 2019-10-22,1247.849976,1250.599976,1241.380005,1242.800049,1242.800049,1023800 206 | 2019-10-23,1242.359985,1259.890015,1242.359985,1259.130005,1259.130005,911500 207 | 2019-10-24,1260.900024,1264.000000,1253.714966,1260.989990,1260.989990,1028100 208 | 2019-10-25,1251.030029,1269.599976,1250.010010,1265.130005,1265.130005,1213100 209 | 2019-10-28,1275.449951,1299.310059,1272.540039,1290.000000,1290.000000,2613200 210 | 2019-10-29,1276.229980,1281.589966,1257.212036,1262.619995,1262.619995,1886400 211 | 2019-10-30,1252.969971,1269.359985,1252.000000,1261.290039,1261.290039,1408900 212 | 2019-10-31,1261.280029,1267.670044,1250.843018,1260.109985,1260.109985,1455700 213 | 2019-11-01,1265.000000,1274.619995,1260.500000,1273.739990,1273.739990,1670100 214 | 2019-11-04,1276.449951,1294.130005,1276.354980,1291.369995,1291.369995,1501000 215 | 2019-11-05,1292.890015,1298.930054,1291.229004,1292.030029,1292.030029,1282700 216 | 2019-11-06,1289.459961,1293.729980,1282.500000,1291.800049,1291.800049,1152700 217 | 2019-11-07,1294.280029,1323.739990,1294.244995,1308.859985,1308.859985,2030000 218 | 2019-11-08,1305.280029,1318.000000,1304.364990,1311.369995,1311.369995,1251400 219 | 2019-11-11,1303.180054,1306.425049,1297.410034,1299.189941,1299.189941,1011900 220 | 2019-11-12,1300.000000,1310.000000,1295.770020,1298.800049,1298.800049,1085900 221 | 2019-11-13,1294.069946,1304.300049,1293.510010,1298.000000,1298.000000,826700 222 | 2019-11-14,1297.500000,1317.000000,1295.650024,1311.459961,1311.459961,1193500 223 | 2019-11-15,1318.939941,1334.880005,1314.280029,1334.869995,1334.869995,1782600 224 | 2019-11-18,1332.219971,1335.529053,1317.500000,1320.699951,1320.699951,1487400 225 | 2019-11-19,1327.699951,1327.699951,1312.800049,1315.459961,1315.459961,1269200 226 | 2019-11-20,1311.739990,1315.000000,1291.150024,1303.050049,1303.050049,1308600 227 | 2019-11-21,1301.479980,1312.589966,1293.000000,1301.349976,1301.349976,995500 228 | 2019-11-22,1305.619995,1308.729980,1291.410034,1295.339966,1295.339966,1385700 229 | 2019-11-25,1299.180054,1311.310059,1298.130005,1306.689941,1306.689941,1036200 230 | 2019-11-26,1309.859985,1314.800049,1305.089966,1313.550049,1313.550049,1069700 231 | 2019-11-27,1315.000000,1318.359985,1309.630005,1312.989990,1312.989990,995600 232 | 2019-11-29,1307.119995,1310.204956,1303.969971,1304.959961,1304.959961,587000 233 | 2019-12-02,1301.000000,1305.829956,1281.000000,1289.920044,1289.920044,1510900 234 | 2019-12-03,1279.569946,1298.461060,1279.000000,1295.280029,1295.280029,1143800 235 | 2019-12-04,1307.010010,1325.800049,1304.869995,1320.540039,1320.540039,1537500 236 | 2019-12-05,1328.000000,1329.358032,1316.439941,1328.130005,1328.130005,1212700 237 | 2019-12-06,1333.439941,1344.000000,1333.439941,1340.619995,1340.619995,1314800 238 | 2019-12-09,1338.040039,1359.449951,1337.839966,1343.560059,1343.560059,1354300 239 | 2019-12-10,1341.500000,1349.974976,1336.040039,1344.660034,1344.660034,1094100 240 | 2019-12-11,1350.839966,1351.199951,1342.670044,1345.020020,1345.020020,850400 241 | 2019-12-12,1345.939941,1355.775024,1340.500000,1350.270020,1350.270020,1281000 242 | 2019-12-13,1347.949951,1353.093018,1343.869995,1347.829956,1347.829956,1549600 243 | 2019-12-16,1356.500000,1364.680054,1352.670044,1361.170044,1361.170044,1397300 244 | 2019-12-17,1362.890015,1365.000000,1351.322998,1355.119995,1355.119995,1854000 245 | 2019-12-18,1356.599976,1360.469971,1351.000000,1352.619995,1352.619995,1522600 246 | 2019-12-19,1351.819946,1358.099976,1348.984985,1356.040039,1356.040039,1469900 247 | 2019-12-20,1363.349976,1363.640015,1349.000000,1349.589966,1349.589966,3315000 248 | 2019-12-23,1355.869995,1359.800049,1346.510010,1348.839966,1348.839966,883100 249 | 2019-12-24,1348.500000,1350.260010,1342.780029,1343.560059,1343.560059,347500 250 | 2019-12-26,1346.170044,1361.327026,1344.469971,1360.400024,1360.400024,667500 251 | 2019-12-27,1362.989990,1364.530029,1349.310059,1351.890015,1351.890015,1038400 252 | 2019-12-30,1350.000000,1353.000000,1334.020020,1336.140015,1336.140015,1050900 253 | -------------------------------------------------------------------------------- /visualize.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Visualization: Trading Session" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import pandas as pd\n", 17 | "import numpy as np\n", 18 | "\n", 19 | "import altair as alt\n", 20 | "import seaborn as sns" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "### 1. Define parameters and Load model" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 3, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "from trading_bot.agent import Agent\n", 37 | "\n", 38 | "model_name = 'model_GOOG_50'\n", 39 | "test_stock = 'data/GOOG_2019.csv'\n", 40 | "window_size = 10\n", 41 | "debug = True\n", 42 | "\n", 43 | "agent = Agent(window_size, pretrained=True, model_name=model_name)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "### 2. Load test data" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 4, 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "data": { 60 | "text/html": [ 61 | "
\n", 62 | "\n", 75 | "\n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | "
dateactual
02019-01-021045.849976
12019-01-031016.059998
22019-01-041070.709961
32019-01-071068.390015
42019-01-081076.280029
\n", 111 | "
" 112 | ], 113 | "text/plain": [ 114 | " date actual\n", 115 | "0 2019-01-02 1045.849976\n", 116 | "1 2019-01-03 1016.059998\n", 117 | "2 2019-01-04 1070.709961\n", 118 | "3 2019-01-07 1068.390015\n", 119 | "4 2019-01-08 1076.280029" 120 | ] 121 | }, 122 | "execution_count": 4, 123 | "metadata": {}, 124 | "output_type": "execute_result" 125 | } 126 | ], 127 | "source": [ 128 | "# read csv into dataframe\n", 129 | "df = pd.read_csv(test_stock)\n", 130 | "# filter out the desired features\n", 131 | "df = df[['Date', 'Adj Close']]\n", 132 | "# rename feature column names\n", 133 | "df = df.rename(columns={'Adj Close': 'actual', 'Date': 'date'})\n", 134 | "# convert dates from object to DateTime type\n", 135 | "dates = df['date']\n", 136 | "dates = pd.to_datetime(dates, infer_datetime_format=True)\n", 137 | "df['date'] = dates\n", 138 | "\n", 139 | "df.head()" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "### 3. Running Eval" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 8, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stderr", 156 | "output_type": "stream", 157 | "text": [ 158 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG switching to TensorFlow for CPU\n", 159 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1057.19\n", 160 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1080.97\n", 161 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1089.90 | Position: +$32.71\n", 162 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1098.26 | Position: +$17.29\n", 163 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1073.90\n", 164 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1090.99 | Position: +$17.09\n", 165 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1098.71\n", 166 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1095.06\n", 167 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1095.01\n", 168 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1121.37 | Position: +$22.66\n", 169 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1120.16\n", 170 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1113.65\n", 171 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1118.56\n", 172 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1113.80\n", 173 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1096.97\n", 174 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1115.13 | Position: +$20.07\n", 175 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1116.05 | Position: +$21.04\n", 176 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1119.92 | Position: -$0.24\n", 177 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1140.99 | Position: +$27.34\n", 178 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1147.80 | Position: +$29.24\n", 179 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1162.03 | Position: +$48.23\n", 180 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1157.86 | Position: +$60.89\n", 181 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1185.55\n", 182 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1184.46\n", 183 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1184.26 | Position: -$1.29\n", 184 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1198.85\n", 185 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1223.97 | Position: +$39.51\n", 186 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1231.54 | Position: +$32.69\n", 187 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1193.00\n", 188 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1184.62 | Position: -$8.38\n", 189 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1173.02\n", 190 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1168.49 | Position: -$4.53\n", 191 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1207.15\n", 192 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1203.84\n", 193 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1197.25\n", 194 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1202.16 | Position: -$4.99\n", 195 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1204.62 | Position: +$0.78\n", 196 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1217.87 | Position: +$20.62\n", 197 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1162.61\n", 198 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1185.40 | Position: +$22.79\n", 199 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1174.10\n", 200 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1166.27\n", 201 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1164.27 | Position: -$9.83\n", 202 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1120.44\n", 203 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1164.21\n", 204 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1178.98\n", 205 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1149.63\n", 206 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1151.42 | Position: -$14.85\n", 207 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1140.77 | Position: +$20.33\n", 208 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1133.47\n", 209 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1134.15\n", 210 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1116.46\n", 211 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1117.95\n", 212 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1103.63\n", 213 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1036.23\n", 214 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1053.05 | Position: -$111.16\n", 215 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1042.22\n", 216 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1044.34\n", 217 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1080.38 | Position: -$98.60\n", 218 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1078.72\n", 219 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1077.03 | Position: -$72.60\n", 220 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1088.77\n", 221 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1085.35 | Position: -$48.12\n", 222 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1092.50 | Position: -$41.65\n", 223 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1103.60\n", 224 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1102.33 | Position: -$14.13\n", 225 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1111.42 | Position: -$6.53\n", 226 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1121.88\n", 227 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1115.52\n", 228 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1086.35\n", 229 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1079.80\n", 230 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1076.01\n", 231 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1080.91\n", 232 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1097.95 | Position: -$5.68\n", 233 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1111.25\n", 234 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1121.58 | Position: +$85.35\n", 235 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1131.59 | Position: +$89.37\n", 236 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1116.35\n", 237 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1124.83 | Position: +$80.49\n", 238 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1140.48 | Position: +$61.76\n", 239 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1144.21 | Position: +$55.44\n", 240 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1144.90 | Position: +$41.30\n", 241 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1150.34 | Position: +$28.46\n", 242 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1153.58 | Position: +$38.06\n", 243 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1146.35 | Position: +$60.00\n", 244 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1146.33 | Position: +$66.53\n", 245 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1130.10 | Position: +$54.09\n", 246 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1138.07 | Position: +$57.16\n", 247 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1146.21 | Position: +$34.96\n", 248 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1137.81\n", 249 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1132.12 | Position: +$15.77\n", 250 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1250.41 | Position: +$112.60\n", 251 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1225.14\n", 252 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1216.68\n", 253 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1209.01\n", 254 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1193.99\n", 255 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1173.99\n", 256 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1204.80 | Position: -$20.34\n", 257 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1188.01\n", 258 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1197.27\n", 259 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1164.29\n", 260 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1167.26\n", 261 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1177.60\n", 262 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1198.45 | Position: -$18.23\n", 263 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1182.69 | Position: -$26.32\n", 264 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1189.53\n", 265 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1151.29 | Position: -$42.70\n", 266 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1168.89\n", 267 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1167.84 | Position: -$6.15\n", 268 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1171.02 | Position: -$16.99\n", 269 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1192.85 | Position: -$4.42\n", 270 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1188.10 | Position: +$23.81\n", 271 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1168.39 | Position: +$1.13\n", 272 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1181.41 | Position: +$3.81\n", 273 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1211.38 | Position: +$21.85\n", 274 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1204.93 | Position: +$36.04\n", 275 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1204.41\n", 276 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1206.00 | Position: +$1.59\n", 277 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1229.15\n", 278 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1232.41 | Position: +$3.26\n", 279 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1225.09\n", 280 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1219.00 | Position: -$6.09\n", 281 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1209.00\n", 282 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1207.68 | Position: -$1.32\n", 283 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1189.13\n", 284 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1202.31\n", 285 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1208.67 | Position: +$19.54\n", 286 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1215.45\n", 287 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1243.01 | Position: +$40.70\n", 288 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1243.64 | Position: +$28.19\n", 289 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1245.49\n", 290 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Buy at: $1246.15\n", 291 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1242.80 | Position: -$2.69\n", 292 | "2020-01-11 01:09:29 192.168.1.14 root[4294] DEBUG Sell at: $1259.13 | Position: +$12.98\n", 293 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1291.37\n", 294 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1292.03 | Position: +$0.66\n", 295 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1303.05\n", 296 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1301.35\n", 297 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1295.34\n", 298 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1313.55\n", 299 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1312.99\n", 300 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1304.96\n", 301 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1289.92\n", 302 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1295.28 | Position: -$7.77\n", 303 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1328.13 | Position: +$26.78\n", 304 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1340.62 | Position: +$45.28\n", 305 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1343.56 | Position: +$30.01\n", 306 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1344.66 | Position: +$31.67\n", 307 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1345.02 | Position: +$40.06\n", 308 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1350.27 | Position: +$60.35\n", 309 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Buy at: $1348.84\n", 310 | "2020-01-11 01:09:30 192.168.1.14 root[4294] DEBUG Sell at: $1343.56 | Position: -$5.28\n", 311 | "2020-01-11 01:09:30 192.168.1.14 root[4294] INFO model_GOOG_50: +$1141.45\n", 312 | "\n" 313 | ] 314 | } 315 | ], 316 | "source": [ 317 | "import logging\n", 318 | "import coloredlogs\n", 319 | "\n", 320 | "from trading_bot.utils import show_eval_result, switch_k_backend_device, get_stock_data\n", 321 | "from trading_bot.methods import evaluate_model\n", 322 | "\n", 323 | "coloredlogs.install(level='DEBUG')\n", 324 | "switch_k_backend_device()\n", 325 | "\n", 326 | "test_data = get_stock_data(test_stock)\n", 327 | "initial_offset = test_data[1] - test_data[0]\n", 328 | "\n", 329 | "test_result, history = evaluate_model(agent, test_data, window_size, debug)\n", 330 | "show_eval_result(model_name, test_result, initial_offset)" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "### 4. Visualize" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 9, 343 | "metadata": {}, 344 | "outputs": [], 345 | "source": [ 346 | "def visualize(df, history, title=\"trading session\"):\n", 347 | " # add history to dataframe\n", 348 | " position = [history[0][0]] + [x[0] for x in history]\n", 349 | " actions = ['HOLD'] + [x[1] for x in history]\n", 350 | " df['position'] = position\n", 351 | " df['action'] = actions\n", 352 | " \n", 353 | " # specify y-axis scale for stock prices\n", 354 | " scale = alt.Scale(domain=(min(min(df['actual']), min(df['position'])) - 50, max(max(df['actual']), max(df['position'])) + 50), clamp=True)\n", 355 | " \n", 356 | " # plot a line chart for stock positions\n", 357 | " actual = alt.Chart(df).mark_line(\n", 358 | " color='green',\n", 359 | " opacity=0.5\n", 360 | " ).encode(\n", 361 | " x='date:T',\n", 362 | " y=alt.Y('position', axis=alt.Axis(format='$.2f', title='Price'), scale=scale)\n", 363 | " ).interactive(\n", 364 | " bind_y=False\n", 365 | " )\n", 366 | " \n", 367 | " # plot the BUY and SELL actions as points\n", 368 | " points = alt.Chart(df).transform_filter(\n", 369 | " alt.datum.action != 'HOLD'\n", 370 | " ).mark_point(\n", 371 | " filled=True\n", 372 | " ).encode(\n", 373 | " x=alt.X('date:T', axis=alt.Axis(title='Date')),\n", 374 | " y=alt.Y('position', axis=alt.Axis(format='$.2f', title='Price'), scale=scale),\n", 375 | " color='action'\n", 376 | " ).interactive(bind_y=False)\n", 377 | "\n", 378 | " # merge the two charts\n", 379 | " chart = alt.layer(actual, points, title=title).properties(height=300, width=1000)\n", 380 | " \n", 381 | " return chart" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "execution_count": 10, 387 | "metadata": {}, 388 | "outputs": [ 389 | { 390 | "data": { 391 | "text/html": [ 392 | "\n", 393 | "
\n", 394 | "" 439 | ], 440 | "text/plain": [ 441 | "alt.LayerChart(...)" 442 | ] 443 | }, 444 | "execution_count": 10, 445 | "metadata": {}, 446 | "output_type": "execute_result" 447 | } 448 | ], 449 | "source": [ 450 | "chart = visualize(df, history, title=test_stock)\n", 451 | "chart" 452 | ] 453 | }, 454 | { 455 | "cell_type": "code", 456 | "execution_count": null, 457 | "metadata": {}, 458 | "outputs": [], 459 | "source": [] 460 | } 461 | ], 462 | "metadata": { 463 | "kernelspec": { 464 | "display_name": "Python 3", 465 | "language": "python", 466 | "name": "python3" 467 | }, 468 | "language_info": { 469 | "codemirror_mode": { 470 | "name": "ipython", 471 | "version": 3 472 | }, 473 | "file_extension": ".py", 474 | "mimetype": "text/x-python", 475 | "name": "python", 476 | "nbconvert_exporter": "python", 477 | "pygments_lexer": "ipython3", 478 | "version": "3.6.8" 479 | } 480 | }, 481 | "nbformat": 4, 482 | "nbformat_minor": 4 483 | } 484 | --------------------------------------------------------------------------------