Uso de Python para aplicar estrategias de gestión de riesgos

0
5
Como conectar nuestra cuenta de MQL5 con Python

Códigos de gestión de riesgo en Python

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:

  1. Cierre de todas las operaciones con una ganancia de 30 pips.
  2. 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.
  3. Cierre de todas las operaciones con una ganancia de 10 pips.
  4. 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.


 

Leave a reply