English Русский 中文 Deutsch 日本語 Português
Protección contra activaciones erróneas del robot comercial

Protección contra activaciones erróneas del robot comercial

MetaTrader 4Sistemas comerciales | 18 agosto 2016, 16:35
1 253 0
Aleksandr Masterskikh
Aleksandr Masterskikh

Introducción

En este artículo hablaremos de cómo aumentar la estabilidad del funcionamiento del robot comercial eliminando las posibles activaciones repetidas (sacudidas) por diferentes medios: tanto por separado en los algoritmos de entrada y salida, como en la vinculación inversa de estos algoritmos.


Esencia del problema

El problema de las activaciones erróneas se manifiesta de forma especialmente llamativa cuando el mercado se derrumba o tiene saltos bruscos, cuando la amplitud de la vela actual es grande, y en el algoritmo del robot no se prevén medidas especiales contra las sacudidas. Esto se convierte en motivo de aperturas y cierres de posición constantes y consecutivas en la vela actual.

Las consecuencias financieras pueden ser diversas y dependen de los algoritmos concretos que tienen en cuenta los parámetros de mercado implementados por el desarrollador del robot. Pero en cualquier caso, durante las sacudidas, los gastos de spread del tráder aumentan de forma directamente proporcional al número de activaciones.

En este artíclo vamos a estudiar diferentes cuestiones sobre el análisis de instrumentos (de carácter técnico y fundamental), que pueden influir en la estabilidad del funcionamiento del experto comercial y que ayudarán a evitar las sacudidas (esto es un tema aparte, he creado una teoría sobre el equilibrio de impulsos y los sistemas basados en él). Aquí el asunto trata sobre medidas de carácter programático que no dependen directamente de los métodos de análisis de los mercados financieros.

Bien, vamos a pasar a la solución de problemas. Como plantilla para el ejemplo usaré un experto del paquete estándar del que se dispone en el terminal de cliente МetaТrader 4, llamado "MACD Sample".

Este es el aspecto visual que tiene el problema de las sacudidas usando como ejemplo un salto brusco de precio de EURUSD el 2 de octubre de este año (marco temporal М15, experto "MACD Sample" con ajustes por defecto):

En la captura de pantalla se pueden ver 8 activaciones consecutivas (entradas Buy) en una vela. De ellas solo es correcta (desde el punto de vista de una lógica de mercado normal) la primera entrada, las otras 7 son fruto de las sacudidas.

Los motivos de las activaciones erróneas son en este caso:

  • la pequeña magnitud de TakeProfit en los ajustes por defecto (se trata del algoritmo de salida), debido a lo cual la posición se cierra rápidamente;
  • y también el algoritmo de entrada del experto "MACD Sample", que se activa justo depués del cierre de la anterior posición, permitiendo una nueva entrada independientemente del número de entradas en la vela dada.

Ya hemos acordado que las cuestiones de filtrado de las oscilaciones de mercado no las vamos a tener en cuenta de antemano (puesto que cada tráder tiene su algoritmo de entrada y salida), por eso, para resolver el problema y que el uso se universal, analizaremos los siguientes factores de carácter más general:

  • el tiempo (duranción de la vela),
  • el número de activaciones (contador),
  • la amplitud del movimiento (amplitud de la vela).


Solución en el algoritmo de entrada

La variante más sencilla y al mismo tiempo más fiable de fijación del punto de entrada es el factor temporal, los motivos son los siguientes:

  • El contador del número de activaciones presupone la creación de un ciclo en el programa, lo que no solo complica el algoritmo, sino que también reduce la rapidez de acción del asesor experto.
  • La amplitud y los niveles de control de precio relacionados con ella pueden repetirse al darse virajes dentro de la vela, lo que hace los niveles de precio ambiguos.
  • Pero nos encontramos con que el tiempo es irreversible, solo se mueve en una dirección (creciente), y esto significa que es el criterio más exacto y a la vez ambiguo para resolver tareas: posibilitar la activación única y terminar con las sacudidas.

De esta forma el factor principal es el momento de activación del algoritmo de entrada, para ser más exactos, el momento de activación de una orden para la aperura de posición (OrderSend), puesto que estos dos momentos pueden no coincidir en el caso de que se den en el algoritmo algunos retrasos especiales de apertura de la orden.

Bien, es posible registrar el momento (hora actual) al abir una posición. ¿Pero cómo usar este parámetro en el algoritmo de entrada para prohibir la segunda y subsecuentes entradas en esta vela? Ya que no conocemos por anticipado este momento (su magnitud absoluta), no podemos "inscribirlo" de antemano en el algoritmo de entrada. El algoritmo debe tener en cuenta (incluir dentro de sí) una cierta condición general que permitirá la primera entrada en la vela, pero que prohibirá todas las siguientes entradas en la vela, además, sin calcular las activaciones (la variente con contador ya la desechamos antes).

La solución es bastante sencilla. Primero esribiré el código con algunos comentarios, y después lo aclararé todo con más detalle. Aquí tenemos el código adicional (marcado con fondo amarillo), que debemos insertar en el algoritmo del experto (ver el archivo MACD_Sample_plus1.mq4):

//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              https://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"

input double TakeProfit    =50;
input double Lots          =0.1;
input double TrailingStop  =30;
input double MACDOpenLevel =3;
input double MACDCloseLevel=2;
input int    MATrendPeriod =26;
//--- introducimos una nueva variable (magnitud en segundos para la 1 barra de este marco temporal, para М15 es igual a 60 s х 15 = 900 s)
datetime Time_open=900;
//--- introducimos una nueva variable (la hora de apertura de la barra donde se dará la 1 entrada)
datetime Time_bar = 0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   double MacdCurrent,MacdPrevious;
   double SignalCurrent,SignalPrevious;
   double MaCurrent,MaPrevious;
   int    cnt,ticket,total;
//---
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
//---
   if(Bars<100)
     {
      Print("bars less than 100");
      return;
     }
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return;
     }
//--- to simplify the coding and speed up access data are put into internal variables
   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
   MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
   MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);

   total=OrdersTotal();
   if(total<1)
     {
      //--- no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ",AccountFreeMargin());
         return;
        }
      //--- check for long position (BUY) possibility
      
      //--- introducimos una nueva línea (quita la prohibición de nueva entrada si se ha abierto una nueva barra)
      if( (TimeCurrent() - Time_bar) > 900 ) Time_open = 900; 
      
      if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && 
         MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious && 
         (TimeCurrent()-Time[0])<Time_open) //introducimos una nueva línea en el algoritmo de entrada (solo se ejecutará 1 vez, puesto que después la condición en esta vela no se puede cumplir)
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
             {
              Print("BUY order opened : ",OrderOpenPrice());
              Time_open = TimeCurrent()-Time[0]; //introducimos una nueva línea (registramos el intervalo desde la hora de apertura de la barra en la que se dio la entrada hasta el momento de la entrada)
              Time_bar = Time[0]; //introducimos una nueva línea (registramos la hora de apertura de la barra donde se dio la 1 entrada)
             }
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }

Más información:

No usamos la hora absoluta (momento de entrada), sino la relativa, el intervalo de tiempo desde el momento de apertura de la vela actual hasta el momento de entrada. Y a continuación comparamos esta magnitud con la anteriormente establecida, una magnitud de tiempo bastante grande (longitud de toda la vela), lo que permite activarse a la primera entrada. En el momento de apertura de posición cambiamos (disminuimos) la magnitud de la variable Time_open, registrando en su valor el intervalo de tiempo desde el comienzo de la vela hasta el momento de apertura real. Y puesto que en otro momento posterior cualquiera de tiempo, el valor (TimeCurrent() - Time[0]) será mayor a la magnitud registrada por nosotros en el momento de entrada, entonces la condición (TimeCurrent() - Time[0]) < Time_open se hace imposible de cumplir, con lo que se logra el bloqueo de la segunda y posteriores entradas en esta vela.

De esta forma, sin ningún contador del número de entradas y analizando la amplitud de los movimientos de precio, hemos resuelto el problema de las activaciones erróneas.

Aquí tenemos el resultado de esta pequeña modificación añadida al algoritmo inicial de entrada del experto ("MACD Sample_plus1"):

Podemos ver que solo hay una entrada en la vela, no hay activaciones erróneas y las sacudidas se han eliminado por completo. Además, los ajustes por defecto se han guardado por entero para que quede claro que el problema está resuelto sin recurrir a los ajustes del experto.

Ahora que el problema de las sacudidas en la entrada ha sido resuelto, vamos a perfeccionar el algoritmo de salida para excluir las posibles sacudidas que aparecen al cerrar la posición rápidamente, lo que en este caso concreto aumenta los beneficios (si el impulso es bueno, y la salida ha sido rápida, temprana).


Solución en el algoritmo de salida

Puesto que el problema inicial es la eliminación de las posibles sacudidas del robot, y no el aumento de los beneficios, no voy a estudiar cuestiones relacionadas con el análisis de la dinámica de instrumentos financieros en relación con este tema, me limitaré a fijar el parámetro elegido sin tener en cuenta esta dinámica.

Antes hemos usado un parámetro fiable, el factor temporal, ahora lo utilizaremos de nuevo, reglamentando rigurosamente el momento de cierre de la posición según la hora, más concretamente el momento de apertura de la siguiente (después de la entrada) vela. Este momento en el algoritmo de salida lo reflejaremos así:

if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         continue;
      if(OrderType()<=OP_SELL &&   // check for opened position 
         OrderSymbol()==Symbol())  // check for symbol
        {
         //--- long position is opened
         if(OrderType()==OP_BUY)
           {
            //--- should it be closed?
            if(/* MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && // quitamos el código de activación de la salida de MACD, para no dificultar la nueva condición de cierre (ver  a continuación)
               MacdCurrent>(MACDCloseLevel*Point) &&
             */
               Bid > OrderOpenPrice() &&  // introducimos una nueva línea, no obligatoria (precio en la zona positiva con respecto al nivel de entrada)
               TimeCurrent() == Time[0] ) // introducimos una nueva línea (sencillo perfeccionamiento del algoritmo de entrada: salida estrictamente en el momento de apertura de la vela actual)
              {
               //--- close order and exit
               if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))
                  Print("OrderClose error ",GetLastError());

               return;
              }

Esta pequeña modificación permitirá "trabajar" al algoritmo de entrada (la posición se ha abierto, no hay condiciones para el cierre), la posición se prolonga hasta el momento TimeCurrent() == Time[0] y se cierra en un solo momento al inicio de la nueva vela después del impulso. Como resultado, aparte de la protección contra las sacudidas, no hemos ganado poco (mire la foto, "MACD Sample_plus2"):

Además, nos hemos visto obligados a quitar del algoritmo de salida la activación de MACD, de otro modo la condición necesaria de salida no se podría cumplir.

De esta forma, podemos ver cómo se puede resolver el problema de las sacudidas: por separado en el algoritmo de entrada, y por separado en el algoritmo de salida. Ahora hablemos de la solución al problema gracias a la vinculación mutua de estos algoritmos de apertura y cierre de posiciones.


Vinculación de los algoritmos de entrada y salida

La vinculación consiste en un modelado preliminar de todo el proceso: apertura de posición - acompañamiento - cierre de posición. Esto se refleja también en la elección del desplazamiento en los indicadores y funciones usadas en los algoritmos de entrada y salida.

Por ejemplo, si usted usa en el algoritmo de salida la condición TimeCurrent() = Time[0], es decir, el punto de salida se ha establecido rigurosamente con el inicio de la vela actual, entonces el algoritmo de entrada deberá procesar en las barras anteriores ya finalizadas para que la condición de salida pueda cumplirse. Es decir, para cerrar la posición según la condición TimeCurrent() = Time[0] sin condiciones adicionales, es imprescindible que todo el algoritmo de comparación (en la entrada) sea ejecutado (finalizado) en la barra anterior. Para ello, en los ajustes de los indicadores que participen en la comparación de magnitudes debe existir un desplazamiento igual a 1. En este caso, la comparación de las magnitudes será correcta, y el comienzo de la vela actual será la finalización lógica del algoritmo de salida.

De esta forma, la vinculación de los algoritmos de entrada y de salida también está relacionada con el factor temporal.


Conclusión

El problema de las activaciones erróneas de los asesores expertos se resuelve de forma efectiva con el uso del factor temporal en el algoritmo de entrada. La fijación de un punto de salida (por ejemplo, por tiempo) puede proporcionar estabilidad adicional al funcionamiento del experto, al igual que la vinculación del funcionamiento de los algoritmos de entrada y salida mediante el modelado preliminar no solo de la lógica principal de activación, sino también teniendo en cuenta el desplzamiento (la barra donde se calculará el indicador o función).

Más abajo presentamos los códigos de los expertos: en su forma inicial (MACD_Sample.mq4), con la entrada perfeccionada (MACD_Sample_plus1.mq4), con la salida perfeccionada (MACD_Sample_plus2.mq4). Además, se han trabajado solo los canales Buy, los canales Sell se han dejado a propósito sin cambios, para que se puedan comparar los algoritmos originales y los perfeccionados.

Y por supuesto, hay que decir que todos los expertos indicados tienen carácter demostrativo y no han sido diseñados para el comercio real en los mercado financieros.

Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/2110

Archivos adjuntos |
MACD_Sample.mq4 (6.1 KB)
Interfaces gráficas IX: Control "Paleta para seleccionar el color" (Capítulo 1) Interfaces gráficas IX: Control "Paleta para seleccionar el color" (Capítulo 1)
Con este artículo se abre la novena parte de la serie sobre el desarrollo de la librería para la creación de las interfaces gráficas en el entorno de los terminales de trading MetaTrader. Se compone de dos partes en las que se muestran nuevos controles y elementos de la interfaz: «Paleta para seleccionar el color», «Botón para abrir la paleta de colores», «Indicador de progreso» y «Gráfico lineal».
Lógica difusa para crear estrategias de trading manual Lógica difusa para crear estrategias de trading manual
Este artículo sugiere las maneras de mejorar la estrategia de trading manual mediante la aplicación de teoría de conjuntos difusa. Como ejemplo hemos incluido una descripción paso a paso en la búsqueda de la estrategia y la selección de sus parámetros, seguido de la aplicación de lógica difusa para desenfocar criterios demasiado formales para entrar en el mercado. Así, después de la modificación de la estrategia obtenemos condiciones flexibles para la apertura de una posición que tiene una reacción razonable a una situación de mercado.
Estudiamos la clase CCanvas. Suavizado y sombras Estudiamos la clase CCanvas. Suavizado y sombras
El algoritmo de suavizado de la clase CCanvas es la base de todas las construcciones en las que se usa el suavizado. En el artículo se cuenta cómo funciona este algoritmo y se muestran ejemplos visuales de su funcionamiento. Además, se analizará el dibujado de las sombras de los objetos gráficos y se desarrollará un algoritmo detallado del dibujado de la sombra en el elemento canvas. Para los cálculos se ha utilizado la biblioteca de análisis numérico ALGLIB.
Evaluando la efectividad de los sistemas comerciales mediante el análisis de sus componentes Evaluando la efectividad de los sistemas comerciales mediante el análisis de sus componentes
En este artículo vamos a investigar la efectividad de los sistemas comerciales complejos mediante el análisis de la efectividad de sus componentes por separado. Cualquier análisis, sea de tipo gráfico, basado en indicadores o de cualquier otro tipo, es uno de los componentes clave para comerciar con éxito en los mercados financieros. Este artículo es una investigación sui generis de varios sistemas comerciales sencillos independientes, en la que se analiza su efectividad y la utilidad de su aplicación conjunta.