Un Exemple de Stratégie de Trading Axée sur les Différences de Fuseau Horaire sur Différents Continents
Introduction
J'avais un peu de temps libre et il était clair que cette fois je consacrerai du temps à étudier les marchés et à rechercher la divergence des cycles économiques et des indicateurs techniques. Vous pouvez voir les résultats de la recherche dans l'article suivant Création d'un Indicateur avec des Options de Contrôle Graphique. Mais ce n'étaient pas que des découvertes ! J'ai trouvé un phénomène d'une échelle encore plus grande, mais pour le comprendre, regardons notre monde en termes de fuseaux horaires (Fig. 1).
Figure 1. Fuseaux Horaires
Comme nous pouvons le constater, la journée commence différemment dans chaque pays et se poursuit à différentes heures, alors que nous voyons notre grand et vaste pays s'étendre sur près de 10 fuseaux horaires, tandis que l'océan Atlantique ne s'étend que sur 6 fuseaux horaires.
Quel est le modèle ici ? Examinons l'ordre d'ouverture des marchés dans les pays suivants : Japon, Australie, Chine, Russie. Au moment où les employés russes arrivent pour la première fois à leur bureau et commencent les opérations de trade, en Asie, il fait déjà nuit et lorsque la session européenne est ouverte, ils sont déjà clôturés.
C'est ici que le plaisir commence. Une fois le marché ouvert, les courtiers et les gestionnaires de fonds spéculatifs européens mettent leurs actifs sur le marché, et prennent des actions spéculatives ou concurrentes aux intérêts de leurs investisseurs. Non, c'est trop tôt pour la partie la plus intéressante, qui commence avec l'aube à Chicago, en rapport avec la moindre étendue de l'océan Atlantique, il arrive un moment où les gérants de la bourse de Chicago ouvrent leurs terminaux de trading et commencent à gérer leur capitale.
Arrêtons-nous en ce moment, à propos d'une moindre étendue de l'océan Atlantique. La session européenne ne s’est pas encore achevée (Fig. 1). Londres est séparée de Chicago par 8 fuseaux horaires, si l'on suppose que la journée de travail est de 8 heures + mettre 45 minutes pour les pauses cigarettes et une heure pour, ce qui prolonge le temps de 1,30 - 2 heures supplémentaires (ceux qui ont travaillé dans un bureau en savent).
C'est le moment où l'on gagne les actifs de marché des gérants européens et américains. J'ai peur de lister tous les zéros d'actifs à ce stade, les gestionnaires européens et américains commencent leur lutte pour le prix des bourses, et à ce stade, c'est un phénomène, comme le montre la figure 2.
Figure 2. Impulsion du marché
Les batailles financières remplissent le marché, les actifs changent de propriétaire à chaque seconde, mais ce n'est pas là que le marché s'arrête ! Une fois cette période terminée, un mouvement calme commence et se déplace dans le sens de la tendance actuelle. À ce stade, la fourchette élargit ses limites, puis les rétrécit à nouveau et continue de se déplacer dans la direction de la tendance principale.
Je suis sûr que vous avez remarqué que le prix du marché peut monter ou baisser, mais il se déplace toujours vers la droite.
2. Les organigrammes comme principale méthode d’élaboration d'un algorithme
Le premier bloc du programme "Start-Stop" est illustré en figure 3 :
Figure 3. Bloc "Start-Stop"
Ce bloc est utilisé pour désigner le début du programme, le début et la fin d'une fonction ou d'une autre procédure, telle qu'une initialisation et une désinitialisation. Le prochain bloc que nous examinerons est étiqueté « Données » et est illustré en figure 4.
Figure 4. Bloc "Données"
Le bloc "Données" permet de déterminer les paramètres spécifiés au démarrage du programme, ou les variables de sortie dans le cas MQL5. Cette unité assure également la fonction de destination des variables globales.
Ensuite, nous considérons un bloc couramment utilisé (99% des programmes en MQL utilisent cette méthode) - il est représenté en deux parties, qui marquent les limites d'un cycle. Examinez la Fig. 5:
Figure 5. Blocs de cycle
Des processus tels que l'attribution ou la comptabilité se déroulent généralement au sein de ces cycles, dont des exemples sont illustrés en figure 6.
Figure 6. Actions
Et nous ne devons pas oublier les blocs logiques - en figure 7 montre le bloc "solution".
Figure 7. Le bloc "Solution"
Le bloc "solution" peut également avoir plus de deux sorties s'il est situé à l'intérieur de l'opérateur du type "interrupteur qui dépend du nombre de placements". Cette unité disposera d’ un nombre correspondant de sorties.
Le bloc suivant induit des fonctions prédéfinies, telles que iMACD ou iRSA, ainsi que des fonctions personnalisées, définies ailleurs dans le programme ou dans la bibliothèque (Fig. 8).
Figure 8. Fonction
Et les deux derniers blocs implémentent uniquement des fonctions de service - comme les commentaires et la brèche (Fig. 9).
Figure 9. Blocs de services
Ce sont tous les types de blocs, qui peuvent être utilisés pour décrire n'importe quel programme écrit pour une machine ; ils sont tous clairs, simples et faciles à utiliser. Dans un premier temps d’élaboration, ils révèlent également les points faibles du système et élaborent des méthodes de leur élimination.
Vous êtes maintenant familiarisé avec cette méthode, cependant, je ne vous demande pas d'agir précisément selon ces schémas, mais connaissant simplement la valeur initiale des organigrammes, il est assez facile de comprendre un certain type de méthode de calcul. Cette méthode m'aide à formuler rapidement une idée, qui s'était rapidement propagée dans l'hémisphère gauche de mon cerveau, prête à s'échapper de l'hémisphère droit.
3. Construction de l'algorithme
Et donc, passons à la préparation de l'Expert Advisor sur la base de la stratégie de l'organigramme.
Le premier bloc aura besoin des paramètres d'entrée. Comme nous l'avons déterminé, il est primordial d'attendre le moment des principales batailles, c'est-à-dire 2 heures après la séance d'ouverture des Etats-Unis, lors de la clôture des marchés européens. Nous surveillerons cela sur l'horloge globale, c'est-à-dire à l'heure du terminal, et nous calculerons donc nous-mêmes l'heure d'ouverture.
Ensuite, nous déterminons la taille des positions et les niveaux de profits et pertes, qui à l'avenir ont le potentiel d'être optimisés. Une attention particulière sera portée au paramètre Magic number, car il sera utilisé par notre Expert Advisor pour déterminer sa commande et ses trades ouverts. Plus loin, nous ferons un ordre suiveur pour limiter le risque de nos positions, à nos observations.
Il y a un autre paramètre intéressant dont nous aurons besoin - un niveau de sécurité, selon lequel nous surveillerons la présence de nouvelles économiques importantes en ce moment, et si elles constituent ou non une menace, étant donné que la principale panique sur les marchés survient au sein de ces deux heures.
Figure 10. Paramètres d’entrée
//--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100;
Passons à la prochaine partie de la formation de la stratégie.
Nous devons déterminer si la session était une paire de devises et si les commandes ont été ou sont en train d'être établies. (Fig. 11).
Figure 11. Il est temps de trader
Comme vous pouvez le voir, l'algorithme donné est un programme fermé avec des paramètres d'entrée, des calculs terminés et des résultats de sortie. De pareils mini-programmes sont appelés fonctions et sont protégés du programme principal par encapsulation.
L'encapsulation est une barrière entre les programmes ou les parties du programme, qui est séparée par des méthodes, telles que Get et Set (get et set) pour les empêcher de traverser le territoire d'autres Gets' et Sets'. L'essence de ce processus réside dans le fait que les noms de variables peuvent être les mêmes dans les fonctions et dans le programme principal, mais lorsque la méthode Get essaie de prélever dans une cellule un nom de variable, elle sera confrontée à l'encapsulation, qui ne lui donnera accès qu'à un secteur particulier de cellules mémoire, allouées à cette fonction ou à ce programme.
La même chose s'applique à la méthode Set, mais contrairement à Get. Il définit la valeur dans la mémoire de la cellule sur le nom de la variable, et si les noms des variables dans le programme et dans la fonction coïncident, alors l'encapsulation ne permettra pas à la méthode Set d'attribuer les valeurs des variables à l'intérieur d'un autre programme ou fonction.
bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); }
Nous avons identifié la session requise et déterminé si nous avons défini des commandes ou non. Voyons ce qu'il faut faire ensuite.
Auparavant, nous avions remarqué que les fluctuations majeures interviennent 2 heures après la séance d'ouverture des États-Unis. On obtient 9 mesures de quinze minutes après l'ouverture de la séance américaine. Nous trouvons la fourchette maximale pour cette période et l'examinons attentivement - si cette variation est considérablement importante, il y a très probablement une panique généralisée sur le marché et les tendances futures sont difficiles à prévoir. Par conséquent, nous aurons besoin de certaines restrictions ici.
Lorsque le marché est calme, la session augmentera leur volatilité. Cela nous offrira l'occasion de déterminer l'écart maximum par rapport à la tendance principale et de placer les commandes-pièges à une distance de sécurité, ce qui fonctionnera car la tendance principale se poursuivra. Comme nous l'avons noté précédemment, le prix peut monter ou baisser, mais il se déplace toujours vers la droite. (Fig. 12).
Figure 12. Ensemble de commande d’algorithme
En façonnant le code du programme, faites attention au fait que le terminal de trading MetaTrader 5 ne permet pas de passer une commande proche du prix de la dernière transaction. Si à ce moment le cours tire un nouveau minimum ou maximum, nous défendrons notre position en reculant à une distance minimum par rapport au dernier cours de transaction, pour une détermination fiable d'une commande. Aussi, nous fixerons la durée de nos commandes avant la fin de la journée, car elles ne seront plus effectives par la suite.
void OnTick() { //--- if(time2trade(America+2,MagicNumber)) { int i; double Highest = 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high;//MathMax(,Highest); if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); // add to the current prices parameters of the minimum distance possible for the setting of orders Lowest=Lowest-StopLevel*Point(); // to ensure the maximum probability of the acceptance of our order 30> if((Higest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; BigDogBuy.action=TRADE_ACTION_PENDING; // Set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //if the stop loss is not set, then set by the strategy /s39> BigDogBuy.tp=Highest+TakeProfit*Point(); //set the take profit/s41> BigDogBuy.deviation=dev; //minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts //with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; // Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //Price, by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //set the take profit BigDogSell.deviation=dev; //Minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts ///with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } }
Les commandes sont passées, les pièges sont mis en place - il est maintenant temps de s'occuper de la réduction des risques de nos positions, appliquons la technologie de l’ ordre suiveur (ordre suiveur ).
Pour identifier notre position, nous utiliserons le nombre magique (MagicNumber) et décalerons le niveau de stop-loss lorsqu'il atteint un certain niveau de profit avec des variations de prix minimes. (Figure 13).
Figure 13. Implémentation de l’ ordre suiveur
Pour les différentes stratégies, l’ordre suiveur est mis en œuvre selon la méthode la plus simple, bien que dans certaines stratégies, il soit recommandé de ne pas utiliser un ordre suiveur , afin de ne pas empêcher le cours d'atteindre son objectif, ou de n'utiliser un tel mécanisme que pour le transfert des positions vers le no-loss. Mais dans cette stratégie, nous appliquons le mécanisme classique de déplacement du stop protecteur, en cas de changement de prix, dans notre direction pour un certain nombre d’évolution de prix minimaux.
//--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } }
Ensuite, rassemblez notre algorithme (Fig. 14).
Fig. 14. Assembler un algorithme
//+------------------------------------------------------------------+ //| BigDog_By_CoreWinTT.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100; int dev=30; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(time2trade(America+2,int(MagicNumber))) { int i; double Highest= 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high; if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); //--- add to the current prices the parameters of a minimum possible distance for the order set. Lowest=Lowest-StopLevel*Point(); //--- to ensure the maximum probability of the acceptance of our order. if((Highest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; ZeroMemory(BigDogBuy); ZeroMemory(BigDogSell); BigDogBuy.action=TRADE_ACTION_PENDING; //--- set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //--- Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //--- if the stop loss is not established, then we set by the strategy BigDogBuy.tp=Highest+TakeProfit*Point(); //--- set the take profit BigDogBuy.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //--- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; //-- Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //--- Price by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //-- Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //--- Set take profit BigDogSell.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //-- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; ZeroMemory(ResultBuy); ZeroMemory(ResultSell); OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } } //--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } } //+------------------------------------------------------------------+
Conclusion
Il existe de nombreux phénomènes de marché qui interviennent périodiquement et régulièrement et, lorsqu'ils sont analysés, peuvent nous assurer un certain avantage. De plus, peut-être que les traders expérimentés ont remarqué un chevauchement avec la célèbre stratégie de "BigDog", l'article ne le mentionne pas, et je l'ai fait exprès - afin que le lecteur réfléchisse à la façon dont ils sont vraiment préparés.
Sur Internet, vous pouvez vous familiariser avec les différentes variations de cette stratégie, cet article ne traite que du phénomène sur lequel cette stratégie est axée.
Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/59
- 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