PineScript V5自定义区间EMA计算求助:代码返回常量值
PineScript V5 自定义EMA函数问题解决
你的代码返回常量值的原因有两个:
- 逻辑错误:当前代码只是计算了输入序列前
period个值的简单平均,完全没有实现EMA的递归计算逻辑。 - 变量声明问题:用
var声明的sum只会在第一根bar初始化,后续bar不会重置或更新这个值,导致返回的始终是第一根bar计算的初始平均值。
正确实现方式分两种场景:
场景1:逐bar实时计算EMA(和内置ta.ema行为一致)
不需要额外外层循环,利用PineScript逐bar运行的特性递归计算即可:
calcEma(src, period) => alpha = 2 / (period + 1) // EMA平滑系数 var float emaVal = na // 保存上一根bar的EMA值 if bar_index >= period - 1 // 初始EMA用SMA初始化,之后递归计算 emaVal := na(emaVal) ? ta.sma(src, period) : src * alpha + emaVal * (1 - alpha) emaVal
场景2:针对指定数组(区间数据)计算EMA
如果是对一段历史数据数组计算区间内的EMA,需要两层循环:先计算初始SMA,再遍历后续元素递归更新EMA:
calcEmaForVector(oVector, period) => arrayLen = array.size(oVector) if arrayLen < period na // 数组长度不足周期,返回空值 else alpha = 2 / (period + 1) // 第一步:计算前period个元素的SMA作为初始EMA emaVal = 0.0 for i = 0 to period - 1 emaVal += array.get(oVector, i) emaVal := emaVal / period // 第二步:遍历剩余元素,递归计算EMA for i = period to arrayLen - 1 emaVal := array.get(oVector, i) * alpha + emaVal * (1 - alpha) emaVal
说明
EMA的核心逻辑是递归加权平均,每一个新值的EMA都依赖前一个EMA结果,这和简单平均的一次性计算有本质区别。你可以根据自己的测试场景选择对应的实现方式。
内容的提问来源于stack exchange,提问作者klausreckefusshamburgde
相关产品推荐
相关产品推荐

