new update

This commit is contained in:
2025-11-11 17:45:56 +08:00
parent 662a1ea7c1
commit 54fd7c9545
7 changed files with 148 additions and 326 deletions
+14
View File
@@ -0,0 +1,14 @@
# 删除交易标的事件
EventTradeTargetUpdate = "trade_target_update"
ActionEventAddTradeTarget = "add_trade_target"
ResultEventTradeTargetAdded = "trade_target_added"
ActionEventDeleteTradeTarget = "delete_trade_target"
ResultEventTradeTargetDeleted = "trade_target_deleted"
# 网格修正事件
ActionEventGridFix = "grid_fix"
# 定义事件处理函数
ActionEventEnableTrade = "enable_trade"
ResultEventTradeEnabled = "trade_enabled"
ActionEventDisableTrade = "disable_trade"
ResultEventTradeDisabled = "trade_disabled"
+99 -256
View File
@@ -1,6 +1,10 @@
# coding:utf-8
from typing import Any
from core.sfgrid.model import SFGridTradeTarget as TradeTarget
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventAddTradeTarget, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, EventTradeTargetUpdate, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, ActionEventGridFix, event_bus
from .bus_events import ActionEventAddTradeTarget, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, EventTradeTargetUpdate, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetAdded, ResultEventTradeTargetDeleted, ActionEventGridFix
from core.eventbus import event_bus, MarketDataEnabled, MarketDataDisabled, MarketDataUpdate
from xtquant import xttrader
from xtquant.xttrader import XtQuantTrader
import time
@@ -9,7 +13,7 @@ from peewee import ModelSelect
import core.sfgrid.model as model
import config
from core.sfgrid.sfgrid_strategy import SFGridStrategy
from core.util import getInstrumentName, getStockPosition, queryPendingOrder
from core.util import getStockPosition, queryPendingOrder
from xtquant.xttrader import XtQuantTrader
from xtquant.xttype import StockAccount, XtAsset, XtOrder, XtPosition, XtTrade
from xtquant import xtdata
@@ -21,52 +25,79 @@ from core.qmt import qmtv
from core.sfgrid.objects import GridFixData
# 量化核心控制对象
class SFGridController(XtQuantTraderCallback):
class SFGridController:
def __init__(self):
super().__init__()
self.registerEventHandler()
self.listening_stock = []
self.stock_trade_ctrl = {}
self.init_instrument_pool(qmtv.xttrader, qmtv.account) # type: ignore
self.seq = None
PrintLog(LogLevel.INFO, '- [成功]三疯交易系统初始化完成')
self.startMarketData()
def registerEventHandler(self):
event_bus.subscribe(ActionEventEnableTrade, self.onEnableTrade)
event_bus.subscribe(ActionEventDisableTrade, self.onDisableTrade)
event_bus.subscribe(ActionEnableMarketData, self.onMarketDataEnabled)
event_bus.subscribe(ActionDisableMarketData, self.onMarketDataDisabled)
event_bus.subscribe(ActionEventAddTradeTarget, self.onAddTradeTarget)
event_bus.subscribe(ActionEventDeleteTradeTarget, self.onDeleteTradeTarget)
event_bus.subscribe(ActionEventGridFix, self.onGridFix)
def onDeleteTradeTarget(self, id: int):
def onDeleteTradeTarget(self, target: TradeTarget):
"""处理删除交易标的事件"""
self.del_trade_target(id)
# 发布删除完成事件
event_bus.publish(ResultEventTradeTargetDeleted, id)
id = target.get_id()
try:
# 从数据库中删除
target.delete_instance()
PrintLog(LogLevel.INFO, f"已删除交易标的: id{id} {target.stock_code} - {target.stock_name}")
# 发布删除完成事件
event_bus.publish(ResultEventTradeTargetDeleted, target)
except Exception as e:
PrintLog(LogLevel.ERROR, f"删除交易标的失败 ID {id}: {str(e)}")
def onAddTradeTarget(self, stock_code: str):
"""处理添加交易标的事件"""
self.add_trade_target(stock_code)
def onMarketDataEnabled(self, data):
"""处理市场数据监听启用事件"""
self.startMarketData()
def onMarketDataDisabled(self, data):
"""处理市场数据监听禁用事件"""
self.stopMarketData()
try:
stock_name = qmtv.getInstrumentName(stock_code)
if not stock_name:
PrintLog(LogLevel.ERROR, f'无法获取股票代码 {stock_code} 的名称,请检查代码是否正确')
return
# 检查是否已存在该标的
existing_target = TradeTarget.get_or_none(TradeTarget.stock_code == stock_code)
if existing_target:
PrintLog(LogLevel.INFO, f'交易标的 {stock_code} {stock_name} 已存在')
return
# 刷新标的持仓
pos = qmtv.getStockPosition(stock_code) # type: ignore
new_target = TradeTarget.create(
stock_name=stock_name,
stock_code=stock_code,
market_price=0.0,
current_position=pos,
grid_index=0,
last_trade_price=0.0,
plan_buy_price=0.0,
plan_sell_price=0.0,
current_order_price=0.0,
current_order_no='',
current_order_type=''
)
new_target.save()
# 更新标的池
event_bus.publish(ResultEventTradeTargetAdded, new_target)
except Exception as e:
PrintLog(LogLevel.ERROR, f'新增交易标的失败 {stock_code} {e}')
def onEnableTrade(self, id: int):
self.start_stock_trade(id)
pass
# self.start_stock_trade(id)
def onDisableTrade(self, id: int):
self.pause_stock_trade(id)
pass
# self.pause_stock_trade(id)
def onGridFix(self, data: GridFixData):
"""处理网格修正事件"""
@@ -82,28 +113,9 @@ class SFGridController(XtQuantTraderCallback):
target.grid_index = grid_index
target.save()
# 更新内存中的交易标的
if target.get_id() in self.instrument_pool:
self.instrument_pool[target.get_id()] = target
# 更新交易控制器中的网格信息
if target.stock_code in self.stock_trade_ctrl:
trade_controller: SFGridStrategy = self.stock_trade_ctrl[target.stock_code]
trade_controller.updateGridIndex(grid_index) # type: ignore
PrintLog(LogLevel.INFO, f"网格修正已应用: {target.stock_code} - {target.stock_name}, 网格索引: {grid_index}")
except Exception as e:
PrintLog(LogLevel.ERROR, f"网格修正更新失败: {str(e)}")
def startMarketData(self):
PrintLog(LogLevel.INFO, '- 启动市场数据订阅')
self.seq = xtdata.subscribe_whole_quote(['SH', 'SZ'], callback=self.onDataUpdate)
if self.seq == -1:
PrintLog(LogLevel.ERROR, '- 市场数据订阅失败')
else:
event_bus.publish(MarketDataEnabled, True)
PrintLog(LogLevel.INFO, f'- 市场数据订阅成功, 订阅号={self.seq}')
@@ -114,222 +126,53 @@ class SFGridController(XtQuantTraderCallback):
xtdata.unsubscribe_quote(self.seq)
event_bus.publish(MarketDataDisabled, False)
def add_trade_target(self, stock_code: str):
try:
stock_name = getInstrumentName(stock_code)
if not stock_name:
PrintLog(LogLevel.ERROR, f'无法获取股票代码 {stock_code} 的名称,请检查代码是否正确')
return
# 检查是否已存在该标的
existing_target = TradeTarget.get_or_none(TradeTarget.stock_code == stock_code)
if existing_target:
PrintLog(LogLevel.INFO, f'交易标的 {stock_code} {stock_name} 已存在')
return
new_target = TradeTarget.create(
stock_name=stock_name,
stock_code=stock_code,
market_price=0.0,
current_position=0,
grid_index=0,
last_trade_price=0.0,
plan_buy_price=0.0,
plan_sell_price=0.0,
current_order_price=0.0,
current_order_no='',
current_order_type=''
)
new_target.save()
PrintLog(LogLevel.INFO, f'新增交易标的 {stock_code} {stock_name}, {new_target.id}')
# 刷新标的持仓
pos = getStockPosition(stock_code, self.xt_trader, self.account) # type: ignore
TradeTarget.update(current_position=pos).where(TradeTarget.stock_code == stock_code).execute()
# 更新标的池
self.refresh_targets()
# 添加交易控制器
stockTradeController = SFGridStrategy(new_target, self.xt_trader, self.account) # type: ignore
self.stock_trade_ctrl[stock_code] = stockTradeController
except Exception as e:
PrintLog(LogLevel.ERROR, f'新增交易标的失败 {stock_code} {e}')
def del_trade_target(self, id:int):
try:
# 检查标的是否存在
if id not in self.instrument_pool:
PrintLog(LogLevel.ERROR, f"交易标的 ID {id} 不存在")
return
target: TradeTarget = self.instrument_pool[id]
# 如果存在交易控制器,先停止交易
if target.stock_code in self.stock_trade_ctrl:
# 停止交易控制器
del self.stock_trade_ctrl[target.stock_code]
# 从数据库中删除
target.delete_instance()
# 从内存中删除
del self.instrument_pool[id]
# 刷新标的池
self.refresh_targets()
PrintLog(LogLevel.INFO, f"已删除交易标的: {target.stock_code} - {target.stock_name}")
except Exception as e:
PrintLog(LogLevel.ERROR, f"删除交易标的失败 ID {id}: {str(e)}")
def init_instrument_pool(self, xtTrader:XtQuantTrader, account:StockAccount):
self.refresh_targets()
for id in self.instrument_pool:
target:TradeTarget = self.instrument_pool[id]
status = "新建" if target.status == 0 else "已建初始仓"
PrintLog(LogLevel.INFO, f' [序号-{id}] 股票代码: {target.stock_code}-{target.stock_name} 当前持仓: {getStockPosition(target.stock_code, self.xt_trader, self.account)} 网格索引: {target.grid_index} 基准价格 {config.grid_price[target.grid_index]} 状态: {status} 启用交易线程: {'自动交易中' if target.enabled else '交易已停止'}') # type: ignore
tradeTarget:TradeTarget = self.instrument_pool[id]
tradeTarget.current_position = getStockPosition(tradeTarget.stock_code, xtTrader, account) # type: ignore
result = tradeTarget.save()
PrintLog(LogLevel.INFO, f' |- 同步[{target.stock_code}-{target.stock_name}]持仓信息[{'成功' if result == 1 else '失败'}]')
stockTradeController = SFGridStrategy(tradeTarget, self.xt_trader, self.account) # type: ignore
self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController
event_bus.publish(EventTradeTargetUpdate, tradeTarget)
PrintLog(LogLevel.INFO, f'- [成功]交易标的信息初始化, 共 {len(self.instrument_pool)} 个标的')
# # 初始化指定标的交易控制器
# def start_stock_trade(self, tradeTarget: TradeTarget):
# # check existing thread
# if tradeTarget.stock_code in self.stock_trade_ctrl:
# tradeController: SFGridStrategy = self.stock_trade_ctrl[tradeTarget.stock_code]
# tradeTarget = tradeController.enabledTrading(True)
# self.instrument_pool[id] = tradeTarget
# event_bus.publish(ResultEventTradeEnabled, tradeTarget)
# else:
# PrintLog(LogLevel.INFO, f"\t创建标的交易控制器 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}")
def refresh_targets(self):
# 更新标的池
results:ModelSelect = TradeTarget.select()
self.instrument_pool: dict[int, TradeTarget] = {}
for temp in results:
result :TradeTarget = temp
self.instrument_pool[result.get_id()] = result
# 初始化指定标的交易控制器
def start_stock_trade(self, id: int):
tradeTarget: TradeTarget = self.instrument_pool[id]
# check existing thread
if tradeTarget.stock_code in self.stock_trade_ctrl:
tradeController: SFGridStrategy = self.stock_trade_ctrl[tradeTarget.stock_code]
tradeTarget = tradeController.enabledTrading(True)
self.instrument_pool[id] = tradeTarget
event_bus.publish(ResultEventTradeEnabled, tradeTarget)
else:
PrintLog(LogLevel.INFO, f"\t创建标的交易控制器 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}")
def pause_stock_trade(self, id: int):
localTarget: TradeTarget = self.instrument_pool[id]
print(f'暂停标的交易 {localTarget.stock_code} - enabled {localTarget.enabled}')
if localTarget.stock_code in self.stock_trade_ctrl:
tradeController: SFGridStrategy = self.stock_trade_ctrl[localTarget.stock_code]
tradeTarget = tradeController.enabledTrading(False)
orders = queryPendingOrder(localTarget.stock_code, tradeController.getName(), self.xt_trader, self.account) # type: ignore
for order in orders:
qmtv.xttrader.cancel_order_stock_async(qmtv.account, order.order_id)
print(f'取消未成交订单 {len(orders)}')
self.instrument_pool[id] = tradeTarget
event_bus.publish(ResultEventTradeDisabled, tradeTarget)
else:
print(f"标的交易控制器不存在 {localTarget.stock_code} {localTarget.stock_name}\n")
# def pause_stock_trade(self, id: int):
# localTarget: TradeTarget = self.instrument_pool[id]
# print(f'暂停标的交易 {localTarget.stock_code} - enabled {localTarget.enabled}')
# if localTarget.stock_code in self.stock_trade_ctrl:
# tradeController: SFGridStrategy = self.stock_trade_ctrl[localTarget.stock_code]
# tradeTarget = tradeController.enabledTrading(False)
# orders = queryPendingOrder(localTarget.stock_code, tradeController.getName(), self.xt_trader, self.account) # type: ignore
# for order in orders:
# qmtv.xttrader.cancel_order_stock_async(qmtv.account, order.order_id)
# print(f'取消未成交订单 {len(orders)}')
# self.instrument_pool[id] = tradeTarget
# event_bus.publish(ResultEventTradeDisabled, tradeTarget)
# else:
# print(f"标的交易控制器不存在 {localTarget.stock_code} {localTarget.stock_name}\n")
# ====== 市场回调方法 -- 以下方法由XtQuantData调用 ======
def onDataUpdate(self, data):
# 收集所有市场数据用于市场监控
for stock_code, tickData in data.items():
if stock_code in self.stock_trade_ctrl:
stock_controller: SFGridStrategy = self.stock_trade_ctrl[stock_code]
stock_controller.onDataUpdate(data)
else:
# 非目标交易,发布市场数据更新事件用于市场监控
lastPrice = tickData['lastPrice']
if lastPrice == 10 or stock_code in self.listening_stock:
# 发布市场数据更新事件用于市场监控
market_target = TradeTarget()
market_target.stock_code = stock_code
market_target.stock_name = getInstrumentName(stock_code) # type: ignore
market_target.market_price = lastPrice # type: ignore
event_bus.publish(MarketDataUpdate, market_target)
if stock_code not in self.listening_stock:
self.listening_stock.append(stock_code)
# def onDataUpdate(self, data):
# # 收集所有市场数据用于市场监控
# for stock_code, tickData in data.items():
# if stock_code in self.stock_trade_ctrl:
# stock_controller: SFGridStrategy = self.stock_trade_ctrl[stock_code]
# stock_controller.onDataUpdate(data)
# else:
# # 非目标交易,发布市场数据更新事件用于市场监控
# lastPrice = tickData['lastPrice']
# if lastPrice == 10 or stock_code in self.listening_stock:
# # 发布市场数据更新事件用于市场监控
# market_target = TradeTarget()
# market_target.stock_code = stock_code
# market_target.stock_name = getInstrumentName(stock_code) # type: ignore
# market_target.market_price = lastPrice # type: ignore
# event_bus.publish(MarketDataUpdate, market_target)
# if stock_code not in self.listening_stock:
# self.listening_stock.append(stock_code)
# ====== 市场回调方法 -- 以下方法由XtQuantTrader调用 ======
def on_connected(self):
"""
连接成功推送
"""
print(datetime.datetime.now(), '连接成功回调')
def on_disconnected(self):
"""
连接断开
:return:
"""
print(datetime.datetime.now(), '连接断开回调')
def on_stock_order(self, order:XtOrder):
"""
委托回报推送
:param order: XtOrder对象
:return:
"""
print(f'orderd {order.strategy_name}-{order.stock_code} {order.order_id} {order.order_volume}-{order.order_status}')
stockCode = order.stock_code
ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode]
# 如果存在对应的StockTradeController,则调用其onDataUpdate方法
if ctrl is not None and order.strategy_name == ctrl.getName():
print(f'controller info {ctrl.getName()}')
ctrl.onAsyncOrderResponse(order) # type: ignore
else:
print(f"委托下单回调 投资备注 orderId: {order.order_sysid} [{order.stock_code}-{order.instrument_name}] volume: {order.order_volume} 订单策略: '{order.strategy_name}'<-->'{ctrl.getName()}'")
def on_stock_trade(self, trade:XtTrade):
"""
成交变动推送
:param trade: XtTrade对象
:return:
"""
stockCode = trade.stock_code
ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode]
# 如果存在对应的StockTradeController,则调用其onDataUpdate方法
if ctrl is not None and trade.strategy_name == ctrl.getName():
ctrl.onOrderTrade(trade)
else:
print(f"委托回调 投资备注 {trade.strategy_name} 不匹配 {ctrl.getName()}")
# def on_order_stock_async_response(self, response:XtOrderResponse):
# stockCode = response.order_remark
# ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode]
# # 如果存在对应的StockTradeController,则调用其onDataUpdate方法
# if ctrl is not None and response.strategy_name == ctrl.getName():
# ctrl.onAsyncOrderResponse(response)
# else:
# print(f"委托回调 投资备注 {response.strategy_name} 不匹配 {ctrl.getName()}")
def on_order_error(self, order_error):
"""
委托失败推送
:param order_error:XtOrderError 对象
:return:
"""
# print("on order_error callback")
# print(order_error.order_id, order_error.error_id, order_error.error_msg)
print(f"\n委托报错回调 {order_error.order_remark} {order_error.error_msg}")
def on_account_status(self, status):
"""
:param response: XtAccountStatus 对象
:return:
"""
print(datetime.datetime.now(), status)
+4 -3
View File
@@ -1,12 +1,13 @@
from core.qmt import qmtv
from core.sfgrid.bus_events import EventTradeTargetUpdate
import core.sfgrid.model as model
from core import constants
from core.eventbus import EventTradeTargetUpdate, event_bus
from core.eventbus import event_bus
from core.constants import OrderTypeBuy, OrderTypeInit, OrderTypeSell
from core.util import queryPendingOrder, is_trading_time
from xtquant import xttrader, xtconstant
from xtquant.xttype import StockAccount, XtOrder, XtTrade
from xtquant import xtconstant
from xtquant.xttype import XtOrder, XtTrade
import config
import threading
+23 -47
View File
@@ -7,31 +7,36 @@ import threading
import time
import core.eventbus as eBus
from core.logger import LogLevel, PrintLog
from core.sfgrid.bus_events import ActionEventAddTradeTarget, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, ActionEventGridFix, EventTradeTargetUpdate, ResultEventTradeTargetAdded, ResultEventTradeTargetDeleted
from core.sfgrid.model import SFGridTradeTarget
import configparser
import config
from core.sfgrid.objects import GridFixData
from core.qmt import qmtv
from core.sfgrid.sfgrid_controller import SFGridController
from core.sfgrid.sfgrid_strategy import SFGridStrategy
class TradeTargetUI(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.controller = SFGridController()
self.tradeTargetData:dict[int, SFGridTradeTarget] = {} # id->trade_target
self.strategy_ctrl:dict[str, SFGridStrategy] = {} # stock_code->trade_target
self.strategy_ctrl:dict[int, SFGridStrategy] = {} # stock_code->trade_target
self.init_trade_target_pool()
self.registerEventHandler()
# 创建刷新线程标志
self.refresh_thread_running = True # 默认不启动刷新线程
self.refresh_thread_running = False # 默认不启动刷新线程
# 市场监控数据
self.marketData: dict[str, Any] = {} # 存储市场数据 {stock_code: {stock_name, last_price, time}}
# 创建界面
self.create_ui()
self.start_ui_refresh()
def refresh_targets(self):
# 更新标的池
@@ -52,20 +57,21 @@ class TradeTargetUI(ttk.Frame):
result = tradeTarget.save()
PrintLog(LogLevel.INFO, f' |- 同步[{tradeTarget.stock_code}-{tradeTarget.stock_name}]持仓信息[{'成功' if result == 1 else '失败'}]')
stockTradeController = SFGridStrategy(tradeTarget) # type: ignore
self.strategy_ctrl[tradeTarget.stock_code] = stockTradeController # pyright: ignore[reportArgumentType]
self.strategy_ctrl[id] = stockTradeController # pyright: ignore[reportArgumentType]
# eBus.event_bus.publish(eBus.EventTradeTargetUpdate, tradeTarget)
PrintLog(LogLevel.INFO, f'- [成功]交易标的信息初始化, 共 {len(self.tradeTargetData)} 个标的')
def registerEventHandler(self):
# eBus.event_bus.subscribe(eBus.EventTradeTargetUpdate, self.onTradeTargetUpdated)
eBus.event_bus.subscribe(EventTradeTargetUpdate, self.onTradeTargetUpdated)
# eBus.event_bus.subscribe(eBus.MarketDataUpdate, self.onMarketDataUpdated)
# eBus.event_bus.subscribe(eBus.ResultEventTradeEnabled, self.onTradeEnabled)
# eBus.event_bus.subscribe(eBus.ResultEventTradeDisabled, self.onTradeDisabled)
# eBus.event_bus.subscribe(eBus.MarketDataEnabled, self.onMarketDataToggled)
# eBus.event_bus.subscribe(eBus.MarketDataDisabled, self.onMarketDataToggled)
eBus.event_bus.subscribe(eBus.ResultEventTradeTargetDeleted, self.onTradeTargetDeleted)
eBus.event_bus.subscribe(ResultEventTradeTargetDeleted, self.onTradeTargetDeleted)
eBus.event_bus.subscribe(ResultEventTradeTargetAdded, self.onTradeTargetUpdated)
def start_refresh_thread(self):
"""启动刷新线程"""
@@ -84,22 +90,17 @@ class TradeTargetUI(ttk.Frame):
"""停止刷新线程"""
self.refresh_thread_running = False
def onTradeTargetDeleted(self, id: int):
def onTradeTargetDeleted(self, target: SFGridTradeTarget):
"""处理交易标的删除完成事件"""
# 从本地数据中删除
id = target.get_id()
if id in self.tradeTargetData:
PrintLog(LogLevel.DEBUG, f"删除交易标的,ID: {id}")
del self.tradeTargetData[id]
del self.strategy_ctrl[id]
# 添加日志
PrintLog(LogLevel.INFO, f"交易标的已删除,ID: {id}")
def onMarketDataToggled(self, data:bool):
self.market_data_enabled = self.market_data_switch_var.get()
PrintLog(LogLevel.INFO, "市场数据监听已" + ("启用" if data else "禁用"))
# 同步UI刷新线程状态
if data:
self.start_ui_refresh()
else:
self.stop_ui_refresh()
def onTradeEnabled(self, target:SFGridTradeTarget):
PrintLog(LogLevel.INFO, f"交易启用: {target.stock_code} - {target.stock_name}")
@@ -147,33 +148,9 @@ class TradeTargetUI(ttk.Frame):
# 添加分隔符
ttk.Separator(toolbar_frame, orient='vertical').pack(side=tk.LEFT, fill=tk.Y, padx=10)
# 市场数据监听开关
self.market_data_switch_var = tk.BooleanVar(value=False)
# self.market_data_switch = ttk.Checkbutton(
# toolbar_frame,
# text="📊 市场数据",
# variable=self.market_data_switch_var,
# command=self.toggle_market_data,
# width=12
# )
# self.market_data_switch.pack(side=tk.LEFT, padx=2)
# 表格区域
self.create_tables_area(main_frame)
def toggle_market_data(self):
"""切换市场数据监听状态"""
print(f'市场数据监听开关')
self.market_data_enabled = self.market_data_switch_var.get()
if self.market_data_enabled:
eBus.event_bus.publish(eBus.ActionEnableMarketData, True)
# 同步开启UI刷新线程
self.start_ui_refresh()
else:
eBus.event_bus.publish(eBus.ActionDisableMarketData, True)
# 同步关闭UI刷新线程
self.stop_ui_refresh()
def start_ui_refresh(self):
"""启动UI刷新线程"""
if not self.refresh_thread_running:
@@ -333,7 +310,7 @@ class TradeTargetUI(ttk.Frame):
if result:
# 发布事件通知主控制器添加标的
eBus.event_bus.publish(eBus.ActionEventAddTradeTarget, stock_code)
eBus.event_bus.publish(ActionEventAddTradeTarget, stock_code)
PrintLog(LogLevel.INFO, f"已发送添加请求: {stock_code} - {stock_name}")
def get_status_indicator(self, target: SFGridTradeTarget) -> str:
@@ -432,12 +409,12 @@ class TradeTargetUI(ttk.Frame):
if result:
target.enabled = True # type: ignore
eBus.event_bus.publish(eBus.ActionEventEnableTrade, target.get_id())
eBus.event_bus.publish(ActionEventEnableTrade, target.get_id())
# self.add_log("INFO", f"已启动交易: {target.stock_code} - {target.stock_name}")
# messagebox.showinfo("启动成功", f"已启动 {target.stock_code} ({target.stock_name}) 的交易")
def on_trade_enabled(self, target: SFGridTradeTarget):
eBus.event_bus.publish(eBus.ActionEventEnableTrade, target)
eBus.event_bus.publish(ActionEventEnableTrade, target)
def pause_selected_trade(self):
"""暂停选中的交易"""
@@ -458,7 +435,7 @@ class TradeTargetUI(ttk.Frame):
if result:
target.enabled = False # type: ignore
eBus.event_bus.publish(eBus.ActionEventDisableTrade, target.get_id())
eBus.event_bus.publish(ActionEventDisableTrade, target.get_id())
# self.add_log("INFO", f"已暂停交易: {target.stock_code} - {target.stock_name}")
# messagebox.showinfo("暂停成功", f"已暂停 {target.stock_code} ({target.stock_name}) 的交易")
@@ -479,7 +456,7 @@ class TradeTargetUI(ttk.Frame):
if result:
# 通过事件总线发出删除动作
eBus.event_bus.publish(eBus.ActionEventDeleteTradeTarget, target.get_id())
eBus.event_bus.publish(ActionEventDeleteTradeTarget, target)
PrintLog(LogLevel.INFO, f"已发送删除请求: {target.stock_code} - {target.stock_name}")
def add_trade_target(self):
@@ -524,7 +501,7 @@ class TradeTargetUI(ttk.Frame):
return
# 发布事件通知主控制器添加标的
eBus.event_bus.publish(eBus.ActionEventAddTradeTarget, stock_code)
eBus.event_bus.publish(ActionEventAddTradeTarget, stock_code)
add_window.destroy()
def cancel_add():
@@ -540,7 +517,6 @@ class TradeTargetUI(ttk.Frame):
PrintLog(LogLevel.INFO, "点击添加交易标的按钮")
def refresh_table(self):
"""刷新表格数据"""
# 保存当前选中的项
@@ -1039,7 +1015,7 @@ class TradeTargetUI(ttk.Frame):
# 发布网格修正事件,传递GridFixData对象
grid_fix_data = GridFixData(new_grid_index, target)
eBus.event_bus.publish(eBus.ActionEventGridFix, grid_fix_data)
eBus.event_bus.publish(ActionEventGridFix, grid_fix_data)
# 关闭窗口
window.destroy()