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.
114 lines
3.6 KiB
114 lines
3.6 KiB
package sig |
|
|
|
import ( |
|
"fmt" |
|
"sig-pub/pkg/indicator" |
|
"sig-pub/pkg/strategy" |
|
"sig-pub/pkg/types" |
|
"sig-pub/pkg/types/series" |
|
) |
|
|
|
type StrategyContext struct { |
|
strategy.ISingleSigStrategyContext |
|
|
|
input types.Input |
|
kSeries *KlineSeries |
|
indicatorsReg *indicator.IndicatorRegistry |
|
indicatorContextStates IndicatorStates |
|
} |
|
|
|
func NewStrategyContext(input types.Input, kSeries *KlineSeries, indicatorsReg *indicator.IndicatorRegistry) *StrategyContext { |
|
return &StrategyContext{ |
|
input: input, |
|
kSeries: kSeries, |
|
indicatorsReg: indicatorsReg, |
|
indicatorContextStates: NewIndicatorStates(), |
|
} |
|
} |
|
|
|
// Input 获取输入参数 |
|
func (c *StrategyContext) Input() (in types.Input) { |
|
return c.input |
|
} |
|
|
|
func (c *StrategyContext) Get(offset int16) (kline types.Kline) { |
|
return c.kSeries.MustGet(offset) |
|
} |
|
|
|
func (c *StrategyContext) Series(offset, count int16) (klines series.Klines) { |
|
return c.kSeries.MustSeries(offset, count) |
|
} |
|
|
|
// 获取窗口类型指标 |
|
func (c *StrategyContext) Indicator(name string, args ...any) (s indicator.IIndicatorSeries) { |
|
indicator, ok := c.indicatorsReg.Indicator(name) |
|
if !ok { |
|
panic(fmt.Errorf("indicator %s not exists", name)) |
|
} |
|
input := matchIndicatorArgs(args...) |
|
indicatorContext := NewIndicatorContext(indicator, input, c.indicatorContextStates, c.kSeries, c.indicatorsReg) |
|
return NewWindowIndicatorSeries(indicator, indicatorContext) |
|
} |
|
|
|
// IntervalStrategyContext 周期策略上下文 |
|
type IntervalStrategyContext struct { |
|
strategy.IIntervalSigStrategyContext |
|
|
|
input types.Input |
|
intervalKlineSeries *types.IntervalState[*KlineSeries] |
|
indicatorsReg *indicator.IndicatorRegistry |
|
intervalIndicatorContextStates map[types.Interval]IndicatorStates |
|
} |
|
|
|
func NewIntervalStrategyContext(input types.Input, intervalKlineSeries *types.IntervalState[*KlineSeries], indicatorsReg *indicator.IndicatorRegistry) *IntervalStrategyContext { |
|
return &IntervalStrategyContext{ |
|
input: input, |
|
intervalKlineSeries: intervalKlineSeries, |
|
indicatorsReg: indicatorsReg, |
|
intervalIndicatorContextStates: make(map[types.Interval]IndicatorStates), |
|
} |
|
} |
|
|
|
// Input 获取输入参数 |
|
func (c *IntervalStrategyContext) Input() (in types.Input) { |
|
return c.input |
|
} |
|
|
|
func (c *IntervalStrategyContext) getCandleSeries(interval types.Interval) *KlineSeries { |
|
klineSeries := c.intervalKlineSeries.Get(interval) |
|
if klineSeries == nil { |
|
panic(fmt.Errorf("interval %s kline series is nil", interval)) |
|
} |
|
return klineSeries |
|
} |
|
|
|
// Get [0]当前k线 |
|
func (c *IntervalStrategyContext) Get(interval types.Interval, offset int16) (kline types.Kline) { |
|
ks := c.getCandleSeries(interval) |
|
return ks.MustGet(offset) |
|
} |
|
|
|
// Series [offset...end] |
|
func (c *IntervalStrategyContext) Series(interval types.Interval, offset, count int16) (klines series.Klines) { |
|
cs := c.getCandleSeries(interval) |
|
return cs.MustSeries(offset, count) |
|
} |
|
|
|
// 获取窗口类型指标 |
|
func (c *IntervalStrategyContext) Indicator(interval types.Interval, name string, args ...any) (series indicator.IIndicatorSeries) { |
|
indicator, ok := c.indicatorsReg.Indicator(name) |
|
if !ok { |
|
panic(fmt.Errorf("indicator %s not exists", name)) |
|
} |
|
|
|
input := matchIndicatorArgs(args...) |
|
kSeries := c.getCandleSeries(interval) |
|
// 状态传递 |
|
state, ok := c.intervalIndicatorContextStates[interval] |
|
if !ok { |
|
state = NewIndicatorStates() |
|
c.intervalIndicatorContextStates[interval] = state |
|
} |
|
indicatorContext := NewIndicatorContext(indicator, input, state, kSeries, c.indicatorsReg) |
|
return NewWindowIndicatorSeries(indicator, indicatorContext) |
|
}
|
|
|