English Русский 中文 Deutsch 日本語 Português
preview
Desarrollo de un robot de trading en Python (Parte 3): Implementamos un algoritmo comercial basado en el modelo

Desarrollo de un robot de trading en Python (Parte 3): Implementamos un algoritmo comercial basado en el modelo

MetaTrader 5Sistemas comerciales | 25 noviembre 2024, 13:34
395 0
Yevgeniy Koshtenko
Yevgeniy Koshtenko

En el primer artículo de la serie, cargamos el dataset, y luego lo etiquetamos, lo enriquecimos y lo marcamos. El segundo artículo de la serie se centró en la creación y el entrenamiento del modelo, así como en la validación cruzada y la aplicación del bagging. 

Ahora que nuestro modelo está entrenado y validado, es momento de empezar a negociar de verdad utilizando la biblioteca MetaTrader 5 para Python. Esta potente biblioteca nos permite automatizar el trading directamente a través de Python, usando las funciones y clases proporcionadas por la plataforma MetaTrader 5.


Implementamos un algoritmo comercial basado en el modelo

Para aplicar un algoritmo comercial basado en nuestro modelo, utilizaremos el siguiente planteamiento. El algoritmo básico consistirá en abrir transacciones con stop loss predeterminados y take profit que coincidan con las etiquetas generadas por el modelo. Si el modelo predice que el precio del activo subirá, abriremos una posición larga con los niveles de stop loss y take profit establecidos. Si el patrón predice una caída del precio, abriremos una posición corta con parámetros similares de stop loss y take profit.

La biblioteca MetaTrader 5 para Python ofrece las herramientas necesarias para gestionar la apertura y cierre de transacciones, así como para establecer niveles de stop loss y take profit. Esto nos permitirá automatizar totalmente el proceso comercial basándonos en las predicciones de nuestro modelo.

Usando los datos obtenidos durante las etapas previas de análisis y entrenamiento, podemos enviar señales en tiempo real para abrir y cerrar posiciones en la plataforma MetaTrader 5, garantizando así la continuidad y precisión de nuestro algoritmo comercial.

Así pues, la integración de nuestro modelo entrenado con la biblioteca MetaTrader 5 para Python nos permitirá crear un algoritmo comercial eficiente y automatizado que negociará basándose en las predicciones del modelo, gestionando los riesgos con los stop loss especificados y protegiendo los beneficios con los take profit necesarios.


Configuración del entorno y el terminal comercial, ejecución del algoritmo

En primer lugar, tendremos que configurar el entorno y el terminal comercial MetaTrader 5. Para ello, seguiremos los pasos que se indican a continuación:

Instalamos las bibliotecas para Python utilizando el comando pip:

pip install numpy pandas MetaTrader5 scikit-learn xgboost

En las referencias del terminal, especificamos nuestra ruta al archivo ejecutable del terminal:

terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"


Escribimos el trading online

Para implementar el trading online, escribiremos la función online_trading , que abrirá transacciones según la predicción de nuestro modelo.

La función online_trading admitirá los siguientes argumentos:

  • symbol - símbolo del instrumento con el que se negociará
  • features - lista de características que se utilizarán para la previsión
  • model - modelo entrenado que se utilizará para las previsiones

Dentro de la función online_trading, primero nos conectaremos al terminal MetaTrader 5 utilizando la ruta especificada en terminal_path . A continuación, obtendremos los precios actuales del instrumento utilizando la función mt5.symbol_info_tick(symbol) .

Después usaremos nuestro modelo para predecir la señal basándonos en las características transmitidas. Si la previsión es positiva (superior a 0,5), abriremos una posición larga, y si la previsión es negativa (inferior a 0,5), abriremos una posición corta.

También fijaremos un stop loss y un take profit para cada transacción con el fin de minimizar el riesgo.

Si ya hemos alcanzado el número máximo de transacciones abiertas (fijado en la constante MAX_OPEN_TRADES), no abriremos nuevas transacciones y esperaremos a que se cierre una de las transacciones abiertas.

Si la previsión no nos permite abrir una nueva transacción, también esperaremos a que aparezca una nueva señal.

Al final de la función retornaremos el resultado de la ejecución de la transacción, si se ha abierto con éxito, o None, si la transacción no se ha abierto.

def online_trading(symbol, features, model):
    terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"

    if not mt5.initialize(path=terminal_path):
        print("Error: Failed to connect to MetaTrader 5 terminal")
        return

    open_trades = 0
    e = None
    attempts = 30000

    while True:
        symbol_info = mt5.symbol_info(symbol)
        if symbol_info is not None:
            break
        else:
            print("Error: Instrument not found. Attempt {} of {}".format(_ + 1, attempts))
            time.sleep(5)

    while True:
        price_bid = mt5.symbol_info_tick(symbol).bid
        price_ask = mt5.symbol_info_tick(symbol).ask

        signal = model.predict(features)

        positions_total = mt5.positions_total()

        for _ in range(attempts):
            if positions_total < MAX_OPEN_TRADES and signal[-1] > 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": 0.3,
                    "type": mt5.ORDER_TYPE_BUY,
                    "price": price_ask,
                    "sl": price_ask - 150 * symbol_info.point,
                    "tp": price_ask + 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            elif positions_total < MAX_OPEN_TRADES and signal[-1] < 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": 0.3,
                    "type": mt5.ORDER_TYPE_SELL,
                    "price": price_bid,
                    "sl": price_bid + 150 * symbol_info.point,
                    "tp": price_bid - 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            else:
                print("No signal to open a position")
                return None

            result = mt5.order_send(request)

            if result.retcode == mt5.TRADE_RETCODE_DONE:
                if signal[-1] < 0.5:
                    print("Buy position opened")
                    open_trades += 1
                elif signal[-1] > 0.5:
                    print("Sell position opened")
                    open_trades += 1
                return result.order
            else:
                print("Error: Trade request not executed, retcode={}. Attempt {}/{}".format(result.retcode, _ + 1, attempts))
                time.sleep(3)

        time.sleep(4000)

def process_symbol(symbol):
    try:
        # Retrieve data for the specified symbol
        raw_data = retrieve_data(symbol)
        if raw_data is None:
            print("Los datos para el símbolo {} no se han encontrado".format(symbol))
            return None

        # Augment data
        augmented_data = augment_data(raw_data)

        # Markup data
        marked_data = markup_data(augmented_data.copy(), 'close', 'label')

        # Label data
        labeled_data = label_data(marked_data, symbol)

        # Generate new features
        labeled_data_generate = generate_new_features(labeled_data, num_features=100, random_seed=1)

        # Cluster features by GMM
        labeled_data_clustered = cluster_features_by_gmm(labeled_data_generate, n_components=4)

        # Feature engineering
        labeled_data_engineered = feature_engineering(labeled_data_clustered, n_features_to_select=10)

        # Train XGBoost classifier
        train_data = labeled_data_engineered[labeled_data_engineered.index <= FORWARD]


Iniciamos el algoritmo comercial online

Para ejecutar el algoritmo comercial online, llamaremos a la función process_symbol , transmitiéndole el símbolo del instrumento a negociar.

Dentro de la función process_symbol, llamaremos a la función online_trading , transmitiéndole los argumentos necesarios, e iniciaremos un ciclo que se ejecutará hasta que sea interrumpido.

Al final del ciclo, haremos una pausa de 6 segundos para no sobrecargar el terminal MetaTrader 5.

Si se produce un error durante la ejecución del algoritmo, mostraremos un mensaje de error e interrumpiremos la ejecución.


Sistema inteligente de gestión de riesgos y reducciones

La gestión del riesgo es la piedra angular del éxito de una estrategia comercial. Uno de los principales riesgos a los que se enfrentan los tráders es el riesgo de reducción, cuando los precios de los activos caen por debajo de un nivel predeterminado. Minimizar este riesgo requiere un sistema eficaz de gestión de riesgos capaz de adaptarse a los cambios en las condiciones del mercado.

Así, desarrollaremos un sistema que reduzca automáticamente el volumen de transacciones en caso de reducción del balance de la cuenta utilizando herramientas de la biblioteca MetaTrader 5 para Python.

Las reglas básicas del sistema serán las siguientes:

  1. Obtención diaria del balance actual de la cuenta: cada día el sistema obtendrá el balance actual de la cuenta para analizar los cambios.

  2. Disminución del volumen de transacciones en caso de reducción: si el balance ha caído más de un 2% durante el día, el sistema reducirá automáticamente el volumen de transacciones abiertas en un 10%. Esto se hará en incrementos de 0,01 lotes para reducir gradualmente los riesgos.

  3. Disminución adicional del volumen si continúa la reducción del balance: si continúa la reducción del balance, cada día se reducirá el volumen de transacciones en un 10% adicional y 0,01 lotes, lo cual ofrecerá una mayor protección del capital.

  4. Regreso al volumen original tras la recuperación del balance: cuando el balance actual de la cuenta supere el pico anterior, el sistema devolverá automáticamente el volumen de transacciones al valor original. Esto ayudará a restablecer la plena actividad comercial tras una caída temporal del volumen debido a una reducción.

Además, hemos añadido nuevas variables a la función online_trading: account_balance, para almacenar el balance actual, peak_balance, para almacenar el nivel de balance máximo anterior y daily_drop, para realizar un seguimiento de la reducción diaria. Estas variables se usarán para aplicar la lógica de gestión de riesgos.

Código de ejemplo:

def online_trading(symbol, features, model):
    terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"

    if not mt5.initialize(path=terminal_path):
        print("Error: Failed to connect to MetaTrader 5 terminal")
        return

    open_trades = 0
    e = None
    attempts = 30000

    # Get the current account balance
    account_info = mt5.account_info()
    account_balance = account_info.balance

    # Set the initial volume for opening trades
    volume = 0.3

    # Set the initial peak balance
    peak_balance = account_balance

    while True:
        symbol_info = mt5.symbol_info(symbol)
        if symbol_info is not None:
            break
        else:
            print("Error: Instrument not found. Attempt {} of {}".format(_ + 1, attempts))
            time.sleep(5)

    while True:
        price_bid = mt5.symbol_info_tick(symbol).bid
        price_ask = mt5.symbol_info_tick(symbol).ask

        signal = model.predict(features)

        positions_total = mt5.positions_total()

        # Calculate the daily drop in account balance
        account_info = mt5.account_info()
        current_balance = account_info.balance
        daily_drop = (account_balance - current_balance) / account_balance

        # Reduce the volume for opening trades by 10% with a step of 0.01 lot for each day of daily drop
        if daily_drop > 0.02:
            volume -= 0.01
            volume = max(volume, 0.01)
        elif current_balance > peak_balance:
            volume = 0.3
            peak_balance = current_balance

        for _ in range(attempts):
            if positions_total < MAX_OPEN_TRADES and signal[-1] > 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_BUY,
                    "price": price_ask,
                    "sl": price_ask - 150 * symbol_info.point,
                    "tp": price_ask + 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            elif positions_total < MAX_OPEN_TRADES and signal[-1] < 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_SELL,
                    "price": price_bid,
                    "sl": price_bid + 150 * symbol_info.point,
                    "tp": price_bid - 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            else:
                print("No signal to open a position")
                return None

            result = mt5.order_send(request)

            if result.retcode == mt5.TRADE_RETCODE_DONE:
                if signal[-1] < 0.5:
                    print("Buy position opened")
                    open_trades += 1
                elif signal[-1] > 0.5:
                    print("Sell position opened")
                    open_trades += 1
                return result.order
            else:
                print("Error: Trade request not executed, retcode={}. Attempt {}/{}".format(result.retcode, _ + 1, attempts))
                time.sleep(3)

        time.sleep(4000)

Aplicación de la gestión de lotes basada en el criterio de Kelly

La gestión de lotes es otro aspecto importante de la gestión de riesgos en el trading. Uno de los métodos más populares de gestión de lotes es el criterio de Kelly. El criterio de Kelly es una fórmula matemática que ayuda a determinar el tamaño óptimo de la apuesta usando como base la probabilidad de ganancia y el ratio de ganancias/pérdidas.

En este artículo, veremos cómo implantar la gestión de lotes según el criterio de Kelly en nuestro sistema de gestión de riesgos. Usaremos la distancia entre la predicción del modelo y 0,5 como probabilidad de ganancia. Cuanto más se acerque la predicción del modelo a 0,5, menor será la probabilidad de ganancia y menor deberá ser el tamaño de la apuesta.

Este es el aspecto que tendrá la función online_trading modificada:

def online_trading(symbol, features, model):
    terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"

    if not mt5.initialize(path=terminal_path):
        print("Error: Failed to connect to MetaTrader 5 terminal")
        return

    open_trades = 0
    e = None
    attempts = 30000

    # Get the current account balance
    account_info = mt5.account_info()
    account_balance = account_info.balance

    # Set the initial volume for opening trades
    volume = 0.1

    # Set the initial peak balance
    peak_balance = account_balance

    while True:
        symbol_info = mt5.symbol_info(symbol)
        if symbol_info is not None:
            break
        else:
            print("Error: Instrument not found. Attempt {} of {}".format(_ + 1, attempts))
            time.sleep(5)

    while True:
        price_bid = mt5.symbol_info_tick(symbol).bid
        price_ask = mt5.symbol_info_tick(symbol).ask

        signal = model.predict(features)

        positions_total = mt5.positions_total()

        # Calculate the daily drop in account balance
        account_info = mt5.account_info()
        current_balance = account_info.balance
        daily_drop = (account_balance - current_balance) / account_balance

        # Calculate the probability of winning based on the distance between the model's prediction and 0.5
        probability_of_winning = abs(signal[-1] - 0.5) * 2

        # Calculate the optimal volume for opening trades using the Kelly criterion
        optimal_volume = (probability_of_winning - (1 - probability_of_winning) / risk_reward_ratio) / risk_reward_ratio * account_balance / price_ask

        # Reduce the volume for opening trades by 10% with a step of 0.01 lot for each day of daily drop
        if daily_drop > 0.02:
            optimal_volume -= 0.01
            optimal_volume = max(optimal_volume, 0.01)
        elif current_balance > peak_balance:
            optimal_volume = (probability_of_winning - (1 - probability_of_winning) / risk_reward_ratio) / risk_reward_ratio * account_balance / price_ask
            peak_balance = current_balance

        # Set the volume for opening trades
        volume = optimal_volume

        for _ in range(attempts):
            if positions_total < MAX_OPEN_TRADES and signal[-1] > 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_BUY,
                    "price": price_ask,
                    "sl": price_ask - 150 * symbol_info.point,
                    "tp": price_ask + 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            elif positions_total < MAX_OPEN_TRADES and signal[-1] < 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_SELL,
                    "price": price_bid,
                    "sl": price_bid + 150 * symbol_info.point,
                    "tp": price_bid - 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            else:
                print("No signal to open a position")
                return None

            result = mt5.order_send(request)

            if result.retcode == mt5.TRADE_RETCODE_DONE:
                if signal[-1] < 0.5:
                    print("Buy position opened")
                    open_trades += 1
                elif signal[-1] > 0.5:
                    print("Sell position opened")
                    open_trades += 1
                return result.order
            else:
                print("Error: Trade request not executed, retcode={}. Attempt {}/{}".format(result.retcode, _ + 1, attempts))
                time.sleep(3)

        time.sleep(4000)

En esta función hemos añadido las variables probability_of_winning y optimal_volume. probability_of_winning almacenará la probabilidad de ganancia que hemos calculado como la distancia entre la previsión del modelo y 0.5, multiplicada por 2. Optimal_volume contendrá el tamaño óptimo de la apuesta calculado con la ayuda del criterio de Kelly.

En el bloque if daily_drop > 0.05: reduciremos optimal_volume un 10% en incrementos de 0,01 lotes. También hemos añadido una condición elif current_balance > peak_balance: que comprobará si el balance actual de la cuenta ha superado el nivel máximo anterior. De ser así, recalcularemos optimal_volume utilizando el balance actual y el ratio de ganancias/pérdidas, y actualizaremos peak_balance.

Este sistema de gestión de lotes de Kelly nos permitirá optimizar automáticamente el tamaño de la apuesta según la probabilidad de ganancia y el ratio de ganancias/pérdidas. Así podremos maximizar los beneficios y minimizar el riesgo de reducción.


Implementación de transacciones multidivisa y computación paralela

la operatividad multidivisa permite al algoritmo trabajar con varios pares de divisas a la vez, diversificando los riesgos. Se implementa a través de una lista con pares.

La computación paralela acelera las operaciones realizando tareas de forma simultánea. Se usará la biblioteca de threading: para cada par se creará un flujo independiente con la función process_symbol.

process_symbol descargará los datos de los pares, los transformará, entrenará el modelo XGBoost, lo probará y, a continuación, negociará online, actualizando los datos periódicamente.

De esta forma, se crearán flujo para todos los pares a partir de symbols. Cuando todos los flujos hayan terminado, el programa los esperará con ayuda de thread.join().

De este modo, se implementará un sistema comercial multiflujo multidivisa de alto rendimiento basado en XGBoost.

import threading

def process_symbol(symbol):
    try:
        # Retrieve data for the specified symbol
        raw_data = retrieve_data(symbol)
        if raw_data is None:
            print("Los datos para el símbolo {} no se han encontrado".format(symbol))
            return None

        # Augment data
        augmented_data = augment_data(raw_data)

        # Markup data
        marked_data = markup_data(augmented_data.copy(), 'close', 'label')

        # Label data
        labeled_data = label_data(marked_data, symbol)

        # Generate new features
        labeled_data_generate = generate_new_features(labeled_data, num_features=100, random_seed=1)

        # Cluster features by GMM
        labeled_data_clustered = cluster_features_by_gmm(labeled_data_generate, n_components=4)

        # Feature engineering
        labeled_data_engineered = feature_engineering(labeled_data_clustered, n_features_to_select=10)

        # Train XGBoost classifier
        train_data = labeled_data_engineered[labeled_data_engineered.index <= FORWARD]
        test_data = labeled_data_engineered[labeled_data_engineered.index > FORWARD]
        xgb_clf = train_xgboost_classifier(train_data, num_boost_rounds=1000)

        # Test XGBoost classifier
        test_features = test_data.drop(['label', 'labels'], axis=1)
        test_labels = test_data['labels']
        initial_balance = 10000.0
        markup = 0.00001
        test_model(xgb_clf, test_features, test_labels, markup, initial_balance)

        # Online trading
        position_id = None
        while True:
            # Get the last 2000 data points for online trading
            features = raw_data[-6000:].drop(['label', 'labels'], axis=1).values.tolist()

            # Update features every 6 seconds
            time.sleep(6)
            new_data = retrieve_data(symbol)
            if new_data is not None:
                raw_data = pd.concat([raw_data, new_data])
                raw_data = raw_data.dropna()

            # Online trading
            position_id = online_trading(symbol, features, xgb_clf, position_id)

    except Exception as e:
        print("Error al procesar el símbolo {}: {}".format(symbol, e))
        return None

symbols = ["EURUSD", "GBPUSD", "USDJPY", "AUDUSD", "USDCAD"]

# Create a list of threads for each symbol
threads = []
for symbol in symbols:
    thread = threading.Thread(target=process_symbol, args=(symbol,))
    thread.start()
    threads.append(thread)

# Wait for all threads to complete
for thread in threads:
    thread.join()

Después de ejecutar el código, nos encontraremos con el problema de la superposición de la muestra en la pantalla (impresiones) de diferentes flujos. Esto hace que la muestra resulte ilegible y dificulte la depuración y el control del rendimiento del algoritmo. A pesar de los numerosos intentos de resolver este problema, todavía no hay forma de evitar el solapamiento de la muestra.

Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31




No data for symbol USDCAD yet (attempt 1)No data for symbol NZDUSD yet (attempt 1)No data for symbol AUDUSD yet (attempt 1)
No data for symbol GBPUSD yet (attempt 1)


Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31



No data for symbol USDCAD yet (attempt 2)No data for symbol AUDUSD yet (attempt 2)No data for symbol GBPUSD yet (attempt 2)


Instruments in terminal: 31Instruments in terminal: 31

Instruments in terminal: 31
No data for symbol GBPUSD yet (attempt 3)
Instruments in terminal: 31

A pesar de este problema, el algoritmo en sí funciona correctamente y cumple sus funciones, pues procesa correctamente los datos, entrena el modelo y ejecuta la operación para cada par de divisas de la lista. La computación paralela puede aumentar considerablemente la velocidad del algoritmo y mejorar su eficacia.

Por ello, podemos ver que el algoritmo abre transacciones correctamente:



Posibles mejoras del sistema

Aprendizaje automático cuántico

Ahora mismo usamos el aprendizaje clásico de modelos, pero en el futuro planeamos pasar al aprendizaje automático cuántico utilizando cúbits para mejorar la precisión y la velocidad. A pesar de las dificultades actuales de las computadoras cuánticas, ya se están desarrollando programas y algoritmos especiales. Tengo previsto investigar e implantar el aprendizaje cuántico en nuestro sistema, lo cual podría suponer un gran avance.

Reacción del mercado: aprendizaje por refuerzo

Para mejorar el sistema comercial, podemos aplicar el aprendizaje por refuerzo. El sistema funcionará como un agente que interactuará con el mercado, recibiendo recompensas por las transacciones rentables y penalizaciones por las no rentables. Mediante algoritmos como DQN, el sistema aprenderá y se adaptará, mejorando las predicciones.

Inteligencia de enjambre para la elección de stops y takes

Para mejorar la eficiencia de nuestro sistema, podemos aplicar la inteligencia de enjambre usando el algoritmo de optimización de enjambre de partículas (PSO). Este sistema generará diferentes parámetros de stop y take, evaluando su eficacia sobre datos históricos. El PSO ayudará a seleccionar los parámetros óptimos, mejorando la adaptabilidad y reduciendo el riesgo.


Conclusión

Nuestro modelo de aprendizaje automático para el comercio usa el preprocesamiento de datos, el análisis de datos y algoritmos como XGBoost. Asimismo, se aplicará la adición de ruido, el desplazamiento temporal, el cálculo de características, el equilibrio de clases y la validación cruzada. La precisión ronda el 60% en los datos de prueba.

Tenemos previsto introducir la computación cuántica, el aprendizaje por refuerzo y la inteligencia de enjambre para la selección de stops y takes. Esto mejorará la calidad del entrenamiento, la eficacia sobre datos reales y la gestión de riesgos.

Pero hay una trampa: debido a estas tecnologías, se dará una competencia feroz entre algoritmos en el mercado. Los tráders solían competir entre sí, pero ahora todo girará en torno a qué algoritmo es más avanzado.


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

Herramientas econométricas para la previsión de la volatilidad: el modelo GARCH Herramientas econométricas para la previsión de la volatilidad: el modelo GARCH
El presente artículo describe las propiedades de un modelo de heteroscedasticidad condicional no lineal (GARCH). Sobre esta base se construye el indicador iGARCH para predecir la volatilidad un paso por delante. Para estimar los parámetros del modelo se usará la biblioteca de análisis numérico ALGLIB.
Estrategia de negociación de órdenes en cascada basada en cruces de EMA para MetaTrader 5 Estrategia de negociación de órdenes en cascada basada en cruces de EMA para MetaTrader 5
El artículo guía en la demostración de un algoritmo automatizado basado en cruces de EMA para MetaTrader 5. Información detallada sobre todos los aspectos de la demostración de un Asesor Experto en MQL5 y su prueba en MetaTrader 5, desde el análisis del comportamiento del rango de precios hasta la gestión de riesgos.
Optimización de carteras en Python y MQL5 Optimización de carteras en Python y MQL5
Este artículo explora técnicas avanzadas de optimización de cartera utilizando Python y MQL5 con MetaTrader 5. Demuestra cómo desarrollar algoritmos para el análisis de datos, la asignación de activos y la generación de señales comerciales, enfatizando la importancia de la toma de decisiones basada en datos en la gestión financiera moderna y la mitigación de riesgos.
Desarrollamos un asesor experto multidivisa (Parte 13): Automatización de la segunda fase: selección en grupos Desarrollamos un asesor experto multidivisa (Parte 13): Automatización de la segunda fase: selección en grupos
Ya hemos puesto en marcha la primera fase del proceso de optimización automatizada. Para distintos símbolos y marcos temporales, realizamos la optimización utilizando varios criterios y almacenamos información sobre los resultados de cada pasada en la base de datos. Ahora vamos a seleccionar los mejores grupos de conjuntos de parámetros de entre los encontrados en la primera etapa.