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) } }