diff --git a/piker/_daemon.py b/piker/_daemon.py index 999b8fce..e732a15d 100644 --- a/piker/_daemon.py +++ b/piker/_daemon.py @@ -426,9 +426,19 @@ async def spawn_brokerd( # ask `pikerd` to spawn a new sub-actor and manage it under its # actor nursery + modpath = brokermod.__name__ + broker_enable = [modpath] + for submodname in getattr( + brokermod, + '__enable_modules__', + [], + ): + subpath = f'{modpath}.{submodname}' + broker_enable.append(subpath) + portal = await _services.actor_n.start_actor( dname, - enable_modules=_data_mods + [brokermod.__name__], + enable_modules=_data_mods + broker_enable, loglevel=loglevel, debug_mode=_services.debug_mode, **tractor_kwargs diff --git a/piker/brokers/ib/__init__.py b/piker/brokers/ib/__init__.py new file mode 100644 index 00000000..877b0667 --- /dev/null +++ b/piker/brokers/ib/__init__.py @@ -0,0 +1,54 @@ +# piker: trading gear for hackers +# Copyright (C) Tyler Goodlet (in stewardship for pikers) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +""" +Interactive Brokers API backend. + +Sub-modules within break into the core functionalities: + +- ``broker.py`` part for orders / trading endpoints +- ``data.py`` for real-time data feed endpoints + +- ``client.py`` for the core API machinery which is ``trio``-ized + wrapping around ``ib_insync``. + +- ``report.py`` for the hackery to build manual pp calcs + to avoid ib's absolute bullshit FIFO style position + tracking.. + +""" +from .client import ( + get_client, + open_history_client, + open_symbol_search, + stream_quotes, + trades_dialogue, +) + +# tractor RPC enable arg +__enable_modules__: list[str] = [ + 'client', +] + +# passed to ``tractor.ActorNursery.start_actor()`` +_spawn_kwargs = { + 'infect_asyncio': True, +} + +# annotation to let backend agnostic code +# know if ``brokerd`` should be spawned with +# ``tractor``'s aio mode. +_infect_asyncio: bool = True diff --git a/piker/brokers/ib.py b/piker/brokers/ib/client.py similarity index 99% rename from piker/brokers/ib.py rename to piker/brokers/ib/client.py index 9b32521f..cbbbd8d4 100644 --- a/piker/brokers/ib.py +++ b/piker/brokers/ib/client.py @@ -15,11 +15,8 @@ # along with this program. If not, see . """ -Interactive Brokers API backend. - -Note the client runs under an ``asyncio`` loop (since ``ib_insync`` is -built on it) and thus actor aware API calls must be spawned with -``infected_aio==True``. +``ib`` core API client machinery; mostly sane wrapping around +``ib_insync``. """ from __future__ import annotations @@ -61,12 +58,12 @@ import numpy as np import pendulum -from .. import config -from ..log import get_logger, get_console_log -from ..data._source import base_ohlc_dtype -from ..data._sharedmem import ShmArray -from ._util import SymbolNotFound, NoData -from ..clearing._messages import ( +from piker import config +from piker.log import get_logger, get_console_log +from piker.data._source import base_ohlc_dtype +from piker.data._sharedmem import ShmArray +from .._util import SymbolNotFound, NoData +from piker.clearing._messages import ( BrokerdOrder, BrokerdOrderAck, BrokerdStatus, BrokerdPosition, BrokerdCancel, BrokerdFill, BrokerdError, @@ -75,10 +72,7 @@ from ..clearing._messages import ( log = get_logger(__name__) -# passed to ``tractor.ActorNursery.start_actor()`` -_spawn_kwargs = { - 'infect_asyncio': True, -} + _time_units = { 's': ' sec', 'm': ' mins', @@ -118,12 +112,6 @@ _search_conf = { } -# annotation to let backend agnostic code -# know if ``brokerd`` should be spawned with -# ``tractor``'s aio mode. -_infect_asyncio: bool = True - - # overrides to sidestep pretty questionable design decisions in # ``ib_insync``: class NonShittyWrapper(Wrapper):