English Русский 中文 Deutsch 日本語 Português
Selección automática de señales prometedoras

Selección automática de señales prometedoras

MetaTrader 5Integración | 25 diciembre 2017, 10:02
3 929 0
Alexander Fedosov
Alexander Fedosov

Introducción

El trading automático en los mercados financieros es el objetivo del desarrollo constante de nuevos y nuevos robots comerciales, es que el mercado no está estancado y se cambia constantemente. No obstante, los Asesores Expertos (EA) automáticos no son capaces de prever todas las situaciones en el mercado. Por eso, el modo más eficaz sigue siendo el simbiosis entre el robot y el hombre que controla el trabajo de sus sistemas automáticos y lo corrige. Los traders pueden monitorear el trading en esta combinación en el servicio «Señales comerciales». No obstante, ahí se ofrecen los sistemas comerciales y los métodos del trading con diferentes niveles de riesgo o dinámica de la negociación. El servicio dispone de suficientes herramientas de búsqueda de la señal que necesita, ¿pero de qué manera se puede identificar la combinación de parámetros que se ajusten a su estilo del trading? Sería conveniente determinar un conjunto de los parámetros de la señal comercial y sus valores que respondan a las exigencias de un trading ariesgado, moderado y conservador.

Modelo de estimación de señales comerciales

Para una evaluación integral de las señales comerciales, fue tomada una decisión de seleccionar cinco criterios de la estimación. Cada uno, en su lugar, va a dar una estimación en una escala de 0 a 20, donde 0 es un estilo arriesgado del trading, mientras que 20 representa un estilo conservador. En total, cada señal comercial va a evaluarse en una escala de 100 puntos. Como criterios, he elegido las siguientes características de las señales comerciales.

1) Apalancamiento de la cuenta comercial.

Como se sabe, cuanto más alto sea el apalancamiento, mayores son los riesgos de perder una importante parte de su propio depósito en caso de un salto brusco del instrumento financiero. Por eso, durante la estimación del uso del apalancamiento en una escala de 20 puntos, ha sido tomada la decisión de establecer los siguientes valores:

  • 20 puntos se asignan al apalancamiento 1:1.
  • 0 puntos se asignan al apalancamiento 1:500 y más.

Para realizar la estimación en vista del valor establecido del apalancamiento que se aplica, usaremos la fórmula de la ecuación canónica de la recta:

donde Xa = 1, Ya = 20, y, por consiguiente, Xb = 500 y Yb = 0. De esta manera, obtendremos la ecuación de la recta que pasa por dos puntos. En nuestro caso, reflejará la dependencia de la estimación en una escala de 20 puntos del valor actual del apalancamiento. 

Otra vez cabe mencionar que la dependencia obtenida es válida en términos del rango de valoración de 0 a 20. Eso significa que si el apalancamiento utilizado es superior a 1:500 (por ejemplo, 1:1000), su estimación igualmente será 0.

2) Incremento de la cuenta en por cientos.

Para estimar este indicador usando la misma escala de 20, hay que tomar en cuenta dos factores. Primero, el incremento puede ser negativo. Segundo, no será de todo correcto estimar su valor absoluto. Por eso, al formar la estimación para este indicador, vamos a introducir las siguientes reglas y admisiones.

  • El incremento negativo va a significar que en este momento la señal estimada se encuentra en el grupo de riesgo, por eso se le asignará la estimación 0.
  • No vamos a estimar el incremento absoluto, sino su dinámica en el tiempo. Para eso, dividimos el incremento de la cuenta por el tiempo de la vida de la señal expresado en semanas.
  • Cada uno tiene su propio concepto sobre el riesgo. Para algunos, el 10% del incremento a la semana es poco, para otros, es mucho. Sin embargo, es necesario establecer un determinado rango. Por eso, admitimos 1% del incremento a la semana como un incremento patrón de una señal conservadora, y el umbral para el trading arriesgado será de 15% a la semana.

Usamos de nuevo la fórmula para obtener la ecuación de la recta a través de dos pùntos, donde  Xa = 1, Ya = 20, y, por consiguiente, Xb = 15 y Yb = 0. Obtenemos la siguiente dependencia:

3) Reducción (drawdown) máxima en por cientos.

Este indicador cacarteriza directamente el riesgo del trading. Para determinar los límites, itroducimos las siguientes reglas.

  • La reducción de hasta un 20% inclusive se considera como un estilo conservador del trading y se evelúa en 20 puntos.
  • La reducción superior a un 40% será considerada como un estilo arriesgado, evaluándose en 0 puntos.
  • El intervalo de 20 a 40% de la reducción máxima va a evaluarse basándose en la ecuación de la recta establecida con dos puntos anteriores.

En esta ecuación Xa = 20, Ya = 20, y por consiguiente, Xb = 40 y Yb = 0. Obtenemos la siguiente dependencia:

4) Valor ROI ( Return on Investment) en por cientos.

Si la recuperación de las inversiones está por encima de un 100%, eso significa que el uso de los fondos es rentable; si está por debajo de un 100%, eso quiere decir que las inversiones no se usan con eficacia. Aplicaremos este indicador del grado de la eficacia de las inversiones a una escala de 20 puntos.

  • ROI menos de un 100% se evaluará en 0 puntos.
  • ROI más de un 200% se evaluará en 20 puntos.
  • El intervalo de 100 a 200 va a evaluarse basándose en la ecuación de la recta establecida con dos puntos anteriores.

En esta ecuación Xa = 100, Ya = 0, y por consiguiente,  Xb = 200 y Yb = 20. Obtenemos la siguiente dependencia:

5) Edad de la señal comercial.

El tiempo de vida de una señal comercial es un indicador muy importante, que caracteriza en mucho si el trading se lleva a cabo correctamente en principio. Para evaluar este indicador en una escala de 20 puntos, primero vamos a determinar qué intervalo de tiempo va a considerarse seguro y fiable. Usamos las semanas como unidad de medición, puesto que las hemos usado ya en la estimación del incremento. Cabe mencionar que este indicador es estrictamente individual, y cada uno es libre de elegir sus propios criterios temporales de seguridad. Para nuestro sistema vamos a elegir los siguientes valores de umbral.

  • La edad de la señal menos de 4 semanas (número de semanas completas en el mes) se evaluará en 0 puntos.
  • La edad de la señal más de 25 semanas (número de semanas completas en el semestre) se evaluará en 20 puntos.
  • El intervalo de 4 a 25 semans va a evaluarse basándose en la ecuación de la recta establecida con dos puntos anteriores.


Implementación de la herramienta para la estimación

Para la implementación, se ha decidido utilizar la librería de las interfaces gráficas EasyandFastGUI. La estructura de la aplicación será como se muestra en las imágenes 1a y 1b (véase más abajo) y va a componerse de los siguientes elementos:

  • Tabla de las señales disponibles para la cuenta comercial actual en el terminal.
  • Estimación detallada de la señal seleccionada en la tabla según las categorías.
  • Número de señales disponibles para la cuenta actual.
  • Estimación visual conjunta de la señal seleccionada en la tabla.


Fig. 1a Estructura de la aplicación (parte izquierda)

La estimación conjunta representada como una escala de gradiente no quiere decir que su parte izquierda (roja) refleja las señales no prometedoras, y la verde, las señales prometedoras. Simplemente representa la visualización del estilo del trading en una determinada señal comercial. Aunque el trading arriesgado contiene unas probabilidades elevadas de sufrir pérdidas, pero un posible beneficio también es elevado.


Рис. 1b Estructura de la aplicación (parte derecha)

En la implementación informática nos centraremos en los métodos clave que reflejan la esencia de la aplicación. El primero es el método CreateGUI() que representa una combinación de todos los demás y que se encarga de mostrar toda la información visual.

  • El método CreateWindow() crea la ventana de la aplicación con el encabezado. Se puede cerrar y minimizarla.
  • El método CreateTable() crea la tabla con todas las señales disponibles para la cuenta comercial actual.
  • El método CreateStatusBar() crea la barra de estado que refleja el número general de las señales disponibles.
  • Los métodos CreatePicture1() y CreatePicture2() crea la escala de gradiente y el puntero para la escala, respectivamente.
  • Los métodos CreateTextLabel() crean la visualización de la información detallada sobre la estimación de la señal comercial seleccionada.
  • El método CreateButton() crea el botón de la suscripción a la señal seleccionada en la tabla.
//+------------------------------------------------------------------+
//| Crea la interfaz gráfica del programa                            |
//+------------------------------------------------------------------+
bool CProgram::CreateGUI(void)
  {
//--- Creación del panel
   if(!CreateWindow("Auto Search Signal"))
      return(false);
//--- Creación de la tabla
   if(!CreateTable(7,100))
      return(false);
//--- Barra de estado
   if(!CreateStatusBar(1,26))
      return(false);
//--- Imágenes
   if(!CreatePicture1(618,40))
      return(false);
   if(!CreatePicture2(610,80))
      return(false);
//--- Etiqueta de texto
   if(!CreateTextLabel1(20,20,"Estimación del apalancamiento: -"))
      return(false);
   if(!CreateTextLabel2(20,40,"Estimación del incremento: -"))
      return(false);
   if(!CreateTextLabel3(20,60,"Estimación del drawdown: -"))
      return(false);
   if(!CreateTextLabel4(200,20,"Estimación de ROI: -"))
      return(false);
   if(!CreateTextLabel5(200,40,"Estimación de la edad: -"))
      return(false);
//--- Botones con imagen
   if(!CreateButton(440,40,"Suscribirse"))
      return(false);
//--- Terminar la creación de GUI
   CWndEvents::CompletedGUI();
   return(true);
  }
//+-----------------------------------------------------------------


El siguiente método se encarga de la interacción interactiva: la selección de la señal comercial de la lista en la tabla y visualización de la información sobre ella. Además, hace seguimiento del evento de la pulsación del botón creado anteriormente y la suscripción a la señal seleccionada en la tabla.

//+------------------------------------------------------------------+
//| Manejador de eventos                                             |
//+------------------------------------------------------------------+
void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Evento de la pulsación en el elemento de la lista o la tabla
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_LIST_ITEM)
     {
      int x=610+3*int(m_table.GetValue(9,m_table.SelectedItem()));
      //---
      CreateTextLabel1(20,20,"Estimación del apalancamiento: "+IntegerToString(GetLeverageRating(int(m_table.GetValue(2,m_table.SelectedItem())))));
      CreateTextLabel2(20,40,"Estimación del incremento: "+IntegerToString(GetGainRating(int(m_table.GetValue(3,m_table.SelectedItem())),int(m_table.GetValue(8,m_table.SelectedItem())))));
      CreateTextLabel3(20,60,"Estimación del drawndown: "+IntegerToString(GetDrawDownRating(int(m_table.GetValue(5,m_table.SelectedItem())))));
      CreateTextLabel4(200,20,"Estimación de ROI: "+IntegerToString(GetROIRating(int(m_table.GetValue(4,m_table.SelectedItem())))));
      CreateTextLabel5(200,40,"Estimación de la edad: "+IntegerToString(GetWeeksRating(int(m_table.GetValue(8,m_table.SelectedItem())))));
      CreatePicture2(x,80);
      //---
      m_button.IsLocked(false);
      Update(true);
     }
//---
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON)
     {
      //--- Si hemos pulsado el botón
      if(lparam==m_button.Id())
        {
         SignalSubscribe(long(m_table.GetValue(6,m_table.SelectedItem())));
        }
     }
  }

A continuación, vamos a considerar los métodos que implementan la estimación de las señales comerciales. Para empezar, es necesario obtener la lista de las señales disponibles para la cuenta actual, así como toda la información que nos interesa para la visualización subsiguiente en la tabla y para la estimación sumaria.

El método GetTradingSignals() obtiene toda la información sobre las señales disponibles y las introduce en los arrays de los datos:

//+------------------------------------------------------------------+
//| Obtención de la información sobre las señales disponibles        |
//+------------------------------------------------------------------+
bool CProgram::GetTradingSignals(void)
  {
//--- solicitamos el número total de las señales en la base 
   m_signals_total=SignalBaseTotal();
//---
   ArrayResize(m_name,m_signals_total);
   ArrayResize(m_curr,m_signals_total);
   ArrayResize(m_leverage,m_signals_total);
   ArrayResize(m_gain,m_signals_total);
   ArrayResize(m_roi,m_signals_total);
   ArrayResize(m_max_drawdown,m_signals_total);
   ArrayResize(m_pips,m_signals_total);
   ArrayResize(m_subscr,m_signals_total);
   ArrayResize(m_weeks,m_signals_total);
   ArrayResize(m_rating,m_signals_total);
//--- ciclo por todas las señales 
   for(int i=0;i<m_signals_total;i++)
     {
      //--- seleccionamos la para el siguiente trabajo 
      if(SignalBaseSelect(i))
        {
         //--- obtención de las propiedades de la señal 
         m_name[i]=SignalBaseGetString(SIGNAL_BASE_NAME);                                                // nombre de la señal
         m_curr[i]=SignalBaseGetString(SIGNAL_BASE_CURRENCY);                                            // divisa de la señal
         m_leverage[i]=SignalBaseGetInteger(SIGNAL_BASE_LEVERAGE);                                       // apalancamiento
         m_gain[i]=SignalBaseGetDouble(SIGNAL_BASE_GAIN);                                                // incremento de la cuenta en %
         m_roi[i]=SignalBaseGetDouble(SIGNAL_BASE_ROI);                                                  // ROI
         m_max_drawdown[i]=SignalBaseGetDouble(SIGNAL_BASE_MAX_DRAWDOWN);                                // Reducción máxima
         m_id[i]=SignalBaseGetInteger(SIGNAL_BASE_ID);                                                   // ID de la señal
         m_subscr[i]=SignalBaseGetInteger(SIGNAL_BASE_SUBSCRIBERS);                                      // número de suscriptores 
         m_weeks[i]=int((TimeCurrent()-SignalBaseGetInteger(SIGNAL_BASE_DATE_PUBLISHED))/3600/24/7);     // edad de la señal
         //--- obtención de la estimación sumaria
         m_rating[i]=GetLeverageRating(m_leverage[i])+GetGainRating(m_gain[i],m_weeks[i])+GetDrawDownRating(m_max_drawdown[i])+GetROIRating(m_roi[i])+GetWeeksRating(m_weeks[i]);
        }
      else
        {
         PrintFormat("Error de la selección de la señal. Código del error=%d",GetLastError());
         return(false);
        }
     }
   return (true);
  }
//+------------------------------------------------------------------+

Como podemos ver en el código de arriba, en el array m_rating[] se insertan los datos de la estimación sumaria para cada señal comercial. Por eso, vamos a analizar los métodos que se utilizan en este cálculo. Ellos representan la implementación informática del modelo del primer apartado del artículo.

//+------------------------------------------------------------------+
//| Evaluación del apalancamiento                                    |
//+------------------------------------------------------------------+
int CProgram::GetLeverageRating(long leverage)
  {
   int lev_rating=int(-20.0/499.0*double(leverage)+10000.0/499.0);
   lev_rating=(lev_rating>20)?20:lev_rating;
   return lev_rating;
  }
//+------------------------------------------------------------------+
//| Evaluación del incremento                                        |
//+------------------------------------------------------------------+
int CProgram::GetGainRating(double gain,int weeks)
  {
   weeks=(weeks==0)?1:weeks;
   int gain_rating=int(-10*(gain/double(weeks)/7.0)+150.0/7.0);
   gain_rating=(gain_rating>20)?20:gain_rating;
   gain_rating=(gain_rating<0)?0:gain_rating;
   gain_rating=(gain<0)?0:gain_rating;
   return gain_rating;
  }
//+------------------------------------------------------------------+
//| Evaluación del drawdown máximo                                   |
//+------------------------------------------------------------------+
int CProgram::GetDrawDownRating(double max_drawdown)
  {
   int drawdn_rating=int(-max_drawdown+40);
   drawdn_rating=(drawdn_rating>20)?20:drawdn_rating;
   drawdn_rating=(drawdn_rating<0)?0:drawdn_rating;
   return drawdn_rating;
  }
//+------------------------------------------------------------------+
//| Evaluación de ROI                                                |
//+------------------------------------------------------------------+
int CProgram::GetROIRating(double roi)
  {
   int roi_rating=int(0.2*roi-20);
   roi_rating=(roi_rating>20)?20:roi_rating;
   roi_rating=(roi_rating<0)?0:roi_rating;
   return roi_rating;
  }
//+------------------------------------------------------------------+
//| Evaluación de la edad de la señal comercial                      |
//+------------------------------------------------------------------+
int CProgram::GetWeeksRating(int weeks)
  {
   int age_rating=int(20.0*double(weeks)/21.0-80.0/21.0);
   age_rating=(age_rating>20)?20:age_rating;
   age_rating=(age_rating<0)?0:age_rating;
   return age_rating;
  }

Luego, todos los datos obtenidos se introducen en la tabla a través del método InitializingTable() se visualizan a través del método CreateTable().

//+------------------------------------------------------------------+
//| Inicialización de la tabla                                       |
//+------------------------------------------------------------------+
void CProgram::InitializingTable(void)
  {
//---
   string columns[10]=
     {
      "Nombre de la señal",
      "Divisa de la cuenta",
      "Apalancamiento de la cuenta comercial",
      "Incremento de la cuenta, %",
      "ROI",
      "Drawdown máximo",
      "ID de la señal",
      "Número de suscriptores",
      "Edad, semanas",
      "Evaluación"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Establecemos el nombre del encabezado
      m_table.SetHeaderText(c,columns[c]);
      //---
      for(int r=0; r<m_signals_total; r++)
        {
         if(c==0)
            m_table.SetValue(c,r,m_name[r]);
         else if(c==1)
            m_table.SetValue(c,r,m_curr[r]);
         else if(c==2)
            m_table.SetValue(c,r,IntegerToString(m_leverage[r]));
         else if(c==3)
            m_table.SetValue(c,r,DoubleToString(m_gain[r],2));
         else if(c==4)
            m_table.SetValue(c,r,DoubleToString(m_roi[r],2));
         else if(c==5)
            m_table.SetValue(c,r,DoubleToString(m_max_drawdown[r],2));
         else if(c==6)
            m_table.SetValue(c,r,IntegerToString(m_id[r]));
         else if(c==7)
            m_table.SetValue(c,r,IntegerToString(m_subscr[r]));
         else if(c==8)
            m_table.SetValue(c,r,IntegerToString(m_weeks[r]));
         else if(c==9)
            m_table.SetValue(c,r,IntegerToString(m_rating[r]));
        }
     }
  }
//+------------------------------------------------------------------+
//| Crea una tabla dibujada                                          |
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\circle_gray.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\calendar.bmp"
//---
bool CProgram::CreateTable(const int x_gap,const int y_gap)
  {
#define COLUMNS1_TOTAL 10
//--- Guardamos el puntero al control principal
   m_table.MainPointer(m_window);
//--- Array del ancho de columnas
   int width[COLUMNS1_TOTAL];
   ::ArrayInitialize(width,110);
   width[1]=80;
   width[2]=100;
   width[4]=90;
   width[8]=85;
   width[9]=90;
//--- Array del margen del texto en las columnas por el eje X
   int text_x_offset[COLUMNS1_TOTAL];
   ::ArrayInitialize(text_x_offset,7);
//--- Array de alineación del texto dentro las columnas
   ENUM_ALIGN_MODE align[COLUMNS1_TOTAL];
   ::ArrayInitialize(align,ALIGN_CENTER);
//---
   GetTradingSignals();
//--- Propiedades
   m_table.XSize(1000);
   m_table.YSize(470);
   m_table.CellYSize(20);
   m_table.TableSize(COLUMNS1_TOTAL,m_signals_total);
   m_table.TextAlign(align);
   m_table.ColumnsWidth(width);
   m_table.TextXOffset(text_x_offset);
   m_table.LabelXGap(5);
   m_table.LabelYGap(4);
   m_table.IconXGap(7);
   m_table.IconYGap(4);
   m_table.MinColumnWidth(0);
   m_table.ShowHeaders(true);
   m_table.IsSortMode(true);
   m_table.LightsHover(true);
   m_table.SelectableRow(true);
   m_table.IsWithoutDeselect(true);
   m_table.ColumnResizeMode(true);
   m_table.IsZebraFormatRows(clrWhiteSmoke);
   m_table.AutoXResizeMode(true);
   m_table.AutoXResizeRightOffset(7);
   m_table.AutoYResizeBottomOffset(28);
   m_table.HeadersColor(clrSkyBlue);
   m_table.DataType(2,TYPE_INT);
   m_table.DataType(3,TYPE_FLOAT);
   m_table.DataType(4,TYPE_FLOAT);
   m_table.DataType(5,TYPE_FLOAT);
   m_table.DataType(6,TYPE_INT);
   m_table.DataType(7,TYPE_INT);
   m_table.DataType(8,TYPE_INT);
   m_table.DataType(9,TYPE_INT);

//--- Llenamos la tabla con datos
   InitializingTable();
//--- Creamos el control
   if(!m_table.CreateTable(x_gap,y_gap))
      return(false);
//--- Añadimos el objeto al array común de los grupos de objetos
   CWndContainer::AddToElementsArray(0,m_table);
   m_table.SortData(9);
   m_table.SortData(9);
   return(true);
  }

Para la comodidad del uso de la tabla de datos sobre las señales comerciales, hay que asignar los tipos de datos para las celdas a visualizar. Es necesario para que la ordenación de datos en las celdas se haga correctamente. Para la mayor evidencia de la representación,se realiza la ordenación inicial en orden descendiente por la última columna, es decir, según la estimación integral de la señal. La ordenación se hace dos veces: primero, en orden descendiente, y la segunda y las siguientes veces, en diercción opuesta a la anterior.

El último elemento en el que se debe prestar atención es la representación visual de la estimación sumaria en forma de una escala de gradiente y un puntero en ella. De eso se encragan dos métodos cuyos códigos se muestran a continuación. El cambio de la posición del puntero en la escala ya ha sido considerado en el método OnEvent() un poco más arriba.

//+------------------------------------------------------------------+
//| Crea la escala de gradiente                                      |
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp64\\000.bmp"
#resource "\\Images\\EasyAndFastGUI\\Controls\\ArrowUp_blue.bmp"
//---
bool CProgram::CreatePicture1(const int x_gap,const int y_gap)
  {
//--- Guardamos el puntero al control principal
   m_picture1.MainPointer(m_window);
//--- Propiedades
   m_picture1.XSize(300);
   m_picture1.YSize(40);
   m_picture1.IconFile("Images\\EasyAndFastGUI\\Icons\\bmp64\\000.bmp");
//--- Creación del botón
   if(!m_picture1.CreatePicture(x_gap,y_gap))
      return(false);
//--- Añadimos el puntero al control a la base
   CWndContainer::AddToElementsArray(0,m_picture1);
   return(true);
  }
//+------------------------------------------------------------------+
//| Crea el puntero para la escala                                   |
//+------------------------------------------------------------------+
bool CProgram::CreatePicture2(const int x_gap,const int y_gap)
  {
//--- Guardamos el puntero al control principal
   m_picture2.MainPointer(m_window);
//--- Propiedades
   m_picture2.XSize(16);
   m_picture2.YSize(16);
   m_picture2.IconFile("Images\\EasyAndFastGUI\\Controls\\ArrowUp_blue.bmp");
//--- Creación del botón
   if(!m_picture2.CreatePicture(x_gap,y_gap))
      return(false);
//--- Añadimos el puntero al control a la base
   CWndContainer::AddToElementsArray(0,m_picture2);
   return(true);
  }


Selección de señales prometedoras

Cuando seleccionamos una señal y determinamos su perspectiva, nos guiamos por lo que en el futuro tendrá que traernos un determinado resultado. La práctica demuestra que las señales que muestran unos indicadores del incremento altos en plazos cortos, no viven mucho. Eso se debe al hecho de que los estilos de alto riesgo del trading se usan principalmente para obtener grandes beneficios. Sin embargo, no sería de todo justo borrar las señales con el estilo arriesgado de la lista de las prometedoras, es que, cada trader persigue sus propios fines. Uno se dispone a permanecer en el mercado durante un largo período de tiempo y ganar sin prisa, otro necesita sacar un beneficio rápido y está listo para correr ciertos riesgos.

Por eso, vamos a dividir visualmente el sistema de estimación de las señales que hemos desarrollado antes en tres categorías (fig. 2).

  • La primera categoría. Zona roja. La perspectiva de las señales en esta zona de la estimación consiste en un posible beneficio grande, pero esto comporta grandes riesgos.
  • La segunda categoría. Zona amarilla. Las señales de esta zona son de perspectiva gracias a unos buenos indicadores de la rentabilidad, con unos riesgos medianos.
  • La tercera categoría. Zona verde. La perspectiva consiste en una seguridad elevada de la señal, pero los indicadores de la rentabilidad no son muy altos.


Fig. 2. División de la escala de gradiente de la estimación de las señales en tres categoríaas

Para programar esta clasificación, añadimos las siguientes líneas al método InitializingTable():

//+------------------------------------------------------------------+
//| Inicialización de la tabla                                       |
//+------------------------------------------------------------------+
void CProgram::InitializingTable(void)
  {
//---
   string columns[10]=
     {
      "Nombre de la señal",
      "Divisa de la cuenta",
      "Apalancamiento de la cuenta comercial",
      "Incremento de la cuenta, %",
      "ROI",
      "Drawdown máximo",
      "ID de la señal",
      "Número de suscriptores",
      "Edad, semanas",
      "Evaluación"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Establecemos el nombre del encabezado
      m_table.SetHeaderText(c,columns[c]);

      //---
      for(int r=0; r<m_signals_total; r++)
        {
         if(c==0)
           {
            m_table.SetValue(c,r,m_name[r]);
            if(m_rating[r]<=30)
               m_table.TextColor(c,r,clrCrimson);
            else if(m_rating[r]>30 && m_rating[r]<=66)
               m_table.TextColor(c,r,clrOrange);
            else if(m_rating[r]>66)
               m_table.TextColor(c,r,clrForestGreen);
           }
         else if(c==1)
            m_table.SetValue(c,r,m_curr[r]);
         else if(c==2)
            m_table.SetValue(c,r,IntegerToString(m_leverage[r]));
         else if(c==3)
            m_table.SetValue(c,r,DoubleToString(m_gain[r],2));
         else if(c==4)
            m_table.SetValue(c,r,DoubleToString(m_roi[r],2));
         else if(c==5)
            m_table.SetValue(c,r,DoubleToString(m_max_drawdown[r],2));
         else if(c==6)
            m_table.SetValue(c,r,IntegerToString(m_id[r]));
         else if(c==7)
            m_table.SetValue(c,r,IntegerToString(m_subscr[r]));
         else if(c==8)
            m_table.SetValue(c,r,IntegerToString(m_weeks[r]));
         else if(c==9)
            m_table.SetValue(c,r,IntegerToString(m_rating[r]));
        }
     }
  }

Usamos el método TextColor() para cambiar el color del nombre de la señal comercial (primera columna de la página) a base de los resultados obtenidos de la estimación. Por eso, se puede ver la pertenencia de la señal a una u otra categoría, incluso sin analizarlo ni mirar la última columna de la tabla, que contiene el valor numérico de la estimación.


Fig. 3. Indicación de color de señales comerciales

Se puede agrupar las señales según las categorías, ordendo la tabla por la última columna. Por defecto, esta ordenación está activada. La última acción evidente consiste en implementar la posibilidad de suscribirse a la señal. Para eso, se usa el método CreateButton() :

//+------------------------------------------------------------------+
//| Crea un botón con imagen                                         |
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\start.bmp"
//---
bool CProgram::CreateButton(const int x_gap,const int y_gap,const string text)
  {
//--- Guardamos el puntero al control principal
   m_button.MainPointer(m_window);
//--- Propiedades
   m_button.XSize(120);
   m_button.YSize(22);
   m_button.IconXGap(3);
   m_button.IconYGap(3);
   m_button.FontSize(10);
   m_button.IsCenterText(true);
   m_button.IconFile("Images\\EasyAndFastGUI\\Icons\\bmp16\\start.bmp");
   m_button.IsLocked(true);
//--- Creamos el control
   if(!m_button.CreateButton(text,x_gap,y_gap))
      return(false);
//--- Añadimos el puntero al control a la base
   CWndContainer::AddToElementsArray(0,m_button);
   return(true);
  }
//+------------------------------------------------------------------+

Para evitar posibles errores en el trabajo de la funcionalidad desarrollada, prestamos nuestra atención en los ajustes previos necesarios del terminal.

1. Para poder trabajar con las señales comerciales en el terminal MetaTrader 5, Usted tiene que estar autorizado en la página de los ajustes usando su cuenta mql5:

Fig. 4. Autorización en el terminal

2. Al iniciar la aplicación, es necesario activar la opción Permitir cambio de ajustes de señales. Si no lo hacemos, la suscripción a la señal mediante la aplicación desarrollada va a saltar el error 4014 («La función de sistema no está permitida para la llamada»).

Fig. 5. Configuración necesaria al iniciarla aplicación

3. Y lo último que puede afectar el trabajo correcto es el archivo signals.dat. Si los datos se muestran de forma incorrecta en la tabla o no se muestran en absoluto, hay que encontrar este archivo siguiendo la ruta C:\Users\Nombre del ordenador\AppData\Roaming\MetaQuotes\Terminal\..\bases\signals y eliminarlo. Luego, reiniciamos el terminal y abrimos la pestaña Señales, tal como se muestra en la Fig. 6. El nuevo archivo se generará automáticamente, después de eso, se puede iniciar y usar la aplicación.

Fig. 6. Pestaña Señales en el terminal MetaTrader 5

En el terminal, a diferencia de la sección «Señales» en el sitio web, no se muestran todas las señales, sino las que se ajustan para el trabajo con la cuenta comercial seleccionada en este momento.


Conclusión

En este artículo, hemos desarrollado un sistema simple de estimación a base de los puntos que se ponen por algunas características de las señales comerciales. Se compone en una estimación de 100 puntos del estilo del trading. A base de esta estimación, todas las señales disponibles han sido destribuidas por tres categorías que se diferencian en perspectivas, riesgos del trading, tiempo y el incremento porcentual de la cuenta comercial.

Al final del articulo se adjunta el archivo comprimido con todos los ficheros mencionados ordenados por las carpetas. Por eso, para un trabajo correcto basta con colocar la carpeta MQL5 en la raíz del terminal. Además, se usa la librería de la interfaz gráfica EasyAndFastGUI prestada de este artículo. Ha sufrido algunas modificaciones, por eso también se adjunta al artículo.

Los programas usados en el artículo:

#
 Nombre
Tipo
Descripción
1
AutoSearch.mq5 Asesor Experto
 Aplicación para la selección automática de señales prometedoras
2
Program.mqh Librería  Clase para crear la aplicación
3
MainWindow.mqh Librería  Conjunto de métodos usados para crear la aplicación


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

Archivos adjuntos |
MQL5.zip (1631.66 KB)
Comercio por los niveles de DiNapoli Comercio por los niveles de DiNapoli
En este artículo se considera una de las versiones de la implementación práctica del Asesor Experto para el comercio por los niveles de DiNapoli a través de las herramientas estándar MQL5. Ha sido realizado el testeo de sus resultados, y han sido sacadas conclusiones.
El comercio nocturno en la sesión asiática: cómo mantener los beneficios El comercio nocturno en la sesión asiática: cómo mantener los beneficios
En el artículo se analizan el concepto de comercio nocturno, sus estrategias comerciales y su implementación en MQL5. Se han realizado varias simulaciones y se han sacado las conclusiones pertinentes.
La estrategia comercial 'Momentum Pinball' La estrategia comercial 'Momentum Pinball'
En este artículo se continúa con el tema de la escritura de código para los sistemas comerciales descritos en el libro de Linda Raschke y Laurence Connors "Secretos bursátiles. Estrategias comerciales de alto rendiemiento a corto plazo". En esta ocasión, analizaremos el sistema 'Momentum Pinball', describiendo la creación de dos indicadores, un robot comercial y un bloque comercial para el sistema.
Evaluación del riesgo en la secuencia de transacciones con un activo. Continuación Evaluación del riesgo en la secuencia de transacciones con un activo. Continuación
Este artículo desarrolla las ideas propuestas en la parte anterior y continua su análisis. Aquí se describen las cuestiones de la distribución de los beneficios, la modelación y el estudio de las regularidades estadísticas.