Copy non-base dtype fields on bar increment

bar_select
Tyler Goodlet 2020-09-09 21:19:36 -04:00
parent 80f191c57d
commit da2325239c
3 changed files with 20 additions and 21 deletions

View File

@ -1,8 +1,6 @@
""" """
Chart axes graphics and behavior. Chart axes graphics and behavior.
""" """
import time
from functools import partial
from typing import List from typing import List
@ -12,7 +10,6 @@ import pyqtgraph as pg
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QPointF from PyQt5.QtCore import QPointF
from .quantdom.utils import fromtimestamp
from ._style import _font, hcolor from ._style import _font, hcolor
@ -78,7 +75,8 @@ class DynamicDateAxis(pg.AxisItem):
bars = self.linked_charts.chart._array bars = self.linked_charts.chart._array
times = bars['time'] times = bars['time']
bars_len = len(bars) bars_len = len(bars)
delay = times[-1] - times[times != times[-1]][-1] # delay = times[-1] - times[times != times[-1]][-1]
delay = times[-1] - times[-2]
epochs = times[list( epochs = times[list(
map(int, filter(lambda i: i < bars_len, indexes)) map(int, filter(lambda i: i < bars_len, indexes))
@ -87,7 +85,6 @@ class DynamicDateAxis(pg.AxisItem):
dts = pd.to_datetime(epochs, unit='s') - 4*pd.offsets.Hour() dts = pd.to_datetime(epochs, unit='s') - 4*pd.offsets.Hour()
return dts.strftime(self.tick_tpl[delay]) return dts.strftime(self.tick_tpl[delay])
def tickStrings(self, values: List[float], scale, spacing): def tickStrings(self, values: List[float], scale, spacing):
return self._indexes_to_timestrs(values) return self._indexes_to_timestrs(values)

View File

@ -22,7 +22,7 @@ from .. import brokers
from .. import data from .. import data
from ..log import get_logger from ..log import get_logger
from ._exec import run_qtractor from ._exec import run_qtractor
from ._source import ohlc_dtype from ._source import base_ohlc_dtype
from ._interaction import ChartView from ._interaction import ChartView
from .. import fsp from .. import fsp
@ -507,13 +507,13 @@ class ChartPlotWidget(pg.PlotWidget):
# TODO: should probably just have some kinda attr mark # TODO: should probably just have some kinda attr mark
# that determines this behavior based on array type # that determines this behavior based on array type
try: try:
ylow = bars['low'].min() ylow = np.nanmin(bars['low'])
yhigh = bars['high'].max() yhigh = np.nanmax(bars['high'])
# std = np.std(bars['close']) # std = np.std(bars['close'])
except IndexError: except IndexError:
# must be non-ohlc array? # must be non-ohlc array?
ylow = bars.min() ylow = np.nanmin(bars)
yhigh = bars.max() yhigh = np.nanmax(bars)
# std = np.std(bars) # std = np.std(bars)
# view margins: stay within 10% of the "true range" # view margins: stay within 10% of the "true range"
@ -589,14 +589,13 @@ async def add_new_bars(delay_s, linked_charts):
def incr_ohlc_array(array: np.ndarray): def incr_ohlc_array(array: np.ndarray):
(index, t, close) = array[-1][['index', 'time', 'close']] (index, t, close) = array[-1][['index', 'time', 'close']]
new_array = np.append(
array, # this copies non-std fields (eg. vwap) from the last datum
np.array( _next = np.array(array[-1], dtype=array.dtype)
[(index + 1, t + delay_s, close, close, _next[
close, close, 0)], ['index', 'time', 'volume', 'open', 'high', 'low', 'close']
dtype=array.dtype ] = (index + 1, t + delay_s, 0, close, close, close, close)
), new_array = np.append(array, _next,)
)
return new_array return new_array
# add new increment/bar # add new increment/bar
@ -668,6 +667,9 @@ async def _async_main(
# figure out the exact symbol # figure out the exact symbol
bars = await client.bars(symbol=sym) bars = await client.bars(symbol=sym)
# allow broker to declare historical data fields
ohlc_dtype = getattr(brokermod, 'ohlc_dtype', base_ohlc_dtype)
# remember, msgpack-numpy's ``from_buffer` returns read-only array # remember, msgpack-numpy's ``from_buffer` returns read-only array
bars = np.array(bars[list(ohlc_dtype.names)]) bars = np.array(bars[list(ohlc_dtype.names)])

View File

@ -8,7 +8,7 @@ import numpy as np
import pandas as pd import pandas as pd
ohlc_dtype = np.dtype( base_ohlc_dtype = np.dtype(
[ [
('index', int), ('index', int),
('time', float), ('time', float),
@ -38,7 +38,7 @@ def ohlc_zeros(length: int) -> np.ndarray:
For "why a structarray" see here: https://stackoverflow.com/a/52443038 For "why a structarray" see here: https://stackoverflow.com/a/52443038
Bottom line, they're faster then ``np.recarray``. Bottom line, they're faster then ``np.recarray``.
""" """
return np.zeros(length, dtype=ohlc_dtype) return np.zeros(length, dtype=base_ohlc_dtype)
@dataclass @dataclass
@ -88,7 +88,7 @@ def from_df(
df = df.rename(columns=columns) df = df.rename(columns=columns)
for name in df.columns: for name in df.columns:
if name not in ohlc_dtype.names[1:]: if name not in base_ohlc_dtype.names[1:]:
del df[name] del df[name]
# TODO: it turns out column access on recarrays is actually slower: # TODO: it turns out column access on recarrays is actually slower: