独立配置

This commit is contained in:
2025-11-12 15:08:56 +08:00
parent 8ab5d83b1a
commit 1193dc2f69
9 changed files with 51 additions and 46 deletions
-2
View File
@@ -4,8 +4,6 @@ ActionEventAddTradeTarget = "add_trade_target"
ResultEventTradeTargetAdded = "trade_target_added"
ActionEventDeleteTradeTarget = "delete_trade_target"
ResultEventTradeTargetDeleted = "trade_target_deleted"
# 网格修正事件
ActionEventGridFix = "grid_fix"
# 定义事件处理函数
ActionEventEnableTrade = "enable_trade"
+2
View File
@@ -0,0 +1,2 @@
GridTypePercentage = "Percentage"
GridTypeFixed = "PriceBreak"
+22
View File
@@ -19,8 +19,30 @@ class SFGridTradeTarget(BaseModel):
status = IntegerField(default=0) # 0表示新标的,1表示已建初始仓,正常交易中
enabled = BooleanField(default=False) # 是否启动交易线程
grid_start_price = FloatField(default=10.0) # 基线价格
grid_size = FloatField(default=0.1) # 网格价位差
grid_volume = IntegerField(default=100) # 网格交易量
grid_upper_count = IntegerField(default=1) # 基线价格上方网格数
grid_lower_count = IntegerField(default=10) # 基线价格下方网格数
def targetName(self):
return f'{self.stock_name}[{self.stock_code}]'
def getPriceGrid(self) -> list:
self.priceGrid: list = []
# 网格大小,数量
if self.priceGrid is None or len(self.priceGrid) == 0:
for i in range(self.grid_upper_count): # type: ignore
upperPrice = self.grid_start_price + (self.grid_upper_count - i) * self.grid_size
self.priceGrid.append(upperPrice)
self.priceGrid.append(self.grid_start_price)
for i in range(self.grid_lower_count): # type: ignore 5
lowerPrice = self.grid_start_price - (i + 1) * self.grid_size
self.priceGrid.append(lowerPrice)
return self.priceGrid
db.create_tables([SFGridTradeTarget])
+8 -8
View File
@@ -40,7 +40,7 @@ class SFGridStrategy:
else: # 已建仓
# 交易阶段,检查仓位,检查现有订单
print(f" |- 标的{self.tradeTarget.targetName()}已有仓位或非初始状态 无需建初始仓 当前仓位: {self.tradeTarget.current_position} 状态: {self.tradeTarget.status}")
minRequirePosition:int = config.grid_volume * int(self.tradeTarget.grid_index) # type: ignore
minRequirePosition:int = self.tradeTarget.grid_volume * int(self.tradeTarget.grid_index) # type: ignore
if minRequirePosition <= int(self.tradeTarget.current_position): # type: ignore
print(f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}')
else:
@@ -74,16 +74,16 @@ class SFGridStrategy:
index: int = self.tradeTarget.grid_index # pyright: ignore[reportAssignmentType]
orderRemark= ""
gridBasePrice = -1 if index>=len(config.grid_price) or index < 0 else config.grid_price[int(index)] # pyright: ignore[reportArgumentType]
gridBasePrice = -1 if index>=len(inTradeTarget.getPriceGrid()) or index < 0 else inTradeTarget.getPriceGrid()[int(index)] # pyright: ignore[reportArgumentType]
if self.tradeTarget.enabled and self.tradeTarget.status == 0 and lastPrice <= config.grid_price[1]: # 已启用,未建仓,建仓
orderPrice = config.grid_price[index]
orderPrice = inTradeTarget.getPriceGrid()[index]
orderType = xtconstant.STOCK_BUY
orderRemark = OrderTypeInit
if self.tradeTarget.enabled and self.tradeTarget.status == 1: # 已启用,已建仓,网格单
lowPrice = -1 if index+1>=len(config.grid_price) else config.grid_price[int(index) + 1] # pyright: ignore[reportArgumentType]
highPrice = config.grid_price[index - 1]
lowPrice = -1 if index+1>=len(inTradeTarget.getPriceGrid()) else inTradeTarget.getPriceGrid()[int(index) + 1] # pyright: ignore[reportArgumentType]
highPrice = inTradeTarget.getPriceGrid()[index - 1]
if lastPrice <= lowPrice: # 下下方多单
orderPrice = lowPrice
@@ -196,11 +196,11 @@ class SFGridStrategy:
buyIdx: int = self.tradeTarget.grid_index + 1 # pyright: ignore[reportAssignmentType]
sellIdx: int = self.tradeTarget.grid_index - 1
if self.tradeTarget.grid_index > 0: # 可以下空单
self.tradeTarget.plan_sell_price = float(config.grid_price[sellIdx]) # pyright: ignore[reportAttributeAccessIssue]
self.tradeTarget.plan_sell_price = float(self.tradeTarget.getPriceGrid()[sellIdx]) # pyright: ignore[reportAttributeAccessIssue]
else:
self.tradeTarget.plan_sell_price = -1.0 # type: ignore
if self.tradeTarget.grid_index < len(config.grid_price) - 1:
self.tradeTarget.plan_buy_price = float(config.grid_price[buyIdx]) # pyright: ignore[reportAttributeAccessIssue]
if self.tradeTarget.grid_index < len(self.tradeTarget.getPriceGrid()) - 1:
self.tradeTarget.plan_buy_price = float(self.tradeTarget.getPriceGrid()[buyIdx]) # pyright: ignore[reportAttributeAccessIssue]
else:
self.tradeTarget.plan_buy_price = -1.0 # pyright: ignore[reportAttributeAccessIssue]
else:
+15 -16
View File
@@ -8,7 +8,7 @@ import time
from core import constants
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.bus_events import ActionEventAddTradeTarget
from core.sfgrid.model import SFGridTradeTarget
import configparser
import config
@@ -47,7 +47,8 @@ class TradeTargetUI(ttk.Frame):
if stock_code in self.stockCodeIdMap:
id:int = self.stockCodeIdMap[stock_code]
tradeTarget = self.tradeTargetData[id]
lastPrice = float("{:.3f}".format(tickData['lastPrice']))
lastPrice = float("{:.3f}".format(tickData['lastPrice']))
print(f'股票代码: {stock_code} {id}, 市场数据更新 {lastPrice}')
tradeTarget.market_price = lastPrice # type: ignore
self.updateTradeTarget(tradeTarget)
stock_controller: SFGridStrategy = self.strategy_ctrl[id]
@@ -85,7 +86,7 @@ class TradeTargetUI(ttk.Frame):
for id, tradeTarget in self.tradeTargetData.items():
status = "新建" if tradeTarget.status == 0 else "已建初始仓"
PrintLog(LogLevel.INFO, f' [序号-{id}] 股票代码: {tradeTarget.stock_code}-{tradeTarget.stock_name} 当前持仓: {qmtv.getStockPosition(tradeTarget.stock_code)} 网格索引: {tradeTarget.grid_index} 基准价格 {config.grid_price[tradeTarget.grid_index]} 状态: {status} 启用交易线程: {'自动交易中' if tradeTarget.enabled else '交易已停止'}') # type: ignore
PrintLog(LogLevel.INFO, f' [序号-{id}] 股票代码: {tradeTarget.stock_code}-{tradeTarget.stock_name} 当前持仓: {qmtv.getStockPosition(tradeTarget.stock_code)} 网格索引: {tradeTarget.grid_index} 基准价格 {tradeTarget.getPriceGrid()[tradeTarget.grid_index]} 状态: {status} 启用交易线程: {'自动交易中' if tradeTarget.enabled else '交易已停止'}') # type: ignore
tradeTarget.current_position = qmtv.getStockPosition(tradeTarget.stock_code) # type: ignore
result = tradeTarget.save()
@@ -143,10 +144,10 @@ class TradeTargetUI(ttk.Frame):
command=self.pause_selected_trade, width=12).pack(side=tk.LEFT, padx=2)
ttk.Button(toolbar_frame, text=" 添加标的",
command=self.add_trade_target, width=12).pack(side=tk.LEFT, padx=2)
ttk.Button(toolbar_frame, text="🛠 网格配置",
command=self.grid_settings, width=12).pack(side=tk.LEFT, padx=2)
ttk.Button(toolbar_frame, text="🗑 删除标的",
command=self.delete_selected_trade, 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)
# 添加抽屉按钮到工具栏最右侧
self.toggle_market_monitor_btn = ttk.Button(toolbar_frame, text="◀▶",
@@ -246,7 +247,7 @@ class TradeTargetUI(ttk.Frame):
column_configs = {
"时间": (50, tk.CENTER),
"股票名称": (80, tk.CENTER),
"最新价格": (80, tk.CENTER)
"最新价格": (50, tk.CENTER)
}
for col in columns:
@@ -303,7 +304,8 @@ class TradeTargetUI(ttk.Frame):
values = [
time_str,
data['stock_name']+f"{stock_code}",
f"{data['last_price']:.3f}"
f"{data['last_price']:.3f}",
stock_code
]
self.market_table.insert('', tk.END, values=values)
@@ -320,9 +322,10 @@ class TradeTargetUI(ttk.Frame):
if selected:
item = selected[0]
values = self.market_table.item(item)['values']
stock_code = values[1]
stock_name = values[2]
last_price = values[3]
print(values)
stock_name = values[1]
last_price = values[2]
stock_code = values[3]
# 检查是否已在交易池中
is_in_trade_pool = any(target.stock_code == stock_code for target in self.tradeTargetData.values())
@@ -501,7 +504,7 @@ class TradeTargetUI(ttk.Frame):
del self.tradeTargetData[id]
del self.strategy_ctrl[id]
del self.stockCodeIdMap[str(target.stock_code)]
del self.stockCodeIdMap[target.stock_code] # type: ignore
# 添加日志
PrintLog(LogLevel.INFO, f"交易标的已删除,ID: {id} {target.targetName()}")
except Exception as e:
@@ -898,7 +901,7 @@ class TradeTargetUI(ttk.Frame):
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)
def grid_correction(self):
def grid_settings(self):
"""网格修正功能"""
target = self.get_selected_target()
if not target:
@@ -1061,10 +1064,6 @@ class TradeTargetUI(ttk.Frame):
if not result:
return
# 发布网格修正事件,传递GridFixData对象
grid_fix_data = GridFixData(new_grid_index, target)
eBus.event_bus.publish(ActionEventGridFix, grid_fix_data)
# 关闭窗口
window.destroy()
View File