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

 
Vitaly Gorbunov:

То что вы определили где то количество нужных ордеров это хорошо, но в этом блоке вы снова бежите по всем ордерам и проверяете их! 

Разбейте код по нормальному сразу увидите! 

Можно конечно пересчитать снова. Но это сути не меняет. Оператор if() не выполняет "иначе". это только один случай, а были еще.
 
for(int h = OrdersTotal()-1; h >= 0; h--)
    {
     if(OrderSelect(h, SELECT_BY_POS))
      {
       if((cnt_OO >= 2))
        {
       if((OrderMagicNumber() == Magic)&&(OrderLots() <= Lots/Prikup - Dplus))
        {
         Nextstep  = NextStep;
         BaseNext  = OrderOpenPrice();
         LotsNext  = NormalizeDouble(OrderLots()*K,lotDigit);
         if(NewPB > 0)
          PBcloseON = true;
         Alert ("Pospedny Order NEXT  ",OrderTicket());
         Alert ("Otkritih orderov  ",cnt_OO);
//         break;
        }
       break;
       }
         LotsNext    = NormalizeDouble(Lots*Prikup,lotDigit); 
         Alert ("Otkritih orderov NEXT net ");
        Alert ("Otkritih orderov  ",cnt_OO);
         break;
     
        }}

Попробуй вот так!

В вот иначе (else) я в вашем коде не вижу!

Кидай другие случаи посмотрим что там не так :)

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

Получилось както так

if(cnt_OO>0) //Если нет ордеров то и не надо ни чего делать
{
  for(int h = OrdersTotal()-1; h >= 0; h--)
   {
    if(OrderSelect(h, SELECT_BY_POS))
     {
      if(cnt_OO==1)
         {
          //Если ордер один проверяем тот ли ордер (майджик и прочее) и что то там делаем
         }
      else
         {
          //Если ордеров больше чем 1 проверяем те ли ордера (майджик и прочее) и что то там делаем
         }
     }
   }
   
}
 

Можно и так. Но в учебнике написано что если не выполняется условие то происходит обработка команд после фигурной скобки закрывающей блок для обработки условия оператора if(). Этого не происходит.

Еще был глюк :

     if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots))
      {
       

Если я добавлял в первый оператор if еще одно условие  - то что следующее, то не работало

У меня два предположения

1. Дебильный тестер стратегий. Потому что эти ситуации возникали на стадии отладки программы,  надо быть полным чудаком чтобы это проверять на реальном счете. Да и на демо тоже, потому что сложно воспроизводить ситуацию рестарта. То что тестер дебильный говорит и то что порядок закрытия нескольких ордеров в окне MT4 часто не соответствует реальному если закрытие происходит в одно время. Это хорошо видно если пересчитать в программе последние ордера. Эта дебильность стоила мне недели работы по выяснению кто чудак.

Сама логика работы тестера даже на тиковой истории далека от реальной жизни. Для моего алгоритма это весьма критично.

2.Как предположение. Вопрос к особенно продвинутым гуру не только в MQL/MT4, но и системным специалистам.

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

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

Выход из положения я нашел  - в начале каждого блока ставлю проверку номера счета. Не уверен что везде где надо. 

 

Amon1953 вы посмотрели первый вариант который я исправил? Он работает? Именно так как написано в руководстве if() и работает за много лет его использования. Проблема в вашем коде вы не в том блоке поставили break.

if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots)) вырвана строка из кода надо смотреть что присваивается переменным.

По второму пункту - обе совы будут выполняться параллельно  поэтому сообщения от них будут в перемешку, для того чтобы сделать так как вы описываете нужно организовать семафоринг между копиями совы. А вот то что при смене счета что то происходит непонятное это очень интересно. Очень хотелось бы увидеть OnInit и OnDeinit. Скорее всего проблема там.

 
Vitaly Gorbunov:

Amon1953 вы посмотрели первый вариант который я исправил? Он работает? Именно так как написано в руководстве if() и работает за много лет его использования. Проблема в вашем коде вы не в том блоке поставили break.

if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots)) вырвана строка из кода надо смотреть что присваивается переменным.

По второму пункту - обе совы будут выполняться параллельно  поэтому сообщения от них будут в перемешку, для того чтобы сделать так как вы описываете нужно организовать семафоринг между копиями совы. А вот то что при смене счета что то происходит непонятное это очень интересно. Очень хотелось бы увидеть OnInit и OnDeinit. Скорее всего проблема там.

Я не проверял, потому что нужен выход из цикла по самому последнему ордеру (у нас он первый в списке) .

Я не опытный программист, и не совсем понимаю работу OnInit и OnDeinit. Поэтому у меня они не используются Но видимо они позволяют работать программе без прерывания посередине.

 Насчет семафора тоже непонятно, советники установлены в разных окнах и имеют разные мэйджики

 
Мой вам совет если вы начали программировать совсем недавно, то ещё раз изучите базовые основы программирования. Без обид, но с вами очень сложно общаться.
 
Vitaly Gorbunov:
Мой вам совет если вы начали программировать совсем недавно, то ещё раз изучите базовые основы программирования. Без обид, но с вами очень сложно общаться.
Спасибо. Это раздел для начинающих. Даже такое общение принесло мне пользу. Сложно делать и алгоритм советника и писать код программы (тем более язык программирования для меня совсем новый)
 
Amon1953:
Спасибо. Это раздел для начинающих. Даже такое общение принесло мне пользу. Сложно делать и алгоритм советника и писать код программы (тем более язык программирования для меня совсем новый)
Похоже что основу вам нужно подтянуть! Так как я не совсем понимаю из вашего кода какую логику вы хотите реализовать, попробуйте объяснить словами что вы хотите сделать. А я попробую объяснить где у вас ошибка. 
 
Vitaly Gorbunov:
Похоже что основу вам нужно подтянуть! Так как я не совсем понимаю из вашего кода какую логику вы хотите реализовать, попробуйте объяснить словами что вы хотите сделать. А я попробую объяснить где у вас ошибка. 

Я уже ранее объяснял что мне нужно. Попробую уточнить детали.

При перезапуске советника необходимо восстановить прежнее состояние, поскольку алгоритм представляет цепочку ордеров. Первый ордер - базовый, от него рассчитываются параметры следующих ордеров в цепочке. Например объем второго 50% от базового, третьего 75% и так далее. При перезапуске советника нам нужно знать объем базового ордера и последнего, потому что от последнего будет вычисляться объем следующего. Например : открытых ордеров 3.  А нам для расчета следующего(четвертого) ордера нужно определить объем  последнего открытого.

Если  ордеров один, то значит он базовый и нас в данном случае он не интересует - его обрабатывает другой блок.

Алгоритм простейший. Но он работает только с двумя операторами if()

 
Amon1953:

Я уже ранее объяснял что мне нужно. Попробую уточнить детали.

При перезапуске советника необходимо восстановить прежнее состояние, поскольку алгоритм представляет цепочку ордеров. Первый ордер - базовый, от него рассчитываются параметры следующих ордеров в цепочке. Например объем второго 50% от базового, третьего 75% и так далее. При перезапуске советника нам нужно знать объем базового ордера и последнего, потому что от последнего будет вычисляться объем следующего. Например : открытых ордеров 3.  А нам для расчета следующего(четвертого) ордера нужно определить объем  последнего открытого.

Если  ордеров один, то значит он базовый и нас в данном случае он не интересует - его обрабатывает другой блок.

Алгоритм простейший. Но он работает только с двумя операторами if()

Amon1953:

Я не проверял, потому что нужен выход из цикла по самому последнему ордеру (у нас он первый в списке) .

Я не опытный программист, и не совсем понимаю работу OnInit и OnDeinit. Поэтому у меня они не используются Но видимо они позволяют работать программе без прерывания посередине.

 Насчет семафора тоже непонятно, советники установлены в разных окнах и имеют разные мэйджики

Читайте документацию:

OnInit

Функция OnInit() является обработчиком события Init. Может иметь тип void или int, параметров не имеет:

void OnInit();

Событие Init генерируется сразу после загрузки эксперта или индикатора. Функция OnInit() используется для инициализации. Если OnInit() имеет возвращаемое значение типа int, то ненулевой код возврата означает неудачную инициализацию и генерирует событие Deinit с кодом причины деинициализации REASON_INITFAILED.

И ещё разберитесь с видимостью переменных.

События клиентского терминала - Программы MQL4 - Справочник MQL4
События клиентского терминала - Программы MQL4 - Справочник MQL4
  • docs.mql4.com
Сразу же после того, как клиентский терминал загрузит программу (эксперт или пользовательский индикатор) и запустит процесс инициализации глобальных переменных, будет послано событие Init, которое обрабатывается функцией OnInit(), если она есть. Это событие также генерируется после смены финансового инструмента и/или периода графика, после...
Причина обращения: