diff --git a/trend/README.md b/trend/README.md
index 8667c3e..b2b797e 100644
--- a/trend/README.md
+++ b/trend/README.md
@@ -25,8 +25,6 @@ The information provided on this project is strictly for informational purposes
## Index
- [Constants](<#constants>)
-- [func MovingMax\[T helper.Number\]\(c \<\-chan T, period int\) \<\-chan T](<#MovingMax>)
-- [func MovingMin\[T helper.Number\]\(c \<\-chan T, period int\) \<\-chan T](<#MovingMin>)
- [type Apo](<#Apo>)
- [func NewApo\[T helper.Number\]\(\) \*Apo\[T\]](<#NewApo>)
- [func \(apo \*Apo\[T\]\) Compute\(c \<\-chan T\) \<\-chan T](<#Apo[T].Compute>)
@@ -51,6 +49,12 @@ The information provided on this project is strictly for informational purposes
- [func NewMassIndex\[T helper.Number\]\(\) \*MassIndex\[T\]](<#NewMassIndex>)
- [func \(m \*MassIndex\[T\]\) Compute\(highs, lows \<\-chan T\) \<\-chan T](<#MassIndex[T].Compute>)
- [func \(m \*MassIndex\[T\]\) IdlePeriod\(\) int](<#MassIndex[T].IdlePeriod>)
+- [type MovingMax](<#MovingMax>)
+ - [func NewMovingMax\[T helper.Number\]\(\) \*MovingMax\[T\]](<#NewMovingMax>)
+ - [func \(m \*MovingMax\[T\]\) Compute\(c \<\-chan T\) \<\-chan T](<#MovingMax[T].Compute>)
+- [type MovingMin](<#MovingMin>)
+ - [func NewMovingMin\[T helper.Number\]\(\) \*MovingMin\[T\]](<#NewMovingMin>)
+ - [func \(m \*MovingMin\[T\]\) Compute\(c \<\-chan T\) \<\-chan T](<#MovingMin[T].Compute>)
- [type MovingSum](<#MovingSum>)
- [func NewMovingSum\[T helper.Number\]\(\) \*MovingSum\[T\]](<#NewMovingSum>)
- [func \(m \*MovingSum\[T\]\) Compute\(c \<\-chan T\) \<\-chan T](<#MovingSum[T].Compute>)
@@ -139,40 +143,6 @@ const (
)
```
-
-## func [MovingMax]()
-
-```go
-func MovingMax[T helper.Number](c <-chan T, period int) <-chan T
-```
-
-MovingMax function takes a channel of numbers and computes the moving maximum over the specified period.
-
-Example:
-
-```
-input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
-actual := trend.MovingMax(input, 4)
-fmt.Println(helper.ChanToSlice(actual)) // [20, 20, 5, 8, 10, 10, 10]
-```
-
-
-## func [MovingMin]()
-
-```go
-func MovingMin[T helper.Number](c <-chan T, period int) <-chan T
-```
-
-MovingMin function takes a channel of numbers and computes the moving minimum over the specified period.
-
-Example:
-
-```
-input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
-actual := trend.MovingMin(input, 4)
-fmt.Println(helper.ChanToSlice(actual)) // [-10, -5, -5, -5, 1, -20, -20]
-```
-
## type [Apo]()
@@ -500,6 +470,70 @@ func (m *MassIndex[T]) IdlePeriod() int
IdlePeriod is the initial period that Mass Index won't yield any results.
+
+## type [MovingMax]()
+
+MovingMax represents the configuration parameters for calculating the Moving Max over the specified period.
+
+Example:
+
+```go
+type MovingMax[T helper.Number] struct {
+ // Time period.
+ Period int
+}
+```
+
+
+### func [NewMovingMax]()
+
+```go
+func NewMovingMax[T helper.Number]() *MovingMax[T]
+```
+
+NewMovingMax function initializes a new Moving Max instance with the default parameters.
+
+
+### func \(\*MovingMax\[T\]\) [Compute]()
+
+```go
+func (m *MovingMax[T]) Compute(c <-chan T) <-chan T
+```
+
+Compute function takes a channel of numbers and computes the Moving Max over the specified period.
+
+
+## type [MovingMin]()
+
+MovingMin represents the configuration parameters for calculating the Moving Min over the specified period.
+
+Example:
+
+```go
+type MovingMin[T helper.Number] struct {
+ // Time period.
+ Period int
+}
+```
+
+
+### func [NewMovingMin]()
+
+```go
+func NewMovingMin[T helper.Number]() *MovingMin[T]
+```
+
+NewMovingMin function initializes a new Moving Min instance with the default parameters.
+
+
+### func \(\*MovingMin\[T\]\) [Compute]()
+
+```go
+func (m *MovingMin[T]) Compute(c <-chan T) <-chan T
+```
+
+Compute function takes a channel of numbers and computes the Moving Min over the specified period.
+
## type [MovingSum]()
diff --git a/trend/aroon.go b/trend/aroon.go
index 72c9c9d..803be06 100644
--- a/trend/aroon.go
+++ b/trend/aroon.go
@@ -43,8 +43,14 @@ func NewAroon[T helper.Number]() *Aroon[T] {
// Compute function takes a channel of numbers and computes the Aroon
// over the specified period.
func (a *Aroon[T]) Compute(high, low <-chan T) (<-chan T, <-chan T) {
- sinceLastHigh := helper.Since(MovingMax(high, a.Period))
- sinceLastLow := helper.Since(MovingMin(low, a.Period))
+ max := NewMovingMax[T]()
+ max.Period = a.Period
+
+ min := NewMovingMin[T]()
+ min.Period = a.Period
+
+ sinceLastHigh := helper.Since(max.Compute(high))
+ sinceLastLow := helper.Since(min.Compute(low))
// Aroon Up = ((25 - Period Since Last 25 Period High) / 25) * 100
aroonUp := helper.MultiplyBy(sinceLastHigh, -1)
diff --git a/trend/moving_max.go b/trend/moving_max.go
index 1687b5d..b3d6cb2 100644
--- a/trend/moving_max.go
+++ b/trend/moving_max.go
@@ -6,17 +6,26 @@ package trend
import "github.com/cinar/indicator/helper"
-// MovingMax function takes a channel of numbers and computes the
-// moving maximum over the specified period.
+// MovingMax represents the configuration parameters for calculating the
+// Moving Max over the specified period.
//
// Example:
-//
-// input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
-// actual := trend.MovingMax(input, 4)
-// fmt.Println(helper.ChanToSlice(actual)) // [20, 20, 5, 8, 10, 10, 10]
-func MovingMax[T helper.Number](c <-chan T, period int) <-chan T {
+type MovingMax[T helper.Number] struct {
+ // Time period.
+ Period int
+}
+
+// NewMovingMax function initializes a new Moving Max instance
+// with the default parameters.
+func NewMovingMax[T helper.Number]() *MovingMax[T] {
+ return &MovingMax[T]{}
+}
+
+// Compute function takes a channel of numbers and computes the
+// Moving Max over the specified period.
+func (m *MovingMax[T]) Compute(c <-chan T) <-chan T {
cs := helper.Duplicate(c, 2)
- cs[1] = helper.Shift(cs[1], period, 0)
+ cs[1] = helper.Shift(cs[1], m.Period, 0)
bst := helper.NewBst[T]()
@@ -26,5 +35,5 @@ func MovingMax[T helper.Number](c <-chan T, period int) <-chan T {
return bst.Max()
})
- return helper.Skip(maxs, period-1)
+ return helper.Skip(maxs, m.Period-1)
}
diff --git a/trend/moving_max_test.go b/trend/moving_max_test.go
index 8849fbb..4f0da67 100644
--- a/trend/moving_max_test.go
+++ b/trend/moving_max_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "reflect"
"testing"
"github.com/cinar/indicator/helper"
@@ -13,12 +12,16 @@ import (
)
func TestMovingMax(t *testing.T) {
- input := []int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4}
- expected := []int{20, 20, 5, 8, 10, 10, 10}
+ input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
+ expected := helper.SliceToChan([]int{20, 20, 5, 8, 10, 10, 10})
- actual := helper.ChanToSlice(trend.MovingMax(helper.SliceToChan(input), 4))
+ max := trend.NewMovingMax[int]()
+ max.Period = 4
- if !reflect.DeepEqual(actual, expected) {
- t.Fatalf("actual %v expected %v", actual, expected)
+ actual := max.Compute(input)
+
+ err := helper.CheckEquals(actual, expected)
+ if err != nil {
+ t.Fatal(err)
}
}
diff --git a/trend/moving_min.go b/trend/moving_min.go
index 18c03fa..9bb5ed6 100644
--- a/trend/moving_min.go
+++ b/trend/moving_min.go
@@ -6,17 +6,26 @@ package trend
import "github.com/cinar/indicator/helper"
-// MovingMin function takes a channel of numbers and computes the
-// moving minimum over the specified period.
+// MovingMin represents the configuration parameters for calculating the
+// Moving Min over the specified period.
//
// Example:
-//
-// input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
-// actual := trend.MovingMin(input, 4)
-// fmt.Println(helper.ChanToSlice(actual)) // [-10, -5, -5, -5, 1, -20, -20]
-func MovingMin[T helper.Number](c <-chan T, period int) <-chan T {
+type MovingMin[T helper.Number] struct {
+ // Time period.
+ Period int
+}
+
+// NewMovingMin function initializes a new Moving Min instance
+// with the default parameters.
+func NewMovingMin[T helper.Number]() *MovingMin[T] {
+ return &MovingMin[T]{}
+}
+
+// Compute function takes a channel of numbers and computes the
+// Moving Min over the specified period.
+func (m *MovingMin[T]) Compute(c <-chan T) <-chan T {
cs := helper.Duplicate(c, 2)
- cs[1] = helper.Shift(cs[1], period, 0)
+ cs[1] = helper.Shift(cs[1], m.Period, 0)
bst := helper.NewBst[T]()
@@ -26,5 +35,5 @@ func MovingMin[T helper.Number](c <-chan T, period int) <-chan T {
return bst.Min()
})
- return helper.Skip(mins, period-1)
+ return helper.Skip(mins, m.Period-1)
}
diff --git a/trend/moving_min_test.go b/trend/moving_min_test.go
index 8af669f..df25d6a 100644
--- a/trend/moving_min_test.go
+++ b/trend/moving_min_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "reflect"
"testing"
"github.com/cinar/indicator/helper"
@@ -13,12 +12,16 @@ import (
)
func TestMovingMin(t *testing.T) {
- input := []int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4}
- expected := []int{-10, -5, -5, -5, 1, -20, -20}
+ input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
+ expected := helper.SliceToChan([]int{-10, -5, -5, -5, 1, -20, -20})
- actual := helper.ChanToSlice(trend.MovingMin(helper.SliceToChan(input), 4))
+ min := trend.NewMovingMin[int]()
+ min.Period = 4
- if !reflect.DeepEqual(actual, expected) {
- t.Fatalf("actual %v expected %v", actual, expected)
+ actual := min.Compute(input)
+
+ err := helper.CheckEquals(actual, expected)
+ if err != nil {
+ t.Fatal(err)
}
}