diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 00000000..e9345c0b
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,222 @@
+# QuanTAlib AI Coding Agent Instructions
+
+## Project Overview
+QuanTAlib is a high-performance C# library for quantitative technical analysis, targeting .NET 8.0 with real-time streaming data processing. The library provides 50+ technical indicators optimized for sub-millisecond calculations using circular buffers, SIMD operations, and event-driven architecture.
+
+## Critical Architecture Patterns
+
+### Core Data Flow
+All indicators inherit from `AbstractBase` (in `lib/core/abstractBase.cs`) which implements `ITValue`:
+```csharp
+// Standard indicator lifecycle:
+Input → Calc() → ManageState(isNew) → Calculation() → Process() → Pub event
+```
+
+**Key insight**: The `isNew` parameter distinguishes between new bars and updates to the last bar. Indicators must support both modes - this is tested extensively in `Tests/test_updates_*.cs`.
+
+### Circular Buffer Pattern
+`CircularBuffer` (in `lib/core/circularbuffer.cs`) is the foundation for memory-efficient fixed-capacity storage:
+- Never grows beyond initial capacity
+- O(1) add/access operations
+- SIMD-optimized aggregations (Sum, Min, Max, Average)
+- **Critical**: Always use `Add(item, isNew)` - the `isNew` flag controls whether to append or update
+
+### State Management in Indicators
+Every indicator must implement:
+```csharp
+protected override void ManageState(bool isNew)
+{
+ if (isNew) {
+ _index++;
+ _p_prevValue = _prevValue; // Backup state
+ } else {
+ _prevValue = _p_prevValue; // Restore state
+ }
+}
+```
+This allows bar updates without corrupting historical calculations.
+
+## Development Workflow
+
+### MCP-Orchestrated Process
+**Research Gate**: Before implementing non-trivial indicators, use Context7 to retrieve authoritative formulas/references. Embed citation tags in PR descriptions.
+
+**Decomposition**: Use Sequential-Thinking for complex multi-stage work (SIMD refactors, multi-timeframe logic).
+
+**Task Tracking**: Taskmaster holds the canonical task graph. Feature branches follow pattern: `feature/{taskId}-{slug}`.
+
+**Quality Gates**:
+1. Formula citation required for non-trivial indicators (Context7 tag)
+2. Benchmark data required for performance-related changes
+3. Taskmaster task IDs must be referenced in PRs
+4. Update `memory-bank/progress.md` after merge when threshold met
+
+### Build & Test Commands
+```powershell
+# Build solution
+dotnet build QuanTAlib.sln
+
+# Run all tests
+dotnet test --no-build
+
+# Run with coverage
+dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov
+
+# Build using tasks.json
+# Use Run Task: "build" or "test"
+```
+
+### Adding a New Indicator
+1. **Research**: Get formula/specification (Context7 if needed)
+2. **Location**: Place in appropriate `lib/` subdirectory (averages, oscillators, momentum, volatility, volume, statistics)
+3. **Template structure**:
+```csharp
+using System.Runtime.CompilerServices;
+namespace QuanTAlib;
+
+[SkipLocalsInit]
+public sealed class MyIndicator : AbstractBase
+{
+ private CircularBuffer _buffer;
+ private double _prevValue, _p_prevValue; // State + backup
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public MyIndicator(int period)
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan(period, 1);
+ _buffer = new(period);
+ WarmupPeriod = period; // Set when indicator stabilizes
+ Name = $"MyIndicator({period})";
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected override void ManageState(bool isNew)
+ {
+ if (isNew) {
+ _index++;
+ _p_prevValue = _prevValue;
+ } else {
+ _prevValue = _p_prevValue;
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
+ protected override double Calculation()
+ {
+ ManageState(Input.IsNew);
+ _buffer.Add(Input.Value, Input.IsNew);
+ // Implement calculation logic
+ return result;
+ }
+}
+```
+
+4. **Testing**: Create update test in `Tests/test_updates_*.cs`:
+```csharp
+[Fact]
+public void MyIndicator_Update()
+{
+ var indicator = new MyIndicator(period: 14);
+ TestTValueUpdate(indicator, indicator.Calc);
+}
+```
+
+### Quantower Integration
+For platform indicators in `quantower/`, create wrapper classes inheriting from Quantower's `Indicator`:
+- Use private `lib/` indicator instances
+- Map `OnUpdate()` to indicator's `Calc()` method
+- Extract output fields (e.g., `ma`, `jmaUp`, `jmaLo`) from indicator state
+
+## Code Style Requirements
+
+### Performance First
+- Use `[MethodImpl(MethodImplOptions.AggressiveInlining)]` for hot paths
+- Use `[MethodImpl(MethodImplOptions.AggressiveOptimization)]` for calculation methods
+- Apply `[SkipLocalsInit]` to indicator classes
+- Prefer SIMD operations in `CircularBuffer` for aggregations
+- Minimize allocations in `Calculation()` methods
+
+### C# Conventions
+- **No inline comments** within methods - code should be self-documenting
+- Use XML doc comments for public APIs only
+- PascalCase for public members, _camelCase for private fields
+- Compact code - minimal whitespace between logical blocks
+- Latest C# features: `ArgumentOutOfRangeException.ThrowIfLessThan`, pattern matching, etc.
+
+### Project Settings
+- `LangVersion: preview` - use cutting-edge C# features
+- `AllowUnsafeBlocks: true` - SIMD and unsafe operations permitted
+- `Nullable: enable` - strict nullability checking
+- Target: `net8.0`
+
+## Key Files & Directories
+
+### Core Library Structure
+```
+lib/
+├── core/ # AbstractBase, CircularBuffer, TSeries, TBar, TValue
+├── averages/ # Moving averages (SMA, EMA, DEMA, TEMA, JMA, etc.)
+├── oscillators/ # RSI, Stochastic, Williams %R, CCI, Fisher
+├── momentum/ # MACD, ADX, ROC, Vortex
+├── volatility/ # ATR, Bollinger Bands, volatility measures
+├── volume/ # Volume-based indicators
+└── statistics/ # Statistical measures, correlations
+```
+
+### Critical Reference Files
+- `lib/core/abstractBase.cs` - Base class for all indicators
+- `lib/core/circularbuffer.cs` - Memory-efficient storage with SIMD
+- `Directory.Build.props` - Solution-wide MSBuild properties
+- `memory-bank/systemPatterns.md` - Architecture patterns
+- `memory-bank/activeContext.md` - Current work focus and MCP policies
+- `memory-bank/progress.md` - Completed features and roadmap
+
+### Testing Reference
+- `Tests/test_updates_*.cs` - Update behavior validation (IsNew handling)
+- `Tests/test_quantower.cs` - Quantower integration validation
+- `Tests/test_talib.cs`, `test_Trady.cs` - Cross-validation against reference libraries
+
+## Common Patterns
+
+### Multi-Stage Smoothing
+Many indicators (DEMA, TEMA, MACD) use cascaded smoothing:
+```csharp
+private readonly Ema _ema1;
+private readonly Ema _ema2;
+
+_ema1.Calc(Input.Value, Input.IsNew);
+_ema2.Calc(_ema1.Value, Input.IsNew);
+```
+
+### Bar-Based vs Value-Based
+- **Value-based**: Accept `TValue`, process single values (most indicators)
+- **Bar-based**: Accept `TBar` (OHLCV), process bar data (ATR, Stochastic, volume indicators)
+
+Override appropriate `Calc()` method:
+```csharp
+public override TValue Calc(TBar barInput) { /* ... */ }
+```
+
+### WarmupPeriod Calculation
+Set `WarmupPeriod` to indicate when the indicator reaches 95% accuracy:
+```csharp
+WarmupPeriod = (int)Math.Ceiling(Math.Log(0.05) / Math.Log(1 - alpha));
+```
+
+## Validation Strategy
+1. **Update tests**: Verify `isNew=false` behavior converges to `isNew=true` with same final value
+2. **Reference comparison**: Validate against TALib, Trady, or Skender implementations
+3. **Edge cases**: Test with insufficient data (< period), NaN/Infinity, extreme values
+4. **Performance**: Benchmark calculation time - target < 0.5ms per update
+
+## Documentation Requirements
+- XML docs on public classes/methods describing purpose, formula, and sources
+- Mathematical formulas in doc comments with source citations
+- No internal comments - let code structure communicate intent
+- Update `memory-bank/progress.md` after significant feature completion
+
+## GitVersion & Releases
+- Semantic versioning via GitVersion.yml
+- Version properties auto-injected: `$(GitVersion_MajorMinorPatch)`
+- Commit messages influence version bumps (conventional commits)
+- Build creates NuGet package with embedded version metadata
diff --git a/lib/averages/Sma.cs b/lib/averages/Sma.cs
index fb267e31..684d4445 100644
--- a/lib/averages/Sma.cs
+++ b/lib/averages/Sma.cs
@@ -1,75 +1,99 @@
-using System.Runtime.CompilerServices;
-namespace QuanTAlib;
-
-///
-/// SMA: Simple Moving Average
-/// The most basic form of moving average, calculating the arithmetic mean over a
-/// specified period. Each data point in the period has equal weight in the
-/// calculation.
-///
-///
-/// The SMA calculation process:
-/// 1. Maintains a buffer of the last 'period' values
-/// 2. Calculates arithmetic mean of all values in the buffer
-/// 3. Updates buffer with new values in FIFO manner
-///
-/// Key characteristics:
-/// - Equal weight for all values in the period
-/// - Simple and straightforward calculation
-/// - Significant lag due to equal weighting
-/// - Smooth output with good noise reduction
-/// - Most basic form of trend following
-///
-/// Sources:
-/// https://www.investopedia.com/terms/s/sma.asp
-/// https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
-///
-public class Sma : AbstractBase
-{
- private readonly CircularBuffer _buffer;
-
- /// The number of data points used in the SMA calculation.
- /// Thrown when period is less than 1.
- public Sma(int period)
- {
- if (period < 1)
- {
- throw new System.ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1.");
- }
- _buffer = new CircularBuffer(period);
- Name = "Sma";
- WarmupPeriod = period;
- Init();
- }
-
- /// The data source object that publishes updates.
- /// The number of data points used in the SMA calculation.
- public Sma(object source, int period) : this(period)
- {
- var pubEvent = source.GetType().GetEvent("Pub");
- pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected override void ManageState(bool isNew)
- {
- if (isNew)
- {
- _lastValidValue = Input.Value;
- _index++;
- }
- }
-
- ///
- /// Performs the core SMA calculation using the circular buffer's average.
- ///
- /// The calculated SMA value.
- protected override double Calculation()
- {
- ManageState(IsNew);
- _buffer.Add(Input.Value, Input.IsNew);
-
- IsHot = _index >= WarmupPeriod;
- return _buffer.Average();
- }
-}
+using System.Runtime.CompilerServices;
+namespace QuanTAlib;
+
+///
+/// SMA: Simple Moving Average
+/// The most basic form of moving average, calculating the arithmetic mean over a
+/// specified period. Each data point in the period has equal weight in the
+/// calculation.
+///
+///
+/// The SMA calculation process:
+/// 1. Maintains a circular buffer of the last 'period' values
+/// 2. Maintains a running sum for O(1) calculation
+/// 3. Updates: sum = sum - oldest + newest
+/// 4. Returns sum / count for the average
+///
+/// Key characteristics:
+/// - Equal weight for all values in the period
+/// - O(1) time complexity using running sum
+/// - Simple and straightforward calculation
+/// - Significant lag due to equal weighting
+/// - Smooth output with good noise reduction
+/// - Most basic form of trend following
+///
+/// Sources:
+/// https://www.investopedia.com/terms/s/sma.asp
+/// https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
+///
+[SkipLocalsInit]
+public sealed class Sma : AbstractBase
+{
+ private readonly CircularBuffer _buffer;
+ private double _sum, _p_sum;
+ private double _lastValue, _p_lastValue;
+
+ /// The number of data points used in the SMA calculation.
+ /// Thrown when period is less than 1.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Sma(int period)
+ {
+ ArgumentOutOfRangeException.ThrowIfLessThan(period, 1);
+ _buffer = new CircularBuffer(period);
+ Name = $"Sma({period})";
+ WarmupPeriod = period;
+ Init();
+ }
+
+ /// The data source object that publishes updates.
+ /// The number of data points used in the SMA calculation.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Sma(object source, int period) : this(period)
+ {
+ var pubEvent = source.GetType().GetEvent("Pub");
+ pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected override void ManageState(bool isNew)
+ {
+ if (isNew)
+ {
+ _index++;
+ _p_sum = _sum;
+ _p_lastValue = _lastValue;
+ }
+ else
+ {
+ _sum = _p_sum;
+ _lastValue = _p_lastValue;
+ }
+ }
+
+ ///
+ /// Performs the core SMA calculation using O(1) running sum algorithm.
+ ///
+ /// The calculated SMA value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
+ protected override double Calculation()
+ {
+ ManageState(Input.IsNew);
+
+ double oldValue;
+ if (Input.IsNew)
+ {
+ oldValue = _buffer.Count == _buffer.Capacity ? _buffer.Oldest() : 0.0;
+ _lastValue = Input.Value;
+ }
+ else
+ {
+ oldValue = _lastValue;
+ }
+
+ _sum = _sum - oldValue + Input.Value;
+ _buffer.Add(Input.Value, Input.IsNew);
+
+ IsHot = _index >= WarmupPeriod;
+ return _sum / _buffer.Count;
+ }
+}