First of all, thank you to the author Stefan, this book seems to be very comprehensive. I am new in my algorithmic trading journey so this book is quite challenging.
The code has been working for the most part, and I have just ran this piece of zipline code:
%%zipline --start 2015-1-1 --end 2018-1-1 --output single_factor.pickle --no-benchmark --bundle quandl
from zipline.api import (
attach_pipeline,
date_rules,
time_rules,
order_target_percent,
pipeline_output,
record,
schedule_function,
get_open_orders,
calendars
)
from zipline.finance import commission, slippage
from zipline.pipeline import Pipeline, CustomFactor
from zipline.pipeline.factors import Returns, AverageDollarVolume
import numpy as np
import pandas as pd
MONTH = 21
YEAR = 12 * MONTH
N_LONGS = N_SHORTS = 25
VOL_SCREEN = 1000
class MeanReversion(CustomFactor):
"""Compute ratio of latest monthly return to 12m average,
normalized by std dev of monthly returns"""
inputs = [Returns(window_length=MONTH)]
window_length = YEAR
def compute(self, today, assets, out, monthly_returns):
df = pd.DataFrame(monthly_returns)
out[:] = df.iloc[-1].sub(df.mean()).div(df.std())
def compute_factors():
"""Create factor pipeline incl. mean reversion,
filtered by 30d Dollar Volume; capture factor ranks"""
mean_reversion = MeanReversion()
dollar_volume = AverageDollarVolume(window_length=30)
return Pipeline(columns={'longs': mean_reversion.bottom(N_LONGS),
'shorts': mean_reversion.top(N_SHORTS),
'ranking': mean_reversion.rank(ascending=False)},
screen=dollar_volume.top(VOL_SCREEN))
def exec_trades(data, assets, target_percent):
"""Place orders for assets using target portfolio percentage"""
for asset in assets:
if data.can_trade(asset) and not get_open_orders(asset):
order_target_percent(asset, target_percent)
def rebalance(context, data):
"""Compute long, short and obsolete holdings; place trade orders"""
factor_data = context.factor_data
record(factor_data=factor_data.ranking)
assets = factor_data.index
record(prices=data.current(assets, 'price'))
longs = assets[factor_data.longs]
shorts = assets[factor_data.shorts]
divest = set(context.portfolio.positions.keys()) - set(longs.union(shorts))
exec_trades(data, assets=divest, target_percent=0)
exec_trades(data, assets=longs, target_percent=1 / N_LONGS)
exec_trades(data, assets=shorts, target_percent=-1 / N_SHORTS)
def initialize(context):
"""Setup: register pipeline, schedule rebalancing,
and set trading params"""
attach_pipeline(compute_factors(), 'factor_pipeline')
schedule_function(rebalance,
date_rules.week_start(),
time_rules.market_open(),
calendar=calendars.US_EQUITIES)
context.set_commission(commission.PerShare(cost=.01, min_trade_cost=0))
context.set_slippage(slippage.VolumeShareSlippage())
def before_trading_start(context, data):
"""Run factor pipeline"""
context.factor_data = pipeline_output('factor_pipeline')
Questions:
- How is the code computing mean reversion exactly? Is it using technical indicators to compute overbought or oversold levels? How is the code computing cases where the price has deviated too far from the mean?
- What financial instruments are being analyzed? I assume stocks, but what stocks? What kind of data pertaining to stocks? Which tickers? OHLCV or orderbook data?
- Does my output look correct?
period_open period_close pnl capital_used orders long_exposure transactions positions short_exposure starting_exposure ... excess_return treasury_period_return trading_days period_label sharpe algorithm_period_return benchmark_period_return benchmark_volatility factor_data prices
2015-01-02 21:00:00+00:00 2015-01-02 14:31:00+00:00 2015-01-02 21:00:00+00:00 0.000000 0.000000e+00 [] 0.000 [] [] 0.000 0.000 ... 0.0 0.0 1 2015-01 NaN 0.000000 0.0 NaN NaN NaN
2015-01-05 21:00:00+00:00 2015-01-05 14:31:00+00:00 2015-01-05 21:00:00+00:00 0.000000 0.000000e+00 [{'id': '4f98521494d1425c91f1485f915ae278', 'd... 0.000 [] [] 0.000 0.000 ... 0.0 0.0 2 2015-01 NaN 0.000000 0.0 0.0 Equity(0 [A]) 2707.0 Equity(2 [AAL]) ... Equity(0 [A]) 39.800 Equity(2 [AAL])...
2015-01-06 21:00:00+00:00 2015-01-06 14:31:00+00:00 2015-01-06 21:00:00+00:00 -3799.475085 -3.118062e+06 [{'id': '4f98521494d1425c91f1485f915ae278', 'd... 4731525.565 [{'amount': 18433, 'dt': 2015-01-06 21:00:00+0... [{'sid': Equity(749 [CVA]), 'amount': 18433, '... -1617262.705 0.000 ... 0.0 0.0 3 2015-01 -9.165151 -0.000380 0.0 0.0 Equity(0 [A]) 2707.0 Equity(2 [AAL]) ... Equity(0 [A]) 39.800 Equity(2 [AAL])...
2015-01-07 21:00:00+00:00 2015-01-07 14:31:00+00:00 2015-01-07 21:00:00+00:00 12850.580000 0.000000e+00 [] 4757100.850 [] [{'sid': Equity(749 [CVA]), 'amount': 18433, '... -1629987.410 3114262.860 ... 0.0 0.0 4 2015-01 4.933673 0.000905 0.0 0.0 Equity(0 [A]) 2707.0 Equity(2 [AAL]) ... Equity(0 [A]) 39.800 Equity(2 [AAL])...
2015-01-08 21:00:00+00:00 2015-01-08 14:31:00+00:00 2015-01-08 21:00:00+00:00 63721.760000 0.000000e+00 [] 4835941.280 [] [{'sid': Equity(749 [CVA]), 'amount': 18433, '... -1645106.080 3127113.440 ... 0.0 0.0 5 2015-01 8.194658 0.007277 0.0 0.0 Equity(0 [A]) 2707.0 Equity(2 [AAL]) ... Equity(0 [A]) 39.800 Equity(2 [AAL])...
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2017-12-22 21:00:00+00:00 2017-12-22 14:31:00+00:00 2017-12-22 21:00:00+00:00 -16960.030000 0.000000e+00 [] 5266915.040 [] [{'sid': Equity(672 [CPRT]), 'amount': -10147,... -4598653.320 685221.750 ... 0.0 0.0 751 2017-12 0.406793 0.102076 0.0 0.0 Equity(0 [A]) 2393.0 Equity(1 [AA]) ... Equity(0 [A]) 67.66 Equity(1 [AA]) ...
2017-12-26 21:00:00+00:00 2017-12-26 14:31:00+00:00 2017-12-26 21:00:00+00:00 -43497.970000 0.000000e+00 [{'id': '8b268f7c87f64aa29b0ee185f14e14c6', 'd... 5217746.950 [] [{'sid': Equity(672 [CPRT]), 'amount': -10147,... -4592983.200 668261.720 ... 0.0 0.0 752 2017-12 0.391704 0.097727 0.0 0.0 Equity(0 [A]) 2363.0 Equity(1 [AA]) ... Equity(0 [A]) 67.25 Equity(1 [AA]) ...
2017-12-27 21:00:00+00:00 2017-12-27 14:31:00+00:00 2017-12-27 21:00:00+00:00 41248.841483 1.940099e+06 [{'id': '8b268f7c87f64aa29b0ee185f14e14c6', 'd... 3966687.510 [{'amount': 10147, 'dt': 2017-12-27 21:00:00+0... [{'sid': Equity(54 [ADSK]), 'amount': 4230, 'c... -5240774.395 624763.750 ... 0.0 0.0 753 2017-12 0.405300 0.101852 0.0 0.0 Equity(0 [A]) 2363.0 Equity(1 [AA]) ... Equity(0 [A]) 67.25 Equity(1 [AA]) ...
2017-12-28 21:00:00+00:00 2017-12-28 14:31:00+00:00 2017-12-28 21:00:00+00:00 25543.807669 -5.744239e+04 [{'id': 'e452bf2065014f2380e23766eb3f7aec', 'd... 3967663.630 [{'amount': 2082, 'dt': 2017-12-28 21:00:00+00... [{'sid': Equity(54 [ADSK]), 'amount': 4230, 'c... -5158764.315 -1274086.885 ... 0.0 0.0 754 2017-12 0.413599 0.104406 0.0 0.0 Equity(0 [A]) 2363.0 Equity(1 [AA]) ... Equity(0 [A]) 67.25 Equity(1 [AA]) ...
2017-12-29 21:00:00+00:00 2017-12-29 14:31:00+00:00 2017-12-29 21:00:00+00:00 47298.175000 0.000000e+00 [] 3953902.420 [] [{'sid': Equity(54 [ADSK]), 'amount': 4230, 'c... -5097704.930 -1191100.685 ... 0.0 0.0 755 2017-12 0.429063 0.109136 0.0 0.0 Equity(0 [A]) 2363.0 Equity(1 [AA]) ... Equity(0 [A]) 67.25 Equity(1 [AA]) ...
755 rows × 39 columns
Thanks