
En el mundo dinámico del trading, la capacidad de eliminar sesgos emocionales es crucial para el éxito. Este artículo explora la aplicación de Python, un poderoso lenguaje de programación, para implementar y ejecutar estrategias de gestión de riesgos basadas en ejemplos de operaciones en vivo que realicé el año pasado para probar un par de estrategias de trading.
Automatizando el proceso de toma de decisiones, los traders pueden reducir significativamente la interferencia emocional y mejorar la efectividad general de sus esfuerzos en los mercados. Únete a nosotros en un viaje al mundo del trading algorítmico, donde Python se convierte en un valioso aliado en la búsqueda de decisiones financieras disciplinadas y libres de emociones.
Operaciones históricas
Mi diario de trading está completamente hecho en Excel, ya que me brinda mucha libertad para construir estadísticas. Estas estadísticas incluyen pips de ganancia y pips de drawdown, lo que me permite realizar pruebas estáticas en mis operaciones para optimizar mi plan de trading basado en operaciones históricas.
Todas estas calculadoras no tienen en cuenta ninguna tarifa. Son puramente para ver si hay una ventaja estadística en cambiar mi plan de gestión de riesgos.
Tras revisar mi actividad de trading, es evidente que alcanzar una ganancia del 10% me tomó un total de 25 operaciones. Dentro de este conjunto de datos, es notable que los factores emocionales llevaron a varios errores, lo que dificultó el ritmo de mi progreso.
Un análisis exhaustivo de mi diario de trading revela un potencial no aprovechado en diversas operaciones, donde se podría haber obtenido un rendimiento mayor. Sin embargo, un problema recurrente fue la tendencia a prolongar posiciones en un intento de maximizar ganancias a partir de los movimientos del mercado.
Para obtener información sobre el impacto de estrategias alternativas en el rendimiento, realicé una evaluación de escenarios estáticos específicos. Estos escenarios incluyen:
- Cierre de todas las operaciones con una ganancia de 30 pips.
- Suponiendo que las operaciones con menos de 20 pips de ganancia se detuvieron en el punto de equilibrio y posteriormente se cerraron con una ganancia de 30 pips.
- Cierre de todas las operaciones con una ganancia de 10 pips.
- Cierre de todas las operaciones con una ganancia de 20 pips e implementación del punto de equilibrio tan pronto como una posición se volvió rentable.
Los hallazgos indican que no es evidente una correlación directa entre una tasa de operaciones ganadoras más alta y un aumento en el rendimiento. Sin embargo, es digno de destacar que, en el contexto de mi enfoque de trading, existe un compromiso entre una tasa de operaciones ganadoras más baja y el potencial de fatiga mental. Esto sugiere que se debe encontrar un equilibrio cuidadoso para optimizar el rendimiento y manejar los factores psicológicos en la búsqueda de objetivos positivos.
Gestión de riesgos en Python
Dado que el escenario #4 tenía el mayor potencial de rendimiento. Las operaciones también tenían un valor de stop loss fijo de 10 pips, por lo que 20 pips son simplemente 2R. La otra condición era que las operaciones se movieran al punto de equilibrio tan pronto como estuvieran en zona de ganancias. Dado que eso no puede cuantificarse, lo que se puede hacer es que, digamos, después de 10 pips o 1R, el stop loss se mueva al precio de entrada.
Para comenzar se usa la librería de MT5 para recuperar todas las posiciones abiertas y colocar los datos en un dataframe legible de Python que se puede utilizar para un análisis adicional:
def OpenPositionsAsDF():
list_current = mt5.positions_get()
if len(list_current) == 0:
return None
else:
# crear un dataframe vacío
summary = pd.DataFrame()
# crear los nombres de las columnas
columns = [
"ticket",
"type",
"symbol",
"volume",
"profit",
"price",
"tp",
"sl",
"price_current",
"trade_size",
]
# Bucle para agregar cada fila al dataframe
for element in list_current:
trade_type = None
if element.type == 0:
trade_type = 'buy'
else:
trade_type = 'sell'
element_pandas = pd.DataFrame(
[
element.ticket,
trade_type,
element.symbol,
element.volume,
element.profit,
element.price_open,
element.tp,
element.sl,
element.price_current,
mt5.symbol_info(element.symbol).trade_contract_size
],
index=columns,
).transpose()
summary = pd.concat((summary, element_pandas), axis=0)
return summary
Calcular la relación riesgo-recompensa (RR) de las operaciones abiertas se puede hacer fácilmente utilizando sólo los precios actuales, de stop loss y de entrada. Aquí tienes una función que lo hace automáticamente por ti en Python:
def CalculateRR(sl: float, entry: float, current_price: float) -> float:
# diferencia entre el stoploss y el precio de entrada
sl_entry_diff = abs(sl - entry)
# diferencia entre el precio actual y el precio de entrada
entry_curr_price = abs(entry - current_price)
# dividir ambos valores y redondear a 2 decimales
rr = round(entry_curr_price / sl_entry_diff, 2)
return rr
Siempre es recomendable agregar una función preventiva que garantice que todas mis operaciones estén dentro de un cierto porcentaje del capital disponible. Esto se etiqueta como asignación máxima de capital por operación. No quiero que mi posición se cierre; sin embargo, haré que suene una campana de alarma para poder evaluar la situación cuando surja:
def CheckTradesRisk(balance: float, profit: float, max_bal_risked_percentage: float):
# crear un sonido de advertencia cuando el riesgo es mayor que el riesgo máximo permitido
risk = (profit / balance)
if risk >= max_bal_risked_percentage:
for i in range(20):
winsound.Beep(500, 1000)
print(f'¡ADVERTENCIA!: {risk} es mayor que {max_bal_risked_percentage}!!')
else:
return
return
Ahora todo lo que necesitamos es una función para tomar parciales y una función que mueva nuestros stops al punto de entrada:
def Partials(position: pd.DataFrame, partial_size: float = 0.5) -> str:
# obtener el precio actual del mercado
tick = mt5.symbol_info_tick(position["symbol"])
# calcular el volumen a cerrar parcialmente
partials = round(position["volume"] * partial_size, 2)
# verificar que el volumen parcial sea mayor que el volumen mínimo
info = mt5.symbol_info(position["symbol"])
if partials >= info.volume_min:
partials = partials
else:
raise ValueError("El volumen parcial es menor que el volumen mínimo")
# construir la solicitud
request = {
"action": mt5.TRADE_ACTION_DEAL,
"position": position["ticket"],
"symbol": position["symbol"],
"volume": partials,
"type": mt5.ORDER_TYPE_BUY if position["type"] == 'sell' else mt5.ORDER_TYPE_SELL,
"price": tick.ask if position["type"] == 'sell' else tick.bid,
"deviation": 10,
"magic": 234000,
"comment": "Partials",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
# enviar la solicitud a mt5
result = mt5.order_send(request)
# verificar si la orden se ejecutó correctamente
if result.retcode != mt5.TRADE_RETCODE_DONE:
print("4. la orden falló, retcode={}".format(result.retcode))
print("resultado", result)
return result.comment
else:
return result.comment
El valor predeterminado para los parciales está establecido en el 50% del valor original. Esto puede cambiarse dependiendo de los resultados estáticos de las estrategias de gestión de riesgos probadas en Excel.
def Breakeven(position: pd.DataFrame) -> str:
# construir la solicitud
request = {
"action": mt5.TRADE_ACTION_SLTP,
"symbol": position['symbol'],
"position": position["ticket"],
"type": mt5.ORDER_TYPE_BUY if position["type"] == 'sell' else mt5.ORDER_TYPE_SELL,
"deviation": 10,
"sl": position["price"],
"type_filling": mt5.ORDER_FILLING_IOC,
"volume": position["volume"],
"type_time": mt5.ORDER_TIME_GTC,
"comment": "Breakeven",
}
# enviar la solicitud a mt5
result = mt5.order_send(request)
# verificar si la orden se ejecutó correctamente
if result.retcode != mt5.TRADE_RETCODE_DONE:
print("4. la orden falló, retcode={}".format(result.retcode))
print("resultado", result)
return result.comment
else:
return result.comment
Con todas estas funciones, se pueden combinar para crear el plan de gestión de riesgos deseado sin necesidad de mirar un gráfico de precios después de que se haya ingresado el intercambio.
Conclusión
En conclusión, la fusión de Python con la biblioteca de MT5 emerge como una combinación potente para implementar estrategias de gestión de riesgos sin emociones en el trading. La utilización de algoritmos proporciona a los traders la capacidad adaptativa para responder dinámicamente a las percepciones de los datos. Es imperativo reconocer que mientras el rendimiento histórico sirve como guía, los resultados futuros siguen siendo inciertos. El enfoque integrado propuesto no solo empodera a los traders, sino que también inculca disciplina y una mentalidad centrada en los datos, lo que permite una experiencia comercial más informada y resiliente en los mercados financieros en constante evolución.















