github.com/0xsequence/ethkit@v1.25.0/ethgas/ema.go (about) 1 package ethgas 2 3 import "math/big" 4 5 // NewEMA(decay) returns a new exponential moving average. It weighs new values more than 6 // existing values according to the decay. For example: NewEMA(0.05) would give 5% weight 7 // to the present and 95% weight to the past. Common to use 2/(selected time period+1). 8 func NewEMA(decay float64) *EMA { 9 return &EMA{decay: big.NewFloat(decay)} 10 } 11 12 // EMA is a moving average with exponential decay. It doesn't have any concept of weight 13 // so it will only work on homogenous (evenly spaced) time series. 14 // ema := NewEMA(0.1818) 15 // avg1 = ema.Tick(price1) 16 // avg2 = ema.Tick(price2) 17 // spike := checkPriceMovingAvg(price, avg, 20%) 18 type EMA struct { 19 decay *big.Float 20 value *big.Int 21 } 22 23 func (ema *EMA) Tick(price *big.Int) *big.Int { 24 if ema.value == nil { 25 ema.value = new(big.Int).Set(price) 26 } 27 current := new(big.Float).Mul(new(big.Float).SetInt(price), ema.decay) 28 past := new(big.Float).Mul( 29 new(big.Float).Sub(big.NewFloat(1), ema.decay), 30 new(big.Float).SetInt(ema.value), 31 ) 32 new(big.Float).Add(current, past).Int(ema.value) 33 return ema.Value() 34 } 35 36 func (ema *EMA) Value() *big.Int { 37 return new(big.Int).Set(ema.value) 38 }