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:
Miha Kralj
2026-03-12 12:34:16 -07:00
parent 8937b0c0fa
commit 060649192f
1149 changed files with 1780 additions and 3316 deletions
-70
View File
@@ -184,76 +184,6 @@ QuanTAlib validates HAMMA against its mathematical definition and internal consi
| **Tulip** | ❌ | Not included. |
| **Ooples** | ❌ | Not included. |
### C# Implementation Considerations
The QuanTAlib HAMMA implementation optimizes Hamming window convolution through precomputation and SIMD-accelerated dot products:
**Precomputed Weights with Inverse Sum**
```csharp
ComputeWeights(_weights, period, out _invWeightSum);
// ...
double twoPiOverPm1 = 2.0 * Math.PI / (period - 1);
for (int i = 0; i < period; i++)
{
double w = 0.54 - 0.46 * Math.Cos(twoPiOverPm1 * i);
weights[i] = w;
sum += w;
}
invWeightSum = 1.0 / sum;
```
Trigonometric operations computed once at construction. Normalization uses multiplication by precomputed inverse rather than division per tick.
**State Record Struct**
```csharp
[StructLayout(LayoutKind.Auto)]
private record struct State(double LastValidValue, bool IsInitialized);
private State _state;
private State _p_state;
```
Compiler optimizes field layout. The `IsInitialized` flag tracks whether valid data has been seen for proper NaN handling.
**SIMD-Accelerated Circular Buffer Dot Product**
```csharp
int part1Len = _period - head;
double sum1 = internalBuf.Slice(head, part1Len).DotProduct(_weights.AsSpan(0, part1Len));
double sum2 = internalBuf[..head].DotProduct(_weights.AsSpan(part1Len));
return (sum1 + sum2) * _invWeightSum;
```
Full buffer splits into two `DotProduct` calls to handle circular wrap. The extension leverages AVX2/FMA intrinsics when available.
**Dual Allocation Strategy for Batch**
```csharp
double[]? weightsArray = period > 256 ? ArrayPool<double>.Shared.Rent(period) : null;
Span<double> weights = period <= 256
? stackalloc double[period]
: weightsArray!.AsSpan(0, period);
```
Small periods use stack allocation; large periods use `ArrayPool` to avoid heap pressure while respecting stack limits.
**Incremental Weight Sum During Warmup**
```csharp
if (count < period)
{
count++;
currentWeightSum += weights[period - count];
}
```
Partial buffer normalization accumulates weight sum incrementally rather than recalculating each tick.
**Memory Layout**
| Field | Type | Size | Notes |
|:------|:-----|-----:|:------|
| `_period` | int | 4B | Window length |
| `_weights` | double[] | 8B + L×8B | Hamming coefficients |
| `_invWeightSum` | double | 8B | Precomputed 1/Σw |
| `_buffer` | RingBuffer | ~40B + L×8B | Circular data buffer |
| `_state` | State | 16B | Last valid + initialized flag |
| `_p_state` | State | 16B | Previous state for rollback |
| **Total** | | ~92B + 2L×8B | Plus object overhead |
For a typical 14-period: ~92 + 224 ≈ **316 bytes** per instance.
## Common Pitfalls
1. **Confusing Hamming and Hanning**: Hamming uses 0.54/0.46 coefficients with edge weights of 0.08. Hanning uses 0.5/0.5 with edge weights of 0.0. They're different windows with different properties.