English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Trademinator 3 : Montée des Machines de Trading

Trademinator 3 : Montée des Machines de Trading

MetaTrader 5Trading | 12 janvier 2022, 14:53
122 0
Roman Zamozhnyy
Roman Zamozhnyy

Prologue

Il était une fois un lointain forum (MQL5) deux articles: «Genetic Algorithms -It’s Easy!" par joo et "Dr. Tradelove...» par moi ont été publiés. Dans le premier article, l’auteur nous a dotés d’un outil puissant pour optimiser tout ce dont vous avez besoin, y compris les stratégies de trading - un algorithme génétique implémenté au moyen du langage MQL5.

En utilisant cet algorithme, dans le deuxième article, j’ai tenté d’élaborer un Expert Advisor auto-optimisant basé sur celui-ci. L’article s’est achevé sur la formulation de la tâche suivante: créer un Expert Advisor (auto-optimisation, bien sûr), qui peut non seulement sélectionner les meilleurs paramètres pour un système de trading particulier, mais également choisir la meilleure stratégie de toutes les stratégies élaborées. Voyons si c’est possible, et si c’est le cas, alors comment.

Récits de Robots de Trading

Tout d’abord, nous formulons les exigences générales pour un Expert Advisor auto-optimisant.

Il devrait être en mesure de (sur la base de données historiques):

  • sélectionner la meilleure stratégie parmi celles décrites
  • choisir le meilleur instrument financier
  • choisir la meilleure taille de dépôt pour le trading avec correction de l’effet de levier
  • choisir les meilleurs paramètres d’indicateurs dans la stratégie sélectionnée

De plus, dans la vie réelle, il devrait être capable de:

  • ouvrir et clôturer des positions
  • choisir la taille de la position
  • décider si une nouvelle optimisation est nécessaire

La figure ci-dessous indique un diagramme schématique de l’Expert Advisor proposé.


Un schéma détaillé avec des limites se trouve dans le fichier joint Scheme_en.

En gardant à l’esprit qu’il est impossible de saisir l’immensité, nous introduisons des restrictions dans la logique Expert Advisor. Nous convenons que (IMPORTANT) :

  1. L’Expert Advisor prendra des décision en matière de trade à la suite de l’avènement d’unnouvelle barre(sur tout intervalle de temps que nous sélectionnons).
  2. Sur la base de p.1, mais sans s’y limiter, l’Expert Advisor clôturera les trades uniquement sur les signaux indicateurs n’utilisant pas Take Profit et Stop Loss et, par conséquent, n’utilisant pas Trailing Stop.
  3. La condition pour démarrer une nouvelle optimisation : un prélèvement du solde est supérieur à la valeur prédéfinie durant l’initialisation du niveau. Veuillez noter qu’il s’agit de ma condition personnelle et que chacun d’entre vous peut sélectionner sa condition spécifique.
  4. Une fonction de fitness modélise le trading sur l’historique et maximise le solde modélisé, à condition que le prélèvement relatif du solde des trades simulées soit inférieur à un certain niveau prédéfini. Notez également qu’il s’agit de ma fonction de fitness personnelle et que vous pouvez sélectionner votre fonction spécifique.
  5. Nous limitons le nombre de paramètres à optimiser, à l’exception des trois paramètres généraux (stratégie, instrument et part de dépôt), à cinq pour les paramètres des tampons indicateurs. Cette restriction suit logiquement depuis le nombre maximum des tampons d’indicateurpour des indicateurs intégrés techniques. Si vous envisagez de décrire les stratégies qui utilisent des indicateurs personnalisés avec un grand nombre de tampons d’indicateurs, modifiez simplement la variable OptParamCount dans le fichier main.mq5 à la quantité souhaitée.

Maintenant que les exigences sont spécifiées et les restrictions sélectionnées, vous pouvez regarder le code qui implémente tout cela.

Commençons par la fonction, où tout s’exécute.

void OnTick()
{
  if(isNewBars()==true)
  {
    trig=false;
    switch(strat)
    {
      case  0: {trig=NeedCloseMA()   ; break;};                      //The number of case strings must be equal to the number of strategies
      case  1: {trig=NeedCloseSAR()  ; break;};
      case  2: {trig=NeedCloseStoch(); break;};
      default: {trig=NeedCloseMA()   ; break;};
    }
    if(trig==true)
    {
      if(GetRelDD()>maxDD)                                           //If a balance drawdown is above the max allowed value:
      {
        GA();                                                        //Call the genetic optimization function
        GetTrainResults();                                           //Get the optimized parameters
        maxBalance=AccountInfoDouble(ACCOUNT_BALANCE);               //Now count the drawdown not from the balance maximum...
                                                                     //...but from the current balance
      }
    }
    switch(strat)
    {
      case  0: {trig=NeedOpenMA()   ; break;};                       //The number of case strings must be equal to the number of strategies
      case  1: {trig=NeedOpenSAR()  ; break;};
      case  2: {trig=NeedOpenStoch(); break;};
      default: {trig=NeedOpenMA()   ; break;};
    }
    Print(TimeToString(TimeCurrent()),";","Main:OnTick:isNewBars(true)",
          ";","strat=",strat);
  }
}

Qu’y a-t-il ici? Comme indiqué dans le diagramme, nous examinons chaque coche, s’il y a une nouvelle barre. S’il y a, alors, sachant quelle stratégie est maintenant choisie, nous appelons sa fonction spécifique pour vérifier s’il y a une position ouverte et la clôturer, si nécessaire. Admettons maintenant que la meilleure stratégie de percée soit SAR,respectivement, la fonction NeedCloseSAR sera appelée:

bool NeedCloseSAR()
{
  CopyBuffer(SAR,0,0,count,SARBuffer);
  CopyOpen(s,tf,0,count,o);
  Print(TimeToString(TimeCurrent()),";","StrategySAR:NeedCloseSAR",
        ";","SAR[0]=",SARBuffer[0],";","SAR[1]=",SARBuffer[1],";","Open[0]=",o[0],";","Open[1]=",o[1]);
  if((SARBuffer[0]>o[0]&&SARBuffer[1]<o[1])||
     (SARBuffer[0]<o[0]&&SARBuffer[1]>o[1]))
  {
    if(PositionsTotal()>0)
    {
      ClosePosition();
      return(true);
    }
  }
  return(false);
}

Toute fonction de fermeture de position doit être booléenne et renvoyer true lors de la clôture d’une position. Cela permet au bloc de code suivant de la fonction OnTick() de décider si une nouvelle optimisation est nécessaire:

    if(trig==true)
    {
      if(GetRelDD()>maxDD)                                           //If the balance drawdown is above the max allowed one:
      {
        GA();                                                        //Call the genetic optimization function
        GetTrainResults();                                           //Get optimized parameters
        maxBalance=AccountInfoDouble(ACCOUNT_BALANCE);                   //Now count the drawdown not from the balance maximum...
                                                                     //...but from the current balance
      }
    }

Obtenez le prélèvement de solde actuel et comparez-le avec le maximum autorisé. S’il a dépassé la valeur maximale, exécutez une nouvelle optimisation (GA()). La fonction GA(), à son tour, appelle le cœur de l’Expert Advisor - la fonction fitness FitnessFunction(int chromos) du module GAModule.mqh:

void FitnessFunction(int chromos)                                    //A fitness function for the genetic optimizer:...
                                                                     //...selects a strategy, symbol, deposit share,...
                                                                     //...parameters of indicator buffers;...
                                                                     //...you can optimize whatever you need, but...
                                                                     //...watch carefully the number of genes
{
  double ff=0.0;                                                     //The fitness function
  strat=(int)MathRound(Colony[GeneCount-2][chromos]*StratCount);     //GA selects a strategy
 //For EA testing mode use the following code...
  z=(int)MathRound(Colony[GeneCount-1][chromos]*3);                  //GA selects a symbol
  switch(z)
  {
    case  0: {s="EURUSD"; break;};
    case  1: {s="GBPUSD"; break;};
    case  2: {s="USDCHF"; break;};
    case  3: {s="USDJPY"; break;};
    default: {s="EURUSD"; break;};
  }
//..for real mode, comment the previous code and uncomment the following one (symbols are selected in the MarketWatch window)
/*
  z=(int)MathRound(Colony[GeneCount-1][chromos]*(SymbolsTotal(true)-1));//GA selects a symbol
  s=SymbolName(z,true);
*/
  optF=Colony[GeneCount][chromos];                                   //GA selects a deposit share
  switch(strat)
  {
    case  0: {ff=FFMA(   Colony[1][chromos],                         //The number of case strings must be equal to the number of strategies
                         Colony[2][chromos],
                         Colony[3][chromos],
                         Colony[4][chromos],
                         Colony[5][chromos]); break;};
    case  1: {ff=FFSAR(  Colony[1][chromos],
                         Colony[2][chromos],
                         Colony[3][chromos],
                         Colony[4][chromos],
                         Colony[5][chromos]); break;};
    case  2: {ff=FFStoch(Colony[1][chromos],
                         Colony[2][chromos],
                         Colony[3][chromos],
                         Colony[4][chromos],
                         Colony[5][chromos]); break;};
    default: {ff=FFMA(   Colony[1][chromos],
                         Colony[2][chromos],
                         Colony[3][chromos],
                         Colony[4][chromos],
                         Colony[5][chromos]); break;};
  }
  AmountStartsFF++;
  Colony[0][chromos]=ff;
  Print(TimeToString(TimeCurrent()),";","GAModule:FitnessFunction",
        ";","strat=",strat,";","s=",s,";","optF=",optF,
        ";",Colony[1][chromos],";",Colony[2][chromos],";",Colony[3][chromos],";",Colony[4][chromos],";",Colony[5][chromos]);
}

En fonction de la stratégie actuellement sélectionnée, le module de calcul de la fonction fitness, spécifique à une stratégie particulière, est appelé. Par exemple, l’ AG a choisi un stochastique, FFStoch () sera appelé, et les paramètres d’optimisation des tampons indicateurs lui seront transférés:

double FFStoch(double par1,double par2,double par3,double par4,double par5)
{
  int    b;
  bool   FFtrig=false;                                               //Is there an open position?
  string dir="";                                                     //Direction of the open position
  double OpenPrice;                                                  //Position Open price
  double t=cap;                                                      //Current balance
  double maxt=t;                                                     //Maximum balance
  double aDD=0.0;                                                    //Absolute drawdown
  double rDD=0.000001;                                               //Relative drawdown
  Stoch=iStochastic(s,tf,(int)MathRound(par1*MaxStochPeriod)+1,
                         (int)MathRound(par2*MaxStochPeriod)+1,
                         (int)MathRound(par3*MaxStochPeriod)+1,MODE_SMA,STO_CLOSECLOSE);
  StochTopLimit   =par4*100.0;
  StochBottomLimit=par5*100.0;
  dig=MathPow(10.0,(double)SymbolInfoInteger(s,SYMBOL_DIGITS));
  leverage=AccountInfoInteger(ACCOUNT_LEVERAGE);
  contractSize=SymbolInfoDouble(s,SYMBOL_TRADE_CONTRACT_SIZE);
  b=MathMin(Bars(s,tf)-1-count-MaxMAPeriod,depth);
  for(from=b;from>=1;from--)                                         //Where to start copying of history
  {
    CopyBuffer(Stoch,0,from,count,StochBufferMain);
    CopyBuffer(Stoch,1,from,count,StochBufferSignal);
    if((StochBufferMain[0]>StochBufferSignal[0]&&StochBufferMain[1]<StochBufferSignal[1])||
       (StochBufferMain[0]<StochBufferSignal[0]&&StochBufferMain[1]>StochBufferSignal[1]))
    {
      if(FFtrig==true)
      {
        if(dir=="BUY")
        {
          CopyOpen(s,tf,from,count,o);
          if(t>0) t=t+t*optF*leverage*(o[1]-OpenPrice)*dig/contractSize; else t=0;
          if(t>maxt) {maxt=t; aDD=0;} else if((maxt-t)>aDD) aDD=maxt-t;
          if((maxt>0)&&(aDD/maxt>rDD)) rDD=aDD/maxt;
        }
        if(dir=="SELL")
        {
          CopyOpen(s,tf,from,count,o);
          if(t>0) t=t+t*optF*leverage*(OpenPrice-o[1])*dig/contractSize; else t=0;
          if(t>maxt) {maxt=t; aDD=0;} else if((maxt-t)>aDD) aDD=maxt-t;
          if((maxt>0)&&(aDD/maxt>rDD)) rDD=aDD/maxt;
        }
        FFtrig=false;
      }
   }
    if(StochBufferMain[0]>StochBufferSignal[0]&&StochBufferMain[1]<StochBufferSignal[1]&&StochBufferMain[1]>StochTopLimit)
    {
      CopyOpen(s,tf,from,count,o);
      OpenPrice=o[1];
      dir="SELL";
      FFtrig=true;
    }
    if(StochBufferMain[0]<StochBufferSignal[0]&&StochBufferMain[1]>StochBufferSignal[1]&&StochBufferMain[1]<StochBottomLimit)
    {
      CopyOpen(s,tf,from,count,o);
      OpenPrice=o[1];
      dir="BUY";
      FFtrig=true;
    }
  }
  Print(TimeToString(TimeCurrent()),";","StrategyStoch:FFStoch",
        ";","K=",(int)MathRound(par1*MaxStochPeriod)+1,";","D=",(int)MathRound(par2*MaxStochPeriod)+1,
        ";","Slow=",(int)MathRound(par3*MaxStochPeriod)+1,";","TopLimit=",StochTopLimit,";","BottomLimit=",StochBottomLimit,
        ";","rDD=",rDD,";","Cap=",t);
  if(rDD<=trainDD) return(t); else return(0.0);
}

La fonction fitness du stochastique renvoie un solde simulé à la fonction principale, qui le transmettra à l’algorithme génétique. À un moment donné, l’AG décide de mettre fin à l’optimisation, et en utilisant la fonction GetTrainResults(), nous retournons les meilleures valeurs actuelles de la stratégie (par exemple - moyennes mobiles), le symbole, la part de dépôt et les paramètres des tampons d’indicateurs au programme de base, ainsi que la création d’indicateurs pour d’autres trades réels:

void GetTrainResults()                                               //Get the best parameters
{
  strat=(int)MathRound(Chromosome[GeneCount-2]*StratCount);          //Remember the best strategy
//For EA testing mode use the following code...
  z=(int)MathRound(Chromosome[GeneCount-1]*3);                       //Remember the best symbol
  switch(z)
  {
    case  0: {s="EURUSD"; break;};
    case  1: {s="GBPUSD"; break;};
    case  2: {s="USDCHF"; break;};
    case  3: {s="USDJPY"; break;};
    default: {s="EURUSD"; break;};
  }
//...for real mode, comment the previous code and uncomment the following one (symbols are selected in the MarketWatch window)
/*
  z=(int)MathRound(Chromosome[GeneCount-1]*(SymbolsTotal(true)-1));  //Remember the best symbol
  s=SymbolName(z,true);
*/
  optF=Chromosome[GeneCount];                                        //Remember the best deposit share
  switch(strat)
  {
    case  0: {GTRMA(   Chromosome[1],                                //The number of case strings must be equal to the number of strategies
                       Chromosome[2],
                       Chromosome[3],
                       Chromosome[4],
                       Chromosome[5]) ; break;};
    case  1: {GTRSAR(  Chromosome[1],
                       Chromosome[2],
                       Chromosome[3],
                       Chromosome[4],
                       Chromosome[5]) ; break;};
    case  2: {GTRStoch(Chromosome[1],
                       Chromosome[2],
                       Chromosome[3],
                       Chromosome[4],
                       Chromosome[5]) ; break;};
    default: {GTRMA(   Chromosome[1],
                       Chromosome[2],
                       Chromosome[3],
                       Chromosome[4],
                       Chromosome[5]) ; break;};
  }
  Print(TimeToString(TimeCurrent()),";","GAModule:GetTrainResults",
        ";","strat=",strat,";","s=",s,";","optF=",optF,
        ";",Chromosome[1],";",Chromosome[2],";",Chromosome[3],";",Chromosome[4],";",Chromosome[5]);
}

void GTRMA(double par1,double par2,double par3,double par4,double par5)
{
  MAshort=iMA(s,tf,(int)MathRound(par1*MaxMAPeriod)+1,0,MODE_SMA,PRICE_OPEN);
  MAlong =iMA(s,tf,(int)MathRound(par2*MaxMAPeriod)+1,0,MODE_SMA,PRICE_OPEN);
  CopyBuffer(MAshort,0,from,count,ShortBuffer);
  CopyBuffer(MAlong, 0,from,count,LongBuffer );
  Print(TimeToString(TimeCurrent()),";","StrategyMA:GTRMA",
        ";","MAL=",(int)MathRound(par2*MaxMAPeriod)+1,";","MAS=",(int)MathRound(par1*MaxMAPeriod)+1);
}

Maintenant, tout est de retour à l’endroit où tout fonctionne (OnTick()): sachant quelle stratégie est maintenant la meilleure, il est vérifié s’il est temps d’aller sur le marché:

bool NeedOpenMA()
{
  CopyBuffer(MAshort,0,0,count,ShortBuffer);
  CopyBuffer(MAlong, 0,0,count,LongBuffer );
  Print(TimeToString(TimeCurrent()),";","StrategyMA:NeedOpenMA",
        ";","LB[0]=",LongBuffer[0],";","LB[1]=",LongBuffer[1],";","SB[0]=",ShortBuffer[0],";","SB[1]=",ShortBuffer[1]);
  if(LongBuffer[0]>LongBuffer[1]&&ShortBuffer[0]>LongBuffer[0]&&ShortBuffer[1]<LongBuffer[1])
  {
    request.type=ORDER_TYPE_SELL;
    OpenPosition();
    return(false);
  }
  if(LongBuffer[0]<LongBuffer[1]&&ShortBuffer[0]<LongBuffer[0]&&ShortBuffer[1]>LongBuffer[1])
  {
    request.type=ORDER_TYPE_BUY;
    OpenPosition();
    return(false);
  }
  return(true);
}

La boucle s’est refermée.

Voyons comment cela fonctionne. Voici un rapport de 2011 sur la période de 1 heure avec quatre paires principales: EURUSD, GBPUSD, USDCHF, USDJPY:

Rapport du Testeur de Stratégie
InstaForex-Server (Build 567)
Paramètres
Expert Principal
Symbole: EURUSD
Période H1 (2011.01.01 - 2011.12.31)
Paramètres d’Entrée: trainDD=0.50000000
maxDD=0.20000000
Courtier Groupe de sociétés InstaForex
Devise USD
Dépôt initial: 10 000.00
Effet de levier 1:100
Résultats
Qualité du Récit: 100%
Barres: 6197 Tiques: 1321631
Bénéfice Net Total: -538.74 Bénéfice Brut 3 535.51 Perte Brute -4 074.25
Facteur de Bénéfice 0.87 Gain attendu -89.79 Niveau de Marge 85.71%
Facteur de Reprise -0.08 Ratio de Sharpe 0.07 Résultat OnTester : 0
Prélèvement de Solde :
Prélèvement de Solde Absolu: 4 074.25 Prélèvement de Solde Maximal: 4 074.25 (40.74%) Prélèvement de Solde Relatif : 40.74% (4 074.25)
Versement du Capital:
Versement Absolu du Capital: 4 889.56 Prélèvement maximal sur le Capital: 6 690.90 (50.53%) Prélèvement Relatif sur le Capital : 50.53% (6 690.90)
Total des trades : 6 Trades Courts (gain %): 6 (16.67%) Trades longs (gain %): 0 (0.00%)
Total des trades : 12 Bénéfice des Trades (% du total): 1 (16.67%) Trades en Perte (% du total): 5 (83.33%)
Le Plus Grand Trade à Bénéfice 3 535.51 Plus Grande Perte en Trade -1 325.40
Bénéfice Moyen du Trade: 3 535.51 Perte Moyenne du Trade: -814.85
Gains consécutifs maximaux 1 (3 535.51) Pertes consécutives maximales 5 (-4 074.25)
Bénéfice consécutif maximal (nombre) : 3 535.51 (1) Pertes consécutives maximales (nombre) -4 074.25 (5)
Moyenne de gains consécutifs : 1 Pertes consécutives maximales 5


 

Commandes
Heure d’ouverture Commande Symbole Type Volume Prix S / L T / P Heure État Commentaire
2011.01.03 01:002USDCHFVente 28.21 / 28.210.93212011.01.03 01:00plein
2011.01.03 03:003USDCHFachat28.21 / 28.210.93652011.01.03 03:00plein
2011.01.03 06:004USDCHFVente 24.47 / 24.470.93522011.01.03 06:00plein
2011.01.03 09:005USDCHFachat24.47 / 24.470.93722011.01.03 09:00plein
2011.01.03 13:006USDCHFVente 22.99 / 22.990.93522011.01.03 13:00plein
2011.01.03 16:007USDCHFachat22.99 / 22.990.93752011.01.03 16:00plein
2011.01.03 18:008USDJPYvente 72.09 / 72.0981.572011.01.03 18:00plein
2011.01.03 21:009USDJPYachat72.09 / 72.0981.662011.01.03 21:00plein
2011.01.04 01:0010USDJPYvente 64.54 / 64.5481.672011.01.04 01:00plein
2011.01.04 02:0011USDJPYachat64.54 / 64.5481.782011.01.04 02:00plein
2011.10.20 21:0012USDCHFvente 56.30 / 56.300.89642011.10.20 21:00plein
2011.10.21 12:0013USDCHFachat56.30 / 56.300.89082011.10.21 12:00plein
Deals
Heure Deal Symbole Type Direction Volume Prix Commande Commission Swap Bénéfice Solde Commentaire
2011.01.01 00:001solde0.000.0010 000.0010 000.00
2011.01.03 01:002USDCHFvente en28.210.932120.000.000.0010 000.00
2011.01.03 03:003USDCHFachatSortie28.210.936530.000.00-1 325.408 674.60
2011.01.03 06:004USDCHFvente en24.470.935240.000.000.008 674.60
2011.01.03 09:005USDCHFachatSortie24.470.937250.000.00-522.198 152.41
2011.01.03 13:006USDCHFvente en22.990.935260.000.000.008 152.41
2011.01.03 16:007USDCHFachatSortie22.990.937570.000.00-564.027 588.39
2011.01.03 18:008USDJPYvente en72.0981.5780.000.000.007 588.39
2011.01.03 21:009USDJPYachatSortie72.0981.6690.000.00-794.536 793.86
2011.01.04 01:0010USDJPYvente en64.5481.67100.000.000.006 793.86
2011.01.04 02:0011USDJPYachatSortie64.5481.78110.000.00-868.115 925.75
2011.10.20 21:0012USDCHFvente en56.300.8964120.000.000.005 925.75
2011.10.21 12:0013USDCHFachatSortie56.300.8908130.00-3.783 539.299 461.26
0.00 -3.78 -534.96 9 461.26
Copyright 2001-2011, MetaQuotes Software Corp.

Permettez-moi d’expliquer la zone indiquée sur le graphique (les explications sont tirées de l’analyse du journal) :

  1. Après le début de l’Expert Advisor, l’algorithme génétique a sélectionné la stratégie de percée SAR sur USDCHF avec une part du dépôt dans le trade égale à 28%, puis a négocié jusqu’au soir du 3 janvier, a perdu plus de 20% du solde et a commencé à se ré-optimiser.
  2. Ensuite, l’Expert Advisor a décidé de négocier la percée SAR sur USDJPY, mais avec la totalité du dépôt (98%). Naturellement, il ne pouvait pas négocier longtemps, et a donc commencé sa troisième optimisation dans la matinée du 4 janvier.
  3. Cette fois, il a décidé de négocier à nouveau une croix dorée et morte de moyennes mobiles sur USDCHF pour l’ensemble du dépôt. Et il a attendu la première croix morte jusqu’au 20 octobre, et l’a vendue au maximum, et a regagné tout ce qu’il a perdu. Après cela, jusqu’à la fin de l’année, l’Expert Advisor n’a pas vu de conditions favorables pour entrer sur le marché.

À suivre ?

Peut-on le poursuivre? Quelle serait la prochaine génération d’Expert Advisors ? L’Expert Advisor qui invente des stratégies et sélectionne la meilleure d’entre elles. Et de plus, il peut gérer l’argent, acheter du matériel plus puissant, un canal et ainsi de suite ...

Avertissement de risque :

Cette brève déclaration ne divulgue pas complètement tous les risques et autres aspects importants du trading de devises forex sur marge. Vous devez comprendre la nature du trading et l’étendue de votre exposition au risque. Vous devez examiner attentivement si le trading vous convient à la lumière de votre expérience, de vos objectifs, de vos ressources financières et d’autres circonstances pertinentes.

Le Forex n’est pas seulement un marché rentable, mais aussi un marché très risqué. En termes de trading sur marge, des fluctuations de change relativement faibles peuvent avoir un impact considérable sur le compte du trader, entraînant une perte égale au dépôt initial et à tous les fonds déposés en plus sur le compte pour maintenir les positions ouvertes. Vous ne devriez pas investir de l’argent que vous ne pouvez pas vous permettre de perdre. Avant de décider de trader, assurez-vous de bien comprendre tous les risques et de prendre en compte votre niveau d’expérience. Si nécessaire, demandez des conseils indépendants.

Licences:

Le module UGAlib.mqh est élaboré et distribué sous licence BSD par Andrey Dik aka joo.

L’Expert Advisor et les modules auxiliaires attachés à cet article sont élaborés et distribués sous licence BSD par l’auteur Roman Rich. Le texte de la licence est disponible dans le fichier Lic.txt.

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

Fichiers joints |
lic.txt (1.43 KB)
sheme_en.gif (147.11 KB)
gamodule.mqh (7.24 KB)
main.mq5 (4.99 KB)
musthave.mqh (7.79 KB)
strategyma.mqh (5.13 KB)
strategysar.mqh (4.09 KB)
strategystoch.mqh (6.04 KB)
ugalib.mqh (33.36 KB)
Sécurisation du code MQL5 : Protection par mot de passe, générateurs de clés, délais, licences à distance et techniques avancées de cryptage des clés de licence EA Sécurisation du code MQL5 : Protection par mot de passe, générateurs de clés, délais, licences à distance et techniques avancées de cryptage des clés de licence EA
La plupart des développeurs doit de sécuriser leur code. Cet article présentera différentes manières de protéger le logiciel MQL5 - il présente des méthodes pour fournir des fonctionnalités de licence aux scripts, aux Expert Advisors et aux indicateurs MQL5. Il couvre la protection par mot de passe, les générateurs de clés, la licence de compte, l'évaluation du délai et la protection à distance à l'aide d'appels MQL5-RPC.
Création d'Expert Advisors à l'aide de l'Assistant visuel d'Expert Advisor Création d'Expert Advisors à l'aide de l'Assistant visuel d'Expert Advisor
Expert Advisor Visual Wizard pour MetaTrader 5 fournit un environnement graphique très intuitif avec un ensemble complet de blocs de trading prédéfinis qui vous permettent de concevoir des Expert Advisors en quelques minutes. L'approche cliquer, glisser-déposer d'Expert Advisor Visual Wizard vous permet de créer des représentations visuelles des stratégies et des signaux de trading forex comme vous le feriez avec un crayon et du papier. Ces diagrammes de trading sont automatiquement analysés par le générateur de code MQL5 de Molanis qui les transforme en Expert Advisors prêts à l'emploi. L'environnement graphique interactif simplifie le processus de conception et élimine le besoin d'écrire du code MQL5.
Faites la Promotion de vos Projets de Développement à l'Aide des Bibliothèques EX5 Faites la Promotion de vos Projets de Développement à l'Aide des Bibliothèques EX5
Cacher les détails d'implémentation des classes/fonctions dans un fichier .ex5 vous permettra de partager vos algorithmes de savoir-faire avec d'autres développeurs, de mettre en place des projets communs et de les promouvoir sur le Web. Et tandis que l'équipe MetaQuotes ne ménage aucun effort pour amener la possibilité d'héritage direct des classes de la bibliothèque ex5, nous allons l'implémenter dès maintenant.
Prévision de séries chronologiques à l'aide du lissage exponentiel (suite) Prévision de séries chronologiques à l'aide du lissage exponentiel (suite)
Cet article vise à faire évoluer l'indicateur créé précédemment et traite brièvement d'une méthode d'estimation des intervalles de confiance des prévisions à l'aide du lancement et des quantiles. En conséquence, nous obtiendrons l'indicateur de prévision et les scripts à utiliser pour estimer l'exactitude des prévisions.