mBA-Terminal / src /ui /main_window.py
algorembrant's picture
Upload 29 files
c99df4c verified
from PyQt6.QtWidgets import (
QMainWindow, QDockWidget, QStatusBar, QMessageBox, QWidget
)
from PyQt6.QtCore import Qt
from src.ui.control_panel import ControlPanel
from src.ui.chart_widget import ChartWidget
from src.core.data_worker import DataWorker
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Python Trading Terminal (MT5 + Gap-Filled Profile)")
self.resize(1200, 800)
self.init_ui()
self.worker = None
def init_ui(self):
# Status Bar
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
# Dock: Control Panel
self.dock_controls = QDockWidget("Controls", self)
self.control_panel = ControlPanel()
self.dock_controls.setWidget(self.control_panel)
self.dock_controls.setAllowedAreas(Qt.DockWidgetArea.LeftDockWidgetArea | Qt.DockWidgetArea.RightDockWidgetArea)
self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, self.dock_controls)
# Central: Chart
self.chart_widget = ChartWidget()
self.setCentralWidget(self.chart_widget)
# Connections
self.control_panel.start_signal.connect(self.start_worker)
self.control_panel.stop_signal.connect(self.stop_worker)
def start_worker(self, symbol, date, multiplier):
if self.worker is not None and self.worker.isRunning():
return
self.chart_widget.clear()
self.chart_widget.price_plot.setTitle(f"{symbol} - {date} (Multiplier: {multiplier}x)")
self.worker = DataWorker(symbol, date, multiplier=multiplier)
self.worker.status_signal.connect(self.status_bar.showMessage)
self.worker.data_signal.connect(self.handle_data)
self.worker.levels_signal.connect(self.handle_levels)
self.worker.finished.connect(self.on_worker_finished)
self.worker.start()
def stop_worker(self):
if self.worker:
self.worker.stop()
self.worker = None
self.status_bar.showMessage("Stream stopped.")
def handle_data(self, ticks_df, profile_counts):
# Update Chart with new ticks
# Note: ChartWidget.update_ticks expects a dataframe.
# If we just append, we might need to handle state inside chart widget better.
# But simpler: pass the full set or update logic.
# For performance, we should probably append.
# In current ChartWidget, update_ticks SETS data.
# DataWorker emits chunks (new_ticks) during loop, but FULL history at start.
# We need to distinguish or accumulate in ChartWidget?
# Actually, DataWorker emits distinct chunks in the loop.
# But ChartWidget `setData` replaces content.
# We need to accumulate data in ChartWidget or pass accumulated data from Worker.
# Passing Full DF every 500ms with millions of rows is bad.
# Better: ChartWidget accumulates.
# Actually, let's just make ChartWidget append.
# Or better: Worker sends everything? No.
# Let's Modify ChartWidget to accumulate.
# WAIT: My ChartWidget implementation `update_ticks` does: `self.bid_curve.setData(t_float, bids)`
# This REPLACES.
# I need to fix ChartWidget to handle incremental updates or large data better.
# For now, let's just pass the full accumulated history from Worker?
# Worker doesn't store accumulated history openly, it just emits `ticks_df` (chunk).
# We need a way to append.
# Let's fix ChartWidget in next step. For now assume it appends.
self.chart_widget.update_ticks(ticks_df)
self.chart_widget.update_profile(profile_counts) # Full profile is cheap (dict)
def handle_levels(self, times, vah, val, poc):
self.chart_widget.update_levels(times, vah, val, poc)
def on_worker_finished(self):
self.control_panel.on_stop()
self.worker = None
self.status_bar.showMessage("Ready.")