Problem Description
Solution
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.
1. Preparation
Before coding, ensure the custom indicator file (.ex4 or .mq4) is located in the correct folder:
- File Path:
Open Data Folder->MQL4->Indicators. - Name: Note the exact file name (e.g.,
SuperTrend.ex4).
2. Identify Buffers and Inputs
To automate the strategy, you need to know two things about the indicator:
- Input Parameters: Does the indicator require settings (e.g., Period, Multiplier)? You must pass these to
iCustomin the exact order they appear in the indicator settings. - Buffer Indices: Which "line" contains the data?
- Open the indicator on a chart.
- Open the Data Window (Ctrl+D).
- Hover over a candle where the indicator shows a signal.
- Note which value changes. The first value in the Data Window is Buffer 0, the second is Buffer 1, etc.
3. The iCustom Function Syntax
double 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)
);
4. Implementation Example
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.
- Buffer 0: Buy Arrow (Non-empty value means Buy).
- Buffer 1: Sell Arrow (Non-empty value means Sell).
//+------------------------------------------------------------------+
//| 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());
}
}
Key Considerations for iCustom
1. Handling "Empty" Values
Custom 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.
- Standard Empty Value:
2147483647(MQL4 constantEMPTY_VALUE). - Zero: Some indicators explicitly return
0. - Logic: Always check
if (value != EMPTY_VALUE && value != 0)to confirm a signal exists.
2. Passing Inputs Correctly
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.
- Incorrect:
iCustom(NULL, 0, "Name", 0, 1);(Inputs ignored). - Correct:
iCustom(NULL, 0, "Name", 10, true, 0, 1);(Inputs passed).
3. Performance
Calling iCustom on every tick can be resource-intensive if the indicator calculation is heavy.
- Optimization: If the indicator logic allows, check for signals only when a new bar opens (
if(Volume[0] == 1)), or ensure the indicator code itself is optimized.
4. Repainting
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."
- Best Practice: Read the value of shift 1 (the previously closed candle) to ensure the signal is permanent.
Q&A: Custom Indicators in MQL4
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.