Как правильно открыть ордер по рынку?

 

Я недавно подымал тему по повторному открытию ордеров. Думал, что проблему решил, т.к. неделю все работало очень четко. Но сегодня столкнулся с аналогичной проблемой только при открытии.
На Финаме открылось очень много ордеров, на Открытие 9...хотя во всех случаях должен был открыться только один ордер.

Вот вырезка кода из советника

    if(OpenOrders<1)
    {
        Coment="Open Sell "+string(OpenOrders+1);
        ret=OpenSellPosition(_Symbol,volume,Coment,Sleeppage,Filling);
    }
    
    
  if(ret)
  {
    OpenOrders++;
    PriceLastOpen=price;
  }

bool OpenSellPosition(string symbol, double volume, string comment="", ulong deviation=10, ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK)
{
  MqlTradeRequest Request;
  MqlTradeResult Results;
  ZeroMemory(Request);
  ZeroMemory(Results);
  Request.price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
  Request.action=TRADE_ACTION_DEAL;
  Request.type=ORDER_TYPE_SELL;
  Request.symbol=symbol;
  Request.volume=volume;      
  Request.deviation=deviation;
  Request.comment=comment;  
  Request.type_filling=filling;
  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);
  }
  return(false);
}

 т.е. из кода видно, что при успешной операции увеличивается переменная OpenOrders, которая изначально равна 0

и если она более 0, то дальнейшего открытия ордера не должно быть, но вся куча ордеров открыта с комментом Ордер1. 

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

Объясните что не так, как решить данную проблему? 

 
Предполагаю, что инфа о  сделке ещё не успела прийти. Вот тут (выделил красным) Вы полагаетесь на удачу. А она капризная дама :-))

bool OpenSellPosition(string symbol, double volume, string comment="", ulong deviation=10, ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK)
{
  MqlTradeRequest Request;
  MqlTradeResult Results;
  ZeroMemory(Request);
  ZeroMemory(Results);
  Request.price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
  Request.action=TRADE_ACTION_DEAL;
  Request.type=ORDER_TYPE_SELL;
  Request.symbol=symbol;
  Request.volume=volume;      
  Request.deviation=deviation;
  Request.comment=comment;  
  Request.type_filling=filling;
  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);

  }
  return(false);
}
 
Gennady Mazur:

Я недавно подымал тему по повторному открытию ордеров. Думал, что проблему решил, т.к. неделю все работало очень четко. Но сегодня столкнулся с аналогичной проблемой только при открытии.
На Финаме открылось очень много ордеров, на Открытие 9...хотя во всех случаях должен был открыться только один ордер.

Вот вырезка кода из советника

    if(OpenOrders<1)
    {
        Coment="Open Sell "+string(OpenOrders+1);
        ret=OpenSellPosition(_Symbol,volume,Coment,Sleeppage,Filling);
    }
    
    
  if(ret)
  {
    OpenOrders++;
    PriceLastOpen=price;
  }

bool OpenSellPosition(string symbol, double volume, string comment="", ulong deviation=10, ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK)
{
  MqlTradeRequest Request;
  MqlTradeResult Results;
  ZeroMemory(Request);
  ZeroMemory(Results);
  Request.price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
  Request.action=TRADE_ACTION_DEAL;
  Request.type=ORDER_TYPE_SELL;
  Request.symbol=symbol;
  Request.volume=volume;      
  Request.deviation=deviation;
  Request.comment=comment;  
  Request.type_filling=filling;
  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);
  }
  return(false);
}

 т.е. из кода видно, что при успешной операции увеличивается переменная OpenOrders, которая изначально равна 0

и если она более 0, то дальнейшего открытия ордера не должно быть, но вся куча ордеров открыта с комментом Ордер1. 

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

Объясните что не так, как решить данную проблему? 

Плохая наследственнось Форекс.

Надо проверять  Results.order. 

Если ордер выставлен, это не значит что уже совершена сделка. 

 
Sergey Chalyshev:

Плохая наследственнось Форекс.

Надо проверять  Results.order. 

Если ордер выставлен, это не значит что уже совершена сделка. 

Вы были бы правы, если бы я ставил отложки, но я работаю по рынку, и тут тикет получается с помощью Results.deal
 
Dennis Kirichenko:
Предполагаю, что инфа о  сделке ещё не успела прийти. Вот тут (выделил красным) Вы полагаетесь на удачу. А она капризная дама :-))

bool OpenSellPosition(string symbol, double volume, string comment="", ulong deviation=10, ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK)
{
  MqlTradeRequest Request;
  MqlTradeResult Results;
  ZeroMemory(Request);
  ZeroMemory(Results);
  Request.price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
  Request.action=TRADE_ACTION_DEAL;
  Request.type=ORDER_TYPE_SELL;
  Request.symbol=symbol;
  Request.volume=volume;      
  Request.deviation=deviation;
  Request.comment=comment;  
  Request.type_filling=filling;
  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);

  }
  return(false);
}
Да нет, этот результат присутствует, это же не тикет ордера на сервере, это временный тикет операции, который сменится в дальнейшем на тикет позиции
 
Dennis Kirichenko:
Предполагаю, что инфа о  сделке ещё не успела прийти. Вот тут (выделил красным) Вы полагаетесь на удачу. А она капризная дама :-))

bool OpenSellPosition(string symbol, double volume, string comment="", ulong deviation=10, ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK)
{
  MqlTradeRequest Request;
  MqlTradeResult Results;
  ZeroMemory(Request);
  ZeroMemory(Results);
  Request.price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
  Request.action=TRADE_ACTION_DEAL;
  Request.type=ORDER_TYPE_SELL;
  Request.symbol=symbol;
  Request.volume=volume;      
  Request.deviation=deviation;
  Request.comment=comment;  
  Request.type_filling=filling;
  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);

  }
  return(false);
}
Да и меня уверяли в предыдущей теме, гуру этого форума, что эта инфа всегда приходит ... чуть ли не мгновенно... а если при положительном ответе сервера тикет не выдан, то ордер не состоялся
 

Вам нужно протоколировать все торговые операции. Например так:

сначала в "шапке" подключаем торговый класс CTrade

#include <Trade\Trade.mqh>
CTrade         m_trade;                      // trading object

а вот пример операции Buy:

   if(m_trade.Buy(lots,NULL,m_symbol.Ask(),sl,tp))
     {
      if(m_trade.ResultDeal()==0)
         Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
               ", description of result: ",m_trade.ResultRetcodeDescription());

      else
         Print("Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),
               ", description of result: ",m_trade.ResultRetcodeDescription());
     }
   else
      Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
            ", description of result: ",m_trade.ResultRetcodeDescription());

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

Потом уже, если случится накладка, по логам можно будет разобраться. 

 

Добавлено: сказанное верно для СИНХРОННОГО режима работы. 

 

Щас и тут гуру научат ))

Объясните что не так, как решить данную проблему? 

С вашим опытом, неприлично здесь задавать такие вопросы. 

 
Vladimir Karputov:

Вам нужно протоколировать все торговые операции. Например так:

сначала в "шапке" подключаем торговый класс CTrade

#include <Trade\Trade.mqh>
CTrade         m_trade;                      // trading object

а вот пример операции Buy:

   if(m_trade.Buy(lots,NULL,m_symbol.Ask(),sl,tp))
     {
      if(m_trade.ResultDeal()==0)
         Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
               ", description of result: ",m_trade.ResultRetcodeDescription());

      else
         Print("Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),
               ", description of result: ",m_trade.ResultRetcodeDescription());
     }
   else
      Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
            ", description of result: ",m_trade.ResultRetcodeDescription());

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

Потом уже, если случится накладка, по логам можно будет разобраться. 

 

Добавлено: сказанное верно для СИНХРОННОГО режима работы. 

Так у меня именно так и сделано

  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);
  }
  return(false);
только своим кодом
 
Vladimir Karputov:

Вам нужно протоколировать все торговые операции. Например так:

сначала в "шапке" подключаем торговый класс CTrade

#include <Trade\Trade.mqh>
CTrade         m_trade;                      // trading object

а вот пример операции Buy:

   if(m_trade.Buy(lots,NULL,m_symbol.Ask(),sl,tp))
     {
      if(m_trade.ResultDeal()==0)
         Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
               ", description of result: ",m_trade.ResultRetcodeDescription());

      else
         Print("Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),
               ", description of result: ",m_trade.ResultRetcodeDescription());
     }
   else
      Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
            ", description of result: ",m_trade.ResultRetcodeDescription());

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

Потом уже, если случится накладка, по логам можно будет разобраться. 

 

Добавлено: сказанное верно для СИНХРОННОГО режима работы. 

Да и еще, а стандартная функция разве поддерживает исполнение ордеров, их филлинг, потому как ранее я использовал СиТрейд для открытия, пока не попал на биржу, где ордера не хотели исполняться, т.к. невозможно было определить филлинг
 
Gennady Mazur:
Так у меня именно так и сделано

  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);
  }
  return(false);
только своим кодом
А логирование? Нужно обязательно выводить и успешное окончание операции и, особенно, неудачу с кодом ошибки.
Причина обращения: