Посмотрите код

 

Здравствуйте. Посмотрите следующий код и скажите правильно ли он написан:

string symb;

int OnInit()
{
symb=Symbol();
}

void OnTick()
{
...
}


bool isexistmarket()
{
for(int i=0; i<OrdersTotal(); i++)
{
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
  {
   if(OrderSymbol()==symb)
   {
   if(OrderType()<=1) return true;
   }
  }

}
  return false;
}

 Смысл функции "isexistmarket()" проверять существует ли открытый ордер(сделка) по инструменту, на котором работает робот. Функция верна? 

 

По сути  функция должна работать согласно тому, чего Вы от нее ожидаете (вернет true, если есть рыночный ордер на текущем символе, и false, если рыночного ордера нет). Но более оптимальный и удобочитаемый вариант функции таков:

bool IsExistMarketOrder()
{
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;
  
      if (OrderSymbol() != Symbol())
         continue;

      if (OrderType() == OP_BUY || OrderType() == OP_SELL)
         return true;

   }
  
   return false;
}

Что именно здесь более оптимально и удобно:

  1. При переборе количества ордеров лучше использовать обратный перебор, т. к. на каждой итерации прямого цикла будет вызываться функция OrdersTotal(). В такой же интерпретации OrdersTotal() будет вызвана только один раз, независимо от кол-ва итераций цикла.
  2. Нет огромного числа вложенных if, что более явно показывает структуру кода.
  3. Убирается необходимость использования глобальной переменной symb (экономия стековой памяти, которой всегда мало).
  4. Код будет выполняться одинаково даже в том случае, если в какой-то момент разработчики МТ решат изменить значения именованных констант OP_BUY и OP_SELL (в Вашем коде есть явная привязка к этим значениям).
 
Ihor Herasko:

По сути  функция должна работать согласно тому, чего Вы от нее ожидаете (вернет true, если есть рыночный ордер на текущем символе, и false, если рыночного ордера нет). Но более оптимальный и удобочитаемый вариант функции таков:

bool IsExistMarketOrder()
{
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;
  
      if (OrderSymbol() != Symbol())
         continue;

      if (OrderType() == OP_BUY || OrderType() == OP_SELL)
         return true;

   }
  
   return false;
}

Что именно здесь более оптимально и удобно:

  1. При переборе количества ордеров лучше использовать обратный перебор, т. к. на каждой итерации прямого цикла будет вызываться функция OrdersTotal(). В такой же интерпретации OrdersTotal будет вызвана только один раз, независимо от кол-ва итераций цикла.
  2. Нет огромного числа вложенных if, что более явно показывает структуру кода.
  3. Убирается необходимость использования глобальной переменной symb (экономия стековой памяти, которой всегда мало).
  4. Код будет выполняться одинаково даже в том случае, если в какой-то момент разработчики МТ решат изменить значения именованных констант OP_BUY и OP_SELL (в Вашем коде есть явная привязка к этим значениям).

"Разложили все по полочкам"! :) Спасибо за подробный ответ.
 

isexistmarket , серьезно? что за функция такая,  гейропейцы наверно придумали?)

 
Ihor Herasko:

По сути  функция должна работать согласно тому, чего Вы от нее ожидаете (вернет true, если есть рыночный ордер на текущем символе, и false, если рыночного ордера нет). Но более оптимальный и удобочитаемый вариант функции таков:

bool IsExistMarketOrder()
{
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;
  
      if (OrderSymbol() != Symbol())
         continue;

      if (OrderType() == OP_BUY || OrderType() == OP_SELL)
         return true;

   }
  
   return false;
}

Что именно здесь более оптимально и удобно:

  1. При переборе количества ордеров лучше использовать обратный перебор, т. к. на каждой итерации прямого цикла будет вызываться функция OrdersTotal(). В такой же интерпретации OrdersTotal будет вызвана только один раз, независимо от кол-ва итераций цикла.
  2. Нет огромного числа вложенных if, что более явно показывает структуру кода.
  3. Убирается необходимость использования глобальной переменной symb (экономия стековой памяти, которой всегда мало).
  4. Код будет выполняться одинаково даже в том случае, если в какой-то момент разработчики МТ решат изменить значения именованных констант OP_BUY и OP_SELL (в Вашем коде есть явная привязка к этим значениям).

Всё гуд только опять.

Если точно используется 2 и более вызовов одной и той же функции с одинаковым результатом(тип ордера,количество знаков после точки в сиволе...), то нужно создавать локальную переменную(перед цыклом).

 

bool IsExistMarketOrder()
{
int type=-1;

   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;
  
      if (OrderSymbol() != Symbol())
         continue;
      
      type=OrderType();
      if (type == OP_BUY || type == OP_SELL)
         return true;

   }
  
   return false;
}
 
Vyacheslav Kornev:

isexistmarket , серьезно? что за функция такая,  гейропейцы наверно придумали?)

Смысл этой темы не в проблеме с названием функции. Она может называться хоть "kldjslkfshdghfdjgh", главное, чтоб она делала свое дело корректно :)
 
eevviill15:

Всё гуд только опять.

Если точно используется 2 и более вызовов одной и той же функции с одинаковым результатом(тип ордера,количество знаков после точки в сиволе...), то нужно создавать локальную переменную(перед цыклом).

 

bool IsExistMarketOrder()
{
int type=-1;

   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;
  
      if (OrderSymbol() != Symbol())
         continue;
      
      type=OrderType();
      if (type == OP_BUY || type == OP_SELL)
         return true;

   }
  
   return false;
}
А не будет ли корректнее переменную "type" объявить как тип short, а не int?
 
eevviill15:

Всё гуд только опять.

Если точно используется 2 и более вызовов одной и той же функции с одинаковым результатом(тип ордера,количество знаков после точки в сиволе...), то нужно создавать локальную переменную(перед цыклом).

Не надо плодить лишние переменные. В первом варианте правильно было предложено:

...
if (OrderType() == OP_BUY || OrderType() == OP_SELL)
   return true;
...

Иначе через некоторое время сами запутаетесь в своих переменных. Например 'type' может означать тип чего угодно, а вот OrderType() только одна, хорошо документирована и более выразительна.

Просто считайте, что функции в MQL имеют нулевой оверхед и будет вам счастье.

Igor Knyazkov:
А не будет ли корректнее переменную "type" объявить как тип short, а не int?

Нет. 

 
Vasiliy Sokolov:

Не надо плодить лишние переменные. В первом варианте правильно было предложено:

...
if (OrderType() == OP_BUY || OrderType() == OP_SELL)
   return true;
...

Иначе через некоторое время сами запутаетесь в своих переменных. Например 'type' может означать тип чего угодно, а вот OrderType() только одна, хорошо документирована и более выразительна.

Просто считайте, что функции в MQL имеют нулевой оверхед и будет вам счастье.

...

OrderType() это функция. Вызов её ведёт к дополнительному использованию ресурсов.

Закрыть глаза и не видеть это??? Очень хорошее предложение.  

Пользуйтесь им, но не советуйте.
 
Igor Knyazkov:
А не будет ли корректнее переменную "type" объявить как тип short, а не int?

Это коректней менять на стороне разработчиков. 

Они говорят что всё ровно все типы целых чисел преобразовуются(или считаются) как int. 

 
Ihor Herasko:

По сути  функция должна работать согласно тому, чего Вы от нее ожидаете (вернет true, если есть рыночный ордер на текущем символе, и false, если рыночного ордера нет). Но более оптимальный и удобочитаемый вариант функции таков:

bool IsExistMarketOrder()
{
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;
  
      if (OrderSymbol() != Symbol())
         continue;

      if (OrderType() == OP_BUY || OrderType() == OP_SELL)
         return true;

   }
  
   return false;
}

Что именно здесь более оптимально и удобно:

  1. При переборе количества ордеров лучше использовать обратный перебор, т. к. на каждой итерации прямого цикла будет вызываться функция OrdersTotal(). В такой же интерпретации OrdersTotal() будет вызвана только один раз, независимо от кол-ва итераций цикла.
  2. Нет огромного числа вложенных if, что более явно показывает структуру кода.
  3. Убирается необходимость использования глобальной переменной symb (экономия стековой памяти, которой всегда мало).
  4. Код будет выполняться одинаково даже в том случае, если в какой-то момент разработчики МТ решат изменить значения именованных констант OP_BUY и OP_SELL (в Вашем коде есть явная привязка к этим значениям).
Не пинайте больно новичка, но -- что случится, если в это время изменится количество ордеров? И возможно-ли такое впринципе?