초보자의 질문 MQL5 MT5 MetaTrader 5 - 페이지 1466

 

안녕하세요. Mql5에서 Expert Advisor를 작성할 때 문제가 발생했습니다. 한 해 동안 개장한 캔들값이 있는 배열이 있습니다. 이 배열의 각 캔들 스틱에서 고점과 저점을 확인하기 위해 30 개의 n 캔들 배열을 만들어야합니다. 지그재그 인디케이터와 같은 것입니다.

이 코드를 작성했는데 "배열이 범위를 벗어났습니다"라는 오류가 발생하거나 전체 배열의 최대값과 최소값이 필요한 30 캔들 주기가 아닌 오류가 발생합니다.

for(int i=0; i<ArraySize(opens); i++)
  {
    if(i+30<=ArraySize(opens))
      {
       double maximum=0;
       double minimum=9;
       for(int j=0; j<30; j++)
        {
         maximum = ArrayMaximum(opens, i, i+j);
         minimum = ArrayMaximum(opens, i, i+j);
        }
     }
  }

ArrayMaximum() 및 ArrayMinimum() 함수에서 확인하기 위해 다른 배열을 만들어야 할 수도 있지만 중첩 루프 및 배열 크기와 혼동됩니다.

힌트를 주세요.

 
Dmitry Ivanushko #:
if(i+30<=ArraySize(opens))
if(i+30<ArraySize(opens))

배열 외부의 출력은다음과 같습니다.

 
if(i+30<ArraySize(opens))

이 오류는 부주의로 인한 것입니다. 이 오류를 수정해도 문제가 해결되지 않습니다.

캔들 시초가 30개의 배열을 만들어 고점과 저점을 검색하려면 어떻게 해야 하나요?

 
Dmitry Ivanushko #:
ArrayMaximum
ArrayMaximum

반환값 index 가 아닌 최대값을 반환합니다.

//+------------------------------------------------------------------+
int indexMax[];
int indexMin[];
int sizeArray = ArraySize(opens);
int size = 0;
int n = 30;

for(int i = n; i < sizeArray; i + n)
  {
   ArrayResize(indexMax, size + 1);
   indexMax[size] = ArrayMaximum(opens, i - n, i);
   indexMin[size] = ArrayMinimum(opens, i - n, i);
   size++;
  }
//+------------------------------------------------------------------+

확인해보지 않았지만 캔들스틱 개장(오픈)의 최소값과 최대값의 지 수를 구하는 방법인 것 같습니다.

가격은 한 번에 얻을 수 있지만 지수는 얻을 수 없습니다.

double PriseMin = opens[ArrayMinimum(opens, i - n, i)];
 
for(int i = n; i < sizeArray; i + n)

단계가 있는 mql 루프의 예는 어디에서도 찾을 수 없습니다. 이것은 모든 문제를 단순화합니다.

ChatGPT만이 이런 식으로 작성하라고 조언했습니다:

for(int i = n; i < sizeArray; i += n)

더 실험해 보겠습니다. 코드가 작동합니다. 감사합니다.

ArrayResize를 수행하지 않으면 "배열이 범위를 벗어남" 오류가 발생합니다.

 
Dmitry Ivanushko #:

이 오류는 부주의로 인한 것입니다. 이 오류를 수정해도 문제가 해결되지 않습니다.

캔들 시초가 30개의 배열을 만들어 고점과 저점을 검색하려면 어떻게 해야 하나요?

무엇이 문제일까요? 배열 temp[]를 선언하고 30개의 요소를 복사한 다음 최소/최대 값의 인덱스를 찾습니다. 그리고 마지막에 30보다 작으면 몇 개가 남았는지 복사합니다. 이 경우에는 차라리 while() 루프를 사용하고 싶습니다.

 
Alexey Viktorov #:
무엇이 문제일까요? 배열 temp[]를 선언하고 30개의 요소를 복사한 다음 최소/최대 값의 인덱스를 찾습니다. 그리고 마지막에 30개 미만이면 남은 개수를 복사합니다. 이 경우에는 while() 루프를 사용하고 싶습니다.

네, 그렇게 할 수 있습니다. 제가 제대로 생각하지 못해서 조언을 구하는 것입니다.

 
Dmitry Ivanushko #:

네, 그렇게 할 수 있습니다. 생각이 잘 안 나서 조언을 구하는 거예요.

정적 배열에서는 크기가 일정하게 설정되어 변경할 수 없고, 동적 배열에서는 변경할 수 있지만 배열의 크기가 설정되어 있습니다! 즉, 배열의 크기와 0에서 끝까지 요소의 인덱스가 알려져 있습니다. 0부터 요소의 인덱스가 0이고 마지막 요소의 인덱스가 배열 크기의 한 단위보다 작기 때문에 <=는 범위를 벗어납니다.

모든 것이 당신의 손에 달려 있습니다))))

 
Valeriy Yastremskiy #:

정적 배열에서는 크기가 일정하게 설정되어 변경할 수 없고, 동적 배열에서는 변경할 수 있지만 배열의 크기가 정해져 있습니다! 즉, 배열의 크기를 알고 있고 요소의 인덱스는 0부터 끝까지 있습니다. <=는 요소의 인덱스가 0부터 시작하고 마지막 요소의 인덱스가 배열 크기의 한 단위보다 작기 때문에 범위를 벗어납니다.

모든 것이 당신의 손에 달려 있습니다))))

무슨 뜻인가요? 한 배열에서 다른 배열로 몇 개의 요소를 복사하려면 일부 temp[]를 복사하기 전에 배열 크기를 설정해야 한다고 생각하시나요? ArrayResize(temp, new_size); ?????

 
Dmitry Ivanushko #:

네, 그렇게 할 수 있습니다. 생각이 잘 안 나서 조언을 구하는 거예요.

임시 배열이 필요하지도 않습니다.

int  ArrayMaximum( 
   const void&   array[],             // массив для поиска 
   int           start=0,             // с какого индекса начинаем поиск 
   int           count=WHOLE_ARRAY    // количество проверяемых 
   );

이 코드

  double open[];
  int copy = CopyOpen(_Symbol, PERIOD_CURRENT, 0, 100, open);
  int arrMaximum = ArrayMaximum(open, 85, 20);

는 20개의 요소를 검색하도록 설정되어 있음에도 불구하고 최대 15개의 남은 요소를 검색합니다.

따라서 남은 배열 항목 수에 대해 걱정하지 말고 while() 루프를 사용하는 것이 좋습니다.

사유: