예제 #1
0
def portfolioSummary(trader: shift.Trader):
    """Takes Trader Object and Prints Summary of Portfolio to Console"""
    print("Buying Power\tTotal Shares\tTotal P&L\tTimestamp")
    print("%12.2f\t%12d\t%9.2f\t%26s" % (
        trader.get_portfolio_summary().get_total_bp(),
        trader.get_portfolio_summary().get_total_shares(),
        trader.get_portfolio_summary().get_total_realized_pl(),
        trader.get_portfolio_summary().get_timestamp(),
    ))

    print()

    print("Symbol\t\tShares\t\tPrice\t\t  P&L\tTimestamp")
    for item in trader.get_portfolio_items().values():
        print("%6s\t\t%6d\t%9.2f\t%9.2f\t%26s" % (
            item.get_symbol(),
            item.get_shares(),
            item.get_price(),
            item.get_realized_pl(),
            item.get_timestamp(),
        ))

    print()

    return
예제 #2
0
def demo_07(trader: shift.Trader):
    """
    This method provides information on the structure of PortfolioSummary and PortfolioItem objects:
     get_portfolio_summary() returns a PortfolioSummary object with the following data:
     1. Total Buying Power (get_total_bp())
     2. Total Shares (get_total_shares())
     3. Total Realized Profit/Loss (get_total_realized_pl())
     4. Timestamp of Last Update (get_timestamp())

     get_portfolio_items() returns a dictionary with "symbol" as keys and PortfolioItem as values,
     with each providing the following information:
     1. Symbol (get_symbol())
     2. Shares (get_shares())
     3. Price (get_price())
     4. Realized Profit/Loss (get_realized_pl())
     5. Timestamp of Last Update (get_timestamp())
    :param trader:
    :return:
    """

    print("Buying Power\tTotal Shares\tTotal P&L\tTimestamp")
    print(
        "%12.2f\t%12d\t%9.2f\t%26s"
        % (
            trader.get_portfolio_summary().get_total_bp(),
            trader.get_portfolio_summary().get_total_shares(),
            trader.get_portfolio_summary().get_total_realized_pl(),
            trader.get_portfolio_summary().get_timestamp(),
        )
    )

    print()

    print("Symbol\t\tShares\t\tPrice\t\t  P&L\tTimestamp")
    for item in trader.get_portfolio_items().values():
        print(
            "%6s\t\t%6d\t%9.2f\t%9.2f\t%26s"
            % (
                item.get_symbol(),
                item.get_shares(),
                item.get_price(),
                item.get_realized_pl(),
                item.get_timestamp(),
            )
        )

    return
예제 #3
0
def demo_01(trader: shift.Trader):
    # We haven't developed a strategy yet.
    # We only want to test whether we could
    # get through the market/limit orders

    limit_buy = shift.Order(shift.Order.Type.LIMIT_BUY, "AAPL", 10, 165.00)
    trader.submit_order(limit_buy)

    xom_limit_buy = shift.Order(shift.Order.Type.LIMIT_BUY, "XOM", 10, 10.00)
    trader.submit_order(xom_limit_buy)

    aapl_market_buy = shift.Order(shift.Order.Type.MARKET_BUY, "AAPL", 1)
    trader.submit_order(aapl_market_buy)

    xom_market_buy = shift.Order(shift.Order.Type.MARKET_BUY, "XOM", 1)
    trader.submit_order(xom_market_buy)

    aapl_market_sell = shift.Order(shift.Order.Type.MARKET_SELL, "AAPL", 1)
    trader.submit_order(aapl_market_sell)

    xom_market_sell = shift.Order(shift.Order.Type.MARKET_SELL, "XOM", 1)
    trader.submit_order(xom_market_sell)

    print("AAPL:")
    print("  Price\t\tSize\t  Dest\t\tTime")
    for order in trader.get_order_book("AAPL", shift.OrderBookType.LOCAL_BID):
        print("%7.2f\t\t%4d\t%6s\t\t%19s" %
              (order.price, order.size, order.destination, order.time))

    print()

    print("XOM:")
    print("  Price\t\tSize\t  Dest\t\tTime")
    for order in trader.get_order_book("XOM", shift.OrderBookType.LOCAL_BID):
        print("%7.2f\t\t%4d\t%6s\t\t%19s" %
              (order.price, order.size, order.destination, order.time))

    print("Buying Power\tTotal Shares\tTotal P&L\tTimestamp")
    print("%12.2f\t%12d\t%9.2f\t%26s" % (
        trader.get_portfolio_summary().get_total_bp(),
        trader.get_portfolio_summary().get_total_shares(),
        trader.get_portfolio_summary().get_total_realized_pl(),
        trader.get_portfolio_summary().get_timestamp(),
    ))

    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
예제 #5
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)
예제 #6
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)
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 technicalStrat(trader: shift.Trader, ticker, lastTradeSell, dayEnd, lag=1):

    rightNow = trader.get_last_trade_time()  # Datetime of simulation

    # While the time is before end of day...
    while (dayEnd > rightNow):
        print("P/L:",
              trader.get_portfolio_summary().get_total_realized_pl(),
              " Waiting list:", trader.get_waiting_list_size())
        """
        Make Trades Here:
        """
        priceSeries = pd.Series(trader.get_sample_prices(
            ticker, True))  # ticker, mid-prices
        time.sleep(lag)  # Give prices some time to change

        if priceSeries.size == 26:
            mShort = priceSeries.ewm(span=12,
                                     adjust=False).mean()  # 12 period EMA
            mLong = priceSeries.ewm(span=26,
                                    adjust=False).mean()  # 26 period EMA
            MACD = mShort - mLong  # Calculate convergence and divergence

            mSignal = MACD.ewm(span=9,
                               adjust=False).mean()  # 9 period EMA signal line

            mHist = MACD - mSignal  # Trade signal producer

            SMA = priceSeries[:19].mean()  # 20 second simple moving average
            if lastTradeSell == True:
                bUpper = SMA + (priceSeries[:19].std() * 3.0
                                )  # Upper Bollinger Band
                bLower = SMA - (
                    priceSeries[:19].std() * 1.5
                )  # Low Bollinger Band - more lenient, safer sell
            else:
                bUpper = SMA + (
                    priceSeries[:19].std() * 1.5
                )  # Upper Bollinger Band - more lenient, safer cover
                bLower = SMA - (priceSeries[:19].std() * 3.0
                                )  # Low Bollinger Band
            #######!!!!!!possibly have a second band outside first..for too strong movement!!!!!!!!!!!!!!!!!!!!!!!!!!!!

            # Open long position / Cover short position
            if lastTradeSell == True and mHist.iloc[
                    -1] > 0 and trader.get_close_price(
                        ticker, True, 1) > bUpper:  # ticker, Buy, Size

                for i in range(
                        1, 20
                ):  # should scale based on order book amount in competition..
                    openLong = shift.Order(shift.Order.Type.MARKET_BUY, ticker,
                                           1)
                    trader.submit_order(openLong)

                print("Tech - Buy", ticker)
                lastTradeSell = False

            # Close long positions for now / Open short position
            elif lastTradeSell == False and mHist.iloc[
                    -1] < 0 and trader.get_close_price(
                        ticker, False, 1) < bLower:  # ticker, Sell, Size

                for i in range(
                        1, 20
                ):  # should scale based on order book amount in competition..
                    closeLong = shift.Order(shift.Order.Type.MARKET_SELL,
                                            ticker, 1)
                    trader.submit_order(closeLong)

                print("Tech - Sell", ticker)
                lastTradeSell = True

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

    # 60 seconds till end of trading day
    trader.cancel_all_sample_prices_requests(
    )  # Stop sampling prices on threads
    closePositions(trader,
                   ticker)  # Close out open positions so we don't get fined

    # 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)