Questions from Beginners MQL5 MT5 MetaTrader 5 - page 573

 
Andrey Koldorkin:

I'll see what I can figure out. Thank you. (chuckles)

You're welcome. It just saves all the highs into an array, and then prints all the data saved in the array into the log in a loop.

This script doesn't necessarily do exactly what you need it to do. It simply shows how the data is stored in the array.

 
Artyom Trishkin:

Not at all. It simply saves all the highs into an array, and then prints out all the data saved in the array in a loop in the logbook.

This script doesn't necessarily do exactly what you need. It just shows the principle of saving data in an array.

That's exactly what I was looking for. I needed it to somehow save the data to an array for the period I choose. That's the part I understood from you.

Now my question is, HOW can I access and compare the recorded data in the array?

Here it turns out to iterate, write the array step by step. This is good. But now we need to compare the elements with each other.

Is it necessary to declare a new iteration count and then retrieve the data and compare them somehow? But this again has to write the results somewhere and ... everything repeats in the end.

Roughly, if comparison period is 5-7 candlesticks, then the 1st one should be compared to other 6, then the 2nd one and so on.... And if two or more of them have equal High, then firstly, you should calculate this High, and secondly, you should find the candlestick with the lowest Low. I.e. the function of calling concrete candlesticks in the end to fetch all their parameters.

But is it possible to do it?

 
Andrey Koldorkin:

that's exactly what I was looking for. I needed it to somehow store the data in an array for the period I was selecting. I understood that part.

Now my question is, HOW can I access and compare the recorded data in the array?

Here it turns out to iterate, write the array step by step. This is good. But now we need to compare the elements with each other.

Is it necessary to declare a new iteration count and then retrieve the data and compare them somehow? But this again has to write the results somewhere and ... everything repeats in the end.

Roughly, if comparison period is 5-7 candlesticks, then the 1st one should be compared to other 6, then the 2nd one and so on.... And if two or more of them have equal High, then firstly, you should calculate this High, and secondly, you should find the candlestick with the lowest Low. I.e. the function of calling concrete candlesticks in the end to fetch all their parameters.

But is it possible to do it?

Here we are just interrogating the saved array and displaying all the saved data in the log:

for(int i=0; i<ArrayRange(mass_high,0); i++) {
   printf("Время: %s, High: %.5f",TimeToString((int)mass_high[i][1],TIME_DATE|TIME_MINUTES),mass_high[i][0]);
   }

Let's be more specific about the task:

We need to find ... what exactly in the saved array?

 
Artyom Trishkin:

This is where the saved array is interrogated, and all saved data is logged:

Let's be specific about the task:

We need to find in the saved array ... what exactly?

I need, to record an array of data for all closed candles (i.e. the current one is not counted) - High, Low, Open, Close candles (4 parameters) for the period which is specified in the settings. - it is.

Next, I need to compare the parameters. Suppose the search period is equal to 10 candlesticks. Here we need to check all High for the period of 10 candlesticks. If there are two or more matches, we should return:

1. Flag - "There is a match".

1. The High value where the candlesticks have the same value.

2. Numbers of these candlesticks, so we can refer to them and find out Low, Close, Open parameters for them.

In general, I understand much of this how to do it.

What is not clear is how to refer to those candlesticks which form the level. Ideally, when recalculating, we could memorize the number of iteration (i) but first we have a recalculation according to which the log is written and it cannot be applied.

And in that variant, as the output log records - this is also not what is required.

I understand that I need to first take a candlestick 1 and compare it with 9 others, if there is a match, then extract the numbers of these candles and their parameters, turn on the checkbox. Then check candle 2 with the others and so on to the middle of the sample, as then will go duplicates of comparisons only from the other side.

If the number of candlesticks was fixed, I would have written it like this - roughly 5 comparison cycles. But that's the question - how to make such recalculation possible for any sample size.

 
Andrey Koldorkin:

I need to write an array of data for all closed candles (i.e. the current one is not counted) - High, Low, Open, Close candles (4 parameters) for the period specified in the settings. - it is.

Next, I need to compare the parameters. Suppose the search period is equal to 10 candlesticks. Here we need to check all High for the period of 10 candlesticks. If there are two or more matches, we should return:

1. Flag - "There is a match".

1. The High value where the candlesticks have the same value.

2. Numbers of these candlesticks, so we can refer to them and find out Low, Close, Open parameters for them.

In general, I understand much of this how to do it.

What is not clear is how to refer to those candlesticks which form the level. Ideally, when recalculating, we could memorize the number of iteration (i) but first we have a recalculation according to which the log is written and it cannot be applied.

And in that variant, as the output log records - this is also not what is required.

I understand that I need to first take a candlestick 1 and compare it with 9 others, if there is a match, then extract the numbers of these candles and their parameters, turn on the checkbox. Then check candle 2 with the others and so on to the middle of the sample, as then will go duplicates of comparisons only from the other side.

If the number of candlesticks was fixed, I would have written it like this - roughly 5 comparison cycles. But that's the question - how to make such a recalculation possible for any sample size.

And by the way, the exact coincidence of price values is unlikely to be frequent. We need to set some delta, and consider it a coincidence if prices do not differ more than this value.

So if we need a separate list of matching candlesticks for each candlestick in the range, I'd try using an array of structures. I'll think about it and let you know.
 
Andrey Koldorkin:

I need to write an array of data for all closed candles (i.e. the current one is not counted) - High, Low, Open, Close candles (4 parameters) for the period specified in the settings. - it is.

Next, I need to compare the parameters. Suppose the search period is equal to 10 candlesticks. Here we need to check all High for the period of 10 candlesticks. If there are two or more matches, we should return:

1. Flag - "There is a match".

1. The High value where the candlesticks have the same value.

2. Numbers of these candlesticks, so we can refer to them and find out Low, Close, Open parameters for them.

In general, I understand much of this how to do it.

What is not clear is how to refer to those candlesticks which form the level. Ideally, when recalculating, we could memorize the number of iteration (i) but first there is a recalculation according to which the log is written and it cannot be applied.

And in that variant, as the output log records - here, too, is not what is required.

I understand that I need to first take a candlestick 1 and compare it with 9 others, if there is a match, then extract the numbers of these candles and their parameters, turn on the checkbox. Then check candle 2 with the others and so on to the middle of the sample, as then will go duplicates of comparisons only from the other side.

If the number of candlesticks was fixed, I would have written it like this - roughly 5 comparison cycles. But that's the question - how to enable such a recalculation for any sample size.

Instead of flag "coincidence" set the counter, on value high where the counter is greatest, there is a level

The high value can be rounded up, for example 1.23456 to 1.2346

and 1.23462 rounded up to 1.2346

because it is unlikely that out of 10 candlesticks, 2 will have a high of 1.23456

so dance from the level

and the number of candlesticks is fixed, you write a certain amount of data into the structure

i.e. the number of candlesticks written in the structure is the same number of iterations

 
Andrey Koldorkin:

I need to write an array of data for all closed candles (i.e. the current one is not counted) - High, Low, Open, Close candles (4 parameters) for the period specified in the settings. - it is.

Next, I need to compare the parameters. Suppose the search period is equal to 10 candlesticks. Here we need to check all High for the period of 10 candlesticks. If there are two or more matches, we should return:

1. Flag - "There is a match".

1. The High value where the candlesticks have the same value.

2. Numbers of these candlesticks, so we can refer to them and find out Low, Close, Open parameters for them.

In general, I understand much of this how to do it.

What is not clear is how to refer to those candlesticks which form the level. Ideally, when recalculating, we could memorize the number of iteration (i) but first we have a recalculation according to which the log is written and it cannot be applied.

And in that variant, as the output log records - here, too, is not what is required.

I understand that I need to first take a candlestick 1 and compare it with 9 others, if there is a match, then extract the numbers of these candles and their parameters, turn on the checkbox. Then check candle 2 with the others and so on to the middle of the sample, as then will go duplicates of comparisons only from the other side.

If the number of candlesticks was fixed, I would have written it like this - roughly 5 comparison cycles. But here's the question: how to make such a recalculation possible for any sample size.

It is an interesting task, but your understanding of how to solve this problem is not correct, because so far you don't have much knowledge in programming.

Look: you have some set of quotes. Your task is to choose from this set only those bars which meet certain conditions. For example, you want to get a collection of bars, whose highs coincide with each other. In fact, there can be many conditions for the selection, and they can be added to over time. Once you have a collection of bars, you can easily analyze any of their other parameters.

So, for your task, you need to write a function that would return an array of bars satisfying a certain condition (pseudocode):

массив_баров = ПолучитьНужныеБары(Символ(), Таймфрейм(), Период(), УсловиеОтбора);
I.e. there's really no problem remembering and iterating some data and indexes. You don't need the indexes of the bars themselves, but a specific collection that satisfies a given condition. Once you have it, you solve a lot of problems in one fell swoop.
 
Artyom Trishkin:
So, if we need a different list of matching candlesticks for each candlestick in the range, I would try to use an array of structures. I'll think about it and let you know.

Thought. I am writing out a test script:

//+------------------------------------------------------------------+
//|                                                     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
//--- 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;
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) {                                                    // если скопировали
      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=i+1; j<copy_bars; j++) {                          // в цикле от i+1 до copy_bars
            //--- если совпадают high эталонной свечи (i) и свечи с индексом j (с допуском на величину delta*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);
               }
            }
         }
      }

   //--- Посмотрим чего понаписали в массивы
   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);
      }
  }
//+------------------------------------------------------------------+

Tried to describe all the steps.

After filling in all matches in the loop, we have an array containing all candlesticks and their matching candlesticks. After that you may look for low in it. And you can organize it right in the loop. It is more convenient to you.

 

Well, here's another way to do it: matches are written for each candle in the range. In the previous version, the matches were written only for one candle - i.e. no match was written for the one that matched this one.

//+------------------------------------------------------------------+
//|                                                     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
//--- 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;
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) {                                                    // если скопировали
      ArrayResize(dataCandle,copied);                                // задаём размер структуры равным числу скопированных данных
      ZeroMemory(dataCandle);                                        // Обнуляем данные в структуре
      //--- основной цикл по "эталонным" свечам в массиве array. Их параметры будем искать в доп. цикле
      for(int i=0; i<copy_bars; 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++) {                            // в цикле от 0 до 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);
               }
            }
         }
      }

   //--- Посмотрим чего понаписали в массивы
   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);
      }
  }
//+------------------------------------------------------------------+
 
The idea of opening orders on a buy or bear grip signal, how to make it so that there is only one buy/sell trade and one pending order trade, I have one open on every tick of the trade. Help to solve the problem.
Files:
ritfv.png  46 kb
ohs.txt  5 kb