Generate code in 3 minutes
Enter your idea and AI generates runnable code.
To build a trading robot (Expert Advisor) using the Accumulation/Distribution (A/D) indicator, it is important to understand that A/D is primarily a volume-based trend confirmation tool. It is rarely used as a standalone trigger for entering trades.
A robust strategy usually combines a Trend Trigger (like a Moving Average crossover) with the A/D Indicator acting as a filter to confirm the volume supports the price movement.
//+------------------------------------------------------------------+
//| AD_Trend_Confirm_Robot.mq4 |
//| Copyright 2023, Quantitative Trading AI |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative Trading AI"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input double Lots = 0.1; // Trading volume
input int StopLoss = 50; // Stop Loss in pips
input int TakeProfit = 100; // Take Profit in pips
input int FastMAPeriod = 12; // Fast Moving Average Period
input int SlowMAPeriod = 26; // Slow Moving Average Period
input int MagicNumber = 123456; // Unique identifier for this EA
input int Slippage = 3; // Max slippage in pips
//--- Global Variables
double pipModifier;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Adjust pips for 3 or 5 digit brokers (Jpy pairs vs others)
if(Digits == 3 || Digits == 5)
pipModifier = 10 * Point;
else
pipModifier = Point;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. Check if we already have an open position for this symbol
if(OrdersTotal() > 0)
{
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
return; // Exit if a trade is already active
}
}
}
// 2. Define Indicator Values
// Moving Averages (Shift 1 is the closed bar, Shift 2 is the bar before that)
double fastMA_Curr = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
double fastMA_Prev = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
double slowMA_Curr = iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
double slowMA_Prev = iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
// Accumulation/Distribution
double ad_Curr = iAD(NULL, 0, 1);
double ad_Prev = iAD(NULL, 0, 2);
// 3. Trading Logic
// BUY SIGNAL
// Logic: Fast MA crosses Above Slow MA AND A/D is rising
if(fastMA_Prev < slowMA_Prev && fastMA_Curr > slowMA_Curr)
{
if(ad_Curr > ad_Prev) // A/D Confirmation
{
OpenBuyOrder();
}
}
// SELL SIGNAL
// Logic: Fast MA crosses Below Slow MA AND A/D is falling
if(fastMA_Prev > slowMA_Prev && fastMA_Curr < slowMA_Curr)
{
if(ad_Curr < ad_Prev) // A/D Confirmation
{
OpenSellOrder();
}
}
}
//+------------------------------------------------------------------+
//| Function to Open Buy Order |
//+------------------------------------------------------------------+
void OpenBuyOrder()
{
double sl = 0, tp = 0;
if(StopLoss > 0) sl = Ask - (StopLoss * pipModifier);
if(TakeProfit > 0) tp = Ask + (TakeProfit * pipModifier);
int ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, sl, tp, "AD Buy", MagicNumber, 0, clrGreen);
if(ticket < 0)
Print("OrderSend failed with error #", GetLastError());
}
//+------------------------------------------------------------------+
//| Function to Open Sell Order |
//+------------------------------------------------------------------+
void OpenSellOrder()
{
double sl = 0, tp = 0;
if(StopLoss > 0) sl = Bid + (StopLoss * pipModifier);
if(TakeProfit > 0) tp = Bid - (TakeProfit * pipModifier);
int ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, sl, tp, "AD Sell", MagicNumber, 0, clrRed);
if(ticket < 0)
Print("OrderSend failed with error #", GetLastError());
}
//+------------------------------------------------------------------+
Inputs:
FastMAPeriod and SlowMAPeriod: Define the sensitivity of the trend trigger.StopLoss and TakeProfit: Standard risk management inputs defined in pips.OnInit():
pipModifier. This ensures the Stop Loss and Take Profit are calculated correctly regardless of whether the broker uses 4-digit or 5-digit pricing (e.g., EURUSD at 1.1000 vs 1.10005).OnTick() - The Main Logic:
MagicNumber on the current Symbol exists, the function returns immediately. This prevents the bot from opening multiple trades on the same signal.iMA: Calculates the Moving Average. We retrieve values for shift 1 (the last closed candle) and shift 2 (the candle before that) to detect the "crossover" moment.iAD: Calculates the Accumulation/Distribution value.ad_Curr > ad_Prev to confirm that volume accumulation is supporting the move.ad_Curr < ad_Prev.Order Execution:
OpenBuyOrder and OpenSellOrder handle the specific OrderSend calls, calculating the correct SL and TP prices based on the current Ask/Bid prices.Q: Why use A/D instead of standard Volume?
A: Standard volume only tells you intensity. Accumulation/Distribution attempts to quantify the flow of money into or out of an asset by considering the close price relative to the high-low range. It provides a directional bias to the volume.
Q: Can I use A/D as the primary trigger?
A: It is not recommended. The A/D line is cumulative and unbounded. It does not oscillate between 0 and 100 like RSI. Therefore, it is difficult to define specific "overbought" or "oversold" levels to trigger a trade. It works best as a filter for price-action triggers.
Q: How can I reduce false signals with this bot?
A: Currently, the bot compares A/D of the current bar vs the previous bar. This can be noisy. To smooth this out, you could calculate a Moving Average of the A/D indicator itself and require the A/D line to be above its own Moving Average for a Buy, rather than just higher than the previous candle.