Generate code in 3 minutes
Enter your idea and AI generates runnable code.
Here is a complete, fully functional Expert Advisor (trading bot) for MetaTrader 4 that uses Heikin-Ashi candles for trading decisions.
This bot uses a Trend Reversal strategy based on Heikin-Ashi color changes:
//+------------------------------------------------------------------+
//| 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;
}
//+------------------------------------------------------------------+
F4 to open the MetaEditor.F7 to Compile. Ensure there are no errors.CalculateHeikinAshi function). It does not require you to download or install a separate custom indicator file (ex4), making it very reliable.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.