From d0530c4e26e52f9e30e1184fe30914f9d1630f38 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 11 May 2022 15:39:42 -0400 Subject: [PATCH 1/2] Deliver accounts from query instead of just pps with `ib` --- piker/brokers/ib.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/piker/brokers/ib.py b/piker/brokers/ib.py index 20865e30..87281f31 100644 --- a/piker/brokers/ib.py +++ b/piker/brokers/ib.py @@ -2143,6 +2143,19 @@ async def trades_dialogue( accounts.add(msg.account) all_positions.append(msg.dict()) + # the account has no open positions (pps) so + # we just deliver the accounts def for now? + for value in client.ib.accountValues(): + account = value.account + if account not in accounts_def.inverse: + log.warning( + f'Client {client} defines an unknown account ' + '(not in brokers.toml):\n' + f'{account}' + ) + else: + accounts.add(accounts_def.inverse[account]) + await ctx.started(( all_positions, tuple(name for name in accounts_def if name in accounts), From de55565f6055902f170d295320fcfde0ce526ed4 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Thu, 12 May 2022 13:21:20 -0400 Subject: [PATCH 2/2] We already collect account values/names in `load_io_clients()` --- piker/brokers/ib.py | 48 ++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/piker/brokers/ib.py b/piker/brokers/ib.py index 87281f31..b861d895 100644 --- a/piker/brokers/ib.py +++ b/piker/brokers/ib.py @@ -996,15 +996,22 @@ async def load_aio_clients( accounts_def.inverse[pp.account] ] = client - # if there are no positions or accounts - # without positions we should still register - # them for this client + # if there are accounts without positions we should still + # register them for this client for value in ib.accountValues(): - acct = value.account - if acct not in accounts_found: - accounts_found[ - accounts_def.inverse[acct] - ] = client + acct_number = value.account + + entry = accounts_def.inverse.get(acct_number) + if not entry: + raise ValueError( + 'No section in brokers.toml for account:' + f' {acct_number}\n' + f'Please add entry to continue using this API client' + ) + + # surjection of account names to operating clients. + if acct_number not in accounts_found: + accounts_found[entry] = client log.info( f'Loaded accounts for client @ {host}:{port}\n' @@ -1028,6 +1035,8 @@ async def load_aio_clients( # torn down correctly ... tractor._actor._lifetime_stack.callback(pop_and_discon) + # XXX: why aren't we just updating this directy above + # instead of using the intermediary `accounts_found`? _accounts2clients.update(accounts_found) except ( @@ -2117,6 +2126,7 @@ async def trades_dialogue( clients: list[tuple[Client, trio.MemoryReceiveChannel]] = [] async with trio.open_nursery() as nurse: + for account, client in _accounts2clients.items(): async def open_stream( @@ -2136,25 +2146,19 @@ async def trades_dialogue( clients.append((client, trade_event_stream)) + assert account in accounts_def + accounts.add(account) + for client in _client_cache.values(): for pos in client.positions(): + msg = pack_position(pos) msg.account = accounts_def.inverse[msg.account] - accounts.add(msg.account) - all_positions.append(msg.dict()) - # the account has no open positions (pps) so - # we just deliver the accounts def for now? - for value in client.ib.accountValues(): - account = value.account - if account not in accounts_def.inverse: - log.warning( - f'Client {client} defines an unknown account ' - '(not in brokers.toml):\n' - f'{account}' - ) - else: - accounts.add(accounts_def.inverse[account]) + assert msg.account in accounts, ( + f'Position for unknown account: {msg.account}') + + all_positions.append(msg.dict()) await ctx.started(( all_positions,