Generate code in 3 minutes
Enter your idea and AI generates runnable code.
To use a custom indicator in an automated trading strategy (Expert Advisor) in MQL4, you must use the iCustom() function. This function allows your EA to read the values of the indicator buffers (lines, arrows, or histograms) calculated by the custom indicator.
Here is the step-by-step guide and the code implementation.
Before coding, ensure the custom indicator file (.ex4 or .mq4) is located in the correct folder:
Open Data Folder -> MQL4 -> Indicators.SuperTrend.ex4).To automate the strategy, you need to know two things about the indicator:
iCustom in the exact order they appear in the indicator settings.iCustom Function Syntaxdouble value = iCustom(
NULL, // Symbol (NULL = current)
0, // Timeframe (0 = current)
"IndicatorName",// Exact file name of the indicator (no extension)
...inputs..., // (Optional) List of indicator inputs in order
buffer_index, // Which line to read (0, 1, 2...)
shift // Shift (0 = current candle, 1 = previous candle)
);
Below is a complete Expert Advisor template. This example assumes we are using a custom indicator named "MyCustomIndicator" that draws arrows for buy/sell signals.
//+------------------------------------------------------------------+
//| CustomIndicatorEA.mq4 |
//| Copyright 2023, Quantitative AI Assistant |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI Assistant"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
// --- Input Parameters for the EA ---
input double Lots = 0.1;
input int StopLoss = 50;
input int TakeProfit = 100;
input int MagicNumber = 123456;
// --- Input Parameters for the Custom Indicator ---
// These must match the indicator's inputs exactly in type and order
input int Ind_Period = 14;
input double Ind_Deviation = 2.0;
// Global variables
int Ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// We usually check for signals on the close of the previous bar (shift 1)
// to ensure the indicator signal is confirmed and won't repaint.
int shift = 1;
// --- 1. Call iCustom to get values ---
// Syntax: Symbol, Timeframe, "FileName", Input1, Input2, ..., BufferIndex, Shift
// Reading Buffer 0 (Assumed Buy Signal)
double buySignal = iCustom(NULL, 0, "MyCustomIndicator", Ind_Period, Ind_Deviation, 0, shift);
// Reading Buffer 1 (Assumed Sell Signal)
double sellSignal = iCustom(NULL, 0, "MyCustomIndicator", Ind_Period, Ind_Deviation, 1, shift);
// --- 2. Check for Trading Logic ---
// Many indicators use EMPTY_VALUE (2147483647) or 0 to signify "no signal".
// We check if the value exists (is not empty).
// BUY LOGIC
if(buySignal != EMPTY_VALUE && buySignal != 0)
{
if(OrdersTotal() == 0) // Simple check to open one trade at a time
{
OpenTrade(OP_BUY);
}
}
// SELL LOGIC
if(sellSignal != EMPTY_VALUE && sellSignal != 0)
{
if(OrdersTotal() == 0)
{
OpenTrade(OP_SELL);
}
}
}
//+------------------------------------------------------------------+
//| Helper function to open trades |
//+------------------------------------------------------------------+
void OpenTrade(int type)
{
double sl = 0, tp = 0;
double price = 0;
if(type == OP_BUY)
{
price = Ask;
if(StopLoss > 0) sl = Ask - StopLoss * Point;
if(TakeProfit > 0) tp = Ask + TakeProfit * Point;
}
else if(type == OP_SELL)
{
price = Bid;
if(StopLoss > 0) sl = Bid + StopLoss * Point;
if(TakeProfit > 0) tp = Bid - TakeProfit * Point;
}
Ticket = OrderSend(Symbol(), type, Lots, price, 3, sl, tp, "Custom Ind EA", MagicNumber, 0, clrBlue);
if(Ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
}
iCustomCustom indicators rarely return 0 for "no signal". They usually return a specific "Empty Value" constant to prevent drawing lines on the chart where there is no data.
2147483647 (MQL4 constant EMPTY_VALUE).0.if (value != EMPTY_VALUE && value != 0) to confirm a signal exists.If your custom indicator has inputs (e.g., input int Length = 10; and input bool Filter = true;), you must pass them to iCustom between the indicator name and the buffer index.
iCustom(NULL, 0, "Name", 0, 1); (Inputs ignored).iCustom(NULL, 0, "Name", 10, true, 0, 1); (Inputs passed).Calling iCustom on every tick can be resource-intensive if the indicator calculation is heavy.
if(Volume[0] == 1)), or ensure the indicator code itself is optimized.If you read the value of the current candle (shift 0), the indicator value might change as the price moves before the candle closes. This is called "repainting."
Q: How do I find out how many buffers an indicator has?
A: Look at the source code (.mq4) for the line #property indicator_buffers X. If you only have the .ex4 file, use the "Data Window" (Ctrl+D) in MetaTrader 4 and count the values displayed when you hover over the chart.
Q: My EA is not trading, but the indicator shows arrows. Why?
A: This usually happens because of incorrect Buffer Indices. The arrow you see might be Buffer 2 or 3, not 0 or 1. Check the Data Window carefully. Also, ensure you are passing the correct input parameters to iCustom.
Q: Can I use an indicator located in a subfolder?
A: Yes. If your indicator is in MQL4/Indicators/MyFolder/Indi.ex4, you write the name as "MyFolder\\Indi" (using a double backslash).
Q: What if the indicator returns a color change instead of a value?
A: MQL4 indicators usually use separate buffers for different colors. For example, a line might use Buffer 0 for Green (Uptrend) and Buffer 1 for Red (Downtrend). You need to check which buffer has a non-empty value at that specific moment.