import random import tkinter as tk from tkinter import ttk from typing import List from datetime import datetime from core.strategy_db import TradeTarget class TradeTargetUI: def __init__(self): self.root = tk.Tk() self.root.title("交易标的监控系统") self.root.geometry("1200x700") # 创建界面 self.create_ui() def create_ui(self): """创建UI界面""" # 主框架 main_frame = ttk.Frame(self.root) main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # 表格区域 self.create_tables_area(main_frame) # 按钮区域 self.create_buttons_area(main_frame) def create_tables_area(self, parent): """创建表格区域""" tables_frame = ttk.Frame(parent) tables_frame.pack(fill=tk.BOTH, expand=True) # 左侧表格框架 left_frame = ttk.LabelFrame(tables_frame, text="交易标的详情", padding=10) left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5)) # 右侧表格框架 right_frame = ttk.LabelFrame(tables_frame, text="操作日志", padding=10) right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0)) # 创建左侧交易标的表格 self.create_trade_target_table(left_frame) # 创建右侧操作日志表格 self.create_log_table(right_frame) def create_trade_target_table(self, parent): """创建交易标的表格""" # 创建Treeview columns = ( "id", "stock_code", "stock_name", "current_position", "grid_index", "last_trade_price", "current_buy_price", "current_sell_price", "current_buy_order_no", "current_sell_order_no", "status", "enabled" ) self.trade_table = ttk.Treeview(parent, columns=columns, show='headings', height=12) # 定义列标题和宽度 column_configs = { "id": ("ID", 80), "stock_code": ("股票代码", 80), "stock_name": ("股票名称", 100), "current_position": ("持仓数量", 90), "grid_index": ("网格索引", 80), "last_trade_price": ("最新成交价", 90), "current_buy_price": ("当前买入价", 90), "current_sell_price": ("当前卖出价", 90), "current_buy_order_no": ("买入订单号", 120), "current_sell_order_no": ("卖出订单号", 120), "status": ("状态", 70), "enabled": ("启用状态", 80) } for col in columns: title, width = column_configs[col] self.trade_table.heading(col, text=title) self.trade_table.column(col, width=width, anchor=tk.CENTER) # 填充数据 self.populate_trade_table() # 滚动条 scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.trade_table.yview) self.trade_table.configure(yscrollcommand=scrollbar.set) # 布局 self.trade_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) # 绑定双击事件 self.trade_table.bind("", self.on_table_double_click) def populate_trade_table(self): """填充交易标的表格数据""" # 颜色标签 self.trade_table.tag_configure('enabled', background='#f0f8ff') # 淡蓝色 self.trade_table.tag_configure('disabled', background='#f5f5f5') # 淡灰色 def create_log_table(self, parent): """创建操作日志表格""" columns = ("timestamp", "level", "message") self.log_table = ttk.Treeview(parent, columns=columns, show='headings', height=12) log_column_configs = { "timestamp": ("时间", 120), "level": ("级别", 60), "message": ("消息", 200) } for col in columns: title, width = log_column_configs[col] self.log_table.heading(col, text=title) self.log_table.column(col, width=width, anchor=tk.W) # 填充示例日志 sample_logs = [ ("2024-01-15 10:30:15", "INFO", "系统启动成功"), ("2024-01-15 10:31:22", "DEBUG", "加载交易标的: 5个"), ("2024-01-15 10:32:45", "INFO", "000001 - 网格交易线程启动"), ("2024-01-15 10:33:10", "WARNING", "601318 - 未启用交易"), ("2024-01-15 10:34:30", "ERROR", "300750 - 订单提交失败"), ("2024-01-15 10:35:18", "INFO", "600036 - 买入订单创建成功"), ("2024-01-15 10:36:05", "INFO", "数据刷新完成") ] for log in sample_logs: self.log_table.insert('', tk.END, values=log) # 滚动条 scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.log_table.yview) self.log_table.configure(yscrollcommand=scrollbar.set) self.log_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) def create_buttons_area(self, parent): """创建按钮区域""" buttons_frame = ttk.LabelFrame(parent, text="操作面板", padding=15) buttons_frame.pack(fill=tk.X, pady=(10, 0)) # 创建五个功能按钮 self.create_five_buttons(buttons_frame) def create_five_buttons(self, parent): """创建五个功能按钮""" button_configs = [ ("刷新数据", self.refresh_data, "🔄"), ("启用交易", self.enable_trading, "✅"), ("禁用交易", self.disable_trading, "⛔"), ("修改参数", self.modify_parameters, "⚙️"), ("系统设置", self.system_settings, "🔧") ] for text, command, icon in button_configs: btn = ttk.Button( parent, text=f"{icon} {text}", command=command, width=15 ) btn.pack(side=tk.LEFT, padx=8) def refresh_data(self): """刷新数据功能""" # 模拟数据更新 for target in self.trade_targets: if target.enabled: # 随机更新价格和仓位 target.last_trade_price += round((random.random() - 0.5) * 0.5, 2) target.current_position += random.randint(-50, 50) # 重新填充表格 for item in self.trade_table.get_children(): self.trade_table.delete(item) for target in self.trade_targets: values = [ target.id, target.stock_code, target.stock_name, target.current_position, target.grid_index, target.last_trade_price, target.current_buy_price, target.current_buy_order_no, target.current_sell_price, target.current_sell_order_no, self.get_status_text(target.status), "是" if target.enabled else "否" ] tags = ('enabled',) if target.enabled else ('disabled',) self.trade_table.insert('', tk.END, values=values, tags=tags) # 添加日志 self.add_log("INFO", "数据刷新完成") def enable_trading(self): """启用交易功能""" selected = self.trade_table.selection() if selected: item = selected[0] values = self.trade_table.item(item)['values'] # 在实际应用中,这里会调用实际的启用逻辑 self.add_log("INFO", f"启用交易标的: {values[0]}") def disable_trading(self): """禁用交易功能""" selected = self.trade_table.selection() if selected: item = selected[0] values = self.trade_table.item(item)['values'] self.add_log("INFO", f"禁用交易标的: {values[0]}") def modify_parameters(self): """修改参数功能""" selected = self.trade_table.selection() if selected: item = selected[0] values = self.trade_table.item(item)['values'] # 弹出修改对话框 self.show_parameter_dialog() def system_settings(self): """系统设置功能""" # 弹出系统设置对话框 settings_window = tk.Toplevel(self.root) settings_window.title("系统设置") settings_window.geometry("400x300") ttk.Label(settings_window, text="网格交易系统设置", font=('Arial', 12, 'bold')).pack(pady=20) # 添加一些设置选项 options = [ ("自动刷新间隔", "5秒"), ("价格变动阈值", "0.1%"), ("最大持仓数量", "10000"), ("最小交易数量", "100") ] for label, value in options: frame = ttk.Frame(settings_window) frame.pack(fill=tk.X, padx=20, pady=10) ttk.Label(frame, text=label, width=20).pack(side=tk.LEFT) ttk.Label(frame, text=value).pack(side=tk.RIGHT) def get_status_text(self, status): """获取状态文本""" status_map = { 0: "新标的", 1: "交易中" } return status_map.get(status, "未知") def on_table_double_click(self, event): """表格双击事件""" selected = self.trade_table.selection() if selected: item = selected[0] values = self.trade_table.item(item)['values'] self.add_log("DEBUG", f"双击查看详情: {values[0]} - {values[1]}") def add_log(self, level, message): """添加日志记录""" timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.log_table.insert('', 0, values=(timestamp, level, message)) def run(self): """运行程序""" # 初始填充数据 for target in self.trade_targets: values = [ target.stock_code, target.stock_name, target.current_position, target.grid_index, target.last_trade_price, target.current_buy_price, target.current_buy_order_no, target.current_sell_price, target.current_sell_order_no, self.get_status_text(target.status), "是" if target.enabled else "否" ] tags = ('enabled',) if target.enabled else ('disabled',) self.trade_table.insert('', tk.END, values=values, tags=tags) self.root.mainloop() # 更专业的版本,集成实际的TradeTarget对象 class ProfessionalTradeUI(TradeTargetUI): def __init__(self, trade_targets: List[TradeTarget] = None): if trade_targets is not None: self.trade_targets = trade_targets else: self.trade_targets = self.create_advanced_sample_data() super().__init__() def create_trade_target_table(self, parent): """专业版的交易标的表格""" columns = ("ID", "股票代码", "股票名称", "持仓数量", "网格索引", "最新成交价", "当前买入价", "当前买入订单号", "当前卖出价", "当前卖出订单号", "启用状态", "交易状态" ) self.trade_table = ttk.Treeview(parent, columns=columns, show='headings', height=15) # 专业化的列配置 column_configs = { "ID": (50, tk.CENTER), "股票代码": (90, tk.CENTER), "股票名称": (100, tk.CENTER), "持仓数量": (90, tk.CENTER), "网格索引": (80, tk.CENTER), "最新成交价": (100, tk.CENTER), "当前买入价": (100, tk.CENTER), "当前买入订单号": (100, tk.CENTER), "当前卖出订单号": (100, tk.CENTER), "当前卖出价": (100, tk.CENTER), "启用状态": (80, tk.CENTER), "交易状态": (80, tk.CENTER), "买入订单号": (120, tk.CENTER), "卖出订单号": (120, tk.CENTER) } for col in columns: width, anchor = column_configs[col] self.trade_table.heading(col, text=col) self.trade_table.column(col, width=width, anchor=anchor) # 带颜色的标签 self.trade_table.tag_configure('trading', background='#e8f5e8') # 交易中的绿色背景 self.trade_table.tag_configure('paused', background='#fff3cd') # 暂停的黄色背景 self.trade_table.tag_configure('inactive', background='#f8d7da') # 禁用的红色背景 # 填充数据 for temp in self.trade_targets: target:TradeTarget = temp values = [ target.id, target.stock_code, target.stock_name, target.current_position, target.grid_index, f"{target.last_trade_price:.2f}", f"{target.current_buy_price:.2f}", target.current_buy_order_no, f"{target.current_sell_price:.2f}", target.current_sell_order_no, "已启用" if target.enabled else "未启用", "交易中" if target.status == 1 else "新标的" ] # 根据状态设置标签 if target.enabled and target.status == 1: tags = ('trading',) elif target.enabled and target.status == 0: tags = ('paused',) else: tags = ('inactive',) self.trade_table.insert('', tk.END, values=values, tags=tags) # 滚动条 scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.trade_table.yview) self.trade_table.configure(yscrollcommand=scrollbar.set) self.trade_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) def refresh_data(self): """专业版的刷新数据功能""" for target in self.trade_targets: if target.enabled: # 模拟实时的价格变动 price_change = (random.random() - 0.5) * 0.1 target.last_trade_price = round(target.last_trade_price + price_change, 2) # 更新表格 for item in self.trade_table.get_children(): self.trade_table.delete(item) for target in self.trade_targets: values = [ target.id, target.stock_code, target.stock_name, target.current_position, target.grid_index, f"{target.last_trade_price:.2f}", f"{target.current_buy_price:.2f}", f"{target.current_sell_price:.2f}", "已启用" if target.enabled else "未启用", "交易中" if target.status == 1 else "新标的" ] # 设置标签 if target.enabled and target.status == 1: tags = ('trading',) elif target.enabled and target.status == 0: tags = ('paused',) else: tags = ('inactive',) self.trade_table.insert('', tk.END, values=values, tags=tags) self.add_log("INFO", "专业版数据刷新完成 - 包含实时价格模拟") def show_parameter_dialog(self): """显示参数修改对话框""" dialog = tk.Toplevel(self.root) dialog.title("交易参数设置") dialog.geometry("500x400") # 创建配置表单 ttk.Label(dialog, text="交易标的参数配置", font=('Arial', 12, 'bold')).pack(pady=20) # 创建标签和输入框 form_frame = ttk.Frame(dialog) form_frame.pack(fill=tk.BOTH, expand=True, padx=20) # 这里可以添加具体的参数配置表单 ttk.Label(form_frame, text="双击表格项可查看详情", font=('Arial', 10)).pack(pady=10) def system_settings(self): """专业版的系统设置""" settings_window = tk.Toplevel(self.root) settings_window.title("网格交易系统配置") settings_window.geometry("600x400") # 创建选项卡 notebook = ttk.Notebook(settings_window) notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # 基础设置 basic_frame = ttk.Frame(notebook) notebook.add(basic_frame, text="基础设置") # 高级设置 advanced_frame = ttk.Frame(notebook) notebook.add(advanced_frame, text="高级设置") # 添加具体的配置选项 settings = [ ("网格宽度", "0.5%"), ("网格数量", "10层"), ("交易间隔", "30秒"), ("单笔数量", "100股") ] for i, (label, default) in enumerate(settings): frame = ttk.Frame(basic_frame) frame.pack(fill=tk.X, padx=20, pady=10) ttk.Label(frame, text=label, width=15).pack(side=tk.LEFT) entry = ttk.Entry(frame, width=20) entry.insert(0, default) entry.pack(side=tk.RIGHT) # 使用示例 if __name__ == "__main__": print("交易标的监控系统启动...") print("功能说明:") print(" - 左侧表格显示所有交易标的详细信息") print(" - 右侧表格显示操作日志") print(" - 底部五个功能按钮提供操作") # 创建并运行界面 app = ProfessionalTradeUI() app.run()