Fractal Dimension Index
length = 30 Overview
Fractal Dimension Index evaluates how efficiently price has moved over a rolling window. It tracks the running highest and lowest values in that window, compares the direct envelope width to the accumulated path length of the intermediate moves, and converts that ratio into a normalized fractal-dimension style reading. Smoother, more directional motion pushes the reading lower, while jagged, back-and-forth movement pushes it higher.
This implementation works directly on one price series and defaults candle input to `close`. The streaming path uses deque-based rolling min and max structures to keep the same window logic online, and the batch path simply sweeps the lookback length across multiple rows of output.
Defaults: Fractal Dimension Index uses `length = 30` and defaults candle input to `close`.
Implementation Examples
Compute the FDI line from a raw series or from candle closes.
use vector_ta::indicators::fractal_dimension_index::{
fractal_dimension_index,
FractalDimensionIndexInput,
FractalDimensionIndexParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let close = vec![100.0, 100.6, 101.2, 100.8, 101.7, 102.1, 101.9];
let output = fractal_dimension_index(&FractalDimensionIndexInput::from_slice(
&close,
FractalDimensionIndexParams { length: Some(30) },
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = fractal_dimension_index(&FractalDimensionIndexInput::with_default_candles(&candles))?;
println!("latest fdi = {:?}", output.values.last());
println!("series length = {}", candle_output.values.len()); API Reference
Input Methods ▼
// From candles
FractalDimensionIndexInput::from_candles(&Candles, FractalDimensionIndexParams)
-> FractalDimensionIndexInput
// From a raw slice
FractalDimensionIndexInput::from_slice(&[f64], FractalDimensionIndexParams)
-> FractalDimensionIndexInput
// From candles with default parameters
FractalDimensionIndexInput::with_default_candles(&Candles)
-> FractalDimensionIndexInput Parameters Structure ▼
pub struct FractalDimensionIndexParams {
pub length: Option<usize>, // default 30
} Output Structure ▼
pub struct FractalDimensionIndexOutput {
pub values: Vec<f64>,
} Validation, Warmup & NaNs ▼
- The input series must be non-empty and contain at least one finite value.
lengthmust be at least2and valid for the supplied data length.- The one-shot function requires a contiguous finite run at least as long as the requested window.
- Streaming resets on non-finite input and reports a warmup period of
length - 1. - The output is NaN-prefixed until the rolling window has filled and a valid path-length ratio can be computed.
- Batch mode validates integer ranges and rejects unsupported kernels through
InvalidKernelForBatch.
Builder, Streaming & Batch APIs ▼
// Builder
FractalDimensionIndexBuilder::new()
.length(usize)
.kernel(Kernel)
.apply_slice(&[f64])
FractalDimensionIndexBuilder::new()
.apply(&Candles)
FractalDimensionIndexBuilder::new()
.into_stream()
// Stream
FractalDimensionIndexStream::try_new(FractalDimensionIndexParams)
FractalDimensionIndexStream::update(f64) -> Option<f64>
FractalDimensionIndexStream::get_warmup_period() -> usize
// Batch
FractalDimensionIndexBatchBuilder::new()
.length_range(start, end, step)
.kernel(Kernel)
.apply_slice(&[f64])
FractalDimensionIndexBatchBuilder::new()
.apply(&Candles) Error Handling ▼
pub enum FractalDimensionIndexError {
EmptyInputData,
AllValuesNaN,
InvalidLength { length: usize, data_len: usize },
NotEnoughValidData { needed: usize, valid: usize },
OutputLengthMismatch { expected: usize, got: usize },
InvalidRange { start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
MismatchedOutputLen { dst_len: usize, expected_len: usize },
InvalidInput { msg: String },
} Python Bindings
Python exposes an array-returning scalar function, a streaming class, and a batch function. The scalar path returns one NumPy FDI array, the stream returns one floating-point value or `None`, and batch returns the values matrix plus the tested lengths.
import numpy as np
from vector_ta import fractal_dimension_index, fractal_dimension_index_batch, FractalDimensionIndexStream
data = np.asarray(close_values, dtype=np.float64)
values = fractal_dimension_index(data, length=30, kernel="auto")
stream = FractalDimensionIndexStream(length=30)
print(stream.update(data[-1]))
batch = fractal_dimension_index_batch(
data,
length_range=(21, 30, 9),
kernel="auto",
)
print(batch["values"].shape)
print(batch["lengths"], batch["rows"], batch["cols"]) JavaScript/WASM Bindings
The WASM layer exposes a direct array-returning scalar wrapper and an object-returning batch wrapper. The scalar JavaScript path returns one FDI array, while batch returns flattened values, `rows`, `cols`, and the tested parameter combos.
import init, { fractal_dimension_index_js, fractal_dimension_index_batch_js } from "/pkg/vector_ta.js";
await init();
const values = fractal_dimension_index_js(closeValues, 30);
console.log(values);
const batch = fractal_dimension_index_batch_js(closeValues, {
length_range: [21, 30, 9],
});
console.log(batch.values, batch.rows, batch.cols, batch.combos); 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)