Дублирование запросов на открытие позиций.

 

Приветствую! Помогите решить проблему с открытием нескольких сделок советником.По условию требуется открывать одну сделки при отсутствии позиций или ордеров 0.02 лота.

Выписка из истории:

вкладка история

Как видно,проходит 2 сделки и суммарная позиция получается 0.04 лота.

В журнале проходит такая информация :

журнал

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

Привожу кратко участок по открытию позиции:

 if (PositionsTotal()==0 && OrdersTotal==0 && a>b) {
             MqlTradeRequest request;
             request.action=TRADE_ACTION_DEAL;    
             request.symbol=_Symbol;           
             request.volume=Lotx;                     
             request.sl=NormalizeDouble(last_tick.ask-StopLoss*_Point,_Digits);                          
             request.tp=0;
             request.deviation=Dev ;                           
             request.type=0;               
             request.price=last_tick.ask ; 
              MqlTradeResult result;
         OrderSend(request,result);}

 

PS.Сначала я считал,что связано с задержкой ответа от сервера по принятию ордера.Новый тик приходил раньше ответа,на новом тике и проходили опять условия.Но вот в журнале видно,что ответ приходит раньше,и тем не менее заходит на очередной круг-отправляет новый запрос Instant . 

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

Благодарю. 

 

подозрительно не стоят () у 
OrdersTotal
дубликата имени случайно нет ?
 
Karlson:

Приветствую! Помогите решить проблему с открытием нескольких сделок советником.По условию требуется открывать одну сделки при отсутствии позиций или ордеров 0.02 лота.

Выписка из истории:

Как видно,проходит 2 сделки и суммарная позиция получается 0.04 лота.

В журнале проходит такая информация :

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

Привожу кратко участок по открытию позиции:

 

PS.Сначала я считал,что связано с задержкой ответа от сервера по принятию ордера.Новый тик приходил раньше ответа,на новом тике и проходили опять условия.Но вот в журнале видно,что ответ приходит раньше,и тем не менее заходит на очередной круг-отправляет новый запрос Instant . 

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

Благодарю. 

 

 

Тоже не однократно наблюдал такую проблему на демо счете, в тестере такого нет конечно. Как с этим бороться пока не понятно.
 
sergey1294:
Тоже не однократно наблюдал такую проблему на демо счете, в тестере такого нет конечно. Как с этим бороться пока не понятно.

может ставить запрет на операции пока не получится результат от OrderSend ? (то есть не ответ, а результат)

будет аля TradeContextBusy в MT4  // хотели как лучше, а получилось как всегда.

 

Скобочки я потерял в последнем редактировании.Есть они там :-)

Одним из способов решил сделать проверку прямо перед запросом:

 if (!PositionsTotal() && !OrdersTotal()) {  OrderSend(request,result);}

 Но думаю не спасет.Попробую с началом торгов запустить.Такие ситуации возникают раз в неделю на демо,так что еще и подождать надо.

Да,другой способ проверку результата делать :

 if (!PositionsTotal() && !OrdersTotal() && x!=1) {  OrderSend(request0,result0);
                                          if (result0.retcode==TRADE_RETCODE_DONE) {x=1;}}
                                                                    

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

 Вообщем пока такие способы попробую протестить.Других решений пока нет. 

 

MqlTradeResult - возвращает тикет ордера / сделки

просто заблокируйте новые открытия, пока в ордерах / сделках не появится возвратившийся тикет.

Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура результата торгового запроса
Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура результата торгового запроса
  • www.mql5.com
Стандартные константы, перечисления и структуры / Структуры данных / Структура результата торгового запроса - Документация по MQL5
 

Если я Вас правильно понял ,то таким образом:

OrderSend(request,result);
if (result.deal!=0) { разрешить;} else { запретить;} 
            

 

Если тикет есть ,то разрешит дальше торговать,если нету,то запрещает,пока не вернется тикет. 

 Не могу в документации найти пока нужную функцию для запрета на торговлю...

Или так :

if (PositionsTotal()==0 && OrdersTotal()==0 && result.deal==0 && a>b) {
             MqlTradeRequest request0;
             request0.action=TRADE_ACTION_DEAL;    
             request0.symbol=_Symbol;           
             request0.volume=Lotx;                     
             request0.sl=NormalizeDouble(last_tick.ask-StopLoss*_Point,_Digits);                          
             request0.tp=0;
             request0.deviation=Dev ;                           
             request0.type=0;               
             request0.price=last_tick.ask ; 
              MqlTradeResult result0;
         OrderSend(request0,result0);}

 

 По незнанию генерируются варианты :

if (MqlTradeResult result==0)      {   OrderSend(request,result);}

 

 

 

А что думаете при таком коде?

 if (PositionsTotal()==0 && OrdersTotal==0 && a>b) {
             MqlTradeRequest request0;
             request0.action=TRADE_ACTION_DEAL;    
             request0.symbol=_Symbol;           
             request0.volume=Lotx;                     
             request0.sl=NormalizeDouble(last_tick.ask-StopLoss*_Point,_Digits);                          
             request0.tp=0;
             request0.deviation=Dev ;                           
             request0.type=0;               
             request0.price=last_tick.ask ; 
              MqlTradeResult result0;
         if (x==true) {OrderSend(request0,result0);
                       x=false;}
         
 OnTrade(){
 x=true;}      

 После отправки запроса меняем переменную.Только при наступлении события Trade (открыта позиция или наоборот закрыта) переменная обнуляется =переводится в True,тем самым разрешая дальнейшую торговлю.

 
Karlson:

Если я Вас правильно понял ,то таким образом:

Нет, надо дождаться появления сделки в истории. Например так:
//--- OrderSend() вернул true
   while(!HistoryDealSelect(result.deal))
     Sleep(10);
или использовать семафор:
MyOrderSend(MqlTradeRequest& request,MqlTradeResult& result) 
   {
    static ulong DealTicket=0; //---тиккет последней сделки
    static bool trade=true;    //---разрешение торговли
    if(DealTicket) //---сделка не первая
     trade=HistoryDealSelect(DealTicket); //---true - сделка в истории, false - ещё не пришла
    if(trade) //--- торгуем
     if(OrderSend(request,result))
      {
       DealTicket=result.deal; //---запомнили тиккет сделки
       return(true);
      } 
     else
      {
       //---обработка ошибки OrderSend
      }
    return(false);
   }
 

Valmars,Благодарю!!!! Крутил  по отдельности result.deal и sleep и все вертолет получался ,а вон как просто.Проверю в онлайне.Еще раз Благодарю!

 if(OrderSend(request,result)) {while(!HistoryDealSelect(result.deal)) { Sleep(10);}}

 Второй вариант в процессе разбора и понимания :-)

 
Karlson:

Valmars,Благодарю!!!! Крутил  по отдельности result.deal и sleep и все вертолет получался ,а вон как просто.Проверю в онлайне.Еще раз Благодарю!

 Второй вариант в процессе разбора и понимания :-)

Скорее всего правильным решением будет вариант с семафором, чтоб не блокировать работу эксперта. У меня аналогичная проблема, делаю семафор.

Торговля по символу блокируется после успешной отсылки ордера. Разблокируется в OnTrade() после совершения сделки.

Причина обращения: