Notebook
In [27]:
# Step One: The Setup
In [28]:
import zipline
import pytz
from datetime import datetime
import matplotlib.pyplot as pyplot
from collections import defaultdict

from zipline import TradingAlgorithm  
from zipline.api import order_target, record, symbol, history, order_target_percent, order, schedule_function  
from zipline.api import attach_pipeline, date_rules, time_rules, pipeline_output  
import numpy as np
import pandas as pd

long_period = 50
short_period = 5

def initialize(context):
    """
    Called once at the start of the algorithm.
    """   
    context.stock = symbol('SPY')
    context.long_period = long_period
    context.short_period = short_period
    context.long_entry = False
    context.long_exit = False
    
    # Rebalance every day, 1 hour after market open.
    schedule_function(entry_long, date_rules.every_day(), time_rules.market_open(hours=1, minutes=30))
    schedule_function(exit_long, date_rules.every_day(), time_rules.market_open(hours=1))

def before_trading_start(context, data):
    """
    Called every day before market open.
    """
    hist = data.history(context.stock, 'price', context.long_period+2, '1d')
    sma_long_list = talib.SMA(hist, context.long_period)
    context.sma_long = sma_long = sma_long_list[-1]
    
    sma_short_list = talib.SMA(hist, context.short_period)
    context.sma_short = sma_short = sma_short_list[-1]
    sma_short_off = sma_short_list[-2]
    
    context.long_entry = (sma_short_off <= sma_long) & (sma_short > sma_long)
    context.long_exit = (sma_short_off >= sma_long) & (sma_short < sma_long)

def entry_long(context,data):
    """
    Execute orders according to our schedule_function() timing. 
    """
    if context.long_entry:
        if context.stock not in context.portfolio.positions:
            order_target_percent(context.stock, 1)
            context.long_entry = False

def exit_long(context,data):
    """
    Execute orders according to our schedule_function() timing. 
    """
    if context.long_exit:
        if context.stock in context.portfolio.positions:
            order_target_percent(context.stock, 0)
            context.long_exit = False 
            
In [29]:
"""
This cell is going to load in the data, run the algorithm, and print out the Sharpe Ratio
"""

data = get_pricing(
    'XIV',
    start_date='2017-01-01',
    end_date = '2017-12-15',
    frequency='daily'
)

algo_obj = TradingAlgorithm(
    initialize=initialize, 
)

#: See this perf_manual object? I'm going to use that to get ending portfolio value
perf_manual = algo_obj.run(data.transpose(2,1,0))

#: Get the sharpe ratio
sharpe = (perf_manual.returns.mean()*252)/(perf_manual.returns.std() * np.sqrt(252))
print "The Sharpe ratio is %0.6f" % sharpe

RemoteDataErrorTraceback (most recent call last)
<ipython-input-29-f48e4e0d1704> in <module>()
     11 
     12 algo_obj = TradingAlgorithm(
---> 13     initialize=initialize,
     14 )
     15 

/build/src/qexec_repo/zipline_repo/zipline/algorithm.pyc in __init__(self, *args, **kwargs)
    272 
    273         if self.trading_environment is None:
--> 274             self.trading_environment = TradingEnvironment()
    275 
    276         # Update the TradingEnvironment with the provided asset metadata

/build/src/qexec_repo/zipline_repo/zipline/finance/trading.pyc in __init__(self, load, bm_symbol, exchange_tz, trading_calendar, asset_db_path, future_chain_predicates, environ)
     97             trading_calendar.day,
     98             trading_calendar.schedule.index,
---> 99             self.bm_symbol,
    100         )
    101 

/build/src/qexec_repo/zipline_repo/zipline/data/loader.pyc in load_market_data(trading_day, trading_days, bm_symbol, environ)
    164         # date so that we can compute returns for the first date.
    165         trading_day,
--> 166         environ,
    167     )
    168     tc = ensure_treasury_data(

/build/src/qexec_repo/zipline_repo/zipline/data/loader.pyc in ensure_benchmark_data(symbol, first_date, last_date, now, trading_day, environ)
    228             symbol,
    229             first_date - trading_day,
--> 230             last_date,
    231         )
    232         data.to_csv(get_data_filepath(filename, environ))

/build/src/qexec_repo/zipline_repo/zipline/data/benchmarks.pyc in get_benchmark_returns(symbol, first_date, last_date)
     48         'google',
     49         first_date,
---> 50         last_date
     51     )
     52 

/usr/local/lib/python2.7/dist-packages/pandas_datareader/data.pyc in DataReader(name, data_source, start, end, retry_count, pause, session)
    103                                  chunksize=25,
    104                                  retry_count=retry_count, pause=pause,
--> 105                                  session=session).read()
    106 
    107     elif data_source == "fred":

/usr/local/lib/python2.7/dist-packages/pandas_datareader/base.pyc in read(self)
    171         # If a single symbol, (e.g., 'GOOG')
    172         if isinstance(self.symbols, (compat.string_types, int)):
--> 173             df = self._read_one_data(self.url, params=self._get_params(self.symbols))
    174         # Or multiple symbols, (e.g., ['GOOG', 'AAPL', 'MSFT'])
    175         elif isinstance(self.symbols, DataFrame):

/usr/local/lib/python2.7/dist-packages/pandas_datareader/base.pyc in _read_one_data(self, url, params)
     78         """ read one data from specified URL """
     79         if self._format == 'string':
---> 80             out = self._read_url_as_StringIO(url, params=params)
     81         elif self._format == 'json':
     82             out = self._get_response(url, params=params).json()

/usr/local/lib/python2.7/dist-packages/pandas_datareader/base.pyc in _read_url_as_StringIO(self, url, params)
     89         Open url (and retry)
     90         """
---> 91         response = self._get_response(url, params=params)
     92         out = StringIO()
     93         if isinstance(response.content, compat.binary_type):

/usr/local/lib/python2.7/dist-packages/pandas_datareader/base.pyc in _get_response(self, url, params)
    115             time.sleep(self.pause)
    116 
--> 117         raise RemoteDataError('Unable to read URL: {0}'.format(url))
    118 
    119     def _read_lines(self, out):

RemoteDataError: Unable to read URL: http://www.google.com/finance/historical
In [ ]:
# Step Two: Running a parameter search
In [ ]:
long_period = [period for period in np.arange(5, 50, 5)]
spy_weights = [weight for weight in np.arange(50, 200, 50)]

#: Create a dictionary to hold all the results of our algorithm run
all_sharpes = defaultdict(dict)

for long_period in long_period:
    for spy_weights in spy_weights:
        
        #: Redfine initialize with new weights
        def initialize(context):
            context.stock = symbol('SPY')
            context.long_period = long_period
            context.short_period = short_period
            context.long_entry = False
            context.long_exit = False
    
            # Rebalance every day, 1 hour after market open.
            schedule_function(entry_long, date_rules.every_day(), time_rules.market_open(hours=1, minutes=30))
            schedule_function(exit_long, date_rules.every_day(), time_rules.market_open(hours=1))

        algo_obj = TradingAlgorithm(
            initialize=initialize, 
        )
        perf_manual = algo_obj.run(data.transpose(2,1,0))
        sharpe = (perf_manual.returns.mean()*252)/(perf_manual.returns.std() * np.sqrt(252))
        
        #: Add the result to our dict
        all_sharpes[aapl_weight][spy_weight] = sharpe

all_sharpes = pd.DataFrame(all_sharpes)
all_sharpes.index.name = "long_period"
all_sharpes.columns.name = "short_period"

Step Three: Plot our results

In [ ]:
import matplotlib.pyplot as pyplot

def heat_map(df):
    """
    This creates our heatmap using our sharpe ratio dataframe
    """
    fig = pyplot.figure()
    ax = fig.add_subplot(111)
    axim = ax.imshow(df.values,cmap = pyplot.get_cmap('RdYlGn'), interpolation = 'nearest')
    ax.set_xlabel(df.columns.name)
    ax.set_xticks(np.arange(len(df.columns)))
    ax.set_xticklabels(list(df.columns))
    ax.set_ylabel(df.index.name)
    ax.set_yticks(np.arange(len(df.index)))
    ax.set_yticklabels(list(df.index))
    ax.set_title("Sharpe Ratios")
    pyplot.colorbar(axim)
    
#: Plot our heatmap
heat_map(all_sharpes)

print all_sharpes