Intraday Momentum Index
length = 14 | length_ma = 6 | mult = 2 | length_bb = 20 | apply_smoothing = | low_band = 10 Overview
Intraday Momentum Index is an intraday-style oscillator that compares up-close and down-close pressure over a rolling window. Instead of using full high and low range structure, it works from open and close values, making it useful when you want a compact measure of whether recent sessions have tended to finish strong or weak relative to where they started.
This implementation returns the core IMI line together with upper-hit and lower-hit markers and an EMA signal line. Optional smoothing can be enabled before the Bollinger-style band test, so the indicator can be run either as a raw momentum oscillator or as a more filtered mean-reversion overlay.
Defaults: length = 14, length_ma = 6, mult = 2.0, length_bb = 20, apply_smoothing = false, and low_band = 10.
Implementation Examples
Compute IMI, upper-hit markers, lower-hit markers, and the signal line from slices or candles.
use vector_ta::indicators::intraday_momentum_index::{
intraday_momentum_index,
IntradayMomentumIndexInput,
IntradayMomentumIndexParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let output = intraday_momentum_index(
&IntradayMomentumIndexInput::from_slices(
&open,
&close,
IntradayMomentumIndexParams::default(),
),
)?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = intraday_momentum_index(
&IntradayMomentumIndexInput::with_default_candles(&candles),
)?;
println!("{:?}", output.imi.last());
println!("{:?}", candle_output.signal.last());API Reference
Input Methods▼
// From candles
IntradayMomentumIndexInput::from_candles(&Candles, IntradayMomentumIndexParams) -> IntradayMomentumIndexInput
// From slices
IntradayMomentumIndexInput::from_slices(&[f64], &[f64], IntradayMomentumIndexParams) -> IntradayMomentumIndexInput
// From candles with default parameters
IntradayMomentumIndexInput::with_default_candles(&Candles) -> IntradayMomentumIndexInputParameters Structure▼
pub struct IntradayMomentumIndexParams {
pub length: Option<usize>,
pub length_ma: Option<usize>,
pub mult: Option<f64>,
pub length_bb: Option<usize>,
pub apply_smoothing: Option<bool>,
pub low_band: Option<usize>,
}Output Structure▼
pub struct IntradayMomentumIndexOutput {
pub imi: Vec<f64>,
pub upper_hit: Vec<f64>,
pub lower_hit: Vec<f64>,
pub signal: Vec<f64>,
}Validation, Warmup & NaNs▼
- Open and close arrays must be non-empty and equal in length.
- The core
length, signallength_ma, and bandlength_bbmust be positive, andmultmust be finite and non-negative. - If smoothing is enabled,
low_bandmust be at least 1. - Not enough valid open/close pairs yields
NotEnoughValidData. - The stream warmup is
length - 1bars before IMI can emit a finite value.
Builder, Streaming & Batch APIs▼
// Builder
IntradayMomentumIndexBuilder::new()
.length(usize)
.length_ma(usize)
.mult(f64)
.length_bb(usize)
.apply_smoothing(bool)
.low_band(usize)
.kernel(Kernel)
.apply(&Candles)
IntradayMomentumIndexBuilder::new()
.apply_slices(&[f64], &[f64])
.into_stream()
// Stream
IntradayMomentumIndexStream::try_new(IntradayMomentumIndexParams)
IntradayMomentumIndexStream::update(f64, f64) -> Option<(f64, f64, f64, f64)>
IntradayMomentumIndexStream::get_warmup_period() -> usize
// Batch
IntradayMomentumIndexBatchBuilder::new()
.length_range(usize, usize, usize)
.length_ma_range(usize, usize, usize)
.mult_range(f64, f64, f64)
.length_bb_range(usize, usize, usize)
.apply_smoothing(bool)
.low_band_range(usize, usize, usize)
.apply_slices(&[f64], &[f64])Error Handling▼
pub enum IntradayMomentumIndexError {
EmptyInputData,
AllValuesNaN,
InconsistentSliceLengths { open_len: usize, close_len: usize },
InvalidLength { length: usize, data_len: usize },
InvalidLengthMa { length_ma: usize, data_len: usize },
InvalidLengthBb { length_bb: usize, data_len: usize },
InvalidMult { mult: f64 },
InvalidLowBand { low_band: usize },
NotEnoughValidData { needed: usize, valid: usize },
OutputLengthMismatch { expected: usize, imi_got: usize, upper_hit_got: usize, lower_hit_got: usize, signal_got: usize },
InvalidRange { 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 four arrays in order: IMI, upper_hit, lower_hit, and signal. The stream returns the same four-field tuple per update. Batch returns those matrices plus the tested parameter arrays and grid dimensions.
import numpy as np
from vector_ta import (
intraday_momentum_index,
intraday_momentum_index_batch,
IntradayMomentumIndexStream,
)
open_ = np.asarray(open_values, dtype=np.float64)
close = np.asarray(close_values, dtype=np.float64)
imi, upper_hit, lower_hit, signal = intraday_momentum_index(
open_,
close,
length=14,
length_ma=6,
mult=2.0,
length_bb=20,
apply_smoothing=False,
low_band=10,
kernel="auto",
)
stream = IntradayMomentumIndexStream()
print(stream.update(float(open_[-1]), float(close[-1])))
print(stream.warmup_period)
batch = intraday_momentum_index_batch(
open_,
close,
length_range=(10, 14, 2),
length_ma_range=(4, 6, 1),
mult_range=(2.0, 3.0, 0.5),
length_bb_range=(18, 20, 2),
apply_smoothing=True,
low_band_range=(10, 12, 2),
kernel="auto",
)
print(batch["imi"].shape)
print(batch["lengths"])JavaScript/WASM Bindings
The WASM layer exposes scalar, batch, and into-buffer helpers. The scalar binding returns an object containing `imi`, `upper_hit`, `lower_hit`, and `signal`. The batch binding returns those flattened arrays plus `combos`, per-axis parameter arrays, and the `rows` and `cols` needed to reshape the results.
import init, {
intraday_momentum_index_js,
intraday_momentum_index_batch_js,
} from "@vectoralpha/vector_ta";
await init();
const single = intraday_momentum_index_js(
open_,
close,
14,
6,
2.0,
20,
false,
10,
);
const batch = intraday_momentum_index_batch_js(open_, close, {
length_range: [10, 14, 2],
length_ma_range: [4, 6, 1],
mult_range: [2.0, 3.0, 0.5],
length_bb_range: [18, 20, 2],
apply_smoothing: true,
low_band_range: [10, 12, 2],
});
console.log(single.imi);
console.log(batch.rows, batch.cols);
console.log(batch.lengths);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
Acceleration Oscillator
Technical analysis indicator
Accumulation/Distribution
Technical analysis indicator
Awesome Oscillator
Technical analysis indicator
Absolute Price Oscillator
Technical analysis indicator
Commodity Channel Index
Technical analysis indicator
CCI Cycle
Technical analysis indicator