Summary
Today users can create custom Series (batch) indicators with plain extension methods, but there is no first-class, documented way to create custom Buffer List indicators. This issue scopes the work to make user-defined buffer lists a supported extension point.
Milestone: v3.1. This is not part of current v3 release work — tracking for a future minor release.
Current state
BufferList<TResult> (src/_common/BufferLists/BufferList.cs:24) is a public abstract class : IReadOnlyList<TResult> where TResult : ISeries, with an implicit protected constructor and protected helpers AddInternal, UpdateInternal, and virtual PruneList; MaxListSize and Name are public. The base class is therefore technically subclassable from outside the assembly.
- Built-ins (e.g.
SmaList, src/s-z/Sma/Sma.BufferList.cs:6) follow a consistent pattern: a public constructor with validation, an internal rolling buffer (Queue<double>), Add(DateTime, double) / Add(IReusable) / Add(IReadOnlyList<IReusable>) overloads, and a ToXxxList(...) factory extension.
Gaps / blockers for an external custom buffer list
- The standard
Add contract interfaces are internal. IIncrementFromChain (src/_common/BufferLists/IIncrementFromChain.cs:10) and IIncrementFromQuote (src/_common/BufferLists/IIncrementFromQuote.cs:10) define the Add(...) overloads built-ins implement. External lists can't implement the same contract, and there is no public IBufferList/add-value interface for uniform handling.
- Rolling-buffer helpers are inaccessible.
BufferListUtilities (src/_common/BufferLists/BufferList.Utilities.cs:6) is internal (its Update/UpdateWithDequeue Queue extensions are public, but the containing class is not), so a custom list must reimplement the windowed-buffer logic.
- Calculation/validation helpers are internal (e.g.
Sma.Validate, and the internal Queue<double>.Average extension at src/s-z/Sma/Sma.Utilities.cs:81), so users cannot reuse them.
- No docs, example project, or tests exist for custom buffer lists.
Proposed work
- Publish a public add-contract surface (promote
IIncrementFromQuote/IIncrementFromChain to public, or introduce a public IBufferList/IAddValue interface) so custom lists integrate uniformly.
- Make
BufferListUtilities public (or expose the windowed-buffer helpers through a public surface).
- Decide which reusable calculation/validation helpers to expose vs. document as "bring your own."
- Add
docs/guide/custom-buffer-lists.md (mirroring the series customization guide): result class → subclass BufferList<TResult> → Add overloads → factory extension.
- Add a
CustomBufferListLibrary example project (+ usage) under docs/examples/.
- Add tests proving an external subclass works and matches the Series result for the same inputs (parity).
- Update
docs/guide/customization.md (relax/remove the "Series style only" note once shipped).
Acceptance criteria
A consumer in a separate assembly can implement a custom buffer-list indicator using only public API, following a documented pattern, with a working example and passing parity tests.
Summary
Today users can create custom Series (batch) indicators with plain extension methods, but there is no first-class, documented way to create custom Buffer List indicators. This issue scopes the work to make user-defined buffer lists a supported extension point.
Current state
BufferList<TResult>(src/_common/BufferLists/BufferList.cs:24) is apublic abstract class : IReadOnlyList<TResult> where TResult : ISeries, with an implicitprotectedconstructor andprotectedhelpersAddInternal,UpdateInternal, andvirtual PruneList;MaxListSizeandNameare public. The base class is therefore technically subclassable from outside the assembly.SmaList,src/s-z/Sma/Sma.BufferList.cs:6) follow a consistent pattern: a public constructor with validation, an internal rolling buffer (Queue<double>),Add(DateTime, double)/Add(IReusable)/Add(IReadOnlyList<IReusable>)overloads, and aToXxxList(...)factory extension.Gaps / blockers for an external custom buffer list
Addcontract interfaces areinternal.IIncrementFromChain(src/_common/BufferLists/IIncrementFromChain.cs:10) andIIncrementFromQuote(src/_common/BufferLists/IIncrementFromQuote.cs:10) define theAdd(...)overloads built-ins implement. External lists can't implement the same contract, and there is no publicIBufferList/add-value interface for uniform handling.BufferListUtilities(src/_common/BufferLists/BufferList.Utilities.cs:6) isinternal(itsUpdate/UpdateWithDequeueQueue extensions arepublic, but the containing class is not), so a custom list must reimplement the windowed-buffer logic.Sma.Validate, and the internalQueue<double>.Averageextension atsrc/s-z/Sma/Sma.Utilities.cs:81), so users cannot reuse them.Proposed work
IIncrementFromQuote/IIncrementFromChainto public, or introduce a publicIBufferList/IAddValueinterface) so custom lists integrate uniformly.BufferListUtilitiespublic (or expose the windowed-buffer helpers through a public surface).docs/guide/custom-buffer-lists.md(mirroring the series customization guide): result class → subclassBufferList<TResult>→Addoverloads → factory extension.CustomBufferListLibraryexample project (+ usage) underdocs/examples/.docs/guide/customization.md(relax/remove the "Series style only" note once shipped).Acceptance criteria
A consumer in a separate assembly can implement a custom buffer-list indicator using only public API, following a documented pattern, with a working example and passing parity tests.