【发布时间】:2015-12-01 09:56:27
【问题描述】:
我正致力于直接在 golang 中开发技术指标库。除其他外,它是学习 golang 的练习。
我一直在通过使用 TA-Lib(或者更确切地说是 TA-Lib 周围的 ruby 包装器)生成的数据构建测试用例来验证我的算法的结果。
在我开始实施布林带之前,这一直运行良好。我的实现似乎运行良好,但在小数点后 14-15 位有所不同。
我已阅读 Floating point math in different programming languages 并怀疑这可能是罪魁祸首(我的计算顺序略有不同)。
编辑添加:
上面的问题涉及浮点数学的一个非常简单的表现形式。很难确认一段较长的代码确实遇到了这个问题。
我如何确认这只是浮点数学的变化,因为顺序?
/结束编辑
我的理解正确吗?
这是我的实现:
package ta
import (
"math"
)
func BollingerBands(values []float64, period int) ([]float64, []float64, []float64) {
deviationsUp := 2.0
deviationsDown := 2.0
middleBand := Sma(values, period)
offset := len(values)-len(middleBand)
var upperBand []float64
var lowerBand []float64
for idx, v := range middleBand {
backIdx := offset+idx-period+1
curIdx := offset+idx+1
if backIdx < 0 {
backIdx = 0
}
stdDev := SliceStdDev(values[backIdx:curIdx])
upperBand = append(upperBand, v + (stdDev * deviationsUp))
lowerBand = append(lowerBand, v - (stdDev * deviationsDown))
}
return upperBand, middleBand, lowerBand
}
// Sma produces the Simple Moving Average for the
// supplied array of float64 values for a given period
func Sma(values []float64, period int) []float64{
var result []float64
for index,_ := range values {
indexPlusOne := index+1
if(indexPlusOne>=period) {
avg := Mean(values[indexPlusOne-period:indexPlusOne])
result = append(result, avg)
}
}
return result
}
// SliceMean returns the Mean of the slice of float64
func SliceMean(values []float64) float64 {
var total float64=0
for _,element := range values {
total += element
}
return total / float64(len(values))
}
// SliceVariance returns the variance of the slice of float64.
func SliceVariance(values []float64) float64 {
if 0 == len(values) {
return 0.0
}
m := SliceMean(values)
var sum float64
for _, v := range values {
d := v - m
sum += d * d
}
return sum / float64(len(values))
}
// SliceStdDev returns the standard deviation of the slice of float64.
func SliceStdDev(values []float64) float64 {
return math.Sqrt(SliceVariance(values))
}
这会产生以下值的上限<[]float64 | len:6, cap:8>: [94.92564730599291, 94.50588827974477, 92.12752961253167, 101.58367006802706, 114.64331379078675, 120.58088881180322]
使用红宝石:
require 'indicator/mixin'
x = [26.0, 54.0, 8.0, 77.0, 61.0, 39.0, 44.0, 91.0, 98.0, 17.0]
y = x.indicator(:bbands_5)
# {:out_real_upper_band=>[94.9256473059929, 94.50588827974477, 92.12752961253167, 101.58367006802709, 114.64331379078678, 120.58088881180323, nil, nil, nil, nil] <SNIP>}
【问题讨论】:
-
这不是一个答案,但如果您想排除显示(四舍五入)浮点值作为差异的原因,您可以考虑将两者打印为十六进制并进行比较。跨度>
-
如果您不以完全相同的顺序执行操作,则完全可以预期得到类似的结果差异。此外,根据编译器使用浮点寄存器的方式,您可能会有所不同(x86 的 C 代码通常被编译为“意外”利用 x87 寄存器的完整 80 位精度,因此如果您舍入到常规值,则会得到不同的舍入一直是 64 位)。
-
@WanderNauta 似乎是一个答案。谢谢
-
@MatteoItalia 谢谢。只要我理解为什么,它的舍入方式不同就没有什么大问题
标签: go floating-point-precision