初步测试通过
This commit is contained in:
+110
-36
@@ -1,7 +1,9 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox, filedialog
|
||||
from datetime import datetime
|
||||
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventDisableTrade, ActionEventEnableTrade, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, event_bus
|
||||
import threading
|
||||
import time
|
||||
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, event_bus
|
||||
from core.strategy_db import TradeTarget
|
||||
import configparser
|
||||
import sfgrid_constants
|
||||
@@ -10,14 +12,20 @@ import sfgrid_constants
|
||||
class TradeTargetUI:
|
||||
def __init__(self):
|
||||
self.data:dict[int, TradeTarget] = {}
|
||||
self.market_data_enabled = True # 添加市场数据监听状态变量
|
||||
self.market_data_enabled = False # 添加市场数据监听状态变量
|
||||
self.ui_refresh_enabled = False # 添加UI刷新线程状态变量
|
||||
self.registerEventHandler()
|
||||
|
||||
# 创建刷新线程标志
|
||||
self.refresh_thread_running = False # 默认不启动刷新线程
|
||||
|
||||
self.root = tk.Tk()
|
||||
self.root.title("三疯交易系统")
|
||||
self.root.geometry("1200x700")
|
||||
# 创建界面
|
||||
self.create_ui()
|
||||
|
||||
# 不再自动启动刷新线程,由市场数据开关控制
|
||||
|
||||
def registerEventHandler(self):
|
||||
event_bus.subscribe(MarketDataUpdate, self.onTradeTargetUpdated)
|
||||
@@ -25,10 +33,42 @@ class TradeTargetUI:
|
||||
event_bus.subscribe(ResultEventTradeDisabled, self.onTradeDisabled)
|
||||
event_bus.subscribe(MarketDataEnabled, self.onMarketDataToggled)
|
||||
event_bus.subscribe(MarketDataDisabled, self.onMarketDataToggled)
|
||||
event_bus.subscribe(ResultEventTradeTargetDeleted, self.onTradeTargetDeleted)
|
||||
|
||||
def start_refresh_thread(self):
|
||||
"""启动刷新线程"""
|
||||
if not hasattr(self, 'refresh_thread') or not self.refresh_thread.is_alive():
|
||||
self.refresh_thread = threading.Thread(target=self.refresh_loop, daemon=True)
|
||||
self.refresh_thread.start()
|
||||
|
||||
def refresh_loop(self):
|
||||
"""刷新循环"""
|
||||
while self.refresh_thread_running:
|
||||
# 在主线程中更新UI
|
||||
if hasattr(self, 'root') and self.root:
|
||||
self.root.after(0, self.refresh_table)
|
||||
time.sleep(0.5) # 每0.5秒刷新一次
|
||||
|
||||
def stop_refresh_thread(self):
|
||||
"""停止刷新线程"""
|
||||
self.refresh_thread_running = False
|
||||
|
||||
def onTradeTargetDeleted(self, id: int):
|
||||
"""处理交易标的删除完成事件"""
|
||||
# 从本地数据中删除
|
||||
if id in self.data:
|
||||
del self.data[id]
|
||||
# 添加日志
|
||||
self.add_log("INFO", f"交易标的已删除,ID: {id}")
|
||||
|
||||
def onMarketDataToggled(self, data:bool):
|
||||
self.market_data_enabled = self.market_data_switch_var.get()
|
||||
self.add_log("INFO", "市场数据监听已" + ("启用" if data else "禁用"))
|
||||
# 同步UI刷新线程状态
|
||||
if data:
|
||||
self.start_ui_refresh()
|
||||
else:
|
||||
self.stop_ui_refresh()
|
||||
|
||||
def onTradeEnabled(self, target:TradeTarget):
|
||||
self.add_log("INFO", f"交易启用: {target.stock_code} - {target.stock_name}")
|
||||
@@ -37,11 +77,10 @@ class TradeTargetUI:
|
||||
self.add_log("INFO", f"交易禁用: {target.stock_code} - {target.stock_name}")
|
||||
|
||||
|
||||
def onTradeTargetUpdated(self, target:TradeTarget):
|
||||
def onTradeTargetUpdated(self, target: TradeTarget):
|
||||
# 更新或添加数据到本地缓存
|
||||
self.data[target.get_id()] = target
|
||||
# 刷新表格显示
|
||||
self.refresh_table()
|
||||
# 不再直接刷新表格,由刷新线程统一处理
|
||||
|
||||
def create_ui(self):
|
||||
"""创建UI界面"""
|
||||
@@ -71,7 +110,7 @@ class TradeTargetUI:
|
||||
ttk.Separator(toolbar_frame, orient='vertical').pack(side=tk.LEFT, fill=tk.Y, padx=10)
|
||||
|
||||
# 市场数据监听开关
|
||||
self.market_data_switch_var = tk.BooleanVar(value=True)
|
||||
self.market_data_switch_var = tk.BooleanVar(value=False)
|
||||
self.market_data_switch = ttk.Checkbutton(
|
||||
toolbar_frame,
|
||||
text="📊 市场数据",
|
||||
@@ -99,8 +138,26 @@ class TradeTargetUI:
|
||||
self.market_data_enabled = self.market_data_switch_var.get()
|
||||
if self.market_data_enabled:
|
||||
event_bus.publish(ActionEnableMarketData, True)
|
||||
# 同步开启UI刷新线程
|
||||
self.start_ui_refresh()
|
||||
else:
|
||||
event_bus.publish(ActionDisableMarketData, True)
|
||||
# 同步关闭UI刷新线程
|
||||
self.stop_ui_refresh()
|
||||
|
||||
def start_ui_refresh(self):
|
||||
"""启动UI刷新线程"""
|
||||
if not self.refresh_thread_running:
|
||||
self.refresh_thread_running = True
|
||||
self.start_refresh_thread()
|
||||
self.add_log("INFO", "UI刷新线程已启动")
|
||||
|
||||
def stop_ui_refresh(self):
|
||||
"""停止UI刷新线程"""
|
||||
if self.refresh_thread_running:
|
||||
self.stop_refresh_thread()
|
||||
self.refresh_thread_running = False
|
||||
self.add_log("INFO", "UI刷新线程已停止")
|
||||
|
||||
def create_menu_bar(self):
|
||||
"""创建菜单栏"""
|
||||
@@ -112,7 +169,14 @@ class TradeTargetUI:
|
||||
menubar.add_cascade(label="系统", menu=system_menu)
|
||||
system_menu.add_command(label="系统设置", command=self.system_settings)
|
||||
system_menu.add_separator()
|
||||
system_menu.add_command(label="退出", command=self.root.destroy)
|
||||
system_menu.add_command(label="退出", command=self.on_exit)
|
||||
|
||||
def on_exit(self):
|
||||
"""退出程序"""
|
||||
# 停止刷新线程
|
||||
self.stop_refresh_thread()
|
||||
# 关闭窗口
|
||||
self.root.destroy()
|
||||
|
||||
def create_tables_area(self, parent):
|
||||
"""创建表格区域"""
|
||||
@@ -137,7 +201,7 @@ class TradeTargetUI:
|
||||
|
||||
columns = ("ID",
|
||||
"股票代码", "股票名称", "市场价", "持仓数量", "网格索引",
|
||||
"最新成交价", "计划买入价", "买入订单号", "计划卖出价", "卖出订单号",
|
||||
"最新成交价", "计划买入价", "计划卖出价", "当前订单价", "当前订单号", "当前订单类型",
|
||||
"启用状态", "交易状态"
|
||||
)
|
||||
|
||||
@@ -147,17 +211,18 @@ class TradeTargetUI:
|
||||
column_configs = {
|
||||
"ID": (50, tk.CENTER),
|
||||
"股票代码": (90, tk.CENTER),
|
||||
"股票名称": (100, tk.CENTER),
|
||||
"市场价": (60, tk.CENTER),
|
||||
"持仓数量": (90, tk.CENTER),
|
||||
"网格索引": (50, tk.CENTER),
|
||||
"最新成交价": (60, tk.CENTER),
|
||||
"计划买入价": (60, tk.CENTER),
|
||||
"买入订单号": (100, tk.CENTER),
|
||||
"计划卖出价": (60, tk.CENTER),
|
||||
"卖出订单号": (100, tk.CENTER),
|
||||
"启用状态": (100, tk.CENTER),
|
||||
"交易状态": (100, tk.CENTER)
|
||||
"股票名称": (80, tk.CENTER),
|
||||
"市场价": (70, tk.CENTER),
|
||||
"持仓数量": (80, tk.CENTER),
|
||||
"网格索引": (80, tk.CENTER),
|
||||
"最新成交价": (90, tk.CENTER),
|
||||
"计划买入价": (90, tk.CENTER),
|
||||
"计划卖出价": (90, tk.CENTER),
|
||||
"当前订单价": (90, tk.CENTER),
|
||||
"当前订单号": (90, tk.CENTER),
|
||||
"当前订单类型": (90, tk.CENTER),
|
||||
"启用状态": (80, tk.CENTER),
|
||||
"交易状态": (80, tk.CENTER)
|
||||
}
|
||||
|
||||
for col in columns:
|
||||
@@ -201,17 +266,18 @@ class TradeTargetUI:
|
||||
for temp in self.data:
|
||||
target: TradeTarget = self.data[temp]
|
||||
values = [
|
||||
target.id, # type: ignore
|
||||
target.id, # type: ignore
|
||||
target.stock_code,
|
||||
target.stock_name,
|
||||
f"{target.market_price:.3f}",
|
||||
"-" if target.market_price is None else f"{target.market_price:.3f}",
|
||||
target.current_position,
|
||||
target.grid_index,
|
||||
f"{target.last_trade_price:.2f}",
|
||||
f"{target.plan_buy_price:.2f}",
|
||||
target.current_buy_order_no,
|
||||
f"{target.plan_sell_price:.2f}",
|
||||
target.current_sell_order_no,
|
||||
f"{target.last_trade_price:.3f}",
|
||||
f"{target.plan_buy_price:.3f}",
|
||||
f"{target.plan_sell_price:.3f}",
|
||||
f"{target.current_order_price:.3f}",
|
||||
target.current_order_no,
|
||||
target.current_order_type,
|
||||
self.get_status_indicator(target),
|
||||
self.get_trade_enabled_indicator(target.enabled) # type: ignore
|
||||
]
|
||||
@@ -310,7 +376,6 @@ class TradeTargetUI:
|
||||
target.enabled = True # type: ignore
|
||||
event_bus.publish(ActionEventEnableTrade, target.get_id())
|
||||
# self.add_log("INFO", f"已启动交易: {target.stock_code} - {target.stock_name}")
|
||||
# self.refresh_table()
|
||||
# messagebox.showinfo("启动成功", f"已启动 {target.stock_code} ({target.stock_name}) 的交易")
|
||||
|
||||
def on_trade_enabled(self, target: TradeTarget):
|
||||
@@ -337,7 +402,6 @@ class TradeTargetUI:
|
||||
target.enabled = False # type: ignore
|
||||
event_bus.publish(ActionEventDisableTrade, target.get_id())
|
||||
# self.add_log("INFO", f"已暂停交易: {target.stock_code} - {target.stock_name}")
|
||||
# self.refresh_table()
|
||||
# messagebox.showinfo("暂停成功", f"已暂停 {target.stock_code} ({target.stock_name}) 的交易")
|
||||
|
||||
def delete_selected_trade(self):
|
||||
@@ -356,14 +420,9 @@ class TradeTargetUI:
|
||||
)
|
||||
|
||||
if result:
|
||||
try:
|
||||
del self.data[target.get_id()]
|
||||
self.add_log("WARNING", f"已删除交易标的: {target.stock_code} - {target.stock_name}")
|
||||
self.refresh_table()
|
||||
messagebox.showinfo("删除成功", f"已删除 {target.stock_code} ({target.stock_name})")
|
||||
except Exception as e:
|
||||
self.add_log("ERROR", f"删除失败: {str(e)}")
|
||||
messagebox.showerror("删除失败", f"删除交易标的时出错:{str(e)}")
|
||||
# 通过事件总线发出删除动作
|
||||
event_bus.publish(ActionEventDeleteTradeTarget, target.get_id())
|
||||
self.add_log("INFO", f"已发送删除请求: {target.stock_code} - {target.stock_name}")
|
||||
|
||||
def add_trade_target(self):
|
||||
"""添加新的交易标的"""
|
||||
@@ -434,12 +493,27 @@ class TradeTargetUI:
|
||||
|
||||
def refresh_table(self):
|
||||
"""刷新表格数据"""
|
||||
# 保存当前选中的项
|
||||
selected_items = self.trade_table.selection()
|
||||
selected_values = []
|
||||
for item in selected_items:
|
||||
values = self.trade_table.item(item)['values']
|
||||
if values:
|
||||
selected_values.append(values[0]) # 保存ID
|
||||
|
||||
# 清空表格
|
||||
for item in self.trade_table.get_children():
|
||||
self.trade_table.delete(item)
|
||||
|
||||
# 重新填充
|
||||
self.populate_trade_table()
|
||||
|
||||
# 恢复之前选中的项
|
||||
if selected_values:
|
||||
for item in self.trade_table.get_children():
|
||||
values = self.trade_table.item(item)['values']
|
||||
if values and values[0] in selected_values:
|
||||
self.trade_table.selection_add(item)
|
||||
|
||||
def add_log(self, level, message):
|
||||
"""添加日志记录"""
|
||||
|
||||
Reference in New Issue
Block a user