Capítulo 12: Gestión Avanzada de Riesgos
En este capítulo, profundizaremos en técnicas avanzadas de gestión de riesgos en MQL5. Aprenderemos a calcular el tamaño de posición basado en el capital o el stop loss, implementar reglas de gestión de dinero y utilizar estrategias como la lotería fraccionada y escalonada. También exploraremos cómo integrar estas técnicas en tus Expert Advisors (EAs) para maximizar la eficiencia y minimizar los riesgos.
12.1. Cálculo del Tamaño de Posición Basado en Capital o Stop Loss
El cálculo del tamaño de posición es una parte fundamental de la gestión de riesgos. Puedes basar el tamaño de la posición en el capital disponible o en la distancia del stop loss. A continuación, te mostramos cómo implementar ambos métodos.
Ejemplo Práctico: Cálculo del Tamaño de Posición
//+------------------------------------------------------------------+
//| Funciones para calcular el tamaño de posición |
//+------------------------------------------------------------------+
// Parámetros de entrada
input double RiskPercentage = 1.0; // Porcentaje de riesgo por operación (%)
input int StopLossPips = 50; // Distancia del stop loss en pips
// Función para calcular el tamaño de lote basado en el capital
double CalculateLotSizeByCapital(double riskPercentage) {
double balance = AccountInfoDouble(ACCOUNT_BALANCE); // Saldo de la cuenta
double riskAmount = (riskPercentage / 100) * balance; // Monto a arriesgar
double contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE); // Tamaño del contrato
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); // Valor del tick
// Calcular el tamaño de lote: (monto a arriesgar / valor del tick) / tamaño del contrato
double lotSize = MathFloor((riskAmount / tickValue) / contractSize);
return lotSize > 0 ? lotSize : 0.01; // Asegurar un mínimo de 0.01 lote
}
// Función para calcular el tamaño de lote basado en el stop loss
double CalculateLotSizeByStopLoss(int stopLossPips) {
double balance = AccountInfoDouble(ACCOUNT_BALANCE); // Saldo de la cuenta
double riskAmount = (RiskPercentage / 100) * balance; // Monto a arriesgar
double contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE); // Tamaño del contrato
// Calcular el tamaño de lote: (monto a arriesgar / valor de punto) / tamaño del contrato
double lotSize = MathFloor((riskAmount / (stopLossPips * Point())) / contractSize);
return lotSize > 0 ? lotSize : 0.01; // Asegurar un mínimo de 0.01 lote
}
Explicación del Código
- Cálculo Basado en Capital:
- Usa el saldo de la cuenta y el porcentaje de riesgo para determinar cuánto capital puedes arriesgar.
- Divide el monto a arriesgar entre el valor del tick y el tamaño del contrato para calcular el tamaño de lote.
- Cálculo Basado en Stop Loss:
- Usa la distancia del stop loss en pips para calcular cuánto arriesgas por punto.
- Ajusta el tamaño de lote para que el riesgo total no exceda el porcentaje especificado.
- Uso en un EA:
- Puedes usar cualquiera de estas funciones en un EA para calcular dinámicamente el tamaño de posición antes de abrir una operación.
12.2. Implementación de Reglas de Gestión de Dinero
La gestión de dinero es crucial para proteger tu capital y maximizar las ganancias. A continuación, exploramos dos estrategias populares: Martingale y Anti-Martingale.
Martingale
- Descripción: Incrementa el tamaño de la posición después de una pérdida para recuperar el capital perdido.
- Riesgo: Puede llevar a grandes pérdidas si la racha negativa continúa.
// Ejemplo de implementación de Martingale
double MartingaleLotSize(double previousLoss, double baseLotSize) {
if (previousLoss > 0) {
return baseLotSize * 2; // Duplica el tamaño de lote después de una pérdida
}
return baseLotSize; // Mantén el tamaño base si no hay pérdida
}
Anti-Martingale
- Descripción: Incrementa el tamaño de la posición después de una ganancia para capitalizar las rachas positivas.
- Ventaja: Reduce el riesgo al no aumentar el tamaño de lote durante rachas negativas.
// Ejemplo de implementación de Anti-Martingale
double AntiMartingaleLotSize(double previousProfit, double baseLotSize) {
if (previousProfit > 0) {
return baseLotSize * 1.5; // Incrementa el tamaño de lote después de una ganancia
}
return baseLotSize; // Mantén el tamaño base si no hay ganancia
}
Interpretación de las Estrategias
- Martingale: Es agresivo y puede ser peligroso si no se gestiona adecuadamente. Se recomienda usarlo con precaución y siempre con un stop loss estricto.
- Anti-Martingale: Es más conservador y adecuado para traders que buscan proteger su capital mientras aprovechan rachas positivas.
12.3. Uso de Lotería Fraccionada y Escalonada
Las estrategias de lotería fraccionada y escalonada permiten gestionar el riesgo dividiendo la posición en partes más pequeñas.
Lotería Fraccionada
- Descripción: Divide el capital en fracciones para abrir múltiples posiciones más pequeñas en lugar de una sola grande.
- Ventaja: Reduce el impacto de una sola operación fallida.
// Ejemplo de implementación de lotería fraccionada
void OpenFractionalPositions(double totalRisk, int fractions) {
double fractionRisk = totalRisk / fractions; // Dividir el riesgo total en fracciones
for (int i = 0; i < fractions; i++) {
double lotSize = CalculateLotSizeByCapital(fractionRisk);
OrderSend(_Symbol, OP_BUY, lotSize, Ask, 10, 0, 0);
}
}
Escalonada
- Descripción: Abre posiciones adicionales a medida que el mercado se mueve en tu favor.
- Ventaja: Maximiza las ganancias en tendencias fuertes.
// Ejemplo de implementación de estrategia escalonada
void AddPositionOnTrend(double initialLotSize, double profitThreshold) {
double currentProfit = PositionGetDouble(POSITION_PROFIT);
if (currentProfit >= profitThreshold) {
double newLotSize = initialLotSize * 1.5; // Incrementa el tamaño de lote
OrderSend(_Symbol, OP_BUY, newLotSize, Ask, 10, 0, 0);
}
}
Interactividad: Ejercicios Prácticos
Ejercicio 1: Modifica el código de cálculo del tamaño de lote para incluir un multiplicador basado en la volatilidad del mercado.
Ver solución:Ocultar soluciónA continuación, te proporciono el código modificado para calcular el tamaño de lote incluyendo un multiplicador basado en la volatilidad del mercado . La volatilidad se calcula utilizando el Average True Range (ATR) , que es un indicador comúnmente utilizado para medir la volatilidad.
Código Modificado: Cálculo del Tamaño de Lote con Multiplicador de Volatilidad
//+------------------------------------------------------------------+
//| Función para calcular el tamaño de lote con multiplicador de volatilidad |
//+------------------------------------------------------------------+
// Parámetros de entrada
input double RiskPercentage = 1.0; // Porcentaje de riesgo por operación (%)
input int StopLossPips = 50; // Distancia del stop loss en pips
input int ATRPeriod = 14; // Período para calcular el ATR (volatilidad)
// Función para calcular el tamaño de lote ajustado por volatilidad
double CalculateLotSizeWithVolatility(double riskPercentage, int stopLossPips) {
// Obtener el saldo de la cuenta
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
// Calcular el monto a arriesgar
double riskAmount = (riskPercentage / 100) * balance;
// Obtener el tamaño del contrato y el valor del punto
double contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
double pointValue = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// Calcular el ATR para medir la volatilidad
double atr = iATR(_Symbol, _Period, ATRPeriod, 0); // ATR actual
double volatilityMultiplier = atr > 0 ? atr : 1.0; // Evitar división por cero
// Calcular el tamaño de lote ajustado por volatilidad
double lotSize = MathFloor((riskAmount / (stopLossPips * pointValue * volatilityMultiplier)) / contractSize);
return lotSize > 0 ? lotSize : 0.01; // Asegurar un mínimo de 0.01 lote
}
Explicación del Código
- Parámetros de Entrada:
RiskPercentage: Define el porcentaje del saldo que estás dispuesto a arriesgar en cada operación.StopLossPips: Define la distancia del stop loss en pips.ATRPeriod: Define el período para calcular el Average True Range (ATR), que mide la volatilidad del mercado.
- Cálculo del Monto a Arriesgar:
- El monto a arriesgar se calcula como un porcentaje del saldo de la cuenta (
balance).
- El monto a arriesgar se calcula como un porcentaje del saldo de la cuenta (
- Cálculo del ATR (Volatilidad):
- Usamos la función
iATRpara calcular el ATR actual del símbolo y período seleccionados. - El ATR actúa como un multiplicador de volatilidad. Si el mercado es más volátil, el multiplicador será mayor, lo que reduce el tamaño de lote para compensar el mayor riesgo.
- Usamos la función
- Ajuste del Tamaño de Lote:
- Dividimos el monto a arriesgar entre el producto de la distancia del stop loss, el valor del punto y el multiplicador de volatilidad.
- Esto asegura que el tamaño de lote sea más pequeño en mercados volátiles y más grande en mercados tranquilos.
- Manejo de Errores:
- Si el ATR es cero (lo cual es improbable pero posible en ciertos casos), usamos un valor predeterminado de
1.0para evitar divisiones por cero.
- Si el ATR es cero (lo cual es improbable pero posible en ciertos casos), usamos un valor predeterminado de
- Resultado Final:
- El tamaño de lote se redondea hacia abajo usando
MathFloory se asegura de que no sea menor a0.01.
- El tamaño de lote se redondea hacia abajo usando
Resultado Esperado
Cuando ejecutes este código, el tamaño de lote se ajustará dinámicamente según la volatilidad del mercado:
- En mercados tranquilos (bajo ATR), el tamaño de lote será mayor porque el riesgo es menor.
- En mercados volátiles (alto ATR), el tamaño de lote será menor para reducir el riesgo asociado con movimientos bruscos del precio.
Por ejemplo:
- Si el ATR es bajo (mercado tranquilo), podrías obtener un tamaño de lote de
0.10. - Si el ATR es alto (mercado volátil), podrías obtener un tamaño de lote de
0.05.
Interpretación del Cambio
Este ejercicio mejora el cálculo del tamaño de lote al incorporar un multiplicador de volatilidad basado en el ATR. Esto es útil porque:
- Reduce el riesgo en mercados volátiles, donde los movimientos impredecibles pueden llevar a pérdidas rápidas.
- Maximiza el uso del capital en mercados tranquilos, donde el riesgo es menor y puedes permitirte posiciones más grandes.
Casos Prácticos
Este tipo de cálculo puede ser utilizado para:
- Adaptar dinámicamente el tamaño de posición a las condiciones del mercado.
- Reducir el impacto de eventos volátiles, como noticias económicas o rupturas técnicas.
- Mejorar la gestión de riesgos en estrategias automatizadas.
¡Espero que este ejemplo te ayude a entender cómo integrar la volatilidad en el cálculo del tamaño de lote en MQL5!
Ejercicio 2: Implementa una estrategia de gestión de dinero combinada que use tanto Martingale como Anti-Martingale según el rendimiento reciente.
Ver solución:Ocultar soluciónA continuación, te proporciono el código de una estrategia de gestión de dinero combinada que utiliza tanto Martingale como Anti-Martingale , ajustando el tamaño de la posición según el rendimiento reciente. He añadido comentarios detallados para explicar cada parte del código.
//+------------------------------------------------------------------+
//| Estrategia de gestión de dinero combinada |
//+------------------------------------------------------------------+
// Parámetros de entrada
input double BaseLotSize = 0.1; // Tamaño base de lote
input int PerformanceLookback = 5; // Número de operaciones para evaluar el rendimiento reciente
input double ProfitThreshold = 10; // Umbral de ganancia para activar Anti-Martingale (en %)
input double LossThreshold = -5; // Umbral de pérdida para activar Martingale (en %)
// Variables globales
double previousPerformance = 0; // Almacena el rendimiento reciente
// Función principal que se ejecuta en cada tick
void OnTick() {
// Calcular el rendimiento reciente
double currentPerformance = CalculateRecentPerformance();
// Determinar el tamaño de lote basado en el rendimiento reciente
double lotSize = AdjustLotSize(currentPerformance);
// Abrir una nueva posición con el tamaño de lote calculado
if (PositionsTotal() == 0) { // Solo si no hay posiciones abiertas
OpenPosition(lotSize);
}
}
// Función para calcular el rendimiento reciente
double CalculateRecentPerformance() {
double totalProfit = 0;
int totalTrades = 0;
// Iterar sobre las últimas operaciones cerradas
for (int i = 0; i < HistoryDealsTotal(); i++) {
ulong ticket = HistoryDealGetTicket(i);
if (ticket > 0) {
double profit = HistoryDealGetDouble(ticket, DEAL_PROFIT);
totalProfit += profit;
totalTrades++;
if (totalTrades >= PerformanceLookback) break; // Limitar a las últimas X operaciones
}
}
// Calcular el rendimiento promedio en porcentaje
double averageProfit = (totalTrades > 0) ? (totalProfit / AccountInfoDouble(ACCOUNT_BALANCE)) * 100 : 0;
return averageProfit;
}
// Función para ajustar el tamaño de lote basado en el rendimiento
double AdjustLotSize(double performance) {
if (performance >= ProfitThreshold) {
// Activar Anti-Martingale: Aumentar el tamaño de lote después de ganancias
return BaseLotSize * 1.5; // Incrementar en un 50%
} else if (performance <= LossThreshold) {
// Activar Martingale: Duplicar el tamaño de lote después de pérdidas
return BaseLotSize * 2; // Duplicar el tamaño base
} else {
// Mantener el tamaño base si el rendimiento está dentro del rango neutro
return BaseLotSize;
}
}
// Función para abrir una nueva posición
void OpenPosition(double lotSize) {
double stopLoss = NormalizeDouble(Ask - 50 * Point(), _Digits); // Stop loss a 50 pips
double takeProfit = NormalizeDouble(Ask + 100 * Point(), _Digits); // Take profit a 100 pips
if (OrderSend(_Symbol, OP_BUY, lotSize, Ask, 10, stopLoss, takeProfit)) {
Print("Posición abierta con tamaño de lote: ", DoubleToString(lotSize, 2));
} else {
Print("Error al abrir posición. Código de error: ", GetLastError());
}
}
Explicación del Código
- Parámetros de Entrada:
BaseLotSize: Define el tamaño base de lote para las operaciones.PerformanceLookback: Número de operaciones recientes utilizadas para evaluar el rendimiento.ProfitThreshold: Umbral de ganancia (en %) para activar la estrategia Anti-Martingale.LossThreshold: Umbral de pérdida (en %) para activar la estrategia Martingale.
- Cálculo del Rendimiento Reciente:
- La función
CalculateRecentPerformanceitera sobre las últimas operaciones cerradas (HistoryDealsTotal) y calcula el rendimiento promedio en porcentaje. - El rendimiento se limita a las últimas
PerformanceLookbackoperaciones para enfocarse en el desempeño reciente.
- La función
- Ajuste del Tamaño de Lote:
- Si el rendimiento supera el umbral de ganancia (
ProfitThreshold), se activa la estrategia Anti-Martingale , incrementando el tamaño de lote en un 50%. - Si el rendimiento cae por debajo del umbral de pérdida (
LossThreshold), se activa la estrategia Martingale , duplicando el tamaño de lote. - Si el rendimiento está dentro del rango neutro, se mantiene el tamaño base de lote.
- Si el rendimiento supera el umbral de ganancia (
- Apertura de Posiciones:
- La función
OpenPositionabre una nueva posición con el tamaño de lote calculado, utilizando stop loss y take profit predefinidos.
- La función
Resultado Esperado
Cuando ejecutes este EA, verás mensajes similares a estos en la ventana de resultados:
- Si el rendimiento reciente es positivo (por ejemplo, +15%):
Posición abierta con tamaño de lote: 0.15
- Si el rendimiento reciente es negativo (por ejemplo, -10%):
Posición abierta con tamaño de lote: 0.20
- Si el rendimiento reciente está dentro del rango neutro:
Posición abierta con tamaño de lote: 0.10
Interpretación del Cambio
Este ejercicio implementa una estrategia de gestión de dinero combinada que adapta dinámicamente el tamaño de lote según el rendimiento reciente. Esto es útil porque:
- Anti-Martingale: Capitaliza las rachas positivas al aumentar el tamaño de lote cuando el rendimiento es bueno.
- Martingale: Intenta recuperar pérdidas al aumentar el tamaño de lote después de una racha negativa.
- Rango Neutro: Mantiene el tamaño base de lote cuando el rendimiento no es ni demasiado bueno ni demasiado malo, evitando movimientos agresivos innecesarios.
Casos Prácticos
Esta estrategia puede ser utilizada para:
- Adaptar el tamaño de posición a las condiciones actuales del mercado y al desempeño reciente.
- Reducir el riesgo durante períodos de incertidumbre al mantener el tamaño base de lote.
- Maximizar las ganancias durante rachas positivas mientras intenta recuperar pérdidas durante rachas negativas.
¡Espero que este ejemplo te ayude a entender cómo combinar estrategias de gestión de dinero en MQL5!
Ejercicio 3: Crea un EA que use lotería fraccionada para abrir tres posiciones con diferentes niveles de stop loss y take profit.
Ver solución:Ocultar soluciónA continuación, te proporciono el código de un Expert Advisor (EA) que utiliza la lotería fraccionada para abrir tres posiciones con diferentes niveles de stop loss y take profit . He añadido comentarios detallados para explicar cada parte del código.
//+------------------------------------------------------------------+
//| EA con lotería fraccionada |
//+------------------------------------------------------------------+
// Parámetros de entrada
input double TotalRiskPercentage = 2.0; // Porcentaje total de riesgo por operación (%)
input int NumberOfPositions = 3; // Número de posiciones a abrir
input int[] StopLossPips = {30, 50, 70}; // Distancias de stop loss para cada posición (en pips)
input int[] TakeProfitPips = {60, 100, 140}; // Distancias de take profit para cada posición (en pips)
// Función principal que se ejecuta en cada tick
void OnTick() {
// Verificar si ya hay posiciones abiertas
if (PositionsTotal() == 0) {
OpenFractionalPositions();
}
}
// Función para abrir posiciones fraccionadas
void OpenFractionalPositions() {
double balance = AccountInfoDouble(ACCOUNT_BALANCE); // Saldo de la cuenta
double totalRiskAmount = (TotalRiskPercentage / 100) * balance; // Monto total a arriesgar
double riskPerPosition = totalRiskAmount / NumberOfPositions; // Riesgo por posición
for (int i = 0; i < NumberOfPositions; i++) {
// Calcular el tamaño de lote para cada posición
double lotSize = CalculateLotSize(riskPerPosition, StopLossPips[i]);
// Calcular los niveles de stop loss y take profit
double stopLoss = NormalizeDouble(Ask - StopLossPips[i] * Point(), _Digits);
double takeProfit = NormalizeDouble(Ask + TakeProfitPips[i] * Point(), _Digits);
// Abrir la posición
if (OrderSend(_Symbol, OP_BUY, lotSize, Ask, 10, stopLoss, takeProfit)) {
Print("Posición ", i + 1, " abierta. Lote: ", DoubleToString(lotSize, 2),
", SL: ", DoubleToString(stopLoss, _Digits),
", TP: ", DoubleToString(takeProfit, _Digits));
} else {
Print("Error al abrir posición ", i + 1, ". Código de error: ", GetLastError());
}
}
}
// Función para calcular el tamaño de lote basado en el riesgo y el stop loss
double CalculateLotSize(double riskAmount, int stopLossPips) {
double contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE); // Tamaño del contrato
double pointValue = SymbolInfoDouble(_Symbol, SYMBOL_POINT); // Valor del punto
// Calcular el tamaño de lote: (monto a arriesgar / valor de punto) / tamaño del contrato
double lotSize = MathFloor((riskAmount / (stopLossPips * pointValue)) / contractSize);
return lotSize > 0 ? lotSize : 0.01; // Asegurar un mínimo de 0.01 lote
}
Explicación del Código
- Parámetros de Entrada:
TotalRiskPercentage: Define el porcentaje total del saldo que estás dispuesto a arriesgar en las tres posiciones combinadas.NumberOfPositions: Número de posiciones que se abrirán (en este caso, 3).StopLossPipsyTakeProfitPips: Arrays que definen las distancias de stop loss y take profit para cada posición.
- Lotería Fraccionada:
- El riesgo total (
TotalRiskPercentage) se divide entre el número de posiciones (NumberOfPositions) para calcular el riesgo por posición. - Cada posición tiene un tamaño de lote diferente basado en su distancia de stop loss.
- El riesgo total (
- Cálculo del Tamaño de Lote:
- La función
CalculateLotSizecalcula el tamaño de lote para cada posición dividiendo el monto a arriesgar entre el valor del punto y el tamaño del contrato. - Esto asegura que el riesgo por posición sea proporcional al stop loss.
- La función
- Apertura de Posiciones:
- Se abren tres posiciones con diferentes niveles de stop loss y take profit.
- Cada posición tiene un tamaño de lote ajustado según su nivel de riesgo.
- Manejo de Errores:
- Si una posición no se abre correctamente, se muestra un mensaje de error con el código correspondiente.
Resultado Esperado
Cuando ejecutes este EA, verás mensajes similares a estos en la ventana de resultados:
- Para la primera posición:
Posición 1 abierta. Lote: 0.05, SL: 1.23000, TP: 1.23600
- Para la segunda posición:
Posición 2 abierta. Lote: 0.03, SL: 1.22800, TP: 1.23800
- Para la tercera posición:
Posición 3 abierta. Lote: 0.02, SL: 1.22600, TP: 1.24000
Interpretación del Cambio
Este ejercicio implementa una estrategia de lotería fraccionada , donde el riesgo total se divide en múltiples posiciones con diferentes niveles de stop loss y take profit. Esto es útil porque:
- Reduce el impacto de una sola operación fallida al distribuir el riesgo en varias posiciones.
- Permite aprovechar diferentes escenarios de mercado al tener múltiples objetivos de take profit.
- Mejora la gestión de riesgos al ajustar dinámicamente el tamaño de lote según el stop loss de cada posición.
Casos Prácticos
Esta estrategia puede ser utilizada para:
- Diversificar el riesgo en mercados volátiles o inciertos.
- Aprovechar diferentes niveles de soporte y resistencia al configurar múltiples stop loss y take profit.
- Implementar una gestión de riesgos más robusta en estrategias automatizadas.
¡Espero que este ejemplo te ayude a entender cómo implementar la lotería fraccionada en MQL5!
Conclusión: La gestión avanzada de riesgos es esencial para proteger tu capital y maximizar tus ganancias. Al dominar técnicas como el cálculo del tamaño de posición, la implementación de reglas de gestión de dinero y el uso de estrategias como la lotería fraccionada y escalonada, puedes desarrollar EAs más robustos y eficientes.
En el próximo capítulo, exploraremos cómo implementar notificaciones, registros de eventos y alertas visuales en MQL5.
¡Sigue practicando y perfeccionando tus habilidades en MQL5!
