Adjust OHLC bar x-offsets to be time span matched
Previously we were drawing with the middle of the bar on each index with arms to either side: +/- some arm length. Instead this changes so that each bar is drawn *after* each index/timestamp such that in graphics coords the bar span more correctly matches the time span in the x-domain. This makes the linked region between slow and fast chart directly match (without any transform) for epoch-time indexing such that the last x-coord in view on the fast chart is no more then the next time step in (downsampled) slow view. Deats: - adjust in `._pathops.path_arrays_from_ohlc()` and take an `bar_w` bar width input (normally taken from the data step size). - change `.ui._ohlc.bar_from_ohlc_row()` and `BarItems.draw_last_datum()` to match.multichartz
parent
e9ca618fcb
commit
f31f4d3256
|
@ -93,7 +93,8 @@ def xy_downsample(
|
||||||
def path_arrays_from_ohlc(
|
def path_arrays_from_ohlc(
|
||||||
data: np.ndarray,
|
data: np.ndarray,
|
||||||
start: int64,
|
start: int64,
|
||||||
bar_gap: float64 = 0.43,
|
bar_w: float64,
|
||||||
|
bar_gap: float64 = 0.16,
|
||||||
use_time_index: bool = True,
|
use_time_index: bool = True,
|
||||||
|
|
||||||
# XXX: ``numba`` issue: https://github.com/numba/numba/issues/8622
|
# XXX: ``numba`` issue: https://github.com/numba/numba/issues/8622
|
||||||
|
@ -119,6 +120,8 @@ def path_arrays_from_ohlc(
|
||||||
)
|
)
|
||||||
y, c = x.copy(), x.copy()
|
y, c = x.copy(), x.copy()
|
||||||
|
|
||||||
|
half_w: float = bar_w/2
|
||||||
|
|
||||||
# TODO: report bug for assert @
|
# TODO: report bug for assert @
|
||||||
# /home/goodboy/repos/piker/env/lib/python3.8/site-packages/numba/core/typing/builtins.py:991
|
# /home/goodboy/repos/piker/env/lib/python3.8/site-packages/numba/core/typing/builtins.py:991
|
||||||
for i, q in enumerate(data[start:], start):
|
for i, q in enumerate(data[start:], start):
|
||||||
|
@ -143,13 +146,14 @@ def path_arrays_from_ohlc(
|
||||||
istop = istart + 6
|
istop = istart + 6
|
||||||
|
|
||||||
# x,y detail the 6 points which connect all vertexes of a ohlc bar
|
# x,y detail the 6 points which connect all vertexes of a ohlc bar
|
||||||
|
mid: float = index + half_w
|
||||||
x[istart:istop] = (
|
x[istart:istop] = (
|
||||||
index - bar_gap,
|
|
||||||
index,
|
|
||||||
index,
|
|
||||||
index,
|
|
||||||
index,
|
|
||||||
index + bar_gap,
|
index + bar_gap,
|
||||||
|
mid,
|
||||||
|
mid,
|
||||||
|
mid,
|
||||||
|
mid,
|
||||||
|
index + bar_w - bar_gap,
|
||||||
)
|
)
|
||||||
y[istart:istop] = (
|
y[istart:istop] = (
|
||||||
open,
|
open,
|
||||||
|
|
|
@ -51,7 +51,8 @@ log = get_logger(__name__)
|
||||||
def bar_from_ohlc_row(
|
def bar_from_ohlc_row(
|
||||||
row: np.ndarray,
|
row: np.ndarray,
|
||||||
# 0.5 is no overlap between arms, 1.0 is full overlap
|
# 0.5 is no overlap between arms, 1.0 is full overlap
|
||||||
bar_gap: float = 0.43
|
bar_w: float,
|
||||||
|
bar_gap: float = 0.16
|
||||||
|
|
||||||
) -> tuple[QLineF]:
|
) -> tuple[QLineF]:
|
||||||
'''
|
'''
|
||||||
|
@ -67,9 +68,11 @@ def bar_from_ohlc_row(
|
||||||
# history path faster since it's done in C++:
|
# history path faster since it's done in C++:
|
||||||
# https://doc.qt.io/qt-5/qgraphicslineitem.html
|
# https://doc.qt.io/qt-5/qgraphicslineitem.html
|
||||||
|
|
||||||
|
mid: float = (bar_w / 2) + index
|
||||||
|
|
||||||
# high -> low vertical (body) line
|
# high -> low vertical (body) line
|
||||||
if low != high:
|
if low != high:
|
||||||
hl = QLineF(index, low, index, high)
|
hl = QLineF(mid, low, mid, high)
|
||||||
else:
|
else:
|
||||||
# XXX: if we don't do it renders a weird rectangle?
|
# XXX: if we don't do it renders a weird rectangle?
|
||||||
# see below for filtering this later...
|
# see below for filtering this later...
|
||||||
|
@ -80,10 +83,13 @@ def bar_from_ohlc_row(
|
||||||
# the index's range according to the view mapping coordinates.
|
# the index's range according to the view mapping coordinates.
|
||||||
|
|
||||||
# open line
|
# open line
|
||||||
o = QLineF(index - bar_gap, open, index, open)
|
o = QLineF(index + bar_gap, open, mid, open)
|
||||||
|
|
||||||
# close line
|
# close line
|
||||||
c = QLineF(index, close, index + bar_gap, close)
|
c = QLineF(
|
||||||
|
mid, close,
|
||||||
|
index + bar_w - bar_gap, close,
|
||||||
|
)
|
||||||
|
|
||||||
return [hl, o, c]
|
return [hl, o, c]
|
||||||
|
|
||||||
|
@ -249,10 +255,11 @@ class BarItems(pg.GraphicsObject):
|
||||||
step_size = index[-1] - index[-2]
|
step_size = index[-1] - index[-2]
|
||||||
|
|
||||||
# generate new lines objects for updatable "current bar"
|
# generate new lines objects for updatable "current bar"
|
||||||
|
bg: float = 0.16 * step_size
|
||||||
self._last_bar_lines = bar_from_ohlc_row(
|
self._last_bar_lines = bar_from_ohlc_row(
|
||||||
last_row,
|
last_row,
|
||||||
bar_gap=step_size * 0.43
|
bar_w=step_size,
|
||||||
# fields,
|
bar_gap=bg,
|
||||||
)
|
)
|
||||||
|
|
||||||
# assert i == graphics.start_index - 1
|
# assert i == graphics.start_index - 1
|
||||||
|
@ -268,10 +275,16 @@ class BarItems(pg.GraphicsObject):
|
||||||
if l != h: # noqa
|
if l != h: # noqa
|
||||||
|
|
||||||
if body is None:
|
if body is None:
|
||||||
body = self._last_bar_lines[0] = QLineF(i, l, i, h)
|
body = self._last_bar_lines[0] = QLineF(
|
||||||
|
i + bg, l,
|
||||||
|
i + step_size - bg, h,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# update body
|
# update body
|
||||||
body.setLine(i, l, i, h)
|
body.setLine(
|
||||||
|
body.x1(), l,
|
||||||
|
body.x2(), h,
|
||||||
|
)
|
||||||
|
|
||||||
# XXX: pretty sure this is causing an issue where the
|
# XXX: pretty sure this is causing an issue where the
|
||||||
# bar has a large upward move right before the next
|
# bar has a large upward move right before the next
|
||||||
|
|
Loading…
Reference in New Issue