Systemicalpha

Ultimate Oscillator

systemic:core-uoIndicatorsfunction1 cr

Inputs

NameTypeDescription
Short Windowinteger - **Description**; The number of periods used to compute the short-term averages of BP and TR.
Medium Windowinteger - **Description**; The number of periods used to compute the medium-term averages of BP and TR.
Long Windowinteger - **Description**; The number of periods used to compute the long-term averages of BP and TR.
Short Weightinteger- **Description**; The weight assigned to the short-term average in the UO calculation.
Medium Weightinteger - **Description**; The weight assigned to the medium-term average in the UO calculation.
Long Weightinteger - **Description**; The weight assigned to the long-term average in the UO calculation.
Price Highfloatarray - **Description**; The highest price of the asset during a specific period.
Price Lowfloatarray - **Description**; The lowest price of the asset during a specific period.
Price Closefloatarray - **Description**; The closing price of the asset at the end of a specific period.

Outputs

NameTypeDescription
UOfloatarrayThe Ultimate Oscillator's output is a value between 0 and 100. The levels of significance in the UO are typically around 70 (overbought) and 30 (oversold).

The Ultimate Oscillator combines buying pressure across three timeframes (7, 14, 28 periods) into a single oscillator. This multi-timeframe approach reduces false signals common in single-period oscillators.

UO=100×4×A7+2×A14+A284+2+1UO = 100 \times \frac{4 \times A_7 + 2 \times A_{14} + A_{28}}{4 + 2 + 1}

Where AnA_n = Average of Buying Pressure / True Range over n periods.


How It Works

flowchart TD
    subgraph Input["Price Data"]
        H["High"]
        L["Low"]
        C["Close"]
        PC["Prior Close"]
    end
    
    subgraph BP["Buying Pressure"]
        BPC["BP = Close - min(Low, Prior Close)"]
    end
    
    subgraph TR["True Range"]
        TRC["TR = max(High, Prior Close) - min(Low, Prior Close)"]
    end
    
    subgraph Avg["Multi-Timeframe Average"]
        A7["7-period: BP/TR × 4"]
        A14["14-period: BP/TR × 2"]
        A28["28-period: BP/TR × 1"]
    end
    
    subgraph Output["Result"]
        SUM["Sum weighted averages"]
        DIV["÷ 7"]
        UO["UO (0-100)"]
    end
    
    H & L & C & PC --> BPC & TRC
    BPC & TRC --> A7 & A14 & A28 --> SUM --> DIV --> UO

Interpreting UO

UO ValueInterpretation
> 70Overbought territory
50Neutral
< 30Oversold territory

Trading Strategies

1. Classic Divergence Setup

Larry Williams (creator) recommended a specific divergence strategy:

Bullish Setup:

  1. UO below 30 (oversold)
  2. Price makes lower low, UO makes higher low
  3. UO then breaks above the divergence high

Bearish Setup:

  1. UO above 70 (overbought)
  2. Price makes higher high, UO makes lower high
  3. UO then breaks below the divergence low

2. Overbought/Oversold

ZoneConditionPotential Action
OverboughtUO > 70Watch for bearish divergence
OversoldUO < 30Watch for bullish divergence

Why Three Timeframes?

flowchart LR
    subgraph Timeframes["Weighted Contribution"]
        T7["7-period (weight 4)<br/>Short-term sensitivity"]
        T14["14-period (weight 2)<br/>Medium-term balance"]
        T28["28-period (weight 1)<br/>Long-term stability"]
    end
TimeframeWeightPurpose
7 periods4Quick reaction to price changes
14 periods2Balances sensitivity and smoothness
28 periods1Provides stability, reduces noise

UO vs RSI

AspectUORSI
Timeframes3 combinedSingle
False signalsFewerMore frequent
ResponsivenessBalancedHigher
ComplexityMore complexSimpler
Weighting4:2:1Equal across period

Advantages

  • Multi-timeframe — Reduces whipsaws
  • Weighted approach — Emphasizes short-term while stabilizing
  • Buying pressure focus — Measures actual demand
  • Divergence-friendly — Designed for divergence trading

Disadvantages

  • Complex calculation — Three separate averages
  • Lagging — Multiple timeframes add lag
  • Less intuitive — Harder to interpret than RSI
  • Strict rules — Original strategy has specific conditions

Further Reading


Missing Data

UO needs High, Low, and Close together on every bar it uses — a gap in any one of the three (a weekend, a holiday, a stale exchange feed) voids the whole bar, including a High-only gap: buying pressure never reads High at all, so an unmasked High gap would silently distort the True Range sum instead of honestly voiding the bar. The 7/14/28-period windows mean N bars actually observed, not N calendar slots: on a market-closed gap the buying-pressure and true-range sums keep counting back through real bars, bridging straight from the last session before the gap to the first session after it — gaps become gaps (None), never the sentinel 50 UO used to fabricate, and never a carried-forward stale value. Three warm-ups stack: the 7-, 14-, and 28-period averages each need their own count of observed bars before they exist, so the first UO value only appears once the longest (28-period, by default) window has enough observed history.

Slot conditionUO output
Any of High/Low/Close missing on a barNone — the bar is skipped entirely, not partially used
Fewer than the longest window's observed bars so farNone (warm-up)
A flat window where True Range sums to zeroNone (honest 0/0, never a fabricated value)

Indicator Assessment

The following chart positions the Ultimate Oscillator based on its complexity (ease of understanding and implementation) versus reliability (consistency of signals across market conditions). Points closer to the top indicate higher reliability; points to the left indicate lower complexity.

quadrantChart
    title Ultimate Oscillator Assessment
    x-axis Low Complexity --> High Complexity
    y-axis Low Reliability --> High Reliability
    quadrant-1 Complex & Reliable
    quadrant-2 Simple & Reliable
    quadrant-3 Simple & Unreliable
    quadrant-4 Complex & Unreliable
    Stocks: [0.60, 0.65]
    Crypto: [0.60, 0.55]

Assessment Breakdown

DimensionStocksCryptoNotes
Popularity5/104/10Respected but overshadowed by simpler oscillators like RSI; Larry Williams legacy gives credibility
Reliability6.5/105.5/10Multi-timeframe approach reduces false signals; crypto volatility still causes whipsaws
Complexity6/106/10Three separate calculations with weighting; requires understanding of buying pressure concept
Versatility6/105.5/10Designed for divergence trading; less useful for overbought/oversold alone
Recent Interest4/104/10Steady but not growing; newer traders prefer simpler alternatives
Rendering diagrams...
© 2026 WanoLabs. All rights reservedAlpha build v0.1.5