Trend Follower
matype = ema | trend_period = 20 | ma_period = 20 | channel_rate_percent = 1 | use_linear_regression = true | linear_regression_period = 5 Overview
Trend Follower is a single-output trend line designed to stay readable while still exposing several important choices: the moving-average family, the trend and smoothing periods, a channel-rate control, and an optional linear-regression pass. The result is a directional study that can be tuned to act more like a classic moving average, a channel-guided trend filter, or a smoother regime line with reduced noise.
In VectorTA the indicator works on HLCV input, accepts either raw slices or candle data, supports several moving average types, streams one update at a time, and exposes batch sweeps across the numeric controls while keeping the moving-average family and linear-regression toggle explicit. It fits best when you want one stable trend line rather than a stacked indicator with many separate outputs.
Defaults: `matype = "ema"`, `trend_period = 20`, `ma_period = 20`, `channel_rate_percent = 1.0`, `use_linear_regression = true`, and `linear_regression_period = 5`.
Implementation Examples
Run Trend Follower from raw HLCV slices or from a candle set using the default EMA configuration.
use vector_ta::indicators::trend_follower::{
trend_follower,
TrendFollowerInput,
TrendFollowerParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let direct = trend_follower(&TrendFollowerInput::from_slices(
&high,
&low,
&close,
&volume,
TrendFollowerParams {
matype: Some("ema".to_string()),
trend_period: Some(20),
ma_period: Some(20),
channel_rate_percent: Some(1.0),
use_linear_regression: Some(true),
linear_regression_period: Some(5),
},
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let from_candles = trend_follower(&TrendFollowerInput::with_default_candles(&candles))?;
println!("latest trend = {:?}", direct.values.last());
println!("candle trend = {:?}", from_candles.values.last()); API Reference
Input Methods ▼
TrendFollowerInput::from_candles(&Candles, TrendFollowerParams)
-> TrendFollowerInput
TrendFollowerInput::from_slices(&[f64], &[f64], &[f64], &[f64], TrendFollowerParams)
-> TrendFollowerInput
TrendFollowerInput::with_default_candles(&Candles)
-> TrendFollowerInput Parameters Structure ▼
pub struct TrendFollowerParams {
pub matype: Option<String>, // default "ema"
pub trend_period: Option<usize>, // default 20
pub ma_period: Option<usize>, // default 20
pub channel_rate_percent: Option<f64>, // default 1.0
pub use_linear_regression: Option<bool>, // default true
pub linear_regression_period: Option<usize> // default 5
} Output Structure ▼
pub struct TrendFollowerOutput {
pub values: Vec<f64>,
} Validation, Warmup & NaNs ▼
- High, low, close, and volume slices must all have the same non-zero length and contain valid numeric data.
- The moving-average family must be one of
ema,sma,rma,wma, orvwma. - The resolved
trend_period,ma_period,linear_regression_period, andchannel_rate_percentmust pass the module validation rules. - Batch mode validates the integer and float range axes before expanding the grid.
Builder, Streaming & Batch APIs ▼
TrendFollowerBuilder::new()
.trend_period(usize)
.ma_period(usize)
.channel_rate_percent(f64)
.use_linear_regression(bool)
.linear_regression_period(usize)
.kernel(Kernel)
.apply(&Candles)
.apply_with_matype(&Candles, "ema")
.apply_slices(&[f64], &[f64], &[f64], &[f64], "ema")
.into_stream("ema")
TrendFollowerStream::try_new(params)
stream.update(high, low, close, volume) -> Option<f64>
TrendFollowerBatchBuilder::new()
.trend_period_range(start, end, step)
.ma_period_range(start, end, step)
.channel_rate_percent_range(start, end, step)
.linear_regression_period_range(start, end, step)
.matype_static("ema")
.use_linear_regression(bool)
.apply_slices(&[f64], &[f64], &[f64], &[f64]) Python Bindings
Python exposes a direct function returning the trend line, a stream class for HLCV updates, and a batch helper that returns the flattened value grid alongside the resolved parameter axes for each row.
from vector_ta import (
trend_follower,
trend_follower_batch,
TrendFollowerStream,
)
values = trend_follower(
high,
low,
close,
volume,
matype="ema",
trend_period=20,
ma_period=20,
channel_rate_percent=1.0,
use_linear_regression=True,
linear_regression_period=5,
)
stream = TrendFollowerStream(
matype="ema",
trend_period=20,
ma_period=20,
channel_rate_percent=1.0,
use_linear_regression=True,
linear_regression_period=5,
)
point = stream.update(high[-1], low[-1], close[-1], volume[-1])
batch = trend_follower_batch(
high,
low,
close,
volume,
trend_period_range=(10, 40, 5),
ma_period_range=(10, 30, 5),
channel_rate_percent_range=(0.5, 2.0, 0.5),
linear_regression_period_range=(3, 9, 2),
matype="ema",
use_linear_regression=True,
) JavaScript/WASM Bindings
The WASM surface includes direct, batch, and into-buffer helpers. The main JS entry points return the trend line as a plain array or a batch object, while the manual memory APIs support higher-throughput integrations.
import init, {
trend_follower_js,
trend_follower_batch_js,
trend_follower_alloc,
trend_follower_free,
trend_follower_into,
trend_follower_into_host,
trend_follower_batch_into,
} from "vector-ta-wasm";
await init();
const single = trend_follower_js(
high,
low,
close,
volume,
"ema",
20,
20,
1.0,
true,
5,
);
const batch = trend_follower_batch_js(high, low, close, volume, {
trend_period_range: [10, 40, 5],
ma_period_range: [10, 30, 5],
channel_rate_percent_range: [0.5, 2.0, 0.5],
linear_regression_period_range: [3, 9, 2],
matype: "ema",
use_linear_regression: true,
});
console.log(single.at(-1), 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)