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
parent
ca1c1cf415
commit
7b13124dd4
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue