def market_maker_one(trader: shift.Trader, ticker: str): tickSize = 0.01 # james code need to change maybe? today = trader.get_last_trade_time() endTime = dt.time(15, 30, 0) dayEnd = dt.datetime.combine(today, dt.datetime(endTime)) rightNow = trader.get_last_trade_time() #right < the end of day at 3:50 while today < dayEnd: ''' check inventory here ''' trader.sub_all_order_book() lastPrice = trader.get_last_price("AAPL") limitBuyPrice = lastPrice - tickSize limitSellPrice = lastPrice + tickSize limit_buy = shift.Order(shift.Order.Type.LIMIT_BUY, "AAPL", 1, limitBuyPrice) limit_sell = shift.Order(shift.Order.Type.LIMIT_SELL, "AAPL", 1, limitSellPrice) # market_buy = shift.Order(shift.Order.Type.MARKET_BUY, "AAPL", 1) # trader.submit_order(market_buy) trader.submit_order(limit_buy) trader.submit_order(limit_sell) time.sleep(10) return
def update_open_interest(trader: shift.Trader, ls, open_interest, order_type): if order_type == "ask": o_i = [trader.get_best_price(sym).get_ask_size() for sym in ls] open_interest.loc[trader.get_last_trade_time(), :] = o_i if order_type == "bid": o_i = [trader.get_best_price(sym).get_bid_size() for sym in ls] open_interest.loc[trader.get_last_trade_time(), :] = o_i return open_interest
def collect_data(trader: shift.Trader, ticker: str): today = trader.get_last_trade_time() print(today) endTime = dt.time(9, 35, 0) end_of_data_collection_period = dt.datetime.combine(today, endTime) prices = [] while (trader.get_last_trade_time() < end_of_data_collection_period): prices.append(trader.get_last_price(ticker)) print(trader.get_last_trade_time()) time.sleep(5) return {"prices": prices, **calculate_statistics(prices)}
def longer(trader: shift.Trader, tickers): today = trader.get_last_trade_time() endTime = dt.time(15, 50, 0) dayEnd = dt.datetime.combine(today, endTime) tickSize = 0.01 bp = (trader.get_portfolio_summary().get_total_bp()) dpa = bp / float(len(tickers)) for t in tickers: lastPrice = trader.get_last_price(t) while lastPrice == 0: lastPrice = trader.get_last_price(t) s = int((dpa / lastPrice) / 100) for i in range(0, s): # limitBuyPrice = lastPrice - tickSize limit_sell = shift.Order(shift.Order.Type.MARKET_BUY, t, 1) trader.submit_order(limit_sell) while trader.get_last_trade_time() < dayEnd: time.sleep(1) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for t in tickers: print(t) lastPrice = trader.get_last_price(t) item = trader.get_portfolio_item(t) if item.get_shares() > 0: sell = shift.Order( shift.Order.Type.MARKET_SELL, t, int(item.get_shares() / 100)) # Order size in 100's of shares, strictly as an int trader.submit_order(sell) elif item.get_shares() < 0: buy = shift.Order( shift.Order.Type.MARKET_BUY, t, int(-1 * item.get_shares() / 100)) # Order size in 100's of shares, strictly as an int trader.submit_order(buy) print(f'submitted buy for {t}') time.sleep(15) utils.print_portfolio_information(trader) utils.print_all_submitted_order(trader) print(trader.get_last_trade_time()) return
def 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
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
def build_candles(ticker: str, trader: shift.Trader, state: Dict[str, Any], end_time): queue_size = 30 while trader.get_last_trade_time() < end_time: s = 0 price = trader.get_last_price(ticker) candle = Candle(price, price, price, price) while s < candle_size: price = trader.get_last_price(ticker) if price < candle.low: candle.setLow(price) if price > candle.high: candle.setHigh(price) sleep(1) s += 1 price = trader.get_last_price(ticker) candle.setClose(price) try: state[candles_key][ticker] += [candle] except KeyError: state[candles_key][ticker] = deque(maxlen=queue_size) sleep(0.5) state[candles_key][ticker] += [candle]
def main(trader: shift.Trader) -> None: """ main entrypoint """ trader = shift.Trader(credentials.my_username) try: trader.connect("initiator.cfg", credentials.my_password) trader.sub_all_order_book() except shift.IncorrectPasswordError as e: print(e) except shift.ConnectionTimeoutError as e: print(e) time.sleep(2) check_time = 5 # minutes current = trader.get_last_trade_time() start_time = dt.combine(current, dt.datetime(10, 0, 0)) end_time = dt.combine(current, dt.datetime(15, 30, 0)) while trader.get_last_trade_time() < start_time: sleep(check_time * 60) processes = run_processes(trader) while trader.get_last_trade_time() < end_time: sleep(check_time * 60) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, item.get_shares()) trader.submit_order(sell) time_wait_sell = 60 # seconds sleep(time_wait_sell) stop_processes(processes) # print stuff routine_summary(trader)
def trafficLight(trader: shift.Trader, dayStart, wait): rightNow = trader.get_last_trade_time() if dayStart > rightNow: print("Wait till market open") time.sleep(wait) print(rightNow) trafficLight(trader, dayStart, wait) else: print("Begin Trading") return
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 routine_summary(trader: shift.Trader, end_time): # today = trader.get_last_trade_time() # endTime = dt.time(9, 50, 0) # dayEnd = dt.datetime.combine(today, endTime) # rightNow = trader.get_last_trade_time() while trader.get_last_trade_time() < end_time: print(f"----------{trader.get_last_trade_time()}-------------") utils.print_all_submitted_order(trader) utils.print_portfolio_information(trader) # print("-----–ASK–-----") # utils.print_ask_order_book(trader) # print("------BID–-----") # utils.print_bid_order_book(trader) ct = dt.datetime.now() print("current time:-", ct) time.sleep(3) return 0
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 main(trader: shift.Trader) -> None: """ main entrypoint """ # { # "prices": { # "AAPL": [234] # }, # } manager = Manager() list_of_shared_dicts = manager.list() list_of_shared_dicts.append({}) # prices_state = list_of_shared_dicts[0] # stop_losses_state = list_of_shared_dicts[1] state = list_of_shared_dicts[0] keys_in_state = [prices_key, stop_loss_key, target_key] for key in keys_in_state: state[key] = manager.dict() for ticker in tickers: if key == prices_key: state[key].setdefault(key, []) elif key == target_key: state[key].setdefault(key, [0,0]) # if key == stop_loss_key: # state[trader_key] = trader # trader_obj = state check_time = 1 # minutes current = trader.get_last_trade_time() start_time = datetime.combine(current, dt.time(10,0,0)) end_time = datetime.combine(current, dt.time(15, 30, 0)) print(trader.get_last_trade_time()) pre_processes = [] for ticker in tickers: # 1 thread per ticker getting price data & saving it pre_processes.append(Thread(target=run_save_prices, args=(ticker, trader, state))) # run_save_prices(ticker, trader, state) for process in pre_processes: process.start() print(f"{len(pre_processes)} processes created for run_save_prices") while trader.get_last_trade_time() < start_time: print(f"Waiting for Market Open @ {trader.get_last_trade_time()}") sleep(check_time * 60) processes = pre_processes.extend(run_processes(trader, state)) while trader.get_last_trade_time() < end_time: print(f"Waiting for Market Close @ {trader.get_last_trade_time()}") sleep(check_time * 60) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, item.get_shares()) trader.submit_order(sell) time_wait_sell = 60 # seconds sleep(time_wait_sell) stop_processes(processes) # print stuff routine_summary(trader)
def 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 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