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

 

mql5 (cobertura)

¿Cómo implementarun algoritmo de cierre de posiciones bajo dos condiciones?

1 caso. Si hay 2 posiciones abiertas, entonces cierra la que tenga más beneficio que... 2 caso. Si hay 2 o más posiciones abiertas, entonces cierra promediando sobre el valor de...

Ahora tengo dos métodos para cerrar estas posiciones,

Para el caso 1 compare las posiciones por beneficio y cierre la que tenga más beneficio, para el caso 2 cierre todas las posiciones por Renta Variable, promediando.

Estos métodos funcionan bien por separado, pero no juntos, porque uno de los dos eventos cae bajo la distribución de ambos métodos.

No consigo separarlos. Como resultado, ambos casos se cierran en su mayoría sobre la equidad con el cierre de todas las posiciones. Esto hace que en el primer caso se borre la posición deseada y se vuelva a abrir.

Como resultado. Doble difusión, doble comisión. Es frustrante))

El esquema de fijación de órdenes y posiciones es el siguiente: Para VENDER (y además sólo para VENDER).

Orden de límite. SELL_LIMIT

posición. VENDER(siempre entre órdenes)

Orden de detención.SELL_STOP

Adjunto el gráfico.

Cierre de posiciones.

1. Si se activa una orden de stop, es decir, si aparecen dos o más posiciones al mismo tiempo, debe cerrar una posición que tenga un beneficio mayor que... (20)

2. si se ha disparado una orden de Límite, es decir, se abren dos o más posiciones simultáneamente, su valor medio (por Equidad) debe cerrarse... (15)

Pregunta. ¿Cómo separar estos dos métodos, para que manejen sólo su propio evento?

¿Tal vez haya algún otro método para manejar estas dos condiciones?

Ejemplos de métodos que utilizo.

//+---------------------------------------------------------------------+
//|  -- ЗАКРЫВАЕМ ОДНУ ИЗ ДВУХ ПОЗИЦИЙ С НИЗУ, ГДЕ ПРОФИТ БОЛЬШЕ ЧЕМ ---|
//+---------------------------------------------------------------------+ 
ulong ticket_n=ULONG_MAX;  double profit=DBL_MIN;

     if(invert_close == true) //Проверка на наличие 2х и более поз.
     {
     int positions=PositionsTotal();
     for(int i=PositionsTotal()-1; i>=0; i--)
     {
     ulong tmp_ticket=PositionGetTicket(i);
     if(ticket_n!=0)
     {
     double tmp_profit=PositionGetDouble(POSITION_PROFIT);
     if(tmp_profit>profit+Prof_eqw_niz)// допустим 20
     {
     ticket_n=tmp_ticket;
     profit=tmp_profit;
     }
     }
     }
//-----------
     if(ticket_n!=ULONG_MAX)
     m_trade.PositionClose(ticket_n);
     invert_close = false;
     Print("------  ЗАКРЫЛИ ТОЛСТУЮ ---------");
     }       

//+---------------------------------------------------------------------+
//|                     Э К В И Т И   ДЛЯ SELL_LIMIT                    |
//+---------------------------------------------------------------------+
   npos_ALL=0; NPos_ALL(npos_ALL);
   if (npos_ALL>=Metod_Eqw && m_account.Equity()>= m_account.Balance()+Prof_eqw)//Допустим 15
   {
   CloseAllPositions();
   Print("------  ЗАКРЫЛИ ВСЕ ---------");
   }
Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
Archivos adjuntos:
 
Vladpedro:


¿Se abren posiciones por el símbolo sobre el que trabaja el EA? ¿Se utiliza el número mágico?
 
Vladimir Karputov:
¿Se abren posiciones por el símbolo sobre el que trabaja el EA? Se utiliza el número mágico

Sí, por el símbolo actual. Sí, se utiliza el magik.

 
Vladpedro:

Sí, por el personaje actual. Sí se usa el magik.

Explique la segunda condición, ¿qué significa?(Si hay 2 o más posiciones abiertas, entonces cierra haciendo un promedio sobre el valor... )

 
Vladimir Karputov:

Explica la segunda condición, ¿qué significa?(Si hay 2 o más posiciones abiertas, cierra promediando sobre el valor... )

Significa: Si dos o más posiciones están abiertas y la Equidad es mayor que el saldo por cualquier valor (digamos 15), entonces todas las posiciones están cerradas.

Por ejemplo, se abren tres posiciones. La primera tiene una pérdida actual de -10, la segunda tiene un beneficio de -5, la tercera tiene un beneficio de +30 y en total +15, todas las posiciones se pueden cerrar.

Si no se alcanza un beneficio medio de +15, las posiciones se cerrarán por su propio SL o TP preestablecido. (Esta es una especie de tercera condición para cerrar posiciones, pero no hay problemas con ella, así que la he omitido).

 
Vladpedro:

Esto significa: Si dos o más posiciones están abiertas y la Equidad es mayor que el balance por cualquier valor (digamos 15), entonces todas las posiciones serán cerradas.

Por ejemplo, hay tres posiciones abiertas. La primera tiene una pérdida actual de -10, la segunda tiene un beneficio de -5, la tercera tiene un total de +30+ de +15, todas las posiciones se pueden cerrar.

Si no se ha alcanzado un beneficio medio de +15, las posiciones se cerrarán por su propio SL o TP preestablecido. (esto es algo así como la tercera condición para cerrar posiciones, pero no hay ningún problema con ello, por eso lo he omitido).

Aquí está el código completo para dos condiciones:

//+------------------------------------------------------------------+
//|                                       Closing Two conditions.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.00"
/*
   barabashkakvn Trading engine 3.116
*/
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
//--- input parameters
input double   InpProfitTarget      = 15;       // Profit target, in deposit money (if Positions > 2)
input ulong    InpDeviation         = 10;       // Deviation, in points (1.00045-1.00055=10 points)
input ulong    InpMagic             = 200;      // Magic number
//---
bool     m_need_close_all           = false;    // close all positions
ulong    m_need_close_ticket        = ULONG_MAX;// close one position
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
   m_trade.SetDeviationInPoints(InpDeviation);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(m_need_close_all)
     {
      if(IsPositionExists())
        {
         CloseAllPositions();
         return;
        }
      else
         m_need_close_all=false;
     }
//---
   if(m_need_close_ticket!=ULONG_MAX)
     {
      //--- close one position
      if(m_position.SelectByTicket(m_need_close_ticket))
        {
         m_trade.PositionClose(m_need_close_ticket); // close a position
         return;
        }
      else
         m_need_close_ticket=ULONG_MAX;
     }
//--- calculate all positions
   int total=0;
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            total++;

   if(total==2)
     {
      //--- conditon 1
      ulong tmp_ticket=ULONG_MAX;
      double tmp_profit=DBL_MIN;
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
            if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
              {
               double profit=m_position.Commission()+m_position.Swap()+m_position.Profit();
               if(profit>tmp_profit)
                 {
                  tmp_profit=profit;
                  tmp_ticket=m_position.Ticket();
                 }
              }
      //---
      if(tmp_ticket!=ULONG_MAX)
         m_need_close_ticket=tmp_ticket;
     }
   else
     {
      if(total>2)
        {
         //--- conditon 2
         double profit=0;
         for(int i=PositionsTotal()-1; i>=0; i--)
            if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
               if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
                  profit+=m_position.Commission()+m_position.Swap()+m_position.Profit();
         //---
         if(profit>=InpProfitTarget)
            m_need_close_all=true;
        }
     }
  }
//+------------------------------------------------------------------+
//| Is position exists                                               |
//+------------------------------------------------------------------+
bool IsPositionExists(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            return(true);
//---
   return(false);
  }
//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void CloseAllPositions(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            m_trade.PositionClose(m_position.Ticket()); // close a position by the specified m_symbol
  }
//+------------------------------------------------------------------+
Archivos adjuntos:
 
Vladimir Karputov:

Aquí está el código completo para las dos condiciones:

Gracias Vladimir. Intentaré averiguarlo.

Traté de resolverlo a mi manera, entiendo cómo se pueden separar estas dos condiciones.

Por ejemplo.

Vamos a declarar tres variables lógicas.

Pos_1;

Pos_2_Clos_1;

Pos_2_Clos_All;

1. Compruebe el número de puestos abiertos.

Si sólo tenemos una posición abierta, la venta se establece en :

Pos_1=true ; Pos_2_Clos_1=false; Pos_2_Clos_All=false;

Si hay 2 posiciones abiertas y el importe de la equidad es positivo (esto sólo puede ocurrir cuando se activa la orden SELL_STOP), asigne un valor lógico a este evento

Pos_1=false ; Pos_2_Clos_1=true; Pos_2_Clos_All=false;

Si se abren 2 posiciones y el importe del capital es negativo (esto sólo puede ocurrir cuando se activa una orden SELL_LIMIT), entonces

Pos_1=false ; Pos_2_Clos_1=false; Pos_2_Clos_All=true;

Eso parece ser todo... Puedes comprobar las variables lógicas y asignarlas a tu método de cierre, pero por alguna razón no me funcionó...

Soy un pésimo programador aún, tal vez me equivoqué en alguna parte...

Gracias por la ayuda)

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

Vladimir Karputov:

Vladimir, estoy teniendo problemas con esto. Cuando se disparan las órdenes SELL_STOP, todo está bien. Sólo se cierra una posición con mayor beneficio,

Pero cuando se activa SELL_LIMIT, todo se cierra incorrectamente, no por la suma de todas las posiciones abiertas sino que parece que se cierra la posición con mayor beneficio.

Antes tenía un error similar, ahora empiezo a pensar, que tal vez sea culpa mía, que no calcule y abra posiciones correctamente.

Por favor, compruebe mi código listo para la prueba y vea si tiene errores, pero tal vez hay algunas inconsistencias en su código también, o tal vez no he explicado correctamente ... ¿Cuál es el beneficio medio para mí?

Ahora he empezado a analizar el algoritmo y me he dado cuenta de que es un poco más complicado en sus consecuencias de lo que os he contado antes.

La tercera condición cuando se cierra una posición por su SL puede causar errores en el algoritmo de las dos primeras condiciones.

Una vez más describiré el algoritmo completo de cierre de posiciones sólo para el caso SELL_LIMIT ya que el caso SEL_STOP se ejecuta correctamente. Dejémoslo por ahora.

1. Inicialmente tenemos una posición abierta SELL que tiene especificado el SL pero es mayor que SELL_LIMIT, lo que significa que el SL no se va a activar antes de SELL_LIMIT.

2. SELL_LIMIT se ha disparado y hay una segunda posición SELL con su propio SL, que tampoco podrá cerrarse antes del siguiente SELL_LIMIT

Si la orden SELL_LIMIT se ha activado, se ha colocado una nueva orden SELL_LIMIT. (siempre)

4. El número de posiciones SELL_LIMIT abiertas puede serde 1 a 3 o más, todo depende de lo lejos que estén de SL. Considere el caso si hay un máximo de tres. (Puedo limitar esto a SL)

Ahora los escenarios para cerrar posiciones.

Si se trata de puestos abiertos. 2, sólo son posibles dos escenarios para cerrar una o todas las posiciones

1. Por Equidad, si es más que el balance por 15 (todas las posiciones están cerradas), (m_account.Equity()>= m_account.Balance()+15) me refería a cerrar varias posiciones por promedio.

2. Por SL propia (una posición está cerrada).

3. la posición rest ante , ahora tiene que ser limpiada de las condiciones de cierre si se establecieron antes, porque no sabemos qué condición aplicar a ella.

Puede repetir el escenario SELL_LIMIT, o puede bajar a SEL_STOP e ir a otra condición de cierre.

4. Si había tres posiciones, también las cerramos (m_account.Equity()>= m_account.Balance()+15) o una de ellas activará el SL y quedarán dos posiciones.

Aplique esta regla hasta que quede una posición para la que no se hayan definido condiciones de cierre...

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

Vladimir Karputov:

Vladimir, estoy teniendo problemas con esto. Cuando se disparan las órdenes SELL_STOP, todo está bien. Sólo se cierra una posición con mayor beneficio,

Pero cuando se activa SELL_LIMIT, la orden se cierra de forma incorrecta, no por la suma de todas las posiciones abiertas sino que parece que se cierra la posición con mayor beneficio.

Antes tenía un error similar, ahora empiezo a pensar, que tal vez sea culpa mía, que no calcule y abra posiciones correctamente.

Por favor, revise mi código listo para la prueba y ver si usted puede encontrar el error, pero tal vez hay inconsistencia en su código y las condiciones. O tal vez no he explicado correctamente ... ¿cuál es el beneficio medio para mí.

En general, no importa la orden pendiente que se dispara - de hecho, terminamos con una posición y luego calculamos el beneficio de la posición.

 
Vladimir Karputov:

No hay ninguna diferencia en la orden pendiente que se disparó - después de todo, obtenemos una posición y luego contamos el beneficio de la posición

No hay ninguna diferencia. Tengo la sospecha de que hay una diferencia porque al establecer órdenes y posiciones, les he asignado "comentarios" propios a las posiciones y propios a las órdenes. Como resultado, cuando una orden se mueve a una posición, hereda el comentario de la orden.

Luego, cuando comprobamos las posiciones a través de los comentarios, hubo un lío... los comentarios eran diferentes. Lo arreglé.

No he encontrado en su código, o no entiendo cómo se cierran las posiciones para la condición SELL_LIMIT activada por la Equidad.

if(total==2)
   {
//-------------------------------------------------------- conditon 1
      ulong tmp_ticket=ULONG_MAX;
      double tmp_profit=DBL_MIN;
      for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
      if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
      {
      double profit=m_position.Commission()+m_position.Swap()+m_position.Profit();
      if(profit>tmp_profit)
      {
      tmp_profit=profit;
      tmp_ticket=m_position.Ticket();
      }
      }
      //---
      if(tmp_ticket!=ULONG_MAX)
      m_need_close_ticket=tmp_ticket;
      }
      else
      {
      if(total==2)
        {
//--------------------------------------------------------- conditon 2
        double profit=0;
        for(int i=PositionsTotal()-1; i>=0; i--)
        if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
        if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
        profit+=m_position.Commission()+m_position.Swap()+m_position.Profit();
//--------
       if(profit>=InpProfitTarget)
        m_need_close_all=true;
        }
        }

Parece que hemos comprobado si todas las posiciones pueden ser cerradas, y la bandera está fijada para ello

pero en elCloseAllPositions();

if(m_need_close_all)
   {
   if(IsPositionExists())
   {
   CloseAllPositions();
   return;
   }
   else
   m_need_close_all=false;
   }

hay algo que falta.

 if(m_account.Equity()>= m_account.Balance()+15)

No hay comprobación de cierre de todas las posiciones para el caso - SELL_LIMIT se ha disparado

¿Quizás este mismom_account.Equity()>= m_account.Balance()+15está implementado de alguna otra manera?

O tal vez sea porque he interpretado mal lo que quiero decir con "promediar".

Razón de la queja: