mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 130

 
// ArrayResize с освобождением памяти
template <typename T>
int ArrayResize2( T &Array[], const int NewSize, const int Reserve = 0 )
{
  T ArrayTmp[];
  
  ArraySwap(Array, ArrayTmp);
  const int Res = ArrayResize(Array, NewSize, Reserve);
  
  if (Res > 0)
    ArrayCopy(Array, ArrayTmp, 0, 0, MathMin(Res, ArraySize(ArrayTmp)));
    
  return(Res);
}
 
fxsaber :

고맙습니다. ArraySwap 기능을 사용하는 것은 나에게 일어나지 않을 것입니다.

내가 이해하는 한 귀하의 기능은 크기가 증가하거나 감소할 때 모두 작동합니다. 즉, ArrayResize의 완전한 유사체로 작동합니다.

ArraySwap, ArrayResize, ArrayCopy 세 함수를 호출하는 것보다 배열을 늘릴 때 표준 ArrayResize를 호출하는 것이 낫지 않습니까?


ps 버전을 확인하고 MqlTick 어레이를 1,000,000에서 500,0000으로 줄이는 동안 두 개의 사본으로 광산을 찾았습니다. 귀하의 버전은 22밀리초 내에 처리됩니다. 내 점수는 37-38입니다.
 
pivomoe :

ArraySwap, ArrayResize, ArrayCopy 세 함수를 호출하는 것보다 배열을 늘릴 때 표준 ArrayResize를 호출하는 것이 낫지 않습니까?

생각했지만 하지 않았기 때문입니다. 실제로 더 많은 뉘앙스가 있습니다. 그래서 더 간단한 버전을 사용하기로 결정했습니다.

뉘앙스 중 하나는 이것이다. 생성자/소멸자가 있는 구조의 배열을 사용하는 경우 ArrayResize는 값의 차이와 동일한 양으로 어느 방향으로든 구조를 호출합니다.

그러나 ArrayCopy의 사용은 모든 생성자에 대한 호출입니다. ArrayTmp 제거 - 모든 소멸자를 호출합니다. 따라서 ArrayResize2는 정확히 ArrayResize가 아닙니다.

 
다음과 같이 ArrayResize ( arr, new_size, -1)를 작성할 수 있습니다. 사실, 귀하의 버전은 37밀리초에서 22밀리초 정도 더 빠릅니다.
 
어드바이저의 프레임 모드를 떠났지만 다시 돌아와야 합니다. 다음 조언자는 이를 수행하는 방법을 보여줍니다.
 // Создание mqd-Файла из Тестера, чтение mqd-файла из Терминала во фрейм/ стандартном режиме работы советника.

input int Range = 0 ; // 0..10

void OnTesterInit ( void ) {}
void OnTesterDeinit ( void ) {}

#define TOSTRING(A) #A + " = " + ( string )(A) + " "

void OnTesterPass ( void )
{
   ulong Pass;
   string Name;
   long ID;
   double Value;

   while ( FrameNext (Pass, Name, ID, Value)) // Прочли очередной проход из mqd-файла.
     Print (TOSTRING(Pass) + TOSTRING(Name) + TOSTRING(Value)); // Вывели данные mqd-файла
}

double OnTester ( void )
{
   if ( MQLInfoInteger ( MQL_OPTIMIZATION ))
  {
     uchar Data[];

     FrameAdd ( TerminalInfoString ( TERMINAL_DATA_PATH ), 0 , MathRand (), Data); // Отправили данные в mqd-файл Терминала.
  }

   return ( 0 );
}

void OnInit ()
{
   if ( MQLInfoInteger ( MQL_TESTER ))
  {
     // OnInit для Тестера
  }
   else if ( FrameFirst ()) // Удалось инициализировать mqd-файл.
  {
     OnTesterInit ();
     OnTesterPass ();
  }
}

void OnDeinit ( const int )
{
   if ( MQLInfoInteger ( MQL_TESTER ))
  {
     // OnDeinit для Тестера
  }
   else
     OnTesterDeinit ();
}

void OnTick ()
{
   static const bool IsTester = MQLInfoInteger ( MQL_TESTER );
  
   if (!IsTester)
     return ;
    
   // OnTick для Тестера.
}


최적화 후에는 이것을 볼 수 있습니다

Pass = 0 Value = 25534.0 
Pass = 1 Value = 12915.0 
Pass = 7 Value = 25534.0 
Pass = 8 Value = 12915.0 
Pass = 6 Value = 6528.0 
Pass = 5 Value = 2523.0 
Pass = 3 Value = 22229.0 
Pass = 2 Value = 9767.0 
Pass = 4 Value = 7748.0 
Pass = 9 Value = 25534.0 
Pass = 10 Value = 12915.0 


프레임 모드에서 Expert Advisor를 끄고 표준 모드에서 실행하면 최적화 중에 받은 것과 동일한 데이터가 표시됩니다.

이 접근 방식을 사용하면 Optimization 의 결과 로 반복적으로 돌아갈 수 있습니다.


PS 어드바이저의 프레임 모드에 대한 터미널에서 열리는 차트에서 2명 이상의 어드바이저를 실행할 수 없습니다. 따라서 표준 모드에서 실행해야 하는 경우 프레임에 대해 열리지 않은 차트에서 실행해야 합니다.

 
extern은 이제 하드코딩된 매크로입니다.
 #undef extern
#define extern // macro redefinition
따라서 변경 없이 mq4 코드가 MT5에서 작동하도록 하는 것이 항상 가능한 것은 아닙니다.
 

fxsaber :
extern теперь является жестко заданным макросом

따라서 변경 없이 mq4 코드가 MT5에서 작동하도록 하는 것이 항상 가능한 것은 아닙니다.

문서에는 변경 사항이 없습니다. 이것을 더 자세히 설명할 수 있습니까?

 
Alexey Viktorov :

문서에는 변경 사항이 없습니다. 이것을 더 자세히 설명할 수 있습니까?

이러한 코드

 #property script_show_inputs

#define extern input // macro redefinition

extern int i = 0 ;

void OnStart () {}

항상 경고를 발행할 것입니다. "불가능"에 대해 - 흥분했습니다. 재정의할 수 있으므로 이러한 상황에서는 항상 경고만 표시됩니다.

 
fxsaber :

뉘앙스 중 하나는 이것이다. 생성자/소멸자가 있는 구조의 배열을 사용하는 경우 ArrayResize는 값의 차이와 동일한 양으로 어느 방향으로든 구조를 호출합니다.

그러나 ArrayCopy의 사용은 모든 생성자에 대한 호출입니다. ArrayTmp 제거 - 모든 소멸자를 호출합니다. 따라서 ArrayResize2는 정확히 ArrayResize가 아닙니다.

그러면 ArrayReallocate라고 부르는 것이 더 정확할 것입니다. 그런 강제복제에는 별 의미가 없지만. 추가 브레이크. 유일한 것은 아마도 클래스 객체의 배열이 포인터를 재설정해야 하는 경우(이전 값을 무효로 만들기), 이것이 어딘가에서 고려된다면(그러나 이것은 목발에 가깝습니다)
 
Alexey Navoykov :
그러면 ArrayReallocate라고 부르는 것이 더 정확할 것입니다. 그런 강제복제에는 별 의미가 없지만. 추가 브레이크.

메모리 해제 가 유일한 이유입니다.

사유: