I have the code below where I'm trying to backtest a portfolio optimization strategy. I'm running the backtest with zipline, and I'm running the code in a jupyter notebook. I'm trying to compare the models performance to the benchmark using the "benchmark_period_return" column in the dataframe I create from reading the pickle file back in after zipline finishes. I tried changing to a different date range in 2019 for my backtest and the benchmark_period_return column all went to 0. I changed back to the original date range I was working with
"start 2015-12-31 --end 2017-12-31"
but it still returns all 0 now for benchmark_period_return. Does anyone see what the issue might be and suggest how to fix it? I'm pretty new to zipline. I've also included the output from the dataframe.
code:
# reading in libraries
%load_ext watermark
%load_ext zipline
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import zipline
import warnings
import pyfolio as pf
import empyrical as ep
from yahoofinancials import YahooFinancials
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt import risk_models
from pypfopt import expected_returns
# import helper functions
import qf_helper_functions as qf
plt.style.use('seaborn')
plt.rcParams['figure.figsize'] = [16, 9]
plt.rcParams['figure.dpi'] = 200
warnings.simplefilter(action='ignore', category=FutureWarning)
%%zipline --start 2015-12-31 --end 2017-12-31 --capital-base 50000.0 -o simple_optimization_30D_rebalance.pkl
# imports
from zipline.api import symbols, record, order_target_percent,set_benchmark,symbol
from zipline.finance import commission
import numpy as np
import pandas as pd
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt import risk_models
from pypfopt import expected_returns
def initialize(context):
context.set_commission(commission.PerShare(cost=0.0, min_trade_cost=0))
context.assets = symbols('TSLA', 'MSFT', 'FB', 'TWTR')
# set_benchmark()
context.n_assets = len(context.assets)
context.window = 252
context.rebalance_period = 30
context.time = 0
def handle_data(context, data):
cleaned_weights = []
if context.time == 0 or (context.time % context.rebalance_period == 0):
# extract prices
prices_df = data.history(context.assets, fields='price',
bar_count=context.window + 1, frequency='1d')
# creating log returns to de-trend and remove seasonality
log_ret = np.log(prices_df/prices_df.shift(1))
def get_ret_vol_sr(weights):
"""
Takes in weights, returns array or return,volatility, sharpe ratio
"""
weights = np.array(weights)
ret = np.sum(log_ret.mean() * weights) * 252
vol = np.sqrt(np.dot(weights.T, np.dot(log_ret.cov() * 252, weights)))
sr = ret/vol
return np.array([ret,vol,sr])
from scipy.optimize import minimize
# objective function
def neg_sharpe(weights):
return get_ret_vol_sr(weights)[2] * -1
# Contraints
def check_sum(weights):
'''
Returns 0 if sum of weights is 1.0
'''
return np.sum(weights) - 1
# By convention of minimize function it should be a function that returns zero for conditions
cons = ({'type':'eq','fun': check_sum})
# 0-1 bounds for each weight
bounds = ((0, 1), (0, 1), (0, 1), (0, 1))
# Initial Guess (equal distribution)
init_guess = [0.25,0.25,0.25,0.25]
# Sequential Least SQuares Programming (SLSQP).
opt_results = minimize(neg_sharpe,init_guess,method='SLSQP',bounds=bounds,constraints=cons)
weights=opt_results.x
cleaned_weights=dict(zip(prices_df.columns.tolist(),weights.tolist()))
# submit orders
for asset in context.assets:
order_target_percent(asset, cleaned_weights[asset])
record(weights=cleaned_weights)
context.time += 1
simple_optimization_30D_rebalance_df = pd.read_pickle('simple_optimization_30D_rebalance.pkl')
print(simple_optimization_30D_rebalance_df[:10])
algo_volatility algorithm_period_return alpha \
2015-12-31 21:00:00+00:00 NaN 0.000000 None
2016-01-04 21:00:00+00:00 0.005480 -0.000488 None
2016-01-05 21:00:00+00:00 0.046403 0.004311 None
2016-01-06 21:00:00+00:00 0.043378 0.003082 None
2016-01-07 21:00:00+00:00 0.330778 -0.042578 None
2016-01-08 21:00:00+00:00 0.297078 -0.046728 None
2016-01-11 21:00:00+00:00 0.276735 -0.045403 None
2016-01-12 21:00:00+00:00 0.287919 -0.029249 None
2016-01-13 21:00:00+00:00 0.318156 -0.063774 None
2016-01-14 21:00:00+00:00 0.351949 -0.036099 None
benchmark_period_return benchmark_volatility \
2015-12-31 21:00:00+00:00 0.0 NaN
2016-01-04 21:00:00+00:00 0.0 0.0
2016-01-05 21:00:00+00:00 0.0 0.0
2016-01-06 21:00:00+00:00 0.0 0.0
2016-01-07 21:00:00+00:00 0.0 0.0
2016-01-08 21:00:00+00:00 0.0 0.0
2016-01-11 21:00:00+00:00 0.0 0.0
2016-01-12 21:00:00+00:00 0.0 0.0
2016-01-13 21:00:00+00:00 0.0 0.0
2016-01-14 21:00:00+00:00 0.0 0.0
beta capital_used ending_cash ending_exposure \
2015-12-31 21:00:00+00:00 None 0.00000 50000.00000 0.00
2016-01-04 21:00:00+00:00 None -48847.89174 1152.10826 48823.48
2016-01-05 21:00:00+00:00 None 0.00000 1152.10826 49063.42
2016-01-06 21:00:00+00:00 None 0.00000 1152.10826 49001.98
2016-01-07 21:00:00+00:00 None 0.00000 1152.10826 46719.00
2016-01-08 21:00:00+00:00 None 0.00000 1152.10826 46511.50
2016-01-11 21:00:00+00:00 None 0.00000 1152.10826 46577.74
2016-01-12 21:00:00+00:00 None 0.00000 1152.10826 47385.46
2016-01-13 21:00:00+00:00 None 0.00000 1152.10826 45659.20
2016-01-14 21:00:00+00:00 None 0.00000 1152.10826 47042.94
ending_value \
2015-12-31 21:00:00+00:00 0.00
2016-01-04 21:00:00+00:00 48823.48
2016-01-05 21:00:00+00:00 49063.42
2016-01-06 21:00:00+00:00 49001.98
2016-01-07 21:00:00+00:00 46719.00
2016-01-08 21:00:00+00:00 46511.50
2016-01-11 21:00:00+00:00 46577.74
2016-01-12 21:00:00+00:00 47385.46
2016-01-13 21:00:00+00:00 45659.20
2016-01-14 21:00:00+00:00 47042.94
... \
2015-12-31 21:00:00+00:00 ...
2016-01-04 21:00:00+00:00 ...
2016-01-05 21:00:00+00:00 ...
2016-01-06 21:00:00+00:00 ...
2016-01-07 21:00:00+00:00 ...
2016-01-08 21:00:00+00:00 ...
2016-01-11 21:00:00+00:00 ...
2016-01-12 21:00:00+00:00 ...
2016-01-13 21:00:00+00:00 ...
2016-01-14 21:00:00+00:00 ...
short_value shorts_count sortino \
2015-12-31 21:00:00+00:00 0.0 0 NaN
2016-01-04 21:00:00+00:00 0.0 0 -11.224972
2016-01-05 21:00:00+00:00 0.0 0 80.962001
2016-01-06 21:00:00+00:00 0.0 0 18.614170
2016-01-07 21:00:00+00:00 0.0 0 -6.614699
2016-01-08 21:00:00+00:00 0.0 0 -6.625288
2016-01-11 21:00:00+00:00 0.0 0 -5.951541
2016-01-12 21:00:00+00:00 0.0 0 -3.490858
2016-01-13 21:00:00+00:00 0.0 0 -5.846201
2016-01-14 21:00:00+00:00 0.0 0 -2.985248
starting_cash starting_exposure starting_value \
2015-12-31 21:00:00+00:00 50000.00000 0.00 0.00
2016-01-04 21:00:00+00:00 50000.00000 0.00 0.00
2016-01-05 21:00:00+00:00 1152.10826 48823.48 48823.48
2016-01-06 21:00:00+00:00 1152.10826 49063.42 49063.42
2016-01-07 21:00:00+00:00 1152.10826 49001.98 49001.98
2016-01-08 21:00:00+00:00 1152.10826 46719.00 46719.00
2016-01-11 21:00:00+00:00 1152.10826 46511.50 46511.50
2016-01-12 21:00:00+00:00 1152.10826 46577.74 46577.74
2016-01-13 21:00:00+00:00 1152.10826 47385.46 47385.46
2016-01-14 21:00:00+00:00 1152.10826 45659.20 45659.20
trading_days \
2015-12-31 21:00:00+00:00 1
2016-01-04 21:00:00+00:00 2
2016-01-05 21:00:00+00:00 3
2016-01-06 21:00:00+00:00 4
2016-01-07 21:00:00+00:00 5
2016-01-08 21:00:00+00:00 6
2016-01-11 21:00:00+00:00 7
2016-01-12 21:00:00+00:00 8
2016-01-13 21:00:00+00:00 9
2016-01-14 21:00:00+00:00 10
transactions \
2015-12-31 21:00:00+00:00 []
2016-01-04 21:00:00+00:00 [{'dt': 2016-01-04 21:00:00+00:00, 'amount': 3...
2016-01-05 21:00:00+00:00 []
2016-01-06 21:00:00+00:00 []
2016-01-07 21:00:00+00:00 []
2016-01-08 21:00:00+00:00 []
2016-01-11 21:00:00+00:00 []
2016-01-12 21:00:00+00:00 []
2016-01-13 21:00:00+00:00 []
2016-01-14 21:00:00+00:00 []
treasury_period_return \
2015-12-31 21:00:00+00:00 0.0
2016-01-04 21:00:00+00:00 0.0
2016-01-05 21:00:00+00:00 0.0
2016-01-06 21:00:00+00:00 0.0
2016-01-07 21:00:00+00:00 0.0
2016-01-08 21:00:00+00:00 0.0
2016-01-11 21:00:00+00:00 0.0
2016-01-12 21:00:00+00:00 0.0
2016-01-13 21:00:00+00:00 0.0
2016-01-14 21:00:00+00:00 0.0
weights
2015-12-31 21:00:00+00:00 {Equity(2892 [TWTR]): 4.2837292936461303e-16, ...
2016-01-04 21:00:00+00:00 []
2016-01-05 21:00:00+00:00 []
2016-01-06 21:00:00+00:00 []
2016-01-07 21:00:00+00:00 []
2016-01-08 21:00:00+00:00 []
2016-01-11 21:00:00+00:00 []
2016-01-12 21:00:00+00:00 []
2016-01-13 21:00:00+00:00 []
2016-01-14 21:00:00+00:00 []
[10 rows x 38 columns]