Market Structure Confluence
swing_size = 10 | bos_confirmation = Candle Close | basis_length = 100 | atr_length = 14 | atr_smooth = 21 | vol_mult = 2 Overview
Market Structure Confluence consumes high, low, and close series and
tracks pivot highs and pivot lows over a symmetric swing_size window. Each new pivot is labeled as
higher high, lower high, higher low, or lower low by comparing it to the previous pivot of the same type. When
price later breaks the last active swing, the indicator flags a bullish or bearish break of structure and
classifies the break as either BOS or CHoCH depending on the prior break direction.
In parallel, the indicator builds a weighted moving average basis from close, computes ATR over
atr_length, smooths that ATR with an SMA of length atr_smooth, and places
upper_band and lower_band at basis ± vol_mult × smoothed ATR. The output
includes structure direction, swing labels, BOS and CHoCH markers, and bullish or bearish arrow markers when
price interacts with the active-side band while structure direction is already set.
Defaults: swing_size = 10, bos_confirmation = "Candle Close",
basis_length = 100, atr_length = 14, atr_smooth = 21,
vol_mult = 2.0.
Implementation Examples
Compute the full structure state from slices or candles:
use vector_ta::indicators::market_structure_confluence::{
market_structure_confluence,
MarketStructureConfluenceInput,
MarketStructureConfluenceParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let params = MarketStructureConfluenceParams {
swing_size: Some(10),
bos_confirmation: Some("Candle Close".to_string()),
basis_length: Some(100),
atr_length: Some(14),
atr_smooth: Some(21),
vol_mult: Some(2.0),
};
let input = MarketStructureConfluenceInput::from_slices(&high, &low, &close, params);
let result = market_structure_confluence(&input)?;
println!("Basis latest: {:?}", result.basis.last());
println!("Bullish BOS latest: {:?}", result.bullish_bos.last());
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = MarketStructureConfluenceInput::with_default_candles(&candles);
let result = market_structure_confluence(&input)?;
println!("Structure direction latest: {:?}", result.structure_direction.last()); API Reference
Input Methods ▼
MarketStructureConfluenceInput::from_slices(&[f64], &[f64], &[f64], MarketStructureConfluenceParams)
MarketStructureConfluenceInput::from_candles(&Candles, MarketStructureConfluenceParams)
MarketStructureConfluenceInput::with_default_candles(&Candles)
Candle input always uses candle high, low, and close; there is no separate source selector.
Parameters Structure ▼
pub struct MarketStructureConfluenceParams {
pub swing_size: Option<usize>, // default 10
pub bos_confirmation: Option<String>, // default "Candle Close"
pub basis_length: Option<usize>, // default 100
pub atr_length: Option<usize>, // default 14
pub atr_smooth: Option<usize>, // default 21
pub vol_mult: Option<f64>, // default 2.0
} bos_confirmationaccepts"Candle Close"or"Wicks".swing_sizemust be at least2and fit inside the input asswing_size * 2 + 1.basis_length,atr_length, andatr_smoothmust be at least1and no larger than the data length.vol_multmust be finite and at least0.0.
Output Structure ▼
pub struct MarketStructureConfluenceOutput {
pub basis: Vec<f64>,
pub upper_band: Vec<f64>,
pub lower_band: Vec<f64>,
pub structure_direction: Vec<f64>,
pub bullish_arrow: Vec<f64>,
pub bearish_arrow: Vec<f64>,
pub bullish_change: Vec<f64>,
pub bearish_change: Vec<f64>,
pub hh: Vec<f64>,
pub lh: Vec<f64>,
pub hl: Vec<f64>,
pub ll: Vec<f64>,
pub bullish_bos: Vec<f64>,
pub bullish_choch: Vec<f64>,
pub bearish_bos: Vec<f64>,
pub bearish_choch: Vec<f64>,
}
The stream output exposes the same 16 fields as scalars, and batch output exposes the same 16 fields as flattened row-major matrices plus combos, rows, and cols.
Validation, Warmup & NaNs ▼
- Input requires matching
high,low, andcloselengths. - Empty input returns
EmptyInputData; all-NaN input returnsAllValuesNaN. - Minimum valid history is the maximum of
swing_size * 2 + 1,basis_length, andatr_length + atr_smooth - 1. - Single-run warmup prefix is
first_valid + max(swing_size * 2, basis_length - 1, atr_length + atr_smooth - 2). - Before the basis and smoothed ATR are both ready, stream updates return
None. - Output arrays are length-checked for all 16 destination slices in
market_structure_confluence_into_slices. - Batch APIs require a batch kernel; non-batch kernels return
InvalidKernelForBatch.
Error Handling ▼
use vector_ta::indicators::market_structure_confluence::{
market_structure_confluence,
MarketStructureConfluenceError,
};
match market_structure_confluence(&input) {
Ok(output) => println!("Computed {} bars", output.basis.len()),
Err(MarketStructureConfluenceError::DataLengthMismatch { high, low, close }) =>
eprintln!("Length mismatch: high={}, low={}, close={}", high, low, close),
Err(MarketStructureConfluenceError::InvalidBosConfirmation { bos_confirmation }) =>
eprintln!("Invalid BOS confirmation: {}", bos_confirmation),
Err(MarketStructureConfluenceError::NotEnoughValidData { needed, valid }) =>
eprintln!("Need {} valid bars, found {}", needed, valid),
Err(e) => eprintln!("Market Structure Confluence error: {}", e),
} Python Bindings
Basic Usage ▼
The Python function returns a dict keyed by every output field:
import numpy as np
from vector_ta import market_structure_confluence
result = market_structure_confluence(
high=np.asarray(high, dtype=np.float64),
low=np.asarray(low, dtype=np.float64),
close=np.asarray(close, dtype=np.float64),
swing_size=10,
bos_confirmation="Candle Close",
basis_length=100,
atr_length=14,
atr_smooth=21,
vol_mult=2.0,
kernel="auto",
)
direction = result["structure_direction"]
bullish_bos = result["bullish_bos"]
upper_band = result["upper_band"] Streaming Real-time Updates ▼
The Python stream class returns a 16-value list in fixed field order:
from vector_ta import MarketStructureConfluenceStream
stream = MarketStructureConfluenceStream(
swing_size=10,
bos_confirmation="Candle Close",
basis_length=100,
atr_length=14,
atr_smooth=21,
vol_mult=2.0,
)
for h, l, c in bars:
point = stream.update(h, l, c)
if point is not None:
basis, upper_band, lower_band, structure_direction, bullish_arrow, bearish_arrow, bullish_change, bearish_change, hh, lh, hl, ll, bullish_bos, bullish_choch, bearish_bos, bearish_choch = point Batch Processing ▼
Batch output returns every matrix plus parameter metadata arrays:
import numpy as np
from vector_ta import market_structure_confluence_batch
result = market_structure_confluence_batch(
high=np.asarray(high, dtype=np.float64),
low=np.asarray(low, dtype=np.float64),
close=np.asarray(close, dtype=np.float64),
swing_size_range=(8, 12, 2),
bos_confirmation_options=["Candle Close", "Wicks"],
basis_length_range=(80, 100, 20),
atr_length_range=(14, 14, 0),
atr_smooth_range=(21, 21, 0),
vol_mult_range=(2.0, 3.0, 1.0),
kernel="auto",
)
basis = result["basis"]
bearish_choch = result["bearish_choch"]
swing_sizes = result["swing_sizes"]
bos_confirmations = result["bos_confirmations"]
rows = result["rows"]
cols = result["cols"] JavaScript/WASM Bindings
Basic Usage ▼
The primary WASM binding returns an object with the same 16 output fields:
import { market_structure_confluence_js } from 'vectorta-wasm';
const result = market_structure_confluence_js(
new Float64Array(high),
new Float64Array(low),
new Float64Array(close),
10,
"Candle Close",
100,
14,
21,
2.0
);
console.log(result.structure_direction);
console.log(result.bullish_bos); Batch Processing ▼
The batch export name is market_structure_confluence_batch and it returns all series plus parameter arrays:
import { market_structure_confluence_batch } from 'vectorta-wasm';
const result = market_structure_confluence_batch(
new Float64Array(high),
new Float64Array(low),
new Float64Array(close),
{
swing_size_range: [8, 12, 2],
bos_confirmation_options: ["Candle Close", "Wicks"],
basis_length_range: [80, 100, 20],
atr_length_range: [14, 14, 0],
atr_smooth_range: [21, 21, 0],
vol_mult_range: [2.0, 3.0, 1.0],
}
);
console.log(result.rows, result.cols);
console.log(result.basis);
console.log(result.swing_sizes);
console.log(result.bos_confirmations); Low-level WASM Notes ▼
This Rust reference exports object-returning WASM functions for single and batch usage. It does not expose the
separate alloc, free, or pointer-based into helpers that some other
indicators provide.
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