def sell_stocks_not_in_portfolio(context, data): for stock in context.portfolio.positions: if stock not in context.stocks: LOG.info( "selling stock %s that should no longer be in the portfolio" % stock.symbol) order_target_percent(stock, 0)
def late_day_trade(context, data): #Get the pipeline output pipe_output = pipeline_output('Stocks') context.days_stocks = pipe_output.sort_values(by =['ann_var'], ascending = False) #log.info(context.days_stocks) log.info(context.daily_message, context.day_count) log.info(context.days_stocks) log.info(type(context.days_stocks)) #Calculate Daily Return Top Losers if (context.days_stocks.size > 0): price_history = data.history(context.days_stocks.index, "price", 745, "1m") #356 +390 open_prices = price_history.iloc[0] current_prices = price_history.iloc[-1] context.idr_losers = ((current_prices - open_prices) / open_prices).sort_values() context.idr_losers = context.idr_losers[0:5]#5 log.info(context.idr_losers) else: price_history = data.history(context.backup_stocks, "price", 1 , "1m") #356 current_prices = price_history.iloc[-1] context.idr_losers = current_prices #Stock info is irrelevant here pct_cash = context.portfolio.cash/context.portfolio.portfolio_value #Get Open Orders and Buy for stock in context.idr_losers.index: if(data.can_trade(stock)): if(stock not in context.open_orders): order_target_percent(stock, pct_cash/(context.idr_losers.size + 1)) #Check Portfolio #log.info(type(context.portfolio.positions)) record(leverage = context.account.leverage) #be sure to always track leverage record(cash = context.portfolio.cash) record(port_value = context.portfolio.portfolio_value)
def my_rebalance(context, data): target_weights = compute_target_weights(context, data, 1) log.info(target_weights) if target_weights: for stock, weight in target_weights.items(): order_target_percent(stock, weight)
def manageStops(context, data): for asset, value in context.portfolio.positions.items(): stopPrice = context.stopPriceMap[asset] currentPrice = data.current(asset, 'close') newStop = currentPrice * context.stopLevel if currentPrice < stopPrice: logging.info(f'Stopped out of {asset}') order_target_percent(asset, 0.0) elif newStop > stopPrice: context.stopPriceMap[asset] = newStop
def handle_data(context, data): today = get_datetime().floor('1D') last_date = getattr(context, 'last_ran_buy', None) if today != last_date: my_rebalance(context, data) context.last_ran_buy = today else: for stock, position in context.portfolio.positions.items(): if get_open_orders(stock): continue current_price = data.current(stock, 'price') cost_basis = position.cost_basis stop_loss = -0.05 current_loss = (current_price - cost_basis) / cost_basis if current_loss < stop_loss: log.info('selling early %s (%.2f)' % (stock.symbol, current_loss)) order_target_percent(stock, 0)
def entryAndExitLogic(context, data, filtered): numOfPositions = len(context.portfolio.positions) if not filtered.empty: for asset, value in filtered.iterrows(): asset = symbol(asset) currentPrice = data.current(asset, 'close') # stopPrice = currentPrice * context.stopLevel if longConditionsMet(value, currentPrice): # enter position with position size as long as leverage is below certain level if withinLeverageLimit(context, numOfPositions): logging.info( f'Ordering shares of {asset} at {currentPrice}') # context.stopPriceMap[asset] = stopPrice order_target_percent(asset, context.position_size) numOfPositions += 1 elif asset in context.portfolio.positions.keys(): logging.info(f'Exiting position in {asset}') if not asset in [symbol('NCNO'), symbol('GME')]: order_target_percent(asset, 0.0)
def handle_data(context, data): # The handle_data method is called by pylivetrader every minute when # new data is received. This is where we'll execute our trading logic. For # an explanation of pylivetrader function scheduling, please see here: # https://github.com/alpacahq/pylivetrader#run. # Compute averages # data.history() will return a pandas dataframe with price information. # pandas' EWM method will give us our exponential moving averages. # Calculate short-term EMA (using data from the past 12 minutes.) short_periods = 12 short_data = data.history(context.asset, 'price', bar_count=short_periods, frequency="1m") short_ema = pd.Series.ewm(short_data, span=short_periods).mean().iloc[-1] # Calculate long-term EMA (using data from the past 26 minutes.) long_periods = 26 long_data = data.history(context.asset, 'price', bar_count=long_periods, frequency="1m") long_ema = pd.Series.ewm(long_data, span=long_periods).mean().iloc[-1] macd = short_ema - long_ema # Trading logic if macd > 0: # order_target_percent allocates a specified percentage of your # portfolio to a long position in a given asset. (A value of 1 # means that 100% of your portfolio will be allocated.) order_target_percent(context.asset, 1) elif macd < 0: # You can supply a negative value to short an asset instead. order_target_percent(context.asset, -1) # Save values for later inspection record(AAPL=data.current(context.asset, 'price'), short_mavg=short_ema, long_mavg=long_ema)
def clear_queue(context, data): if context.rebalance_complete: if bool(context.trade_queue): log.info('Attempting to clear trading queue') remove_queue_list = [] for security, amount in context.trade_queue.items(): if data.can_trade(security): order_target_percent(security, amount) remove_queue_list.append(security) else: if context.clear_queue_run == 0: log.warning('{} is not able to trade'.format(security)) asset_info = api.get_asset(security.symbol) log.info('Asset info: {}'.format(asset_info)) for security in remove_queue_list: del context.trade_queue[security] context.clear_queue_run += 1 if bool(context.trade_queue): if context.clear_queue_run % 5 == 0: log.info('Items remaining in trade queue: {}'.format( context.trade_queue)) else: log.info('Trade queue is now empty')
def sell(context, data): context.tracker = clean_tracker(context.tracker, context.portfolio.positions) add_to_tracker(context.tracker, context.portfolio.positions, context.tmp_tracker) increment_day(context.tracker) for security in context.portfolio.positions: if data.can_trade(security): age = int(context.tracker[security.symbol]['days']) if is_expired(age): order_target_percent(security, 0) else: price_share = context.portfolio.positions[security].cost_basis atr = float(context.tracker[security.symbol]['atr']) stop_loss_price = get_stop_price(price_share, atr) if stop_loss_price > 0: order_target_percent(security, 0, style=StopOrder(stop_loss_price)) profit_price = price_share * 1.03 last_price = context.portfolio.positions[security].last_sale_price if last_price >= profit_price: order_target_percent(security, 0) context.tmp_tracker = dict()
def handle_data(context, data): # Morning Margin Check (UTC timezone) - LONG ONLY if get_datetime().hour == 14 and get_datetime().minute == 35: context.requiredMargin = marginRequirements(context.portfolio) * 3.0 if context.portfolio.cash < 0.: context.usedMargin = abs(context.portfolio.cash) else: context.usedMargin = 0. if context.requiredMargin < context.usedMargin: log.warn('MARGIN REQUIREMENTS EXCEEDED. ' +\ 'Used Margin = ' + str(context.usedMargin) +\ ' Allowable Margin = ' + str(context.requiredMargin)) # Liquidate if total value falls 10% or more (disable margin use after 5% loss) if 0.9 * (context.portfolio.positions_value + context.portfolio.cash) > context.trailingStopPortfolioValue: context.trailingStopPortfolioValue = 0.90 * ( context.portfolio.positions_value + context.portfolio.cash) context.disableMarginPortfolioValue = 0.95 * ( context.portfolio.positions_value + context.portfolio.cash) if (context.portfolio.positions_value + context.portfolio.cash) < context.trailingStopPortfolioValue: log.warn('*** L I Q U I D A T E ***') liquidate(context.portfolio) context.trailingStopPortfolioValue = 0.90 * ( context.portfolio.positions_value + context.portfolio.cash) if (context.portfolio.positions_value + context.portfolio.cash) < context.disableMarginPortfolioValue: log.info('*** MARGIN USE DISABLED ***') context.allowableMargin = 1. context.enableMarginPortfolioValue = 1.10 * ( context.portfolio.positions_value + context.portfolio.cash) elif (context.portfolio.positions_value + context.portfolio.cash) > context.enableMarginPortfolioValue: log.info('*** MARGIN USE ENABLED ***') context.allowableMargin = 2. # End of Day if get_datetime().hour == 20 and get_datetime().minute == 55: for stock in list(data.keys()): closeAnyOpenOrders(stock) #if loc_dt.month != context.previous_month: ### if (get_datetime() - context.lastPortfolioUpdate) >= timedelta(weeks=context.rebalanceFrequency): ### context.lastPortfolioUpdate = get_datetime() ### log.debug('Number of secruities to be considered: ' + str(len(data.keys()))) if get_datetime().hour == 14 and get_datetime().minute == 35: all_prices = history(250, '1d', 'price') daily_returns = all_prices.pct_change().dropna() dr = np.array(daily_returns) (rr, cc) = dr.shape expreturns, covars = assets_meanvar(dr, list(data.keys())) R = expreturns C = covars rf = 0.015 expreturns = np.array(expreturns) frontier_mean, frontier_var, frontier_weights = solve_frontier( R, C, rf, context) f_w = array(frontier_weights) (row_1, col_1) = f_w.shape # Choose an allocation along the efficient frontier wts = frontier_weights[context.risk_tolerance] new_weights = wts # Set leverage to 1 leverage = sum(abs(new_weights)) portfolio_value = (context.portfolio.positions_value + context.portfolio.cash) / leverage record(PV=portfolio_value) record(Cash=context.portfolio.cash) # Reweight portfolio i = 0 for sec in list(data.keys()): if wts[i] < 0.01: wts[i] = 0.0 if wts[i] < 0.01 and context.portfolio.positions[sec].amount == 0: i = i + 1 continue order_target_percent(sec, wts[i], None, None) log.info('Adjusting ' + str(sec) + ' to ' + str(wts[i] * 100.0) + '%') i = i + 1
def handle_trade(context, data): context.dgaz = [symbol('DGAZ')] context.ugaz = [symbol('UGAZ')] current_dgaz_price = data.current(context.dgaz, 'price') current_ugaz_price = data.current(context.ugaz, 'price') average_dgaz_two_week_price = dgaz_two_week_price.mean() average_ugaz_two_week_price = ugaz_two_week_price.mean() average_dgaz_week_price = dgaz_week_price.mean() if current_dgaz_price > average_dgaz_two_week_price: order_target_percent(symbol('DGAZ'), 0) if current_ugaz_price > average_ugaz_two_week_price: order_target_percent(symbol('UGAZ'), 0) if current_dgaz_price <= (0.8 * average_dgaz_two_week_price): order_target_percent(symbol('DGAZ'), 0) if current_ugaz_price <= (0.8 * average_ugaz_two_week_price): order_target_percent(symbol('UGAZ'), 0) if current_dgaz_price <= (0.8 * average_dgaz_two_week_price): order_target_percent(symbol('UGAZ'), 1) if current_ugaz_price <= (0.8 * average_ugaz_two_week_price): order_target_percent(symbol('DGAZ'), 1) if current_dgaz_price < (0.95 * average_dgaz_week_price): order_target_percent(symbol('DGAZ'), 1) if current_dgaz_price >= (1.1 * average_dgaz_two_week_price): order_target_percent(symbol('DGAZ'), 1)
def rebalance(context, data): if context.ndays % context.idays == 0: if context.str_weight == 1: rdf = context.pipe_out # Remove stocks with trade restrictions and non-shortable stocks for short selection assets = api.list_assets() asset_dict = {} for i in range(len(assets)): asset_dict.update({assets[i].symbol: assets[i].easy_to_borrow}) rdf['etb'] = rdf['symbol'].map(asset_dict) rdf = rdf[~rdf['symbol'].isin(context.combined_restrictions)] rdf_short = rdf[rdf.etb == True] # Select securities for long and short if context.flip_signal == False: longs = rdf['ind_adj_str'].nsmallest(context.num_longs * 2) longs = longs.nlargest(context.num_longs) shorts = rdf_short['ind_adj_str'].nlargest(context.num_shorts) else: longs = rdf['ind_adj_str'].nlargest(context.num_longs) shorts = rdf_short['ind_adj_str'].nsmallest(context.num_shorts) # Select and log stocks to trade context.longs = longs.index.tolist() context.shorts = shorts.index.tolist() log.info('longs: {}'.format(context.longs)) log.info('Shorts: {}'.format(context.shorts)) log.info('Portfolio positions: {}'.format( context.portfolio.positions)) # Place trades log.info('Rebalancing existing positions') not_tradeable_count = 0 for security in context.portfolio.positions: if security not in context.longs and security not in context.shorts: if data.can_trade(security): order_id = order_target_percent(security, 0.0) else: not_tradeable_count += 1 log.warning('{} is not able to trade'.format(security)) context.trade_queue[security] = 0.0 log.info('Rebalancing existing positions complete!') # Check circuit breaker if not_tradeable_count / 30 > 0.75: log.info('Circuit breaker may have been hit') log.info('Buying new long positions') for security in context.longs: if data.can_trade(security): order_id = order_target_percent(security, context.long_weight) else: log.warning('{} is not able to trade'.format(security)) context.trade_queue[security] = context.long_weight log.info('Buying new long positions complete!') log.info('Selling new short positions') for security in context.shorts: if data.can_trade(security): order_id = order_target_percent(security, context.short_weight) else: log.warning('{} is not able to trade'.format(security)) context.trade_queue[security] = context.short_weight log.info('Selling new short positions complete!') log.info('Trading complete!') context.rebalance_complete = True else: for security in context.portfolio.positions: if security not in context.SPY: if data.can_trade(security): order_target_percent(security, 0.0) else: not_tradeable_count += 1 log.warning('{} is not able to trade'.format(security)) context.trade_queue[security] = 0.0 order_target_percent(context.SPY, context.spyleverage)
def morning_day_trade3(context, data): for stock in context.portfolio.positions: if((data.current(stock, 'price')) - context.portfolio.positions[stock].cost_basis)/context.portfolio.positions[stock].cost_basis > 0.2: if (context.portfolio.positions[stock].amount > 0): #or context.portfolio.positions[stock].amount < 0): order_target_percent(stock, 0) log.info("{} Current Price = {} :: Cost Basis = {}",stock.symbol, data.current(stock, 'price'), context.portfolio.positions[stock].cost_basis)
def morning_day_trade2(context, data): for stock in context.portfolio.positions: if((data.current(stock, 'price')) - context.portfolio.positions[stock].cost_basis)/context.portfolio.positions[stock].cost_basis > 0.001: if ((context.portfolio.positions[stock].amount > 0) or (data.current(stock, 'price') < 0.30)): order_target_percent(stock, 0)