diff --git a/internal/trading/sig/indicator_context.go b/internal/trading/sig/indicator_context.go index 98a93c1..039048e 100644 --- a/internal/trading/sig/indicator_context.go +++ b/internal/trading/sig/indicator_context.go @@ -28,7 +28,7 @@ type IOffsetIndicatorContext interface { // IndicatorContext 指标上下文, 提供k线序列给指标计算使用 type IndicatorContext struct { IOffsetIndicatorContext - indicator indicator.IIndicator + indicator indicator.IIndicatorMetable indicatorKey string indicatorsReg *indicator.IndicatorRegistry input types.Input @@ -38,7 +38,7 @@ type IndicatorContext struct { indicatorTrace []string // 指标调用链避免指标循环引用 } -func NewIndicatorContext(indicator indicator.IIndicator, input types.Input, indicatorStates IndicatorStates, kSeries *types.KlineSeries, indicatorsReg *indicator.IndicatorRegistry) *IndicatorContext { +func NewIndicatorContext(indicator indicator.IIndicatorMetable, input types.Input, indicatorStates IndicatorStates, kSeries *types.KlineSeries, indicatorsReg *indicator.IndicatorRegistry) *IndicatorContext { // 指标参数默认值 FillDefaultInputs(input, indicator.Meta().Input) @@ -108,7 +108,9 @@ func (c *IndicatorContext) State() indicator.IIndicatorState { state = NewIndicatorState(c.kSeries.Interval) c.indicatorStates[c.indicatorKey] = state // 从头KlineSeries跑一遍, 针对ema,macd等回溯迭代指标, 将state与KlineSeries对齐 - c.backtrackIndicatorState(c.indicator) + if ind, ok := c.indicator.(indicator.IIndicator); ok { + c.backtrackIndicatorState(ind) + } } state.SetIndicatorContext(c) return state @@ -149,6 +151,16 @@ func (c *IndicatorContext) Indicator(name string, args ...any) (series indicator return NewWindowIndicatorSeries(indicator, indicatorContext) } +func (c *IndicatorContext) SummaryIndicator(name string, args ...any) (summary indicator.IIndicatorSummary) { + input := matchIndicatorArgs(args...) + + indicatorContext := NewIndicatorContext(nil, input, c.indicatorStates, c.kSeries, c.indicatorsReg) + indicatorContext.offset = c.offset + indicatorContext.indicatorTrace = append(c.indicatorTrace, name) + + return NewIndicatorSummary(nil, indicatorContext) +} + func matchIndicatorArgs(args ...any) (input types.Input) { inputLoop: for _, arg := range args { diff --git a/internal/trading/sig/indicator_series.go b/internal/trading/sig/indicator_series.go index 8d88c54..27a9135 100644 --- a/internal/trading/sig/indicator_series.go +++ b/internal/trading/sig/indicator_series.go @@ -50,6 +50,12 @@ func (s *WindowIndicatorSeries) Series(offset, count int16) (matrix series.Float return } +// Summary指标 计算完毕获取计算结果 +func (s *WindowIndicatorSeries) Summary(offset, count int16) (summary any, ok bool) { + // summary, ok = s.indicator.Summary(s.indicatorContext) + return +} + func (s *WindowIndicatorSeries) State(k string, offset int16) (state float64) { if collect.NotIn(k, s.indicator.Meta().State...) { panic(fmt.Errorf("indicator %s not export state %s", s.indicator.Meta().Name, k)) diff --git a/internal/trading/sig/indicator_summary.go b/internal/trading/sig/indicator_summary.go new file mode 100644 index 0000000..61d3ef7 --- /dev/null +++ b/internal/trading/sig/indicator_summary.go @@ -0,0 +1,21 @@ +package sig + +import "sig-pub/pkg/indicator" + +type IndicatorSummary struct { + indicator.IIndicatorSummary + indicatorContext IOffsetIndicatorContext + summaryIndicator indicator.ISummaryIndicator +} + +func NewIndicatorSummary(summaryIndicator indicator.ISummaryIndicator, indicatorContext IOffsetIndicatorContext) *IndicatorSummary { + return &IndicatorSummary{ + summaryIndicator: summaryIndicator, + indicatorContext: indicatorContext, + } +} + +func (s *IndicatorSummary) Summary(offset, count int16) (summary any, ok bool) { + + return +} diff --git a/pkg/indicator/indicator.go b/pkg/indicator/indicator.go index 792d959..74050b9 100644 --- a/pkg/indicator/indicator.go +++ b/pkg/indicator/indicator.go @@ -18,7 +18,12 @@ type IndicatorMeta struct { Plots []Plot `json:"plots"` // 指标绘图属性 } -// IIndicator 指标基础计算接口 +type IIndicatorMetable interface { + // Meta 指标元信息 + Meta() IndicatorMeta +} + +// IIndicator 指标基础计算接口(无状态计算单元) type IIndicator interface { // Meta 指标元信息 Meta() IndicatorMeta @@ -28,6 +33,18 @@ type IIndicator interface { Calculate(ctx IIndicatorContext) (vector float64) } +// ISummaryIndicator 累加型计算指标(有状态计算单元) +type ISummaryIndicator interface { + // Meta 指标元信息 + Meta() IndicatorMeta + // CandlePeriods 计算窗口大小的指标值需要的K线数量 + CandlePeriods(ctx IIndicatorContext) int16 + // Accumulate 计算并累加值 + Accumulate(ctx IIndicatorContext) + // Summary 计算完毕获取计算累加结果 + Summary(ctx IIndicatorContext) (summary any, ok bool) +} + // IIndicatorContext k线序列, trading服务提供 type IIndicatorContext interface { Get(offset int16) (kline types.Kline) @@ -50,6 +67,10 @@ type IIndicatorSeries interface { StateSeries(k string, offset, count int16) (matrix series.Floats) } +type IIndicatorSummary interface { + Summary(offset, count int16) (summary any, ok bool) +} + type IIndicatorState interface { // Set 存储指标当前状态 Set(k string, v float64) diff --git a/pkg/indicator/vrvp.go b/pkg/indicator/vrvp.go new file mode 100644 index 0000000..aae7387 --- /dev/null +++ b/pkg/indicator/vrvp.go @@ -0,0 +1,47 @@ +package indicator + +import "sig-pub/pkg/types" + +// VRVP 成交量分布图 +type VRVP struct { +} + +func (c *VRVP) Meta() IndicatorMeta { + return IndicatorMeta{ + Name: "VRVP", + Input: []types.InputArg{ + {Name: "window", Type: types.InputTypeUInt, Desc: "窗口大小", Default: 10}, + }, + State: []string{"sig"}, + Plots: []Plot{ + {Name: "RVI", State: "vector", Type: PlotLine, Props: PlotProps{"color": ColorGreen}}, + {Name: "Signal", State: "sig", Type: PlotLine, Props: PlotProps{"color": ColorRed}}, + }, + } +} + +func (s *VRVP) Init(input types.Input) (err error) { // 校验参数并初始化 + // s.rate = input.Float("rate") + // s.rate2 = input.Float("rate2") + return +} + +// Accumulate 计算累加值 +func (v *VRVP) Accumulate(ctx IIndicatorContext) { +} + +// Summary 计算完毕获取计算结果 +func (v *VRVP) Summary(ctx IIndicatorContext) (summary any, ok bool) { + + return +} + +type RVVPSummary struct { + TotalVolume float64 + Buckets []PriceBucket +} + +type PriceBucket struct { + Price float64 + Volume float64 +} diff --git a/pkg/strategy/bollgrid.go b/pkg/strategy/bollgrid.go index 0f8e037..0b78bd1 100644 --- a/pkg/strategy/bollgrid.go +++ b/pkg/strategy/bollgrid.go @@ -46,6 +46,15 @@ func (s *BollGrid) CandlePeriods(ctx ISingleSigStrategyContext) int16 { } func (s *BollGrid) Update(ctx ISingleSigStrategyContext) (side types.Side) { + // ind := ctx.Indicator("abc", "", "") + // ind.Summary() + // var ind indicator.IIndicatorSummary + // r, ok := ind.Summary(0, 100) // 100根k线的成交量分布图 + // if !ok { + // return types.SideNone + // } + // _ = r + // 获取指标数据 // BOLL指标 Calculate 返回值为 mb (中轨) bollInd := ctx.Indicator("BOLL", s.period)