вопросы о советнике который должен имитировать ручную торговлю в конкурсах - страница 3

 
ilqar200 #:
Этот код тоже действует не так как мне нужно. Если EventSetTimer сделать с интервалом 5 секунд то этот код будет равносилен моему коду в котором есть цикл for и Sleep интервалом 5 секунд.В моем коде как и в вашем клик на ордерах ЗАВИСЕТЬ ОТ ИНТЕРВАЛА ВРЕМЕНИ который мы выставляем.Как я писал выше  это не решение. Нужно сделать клик на ордере ПО ФАКТУ ЗАКРЫТИЕ предыдущего окна Ордер.Какой бы интервал клика мы не выставили этого интервала может не хватить для клика на ордере или этот интервал будет большим и советник будет попросту ждать вместо того чтобы сделать другие действие. Понимаете нужно кликать по ФАКТУ ЗАКРЫТИЕ ОКНО а не по времени. Нужно запрограммировать такое действие как я выше писал : клик на 1-ом ордере ЖДАТЬ ЗАКРЫТИЕ ОКНО ПОСЛЕ ЗАКРЫТИЕ клик на 2-ом ордере ЖДАТЬ ЗАКРЫТИЕ ОКНО ПОСЛЕ ЗАКРЫТИЕ клик на 3-им ордере и т.д. Таймер помогает лучше справляться с отловом состояние нет связи . Здесь уже интервал времени не мешает отловке состояние нет связи.Ну например выставили 1 секунд и таймер ежесекундно будет следить за появлением сообшение нет связи и если это сообшение есть то  попробует заново отправить запрос в окне Ордер. Ну я не поверю что нету такого кода чтобы состание ожидание невозможно было бы запрограммировать в цикле.Вот как ждать в цикле ? вопрос трудный для меня.

В MQL нет такого события, как закрытие заданного окна. В C++ еще есть с оговорками (например, если это собственное окно), но даже там не получится в чистом виде получить событие закрытия окна другого приложения. В любом случае придется отслеживать: либо создавать поток с WaitForSingleObject(), либо организуя тот же самый таймер.

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

 

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

int OnInit()
  {

int a;int i;
for (i=1;i<=OrdersTotal();i++)
{orderclick(i);Sleep(3000);
do {openedorderwindow=FindWindowW("#32770",NULL);} while (openedorderwindow!=0);
do {a=-1;a=a+1;}while (a!=openedorderwindow);
};
   

   return(INIT_SUCCEEDED);
  }
Главное то что с помощью этого кода советник ждет когда закроется окно. Если окно закрывается далее кликает по следующему ордеру и ждет опять закрытие. Вот уже после открытие окна Ордер можно модифицировать ордер.Хорошая особенность ожидание закрытие окно Ордер в том что можно выяснить причину НЕ закрытие окно Ордер после модификации прямо в этом окне т.е если закрывается значить модифицировано успешно а если нет то ищем причину в окне и пытаемся исправить ситуацию. Остается мне запрограммировать эти и другие действие и советник будет готов.Спасибо за помощь. Если будут вопросы выложу здесь.
 
ilqar200 #:

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

Такой подход еще более-менее хорош в случае, если это советник (которым бы нежелательно пользоваться с Ваших же слов). А вот в индикаторе подобное вообще не пройдет, т. к. терминал зависнет.

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

И не забывайте еще об одном моменте, который не учтен как в моем, так и в Вашем коде - изменение списка во время отображения окна "Ордер". 

 
Ihor Herasko #:

Такой подход еще более-менее хорош в случае, если это советник (которым бы нежелательно пользоваться с Ваших же слов). А вот в индикаторе подобное вообще не пройдет, т. к. терминал зависнет.

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

И не забывайте еще об одном моменте, который не учтен как в моем, так и в Вашем коде - изменение списка во время отображения окна "Ордер". 

Честно говоря не знаю чем отличается программирование индикатора от программирование советника. Но по крайной мере код выше работает в моем советнике.По поводу таймера. Если я буду использовать таймер он "вернется" обратно в цикл или как можно исползовать таймер в этом случае т.е с циклом ? Вед я вызываю его из цикла. Да вы правы нужно учесть и изменение списка а конкретно сдвиг ордеров .
 

ilqar200 #:
Честно говоря не знаю чем отличается программирование индикатора от программирование советника.

В контексте обсуждаемого вопроса основная разница в следующем:

  1. Индикатор работает в потоке терминала. То есть пока индикатор исполняется (по событию Init, Calculate, ChartEvent, Timer, Deinit) весь терминал простаивает (в МТ5 - только текущий график), ожидая окончания обработки события индикатора. Таким образом, если индикатор зациклился, то весь терминал повиснет. Если ожидать открытия или закрытия любого окна терминала из индикатора посредством Sleep, то такое ожидание будет вечным. Это классический dead lock: терминал ждет окончания работы индикатора, а индикатор, в свою очередь, ждет каких-то действий от терминала.
  2. Советник работает в своем собственном потоке. Если советник зациклится, то это почти никак не отразится на работе терминала. В советнике решение, основанное на Sleep, еще простительно.

По поводу таймера. Если я буду использовать таймер он "вернется" обратно в цикл или как можно исползовать таймер в этом случае т.е с циклом ? Вед я вызываю его из цикла.

Решение, основанное на таймере, просто показывает тот перерыв, который действует в цикле. Ведь каждая итерация цикла прерывается на ожидание открытия или закрытия окна "Ордер". В такой момент может много, чего случится. По большому счету цикл нужно тогда начинать сначала. И чтобы он когда-нибудь закончился, нужно запоминать те ордера, действия с которыми уже произведены, пропуская такие ордера на очередной итерации. То же самое с таймером. Ничего по сути не меняется. Меняется лишь представление цикла. В моем варианте показан тот же самый цикл, но только разбитый на события, которые по коду незаметны в случае с традиционным циклом

Да вы правы нужно учесть и изменение списка а конкретно сдвиг ордеров .

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

 
Ihor Herasko #:

В контексте обсуждаемого вопроса основная разница в следующем:

  1. Индикатор работает в потоке терминала. То есть пока индикатор исполняется (по событию Init, Calculate, ChartEvent, Timer, Deinit) весь терминал простаивает (в МТ5 - только текущий график), ожидая окончания обработки события индикатора. Таким образом, если индикатор зациклился, то весь терминал повиснет. Если ожидать открытия или закрытия любого окна терминала из индикатора посредством Sleep, то такое ожидание будет вечным. Это классический dead lock: терминал ждет окончания работы индикатора, а индикатор, в свою очередь, ждет каких-то действий от терминала.
  2. Советник работает в своем собственном потоке. Если советник зациклится, то это почти никак не отразится на работе терминала. В советнике решение, основанное на Sleep, еще простительно.

Решение, основанное на таймере, просто показывает тот перерыв, который действует в цикле. Ведь каждая итерация цикла прерывается на ожидание открытия или закрытия окна "Ордер". В такой момент может много, чего случится. По большому счету цикл нужно тогда начинать сначала. И чтобы он когда-нибудь закончился, нужно запоминать те ордера, действия с которыми уже произведены, пропуская такие ордера на очередной итерации. То же самое с таймером. Ничего по сути не меняется. Меняется лишь представление цикла. В моем варианте показан тот же самый цикл, но только разбитый на события, которые по коду незаметны в случае с традиционным циклом

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

Оператор Sleep в индикаторе не исполняется. 

 
Ihor Herasko #:

В контексте обсуждаемого вопроса основная разница в следующем:

  1. Индикатор работает в потоке терминала. То есть пока индикатор исполняется (по событию Init, Calculate, ChartEvent, Timer, Deinit) весь терминал простаивает (в МТ5 - только текущий график), ожидая окончания обработки события индикатора. Таким образом, если индикатор зациклился, то весь терминал повиснет. Если ожидать открытия или закрытия любого окна терминала из индикатора посредством Sleep, то такое ожидание будет вечным. Это классический dead lock: терминал ждет окончания работы индикатора, а индикатор, в свою очередь, ждет каких-то действий от терминала.
  2. Советник работает в своем собственном потоке. Если советник зациклится, то это почти никак не отразится на работе терминала. В советнике решение, основанное на Sleep, еще простительно.

Решение, основанное на таймере, просто показывает тот перерыв, который действует в цикле. Ведь каждая итерация цикла прерывается на ожидание открытия или закрытия окна "Ордер". В такой момент может много, чего случится. По большому счету цикл нужно тогда начинать сначала. И чтобы он когда-нибудь закончился, нужно запоминать те ордера, действия с которыми уже произведены, пропуская такие ордера на очередной итерации. То же самое с таймером. Ничего по сути не меняется. Меняется лишь представление цикла. В моем варианте показан тот же самый цикл, но только разбитый на события, которые по коду незаметны в случае с традиционным циклом

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

Кроме моего варианта кода я не знаю как можно ждать закрытие окно ордер чтобы потом можно было кликнут на следующем. Можете показать ваш вариант кода в котором используется таймер и в котором советник будет ждать закрытие окно ордер для открытие следующего ?
 
ilqar200 #:
Кроме моего варианта кода я не знаю как можно ждать закрытие окно ордер чтобы потом можно было кликнут на следующем. Можете показать ваш вариант кода в котором используется таймер и в котором советник будет ждать закрытие окно ордер для открытие следующего ?

Логика уже была мною представлена. Да, это не "боевой" вариант, еще нужно будет допиливать. Но сама архитектура именно такая.

вопросы о советнике который должен имитировать ручную торговлю в конкурсах
вопросы о советнике который должен имитировать ручную торговлю в конкурсах
  • 2021.12.16
  • www.mql5.com
Здравствуйте уважаемые форумчане. Я искал на форуме сообщении на эту тему но конкретные ответы на мои вопросы не нашел...
 
Ihor Herasko #:

Логика уже была мною представлена. Да, это не "боевой" вариант, еще нужно будет допиливать. Но сама архитектура именно такая.

Скажу честно помоему sleep на 3 секунды  не испортить работу советника потому что я буду использовать модификацию ордеров из редко. В основном у всех моих ордеров при открытии будут выставлены заранее вычисленные стоп-лоссы и тейкпрофиты. Модифицировать их не будет нужды. Из редко какие-то ордера нужно будет модифицировать.Но я не верю  что пауза на 3 секунд в момент модификации может испортить работу советника.Дальше буду дописывать советник по алгоритму. Спасибо за помощь. Если будут вопросы то обязательно отпишус здесь.
 

Продолжаю дописывать этот советник. Возник трудный момент для меня.Опишу ситуации:

1. Отсутствует связь с интернетом.Запускаю терминал С прикрепленным советником .Не срабатывает события oninit() и соответственно таймер не активируеться .

2. Отсутствует связь с интернетом . Запускаю терминал БЕЗ прикрепленного  советника. После запуска терминала загружаю советник.Срабатывает события oninit() и соответственно таймер активируеться.

 Итак вопросы: 

1. Почему в 1-ой ситуации не сработало события oninit() с дальнейшей активации таймера а во 2-ой ситуации сработало ? 

2.Как сделать так чтобы при запуске терминала С прикрепленном советником при отсутствии связи с интернетом всегда сработало события oninit() с дальнейшей активации таймера ?