# Import the libraries we will use here
import math
import numpy as np
import pandas
from scipy.optimize import minimize
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline import CustomFactor
from quantopian.pipeline.factors import SimpleMovingAverage,AverageDollarVolume
from quantopian.pipeline.data import morningstar
class Mean(CustomFactor):
inputs = [USEquityPricing.close]
def compute(self, today, asset_ids, out, close):
r = np.diff(close, axis=0) / close[0:-1]
mean = np.mean(r,axis=0)
out[:] = mean
class Variance(CustomFactor):
inputs = [USEquityPricing.close]
def compute(self, today, asset_ids, out, close):
r = np.diff(close, axis=0) / close[0:-1]
var = np.var(r,axis=0)
out[:] = var
class Value(CustomFactor):
inputs = [morningstar.valuation_ratios.ev_to_ebitda]
def compute(self, today, asset_ids, out, ratio):
out[:] = 1.0/ratio[-1]
class Quality(CustomFactor):
inputs = [morningstar.cash_flow_statement.free_cash_flow,morningstar.balance_sheet.net_debt]
def compute(self, today, asset_ids, out, fcf, debt):
out[:] = fcf[-1]/debt[-1]
class Growth(CustomFactor):
inputs = [morningstar.earnings_ratios.diluted_eps_growth]
def compute(self, today, asset_ids, out, ratio):
out[:] = ratio[-1]
class Volume(CustomFactor):
inputs = [USEquityPricing.volume]
def compute(self, today, asset_ids, out, vol):
out[:] = np.nan_to_num(np.mean(vol,axis=0))
# The initialize function is the place to set your tradable universe and define any parameters.
def initialize(context):
set_symbol_lookup_date('2016-01-01')
# OPTIONS ###################################
# context.random_universe = False
context.random_universe = True
context.securities = []
context.longs = []
context.shorts = []
context.leverage = {}
context.benchmark = symbol('SPY')
context.riskless = symbol('SHY')
context.riskless_apr = 1.005 # Assumed rate of riskless investment
# context.riskless = symbol('BSV')
# context.riskless_apr = 1.01 # Assumed rate of riskless investment
context.ignore = [ # Stocks to ignore when picking
context.riskless,
context.benchmark,
]
context.max_drawdown = 1.0 # Portion of portfolio to risk
context.risk_leverage = 1.0 # Portion leverage = max_drawdown * risk_leverage
context.curr_risk = context.portfolio.portfolio_value*context.max_drawdown
context.max_risk = context.curr_risk
context.port_ceil = context.portfolio.portfolio_value
context.recalculate_period_days = 10
context.trade_period_days = 1
context.lookback = 21*12 # Number of previous days to sample
# context.minute_mode_only = True
context.minute_mode_only = False
# context.hold_cash = False # Use or don't use excess cash to invest in riskless
context.hold_cash = True # Use or don't use excess cash to invest in riskless
context.hedge = True
# context.hedge = False
context.hedge_shortable = False
# context.hedge_shortable = True
context.always_shorted = False
context.hedge_kelly_limit = True
context.hedge_max_variance = 999
context.hedge_short_long_ratio = 0.1
context._day_count = -1
context._first_traded = False
context.borrowing_rate = 1.02
context.accrued_interest = 0
context.pick_period = context.recalculate_period_days
context.long_size = 10
context.short_size = 10
context.alpha = 1.0
context.drawdown_trigger = 0.10
context.trigger_fraction = 1.00
context.max_pct_liquidity = 0.10
# END #######################################
if context.random_universe == False:
context.universe = symbols(
# 'EDV',
# 'VTI',
# 'VNQ',
# 'VNQI',
# 'VPL',
# 'VGK',
# 'VWO',
# 'VDE',
# 'BIV',
'VTI', # USA
'IYR', # REIT
'EZU', # Europe
'EWJ', # Japan
'EEM', # Emerging
'IYE', # US Energy
'TLT', # 20+ Treasury
'IEF', # 7-10 Treasury
'LQD', # Corporate bonds
'DBC', # Commodities index
'FXE', # Euro
'FXY', # Yen
'XIV',
)
context.universe_yield = dict.fromkeys(context.universe,1.00)
custom_yield = {
# 'EDV' :1.025,
# 'VTI' :1.02,
# 'VNQ' :1.025,
# 'VNQI':1.025,
# 'VPL' :1.02,
# 'VGK' :1.02,
# 'VWO' :1.02,
# 'VDE' :1.02,
# 'BIV' :1.02,
'VTI':1.02,
'IYR':1.03,
'EZU':1.02,
'EWJ':1.01,
'EEM':1.02,
'IYE':1.02,
'TLT':1.02,
'IEF':1.015,
'LQD':1.03,
}
for sec in context.universe:
if sec.symbol in custom_yield:
context.universe_yield[sec] = custom_yield[sec.symbol]
if context.random_universe == True:
pipe = Pipeline()
attach_pipeline(pipe, name='my_pipeline')
mean = Mean(window_length = context.lookback)
var = Variance(window_length = context.lookback)
f1 = (mean - var/2.0)
f2 = Value(window_length = context.lookback)
f3 = Quality(window_length = context.lookback)
f4 = Growth(window_length = context.lookback)
pipe.add(f1,'f1')
pipe.add(f2,'f2')
pipe.add(f3,'f3')
pipe.add(f4,'f4')
def before_trading_start(context,data):
if not context._first_traded:
context._day_count = -1
context._day_count += 1
if context.random_universe and context._day_count % context.pick_period == 0:
context.universe = pipeline_output('my_pipeline').dropna(axis=0)
context.universe = context.universe[~context.universe.index.isin(context.ignore)]
context.universe = context.universe[~context.universe.index.isin(security_lists.leveraged_etf_list)]
context.universe = context.universe.rank().mean(axis=1).order()
longs = context.universe.tail(context.long_size)
shorts = context.universe.head(context.short_size)
context.universe = pandas.concat((longs,shorts)).index
context.universe_yield = dict.fromkeys(context.universe,1.00)
update_universe(context.universe)
def handle_data(context,data):
pass
I commented out the factors that access Morningstar and the backtest works fine. I always get a timeout with the fundamental factors on.