Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 329

 
Alexey Viktorov:

Нет необходимости сортировать массив после каждого добавления элемента массива. Лучше перенести сортировку

Из справки

Mas[Blizko2] это и есть ближайшее меньшее значение в массиве

Спасибо за ответ! Подскажите пожалуста, для опредиления следующего элемента массива я использовал уже найденный элемент +1, но в тестере в этом месте выдает ошибку. 

 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];                                      // Цена выбранного ордера   

А мне необходимо определить следующий элемент. Очевидно это +1, но программа выдает ошибку! Может есть еще способ или может я не верно это делаю? Подскажите пожалуйста) 

Blizko1 = Mas[Blizko2]+1;

либо вот так??

но тогда при компиляции предупреждение о возможной потере данных

 
vikzip:

При такой конструкции

Blizko1 = Mas[Blizko2]+1;

вы к значению, полученному из ячейки с индексом Blizko2, прибавляете 1. А там хранится цена - double-значение. Вы же прибавляете целочисленное 1. Чтобы не было предупреждения, нужно написать +1.0

Но и это не спасёт "отца русской демократии", так как вы прибавляете единицу не к индексу, а к значению, хранящемуся в массиве Mas[] по индексу Blizko2.

Поэтому, естественно, чтобы получить значение из близлежащей ячейки массива, нужно к индексу прибавить или отнять 1. Но тут организуется ошибка, о которую вы и споткнулись: если индекс указывает на крайнюю ячейку массива - либо 0, либо самую последнюю, то отнимание 1 (при 0), или прибавление 1 (при самой последней), вы выйдете за пределы массива - нет там такой ячейки. Соответственно, вам нужно проконтролировать чтобы Blizko2+1 не было больше, чем ArraySize(Mas)-1, либо Blizko2-1 не было меньше ноля.

И..., вам же говорили, что не нужно сортировать массив на каждой итерации цикла - вам нужны тормоза?

Сортировать его нужно после проверки, что размер массива больше 1.

А вот эта конструкция вообще непонятно зачем:

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

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

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

Смотрите: в Blizko2 у вас индекс ячейки массива с ценой.
Далее вы записываете в массив - в его ячейку Blizko2+1 значение, содержащееся в переменной Blizko1 (зачем???) - там же у вас должны быть цены, а вы их забиваете непонятными значениями.

Вам нужно разобраться что вы вообще делаете - просто прокомментируйте каждую строчку вашей функции. Вдумчиво.

 
Artyom Trishkin:

При такой конструкции

вы к значению, полученному из ячейки с индексом Blizko2, прибавляете 1. А там хранится цена - double-значение. Вы же прибавляете целочисленное 1. Чтобы не было предупреждения, нужно написать +1.0

Но и это не спасёт "отца русской демократии", так как вы прибавляете единицу не к индексу, а к значению, хранящемуся в массиве Mas[] по индексу Blizko2.

Поэтому, естественно, чтобы получить значение из близлежащей ячейки массива, нужно к индексу прибавить или отнять 1. Но тут организуется ошибка, о которую вы и споткнулись: если индекс указывает на крайнюю ячейку массива - либо 0, либо самую последнюю, то отнимание 1 (при 0), или прибавление 1 (при самой последней), вы выйдете за пределы массива - нет там такой ячейки. Соответственно, вам нужно проконтролировать чтобы Blizko2+1 не было больше, чем ArraySize(Mas)-1, либо Blizko2-1 не было меньше ноля.

И..., вам же говорили, что не нужно сортировать массив на каждой итерации цикла - вам нужны тормоза?

Сортировать его нужно после проверки, что размер массива больше 1.

А вот эта конструкция вообще непонятно зачем:

Смотрите: в Blizko2 у вас индекс ячейки массива с ценой.
Далее вы записываете в массив - в его ячейку Blizko2+1 значение, содержащееся в переменной Blizko1 (зачем???) - там же у вас должны быть цены, а вы их забиваете непонятными значениями.

Вам нужно разобраться что вы вообще делаете - просто прокомментируйте каждую строчку вашей функции. Вдумчиво.


Спасибо за содержательный ответ! Цель по которой я намерен создать массив, заключается в опредилении цен ближайших ордеров ниже цены и выше цены если такие имеются. И если они есть, и расстояние от них до цены превышает опредиленную дистанцию, то открыть соответствующие ордера. Я думал что это должно выглядеть так(Здесь я описал на сколько смог логику  своих действий)

//---Создаем массив для учета всех ордеров в терминале
  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];                                          // Цена выбранного ордера выше цены         

        
 

я бы искал примерно так

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:

я бы искал примерно так


Спасибо!  Что значит  DBL_MAX в верхнем уровне

 
vikzip:

Спасибо!  Что значит DBL_MAX

Вам даже умный движок форума ссылку вставил. Проще перейти по ней, чем ответа ждать.

 
Artyom Trishkin:

Вам даже умный движок форума ссылку вставил. Проще перейти по ней, чем ответа ждать.


Спасибо! Мне бы такой движок)))

 
vikzip:

Спасибо за содержательный ответ! Цель по которой я намерен создать массив, заключается в опредилении цен ближайших ордеров ниже цены и выше цены если такие имеются. И если они есть, и расстояние от них до цены превышает опредиленную дистанцию, то открыть соответствующие ордера. Я думал что это должно выглядеть так(Здесь я описал на сколько смог логику  своих действий)

Ошибка в комментарии этой строки.

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


Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Любые вопросы новичков по MQL4, помощь и обсуждение по алгоритмам и кодам

Alexey Viktorov, 2017.10.04 09:32


Из справки

Возвращаемое значение

Возвращает индекс первого найденного элемента. Если искомое значение не найдено, то возвращает индекс ближайшего меньшего по значению из элементов, между которыми расположено искомое значение.

Mas[Blizko2] это и есть ближайшее меньшее значение в массиве.


Остаётся только добавить, что в справке не сказано о зависимости от направления сортировки массива. Так-что, после ArrayBsearch никаких манипуляций не надо. Задача уже выполнена.

Дальше всё уже Артём разжевал. Проверяйте равенство индекса нулю и размеру массива чтобы не выскочить за пределы...

 

Как сделать чтобы мышка начала отслеживаться только после нажатия на кнопку. А то происходит ситуация (по идее перенос стопа по всем одерам в одну точку по клику мыши из советника) когда я нажимаю на кнопку сразу начинается переноситься стоп по всем ордерам по той цене где была нажата кнопка. Как вот это свойство  if(id==CHARTEVENT_CLICK)

      запустить  только после нажатия на вот эту кнопку     if(ObjectGetInteger(0,"cm STOP ALL",OBJPROP_STATE))

 
Basicprof:

Как сделать чтобы мышка начала отслеживаться только после нажатия на кнопку. А то происходит ситуация (по идее перенос стопа по всем одерам в одну точку по клику мыши из советника) когда я нажимаю на кнопку сразу начинается переноситься стоп по всем ордерам по той цене где была нажата кнопка. Как вот это свойство  if(id==CHARTEVENT_CLICK)

      запустить  только после нажатия на вот эту кнопку     if(ObjectGetInteger(0,"cm STOP ALL",OBJPROP_STATE))


if(id==CHARTEVENT_OBJECT_CLICK && sparam == "cm STOP ALL") { // код }
Причина обращения: