使用满足条件的数据计算均值和标准差

Calculating Mean And Standard Deviation With Data That Meets A Condition

我有一个指标,它根据单个变量的值在 1 和 -1 之间振荡,我们称它为 M。我想在一段时间内获取 M 的均值和 sDev,但我想要分别为 M.

的正值和负值执行此操作

换句话说,我希望能够在时间序列中当 M > 0 时获得 M 的平均值,同时忽略时间序列中 M < 0 时的任何值。对于 sDev 也是如此,对于负值则反之亦然。

我不确定如何在代码中过滤掉我不需要的数据,或者这是否可行。感谢您的帮助!

更新

看来我 运行 遇到了另一个问题,这可能是一个单独的问题,但我会在这里提供一些背景信息。我想做的是取标准偏差并将其添加到给定回顾期的平均值,并分别对指标的正负侧执行此操作。

我发现采用移动平均线的效果与预期一致。当振荡器从正到负或相反方向翻转时,对于给定的一侧,使用上次正或负时的值简单地重新开始计算平均值。下面的屏幕说明了所有这些要点。

stdev() 函数是另一回事。它不像 sma() 函数那样计算每一边。相反,它只会在回溯期大于或等于 pos 或 neg 值的完整序列时计算系列的 sdev。因此,如果我将我的回溯期设置为 60,这是一个很长的时间序列,那么不会有一个时间序列在该长度内所有正或负,因此 sdev 将读作 na。我曾希望它只包含该系列早期部分的 sdev,但情况似乎并非如此。以下是有助于说明的屏幕和代码

Upper = Spread > 0 ? Spread : na
Lower = Spread < 0 ? Spread : na

lbp = 60  //avg and sdev look back periods
sDevLbp = 7  

UpperSdev = stdev(Upper,sDevLbp)
LowerSdev = stdev(Lower,sDevLbp)


UpperTreshold = sma(Upper,lbp)
LowerTreshold = sma(Lower,lbp)


plot(msaSpread, title='MSA Spread', style=columns)
plot(UpperS, title='Upper S', style=line, color=orange)
plot(UpperTreshold, title='Upper Band', style=line, color=purple)

输出的第一个屏幕截图显示我突出显示了上升趋势中的早期柱线。不是在数据 window 中,sdev 是 na 而均值不是。

Image1 Link

在第二个中,我突出显示了一个等于或大于 sdev 回溯期(在本例中为 7)的柱状图,在正侧的同一脉冲中。不是上面的 sdev 显示一个值。

Image 2 Link

现在的问题是,由于 stdev() 函数的作用方式,我无法计算更长期的 sdev。我一直无法找到解决方法来访问该系列中较早的条目。我现在正在阅读那个新答案,所以我会试一试。

更新 2

我使用下面 Gustavo Cardelle 的善意建议使事情成功了 95%。我有一个小问题尚未解决,但我稍后会解决。我所做的是回顾很长一段时间 运行ge 并使用固定数量的良好值构建 avg 和 sDev。因此,如果我想要的回顾期是超过 15 个非 na 柱的 avg 和 sDev,我将回顾超过 100 个柱并获取最近的 15 个好的柱并用它们计算。下面的代码和屏幕。我遇到的问题是,虽然上限看起来是正确的,但当值为正时它会移动,当值为负时它会变平,而当值为正时下限似乎会摆动。我不确定这是为什么。

lbp = 15
Range = 100

lbpCount = 1
UpperAVG = 0.0
for i = 0 to Range+1
    if(na(Upper[i]))
        continue
    if(lbpCount<=lbp)
        UpperAVG := UpperAVG+Upper[i]
        lbpCount := lbpCount+1
    if(lbpCount>lbp)
        UpperAVG := UpperAVG/lbp
        break

lbpCount2 = 1
holder = 0.0
UpperSTDEV = 0.0
for i = 0 to Range+1
    if(na(Upper[i]))
        continue
    if(lbpCount2<=lbp)
        holder := Upper[i] - UpperAVG
        holder := holder*holder
        UpperSTDEV := UpperSTDEV + holder
        lbpCount2 := lbpCount2+1
    if(lbpCount2>lbp)
        UpperSTDEV := UpperSTDEV/lbp
        UpperSTDEV := sqrt(UpperSTDEV)
        break

plot(UpperSTDEV+UpperAVG, title='UpperBOUND', color=orange )        


lbpCount3 = 1
LowerAVG = 0.0
for i = 0 to Range+1
    if(na(Lower[i]))
        continue
    if(lbpCount3<=lbp)
        LowerAVG := LowerAVG+Lower[i]
        lbpCount3 := lbpCount3+1
    if(lbpCount3>lbp)
        LowerAVG := LowerAVG/lbp
        break

lbpCount4 = 1
holder4 = 0.0
LowerSTDEV = 0.0
for i = 0 to Range+1
    if(na(Lower[i]))
        continue
    if(lbpCount4<=lbp)
        holder4 := Lower[i] - LowerAVG
        holder4 := holder4*holder4
        LowerSTDEV := LowerSTDEV + holder4
        lbpCount4 := lbpCount4+1
    if(lbpCount4>lbp)
        LowerSTDEV := LowerSTDEV/lbp
        LowerSTDEV := sqrt(LowerSTDEV)
        break

plot(LowerAVG-LowerSTDEV, title='LowerBOUND', color=orange )

这是输出的图片:

Output Image Link

正如您所见,下限有点奇怪,因为即使值不是负数它也会移动(因此没有任何变化)。我认为这与 sdev 计算中的负值有关,但我认为我的数学是正确的。我可能盯着这个看得太久了,或者它可能是对的,但我不明白为什么。你有它!只需要弄清楚最后的细节。感谢大家的帮助!

更新 3

想出了最后一点并更新了上面的代码。按预期工作!

您可以使用 三元条件运算符 并创建两个变量(正和负)

类似的东西

ema_M = ema(M, length)
ema_M_Pos = M > 0 ? ema_M : na
ema_M_Neg = M < 0 ? ema_M : na
plot (ema_M_Pos)
plot (ema_M_Neg)

您的想法 运行 有一些限制。

让我们首先讨论为什么 sma() 做得好而 stdev() 做得不好:当您计算平均值并且缺少一个值时,您只需用最后一个已知值替换缺失值average 并且您的平均计算不会受到影响。然而,标准偏差非线性地依赖于样本数量,并且猜测使用哪个值来替换 na 以使最终结果不改变是一个繁重的迭代过程,因为 pine 是 NOT(编辑)意味着。

就是说,考虑到有偏差的标准差表达式,如:

我建议采用以下解决方法:

1) 制作一个 for 循环,您可以在其中回顾 N 个柱状图并计算您感兴趣的值的平均值(仅正值或仅负值)。借此机会计算 N,即您要平均的有效值的数量

2) 进行另一个 for 循环,在该循环中您再次查看相同的 N 个柱状图,并计算每个有效数据点与第一步中计算的平均值相比的平方差总和。这是公式的 SIGMA[(xi-x_avg)^2] 部分)

3)将第2步的结果除以第1步得到的N

4) 对步骤3

中得到的值进行平方根得到所需的stdev

最后,这个任务很困难,因为 Pine 不允许我们使用可变大小的向量,而且标准差函数的本质也是如此。