Modificación en dos etapas de posiciones abiertas

Genkov | 13 abril, 2016

  if(OrderStopLoss()>=OrderOpenPrice()) // StopLoss is on a lossless level
   {    // calculate correction coefficient
    double Coeff_up = NormalizeDouble((Bid-OrderOpenPrice())*0.382,Digits);
    // and if the differnece between the current and the open price of the position is greater than corr. coefficient 
    if(Bid-OrderOpenPrice()>Coeff_up) 
     {    // calculate the value of new StopLoss with the margin of 2 points
      double New_S_Loss = Bid-Coeff_up-2*Point;
      // and if the value of new StopLoss is higer than the current one
      if(New_S_Loss-OrderStopLoss()>3*Point)
       {     // move S/L and T/P
        OrderModify(OrderTicket(),OrderOpenPrice(),
        New_S_Loss,OrderTakeProfit()+Step*Point,0,Yellow);
        }
//        Print(" Bid-OrderOpenPrice()= ",Bid-OrderOpenPrice());
//        Print("  2   Coeff_up= ",Coeff_up," Order_S_Los= ",New_S_Loss," Bid= ",Bid);
       return;
       }
      }
     }

Introducción

El artículo llamado "Método de T.DeMark para el análisis técnico" contiene los coeficientes recomendados para la longitud de corrección, en particular 0.382 y 0.618. El uso de estos coeficientes durante la apertura de posiciones nos permite evitar las situaciones innecesarias de cierre y reapertura de posiciones en situaciones cercanas a la tendencia. La función funciona bien, especialmente cuando se produce una situación de divergencia.

Este método, siempre que se reinicie el valor del beneficio, ayuda a detectar la aparición de una tendencia "favorable". Por ejemplo, como se muestra en la Fig. 1 y comparada con la Fig. 2.




Algoritmo de la función

La primera modificación de la orden se realiza por el valor especificado TrailingStop, las posteriores establecen StopLoss más pequeñas que el nivel de corrección posible en 1 o 2 puntos (en este caso el coeficiente de corrección = 0,382 "Coeff_"). Incrementar el valor de TakeProfit en cada paso en, por ejemplo, la mitad del valor de TrailingStop (puede elegir también cualquier otro valor). El valor de TakeProfit también puede cambiarse. Para ello, debe establecerse el valor cero de March = 0 doble externo del operador al comienzo del programa.

Sería más inteligente para los traders que prefieren el análisis y soporte de la dirección de acciones específicas del programa que se realizara directamente durante el trading para transferir la variable MagicNumber al propio código del asesor experto donde la posición es abierta. Puede leer más información en detalle sobre la ayuda sobre la dirección específica en el libro de S. Kovalyov publicado en el sitio web de MQL4.com.


Vamos a analizar el código recomendado de la función prospectiva en el asesor experto y los comentarios en detalle:

//+------------------------------------------------------------------+
//|      Two-stage variant of TrailingStop       Modify_2step v5.mq4 |
//|   Orders modification: re-placing StopLoss and TakeProfit        |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, GenKov"
#property link      Genkov@bk.ru
//+------------------------------------------------------------------+

/* Magic=N

Magic=N - Este operador debe insertarse durante la apertura de la posición justo después del operador de control del cumplimiento de la condición en el propio programa (asesor experto) y en la función. No puede crear un modificador universal, puede que debido a que el mercado no es predecible, según me parece a mí, por lo que la función de seguimiento (movimiento de S/L y T/P) y las condiciones de cierre de la posición deben escribirse para cada tipo de condición de apertura de la posición (en Magic=N).

extern double    March         =  1;  // step of increasing TakeProfit 
                                      // step 0 doesn't increase T/P.

S/L debe ser inferior a TrailingStop en un punto para llevar S/L a un nivel seguro en la primera activación. De esta manera, nos aseguramos frente a posibles pérdidas (gestión del capital).

extern double    StopLoss      = 15;  
extern double    TrailingStop  = 16;  
extern double    TakeProfit    = 60;  // fitting with the tester
//+------------------------------------------------------------------+
//void TrailingStop()
  int start()                                   
   {
   //----------------------------------------------------------------+
   int point  = MarketInfo(Symbol(),MODE_POINT);      // Point size 
   int StopLev= MarketInfo(Symbol(),MODE_STOPLEVEL);  
   double half_Trail = MathRound(TrailingStop/2);//half TrailingStop
   double Step = March*half_Trail;  //value of TakeProfit increase
  if (TrailingStop<0) return;
   { 
   for (int i=0; i<OrdersTotal(); i++)
    {
    if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
    if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
    if (OrderType()==OP_BUY)
     {

Primera etapa de la modificación de la posición BUY

if(OrderStopLoss()<OrderOpenPrice())//if S/L is less than the order open price
      {   // and if the difference between the current price and the position opening price is greater than T/S
      if(Bid-OrderOpenPrice()>TrailingStop*Point) // && 
       {     // and if OrderStopLoss() is less than the difference between the current price and T/S
       if(OrderStopLoss()<Bid-TrailingStop*Point)
        {    // calculate new T/P value
        double Now_T_P=(OrderTakeProfit()+Step*Point);
       { 
       OrderModify(OrderTicket(),OrderOpenPrice(),
       OrderStopLoss()+TrailingStop*Point,
       OrderTakeProfit()+Step*Point,0,Aqua); // increasing T/P value
      return;
      }
     }
    }
   }

No obstante, puede producirse la siguiente situación: el cambio de TakeProfir se hace 2-3 puntos superior que el nivel de beneficio previsto anteriormente y las paradas y los inicios disminuyen lentamente.



Para evitar perder beneficios, vamos a introducir el operador de control de la situación que cerrará la orden en el nivel de beneficio previsto. Si el precio sigue creciendo, el cambio de StopLoss y TakeProfit continuará.

if(Bid-OrderOpenPrice()>=TakeProfit*Point && (Pr_Op_1-Pr_Op_0)>2*Point) 
   {
    // Print(" Bid= ",Bid," >= ",OrderTakeProfit()," Magic= ",Magic);
    OrderClose(OrderTicket(),Lots,Bid,2,Red);
    }

// Second stage of BUY position modification

El método de la posición corta es el mismo que el descrito anteriormente, por lo que hay menos comentarios.

// ---------------------------- 1 stage of modification -----SELL-------------&
   else  if(OrderType()==OP_SELL) 
    {
   if(OrderStopLoss()>OrderOpenPrice())//if S/L is greater than order open price
     {
     if(OrderOpenPrice()-Ask>TrailingStop*Point && 
        OrderStopLoss()>Ask+TrailingStop*Point)
     { 
      OrderModify(OrderTicket(),OrderOpenPrice(),
      Ask+TrailingStop*Point,OrderTakeProfit()-Step*Point,0,SkyBlue);
      return;
      }
     }
if(OrderOpenPrice()-Ask>=TakeProfit*Point && (Pr_Op_0-Pr_Op_1)>2*Point) 
   {
    OrderClose(OrderTicket(),Lots,Bid,2,Red);
    }     
// ---------------------------- 2 stage of modification -----SELL-------------&
   if(OrderStopLoss()<=OrderOpenPrice()) // StopLoss is on a lossless level
    { // calculate correction coefficient
     double Coeff_down = NormalizeDouble((OrderOpenPrice()-Ask)*0.382,Digits);
     // and if the difference between the price of position opening and the current price is greater than corr. coefficient 
    if(OrderOpenPrice()-Ask>Coeff_down) 
     {    // calculate the value of new StopLoss with the margin of 2 points
      New_S_Loss = Ask+Coeff_down+2*Point; 
      // and if the value of new StopLoss is less than the current value
      if(New_S_Loss-OrderStopLoss()>3*Point)
       {     // move S/L and T/P   
       OrderModify(OrderTicket(),OrderOpenPrice(),
       New_S_Loss,OrderTakeProfit()-Step*Point,0,Khaki);
      return;
      }
     }
    }
   }
  } 
 //  -----------------------------------------------------------------------------------

Para convertir este asesor experto en una función, es necesrio comentar la función especial int start() ubicada al comienzo del programa y sustituirla por una descripción sin comentario de la función TrailingStop() situada al comienzo del programa. Llamada de la función sin comentario:

//TrailingStop();

al final del programa.

Si añadimos el bloque representado a continuación podemos comprobar la eficiencia de la función usándola como un asesor experto en el probador.

// --------------------------------------------------------------------------------
  
   double Macd_m15_0= iMACD(NULL,PERIOD_M15,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   double Macd_m15_1= iMACD(NULL,PERIOD_M15,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   
   if(OrdersTotal()<2)
    {
    if(Macd_m15_0<Macd_m15_1)
     {
     OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+StopLoss*Point,Bid-TakeProfit*Point,"",Magic,0,Red);
     }
    if(Macd_m15_0>Macd_m15_1)
     {
     OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Bid-StopLoss*Point,Ask+TakeProfit*Point,"",Magic,0,Blue);
     }
    return(0);
   }
// --------------------------------------------------------------------------------
//  TrailingStop();
  }
   return(0);
  }
// --- end --- &

Ahora eliminamos los comentarios detallados del texto del código mencionado anteriormente y lo formamos como una función de ejecución: obtendremos el archivo ejecutable que se recomienda guardar en el directorio terminal_folder\experts\include con la extensión .mqh o en el directorio terminal_folder\libraries con la extensión mq4.



//+------------------------------------------------------------------+
//|                                             Modify_2_Step v5.mq4 |
//|                                         Copyright © 2008, GenKov |
//|                                                     Genkov@bk.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, GenKov"
#property link      "Genkov@bk.ru"
extern double    March         =  1;  // the step of TakeProfit increase
                                      // "0" step doesn't increase T/P.
// S/L must be less than TrailingStop by 1 point to bring the S/L  
// on a safe level in the time of the very first triggering
extern double    StopLoss      = 15;  
extern double    TrailingStop  = 16;
extern double Lots             = 0.1;  
extern double    TakeProfit    = 60;  // fitting with the tester
void TrailingStop()
  {
   int Magic=3090;  //  number of condition that opens position
   int point  = MarketInfo(Symbol(),MODE_POINT);      // Point size 
   int StopLev= MarketInfo(Symbol(),MODE_STOPLEVEL);  
   double half_Trail = MathRound(TrailingStop/2);//half TrailingStop
   double Step = March*half_Trail;  //TakeProfit-а increase size
  if (TrailingStop<0) return;
   { 
   for (int i=0; i<OrdersTotal(); i++)
    {//1 +cycle by orders search
    if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
    if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
    if (OrderType()==OP_BUY)
     {
// --------------------------- 1 stage of modification -----BUY-------------&     
    if(OrderStopLoss()<OrderOpenPrice())//if the S/L is less than the order open price
      {   // and if the difference between the current and the open price is greater than T/S
      if(Bid-OrderOpenPrice()>TrailingStop*Point) // && 
       {     // and if OrderStopLoss() is less than the difference between current price andT/S
       if(OrderStopLoss()<Bid-TrailingStop*Point)
        {    // calculate new T/P value
        double Now_T_P=(OrderTakeProfit()+Step*Point);
       { 
       OrderModify(OrderTicket(),OrderOpenPrice(),
       OrderStopLoss()+TrailingStop*Point,
       OrderTakeProfit()+Step*Point,0,Aqua); // increase T/P value
      return;
      }
     }
    }
   }
  if(Bid-OrderOpenPrice()>=TakeProfit*Point) 
   {
    OrderClose(OrderTicket(),Lots,Bid,2,Red);
    }
//------------------------- 2 stage of modification -----BUY---------------&
  if(OrderStopLoss()>=OrderOpenPrice()) // StopLoss is on the lossless level
   {    // calculate correction coefficient
    double Coeff_up = NormalizeDouble((Bid-OrderOpenPrice())*0.382,Digits);
    // and if the difference between the current and the position price is greater than correction coefficient
    if(Bid-OrderOpenPrice()>Coeff_up) 
     {    // clculate new StopLoss value with the margin of 6 points
      double New_S_Loss = Bid-Coeff_up-6*Point-StopLev*Point;
      // if the value of new StopLoss is greater than the current value
      if((New_S_Loss-OrderStopLoss())<2*Point)
       {     // move S/L and T/P
        OrderModify(OrderTicket(),OrderOpenPrice(),
        OrderStopLoss(),OrderTakeProfit()+Step*Point/2,0,Yellow);
        }
        else
        {
         OrderModify(OrderTicket(),OrderOpenPrice(),
        New_S_Loss+1*Point,OrderTakeProfit()+Step*Point,0,Yellow);
        }
       return;
       }
      }
     }
// ---------------------------- 1 stage of modification -----SELL-------------&
  else if(OrderType()==OP_SELL)
    {
   if(OrderStopLoss()>OrderOpenPrice())//if S/L is greater than the order open price
     {
     if(OrderOpenPrice()-Ask>TrailingStop*Point && 
        OrderStopLoss()>Ask+TrailingStop*Point)
     { 
      OrderModify(OrderTicket(),OrderOpenPrice(),
      Ask+TrailingStop*Point,OrderTakeProfit()-Step*Point,0,SkyBlue);
      return;
      }
     }
if(OrderOpenPrice()-Ask>=TakeProfit*Point) 
   {
    OrderClose(OrderTicket(),Lots,Bid,2,Red);
    }     
// ---------------------------- 2 stage of modification -----SELL-------------&
   if(OrderStopLoss()<=OrderOpenPrice()) // StopLoss is on the lossless level
    if(OrderOpenPrice()-Ask>=OrderTakeProfit()) OrderClose(OrderTicket(),Lots,Ask,2,Red);   
    { // calculate correction coefficient
     double Coeff_down = NormalizeDouble((OrderOpenPrice()-Ask)*0.382,Digits);
     // and if the difference between the position open price and the current price is greater than corr. coefficient
    if(OrderOpenPrice()-Ask>Coeff_down) 
     {   // calculate the value of new StopLoss with the margin of 6 points
      New_S_Loss = Ask+Coeff_down+6*Point; 
      // and if the value of new StopLoss is less than the current value
      if((OrderStopLoss()-New_S_Loss-StopLev*Point)>=10*Point)
       {    // move S/L and T/P
       OrderModify(OrderTicket(),OrderOpenPrice(),
       New_S_Loss-5*Point,OrderTakeProfit()-Step*Point,0,Khaki);
      return;
      }
     }
    }
   }
  } 
return(0);
}
}
// ---end----- void TrailingStop()--------------------------------&
  // this block is only for error controlling in the function code
  //  int start()  
  //   {
  //    if(25>26) TrailingStop();
  //    }
  // --------------------------------


Conclusión

Debe decirse que, en comparación con la "ejemplar trailing-stop" descrita en el artículo "Una plantilla Trailing Stop y de salida del mercado" de Sergey Kravchuk, la versión recomendada es más fácil de comprender y ahora ha funcionado en mi asesor experto (a decir verdad, en una cuenta demostración) y, creo, que se ajusta al trailing agresivo y moderado.

Las versiones adjuntas:

v4 - con cierre de S/L; v5 - con cierre previsto de T/P; v6 - con una mirada en la ayuda a la predicción y dirección por el número mágico.