indicator-buffer
Implement BufferList incremental indicators with efficient state management. Use for IIncrementFromChain or IIncrementFromQuote implementations. Covers interface selection, constructor patterns, and BufferListTestBase testing requirements.
When & Why to Use This Skill
This Claude skill provides a comprehensive framework for implementing BufferList incremental indicators with efficient state management. It streamlines the development process by guiding users through interface selection (IIncrementFromChain vs. IIncrementFromQuote), standardized constructor patterns, and rigorous testing protocols to ensure high-performance data processing and architectural consistency.
Use Cases
- Developing chainable single-value technical indicators such as SMA, EMA, or RSI using the IIncrementFromChain interface for optimized performance.
- Implementing complex indicators requiring full OHLCV (Open, High, Low, Close, Volume) data, such as Stochastic or ATR, via the IIncrementFromQuote interface.
- Refactoring legacy indicator code to utilize standardized rolling buffer management and efficient state reset patterns (Clear() method).
- Automating the creation of unit tests that inherit from BufferListTestBase to verify exact parity between incremental and series-based calculation results.
| name | indicator-buffer |
|---|---|
| description | Implement BufferList incremental indicators with efficient state management. Use for IIncrementFromChain or IIncrementFromQuote implementations. Covers interface selection, constructor patterns, and BufferListTestBase testing requirements. |
BufferList indicator development
Interface selection
All BufferList implementations support IQuote inputs from the base class. The interface determines what additional input types are supported:
| Interface | Additional Inputs | Use Case | Examples |
|---|---|---|---|
IIncrementFromChain |
IReusable, (DateTime, double) |
Chainable single-value indicators | SMA, EMA, RSI |
IIncrementFromQuote |
(none - only IQuote) | Requires OHLCV properties | Stoch, ATR, VWAP |
Constructor pattern
public class MyIndicatorList : BufferList<MyResult>, IIncrementFromChain
{
private readonly Queue<double> _buffer;
// Primary constructor (parameters only)
public MyIndicatorList(int lookbackPeriods)
{
ArgumentOutOfRangeException.ThrowIfLessThan(lookbackPeriods, 1);
LookbackPeriods = lookbackPeriods;
_buffer = new Queue<double>(lookbackPeriods);
}
// Chaining constructor (parameters + quotes)
public MyIndicatorList(int lookbackPeriods, IReadOnlyList<IQuote> quotes)
: this(lookbackPeriods) => Add(quotes);
}
Buffer management
Use extension methods from BufferListUtilities:
_buffer.Update(capacity, value)- Standard rolling buffer_buffer.UpdateWithDequeue(capacity, value)- Returns dequeued value for sum adjustment
Note: Future refactor planned to rename
BufferListUtilitiestoBufferListExtensionsfor .NET idiomatic naming.
State management
Use Clear() to reset all internal state:
public override void Clear()
{
base.Clear();
_buffer.Clear();
_bufferSum = 0;
}
Testing constraints
- Inherit
BufferListTestBase(NOTTestBase) - Implement test interface matching increment interface:
IIncrementFromChain→ITestChainBufferListIIncrementFromQuote→ITestQuoteBufferList
- Verify exact Series parity with
bufferResults.IsExactly(seriesResults)(NOTShould().Be()) - All 5 base class tests pass (incremental adds, batching, constructor chaining, Clear(), auto-pruning)
Required implementation
- Source code:
src/**/{IndicatorName}.BufferList.csfile exists- Inherits
BufferList<TResult>and implements correct increment interface - Two constructors: primary + chaining via
: this(...) => Add(quotes); - Uses
BufferListUtilities.Update()orUpdateWithDequeue() -
Clear()resets results and all internal buffers
- Inherits
- Unit testing:
tests/indicators/**/{IndicatorName}.BufferList.Tests.csexists- Inherits
BufferListTestBaseand implements correct test interface - All 5 required tests from base class pass
- Verifies equivalence with Series results
- Inherits
Anti-patterns to avoid
Manual buffer management (WRONG):
if (_buffer.Count == capacity) _buffer.Dequeue();
_buffer.Enqueue(value);
Use extension methods (CORRECT):
_buffer.Update(capacity, value);
Examples
- Chain:
src/e-k/Ema/Ema.BufferList.cs - Quote:
src/s-z/Stoch/Stoch.BufferList.cs - Complex:
src/a-d/Adx/Adx.BufferList.cs
See references/interface-selection.md for interface decision guidance.
Last updated: December 31, 2025