diff --git a/deploy/profile-scripts/strategy_lifecycle.py b/deploy/profile-scripts/strategy_lifecycle.py index ac56e572..35431fda 100644 --- a/deploy/profile-scripts/strategy_lifecycle.py +++ b/deploy/profile-scripts/strategy_lifecycle.py @@ -367,32 +367,28 @@ def enforce_strategy_quality(code, name, result): def calc_atr(code, period=14): - """从腾讯API K线数据计算ATR(period),返回ATR值或None""" + """从 stock_daily 表计算ATR(period),返回ATR值或None(2026-08-26 分层铁律:消费层不直连腾讯API)""" 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: + conn = sqlite3.connect('/home/hmo/MoFin/data/mofin.db', timeout=5) + rows = conn.execute( + "SELECT high, low, close FROM stock_daily WHERE code=? ORDER BY date DESC LIMIT 60", (code,) + ).fetchall() + conn.close() + if len(rows) < period + 1: return None + rows = list(reversed(rows)) 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 + for i in range(1, len(rows)): + high, low, close = float(rows[i][0]), float(rows[i][1]), float(rows[i][2]) + prev_close = float(rows[i-1][2]) + tr = max(high - low, abs(high - prev_close), abs(low - prev_close)) + trs.append(tr) if not trs: return None - return round(sum(trs) / len(trs), 2) + return round(sum(trs[-period:]) / period, 2) except Exception: return None - def calc_chip_sr(code, price): """从筹码分布计算支撑/阻力位。