Add OHLC to m4 line converters
Helpers to quickly convert ohlc struct-array sequences into lines for consumption by the m4 downsampler. Strip trailing zero entries from the `ds_m4()` output if found (avoids lines back to origin).mkts_backup
parent
01f06976ed
commit
7e5c8f4417
|
@ -22,7 +22,7 @@ limits on the display device.
|
||||||
import math
|
import math
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
# from numpy.lib.recfunctions import structured_to_unstructured
|
from numpy.lib import recfunctions as rfn
|
||||||
from numba import (
|
from numba import (
|
||||||
jit,
|
jit,
|
||||||
# float64, optional, int64,
|
# float64, optional, int64,
|
||||||
|
@ -174,6 +174,51 @@ def downsample(
|
||||||
return ds_m4(x, y, kwargs['px_width'])
|
return ds_m4(x, y, kwargs['px_width'])
|
||||||
|
|
||||||
|
|
||||||
|
def ohlc_flatten(
|
||||||
|
ohlc: np.ndarray,
|
||||||
|
|
||||||
|
) -> tuple[np.ndarray, np.ndarray]:
|
||||||
|
'''
|
||||||
|
Convert an OHLCV struct-array into a flat ready-for-line-plotting
|
||||||
|
1-d array that is 4 times the size with x-domain values distributed
|
||||||
|
evenly (by 0.5 steps) over each index.
|
||||||
|
|
||||||
|
'''
|
||||||
|
index = ohlc['index']
|
||||||
|
|
||||||
|
flat = rfn.structured_to_unstructured(
|
||||||
|
ohlc[['open', 'high', 'low', 'close']]
|
||||||
|
).flatten()
|
||||||
|
|
||||||
|
x = np.linspace(
|
||||||
|
start=index[0] - 0.5,
|
||||||
|
stop=index[-1] + 0.5,
|
||||||
|
num=4*len(ohlc),
|
||||||
|
)
|
||||||
|
return x, flat
|
||||||
|
|
||||||
|
|
||||||
|
def ohlc_to_m4_line(
|
||||||
|
ohlc: np.ndarray,
|
||||||
|
px_width: int,
|
||||||
|
|
||||||
|
) -> tuple[np.ndarray, np.ndarray]:
|
||||||
|
'''
|
||||||
|
Convert an OHLC struct-array to a m4 downsampled 1-d array.
|
||||||
|
|
||||||
|
'''
|
||||||
|
xpts, flat = ohlc_flatten(ohlc)
|
||||||
|
bins, x, y = ds_m4(
|
||||||
|
xpts,
|
||||||
|
flat,
|
||||||
|
px_width=px_width * 16,
|
||||||
|
)
|
||||||
|
x = np.broadcast_to(x[:, None], y.shape)
|
||||||
|
x = (x + np.array([-0.43, 0, 0, 0.43])).flatten()
|
||||||
|
y = y.flatten()
|
||||||
|
return x, y
|
||||||
|
|
||||||
|
|
||||||
def ds_m4(
|
def ds_m4(
|
||||||
x: np.ndarray,
|
x: np.ndarray,
|
||||||
y: np.ndarray,
|
y: np.ndarray,
|
||||||
|
@ -233,7 +278,7 @@ def ds_m4(
|
||||||
# (uniform quotient output) worth of datum-domain-points
|
# (uniform quotient output) worth of datum-domain-points
|
||||||
# per windows-frame, add one more window to ensure
|
# per windows-frame, add one more window to ensure
|
||||||
# we have room for all output down-samples.
|
# we have room for all output down-samples.
|
||||||
pts_per_pixel, r = divmod(len(x), px_width)
|
pts_per_pixel, r = divmod(len(x), frames)
|
||||||
if r:
|
if r:
|
||||||
frames += 1
|
frames += 1
|
||||||
|
|
||||||
|
@ -257,6 +302,12 @@ def ds_m4(
|
||||||
w,
|
w,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# filter out any overshoot in the input allocation arrays by
|
||||||
|
# removing zero-ed tail entries which should start at a certain
|
||||||
|
# index.
|
||||||
|
i_win = i_win[i_win != 0]
|
||||||
|
y_out = y_out[:i_win.size]
|
||||||
|
|
||||||
return nb, i_win, y_out
|
return nb, i_win, y_out
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue