Introduction to Zipline in Python

Zipline in Python

By Priyanka Sah


Python has emerged as one of the most popular languages for programmers in financial trading, due to its ease of availability, user-friendliness, and the presence of sufficient scientific libraries like Pandas, NumPy, PyAlgoTrade, Pybacktest and more.

Python serves as an excellent choice for automated trading when the trading frequency is low/medium, i.e. for trades which do not last less than a few seconds. It has multiple APIs/Libraries that can be linked to make it optimal, cheaper and allow greater exploratory development of multiple trade ideas.

Learn Algorithmic trading from Experienced Market Practitioners

  • This field is for validation purposes and should be left unchanged.

It is due to these reasons that Python has a very interactive online community of users, who share, reshare, and critically review each other’s work or codes. The two current popular web-based backtesting systems are Quantopian and QuantConnect.

Quantopian makes use of Python (and Zipline) while QuantConnect utilises C#. Both provide a wealth of historical data. Quantopian currently supports live trading with Interactive Brokers, while QuantConnect is working towards live trading.

Zipline is a Python library for trading applications that powers the Quantopian service mentioned above. It is an event-driven system that supports both backtesting and live trading.

In this article, we will learn how to install Zipline and then how to implement Moving Average Crossover strategy and calculate P&L, Portfolio value etc.

This article is divided into the following four sections:

  • Benefits of Zipline
  • Installation (how to install Zipline on local)
  • Structure (format to write code in Zipline),
  • Coding Moving average crossover strategy with Zipline

Benefits of Zipline

  • Ease of use
  • Zipline comes “batteries included” as many common statistics like moving average and linear regression can be readily accessed from within a user-written algorithm.
  • Input of historical data and output of performance statistics are based on Pandas DataFrames to integrate nicely into the existing PyData ecosystem
  • Statistic and machine learning libraries like matplotlib, scipy, statsmodels, and sklearn support development, analysis, and visualization of state-of-the-art trading systems


Using pip

Assuming you have all required non-Python dependencies, you can install Zipline with pip via:

# code
pip install Zipline

Using conda

Another way to install Zipline is via the conda package manager, which comes as part of Anaconda or can be installed via pip install conda.

Once setup, you can install Zipline from our Quantopian channel:

conda install -c Quantopian Zipline


Basic structure

Zipline provide a particular structure to code which includes defining few functions that run the algorithms over a dataset as mentioned below.

from Zipline.api import order, record, symbol
from Zipline.algorithm import TradingAlgorithm
def initialize(context):

def handle_data(context, data):
  order(symbol('AAPL'), 10)
  record(AAPL=data.current(symbol('AAPL'), 'price'))

algo_obj = TradingAlgorithm(initialize=initialize, handle_data=handle_data)
perf_manual =

So, first we have to import some functions we would need in the code. Every Zipline algorithm consists of two functions you have to define:

* initialize(context) and * handle_data(context, data)

Before the start of the algorithm, Zipline calls the initialize() function and passes in a context variable. Context is a global variable that allows you to store variables you need to access from one algorithm iteration to the next.

After the algorithm has been initialized, Zipline calls the handle_data() function once for each event. At every call, it passes the same context variable and an event frame called data containing the current trading bar with open, high, low, and close (OHLC) prices as well as volume for each stock.

All functions commonly used in the algorithm can be found in Zipline.api module. Here we are using order(arg1, arg2) that takes two arguments: a security object, and a number specifying how many stocks you would like to order (if negative, order() will sell/short stocks). In this case, we want to order 10 shares of Apple at each iteration.

Now, the second method record() allows you to save the value of a variable at each iteration. You provide it with a name for the variable together with the variable itself. After the algorithm finished running you can all the variables you recorded, we will learn how to do that.

To run the algorithm, you would need to call TradingAlgorithm() that uses two arguments: initialize function and handle_data.  Then, call run method using data as argument on which algorithm will run (data is panda data frame that stores the stocks prices)

run() first calls the initialize() function, and then streams the historical stock price day-by-day through handle_data(). After each call to handle_data() we instruct Zipline to order 10 stocks of AAPL.

How to code Moving average crossover strategy with Zipline

Moving Averages

It is the simple average of a security over a defined number of time periods.


Moving average crossovers are a common way traders can use Moving Averages. A crossover occurs when a faster Moving Average (i.e. a shorter period Moving Average) crosses either above a slower Moving Average (i.e. a longer period Moving Average) which is considered a bullish crossover or below which is considered a bearish crossover.

Now we will learn how to implement this strategy using Zipline. To import libraries and initialize variables that will be used in the algorithm.

The code is divided into 5 parts

  • Initialization
  • Initialize method
  • handle_data method
  • Strategy logic
  • Run Algo



import pytz
from datetime import datetime
from Zipline.api import order, symbol, record, order_target
from Zipline.algorithm import TradingAlgorithm
from Zipline.utils.factory import load_bars_from_yahoo
import pyexcel

# Load data manually from Yahoo! finance
start = datetime(2011, 1, 1, 0, 0, 0, 0, pytz.utc).date()
end = datetime(2012,1,1,0,0,0,0, pytz.utc).date()

data = load_bars_from_yahoo(stocks=['SPY'], start=start,end=end)

load_bars_from_yahoo() is the function that takes stock and time period for which you want to fetch the data. Here I am using SPY stocks between 2011 to 2012, you can change this according to you.

Initialize method

def initialize(context): = symbol('SPY')

Now we would define initialize function, represents the stock that we are dealing with, in our case its SPY.

handle_data method

def handle_data(context, data):
  MA1 = data[].mavg(50)
  MA2 = data[].mavg(100)
  date = str(data[].datetime)[:10]
  current_price = data[].price
  current_positions = context.portfolio.positions[symbol('SPY')].amount
  cash =
  value = context.portfolio.portfolio_value
  current_pnl = context.portfolio.pnl

handle_data() contains all the operation we want to do, the main code for our algorithm. we need to calculate moving averages for different windows, Zipline gives an inbuilt function mavg() that takes an integer to define the window size.

Also, Zipline automatically calculates current_price, portfolio_value etc. we can just call the variables, in this algorithm, I have calculated current_positions, price, cash, portfolio_value, and the PnL.

Strategy logic

#code (this will come under handle_data function only)
if (MA1 > MA2) and current_positions == 0:
    number_of_shares = int(cash/current_price)
    order(, number_of_shares)
    record(date=date,MA1 = MA1, MA2 = MA2, Price= 

elif (MA1 < MA2) and current_positions != 0:
     order_target(, 0)
     record(date=date,MA1 = MA1, MA2 = MA2, Price= current_price,status="sell",shares="--",PnL=current_pnl,cash=cash,value=value)

    record(date=date,MA1 = MA1, MA2 = MA2, Price= current_price,status="--",shares="--",PnL=current_pnl,cash=cash,value=value)

Now the logic that will place the order for buy or sell depending upon the condition that compares moving averages.

  1. If short moving average is greater than longer one and your current_positions is 0 then you need to calculate the no of shares and place an order
  2. If the short moving average is smaller than the longer one and your current_positions is not 0 then you need to sell all the shares that you have currently.
  3. the third condition is if nothing satisfies then do nothing just record the variables you need to save.


For running this algorithm, you need the following code:

Learn Algorithmic trading from Experienced Market Practitioners

  • This field is for validation purposes and should be left unchanged.

algo_obj = TradingAlgorithm(initialize=initialize,handle_data=handle_data)
perf_manual =

You can plot the graph also using method plot()

Graph for the strategy

graph of moving crossover strategy using zipline

Snapshot of the screen using Zipline

Snapshot of screen in Zipline


We hope that you found this introduction to zipline and implementing a strategy using the same useful. In our next article, we will show you how to import and backtest data in CSV format using Zipline. For building technical indicators using python, here are few examples.

If you are a coder or a tech professional looking to start your own automated trading desk. Learn automated trading from live Interactive lectures by daily-practitioners. Executive Programme in Algorithmic Trading covers training modules like Statistics & Econometrics, Financial Computing & Technology, and Algorithmic & Quantitative Trading. Enroll now!

24 thoughts on “Introduction to Zipline in Python

  1. July 20, 2016

    Paska Reply

    A lot easier with a modern library like backtrader

    import datetime
    import backtrader as bt

    class CrossOverStrat(bt.Strategy):
    params = ((‘stake’, 10), (‘period1’, 50), (‘period2′, 200))

    def __init__(self):
    sma1 = bt.indicators.SMA(self.data0, period=self.p.period1)
    sma2 = bt.indicators.SMA(self.data0, period=self.p.period2)
    self.signal = bt.indicators.CrossOver(sma1, sma2, plot=False)

    def next(self):
    if self.position:
    if self.signal 0:

    fromdate = datetime.datetime(2011, 1, 1)
    todate = datetime.datetime(2011, 12, 31)

    cerebro = bt.Cerebro()

    data0 = bt.feeds.YahooFinanceData(dataname=’YHOO’,
    fromdate=fromdate, todate=todate)

    • November 16, 2017

      Anthony FJ Garner Reply

      Pandas is not a requirement of backtrader….does it do it all under the cover with Numpy? If you want to develop strategies with back trader what Python dependencies can/must you use? Numpy, Math etc these days come with Python, at least if one uses anaconda?

  2. July 20, 2016

    arun Reply

    Nice post. Is it possible to use zipline live for trading with brokers who provide api access other than IB.

    • July 22, 2016

      priyanka Reply

      Any broker that provides python api, can be integrated with this zipline code. I personally have just worked on IB.

  3. July 21, 2016

    Panda Reply

    Thanks for a great post!
    Is it possible to use ZipLine with Futures or FX data?

  4. July 26, 2016

    sameer Reply

    It’s not very clear whether it is buying at the close of current bar or open of next? And indeed how one could make that choice with Zipline? Thanks for the post though – very interesting.

    • August 3, 2016

      priyanka sah Reply

      moving average is calculated on “closing price” of current bar, and no you cant choose the price if u want to use this method only. This method is deprecated so i will suggest you to use .mean(), you can slice the data.history output depending on whether you want to include the current bar, and you can specify open or close depending on what you want.

      • August 4, 2016

        sameer Reply

        Hi Priyanka, actually I was referring to the execution price. Regardless of the indicator used (moving avg, bollinger, whatever)… once you’ve generated a signal and run order(, number_of_shares) … what price is this order being filled at? Does it assume you will buy at the next market open price? Will it buy at the current close?

  5. September 2, 2016

    shrivathsan chandrasekaran Reply

    Quantconnect already supports live trading through Tradier and IB.

  6. January 22, 2017

    Mohamed Amine Guessous Reply


    Very helpful tutorial!!

    Though, I have a problem when I run the code : “zipline.errors.HistoryWindowStartsBeforeData: History window extends before 2011-01-03. To use this history window, start the backtest on or after 2011-03-16.

    the zipline version I have is :
    >>> print zipline.__version__

    please help me!!


  7. January 22, 2017

    Mohamed Amine Guessous Reply


    the solution to the problem is to start the trading after reaching 100 days information in the algo. you can add a parameter i in context and start trading after getting the data nbr 100:

    def initialize(context):

    context.i = 0

    def handle_data(context, data):
    # Skip first 100 days to get full windows
    context.i += 1
    if context.i < 100:

    thanks for all

    great article

  8. January 22, 2017

    Andy Reply

    When I try to run this I get an error….

    perf_manual =
    NameError: name ‘data’ is not defined

    Any ideas? I’m somewhat new to python, have made a few algos on Quantopian but would like to run it locally instead.

    • January 23, 2017

      Priyanka Sah Reply

      You must be missing some line, its clearly saying “data” is not defined, means it is not able to get the data.
      You need to get the data first on which algo_obj(trading algorithm object) will run.
      Define data like this “data = load_bars_from_yahoo(stocks=[‘SPY’], start=start,end=end)”.

  9. January 23, 2017

    Mth Reply

    Can’t manage to install zipline
    Windows 7 Python 3.5
    error: Unable to find vcvarsall.bat
    Seems to be a problem with C compiler from what I understood
    I have Visual Studio 2010 installed
    What do you recommend?

  10. February 5, 2017

    Abhinav Chandra Reply


    Use “Anaconda” with

    conda install -c Quantopian zipline

    use following link for further details

  11. March 9, 2017

    John Reply

    Wow. That is so elegant and logical and clearly explained. Keep it up! I follow up your blog for future post.
    Python developer

  12. August 18, 2017

    Jared Broad Reply supports many brokerages, futures, options, equities, FX and CFD assets.
    We also completely support Python and C# programming (I’m founder of QC).

  13. September 14, 2017

    Thomas Chang Reply


    I happend to come to this pade and it’s quite interessintg.

    I use the Python 3.5.4 and Spyder 3.2.3. I’ve copied and pasted your exampe code to my Spyder and try to run it. But I got error message as follow:

    File “Z:/Eigene_Dateien/Temp/Python/”, line 12, in
    from zipline.utils.factory import load_bars_from_yahoo

    ImportError: cannot import name ‘load_bars_from_yahoo’

    What could be the problem?


    Thomas Chang

  14. September 14, 2017

    Thomas Chang Reply

    I see the ‘load_bars_from_yahoo’ is no anymore in the latest version of zipline-1.1.1. It should be the ‘load_from_yahoo’. (see [1])

    I replace this and run the code. But I get following errors:

    File “C:\Users\a5xprq1\AppData\Local\Continuum\Anaconda3\lib\site-packages\zipline\data\”, line 733, in _get_days_for_window
    self._first_trading_day_loc + bar_count

    HistoryWindowStartsBeforeData: History window extends before {first_trading_day}. To use this history window, start the backtest on or after {suggested_start_day}.

    Any idea?


    • September 19, 2017

      admin Reply

      Hi Thomas,

      In previous comments, Mr. Mohamed Amine Guessous has provided the solution for this error. Request you to take a look.

      We will soon incorporate other changes that you have mentioned in your comments and update the post.

      Thanks a bunch.

  15. September 14, 2017

    Thomas Chang Reply

    Hi priyanka,

    I use Spyder 3.3.2 and Python 3.5.4. I copy and paste your code to the Spyder and try to run it. But I got error that “from Zipline.utils.factory import load_bars_from_yahoo” is not possible. I read the zipline in github and find, in the latest version of zipline-1.1.1 it should be the “rom import load_from_yahoo”. Could you please have a check?

    You said in your post above:
    >> This method is deprecated so i will suggest you to use .mean(), you can slice the data.history …

    I change this as follow:
    MA1 = data.history(, ‘price’, 50, ‘1d’).mean()

    Is this correct?

    It will be very nice if you could update your code because the zipline has a new version.

    Many thanks!



  16. November 16, 2017

    Anthony FJ Garner Reply

    “Can’t manage to install zipline
    Windows 7 Python 3.5
    error: Unable to find vcvarsall.bat”

    I am stunned if this now works on Windows with ease. Delighted but stunned. My partner is a computer scientist working for JP Morgan and he could not manage it – he had to resort to Linux. Anyway I’ll give it another go and see if anything has changed. Zipline is wonderful work but it is way too bloated for many of us. I have every respect for Thomas Wiecki et al but for my simple tastes I prefer a slimmer engine.

Leave a Reply

Your email address will not be published. Required fields are marked *