Esempio n. 1
0
def buy_back_shorted(ticker: str, trader: shift.Trader):

    item = trader.get_portfolio_item(ticker)
    while(item.get_shares() < 0):
        orders_placed = place_orders(shift.Order.Type.MARKET_BUY,ticker, int(-1* item.get_shares() / 100))
        sleep(10)
        item = trader.get_portfolio_item(ticker)
        print(f'submitted buy for {ticker}')
Esempio n. 2
0
def sell_long(ticker: str, trader: shift.Trader):
    
    item = trader.get_portfolio_item(ticker)
    while(item.get_shares() > 0):
        orders_placed = place_orders(shift.Order.Type.MARKET_SELL,ticker, int(item.get_shares() / 100))
        sleep(10)
        item = trader.get_portfolio_item(ticker)
        # sell = shift.Order(shift.Order.Type.MARKET_SELL,ticker, int(item.get_shares() / 100)) # Order size in 100's of shares, strictly as an int
        # trader.submit_order(sell)
        print(f'submitted sell for {ticker}')
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
Esempio n. 4
0
def run_mm_long(ticker: str, trader: shift.Trader, end_time):
    
    minimum_spread = 0.02
    maximum_allocation = 0.15

    while trader.get_last_trade_time() < end_time:
        
        sleep(frequency)       

        item = trader.get_portfolio_item(ticker)
        shares = item.get_shares()
        ask,bid,mid = get_prices(ticker)

        if bid == 0 or ask == 0:
            continue

        spread = (ask-bid)
        
        portfolio_value_of_ticker = shares*mid
        allocation = maximum_allocation*1000000
        
        if allocation > portfolio_value_of_ticker:
            lots = 3
            price = bid
            if spread < minimum_spread:
                price -= 0.01
                
            order = place_limit_order(shift.Order.Type.LIMIT_BUY, ticker, lots, price)
            status = get_order_status(order)
            check_order(order, trader)
        else: 
            continue
Esempio n. 5
0
def run_mm_short(ticker: str, trader: shift.Trader, end_time):
    minimum_spread = 0.02
    maximum_allocation = 0.1
    while trader.get_last_trade_time() < end_time:
        
        sleep(frequency)       

        item = trader.get_portfolio_item(ticker)
        short_shares = item.get_short_shares()
        ask,bid,mid = get_prices(ticker)
        if int(ask) == 0 or int(bid) == 0:
            continue

        spread = (ask-bid)
        
        portfolio_value_of_ticker = (short_shares*mid)
        allocation = maximum_allocation*1000000
        
        if allocation > portfolio_value_of_ticker:
            
            lots = 3
            price=ask
            if spread < minimum_spread:
                price += 0.01
                
            order = place_limit_order(shift.Order.Type.LIMIT_SELL, ticker, lots, price)
            check_order(order, trader)

        else: 
            continue
Esempio n. 6
0
def buy_back_half(ticker: str, trader: shift.Trader):

    item = trader.get_portfolio_item(ticker)

    if item.get_shares() == -100:
        orders_placed = place_orders(shift.Order.Type.MARKET_BUY,ticker, int(-1* item.get_shares() / 100))
    else:
        orders_placed = place_orders(shift.Order.Type.MARKET_BUY,ticker, int((-1* item.get_shares() / 100)/2))
    sleep(10)

    print(f'submitted buy for {ticker}')
Esempio n. 7
0
def get_unrealized_pl(ticker: str, trader: shift.Trader):

    p = trader.get_last_price(ticker)
    item = trader.get_portfolio_item(ticker)
    upl = -1 if item.get_shares() < 0 else 1
    currValue = item.get_shares() * p
    cost = item.get_shares() * item.get_price()
    if cost == 0:
        return 0
    upl = upl*((currValue - cost)/cost)
    return upl
Esempio n. 8
0
def manage_inventory(ticker: str, trader: shift.Trader, end_time):
    while trader.get_last_trade_time() < end_time:            
        sleep(frequency)
        upl = get_unrealized_pl(ticker, trader)
        item = trader.get_portfolio_item(ticker)
        if int(item.get_price()) != 0:
            if upl >= 0.4 or upl <= -0.2:
                print(f"Closing positions on {ticker} for {'loss' if upl <= -0.2 else 'profit'}")
                if item.get_shares() > 0:
                    sell_long(ticker)
                elif item.get_shares() < 0:
                    buy_back_shorted(ticker)
def check_pnl(ticker: str, trader: shift.Trader, state: Dict[str, Any],
              end_time):
    while trader.get_last_trade_time() < end_time:

        bid = trader.get_best_price(ticker).get_bid_price()
        ask = trader.get_best_price(ticker).get_ask_price()
        mid_price = (bid + ask) / 2

        shares = trader.get_portfolio_item(ticker).get_shares()
        cost = trader.get_portfolio_item(ticker).get_price()
        unrealized_pnl = 0
        if shares < 0:
            unrealized_pnl = (-1 * shares * cost) - (-1 * shares * mid_price)
        elif shares > 0:
            unrealized_pnl = (shares * mid_price) - (shares * cost)

        print(f"Current Mid Price: {mid_price}")
        print(f"Current Time P&L: {unrealized_pnl}")

        if unrealized_pnl >= 500:

            if trader.get_portfolio_item(ticker).get_shares() > 0:
                sell_half(ticker, trader)
                print("SELLING HALF LONGS FOR PROFIT")

            else:
                buy_back_half(ticker, trader)
                print("BUYING BACK HALF SHORTS FOR PROFIT")

        elif unrealized_pnl <= -500:

            if trader.get_portfolio_item(ticker).get_shares() > 0:
                sell_half(ticker, trader)
                print("SELLING HALF LONGS FOR LOSS")

            else:
                buy_back_half(ticker, trader)
                print("BUYING BACK HALF SHORTS FOR LOSS")

        sleep(candle_size / 2)
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
Esempio n. 11
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)
Esempio n. 12
0
def get_unrealized_pl(ticker: str, trader: shift.Trader):

    p = trader.get_last_price(ticker)
    item = trader.get_portfolio_item(ticker)
    long_shares = item.get_long_shares()
    short_shares = item.get_short_shares()
    upl = 0

    curr_long_value = long_shares * p
    cost_long = long_shares * item.get_long_price()
    curr_short_value = short_shares * p
    cost_short = short_shares * item.get_short_price()

    
    if cost_long != 0:
        upl += (curr_long_value - cost_long)/float(cost_long)
    if cost_short != 0:
        upl -= (curr_short_value - cost_short)/float(cost_short)

    return upl
Esempio n. 13
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 manageInventory(trader: shift.Trader, ticker, dayEnd):

    # Datetime of simulation
    rightNow = trader.get_last_trade_time()

    # While the time is before end of day...
    while (dayEnd > rightNow):

        time.sleep(5)  # Give prices time to fluctuate

        item = trader.get_portfolio_item(ticker)
        if item.get_shares() != 0:

            unrealizedPL = 0
            tradedPrice = item.get_price()
            numShares = int(
                item.get_shares() /
                100)  # Order size in 100's of shares, strictly as an int

            if numShares > 0:
                unrealizedPL = (
                    (trader.get_close_price(ticker, False, numShares) -
                     tradedPrice) / tradedPrice) * 100

            else:  # numShares < 0:
                unrealizedPL = -(
                    (trader.get_close_price(ticker, True, -numShares) -
                     tradedPrice) / tradedPrice) * 100

            print(ticker, "Unrealized P/L:", unrealizedPL, "%")
            if unrealizedPL >= 0.40:  # Target met, take profit
                #if unrealizedPL >= 3.0: # Target met, take profit
                if item.get_shares() > 0:
                    closePositions(trader, ticker)
                    """
                    closeLong = shift.Order(shift.Order.Type.MARKET_SELL, item.get_symbol(), numShares)
                    trader.submit_order(closeLong)
                    """
                    print(ticker, "take profit on long")
                    time.sleep(
                        5
                    )  # Don't act on volatile spikes and dips, only identify longer trends
                elif item.get_shares() < 0:
                    closePositions(trader, ticker)
                    """
                    coverShort = shift.Order(shift.Order.Type.MARKET_BUY, item.get_symbol(), -numShares)
                    trader.submit_order(coverShort)
                    """
                    print(ticker, "take profit on short")
                    time.sleep(
                        5
                    )  # Don't act on volatile spikes and dips, only identify longer trends

            elif unrealizedPL <= -0.30:  # Stop loss met, sell risk
                #elif unrealizedPL <= -0.50: # Stop loss met, sell risk
                if item.get_shares() > 0:
                    closePositions(trader, ticker)
                    """
                    closeLong = shift.Order(shift.Order.Type.MARKET_SELL, item.get_symbol(), numShares)
                    trader.submit_order(closeLong)
                    """
                    print(ticker, "stop loss on long")
                    time.sleep(
                        5
                    )  # Don't act on volatile spikes and dips, only identify longer trends
                elif item.get_shares() < 0:
                    closePositions(trader, ticker)
                    """
                    coverShort = shift.Order(shift.Order.Type.MARKET_BUY, item.get_symbol(), -numShares)
                    trader.submit_order(coverShort)
                    """
                    print(ticker, "stop loss on short")
                    time.sleep(
                        5
                    )  # Don't act on volatile spikes and dips, only identify longer trends

        rightNow = trader.get_last_trade_time()  # Reset datetime of right now
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)