Market Structure Trailing Stop
length = 14 | increment_factor = 100 | reset_on = CHoCH Overview
Market Structure Trailing Stop reads market structure directly from OHLC bars. It scans for pivot highs and lows, promotes those pivots into structure events, and then advances a trailing stop only when the active structure regime remains intact. The result is a stop line that follows confirmed structure rather than raw volatility.
VectorTA returns three aligned outputs: the trailing stop, a directional `state` series, and a `structure` series that reflects the structure classification driving the stop logic. The `reset_on` mode determines whether the stop resets only on change-of-character events or on every qualifying structure event.
Defaults: `length = 14`, `increment_factor = 100.0`, and `reset_on = "CHoCH"`.
Implementation Examples
Run the indicator on aligned OHLC slices or directly from a candle set.
use vector_ta::indicators::market_structure_trailing_stop::{
market_structure_trailing_stop,
MarketStructureTrailingStopInput,
MarketStructureTrailingStopParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let output = market_structure_trailing_stop(&MarketStructureTrailingStopInput::from_slices(
&open,
&high,
&low,
&close,
MarketStructureTrailingStopParams {
length: Some(14),
increment_factor: Some(100.0),
reset_on: Some("CHoCH".to_string()),
},
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = market_structure_trailing_stop(
&MarketStructureTrailingStopInput::with_default_candles(&candles),
)?;
println!("trailing stop = {:?}", output.trailing_stop.last());
println!("state = {:?}", candle_output.state.last());
println!("structure = {:?}", candle_output.structure.last()); API Reference
Input Methods ▼
// From candles
MarketStructureTrailingStopInput::from_candles(&Candles, MarketStructureTrailingStopParams)
-> MarketStructureTrailingStopInput
// From aligned OHLC slices
MarketStructureTrailingStopInput::from_slices(&[f64], &[f64], &[f64], &[f64], MarketStructureTrailingStopParams)
-> MarketStructureTrailingStopInput
// From candles with default parameters
MarketStructureTrailingStopInput::with_default_candles(&Candles)
-> MarketStructureTrailingStopInput Parameters Structure ▼
pub struct MarketStructureTrailingStopParams {
pub length: Option<usize>, // default 14
pub increment_factor: Option<f64>, // default 100.0
pub reset_on: Option<String>, // "CHoCH" or "All"
} Output Structure ▼
pub struct MarketStructureTrailingStopOutput {
pub trailing_stop: Vec<f64>,
pub state: Vec<f64>,
pub structure: Vec<f64>,
} Validation, Warmup & NaNs ▼
- All four OHLC series must be non-empty and have identical lengths.
lengthmust be greater than0.increment_factormust be finite and non-negative.reset_onmust resolve toCHoCHorAll, case-insensitively.- The longest contiguous finite OHLC run must be at least
2 * length + 1bars. - Output slots remain
NaNoutside valid runs and before enough structure context exists to establish pivots and state. - Batch mode only accepts scalar, auto, AVX2, and AVX512 batch-compatible kernels; other kernels raise
InvalidKernelForBatch.
Builder, Batch & Into APIs ▼
// Builder
MarketStructureTrailingStopBuilder::new()
.length(usize)
.increment_factor(f64)
.reset_on(&str) -> Result<Self, MarketStructureTrailingStopError>
.kernel(Kernel)
.apply(&Candles)
MarketStructureTrailingStopBuilder::new()
.apply_slices(&[f64], &[f64], &[f64], &[f64])
// Into-buffer scalar API
market_structure_trailing_stop_into_slice(
&mut [f64],
&mut [f64],
&mut [f64],
&MarketStructureTrailingStopInput,
Kernel,
)
// Batch
MarketStructureTrailingStopBatchBuilder::new()
.length_range(usize, usize, usize)
.length_static(usize)
.increment_factor_range(f64, f64, f64)
.increment_factor_static(f64)
.reset_on(&str) -> Result<Self, MarketStructureTrailingStopError>
.kernel(Kernel)
.apply_slices(&[f64], &[f64], &[f64], &[f64])
MarketStructureTrailingStopBatchBuilder::new()
.apply_candles(&Candles) Error Handling ▼
pub enum MarketStructureTrailingStopError {
EmptyInputData,
InputLengthMismatch { open_len: usize, high_len: usize, low_len: usize, close_len: usize },
AllValuesNaN,
InvalidLength { length: usize },
InvalidIncrementFactor { increment_factor: f64 },
InvalidResetOn { value: String },
NotEnoughValidData { needed: usize, valid: usize },
OutputLengthMismatch { expected: usize, got: usize },
MismatchedOutputLen { dst_len: usize, expected_len: usize },
InvalidRange { start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
InvalidInput { msg: String },
} Python Bindings
Python exposes a scalar OHLC function and a batch sweep. The scalar path returns three NumPy arrays: `trailing_stop`, `state`, and `structure`. Batch returns those three matrices plus the tested lengths, increment factors, reset modes, and output dimensions.
import numpy as np
from vector_ta import (
market_structure_trailing_stop,
market_structure_trailing_stop_batch,
)
trailing_stop, state, structure = market_structure_trailing_stop(
open_values,
high_values,
low_values,
close_values,
length=14,
increment_factor=100.0,
reset_on="CHoCH",
kernel="auto",
)
batch = market_structure_trailing_stop_batch(
open_values,
high_values,
low_values,
close_values,
length_range=(10, 20, 5),
increment_factor_range=(75.0, 125.0, 25.0),
reset_on="All",
kernel="auto",
)
print(batch["trailing_stop"].shape)
print(batch["lengths"])
print(batch["reset_ons"]) JavaScript/WASM Bindings
The WASM surface exposes scalar, batch, and into-buffer entry points. The scalar function returns an object with `trailing_stop`, `state`, and `structure`. Batch returns flattened row-major outputs plus `rows`, `cols`, and the tested parameter combinations in `combos`.
import init, {
market_structure_trailing_stop_js,
market_structure_trailing_stop_batch_js,
} from "@vectoralpha/vector_ta";
await init();
const single = market_structure_trailing_stop_js(
open,
high,
low,
close,
14,
100.0,
"CHoCH",
);
console.log(single.trailing_stop);
console.log(single.state);
console.log(single.structure);
const batch = market_structure_trailing_stop_batch_js(open, high, low, close, {
length_range: [10, 20, 5],
increment_factor_range: [75.0, 125.0, 25.0],
reset_on: "All",
});
console.log(batch.trailing_stop);
console.log(batch.state);
console.log(batch.structure);
console.log(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
Average Directional Index
Technical analysis indicator
Average Directional Movement Index Rating
Technical analysis indicator
Alligator
Technical analysis indicator
Aroon
Technical analysis indicator
Aroon Oscillator
Technical analysis indicator
Chande Momentum Oscillator
Technical analysis indicator