
Dibujando emisiones de indicador en MQL5
Introducción
Ciertamente, muchos operadores y programadores de estrategias de trading están interesados en estas cuestiones:- ¿Cómo están surgiendo los sólidos movimientos del mercado?
- ¿Cómo determinar la dirección correcta de los próximos cambios?
- ¿Cómo abrir posiciones rentables para operar?
- ¿Cómo cerrar una posición con el máximo beneficio?
Encontrar la respuesta a estas preguntas me llevó a la creación de un nuevo enfoque sobre la investigación del mercado: la construcción y el análisis de emisiones de indicadores. Para hacerlo más claro echemos un vistazo a las siguientes figuras:
Fig. 1 Emisión del indicador DCMV.
Fig. 2. Emisión del indicador basado en envelopes iMA.
Muestra la emisión de diferentes indicadores pero el principio de su construcción es el mismo. Después de cada tick aparecen más y más puntos con diferentes colores y formas. Forman numerosas agrupaciones como nebulosas, nubes, rastros, líneas, arcos, etc. Estas formas ayudan a detectar los resortes ocultos y las fuerzas que afectan al movimiento de los precios del mercado. La investigación y análisis de estas emisiones se parece a la quiromancia.
Emisiones y sus propiedades
La emisión es un conjunto de puntos ubicados en los puntos de intersección de líneas concretas del indicador.
Las propiedades de las emisiones no han sido todavía aclaradas y están esperando a que los investigadores lo hagan. Esta es la lista de propiedades:
- los puntos del mismo tipo tienden a agruparse;
- la emisión tiene una dirección - desde el presente hacia el futuro o hacia el pasado;
- los conglomerados son importantes - los conglomerados densos pueden atraer o, a la inversa, repeler el precio.
Cálculo de la emisión del indicador
Vamos a ver los principios básicos del cálculo de una emisión usando un ejemplo. Vamos a tomar dos indicadores - iBands y iMA - y a encontrar la intersección de sus líneas. Los usaremos para dibujar los puntos de emisión. Para ello necesitaremos objetos gráficos. El algoritmo se implementa en los asesores expertos, pero puede hacerse en los indicadores.
Los indicadores iniciales se presentan en la Fig. 3:
Fig. 3. Los indicadores iBands (verde) y iMA (rojo) .
Necesitamos un asesor experto para crear los puntos de emisión. Es mejor usar el MQL5 Wizard para crear una plantilla de asesor experto.
Fig. 4. Crear una plantilla de asesor experto usando el MQL5 Wizard.
//+------------------------------------------------------------------+ //| Emission of Bands && MA.mq5 | //| Copyright DC2008 | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "DC2008" #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+
Primero necesitamos algunos trazados auxiliares. Necesitamos continuar las líneas del indicador usando rayos. (Fig. 5). Nos permitirá controlar la precisión del cálculo y la visualización de los puntos de emisión. Posteriormente, eliminaremos estas líneas del gráfico.
Fig. 5. Trazados auxiliares. Continuación de las líneas del indicador usando rayos.
De esta forma, vamos a añadir los objetos gráficos (líneas horizontales y de tendencia) al código de nuestro asesor experto.
input bool H_line=true; // flag to enable drawing of the horizontal lines input bool I_line=true; // flag to enable drawing of the indicator's lines //--- string name; //---- indicator buffers double MA[]; // array for iMA indicator double BBH[]; // array for iBands indicator - UPPER_BAND double BBL[]; // array for iBands indicator - LOWER_BAND double BBM[]; // array for iBands indicator - BASE_LINE datetime T[]; // array for time coordinates //---- handles for indicators int MAHandle; // iMA indicator handle int BBHandle; // iBands indicator handle //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- MAHandle=iMA(Symbol(),0,21,0,MODE_EMA,PRICE_CLOSE); BBHandle=iBands(Symbol(),0,144,0,2,PRICE_CLOSE); //--- if(H_line) // Horizontal lines of iBands indicator { //--- iBands - UPPER_BAND name="Hi"; ObjectCreate(0,name,OBJ_HLINE,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,Red); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); //--- iBands - LOWER_BAND name="Lo"; ObjectCreate(0,name,OBJ_HLINE,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,Blue); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); //--- iBands - BASE_LINE name="MIDI"; ObjectCreate(0,name,OBJ_HLINE,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,DarkOrange); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); } //--- if(I_line) // Indicator lines { //--- iMA name="MA"; ObjectCreate(0,name,OBJ_TREND,0,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,Red); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); ObjectSetInteger(0,name,OBJPROP_WIDTH,2); ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1); ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1); //--- iBands - UPPER_BAND name="BH"; ObjectCreate(0,name,OBJ_TREND,0,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,MediumSeaGreen); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1); ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1); //--- iBands - LOWER_BAND name="BL"; ObjectCreate(0,name,OBJ_TREND,0,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,MediumSeaGreen); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1); ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1); //--- iBands - BASE_LINE name="BM"; ObjectCreate(0,name,OBJ_TREND,0,0,0,0); ObjectSetInteger(0,name,OBJPROP_COLOR,MediumSeaGreen); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1); ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1); } return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- filling the arrays with current values CopyBuffer(MAHandle,0,0,2,MA); ArraySetAsSeries(MA,true); CopyBuffer(BBHandle,0,0,2,BBM); ArraySetAsSeries(BBM,true); CopyBuffer(BBHandle,1,0,2,BBH); ArraySetAsSeries(BBH,true); CopyBuffer(BBHandle,2,0,2,BBL); ArraySetAsSeries(BBL,true); CopyTime(Symbol(),0,0,10,T); ArraySetAsSeries(T,true); //--- Horizontal lines of iBands indicator (correction) if(H_line) { name="Hi"; ObjectSetDouble(0,name,OBJPROP_PRICE,BBH[0]); name="Lo"; ObjectSetDouble(0,name,OBJPROP_PRICE,BBL[0]); name="MIDI"; ObjectSetDouble(0,name,OBJPROP_PRICE,BBM[0]); } //--- Indicator's lines (correction) if(I_line) { name="MA"; //--- iMA ObjectSetInteger(0,name,OBJPROP_TIME,T[1]); ObjectSetDouble(0,name,OBJPROP_PRICE,MA[1]); ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]); ObjectSetDouble(0,name,OBJPROP_PRICE,1,MA[0]); name="BH"; //--- iBands - UPPER_BAND ObjectSetInteger(0,name,OBJPROP_TIME,T[1]); ObjectSetDouble(0,name,OBJPROP_PRICE,BBH[1]); ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]); ObjectSetDouble(0,name,OBJPROP_PRICE,1,BBH[0]); name="BL"; //--- iBands - LOWER_BAND ObjectSetInteger(0,name,OBJPROP_TIME,T[1]); ObjectSetDouble(0,name,OBJPROP_PRICE,BBL[1]); ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]); ObjectSetDouble(0,name,OBJPROP_PRICE,1,BBL[0]); name="BM"; //--- iBands - BASE_LINE ObjectSetInteger(0,name,OBJPROP_TIME,T[1]); ObjectSetDouble(0,name,OBJPROP_PRICE,BBM[1]); ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]); ObjectSetDouble(0,name,OBJPROP_PRICE,1,BBM[0]); } } //+------------------------------------------------------------------+Como la emisión continua hacia el pasado y hacia el futuro, la línea de tendencia propiedades debe ser la siguiente:
- OBJPROP_RAY_LEFT = 1, (el rayo va hacia la izquierda);
- OBJPROP_RAY_RIGHT = 1, (el rayo va hacia la derecha).
Como resultado, el gráfico con líneas adicionales es como se indica en la Fig. 6.
La fase preparatoria se ha completado, vamos ahora a proceder con la emisión. Vamos a crear las primeras series de puntos en la intersección de las líneas siguientes:
- entre la línea "MA" (iMA) y la "BH" (iBands = UPPER_BAND);
- entre la línea "MA" (iMA) y la "BL" (iBands = LOWER_BAND);
- entre la línea "MA" (iMA) y la "BM" (iBands = BASE_BAND).
Fig. 6. Trazados auxiliares. Continuación de las líneas del indicador usando líneas rectas.
Ahora es el momento de calcular las coordenadas de intersección y dibujar los puntos de emisión. Vamos a crear la función:
void Draw_Point( string P_name, // Object name (OBJ_ARROW) double P_y1, // Y-coordinate of the 1st line at the [1] bar double P_y0, // Y-coordinate of the 1st line at the [0] bar double P_yy1, // Y-coordinate of the 2nd line at the [1] bar double P_yy0, // Y-coordinate of the 2nd line at the [0] bar char P_code1, // Char at the right side of the [0] bar char P_code2, // Char at the left side of the [0] bar color P_color1, // Color of point at the right side of the [0] bar color P_color2 // color of point at the left side of the [0] bar ) { double P,X; datetime P_time; if(MathAbs((P_yy0-P_yy1)-(P_y0-P_y1))>0) { P=P_y1+(P_y0-P_y1)*(P_y1-P_yy1)/((P_yy0-P_yy1)-(P_y0-P_y1)); X=(P_y1-P_yy1)/((P_yy0-P_yy1)-(P_y0-P_y1)); if(X>draw_period) { P_time=T[0]+(int)(X*PeriodSeconds()); ObjectCreate(0,P_name,OBJ_ARROW,0,0,0); ObjectSetDouble(0,P_name,OBJPROP_PRICE,P); ObjectSetInteger(0,P_name,OBJPROP_TIME,P_time); ObjectSetInteger(0,P_name,OBJPROP_WIDTH,0); ObjectSetInteger(0,P_name,OBJPROP_ARROWCODE,P_code1); ObjectSetInteger(0,P_name,OBJPROP_COLOR,P_color1); if(X<0) { ObjectSetInteger(0,P_name,OBJPROP_ARROWCODE,P_code2); ObjectSetInteger(0,P_name,OBJPROP_COLOR,P_color2); } } } }
Y a añadir las siguientes líneas de código a la función OnTick:
//+------------------------------------------------------------------+ int GTC=GetTickCount(); //+------------------------------------------------------------------+ name="H"+(string)GTC; Draw_Point(name,BBH[1],BBH[0],MA[1],MA[0],170,178,Red,Red); name="L"+(string)GTC; Draw_Point(name,BBL[1],BBL[0],MA[1],MA[0],170,178,Blue,Blue); name="M"+(string)GTC; Draw_Point(name,BBM[1],BBM[0],MA[1],MA[0],170,178,Green,Green); //--- ChartRedraw(0);
Vamos ahora a ejecutar el asesor experto y ver el resultado (Fig. 7.).
No está mal, pero hay algunos casos de intersección que no hemos considerado. Por ejemplo, el indicador iBands tiene tres líneas que se cruzan entre sí y pueden complementar todo el conjunto.
Fig. 7. La emisión de los indicadores iMA y iBands (3 intersecciones).
Ahora vamos a intentar añadir otra serie de puntos a la emisión calculada, que serán la intersección de las siguientes líneas:- entre la línea "BH" (iBands = UPPER_BAND) y la "BL" (iBands = LOWER_BAND);
- entre la línea "BH" (iBands = UPPER_BAND) y la "BM" (iBands = BASE_BAND);
- entre la línea "BL" (iBands = LOWER_BAND) y la "BM" (iBands = BASE_BAND).
Debido a estas intersecciones obtendríamos 3 puntos, pero todos ellos tienen las mismas coordenadas. Por tanto, es suficiente usar una sola intersección entre la línea "BH" y la "BL".
Vamos a añadir estas líneas de código a nuestro asesor experto y ver el resultado (Fig. 8.).
name="B"+(string)GTC; Draw_Point(name,BBH[1],BBH[0],BBL[1],BBL[0],170,178,Magenta,Magenta);
Fig. 8. La emisión de los indicadores iMA y iBands (4 intersecciones).
Tenemos la emisión pero tengo la impresión de que nos hemos olvidado de algo importante. Pero ¿qué hemos olvidado?
¿Por qué hemos usado dichos parámetros de entrada? ¿Qué obtendríamos si los cambiásemos? Y en cualquier caso, ¿cuál es su papel en las emisiones?
De acuerdo, la emisión que tenemos representa una única frecuencia, que deriva de los parámetros de entrada del indicador. Para calcular todo el espectro multifrecuencia es necesario realizar los mismos cálculos para las demás frecuencias. Como ejemplo, esta es mi versión del espectro de emisión posible:
//---- handles for indicators int MAHandle[5]; // handles array of iMA indicators int BBHandle[7]; // handles array of iBands indicator //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- MAHandle[0]=iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE); MAHandle[1]=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE); MAHandle[2]=iMA(NULL,0,55,0,MODE_EMA,PRICE_CLOSE); MAHandle[3]=iMA(NULL,0,89,0,MODE_EMA,PRICE_CLOSE); MAHandle[4]=iMA(NULL,0,144,0,MODE_EMA,PRICE_CLOSE); //--- BBHandle[0]=iBands(NULL,0,55,0,2,PRICE_CLOSE); BBHandle[1]=iBands(NULL,0,89,0,2,PRICE_CLOSE); BBHandle[2]=iBands(NULL,0,144,0,2,PRICE_CLOSE); BBHandle[3]=iBands(NULL,0,233,0,2,PRICE_CLOSE); BBHandle[4]=iBands(NULL,0,377,0,2,PRICE_CLOSE); BBHandle[5]=iBands(NULL,0,610,0,2,PRICE_CLOSE); BBHandle[6]=iBands(NULL,0,987,0,2,PRICE_CLOSE); //--- return(0); }
Para tener en cuenta todas las combinaciones posibles vamos a añadir el siguiente código al asesor experto:
//+------------------------------------------------------------------+ CopyTime(NULL,0,0,10,T); ArraySetAsSeries(T,true); int GTC=GetTickCount(); //+------------------------------------------------------------------+ int iMax=ArraySize(BBHandle)-1; int jMax=ArraySize(MAHandle)-1; for(int i=0; i<iMax; i++) { for(int j=0; j<jMax; j++) { //--- filling the arrays with current values CopyBuffer(MAHandle[j],0,0,2,MA); ArraySetAsSeries(MA,true); CopyBuffer(BBHandle[i],0,0,2,BBM); ArraySetAsSeries(BBM,true); CopyBuffer(BBHandle[i],1,0,2,BBH); ArraySetAsSeries(BBH,true); CopyBuffer(BBHandle[i],2,0,2,BBL); ArraySetAsSeries(BBL,true); name="H"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBH[1],BBH[0],MA[1],MA[0],250,158,Aqua,Aqua); name="L"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBL[1],BBL[0],MA[1],MA[0],250,158,Blue,Blue); name="M"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBM[1],BBM[0],MA[1],MA[0],250,158,Green,Green); name="B"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBH[1],BBH[0],BBL[1],BBL[0],250,158,Magenta,Magenta); } } //--- ChartRedraw(0);
Cuantas más frecuencias estén involucradas en el espectro de emisión, mejor será la imagen en el gráfico, pero no debemos abusar de ello ya que sería tan solo una forma simple de agotar los recursos del ordenador y de conseguir el caos en el gráfico. El número de frecuencias puede determinarse experimentalmente. Para percibir mejor los gráficos debemos prestar especial atención al estilo de dibujo.
Fig. 9. Espectro de emisión multifrecuencia.
De los estilos de dibujo de las emisiones
El lenguaje MQL5 proporciona un amplio rango de colores web y caracteres windings para dibujar emisiones. Me gustaría compartir mis ideas al respecto:- Cada persona tiene su propia percepción de las imágenes gráficas, por lo que necesitaremos algún tiempo para personalizar las emisiones.
- El "caos" de la Fig. 9. no permite reconocer ninguna irregularidad o patrón en las imágenes. Es un ejemplo de un mal dibujo.
- Trataremos de usar los colores más próximos en el espectro del arcoíris.
- Los códigos de caracteres para el pasado (desde la izquierda de la barra [0]) y para el futuro (desde la derecha de la barra [0]) pueden diferir.
- La combinación correcta de colores y formas de puntos puede convertir la emisión en una obra maestra que no solo ayudaría en las transacciones sino que también sería una placer para la vista.
name="H"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBH[1],BBH[0],MA[1],MA[0],250,158,Aqua,Aqua); name="L"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBL[1],BBL[0],MA[1],MA[0],250,158,Blue,Blue); name="M"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBM[1],BBM[0],MA[1],MA[0],250,158,Magenta,Magenta); name="B"+(string)GTC+(string)i+(string)j; Draw_Point(name,BBH[1],BBH[0],BBL[1],BBL[0],250,158,DarkOrchid,DarkOrchid);
La galería de emisiones iMA e iBands
En este capítulo se presentan las imágenes con estas emisiones.
Fig. 10.
Fig. 11
Fig. 12
Fig. 13
Fig. 14
Fig. 15
Fig. 16
Fig. 17
Análisis de emisiones
El análisis de las emisiones es una tarea distinta. Lo más útil es mirar a su dinámica en tiempo real, ya que es la mejor forma de comprender muchos efectos y patrones.
Preste atención a las correcciones de precio, parece que las emisiones "conocen" el precio de destino. Además, puede ver los niveles del precio de apoyo, resistencia y equilibrio.
Conclusión
- Las emisiones de los indicadores pueden ser interesantes para los operadores y los desarrolladores de sistemas de trading que busquen nuevos enfoques en la investigación de mercado y el análisis.
- Como artículo introductorio, no contiene las soluciones finales. Sin embargo, la tecnología presentada para el cálculo de emisiones puede aplicarse a otros indicadores o sus combinaciones.
- Mientras preparaba este artículo he recopilado más preguntas que respuestas. Estas son algunas: ¿cómo optimizar el algoritmo del dibujo de las emisiones?; ¿cuál es el papel de las características del espectro de emisión en la estructura de la emisión?; ¿cómo usar las emisiones en el trading automatizado?
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/26





- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso