mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-19 02:14:35 +08:00
feat(market): add Donchian channel calculation
Add calculateDonchian function to compute highest high and lowest low over a specified period. This is the foundation for box (range) detection in the multi-period box indicator system for grid trading.
This commit is contained in:
@@ -1210,3 +1210,35 @@ func ExportCalculateATR(klines []Kline, period int) float64 {
|
|||||||
func ExportCalculateBOLL(klines []Kline, period int, multiplier float64) (upper, middle, lower float64) {
|
func ExportCalculateBOLL(klines []Kline, period int, multiplier float64) (upper, middle, lower float64) {
|
||||||
return calculateBOLL(klines, period, multiplier)
|
return calculateBOLL(klines, period, multiplier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calculateDonchian calculates Donchian channel (highest high, lowest low) for given period
|
||||||
|
func calculateDonchian(klines []Kline, period int) (upper, lower float64) {
|
||||||
|
if len(klines) == 0 {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use all available klines if period > len(klines)
|
||||||
|
start := len(klines) - period
|
||||||
|
if start < 0 {
|
||||||
|
start = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
upper = klines[start].High
|
||||||
|
lower = klines[start].Low
|
||||||
|
|
||||||
|
for i := start + 1; i < len(klines); i++ {
|
||||||
|
if klines[i].High > upper {
|
||||||
|
upper = klines[i].High
|
||||||
|
}
|
||||||
|
if klines[i].Low < lower {
|
||||||
|
lower = klines[i].Low
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return upper, lower
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportCalculateDonchian exports calculateDonchian for testing
|
||||||
|
func ExportCalculateDonchian(klines []Kline, period int) (float64, float64) {
|
||||||
|
return calculateDonchian(klines, period)
|
||||||
|
}
|
||||||
|
|||||||
@@ -500,3 +500,40 @@ func TestIsStaleData_EmptyKlines(t *testing.T) {
|
|||||||
t.Error("Expected false for empty klines, got true")
|
t.Error("Expected false for empty klines, got true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCalculateDonchian(t *testing.T) {
|
||||||
|
// Create test klines with known high/low values
|
||||||
|
klines := []Kline{
|
||||||
|
{High: 100, Low: 90},
|
||||||
|
{High: 105, Low: 88},
|
||||||
|
{High: 102, Low: 92},
|
||||||
|
{High: 108, Low: 85},
|
||||||
|
{High: 103, Low: 91},
|
||||||
|
}
|
||||||
|
|
||||||
|
upper, lower := ExportCalculateDonchian(klines, 5)
|
||||||
|
|
||||||
|
if upper != 108 {
|
||||||
|
t.Errorf("Expected upper = 108, got %v", upper)
|
||||||
|
}
|
||||||
|
if lower != 85 {
|
||||||
|
t.Errorf("Expected lower = 85, got %v", lower)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateDonchian_PartialPeriod(t *testing.T) {
|
||||||
|
klines := []Kline{
|
||||||
|
{High: 100, Low: 90},
|
||||||
|
{High: 105, Low: 88},
|
||||||
|
}
|
||||||
|
|
||||||
|
upper, lower := ExportCalculateDonchian(klines, 10)
|
||||||
|
|
||||||
|
// Should use all available klines when period > len(klines)
|
||||||
|
if upper != 105 {
|
||||||
|
t.Errorf("Expected upper = 105, got %v", upper)
|
||||||
|
}
|
||||||
|
if lower != 88 {
|
||||||
|
t.Errorf("Expected lower = 88, got %v", lower)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user