def closePositions(trader: shift.Trader, ticker): # Cancel pending orders print("Waiting list size:", trader.get_waiting_list_size()) for order in trader.get_waiting_list(): if order.symbol == ticker: trader.submit_cancellation(order) print("All", ticker, "pending orders cancelled" ) # Cancel open orders before submitting closing orders # Close / Cover all open positions #portfolioSummary(trader) # Print summary of portfolio**************************************************************************Good for developing item = trader.get_portfolio_item(ticker) if item.get_shares() > 0: closeLong = shift.Order( shift.Order.Type.MARKET_SELL, item.get_symbol(), int(item.get_shares() / 100)) # Order size in 100's of shares, strictly as an int trader.submit_order(closeLong) #print("Close all long positions") elif item.get_shares() < 0: coverShort = shift.Order(shift.Order.Type.MARKET_BUY, item.get_symbol(), int(item.get_shares() / -100)) trader.submit_order(coverShort) #print("Close all short positions") print("All", ticker, "closing orders submitted") return
def demo_04(trader: shift.Trader): """ This method prints all current waiting orders information. :param trader: :return: """ print( "Symbol\t\t\t\tType\t Price\t\tSize\tExecuted\tID\t\t\t\t\t\t\t\t\t\t\t\t\t\t Status\t\tTimestamp" ) for o in trader.get_waiting_list(): print( "%6s\t%16s\t%7.2f\t\t%4d\t\t%4d\t%36s\t%23s\t\t%26s" % ( o.symbol, o.type, o.price, o.size, o.executed_size, o.id, o.status, o.timestamp, ) ) return
def run_stop_loss_check(trader: shift.Trader, state: Dict[str, Any]) -> None: """ check for stop loss hit """ stop_loss_interval = 5 # seconds acceptable_loss = .2 # percent if stop_loss_key not in state: state[stop_loss_key] = {} while True: sleep(stop_loss_interval) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() current_price = state[prices_key][ticker][-1] new_stop_loss = current_price * ((100 - acceptable_loss) / 100.) has_stop_loss = ticker in state[stop_loss_key] if not has_stop_loss or new_stop_loss > state[stop_loss_key][ ticker]: if has_stop_loss: for order in trader.get_waiting_list(): if order.symbol == ticker and order.type == shift.Order.Type.LIMIT_SELL: trader.submit_cancellation(order) limit_sell = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, item.get_shares()) trader.submit_order(limit_sell) state[stop_loss_key][ticker] = new_stop_loss, limit_sell
def demo_05(trader: shift.Trader): """ This method cancels all the orders in the waiting list. :param trader: :return: """ print( "Symbol\t\t\t\tType\t Price\t\tSize\tExecuted\tID\t\t\t\t\t\t\t\t\t\t\t\t\t\t Status\t\tTimestamp" ) for o in trader.get_waiting_list(): print( "%6s\t%16s\t%7.2f\t\t%4d\t\t%4d\t%36s\t%23s\t\t%26s" % ( o.symbol, o.type, o.price, o.size, o.executed_size, o.id, o.status, o.timestamp, ) ) print() print("Waiting list size: " + str(trader.get_waiting_list_size())) print("Canceling all pending orders...", end=" ") # trader.cancel_all_pending_orders() also works for o in trader.get_waiting_list(): trader.submit_cancellation(o) i = 0 while trader.get_waiting_list_size() > 0: i += 1 print(i, end=" ") time.sleep(1) print() print("Waiting list size: " + str(trader.get_waiting_list_size())) return
def longer(trader: shift.Trader, tickers): today = trader.get_last_trade_time() endTime = dt.time(15, 50, 0) dayEnd = dt.datetime.combine(today, endTime) tickSize = 0.01 bp = (trader.get_portfolio_summary().get_total_bp()) dpa = bp / float(len(tickers)) for t in tickers: lastPrice = trader.get_last_price(t) while lastPrice == 0: lastPrice = trader.get_last_price(t) s = int((dpa / lastPrice) / 100) for i in range(0, s): # limitBuyPrice = lastPrice - tickSize limit_sell = shift.Order(shift.Order.Type.MARKET_BUY, t, 1) trader.submit_order(limit_sell) while trader.get_last_trade_time() < dayEnd: time.sleep(1) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for t in tickers: print(t) lastPrice = trader.get_last_price(t) item = trader.get_portfolio_item(t) if item.get_shares() > 0: sell = shift.Order( shift.Order.Type.MARKET_SELL, t, int(item.get_shares() / 100)) # Order size in 100's of shares, strictly as an int trader.submit_order(sell) elif item.get_shares() < 0: buy = shift.Order( shift.Order.Type.MARKET_BUY, t, int(-1 * item.get_shares() / 100)) # Order size in 100's of shares, strictly as an int trader.submit_order(buy) print(f'submitted buy for {t}') time.sleep(15) utils.print_portfolio_information(trader) utils.print_all_submitted_order(trader) print(trader.get_last_trade_time()) return
def waiting_list_updated_cb(trader: shift.Trader): if trader.get_waiting_list_size() > 0: waiting_list = trader.get_waiting_list() print("Waiting List:") for order in waiting_list: print("%6s\t%21s\t%7.2f\t\t%4d\t\t%4d\t%36s\t%28s\t%26s" % ( order.symbol, order.type, order.price, order.size, order.executed_size, order.id, order.status, order.timestamp, )) else: print("Waiting List Empty!")
def main(trader: shift.Trader) -> None: """ main entrypoint """ trader = shift.Trader(credentials.my_username) try: trader.connect("initiator.cfg", credentials.my_password) trader.sub_all_order_book() except shift.IncorrectPasswordError as e: print(e) except shift.ConnectionTimeoutError as e: print(e) time.sleep(2) check_time = 5 # minutes current = trader.get_last_trade_time() start_time = dt.combine(current, dt.datetime(10, 0, 0)) end_time = dt.combine(current, dt.datetime(15, 30, 0)) while trader.get_last_trade_time() < start_time: sleep(check_time * 60) processes = run_processes(trader) while trader.get_last_trade_time() < end_time: sleep(check_time * 60) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, item.get_shares()) trader.submit_order(sell) time_wait_sell = 60 # seconds sleep(time_wait_sell) stop_processes(processes) # print stuff routine_summary(trader)
def run_trades(trader: shift.Trader, state: Dict[str, Any]) -> None: """ run buy / sell trades """ run_trades_interval = 60 # seconds while True: sleep(run_trades_interval) unsorted_differences: List[float] = [] unsorted_tickers: List[str] = [] for ticker in tickers: prices = np.array(list(state[prices_key][ticker])) ema_difference, price_minus_bollinger = get_should_long(prices) unsorted_differences.append(ema_difference) unsorted_tickers.append(ticker) _, ranked_tickers = map( list, zip(*sorted(zip(unsorted_differences, unsorted_tickers)))) for ticker in ranked_tickers: prices = np.array(list(state[prices_key][ticker])) ema_difference, price_minus_bollinger = get_should_long(prices) item = trader.get_portfolio_item(ticker) if item.get_shares() > 0: # check to sell if price_minus_bollinger > 0 or ema_difference < 0: sell = shift.Order( shift.Order.Type.MARKET_SELL, ticker, int(math.ceil((item.get_shares() / 2) / 100.0))) trader.submit_order(sell) else: for order in trader.get_waiting_list(): if order.symbol == ticker and order.type == shift.Order.Type.MARKET_BUY: trader.submit_cancellation(order) if ema_difference > 0: bp = trader.get_portfolio_summary().get_total_bp() amount = 200e3 if bp >= amount: lastPrice = trader.get_last_price(ticker) s = int((amount / lastPrice) / 100.) buy = shift.Order(shift.Order.Type.MARKET_BUY, ticker, s) trader.submit_order(buy)
def __call__(self, trader: shift.Trader): if self.verbose: if trader.get_waiting_list_size() > 0: waiting_list = trader.get_waiting_list() print("Waiting List:") for order in waiting_list: print( "%6s\t%16s\t%7.2f\t\t%4d\t\t%4d\t%36s\t%23s\t\t%26s" % ( order.symbol, order.type, order.price, order.size, order.executed_size, order.id, order.status, order.timestamp, )) else: print("Waiting List Empty!")
def run_stop_loss_check(trader: shift.Trader, state: Dict[str, Any]) -> None: """ check for stop loss hit """ stop_loss_interval = 5 # seconds acceptable_loss = .2 # percent # if stop_loss_key not in stop_losses_state: # stop_losses_state = {} ''' Set original stop loss when originally buying to -.2% Set original target when originally buying to the bollinger band Update target every minute to the most recent bollinger band First time you hit target: remove half position update stop loss to original buy prices and make this a trailing stop Keep updating target Scenario: Buy 100 at 100 Set stop loss to 99.8 and target to 101 We hit 101 so we sell 50 (left with 50) and update stop loss to 100 101 - 100 = stop loss Next minute upper band changes to 102: change target to 102 Next minute upper band changes to 99: sell everything ALREADY HIT TARGET ONCE: We hit 102 so we sell 25 (left with 25) and update stop loss to 101 price goes to 101.50, stop loss is 101 price hits target at 104, stop loss is 103.50 begin position initial_buy_price = ... target = upper_bollinger_band[-1] stop_loss = initial_buy_price*-.002 first target hits stop_loss = (1 - ((first_target_sell - initial_buy_price) / initial_buy_price))*current_price price goes up stop_loss = (1 - ((first_target_sell - initial_buy_price) / initial_buy_price))*current_price second target hits - just half, and reapply trailing stop loss stop_loss = (1 - ((first_target_sell - initial_buy_price) / initial_buy_price))*current_price price goes down stop_loss = stop_loss ''' while True: sleep(stop_loss_interval) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() current_price = state[prices_key][ticker][-1] new_stop_loss = current_price * ((100 - acceptable_loss) / 100.) has_stop_loss = ticker in state[stop_loss_key] if not has_stop_loss or new_stop_loss > state[stop_loss_key][ticker]: if has_stop_loss: for order in trader.get_waiting_list(): if order.symbol == ticker and order.type == shift.Order.Type.LIMIT_SELL: trader.submit_cancellation(order) limit_sell = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, item.get_shares()) trader.submit_order(limit_sell) state[stop_loss_key][ticker] = new_stop_loss, limit_sell
def main(trader: shift.Trader) -> None: """ main entrypoint """ # { # "prices": { # "AAPL": [234] # }, # } manager = Manager() list_of_shared_dicts = manager.list() list_of_shared_dicts.append({}) # prices_state = list_of_shared_dicts[0] # stop_losses_state = list_of_shared_dicts[1] state = list_of_shared_dicts[0] keys_in_state = [prices_key, stop_loss_key, target_key] for key in keys_in_state: state[key] = manager.dict() for ticker in tickers: if key == prices_key: state[key].setdefault(key, []) elif key == target_key: state[key].setdefault(key, [0,0]) # if key == stop_loss_key: # state[trader_key] = trader # trader_obj = state check_time = 1 # minutes current = trader.get_last_trade_time() start_time = datetime.combine(current, dt.time(10,0,0)) end_time = datetime.combine(current, dt.time(15, 30, 0)) print(trader.get_last_trade_time()) pre_processes = [] for ticker in tickers: # 1 thread per ticker getting price data & saving it pre_processes.append(Thread(target=run_save_prices, args=(ticker, trader, state))) # run_save_prices(ticker, trader, state) for process in pre_processes: process.start() print(f"{len(pre_processes)} processes created for run_save_prices") while trader.get_last_trade_time() < start_time: print(f"Waiting for Market Open @ {trader.get_last_trade_time()}") sleep(check_time * 60) processes = pre_processes.extend(run_processes(trader, state)) while trader.get_last_trade_time() < end_time: print(f"Waiting for Market Close @ {trader.get_last_trade_time()}") sleep(check_time * 60) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, item.get_shares()) trader.submit_order(sell) time_wait_sell = 60 # seconds sleep(time_wait_sell) stop_processes(processes) # print stuff routine_summary(trader)
def cancel_all_trades(trader: shift.Trader, ticker: str): for o in trader.get_waiting_list(): if(o.symbol == ticker): trader.submit_cancellation(o)
def run_trades(trader: shift.Trader, state: Dict[str, Any]) -> None: """ run buy / sell trades """ run_trades_interval = 60 # seconds maxLoss = 0.01 while True: # if (len()) unsorted_differences: List[float] = [] unsorted_tickers: List[str] = [] for ticker in tickers: print(f"entered run trades: {ticker}") if (ticker not in state[prices_key]) or len(list(state[prices_key][ticker])) < 22: # print(f"have {len(list(state[prices_key][ticker]))} prices for {ticker}...moving on") continue prices = np.array(list(state[prices_key][ticker])) # print(f"Prices({len(prices)}): {prices} ") should_long = get_should_long(prices) if(should_long is None): # print(f"should_long is None {ticker}") continue ema_difference = should_long["ema_difference"] prev_ema_difference = should_long["prev_ema_difference"] # print(f"emaaaaa {ticker}: {ema_difference}") unsorted_differences.append(ema_difference) unsorted_tickers.append(ticker) if(len(unsorted_differences) < 5): sleep(5) continue print(unsorted_differences) print(unsorted_tickers) _, ranked_tickers = (reversed(list(t)) for t in zip(*sorted(zip(unsorted_differences, unsorted_tickers)))) for ticker in ranked_tickers: prices = np.array(list(state[prices_key][ticker])) should_long = get_should_long(prices) if(should_long is None): sleep(1) continue ema_difference = should_long["ema_difference"] price_minus_bollinger_high = should_long["bollinger_band_high_difference"] price_minus_bollinger_low = should_long["bollinger_band_low_difference"] last_upper_bollinger_band = should_long["last_bollinger_band_high"] last_lower_bollinger_band = should_long["last_bollinger_band_low"] item = trader.get_portfolio_item(ticker) if item.get_shares() > 0: # check to sell target_hit_count = state[target_key][ticker][0] if ema_difference < 0: cancel_all_trades(trader, ticker) sleep(2) print(f"{ticker} : HAVE SHARES, EMA CROSSED DOWN, SELL") sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, int(item.get_shares()/100.0)) trader.submit_order(sell) # over band, never hit elif price_minus_bollinger_high > 0 and target_hit_count == 0: cancel_all_trades(trader, ticker) sleep(2) s = item.get_shares() print(f"{ticker} : HAVE SHARES, FIRST TARGET HIT, SELL HALF") sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, int(math.ceil((s/2) / 100.0))) trader.submit_order(sell) sleep(5) #check if you didn't happen to sell all due to minimum lot if int(math.ceil((item.get_shares()/2) / 100.0)) < int(s/100): lastPrice = trader.get_last_price(ticker) initial_buy_price = item.get_price() #keep track of this in state trailing_stop_perc = (lastPrice - initial_buy_price) / initial_buy_price trailing_stop_price = (1 - trailing_stop_perc) * lastPrice print(f"{ticker} : HAVE SHARES, FIRST TARGET HIT, RESETTING LIMIT SELL") sell = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, int(math.ceil((item.get_shares()/2) / 100.0)), trailing_stop_price) trader.submit_order(sell) state[target_key][ticker] = [target_hit_count + 1, trailing_stop_perc] elif target_hit_count > 0: sold = 0 if price_minus_bollinger_low > 0: cancel_all_trades(trader, ticker) sleep(2) sold = int(math.ceil((item.get_shares()/2) / 100.0)) print(f"{ticker} : HAVE SHARES, OVER FIRST TARGET HIT, TAKING MORE PROFIT SINCE STILL ABOVE BOLLINGER, SELL HALFT") sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, sold) trader.submit_order(sell) sleep(5) if sold < int(item.get_shares()/100): lastPrice = trader.get_last_price(ticker) avg_last_two_prices = (state[prices_key][ticker][-2] + state[prices_key][ticker][-1]) / 2. if lastPrice >= avg_last_two_prices: cancel_all_trades(trader, ticker) sleep(2) # keep same percentarange and update the loss PRICE trailing_stop_perc = state[target_key][ticker][1] trailing_stop_price = (1 - trailing_stop_perc) * lastPrice print(f"{ticker} : HAVE SHARES, OVER FIRST TARGET HIT, SOLD MORE PROFIT SINCE STILL ABOVE BOLLINGER, STILL HAVE MORE, RESETTING LIMIT") sell = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, item.get_shares() / 100.0, trailing_stop_price) trader.submit_order(sell) sleep(5) else: pass elif item.get_shares() < 0: #check to see if we need to exit short positions target_hit_count = state[target_key][ticker][0] if ema_difference > 0: cancel_all_trades(trader, ticker) sleep(2) buy = Shift.Order(shift.Order.Type.MARKET_BUY, ticker, -1*int(item.get_shares()/100.0)) trader.submit_order(buy) elif price_minus_bollinger_low < 0 and target_hit_count == 0: cancel_all_trades(trader, ticker) sleep(2) s = item.get_shares() buy = shift.Order(shift.Order.Type.MARKET_BUY, ticker, -1*int(math.ceil((s/2) / 100.0))) trader.submit_order(buy) sleep(5) #check if you happen to buy all back due to minimum lot #if still have short positions, reset limit buy if -1*int(math.ceil((item.get_shares()/2) / 100.0)) < -1*int(s/100) : lastPrice = trader.get_last_price(ticker) initial_sell_price = item.get_price() trailing_stop_perc = (lastPrice - initial_sell_price) / initial_sell_price trailing_stop_price = (1 + trailing_stop_perc) * lastPrice buy = shift.Order(shift.Order.Type.LIMIT_BUY, ticker, int(math.ceil((item.get_shares()/2) / 100.0)), trailing_stop_price) trader.submit_order(buy) state[target_key][ticker] = [target_hit_count + 1, trailing_stop_perc] #no close of position at all, so we just wanna reset the trailing stop loss elif target_hit_count > 0: bought = 0 if price_minus_bollinger_low < 0: cancel_all_trades(trader, ticker) sleep(2) bought = -1*int(math.ceil((item.get_shares()/2) / 100.0)) buy = shift.Order(shift.Order.Type.MARKET_BUY, ticker, bought) trader.submit_order(buy) sleep(5) if bought < -1*int(item.get_shares() / 100.0): lastPrice = trader.get_last_price(ticker) avg_last_two_prices = (state[prices_key][ticker][-2] + state[prices_key][ticker][-1]) / 2. # keep same percentarange and update the loss PRICE #TODO: fix a dollar amount instead of percentage if lastPrice <= avg_last_two_prices: cancel_all_trades(trader, ticker) sleep(2) trailing_stop_perc = state[target_key][1] trailing_stop_price = (1 + trailing_stop_perc) * lastPrice buy = shift.Order(shift.Order.Type.LIMIT_BUY, ticker, item.get_shares() / 100.0, trailing_stop_price) trader.submit_order(buy) else: pass else: #reset target_hit_count because no shores no more state[target_key][ticker] = [0,0] for order in trader.get_waiting_list(): if order.symbol == ticker and order.type == shift.Order.Type.MARKET_BUY: trader.submit_cancellation(order) sleep(2) if ema_difference > 0 and prev_ema_difference < 0: bp = trader.get_portfolio_summary().get_total_bp() amount = 200e3 if bp >= amount: lastPrice = trader.get_last_price(ticker) s = int((amount / lastPrice) / 100.) buy = shift.Order(shift.Order.Type.MARKET_BUY, ticker, s) initial_buy_price = trader.get_last_price(ticker) initial_stop_loss = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, s, trader.get_last_price(ticker)*(1-maxLoss)) print(f"{ticker} : DONT HAVE SHARES, HIT TARGET, HAVE BP, BUY") trader.submit_order(buy) sleep(5) print(f"{ticker} : DONT HAVE SHARES, HIT TARGET, HAVE BP, SETTING INITIAL STOP LOSS") trader.submit_order(initial_stop_loss) elif ema_difference < 0: bp = trader.get_portfolio_summary().get_total_bp() short_profit, long_profit = get_unrealized_pl(trader) #lost money on shorts amount = (200e3 / 2) amount_to_subtract = 0 if short_profit < 0: amount_to_subtract += (-1*short_profit) if (0.995 * (amount - amount_to_subtract)) < bp: lastPrice = trader.get_last_price() s = int((amount / lastPrice) / 100.) sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, s) initial_sell_price = trader.get_last_price(ticker) initial_stop_loss = shift.Order(shift.Order.Type.LIMIT_BUY, ticker, trader.get_last_price(ticker)*(1+maxLoss), s) trader.submit_order(sell) sleep(5) trader.submit_order(initial_stop_loss) sleep(5) sleep(run_trades_interval)
def run_trades(trader: shift.Trader, state: Dict[str, Any]) -> None: """ run buy / sell trades """ run_trades_interval = 30 # seconds maxLoss = 0.004 maxGain = 0.004 while True: unsorted_differences: List[float] = [] unsorted_tickers: List[str] = [] for ticker in tickers: if (ticker not in state[prices_key]) or len( list(state[prices_key][ticker])) < 21: sleep(5) continue prices = np.array(list(state[prices_key][ticker])) should_long = get_should_long(prices) ema_difference = should_long["ema_difference"] unsorted_differences.append(ema_difference) unsorted_tickers.append(ticker) if ticker == "AAPL": print("PRE UNPACKING") print(unsorted_differences) print(unsorted_tickers) print((list(t) for t in zip( *sorted(zip(unsorted_differences, unsorted_tickers))))) _, ranked_tickers = (list(t) for t in zip( *sorted(zip(unsorted_differences, unsorted_tickers)))) for ticker in ranked_tickers: prices = np.array(list(state[prices_key][ticker])) should_long = get_should_long(prices) ema_difference = should_long["ema_difference"] price_minus_bollinger_high = should_long[ "bollinger_band_high_difference"] price_minus_bollinger_low = should_long[ "bollinger_band_low_difference"] last_upper_bollinger_band = should_long["last_bollinger_band_high"] last_lower_bollinger_band = should_long["last_bollinger_band_low"] item = trader.get_portfolio_item(ticker) if item.get_shares() > 0: # check to sell target_hit_count = state[target_key][ticker][0] if ema_difference < 0: cancel_all_trades(trader, ticker) sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, int(item.get_shares() / 100.0)) trader.submit_order(sell) elif price_minus_bollinger_high > 0 and target_hit_count == 0: # over band, never hit cancel_all_trades(trader, ticker) s = item.get_shares() sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, int(math.ceil((s / 2) / 100.0))) trader.submit_order(sell) #check if you happen to sell all due to minimum lot #if still have long positions, reset limit sell if int(math.ceil( (item.get_shares() / 2) / 100.0)) < int(s / 100): lastPrice = trader.get_last_price(ticker) initial_buy_price = item.get_price() trailing_stop_perc = ( lastPrice - initial_buy_price) / initial_buy_price trailing_stop_price = (1 - trailing_stop_perc) * lastPrice sell = shift.Order( shift.Order.Type.LIMIT_SELL, ticker, int(math.ceil((item.get_shares() / 2) / 100.0)), trailing_stop_price) trader.submit_order(sell) #keep track of this in state state[target_key][ticker] = [ target_hit_count + 1, trailing_stop_perc ] elif target_hit_count > 0: sold = 0 if price_minus_bollinger_high > 0: cancel_all_trades(trader, ticker) sold = int(math.ceil((item.get_shares() / 2) / 100.0)) sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, sold) trader.submit_order(sell) if sold < int(item.get_shares() / 100): lastPrice = trader.get_last_price(ticker) avg_last_two_prices = ( state[prices_key][ticker][-2] + state[prices_key][ticker][-1]) / 2. #we have shares, hits target for 2nd time, and price > upper bo, and we took 1/2 profit, we still have more if lastPrice >= avg_last_two_prices: cancel_all_trades(trader, ticker) # keep same percentarange and update the loss PRICE #TODO: fix a dollar amount instead of percentage trailing_stop_perc = state[target_key][ticker][1] trailing_stop_price = ( 1 - trailing_stop_perc) * lastPrice sell = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, item.get_shares() / 100.0, trailing_stop_price) trader.submit_order(sell) else: pass #comment this if you want to yeet the short logic elif item.get_shares() < 0: #check to see if we need to exit short positions target_hit_count = state[target_key][ticker][0] if ema_difference > 0: cancel_all_trades(trader, ticker) buy = Shift.Order(shift.Order.Type.MARKET_BUY, ticker, -1 * int(item.get_shares() / 100.0)) trader.submit_order(buy) elif price_minus_bollinger_low < 0 and target_hit_count == 0: cancel_all_trades(trader, ticker) s = item.get_shares() buy = shift.Order(shift.Order.Type.MARKET_BUY, ticker, -1 * int(math.ceil((s / 2) / 100.0))) trader.submit_order(buy) #check if you happen to buy all back due to minimum lot #if still have short positions, reset limit buy if -1 * int(math.ceil( (item.get_shares() / 2) / 100.0)) < -1 * int(s / 100): lastPrice = trader.get_last_price(ticker) initial_sell_price = item.get_price() trailing_stop_perc = (lastPrice - initial_sell_price ) / initial_sell_price trailing_stop_price = (1 + trailing_stop_perc) * lastPrice buy = shift.Order( shift.Order.Type.LIMIT_BUY, ticker, int(math.ceil((item.get_shares() / 2) / 100.0)), trailing_stop_price) trader.submit_order(buy) state[target_key][ticker] = [ target_hit_count + 1, trailing_stop_perc ] #no close of position at all, so we just wanna reset the trailing stop loss elif target_hit_count > 0: bought = 0 if price_minus_bollinger_low < 0: cancel_all_trades(trader, ticker) bought = -1 * int( math.ceil((item.get_shares() / 2) / 100.0)) buy = shift.Order(shift.Order.Type.MARKET_BUY, ticker, bought) trader.submit_order(buy) if bought < -1 * int(item.get_shares() / 100.0): lastPrice = trader.get_last_price(ticker) avg_last_two_prices = ( state[prices_key][ticker][-2] + state[prices_key][ticker][-1]) / 2. # keep same percentarange and update the loss PRICE #TODO: fix a dollar amount instead of percentage if lastPrice <= avg_last_two_prices: cancel_all_trades(trader, ticker) trailing_stop_perc = state[target_key][1] trailing_stop_price = ( 1 + trailing_stop_perc) * lastPrice buy = shift.Order(shift.Order.Type.LIMIT_BUY, ticker, item.get_shares() / 100.0, trailing_stop_price) trader.submit_order(buy) else: pass else: #reset target_hit_count because no shares no more state[target_key][ticker] = [0, 0] for order in trader.get_waiting_list(): if order.symbol == ticker and order.type == shift.Order.Type.MARKET_BUY: trader.submit_cancellation(order) if order.symbol == ticker and order.type == shift.Order.Type.MARKET_SELL: trader.submit_cancellation(order) if ema_difference > 0: bp = trader.get_portfolio_summary().get_total_bp() amount = 200e3 if bp >= amount: lastPrice = trader.get_last_price(ticker) s = int((amount / lastPrice) / 100.) buy = shift.Order(shift.Order.Type.MARKET_BUY, ticker, s) initial_buy_price = trader.get_last_price(ticker) initial_stop_loss = shift.Order( shift.Order.Type.LIMIT_SELL, ticker, trader.get_last_price(ticker) * (1 - maxLoss), s) trader.submit_order(buy) trader.submit_order(initial_stop_loss) #comment this if you want to yeet the short logic elif ema_difference < 0: bp = trader.get_portfolio_summary().get_total_bp() short_profit, long_profit = get_unrealized_pl(trader) #lost money on shorts amount = (200e3 / 2) amount_to_subtract = 0 if short_profit < 0: amount_to_subtract += (-1 * short_profit) if (0.995 * (amount - amount_to_subtract)) < bp: lastPrice = trader.get_last_price() s = int((amount / lastPrice) / 100.) sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, s) initial_sell_price = trader.get_last_price(ticker) initial_stop_loss = shift.Order( shift.Order.Type.LIMIT_BUY, ticker, trader.get_last_price(ticker) * (1 + maxLoss), s) trader.submit_order(sell) trader.submit_order(initial_stop_loss) # # check to see if we should enter short position pass sleep(run_trades_interval)