> **To all AI Agents:** This file defines the laws, physics, and protocols of the QuanTAlib repository. Read this before writing a single line of code. Failure to adhere to these standards will result in rejected code.
## 1. Identity & Mission
**QuanTAlib** is a high-performance, zero-allocation C# library for quantitative technical analysis.
* **Target**: Quantower and custom C# trading engines.
* **Core Philosophy**: Speed, Correctness, and Memory Efficiency.
* **Key Constraint**: Hot paths must be allocation-free (GC pressure is the enemy).
## 2. Architecture & "Physics"
### Memory Model: Structure of Arrays (SoA)
We do not store objects in lists. We store primitive arrays.
* **Source Material:** The algorithm and markdown documentation foundation should be sourced from [https://github.com/mihakralj/pinescript/blob/main/indicators/](PineScript).
* **Zero Allocation:** The core calculation loop must not allocate memory on the heap. Use `stackalloc`, `Span<T>`, and pinned memory where possible.
* **O(1) Complexity:** Streaming updates must be O(1) whenever mathematically possible. Use running sums/products or circular buffers to avoid re-iterating over history.
* **Dual API:** Provide both a stateful object-oriented API (`Update`) and a stateless static vector API (`Calculate`).
* **Bar Correction:** Support intra-bar updates via the `isNew` parameter. The indicator must be able to rollback the last update and apply a new value for the same timestamp.
* **Robustness:** Handle `NaN` and `Infinity` gracefully using last-valid-value substitution. Never propagate invalid values.
* **Reactive:** Implement `ITValuePublisher` to support event-driven architectures.
* **Time Handling:** Always use `DateTime.UtcNow` instead of `DateTime.Now` to ensure consistent time handling across timezones.
3.**SIMD**: Batch operations (`Calculate`) should use `System.Runtime.Intrinsics` (AVX2) or `System.Numerics.Vector<T>` where possible. Use `Vector.ConditionalSelect` to handle edge cases (e.g., division by zero) without branching. If SIMD is not possible due to recursive dependencies, use `stackalloc` for internal buffers to avoid heap allocations.
* **Attributes:** `[SkipLocalsInit]` for performance.
* **Modifiers:** `public sealed class`
* **Interface:** Implements `ITValuePublisher`
### State Management
* **Scalar State:** Use a `private record struct State` to group all scalar state variables. This ensures value semantics, automatic `IEquatable` implementation, and cleaner rollback logic.
* **State Variables:** Maintain `private State _state;` (current) and `private State _p_state;` (previous valid state).
* **Buffers:** Use `RingBuffer` for sliding window data.
* **Resync:** Implement a periodic full recalculation (e.g., every 1000 ticks) to prevent floating-point drift in running sums.
### Constructor
* Validate all parameters (throw `ArgumentException` for invalid values).
* **Event Subscription:** Subscribe to events directly (`source.Pub += ...`) when the source is passed as a non-nullable parameter. Do not use defensive null checks (`if (_source != null)`).
* **Tolerance**: Use explicit constants from `ValidationHelper` (e.g., `ValidationHelper.SkenderTolerance`, `ValidationHelper.TalibTolerance`) rather than relying on defaults. Typically `1e-7`.
* **Data**: Use `ValidationTestData` class which wraps `GBM` (Geometric Brownian Motion) to generate realistic test data (default 5000 bars) and provides pre-calculated Skender quotes.
* **Coverage**: Validate all 3 modes (Batch, Streaming, Span) against the external library.
* **Verification**: Use `ValidationHelper.VerifyData` which checks the last 100 bars to ensure convergence and correctness.
* **Note:** Be aware of potential 1-bar shifts due to different initialization strategies (e.g., Tulip often skips index 0). Use `lookback` parameter to align.
* **Pronouns**: Avoid first-person plural in documentation; prefer explicit "QuanTAlib" subject or passive voice. Treat this as a persistent style rule (to be stored in qdrant style/pattern entries when available).
* **Project Inclusion:** Ensure the adapter is included in the appropriate project (e.g., `quantower/Statistics.csproj`) and tests in `quantower/Quantower.Tests.csproj`.
* **Patterns & Decisions**: When designing, refactoring, or fixing indicators or tests, first query `qdrant.mcp` for stored QuanTAlib patterns, architectural decisions, and benchmarks, and align new work with those references unless there is a documented reason to diverge.
* **Event Flow Pattern (Commit d7dbd70)**: For `ITValuePublisher`-based indicators, subscribe directly with `source.Pub += Handle;` in constructors instead of storing `source` or delegate fields solely for subscription; rely on struct-based event args (e.g., `TBarEventArgs`, `TValueEventArgs`) and, when Meziantou MA0046 flags the non-EventArgs signature, suppress it locally with a targeted pragma and comment explaining the performance trade-off.
* **SoA Backing Storage (Commit d7dbd70)**: Core series types (`TSeries`, `TBarSeries`) intentionally use concrete `List<T>` fields to support SoA layout and `CollectionsMarshal.AsSpan`; when analyzers suggest collection abstractions (MA0016), suppress them narrowly around those fields, as this is a deliberate performance design.
* **Argument Validation (Commit d7dbd70)**: All `Calculate`/`Batch` and span-based APIs must use `ArgumentException` (or derived) overloads that include the offending parameter name (e.g., `nameof(output)` or `nameof(sourceY)`) for length and range checks, matching the MA0015-compliant pattern adopted across indicators.