Trademinator 3 : Montée des Machines de Trading
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) :
- 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).
- 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.
- 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.
- 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.
- 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:00 | 2 | USDCHF | Vente | 28.21 / 28.21 | 0.9321 | 2011.01.03 01:00 | plein | |||||
2011.01.03 03:00 | 3 | USDCHF | achat | 28.21 / 28.21 | 0.9365 | 2011.01.03 03:00 | plein | |||||
2011.01.03 06:00 | 4 | USDCHF | Vente | 24.47 / 24.47 | 0.9352 | 2011.01.03 06:00 | plein | |||||
2011.01.03 09:00 | 5 | USDCHF | achat | 24.47 / 24.47 | 0.9372 | 2011.01.03 09:00 | plein | |||||
2011.01.03 13:00 | 6 | USDCHF | Vente | 22.99 / 22.99 | 0.9352 | 2011.01.03 13:00 | plein | |||||
2011.01.03 16:00 | 7 | USDCHF | achat | 22.99 / 22.99 | 0.9375 | 2011.01.03 16:00 | plein | |||||
2011.01.03 18:00 | 8 | USDJPY | vente | 72.09 / 72.09 | 81.57 | 2011.01.03 18:00 | plein | |||||
2011.01.03 21:00 | 9 | USDJPY | achat | 72.09 / 72.09 | 81.66 | 2011.01.03 21:00 | plein | |||||
2011.01.04 01:00 | 10 | USDJPY | vente | 64.54 / 64.54 | 81.67 | 2011.01.04 01:00 | plein | |||||
2011.01.04 02:00 | 11 | USDJPY | achat | 64.54 / 64.54 | 81.78 | 2011.01.04 02:00 | plein | |||||
2011.10.20 21:00 | 12 | USDCHF | vente | 56.30 / 56.30 | 0.8964 | 2011.10.20 21:00 | plein | |||||
2011.10.21 12:00 | 13 | USDCHF | achat | 56.30 / 56.30 | 0.8908 | 2011.10.21 12:00 | plein | |||||
Deals | ||||||||||||
Heure | Deal | Symbole | Type | Direction | Volume | Prix | Commande | Commission | Swap | Bénéfice | Solde | Commentaire |
2011.01.01 00:00 | 1 | solde | 0.00 | 0.00 | 10 000.00 | 10 000.00 | ||||||
2011.01.03 01:00 | 2 | USDCHF | vente | en | 28.21 | 0.9321 | 2 | 0.00 | 0.00 | 0.00 | 10 000.00 | |
2011.01.03 03:00 | 3 | USDCHF | achat | Sortie | 28.21 | 0.9365 | 3 | 0.00 | 0.00 | -1 325.40 | 8 674.60 | |
2011.01.03 06:00 | 4 | USDCHF | vente | en | 24.47 | 0.9352 | 4 | 0.00 | 0.00 | 0.00 | 8 674.60 | |
2011.01.03 09:00 | 5 | USDCHF | achat | Sortie | 24.47 | 0.9372 | 5 | 0.00 | 0.00 | -522.19 | 8 152.41 | |
2011.01.03 13:00 | 6 | USDCHF | vente | en | 22.99 | 0.9352 | 6 | 0.00 | 0.00 | 0.00 | 8 152.41 | |
2011.01.03 16:00 | 7 | USDCHF | achat | Sortie | 22.99 | 0.9375 | 7 | 0.00 | 0.00 | -564.02 | 7 588.39 | |
2011.01.03 18:00 | 8 | USDJPY | vente | en | 72.09 | 81.57 | 8 | 0.00 | 0.00 | 0.00 | 7 588.39 | |
2011.01.03 21:00 | 9 | USDJPY | achat | Sortie | 72.09 | 81.66 | 9 | 0.00 | 0.00 | -794.53 | 6 793.86 | |
2011.01.04 01:00 | 10 | USDJPY | vente | en | 64.54 | 81.67 | 10 | 0.00 | 0.00 | 0.00 | 6 793.86 | |
2011.01.04 02:00 | 11 | USDJPY | achat | Sortie | 64.54 | 81.78 | 11 | 0.00 | 0.00 | -868.11 | 5 925.75 | |
2011.10.20 21:00 | 12 | USDCHF | vente | en | 56.30 | 0.8964 | 12 | 0.00 | 0.00 | 0.00 | 5 925.75 | |
2011.10.21 12:00 | 13 | USDCHF | achat | Sortie | 56.30 | 0.8908 | 13 | 0.00 | -3.78 | 3 539.29 | 9 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) :
- 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.
- 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.
- 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
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation