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

 
Artyom Trishkin :

dataCandles는 구조체입니다. 우리가 기록에서 촛불 자체를 쓰는 배열 - array[]. 따라서 인덱싱이 차트의 양초 인덱싱과 일치하도록 시계열로 수행해야 합니다. 즉, array[] 배열의 0 셀은 현재 날짜에 가장 가까운 양초에 해당합니다.

즉, 1. 양초를 array[] 배열에 복사하고, 2. 그것을 시계열로 만든 다음, 그 값을 구조로 읽어옵니다.

array[] 배열 없이도 가능합니다. 차트에서 직접 구조로 데이터를 쓰는 것이 가능하지만 5개와의 호환성을 위해 이것을 제안했습니다. high[i], low를 사용하여 표시기에서만 직접 복사할 수 있습니다. [i] 및 기타 데이터를 사용하지만 스크립트 또는 Expert Advisor에서 원하는 히스토리 세그먼트를 먼저 어레이에 복사해야 합니다.

부울 시리즈=ArrayIsSeries(배열);
경고(시리즈);
ArraySetAsSeries (배열, true);
부울 시리즈=ArrayIsSeries(배열);

경고(시리즈);

이와 같이?

여전히 두 경고 모두 거짓을 제공합니다.

 
Andrey Koldorkin :
bool 시리즈=ArrayIsSeries(배열);
경고(시리즈);
ArraySetAsSeries(배열, 참);
bool 시리즈=ArrayIsSeries(배열);

경고(시리즈);

이와 같이?

여전히 두 경고 모두 거짓을 제공합니다.

따라서 이것은 "버그, 버그, 질문"에 보고되어야 하는 버그입니다.

다음은 테스트 스크립트입니다. array[] 배열의 0과 마지막 셀에 복사된 양초의 시간을 보여줍니다.

 //+------------------------------------------------------------------+
//|                                                     TestCopy.mq4 |
//|              Copyright 2016, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Artem A. Trishkin, Skype artmedia70"
#property link        "https://login.mql5.com/ru/users/artmedia70"
#property version    "1.00"
#property strict
#property script_show_inputs

enum enumYN
  {
   enYes= 1 , // Да
   enNo= 0 ,   // Нет
  };

//--- input parameters
input int Search_Period= 10 ;   // Количество копируемых свечей
int searchPeriod=(Search_Period< 1 )? 1 :Search_Period;
input int Delta= 2 ;             // Количество пунктов допуска
int delta=(Delta< 0 )? 0 :Delta;
input enumYN AsSeries=enYes;   // Массив array как таймсерия
MqlRates array[];             // Массив структур для копирования Open, High, Low, Close, Time
  
struct DataCandle             // Структура для хранения всех совпадений
  {
   int number_matched;           // Количество совпадений
   MqlRates reference_candle;     // Данные эталонной свечи
   MqlRates matched_candles[];   // Массив свечей, совпадающих с эталонной по нужному критерию 
  };
  DataCandle dataCandle[];     // Массив структур данных свечей и их совпадений
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
//---
   int copy_bars=( int ) fmin (Search_Period, Bars ( Symbol (), Period ()));   // количество копируемых свечей
   int copied= CopyRates ( Symbol (), PERIOD_CURRENT , 1 ,copy_bars,array);   // копируем данные
   if (copied> 0 ) {                                                     // если скопировали
       ArraySetAsSeries (array,AsSeries);                               // задаём массив как таймсерию или нет
       ArrayResize (dataCandle,copied);                                 // задаём размер структуры равным числу скопированных данных
       ZeroMemory (dataCandle);                                         // Обнуляем данные в структуре
       //--- основной цикл по "эталонным" свечам в массиве array. Их параметры будем искать в доп. цикле
       for ( int i= 0 ; i<copy_bars- 1 ; i++) {                             // цикл по скопированным данным от начала до "на один меньше размера массива"
         dataCandle[i].reference_candle.high=array[i].high;           // ищем этот high
         dataCandle[i].reference_candle.low=array[i].low;             // запомнили low для сравнения
         dataCandle[i].reference_candle.time=array[i].time;           // запомнили time для вывода в журнал
         //--- поиск совпадений с эталонной свечой, индексируемой индексом основного цикла i
         int size= 0 ;                                                 // размер массива совпадающих свечей
         ArrayResize (dataCandle[i].matched_candles,size);             // Размер массива совпадений в ноль
         dataCandle[i].number_matched=size;                           // Инициализируем количество совпадений нулём
         //--- теперь ищем совпадения по high свечей в цикле j с high эталонной свечи с индексом i
         for ( int j= 0 ; j<copy_bars; j++) {                             // в цикле от i+1 до copy_bars
             if (j==i) continue ;                                       // пропустим свечу "саму себя"
             //--- если совпадают high эталонной свечи (i) и свечи с индексом j (с допуском на величину Point)
             if ( NormalizeDouble (delta* Point ()- fabs (array[i].high-array[j].high), Digits ())>= 0 ) {
               size++;                                               
               ArrayResize (dataCandle[i].matched_candles,size);             // увеличим размер массива совпадающих свечей
               dataCandle[i].number_matched=size;                           // запишем количество совпадений
               dataCandle[i].matched_candles[size- 1 ].high=array[j].high;   // запишем в массив high совпадающей свечи
               dataCandle[i].matched_candles[size- 1 ].low=array[j].low;     // запишем в массив low совпадающей свечи
               dataCandle[i].matched_candles[size- 1 ].time=array[j].time;   // запишем в массив время совпадающей свечи
               //Print("Время свечи ",i," :",TimeToString(dataCandle[i].reference_candle.time=array[i].time),", high=",DoubleToString(dataCandle[i].reference_candle.high=array[i].high,Digits()),". Совпадение со свечой ",TimeToString(dataCandle[i].matched_candles[size-1].time=array[j].time),", её high ",DoubleToString(dataCandle[i].matched_candles[size-1].high=array[j].high,Digits()),". Совпадений: ",(string)dataCandle[i].number_matched);
               }
            }
         }
      }

   //--- Посмотрим чего понаписали в массивы
   Alert ( "Array is series: " , ArrayIsSeries (array),
         "\ntime array[0]: " , TimeToString (array[ 0 ].time, TIME_DATE | TIME_MINUTES ),
         "\ntime array[" , string (searchPeriod- 1 ), "]: " , TimeToString (array[ ArraySize (array)- 1 ].time, TIME_DATE | TIME_MINUTES ));
   for ( int i= 0 ; i< ArraySize (dataCandle)- 1 ; i++) {
       string refs_txt= "" ;
       string matched_txt= "" ;
      refs_txt= "Свеча " + IntegerToString (i, 2 , '0' )+ ": время " + TimeToString (dataCandle[i].reference_candle.time)+ ", high: " + DoubleToString (dataCandle[i].reference_candle.high, Digits ())+ " имеет совпадений: " +( string )dataCandle[i].number_matched+ " шт. " ;
       if (dataCandle[i].number_matched> 0 ) {
         for ( int j= 0 ; j< ArraySize (dataCandle[i].matched_candles); j++) {
            matched_txt= "Совпадение " + IntegerToString (j+ 1 )+ ": " + TimeToString (dataCandle[i].matched_candles[j].time)+ ", high: " + DoubleToString (dataCandle[i].matched_candles[j].high, Digits ());
            }
         }
       Print (refs_txt,matched_txt);
      }
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin :

따라서 이것은 "버그, 버그, 질문"에 보고되어야 하는 버그입니다.

다음은 테스트 스크립트입니다. array[] 배열의 0과 마지막 셀에 복사된 양초의 시간을 보여줍니다.

이것을 준다:

배열이 계열: false

시간 배열[0]: 2016.05.12 21:00

시간 배열[9]: 2016.05.12 12:00

 
Andrey Koldorkin :

이것을 준다:

배열이 계열: false

시간 배열[0]: 2016.05.12 21:00

시간 배열[9]: 2016.05.12 12:00

나는 그것이 제공하는 것을 확인했습니다-항상 거짓이지만 시간은 정확합니다. 스크립트를 시작할 때 배열 배열을 시계열 "예"로 선택하면 다음과 같습니다.

Array is series: false
time array[ 0 ]: 2016.05 . 12 21 : 00
time array[ 9 ]: 2016.05 . 12 12 : 00

"아니오"를 선택한 경우:

Array is series: false
time array[ 0 ]: 2016.05 . 12 12 : 00
time array[ 9 ]: 2016.05 . 12 21 : 00

배열에 기록된 초의 시간이 변경되었습니다. 즉 , ArraySetAsSeries() 는 올바르게 작동하지만 ArrayIsSeries()는 작동하지 않고 항상 false를 반환합니다. 이미 위에서 언급한 버그 스레드를 구독 취소했습니다.

 
Andrey Koldorkin :

아, 프로그래밍이군요. 숲속으로 더....

배열의 방향을 알 필요는 없습니다. 알고리즘은 반복을 찾고 있습니다. 따라서 막대가 처리되는 순서는 중요하지 않습니다.
 
Vasiliy Sokolov :
배열의 방향을 알 필요는 없습니다. 알고리즘은 반복을 찾고 있습니다. 따라서 막대가 처리되는 순서는 중요하지 않습니다.
필요. 결국, 나는 어떤 양초가 우연의 일치를 형성했는지 알아내고 현재 가격 에 가장 가까운 것에서 낮은 가격을 취해야 합니다.
 
Andrey Koldorkin :
필요. 결국, 나는 어떤 양초가 우연의 일치를 형성했는지 알아내고 현재 가격 에 가장 가까운 것에서 낮은 가격을 취해야 합니다.

이를 위해 구조에는 촛불 시간이 있어 필요할 때 가장 가까운 촛불을 찾을 수 있습니다.

그리고 촛불의 숫자를 표시할 필요가 없습니다. 막대의 실제 숫자와 일치하지 않습니다. 결국 우리는 배열을 채우고 배열의 인덱스는 차트가 아닌 배열의 촛불 번호에만 속합니다.

 
Artyom Trishkin :

나는 그것이 제공하는 것을 확인했습니다-항상 거짓이지만 시간은 정확합니다. 스크립트를 시작할 때 배열 배열을 시계열 "예"로 선택하면 다음과 같습니다.

"아니오"를 선택하는 경우:

배열에 기록된 초의 시간이 변경되었습니다. 즉, ArraySetAsSeries()는 올바르게 작동하지만 ArrayIsSeries()는 작동하지 않고 항상 false를 반환합니다. 이미 위에서 언급한 버그 스레드를 구독 취소했습니다.

코드를 약간 변경했습니다.

ArraySetAsSeries (배열, 참); // 여기에 그냥 true를 넣어

그런 다음 자체 테스트를 위해 양초 수를 작성하기 위해 추가되었습니다.

Alert("배열은 시리즈입니다: ",ArrayIsSeries(array),

"\nCandle "+IntegerToString(0,2,'0')+" 시간 배열[0]: ",TimeToString(array[0].time,TIME_DATE|TIME_MINUTES),

"\nCandle "+IntegerToString(searchperiod-1,2,'0')+" 시간 배열[",string(searchperiod-1),"]: ",TimeToString(array[ArraySize(array)-1].time, TIME_DATE|TIME_MINUTES));

다음을 제공합니다.

배열이 계열: false

캔들 00 타임 어레이[0]: 2016.05.12 22:00

캔들 09 타임 어레이[9]: 2016.05.12 13:00

 
Artyom Trishkin :
이를 위해 구조에는 촛불 시간이 있어 필요할 때 가장 가까운 촛불을 찾을 수 있습니다.
글쎄, 그것은 중요하지 않습니다. 방향이 한 줄의 코드로 변경되었음을 알 수 있습니다. 프로세스가 복잡하지 않습니다. 그러나 나는 무슨 일이 일어나고 있는지 이해하려고 노력하는 동안 최소한 내 머리와 차가 같은 순서로있을 것입니다))
 
Andrey Koldorkin :

코드를 약간 변경했습니다.

ArraySetAsSeries(배열, 참); // 여기에 그냥 true를 넣어

그런 다음 자체 테스트를 위해 양초 수를 작성하기 위해 추가되었습니다.

Alert("배열은 시리즈입니다: ",ArrayIsSeries(array),

"\nCandle "+IntegerToString(0,2,'0')+" 시간 배열[0]: ",TimeToString(array[0].time,TIME_DATE|TIME_MINUTES),

"\nCandle "+IntegerToString(searchperiod-1,2,'0')+" 시간 배열[",string(searchperiod-1),"]: ",TimeToString(array[ArraySize(array)-1].time, TIME_DATE|TIME_MINUTES));

다음을 제공합니다.

배열이 시리즈임: false

촛불 00 시간 배열[0]: 2016.05.12 22:00

캔들 09 타임 어레이[9]: 2016.05.12 13:00

mql4를 사용하고 있습니까? 그렇다면 구조에 기록된 시간별로 양초의 수를 찾으십시오. iBarShift() 가 도움이 됩니다.
사유: