1package gota
2
3// Trix - TRIple Exponential average (http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:trix)
4type TRIX struct {
5	ema1  EMA
6	ema2  EMA
7	ema3  EMA
8	last  float64
9	count int
10}
11
12// NewTRIX constructs a new TRIX.
13func NewTRIX(inTimePeriod int, warmType WarmupType) *TRIX {
14	ema1 := NewEMA(inTimePeriod, warmType)
15	ema2 := NewEMA(inTimePeriod, warmType)
16	ema3 := NewEMA(inTimePeriod, warmType)
17	return &TRIX{
18		ema1: *ema1,
19		ema2: *ema2,
20		ema3: *ema3,
21	}
22}
23
24// Add adds a new sample value to the algorithm and returns the computed value.
25func (trix *TRIX) Add(v float64) float64 {
26	cur := trix.ema1.Add(v)
27	if trix.ema1.Warmed() || trix.ema1.warmType == WarmEMA {
28		cur = trix.ema2.Add(cur)
29		if trix.ema2.Warmed() || trix.ema2.warmType == WarmEMA {
30			cur = trix.ema3.Add(cur)
31		}
32	}
33
34	rate := ((cur / trix.last) - 1) * 100
35	trix.last = cur
36	if !trix.Warmed() && trix.ema3.Warmed() {
37		trix.count++
38	}
39	return rate
40}
41
42// WarmCount returns the number of samples that must be provided for the algorithm to be fully "warmed".
43func (trix *TRIX) WarmCount() int {
44	if trix.ema1.warmType == WarmEMA {
45		return trix.ema1.WarmCount() + 1
46	}
47	return trix.ema1.WarmCount()*3 + 1
48}
49
50// Warmed indicates whether the algorithm has enough data to generate accurate results.
51func (trix *TRIX) Warmed() bool {
52	return trix.count == 2
53}
54