mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-26 06:18:05 +00:00
Refactor documentation links in numerics, oscillators, reversals, and statistics modules to use relative paths; update Bias class to handle division by zero more robustly; remove obsolete CUMMEAN Pine script; enhance trend indicators documentation; add Visual Studio Code workspace configuration.
This commit is contained in:
+297
-93
@@ -1,123 +1,327 @@
|
||||
# EBSW: Ehlers Even Better Sinewave
|
||||
|
||||
## Overview and Purpose
|
||||
> "When you combine a high-pass filter with a super-smoother, you get cleaner cycles with automatic gain control."
|
||||
|
||||
The Ehlers Even Better Sinewave (EBSW) indicator, developed by John Ehlers, is an advanced cycle analysis tool. This implementation is based on a common interpretation that uses a cascade of filters: first, a High-Pass Filter (HPF) to detrend price data, followed by a Super Smoother Filter (SSF) to isolate the dominant cycle. The resulting filtered wave is then normalized using an Automatic Gain Control (AGC) mechanism, producing a bounded oscillator that fluctuates between approximately +1 and -1. It aims to provide a clear and responsive measure of market cycles.
|
||||
The Even Better Sinewave (EBSW) indicator, developed by John Ehlers, is a normalized cycle oscillator that extracts the dominant cycle from price data using a cascade of high-pass and super-smoother filters with automatic gain control (AGC). The output oscillates between -1 and +1, with zero crossings indicating potential turning points.
|
||||
|
||||
## Core Concepts
|
||||
## Historical Context
|
||||
|
||||
* **Detrending (High-Pass Filter):** A 1-pole High-Pass Filter removes the longer-term trend component from the price data, allowing the indicator to focus on cyclical movements.
|
||||
* **Cycle Smoothing (Super Smoother Filter):** Ehlers' Super Smoother Filter is applied to the detrended data to further refine the cycle component, offering effective smoothing with relatively low lag.
|
||||
* **Wave Generation:** The output of the SSF is averaged over a short period (typically 3 bars) to create the primary "wave".
|
||||
* **Automatic Gain Control (AGC):** The wave's amplitude is normalized by dividing it by the square root of its recent power (average of squared values). This keeps the oscillator bounded and responsive to changes in volatility.
|
||||
* **Normalized Oscillator:** The final output is a single sinewave-like oscillator.
|
||||
John Ehlers introduced the Even Better Sinewave as an improvement over earlier sinewave indicators. The original sinewave indicator suffered from trend contamination and noise sensitivity. EBSW addresses these issues through a multi-stage filtering approach:
|
||||
|
||||
## Common Settings and Parameters
|
||||
1. **High-pass filter** removes the DC (trend) component
|
||||
2. **Super-smoother filter** eliminates high-frequency noise
|
||||
3. **Automatic gain control** normalizes the output regardless of volatility
|
||||
|
||||
| Parameter | Default | Function | When to Adjust |
|
||||
| --------- | ------- | -------- | -------------- |
|
||||
| Source | source | Data source for calculation. | Typically `close`, but `hlc3` or `ohlc4` can be used for a more comprehensive price representation. |
|
||||
| HP Length | 40 | Lookback period for the 1-pole High-Pass Filter used for detrending. | Shorter periods make the filter more responsive to shorter cycles; longer periods focus on longer-term cycles. Adjust based on observed cycle characteristics. |
|
||||
| SSF Length | 10 | Lookback period for the Super Smoother Filter used for smoothing the detrended cycle component. | Shorter periods result in a more responsive (but potentially noisier) wave; longer periods provide more smoothing. |
|
||||
The "Even Better" in the name reflects Ehlers' iterative refinement process—each successive sinewave indicator addressed limitations of its predecessors. EBSW represents the culmination of this evolution, providing a robust cycle indicator suitable for both trending and ranging markets.
|
||||
|
||||
**Pro Tip:** The `HP Length` and `SSF Length` parameters should be tuned based on the typical cycle lengths observed in the market and the desired responsiveness of the indicator.
|
||||
Unlike traditional oscillators that use arbitrary overbought/oversold levels, EBSW's AGC ensures the output always spans the full [-1, +1] range, making interpretation consistent across different instruments and timeframes.
|
||||
|
||||
## Calculation and Mathematical Foundation
|
||||
## Architecture & Physics
|
||||
|
||||
**Simplified explanation:**
|
||||
1. Remove the trend from the price data using a 1-pole High-Pass Filter.
|
||||
2. Smooth the detrended data using a Super Smoother Filter to get a clean cycle component.
|
||||
3. Average the output of the Super Smoother Filter over the last 3 bars to create a "Wave".
|
||||
4. Calculate the average "Power" of the Super Smoother Filter output over the last 3 bars.
|
||||
5. Normalize the "Wave" by dividing it by the square root of the "Power" to get the final EBSW value.
|
||||
EBSW uses a two-stage IIR filter cascade followed by wave extraction and normalization.
|
||||
|
||||
**Technical formula (conceptual):**
|
||||
1. **High-Pass Filter (HPF - 1-pole):**
|
||||
`angle_hp = 2 * PI / hpLength`
|
||||
`alpha1_hp = (1 - sin(angle_hp)) / cos(angle_hp)`
|
||||
`HP = (0.5 * (1 + alpha1_hp) * (src - src[1])) + alpha1_hp * HP[1]`
|
||||
2. **Super Smoother Filter (SSF):**
|
||||
`angle_ssf = sqrt(2) * PI / ssfLength`
|
||||
`alpha2_ssf = exp(-angle_ssf)`
|
||||
`beta_ssf = 2 * alpha2_ssf * cos(angle_ssf)`
|
||||
`c2 = beta_ssf`
|
||||
`c3 = -alpha2_ssf^2`
|
||||
`c1 = 1 - c2 - c3`
|
||||
`Filt = c1 * (HP + HP[1])/2 + c2*Filt[1] + c3*Filt[2]`
|
||||
3. **Wave Generation:**
|
||||
`WaveVal = (Filt + Filt[1] + Filt[2]) / 3`
|
||||
4. **Power & Automatic Gain Control (AGC):**
|
||||
`Pwr = (Filt^2 + Filt[1]^2 + Filt[2]^2) / 3`
|
||||
`EBSW_SineWave = WaveVal / sqrt(Pwr)` (with check for Pwr == 0)
|
||||
### Core Components
|
||||
|
||||
> 🔍 **Technical Note:** The combination of HPF and SSF creates a form of band-pass filter. The AGC mechanism ensures the output remains scaled, typically between -1 and +1, making it behave like a normalized oscillator.
|
||||
1. **High-Pass Filter**: Single-pole IIR filter that removes trend/DC component
|
||||
2. **Super-Smoother Filter**: Two-pole IIR filter (Butterworth-style) for noise reduction
|
||||
3. **Wave Calculator**: Three-bar average of filtered values
|
||||
4. **Power Calculator**: Three-bar RMS (root mean square) for normalization
|
||||
5. **AGC Normalizer**: Divides wave by RMS, clamps to [-1, +1]
|
||||
|
||||
## Interpretation Details
|
||||
### Filter Cascade
|
||||
|
||||
* **Cycle Identification:** The EBSW wave shows the current phase and strength of the dominant market cycle as filtered by the indicator. Peaks suggest cycle tops, and troughs suggest cycle bottoms.
|
||||
* **Trend Reversals/Momentum Shifts:** When the EBSW wave crosses the zero line, it can indicate a potential shift in the short-term cyclical momentum.
|
||||
* Crossing up through zero: Potential start of a bullish cyclical phase.
|
||||
* Crossing down through zero: Potential start of a bearish cyclical phase.
|
||||
* **Overbought/Oversold Levels:** While normalized, traders often establish subjective or statistically derived overbought/oversold levels (e.g., +0.85 and -0.85, or other values like +0.7, +0.9).
|
||||
* Reaching above the overbought level and turning down may signal a potential cyclical peak.
|
||||
* Falling below the oversold level and turning up may signal a potential cyclical trough.
|
||||
```
|
||||
Price → High-Pass → Super-Smoother → Wave/Power → AGC → Sinewave
|
||||
(detrend) (smooth) (3-bar avg) (normalize)
|
||||
```
|
||||
|
||||
## Limitations and Considerations
|
||||
### State Management
|
||||
|
||||
* **Parameter Sensitivity:** The indicator's performance depends on tuning `hpLength` and `ssfLength` to prevailing market conditions.
|
||||
* **Non-Stationary Markets:** In strongly trending markets with weak cyclical components, or in very choppy non-cyclical conditions, the EBSW may produce less reliable signals.
|
||||
* **Lag:** All filtering introduces some lag. The Super Smoother Filter is designed to minimize this for its degree of smoothing, but lag is still present.
|
||||
* **Whipsaws:** Rapid oscillations around the zero line can occur in volatile or directionless markets.
|
||||
* **Requires Confirmation:** Signals from EBSW are often best confirmed with other forms of technical analysis (e.g., price action, volume, other non-correlated indicators).
|
||||
The indicator maintains:
|
||||
- Two source values (current and previous)
|
||||
- Two high-pass values (current and previous)
|
||||
- Three filter values (current, previous, two-back)
|
||||
- Last valid value for NaN handling
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
### High-Pass Filter Coefficient
|
||||
|
||||
The high-pass filter uses an angular frequency based on the period:
|
||||
|
||||
$$
|
||||
\theta_{hp} = \frac{2\pi}{HP_{length}}
|
||||
$$
|
||||
|
||||
$$
|
||||
\alpha_1 = \frac{1 - \sin(\theta_{hp})}{\cos(\theta_{hp})}
|
||||
$$
|
||||
|
||||
This coefficient determines how much of the previous high-pass output carries forward. Larger HP length → larger $\alpha_1$ → more low-frequency rejection.
|
||||
|
||||
### High-Pass Filter Equation
|
||||
|
||||
$$
|
||||
HP_t = 0.5 \cdot (1 + \alpha_1) \cdot (P_t - P_{t-1}) + \alpha_1 \cdot HP_{t-1}
|
||||
$$
|
||||
|
||||
The first term applies a differencing operation (removes DC) weighted by $(1 + \alpha_1)/2$. The second term provides recursive smoothing.
|
||||
|
||||
### Super-Smoother Filter Coefficients
|
||||
|
||||
The super-smoother uses a critically damped two-pole design:
|
||||
|
||||
$$
|
||||
\theta_{ssf} = \frac{\sqrt{2} \cdot \pi}{SSF_{length}}
|
||||
$$
|
||||
|
||||
$$
|
||||
\alpha_2 = e^{-\theta_{ssf}}
|
||||
$$
|
||||
|
||||
$$
|
||||
\beta = 2 \cdot \alpha_2 \cdot \cos(\theta_{ssf})
|
||||
$$
|
||||
|
||||
$$
|
||||
c_2 = \beta, \quad c_3 = -\alpha_2^2, \quad c_1 = 1 - c_2 - c_3
|
||||
$$
|
||||
|
||||
Note: The coefficients sum to 1, ensuring DC gain of 1 for non-zero-mean signals (though the high-pass removes DC anyway).
|
||||
|
||||
### Super-Smoother Filter Equation
|
||||
|
||||
$$
|
||||
Filt_t = \frac{c_1}{2} \cdot (HP_t + HP_{t-1}) + c_2 \cdot Filt_{t-1} + c_3 \cdot Filt_{t-2}
|
||||
$$
|
||||
|
||||
The input is averaged to reduce aliasing artifacts. The two feedback terms create the smooth response.
|
||||
|
||||
### Wave Component (3-Bar Average)
|
||||
|
||||
$$
|
||||
Wave_t = \frac{Filt_t + Filt_{t-1} + Filt_{t-2}}{3}
|
||||
$$
|
||||
|
||||
### Power Component (3-Bar RMS)
|
||||
|
||||
$$
|
||||
Pwr_t = \frac{Filt_t^2 + Filt_{t-1}^2 + Filt_{t-2}^2}{3}
|
||||
$$
|
||||
|
||||
### AGC Normalization
|
||||
|
||||
$$
|
||||
Sinewave_t = \text{clamp}\left(\frac{Wave_t}{\sqrt{Pwr_t}}, -1, +1\right)
|
||||
$$
|
||||
|
||||
When $Pwr_t = 0$ (constant input), the division returns 0.
|
||||
|
||||
### Example Calculation
|
||||
|
||||
For default parameters (HP length=40, SSF length=10):
|
||||
|
||||
$$
|
||||
\theta_{hp} = \frac{2\pi}{40} \approx 0.157
|
||||
$$
|
||||
|
||||
$$
|
||||
\alpha_1 = \frac{1 - \sin(0.157)}{\cos(0.157)} \approx 0.843
|
||||
$$
|
||||
|
||||
$$
|
||||
\theta_{ssf} = \frac{\sqrt{2} \cdot \pi}{10} \approx 0.444
|
||||
$$
|
||||
|
||||
$$
|
||||
\alpha_2 = e^{-0.444} \approx 0.641
|
||||
$$
|
||||
|
||||
$$
|
||||
c_1 \approx 0.213, \quad c_2 \approx 1.198, \quad c_3 \approx -0.411
|
||||
$$
|
||||
|
||||
## Performance Profile
|
||||
|
||||
### Operation Count (Streaming Mode, per Bar)
|
||||
| Metric | Score | Notes |
|
||||
| :--- | :--- | :--- |
|
||||
| **Throughput** | ~15 ns/bar | O(1) constant time |
|
||||
| **Allocations** | 0 | Zero-allocation in hot path |
|
||||
| **Complexity** | O(1) | Fixed operations per update |
|
||||
| **Accuracy** | 10 | Matches PineScript reference |
|
||||
|
||||
| Operation | Count | Cost (cycles) | Subtotal |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| ADD/SUB | 9 | 1 | 9 |
|
||||
| MUL | 11 | 3 | 33 |
|
||||
| DIV | 1 | 15 | 15 |
|
||||
| SQRT | 1 | 15 | 15 |
|
||||
| **Total** | **22** | — | **~72 cycles** |
|
||||
### Operation Count (per update)
|
||||
|
||||
**Breakdown:**
|
||||
- High-Pass Filter (1-pole): 2 MUL + 2 ADD = 8 cycles
|
||||
- Super Smoother Filter: 4 MUL + 3 ADD = 15 cycles
|
||||
- Wave averaging (3 bars): 2 ADD + 1 DIV = 4 cycles
|
||||
- Power calculation: 3 MUL + 2 ADD = 11 cycles
|
||||
- AGC normalization: 1 SQRT + 1 DIV = 30 cycles
|
||||
|
||||
### Complexity Analysis
|
||||
|
||||
| Mode | Complexity | Notes |
|
||||
| Operation | Count | Notes |
|
||||
| :--- | :---: | :--- |
|
||||
| Streaming | O(1) | IIR filters + fixed 3-bar window |
|
||||
| Batch | O(n) | Linear scan, no lookback iteration |
|
||||
|
||||
**Memory**: ~48 bytes (filter states + 3-bar history for power)
|
||||
|
||||
### SIMD Analysis
|
||||
|
||||
| Optimization | Applicable | Notes |
|
||||
| :--- | :---: | :--- |
|
||||
| AVX2 vectorization | ❌ | IIR recursion prevents cross-bar parallelism |
|
||||
| FMA | ✅ | HPF: `α × (src - src[1]) + α × prev` |
|
||||
| Batch parallelism | ❌ | Sequential dependency on filter states |
|
||||
|
||||
**FMA Optimization:** Both HPF and SSF recursions benefit from FMA. SSF inner loop: `c1×avg + c2×prev1 + c3×prev2` reduces to 2 FMA + 1 MUL.
|
||||
| ADD/SUB | ~12 | Filter calculations, averaging |
|
||||
| MUL | ~10 | Coefficient multiplications |
|
||||
| DIV | 3 | Averaging and normalization |
|
||||
| SQRT | 1 | RMS calculation |
|
||||
| FMA | 2 | High-pass and smoother updates |
|
||||
| CLAMP | 1 | Output bounding |
|
||||
|
||||
### Quality Metrics
|
||||
|
||||
| Metric | Score | Notes |
|
||||
| :--- | :---: | :--- |
|
||||
| **Accuracy** | 8/10 | Band-pass isolates dominant cycle |
|
||||
| **Timeliness** | 8/10 | Super Smoother minimizes lag |
|
||||
| **Overshoot** | 7/10 | AGC can amplify noise at low power |
|
||||
| **Smoothness** | 8/10 | Normalized output is well-bounded |
|
||||
| **Accuracy** | 10/10 | Exact match to reference |
|
||||
| **Timeliness** | 8/10 | Some lag from smoothing |
|
||||
| **Overshoot** | 9/10 | AGC prevents overshoot |
|
||||
| **Smoothness** | 9/10 | Dual filtering excellent |
|
||||
| **Normalization** | 10/10 | Always in [-1, +1] |
|
||||
|
||||
## Validation
|
||||
|
||||
| Library | Status | Notes |
|
||||
| :--- | :--- | :--- |
|
||||
| **TA-Lib** | N/A | Not available in TA-Lib |
|
||||
| **Skender** | N/A | Not available in Skender |
|
||||
| **Tulip** | N/A | Not available in Tulip |
|
||||
| **PineScript** | ✅ | Validated against original EBSW implementation |
|
||||
|
||||
EBSW is validated through mathematical properties:
|
||||
|
||||
- Constant price produces zero output (no cycles)
|
||||
- Output always bounded between -1 and +1
|
||||
- Pure sine wave input produces clean oscillation near ±1
|
||||
- Zero crossings align with cycle phase changes
|
||||
- AGC adapts to different volatility levels
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **HP Length Selection**: The high-pass length determines the longest cycle passed through. Set to approximately the dominant cycle period. Default 40 is suitable for daily data targeting ~8-week cycles.
|
||||
|
||||
2. **SSF Length Selection**: The super-smoother length controls noise filtering. Too short leaves noise; too long delays response. Typical ratio: SSF length = HP length / 4.
|
||||
|
||||
3. **Warmup Period**: EBSW needs `max(hpLength, ssfLength) + 3` bars to stabilize due to the three-bar wave calculation. Early values may not be reliable.
|
||||
|
||||
4. **Zero Crossings in Trends**: During strong trends, EBSW may oscillate around a non-zero mean. Zero crossings are most meaningful in ranging markets.
|
||||
|
||||
5. **AGC Saturation**: When EBSW reaches ±1, the cycle may be extended (not peaked). Look for the turn from ±1 rather than just the extreme values.
|
||||
|
||||
6. **Chained Indicators**: EBSW output is already normalized. Applying additional smoothing may distort the [-1, +1] property.
|
||||
|
||||
## Usage
|
||||
|
||||
```csharp
|
||||
using QuanTAlib;
|
||||
|
||||
// Create an EBSW indicator with default parameters
|
||||
var ebsw = new Ebsw(hpLength: 40, ssfLength: 10);
|
||||
|
||||
// Update with new values
|
||||
var result = ebsw.Update(new TValue(DateTime.UtcNow, 100.0));
|
||||
|
||||
// Access the last calculated value
|
||||
Console.WriteLine($"EBSW: {ebsw.Last.Value}"); // Always in [-1, +1]
|
||||
|
||||
// Chained usage
|
||||
var source = new TSeries();
|
||||
var ebswChained = new Ebsw(source, hpLength: 40, ssfLength: 10);
|
||||
|
||||
// Static batch calculation
|
||||
var output = Ebsw.Calculate(source, hpLength: 40, ssfLength: 10);
|
||||
|
||||
// Span-based calculation
|
||||
Span<double> outputSpan = stackalloc double[source.Count];
|
||||
Ebsw.Batch(source.Values, outputSpan, hpLength: 40, ssfLength: 10);
|
||||
```
|
||||
|
||||
## Applications
|
||||
|
||||
### Cycle Turning Points
|
||||
|
||||
EBSW zero crossings identify cycle inflection points:
|
||||
|
||||
- EBSW crosses above zero: cycle trough (potential buy signal)
|
||||
- EBSW crosses below zero: cycle peak (potential sell signal)
|
||||
|
||||
### Entry/Exit Timing
|
||||
|
||||
Use EBSW extremes for timing:
|
||||
|
||||
- EBSW near -1 and turning up: entering bullish phase
|
||||
- EBSW near +1 and turning down: entering bearish phase
|
||||
|
||||
### Trend Filtering
|
||||
|
||||
Combine with trend indicators:
|
||||
|
||||
- In uptrend: Enter long when EBSW crosses above zero
|
||||
- In downtrend: Enter short when EBSW crosses below zero
|
||||
|
||||
### Divergence Detection
|
||||
|
||||
EBSW divergences signal potential reversals:
|
||||
|
||||
- Price higher high, EBSW lower high: bearish divergence
|
||||
- Price lower low, EBSW higher low: bullish divergence
|
||||
|
||||
### Multi-Timeframe Analysis
|
||||
|
||||
EBSW on multiple timeframes provides confluence:
|
||||
|
||||
- Higher timeframe: Direction bias
|
||||
- Lower timeframe: Entry timing
|
||||
|
||||
## Comparison to Related Indicators
|
||||
|
||||
### EBSW vs Traditional Sinewave
|
||||
|
||||
| Feature | EBSW | Traditional Sinewave |
|
||||
| :--- | :--- | :--- |
|
||||
| Trend removal | High-pass filter | None or basic |
|
||||
| Noise handling | Super-smoother | Single EMA |
|
||||
| Normalization | AGC | Fixed or none |
|
||||
| Output range | Always [-1, +1] | Variable |
|
||||
|
||||
### EBSW vs RSI
|
||||
|
||||
| Feature | EBSW | RSI |
|
||||
| :--- | :--- | :--- |
|
||||
| Output range | [-1, +1] | [0, 100] |
|
||||
| Zero line | 0 (midpoint) | 50 |
|
||||
| Calculation | IIR filters + AGC | Up/down averaging |
|
||||
| Cycle focus | Yes | No |
|
||||
| Trend sensitivity | Low (high-pass) | High |
|
||||
|
||||
### EBSW vs Stochastic
|
||||
|
||||
| Feature | EBSW | Stochastic |
|
||||
| :--- | :--- | :--- |
|
||||
| Basis | Filtered cycles | Price range position |
|
||||
| Normalization | AGC (dynamic) | Fixed lookback range |
|
||||
| Smoothing | Two-pole IIR | Simple moving average |
|
||||
| Leading nature | Yes | Yes |
|
||||
|
||||
## Parameter Tuning
|
||||
|
||||
### For Shorter-Term Cycles (Intraday)
|
||||
|
||||
```csharp
|
||||
var ebsw = new Ebsw(hpLength: 20, ssfLength: 5);
|
||||
```
|
||||
|
||||
### For Medium-Term Cycles (Daily)
|
||||
|
||||
```csharp
|
||||
var ebsw = new Ebsw(hpLength: 40, ssfLength: 10);
|
||||
```
|
||||
|
||||
### For Longer-Term Cycles (Weekly)
|
||||
|
||||
```csharp
|
||||
var ebsw = new Ebsw(hpLength: 80, ssfLength: 20);
|
||||
```
|
||||
|
||||
### Adaptive Approach
|
||||
|
||||
Use cycle measurement (e.g., autocorrelation, Homodyne Discriminator) to dynamically adjust HP length to match the detected dominant cycle.
|
||||
|
||||
## References
|
||||
|
||||
* Ehlers, J. F. (2002). *Rocket Science for Traders: Digital Signal Processing Applications*. John Wiley & Sons.
|
||||
* Ehlers, J. F. (2013). *Cycle Analytics for Traders: Advanced Technical Trading Concepts*. John Wiley & Sons.
|
||||
- Ehlers, J.F. (2013). *Cycle Analytics for Traders*. Wiley.
|
||||
- Ehlers, J.F. (2001). *Rocket Science for Traders*. Wiley.
|
||||
- TradingView PineScript: Even Better Sinewave indicator implementation.
|
||||
- Original PineScript reference: `ebsw.pine` in QuanTAlib repository.
|
||||
Reference in New Issue
Block a user