mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-14 16:48:04 +00:00
231 lines
6.2 KiB
Markdown
231 lines
6.2 KiB
Markdown
# HT_TRENDMODE: Hilbert Transform Trend Mode
|
||||
|
|
|
|||
|
|
## Historical Context
|
|||
|
|
|
|||
|
|
The Hilbert Transform Trend Mode indicator was developed by **John Ehlers** as part of his cycle analysis toolkit. It uses the Hilbert Transform—a signal processing technique—to determine whether price action is dominated by **trending behavior** or **cyclical/mean-reverting behavior**.
|
|||
|
|
|
|||
|
|
This implementation follows **TA-Lib's Ehlers-faithful algorithm** from his February 2002 publication "The Instantaneous Trendline." The key insight: trend mode is detected via multiple criteria including SineWave crossings, phase rate analysis, and price-trendline deviation.
|
|||
|
|
|
|||
|
|
## Architecture & Physics
|
|||
|
|
|
|||
|
|
### The Trend/Cycle Duality
|
|||
|
|
|
|||
|
|
Markets alternate between two fundamental states:
|
|||
|
|
|
|||
|
|
| State | Characteristic | Strategy |
|
|||
|
|
|-------|---------------|----------|
|
|||
|
|
| **Trend Mode (1)** | Directional momentum | Trend-following |
|
|||
|
|
| **Cycle Mode (0)** | Mean-reverting oscillation | Range-trading |
|
|||
|
|
|
|||
|
|
The TA-Lib algorithm uses **four criteria** to determine trend mode:
|
|||
|
|
|
|||
|
|
1. **SineWave Crossings**: Reset trend counter when Sine crosses LeadSine
|
|||
|
|
2. **Days in Trend**: Must exceed half the smooth period
|
|||
|
|
3. **Phase Rate Check**: Normal phase change rate indicates cycle mode
|
|||
|
|
4. **Price-Trendline Deviation**: ≥1.5% deviation forces trend mode
|
|||
|
|
|
|||
|
|
## Mathematical Foundation
|
|||
|
|
|
|||
|
|
### 1. Hilbert Transform Components
|
|||
|
|
|
|||
|
|
The indicator uses the same Hilbert Transform core as HT_DCPERIOD:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
smooth_price = (4×P₀ + 3×P₁ + 2×P₂ + P₃) / 10
|
|||
|
|
|
|||
|
|
detrender = FIR(smooth_price) × bandwidth
|
|||
|
|
Q1 = FIR(detrender) × bandwidth
|
|||
|
|
I1 = detrender[3]
|
|||
|
|
|
|||
|
|
// Phasor rotation
|
|||
|
|
I2 = I1 - jQ
|
|||
|
|
Q2 = Q1 + jI
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Period and DC Phase
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Re = 0.2×(I2×I2[1] + Q2×Q2[1]) + 0.8×Re[1]
|
|||
|
|
Im = 0.2×(I2×Q2[1] - Q2×I2[1]) + 0.8×Im[1]
|
|||
|
|
|
|||
|
|
period = 360 / (atan(Im/Re) × RAD2DEG)
|
|||
|
|
smooth_period = 0.33×period + 0.67×smooth_period[1]
|
|||
|
|
|
|||
|
|
// DC Phase calculation
|
|||
|
|
realPart = Σ sin(i × 360/dcPeriod) × smoothPrice[i]
|
|||
|
|
imagPart = Σ cos(i × 360/dcPeriod) × smoothPrice[i]
|
|||
|
|
dcPhase = atan(realPart/imagPart) × RAD2DEG + 90 + lag_compensation
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. SineWave Indicators
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
sine = sin(dcPhase × DEG2RAD)
|
|||
|
|
leadSine = sin((dcPhase + 45) × DEG2RAD)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. Trendline Calculation
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
// SMA over dominant cycle period
|
|||
|
|
sma = average(price, dcPeriodInt)
|
|||
|
|
|
|||
|
|
// WMA smoothing
|
|||
|
|
trendline = (4×sma₀ + 3×sma₁ + 2×sma₂ + sma₃) / 10
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. Trend Mode Decision (TA-Lib Algorithm)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
trend = 1 // Assume trend by default
|
|||
|
|
|
|||
|
|
// Criterion 1: SineWave crossing resets counter
|
|||
|
|
if (sine crosses leadSine):
|
|||
|
|
daysInTrend = 0
|
|||
|
|
trend = 0
|
|||
|
|
|
|||
|
|
daysInTrend++
|
|||
|
|
|
|||
|
|
// Criterion 2: Must be trending for half a cycle
|
|||
|
|
if (daysInTrend < 0.5 × smoothPeriod):
|
|||
|
|
trend = 0
|
|||
|
|
|
|||
|
|
// Criterion 3: Normal phase rate → cycle mode
|
|||
|
|
phaseChange = dcPhase - prevDcPhase
|
|||
|
|
expectedChange = 360 / smoothPeriod
|
|||
|
|
if (phaseChange > 0.67×expectedChange AND phaseChange < 1.5×expectedChange):
|
|||
|
|
trend = 0
|
|||
|
|
|
|||
|
|
// Criterion 4: Price deviation override
|
|||
|
|
if (abs((smoothPrice - trendline) / trendline) >= 0.015):
|
|||
|
|
trend = 1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Performance Profile
|
|||
|
|
|
|||
|
|
- **Complexity**: O(1) per update
|
|||
|
|
- **Memory**: ~450 bytes state + circular buffers
|
|||
|
|
- **Lookback**: 63 bars (TA-Lib compatible)
|
|||
|
|
|
|||
|
|
### Zero-Allocation Design
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
[SkipLocalsInit]
|
|||
|
|
public sealed class HtTrendmode : AbstractBase
|
|||
|
|
{
|
|||
|
|
// All state in value types
|
|||
|
|
private State _state;
|
|||
|
|
private State _p_state;
|
|||
|
|
|
|||
|
|
// Pre-allocated buffers for Hilbert Transform
|
|||
|
|
private readonly double[] _circBuffer;
|
|||
|
|
private readonly double[] _smoothPrice;
|
|||
|
|
private readonly double[] _priceHistory;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Bar Correction Pattern
|
|||
|
|
|
|||
|
|
Supports streaming updates with correction:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// New bar
|
|||
|
|
var result = indicator.Update(price, isNew: true);
|
|||
|
|
|
|||
|
|
// Same bar, corrected price
|
|||
|
|
var corrected = indicator.Update(newPrice, isNew: false);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Usage
|
|||
|
|
|
|||
|
|
### Streaming
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
var indicator = new HtTrendmode();
|
|||
|
|
|
|||
|
|
foreach (var bar in bars)
|
|||
|
|
{
|
|||
|
|
var result = indicator.Update(bar.Close, isNew: true);
|
|||
|
|
|
|||
|
|
if (indicator.TrendMode == 1)
|
|||
|
|
{
|
|||
|
|
// Use trend-following strategy
|
|||
|
|
ApplyMomentumStrategy();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// Use mean-reversion strategy
|
|||
|
|
ApplyRangeStrategy();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Batch
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
var result = HtTrendmode.Calculate(closePrices);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Properties
|
|||
|
|
|
|||
|
|
| Property | Type | Description |
|
|||
|
|
|----------|------|-------------|
|
|||
|
|
| `TrendMode` | int | Current mode: 1=trend, 0=cycle |
|
|||
|
|
| `SmoothPeriod` | double | Smoothed dominant cycle period [6-50] |
|
|||
|
|
| `InstPeriod` | double | Instantaneous (unsmoothed) period |
|
|||
|
|
| `DCPhase` | double | Dominant cycle phase in degrees |
|
|||
|
|
| `Trendline` | double | WMA-smoothed SMA over cycle period |
|
|||
|
|
| `DaysInTrend` | int | Days since last SineWave crossing |
|
|||
|
|
|
|||
|
|
## Interpretation
|
|||
|
|
|
|||
|
|
### Signal Interpretation
|
|||
|
|
|
|||
|
|
| Value | Mode | Interpretation |
|
|||
|
|
|-------|------|----------------|
|
|||
|
|
| **1** | Trend | Price is trending; momentum strategies preferred |
|
|||
|
|
| **0** | Cycle | Price is oscillating; mean-reversion preferred |
|
|||
|
|
|
|||
|
|
### Common Patterns
|
|||
|
|
|
|||
|
|
1. **Trend Confirmation**: When TrendMode flips from 0→1 after a breakout
|
|||
|
|
2. **Cycle Entry**: When TrendMode flips from 1→0 at potential reversal zones
|
|||
|
|
3. **Mode Persistence**: Long runs of 1s indicate strong trends
|
|||
|
|
4. **Mode Oscillation**: Rapid flipping indicates choppy markets
|
|||
|
|
|
|||
|
|
### Using Auxiliary Properties
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Access the trendline for support/resistance
|
|||
|
|
double trend = indicator.Trendline;
|
|||
|
|
|
|||
|
|
// Check how long in current trend
|
|||
|
|
int duration = indicator.DaysInTrend;
|
|||
|
|
|
|||
|
|
// Use phase for timing entries
|
|||
|
|
double phase = indicator.DCPhase;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Validation
|
|||
|
|
|
|||
|
|
### Cross-Library Comparison
|
|||
|
|
|
|||
|
|
| Library | Function | Notes |
|
|||
|
|
|---------|----------|-------|
|
|||
|
|
| TA-Lib | `HT_TRENDMODE` | Reference implementation (matched) |
|
|||
|
|
| TradingView | Built-in | PineScript version (differs) |
|
|||
|
|
|
|||
|
|
### Common Pitfalls
|
|||
|
|
|
|||
|
|
1. **Lag**: Hilbert Transform has inherent lag (~32-63 bars for reliable signal)
|
|||
|
|
2. **Whipsaws**: Mode can flip rapidly in transitional markets
|
|||
|
|
3. **Warmup**: Requires 63+ bars before valid output
|
|||
|
|
4. **Division Safety**: Use epsilon checks to avoid division by zero
|
|||
|
|
|
|||
|
|
## References
|
|||
|
|
|
|||
|
|
- Ehlers, J.F. "The Instantaneous Trendline" (February 2002)
|
|||
|
|
- Ehlers, J.F. "MESA and Trading Market Cycles" (2002)
|
|||
|
|
- Ehlers, J.F. "Rocket Science for Traders" (2001)
|
|||
|
|
- [TA-Lib HT_TRENDMODE Source](https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_HT_TRENDMODE.c)
|