def trade_di(context, data, window, portfolio, capital_ppi, log): ''' zipline trading algorithm that uses the Directional Indicator system for trending instruments :param context: the context for the trading system :param data: data for the trading system :param window: the DI window period :param portfolio: instruments to trade :param capital_ppi: capital % per instrument :param log: log to use for trading system :type context: `zipline.algorithm.TradingAlgorithm` :type data: `zipline.data.data_portal.DataPortal` :type window: `int` :type portfolio: `list` of `zipline.assets._assets` objects (e.g. `Equity`) :type capital_ppi: `Decimal` :type log: `logbook.Logger` or `Mock` object expects the following in `context`: :param i: iteration counter :param portfolio: current positions :type i: `int` :type portfolio: `zipline.protocol.Portfolio` ''' # ensure we have enough history if context.i < window + 1: return # step through each instrument for i in portfolio: # calculate plus and minus directional movement indicators input = { 'high': data.history(i, 'high', window + 1, '1d'), 'low': data.history(i, 'low', window + 1, '1d'), 'close': data.history(i, 'close', window + 1, '1d'), } (plus_di, minus_di) = (PLUS_DI(input), MINUS_DI(input)) p = context.portfolio.positions v = (i.symbol, plus_di[-1], minus_di[-1]) # go long if plus directional movement is greater if plus_di[-1] >= minus_di[-1]: if (i not in p) or (i in p and p[i].amount <= 0): log.info('long %s (+DI %s >= -DI %s)' % v) order_percent(i, capital_ppi) # go short if minus directional movement is greater else: if (i not in p) or (i in p and p[i].amount >= 0): log.info('short %s (+DI %s < -DI %s)' % v) order_percent(i, -capital_ppi)
def rebalance(context, data): month = context.get_datetime().month if month in [2, 5, 8, 11] and context.reb_flag: # 原始持仓权重 weight_old = get_weight(context) # 目标持仓权重 print context.rank_score h = np.nanpercentile(context.rank_score, 100 - context.percent, interpolation='higher') fund_pool = context.rank_score[context.rank_score >= h] # 过滤年轻基金 longevit = 252 * 1 fund_data = data.history(fund_pool.index, 'close', longevit, '1d') selected = fund_pool[fund_data.dropna(how='any', axis=0).columns] print selected weight_new = pd.Series(0.98 / len(selected), index=selected.index) # 仓位变动百分比计算 change = {} for stock in weight_new.keys(): if stock not in weight_old.keys(): change[stock] = weight_new[stock] else: change[stock] = weight_new[stock] - weight_old[stock] # 下订单 for stock in sorted(change, key=change.get): order_percent(stock, change[stock]) # 残余头寸清仓处理 for stock in weight_old.keys(): if stock not in weight_new.keys(): order_target_percent(stock, 0) record(weights=weight_new) print '调仓了:' print weight_new
def stop_loss(context, stock_to_sell, data): # 止损: 将 stock 仓位降低为0,并调入货币基金 # replace_stock: 调入的货币基金, 目前使用OF110006 # stock: 将要进行止损的基金 # flag: 判断 replace_stock 是否存在于原有仓位中 # weight 原有仓位权重 # stop_weight: 止损仓位,等于原始仓位重stock 的权重 flag = False #初始值为货币基金不在持仓当中 replace_stock = "110006.OF" weight = get_weight(context) stop_weight = weight[stock_to_sell] stocks = get_weight(context).keys() for stock in stocks: if stock.symbol == replace_stock: flag = True # 记录仓位及价格变动 weight = weight.drop(stock_to_sell) if flag: weight[symbol( replace_stock)] = stop_weight + weight[symbol(replace_stock)] else: weight[symbol(replace_stock)] = stop_weight weight = weight / np.sum(weight) # 更新 调入货币基金 的成本价格 context.init_value[symbol(replace_stock)] = data[symbol( replace_stock)]["price"] record(weights=weight) record(rebalance_reason=STOPLOSS) # 止损+调入货币基金下单 order_target_percent(stock_to_sell, 0) order_percent(symbol(replace_stock), stop_weight)
def handle_data(self, data): from zipline.api import ( order_percent, order_target, order_target_percent, order_target_value, order_value, ) for style in [ MarketOrder(), LimitOrder(10), StopOrder(10), StopLimitOrder(10, 10) ]: with assert_raises(UnsupportedOrderParameters): order(self.asset, 10, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order(self.asset, 10, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_value(self.asset, 300, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_value(self.asset, 300, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_percent(self.asset, .1, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_percent(self.asset, .1, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target(self.asset, 100, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target(self.asset, 100, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_value(self.asset, 100, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_value(self.asset, 100, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_percent(self.asset, .2, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_percent(self.asset, .2, stop_price=10, style=style)
def handle_data(context, data): post_initialize(context, data) handle_terminations(context) handle_countdowns(context, data) old_data_counts = len(context.data_countdowns) handle_price_histories(context, data) new_data_counts = len(context.data_countdowns) if len( context.x ) > context.data_points_necessary and new_data_counts > old_data_counts: context.model.fit(context.x, context.y) new_counts = context.data_countdowns[old_data_counts:] for idx, stock_tuple in enumerate(new_counts): prediction = context.model.predict( get_x_point(context, data, stock_tuple.ticker, stock_tuple.move_return)) record(prediction={1: 1, 0: -1}[int(prediction)]) order_percent(stock_tuple.ticker, { 1: 1, 0: -1 }[int(prediction)] * (1.0 / len(data))) context.to_terminate.append( (stock_tuple.ticker, context.number_days_after)) tmp_tuple = context.data_countdowns[old_data_counts + idx] tmp_tuple = context.StockTuple(tmp_tuple[0], tmp_tuple[1], tmp_tuple[2], tmp_tuple[3], bool(prediction)) context.data_countdowns[old_data_counts + idx] = tmp_tuple
def handle_data(context, data): # Skip first 90 days to get full windows if context.day < context.DAYS_CUMULATIVE: context.day += 1 return if context.day % context.REFORM_PERIOD != 0: context.day += 1 return context.day += 1 # For each stock, compute gain in last 90 days d = {} for ticker in context.tickers: # Compute averages # data.history() has to be called with the same params # from above and returns a pandas dataframe. try: df = data.history(symbol(ticker), 'close', bar_count=context.DAYS_CUMULATIVE, frequency="1d") start_price = df.iloc[:1].tolist()[0] end_price = df.iloc[-1:].tolist()[0] gain = float(end_price) / start_price if not math.isnan(gain): d[ticker] = gain except SymbolNotFound as e: # print "WARN: Unable to get data for %s" % ticker print '', # Sort all tickers by there gain in ascending order sorted_d = sorted(d.items(), key=operator.itemgetter(1)) portfolio_with_gain = sorted_d[-context.PORTFOLIO_SIZE:] portfolio = [i[0] for i in portfolio_with_gain] capital_each_share = context.STARTING_CASH / context.PORTFOLIO_SIZE # Trading logic for stock in portfolio: if stock not in context.my_portfolio_quantity.keys(): quantity = int(capital_each_share / data.current(symbol(stock), 'close')) order_percent(symbol(stock), 1.0 / context.PORTFOLIO_SIZE) context.my_portfolio_quantity[stock] = quantity for stock in context.my_portfolio_quantity.keys(): if stock not in portfolio: quantity = context.my_portfolio_quantity[stock] del context.my_portfolio_quantity[stock] order_target_percent(symbol(stock), 0.0) # Printing each portfolio print "day %d" % context.day print portfolio print '\n\n'
def trade_so(context, data, window, portfolio, capital_ppi, log): ''' zipline trading algorithm that uses the Stochastic Oscillator system for trending instruments :param context: the context for the trading system :param data: data for the trading system :param window: the SO window period :param portfolio: instruments to trade :param capital_ppi: capital % per instrument :param log: log to use for trading system :type context: `zipline.algorithm.TradingAlgorithm` :type data: `zipline.data.data_portal.DataPortal` :type window: `int` :type portfolio: `list` of `zipline.assets._assets` objects (e.g. `Equity`) :type capital_ppi: `Decimal` :type log: `logbook.Logger` or `Mock` object expects the following in `context`: :param i: iteration counter :param portfolio: current positions :type i: `int` :type portfolio: `zipline.protocol.Portfolio` ''' # ensure we have enough history if context.i < window + 4: return # step through each instrument for i in portfolio: # calculate plus and minus directional movement indicators input = { 'high': data.history(i, 'high', window + 4, '1d'), 'low': data.history(i, 'low', window + 4, '1d'), 'close': data.history(i, 'close', window + 4, '1d'), } STOCH.set_parameters({'fastk_period': window}) (so_k, so_d) = STOCH(input) p = context.portfolio.positions v = (i.symbol, so_k[-1], so_d[-1]) # go long if %K line crosses above %D line if so_k[-1] >= so_d[-1]: if (i not in p) or (i in p and p[i].amount <= 0): log.info('long %s (K %s >= D %s)' % v) order_percent(i, capital_ppi) # go short if %K line crosses below %D line else: if (i not in p) or (i in p and p[i].amount >= 0): log.info('short %s (K %s < D %s)' % v) order_percent(i, -capital_ppi)
def trade(self, shorts, longs): print("do sell .....", shorts) for stock in shorts: order_percent(symbol(stock), shorts[stock]) del self.stocks[stock] print("do buy .....", longs) for stock in longs: order_percent(symbol(stock), longs[stock]) self.stocks[stock] = True pass
def handle_data(self, data): from zipline.api import ( order_percent, order_target, order_target_percent, order_target_value, order_value, ) for style in [MarketOrder(), LimitOrder(10), StopOrder(10), StopLimitOrder(10, 10)]: with assert_raises(UnsupportedOrderParameters): order(self.asset, 10, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order(self.asset, 10, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_value(self.asset, 300, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_value(self.asset, 300, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_percent(self.asset, .1, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_percent(self.asset, .1, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target(self.asset, 100, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target(self.asset, 100, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_value(self.asset, 100, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_value(self.asset, 100, stop_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_percent(self.asset, .2, limit_price=10, style=style) with assert_raises(UnsupportedOrderParameters): order_target_percent(self.asset, .2, stop_price=10, style=style)
def rebalance(context, data): stocks = context.stocks df_index = context.df_index hist = data.history(stocks, 'close', drowdown_para, '1d') hist = hist.dropna(how='any', axis=1) for i in df_index.index: j = symbol(df_index.loc[i][0]) if j in hist.columns: try: hist = hist.drop(symbol(i), 1) except: pass else: continue print hist.iloc[-1, :] back_holding_period = drowdown_para # window length for expected return return_period = return_para # window length for covariance matrix, 不能超过有效数据长度,否则会出错 cov_period = cov_para # get the stock list available for trading # stocks = context.get_universe(data) # calculate the optimized portfolio weight weight_new = iter_opt(context, hist, context.mdd, back_holding_period, return_period, cov_period, df_index) # 小与p=0.05的基金被筛除掉 weight_new = fix_fund_order(weight_new) print '调仓了' print weight_new record(weights=weight_new) # 下单 weight_old = get_weight(context) for stock in weight_old.keys(): if stock not in weight_new.keys(): order_target_percent(stock, 0) change = {} for stock in weight_new.keys(): if stock not in weight_old.keys(): change[stock] = weight_new[stock] else: change[stock] = weight_new[stock] - weight_old[stock] for stock in sorted(change, key=change.get): order_percent(stock, change[stock]) # 下单完成,记录最大净值变化 context.init_value = pd.Series(np.zeros(weight_new.size), index=weight_new.keys()) for stock in weight_new.keys(): cost_price = hist[stock][-1] context.init_value[stock] = cost_price
def handle_data(context, data): # # Bad news flag # flag_bad = False # try: # # Get history data() # data_hist = data.history(context.security, 'price', 5, '1d') # if data_hist[0] > data_hist[1] and data_hist[1] > data_hist[2] and data_hist[2] > data_hist[3] and data_hist[3] > data_hist[4]: # flag_bad = True # except Exception as e: # pass # Get current date now = str(get_datetime('US/Eastern'))[0:11] + "00:00:00+0000" # Get current state state = context.TP_matrixs.ix[now].values # Predict using the estimator predictions = context.cnn_estimator.predict(x=state.astype(np.float32), as_iterable=False) ratio_predict = predictions["results"][0][0] mylogger.logger.info(ratio_predict) # Execute chosen action now = now[0:10] if ratio_predict < context.threshold_down: # Sell # No short if context.portfolio.positions[context.security].amount > 0: order_target_percent(context.security, 0) mylogger.logger.info(now + ': sell') action = "sell" elif context.portfolio.positions[context.security].amount == 0: mylogger.logger.info(now + ': No short!') action = "hold" elif ratio_predict > context.threshold_up: # Buy # No cover if context.portfolio.cash > 0: order_percent(context.security, 1) mylogger.logger.info(now + ': buy') mylogger.logger.info(context.portfolio.cash) action = "buy" else: mylogger.logger.info(now + ': No cover!') action = "hold" else: # Hold mylogger.logger.info(now + ': hold') action = "hold" # Save values for later inspection record(AAPL=data.current(context.security, 'price'), actions=action)
def handle_data(context, data): for symb in filter(data.__contains__, map(symbol, context.panel.axes[0].values)): prev = context.prev_prices.setdefault(symb, []) prev.append(data[symb].price) del prev[:-500] if len(prev) > 5: lr = LinearRegression().fit(np.arange(len(prev)).reshape((-1, 1)), prev) pred = lr.predict(np.asarray([len(prev)]).reshape((-1, 1)))[0] to_order = (prev[-1] - pred) / prev[-1] * 10. if abs(to_order) > .1: to_order /= 10. * abs(to_order) order_percent(symb, to_order)
def handle_data(context, data): for symb in filter(data.__contains__, map(symbol, context.panel.axes[0].values)): prev = context.prev_prices.setdefault(symb, []) prev.append(data[symb].price) del prev[:-500] if len(prev) > 5: lr = LinearRegression().fit( np.arange(len(prev)).reshape((-1, 1)), prev) pred = lr.predict(np.asarray([len(prev)]).reshape((-1, 1)))[0] to_order = (prev[-1] - pred) / prev[-1] * 10. if abs(to_order) > .1: to_order /= 10. * abs(to_order) order_percent(symb, to_order)
def handle_data(context, data): context.i += 1 short, long = 20, 100 if context.i < long: return sma = data.history(context.sym, 'price', short, '1d').mean() lma = data.history(context.sym, 'price', long, '1d').mean() if sma > lma: order_percent(context.sym, 1) else: # elif sma < lma: # order_percent(context.sym, 0) pass record(AAPL=data.current(context.sym, "price"), sma=sma, lma=lma)
def handle_data(context, data): post_initialize(context, data) handle_terminations(context) handle_countdowns(context, data) old_data_counts = len(context.data_countdowns) handle_price_histories(context, data) new_data_counts = len(context.data_countdowns) if len(context.x) > context.data_points_necessary and new_data_counts > old_data_counts: context.model.fit(context.x, context.y) new_counts = context.data_countdowns[old_data_counts:] for idx, stock_tuple in enumerate(new_counts): prediction = context.model.predict( get_x_point(context, data, stock_tuple.ticker, stock_tuple.move_return) ) record(prediction={1: 1, 0: -1}[int(prediction)]) order_percent(stock_tuple.ticker, {1: 1, 0: -1}[int(prediction)] * (1.0 / len(data))) context.to_terminate.append((stock_tuple.ticker, context.number_days_after)) tmp_tuple = context.data_countdowns[old_data_counts + idx] tmp_tuple = context.StockTuple( tmp_tuple[0], tmp_tuple[1], tmp_tuple[2], tmp_tuple[3], bool(prediction) ) context.data_countdowns[old_data_counts + idx] = tmp_tuple
def rebalance(context, data, stocks): hist = data.history(stocks, 'close', LOOKBACK_PERIOD, '1d') N = len(stocks) X1 = np.array(hist.iloc[0:T - 1, :]) X2 = np.array(hist.iloc[1:T, :]) ReturnMatrix = (X2 - X1) / X1 Cov_Var = np.cov(ReturnMatrix.T) Var = [] for n in range(0, N): Var.append(np.var(ReturnMatrix[:, n])) StdVar = np.sqrt(Var) p = np.zeros((N, N)) y = np.zeros((N + 1, 1)) w = np.zeros((N, 1)) w_1 = np.zeros((N, 1)) w_2 = np.zeros((N, 1)) for m in range(0, N): for n in range(0, N): p[m, n] = Cov_Var[m, n] / StdVar[m] / StdVar[n] for n in range(0, N): y[n, 0] = 0.5 y[N, 0] = 0.5 for j in range(0, 1000): for n in range(0, N): w[n, 0] = y[n, 0] lamda = y[N, 0] for n in range(0, N): w_1[n, 0] = 1 / w[n, 0] w_2[n, 0] = 1 / w[n, 0] / w[n, 0] F1 = np.dot(Cov_Var, w) - lamda * w_1 S = np.zeros((1, 1)) F = np.concatenate((F1, S)) F[N, 0] = 0 for n in range(0, N): F[N, 0] = F[N, 0] + w[n, 0] F[N, 0] = F[N, 0] - 1 D = np.zeros((N, N)) for p in range(0, N): D[p, p] = w_2[p, 0] J = Cov_Var + lamda * D S = -w_1 J = np.hstack((J, S)) S = np.ones((1, N + 1)) J = np.concatenate((J, S)) c = w c = np.concatenate((c, np.zeros((1, 1)))) c[N, 0] = lamda y = c - np.dot(np.linalg.inv(J), F) j = j + 1 W = np.zeros((N)) for n in range(0, N): W[n] = y[n, 0] weight_new = pd.Series(W, index=hist.columns) print("在{}调仓了!".format(str(get_datetime()))) print(weight_new) record(weights=weight_new) # record(rebalance_reason=REBALANCE.format(**{"date":get_datetime().strftime( # "%Y年%m月%d日")})) record(TRC=y[-1, 0]) record(MRC=y[-1, 0] / y[:-1, 0]) context.weights = weight_new # 下单 weight_old = get_weight(context) # print weight_old for stock in weight_old.keys(): if stock not in weight_new.keys(): order_target_percent(stock, 0) change = {} for stock in weight_new.keys(): if stock not in weight_old.keys(): change[stock] = weight_new[stock] else: change[stock] = weight_new[stock] - weight_old[stock] for stock in sorted(change, key=change.get): order_percent(stock, change[stock])