- 1 1. What Is MQL5 CopyBuffer?
- 2 2. Basic CopyBuffer Syntax
- 3 3. Basic Usage of CopyBuffer (Minimal Code Example)
- 4 4. Relationship Between CopyBuffer Index and Bars
- 5 5. Common Errors When Using CopyBuffer
- 6 6. Important Considerations When Using CopyBuffer in EAs
- 7 7. EA Implementation Example Using CopyBuffer
- 8 8. Relationship Between CopyBuffer and iCustom
- 9 9. Best Practices for Using CopyBuffer in Real EAs
- 10 10. Frequently Asked Questions About CopyBuffer
1. What Is MQL5 CopyBuffer?
In MQL5, CopyBuffer is a function used to copy an indicator’s calculated results into an array.
In MetaTrader 5, indicator values are not obtained directly. Instead, you first create an indicator handle, and then use that handle with CopyBuffer to retrieve the values.
This structure is often confusing at first, especially for people who have written MQL4 programs before.
In MQL4, you could get a value simply by calling an indicator function like this.
double ma = iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE,0);
In MQL5, however, the following two-step process is required.
- Create the indicator handle
- Use CopyBuffer to retrieve the calculated result
In other words, the basic MQL5 workflow is as follows.
Create indicator
↓
Get indicator handle
↓
Retrieve values with CopyBuffer
↓
Use in EA logic
This design exists because MetaTrader 5 was built with multithreaded processing and performance optimization in mind.
By separating indicator calculation from EA processing, it becomes possible to calculate multiple indicators more efficiently.
For that reason, when developing EAs or indicators in MQL5, CopyBuffer is a function you will almost always use.
Typical use cases include the following.
- Retrieving moving average (iMA) values
- Retrieving RSI (iRSI) values
- Retrieving multi-buffer indicators such as MACD
- Retrieving custom indicator (iCustom) values
- Evaluating signals in EA logic
For example, even when using a moving average for an EA’s trading decision, the process looks like this.
Create indicator handle with iMA
↓
Get the latest value with CopyBuffer
↓
Compare with price
↓
Make trading decision
In short, CopyBuffer is the entry point an EA uses to read an indicator’s calculated results.
1.1 Key Points for Understanding CopyBuffer
To understand CopyBuffer, you need to understand the following three concepts together.
1) Indicator handle
This is like an ID that refers to the actual indicator instance.
Functions such as iMA and iRSI return a handle, not the value itself.
2) Indicator buffer
This is the memory area where the indicator stores its calculated results.
For example, MACD has multiple buffers such as the following.
- Main line
- Signal line
- Histogram
With CopyBuffer, you retrieve values by specifying this buffer number.
3) Array
CopyBuffer copies the retrieved values into an array.
The EA then runs its logic using that array.
Common Points Where Beginners Get Stuck
CopyBuffer is a very basic function, but there are several points that often confuse beginners.
1) Trying to get the value directly, as in MQL4
In MQL5, you cannot write it like this.
double ma = iMA(...);
iMA is a function that returns a handle.
2) Assuming that simply calling CopyBuffer will always retrieve a value
In practice, the following conditions are required.
- The indicator handle is valid
- A sufficient number of bars exists
- The indicator calculation has completed
If these conditions are not satisfied, CopyBuffer may fail.
3) Handling the forming bar
The value of the latest bar retrieved by CopyBuffer
may still be unconfirmed.
In EA logic, you need to clearly decide one of the following.
- Use the forming bar
- Use only confirmed bars
In production EAs, it is common to use only confirmed bars.
CopyBuffer is just one function, but it is one of the most important functions for understanding how indicator processing works in MetaTrader 5.
2. Basic CopyBuffer Syntax
To use CopyBuffer correctly, you first need to understand the function syntax (signature) and the meaning of each parameter.
This function is used to copy values calculated internally by an indicator into an array.
CopyBuffer may look simple, but if you misunderstand the meaning of its arguments, you can run into problems such as the following.
- Unable to retrieve values
array out of rangeerror- Retrieving values from bars different from what you intended
That is why it is important to understand the basic syntax accurately first.
2.1 CopyBuffer Function Syntax
The basic syntax of CopyBuffer is as follows.
int CopyBuffer(
int indicator_handle,
int buffer_num,
int start_pos,
int count,
double buffer[]
);
This function retrieves data from the specified indicator buffer and copies it into the specified array.
The return value is the number of elements copied.
If the operation fails, -1 is returned.
2.2 Meaning of Each Parameter
CopyBuffer has five arguments.
It is important to understand the meaning of each one accurately.
indicator_handle
This is the target indicator handle.
It is usually obtained using a function like this.
int handle = iMA(Symbol(), PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
By passing this handle to CopyBuffer, you can retrieve the indicator’s calculated results.
Important note
- If the handle is
INVALID_HANDLE, CopyBuffer will fail
buffer_num
This is the indicator buffer number to retrieve.
For example, if you consider MACD, it has buffers like the following.
| Buffer Number | Content |
|---|---|
| 0 | Main line |
| 1 | Signal line |
| 2 | Histogram |
Therefore, if you want to retrieve the main line, you would write the following.
CopyBuffer(handle,0,0,1,buffer);
Common mistakes
- Using the wrong buffer number
- Not checking the custom indicator’s specification
start_pos
This is the starting position (bar number) for retrieval.
The basic rules are as follows.
| Value | Meaning |
|---|---|
| 0 | Latest bar |
| 1 | One bar ago |
| 2 | Two bars ago |
In other words, the following code retrieves the “latest bar.”
CopyBuffer(handle,0,0,1,buffer);
count
This is the number of data points (bars) to retrieve.
Example
CopyBuffer(handle,0,0,10,buffer);
In this case, it retrieves 10 data points starting from the latest bar.
Important note
If the array size is too small, you may get the following error.
array out of range
buffer[]
This is the array that stores the retrieved data.
It is usually defined like this.
double buffer[];
ArraySetAsSeries(buffer,true);
When you use ArraySetAsSeries, the array index becomes time-series based (latest = 0).
2.3 CopyBuffer Return Value
The return value of CopyBuffer is the number of data points actually copied.
Example
int copied = CopyBuffer(handle,0,0,5,buffer);
Meaning of the return value
| Return Value | Meaning |
|---|---|
| 5 | Successfully retrieved 5 data points |
| -1 | Retrieval failed |
Important point
When using CopyBuffer, it is recommended to check the return value.
Example
if(copied <= 0)
{
Print("CopyBuffer failed");
}
If you do not do this, the EA may continue running even when an error has occurred.
Common Mistakes
Here is a summary of mistakes beginners often make.
1) Array size is too small
CopyBuffer(handle,0,0,10,buffer);
But then
double buffer[5];
This will cause an error.
2) The handle has not been created
This means a state like the following.
int handle;
CopyBuffer(handle,0,0,1,buffer);
You must create the handle in OnInit or a similar initialization step.
3) Misunderstanding the meaning of start_pos in reverse
In MetaTrader,
0 = latest bar
That is the rule.
If you get this wrong, your EA logic will break.
3. Basic Usage of CopyBuffer (Minimal Code Example)
The fastest way to understand how to use CopyBuffer is to look at the actual code workflow.
In MQL5, retrieving indicator values generally follows these three steps.
- Create the indicator handle
- Retrieve data using CopyBuffer
- Read the values from the array
This workflow is the same for almost all indicators such as moving averages, RSI, MACD, and custom indicators.
Here we will explain the most basic example using a moving average (iMA) with CopyBuffer.
3.1 Basic Example Using iMA and CopyBuffer
First, create the moving average indicator handle.
This process is usually performed in OnInit().
int ma_handle;
int OnInit()
{
ma_handle = iMA(Symbol(), PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("Failed to create iMA handle");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
This code creates a 20-period Simple Moving Average (SMA).
Next, retrieve the moving average value using CopyBuffer.
This is typically done inside OnTick().
void OnTick()
{
double ma_buffer[];
ArraySetAsSeries(ma_buffer,true);
int copied = CopyBuffer(ma_handle,0,0,1,ma_buffer);
if(copied <= 0)
{
Print("CopyBuffer failed");
return;
}
double ma = ma_buffer[0];
Print("MA value: ", ma);
}
This code performs the following steps.
Create iMA handle
↓
Retrieve one value using CopyBuffer
↓
Store in array
↓
Use ma_buffer[0]
This workflow represents the basic pattern for retrieving indicator values in MQL5.
3.2 Reading Indicator Values from the Array
The data retrieved with CopyBuffer is stored in an array.
For example, consider the following code.
CopyBuffer(ma_handle,0,0,3,ma_buffer);
The retrieved data will look like this.
| Array Index | Content |
|---|---|
| 0 | Latest bar |
| 1 | One bar ago |
| 2 | Two bars ago |
Therefore, the values can be used like this.
double current_ma = ma_buffer[0];
double prev_ma = ma_buffer[1];
By retrieving multiple bars, you can perform trend detection or crossover detection.
For example, a simple moving average trend check might look like this.
if(ma_buffer[0] > ma_buffer[1])
{
Print("Uptrend");
}
Common Beginner Mistakes
When using CopyBuffer, beginners often struggle with the following points.
1. Not Understanding Array Direction
In MetaTrader, the order of arrays depends on the settings.
ArraySetAsSeries(buffer,true);
With this setting, the array order becomes:
buffer[0] = latest bar
buffer[1] = one bar ago
buffer[2] = two bars ago
If this setting is not used, the array order may be reversed.
In EA development, it is standard practice to use series arrays.
2. Retrieving Too Much Data on Every Tick
For example:
CopyBuffer(handle,0,0,1000,buffer);
If this runs on every tick, EA performance may degrade.
Production EAs typically do one of the following:
- Retrieve only the required number of bars
- Retrieve data only when a new bar appears
3. Indicator Calculation Not Completed Yet
Sometimes the indicator calculation has not finished yet when CopyBuffer is called.
In this case:
- The return value may be -1
- The retrieved value may be 0
Therefore, in practice you may check the following.
BarsCalculated(ma_handle)
Although CopyBuffer is simple, it is important to understand the relationship between arrays, bar indices, and indicator handles.
4. Relationship Between CopyBuffer Index and Bars
One of the most confusing aspects of CopyBuffer is the relationship between bar numbers (start_pos) and array indices.
If you misunderstand this mechanism, your EA logic may reference unintended data.
Beginners often struggle with these three points.
- The meaning of start_pos
- The order of array indices
- Handling the forming bar
Understanding this correctly can prevent many CopyBuffer-related issues.
4.1 Meaning of start_pos
The start_pos parameter specifies which bar to start retrieving data from.
The basic rules are as follows.
| Value | Meaning |
|---|---|
| 0 | Latest bar |
| 1 | One bar ago |
| 2 | Two bars ago |
| n | n bars ago |
For example:
CopyBuffer(handle,0,0,1,buffer);
This means:
start_pos = 0
count = 1
So it retrieves only the latest bar.
Meanwhile:
CopyBuffer(handle,0,1,1,buffer);
retrieves only the previous bar.
4.2 Meaning of count
The count parameter specifies how many bars of data to retrieve.
Example:
CopyBuffer(handle,0,0,5,buffer);
This retrieves 5 bars starting from the latest bar.
The result is stored in the array as follows.
| Array | Content |
|---|---|
| buffer[0] | Latest bar |
| buffer[1] | One bar ago |
| buffer[2] | Two bars ago |
| buffer[3] | Three bars ago |
| buffer[4] | Four bars ago |
This assumes the following setting is used.
ArraySetAsSeries(buffer,true);
If this setting is not used, the array order may be reversed.
Therefore, in EA development it is common to use series arrays.
5. Common Errors When Using CopyBuffer
CopyBuffer is frequently used in MetaTrader 5 EA development, but it is also an area where errors and unexpected behavior often occur.
Many of the problems commonly searched for online are related to incorrect CopyBuffer usage or indicator initialization timing.
In this section, we will explain the following common issues.
array out of range- CopyBuffer returning -1
- Indicator values becoming 0
- Incorrect signals caused by forming bars
Understanding these issues can significantly reduce troubleshooting during EA development.
5.1 array out of range
One of the most common errors in MetaTrader is:
array out of range
This occurs when CopyBuffer attempts to retrieve more data than the array can store.
For example:
double buffer[3];
CopyBuffer(handle,0,0,5,buffer);
In this case:
Requested data = 5
Array size = 3
This mismatch causes the error.
Solution
Ensure the array size matches the number of elements retrieved.
double buffer[];
ArrayResize(buffer,5);
ArraySetAsSeries(buffer,true);
CopyBuffer(handle,0,0,5,buffer);
In practice, using dynamic arrays with ArrayResize is safer.
5.2 CopyBuffer Returning -1
If the return value of CopyBuffer is -1, the data retrieval failed.
Example:
int copied = CopyBuffer(handle,0,0,1,buffer);
if(copied < 0)
{
Print("CopyBuffer failed");
}
Common causes include the following.
Cause 1: Invalid indicator handle
For example:
int handle = iMA(...);
If this handle becomes:
INVALID_HANDLE
CopyBuffer will always fail.
Solution:
if(handle == INVALID_HANDLE)
{
Print("Indicator handle error");
}
Cause 2: Indicator calculation not completed
An indicator sometimes requires a minimum number of bars before calculation can be completed.
Example:
- 200-period moving average
- Only 100 bars on the chart
In this situation, values cannot be calculated.
A common solution is to check:
BarsCalculated(handle)
Example:
if(BarsCalculated(handle) <= 0)
{
return;
}
Cause 3: Historical data not loaded yet
Immediately after opening a chart, historical data may not be fully loaded.
If CopyBuffer is called at that moment:
- -1 may be returned
- 0 may be returned
This often occurs:
- Immediately after EA startup
- Immediately after VPS restart
5.3 Indicator Value Becoming 0
Sometimes CopyBuffer succeeds but the retrieved value becomes 0.
The main causes include the following.
Indicator calculation not completed
This is common with:
- Long-period moving averages
- ATR
- Custom indicators
For example:
MA200
This requires at least 200 bars.
Incorrect buffer number
For example, in MACD:
| Buffer | Content |
|---|---|
| 0 | Main line |
| 1 | Signal line |
| 2 | Histogram |
If the wrong buffer number is used, the retrieved value may not be what you expect.
5.4 Incorrect Signals from Forming Bars
Another common issue when using CopyBuffer in EAs involves forming bars.
For example:
CopyBuffer(handle,0,0,1,buffer);
In this case:
buffer[0] = currently forming bar
Forming bars:
- Change values in real time
- Can cause unstable signals
Solution
Many EAs instead use the previous confirmed bar.
CopyBuffer(handle,0,1,1,buffer);
This means:
Use confirmed bar only
This is a common safe design in algorithmic trading.
6. Important Considerations When Using CopyBuffer in EAs
CopyBuffer is a basic function for retrieving indicator values, but when used in a real EA (Expert Advisor), there are important design considerations.
Even simple code can cause problems depending on how it is implemented.
- Heavy EA processing
- Unstable trading decisions
- Delayed execution on VPS environments
Therefore, CopyBuffer should be treated not just as a function but as a core part of EA architecture.
6.1 Calling CopyBuffer on Every Tick
EAs usually execute OnTick() whenever the price changes.
If you write code like this:
void OnTick()
{
double buffer[];
ArraySetAsSeries(buffer,true);
CopyBuffer(handle,0,0,1,buffer);
}
CopyBuffer may be executed extremely frequently.
This can become problematic when:
- Multiple indicators are used
- Multiple currency pairs are traded
- The EA runs on a VPS
- Tick frequency is high
This may lead to:
- Higher CPU usage
- EA processing delays
- Increased slippage
Solution: Use New Bar Detection
A common design approach is to call CopyBuffer only when a new bar appears.
datetime last_bar = 0;
void OnTick()
{
datetime current_bar = iTime(Symbol(),PERIOD_CURRENT,0);
if(current_bar != last_bar)
{
last_bar = current_bar;
double buffer[];
ArraySetAsSeries(buffer,true);
CopyBuffer(handle,0,0,2,buffer);
}
}
This optimizes the logic from:
Every tick processing
↓
Per-bar processing
which greatly reduces system load.
7. EA Implementation Example Using CopyBuffer
So far, we have explained the basic syntax and precautions for CopyBuffer.
In this section, we will show how CopyBuffer is integrated into an actual EA logic.
As an example, we will implement a simple trend detection using a moving average, which is one of the most basic trading logics.
In a typical EA, the workflow looks like this.
OnInit
↓
Create indicator handle
↓
OnTick
↓
Retrieve value with CopyBuffer
↓
Trading decision
This structure is a common basic pattern used in many EAs.
7.1 EA Example for Retrieving Moving Average Values
First, create the moving average indicator handle in OnInit.
int ma_handle;
int OnInit()
{
ma_handle = iMA(Symbol(),PERIOD_CURRENT,20,0,MODE_SMA,PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("Failed to create MA handle");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
This code creates a moving average with the following parameters.
Period: 20
Type: SMA
Applied price: Close
Next, retrieve the values using CopyBuffer inside OnTick.
void OnTick()
{
double ma_buffer[];
ArraySetAsSeries(ma_buffer,true);
int copied = CopyBuffer(ma_handle,0,0,2,ma_buffer);
if(copied <= 0)
{
Print("CopyBuffer failed");
return;
}
double current_ma = ma_buffer[0];
double prev_ma = ma_buffer[1];
Print("MA current:",current_ma);
Print("MA previous:",prev_ma);
}
This code retrieves the moving average values for:
Latest bar
Previous bar
7.2 Trend Detection Using Moving Average
The values retrieved with CopyBuffer can be used directly in EA logic.
For example, a simple trend detection can be written as follows.
if(current_ma > prev_ma)
{
Print("Uptrend");
}
else
{
Print("Downtrend");
}
This logic means:
MA rising → Uptrend
MA falling → Downtrend
This is one of the most basic evaluation methods in trading systems.
In real EAs, this logic is typically used for trade decisions.
7.3 Moving Average Crossover Example
Another common trading strategy is the moving average crossover.
For example:
- Fast MA (20)
- Slow MA (50)
First, create two indicator handles.
int ma_fast;
int ma_slow;
int OnInit()
{
ma_fast = iMA(Symbol(),PERIOD_CURRENT,20,0,MODE_SMA,PRICE_CLOSE);
ma_slow = iMA(Symbol(),PERIOD_CURRENT,50,0,MODE_SMA,PRICE_CLOSE);
return(INIT_SUCCEEDED);
}
Then retrieve the data using CopyBuffer.
double fast[];
double slow[];
ArraySetAsSeries(fast,true);
ArraySetAsSeries(slow,true);
CopyBuffer(ma_fast,0,0,2,fast);
CopyBuffer(ma_slow,0,0,2,slow);
The crossover detection can be written as follows.
if(fast[1] < slow[1] && fast[0] > slow[0])
{
Print("Golden Cross");
}
if(fast[1] > slow[1] && fast[0] < slow[0])
{
Print("Dead Cross");
}
This logic forms the basis of many automated trading systems.
Implementation Notes
Possible Use of a Forming Bar
The following code:
CopyBuffer(handle,0,0,1,buffer);
retrieves:
The currently forming bar
Depending on EA design, using only confirmed bars may be safer.
In that case:
CopyBuffer(handle,0,1,1,buffer);
Forgetting to Check the Return Value
If CopyBuffer fails but the EA continues executing logic, it may lead to:
- Incorrect entries
- Abnormal values
Always verify the return value.
Insufficient Number of Retrieved Bars
For crossover detection, at least:
2 bars
are required.
Therefore:
CopyBuffer(handle,0,0,2,buffer);
should be used.
By using CopyBuffer, almost any indicator value can be integrated into EA logic.
8. Relationship Between CopyBuffer and iCustom
CopyBuffer in MQL5 is not limited to standard indicators.
In practice, you often need to use values from custom indicators or indicators distributed by third parties.
The function used in that case is iCustom.
The roles can be simplified as follows.
iCustom = create handle for custom indicator
CopyBuffer = read values from that handle
In other words, iCustom alone cannot retrieve indicator values.
It only returns an indicator handle. The actual buffer values must be retrieved with CopyBuffer.
8.1 What is iCustom?
iCustom is a function used to load custom indicators.
While indicators like iMA, iRSI, and iMACD are built into MetaTrader, iCustom is used for custom indicator files such as .ex5.
The concept is simple:
iMAcreates a handle for the standard moving averageiCustomcreates a handle for a custom indicator
For example, if you want to use a custom indicator named MyIndicator.ex5, you would write:
int custom_handle;
int OnInit()
{
custom_handle = iCustom(Symbol(), PERIOD_CURRENT, "MyIndicator");
if(custom_handle == INVALID_HANDLE)
{
Print("Failed to create custom indicator handle");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
At this stage, no indicator values have been retrieved yet.
You have only obtained the handle used to identify the custom indicator.
9. Best Practices for Using CopyBuffer in Real EAs
When CopyBuffer is used in production Expert Advisors, several implementation patterns are commonly adopted to improve stability, performance, and maintainability.
Even though CopyBuffer itself is simple, how it is integrated into EA architecture can significantly affect execution reliability.
This section summarizes practical design approaches frequently used in professional EA development.
9.1 Create Indicator Handles Only Once
Indicator handles should typically be created in OnInit() and reused afterward.
Creating handles repeatedly inside OnTick can increase system load.
Correct design:
int ma_handle;
int OnInit()
{
ma_handle = iMA(Symbol(),PERIOD_CURRENT,20,0,MODE_SMA,PRICE_CLOSE);
return(INIT_SUCCEEDED);
}
Incorrect design:
void OnTick()
{
int handle = iMA(Symbol(),PERIOD_CURRENT,20,0,MODE_SMA,PRICE_CLOSE);
}
Repeated creation can waste CPU resources and reduce EA efficiency.
9.2 Retrieve Only the Data You Need
Some developers attempt to retrieve large amounts of historical data on every tick.
CopyBuffer(handle,0,0,1000,buffer);
However, most trading logic requires only a few recent bars.
Typical usage:
- 1 bar for current value
- 2 bars for crossover detection
- 3–5 bars for simple trend analysis
Efficient implementation:
CopyBuffer(handle,0,0,2,buffer);
This significantly reduces unnecessary data processing.
9.3 Use Confirmed Bars for Trading Decisions
One of the most important practices in algorithmic trading is avoiding signals based on forming bars.
For example:
CopyBuffer(handle,0,0,1,buffer);
This retrieves the value of the currently forming bar.
Forming bars change continuously as price updates arrive, which can cause unstable signals.
Safer approach:
CopyBuffer(handle,0,1,1,buffer);
This retrieves the value from the previous confirmed bar.
This approach is widely used in professional trading systems.
9.4 Always Check the Return Value
Because CopyBuffer can fail, it is important to check the return value before using the retrieved data.
int copied = CopyBuffer(handle,0,0,2,buffer);
if(copied <= 0)
{
Print("CopyBuffer failed");
return;
}
If this check is omitted, the EA may continue operating using invalid data.
9.5 Release Indicator Handles When EA Stops
Although not always required, releasing indicator handles when the EA stops can improve resource management.
This can be done in OnDeinit().
void OnDeinit(const int reason)
{
IndicatorRelease(ma_handle);
}
This ensures that indicator resources are properly released when the EA is removed from the chart.
10. Frequently Asked Questions About CopyBuffer
This section answers common questions related to CopyBuffer that often appear in developer forums and beginner discussions.
10.1 Why Does CopyBuffer Return -1?
The most common reasons include:
- The indicator handle is invalid
- The indicator calculation has not finished
- Historical data is not yet loaded
- The requested number of bars exceeds available data
In many cases, waiting until sufficient data is available resolves the issue.
10.2 Why Are Retrieved Values Sometimes Zero?
Possible reasons include:
- Not enough historical bars
- Indicator period larger than available data
- Incorrect buffer index
- Indicator not fully calculated yet
Always ensure that enough historical data exists before retrieving values.
10.3 Is CopyBuffer Slow?
CopyBuffer itself is optimized and generally fast.
Performance issues typically occur due to incorrect usage patterns.
Examples of inefficient usage:
- Retrieving thousands of bars on every tick
- Creating indicator handles repeatedly
- Calling multiple indicators excessively
Using new-bar detection and retrieving minimal data can greatly improve performance.
10.4 Can CopyBuffer Be Used With Custom Indicators?
Yes. Custom indicators loaded using iCustom can be accessed through CopyBuffer.
The workflow is as follows:
Create custom indicator handle with iCustom
↓
Use CopyBuffer to retrieve indicator buffer values
↓
Apply values to EA logic
This mechanism allows EAs to integrate virtually any indicator logic.
CopyBuffer therefore serves as a central bridge between indicator calculation and trading logic in MetaTrader 5.