Keep clear loop price pedantically up to date

To avoid the "trigger finger" issue (darks execing before they should
due to a stale last price state, normally when generating a trigger
predicate..) always iterate the loop and update the last known book
price even when no execs/triggered orders are registered.
pp_bar_fixes
Tyler Goodlet 2022-02-10 12:48:13 -05:00
parent ca1c1cf415
commit 7b13124dd4
1 changed files with 19 additions and 15 deletions

View File

@ -54,7 +54,8 @@ def mk_check(
action: str, action: str,
) -> Callable[[float, float], bool]: ) -> Callable[[float, float], bool]:
"""Create a predicate for given ``exec_price`` based on last known '''
Create a predicate for given ``exec_price`` based on last known
price, ``known_last``. price, ``known_last``.
This is an automatic alert level thunk generator based on where the This is an automatic alert level thunk generator based on where the
@ -62,7 +63,7 @@ def mk_check(
interest is; pick an appropriate comparison operator based on interest is; pick an appropriate comparison operator based on
avoiding the case where the a predicate returns true immediately. avoiding the case where the a predicate returns true immediately.
""" '''
# str compares: # str compares:
# https://stackoverflow.com/questions/46708708/compare-strings-in-numba-compiled-function # https://stackoverflow.com/questions/46708708/compare-strings-in-numba-compiled-function
@ -139,29 +140,32 @@ async def clear_dark_triggers(
book: _DarkBook, book: _DarkBook,
) -> None: ) -> None:
"""Core dark order trigger loop. '''
Core dark order trigger loop.
Scan the (price) data feed and submit triggered orders Scan the (price) data feed and submit triggered orders
to broker. to broker.
""" '''
# this stream may eventually contain multiple symbols
# XXX: optimize this for speed! # XXX: optimize this for speed!
# TODO:
# - numba all this!
# - this stream may eventually contain multiple symbols
async for quotes in quote_stream: async for quotes in quote_stream:
# TODO: numba all this!
# start = time.time() # start = time.time()
for sym, quote in quotes.items(): for sym, quote in quotes.items():
execs = book.orders.get(sym, {})
execs = book.orders.get(sym, None)
if execs is None:
continue
for tick in iterticks( for tick in iterticks(
quote, quote,
# dark order price filter(s) # dark order price filter(s)
types=('ask', 'bid', 'trade', 'last') types=(
'ask',
'bid',
'trade',
'last',
# 'dark_trade', # TODO: should allow via config?
)
): ):
price = tick.get('price') price = tick.get('price')
ttype = tick['type'] ttype = tick['type']
@ -178,7 +182,6 @@ async def clear_dark_triggers(
) in ( ) in (
tuple(execs.items()) tuple(execs.items())
): ):
if ( if (
not pred or not pred or
ttype not in tf or ttype not in tf or
@ -290,7 +293,8 @@ class TradesRelay:
class Router(BaseModel): class Router(BaseModel):
'''Order router which manages and tracks per-broker dark book, '''
Order router which manages and tracks per-broker dark book,
alerts, clearing and related data feed management. alerts, clearing and related data feed management.
A singleton per ``emsd`` actor. A singleton per ``emsd`` actor.