import sys
import time
import datetime as dt
import pandas as pd
import numpy as np
import threading
import json
import os
import sqlite3
import matplotlib.pyplot as plt
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
                            QLabel, QPushButton, QLineEdit, QTabWidget, QTableWidget,
                            QTableWidgetItem, QMessageBox, QProgressBar, QCheckBox,
                            QHeaderView, QFileDialog, QGroupBox, QScrollArea,
                            QStatusBar, QSystemTrayIcon, QMenu, QAction, QDoubleSpinBox)
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QThread
from PyQt5.QtGui import QIcon, QFont, QClipboard
import MetaTrader5 as mt5
import pyqtgraph as pg
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import io
import base64

class AccountMonitor(QThread):
    update_signal = pyqtSignal(dict)
    error_signal = pyqtSignal(str)

    def __init__(self, account_info, risk_settings, db_path):
        super().__init__()
        self.account_info = account_info
        self.risk_settings = risk_settings
        self.connected = False
        self.running = True
        self.db_path = db_path
        self.block_lock = threading.Lock()
        self.blocked_trading = False
        self.last_save_time = time.time()
        self.last_weekly_report_time = time.time()
        self.terminal_path = r"C:\Program Files\RoboForex MT5 Terminal\terminal64.exe"  # Specify the path
        self.load_blocked_state()

    def load_blocked_state(self):
        # No changes
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            cursor.execute('SELECT blocked_trading FROM account_history WHERE account_id = ? ORDER BY timestamp DESC LIMIT 1', (self.account_info['login'],))
            result = cursor.fetchone()
            with self.block_lock:
                self.blocked_trading = bool(result[0]) if result else False
            conn.close()
        except sqlite3.Error as e:
            self.error_signal.emit(f"Error loading block state: {str(e)}")

    def run(self):
        try:
            # Check if the specified path exists
            if not os.path.exists(self.terminal_path):
                self.error_signal.emit(f"Specified MT5 terminal path not found: {self.terminal_path}")
                return

            # Initialize MT5 with explicit path
            if not mt5.initialize(path=self.terminal_path):
                self.error_signal.emit(f"MT5 initialization error at path {self.terminal_path}: {mt5.last_error()}")
                return

            authorized = mt5.login(
                login=int(self.account_info['login']),
                password=self.account_info['password'],
                server=self.account_info['server']
            )
            if not authorized:
                self.error_signal.emit(f"Authorization error: {mt5.last_error()}")
                mt5.shutdown()
                return

            self.connected = True
            initial_account_info = mt5.account_info()
            if not initial_account_info:
                self.error_signal.emit("Failed to get initial account information")
                mt5.shutdown()
                return

            initial_balance = initial_account_info.balance
            initial_equity = initial_account_info.equity

            # The rest of the run method remains unchanged
            while self.running:
                try:
                    account_info = mt5.account_info()
                    if not account_info:
                        self.error_signal.emit("Failed to get account information")
                        time.sleep(18)
                        continue

                    positions = mt5.positions_get()
                    if positions is None:
                        self.error_signal.emit(f"Error getting positions: {mt5.last_error()}")
                        time.sleep(18)
                        continue
                    positions_df = pd.DataFrame(list(positions), columns=positions[0]._asdict().keys()) if positions else pd.DataFrame()
                    floating_profit = positions_df['profit'].sum() if not positions_df.empty else 0
                    equity = account_info.balance + floating_profit

                    conn = sqlite3.connect(self.db_path)
                    cursor = conn.cursor()
                    cursor.execute('''CREATE TABLE IF NOT EXISTS account_history (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        account_id INTEGER,
                        balance REAL,
                        equity REAL,
                        balance_drawdown REAL,
                        equity_drawdown REAL,
                        margin REAL,
                        free_margin REAL,
                        margin_level REAL,
                        daily_balance_loss REAL,
                        weekly_balance_loss REAL,
                        daily_equity_loss REAL,
                        weekly_equity_loss REAL,
                        positions_count INTEGER,
                        blocked_trading INTEGER,
                        timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
                    )''')
                    cursor.execute('SELECT MAX(balance) FROM account_history WHERE account_id = ?', (self.account_info['login'],))
                    result = cursor.fetchone()
                    max_balance = result[0] if result and result[0] is not None else initial_balance

                    balance_drawdown = 0
                    equity_drawdown = 0
                    drawdown_mode = self.risk_settings.get('drawdown_mode', 'balance')
                    limit_mode = self.risk_settings.get('limit_mode', 'percent')

                    if max_balance > 0:
                        if drawdown_mode in ['balance', 'both']:
                            balance_drawdown = (max_balance - account_info.balance) / max_balance * 100 if limit_mode == 'percent' else max_balance - account_info.balance

                    cursor.execute('SELECT MAX(equity) FROM account_history WHERE account_id = ?', (self.account_info['login'],))
                    result = cursor.fetchone()
                    max_equity = result[0] if result and result[0] is not None else initial_equity

                    if max_equity > 0:
                        if drawdown_mode in ['equity', 'both']:
                            equity_drawdown = (max_equity - equity) / max_equity * 100 if limit_mode == 'percent' else max_equity - equity

                    conn.close()

                    from_date = dt.datetime.now() - dt.timedelta(days=7)
                    to_date = dt.datetime.now()
                    deals = mt5.history_deals_get(from_date, to_date) or []
                    daily_balance_loss = weekly_balance_loss = daily_equity_loss = weekly_equity_loss = 0

                    if deals:
                        deals_df = pd.DataFrame(list(deals), columns=deals[0]._asdict().keys())
                        today = dt.datetime.now().date()
                        today_deals = deals_df[pd.to_datetime(deals_df['time']).dt.date == today]
                        week_start = (dt.datetime.now() - dt.timedelta(days=dt.datetime.now().weekday())).date()
                        week_deals = deals_df[pd.to_datetime(deals_df['time']).dt.date >= week_start]

                        daily_balance_loss = today_deals[today_deals['profit'] < 0]['profit'].sum() if not today_deals.empty else 0
                        weekly_balance_loss = week_deals[week_deals['profit'] < 0]['profit'].sum() if not week_deals.empty else 0
                        daily_equity_loss = daily_balance_loss + (positions_df[positions_df['profit'] < 0]['profit'].sum() if not positions_df.empty else 0)
                        weekly_equity_loss = weekly_balance_loss + (positions_df[positions_df['profit'] < 0]['profit'].sum() if not positions_df.empty else 0)

                    daily_balance_limit = self.risk_settings.get('daily_loss_limit', 5 if limit_mode == 'percent' else 100)
                    weekly_balance_limit = self.risk_settings.get('weekly_loss_limit', 10 if limit_mode == 'percent' else 300)
                    daily_balance_limit_exceeded = abs(daily_balance_loss) > (account_info.balance * daily_balance_limit / 100 if limit_mode == 'percent' else daily_balance_limit)
                    weekly_balance_limit_exceeded = abs(weekly_balance_loss) > (account_info.balance * weekly_balance_limit / 100 if limit_mode == 'percent' else weekly_balance_limit)
                    daily_equity_limit_exceeded = abs(daily_equity_loss) > (equity * daily_balance_limit / 100 if limit_mode == 'percent' else daily_balance_limit)
                    weekly_equity_limit_exceeded = abs(weekly_equity_loss) > (equity * weekly_balance_limit / 100 if limit_mode == 'percent' else weekly_balance_limit)

                    max_drawdown_limit = self.risk_settings.get('max_drawdown', 10 if limit_mode == 'percent' else 100)
                    max_drawdown_exceeded = False
                    if drawdown_mode == 'balance':
                        max_drawdown_exceeded = balance_drawdown > max_drawdown_limit
                    elif drawdown_mode == 'equity':
                        max_drawdown_exceeded = equity_drawdown > max_drawdown_limit
                    else:  # both
                        max_drawdown_exceeded = balance_drawdown > max_drawdown_limit or equity_drawdown > max_drawdown_limit

                    limits_exceeded = daily_balance_limit_exceeded or weekly_balance_limit_exceeded or daily_equity_limit_exceeded or weekly_equity_limit_exceeded or max_drawdown_exceeded

                    with self.block_lock:
                        if limits_exceeded and self.risk_settings.get('auto_close_positions', True):
                            self.blocked_trading = True
                            if positions:
                                self.close_all_positions()
                                self.error_signal.emit(f"All positions closed due to limit exceedance: DBL={daily_balance_limit_exceeded}, WBL={weekly_balance_limit_exceeded}, DEL={daily_equity_limit_exceeded}, WEL={weekly_equity_limit_exceeded}, MDD={max_drawdown_exceeded}")
                        elif self.blocked_trading:
                            if positions:
                                self.close_all_positions()
                                self.error_signal.emit("Positions closed: trading remains blocked")
                            if self.risk_settings.get('auto_unblock_trading', False) and not limits_exceeded:
                                self.blocked_trading = False
                                self.error_signal.emit("Trading unblocked automatically")

                    update_data = {
                        'account_id': self.account_info['login'],
                        'balance': account_info.balance,
                        'equity': equity,
                        'margin': account_info.margin,
                        'free_margin': account_info.margin_free,
                        'margin_level': account_info.margin_level if account_info.margin_level else 0,
                        'balance_drawdown': balance_drawdown,
                        'equity_drawdown': equity_drawdown,
                        'daily_balance_loss': daily_balance_loss,
                        'weekly_balance_loss': weekly_balance_loss,
                        'daily_equity_loss': daily_equity_loss,
                        'weekly_equity_loss': weekly_equity_loss,
                        'daily_balance_limit_exceeded': daily_balance_limit_exceeded,
                        'weekly_balance_limit_exceeded': weekly_balance_limit_exceeded,
                        'daily_equity_limit_exceeded': daily_equity_limit_exceeded,
                        'weekly_equity_limit_exceeded': weekly_equity_limit_exceeded,
                        'max_drawdown_exceeded': max_drawdown_exceeded,
                        'blocked_trading': self.blocked_trading,
                        'positions_count': len(positions) if positions else 0,
                        'positions': positions_df.to_dict('records') if not positions_df.empty else []
                    }

                    current_time = time.time()
                    if current_time - self.last_save_time >= 300:  # Save every 5 minutes
                        self.save_to_db(update_data)
                        self.last_save_time = current_time

                    if current_time - self.last_weekly_report_time >= 604800:  # Weekly report
                        self.generate_weekly_report(update_data)
                        self.last_weekly_report_time = current_time

                    self.update_signal.emit(update_data)

                except Exception as e:
                    self.error_signal.emit(f"Error in monitoring loop: {str(e)}")
                    time.sleep(18)
                    continue

                time.sleep(18)  # Update every 18 seconds

        except Exception as e:
            self.error_signal.emit(f"Critical error: {str(e)}")
        finally:
            if self.connected:
                mt5.shutdown()

    def close_all_positions(self):
        positions = mt5.positions_get()
        if positions is None:
            self.error_signal.emit(f"Error getting positions for closing: {mt5.last_error()}")
            return
        if not positions:
            self.error_signal.emit("No open positions to close")
            return

        for position in positions:
            try:
                symbol = position.symbol
                volume = position.volume
                position_id = position.ticket
                position_type = position.type
                tick = mt5.symbol_info_tick(symbol)
                if not tick:
                    self.error_signal.emit(f"Failed to get data for symbol {symbol}")
                    continue

                close_price = tick.bid if position_type == mt5.ORDER_TYPE_BUY else tick.ask
                close_type = mt5.ORDER_TYPE_SELL if position_type == mt5.ORDER_TYPE_BUY else mt5.ORDER_TYPE_BUY

                close_request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": close_type,
                    "position": position_id,
                    "price": close_price,
                    "deviation": 100,
                    "comment": "Close by Risk Manager",
                }

                result = mt5.order_send(close_request)
                if not result or result.retcode != mt5.TRADE_RETCODE_DONE:
                    self.error_signal.emit(f"Error closing position {position_id}: {result.retcode if result else mt5.last_error()}")
            except Exception as e:
                self.error_signal.emit(f"Error closing position: {str(e)}")

    def save_to_db(self, data):
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()

            cursor.execute('''CREATE TABLE IF NOT EXISTS accounts (
                account_id INTEGER PRIMARY KEY,
                server TEXT,
                login TEXT,
                password TEXT,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
            )''')

            cursor.execute('''CREATE TABLE IF NOT EXISTS account_history (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                account_id INTEGER,
                balance REAL,
                equity REAL,
                balance_drawdown REAL,
                equity_drawdown REAL,
                margin REAL,
                free_margin REAL,
                margin_level REAL,
                daily_balance_loss REAL,
                weekly_balance_loss REAL,
                daily_equity_loss REAL,
                weekly_equity_loss REAL,
                positions_count INTEGER,
                blocked_trading INTEGER,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
            )''')

            cursor.execute('INSERT OR REPLACE INTO accounts (account_id, server, login, password) VALUES (?, ?, ?, ?)',
                          (self.account_info['login'], self.account_info['server'], self.account_info['login'], self.account_info['password']))

            with self.block_lock:
                blocked_value = 1 if self.blocked_trading else 0
            cursor.execute('''INSERT INTO account_history (
                account_id, balance, equity, balance_drawdown, equity_drawdown, margin, free_margin, margin_level,
                daily_balance_loss, weekly_balance_loss, daily_equity_loss, weekly_equity_loss, positions_count, blocked_trading
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', (
                data['account_id'], data['balance'], data['equity'], data['balance_drawdown'], data['equity_drawdown'],
                data['margin'], data['free_margin'], data['margin_level'],
                data['daily_balance_loss'], data['weekly_balance_loss'], data['daily_equity_loss'],
                data['weekly_equity_loss'], data['positions_count'], blocked_value
            ))

            conn.commit()
        except sqlite3.Error as e:
            self.error_signal.emit(f"Database error: {str(e)}")
        finally:
            conn.close()

    def generate_weekly_report(self, data):
        try:
            conn = sqlite3.connect(self.db_path)
            df = pd.read_sql_query('SELECT timestamp, balance, equity, balance_drawdown, equity_drawdown FROM account_history WHERE account_id = ? AND timestamp >= ?',
                                  conn, params=(data['account_id'], dt.datetime.now() - dt.timedelta(days=7)))

            if df.empty:
                self.error_signal.emit(f"No data for report for account {data['account_id']}")
                return

            table_html = df.to_html(index=False, classes='table table-striped', border=0)

            fig, ax = plt.subplots(figsize=(10, 6))
            ax.plot(pd.to_datetime(df['timestamp']), df['balance_drawdown'], label='Balance Drawdown (%)', color='blue')
            ax.plot(pd.to_datetime(df['timestamp']), df['equity_drawdown'], label='Equity Drawdown (%)', color='red')
            ax.set_title(f"Weekly Drawdown Report for Account {data['account_id']}")
            ax.set_xlabel("Date")
            ax.set_ylabel("Drawdown (%)")
            ax.legend()
            ax.grid(True)

            buf = io.BytesIO()
            FigureCanvas(fig).print_png(buf)
            buf.seek(0)
            img_base64 = base64.b64encode(buf.getvalue()).decode('utf-8')
            plt.close(fig)

            html_content = f"""
            <html>
            <head>
                <title>SHTENCO Weekly Report - Account {data['account_id']}</title>
                <style>
                    body {{ font-family: Arial, sans-serif; margin: 20px; }}
                    .table {{ width: 100%; border-collapse: collapse; }}
                    .table th, .table td {{ padding: 8px; text-align: left; }}
                    .table-striped tr:nth-child(even) {{ background-color: #f2f2f2; }}
                    h1 {{ text-align: center; }}
                </style>
            </head>
            <body>
                <h1>SHTENCO Risk Management Weekly Report - Account {data['account_id']}</h1>
                <h2>Data for the Last Week</h2>
                {table_html}
                <h2>Drawdown Chart</h2>
                <img src="data:image/png;base64,{img_base64}" alt="Drawdown Chart">
            </body>
            </html>
            """

            report_dir = "weekly_reports"
            os.makedirs(report_dir, exist_ok=True)
            report_path = os.path.join(report_dir, f"report_{data['account_id']}_{dt.datetime.now().strftime('%Y%m%d')}.html")
            with open(report_path, 'w', encoding='utf-8') as f:
                f.write(html_content)

            self.error_signal.emit(f"Weekly report saved: {report_path}")
        except Exception as e:
            self.error_signal.emit(f"Error generating report: {str(e)}")
        finally:
            conn.close()

    def stop(self):
        self.running = False
        self.wait()

class RiskManagerGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("SHTENCO Risk Management Panel")
        self.setGeometry(100, 100, 1280, 800)
        self.setMinimumWidth(1000)
        self.account_monitors = {}
        self.clipboard = QApplication.clipboard()
        self.last_clipboard_text = ""
        self.db_path = 'afif_accounts.db'
        self.init_ui()
        self.clipboard_timer = QTimer()
        self.clipboard_timer.timeout.connect(self.check_clipboard)
        self.clipboard_timer.start(1000)
        self.load_accounts()
        self.setup_tray()

    def init_ui(self):
        central_widget = QWidget()
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setWidget(central_widget)
        self.setCentralWidget(scroll_area)

        main_layout = QVBoxLayout(central_widget)

        connection_group = QGroupBox("Connect to MetaTrader 5 Account")
        connection_layout = QVBoxLayout(connection_group)

        form_layout = QHBoxLayout()
        server_layout = QVBoxLayout()
        server_layout.addWidget(QLabel("Server:"))
        self.server_input = QLineEdit()
        self.server_input.setPlaceholderText("e.g., ICMarketsSC-Demo")
        server_layout.addWidget(self.server_input)
        form_layout.addLayout(server_layout)

        login_layout = QVBoxLayout()
        login_layout.addWidget(QLabel("Login:"))
        self.login_input = QLineEdit()
        self.login_input.setPlaceholderText("MT5 Account Number")
        login_layout.addWidget(self.login_input)
        form_layout.addLayout(login_layout)

        password_layout = QVBoxLayout()
        password_layout.addWidget(QLabel("Password:"))
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.Password)
        self.password_input.setPlaceholderText("MT5 Account Password")
        password_layout.addWidget(self.password_input)
        form_layout.addLayout(password_layout)

        self.auto_paste = QCheckBox("Auto from Clipboard")
        self.auto_paste.setChecked(True)
        form_layout.addWidget(self.auto_paste)

        self.connect_button = QPushButton("Connect Account")
        self.connect_button.clicked.connect(self.connect_account)
        form_layout.addWidget(self.connect_button)

        connection_layout.addLayout(form_layout)
        main_layout.addWidget(connection_group)

        self.tabs = QTabWidget()
        main_layout.addWidget(self.tabs)

        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage("Ready to connect MT5 accounts")

        self.setup_styles()

    def apply_risk_settings(self, login):
        try:
            limit_mode = "percent" if getattr(self, f"limit_mode_percent_{login}").isChecked() else "dollars"
            daily_loss_limit = getattr(self, f"daily_loss_limit_{login}").value()
            daily_loss_mode = "balance" if getattr(self, f"daily_loss_mode_balance_{login}").isChecked() else "equity" if getattr(self, f"daily_loss_mode_equity_{login}").isChecked() else "both"
            weekly_loss_limit = getattr(self, f"weekly_loss_limit_{login}").value()
            weekly_loss_mode = "balance" if getattr(self, f"weekly_loss_mode_balance_{login}").isChecked() else "equity" if getattr(self, f"weekly_loss_mode_equity_{login}").isChecked() else "both"
            max_drawdown = getattr(self, f"max_drawdown_{login}").value()
            drawdown_mode = "balance" if getattr(self, f"drawdown_mode_balance_{login}").isChecked() else "equity" if getattr(self, f"drawdown_mode_equity_{login}").isChecked() else "both"
            auto_close_positions = getattr(self, f"auto_close_{login}").isChecked()
            auto_unblock_trading = getattr(self, f"auto_unblock_{login}").isChecked()

            monitor = self.account_monitors[login]['monitor']
            monitor.risk_settings = {
                'limit_mode': limit_mode,
                'daily_loss_limit': daily_loss_limit,
                'daily_loss_mode': daily_loss_mode,
                'weekly_loss_limit': weekly_loss_limit,
                'weekly_loss_mode': weekly_loss_mode,
                'max_drawdown': max_drawdown,
                'drawdown_mode': drawdown_mode,
                'auto_close_positions': auto_close_positions,
                'auto_unblock_trading': auto_unblock_trading
            }
            self.account_monitors[login]['risk_settings'] = monitor.risk_settings
            self.status_bar.showMessage(f"Settings applied to account {login}")
        except AttributeError as e:
            self.show_error(f"Error applying settings: {str(e)}")

    def connect_account(self):
        server = self.server_input.text().strip()
        login = self.login_input.text().strip()
        password = self.password_input.text().strip()

        if not all([server, login, password]):
            QMessageBox.warning(self, "Error", "Please fill in all fields!")
            return

        if login in self.account_monitors:
            QMessageBox.warning(self, "Error", f"Account {login} is already connected!")
            return

        account_tab = QWidget()
        self.tabs.addTab(account_tab, f"Account {login}")
        tab_layout = QVBoxLayout(account_tab)

        info_group = QGroupBox("Account Information")
        info_layout = QHBoxLayout(info_group)
        self.create_info_widget(info_layout, "Balance:", f"balance_{login}")
        self.create_info_widget(info_layout, "Equity:", f"equity_{login}")
        self.create_info_widget(info_layout, "Margin:", f"margin_{login}")
        self.create_info_widget(info_layout, "Free Margin:", f"free_margin_{login}")
        self.create_info_widget(info_layout, "Margin Level:", f"margin_level_{login}")
        blocked_layout = QVBoxLayout()
        blocked_layout.addWidget(QLabel("Trading Status:"))
        setattr(self, f"blocked_status_{login}", QLabel("Active"))
        getattr(self, f"blocked_status_{login}").setStyleSheet("font-weight: bold; font-size: 16px; color: green;")
        blocked_layout.addWidget(getattr(self, f"blocked_status_{login}"))
        info_layout.addLayout(blocked_layout)
        tab_layout.addWidget(info_group)

        risk_group = QGroupBox("Risk Management Settings")
        risk_layout = QVBoxLayout(risk_group)

        upper_risk_layout = QHBoxLayout()
        limit_mode_group = QGroupBox("Limit Units")
        limit_mode_layout = QVBoxLayout(limit_mode_group)
        setattr(self, f"limit_mode_percent_{login}", QCheckBox("Percent (%)"))
        getattr(self, f"limit_mode_percent_{login}").setChecked(True)
        limit_mode_layout.addWidget(getattr(self, f"limit_mode_percent_{login}"))
        setattr(self, f"limit_mode_dollars_{login}", QCheckBox("Dollars ($)"))
        limit_mode_layout.addWidget(getattr(self, f"limit_mode_dollars_{login}"))
        getattr(self, f"limit_mode_percent_{login}").toggled.connect(lambda checked: getattr(self, f"limit_mode_dollars_{login}").setChecked(not checked))
        getattr(self, f"limit_mode_dollars_{login}").toggled.connect(lambda checked: getattr(self, f"limit_mode_percent_{login}").setChecked(not checked))
        upper_risk_layout.addWidget(limit_mode_group)

        daily_limit_group = QGroupBox("Daily Loss Limit")
        daily_limit_layout = QVBoxLayout(daily_limit_group)
        value_layout = QHBoxLayout()
        value_layout.addWidget(QLabel("Value:"))
        setattr(self, f"daily_loss_limit_{login}", QDoubleSpinBox())
        getattr(self, f"daily_loss_limit_{login}").setRange(0.1, 100000)
        getattr(self, f"daily_loss_limit_{login}").setValue(5)
        value_layout.addWidget(getattr(self, f"daily_loss_limit_{login}"))
        daily_limit_layout.addLayout(value_layout)
        setattr(self, f"daily_loss_mode_balance_{login}", QCheckBox("By Balance"))
        getattr(self, f"daily_loss_mode_balance_{login}").setChecked(True)
        daily_limit_layout.addWidget(getattr(self, f"daily_loss_mode_balance_{login}"))
        setattr(self, f"daily_loss_mode_equity_{login}", QCheckBox("By Equity"))
        daily_limit_layout.addWidget(getattr(self, f"daily_loss_mode_equity_{login}"))
        setattr(self, f"daily_loss_mode_both_{login}", QCheckBox("By Balance and Equity"))
        daily_limit_layout.addWidget(getattr(self, f"daily_loss_mode_both_{login}"))
        getattr(self, f"daily_loss_mode_balance_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "daily_loss_mode", "balance", checked))
        getattr(self, f"daily_loss_mode_equity_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "daily_loss_mode", "equity", checked))
        getattr(self, f"daily_loss_mode_both_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "daily_loss_mode", "both", checked))
        upper_risk_layout.addWidget(daily_limit_group)

        weekly_limit_group = QGroupBox("Weekly Loss Limit")
        weekly_limit_layout = QVBoxLayout(weekly_limit_group)
        value_layout = QHBoxLayout()
        value_layout.addWidget(QLabel("Value:"))
        setattr(self, f"weekly_loss_limit_{login}", QDoubleSpinBox())
        getattr(self, f"weekly_loss_limit_{login}").setRange(0.1, 100000)
        getattr(self, f"weekly_loss_limit_{login}").setValue(10)
        value_layout.addWidget(getattr(self, f"weekly_loss_limit_{login}"))
        weekly_limit_layout.addLayout(value_layout)
        setattr(self, f"weekly_loss_mode_balance_{login}", QCheckBox("By Balance"))
        getattr(self, f"weekly_loss_mode_balance_{login}").setChecked(True)
        weekly_limit_layout.addWidget(getattr(self, f"weekly_loss_mode_balance_{login}"))
        setattr(self, f"weekly_loss_mode_equity_{login}", QCheckBox("By Equity"))
        weekly_limit_layout.addWidget(getattr(self, f"weekly_loss_mode_equity_{login}"))
        setattr(self, f"weekly_loss_mode_both_{login}", QCheckBox("By Balance and Equity"))
        weekly_limit_layout.addWidget(getattr(self, f"weekly_loss_mode_both_{login}"))
        getattr(self, f"weekly_loss_mode_balance_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "weekly_loss_mode", "balance", checked))
        getattr(self, f"weekly_loss_mode_equity_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "weekly_loss_mode", "equity", checked))
        getattr(self, f"weekly_loss_mode_both_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "weekly_loss_mode", "both", checked))
        upper_risk_layout.addWidget(weekly_limit_group)
        risk_layout.addLayout(upper_risk_layout)

        lower_risk_layout = QHBoxLayout()
        drawdown_group = QGroupBox("Maximum Drawdown")
        drawdown_layout = QVBoxLayout(drawdown_group)
        value_layout = QHBoxLayout()
        value_layout.addWidget(QLabel("Value:"))
        setattr(self, f"max_drawdown_{login}", QDoubleSpinBox())
        getattr(self, f"max_drawdown_{login}").setRange(0.1, 100000)
        getattr(self, f"max_drawdown_{login}").setValue(10)
        value_layout.addWidget(getattr(self, f"max_drawdown_{login}"))
        drawdown_layout.addLayout(value_layout)
        setattr(self, f"drawdown_mode_balance_{login}", QCheckBox("By Balance"))
        getattr(self, f"drawdown_mode_balance_{login}").setChecked(True)
        drawdown_layout.addWidget(getattr(self, f"drawdown_mode_balance_{login}"))
        setattr(self, f"drawdown_mode_equity_{login}", QCheckBox("By Equity"))
        drawdown_layout.addWidget(getattr(self, f"drawdown_mode_equity_{login}"))
        setattr(self, f"drawdown_mode_both_{login}", QCheckBox("By Balance and Equity"))
        drawdown_layout.addWidget(getattr(self, f"drawdown_mode_both_{login}"))
        getattr(self, f"drawdown_mode_balance_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "drawdown_mode", "balance", checked))
        getattr(self, f"drawdown_mode_equity_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "drawdown_mode", "equity", checked))
        getattr(self, f"drawdown_mode_both_{login}").toggled.connect(lambda checked: self.handle_mode_toggle(login, "drawdown_mode", "both", checked))
        lower_risk_layout.addWidget(drawdown_group)

        actions_group = QGroupBox("Actions on Limit Exceedance")
        actions_layout = QVBoxLayout(actions_group)
        setattr(self, f"auto_close_{login}", QCheckBox("Automatically Close Positions"))
        getattr(self, f"auto_close_{login}").setChecked(True)
        actions_layout.addWidget(getattr(self, f"auto_close_{login}"))
        setattr(self, f"auto_unblock_{login}", QCheckBox("Automatically Unblock Trading"))
        getattr(self, f"auto_unblock_{login}").setChecked(False)
        actions_layout.addWidget(getattr(self, f"auto_unblock_{login}"))
        close_all_button = QPushButton("Close All Positions Now")
        close_all_button.clicked.connect(lambda: self.close_all_positions(login))
        actions_layout.addWidget(close_all_button)
        unblock_button = QPushButton("Unblock Trading")
        unblock_button.clicked.connect(lambda: self.unblock_trading(login))
        actions_layout.addWidget(unblock_button)
        lower_risk_layout.addWidget(actions_group)
        risk_layout.addLayout(lower_risk_layout)

        apply_settings_button = QPushButton("Apply Risk Management Settings")
        apply_settings_button.clicked.connect(lambda: self.apply_risk_settings(login))
        risk_layout.addWidget(apply_settings_button)
        tab_layout.addWidget(risk_group)

        risk_stats_group = QGroupBox("Risk Statistics")
        risk_stats_layout = QHBoxLayout(risk_stats_group)
        daily_balance_layout = QVBoxLayout()
        daily_balance_layout.addWidget(QLabel("Daily Balance Loss:"))
        setattr(self, f"daily_balance_loss_{login}", QLabel("0.00"))
        daily_balance_layout.addWidget(getattr(self, f"daily_balance_loss_{login}"))
        setattr(self, f"daily_balance_progress_{login}", QProgressBar())
        getattr(self, f"daily_balance_progress_{login}").setRange(0, 100)
        getattr(self, f"daily_balance_progress_{login}").setValue(0)
        daily_balance_layout.addWidget(getattr(self, f"daily_balance_progress_{login}"))
        risk_stats_layout.addLayout(daily_balance_layout)

        daily_equity_layout = QVBoxLayout()
        daily_equity_layout.addWidget(QLabel("Daily Equity Loss:"))
        setattr(self, f"daily_equity_loss_{login}", QLabel("0.00"))
        daily_equity_layout.addWidget(getattr(self, f"daily_equity_loss_{login}"))
        setattr(self, f"daily_equity_progress_{login}", QProgressBar())
        getattr(self, f"daily_equity_progress_{login}").setRange(0, 100)
        getattr(self, f"daily_equity_progress_{login}").setValue(0)
        daily_equity_layout.addWidget(getattr(self, f"daily_equity_progress_{login}"))
        risk_stats_layout.addLayout(daily_equity_layout)

        weekly_balance_layout = QVBoxLayout()
        weekly_balance_layout.addWidget(QLabel("Weekly Balance Loss:"))
        setattr(self, f"weekly_balance_loss_{login}", QLabel("0.00"))
        weekly_balance_layout.addWidget(getattr(self, f"weekly_balance_loss_{login}"))
        setattr(self, f"weekly_balance_progress_{login}", QProgressBar())
        getattr(self, f"weekly_balance_progress_{login}").setRange(0, 100)
        getattr(self, f"weekly_balance_progress_{login}").setValue(0)
        weekly_balance_layout.addWidget(getattr(self, f"weekly_balance_progress_{login}"))
        risk_stats_layout.addLayout(weekly_balance_layout)

        weekly_equity_layout = QVBoxLayout()
        weekly_equity_layout.addWidget(QLabel("Weekly Equity Loss:"))
        setattr(self, f"weekly_equity_loss_{login}", QLabel("0.00"))
        weekly_equity_layout.addWidget(getattr(self, f"weekly_equity_loss_{login}"))
        setattr(self, f"weekly_equity_progress_{login}", QProgressBar())
        getattr(self, f"weekly_equity_progress_{login}").setRange(0, 100)
        getattr(self, f"weekly_equity_progress_{login}").setValue(0)
        weekly_equity_layout.addWidget(getattr(self, f"weekly_equity_progress_{login}"))
        risk_stats_layout.addLayout(weekly_equity_layout)

        drawdown_layout = QVBoxLayout()
        drawdown_layout.addWidget(QLabel("Drawdown:"))
        balance_drawdown_layout = QHBoxLayout()
        balance_drawdown_layout.addWidget(QLabel("Balance:"))
        setattr(self, f"balance_drawdown_{login}", QLabel("0.00%"))
        balance_drawdown_layout.addWidget(getattr(self, f"balance_drawdown_{login}"))
        drawdown_layout.addLayout(balance_drawdown_layout)
        setattr(self, f"balance_drawdown_progress_{login}", QProgressBar())
        getattr(self, f"balance_drawdown_progress_{login}").setRange(0, 100)
        getattr(self, f"balance_drawdown_progress_{login}").setValue(0)
        drawdown_layout.addWidget(getattr(self, f"balance_drawdown_progress_{login}"))
        equity_drawdown_layout = QHBoxLayout()
        equity_drawdown_layout.addWidget(QLabel("Equity:"))
        setattr(self, f"equity_drawdown_{login}", QLabel("0.00%"))
        equity_drawdown_layout.addWidget(getattr(self, f"equity_drawdown_{login}"))
        drawdown_layout.addLayout(equity_drawdown_layout)
        setattr(self, f"equity_drawdown_progress_{login}", QProgressBar())
        getattr(self, f"equity_drawdown_progress_{login}").setRange(0, 100)
        getattr(self, f"equity_drawdown_progress_{login}").setValue(0)
        drawdown_layout.addWidget(getattr(self, f"equity_drawdown_progress_{login}"))
        risk_stats_layout.addLayout(drawdown_layout)

        positions_layout = QVBoxLayout()
        positions_layout.addWidget(QLabel("Open Positions:"))
        setattr(self, f"positions_count_{login}", QLabel("0"))
        positions_layout.addWidget(getattr(self, f"positions_count_{login}"))
        risk_stats_layout.addLayout(positions_layout)
        tab_layout.addWidget(risk_stats_group)

        positions_group = QGroupBox("Open Positions")
        positions_layout = QVBoxLayout(positions_group)
        positions_table = QTableWidget()
        positions_table.setColumnCount(7)
        positions_table.setHorizontalHeaderLabels(["Ticket", "Symbol", "Type", "Volume", "Open Price", "Profit/Loss", "Time"])
        positions_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        positions_table.setMinimumHeight(150)
        positions_table.setMaximumHeight(200)
        positions_layout.addWidget(positions_table)
        setattr(self, f"positions_table_{login}", positions_table)
        tab_layout.addWidget(positions_group)

        plot_group = QGroupBox("Equity Trend")
        plot_layout = QVBoxLayout(plot_group)
        equity_plot = pg.PlotWidget()
        equity_plot.setBackground('w')
        equity_plot.setTitle("Equity Trend")
        equity_plot.setLabel('left', 'Equity')
        equity_plot.setLabel('bottom', 'Time')
        equity_plot.showGrid(x=True, y=True)
        equity_plot.setMinimumHeight(200)
        equity_plot.setMaximumHeight(250)
        plot_layout.addWidget(equity_plot)
        setattr(self, f"equity_plot_{login}", equity_plot)
        setattr(self, f"equity_data_{login}", [])
        setattr(self, f"equity_times_{login}", [])
        tab_layout.addWidget(plot_group)

        account_info = {'server': server, 'login': login, 'password': password}
        risk_settings = {
            'limit_mode': 'percent',
            'daily_loss_limit': getattr(self, f"daily_loss_limit_{login}").value(),
            'daily_loss_mode': 'balance',
            'weekly_loss_limit': getattr(self, f"weekly_loss_limit_{login}").value(),
            'weekly_loss_mode': 'balance',
            'max_drawdown': getattr(self, f"max_drawdown_{login}").value(),
            'drawdown_mode': 'balance',
            'auto_close_positions': getattr(self, f"auto_close_{login}").isChecked(),
            'auto_unblock_trading': getattr(self, f"auto_unblock_{login}").isChecked()
        }

        monitor = AccountMonitor(account_info, risk_settings, self.db_path)
        monitor.update_signal.connect(self.update_account_info)
        monitor.error_signal.connect(self.show_error)
        monitor.start()

        self.account_monitors[login] = {
            'monitor': monitor,
            'tab_index': self.tabs.count() - 1,
            'risk_settings': risk_settings,
            'account_info': account_info
        }

        self.save_accounts()
        self.server_input.clear()
        self.login_input.clear()
        self.password_input.clear()
        self.status_bar.showMessage(f"Account {login} successfully connected")

    def handle_mode_toggle(self, login, mode_type, mode_value, checked):
        if checked:
            for value in ["balance", "equity", "both"]:
                if value != mode_value:
                    getattr(self, f"{mode_type}_{value}_{login}").setChecked(False)

    def create_info_widget(self, layout, label_text, object_name):
        info_layout = QVBoxLayout()
        info_layout.addWidget(QLabel(label_text))
        setattr(self, object_name, QLabel("0.00"))
        getattr(self, object_name).setStyleSheet("font-weight: bold; font-size: 16px;")
        info_layout.addWidget(getattr(self, object_name))
        layout.addLayout(info_layout)

    def update_account_info(self, data):
        account_id = data['account_id']
        getattr(self, f"balance_{account_id}").setText(f"{data['balance']:.2f}")
        getattr(self, f"equity_{account_id}").setText(f"{data['equity']:.2f}")
        getattr(self, f"margin_{account_id}").setText(f"{data['margin']:.2f}")
        getattr(self, f"free_margin_{account_id}").setText(f"{data['free_margin']:.2f}")
        getattr(self, f"margin_level_{account_id}").setText(f"{data['margin_level']:.2f}%")

        blocked_status = getattr(self, f"blocked_status_{account_id}")
        blocked_status.setText("BLOCKED" if data['blocked_trading'] else "Active")
        blocked_status.setStyleSheet(f"font-weight: bold; font-size: 16px; color: {'red' if data['blocked_trading'] else 'green'};")

        unit = "%" if self.account_monitors[account_id]['risk_settings']['limit_mode'] == 'percent' else "$"
        getattr(self, f"balance_drawdown_{account_id}").setText(f"{data['balance_drawdown']:.2f}{unit}")
        getattr(self, f"equity_drawdown_{account_id}").setText(f"{data['equity_drawdown']:.2f}{unit}")

        max_drawdown = self.account_monitors[account_id]['risk_settings']['max_drawdown']
        balance_percent = min(100, data['balance_drawdown'] / max_drawdown * 100) if max_drawdown > 0 else 0
        equity_percent = min(100, data['equity_drawdown'] / max_drawdown * 100) if max_drawdown > 0 else 0
        getattr(self, f"balance_drawdown_progress_{account_id}").setValue(int(balance_percent))
        getattr(self, f"equity_drawdown_progress_{account_id}").setValue(int(equity_percent))

        for prog in [f"balance_drawdown_progress_{account_id}", f"equity_drawdown_progress_{account_id}"]:
            percent = balance_percent if "balance" in prog else equity_percent
            color = "red" if percent > 90 else "orange" if percent > 70 else "green"
            getattr(self, prog).setStyleSheet(f"QProgressBar {{ text-align: center; }} QProgressBar::chunk {{ background-color: {color}; }}")

        getattr(self, f"daily_balance_loss_{account_id}").setText(f"{data['daily_balance_loss']:.2f}")
        getattr(self, f"weekly_balance_loss_{account_id}").setText(f"{data['weekly_balance_loss']:.2f}")
        getattr(self, f"daily_equity_loss_{account_id}").setText(f"{data['daily_equity_loss']:.2f}")
        getattr(self, f"weekly_equity_loss_{account_id}").setText(f"{data['weekly_equity_loss']:.2f}")
        getattr(self, f"positions_count_{account_id}").setText(str(data['positions_count']))

        daily_limit = self.account_monitors[account_id]['risk_settings']['daily_loss_limit']
        weekly_limit = self.account_monitors[account_id]['risk_settings']['weekly_loss_limit']
        for period, base in [("daily", "balance"), ("daily", "equity"), ("weekly", "balance"), ("weekly", "equity")]:
            loss = data[f"{period}_{base}_loss"]
            limit = daily_limit if period == "daily" else weekly_limit
            base_value = data['balance'] if base == "balance" else data['equity']
            percent = min(100, abs(loss) / (base_value * limit / 100) * 100 if self.account_monitors[account_id]['risk_settings']['limit_mode'] == 'percent' else abs(loss) / limit * 100) if limit > 0 and base_value > 0 else 0
            prog = getattr(self, f"{period}_{base}_progress_{account_id}")
            prog.setValue(int(percent))
            color = "red" if percent > 90 else "orange" if percent > 70 else "green"
            prog.setStyleSheet(f"QProgressBar {{ text-align: center; }} QProgressBar::chunk {{ background-color: {color}; }}")

        positions_table = getattr(self, f"positions_table_{account_id}")
        positions_table.setRowCount(len(data['positions']))
        for row, position in enumerate(data['positions']):
            positions_table.setItem(row, 0, QTableWidgetItem(str(position['ticket'])))
            positions_table.setItem(row, 1, QTableWidgetItem(position['symbol']))
            positions_table.setItem(row, 2, QTableWidgetItem("BUY" if position['type'] == mt5.ORDER_TYPE_BUY else "SELL"))
            positions_table.setItem(row, 3, QTableWidgetItem(str(position['volume'])))
            positions_table.setItem(row, 4, QTableWidgetItem(str(position['price_open'])))
            profit_item = QTableWidgetItem(f"{position['profit']:.2f}")
            profit_item.setForeground(Qt.red if position['profit'] < 0 else Qt.darkGreen)
            positions_table.setItem(row, 5, profit_item)
            positions_table.setItem(row, 6, QTableWidgetItem(dt.datetime.fromtimestamp(position['time']).strftime('%Y-%m-%d %H:%M:%S')))

        equity_plot = getattr(self, f"equity_plot_{account_id}")
        equity_data = getattr(self, f"equity_data_{account_id}")
        equity_times = getattr(self, f"equity_times_{account_id}")
        equity_data.append(data['equity'])
        equity_times.append(dt.datetime.now().timestamp())
        if len(equity_data) > 100:
            equity_data.pop(0)
            equity_times.pop(0)
        equity_plot.clear()
        equity_plot.plot(equity_times, equity_data, pen=pg.mkPen(color=(0, 150, 0), width=2))

    def unblock_trading(self, account_id):
        if account_id in self.account_monitors:
            with self.account_monitors[account_id]['monitor'].block_lock:
                self.account_monitors[account_id]['monitor'].blocked_trading = False
            self.status_bar.showMessage(f"Trading unblocked for account {account_id}")
        else:
            self.show_error(f"Account {account_id} not found")

    def close_all_positions(self, account_id):
        if account_id in self.account_monitors:
            self.account_monitors[account_id]['monitor'].close_all_positions()
            self.status_bar.showMessage(f"Request to close all positions for account {account_id} sent")
        else:
            self.show_error(f"Account {account_id} not found")

    def load_accounts(self):
        if not os.path.exists(self.db_path):
            return
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            cursor.execute('SELECT DISTINCT account_id FROM accounts')
            accounts = cursor.fetchall()
            conn.close()
            for account in accounts:
                self.connect_account_from_db(account[0])
        except sqlite3.Error as e:
            self.show_error(f"Error loading accounts: {str(e)}")

    def connect_account_from_db(self, account_id):
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            cursor.execute('SELECT server, login, password FROM accounts WHERE account_id = ? ORDER BY timestamp DESC LIMIT 1', (account_id,))
            account_info = cursor.fetchone()
            conn.close()
            if account_info:
                self.server_input.setText(account_info[0])
                self.login_input.setText(account_info[1])
                self.password_input.setText(account_info[2])
                self.connect_account()
            else:
                self.show_error(f"Data for account {account_id} not found")
        except sqlite3.Error as e:
            self.show_error(f"Error connecting account from DB: {str(e)}")

    def save_accounts(self):
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            cursor.execute('''CREATE TABLE IF NOT EXISTS accounts (
                account_id INTEGER PRIMARY KEY,
                server TEXT,
                login TEXT,
                password TEXT,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
            )''')
            for login, account in self.account_monitors.items():
                account_info = account['account_info']
                cursor.execute('INSERT OR REPLACE INTO accounts (account_id, server, login, password) VALUES (?, ?, ?, ?)',
                              (login, account_info['server'], account_info['login'], account_info['password']))
            conn.commit()
            conn.close()
        except sqlite3.Error as e:
            self.show_error(f"Error saving accounts: {str(e)}")

    def show_error(self, message):
        QMessageBox.critical(self, "Error", message)

    def close_application(self):
        for monitor in self.account_monitors.values():
            monitor['monitor'].stop()
        self.close()

    def check_clipboard(self):
        if not self.auto_paste.isChecked():
            return
        text = self.clipboard.text()
        if text != self.last_clipboard_text and ":" in text and text.count(":") >= 2:
            self.last_clipboard_text = text
            parts = text.strip().split(":")
            if len(parts) >= 3:
                self.server_input.setText(parts[0])
                self.login_input.setText(parts[1])
                self.password_input.setText(parts[2])

    def setup_styles(self):
        self.setStyleSheet("""
            QMainWindow { background-color: #f5f9ff; }
            QGroupBox { font-weight: bold; border: 1px solid #d0d0d0; border-radius: 5px; margin-top: 1ex; padding-top: 10px; }
            QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top center; padding: 0 5px; }
            QPushButton { background-color: #2e7d32; color: white; border: none; border-radius: 4px; padding: 8px 16px; font-weight: bold; }
            QPushButton:hover { background-color: #1b5e20; }
            QPushButton:pressed { background-color: #1b5e20; }
            QLineEdit, QDoubleSpinBox { border: 1px solid #d0d0d0; border-radius: 4px; padding: 6px; }
            QLabel { font-weight: bold; }
            QTableWidget { border: 1px solid #d0d0d0; border-radius: 4px; }
            QTableWidget::item:selected { background-color: #e3f2fd; color: black; }
            QHeaderView::section { background-color: #e0e0e0; padding: 4px; border: 1px solid #d0d0d0; font-weight: bold; }
            QScrollArea { border: none; background-color: #f5f9ff; }
            QScrollBar:vertical { border: none; background: #f0f0f0; width: 10px; margin: 0px; }
            QScrollBar::handle:vertical { background: #c0c0c0; min-height: 20px; border-radius: 5px; }
        """)

    def setup_tray(self):
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(QIcon("icon.png"))
        tray_menu = QMenu()
        tray_menu.addAction(QAction("Show", self, triggered=self.show))
        tray_menu.addAction(QAction("Hide", self, triggered=self.hide))
        tray_menu.addAction(QAction("Exit", self, triggered=self.close_application))
        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.show()
        self.tray_icon.activated.connect(self.tray_icon_activated)

    def tray_icon_activated(self, reason):
        if reason == QSystemTrayIcon.DoubleClick:
            self.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = RiskManagerGUI()
    window.show()
    sys.exit(app.exec_())
