Preguntas de los principiantes MQL5 MT5 MetaTrader 5 - página 713

 
dimnik:
¿Pueden decirme cómo saber el resultado de la última o las últimas operaciones?

Hay dos maneras:

utilizarOnTradeTransaction() directamente en el Asesor Experto y capturar las operaciones que se han registrado en el historial.

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      double   deal_profit       =0.0;
      double   deal_volume       =0.0;
      string   deal_symbol       ="";
      long     deal_magic        =0;
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_profit=HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
        }
      else
         return;
      if(deal_symbol==Symbol() && deal_magic==m_magic)
         if(deal_entry==DEAL_ENTRY_OUT)
           {
            // здесь ваши действия
           }
     }
  }

o para referirse al historial de operaciones, por ejemplo, algo así:

//+------------------------------------------------------------------+
//|                                               HistorySelect.mq5  |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Реверс позиции и исследование \"DEAL_POSITION_ID\" истории сделок"
#property script_show_inputs
//---
input datetime start=D'2016.08.05 09:00:00';
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   if(AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      Print("This script cannot be run on a hedge; Этот скрипт нельзя запускать на хедж");
      return;
     }
   Print_IDs();
  }
//+------------------------------------------------------------------+
//| List all positions and deals                                     |
//+------------------------------------------------------------------+
void Print_IDs(void)
  {
//--- запрашиваем историю сделок и ордеров за указанный период серверного времени
   HistorySelect(start,TimeCurrent()+86400);
   uint     total    =HistoryDealsTotal();   // количество сделок в истории
   ulong    ticket   =0;                     // тикет сделки в истории
   long     type     =0;                     // тип сделки
   long     deal_id=0;   // идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка
   double   volume   =0.0;                   // объём сделки
   double   profit   =0.0;                   // финансовый результат сделки
   double   price    =0.0;                   // цена сделки
   string   symbol   =NULL;                  // имя символа, по которому произведена сделка
   long     entry    =0;                     // направление сделки – вход в рынок, выход из рынка или разворот
//--- for all deals
   for(uint i=0;i<total;i++)
     {
      //--- try to get deals ticket
      if((ticket=HistoryDealGetTicket(i))>0)
        {
         //--- get deals properties
         type     =HistoryDealGetInteger(ticket,DEAL_TYPE);
         deal_id  =HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
         volume   =HistoryDealGetDouble(ticket,DEAL_VOLUME);
         profit   =HistoryDealGetDouble(ticket,DEAL_PROFIT);
         price    =HistoryDealGetDouble(ticket,DEAL_PRICE);
         symbol   =HistoryDealGetString(ticket,DEAL_SYMBOL);
         entry    =HistoryDealGetInteger(ticket,DEAL_ENTRY);
         Print(EnumToString((ENUM_DEAL_ENTRY)entry),
               ", type ",EnumToString((ENUM_DEAL_TYPE)type),
               ", price ",DoubleToString(price,Digits()),
               ", Deal ",symbol," volume ",DoubleToString(volume,2),
               ", DEAL_POSITION_ID #",deal_id,
               ", profit ",DoubleToString(profit,2));
        }
     }
   Print("");
  }
//+------------------------------------------------------------------+


Dependiendo del método que elija, tendrá que editar un poco el código para obtener información sobre la última operación.

Archivos adjuntos:
 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
     {
       if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
       if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
     }  
    
  }

El manejador de eventos mantiene un registro de todas las operaciones con los magos de EA.

Pero por alguna razón, la primera operación siempre obtiene un mago equivocado (cero), mientras que las siguientes operaciones están bien.

¿Cómo lo corrijo? ¿O tal vez debería hacerlo de otra manera?

 
dimnik:
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
     {
       if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
       if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
     }  
    
  }

El manejador de eventos monitorea todas las operaciones con los magos de EA.

Pero por alguna razón, la primera operación siempre obtiene un mago equivocado (cero), mientras que las siguientes operaciones están bien.

¿Cómo lo corrijo? ¿O tal vez debería hacerlo de otra manera?

Hayque dejar de operar con órdenes: es un sistema anticuado. Entonces todo saldrá bien. "TRADE_TRANSACTION_DEAL_ADD" - añadir la transacción al historial. Esto se hace como resultado de la ejecución de una orden o de las operaciones de saldo de la cuenta. ¿Qué más necesitas? El acuerdo se ejecutó y quedó registrado en la historia.
 
dimnik:

El manejador de eventos mantiene un registro de todas las operaciones con los magos de EA.

Pero por alguna razón, para el primer comercio el mago (recibido a través de chistoriorder) es siempre mal (cero), para los siguientes oficios - todo es normal.


para imprimir los parámetros de esta transacción.

¿cuál es el problema de conocer su billete/tipo/símbolo/beneficio?

 
o_O:


así que imprime los parámetros de este acuerdo.

¿cuál es el problema para averiguar su billete/tipo/símbolo/ganancia?

Salidas:

Trato 2, Magia 0, Volumen 0.000000

En general en todas las operaciones muestra un número correcto, pero cero magia y volumen.


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
 
dimnik:

Salidas:

Trato 2, Magia 0, Volumen 0.000000

En general en todas las ofertas da número correcto, pero cero mags y volúmenes.


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());

Añade este código:

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
   long     deal_type         =0;
   long     deal_positions_id =0;
   long     deal_ticket       =0;
   double   deal_volume       =0;
   long     deal_entry        =0;
   long     deal_magic        =0;
   string   deal_symbol       ="";
   string   deal_comment      ="";
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
      deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
      deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
      deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);
      Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
            "D_POSITION_ID: ",deal_positions_id,", ",
            "D_TICKET: ",deal_ticket,", ",
            "D_VOLUME: ",DoubleToString(deal_volume,2),", ",
            "D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
            "_MAGIC: ",deal_magic,", ",
            "D_SYMBOL: ",deal_symbol,", ",
            "D_COMMENT: ",deal_comment);
     }
   else
      return;
  }

y verá qué tipos de transacciones se producen y también verá que con "TRADE_TRANSACTION_DEAL_ADD" se ven tanto la magia como el volumen.


 
Vladimir Karputov:

Añade este código:

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
   long     deal_type         =0;
   long     deal_positions_id =0;
   long     deal_ticket       =0;
   double   deal_volume       =0;
   long     deal_entry        =0;
   long     deal_magic        =0;
   string   deal_symbol       ="";
   string   deal_comment      ="";
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
      deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
      deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
      deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);
      Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
            "D_POSITION_ID: ",deal_positions_id,", ",
            "D_TICKET: ",deal_ticket,", ",
            "D_VOLUME: ",DoubleToString(deal_volume,2),", ",
            "D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
            "_MAGIC: ",deal_magic,", ",
            "D_SYMBOL: ",deal_symbol,", ",
            "D_COMMENT: ",deal_comment);
     }
   else
      return;
  }

y verás qué tipos de transacciones se realizan, y también verás que con "TRADE_TRANSACTION_DEAL_ADD" se ven tanto el magik como el volumen.


Gracias, funciona así.
 
dimnik:

Salidas:

Trato 2, Magia 0, Volumen 0.000000

En general, todas las operaciones dan el número correcto, pero cero números mágicos y volúmenes.


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());

Hace tiempo que me he dado cuenta de que cuando uso la clase CDealInfo, tengo que cargar el historial de ofertas de forma independiente, luego todo funciona bien

   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      HistorySelect(0,TimeCurrent());
       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
     }
 
dimnik:
Gracias, funciona.

Para evitar la impresión de todos los tipos de transacciones, haga la siguiente condición en OnTradeTransaction:

//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   if(type!=TRADE_TRANSACTION_DEAL_ADD)
      return;

   long     deal_type         =0;

es decir, si el tipo de transacción no es "TRADE_TRANSACTION_DEAL_ADD" - entonces salga.

Si necesitamos seguir la colocación (no la activación, sólo la colocación) de una orden pendiente, OnTradeTransaction tomará esta forma:

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_ORDER_ADD)
     {
      long     order_type        =0;
      double   order_price       =0.0;
      double   order_volume      =0.0;
      string   order_symbol      ="";
      long     order_magic       =0;
      if(OrderSelect(trans.order)) // select pending orders
        {
         order_type=OrderGetInteger(ORDER_TYPE);
         order_price=OrderGetDouble(ORDER_PRICE_OPEN);
         order_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
         order_symbol=OrderGetString(ORDER_SYMBOL);
         order_magic=OrderGetInteger(ORDER_MAGIC);
        }
      else
         return;
      if(order_symbol==m_symbol.Name() && order_magic==m_magic)
        {
         if(order_type==ORDER_TYPE_BUY_LIMIT)
           {
            //
           }
         if(order_type==ORDER_TYPE_SELL_LIMIT)
           {
            //
           }
        }
     }
  }
 

Con el uso de OnTradeTransaction, el tiempo de optimización ha cambiado extrañamente. Un sistema en 15M, muy simple, historia anual, una carrera se produce en 0,3 - 0,4 segundos.

Tras el inicio de la optimización, las primeras 200-300 carreras van a menos de un segundo, las siguientes se ralentizan hasta 15-20 segundos (¡50 veces!);

No hay sobrecalentamiento ni trote del procesador, más de la mitad de la memoria está libre (de 16GB).

Antes de usar el manejador OnTradeTransaction no había nada de eso - incluso los EAs más complejos en marcos de tiempo pequeños se optimizaban con aproximadamente la misma velocidad en cada ejecución.

¿Afecta tanto a la velocidad HistoryDealSelect? ¿Cómo podemos eliminar los retrasos?

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if( trans.type != TRADE_TRANSACTION_DEAL_ADD) return;
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   long     deal_type         =0;
   double   deal_volume       =0;
   long     deal_magic        =0;
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
     }
   else
      return;
   if (deal_type == DEAL_TYPE_BUY && deal_magic == MagicNumber) current_position += deal_volume;
   if (deal_type == DEAL_TYPE_SELL && deal_magic == MagicNumber) current_position -= deal_volume;
      
  }
Razón de la queja: