def handle_data(context, data): context.iwarmup = context.iwarmup + 1 if context.iwarmup <= (context.history_depth + 1): return dfHistD = history(30, '1d', 'price') S = context.secs[0] CurP = data[S].price BolU, BolM, BolL = talib.BBANDS(dfHistD[S].values, timeperiod=context.BBANDS_timeperiod, nbdevup=context.BBANDS_nbdevup, nbdevdn=context.BBANDS_nbdevdn, matype=0) record(CurP=CurP, BolU=BolU[-1], BolM=BolM[-1], BolL=BolL[-1]) if CurP < BolL[-1]: order_target_percent(S, +0.97) elif CurP > BolU[-1]: order_target_percent(S, -0.97) return
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 rebalance(context, data): """ Execute orders according to our schedule_function() timing. """ predictions = context.predicted_returns # Drop stocks that can not be traded predictions = predictions.loc[data.can_trade(predictions.index)] longs = (predictions[predictions > 0] .sort_values(ascending=False)[:N_LONGS] .index .tolist()) shorts = (predictions[predictions < 0] .sort_values()[:N_SHORTS] .index .tolist()) targets = set(longs + shorts) for position in context.portfolio.positions: if position not in targets: order_target(position, 0) n_longs, n_shorts = len(longs), len(shorts) if n_longs > MIN_POSITIONS and n_shorts > MIN_POSITIONS: for stock in longs: order_target_percent(stock, target=1/n_longs) for stock in shorts: order_target_percent(stock, target=-1/n_shorts) else: for stock in targets: if stock in context.portfolio.positions: order_target(stock, 0)
def handle_data(context, data): # Skip first 300 days to get full windows date = get_datetime() context.i += 1 if context.i < 10: return prices = history(25, '1d', 'price') for sym in data: upper, middle, lower = talib.BBANDS( np.array(prices[sym]), timeperiod=20, nbdevup=2, nbdevdn=2, matype=0 ) potential_buy = [] buy = False sell = False if data[sym].price > upper[-1] and context.portfolio.positions[sym].amount == 0: # log.info('buy') # log.info(get_datetime()) # log.info(data[sym].price) # log.info(upper[-1]) order_target_percent(sym, 1.0, limit_price=data[sym].price) elif data[sym].price < middle[-1] and context.portfolio.positions[sym].amount > 0: # log.info('sell') # log.info(get_datetime()) # log.info(data[sym].price) # log.info(middle[-1]) order_target(sym, 0, limit_price=data[sym].price)
def handle_data(self, context, data): rebalance_period = 20 context.tick += 1 if context.tick % rebalance_period != 0: return # Get rolling window of past prices and compute returns prices_6m = history(120, '1d', 'price').dropna() returns_6m = prices_6m.pct_change().dropna() prices_60d = history(60, '1d', 'price').dropna() returns_60d = prices_60d.pct_change().dropna() try: # Get the strongest 5 in momentum mom = returns_6m.T.sum(axis=1) selected = (mom > np.median(mom)) * 1 # 60 days volatility vol = np.std(returns_60d.T, axis=1) vol_target = 0.01 wt = vol_target / vol * 0.2 wt[wt > 0.2] = 0.2 # weights = wt * selected # Rebalance portfolio accordingly for stock, weight in zip(prices_60d.columns, weights): order_target_percent(stock, weight) except ValueError as e: # Sometimes this error is thrown # ValueError: Rank(A) < p or Rank([P; A; G]) < n pass
def handle_data(self, context, data): rebalance_period = 20 context.tick += 1 if context.tick < 120: return if context.tick % rebalance_period != 0: return # Get rolling window of past prices and compute returns prices_6m = history(120, '1d', 'price').dropna() returns_6m = prices_6m.pct_change().dropna() prices_60d = history(60, '1d', 'price').dropna() returns_60d = prices_60d.pct_change().dropna() try: # Get the strongest 5 in momentum mom = returns_6m.T.sum(axis=1) #selected_indices = mom[mom>0].order().tail(len(mom) /2).index selected_indices = mom.index #selected_indices = mom[mom > 0 ].index selected_returns = returns_60d[selected_indices] weights = self.minimize_vol(selected_returns.T) # weights = minimize_vol(returns_60d.T) # Rebalance portfolio accordingly for stock, weight in zip(selected_returns.columns, weights): order_target_percent(stock, weight) except: # Sometimes this error is thrown # ValueError: Rank(A) < p or Rank([P; A; G]) < n pass
def handle_data(context, data): trading_date = data.history(context.asset1, ['close'], bar_count=1, frequency='1d').index[0].date() context.i += 1 asset1_close = data.history(context.asset1, ['price'], bar_count=1, frequency='1d').price.values[0] asset2_close = data.history(context.asset2, ['price'], bar_count=1, frequency='1d').price.values[0] spread = asset1_close - asset2_close record(S1=asset1_close, S2=asset2_close, spread=spread, action=context.today_action) action = my_round(context.today_action) if action != context.previous_action: signal_percent = action / 2 order_target_percent(context.asset1, signal_percent) order_target_percent(context.asset2, -signal_percent) context.previous_action = action if context.i % 100 == 0: print(trading_date) print(context.portfolio) if context.tensorboard is not None: # record algo stats to tensorboard context.tensorboard.log_algo(context, epoch=context.i)
def rebalance(context, data): history = data.history(assets=context.asset, fields=['close'], bar_count=context.tema_window * 4, frequency='1d') date = history.index.values[-1] close = history['close'].values tema = ta.TEMA(close, timeperiod=context.tema_window) current_price = data[context.asset].price record(price=current_price) buy_signal_triggered = False sell_signal_triggered = False if current_price > tema[-1]: buy_signal_triggered = True elif current_price < tema[-1]: sell_signal_triggered = True current_position = context.portfolio.positions[context.asset].amount if buy_signal_triggered and current_position == 0: print(str(date) + '==>Buy') order_target_percent(context.asset, 1.0) elif sell_signal_triggered and current_position > 0: print(str(date) + '==>Sell') order_target_percent(context.asset, 0.0) else: print("No trading")
def rebalance(context, data): # update the fundamentals data if not context.initial: get_fundamentals(context, data) # Exit all positions before starting new ones for stock in context.portfolio.positions: if stock not in context.fundamental_df: order_target_percent(stock, 0) print("The two sectors we are ordering today are %r" % context.sectors) # Create weights for each stock weight = create_weights(context, context.stocks) # Rebalance all stocks to target weights for stock in context.fundamental_df: if weight != 0: print("Ordering %0.0f%% percent of %s in %s" % (weight * 100, stock.symbol, context.sector_mappings[context.fundamental_df[stock]['sector_code']])) order_target_percent(stock, weight) # track how many positions we're holding record(num_positions=len(context.fundamental_df))
def handle_data(context, data): ''' Called when a market event occurs for any of the algorithm's securities. Parameters data: A dictionary keyed by security id containing the current state of the securities in the algo's universe. context: The same context object from the initialize function. Stores the up to date portfolio as well as any state variables defined. Returns None ''' # Allow history to accumulate 100 days of prices before trading # and rebalance every day thereafter. context.tick += 1 if context.tick < 100: return # Get rolling window of past prices and compute returns prices = history(100, '1d', 'price').dropna() returns = prices.pct_change().dropna() try: # Perform Markowitz-style portfolio optimization weights, _, _ = optimal_portfolio(returns.T) # Rebalance portfolio accordingly for stock, weight in zip(prices.columns, weights): order_target_percent(stock, weight) except ValueError as e: # Sometimes this error is thrown # ValueError: Rank(A) < p or Rank([P; A; G]) < n pass
def handle_data(context, data): #assert context.portfolio.cash > 0.0, "ERROR: negative context.portfolio.cash" #assert len(context.raw_data) == context.training_data_length; "ERROR: " # data stored as (open, high, low, close, volume, price) feed_data = ([ data[context.security].open, data[context.security].high, data[context.security].low, data[context.security].close #data[context.security].volume, #data[context.security].close, ]) #keep track of history. context.raw_data.pop(0) context.raw_data.append(feed_data) context.normalized_data = Manager.preprocessData(context.raw_data)[:-2] prediction = context.strategy.predict(context.normalized_data)[-1] print "Value: $%.2f Cash: $%.2f Predict: %.5f" % ( context.portfolio.portfolio_value, context.portfolio.cash, prediction[0]) # Do nothing if there are open orders: if has_orders(context, data): print('has open orders - doing nothing!') # Put entire position in elif prediction > 0.5: order_target_percent(context.security, .95) # Take entire position out else: order_target_percent(context.security, 0) #order_target_percent(context.security, -.99) record(BENCH=data[context.security].price) record(SPY=data[context.benchmark].price)
def handle_data(context, data): #assert context.portfolio.cash > 0.0, "ERROR: negative context.portfolio.cash" #assert len(context.raw_data) == context.training_data_length; "ERROR: " # data stored as (open, high, low, close, volume, price) feed_data = ([ data[context.security].open, data[context.security].high, data[context.security].low, data[context.security].close #data[context.security].volume, #data[context.security].close, ]) #keep track of history. context.raw_data.pop(0) context.raw_data.append(feed_data) context.normalized_data = Manager.preprocessData(context.raw_data)[:-2] prediction = context.strategy.predict(context.normalized_data)[-1] print "Value: $%.2f Cash: $%.2f Predict: %.5f" % (context.portfolio.portfolio_value, context.portfolio.cash, prediction[0]) # Do nothing if there are open orders: if has_orders(context, data): print('has open orders - doing nothing!') # Put entire position in elif prediction > 0.5: order_target_percent(context.security, .95) # Take entire position out else: order_target_percent(context.security, 0) #order_target_percent(context.security, -.99) record(BENCH=data[context.security].price) record(SPY=data[context.benchmark].price)
def updatePositions(context: TradingAlgorithm): """Function to update asset positions in Zipline. This function computes specific asset proportions in the final portfolio by multiplying the weight of the sector containing the asset by the weight of the asset within the sector. Then, it uses zipline's `order_target_percent` function to specify the percentage (specified as a decimal) of the position for a given asset in the portofolio as a whole. Arguments: context {TradingAlgorithm} -- Zipline context namespace variable. """ # Looping through each sector for sector_label in config.sector_universe.getSectorLabels(): # Isolating current sector synthetic ETF sector = context.synthetics[sector_label] # Isolating portfolio weight for current sector sector_weight = context.port_weights[sector_label] for ticker in sector.getTickerList(): # Computing current portfolio percentage of the given ticker # NOTE: This is the product of the synthetic ETF weight in the # portfolio and the component weight in the synthetic ETF port_ticker_weight = sector_weight *\ sector.getTickerWeight(ticker) # Executing trade to update weight in the portfolio order_target_percent(asset=symbol(ticker), target=port_ticker_weight) logging.debug( 'Updated portfolio ticker {0} weight to {1}%'.format( ticker, port_ticker_weight * 100))
def daily_check(context, data): c = context #global c.BULL, c.COUNT, OUT_DAY vola = data.history(c.MKT, 'price', c.VOLA + 1, '1d').pct_change().std() * np.sqrt(252) WAIT_DAYS = int(vola * c.RET_INITIAL) RET = int((1.0 - vola) * c.RET_INITIAL) P = data.history([c.A, c.B, c.C, c.D], 'price', RET + 2, '1d').iloc[:-1].dropna() ratio_ab = (P[c.A].iloc[-1] / P[c.A].iloc[0]) / (P[c.B].iloc[-1] / P[c.B].iloc[0]) ratio_cd = (P[c.C].iloc[-1] / P[c.C].iloc[0]) / (P[c.D].iloc[-1] / P[c.D].iloc[0]) exit = ratio_ab < c.LB and ratio_cd < c.LB if exit: c.BULL = 0 c.OUT_DAY = c.COUNT elif (c.COUNT >= c.OUT_DAY + WAIT_DAYS): c.BULL = 1 c.COUNT += 1 wt_stk = c.LEV if c.BULL else 0 wt_bnd = 0 if c.BULL else c.LEV for sec in c.STOCKS: c.wt[sec] = wt_stk / len(c.STOCKS) for sec in c.BONDS: c.wt[sec] = wt_bnd / len(c.BONDS) for sec, weight in c.wt.items(): order_target_percent(sec, weight) record(wt_bnd=wt_bnd, wt_stk=wt_stk)
def rebalance(context, data): history = data.history(context.asset, ['close'], 40, '1d') close = history['close'].values date = history.index.values[-1] current_position = context.portfolio.positions[context.asset].amount print("当前持仓==>%d" % current_position) price = data[context.asset].price record(price=price) # 计算指标 sma_data = talib.SMA(close)[-1] wma_data = talib.WMA(close)[-1] mom_data = talib.MOM(close)[-1] # 添加今日的特征 features = [] x = [] features.append(sma_data) features.append(wma_data) features.append(mom_data) x.append(features) flag = context.svm_module.predict(x) # 预测的涨跌结果 if bool(flag) and current_position == 0: order_target_percent(context.asset, 0.5) print(str(date) + "==>买入信号") elif bool(flag) is False and current_position > 0: order_target_percent(context.asset, 0.0) print(str(date) + "==>卖出信号") else: print(str(date) + "==>无交易信号")
def rebalance(context, data): threshold = 0.05 # trigger a rebalance if we are off by this threshold (5%) # Get the current exchange time, in the exchange timezone exchange_time = pd.Timestamp(get_datetime()).tz_convert('US/Eastern') if exchange_time.month < 12: return # bail if it's not December need_full_rebalance = False portfolio_value = context.portfolio.portfolio_value # rebalance if we have too much cash if context.portfolio.cash / portfolio_value > threshold: need_full_rebalance = True # or rebalance if an ETF is off by the given threshold for sid, target in context.ETFs: pos = context.portfolio.positions[sid] position_pct = (pos.amount * pos.last_sale_price) / portfolio_value # if any position is out of range then rebalance the whole portfolio if abs(position_pct - target) > threshold: need_full_rebalance = True break # don't bother checking the rest # perform the full rebalance if we flagged the need to do so if need_full_rebalance: for sid, target in context.ETFs: order_target_percent(sid, target) log.info("Rebalanced at %s" % str(exchange_time)) context.rebalance_date = exchange_time
def handle_data(context, data): rebalance_period = 20 context.tick += 1 if context.tick < 120 : return if context.tick % rebalance_period != 0: return # Get rolling window of past prices and compute returns prices_6m = history(120, '1d', 'price').dropna() returns_6m = prices_6m.pct_change().dropna() prices_60d = history(60, '1d', 'price').dropna() returns_60d = prices_60d.pct_change().dropna() try: # Get the strongest 5 in momentum mom = returns_6m.T.sum(axis=1) selected_indices = mom[mom>0].order().tail(len(mom) /2).index # selected_indices = mom.index # selected_indices = mom[mom > 0 ].index selected_returns = returns_60d[selected_indices] weights = minimize_vol(selected_returns.T) # weights = minimize_vol(returns_60d.T) # Rebalance portfolio accordingly for stock, weight in zip(selected_returns.columns, weights): order_target_percent(stock, weight) except : # Sometimes this error is thrown # ValueError: Rank(A) < p or Rank([P; A; G]) < n pass
def rebalance(context, data): history = data.history(assets=context.asset, fields=['close'], bar_count=context.cmo_window + 1, frequency='1d') date = history.index.values[-1] close = history['close'].values # 计算CMO指标 cmo = ta.CMO(close, timeperiod=context.cmo_window) print(cmo[-1]) current_price = data[context.asset].price record(price=current_price) buy_signal_triggered = False sell_signal_triggered = False if cmo[-1] < context.over_sell: buy_signal_triggered = True elif cmo[-1] > context.over_buy: sell_signal_triggered = True current_position = context.portfolio.positions[context.asset].amount if buy_signal_triggered and current_position == 0: print(str(date) + '==>Buy') order_target_percent(context.asset, 1.0) elif sell_signal_triggered and current_position > 0: print(str(date) + '==>Sell') order_target_percent(context.asset, 0.0) else: print("No trading")
def run_strategy(context, data): # Get the data for the previous 900 minutes stock_data = data.history(context.stock, ["close"], 900, "1m") for stock in context.stock: # aggregate 15 minutes, all OHLCV columns stock_data["close"][stock] = (stock_data["close"][stock]).resample("15T", label="right", closed="right").last() stock_data["close"].dropna(inplace=True) # Calculate the SMAs for stock in context.stock: # Get the last 20 close prices last_20_prices = stock_data["close"][stock].iloc[-context.length_small_sma:] # Calculate the 20 SMA sma_20 = last_20_prices.mean() # Get the last 50 close prices last_50_prices = stock_data["close"][stock].iloc[-context.length_long_sma:] # Calculate the 50 SMA sma_50 = last_50_prices.mean() # Placing orders # Long Entry if ((sma_20 > sma_50) & (context.portfolio.positions[stock].amount == 0)): print("{} Going long on {}".format(get_datetime(), stock)) order_target_percent(stock, 0.5) # Exiting Long entry elif ((sma_20 < sma_50) & (context.portfolio.positions[stock].amount != 0)): print("{} Exiting {}".format(get_datetime(), stock)) order_target_percent(stock, 0)
def handle_data(context, data): # Skip first 100 days to get full windows context.i += 1 if context.i < 200: return # Compute averages # data.history() has to be called with the same params # from above and returns a pandas dataframe. equity_hist = data.history(context.stock, 'close', bar_count=21, frequency="1d") short_mavg = equity_hist.mean() long_mavg = data.history(context.stock, 'close', bar_count=50, frequency="1d").mean() # Trading logic if short_mavg > long_mavg: print('Buying - ' + str(context.i) + ', price - ' + str(equity_hist[-1])) # order_target orders as many shares as needed to # achieve the desired number of shares. order_target_percent(context.stock, 1.0) elif short_mavg < long_mavg: print('Selling - ' + str(context.i) + ', price - ' + str(equity_hist[-1])) order_target_percent(context.stock, 0.0)
def square_off(context): """ cancel all open orders. """ cancel_all_open_orders(context) positions = context.portfolio.positions for asset in positions: order_target_percent(asset, 0)
def rebalance(context, data): history = data.history(assets=context.asset, fields=['close'], bar_count=context.bar_window, frequency='1d') date = history.index.values[-1] close = history['close'].values current_position = context.portfolio.positions[context.asset].amount current_price = data[context.asset].price record(price=current_price) print("持仓数==>%d" % current_position) short_value = ta.SMA(close, timeperiod=5) long_value = ta.SMA(close, timeperiod=15) buy_signal_triggered = False sell_signal_triggered = False if short_value[-1] >= long_value[-1] and short_value[-2] < long_value[-2]: buy_signal_triggered = True elif short_value[-1] <= long_value[-1] and short_value[-2] > long_value[-2]: sell_signal_triggered = True if buy_signal_triggered and current_position == 0: print(str(date) + '==>买入信号') order_target_percent(context.asset, 1.0) elif sell_signal_triggered and current_position > 0: print(str(date) + '==>卖出信号') order_target_percent(context.asset, 0.0) else: print(str(date) + '==>无交易信号')
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 check_stop_loss(context, data): px = data.current(context.securities, 'close') for security in context.securities: if context.entry_side[security] == 0: continue loss = px[security] / context.entry_price[security] - 1 if context.entry_side[security] == 1 and\ loss < -context.stoploss: # we were long and hit the stoploss order_target_percent(security, 0) # reset data context.entry_price[security] = 0 context.entry_side[security] = 0 context.target_position[security] = 0 return True elif context.entry_side[security] == -1 and\ loss > context.stoploss: # we were short and hit the stoploss order_target_percent(security, 0) # reset data context.entry_price[security] = 0 context.entry_side[security] = 0 context.target_position[security] = 0 return True return False
def rebalance(context, data): threshold = 0.05 # trigger a rebalance if we are off by this threshold (5%) # Get the current exchange time, in the exchange timezone exchange_time = pd.Timestamp(get_datetime()).tz_convert("US/Eastern") if exchange_time.month < 12: return # bail if it's not December need_full_rebalance = False portfolio_value = context.portfolio.portfolio_value # rebalance if we have too much cash if context.portfolio.cash / portfolio_value > threshold: need_full_rebalance = True # or rebalance if an ETF is off by the given threshold for sid, target in context.ETFs: pos = context.portfolio.positions[sid] position_pct = (pos.amount * pos.last_sale_price) / portfolio_value # if any position is out of range then rebalance the whole portfolio if abs(position_pct - target) > threshold: need_full_rebalance = True break # don't bother checking the rest # perform the full rebalance if we flagged the need to do so if need_full_rebalance: for sid, target in context.ETFs: order_target_percent(sid, target) log.info("Rebalanced at %s" % str(exchange_time)) context.rebalance_date = exchange_time
def rebalance(context, data): history = data.history(assets=context.asset, fields=['open', 'high', 'low', 'close'], bar_count=context.cci_window + 1, frequency='1d') date = history.index.values[-1] high = history['high'].values low = history['low'].values close = history['close'].values # 计算CCI指标 cci = ta.CCI(high, low, close, timeperiod=context.cci_window) current_price = data[context.asset].price record(price=current_price) buy_signal_triggered = False sell_signal_triggered = False if cci[-1] > -100 >= cci[-2]: buy_signal_triggered = True elif cci[-1] < 100 <= cci[-2]: sell_signal_triggered = True current_position = context.portfolio.positions[context.asset].amount if buy_signal_triggered and current_position == 0: print(str(date) + '==>Buy') order_target_percent(context.asset, 0.5) elif sell_signal_triggered and current_position > 0: print(str(date) + '==>Sell') order_target_percent(context.asset, 0.0) else: print("No trading")
def handle_data(context, data): #print('handle data') prices = data.history(context.asset, 'price', argcount, '1d') normalizedPrices = (np.divide(prices, np.mean(prices))) scaledPrice = np.divide( (normalizedPrices - np.min(normalizedPrices)), (np.max(normalizedPrices) - np.min(normalizedPrices))) dp = tradingRule( *scaledPrice ) #[0],scaledPrice[1],scaledPrice[2],scaledPrice[3],scaledPrice[4],scaledPrice[5]) # print(dp) # dpList.append(dp) if dp < 0: desiredPosition = max(-1, dp) else: desiredPosition = min(1, dp) # if desired position varies from previous desired position by more than 10%, order to target percentage currentPosition = np.divide( (context.portfolio.positions[context.asset].amount) * (context.portfolio.positions[context.asset].cost_basis ), context.portfolio.portfolio_value) if np.abs(desiredPosition - currentPosition) > 0.1: order_target_percent(context.asset, desiredPosition) context.tradeCount += 1 context.dayCount += 1 record(Asset=data.current(context.asset, 'price'))
def rebalance(context, data): if context.volatility_policy: compute_asserts_volatility(context, data) for i in range(0, len(context.asserts)): if data.can_trade(context.asserts[i]): #print("rebalance " + context.asserts[i].symbol + " to:" + str(context.asserts_position[i]*100) + "%") order_target_percent(context.asserts[i], context.asserts_position[i]* context.leverage_buffer)
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): # Skip first 200 days to get full windows context.i += 1 if context.i < 200: return # Compute averages short_mavg = data.history(context.asset, 'price', bar_count=50, frequency="1d").mean() long_mavg = data.history(context.asset, 'price', bar_count=200, frequency="1d").mean() # Trading logic open_orders = get_open_orders() if context.asset not in open_orders: if short_mavg > long_mavg: # order_target orders as many shares as needed to # achieve the desired number of shares. order_target_percent(context.asset, 1.0) elif short_mavg < long_mavg: order_target_percent(context.asset, 0.0) # Save values for later inspection record(AAPL=data.current(context.asset, 'price'), short_mavg=short_mavg, long_mavg=long_mavg)
def handle_data(context, data): # Load historical pricing data for the stocks, using daily frequncy and a rolling 20 days prices = data.history(context.stocks, 'price', bar_count=20, frequency="1d") rsis = {} # Loop through our list of stocks for stock in context.stocks: # Get the rsi of this stock. rsi = talib.RSI(prices[stock], timeperiod=14)[-1] rsis[stock] = rsi current_position = context.portfolio.positions[stock].amount # RSI is above 70 and we own shares, time to sell if rsi > context.HIGH_RSI and current_position > 0 and data.can_trade(stock): order_target(stock, 0) # RSI is below 30 and we don't have any shares, time to buy elif rsi < context.LOW_RSI and current_position == 0 and data.can_trade(stock): order_target_percent(stock, context.target_pct_per_stock) # record the current RSI values of each stock for later ispection record(fb_rsi=rsis[symbol('FB')], amzn_rsi=rsis[symbol('AMZN')], aapl_rsi=rsis[symbol('AAPL')], nflx_rsi=rsis[symbol('NFLX')], googl_rsi=rsis[symbol('GOOGL')])
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 rebalance(context, data): # Wait for 756 trading days (3 yrs) of historical prices before trading if context.day < context.min_data_window - 1: return # Get expanding window of past prices and compute returns context.today = get_datetime().date() prices = data.history(context.assets, "price", context.day, "1d") if context.first_rebal_date is None: context.first_rebal_date = context.today context.first_rebal_idx = context.day print('Starting dynamic allocation simulation...') # Get investment horizon in days ie number of trading days next month context.tau = rnr.get_num_days_nxt_month(context.today.month, context.today.year) # Calculate HFP distribution asset_rets = np.array(prices.pct_change(context.tau).iloc[context.tau:, :]) num_scenarios = len(asset_rets) # Set Flexible Probabilities Using Exponential Smoothing half_life_prjn = 252 * 2 # in days lambda_prjn = np.log(2) / half_life_prjn probs_prjn = np.exp(-lambda_prjn * (np.arange(0, num_scenarios)[::-1])) probs_prjn = probs_prjn / sum(probs_prjn) mu_pc, sigma2_pc = rnr.fp_mean_cov(asset_rets.T, probs_prjn) # Perform shrinkage to mitigate estimation risk mu_shrk, sigma2_shrk = rnr.simple_shrinkage(mu_pc, sigma2_pc) weights, _, _ = rnr.efficient_frontier_qp_rets(context.n_portfolio, sigma2_shrk, mu_shrk) print('Optimal weights calculated 1 day before month end on %s (day=%s)' \ % (context.today, context.day)) #print(weights) min_var_weights = weights[0,:] # Rebalance portfolio accordingly for stock, weight in zip(prices.columns, min_var_weights): order_target_percent(stock, np.asscalar(weight)) context.weights = min_var_weights
def handle_data(context, data): # print context.get_datetime() # ========== Pre-Game Setup ========== context.vixData = context.vixData.append({"VIX Close": data.current('VIX', 'VIX Close')}, ignore_index=True) context.trading_day_count += 1 if context.trading_day_count < TRADING_DAY_MINIMUM: return # ========== Active Analysis ========== volatilityRatio = data.current('VIX', 'VIX Close') / data.current('VXV', 'CLOSE') print "VIX/VXV: %s" % volatilityRatio if volatilityRatio > 1: # order_target_percent(symbol('VXX'), 1.0) order_target_percent(symbol('XIV'), 0.0) record(VXX=data[symbol('VXX')].price) record(XIV=data[symbol('VXX')].price) else: order_target_percent(symbol('XIV'), 1.0) # order_target_percent(symbol('VXX'), 0.0) record(VXX=data[symbol('VXX')].price) record(XIV=data[symbol('VXX')].price)
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(self, context, data): rebalance_period = 20 context.tick += 1 if context.tick < 200 : return if context.tick % rebalance_period != 0: return # condition 1: momentum conditons, current monthly prices > 10 months MA prices_200d = history(200, '1d', 'price').dropna() prices_m = self.filtering(prices_200d, rebalance_period) prices_ma_10m = pd.rolling_mean(prices_m, 10) con1 = prices_m.tail(1) > prices_ma_10m.tail(1) # condition 2: picking up the ETF, which outperforms the SPY moving_win = 3 symbol_spy = symbol(self.ticker_spy) rets_3m = (prices_m / prices_m.shift(moving_win) - 1) rets_spy_3m = (prices_m[symbol_spy] / prices_m[symbol_spy].shift(moving_win) - 1) con2 = rets_3m.tail(1) > np.asarray(rets_spy_3m.tail(1)) # condition 3: picking up the ETF, which have positive returns rets = prices_m.pct_change() con3 = rets.tail(1) > 0 # signals sig1 = con1 sig2 = con1 & con2 sig3 = con2 & con3 sig4 = con1 & con3 sig5 = con1 & con2 & con3 sig = sig1 # Trading count = np.asarray(sig.sum(axis=1)) if count == 0: weights = sig * 0.0 else : weights = sig * 1.0 / count weights = np.asarray(weights.fillna(0)) stocks = np.asarray(sig.columns) try: # Rebalance portfolio accordingly for stock, weight in zip(stocks, weights.T): #print 'stock={stock}:weight={weight}'.format(stock=stock, weight=weight) order_target_percent(stock, weight) except : # Sometimes this error is thrown # ValueError: Rank(A) < p or Rank([P; A; G]) < n pass
def handle_data(context, data): # check if the spot is outside CI of MPP day_option_df = context.options[context.options['date'] == get_datetime()] call_sums = call_otm(day_option_df, 'FB', get_datetime()) put_sums = put_otm(day_option_df, 'FB', get_datetime()) add_to_window(context, 10, max_pain_strike(call_sums, put_sums), 'FB') ci = CI(context.window, 1) price = history(1, '1d', 'price').iloc[0,0] if price < ci[0]: order_target_percent(symbol('FB'), 1) elif price > ci[1]: order_target_percent(symbol('FB'), 0)
def rebalance(context, data): if context.trade == True: context.trade = False dogs = context.fundamentals_df current_portfolio = context.portfolio.positions # Check if we are holding an old position that is no longer in the dogs, needs to be closed for s in current_portfolio: if s not in dogs: api.order_target_percent(s, 0) # Check if we are holding each of the dogs, if not buy to 10% of our total portfolio for s in dogs: if s not in current_portfolio: api.order_target_percent(s, .1)
def deallocate_(context): # order_target_percent(symbol(REFERENCE_GROUP_SYMBOL['Cash']), 1.0) for symbol_ in context.active_orders: order_target_percent(symbol(symbol_), 0.0) # order_target(symbol(symbol_), 0.0) context.active_orders = [] if context.verbose: print "Record Variables for Performance Analysis." out_dict = {} for symbol_ in context.symbols: out_dict[symbol_] = 0.0 if context.verbose: print "Recording weight %s for symbol %s." %(0.0, symbol_) record(allocation = out_dict)
def handle_data(self, context, data): rebalance_period = 20 context.tick += 1 if context.tick % rebalance_period != 0: return # Get rolling window of past prices and compute returns prices = history(120, '1d', 'price').dropna() returns = prices.pct_change().dropna() try: weights = self.MOM(returns.T) for stock, weight in zip(prices.columns, weights): order_target_percent(stock, weight) except ValueError as e: pass
def handle_data(context, data): #print "Cash: $" + str(context.portfolio.cash), "Data: ", str(len(context.training_data)) #assert context.portfolio.cash > 0.0, "ERROR: negative context.portfolio.cash" assert len(context.training_data) == context.training_data_length; "ERROR: " context.security = symbol(BACKTEST_STOCK) # data stored as (open, high, low, close, volume, price) if IS_NORMALIZE: feed_data = ([ data[context.security].open - data[context.security].open, data[context.security].high - data[context.security].open, data[context.security].low - data[context.security].open, data[context.security].close - data[context.security].open #data[context.security].volume, #data[context.security].close, ]) else: feed_data = ([ data[context.security].open, data[context.security].high, data[context.security].low, data[context.security].close #data[context.security].volume, #data[context.security].close, ]) #keep track of history. context.training_data.pop(0) context.training_data.append(feed_data) context.normalized_data = Manager.normalize(context.training_data) # will have to redo every time step #print len(context.training_data), len(context.normalized_data), len(context.normalized_data[0]) prediction = context.strategy.predict(context.training_data)[-1] print "Value: $%.2f Cash: $%.2f Predict: %.5f" % (context.portfolio.portfolio_value, context.portfolio.cash, prediction[0]) # Do nothing if there are open orders: if has_orders(context, data): print('has open orders - doing nothing!') # Put entire position in elif prediction > 0.5: order_target_percent(context.security, .98) # Take entire position out else: order_target_percent(context.security, 0) #order_target_percent(context.security, -.99) record(BENCH=data[context.security].price) record(SPY=data[context.benchmark].price)
def handle_data(context, data): context.day_count += 1 if context.day_count < 100: return prices = history(950, '1d', 'price').dropna() security_index = 0; daily_returns = np.zeros((len(context.stocks), 950)) for security in context.stocks: if data.has_key(security): for day in range(0, 99): day_of = prices[security][day] day_before = prices[security][day - 1] daily_returns[security_index][day] = (day_of - day_before) / day_before security_index = security_index + 1 covars = cov(daily_returns) covars = covars * 250 ########################################################### returns = prices.pct_change().dropna() bnds = ((0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1)) cons = ({'type': 'eq', 'fun': lambda x: np.sum(x)-1.0}) res = scipy.optimize.minimize(compute_var, context.x0, cov(daily_returns)*255, method='SLSQP', constraints=cons, bounds=bnds) allocation = res.x allocation[allocation < 0] = 0 # jamais de vente, que des achats denom = np.sum(allocation) if denom != 0: allocation = allocation/denom context.x0 = allocation record(stocks=np.sum(allocation[0:-1])) record(bonds=allocation[-1]) for i, stock in enumerate(context.stocks): order_target_percent(stock, allocation[i])
def trade(context, data): """ Make sure the porfolio is fully invested every day. """ threshold = 0.05 need_full_rebalance = False # rebalance if we have too much cash if context.portfolio.cash / context.portfolio.portfolio_value > threshold: need_full_rebalance = True # What we should do is first sell the overs and then buy the unders. if need_full_rebalance: # Get the current exchange time, in the exchange timezone exchange_time = pd.Timestamp(get_datetime()).tz_convert('US/Eastern') # perform the full rebalance if we flagged the need to do so for sid, target in context.ETFs: order_target_percent(sid, target) log.info("Rebalanced at %s" % str(exchange_time))
def rebalance(context, data): if context.trade == True: log.info('REBALANCING...') context.trade = False dt = get_datetime() members = context.dow30.get(dt) for s in members: if s not in data: log.error("NoTradeDataAvailableEvent for %s" % s.symbol) for s in data: if s in members and s in context.fundamentals_df.columns: log.info('ordering %s, price = %.2f, yield = %.2f' % (s.symbol, data[s].price, 100 * context.fundamentals_df[s].dividend_yield)) order_target_percent(s, .1) else: order_target_percent(s, 0) log.info('\n')
def handle_data(context, data): context.recent_prices.append(data[context.security].price) # Update the recent prices if len(context.recent_prices) == context.window_length+2: # If there's enough recent price data # Make a list of 1's and 0's, 1 when the price increased from the prior bar changes = np.diff(context.recent_prices) > 0 context.X.append(changes[:-1]) # Add independent variables, the prior changes context.Y.append(changes[-1]) # Add dependent variable, the final change if len(context.Y) >= 100: # There needs to be enough data points to make a good model context.classifier.fit(context.X, context.Y) # Generate the model context.prediction = context.classifier.predict(changes[1:]) # Predict # If prediction = 1, buy all shares affordable, if 0 sell all shares order_target_percent(context.security, context.prediction) record(prediction=int(context.prediction))
def handle_orders(context, data): if (context.new_weights == context.current_weights).all() : print ('\n{} ALLOCATION UNCHANGED\n'.format(get_datetime().date())) return for asset in context.new_weights.index: if abs(context.new_weights[asset] - context.current_weights[asset]) > context.threshold : print ('\n{} ORDER {} of {} @ {}'.format(get_datetime(), context.new_weights[asset], asset, data[asset].close_price)) order_target_percent(asset, context.new_weights[asset]) context.current_weights = context.new_weights context.order_placed = True # print (context.strat_data['price'].ix[-1]) # print ('\n\n', get_open_orders()) return
def handle_data(self, context, data): rebalance_period = 20 context.tick += 1 if context.tick % rebalance_period != 0: return # Get rolling window of past prices and compute returns prices = history(60, '1d', 'price').dropna() returns = prices.pct_change().dropna() try: # Perform Markowitz-style portfolio optimization weights = self.vol_weighting(returns.T) # Rebalance portfolio accordingly for stock, weight in zip(prices.columns, weights): order_target_percent(stock, weight) except ValueError as e: # Sometimes this error is thrown # ValueError: Rank(A) < p or Rank([P; A; G]) < n pass
def rebalance(context, data): # Pipeline data will be a dataframe with boolean columns named 'longs' and # 'shorts'. pipeline_data = context.pipeline_data all_assets = pipeline_data.index longs = all_assets[pipeline_data.longs] shorts = all_assets[pipeline_data.shorts] record(universe_size=len(all_assets)) # Build a 2x-leveraged, equal-weight, long-short portfolio. one_third = 1.0 / 3.0 for asset in longs: order_target_percent(asset, one_third) for asset in shorts: order_target_percent(asset, -one_third) # Remove any assets that should no longer be in our portfolio. portfolio_assets = longs | shorts positions = context.portfolio.positions for asset in viewkeys(positions) - set(portfolio_assets): # This will fail if the asset was removed from our portfolio because it # was delisted. if data.can_trade(asset): order_target_percent(asset, 0)
def rebalance(context, data, exchange_time, threshold = 0.05): """ For every stock or cash position, if the target percent is off by the threshold amount (5% as a default), then place orders to adjust all positions to the target percent of the current portfolio value. """ # if the backtest is in minute mode if get_environment('data_frequency') == 'minute': # rebalance if we are in the user specified rebalance time-of-day window if exchange_time.hour < context.rebalance_hour_start or \ exchange_time.hour > context.rebalance_hour_end: return need_full_rebalance = False portfolio_value = context.portfolio.portfolio_value # rebalance if we have too much cash if context.portfolio.cash / portfolio_value > threshold: need_full_rebalance = True # or rebalance if an ETF is off by the given threshold for sid, target in context.ETFs: pos = context.portfolio.positions[sid] position_pct = (pos.amount * pos.last_sale_price) / portfolio_value # if any position is out of range then rebalance the whole portfolio if abs(position_pct - target) > threshold: need_full_rebalance = True break # don't bother checking the rest # perform the full rebalance if we flagged the need to do so # What we should do is first sell the overs and then buy the unders. if need_full_rebalance: for sid, target in context.ETFs: order_target_percent(sid, target) log.info("Rebalanced at %s" % str(exchange_time)) context.rebalance_date = exchange_time
def handle_data(context, data): trailing_window = data.history(context.asset, 'price', 40, '1d') if trailing_window.isnull().values.any(): return short_ema = EMA(trailing_window.values, timeperiod=20) long_ema = EMA(trailing_window.values, timeperiod=40) buy = False sell = False if (short_ema[-1] > long_ema[-1]) and not context.invested: order_target_percent(context.asset, 1) context.invested = True buy = True elif (short_ema[-1] < long_ema[-1]) and context.invested: order_target_percent(context.asset, 0) context.invested = False sell = True record(SH600019=data.current(context.asset, "price"), short_ema=short_ema[-1], long_ema=long_ema[-1], buy=buy, sell=sell)
def handle_data(context, data): # Skip first 300 days to get full windows context.n += 1 if context.n < 359: return context.day += 1 if context.day < 7: return # Compute averages # history() has to be called with the same params # from above and returns a pandas dataframe. historical_data =history(365, '1d', 'price') pastReturns = (historical_data - historical_data.shift(-1)) / historical_data.shift(-1) short_mavg = history(42, '1d', 'price').mean() long_mavg = history(84, '1d', 'price').mean() diff = short_mavg / long_mavg - 1 diff = diff.dropna() diff.sort() buys = diff [diff > 0.03] sells = diff[diff < -0.03] buy_length = min(context.stocks_to_long, len(buys)) short_length = min(context.stocks_to_short, len(sells)) buy_weight = 1.0/buy_length if buy_length != 0 else 0 short_weight = -1.0/short_length if short_length != 0 else 0 buys.sort(ascending=False) sells.sort() buys = buys.iloc[:buy_length] if buy_weight != 0 else None sells = sells.iloc[:short_length] if short_weight != 0 else None stops = historical_data.iloc[-1] * 0.05 for i in range(len(context.syms)): #: If the security exists in our sells.index then sell if sells is not None and context.syms[i] in sells.index: #print ('SHORT: %s'%context.syms[i]) order_target_percent(context.syms[i], short_weight) #print 'sell' #: If the security instead, exists in our buys index, buy elif buys is not None and context.syms[i] in buys.index: # print ('BUYS: %s'%context.syms[i]) order_target_percent(context.syms[i], buy_weight) #print 'nothing' #: If the security is in neither list, exit any positions we might have in that security else: order_target(context.syms[i], 0) context.day = 0 # Keep track of the number of long and short positions in the portfolio longs = shorts = 0 for position in context.portfolio.positions.itervalues(): if position.amount > 0: longs += 1 if position.amount < 0: shorts += 1 record(short_mavg=short_mavg[context.syms[1]], long_mavg=long_mavg[context.syms[1]], portfoliovalue = (context.portfolio.returns), long_count=longs, short_count=shorts)
def handle_data(self, context, data): # Implement your algorithm logic here. # data[sid(X)] holds the trade event data for that security. # context.portfolio holds the current portfolio state. # Place orders with the order(SID, amount) method. # TODO: implement your own logic here. context.trade_days += 1 if context.trade_days <> 5 : return context.trade_days = 0 ## checking the market status: ## if SPY > price one year ago, Market is in uptrend ## otherwise, market is in downtrend hist = history(bar_count = 241, frequency='1d', field='price') cash = context.portfolio.cash current_price_spy = data[symbol(self.ticker_spy)].price try: if current_price_spy > hist[symbol(self.ticker_spy)][200] : lst = self.top_rets(context.equities, 240) lst_mean = lst['zero'] count = len(lst_mean) for ticker in sector_tickers: if ticker in lst_mean: order_target_percent(symbol(ticker), 1.0/count) else : order_target_percent(symbol(ticker), 0) order_target_percent(symbol(self.ticker_gld), 0) order_target_percent(symbol(self.ticker_tlt), 0) else : for ticker in sector_tickers: order_target_percent(symbol(ticker), 0) order_target_percent(symbol(self.ticker_spy), 0) order_target_percent(symbol(self.ticker_gld), 0.5) order_target_percent(symbol(self.ticker_tlt), 0.5) except: pass
def rebalance(context, data): start_time_rebalance = time.time() curr_date = context.get_datetime().date() # if curr_date < pd.to_datetime('2009-01-01').date(): # return # if curr_date > pd.to_datetime('2009-06-01').date(): # print sdfsdfsdfsdf context.active_orders = [] if context.verbose: print "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" print "New iteration at: ", curr_date print context.portfolio # Build list of the current active symbols active_symbols = [] cur_date = context.get_datetime() for symbol_ in context.symbols: if cur_date >= context.date_limits.loc[symbol_]['start'] and cur_date + DATES_CHECK[SCHEDULER] <= context.date_limits.loc[symbol_]['end']: active_symbols.append(symbol_) if context.verbose: print "INFO: Ellapsed time : %f s." % (time.time() - start_time_rebalance) context.group.update(curr_date, active_symbols, round = context.round_weights, verbose = context.verbose) if context.group.weights is None: deallocate_(context) record(iteration_time = time.time() - start_time_rebalance) if context.verbose: print "Warning: Quitting Allocation because %s group has no weights." % context.group.name print "INFO: This iteration took: %f s." % (time.time() - start_time_rebalance) return if context.verbose: print "Top Group Allocation:" print 'Weights:\n', context.group.weights print 'Updated Symbols: ', context.group.updated_symbols print "---------------------" if context.verbose: print "INFO: Ellapsed time : %f s." % (time.time() - start_time_rebalance) # Place the orders - the extended_weights of the mixed group assets if context.verbose: print "Performing Allocation" total_weight = 0.0 # sum of absolute weights for symbol_ in context.symbols: if symbol_ in context.group.updated_symbols: context.active_orders.append(symbol_) weight = context.group.weights.values.ravel()[context.group.updated_symbols.index(symbol_)] if context.verbose: print 'Allocating for %s in %s.' % (weight, symbol_) total_weight += abs(weight) else: weight = 0.0 try: order_target_percent(symbol(symbol_), weight) except: pass if context.verbose: print "Total Weight: ", total_weight if total_weight > 1.0: raise ValueError('Weight is larger than one!') # SAVE MORE VARIABLES if context.verbose: print "Record Variables for Performance Analysis." out_dict = {} for symbol_ in context.symbols: out_dict[symbol_] = 0 if symbol_ in context.group.updated_symbols: if context.verbose: print "Recording weight %s for symbol %s." %(context.group.weights.values.ravel()[context.group.updated_symbols.index(symbol_)], symbol_) out_dict[symbol_] = context.group.weights.values.ravel()[context.group.updated_symbols.index(symbol_)] record(allocation = out_dict) record(iteration_time = time.time() - start_time_rebalance) if context.verbose: print "==================================" if context.verbose: print "INFO: This iteration took: %f s." % (time.time() - start_time_rebalance) filename = os.getcwd() + '/ITERATION_TIMES_LOG_'+ SCHEDULER.upper() + '/' + ID + '.txt' if not os.path.exists(os.path.dirname(filename)): os.makedirs(os.path.dirname(filename)) with open(filename, 'a') as logfile: logfile.write(str(time.time() - start_time_rebalance) + '\n')
def handle_data(self, context, data): context.tick += 1 total_window = self.train_win + self.nn_win + 1 if context.tick < (total_window): return try : # print 'tick = {t}'.format(t = context.tick) price = history(total_window - 1, '1d', 'price').dropna() df_price = pd.DataFrame(data=price.values, index=price.index, columns=['close']) features, target = self.create_features(df_price, self.nn_win) features_insample = features.iloc[(self.nn_win -1):-1, :].values target_insample = target.iloc[(self.nn_win -1):-1, :].values.ravel() features_oosample = features.iloc[-1, :] features_oosample = features_oosample.values.reshape([1, len(features_oosample)]) ATR = self.atr.loc[price.index[-1], :][0] symbol = price.columns[0] if self.enable_stoploss: if data[symbol].price < context.longstop: print 'Stop Loss ' order_target_percent(symbol, 0.0) context.longstop = 0.0 return if self.ml == 'SVM' : ### Training the SVM from sklearn import svm model_svm = svm.SVC() model_svm.fit(features_insample, target_insample) preds_svm = model_svm.predict(features_oosample)[0] if preds_svm < 0.5: #print "Sell " order_target_percent(symbol, 0.0) context.longstop = 0.0 else : #print "Buy" order_target_percent(symbol, 1.0) context.longstop = max(context.longstop, data[symbol].price * (1 - 0.7*ATR)) print "target sl = {n}".format(n=context.longstop) if self.ml == 'KNN' : ### Training the SVM from sklearn import neighbors k = 10 model_knn = neighbors.KNeighborsClassifier(k, 'distance') model_knn.fit(features_insample, target_insample) preds_knn = model_knn.predict(features_oosample)[0] if preds_knn < 0.5: #print "Sell " order_target_percent(symbol, 0.0) else : #print "Buy" order_target_percent(symbol, 1.0) record('price', data[symbol]['price']) except : pass
def svr_trading(context, data): # Historical data, lets get the past days close prices for pastPrice = history(bar_count=context.history_len, frequency='1d', field='price') # Make predictions on universe for stock in data: # Make sure this stock has no existing orders or positions to simplify our portfolio handling. if check_if_no_conflicting_orders(stock) and context.portfolio.positions[stock].amount == 0: #This is a scoring system for our model, we only trade when confident our model is wicked awesome full_series = np.array(pastPrice[stock].values) l = context.out_of_sameple_bin_size power = 1 #N where X^n for weight function # Create bins of X len to hold as out of sample data, average score(error) of these is a decent measure of fit. prediction_history = [] for i in np.arange(context.history_len/context.out_of_sameple_bin_size): #Index of current in same, and out of sample data. # 3 cases of this slicing if i == 0: #First run, only two bins to work with(First OOSD bin, and the rest of the data) ISD = full_series[l:] OOSD = full_series[:l] X = np.arange(l,len(full_series)) # use a variable weight (~0 - 1.0) weight_training = np.power(np.arange(l,len(full_series),dtype=float), power)[::-1]/np.power(np.arange(l,len(full_series),dtype=float), power)[::-1].max() # use a variable weight, focus on next day prediction (~0 - 1.0 - ~0) weight_score = np.concatenate((np.power(np.arange(1,l+1,dtype=float), power)/np.power(np.arange(1,l+1,dtype=float), power).max(), np.power(np.arange(l+1,len(full_series)+1,dtype=float), power)[::-1]/np.power(np.arange(l+1,len(full_series)+2,dtype=float), power)[::-1].max())) """print len (weight_training) print weight_training print len (weight_score) print weight_score print exit()""" elif i == context.history_len/context.out_of_sameple_bin_size - 1: #Last run, only two bins to work with(Last OOSD bin, and the rest of the data) ISD = full_series[:-l] OOSD = full_series[-l:] X = np.arange(0,len(full_series)-l) # use a variable weight (~0 - 1.0) weight_training = np.power(np.arange(l,len(full_series),dtype=float)+1, power)/np.power(np.arange(l,len(full_series),dtype=float)+1, power).max() # use a variable weight, focus on next day prediction (~0 - 1.0 - ~0) weight_score = np.concatenate((np.power(np.arange(1,len(full_series)-l+1,dtype=float), power)/np.power(np.arange(1,len(full_series)-l+2,dtype=float), power).max(), np.power(np.arange(1,l+1,dtype=float), power)[::-1]/np.power(np.arange(1,l+1,dtype=float), power)[::-1].max())) """print len (weight_training) print weight_training print len (weight_score) print weight_score print exit()""" else: #Any other run, we have a sandwhich of OOSD in the middle of two ISD sets so we need to aggregate. ISD = np.concatenate((full_series[:(l*i)], full_series[l*(i+1):])) OOSD = full_series[l*i:l*(i+1)] X = np.concatenate(( np.arange(0,(l*i)), np.arange(l*(i+1),len(full_series)) )) # use a variable weight (~0 - 1.0) weight_training = np.concatenate(( np.power(np.arange(1, l*i+1, dtype=float), power)/np.power(np.arange(1, l*i+1, dtype=float), power).max(), np.power(np.arange(l*(i+1), len(full_series), dtype=float), power)[::-1]/np.power(np.arange(l*(i+1), len(full_series),dtype=float), power)[::-1].max() )) # use a variable weight, focus on next day prediction (~0 - 1.0 - ~0) weight_score = np.concatenate(( np.power(np.arange(1, l*(i+1)+1, dtype=float), power)/np.power(np.arange(1, l*(i+1)+1, dtype=float), power).max(), np.power(np.arange(l*(i+1), len(full_series), dtype=float), power)[::-1]/np.power(np.arange(l*(i+1), len(full_series)+1, dtype=float), power)[::-1].max() )) """print len (weight_training) print weight_training print len (weight_score) print weight_score exit()""" # Domain and range of training data #X = np.arange(len(ISD)) X = np.atleast_2d(X).T y = ISD # Domain of prediction set #x = np.atleast_2d(np.linspace(0, len(ISD)+len(OOSD)-1, len(ISD)+len(OOSD))).T #x = np.atleast_2d(np.linspace(len(ISD) ,len(ISD)+len(OOSD)-1, len(OOSD))).T x = np.atleast_2d(np.linspace(0, len(full_series)-1, len(full_series))).T # epsilon-Support Vector Regression using scikit-learn # Read more here: http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html SVR_model = SVR(kernel='rbf', C=100, gamma=.01) SVR_model.fit(X,y, weight_training) y_predSVR = SVR_model.predict(x) if np.isnan(full_series).any() or np.isinf(full_series).any(): print(stock + " Failed due to data INF or NAN") y_score = 0 break else: y_score = SVR_model.score(x, full_series)#, sample_weight=weight_score) #y_predSVR[-len(OOSD):] np.atleast_2d(y_predSVR).T #log.debug(y_score) prediction_history.append(y_score) score = np.mean(y_score) # If we are studying one stock, lets plot its correlation regression results if len(data) == 1: record(Ideal=1.0, Score=score) #Slope=slope, R_value=r # Store the prediction for comparison with the rest of the universe # Measure accuracy as the mean of the distance to the ideal value of # the r2 and slope from past vs predicted price correlation regression if score >= context.score_filter: #The model was accepted, make a forecast #form domain and range of test data(we leave no out of sameple data out since we already scored the model) X = np.arange(context.history_len) X = np.atleast_2d(X).T y = np.array(pastPrice[stock].values) # Domain of predection set. We only need to predict the next close price. x = np.atleast_2d(np.linspace(len(y), len(y), 1)).T """log.debug(X) log.debug(len(X)) log.debug(x) log.debug(len(x)) exit()""" # use a linearly peaking weight, focus on next day prediction (~0 - 1.0 - ~0) #weight_training = np.power(np.arange(1,context.history_len+1, dtype=float), power)/np.power(np.arange(1,context.history_len+1, dtype=float), power).max() #weight_training = np.exp(np.arange(1,context.history_len+1, dtype=float))/np.exp(np.arange(1,context.history_len+1, dtype=float)).max() # epsilon-Support Vector Regression using scikit-learn # Read more here: http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html SVR_model = SVR(kernel='rbf', C=100, gamma=.01) SVR_model.fit(X, y)#, weight_training) y_predSVR = SVR_model.predict(x) context.next_pred_price[stock] = y_predSVR[-1] else: #Case where stock is left in dict and we dont want to use it, so remove it. if stock in context.next_pred_price: del context.next_pred_price[stock] # Count number of trades so we can split the availible cash properly number_of_trades_today = 0 for stock in data: # Make sure this stock has no existing orders or positions to simplify our portfolio handling # Also check that we have a prediction stored in the dict if check_if_no_conflicting_orders(stock) and \ context.portfolio.positions[stock].amount == 0 and \ stock in context.next_pred_price: # If we plan to move on this stock, take count of it(explained more in actual buy statement below)(Make sure these match both buy statements. if (percent_change(context.next_pred_price[stock], pastPrice[stock][-1]) >= context.action_to_move_percent and \ percent_change(context.next_pred_price[stock], data[stock]['price']) >= context.action_to_move_percent) or \ (percent_change(context.next_pred_price[stock], pastPrice[stock][-1]) <= -context.action_to_move_percent and \ percent_change(context.next_pred_price[stock], data[stock]['price']) <= -context.action_to_move_percent): number_of_trades_today += 1 # #Lets use record to plot how many securities are traded on each day. if len(data) >= 2: record(number_of_stocks_traded=number_of_trades_today) #Make buys and shorts if the predicted close change is bigger than our tollerance, same with current price to avoid opening gaps. for stock in data: # Make sure this stock has no existing orders or positions to simplify our portfolio handling # Also check that we have a prediction stored in the dict if check_if_no_conflicting_orders(stock) and context.portfolio.positions[stock].amount == 0 and stock in context.next_pred_price: #Go long if we predict the close price will change more(upward) than our tollerance, # apply same filter against current price vs predicted close in case of gap up/down. if percent_change(context.next_pred_price[stock], pastPrice[stock][-1]) >= context.action_to_move_percent and \ percent_change(context.next_pred_price[stock], data[stock]['price']) >= context.action_to_move_percent: # Place an order, and store the ID to fetch order info orderId = order_target_percent(stock, 1.0/number_of_trades_today) # How many shares did we just order, since we used target percent of availible cash to place order not share count. shareCount = get_order(orderId).amount # We can add a timeout time on the order. #context.duration[orderId] = exchange_time + timedelta(minutes=5) # We need to calculate our own inter cycle portfolio snapshot as its not updated till next cycle. value_of_open_orders(context, data) availibleCash = context.portfolio.cash-context.cashCommitedToBuy-context.cashCommitedToSell print("+ BUY {0:,d} of {1:s} at ${2:,.2f} for ${3:,.2f} / ${4:,.2f} @ {5:s}"\ .format(shareCount, stock,data[stock]['price'], data[stock]['price']*shareCount, availibleCash, context.exchange_time)) #Go short if we predict the close price will change more(downward) than our tollerance, # apply same filter against current price vs predicted close incase of gap up/down. elif percent_change(context.next_pred_price[stock], pastPrice[stock][-1]) <= -context.action_to_move_percent and \ percent_change(context.next_pred_price[stock], data[stock]['price']) <= -context.action_to_move_percent: #orderId = order_target_percent(stock, -1.0/len(data)) orderId = order_target_percent(stock, -1.0/number_of_trades_today) # How many shares did we just order, since we used target percent of availible cash to place order not share count. shareCount = get_order(orderId).amount # We can add a timeout time on the order. #context.duration[orderId] = exchange_time + timedelta(minutes=5) # We need to calculate our own inter cycle portfolio snapshot as its not updated till next cycle. value_of_open_orders(context, data) availibleCash = context.portfolio.cash-context.cashCommitedToBuy+context.cashCommitedToSell print("- SHORT {0:,d} of {1:s} at ${2:,.2f} for ${3:,.2f} / ${4:,.2f} @ {5:s}"\ .format(shareCount, stock,data[stock]['price'], data[stock]['price']*shareCount, availibleCash, context.exchange_time))