English Русский 中文 Deutsch 日本語
preview
Análisis de múltiples símbolos con Python y MQL5 (Parte II): Análisis de componentes principales para la optimización de carteras

Análisis de múltiples símbolos con Python y MQL5 (Parte II): Análisis de componentes principales para la optimización de carteras

MetaTrader 5Ejemplos |
133 0
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

Gestionar el riesgo total al que está expuesta una cartera es una tarea bastante desafiante para todos los miembros de nuestra comunidad comercial. Considerando la gran cantidad de oportunidades de inversión que se ofrecen al inversor moderno, ¿cómo puede alguien analizar y decidir exhaustivamente las asignaciones de activos adecuadas en el mundo actual de mercados en constante expansión? En nuestra última discusión, demostré cómo se podría maximizar el rendimiento total de la cartera utilizando SciPy. Hoy me centraré en cómo controlar el riesgo/varianza de cualquier cartera que pueda tener a mano. Hay muchos modelos posibles que podemos utilizar para controlar el riesgo de nuestra cartera. Podemos utilizar una herramienta popular de la estadística, el Análisis de Componentes Principales (Principal Components Analysis, PCA), para gestionar eficazmente la varianza total de nuestra cartera.

Para los miembros de nuestra comunidad que buscan vender Asesores Expertos, este artículo demostrará cómo pueden crear una experiencia perfecta para sus usuarios finales. Nuestra aplicación comercial será flexible y robusta al mismo tiempo. Le mostraré cómo crear aplicaciones comerciales que permitirán a sus clientes cambiar fácilmente entre modos comerciales de riesgo alto, medio y bajo. Mientras que el algoritmo PCA se encargará del trabajo pesado para los usuarios finales en segundo plano.


Descripción general de la metodología

En este artículo gestionaremos una cartera de 10 criptomonedas. Las criptomonedas son activos digitales que existen en un tipo especial de red conocida como red blockchain. La tecnología blockchain es un protocolo de seguridad que hace prácticamente imposible que cualquier miembro de la red realice transacciones fraudulentas. Por lo tanto, dada la solidez de la red subyacente, uno de los primeros usos populares de la tecnología blockchain fue la moneda digital. Sin embargo, estos activos digitales son conocidos por su gran volatilidad, y a los inversores les puede resultar difícil gestionar adecuadamente sus niveles de riesgo al invertir en criptoactivos. Afortunadamente, podemos utilizar métodos estadísticos como el PCA para gestionar la cantidad total de varianza a la que deseamos exponernos al invertir en criptomonedas.
El análisis de componentes principales es una técnica que proviene de una rama de la estadística multivariante llamada análisis factorial. El PCA se utiliza en muchos ámbitos, desde el análisis de imágenes hasta el aprendizaje automático. En el análisis de imágenes, el PCA se utiliza habitualmente para tareas como la compresión de datos, mientras que en el aprendizaje automático se emplea con mayor frecuencia para la reducción de la dimensionalidad.

La idea del PCA es encontrar un valor de coeficiente para cada columna del conjunto de datos. Si cada columna se multiplica por su coeficiente, las nuevas columnas que obtendremos deberían maximizar la varianza del conjunto de datos. Si hemos completado con éxito este procedimiento, habremos encontrado con éxito el primer componente principal.
El segundo componente principal será ortogonal al primero, lo que significa que no estarán correlacionados entre sí, al tiempo que maximizan la varianza total del conjunto de datos. Este patrón continúa hasta que hayamos creado suficientes componentes para explicar toda la varianza del conjunto de datos original.

Le mostraré cómo cada componente principal se asigna individualmente a niveles de riesgo discretos que podemos utilizar como ajustes para nuestras aplicaciones de trading. Esto le ayudará a gestionar de forma inteligente sus ajustes de riesgo en cuestión de minutos.


Primeros pasos

Creo que una demostración visual del funcionamiento del algoritmo sería muy útil para los lectores que se enfrentan al algoritmo por primera vez. Tomaré la imagen del logotipo de MQL5 de la figura 1 y primero la convertiré a blanco y negro. Este filtro en blanco y negro nos facilitará la aplicación y nos permitirá ver visualmente lo que el algoritmo PCA está haciendo con nuestros datos.

Fig. 1: Utilizaremos el logotipo de MQL5 que aparece arriba para demostrar el funcionamiento del algoritmo PCA.

Ahora que tenemos una imagen con la que trabajar, carguemos nuestras bibliotecas de Python.

#Let's go
import pandas as pd
import numpy  as np
import MetaTrader5 as mt5
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from skimage import io, color

Lea la imagen y conviértala a blanco y negro.

# Load and preprocess the image
image = io.imread('mql5.png')  # Replace with your image path
image_gray = image_gray = color.rgb2gray(image)   # Convert to grayscale

Aplana la imagen a dos dimensiones y aplica el PCA apuntando a cinco niveles de componentes diferentes. La imagen original se encuentra en el extremo izquierdo de la figura 2. El primer componente principal maximiza la varianza de los datos de entrada. Como podemos ver en la imagen titulada «1 Components», la estructura general de la imagen original se conserva en cierta medida. Aunque el texto «MQL5» en el centro de la imagen ya no es legible, podemos deducir razonablemente a partir de la imagen que hay un fondo negro con una estructura blanca en el centro.

Cuando se utilizan 5 componentes principales, el texto de la imagen es legible. Sin embargo, se pierden detalles finos como los iconos de color gris claro que se integran en el fondo y es necesario recuperar más componentes.

Este ejercicio debería proporcionarle una comprensión intuitiva de que el algoritmo PCA intenta crear representaciones compactas y no correlacionadas de los datos de entrada originales. Esta tarea se logra creando combinaciones lineales sucesivas de los datos de entrada que maximizan la varianza de los datos de entrada.

# Flatten the image
h, w = image_gray.shape
image_flattened = image_gray.reshape(h, w)

# Apply PCA with different numbers of components
n_components_list = [1,5,20,50,100]  # Number of components to keep

fig, axes = plt.subplots(1, len(n_components_list) + 1, figsize=(20, 10))
axes[0].imshow(image_gray, cmap='gray')
axes[0].set_title("Original Image")
axes[0].axis('off')

for i, n_components in enumerate(n_components_list):
        # Initialize PCA and transform the flattened image
        pca = PCA(n_components=n_components)
        pca.fit(image_flattened)
    
        # Transform and inverse transform the image
        transformed_image = pca.transform(image_flattened)
        reconstructed_image = pca.inverse_transform(transformed_image).reshape(h, w)
    
        # Plot the reconstructed image
        axes[i + 1].imshow(reconstructed_image, cmap='gray')
        axes[i + 1].set_title(f"{n_components} Components")
        axes[i + 1].axis('off')

plt.tight_layout()
plt.show()

Fig. 2: Los dos primeros componentes principales, que resumen nuestro logotipo MQL5.

Fig. 3: Los tres últimos componentes principales, que resumen nuestro logotipo MQL5.

En lugar de una imagen, nos interesa más maximizar o minimizar la varianza de una cartera. Podemos lograrlo pasando un conjunto de datos que contenga los rendimientos de cada activo de la cartera a nuestro algoritmo PCA.


Obtención de nuestros datos de mercado

Para empezar, primero debemos asegurarnos de que nuestra terminal MetaTrader 5 esté activa.

mt5.initialize()
True

Ahora enumera todos los activos que mantendremos en nuestra cartera.

#List of cryptocurrencies we wish to invest
crypto = [
                "BCHUSD", #BitcoinCash
                "EOSUSD", #EOS
                "BTCUSD", #Bitcoin
                "ETHUSD", #Etherum
                "ADAUSD", #Cardano
                "XRPUSD", #Ripple
                "UNIUSD", #Monero
                "DOGUSD", #Dogecoin
                "LTCUSD", #Litecoin
                "SOLUSD"  #Solana
]

Queremos obtener los datos diarios del mercado de los últimos 6 años.

fetch = 365 * 6

Nuestro modelo realizará previsiones para los próximos 30 días.

look_ahead = 30

Crear el marco de datos que almacenará los rendimientos de nuestras criptomonedas.

data = pd.DataFrame(columns=crypto,index=range(fetch))

Obtener las cotizaciones de mercado para cada uno de los símbolos que tenemos en nuestra lista.

for i in range(0,len(crypto)):
        data[crypto[i]]         = pd.DataFrame(mt5.copy_rates_from_pos(crypto[i],mt5.TIMEFRAME_M1,0,fetch)).loc[:,"close"]

Obtener las cotizaciones de mercado para cada uno de los símbolos que tenemos en nuestra lista.

Datos

Fig. 4: Visualización de algunos de los datos de mercado que hemos recopilado, con el registro de seis años de precios históricos de una serie de criptomonedas.


Análisis exploratorio de datos

El comercio de criptomonedas puede ser complicado porque los valores son muy volátiles. La figura 5 nos ayuda a visualizar el rendimiento de una cesta de 10 criptomonedas durante un periodo de seis años, desde 2018 hasta 2024. El diferencial (spread) entre los activos evoluciona y puede que no resulte intuitivo para un ser humano calcularlo o utilizarlo de manera eficaz.

data_plotting = data.iloc[:,:]/data.iloc[0,:]
sns.lineplot(data_plotting)

Fig. 5: El rendimiento de 10 criptomonedas diferentes en las que podríamos haber invertido.

El riesgo que introduce cada criptomoneda en nuestra cartera puede visualizarse como la desviación estándar móvil de los rendimientos de cada símbolo. En la figura 6 podemos observar que los periodos de alta volatilidad parecen agruparse. Sin embargo, algunos mercados muestran un comportamiento más volátil que otros.

plt.plot(data_plotting.iloc[:,0].rolling(14).std())
plt.plot(data_plotting.iloc[:,1].rolling(14).std())
plt.plot(data_plotting.iloc[:,2].rolling(14).std())
plt.plot(data_plotting.iloc[:,3].rolling(14).std())
plt.plot(data_plotting.iloc[:,4].rolling(14).std())
plt.plot(data_plotting.iloc[:,5].rolling(14).std())
plt.plot(data_plotting.iloc[:,6].rolling(14).std())
plt.plot(data_plotting.iloc[:,7].rolling(14).std())
plt.plot(data_plotting.iloc[:,8].rolling(14).std())
plt.plot(data_plotting.iloc[:,9].rolling(14).std())
plt.legend(crypto)
plt.title("The Risk Associated With Each of our Cryptocurrencies")
plt.xlabel("Time")
plt.ylabel("Standard Deviation") 

Fig. 6: La desviación estándar de cada criptomoneda en nuestra cartera.

El algoritmo PCA nos ayudará a minimizar o maximizar intencionadamente nuestra exposición a la varianza total de la cartera que se visualiza en la figura 6. Intentar decidir manualmente qué activos maximizarán la varianza de nuestra cartera, dado que hay 10 activos, podría resultar imposible para un ser humano sin ayuda.

Es de esperar que se observen fuertes niveles de correlación cuando analizamos activos de la misma clase de activos. Especialmente interesantes son los niveles de correlación entre:
  1. EOSUSD y XRPUSD
  2. DOGUSD y BCHUSD

Estos pares muestran niveles de correlación casi perfectos a lo largo de 6 años de cotizaciones diarias del mercado. Esta podría ser una relación que nuestro modelo podría utilizar de manera eficaz, y que valdría la pena explorar en diferentes circunstancias.
#Correlation analysis
sns.heatmap(data.corr(),annot=True)

Fig. 7: Visualización de los niveles de correlación en nuestra cartera de 10 criptomonedas.

Calcula la variación en los niveles de precios durante dos semanas.

#Calculate the change over 2 weeks
data = data.diff(14).dropna().reset_index(drop=True)

Ahora coloque el escalador.

scaler = RobustScaler()
scaled_data = pd.DataFrame(scaler.fit_transform(data), columns=data.columns)

Ajustar el objeto PCA de Scikit learn a nuestros rendimientos diarios del mercado.

pca = PCA()
pca.fit(scaled_data)

Analicemos ahora el primer componente principal. El signo del coeficiente nos indica si debemos ocupar posiciones largas o cortas en cada mercado. Los coeficientes positivos nos indican que debemos operar en largo plazo, y los coeficientes negativos nos indican que debemos operar en corto plazo. Por lo tanto, para maximizar la varianza de nuestra cartera, el algoritmo PCA sugiere operar en corto en todos los mercados que hemos seleccionado.

Para los traders que buscan desarrollar estrategias de scalping, este primer componente principal es el camino a seguir.

#High risk strategy
pca.components_[0]
array([-0.31760842, -0.32146743, -0.35867192, -0.35797826, -0.28276975, -0.36658864, -0.2954465 , -0.19875535, -0.32278201, -0.30604428])

Además, cada componente también nos proporciona ratios óptimos de asignación de capital que maximizarán o minimizarán la varianza en consecuencia. Sin embargo, para obtener esta información, debemos aplicar algunas transformaciones al componente.

Dividiremos el componente por su Norma L1. La Norma L1 es la suma de los valores absolutos en el componente. Dividiendo cada puntuación de carga principal por su suma total, sabremos las proporciones óptimas que debemos asignar a cada activo para maximizar la varianza de nuestra cartera.

Después de calcular la proporción de cada criptomoneda en el componente, podemos multiplicar el ratio de asignación de activos por el número de posiciones que queremos abrir, para obtener una aproximación de cuántas posiciones debemos abrir en cada mercado. Calculamos la suma para demostrar que las posiciones totales sumarán 100 si multiplicamos el índice de asignación de activos por 100.

#High risk asset allocations can be estimated from the first principal component
high_risk_asset_allocation = pca.components_[0] / np.linalg.norm(pca.components_[0],1)
np.sum(high_risk_asset_allocation * 100)
-100

Por ejemplo, si quisiéramos abrir 10 posiciones siguiendo la estrategia de alto riesgo, nuestro componente principal sugiere que vendamos 1 posición en BCHUSD (Bitcoin Cash). La parte decimal del coeficiente se puede interpretar como una posición de un tamaño de lote ligeramente menor. Pero puede resultar que considerarlo con precisión en nuestra cartera consuma mucho tiempo. Quizás sea más sencillo confiar en la parte numérica completa de la asignación.

high_risk_asset_allocation * 10
array([-1.01533565, -1.02767219, -1.1466081 , -1.14439061, -0.90396285,-1.17191639, -0.94448806, -0.63538425, -1.03187466, -0.97836721])

Pasemos ahora a los componentes principales de riesgo medio.

#Mid risk strategy
pca.components_[len(crypto)//2]
array([-0.00530455,  0.16374242,  0.03976866, -0.19508115,  0.75650629,0.08559565, -0.51882352, -0.15840483, -0.23524968,  0.06543203])

Y, por último, nuestros componentes principales de bajo riesgo sugieren una estrategia comercial completamente diferente.

#Low risk strategy
pca.components_[len(crypto)-1]
array([-0.03520096,  0.37157999, -0.41562007,  0.74700647, -0.06764155,-0.15451366, -0.28321595, -0.01342945, -0.09973515, -0.10555529])

Guardemos estos componentes principales en un archivo de texto, para que podamos utilizar los resultados en nuestra aplicación de trading MetaTrader 5.

np.savetxt("LOW RISK COMPONENTS.txt",pca.components_[len(crypto)-1])
np.savetxt("MID RISK COMPONENTS.txt",pca.components_[len(crypto)//2])
np.savetxt("HIGH RISK COMPONENTS.txt",pca.components_[0])


Implementación en MQL5

Ya estamos listos para comenzar a implementar nuestra aplicación de trading en MetaTrader 5.
Nuestra aplicación comercial buscará seguir los hallazgos de nuestras asignaciones óptimas de activos. Abriremos solo 1 operación en cada mercado de acuerdo con la configuración de riesgo actual que haya seleccionado el usuario. La aplicación comercial cronometrará sus entradas utilizando el promedio móvil y el oscilador estocástico.

Si el componente principal sugiere que entremos en posiciones largas en el mercado, esperaremos a que los niveles de precios suban por encima de la lectura del promedio móvil en ese mercado y a que el Oscilador Estocástico esté por encima de 50. Una vez que se cumplan ambas condiciones, tomaremos nuestra posición larga y, en consecuencia, estableceremos nuestros niveles de take profit y stop loss utilizando el ATR. Esperamos que al programar nuestras entradas al mercado de esta manera obtengamos señales de entrada más estables y consistentes a lo largo del tiempo.

Para comenzar, primero definiremos el enumerador personalizado que le brinda a nuestro usuario final control sobre los parámetros de riesgo de nuestra aplicación comercial.

//+------------------------------------------------------------------+
//|                               PCA For Portfolio Optimization.mq5 |
//|                                        Gamuchirai Zororo Ndawana |
//|                          https://www.mql5.com/en/gamuchiraindawa |
//+------------------------------------------------------------------+
#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com/en/gamuchiraindawa"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Custom enumerations                                              |
//+------------------------------------------------------------------+
enum risk_level
  {
   High=0,
   Mid=1,
   Low=2
  };

Cargue las bibliotecas que necesitamos.

//+------------------------------------------------------------------+
//| Libraries                                                        |
//+------------------------------------------------------------------+
#include  <Trade\Trade.mqh>
CTrade Trade;

Define valores constantes que no cambiarán en ningún momento.

//+------------------------------------------------------------------+
//| Constants values                                                 |
//+------------------------------------------------------------------+
const double high_risk_components[] = {#include "HIGH RISK COMPONENTS.txt"};
const double mid_risk_components[]  = {#include "MID RISK COMPONENTS.txt"};
const double low_risk_components[]  = {#include "LOW RISK COMPONENTS.txt"};
const string crypto[]               = {"BCHUSD","EOSUSD","BTCUSD","ETHUSD","ADAUSD","XRPUSD","UNIUSD","DOGUSD","LTCUSD","SOLUSD"};

Nuestras variables globales que utilizaremos a lo largo de nuestro programa.

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
double current_risk_settings[];
double vol,bid,ask;
int    atr_handler;
int    stoch_handler;
int    ma_handler;
double atr_reading[],ma_reading[],stoch_reading[];

Permitiremos al usuario final controlar dinámicamente la configuración de riesgo de la cuenta comercial y el tamaño de lote deseado.

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
input group "Risk Levels"
input risk_level user_risk = High; //Which risk level should we use?

input group "Money Management"
input int lot_multiple     = 1;    //How big should out lot size be?

Cuando se carga nuestra aplicación comercial, primero cargaremos nuestros componentes principales de acuerdo con la configuración de riesgo que el usuario haya seleccionado. Todo esto lo gestionará la función "setup".

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Setup our market data
   setup();

//---
   return(INIT_SUCCEEDED);
  }

Si ya no utilizamos el Asesor Experto, liberemos los recursos que no estamos utilizando.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Release the indicators
   IndicatorRelease(atr_handler);
   IndicatorRelease(ma_handler);
   IndicatorRelease(stoch_handler);
  }

Por último, cada vez que recibamos precios actualizados, mantengamos una cartera de 1 posición en cada mercado de criptomonedas. La posición que ocuparemos vendrá determinada por la configuración de riesgo que haya seleccionado el usuario. Dependiendo de la configuración de riesgo, puede que necesitemos ocupar una posición “buy” o “sell” para controlar la varianza en la cartera.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Ensure we always have 10 positions
   if(PositionsTotal() < 10)
     {
      //--- Let's see which market we aren't in
      for(int i = 0; i < 10; i++)
        {
         //--- Check if we can now enter that market
         if(!PositionSelect(crypto[i]))
           {
            check_setup(i);
           }
        }
     }
  }

La función de configuración determinará qué configuración de riesgo ha seleccionado el usuario final y luego cargará el componente principal correspondiente.

//+------------------------------------------------------------------+
//| Setup our market data                                            |
//+------------------------------------------------------------------+
void setup(void)
  {
//--- First let us define the current risk settings
   switch(user_risk)
     {
      //--- The user selected high risk
      case 0:
        {
         ArrayCopy(current_risk_settings,high_risk_components,0,0,WHOLE_ARRAY);
         Comment("EA in high risk mode");
         break;
        }
      //--- The user selected mid risk
      case 1:
        {
         ArrayCopy(current_risk_settings,mid_risk_components,0,0,WHOLE_ARRAY);
         Comment("EA in mid risk mode");
         break;
        }
      //--- The user selected low risk
      //--- Low risk is also the default setting for safety!
      default:
        {
         ArrayCopy(current_risk_settings,low_risk_components,0,0,WHOLE_ARRAY);
         Comment("EA in low risk mode");
         break;
        }
     }
  }

Dado que negociamos activamente 10 símbolos diferentes, necesitamos una función responsable de obtener datos de mercado relacionados con cada símbolo. La función "update" definida a continuación se encargará de esta tarea por nosotros. Cada vez que se llama a la función, cargará en la memoria el precio de oferta y demanda actual junto con otras lecturas de indicadores técnicos que se calculan a partir del mercado especificado. Una vez que hayamos utilizado los datos y decidido qué acción tomar, la función cargará los datos de mercado del próximo símbolo en la memoria.

//+------------------------------------------------------------------+
//| Update our system varaibles                                      |
//+------------------------------------------------------------------+
void update(string market)
  {
//--- Get current prices
   bid = SymbolInfoDouble(market,SYMBOL_BID);
   ask = SymbolInfoDouble(market,SYMBOL_ASK);
//--- Get current technical readings
   atr_handler   = iATR(market,PERIOD_CURRENT,14);
   stoch_handler = iStochastic(market,PERIOD_CURRENT,5,3,3,MODE_EMA,STO_CLOSECLOSE);
   ma_handler    = iMA(market,PERIOD_CURRENT,30,0,MODE_EMA,PRICE_CLOSE);
//--- Copy buffer
   CopyBuffer(atr_handler,0,0,1,atr_reading);
   CopyBuffer(ma_handler,0,0,1,ma_reading);
   CopyBuffer(stoch_handler,0,0,1,stoch_reading);
//---
  }

Por último, necesitamos una función que verifique si podemos abrir una posición alineada con la configuración de riesgo actual que el usuario ha especificado. De lo contrario, si no podemos, le daremos al usuario final una explicación significativa de por qué no podemos abrir una posición en ese mercado.

//+------------------------------------------------------------------+
//| Open a position if we can                                        |
//+------------------------------------------------------------------+
void check_setup(int idx)
  {
//--- The function takes the index of the symbol as its only parameter
//--- It will look up the principal component loading of the symbol to determine whether it should buy or sell
   update(crypto[idx]);
   vol = lot_multiple * SymbolInfoDouble(crypto[idx],SYMBOL_VOLUME_MIN);

   if(current_risk_settings[idx] > 0)
     {
      if((iClose(crypto[idx],PERIOD_D1,0) > ma_reading[0]) && (stoch_reading[0] > 50))
        {
         Comment("Analyzing: ",crypto[idx],"\nMA: ",ma_reading[0],"\nStoch: ",stoch_reading[0],"\nAction: Buy");
         Trade.Buy(vol,crypto[idx],ask,(ask - (atr_reading[0] * 3)),(ask + (atr_reading[0] * 3)),"PCA Risk Optimization");
         return;
        }
      else
        {
         Comment("Waiting for an oppurtunity to BUY: ",crypto[idx]);
        }
     }

   else
      if(current_risk_settings[idx] < 0)
        {

         if((iClose(crypto[idx],PERIOD_D1,0) < ma_reading[0]) && (stoch_reading[0] < 50))
           {
            Comment("Analyzing: ",crypto[idx],"\nClose: ","\nMA: ",ma_reading[0],"\nStoch: ",stoch_reading[0],"\nAction: Sell");
            Trade.Sell(vol,crypto[idx],bid,(bid + (atr_reading[0] * 3)),(bid - (atr_reading[0] * 3)),"PCA Risk Optimization");
            return;
           }

         else
           {
            Comment("Waiting for an oppurtunity to SELL: ",crypto[idx]);
            return;
           }
        }
   Comment("Analyzing: ",crypto[idx],"\nMA: ",ma_reading[0],"\nStoch: ",stoch_reading[0],"\nAction: None");
   return;
  };
//+------------------------------------------------------------------+

Fig. 8: Visualización de nuestro asesor experto en MetaTrader 5.

Fig. 9: Ajuste de los parámetros de riesgo de nuestra aplicación de trading.

Fig. 10: Nuestra aplicación comercial se prueba en tiempo real con datos reales del mercado.



Conclusión

El PCA normalmente se considera un tema algo complicado, debido a la notación matemática requerida para aprender el concepto. Sin embargo, este artículo le ha mostrado cómo utilizar PCA de una manera fácil de usar, para que pueda comenzar a aplicarlo hoy mismo incluso si es la primera vez que aprende sobre el tema.

Gestionar el riesgo en la asignación de tu cartera no es una tarea sencilla, las herramientas y modelos matemáticos son la mejor forma de medir y gestionar el riesgo al que estás expuesto en los mercados financieros. Especialmente cuando el número de mercados en los que desea participar aumenta.

Ya sea que tengamos 10 símbolos o 100 símbolos, PCA siempre nos mostrará qué combinaciones maximizarán el riesgo en la cartera y qué combinaciones minimizarán el riesgo de nuestra cartera.

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

Redes neuronales en el trading: Framework comercial híbrido con codificación predictiva (Final) Redes neuronales en el trading: Framework comercial híbrido con codificación predictiva (Final)
Continuamos nuestro análisis del sistema comercial híbrido StockFormer, que combina codificación predictiva y algoritmos de aprendizaje por refuerzo para el análisis de series temporales financieras. El sistema se basa en tres ramas del Transformer con un mecanismo Diversified Multi-Head Attention (DMH-Attn) que permite identificar patrones complejos y relaciones entre activos. Ya nos hemos familiarizado con los aspectos teóricos del framework e implementado los mecanismos de DMH-Attn, así que hoy hablaremos sobre la arquitectura de los modelos y su entrenamiento.
Algoritmo de agujero negro — Black Hole Algorithm (BHA) Algoritmo de agujero negro — Black Hole Algorithm (BHA)
El algoritmo de agujero negro (BHA) utiliza los principios de la gravedad de los agujeros negros para optimizar las soluciones. En este artículo, analizaremos cómo el BHA atrae las mejores soluciones evitando los extremos locales, y por qué este algoritmo se ha convertido en una poderosa herramienta para resolver problemas complejos. Descubra cómo ideas sencillas pueden dar lugar a resultados impresionantes en el mundo de la optimización.
Operar con noticias de manera sencilla (Parte 5): Ejecución de operaciones (II) Operar con noticias de manera sencilla (Parte 5): Ejecución de operaciones (II)
Este artículo ampliará la clase de gestión de operaciones para incluir órdenes de compra y venta con límite (buy-stop y sell-stop) con el fin de operar con eventos de noticias e implementar una restricción de vencimiento en estas órdenes para evitar cualquier operación nocturna. Se incorporará una función de deslizamiento (slippage) al experto para intentar prevenir o minimizar el posible deslizamiento que puede producirse al utilizar órdenes stop en las operaciones, especialmente durante eventos noticiosos.
Asesores Expertos Auto-Optimizables con MQL5 y Python (Parte VI): Cómo aprovechar el doble descenso profundo Asesores Expertos Auto-Optimizables con MQL5 y Python (Parte VI): Cómo aprovechar el doble descenso profundo
El aprendizaje automático tradicional enseña a los profesionales a estar atentos para no sobreajustar sus modelos. Sin embargo, esta ideología está siendo cuestionada por nuevos hallazgos publicados por diligentes investigadores de Harvard, quienes han descubierto que lo que parece ser un sobreajuste puede, en algunas circunstancias, ser el resultado de finalizar prematuramente los procedimientos de entrenamiento. Demostraremos cómo podemos utilizar las ideas publicadas en el artículo de investigación para mejorar nuestro uso de la IA en la previsión de retornos del mercado.