mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-22 04:28:04 +00:00
feat: Enhance volume indicators with ADOSC and SSF implementation and validation
This commit is contained in:
+34
-107
@@ -1,130 +1,57 @@
|
||||
# TEMA: Triple Exponential Moving Average
|
||||
|
||||
## What It Does
|
||||
> "Patrick Mulloy looked at the lag of an EMA and took it personally. TEMA is what happens when you apply algebra to impatience."
|
||||
|
||||
The Triple Exponential Moving Average (TEMA) is a technical indicator designed to smooth price data while virtually eliminating the lag associated with traditional moving averages. By combining a single, double, and triple Exponential Moving Average (EMA), TEMA creates a composite line that tracks price action with remarkable speed and accuracy.
|
||||
The Triple Exponential Moving Average (TEMA) is a lag-reducing filter that combines a single, double, and triple EMA. Unlike a simple triple smoothing (which would be incredibly slow), TEMA uses a weighted combination of the three to cancel out the lag, resulting in an indicator that hugs price action tighter than a spandex cycling short.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Developed by Patrick Mulloy and introduced in his 1994 article "Smoothing Data with Faster Moving Averages" in *Technical Analysis of Stocks & Commodities*, TEMA was created alongside DEMA (Double EMA) to solve the persistent problem of lag in trend-following indicators. Mulloy's innovation was to use the lag inherent in multiple EMA calculations to estimate and subtract the total lag from the original signal.
|
||||
Introduced by Patrick Mulloy in *Technical Analysis of Stocks & Commodities* (Jan 1994), "Smoothing Data With Less Lag." Mulloy's goal was to replace the standard moving averages in MACD and other indicators to reduce the delay in signal generation.
|
||||
|
||||
## How It Works
|
||||
## Architecture & Physics
|
||||
|
||||
### The Core Idea
|
||||
TEMA is not just "EMA applied three times." That would be $EMA(EMA(EMA(x)))$. TEMA is a composite:
|
||||
$$ TEMA = 3 \cdot EMA_1 - 3 \cdot EMA_2 + EMA_3 $$
|
||||
|
||||
TEMA is not just "an EMA of an EMA of an EMA" (which would be very slow). Instead, it uses a clever formula to cancel out lag:
|
||||
This formula effectively projects the trend forward to compensate for the delay inherent in smoothing.
|
||||
|
||||
- $EMA_1$ has some lag.
|
||||
- $EMA_2$ (EMA of EMA) has roughly double the lag.
|
||||
- $EMA_3$ (EMA of EMA of EMA) has roughly triple the lag.
|
||||
### Convergence Speed
|
||||
|
||||
By combining these terms with specific weights ($3 \times EMA_1 - 3 \times EMA_2 + EMA_3$), the lag terms cancel out, leaving a moving average that hugs the price closely.
|
||||
Because of the aggressive weighting, TEMA converges (warms up) faster than a standard EMA. While an EMA takes $\approx 3.45(N+1)$ steps to converge to 99.9%, TEMA stabilizes quicker due to the subtraction terms canceling out the initial error.
|
||||
|
||||
### Mathematical Foundation
|
||||
## Mathematical Foundation
|
||||
|
||||
### 1. The Cascade
|
||||
|
||||
$$ EMA_1 = EMA(Price) $$
|
||||
$$ EMA_2 = EMA(EMA_1) $$
|
||||
$$ EMA_3 = EMA(EMA_2) $$
|
||||
|
||||
### 2. The Combination
|
||||
|
||||
$$ TEMA = (3 \times EMA_1) - (3 \times EMA_2) + EMA_3 $$
|
||||
|
||||
Where:
|
||||
|
||||
- $EMA_1 = EMA(Price)$
|
||||
- $EMA_2 = EMA(EMA_1)$
|
||||
- $EMA_3 = EMA(EMA_2)$
|
||||
|
||||
### Implementation Details
|
||||
|
||||
Our implementation uses three internal EMA instances.
|
||||
|
||||
- **Complexity:** O(1) per update.
|
||||
- **Initialization:** We use Hunter's method for initializing the underlying EMAs to ensure the TEMA starts with valid values as early as possible.
|
||||
|
||||
## Configuration
|
||||
|
||||
| Parameter | Default | Purpose | Adjustment Guidelines |
|
||||
|-----------|---------|---------|----------------------|
|
||||
| Period | 14 | Lookback window | Short (5-10) for scalping; Medium (20-50) for swing trading. |
|
||||
|
||||
## Performance Profile
|
||||
|
||||
| Operation | Complexity | Description |
|
||||
|-----------|------------|-------------------|
|
||||
| Streaming update | O(1) | 3 EMA updates + scalar math |
|
||||
| Bar correction | O(1) | Efficient state rollback |
|
||||
| Batch processing | O(N) | Single pass through data |
|
||||
| Memory footprint | O(1) | Stores state for 3 internal EMAs |
|
||||
### Zero-Allocation Design
|
||||
|
||||
## Interpretation
|
||||
QuanTAlib's `Tema` implementation does not create three separate `Ema` objects. Instead, it maintains three lightweight `EmaState` structs within the main class. This ensures zero heap allocations during updates and keeps the memory footprint minimal.
|
||||
|
||||
### Trading Signals
|
||||
| Metric | Score | Notes |
|
||||
| :--- | :--- | :--- |
|
||||
| **Throughput** | High | 3 EMAs |
|
||||
| **Complexity** | O(1) | Constant time update |
|
||||
| **Accuracy** | 8/10 | Extremely responsive to turns |
|
||||
| **Timeliness** | 9/10 | Near-zero lag (Lag ≈ 0) |
|
||||
| **Overshoot** | 4/10 | Significant overshoot on reversals |
|
||||
| **Smoothness** | 7/10 | Smoother than DEMA, less than T3 |
|
||||
|
||||
#### Trend Direction
|
||||
## Validation
|
||||
|
||||
- **Fast Response:** TEMA turns much faster than SMA or EMA. A turn in TEMA often precedes a turn in price trend.
|
||||
Validated against TA-Lib (`TA_TEMA`) and Skender.Stock.Indicators.
|
||||
|
||||
#### Crossovers
|
||||
### Common Pitfalls
|
||||
|
||||
- **Price Crossover:** Because TEMA hugs price so closely, crossovers are frequent. They are best used for short-term entries in the direction of a larger trend.
|
||||
|
||||
### When It Works Best
|
||||
|
||||
- **Momentum Trading:** TEMA is excellent for capturing short-term bursts of momentum.
|
||||
|
||||
### When It Struggles
|
||||
|
||||
- **Overshoot:** In a sudden V-shaped reversal, TEMA can "overshoot" the price briefly due to the momentum of its internal calculation components.
|
||||
|
||||
## Architecture Notes
|
||||
|
||||
This implementation makes specific trade-offs:
|
||||
|
||||
### Choice: Composition
|
||||
|
||||
- **Implementation:** Composed of 3 `Ema` objects.
|
||||
- **Rationale:** Reusing the robust `Ema` class ensures consistent behavior (like initialization and NaN handling) across the library.
|
||||
|
||||
## References
|
||||
|
||||
- Mulloy, Patrick G. "Smoothing Data with Faster Moving Averages." *Technical Analysis of Stocks & Commodities*, Jan 1994.
|
||||
|
||||
## C# Usage
|
||||
|
||||
### Streaming Updates (Single Instance)
|
||||
|
||||
```csharp
|
||||
using QuanTAlib;
|
||||
|
||||
var tema = new Tema(period: 14);
|
||||
|
||||
// Process each new bar
|
||||
TValue result = tema.Update(new TValue(timestamp, closePrice));
|
||||
Console.WriteLine($"TEMA: {result.Value:F2}");
|
||||
|
||||
// Check if buffer is full
|
||||
if (tema.IsHot)
|
||||
{
|
||||
// Indicator is fully initialized
|
||||
}
|
||||
```
|
||||
|
||||
### Batch Processing (Historical Data)
|
||||
|
||||
```csharp
|
||||
// TSeries API
|
||||
TSeries prices = ...;
|
||||
TSeries temaValues = Tema.Batch(prices, period: 14);
|
||||
|
||||
// Span API (High Performance)
|
||||
double[] prices = new double[1000];
|
||||
double[] output = new double[1000];
|
||||
Tema.Calculate(prices.AsSpan(), output.AsSpan(), period: 14);
|
||||
```
|
||||
|
||||
### Bar Correction (isNew Parameter)
|
||||
|
||||
```csharp
|
||||
var tema = new Tema(14);
|
||||
|
||||
// New bar
|
||||
tema.Update(new TValue(time, 100), isNew: true);
|
||||
|
||||
// Intra-bar update
|
||||
tema.Update(new TValue(time, 101), isNew: false); // Replaces 100 with 101
|
||||
1. **Overshoot**: TEMA is so responsive it can overshoot price turns, creating a "whiplash" effect in volatile markets.
|
||||
2. **Noise**: By reducing lag, TEMA sacrifices some noise suppression. It is "nervous" compared to an SMA.
|
||||
3. **Identity Crisis**: Often confused with T3 (Tillson). T3 is a generalized version; TEMA is specifically T3 with $v=1$.
|
||||
|
||||
Reference in New Issue
Block a user