Português
preview
Del nivel básico al intermedio: Subventanas (I)

Del nivel básico al intermedio: Subventanas (I)

MetaTrader 5Ejemplos |
20 0
CODE X
CODE X

Introducción

En el artículo anterior, Del nivel básico al intermedio: Indicadores técnicos (II), mostré cómo añadir varias medias móviles a un mismo indicador de forma sencilla, sin tener que modificar mucho el código fuente. Esa forma de estructurar el código resulta muy útil cuando necesitas cambiar su comportamiento con rapidez y sin complicaciones.

Sin embargo, aunque aquel método es útil e interesante, representa solo una pequeña parte de lo que podemos hacer con los indicadores que añadimos a un gráfico.

Hay situaciones que exigen un enfoque más elaborado y un mejor aprovechamiento de los recursos de MQL5. Cuando eso no basta, también debemos conocer bien cómo funciona MetaTrader 5, ya que MQL5 sirve principalmente para controlar el comportamiento de la plataforma y obtener los resultados que buscamos. Muchos creen que MQL5 es un lenguaje de propósito general, como C o C++, pero no es así. Por eso debemos comprender hasta dónde podemos llegar con MQL5 antes de recurrir a soluciones más radicales.

En algunos de mis primeros artículos publicados en esta comunidad presenté un tipo de implementación posible en MetaTrader 5. En aquel momento cometí el error de suponer que los miembros de la comunidad ya tenían bastante experiencia programando. Por eso no expliqué debidamente por qué funcionaba aquella implementación ni qué había que tener en cuenta antes de añadirla a un gráfico. Es posible que muchos la encontraran interesante, pero no consiguieran utilizarla porque aún no tenían los conocimientos necesarios.

Y, por favor, no me malinterpretes cuando digo que probablemente todavía no estás preparado para entender cómo funcionan esas aplicaciones. Al contrario: siéntete motivado y dispuesto a aprender. El remedio para la falta de conocimientos no es el orgullo, sino la humildad para reconocer que aún tenemos mucho que aprender unos de otros.

Bien, si no sabes a qué me refería en la introducción, puedes consultar Múltiples indicadores en un gráfico (Parte 03): Desarrollo de definiciones para usuarios. Ahora sí, es hora de dejar a un lado las distracciones y concentrarnos en este artículo.


Uso de subventanas (I)

En muchas situaciones necesitamos mostrar un indicador en una subventana o, al menos, nos resulta más conveniente hacerlo. Quizá «subventana» no sea el mejor nombre, pero, como dijo una vez un amigo:

Los programadores son pésimos poniendo nombres a las cosas.

En cualquier caso, ese es el término que se utiliza y nosotros también lo adoptaremos. A diferencia de lo que muchos creen, crear un indicador para mostrarlo en una subventana no suele ser complicado, al menos en los casos más habituales. Sin embargo, algunas situaciones pueden resultar confusas si no aplicas los conceptos adecuados: esperas que algo funcione de cierta manera y descubres que funciona de otra completamente distinta. Esto ocurría con frecuencia en mis primeros artículos, que terminaban generando más dudas que respuestas. Como dije, fue un error por mi parte.

Había supuesto que los artículos siempre se dirigían a personas con cierta experiencia, pero no era así. Por eso decidí crear un nuevo perfil dedicado exclusivamente a explicar los pequeños detalles que influyen en las decisiones que tomamos al implementar una solución real. También quería mostrar a principiantes y entusiastas cómo pensar al escribir código. Así surgieron estos artículos.

Ya hemos tratado temas que van desde lo más básico, como la sintaxis de las instrucciones esenciales, hasta otros algo más complejos, como la sobrecarga de operadores. Quedan por explicar algunos detalles de programación básica, pero eso no nos impide hacer cosas interesantes y entretenidas. Quiero darte tiempo para asimilar la sobrecarga de operadores, sin duda el tema más complejo de los que hemos visto hasta ahora. Por eso, durante algunos artículos abordaremos temas más sencillos de comprender, mientras aumentamos la dificultad poco a poco.

Así todos podrán seguirlos sin agotarse, ya que no es necesario leerlos en un orden determinado. Piensa en estos artículos como una ampliación de la documentación de MQL5, que siempre debes consultar cuando tengas dudas.

Bien, ¿qué veremos en este artículo? Daremos los primeros pasos para trabajar con una subventana. Veremos cómo puede utilizarla nuestro código incluso cuando no lo hemos programado expresamente para ello. Entender esto es fundamental para comprender otros aspectos más complejos que trataremos más adelante.

Como no quiero escribir código desde cero y dedicar tiempo a explicar cómo funciona, tomaremos el del artículo anterior para estudiar estos primeros pasos.

El código original aparece a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. const struct stAverange
07. {
08.    uint           nPeriods;
09.    ENUM_MA_METHOD Method;
10.    color          cor;
11. }Averange[] = 
12. {
13.    {9, MODE_EMA, clrRed},
14.    {20, MODE_SMA, clrGreen},
15.    {50, MODE_SMA, clrBlue},
16.    {200, MODE_SMA, clrBlack}
17. };
18. //+----------------+
19. #property indicator_chart_window
20. #property indicator_applied_price   PRICE_CLOSE
21. #property indicator_buffers         Averange.Size();
22. #property indicator_plots           Averange.Size();
23. //+------------------------------------------------------------------+
24. struct stInfos
25. {
26.    double   Buff_iMA[];
27.    int      Handle;
28. }Infos[Averange.Size()];
29. //+------------------------------------------------------------------+
30. int OnInit(void)
31. {
32.    for (uint c = 0; c < Averange.Size(); c++)
33.    {
34.       SetIndexBuffer(c, Infos[c].Buff_iMA, INDICATOR_DATA);
35.       PlotIndexSetInteger(c, PLOT_DRAW_TYPE, DRAW_LINE);
36.       PlotIndexSetInteger(c, PLOT_LINE_STYLE, STYLE_SOLID);
37.       PlotIndexSetInteger(c, PLOT_LINE_WIDTH, 2);
38.       PlotIndexSetInteger(c, PLOT_LINE_COLOR, Averange[c].cor);
39.       PlotIndexSetString(c, PLOT_LABEL, StringFormat("%s of %d", (Averange[c].Method == MODE_EMA ? "Exponential" : "Arithmetica"), Averange[c].nPeriods));
40.       if ((Infos[c].Handle = iMA(NULL, NULL, Averange[c].nPeriods, 0, Averange[c].Method, _AppliedTo)) == INVALID_HANDLE)
41.       {
42.          Print("Could not start the indicator...");
43.          return INIT_FAILED;
44.       };
45.    }
46. 
47.    return INIT_SUCCEEDED;
48. };
49. //+------------------------------------------------------------------+
50. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
51. {
52.    for (uint c = 0; c < Averange.Size(); c++)
53.    {
54.        ArrayInitialize(Infos[c].Buff_iMA, EMPTY_VALUE);
55.       CopyBuffer(Infos[c].Handle, 0, 0, Averange[c].nPeriods, Infos[c].Buff_iMA);
56.    }
57. 
58.    return rates_total;
59. };
60. //+------------------------------------------------------------------+
61. void OnDeinit(const int reason)
62. {
63.    for (uint c = 0; c < Averange.Size(); c++)
64.       IndicatorRelease(Infos[c].Handle);
65. };
66. //+------------------------------------------------------------------+

Código 01

En el código 01 hay una indicación interesante para el compilador: la línea 19. Esta le dice que el indicador utilizará la ventana en la que se aplique. «Ah, pero eso es obvio». Tal vez no hayas reparado en lo que significa, querido lector. NO DIJE que el indicador utilizará la ventana en la que se trazan las barras. Dije que utilizará la ventana donde lo coloques. Mucha gente pasa por alto esta distinción, comete un gran error y termina diciendo que MetaTrader 5 es una plataforma horrible.

Para que resulte más fácil de entender, modificaremos el código 01 con el fragmento que aparece a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. const struct stAverange
07. {
08.    uint           nPeriods;
09.    ENUM_MA_METHOD Method;
10.    color          cor;
11. }Averange[] = 
12. {
13.    // {9, MODE_EMA, clrRed},
14.    {20, MODE_SMA, clrGreen},
15.    // {50, MODE_SMA, clrBlue},
16.    // {200, MODE_SMA, clrBlack}
17. };
18. //+----------------+
                   .
                   .
                   .

Fragmento 01

Ahora solo se trazará una de las medias. Si no entiendes el cambio, consulta los artículos anteriores, donde ya lo expliqué. Aquí no volveré a detenerme en esos detalles. Al añadir el indicador al gráfico, veremos el resultado que muestra la siguiente imagen.

Imagen 01

Vamos a extender el trazado de esta media móvil para que abarque más barras. Basta con modificar el código como muestra el siguiente fragmento.

                   .
                   .
                   .
49. //+------------------------------------------------------------------+
50. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
51. {
52.    for (uint c = 0; c < Averange.Size(); c++)
53.    {
54.        ArrayInitialize(Infos[c].Buff_iMA, EMPTY_VALUE);
55.       CopyBuffer(Infos[c].Handle, 0, 0, Bars(NULL, NULL), Infos[c].Buff_iMA);
56.    }
57. 
58.    return rates_total;
59. };
60. //+------------------------------------------------------------------+
                   .
                   .
                   .

Fragmento 02

El resultado aparece a continuación.

Imagen 02

Todo esto ya se explicó anteriormente. Hemos llegado al punto desde el que quería empezar a tratar otro aspecto.

Antes de escribir código que utilice una subventana, debemos entender cómo trabaja MetaTrader 5 con ellas. Y sí, aunque te parezca sencillo, querido lector, muchos programadores y operadores NO SABEN CÓMO TRABAJA METATRADER 5 CON LAS SUBVENTANAS. Aun así, algunos afirman con total seguridad que tienen mucha experiencia usando MetaTrader 5. Vamos, eso es, como mínimo, trágico.

Entre los indicadores precompilados que vienen con MetaTrader 5, hay varios que utilizan una subventana. Para nuestro propósito, escogeremos uno clásico: el que muestra el volumen negociado. Al añadirlo al gráfico, el aspecto que tenía en la imagen 02 pasa a ser el que muestra la siguiente imagen.

Imagen 03

La ventana que ves en la parte inferior del gráfico es una subventana. Ahora presta atención. Una subventana está vinculada de algún modo a la ventana principal, pero tiene sus propios mecanismos y ajustes. Incluso podemos modificarla para que funcione como lo que consideraríamos una ventana principal. Un momento, ahora me has confundido. ¿Me estás diciendo que la ventana de la parte inferior del gráfico puede utilizarse como si fuera la principal? Sí, querido lector, exactamente. Pero, si lo haces, tendrás que tener en cuenta las consecuencias.

Como este es apenas el primer artículo en el que hablamos del tema, no entraré en esos detalles todavía. Los entenderás mejor a medida que publiquemos nuevos artículos.

Volvamos a nuestra cuestión principal. ¿Recuerdas la línea 19 de nuestro código? Bien, ahora queremos hacer algo que, por lo que sé, es bastante habitual. Muchos operadores no observan directamente el volumen que aparece en la subventana: añaden una media y se fijan en ella. Pero espera, ¿cómo añadimos una media móvil a ese volumen?

Precisamente, ese es uno de los pasos que muchos no saben realizar. Y, cuando lo intentan, suelen equivocarse, lo que perjudica considerablemente el análisis que querían hacer.

Para ver el problema, observa la siguiente animación.

Animación 01

En cierto modo, la animación 01 muestra la forma correcta de añadir un indicador a una subventana. Sin embargo, fíjate en la curva que traza la media móvil. La siguiente imagen permite verla con más claridad.

Imagen 04

Aquí se aprecia que la curva de la media móvil NO REFLEJA LA CURVA DEL VOLUMEN. La media móvil que aparece en la subventana sigue la curva de cotizaciones de la ventana principal. Eso no era lo que el operador quería. Así que, aprovechando su experiencia con MetaTrader 5, hace lo que muestra la siguiente animación.

Animación 02

Pero ¿qué ha pasado? ¿Dónde está la media móvil del volumen? Algo ha ocurrido. Para averiguarlo, el operador abre el terminal y encuentra el siguiente mensaje.

Imagen 05

Bien, ahora sí tenemos un problema. Ah, ya sé: la culpa es de la plataforma. Un momento, querido lector. La culpa no es de la plataforma, sino tuya o, mejor dicho, del programador que escribió el código del indicador. Espera, ¿lo hemos programado nosotros? ¿Me estás diciendo que somos incompetentes? No es eso, querido lector. Como dije al principio del artículo, hay que tener la humildad de aceptar que no lo sabemos todo y que siempre podemos aprender algo unos de otros.

El problema está, efectivamente, en el código del indicador. ¿Recuerdas que en los artículos anteriores expliqué cómo funcionan los indicadores técnicos y por qué? Sus cálculos funcionan bien, como muestran las imágenes: la curva de la media se traza correctamente en el gráfico principal. Sin embargo, NO SON ADECUADOS para calcular a partir de datos de otros indicadores cuyos valores MetaTrader 5 desconoce. Si cambiamos la fuente de datos para utilizar otro indicador, en este caso el de volumen, el indicador técnico que empleamos, iMA, no llega a calcularse. MetaTrader 5 no sabe qué valores contiene el indicador de volumen; por eso falla el código y aparece el resultado de la imagen 05. Así que acepta que no siempre sabemos lo que hacemos. Reconocerlo con humildad suele ayudarnos a entender las cosas correctamente.

Mmm, de acuerdo. Pero entonces te pregunto: ¿cómo podemos resolverlo? Tiene que haber alguna solución, ¿no? Sí la hay, querido lector. Aquí es donde el tema se vuelve más interesante, aunque también algo más complicado. Tendremos que implementar nosotros mismos el cálculo de la media móvil, sin depender de la ayuda de MetaTrader 5; es decir, no podremos recurrir a los indicadores técnicos ya disponibles. Ahí radica la dificultad: al programar estos cálculos, muchos cometen errores, ya sea en el cálculo mismo o al escribir un código que consume muchos más recursos de los necesarios.

Por tanto, haz lo que vamos a hacer aquí solo como último recurso o si estás completamente seguro de lo que haces. Cualquier error que cometas será tu responsabilidad. Una vez aclarado esto, podemos empezar a escribir el código.

Para comenzar, simplificaremos un poco el código 01. Quedará como se muestra a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. const struct stAverange
07. {
08.     int            nPeriods;
09.     ENUM_MA_METHOD Method;
10.     color          cor;
11. }Averange[] = 
12. {
13.     {9, MODE_EMA, clrRed},
14.     {20, MODE_SMA, clrGreen},
15. };
16. //+----------------+
17. #property indicator_chart_window
18. #property indicator_applied_price   PRICE_CLOSE
19. #property indicator_buffers         Averange.Size();
20. #property indicator_plots           Averange.Size();
21. //+------------------------------------------------------------------+
22. struct stInfos
23. {
24.     double   Buff_iMA[];
25. }Infos[Averange.Size()];
26. //+------------------------------------------------------------------+
27. int OnInit(void)
28. {
29.     for (uint c = 0; c < Averange.Size(); c++)
30.     {
31.         SetIndexBuffer(c, Infos[c].Buff_iMA, INDICATOR_DATA);
32.         PlotIndexSetInteger(c, PLOT_DRAW_TYPE, DRAW_LINE);
33.         PlotIndexSetInteger(c, PLOT_LINE_STYLE, STYLE_SOLID);
34.         PlotIndexSetInteger(c, PLOT_LINE_WIDTH, 2);
35.         PlotIndexSetInteger(c, PLOT_LINE_COLOR, Averange[c].cor);
36.         PlotIndexSetString(c, PLOT_LABEL, StringFormat("%s of %d", (Averange[c].Method == MODE_EMA ? "Exponential" : "Arithmetica"), Averange[c].nPeriods));
37.     }
38. 
39.        return INIT_SUCCEEDED;
40. };
41. //+------------------------------------------------------------------+
42. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
43. {
44.     for (uint c = 0; c < Averange.Size(); c++)
45.     {
46.     }
47. 
48.     return rates_total;
49. };
50. //+------------------------------------------------------------------+

Código 02

Este es el código del que partiremos. He eliminado varias partes, sobre todo la que nos daba acceso al indicador técnico iMA. Ahora añadiremos algunos elementos que nos ayudarán con los cálculos. Para ello, modificaremos el código 02 como muestra el siguiente fragmento.

                   .
                   .
                   .
21. //+------------------------------------------------------------------+
22. struct stInfos
23. {
24.     double  Buff_iMA[],
25.             f_Expo;
26. }Infos[Averange.Size()];
27. //+------------------------------------------------------------------+
28. int OnInit(void)
29. {
30.     for (uint c = 0; c < Averange.Size(); c++)
31.     {
32.         SetIndexBuffer(c, Infos[c].Buff_iMA, INDICATOR_DATA);
33.         Infos[c].f_Expo = (double) (2.0 / (1.0 + Averange[c].nPeriods));
34.         PlotIndexSetInteger(c, PLOT_DRAW_TYPE, DRAW_LINE);
35.         PlotIndexSetInteger(c, PLOT_LINE_STYLE, STYLE_SOLID);
36.         PlotIndexSetInteger(c, PLOT_LINE_WIDTH, 2);
37.         PlotIndexSetInteger(c, PLOT_LINE_COLOR, Averange[c].cor);
38.         PlotIndexSetString(c, PLOT_LABEL, StringFormat("%s of %d", (Averange[c].Method == MODE_EMA ? "Exponential" : "Arithmetica"), Averange[c].nPeriods));
39.     }
40. 
41.        return INIT_SUCCEEDED;
42. };
43. //+------------------------------------------------------------------+
                   .
                   .
                   .

Fragmento 03

Ya podemos centrarnos en el cálculo, pues tenemos preparada la base necesaria. Lo implementaremos como muestra el siguiente fragmento.

                   .
                   .
                   .
43. //+------------------------------------------------------------------+
44. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
45. {
46.     int c0 = 0;
47. 
48.     for (uint c = 0; c < Averange.Size(); c++)
49.     {
50.         if (prev_calculated == 0)
51.         {
52.             double loc = 0;
53.             for (int c1 = 0; c1 < Averange[c].nPeriods; c1++) loc += price[Averange[c].nPeriods - c1];
54.             Infos[c].Buff_iMA[Averange[c].nPeriods] = loc / Averange[c].nPeriods;
55.         }
56.         switch (Averange[c].Method)
57.         {
58.             case MODE_EMA:
59.                 for (c0 = (prev_calculated > 0 ? prev_calculated - 1 : 0); c0 < rates_total; c0++)
60.                     Infos[c].Buff_iMA[c0] = (c0 > 0 ? (((price[c0] - Infos[c].Buff_iMA[c0 - 1])) * Infos[c].f_Expo) + Infos[c].Buff_iMA[c0 - 1] : Infos[c].Buff_iMA[c0]);
61.                 break;
62.             case MODE_SMA:
63.                 for (c0 = (prev_calculated > 0 ? prev_calculated - 1 : Averange[c].nPeriods + 1); c0 < rates_total; c0++)
64.                     Infos[c].Buff_iMA[c0] = ((Infos[c].Buff_iMA[c0 - 1] * Averange[c].nPeriods) - price[c0 - Averange[c].nPeriods] + price[c0]) / Averange[c].nPeriods;
65.                 break;
66.         }
67.     }
68. 
69.     return rates_total;
70. };
71. //+------------------------------------------------------------------+

Fragmento 04

No entraré en los detalles de estos cálculos para no extenderme. A estas alturas, estoy seguro de que ya puedes entender qué hacen. Recuerda que este ejemplo tiene fines didácticos y no presenta la forma más eficiente de calcularlo: el propio MQL5 ofrece maneras mucho más rápidas.

Una vez compilado el código 02 con los cambios de ambos fragmentos, podremos ver cómo funciona. Primero añadiremos el indicador directamente al gráfico principal, como se muestra en la siguiente animación.

Animación 03

Observa que funciona. Para comprobar que las medias se calculan correctamente, utiliza el mismo principio que mostramos en los artículos anteriores. Siempre conviene asegurarse de que no hay errores en los cálculos. Después podremos dar el siguiente paso: añadir el indicador a la subventana donde aparece el volumen. Lo haremos como antes, según muestra la siguiente animación.

Animación 04

Observa que la curva de la media conserva la misma forma que la que vemos en la zona donde se trazan las barras de cotización. Esto significa que estamos viendo la media de los precios y no la del volumen, como esperábamos. La siguiente imagen permite apreciarlo con claridad.

Imagen 06

Bien, el siguiente paso es hacer el cambio que muestra la siguiente animación.

Animación 05

¡Por fin ha funcionado! Como quizá la animación sea demasiado rápida para apreciarlo, examinemos con más calma los últimos fotogramas de la animación 05, capturados en la siguiente imagen.

Imagen 07

Ahora sí tenemos un indicador que funciona correctamente y resulta adecuado para muchas más situaciones, incluso para aplicarlo a subventanas. Pero espera, antes de terminar el artículo, ¿podrías explicarme algunas cosas de lo que hemos visto? Por supuesto, querido lector. Dime qué dudas tienes.

Mi primera duda es esta: he observado que tanto el código 01 como el código 02 utilizan la propiedad indicator_chart_window. Según entiendo por la documentación, esta propiedad indica que el indicador se mostrará en la ventana del gráfico y no en otra. Sin embargo, aquí dijiste que algunos indicadores crean una ventana nueva, o subventana. En las animaciones, el indicador de volumen crea una subventana y nuestro indicador aparece en ella. ¿Por qué? ¿No debería permanecer vinculado a la ventana principal, donde se trazan las barras? Excelente pregunta, querido lector. Antes de pasar a la siguiente duda, veamos por qué nuestro indicador aparece en la subventana a pesar de utilizar la propiedad indicator_chart_window. El detalle que suele confundir a muchos principiantes es precisamente este.

Para responder a tu pregunta sin complicar demasiado la explicación, repasemos las animaciones, sobre todo la 02 y la 04, en las que añadimos el indicador al gráfico. Observa que, en ambas, arrastramos el indicador y lo soltamos en un lugar concreto: dentro de la subventana creada por el indicador de volumen.

Presta mucha atención a este detalle, porque aquí marca toda la diferencia. MetaTrader 5 interpreta dónde hemos soltado el indicador y, al cargar el indicador que utiliza la propiedad indicator_chart_window, trata esa subventana como la ventana principal para ese indicador. Aquí es donde surge gran parte de la confusión: MetaTrader 5 NO CAMBIARÁ AUTOMÁTICAMENTE LA FUENTE DE DATOS DEL INDICADOR para que utilice los valores de esa subventana. Tú, como operador, debes cambiar manualmente la fuente de datos que utiliza el indicador, tal como vimos en las animaciones.

Muchas personas vienen de otras plataformas donde ese cambio se realiza automáticamente, como PROFIT, muy utilizada por operadores en Brasil. Al ver que la media no se ajusta como esperaban, terminan teniendo una mala experiencia con MetaTrader 5.

Bien, creo que lo he entendido. Pero tengo otra duda. En las animaciones 02 y 05, cuando cambias el parámetro de cálculo, eliges FIRST INDICATOR'S DATA, aunque también podrías elegir PREVIOUS INDICATOR'S DATA. ¿Por qué prefieres uno al otro? Vaya, tenemos aquí a un lector muy observador. Me gusta la pregunta. Todavía es pronto para explicarlo a fondo, pero intentaré mostrarte el motivo sin entrar en todos los detalles. Eso lo haremos más adelante.

Para que te hagas una idea de por qué elegí un parámetro y no el otro en esas animaciones, modificaremos el código 02 como se muestra a continuación. Es un cambio sencillo, pero te ayudará a entenderlo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. const struct stAverange
07. {
08.     int            nPeriods;
09.     ENUM_MA_METHOD Method;
10.     color          cor;
11. }Averange[] = 
12. {
13.     {3, MODE_SMA, clrBlack}
14. };
15. //+----------------+
                   .
                   .
                   .

Fragmento 05

Observa que ahora el código calcula una media aritmética de período muy corto. Así nos aseguraremos de que el efecto sea visible. Quizá esta no sea la mejor explicación, pero al menos ayudará a satisfacer parte de tu curiosidad.

Una vez creado y compilado, podemos añadir el indicador al gráfico. El resultado aparece en la siguiente imagen.

Imagen 08

Ahora lo configuraremos para que utilice la opción que muestra la siguiente imagen.

Imagen 09

Al hacerlo, obtendremos el resultado que aparece a continuación.

Imagen 10

Observa que he cambiado el color y el grosor de la línea para que resulte más fácil apreciar lo que ocurrirá después. Ahora añadiremos otra instancia del mismo indicador. El resultado aparece a continuación.

Imagen 11

Presta atención a este ajuste; lo explicaré con más detalle más adelante. Como tenemos dos medias en pantalla, haremos que la negra utilice la opción que muestra la siguiente imagen.

Imagen 12

Esta vez elegimos un parámetro diferente. Sin embargo, el resultado será el que verás a continuación.

Imagen 13

Qué extraño. Pensé que el resultado sería el mismo. Ahora estoy algo confundido: nunca me había detenido a pensar cuál de estos parámetros debía elegir. Para mí, los dos eran iguales. Así es, querido lector. A menudo creemos que algo funciona de cierta manera y descubrimos que funciona de otra completamente distinta. Lo que ves en la imagen 13 puede parecer extraño, pero tiene una explicación y, en algunos casos, incluso puede resultar útil, aunque cabría preguntarse hasta qué punto. Conozco operadores que sí lo utilizan.


Consideraciones finales

En este artículo mostré los principios básicos del uso de las subventanas. Algunas cuestiones, como por qué elegir un tipo de entrada u otro para calcular el indicador, aún no han quedado del todo explicadas; las abordaremos en los próximos artículos. Aun así, creo que lo visto aquí permite comprender que, para utilizar correctamente MetaTrader 5, debemos prestar atención tanto a la programación como a la forma en que utilizamos los indicadores que añadimos a un gráfico.

En el próximo artículo veremos aspectos más específicos de las subventanas. Es un recurso que podemos aprovechar de distintas maneras e incluso utilizar como base para un posible sistema que permita una interacción más avanzada con el usuario. Para llegar a hacerlo, primero necesitas comprender mejor cómo trabajar con ellas.

Archivo MQ5Descripción
Indicators\Code 01Demostración básica
Indicators\Code 02Demostración básica
Indicators\Code 03Demostración básica

Traducción del portugués realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/pt/articles/17086

Archivos adjuntos |
Anexo.zip (3.03 KB)
Red neuronal en la práctica: Cuándo usar una neurona artificial y entender su función en MQL5 Red neuronal en la práctica: Cuándo usar una neurona artificial y entender su función en MQL5
Implementamos en MQL5 una neurona entrenada mediante descenso de gradiente estocástico y comparamos su función de costo con la regresión lineal. Mostramos, mediante código y gráficos, cómo la normalización, la elección de la tasa de aprendizaje y la estructura del problema afectan a la convergencia. El artículo ofrece una guía para depurar el entrenamiento, interpretar el comportamiento del error y seleccionar la arquitectura o la función de activación adecuada.
Desarrollo de asesores expertos autooptimizables en MQL5 (Parte 11): Una introducción sencilla a los fundamentos del álgebra lineal Desarrollo de asesores expertos autooptimizables en MQL5 (Parte 11): Una introducción sencilla a los fundamentos del álgebra lineal
En este artículo, sentaremos las bases para el uso de potentes herramientas algebraicas lineales implementadas en la API de matrices y vectores de MQL5. Para poder utilizar esta API con soltura, debemos tener un conocimiento sólido de los principios del álgebra lineal que rigen el uso adecuado de estos métodos. El objetivo de este artículo es que el lector adquiera una comprensión intuitiva de algunas de las reglas más importantes del álgebra lineal que nosotros, como traders algorítmicos en MQL5, necesitamos para empezar a sacar partido a esta potente biblioteca.
Probador de estrategias para Python-MetaTrader 5 (Parte 01): Simulador de operaciones Probador de estrategias para Python-MetaTrader 5 (Parte 01): Simulador de operaciones
El módulo de MetaTrader 5 disponible en Python ofrece una forma cómoda de abrir operaciones en la aplicación de MetaTrader 5 utilizando Python, pero presenta un gran problema: carece de la función de Probador de estrategias que sí incluye la aplicación de MetaTrader 5. En esta serie de artículos, crearemos un marco de trabajo para realizar pruebas retrospectivas de tus estrategias de trading en entornos de Python.
Redes neuronales en el trading: Señales de trading robustas en cualquier régimen de mercado (ST-Expert) Redes neuronales en el trading: Señales de trading robustas en cualquier régimen de mercado (ST-Expert)
En este artículo conoceremos el framework ST-Expert, que aporta robustez a las previsiones frente a la incertidumbre del mercado y permite tener en cuenta las dependencias locales y globales en las series temporales. Su arquitectura flexible favorece la adaptabilidad de los modelos y mejora la precisión de las predicciones.