package indicator import ( "math" "sig-pub/pkg/types" ) // Boll 布林带 type Boll struct { } func (c *Boll) Meta() IndicatorMeta { return IndicatorMeta{ Name: "Boll", Input: []types.InputArg{ {Name: "window", Type: types.InputTypeUInt, Desc: "窗口大小"}, {Name: "pt", Type: types.InputTypeKPriceType, Desc: "k线序列类型"}, }, State: []string{"ub", "lb"}, Plots: []Plot{ {Name: "中轨", State: "vector", Type: PlotHistogram, Props: PlotProps{"color": ColorOrange}}, {Name: "上轨", State: "ub", Type: PlotLine, Props: PlotProps{"color": ColorRed2}}, {Name: "下轨", State: "lb", Type: PlotLine, Props: PlotProps{"color": ColorRed2}}, {Name: "布林带阴影", State: "ub,lb", Type: PlotShadow, Props: PlotProps{"color": "rgba(247, 169, 167, 0.3)"}}, }, } } func (c *Boll) CandlePeriods(ctx IIndicatorContext) int16 { return ctx.Input().Int16("window") } func (c *Boll) Calculate(ctx IIndicatorContext) (vector float64) { window := ctx.Input().Int16("window") pt := ctx.Input().PriceType() priceSeries := ctx.Series(0, int16(window)).Price(pt) mb := priceSeries.Avg() // 中轨 vector = mb // 标准差σ_t = sqrt(∑(P-MB)^2 / (n-1)) sst := float64(0) for _, p := range priceSeries { sst += math.Pow(p-mb, 2) } sigma := math.Sqrt(sst / float64(window-1)) // BollUB 布林带上轨 ub := mb + 2*sigma ctx.State().Set("ub", ub) // BollLB 布林带下轨 lb := mb - 2*sigma ctx.State().Set("lb", lb) return }