From 7836b5cf75840f95656f921547d90226f2ff9669 Mon Sep 17 00:00:00 2001 From: hmo Date: Wed, 12 Aug 2026 10:44:21 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8C=87=E6=A0=87=E5=8F=A3=E5=BE=84?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E2=80=94=E2=80=94indicators.calc=5Fatr?= =?UTF-8?q?=E6=94=B9EMA=E5=B9=B3=E6=BB=91(=E4=B8=8Ebacktest=5Fframework?= =?UTF-8?q?=E5=AE=8C=E5=85=A8=E4=B8=80=E8=87=B4),=E6=B6=88=E9=99=A4?= =?UTF-8?q?=E5=9B=9E=E6=B5=8BEMA/=E5=AE=9E=E7=9B=98SMA=E7=9A=843.59%?= =?UTF-8?q?=E5=8F=A3=E5=BE=84=E5=88=86=E8=A3=82,=E5=9B=9E=E6=B5=8B?= =?UTF-8?q?=E5=AE=9E=E7=9B=98=E5=90=8C=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/profile-scripts/indicators.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/deploy/profile-scripts/indicators.py b/deploy/profile-scripts/indicators.py index 6a012628..c6a33ffb 100644 --- a/deploy/profile-scripts/indicators.py +++ b/deploy/profile-scripts/indicators.py @@ -47,17 +47,27 @@ def calc_rsi(series, n=14): def calc_atr(klines, n=14): - """ATR(Average True Range),与回测 calc_factors 的 atr_pct 同口径。 - klines: [{high, low, close, ...}]""" + """ATR(Average True Range),EMA 平滑——与 backtest_framework.calc_atr 完全一致 + (2026-08-12 统一口径:原 SMA 与回测 EMA 差 3.59%,回测实盘口径分裂)。 + klines: [{high, low, close, ...}]。返回最新 ATR 值(单值)。""" if len(klines) < n + 1: return None - trs = [] - for i in range(1, len(klines)): - h, l, pc = klines[i]["high"], klines[i]["low"], klines[i - 1]["close"] - tr = max(h - l, abs(h - pc), abs(l - pc)) - trs.append(tr) - atr = sum(trs[-n:]) / n - return atr + highs = [k["high"] for k in klines] + lows = [k["low"] for k in klines] + closes = [k["close"] for k in klines] + # True Range(与 backtest_framework.calc_tr 一致) + tr = [highs[0] - lows[0]] + for i in range(1, len(highs)): + hl = highs[i] - lows[i] + hc = abs(highs[i] - closes[i - 1]) + lc = abs(lows[i] - closes[i - 1]) + tr.append(max(hl, hc, lc)) + # EMA 平滑(与 backtest_framework.calc_atr 一致:calc_ema(tr, n)) + k = 2 / (n + 1) + ema = tr[0] + for t in tr[1:]: + ema = t * k + ema * (1 - k) + return ema def calc_obv(klines):