mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-19 02:58:05 +00:00
Complete thin Dx-composition wrapper indicators with full test coverage: - PlusDi/MinusDi: Directional Indicator wrappers (DiPlus/DiMinus from Dx) - PlusDm/MinusDm: Directional Movement wrappers (DmPlus/DmMinus from Dx) - Individual validation tests per indicator directory (TALib, Skender, bounds) - Combined unit tests (DiDm.Tests.cs) and validation tests (DiDm.Validation.Tests.cs) - Quantower wrappers + tests for all 4 indicators - PineScript v6 implementations with compensated RMA - Normalized .md documentation for all indicators and categories - 182 tests passing, 0 failures
117 lines
5.8 KiB
Markdown
117 lines
5.8 KiB
Markdown
# FISHER04: Ehlers Fisher Transform (2004 Cybernetic Analysis)
|
|
|
|
> *The Fisher Transform provides clear, unambiguous turning points that make it possible to identify trend reversals.*
|
|
|
|
## Introduction
|
|
|
|
The Fisher04 indicator implements the revised Fisher Transform from Chapter 1 of Ehlers' 2004 book *Cybernetic Analysis for Stocks and Futures*. It converts price data into a Gaussian normal distribution using the inverse hyperbolic tangent (arctanh), producing sharp turning-point signals. This 2004 revision uses wider normalization bandwidth, gentler IIR smoothing, and a reduced arctanh multiplier compared to the original 2002 TASC article, resulting in a smoother oscillator with less noise.
|
|
|
|
## Historical Context
|
|
|
|
Ehlers first published the Fisher Transform in a November 2002 *Stocks & Commodities* article titled "Using The Fisher Transform." That version used a 0.66 normalization coefficient and 0.67 IIR feedback. Two years later, in *Cybernetic Analysis for Stocks and Futures* (Wiley, 2004), Ehlers revised the coefficients. The 2004 version normalizes with a full 1.0 coefficient and 0.5 IIR feedback, tightens the clamp to 0.9999, and halves the arctanh multiplier from 0.5 to 0.25. No major external library (Skender, TA-Lib, Tulip, Ooples) implements this specific 2004 variant; they all use the 2002 formulation.
|
|
|
|
## Architecture
|
|
|
|
### 1. Min/Max Normalization
|
|
|
|
The lookback window tracks the highest high and lowest low over `period` bars using a `RingBuffer`. The raw price is mapped to [-0.5, 0.5]:
|
|
|
|
$$\text{norm} = \frac{\text{price} - \text{lowest}}{\text{highest} - \text{lowest}} - 0.5$$
|
|
|
|
When range is zero (flat price), `Value1` resets to 0.
|
|
|
|
### 2. IIR Smoothing (Value1)
|
|
|
|
The normalized value is smoothed with a single-pole IIR filter:
|
|
|
|
$$\text{Value1}_t = 1.0 \times \text{norm}_t + 0.5 \times \text{Value1}_{t-1}$$
|
|
|
|
Compare with Fisher (2002): $\text{Value1}_t = 0.66 \times \text{norm}_t + 0.67 \times \text{Value1}_{t-1}$
|
|
|
|
### 3. Clamping
|
|
|
|
Value1 is clamped to $(-0.9999, 0.9999)$ to prevent arctanh singularity:
|
|
|
|
$$\text{Value1} = \text{clamp}(\text{Value1}, -0.9999, 0.9999)$$
|
|
|
|
The clamped value is stored back for next iteration's IIR feedback.
|
|
|
|
### 4. Fisher Transform
|
|
|
|
The Fisher Transform applies arctanh with IIR feedback:
|
|
|
|
$$\text{Fish}_t = 0.25 \times \ln\!\left(\frac{1 + \text{Value1}}{1 - \text{Value1}}\right) + 0.5 \times \text{Fish}_{t-1}$$
|
|
|
|
The 0.25 multiplier (vs 0.5 in 2002) produces approximately half the amplitude, reducing false signals.
|
|
|
|
### 5. Signal Line
|
|
|
|
The signal line is the previous bar's Fisher value: $\text{Signal}_t = \text{Fish}_{t-1}$
|
|
|
|
## Coefficient Comparison
|
|
|
|
| Parameter | Fisher (2002) | Fisher04 (2004) |
|
|
|-----------|---------------|-----------------|
|
|
| Normalization | 0.66 | 1.0 |
|
|
| IIR feedback (Value1) | 0.67 | 0.5 |
|
|
| Clamp threshold | 0.99 → 0.999 | 0.9999 |
|
|
| Arctanh multiplier | 0.5 | 0.25 |
|
|
| Fisher IIR | 0.5 | 0.5 |
|
|
|
|
## Performance Profile
|
|
|
|
### Key Optimizations
|
|
|
|
- **FMA in IIR updates**: Both Value1 IIR and Fisher IIR use `Math.FusedMultiplyAdd` for the `feedback * prev + coeff * input` pattern.
|
|
- **Precomputed constants**: Normalization coefficient (1.0), IIR feedback (0.5), clamp threshold (0.9999), arctanh multiplier (0.25) are all `const` fields, avoiding repeated literal encoding.
|
|
- **RingBuffer for O(1) update**: `Add` and `UpdateNewest` are constant-time; only the min/max scan is O(period).
|
|
- **State copy pattern**: `_state`/`_p_state` record struct enables bar correction without allocation.
|
|
- **Zero allocation**: No heap allocation in the `Update` hot path; all state is stack-promoted via local copy.
|
|
|
|
### Operation Count (Streaming Mode)
|
|
|
|
| Operation | Count per bar |
|
|
|-----------|--------------|
|
|
| Comparisons | 2 x period (min/max scan) |
|
|
| Multiplications | 2 (normalize + arctanh multiplier) |
|
|
| Additions | 3 (normalize offset + 2x IIR) |
|
|
| FMA calls | 2 (Value1 IIR, Fisher IIR) |
|
|
| Log | 1 (arctanh via `Math.Log`) |
|
|
| Clamp | 1 |
|
|
| Division | 1 (normalization) |
|
|
|
|
### SIMD Analysis (Batch Mode)
|
|
|
|
| Aspect | Status |
|
|
|--------|--------|
|
|
| Min/max scan | Scalar (RingBuffer-based, O(period) per bar) |
|
|
| Normalization | Scalar (data-dependent division) |
|
|
| Value1 IIR smoothing | Scalar (sequential IIR dependency) |
|
|
| arctanh | Scalar (`Math.Log`, not vectorizable) |
|
|
| Fisher IIR | Scalar (sequential dependency on previous Fisher) |
|
|
| Vectorization potential | Low: dual IIR chain + logarithm prevents SIMD |
|
|
|
|
## Validation
|
|
|
|
No external library implements the 2004 Ehlers variant. Validation is performed against:
|
|
|
|
- Manual step-by-step computation matching the published algorithm
|
|
- Batch vs streaming consistency (tolerance: 1e-12)
|
|
- Span vs streaming consistency (tolerance: 1e-12)
|
|
- Coefficient difference verification against Fisher (2002)
|
|
- Amplitude reduction verification (Fisher04 < Fisher in avg absolute value)
|
|
|
|
## Common Pitfalls
|
|
|
|
1. **Confusing 2002 and 2004 versions.** The coefficient differences are subtle but produce measurably different outputs. Using 2002 coefficients with 2004 labels (or vice versa) produces incorrect results.
|
|
2. **Not storing clamped Value1 back.** The IIR feedback must use the clamped value, not the pre-clamp value. Failing to store back causes drift.
|
|
3. **Expecting identical results to Fisher.** Fisher04 uses 0.25x arctanh multiplier vs 0.5x; the amplitude is roughly halved.
|
|
4. **Using Fisher04 for high-frequency scalping.** The gentler coefficients make it slower to react than Fisher (2002). Better suited for swing trading.
|
|
5. **Ignoring the signal line crossover.** The primary trading signal is Fisher crossing above/below its one-bar-lagged signal line.
|
|
|
|
## References
|
|
|
|
1. Ehlers, J. F. (2004). *Cybernetic Analysis for Stocks and Futures*. Wiley. Chapter 1.
|
|
2. Ehlers, J. F. (2002). "Using The Fisher Transform." *Technical Analysis of Stocks & Commodities*, November 2002.
|
|
3. MESA Software. "The Inverse Fisher Transform." [mesasoftware.com](http://www.mesasoftware.com)
|