From 147207a0ad7d41633ab32b0c58b2994af0529e77 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Tue, 28 Sep 2021 16:39:11 -0400 Subject: [PATCH 1/6] Add first draft of "dollar volume" fsp --- piker/fsp/_volume.py | 65 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/piker/fsp/_volume.py b/piker/fsp/_volume.py index 30397920..8dd93d4f 100644 --- a/piker/fsp/_volume.py +++ b/piker/fsp/_volume.py @@ -14,16 +14,20 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from typing import AsyncIterator, Optional +from typing import AsyncIterator, Optional, Union import numpy as np +from tractor._broadcast import AsyncReceiver from ..data._normalize import iterticks +from ..data._sharedmem import ShmArray def wap( + signal: np.ndarray, weights: np.ndarray, + ) -> np.ndarray: """Weighted average price from signal and weights. @@ -47,15 +51,22 @@ def wap( async def _tina_vwap( - source, #: AsyncStream[np.ndarray], - ohlcv: np.ndarray, # price time-frame "aware" + + source: AsyncReceiver[dict], + ohlcv: ShmArray, # OHLC sampled history + + # TODO: anchor logic (eg. to session start) anchors: Optional[np.ndarray] = None, -) -> AsyncIterator[np.ndarray]: # maybe something like like FspStream? - """Streaming volume weighted moving average. + +) -> Union[ + AsyncIterator[np.ndarray], + float +]: + '''Streaming volume weighted moving average. Calling this "tina" for now since we're using HLC3 instead of tick. - """ + ''' if anchors is None: # TODO: # anchor to session start of data if possible @@ -75,7 +86,6 @@ async def _tina_vwap( # vwap_tot = h_vwap[-1] async for quote in source: - for tick in iterticks(quote, types=['trade']): # c, h, l, v = ohlcv.array[-1][ @@ -91,3 +101,44 @@ async def _tina_vwap( # yield ((((o + h + l) / 3) * v) weights_tot) / v_tot yield w_tot / v_tot + + +async def dolla_vlm( + source: AsyncReceiver[dict], + ohlcv: ShmArray, # OHLC sampled history + +) -> Union[ + AsyncIterator[np.ndarray], + float +]: + a = ohlcv.array + chl3 = (a['close'] + a['high'] + a['low']) / 3 + v = a['volume'] + + # history + yield chl3 * v + + i = ohlcv.index + lvlm = 0 + + async for quote in source: + for tick in iterticks(quote): + + # this computes tick-by-tick weightings from here forward + size = tick['size'] + price = tick['price'] + + li = ohlcv.index + if li > i: + i = li + lvlm = 0 + + c, h, l, v = ohlcv.last()[ + ['close', 'high', 'low', 'volume'] + ] + + lvlm += price * size + tina_lvlm = c+h+l/3 * v + # print(f' tinal vlm: {tina_lvlm}') + + yield lvlm From 4c9e5feace23fb41fa341bd208774646209ab8cd Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Thu, 30 Sep 2021 07:41:09 -0400 Subject: [PATCH 2/6] Expose dollar volume to fsp engine It can now be declared inside an fsp config dict under the name `dolla_vlm`. We still need to offer an engine control that zeros the newest sample value instead of copying from the previous. This also litters the engine code with `pyqtgraph` profiling to see if we can improve startup times - likely it'll mean pre-allocating a small fsp daemon cluster at startup. --- piker/fsp/_engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/piker/fsp/_engine.py b/piker/fsp/_engine.py index 2b7056da..bc55e154 100644 --- a/piker/fsp/_engine.py +++ b/piker/fsp/_engine.py @@ -34,7 +34,7 @@ from ..data import attach_shm_array from ..data.feed import Feed from ..data._sharedmem import ShmArray from ._momo import _rsi, _wma -from ._volume import _tina_vwap +from ._volume import _tina_vwap, dolla_vlm log = get_logger(__name__) @@ -42,6 +42,7 @@ _fsp_builtins = { 'rsi': _rsi, 'wma': _wma, 'vwap': _tina_vwap, + 'dolla_vlm': dolla_vlm, } # TODO: things to figure the heck out: From 1f64f47ee9c324eaf895365bfca3afa899ab6be1 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Fri, 22 Oct 2021 12:13:08 -0400 Subject: [PATCH 3/6] Port imports to tractor's new subpkg --- piker/fsp/_volume.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/piker/fsp/_volume.py b/piker/fsp/_volume.py index 8dd93d4f..e5a592e3 100644 --- a/piker/fsp/_volume.py +++ b/piker/fsp/_volume.py @@ -17,7 +17,7 @@ from typing import AsyncIterator, Optional, Union import numpy as np -from tractor._broadcast import AsyncReceiver +from tractor.trionics._broadcast import AsyncReceiver from ..data._normalize import iterticks from ..data._sharedmem import ShmArray From 0f200d959641a3c28697a925147669c18eb5b2b5 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Fri, 1 Oct 2021 17:47:02 -0400 Subject: [PATCH 4/6] Revert to old shm "last" meaning last row --- piker/fsp/_volume.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/piker/fsp/_volume.py b/piker/fsp/_volume.py index e5a592e3..f4fb8f7c 100644 --- a/piker/fsp/_volume.py +++ b/piker/fsp/_volume.py @@ -135,7 +135,7 @@ async def dolla_vlm( c, h, l, v = ohlcv.last()[ ['close', 'high', 'low', 'volume'] - ] + ][0] lvlm += price * size tina_lvlm = c+h+l/3 * v From 8e81f8bd81b05dae0ad88b1adc939c8fd8290351 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Mon, 24 Jan 2022 06:38:26 -0500 Subject: [PATCH 5/6] Add dollar volume fsp config section to display in subchart --- piker/ui/_display.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/piker/ui/_display.py b/piker/ui/_display.py index dcc0badd..43085b7d 100644 --- a/piker/ui/_display.py +++ b/piker/ui/_display.py @@ -932,7 +932,7 @@ async def maybe_open_vlm_display( async with open_fsp_sidepane( linked, { - '$_vlm': { + 'vlm': { 'params': { @@ -1102,6 +1102,20 @@ async def display_symbol_data( # TODO: eventually we'll support some kind of n-compose syntax fsp_conf = { + 'dolla_vlm': { + 'func_name': 'dolla_vlm', + 'zero_on_step': True, + 'params': { + 'price_func': { + 'default_value': 'chl3', + # tell target ``Edit`` widget to not allow + # edits for now. + 'widget_kwargs': {'readonly': True}, + }, + }, + 'chart_kwargs': {'style': 'step'} + }, + 'rsi': { 'func_name': 'rsi', # literal python func ref lookup name From ba7ed8b87742a39a807601d13abe578637488845 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Wed, 22 Dec 2021 08:35:00 -0500 Subject: [PATCH 6/6] Add draft $_vlm doc string --- piker/fsp/_volume.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/piker/fsp/_volume.py b/piker/fsp/_volume.py index f4fb8f7c..e662343f 100644 --- a/piker/fsp/_volume.py +++ b/piker/fsp/_volume.py @@ -103,6 +103,11 @@ async def _tina_vwap( yield w_tot / v_tot +# @fsp.config( +# name='dolla_vlm', +# ohlc=False, +# style='step', +# ) async def dolla_vlm( source: AsyncReceiver[dict], ohlcv: ShmArray, # OHLC sampled history @@ -111,6 +116,15 @@ async def dolla_vlm( AsyncIterator[np.ndarray], float ]: + ''' + "Dollar Volume", aka the volume in asset-currency-units (usually + a fiat) computed from some price function for the sample step + *times* the asset unit volume. + + Useful for comparing cross asset "money flow" in #s that are + asset-currency-independent. + + ''' a = ohlcv.array chl3 = (a['close'] + a['high'] + a['low']) / 3 v = a['volume']