¿Cómo puedo abrir una orden de mercado correctamente?

 

Hace poco planteé un tema sobre la reapertura de pedidos. Pensé que había resuelto el problema, ya que todo funcionó sin problemas durante una semana. Pero hoy me he encontrado con un problema similar sólo al abrir.
Se abrieron muchas órdenes en Finam, y 9 en Otkritie... aunque sólo debería haberse abierto una orden en todos los casos.

Este es un fragmento de código del EA

    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);
}

es decir, podemos ver en el código que si la operación tiene éxito, aumenta la variableOpenOrders, que inicialmente es igual a 0

Si es superior a 0, no debe haber más apertura de la orden, sino que toda la pila de órdenes se abre con el comentario Orden1.

Compruebo si hay una respuesta positiva en la función de apertura de la orden y si se ha recibido el ticket de la orden, pero por alguna razón esta función devuelve false, aunque la orden esté realmente establecida.

Explique qué es lo que falla, cómo resolver este problema.

 
Supongo que la información sobre el acuerdo aún no ha llegado. Aquí (resaltado en rojo) confías en la suerte. Y es una señora caprichosa :-))

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:

Hace poco planteé la cuestión de la reapertura de las órdenes. Pensé que había resuelto el problema porque todo funcionó muy bien durante una semana. Pero hoy me he encontrado con un problema similar sólo con la apertura.
Un gran número de órdenes se abrieron en Finam, y 9 en Otkritie... aunque en todos los casos sólo debería haberse abierto una orden.

Este es un fragmento de código del EA

    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);
}

es decir, podemos ver en el código que si la operación tiene éxito, aumenta la variableOpenOrders, que inicialmente es igual a 0

Si es superior a 0, no debe haber más apertura de la orden, sino que toda la pila de órdenes se abre con el comentario Orden1.

Compruebo si hay una respuesta positiva en la función de apertura de la orden y si se ha recibido el ticket de la orden, pero por alguna razón esta función devuelve false, aunque la orden esté realmente establecida.

¿Puede explicar qué es lo que está mal y cómo solucionar este problema?

Mala herencia de forex.

Debería comprobarlos resultados.orden.

Si el pedido se realiza, no significa que el trato ya esté hecho.

 
Sergey Chalyshev:

Mala herencia de forex.

Tenemos que comprobarlo.orden.

La colocación de una orden no significa que se haya ejecutado una operación.

Tendrías razón si pusiera órdenes pendientes, pero yo trabajo por mercado y aquí la entrada se obtiene conResultados.deal
 
Dennis Kirichenko:
Supongo que la información sobre el acuerdo aún no ha llegado. Aquí (resaltado en rojo) confías en la suerte. Y es una señora caprichosa :-))

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);
}
No, este resultado está presente, no se trata de un pedido de billetes en el servidor, se trata de una operación temporal de billetes, que más tarde será sustituida por una posición de billetes
 
Dennis Kirichenko:
Supongo que la información sobre el acuerdo aún no ha llegado. Aquí (resaltado en rojo) confías en la suerte. Y es una señora caprichosa :-))

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);
}
Y me aseguró en un hilo anterior, el gurú de este foro, que esa información siempre llega... casi al instante... y si el servidor respondía positivamente el ticket no se emitía, el pedido fallaba
 

Hay que registrar todas las operaciones. Por ejemplo, así:

primero en la "cabecera" conectamos la clase de comercio CTrade

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

y aquí hay un ejemplo de la operación 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());

por lo que puede obtener dos errores: de primer nivel - la operación no ha pasado la comprobación básica y de segundo nivel - la comprobación del ticket de la operación.

Luego, si hay un problema, puedes usar los registros para resolverlo.

Añadido: lo anterior es válido para el modo de funcionamiento SYNC.

 

Ahora los gurús de aquí también te enseñarán ))

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

Con su experiencia, es impropio hacer esas preguntas aquí.

 
Vladimir Karputov:

Hay que registrar todas las operaciones. Por ejemplo, así:

primero en la "cabecera" conectamos la clase de comercio CTrade

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

y aquí hay un ejemplo de la operación 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());

por lo que puede obtener dos errores: de primer nivel - la operación no ha pasado la comprobación básica y de segundo nivel - la comprobación del ticket de la operación.

Luego, si hay un problema, puedes usar los registros para resolverlo.

Añadido: esto es cierto para el modo de funcionamiento SYNC.

Así es exactamente como lo hice.

  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);
  }
  return(false);
sólo con mi propio código
 
Vladimir Karputov:

Hay que registrar todas las operaciones. Por ejemplo, así:

primero en la "cabecera" conectamos la clase de comercio CTrade

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

y aquí hay un ejemplo de la operación 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());

por lo que puede obtener dos errores: de primer nivel - la operación no ha pasado la comprobación básica y de segundo nivel - la comprobación del ticket de la operación.

Luego, si hay un problema, puedes usar los registros para resolverlo.

Añadido: lo anterior es válido para el modo de funcionamiento SYNC.

Ah y otra cosa, ¿la función estándar admite la ejecución de órdenes, su presentación, porque yo utilizaba SeaTrade para la apertura, hasta que llegué a una bolsa donde las órdenes no querían ejecutarse porque era imposible determinar la presentación
 
Gennady Mazur:
Eso es exactamente lo que he hecho.

  bool res=false;
  res=OrderSend(Request,Results);
  if(res)
  {
    if(Results.deal>0) return(true);
    else return(false);
  }
  return(false);
pero con mi propio código.
¿Y la tala de árboles? Hay que dar salida tanto a la finalización con éxito de la operación como, sobre todo, al fallo con el código de error.