Momentum Ratio Oscillator
source = close | period = 50 Overview
Momentum Ratio Oscillator operates on a single source series. For each valid bar it updates an EMA, compares
that EMA to the previous EMA, and treats the ratio differently depending on whether it is below or above
1.0. Those lower and upper ratio components are smoothed again and combined into the final
line value with
2 * ratioa / (ratioa + ratiob * emaa) - 1
when the denominator stays finite and non-zero. The companion signal output is the prior
line value, so this implementation exposes both the current oscillator and its one-bar lag.
Defaults: period = 50. Candle helpers and builder candle input default to close.
Implementation Examples
Use explicit slices or the default candle helper on close:
use vector_ta::indicators::momentum_ratio_oscillator::{
momentum_ratio_oscillator,
MomentumRatioOscillatorInput,
MomentumRatioOscillatorParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let data = vec![100.0, 101.2, 100.8, 102.1, 103.5, 102.9];
let input = MomentumRatioOscillatorInput::from_slice(
&data,
MomentumRatioOscillatorParams::default(),
);
let out = momentum_ratio_oscillator(&input)?;
// Default candle helper uses close
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_out = momentum_ratio_oscillator(
&MomentumRatioOscillatorInput::with_default_candles(&candles),
)?;
println!("{:?}", out.line.last());
println!("{:?}", out.signal.last()); API Reference
Input Methods ▼
// From candles
MomentumRatioOscillatorInput::from_candles(
&Candles,
&str,
MomentumRatioOscillatorParams,
) -> MomentumRatioOscillatorInput
// From a source slice
MomentumRatioOscillatorInput::from_slice(
&[f64],
MomentumRatioOscillatorParams,
) -> MomentumRatioOscillatorInput
// Default candles helper
MomentumRatioOscillatorInput::with_default_candles(&Candles)
-> MomentumRatioOscillatorInput Parameters and Outputs ▼
pub struct MomentumRatioOscillatorParams {
pub period: Option<usize>, // default 50
}
pub struct MomentumRatioOscillatorOutput {
pub line: Vec<f64>,
pub signal: Vec<f64>,
} Builder, Stream, and Batch Surface ▼
MomentumRatioOscillatorBuilder::new()
.period(usize)
.source(&str)
.kernel(Kernel)
.apply(&Candles) -> Result<MomentumRatioOscillatorOutput, _>
MomentumRatioOscillatorBuilder::new()
.apply_slice(&[f64]) -> Result<MomentumRatioOscillatorOutput, _>
MomentumRatioOscillatorBuilder::new()
.into_stream() -> Result<MomentumRatioOscillatorStream, _>
MomentumRatioOscillatorStream::update(value) -> Option<(f64, f64)>
MomentumRatioOscillatorStream::update_reset_on_nan(value) -> Option<(f64, f64)>
MomentumRatioOscillatorBatchBuilder::new()
.kernel(Kernel)
.period_range(start, end, step)
.period_static(period)
.run_on_slice(&[f64]) -> Result<MomentumRatioOscillatorBatchOutput, _> Validation, Warmup, and NaNs ▼
- The input slice must be non-empty and contain at least one finite value.
periodmust be greater than0and no larger than the data length.- The scalar and batch validators require at least
2finite values from the first valid bar onward. - Scalar warmup prefixes are
first_valid + 1forlineandfirst_valid + 2forsignal. - In the slice and batch compute paths, any non-finite source value writes
NaNfor that index and resets EMA state. - The stream also resets on non-finite input and returns
Noneuntil a new finite oscillator value is available. - The first finite stream result can carry
signal = NaNbecause it is the priorline.
Calculation and Batch Output ▼
- The implementation uses
alpha = 2.0 / periodfor the main EMA and both ratio-side EMA tracks. ratioais the ratio of the current EMA to the previous EMA.- Values of
ratioa < 1.0feedemaa; values ofratioa > 1.0feedemab. ratiobisratioa / (ratioa + emab)when that ratio is valid.- The published outputs are
line = valandsignal = previous val. - Batch defaults are
period = (50, 50, 0). - Rust batch output is
MomentumRatioOscillatorBatchOutputwith flattenedlineandsignalbuffers pluscombos,rows, andcols.
Error Handling ▼
use vector_ta::indicators::momentum_ratio_oscillator::MomentumRatioOscillatorError;
// Common errors:
// - EmptyInputData
// - AllValuesNaN
// - InvalidPeriod
// - NotEnoughValidData
// - OutputLengthMismatch
// - InvalidRange
// - InvalidKernelForBatch Python Bindings
Basic Usage ▼
The Python scalar function returns the oscillator line and one-bar signal arrays:
from vector_ta import momentum_ratio_oscillator
line, signal = momentum_ratio_oscillator(
data,
period=50,
kernel="auto",
) Streaming Real-time Updates ▼
The Python stream wrapper exposes the same per-value update contract:
from vector_ta import MomentumRatioOscillatorStream
stream = MomentumRatioOscillatorStream(period=50)
for value in live_values:
result = stream.update(value)
if result is not None:
line, signal = result Batch Processing ▼
Python batch returns reshaped output matrices plus the swept period column:
from vector_ta import momentum_ratio_oscillator_batch
result = momentum_ratio_oscillator_batch(
data,
period_range=(20, 60, 20),
kernel="auto",
)
line = result["line"]
signal = result["signal"]
periods = result["periods"]
rows = result["rows"]
cols = result["cols"] JavaScript/WASM Bindings
Basic Usage ▼
The scalar JS/WASM export returns an object with line and signal arrays:
import { momentum_ratio_oscillator_js } from 'vectorta-wasm';
const result = momentum_ratio_oscillator_js(data, 50) as {
line: number[];
signal: number[];
};
console.log(result.line);
console.log(result.signal); Host Buffer API ▼
Low-level WASM allocates one packed buffer of length len * 2, split into line then signal:
import {
momentum_ratio_oscillator_alloc,
momentum_ratio_oscillator_free,
momentum_ratio_oscillator_into_host,
} from 'vectorta-wasm';
const len = data.length;
const outPtr = momentum_ratio_oscillator_alloc(len);
try {
momentum_ratio_oscillator_into_host(data, outPtr, 50);
} finally {
momentum_ratio_oscillator_free(outPtr, len);
} Batch Processing ▼
The JS batch config takes a 3-element period_range and returns output arrays plus parameter combos:
import { momentum_ratio_oscillator_batch_js } from 'vectorta-wasm';
const batch = momentum_ratio_oscillator_batch_js(data, {
period_range: [20, 60, 20],
}) as {
line: number[];
signal: number[];
rows: number;
cols: number;
combos: Array<{ period?: number }>;
};
console.log(batch.rows, batch.cols);
console.log(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)