이제 ArrayCopyRates 기능으로 복사한 모든 파리의 속도를 사용하여 RSI와 같은 일부 그래픽 표시기를 넣어야 합니다... 아래 이미지를 그릴 때:
내 초기 질문에서 나는 이것을 하는 방법을 알고자 하며... 읽기 속도에 대해서는 아닙니다. 그리기 전에 비율을 복사해야 할 필요는 없다고 생각하지만 수행하는 방법을 아는 것은 좋았습니다... 이제 모든 쌍을 표시하기 위해 표시기 영역을 분할하는 방법을 찾아야 합니다...
나는 PM을 통해 OP가 영어에 어려움을 겪고 우리 둘 다 포르투갈어를 사용하기 때문에 코드를 수정하는 것을 도왔습니다. 테스트에서 " ArrayCopyRates() " 함수에서 발생하는 또 다른 "재미"를 발견했습니다. EA에서 " ArrayCopyRates() "와 함께 MqlRates 배열을 사용할 때 데이터 배열은 항상 사물의 현재 상태를 보고하는 가상 배열이므로 데이터는 항상 최신 상태입니다.
그러나 지표에서는 그렇지 않은 것 같습니다. 어레이는 가상 복사본이 아니라 " ArrayCopyRates() "가 호출된 순간에 설정된 정적 복사본입니다. 기호가 차트 기호와 다른 경우 데이터가 업데이트되지 않습니다. 차트와 동일한 기호인 경우 배열 데이터는 "라이브"이고 예상대로 업데이트되지만 다른 기호의 경우에는 정적 복사본입니다.
따라서 표시기에서 작동하려면 새 데이터가 필요한 경우 OnCalculate() 이벤트를 호출할 때마다 " ArrayCopyRates() " 함수를 호출해야 합니다.
검색 결과를 확장하기 위해 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이 0:00 1h 캔들의 인덱스가 되고 PrevDayEnd가 23:00 1h 캔들의 인덱스가 되기 때문에 통화에 대한 지표만 사용하는 경우(다시 주 중반이라고 가정) 잘 작동합니다. 문제는 선물(지수, 금, 원유 등)에 있습니다. 일일 양초 시작은 항상 0:00이지만 선물의 첫 번째 양초는 GMT+2 브로커에서 오전 1시이므로 PrevDayBegin을 계산하는 위의 코드 행은 전날 23:00의 1h 양초를 반환합니다.
그런 다음 이 상황을 수용할 코드를 포함하고 PrevDayEnd와 같은 요일이 될 때까지 PrevDayBegin을 이동하기로 결정했습니다.
그리고 그 모든 논리는 모든 1h 초가 최신 상태라면 훌륭하게 작동하지만 오늘 일어난 일에 대한 몇 가지 지문을 보여주는 아래 로그를 살펴보십시오. 참고로 저는 전날 저녁에 MT4를 닫았다가 오늘 아침(영국 오전 7시경)에 다시 열었습니다. 따라서 차트에 누락된 데이터가 몇 시간밖에 없었습니다.
2017.02.09 06:56:20.613Prev_Day_Range_LRT_50_v0.6 SPX500,H1: == 다른 요일 ==
로그를 보면 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[];
양초 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.252Prev_Day_Range_LRT_50_v0.6 SPX500,H1: 과거 날짜의 표시기! 삭제하고 오늘 생성합니다!
그런 다음 이 메시지의 시작 부분에서 언급한 문제로 돌아갑니다. 위에서 다시 구현한 테스트는 표시기가 기록이 완전히 로드될 때까지 기다리게 하지 않으므로 부분 데이터를 기반으로 범위가 잘못 계산됩니다.
이것은 PrevDayEnd가 1h 차트의 두 번째 캔들(인덱스 1)로 잘못 계산되고 있을 뿐만 아니라 (2017.02.07 21:00) CurrDayBegin이라는 메시지 시작 부분에 표시된 로그의 보다 완전한 버전입니다. 1h 차트에서 오늘의 첫 번째 캔들은 iBarShift에 의해 (2017.02.08 06:00)에 근사됩니다.
자, 첫 번째 부분은 완료되었습니다(모든 쌍 비율 읽기).
이제 ArrayCopyRates 기능으로 복사한 모든 파리의 속도를 사용하여 RSI와 같은 일부 그래픽 표시기를 넣어야 합니다... 아래 이미지를 그릴 때:
내 초기 질문에서 나는 이것을 하는 방법을 알고자 하며... 읽기 속도에 대해서는 아닙니다. 그리기 전에 비율을 복사해야 할 필요는 없다고 생각하지만 수행하는 방법을 아는 것은 좋았습니다... 이제 모든 쌍을 표시하기 위해 표시기 영역을 분할하는 방법을 찾아야 합니다...
표시 영역을 분할하는 방법은 없습니다. 모든 것은 별도로 그려야 하며 버퍼나 자동 크기 조정이 필요하지 않습니다. 보다
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 12
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 14
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 36
표시 영역을 분할하는 방법은 없습니다. 모든 것은 별도로 그려야 하며 버퍼나 자동 크기 조정이 필요하지 않습니다. 보다
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 12
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 14
이런 사진 봤어? (MetaQuotes Software Corp.) - MQL4 forum - Page 36
이것은 내가 어딘가에서 주운 표시기이며 해독을 시도한 적이 없습니다. 나는 현재 차트의 3개 시간대를 보여줍니다. 미친 것은 양초가 히스토그램으로 그려져 있다는 것입니다. 꽤 깔끔하지만 지금 내가 좋아하는 것은 아닙니다.
최고의 소원
이 스레드를 팔로우하는 사람들에 대한 업데이트입니다!
나는 PM을 통해 OP가 영어에 어려움을 겪고 우리 둘 다 포르투갈어를 사용하기 때문에 코드를 수정하는 것을 도왔습니다. 테스트에서 " ArrayCopyRates() " 함수에서 발생하는 또 다른 "재미"를 발견했습니다. EA에서 " ArrayCopyRates() "와 함께 MqlRates 배열을 사용할 때 데이터 배열은 항상 사물의 현재 상태를 보고하는 가상 배열이므로 데이터는 항상 최신 상태입니다.
그러나 지표에서는 그렇지 않은 것 같습니다. 어레이는 가상 복사본이 아니라 " ArrayCopyRates() "가 호출된 순간에 설정된 정적 복사본입니다. 기호가 차트 기호와 다른 경우 데이터가 업데이트되지 않습니다. 차트와 동일한 기호인 경우 배열 데이터는 "라이브"이고 예상대로 업데이트되지만 다른 기호의 경우에는 정적 복사본입니다.
따라서 표시기에서 작동하려면 새 데이터가 필요한 경우 OnCalculate() 이벤트를 호출할 때마다 " ArrayCopyRates() " 함수를 호출해야 합니다.
검색 결과를 확장하기 위해 Fernando - 기호가 차트 기호와 같더라도 기간이 다르면 배열은 정적입니다.
따라서 가상 사본을 가지려면 표시기에서 동일한 기호 및 동일한 기간이어야 합니다. 다른 것은 정적입니다.
전일의 최고가와 최저가를 찾기 위해 주 중반이라고 가정하고 간단히 다음을 사용합니다.
Lo = iLow ( NULL , PERIOD_D1 , 1 );
괜찮습니다. 하지만 지금은 전날의 최고점과 최저점을 찾아야 합니다. 나는 iHighest와 iLowest를 사용하여 높고 낮은 1h 캔들에 시간을 근사하기로 결정했습니다. 그리고 그때부터 문제가 시작되었습니다.
PrevDayEnd = iBarShift ( NULL , PERIOD_H1 , iTime ( NULL , PERIOD_D1 , 0 )- 1 );
PrevDayBegin--;
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 );
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);
}
:
:
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, 추세선 등)를 다시 그립니다. ).
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.다음은 표시기의 스크린샷입니다.
(1) 불완전한 기록을 사용하여 계산됨(가로선은 하루의 시작 부분에서 시작하지 않는다는 점에 유의하십시오)
(2) 전체 이력을 사용하여 재계산(하루의 시작에서 시작하는 가로줄)