English Русский 中文 Deutsch 日本語 Português
preview
Combinación de estrategias de análisis técnico y fundamental en MQL5 para principiantes

Combinación de estrategias de análisis técnico y fundamental en MQL5 para principiantes

MetaTrader 5Ejemplos | 9 enero 2025, 12:26
248 0
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

Introducción

El análisis fundamental y las estrategias de seguimiento de tendencias a menudo se consideran enfoques opuestos. Muchos traders que favorecen el análisis fundamental creen que el análisis técnico es una pérdida de tiempo porque toda la información necesaria ya está reflejada en el precio. Por el contrario, los analistas técnicos a menudo consideran que el análisis fundamental es defectuoso porque patrones idénticos, como el de cabeza y hombros, pueden llevar a resultados diferentes en el mismo mercado.

Para cualquier trader novato, esto puede resultar abrumador porque se enfrenta a muchas opciones, pero ¿cuál es la mejor? ¿Qué estrategia le permitirá mantener su cuenta de operaciones con ganancias de manera constante y al mismo tiempo mantenerlo fuera del mercado durante condiciones desfavorables?

Como escritor, creo que la verdad se encuentra en algún punto intermedio. El propósito de este artículo es explorar si podemos crear una estrategia comercial estable que combine los mejores aspectos del análisis fundamental y técnico, y determinar si dicha estrategia vale la inversión de tiempo.

Construiremos nuestro Asesor Experto desde cero utilizando MQL5 nativo, lo que nos permitirá la flexibilidad de probar nuestra estrategia en cualquier mercado. Al final de este artículo comprenderás:

  1. Cómo construir sus propios asesores expertos en MQL5.
  2. Cómo combinar un conjunto de indicadores técnicos.
  3. Un marco para conceptualizar datos fundamentales y técnicos. 


Descripción general de la estrategia comercial

Nuestra estrategia comercial se compone de 2 componentes:

  1. Análisis fundamental
  2. Análisis técnico

Consideremos cada enfoque por separado para comprender cómo se complementan entre sí, en lugar de intentar determinar cuál es superior. Comenzaremos por comprender los principios fundamentales que motivan nuestra estrategia.

A primera vista, los gráficos financieros pueden parecer muy aleatorios e impredecibles. Los conjuntos de datos financieros son notoriamente ruidosos y a veces incluso inestables. Sin embargo, analizar estos gráficos desde una perspectiva fundamental puede llevar a conclusiones completamente diferentes sobre el comportamiento del mercado.


Análisis fundamental

El análisis fundamental se basa en la comprensión de cómo funcionan los mercados. En nuestra discusión, nos centraremos en los pares de divisas y construiremos nuestro algoritmo comercial para aprovechar nuestra comprensión de los mercados de divisas y sus principales participantes.

Datos financieros

Fig. 1: Un ejemplo de análisis fundamental del par AUDJPY.



Los traders fundamentales a menudo hablan de soporte y resistencia, aunque no existen definiciones definitivas para estos conceptos. Me gustaría ofrecer una posible interpretación desde una perspectiva fundamental.

Cuando observamos el tipo de cambio entre dos monedas, es fácil olvidar las implicaciones en el mundo real. Por ejemplo, si el gráfico USDJPY está subiendo, significa que el yen japonés se está depreciando frente al dólar. Dado que el 90% de los productos básicos del mundo se cotizan en dólares, un gráfico ascendente indica que las exportaciones de Japón generan menos dinero en el exterior.

Si el tipo de cambio continúa aumentando sin límites, el gobierno japonés enfrentará desafíos importantes. Sus exportaciones valdrían muy poco, lo que provocaría tensiones económicas y un descenso del nivel de vida. Las familias podrían tener dificultades para cubrir sus necesidades básicas y el país podría enfrentarse a una hiperinflación y a unas condiciones económicas terribles.

Para evitar esos resultados, es crucial para el bienestar de Japón que el tipo de cambio entre el yen y el dólar estadounidense se mantenga dentro de un rango tolerable. Cuando el tipo de cambio se vuelve demasiado alto, el gobierno japonés se ve incentivado a intervenir en los mercados cambiarios para proteger su economía. Por el contrario, cuando el tipo de cambio es demasiado bajo, el gobierno estadounidense podría ofrecer apoyo para mantener el equilibrio. Así es como se pueden interpretar el soporte y la resistencia desde una perspectiva fundamental.

En su mayor parte, los tipos de cambio se fijan mediante decisiones acumulativas que toman las grandes instituciones financieras, como los bancos minoristas, los bancos de inversión y los fondos de cobertura. Estas potencias financieras controlan grandes volúmenes de dinero y sus decisiones en conjunto son las que impulsan los mercados.

Entonces, desde una perspectiva fundamental, no querríamos operar contra los grandes actores corporativos, sino que preferiríamos encontrar oportunidades para operar en la misma dirección con los actores dominantes del mercado.

Al analizar los cambios de precio en marcos temporales más amplios, como los semanales o mensuales, podemos obtener una idea de lo que los grandes actores institucionales creen que es un nivel de precio justo para el valor en observación. Por lo tanto, buscaremos oportunidades comerciales que se alineen con el cambio de precio a largo plazo.

Poniendo todo junto, nuestra estrategia fundamental, implica varios pasos. En primer lugar, analizaremos marcos temporales más altos para entender hacia dónde es probable que lleven el precio los actores institucionales. Una vez confirmado, identificaremos nuestros niveles de soporte y resistencia examinando los precios más altos y más bajos de la semana anterior. Nuestro objetivo es operar con configuraciones de alta probabilidad, por lo que si el precio supera el nivel de resistencia, entraremos en una posición de compra. Por el contrario, si el precio rompe por debajo del nivel de soporte, entraremos en una posición de venta.


Análisis técnico

Ahora, definiremos el análisis técnico involucrado en nuestra estrategia comercial. Nuestro análisis técnico se centra en identificar configuraciones comerciales donde nuestros indicadores se alinean con nuestro análisis fundamental. Esto significa que si la tendencia en marcos temporales mayores es alcista, solo buscamos configuraciones en las que nuestros indicadores técnicos nos indiquen que debemos operar en largo. Por el contrario, si la tendencia en marcos temporales superiores es bajista, solo buscamos configuraciones en las que nuestros indicadores se alineen para una operación corta.

El primer indicador de nuestro conjunto es el Índice de Flujo Monetario (MFI). El MFI sirve como indicador de volumen y juega un papel crucial en nuestra estrategia. Sólo consideramos operaciones respaldadas por un volumen significativo. Las operaciones con volumen débil u opuesto no están dentro de nuestro alcance. En nuestra estrategia interpretamos el MFI de forma diferente a los métodos convencionales. Centramos el MFI en 50: las lecturas por debajo de 50 indican volumen bajista, mientras que las lecturas por encima de 50 indican volumen alcista.

A continuación, utilizamos el indicador de convergencia/divergencia de medias móviles (MACD). De manera similar a nuestro enfoque con el MFI, no utilizamos el MACD en su sentido tradicional. En lugar de ello, centramos nuestro MACD alrededor de 0. Una línea de señal MACD por debajo de 0 indica una tendencia bajista, mientras que una línea de señal por encima de 0 indica una tendencia alcista.

Además del MFI y el MACD, nuestra estrategia incorpora un enfoque clásico de seguimiento de tendencias utilizando un promedio móvil. A diferencia de nuestro enfoque con otros indicadores técnicos, interpretamos la media móvil de manera convencional: si el precio está por debajo de la media móvil, indica una oportunidad de venta; si el precio está por encima de la media móvil, indica una oportunidad de compra.

Además, integramos el oscilador estocástico en nuestra estrategia, adhiriéndonos a su interpretación tradicional. Cuando el oscilador proporciona una lectura superior a 20, lo interpretamos como una señal de compra. Por el contrario, una lectura por debajo de 80 del oscilador indica una señal de venta.

Por lo tanto, para que podamos comprar un valor:

  1. El precio debe cerrar por encima de la media móvil.
  2. La señal MACD debe estar por encima de 0
  3. La lectura del MFI debe ser mayor a 50
  4. El oscilador estocástico debe estar por encima de 20
  5. El precio debe haberse apreciado en los últimos 3 meses.
  6. Los niveles de precios deberían estar por encima del nivel de soporte.

Y a la inversa, para que vendamos un valor:

  1. El precio debe cerrar por debajo de la media móvil.
  2. La señal MACD debe estar por debajo de 0
  3. La lectura del MFI debe ser inferior a 50
  4. El oscilador estocástico debe estar por debajo de 80
  5. El precio debe haberse depreciado en los últimos 3 meses.
  6. Los niveles de precios deberían estar por debajo del nivel de resistencia.

Empecemos

Primero importamos las librerías que necesitamos. En este caso, importaremos la biblioteca comercial para ejecutar órdenes comerciales.

//+------------------------------------------------------------------+
//|                           Price Action & Trend Following.mq5     |
//|                        Copyright 2024, MetaQuotes Ltd.           |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
/*
   This Expert Advisor will help us implement a combination of fundamental analysis
   and trend following principles to trade financial securities with precision
   thanks to the easy to learn MQL5 Language that gives us a blend of creative
   flexibility and technical control at the same time.

   Our Fundamental strategy follows the principles outlined below:
   1)Respect price movements on higher order time frames
   2)Enter at support levels and exit on resistance levels

   Our Trend following strategy follows principles that have been proven over time:
   1)Only enter trades backed by volume
   2)Do not trade against the dominant trend, rather wait for setups to go with the bigger trend.
   3)Use an ensemble of good confirmation indicators

   Gamuchirai Zororo Ndawana
   Selebi Phikwe
   Botswana
   11:06 Thursday 11 July 2024
*/

//+------------------------------------------------------------------+
//| Include necessary libraries                                      |
//+------------------------------------------------------------------+
#include <Trade/Trade.mqh>
CTrade Trade;

Continuando, ahora necesitamos definir las entradas para nuestro programa. Estas entradas controlarán los períodos de nuestros indicadores técnicos, el tamaño del lote comercial deseado y otras variables de esa naturaleza.

//+------------------------------------------------------------------+
//| Input parameters for technical indicators                        |
//+------------------------------------------------------------------+
input int stoch_percent_k = 5; // Stochastic %K
input int stoch_percent_d = 3; // Stochastic %D
input int stoch_slowing   = 3; // Stochastic Slowing

input int macd_fast_ema = 12; // MACD Fast EMA
input int macd_slow_ema = 26; // MACD Slow EMA
input int macd_sma = 9;       // MACD SMA

input int ma_period = 60; // Moving Average Period
input int mfi_period = 14; // MFI Period

input int lot_multiple = 10; // Lot size multiplier

Ahora crearemos variables globales que usaremos en toda nuestra aplicación. Estas variables almacenarán nuestros niveles de soporte y resistencia, buffers de indicadores técnicos, precios de oferta y demanda y otra información de esa naturaleza.

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
double ask, bid;               // Ask and Bid prices
double min_distance = 0.2;     // Minimum distance for stoploss
double min_lot_size = 0;       // Minimum lot size
double position_size;          // Actual position size

double last_week_high = 0;     // High of the previous week
double last_week_low = 0;      // Low of the previous week

string last_week_high_name = "last week high"; // Name for high level object
string last_week_low_name = "last week low";   // Name for low level object

double higher_time_frame_change = 0.0; // Change on higher time frame
string zone_location = "";             // Current zone location

int zone = 0;                // Zone indicator
string higher_time_frame_trend = ""; // Higher time frame trend
int trend = 0;               // Trend indicator

int ma_handler, stoch_handler, macd_handler, mfi_handler; // Handlers for indicators
double ma_reading[], stoch_signal_reading[], macd_signal_reading[], mfi_reading[]; // Buffers for indicator readings

Nuestro objetivo ahora es definir nuestro controlador OnInit(), en esta función inicializaremos nuestros indicadores técnicos y ajustaremos el tamaño de nuestro lote comercial apropiadamente.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Set up handlers for technical indicators
   ma_handler = iMA(_Symbol, PERIOD_CURRENT, ma_period, 0, MODE_EMA, PRICE_CLOSE);
   macd_handler = iMACD(_Symbol, PERIOD_CURRENT, macd_fast_ema, macd_slow_ema, macd_sma, PRICE_CLOSE);
   stoch_handler = iStochastic(_Symbol, PERIOD_CURRENT, stoch_percent_k, stoch_percent_d, stoch_slowing, MODE_EMA, STO_CLOSECLOSE);
   mfi_handler = iMFI(_Symbol, PERIOD_CURRENT, mfi_period, VOLUME_TICK);

//--- Adjust lot size
   min_lot_size = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   position_size = min_lot_size * lot_multiple;

//--- Initialization done
   return(INIT_SUCCEEDED);
  }

Ahora definiremos una función que recuperará los niveles de soporte y resistencia que fueron definidos por el historial comercial de la semana pasada.

//+------------------------------------------------------------------+
//| Function to get the previous week's high and low prices          |
//+------------------------------------------------------------------+
bool get_last_week_high_low(void)
  {
//--- Reset values
   last_week_high = 0;
   last_week_low = 0;

//--- Remove old levels if any
   ObjectDelete(0, last_week_high_name);
   ObjectDelete(0, last_week_low_name);

//--- Update high and low values
   last_week_high = iHigh(_Symbol, PERIOD_W1, 1);
   last_week_low = iLow(_Symbol, PERIOD_W1, 1);

//--- Mark current levels of support and resistance
   ObjectCreate(0, last_week_high_name, OBJ_HLINE, 0, 0, last_week_high);
   ObjectCreate(0, last_week_low_name, OBJ_HLINE, 0, 0, last_week_low);

//--- Check for valid values
   return((last_week_high * last_week_low) != 0);
  }

Siguiendo adelante, necesitamos entender la acción del precio que ocurre en un marco temporal superior. Recuerde que miraremos hacia atrás en el último ciclo económico, aproximadamente 3 meses, para inferir qué han estado haciendo los actores institucionales en el mercado.

//+------------------------------------------------------------------+
//| Function to determine higher time frame price movement           |
//+------------------------------------------------------------------+
bool get_higher_time_frame_move(void)
  {
//--- Analyze weekly time frame
   higher_time_frame_change = iClose(_Symbol, PERIOD_CURRENT, 1) - iClose(_Symbol, PERIOD_W1, 12);

//--- Check for valid values
   return((iClose(_Symbol, PERIOD_W1, 12) * iClose(_Symbol, PERIOD_W1, 1)) != 0);
  }

Nuestra próxima agenda será interpretar las señales de acción del precio que hemos recopilado. En particular, debemos entender si estamos por encima del máximo de la semana pasada, lo que indicamos como zona 1, o si estamos por debajo del mínimo de la semana pasada, estamos en la zona 3 y, finalmente, si estamos en el medio, entonces estamos en la zona 2. Luego etiquetaremos la tendencia que identificamos en el marco de tiempo superior, si el precio se estaba apreciando en el marco de tiempo superior etiquetaremos la tendencia como 1, de lo contrario etiquetaremos la tendencia como -1.

//+------------------------------------------------------------------+
//| Function to interpret price action data                          |
//+------------------------------------------------------------------+
void interpet_price_action(void)
  {
//--- Determine zone location based on last week's high and low
   if(iClose(_Symbol, PERIOD_CURRENT, 0) > last_week_high)
     {
      zone = 1;
      zone_location = "We are above last week's high";
     }
   else if(iClose(_Symbol, PERIOD_CURRENT, 0) < last_week_low)
     {
      zone = 3;
      zone_location = "We are below last week's low";
     }
   else
     {
      zone = 2;
      zone_location = "We are stuck inside last week's range";
     }

//--- Determine higher time frame trend
   if(higher_time_frame_change > 0)
     {
      higher_time_frame_trend = "Higher time frames are in an up trend";
      trend = 1;
     }
   else if(higher_time_frame_change < 0)
     {
      higher_time_frame_trend = "Higher time frames are in a down trend";
      trend = -1;
     }
  }

Ahora necesitaremos una función que actualice los valores de nuestros indicadores técnicos y obtenga los datos actuales del mercado.

//+------------------------------------------------------------------+
//| Function to update technical indicators and fetch market data    |
//+------------------------------------------------------------------+
void update_technical_indicators(void)
  {
//--- Update market prices
   ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

//--- Copy indicator buffers
   CopyBuffer(ma_handler, 0, 1, 1, ma_reading);
   CopyBuffer(stoch_handler, 1, 1, 1, stoch_signal_reading);
   CopyBuffer(macd_handler, 1, 1, 1, macd_signal_reading);
   CopyBuffer(mfi_handler, 0, 1, 1, mfi_reading);
  }

Esta función ejecutará nuestras entradas comerciales por nosotros, si tenemos permiso de nuestra función de sentimiento bajista, abriremos una operación de venta. Por el contrario, solo podemos abrir posiciones de compra si tenemos permiso de nuestra función de sentimiento alcista.

//+------------------------------------------------------------------+
//| Function to find entry points for trades                         |
//+------------------------------------------------------------------+
void find_entry(void)
  {
//--- Check for bullish sentiment
   if(bullish_sentiment())
     {
      Trade.Buy(position_size, _Symbol, ask, (last_week_low - min_distance), (last_week_high + min_distance));
     }
//--- Check for bearish sentiment
   else if(bearish_sentiment())
     {
      Trade.Sell(position_size, _Symbol, bid, (last_week_high + min_distance), (last_week_low - min_distance));
     }
  }

Ahora definamos cuidadosamente qué significa que nuestros dos sistemas comerciales se alineen para una configuración de compra. Recordemos las condiciones que definimos anteriormente en nuestra discusión, queremos ver el precio cerrando por encima del promedio móvil, nuestro indicador MFI debe estar por encima de 50, nuestra lectura MACD debe estar por encima de 0, el oscilador estocástico debe estar por encima de 20, la tendencia en el marco de tiempo superior debe ser alcista y deberíamos estar por encima del nivel de soporte.

//+------------------------------------------------------------------+
//| Function to analyze bullish signals                              |
//+------------------------------------------------------------------+
bool bullish_sentiment(void)
  {
//--- Analyze conditions for bullish sentiment
   return((mfi_reading[0] > 50) &&
          (iClose(_Symbol, PERIOD_CURRENT, 1) > ma_reading[0]) &&
          (macd_signal_reading[0] > 0) &&
          (stoch_signal_reading[0] > 20) &&
          (trend == 1) &&
          (zone < 3));
  }

Y lo contrario es válido para nuestras configuraciones de venta.

//+------------------------------------------------------------------+
//| Function to analyze bearish signals                              |
//+------------------------------------------------------------------+
bool bearish_sentiment(void)
  {
//--- Analyze conditions for bearish sentiment
   return((mfi_reading[0] < 50) &&
          (iClose(_Symbol, PERIOD_CURRENT, 1) < ma_reading[0]) &&
          (macd_signal_reading[0] > 0) &&
          (stoch_signal_reading[0] < 80) &&
          (trend == -1) &&
          (zone > 1));
  }

Finalmente, necesitamos un controlador de eventos OnTick() que garantice que el flujo de eventos en nuestra aplicación se ejecute como lo deseamos. Tenga en cuenta que comenzamos verificando la marca de tiempo, esto nos ayuda a asegurarnos de que nuestra aplicación solo verificará los niveles de soporte y resistencia una vez por semana. De lo contrario, si no tenemos nuevas velas semanales, ¡no tiene sentido verificar la misma información una y otra vez en cada tic! Si todo funciona bien, nuestro Asesor Experto procederá a interpretar la acción del precio, actualizará nuestros indicadores técnicos y luego buscará una entrada comercial.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Check for new candle on higher time frame
   static datetime time_stamp;
   datetime current_time = iTime(_Symbol, PERIOD_W1, 0);

   if(time_stamp != current_time)
     {
      time_stamp = current_time;

      if(!get_last_week_high_low())
        {
         Print("Failed to get historical performance of ", _Symbol);
         Print("[ERROR]: ", GetLastError());
        }
      else if(!get_higher_time_frame_move())
        {
         Print("Failed to analyze historical performance of ", _Symbol);
         Print("[ERROR]: ", GetLastError());
        }
     }
   else
     {
      interpet_price_action();
      update_technical_indicators();
      if(PositionsTotal() == 0)
        {
         find_entry();
        }
      Comment("Last week high: ", last_week_high, "\nLast week low: ", last_week_low, "\nZone: ", zone_location, "\nTrend: ", higher_time_frame_trend);
     }
  }


Nuestro sistema en acción

Fig. 2: Nuestro Asesor Experto negociando el par AUDJPY en el marco temporal H1.

Nuestro sistema en acción

Fig. 3: Resultados de las pruebas retrospectivas de nuestro algoritmo comercial en datos H1 del símbolo AUDJPY durante 1 mes.


Conclusión

Este artículo ilustra la integración del análisis fundamental y técnico en las estrategias comerciales. Usando MQL5, hemos demostrado cómo combinar sin problemas los conocimientos de estas dos perspectivas para generar instrucciones comerciales prácticas. Al presentar un marco en el que los datos fundamentales y técnicos se complementan entre sí, en lugar de competir, capacitamos a los lectores para aprovechar ambos enfoques de manera efectiva.


Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/15293

Del básico al intermedio: Comando WHILE y DO WHILE Del básico al intermedio: Comando WHILE y DO WHILE
En este artículo veremos de manera práctica y bastante didáctica el primer comando de bucle. A pesar de que muchos principiantes sienten temor al enfrentarse a la necesidad de crear bucles, saber cómo hacerlo de manera adecuada y segura, es algo que solo la experiencia y la práctica pueden proporcionar. Pero, ¿quién sabe? Tal vez pueda ayudarte a reducir las dificultades y el sufrimiento, mostrándote los principales problemas y precauciones que debes tener al utilizar bucles en tus códigos. El contenido expuesto aquí tiene como objetivo exclusivamente la enseñanza didáctica. En ningún caso debe considerarse como una aplicación destinada a otro fin que no sea el aprendizaje y estudio de los conceptos presentados.
Redes neuronales en el trading: Representación lineal por partes de series temporales Redes neuronales en el trading: Representación lineal por partes de series temporales
Este artículo es algo distinto de los anteriores de esta serie. En él, hablaremos de una representación alternativa de las series temporales. La representación lineal por partes de series temporales es un método de aproximación de una serie temporal usando funciones lineales en intervalos pequeños.
Del básico al intermedio: Comandos BREAK y CONTINUE Del básico al intermedio: Comandos BREAK y CONTINUE
En este artículo veremos cómo usar los comandos RETURN, BREAK y CONTINUE dentro de un bucle. Entender lo que cada uno de estos comandos hace en el flujo de ejecución de un bucle es algo muy importante para que puedas trabajar con aplicaciones más elaboradas. El contenido expuesto aquí tiene un propósito puramente didáctico. En ningún caso debe considerarse una aplicación cuya finalidad no sea el aprendizaje y el estudio de los conceptos presentados.
Algoritmo de búsqueda por vecindad — Across Neighbourhood Search (ANS) Algoritmo de búsqueda por vecindad — Across Neighbourhood Search (ANS)
El artículo revela el potencial del algoritmo ANS como paso importante en el desarrollo de métodos de optimización flexibles e inteligentes capaces de considerar la especificidad del problema y la dinámica del entorno en el espacio de búsqueda.