diff --git a/mango/marketmaking/orderchain/preventpostonlycrossingbookelement.py b/mango/marketmaking/orderchain/preventpostonlycrossingbookelement.py index 3c61317..56d05d3 100644 --- a/mango/marketmaking/orderchain/preventpostonlycrossingbookelement.py +++ b/mango/marketmaking/orderchain/preventpostonlycrossingbookelement.py @@ -40,20 +40,20 @@ class PreventPostOnlyCrossingBookElement(Element): new_orders: typing.List[mango.Order] = [] for order in orders: if order.order_type == mango.OrderType.POST_ONLY: - top_bid: typing.Optional[mango.Order] = model_state.top_bid - top_ask: typing.Optional[mango.Order] = model_state.top_ask - if order.side == mango.Side.BUY and top_bid is not None and top_ask is not None and order.price >= top_ask.price: - new_buy_price: Decimal = top_ask.price - model_state.market.lot_size_converter.tick_size + top_bid: typing.Optional[Decimal] = model_state.top_bid.price if model_state.top_bid is not None else None + top_ask: typing.Optional[Decimal] = model_state.top_ask.price if model_state.top_ask is not None else None + if order.side == mango.Side.BUY and top_ask is not None and order.price >= top_ask: + new_buy_price: Decimal = top_ask - model_state.market.lot_size_converter.tick_size new_buy: mango.Order = order.with_price(new_buy_price) - self.logger.debug(f"""Order change - would cross the orderbook {top_bid.price} / {top_ask.price}: + self.logger.debug(f"""Order change - would cross the orderbook {top_bid} / {top_ask}: Old: {order} New: {new_buy}""") new_orders += [new_buy] - elif order.side == mango.Side.SELL and top_bid is not None and top_ask is not None and order.price <= top_bid.price: - new_sell_price: Decimal = top_bid.price + model_state.market.lot_size_converter.tick_size + elif order.side == mango.Side.SELL and top_bid is not None and order.price <= top_bid: + new_sell_price: Decimal = top_bid + model_state.market.lot_size_converter.tick_size new_sell: mango.Order = order.with_price(new_sell_price) self.logger.debug( - f"""Order change - would cross the orderbook {top_bid.price} / {top_ask.price}: + f"""Order change - would cross the orderbook {top_bid} / {top_ask}: Old: {order} New: {new_sell}""") diff --git a/tests/marketmaking/orderchain/test_preventpostonlycrossingbookelement.py b/tests/marketmaking/orderchain/test_preventpostonlycrossingbookelement.py index d6cd57b..b57e391 100644 --- a/tests/marketmaking/orderchain/test_preventpostonlycrossingbookelement.py +++ b/tests/marketmaking/orderchain/test_preventpostonlycrossingbookelement.py @@ -69,3 +69,52 @@ def test_ask_too_high_results_in_no_change(): result = actual.process(context, model_state, [order]) assert result == [order] + + +def test_bid_too_high_no_bid_results_in_new_bid(): + args: argparse.Namespace = argparse.Namespace() + context = fake_context() + order: mango.Order = fake_order(price=Decimal(120), side=mango.Side.BUY, order_type=mango.OrderType.POST_ONLY) + + actual: PreventPostOnlyCrossingBookElement = PreventPostOnlyCrossingBookElement(args) + model_state = fake_model_state(market=fake_loaded_market(), bids=[], asks=[top_ask]) + + result = actual.process(context, model_state, [order]) + + assert result[0].price == 109 + + +def test_ask_too_low_no_ask_results_in_new_ask(): + args: argparse.Namespace = argparse.Namespace() + context = fake_context() + order: mango.Order = fake_order(price=Decimal(80), side=mango.Side.SELL, order_type=mango.OrderType.POST_ONLY) + + actual: PreventPostOnlyCrossingBookElement = PreventPostOnlyCrossingBookElement(args) + model_state = fake_model_state(market=fake_loaded_market(), bids=[top_bid], asks=[]) + result = actual.process(context, model_state, [order]) + + assert result[0].price == 91 + + +def test_ask_no_orderbook_results_in_no_change(): + args: argparse.Namespace = argparse.Namespace() + context = fake_context() + order: mango.Order = fake_order(price=Decimal(120), side=mango.Side.SELL, order_type=mango.OrderType.POST_ONLY) + + actual: PreventPostOnlyCrossingBookElement = PreventPostOnlyCrossingBookElement(args) + model_state = fake_model_state(market=fake_loaded_market(), bids=[], asks=[]) + result = actual.process(context, model_state, [order]) + + assert result == [order] + + +def test_bid_no_orderbook_results_in_no_change(): + args: argparse.Namespace = argparse.Namespace() + context = fake_context() + order: mango.Order = fake_order(price=Decimal(80), side=mango.Side.BUY, order_type=mango.OrderType.POST_ONLY) + + actual: PreventPostOnlyCrossingBookElement = PreventPostOnlyCrossingBookElement(args) + model_state = fake_model_state(market=fake_loaded_market(), bids=[], asks=[]) + result = actual.process(context, model_state, [order]) + + assert result == [order]