def watch(context, data): # On schedule, process any sids in watch_list prices = data.history(context.watch_list, 'close', 2, '1d') # Daily, couple days for s in context.watch_list: if s not in context.portfolio.positions: # If sold elsewhere, drop it from watch context.watch_list.remove(s) continue # Slope of prices, minute slp = slope( data.history(s, 'close', 60, '1m').dropna()) # Minutes, note dropna(), important if slp < 0: # Close if downward log.info('sell {} at {} prv {} {}%'.format( s.symbol, data.current(s, 'price'), '%.2f' % prices[s][0], '%.0f' % (100 * data.current(s, 'price') / prices[s][0]))) order_target(s, 0) # Close/sell context.watch_list.remove(s) # Any new for price jump watch_list prices = data.history(context.portfolio.positions.keys(), 'close', 2, '1d') # Couple days for s in context.portfolio.positions: # Add to watch_list with price jump if not data.can_trade(s): continue if data.current( s, 'price') > 1.10 * prices[s][0]: # If price has jumped upward if s in context.watch_list: continue log.info('{} to watch_list at {} prv {} {}%'.format( s.symbol, data.current(s, 'price'), '%.2f' % prices[s][0], '%.0f' % (100 * data.current(s, 'price') / prices[s][0]))) context.watch_list.append(s)
def my_rebalance(context, data): GDXJ_prices = data.history(context.GDXJ, "price", 10000, "1m").resample('30T', closed='right', label='right').last().dropna() #GDXJ_prices = data.history(context.GDXJ, "price", 100, "1d") ema12 = talib.EMA(GDXJ_prices, 12) ema26 = talib.EMA(GDXJ_prices, 26) macd = ema12 - ema26 signal = talib.EMA(macd, 9) record(SIG=macd[-1] - signal[-1]) record(MACD=macd[-1]) if macd[-2] < signal[-2] and macd[-1] >= signal[-1] and not context.bought: set_fixed_stop_long(context, data) order_target_percent(context.GDXJ, context.allocation) context.bought = True context.sold = False if macd[-1] < signal[-1] and not context.sold: set_fixed_stop_short(context, data) order_target_percent(context.GDXJ, 0) context.bought = False context.sold = True
def my_rebalance_close(context, data): #If we have a position check sell conditions DBC_prices = data.history(context.DBC, "price", 100, "1d") ema12 = talib.EMA(DBC_prices, 12) ema26 = talib.EMA(DBC_prices, 26) macd = ema12 - ema26 signal = talib.EMA(macd, 9) if macd[-2] > signal[-2] and macd[-1] < signal[ -1] and context.portfolio.positions[ context.DBC].amount != 0 and context.bought: order_target_percent(context.DBC, 0) log.info( "Closed Long Position; MACD_val: %.5f; PNL: %.5f; Market Value: %.5f" % (macd[-1] - signal[-1], context.portfolio.pnl, context.portfolio.portfolio_value)) # log.info(context.portfolio.positions) context.bought = False if macd[-2] < signal[-2] and macd[-1] > signal[ -1] and context.portfolio.positions[ context.DBC].amount != 0 and context.sold: order_target_percent(context.DBC, 0) log.info( "Closed Short Position; MACD_val: %.5f; PNL: %.5f; Market Value: %.5f" % (macd[-1] - signal[-1], context.portfolio.pnl, context.portfolio.portfolio_value)) # log.info(context.portfolio.positions) context.sold = False
def my_rebalance(context, data): DBC_prices = data.history(context.DBC, "price", 100, "1d") ema12 = talib.EMA(DBC_prices, 12) ema26 = talib.EMA(DBC_prices, 26) macd = ema12 - ema26 signal = talib.EMA(macd, 9) record(MACD_val=macd[-1] - signal[-1]) record(macd=macd[-1]) record(exp3=signal[-1]) if macd[-2] < signal[-2] and macd[-1] > signal[-1] and not context.bought: order(context.DBC, 40) log.info("------------------------------------") log.info( "Opened Long Position; MACD_val: %.3f; PNL: %.3f; Market Value: %.5f" % (macd[-1] - signal[-1], context.portfolio.pnl, context.portfolio.portfolio_value)) # log.info(context.portfolio.positions) context.boughtPrice = data.current(context.DBC, 'price') context.bought = True context.sold = False if macd[-2] > signal[-2] and macd[-1] < signal[-1] and not context.sold: order(context.DBC, -40) log.info("------------------------------------") log.info( "Opened Short Position; MACD_val: %.5f; PNL: %.5f; Market Value: %.5f" % (macd[-1] - signal[-1], context.portfolio.pnl, context.portfolio.portfolio_value)) # log.info(context.portfolio.positions) context.boughtPrice = data.current(context.DBC, 'price') context.bought = False context.sold = True
def _get_macd(data, ticker): prices = data.history(ticker, "price", 100, "1d") prices.dropna(inplace=True) ema12 = talib.EMA(prices, 12) ema26 = talib.EMA(prices, 26) macd = ema12 - ema26 signal = talib.EMA(macd, 9) return macd, signal
def my_record_vars(context, data): DBC_prices = data.history(context.DBC, "price", 100, "1d") ema12 = talib.EMA(DBC_prices, 12) ema26 = talib.EMA(DBC_prices, 26) macd = ema12 - ema26 signal = talib.EMA(macd, 9) if context.bought or context.sold: log.info( "Holding position; MACD_val: %.5f; PNL: %.5f; Market Value: %.5f" % (macd[-1] - signal[-1], context.portfolio.pnl, context.portfolio.portfolio_value))
def check_rsi(context,data): vxx_highs = data.history(context.VXX, "high", context.wvf_length*2, "1d") vxx_prices = data.history(context.VXX, "price", context.wvf_length*2, "1d") vxx_lows = data.history(context.VXX, "low", context.wvf_length*2, "1d") vxx_highest = vxx_highs.rolling(window = context.wvf_length, center=False).max() WVF = ((vxx_highest - vxx_lows)/(vxx_highest)) * 100 context.SmoothedWVF1 = talib.EMA(WVF, timeperiod=context.ema1) context.SmoothedWVF2 = talib.EMA(WVF, timeperiod=context.ema2) SMA30VXX = talib.SMA(vxx_prices, 30) SMA5VXX = talib.SMA(vxx_prices, 5) record(WVF1=WVF[-1]) #record(SMA30=SMA30VXX[-1]) USELESS WITHOUT VXX PRICE! record(EMA5=context.SmoothedWVF1[-1]) record(EMA20=context.SmoothedWVF2[-1]) print("VXX[-2]: {} VXX[-1]: {} SMA5: {} SMA30[-2]: {} SMA30[-1]: {} WVF[-2]: {} WVF[-1]: {} SmoothedWVF1[-2]: {} SmoothedWVF1[-1]: {} SmoothedWVF2[-2]: {} SmoothedWVF2[-1]: {}".format(vxx_prices[-2], vxx_prices[-1], SMA5VXX[-1], SMA30VXX[-2], SMA30VXX[-1], WVF[-2], WVF[-1], context.SmoothedWVF1[-2], context.SmoothedWVF1[-1], context.SmoothedWVF2[-2], context.SmoothedWVF2[-1])) ## BUY RULES if context.portfolio.positions[context.XIV].amount == 0: if ((WVF[-1] > context.SmoothedWVF1[-1] and WVF[-2] < context.SmoothedWVF1[-2] and WVF[-1] < context.SmoothedWVF2[-1]) or (WVF[-1] > context.SmoothedWVF1[-1] and WVF[-2] < context.SmoothedWVF1[-2] and WVF[-1] > context.SmoothedWVF2[-1] and WVF[-2] < context.SmoothedWVF2[-2])) and vxx_prices[-1] < SMA5VXX[-1]: set_fixed_stop(context, data) order_target_percent(context.XIV, 1.0) print("bought") ## SELL RULES if context.portfolio.positions[context.XIV].amount > 0 and len(get_open_orders()) == 0: #if vxx crosses above SMA30: sell if vxx_prices[-2] < SMA30VXX[-2] and vxx_prices[-1] > SMA30VXX[-1]: context.sell = True print("vxx crosses above SMA30: sell") #if wvf crosses under smoothwvf2: sell if WVF[-2] > context.SmoothedWVF2[-2] and WVF[-1] < context.SmoothedWVF2[-1]: context.sell = True print("wvf crosses under smoothwvf2: sell")
def my_rebalance(context, data): # my_assigned_weights(context, data) n = 28 WFV_limit = 14.5 vxx_prices = data.history(context.VXX, "price", n + 2, "1d")[:-1] vxx_lows = data.history(context.VXX, "low", n + 2, "1d")[:-1] vxx_highest = vxx_prices.rolling(window=n, center=False).max() WVF = ((vxx_highest - vxx_lows) / (vxx_highest)) * 100 record(WVF=WVF[-1]) xn = 28 xiv_prices = data.history(context.XIV, "price", xn + 2, "1d")[:-1] xiv_lows = data.history(context.XIV, "low", xn + 2, "1d")[:-1] xiv_highest = xiv_prices.rolling(window=xn, center=False).max() XWVF = ((xiv_highest - xiv_lows) / (xiv_highest)) * 100 record(XWVF=XWVF[-1]) if (WVF[-1] >= WFV_limit and WVF[-2] < WFV_limit): BuyStock = context.XIV context.Safety_Weight = 0.0 if context.XIV not in context.portfolio.positions: order_target_percent(BuyStock, context.maxBuy) message = 'BUY: {stock}' log.info(message.format(stock=BuyStock.symbol)) if (WVF[-1] < WFV_limit and WVF[-2] >= WFV_limit) or (WVF[-1] < XWVF[-1] and WVF[-2] >= XWVF[-2]): if context.XIV in context.portfolio.positions: SellStock = context.XIV order_target_percent(SellStock, 0.00) message = 'Sell: {stock}' log.info(message.format(stock=SellStock.symbol)) context.Safety_Weight = 1.00
def rebalance(context, data): # check if it is January if get_datetime().month not in [1]: return # read and produce returns dataframe context.returns_df = pd.DataFrame() for ticker in context.tickers: prices = data.history(ticker, "price", 252, "1d") df = pd.DataFrame(data={ticker: prices}) context.returns_df = pd.concat([context.returns_df, df], axis=1) context.returns_df.dropna(inplace=True) pct = context.returns_df #协方差矩阵 cov_mat = pct.cov() # log.info(cov_mat) if not isinstance(cov_mat, pd.DataFrame): raise ValueError('cov_mat should be pandas DataFrame!') omega = np.matrix(cov_mat.values) # 协方差矩阵 a, b = np.linalg.eig(np.array(cov_mat)) #a为特征值,b为特征向量 a = np.matrix(a) b = np.matrix(b) # 定义目标函数 def fun1(x): tmp = (omega * np.matrix(x).T).A1 risk = x * tmp / np.sqrt(np.matrix(x) * omega * np.matrix(x).T).A1[0] delta_risk = [sum((i - risk)**2) for i in risk] return sum(delta_risk) # 初始值 + 约束条件 x0 = np.ones(omega.shape[0]) / omega.shape[0] bnds = tuple((0, None) for x in x0) cons = ({'type': 'eq', 'fun': lambda x: sum(x) - 1}) options = {'disp': False, 'maxiter': 1000, 'ftol': 1e-20} try: res = minimize(fun1, x0, bounds=bnds, constraints=cons, method='SLSQP', options=options) except: raise ValueError('method error!!!') # 权重调整 if res['success'] == False: # print res['message'] pass wts = pd.Series(index=cov_mat.index, data=res['x']) # weight adjust wts = wts / wts.sum() risk = pd.Series(wts * (omega * np.matrix(wts).T).A1 / np.sqrt(np.matrix(wts) * omega * np.matrix(wts).T).A1[0], index=cov_mat.index) risk[risk < 0.0] = 0.0 context.weights = wts
def my_rebalance(context,data): xiv_prices = data.history(context.XIV, "price", 1600, "1m").resample('30T', closed='right', label='right').last().dropna() #convert to 2 hour: xiv2hr = [] if '20:00:00+00:00' in str(xiv_prices.index[-1]) or '21:00:00+00:00' in str(xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-28], xiv_prices[-28]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-23], xiv_prices[-23]]) xiv2hr.append([xiv_prices.index[-19], xiv_prices[-19]]) xiv2hr.append([xiv_prices.index[-15], xiv_prices[-15]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-10], xiv_prices[-10]]) xiv2hr.append([xiv_prices.index[-6], xiv_prices[-6]]) xiv2hr.append([xiv_prices.index[-2], xiv_prices[-2]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = True elif '19:30:00+00:00' in str(xiv_prices.index[-1]) or '20:30:00+00:00' in str(xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-31], xiv_prices[-31]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-26], xiv_prices[-26]]) xiv2hr.append([xiv_prices.index[-22], xiv_prices[-22]]) xiv2hr.append([xiv_prices.index[-18], xiv_prices[-18]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-13], xiv_prices[-13]]) xiv2hr.append([xiv_prices.index[-9], xiv_prices[-9]]) xiv2hr.append([xiv_prices.index[-5], xiv_prices[-5]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = False elif '17:30:00+00:00' in str(xiv_prices.index[-1]) or '18:30:00+00:00' in str(xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-31], xiv_prices[-31]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-23], xiv_prices[-23]]) xiv2hr.append([xiv_prices.index[-22], xiv_prices[-22]]) xiv2hr.append([xiv_prices.index[-18], xiv_prices[-18]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-10], xiv_prices[-10]]) xiv2hr.append([xiv_prices.index[-9], xiv_prices[-9]]) xiv2hr.append([xiv_prices.index[-5], xiv_prices[-5]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = False elif '15:30:00+00:00' in str(xiv_prices.index[-1]) or '16:30:00+00:00' in str(xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-31], xiv_prices[-31]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-23], xiv_prices[-23]]) xiv2hr.append([xiv_prices.index[-19], xiv_prices[-19]]) xiv2hr.append([xiv_prices.index[-18], xiv_prices[-18]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-10], xiv_prices[-10]]) xiv2hr.append([xiv_prices.index[-6], xiv_prices[-6]]) xiv2hr.append([xiv_prices.index[-5], xiv_prices[-5]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = False else: log.error("2 HOUR CONVERSION FAILURE") return dates, vals = zip(*xiv2hr) s = pd.Series(vals, index=dates) rsi = talib.RSI(s,2) RSI5 = talib.RSI(s, 5) # XIV # BUY RULE if context.xiv_buy is False and rsi[-2] < 70 and rsi[-1] >= 70 and context.portfolio.positions[context.XIV].amount == 0: context.xiv_buy = True # SELL RULE if rsi[-2] > 85 and rsi[-1] <= 85 and context.portfolio.positions[context.XIV].amount > 0: order_target_percent(context.XIV, 0) context.xiv_buy = False # VXX if RSI5[-1] < 70: if rsi[-2] > 85 and rsi[-1] <= 85: if context.portfolio.positions[context.VXX].amount == 0: #if len(get_open_orders()) == 0 and context.portfolio.positions[context.VXX].amount == 0: context.vxx_buy = True if context.portfolio.positions[context.VXX].amount > 0 and len(get_open_orders()) == 0: if rsi[-2] < 70 and rsi[-1] >= 70: order_target_percent(context.VXX, 0) # panic button high = (data.history(context.XIV, "high", 119, "1m")).max() if context.last_bar: high = (data.history(context.XIV, "high", 29, "1m")).max() price = data.current(context.XIV, 'price') if ((high/price) - 1) > .1 and len(get_open_orders()) == 0: order_target_percent(context.XIV, 0) context.xiv_sell = False context.xiv_buy = False
def my_rebalance(context, data): xiv_prices = data.history(context.XIV, "price", 1600, "1m").resample('30T', closed='right', label='right').last().dropna() #convert to 2 hour: xiv2hr = [] if '20:00:00+00:00' in str( xiv_prices.index[-1]) or '21:00:00+00:00' in str( xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-28], xiv_prices[-28]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-23], xiv_prices[-23]]) xiv2hr.append([xiv_prices.index[-19], xiv_prices[-19]]) xiv2hr.append([xiv_prices.index[-15], xiv_prices[-15]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-10], xiv_prices[-10]]) xiv2hr.append([xiv_prices.index[-6], xiv_prices[-6]]) xiv2hr.append([xiv_prices.index[-2], xiv_prices[-2]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = True elif '19:30:00+00:00' in str( xiv_prices.index[-1]) or '20:30:00+00:00' in str( xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-31], xiv_prices[-31]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-26], xiv_prices[-26]]) xiv2hr.append([xiv_prices.index[-22], xiv_prices[-22]]) xiv2hr.append([xiv_prices.index[-18], xiv_prices[-18]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-13], xiv_prices[-13]]) xiv2hr.append([xiv_prices.index[-9], xiv_prices[-9]]) xiv2hr.append([xiv_prices.index[-5], xiv_prices[-5]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = False elif '17:30:00+00:00' in str( xiv_prices.index[-1]) or '18:30:00+00:00' in str( xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-31], xiv_prices[-31]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-23], xiv_prices[-23]]) xiv2hr.append([xiv_prices.index[-22], xiv_prices[-22]]) xiv2hr.append([xiv_prices.index[-18], xiv_prices[-18]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-10], xiv_prices[-10]]) xiv2hr.append([xiv_prices.index[-9], xiv_prices[-9]]) xiv2hr.append([xiv_prices.index[-5], xiv_prices[-5]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = False elif '15:30:00+00:00' in str( xiv_prices.index[-1]) or '16:30:00+00:00' in str( xiv_prices.index[-1]): xiv2hr.append([xiv_prices.index[-31], xiv_prices[-31]]) xiv2hr.append([xiv_prices.index[-27], xiv_prices[-27]]) xiv2hr.append([xiv_prices.index[-23], xiv_prices[-23]]) xiv2hr.append([xiv_prices.index[-19], xiv_prices[-19]]) xiv2hr.append([xiv_prices.index[-18], xiv_prices[-18]]) xiv2hr.append([xiv_prices.index[-14], xiv_prices[-14]]) xiv2hr.append([xiv_prices.index[-10], xiv_prices[-10]]) xiv2hr.append([xiv_prices.index[-6], xiv_prices[-6]]) xiv2hr.append([xiv_prices.index[-5], xiv_prices[-5]]) xiv2hr.append([xiv_prices.index[-1], xiv_prices[-1]]) context.last_bar = False else: log.error("2 HOUR CONVERSION FAILURE") return dates, vals = zip(*xiv2hr) s = pd.Series(vals, index=dates) rsi = talib.RSI(s, 2) #rsi7 = talib.RSI(s,7) record(RSI_2=rsi[-1]) #FR#4: Improve buy/sell condition if context.rsi_last == -1: context.rsi_last = rsi[-2] #Using Agent conditions if context.buy is False and context.rsi_last < TraderAgent_RSIBASED_RGQF.RsiUpperLimit and rsi[ -1] >= TraderAgent_RSIBASED_RGQF.RsiUpperLimit and context.portfolio.positions[ context.XIV].amount == 0: context.buy = True if context.rsi_last > TraderAgent_RSIBASED_RGQF.RsiUpperLimitTrend and rsi[ -1] <= TraderAgent_RSIBASED_RGQF.RsiUpperLimitTrend and context.portfolio.positions[ context.XIV].amount > 0 and len(get_open_orders()) == 0: order_target_percent(context.XIV, 0) context.buy = False if context.buyVXX is False and rsi[ -1] <= TraderAgent_RSIBASED_RGQF.RsiLowerLimit and context.portfolio.positions[ context.VXX].amount == 0: context.buyVXX = True # Buy rule if context.buyVXX is False and context.rsi_last > TraderAgent_RSIBASED_RGQF.RsiLowerLimit and rsi[ -1] <= TraderAgent_RSIBASED_RGQF.RsiLowerLimit and context.portfolio.positions[ context.XIV].amount == 0 and context.portfolio.positions[ context.VXX].amount == 0: context.buyVXX = True # Sell rule if context.rsi_last < TraderAgent_RSIBASED_RGQF.RsiLowerLimitTrend and rsi[ -1] >= TraderAgent_RSIBASED_RGQF.RsiLowerLimitTrend and context.portfolio.positions[ context.VXX].amount > 0: order_target_percent(context.VXX, 0) context.buyVXX = False #End of agent usage # panic button hard for safety: high = (data.history(context.XIV, "high", 119, "1m")).max() if context.last_bar: high = (data.history(context.XIV, "high", 29, "1m")).max() price = data.current(context.XIV, 'price') if ((high / price) - 1) > .1: order_target_percent(context.XIV, 0) context.sell = False context.buy = False #Update for next cicle context.rsi_last = rsi[-1]