Discussion de l'article "Rédaction d'un Expert Advisor à l'aide de l'approche de programmation orientée-objet MQL5" - page 2

[Supprimé]  
Yedelkin:
Si l'offre à l'ouverture sera à 1,2695, nous avons déjà 5 pips de perte automatiquement. Si dans le même temps le SL est de 50 pips selon l'idée du développeur, alors 45 pips supplémentaires doivent passer dans la direction défavorable avant qu'il ne se déclenche. C'est-à-dire que lorsque le stop loss est déclenché, le Bid ne devrait pas être à 1.2645, mais à 1.2650 ; et le Ask, respectivement, à 1.2655.

1. A propos de la perte de 5 pips à l'ouverture.

Vous avez raison à propos de la perte, si nous fermons la position au même moment (conditionnellement), nous aurons une perte du montant de l'écart, soit 5 pips.

Puisque les positions longues sont fermées au prix d'achat (counter).

Au moins logiquement dans ce cas nous devrions avoir cette perte (et c'est correct).

Ceci est également vrai pour la clôture avec un ordre de contrepartie. Quel résultat pensez-vous que nous obtiendrons lorsque l'ordre contraire est déclenché au prix de 1,2695 (qui est le prix d'achat en ce moment) ?

Vous n'allez tout de même pas prétendre que le prix d'ouverture des positions SHORT est Ask ?

2. Traitons de la clôture de l'UB

Nous nous souvenons que nous avons ouvert à l'achat à 1,27 (ce prix est maintenant un niveau BU pour nous).

Il est raisonnable de supposer que la clôture de la position BU se produira si le prix Bid atteint 1,27 (c'est-à-dire qu'il augmentera d'exactement 5 pips).

Vérifions notre affirmation en clôturant sur le CU à l'aide d'un contre-ordre. Le prix d'ouverture d'une telle position devrait être à 1,27, et comme nous le savons, les ordres de vente sont placés à l'offre. Actuellement, le cours acheteur est à 1,2695. Par conséquent, pour clôturer en BU, il faut passer 5 pips, donc il n'y a pas d'erreur dans les calculs et la déclaration est correcte.

3. à propos du SL et du TP

Deux règles s'appliquent ici :

а. Les positions longues ouvrent à la demande et ferment à l'offre ; les positions courtes ouvrent à l'offre et ferment à la demande.

б. La distance au TP et au SL est calculée à partir du prix d'ouverture, le calcul tient compte de la direction de la position.


En accord avec le deuxième énoncé, nous allons déterminer les prix SL et TP pour notre exemple. Au cours d'ouverture 1,27, le SL = 1,2650 et le TP = 1,28 (selon les conditions décrites ci-dessus).

Selon la première déclaration, le LONG (et dans l'exemple c'est le LONG) ouvrira à la condition que le Ask soit égal à 1,27 (et le Bid sera égal à 1,2695, basé sur le spread de 5 pips). 4.

4) Déterminons maintenant dans quelles conditions nos SL et TP seront déclenchés.

Notre position sera fermée lorsque l'une des conditions sera remplie (s'il n'y a pas d'autres facteurs) :

Sur TP - Si l'offre atteint 1,28 (100 pips à partir de 1,27), l'offre sera à ce moment-là à 1,2805 (la première déclaration et la taille de la règle de l'écart ici).

Vérifions notre déclaration en clôturant sur le TP à l'aide d'une contre-position. Le prix d'ouverture d'une telle position devrait être à 1,28, et comme nous le savons, les ordres de vente sont placés à l'offre. Actuellement, l'offre est à 1,2695. Par conséquent, pour clôturer sur le TP, il est nécessaire de passer 5 pips (pour couvrir les pertes sur le spread) + 100 pips pour fixer le profit.

Sur SL - Si le prix atteint le niveau SL, égal à 1,2650 comme nous nous en souvenons.


Comprenons maintenant quel prix sera atteint. Logiquement, il devrait s'agir du prix de l'offre (qui correspond au prix d'ouverture du contre-ordre).

Nous nous souvenons qu'à l'heure actuelle (selon la condition d'ouverture de la position), l'offre est à 1,2695. Il faut donc que le cours passe 45 pips pour que le SL se déclenche.

Ainsi, nous enregistrerons une perte égale au spread (5 pips) + 45 pips que le prix a eu le temps de passer avant que le SL ne se déclenche.

De ce point de vue, vous avez raison

Vérifions notre affirmation en clôturant sur le SL à l'aide d'une contre-position. Le prix d'ouverture d'une telle position devrait être à 1,2650, et comme nous le savons, les ordres de vente s'ouvrent à l'offre. Actuellement, l'offre est à 1,2695. Par conséquent, pour clôturer sur le SL, il est nécessaire de passer 45 pips. Lorsque le SL est déclenché, une perte de 50 pips sera enregistrée (5 pips sur le spread + 45 pips sur le mouvement contre nous).

PS

Mais de ce point de vue, cet exemple pour MQL4 n'est pas très clair pour moi.

int ticket;

  if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25)
    {
     ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point,"My order #"+counter,16384,0,Green);
     if(ticket<0)
       {
        Print("OrderSend failed with error #",GetLastError());
        return(0);
       }
    }

Plus précisément, je ne vois pas très bien sur la base de quelle logique et de quels énoncés SL et lui seul est pris en compte.

Mais sur la base de cet exemple (et uniquement de celui-ci), j'obtiens ce qui suit

//Exemple de base
ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,SL = Bid-Loss*Point,TP = Ask+Profit*Point,"My order #"+counter,16384,0,Green);
//Ordre d'ouverture d'une position de marché
ticket=OrderSend(Symbol(),OP_BUY,1,1.27,3,1.2645 = 1.2695-50*Point,1.28 = 1.27+100*Point);

Sur la base des valeurs Open = 1,27, SL = 1,2645 et TP = 1,28, je comprends ce qui suit :

1. La position est ouverte lorsque l'Ask atteint le prix de 1,27 (dans notre cas, il y est déjà) ;

2. Le niveau BU est situé au prix de 1,27 et pour clôturer dessus le cours du symbole (dans notre cas EUR) doit augmenter de la taille du spread (dans notre cas 5 pips) ;

3. Au moment de l'ouverture, nous obtenons immédiatement une perte du montant du spread (dans le cas où nous fermons la position IMMÉDIATEMENT), car la position ouverte, basée sur des déclarations logiques, doit être fermée avec un contre-ordre. Dans le code MQL4, une telle opération se présente comme suit

//Exemple de base
ticket=OrderSend(Symbol(),OP_SELL,1,Bid,3,0,0);
/Clore une position sur le marché avec un ordre de contrepartie
ticket=OrderSend(Symbol(),OP_SELL,1,1.2695,3,0,0);

4. Le TP est déclenché lorsque le prix atteint le niveau de 1,28. Logiquement, il devrait s'agir du prix d'offre, puisque l'ordre inverse est ouvert à ce prix (la transaction est exécutée lorsque le prix d'offre atteint la valeur de 1,28). Sur cette base, la clôture dans le code MQL4 devrait se présenter comme suit

/Clore une position TP avec un ordre de marché (contre-ordre)
ticket=OrderSend(Symbol(),OP_SELL,1,1.28,3,0,0);
//Fermeture d'une position avec un contre-ordre en attente (limiteur)
ticket=OrderSend(Symbol(),OP_SELLLIMIT,1,1.28,3,0,0);

5. Le SL sera déclenché après que le taux du symbole négocié (dans notre cas, l'EUR) ait chuté de 50 pips à partir du moment de l'ouverture.


Et maintenant, la chose la plus intéressante

Vérifions l'ouverture d'une position de marché en nous basant sur le même exemple de l'aide MQL4 (un exemple classique, qui a probablement été utilisé par des milliers de personnes).

Nous allons utiliser ce code pour le vérifier

//+------------------------------------------------------------------+
double PriceOpen,PriceSL,PriceTP;
int ticket;
//+------------------------------------------------------------------+
//Formuler les prix pour la commande
PriceOpen = Ask;
PriceSL   = Bid-500*Point;
PriceTP   = PriceOpen+1000*Point;
//Ordre d'ouverture d'une position de marché
ticket = OrderSend(Symbol(),OP_BUY,0.10,PriceOpen,5,PriceSL,PriceTP);
//+------------------------------------------------------------------+

L'exécution de ce code sur le serveur d'Alpari (en utilisant des cotations réelles) donne le résultat suivant

2010.08.24 09:12:47 '******': instant order buy 0.10 EURUSD at 1.26292 sl: 1.25776 tp: 1.27292

Il est facile de deviner que dans ce cas, nous obtiendrons les tailles suivantes SL = 516 (ou 51 pips pour 4 chiffres) TP = 1000 (ou 100 pips pour 4 chiffres)

PPS

Regardons l'aide de MQL4:

Paramètres :
symbole - Nom de l'instrument financier avec lequel l'opération est effectuée.
cmd - Opération commerciale. Il peut s'agir de n'importe quelle valeur d'opération.
volume - Nombre de lots.
prix - Prix d'ouverture.
slippage - Écart de prix maximum autorisé pour les ordres de marché (ordres d'achat ou de vente).
stoploss - Prix de clôture de la position lorsque le niveau de perte est atteint (0 en cas d'absence de niveau de perte).
takeprofit - Prix de clôture de la position lorsque le niveau de rentabilité est atteint (0 en cas d'absence de niveau de rentabilité).
commentaire - Texte du commentaire de l'ordre. La dernière partie du commentaire peut être modifiée par le serveur commercial.
magie - Numéro magique de l'ordre. Il peut être utilisé comme identifiant défini par l'utilisateur.
expiration - Période d'expiration de l'ordre en attente.
couleur_flèche - Couleur de la flèche d'ouverture sur le graphique. Si le paramètre est absent ou si sa valeur est CLR_NONE, la flèche d'ouverture n'est pas affichée sur le graphique.
Exemple : int ticket ; if(iRSI) ; if(CLR_NONE) :
  int ticket ; if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25) { ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point, "My order #"+counter,16384,0,Green) ; if(ticket<0) { Print("OrderSend failed with error #",GetLastError()) ; return(0) ; } } } }

"Dis-moi où est la vérité, mon frère ?"... ?

OrderSend - Документация на MQL4
  • docs.mql4.com
OrderSend - Документация на MQL4
[Supprimé]  
Yedelkin:

Je ne comprends pas la partie suivante du code :

// Copie le prix de clôture de la barre précédente (barre 1) dans la variable Expert Advisor correspondante.
   Cexpert.setCloseprice(mrate[1].close);  // prix de clôture de la mesure 1
//--- Vérifier s'il existe une position d'achat
   if (Cexpert.checkBuy()==true)
   {
      if (Buy_opened) 
         {
            Alert("Nous avons déjà une position à acheter !!!); 
            return;    // Ne pas ajouter à la position longue
         }
      double aprice = NormalizeDouble(latest_price.ask,_Digits);
      double stl    = NormalizeDouble(latest_price.ask - STP*_Point,_Digits);
      double tkp    = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits);
      int    mdev   = 100;
      // passer la commande
      Cexpert.openBuy(ORDER_TYPE_BUY,Lot,aprice,stl,tkp,mdev);
   }
Si nous allons ouvrir une position d'achat, nous devrions nous concentrer sur le dernier prixdemandé, mais lorsque nous définissons un Stop Loss et un Take Profit pour une telle position, nous devrions nous concentrer sur le dernier prixoffert. Est-ce correct ? Pourquoi le Stop Loss et le Take Profit sont-ils fixés sur la base du prix d'achat dans le texte du code ? S'agit-il d'une erreur d'impression ou d'une particularité d'une stratégie spécifique (le code a une construction similaire pour l'ouverture d'une position de vente) ?

Cette partie du code doit être comprise sur la base des déclarations suivantes :

а. Long - ouverture à la demande et clôture à l'offre ; Short - ouverture à l'offre et clôture à la demande ;

б. Les positions sont fermées par des contre-ordres ;

в. Le niveau de la BU est au prix d'ouverture ;

г. La distance au TP et au SL est calculée à partir du cours d'ouverture (niveau CU) ;

д. Le TP sera déclenché lorsque le prix Bid atteindra un niveau égal à Open Price + Profit size ;

e. SL sera déclenché lorsque le titre atteindra le niveau Bid égal à Open Price - Loss size.

L'auteur du conseiller expert s'est très probablement inspiré de déclarations similaires dans son travail. Pour que tout soit aussi clair que possible, je propose une illustration de ce qui précède à l'aide de l'écran suivant (nous nous intéressons au rectangle rouge).


 
Interesting:

e. Le SL sera déclenché lorsque le prix Bid atteindra un niveau égal à Open Price - Loss size.

Merci, je comprends la logique. Mais quand même, selon le point "e" il s'avère que lorsque le stoploss est déclenché, le Bid ne devrait pas être à 1.2645, mais à 1.2650 ; et le Ask, respectivement, à 1.2655.

[Supprimé]  
Yedelkin:

Merci, je comprends la logique. Mais tout de même, selon le point "e", il s'avère que lorsqu'un stop-loss est déclenché, le Bid ne devrait pas être à 1,2645, mais à 1,2650 ; et le Ask, respectivement, à 1,2655.

Il se peut que ce soit le cas, il faut vérifier ce qui se passe exactement lors du déclenchement d'un stop-loss par le marché (enfin, ou ajuster le modèle matriciel en prenant en compte toutes les possibilités de clôture disponibles).....


Pour le point "e" (tel que je le comprends)

Dans le cas d'un comptage à partir de l'ouverture (Ask), ce sera 1,27-50 = 1,2650 (le prix passera 45 pips et la pose se fermera), si j'ai bien compris. Dans ce cas, je pense que le SL devrait fonctionner à Bid 1.2650 et Ask 1.2655.

Autre chose, si nous comptons à partir de l'offre, nous obtiendrons le prix 1,2695-50 - 1,2645 (on ne peut pas discuter avec les maths). Si nous calculons le SL à partir du Bid, nous obtiendrons 1,27-1,2645 = 55 pips (ce qui, si j'ai bien compris, ne faisait pas partie de nos plans).

PS

Au moins, ce modèle nous permet de casser correctement les niveaux de SL et TP à partir du prix d'ouverture (à mon avis correctement)...

Bien sûr, il serait intéressant d'entendre l'opinion officielle des développeurs sur la façon dont les prix devraient être calculés en réalité (pas seulement SL et TP).

 

Question.


100 billets verts - est-ce en roubles ou en euros ? ;)

 
que l'on avait promis de supprimer.
 
Jager:

Question.


100 billets verts - est-ce en roubles ou en euros ? ;)

Il s'agit de la valeur du délai d'attente en millisecondes. Ce paramètre a déjà été supprimé de toutes les fonctions de négociation.
 

Bonjour, merci pour cet exemple bien présenté.

Mais je dois demander si c'est correct ?

Dans l'EA, il vérifie la présence d'une opportunité de transaction au début de chaque nouvelle barre.

Dans la fonction de classe getbuffers(), il récupère les données des 3 dernières barres en commençant par la barre 0 qui vient juste d'être formée et donc la valeur est erronée.

void MyExpert: :getBuffers()
{
if(CopyBuffer(ADX_handle,0,0,3,ADX_val)<0 || CopyBuffer(ADX_handle,1,0,3,plus_DI)<0
|| CopyBuffer(ADX_handle,2,0,3,minus_DI)<0 || CopyBuffer(MA_handle,0,0,3,MA_val)<0)

Ne devrait-il pas récupérer les données de l'indicateur des 3 dernières barres à partir de la position 1 ?

Merci de votre compréhension.

 

Excellent article Samuel

Merci d'avance pour cet article inestimable,

En nous basant sur cet article, nous pourrions inclure des fonctions telles que IsNewBar ou Buy_opened dans la classe et les appeler simplement depuis EA.

Je vous remercie encore une fois,

J'espère voir d'autres articles de votre part,

Hamed,

 

Merci de m'aider à comprendre quelque chose que je ne comprends pas :

Au tout début de l'EA , la fonction est appelée:

  Cexpert.doInit(ADX_Period,MA_Period);
при этом для ее корректного выполнения требуются уже установленные параметры symbol  и period :
//+-----------------------------------------------------------------------+
// FONCTIONS PUBLIQUES DE NOTRE CLASSE 
//+-----------------------------------------------------------------------+
/*
 Initialisation de 
*/
void MyExpert::doInit(int adx_period,int ma_period)
{
   //--- Obtenir la poignée de l'indicateur ADX
   ADX_handle=iADX(symbol,period,adx_period);
  //--- Obtenir la poignée de l'indicateur de moyenne mobile
   MA_handle=iMA(symbol,period,ma_period,0,MODE_EMA,PRICE_CLOSE);
однако, заполнение этих параметров конкретными значениями происходит позже, уже после Cexpert.doInit :
//--- lancer la fonction d'initialisation
   Cexpert.doInit(ADX_Period,MA_Period);
//--- définir toutes les variables nécessaires pour notre objet de classe
   Cexpert.setPeriod(_Period);     // définit la période
   Cexpert.setSymbol(_Symbol);     // spécifie le symbole (paire de devises)
   
   Никак не пойму, как может правильно выполниться Cexpert.doInit, если переменной symbol пока не присвоено
значение (или как-то присвоено ?) Застрял тут и дальше никак . Спасибо.