EMA Deviation Corrected T3
period = 10 | hot = 0.7 | t3_mode = 0 Overview
EMA Deviation Corrected T3 is a two-line overlay that starts from a classic multi-stage T3 smoothing chain and then adds a second line designed to correct for the amount of deviation that line can support. The base output is the T3 itself. The companion corrected line compares the current T3 value against a rolling EMA-based estimate of price variance and only lets the correction expand when the gap is large enough to justify it.
In practice, that means the page documents two related overlays rather than one. The T3 line gives you the raw smoothed trend estimate, while the corrected line tries to keep that trend estimate from overreacting when the move is already well explained by recent variance. Candle mode defaults to `close`, and unlike many longer-cycle studies this implementation starts producing finite output immediately from the first valid value.
Defaults: EMA Deviation Corrected T3 uses `period = 10`, `hot = 0.7`, `t3_mode = 0`, and defaults candle input to `close`.
Implementation Examples
Compute both the corrected overlay and the baseline T3 line from a slice or candle closes.
use vector_ta::indicators::moving_averages::ema_deviation_corrected_t3::{
ema_deviation_corrected_t3,
EmaDeviationCorrectedT3Input,
EmaDeviationCorrectedT3Params,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let values = vec![100.0, 100.5, 101.1, 101.8, 101.4, 102.0, 102.6];
let output = ema_deviation_corrected_t3(
&EmaDeviationCorrectedT3Input::from_slice(
&values,
EmaDeviationCorrectedT3Params {
period: Some(10),
hot: Some(0.7),
t3_mode: Some(0),
},
)
)?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = ema_deviation_corrected_t3(
&EmaDeviationCorrectedT3Input::with_default_candles(&candles)
)?;
println!("corrected = {:?}", output.corrected.last());
println!("t3 = {:?}", candle_output.t3.last()); API Reference
Input Methods ▼
// From candles and a named source field
EmaDeviationCorrectedT3Input::from_candles(
&Candles,
&str,
EmaDeviationCorrectedT3Params,
) -> EmaDeviationCorrectedT3Input
// From a raw slice
EmaDeviationCorrectedT3Input::from_slice(&[f64], EmaDeviationCorrectedT3Params)
-> EmaDeviationCorrectedT3Input
// From candles with default parameters
EmaDeviationCorrectedT3Input::with_default_candles(&Candles)
-> EmaDeviationCorrectedT3Input Parameters Structure ▼
pub struct EmaDeviationCorrectedT3Params {
pub period: Option<usize>, // default 10
pub hot: Option<f64>, // default 0.7
pub t3_mode: Option<usize>, // default 0
} Output Structure ▼
pub struct EmaDeviationCorrectedT3Output {
pub corrected: Vec<f64>,
pub t3: Vec<f64>,
} Validation, Warmup & NaNs ▼
- The input slice must be non-empty and contain at least one finite value.
periodmust be valid for the supplied data length.hotmust be finite and valid for the T3 coefficient calculation.t3_modemust be a supported integer mode for the alpha calculation path.- There is no long warmup gate here: the first finite input produces finite T3 and corrected outputs immediately.
- Streaming returns
Nonefor non-finite input and resets its internal state when that happens. - Batch mode validates both integer and floating-point ranges and rejects unsupported non-batch kernels.
Builder, Streaming & Batch APIs ▼
// Builder
EmaDeviationCorrectedT3Builder::new()
.period(usize)
.hot(f64)
.t3_mode(usize)
.kernel(Kernel)
.apply_slice(&[f64])
EmaDeviationCorrectedT3Builder::new()
.apply(&Candles)
EmaDeviationCorrectedT3Builder::new()
.into_stream()
// Stream
EmaDeviationCorrectedT3Stream::try_new(EmaDeviationCorrectedT3Params)
EmaDeviationCorrectedT3Stream::update(f64) -> Option<(f64, f64)>
EmaDeviationCorrectedT3Stream::reset()
// Batch
EmaDeviationCorrectedT3BatchBuilder::new()
.period_range(start, end, step)
.hot_range(start, end, step)
.t3_mode_range(start, end, step)
.kernel(Kernel)
.apply_slice(&[f64])
EmaDeviationCorrectedT3BatchBuilder::new()
.apply_candles(&Candles, &str) Error Handling ▼
pub enum EmaDeviationCorrectedT3Error {
EmptyInputData,
AllValuesNaN,
InvalidPeriod { period: usize, data_len: usize },
InvalidHot { hot: f64 },
InvalidT3Mode { mode: usize },
OutputLengthMismatch { expected: usize, got: usize },
InvalidRangeUsize { start: usize, end: usize, step: usize },
InvalidRangeF64 { start: f64, end: f64, step: f64 },
InvalidKernelForBatch(Kernel),
} Python Bindings
Python exposes a tuple-returning single-run function, a streaming class, and a batch function. The single-run binding returns the corrected line first and the baseline T3 line second. The batch binding returns separate corrected and T3 matrices plus the tested parameter axes.
import numpy as np
from vector_ta import (
ema_deviation_corrected_t3,
ema_deviation_corrected_t3_batch,
EmaDeviationCorrectedT3Stream,
)
data = np.asarray(close_values, dtype=np.float64)
corrected, t3 = ema_deviation_corrected_t3(
data,
period=10,
hot=0.7,
t3_mode=0,
kernel="auto",
)
stream = EmaDeviationCorrectedT3Stream(period=10, hot=0.7, t3_mode=0)
print(stream.update(data[-1])) # returns (corrected, t3) or None
batch = ema_deviation_corrected_t3_batch(
data,
period_range=(10, 14, 2),
hot_range=(0.7, 0.9, 0.1),
t3_mode_range=(0, 1, 1),
kernel="auto",
)
print(batch["corrected"].shape, batch["t3"].shape)
print(batch["periods"], batch["hots"], batch["t3_modes"])
print(batch["rows"], batch["cols"]) JavaScript/WASM Bindings
The WASM layer exposes a packed scalar wrapper, a structured batch wrapper, and lower-level allocation and in-place exports. The scalar JavaScript path returns one object with `rows = 2`, `cols = data.length`, and a packed `values` array containing the corrected row first and the T3 row second.
import init, {
ema_deviation_corrected_t3_js,
ema_deviation_corrected_t3_batch_js,
} from "/pkg/vector_ta.js";
await init();
const data = new Float64Array(closeValues);
const packed = ema_deviation_corrected_t3_js(data, 10, 0.7, 0);
console.log(packed.values, packed.rows, packed.cols);
const batch = ema_deviation_corrected_t3_batch_js(data, {
period_range: [10, 14, 2],
hot_range: [0.7, 0.9, 0.1],
t3_mode_range: [0, 1, 1],
});
console.log(batch.corrected, batch.t3, batch.periods, batch.hots, batch.t3_modes, batch.rows, batch.cols); CUDA Bindings (Rust)
Additional details for the CUDA bindings can be found inside the VectorTA repository.
Performance Analysis
Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)
Related Indicators
Arnaud Legoux Moving Average
Moving average indicator
Compound Ratio Moving Average (CoRa Wave)
Moving average indicator
Centered Weighted Moving Average
Moving average indicator
Double Exponential Moving Average
Moving average indicator
Deviation
Technical analysis indicator
Ehlers Distance Coefficient Filter
Moving average indicator