InSync Index
emo_divisor = 10000 | emo_length = 14 | fast_length = 12 | slow_length = 26 | mfi_length = 20 | bb_length = 20 | bb_multiplier = 2 | cci_length = 14 | dpo_length = 18 | roc_length = 10 | rsi_length = 14 | stoch_length = 14 | stoch_d_length = 3 | stoch_k_length = 1 | sma_length = 10 Overview
InSync Index is a composite scoring model that blends several familiar studies into one alignment readout. It uses Bollinger-style position, CCI, an EMO-derived volume signal, MACD-style trend structure, MFI, DPO, ROC, RSI, and stochastic components, then adds or subtracts score increments depending on whether those internal signals are pointing toward strength or weakness.
The result is a single values series instead of a multi-line bundle. That makes the indicator useful when you want a compact confirmation layer for screening, ranking, or strategy filters rather than monitoring each component separately. The calculation expects full OHLCV input because several internal signals depend on high, low, close, and volume together.
Defaults: InSync Index uses `emo_divisor = 10000`, `emo_length = 14`, `fast_length = 12`, `slow_length = 26`, `mfi_length = 20`, `bb_length = 20`, `bb_multiplier = 2.0`, `cci_length = 14`, `dpo_length = 18`, `roc_length = 10`, `rsi_length = 14`, `stoch_length = 14`, `stoch_d_length = 3`, `stoch_k_length = 1`, and `sma_length = 10`.
Implementation Examples
Compute the composite alignment score from OHLCV slices or a Candles dataset.
use vector_ta::indicators::insync_index::{
insync_index,
InsyncIndexInput,
InsyncIndexParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let output = insync_index(
&InsyncIndexInput::from_slices(
&high,
&low,
&close,
&volume,
InsyncIndexParams::default(),
),
)?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = insync_index(&InsyncIndexInput::with_default_candles(&candles))?;
println!("{:?}", output.values.last());
println!("{:?}", candle_output.values.last());API Reference
Input Methods▼
// From candles
InsyncIndexInput::from_candles(&Candles, InsyncIndexParams) -> InsyncIndexInput
// From slices
InsyncIndexInput::from_slices(&[f64], &[f64], &[f64], &[f64], InsyncIndexParams) -> InsyncIndexInput
// From candles with default parameters
InsyncIndexInput::with_default_candles(&Candles) -> InsyncIndexInputParameters Structure▼
pub struct InsyncIndexParams {
pub emo_divisor: Option<usize>,
pub emo_length: Option<usize>,
pub fast_length: Option<usize>,
pub slow_length: Option<usize>,
pub mfi_length: Option<usize>,
pub bb_length: Option<usize>,
pub bb_multiplier: Option<f64>,
pub cci_length: Option<usize>,
pub dpo_length: Option<usize>,
pub roc_length: Option<usize>,
pub rsi_length: Option<usize>,
pub stoch_length: Option<usize>,
pub stoch_d_length: Option<usize>,
pub stoch_k_length: Option<usize>,
pub sma_length: Option<usize>,
}Output Structure▼
pub struct InsyncIndexOutput {
pub values: Vec<f64>,
}Validation, Warmup & NaNs▼
- High, low, close, and volume arrays must be non-empty and equal in length.
- At least one valid OHLCV bar is required; bars are valid only when values are finite, volume is positive, and high is not below low.
- All period parameters must be greater than zero, and
bb_multipliermust be finite and positive. - Streaming resets on invalid bars and returns
Nonefor those updates. - Batch mode validates each sweep axis and rejects unsupported kernels through
InvalidKernelForBatch.
Builder, Streaming & Batch APIs▼
// Builder
InsyncIndexBuilder::new()
.emo_divisor(usize)
.emo_length(usize)
.fast_length(usize)
.slow_length(usize)
.mfi_length(usize)
.bb_length(usize)
.bb_multiplier(f64)
.cci_length(usize)
.dpo_length(usize)
.roc_length(usize)
.rsi_length(usize)
.stoch_length(usize)
.stoch_d_length(usize)
.stoch_k_length(usize)
.sma_length(usize)
.kernel(Kernel)
.apply(&Candles)
InsyncIndexBuilder::new()
.apply_slices(&[f64], &[f64], &[f64], &[f64])
.into_stream()
// Stream
InsyncIndexStream::try_new(InsyncIndexParams)
InsyncIndexStream::update(f64, f64, f64, f64) -> Option<f64>
InsyncIndexStream::reset()
// Batch
InsyncIndexBatchBuilder::new()
.emo_length_range(usize, usize, usize)
.fast_length_range(usize, usize, usize)
.bb_multiplier_range(f64, f64, f64)
.apply_slices(&[f64], &[f64], &[f64], &[f64])Error Handling▼
pub enum InsyncIndexError {
EmptyInputData,
DataLengthMismatch,
AllValuesNaN,
InvalidPeriod { name: &'static str, value: usize },
InvalidFloat { name: &'static str, value: f64 },
OutputLengthMismatch { expected: usize, got: usize },
InvalidRange { name: &'static str, start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
}Python Bindings
Python exposes a scalar function, a stream class, and a batch sweep. The scalar function returns one NumPy array of composite scores. The stream class returns one score per update. Batch returns a dictionary with the flattened values matrix, dimensions, and one parameter array for each swept axis.
import numpy as np
from vector_ta import (
insync_index,
insync_index_batch,
InsyncIndexStream,
)
high = np.asarray(high_values, dtype=np.float64)
low = np.asarray(low_values, dtype=np.float64)
close = np.asarray(close_values, dtype=np.float64)
volume = np.asarray(volume_values, dtype=np.float64)
values = insync_index(
high,
low,
close,
volume,
emo_divisor=10000,
emo_length=14,
fast_length=12,
slow_length=26,
kernel="auto",
)
stream = InsyncIndexStream()
print(stream.update(float(high[-1]), float(low[-1]), float(close[-1]), float(volume[-1])))
batch = insync_index_batch(
high,
low,
close,
volume,
emo_length_range=(10, 14, 2),
fast_length_range=(10, 14, 2),
bb_multiplier_range=(2.0, 3.0, 0.5),
kernel="auto",
)
print(batch["values"].shape)
print(batch["fast_lengths"])JavaScript/WASM Bindings
The WASM layer exposes scalar, batch, and into-buffer helpers. The scalar binding returns a plain array of InSync scores. The batch binding returns an object with `values`, `rows`, `cols`, and the tested parameter `combos`.
import init, {
insync_index_js,
insync_index_batch_js,
} from "@vectoralpha/vector_ta";
await init();
const values = insync_index_js(
high,
low,
close,
volume,
10000,
14,
12,
26,
20,
20,
2.0,
14,
18,
10,
14,
14,
3,
1,
10,
);
const batch = insync_index_batch_js(high, low, close, volume, {
emo_length_range: [10, 14, 2],
fast_length_range: [10, 14, 2],
bb_multiplier_range: [2.0, 3.0, 0.5],
});
console.log(values.at(-1));
console.log(batch.rows, batch.cols);
console.log(batch.combos[0]);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)