Fixed bug where PreventPostOnlyCrossingBookElement wouldn't change orders if there wasn't both a top bid and a top ask.

This commit is contained in:
Geoff Taylor 2021-09-29 18:03:25 +01:00
parent 9d030f1af7
commit 66e137e726
2 changed files with 57 additions and 8 deletions

View File

@ -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}""")

View File

@ -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]