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

 
Roman Sharanov:
Подскажите верно ли реализована функция закрытия всех ордеров открытых советником по символу?

Сама архитектура - верная. Ошибки в отсутствии проверок и использовании некоторых функций:

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

         if(OrderSymbol() !=Symbol() || OrderMagicNumber() != Magic)
            continue;
         
         if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage, clrWhite))
            return false;
   }

   return true;
}

  1. Первая итерация в Вашем случае будет провальной - ордер с индексом OrdersTotal() не существует.
  2. Нет проверки результата функции OrderSelect.
  3. Нет проверки результата функции OrderClose. Если закрытие ордера прошло неудачно, то нельзя оставаться в этой же функции, т. к. нужно определиться, почему закрытие прошло неудачно. Для этого - выход из функции с результатом false и уже за ее пределами решать, что делать дальше.
  4. Нельзя применять одну и ту же цену закрытия для всех ордеров. Во-первых, ордера могут быть разного типа, а, во-вторых, за время выполнения предыдущих приказов (на закрытие) цена, скорее всего, изменилась. Чтобы не гадать, какую цену использовать, можно воспользоваться особенностью МТ4: у рыночного ордера до момент его закрытия значение OrderClosePrice() - это цена Bid или Ask в зависимости от типа ордера.
 
Ihor Herasko:

Сама архитектура - верная. Ошибки в отсутствии проверок и использовании некоторых функций:

  1. Первая итерация в Вашем случае будет провальной - ордер с индексом OrdersTotal() не существует.
  2. Нет проверки результата функции OrderSelect.
  3. Нет проверки результата функции OrderClose. Если закрытие ордера прошло неудачно, то нельзя оставаться в этой же функции, т. к. нужно определиться, почему закрытие прошло неудачно. Для этого - выход из функции с результатом false и уже за ее пределами решать, что делать дальше.
  4. Нельзя применять одну и ту же цену закрытия для всех ордеров. Во-первых, ордера могут быть разного типа, а, во-вторых, за время выполнения предыдущих приказов (на закрытие) цена, скорее всего, изменилась. Чтобы не гадать, какую цену использовать, можно воспользоваться особенностью МТ4: у рыночного ордера до момент его закрытия значение OrderClosePrice() - это цена Bid или Ask в зависимости от типа ордера.

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

 

Из справки по OrderSelect "При последовательном выборе ордеров с помощью параметра SELECT_BY_POS информация отдаётся в том порядке, в котором она поступила с торгового сервера. Никакая сортировка полученного списка ордеров не гарантируется".

Если считать, что эта фраза зря вставлена в справку, то все нормально. Если же думать, что не зря, то не стоит во время пробега циклом по списку ордеров менять этот список. Как будут упорядочены ордера после удаления одного их них на сервере и прихода нового, актуального списка с меньшим OrdersTotal, неизвестно. Надежнее, не удаляя, пробежать по одному и тому же неизменному экземпляру списка и собрать (в массив) все номера тикетов сделок, подлежащих удалению. Затем забыть об этом списке и удалять сделки, выбирая их по тикетам.

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

 
Vladimir:

Из справки по OrderSelect "При последовательном выборе ордеров с помощью параметра SELECT_BY_POS информация отдаётся в том порядке, в котором она поступила с торгового сервера. Никакая сортировка полученного списка ордеров не гарантируется".

Если считать, что эта фраза зря вставлена в справку, то все нормально. Если же думать, что не зря, то не стоит во время пробега циклом по списку ордеров менять этот список. Как будут упорядочены ордера после удаления одного их них на сервере и прихода нового, актуального списка с меньшим OrdersTotal, неизвестно. Надежнее, не удаляя, пробежать по одному и тому же неизменному экземпляру списка и собрать (в массив) все номера тикетов сделок, подлежащих удалению. Затем забыть об этом списке и удалять сделки, выбирая их по тикетам.

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

Такая "америка" открыта уже лет как триста :)

 
Artyom Trishkin:

Такая "америка" открыта уже лет как триста :)

Не думаю, что люди, задающие здесь вопросы от имени новичков, уже ее открыли сами. Поэтому и пишу. Не для модераторов, а для задающих вопросы. Посмотрите, как называется ветка.

P.S. Посмотрел, откуда такой интерес. Оказывается из ветки https://www.mql5.com/ru/forum/215783/page8 "Организация цикла перебора ордеров". Как выясняется, в октябре 2017 эти триста лет еще не закончились, все еще есть новизна.

Организация цикла перебора ордеров
Организация цикла перебора ордеров
  • 2017.09.16
  • www.mql5.com
MQL4 и MetaTrader 4: Организация цикла перебора ордеров
 
Vladimir:

Не думаю, что люди, задающие здесь вопросы от имени новичков, уже ее открыли сами. Поэтому и пишу. Не для модераторов, а для задающих вопросы. Посмотрите, как называется ветка.

P.S. Посмотрел, откуда такой интерес. Оказывается из ветки https://www.mql5.com/ru/forum/215783/page8 "Организация цикла перебора ордеров". Как выясняется, в октябре 2017 эти триста лет еще не закончились, все еще есть новизна.

Опять не угадали :) Триста лет начались ещё на mql4.com - было время, когда там активно это обсуждалось. И даже были как раз те моменты, которые описаны вами в "Сейчас работает, а выйдет новый билд - "мы предупреждали". Только без предупреждений, и так раз несколько - то зависит, то не зависит от сортировки...

И, да, есть специальная для таких ответов тема:

Особенности языка mql4, тонкости и приёмы работы
Особенности языка mql4, тонкости и приёмы работы
  • 2017.02.24
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql4, примеры решения тех, или иных задач...
 
Vladimir:

Из справки по OrderSelect "При последовательном выборе ордеров с помощью параметра SELECT_BY_POS информация отдаётся в том порядке, в котором она поступила с торгового сервера. Никакая сортировка полученного списка ордеров не гарантируется".

Если считать, что эта фраза зря вставлена в справку, то все нормально. Если же думать, что не зря, то не стоит во время пробега циклом по списку ордеров менять этот список. Как будут упорядочены ордера после удаления одного их них на сервере и прихода нового, актуального списка с меньшим OrdersTotal, неизвестно. Надежнее, не удаляя, пробежать по одному и тому же неизменному экземпляру списка и собрать (в массив) все номера тикетов сделок, подлежащих удалению. Затем забыть об этом списке и удалять сделки, выбирая их по тикетам.

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

По хорошему (если учитывать, что на счете может параллельно работать несколько экспертов + трейдер), вообще нельзя производить торговые операции в цикле. Взяли нужный ордер, провели операцию, выполняем весь OnTick() заново (не обязательно с приходом нового тика). И так до тех пор, пока не будут выполнены все необходимые операции.

Таким образом, формирование массива для удаления ордеров эквивалентно удалению ордеров в цикле. 

 

Есть кнопка “Stop”, как изменить её текст на “Start”, после нажатия?

bool stop;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//Closed at Profit
   ObjectCreate(0,"Stop",OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,"Stop",OBJPROP_XDISTANCE,10);
   ObjectSetInteger(0,"Stop",OBJPROP_YDISTANCE,105);
   ObjectSetInteger(0,"Stop",OBJPROP_XSIZE,100);
   ObjectSetInteger(0,"Stop",OBJPROP_YSIZE,25);

   ObjectSetString(0,"Stop",OBJPROP_TEXT,"Stop");

   ObjectSetInteger(0,"Stop",OBJPROP_COLOR,White);
   ObjectSetInteger(0,"Stop",OBJPROP_BGCOLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_COLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_TYPE,BORDER_FLAT);
   ObjectSetInteger(0,"Stop",OBJPROP_HIDDEN,true);
   ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
   ObjectSetInteger(0,"Stop",OBJPROP_FONTSIZE,12);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
if(sparam=="Stop")
     {
      ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
      CloseAtProfit();
      stop=true;
     }
     }
 
lil_lil:  Есть кнопка “Stop”, как изменить её текст на “Start”, после нажатия?

Посмотрите мой пример эксперта

Файлы:
ToFile.mq4  11 kb
 
STARIJ:

Посмотрите мой пример эксперта

Спасибо, то что нужно

Может вам пригодится знать, в отсутствии позиций ошибка--- ToFile EURUSD,H1: zero divide in 'ToFile.mq4' (62,39)

/*62*/  Строка=DoubleToStr(AccountEquity()/AccountMargin()*100,2)+"%"; // Уровень=Средства/Залог
В тестере не изменяется текст, что, нет такой возможности?
Причина обращения: