You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
43 lines
1005 B
43 lines
1005 B
package indicator |
|
|
|
import ( |
|
"sig-pub/pkg/types" |
|
) |
|
|
|
// EMA stateful indicator |
|
type EMA struct { |
|
} |
|
|
|
func (c *EMA) Meta() IndicatorMeta { |
|
return IndicatorMeta{ |
|
Name: "EMA", |
|
Input: []types.InputArg{ |
|
{Name: "window", Type: types.InputTypeUInt, Desc: "窗口大小"}, |
|
{Name: "pt", Type: types.InputTypePriceType, Desc: "k线序列类型"}, |
|
}, |
|
} |
|
} |
|
|
|
func (c *EMA) CandlePeriods(ctx IIndicatorContext) int16 { |
|
return ctx.Input().Int16("window") + 1 |
|
} |
|
|
|
// Calculate 计算单根k线sma指标 |
|
func (c *EMA) Calculate(ctx IIndicatorContext) (vector float64) { |
|
window := ctx.Input().Int16("window") |
|
pt := ctx.Input().PriceType() |
|
|
|
prevEma, ok := ctx.State().Get("_vector", 1) |
|
if !ok { |
|
// 初始值用 sma 替代 |
|
prevEma = ctx.Series(1, window).Price(pt).Avg() |
|
} |
|
|
|
multiplier := 2.0 / float64(window+1) |
|
price := ctx.Get(0).Price(pt) |
|
vector = multiplier*price + (1-multiplier)*prevEma |
|
// same: vector = ((close - prevEma) * multiplier) + prevEma |
|
|
|
ctx.State().Set("_vector", vector) |
|
return |
|
}
|
|
|