From 83d1f117a833aaa904dd6529e5d6b9a05bcde5a8 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 17 Jan 2024 09:42:29 -0500 Subject: [PATCH] Always cancel (loaded) zero-priced orders Ran into this trading a peenee where a dark got (mistakenly) submitted at a price of 0 and then that consecutively broke upstream allocator/pp code due to a divide-by-zero.. So instead always check for a zero-price (since that should never ever be valid in any market) and instead cancel any such order in the EMS and return `None` so that upstream callers can ignore it without crash handling. --- piker/ui/order_mode.py | 44 +++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/piker/ui/order_mode.py b/piker/ui/order_mode.py index dd02cde5..ea96e97a 100644 --- a/piker/ui/order_mode.py +++ b/piker/ui/order_mode.py @@ -358,7 +358,7 @@ class OrderMode: send_msg: bool = True, order: Order | None = None, - ) -> Dialog: + ) -> Dialog | None: ''' Send execution order to EMS return a level line to represent the order on a chart. @@ -378,6 +378,16 @@ class OrderMode: 'oid': oid, }) + if order.price <= 0: + log.error( + '*!? Invalid `Order.price <= 0` ?!*\n' + # TODO: make this present multi-line in object form + # like `ib_insync.contracts.Contract.__repr__()` + f'{order}\n' + ) + self.cancel_orders([order.oid]) + return None + lines = self.lines_from_order( order, show_markers=True, @@ -663,7 +673,7 @@ class OrderMode: self, msg: Status, - ) -> Dialog: + ) -> Dialog | None: # NOTE: the `.order` attr **must** be set with the # equivalent order msg in order to be loaded. order = msg.req @@ -694,12 +704,15 @@ class OrderMode: fqsn=fqme, info={}, ) - dialog = self.submit_order( + maybe_dialog: Dialog | None = self.submit_order( send_msg=False, order=order, ) - assert self.dialogs[oid] == dialog - return dialog + if maybe_dialog is None: + return None + + assert self.dialogs[oid] == maybe_dialog + return maybe_dialog @asynccontextmanager @@ -1079,8 +1092,25 @@ async def process_trade_msg( ) ): msg.req = order - dialog = mode.load_unknown_dialog_from_msg(msg) - mode.on_submit(oid) + dialog: ( + Dialog + # NOTE: on an invalid order submission (eg. + # price <=0) the downstream APIs may return + # a null. + | None + ) = mode.load_unknown_dialog_from_msg(msg) + + # cancel any invalid pre-existing order! + if dialog is None: + log.warning( + 'Order was ignored/invalid?\n' + f'{order}' + ) + + # if valid, display the order line the same as if + # it was submitted during this UI session. + else: + mode.on_submit(oid) case Status(resp='error'):