English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
preview
Analyse quantitative avec MQL5 : Mise en œuvre d'un algorithme prometteur

Analyse quantitative avec MQL5 : Mise en œuvre d'un algorithme prometteur

MetaTrader 5Systèmes de trading |
370 0
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Qu'est-ce que l'analyse quantitative sur les marchés financiers ?

Qu'est-ce que l'analyse quantitative sur les marchés financiers ? L'analyse quantitative est apparue comme une sorte de précurseur de l'apprentissage automatique, étant en fait une sous-section de l'apprentissage statistique. À l'époque où les ordinateurs commençaient à apparaître, occupaient une pièce entière et fonctionnaient sur des cartes perforées, des esprits progressistes tentaient de les adapter à l'analyse des données et des statistiques. L'ensemble des opérations statistiques et des fonctions permettant de calculer les prix était extrêmement réduit, les fonctions elles-mêmes étaient assez simples et les modèles trouvés n'étaient pas particulièrement complexes.

Ces études étaient de simples calculs visant à identifier certaines relations dans les données, le plus souvent linéaires.

La méthode d'analyse quantitative la plus simple et la plus facile à apprendre sur les marchés financiers est l'analyse de l'écart entre des actifs liés. Par exemple, nous pouvons tracer un écart entre deux actifs corrélés et, à l'aide d'une analyse quantitative, trouver la moyenne, le maximum et l'écart médian de cet écart. Après avoir reçu une description quantitative des données, nous pouvons comprendre à quel point un actif s'est écarté de l'autre, et comprendre approximativement l'état d'équilibre des deux actifs, où ils reviendront tous deux de manière certaine lorsque l'écart entre eux sera éliminé (lorsque les actifs se rapprochent l'un de l'autre). D'une manière générale, l'utilisation de l'analyse quantitative dans le trading de paires est un sujet très intéressant ; nous aborderons certainement ce point dans de futurs articles. 


Comment l'analyse quantitative est utilisée par les fonds spéculatifs

La première tentative d'utilisation de l'analyse quantitative a été le cabinet d'Edward O. Thorp qui, dans les années 1970, a appris à analyser l'écart entre une action et un warrant sur cette action, en calculant dans quelle mesure l'actif est surévalué ou sous-évalué par rapport à son warrant. À l'époque, l'ordinateur de Thorp occupait une pièce entière et fonctionnait également avec des cartes perforées. Edward O. Thorp a été le premier à appliquer l'analyse quantitative informatique aux marchés financiers. Il s'agissait d'une percée à l'époque, reconnue par le monde entier. Thorp a créé le premier fonds spéculatif "quantitatif" au monde. 

Vous l'aurez compris, le premier exemple d'analyse quantitative en bourse qui nous vient à l'esprit est son application dans le trading de paires, ou « basket trading ». Nous ne manquerons pas d'envisager ces options, mais l'algorithme d'analyse quantitative d'aujourd'hui sera basé sur d'autres principes.

De quelle autre manière les principaux acteurs du marché utilisent-ils l'analyse quantitative ? 

L'arbitrage statistique leur permet de détecter les différences de prix des instruments financiers sur différents marchés ou à différents moments. Cela permet aux fonds d'identifier et de tirer parti d'opportunités de trading rentables sur une variété de marchés connexes. Les modèles quantitatifs aident aussi les fonds spéculatifs à prévoir les mouvements futurs du marché sur la base de données statistiques, ce qui leur permet de prendre des décisions de trading en connaissance de cause.

La gestion des risques est une autre application extrêmement importante de l'analyse quantitative. Les fonds spéculatifs utilisent des modèles pour évaluer et gérer le risque dans leurs portefeuilles. Ils optimisent la structure des actifs en fonction du risque afin de minimiser les pertes potentielles. Il existe différents exemples, comme l'optimisation du portefeuille selon la théorie du portefeuille de Markowitz (qui se base sur le risque pour que la déviation du portefeuille ne dépasse pas le profit potentiel) et la gestion du risque selon le système VaR. Ce dernier est un modèle unique qui nous permet de calculer le drawdown, que nous ne dépasserons pas avec une chance de 99%.

Bien entendu, il est parfois difficile de décrire le marché réel à l'aide des mathématiques, c'est pourquoi il existe également des exemples négatifs. En 1998, le fonds spéculatif LTCM a calculé que ses positions n'entraîneraient pas de pertes importantes et a adopté une stratégie d'arbitrage ciblant l'écart entre les obligations américaines à long terme et à court terme sur la base d'une analyse quantitative. La Russie a fait défaut, l'Asie a connu une crise, ce qui, par effet papillon, a entraîné une panique sur le marché des obligations d'État américaines. Le fonds LTCM a utilisé des modèles qui suggéraient que le spread était anormalement élevé, que le prix allait certainement "revenir" dans la direction opposée et que les positions du fonds allaient certainement être clôturées avec un profit.

En conséquence, le fonds a appliqué un calcul de moyenne, extrêmement agressif, a obtenu un effet de levier important, en chargeant les dettes avec des actifs, et a explosé, bien que des lauréats du prix Nobel au sein du personnel de l'entreprise aient parlé de l'impossibilité d'un tel résultat. Ce fut le cas lorsqu'un modèle d'analyse quantitative intitulé VaR a failli détruire l'ensemble du marché américain. Le président de la Fed, Alan Greenspan, a dû appeler d'urgence les dirigeants des plus grandes banques américaines pour qu'ils rachètent les positions marginales du fonds, sans quoi la vente au marché d'une telle masse d'actifs aurait provoqué une remise à zéro immédiate du marché boursier américain et une panique pire que celle de la Grande Dépression.

Par conséquent, lors de l'application de l'analyse quantitative et du calcul de la moyenne de tout indicateur, il est important de se rappeler les queues de la distribution de probabilité normale. Dans le cas des marchés financiers, la courbe de probabilité en forme de cloche présente des "queues grasses" qui reflètent des écarts importants, également appelés "cygnes noirs". D'une part, ils sont statistiquement extrêmement improbables, d'autre part, l'ampleur et la puissance de ces événements peuvent détruire les portefeuilles des investisseurs et des fonds spéculatifs, éliminer les positions marginales, détruire les marchés et les modifier à chaque nouveau cycle. C'est ce qui s'est passé en 1998, en 2008, en 2020 et en 2022. Nous le verrons à de nombreuses reprises à l'avenir.

L'analyse quantitative apporte beaucoup aux fonds spéculatifs et ils l’utilisent constamment dans leur travail quotidien. Mais il est important de rappeler qu'il n'existe pas de telles fonctions capables de calculer les décisions de millions de personnes, leur panique et leurs réactions face à certains événements. Il est également important de se souvenir des queues de la distribution normale, qui peuvent ruiner le dépôt lors de l'utilisation de tactiques de trading agressives. 


Base de l'algorithme : comptage des vagues de mouvement

La base de notre idée a été exprimée pour la première fois par le trader Artem Zvezdin, qui calcule la taille des vagues de mouvement des prix afin de comprendre à quel point un actif est surévalué ou sous-évalué par rapport à lui-même. Par exemple, nous comptons les vagues haussières et baissières sur les 500 à 5000 dernières barres pour comprendre la distance parcourue par le prix dans chacun de ses petits cycles. Chaque cycle de mouvement des prix reflète les positions de quelqu'un, l'argent de quelqu'un et les décisions d'achat ou de vente. Chaque nouveau cycle est une nouvelle naissance et une nouvelle mort du marché. Nous utiliserons l'idée d'analyser les mouvements de prix sans retour en arrière, de haut en bas. Il s'agit d'un ensemble distinct de participants qui agissent à peu près de la même manière, de sorte que nous émettons l'hypothèse que la durée des cycles sera toujours à peu près la même. Nous allons calculer le mouvement moyen des prix à l'aide de l'indicateur ZigZag, qui est inclus dans la version standard du terminal MetaTrader 5.

Examinons l'Expert Advisor que j'ai créé dans le cadre de cet article. Tout d'abord, jetez un coup d'œil à l'en-tête de l'EA. Les réglages sont assez simples. Pour le trading, nous utilisons la bibliothèque standard Trade. Pour les paramètres de lot, vous pouvez spécifier soit un lot pour négocier un lot fixe, soit un calcul de lot basé sur la valeur du solde. Si vous indiquez un bénéfice de clôture supérieur à 0, l'EA clôturera les transactions sur la base du bénéfice total. Le Stop Loss et le Take Profit sont calculés sur la base de la valeur de l’ATR, c'est-à-dire qu'ils dépendent de la volatilité actuelle de l'instrument. Les paramètres du ZigZag pour les calculs de l'EA sont généralement standards, nous ne nous y attarderons pas. Veuillez également noter que notre modèle d'EA est multi-devises et qu'il peut être utilisé avec une grande variété d'actifs. Nous en avons besoin pour réduire le risque global en négociant des paniers d'actifs connexes dans les futures versions de l’Expert Advisor. La version actuelle 0.90 ne fonctionne que sur un seul symbole.

//+------------------------------------------------------------------+
//|                                          QuantAnalysisSample.mq5 |
//|                                                   Copyright 2023 |
//|                                                Evgeniy Koshtenko |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2023, Evgeniy Koshtenko"
#property link        "https://www.mql5.com"
#property version     "0.90"
#property strict

#include <Trade\Trade.mqh>
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Normal.mqh>
#include <Math\Stat\Math.mqh>
CTrade trade;
//--- Inputs
input double Lots       = 0.1;      // lot
input double Risk       = 0.1;     // risk
input double Profit     = 0;     // profit
input int StopLoss      = 0;        // ATR stop loss
input int TakeProfit    = 0;        // ATR take profit
input string Symbol1    = "EURUSD";
input int    Magic      = 777;    // magic number
//--- Indicator inputs
input uint   InpDepth       =  120;   // ZigZag Depth
input uint   InpDeviation   =  50;    // ZigZag Deviation
input uint   InpBackstep    =  30;    // ZigZag Backstep
input uchar  InpPivotPoint  =  1;    // ZigZag pivot point
datetime t=0;
double last=0;
double countMovements;
double currentMovement;
// Global variable for storing the indicator descriptor
int zigzagHandle;

Examinons maintenant les autres fonctions de l'EA. Les fonctions d'initialisation et de dé-initialisation sont généralement simples et compréhensibles. Nous définissons le numéro magique de l'EA, un identifiant unique qui permettra à l'EA de distinguer ses ordres des autres. En même temps, nous définissons le handle dans une fonction supplémentaire auto-écrite, car si nous chargeons un handle multi-devise directement via OnInit, l'EA lancera une erreur. C'est pourquoi nous utilisons cette solution assez simple et facile.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   trade.SetExpertMagicNumber(Magic);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert initialization function custom                            |
//+------------------------------------------------------------------+
int OnIniti(string symb)
  {// Loading the ZigZag indicator
   zigzagHandle = iCustom(symb, _Period, "ZigZag", InpDepth, InpDeviation, InpBackstep, InpPivotPoint);
   if (zigzagHandle == INVALID_HANDLE)
     {
      Print("Error loading the ZigZag indicator: ", GetLastError());
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }

Examinons les autres fonctions de l’Expert Advisor. Nous disposons ensuite de fonctions permettant de calculer le bénéfice total pour toutes les positions et d'une fonction permettant de clôturer complètement tous les ordres :

//+------------------------------------------------------------------+
//|  Position Profit                                                 |
//+------------------------------------------------------------------+
double AllProfit(int type=-1)
  {
   double p=0;

    for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)))
        {
         if(PositionGetInteger(POSITION_MAGIC)==Magic)
           {
            if(PositionGetInteger(POSITION_TYPE)==type || type==-1)
               p+=PositionGetDouble(POSITION_PROFIT);
           }
        }
     }

   return(p);
  }
//+------------------------------------------------------------------+
//|   CloseAll                                                       |
//+------------------------------------------------------------------+
void CloseAll(int type=-1)
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)))
        {
         if(PositionGetInteger(POSITION_MAGIC)==Magic)
           {
            if(PositionGetInteger(POSITION_TYPE)==type || type==-1)
               trade.PositionClose(PositionGetTicket(i));
           }
        }
     }
  }

Ensuite, nous avons la fonction de calcul des lots et la fonction de calcul du nombre de positions ouvertes :

//+------------------------------------------------------------------+
//|     CountTrades                                                  |
//+------------------------------------------------------------------+
int CountTrades(string symb)
  {
   int count=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)))
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            count++;
           }
        }
     }
   return(count);
  }
//+------------------------------------------------------------------+
//|     Lot                                                          |
//+------------------------------------------------------------------+  
double Lot()
  {
   double lot=Lots;

   if(Risk>0)
      lot=AccountInfoDouble(ACCOUNT_BALANCE)*Risk/100000;

   return(NormalizeDouble(lot,2));
  }

Nous disposons également de fonctions permettant de calculer le dernier prix de transaction pour les achats et les ventes (nous les utiliserons plus tard) et d'une fonction permettant de déterminer la direction de la position.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastBuyPrice(string symb)
  {
   double pr=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            pr=PositionGetDouble(POSITION_PRICE_OPEN);
            break;
           }
        }
     }
   return(pr);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastSellPrice(string symb)
  {
   double pr=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==1)
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            pr=PositionGetDouble(POSITION_PRICE_OPEN);
            break;
           }
        }
     }
   return(pr);
  }
//+------------------------------------------------------------------+
//|  PositionType                                                    |
//+------------------------------------------------------------------+
int PositionType(string symb)
  {
   int type=8;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(PositionSelectByTicket(PositionGetTicket(i)))
        {
         if(PositionGetString(POSITION_SYMBOL)==symb)
           {
            type=(int)PositionGetInteger(POSITION_TYPE);
            break;
           }
        }
     }
   return(type);
  }

Et bien sûr, notre fonction la plus importante est celle qui consiste à calculer le mouvement moyen et le mouvement actuel. Ils sont calculés non pas en points, mais en quantité de mouvement d'une unité de prix, pour des raisons de commodité. C'est simple : nous appelons notre "initialisation personnalisée", nous copions les buffers et, dans la boucle for, nous calculons la taille du mouvement du prix depuis le sommet du ZigZag jusqu'à son dernier extremum. La fonction indique le mouvement actuel en unités de prix et le mouvement moyen. 

//+------------------------------------------------------------------+
//|     CalculateAverageMovement                                     |
//+------------------------------------------------------------------+ 
void CalculateAverageMovement(string symb, double &averageMovement, double &currentMovement) {
    const int lookback = 500; // Number of bars for analysis
    double sumMovements = 0.0;
    int countMovements = 0;
    double lastExtremePrice = 0.0;
    double zigzagArray[500]; // Array to store ZigZag values
    OnIniti(symb);
    // Copy ZigZag values to array
    if (CopyBuffer(zigzagHandle, 0, 0, lookback, zigzagArray) <= 0) {
        Print("Error copying indicator data");
        averageMovement = -1;
        currentMovement = -1;
        return;
    }

    // Copy ZigZag values to array
    if (CopyBuffer(zigzagHandle, 0, 0, lookback, zigzagArray) <= 0) {
        Print("Error copying indicator data");
        averageMovement = -1;
        currentMovement = -1;
        return;
    }

    for (int i = 0; i < lookback; i++) {
        if (zigzagArray[i] != 0 && zigzagArray[i] != lastExtremePrice) {
            if (lastExtremePrice != 0) {
                // Determine the movement direction
                double movement = zigzagArray[i] - lastExtremePrice;
                sumMovements += movement;
                countMovements++;
            }
            lastExtremePrice = zigzagArray[i];
        }
    }

    // Calculate the current movement
    double lastMovement = iClose(symb, _Period, 0) - lastExtremePrice;
    currentMovement = lastMovement;

    // Calculate the average movement
    averageMovement = countMovements > 0 ? sumMovements / countMovements : 0.0;

    // Print the result
    Print("Average movement: ", averageMovement);
    Print("Current movement: ", currentMovement);

    // Release resources
    IndicatorRelease(zigzagHandle);
}

Une autre fonction, parmi les plus importantes, est la fonction de trading multi-devises basée sur des signaux montrant que le mouvement du prix actuel dépasse sa valeur moyenne. Le Take Profit et le Stop Loss sont définis en fonction de l'ATR. L'ATR est également utilisé pour les pas de grille (calcul de la moyenne). Les transactions sont ouvertes sur de nouvelles barres. C'est important pour nous. Cette fonction est ensuite appelée dans OnTick et fonctionne sur un ou plusieurs symboles. Je n'ai pas encore réussi à faire fonctionner l'EA sur plusieurs symboles, comme je l'ai déjà dit, je n'utiliserai qu'un seul symbole sur lequel l'EA sera lancé. Ce symbole doit être spécifié dans les paramètres de l'EA. 

//+------------------------------------------------------------------+
//| Expert Trade unction                                             |
//+------------------------------------------------------------------+
void Trade(string symb)
  {
   double averageMovement = 0;
   double currentMovement = 0;
   double pr=0,sl=0,tp=0,hi=0,lo=0;
// Call function for calculation
   CalculateAverageMovement(symb, averageMovement, currentMovement);

// Use results
   double Ask = SymbolInfoDouble(symb, SYMBOL_ASK);
   double Bid = SymbolInfoDouble(symb, SYMBOL_BID);
   int dg=(int)SymbolInfoInteger(symb,SYMBOL_DIGITS);
   double pp=SymbolInfoDouble(symb,SYMBOL_POINT);
  
   double atr = iATR(symb, PERIOD_CURRENT, 3);
     
// Here define your logic for buying and selling
   bool sell  = currentMovement > -averageMovement; // Buy condition
   bool buy = -currentMovement > averageMovement; // Sell condition
  
   if(AllProfit()>Profit && Profit>0)
      CloseAll();

   if(t!=iTime(symb,PERIOD_CURRENT,0))
     {
      if(buy && CountTrades(symb)<1)
        {
         if(StopLoss>0)
            sl=NormalizeDouble(Bid-(atr*StopLoss)*Point(),_Digits);
         if(TakeProfit>0)
            tp=NormalizeDouble(Bid+(atr*TakeProfit)*Point(),_Digits);
         pr=NormalizeDouble(Bid,dg);
         trade.Buy(Lot(),symb,pr,sl,tp,"");
         last=pr;
        }
      if(sell && CountTrades(symb)<1)
        {
         if(StopLoss>0)
            sl=NormalizeDouble(Ask+(atr*StopLoss)*Point(),_Digits);
         if(TakeProfit>0)
            tp=NormalizeDouble(Ask-(atr*TakeProfit)*Point(),_Digits);
         pr=NormalizeDouble(Ask,dg);
         trade.Sell(Lot(),symb,Ask,sl,tp,"");
         last=pr;
        }
      if(CountTrades(symb)>0)
        {
         if(PositionType(symb)==0 && (FindLastBuyPrice(symb)-Ask)/pp>=atr*30)
           {
            if(StopLoss>0)
               sl=NormalizeDouble(Bid-(atr*StopLoss)*Point(),_Digits);
            if(TakeProfit>0)
               tp=NormalizeDouble(Bid+(atr*TakeProfit)*Point(),_Digits);
            trade.Buy(Lot(),symb,Ask,sl,tp);
           }
         if(PositionType(symb)==1 && (Bid-FindLastSellPrice(symb))/pp>=atr*30)
           {
            if(StopLoss>0)
               sl=NormalizeDouble(Ask+(atr*StopLoss)*Point(),_Digits);
            if(TakeProfit>0)
               tp=NormalizeDouble(Ask-(atr*TakeProfit)*Point(),_Digits);
            trade.Sell(Lot(),symb,Bid,sl,tp);
           }
        }
      t=iTime(symb,0,0);
     }
  }


Test du modèle

Le moment est venu de passer à la partie la plus amusante : nous allons tester notre modèle sur le marché réel. Veuillez noter que les calculs basés sur des boucles sont assez gourmands en ressources, il est donc plus judicieux d'exécuter l'EA uniquement sur les prix d'ouverture. Effectuons un seul test sur l'EURUSD, prix d’ouverture, échelle de temps H1, du 1er janvier 2020 au 6 décembre 2023 :


Un seul test est rentable, mais le drawdown est élevé. Personne ne souhaite prendre des risques supplémentaires lorsqu'il fait du trading. N'oubliez pas que nous avons également une clôture basée sur les bénéfices. Nous pouvons effectuer un test sur un compte de compensation.

Pour effectuer un test avec une clôture basée sur le profit, définissez la clôture avec un profit supérieur à 0. Essayons de tester. Peut-être obtiendrons-nous un test stable. Exécutez l'EA sur le même actif sur les prix d’ouverture. Notre type de compte est un compte de couverture. Et c'est ce que nous voyons :


L'EA s'est avéré extrêmement risqué en raison de la moyenne. Essayons d'effectuer le même test sur un compte de compensation.


Une fois de plus, nous avons une baisse importante ; le profit ne vaut absolument pas le risque. Essayons de revoir le code. Cette fois, mettons en œuvre la clôture par signal (lorsqu'un signal haussier se transforme en signal baissier, les positions précédentes seront fermées). Nous ajoutons la clôture par profit en utilisant le code suivant :

if (CloseSig)
   {
      if (buy)
         CloseAll(1);
      if (sell)
         CloseAll(0);
   }

Et ajoutez ce paramètre :

input bool CloseSig     = 1;        // close by signal

Répétez le test. Les résultats ne sont pas bons non plus :


Les tests en général ne peuvent être qualifiés d'idéaux. L'écart est énorme, tant sur le compte de compensation que sur le compte de couverture. La clôture sur la base d'un signal ne génère aucun résultat positif non plus et n'est généralement pas rentable. C'est assez bouleversant.


Conclusion

Nous avons vu un exemple simple de création d'un algorithme d'analyse quantitative simple et basique dans MQL5. Nous avons compté les vagues de mouvements de prix, nous les avons comparées aux valeurs moyennes et, sur la base de ces données, nous avons pris la décision d'acheter ou de vendre. Malheureusement, cela a abouti à un algorithme déficitaire, même si l'idée de base était assez bonne. Dans les prochains articles, nous poursuivrons notre exploration de l'analyse quantitative.

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

Fichiers joints |
Installation de MetaTrader 5 et d'autres applications MetaQuotes sur HarmonyOS NEXT Installation de MetaTrader 5 et d'autres applications MetaQuotes sur HarmonyOS NEXT
Installez facilement MetaTrader 5 et d'autres applications MetaQuotes sur les appareils HarmonyOS NEXT à l'aide de DroiTong. Un guide détaillé étape par étape pour votre téléphone ou votre ordinateur portable.
Python, ONNX et MetaTrader 5 : Création d'un modèle RandomForest avec RobustScaler et PolynomialFeatures pour le pré-traitement des données Python, ONNX et MetaTrader 5 : Création d'un modèle RandomForest avec RobustScaler et PolynomialFeatures pour le pré-traitement des données
Dans cet article, nous allons créer un modèle de forêt aléatoire (random forest) en Python, entraîner le modèle et le sauvegarder en tant que pipeline ONNX avec un pré-traitement des données. Ensuite, nous utiliserons le modèle dans le terminal MetaTrader 5.
Comment créer un indicateur Canal de Donchian (Donchian Channel) personnalisé avec MQL5 Comment créer un indicateur Canal de Donchian (Donchian Channel) personnalisé avec MQL5
Il existe de nombreux outils techniques permettant de visualiser un canal autour des prix. L'un de ces outils est l'indicateur du Canal de Donchian, ou Donchian Channel en anglais. Dans cet article, nous allons apprendre comment créer l'indicateur Donchian Channel et comment le négocier en tant qu'indicateur personnalisé à l'aide de l'EA.
Modèles prêts à l'emploi pour inclure des indicateurs dans les Expert Advisors (Partie 3) : Indicateurs de tendance Modèles prêts à l'emploi pour inclure des indicateurs dans les Expert Advisors (Partie 3) : Indicateurs de tendance
Dans cet article de référence, nous examinerons les indicateurs standard de la catégorie Indicateurs de Tendance. Nous créerons des modèles prêts à l'emploi pour l'utilisation d'indicateurs dans les EA - déclaration et définition des paramètres, initialisation et dé-initialisation de l'indicateur, ainsi que l’obtention des résultats et des signaux à partir des buffers des indicateurs dans les EA.