forked from sdcoffey/techan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
indicator_trend.go
72 lines (53 loc) · 1.39 KB
/
indicator_trend.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package techan
import "github.com/sdcoffey/big"
type trendLineIndicator struct {
indicator Indicator
window int
}
// NewTrendlineIndicator returns an indicator whose output is the slope of the trend
// line given by the values in the window.
func NewTrendlineIndicator(indicator Indicator, window int) Indicator {
return trendLineIndicator{
indicator: indicator,
window: window,
}
}
func (tli trendLineIndicator) Calculate(index int) big.Decimal {
window := Min(index+1, tli.window)
values := make([]big.Decimal, window)
for i := 0; i < window; i++ {
values[i] = tli.indicator.Calculate(index - (window - 1) + i)
}
n := big.ONE.Mul(big.NewDecimal(float64(window)))
ab := sumXy(values).Mul(n).Sub(sumX(values).Mul(sumY(values)))
cd := sumX2(values).Mul(n).Sub(sumX(values).Pow(2))
return ab.Div(cd)
}
func sumX(decimals []big.Decimal) (s big.Decimal) {
s = big.ZERO
for i := range decimals {
s = s.Add(big.NewDecimal(float64(i)))
}
return s
}
func sumY(decimals []big.Decimal) (b big.Decimal) {
b = big.ZERO
for _, d := range decimals {
b = b.Add(d)
}
return
}
func sumXy(decimals []big.Decimal) (b big.Decimal) {
b = big.ZERO
for i, d := range decimals {
b = b.Add(d.Mul(big.NewDecimal(float64(i))))
}
return
}
func sumX2(decimals []big.Decimal) big.Decimal {
b := big.ZERO
for i := range decimals {
b = b.Add(big.NewDecimal(float64(i)).Pow(2))
}
return b
}