Gator Oscillator

Parameters: jaws_length = 13 | jaws_shift = 8 | teeth_length = 8 | teeth_shift = 5 | lips_length = 5 | lips_shift = 3

Overview

The Gator Oscillator visualizes market awakening and sleeping phases by measuring the expansion and contraction between the Alligator's three balance lines, creating a histogram that shows when trends gain momentum or consolidate. The upper bars display the absolute difference between Jaws and Teeth, while lower bars show the negative absolute difference between Teeth and Lips, with color changes indicating whether each spread widens or narrows from bar to bar. When both histogram sections expand, the market awakens from consolidation and begins trending strongly, signaling ideal conditions for trend following strategies. Conversely, when both sections contract toward zero, the gator sleeps and markets enter ranging phases where trend systems produce whipsaws. Traders watch for the gator's mouth opening sequence where green bars appear on both sides simultaneously, confirming a new trend birth, then monitor for red bars signaling the trend exhaustion as the gator becomes satisfied. The oscillator particularly excels at keeping traders out during choppy periods and encouraging aggressive positioning when convergence patterns give way to powerful directional moves marked by steadily widening histogram bars.

Implementation Examples

Compute Gator Oscillator from slices or candles:

use vectorta::indicators::gatorosc::{gatorosc, GatorOscInput, GatorOscParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};

// From a price slice
let prices = vec![100.0, 102.0, 101.5, 103.0, 104.0, 106.0];
let params = GatorOscParams { jaws_length: Some(13), jaws_shift: Some(8), teeth_length: Some(8), teeth_shift: Some(5), lips_length: Some(5), lips_shift: Some(3) };
let input = GatorOscInput::from_slice(&prices, params);
let out = gatorosc(&input)?; // GatorOscOutput { upper, lower, upper_change, lower_change }

// From candles (defaults: close, 13/8/5 and shifts 8/5/3)
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = GatorOscInput::with_default_candles(&candles);
let out = gatorosc(&input)?;

// Access the outputs
for (u, l) in out.upper.iter().zip(out.lower.iter()) {
    println!("upper={}, lower={}", u, l);
}

API Reference

Input Methods
// From price slice
GatorOscInput::from_slice(&[f64], GatorOscParams) -> GatorOscInput

// From candles with custom source
GatorOscInput::from_candles(&Candles, &str, GatorOscParams) -> GatorOscInput

// From candles with default params (close, 13/8/5; shifts 8/5/3)
GatorOscInput::with_default_candles(&Candles) -> GatorOscInput
Parameters Structure
pub struct GatorOscParams {
    pub jaws_length: Option<usize>, // Default: 13
    pub jaws_shift: Option<usize>,  // Default: 8
    pub teeth_length: Option<usize>, // Default: 8
    pub teeth_shift: Option<usize>,  // Default: 5
    pub lips_length: Option<usize>,  // Default: 5
    pub lips_shift: Option<usize>,   // Default: 3
}
Output Structure
pub struct GatorOscOutput {
    pub upper: Vec<f64>,         // |Jaws - Teeth|
    pub lower: Vec<f64>,         // -|Teeth - Lips|
    pub upper_change: Vec<f64>,  // 1-bar delta of upper
    pub lower_change: Vec<f64>,  // 1-bar delta of lower (negated)
}
Validation, Warmup & NaNs
  • jaws_length > 0, teeth_length > 0, lips_length > 0. Shifts can be 0+; otherwise GatorOscError::InvalidSettings.
  • First finite input index defines start; if none, GatorOscError::AllValuesNaN; if data.len() - first < max(lengths) + max(shifts), NotEnoughValidData.
  • Warmup: upper is valid after max(Jaws,Teeth)+max(shift(Jaws,Teeth)) - 1 bars past first finite; lower uses Teeth/Lips. Change series start one bar later.
  • Outputs are NaN before their warmup. After warmup, internal EMA update treats NaN inputs as prior EMA state, keeping outputs finite.
  • Streaming: GatorOscStream::update returns None until the computed warmup period elapses; then returns (upper, lower, upper_change, lower_change).
Error Handling
pub enum GatorOscError {
    EmptyInputData,
    AllValuesNaN,
    InvalidSettings,
    NotEnoughValidData { needed: usize, valid: usize },
}

match gatorosc(&input) {
    Ok(out) => {/* use out */},
    Err(GatorOscError::NotEnoughValidData { needed, valid }) => eprintln!("need {needed}, have {valid}"),
    Err(e) => eprintln!("gatorosc error: {e}"),
}

Python Bindings

Quick Start
import numpy as np
from vectorta import gatorosc, gatorosc_batch, GatorOscStream

prices = np.array([...], dtype=float)
upper, lower, upper_change, lower_change = gatorosc(
    prices,
    jaws_length=13, jaws_shift=8,
    teeth_length=8, teeth_shift=5,
    lips_length=5, lips_shift=3,
)

# Streaming
stream = GatorOscStream()
for p in prices:
    tup = stream.update(float(p))
    if tup is not None:
        u, l, uc, lc = tup
Batch
import numpy as np
from vectorta import gatorosc_batch

prices = np.array([...], dtype=float)
res = gatorosc_batch(
    prices,
    jaws_length_range=(10, 14, 2),
    teeth_length_range=(6, 10, 2),
    lips_length_range=(4, 6, 1),
    kernel="auto",
)

# res is a dict with arrays shaped [rows, cols]
upper = res["upper"]
lower = res["lower"]
upper_change = res["upper_change"]
lower_change = res["lower_change"]

JavaScript/WASM Bindings

Basic Usage

Compute Gator Oscillator in JS/TS:

import { gatorosc_js } from 'vectorta-wasm';

const prices = new Float64Array([/* your data */]);
// Returns an object with flattened values (4 rows x N cols)
const out = gatorosc_js(prices, 13, 8, 8, 5, 5, 3);
// out: { values: Float64Array, rows: 4, cols: prices.length }
const { values, rows, cols } = out as { values: Float64Array, rows: number, cols: number };
const upper = values.slice(0, cols);
const lower = values.slice(cols, 2*cols);
const upper_change = values.slice(2*cols, 3*cols);
const lower_change = values.slice(3*cols, 4*cols);
Memory-Efficient Operations

Use zero-copy buffers for large datasets:

import { gatorosc_alloc, gatorosc_free, gatorosc_into, memory } from 'vectorta-wasm';

const prices = new Float64Array([/* your data */]);
const n = prices.length;

// Allocate WASM memory
const inPtr = gatorosc_alloc(n);
const upPtr = gatorosc_alloc(n);
const loPtr = gatorosc_alloc(n);
const ucPtr = gatorosc_alloc(n);
const lcPtr = gatorosc_alloc(n);

new Float64Array(memory.buffer, inPtr, n).set(prices);

// Fill outputs directly into allocated memory
gatorosc_into(inPtr, upPtr, loPtr, ucPtr, lcPtr, n, 13, 8, 8, 5, 5, 3);

// Read results
const upper = new Float64Array(memory.buffer, upPtr, n).slice();
const lower = new Float64Array(memory.buffer, loPtr, n).slice();
const upper_change = new Float64Array(memory.buffer, ucPtr, n).slice();
const lower_change = new Float64Array(memory.buffer, lcPtr, n).slice();

// Free
gatorosc_free(inPtr, n); gatorosc_free(upPtr, n); gatorosc_free(loPtr, n);
gatorosc_free(ucPtr, n); gatorosc_free(lcPtr, n);
Batch Processing
import { gatorosc_batch } from 'vectorta-wasm';

const prices = new Float64Array([/* data */]);
// Returns flattened outputs for all combos (no metadata helper; supply ranges via config object)
const cfg = {
  jaws_length_range: [10, 14, 2],
  jaws_shift_range: [8, 8, 0],
  teeth_length_range: [6, 10, 2],
  teeth_shift_range: [5, 5, 0],
  lips_length_range: [4, 6, 1],
  lips_shift_range: [3, 3, 0],
};
const res = gatorosc_batch(prices, cfg);
// res: { values: Float64Array, combos: GatorOscParams[], rows: number, cols: number, outputs: 4 }

CUDA Acceleration

CUDA support for Gator Oscillator is currently under development. The API will follow the same pattern as other CUDA-enabled indicators.

Performance Analysis

Comparison:
View:
Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05

Related Indicators