Косяки? Глюки? Как такое возможно? - страница 2

 
Nextor:

@Vladimir Karputov:

Версии:

@Ilyas:

Эксперт прикрепил архивом.

...


Спасибо за предоставленные данные

Некорректно учитывается область жизни переменных, при их сохранении в отладочный блок (DEBUG_INFO)

В теле функции имеется несколько циклов, все по 'i'
Из-за ошибки в компиляторе, у всех 'i' время жизни по коду одинаковое - всё тело функции
Берётся первая из DEBUG_INFO и она не для первого цикла в предоставленном коде.
Т.к. до этой первой 'i' выполнение ещё не дошло, она не инициализирована (в ней мусор со стека).

Данная ошибка не связана с реальным исполнением кода, ошибка проявляется только в вычислении выражений WatchList отладчика - исправляю


UPD: данная ошибка касается только оператора FOR, для отладчика, время жизни объявленных в заголовке FOR локальных переменных была область видимости, в которой находился FOR

 

Ilyas:


Данная ошибка не связана с реальным исполнением кода, ошибка проявляется только в вычислении выражений WatchList отладчика - исправляю

Нет, вы не правы.


Если бы ошибка была только с вычислением выражений в WatchList, то Эксперт работал бы одинаково как на реальных данных, так и на исторических.
Однако, на исторических данных он работает верно, на реальных - не верно (можете запустить, проверить)

А также, вот вам конкретный пример:


Опять, с той же i. Если проблема только в вычислении выражений для окошка  WatchList  (правое, нижнее, с переменными), то даже при i = 85132988, отладчик бы все равно заходил в цикл (так как на самом деле i был бы 0). Но отладчик в цикл не заходит, значит, проблема не только в вычислении выражений WatchList отладчика, и данная ошибка связана с реальным исполнением кода (и это подтверждает разная работа эксперта на реальных и исторических данных, тем более, что все переменные выводятся на экран). Также,я пробовал просто добавить эксперт к графику, в обычном режиме (не в отладке) на ночь - и работа была совсем не такой, как за эту же ночь, но при отладке на исторических данных.


Значит, ваша ошибка глубже.

И как вы объясните случай ниже?

Ниже функция, добавляет позицию к себе в массив. Если на ней встать отладчиком при добавлении первой позиции, тип позиции (11 - Селл) добавиться в переменную PositionType:

И следующей функции, которая обновляет информацию по всем переменным, мы верно попадаем в условие по Селл, потому что pm_PositionsArray[0].PositionType == "11", и посчитаем прибыль со всех позиций Селл:

Но если не вставать изначально отладчиком в функцию добавления позиции к себе в массив (чего для позиции бай я не делал), то в следующей функции, которая обновляет информацию по позициям, мы увидим pm_PositionsArray[0].PositionType = NULL, а должно быть "00" (в терминале открыты Бай и Селл по GBPUSD, видно на последнем скриншоте)

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


Позиция с тикетом 85130320 в терминале есть, она открыта, по ней есть прибыль, но в эксперте отображаются везде нули.

Получается, проблема в самом MQL

 
Nextor:

Нет, вы не правы.


Если бы ошибка была только с вычислением выражений в WatchList, то Эксперт работал бы одинаково как на реальных данных, так и на исторических.
Однако, на исторических данных он работает верно, на реальных - не верно (можете запустить, проверить)

Конечно же я проверил, то что работает в тестере, можно назвать "фичей" тестера.

Вам нужно более детально разобраться в Deal/Order/Ticket, почитать про OrderSend/OnTradeTransaction

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


В текущей версии компилятора, используйте следующий "трюк", чтобы ограничить область видимости переменных объявленных в FOR, это поможет разобраться в коде и понять что не так:

       // ограничим область видиости FOR, чтобы обойти ошибку области видимости переменных
      {
      
      for (int i = pm_QtyPos - 1; i >= 0; i--)
        {
          if (PositionSelectByTicket(pm_PositionsArray[i].PositionTicket)==true){
            pm_PositionsArray[i].PositionProfit=PositionGetDouble(POSITION_PROFIT);
            pm_PositionsArray[i].PositionSwap = PositionGetDouble(POSITION_SWAP);
            }
        }
        
      }
* вокруг оператора FOR добавлены {  }
 
Ilyas:

Конечно же я проверил, то что работает в тестере, можно назвать недоработкой тестера, "фичей".

Вам нужно более детально разобраться в Deal/Order/Ticket, почитать про OrderSend/OnTradeTransaction

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


В текущей версии компилятора, используйте следующий "трюк", чтобы ограничить область видимости переменных объявленных в FOR, это поможет разобраться в коде и понять что не так:

* вокруг оператора FOR добавлены {  }

Спасибо, скобки добавлю, посмотрю.

Что за "фича" такая? С чем это связано?

Deal/Order/Ticket  - это я учитываю здесь: pm_PositionsArray[size].PositionTicket  = (aDeal==0)?aOrder:aDeal;


Есть есть серьезные ошибки в логике эксперта, укажите хотя бы на одну.

 
Ilyas:


Вам нужно более детально разобраться в Deal/Order/Ticket, почитать про OrderSend/OnTradeTransaction

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

В справке по OrderSend явно сказано

При отправке рыночного ордера (MqlTradeRequest.action=TRADE_ACTION_DEAL) успешный результат функции OrderSend() не означает, что ордер был выполнен (исполнены соответствующие сделки): true в этом случае означает только то, что ордер был успешно размещен в торговой системе для дальнейшего выполнения. Торговый сервер может в возвращаемой структуре результата result заполнить значения полей deal или order, если эти данные будут ему известны в момент формирования ответа на вызов OrderSend(). В общем случае событие или события исполнения сделок, соответствующих ордеру, могут произойти уже после того, как будет отправлен ответ на вызов OrderSend(). Поэтому для любого типа торгового запроса при получении результата выполнения OrderSend() необходимо в первую очередь проверять код возврата торгового сервера retcode и код ответа внешней торговой системы retcode_external (при необходимости), которые доступны в возвращаемой структуре результата result.

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

  • истечение срока действия,
  • появление встречного запроса,
  • срабатывание ордера при поступлении цены исполнения,
  • поступление запроса на отмену ордера.

В момент обработки ордера торговый сервер посылает терминалу сообщение о наступлении торгового события Trade, которое можно обработать функцией OnTrade().

Результат исполнения торгового запроса на сервере, отправленного функцией OrderSend() можно отслеживать при помощи обработчика OnTradeTransaction. При этом следует учитывать, что в результате исполнения одного торгового запроса обработчик OnTradeTransaction будет вызван несколько раз.

Документация по MQL5: Торговые функции / OrderSend
Документация по MQL5: Торговые функции / OrderSend
  • www.mql5.com
OrderSend - Торговые функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

Смотрите также статью https://www.mql5.com/ru/articles/2513

Для разработчиков торговых роботов важно понимать одно существенное обстоятельство: каждая торговая операция, будь то открытие позиции, установка StopLoss или TakeProfit,  или закрытие позиции встречной сделкой — всегда состоит из множества транзакций, совершаемых на сервере MetaTrader 5 и на Московской бирже. Чтобы увидеть как это происходит, вы можете запустить на своем счете советника TradeTransactionListener.mql5, который просто слушает события TradeTransaction и выводит краткую информацию по ним:


С чего начать при создании торгового робота для Московской биржи MOEX
С чего начать при создании торгового робота для Московской биржи MOEX
  • www.mql5.com
Многие трейдеры на Московской бирже хотели бы автоматизировать свои торговые алгоритмы, но не знают с чего начать. Язык MQL5 предлагает не только огромный набор торговых функций, но и готовые классы, которые максимально облегчают первые шаги в алготрейдинге.
 
Nextor:


1. Что за "фича" такая? С чем это связано?

2. Есть есть серьезные ошибки в логике эксперта, укажите хотя бы на одну.

1. Тестер синхронная песочница для одного пользователя, Deal = Order

2. Сильно на качество кода не смотрел
    Мало проверок, в реальных условиях могут быть проблемы, например со связью...
    Функции удаления позиции вызывает подозрение, перепроверьте, а лучше перепишите - это же простое уплотнение массива, задача решается за O(N), у Вас O(N^2)
  
    Дальше не смотрел

 
Ilyas:

1. Тестер синхронная песочница для одного пользователя, Deal = Order

Ну блин, так не интересно, взял и всем рассказал. А я купил эту информацию за 19 т.р.   )))

В проверке использовал  Deal вместо  Order,  в тестере всё красиво работало, а на реале советник за пару минут запилил столько сделок, что комиссия вылезла в эту сумму.

Теперь пишу ещё пару проверок на проверку )))

 

@Ilyas, @Rashid Umarov, спасибо большое, разобрался!

Всё работает!

 
Комментарии, не относящиеся к этой теме, были перенесены в "Вопросы от начинающих MQL4 MT4 MetaTrader 4".