ArrayCopy

배열을 다른 배열로 복사합니다.

int  ArrayCopy(
   void&        dst_array[],         // 대상 배열
   const void&  src_array[],         // 원본 배열
   int          dst_start=0,         // 대상 배열에 쓸 인덱스 시작
   int          src_start=0,         // 원본 배열의 첫 번째 인덱스
   int          count=WHOLE_ARRAY    // 요소의 수
   );

매개변수

dst_array[]

[out]  대상 배열

src_array[]

[in]  원본 배열

dst_start=0

[in]  대상 배열에서의 시작 인덱스. 기본적으로 시작 인덱스는 0입니다.

src_start=0

[in]  원본 배열의 시작 인덱스. 기본적으로 시작 인덱스는 0입니다.

count=WHOLE_ARRAY

[in]  복사할 요소의 수. 기본적으로 전체 배열이 복사됩니다 (count=WHOLE_ARRAY).

반환 값

복사된 요소의 수를 반환합니다.

참고

count<0 또는 count>src_size-src_start이면, 나머지 배열 부분이 모두 복사됩니다. 배열이 좌측에서 우측으로 복사됩니다. 배열 시리즈의 경우, 좌측에서 우측으로 복사하기 위해 시작 포지션이 올바르게 정의됩니다.

배열 유형이 다른 경우 복사하는 동안 원본 배열의 각 요소를 대상 배열 유형으로의 변환을 시도합니다. 문자열 배열은 문자열 배열로만 복사할 수 있습니다. 초기화가 필요하지 않은 개체를 포함하는 클래스 및 구조의 배열은 복사되지 않습니다. 구조 배열을 동일한 유형의 배열로만 복사할 수 있습니다.

For dynamic arrays with indexing as in 시계열과 같은 인덱싱을 사용하는 동적 배열의 경우 대상 배열 크기가 복사된 데이터의 양(배열의 크기를 초과하는 경우)으로 자동으로 증가합니다. 대상 배열 크기는 자동으로 줄어들지 않습니다.

예:

#property description "지표가 로컬 캔들스틱을 강조처리 합니다"
#property description "고가 및 저가. 검색 간격 길이"
#property description "입력 매개변수를 사용하여 극한값을 찾아야 합니다."
//--- 지표 설정
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   1
//---- 플롯
#property indicator_label1  "극값"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrLightSteelBlue,clrRed,clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- 사전정의된 상수
#define INDICATOR_EMPTY_VALUE 0.0
//--- 매개변수 입력
input int InpNum=4; // 간격 길이의 반
//--- 지표 버퍼
double ExtOpen[];
double ExtHigh[];
double ExtLow[];
double ExtClose[];
double ExtColor[];
//--- 글로벌 변수
int    ExtStart=0; // 극값이 아닌 최초의 캔들스틱 인덱스
int    ExtCount=0; // 간격 내 비극값 수
//+------------------------------------------------------------------+
//| 비극값 캔들 스틱 채움                            |
//+------------------------------------------------------------------+
void FillCandles(const double &open[],const double &high[],
                 const double &low[],const double &close[])
  {
//--- 캔들스틱 채움
   ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount);
  }
//+------------------------------------------------------------------+
//| 사용자 지정 지표 초기화 함수                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 지표 버퍼 맵핑
   SetIndexBuffer(0,ExtOpen);
   SetIndexBuffer(1,ExtHigh);
   SetIndexBuffer(2,ExtLow);
   SetIndexBuffer(3,ExtClose);
   SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX);
//--- 표시되지 않ㅇ는 값을 지정
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- 데이터 창에 표시할 지표 버퍼 이름 지정
   PlotIndexSetString(0,PLOT_LABEL,"시가;고가;저가;종가");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 사용자 지정 지표 반복 함수                              |
//+------------------------------------------------------------------+
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[])
  {
//--- 시계열에서 정확한 인덱스 설정
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(close,false);
//--- 막대 계산 시작의 변수
   int start=prev_calculated;
//--- 첫 번째 InpNum*2 막대에 대한 계산이 수행되지 않습니다
   if(start==0)
     {
      start+=InpNum*2;
      ExtStart=0;
      ExtCount=0;
     }
//--- 막대가 막 형성된 경우, 다음 극값을 확인
   if(rates_total-start==1)
      start--;
//--- 극값에 대해 확인할 막대 인덱스
   int ext;
//--- 지표 값 계산 루프
   for(int i=start;i<rates_total-1;i++)
     {
      //--- 초기에 그려지지 않은 i 막대 
      ExtOpen[i]=0;
      ExtHigh[i]=0;
      ExtLow[i]=0;
      ExtClose[i]=0;
      //--- 확인할 극값 인덱스
      ext=i-InpNum;
      //--- 로컬 최대값 확인
      if(IsMax(high,ext))
        {
         //--- 극값의 캔들스틱 강조
         ExtOpen[ext]=open[ext];
         ExtHigh[ext]=high[ext];
         ExtLow[ext]=low[ext];
         ExtClose[ext]=close[ext];
         ExtColor[ext]=1;
         //--- 다른 캔들스틱을 극단까지 뉴트럴 색상으로 강조
         FillCandles(open,high,low,close);
         //--- 변수 색상 변경
         ExtStart=ext+1;
         ExtCount=0;
         //--- 다음 반복으로 넘어가기
         continue;
        }
      //--- 로컬 최소값 확인
      if(IsMin(low,ext))
        {
         //--- 극값의 캔들스틱 강조
         ExtOpen[ext]=open[ext];
         ExtHigh[ext]=high[ext];
         ExtLow[ext]=low[ext];
         ExtClose[ext]=close[ext];
         ExtColor[ext]=2;
         //--- 다른 캔들스틱을 극단까지 뉴트럴 색상으로 강조
         FillCandles(open,high,low,close);
         //--- 변수 값 변경
         ExtStart=ext+1;
         ExtCount=0;
         //--- 다음 반복으로 넘어가기
         continue;
        }
      //--- 간격에 따라 비극값 수를 늘림
      ExtCount++;
     }
//--- 다음 호출을 위한 prev_calculated의 반환 값
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| 현재 배열 요소가 로컬 고가인지 확인               |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
  {
//--- 간격 시작 변수
   int i=ind-InpNum;
//--- 간격 종료 기간
   int finish=ind+InpNum+1;
//--- 간격의 전반부를 점검
   for(;i<ind;i++)
     {
      if(price[ind]<=price[i])
         return(false);
     }
//--- 간격의 후반부를 점검
   for(i=ind+1;i<finish;i++)
     {
      if(price[ind]<=price[i])
         return(false);
     }
//--- 이는 극값입니다
   return(true);
  }
//+------------------------------------------------------------------+
//| 현재 배열 요소가 로컬 저가인지 확인                |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
  {
//--- 간격 시작 변수
   int i=ind-InpNum;
//--- 간격 끝 변수
   int finish=ind+InpNum+1;
//--- 간격의 전반부를 점검
   for(;i<ind;i++)
     {
      if(price[ind]>=price[i])
         return(false);
     }
//--- 간격의 후반부를 점검
   for(i=ind+1;i<finish;i++)
     {
      if(price[ind]>=price[i])
         return(false);
     }
//--- 이는 극값입니다
   return(true);
  }