Неизбежная 4108 - страница 3

 
Alexey Viktorov:

Если ордер выбирается из списка открытых по индексу, у него никогда не будет OrderCloseTime() > 0 именно по той причине, что он ещё в списке открытых, действующих.

Эта проверка обязательна если ордер выбирать по тикету из переменной или массива.


Да, и потому приходится каждый ордер выбирать дважды: первый раз по индексу, только ради того, чтоб получить список тикетов.

И только потом обрабатывать каждый полученный тикет в отдельности.

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

Но даже в момент обновления на только OrderCloseTime(), но и все остальное уже устарело на время пинга.

Такое ощущение, что тестер стратегий настолько идеален, что имитирует даже запаздывание клиента относительно сервера.

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

 
Dmitriy Susloparov:


Да, и потому приходится каждый ордер выбирать дважды: первый раз по индексу, только ради того, чтоб получить список тикетов.

И только потом обрабатывать каждый полученный тикет в отдельности.

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

Но даже в момент обновления на только OrderCloseTime(), но и все остальное уже устарело на время пинга.

Такое ощущение, что тестер стратегий настолько идеален, что имитирует даже запаздывание клиента относительно сервера.

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

Зачем дважды? Для обработки ордера достаточно того что он выбран, а как он выбран никакой роли не играет. Но если на счёте работают несколько советников которые открывают много ордеров, то перебирать весь список своих и чужих слишком затратно. В этом случае может помочь хранение тикетов в массиве который перезаполняется только в случае открытия или закрытия ордера, а на каждом тике перебираются только свои из списка в готовом массиве. В этом случае OrderSelect() идёт по тикету и выбирается независимо в каком списке он находится, в действующих или в истории. В этом случае вероятность того что ордер был уже закрыт, но всё ещё находится в массиве тикетов, возрастает и в этом случае обязательно надо делать проверку на OrderCloseTime() > 0 или == 0. Кому как больше нравится.

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

 
Alexey Viktorov:

Зачем дважды? Для обработки ордера достаточно того что он выбран, а как он выбран никакой роли не играет. Но если на счёте работают несколько советников которые открывают много ордеров, то перебирать весь список своих и чужих слишком затратно. 

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

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

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

Так то да, модифай желательно вытащить поближе к началу кода, но все равно, прежде надо знать тикет.

Быстрее его взять из загашника, но надежнее из селекта но индексу.

Тут писали, что селект работает мгновенно, не может быть, чтоб если перед модифай перебрать 5 ордеров, оно будет сравнимо с пингом до сервера.

 
Dmitriy Susloparov:

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

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

Так то да, модифай желательно вытащить поближе к началу кода, но все равно, прежде надо знать тикет.

Быстрее его взять из загашника, но надежнее из селекта но индексу.

Тут писали, что селект работает мгновенно, не может быть, чтоб если перед модифай перебрать 5 ордеров, оно будет сравнимо с пингом до сервера.

Так ведь замерить, даже в микросекундах, никто не запрещает.
GetMicrosecondCount - Общие функции - Справочник MQL4
GetMicrosecondCount - Общие функции - Справочник MQL4
  • docs.mql4.com
GetMicrosecondCount - Общие функции - Справочник MQL4
 
Dmitriy Susloparov:


Такое ощущение, что тестер стратегий настолько идеален, что имитирует даже запаздывание клиента относительно сервера.

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


Если такую ошибку получаете в тестере, то диагноз однозначный: ошибка в программе. Появление же такой ошибки только при работе в онлайн - нормальная ситуация. Главное, чтобы советник обрабатывал эту ошибку и не пытался отправлять повторный запрос по этому же ордеру. Тогда это тоже недоработка.
 

Я специально проверял: тестер дает 4108 именно на тот тикет, который в клиенте после данного тика числился как открытый, но в тот же тик был закрыт по sl.

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

Что дадут замеры даже в микросекундах? Если даже клиент выдаст модифай мгновенно после тика, пинг до сервера как был, так и останется.

Раньше у меня такой ошибки никогда не было, а узнал я о ней с тех пор, как начал эксперименты по замене закрытия по рынку на закрытие по sl.

Как только я начал подтягивать sl настолько близко, насколько позволяло отсутствие ошибки 130, начала проскакивать 4108.

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

Но это "чуть подальше" - это сколько-то пунктов, то есть, какие-то деньги.

 
Dmitriy Susloparov:

Получается, что полностью избежать ошибки 4108 невозможно?

Смотрите:

Что такое OrderSelect() ? Это сперва запрос к серверу, потом ответ от сервера.

То есть, до тех пор, пока будет получено true, пройдет какое-то время.

Потом мы шлем OrderModify(). И это тоже время, пока пакет дойдут до сервера.

Так вот, до момента, пока сервер получит OrderModify(),  цена прыгнет, сработает sl или tp, и ордер закроется.

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

В итоге, даже если программист сперва проверил, что данный тикет существует и открыт, нет никакой

гарантии, что советник не выплюнет 4108 !


Поправьте меня, если я что-то неправильно понимаю?


Да. Ну и что с того?
 
Dmitriy Susloparov:


Да, и потому приходится каждый ордер выбирать дважды: первый раз по индексу, только ради того, чтоб получить список тикетов.

И только потом обрабатывать каждый полученный тикет в отдельности.

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

Но даже в момент обновления на только OrderCloseTime(), но и все остальное уже устарело на время пинга.

Такое ощущение, что тестер стратегий настолько идеален, что имитирует даже запаздывание клиента относительно сервера.

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


Нет же. Если описанная в начальном посте проблема может быть, то она может проявиться и при выделении по индексу - между выделением и началом модификации ордер закрывается по стоплоссу и будет ошибка.

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

 
Dmitry Fedoseev:

Да. Ну и что с того?


Пропустит ли такую ошибку модератор?

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

ради избавления от этой ошибки.

 
Dmitriy Susloparov:


Пропустит ли такую ошибку модератор?

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

ради избавления от этой ошибки.


Если выделяете по индексу и тут же модифицируете, тот тут ничего не сделать. Если тикет храните, то после выделения по тикету проверяйте время закрытия, здесь тоже ничего не сделать. Поэтому, модератор наверно должен пропустить. Если, конечно, не по какой-то другой причине возникает эта ошибка.  
Причина обращения: