Add a pyqtgraph profiling toggle to chart CLI

chart_trader
Tyler Goodlet 2020-12-29 10:15:38 -05:00
parent a68fff4139
commit 98c3bb8aee
6 changed files with 29 additions and 15 deletions

View File

@ -1,5 +1,5 @@
# piker: trading gear for hackers. # piker: trading gear for hackers.
# Copyright 2018 Tyler Goodlet # Copyright 2020-eternity Tyler Goodlet (in stewardship for piker0)
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU Affero General Public License as published by
@ -16,6 +16,7 @@
""" """
piker: trading gear for hackers. piker: trading gear for hackers.
""" """
import msgpack # noqa import msgpack # noqa
import msgpack_numpy import msgpack_numpy

View File

@ -16,10 +16,18 @@
""" """
Profiling wrappers for internal libs. Profiling wrappers for internal libs.
""" """
import time import time
from functools import wraps from functools import wraps
_pg_profile: bool = False
def pg_profile_enabled() -> bool:
global _pg_profile
return _pg_profile
def timeit(fn): def timeit(fn):
@wraps(fn) @wraps(fn)

View File

@ -1068,7 +1068,6 @@ async def chart_from_quotes(
mn_in_view = min(price, mn_in_view) mn_in_view = min(price, mn_in_view)
if mx_in_view > last_mx or mn_in_view < last_mn: if mx_in_view > last_mx or mn_in_view < last_mn:
print('scaling')
chart._set_yrange(yrange=(mn_in_view, mx_in_view)) chart._set_yrange(yrange=(mn_in_view, mx_in_view))
last_mx, last_mn = mx_in_view, mn_in_view last_mx, last_mn = mx_in_view, mn_in_view

View File

@ -22,6 +22,8 @@ from typing import Tuple
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
from ..._profile import pg_profile_enabled
class FastAppendCurve(pg.PlotCurveItem): class FastAppendCurve(pg.PlotCurveItem):
@ -46,7 +48,7 @@ class FastAppendCurve(pg.PlotCurveItem):
y, y,
) -> QtGui.QPainterPath: ) -> QtGui.QPainterPath:
profiler = pg.debug.Profiler(disabled=True) profiler = pg.debug.Profiler(disabled=not pg_profile_enabled())
flip_cache = False flip_cache = False
# print(f"xrange: {self._xrange}") # print(f"xrange: {self._xrange}")
@ -139,7 +141,7 @@ class FastAppendCurve(pg.PlotCurveItem):
def paint(self, p, opt, widget): def paint(self, p, opt, widget):
profiler = pg.debug.Profiler(disabled=True) profiler = pg.debug.Profiler(disabled=not pg_profile_enabled())
# p.setRenderHint(p.Antialiasing, True) # p.setRenderHint(p.Antialiasing, True)
p.setPen(self.opts['pen']) p.setPen(self.opts['pen'])

View File

@ -25,9 +25,9 @@ from numba import jit, float64, int64 # , optional
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QLineF, QPointF from PyQt5.QtCore import QLineF, QPointF
# from numba import types as ntypes # from numba import types as ntypes
# from .._profile import timeit
# from ..data._source import numba_ohlc_dtype # from ..data._source import numba_ohlc_dtype
from ..._profile import pg_profile_enabled
from .._style import hcolor from .._style import hcolor
@ -141,14 +141,13 @@ def path_arrays_from_ohlc(
return x, y, c return x, y, c
# @timeit
def gen_qpath( def gen_qpath(
data, data,
start, # XXX: do we need this? start, # XXX: do we need this?
w, w,
) -> QtGui.QPainterPath: ) -> QtGui.QPainterPath:
profiler = pg.debug.Profiler(disabled=True) profiler = pg.debug.Profiler(disabled=not pg_profile_enabled())
x, y, c = path_arrays_from_ohlc(data, start, bar_gap=w) x, y, c = path_arrays_from_ohlc(data, start, bar_gap=w)
profiler("generate stream with numba") profiler("generate stream with numba")
@ -207,7 +206,6 @@ class BarItems(pg.GraphicsObject):
self.start_index: int = 0 self.start_index: int = 0
self.stop_index: int = 0 self.stop_index: int = 0
# @timeit
def draw_from_data( def draw_from_data(
self, self,
data: np.ndarray, data: np.ndarray,
@ -238,7 +236,6 @@ class BarItems(pg.GraphicsObject):
return self.path return self.path
# @timeit
def update_from_array( def update_from_array(
self, self,
array: np.ndarray, array: np.ndarray,
@ -342,10 +339,9 @@ class BarItems(pg.GraphicsObject):
if flip_cache: if flip_cache:
self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache) self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache)
# @timeit
def paint(self, p, opt, widget): def paint(self, p, opt, widget):
profiler = pg.debug.Profiler(disabled=False) # , delayed=False) profiler = pg.debug.Profiler(disabled=not pg_profile_enabled()) # , delayed=False)
# p.setCompositionMode(0) # p.setCompositionMode(0)
p.setPen(self.bars_pen) p.setPen(self.bars_pen)
@ -362,7 +358,6 @@ class BarItems(pg.GraphicsObject):
p.drawPath(self.path) p.drawPath(self.path)
profiler('draw history path') profiler('draw history path')
# @timeit
def boundingRect(self): def boundingRect(self):
# Qt docs: https://doc.qt.io/qt-5/qgraphicsitem.html#boundingRect # Qt docs: https://doc.qt.io/qt-5/qgraphicsitem.html#boundingRect

View File

@ -84,7 +84,7 @@ def monitor(config, rate, name, dhost, test, tl):
@cli.command() @cli.command()
@click.option('--tl', is_flag=True, help='Enable tractor logging') # @click.option('--tl', is_flag=True, help='Enable tractor logging')
@click.option('--date', '-d', help='Contracts expiry date') @click.option('--date', '-d', help='Contracts expiry date')
@click.option('--test', '-t', help='Test quote stream file') @click.option('--test', '-t', help='Test quote stream file')
@click.option('--rate', '-r', default=1, help='Logging level') @click.option('--rate', '-r', default=1, help='Logging level')
@ -121,16 +121,25 @@ def optschain(config, symbol, date, tl, rate, test):
@cli.command() @cli.command()
@click.option(
'--profile',
is_flag=True,
help='Enable pyqtgraph profiling'
)
@click.option('--date', '-d', help='Contracts expiry date') @click.option('--date', '-d', help='Contracts expiry date')
@click.option('--test', '-t', help='Test quote stream file') @click.option('--test', '-t', help='Test quote stream file')
@click.option('--rate', '-r', default=1, help='Logging level') @click.option('--rate', '-r', default=1, help='Logging level')
@click.argument('symbol', required=True) @click.argument('symbol', required=True)
@click.pass_obj @click.pass_obj
def chart(config, symbol, date, rate, test): def chart(config, symbol, date, rate, test, profile):
"""Start an option chain UI """Start a real-time chartng UI
""" """
from .. import _profile
from ._chart import _main from ._chart import _main
# possibly enable profiling
_profile._pg_profile = profile
# global opts # global opts
brokername = config['broker'] brokername = config['broker']
tractorloglevel = config['tractorloglevel'] tractorloglevel = config['tractorloglevel']