Port all `.ui*` submods to new `.ui.qt` imports
This also officially moves the code base to using `PyQt6` including all necessary reference changes and enum namespace path moves. Also includes a small `.ui.order_mode` fix to cancel any `Order.price <= 0` and a name error fix with logging using `msg`, which is already used for the input order msg..pyqt6
							parent
							
								
									d0170982bf
								
							
						
					
					
						commit
						1fd8654ca5
					
				|  | @ -14,9 +14,8 @@ | |||
| # 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/>. | ||||
| 
 | ||||
| """ | ||||
| Stuff for your eyes, aka super hawt Qt UI components. | ||||
| ''' | ||||
| UI components built using `Qt` with major versions swapped in via | ||||
| the import indirection in the `.qt` sub-mod. | ||||
| 
 | ||||
| Currently we only support PyQt5 due to this issue in Pyside2: | ||||
| https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1313 | ||||
| """ | ||||
| ''' | ||||
|  |  | |||
|  | @ -21,8 +21,10 @@ Anchor funtions for UI placement of annotions. | |||
| from __future__ import annotations | ||||
| from typing import Callable, TYPE_CHECKING | ||||
| 
 | ||||
| from PyQt5.QtCore import QPointF | ||||
| from PyQt5.QtWidgets import QGraphicsPathItem | ||||
| from piker.ui.qt import ( | ||||
|     QPointF, | ||||
|     QGraphicsPathItem, | ||||
| ) | ||||
| 
 | ||||
| if TYPE_CHECKING: | ||||
|     from ._chart import ChartPlotWidget | ||||
|  |  | |||
|  | @ -20,12 +20,22 @@ Annotations for ur faces. | |||
| """ | ||||
| from typing import Callable | ||||
| 
 | ||||
| from PyQt5 import QtCore, QtGui, QtWidgets | ||||
| from PyQt5.QtCore import QPointF, QRectF | ||||
| from PyQt5.QtWidgets import QGraphicsPathItem | ||||
| from pyqtgraph import Point, functions as fn, Color | ||||
| from pyqtgraph import ( | ||||
|     Point, | ||||
|     functions as fn, | ||||
|     Color, | ||||
| ) | ||||
| import numpy as np | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QtCore, | ||||
|     QtGui, | ||||
|     QtWidgets, | ||||
|     QPointF, | ||||
|     QRectF, | ||||
|     QGraphicsPathItem, | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| def mk_marker_path( | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,9 +21,11 @@ Main app startup and run. | |||
| from functools import partial | ||||
| from types import ModuleType | ||||
| 
 | ||||
| from PyQt5.QtCore import QEvent | ||||
| import trio | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QEvent, | ||||
| ) | ||||
| from ..service import maybe_spawn_brokerd | ||||
| from . import _event | ||||
| from ._exec import run_qtractor | ||||
|  |  | |||
|  | @ -25,9 +25,16 @@ from math import floor | |||
| 
 | ||||
| import polars as pl | ||||
| import pyqtgraph as pg | ||||
| from PyQt5 import QtCore, QtGui, QtWidgets | ||||
| from PyQt5.QtCore import QPointF | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QtCore, | ||||
|     QtGui, | ||||
|     QtWidgets, | ||||
|     QPointF, | ||||
|     txt_flag, | ||||
|     align_flag, | ||||
|     px_cache_mode, | ||||
| ) | ||||
| from . import _pg_overrides as pgo | ||||
| from ..accounting._mktinfo import float_digits | ||||
| from ._label import Label | ||||
|  | @ -414,11 +421,15 @@ class AxisLabel(pg.GraphicsObject): | |||
|         super().__init__() | ||||
|         self.setParentItem(parent) | ||||
| 
 | ||||
|         self.setFlag(self.ItemIgnoresTransformations) | ||||
|         self.setFlag( | ||||
|             self.GraphicsItemFlag.ItemIgnoresTransformations | ||||
|         ) | ||||
|         self.setZValue(100) | ||||
| 
 | ||||
|         # XXX: pretty sure this is faster | ||||
|         self.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) | ||||
|         self.setCacheMode( | ||||
|             px_cache_mode.DeviceCoordinateCache | ||||
|         ) | ||||
| 
 | ||||
|         self._parent = parent | ||||
| 
 | ||||
|  | @ -555,21 +566,14 @@ class AxisLabel(pg.GraphicsObject): | |||
| 
 | ||||
|         return (self.rect.width(), self.rect.height()) | ||||
| 
 | ||||
| # _common_text_flags = ( | ||||
| #     QtCore.Qt.TextDontClip | | ||||
| #     QtCore.Qt.AlignCenter | | ||||
| #     QtCore.Qt.AlignTop | | ||||
| #     QtCore.Qt.AlignHCenter | | ||||
| #     QtCore.Qt.AlignVCenter | ||||
| # ) | ||||
| 
 | ||||
| 
 | ||||
| class XAxisLabel(AxisLabel): | ||||
|     _x_margin = 8 | ||||
| 
 | ||||
|     text_flags = ( | ||||
|         QtCore.Qt.TextDontClip | ||||
|         | QtCore.Qt.AlignCenter | ||||
|         align_flag.AlignCenter | ||||
|         | txt_flag.TextDontClip | ||||
|     ) | ||||
| 
 | ||||
|     def size_hint(self) -> tuple[float, float]: | ||||
|  | @ -626,10 +630,10 @@ class YAxisLabel(AxisLabel): | |||
|     _y_margin: int = 4 | ||||
| 
 | ||||
|     text_flags = ( | ||||
|         QtCore.Qt.AlignLeft | ||||
|         # QtCore.Qt.AlignHCenter | ||||
|         | QtCore.Qt.AlignVCenter | ||||
|         | QtCore.Qt.TextDontClip | ||||
|         align_flag.AlignLeft | ||||
|         | align_flag.AlignVCenter | ||||
|         # | align_flag.AlignHCenter | ||||
|         | txt_flag.TextDontClip | ||||
|     ) | ||||
| 
 | ||||
|     def __init__( | ||||
|  |  | |||
|  | @ -28,22 +28,20 @@ from typing import ( | |||
|     TYPE_CHECKING, | ||||
| ) | ||||
| 
 | ||||
| from PyQt5 import QtCore, QtWidgets | ||||
| from PyQt5.QtCore import ( | ||||
| import pyqtgraph as pg | ||||
| import trio | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QtCore, | ||||
|     QtWidgets, | ||||
|     Qt, | ||||
|     QLineF, | ||||
|     # QPointF, | ||||
| ) | ||||
| from PyQt5.QtWidgets import ( | ||||
|     QFrame, | ||||
|     QWidget, | ||||
|     QHBoxLayout, | ||||
|     QVBoxLayout, | ||||
|     QSplitter, | ||||
| ) | ||||
| import pyqtgraph as pg | ||||
| import trio | ||||
| 
 | ||||
| from ._axes import ( | ||||
|     DynamicDateAxis, | ||||
|     PriceAxis, | ||||
|  | @ -570,8 +568,8 @@ class LinkedSplits(QWidget): | |||
| 
 | ||||
|         # style? | ||||
|         self.chart.setFrameStyle( | ||||
|             QFrame.StyledPanel | | ||||
|             QFrame.Plain | ||||
|             QFrame.Shape.StyledPanel | | ||||
|             QFrame.Shadow.Plain | ||||
|         ) | ||||
| 
 | ||||
|         return self.chart | ||||
|  | @ -689,8 +687,8 @@ class LinkedSplits(QWidget): | |||
| 
 | ||||
|         cpw.plotItem.vb.linked = self | ||||
|         cpw.setFrameStyle( | ||||
|             QtWidgets.QFrame.StyledPanel | ||||
|             # | QtWidgets.QFrame.Plain | ||||
|             QFrame.Shape.StyledPanel | ||||
|             # | QFrame.Shadow.Plain | ||||
|         ) | ||||
| 
 | ||||
|         # don't show the little "autoscale" A label. | ||||
|  |  | |||
|  | @ -28,9 +28,14 @@ from typing import ( | |||
| import inspect | ||||
| import numpy as np | ||||
| import pyqtgraph as pg | ||||
| from PyQt5 import QtCore, QtWidgets | ||||
| from PyQt5.QtCore import QPointF, QRectF | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QPointF, | ||||
|     QRectF, | ||||
|     QtCore, | ||||
|     QtWidgets, | ||||
|     px_cache_mode, | ||||
| ) | ||||
| from ._style import ( | ||||
|     _xaxis_at, | ||||
|     hcolor, | ||||
|  | @ -104,7 +109,9 @@ class LineDot(pg.CurvePoint): | |||
|         dot.setParentItem(self) | ||||
| 
 | ||||
|         # keep a static size | ||||
|         self.setFlag(self.ItemIgnoresTransformations) | ||||
|         self.setFlag( | ||||
|             self.GraphicsItemFlag.ItemIgnoresTransformations | ||||
|         ) | ||||
| 
 | ||||
|     def event( | ||||
|         self, | ||||
|  | @ -424,10 +431,10 @@ class Cursor(pg.GraphicsObject): | |||
|         # vertical and horizonal lines and a y-axis label | ||||
| 
 | ||||
|         vl = plot.addLine(x=0, pen=self.lines_pen, movable=False) | ||||
|         vl.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) | ||||
|         vl.setCacheMode(px_cache_mode.DeviceCoordinateCache) | ||||
| 
 | ||||
|         hl = plot.addLine(y=0, pen=self.lines_pen, movable=False) | ||||
|         hl.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) | ||||
|         hl.setCacheMode(px_cache_mode.DeviceCoordinateCache) | ||||
|         hl.hide() | ||||
| 
 | ||||
|         yl = YAxisLabel( | ||||
|  | @ -511,7 +518,10 @@ class Cursor(pg.GraphicsObject): | |||
|             plot=chart | ||||
|         ) | ||||
|         chart.addItem(cursor) | ||||
|         self.graphics[chart].setdefault('cursors', []).append(cursor) | ||||
|         self.graphics[chart].setdefault( | ||||
|             'cursors', | ||||
|             [], | ||||
|         ).append(cursor) | ||||
|         return cursor | ||||
| 
 | ||||
|     def mouseAction( | ||||
|  |  | |||
|  | @ -19,20 +19,21 @@ Fast, smooth, sexy curves. | |||
| 
 | ||||
| """ | ||||
| from contextlib import contextmanager as cm | ||||
| from enum import EnumType | ||||
| from typing import Callable | ||||
| 
 | ||||
| import numpy as np | ||||
| import pyqtgraph as pg | ||||
| from PyQt5 import QtWidgets | ||||
| from PyQt5.QtWidgets import QGraphicsItem | ||||
| from PyQt5.QtCore import ( | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QtWidgets, | ||||
|     QGraphicsItem, | ||||
|     Qt, | ||||
|     QLineF, | ||||
|     QRectF, | ||||
| ) | ||||
| from PyQt5.QtGui import ( | ||||
|     QPainter, | ||||
|     QPainterPath, | ||||
|     px_cache_mode, | ||||
| ) | ||||
| from ._style import hcolor | ||||
| from ..log import get_logger | ||||
|  | @ -42,15 +43,16 @@ from ..toolz.profile import ( | |||
|     ms_slower_then, | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| log = get_logger(__name__) | ||||
| 
 | ||||
| 
 | ||||
| pen_style: EnumType = Qt.PenStyle | ||||
| 
 | ||||
| _line_styles: dict[str, int] = { | ||||
|     'solid': Qt.PenStyle.SolidLine, | ||||
|     'dash': Qt.PenStyle.DashLine, | ||||
|     'dot': Qt.PenStyle.DotLine, | ||||
|     'dashdot': Qt.PenStyle.DashDotLine, | ||||
|     'solid': pen_style.SolidLine, | ||||
|     'dash': pen_style.DashLine, | ||||
|     'dot': pen_style.DotLine, | ||||
|     'dashdot': pen_style.DashDotLine, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -69,12 +71,12 @@ class FlowGraphic(pg.GraphicsObject): | |||
|     # XXX-NOTE-XXX: graphics caching B) | ||||
|     # see explanation for different caching modes: | ||||
|     # https://stackoverflow.com/a/39410081 | ||||
|     cache_mode: int = QGraphicsItem.DeviceCoordinateCache | ||||
|     cache_mode: int = px_cache_mode.DeviceCoordinateCache | ||||
|     # XXX: WARNING item caching seems to only be useful | ||||
|     # if we don't re-generate the entire QPainterPath every time | ||||
|     # don't ever use this - it's a colossal nightmare of artefacts | ||||
|     # and is disastrous for performance. | ||||
|     # QGraphicsItem.ItemCoordinateCache | ||||
|     # cache_mode.ItemCoordinateCache | ||||
|     # TODO: still questions todo with coord-cacheing that we should | ||||
|     # probably talk to a core dev about: | ||||
|     # - if this makes trasform interactions slower (such as zooming) | ||||
|  | @ -176,7 +178,7 @@ class FlowGraphic(pg.GraphicsObject): | |||
|     @cm | ||||
|     def reset_cache(self) -> None: | ||||
|         try: | ||||
|             none = QGraphicsItem.NoCache | ||||
|             none = px_cache_mode.NoCache | ||||
|             log.debug( | ||||
|                 f'{self._name} -> CACHE DISABLE: {none}' | ||||
|             ) | ||||
|  |  | |||
|  | @ -40,8 +40,8 @@ from numpy import ( | |||
|     ndarray, | ||||
| ) | ||||
| import pyqtgraph as pg | ||||
| from PyQt5.QtCore import QLineF | ||||
| 
 | ||||
| from piker.ui.qt import QLineF | ||||
| from ..data._sharedmem import ( | ||||
|     ShmArray, | ||||
| ) | ||||
|  |  | |||
|  | @ -57,6 +57,7 @@ from piker.toolz import ( | |||
|     Profiler, | ||||
| ) | ||||
| from piker.log import get_logger | ||||
| from piker import config | ||||
| # from ..data._source import tf_in_1s | ||||
| from ._axes import YAxisLabel | ||||
| from ._chart import ( | ||||
|  | @ -1231,6 +1232,8 @@ async def link_views_with_region( | |||
|     # region.sigRegionChangeFinished.connect(update_pi_from_region) | ||||
| 
 | ||||
| 
 | ||||
| # NOTE: default is set to 60 FPS until the runtime delivers the | ||||
| # discoverd hw value below. | ||||
| _quote_throttle_rate: int = 60 - 6 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1272,26 +1275,54 @@ async def display_symbol_data( | |||
|     # TODO: ctl over update loop's maximum frequency. | ||||
|     # - load this from a config.toml! | ||||
|     # - allow dyanmic configuration from chart UI? | ||||
|     ( | ||||
|         conf, | ||||
|         path, | ||||
|     ) = config.load() | ||||
|     ui_conf: dict = conf['ui'] | ||||
| 
 | ||||
|     global _quote_throttle_rate | ||||
|     from ._window import main_window | ||||
|     display_rate = main_window().current_screen().refreshRate() | ||||
|     _quote_throttle_rate = floor(display_rate) - 6 | ||||
| 
 | ||||
|     display_rate: int = floor( | ||||
|         main_window().current_screen().refreshRate() | ||||
|     ) - 6 | ||||
| 
 | ||||
|     mx_redraw_rate: int = ui_conf.get( | ||||
|         'max_redraw_rate', | ||||
|         _quote_throttle_rate, | ||||
|     ) | ||||
| 
 | ||||
|     if mx_redraw_rate < display_rate: | ||||
|         log.info( | ||||
|             'Down-throttling redraw rate to config setting\n' | ||||
|             f'display FPS: {display_rate}\n' | ||||
|             'max_redraw_rate: {max_redraw_rate}\n' | ||||
|         ) | ||||
|     else: | ||||
|         _quote_throttle_rate = display_rate | ||||
| 
 | ||||
|     # TODO: we should be able to increase this if we use some | ||||
|     # `mypyc` speedups elsewhere? 22ish seems to be the sweet | ||||
|     # spot for single-feed chart. | ||||
|     num_of_feeds = len(fqmes) | ||||
|     mx: int = 22 | ||||
|     if num_of_feeds > 1: | ||||
|         # there will be more ctx switches with more than 1 feed so we | ||||
|         # max throttle down a bit more. | ||||
|         mx = 16 | ||||
|     # if num_of_feeds > 1: | ||||
| 
 | ||||
|     # there will be more ctx switches with more than 1 feed so we | ||||
|     # max throttle down a bit more. | ||||
|     mx_per_feed: int = ( | ||||
|         ui_conf.get( | ||||
|         'per_feed_redraw_rate', | ||||
|         mx_redraw_rate, | ||||
|         ) | ||||
|         or 16 | ||||
|     ) | ||||
| 
 | ||||
|     # limit to at least display's FPS | ||||
|     # avoiding needless Qt-in-guest-mode context switches | ||||
|     cycles_per_feed = min( | ||||
|         round(_quote_throttle_rate/num_of_feeds), | ||||
|         mx, | ||||
|         mx_per_feed, | ||||
|     ) | ||||
| 
 | ||||
|     feed: Feed | ||||
|  |  | |||
|  | @ -32,24 +32,21 @@ from pyqtgraph import ( | |||
|     QtCore, | ||||
|     QtWidgets, | ||||
| ) | ||||
| from PyQt5.QtCore import ( | ||||
|     QPointF, | ||||
|     QRectF, | ||||
| ) | ||||
| from PyQt5.QtGui import ( | ||||
|     QColor, | ||||
|     QTransform, | ||||
| ) | ||||
| from PyQt5.QtWidgets import ( | ||||
|     QGraphicsProxyWidget, | ||||
|     QGraphicsScene, | ||||
|     QLabel, | ||||
| ) | ||||
| 
 | ||||
| from pyqtgraph import functions as fn | ||||
| import numpy as np | ||||
| 
 | ||||
| from piker.types import Struct | ||||
| from piker.ui.qt import ( | ||||
|     Qt, | ||||
|     QPointF, | ||||
|     QRectF, | ||||
|     QGraphicsProxyWidget, | ||||
|     QGraphicsScene, | ||||
|     QLabel, | ||||
|     QColor, | ||||
|     QTransform, | ||||
| ) | ||||
| from ._style import ( | ||||
|     hcolor, | ||||
|     _font, | ||||
|  | @ -316,7 +313,9 @@ class SelectRect(QtWidgets.QGraphicsRectItem): | |||
|         self.setZValue(1e9) | ||||
| 
 | ||||
|         label = self._label = QLabel() | ||||
|         label.setTextFormat(0)  # markdown | ||||
|         label.setTextFormat( | ||||
|             Qt.TextFormat.MarkdownText | ||||
|         ) | ||||
|         label.setFont(_font.font) | ||||
|         label.setMargin(0) | ||||
|         label.setAlignment( | ||||
|  |  | |||
|  | @ -23,28 +23,29 @@ from typing import Callable | |||
| 
 | ||||
| import trio | ||||
| from tractor.trionics import gather_contexts | ||||
| from PyQt5 import QtCore | ||||
| from PyQt5.QtCore import QEvent, pyqtBoundSignal | ||||
| from PyQt5.QtWidgets import QWidget | ||||
| from PyQt5.QtWidgets import ( | ||||
|     QGraphicsSceneMouseEvent as gs_mouse, | ||||
| ) | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QtCore, | ||||
|     QWidget, | ||||
|     QEvent, | ||||
|     keys, | ||||
|     gs_keys, | ||||
|     pyqtBoundSignal, | ||||
| ) | ||||
| from piker.types import Struct | ||||
| 
 | ||||
| 
 | ||||
| MOUSE_EVENTS = { | ||||
|     gs_mouse.GraphicsSceneMousePress, | ||||
|     gs_mouse.GraphicsSceneMouseRelease, | ||||
|     QEvent.MouseButtonPress, | ||||
|     QEvent.MouseButtonRelease, | ||||
|     gs_keys.GraphicsSceneMousePress, | ||||
|     gs_keys.GraphicsSceneMouseRelease, | ||||
|     keys.MouseButtonPress, | ||||
|     keys.MouseButtonRelease, | ||||
|     # QtGui.QMouseEvent, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| # TODO: maybe consider some constrained ints down the road? | ||||
| # https://pydantic-docs.helpmanual.io/usage/types/#constrained-types | ||||
| 
 | ||||
| class KeyboardMsg(Struct): | ||||
|     '''Unpacked Qt keyboard event data. | ||||
| 
 | ||||
|  | @ -114,7 +115,10 @@ class EventRelay(QtCore.QObject): | |||
|         # something to do with Qt internals and calling the | ||||
|         # parent handler? | ||||
| 
 | ||||
|         if etype in {QEvent.KeyPress, QEvent.KeyRelease}: | ||||
|         if etype in { | ||||
|             QEvent.Type.KeyPress, | ||||
|             QEvent.Type.KeyRelease, | ||||
|         }: | ||||
| 
 | ||||
|             msg = KeyboardMsg( | ||||
|                 event=ev, | ||||
|  | @ -160,7 +164,9 @@ class EventRelay(QtCore.QObject): | |||
| async def open_event_stream( | ||||
| 
 | ||||
|     source_widget: QWidget, | ||||
|     event_types: set[QEvent] = {QEvent.KeyPress}, | ||||
|     event_types: set[QEvent] = { | ||||
|         QEvent.Type.KeyPress, | ||||
|     }, | ||||
|     filter_auto_repeats: bool = True, | ||||
| 
 | ||||
| ) -> trio.abc.ReceiveChannel: | ||||
|  |  | |||
|  | @ -30,25 +30,22 @@ from typing import ( | |||
| import platform | ||||
| import traceback | ||||
| 
 | ||||
| # Qt specific | ||||
| import PyQt5  # noqa | ||||
| from PyQt5.QtWidgets import ( | ||||
|     QWidget, | ||||
|     QMainWindow, | ||||
|     QApplication, | ||||
| ) | ||||
| from PyQt5 import QtCore | ||||
| from PyQt5.QtCore import ( | ||||
|     pyqtRemoveInputHook, | ||||
|     Qt, | ||||
|     QCoreApplication, | ||||
| ) | ||||
| import qdarkstyle | ||||
| from qdarkstyle import DarkPalette | ||||
| # import qdarkgraystyle  # TODO: play with it | ||||
| import trio | ||||
| from outcome import Error | ||||
| 
 | ||||
| # Qt version-agnostic | ||||
| from .qt import ( | ||||
|     QWidget, | ||||
|     QMainWindow, | ||||
|     QApplication, | ||||
|     QtCore, | ||||
|     pyqtRemoveInputHook, | ||||
|     Qt, | ||||
|     QCoreApplication, | ||||
| ) | ||||
| from ..service import ( | ||||
|     maybe_open_pikerd, | ||||
|     get_runtime_vars, | ||||
|  | @ -150,7 +147,7 @@ def run_qtractor( | |||
| 
 | ||||
|     # load dark theme | ||||
|     stylesheet = qdarkstyle.load_stylesheet( | ||||
|         qt_api='pyqt5', | ||||
|         qt_api='pyqt6', | ||||
|         palette=DarkPalette, | ||||
|     ) | ||||
|     app.setStyleSheet(stylesheet) | ||||
|  |  | |||
|  | @ -28,9 +28,15 @@ from typing import ( | |||
| ) | ||||
| 
 | ||||
| import trio | ||||
| from PyQt5 import QtGui | ||||
| from PyQt5.QtCore import QSize, QModelIndex, Qt, QEvent | ||||
| from PyQt5.QtWidgets import ( | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     keys, | ||||
|     size_policy, | ||||
|     QtGui, | ||||
|     QSize, | ||||
|     QModelIndex, | ||||
|     Qt, | ||||
|     QEvent, | ||||
|     QWidget, | ||||
|     QLabel, | ||||
|     QComboBox, | ||||
|  | @ -39,7 +45,6 @@ from PyQt5.QtWidgets import ( | |||
|     QVBoxLayout, | ||||
|     QFormLayout, | ||||
|     QProgressBar, | ||||
|     QSizePolicy, | ||||
|     QStyledItemDelegate, | ||||
|     QStyleOptionViewItem, | ||||
| ) | ||||
|  | @ -71,14 +76,14 @@ class Edit(QLineEdit): | |||
| 
 | ||||
|         if width_in_chars: | ||||
|             self._chars = int(width_in_chars) | ||||
|             x_size_policy = QSizePolicy.Fixed | ||||
|             x_size_policy = size_policy.Fixed | ||||
| 
 | ||||
|         else: | ||||
|             # chart count which will be used to calculate | ||||
|             # width of input field. | ||||
|             self._chars: int = 6 | ||||
|             # fit to surroundingn frame width | ||||
|             x_size_policy = QSizePolicy.Expanding | ||||
|             x_size_policy = size_policy.Expanding | ||||
| 
 | ||||
|         super().__init__(parent) | ||||
| 
 | ||||
|  | @ -86,7 +91,7 @@ class Edit(QLineEdit): | |||
|         # https://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum | ||||
|         self.setSizePolicy( | ||||
|             x_size_policy, | ||||
|             QSizePolicy.Fixed, | ||||
|             size_policy.Fixed, | ||||
|         ) | ||||
|         self.setFont(font.font) | ||||
| 
 | ||||
|  | @ -180,11 +185,13 @@ class Selection(QComboBox): | |||
| 
 | ||||
|         self._items: dict[str, int] = {} | ||||
|         super().__init__(parent=parent) | ||||
|         self.setSizeAdjustPolicy(QComboBox.AdjustToContents) | ||||
|         self.setSizeAdjustPolicy( | ||||
|             QComboBox.SizeAdjustPolicy.AdjustToContents, | ||||
|         ) | ||||
|         # make line edit expand to surrounding frame | ||||
|         self.setSizePolicy( | ||||
|             QSizePolicy.Expanding, | ||||
|             QSizePolicy.Fixed, | ||||
|             size_policy.Expanding, | ||||
|             size_policy.Fixed, | ||||
|         ) | ||||
|         view = self.view() | ||||
|         view.setUniformItemSizes(True) | ||||
|  | @ -308,8 +315,8 @@ class FieldsForm(QWidget): | |||
| 
 | ||||
|         # size it as we specify | ||||
|         self.setSizePolicy( | ||||
|             QSizePolicy.Expanding, | ||||
|             QSizePolicy.Expanding, | ||||
|             size_policy.Expanding, | ||||
|             size_policy.Expanding, | ||||
|         ) | ||||
| 
 | ||||
|         # XXX: not sure why we have to create this here exactly | ||||
|  | @ -416,8 +423,8 @@ class FieldsForm(QWidget): | |||
|         select.set_items(values) | ||||
| 
 | ||||
|         self.setSizePolicy( | ||||
|             QSizePolicy.Fixed, | ||||
|             QSizePolicy.Fixed, | ||||
|             size_policy.Fixed, | ||||
|             size_policy.Fixed, | ||||
|         ) | ||||
|         select.show() | ||||
|         self.form.addRow(label, select) | ||||
|  | @ -437,7 +444,10 @@ async def handle_field_input( | |||
| 
 | ||||
|     async for kbmsg in recv_chan: | ||||
| 
 | ||||
|         if kbmsg.etype in {QEvent.KeyPress, QEvent.KeyRelease}: | ||||
|         if kbmsg.etype in { | ||||
|             keys.KeyPress, | ||||
|             keys.KeyRelease, | ||||
|         }: | ||||
|             event, etype, key, mods, txt = kbmsg.to_tuple() | ||||
|             print(f'key: {kbmsg.key}, mods: {kbmsg.mods}, txt: {kbmsg.txt}') | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,15 +15,18 @@ | |||
| # along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| ''' | ||||
| ``QIcon`` hackery. | ||||
| `QIcon` hackery. | ||||
| 
 | ||||
| Mostly dynamically loading pixmaps for use with `QGraphicsScene`. | ||||
| 
 | ||||
| ''' | ||||
| from PyQt5.QtWidgets import QStyle | ||||
| from PyQt5.QtGui import ( | ||||
|     QIcon, QPixmap, QColor | ||||
| from piker.ui.qt import ( | ||||
|     QSize, | ||||
|     QStyle, | ||||
|     QIcon, | ||||
|     QPixmap, | ||||
|     QColor, | ||||
| ) | ||||
| from PyQt5.QtCore import QSize | ||||
| 
 | ||||
| from ._style import hcolor | ||||
| 
 | ||||
| # https://www.pythonguis.com/faq/built-in-qicons-pyqt/ | ||||
|  | @ -44,7 +47,8 @@ def mk_icons( | |||
|     size: QSize, | ||||
| 
 | ||||
| ) -> dict[str, QIcon]: | ||||
|     '''This helper is indempotent. | ||||
|     ''' | ||||
|     This helper is indempotent. | ||||
| 
 | ||||
|     ''' | ||||
|     global _icons, _icon_names | ||||
|  | @ -56,7 +60,11 @@ def mk_icons( | |||
|     # load account selection using current style | ||||
|     for name, icon_name in _icon_names.items(): | ||||
| 
 | ||||
|         stdpixmap = getattr(QStyle, icon_name) | ||||
|         stdpixmap = getattr( | ||||
|             # https://www.pythonguis.com/faq/built-in-qicons-pyqt/ | ||||
|             QStyle.StandardPixmap,  # pyqt/pyside6 | ||||
|             icon_name, | ||||
|         ) | ||||
|         stdicon = style.standardIcon(stdpixmap) | ||||
|         pixmap = stdicon.pixmap(size) | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,23 +36,21 @@ import pyqtgraph as pg | |||
| # this down the road.. Bo | ||||
| from pyqtgraph.GraphicsScene import mouseEvents as mevs | ||||
| # from pyqtgraph.GraphicsScene.mouseEvents import MouseDragEvent | ||||
| from PyQt5.QtWidgets import QGraphicsSceneMouseEvent as gs_mouse | ||||
| from PyQt5.QtGui import ( | ||||
|     QWheelEvent, | ||||
| ) | ||||
| from PyQt5.QtCore import ( | ||||
|     Qt, | ||||
|     QEvent, | ||||
| ) | ||||
| from pyqtgraph import ( | ||||
|     ViewBox, | ||||
|     Point, | ||||
|     QtCore, | ||||
|     functions as fn, | ||||
| ) | ||||
| from pyqtgraph import functions as fn | ||||
| import numpy as np | ||||
| import trio | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QWheelEvent, | ||||
|     QGraphicsSceneMouseEvent as gs_mouse, | ||||
|     Qt, | ||||
|     QEvent, | ||||
| ) | ||||
| from ..log import get_logger | ||||
| from ..toolz import ( | ||||
|     Profiler, | ||||
|  | @ -81,22 +79,22 @@ if TYPE_CHECKING: | |||
| log = get_logger(__name__) | ||||
| 
 | ||||
| NUMBER_LINE = { | ||||
|     Qt.Key_1, | ||||
|     Qt.Key_2, | ||||
|     Qt.Key_3, | ||||
|     Qt.Key_4, | ||||
|     Qt.Key_5, | ||||
|     Qt.Key_6, | ||||
|     Qt.Key_7, | ||||
|     Qt.Key_8, | ||||
|     Qt.Key_9, | ||||
|     Qt.Key_0, | ||||
|     Qt.Key.Key_1, | ||||
|     Qt.Key.Key_2, | ||||
|     Qt.Key.Key_3, | ||||
|     Qt.Key.Key_4, | ||||
|     Qt.Key.Key_5, | ||||
|     Qt.Key.Key_6, | ||||
|     Qt.Key.Key_7, | ||||
|     Qt.Key.Key_8, | ||||
|     Qt.Key.Key_9, | ||||
|     Qt.Key.Key_0, | ||||
| } | ||||
| 
 | ||||
| ORDER_MODE = { | ||||
|     Qt.Key_A, | ||||
|     Qt.Key_F, | ||||
|     Qt.Key_D, | ||||
|     Qt.Key.Key_A, | ||||
|     Qt.Key.Key_F, | ||||
|     Qt.Key.Key_D, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,9 +21,12 @@ Double auction top-of-book (L1) graphics. | |||
| from typing import Tuple | ||||
| 
 | ||||
| import pyqtgraph as pg | ||||
| from PyQt5 import QtCore, QtGui | ||||
| from PyQt5.QtCore import QPointF | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QPointF, | ||||
|     QtCore, | ||||
|     QtGui, | ||||
| ) | ||||
| from ._axes import YAxisLabel | ||||
| from ._style import hcolor | ||||
| from ._pg_overrides import PlotItem | ||||
|  |  | |||
|  | @ -25,10 +25,17 @@ from typing import ( | |||
| ) | ||||
| 
 | ||||
| import pyqtgraph as pg | ||||
| from PyQt5 import QtGui, QtWidgets | ||||
| from PyQt5.QtWidgets import QLabel, QSizePolicy | ||||
| from PyQt5.QtCore import QPointF, QRectF, Qt | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     px_cache_mode, | ||||
|     QtGui, | ||||
|     QtWidgets, | ||||
|     QLabel, | ||||
|     size_policy, | ||||
|     QPointF, | ||||
|     QRectF, | ||||
|     Qt, | ||||
| ) | ||||
| from ._style import ( | ||||
|     DpiAwareFont, | ||||
|     hcolor, | ||||
|  | @ -78,7 +85,7 @@ class Label: | |||
|         self._x_offset = x_offset | ||||
| 
 | ||||
|         txt = self.txt = QtWidgets.QGraphicsTextItem(parent=parent) | ||||
|         txt.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) | ||||
|         txt.setCacheMode(px_cache_mode.DeviceCoordinateCache) | ||||
| 
 | ||||
|         vb.scene().addItem(txt) | ||||
| 
 | ||||
|  | @ -103,7 +110,7 @@ class Label: | |||
|         self._anchor_func = self.txt.pos().x | ||||
| 
 | ||||
|         # not sure if this makes a diff | ||||
|         self.txt.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) | ||||
|         self.txt.setCacheMode(px_cache_mode.DeviceCoordinateCache) | ||||
| 
 | ||||
|         # TODO: edit and selection support | ||||
|         # https://doc.qt.io/qt-5/qt.html#TextInteractionFlag-enum | ||||
|  | @ -299,12 +306,14 @@ class FormatLabel(QLabel): | |||
|             """ | ||||
|         ) | ||||
|         self.setFont(_font.font) | ||||
|         self.setTextFormat(Qt.MarkdownText)  # markdown | ||||
|         self.setTextFormat( | ||||
|             Qt.TextFormat.MarkdownText | ||||
|         ) | ||||
|         self.setMargin(0) | ||||
| 
 | ||||
|         self.setSizePolicy( | ||||
|             QSizePolicy.Expanding, | ||||
|             QSizePolicy.Expanding, | ||||
|             size_policy.Expanding, | ||||
|             size_policy.Expanding, | ||||
|         ) | ||||
|         self.setAlignment( | ||||
|             Qt.AlignVCenter | Qt.AlignLeft | ||||
|  |  | |||
|  | @ -27,20 +27,22 @@ from typing import ( | |||
| ) | ||||
| 
 | ||||
| import pyqtgraph as pg | ||||
| from pyqtgraph import Point, functions as fn | ||||
| from PyQt5 import ( | ||||
| from pyqtgraph import ( | ||||
|     Point, | ||||
|     functions as fn, | ||||
| ) | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     px_cache_mode, | ||||
|     QtCore, | ||||
|     QtGui, | ||||
| ) | ||||
| from PyQt5.QtWidgets import ( | ||||
|     QGraphicsPathItem, | ||||
|     QStyleOptionGraphicsItem, | ||||
|     QGraphicsItem, | ||||
|     QGraphicsScene, | ||||
|     QWidget, | ||||
|     QPointF, | ||||
| ) | ||||
| from PyQt5.QtCore import QPointF | ||||
| 
 | ||||
| from ._annotate import LevelMarker | ||||
| from ._anchors import ( | ||||
|     vbr_left, | ||||
|  | @ -140,7 +142,9 @@ class LevelLine(pg.InfiniteLine): | |||
|         self._right_end_sc: float = 0 | ||||
| 
 | ||||
|         # use px caching | ||||
|         self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) | ||||
|         self.setCacheMode( | ||||
|             px_cache_mode.DeviceCoordinateCache | ||||
|         ) | ||||
| 
 | ||||
|     def txt_offsets(self) -> tuple[int, int]: | ||||
|         return 0, 0 | ||||
|  | @ -211,7 +215,7 @@ class LevelLine(pg.InfiniteLine): | |||
|     ) -> None: | ||||
| 
 | ||||
|         if not called_from_on_pos_change: | ||||
|             last = self.value() | ||||
|             last: float = self.value() | ||||
| 
 | ||||
|             # if the position hasn't changed then ``.update_labels()`` | ||||
|             # will not be called by a non-triggered `.on_pos_change()`, | ||||
|  |  | |||
|  | @ -20,16 +20,14 @@ Super fast OHLC sampling graphics types. | |||
| from __future__ import annotations | ||||
| 
 | ||||
| import numpy as np | ||||
| from PyQt5 import ( | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     QtGui, | ||||
|     QtWidgets, | ||||
| ) | ||||
| from PyQt5.QtCore import ( | ||||
|     QPainterPath, | ||||
|     QLineF, | ||||
|     QRectF, | ||||
| ) | ||||
| from PyQt5.QtGui import QPainterPath | ||||
| 
 | ||||
| from ._curve import FlowGraphic | ||||
| from ..toolz import ( | ||||
|     Profiler, | ||||
|  |  | |||
|  | @ -38,14 +38,14 @@ from tractor import ( | |||
|     Context, | ||||
|     MsgStream, | ||||
| ) | ||||
| from PyQt5.QtWidgets import ( | ||||
|     QGraphicsItem, | ||||
| ) | ||||
| 
 | ||||
| from piker.log import get_logger | ||||
| from piker.types import Struct | ||||
| from piker.service import find_service | ||||
| from piker.brokers import SymbolNotFound | ||||
| from piker.ui.qt import ( | ||||
|     QGraphicsItem, | ||||
| ) | ||||
| from ._display import DisplayState | ||||
| from ._interaction import ChartView | ||||
| from ._editors import SelectRect | ||||
|  |  | |||
|  | @ -30,8 +30,8 @@ from typing import ( | |||
| import msgspec | ||||
| import numpy as np | ||||
| import pyqtgraph as pg | ||||
| from PyQt5.QtGui import QPainterPath | ||||
| 
 | ||||
| from piker.ui.qt import QPainterPath | ||||
| from ..data._formatters import ( | ||||
|     IncrementalFormatter, | ||||
| ) | ||||
|  |  | |||
|  | @ -48,27 +48,24 @@ from pprint import pformat | |||
| from rapidfuzz import process as fuzzy | ||||
| import trio | ||||
| from trio_typing import TaskStatus | ||||
| from PyQt5 import QtCore | ||||
| from PyQt5 import QtWidgets | ||||
| from PyQt5.QtCore import ( | ||||
| 
 | ||||
| from piker.ui.qt import ( | ||||
|     size_policy, | ||||
|     align_flag, | ||||
|     Qt, | ||||
|     QtCore, | ||||
|     QtWidgets, | ||||
|     QModelIndex, | ||||
|     QItemSelectionModel, | ||||
| ) | ||||
| from PyQt5.QtGui import ( | ||||
|     # QLayout, | ||||
|     QStandardItem, | ||||
|     QStandardItemModel, | ||||
| ) | ||||
| from PyQt5.QtWidgets import ( | ||||
|     QWidget, | ||||
|     QTreeView, | ||||
|     # QListWidgetItem, | ||||
|     # QAbstractScrollArea, | ||||
|     # QStyledItemDelegate, | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| from ..log import get_logger | ||||
| from ._style import ( | ||||
|     _font, | ||||
|  | @ -129,8 +126,8 @@ class CompleterView(QTreeView): | |||
| 
 | ||||
|         # ux settings | ||||
|         self.setSizePolicy( | ||||
|             QtWidgets.QSizePolicy.Expanding, | ||||
|             QtWidgets.QSizePolicy.Expanding, | ||||
|             size_policy.Expanding, | ||||
|             size_policy.Expanding, | ||||
|         ) | ||||
|         self.setItemsExpandable(True) | ||||
|         self.setExpandsOnDoubleClick(False) | ||||
|  | @ -567,8 +564,8 @@ class SearchWidget(QtWidgets.QWidget): | |||
| 
 | ||||
|         # size it as we specify | ||||
|         self.setSizePolicy( | ||||
|             QtWidgets.QSizePolicy.Fixed, | ||||
|             QtWidgets.QSizePolicy.Fixed, | ||||
|             size_policy.Fixed, | ||||
|             size_policy.Fixed, | ||||
|         ) | ||||
| 
 | ||||
|         self.godwidget = godwidget | ||||
|  | @ -592,14 +589,16 @@ class SearchWidget(QtWidgets.QWidget): | |||
|             }} | ||||
|             """ | ||||
|         ) | ||||
|         label.setTextFormat(3)  # markdown | ||||
|         label.setTextFormat( | ||||
|             Qt.TextFormat.MarkdownText | ||||
|         ) | ||||
|         label.setFont(_font.font) | ||||
|         label.setMargin(4) | ||||
|         label.setText("search:") | ||||
|         label.show() | ||||
|         label.setAlignment( | ||||
|             QtCore.Qt.AlignVCenter | ||||
|             | QtCore.Qt.AlignLeft | ||||
|             align_flag.AlignVCenter | ||||
|             | align_flag.AlignLeft | ||||
|         ) | ||||
| 
 | ||||
|         self.bar_hbox.addWidget(label) | ||||
|  | @ -617,9 +616,17 @@ class SearchWidget(QtWidgets.QWidget): | |||
| 
 | ||||
|         self.vbox.addLayout(self.bar_hbox) | ||||
| 
 | ||||
|         self.vbox.setAlignment(self.bar, Qt.AlignTop | Qt.AlignRight) | ||||
|         self.vbox.setAlignment( | ||||
|             self.bar, | ||||
|             align_flag.AlignTop | ||||
|             | align_flag.AlignRight, | ||||
|         ) | ||||
|         self.vbox.addWidget(self.bar.view) | ||||
|         self.vbox.setAlignment(self.view, Qt.AlignTop | Qt.AlignLeft) | ||||
|         self.vbox.setAlignment( | ||||
|             self.view, | ||||
|             align_flag.AlignTop | ||||
|             | align_flag.AlignLeft, | ||||
|         ) | ||||
| 
 | ||||
|     def focus(self) -> None: | ||||
|         self.show() | ||||
|  |  | |||
|  | @ -22,10 +22,14 @@ from typing import Dict | |||
| import math | ||||
| 
 | ||||
| import pyqtgraph as pg | ||||
| from PyQt5 import QtCore, QtGui | ||||
| from PyQt5.QtCore import Qt, QCoreApplication | ||||
| from qdarkstyle import DarkPalette | ||||
| 
 | ||||
| from .qt import ( | ||||
|     QtCore, | ||||
|     QtGui, | ||||
|     Qt, | ||||
|     QCoreApplication, | ||||
| ) | ||||
| from ..log import get_logger | ||||
| 
 | ||||
| from .. import config | ||||
|  |  | |||
|  | @ -27,16 +27,14 @@ from typing import ( | |||
| ) | ||||
| import uuid | ||||
| 
 | ||||
| from PyQt5 import QtCore | ||||
| from PyQt5.QtWidgets import ( | ||||
| from piker.ui.qt import ( | ||||
|     Qt, | ||||
|     QtCore, | ||||
|     QWidget, | ||||
|     QMainWindow, | ||||
|     QApplication, | ||||
|     QLabel, | ||||
|     QStatusBar, | ||||
| ) | ||||
| 
 | ||||
| from PyQt5.QtGui import ( | ||||
|     QScreen, | ||||
|     QCloseEvent, | ||||
| ) | ||||
|  | @ -197,7 +195,9 @@ class MainWindow(QMainWindow): | |||
|                 """ | ||||
|                 # font-size : {font_size}px; | ||||
|             ) | ||||
|             label.setTextFormat(3)  # markdown | ||||
|             label.setTextFormat( | ||||
|                 Qt.TextFormat.MarkdownText | ||||
|             ) | ||||
|             label.setFont(_font_small.font) | ||||
|             label.setMargin(2) | ||||
|             label.setAlignment( | ||||
|  |  | |||
|  | @ -34,7 +34,6 @@ import uuid | |||
| from bidict import bidict | ||||
| import tractor | ||||
| import trio | ||||
| from PyQt5.QtCore import Qt | ||||
| 
 | ||||
| from piker import config | ||||
| from piker.accounting import ( | ||||
|  | @ -59,6 +58,7 @@ from piker.data import ( | |||
| ) | ||||
| from piker.types import Struct | ||||
| from piker.log import get_logger | ||||
| from piker.ui.qt import Qt | ||||
| from ._editors import LineEditor, ArrowEditor | ||||
| from ._lines import order_line, LevelLine | ||||
| from ._position import ( | ||||
|  | @ -358,7 +358,7 @@ class OrderMode: | |||
|         send_msg: bool = True, | ||||
|         order: Order | None = None, | ||||
| 
 | ||||
|     ) -> Dialog | None: | ||||
|     ) -> Dialog|None: | ||||
|         ''' | ||||
|         Send execution order to EMS return a level line to | ||||
|         represent the order on a chart. | ||||
|  | @ -494,7 +494,7 @@ class OrderMode: | |||
|         uuid: str, | ||||
|         order: Order | None = None, | ||||
| 
 | ||||
|     ) -> Dialog: | ||||
|     ) -> Dialog | None: | ||||
|         ''' | ||||
|         Order submitted status event handler. | ||||
| 
 | ||||
|  | @ -515,6 +515,11 @@ class OrderMode: | |||
|             # if an order msg is provided update the line | ||||
|             # **from** that msg. | ||||
|             if order: | ||||
|                 if order.price <= 0: | ||||
|                     log.error(f'Order has 0 price, cancelling..\n{order}') | ||||
|                     self.cancel_orders([order.oid]) | ||||
|                     return None | ||||
| 
 | ||||
|                 line.set_level(order.price) | ||||
|                 self.on_level_change_update_next_order_info( | ||||
|                     level=order.price, | ||||
|  | @ -1013,8 +1018,13 @@ async def process_trade_msg( | |||
| 
 | ||||
| ) -> tuple[Dialog, Status]: | ||||
| 
 | ||||
|     fmsg = pformat(msg) | ||||
|     log.debug(f'Received order msg:\n{fmsg}') | ||||
|     # TODO: obvi once we're parsing to native struct instances we can | ||||
|     # drop the `pformat()` call Bo | ||||
|     fmtmsg: Struct | dict = msg | ||||
|     if not isinstance(msg, Struct): | ||||
|         fmtmsg: str = pformat(msg) | ||||
| 
 | ||||
|     log.debug(f'Received order msg:\n{fmtmsg}') | ||||
|     name = msg['name'] | ||||
| 
 | ||||
|     if name in ( | ||||
|  | @ -1030,7 +1040,7 @@ async def process_trade_msg( | |||
|         ): | ||||
|             log.info( | ||||
|                 f'Loading position for `{fqme}`:\n' | ||||
|                 f'{fmsg}' | ||||
|                 f'{fmtmsg}' | ||||
|             ) | ||||
|             tracker = mode.trackers[msg['account']] | ||||
|             tracker.live_pp.update_from_msg(msg) | ||||
|  | @ -1072,7 +1082,7 @@ async def process_trade_msg( | |||
| 
 | ||||
|             elif order.action != 'cancel': | ||||
|                 log.warning( | ||||
|                     f'received msg for untracked dialog:\n{fmsg}' | ||||
|                     f'received msg for untracked dialog:\n{fmtmsg}' | ||||
|                 ) | ||||
|                 assert msg.resp in ('open', 'dark_open'), f'Unknown msg: {msg}' | ||||
| 
 | ||||
|  | @ -1139,7 +1149,7 @@ async def process_trade_msg( | |||
|             req={'exec_mode': 'dark'}, | ||||
|         ): | ||||
|             # TODO: UX for a "pending" clear/live order | ||||
|             log.info(f'Dark order triggered for {fmsg}') | ||||
|             log.info(f'Dark order triggered for {fmtmsg}') | ||||
| 
 | ||||
|         case Status( | ||||
|             resp='triggered', | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue