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);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
```
|