mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-19 11:08:05 +00:00
- Implemented ChopIndicator for Quantower with configurable period and cold value display. - Created Chop class for calculating the Choppiness Index with detailed documentation. - Added comprehensive unit tests for Chop functionality, covering various market conditions and edge cases. - Developed markdown documentation for CHOP, detailing its historical context, mathematical foundation, and usage examples. - Established a remediation plan for channel indicators documentation, identifying gaps and prioritizing updates.
144 lines
4.0 KiB
Markdown
144 lines
4.0 KiB
Markdown
# HT_DCPERIOD: Hilbert Transform - Dominant Cycle Period
|
||
|
||
> "Knowing the cycle period is the master key—it calibrates other indicators to the market's current rhythm."
|
||
|
||
HT_DCPERIOD estimates the period of the dominant market cycle using Ehlers' Hilbert Transform cascade. The indicator measures the instantaneous period based on the rate of change of the phase angle, providing a variable period length (typically 6-50 bars) that dynamically tunes other indicators.
|
||
|
||
## Historical Context
|
||
|
||
John Ehlers introduced the Hilbert Transform Dominant Cycle Period in *Rocket Science for Traders* (2001). The goal was to overcome the limitations of fixed-period indicators by measuring the actual cycle length present in the data.
|
||
|
||
TA-Lib implements HT_DCPERIOD using Ehlers' specific coefficients (A = 0.0962, B = 0.5769) and smoothing algorithms. QuanTAlib matches the TA-Lib implementation within floating-point tolerance.
|
||
|
||
## Architecture & Physics
|
||
|
||
The algorithm follows a complex pipeline to extract cycle period from phase information.
|
||
|
||
### 1. WMA Price Smoothing
|
||
|
||
$$
|
||
SmoothPrice_t = \frac{4P_t + 3P_{t-1} + 2P_{t-2} + P_{t-3}}{10}
|
||
$$
|
||
|
||
### 2. Hilbert Transform Components
|
||
|
||
The Hilbert Transform generates In-Phase (I) and Quadrature (Q) components:
|
||
|
||
- **Detrender**: Removes DC component and trend
|
||
- **Q1**: Quadrature component of detrender
|
||
- **I1**: In-Phase component (delayed detrender)
|
||
- **jI, jQ**: Hilbert transforms of I1 and Q1
|
||
|
||
### 3. Phasor Components
|
||
|
||
$$
|
||
I2_t = I1_t - jQ_t
|
||
$$
|
||
|
||
$$
|
||
Q2_t = Q1_t + jI_t
|
||
$$
|
||
|
||
Smoothed with EMA (α = 0.2).
|
||
|
||
### 4. Period Extraction
|
||
|
||
$$
|
||
Period_t = \frac{2\pi}{\arctan(Im_t / Re_t)}
|
||
$$
|
||
|
||
Clamped to [6, 50] and smoothed with EMA (α = 0.33).
|
||
|
||
## Performance Profile
|
||
|
||
### Operation Count (Streaming Mode, per Bar)
|
||
|
||
| Operation | Count | Cost (cycles) | Subtotal |
|
||
| :--- | :---: | :---: | :---: |
|
||
| MUL (Hilbert taps) | 28 | 3 | 84 |
|
||
| MUL (homodyne mix) | 4 | 3 | 12 |
|
||
| ADD/SUB | 40 | 1 | 40 |
|
||
| ATAN2 | 1 | 25 | 25 |
|
||
| DIV | 3 | 15 | 45 |
|
||
| **Total** | **76** | — | **~206 cycles** |
|
||
|
||
### Complexity Analysis
|
||
|
||
- **Streaming:** O(1) per bar—fixed Hilbert cascade
|
||
- **Memory:** ~1.2 KB per instance (circular buffers + state)
|
||
- **Warmup:** 32 bars (TA-Lib lookback)
|
||
|
||
## Validation
|
||
|
||
| Library | Status | Notes |
|
||
| :--- | :---: | :--- |
|
||
| TA-Lib | ✅ | Matches `TALib.Functions.HtDcPeriod()` |
|
||
| Skender | N/A | Not implemented |
|
||
| PineScript | ✅ | Matches `ht_dcperiod.pine` reference |
|
||
|
||
## Usage & Pitfalls
|
||
|
||
- **Output is period in bars** (6-50 range)—not an oscillator
|
||
- **32-bar warmup required**—ignore early values
|
||
- **Trending markets** cause period to drift to upper limit (50)
|
||
- **High noise** causes jitter—internal smoothing helps
|
||
- **Use for adaptive tuning**: `RSI(period: htDcperiod.Value / 2)`
|
||
- **Stable periods** indicate rhythmic market suitable for oscillators
|
||
|
||
## API
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class HtDcperiod {
|
||
+double Value
|
||
+bool IsHot
|
||
+HtDcperiod()
|
||
+HtDcperiod(ITValuePublisher source)
|
||
+TValue Update(TValue input, bool isNew)
|
||
+void Reset()
|
||
}
|
||
```
|
||
|
||
### Class: `HtDcperiod`
|
||
|
||
| Parameter | Type | Default | Range | Description |
|
||
| :--- | :--- | :--- | :--- | :--- |
|
||
| (none) | — | — | — | No constructor parameters |
|
||
|
||
### Properties
|
||
|
||
- `Value` (`double`): Dominant cycle period in bars (6-50)
|
||
- `IsHot` (`bool`): Returns `true` when warmup (32 bars) is complete
|
||
|
||
### Methods
|
||
|
||
- `Update(TValue input, bool isNew)`: Updates the indicator with a new data point
|
||
|
||
## C# Example
|
||
|
||
```csharp
|
||
using QuanTAlib;
|
||
|
||
// Create HT_DCPERIOD
|
||
var htPeriod = new HtDcperiod();
|
||
|
||
// Update with streaming data
|
||
foreach (var bar in quotes)
|
||
{
|
||
var result = htPeriod.Update(new TValue(bar.Date, bar.Close));
|
||
|
||
if (htPeriod.IsHot)
|
||
{
|
||
double period = result.Value;
|
||
Console.WriteLine($"{bar.Date}: Dominant Cycle = {period:F2} bars");
|
||
|
||
// Use cycle to tune RSI adaptively
|
||
int adaptivePeriod = (int)(period / 2);
|
||
var adaptiveRsi = new Rsi(adaptivePeriod);
|
||
}
|
||
}
|
||
|
||
// Batch calculation
|
||
var output = HtDcperiod.Calculate(sourceSeries);
|
||
```
|