commit
fa2468b175
|
@ -34,7 +34,7 @@ from ..data import attach_shm_array
|
||||||
from ..data.feed import Feed
|
from ..data.feed import Feed
|
||||||
from ..data._sharedmem import ShmArray
|
from ..data._sharedmem import ShmArray
|
||||||
from ._momo import _rsi, _wma
|
from ._momo import _rsi, _wma
|
||||||
from ._volume import _tina_vwap
|
from ._volume import _tina_vwap, dolla_vlm
|
||||||
|
|
||||||
log = get_logger(__name__)
|
log = get_logger(__name__)
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ _fsp_builtins = {
|
||||||
'rsi': _rsi,
|
'rsi': _rsi,
|
||||||
'wma': _wma,
|
'wma': _wma,
|
||||||
'vwap': _tina_vwap,
|
'vwap': _tina_vwap,
|
||||||
|
'dolla_vlm': dolla_vlm,
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: things to figure the heck out:
|
# TODO: things to figure the heck out:
|
||||||
|
|
|
@ -14,16 +14,20 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from typing import AsyncIterator, Optional
|
from typing import AsyncIterator, Optional, Union
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from tractor.trionics._broadcast import AsyncReceiver
|
||||||
|
|
||||||
from ..data._normalize import iterticks
|
from ..data._normalize import iterticks
|
||||||
|
from ..data._sharedmem import ShmArray
|
||||||
|
|
||||||
|
|
||||||
def wap(
|
def wap(
|
||||||
|
|
||||||
signal: np.ndarray,
|
signal: np.ndarray,
|
||||||
weights: np.ndarray,
|
weights: np.ndarray,
|
||||||
|
|
||||||
) -> np.ndarray:
|
) -> np.ndarray:
|
||||||
"""Weighted average price from signal and weights.
|
"""Weighted average price from signal and weights.
|
||||||
|
|
||||||
|
@ -47,15 +51,22 @@ def wap(
|
||||||
|
|
||||||
|
|
||||||
async def _tina_vwap(
|
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,
|
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.
|
Calling this "tina" for now since we're using HLC3 instead of tick.
|
||||||
|
|
||||||
"""
|
'''
|
||||||
if anchors is None:
|
if anchors is None:
|
||||||
# TODO:
|
# TODO:
|
||||||
# anchor to session start of data if possible
|
# anchor to session start of data if possible
|
||||||
|
@ -75,7 +86,6 @@ async def _tina_vwap(
|
||||||
# vwap_tot = h_vwap[-1]
|
# vwap_tot = h_vwap[-1]
|
||||||
|
|
||||||
async for quote in source:
|
async for quote in source:
|
||||||
|
|
||||||
for tick in iterticks(quote, types=['trade']):
|
for tick in iterticks(quote, types=['trade']):
|
||||||
|
|
||||||
# c, h, l, v = ohlcv.array[-1][
|
# c, h, l, v = ohlcv.array[-1][
|
||||||
|
@ -91,3 +101,58 @@ async def _tina_vwap(
|
||||||
|
|
||||||
# yield ((((o + h + l) / 3) * v) weights_tot) / v_tot
|
# yield ((((o + h + l) / 3) * v) weights_tot) / v_tot
|
||||||
yield w_tot / v_tot
|
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
|
||||||
|
|
||||||
|
) -> Union[
|
||||||
|
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']
|
||||||
|
|
||||||
|
# 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']
|
||||||
|
][0]
|
||||||
|
|
||||||
|
lvlm += price * size
|
||||||
|
tina_lvlm = c+h+l/3 * v
|
||||||
|
# print(f' tinal vlm: {tina_lvlm}')
|
||||||
|
|
||||||
|
yield lvlm
|
||||||
|
|
|
@ -932,7 +932,7 @@ async def maybe_open_vlm_display(
|
||||||
|
|
||||||
async with open_fsp_sidepane(
|
async with open_fsp_sidepane(
|
||||||
linked, {
|
linked, {
|
||||||
'$_vlm': {
|
'vlm': {
|
||||||
|
|
||||||
'params': {
|
'params': {
|
||||||
|
|
||||||
|
@ -1102,6 +1102,20 @@ async def display_symbol_data(
|
||||||
# TODO: eventually we'll support some kind of n-compose syntax
|
# TODO: eventually we'll support some kind of n-compose syntax
|
||||||
fsp_conf = {
|
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': {
|
'rsi': {
|
||||||
'func_name': 'rsi', # literal python func ref lookup name
|
'func_name': 'rsi', # literal python func ref lookup name
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue