In [1]:
# Imports
from contextlib import contextmanager
from datetime import datetime, timedelta
import sqlite3
import os
from zipline.api import order, order_target, record, symbol
from zipline.finance import commission, slippage
import zipline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
In [2]:
# Access Database
@contextmanager
def db(db_filename='stock.db'):
conn = sqlite3.connect(os.path.join('..', 'data', db_filename), detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = conn.cursor()
yield conn, cur
conn.close()
In [3]:
# Custom Slippage Model
class TradeNearTheOpenSlippageModel(slippage.SlippageModel):
def __init__(self, deviation=0.001):
self.deviation = deviation
def process_order(self, data, order):
rand = min(np.abs(np.random.normal(0, self.deviation)), 1) # Generate a random value thats likely zero (zero=openprice)
open_price = data.current(symbol(stock), 'open')
close_price = data.current(symbol(stock), 'close')
new_price = (close_price - open_price) * rand + open_price
return (new_price, order.amount)
In [4]:
# Perfect Algo (aka already knows the future)
def predict_perfect(stock, date): # ~Perfect~ Predictor
with db() as (conn, cur):
cur.execute("SELECT date, adjclose FROM ticks WHERE stock=? AND date BETWEEN ? AND ? ORDER BY date DESC LIMIT 1",
[stock, (date + timedelta(days=-5)).strftime('%Y-%m-%d'), (date + timedelta(days=0)).strftime('%Y-%m-%d')])
before = cur.fetchall()[0]
cur.execute("SELECT date, adjclose FROM ticks WHERE stock=? AND date BETWEEN ? AND ? ORDER BY date ASC LIMIT 1",
[stock, (date + timedelta(days=1)).strftime('%Y-%m-%d'), (date + timedelta(days=5)).strftime('%Y-%m-%d')])
after = cur.fetchall()[0]
if after[1] > before[1]:
return 1., 0.
else:
return 0., 1.
In [5]:
# Load Stuff
# import pickle, os
# with open(os.path.join('..', 'models', 'toke-tick.pkl'), 'rb') as toke_file:
# toke = pickle.load(toke_file)
from keras.models import load_model
from gensim.models.doc2vec import Doc2Vec
model_type = 'multiheadlineclf'
vec_model = Doc2Vec.load(os.path.join('..', 'models', 'doc2vec-' + model_type + '.doc2vec'))
model = load_model(os.path.join('..', 'models', 'media-headlines-ticks-' + model_type + '.h5'))
In [6]:
# Load Stuff Part 2
# from algoA import predict, correct_sign_acc, model_type
# from keras.models import load_model
# import keras.metrics
# keras.metrics.correct_sign_acc = correct_sign_acc
# model = load_model(os.path.join('..', 'models', 'media-headlines-ticks-' + model_type + '.h5'))
from algoB import predict
In [7]:
# Actual Algo
def predict_deep_nn(stock, date):
# preds, prices = predict(stock, model, toke, current_date=date)
preds = predict(stock, model, vec_model, current_date=date)
return np.mean(preds[:, 0]), np.mean(preds[:, 1])
In [8]:
stock = 'INTC'
def initialize(context):
context.set_commission(commission.PerShare(cost=0, min_trade_cost=1.0))
context.set_slippage(TradeNearTheOpenSlippageModel())
def trade_logic(pred_func, context, data):
date = data.current(symbol(stock), 'last_traded').to_datetime()
up, down = pred_func(stock, date + timedelta(days=0))
shares = context.portfolio.positions[symbol(stock)].amount
if up > .6:
max_shares = context.portfolio.cash // data.current(symbol(stock), 'price')
if max_shares > 0:
order(symbol(stock), max_shares)
elif down > .6:
if shares > 0:
order_target(symbol(stock), 0)
record(stock=data.current(symbol(stock), 'price'))
record(shares=context.portfolio.positions[symbol(stock)].amount)
def handle_data_perfect(context, data):
trade_logic(predict_perfect, context, data)
def handle_data_algo(context, data):
trade_logic(predict_deep_nn, context, data)
start = pd.to_datetime('2018-01-01').tz_localize('US/Eastern')
end = pd.to_datetime('2018-05-8').tz_localize('US/Eastern')
perf_perfect = zipline.run_algorithm(start, end, initialize, 100, handle_data=handle_data_perfect)
perf_algo = zipline.run_algorithm(start, end, initialize, 100, handle_data=handle_data_algo)
In [9]:
f, (ax1, ax2) = plt.subplots(2, 1, figsize=(20, 20), sharex=True)
perf_perfect.portfolio_value.plot(ax=ax1)
perf_algo.portfolio_value.plot(ax=ax1)
ax1.set_ylabel('Portfolio Value')
perf_perfect.stock.plot(ax=ax2)
ax2.set_ylabel('Stock Price')
plt.show()