mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-26 06:18:05 +00:00
docs: remove C# Implementation Considerations sections, clean up temp scripts, reorganize test files
- Remove 'C# Implementation Considerations' sections from 34 indicator .md files - Delete 29 temp PowerShell scripts (_fix_mojibake.ps1, _hex_scan.ps1, etc.) - Move test files into tests/ subdirectories for consistent project structure - Add trader-focused bullet points to indicator documentation
This commit is contained in:
@@ -158,89 +158,6 @@ DSMA is not implemented in mainstream libraries (TA-Lib, Skender, Tulip, Ooples)
|
||||
- **Bounds**: Output remains within [min, max] price range ±1% tolerance
|
||||
- **Mathematical Consistency**: Streaming updates match batch calculations (ε < 1e-10)
|
||||
|
||||
## C# Implementation Considerations
|
||||
|
||||
### State Management
|
||||
|
||||
DSMA uses a comprehensive State record struct combining all filter stages:
|
||||
|
||||
```csharp
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
private record struct State
|
||||
{
|
||||
public double Filt; // current filtered value
|
||||
public double Filt1; // filt[t-1]
|
||||
public double Filt2; // filt[t-2]
|
||||
public double Zeros1; // deviation[t-1]
|
||||
public double SumSquared; // running sum for RMS
|
||||
public double Result; // current DSMA value
|
||||
public double LastPrice; // last valid price
|
||||
public int Bars;
|
||||
}
|
||||
```
|
||||
|
||||
Bar correction requires coordinated rollback of both state and RingBuffer:
|
||||
|
||||
```csharp
|
||||
if (isNew) { _p_state = _state; _filtSquaredBuffer.Snapshot(); }
|
||||
else { _state = _p_state; _filtSquaredBuffer.Restore(); }
|
||||
```
|
||||
|
||||
### RingBuffer for RMS
|
||||
|
||||
The RingBuffer maintains O(1) running sum updates for RMS calculation:
|
||||
|
||||
```csharp
|
||||
double removed = _filtSquaredBuffer.Add(filtSq);
|
||||
_state.SumSquared = Math.FusedMultiplyAdd(-1.0, removed, _state.SumSquared + filtSq);
|
||||
```
|
||||
|
||||
The buffer's `Snapshot()`/`Restore()` methods enable atomic rollback on bar corrections.
|
||||
|
||||
### Precomputed Constants
|
||||
|
||||
Constructor calculates all filter coefficients once:
|
||||
|
||||
```csharp
|
||||
double arg = SqrtTwo * Math.PI / (period * 0.5);
|
||||
double a1 = Math.Exp(-arg);
|
||||
_b1 = 2.0 * a1 * Math.Cos(arg);
|
||||
_a1Sq = a1 * a1;
|
||||
_c1Half = (1.0 - _b1 + _a1Sq) * 0.5;
|
||||
_periodRecip = 1.0 / period;
|
||||
_scaleAdjustment = scaleFactor * 5.0 / period;
|
||||
```
|
||||
|
||||
### FMA Usage
|
||||
|
||||
FMA optimizes the Super Smoother IIR and adaptive EMA:
|
||||
|
||||
```csharp
|
||||
// Super Smoother: filt = c1Half*(zeros+zeros1) + b1*filt1 - a1Sq*filt2
|
||||
double filtPart2 = Math.FusedMultiplyAdd(_state.Filt1, _b1, -_a1Sq * _state.Filt2);
|
||||
|
||||
// Adaptive EMA: result = prevResult*decay + alpha*value
|
||||
double result = Math.FusedMultiplyAdd(_state.Result, decay, alpha * value);
|
||||
```
|
||||
|
||||
### Memory Layout
|
||||
|
||||
| Field | Type | Size | Purpose |
|
||||
| :--- | :--- | :---: | :--- |
|
||||
| `_b1` | double | 8B | Super Smoother coefficient |
|
||||
| `_c1Half` | double | 8B | Halved c₁ coefficient |
|
||||
| `_a1Sq` | double | 8B | a₁² coefficient |
|
||||
| `_periodRecip` | double | 8B | 1/period |
|
||||
| `_scaleAdjustment` | double | 8B | Combined scale factor |
|
||||
| `_filtSquaredBuffer` | RingBuffer | ~8B+period×8B | Circular buffer for RMS |
|
||||
| `_state` | State | ~64B | Current calculation state |
|
||||
| `_p_state` | State | ~64B | Previous state for rollback |
|
||||
| **Total (fixed)** | | **~176B + period×8B** | Per indicator instance |
|
||||
|
||||
### SIMD Limitations
|
||||
|
||||
The 2-pole IIR recursion and adaptive alpha dependency on running RMS preclude SIMD parallelization across bars. The `Calculate(Span)` method uses a scalar loop—parallelization should target multiple independent series rather than within-series vectorization.
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Warmup Period**: DSMA requires `Period` bars to fill the Super Smoother delay line and RMS buffer. The first `Period` outputs will be unstable. Use `IsHot` to detect when the indicator has sufficient history.
|
||||
|
||||
Reference in New Issue
Block a user