72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
|
package strategy
|
|||
|
|
|||
|
import (
|
|||
|
"github.com/shopspring/decimal"
|
|||
|
"testing"
|
|||
|
)
|
|||
|
|
|||
|
func TestRSI_WarmupAndRange(t *testing.T) {
|
|||
|
n := 2
|
|||
|
r := NewRSI(n)
|
|||
|
|
|||
|
type step struct {
|
|||
|
close float64
|
|||
|
wantReady bool
|
|||
|
}
|
|||
|
steps := []step{
|
|||
|
{10, false}, // 第一根,只建立 prevC
|
|||
|
{11, false}, // 第二根,累積
|
|||
|
{12, true}, // 第三根,完成 seed -> ready
|
|||
|
{13, true},
|
|||
|
{12, true},
|
|||
|
{11, true},
|
|||
|
{12, true},
|
|||
|
{13, true},
|
|||
|
}
|
|||
|
|
|||
|
for i, st := range steps {
|
|||
|
val, ready := r.Push(CandleForStrategy{C: dv(st.close)})
|
|||
|
if ready != st.wantReady {
|
|||
|
t.Fatalf("step %d: ready got=%v want=%v", i, ready, st.wantReady)
|
|||
|
}
|
|||
|
if ready {
|
|||
|
// RSI 應落在 0..100
|
|||
|
if val.LessThan(decimal.Zero) || val.GreaterThan(decimal.NewFromInt(100)) {
|
|||
|
t.Fatalf("step %d: RSI out of [0,100], got %s", i, val)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func TestRSI_PerfectUpAndDown(t *testing.T) {
|
|||
|
n := 2
|
|||
|
r := NewRSI(n)
|
|||
|
|
|||
|
// 先 seed
|
|||
|
_, _ = r.Push(CandleForStrategy{C: d(10)})
|
|||
|
_, _ = r.Push(CandleForStrategy{C: d(11)})
|
|||
|
val, ready := r.Push(CandleForStrategy{C: d(12)})
|
|||
|
if !ready {
|
|||
|
t.Fatalf("should be ready after %d candles", n)
|
|||
|
}
|
|||
|
|
|||
|
// 連續上漲:理想情況 avgLoss -> 0,RSI 逼近 100
|
|||
|
val, ready = r.Push(CandleForStrategy{C: d(13)})
|
|||
|
if !ready || !val.LessThanOrEqual(decimal.NewFromInt(100)) {
|
|||
|
t.Fatalf("uptrend: ready=%v val=%s", ready, val)
|
|||
|
}
|
|||
|
|
|||
|
// 連續下跌:理想情況 avgGain -> 0,RSI 逼近 0
|
|||
|
r = NewRSI(n)
|
|||
|
_, _ = r.Push(CandleForStrategy{C: d(13)})
|
|||
|
_, _ = r.Push(CandleForStrategy{C: d(12)})
|
|||
|
val, ready = r.Push(CandleForStrategy{C: d(11)})
|
|||
|
if !ready {
|
|||
|
t.Fatalf("should be ready after %d candles", n)
|
|||
|
}
|
|||
|
val, ready = r.Push(CandleForStrategy{C: d(10)})
|
|||
|
if !ready || !val.GreaterThanOrEqual(decimal.Zero) {
|
|||
|
t.Fatalf("downtrend: ready=%v val=%s", ready, val)
|
|||
|
}
|
|||
|
}
|