void ArrayPrint( const void& array[], // Tableau à imprimer uint digits=_Digits, // Nombre de décimales const string separator=NULL, // Le séparateur entre les valeurs des champs de la structure ulong start=0, // L'indice du premier élément à imprimer ulong count=WHOLE_ARRAY, // Le nombre d'éléments à imprimer ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN );ArrayPrint n'imprime pas tous les champs d'une structure dans les journaux – les champs du tableau et les champs pointeurs vers les objets sont passés. Si vous désirez imprimer tous les champs de la structure, vous devrez utiliser une fonction personnalisée pour imprimer en masse avec le format désiré.
//--- Affiche les valeurs des 10 dernières barres MqlRates rates[]; if(CopyRates(_Symbol,_Period,1,10,rates)) { ArrayPrint(rates); Print("Révision\n[time]\t[open]\t[high]\t[low]\t[close]\t[tick_volume]\t[spread]\t[real_volume]"); for(int i=0;i<10;i++) { PrintFormat("[%d]\t%s\t%G\t%G\t%G\t%G\t%G\t%G\t%I64d\t",i, TimeToString(rates[i].time,TIME_DATE|TIME_MINUTES|TIME_SECONDS), rates[i].open,rates[i].high,rates[i].low,rates[i].close, rates[i].tick_volume,rates[i].spread,rates[i].real_volume); } } else PrintFormat("CopyRates a échoué, code d'erreur=%d",GetLastError()); //--- Un exemple de journal /* [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.11930 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 Vérification [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.1193 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 */
void OnStart() { int arr[]; //--- Quantité de mémoire utilisée initialement Print("Taille du tableau :",ArraySize(arr)," Mémoire utilisée :",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- Quantité de mémoire utilisée pour le tableau de taille 1 avec une réserve ArrayResize(arr,1,1024*1024); Print("Taille du tableau :",ArraySize(arr)," Mémoire utilisée :",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- Après l'augmentation du tableau, la quantité de mémoire utilisée ne changera pas grâce à la réserve ArrayResize(arr,1024*512,1024*1024); Print("Taille du tableau :",ArraySize(arr)," Mémoire utilisée :",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- Après la réduction du tableau, la taille de la mémoire ne changera pas non plus ArrayResize(arr,1); Print("Taille du tableau :",ArraySize(arr)," Mémoire utilisée :",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- La mémoire non utilisée ne sera pas libérée après la suppression de la réserve ArrayResize(arr,1,-1); Print("Taille du tableau :",ArraySize(arr)," Mémoire utilisée :",MQLInfoInteger(MQL_MEMORY_USED)," MB"); }
#include <Graphics/Graphic.mqh> double Func1(double x) { return MathPow(x,2); } double Func2(double x) { return MathPow(x,3); } double Func3(double x) { return MathPow(x,4); } void OnStart() { GraphPlot(Func1,Func2,Func3,-2,2,0.05,CURVE_LINES); }Le résultat :
#include <Math/Stat/Binomial.mqh> #include <Graphics/Graphic.mqh> void OnStart(void) { double vars[101]; double results[101]; const int N=2000; //--- MathSequence(0,N,20,vars); MathProbabilityDensityBinomial(vars,N,M_PI/10,true,results); ArrayPrint(results,4); GraphPlot(results); //--- }Le résultat :
Mise à jour de la documentation.
Ajout d'infobulles pour les boutons Buy, Sell et Close dans les boîtes de dialogue de trading. Les infobulles contiennent des informations sur l'instrument sur le point d'être acheté ou vendu, pour aider les débutants à comprendre le processus de trading.
Une version MQL5 de la bibliothèque d'analyse numérique ALGLIB a été inclue dans la Bibliothèque Standard.
Fonctions de la Bibliothèque
Comment l'Utiliser
Les fichiers de ALGLIB sont situés dans \MQL5\Include\Math\Alglib. Pour utiliser les fonctions, incluez le fichier principal de la bibliothèques dans votre programme :
#include <Math\Alglib\alglib.mqh>
Des fonctions de statistiques mathématiques ont été inclues dans la Bibliothèque Standard. MQL5 fournit maintenant la fonctionnalité du langage R, qui est l'un des meilleurs outils pour le traitement et l'analyse de données statistiques.
Fonctions de la Bibliothèque
La bilbliothèque statistique contient des fonctions de calcul des caractéristiques statistiques des données, mais aussi des fonctions d'opérations avec les distributions statistiques :
Comment l'Utiliser
Les fichiers de la bilbiothèque statistique sont situés dans \MQL5\Include\Math\Stat. Pour utiliser cette bibliothèque, incluez dans votre programme les fichiers des fonctions désirées, par exemple :
#include <Math\Stat\Binomal.mqh> #include <Math\Stat\Cauchy.mqh>
La description détaillée des fonctions de la bibliothèque est disponible dans l'article Distributions Statistiques en MQL5 - Profiter du Meilleur de R.
La version MQL5 de la bibliothèque Fuzzy a été inclue dans la Bibliothèque Standard. La bibliothèque Fuzzy implémente les systèmes d'inférence floue Mamdani et Sugeno.
Fonctions de la Bibliothèque
Comment l'Utiliser
Les fichiers de la bibliothèque Fuzzy sont situés dans \MQL5\Include\Math\Fuzzy. Pour utiliser cette bibliothèque, incluez dans votre programme les fichiers des fonctions désirées, par exemple :
#include <Math\Fuzzy\mamdanifuzzysystem.mqh> #include <Math\Fuzzy\sugenofuzzysystem.mqh>
Une description détaillée des fonctions de la bibliothèque est disponible dans Code Base : Fuzzy - bibliothèque de développement des modèles flous
long FileLoad( const string filename, // [in] Nom du fichier void &buffer[], // [out] Un tableau qui sera rempli par le fichier lu uint common_flag=0 // [in] 0 - recherche du fichier dans le répertoire Files du terminal, FILE_COMMON - recherche dans le répertoire commun des terminaux ); bool FileSave( const string filename, // [in] Nom du fichier const void &buffer[], // [in] Le tableau à sauvegarder dans un fichier uint common_flag=0 // [in] 0 - crée un fichier dans le répertoire Files du terminal, FILE_COMMON - crée le fichier dans le répertoire commun des terminaux );Exemple d'écriture des ticks dans un fichier et de relecture du fichier :
//--- paramètres d'entrée input int ticks_to_save=1000; // Nombre de ticks //+------------------------------------------------------------------+ //| Fonction de démarrage du programme | //+------------------------------------------------------------------+ void OnStart() { string filename=_Symbol+"_ticks.bin"; MqlTick ticks[]; //--- int copied=CopyTicks(_Symbol,ticks,COPY_TICKS_ALL,0,ticks_to_save); if(copied!=-1) { PrintFormat(" CopyTicks(%s) a copié %d ticks",_Symbol,copied); //--- Si l'historique des ticks est synchronisé, le code d'erreur est égal à zéro if(!GetLastError()==0) PrintFormat("%s : les ticks ne sont pas synchronisés. Erreur=",_Symbol,copied,_LastError); //--- Ecriture des ticks dans un fichier if(!FileSave(filename,ticks,FILE_COMMON)) PrintFormat("FileSave() a échoué, erreur=%d",GetLastError()); } else PrintFormat("Echec de CopyTicks(%s), Erreur=",_Symbol,GetLastError()); //--- Relecture des ticks depuis le fichier ArrayFree(ticks); long count=FileLoad(filename,ticks,FILE_COMMON); if(count!=-1) { Print("Time\tBid\tAsk\tLast\tVolume\tms\tflags"); for(int i=0;i<count;i++) { PrintFormat("%s.%03I64u:\t%G\t%G\t%G\t%I64u\t0x%04x", TimeToString(ticks[i].time,TIME_DATE|TIME_SECONDS),ticks[i].time_msc%1000, ticks[i].bid,ticks[i].ask,ticks[i].last,ticks[i].volume,ticks[i].flags); } } }
//--- Bougies dessinées avec la même couleur #property indicator_label1 "Bougies à une couleur" #property indicator_type1 DRAW_CANDLES //--- Une seule couleur est spécifiée, donc toutes les bougies ont la même couleur #property indicator_color1 clrGreenSi deux couleurs sont spécifiées, une couleur est utilisée pour les contours de la bougie, l'autre pour son corps.
//--- La couleur des bougies diffère de la couleur des ombres #property indicator_label1 "Bougies à deux couleurs" #property indicator_type1 DRAW_CANDLES //--- Les contours des bougies et les ombres sont verts, le corps est blanc #property indicator_color1 clrGreen,clrWhiteSi trois couleurs sont spécifiées, une couleur est utilisée pour les contours de la bougie, les deux autres couleurs sont utilisées pour le corps des bougies montantes et descendantes.
//--- La couleur des bougies diffère de la couleur des ombres #property indicator_label1 "Bougies à une couleur" #property indicator_type1 DRAW_CANDLES //--- Les contours des bougies et les ombres sont verts, le corps d'une bougie haussière est blanc, celui d'une bougie baissière est rouge #property indicator_color1 clrGreen,clrWhite,clrRedLe style DRAW_CANDLES permet de définir des couleurs personnalisées pour la bougie. Toutes les couleurs peuvent également être changées dynamiquement lorsque l'indicateur est en cours d'exécution, en utilisant la fonction PlotIndexSetInteger(drawing_index_DRAW_CANDLES, PLOT_LINE_COLOR, modifier_number, couleur) où modifier_number peut avoir les valeurs suivantes :
//--- Définition de la couleur des bordures et des ombres PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrBlue); //--- Définition de la couleur du corps d'une bougie haussière PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,clrGreen); //--- Définition de la couleur du corps d'une bougie baissière PlotIndexSetInteger(0,PLOT_LINE_COLOR,2,clrRed);
Documentation mise à jour.
class CFoo final { //--- corps de la classe }; class CBar : public CFoo { //--- corps de la classe };Lors de la tentative d'héritage d'une classe ayant le modificateur 'final' comme ci-dessus, le compilateur affiche une erreur :
class CFoo { void virtual func(int x) const { } };La méthode est surchargée dans la classe héritée :
class CBar : public CFoo { void func(short x) { } };Mais le type de l'argument est changé par erreur de 'int' en 'short'. En fait, la surcharge de la méthode au lieu de sa spécialisation est effectuée dans ce cas. Tout en se conformant à l'algorithme de surcharge de la définition d'une fonction, le compilateur peut dans certains cas sélectionner une méthode définie dans la classe de base au lieu de celle spécialisée.
class CBar : public CFoo { void func(short x) override { } };Si la signature de la méthode est changée pendant la spécialisation, le compilateur ne peut pas trouver la méthode de la classe parent ayant la même signature, provoquant l'erreur de compilation :
class CFoo { void virtual func(int x) final { } }; class CBar : public CFoo { void func(int) { } };Lors de la tentative de spécialisation d'une méthode ayant le modificateur 'final' comme ci-dessus, le compilateur affiche une erreur :
Documentation mise à jour.
class CFoo { }; class CBar { }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { void *vptr[2]; vptr[0]=new CFoo(); vptr[1]=new CBar(); //--- for(int i=0;i<ArraySize(vptr);i++) { if(dynamic_cast<CFoo *>(vptr[i])!=NULL) Print("CFoo * object at index ",i); if(dynamic_cast<CBar *>(vptr[i])!=NULL) Print("CBar * object at index ",i); } CFoo *fptr=vptr[1]; // Will return an error while casting pointers, vptr[1] is not an object of CFoo } //+------------------------------------------------------------------+
String text="Bonjour"; ushort symb=texte[0];// retournera le code de symbole 'H'
Mise à jour de la documentation.
Tester : Correction du calcul des commissions comme un pourcentage annuel pendant le test.
Après deux mois de test public, la version web de la plateforme multi-actifs MetaTrader 5 a été publiée officiellement. Elle permet de trader le Forex et les bourses depuis n'importe quel navigateur et n'importe quel système d'exploitation. Seule une connexion Internet est nécessaire, aucune installation de logiciel n'est demandée.
L'application combine les principaux avantages des versions de bureau (haute vitesse, support de plusieurs marchés et fonctions étendues de trading) avec l'aspect pratique de la nature multi-plateformes du terminal web. La fonctionnalité principale de la nouvelle version est le Depth of Market, qui n'était pas présent dans la version beta.
La plateforme web permet aux traders d'effectuer des analyses
techniques et des opérations de trading comme dans la version de bureau.
La plateforme web fournit les fonctionnalités suivantes :
Il est maintenant plus facile de transférer les certificats SSL depuis la version de bureau vers la version mobile. Vous n'avez plus besoin d'iTunes pour le faire.
MetaTrader 5 vous permet d'ajouter une protection supplémentaire à votre compte en utilisant un certificat. Sans le certificat, la connexion est impossible. Si le certificat a été créé sur la version de bureau, vous devez le transférer pour pouvoir vous connecter à votre compte depuis votre appareil mobile.
Pour cela, ouvrez la plateforme de bureau, faites un clic droit sur le compte désiré dans la fenêtre Navigator, et sélectionnez Transfert. Définissez le mot de passe du certificat qui ne sera connu que par vous, ouvrez la plateforme mobile et connectez-vous à votre compte. Il vous sera alors immédiatement demandé d'importer le certificat.
De plus, la dernière version inclut la procédure de migration pour les comptes transférés depuis MetaTrader 4. Si votre compte a été transféré vers la plateforme de 5ème génération, vous serez chaleureusement accueilli, les dernières fonctionnalités vous sont présentées et il vous est proposé de changer votre mot de passe.
Avant |
Après |
|
---|---|---|
Déclencheur | Bid/Ask pour tous les types d'Ordres en Attente et SL/TP |
Bid/Ask pour les Ordres Limit Last pour les ordres Stop, Stop-Limit et SL/TP |
Exécution | Le prix spécifié dans l'ordre pour tous les types d'Ordres en Attente et les SL/TP |
Bid/Ask au moment du déclenchement de l'ordre pour tous les types d'Ordres en Attente et les SL/TP |
Considérons l'exemple sur le symbole Si-6.16. Un nouvel ordre Buy Stop au prix de déclenchement = 72580 est défini alors que les prix actuels sont : Bid=72570, Ask=72572, Last=72552. De nouveaux prix courants sont reçus dans un flux de prix :
Le déclencheur pour les Ordres Stops des instruments échangés est le prix Last. Donc le prix Last=72580 reçu dans le flux active l'ordre Buy Stop. Dans les versions précédentes, le même prix était utilisé pour exécuter cet ordre. Ce comportement est incorrect car il n'y a plus de prix Ask=72580 sur la marché pour exécuter la transaction Buy.
Correction d'erreurs reportées dans les journaux des crash.
La version beta de la Plateforme Web MetaTrader 5 a été publiée. Le nouveau produit combine l'aspect pratique et la nature multi-plateformes du terminal web avec les avantages de la version de bureau de MetaTrader 5 – vitesse, support de plusieurs marchés et fonctions étendues de trading.
La plateforme web MetaTrader 5 est disponible sur la MQL5.community et elle permet aux traders d'effectuer des opérations de trading sur les marchés financiers depuis n'importe quel navigateur et n'importe quel système d'exploitation, incluant Windows, Mac et Linux. Vous n'avez besoin que d'une connexion internet. Aucun logiciel supplémentaire n'est requis.
Les fonctionnalités suivantes sont disponibles dans la version beta :
Système de compensation
Avec ce système, vous ne pouvez avoir qu'une seule position pour un symbole au même moment :
Ce qui a causé la transaction opposée n'importe pas - un ordre au marché exécuté ou un ordre en attente déclenché.
L'exemple ci-dessous montre l'exécution de deux transactions Buy sur l'EURUSD de 0,5 lots chacunes :
L'exécution des deux transactions a résulté en une seule position d'1 lot.
Système de couverture
Avec ce système, vous pouvez avoir plusieurs positions ouvertes d'un seul et même symbole, incluant des positions opposées.
Si vous avez une position ouverte pour un symbole et que vous exécutez une nouvelle transaction (ou qu'un ordre en attente est déclenché), une nouvelle position est ouverte en supplément. Votre position actuelle ne change pas.
L'exemple ci-dessous montre l'exécution de deux transactions Buy sur l'EURUSD de 0,5 lots chacunes :
L'exécution de ces transactions a résulté dans l'ouverture de deux positions séparées.
Nouveau type d'opération - Close By
Un nouveau type d'opération de trading a été ajouté pour les comptes de couverture - fermer une position par une position opposée. Cette opération permet de fermer deux positions dans des directions opposées d'un même symbole. Si les positions opposées ont des nombres de lots différents, un seul des deux ordres reste ouvert. Son volume sera égal à la différence des lots des positions fermées, tandis que la direction de la position et le prix d'ouverture correspondront (en volume) à la plus grande des positions fermées.
Comparée à une fermeture simple des deux positions, la fermeture par une position opposée permet aux traders d'économiser un spread :
Dans ce dernier cas, un ordre "close by" est placé. Les tickets des positions fermées sont spécifiés dans leurs commentaires. Une paire de positions opposées est fermée par deux transactions "out by". Le profit/perte résultant de la fermeture des deux positions n'est spécifié que dans une seule transaction.
Les tickets des ordres et des positions (incluant l'historique des ordres) ne sont pas conservés pendant l'import, car un enregistrement de l'historique de MetaTrader 4 peut être importé en 4 opérations d'historique dans MetaTrader 5. Les nouveaux tickets sont assignés à tous les enregistrements de trading.
Les numéros des comptes peuvent être préservés ou remplacés suivant la façon dont le courtier les importe.
class CAnimal { public: CAnimal(); // Constructeur virtual void Sound() = 0; // Une fonction virtuelle pure private: double m_legs_count; // Le nombre de pattes de l'animal };Ici Sound() est une fonction virtuelle pure, car elle est déclarée avec le spécificateur de fonction virtuelle pure (=0).
class CAnimal { public: virtual void Sound()=NULL; // méthode PURE, doit être surchargée dans la classe dérivée, CAnimal est maintenant abstraite et ne peut pas être créée }; //--- Dérivée d'une classe abstraite class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // la méthode pure est surchargée, CCat n'est pas abstraite et peut être créée }; //--- exemples de mauvaises utilisations new CAnimal; // Erreur de 'CAnimal' - le compilateur retourne l'erreur "ne peut pas instantier une classe abstraite" CAnimal some_animal; // Erreur de 'CAnimal' - le compilateur retourne l'erreur "ne peut pas instancier une classe abstraite" //--- exemples d'utilisations correctes new CCat; // aucune erreur - la classe CCat n'est pas abstraite CCat cat; // aucune erreur - la classe CCat n'est pas abstraiteRestrictions concernant les classes abstraites
//+------------------------------------------------------------------+ //| Une classe de base abstraite | //+------------------------------------------------------------------+ class CAnimal { public: //--- une fonction virtuelle pure virtual void Sound(void)=NULL; //--- fonction void CallSound(void) { Sound(); } //--- constructeur CAnimal() { //--- un appel explicite à la méthode virtuelle Sound(); //--- un appel implicite (en utilisant une troisième fonction) CallSound(); //--- un constructeur et/ou un destructeur appelle toujours ses propres fonctions, //--- même si elles sont virtuelles et surchargées par une fonction appellée dans une classe dérivée //--- si la fonction appelée est purement virtuelle //--- l'appel génère une erreur critique d'exécution "appel à une fonction virtuelle pure" } };Cependant, les constructeurs et les destructeurs des classes abstraites peuvent appeler d'autres fonctions membres.
typedef int (*TFunc)(int,int);TFunc est maintenant un type, et il est possible de déclarer une variable pointant vers la fonction :
TFunc func_ptr;La variable func_ptr peut stocker l'adresse de la fonction pour la déclarer par la suite :
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // erreur : neg n'est pas du type int (int,int) Print(func_ptr(10)); // erreur : il devrait y avoir 2 paramètresLes pointeurs de fonctions peuvent être stockés et passés comme paramètres. Vous ne pouvez pas avoir un pointeur vers une méthode de classe non statique.
ulong PositionGetTicket( int index // index dans la liste des positions );
bool PositionSelectByTicket(
ulong ticket // ticket de la position
);
Système de compensation
Avec ce système, vous pouvez n'avoir qu'une seule position commune pour un symbole à la fois :
Ce qui a causé la transaction opposée n'importe pas - un ordre au marché exécuté ou un ordre en attente déclenché.
L'exemple ci-dessous montre l'exécution de deux transactions Buy sur l'EURUSD de 0.5 lots chacunes :
L'exécution des deux transactions a résulté en une seule position d'1 lot.
Système de couverture
Avec ce système, vous pouvez avoir plusieurs positions ouvertes d'un seul et même symbole, incluant des positions opposées.
Si vous avez une position ouverte pour un symbole et que vous exécutez une nouvelle transaction (ou qu'un ordre en attente est déclenché), une nouvelle position est ouverte en supplément. Votre position actuelle ne change pas.
L'exemple ci-dessous montre l'exécution de deux transactions Buy sur l'EURUSD de 0.5 lots chacunes :
L'exécution de ces transactions a résulté dans l'ouverture de deux positions séparées.
Nouveau type d'opération - Close By
Un nouveau type d'opération de trading a été ajouté pour les comptes de couverture - fermer une position par une position opposée. Cette opération permet de fermer deux positions dans des directions opposées d'un même symbole. Si les positions opposées ont des nombres de lots différents, un seul des deux ordres reste ouvert. Son volume sera égal à la différence des lots des positions fermées, tandis que la direction de la position et le prix d'ouverture correspondront (en volume) à la plus grande des positions fermées.
Comparée à une fermeture simple des deux positions, la fermeture par une position opposée permet aux traders d'économiser un spread :
Dans ce dernier cas, un ordre "close by" est placé. Les tickets des positions fermées sont spécifiés dans leurs commentaires. Une paire de positions opposées est fermée par deux transactions "out by". Le profit/perte résultant de la fermeture des deux positions n'est spécifié que dans une seule transaction.
class CAnimal { public: CAnimal(); // constructeur virtual void Sound() = 0; // fonction virtuelle pure private: double m_legs_count; // nombre de pattes de l'animal };Ici Sound() est une fonction virtuelle pure car elle est déclarée avec le spécificateur de fonction virtuelle pure (=0).
class CAnimal { public: virtual void Sound()=NULL; // méthode pure, doit être surchargée dans la classe dérivée, CAnimal est maintenant abstraite et ne peut pas être créée }; //--- descendant de la classe abstraite class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // la méthode pure est surchargée, CCat n'est pas abstraite et peut être créée }; //--- exemples de mauvaises utilisations new CAnimal; // Erreur de 'CAnimal' - le compilateur retourne l'erreur "ne peut pas instantier une classe abstraite" CAnimal some_animal; // Erreur de 'CAnimal' - le compilateur retourne l'erreur "ne peut pas instancier une classe abstraite" //--- exemples d'utilisations correctes new CCat; // aucune erreur - la classe CCat n'est pas abstraite CCat cat; // aucune erreur - la classe CCat n'est pas abstraiteRestrictions concernant les classes abstraites
//+------------------------------------------------------------------+ //| Une classe de base abstraite | //+------------------------------------------------------------------+ class CAnimal { public: //--- une fonction virtuelle pure virtual void Sound(void)=NULL; //--- fonction void CallSound(void) { Sound(); } //--- constructeur CAnimal() { //--- un appel explicite à la méthode virtuelle Sound(); //--- un appel implicite (en utilisant une troisième fonction) CallSound(); //--- un constructeur et/ou un destructeur appelle toujours ses propres fonctions, //--- même si elles sont virtuelles et surchargées par une fonction appellée dans une classe dérivée //--- si la fonction appelée est purement virtuelle //--- l'appel génère une erreur critique d'exécution "appel à une fonction virtuelle pure" } };Cependant, les constructeurs et les destructeurs des classes abstraites peuvent appeler d'autres fonctions membres.
typedef int (*TFunc)(int,int);TFunc est maintenant un type, et il est possible de déclarer une variable pointant vers la fonction :
TFunc func_ptr;La variable func_ptr peut stocker l'adresse de la fonction pour la déclarer par la suite :
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // erreur : neg n'est pas du type int (int,int) Print(func_ptr(10)); // erreur : il devrait y avoir 2 paramètresLes pointeurs de fonctions peuvent être stockés et passés comme paramètres. Vous ne pouvez pas avoir un pointeur vers une méthode de classe non statique.
ulong PositionGetTicket( int index // index dans la liste des positions );
bool PositionSelectByTicket(
ulong ticket // ticket de la position
);
Le nouveau système de comptabilité d'une position est similaire à celle de MetaTrader 4, combiné avec tous les avantages de la plateforme de cinquième génération - exécution des ordres en utilisant plusieurs offres (y compris remplissage partiel), ordres stop-limit, etc.
Mettez maintenant à jour la plateforme pour voir comment fonctionne l'option de couverture. Lors de l'ouverture d'un nouveau compte de démonstration, activez l'option \ "Utiliser couverture \". L'option sera disponible si le serveur de votre courtier a été mis à jour et configuré.
Le nouveau système de comptabilité d'une position est similaire à celle de MetaTrader 4, combiné avec tous les avantages de la plateforme de cinquième génération - exécution des ordres en utilisant plusieurs offres (y compris remplissage partiel), ordres stop-limit, etc.
Mettez maintenant à jour la plateforme pour voir comment fonctionne l'option de couverture. Lors de l'ouverture d'un nouveau compte de démonstration, activez l'option "Utiliser couverture". L'option sera disponible si le serveur de votre courtier a été mis à jour et configuré.