网格修正
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
from core.strategy_db import TradeTarget
|
||||||
|
|
||||||
|
|
||||||
|
class GridFixData:
|
||||||
|
def __init__(self, grid_index, tradeTarget:TradeTarget):
|
||||||
|
self.grid_index = grid_index
|
||||||
|
self.tradeTarget = tradeTarget
|
||||||
+197
-1
@@ -106,7 +106,8 @@ class TradeTargetUI:
|
|||||||
command=self.add_trade_target, width=12).pack(side=tk.LEFT, padx=2)
|
command=self.add_trade_target, width=12).pack(side=tk.LEFT, padx=2)
|
||||||
ttk.Button(toolbar_frame, text="🗑 删除标的",
|
ttk.Button(toolbar_frame, text="🗑 删除标的",
|
||||||
command=self.delete_selected_trade, width=12).pack(side=tk.LEFT, padx=2)
|
command=self.delete_selected_trade, width=12).pack(side=tk.LEFT, padx=2)
|
||||||
ttk.Button(toolbar_frame, text="🛠 网格修正", width=12).pack(side=tk.LEFT, padx=2)
|
ttk.Button(toolbar_frame, text="🛠 网格修正",
|
||||||
|
command=self.grid_correction, width=12).pack(side=tk.LEFT, padx=2)
|
||||||
|
|
||||||
# 添加分隔符
|
# 添加分隔符
|
||||||
ttk.Separator(toolbar_frame, orient='vertical').pack(side=tk.LEFT, fill=tk.Y, padx=10)
|
ttk.Separator(toolbar_frame, orient='vertical').pack(side=tk.LEFT, fill=tk.Y, padx=10)
|
||||||
@@ -829,6 +830,201 @@ class TradeTargetUI:
|
|||||||
ttk.Button(button_frame, text="💾 保存配置", command=save_settings, width=15).pack(side=tk.LEFT, padx=5)
|
ttk.Button(button_frame, text="💾 保存配置", command=save_settings, width=15).pack(side=tk.LEFT, padx=5)
|
||||||
ttk.Button(button_frame, text="❌ 取消", command=cancel_settings, width=15).pack(side=tk.LEFT, padx=5)
|
ttk.Button(button_frame, text="❌ 取消", command=cancel_settings, width=15).pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
|
def grid_correction(self):
|
||||||
|
"""网格修正功能"""
|
||||||
|
target = self.get_selected_target()
|
||||||
|
if not target:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 创建网格修正窗口
|
||||||
|
self.create_grid_correction_window(target)
|
||||||
|
|
||||||
|
def create_grid_correction_window(self, target: TradeTarget):
|
||||||
|
"""创建网格修正窗口"""
|
||||||
|
# 创建顶层窗口
|
||||||
|
correction_window = tk.Toplevel(self.root)
|
||||||
|
correction_window.title(f"网格修正 - {target.stock_code} ({target.stock_name})")
|
||||||
|
correction_window.geometry("500x400")
|
||||||
|
correction_window.resizable(False, False)
|
||||||
|
|
||||||
|
# 设置窗口模态
|
||||||
|
correction_window.transient(self.root)
|
||||||
|
correction_window.grab_set()
|
||||||
|
|
||||||
|
# 居中显示
|
||||||
|
self.root.update_idletasks()
|
||||||
|
x = self.root.winfo_x() + (self.root.winfo_width() // 2) - 250
|
||||||
|
y = self.root.winfo_y() + (self.root.winfo_height() // 2) - 200
|
||||||
|
correction_window.geometry(f"500x400+{x}+{y}")
|
||||||
|
|
||||||
|
# 创建主框架
|
||||||
|
main_frame = ttk.Frame(correction_window, padding=20)
|
||||||
|
main_frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
# 显示股票信息
|
||||||
|
info_frame = ttk.LabelFrame(main_frame, text="标的详情", padding=10)
|
||||||
|
info_frame.pack(fill=tk.X, pady=(0, 10))
|
||||||
|
|
||||||
|
ttk.Label(info_frame, text=f"股票代码: {target.stock_code}").grid(row=0, column=0, sticky=tk.W, pady=2)
|
||||||
|
ttk.Label(info_frame, text=f"股票名称: {target.stock_name}").grid(row=0, column=1, sticky=tk.W, padx=(20, 0), pady=2)
|
||||||
|
|
||||||
|
# 创建修正选项框架
|
||||||
|
options_frame = ttk.LabelFrame(main_frame, text="修正选项", padding=10)
|
||||||
|
options_frame.pack(fill=tk.X, pady=(0, 10))
|
||||||
|
|
||||||
|
# 网格序号
|
||||||
|
grid_index_frame = ttk.Frame(options_frame)
|
||||||
|
grid_index_frame.pack(fill=tk.X, pady=5)
|
||||||
|
|
||||||
|
ttk.Label(grid_index_frame, text="网格序号:", width=12).pack(side=tk.LEFT)
|
||||||
|
|
||||||
|
# 网格序号调整控件
|
||||||
|
grid_index_var = tk.IntVar(value=getattr(target, 'grid_index'))
|
||||||
|
|
||||||
|
# 当前持仓量
|
||||||
|
position_frame = ttk.Frame(options_frame)
|
||||||
|
position_frame.pack(fill=tk.X, pady=5)
|
||||||
|
|
||||||
|
current_position_value = getattr(target, 'current_position')
|
||||||
|
ttk.Label(position_frame, text="当前持仓量:", width=12).pack(side=tk.LEFT)
|
||||||
|
ttk.Label(position_frame, text=str(current_position_value), width=10, anchor=tk.CENTER).pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
|
# 需求持仓量
|
||||||
|
required_position_frame = ttk.Frame(options_frame)
|
||||||
|
required_position_frame.pack(fill=tk.X, pady=5)
|
||||||
|
|
||||||
|
grid_index_value = getattr(target, 'grid_index')
|
||||||
|
required_position = grid_index_value * sfgrid_constants.grid_volume
|
||||||
|
ttk.Label(required_position_frame, text="需求持仓量:", width=12).pack(side=tk.LEFT)
|
||||||
|
required_position_label = ttk.Label(required_position_frame, text=str(required_position), width=10, anchor=tk.CENTER)
|
||||||
|
required_position_label.pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
|
# 持仓量状态提示
|
||||||
|
position_status_frame = ttk.Frame(options_frame)
|
||||||
|
position_status_frame.pack(fill=tk.X, pady=5)
|
||||||
|
|
||||||
|
position_status_label = ttk.Label(position_status_frame, text="", foreground="red")
|
||||||
|
position_status_label.pack(side=tk.LEFT, padx=(12, 0))
|
||||||
|
|
||||||
|
# 初始化持仓量状态
|
||||||
|
self.update_position_status(current_position_value, required_position, position_status_label)
|
||||||
|
|
||||||
|
# 网格序号显示和按钮
|
||||||
|
grid_index_label = ttk.Label(grid_index_frame, textvariable=grid_index_var, width=10, anchor=tk.CENTER)
|
||||||
|
grid_index_label.pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
|
# 减少按钮
|
||||||
|
ttk.Button(grid_index_frame, text="-", width=3,
|
||||||
|
command=lambda: self.decrease_grid_index(grid_index_var, target, required_position_label, position_status_label)).pack(side=tk.LEFT, padx=(5, 5))
|
||||||
|
|
||||||
|
# 增加按钮
|
||||||
|
ttk.Button(grid_index_frame, text="+", width=3,
|
||||||
|
command=lambda: self.increase_grid_index(grid_index_var, len(sfgrid_constants.grid_price)-1, target, required_position_label, position_status_label)).pack(side=tk.LEFT, padx=(5, 0))
|
||||||
|
|
||||||
|
# 当前价格(实时更新)
|
||||||
|
price_frame = ttk.Frame(options_frame)
|
||||||
|
price_frame.pack(fill=tk.X, pady=5)
|
||||||
|
|
||||||
|
ttk.Label(price_frame, text="当前价格:", width=12).pack(side=tk.LEFT)
|
||||||
|
current_price_var = tk.StringVar(value="-")
|
||||||
|
current_price_label = ttk.Label(price_frame, textvariable=current_price_var, width=10, anchor=tk.CENTER)
|
||||||
|
current_price_label.pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
|
# 保存按钮框架
|
||||||
|
button_frame = ttk.Frame(main_frame)
|
||||||
|
button_frame.pack(fill=tk.X, pady=(10, 0))
|
||||||
|
|
||||||
|
# 保存按钮
|
||||||
|
ttk.Button(button_frame, text="确认修正",
|
||||||
|
command=lambda: self.save_grid_correction(correction_window, target, grid_index_var.get())).pack(side=tk.RIGHT, padx=5)
|
||||||
|
|
||||||
|
# 取消按钮
|
||||||
|
ttk.Button(button_frame, text="取消",
|
||||||
|
command=correction_window.destroy).pack(side=tk.RIGHT, padx=5)
|
||||||
|
|
||||||
|
# 监听市场数据更新
|
||||||
|
def on_market_data_update(updated_target: TradeTarget):
|
||||||
|
if updated_target.get_id() == target.get_id():
|
||||||
|
current_price_var.set(f"{updated_target.market_price:.3f}" if updated_target.market_price else "-")
|
||||||
|
|
||||||
|
# 订阅市场数据更新事件
|
||||||
|
eBus.event_bus.subscribe(eBus.MarketDataUpdate, on_market_data_update)
|
||||||
|
|
||||||
|
# 窗口关闭时取消订阅
|
||||||
|
def on_window_close():
|
||||||
|
if eBus.MarketDataUpdate in eBus.event_bus.listeners and on_market_data_update in eBus.event_bus.listeners[eBus.MarketDataUpdate]:
|
||||||
|
eBus.event_bus.listeners[eBus.MarketDataUpdate].remove(on_market_data_update)
|
||||||
|
correction_window.destroy()
|
||||||
|
|
||||||
|
correction_window.protocol("WM_DELETE_WINDOW", on_window_close)
|
||||||
|
|
||||||
|
# 初始化当前价格
|
||||||
|
if target.market_price is not None:
|
||||||
|
current_price_var.set(f"{target.market_price:.3f}")
|
||||||
|
|
||||||
|
def update_position_status(self, current_position: int, required_position: int, status_label: ttk.Label):
|
||||||
|
"""更新持仓量状态提示"""
|
||||||
|
if current_position >= required_position:
|
||||||
|
status_label.config(text="持仓量充足", foreground="green")
|
||||||
|
else:
|
||||||
|
shortage = required_position - current_position
|
||||||
|
status_label.config(text=f"还需补充 {shortage} 手仓位", foreground="red")
|
||||||
|
|
||||||
|
def save_grid_correction(self, window, target: TradeTarget, new_grid_index: int):
|
||||||
|
"""保存网格修正"""
|
||||||
|
# 更新网格序号
|
||||||
|
setattr(target, 'grid_index', new_grid_index)
|
||||||
|
|
||||||
|
# 重新计算需求持仓量
|
||||||
|
required_position = new_grid_index * sfgrid_constants.grid_volume
|
||||||
|
|
||||||
|
# 检查持仓量是否满足要求
|
||||||
|
current_position = getattr(target, 'current_position')
|
||||||
|
if current_position < required_position:
|
||||||
|
shortage = required_position - current_position
|
||||||
|
result = messagebox.askyesno(
|
||||||
|
"持仓量不足",
|
||||||
|
f"当前持仓量({current_position}手)小于需求持仓量({required_position}手)\n"
|
||||||
|
f"还需补充 {shortage} 手仓位,是否继续保存?"
|
||||||
|
)
|
||||||
|
if not result:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 保存到数据库(这里需要发布事件让控制器处理)
|
||||||
|
# TODO: 发布保存事件到控制器
|
||||||
|
|
||||||
|
# 关闭窗口
|
||||||
|
window.destroy()
|
||||||
|
|
||||||
|
# 添加日志
|
||||||
|
self.add_log(LogLevel.INFO, f"网格修正已保存: {target.stock_code} - {target.stock_name}, 网格序号: {new_grid_index}")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""运行程序"""
|
"""运行程序"""
|
||||||
self.root.mainloop()
|
self.root.mainloop()
|
||||||
|
|
||||||
|
def decrease_grid_index(self, grid_index_var: tk.IntVar, target: TradeTarget, required_position_label: ttk.Label, position_status_label: ttk.Label):
|
||||||
|
"""减少网格序号"""
|
||||||
|
current_value = grid_index_var.get()
|
||||||
|
if current_value > 0:
|
||||||
|
grid_index_var.set(current_value - 1)
|
||||||
|
# 同步更新需求持仓量和持仓状态
|
||||||
|
self.update_required_position_and_status(grid_index_var.get(), target, required_position_label, position_status_label)
|
||||||
|
|
||||||
|
def increase_grid_index(self, grid_index_var: tk.IntVar, max_index: int, target: TradeTarget, required_position_label: ttk.Label, position_status_label: ttk.Label):
|
||||||
|
"""增加网格序号"""
|
||||||
|
current_value = grid_index_var.get()
|
||||||
|
if current_value < max_index:
|
||||||
|
grid_index_var.set(current_value + 1)
|
||||||
|
# 同步更新需求持仓量和持仓状态
|
||||||
|
self.update_required_position_and_status(grid_index_var.get(), target, required_position_label, position_status_label)
|
||||||
|
|
||||||
|
def update_required_position_and_status(self, grid_index: int, target: TradeTarget, required_position_label: ttk.Label, position_status_label: ttk.Label):
|
||||||
|
"""更新需求持仓量和持仓状态"""
|
||||||
|
# 计算需求持仓量
|
||||||
|
required_position = grid_index * sfgrid_constants.grid_volume
|
||||||
|
required_position_label.config(text=str(required_position))
|
||||||
|
|
||||||
|
# 更新持仓量状态
|
||||||
|
current_position = getattr(target, 'current_position')
|
||||||
|
self.update_position_status(current_position, required_position, position_status_label)
|
||||||
|
|||||||
Reference in New Issue
Block a user