From b63475402efd7b748eb921259686504f9d469a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Thu, 25 Jun 2026 21:11:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B8=AF=E8=82=A1ATR=E6=B3=A2=E5=8A=A8?= =?UTF-8?q?=E7=8E=87=E6=AD=A2=E6=8D=9F=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 is_hk_stock(code): 港股判断(5位代码) - 新增 calc_atr(code): 腾讯API K线→ATR(14)计算 - 港股止损增加ATR校验:止损距现价不得小于1×ATR 技术位仍为主依据,ATR仅作为港股高波动下的间距底线 A股不受影响保持原有逻辑 - 不违背"技术位优先,不机械乘系数"原则 --- .../strategy_lifecycle.cpython-312.pyc | Bin 72672 -> 75233 bytes strategy_lifecycle.py | 42 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/__pycache__/strategy_lifecycle.cpython-312.pyc b/__pycache__/strategy_lifecycle.cpython-312.pyc index d2a8a137ff8910fdbf6c2af1575c1b63d8299c1e..6b4811ca923af193f9c18422f5cf8d3319d6194a 100644 GIT binary patch delta 13046 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 RLG@Nbz~WTRTa!7!{|DPAP@4b% delta 10971 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 Z@w$`@tWHKR8LxY7eAE(~;k9f6_`l5-7CQg{ diff --git a/strategy_lifecycle.py b/strategy_lifecycle.py index c9a4d3c..00bc6a1 100644 --- a/strategy_lifecycle.py +++ b/strategy_lifecycle.py @@ -18,6 +18,38 @@ from datetime import datetime import technical_analysis as ta import multi_timeframe as mtf + +def is_hk_stock(code): + """判断是否港股(港股代码5位,A股6位带前导零)""" + return len(str(code)) <= 5 + + +def calc_atr(code, period=14): + """从腾讯API K线数据计算ATR(period),返回ATR值或None""" + try: + url = f"http://ifzq.gtimg.cn/appstock/app/fqkline/get?param=hk{code},day,,,60,qfq" + req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) + resp = urllib.request.urlopen(req, timeout=5).read().decode('utf-8') + data = json.loads(resp) + bars = data.get('data', {}).get(f'hk{code}', {}).get('day', []) + if len(bars) < period + 1: + return None + trs = [] + for i in range(1, min(len(bars), period + 1)): + try: + high = float(bars[i][2]) + low = float(bars[i][3]) + prev_close = float(bars[i-1][4]) if len(bars[i-1]) > 4 else float(bars[i-1][3]) + tr = max(high - low, abs(high - prev_close), abs(low - prev_close)) + trs.append(tr) + except (ValueError, IndexError): + continue + if not trs: + return None + return round(sum(trs) / len(trs), 2) + except Exception: + return None + # 提示词版本追踪 try: from prompt_manager.tracking import record_strategy_generation @@ -581,6 +613,16 @@ def reassess_strategy(code, name, price, cost, shares, current_action, new_stop = min_stop if old_stop != new_stop: print(f" 最小止损 {round(min_stop_gap*100)}%间距约束: {old_stop}→{new_stop} (趋势{'强' if is_strong_trend else '普通'})") + + # 港股附加:ATR波动率校验 — 止损距现价不得小于 1×ATR(14) + if is_hk_stock(code): + atr = calc_atr(code) + if atr and atr > 0: + min_atr_stop = round(price - atr, 2) + if new_stop > min_atr_stop: + old_stop_val = new_stop + new_stop = min_atr_stop + print(f" 港股ATR波动率校验({atr:.2f}): 止损 {old_stop_val}→{new_stop} (1×ATR间距)") # ----- 止盈设置 ----- if is_short_term_strong_trend and not is_new_entry: