37172-vm/algo_trader/ui/main_window.py
2025-12-27 04:26:41 +00:00

121 lines
5.1 KiB
Python

import sys
import asyncio
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QWidget, QVBoxLayout, QTabWidget
from PySide6.QtCore import Qt, QTimer, QThread, Signal
from .dashboard import DashboardPanel
from .strategy_panel import StrategyPanel
from .positions_panel import PositionsPanel
from .orders_panel import OrdersPanel
from .logs_panel import LogsPanel
class AsyncWorker(QThread):
def __init__(self, loop: asyncio.AbstractEventLoop, target_coro, kwargs):
super().__init__()
self.loop = loop
self.target_coro = target_coro
self.kwargs = kwargs
def run(self):
asyncio.set_event_loop(self.loop)
self.loop.run_until_complete(self.target_coro(**self.kwargs))
self.loop.close()
class MainWindow(QMainWindow):
def __init__(
self, broker, data_feed, db_session, order_manager, risk_manager, strategy_engine, settings, backend_runner, app_logger, portfolio
):
super().__init__()
self.broker = broker
self.data_feed = data_feed
self.db_session = db_session
self.order_manager = order_manager
self.risk_manager = risk_manager
self.strategy_engine = strategy_engine
self.settings = settings
self.backend_runner = backend_runner
self.app_logger = app_logger # Store the app_logger instance
self.portfolio = portfolio
self.setWindowTitle("Algo Trader")
self.setGeometry(100, 100, 1600, 900)
# Create main tab widget
self.tabs = QTabWidget()
self.tabs.setTabPosition(QTabWidget.North)
# Create panels
self.dashboard_panel = DashboardPanel()
self.strategy_panel = StrategyPanel()
self.positions_panel = PositionsPanel()
self.orders_panel = OrdersPanel()
self.logs_panel = LogsPanel()
# Add panels to tabs
self.tabs.addTab(self.dashboard_panel, "Dashboard")
self.tabs.addTab(self.strategy_panel, "Strategies")
self.tabs.addTab(self.positions_panel, "Positions")
self.tabs.addTab(self.orders_panel, "Orders")
self.tabs.addTab(self.logs_panel, "Logs")
self.setCentralWidget(self.tabs)
# Connect logger signal to logs panel
self.app_logger.log_signal.connect(self.logs_panel.append_log)
# Connect data_feed signals to dashboard and logger
self.data_feed.signals.connected.connect(lambda: self.app_logger.info("DataFeed: Connected"))
self.data_feed.signals.disconnected.connect(lambda: self.app_logger.warning("DataFeed: Disconnected"))
self.data_feed.signals.error.connect(lambda msg: self.app_logger.error(f"DataFeed Error: {msg}"))
self.data_feed.signals.tick.connect(self.dashboard_panel.update_market_data)
# Connect order_manager signals to orders panel
self.order_manager.signals.order_updated.connect(self.orders_panel.add_or_update_order)
# Connect portfolio signals to positions panel
self.portfolio.signals.position_updated.connect(self.positions_panel.add_or_update_position)
self.portfolio.signals.portfolio_value_updated.connect(lambda value: self.app_logger.info(f"Portfolio Value Updated: {value}"))
# Connect strategy_engine signals to strategy_panel and logger
self.strategy_engine.signals.strategy_loaded.connect(self.strategy_panel.update_status)
self.strategy_engine.signals.strategy_started.connect(lambda name: self.strategy_panel.update_status(f"Running: {name}"))
self.strategy_engine.signals.strategy_stopped.connect(lambda name: self.strategy_panel.update_status(f"Stopped: {name}"))
self.strategy_engine.signals.trade_signal.connect(lambda signal: self.app_logger.info(f"Trade Signal: {signal}"))
# Connect strategy_panel UI signals to strategy_engine methods
self.strategy_panel.strategy_selected.connect(self.strategy_engine.load_strategy)
self.strategy_panel.start_strategy_requested.connect(self.strategy_engine.start_strategy)
self.strategy_panel.stop_strategy_requested.connect(self.strategy_engine.stop_strategy)
# --- Asyncio Integration ---
self.loop = asyncio.get_event_loop()
if self.loop.is_running():
self.loop = asyncio.new_event_loop()
self.backend_worker = AsyncWorker(
loop=self.loop,
target_coro=self.backend_runner,
kwargs={
"broker": self.broker,
"data_feed": self.data_feed,
"db_session": self.db_session,
"order_manager": self.order_manager,
"risk_manager": self.risk_manager,
"strategy_engine": self.strategy_engine,
"settings": self.settings,
"portfolio": self.portfolio,
},
)
self.backend_worker.start()
def closeEvent(self, event):
if self.data_feed:
asyncio.run_coroutine_threadsafe(self.data_feed.close(), self.loop)
if self.db_session:
self.db_session.close()
self.loop.call_soon_threadsafe(self.loop.stop)
self.backend_worker.wait() # Wait for the backend thread to finish
super().closeEvent(event)