From 769b292dca6e7d2eda16193fe507c5eb916ebd1f Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Tue, 9 May 2023 18:29:28 -0400 Subject: [PATCH] Allow `brokerd` runtime switch to paper mode Previously you couldn't have a brokerd backend which defined `.trades_dialogue()` but which could also indicate that the paper clearing engine should be used. This adds that support by allowing the endpoint task to return a simple `'paper'` string, in which case the ems will boot a paperboi. The obvious useful case for this is if you have a broker you want to use but do not have actual broker credentials setup (yet) with that provider in your `brokers.toml`; demonstrated here with the adjustment to `kraken`'s startup to no longer raise a runtime error B) --- piker/brokers/kraken/broker.py | 4 +-- piker/brokers/kraken/feed.py | 2 -- piker/clearing/_ems.py | 45 +++++++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/piker/brokers/kraken/broker.py b/piker/brokers/kraken/broker.py index 776d33cb..994b7158 100644 --- a/piker/brokers/kraken/broker.py +++ b/piker/brokers/kraken/broker.py @@ -429,8 +429,8 @@ async def trades_dialogue( async with get_client() as client: if not client._api_key: - raise RuntimeError( - 'Missing Kraken API key in `brokers.toml`!?!?') + await ctx.started('paper') + return # TODO: make ems flip to paper mode via # some returned signal if the user only wants to use diff --git a/piker/brokers/kraken/feed.py b/piker/brokers/kraken/feed.py index b4364da2..4d496376 100644 --- a/piker/brokers/kraken/feed.py +++ b/piker/brokers/kraken/feed.py @@ -413,8 +413,6 @@ async def stream_quotes( topic, quote = normalize(ohlc_last) task_status.started((init_msgs, quote)) - - # lol, only "closes" when they're margin squeezing clients ;P feed_is_live.set() # keep start of last interval for volume tracking diff --git a/piker/clearing/_ems.py b/piker/clearing/_ems.py index 7373a5ea..77cad1bd 100644 --- a/piker/clearing/_ems.py +++ b/piker/clearing/_ems.py @@ -407,11 +407,7 @@ class Router(Struct): yield relay return - trades_endpoint = getattr(brokermod, 'trades_dialogue', None) - if ( - trades_endpoint is None - or exec_mode == 'paper' - ): + def mk_paper_ep(): # for logging purposes brokermod = paper @@ -426,26 +422,53 @@ class Router(Struct): # load the paper trading engine as a subactor of this emsd # actor to simulate the real IPC load it'll have when also # pulling data from feeds - open_trades_endpoint = paper.open_paperboi( + return paper.open_paperboi( fqme=fqme, loglevel=loglevel, ) - else: + trades_endpoint = getattr(brokermod, 'trades_dialogue', None) + if ( + trades_endpoint is not None + or exec_mode != 'paper' + ): # open live brokerd trades endpoint open_trades_endpoint = portal.open_context( trades_endpoint, loglevel=loglevel, ) - # open trades-dialog endpoint with backend broker + else: + exec_mode: str = 'paper' + + @acm + async def maybe_open_paper_ep(): + if exec_mode == 'paper': + async with mk_paper_ep() as msg: + yield msg + return + + # open trades-dialog endpoint with backend broker + async with open_trades_endpoint as msg: + ctx, first = msg + + # runtime indication that the backend can't support live + # order ctrl yet, so boot the paperboi B0 + if first == 'paper': + async with mk_paper_ep() as msg: + yield msg + return + else: + # working live ep case B) + yield msg + return + positions: list[BrokerdPosition] accounts: tuple[str] - async with ( - open_trades_endpoint as ( + maybe_open_paper_ep() as ( brokerd_ctx, - (positions, accounts,), + (positions, accounts), ), brokerd_ctx.open_stream() as brokerd_trades_stream, ):