-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathwma.go
70 lines (58 loc) · 1.55 KB
/
wma.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
package tart
// A Weighted Moving Average puts more weight on recent data and less on past
// data. This is done by multiplying each bar’s price by a weighting factor.
// Because of its unique calculation, WMA will follow prices more closely
// than a corresponding Simple Moving Average.
// https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/wma
type Wma struct {
n int64
d float64
hist *CBuf
sum float64
wsum float64
}
func NewWma(n int64) *Wma {
return &Wma{
n: n,
d: float64(n*(n+1)) / 2,
hist: NewCBuf(n),
sum: 0,
wsum: 0,
}
}
func (w *Wma) Update(v float64) float64 {
if w.n == 1 {
return v
}
old := w.hist.Append(v)
w.sum += v - old
sz := w.hist.Size()
if sz < w.n {
w.wsum += v * float64(sz)
return 0
} else {
w.wsum += v * float64(w.n)
}
ret := w.wsum / w.d
w.wsum -= w.sum
return ret
}
func (w *Wma) InitPeriod() int64 {
return w.n - 1
}
func (w *Wma) Valid() bool {
return w.hist.Size() > w.InitPeriod()
}
// A Weighted Moving Average puts more weight on recent data and less on past
// data. This is done by multiplying each bar’s price by a weighting factor.
// Because of its unique calculation, WMA will follow prices more closely
// than a corresponding Simple Moving Average.
// https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/wma
func WmaArr(in []float64, n int64) []float64 {
out := make([]float64, len(in))
w := NewWma(n)
for i, v := range in {
out[i] = w.Update(v)
}
return out
}