模型,评分,修复网格策略市场状态监听
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
# 删除交易标的事件
|
||||
EventTradeTargetUpdate = "trade_target_update"
|
||||
EventTradeTargetDeleted = "trade_target_deleted"
|
||||
|
||||
# 评分系统事件
|
||||
EventScoringCompleted = "scoring_completed" # 评分完成, data: {'date', 'count'}
|
||||
EventSyncProgress = "sync_progress" # 同步进度, data: {'source', 'status', 'stats'}
|
||||
|
||||
@@ -58,6 +58,7 @@ class SFGridStrategy:
|
||||
event_bus.subscribe(eBus.MarketOrderCreated, self.onOrderCreateAsync)
|
||||
event_bus.subscribe(eBus.MarketOrderTraded, self.onOrderTrade)
|
||||
event_bus.subscribe(eBus.MarketOrderError, self.onOrderError)
|
||||
event_bus.subscribe(eBus.EventMarketActiveSwitch, self.onMarketActiveSwitch)
|
||||
|
||||
# 获取当日涨跌停价格(用于价格边界校验)
|
||||
self.todayUpStopPrice = qmtv.dailyUpStop(tradeTarget.stock_code) # type: ignore
|
||||
@@ -139,93 +140,97 @@ class SFGridStrategy:
|
||||
每个方向都先检查是否已存在同价位订单,避免重复下单
|
||||
"""
|
||||
# ── 前置检查:市场和策略状态 ──
|
||||
if not qmtv.isMarketActive or not self.tradeTarget.enabled:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 市场 {qmtv.isMarketActive}, 策略 {self.getName()} '
|
||||
f'{self.tradeTarget.enabled}, 不下单')
|
||||
return
|
||||
|
||||
# 获取当前该标的所有未成交订单
|
||||
orders = qmtv.queryPendingOrder(self.tradeTarget.stock_code, self.getName()) # type: ignore
|
||||
|
||||
# ── 统一网格逻辑 ──
|
||||
# grid_index=0 空仓: 只挂买单 @ grid[1],无持仓可卖
|
||||
# grid_index>0 有仓: 上方挂卖单 @ grid[idx-1],下方挂买单 @ grid[idx+1]
|
||||
if self.tradeTarget.grid_index >= 0:
|
||||
currentIdx = self.tradeTarget.grid_index # type: ignore
|
||||
|
||||
# --- 上方挂卖出单(空单)---
|
||||
# 条件: grid_index > 0,即当前位置不是价格最低点,还有向下(卖出)空间
|
||||
if currentIdx > 0:
|
||||
sellIdx = currentIdx - 1 # 向上一个网格
|
||||
sellPrice = self.tradeTarget.getPriceGrid()[sellIdx]
|
||||
sell_remark = self._make_remark(OrderTypeSell, sellIdx)
|
||||
|
||||
# 检查是否已存在同 remark 的卖单(避免重复挂单)
|
||||
if not any(o.order_remark == sell_remark for o in orders):
|
||||
# 卖单价格超过涨停价 → 今日无法成交,跳过下单
|
||||
if sellPrice > self.todayUpStopPrice:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] '
|
||||
f'上方网格[{sellIdx}]卖价 {sellPrice:.3f} > 涨停价 {self.todayUpStopPrice:.3f},'
|
||||
f'今日无法下卖单 (当前网格基准 grid-{currentIdx})')
|
||||
else:
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
str(self.tradeTarget.stock_code),
|
||||
self.tradeTarget.grid_volume,
|
||||
xtconstant.STOCK_SELL, # 卖出
|
||||
sellPrice,
|
||||
xtconstant.FIX_PRICE,
|
||||
sell_remark,
|
||||
self.getName(),
|
||||
)
|
||||
self.orderGrid[sellIdx] = tmpOrderSeq
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'下空单,价格: {sellPrice:.3f}')
|
||||
else:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'已存在同价位空单,跳过下单')
|
||||
|
||||
# --- 下方挂买入单(多单)---
|
||||
# 条件: grid_index < 价格网格长度-1,即当前位置不是价格最高点,还有向上(买入)空间
|
||||
if currentIdx < len(self.tradeTarget.getPriceGrid()) - 1:
|
||||
buyIdx = currentIdx + 1 # 向下一个网格
|
||||
buyPrice = self.tradeTarget.getPriceGrid()[buyIdx]
|
||||
buy_remark = self._make_remark(OrderTypeBuy, buyIdx)
|
||||
|
||||
# 检查是否已存在同 remark 的买单(避免重复挂单)
|
||||
if not any(o.order_remark == buy_remark for o in orders):
|
||||
# 买单价格低于跌停价 → 今日无法成交,跳过下单
|
||||
if buyPrice < self.todayDownStopPrice:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] '
|
||||
f'下方网格[{buyIdx}]买价 {buyPrice:.3f} < 跌停价 {self.todayDownStopPrice:.3f},'
|
||||
f'今日无法下买单 (当前网格基准 grid-{currentIdx})')
|
||||
else:
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
str(self.tradeTarget.stock_code),
|
||||
self.tradeTarget.grid_volume,
|
||||
xtconstant.STOCK_BUY, # 买入
|
||||
buyPrice,
|
||||
xtconstant.FIX_PRICE,
|
||||
buy_remark,
|
||||
self.getName(),
|
||||
)
|
||||
self.orderGrid[buyIdx] = tmpOrderSeq
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'下多单,价格: {buyPrice:.3f}')
|
||||
else:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'已存在同价位多单,跳过下单')
|
||||
else:
|
||||
# grid_index 已到达价格网格上边界,无法再挂买入单(价格已经到顶)
|
||||
# 注意:这里用 dataUpdateLock 包裹检查和下单操作,防止竞态条件:
|
||||
# 主线程在检查 isMarketActive 时,另一线程的行情回调可能同时将其设为 True,
|
||||
# 导致部分标的通过检查下单,部分被拦截(表现为一票有单、一票无单)
|
||||
with self.dataUpdateLock:
|
||||
if not qmtv.isMarketActive or not self.tradeTarget.enabled:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'已过下边界,停止多单交易')
|
||||
f'|- 市场 {qmtv.isMarketActive}, 策略 {self.getName()} '
|
||||
f'{self.tradeTarget.enabled}, 不下单')
|
||||
return
|
||||
|
||||
# 获取当前该标的所有未成交订单
|
||||
orders = qmtv.queryPendingOrder(self.tradeTarget.stock_code, self.getName()) # type: ignore
|
||||
|
||||
# ── 统一网格逻辑 ──
|
||||
# grid_index=0 空仓: 只挂买单 @ grid[1],无持仓可卖
|
||||
# grid_index>0 有仓: 上方挂卖单 @ grid[idx-1],下方挂买单 @ grid[idx+1]
|
||||
if self.tradeTarget.grid_index >= 0:
|
||||
currentIdx = self.tradeTarget.grid_index # type: ignore
|
||||
|
||||
# --- 上方挂卖出单(空单)---
|
||||
# 条件: grid_index > 0,即当前位置不是价格最低点,还有向下(卖出)空间
|
||||
if currentIdx > 0:
|
||||
sellIdx = currentIdx - 1 # 向上一个网格
|
||||
sellPrice = self.tradeTarget.getPriceGrid()[sellIdx]
|
||||
sell_remark = self._make_remark(OrderTypeSell, sellIdx)
|
||||
|
||||
# 检查是否已存在同 remark 的卖单(避免重复挂单)
|
||||
if not any(o.order_remark == sell_remark for o in orders):
|
||||
# 卖单价格超过涨停价 → 今日无法成交,跳过下单
|
||||
if sellPrice > self.todayUpStopPrice:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] '
|
||||
f'上方网格[{sellIdx}]卖价 {sellPrice:.3f} > 涨停价 {self.todayUpStopPrice:.3f},'
|
||||
f'今日无法下卖单 (当前网格基准 grid-{currentIdx})')
|
||||
else:
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
str(self.tradeTarget.stock_code),
|
||||
self.tradeTarget.grid_volume,
|
||||
xtconstant.STOCK_SELL, # 卖出
|
||||
sellPrice,
|
||||
xtconstant.FIX_PRICE,
|
||||
sell_remark,
|
||||
self.getName(),
|
||||
)
|
||||
self.orderGrid[sellIdx] = tmpOrderSeq
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'下空单,价格: {sellPrice:.3f}')
|
||||
else:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'已存在同价位空单,跳过下单')
|
||||
|
||||
# --- 下方挂买入单(多单)---
|
||||
# 条件: grid_index < 价格网格长度-1,即当前位置不是价格最高点,还有向上(买入)空间
|
||||
if currentIdx < len(self.tradeTarget.getPriceGrid()) - 1:
|
||||
buyIdx = currentIdx + 1 # 向下一个网格
|
||||
buyPrice = self.tradeTarget.getPriceGrid()[buyIdx]
|
||||
buy_remark = self._make_remark(OrderTypeBuy, buyIdx)
|
||||
|
||||
# 检查是否已存在同 remark 的买单(避免重复挂单)
|
||||
if not any(o.order_remark == buy_remark for o in orders):
|
||||
# 买单价格低于跌停价 → 今日无法成交,跳过下单
|
||||
if buyPrice < self.todayDownStopPrice:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] '
|
||||
f'下方网格[{buyIdx}]买价 {buyPrice:.3f} < 跌停价 {self.todayDownStopPrice:.3f},'
|
||||
f'今日无法下买单 (当前网格基准 grid-{currentIdx})')
|
||||
else:
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
str(self.tradeTarget.stock_code),
|
||||
self.tradeTarget.grid_volume,
|
||||
xtconstant.STOCK_BUY, # 买入
|
||||
buyPrice,
|
||||
xtconstant.FIX_PRICE,
|
||||
buy_remark,
|
||||
self.getName(),
|
||||
)
|
||||
self.orderGrid[buyIdx] = tmpOrderSeq
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'下多单,价格: {buyPrice:.3f}')
|
||||
else:
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'已存在同价位多单,跳过下单')
|
||||
else:
|
||||
# grid_index 已到达价格网格上边界,无法再挂买入单(价格已经到顶)
|
||||
PrintLog(LogLevel.INFO,
|
||||
f'|- 标的[{self.tradeTarget.targetName()}] 网格策略: '
|
||||
f'已过下边界,停止多单交易')
|
||||
|
||||
# ── 标的管理 ──────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user