English Русский 中文 Deutsch 日本語 Português 한국어 Français Italiano Türkçe
Control de eventos en MQL5: cambiar el periodo de la media móvil sobre la marcha

Control de eventos en MQL5: cambiar el periodo de la media móvil sobre la marcha

MetaTrader 5Indicadores | 23 enero 2014, 09:32
1 266 0
Sceptic Philozoff
Sceptic Philozoff

Introducción

Este breve artículo está dedicado a las nuevas características de MQL5 en la plataforma MetaTrader 5, desarrollada por MetaQuotes Software Corp. Quizás llegue tarde este artículo (debería haberse publicado en septiembre-octubre de 2009), pero no hubo artículos parecidos sobre este tema. Además, en aquel momento no existían dichas posibilidades para controlar eventos en los indicadores.

Imagine que tenemos algunos indicadores de precio simples aplicados a un gráfico (es este caso es la media móvil, es decir, MA), y queremos cambiar su periodo de ajuste. En la plataforma de MT4 teníamos las siguientes opciones:

  • En MetaEditor podíamos editar el parámetro de entrada del experto (extern) responsable del periodo de MA y a continuación compilar el archivo fuente.
  • Sin cambiar a MetaEditor, en la ventana del terminal podemos abrir el cuadro de diálogo de propiedades y editar ahí el parámetro de entrada correspondiente.
  • Podemos abrir la librería API Win32, encontrar funciones de captura de mensajes y modificar el código del indicador para que responda a los eventos del teclado.

Como sabemos, el deseo de minimizar los esfuerzos es el mayor motor del progreso. Ahora, gracias a la nueva plataforma de MT5, que permite controladores de eventos de indicadores iniciados por el usuario, podemos prescindir de las posibilidades anteriores y cambiar los parámetros del indicador con solo pulsar una tecla. Este artículo trata sobre la implementación técnica de la solución a este problema.


Asignación de tareas y problemas

El código fuente del indicador utilizado en nuestros experimentos se envía con el terminal de cliente. El archivo de código fuente (Custom Moving Average.mq5) se adjunta al final de este artículo.

Por ahora no analizaremos el código fuente, especialmente los cambios con respecto a MQL4. Sí, en algunas partes ha cambiado de forma considerable y esto no siempre es obvio. Las explicaciones correspondientes relativas a la reestructuración de la parte básica del cálculo se encuentran en el foro y en la ayuda en línea.

No obstante, la parte principal del indicador en MQL4 permanece inalterada. Al menos el 80% de los cambios en el código destinados a resolver nuestro problema se han realizado sobre la idea de las funciones de cómputo del indicador como "cajas negras".

Un ejemplo de lo que queremos conseguir sería el siguiente. Supongamos que hemos aplicado este indicador a un gráfico y que en un momento determinado se visualiza una MA exponencial (EMA) con cambio cero y periodo 10. Nuestro objetivo es incrementar el periodo de ajuste de la MA simple (SMA) en 3 (hasta 13) y cambiarlo por 5 barras a la derecha. La secuencia de acción asumida es la siguiente:

  • Presionamos la tecla TAB varias veces para cambiar la MA de exponencial a simple (cambiando el tipo de MA).
  • Presionamos la tecla de flecha arriba en la parte principal del teclado tres veces para incrementar el periodo de la MA simple en 3.
  • Presionando la tecla de flecha ARRIBA (8) en el teclado numérico 5 veces para compensar MA en 5 barras a la derecha.

La primera y más obvia solución es insertar la función OnChartEvent() en el código del indicador y escribir el controlador de evento de pulsación de teclas. Según la lista de cambios en las versiones 245 y 246 del terminal de cliente de MetaTrader 4 https://www.mql5.com/en/forum/53/page1/#comment_2655,

Versiones 245 y 246 del terminal de cliente de MetaTrader 5

MQL5: incorpora la posibilidad de controlar eventos mediante indicadores personalizados, de forma similar a los asesores expertos.

Ahora no tenemos ningún problema al añadir un nuevo controlador de evento en el indicador. Pero para esto todavía tenemos que modificar ligeramente su código.

Primero, en MQL5 el estado de los parámetros externos del indicador ha cambiado: no podemos modificarlos en el código. La única forma de cambiarlos es mediante el cuadro de diálogo Propiedades del terminal de cliente. Generalmente, cuando hay una necesidad urgente de cambiarlos puede superarse esta restricción con facilidad: copiamos los valores de los parámetros externos en las nuevas variables globales del indicador y se realizan todos los cálculos como si estas variables fueran actualmente los parámetros externos del indicador. Por otro lado, en este caso desaparece la fiabilidad de los parámetros externos cuyos valores solo pueden inducir a error a los usuarios. Ahora, estos parámetros son simplemente innecesarios.

De esta forma, no hay parámetros (de entrada) externos en el indicador. Las variables que juegan el papel de parámetros externos ahora serán las variables globales del terminal o TGV de forma abreviada. Si quiere ver la TGV responsable de los primeros parámetros externos del indicador, puede pulsar la tecla F3 en el terminal. No veo ninguna otra forma sencilla de controlar los parámetros del indicador.

Segundo (y esto es importante), con cualquier cambio en los parámetros del indicador tenemos que recalcular todos sus valores a lo largo del historial de nuevo partiendo de cero. En otras palabras, tendremos que realizar los cálculos que son habitualmente realizados solo en el primer inicio del indicador. La optimización de los cálculos del indicador se mantiene pero ahora es más sutil.

A continuación se muestran algunas partes del código de la primera versión del indicador modificado. El código al completo se adjunta al final de este artículo.

 

Versión "estándar": la descripción de los cambios en el código fuente del indicador estándar

Los parámetros externos ya no son externos, tan solo variables globales

Todos los parámetros externos del indicador han perdido su modificador de entrada. Generalmente, ni siquiera podría hacerlos globales, pero he decidido hacerlo por tradición:

int              MA_Period   = 13;
int              MA_Shift    =  0;
ENUM_MA_METHOD   MA_Method   =  0;
int              Updated     =  0;     /// Indicates whether the indicator has updated after changing it's values

Las primeras tres opciones son el periodo, el desplazamiento y el tipo de media móvil, y el cuarto, Updated, es responsable de la optimización de los cálculos al cambiar los parámetros de la media móvil. Las explicaciones se encuentran unas líneas más abajo. 

Códigos de teclas virtuales

Introducir los códigos de las teclas virtuales:

#define KEY_UP             38
#define KEY_DOWN           40
#define KEY_NUMLOCK_DOWN   98
#define KEY_NUMLOCK_UP    104
#define KEY_TAB             9

Estos códigos son para las teclas "flecha arriba" y "flecha abajo", flechas en el teclado numérico (tecla "8" y "2") así como la tecla TAB. Los mismos códigos (con otros nombres de constantes VK_XXX) existen actualmente en el archivo <MT5dir>\MQL5\Include\VirtualKeys.mqh , pero en este caso he decidido dejarlo como está.


Pequeña corrección del código en la función de cálculo de la media móvil ponderada linealmente (LWMA).

He hecho algunos ajustes en la función CalculateLWMA(): en la versión original la variable weightsum fue declarada usando el modificador estático. Aparentemente, la única razón por la que los desarrolladores han hecho esto es por la necesidad de precalcular en la primera llamada de esta función. Además, esta variable permanece sin cambios en el código. Este es el código original de la función en el que las partes relativas al cálculo y al uso de weightsum están marcadas con comentarios:

void CalculateLWMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int              i,limit;
   static int     weightsum;                       // <-- using weightsum
   double               sum;
//--- first calculation or number of bars was changed
   if(prev_calculated==0)                          // <-- using weightsum
     {
      weightsum=0;                                 // <-- using  weightsum
      limit=InpMAPeriod+begin;                     // <-- using weightsum
      //--- set empty value for first limit bars
      for(i=0;i<limit;i++) ExtLineBuffer[i]=0.0;
      //--- calculate first visible value
      double firstValue=0;
      for(i=begin;i<limit;i++)                     // <-- using weightsum
        {
         int k=i-begin+1;                          // <-- using weightsum
         weightsum+=k;                             // <-- using weightsum
         firstValue+=k*price[i];
        }
      firstValue/=(double)weightsum;
      ExtLineBuffer[limit-1]=firstValue;
     }
   else limit=prev_calculated-1;
//--- main loop
   for(i=limit;i<rates_total;i++)
     {
      sum=0;
      for(int j=0;j<InpMAPeriod;j++) sum+=(InpMAPeriod-j)*price[i-j];
      ExtLineBuffer[i]=sum/weightsum;              // <-- using weightsum
      }
//---
  }

Previamente, esta variante ha funcionado muy bien, pero cuando ejecuté el conjunto "indicador + asesor" (esto se menciona al final de este artículo) en este tipo de media móvil, vinieron los problemas. El principal problema fue causado por las circunstancias descritas más arriba, es decir, weightsum fue la variable estática: esta variable se fue incrementando de forma constante ya que en cada cambio del parámetro de la media móvil fue necesario recalcularla sobre la marcha desde cero.

La forma más fácil es calcular directa e inmediatamente el valor weightsum (es igual a la suma de los enteros desde 1 hasta el periodo de la media móvil. Para este propósito hay una fórmula simple para la suma de la progresión aritmética) y al mismo tiempo declarar falso su estado como estático, que fue lo que hice. Ahora, en lugar de la declaración previa de weightsum usando el modificador estático, lo declaramos sin él, tan solo inicializamos con el valor "correcto" y de esta forma eliminamos el lazo inicial de "acumulación variable".

int weightsum = MA_Period *( MA_Period + 1 ) / 2;

Ahora todo funciona correctamente.


Función OnCalculate() como controlador

Tuve que hacer un montón de cambios en la función OnCalculate() y por tanto he citado aquí su código al completo.

int OnCalculate(const int rates_total,
                const int prev_calculated,            /// Mathemat: full recalculation!
                const int begin,                      /// Mathemat: full recalculation!
                const double &price[])
  {
//--- check for bars count
   if(rates_total<MA_Period-1+begin)
      return(0);// not enough bars for calculation
//--- first calculation or number of bars was changed
   if(prev_calculated==0)
      ArrayInitialize(LineBuffer,0);
//--- sets first bar from what index will be draw
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MA_Period-1+begin);

//--- calculation (Mthmt - optimized by Mathemat)

   if( GlobalVariableGet( "Updated" ) == 1 )
   {
      if(MA_Method==MODE_EMA)  CalculateEMA(       rates_total,prev_calculated,begin,price);
      if(MA_Method==MODE_LWMA) CalculateLWMA_Mthmt(rates_total,prev_calculated,begin,price);
      if(MA_Method==MODE_SMMA) CalculateSmoothedMA(rates_total,prev_calculated,begin,price);
      if(MA_Method==MODE_SMA)  CalculateSimpleMA(  rates_total,prev_calculated,begin,price);
   }
   else
   {
      OnInit( );                 /// Mthmt
      if(MA_Method==MODE_EMA)  CalculateEMA(       rates_total,0,0,price);
      if(MA_Method==MODE_LWMA) CalculateLWMA_Mthmt(rates_total,0,0,price);
      if(MA_Method==MODE_SMMA) CalculateSmoothedMA(rates_total,0,0,price);
      if(MA_Method==MODE_SMA)  CalculateSimpleMA(  rates_total,0,0,price);
      GlobalVariableSet( "Updated", 1 );
      Updated = 1;
   }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

La modificación principal tiene que ver con la necesidad de calcular al completo el indicador "desde cero": es obvio que si el usuario ha cambiado el periodo de la media móvil de 13 a 14, todas las optimizaciones de sus cálculos ya no son válidas y tenemos que calcular la media móvil de nuevo. Esto ocurre cuando la variable Updated tiene el valor 0 (TGV ha cambiado después de pulsar la tecla rápida, pero el tick que dibuja el indicador aún no ha llegado)

Sin embargo, tenemos además que llamar previamente de forma explícita a la función OnInit(), ya que necesitamos cambiar el nombre corto del indicador que será visualizado cuando se pase el cursor sobre la línea. Después del cálculo inicial de la media móvil la TGV Updated se establece en 1, lo que da paso al cálculo del indicador optimizado hasta que no estemos dispuestos de nuevo a cambiar algunos parámetros del indicador sobre la marcha.


Controlador OnChartEvent()

Este es un código simple del controlador OnChartEvent():

void OnChartEvent( const int          id,
                   const long    &lparam,
                   const double  &dparam,
                   const string  &sparam )
{
   if( id == CHARTEVENT_KEYDOWN )
      switch( lparam )
      {
         case( KEY_TAB          ):  changeTerminalGlobalVar( "MA_Method",  1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         
         case( KEY_UP           ):  changeTerminalGlobalVar( "MA_Period",  1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         case( KEY_DOWN         ):  changeTerminalGlobalVar( "MA_Period", -1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         
         case( KEY_NUMLOCK_UP   ):  changeTerminalGlobalVar( "MA_Shift",   1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         case( KEY_NUMLOCK_DOWN ):  changeTerminalGlobalVar( "MA_Shift",  -1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
      }
      
      return;
}//+------------------------------------------------------------------+      

El controlador funciona de la siguiente forma: presionamos la tecla rápida, su código virtual se define y a continuación la función auxiliar changeTerminalGlobalVar() se inicia y modifica correctamente la TGV deseada. Después de esto el flag Updated se resetea a cero, esperando al tick, que lanzará OnCalculate() y redibujará el indicador "desde cero".


Función auxiliar que cambia "correctamente" TGV

Y, finalmente, el código de la función changeTerminalGlobalVar() usado en el controlador OnChartEvent():

void changeTerminalGlobalVar( string name, int dir = 0 )
{
   int var = GlobalVariableGet( name );
   int newparam = var + dir;
   if( name == "MA_Period" )
   {
      if( newparam > 0 )       /// Possible period is valid for MA
      {
         GlobalVariableSet( name, newparam ); 
         MA_Period = newparam;     /// Don't forget to change the global variable    
      }   
      else                       /// we do not change the period, because MA period is equal to 1 minimum
      {   
         GlobalVariableSet( name, 1 );     
         MA_Period = 1;     /// Don't forget to change the global variable 
      }   
   }   
      
   if( name == "MA_Method" )    /// Here when you call the 'dir' it is always equal to 1, the dir value is not important    
   {
      newparam = ( var + 1 ) % 4;
      GlobalVariableSet( name, newparam );  
      MA_Method = newparam;
   }      

   if( name == "MA_Shift" )
   {
      GlobalVariableSet( name, newparam );     
      MA_Shift = newparam;
   }      

   ChartRedraw( );
   return;
}//+------------------------------------------------------------------+

El principal objetivo de esta función es el cálculo correcto de los parámetros de la media móvil teniendo en cuenta "las limitaciones físicas". Obviamente, no podemos hacer que el periodo de la media móvil sea menor que 1, el cambio de la media móvil puede ser aleatorio, pero el tipo de la media móvil es un número entre 0 y 3 que corresponde al número de miembro condicional en la enumeración de ENUM_MA_METHOD.

 

Comprobando. Funciona, pero en "grado C". ¿Qué podemos hacer?

De acuerdo, vamos a aplicar nuestro indicador al gráfico y empezamos a pulsar aleatoriamente las teclas rápidas que cambian los parámetros de la media móvil. Sí, todo funciona correctamente, pero hay un hecho desagradable: las TGV están cambiando inmediatamente (puede comprobar esto llamando a las TGV mediante la tecla F3), pero las medias móviles no se redibujan inmediatamente, sino solo con la llegada del nuevo tick. Si tenemos una sesión americana con el flujo de ticks activo, apenas notaremos el retraso. Pero si ocurre de noche, mientras todo está en calma, podemos esperar varios minutos para que se redibujen. ¿Qué ocurre?

Bueno, como dicen, tienes lo que escribes. Antes de la versión 245 en los indicadores había solo un "punto de entrada", la función OnCalculate(). Por supuesto, no hablo de las funciones OnInit() y OnDeinit() que proporcionan los cálculos iniciales del indicador, la inicialización y la terminación. Ahora hay varios puntos de entrada y están conectados con los nuevos eventos Timer y ChartEvent.

Sin embargo, los nuevos controladores están haciendo solo lo que incluyen y no están asociados formalmente con el controlador OnCalculate(). Entonces, ¿qué podemos hacer con nuestro controlador OnChartEvent() "alienígena" para que funcione correctamente, es decir, para que permita redibujar la media móvil inmediatamente?

En general, hay varias formas de implementar este requisito:

  • "Matryoshka" (OnCalculate() llama dentro de OnChartEvent()): inserta la llamada de la función OnCalculate() en este controlador, haciendo un llenado previo de todos sus parámetros. Como el controlador OnChartEvent() implica cambiar al menos un parámetro de la media móvil, afectará a todo su historial, es decir, debemos recalcularlo de nuevo "desde cero" sin la optimización de los cálculos.
  • "Tick artificial" que transfiere el control al inicio de la función OnCalculate() que modifica el buffer gráfico. Aparentemente, no hay métodos "legítimos" como se refleja en la documentación de MT5 (aunque, quizás no haya buscado tan minuciosamente). Si está interesado, puede buscar algo como «API», «PostMessageA», etc. Por tanto, no vamos a considerar esta variante aquí, ya que no garantiza que no cambien algún día las características sin documentar. No tengo duda de que puede realizarse.

 

¡"Matryoshka" funciona!

Resulta que ya hemos hecho lo más importante. Este es un código, muy simple, de la función: puede simplemente insertar su llamada directamente frente al operador return del controlador OnChartEvent() .

int OnCalculate_Void()
{
   const int rates_total = Bars( _Symbol, PERIOD_CURRENT );
   CopyClose( _Symbol, PERIOD_CURRENT, 0, rates_total, _price );
   OnCalculate( rates_total, 0, 0, _price );
   return( 1 );
}//+------------------------------------------------------------------+

Después de compilar el indicador y aplicarlo al gráfico vemos que, en general, el código funciona de forma rápida e independientemente de la llegada de los ticks.

La desventaja de esta implementación es que los precios de cierre se copian exactamente en la matriz price[]. Si lo desea, la función CopyClose() puede reemplazarse con lo que quiera mediante el campo "Aplicar" de la pestaña "Ajustes" del cuadro de diálogo del indicador. Si el precio actual va a ser básico (Open, High, Low, Close), ya tenemos la función CopyXXXX() correspondiente. En caso de precios más complicados (medio, típico o ponderado) tenemos que calcular la matriz de otra forma.

No estoy seguro de si necesitamos o no la función CopyClose() que copia todo el historial de la matriz. Por otro lado, esta función es lo suficientemente rápida cuando el historial no se ha cargado con demasiada profundidad. La comprobación del indicador sobre EURUSD H1 con el historial anterior a 1999 (en torno a 700.000 barras) mostró que el indicador realiza cálculos y no muestra ninguna ralentización. Sobre dicho historial, las posibles desaceleraciones pueden ser debidas, no a la función CopyXXXX(), sino a la necesidad de un recálculo más complicado del indicador desde el principio del historial (esto es obligatorio).


Algunos hallazgos y conclusión

¿Qué es mejor, un archivo de indicador o el conjunto "indicador + asesor" ?

De hecho, esta cuestión no es tan simple. Por un lado, es buena idea tener un archivo de indicador porque todas las funciones, incluyendo los controladores de evento, se concentran en un solo sitio.

Por otro lado, imaginemos que hay 3 o 4 indicadores aplicados al gráfico junto al asesor experto. Esta situación no es habitual. Además, se asume que cada indicador está provisto de su propio controlador de evento, además del estándar OnCalculate(). Para evitar la confusión con el procesamiento de eventos en esta "mezcla heterogénea" es más razonable concentrar todos los controladores de evento, no admitidos en los indicadores, en un lugar, el asesor experto.

Durante mucho tiempo, los desarrolladores de software han decidido darnos la capacidad de procesar eventos en el indicador: desde la versión no beta pública de 09.09.09 (cuando el indicador es considerado como "entidad de puro cálculo y matemática" y no debe contaminarse con ninguna característica que altere la velocidad de cálculo) han pasado exactamente 5 meses. De la misma forma, "la pureza de la idea" se vio afectada y ahora se dará rienda suelta a algún que otro caos procedente de las fantasías de los programadores. Pero el equilibrio está siempre en algún punto intermedio comprendido entre la idea pura, aunque limitada, y la no tan pura, pero más potente capacidad.

En septiembre-octubre de 2009, cuando el número de la versión beta de MT5 no había alcanzado aún el valor 200, escribí y compilé el código del conjunto "asesor experto + indicador", que permitió gestionar los parámetros de la media móvil sobre la marcha, pero "en un grado C": solo se actualizó después de la llegada del tick, pero no inmediatamente. En ese momento, este conjunto era la única solución posible y ahora es poco probable que interese a alguien.

No sabría cómo llevar la funcionalidad del indicador al "grado B", es decir, como se presenta en la última versión. Ahora estoy encantado de poder proporcionar una solución más adecuada a todos aquellos que puedan estar interesados.


Vídeo demostración de "Matryoshka"

Adjunto se encuentra mi breve vídeo, fruto de nuestra creación. Aún destaca, de alguna forma, el suave cambio de la curva de la media móvil (solo cambia el periodo, al principio aumenta y luego disminuye). Esto es Matryoshka (como se llamaba el famoso juego de muñecas rusas).


Por supuesto, estos trucos son útiles solo cuando el cálculo del indicador desde cero no lleva mucho tiempo. La media móvil simple contenida en este indicador cumple este requisito.


Un aspecto resbaladizo

Recuerde que los primeros parámetros externos del indicador son ahora las variables globales del terminal (TGV) que puede ver al presionar la tecla F3. Suponga que ha abierto el cuadro de diálogo de variables globales y ha cambiado un de las TGV (por ejemplo, el periodo de la media móvil). Puede esperar que este cambio se refleje inmediatamente en el indicador en el gráfico.

Actualmente en el terminal no hay ningún evento relacionado con la edición de TGV hecha por el usuario (por ejemplo, CHARTEVENT_GLOBALVAR_ENDEDIT). Piense también que no podemos desactivar la modificación de TGV en el cuadro de diálogo de las variables globales. Por tanto, aquí no podemos considerar ahora ningún evento excepto el tick. ¿Qué pasará en realidad?

Si no toca el teclado, entonces la actualización será "errónea" incluso en el siguiente tick: la variable Updated no se estableció a cero y, por tanto, solo se realizará el cálculo optimizado del indicador (correspondiente al valor previo del TGV cambiado). En este caso, para hacer justicia podemos aconsejar solo una cosa: después de editar TGV, debe presionar al menos una vez la tecla rápida que modifica la TGV, establecer Updated = 0 y provocar el recálculo completo del indicador.

Todos los posibles usuarios y desarrolladores deben tener este hecho en mente.


Archivos adjuntos del código fuente y de vídeos

Finalmente, adjunto los archivos del código fuente. Explicación:

  1. Custom Moving Average.mq5 - archivo de código fuente de la media móvil que se envía con MT5.
  2. MyMA_ind_with_ChartEvent.mq5 - implementación inicial ("Grado C"): el indicador se actualiza solo después de la llegada del tick.
  3. MyMA_ind_with_ChartEvent_Matryoshka.mq5 - la segunda variante (quizás el "grado B"): el indicador se actualiza inmediatamente, sin esperar la llegada del tick.

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

Crear un indicador con opciones de control gráficas Crear un indicador con opciones de control gráficas
Aquellos que estén familiarizados con las emociones del mercado conocen el indicador MACD (su nombre completo es Moving Average Convergence/Divergence, Media Móvil Convergencia/Divergencia) - la poderosa herramienta para analizar el movimiento del precio usada por los operadores desde los primeros momentos en que aparecieron los métodos de análisis por computadora. En este artículo vamos a considerar las posibles modificaciones de MACD y a implementarlas en un indicador con la posibilidad de cambiar gráficamente entre las modificaciones.
MQL5: análisis y procesado de informes de la Comisión de Operaciones del Mercado de Futuros (CFTC) en MetaTrader 5 MQL5: análisis y procesado de informes de la Comisión de Operaciones del Mercado de Futuros (CFTC) en MetaTrader 5
En este artículo vamos a desarrollar una herramienta para el análisis de informes de la CFTC (Commodity Futures Trading Commission). Vamos a resolver los siguientes problemas: desarrollar un indicador que permita el uso de los datos de los informes de la CFTC directamente de los archivos de datos suministrados por la Comisión sin necesidad de un procesado o conversión intermedia. Además puede usarse para diferentes finalidades: para trazar los datos como un indicador, para proceder con los datos en los demás indicadores, en los scripts para el análisis automatizado y en los Expert Advisors para su uso en las estrategias de trading.
Interacción entre MetaTrader 5 y MATLAB Interacción entre MetaTrader 5 y MATLAB
Este artículo trata sobre la interacción entre MetaTrader 5 y el paquete matemático MatLab. Muestra el mecanismo de conversión de datos y el proceso de desarrollo de una librería universal para interactuar con el escritorio de MatLab. También describe el uso de las DLL generadas por el entorno de MatLab. Este artículo está dirigido a lectores experimentados que tienen conocimientos de C+ y MQL5.
Implementación práctica de filtros digitales en MQL5 para principiantes Implementación práctica de filtros digitales en MQL5 para principiantes
La idea del filtrado de señales digitales ha sido ampliamente discutida en foros sobre el tema de la elaboración de sistemas de trading. Y sería imprudente no crear un código estándar de filtros digitales en MQL5. En este artículo el autor describe la transformación de código simple de indicadores SMA de su artículo "Indicadores personalizados en MQL5 para principiantes", en el código de un filtro digital más complejo y universal. Este artículo es consecuencia del artículo anterior. También trata sobre cómo reemplazar texto en el código y cómo corregir errores de programación.