ArrayCopy
ArrayCopy
It copies an array into another one.
int ArrayCopy(
void& dst_array[], // destination array
const void& src_array[], // source array
int dst_start=0, // index starting from which write into destination array
int src_start=0, // first index of a source array
int count=WHOLE_ARRAY // number of elements
);Parameters
- dst_array[]
[out] Destination array
- src_array[]
[in] Source array
- dst_start=0
[in] Starting index from the destination array. By default, start index is 0.
- src_start=0
[in] Starting index for the source array. By default, start index is 0.
- count=WHOLE_ARRAY
[in] Number of elements that should be copied. By default, the whole array is copied (count=WHOLE_ARRAY).
Return Value
It returns the number of copied elements.
Note
If count<0 or count>src_size-src_start, all the remaining array part is copied. Arrays are copied from left to right. For series arrays, the starting position is correctly defined adjusted for copying from left to right.
If arrays are of different types, during copying it tries to transform each element of a source array into the type of the destination array. A string array can be copied into a string array only. Array of classes and structures containing objects that require initialization aren’t copied. An array of structures can be copied into an array of the same type only.
For dynamic arrays with indexing as in timeseries, the size of a destination array is automatically increased to the amount of copied data (if the latter exceeds the array size). The destination array size is not decreased automatically.
Example:
#property description "The indicator highlights the candlesticks that are local"
#property description "highs and lows. Interval length for finding"
#property description "extreme values should be found using an input parameters."
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//---- plot
#property indicator_label1 "Extremums"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrLightSteelBlue,clrRed,clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- predefined constant
#define INDICATOR_EMPTY_VALUE 0.0
//--- input parameters
input int InpNum=4; // Half-interval length
//--- indicator buffers
double ExtOpen[];
double ExtHigh[];
double ExtLow[];
double ExtClose[];
double ExtColor[];
//--- global variables
int ExtStart=0; // index of the first candlestick that is not an extremum
int ExtCount=0; // number of non-extremums in the interval
//+------------------------------------------------------------------+
//| Filling out non-extremum candlesticks |
//+------------------------------------------------------------------+
void FillCandles(const double &open[],const double &high[],
const double &low[],const double &close[])
{
//--- fill out the candlesticks
ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ExtOpen);
SetIndexBuffer(1,ExtHigh);
SetIndexBuffer(2,ExtLow);
SetIndexBuffer(3,ExtClose);
SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX);
//--- specify the value, which is not displayed
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- specify the names of indicator buffers for displaying in the data window
PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- set straight indexing in time series
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- variable of the bar calculation start
int start=prev_calculated;
//--- calculation is not performed for the first InpNum*2 bars
if(start==0)
{
start+=InpNum*2;
ExtStart=0;
ExtCount=0;
}
//--- if the bar has just formed, check the next potential extremum
if(rates_total-start==1)
start--;
//--- bar index to be checked for the extremum
int ext;
//--- indicator value calculation loop
for(int i=start;i<rates_total-1;i++)
{
//--- initially on i bar without drawing
ExtOpen[i]=0;
ExtHigh[i]=0;
ExtLow[i]=0;
ExtClose[i]=0;
//--- extremum index for check
ext=i-InpNum;
//--- check for the local maximum
if(IsMax(high,ext))
{
//--- highlight an extremum candlestick
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=1;
//--- highlight other candles up to the extremum with a neutral color
FillCandles(open,high,low,close);
//--- change the variable colors
ExtStart=ext+1;
ExtCount=0;
//--- pass to the next iteration
continue;
}
//--- check for the local minimum
if(IsMin(low,ext))
{
//--- highlight an extremum candlestick
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=2;
//--- highlight other candles up to the extremum with a neutral color
FillCandles(open,high,low,close);
//--- change variable values
ExtStart=ext+1;
ExtCount=0;
//--- pass to the next iteration
continue;
}
//--- increase the number of non-extremums at the interval
ExtCount++;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Check if the current array element is a local high |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
{
//--- interval start variable
int i=ind-InpNum;
//--- interval end period
int finish=ind+InpNum+1;
//--- check for the first half of the interval
for(;i<ind;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- check for the second half of the interval
for(i=ind+1;i<finish;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- this is an extremum
return(true);
}
//+------------------------------------------------------------------+
//| Check if the current array element is a local low |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
{
//--- interval start variable
int i=ind-InpNum;
//--- interval end variable
int finish=ind+InpNum+1;
//--- check for the first half of the interval
for(;i<ind;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- check for the second half of the interval
for(i=ind+1;i<finish;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- this is an extremum
return(true);
}