Помогите разобраться с оператором if и логикой флагов с ! (не)

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Valeriy Yastremskiy
1590
Valeriy Yastremskiy  

Подскажите где туплю, не люблю что либо не до понимать. Допустим флаг BuyStop Истина и AllSymbol=true

 if(Type == ORDER_TYPE_BUY_STOP && !BuyStop) continue;

Я понимаю так, если Type равен BUY_STOP И флаг BuyStop Не Истина, то continue, т.е. заканчиваем исполнение текущей итерации оператора for и проверяем условие цикла и переходим к Выражению 2. Иначе переходим к следующему оператору. 

Из справки:

Оператор continue передает управление в начало ближайшего внешнего оператора цикла while, do-while или for, вызывая начало следующей итерации. Этот оператор по действию противоположен оператору break.

Т.е. если тип Байстоп, и флаг удаления Байстоп Истина, то переходим к следующей итерации. 

Как до удаления ордеров скрипт доходит.

Так же

if(!AllSymbol && Symbol()!=OrderGetString(ORDER_SYMBOL)) continue;

Если флаг удаления ордеров во всех окнах Не Истина И символ текущего окна не равен символу выбранного ордера, то следующая итерация, иначе переходим к следующему оператору. В котором как раз и происходит удаление.

Скрипт то работает, я что то не догоняю. Почему удаление ордера находится в теле цикла for(int i=0; i<OrdersTotal(); i++)?


// Подключение файла для использования класса CTrade из комплекта терминала
#include <Trade/Trade.mqh>

// Внешние параметры

// Выбор символа. true  - удалять ордера всех символов, 
//                false - только с символом графика, на котором выполняется скрипт
input bool AllSymbol=false;

// Включение типов удаляемых ордеров
input bool BuyStop       = false;
input bool SellStop      = false;
input bool BuyLimit      = false;
input bool SellLimit     = false;
input bool BuyStopLimit  = false;
input bool SellStopLimit = false;

// Загрузка класса CTrade
CTrade Trade;
//---
void OnStart()
  {
// Переменная для проверки результата работы функции
   bool Ret=true;
// По всем ордерам в терминале
   for(int i=0; i<OrdersTotal(); i++)
     {
      ulong Ticket=OrderGetTicket(i); // Выделение ордера и получение его тикета
                                      // Удалось выделить
      if(Ticket>0)
        {
         long Type=OrderGetInteger(ORDER_TYPE);
         // Проверки типа ордера
         if(Type == ORDER_TYPE_BUY_STOP && !BuyStop) continue;
         if(Type == ORDER_TYPE_SELL_STOP && !SellStop) continue;
         if(Type == ORDER_TYPE_BUY_LIMIT && !BuyLimit) continue;
         if(Type == ORDER_TYPE_SELL_LIMIT && !SellLimit) continue;
         if(Type == ORDER_TYPE_BUY_STOP_LIMIT && !BuyStopLimit) continue;
         if(Type == ORDER_TYPE_SELL_STOP_LIMIT && !SellStopLimit) continue;
         // Проверка символа
         if(!AllSymbol && Symbol()!=OrderGetString(ORDER_SYMBOL)) continue;
         // Удаление
         if(!Trade.OrderDelete(Ticket))
           {
            Ret=false; // Не удалось удалить
           }
        }
      // Не удалось выделить ордер, результат неизвестен,
      // значит функция отработала с ошибкой
      else
        {
         Ret=false;
         Print("Ошибка выделения ордера");
        }
     }

   if(Ret)
     {
      Alert("Работа скрипта завершена успешно");
     }
   else    
     {
      Alert("При работе скрипта произошла ошибка, подробности см. в журнале");
     }
  }
Документация по MQL5: Основы языка / Операторы / Оператор цикла for
Документация по MQL5: Основы языка / Операторы / Оператор цикла for
  • www.mql5.com
. Все повторяется, пока выражение2 не станет ложным. Если оно ложно, цикл заканчивается и управление передается следующему оператору. ВыражениеЗ вычисляется после каждой итерации. могут отсутствовать, однако разделяющие их точки с запятыми (;) опускать нельзя. Если опущено...
Evgeniy Zhdan
16784
Evgeniy Zhdan  
Valeriy Yastremskiy:

Скрипт то работает, я что то не догоняю. Почему удаление ордера находится в теле цикла for(int i=0; i<OrdersTotal(); i++)?

С continue все правильно.

Про удаление - в цикле происходит перебор открытых ордеров и какой надо, тот удаляется.

Можно и без цикла, но тогда надо знать тикет ордера и удалить по этому тикету

Igor Zakharov
6651
Igor Zakharov  
между прочим, цикл неверно направлен. нужно перевернуть
for(int i=OrdersTotal()-1; i>=0; i--)

например, ордера с порядковыми номерами 0 и 1 соответствуют всем условиям. в вашем первоначальном варианте, начав с 0, он будет удалён, а список сдвинется - первый станет нулевым. НО индекс цикла тоже повысится, и проверка на соответсвие условиям будет текущего 1го... а на этой позиции теперь бывший 2й (из-за сдвига после удаления)

Valeriy Yastremskiy
1590
Valeriy Yastremskiy  
Evgeniy Zhdan:

С continue все правильно.

Про удаление - в цикле происходит перебор открытых ордеров и какой надо, тот удаляется.

Можно и без цикла, но тогда надо знать тикет ордера и удалить по этому тикету

Можно словами, что происходит? Почему по continue итерация не заканчивается, а переходит к строке удаления? С перебором согласен, порядковые номера меняются. И как срабатывает Не true в операторе if. Не догоняю.
Evgeniy Zhdan
16784
Evgeniy Zhdan  
Valeriy Yastremskiy:
Можно словами, что происходит? Почему по continue итерация не заканчивается, а переходит к строке удаления? С перебором согласен, порядковые номера меняются. И как срабатывает Не true в операторе if. Не догоняю.

А при каких настройках переходит к строке удаления?

Не true - значит false

Konstantin Nikitin
9256
Konstantin Nikitin  
         if(Type == ORDER_TYPE_BUY_STOP && !BuyStop) continue;
         if(Type == ORDER_TYPE_SELL_STOP && !SellStop) continue;
         if(Type == ORDER_TYPE_BUY_LIMIT && !BuyLimit) continue;
         if(Type == ORDER_TYPE_SELL_LIMIT && !SellLimit) continue;
         if(Type == ORDER_TYPE_BUY_STOP_LIMIT && !BuyStopLimit) continue;
         if(Type == ORDER_TYPE_SELL_STOP_LIMIT && !SellStopLimit) continue;

Так будет понятней?

         if(Type == ORDER_TYPE_BUY_STOP)
              if(!BuyStop) continue;
         if(Type == ORDER_TYPE_SELL_STOP)
             if(!SellStop) continue;
         if(Type == ORDER_TYPE_BUY_LIMIT)
              if(!BuyLimit) continue;
         if(Type == ORDER_TYPE_SELL_LIMIT)
              if(!SellLimit) continue;
         if(Type == ORDER_TYPE_BUY_STOP_LIMIT)
              if(!BuyStopLimit) continue;
         if(Type == ORDER_TYPE_SELL_STOP_LIMIT)
              if(!SellStopLimit) continue;

Вам похоже нужно понять поведение при && ||

Ну и если ни чего не устраивает проверку, то идем дальше до строки удаления

Valeriy Yastremskiy
1590
Valeriy Yastremskiy  
Konstantin Nikitin:

Так будет понятней?

Вам похоже нужно понять поведение при && ||

Ну и если ни чего не устраивает проверку, то идем дальше до строки удаления

Если истина то continue. Иначе к следующему if. И на нём если истина? Удаление идёт по флагу истина.
Я понимаю так, если Type равен BUY_STOP И флаг BuyStop Не Истина, то continue, т.е. заканчиваем исполнение текущей итерации оператора for и проверяем условие цикла и переходим к Выражению 2. Иначе переходим к следующему оператору.  
Alexey Viktorov
27910
Alexey Viktorov  
Valeriy Yastremskiy:
Если истина то continue. Иначе к следующему if. И на нём если истина? Удаление идёт по флагу истина.
Я понимаю так, если Type равен BUY_STOP И флаг BuyStop Не Истина, то continue, т.е. заканчиваем исполнение текущей итерации оператора for и проверяем условие цикла и переходим к Выражению 2. Иначе переходим к следующему оператору.  

Для полного понимания напишите самый простой пример и проверьте выполнение в режиме пошаговой отладки.

Evgeniy Zhdan
16784
Evgeniy Zhdan  
Valeriy Yastremskiy:
Если истина то continue. Иначе к следующему if. И на нём если истина? Удаление идёт по флагу истина.
Я понимаю так, если Type равен BUY_STOP И флаг BuyStop Не Истина, то continue, т.е. заканчиваем исполнение текущей итерации оператора for и проверяем условие цикла и переходим к Выражению 2. Иначе переходим к следующему оператору.  

Не переходит оно в выражение 2. Просто на следующую итерацию и снова по очереди все if, пока ордера не кончатся

Valeriy Yastremskiy
1590
Valeriy Yastremskiy  
Evgeniy Zhdan:
Igor Zakharov:

Konstantin Nikitin:

Alexey Viktorov:

Спасибо всем за участие)

Догнал наконец то.

На человеческом языке это звучит так. Если мы не хотим удалять удалять ордер найденного типа и флаг не хотим то на следующую итерацию, если хотим удалять, то далее вниз.

И так же, если не хотим удалять из всех окон, и символ ордера не совпадает с символом нашего окна, то на следующую итерацию, иначе удаляем, т.е. если не хотим удалять со всех инструментов и символ ордера совпадает, то далее вниз и удаляем.

От обратного логика просто. Не всегда очевидно мне обратная логика видимо. Еще раз спасибо всем)))))

Alexey Viktorov
27910
Alexey Viktorov  
Valeriy Yastremskiy:

Спасибо всем за участие)

Догнал наконец то.

На человеческом языке это звучит так. Если мы не хотим удалять удалять ордер найденного типа и флаг не хотим то на следующую итерацию, если хотим удалять, то далее вниз.

И так же, если не хотим удалять из всех окон, и символ ордера не совпадает с символом нашего окна, то на следующую итерацию, иначе удаляем, т.е. если не хотим удалять со всех инструментов и символ ордера совпадает, то далее вниз и удаляем.

От обратного логика просто. Не всегда очевидно мне обратная логика видимо. Еще раз спасибо всем)))))

Вот теперь самое время разобраться в нелогичности такого подхода к условиям.

На мой взгляд гораздо понятней и логичней писать

for(int i = 0; i > 7; i++)
 {
  if(условие выполнено)
   {
    какое-то действие
   }
 }

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

И даже если будет несколько условий через и && ничего не замедлит выполнение. Проверка условий проводится слева направо и если очередное условие не выполнено, проверка прекращается. Правда если в условиях есть или || то при невыполнении одной части проверяется вторая часть и так-же прекращается проверка при невыполнении очередного условия.

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий