English Русский 한국어 Italiano Türkçe
preview
Visualisation 3D sans bibliothèques externes : comment MetaTrader 5 révèle les résultats d’optimisation avec MQL5 et DirectX 11

Visualisation 3D sans bibliothèques externes : comment MetaTrader 5 révèle les résultats d’optimisation avec MQL5 et DirectX 11

MetaTrader 5Exemples |
19 3
MetaQuotes
MetaQuotes

D'une belle image à un outil fonctionnel

Lorsque le nombre de paramètres de stratégie dépasse dix et que le rapport du Testeur de Stratégie se transforme en un tableau de plusieurs pages contenant des séries numériques, les traders et les développeurs sont confrontés à un problème : le signal utile se perd dans le bruit. Les graphiques plats et les cartes thermiques bidimensionnelles sont efficaces jusqu'à un certain point. Mais au-delà, le cerveau humain se heurte inévitablement à la multidimensionnalité des données. Nous essayons de garder à l'esprit la corrélation entre la période de l'indicateur, le stop-loss, la volatilité et le drawdown maximal. Mais la charge cognitive augmente plus vite que l'utilité de l'information. 

La visualisation 3D et les interfaces interactives de MetaTrader 5 ne sont pas une tentative de transformer le terminal de trading en un moteur de jeu. Il s’agit d’une technique visant à réduire la friction cognitive. Une surface 3D, où la hauteur correspond à la valeur attendue et le dégradé de couleur reflète la robustesse face aux drawdowns, nous permet de mettre en évidence le « plateau de stabilité » et de repérer et écarter les pics étroits typiques du sur-ajustement en quelques secondes. Ce qui nécessite des heures de comparaison sous forme de tableau se lit comme un motif dans l'espace tridimensionnel : pentes planes, changements d'altitude, plateaux/pics étroits en aiguille et zones de contraste.

MetaTrader 5 fournit une base technologique prête à l'emploi pour cette tâche. La prise en charge native de DirectX 11, le pipeline de shaders intégré ainsi que les classes CDXCanvas / CChartObjectDX sont directement intégrés dans l'environnement MQL5. Le développeur n'a pas besoin de connecter des bibliothèques graphiques externes, d'écrire des wrappers en C++ ou de gérer des dépendances : le cycle complet, de la création du périphérique à la sortie de l'image, est accessible via l'API 3D standard, et le chargement des shaders et des textures fonctionne directement à partir du dossier Files\DX\.

Dans cet article, nous allons détailler comment transformer les tableaux de résultats d'optimisation, les volumes de clusters et les modèles de scénarios en paysages 3D exploitables. Nous définirons les critères de pertinence : quand les graphiques 3D ajoutent des capacités d’analyse du signal et quand ils génèrent du bruit visuel. Nous passerons ensuite à l'architecture du pipeline DX, en examinant l'initialisation, la liaison des métriques aux buffers de sommets, les mécanismes de la caméra et les panneaux d'interface utilisateur, et enfin en évaluant les limitations technologiques de l'environnement.

Texte vs 3D

Fig. 1 : texte vs. visualisation

Quand la 3D et l'interactivité sont vraiment utiles

Un trader et un développeur de stratégies disposent d'un outil puissant, mais souvent sous-estimé, dans leur arsenal : la perception visuelle. Les tableaux de rapports, les listes de métriques et les graphiques 2D permettent de bien documenter les résultats. Mais lorsqu'il s'agit de comprendre des relations complexes, le cerveau humain passe à un autre mode d’analyse : il recherche des schémas sous forme d'images, de volume et de contexte. C’est là que la visualisation 3D et l’interactivité cessent d’être un simple élément décoratif et deviennent un outil d’analyse.

L'ajout d'un troisième axe se justifie lorsqu'il existe une hypothèse analytique claire dans les données. Par exemple, la dépendance de la valeur attendue à l'égard de deux paramètres clés du système à un niveau de risque fixe. Dans ce cas, la surface 3D transforme les coordonnées abstraites en un terrain, où les « montagnes » vertes indiquent des zones de profit stable et les « creux » rouges indiquent des drawdowns. La représentation 3D agit comme un filtre : elle élimine le bruit et ne laisse subsister que les combinaisons significatives.

Non pas pour des raisons esthétiques, mais pour des raisons analytiques.

Il ne s'agit pas de graphismes décoratifs, mais de couches visuelles qui révèlent directement ce qui est caché dans les lignes du rapport d’optimisation. Un tableau plat répond à la question : « Quel est le résultat de cette combinaison de paramètres ? »

Une surface 3D répond à la question : « Comment le résultat évolue-t-il en fonction des variations progressives de deux paramètres, et où se situent les zones de stabilité ? » Il s'agit d'un niveau d'analyse stratégique fondamentalement différent. La stabilité du résultat lorsque le contexte externe change est l'objectif principal à atteindre lors du test de toute idée de stratégie. Tout le reste est secondaire.

Il existe au moins trois scénarios où la visualisation 3D offre un avantage :

1. Paysage d'optimisation

Imaginez que vous sélectionniez deux paramètres : la période de la moyenne mobile et la taille du stop loss. Le tableau comporte 100 lignes avec les valeurs de Profit et de Drawdown. Sur une surface 3D présentant un dégradé de couleurs, vous verrez instantanément :

  • les plateaux de robustesse sont de vastes zones vertes où la stratégie est constamment rentable même avec des paramètres variables
  • les pics aigus sont des maxima locaux étroits qui sont souvent le signe d'un sur-ajustement
  • les pentes abruptes sont des zones où une petite modification d'un paramètre entraîne une forte augmentation du drawdown

Cette surface 3D permet de prendre des décisions éclairées quant au choix d'un ensemble de paramètres, non pas en fonction du profit maximal, mais de la robustesse.

2. Les conditions de marché en tant qu'espace multidimensionnel

Le regroupement des régimes de marché (tendance, phase latérale, volatilité accrue) nécessite souvent l'analyse simultanée de plus de trois indicateurs. Ici, la visualisation 3D permet de :

  • représenter chaque état du marché comme un point dans l'espace des variables
  • coder par couleur l'efficacité de la stratégie dans ce mode (ce point)
  • faire pivoter interactivement le nuage de points pour révéler des groupements cachés

Ceci est particulièrement pratique lors du paramétrage adaptatif : vous pouvez voir dans quelles conditions la stratégie échoue et dans quelles conditions elle fonctionne de manière robuste.

3. Modélisation de scénarios et tests de résistance

Lors de l'exécution de la stratégie sur divers scénarios synthétiques (méthode de Monte Carlo, génération de trajectoires de prix, ou encore des hypothèses du type : « que se passe-t-il si la volatilité augmente de 30 % ? »), la 3e dimension peut afficher :

  • axe X — paramètre de stratégie
  • axe Y – niveau de stress du marché (volatilité, écarts)
  • axe Z / couleur — métrique finale (facteur de récupération, valeur attendue)

Par conséquent, nous n'observons pas seulement un scénario catastrophe, mais bien les limites de la robustesse de la stratégie face à la détérioration des conditions de marché.

Critères de sélection : quand la 3D est excessive

Établissons une règle : La visualisation 3D se justifie lorsque vous étudiez la dépendance d'un résultat par rapport à deux variables continues ou plus et qu'il est important pour vous de visualiser la géométrie de cette dépendance.

Si vous êtes prêt à remplacer des heures passées à éplucher des rapports par une analyse visuelle intuitive, commençons par le pipeline de rendu.


Pipeline DX de base en MQL5 : de l'initialisation à la première image

La création de graphismes 3D dans MetaTrader 5 est un processus séquentiel, où chaque étape a son propre objectif. Comprendre l'architecture des objets DirectX et la boucle de rendu nous permet d'éviter les pièges courants, tels que les fuites de mémoire, les effets de clignotement et la dégradation des performances lors du traitement de grandes quantités de données.

Architecture objet DirectX en MQL5

La base des graphismes 3D en MQL5 est la classe CCanvas3D, qui encapsule toute la complexité du fonctionnement avec DirectX 11. Elle fournit une API de haut niveau au développeur, masquant les détails de bas niveau liés à la création de périphériques, de contextes et de buffers.

Hiérarchie des objets :

  • CCanvas3D — une classe qui gère la scène, la caméra et le rendu
  • CDXMesh et ses descendants (CDXBox, CDXSphere, CDXTorus) — objets géométriques
  • DXVertex — structure de sommet contenant les coordonnées, les normales, les coordonnées de texture et la couleur
struct DXVertex
  {
   DXVector4  position;   // vertex coordinates
   DXVector4  normal;     // normal vector
   DXVector2  tcoord;     // texture coordinates
   DXColor    vcolor;     // color
  };

Cette structure est compatible avec le shader de vertex standard, éliminant ainsi le besoin d'écrire des shaders personnalisés pour les tâches de base. Pour les projets complexes, nous recommandons d'utiliser les méthodes et utilitaires présentés dans le fichier MQL5\Include\Canvas\DX\DXUtils.mqh.

Diagramme hiérarchique

Fig. 2 : hiérarchie des graphismes 3D en MQL5

Toutes les ressources (shaders, textures, buffers) sont gérées via DXDispatcher. Chaque objet créé doit être explicitement détruit via Destroy() ou Shutdown() dans le destructeur. MetaTrader 5 ne dispose pas de garbage collector pour les ressources DirectX, et les fuites de mémoire s'accumulent jusqu'au redémarrage du terminal.


Initialisation du pipeline

La première étape consiste à créer un canevas et à configurer la matrice de projection :

//+------------------------------------------------------------------+
//+ canvas creation and projection matrix setup                      |
//+------------------------------------------------------------------+
virtual bool Create(const int width, const int height)
  {
//--- save canvas dimensions
   m_width = width;
   m_height = height;
   
//--- create a canvas to render a 3D scene
   ResetLastError();
   if(!m_canvas.CreateBitmapLabel("3D Sample_1", 0, 0, m_width, m_height, COLOR_FORMAT_ARGB_NORMALIZE))
     {
      Print("Error creating canvas: ", GetLastError());
      return(false);
     }
   
//--- set the projection matrix parameters
   m_canvas.ProjectionMatrixSet((float)M_PI/6, (float)m_width/m_height, 0.1f, 100.0f);
   
//--- create a 3D object
   if(!m_box.Create(m_canvas.DXDispatcher(), m_canvas.InputScene(),DXVector3(-1.0, -1.0, -1.0), DXVector3(1.0, 1.0, 1.0)))
     {
      m_canvas.Destroy();
      return(false);
     }
   
//--- add a cube to the scene
   m_canvas.ObjectAdd(&m_box);
   
   Redraw();
   return(true);
  }

Principaux paramètres de projection :

  • le champ de vision (« Field of View » ou FOV) - 30 degrés (M_PI/6), équilibre entre perspective et distorsion
  • le rapport d'aspect — le rapport entre la largeur et la hauteur (m_largeur/m_hauteur), le préserver empêche l'étirement en hauteur/largeur
  • Les plans de découpage sont de 0,1f (le plus proche) et de 100,0f (le plus éloigné) ; les objets situés en dehors de ces limites ne sont pas rendus

Ces paramètres définissent la pyramide de visibilité : seuls les objets situés entre deux murs virtuels et dans l’angle de vision horizontal sont inclus dans la matrice de projection.

Compilation des shaders - pour les primitives standard, les shaders sont compilés automatiquement. Si vous appliquez des effets personnalisés, utilisez DXCompileShader() avec une gestion des erreurs :

string error_log;
if(!DXCompileShader("shader.hlsl", "vs_main", "vs_5_0", shader_blob, error_log))
  {
   Print("Shader compilation failed: ", error_log);
   return(false);
  }


Données → Sommets → Image

Après l'initialisation, le cycle de rendu commence. Chaque image passe par un pipeline de transformation :

Modèle objet — Le modèle tridimensionnel est décrit par un maillage de polygones. En pratique, on utilise la triangulation : chaque polygone est divisé en triangles, puisqu'un triangle décrit de manière unique un plan dans l'espace. Un cube, par exemple, possède 8 sommets, mais pour un éclairage correct, 24 sommets sont créés (4 pour chaque face avec des normales uniques).

Topologie et indices — Les sommets sont liés en primitives via un buffer d'index. Cela permet d'économiser de la mémoire : un même sommet peut être utilisé dans plusieurs triangles.
    //--- preparing vertices and indices for the sphere
    DXVertex vertices[];
    uint indices[];
    if(!DXComputeSphere(0.3f, 50, vertices, indices))
       return(false);
    
    //--- create the sphere object
    if(!m_sphere.Create(m_canvas.DXDispatcher(), m_canvas.InputScene(), vertices, indices))
      {
       m_canvas.Destroy();
       return(false);
      }
    


    Transformations — Chaque objet passe par les matrices :

    • matrice du modèle — coordonnées locales → monde (rotation, échelle, translation)
    • matrice de vue — coordonnées mondiales → coordonnées de la caméra
    • matrice de projection — coordonnées de la caméra → coordonnées de l'écran
    //--- calculate the cube position and the transfer matrix
    DXMatrix rotation, translation;
    
    //--- rotate the cube sequentially along the X, Y and Z axes
    DXMatrixRotationYawPitchRoll(rotation, (float)M_PI/4, (float)M_PI/3, (float)M_PI/6);
    
    //--- shift the cube to the right-down-into the depth
    DXMatrixTranslation(translation, 1.0, -2.0, 5.0);
    
    //--- get the transformation matrix as a product of rotation and transfer
    DXMatrix transform;
    DXMatrixMultiply(transform, rotation, translation);
    
    //--- set the transformation matrix
    m_box.TransformMatrixSet(transform);
    


    Éclairage (modèle de Phong) — une image réaliste nécessite le calcul de trois composantes d'éclairage :

    • Ambiant (arrière-plan) — une composante constante qui simule la lumière diffuse ;
    • Diffuse (dispersée) — dépend de l'angle d'incidence de la lumière sur la surface ;
    • Spéculaire (miroir) — reflets qui créent un effet brillant.
    //--- set the source color to yellow and direct it from top to bottom
    m_canvas.LightColorSet(DXColor(1.0, 1.0, 0.0, 0.8f));
    m_canvas.LightDirectionSet(DXVector3(0.0, -1.0, 0.0));
    
    //--- set the blue color for the ambient light
    m_canvas.AmbientColorSet(DXColor(0.0, 0.0, 1.0, 0.4f));
    
    //--- set the cube color to white with a green glow
    m_box.DiffuseColorSet(DXColor(1.0, 1.0, 1.0, 1.0));
    m_box.EmissionColorSet(DXColor(0.0, 1.0, 0.0, 0.2f));
    


    Rendu et mise à jour du canevas — toutes les opérations sont effectuées dans la méthode Render(). Ensuite, l'image est transférée sur le canevas via Update() :

    //--- calculate the 3D scene
    m_canvas.Render(DX_CLEAR_COLOR | DX_CLEAR_DEPTH, ColorToARGB(clrBlack));
       
    //--- update the picture on the canvas in accordance with the current scene
    m_canvas.Update();
    


    Gestion de la mémoire — chaque objet DX consomme de la mémoire vidéo. Lors de la création de scènes dynamiques (par exemple, la mise à jour de la surface d'optimisation), il est nécessaire de :

    • effacer les anciens buffers avant d'en créer de nouveaux
    • utiliser DXResourceRelease() pour libérer explicitement les ressources
    • contrôler le nombre de sommets : des milliers de polygones sont autorisés pour les objets statiques, des centaines pour les objets animés (le nombre exact dépend des performances de l’ordinateur)


    Diagnostic et vérification des erreurs — vérifiez toujours les valeurs de retour et utilisez GetLastError() pour le diagnostic en cas d'erreur :

    if(!m_canvas.CreateBitmapLabel(...))
      {
       int err = GetLastError();
       Print("DX Error code: ", err);
       
    //--- typical errors:
    //--- 1: device does not support DX11
    //--- 2: insufficient video memory
    //--- 3: shader compilation error
      }
    


    Accélération matérielle ou rendu logiciel :

    MT5 détecte automatiquement les capacités de votre carte vidéo. Si DirectX 11 n'est pas disponible, les graphismes ne s'afficheront pas. Exigences de vérification :

    • carte vidéo compatible avec DX11 et la version 5.0 des shaders
    • pilotes à jour (les versions obsolètes peuvent provoquer des artefacts)
    • activer l'accélération matérielle dans les paramètres du terminal

    Pour savoir quelle version de DirectX est installée sur votre ordinateur, suivez les étapes suivantes :

    • dans la zone de recherche de la barre d'outils Windows, tapez « dxdiag », et sélectionnez ensuite « dxdiag » dans la liste des résultats
    • dans l'outil de diagnostic DirectX, sélectionnez l'onglet Système - la version de DirectX doit être au moins 11

    Vérification de DirectX

    Fig. 3 : vérification de la version de DirectX

    Note :

    Lors de votre première utilisation de l'outil de diagnostic DirectX, il se peut que vous soyez invité à vérifier les signatures numériques de vos pilotes. Il est recommandé de sélectionner Oui pour garantir que vos pilotes sont signés par un éditeur qui a vérifié leur authenticité.


    Optimisation de la consommation des ressources informatiques pour la boucle de rendu :

    • OnTimer() ou OnChartEvent() — pour les scènes statiques, appelez la fonction Redraw() uniquement lorsque les données changent, et non à chaque tick
    • niveau de détail (« Level of Detail » ou LOD) — réduit le niveau de détail des objets à mesure que la caméra s'éloigne ;
    • Instanciation - pour plusieurs objets identiques (clusters, marqueurs), utilisez un seul maillage avec des matrices de transformation différentes.


    Le pipeline de base est prêt. Nous avons créé un canevas, configuré une projection, défini des objets avec des sommets et des normales, appliqué des transformations et un éclairage. L'étape suivante consiste à alimenter ce cadre avec du contenu analytique : transformer les résultats d'optimisation en surfaces 3D, les clusters de liquidité en structures volumétriques et les modèles de scénarios en rapports interactifs.

    Visualisation de données complexes — surfaces, clusters, scénarios

    Une fois le pipeline DX de base mis en place, nous disposons d'un espace vide prêt à visualiser les données. La prochaine étape consiste à transformer les chiffres du rapport du Testeur de Stratégie en primitives géométriques compréhensibles par l'œil humain. Nous passons des matrices brutes aux paysages visuels.

    La création d'une surface d'optimisation 3D est probablement la manière la plus utile d'utiliser la 3D dans le trading. Le Testeur de Stratégie produit un tableau où les lignes représentent les exécutions et les colonnes les paramètres et les métriques. La visualisation des résultats d'optimisation en 3D transforme ce tableau en un terrain.

    Mathématiques de visualisation simples : les axes X et Z deviennent les paramètres de la stratégie (par exemple, la période de moyenne mobile et la taille du stop), et l'axe Y (hauteur) devient la fonction cible (par exemple, le facteur de récupération, la valeur attendue). Pour construire cette surface, nous devons générer un maillage triangulaire (Mesh) basé sur le tableau de résultats.

    Algorithme de construction :

    • collecte des données – parcourir l’ensemble des résultats d’optimisation, sélectionner et structurer les données nécessaires
    • normalisation - normaliser les valeurs des paramètres à une échelle commune afin d’éviter un rendu visuellement écrasé
    • génération des sommets - pour chaque point de données, nous créons le sommet DXVertex
    • triangulation - relier les sommets adjacents par leurs indices pour former des triangles
    //+------------------------------------------------------------------+
    //| example of creating a surface from a data array                  |
    //+------------------------------------------------------------------+
    void CreateOptimizationSurface(const double &data[],const int width,const int height)
      {
       DXVertex vertices[];
       uint indices[];
       int v_count = 0;
       int i_count = 0;
       
    //--- allocate memory for vertices (width*height of points)
       ArrayResize(vertices,width*height);
       
       for(int y=0;y<height;y++)
         {
          for(int x=0;x<width;x++)
            {
             int idx=y*width+x;
             //--- X and Z are the coordinates of the parameters, Y is the value of the metric (profit)
             vertices[idx].position=DXVector3(x, data[idx], y); 
             vertices[idx].normal=DXVector3(0, 1, 0); // simplified normal
             vertices[idx].vcolor=ColorToVector4(ColorFromValue(data[idx])); // color depends on value
             vertices[idx].tcoord=DXVector2((float)x/width, (float)y/height);
            }
         }
       
    //--- next, we form an array of indices for triangles and create an object using m_mesh.Create(...)
      }
    

    Sur une telle surface, des « plateaux » apparaissent immédiatement — de vastes zones où la stratégie fonctionne de manière relativement stable lorsque les paramètres changent. À l'inverse, des pics de profit étroits (semblables à des aiguilles) sont clairement visibles, ce qui indique un sur-ajustement. Il est beaucoup plus facile de repérer visuellement une telle « aiguille » que de la remarquer dans un tableau de 1.000 lignes, étant donné que les dépendances multidimensionnelles sont difficilement visibles sous forme tabulaire.

    Analyse de clusters dans l'espace

    Les données de marché incluent non seulement le prix et le temps, mais aussi le volume. En 2D, on dessine généralement un histogramme de volume en bas de l'écran, mais en 3D, le volume devient une dimension à part entière. Au lieu de barres plates, nous pouvons utiliser des blocs de volume (voxels) ou des cylindres, dont la hauteur et l'épaisseur dépendent du volume des échanges ou de la densité du cluster :

    • axe X - le temps
    • axe Z - le prix
    • axe Y — le volume / nombre de transactions (rayon du voxel)

    Visualisation de la liquidité : à l’aide de DXComputeSphere ou de maillages personnalisés, vous pouvez dessiner de grands groupes de transactions sous forme de sphères de tailles et de transparences variables. Superposées les unes aux autres, elles créent un nuage de liquidité, où le trader voit des « vides » (zones où le prix a évolué rapidement) et des « zones de concentration » (niveaux de support/résistance).

    //--- setting color based on volume (heatmap effect)
    //--- the larger the volume, the redder the color (from blue to red)
    color cluster_color=ColorInterpolate(clrBlue,clrRed,volume_ratio);
    m_cluster.MeshColorSet(ColorToVector4(cluster_color,0.7)); // 0.7 - transparency
    


    Génération de surface via DXComputeSurface()

    Pour les tâches typiques de visualisation de données bidimensionnelles (cartes thermiques, résultats d'optimisation, matrices de corrélation), la bibliothèque DirectX MQL5 fournit la fonction modèle prête à l'emploi DXComputeSurface(). Cette fonction se trouve dans le fichier DXUtils.mqh.

    Déclaration :

    //+------------------------------------------------------------------+
    //| Surface                                                          |
    //| TVertex must have                                                |
    //| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
    //+------------------------------------------------------------------+
    template <typename TVertex>
    bool DXComputeSurface(double &data[],uint data_width,uint data_height,double data_range,
                          const DXVector3 &from,const DXVector3 &to,DXVector2 &texture_size,
                          bool two_sided,bool use_normals,
                          TVertex &vertices[],uint &indices[])
    

    But :

    Générer automatiquement les sommets et les indices d'une surface 3D à partir d'un tableau de données 2D. Cette fonction dispense le développeur de la nécessité de calculer manuellement les coordonnées, la triangulation du maillage et les normales.

    Entrées :

    Paramètre  Type  Description 
    [in] data[]
    double&
    Tableau unidimensionnel de valeurs de hauteur (données d'optimisation, corrélations, etc.)
    [in] data_width
    uint
    Largeur de la matrice de données d'origine (nombre de colonnes)
    [in] data_height
    uint
    Hauteur de la matrice de données originale (nombre de lignes)
    [in] data_range
    double
    Plage d'échelle pour les valeurs le long de l'axe Z (hauteur)
    [in] from
    const DXVector3&
    Coordonnées du coin inférieur gauche de la surface dans l'espace 3D
    [in] to
    const DXVector3&
    Coordonnées du coin supérieur droit de la surface dans l'espace 3D
    [in] texture_size
    DXVector2&
    Taille des coordonnées de texture (pour le mappage de texture ou les dégradés)
    [in] two_sided
    bool
    Indicateur de rendu double face (utile pour les surfaces transparentes)
    [in] use_normals
    bool
    Indicateur de calcul des normales pour un éclairage correct
    [out] vertices[]
    TVertex&
    Tableau des sommets de sortie (rempli par la fonction)
    [out] indices[]
    uint&
    Tableau de sortie des indices pour la triangulation (rempli par la fonction)

    Exigences relatives au type TVertex - le paramètre de modèle TVertex doit être une structure contenant au moins trois champs :

    struct MyVertex
      {
       DXVector4 position;  // vertex coordinates (x,y,z,w)
       DXVector4 normal;    // normal vector (nx,ny,nz,0)
       DXVector2 tcoord;    // texture coordinates (u,v)
       // additional fields as needed: color, binormal, etc.
      };
    

    Valeur renvoyée :

    • true — la surface a été générée avec succès
    • false — erreur (vérifiez la taille des tableaux et la validité des données d'entrée)

    Exemple d'utilisation :

    Supposons que nous ayons les résultats de l'optimisation de stratégie sous la forme d'une matrice 20x20, où chaque valeur représente la valeur attendue d'une transaction. Nous souhaitons visualiser ces données sous forme de surface 3D.

    //+------------------------------------------------------------------+
    //| Generate optimization surface via DXComputeSurface               |
    //+------------------------------------------------------------------+
    void BuildOptimizationSurface(double &optimization_data[],uint width,uint height)
      {
    //--- define the vertex type with an additional color field
       struct SVertex
         {
          DXVector4 position;
          DXVector4 normal;
          DXVector2 tcoord;
          DXColor   vcolor;  // vertex color for gradient
         };
       
       SVertex vertices[];
       uint    indices[];
       
    //--- surface parameters
       DXVector3 from(-10.0,-5.0,0.0);   // lower left corner
       DXVector3 to(10.0,5.0,1.0);       // upper right corner
       DXVector2 texture_size(1.0,1.0);  // full coverage of texture coordinates
       double    data_range=2.0;         // height scaling
       
    //--- generate geometry
       if(!DXComputeSurface(optimization_data,width,height,data_range,
                            from,to,texture_size,
                            false,true,  // one-sided, with normals
                            vertices,indices))
         {
          Print("surface generation error: ",GetLastError());
          return;
         }
       
    //--- color the vertices by height (gradient: red → green)
       for(uint i=0;i<ArraySize(vertices);i++)
         {
          double t=MathMax(0.0,MathMin(1.0,vertices[i].position.z/data_range));
          vertices[i].vcolor=DXColor(1.0f-(float)t,(float)t,0.2f,1.0f);
         }
       
    //--- create a mesh and add it to the scene
       if(!mesh.Create(canvas.DXDispatcher(),canvas.InputScene(),vertices,indices))
          Print("error creating mesh: ",GetLastError());
       
       mesh.DiffuseColorSet(DXColor(1.0f,1.0f,1.0f,1.0f));
       canvas.ObjectAdd(&mesh);
      }
    

    Avantages de DXComputeSurface() :

    • vitesse de développement : plus besoin d’écrire manuellement les cycles de triangulation et de calcul normal
    • optimisation - l'implémentation interne utilise des algorithmes de génération de maillage efficaces
    • flexibilité - le type de sommet du modèle permet d'ajouter tous les attributs supplémentaires (couleur, texture, données personnalisées)

    Limitations de DXComputeSurface() :

    • grilles régulières uniquement - la fonction suppose que les données sont une matrice rectangulaire ; pour les nuages de points irréguliers ou les topologies arbitraires, une génération manuelle sera nécessaire
    • interpolation par défaut : les hauteurs des sommets sont interpolées linéairement entre les nœuds de la grille, un pré-filtrage des données peut être nécessaire pour lisser les aspérités
    • mémoire - la fonction alloue dynamiquement les tableaux de sommets et d'indices (lorsque vous travaillez avec de grandes matrices (par exemple 100x100 et plus), surveiller la consommation de mémoire et la fréquence de reconstruction de la surface)

    Intégration avec le contrôle interactif :

    Étant donné que DXComputeSurface() génère une géométrie statique, les mises à jour dynamiques (par exemple lors de la modification des paramètres d'optimisation en temps réel) nécessitent :

    1. l’enregistrement d’une référence à l'objet CDXMesh
    2. un appel à mesh.Shutdown() lorsque les données changent pour libérer les anciens buffers
    3. un nouvel appel à DXComputeSurface() et mesh.Create() avec les nouvelles données
    4. un appel à RedrawScene() pour afficher les modifications

    Pour une animation fluide, il est recommandé de déplacer les opérations lourdes vers le gestionnaire OnTimer, comme cela est fait dans l'EA DX_OptimizationSurface (voir la description ci-dessous). L'utilisation de DXComputeSurface() dans de nombreux cas typiques réduit la quantité de code de 30 à 40% lors de la construction de surfaces typiques, ce qui nous permet de nous concentrer sur la logique analytique plutôt que sur les graphismes de bas niveau.


    Modélisation de scénarios et rapports interactifs

    L'un des avantages de DirectX dans MQL5 est la possibilité de mettre à jour dynamiquement la scène sans recharger l'indicateur. Cela ouvre la voie à la modélisation de scénarios hypothétiques. Par exemple, le panneau où vous déplacez le curseur intitulé « Volatilité » ou « Commission ». Le tableau data[] est recalculé en temps réel, et la fonction de mise à jour du buffer de sommets VertexSet() modifie dynamiquement la surface 3D.

    //+------------------------------------------------------------------+
    //| dynamic update example                                           |
    //+------------------------------------------------------------------+
    void OnSliderChange(const double new_vol)
      {
    //--- recalculate the strategy metrics with the new volatility
       RecalculateStrategyMetrics(new_vol);
       
    //--- update only the Y-coordinate of the vertices (height), without recreating the mesh
       for(int i=0;i<ArraySize(m_vertices);i++)
         {
          m_vertices[i].position.y=m_new_metrics[i];
          //--- recalculate normals for correct lighting
          m_vertices[i].normal=CalculateNormal(i); 
         }
       
    //--- send updated data to video memory
       m_mesh.VertexSet(m_vertices);
       Redraw();
     }
    

    Cela permet au trader d'évaluer la robustesse de la stratégie : si une petite variation de la volatilité transforme un résultat rentable en résultat perdant, il est peu probable que la stratégie soit viable à long terme.


    Les shaders en tant que filtre analytique

    Les shaders standard de MetaTrader 5 sont responsables de l'éclairage (modèle de Phong). Mais pour l'analyse, nous avons besoin de shaders qui fonctionnent avec les données. Nous pouvons écrire un simple Pixel Shader qui servira de filtre.

    Par exemple, vous devez mettre en évidence sur le graphique 3D uniquement les zones où le drawdown dépasse 20%, ou celles où le facteur de profit est inférieur à un :

    //+------------------------------------------------------------------+
    //| example of logic in HLSL shader                                  |
    //+------------------------------------------------------------------+
    float4 PS_Main(PS_INPUT input) : SV_TARGET
      {
    //--- input.color contains the metric information encoded in the vertex
       float profit=input.color.r; 
       
    //--- if the profit is below the threshold, make the object transparent
       if(profit<threshold)
          return float4(0.5,0.5,0.5,0.2); // gray and transparent
       else
          return float4(0.0,1.0,0.0,1.0); // bright green
      }
    

    Dans le shader, nous vérifions la valeur d'un attribut de sommet (tel que la hauteur ou la couleur transmise) et, si elle ne répond pas aux critères, nous rendons le pixel transparent ou gris. Cette approche nous permet d'éliminer le « bruit » du graphique, ne laissant apparaître que les zones significatives. Ceci est important lors de l'analyse de grands ensembles de données d'optimisation.


    Interactivité - contrôle de la souris, des boutons et de la caméra

    Une image 3D statique est belle, mais elle est peu utile en trading si vous ne pouvez pas la faire pivoter, zoomer ou la filtrer. Le véritable avantage de DirectX dans MQL5 apparaît lorsque nous avons la possibilité d'explorer activement les données. Voyons comment donner vie à une scène en liant les événements de la souris et du clavier aux calculs de la caméra.

    Gestion des événements en MQL5 — donner vie au canevas

    Par défaut, le canevas (CDXCanvas) est simplement une image raster qui ne répond pas au curseur. Pour permettre l'interaction avec l'utilisateur, il faut s'abonner aux événements du graphique. Cela se fait via les modificateurs CHART_EVENT_MOUSE_... dans la fonction OnInit() :

    //+------------------------------------------------------------------+
    //| subscribe to mouse events                                        |
    //+------------------------------------------------------------------+
    int OnInit()
      {
    //--- enable receiving mouse events
       ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
       ChartSetInteger(0,CHART_EVENT_MOUSE_WHEEL,1);
       
    //--- timer for animation
       EventSetMillisecondTimer(16); 
       
       return(INIT_SUCCEEDED);
      }
    

    Après cela, tous les mouvements du curseur seront traités par le gestionnaire OnChartEvent(). La prochaine étape consiste à filtrer les identifiants requis (CHARTEVENT_MOUSE_MOVE, CHARTEVENT_MOUSE_WHEEL) et à transmettre les coordonnées au module de rendu.

    Remarques :

    Dans OnDeinit(), assurez-vous de désactiver ces événements (en appelant ChartSetInteger(..., 0)), sinon après la suppression de l'indicateur, le terminal continuera à les générer et créera une charge supplémentaire.


    Contrôle de la caméra — orbite et zoom

    La méthode la plus courante pour interagir avec des graphismes 3D consiste à faire pivoter un objet (orbite) et à zoomer/dézoomer. Dans DirectX, cela se réalise non pas en faisant pivoter l'objet lui-même, mais en déplaçant la caméra sur une sphère autour du centre de la scène.

    Trois méthodes interdépendantes sont utilisées pour contrôler la caméra dans la classe CCanvas3D :

    • ViewPositionSet() — définit l'emplacement de l'œil de l'observateur (coordonnées de la caméra)
    • ViewTargetSet() — définit où l'observateur regarde (généralement le centre de la scène est 0,0,0)
    • ViewUpDirectionSet() — définit la direction du haut du cadre (afin que la caméra ne se retourne pas)

    Mise en œuvre de la rotation

    La rotation s'effectue en déplaçant le curseur de la souris tout en maintenant le bouton gauche de la souris enfoncé. Pour faire pivoter la scène, nous suivons le delta de déplacement du curseur : la différence entre la position actuelle et la position précédente. Nous convertissons ce delta en angles de rotation autour des axes X et Y.

    //+------------------------------------------------------------------+
    //| mouse movement event handler                                     |
    //+------------------------------------------------------------------+
    void OnMouseMove(int x, int y, uint flags)
      {
    //--- check that the left mouse button is pressed
       if((flags&1)==1) 
         {
          //--- calculate the change in angles based on the mouse offset
          //--- divide by the coefficient (for example, 300.0f) for sensitivity
          m_camera_angles.y+=(x-m_mouse_x)/300.0f;
          m_camera_angles.x+=(y-m_mouse_y)/300.0f;
          //--- limit the vertical angle
          if(m_camera_angles.x<-DX_PI*0.49f)
             m_camera_angles.x=-DX_PI*0.49f;
          if(m_camera_angles.x>DX_PI*0.49f)
             m_camera_angles.x=DX_PI*0.49f;
          //--- recalculate the camera position
          UpdateCameraPosition();
          Redraw();
         }
    //--- save the current coordinates for the next step
       m_mouse_x=x;
       m_mouse_y=y;
      }
    

    Dans la fonction UpdateCameraPosition(), nous utilisons les matrices de rotation DXMatrixRotationX et DXMatrixRotationY pour faire pivoter le vecteur de direction de la caméra et mettre à jour sa position dans l'espace.

    Mise en œuvre du zoom

    La rotation de la molette de la souris modifie la distance entre la caméra et le centre de la scène (m_camera_distance).

    //+------------------------------------------------------------------+
    //| mouse wheel rotation event handler                               |
    //+------------------------------------------------------------------+
    void OnMouseWheel(double delta)
      {
    //--- decrease or increase the distance
       m_camera_distance*=1.0-delta*0.001;
       
    //--- limit the zoom to reasonable values
       if(m_camera_distance>50.0)
          m_camera_distance=50.0;
       if(m_camera_distance<3.0)
          m_camera_distance=3.0;
    
       UpdateCameraPosition();
       Redraw();
      }
    


    Panneau d'interface utilisateur au-dessus de la scène 3D

    Les graphismes 3D sont responsables de l'affichage des données, mais pour contrôler les paramètres, nous avons besoin d'éléments d'interface MQL5 standard et familiers. Pour éviter de réinventer la roue, utilisez les classes de la bibliothèque de contrôles MQL5 standard (CAppDialog, CSlider, CComboBox, etc.), qui sont dessinées au-dessus ou sur le côté du canevas graphique. Vous pouvez également utiliser d'autres classes pour construire l'interface.

    Lorsque la valeur du curseur change (par exemple, « Seuil de profit »), une fonction est appelée qui met à jour les données dans le buffer de sommets ou modifie les variables du shader, après quoi la fonction Redraw() est appelée. Cela nous permet de créer un outil analytique complet. Par exemple : à gauche se trouve un paysage 3D interactif affichant les résultats de l’optimisation, à droite se trouve un panneau de contrôle avec des filtres.

    Optimisation du cycle interactif

    L'interactivité ne doit pas réduire significativement les performances du terminal et de l'ordinateur dans son ensemble. Si vous appelez la fonction Redraw() à chaque micro-mouvement de la souris sans maintenir le bouton enfoncé, l'interface du terminal commencera à ralentir.

    Énonçons les règles de base pour optimiser l'interactivité :

    • appelez Redraw() uniquement lorsque cela est nécessaire - appelez le dessin de la scène uniquement à l'intérieur des blocs de vérification : if((flags & 1) == 1) (vérifiez lorsque le bouton est pressé) ou lors de la modification des paramètres d'interface utilisateur
    • filtrez les événements inutiles - si les données de dessin arrivent trop souvent (par exemple, à partir des ticks dans le gestionnaire OnTick()), ne mettez pas à jour le buffer de sommets plus de 10 à 15 fois par seconde
    • asynchronisme des calculs lourds - si la modification d'un paramètre nécessite le recalcul de milliers de sommets (par exemple, la reconstruction de l'ensemble de la surface d'optimisation), effectuez-le dans le gestionnaire d'événements de minuterie OnTimer() ou déplacez-le vers un thread séparé via une DLL pour éviter de bloquer l'interface


    Expert Advisor de test pour la validation des technologies 3D

    Nous développerons un EA mettant en œuvre les technologies 3D décrites. L'EA est un outil de visualisation tridimensionnelle des données analytiques dans le terminal de trading MetaTrader 5. L'objectif principal est de transformer les résultats numériques de l'optimisation de la stratégie de trading en surfaces tridimensionnelles, permettant ainsi au trader et/ou au développeur d'évaluer rapidement la qualité et la stabilité de la stratégie.

    L'EA résout les problèmes suivants :

    • la visualisation de la surface d'optimisation est une représentation de la dépendance de la fonction objectif (profit, valeur attendue, ratio de Sharpe) sur deux paramètres de stratégie optimisés sous la forme d'un paysage tridimensionnel
    • l’analyse de la stabilité de la stratégie – identification des « plateaux de stabilité » (zones de variations progressives des résultats) et des « aiguilles de sur-ajustement » (pics étroits et isolés indiquant un sur-ajustement des données historiques)
    • l’exploration interactive des données – permettant de faire pivoter, de zoomer et d'explorer la surface en détail à l'aide d'une souris
    • la comparaison des modes – pour basculer entre différents modes d'affichage (par exemple, mode profit et mode bruit) pour évaluer la qualité de l'optimisation

    Caractéristiques :

    Visualisation 3D — l'EA crée un canevas 3D interactif sur le graphique mesurant 640×480 pixels, qui affiche une surface générée sur la base de la fonction analytique. La surface est un maillage de 25x25 sommets, triangulé pour un affichage correct.

    Codage couleur — le schéma de couleurs suivant a été appliqué :

    • la partie supérieure (valeurs maximales) est d'un vert intense
    • la base (valeurs minimales) - couleur rouge riche
    • les valeurs intermédiaires présentent un dégradé progressif avec une transition par des nuances jaune-orange

    Ce codage nous permet d'identifier avec précision les zones de profit maximal (les « collines » vertes) et les zones de pertes (les « creux » rouges).

    Contrôle de la caméra — un contrôle complet du point de vue a été implémenté :

    • rotation - maintenir le bouton gauche de la souris enfoncé et déplacer le curseur permet de faire pivoter la caméra autour du centre de la scène sur une orbite sphérique
    • zoom - faire défiler la molette de la souris permet de zoomer ou de dézoomer la caméra (distance de 5,0 à 40,0 unités)
    • limitations - l'angle vertical est limité à ±0,9×π/2 pour éviter que la caméra ne se retourne

    Contrôle interactif

    Il y a un bouton de changement de mode sur le canevas :

    • mode profit - affiche une surface de courbe gaussienne lisse (simulant une stratégie stable)
    • mode bruit - affiche la surface avec du bruit aléatoire ajouté (simulant une stratégie sur-optimisée)

    Lors du changement de mode, le texte du bouton est automatiquement mis à jour.

    Éclairage et matériaux

    Pour créer une image volumétrique réaliste, un modèle d'éclairage Phong à trois composantes a été utilisé :

    • source de lumière directionnelle - couleur jaune (1,0, 0,95, 0,8), direction (0,5, -0,8, 0,3)
    • éclairage ambiant - couleur grise (0,55, 0,55, 0,55) avec une intensité accrue pour une meilleure visibilité des zones d'ombre
    • matériau diffus - couleur blanche (1.0, 1.0, 1.0, 1.0) pour se combiner correctement avec les couleurs des sommets


    Caractéristiques de l'implémentation

    Gestion des événements asynchrones :

    • réaction aux mouvements du curseur de la souris et à la rotation de la molette - le programme reçoit l'appel de fonction OnChartEvent() et le traite immédiatement (l'orientation du modèle 3D, ses dimensions, etc. sont modifiées) - aucun calcul complexe n'est nécessaire
    • réaction à l'appui sur le bouton de changement de mode - le programme reçoit l'appel de fonction OnChartEvent() et définit l'indicateur need_rebuild, la fonction BuildSurface() chargée de détruire l'ancien maillage, de générer une nouvelle surface 3D et d'effectuer le rendu est appelée dans le gestionnaire OnTimer(), qui vérifie l'état de l'indicateur need_rebuild toutes les 50 ms

    Cette approche garantit que même si le recalcul du modèle 3D consomme des ressources du processeur, le graphique du terminal et les commandes restent pleinement réactifs.

    La bibliothèque MQL5\Include\Canvas\DX\DXMath.mqh est utilisée pour calculer correctement l'éclairage et l'orientation de la caméra :

    • normales - pour chaque sommet de la surface, le vecteur normal est calculé à l'aide de la fonction de produit vectoriel DXVec3Cross(), nécessaire pour que la surface ait du volume et réagisse à la source lumineuse, créant ainsi des ombres et des reflets réalistes
    • caméra - la position de l'observateur est calculée à l'aide de coordonnées sphériques, ce qui permet une rotation intuitive autour d'un objet (« orbite ») sans l'effet de retournement de la caméra, limitant ainsi l'angle vertical


    Le code complet de l'EA est contenu dans le fichier DX_OptimizationSurface.mq5 joint à l'article.

    Des exemples du fonctionnement de l'EA dans différents modes sont présentés dans les figures ci-dessous :

    Profit

    Fig. 4 : mode de profit


    Bruit

    Fig. 5 : mode bruit


    Nous disposons désormais d'une panoplie complète d'outils : nous pouvons créer une scène, la remplir de données d'optimisation et donner à l'utilisateur la possibilité d'explorer ces données en effectuant des rotations et des zooms. Mais avant de nous précipiter pour implémenter la 3D partout où c'est possible, examinons d'abord où cette technologie est inutile et où il est préférable de s'en tenir aux graphiques conventionnels.


    Quand vaut-il mieux s'en tenir aux graphiques classiques ?

    Un outil n'est utile que s'il résout un problème plus rapidement et avec plus de précision que son prédécesseur. Nous avons exploré l'architecture du pipeline DX, appris à générer des surfaces et à contrôler la caméra. Mais en matière de trading, il faut faire la distinction entre une visualisation analytique utile et le bruit visuel. L'intégration de graphismes 3D dans MetaTrader 5 n'est pas une fin en soi, mais un moyen de résoudre des problèmes. Examinons les cas où l'abandon de la 3D au profit de la 2D classique se justifiera techniquement et économiquement.

    Règle de dimensionnalité des données

    Établissons une règle justifiant la nécessité de la visualisation 3D : la troisième dimension doit véhiculer des informations uniques :

    • la 3D est inutile si vous essayez d'afficher une série temporelle (Prix/Temps) dans un espace 3D - ajouter un axe Z qui duplique le prix ou le temps ne fera que compliquer la perception, obligeant le trader à faire pivoter la scène pour voir la ligne de tendance classique.
    • la 3D est nécessaire pour analyser les résultats d'optimisation - ici, nous avons deux entrées indépendantes (par exemple, la période de moyenne mobile et la taille du stop) et une mesure de sortie (le profit ou le facteur de profit) ; sans surface 3D, nous ne verrons qu'un ensemble de points : la 3D nous permet de visualiser la relation entre deux variables et le résultat

    si votre ensemble de données se résume à une paire de coordonnées, un graphique 2D classique (DRAW_LINE, DRAW_HISTOGRAM) sera plus efficace

    Limitations matérielles et VPS

    Les graphismes 3D en MQL5 sont basés sur DirectX 11. Cela nécessite la prise en charge du Shader Model 5.0 et un certain niveau de performances CPU/GPU.

    La plupart des développeurs professionnels exécutent leurs EA sur des serveurs privés virtuels (VPS). De nombreuses configurations VPS standard ne disposent pas de cartes graphiques puissantes ni d'accélération matérielle DirectX. Dans de tels environnements, l'appel à CreateBitmapLabel() peut provoquer une erreur critique de l’EA et/ou un plantage.

    Par conséquent, si votre programme est conçu pour fonctionner en mode « aveugle », c’est-à-dire sans graphismes, ou sur un serveur bon marché, le module 3D doit être désactivé ou remplacé par une journalisation dans un fichier/une base de données. Les graphismes 2D peuvent être facilement rendus par le processeur, même sans carte vidéo.

    Vitesse de perception — Surface 3D comparée à une carte thermique

    L'une des principales alternatives à une surface 3D est une carte thermique bidimensionnelle (HeatMap). Les différences fondamentales entre eux sont les suivantes :

    • 3D - affiche la hauteur (Z) comme élévation physique : une rotation est nécessaire pour analyser avec précision toutes les faces et les pentes cachées
    • carte thermique — affiche la valeur (Z) comme la couleur d'une cellule sur le plan (X, Y)

    Si l'objectif est de trouver rapidement l'optimisation maximale (la zone la plus verte), la carte thermique de l'indicateur standard fonctionnera plus rapidement et nécessitera moins de code.

    Interactivité vs surveillance

    Les scènes 3D interactives (comme notre DX_OptimizationSurface EA) nécessitent une participation humaine active. Vous devez survoler la zone avec votre souris, maintenir le bouton enfoncé et faire pivoter la scène.

    Si l'objectif du graphique est la surveillance passive, les graphiques 3D interactifs peuvent être une source de distraction et ralentir le processus.

    Si l'objectif est une présentation ou une analyse approfondie avant le lancement d'une stratégie, alors la 3D est indispensable.

    Conclusion : 

    N’utilisez la 3D que lorsque le volume des données ou leur structure rendent l’analyse en 2D impossible. Si votre objectif est de trouver rapidement le maximum dans un tableau d'optimisation, une carte thermique sera plus efficace. La 3D est nécessaire lorsqu'il faut visualiser la forme de la relation, et pas seulement sa valeur.

    Dans d'autres cas, les classes MQL5 standard (CCanvas pour les objets 2D ou graphiques) constitueront une solution plus simple.


    Conclusion

    Nous sommes passés de la justification théorique du besoin de graphismes 3D à la création d'un EA interactif à part entière. L'Expert Advisor DX_OptimizationSurface démontre que MetaTrader 5 n'est pas seulement un terminal d'exécution d'ordres, mais une plateforme puissante pour l'analyse visuelle des données.

    Principales conclusions :

    • efficacité cognitive – la visualisation 3D nous permet de transformer des ensembles infinis de chiffres en paysages visuels, ce qui réduit la charge cognitive du trader, lui permettant de distinguer visuellement les plateaux de profit stables des dangereuses fluctuations dues au sur-ajustement
    • accessibilité technologique – la prise en charge intégrée de DirectX 11 et les classes natives CCanvas3D et CDXMesh offrent aux développeurs les outils nécessaires pour résoudre les problèmes de trading, il n'est pas nécessaire d'écrire du code C++ ni d'inclure des bibliothèques externes : tout est déjà intégré à MQL5 - il ne reste plus qu'à en profiter.
    • l’importance de l’architecture — comme nous l’avons vu, l’intégration graphique exige une attention particulière aux cycles de vie des ressources et à l’asynchronisme : le fait de déporter les opérations de calcul vers une minuterie et d'effacer correctement la mémoire garantit l'absence de problèmes de performance du terminal

    La visualisation est une lentille, pas un ornement. Elle doit répondre à une question analytique précise.

    Nous avons créé cet outil non pas pour produire un effet externe, mais pour accélérer la prise de décision. Si les graphismes 3D vous aident à comprendre rapidement le comportement d'une stratégie et à éliminer les options non viables, alors ils ont rempli leur rôle. Si ce n'est qu'une distraction, n'hésitez pas à revenir aux méthodes 2D éprouvées. La valeur d'un outil ne réside pas dans son apparence, mais dans les décisions qu'il permet de prendre plus rapidement.

    Prochaines étapes – pour ceux qui souhaitent approfondir le sujet, nous recommandons ce qui suit :

    • exploration de la bibliothèque DXMath pour travailler avec les quaternions et les transformations complexes
    • développement de shaders personnalisés (HLSL) pour créer des effets de rendu uniques
    • intégration avec Python via MetaTrader 5 pour le prétraitement des données avant leur visualisation dans le terminal

    MetaTrader 5 fournit la base technologique. Les outils analytiques que vous développerez à partir de ces données ne dépendent que de votre imagination et de la nécessité de rechercher des « perles » dans l’immensité des données de marché.


    Ressources recommandées pour apprendre à utiliser DirectX dans MetaTrader 5 :


    Liste des fichiers joints à l'article :

    Nom de fichier Description
    DX_OptimizationSurface.mq5 Un fichier contenant le code d'un EA de test avec visualisation 3D interactive



    Traduit du russe par MetaQuotes Ltd.
    Article original : https://www.mql5.com/ru/articles/22393

    Fichiers joints |
    Derniers commentaires | Aller à la discussion (3)
    Vladislav Andruschenko
    Vladislav Andruschenko | 26 mai 2026 à 11:53

    Waouh. C'est vraiment génial ! Merci. Je vais le démonter…

    INCROYABLE..........

    Isaac Uriel Arenas Caldera
    Isaac Uriel Arenas Caldera | 6 juil. 2026 à 02:47
    Je ne savais pas que c'était possible…
    Gerard William G J B M Dinh Sy
    Gerard William G J B M Dinh Sy | 4 sept. 2026 à 09:54
    Merci 
    Je pense me l'adapter à mes propres idées 
    Comment Échanger des Données : Une DLL pour MQL5 en 10 minutes Comment Échanger des Données : Une DLL pour MQL5 en 10 minutes
    Maintenant, peu de développeurs se rappellent de la façon d'écrire une DLL simple et des caractéristiques spéciales des différentes liaisons système. À l'aide de plusieurs exemples, je vais tenter de montrer l'ensemble du processus de création de la DLL simple en 10 minutes, ainsi que de discuter de certains détails techniques de notre implémentation de liaison. Je vais montrer étape par étape le processus de la création de DLL dans Visual Studio avec des exemples d'échange de différents types de variables (nombres, tableaux, chaînes, etc.). En outre, je vais vous expliquer comment protéger votre terminal client des plantages dans les DLL personnalisées.
    Architecture événementielle en MQL5 : Comment transformer un Expert Advisor en un système de trading à part entière Architecture événementielle en MQL5 : Comment transformer un Expert Advisor en un système de trading à part entière
    Cet article est consacré à l'architecture événementielle de MQL5 et décrit la transition du modèle monolithique OnTick au traitement distribué. Nous examinerons les événements prédéfinis et personnalisés, les services, l’échange de messages entre programmes, ainsi que les erreurs d'architecture courantes. Un exemple pratique montre comment organiser les interactions entre les indicateurs et un Expert Advisor afin de réduire la charge, d'améliorer la lisibilité et de simplifier la maintenance.
    L'Histogramme des prix (Profile du Marché) et son implémentation  en MQL5 L'Histogramme des prix (Profile du Marché) et son implémentation en MQL5
    Le Profile du Marché a été élaboré par le brillant penseur Peter Steidlmayer. Il a suggéré l’utilisation de la représentation alternative de l'information sur les mouvements de marché « horizontaux » et « verticaux » qui conduit à un ensemble de modèles complètement différent. Il a assumé qu'il existe une impulsion sous-jacente du marché ou un modèle fondamental appelé cycle d'équilibre et de déséquilibre. Dans cet article, j’examinerai l'Histogramme des Prix - un modèle simplifié de profil de marché, et décrirai son implémentation dans MQL5.
    MetaTrader 5 : créez un marché adapté à votre stratégie — barres Renko, Range et Volume Egal, instruments synthétiques et tests de résistance sur symboles personnalisés MetaTrader 5 : créez un marché adapté à votre stratégie — barres Renko, Range et Volume Egal, instruments synthétiques et tests de résistance sur symboles personnalisés
    Dans cet article, nous démontrons comment utiliser l'API des symboles personnalisés de MetaTrader 5 pour transformer votre terminal en un outil de construction des données permettant de générer des graphiques Renko, Range et Volume Egal indépendants du temps et d'assembler des instruments synthétiques. Nous analyserons l'agrégation des ticks et la modification de l'historique pour les tests de résistance (élargissement du spread, modifications du niveau de stop) en tenant compte des limitations de la plateforme. Vous pourrez également vous entraîner à utiliser CiCustomSymbol et le routage des ordres vers un symbole réel via le wrapper CustomOrder grâce à des fragments de code prêts à l'emploi.