🚀 AI One-Click Generation of mql4 Strategy Code

Mql4 Tutorial: How to Use iCustom() with Indicators That Have Multiple Buffers

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

Problem Description

I have a custom indicator with an arrow buffer and a line buffer. How do I get values from both buffers inside my EA?

Solution

To access values from a custom indicator with multiple buffers (like an arrow and a line) inside an Expert Advisor, you use the iCustom() function.

The key is identifying the Buffer Index (0 to 7) assigned to the arrow and the line, and ensuring you pass all the indicator's input parameters correctly.

Prerequisites: Finding the Buffer Indices

Before writing the code, you must know which buffer index corresponds to which visual element.

  1. Open the Data Window in MT4 (Ctrl+D).
  2. Hover your mouse over a bar where the Arrow or Line appears.
  3. Look at the values listed under your indicator's name.
    • The first value is Buffer 0.
    • The second value is Buffer 1, and so on.

MQL4 Implementation

Here is a complete, robust example of how to retrieve these values.

//+------------------------------------------------------------------+
//|                                            CustomInd_Example.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Input parameters for the EA (Should match your Indicator's inputs)
input int      InpIndPeriod = 14;   // Example Indicator Input 1
input double   InpIndDev    = 2.0;  // Example Indicator Input 2

//--- Constants for Buffer Indices (Update these based on your Data Window check)
const int BUFFER_ARROW = 0; // Assume Buffer 0 is the Arrow
const int BUFFER_LINE  = 1; // Assume Buffer 1 is the Line

//--- Name of your custom indicator file (without .ex4)
const string IND_NAME = "NameOfYourIndicator"; 

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. Define the shift (bar index). 
   // 1 = Closed bar (confirmed signal), 0 = Current bar (repainting possible)
   int shift = 1;

   // 2. Get the value of the ARROW buffer
   // Note: We pass input parameters (InpIndPeriod, InpIndDev) before the buffer index
   double arrowValue = iCustom(NULL, 0, IND_NAME, InpIndPeriod, InpIndDev, BUFFER_ARROW, shift);

   // 3. Get the value of the LINE buffer
   double lineValue  = iCustom(NULL, 0, IND_NAME, InpIndPeriod, InpIndDev, BUFFER_LINE, shift);

   // 4. Check for Arrow Signal
   // Custom indicators usually return EMPTY_VALUE (approx 2147483647) when no arrow is drawn
   if(arrowValue != EMPTY_VALUE && arrowValue != 0)
   {
      Print("Arrow detected on bar ", shift, ". Value: ", arrowValue);
      
      // Example: If arrow is below price, it might be a Buy signal
      if(arrowValue < Close[shift])
      {
         // Place Buy Logic Here
      }
   }

   // 5. Logic for the Line
   // Example: Check if price crossed the line
   double lineValuePrev = iCustom(NULL, 0, IND_NAME, InpIndPeriod, InpIndDev, BUFFER_LINE, shift+1);
   
   if(Close[shift] > lineValue && Close[shift+1] < lineValuePrev)
   {
      Print("Price crossed above the indicator line.");
   }
}
//+------------------------------------------------------------------+

Key Explanations

1. The iCustom Syntax
The function signature is:
iCustom(Symbol, Timeframe, Name, ...Inputs..., BufferIndex, Shift)

  • ...Inputs...: You must list every external input parameter of the custom indicator in the exact order and type (int, double, string, etc.) as they appear in the indicator's settings. If you skip one, the buffer mapping will fail.
  • BufferIndex: This is the mode parameter. In the example above, we requested BUFFER_ARROW (0) in the first call and BUFFER_LINE (1) in the second call.

2. Handling Empty Values (EMPTY_VALUE)
Arrow buffers are sparse; they do not have a value on every bar.

  • When no arrow is drawn, MT4 usually fills the buffer with a specific "Empty" number.
  • By default, this is 2147483647 (represented by the constant EMPTY_VALUE).
  • Sometimes, poorly written indicators use 0 instead.
  • Best Practice: Check if(value != EMPTY_VALUE && value != 0) to confirm an arrow actually exists.

3. The Shift Parameter

  • Using shift = 0 reads the current forming bar. If the indicator repaints (recalculates), the arrow might appear and disappear.
  • Using shift = 1 reads the previously closed bar. This is safer for backtesting and live trading as the signal is confirmed and will not vanish.

Q&A: Custom Indicators in MQL4

Q: How do I find the buffer index if I don't have the source code?
A: Use the "Data Window" (Ctrl+D) in the MT4 terminal. Add the indicator to the chart, hover over a bar where the arrow appears, and note which value field (1st, 2nd, 3rd...) populates with a number. The 1st value is Buffer 0, the 2nd is Buffer 1, etc.

Q: Why does my EA run extremely slowly when using iCustom?
A: This usually happens if the custom indicator performs heavy calculations (like nested loops) on every tick. To optimize, ensure you are not calling iCustom on every tick if you only need to check once per bar, or contact the indicator developer to optimize the OnCalculate or start function.

Q: Can I change the indicator inputs dynamically from the EA?
A: Yes. The inputs passed to iCustom are just variables. You can change InpIndPeriod in your EA logic, and the next iCustom call will calculate the indicator based on that new period. Note that this is computationally expensive as MT4 has to recalculate the indicator history for the new parameter.