Anchored VWAP + EMA Crossover

Anchored VWAP + EMA Crossover

19 September 2026, 18:50
Jose Rodrgues Chaves
0
25

Building an Anchored VWAP + EMA Crossover Indicator in MQL5 — A Concept Walkthrough

How I combined anchored VWAP with a 9-period EMA to create a single, bias-gated signal system — and the design decisions that keep it clean.

The Idea Behind VWAP + EMA Crossover

Anchored VWAP and the 9-period EMA answer two different questions. VWAP tells you where the market's average participant is positioned — the volume-weighted center of gravity. The EMA tells you where price is right now relative to recent momentum.

On their own, each has well-known weaknesses. VWAP lags on strong trends. The EMA whipsaws in ranges. But when the two are combined into a cross-based bias filter, something useful emerges:

  • When the EMA crosses above VWAP, the market has shifted to favoring buyers — set a bullish bias.
  • When the EMA crosses below VWAP, the market has shifted to favoring sellers — set a bearish bias.
  • Price/EMA crosses only fire in the direction of the active bias.
  • A close against the EMA in the opposite direction marks an exit.

The result is a small, self-contained system: one line of context (VWAP), one line of momentum (EMA), and a set of bias-gated signals. No bands, no oscillators, no clutter.

This blog walks through how it works and the design decisions behind it. The source is not posted — the indicator is on the MQL5 Market — but the concepts are worth sharing.


The Core Inputs

The indicator is organized around six groups of settings:

Anchor Settings:
    Anchor Type        — where to start the VWAP calculation
    Anchor Date        — manual start date (if Manual mode)
    Anchor Bar Number  — bar offset from current (if Bar Number mode)
    Extend to Right     — whether the VWAP extends to the current bar

Period Filter:
    Periods to Show    — how many anchor periods to display

VWAP Settings:
    Color, Width, Style

EMA Settings:
    EMA Period         — default 9
    Color, Width, Style

Crossover Settings:
    Show Arrows        — toggle the EMA/VWAP crossover markers
    Bull / Bear Colors

Price/EMA Crossover:
    Show Price/EMA     — toggle price/EMA signals (bias-gated)
    Buy / Sell Colors

Alerts:
    Separate toggles and sound files for crossover, entry, and exit

Three design choices stand out:

  • Anchor is configurable. VWAP is only meaningful relative to where you start it. Session, weekly, monthly, manual date, or any chart bar — all supported. Different traders use different anchors, so the choice belongs in the inputs, not the code.
  • Signals are opt-in. The crossover arrows are on by default. Price/EMA signals are off by default. Exit signals fire automatically once a trade is active. This layering lets a trader use as much or as little as they want.
  • Alerts are separated by category. Crossover alerts, entry alerts, and exit alerts have independent toggles and sound files. Some traders want a sound on entry but silence on exit. Others want the opposite. Independent toggles make both possible.

How the VWAP Line Is Built

VWAP is the volume-weighted average of typical price, computed from the anchor bar forward. The typical price is (high + low + close) / 3 , and the running sum is updated bar by bar:

Starting at the anchor bar and moving forward:

    typical_price = (high + low + close) / 3
    cumulative_pv += typical_price * volume
    cumulative_volume += volume
    VWAP[bar] = cumulative_pv / cumulative_volume

Two implementation details matter more than they look:

  • Volume fallback. If tick volume is zero — common on some instruments or off-hours — the code falls back to real volume. If both are zero, the bar is skipped and the cumulative volume is unchanged.
  • Zero-guard on division. If cumulative volume is still zero (the very first bars of a new anchor), the buffer is written as zero rather than producing a divide-by-zero result.

The indicator supports five anchor modes, and each is handled slightly differently at the "find the anchor bar" stage. The rest of the pipeline is identical regardless of which anchor is chosen — a single compute function drives all modes.


Anchored Modes and Their Reset Behavior

The five anchor modes are:

Manual Date       — start at the first bar at or after a given datetime.
Chart Bar         — start N bars back from the current bar.
All Days          — draw a fresh VWAP for every day, showing the last N days.
Session Start     — start at today's midnight (or session open).
Weekly / Monthly  — start at the beginning of the current week or month.

The first two modes are "single-anchor" — one continuous VWAP line. The last three are "multi-period" — a separate VWAP is computed for each day, week, or month, and only the most recent N periods are drawn.

Multi-period mode needs a careful reset each time a new period begins:

On each new closed bar:

    If the period key changed from the previous bar:
        Finalize the previous period's cumulative values.
        Start a new period with zeroed accumulators.

    Add the current bar's typical price × volume to the active period.

    Write the running VWAP into the buffer at this bar.

After processing:
    If the number of stored periods exceeds the display limit,
    drop the oldest periods and clear their VWAP buffer values.

The period key is time-based, not bar-index-based. This matters because bar indices shift when MT5 drops old history; time does not. Any time you need to know "has a new period started," compare timestamps, not indices.


How the EMA Is Computed

The EMA is a straightforward exponential moving average over the close price, with the standard Wilder-style seeding:

alpha = 2 / (period + 1)

For each bar:
    If this is the first bar with a valid close:
        EMA[bar] = close[bar]     (seed with the source value)
    Else:
        EMA[bar] = alpha * close[bar] + (1 - alpha) * EMA[bar - 1]

Seeding with the source value — not zero — avoids a distorted EMA for the first few dozen bars. This is the same principle I use in every indicator that computes an EMA from scratch. The built-in iMA handle does this internally, but computing it manually gives full control over when the seed occurs and how the buffer is initialized.


Vwap Ema Crossover


The Bias State Machine

The heart of the indicator is a small state machine with three possible states:

BIAS_NONE  — no crossover has occurred yet
BIAS_BULL  — EMA is above VWAP
BIAS_BEAR  — EMA is below VWAP

Transitions happen only on crossovers of the EMA and VWAP lines, and only on closed bars:

On each closed bar i:

    If EMA[i] > VWAP[i] and EMA[i-1] <= VWAP[i-1]:
        Set BIAS_BULL.
        Draw a bullish crossover arrow at this bar.
        Clear any active sell trade state.
        If price/EMA signals are disabled, arm a buy trade.
        Fire the crossover alert (if enabled and armed).

    If EMA[i] < VWAP[i] and EMA[i-1] >= VWAP[i-1]:
        Set BIAS_BEAR.
        Draw a bearish crossover arrow at this bar.
        Clear any active buy trade state.
        If price/EMA signals are disabled, arm a sell trade.
        Fire the crossover alert (if enabled and armed).

Notice the two-arm pattern. When price/EMA signals are enabled, the crossover only sets the bias — the actual buy/sell signals come from price crossing the EMA in the direction of the bias. When price/EMA signals are disabled, the crossover itself acts as the entry trigger.

This dual behavior lets the indicator work in two very different styles: as a complete entry/exit system (with price/EMA enabled) or as a simple bias-only trend filter (with price/EMA disabled).


Price/EMA Signals — Gated by Bias

When price/EMA signals are enabled, they only fire in the direction of the active bias:

On each closed bar i:

    If bias is BULL and close[i] > EMA[i] and close[i-1] <= EMA[i-1]:
        Draw a buy cross arrow below the low.
        Mark that a buy trade is active.
        Fire the entry alert (if enabled and armed).

    If bias is BEAR and close[i] < EMA[i] and close[i-1] >= EMA[i-1]:
        Draw a sell cross arrow above the high.
        Mark that a sell trade is active.
        Fire the entry alert (if enabled and armed).

The bias gate is what makes this more than just a moving average crossover. Without it, price/EMA crosses happen dozens of times a day on lower timeframes. With the bias filter, only the crosses that occur in the direction of the higher-level trend structure are kept.

The result is a dramatically reduced signal count with no loss of the important ones. Most importantly, no signals fire against the current bias — which is exactly what you want from a trend-following system.


Exit Signals

Once a trade is active, an exit signal fires when price closes against the EMA:

If a buy trade is active:
    On each closed bar:
        If close[i] < EMA[i] and close[i-1] >= EMA[i-1]:
            Draw an exit X above the high.
            Mark the buy trade as closed.
            Fire the exit alert (if enabled and armed).

If a sell trade is active:
    On each closed bar:
        If close[i] > EMA[i] and close[i-1] <= EMA[i-1]:
            Draw an exit X below the low.
            Mark the sell trade as closed.
            Fire the exit alert (if enabled and armed).

Exit signals use two different X markers — one color for closing a buy, another for closing a sell. Keeping the marker distinct means a trader can distinguish at a glance between "this is where I would exit a long" and "this is where I would exit a short."


The Alert Arming Mechanism

One of the subtle design problems in this indicator is when to start firing alerts. On the initial chart load, the indicator must rebuild hundreds or thousands of bars of VWAP and EMA history. If alerts fire during that rebuild, the user gets buried in a flood of historical notifications for signals that already happened.

The solution is a two-stage arming mechanism:

Stage 1 — Rebuild phase:
    On the first calculation pass after loading:
        Rebuild the entire VWAP and EMA history silently.
        Record the index of the last closed bar processed.
        Leave alerts disarmed.

Stage 2 — Armed phase:
    On subsequent passes:
        If the last processed bar index has advanced past the
        recorded index, arm alerts.
        From this point on, alerts fire normally.

The result is that alerts only ever fire for events that occur after the indicator has fully loaded. Historical signals still display on the chart as arrows — but they do not generate alert noise.

This is a pattern worth remembering for any indicator that fires alerts. The question "has the initial rebuild completed?" is easy to answer, but easy to forget to ask.


What the Indicator Does Not Do

To be clear about what this is:

  • It does not predict price direction.
  • It does not manage positions, lots, or stops.
  • It does not use any repainting logic — every signal is derived from closed bars only.
  • The VWAP and EMA lines extend to the current bar, but the signal markers never repaint.

It is a signal and bias tool. The VWAP line shows the market's average participant; the EMA line shows the momentum; the crossover establishes bias; the price/EMA signals show entries and exits within that bias. What you do with those signals is entirely up to you.


What I Learned Building It

  1. Anchored VWAP is more flexible than it looks. Most traders think of it as a session-level tool. Anchoring it to a specific bar or a weekly open produces very different — and sometimes more useful — contexts.
  2. Bias gating transforms signal quality. A raw price/EMA crossover indicator is unusable. The same signals filtered by a higher-level bias (VWAP/EMA) become tradeable. One extra condition, dramatically different outcome.
  3. Alert arming is not optional. Any indicator that fires alerts during historical rebuild will annoy users into turning alerts off entirely. The two-stage arming mechanism is a small addition with a large usability impact.
  4. Separate alerts for separate events. Crossover, entry, and exit are three distinct events. Giving each its own toggle and its own sound file lets the user tune the indicator to their workflow instead of the other way around.

Wrapping Up

Anchored VWAP + EMA Crossover is a small indicator with a clear purpose: combine a volume-weighted context line with a fast momentum line, then gate all signals by the resulting bias. The result is a self-contained bias and signal system that works on any symbol and any timeframe.

The full version is available on the MQL5 Market — the link is in my profile. If you find any of the design principles here useful — anchor flexibility, bias gating, alert arming, or per-category alert separation — feel free to apply them in your own indicators. Those patterns are not unique to this tool; they are worth knowing regardless of what you build.

Trade safely.

— Jose Rodrigues Chaves


About the author: Independent MQL5 developer. Interested in volume-weighted context tools, momentum-based signals, and clean indicator design. All opinions are my own.