def initialize(context): context.asserts = symbols('SPY','ZSL', 'KOLD', 'GLD') context.bonds = symbol('SHY') context.universe = symbols('SPY','ZSL', 'KOLD', 'GLD', 'SHY') context.top_n_by_momentum = pd.Series() #Choose X stocks out of portfolio of Y stocks- how many stocks to hold - top X by momentum context.num_stocks=3 #Lookback for momentum calculation context.momentum_days=60 #Set context.trend to 0 to reject any stocks with negative momentum, set to -1 to accept stocks with negative momentum context.trend =0.0 context.stocks=[]
def getCurrentPrice(self, zipline_data: BarData, alloc_weights: np.array = None) -> float: """Compute and return the current asset price (using stored component asset allocation weights) or supplied override allocation weights. Arguments: zipline_data {BarData} -- Instance zipline data bundle. Keyword Arguments: alloc_weights {np.array} -- Alternate allocation weights to be used instead of stored allocation weights (default: {None}). Returns: float -- Synthetic ETF price at the current time step. """ # Getting current component asset prices current_asset_prices = np.array( zipline_data.current(symbols(*self.tickers), 'price')) if alloc_weights is None: alloc_weights = self.alloc_weights # Comuting current price (dot product b/w current prices and alloc) return np.dot(current_asset_prices, alloc_weights)
def initialize(context): # set_symbol_lookup_date('2009-01-01') context.cost = 0.06 # (round trade cost) 0.03 per share context.secs = symbols('AAPL', 'GOOGL') context.drift = 0 context.lag = 1 context.c_val = 0.40 # critical level for ADF test # Money Management context.leverage_limit = 0.1 # Set the no-trade-region context.dev_upper_threshold = 0.2 context.dev_lower_threshold = 0.1 context.freq = 5 # mins context.lookback = 100 # periods Note: 390 mins/6.5 hours per day context.trade_bars = 5 # context.freq_counter = 0 # Count the bars in tartget frequency, context.freq context.base_counter = 0 # Count the bars in base frequncy, 1m or 1d # initialize the holders context.past_prices = {secs:[] for secs in context.secs} context.weights = [] context.prices = [] context.pct_allocation = []
def initialize(context): """ Called once at the start of the algorithm. """ c = context c.etf_universe = StaticAssets( symbols('XLY', 'XLP', 'XLE', 'XLF', 'XLV', 'XLI', 'XLB', 'XLK', 'XLU')) c.alphas = pd.DataFrame() # Rebalance every day, 1 hour after market open. schedule_function( rebalance, date_rules.every_day(), time_rules.market_open(hours=1), ) # Record tracking variables at the end of each day. schedule_function( record_vars, date_rules.every_day(), time_rules.market_close(), ) # Create our dynamic stock selector. attach_pipeline(make_pipeline(context), 'pipeline') attach_pipeline(make_pipeinit(context), 'pipeinit') c.first_trading_day = True c.factor_name_list = make_factor().keys()
def initialize(context): schedule_function(func=trade, date_rule=date_rules.every_day(), time_rule=time_rules.market_open(), half_days=True) schedule_function(func=cancel, time_rule=time_rules.market_close(minutes=5), date_rule=date_rules.every_day(), half_days=True) schedule_function(func=reorder, time_rule=time_rules.market_open(minutes=5), date_rule=date_rules.every_day(), half_days=True) context.asserts = symbols('SPY') context.bonds = symbol('SHY') context.rebalance_date = 0 context.fired = False context.rebalance_inteval = 'D' #'Q', #'D', #'M' #'Q' #'Y' context.top_n_by_momentum = pd.Series() #Choose X stocks out of portfolio of Y stocks- how many stocks to hold - top X by momentum context.stocks = 1 #Lookback for momentum calculation context.momentum_days = 60 #set at less than 1 to ensure no leverage context.leverage_buffer = 0.99 #Set to 0 to reject any stocks with negative momentum, set to -1 to accept stocks with negative momentum context.trend = 0.0 context.reorder_dict = {}
def handle_data(context, data): print context.datetime.tz_convert(pytz.timezone("Asia/Shanghai")) import pandas as pd # print data.history(symbols("000001.SZ"), ["price","volume"], 10, # '1d').iloc[:,1] # print data.history(symbols("000002.SZ"), "price", 2, '1m').iloc[0] print data.history(symbols("600000.SH"), "close", 1, '1d')
def initialize(context): schedule_function(func=trade, date_rule=date_rules.every_day(), time_rule=time_rules.market_open(), half_days=True) context.asserts = symbols('SPY', 'SHY', 'TLT', 'GLD') context.asserts_position = [0.25, 0.25, 0.25, 0.25] context.rebalance_inteval = 'Q' #'Q', #'D', #'M' #'Q' #'Y' context.rebalance_date = 0 context.fired = False
def initialize(context): # ----------------------------------------------------------------------------------------------- # YAHOO_SYM_LST=QQQ,TLT,IEF,SLV,GLD,XLI,XLU zipline ingest -b yahoo_direct c = context c.STOCKS = symbols('QQQ') c.BONDS = symbols('TLT', 'IEF') c.LEV = 1.00 c.wt = {} c.A = symbol('SLV') c.B = symbol('GLD') c.C = symbol('XLI') c.D = symbol('XLU') c.MKT = symbol('QQQ') c.VOLA = 126 c.LB = 1.00 c.BULL = 1 c.COUNT = 0 c.OUT_DAY = 0 c.RET_INITIAL = 80
def updateParameters(self, zipline_data: BarData): """Update ETF parameters; specifically, the asset allocations weights, the log return (over the configuration lookback window), the variance, and the synthetic ETF prices over the lookback window. Arguments: zipline_data {BarData} -- Instance zipline data bundle. """ # Get historical price data for lookback window from config historical_data = zipline_data.history( symbols(*self.tickers), 'price', bar_count=config.setf_lookback_window, frequency=config.setf_data_frequency) # Filling na values historical_data = historical_data.fillna(method='bfill') historical_data = historical_data.fillna(method='ffill') # Computing prices, restructuring per the period in the configuration setf_prices = np.array([]) first_run = True # Flag for first run for idx, row in historical_data.iterrows(): if (self.backtest_util.isRestructureTriggered(current_date=idx, log_flag=False) or first_run): # Recompute allocation weights alloc_weights = np.array(row / row.sum()) # Update first run flag first_run = False # Computing synthetic ETF price setf_price = np.dot(alloc_weights, row.values) # Appending to prices array setf_prices = np.append(setf_prices, setf_price) if (np.count_nonzero(np.isnan(setf_prices)) > 0): logging.error('NA values detected in Synthetic ETF prices') raise Exception # Computing ETF log returns self.log_rets = np.diff(np.log(setf_prices)) # Computing single-period ETF log return (sum of log returns) self.period_log_ret = np.sum(self.log_rets) # Computing ETF variance self.variance = np.var(self.log_rets) # Casting synthetic ETF prices to DataFrame with original index, binding self.setf_prices = pd.DataFrame(setf_prices, index=historical_data.index)
def initialize(context): # ----------------------------------------------------------------------------------------------- c = context c.STOCKS = symbols('QQQ') c.BONDS = symbols('TLT', 'IEF') c.LEV = 1.00 c.wt = {} c.A = symbol('SLV') c.B = symbol('GLD') c.C = symbol('XLI') c.D = symbol('XLU') c.MKT = symbol('QQQ') c.VOLA = 126 c.LB = 1.00 c.BULL = 1 c.COUNT = 0 c.OUT_DAY = 0 c.RET_INITIAL = 80 # ----------------------------------------------------------------------------------------------- schedule_function(daily_check, date_rules.every_day(), time_rules.market_open(minutes=140)) schedule_function(record_vars, date_rules.every_day(), time_rules.market_close())
def initialize(context): schedule_function(func=trade, date_rule=date_rules.every_day(), time_rule=time_rules.market_open(),half_days=True) context.asserts = symbols('SPY','IEF') context.rebalance_date = 0 context.fired = False context.rebalance_inteval = 'M'#'Q', #'D', #'M' #'Q' #'Y' context.asserts_position = [0.5, 0.5] context.volatility_policy = True #unused if volatility_policy is false context.volatility_days = 252 context.volatility_price_history = 66 #set at less than 1 to ensure no leverage context.leverage_buffer=0.90
def initialize(context): c = context # Some Risk-On universes core_etf = symbols('QQQ', 'XLP', 'TLT', 'IEF') tact_etf = symbols('XLV', 'XLY', 'TLT', 'GLD') VAAG12 = symbols('SPY', 'IWM', 'QQQ', 'VGK', 'EWJ', 'VWO', 'VNQ', 'GSG', 'GLD', 'TLT', 'LQD', 'HYG') VAAG4 = symbols('SPY', 'VEA', 'VWO', 'BND') c.RISK = VAAG4 # Which Riskasset universe to use? alletf = symbols('QQQ', 'XLP', 'TLT', 'IEF', 'SPY', 'IWM', 'QQQ', 'VGK', 'EWJ', 'VWO', 'VNQ', 'GSG', 'GLD', 'TLT', 'LQD', 'HYG', 'XLV', 'XLY', 'GLD', 'VEA') # 'TLO' repleced by 'TLT' # Some Risk Off (Cash) universes c.CASH = symbols('SHY', 'IEF', 'LQD') schedule_function(define_weights, date_rules.month_end(Month_Offset), time_rules.market_open(minutes=64)) log.info('define_weights for last trading day of the month') schedule_function(trade_sell, date_rules.month_end(Month_Offset), time_rules.market_open(minutes=65)) log.info('trade_sell for last trading day of the month') if TplusX > 0: schedule_function( trade_buy, date_rules.month_start(max(0, TplusX - 1 - Month_Offset)), time_rules.market_open(minutes=66)) log.info('trade_buy for month day ' + str(max(0, TplusX - Month_Offset))) else: schedule_function(trade_buy, date_rules.month_end(Month_Offset), time_rules.market_open(minutes=66)) log.info('trade_buy last trading day of the month') stocks = core_etf + tact_etf context.sell = {} context.buy = {} for stock in stocks: context.sell[stock] = 0 context.buy[stock] = 0 context.difference_perc = 0.02 context.stops = {} context.stoploss = 0.30 context.stoppedout = []
def make_pipeline(): """ A function to create our dynamic stock selector (pipeline). Documentation on pipeline can be found here: https://www.quantopian.com/help#pipeline-title """ base_universe = StaticAssets( symbols('XLY', 'XLP', 'XLE', 'XLF', 'XLV', 'XLI', 'XLB', 'XLK', 'XLU')) # Factor of yesterday's close price. yesterday_close = USEquityPricing.close.latest pipeline = Pipeline(columns={ 'close': yesterday_close, }, screen=base_universe) return pipeline
def initialize(context): add_history(190, '1d', 'price') add_history(365, '1d', 'price') context.syms = symbols('AAPL', 'AXP', 'BA', 'CAT', 'CSCO', 'CVX', 'DD', 'DIS', 'GE', 'GS', 'HD', 'IBM', 'INTC', 'JNJ', 'JPM', 'KO', 'MCD', 'MMM', 'MRK', 'MSFT', 'NKE', 'PFE', 'PG', 'TRV', 'UNH', 'UTX', 'V', 'VZ', 'WMT', 'XOM') context.stocks_to_long = 10 context.stocks_to_short = 10 context.day = 0 context.n = 0 context.weekCounter = 0 algo.set_commission(commission.PerShare(cost=0.15))
def initialize(context): spy_tlt = StaticAssets([symbol('AAPL'), symbol('IBM')]) print(symbol('AAPL'), symbols('AAPL')) # Create an arbitrary factor price = USEquityPricing.close.latest pipe = Pipeline(screen=spy_tlt, columns={ 'price': price, }) attach_pipeline(pipe, 'my_pipeline') schedule_function(rebalance, date_rules.every_day()) pass
def initialize(context): attach_pipeline(make_pipeline(), 'data_pipeline') context.technical_indicator_states = {} context.window_length = 7 context.benchmark = deque(maxlen=context.window_length) context.benchmark_asset = symbol('SPY') context.benchmark_assets = symbols('QQQ', 'SPY') #context.classifier = RandomForestClassifier() # Use a random forest classifier context.classifier = DecisionTreeClassifier(max_depth=5, max_leaf_nodes=10) # Clasifier training data context.features = [ 'RSI', 'EMA', 'MACD', 'SMA_5', 'SMA_10', 'bb_lower', 'bb_middle', 'bb_upper' ] context.response = ['Class'] context.X = pd.DataFrame( columns=context.features) # Independent, or input variables context.Y = pd.DataFrame( columns=context.response) # Dependent, or output variable context.prediction = {} # Stores most recent prediction context.tick = 0 context.total_buy = 0 context.positions = None context.position_adjustment_days = 5 # Number of days to wait before adjusting positions context.min_data_points = 500 context.max_data_points = 1500 schedule_function(rebalance, date_rules.every_day(), time_rules.market_open(minutes=1)) schedule_function(record_vars, date_rules.every_day(), time_rules.market_close()) set_benchmark(symbol('SPY')) # Turn off the slippage model set_slippage(slippage.FixedSlippage(spread=0.0)) # Set the commission model (Interactive Brokers Commission) set_commission(commission.PerShare(cost=0.01, min_trade_cost=1.0))
def initialize(context): context.universe = StaticAssets(symbols( 'XLY', # Select SPDR U.S. Consumer Discretionary 'XLP', # Select SPDR U.S. Consumer Staples 'XLE', # Select SPDR U.S. Energy 'XLF', # Select SPDR U.S. Financials 'XLV', # Select SPDR U.S. Healthcare 'XLI', # Select SPDR U.S. Industrials 'XLB', # Select SPDR U.S. Materials 'XLK', # Select SPDR U.S. Technology 'XLU', # Select SPDR U.S. Utilities )) # my_pipe = Pipeline() my_pipe = make_pipeline(context) # context.universe = StaticAssets(etfs) attach_pipeline(my_pipe, 'my_pipeline') schedule_function(func=rebalance, date_rule=date_rules.month_end(days_offset=2), # date_rule=date_rules.every_day(), time_rule=time_rules.market_close(minutes=30))
def updateWeights(self, zipline_data: BarData) -> np.array: """Update current weights of the component assets; this recomputes the price-weighted allocation as of the date of the current `zipline_data`. Arguments: zipline_data {BarData} -- Instance zipline data bundle. Returns: np.array -- Array of asset weights. """ # Getting current component asset prices current_asset_prices = np.array( zipline_data.current(symbols(*self.tickers), 'price')) # Computing current sum current_sum = np.sum(current_asset_prices) # Binding allocation weights (list and dict) self.alloc_weights = current_asset_prices / current_sum self.alloc_weights_dict = dict(zip(self.tickers, self.alloc_weights)) # Return new weights return self.alloc_weights
def initialize(context): # Manually define stocks instead of downloading a universe with Fetch or using a cross section with set_universe context.stocks = symbols('AAPL', 'IBM', 'CSCO', 'SYN') # Dictionary of durations, optional for any order context.duration = {} # Inside the data loop, keep track of commited cash for the new orders. # The portfolio cash is not updated on an intra cycle time scale yet. context.cashCommitedToBuy = 0 context.cashCommitedToSell = 0 # set a more realistic commission for IB set_commission(commission.PerShare(cost=0.014, min_trade_cost=1.4)) # Prevent shorting, not needed here but it will stop # runaway code, like if you buy condition goes nuts # borrowing uncontrollably. set_long_only() logging.info( "---Prices below reflect market price or average held value at time of action and" + " NOT the value of the transactions. Use the Run Full Backtest" + " button and view the transactions tab to view real prices.---")
def initialize(context): # these must ALWAYS be present! context.transforms = [] context.algo_rules = [] context.max_lookback = 63 context.outstanding = {} # orders which span multiple days context.raw_data = {} ############################################################# # set the following parameters as required context.show_positions = True # select records to show in algo.show_records() context.show_records = True # replace cash_proxy with risk_free if cantec.allow_cash_proxY_replacement is True # and cash_proxy price is <= average cash_proxy price over last context.cash_proxy_lookback days context.allow_cash_proxy_replacement = False context.cash_proxy_lookback = 43 # must be <= context.max_lookback context.update_metrics = False # to calculate Sharpe ratio context.calculate_SR = False context.SR_lookback = 63 # must be <= context.max_lookback context.SD_factor = 0 # position only changed if percentage change > threshold context.threshold = 0.01 # the following can be changed context.market_proxy = symbols('VFINX')[0] context.risk_free = symbols('VFISX')[0] # context.market_proxy = symbols('SPY')[0] # context.risk_free = symbols('SHY')[0] set_commission(commission.PerTrade(cost=10.0)) context.leverage = 1.0 ################################################################# # configure strategies context.rebalance_interval = 3 # set interval to n = no of periods (default: months) # if you want to change default period, change schedule reallocate below # Strategy 1 rs0003 = StrategyParameters( context, name='rs0003', portfolios=[symbols('NHMAX', 'FAGIX', 'VFIIX')], # portfolios=[symbols('HYD','HYD','MBB')], portfolio_allocation_modes=['EW'], portfolio_allocation_kwargs=[{}], security_weights=[None], portfolio_allocation_formulas=[None], scoring_methods=['RS'], scoring_factors=[{ '+momentum': 1.0 }], n_tops=[1], protection_modes=['BY_RULE'], protection_rules=['smma_rule'], protection_formulas=[None], cash_proxies=[symbol('VFISX')], # cash_proxies=[symbol('SHY')], strategy_allocation_mode='FIXED', portfolio_weights=[1.0], strategy_allocation_formula=None, strategy_allocation_rule=None) Configurator(context, define_transforms, define_rules, strategies=[rs0003]) ############################ # configure algorithm algo = Algo(context, strategies=[rs0003.strategy], allocation_model=AllocationModel(context, mode='EW', weights=None, formula=None), regime=None) ########################################################################################################### # generate algo data every day at close schedule_function(algo.update_data, date_rules.every_day(), time_rules.market_close()) # daily functions to handle GTC orders schedule_function(algo.check_for_unfilled_orders, date_rules.every_day(), time_rules.market_close()) schedule_function(algo.fill_outstanding_orders, date_rules.every_day(), time_rules.market_open()) if context.update_metrics: # calculate metrics every day schedule_function(algo.update_metrics, date_rules.every_day(), time_rules.market_close()) if context.show_positions: schedule_function(algo.show_positions, date_rules.month_start(days_offset=0), time_rules.market_open()) if context.show_records: # show records every day # edit the show_records function to include records required schedule_function(algo.show_records, date_rules.every_day(), time_rules.market_close()) schedule_function(algo.rebalance, date_rules.month_end(days_offset=2), time_rules.market_open())
def initialize(context): context.record_rank = {} context.save2mysql = 0 # 模型训练参数 context.horizon = 6 context.percent = 5 context.model_name = 'adaBoost' context.rolling = 1 # 是否为滚动,0为不滚动 context.ishistory = 0 #是否用历史分类。0为不使用 context.train_period = 12 * 1 context.i = 0 set_slippage(slippage.FixedSlippage(spread=0.00)) set_commission(commission.PerDollar(cost=0.00325)) month = 21 week = 5 rf = 0.025 c = 252 if context.namespace["fund_type"] == 'stock': benchmark = '000300.SH' fund_type = 1 elif context.namespace["fund_type"] == 'hybrid': benchmark = '000300.SH' fund_type = 2 elif context.namespace["fund_type"] == 'bond': benchmark = '037.CS' fund_type = 3 # 选择基金池和benchmark ben_sid = symbol(benchmark).sid df_stock = df.query("update_time == update_time.max() and type_code=={"\ "type}".format(type = fund_type)) # 基金900 开头的不需要,专门去掉 df_stock = df_stock[df_stock["fund_code"] < '900000'].fund_code + ".OF" sfilt = SpecificAssets(symbols( benchmark, *tuple(df_stock))) # 使用到的数据,包括基金和对应benchmark指数 sample_filt = SpecificAssets(symbols( *tuple(df_stock))) # 只包含基金,因为评级不应该包含benchmark,故在事后screen去掉benchmark # 只包含基金,因为评级不应该包含benchmark,故在事后screen去掉benchmark ## 16个因子指标 down_sharpe = Down_sharpe(window_length=9 * month, rf=rf, c=c, mask=sfilt) drawdown = Drawdown(window_length=9 * month, mask=sfilt) dvar = Down_variation(window_length=9 * month, rf=rf, c=c, mask=sfilt) mean_r = Average_return(window_length=9 * month, mask=sfilt) lasting = Lasting(window_length=9 * month, mask=sfilt, time=6 * month, percent=20) emr = Emr(window_length=9 * month, mask=sfilt, time=6 * month) rlt_var = Negative_variation(window_length=9 * month, c=c, mask=sfilt) mcv_in = Mcv_in(window_length=9 * month, rf=rf, c=c, mask=sfilt, time=week, index_sid=ben_sid) rank_stable = Rank_stable(window_length=9 * month, mask=sfilt, time=6 * month) select_time, select_stock = CL(window_length=9 * month, rf=rf, mask=sfilt, time=week, index_sid=ben_sid) hit_rate = Hit_rate(window_length=10 * month, mask=sfilt, time=6 * month, time_window=9 * month, index_sid=ben_sid) value_at_risk = Value_at_risk(window_length=9 * month, mask=sfilt, q_value=5, time=6 * month) beta_in = Beta_in(window_length=9 * month, mask=sfilt, rf=rf, time=week, index_sid=ben_sid) bias_in = Bias_in(window_length=9 * month, mask=sfilt, time=126) ir = Information_ratio(window_length=9 * month, mask=sfilt, time=1, index_sid=ben_sid) # 预测因变量Y _ry = Lag_Return(window_length=context.horizon * month, mask=sfilt) _sp = Lag_Sharpe(window_length=context.horizon * month, mask=sfilt) pipe = Pipeline(columns={ "dhsp": down_sharpe, "drwd": drawdown, "dvar": dvar, "mean_r": mean_r, "lasting": lasting, "emr": emr, "rlt_var": rlt_var, "mcv_in": mcv_in, "rank_stable": rank_stable, "select_time": select_time, "select_stock": select_stock, "hit_rate": hit_rate, "value_at_risk": value_at_risk, "beta_in": beta_in, "bias_in": bias_in, "ir": ir, "_ry": _sp }, screen=sample_filt) attach_pipeline(pipe, 'my_pipeline') set_max_leverage(1.1) schedule_function(rebalance, date_rule=date_rules.month_start(), time_rule=time_rules.market_open()) # 初始化记录变量 context.rank_score = pd.Series() context.f = pd.Panel() context.f_dict = {} context.reb_flag = False context.B = {}
def initialize(context): # we will be trading in AMZN and WMT shares context.stocks = symbols('AMZN', 'WMT') context.bet_amount = 100000 context.long = 0
def initialize(self, context): super(TradingSignalAlgorithm, self).initialize(context) # set universe context.stocks = self.all_portfolios[self.grp][self.subgrp]['stocks'] if self.stocks is None else symbols(*self.stocks) if self.verbose: print(context.stocks) # initialise weights and target allocation context.weights = False context.target_allocation = dict(zip(context.stocks, self.initial_weights)) # initialise target allocations
def initialize(self, context): super(OptAlgorithm, self).initialize(context) # set universe context.stocks = self.all_portfolios[self.grp][self.subgrp]['stocks'] if self.stocks is None else symbols(*self.stocks) if self.verbose: print(context.stocks) context.weights = False context.target_allocation = dict(zip(context.stocks, [0]*len(context.stocks))) # initialise target allocations to zero context.tick = 0
def _check_valid_parameters(self, context, strategy): N = len(strategy.portfolios) s = strategy self._check_valid_parameter(context, s, strategy.portfolios, 'portfolios', list, N, list, ''), self._check_valid_parameter(context, s, strategy.portfolio_allocation_modes, 'portfolio_allocation_modes', list, N, str, VALID_PORTFOLIO_ALLOCATION_MODES), self._check_valid_parameter(context, s, strategy.security_weights, 'security_weights', list, N, list, ''), self._check_valid_parameter(context, s, strategy.portfolio_allocation_formulas, 'portfolio_allocation_formulas', list, N, str, VALID_PORTFOLIO_ALLOCATION_FORMULAS), self._check_valid_parameter(context, s, strategy.scoring_methods, 'scoring_methods', list, N, str, VALID_SCORING_METHODS), self._check_valid_parameter(context, s, strategy.scoring_factors, 'scoring_factors', list, N, dict, ''), self._check_valid_parameter(context, s, strategy.n_tops, 'n_tops', list, N, int, '') self._check_valid_parameter(context, s, strategy.protection_modes, 'protection_modes', list, N, str, VALID_PROTECTION_MODES), self._check_valid_parameter(context, s, strategy.protection_rules, 'protection_rules', list, N, str, ''), self._check_valid_parameter(context, s, strategy.protection_formulas, 'protection_formulas', list, N, str, VALID_PROTECTION_FORMULAS), self._check_valid_parameter(context, s, strategy.cash_proxies, 'cash_proxies', list, N, type(symbols('SPY')[0]), ''), self._check_valid_parameter(context, s, strategy.strategy_allocation_mode, 'strategy_allocation_mode', str, 1, str, VALID_STRATEGY_ALLOCATION_MODES) self._check_valid_parameter(context, s, strategy.portfolio_weights, 'portfolio_weights', list, N, float, ''), self._check_valid_parameter(context, s, strategy.strategy_allocation_formula, 'strategy_allocation_formula', str, 1, str, VALID_STRATEGY_ALLOCATION_FORMULAS) self._check_valid_parameter(context, s, strategy.strategy_allocation_rule, 'strategy_allocation_rule', str, 1, str, '')
def initialize_portfolio(verbose=False): """Initialises pre-assembled fixed basket of ETFs, each with their own predefined risk buckets Currently contains Vanguard ETF strategic model portfolios (https://advisors.vanguard.com/iwe/pdf/FASINVMP.pdf) - CORES_SERIES - CRSP_SERIES - SP_SERIES - RUSSELL_SERIES - INCOME_SERIES - TAX_SERIES Ray Dalio's All-Weather Portfolio Returns: dict containing all added portfolios """ if verbose: print('Initialising portfolio database') all_portfolios = {} # Benchmarks # use [] for single ticker, so that it is iterable to avoid error 'int' object is not iterable add_portfolio(all_portfolios, 'BENCHMARK', 'SPY', symbols('SPY'), {0: [1]}) # 11 SPDR sector ETFs add_portfolio(all_portfolios, 'SPDR', 'ALL_SECTORS', symbols('XLE', 'XLRE', 'XLF', 'XLV', 'XLC', 'XLI', 'XLY', 'XLP', 'XLB', 'XLK', 'XLU'), { 0: tuple(1 for _ in range(11)) }) # Ray Dalio's All Weather Portfolio. Rebalancing once a year or more, with the following suggested distributions: # * 30% stocks (eg VTI) # * 40% long-term bonds (eg TLT) # * 15% intermediate-term bonds (eg IEF) # * 7.5% gold (eg GLD) # * 7.5% commodities (eg DBC) add_portfolio(all_portfolios, 'DALIO', 'ALL_WEATHER', symbols('VTI', 'TLT', 'IEF', 'GLD', 'DBC'), { 0: (0.3, 0.4, 0.15, 0.075, 0.075) }) # Vanguard Core Serie add_portfolio(all_portfolios, 'VANGUARD', 'CORE_SERIES', symbols('VTI', 'VXUS', 'BND', 'BNDX'), { 0: (0, 0, 0.686, 0.294), 1: (0.059, 0.039, 0.617, 0.265), 2: (0.118, 0.078, 0.549, 0.235), 3: (0.176, 0.118, 0.480, 0.206), 4: (0.235, 0.157, 0.412, 0.176), 5: (0.294, 0.196, 0.343, 0.147), 6: (0.353, 0.235, 0.274, 0.118), 7: (0.412, 0.274, 0.206, 0.088), 8: (0.470, 0.314, 0.137, 0.059), 9: (0.529, 0.353, 0.069, 0.029), 10: (0.588, 0.392, 0, 0) }) # add_portfolio(all_portfolios, 'VANGUARD', 'CRSP_SERIES', symbols('VUG', 'VTV', 'VB', 'VEA', 'VWO', 'BSV', 'BIV', 'BLV', 'VMBS', 'BNDX'), { # 0: (0, 0, 0, 0, 0, 0.273, 0.14, 0.123, 0.15, 0.294), # 1: (0.024, 0.027, 0.008, 0.03, 0.009, 0.245, 0.126, 0.111, 0.135, 0.265), # 2: (0.048, 0.054, 0.016, 0.061, 0.017, 0.218, 0.112, 0.099, 0.12, 0.235), # 3: (0.072, 0.082, 0.022, 0.091, 0.027, 0.191, 0.098, 0.086, 0.105, 0.206), # 4: (0.096, 0.109, 0.03, 0.122, 0.035, 0.164, 0.084, 0.074, 0.09, 0.176), # 5: (0.120, 0.136, 0.038, 0.152, 0.044, 0.126, 0.07, 0.062, 0.075, 0.147), # 6: (0.143, 0.163, 0.047, 0.182, 0.053, 0.109, 0.056, 0.049, 0.06, 0.118), # 7: (0.167, 0.190, 0.055, 0.213, 0.061, 0.082, 0.042, 0.037, 0.045, 0.088), # 8: (0.191, 0.217, 0.062, 0.243, 0.071, 0.055, 0.028, 0.024, 0.030, 0.059), # 9: (0.215, 0.245, 0.069, 0.274, 0.079, 0.027, 0.014, 0.013, 0.015, 0.029), # 10: (0.239, 0.272, 0.077, 0.304, 0.088, 0, 0, 0, 0, 0) # }) # add_portfolio(all_portfolios, 'VANGUARD', 'SP_SERIES', symbols('VOO', 'VXF', 'VEA', 'VWO', 'BSV', 'BIV', 'BLV', 'VMBS', 'BNDX'), { # 0: (0, 0, 0, 0, 0.273, 0.140, 0.123, 0.150, 0.294), # 1: (0.048, 0.011, 0.03, 0.009, 0.245, 0.126, 0.111, 0.135, 0.265), # 2: (0.097, 0.021, 0.061, 0.017, 0.218, 0.112, 0.099, 0.12, 0.235), # 3: (0.145, 0.031, 0.091, 0.027, 0.191, 0.098, 0.086, 0.105, 0.206), # 4: (0.194, 0.041, 0.0122, 0.035, 0.164, 0.084, 0.074, 0.09, 0.176), # 5: (0.242, 0.052, 0.152, 0.044, 0.136, 0.07, 0.062, 0.075, 0.147), # 6: (0.29, 0.063, 0.182, 0.053, 0.109, 0.056, 0.049, 0.06, 0.118), # 7: (0.339, 0.073, 0.213, 0.061, 0.082, 0.042, 0.037, 0.045, 0.088), # 8: (0.387, 0.083, 0.243, 0.071, 0.055, 0.028, 0.024, 0.03, 0.059), # 9: (0.436, 0.093, 0.274, 0.079, 0.027, 0.014, 0.013, 0.015, 0.029), # 10: (0.484, 0.104, 0.304, 0.088, 0, 0, 0, 0, 0) # }) # add_portfolio(all_portfolios, 'VANGUARD', 'RUSSELL_SERIES', symbols('VONG', 'VONV', 'VTWO', 'VEA', 'VTWO', 'VEA', 'VWO', 'BSV', 'BIV', 'BLV', 'VMBS', 'BNDX'), { # 0: (0, 0, 0, 0, 0, 0.273, 0.14, 0.123, 0.15, 0.294), # 1: (0.028, 0.026, 0.005, 0.03, 0.009, 0.245, 0.126, 0.111, 0.135, 0.265), # 2: (0.056, 0.052, 0.01, 0.061, 0.017, 0.218, 0.112, 0.099, 0.086, 0.105, 0.206), # 3: (0.084, 0.079, 0.013, 0.091, 0.027, 0.191, 0.098, 0.086, 0.105, 0.206), # 4: (0.112, 0.105, 0.018, 0.122, 0.035, 0.164, 0.084, 0.074, 0.09, 0.176, 0.02), # 5: (0.14, 0.131, 0.023, 0.152, 0.044, 0.136, 0.07, 0.062, 0.075, 0.147), # 6: (0.168, 0.157, 0.028, 0.182, 0.053, 0.109, 0.056, 0.049, 0.06, 0.118), # 7: (0.196, 0.184, 0.032, 0.213, 0.061, 0.082, 0.042, 0.037, 0.045, 0.088), # 8: (0.224, 0.210, 0.036, 0.243, 0.071, 0.055, 0.028, 0.024, 0.03, 0.059), # 9: (0.252, 0.236, 0.041, 0.274, 0.079, 0.027, 0.014, 0.013, 0.015, 0.029), # 10: (0.281, 0.262, 0.045, 0.304, 0.088, 0, 0, 0, 0, 0) # }) # add_portfolio(all_portfolios, 'VANGUARD', 'INCOME_SERIES', symbols('VTI', 'VYM', 'VXUS', 'VYMI', 'BND', 'VTC', 'BNDX'), { # 0: (0, 0, 0, 0, 0.171, 0.515, 0.294), # 1: (0.015, 0.044, 0.01, 0.029, 0.154, 0.463, 0.265), # 2: (0.03, 0.088, 0.019, 0.059, 0.137, 0.412, 0.235), # 3: (0.044, 0.132, 0.03, 0.088, 0.12, 0.36, 0.206), # 4: (0.059, 0.176, 0.039, 0.118, 0.103, 0.309, 0.176), # 5: (0.073, 0.221, 0.049, 0.147, 0.086, 0.257, 0.147), # 6: (0.088, 0.265, 0.059, 0.176, 0.068, 0.206, 0.118), # 7: (0.103, 0.309, 0.068, 0.206, 0.052, 0.154, 0.088), # 8: (0.117, 0.353, 0.079, 0.235, 0.034, 0.103, 0.059), # 9: (0.132, 0.397, 0.088, 0.265, 0.018, 0.051, 0.029), # 10: (0.147, 0.441, 0.098, 0.294, 0, 0, 0) # }) # add_portfolio(all_portfolios, 'VANGUARD', 'TAX_SERIES', symbols('VUG', 'VTV', 'VB', 'VEA', 'VWO', 'VTEB'), { # 1: (0.024, 0.027, 0.008, 0.03, 0.009, 0.882), # 2: (0.048, 0.054, 0.016, 0.061, 0.017, 0.784), # 3: (0.072, 0.082, 0.022, 0.091, 0.027, 0.686), # 4: (0.096, 0.109, 0.03, 0.122, 0.035, 0.588), # 5: (0.12, 0.136, 0.038, 0.152, 0.044, 0.49), # 6: (0.143, 0.163, 0.047, 0.182, 0.053, 0.392), # 7: (0.167, 0.190, 0.055, 0.213, 0.061, 0.294), # 8: (0.191, 0.217, 0.062, 0.243, 0.071, 0.196), # 9: (0.215, 0.245, 0.069, 0.274, 0.079, 0.098) # }) return all_portfolios
def get_data(ENVIRONMENT, tickers, start, end, benchmark, risk_free, cash_proxy): if ENVIRONMENT == 'ZIPLINE': benchmark_symbol = benchmark cash_proxy_symbol = cash_proxy risk_free_symbol = risk_free elif ENVIRONMENT == 'RESEARCH': benchmark_symbol = symbols(benchmark) cash_proxy_symbol = symbols(cash_proxy) risk_free_symbol = symbols(risk_free) # data is a Panel of DataFrames, one for each security if ENVIRONMENT == 'ZIPLINE': data = load_bars_from_yahoo( stocks = list(set(tickers + [benchmark_symbol, cash_proxy_symbol, risk_free_symbol])), start = start, end = end, adjusted=False).transpose(2,1,0) data.price = data.close # use this for comparing to Quantopian 'get_pricing' elif ENVIRONMENT == 'RESEARCH': data = get_pricing( set(tickers + [benchmark_symbol, cash_proxy_symbol, risk_free_symbol]), start_date=start, end_date = end, frequency='daily' ) # repair unusable data # BE CAREFUL!! dropna doesn't change the Panel's Major Index, so NA may still remain! # safer to use ffill for security in data.transpose(2,1,0): data.transpose(2,1,0)[security] = data.transpose(2,1,0)[security].ffill() if ENVIRONMENT == 'ZIPLINE': other_data = load_bars_from_yahoo( stocks=[benchmark_symbol] + [cash_proxy_symbol], start=start, end=end, adjusted=False) # use this for comparing to Quantopian 'get_pricing' other_data.transpose(2,1,0).price = other_data.transpose(2,1,0).close # use this for comparing to Quantopian 'get_pricing' elif ENVIRONMENT == 'RESEARCH': other_data = get_pricing( [benchmark_symbol] + [cash_proxy_symbol], fields='price', start_date= data.major_axis[0], end_date = data.major_axis[-1], frequency='daily', ) other_data = other_data.ffill() # need to add benchmark (eg SPY) and cash proxy to data panel benchmark = other_data[benchmark_symbol] benchmark_rets = benchmark.pct_change().dropna() benchmark2 = other_data[cash_proxy_symbol] benchmark2_rets = benchmark2.pct_change().dropna() # make sure we have all the data we need inception_dates = pd.DataFrame([data.transpose(2,1,0)[security].dropna().index[0].date() \ for security in data.transpose(2,1,0)], \ index=data.transpose(2,1,0).items, columns=['inception']) inception_dates.loc['benchmark'] = benchmark.index[0].date() inception_dates.loc['benchmark2'] = benchmark2.index[0].date() print(inception_dates) print() # check that the end dates coincide end_dates = pd.DataFrame([data.transpose(2,1,0)[security].dropna().index[-1].date() \ for security in data.transpose(2,1,0)], \ index=data.transpose(2,1,0).items, columns=['end_date']) end_dates.loc['benchmark'] = benchmark.index[-1].date() end_dates.loc['benchmark2'] = benchmark2.index[-1].date() print(end_dates) # this will ensure that the strat and end dates are aligned data = data[:,inception_dates.values.max(): end_dates.values.min(),:] benchmark_rets = benchmark_rets[inception_dates.values.max(): end_dates.values.min()] benchmark2_rets = benchmark2_rets[inception_dates.values.max(): end_dates.values.min()] print ('\n\nBACKTEST DATA IS FROM {} UNTIL {} \n*************************************************' .format(inception_dates.values.max(), end_dates.values.min())) # DATA FROM ZIPLINE LOAD_YAHOO_BARS DIFFERS FROM RESEARCH ENVIRONMENT! data.items = ['open_price', 'high', 'low', 'close_price', 'volume', 'price'] print ('\n\n{}'.format(data)) return data
def _check_valid_portfolio(self, pfolio): if len(pfolio) < 1: raise RuntimeError('Portfolio must have at least one item') for n in range(len(pfolio)): if not isinstance(pfolio[n], type(symbols('SPY')[0])): raise RuntimeError('portfolio item {} must be of type '.format(type(symbols('SPY')[0])))
def initialize (context) : # Algorithm parameters are defined here if ENVIRONMENT == 'RESEARCH': context.benchmark = symbols('SPY') context.risk_free = symbols('SHY') context.cash_proxy = symbols('SHY') elif ENVIRONMENT == 'ZIPLINE' or ENVIRONMENT == 'IDE': context.benchmark = symbol('SPY') context.risk_free = symbol('SHY') context.cash_proxy = symbol('SHY') context.algo_transforms = [(['price'], ROCP, ['mom_63'], 62), (['price'], ROCP, ['mom_21'], 20), (['price'], average_historic_volatility, ['hvol_20'], 63, 20), (['price'], SMA, ['short_mavg'], 21), (['price'], SMA, ['long_mavg'], 63) ] if ENVIRONMENT == 'ZIPLINE' or ENVIRONMENT == 'IDE': context.strategies = { 'strategy1': { 'strat_wt' : 1.0, 'strat_type' : 'SIGNAL', 'alloc_type' : 'EQWT', 'portfolios' : [ symbols('VHT', 'VGT', 'VCR', 'IBB', 'EDV', 'VB', 'VAW', 'TLT') ], 'weights' : [1.0], 'n_top' : [1], 'zscore_data' : ['+mom_63', '+mom_21', '-hvol_20'], 'zscore_weights' : [0.7, 0.0, 0.3], # 'filter' : [lambda x,y: (x > y) & (x > 0), 'mom_21', ('mom_21', context.risk_free)] # 'filter' : [] 'filter' : [lambda x,y: x > y, 'mom_63', ('mom_63', context.risk_free)], 'buy_trigger' : [lambda x,y: (x > y) and (context.buy_flag==False), 'short_mavg', 'long_mavg'], 'sell_trigger' : [lambda x,y : (x < y) and (context.buy_flag==True), 'short_mavg', 'long_mavg'] } } elif ENVIRONMENT == 'RESEARCH': context.strategies = { 'strategy1': { 'strat_wt' : 1.0, 'strat_type' : 'SIGNAL', 'alloc_type' : 'EQWT', 'portfolios' : [ [symbols('VHT'), symbols('VGT'), symbols('VCR'), symbols('IBB'), symbols('EDV'), symbols('VB'), symbols('VAW'), symbols('TLT')] ], 'weights' : [1.0], 'n_top' : [1], 'zscore_data' : ['+mom_63', '+mom_21', '-hvol_20'], 'zscore_weights' : [0.7, 0.0, 0.3], # 'filter' : [lambda x,y: (x > y) & (x > 0), 'mom_21', # ('mom_21', context.risk_free)] # 'filter' : [] 'filter' : [lambda x,y: x > y, 'mom_63', ('mom_63', context.risk_free)], 'buy_trigger' : [lambda x,y: (x > y) and (context.buy_flag==False), 'short_mavg', 'long_mavg'], 'sell_trigger' : [lambda x,y : (x < y) and (context.buy_flag==True), 'short_mavg', 'long_mavg'] } } # have to set this manually 'til I figure how to generate it programmatically from above parameters context.max_lookback = 120 # need additional data for recursive indicators like EMA, historic_vol etc. # set the appropriate time_rule offsets (hours, minutes) for order processing context.order_time_rule = time_rules.market_close(hours=0, minutes=1) context.threshold = 0.0 # only BUY/SELL if asset QTY changes by threshold% set_commission(commission.PerTrade(cost=0.0)) set_slippage(slippage.FixedSlippage(spread=0)) ####################################################################################### # THE FOLLOWING MUST ALWAYS BE INCLUDED AND MUST PRECEDE ANY SCHEDULED FUNCTIONS! # include this check to make sure that the algo parameters are formatted as required check_algo_parameters (context) # create a set of all the symbols used by the algorithm create_symbol_list(context) initialize_strat_variables(context) if ENVIRONMENT != 'IDE': add_strat_history(context) ####################################################################################### schedule_function(generate_strat_data, # date_rule=date_rules.month_start(days_offset=0), date_rule=date_rules.month_start(days_offset=0), time_rule=time_rules.market_open(hours=0, minutes=1), half_days=True) # schedule_function_by_interval(context, test_signal, # date_rule=date_rules.every_day(), # time_rule=time_rules.market_open(hours=0, minutes=5), # half_days=True, # freq=1) # the 'freq' parameter is added to the norma schedule_function routine # to enable intervals of 'freq' periods - 1,2,3,..... months schedule_function_by_interval(context, rebalance, date_rule=date_rules.month_start(days_offset=0), time_rule=time_rules.market_open(hours=0, minutes=5), half_days=True, freq=1) schedule_function_by_interval(context, handle_orders, date_rule=date_rules.month_start(days_offset=0), time_rule=time_rules.market_close(hours=0, minutes=15), half_days=True, freq=1)