-
Notifications
You must be signed in to change notification settings - Fork 0
/
superTrend.go
130 lines (112 loc) · 2.59 KB
/
superTrend.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package shingo
import (
"math"
"github.com/pkg/errors"
)
// AppendSuperTrend generates super trend delta for candlestick
func (cs *Candlesticks) AppendSuperTrend(arg IndicatorInputArg) error {
limit := arg.Limit
period := arg.Period
multi := arg.Multiplier
cs.mux.Lock()
defer cs.mux.Unlock()
total := cs.Total()
if period < 1 {
return errors.New("expected period to be positive")
}
if multi <= 0.0 {
return errors.New("multiplier must be greater than zero")
}
if total < 1 {
return nil
}
if limit < 1 {
limit = total
}
if err := cs.AppendATR(arg); err != nil {
return errors.New("error appending ATR for super trend")
}
startIdx := total - 1 - limit - period
if startIdx < 0 {
startIdx = 0
}
var count int
for i := startIdx; i < total; i++ {
count++
if count < period {
continue
}
p := cs.ItemAtIndex(i - 1)
pst := p.GetSuperTrend(period, multi)
v := cs.ItemAtIndex(i)
atr := v.GetATR(arg.Period)
if atr == nil {
continue
}
nshortb := (v.High+v.Low)/2.0 + atr.Value*multi
nlongb := (v.High+v.Low)/2.0 - atr.Value*multi
var long float64
var short float64
var trend Trend
if pst != nil {
if p.Close > pst.Longband {
long = math.Max(nlongb, pst.Longband)
} else {
long = nlongb
}
if p.Close < pst.Shortband {
short = math.Min(nshortb, pst.Shortband)
} else {
short = nshortb
}
if v.Close > pst.Shortband {
trend = Bull
} else if v.Close < pst.Longband {
trend = Bear
} else {
trend = pst.Trend
}
} else {
long = nlongb
short = nshortb
trend = Undeterminable
}
v.setSuperTrend(period, multi, short, long, trend)
}
return nil
}
// GetSuperTrend gets super trend value for this candlestick, given period and multiplier
func (c *Candlestick) GetSuperTrend(period int, multi float64) *SuperTrendDelta {
if c == nil {
return nil
}
if c.Indicators == nil {
return nil
}
if c.Indicators.SuperTrends == nil {
return nil
}
if c.Indicators.SuperTrends[period] == nil {
return nil
}
return c.Indicators.SuperTrends[period][multi]
}
func (c *Candlestick) setSuperTrend(period int, multi float64, short float64, long float64, trend Trend) {
if c == nil {
return
}
if c.Indicators == nil {
c.Indicators = &Indicators{}
}
if c.Indicators.SuperTrends == nil {
c.Indicators.SuperTrends = make(map[int]map[float64]*SuperTrendDelta)
}
if c.Indicators.SuperTrends[period] == nil {
c.Indicators.SuperTrends[period] = make(map[float64]*SuperTrendDelta)
}
c.Indicators.SuperTrends[period][multi] = &SuperTrendDelta{
Shortband: short,
Longband: long,
Trend: trend,
}
}