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.
distribute_dis
Tyler Goodlet 2024-01-17 09:42:29 -05:00
parent e4ce79f720
commit 83d1f117a8
1 changed files with 37 additions and 7 deletions

View File

@ -358,7 +358,7 @@ class OrderMode:
send_msg: bool = True, send_msg: bool = True,
order: Order | None = None, order: Order | None = None,
) -> Dialog: ) -> Dialog | None:
''' '''
Send execution order to EMS return a level line to Send execution order to EMS return a level line to
represent the order on a chart. represent the order on a chart.
@ -378,6 +378,16 @@ class OrderMode:
'oid': oid, '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( lines = self.lines_from_order(
order, order,
show_markers=True, show_markers=True,
@ -663,7 +673,7 @@ class OrderMode:
self, self,
msg: Status, msg: Status,
) -> Dialog: ) -> Dialog | None:
# NOTE: the `.order` attr **must** be set with the # NOTE: the `.order` attr **must** be set with the
# equivalent order msg in order to be loaded. # equivalent order msg in order to be loaded.
order = msg.req order = msg.req
@ -694,12 +704,15 @@ class OrderMode:
fqsn=fqme, fqsn=fqme,
info={}, info={},
) )
dialog = self.submit_order( maybe_dialog: Dialog | None = self.submit_order(
send_msg=False, send_msg=False,
order=order, order=order,
) )
assert self.dialogs[oid] == dialog if maybe_dialog is None:
return dialog return None
assert self.dialogs[oid] == maybe_dialog
return maybe_dialog
@asynccontextmanager @asynccontextmanager
@ -1079,8 +1092,25 @@ async def process_trade_msg(
) )
): ):
msg.req = order msg.req = order
dialog = mode.load_unknown_dialog_from_msg(msg) dialog: (
mode.on_submit(oid) 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'): case Status(resp='error'):