From 35b097469b8e4921f55785c90db522f1e8435878 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Thu, 12 Jan 2023 01:32:30 -0500 Subject: [PATCH 1/3] Round spread (slap) offset to min tick digits --- piker/clearing/_ems.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/piker/clearing/_ems.py b/piker/clearing/_ems.py index ad512c08..01de9822 100644 --- a/piker/clearing/_ems.py +++ b/piker/clearing/_ems.py @@ -46,6 +46,7 @@ from ..data._normalize import iterticks from ..data._source import ( unpack_fqsn, mk_fqsn, + float_digits, ) from ..data.feed import ( Feed, @@ -1249,6 +1250,7 @@ async def process_client_order_cmds( spread_slap: float = 5 min_tick = flume.symbol.tick_size + min_tick_digits = float_digits(min_tick) if action == 'buy': tickfilter = ('ask', 'last', 'trade') @@ -1257,12 +1259,18 @@ async def process_client_order_cmds( # TODO: we probably need to scale this based # on some near term historical spread # measure? - abs_diff_away = spread_slap * min_tick + abs_diff_away = round( + spread_slap * min_tick, + ndigits=min_tick_digits, + ) elif action == 'sell': tickfilter = ('bid', 'last', 'trade') percent_away = -0.005 - abs_diff_away = -spread_slap * min_tick + abs_diff_away = round( + -spread_slap * min_tick, + ndigits=min_tick_digits, + ) else: # alert tickfilter = ('trade', 'utrade', 'last') From 7ef81113813339556e58b75d2e7e06b09805260e Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Thu, 12 Jan 2023 16:30:56 -0500 Subject: [PATCH 2/3] Provide `datetime`-sorted clears table iteration Likely pertains to helping with stuff in issues #345 and #373 and just generally is handy to have when processing ledgers / clearing event tables. Adds the following helper methods: - `iter_by_dt()` to iter-sort an arbitrary `Transaction`-like table of clear entries. - `Position.iter_clears()` as a convenience wrapper for the above. --- piker/pp.py | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/piker/pp.py b/piker/pp.py index 8fdaaa4d..48cf0daa 100644 --- a/piker/pp.py +++ b/piker/pp.py @@ -29,6 +29,7 @@ import re import time from typing import ( Any, + Iterator, Optional, Union, ) @@ -116,6 +117,21 @@ class Transaction(Struct, frozen=True): # from: Optional[str] = None +def iter_by_dt( + clears: dict[str, Any], +) -> Iterator[tuple[str, dict]]: + ''' + Iterate entries of a ``clears: dict`` table sorted by entry recorded + datetime presumably set at the ``'dt'`` field in each entry. + + ''' + for tid, data in sorted( + list(clears.items()), + key=lambda item: item[1]['dt'], + ): + yield tid, data + + class Position(Struct): ''' Basic pp (personal/piker position) model with attached clearing @@ -183,12 +199,7 @@ class Position(Struct): toml_clears_list = [] # reverse sort so latest clears are at top of section? - for tid, data in sorted( - list(clears.items()), - - # sort by datetime - key=lambda item: item[1]['dt'], - ): + for tid, data in iter_by_dt(clears): inline_table = toml.TomlDecoder().get_empty_inline_table() # serialize datetime to parsable `str` @@ -301,6 +312,14 @@ class Position(Struct): # def lifo_price() -> float: # ... + def iter_clears(self) -> Iterator[tuple[str, dict]]: + ''' + Iterate the internally managed ``.clears: dict`` table in + datetime-stamped order. + + ''' + return iter_by_dt(self.clears) + def calc_ppu( self, # include transaction cost in breakeven price @@ -331,10 +350,9 @@ class Position(Struct): asize_h: list[float] = [] # historical accumulative size ppu_h: list[float] = [] # historical price-per-unit - clears = list(self.clears.items()) - - for i, (tid, entry) in enumerate(clears): - + tid: str + entry: dict[str, Any] + for (tid, entry) in self.iter_clears(): clear_size = entry['size'] clear_price = entry['price'] @@ -344,6 +362,11 @@ class Position(Struct): sign_change: bool = False + if accum_size == 0: + ppu_h.append(0) + asize_h.append(0) + continue + if accum_size == 0: ppu_h.append(0) asize_h.append(0) From 51f4afbd88ddbca2bb18630dab670fefc8e402c1 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Mon, 9 Jan 2023 14:24:39 -0500 Subject: [PATCH 3/3] Don't raise on quote feed lags to dark clearing loop --- piker/clearing/_ems.py | 1 + 1 file changed, 1 insertion(+) diff --git a/piker/clearing/_ems.py b/piker/clearing/_ems.py index 01de9822..32a1cc36 100644 --- a/piker/clearing/_ems.py +++ b/piker/clearing/_ems.py @@ -173,6 +173,7 @@ async def clear_dark_triggers( # TODO: # - numba all this! # - this stream may eventually contain multiple symbols + quote_stream._raise_on_lag = False async for quotes in quote_stream: # start = time.time() for sym, quote in quotes.items():