我正在努力直接在golang开发一个技术指标库。除其他外,这是一次学习golang的练习。稍微不同的浮点数学结果(C去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]
使用Ruby:
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看起来像一个答案。谢谢 –