오류, 버그, 질문 - 페이지 3027

 
Сергей Таболин :

지표는 나의 약점)))

하지만!

내가 전혀 이해하지 못하거나 당신이 약간 잘못 알고 있습니다.

내가 아는 한 prev_calculated는 계산되지 않은 데이터의 카운터입니다. 그리고 수신된 데이터가 계산되기 때문에 이 카운터는 0으로 재설정됩니다 ... 마치, 그게 다야, 더 이상 계산할 새 데이터가 없습니다 ....)))

그리고 이 경우 지표를 완전히 다시 계산해야 하는 이유는 무엇입니까? 모르겠습니다!

---------------

약간 거짓말))))

지표가 다시 그려지지 않고 "칠면조"는 역사에서 "아름다운"것으로 보입니다 ;)

카운터는 프로그래머가 제어할 수 없는 이유로 초기 상태로 리셋됩니다. 마치 인디케이터가 처음으로 시작된 것처럼!

내 메시지가 이해할 수 없는 응용 프로그램 사이에서 사라지는 것을 원하지 않았지만 여전히 존경받는 개발자에게 도달했습니다.



OnCalculate() 함수에서 반환된 값과 두 번째 입력 매개변수 prev_calculated 사이의 관계에 유의하십시오. 함수를 호출할 때 prev_calculated 매개변수에는 이전 호출에서 OnCalculate() 함수가 반환한 값이 포함됩니다. 이를 통해 이 기능의 이전 실행 이후 변경되지 않은 막대에 대한 재계산을 피하기 위해 사용자 지정 지표를 계산하는 경제적인 알고리즘을 구현할 수 있습니다.

문서에서 가져온 것입니다. 계산이 제대로 작동하지 않으면 경제적 계산의 전체 개념이 깨집니다.
 
Andrey Dik :
카운터는 프로그래머가 제어할 수 없는 이유로 초기 상태로 리셋됩니다. 마치 인디케이터가 처음으로 시작된 것처럼!

내 메시지가 이해할 수 없는 응용 프로그램 사이에서 사라지는 것을 원하지 않았지만 여전히 존경받는 개발자에게 도달했습니다.

이것은 모든 새로운 바에 있습니까? 재보험이든 뭐든..

각각에 없으면 prev_calk가 재설정될 때 다른 이유가 있습니다.

 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

오류, 버그, 질문

안드레이 딕 , 2021.05.27 13:53

데이터가 수신되는 새 시간 표시줄 이 나타나면 prev_calculated 카운터가 0으로 재설정됩니다. 이것은 전체 지표가 마치 처음에 시작된 것처럼 다시 계산된다는 것을 의미합니다 .

이 구조가 익숙합니까?

 if (rates_total == prev_calculated) return rates_total;
  
int startInd = rates_total - prev_calculated;

for ( int i = startInd; i >= 0 ; i--)
{
   //тут считаем индикатор, который обращается к другому индикатору на старшем ТФ
}

그것은 EA의 논리(다시 그리기, 다시 그리기 안 함, 언더드로잉 또는 기타)가 아니라 prev_calculated가 아무도 요청하지 않은 동안 0으로 재설정된다는 사실입니다!

문제는 다음과 같습니다.

 if (rates_total == prev_calculated) return rates_total;

다른 TF의 호출된 표시기가 매 틱마다 계산되는 것을 허용하지 않고 호출하면 기록이 동기화되고 이 표시기는 처음부터 계산됩니다.


테스트를 스케치하면 호출된 표시기가 모든 것을 계산하고 prev_calculated == 0으로 재설정되지 않습니다.

닫기 표시기를 그리고 새 막대 및 prev_calculated == 0 이벤트를 인쇄합니다.

 // tst.mq5

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[])
{
   int start;
   static datetime t = 0 ;
   if (t != time[rates_total- 1 ])
   {
      t = time[rates_total- 1 ];
       Print ( MQLInfoString ( MQL_PROGRAM_NAME ), " New bar " , t);
   }
   
   if (prev_calculated == 0 )
   {
      start = 0 ;
       ArrayInitialize (Buffer, EMPTY_VALUE );
       Print ( MQLInfoString ( MQL_PROGRAM_NAME ), " prev_calculated == 0" );
   }
   else start = prev_calculated - 1 ;


   for ( int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
//--- return value of prev_calculated for next call
   return (rates_total);
}

이 표시기를 호출하고(버퍼의 마지막 2개 값을 얻음) TF를 닫습니다.

 input ENUM_TIMEFRAMES TF = PERIOD_M5;
int OnInit ()
{
//--- indicator buffers mapping
   SetIndexBuffer ( 0 , Buffer, INDICATOR_DATA );
   ind_handle = iCustom ( NULL , TF, "NewFolder\\tst" );
//---
   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[])
{
   int start;
   static datetime t = 0 ;
   if (t != time[rates_total- 1 ])
   {
      t = time[rates_total- 1 ];
       Print ( MQLInfoString ( MQL_PROGRAM_NAME ), " New bar " , t);
   }

   if (prev_calculated == 0 )
   {
      start = 0 ;
       ArrayInitialize (Buffer, EMPTY_VALUE );
       Print ( MQLInfoString ( MQL_PROGRAM_NAME ), " prev_calculated == 0" );
   }
   else start = prev_calculated - 1 ;


   for ( int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
   double buf[];
   if ( CopyBuffer (ind_handle, 0 , 0 , 2 , buf) < 0 ) Print ( "Error CopyBuffer # " , GetLastError ());
//--- return value of prev_calculated for next call
   return (rates_total);
}


M1 의 마지막 표시기를 시작하고 다음을 기록합니다.

2021.05.27 21:48:34.196 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:48:00

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) tst_tf prev_calculated == 0

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) 오류 CopyBuffer#4806

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst 새로운 바 2021.05.27 21:45:00

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst prev_calculated == 0

2021.05.27 21:49:01.636 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:49:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:50:00

2021.05.27 21:50:00.149 tst (EURUSD,M5) tst 뉴바 2021.05.27 21:50:00

2021.05.27 21:51:01.789 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:51:00

2021.05.27 21:52:02.832 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:52:00

2021.05.27 21:53:00.920 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:53:00

2021.05.27 21:54:02.778 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:54:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:55:00

2021.05.27 21:55:00.308 tst (EURUSD,M5) tst 뉴바 2021.05.27 21:55:00

2021.05.27 21:56:00.118 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:56:00

2021.05.27 21:57:00.419 tst_tf (EURUSD,M1) tst_tf 새로운 바 2021.05.27 21:57:00

 
Andrey Khatimlianskii :

이것은 모든 새로운 바에 있습니까? 재보험이든 뭐든..

각각에 없으면 prev_calk가 재설정될 때 다른 이유가 있습니다.

이전 TF의 각 새 막대에 정확히 표시됩니다.

예를 들어 표시기가 M1에서 작동하고 M5의 표시기를 참조하는 경우 5분마다 표시기가 완전히 새로 계산됩니다. 최적화의 상당한 속도 저하가 보장됩니다.

 
Igor Makanu :

문제는 다음과 같습니다.

다른 TF의 호출된 표시기가 매 틱마다 계산되는 것을 허용하지 않고 호출하면 기록이 동기화되고 이 표시기는 처음부터 계산됩니다.


테스트를 스케치하면 호출된 표시기가 모든 것을 계산하고 prev_calculated == 0으로 재설정되지 않습니다.

닫기 표시기를 그리고 새 막대 및 prev_calculated == 0 이벤트를 인쇄합니다.

이 표시기를 호출하고(버퍼의 마지막 2개 값을 얻음) TF를 닫습니다.

요청한 시니어 TF(M5)에서 데이터 동기화 를 확인하고 준비되지 않은 경우 표시기의 준비 상태를 확인한 다음 종료합니다.

결과적으로 표시기는 모든 눈금이 아니라 M1 막대가 열릴 때 한 번만 작동합니다.


 //проверка готовности данных и индикатора на другом TF
if ( SeriesInfoInteger ( Symbol (), tf, SERIES_SYNCHRONIZED ))
{
   if ( iBars ( Symbol (), tf) != BarsCalculated (handleFr)) return 0 ;
}
else return 0 ;

//проверка на наличие нового бара
if (rates_total == prev_calculated) return rates_total;

정말 커스텀 prev calc를 사용해야 합니까? 개발자들이 내 간청에 귀를 기울이기를 바랍니다.

 
Andrey Dik :

요청한 시니어 TF(M5)에서 데이터 동기화 를 확인하고 준비되지 않은 경우 표시기의 준비 상태를 확인한 다음 종료합니다.

결과적으로 표시기는 모든 눈금이 아니라 M1 막대가 열릴 때 한 번만 작동합니다.


정말 커스텀 prev calc를 사용해야 합니까? 개발자들이 내 간청에 귀를 기울이기를 바랍니다.

이것은 표시기에서 올바르게 작동하지 않아야 합니다.

 if ( SeriesInfoInteger ( Symbol (), tf, SERIES_SYNCHRONIZED ))

내가 틀리지 않았다면 도움말에는 모든 기간 동안 데이터를 업로드하기 위한 스크립트 구문 분석이 포함되어 있으며 표시기가 작동한다는 사실 때문에 이러한 방식으로 표시기에서 기록 데이터를 요청할 수 없다는 경고가 있어야 합니다. 비동기적으로

예, BarsCalculated()는 핸들을 바인딩한 후 한 번 사용하는 것이 좋습니다.


UPD: 스와핑 기록용 스크립트 및 지표에서 작동하지 않는 이유 설명: https://www.mql5.com/ru/docs/series/timeseries_access

 
Andrey Dik :

요청한 시니어 TF(M5)에서 데이터 동기화 를 확인하고 준비되지 않은 경우 표시기의 준비 상태를 확인한 다음 종료합니다.

결과적으로 표시기는 모든 눈금이 아니라 M1 막대가 열릴 때 한 번만 작동합니다.


정말 커스텀 prev calc를 사용해야 합니까? 개발자들이 내 간청에 귀를 기울이기를 바랍니다.

왜 그런 수표?

 //проверка готовности данных и индикатора на другом TF
if ( SeriesInfoInteger ( Symbol (), tf, SERIES_SYNCHRONIZED ))
{
   if ( iBars ( Symbol (), tf) != BarsCalculated (handleFr)) return 0 ;
}
else return 0 ;

조건 반환 0 없이 작성하는 것이 더 쉬울 것입니다. 그리고 모든 것...

각각의 새 막대에서 조건이 충족되고 동기화와 상관없이 모든 막대가 다시 계산됩니다. 당신은 래쉬 코드를 작성하고 그것을 터미널 버그로 전달했습니다 ...

 
컴파일 중 오류:
 union X1 { //(1) нормально
         char x11[ INT_MAX / 2 + 1 ];
};
union X2 { //(2) Error: 'X2' - struct is too large
         char x21[ INT_MAX / 2 + 1 ];
         char x22[ INT_MAX / 2 + 1 ];
};
그리고 (1)과 (2)의 근본적인 차이점은 무엇입니까?
 
단일 필드와 결합하는 것은 이상한 일입니다.
 
Alexey Viktorov :

왜 그런 수표?

조건 반환 0 없이 작성하는 것이 더 쉬울 것입니다. 그리고 모든 것...

각각의 새 막대에서 조건이 충족되고 동기화와 상관없이 모든 막대가 다시 계산됩니다. 당신은 래쉬 코드를 작성하고 그것을 터미널 버그로 전달했습니다 ...

다시 생각 해봐.

사유: