🚀 AI One-Click Generation of mql4 Strategy Code

How to Code a Heikin-Ashi Smoothed Trend Strategy in Mql4

mql4 | Published on: 2025/12/15
The following content is generated by EasyQuant .

Problem Description

Can you show me how to code a trading bot that uses Heikin-Ashi candles for its entry and exit signals?

Solution

Here is a complete, fully functional Expert Advisor (trading bot) for MetaTrader 4 that uses Heikin-Ashi candles for trading decisions.

The Strategy Logic

This bot uses a Trend Reversal strategy based on Heikin-Ashi color changes:

  1. Buy Signal: The previous Heikin-Ashi candle was Red (Bearish), and the current closed Heikin-Ashi candle is Green (Bullish).
  2. Sell Signal: The previous Heikin-Ashi candle was Green (Bullish), and the current closed Heikin-Ashi candle is Red (Bearish).
  3. Exit Rule: It closes the position if the Heikin-Ashi color changes against the trade direction (or hits Stop Loss/Take Profit).

MQL4 Code

//+------------------------------------------------------------------+
//|                                             HeikinAshi_Bot.mq4   |
//|                                  Copyright 2023, Quantitative AI |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Input Parameters
input double InpLots          = 0.1;   // Lot Size
input int    InpStopLoss      = 50;    // Stop Loss in pips (0 = none)
input int    InpTakeProfit    = 100;   // Take Profit in pips (0 = none)
input int    InpMagicNumber   = 12345; // Magic Number to identify orders
input int    InpSlippage      = 3;     // Max Slippage in pips

//--- Global Variables
double m_point;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Adjust point for 3/5 digit brokers
   if(Digits == 3 || Digits == 5) m_point = Point * 10;
   else m_point = Point;
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // We only trade on the close of a bar, but for simplicity in this example,
   // we check conditions every tick. The logic ensures we don't open multiple trades
   // because we check if an order is already open.

   // 1. Calculate Heikin Ashi values for the last two closed candles (Index 1 and 2)
   double haOpen1, haClose1, haOpen2, haClose2;
   
   // Get HA values for Bar 1 (Most recently closed)
   CalculateHeikinAshi(1, haOpen1, haClose1);
   
   // Get HA values for Bar 2 (The one before that)
   CalculateHeikinAshi(2, haOpen2, haClose2);

   // 2. Determine Candle Colors (Green/Bullish or Red/Bearish)
   bool isBullish1 = (haClose1 > haOpen1);
   bool isBearish1 = (haClose1 < haOpen1);
   
   bool isBullish2 = (haClose2 > haOpen2);
   bool isBearish2 = (haClose2 < haOpen2);

   // 3. Manage Open Positions (Exit Logic)
   if(OrdersTotal() > 0)
   {
      for(int i = OrdersTotal() - 1; i >= 0; i--)
      {
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
            if(OrderMagicNumber() == InpMagicNumber && OrderSymbol() == Symbol())
            {
               // Close Buy if Candle 1 turns Bearish
               if(OrderType() == OP_BUY && isBearish1)
               {
                  bool closed = OrderClose(OrderTicket(), OrderLots(), Bid, InpSlippage, clrRed);
               }
               // Close Sell if Candle 1 turns Bullish
               if(OrderType() == OP_SELL && isBullish1)
               {
                  bool closed = OrderClose(OrderTicket(), OrderLots(), Ask, InpSlippage, clrGreen);
               }
            }
         }
      }
   }

   // 4. Check for Entry Signals (Only if no orders are open for this symbol/magic)
   if(CountOpenOrders() == 0)
   {
      // BUY SIGNAL: Bar 2 was Bearish, Bar 1 is Bullish (Color Flip)
      if(isBearish2 && isBullish1)
      {
         double sl = (InpStopLoss > 0) ? Ask - InpStopLoss * m_point : 0;
         double tp = (InpTakeProfit > 0) ? Ask + InpTakeProfit * m_point : 0;
         
         int ticket = OrderSend(Symbol(), OP_BUY, InpLots, Ask, InpSlippage, sl, tp, "HA Buy", InpMagicNumber, 0, clrBlue);
         if(ticket < 0) Print("OrderSend failed with error #", GetLastError());
      }
      
      // SELL SIGNAL: Bar 2 was Bullish, Bar 1 is Bearish (Color Flip)
      if(isBullish2 && isBearish1)
      {
         double sl = (InpStopLoss > 0) ? Bid + InpStopLoss * m_point : 0;
         double tp = (InpTakeProfit > 0) ? Bid - InpTakeProfit * m_point : 0;
         
         int ticket = OrderSend(Symbol(), OP_SELL, InpLots, Bid, InpSlippage, sl, tp, "HA Sell", InpMagicNumber, 0, clrRed);
         if(ticket < 0) Print("OrderSend failed with error #", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+
//| Helper: Calculate Heikin Ashi values manually                    |
//| This makes the EA standalone (no custom indicators needed)       |
//+------------------------------------------------------------------+
void CalculateHeikinAshi(int index, double& haOpen, double& haClose)
{
   // HA Close is the average of OHLC
   haClose = (Open[index] + High[index] + Low[index] + Close[index]) / 4.0;
   
   // HA Open is the average of the PREVIOUS HA Open and HA Close.
   // Since we don't store history in arrays here, we approximate by smoothing 
   // over a small loop of previous bars to stabilize the value.
   
   double prevOpen  = Open[index + 10]; 
   double prevClose = Close[index + 10];
   
   // Loop forward from 10 bars back to the requested index to calculate accurate HA Open
   for(int i = index + 10; i >= index; i--)
   {
      double tempClose = (Open[i] + High[i] + Low[i] + Close[i]) / 4.0;
      
      // Standard HA Open formula: (PrevHAOpen + PrevHAClose) / 2
      double tempOpen = (prevOpen + prevClose) / 2.0;
      
      prevOpen = tempOpen;
      prevClose = tempClose;
   }
   
   haOpen = prevOpen;
}

//+------------------------------------------------------------------+
//| Helper: Count open orders for this EA                            |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagicNumber)
            count++;
      }
   }
   return count;
}
//+------------------------------------------------------------------+

How to Install and Run

  1. Open MetaTrader 4.
  2. Press F4 to open the MetaEditor.
  3. Click New -> Expert Advisor (template) -> Name it "HeikinAshi_Bot".
  4. Delete everything in the new file and paste the code above.
  5. Press F7 to Compile. Ensure there are no errors.
  6. Go back to the MT4 terminal. You will find "HeikinAshi_Bot" in the Navigator window under Expert Advisors.
  7. Drag it onto a chart (e.g., EURUSD H1).
  8. Ensure the "AutoTrading" button at the top is Green.

Key Features of This Code

  1. Standalone Calculation: It calculates Heikin-Ashi values mathematically inside the code (CalculateHeikinAshi function). It does not require you to download or install a separate custom indicator file (ex4), making it very reliable.
  2. 5-Digit Broker Support: It automatically detects if your broker uses 5 digits (points) or 4 digits (pips) and adjusts the Stop Loss and Take Profit calculations accordingly.
  3. Risk Management: Includes inputs for Stop Loss and Take Profit.
  4. Exit Logic: It will close a trade immediately if the Heikin-Ashi candle changes color against your trade, even if the Stop Loss hasn't been hit yet. This is crucial for trend-following strategies.

Q&A

Q: Why does the bot calculate HA values using a loop?
A: The Heikin-Ashi "Open" price depends on the previous Heikin-Ashi Open and Close. To get an accurate value without storing years of history in memory, we calculate a small sequence (10 bars back) to let the mathematical formula stabilize. This ensures the values match what you see on your chart.

Q: Can I use this on any timeframe?
A: Yes. However, Heikin-Ashi strategies usually perform better on higher timeframes (H1, H4, Daily) because they filter out the "noise" found on M1 or M5 charts.

Q: Why does it wait for the candle to close (Index 1)?
A: Heikin-Ashi candles repaint while the current bar (Index 0) is forming. To avoid fake signals, the bot looks at Index 1 (the most recently completed bar) and Index 2 to confirm a color change.