package indicator import ( "sig-pub/pkg/types" ) // MACD 拆分成: MACD线, MacdDEA(信号线), MacdHist(柱状图) // 计算 MACD 线 (DIF): 反映短期趋势与长期趋势的“收敛/散度” // MACD: https://www.investopedia.com/terms/m/macd.asp type MACD struct { } // indicator interface func (c *MACD) Meta() IndicatorMeta { return IndicatorMeta{ Name: "macd", Input: []types.InputArg{ {Name: "fast", Type: types.InputTypeUInt, Desc: "快线周期"}, {Name: "slow", Type: types.InputTypeUInt, Desc: "慢线周期"}, }, } } func (c *MACD) CandlePeriods(ctx IIndicatorContext) int16 { return max( ctx.Indicator("ema", ctx.Input().Int16("fast")).CandlePeriods(), ctx.Indicator("ema", ctx.Input().Int16("slow")).CandlePeriods(), ) } // Calculate 计算单根k线sma指标 func (c *MACD) Calculate(ctx IIndicatorContext) (vector float64) { fast := ctx.Input().Int16("fast") // 12 slow := ctx.Input().Int16("slow") // 26 // macd计算从第max(fast, slow)期开始稳定 fastEma := ctx.Indicator("ema", fast).Get(0) slowEma := ctx.Indicator("ema", slow).Get(0) macd := fastEma - slowEma vector = macd return } // MacdDEA macd信号线计算 type MacdDEA struct { } func (c *MacdDEA) Meta() IndicatorMeta { return IndicatorMeta{ Name: "macd_dea", Input: []types.InputArg{ {Name: "fast", Type: types.InputTypeUInt, Desc: "快线周期"}, {Name: "slow", Type: types.InputTypeUInt, Desc: "慢线周期"}, {Name: "singal", Type: types.InputTypeUInt, Desc: "信号线周期"}, }, } } func (c *MacdDEA) CandlePeriods(ctx IIndicatorContext) int16 { return max( ctx.Input().Int16("singal")+1, ctx.Indicator("macd", ctx.Input()).CandlePeriods(), ) } func (c *MacdDEA) Calculate(ctx IIndicatorContext) (vector float64) { singal := ctx.Input().Int16("singal") // 9 deaPrev, ok := ctx.State().Get("macd_dea", 1) if !ok { // 初始值前9期的 MACD SMA macdPrevs := ctx.Indicator("macd", ctx.Input()).Series(1, singal) deaPrev = macdPrevs.Avg() } macd := ctx.Indicator("macd", ctx.Input()).Get(0) // 计算DEA beta := 2 / float64(singal+1) dea := beta*macd + (1-beta)*deaPrev ctx.State().Set("macd_dea", dea) vector = dea return } // MacdSingal macd柱状图计算 type MacdHist struct { } func (c *MacdHist) Meta() IndicatorMeta { return IndicatorMeta{ Name: "macd_hist", Input: []types.InputArg{ {Name: "fast", Type: types.InputTypeUInt, Desc: "快线周期"}, {Name: "slow", Type: types.InputTypeUInt, Desc: "慢线周期"}, {Name: "singal", Type: types.InputTypeUInt, Desc: "信号线周期"}, }, } } func (c *MacdHist) CandlePeriods(ctx IIndicatorContext) int16 { return max( ctx.Indicator("macd", ctx.Input()).CandlePeriods(), ctx.Indicator("macd_dea", ctx.Input()).CandlePeriods(), ) } func (c *MacdHist) Calculate(ctx IIndicatorContext) (vector float64) { macd := ctx.Indicator("macd", ctx.Input()).Get(0) macd_dea := ctx.Indicator("macd_dea", ctx.Input()).Get(0) vector = macd - macd_dea return }