Skip to content

Commit

Permalink
Min and Max conveted to structs.
Browse files Browse the repository at this point in the history
  • Loading branch information
cinar committed Dec 28, 2023
1 parent 4ec674b commit 208ecd1
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 68 deletions.
106 changes: 70 additions & 36 deletions trend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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>)
Expand All @@ -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>)
Expand Down Expand Up @@ -139,40 +143,6 @@ const (
)
```

<a name="MovingMax"></a>
## func [MovingMax](<https://github.com/cinar/indicator/blob/v2/trend/moving_max.go#L17>)

```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]
```

<a name="MovingMin"></a>
## func [MovingMin](<https://github.com/cinar/indicator/blob/v2/trend/moving_min.go#L17>)

```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]
```

<a name="Apo"></a>
## type [Apo](<https://github.com/cinar/indicator/blob/v2/trend/apo.go#L41-L53>)

Expand Down Expand Up @@ -500,6 +470,70 @@ func (m *MassIndex[T]) IdlePeriod() int

IdlePeriod is the initial period that Mass Index won't yield any results.

<a name="MovingMax"></a>
## type [MovingMax](<https://github.com/cinar/indicator/blob/v2/trend/moving_max.go#L13-L16>)

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

<a name="NewMovingMax"></a>
### func [NewMovingMax](<https://github.com/cinar/indicator/blob/v2/trend/moving_max.go#L20>)

```go
func NewMovingMax[T helper.Number]() *MovingMax[T]
```

NewMovingMax function initializes a new Moving Max instance with the default parameters.

<a name="MovingMax[T].Compute"></a>
### func \(\*MovingMax\[T\]\) [Compute](<https://github.com/cinar/indicator/blob/v2/trend/moving_max.go#L26>)

```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.

<a name="MovingMin"></a>
## type [MovingMin](<https://github.com/cinar/indicator/blob/v2/trend/moving_min.go#L13-L16>)

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

<a name="NewMovingMin"></a>
### func [NewMovingMin](<https://github.com/cinar/indicator/blob/v2/trend/moving_min.go#L20>)

```go
func NewMovingMin[T helper.Number]() *MovingMin[T]
```

NewMovingMin function initializes a new Moving Min instance with the default parameters.

<a name="MovingMin[T].Compute"></a>
### func \(\*MovingMin\[T\]\) [Compute](<https://github.com/cinar/indicator/blob/v2/trend/moving_min.go#L26>)

```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.

<a name="MovingSum"></a>
## type [MovingSum](<https://github.com/cinar/indicator/blob/v2/trend/moving_sum.go#L13-L16>)

Expand Down
10 changes: 8 additions & 2 deletions trend/aroon.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
27 changes: 18 additions & 9 deletions trend/moving_max.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]()

Expand All @@ -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)
}
15 changes: 9 additions & 6 deletions trend/moving_max_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,23 @@
package trend_test

import (
"reflect"
"testing"

"github.com/cinar/indicator/helper"
"github.com/cinar/indicator/trend"
)

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)
}
}
27 changes: 18 additions & 9 deletions trend/moving_min.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]()

Expand All @@ -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)
}
15 changes: 9 additions & 6 deletions trend/moving_min_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,23 @@
package trend_test

import (
"reflect"
"testing"

"github.com/cinar/indicator/helper"
"github.com/cinar/indicator/trend"
)

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

0 comments on commit 208ecd1

Please sign in to comment.