Questions des débutants MQL5 MT5 MetaTrader 5 - page 578

 
Artyom Trishkin:

DataCandles est une structure. Le tableau dans lequel nous écrivons les chandeliers de l'historique est array[]. Nous devons donc en faire une série temporelle pour que son indexation coïncide avec l'indexation des bougies sur le graphique. C'est-à-dire que la cellule zéro du tableau[] correspondra aux chandeliers les plus proches de la date actuelle.

C'est-à-dire que 1. nous copions les chandeliers dans le tableau array[], 2. nous en faisons une série temporelle, puis nous lisons les valeurs de celle-ci dans la structure.

Vous pouvez faire sans array[] - juste écrire les données directement du graphique dans la structure, mais j'ai suggéré ceci pour la compatibilité avec Five - il permet de copier directement seulement dans l'indicateur en utilisant high[i], low[i] et d'autres données, mais dans le script ou Expert Advisor, nous devrons d'abord copier l'intervalle historique nécessaire dans le tableau, ce que j'ai fait.

bool series=ArrayIsSeries(array) ;
Alerte (série) ;
ArraySetAsSeries (tableau, true) ;
bool series=ArrayIsSeries(array) ;

Alerte (série) ;

comme ça ?

Les deux alertes retournent toujours faux

 
Andrey Koldorkin:
bool series=ArrayIsSeries(array) ;
Alerte (série) ;
ArraySetAsSeries(tableau, true) ;
bool series=ArrayIsSeries(array) ;

Alerte (série) ;

comme ça ?

Les deux alertes retournent toujours faux

Il s'agit donc d'un bogue qui doit être signalé à la rubrique "Erreurs, bogues, questions".

Voici un script de vérification, il montre le temps des chandeliers copiés dans les cellules zéro et dernière du tableau[] :

//+------------------------------------------------------------------+
//|                                                     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:

Il s'agit donc d'un bogue qui doit être signalé à la rubrique "Erreurs, bogues, questions".

Voici un script de vérification, il montre le temps des chandeliers copiés dans les cellules zéro et dernière du tableau[] :

Ça donne ça :

Le tableau est une série : false

time array[0] : 2016.05.12 21:00

time array[9] : 2016.05.12 12:00

 
Andrey Koldorkin:

Il en ressort ceci :

Le tableau est une série : false

time array[0] : 2016.05.12 21:00

time array[9] : 2016.05.12 12:00

Je l'ai vérifié - toujours faux, mais le temps est correct : si au début du script sélectionner Array array comme série temporelle "Oui", alors :

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

Si vous sélectionnez "Non", alors :

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

les temps des chandeliers écrits dans le tableau sont inversés, ce qui signifie que ArraySetAsSeriess() fonctionne correctement, mais pas ArrayIsSeries(), qui sort toujours false, ce que j'ai déjà écrit dans le fil de discussion sur les bugs ci-dessus.

 
Andrey Koldorkin:

Oh, cette programmation. Plus on avance dans les bois....

Comprenez que vous n'avez pas besoin de connaître la direction du réseau. L'algorithme recherche les répétitions. Par conséquent, l'ordre dans lequel les barres sont traitées importe peu.
 
Vasiliy Sokolov:
Comprenez que vous n'avez pas besoin de connaître la direction du réseau. L'algorithme recherche les répétitions. L'ordre dans lequel les barres sont traitées importe donc peu.
il le fait. Après tout, j'ai ensuite besoin de savoir quels chandeliers ont formé une correspondance et avec le plus proche du prix actuel prendre le prix Low.
 
Andrey Koldorkin:
vous avez besoin. Parce qu'alors je dois trouver quelles bougies ont formé une correspondance et prendre le prix bas de la plus proche du prix actuel.

Il existe pour cela une heure de bougie dans la structure, grâce à laquelle vous pouvez trouver la bougie la plus proche de l'heure dont vous avez besoin.

Et vous n'avez pas besoin de sortir les numéros des chandeliers - ils ne coïncident pas avec les numéros des barres réelles. Parce que nous remplissons le tableau, et les index dans le tableau n'appartiennent qu'au numéro du chandelier dans le tableau, pas sur le graphique.

 
Artyom Trishkin:

J'ai vérifié ce qu'il produit - toujours faux, mais le temps est correct : si vous sélectionnez Array array comme série temporelle "Oui" lors de l'exécution du script, alors :

Si vous sélectionnez "Non", alors :

Les temps des chandeliers écrits dans le tableau sont inversés, ce qui signifie que ArraySetAsSeriess() fonctionne correctement, mais pas ArrayIsSeries(), qui sort toujours false, ce que j'ai déjà écrit dans le fil de discussion sur les bugs ci-dessus.

J'ai légèrement modifié le code :

ArraySetAsSeries(array,true) ; //là, il suffit de mettre true

et a ensuite ajouté des nombres de chandeliers pour l'auto-vérification :

Alert("Array is series : ",ArrayIsSeries(array),

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

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

Il donne le résultat suivant :

Le tableau est une série : false

Candle 00 time array[0] : 2016.05.12 22:00

Bougie 09 time array[9] : 2016.05.12 13:00

 
Artyom Trishkin:
Pour ce faire, il existe une heure de bougie dans la structure, grâce à laquelle vous pouvez trouver la bougie la plus proche de l'heure dont vous avez besoin.
Eh bien, tout de même. il s'avère que la direction change avec une ligne de code. cela ne compliquera pas le processus. Mais pendant que j'essaie de comprendre ce qui se passe, au moins les chandeliers dans ma tête et dans la machine seront dans le même ordre ;))
 
Andrey Koldorkin:

J'ai changé le code un peu :

ArraySetAsSeries(array,true) ; //là, il suffit de mettre true

et a ensuite ajouté des nombres de chandeliers pour l'auto-vérification :

Alert("Array is series : ",ArrayIsSeries(array),

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

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

Il donne le résultat suivant :

Le tableau est une série : false

Candle 00 time array[0] : 2016.05.12 22:00

Bougie 09 time array[9] : 2016.05.12 13:00

Utilisez-vous mql4 ? Si c'est le cas, trouvez le numéro du chandelier à partir de son heure, qui est inscrite dans la structure. iBarShift() vous aidera.