Ichimoku Oscillator

Parameters: conversion_periods = 9 | base_periods = 26 | lagging_span_periods = 52 | displacement = 26 | ma_length = 12 | smoothing_length = 3 | extra_smoothing = true | normalize = window | window_size = 20 | clamp = true | top_band = 2 | mid_band = 1.5

Overview

Ichimoku Oscillator compresses the usual Ichimoku chart structure into an indicator-style output pack that still preserves the main moving parts of the system. It derives signal, moving-average, conversion, base, chikou, and kumo values, then maps those relationships into normalized level outputs that are easier to consume in screening, automation, and compact chart panels than the full visual cloud layout.

The page returns more than one line because the indicator is effectively a structured Ichimoku state model rather than a single oscillator trace. The main `signal` and `ma` lines are supported by current and future kumo boundaries, lagging context, and four level bands. Normalization can be disabled, applied across all data, or applied over a rolling window depending on whether you want stable ranges or more local regime sensitivity.

Defaults: Ichimoku Oscillator uses `conversion_periods = 9`, `base_periods = 26`, `lagging_span_periods = 52`, `displacement = 26`, `ma_length = 12`, `smoothing_length = 3`, `extra_smoothing = true`, `normalize = "window"`, `window_size = 20`, `clamp = true`, `top_band = 2.0`, `mid_band = 1.5`, and candle source `close`.

Implementation Examples

Compute the full oscillator state pack from OHLC arrays and a source series.

use vector_ta::indicators::ichimoku_oscillator::{
    ichimoku_oscillator,
    IchimokuOscillatorInput,
    IchimokuOscillatorParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let output = ichimoku_oscillator(
    &IchimokuOscillatorInput::from_slices(
        &high,
        &low,
        &close,
        &close,
        IchimokuOscillatorParams::default(),
    ),
)?;

let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = ichimoku_oscillator(
    &IchimokuOscillatorInput::with_default_candles(&candles),
)?;

println!("{:?}", output.signal.last());
println!("{:?}", candle_output.future_kumo_a.last());

API Reference

Input Methods
// From candles
IchimokuOscillatorInput::from_candles(&Candles, &str, IchimokuOscillatorParams) -> IchimokuOscillatorInput

// From slices
IchimokuOscillatorInput::from_slices(&[f64], &[f64], &[f64], &[f64], IchimokuOscillatorParams) -> IchimokuOscillatorInput

// From candles with default parameters and source "close"
IchimokuOscillatorInput::with_default_candles(&Candles) -> IchimokuOscillatorInput
Parameters Structure
pub struct IchimokuOscillatorParams {
    pub conversion_periods: Option<usize>,
    pub base_periods: Option<usize>,
    pub lagging_span_periods: Option<usize>,
    pub displacement: Option<usize>,
    pub ma_length: Option<usize>,
    pub smoothing_length: Option<usize>,
    pub extra_smoothing: Option<bool>,
    pub normalize: Option<IchimokuOscillatorNormalizeMode>,
    pub window_size: Option<usize>,
    pub clamp: Option<bool>,
    pub top_band: Option<f64>,
    pub mid_band: Option<f64>,
}
Output Structure
pub struct IchimokuOscillatorOutput {
    pub signal: Vec<f64>,
    pub ma: Vec<f64>,
    pub conversion: Vec<f64>,
    pub base: Vec<f64>,
    pub chikou: Vec<f64>,
    pub current_kumo_a: Vec<f64>,
    pub current_kumo_b: Vec<f64>,
    pub future_kumo_a: Vec<f64>,
    pub future_kumo_b: Vec<f64>,
    pub max_level: Vec<f64>,
    pub high_level: Vec<f64>,
    pub low_level: Vec<f64>,
    pub min_level: Vec<f64>,
}
Validation, Warmup & NaNs
  • High, low, close, and source arrays must be non-empty, equal in length, and finite.
  • All period-style parameters must be positive integers, and window_size must be at least 5 when normalization mode is window.
  • top_band and mid_band must be valid finite bands.
  • Normalization mode supports all, window, and disabled.
  • Batch mode validates all axes and rejects unsupported kernels through InvalidKernelForBatch.
Builder, Streaming & Batch APIs
// Builder
IchimokuOscillatorBuilder::new()
    .source(String)
    .conversion_periods(usize)
    .base_periods(usize)
    .lagging_span_periods(usize)
    .displacement(usize)
    .ma_length(usize)
    .smoothing_length(usize)
    .extra_smoothing(bool)
    .normalize(IchimokuOscillatorNormalizeMode)
    .window_size(usize)
    .clamp(bool)
    .top_band(f64)
    .mid_band(f64)
    .kernel(Kernel)
    .apply(&Candles)

IchimokuOscillatorBuilder::new()
    .apply_slices(&[f64], &[f64], &[f64], &[f64])
    .into_stream()

// Stream
IchimokuOscillatorStream::try_new(IchimokuOscillatorParams)
IchimokuOscillatorStream::update(f64, f64, f64, f64) -> (f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64)

// Batch
IchimokuOscillatorBatchBuilder::new()
    .conversion_periods_range(usize, usize, usize)
    .base_periods_range(usize, usize, usize)
    .lagging_span_periods_range(usize, usize, usize)
    .displacement_range(usize, usize, usize)
    .ma_length_range(usize, usize, usize)
    .smoothing_length_range(usize, usize, usize)
    .window_size_range(usize, usize, usize)
    .top_band_range(f64, f64, f64)
    .mid_band_range(f64, f64, f64)
    .apply_slices(&[f64], &[f64], &[f64], &[f64])
Error Handling
pub enum IchimokuOscillatorError {
    EmptyInputData,
    AllValuesNaN,
    InconsistentSliceLengths { high_len: usize, low_len: usize, close_len: usize, source_len: usize },
    InvalidPeriod { name: String, value: usize },
    InvalidWindowSize { window_size: usize },
    InvalidBand { name: String, value: f64 },
    OutputLengthMismatch { expected: usize, 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 path returns a dictionary containing all thirteen output arrays. The stream returns one dictionary-like state snapshot per update. Batch returns reshaped matrices for the same field set.

import numpy as np
from vector_ta import (
    ichimoku_oscillator,
    ichimoku_oscillator_batch,
    IchimokuOscillatorStream,
)

high = np.asarray(high_values, dtype=np.float64)
low = np.asarray(low_values, dtype=np.float64)
close = np.asarray(close_values, dtype=np.float64)

result = ichimoku_oscillator(
    high,
    low,
    close,
    source=close,
    conversion_periods=9,
    base_periods=26,
    lagging_span_periods=52,
    displacement=26,
    ma_length=12,
    smoothing_length=3,
    extra_smoothing=True,
    normalize="window",
    window_size=20,
    clamp=True,
    top_band=2.0,
    mid_band=1.5,
    kernel="auto",
)

stream = IchimokuOscillatorStream()
print(stream.update(float(high[-1]), float(low[-1]), float(close[-1]), float(close[-1])))

batch = ichimoku_oscillator_batch(
    high,
    low,
    close,
    source=close,
    conversion_periods_range=(9, 11, 2),
    base_periods_range=(26, 26, 0),
    lagging_span_periods_range=(52, 52, 0),
    displacement_range=(26, 26, 0),
    ma_length_range=(12, 12, 0),
    smoothing_length_range=(3, 5, 2),
    window_size_range=(20, 20, 0),
    top_band_range=(2.0, 2.0, 0.0),
    mid_band_range=(1.5, 1.5, 0.0),
    extra_smoothing=True,
    normalize="window",
    clamp=True,
    kernel="auto",
)

print(batch["signal"].shape)

JavaScript/WASM Bindings

The WASM layer exposes scalar, batch, and into-buffer helpers. The scalar binding returns a full object with the signal, conversion/base lines, chikou, current and future kumo values, and the four normalized levels. The batch binding returns flattened arrays for the same field set plus rows and cols.

import init, {
  ichimoku_oscillator_js,
  ichimoku_oscillator_batch_js,
} from "@vectoralpha/vector_ta";

await init();

const single = ichimoku_oscillator_js(
  high,
  low,
  close,
  close,
  9,
  26,
  52,
  26,
  12,
  3,
  true,
  "window",
  20,
  true,
  2.0,
  1.5,
);

console.log(single.signal);
console.log(single.future_kumo_a);

const batch = ichimoku_oscillator_batch_js(high, low, close, close, {
  conversion_periods_range: [9, 11, 2],
  base_periods_range: [26, 26, 0],
  lagging_span_periods_range: [52, 52, 0],
  displacement_range: [26, 26, 0],
  ma_length_range: [12, 12, 0],
  smoothing_length_range: [3, 5, 2],
  window_size_range: [20, 20, 0],
  top_band_range: [2.0, 2.0, 0.0],
  mid_band_range: [1.5, 1.5, 0.0],
  extra_smoothing: true,
  normalize: "window",
  clamp: true,
});

console.log(batch.rows, batch.cols);

CUDA Bindings (Rust)

Additional details for the CUDA bindings can be found inside the VectorTA repository.

Performance Analysis

Comparison:
View:
Placeholder data (no recorded benchmarks for this indicator)

Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.

Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)

Related Indicators