Nest nursery scope inside EMS ctx in order mode
Move the `trio.open_nursery()` + `collapse_eg()`
block to be nested inside `open_ems()` instead
of as a sibling — nursery tasks (order handling,
trade processing) depend on the EMS connection
staying alive.
Also,
- Default `'paper'` entry upfront in `accounts`
dict and raise `ConfigurationError` with an
actionable msg when a `brokerd_accounts` fqan
isn't found in `accounts_def`.
- Use `msg.setdefault('brokerd_msg', msg)` for
ems dialog msgs instead of blind assignment;
warn if already set.
- Alias `asynccontextmanager as acm`.
- Use `fqan` var naming for fully-qualified
account names, `broker_name` from `mkt.broker`.
- Tighten log msg formatting (`fqme!r`).
(this commit msg was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
nested_order_mode_block
parent
5387538ba9
commit
e05c258914
|
|
@ -19,7 +19,7 @@ Chart trading, the only way to scalp.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager as acm
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
@ -779,7 +779,7 @@ class OrderMode:
|
||||||
return maybe_dialog
|
return maybe_dialog
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@acm
|
||||||
async def open_order_mode(
|
async def open_order_mode(
|
||||||
feed: Feed,
|
feed: Feed,
|
||||||
godw: GodWidget,
|
godw: GodWidget,
|
||||||
|
|
@ -814,6 +814,7 @@ async def open_order_mode(
|
||||||
|
|
||||||
# spawn EMS actor-service
|
# spawn EMS actor-service
|
||||||
async with (
|
async with (
|
||||||
|
# tractor.trionics.collapse_eg(),
|
||||||
open_ems(
|
open_ems(
|
||||||
fqme,
|
fqme,
|
||||||
loglevel=loglevel,
|
loglevel=loglevel,
|
||||||
|
|
@ -824,11 +825,10 @@ async def open_order_mode(
|
||||||
brokerd_accounts,
|
brokerd_accounts,
|
||||||
ems_dialog_msgs,
|
ems_dialog_msgs,
|
||||||
),
|
),
|
||||||
tractor.trionics.collapse_eg(),
|
|
||||||
trio.open_nursery() as tn,
|
|
||||||
|
|
||||||
):
|
):
|
||||||
log.info(f'Opening order mode for {fqme}')
|
log.info(
|
||||||
|
f'Opening order-mode for {fqme!r}'
|
||||||
|
)
|
||||||
|
|
||||||
# annotations editors
|
# annotations editors
|
||||||
lines = LineEditor(godw=godw)
|
lines = LineEditor(godw=godw)
|
||||||
|
|
@ -841,21 +841,34 @@ async def open_order_mode(
|
||||||
trackers: dict[str, PositionTracker] = {}
|
trackers: dict[str, PositionTracker] = {}
|
||||||
|
|
||||||
# load account names from ``brokers.toml``
|
# load account names from ``brokers.toml``
|
||||||
|
broker_name: str = mkt.broker
|
||||||
accounts_def: bidict[str, str | None] = config.load_accounts(
|
accounts_def: bidict[str, str | None] = config.load_accounts(
|
||||||
providers=[mkt.broker],
|
providers=[broker_name],
|
||||||
)
|
)
|
||||||
|
|
||||||
# XXX: ``brokerd`` delivers a set of account names that it
|
# XXX: ``brokerd`` delivers a set of account names that it
|
||||||
# allows use of but the user also can define the accounts they'd
|
# allows use of but the user also can define the accounts they'd
|
||||||
# like to use, in order, in their `brokers.toml` file.
|
# like to use, in order, in their `brokers.toml` file.
|
||||||
accounts: dict[str, str] = {}
|
accounts: dict[str, str] = {
|
||||||
for name in brokerd_accounts:
|
'paper': 'paper',
|
||||||
# ensure name is in ``brokers.toml``
|
}
|
||||||
accounts[name] = accounts_def[name]
|
fqan: str # ex. 'kraken.spot'
|
||||||
|
for fqan in brokerd_accounts:
|
||||||
|
# ensure fully-qualified-account-name declared in `brokers.toml`
|
||||||
|
|
||||||
# always add a paper entry so that paper cleared
|
try:
|
||||||
|
accounts[fqan] = accounts_def[fqan]
|
||||||
|
except KeyError as ke:
|
||||||
|
raise config.ConfigurationError(
|
||||||
|
f'The {broker_name!r} account {fqan!r} could not be found?\n'
|
||||||
|
f'\n'
|
||||||
|
f'Did you forget to define the correct account name in your `brokers.toml`?\n'
|
||||||
|
f'{ppfmt(accounts_def)}\n'
|
||||||
|
) from ke
|
||||||
|
|
||||||
|
# NOTE, always add a paper entry so that paper cleared
|
||||||
# order dialogs can be tracked in the order mode UIs.
|
# order dialogs can be tracked in the order mode UIs.
|
||||||
accounts['paper'] = 'paper'
|
# accounts['paper'] = 'paper'
|
||||||
|
|
||||||
# first account listed is the one we select at startup
|
# first account listed is the one we select at startup
|
||||||
# (aka order based selection).
|
# (aka order based selection).
|
||||||
|
|
@ -940,6 +953,10 @@ async def open_order_mode(
|
||||||
for name, tracker in trackers.items():
|
for name, tracker in trackers.items():
|
||||||
order_pane.update_account_icons({name: tracker.live_pp})
|
order_pane.update_account_icons({name: tracker.live_pp})
|
||||||
|
|
||||||
|
async with (
|
||||||
|
tractor.trionics.collapse_eg(),
|
||||||
|
trio.open_nursery() as tn,
|
||||||
|
):
|
||||||
# top level abstraction which wraps all this crazyness into
|
# top level abstraction which wraps all this crazyness into
|
||||||
# a namespace..
|
# a namespace..
|
||||||
mode = OrderMode(
|
mode = OrderMode(
|
||||||
|
|
@ -1028,7 +1045,17 @@ async def open_order_mode(
|
||||||
# parse into proper ``Status`` equivalents ems-side?
|
# parse into proper ``Status`` equivalents ems-side?
|
||||||
# msg.setdefault('resp', msg['broker_details']['resp'])
|
# msg.setdefault('resp', msg['broker_details']['resp'])
|
||||||
# msg.setdefault('oid', msg['broker_details']['oid'])
|
# msg.setdefault('oid', msg['broker_details']['oid'])
|
||||||
msg['brokerd_msg'] = msg
|
ya_msg: dict = msg.setdefault(
|
||||||
|
'brokerd_msg',
|
||||||
|
msg,
|
||||||
|
)
|
||||||
|
if msg is not ya_msg:
|
||||||
|
log.warning(
|
||||||
|
f'A `.brokerd_msg` was already set for ems-dialog msg?\n'
|
||||||
|
f'oid: {oid!r}\n'
|
||||||
|
f'ya_msg: {ya_msg!r}\n'
|
||||||
|
f'msg: {ya_msg!r}\n'
|
||||||
|
)
|
||||||
|
|
||||||
await process_trade_msg(
|
await process_trade_msg(
|
||||||
mode,
|
mode,
|
||||||
|
|
@ -1281,7 +1308,8 @@ async def process_trade_msg(
|
||||||
# that should never happen tho?
|
# that should never happen tho?
|
||||||
action: str = (
|
action: str = (
|
||||||
getattr(order, 'action', None)
|
getattr(order, 'action', None)
|
||||||
or order['action']
|
or
|
||||||
|
order['action']
|
||||||
)
|
)
|
||||||
details: dict = msg.brokerd_msg
|
details: dict = msg.brokerd_msg
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue