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

时间:2020-01-17 12:05:47

标签: pine-script

我有一个指标,它根据单个变量的值在1到-1之间波动,我们称其为M。我想在一段时间内取M的均值和sDev,但我想做分别表示M的正值和负值。

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

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

更新

似乎我遇到了另一个问题,它可能是一个单独的问题,但是我将在此处提供一些背景信息。我想做的是获取标准偏差,并将其添加到给定回溯期的平均值中,然后分别对指标的正负两面进行计算。

我发现,以移动平均线工作符合预期。当振荡器从pos变为neg或相反时,平均值计算只是使用上一次为pos或neg的值再次针对给定的一侧重新开始计算。下面的屏幕说明了所有这些点。

stdev()函数是另一回事。它的作用不像sma()函数计算每一侧。取而代之的是,仅当回溯期大于或等于pos或neg值的连续序列时,才计算该系列的sdev。因此,如果我将回溯期设置为60,这很长,那么就不会有一个时间序列在该长度上所有pos或neg,因此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)

输出的第一张屏幕截图显示了我在冲动中突出显示了一个早期的柱线。并不是说在“数据”窗口中,sdev是na,而平均值不是。

Image1 Link

在第二个中,我在正向相同的脉冲中突出显示了一个等于或大于sdev回溯期(在这种情况下为七个)的小节。上级sdev不会显示值。

Image 2 Link

现在的问题是,由于stdev()函数的行为方式,我无法计算长期的sdev。我一直无法找到解决该系列早期问题的方法。我现在正在阅读新答案,所以我会给您一个机会。

更新2

使用以下Gustavo Cardelle的善意建议,我可以使95%的工作正常。我有一个尚未解决的小问题,但我会尽快解决。我所做的就是回顾很长一段时间,并使用固定数量的良好值构建了平均值和sDev。因此,如果我想要的回顾期是15个非na条的平均值和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

确定最后一位,并更新了上面的代码。按预期工作!

2 个答案:

答案 0 :(得分:1)

您的想法遇到了一些限制。

让我们首先讨论为何pagination = { 'pageSize': 25, 'someInformation': 'blablabla...' } res.header('Access-Control-Expose-Headers', 'X-Pagination'); res.setHeader('X-Pagination', JSON.stringify(pagination)); 表现出色而sma()却不能做到这一点:当您计算平均值但缺少一个值时,您只需将丢失的值替换为最后一个已知的平均值,然后您的平均计算不受此影响。但是,标准偏差与样本量成非线性关系,并猜测用于替换na的值,以使最终结果不会改变,这是什么是 NOT (编辑)的目的。

话虽如此,并考虑如下偏差标准偏差表达式:

Biased standard deviation

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

1)进行一个stdev()循环,在该循环中,您可以向后看N条并计算出您感兴趣的值的平均值(仅正值或负值)。借此机会计算N,即您正在平均的有效值的数量

2)进行另一个for循环,您在时间上再次回看相同的N条,并计算与步骤1中计算出的平均值相比,每个有效数据点的平方差总和。这是公式的SIGMA [(xi-x_avg)^ 2]部分)

3)将步骤2的结果除以步骤1中获得的N

4)通过将步骤3中获得的值平方根来获得所需的stdev。

最后,这项任务很困难,因为Pine不允许我们玩可变大小的向量,并且由于标准偏差函数的本质。

答案 1 :(得分:0)

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

类似的东西

open class MyTestClass
{
      open func clear(){...}
      internal func initialize(){...}
}