You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何归一化TradingView多零交叉指标并保留零交叉特性?

问题描述

在TradingView中整合Coppock Curve、QQE、PMI三类零交叉指标时,因指标原生值域差异大,使用自定义历史极值归一化函数将其统一至[-100,100]区间后,指标的零交叉点出现偏移,无法在原应交叉0线的位置准确对齐。需要找到既能统一缩放范围,又能严格保留零交叉一致性的方案。

原因分析

原normalize函数基于历史极值线性映射,公式为:
_min + (_max - _min) * (_src - _historicMin) / (_historicMax - _historicMin)
这种方式会将原指标的整个值域从[_historicMin, _historicMax]强制拉伸到[-100,100],但原指标的0点并非历史极值的中点,因此映射后0点会偏移到非零位置,破坏了零交叉的一致性。

解决方案:中心化比例缩放

采用以0为中心的比例缩放,核心逻辑是:

  • 计算指标历史数据的绝对值最大值(确保正负方向缩放比例一致)
  • 将原指标值乘以100 / max_abs_value,把值域缩放到[-100,100]区间
  • 保留原指标的0点不变,确保零交叉位置完全对齐

这种方式既统一了指标的显示范围,又严格保留了零交叉的一致性,同时避免了历史极值漂移导致的缩放比例突变。

修改后的完整代码
//@version=4
study("QQE, CC, PMI (Normalized with Zero-Cross Preserve)", shorttitle="QQE/CC/PMI Norm", precision=4, resolution="")

// 中心化归一化函数:保留零交叉,缩放到[-100,100]
normalize_preserve_zero(_src) =>
    var float max_abs = 0.0
    current_abs = abs(nz(_src))
    max_abs := max(max_abs, current_abs)
    // 避免除以0,最小用0.0001
    scale_factor = 100 / max(max_abs, 0.0001)
    _src * scale_factor

// ------------------------------
// Coppock Curve
// ------------------------------
section1 = input(false, 'Coppock Curve')
length = input(title="Smoothing Length", type=input.integer, defval=10)
longRocLength = input(title="Long ROC Length", type=input.integer, defval=14)
shortRocLength = input(title="Short ROC Length", type=input.integer, defval=11)
src = input(title="Source", type=input.source, defval=close)

coppock = wma(roc(src, longRocLength) + roc(src, shortRocLength), length)
normalized_coppock = normalize_preserve_zero(coppock)

coppockColor = normalized_coppock > 0 ? #0ebb23 : color.red
plot(normalized_coppock, title="Coppock", linewidth=2, color=coppockColor, transp=0)

// ------------------------------
// QQE
// ------------------------------
section2 = input(false, 'QQE')
src2=input(close)
length2 = input(14,"RSI Length", minval=1)
SSF=input(5, "SF RSI SMoothing Factor", minval=1)
showsignals = input(title="Show Crossing Signals?", type=input.bool, defval=true)
highlighting = input(title="Highlighter On/Off ?", type=input.bool, defval=true)

RSII=ema(rsi(src2,length2),SSF)
TR=abs(RSII-RSII[1])
wwalpha = 1/ length2
WWMA = 0.0
WWMA := wwalpha*TR + (1-wwalpha)*nz(WWMA[1])
ATRRSI=0.0
ATRRSI := wwalpha*WWMA + (1-wwalpha)*nz(ATRRSI[1])
QQEF=ema(rsi(src2,length2),SSF)
QUP=QQEF+ATRRSI*4.236
QDN=QQEF-ATRRSI*4.236
QQES=0.0
QQES:=QUP<nz(QQES[1]) ? QUP : QQEF>nz(QQES[1]) and QQEF[1]<nz(QQES[1]) ? QDN :  QDN>nz(QQES[1]) ? QDN : QQEF<nz(QQES[1]) and QQEF[1]>nz(QQES[1]) ? QUP : nz(QQES[1])

QQF_raw = (QQEF-50)*3
normalized_QQF = normalize_preserve_zero(QQF_raw)
QQS_raw = (QQES-50)*3
normalized_QQS = normalize_preserve_zero(QQS_raw)

plot(normalized_QQF, "FAST", color.maroon, 2)
plot(normalized_QQS, "SLOW", color=color.blue, linewidth=1)

longFillColor = highlighting ? (QQEF>QQES ? color.green : na) : na
shortFillColor = highlighting ? (QQEF<QQES ? color.red : na) : na
fill(normalized_QQF, normalized_QQS, title="UpTrend Highligter", color=longFillColor)
fill(normalized_QQF, normalized_QQS, title="DownTrend Highligter", color=shortFillColor)

// ------------------------------
// Basic Polychromatic Momentum Indicator (PMI)
// ------------------------------
section3 = input(false, 'PMI')
len = input(14, title="Length", minval=1)
smoothing = input(2, title="Smoothing", minval=1)

mom = src - src[len]
pmi = (mom - (mom - mom[len]) / len) * 130
sm_pmi = sma(pmi, smoothing)
normalized_sm_pmi = normalize_preserve_zero(sm_pmi)

plot(normalized_sm_pmi, title="PMI", color=color.blue, linewidth=2)

// 零参考线
hline(0, title="Zero Level", linestyle=hline.style_dotted)
关键说明
  • 新的normalize_preserve_zero函数会持续跟踪指标的历史绝对值最大值,动态调整缩放比例,确保指标始终在[-100,100]范围内
  • 原指标的0点经过缩放后仍为0,完美保留零交叉信号的一致性
  • 所有指标的正负方向缩放比例对称,不会扭曲原指标的波动幅度比例

内容的提问来源于stack exchange,提问作者vulcan4d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:14:54