2026-02-05 19:42:49 -08:00
# SSFDSP: SSF-Based Detrended Synthetic Price
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
> "The Super-Smoother filter provides Butterworth-quality noise rejection—combine two of them and you isolate cycles with surgical precision."
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
The SSF-Based Detrended Synthetic Price (SSFDSP) is an advanced oscillator by John Ehlers. It creates a synthetic, detrended price series by subtracting a half-cycle Super-Smoother from a quarter-cycle Super-Smoother, providing superior noise rejection and reduced lag compared to EMA-based DSP.
2026-02-04 20:58:05 -08:00
## Historical Context
2026-02-05 19:42:49 -08:00
Ehlers introduced the concept of "Synthetic Price" to remove the DC (trend) component from market data, isolating cyclic energy. While earlier versions used EMAs, the SSF variant exploits the 2-pole Butterworth characteristics of the Super-Smoother Filter to achieve cleaner separation between trend and cycle.
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
The SSF provides zero phase lag at the cutoff frequency, making it ideal for cycle isolation in noisy market data.
2026-02-04 20:58:05 -08:00
## Architecture & Physics
2026-02-05 19:42:49 -08:00
The indicator computes the difference between two Super-Smoother filters tuned to fractions of the dominant cycle period.
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
### 1. Filter Periods
2026-02-04 20:58:05 -08:00
$$
2026-02-05 19:42:49 -08:00
P_{fast} = \max(2, \text{round}(P / 4))
2026-02-04 20:58:05 -08:00
$$
$$
2026-02-05 19:42:49 -08:00
P_{slow} = \max(3, \text{round}(P / 2))
2026-02-04 20:58:05 -08:00
$$
2026-02-05 19:42:49 -08:00
### 2. Super-Smoother Coefficients
2026-02-04 20:58:05 -08:00
$$
2026-02-05 19:42:49 -08:00
\alpha = \frac{\pi\sqrt{2}}{period}
2026-02-04 20:58:05 -08:00
$$
$$
2026-02-05 19:42:49 -08:00
c_2 = 2e^{-\alpha}\cos(\alpha)
2026-02-04 20:58:05 -08:00
$$
$$
2026-02-05 19:42:49 -08:00
c_3 = -e^{-2\alpha}
2026-02-04 20:58:05 -08:00
$$
$$
c_1 = 1 - c_2 - c_3
$$
2026-02-05 19:42:49 -08:00
### 3. SSF Recursion
2026-02-04 20:58:05 -08:00
$$
2026-02-05 19:42:49 -08:00
SSF_t = c_1 \cdot \frac{P_t + P_{t-1}}{2} + c_2 \cdot SSF_{t-1} + c_3 \cdot SSF_{t-2}
2026-02-04 20:58:05 -08:00
$$
2026-02-05 19:42:49 -08:00
### 4. SSFDSP Output
2026-02-04 20:58:05 -08:00
$$
2026-02-05 19:42:49 -08:00
SSFDSP = SSF_{fast} - SSF_{slow}
2026-02-04 20:58:05 -08:00
$$
## Performance Profile
2026-02-05 19:42:49 -08:00
### Operation Count (Streaming Mode, per Bar)
2026-02-04 20:58:05 -08:00
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
2026-02-05 19:42:49 -08:00
| FMA (SSF updates) | 4 | 4 | 16 |
| MUL (coefficients) | 2 | 3 | 6 |
| ADD/SUB (input avg, output) | 3 | 1 | 3 |
| **Total** | **9** | — | ** ~25 cycles** |
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
### Complexity Analysis
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
- **Streaming:** O(1) per bar—fixed 2-pole IIR filters
- **Memory:** O(1)—only filter state variables
- **Warmup:** ~2 × slow period for convergence
- **Note:** Recursive dependencies prevent SIMD vectorization
2026-02-04 20:58:05 -08:00
## Validation
| Library | Status | Notes |
| :--- | :---: | :--- |
2026-02-05 19:42:49 -08:00
| TA-Lib | N/A | Not standard |
| Skender | N/A | Not standard |
| PineScript | ✅ | Matches Ehlers' reference logic |
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
## Usage & Pitfalls
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
- **Oscillates around zero**—positive values indicate bullish cycle phase
- **Zero crossings** signal cycle phase changes—entry points in direction of cross
- **Period mismatch** degrades amplitude and phase accuracy
- **Smoother than EMA-DSP** with sharper turning points
- **Divergence** (price highs vs DSP highs) indicates trend exhaustion
- **Pre-smooth input** for extremely noisy data
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
## API
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
```mermaid
classDiagram
class Ssfdsp {
+int Period
+double Value
+bool IsHot
+Ssfdsp(int period)
+Ssfdsp(ITValuePublisher source, int period)
+TValue Update(TValue input, bool isNew)
+void Reset()
}
```
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
### Class: `Ssfdsp`
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
| Parameter | Type | Default | Range | Description |
| :--- | :--- | :--- | :--- | :--- |
| `period` | `int` | `40` | `≥4` | Expected dominant cycle period |
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
### Properties
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
- `Value` (`double` ): The current SSFDSP value (oscillates around 0)
- `IsHot` (`bool` ): Returns `true` when warmup is complete
2026-02-04 20:58:05 -08:00
2026-02-05 19:42:49 -08:00
### Methods
- `Update(TValue input, bool isNew)` : Updates the indicator with a new data point
## C# Example
2026-02-04 20:58:05 -08:00
```csharp
2026-02-05 19:42:49 -08:00
using QuanTAlib ;
// Initialize with a 40-bar dominant cycle assumption
var ssfdsp = new Ssfdsp ( period : 40 );
// Update with streaming data
foreach ( var bar in quotes )
2026-02-04 20:58:05 -08:00
{
2026-02-05 19:42:49 -08:00
var result = ssfdsp . Update ( new TValue ( bar . Date , bar . Close ));
2026-02-04 20:58:05 -08:00
if ( ssfdsp . IsHot )
{
2026-02-05 19:42:49 -08:00
Console . WriteLine ( $"{bar.Date}: SSF-DSP = {result.Value:F4}" );
// Zero crossing detection
if ( result . Value > 0 && ssfdsp . Previous . Value <= 0 )
Console . WriteLine ( " → Bullish cycle phase" );
else if ( result . Value < 0 && ssfdsp . Previous . Value >= 0 )
Console . WriteLine ( " → Bearish cycle phase" );
2026-02-04 20:58:05 -08:00
}
}
2026-02-05 19:42:49 -08:00
// Batch calculation
var output = Ssfdsp . Calculate ( sourceSeries , period : 40 );
2026-02-04 20:58:05 -08:00
```