Description
Currently, all indicators in the library are tightly coupled to channels and stream-based processing. While channels are excellent for real-time streaming data, batch operations (such as running backtests over historical datasets loaded from CSVs) can incur scheduling, allocation, and context-switching overhead from spawning multiple goroutines and passing values through channels.
To improve performance for batch calculations and backtesting, we should introduce a way to compute indicators directly on slices with zero goroutines.
Proposed Changes
- Define a stateful calculation interface (e.g.,
Calculator or similar step-by-step interface) representing the state of an indicator:
type Calculator[T Number] interface {
Next(input T) (output T, ok bool)
}
- Implement this interface on existing indicator structs (like
Sma, Ema, etc.).
- Add a new
ComputeSlice(inputs []T) []T method to the indicators, which processes the inputs sequentially in a simple loop without channels.
- Keep the existing channel-based
Compute(<-chan T) <-chan T methods intact for backwards compatibility, but rewrite their internals to utilize the stateful calculator logic.
Description
Currently, all indicators in the library are tightly coupled to channels and stream-based processing. While channels are excellent for real-time streaming data, batch operations (such as running backtests over historical datasets loaded from CSVs) can incur scheduling, allocation, and context-switching overhead from spawning multiple goroutines and passing values through channels.
To improve performance for batch calculations and backtesting, we should introduce a way to compute indicators directly on slices with zero goroutines.
Proposed Changes
Calculatoror similar step-by-step interface) representing the state of an indicator:Sma,Ema, etc.).ComputeSlice(inputs []T) []Tmethod to the indicators, which processes the inputs sequentially in a simple loop without channels.Compute(<-chan T) <-chan Tmethods intact for backwards compatibility, but rewrite their internals to utilize the stateful calculator logic.