初步完成网格交易统计重构

This commit is contained in:
2025-11-19 14:14:37 +08:00
parent 0262bfc71b
commit 4c4c8730f2
4 changed files with 35 additions and 43 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ class MainWindow:
# 创建Tab按钮(垂直排列,文字垂直显示) # 创建Tab按钮(垂直排列,文字垂直显示)
self.tab_buttons = [] self.tab_buttons = []
strategy_names = ["蒙派\n策略", "涨停\n复盘"] strategy_names = ["蒙派", "复盘"]
for idx, name in enumerate(strategy_names): for idx, name in enumerate(strategy_names):
btn = ttk.Button( btn = ttk.Button(
+4 -8
View File
@@ -7,15 +7,11 @@ from core.database import BaseModel, db
class SFGridTradeTarget(BaseModel): class SFGridTradeTarget(BaseModel):
stock_code = CharField(unique=True) stock_code = CharField(unique=True)
stock_name = CharField() stock_name = CharField()
market_price = FloatField()
current_position = IntegerField() current_position = IntegerField()
grid_index = IntegerField() grid_index = IntegerField(default=0)
last_trade_price = FloatField() init_price = FloatField(null=True) # 建仓成本
plan_buy_price = FloatField() grid_match_count = IntegerField(default=0)
plan_sell_price = FloatField() grid_total_profit = FloatField(default=0.0)
current_order_price = FloatField()
current_order_no = CharField(default='')
current_order_type = CharField(default='')
status = IntegerField(default=0) # -1表示新标的,未完成交易配置,0表示新标的,已完成交易配置,1表示已建初始仓,正常交易中 status = IntegerField(default=0) # -1表示新标的,未完成交易配置,0表示新标的,已完成交易配置,1表示已建初始仓,正常交易中
enabled = BooleanField(default=False) # 是否启动交易线程 enabled = BooleanField(default=False) # 是否启动交易线程
+5 -2
View File
@@ -40,12 +40,12 @@ class SFGridStrategy:
self.refreshGridOrder() self.refreshGridOrder()
def refreshGridOrder(self): # 下网格单 def refreshGridOrder(self): # 下网格单
if not qmtv.isMarketActive: if not qmtv.isMarketActive or not self.tradeTarget.enabled:
return return
currentIdx:int = 0 currentIdx:int = 0
if self.tradeTarget.status == 0: if self.tradeTarget.status == 0: # status == 0 表示已配置好交易参数
price = self.tradeTarget.getPriceGrid()[0] price = self.tradeTarget.getPriceGrid()[0]
tmpOrderSeq = qmtv.orderAsync( tmpOrderSeq = qmtv.orderAsync(
str(self.tradeTarget.stock_code), str(self.tradeTarget.stock_code),
@@ -167,6 +167,7 @@ class SFGridStrategy:
if trade.order_remark == OrderTypeInit: if trade.order_remark == OrderTypeInit:
PrintLog(LogLevel.INFO, f'|- 委托成交通知[{self.tradeTarget.targetName()}-{trade.order_id}] - 建仓单成交') PrintLog(LogLevel.INFO, f'|- 委托成交通知[{self.tradeTarget.targetName()}-{trade.order_id}] - 建仓单成交')
self.tradeTarget.status = 1 # type: ignore self.tradeTarget.status = 1 # type: ignore
self.tradeTarget.init_price = trade.traded_price # type: ignore
self.tradeTarget.grid_index = 1 # type: ignore self.tradeTarget.grid_index = 1 # type: ignore
self.saveProxy() self.saveProxy()
type = "建仓单" type = "建仓单"
@@ -180,6 +181,8 @@ class SFGridStrategy:
self.tradeTarget.grid_index +=1 self.tradeTarget.grid_index +=1
elif idx < self.tradeTarget.grid_index: elif idx < self.tradeTarget.grid_index:
type = "上移一格" type = "上移一格"
self.tradeTarget.grid_match_count += 1
self.tradeTarget.grid_total_profit += self.tradeTarget.grid_size * trade.traded_volume
self.tradeTarget.grid_index -= 1 self.tradeTarget.grid_index -= 1
elif idx == self.tradeTarget.grid_index: elif idx == self.tradeTarget.grid_index:
type = "保持格, 理论上不应该输出" type = "保持格, 理论上不应该输出"
+25 -32
View File
@@ -6,7 +6,6 @@ from tkinter import ttk, messagebox
from datetime import datetime from datetime import datetime
import threading import threading
import time import time
from core import constants
import core.eventbus as eBus import core.eventbus as eBus
from core.logger import LogLevel, PrintLog from core.logger import LogLevel, PrintLog
from core.sfgrid import bus_events from core.sfgrid import bus_events
@@ -21,6 +20,7 @@ class TradeTargetUI(ttk.Frame):
self.tradeTargetData:dict[int, SFGridTradeTarget] = {} # id->trade_target self.tradeTargetData:dict[int, SFGridTradeTarget] = {} # id->trade_target
self.stockCodeIdMap:dict[str, int] = {} self.stockCodeIdMap:dict[str, int] = {}
self.strategy_ctrl:dict[int, SFGridStrategy] = {} # stock_code->trade_target self.strategy_ctrl:dict[int, SFGridStrategy] = {} # stock_code->trade_target
self.targetMarketPrice: dict[int, float] = {}
self.listening_stock = [] self.listening_stock = []
# 监控价格,默认值为10 # 监控价格,默认值为10
self.monitor_price = 10.0 self.monitor_price = 10.0
@@ -35,8 +35,8 @@ class TradeTargetUI(ttk.Frame):
# 创建界面 # 创建界面
self.create_ui() self.create_ui()
eBus.event_bus.subscribe(eBus.MarketDataUpdate, self.onMarketDataUpdated) eBus.event_bus.subscribe(eBus.MarketDataUpdate, self.onMarketDataUpdated)
eBus.event_bus.subscribe(bus_events.EventTradeTargetUpdate, self.onStrategyUpdate) eBus.event_bus.subscribe(bus_events.EventTradeTargetUpdate, self.onStrategyUpdate)
eBus.event_bus.subscribe(bus_events.EventTradeTargetDeleted, self.onTradeTargetDeleted) eBus.event_bus.subscribe(bus_events.EventTradeTargetDeleted, self.onTradeTargetDeleted)
@@ -56,6 +56,7 @@ class TradeTargetUI(ttk.Frame):
for stock_code, tickData in data.items(): for stock_code, tickData in data.items():
if stock_code in self.stockCodeIdMap: if stock_code in self.stockCodeIdMap:
id:int = self.stockCodeIdMap[stock_code] id:int = self.stockCodeIdMap[stock_code]
self.targetMarketPrice[id] = tickData['lastPrice']
tradeTarget = self.tradeTargetData[id] tradeTarget = self.tradeTargetData[id]
# timeStr = datetime.fromtimestamp(tickData['time']/1000) # timeStr = datetime.fromtimestamp(tickData['time']/1000)
lastPrice = float("{:.3f}".format(tickData['lastPrice'])) lastPrice = float("{:.3f}".format(tickData['lastPrice']))
@@ -137,8 +138,11 @@ class TradeTargetUI(ttk.Frame):
ttk.Label(toolbar_frame, text="价格").pack(side=tk.RIGHT, padx=(20, 2)) ttk.Label(toolbar_frame, text="价格").pack(side=tk.RIGHT, padx=(20, 2))
ttk.Label(toolbar_frame, text="监控配置").pack(side=tk.RIGHT, padx=(20, 2)) ttk.Label(toolbar_frame, text="监控配置").pack(side=tk.RIGHT, padx=(20, 2))
PrintLog(LogLevel.INFO, "构建交易池列表")
# 表格区域 # 表格区域
self.create_tables_area(main_frame) self.create_tables_area(main_frame)
PrintLog(LogLevel.INFO, "启动UI刷新线程")
# 启动刷新线程 # 启动刷新线程
self.refresh_thread = threading.Thread(target=self.refresh_loop, daemon=True) self.refresh_thread = threading.Thread(target=self.refresh_loop, daemon=True)
@@ -179,9 +183,8 @@ class TradeTargetUI(ttk.Frame):
"""创建交易标的表格""" """创建交易标的表格"""
columns = ("ID", columns = ("ID",
"股票代码", "股票名称", "市场价", "持仓数量", "股票代码", "股票名称", "市场价", "当前持仓", "建仓成本",
"最新成交价", "计划买入价", "计划卖出价", "当前订单价", "当前订单号", "当前订单类型", "平均成本", "网格匹配次数", "网格收益", "交易状态"
"交易状态"
) )
self.trade_table = ttk.Treeview(parent, columns=columns, show='headings', height=15) self.trade_table = ttk.Treeview(parent, columns=columns, show='headings', height=15)
@@ -192,13 +195,11 @@ class TradeTargetUI(ttk.Frame):
"股票代码": (90, tk.CENTER), "股票代码": (90, tk.CENTER),
"股票名称": (80, tk.E), "股票名称": (80, tk.E),
"市场价": (70, tk.E), "市场价": (70, tk.E),
"持仓数量": (80, tk.E), "当前持仓": (80, tk.E),
"最新成交价": (90, tk.E), "建仓成本": (70, tk.E),
"计划买入价": (90, tk.E), "平均成本": (70, tk.E),
"计划卖出价": (90, tk.E), "网格匹配次数": (90, tk.E),
"当前订单价": (90, tk.E), "网格收益": (90, tk.E),
"当前订单号": (90, tk.E),
"当前订单类型": (90, tk.E),
"交易状态": (80, tk.CENTER) "交易状态": (80, tk.CENTER)
} }
@@ -337,27 +338,17 @@ class TradeTargetUI(ttk.Frame):
def populate_trade_table(self): def populate_trade_table(self):
"""填充交易标的表格数据""" """填充交易标的表格数据"""
for temp, target in self.tradeTargetData.items(): for id, target in self.tradeTargetData.items():
if target.current_order_type == constants.OrderTypeBuy:
orderTypeStr = ""
elif target.current_order_type == constants.OrderTypeSell:
orderTypeStr = ""
elif target.current_order_type == constants.OrderTypeInit:
orderTypeStr = "建仓"
else:
orderTypeStr = "未知"
values = [ values = [
target.id, # type: ignore id,
target.stock_code, target.stock_code, # "股票代码"
target.stock_name, target.stock_name, # "股票名称"
"-" if target.market_price is None else f"{target.market_price:.3f}", f"{self.targetMarketPrice[id]:.3f}" if id in self.targetMarketPrice else '-', # "市场价"
target.current_position, target.current_position, # "当前持仓"
'-' if target.last_trade_price is None else f"{target.last_trade_price:.3f}", '-' if target.init_price is None else f"{target.init_price:.3f}", # "建仓成本"
'-' if target.plan_buy_price is None else f"{target.plan_buy_price:.3f}", '-', # if target.plan_buy_price is None else f"{target.plan_buy_price:.3f}", # "平均成本"
'-' if target.plan_sell_price is None else f"{target.plan_sell_price:.3f}", target.grid_match_count, # "网格匹配次数"
'-' if target.current_order_price is None else f"{target.current_order_price:.3f}", f"{target.grid_total_profit:.3f}", # "网格收益"
target.current_order_no,
orderTypeStr,
self.get_trade_enabled_indicator(target.enabled) # type: ignore self.get_trade_enabled_indicator(target.enabled) # type: ignore
] ]
@@ -378,7 +369,9 @@ class TradeTargetUI(ttk.Frame):
if selected: if selected:
item = selected[0] item = selected[0]
values = self.trade_table.item(item)['values'] values = self.trade_table.item(item)['values']
ctrl = self.strategy_ctrl[values[0]]
PrintLog(LogLevel.DEBUG, f"双击查看详情: {values[0]} - {values[1]}") PrintLog(LogLevel.DEBUG, f"双击查看详情: {values[0]} - {values[1]}")
PrintLog(LogLevel.DEBUG, f"双击查看详情 - 订单网格: \n{ctrl.orderGrid}")
def get_selected_target(self): def get_selected_target(self):
"""获取选中的交易标的""" """获取选中的交易标的"""