feat: 止损洗盘检测(60日K线反弹验证)

- 止损触发后检查是否反弹回SL以上3%→标记"洗盘"
- 模塑科技这类: 差两分钱触发+后来反弹=洗盘
- 执行层统一处理: 卖飞/洗盘/临界触发 三类边缘案例
This commit is contained in:
知微
2026-06-25 20:33:34 +08:00
parent 127a0ff021
commit dff8e17d68
2 changed files with 772 additions and 794 deletions
+23 -5
View File
@@ -131,9 +131,11 @@ def evaluate_strategy(s, price):
exec_verdict = "待定"
exec_fail = None
# 取近期最高价(判断是否卖飞,只对有TP的策略拉数据
# 取近期最高/最低价(判断卖飞/洗盘
recent_high = 0
if tp > 0:
recent_low = 0
sl_recovery = False
if tp > 0 or sl > 0:
try:
prefix = "sh" if code.startswith(('60','68','51','56','50')) else "sz" if code.startswith(('00','30','15')) else "hk"
url = f"http://ifzq.gtimg.cn/appstock/app/fqkline/get?param={prefix}{code},day,,,60,qfq"
@@ -144,13 +146,29 @@ def evaluate_strategy(s, price):
day_key = 'qfqday' if prefix != 'hk' else 'day'
bars = data.get('data', {}).get(f'{prefix}{code}', {}).get(day_key, [])
if bars:
recent_high = max(float(b[2]) for b in bars if len(b) > 2)
prices = [(float(b[2]), float(b[3]), b[0]) for b in bars if len(b) > 3] # (high, low, date)
recent_high = max(p[0] for p in prices)
recent_low = min(p[1] for p in prices)
# 检查止损触发后的走势:是否后来反弹了?
if sl > 0:
# 找出价格低于SL的K线
below_sl = [p for p in prices if p[1] <= sl]
above_sl_later = [p for p in prices if p[1] > sl * 1.03]
if below_sl and above_sl_later:
# 曾跌破SL,但后来涨回去了 → 洗盘
first_below = min(below_sl, key=lambda x: x[2])
last_above = max(above_sl_later, key=lambda x: x[2])
if last_above[2] > first_below[2]:
sl_recovery = True
except:
pass
if sl > 0 and price <= sl:
if price >= sl * 0.95:
exec_verdict = "存疑(临界触发"
if sl_recovery:
exec_verdict = "洗盘(触发后反弹"
exec_fail = "stop_too_tight"
elif price >= sl * 0.95:
exec_verdict = "临界(差一点触发)"
exec_fail = "stop_too_tight"
else:
exec_verdict = "已触发"