import zipline.api as algo
from zipline.pipeline import Pipeline
from zipline.pipeline.factors import AverageDollarVolume, Returns
from zipline.finance.execution import MarketOrder
def initialize(context):
"""
Called once at the start of a backtest, and once per day at
the start of live trading.
"""
algo.attach_pipeline(make_pipeline(), 'pipeline')
algo.schedule_function(
rebalance,
algo.date_rules.every_day(),
algo.time_rules.market_close(minutes=30),
)
def make_pipeline():
"""
Create a pipeline that filters by dollar volume and
calculates 1-year return.
"""
pipeline = Pipeline(
columns={
"1y_returns": Returns(window_length=252),
},
screen=AverageDollarVolume(window_length=30) > 10e6
)
return pipeline
def before_trading_start(context, data):
"""
Called every day before market open.
"""
factors = algo.pipeline_output('pipeline')
returns = factors["1y_returns"].sort_values(ascending=False)
context.winners = returns.index[:3]
def rebalance(context, data):
"""
Execute orders according to our schedule_function() timing.
"""
current_prices = data.current(context.winners, "price")
prior_closes = data.history(context.winners, "close", 2, "1d").iloc[0]
intraday_returns = (current_prices - prior_closes) / prior_closes
positions = context.portfolio.positions
for asset, position in positions.items():
if asset not in context.winners:
algo.order_target_value(asset, 0, style=MarketOrder())
for asset in context.winners:
if asset in positions:
continue
if intraday_returns[asset] > 0:
continue
algo.order_target_value(asset, 100e3, style=MarketOrder())