배열, 버퍼 및 시계열 인덱싱 방향

모든 배열 및 지표 버퍼의 기본 인덱스는 왼쪽에서 오른쪽으로입니다. 첫 번째 요소의 인덱스는 항상 0입니다. 따라서 색인 0을 가진 배열 또는 지표 버퍼의 첫 번째 요소는 기본적으로 맨 왼쪽 위치에 있고 마지막 요소는 맨 오른쪽 위치에 있습니다.

지표 버퍼는 클라이언트 터미널에서 크기를 관리하여 지표가 계산되는 막대의 수에 항상 일치하도록 하는 유형의 동적 배열입니다. SetIndexBuffer() 함수를 사용하여 일반적인 유형의 동적 이중 배열이 지표 버퍼로 할당됩니다.. 지표 버퍼는 ArrayResize() 함수를 사용하여 크기를 설정할 필요가 없습니다 - 이 작업은 터미널의 실행 시스템에서 수행합니다.

시계열은 역색인이 있는 배열입니다. 즉, 시계열의 첫 번째 요소는 오른쪽 끝에 있고 마지막 요소는 왼쪽 끝에 있습니다. 가격 내역 데이터를 저장하고 시간 정보를 포함하는 시계열은 시계열의 오른쪽 끝에 배치되며 가장 오래된 데이터는 왼쪽 끝에 배치됩니다.

따라서 인덱스가 0인 시계열 요소에는 심볼의 최신 따옴표에 대한 정보가 포함됩니다. 시계열에 일일 시간대의 데이터가 포함된 경우 현재 완료되지 않은 날의 데이터는 0 위치에 위치하며 인덱스 1의 위치에는 어제 데이터가 포함됩니다.

인덱싱 방향 변경

함수 ArraySetAsSeries()를 사용하면 동적 배열의 요소에 액세스하는 방법을 변경할 수 있습니다; 시스템 메모리에 저장된 데이터의 실제 순서는 변경되지 않습니다. 이 함수는 단순히 배열 요소의 주소 지정 방법을 변경하므로 함수 ArrayCopy()를 사용하여 한 배열을 다른 배열로 복사할 때 소스 배열의 인덱싱 방향에 따라 수신자 배열의 내용이 달라지지 않습니다.

정적 분포 배열의 인덱싱 방향은 변경할 수 없습니다. 배열이 함수에 매개 변수로 전달된 경우에도 이 기능 내에서 인덱싱 방향을 변경하려고 하면 아무런 효과가 없습니다.

지표 버퍼의 경우, 일반적인 배열과 마찬가지로 인덱싱 방향도 역방향으로 설정할 수 있습니다. 즉, 지표 버퍼의 0 포지션을 참조하는 것은 해당 지표 버퍼의 마지막 값을 참조하는 것이며 이는 최신 막대의 지표 값에 해당합니다. 그래도 표시 막대의 실제 위치는 변경되지 않습니다.

지표의 가격 데이터 수신

맞춤형 지표에는 지표 버퍼의 값을 계산하는 데 필요한 가격 데이터가 전달되는 OnCalculate() 함수가 반드시 포함되어야 합니다. ArrayGetAsSeries() 함수를 사용하여 이러한 통과된 배열의 인덱싱 방향을 확인할 수 있습니다.

배열 함수로 전달해 가격 데이터를 반영합니다, 즉, 이러한 배열에는 시계열의 심볼이 있으며 이러한 배열을 확인할 때 함수 ArrayIsSeries()가 참을 반환합니다. 단, 어떤 경우에도 지수화 명령은 ArrayGetAsSeries()함수에 의해서만 확인해야 합니다.

기본값에 종속되지 않으려면 사용할 어레이에 대해 무조건 ArraySetAsSeries()를 호출하고 필요한 방향을 설정해야 합니다.

가격 데이터 및 지표 값 수신

Expert Advisors, 지표 및 스크립트에서 모든 배열의 기본 인덱싱 방향은 왼쪽에서 오른쪽으로입니다. 필요한 경우 모든 mql5 프로그램에서 심볼 및 타임프레임에 대한 시계열 값뿐 아니라 심볼 및 타임프레임에 대해 계산된 값도 요청할 수 있습니다.

Copy...() 함수를 사용하여 다음을 수행합니다:

  • CopyBuffer – 지표 버퍼 값을 이중 유형의 배열로 복사;
  • CopyRates – 일련의 구조에 가격 이력을 복사 MqlRates;
  • CopyTime – 시간 값을 datetime 유형의 배열로 복사;
  • CopyOpen – 오픈 값을 double 유형의 배열로 복사;
  • CopyHigh – 고가를 double 유형의 배열로 복사;
  • CopyLow – 저가를 double 유형의 배열로 복사;
  • CopyClose – 종가를 double 유형의 배열로 복사;
  • CopyTickVolume – 틱 거래량을 long 유형의 배열로 복사;
  • CopyRealVolume – 자본 량을 long 유형의 배열로 복사;
  • CopySpread – 스프레드 내역을 int 유형의 배열로 복사;

 

이 모든 함수들은 유사하게 작동합니다. CopyBuffer()의 예에서 데이터 수집 메커니즘을 살펴보겠습니다. 이는 요청된 데이터의 인덱싱 방향이 시계열 방향임을 암시하며, 인덱스가 0인 위치는 현재 완료되지 않은 막대의 데이터를 저장합니다. 이러한 데이터에 액세스하려면 필요한 양의 데이터를 수신자 배열 (예: 배열 버퍼)로 복사해야 합니다.

copyBuffer

복사할 때 원본 배열의 시작 포지션을 지정해야 하며, 이 위치에서 수신자 배열로 데이터를 복사할 수 있습니다. 성공하면 지정된 개수의 요소가 소스 배열(이 경우 지표 버퍼)에서 수신자 배열로 복사됩니다. 수신자 배열에 설정된 인덱싱 값에 관계없이 복사는 항상 위 그림에 표시된 대로 수행됩니다.

가격 데이터가 반복 횟수가 많은 루프에서 처리될 것으로 예상되는 경우 IsStopped() 함수를 사용하여 강제 프로그램 종료 사실을 확인하는 것이 좋습니다:

int copied=CopyBuffer(ma_handle,// 지표 핸들
                      0,        // 지표 버퍼의 인덱스
                      0,        // 복사를 위한 시작 포지션
                      number,   // 복사할 값의 수 
                      Buffer    // 값을 수령하는 배열
                      );
if(copied<0) return;
int k=0;
while(k<copied && !IsStopped())
  {
   //--- k 인덱스용 값 가져오기
   double value=Buffer[k];
   // ... 
   // 값과 함께 작동
   k++;
  }

예:

input int per=10; // 지수의 주기
int ma_handle;    // 지표 핸들
//+------------------------------------------------------------------+
//| Expert 초기화 함수                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ma_handle=iMA(_Symbol,0,per,0,MODE_EMA,PRICE_CLOSE);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert 틱 함수                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double ema[10];
   int copied=CopyBuffer(ma_handle,// indicator handle
                         0,        // 지표 버퍼 인덱스
                         0,        // 복사할 시작 포지션
                         10,       // 복사를 위한 값 번호
                         ema       // 배열을 수령하는 값
                         );
   if(copied<0) return;
// .... 추가 코드
  }

더 보기

데이터 액세스 구성