Zipline, Backtesting in Python 2: My First Data Analysis

Zipline, Backtesting in Python 2: My First Data Analysis

Table of contents

In this second part of the Zipline tutorial, we will perform our first data analysis using bundles and build a basic strategy. In the first part, we introduced Zipline and its integration with the Quant Stack and Pipeline.

Zipline pipeline
Zipline: data, pipeline, algorithm, results

What is a Bundle?

A bundle in Zipline is a data source that has been formatted and indexed for use in backtesting. Bundles can contain daily price data, corporate actions (splits, dividends), and other relevant information for backtesting.

Loading a Bundle

To load a bundle in Zipline, we first need to make sure it is available. The most common bundle is the quandl/eod bundle, which contains end-of-day data for US stocks.

from zipline.data import bundles

# List available bundles
bundles.bundles

# Load a bundle
bundle_data = bundles.load('quandl-eod')

$$\text{CAGR} = \left(\frac{V_T}{V_0}\right)^{1/T} - 1$$

$$S = \frac{\mathbb{E}[R_p - R_f]}{\sigma_p}$$

First Data Analysis

Once we have loaded the bundle, we can start exploring the data:

import pandas as pd

# Get the list of available assets
assets = bundle_data.asset_finder.retrieve_all(
    bundle_data.asset_finder.sids
)

# Get data for a specific asset
from zipline.pipeline.data import USEquityPricing
from zipline.pipeline.loaders import USEquityPricingLoader

# Create a pipeline
from zipline.pipeline import Pipeline
from zipline.research import run_pipeline

pipe = Pipeline()
pipe.add(USEquityPricing.close.latest, 'close')

# Run the pipeline
data = run_pipeline(pipe, start='2020-01-01', end='2023-12-31')
print(data.head())

Data Analysis Examples

Correlation of Daily Returns

correlation_matrix = historical_data.pct_change().corr(method='kendall')
plt.figure(figsize=(12, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
plt.title('Correlation Matrix of ETF Returns')
plt.show()

Cumulative Returns Curves

pct_data = historical_data.pct_change()
pct_data.cumsum().plot(figsize=(20, 9), title='Cumulative Returns')
plt.show()

$$\text{CAGR} = \left(\frac{V_T}{V_0}\right)^{1/T} - 1$$

$$S = \frac{\mathbb{E}[R_p - R_f]}{\sigma_p}$$

Building a Basic Strategy

Now that we know how to load data, we can build a basic trading strategy:

from zipline.api import order_target_percent, record, symbol, schedule_function
from zipline.utils.events import date_rules, time_rules

def initialize(context):
    context.asset = symbol('AAPL')
    schedule_function(rebalance, date_rules.every_day(), time_rules.market_open())

def rebalance(context, data):
    order_target_percent(context.asset, 0.5)

def analyze(context, perf):
    import matplotlib.pyplot as plt
    perf.portfolio_value.plot()
    plt.show()

Running the Backtest

To run the backtest, we need to execute the strategy with the loaded data:

from zipline import run_algorithm
import pandas as pd

start = pd.Timestamp('2020-01-01', tz='utc')
end = pd.Timestamp('2023-12-31', tz='utc')

results = run_algorithm(
    start=start,
    end=end,
    initialize=initialize,
    analyze=analyze,
    capital_base=10000,
    bundle='quandl-eod'
)

Conclusion

In this second part, we have learned how to work with bundles in Zipline, perform basic data analysis, and build a simple trading strategy. In the next part, we will explore more advanced strategies and pipeline features.

Jesús Cuesta

Odesa (Ucrania)
Inversor desde 2014. Research desde 2017. He trabajado en diferentes gestoras de capital y Hedgefunds Crypto. Apasionado del codigo, los datos y las finanzas. Actualmente localizado en Ucrania.

You might also like