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  }