市场数据跟踪
This commit is contained in:
@@ -10,10 +10,13 @@ ActionDisableMarketData = "disable_market_data"
|
|||||||
MarketDataEnabled = "market_data_enabled"
|
MarketDataEnabled = "market_data_enabled"
|
||||||
MarketDataDisabled = "market_data_disabled"
|
MarketDataDisabled = "market_data_disabled"
|
||||||
# 删除交易标的事件
|
# 删除交易标的事件
|
||||||
|
EventTradeTargetUpdate = "trade_target_update"
|
||||||
ActionEventAddTradeTarget = "add_trade_target"
|
ActionEventAddTradeTarget = "add_trade_target"
|
||||||
ResultEventTradeTargetAdded = "trade_target_added"
|
ResultEventTradeTargetAdded = "trade_target_added"
|
||||||
ActionEventDeleteTradeTarget = "delete_trade_target"
|
ActionEventDeleteTradeTarget = "delete_trade_target"
|
||||||
ResultEventTradeTargetDeleted = "trade_target_deleted"
|
ResultEventTradeTargetDeleted = "trade_target_deleted"
|
||||||
|
# 网格修正事件
|
||||||
|
ActionEventGridFix = "grid_fix"
|
||||||
# Pring Log
|
# Pring Log
|
||||||
EventPrintLog = "print_log"
|
EventPrintLog = "print_log"
|
||||||
|
|
||||||
|
|||||||
+46
-15
@@ -1,6 +1,6 @@
|
|||||||
# coding:utf-8
|
# coding:utf-8
|
||||||
from core.strategy_db import TradeTarget
|
from core.strategy_db import TradeTarget
|
||||||
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventAddTradeTarget, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, event_bus
|
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventAddTradeTarget, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, EventTradeTargetUpdate, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, ActionEventGridFix, event_bus
|
||||||
from xtquant.xttrader import XtQuantTrader
|
from xtquant.xttrader import XtQuantTrader
|
||||||
import time
|
import time
|
||||||
from peewee import ModelSelect
|
from peewee import ModelSelect
|
||||||
@@ -16,6 +16,7 @@ from xtquant.xttrader import XtQuantTraderCallback
|
|||||||
import datetime
|
import datetime
|
||||||
import core.ui as ui
|
import core.ui as ui
|
||||||
from core.logger import PrintLog, LogLevel
|
from core.logger import PrintLog, LogLevel
|
||||||
|
from core.objects import GridFixData
|
||||||
|
|
||||||
# 量化核心控制对象
|
# 量化核心控制对象
|
||||||
class SFGridController(XtQuantTraderCallback):
|
class SFGridController(XtQuantTraderCallback):
|
||||||
@@ -49,6 +50,7 @@ class SFGridController(XtQuantTraderCallback):
|
|||||||
else:
|
else:
|
||||||
self.inited = False
|
self.inited = False
|
||||||
return
|
return
|
||||||
|
self.listening_stock = []
|
||||||
self.stock_trade_ctrl = {}
|
self.stock_trade_ctrl = {}
|
||||||
self.init_instrument_pool(self.xt_trader, self.account) # type: ignore
|
self.init_instrument_pool(self.xt_trader, self.account) # type: ignore
|
||||||
|
|
||||||
@@ -63,6 +65,7 @@ class SFGridController(XtQuantTraderCallback):
|
|||||||
event_bus.subscribe(ActionDisableMarketData, self.onMarketDataDisabled)
|
event_bus.subscribe(ActionDisableMarketData, self.onMarketDataDisabled)
|
||||||
event_bus.subscribe(ActionEventAddTradeTarget, self.onAddTradeTarget)
|
event_bus.subscribe(ActionEventAddTradeTarget, self.onAddTradeTarget)
|
||||||
event_bus.subscribe(ActionEventDeleteTradeTarget, self.onDeleteTradeTarget)
|
event_bus.subscribe(ActionEventDeleteTradeTarget, self.onDeleteTradeTarget)
|
||||||
|
event_bus.subscribe(ActionEventGridFix, self.onGridFix)
|
||||||
|
|
||||||
def onDeleteTradeTarget(self, id: int):
|
def onDeleteTradeTarget(self, id: int):
|
||||||
"""处理删除交易标的事件"""
|
"""处理删除交易标的事件"""
|
||||||
@@ -88,6 +91,33 @@ class SFGridController(XtQuantTraderCallback):
|
|||||||
def onDisableTrade(self, id: int):
|
def onDisableTrade(self, id: int):
|
||||||
self.pause_stock_trade(id)
|
self.pause_stock_trade(id)
|
||||||
|
|
||||||
|
def onGridFix(self, data: GridFixData):
|
||||||
|
"""处理网格修正事件"""
|
||||||
|
self.update_trade_target_grid(data)
|
||||||
|
|
||||||
|
def update_trade_target_grid(self, data: GridFixData):
|
||||||
|
"""更新交易标的网格信息"""
|
||||||
|
try:
|
||||||
|
target = data.tradeTarget
|
||||||
|
grid_index = data.grid_index
|
||||||
|
|
||||||
|
# 更新数据库中的网格索引
|
||||||
|
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 hold(self):
|
def hold(self):
|
||||||
self.appUi.run()
|
self.appUi.run()
|
||||||
|
|
||||||
@@ -193,7 +223,7 @@ class SFGridController(XtQuantTraderCallback):
|
|||||||
PrintLog(LogLevel.INFO, f' |- 同步[{target.stock_code}-{target.stock_name}]持仓信息[{'成功' if result == 1 else '失败'}]')
|
PrintLog(LogLevel.INFO, f' |- 同步[{target.stock_code}-{target.stock_name}]持仓信息[{'成功' if result == 1 else '失败'}]')
|
||||||
stockTradeController = SFGridStrategy(tradeTarget, self.xt_trader, self.account) # type: ignore
|
stockTradeController = SFGridStrategy(tradeTarget, self.xt_trader, self.account) # type: ignore
|
||||||
self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController
|
self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController
|
||||||
event_bus.publish(MarketDataUpdate, tradeTarget)
|
event_bus.publish(EventTradeTargetUpdate, tradeTarget)
|
||||||
|
|
||||||
PrintLog(LogLevel.INFO, f'- [成功]交易标的信息初始化, 共 {len(self.instrument_pool)} 个标的')
|
PrintLog(LogLevel.INFO, f'- [成功]交易标的信息初始化, 共 {len(self.instrument_pool)} 个标的')
|
||||||
|
|
||||||
@@ -280,22 +310,23 @@ class SFGridController(XtQuantTraderCallback):
|
|||||||
|
|
||||||
# ====== 市场回调方法 -- 以下方法由XtQuantData调用 ======
|
# ====== 市场回调方法 -- 以下方法由XtQuantData调用 ======
|
||||||
def onDataUpdate(self, data):
|
def onDataUpdate(self, data):
|
||||||
if sfgrid_constants.max_enabled_targets <= 0: # 全推
|
# 收集所有市场数据用于市场监控
|
||||||
for stock_code, tickData in data.items():
|
for stock_code, tickData in data.items():
|
||||||
lastPrice = tickData['lastPrice']
|
if stock_code in self.stock_trade_ctrl:
|
||||||
if lastPrice == 10.0 and stock_code not in self.stock_trade_ctrl:
|
|
||||||
print(f'New trade target = {stock_code} - {getInstrumentName(stock_code)} {tickData['lastPrice']}')
|
|
||||||
self.add_trade_target(stock_code)
|
|
||||||
self.stock_trade_ctrl[stock_code].enabledTrading(True)
|
|
||||||
else: # 指定目标 当前主要使用这种模式
|
|
||||||
for id in self.instrument_pool:
|
|
||||||
stock_code = self.instrument_pool[id].stock_code
|
|
||||||
# 如果存在对应的StockTradeController,则调用其onDataUpdate方法
|
|
||||||
if stock_code not in self.stock_trade_ctrl or stock_code not in data:
|
|
||||||
# print(f"股票代码 {stock_code} 未在交易控制器中找到,跳过处理。\n")
|
|
||||||
continue
|
|
||||||
stock_controller: SFGridStrategy = self.stock_trade_ctrl[stock_code]
|
stock_controller: SFGridStrategy = self.stock_trade_ctrl[stock_code]
|
||||||
stock_controller.onDataUpdate(data)
|
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调用 ======
|
# ====== 市场回调方法 -- 以下方法由XtQuantTrader调用 ======
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from peewee import IntegerField
|
|||||||
|
|
||||||
|
|
||||||
from core import strategy_db
|
from core import strategy_db
|
||||||
from core.eventbus import MarketDataUpdate, event_bus
|
from core.eventbus import EventTradeTargetUpdate, event_bus
|
||||||
from core.strategy_db import OrderTypeBuy, OrderTypeInit, OrderTypeSell, TradeTarget
|
from core.strategy_db import OrderTypeBuy, OrderTypeInit, OrderTypeSell, TradeTarget
|
||||||
from core.util import queryPendingOrder, is_trading_time
|
from core.util import queryPendingOrder, is_trading_time
|
||||||
|
|
||||||
@@ -20,9 +20,14 @@ class SFGridStrategy:
|
|||||||
self.account:StockAccount = account
|
self.account:StockAccount = account
|
||||||
self.enabledTrading(bool(tradeTarget.enabled)) # 修复类型兼容性问题
|
self.enabledTrading(bool(tradeTarget.enabled)) # 修复类型兼容性问题
|
||||||
|
|
||||||
event_bus.publish(MarketDataUpdate, self.tradeTarget)
|
event_bus.publish(EventTradeTargetUpdate, self.tradeTarget)
|
||||||
self.dataUpdateLock = threading.Lock()
|
self.dataUpdateLock = threading.Lock()
|
||||||
|
|
||||||
|
def updateGridIndex(self, grid_index: int):
|
||||||
|
"""更新网格索引"""
|
||||||
|
self.tradeTarget.grid_index = grid_index # type: ignore
|
||||||
|
self.refreshPlanPrice()
|
||||||
|
self.saveProxy()
|
||||||
|
|
||||||
def enabledTrading(self, enabled: bool) -> TradeTarget:
|
def enabledTrading(self, enabled: bool) -> TradeTarget:
|
||||||
self.tradeTarget.enabled = enabled # type: ignore
|
self.tradeTarget.enabled = enabled # type: ignore
|
||||||
@@ -216,5 +221,5 @@ class SFGridStrategy:
|
|||||||
|
|
||||||
def saveProxy(self):
|
def saveProxy(self):
|
||||||
rc = self.tradeTarget.save()
|
rc = self.tradeTarget.save()
|
||||||
event_bus.publish(MarketDataUpdate, self.tradeTarget)
|
event_bus.publish(EventTradeTargetUpdate, self.tradeTarget)
|
||||||
return rc
|
return rc
|
||||||
+132
-20
@@ -1,3 +1,6 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk, messagebox, filedialog
|
from tkinter import ttk, messagebox, filedialog
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -8,11 +11,13 @@ from core.logger import LogData, LogLevel
|
|||||||
from core.strategy_db import TradeTarget
|
from core.strategy_db import TradeTarget
|
||||||
import configparser
|
import configparser
|
||||||
import sfgrid_constants
|
import sfgrid_constants
|
||||||
|
from core.objects import GridFixData
|
||||||
|
from core.util import getInstrumentName
|
||||||
|
|
||||||
|
|
||||||
class TradeTargetUI:
|
class TradeTargetUI:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.data:dict[int, TradeTarget] = {}
|
self.tradeTargetData:dict[int, TradeTarget] = {}
|
||||||
self.market_data_enabled = False # 添加市场数据监听状态变量
|
self.market_data_enabled = False # 添加市场数据监听状态变量
|
||||||
self.ui_refresh_enabled = False # 添加UI刷新线程状态变量
|
self.ui_refresh_enabled = False # 添加UI刷新线程状态变量
|
||||||
self.registerEventHandler()
|
self.registerEventHandler()
|
||||||
@@ -20,16 +25,20 @@ class TradeTargetUI:
|
|||||||
# 创建刷新线程标志
|
# 创建刷新线程标志
|
||||||
self.refresh_thread_running = False # 默认不启动刷新线程
|
self.refresh_thread_running = False # 默认不启动刷新线程
|
||||||
|
|
||||||
|
# 市场监控数据
|
||||||
|
self.marketData: dict[str, Any] = {} # 存储市场数据 {stock_code: {stock_name, last_price, time}}
|
||||||
|
|
||||||
self.root = tk.Tk()
|
self.root = tk.Tk()
|
||||||
self.root.title("三疯交易系统")
|
self.root.title("三疯交易系统")
|
||||||
self.root.geometry("1200x700")
|
self.root.geometry("1400x700")
|
||||||
# 创建界面
|
# 创建界面
|
||||||
self.create_ui()
|
self.create_ui()
|
||||||
|
|
||||||
# 不再自动启动刷新线程,由市场数据开关控制
|
# 不再自动启动刷新线程,由市场数据开关控制
|
||||||
|
|
||||||
def registerEventHandler(self):
|
def registerEventHandler(self):
|
||||||
eBus.event_bus.subscribe(eBus.MarketDataUpdate, self.onTradeTargetUpdated)
|
eBus.event_bus.subscribe(eBus.EventTradeTargetUpdate, self.onTradeTargetUpdated)
|
||||||
|
eBus.event_bus.subscribe(eBus.MarketDataUpdate, self.onMarketDataUpdated)
|
||||||
eBus.event_bus.subscribe(eBus.ResultEventTradeEnabled, self.onTradeEnabled)
|
eBus.event_bus.subscribe(eBus.ResultEventTradeEnabled, self.onTradeEnabled)
|
||||||
eBus.event_bus.subscribe(eBus.ResultEventTradeDisabled, self.onTradeDisabled)
|
eBus.event_bus.subscribe(eBus.ResultEventTradeDisabled, self.onTradeDisabled)
|
||||||
eBus.event_bus.subscribe(eBus.MarketDataEnabled, self.onMarketDataToggled)
|
eBus.event_bus.subscribe(eBus.MarketDataEnabled, self.onMarketDataToggled)
|
||||||
@@ -58,8 +67,8 @@ class TradeTargetUI:
|
|||||||
def onTradeTargetDeleted(self, id: int):
|
def onTradeTargetDeleted(self, id: int):
|
||||||
"""处理交易标的删除完成事件"""
|
"""处理交易标的删除完成事件"""
|
||||||
# 从本地数据中删除
|
# 从本地数据中删除
|
||||||
if id in self.data:
|
if id in self.tradeTargetData:
|
||||||
del self.data[id]
|
del self.tradeTargetData[id]
|
||||||
# 添加日志
|
# 添加日志
|
||||||
self.add_log(LogLevel.INFO, f"交易标的已删除,ID: {id}")
|
self.add_log(LogLevel.INFO, f"交易标的已删除,ID: {id}")
|
||||||
|
|
||||||
@@ -81,8 +90,17 @@ class TradeTargetUI:
|
|||||||
|
|
||||||
def onTradeTargetUpdated(self, target: TradeTarget):
|
def onTradeTargetUpdated(self, target: TradeTarget):
|
||||||
# 更新或添加数据到本地缓存
|
# 更新或添加数据到本地缓存
|
||||||
self.data[target.get_id()] = target
|
self.tradeTargetData[target.get_id()] = target
|
||||||
# 不再直接刷新表格,由刷新线程统一处理
|
|
||||||
|
|
||||||
|
def onMarketDataUpdated(self, target: TradeTarget):
|
||||||
|
# 更新市场监控数据
|
||||||
|
current_time = datetime.now().strftime("%H:%M:%S")
|
||||||
|
self.marketData[str(target.stock_code)] = {
|
||||||
|
'stock_name': target.stock_name,
|
||||||
|
'last_price': target.market_price if target.market_price is not None else 0.0,
|
||||||
|
'time': current_time
|
||||||
|
}
|
||||||
|
|
||||||
def create_ui(self):
|
def create_ui(self):
|
||||||
"""创建UI界面"""
|
"""创建UI界面"""
|
||||||
@@ -183,13 +201,24 @@ class TradeTargetUI:
|
|||||||
|
|
||||||
def create_tables_area(self, parent):
|
def create_tables_area(self, parent):
|
||||||
"""创建表格区域"""
|
"""创建表格区域"""
|
||||||
# 上方交易标的区域
|
# 创建主表格框架(水平排列)
|
||||||
trade_frame = ttk.LabelFrame(parent, text="交易标的详情", padding=10)
|
tables_frame = ttk.Frame(parent)
|
||||||
trade_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 5))
|
tables_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 5))
|
||||||
|
|
||||||
|
# 左侧交易标的区域
|
||||||
|
trade_frame = ttk.LabelFrame(tables_frame, text="交易标的详情", padding=10)
|
||||||
|
trade_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))
|
||||||
|
|
||||||
# 创建交易标的表格
|
# 创建交易标的表格
|
||||||
self.create_trade_target_table(trade_frame)
|
self.create_trade_target_table(trade_frame)
|
||||||
|
|
||||||
|
# 右侧市场监控区域
|
||||||
|
market_frame = ttk.LabelFrame(tables_frame, text="市场监控", padding=10)
|
||||||
|
market_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0))
|
||||||
|
|
||||||
|
# 创建市场监控表格
|
||||||
|
self.create_market_monitor_table(market_frame)
|
||||||
|
|
||||||
# 下方操作日志区域(默认隐藏)
|
# 下方操作日志区域(默认隐藏)
|
||||||
self.log_frame = ttk.LabelFrame(parent, text="操作日志", padding=10)
|
self.log_frame = ttk.LabelFrame(parent, text="操作日志", padding=10)
|
||||||
# 默认不显示,通过工具栏按钮控制
|
# 默认不显示,通过工具栏按钮控制
|
||||||
@@ -246,6 +275,85 @@ class TradeTargetUI:
|
|||||||
# 绑定双击事件
|
# 绑定双击事件
|
||||||
self.trade_table.bind("<Double-1>", self.on_table_double_click)
|
self.trade_table.bind("<Double-1>", self.on_table_double_click)
|
||||||
|
|
||||||
|
def create_market_monitor_table(self, parent):
|
||||||
|
"""创建市场监控表格"""
|
||||||
|
columns = ("时间", "股票代码", "股票名称", "最新价格")
|
||||||
|
|
||||||
|
self.market_table = ttk.Treeview(parent, columns=columns, show='headings', height=15)
|
||||||
|
|
||||||
|
# 列配置
|
||||||
|
column_configs = {
|
||||||
|
"时间": (120, "center"),
|
||||||
|
"股票代码": (90, "center"),
|
||||||
|
"股票名称": (80, "center"),
|
||||||
|
"最新价格": (80, "center")
|
||||||
|
}
|
||||||
|
|
||||||
|
for col in columns:
|
||||||
|
width, anchor = column_configs[col]
|
||||||
|
self.market_table.heading(col, text=col)
|
||||||
|
self.market_table.column(col, width=width, anchor=anchor) # type: ignore
|
||||||
|
|
||||||
|
# 滚动条
|
||||||
|
scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.market_table.yview)
|
||||||
|
self.market_table.configure(yscrollcommand=scrollbar.set)
|
||||||
|
|
||||||
|
self.market_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
||||||
|
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
||||||
|
|
||||||
|
# 绑定双击事件
|
||||||
|
self.market_table.bind("<Double-1>", self.on_market_table_double_click)
|
||||||
|
|
||||||
|
# 填充初始数据
|
||||||
|
self.populate_market_table()
|
||||||
|
|
||||||
|
def populate_market_table(self):
|
||||||
|
"""填充市场监控表格数据"""
|
||||||
|
pass
|
||||||
|
# 清空现有数据
|
||||||
|
for item in self.market_table.get_children():
|
||||||
|
self.market_table.delete(item)
|
||||||
|
|
||||||
|
# 填充市场数据
|
||||||
|
tmp = self.marketData.copy()
|
||||||
|
for stock_code, data in tmp.items():
|
||||||
|
values = [
|
||||||
|
data['time'],
|
||||||
|
stock_code,
|
||||||
|
data['stock_name'],
|
||||||
|
f"{data['last_price']:.3f}"
|
||||||
|
]
|
||||||
|
self.market_table.insert('', tk.END, values=values)
|
||||||
|
|
||||||
|
def on_market_table_double_click(self, event):
|
||||||
|
"""市场监控表格双击事件"""
|
||||||
|
selected = self.market_table.selection()
|
||||||
|
if selected:
|
||||||
|
item = selected[0]
|
||||||
|
values = self.market_table.item(item)['values']
|
||||||
|
stock_code = values[1]
|
||||||
|
stock_name = values[2]
|
||||||
|
last_price = values[3]
|
||||||
|
|
||||||
|
# 检查是否已在交易池中
|
||||||
|
is_in_trade_pool = any(target.stock_code == stock_code for target in self.tradeTargetData.values())
|
||||||
|
|
||||||
|
if is_in_trade_pool:
|
||||||
|
messagebox.showinfo("提示", f"{stock_code} ({stock_name}) 已在交易池中")
|
||||||
|
else:
|
||||||
|
result = messagebox.askyesno(
|
||||||
|
"添加交易标的",
|
||||||
|
f"确定要将以下股票添加到交易池吗?\n\n"
|
||||||
|
f"股票代码: {stock_code}\n"
|
||||||
|
f"股票名称: {stock_name}\n"
|
||||||
|
f"最新价格: {last_price}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
# 发布事件通知主控制器添加标的
|
||||||
|
eBus.event_bus.publish(eBus.ActionEventAddTradeTarget, stock_code)
|
||||||
|
self.add_log(LogLevel.INFO, f"已发送添加请求: {stock_code} - {stock_name}")
|
||||||
|
|
||||||
def get_status_indicator(self, target: TradeTarget) -> str:
|
def get_status_indicator(self, target: TradeTarget) -> str:
|
||||||
"""获取状态指示器(带颜色色块的文本)"""
|
"""获取状态指示器(带颜色色块的文本)"""
|
||||||
if target.status == 1:
|
if target.status == 1:
|
||||||
@@ -266,8 +374,8 @@ class TradeTargetUI:
|
|||||||
|
|
||||||
def populate_trade_table(self):
|
def populate_trade_table(self):
|
||||||
"""填充交易标的表格数据"""
|
"""填充交易标的表格数据"""
|
||||||
for temp in self.data:
|
for temp in self.tradeTargetData:
|
||||||
target: TradeTarget = self.data[temp]
|
target: TradeTarget = self.tradeTargetData[temp]
|
||||||
values = [
|
values = [
|
||||||
target.id, # type: ignore
|
target.id, # type: ignore
|
||||||
target.stock_code,
|
target.stock_code,
|
||||||
@@ -275,10 +383,10 @@ class TradeTargetUI:
|
|||||||
"-" if target.market_price is None else f"{target.market_price:.3f}",
|
"-" if target.market_price is None else f"{target.market_price:.3f}",
|
||||||
target.current_position,
|
target.current_position,
|
||||||
target.grid_index,
|
target.grid_index,
|
||||||
f"{target.last_trade_price:.3f}",
|
'-' if target.last_trade_price is None else f"{target.last_trade_price:.3f}",
|
||||||
f"{target.plan_buy_price:.3f}",
|
'-' if target.plan_buy_price is None else f"{target.plan_buy_price:.3f}",
|
||||||
f"{target.plan_sell_price:.3f}",
|
'-' if target.plan_sell_price is None else f"{target.plan_sell_price:.3f}",
|
||||||
f"{target.current_order_price:.3f}",
|
'-' if target.current_order_price is None else f"{target.current_order_price:.3f}",
|
||||||
target.current_order_no,
|
target.current_order_no,
|
||||||
target.current_order_type,
|
target.current_order_type,
|
||||||
self.get_status_indicator(target),
|
self.get_status_indicator(target),
|
||||||
@@ -348,9 +456,9 @@ class TradeTargetUI:
|
|||||||
target_id = values[0]
|
target_id = values[0]
|
||||||
|
|
||||||
# 从列表中找到对应的target对象
|
# 从列表中找到对应的target对象
|
||||||
for id in self.data:
|
for id in self.tradeTargetData:
|
||||||
if int(target_id) == id: # type: ignore
|
if int(target_id) == id: # type: ignore
|
||||||
return self.data[id]
|
return self.tradeTargetData[id]
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -514,6 +622,9 @@ class TradeTargetUI:
|
|||||||
if values and values[0] in selected_values:
|
if values and values[0] in selected_values:
|
||||||
self.trade_table.selection_add(item)
|
self.trade_table.selection_add(item)
|
||||||
|
|
||||||
|
# 刷新市场监控表格
|
||||||
|
self.populate_market_table()
|
||||||
|
|
||||||
def onLog(self, data:LogData):
|
def onLog(self, data:LogData):
|
||||||
self.add_log(data.level, data.message)
|
self.add_log(data.level, data.message)
|
||||||
|
|
||||||
@@ -990,8 +1101,9 @@ class TradeTargetUI:
|
|||||||
if not result:
|
if not result:
|
||||||
return
|
return
|
||||||
|
|
||||||
# 保存到数据库(这里需要发布事件让控制器处理)
|
# 发布网格修正事件,传递GridFixData对象
|
||||||
# TODO: 发布保存事件到控制器
|
grid_fix_data = GridFixData(new_grid_index, target)
|
||||||
|
eBus.event_bus.publish(eBus.ActionEventGridFix, grid_fix_data)
|
||||||
|
|
||||||
# 关闭窗口
|
# 关闭窗口
|
||||||
window.destroy()
|
window.destroy()
|
||||||
|
|||||||
Reference in New Issue
Block a user