다중 통화 지표를 개발하는 방법을 아는 사람이 있습니까? - 페이지 4

 

자, 첫 번째 부분은 완료되었습니다(모든 쌍 비율 읽기).

이제 ArrayCopyRates 기능으로 복사한 모든 파리의 속도를 사용하여 RSI와 같은 일부 그래픽 표시기를 넣어야 합니다... 아래 이미지를 그릴 때:

내 초기 질문에서 나는 이것을 하는 방법을 알고자 하며... 읽기 속도에 대해서는 아닙니다. 그리기 전에 비율을 복사해야 할 필요는 없다고 생각하지만 수행하는 방법을 아는 것은 좋았습니다... 이제 모든 쌍을 표시하기 위해 표시기 영역을 분할하는 방법을 찾아야 합니다...

 

표시 영역을 분할하는 방법은 없습니다. 모든 것은 별도로 그려야 하며 버퍼나 자동 크기 조정이 필요하지 않습니다. 보다

이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 12
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 14
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 36

 
WHRoeder :

표시 영역을 분할하는 방법은 없습니다. 모든 것은 별도로 그려야 하며 버퍼나 자동 크기 조정이 필요하지 않습니다. 보다

이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 12
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 14
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 36

이해하다. 그런 다음 모든 요소를 개체로 그려야 합니다.
 

이것은 내가 어딘가에서 주운 표시기이며 해독을 시도한 적이 없습니다. 나는 현재 차트의 3개 시간대를 보여줍니다. 미친 것은 양초가 히스토그램으로 그려져 있다는 것입니다. 꽤 깔끔하지만 지금 내가 좋아하는 것은 아닙니다.

최고의 소원

파일:
 
알았어 고마워. 나는 직장에서 여행하고 돌아올 때 테스트 할 것입니다.
 
Fernando Carreiro :

이 스레드를 팔로우하는 사람들에 대한 업데이트입니다!

나는 PM을 통해 OP가 영어에 어려움을 겪고 우리 둘 다 포르투갈어를 사용하기 때문에 코드를 수정하는 것을 도왔습니다. 테스트에서 " ArrayCopyRates() " 함수에서 발생하는 또 다른 "재미"를 발견했습니다. EA에서 " ArrayCopyRates() "와 함께 MqlRates 배열을 사용할 때 데이터 배열은 항상 사물의 현재 상태를 보고하는 가상 배열이므로 데이터는 항상 최신 상태입니다.

그러나 지표에서는 그렇지 않은 것 같습니다. 어레이는 가상 복사본이 아니라 " ArrayCopyRates() "가 호출된 순간에 설정된 정적 복사본입니다. 기호가 차트 기호와 다른 경우 데이터가 업데이트되지 않습니다. 차트와 동일한 기호인 경우 배열 데이터는 "라이브"이고 예상대로 업데이트되지만 다른 기호의 경우에는 정적 복사본입니다.

따라서 표시기에서 작동하려면 새 데이터가 필요한 경우 OnCalculate() 이벤트를 호출할 때마다 " ArrayCopyRates() " 함수를 호출해야 합니다.

검색 결과를 확장하기 위해 Fernando - 기호가 차트 기호와 같더라도 기간이 다르면 배열은 정적입니다.

따라서 가상 사본을 가지려면 표시기에서 동일한 기호 및 동일한 기간이어야 합니다. 다른 것은 정적입니다.

 
honest_knave : 결과를 확장하기 위해 Fernando - 기호가 차트 기호와 같더라도 기간이 다르면 배열은 정적입니다. 따라서 가상 사본을 가지려면 표시기에서 동일한 기호 및 동일한 기간이어야 합니다. 다른 것은 정적입니다.
업데이트 해주셔서 감사합니다!
 
안녕,

나는 이 문제에 대한 해결책을 찾기 위해 여기저기서 찾고 있었고 이 토론에 대해 이 스레드의 모든 사람에게 감사하고 싶습니다.

그것이 포럼의 첫 번째 메시지이므로 누락된 프로토콜이 있으면 알려주시면 다음 메시지에서 수정하겠습니다.

나는 매우 간단한 지표를 개발하려고 노력하고 있지만 내 논리는 차트가 완전히 최신 상태인 것에 민감한 것처럼 보이기 때문에 이 토론에 관심이 많습니다.

내 지표는 전일 범위(일 고가에서 고가 또는 일 저가에서 고가)에 원점을 그리고 현재 날에는 원가의 고가, 저가 및 50%에 선을 그리는 것으로 보입니다. 표시기가 GMT 중개인(일요일 일간 양초)에서 사용되는 경우 사용자는 월요일에 금요일 또는 일요일 범위 또는 금요일 + 일요일만 사용할지 선택하도록 입력 매개변수를 설정할 수 있습니다. 일요일 양초가 없다는 점을 감안할 때 차이가 없는 NY 종가 중개인(GMT+2)에서.

이 표시기의 또 다른 기능은 사용자가 fib를 이리저리 움직일 수 있게 하고 현재 날짜의 라인(high, 50% 및 low)이 fib에 의해 설정된 새로운 범위로 조정됩니다. 그러면 사용자가 범위가 축소되는 경우 범위를 조정할 수 있습니다.

표시기는 주로 여러 1h 차트에서 사용되지만 사용자는 fib에서 변경한 사항을 잃지 않고 기간을 전환할 수 있어야 합니다.

fib를 그리려면 전날의 고점과 저점뿐만 아니라 이러한 포인트의 시간도 찾아야 합니다.

아이디어는 간단하지만 몇 가지 문제에 직면했습니다.

전일의 최고가와 최저가를 찾기 위해 주 중반이라고 가정하고 간단히 다음을 사용합니다.

       Hi = iHigh ( NULL , PERIOD_D1 , 1 );
       Lo = iLow ( NULL , PERIOD_D1 , 1 );

괜찮습니다. 하지만 지금은 전날의 최고점과 최저점을 찾아야 합니다. 나는 iHighest와 iLowest를 사용하여 높고 낮은 1h 캔들에 시간을 근사하기로 결정했습니다. 그리고 그때부터 문제가 시작되었습니다.


iHighest와 iLowest를 사용하려면 처음 1h 캔들과 범위의 크기를 지정해야 하므로 제 경우에는 전날의 처음 1h 캔들과 마지막 1h 캔들이 될 것입니다. 그래서 나는 전날의 시작에 대한 이전 일간 양초의 시가와 당일의 시가를 사용하여 전날의 끝을 찾기 위해 일간 양초 -1을 사용했습니다.

       PrevDayBegin = iBarShift ( NULL , PERIOD_H1 , iTime ( NULL , PERIOD_D1 , 1 ));                
       PrevDayEnd = iBarShift ( NULL , PERIOD_H1 , iTime ( NULL , PERIOD_D1 , 0 )- 1 );

그리고 PrevDayBegin이 0:00 1h 캔들의 인덱스가 되고 PrevDayEnd가 23:00 1h 캔들의 인덱스가 되기 때문에 통화에 대한 지표만 사용하는 경우(다시 주 중반이라고 가정) 잘 작동합니다. 문제는 선물(지수, 금, 원유 등)에 있습니다. 일일 양초 시작은 항상 0:00이지만 선물의 첫 번째 양초는 GMT+2 브로커에서 오전 1시이므로 PrevDayBegin을 계산하는 위의 코드 행은 전날 23:00의 1h 양초를 반환합니다.

그런 다음 이 상황을 수용할 코드를 포함하고 PrevDayEnd와 같은 요일이 될 때까지 PrevDayBegin을 이동하기로 결정했습니다.

       if ( TimeDayOfWeek ( iTime ( NULL , PERIOD_H1 , PrevDayBegin)) != TimeDayOfWeek ( iTime ( NULL , PERIOD_H1 , PrevDayEnd)))
         PrevDayBegin--;  

그리고 그 모든 논리는 모든 1h 초가 최신 상태라면 훌륭하게 작동하지만 오늘 일어난 일에 대한 몇 가지 지문을 보여주는 아래 로그를 살펴보십시오. 참고로 저는 전날 저녁에 MT4를 닫았다가 오늘 아침(영국 오전 7시경)에 다시 열었습니다. 따라서 차트에 누락된 데이터가 몇 시간밖에 없었습니다.

2017.02.09 06:56:20.613 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: == 다른 요일 ==
2017.02.09 06:56:20.613 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PrevDayEnd = 1 (2017.02.08 19:00)
2017.02.09 06:56:20.613 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PrevDayBegin = 20(2017.02.08 00:00)

로그를 보면 1h 차트의 가장 최신 캔들이 2017.02.08 20:00(인덱스 0)인 것 같으므로 iBarShift(NULL, PERIOD_H1, iTime(NULL, PERIOD_D1, 0)-1)은 (인덱스 1) 2017.02.08 19:00에 근사합니다. 결과적으로 iHighest 및 iLowest가 잘못된 범위를 사용하기 때문에 표시기에 대한 모든 계산이 혼동됩니다.

이전 토론을 기반으로 계산을 수행하기 전에 모든 양초가 로드될 때까지 기다리라는 제안된 솔루션 중 일부를 시도하고 사용했지만 여전히 작동하지 않습니다.

예를 들어 OnInit()에서 1h, Daily 및 현재 시간대에 차트 업데이트를 트리거하는 다음 코드 줄을 포함했습니다(차트가 다른 시간대에 열려 있을 때 플랫폼이 닫혀 있는 경우에 한함).

   // Triggers history update
   MqlRates mqlrates_array_d1[];
   MqlRates mqlrates_array_h1[];
   MqlRates mqlrates_array[];
  
   ArrayCopyRates (mqlrates_array_d1, NULL , PERIOD_D1 );
   ArrayCopyRates (mqlrates_array_h1, NULL , PERIOD_H1 );
   ArrayCopyRates (mqlrates_array, NULL , 0 );  
내가 알아차린 또 다른 사실은 MT4가 누락된 모든 기록을 로드하기 전에 차트에 열려 있는 시간대에서 가장 최근의 촛불 Time[0]을 업데이트하는 것 같아서 Time[1]도 유효한지 테스트하기로 결정했다는 것입니다. 가격.

해당 코드는 OnCalculate()에 삽입되었으며 @whroeder1 ( 여기 ) 및 @Fernando Carreiro & @Wemerson Guimaraes ( 여기 )의 코드를 기반으로 했습니다.

bool isHistoryLoading;

OnInit ();
:
isHistoryLoading = true ;
:

OnCalculate ( ... )
:
       MqlRates mqlrates_array_d1[];
       MqlRates mqlrates_array_h1[];
       MqlRates mqlrates_array[];
      
       if (isHistoryLoading)
        {      
         ResetLastError ();        
        
         if ( ArrayCopyRates (mqlrates_array_d1, NULL , PERIOD_D1 )> 0 )
           {
             if ( GetLastError () == 0 )
              {
               if (( iTime ( NULL , PERIOD_D1 , 0 ) > 0 ) && ( iTime ( NULL , PERIOD_D1 , 1 ) > 0 ))
                 {
                   ResetLastError ();
  
                   if ( ArrayCopyRates (mqlrates_array_h1, NULL , PERIOD_H1 )> 0 )
                    {
                     if ( GetLastError () == 0 )
                       {
                         if (( iTime ( NULL , PERIOD_H1 , 0 ) > 0 ) && ( iTime ( NULL , PERIOD_H1 , 1 ) > 0 ))
                          {
                           ResetLastError ();
      
                           if ( ArrayCopyRates (mqlrates_array, NULL , 0 )> 0 )
                             {
                               if ( GetLastError () == 0 )
                                {
                                 if (( iTime ( NULL , 0 , 0 ) > 0 ) && ( iTime ( NULL , 0 , 1 ) > 0 ))                            
                                   {
                                    isHistoryLoading = false ;
                                
                                     if (DebugLog)
                                       Print ("Chart up-to-date!");        
                                    }
                                }
                             }
                          }
                       }
                    }                      
                 }
              }
           }
        }
        
       if (isHistoryLoading)
        {
         if (DebugLog)
           Print ("Waiting for chart to update!");
         return (rates_total);
        }    

:

그리고 이것은 플랫폼이 열리고 표시기가 처음으로 로드되었을 때의 로그입니다.

2017.02.09 06:56:18.492 사용자 지정 표시기 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 성공적으로 로드됨
2017.02.09 06:56:18.630 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 초기화됨
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 최신 차트!
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 표시기가 존재하지 않습니다! 만들기.
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: == 다른 요일 ==
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PrevDayEnd = 20 (2017.02.07 23:00)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PrevDayBegin = 42 (2017.02.07 00:00)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR CurrDayBegin = (2017.02.08 00:00)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PERIOD_D1 [0] = (2017.02.08 00:00)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PERIOD_D1 [1] = (2017.02.07 00:00)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PERIOD_D1 [2] = (2017.02.06 00:00)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR 요일 = 3
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR iHighest (촛불 = 28) (가격 = 2299.33) (시간 = 2017.02.07 14:00:001)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR iLowest (촛불 = 20) (가격 = 2287.88) (시간 = 2017.02.07 23:00:001)
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: Fib from Time1=2017.02.07 14:00 Price1=2299.33 to Time2=2017.02.07 23:00 Price2=2287.88
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 추세선 'PDRTrend1 131296489639296384'에서 Time1=2017.02.08 00:00 Price1=2299.23에서 Time2=2017.0까지입니다.
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 추세선 'PDRTrend2 131296489639296384'에서 Time1=2017.02.08 00:00 Price1=2293.2605에서 Time2=2019.0까지
2017.02.09 06:56:18.639 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 추세선 'PDRTrend3 131296489639296384'에서 Time1=2017.02.08 00:00 Price1=22872.88에서 Time2=2017.0까지입니다.

양초 0과 1 또는 ArrayCopyRates 함수에 대한 참조는 정보가 이미 차트에 로드된 곳에서만 액세스하는 것 같습니다. 따라서 ArrayCopyRates는 복사된 유효한 요소 수와 iTime(..., 0) 및 iTime을 반환하는 것으로 보입니다. (..., 1)은 전날 플랫폼이 닫혔을 때 저장된 마지막 2개의 양초에 대해 유효한 가격을 반환합니다.

이는 지표가 마치 어제(PERIOD_D1 [0] = (2017.02.08 00:00))인 것처럼 표시되었음을 의미합니다.

표시기는 사용자가 fib를 이동하더라도 고가, 50% 및 저가 선이 항상 현재 날짜에 표시되도록 제작되었습니다(위의 로그에 표시되는 3개의 추세선). 따라서 중간 추세선이 현재 날짜에 표시되는지 테스트하는 OnCalculate() 코드가 있습니다(사용자는 상단 및 하단 라인을 비활성화하는 입력 옵션이 있으므로 항상 그려지는 유일한 라인은 중간 하나).

OnCalculate ( ... )
:

       if ( ObjectFind (Trend2Name) != - 1 )                 // Check whether mid range line exists
        {
            
         if (( TimeDay ( ObjectGetInteger ( 0 ,Trend2Name, OBJPROP_TIME , 0 ))== TimeDay ( TimeCurrent ()))
           && ( TimeMonth ( ObjectGetInteger ( 0 ,Trend2Name, OBJPROP_TIME , 0 ))== TimeMonth ( TimeCurrent ()))
           && ( TimeYear ( ObjectGetInteger ( 0 ,Trend2Name, OBJPROP_TIME , 0 ))== TimeYear ( TimeCurrent ()))) // Indicator has already been ploted today        
           {
             return (rates_total);
           }
         else      // Indicator exists but in a past date, so delete it and plot it on current day
           {
             if (DebugLog)
               Print ( "Indicator in a past date! Deleting it and creating it today!" );
              
             if ( ObjectFind (FibName) != - 1 )
              FiboLevelsDelete( 0 ,FibName);              
             // Indicator will be created by the OnChartEvent() when it detects the fib was deleted.
           }
        }
       else          // Indicator doesn't exist, so create it
        {
         if (DebugLog)
             Print ( "Indicator doesn't exist! Creating it." );
         CreateIndicator();
        }
:

몇 틱 후에 데이터가 부분적으로 로드되고 위의 코드 조각은 선이 전날에 그려졌음을 감지하고 fib를 삭제하고 범위 재계산을 트리거하고 객체(예: fib, 추세선 등)를 다시 그립니다. ).


2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 과거 날짜의 표시기! 삭제하고 오늘 생성합니다!
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDFibo 131296489639296384가 삭제되었습니다!
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDRRectangle 삭제 131296489639296384
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDRTrend1 삭제 131296489639296384
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDRTrend2 삭제 131296489639296384
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDRTrend3 삭제 131296489639296384

그런 다음 이 메시지의 시작 부분에서 언급한 문제로 돌아갑니다. 위에서 다시 구현한 테스트는 표시기가 기록이 완전히 로드될 때까지 기다리게 하지 않으므로 부분 데이터를 기반으로 범위가 잘못 계산됩니다.

이것은 PrevDayEnd가 1h 차트의 두 번째 캔들(인덱스 1)로 잘못 계산되고 있을 뿐만 아니라 (2017.02.07 21:00) CurrDayBegin이라는 메시지 시작 부분에 표시된 로그의 보다 완전한 버전입니다. 1h 차트에서 오늘의 첫 번째 캔들은 iBarShift에 의해 (2017.02.08 06:00)에 근사됩니다.

CurrDayBegin = iTime ( NULL , PERIOD_D1 , 0 );
      
while ( TimeDayOfWeek ( iTime ( NULL , PERIOD_H1 , iBarShift ( NULL , PERIOD_H1 , CurrDayBegin))) != TimeDayOfWeek ( TimeCurrent ()))

     // If iBarShift can't find the 0am candle and returns the 11pm candle of prev day.

  CurrDayBegin = CurrDayBegin + 3600 ;         // Move 1h until you find the 1st candle of today.                                        

2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: == 다른 요일 ==
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PrevDayEnd = 1 (2017.02.07 21:00)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PrevDayBegin = 22(2017.02.07 00:00)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR CurrDayBegin = (2017.02.08 06:00)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PERIOD_D1 [0] = (2017.02.08 00:00)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PERIOD_D1 [1] = (2017.02.07 00:00)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR PERIOD_D1 [2] = (2017.02.06 00:00)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR 요일 = 3
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR iHighest (촛불 = 8) (가격 = 2299.33) (시간 = 2017.02.07 14:00:001)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: PDR iLowest (촛불 = 19) (가격 = 2288.57) (시간 = 2017.02.07 03:00:001)
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: Fib from Time1=2017.02.07 03:00 Price1=2288.57 to Time2=2017.02.07 14:00 Price2=2299.33
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: Time1=2017.02.08 06:00 Price1=22882=27에서 Time2=2017.0까지의 추세선 'PDRTrend1 131296489639296384'
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: Time1=2017.02.08 06:00 Price1=2293.95에서 Time2=2017.0까지의 추세선 'PDRTrend2 131296489639296384'
2017.02.08 06:53:53.252 Prev_Day_Range_LRT_50_v0.6 SPX500,H1: Time1=2017.02.08 06:00 Price1=2299.33에서 Time2=2017.0까지의 추세선 'PDRTrend3 131296489639296384'

간단히 말해서 모든 histoy가 차트에 로드되었는지 여부를 테스트할 이유가 있습니까? 아니면 내 코드에서 누락된 것이 있습니까?

이 매우 긴 메시지에 나와 함께해주셔서 감사합니다.

전체 코드와 로그를 보고 싶다면 알려주세요. 여기에 코드를 첨부하지 않고 개인적으로 보내드리고 싶습니다.

다음은 표시기의 스크린샷입니다.

(1) 불완전한 기록을 사용하여 계산됨(가로선은 하루의 시작 부분에서 시작하지 않는다는 점에 유의하십시오)

불완전한 기록으로 계산된 지표

(2) 전체 이력을 사용하여 재계산(하루의 시작에서 시작하는 가로줄)

전체 기록을 사용하여 다시 계산된 표시기

Problems with ERR_HISTORY_WILL_UPDATED (4066 ) & weekends
Problems with ERR_HISTORY_WILL_UPDATED (4066 ) & weekends
  • www.mql5.com
Hi i m building a custom indicator and got problems with the 4066 Error...