Factor order request processing into new func
parent
e71bcb363c
commit
5deea50963
|
@ -448,72 +448,16 @@ async def process_broker_trades(
|
||||||
await ctx.send_yield(resp)
|
await ctx.send_yield(resp)
|
||||||
|
|
||||||
|
|
||||||
@tractor.stream
|
async def process_order_cmds(
|
||||||
async def _emsd_main(
|
|
||||||
ctx: tractor.Context,
|
ctx: tractor.Context,
|
||||||
client_actor_name: str,
|
cmd_stream: 'tractor.ReceiveStream', # noqa
|
||||||
broker: str,
|
|
||||||
symbol: str,
|
symbol: str,
|
||||||
_mode: str = 'dark', # ('paper', 'dark', 'live')
|
feed: 'Feed', # noqa
|
||||||
|
client: 'Client', # noqa
|
||||||
|
dark_book: _DarkBook,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""EMS (sub)actor entrypoint providing the
|
|
||||||
execution management (micro)service which conducts broker
|
|
||||||
order control on behalf of clients.
|
|
||||||
|
|
||||||
This is the daemon (child) side routine which starts an EMS runtime
|
async for cmd in cmd_stream:
|
||||||
(one per broker-feed) and and begins streaming back alerts from
|
|
||||||
broker executions/fills.
|
|
||||||
|
|
||||||
``send_order_cmds()`` is called here to execute in a task back in
|
|
||||||
the actor which started this service (spawned this actor), presuming
|
|
||||||
capabilities allow it, such that requests for EMS executions are
|
|
||||||
received in a stream from that client actor and then responses are
|
|
||||||
streamed back up to the original calling task in the same client.
|
|
||||||
|
|
||||||
The task tree is:
|
|
||||||
- ``_emsd_main()``:
|
|
||||||
accepts order cmds, registers execs with exec loop
|
|
||||||
|
|
||||||
- ``exec_loop()``:
|
|
||||||
run (dark) conditions on inputs and trigger broker submissions
|
|
||||||
|
|
||||||
- ``process_broker_trades()``:
|
|
||||||
accept normalized trades responses, process and relay to ems client(s)
|
|
||||||
|
|
||||||
"""
|
|
||||||
from ._client import send_order_cmds
|
|
||||||
|
|
||||||
dark_book = get_dark_book(broker)
|
|
||||||
|
|
||||||
# get a portal back to the client
|
|
||||||
async with tractor.wait_for_actor(client_actor_name) as portal:
|
|
||||||
|
|
||||||
# spawn one task per broker feed
|
|
||||||
async with trio.open_nursery() as n:
|
|
||||||
|
|
||||||
# TODO: eventually support N-brokers
|
|
||||||
|
|
||||||
# start the condition scan loop
|
|
||||||
quote, feed, client = await n.start(
|
|
||||||
exec_loop,
|
|
||||||
ctx,
|
|
||||||
broker,
|
|
||||||
symbol,
|
|
||||||
_mode,
|
|
||||||
)
|
|
||||||
|
|
||||||
await n.start(
|
|
||||||
process_broker_trades,
|
|
||||||
ctx,
|
|
||||||
feed,
|
|
||||||
dark_book,
|
|
||||||
)
|
|
||||||
|
|
||||||
# connect back to the calling actor (the one that is
|
|
||||||
# acting as an EMS client and will submit orders) to
|
|
||||||
# receive requests pushed over a tractor stream
|
|
||||||
# using (for now) an async generator.
|
|
||||||
async for cmd in await portal.run(send_order_cmds):
|
|
||||||
|
|
||||||
log.info(f'Received order cmd:\n{pformat(cmd)}')
|
log.info(f'Received order cmd:\n{pformat(cmd)}')
|
||||||
|
|
||||||
|
@ -549,7 +493,7 @@ async def _emsd_main(
|
||||||
trigger_price = cmd['price']
|
trigger_price = cmd['price']
|
||||||
size = cmd['size']
|
size = cmd['size']
|
||||||
brokers = cmd['brokers']
|
brokers = cmd['brokers']
|
||||||
exec_mode = cmd.get('exec_mode', _mode)
|
exec_mode = cmd['exec_mode']
|
||||||
|
|
||||||
broker = brokers[0]
|
broker = brokers[0]
|
||||||
last = dark_book.lasts[(broker, sym)]
|
last = dark_book.lasts[(broker, sym)]
|
||||||
|
@ -642,4 +586,80 @@ async def _emsd_main(
|
||||||
'oid': oid
|
'oid': oid
|
||||||
})
|
})
|
||||||
|
|
||||||
# continue and wait on next order cmd
|
|
||||||
|
@tractor.stream
|
||||||
|
async def _emsd_main(
|
||||||
|
ctx: tractor.Context,
|
||||||
|
client_actor_name: str,
|
||||||
|
broker: str,
|
||||||
|
symbol: str,
|
||||||
|
_mode: str = 'dark', # ('paper', 'dark', 'live')
|
||||||
|
) -> None:
|
||||||
|
"""EMS (sub)actor entrypoint providing the
|
||||||
|
execution management (micro)service which conducts broker
|
||||||
|
order control on behalf of clients.
|
||||||
|
|
||||||
|
This is the daemon (child) side routine which starts an EMS runtime
|
||||||
|
(one per broker-feed) and and begins streaming back alerts from
|
||||||
|
broker executions/fills.
|
||||||
|
|
||||||
|
``send_order_cmds()`` is called here to execute in a task back in
|
||||||
|
the actor which started this service (spawned this actor), presuming
|
||||||
|
capabilities allow it, such that requests for EMS executions are
|
||||||
|
received in a stream from that client actor and then responses are
|
||||||
|
streamed back up to the original calling task in the same client.
|
||||||
|
|
||||||
|
The task tree is:
|
||||||
|
- ``_emsd_main()``:
|
||||||
|
accepts order cmds, registers execs with exec loop
|
||||||
|
|
||||||
|
- ``exec_loop()``:
|
||||||
|
run (dark) conditions on inputs and trigger broker submissions
|
||||||
|
|
||||||
|
- ``process_broker_trades()``:
|
||||||
|
accept normalized trades responses, process and relay to ems client(s)
|
||||||
|
|
||||||
|
"""
|
||||||
|
from ._client import send_order_cmds
|
||||||
|
|
||||||
|
dark_book = get_dark_book(broker)
|
||||||
|
|
||||||
|
# get a portal back to the client
|
||||||
|
async with tractor.wait_for_actor(client_actor_name) as portal:
|
||||||
|
|
||||||
|
# spawn one task per broker feed
|
||||||
|
async with trio.open_nursery() as n:
|
||||||
|
|
||||||
|
# TODO: eventually support N-brokers
|
||||||
|
|
||||||
|
# start the condition scan loop
|
||||||
|
quote, feed, client = await n.start(
|
||||||
|
exec_loop,
|
||||||
|
ctx,
|
||||||
|
broker,
|
||||||
|
symbol,
|
||||||
|
_mode,
|
||||||
|
)
|
||||||
|
|
||||||
|
await n.start(
|
||||||
|
process_broker_trades,
|
||||||
|
ctx,
|
||||||
|
feed,
|
||||||
|
dark_book,
|
||||||
|
)
|
||||||
|
|
||||||
|
# connect back to the calling actor (the one that is
|
||||||
|
# acting as an EMS client and will submit orders) to
|
||||||
|
# receive requests pushed over a tractor stream
|
||||||
|
# using (for now) an async generator.
|
||||||
|
order_stream = await portal.run(send_order_cmds)
|
||||||
|
|
||||||
|
# start inbound order request processing
|
||||||
|
await process_order_cmds(
|
||||||
|
ctx,
|
||||||
|
order_stream,
|
||||||
|
symbol,
|
||||||
|
feed,
|
||||||
|
client,
|
||||||
|
dark_book,
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue