def get_unrealized_pnl(trader: shift.Trader): short_profit = 0 long_profit = 0 for item, value in ziplist(trader.get_portfolio_items().keys(), trader.get_portfolio_items().values()): pnl = trader.get_unrealized_pl(item) #in short if value.get_shares() < 0: short_profit += pnl if value.get_shares() > 0: long_profit += pnl return short_profit, long_profit
def get_unrealized_short_pnl(trader: shift.Trader): total_unrealized_short_pnl = 0 for item, value in trader.get_portfolio_items().items(): if(value.get_shares() < 0): total_unrealized_short_pnl += trader.get_unrealized_pl(item) return total_unrealized_short_pnl
def run_stop_loss_check(trader: shift.Trader, state: Dict[str, Any]) -> None: """ check for stop loss hit """ stop_loss_interval = 5 # seconds acceptable_loss = .2 # percent if stop_loss_key not in state: state[stop_loss_key] = {} while True: sleep(stop_loss_interval) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() current_price = state[prices_key][ticker][-1] new_stop_loss = current_price * ((100 - acceptable_loss) / 100.) has_stop_loss = ticker in state[stop_loss_key] if not has_stop_loss or new_stop_loss > state[stop_loss_key][ ticker]: if has_stop_loss: for order in trader.get_waiting_list(): if order.symbol == ticker and order.type == shift.Order.Type.LIMIT_SELL: trader.submit_cancellation(order) limit_sell = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, item.get_shares()) trader.submit_order(limit_sell) state[stop_loss_key][ticker] = new_stop_loss, limit_sell
def 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
def print_portfolio_information(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(), )) upl = {} for item in list(trader.get_portfolio_items().keys()): upl[item] = trader.get_unrealized_pl(item) print("Symbol\t\tShares\t\tPrice\t\t P&L\t\t Unrealized P&L \nTimestamp") 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("UNREALIZED PNL") print(upl) return
def close_positions(trader: shift.Trader): for item in trader.get_portfolio_items().values(): if item.get_shares() < 0: print(f"Closing short position in {item.get_symbol()}...") market_order(trader, "buy", item.get_symbol(), contract_size=int(abs(item.get_shares()) / 100)) if item.get_shares() > 0: print(f"Closing long position in {item.get_symbol()}...") market_order(trader, "sell", item.get_symbol(), contract_size=int(abs(item.get_shares()) / 100)) time.sleep(0.05) return
def main(trader: shift.Trader) -> None: """ main entrypoint """ trader = shift.Trader(credentials.my_username) try: trader.connect("initiator.cfg", credentials.my_password) trader.sub_all_order_book() except shift.IncorrectPasswordError as e: print(e) except shift.ConnectionTimeoutError as e: print(e) time.sleep(2) check_time = 5 # minutes current = trader.get_last_trade_time() start_time = dt.combine(current, dt.datetime(10, 0, 0)) end_time = dt.combine(current, dt.datetime(15, 30, 0)) while trader.get_last_trade_time() < start_time: sleep(check_time * 60) processes = run_processes(trader) while trader.get_last_trade_time() < end_time: sleep(check_time * 60) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, item.get_shares()) trader.submit_order(sell) time_wait_sell = 60 # seconds sleep(time_wait_sell) stop_processes(processes) # print stuff routine_summary(trader)
def run_stop_loss_check(trader: shift.Trader, state: Dict[str, Any]) -> None: """ check for stop loss hit """ stop_loss_interval = 5 # seconds acceptable_loss = .2 # percent # if stop_loss_key not in stop_losses_state: # stop_losses_state = {} ''' Set original stop loss when originally buying to -.2% Set original target when originally buying to the bollinger band Update target every minute to the most recent bollinger band First time you hit target: remove half position update stop loss to original buy prices and make this a trailing stop Keep updating target Scenario: Buy 100 at 100 Set stop loss to 99.8 and target to 101 We hit 101 so we sell 50 (left with 50) and update stop loss to 100 101 - 100 = stop loss Next minute upper band changes to 102: change target to 102 Next minute upper band changes to 99: sell everything ALREADY HIT TARGET ONCE: We hit 102 so we sell 25 (left with 25) and update stop loss to 101 price goes to 101.50, stop loss is 101 price hits target at 104, stop loss is 103.50 begin position initial_buy_price = ... target = upper_bollinger_band[-1] stop_loss = initial_buy_price*-.002 first target hits stop_loss = (1 - ((first_target_sell - initial_buy_price) / initial_buy_price))*current_price price goes up stop_loss = (1 - ((first_target_sell - initial_buy_price) / initial_buy_price))*current_price second target hits - just half, and reapply trailing stop loss stop_loss = (1 - ((first_target_sell - initial_buy_price) / initial_buy_price))*current_price price goes down stop_loss = stop_loss ''' while True: sleep(stop_loss_interval) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() current_price = state[prices_key][ticker][-1] new_stop_loss = current_price * ((100 - acceptable_loss) / 100.) has_stop_loss = ticker in state[stop_loss_key] if not has_stop_loss or new_stop_loss > state[stop_loss_key][ticker]: if has_stop_loss: for order in trader.get_waiting_list(): if order.symbol == ticker and order.type == shift.Order.Type.LIMIT_SELL: trader.submit_cancellation(order) limit_sell = shift.Order(shift.Order.Type.LIMIT_SELL, ticker, item.get_shares()) trader.submit_order(limit_sell) state[stop_loss_key][ticker] = new_stop_loss, limit_sell
def main(trader: shift.Trader) -> None: """ main entrypoint """ # { # "prices": { # "AAPL": [234] # }, # } manager = Manager() list_of_shared_dicts = manager.list() list_of_shared_dicts.append({}) # prices_state = list_of_shared_dicts[0] # stop_losses_state = list_of_shared_dicts[1] state = list_of_shared_dicts[0] keys_in_state = [prices_key, stop_loss_key, target_key] for key in keys_in_state: state[key] = manager.dict() for ticker in tickers: if key == prices_key: state[key].setdefault(key, []) elif key == target_key: state[key].setdefault(key, [0,0]) # if key == stop_loss_key: # state[trader_key] = trader # trader_obj = state check_time = 1 # minutes current = trader.get_last_trade_time() start_time = datetime.combine(current, dt.time(10,0,0)) end_time = datetime.combine(current, dt.time(15, 30, 0)) print(trader.get_last_trade_time()) pre_processes = [] for ticker in tickers: # 1 thread per ticker getting price data & saving it pre_processes.append(Thread(target=run_save_prices, args=(ticker, trader, state))) # run_save_prices(ticker, trader, state) for process in pre_processes: process.start() print(f"{len(pre_processes)} processes created for run_save_prices") while trader.get_last_trade_time() < start_time: print(f"Waiting for Market Open @ {trader.get_last_trade_time()}") sleep(check_time * 60) processes = pre_processes.extend(run_processes(trader, state)) while trader.get_last_trade_time() < end_time: print(f"Waiting for Market Close @ {trader.get_last_trade_time()}") sleep(check_time * 60) for order in trader.get_waiting_list(): trader.submit_cancellation(order) for item in trader.get_portfolio_items().values(): ticker = item.get_symbol() sell = shift.Order(shift.Order.Type.MARKET_SELL, ticker, item.get_shares()) trader.submit_order(sell) time_wait_sell = 60 # seconds sleep(time_wait_sell) stop_processes(processes) # print stuff routine_summary(trader)
def get_tickers_with_positions(trader: shift.Trader): t = [] for ticker, item in trader.get_portfolio_items().items(): if(item.get_shares() != 0 and len(item.get_symbol()) >= 1): t.append(ticker) return t