def exit_price_test_func(book, pandl, broker): config = MMParams({ "min_levels": "5", "liq_behind_exit": "0.02", "liq_behind_entry": {"BID": "0.41", "ASK": "0.41"}, "order_sizes": {"BID": "0.07", "ASK": "0.07"}, "min_profit": "0.01", "min_order_size": "0.01", "buried_volume": "1", "taker_exit_profit": "0.1", "price_tolerance": "0.0005" }) start_position = Position(pandl.position(), pandl.balance()) print("before " + str(start_position)) exit_order = remove_exit_price_strategy(book, start_position, config) pandl.execution(exit_order.side(), exit_order.abs_position(), exit_order.price()) broker.request(0, exit_order.side(), exit_order.price(), exit_order.abs_position()) keys = broker.om.by_oid.keys() tmp = '' for x in keys: tmp = x broker.om.on_ack(Ack(tmp, 1, start_position.abs_position(), start_position.abs_position())) print_book_and_orders(book, broker) print("after " + str(exit_order)) assert pandl.closed_pnl > 0 return exit_order
def hedge_workflow(prior_pos: Position, target_price, enter_price): # define current state pandl.execution(prior_pos.side(), prior_pos.abs_position(), prior_pos.price()) exit_order = remove_exit_price_strategy(book, prior_pos, None) #place exit order broker.request(0, exit_order.side(), exit_order.price(), exit_order.abs_position()) # calc hedge order hedge_pos = hedge_position(prior_pos, target_price, enter_price) #place hedge order broker.request(1, hedge_pos.side(), hedge_pos.price(), hedge_pos.abs_position()) # exec hedge order pandl.execution(hedge_pos.side(), hedge_pos.abs_position(), hedge_pos.price()) # look at new exit exit_order = remove_exit_price_strategy( book, Position(pandl.pos(), pandl.balance()), None)
class PNL: def __init__(self, fee): self.method = BipolarContainer('NONE', 'NONE') self.pos = Position(0, 0) self.nbbo = BipolarContainer(0, 0) self.closed_pnl = Decimal('0') self.clean_closed_pnl = Decimal('0') self.exit_price = Decimal('0') self.fee = Decimal(fee) self.ema = EMAHolder(5 * 60) self.zero_position_time = time.time() def execution(self, tx: Exec): exec_pos = Position(pos=tx.delta, price=tx.price, side=tx.side) if tx.delta > 0: self.pos += exec_pos + exec_pos.fee_pos(tx.fee) if self.pos.position() == 0: self.closed_pnl += self.pos.balance self.pos = Position(0, 0) self.zero_position_time = time.time() # self.clean_closed_pnl += self.closed_pnl # self.closed_pnl = 0 def position(self): return self.pos.position() def abs_position(self): return self.pos.abs_position() def quote_changed(self, quote): self.nbbo.set_side(quote.side, quote.price) if self.nbbo.bid() == 0 or self.nbbo.ask() == 0: return mid_price = (self.nbbo.bid() + self.nbbo.ask()) / 2 self.ema.add(mid_price) def balance(self): return self.pos.balance def open_pnl(self): return self.balance() + self.position() * self.exit_price def update_open_pnl(self, exit_price): self.exit_price = exit_price def nbbo_pnl(self): exit_side = Side.opposite_side(self.position()) nbbo_price = self.nbbo.side(exit_side) return (self.pos + Position(pos=self.pos.abs_position(), price=nbbo_price, side=exit_side)).balance def take_pnl(self): if self.pos.position() == 0: return Decimal('0') exit_side = Side.opposite_side(self.position()) take_price = self.nbbo.side(Side.side(self.position())) take_order = Position(pos=self.pos.abs_position(), price=take_price, side=exit_side) take_pos = self.pos + take_order + take_order.fee_pos(self.fee) return take_pos.balance def position_zero_price(self): if self.abs_position() == 0: return Decimal('0') else: return abs(self.balance() / self.abs_position()) def position_side(self): return Side.side(self.position()) def set_order_method(self, side, method): self.method.set_side(side, method) def exit_method(self): return str(self.method)
def bound_pos_to_lower_quote(quote: Level, pos: Position, tick_size): lower_quote_price = bound_price_to_lower_quote(quote, pos.price(), tick_size) return Position(side=pos.side(), price=lower_quote_price, pos=pos.abs_position())