Heikin Ashi Candles

Overview

Heikin Ashi candles transform chaotic price action into smooth, visually intuitive patterns by averaging open, high, low, and close values with previous candle data to create modified bars that clearly reveal trend strength and direction. The close averages all four price points of the current bar, the open averages the previous Heikin Ashi open and close, while highs and lows incorporate the actual extremes, resulting in candles that show fewer gaps and more consistent coloring during trends. Strong bullish momentum appears as a series of green candles with no lower wicks, indicating buyers maintain complete control, while bearish pressure manifests as red candles lacking upper wicks where sellers dominate entirely. Traders identify trend reversals when candles develop small bodies with long wicks on both sides, forming doji patterns that signal indecision after extended moves. The smoothing effect eliminates minor retracements that create false signals on regular charts, allowing traders to stay with trends longer without getting shaken out by normal volatility. Moreover, Heikin Ashi excels at confirming breakouts since the transformation reduces noise around key levels, showing clean candle closes beyond resistance or support that provide higher confidence entry signals than traditional candlestick patterns.

Implementation Examples

Heikin Ashi Candles are currently implemented as a chart/price transform in the docs UI (TypeScript). There is no vector_ta::indicators::heikin_ashi_candles Rust API (and no Python/WASM/CUDA binding) in this repository yet.

This is the exact algorithm used by the docs chart renderer (src/components/charts/EnhancedIndicatorChart.tsx):

type Candle = {
  time: number;
  open: number;
  high: number;
  low: number;
  close: number;
};

function heikinAshi(data: Candle[]) {
  if (data.length === 0) return [];

  const out: Candle[] = [];
  let prev: Candle | null = null;

  data.forEach((c, i) => {
    const haClose = (c.open + c.high + c.low + c.close) / 4;
    const haOpen = i === 0 ? (c.open + c.close) / 2 : (prev!.open + prev!.close) / 2;
    const haHigh = Math.max(c.high, haOpen, haClose);
    const haLow = Math.min(c.low, haOpen, haClose);

    const ha: Candle = { time: c.time, open: haOpen, high: haHigh, low: haLow, close: haClose };
    out.push(ha);
    prev = ha;
  });

  return out;
}

API Reference

Input Methods

Heikin Ashi is computed from OHLC inputs (open/high/low/close). In the docs UI it operates on an array of candle objects with fields time, open, high, low, close.

Parameters Structure

No tunable parameters are expected for Heikin Ashi candles.

Output Structure

Returns a transformed OHLC series (same length as input): open, high, low, close.

Validation, Warmup & NaNs
  • Empty input returns an empty output.
  • First candle seed: HA_open[0] = (open[0] + close[0]) / 2.
  • Subsequent candles depend on the previous HA values, so the series is not pointwise independent.
  • NaNs propagate (e.g., Math.max/Math.min with NaN yields NaN in JS).
Error Handling

No dedicated error type is exposed in this repo because the transform is currently implemented in the docs UI as a pure function. Callers should validate input lengths and numeric sanity as needed.

Python Bindings

There is no vector_ta Python binding for this transform in this repository. If you need it, implement it locally (example below mirrors the docs algorithm):

import numpy as np

def heikin_ashi(open_, high, low, close):
    open_ = np.asarray(open_, dtype=np.float64)
    high = np.asarray(high, dtype=np.float64)
    low = np.asarray(low, dtype=np.float64)
    close = np.asarray(close, dtype=np.float64)

    n = close.shape[0]
    if n == 0:
        return (open_.copy(), high.copy(), low.copy(), close.copy())

    ha_close = (open_ + high + low + close) / 4.0
    ha_open = np.empty(n, dtype=np.float64)
    ha_open[0] = (open_[0] + close[0]) / 2.0
    for i in range(1, n):
        ha_open[i] = (ha_open[i - 1] + ha_close[i - 1]) / 2.0

    ha_high = np.maximum(np.maximum(high, ha_open), ha_close)
    ha_low = np.minimum(np.minimum(low, ha_open), ha_close)
    return ha_open, ha_high, ha_low, ha_close

JavaScript/WASM Bindings

The docs WebAssembly bundle (src/pkg/my_project.*) does not currently export a dedicated Heikin Ashi binding. The docs charts compute Heikin Ashi candles in JavaScript (see the Quick Start tab above).

CUDA

No CUDA implementation is exposed for this transform in this repository.

CUDA Bindings (Rust)

No Rust CUDA bindings are currently available for "heikin_ashi_candles".

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