blockchain/internal/lib/strategy/bool_test.go

66 lines
1.7 KiB
Go
Raw Permalink Normal View History

2025-08-20 12:35:31 +00:00
package strategy
import (
"github.com/shopspring/decimal"
"testing"
)
func TestBoll_WarmupAndSliding(t *testing.T) {
n := 5
k := d(2.0)
b := NewBollW(n)
// 前 n-1 根not ready
for i, px := range []float64{10, 11, 12, 13} {
out := b.Push(d(int64(px)), k)
if out.Ready {
t.Fatalf("i=%d: should not be ready yet", i)
}
}
// 第 n 根開始ready
out := b.Push(d(14), k)
if !out.Ready {
t.Fatalf("should be ready at %d-th push", n)
}
// 中線應為 (10+11+12+13+14)/5 = 12
if out.Mid.StringFixed(6) != d(12).StringFixed(6) {
t.Fatalf("mid expect 12, got %s", out.Mid)
}
// 標準差 > 0上軌 > 中線 > 下軌
if !out.Std.GreaterThan(decimal.Zero) ||
!out.Upper.GreaterThan(out.Mid) ||
!out.Mid.GreaterThan(out.Lower) {
t.Fatalf("band ordering violated: U=%s M=%s L=%s Std=%s", out.Upper, out.Mid, out.Lower, out.Std)
}
// 再推兩根 -> 視窗滑到 [12,13,14,15,16],中線=14
for _, px := range []float64{15, 16} {
out = b.Push(d(int64(px)), k)
}
if out.Mid.StringFixed(6) != d(14).StringFixed(6) {
t.Fatalf("sliding mid expect 14, got %s", out.Mid)
}
if !out.Std.GreaterThan(decimal.Zero) {
t.Fatalf("std should remain > 0 after slide, got %s", out.Std)
}
}
func TestBoll_FlatSeries(t *testing.T) {
n := 4
k := d(2.0)
b := NewBollW(n)
// 全部相同價格 -> 標準差=0、三條線重合
for i := 0; i < n; i++ {
_ = b.Push(d(10), k)
}
out := b.Push(d(10), k) // 視窗仍為相同值
if !out.Std.Equal(decimal.Zero) {
t.Fatalf("std should be 0 on flat series, got %s", out.Std)
}
if !(out.Upper.Equal(out.Mid) && out.Mid.Equal(out.Lower) && out.Mid.Equal(d(10))) {
t.Fatalf("bands should coincide at 10: U=%s M=%s L=%s", out.Upper, out.Mid, out.Lower)
}
}