94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
package indicators
|
|
|
|
// MACDResult contient MACD line, signal line et histogramme.
|
|
type MACDResult struct {
|
|
MACD float64
|
|
Signal float64
|
|
Histogram float64
|
|
}
|
|
|
|
// MACD calcule le Moving Average Convergence Divergence (12/26/9 standard).
|
|
// Retourne zéro-value si pas assez de données.
|
|
func MACD(closes []float64) MACDResult {
|
|
return MACDCustom(closes, 12, 26, 9)
|
|
}
|
|
|
|
func MACDCustom(closes []float64, fast, slow, signal int) MACDResult {
|
|
if len(closes) < slow+signal {
|
|
return MACDResult{}
|
|
}
|
|
|
|
emaFast := emaSlice(closes, fast)
|
|
emaSlow := emaSlice(closes, slow)
|
|
|
|
// Aligner les deux séries (emaSlow est plus courte)
|
|
offset := len(emaFast) - len(emaSlow)
|
|
macdLine := make([]float64, len(emaSlow))
|
|
for i := range emaSlow {
|
|
macdLine[i] = emaFast[offset+i] - emaSlow[i]
|
|
}
|
|
|
|
if len(macdLine) < signal {
|
|
return MACDResult{}
|
|
}
|
|
|
|
signalLine := emaSlice(macdLine, signal)
|
|
last := macdLine[len(macdLine)-1]
|
|
sig := signalLine[len(signalLine)-1]
|
|
|
|
return MACDResult{
|
|
MACD: last,
|
|
Signal: sig,
|
|
Histogram: last - sig,
|
|
}
|
|
}
|
|
|
|
// SMA calcule la moyenne mobile simple sur les n dernières valeurs.
|
|
func SMA(closes []float64, period int) float64 {
|
|
if len(closes) < period {
|
|
return 0
|
|
}
|
|
slice := closes[len(closes)-period:]
|
|
sum := 0.0
|
|
for _, v := range slice {
|
|
sum += v
|
|
}
|
|
return sum / float64(period)
|
|
}
|
|
|
|
// AvgVolume calcule le volume moyen sur les n dernières barres.
|
|
func AvgVolume(volumes []int64, period int) int64 {
|
|
if len(volumes) < period {
|
|
period = len(volumes)
|
|
}
|
|
if period == 0 {
|
|
return 0
|
|
}
|
|
slice := volumes[len(volumes)-period:]
|
|
var sum int64
|
|
for _, v := range slice {
|
|
sum += v
|
|
}
|
|
return sum / int64(period)
|
|
}
|
|
|
|
func emaSlice(data []float64, period int) []float64 {
|
|
if len(data) < period {
|
|
return nil
|
|
}
|
|
k := 2.0 / float64(period+1)
|
|
|
|
// Première valeur = SMA des `period` premières
|
|
sum := 0.0
|
|
for i := 0; i < period; i++ {
|
|
sum += data[i]
|
|
}
|
|
ema := make([]float64, 0, len(data)-period+1)
|
|
ema = append(ema, sum/float64(period))
|
|
|
|
for i := period; i < len(data); i++ {
|
|
ema = append(ema, data[i]*k+ema[len(ema)-1]*(1-k))
|
|
}
|
|
return ema
|
|
}
|