Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 329

 
Alexey Viktorov:

There is no need to sort the array after each addition of an array element. It is better to move the sorting

From the reference

Mas[Blizko2] is the closest smaller value in the array

Thank you for your reply! Could you please tell me, to determine the next element of the array, I used the already found element +1, but the tester gives out an error in this place.

 double Mas[];                                                                //массив для упорядочивания всех ордеров
  for(int i=0; i<OrdersTotal(); i++)                                           // Цикл перебора ордер
   {
    if(OrderSelect(i,SELECT_BY_POS))                                           // Если есть следующий
     {
       Price=OrderOpenPrice();
       ArrayResize(Mas, i+1);                                                 //задан размер массива
       Mas [i] = Price; 
       ArraySort (Mas,WHOLE_ARRAY,0,MODE_DESCEND);                           // Теперь цены открытия упорядочены по убыванию
     }
   } 
   if(ArraySize(Mas)>1)                                                         //Если массив не пустой
   
         { 
        int Blizko2=ArrayBsearch(Mas,Ask,WHOLE_ARRAY,0,MODE_DESCEND);          //Определен индекс ближайшего большего по значению елемента к текущей цене
        

        Mas[Blizko2+1]= Blizko1;     // В этой строке перед квадратной скобкой выдает ошибку!                           //Определен индекс ближайшего меньшего по значению елемента к текущей цене

        PriceBlizko1=Mas[Blizko1];
        PriceBlizko2 = Mas[Blizko2];                                      // Цена выбранного ордера   

I need to find the next element. Obviously it is +1, but the program gives me an error! Maybe there is another way or maybe I do it wrong? Please give me a hint)

Blizko1 = Mas[Blizko2]+1;

or like this??

but then at compilation a warning about possible data loss

 
vikzip:

With this construction

Blizko1 = Mas[Blizko2]+1;

you add 1 to the value obtained from the Blizko2 index cell, and that's where the price is stored - a double value. You are adding an integer 1. To avoid a warning, you need to write +1.0

But this will not save the "father of Russian democracy" either, because you are adding 1 not to the index but to the value stored in the Mas[] array by the index Blizko2.

So, naturally, to get a value from a nearby cell of the array, you need to add or subtract 1 to the index. But here we have an error you have stumbled on: if index points to the outermost cell of an array - either 0 or the very last, then subtracting 1 (at 0) or adding 1 (at the very last), you will fall outside the array - no such cell is there. Accordingly, you need to control that Blizko2+1 is not more than ArraySize(Mas)-1, or Blizko2-1 is not less than zero.

And... you've been told that you don't need to sort the array at each iteration of the loop - do you need brakes?

It should be sorted after checking if the array's size is greater than 1.

And this design is not clear at all:

int Blizko2=ArrayBsearch(Mas,Ask,WHOLE_ARRAY,0,MODE_DESCEND);          //Определен индекс ближайшего большего по значению елемента к текущей цене

Mas[Blizko2+1]= Blizko1; // В этой строке перед квадратной скобкой выдает ошибку! //Определен индекс ближайшего меньшего по значению елемента к текущей цене

        PriceBlizko1=Mas[Blizko1];
        PriceBlizko2 = Mas[Blizko2];                                      // Цена выбранного ордера   

Look: in Blizko2 you have the index of the array cell with the price.
Then you write into the array - into its cell Blizko2+1 the value contained in the variable Blizko1 (why???) - you should have prices there, but you're stuffing them with incomprehensible values.

You need to figure out what you're doing in general - just comment out each line of your function. Thoughtfully.

 
Artyom Trishkin:

With this construction

you add 1 to the value obtained from the Blizko2 index cell, and that's where the price is stored - a double value. You are adding an integer 1. To avoid a warning, you need to write +1.0

But this will not save the "father of Russian democracy" either, because you are adding 1 not to the index but to the value stored in the Mas[] array by the index Blizko2.

So, naturally, to get a value from a nearby cell of the array, you need to add or subtract 1 to the index. But here we have an error you have stumbled on: if index points to the outermost cell of an array - either 0 or the very last, then subtracting 1 (at 0) or adding 1 (at the very last), you will fall outside the array - no such cell is there. Accordingly, you need to control that Blizko2+1 is not more than ArraySize(Mas)-1, or Blizko2-1 is not less than zero.

And... you've been told that you don't need to sort the array at each iteration of the loop - do you need brakes?

To sort it, we have to check if the size of array is more than 1.

And this construction is not clear at all:

See: in Blizko2 you have the index of the array cell with the price.
Then you write into the array - into its cell Blizko2+1 the value contained in the variable Blizko1 (why???) - you should have prices there, but you're stuffing them with incomprehensible values.

You need to figure out what you're doing in general - just comment out each line of your function. Thoughtfully.


Thanks for the informative answer! The purpose for which I want to create the array is to determine the prices of the nearest orders below the price and above the price, if there are any. If they are available and the distance from them to the price exceeds the distance I have defined, then open the corresponding orders. I thought it would look like this (I described the logic of my actions here as much as I could)

//---Создаем массив для учета всех ордеров в терминале
  double Price;                                                               // Цена выбранного ордера
  double Mas[];                                                                //массив для упорядочивания всех ордеров
  for(int i=0; i<OrdersTotal(); i++)                                           // Цикл перебора ордер
   {
    if(OrderSelect(i,SELECT_BY_POS))                                           // Если есть следующий
     {
       Price=OrderOpenPrice();                                                //Цена ордера
       ArrayResize(Mas, i+1);                                                 //задан размер массива
       Mas [i] = Price; 
       ArraySort (Mas,WHOLE_ARRAY,0,MODE_DESCEND);                           // Теперь цены открытия упорядочены по убыванию. Я намеренно сортирую массив, потому что ордера добовляются в него в том порядке в котором появляются в 
                                                                             //терминале и не сортируются по убыванию(Верно ли это мое утверждение??)А мне необходимо позже точно определить ближайший ордер выше и ниже цены

     }
   } 
   if(ArraySize(Mas)>1)                                                         //Если массив не пустой
   
         { 
        int Blizko2=ArrayBsearch(Mas,Ask,WHOLE_ARRAY,0,MODE_DESCEND);          //Определен индекс ближайшего большего по значению елемента к текущей цене
                                                                               //Здесь я справку прочитал и если указано MODE_ASCEND тогда будет найдено ближайшее меньшее значение, но первым я намерен определить ордер выше цены и 
                                                                               // поэтому поставил MODE_DESCEND. Скажите пожалуйста - это верно?? 
         PriceBlizko1 = Mas[Blizko2]+1;                                        //!!!Вот здесь я намереваюсь определить ордер сразу ниже цены и так как я намеренно упорядочил по убыванию уже все ордера в массиве, то по логике после 
                                                                               //определения ближайшего верхнего ордера к цене Blizko2 следующим в массиве будет ордер уже ниже цены(Верно ли мое утверждение??)И вот на этом месте я не 
                                                                               //могу понять: каким же образом это сделать? Ведь мне очевидно что он следующий, но как это записать в код я не могу понять))) Пробовал и в скобках уже 
                                                                               //прибавлять еденицу)) А мне нужно что бы PriceBlizko1 была присвоена цена ордера сразу ниже цены!! Подскажите пожалуйста как определить цену ордера ниже 
                                                                               //цены PriceBlizko2 ??
         PriceBlizko2 = Mas[Blizko2];                                          // Цена выбранного ордера выше цены         

        
 

I would look something like this

double levelDown=0;
double levelUp=DBL_MAX;

int totalOrders=OrdersTotal();


   for(int i=0;i<totalOrders;i++)
      {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         {
         double price=OrderOpenPrice();
         
         if (price-Ask>_Point && levelUp-price>_Point)
            levelUp=price;
         
         if (Bid-price>_Point && price-levelDown>_Point)
            levelDown=price;
         }
      }
 
Taras Slobodyanik:

I would look something like this


Thank you, what doesDBL_MAX in the top level mean?

 
vikzip:

Thank you! What doesDBL_MAX mean?

You even got a link inserted by the clever forum engine. It's easier to click on it than to wait for an answer.

 
Artyom Trishkin:

You even got a link inserted by the clever forum engine. It's easier to click on it than to wait for a reply.


Thank you! I wish I had such an engine)))

 
vikzip:

Thanks for the informative reply! The purpose for which I intend to create the array is to determine the prices of the nearest orders below the price and above the price, if there are any. If they are available and the distance from them to the price exceeds a certain distance, then open the corresponding orders. I thought it would look like this (I described the logic of my actions here as much as I could)

There is an error in this line comment.

        int Blizko2=ArrayBsearch(Mas,Ask,WHOLE_ARRAY,0,MODE_DESCEND);          //Определен индекс ближайшего большего по значению елемента к текущей цене


Forum on trading, automated trading systems and trading strategies testing.

Any MQL4 beginners questions, help and discussion on algorithms and codes

Alexey Viktorov, 2017.10.04 09:32


From the help

Returned value

Returns index of the first element found. If the sought value is not found, it returns the index of the closest smaller element between which the sought value is located.

Mas[Blizko2] is the nearest smaller value in the array.


It only remains to add that the reference does not say anything about dependence on the sorting direction of the array. So, no manipulation is needed after ArrayBsearch. The task is already done.

Artyom has already explained everything further. Check equality of an index to zero and the size of an array not to jump out of bounds...

 

How can I make the mouse start to be tracked only after I click on the button? But the situation happens (in the idea of transferring a stop on all orders to one point by mouse click from the EA) when I click the button, a stop on all orders at the price where the button was clicked starts to be transferred at once. How can this property if(id==CHARTEVENT_CLICK)

run only after this button has been clicked if(ObjectGetInteger(0, "cm STOP ALL",OBJPROP_STATE))

 
Basicprof:

How can I make the mouse start to be tracked only after the button is clicked? But the situation happens (in the idea of transferring a stop on all orders to one point by mouse click from the EA) when I click the button, a stop on all orders at the price where the button was clicked starts to be transferred at once. How can this property if(id==CHARTEVENT_CLICK)

run only after this button has been clicked if(ObjectGetInteger(0, "cm STOP ALL",OBJPROP_STATE))


if(id==CHARTEVENT_OBJECT_CLICK && sparam == "cm STOP ALL") { // код }
Reason: