Move qpath-ops routines back to separate mod
							parent
							
								
									ce8279b6b1
								
							
						
					
					
						commit
						eda7b7f3c7
					
				| 
						 | 
					@ -14,7 +14,7 @@
 | 
				
			||||||
# 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/>.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
Super fast ``QPainterPath`` generation related operator routines.
 | 
					Pre-(path)-graphics formatted x/y nd/1d rendering subsystem.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
from __future__ import annotations
 | 
					from __future__ import annotations
 | 
				
			||||||
| 
						 | 
					@ -26,20 +26,12 @@ from typing import (
 | 
				
			||||||
import msgspec
 | 
					import msgspec
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
from numpy.lib import recfunctions as rfn
 | 
					from numpy.lib import recfunctions as rfn
 | 
				
			||||||
from numba import (
 | 
					 | 
				
			||||||
    # types,
 | 
					 | 
				
			||||||
    njit,
 | 
					 | 
				
			||||||
    float64,
 | 
					 | 
				
			||||||
    int64,
 | 
					 | 
				
			||||||
    # optional,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ._sharedmem import (
 | 
					from ._sharedmem import (
 | 
				
			||||||
    ShmArray,
 | 
					    ShmArray,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
# from ._source import numba_ohlc_dtype
 | 
					from ._pathops import (
 | 
				
			||||||
from ._compression import (
 | 
					    path_arrays_from_ohlc,
 | 
				
			||||||
    ds_m4,
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if TYPE_CHECKING:
 | 
					if TYPE_CHECKING:
 | 
				
			||||||
| 
						 | 
					@ -49,129 +41,6 @@ if TYPE_CHECKING:
 | 
				
			||||||
    from .._profile import Profiler
 | 
					    from .._profile import Profiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def xy_downsample(
 | 
					 | 
				
			||||||
    x,
 | 
					 | 
				
			||||||
    y,
 | 
					 | 
				
			||||||
    uppx,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    x_spacer: float = 0.5,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
) -> tuple[
 | 
					 | 
				
			||||||
    np.ndarray,
 | 
					 | 
				
			||||||
    np.ndarray,
 | 
					 | 
				
			||||||
    float,
 | 
					 | 
				
			||||||
    float,
 | 
					 | 
				
			||||||
]:
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    Downsample 1D (flat ``numpy.ndarray``) arrays using M4 given an input
 | 
					 | 
				
			||||||
    ``uppx`` (units-per-pixel) and add space between discreet datums.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    # downsample whenever more then 1 pixels per datum can be shown.
 | 
					 | 
				
			||||||
    # always refresh data bounds until we get diffing
 | 
					 | 
				
			||||||
    # working properly, see above..
 | 
					 | 
				
			||||||
    bins, x, y, ymn, ymx = ds_m4(
 | 
					 | 
				
			||||||
        x,
 | 
					 | 
				
			||||||
        y,
 | 
					 | 
				
			||||||
        uppx,
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # flatten output to 1d arrays suitable for path-graphics generation.
 | 
					 | 
				
			||||||
    x = np.broadcast_to(x[:, None], y.shape)
 | 
					 | 
				
			||||||
    x = (x + np.array(
 | 
					 | 
				
			||||||
        [-x_spacer, 0, 0, x_spacer]
 | 
					 | 
				
			||||||
    )).flatten()
 | 
					 | 
				
			||||||
    y = y.flatten()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return x, y, ymn, ymx
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@njit(
 | 
					 | 
				
			||||||
    # NOTE: need to construct this manually for readonly
 | 
					 | 
				
			||||||
    # arrays, see https://github.com/numba/numba/issues/4511
 | 
					 | 
				
			||||||
    # (
 | 
					 | 
				
			||||||
    #     types.Array(
 | 
					 | 
				
			||||||
    #         numba_ohlc_dtype,
 | 
					 | 
				
			||||||
    #         1,
 | 
					 | 
				
			||||||
    #         'C',
 | 
					 | 
				
			||||||
    #         readonly=True,
 | 
					 | 
				
			||||||
    #     ),
 | 
					 | 
				
			||||||
    #     int64,
 | 
					 | 
				
			||||||
    #     types.unicode_type,
 | 
					 | 
				
			||||||
    #     optional(float64),
 | 
					 | 
				
			||||||
    # ),
 | 
					 | 
				
			||||||
    nogil=True
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
def path_arrays_from_ohlc(
 | 
					 | 
				
			||||||
    data: np.ndarray,
 | 
					 | 
				
			||||||
    start: int64,
 | 
					 | 
				
			||||||
    bar_gap: float64 = 0.43,
 | 
					 | 
				
			||||||
    # index_field: str,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
) -> tuple[
 | 
					 | 
				
			||||||
    np.ndarray,
 | 
					 | 
				
			||||||
    np.ndarray,
 | 
					 | 
				
			||||||
    np.ndarray,
 | 
					 | 
				
			||||||
]:
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    Generate an array of lines objects from input ohlc data.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    size = int(data.shape[0] * 6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # XXX: see this for why the dtype might have to be defined outside
 | 
					 | 
				
			||||||
    # the routine.
 | 
					 | 
				
			||||||
    # https://github.com/numba/numba/issues/4098#issuecomment-493914533
 | 
					 | 
				
			||||||
    x = np.zeros(
 | 
					 | 
				
			||||||
        shape=size,
 | 
					 | 
				
			||||||
        dtype=float64,
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    y, c = x.copy(), x.copy()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # TODO: report bug for assert @
 | 
					 | 
				
			||||||
    # /home/goodboy/repos/piker/env/lib/python3.8/site-packages/numba/core/typing/builtins.py:991
 | 
					 | 
				
			||||||
    for i, q in enumerate(data[start:], start):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # TODO: ask numba why this doesn't work..
 | 
					 | 
				
			||||||
        # open, high, low, close, index = q[
 | 
					 | 
				
			||||||
        #     ['open', 'high', 'low', 'close', 'index']]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        open = q['open']
 | 
					 | 
				
			||||||
        high = q['high']
 | 
					 | 
				
			||||||
        low = q['low']
 | 
					 | 
				
			||||||
        close = q['close']
 | 
					 | 
				
			||||||
        # index = float64(q[index_field])
 | 
					 | 
				
			||||||
        index = float64(q['index'])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        istart = i * 6
 | 
					 | 
				
			||||||
        istop = istart + 6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # x,y detail the 6 points which connect all vertexes of a ohlc bar
 | 
					 | 
				
			||||||
        x[istart:istop] = (
 | 
					 | 
				
			||||||
            index - bar_gap,
 | 
					 | 
				
			||||||
            index,
 | 
					 | 
				
			||||||
            index,
 | 
					 | 
				
			||||||
            index,
 | 
					 | 
				
			||||||
            index,
 | 
					 | 
				
			||||||
            index + bar_gap,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        y[istart:istop] = (
 | 
					 | 
				
			||||||
            open,
 | 
					 | 
				
			||||||
            open,
 | 
					 | 
				
			||||||
            low,
 | 
					 | 
				
			||||||
            high,
 | 
					 | 
				
			||||||
            close,
 | 
					 | 
				
			||||||
            close,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # specifies that the first edge is never connected to the
 | 
					 | 
				
			||||||
        # prior bars last edge thus providing a small "gap"/"space"
 | 
					 | 
				
			||||||
        # between bars determined by ``bar_gap``.
 | 
					 | 
				
			||||||
        c[istart:istop] = (1, 1, 1, 1, 1, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return x, y, c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class IncrementalFormatter(msgspec.Struct):
 | 
					class IncrementalFormatter(msgspec.Struct):
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    Incrementally updating, pre-path-graphics tracking, formatter.
 | 
					    Incrementally updating, pre-path-graphics tracking, formatter.
 | 
				
			||||||
| 
						 | 
					@ -652,7 +521,6 @@ class OHLCBarsFmtr(IncrementalFormatter):
 | 
				
			||||||
            new_y_nd.shape,
 | 
					            new_y_nd.shape,
 | 
				
			||||||
        ) + np.array([-0.5, 0, 0, 0.5])
 | 
					        ) + np.array([-0.5, 0, 0, 0.5])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    # TODO: can we drop this frame and just use the above?
 | 
					    # TODO: can we drop this frame and just use the above?
 | 
				
			||||||
    def format_xy_nd_to_1d(
 | 
					    def format_xy_nd_to_1d(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,155 @@
 | 
				
			||||||
 | 
					# piker: trading gear for hackers
 | 
				
			||||||
 | 
					# Copyright (C) 2018-present  Tyler Goodlet (in stewardship of piker0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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/>.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Super fast ``QPainterPath`` generation related operator routines.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					import numpy as np
 | 
				
			||||||
 | 
					from numba import (
 | 
				
			||||||
 | 
					    # types,
 | 
				
			||||||
 | 
					    njit,
 | 
				
			||||||
 | 
					    float64,
 | 
				
			||||||
 | 
					    int64,
 | 
				
			||||||
 | 
					    # optional,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# from ._source import numba_ohlc_dtype
 | 
				
			||||||
 | 
					from ._compression import (
 | 
				
			||||||
 | 
					    ds_m4,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def xy_downsample(
 | 
				
			||||||
 | 
					    x,
 | 
				
			||||||
 | 
					    y,
 | 
				
			||||||
 | 
					    uppx,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x_spacer: float = 0.5,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					) -> tuple[
 | 
				
			||||||
 | 
					    np.ndarray,
 | 
				
			||||||
 | 
					    np.ndarray,
 | 
				
			||||||
 | 
					    float,
 | 
				
			||||||
 | 
					    float,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Downsample 1D (flat ``numpy.ndarray``) arrays using M4 given an input
 | 
				
			||||||
 | 
					    ``uppx`` (units-per-pixel) and add space between discreet datums.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    # downsample whenever more then 1 pixels per datum can be shown.
 | 
				
			||||||
 | 
					    # always refresh data bounds until we get diffing
 | 
				
			||||||
 | 
					    # working properly, see above..
 | 
				
			||||||
 | 
					    bins, x, y, ymn, ymx = ds_m4(
 | 
				
			||||||
 | 
					        x,
 | 
				
			||||||
 | 
					        y,
 | 
				
			||||||
 | 
					        uppx,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # flatten output to 1d arrays suitable for path-graphics generation.
 | 
				
			||||||
 | 
					    x = np.broadcast_to(x[:, None], y.shape)
 | 
				
			||||||
 | 
					    x = (x + np.array(
 | 
				
			||||||
 | 
					        [-x_spacer, 0, 0, x_spacer]
 | 
				
			||||||
 | 
					    )).flatten()
 | 
				
			||||||
 | 
					    y = y.flatten()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x, y, ymn, ymx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@njit(
 | 
				
			||||||
 | 
					    # NOTE: need to construct this manually for readonly
 | 
				
			||||||
 | 
					    # arrays, see https://github.com/numba/numba/issues/4511
 | 
				
			||||||
 | 
					    # (
 | 
				
			||||||
 | 
					    #     types.Array(
 | 
				
			||||||
 | 
					    #         numba_ohlc_dtype,
 | 
				
			||||||
 | 
					    #         1,
 | 
				
			||||||
 | 
					    #         'C',
 | 
				
			||||||
 | 
					    #         readonly=True,
 | 
				
			||||||
 | 
					    #     ),
 | 
				
			||||||
 | 
					    #     int64,
 | 
				
			||||||
 | 
					    #     types.unicode_type,
 | 
				
			||||||
 | 
					    #     optional(float64),
 | 
				
			||||||
 | 
					    # ),
 | 
				
			||||||
 | 
					    nogil=True
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					def path_arrays_from_ohlc(
 | 
				
			||||||
 | 
					    data: np.ndarray,
 | 
				
			||||||
 | 
					    start: int64,
 | 
				
			||||||
 | 
					    bar_gap: float64 = 0.43,
 | 
				
			||||||
 | 
					    # index_field: str,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					) -> tuple[
 | 
				
			||||||
 | 
					    np.ndarray,
 | 
				
			||||||
 | 
					    np.ndarray,
 | 
				
			||||||
 | 
					    np.ndarray,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Generate an array of lines objects from input ohlc data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    size = int(data.shape[0] * 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # XXX: see this for why the dtype might have to be defined outside
 | 
				
			||||||
 | 
					    # the routine.
 | 
				
			||||||
 | 
					    # https://github.com/numba/numba/issues/4098#issuecomment-493914533
 | 
				
			||||||
 | 
					    x = np.zeros(
 | 
				
			||||||
 | 
					        shape=size,
 | 
				
			||||||
 | 
					        dtype=float64,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    y, c = x.copy(), x.copy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # TODO: report bug for assert @
 | 
				
			||||||
 | 
					    # /home/goodboy/repos/piker/env/lib/python3.8/site-packages/numba/core/typing/builtins.py:991
 | 
				
			||||||
 | 
					    for i, q in enumerate(data[start:], start):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # TODO: ask numba why this doesn't work..
 | 
				
			||||||
 | 
					        # open, high, low, close, index = q[
 | 
				
			||||||
 | 
					        #     ['open', 'high', 'low', 'close', 'index']]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        open = q['open']
 | 
				
			||||||
 | 
					        high = q['high']
 | 
				
			||||||
 | 
					        low = q['low']
 | 
				
			||||||
 | 
					        close = q['close']
 | 
				
			||||||
 | 
					        # index = float64(q[index_field])
 | 
				
			||||||
 | 
					        index = float64(q['index'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        istart = i * 6
 | 
				
			||||||
 | 
					        istop = istart + 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # x,y detail the 6 points which connect all vertexes of a ohlc bar
 | 
				
			||||||
 | 
					        x[istart:istop] = (
 | 
				
			||||||
 | 
					            index - bar_gap,
 | 
				
			||||||
 | 
					            index,
 | 
				
			||||||
 | 
					            index,
 | 
				
			||||||
 | 
					            index,
 | 
				
			||||||
 | 
					            index,
 | 
				
			||||||
 | 
					            index + bar_gap,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        y[istart:istop] = (
 | 
				
			||||||
 | 
					            open,
 | 
				
			||||||
 | 
					            open,
 | 
				
			||||||
 | 
					            low,
 | 
				
			||||||
 | 
					            high,
 | 
				
			||||||
 | 
					            close,
 | 
				
			||||||
 | 
					            close,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # specifies that the first edge is never connected to the
 | 
				
			||||||
 | 
					        # prior bars last edge thus providing a small "gap"/"space"
 | 
				
			||||||
 | 
					        # between bars determined by ``bar_gap``.
 | 
				
			||||||
 | 
					        c[istart:istop] = (1, 1, 1, 1, 1, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x, y, c
 | 
				
			||||||
| 
						 | 
					@ -42,8 +42,8 @@ from ..data._formatters import (
 | 
				
			||||||
    OHLCBarsFmtr,  # Plain OHLC renderer
 | 
					    OHLCBarsFmtr,  # Plain OHLC renderer
 | 
				
			||||||
    OHLCBarsAsCurveFmtr,  # OHLC converted to line
 | 
					    OHLCBarsAsCurveFmtr,  # OHLC converted to line
 | 
				
			||||||
    StepCurveFmtr,  # "step" curve (like for vlm)
 | 
					    StepCurveFmtr,  # "step" curve (like for vlm)
 | 
				
			||||||
    xy_downsample,
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from ..data._pathops import xy_downsample
 | 
				
			||||||
from .._profile import (
 | 
					from .._profile import (
 | 
				
			||||||
    pg_profile_enabled,
 | 
					    pg_profile_enabled,
 | 
				
			||||||
    # ms_slower_then,
 | 
					    # ms_slower_then,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue