From a96099511d6d1fef4241a3c1d6375dea3b95d041 Mon Sep 17 00:00:00 2001 From: Geoff Taylor Date: Fri, 14 Jan 2022 17:44:07 +0000 Subject: [PATCH] Added an AlwaysReplaceOrderReconciler. --- bin/marketmaker | 8 ++++++-- mango/marketmaking/__init__.py | 1 + mango/marketmaking/orderreconciler.py | 18 ++++++++++++++++ tests/marketmaking/test_orderreconciler.py | 24 +++++++++++++++++++++- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/bin/marketmaker b/bin/marketmaker index bb6b0c6..bec152b 100755 --- a/bin/marketmaker +++ b/bin/marketmaker @@ -131,8 +131,12 @@ if args.hedging_market is not None: args.hedging_max_chunk_quantity, target_balance, args.hedging_action_threshold) -order_reconciler = mango.marketmaking.ToleranceOrderReconciler( - args.existing_order_tolerance, args.existing_order_tolerance) +order_reconciler: mango.marketmaking.OrderReconciler +if args.existing_order_tolerance < 0: + order_reconciler = mango.marketmaking.AlwaysReplaceOrderReconciler() +else: + order_reconciler = mango.marketmaking.ToleranceOrderReconciler( + args.existing_order_tolerance, args.existing_order_tolerance) desired_orders_chain: chain.Chain = chainbuilder.ChainBuilder.from_command_line_parameters(args) logging.info(f"Desired orders chain: {desired_orders_chain}") diff --git a/mango/marketmaking/__init__.py b/mango/marketmaking/__init__.py index c5084ab..038bd29 100644 --- a/mango/marketmaking/__init__.py +++ b/mango/marketmaking/__init__.py @@ -16,6 +16,7 @@ from .modelstatebuilder import SpotPollingModelStateBuilder as SpotPollingModelS from .modelstatebuilder import WebsocketModelStateBuilder as WebsocketModelStateBuilder from .modelstatebuilderfactory import ModelUpdateMode as ModelUpdateMode from .modelstatebuilderfactory import model_state_builder_factory as model_state_builder_factory +from .orderreconciler import AlwaysReplaceOrderReconciler as AlwaysReplaceOrderReconciler from .orderreconciler import NullOrderReconciler as NullOrderReconciler from .orderreconciler import OrderReconciler as OrderReconciler from .reconciledorders import ReconciledOrders as ReconciledOrders diff --git a/mango/marketmaking/orderreconciler.py b/mango/marketmaking/orderreconciler.py index 802aea2..a05272e 100644 --- a/mango/marketmaking/orderreconciler.py +++ b/mango/marketmaking/orderreconciler.py @@ -58,3 +58,21 @@ class NullOrderReconciler(OrderReconciler): def __str__(self) -> str: return """« NullOrderReconciler »""" + + +# # 🥭 AlwaysReplaceOrderReconciler class +# +# Implementation of OrderReconciler that never keeps orders, just always cancels and replaces. +# +class AlwaysReplaceOrderReconciler(OrderReconciler): + def __init__(self) -> None: + super().__init__() + + def reconcile(self, _: ModelState, existing_orders: typing.Sequence[mango.Order], desired_orders: typing.Sequence[mango.Order]) -> ReconciledOrders: + outcomes: ReconciledOrders = ReconciledOrders() + outcomes.to_cancel = list(existing_orders) + outcomes.to_place = list(desired_orders) + return outcomes + + def __str__(self) -> str: + return """« AlwaysReplaceOrderReconciler »""" diff --git a/tests/marketmaking/test_orderreconciler.py b/tests/marketmaking/test_orderreconciler.py index 3755653..3a92371 100644 --- a/tests/marketmaking/test_orderreconciler.py +++ b/tests/marketmaking/test_orderreconciler.py @@ -2,7 +2,7 @@ import mango from decimal import Decimal -from mango.marketmaking.orderreconciler import NullOrderReconciler +from mango.marketmaking.orderreconciler import NullOrderReconciler, AlwaysReplaceOrderReconciler from ..fakes import fake_model_state @@ -23,3 +23,25 @@ def test_nulloperation() -> None: assert result.to_keep == existing assert result.to_ignore == desired + assert result.to_cancel == [] + assert result.to_place == [] + + +def test_alwaysreplace() -> None: + existing = [ + mango.Order.from_basic_info(mango.Side.BUY, price=Decimal(1), quantity=Decimal(10)), + mango.Order.from_basic_info(mango.Side.SELL, price=Decimal(2), quantity=Decimal(20)) + ] + desired = [ + mango.Order.from_basic_info(mango.Side.BUY, price=Decimal(3), quantity=Decimal(30)), + mango.Order.from_basic_info(mango.Side.SELL, price=Decimal(4), quantity=Decimal(40)) + ] + + model_state = fake_model_state() + actual = AlwaysReplaceOrderReconciler() + result = actual.reconcile(model_state, existing, desired) + + assert result.to_keep == [] + assert result.to_ignore == [] + assert result.to_cancel == existing + assert result.to_place == desired