Ejemplo n.º 1
0
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 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
Ejemplo n.º 3
0
def check_order(order, trader: shift.Trader):
    sleep(1)
    status = get_order_status(order)
    tries = 0
    while status != shift.Order.Status.REJECTED and status != shift.Order.Status.FILLED and tries < 10:
        sleep(1)
        tries += 1
        status = get_order_status(order)
    if status != shift.Order.Status.REJECTED and status != shift.Order.Status.FILLED:
        trader.submit_cancellation(order)
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
def cancel_all_trades(trader: shift.Trader, ticker: str):
    for o in trader.get_waiting_list():
        if(o.symbol == ticker):
            trader.submit_cancellation(o)
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
def marketMaker(trader: shift.Trader,
                ticker,
                dayEnd,
                allocation,
                orderType,
                lag=3,
                fillTime=30,
                spreadWiden=0.00):

    # Datetime of simulation
    rightNow = trader.get_last_trade_time()

    fillTime = fillTime * 10
    # While the time is before end of day...
    while dayEnd > rightNow:
        time.sleep(lag)  # Give prices some time to change
        """
        Make Trades Here:
        """
        onHand = trader.get_portfolio_item(ticker).get_shares() * (
            (trader.get_best_price(ticker).get_bid_price() +
             trader.get_best_price(ticker).get_ask_price()) / 2
        )  # Portfolio value of the stock
        maxAllowed = allocation * (
            1000000 + trader.get_portfolio_summary().get_total_realized_pl()
        )  # Maximum portfolio allocation for this stock
        print(ticker, "on hand:", round(onHand, 2), "max:", round(maxAllowed),
              "    P/L:",
              round(trader.get_portfolio_summary().get_total_realized_pl(),
                    2), " Waiting list:", trader.get_waiting_list_size())

        if onHand > maxAllowed and orderType == shift.Order.Type.LIMIT_BUY:  # Holding too much
            continue  # Allow Sell side to catch up
        elif onHand < -maxAllowed and orderType == shift.Order.Type.LIMIT_SELL:  # Short too much
            continue  # Allow Buy side to catch up

        time.sleep(lag)  # Give prices some time to change

        # Submit an order
        bid = trader.get_best_price(ticker).get_bid_price()
        ask = trader.get_best_price(ticker).get_ask_price()
        spreadWiden = max(.01, (ask - bid) * .25)
        if (ask - bid) < .05:  # If spread is too tight, widen it
            spreadWiden = -spreadWiden

        if orderType == shift.Order.Type.LIMIT_BUY:
            size = max(
                1, round(trader.get_best_price(ticker).get_ask_size() / 5)
            )  # Only buy as much as you can sell. Divide by 5 so buying power lasts on high volume. At least 1
            price = bid + spreadWiden  # Can buy above bid if wide spread, or below bid if high volume
        elif orderType == shift.Order.Type.LIMIT_SELL:
            size = max(
                1, round(trader.get_best_price(ticker).get_ask_size() / 5)
            )  # Only sell as much as you can buy back. Divide by 5 to decrease risk. At least 1
            price = ask - spreadWiden  # Can sell below ask if wide spread, or above ask if high volume

        order = shift.Order(orderType, ticker, size, price)
        trader.submit_order(order)
        #print(orderType, size, ticker, "@", price)

        # Give the order time to fill
        waitCount = 1
        while trader.get_order(
                order.id
        ).status != shift.Order.Status.FILLED and waitCount <= fillTime and trader.get_order(
                order.id).status != shift.Order.Status.REJECTED:
            #print(waitCount, ticker, "Status:",trader.get_order(order.id).status)
            time.sleep(.1)
            waitCount = waitCount + 1
        #print(waitCount, trader.get_order(order.id).status)

        # Cancel the buy order if never filled and was not rejected
        if trader.get_order(
                order.id
        ).status != shift.Order.Status.REJECTED and trader.get_order(
                order.id).status != shift.Order.Status.FILLED:
            trader.submit_cancellation(order)
            #print("Cancelled", ticker)

        rightNow = trader.get_last_trade_time()  # Reset datetime of right now

    # 30 minutes till end of trading day
    closePositions(trader, ticker)

    # Done trading
    return
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)