242 lines
9.4 KiB
Markdown
242 lines
9.4 KiB
Markdown
# 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](/en/docs/constants/namedconstants/otherconstants)).
|
||
|
||
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](/en/docs/basis/types/classes) 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](/en/docs/series/bufferdirection), 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);
|
||
}
|
||
|
||
```
|