added
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user