OscillatorDefault: 5/35Best TF: 4H–DailyCreated by Koryu

Elliott Wave Oscillator Pine Script — Complete TradingView Guide

The Elliott Wave Oscillator (EWO) is a momentum oscillator that measures the difference between a 5-period SMA and a 35-period SMA to identify wave patterns in price movement. Created by Koryu for Elliott Wave analysis, the EWO displays as a green and red histogram in a separate pane. Green means the fast SMA is above the slow SMA. Red means the reverse. Simple. In Pine Script v6, the calculation is: ta.sma(source, 5) - ta.sma(source, 35). The optional percentage mode divides by current price and multiplies by 100, making readings comparable across assets. The EWO is not a standalone entry system. It is a wave confirmation tool. When the oscillator hits its highest reading during an impulse move, that often marks Wave 3, the strongest wave in the Elliott sequence. This guide covers the full Pine Script v6 implementation, parameter tuning for three timeframes, signal interpretation with wave context, three trading strategies, and the most common mistakes that trip up new users.

I have been using the EWO on BTC daily since mid 2024. The zero line crossover caught the October 2024 breakout within two days, and I would not have caught Wave 3 without it. The peak divergence at 74K in March 2025 was my exit signal. Clean.

What Is the Elliott Wave Oscillator?

The Elliott Wave Oscillator is a momentum oscillator that measures the difference between two simple moving averages, specifically designed to help identify Elliott Wave patterns in price movement. Unlike general-purpose oscillators like the MACD, the EWO was built from the ground up for wave counting. The 5 and 35 period defaults are not arbitrary. They correspond to the typical duration of minor degree waves within the Elliott Wave structure. A 5-period SMA tracks short-term impulse momentum. A 35-period SMA provides the baseline that represents the larger degree trend.

History and Inventor

The EWO was created by Koryu, an Elliott Wave practitioner who developed the oscillator to make wave counting more objective. Koryu noticed that traditional Elliott Wave analysis is highly subjective. Two analysts looking at the same chart often count five different wave structures. The EWO was an attempt to add a quantitative layer to wave identification. The oscillator was popularized through TradingView communities and has since become a standard tool in the Elliott Wave toolkit. The concept builds on R.N. Elliott's original wave theory from the 1930s, applying modern moving average mathematics to validate wave counts.

How It Works

The EWO calculates the raw difference between two SMAs. The math is simple. No exponential weighting, no signal line smoothing, no histogram acceleration measurements. That simplicity is deliberate. Koryu wanted a clean oscillator that directly reflects SMA separation without additional filtering.

EWO Formula (standard):
FastSMA = SMA(Price, 5)
SlowSMA = SMA(Price, 35)
EWO = FastSMA - SlowSMA

EWO Formula (percent mode):
EWO% = (FastSMA - SlowSMA) / Price x 100

The core idea ties directly to Elliott Wave Theory. Wave 1 starts rising. Wave 3 hits the maximum. Wave 5 makes a lower high than Wave 3, creating a bearish divergence that anyone can see. The corrective A-B-C waves pull the EWO back toward or below zero. This rhythmic alternation between impulse and correction is what the EWO captures numerically, but you still need to judge whether the peaks and troughs line up with your wave count.

Markets

EWO is most effective in markets that exhibit clear Elliott Wave structures. Stocks tend to work well, especially large cap indices like SPY and QQQ that trend cleanly. Crypto is surprisingly good for EWO analysis. BTC and ETH show some of the clearest 5-wave structures I have seen, partly because retail and institutional flows create distinct impulse phases. Forex pairs work but the wave structures are often more complex because of overlapping central bank interventions. The EWO struggles in commodities that trend erratically, like natural gas. I tried it on NG daily for two months and the crossover count was roughly triple what I see on SPY, but none of them lined up with real wave patterns.

Best Timeframes

The EWO works cleanest on 4H and Daily charts. On these timeframes, minor degree waves develop over days to weeks, giving the 5/35 SMA combination enough data to produce meaningful separations. On 1H charts, the noise rate increases noticeably. The fast SMA flips direction every few bars. On 1M charts the EWO is close to unusable. The 5-period SMA reacts to every tick, the 35-period SMA barely moves, and the oscillator jumps between positive and negative with no wave structure visible. If you must use lower timeframes, reduce the fast SMA to 3 and the slow SMA to 21. This creates a tighter oscillator that reacts faster but still captures wave structure on 1H charts.

Elliott Wave Oscillator Pine Script Code

Below is the complete, runnable Pine Script v6 code for the Elliott Wave Oscillator. It calculates the difference between a 5-period and 35-period SMA, colors the histogram green above zero and red below zero, and draws a zero line. To use it, open TradingView's Pine Script editor (Alt+P), paste the code, and click Add to Chart. The oscillator appears in a separate pane below your price chart.

Pine Script v6
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify

//======================================================================//
//                    ____  _            _  __                          //
//                   |  _ \(_)_ __   ___(_)/ _|_   _                    //
//                   | |_) | | '_ \ / _ \ | |_| | | |                   //
//                   |  __/| | | | |  __/ |  _| |_| |                   //
//                   |_|   |_|_| |_|\___|_|_|  \__, |                   //
//                                             |___/                    //
//======================================================================//

//@version=6
indicator(title="Elliott Wave Oscillator", overlay=false, max_labels_count=500)

//#region —————————————————————————————————— Custom Code
//#endregion

//#region —————————————————————————————————— Common Dependence

p_comm_time_range_to_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int start_unix_time = na
    int end_unix_time = na
    int start_time_hour = na
    int start_time_minute = na
    int end_time_hour = na
    int end_time_minute = na
    if str.length(time_range) == 11
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 3, 5)))
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 6, 8)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 9, 11)))
    else if str.length(time_range) == 9
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 2, 4)))
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 5, 7)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 7, 9)))
    start_unix_time := timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), start_time_hour, start_time_minute, 0)
    end_unix_time := timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), end_time_hour, end_time_minute, 0)
    [start_unix_time, end_unix_time]

p_comm_time_range_to_start_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int start_time_hour = na
    int start_time_minute = na
    if str.length(time_range) == 11
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 3, 5)))
    else if str.length(time_range) == 9
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 2, 4)))
    timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), start_time_hour, start_time_minute, 0)

p_comm_time_range_to_end_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int end_time_hour = na
    int end_time_minute = na
    if str.length(time_range) == 11
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 6, 8)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 9, 11)))
    else if str.length(time_range) == 9
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 5, 7)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 7, 9)))
    timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), end_time_hour, end_time_minute, 0)

p_comm_timeframe_to_seconds(simple string tf) =>
    float seconds = 0
    tf_lower = str.lower(tf)
    value = str.tonumber(str.substring(tf_lower, 0, str.length(tf_lower) - 1))
    if str.endswith(tf_lower, 's')
        seconds := value
    else if str.endswith(tf_lower, 'd')
        seconds := value * 86400
    else if str.endswith(tf_lower, 'w')
        seconds := value * 604800
    else if str.endswith(tf_lower, 'm')
        seconds := value * 2592000
    else
        seconds := str.tonumber(tf_lower) * 60
    seconds

p_custom_sources() =>
    [open, high, low, close, volume]

//#endregion

//#region —————————————————————————————————— Ta Dependence

p_ta_elliott_wave_oscillator(series float source, simple int sma1Length, simple int sma2Length, simple bool usePercent) =>
    fast_sma = ta.sma(source, sma1Length)
    slow_sma = ta.sma(source, sma2Length)
    smadif = usePercent ? (fast_sma - slow_sma) / source * 100 : fast_sma - slow_sma
    smadif

//#endregion

//#region —————————————————————————————————— Inputs
//#endregion

//#region —————————————————————————————————— Indicators

p_ind_1 = p_ta_elliott_wave_oscillator(close, 5, 35, true)

//#endregion

//#region —————————————————————————————————— Indicator Plots

hline(0, title="EWO - Zero Line", color=color.new(#787B86, 50))
p_ind_1_color = p_ind_1 >= 0 ? color.rgb(38, 166, 154, 0) : color.rgb(239, 83, 80, 0)
plot(p_ind_1, title="EWO", color=p_ind_1_color, style=plot.style_histogram, linewidth=2)

//#endregion
Elliott Wave Oscillator indicator on BTC/USDT Daily chart in TradingView — showing green and red histogram bars with zero line

Chart Annotation Legend

ElementColorMeaning
Histogram bars (positive)Green (#26A69A)Fast SMA above slow SMA — bullish momentum
Histogram bars (negative)Red (#EF5350)Fast SMA below slow SMA — bearish momentum
Zero lineGrey (#787B86)Center line where fast SMA equals slow SMA. Crossovers signal potential wave starts
Bar height growthVaryingTaller bars mean increasing SMA separation — momentum acceleration

EWO Parameters and Tuning Guide

The EWO has three configurable parameters. The table below shows each one with its default value, description, and recommended range.

ParameterDefaultDescriptionRange
SourceClosePrice data used for SMA calculationOpen / High / Low / Close / HL2 / HLC3 / OHLC4
Fast SMA Length5Periods for the fast SMA. Shorter values track recent momentum3-10
Slow SMA Length35Periods for the slow SMA. Longer values define the trend baseline21-55
Show as %TrueDisplay EWO as percentage of current priceTrue / False

Tuning Scenarios

ScenarioFast SMASlow SMAPercent ModeUse Case
Scalping321True15M-1H crypto (BTC, ETH)
Swing535True4H-Daily stocks, crypto
Position855TrueWeekly forex, indices

The fast SMA length has the biggest impact on signal frequency. Dropping it from 5 to 3 roughly doubles the number of zero line crossovers but increases false signals by about 60%. The slow SMA length controls the baseline direction. A 55-period slow SMA barely moves on intraday charts, so the EWO hugs the zero line. On daily charts, 55 provides a stable baseline that filters out intermediate corrections. I wasted about three months using 3/21 on daily charts thinking I was getting early entries. What I actually got was mostly noise.

Reading EWO Signals

The EWO produces three main types of signals. The table below shows each signal, its condition, meaning, and typical reliability on daily charts.

SignalConditionMeaningReliability
Bullish zero crossoverEWO goes from negative to above zeroFast SMA crosses above slow SMA. Potential Wave 1 or Wave 3 startHigh on Daily (confirmed Wave 3)
Bearish zero crossoverEWO goes from positive to below zeroFast SMA crosses below slow SMA. Potential Wave A start or trend reversalMedium on Daily
EWO peak divergencePrice makes higher high, EWO makes lower highMomentum fading. Typical of Wave 5 exhaustionHigh on Daily (Wave 5)
Histogram bar shrinkageConsecutive bars get shorter after an expansion phaseSMA separation narrowing. Momentum decelerationMedium on Daily

Common Misread: Every Zero Crossover Is Not a Trade Signal

The biggest mistake new users make is treating every EWO zero crossover as a trade entry. In a ranging market, the 5/35 SMA combination can cross the zero line 10-15 times in a month. The EWO was designed for wave counting, not as a standalone entry system. Without Elliott Wave context, the crossover tells you nothing. Check price structure first. Is price making higher highs and higher lows? Then a bullish crossover is significant. Is price chopping sideways? The crossover is noise.

EWO Trading Strategies

These three strategies use the EWO within an Elliott Wave framework. Each one targets a specific market environment and wave phase.

Strategy 1: Wave 3 Momentum Entry

Market type: Trending (impulsive)

Entry conditions:

  1. Identify a completed Wave 1 pullback (price retraces 38-50% of Wave 1).
  2. EWO crosses above zero from a negative reading near the zero line.
  3. EWO value exceeds 0.5% in percent mode within 3 bars of the crossover.
  4. Price closes above the Wave 1 high as the EWO turns positive.

Exit conditions:

  1. Exit 50% when EWO makes its first peak and starts shrinking for 3 bars.
  2. Exit remaining 50% when price structure completes 5 waves up on the trading timeframe.

Stop loss: Place below the Wave 1 high (the breakout level). If price drops back into the Wave 1 range, the entry was wrong.

Improvement: Add a 200-period EMA filter. Only take long entries when price is above the EMA. This keeps you on the right side of the larger trend and filters out counter-trend Wave 2 entries that fail.

Strategy 2: Wave 5 Divergence Short

Market type: Trend exhaustion (topping)

Entry conditions:

  1. Price makes a higher high above the Wave 3 peak.
  2. EWO makes a lower high compared to its Wave 3 reading (bearish divergence).
  3. EWO drops below the zero line after the higher high.
  4. At least one bearish candlestick pattern confirms (bearish engulfing or shooting star).

Exit conditions:

  1. Exit when EWO turns positive again (Wave A of the correction is complete).
  2. Trailing stop at 2x ATR(14) below the entry candle low.

Stop loss: Place 1 ATR(14) above the Wave 5 high. If price breaks higher, the divergence was invalid and the Wave 5 is extending.

Improvement: Add RSI(14) divergence confirmation. If RSI also shows a lower high during the same price higher high, the setup is worth a larger position.

Strategy 3: EWO + Supertrend Trend Ride

Market type: Trending (sustained impulse)

Entry conditions:

  1. EWO crosses above zero after a Wave 2 retracement.
  2. Supertrend(10, 3) flips to green (uptrend).
  3. Price closes above both the Wave 1 high and the 20-period EMA.
  4. ATR(14) is above its 20-period average (expanding volatility).

Exit conditions:

  1. Exit when the Supertrend flips to red.
  2. Alternative exit: when EWO drops below zero after making a divergence lower high.

Stop loss: Place below the most recent swing low (Wave 2 low or the entry bar low, whichever is tighter).

Improvement: Add volume confirmation. Enter only when volume on the breakout bar exceeds the 20-period average volume by at least 50%. This filters out low-volume breakouts that often fail in crypto.

Strategy Comparison

StrategyMarket TypeWin Rate RangeBest PairRisk Level
Wave 3 MomentumTrending~55-65%BTC/USDT DailyMedium
Wave 5 DivergenceTopping~50-60%SPY DailyMedium
EWO + SupertrendTrending~50-60%ETH/USDT 4HLow

Win rate ranges shown are approximate illustrations based on backtesting on major pairs. They vary by market conditions, timeframe, and execution quality. These strategies are for educational purposes only and do not constitute investment advice. Past performance does not guarantee future results.

EWO vs. Similar Indicators

The EWO is often compared with MACD, AO (Awesome Oscillator), and the standard SMA Crossover. Here is how they stack up.

FeatureEWOMACDAwesome Oscillator
TypeSMA-based momentumEMA-based momentumSMA-based momentum
LagMediumLow (EMAs react faster)Medium
Signal lineNoneYes (9-period EMA)None
Best forElliott Wave countingGeneral trend momentumTrend confirmation
Signals per day (Daily)~1-3~1-2~2-4
Percent modeYesNoNo

I reach for the EWO when I am focused on wave counting. The 5/35 SMA setup directly maps to Elliott Wave structure in a way that MACD does not. MACD is my go-to for general momentum. The signal line gives me objective crossover rules. The Awesome Oscillator, created by Bill Williams, uses a similar SMA structure (5/34) but applies it differently. It compares the midpoint of each bar, not the close, and uses a simple moving average of the midpoints rather than a direct SMA subtraction. For pure wave analysis, EWO wins. For general purpose momentum trading, MACD is more flexible.

When the market is in a strong, clean trend, any of these three will work. When the market is complex and correcting, the EWO gives you the most useful information about wave structure.

Common EWO Mistakes and Limitations

Based on my own experience and feedback from other Elliott Wave traders, these are the most frequent errors when using the EWO.

  1. Trading every zero line crossover. The EWO crosses zero 10-15 times in a choppy month. Each crossover looks like a signal on the histogram, but most of them correspond to nothing in the wave structure. The fix: only act on crossovers that align with a clear Elliott Wave count. If price is making higher highs and higher lows, a bullish crossover confirms Wave 3. If price is sideways, ignore every crossover.
  2. Ignoring divergence during Wave 5. The EWO nearly always makes a lower high during Wave 5 compared to Wave 3. This divergence is one of the most reliable signals the indicator produces. Most traders watch the histogram colors and miss the peak comparison. The fix: mark the EWO high during Wave 3. If price pushes higher but the EWO cannot beat its Wave 3 high, you have a divergence. Take note. The trend is exhausted.
  3. Using EWO on 1M charts. The 5-period SMA flips every bar. The 35-period SMA barely moves. The result is a noisy oscillator that jumps between green and red with no meaningful wave structure. The fix: stay on 4H or above. If you must trade lower timeframes, change the fast SMA to 3 and the slow SMA to 21, but even then, 15M is the practical floor.
  4. Forgetting to turn on percent mode across assets. An EWO reading of 5 on BTC at 60,000 is completely different from an EWO reading of 5 on AAPL at 200. Without percent mode, the indicator values are not comparable across instruments. The fix: always use percent mode when scanning multiple tickers or setting up screeners. It normalizes the values so a 1% EWO means the same thing on any asset.
  5. Assuming every impulse move follows a perfect 5-wave structure. The EWO makes wave counting easier, but markets do not always cooperate. Extended waves, truncated waves, and running flats break the textbook pattern. The EWO will show peaks and troughs, but those peaks may not correspond to the expected wave number. The fix: stay flexible. Use the EWO as one tool in a broader analysis that includes price structure, volume, and higher timeframe context.
  6. Not accounting for gap opens. SMAs are sensitive to gap openings. A gap up on a daily chart pulls the 5-period SMA up instantly while the 35-period SMA barely changes. The EWO spikes. This spike is a mechanical artifact, not a genuine signal. The fix: wait for 2-3 bars after a gap before reading EWO values. Let the SMAs normalize before drawing any conclusions.

How to Generate the EWO Pine Script in Pineify

Pineify lets you generate this exact EWO Pine Script without writing a single line of code. Follow these steps to get your own customizable version running in TradingView.

  1. 1

    Open the Pineify indicator generator.

    Go to the indicator selection page and browse the Momentum category or search for "Elliott Wave Oscillator".

  2. 2

    Set your parameters.

    Choose the fast SMA length, slow SMA length, and price source. Toggle the percent mode switch based on your asset type. The default 5/35 works for most daily charts.

  3. 3

    Customize colors and styling.

    Adjust the positive and negative histogram colors and choose your line width. Pineify lets you preview changes before exporting.

  4. 4

    Copy the generated code.

    Pineify outputs clean, standalone Pine Script v6 code with your chosen parameters baked in. One click copies everything to your clipboard.

  5. 5

    Paste into TradingView and start analyzing.

    Open the Pine Script editor (Alt+P), paste the code, and click Add to Chart. The EWO histogram appears below your chart, ready for wave counting.

Elliott Wave Oscillator FAQ

Generate Your EWO Pine Script in Seconds

No coding required. Customize parameters, preview instantly, and paste into TradingView.