Мой эксперт выполняет двойную запись - страница 4

 
doshur:

могу ли я спросить, PositionSelect() проверяет клиентскую сторону или сторону сервера?

У меня есть сильное ощущение, что проблема вызвана задержкой, когда сервер (сторона брокера) обрабатывает запрос и не обновляет клиентскую сторону, поэтому PositionSelect() запускается снова.

Я действительно чувствую, что нет никакой разницы, когда мы используем cTrade против MqlTradeRequest, и функция Sleep должна помочь задержать все, чтобы наша клиентская сторона была "обновлена" до того, как PositionSelect() будет запущен снова, вызывая двойную запись. Проверяю на вкладке журнала, >2013.12.20 08:35:00 Trades '800****': exchange buy 0.01 EURUSD at market placed for execution in 313 ms <

если ставить сон более 400, то это должно быть безопасно?

Что вы думаете?


"У меня сильное чувство, что проблема вызвана задержкой, когда сервер (сторона брокера) обрабатывает запрос и не обновляет клиентскую сторону, поэтому PositionSelect() запускается снова"

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


"Постановка sleep более 400 должна быть безопасной????"

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

 
snelle_moda:


"У меня есть сильное ощущение, что проблема вызвана задержкой, когда сервер (сторона брокера) обрабатывает запрос и не обновляет клиентскую сторону, поэтому PositionSelect() запускается снова"

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


"Если ставить sleep больше 400, это должно быть безопасно????"

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

Я думаю, что это не должно быть проблемой. Мой советник не разворачивается немедленно, когда я только что отправил запрос на покупку/продажу. Я ставлю время сна на 800 мс, чтобы у моего советника было достаточно времени, чтобы дождаться обновлений от брокера. Надеюсь, Sleep поможет решить эту проблему.
 
doshur:
Я не знаю, играет ли брокер здесь разную роль, но похоже, что наш брокер один и тот же. Альпари.

Пожалуйста, удалите имя брокера, если это необходимо.
Да, брокер один и тот же.
 
snelle_moda:


С 03-10-2013 у меня была еще 1 двойная запись. Я использую оба метода для отправки заказа. См. мое предыдущее сообщение.

Аааа... как я и ожидал...
 

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

if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0))
            {
               Sleep(800);

               if(m_Trade.ResultRetcode() == 10009)
               {
                  Print("Position opened in ", Symbol());

                  return;
               }
               else
               {
                  Print("Error opening position in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
               }
            }
            else
            {
               Print("Error with PositionOpen in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
            }
 
doshur:

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

Насколько я знаю, код результата = 10008 также указывает на то, что сделка хорошо размещена.
 

Я думаю, что очень важно найти причину этой проблемы, конечно, также важно иметь обходной путь (Sleep ?), пока мы не сможем полностью понять, что происходит. Итак, я попытаюсь восстановить ситуацию:

  • При использовании метода PositionOpen из класса CTrade, по крайней мере 3 пользователя получили в определенное время 2 сделки в одном направлении вместо 1, что привело к позиции с удвоенным объемом по сравнению с ожидаемым.
  • Код, первоначально опубликованный doshur, может объяснить, почему он видит в своем журнале "Позиция открыта в...", в то время как ни одна сделка не была открыта. Это происходит потому, что даже если PositionOpen() возвращает true, это не означает, что сделка открыта. См. документацию. Но это не может объяснить, почему "двойная" сделка была размещена.
  • Я вижу только 2 объяснения этой "двойной" торговле:
  1. PositionSelect() не всегда возвращает истинное положение дел с позицией. Позиция открыта, но PositionSelect возвращает false. Значит, ошибка в PositionSelect.
  2. Сделка размещается, но когда на следующем тике вызывается PositionSelect(), позиция еще не существует. Чтобы понять, возможно ли это, мы должны знать поток операций, когда сделка размещена.
  • Эта проблема, похоже, возникает на одном и том же брокере, с символом, где активирована Depth of Market (могут ли заинтересованные лица подтвердить это, пожалуйста).
  • Эта проблема возникает с синхронным ордером, асинхронный ордер не использовался (пожалуйста, подтвердите это).
  • Проблема возникает случайным образом.
  • Klammeraffe сообщает, что проблемыбольше нет , но я не могу понять, как код, который он опубликовал, может объяснить это. Выполняется ли этот код на каждом тике? Выполняется ли этот код после использования PositionSelect()? Так что, возможно, он устранил причину ошибки или она просто случайна.
  • После проверки кода я не вижу никакой разницы между использованием класса CTrade или MqlTradeRequest с OrderSend напрямую.

Я согласен с snella_moda, что лучшим объяснением является:

I think the problem is the (to slow) execution of the PositionSelect(Symbol()) function. Maybe, the new ticks come in so fast, the EA sends in a new order before it receives a response of the PositionSelect(Symbol()). So the current position size is not calculated properly. In my code, its theoretically impossible to send in a new/double order if the current position size is equal or greater than the max allowed position size, see code. 

Но это трудно проверить.

Я думаю, что лучше всего обратиться за советом к Metaquotes. Я попробую это сделать.

 
angevoyageur:
  • Klammeraffe сообщает, что проблемыбольше нет , но я не могу понять, как код, который он разместил, может объяснить это. Выполняется ли этот код на каждом тике? Выполняется ли этот код после использования PositionSelect()? Так что, возможно, он устранил причину ошибки или она просто случайна.

Строка о "каждом тике" может быть причиной того, что этого больше не происходит.

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

Я думаю, что этот кусок кода взят из статей:

//-------------------------------------------------- Check for new bar     
         static datetime OldTime;
         datetime NewTime[1];
         bool newBar=false;
         
         int copied=CopyTime(Symbol(),Period(),0,1,NewTime);
         if (copied>0)
           {
             if (OldTime != NewTime[0])
               {  
                 newBar=true;
                 OldTime=NewTime[0];
               }
           }
         else
           {
            Print("Error in copying historical times data, error =",GetLastError());
            ResetLastError();
            return;
           }  
         if(newBar==false) return;      
//-------------------------------------------------- Check for new bar
 
Klammeraffe:

Строка о "каждом тике" может быть причиной того, что этого больше не происходит.

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

Я думаю, что этот кусок кода взят из статей:

Да, я так думаю. Спасибо.
 
  • Код, первоначально опубликованный doshur, может объяснить, почему он может видеть в своем журнале "Позиция открыта в...", в то время как ни одна сделка не была открыта. Это потому, что даже если PositionOpen() возвращает true, это не означает, что сделка открыта.См. документацию. Но это не может объяснить, почему была размещена "двойная" сделка.

исправление. Есть двойная"Позиция открыта в..." и 2 сделки были открыты.

  • Эта проблема, похоже, возникает у одного и того же брокера, с символом, где активирована функция Depth of Market (могут ли заинтересованные лица подтвердить это, пожалуйста).
Не уверен насчет других, но у меня есть DOM.

  • Эта проблема возникает с синхронным ордером, асинхронный ордер не использовался (пожалуйста, подтвердите).
Я использую настройки cTrade по умолчанию.

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