Procesamiento de OnTradeTransaction

 

Buenas noches.

Chicos, por favor, ayudadme. El problema probablemente no es nuevo, pero no he encontrado una sola solución (ni en la práctica ni en los foros).

Estoy ejecutando 2 robots diferentes en el terminal en 2 instrumentos diferentes. Las magias son diferentes en todas partes. El robot coloca límites pendientes y el procedimiento OnTradeTransaction me permite detectar una transacción y colocar órdenes stop pendientes utilizando esta transacción.

A continuación se muestra el código de la transacción comercial

case TRADE_TRANSACTION_DEAL_ADD:
        {
         drop_info2("TRADE_TRANSACTION_DEAL_ADD\r\n"+TransactionDescription(trans));
         if((trans.deal_type==DEAL_TYPE_BUY || trans.deal_type==DEAL_TYPE_SELL) && trans.order!=0)
           {
            if(getIsDealOfExpert(trans.deal)) //функция проверки принадлежности сделки к роботу
              {
               drop_info2("Сделка наша");
               analyzeFilledOrder(trans.order,trans.volume); //процедура по выставлению отложенных стоп ордеров
              }
           }
        }
      break;

Este es el código de la función que comprueba si el acuerdo pertenece a un robot

bool getIsDealOfExpert(ulong dealTicket)
     {
      if(HistoryDealSelect(dealTicket) && HistoryDealGetInteger(dealTicket,DEAL_MAGIC)==magic_number && HistoryDealGetString(dealTicket,DEAL_SYMBOL)==symbol)
         return true;
      else
         return false;
     }

Este es el código del procedimiento para las órdenes de stop pendientes

void analyzeFilledOrder(ulong orderTicket,double volume)
  {
   bool isFindOrder=false;
   string fullComment;
   ENUM_ORDER_TYPE orderType;
   if(getIsOrderOfExpert(orderTicket,true)) //Если ордер из сделки уже в истории
     {
      fullComment=HistoryOrderGetString(orderTicket,ORDER_COMMENT);
      orderType=ENUM_ORDER_TYPE(HistoryOrderGetInteger(orderTicket,ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли в истории
     }
   if(!isFindOrder && getIsOrderOfExpert(orderTicket,false)) //Если не нашли ордер в истории и ордер есть не в истории
     {
      fullComment=OrderGetString(ORDER_COMMENT); 
      orderType=ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли не в истории
     }
   if(isFindOrder) //если хоть где-то нашли, то выставляем отложенные стоп ордера
     {
     //выставляем стоп ордера

Este es el código de la función para buscar un pedido en el historial y fuera del historial

bool getIsOrderOfExpert(ulong OrderTicket,bool isHistory)
     {
      bool is_expert=false;
      //если ордер находится в истории
      if(isHistory)
        {
         if(HistoryOrderSelect(OrderTicket) && HistoryOrderGetInteger(OrderTicket,ORDER_MAGIC)==magic_number && HistoryOrderGetString(OrderTicket,ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      else
        {
         if(OrderSelect(OrderTicket) && OrderGetInteger(ORDER_MAGIC)==magic_number && OrderGetString(ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      return is_expert;
     }

La información sobre las transacciones entrantes se publicaría en los archivos de registro en el orden en que se reciben en el terminal. Ahora tengo un problema que he enfrentado al operar en una cuenta demo:

A veces las transacciones vienen en el siguiente orden TRADE_TRANSACTION_ORDER_DELETE, luego TRADE_TRANSACTION_DEAL_ADD, luego TRADE_TRANSACTION_HISTORY_ADD. En este caso, las órdenes de stop no suelen colocarse después de que se haya ejecutado una operación. Supongo que esto ocurre porque el pedido ya ha sido eliminado pero aún no se ha añadido al historial. Significa que no podemos encontrar la orden del acuerdo ni en el historial ni en el terminal. Aunque es dudoso, el hecho es que no se coloca ninguna orden de stop porque el robot no la encuentra después de buscar la orden en todas las dimensiones(isFindOrder=false). En todos los casos, el robot detecta la transacción correctamente, pero no llega a colocar las órdenes.Sin embargo, en ocasiones también funciona correctamente y se colocan las órdenes.

He probado diferentes enfoques, nada funciona. Ahora estoy pensando en añadir un intervalo de 1 segundo al principio del procedimiento de colocación de pedidos pendientes. No sé realmente a dónde ir.

Por favor, comparta sus experiencias e ideas.

 
Илья Ребенок:

Buenas noches.

Chicos, por favor, ayudadme. El problema probablemente no es nuevo, pero no he encontrado una sola solución (ni en la práctica ni en los foros).

Estoy ejecutando 2 robots diferentes en el terminal en 2 instrumentos diferentes. Las magias son diferentes en todas partes. El robot coloca límites pendientes y el procedimiento OnTradeTransaction me permite detectar una transacción y colocar órdenes stop pendientes utilizando esta transacción.

A continuación se muestra el código de la transacción comercial

Este es el código de la función que comprueba si el acuerdo pertenece a un robot

Este es el código del procedimiento para las órdenes de stop pendientes

Este es el código de la función para buscar un pedido en el historial y fuera del historial

La información sobre las transacciones entrantes se mostraría en el registro en el orden en que se reciben en el terminal. Ahora tengo un problema que he enfrentado al operar en una cuenta demo:

A veces las transacciones vienen en el siguiente orden TRADE_TRANSACTION_ORDER_DELETE, luego TRADE_TRANSACTION_DEAL_ADD, luego TRADE_TRANSACTION_HISTORY_ADD. En este caso, las órdenes de stop no suelen colocarse tras la ejecución de una operación. Supongo que esto ocurre porque el pedido ya ha sido eliminado pero aún no se ha añadido al historial. Significa que no podemos encontrar la orden del acuerdo ni en el historial ni en el terminal. Aunque es dudoso, el hecho es que no se coloca ninguna orden de stop porque el robot no la encuentra después de buscar la orden en todas las dimensiones(isFindOrder=false). El orden de la transacción puede ser correcto, pero el orden no se encuentra en ninguna parte.

He intentado diferentes enfoques, nada ayuda. Ahora estoy pensando en añadir una suspensión de 1 segundo al principio de un procedimiento para colocar órdenes pendientes, tal vez el tiempo no sea suficiente. Ni siquiera sé dónde más cavar.

Por favor, comparta sus experiencias e ideas.

No he empezado a mirar todo el código. No creo que este enfoque sea correcto en absoluto.

En el momento de la transacción tipo TRADE_TRANSACTION_DEAL_ADD debemos elegir la posición trans.y comprobar su magia.

if(PositionSelectByTicket(trans.position) && PositionGetInteger(POSITION_MAGIC) == mag)

También puede comprobar que trans.symbol == _Symbol y tomar una decisión basada en los resultados de estas comprobaciones.

 
Alexey Viktorov:

No he mirado todo el código. En mi opinión, el planteamiento no es en absoluto correcto.

En el momento del tipo de transacción TRADE_TRANSACTION_DEAL_ADD se debe elegir trans.position y comprobar su magik.

También puede comprobar que trans.symbol == _Symbol y tomar una decisión basada en los resultados de estas comprobaciones.

Se me olvidó añadir que el modo es de red. La posición es la misma para todos los robots. Es decir, un robot compró una posición, el segundo la compró, los eventos TRADE_TRANSACTION_DEAL_ADD llegaron en orden inverso y el primer robot no lo vio como resultado.

Y lógicamente necesito obtener el comentario de la orden del comercio, la posición no es de mucha ayuda aquí.
 
Илья Ребенок:

Comparta sus experiencias e ideas, por favor.

Una situación

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Bichos, errores, preguntas

fxsaber, 2018.06.20 23:18

Decidí comprobar cuánto duran estas situaciones de pedidos fantasmas, cuando un pedido está en el sistema pero no en la Terminal.

// Советник отслеживает длительность ситуаций, когда ордер отсутствует среди текущих и исторических

#define  TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define  TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

bool OrderIsExist( const ulong &OrderTicket )
{
  return(OrderTicket ? OrderSelect(OrderTicket) || HistoryOrderSelect(OrderTicket) : true);
}

void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest&, const MqlTradeResult& )
{
  static bool PrevIsExist = true;
  static ulong StartTime = 0;
  static ulong MaxInterval = 0;
  
  const ulong NowTime = GetMicrosecondCount();
  const bool IsExist = OrderIsExist(Trans.order);
    
  if (!IsExist)
  {
    Print(TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
  
    if (PrevIsExist) 
      StartTime = NowTime;
  }
  else if (!PrevIsExist)
  {
    const ulong Interval = NowTime - StartTime;
    
    Print(TOSTRING(Interval) + TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
    
    if (Interval > MaxInterval)
    {
      MaxInterval = Interval;
      
      Comment(TOSTRING(MaxInterval) + TOSTRING(Trans.order)); // mcs.
    }
  }
          
  PrevIsExist = IsExist;
}


Resultado

2018.06.21 00:10:31.047 Trans.type = TRADE_TRANSACTION_ORDER_DELETE (2)
2018.06.21 00:10:31.047 Trans.order = 2210967406
2018.06.21 00:10:31.047 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 HistoryOrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 
2018.06.21 00:10:31.080 Interval = 32643
2018.06.21 00:10:31.080 Trans.type = TRADE_TRANSACTION_HISTORY_ADD (3)
2018.06.21 00:10:31.080 Trans.order = 2210967406
2018.06.21 00:10:31.080 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.080 HistoryOrderSelect(Trans.order) = true


¡32 milisegundos una orden está ahí pero no en el Terminal! Imagínese las consecuencias si la lógica comercial se ejecutara en este intervalo...


Es interesante que las órdenes fantasma se presentan con mayor frecuencia sólo en los tipos de transacciónTRADE_TRANSACTION_ORDER_DELETE y en TRADE_TRANSACTION_DEAL_ADD (mucho más raro).


Muy mal el matiz de la plataforma.


ZZY velocidad cuestionable de las transacciones comerciales en 5, por desgracia.


Segundo

abriendo una posición y OrdersTotal ha aumentado en uno.

  • Se ejecutó y OrdersTotal disminuyó en uno, pero PositionsTotal no aumentó en uno. En otras palabras, hay una posición, pero la Terminal no lo sabe.
  • Por ejemplo, no hay posiciones ni órdenes - PositionsTotal = 0, OrdersTotal = 0.

    Se establece una orden de mercado. PosicionesTotal = 0, PedidosTotal = 1.

    La orden de mercado se ejecuta - OrdersTotal = 0. ¡Pero PositionsTotal = 0!

     
    Илья Ребенок:

    Se me olvidó añadir que el modo es de red. La posición es la misma para todos los robots.

    No importa. La posición siempre tiene una entrada, pero también se puede seleccionar por símbolo. Puede que tengas que añadir una comprobación del volumen de operaciones o algo más. Por ejemplo, seleccione las órdenes y las operaciones de una posición y agítelas para encontrar la correcta. Pero un trato es un trato... Y nadie garantiza la coherencia de las transacciones. No hace mucho tiempo se advirtió de la posible pérdida de transacciones.


    Teniendo en cuenta la adición en su puesto, todo está mal. En ese caso, hay que investigar con más detenimiento.

     
    Илья Ребенок:

    He intentado diferentes enfoques, pero nada funciona.

    Escriba una acción simple que necesite ser implementada.

     
    fxsaber:

    Una situación


    Segundo

    Gracias, lo leeré, pero a primera vista confirma mi suposición.

    Alexey Viktorov:

    No importa. La posición siempre tiene una entrada, pero también se puede seleccionar por símbolo. Es posible que tenga que añadir una comprobación del volumen de transacciones o algo más. Por ejemplo, seleccione las órdenes y las operaciones de una posición y agítelas para encontrar la correcta. Pero un trato es un trato... Y nadie garantiza la coherencia de las transacciones. No hace mucho tiempo se advirtió de la posible pérdida de transacciones.


    Teniendo en cuenta la adición en su puesto, no todo encaja. En ese caso, hay que investigar con más detenimiento.

    Vi un post sobre la pérdida de transacciones, pero los moderadores de allí dijeron que era una reliquia del pasado y se olvidaron de quitarlo de la documentación.

    fxsaber:

    Escriba una acción simple para ser implementada.

    No entiendo muy bien lo de escribir una acción simple) Por favor, explíquelo.

     
    Илья Ребенок:


    Vi un post sobre la pérdida de transacciones, pero los moderadores allí dijeron que era una reliquia del pasado y se olvidaron de quitarlo de la documentación.

    Lo hicieron, pero no fue hace mucho tiempo.

     
    Илья Ребенок:

    No entiendo muy bien lo de escribir una acción simple) Explique por favor.

    ¿Cuál es el objetivo de la negociación?

     
    fxsaber:

    ¿Cuál es su objetivo comercial?

    Colocamos órdenes limitadas, y cuando se activan, colocamos una orden de stop y una orden de toma de beneficios. Cuando se dispara una orden de stop, eliminamos el take profit y viceversa. En el comentario de la orden de stop y take profit se escribe la entrada límite inicial, en base a la cual establecemos la orden de stop y take profit. Por eso es importante obtener los comentarios de las órdenes para que, cuando se dispare una orden de stop, se pueda encontrar el take profit con el mismo comentario y eliminarlo.

    Dado que nuestro robot nos permite rellenar posiciones, también debemos colocar una orden de stop y una de take profit y dejar un comentario con la entrada de take profit cuando compremos más posiciones.

    ¿Puede ser un sueño de 1 segundo una buena idea? Tener tiempo para todas las transaccionesTRADE_TRANSACTION_ORDER_DELETE yTRADE_TRANSACTION_HISTORY_ADD

    Общие принципы - Торговые операции - MetaTrader 5
    Общие принципы - Торговые операции - MetaTrader 5
    • www.metatrader5.com
    Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит...
     

    Илья Ребенок:

    El robot permite el escalamiento, por lo que cuando compramos más, también colocamos una orden stop y una take profit, y registramos el escalamiento en el comentario del ticket

    ¿Podemos tener >=2 órdenes de compra y de stop al mismo tiempo?

    Razón de la queja: