Не правильно выполняется условие if

 

Как-то раз решил перенести свой советник с МТ4 на МТ5. И все было по началу хорошо, пока не обнаружил странное поведение в коде. При помощи записи состояния всех переменных стратегий в лог я выяснил, что некоторые условия срабатывали тогда, когда не надо. И наоборот, некоторые условия не срабатывали.

double a = 5;
double b = 10;

if (a > b) {

}

Самый простой пример.  В любом языке программирования такое условие не выполнится. Но в MQL5 подобные условия иногда выполняются. И от чего это зависит — не понятно.

Тогда мне помогло лишь одно: я переехал с терминала МТ5 от брокера Альпари (он не хотел обновляться до свежей версии) на оригинальный МТ5 последней (на тот момент) версии. И это помогло, подобные баги исчезли. Менять что либо в коде было бесполезно.

И вот недавно я решился сделать заказ для знакомого. По началу все шло хорошо, но вот захотелось добавить асинхронное открытие и закрытие сделок. Казалось бы, что может быть проще?

Иногда сделки не открываются с первого раза. Да и не всегда закрываются. Значит, нужно добавить повторные попытки открыть/закрыть позицию. Но код, который работает с точки зрения здравого смысла, не работает в MQL5:

pos_info.error++;
const int close_error = pos_info.error;
Print("-close-error ", symbol, " magic ", m_magic, " ticket ", ticket, " uid ", unique_id, " num ", close_error, " attempts ", m_open_attempts);
if (close_error > m_open_attempts) {
        Print("-1-close-error; errors ", close_error);
        Print("-1-close-error; attempts ", m_open_attempts);
}
if (close_error == m_open_attempts) {
        Print("-2-close-error; errors ", close_error);
        Print("-2-close-error; attempts ", m_open_attempts);
}
if (close_error != m_open_attempts) {
        Print("-3-close-error; errors ", close_error);
        Print("-3-close-error; attempts ", m_open_attempts);
}
if (close_error < m_open_attempts) {
        Print("-4-close-error; errors ", close_error);
        Print("-4-close-error; attempts ", m_open_attempts);
}
if (close_error > m_open_attempts) {
        pos_info.state = TradePositionState::POSITION_CLOSE_ERROR;
        on_close_position_error(m_magic);
        on_close_position(m_magic, symbol, pos_info.type, result);
        remove_position(symbol, unique_id);
        Print("-4-remove ", symbol, " magic ", m_magic, " ticket ", ticket, " uid ", unique_id);
        break;
}

Переменная close_error содержит 1, так как ошибка при закрытии позиции возникла 1 раз. Это видно в терминале в соответствующем сообщении. Переменная m_open_attempts содержит 5. Внимание, вопрос: какие условия сработают в этом коде?

Правильный ответ

1. Условия:

if (close_error > m_open_attempts) {
        Print("-1-close-error; errors ", close_error);
        Print("-1-close-error; attempts ", m_open_attempts);
        break;
}
if (close_error == m_open_attempts) {
        Print("-2-close-error; errors ", close_error);
        Print("-2-close-error; attempts ", m_open_attempts);
}

Не сработают, что логично.

2.  Условия:

if (close_error != m_open_attempts) {
        Print("-3-close-error; errors ", close_error);
        Print("-3-close-error; attempts ", m_open_attempts);
}
if (close_error < m_open_attempts) {
        Print("-4-close-error; errors ", close_error);
        Print("-4-close-error; attempts ", m_open_attempts);
}

Сработают, что тоже логично.

3.  Условие:

if (close_error > m_open_attempts) {
        pos_info.state = TradePositionState::POSITION_CLOSE_ERROR;
        on_close_position_error(m_magic);
        on_close_position(m_magic, symbol, pos_info.type, result);
        remove_position(symbol, unique_id);
        Print("-4-remove ", symbol, " magic ", m_magic, " ticket ", ticket, " uid ", unique_id);
        break;
}

Сработает! При этом ранее 

if (close_error > m_open_attempts)

Не сработало!

Сами условия находятся в switch.

Отключение оптимизации не помогает.

 
Очень бы хотелось, чтобы такие проблемы были всего лишь из-за какой-нибудь утечки памяти, а не глюком компилятора или терминала. Потому что иначе выходит, что есть некие "правила", по которым надо писать код, например не использовать break в условии if внутри swith case конструкции (еще не проверил, просто предполагаю). 

Из-за таких багов нельзя быть уверенным, что советник отрабатывает логику правильно, а главное эти баги очень трудно отловить, потому что просто рушится логика выполнения кода. Никогда ведь не подумаешь, что if (1 > 5) может сработать.

В старой версии МТ5 еще могли пропускаться некоторые элементы массива в цикле, что тоже не поддавалось никакому здравому смыслу, а списать на утечку памяти было нельзя, т.к. массив не менял свой размер в процессе выполнения.
 
Yaroslav Barabanov:

Как-то раз решил перенести свой советник с МТ4 на МТ5. И все было по началу хорошо, пока не обнаружил странное поведение в коде. При помощи записи состояния всех переменных стратегий в лог я выяснил, что некоторые условия срабатывали тогда, когда не надо. И наоборот, некоторые условия не срабатывали.

Самый простой пример.  В любом языке программирования такое условие не выполнится. Но в MQL5 подобные условия иногда выполняются. И от чего это зависит — не понятно.

Тогда мне помогло лишь одно: я переехал с терминала МТ5 от брокера Альпари (он не хотел обновляться до свежей версии) на оригинальный МТ5 последней (на тот момент) версии. И это помогло, подобные баги исчезли. Менять что либо в коде было бесполезно.

И вот недавно я решился сделать заказ для знакомого. По началу все шло хорошо, но вот захотелось добавить асинхронное открытие и закрытие сделок. Казалось бы, что может быть проще?

Иногда сделки не открываются с первого раза. Да и не всегда закрываются. Значит, нужно добавить повторные попытки открыть/закрыть позицию. Но код, который работает с точки зрения здравого смысла, не работает в MQL5:

Переменная close_error содержит 1, так как ошибка при закрытии позиции возникла 1 раз. Это видно в терминале в соответствующем сообщении. Переменная m_open_attempts содержит 5. Внимание, вопрос: какие условия сработают в этом коде?

Правильный ответ

1. Условия:

Не сработают, что логично.

2.  Условия:

Сработают, что тоже логично.

3.  Условие:

Сработает! При этом ранее 

Не сработало!

Сами условия находятся в switch.

Отключение оптимизации не помогает.

С такой подачей материала, я думаю, вам придётся ……… это… Как заниматься любовью без девушки.

Откуда какие значения переменных берутся, где они могут потеряться… И всё остальное покрыто мраком.

Удачи вам в этом неблагородном деле…

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

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

Так много  текста и ни одного рабочего примера, где воспроизводится проблема.

А без примера вам никто не поверит.

 
Тем более, что "Сами условия находятся в switch." - а там может играть эффект "проваливания" в следующий case.