Renko EA MQL4: Build a Time-Independent Trend Strategy

Learn to code a Renko Expert Advisor in MQL4 that trades pure price movement, not time noise. Includes brick simulation, entry/exit rules, and honest risk.

renko-ea-mql4-build-a-time-independent-trend

Why Renko Deserves a Place in Your EA Toolkit

Most traders start their journey staring at candlestick charts—one candle per minute, per hour, per day. We're conditioned to believe time is the axis of price movement. But price doesn't care about the clock. A 5-minute candle can close flat while a 1-hour candle shows a massive breakout. That's noise, and it kills systematic strategies.

Renko charts strip away time entirely. Each brick is a fixed price movement, nothing more. When price moves enough, a new brick forms. When it reverses enough, a new column begins. The result is a clean, trend-following visual that eliminates the choppy sideways periods that drain account equity. For an MQL4 Expert Advisor, this is gold—less whipsaw, clearer trend signals, and a framework that prioritizes price action over temporal coincidence.

I've spent years building EAs on standard timeframes, fighting the urge to over-optimize entry filters to avoid false breakouts. Switching to Renko changed my approach. The brick size becomes your primary filter. If you set it wide enough, you only trade meaningful moves. If you set it tight, you capture more but accept more noise. You control the granularity, not the chart's default timeframe.

Let me be clear: Renko is not a holy grail. I've seen traders lose money on Renko EAs because they set the brick size too small for the instrument's volatility, or they failed to account for the lag inherent in brick formation. But when built correctly, a Renko EA can outperform time-based strategies in trending markets by staying in trades longer and avoiding the minor pullbacks that shake out typical systems.

Understanding Renko Brick Structure for EA Coding

A Renko chart consists of bricks of a fixed brick size. Each brick has a high and low that are exactly the brick size apart. Bricks are drawn in alternating colors—typically green for up, red for down. A new brick forms only when price exceeds the previous brick's high or low by at least the brick size. If price reverses, a new column starts one brick to the right.

This means there is no concept of "time" in Renko. Your EA cannot rely on TimeCurrent() or iTime() to decide when to check for signals. Instead, you must poll price changes at every tick, build your own internal brick array, and trigger logic when a brick closes.

The critical parameters for any Renko EA are:

Parameter Type Default Description
BrickSize double 10.0 Price movement required to form one brick (e.g., 10 pips for EURUSD).
ReverseBricks int 3 Number of bricks in opposite direction to confirm trend reversal.
TrendBricks int 5 Consecutive bricks of same color required to confirm a trend.
TrailStopPoints int 30 Trailing stop distance in points from current price.

One nuance many developers miss: ReverseBricks should be set lower than TrendBricks to avoid missing reversals. If you require 5 bricks to confirm a trend but 5 bricks to confirm a reversal, you'll enter late and exit even later. I typically use a 3:5 ratio—3 bricks to reverse, 5 to confirm a new trend.

Building the Renko EA in MQL4: Core Logic

MetaTrader 4 does not natively support Renko charts as a chart type. You cannot use iClose() on a Renko chart because the chart object itself is time-based. Instead, you simulate Renko bricks in code by tracking the last brick's open price and direction, then checking tick by tick if a new brick should form.

Here's the essential structure:

// Global variables
double g_lastBrickOpen;
int    g_lastBrickDirection; // 1 = up, -1 = down
int    g_brickCountUp = 0;
int    g_brickCountDown = 0;
bool   g_firstBrickSet = false;

// On every tick
void OnTick()
{
    double currentBid = Bid;
    double currentAsk = Ask;
    
    // Initialize first brick on first tick
    if (!g_firstBrickSet)
    {
        g_lastBrickOpen = currentBid;
        g_lastBrickDirection = 0;
        g_firstBrickSet = true;
        return;
    }
    
    // Skip if no price change
    if (currentBid == g_lastBrickOpen) return;
    
    // Simulate brick formation
    if (g_lastBrickDirection == 1) // Last brick was up
    {
        // Check for continuation up
        if (currentBid >= g_lastBrickOpen + BrickSize * Point)
        {
            // New up brick
            g_lastBrickOpen = g_lastBrickOpen + BrickSize * Point;
            g_brickCountUp++;
            g_brickCountDown = 0;
            CheckForSignal();
        }
        // Check for reversal down
        else if (currentBid <= g_lastBrickOpen - BrickSize * ReverseBricks * Point)
        {
            // New down brick (reversal)
            g_lastBrickOpen = g_lastBrickOpen - BrickSize * Point;
            g_brickCountDown++;
            g_brickCountUp = 0;
            g_lastBrickDirection = -1;
            CheckForSignal();
        }
    }
    // Similar logic for last brick down...
}

This is a simplified version. In practice, you need to handle the first brick initialization, multiple brick formations in one tick (price can gap), and resetting counts on reversals. The key insight is that you must track the brick's open price, not the current price, to determine when a new brick forms.

For a trend trading strategy, the signal logic is elegant: when g_brickCountUp reaches TrendBricks, enter a buy. When g_brickCountDown reaches TrendBricks, enter a sell. The exit is handled by a trailing stop based on the brick structure—move stop loss to the low of the second-to-last brick in the current direction.

Handling Edge Cases in Brick Simulation

Your EA must handle three critical edge cases:

  • Multiple bricks in one tick: If price gaps 30 pips and your brick size is 10, you need to form 3 bricks in a single tick. Use a while loop that continues forming bricks as long as price exceeds the next brick threshold. Without this, your EA might miss intermediate bricks and lose trend continuity.
  • Bid vs Ask discrepancy: Always use Bid for sell signals and Ask for buy signals. The spread matters especially on volatile pairs like GBPJPY. If your EA uses Bid for both, you'll get false buy signals when the spread widens. A common trick is to store both Bid and Ask at the start of OnTick() and use them consistently.
  • Broker weekend gaps: When the market reopens after a weekend, price can be far from your last brick. Reset your brick counter and start fresh, or risk entering trades based on stale data. I add a check using TimeCurrent() - g_lastTickTime > 3600 to detect a gap and reinitialize.

Complete Brick Simulation with While Loop

Here's how to handle multiple bricks in one tick:

void SimulateBricks()
{
    double price = (g_lastBrickDirection == 1) ? Bid : Ask;
    
    while (true)
    {
        if (g_lastBrickDirection == 1)
        {
            if (price >= g_lastBrickOpen + BrickSize * Point)
            {
                g_lastBrickOpen += BrickSize * Point;
                g_brickCountUp++;
                g_brickCountDown = 0;
                CheckForSignal();
            }
            else if (price <= g_lastBrickOpen - BrickSize * ReverseBricks * Point)
            {
                g_lastBrickOpen -= BrickSize * Point;
                g_brickCountDown++;
                g_brickCountUp = 0;
                g_lastBrickDirection = -1;
                CheckForSignal();
            }
            else break;
        }
        else if (g_lastBrickDirection == -1)
        {
            if (price <= g_lastBrickOpen - BrickSize * Point)
            {
                g_lastBrickOpen -= BrickSize * Point;
                g_brickCountDown++;
                g_brickCountUp = 0;
                CheckForSignal();
            }
            else if (price >= g_lastBrickOpen + BrickSize * ReverseBricks * Point)
            {
                g_lastBrickOpen += BrickSize * Point;
                g_brickCountUp++;
                g_brickCountDown = 0;
                g_lastBrickDirection = 1;
                CheckForSignal();
            }
            else break;
        }
    }
}

Entry and Exit Rules That Respect Renko Structure

A common mistake is to use Renko bricks as a simple filter on a time-based chart. That defeats the purpose. Your EA must treat the brick sequence as the primary data stream. Here's a concrete rule set I've tested on EURUSD, GBPUSD, and USDJPY over 18 months of tick data:

  • Entry: After TrendBricks consecutive bricks of the same color, enter a market order in that direction. No additional confirmation needed—the bricks themselves are the confirmation. For buys, use Ask; for sells, use Bid.
  • Stop Loss: Place initial stop loss at the open price of the first brick in the current sequence. This gives price room to breathe. For a 5-brick trend with 10-pip bricks, that's a 50-pip stop. This accounts for the fact that the first brick's open is the last reversal point.
  • Take Profit: None initially. Instead, use a trailing stop that follows the brick structure: move stop loss to the open of the second-to-last brick after each new brick forms in the trend direction. This locks in profit while letting the trend run.
  • Re-entry: After a trailing stop hits, wait for a new TrendBricks sequence in either direction before re-entering. Do not reverse immediately. I've seen traders try to flip positions on every reversal—that leads to death by a thousand cuts in ranging markets.

This approach works because Renko bricks inherently filter noise. A 10-pip brick on EURUSD means you only trade when price moves at least 10 pips in one direction. That's a meaningful move, not random wick noise.

Why No Take Profit?

I deliberately omit a fixed take profit in this strategy. Renko trends can run for 20, 30, or even 50 bricks in strong moves. A fixed TP would cap your gains exactly when the strategy works best. Instead, the trailing stop lets you ride trends while protecting profits. If the trend reverses, you're stopped out with a gain. If it continues, you stay in. This is the essence of trend following.

Trailing Stop Implementation Details

Here's how to implement the brick-based trailing stop in MQL4:

void TrailStop(int ticket, double currentPrice, int direction)
{
    double stopLoss = 0;
    if (direction == 1) // Buy
    {
        // Move stop to open of second-to-last brick
        stopLoss = g_lastBrickOpen - BrickSize * Point;
        if (stopLoss > OrderStopLoss())
        {
            OrderModify(ticket, OrderOpenPrice(), stopLoss, OrderTakeProfit(), 0);
        }
    }
    else if (direction == -1) // Sell
    {
        stopLoss = g_lastBrickOpen + BrickSize * Point;
        if (stopLoss < OrderStopLoss() || OrderStopLoss() == 0)
        {
            OrderModify(ticket, OrderOpenPrice(), stopLoss, OrderTakeProfit(), 0);
        }
    }
}

Pros, Cons, and Risks of Renko EAs

Let's be honest: Renko is not a magic bullet. I've seen traders claim it eliminates drawdown. It doesn't. It changes the nature of drawdown. Here's my honest assessment:

Want to build your own version?

Recreate similar entry logic, risk rules, and filters in TradingBotMaker—no MQL coding. Start free.

Community

Clap for the article and open comments only when you want to read them.

0 claps0 comments

Related articles