Questions des débutants MQL4 MT4 MetaTrader 4 - page 247

 
Valeriy Yastremskiy #:

Insérez le code correctement, alt S ou par l'icône, hint code.

Pourquoi avez-vous besoin d'un tableauSaveTick ?

Vous n'utilisez que 2 éléments du tableau. Remplacez-les par des variables globales ou statiques si vous les déclarez dans une fonction.

Il n'est pas raisonnable d'utiliser un tableau pour deux variables.

Et vous semblez appeler les tableaux avant l'appel de la fonctionFindTick(), dans laquelle la taille du tableau SaveTick est définie. Et il y a un dépassement du tableau.

Merci. Je l'ai.
Pouvez-vous me dire quelle est l'erreur, il me semble que la fonction ne compte pas correctement.


***
 
makssub #:

Merci. Je l'ai.
Pouvez-vous me dire quelle est l'erreur, il me semble que la fonction ne compte pas correctement.


Insérez le code correctement, c'est la 13ème case en haut de la fenêtre de réponse.

Et vous pouvez écrire en mots ce que la fonction fait ligne par ligne.

Ça n'a certainement pas l'air correct.

Je ne comprends pas où et comment la variable Tick est affectée au ticket de commande. Et il n'est pas nécessaire de vérifier le nombre magique et le type d'ordre par la condition suivante
_magic < 0 || OrderMagicNumber() == _magic
Si la fonction est appelée avec un nombre magique inférieur à zéro ou si le nombre magique est égal à l'ordre sélectionné, nous demanderons la taille du point et si elle est égale à zéro, nous chercherons une valeur vide dans le symbole de l'ordre... et ainsi de suite.

Oh, et n'oubliez pas que la sélection de l'ordre remplit la structure de données de l'ordre et la stocke. Et ce n'est qu'après la sélection de la prochaine commande avec un numéro de commande ou un ticket différent que les données de cette structure changeront.

C'est-à-dire que OrderSend ne remplit pas la structure de données de la commande, mais renvoie le ticket de commande ou moins 1. Et la structure de la commande n'est remplie que par OrderSelect. Et ensuite, les données de cet ordre peuvent être obtenues à partir de cette structure.

 
Valeriy Yastremskiy #:

Insérez le code correctement, c'est la 13ème case en haut de la fenêtre de réponse.

Et vous pouvez écrire en mots ce que la fonction fait ligne par ligne.

Il semble que ce soit faux, bien sûr.

Et il n'est pas clair où et comment la variable Tick est assignée au ticket de commande. Et il n'est pas nécessaire de vérifier le nombre magique et le type d'ordre par la condition suivante
_magic < 0 || OrderMagicNumber() == _magic
Si la fonction est appelée avec un nombre magique inférieur à zéro ou si le nombre magique est égal à l'ordre sélectionné, nous demanderons la taille du point et si elle est égale à zéro, nous chercherons une valeur vide dans le symbole de l'ordre... et ainsi de suite.

Oh, et n'oubliez pas que la sélection d'ordre remplit la structure de données de l'ordre et la stocke. Et ce n'est qu'après la sélection de la prochaine commande avec un numéro de commande ou un ticket différent que les données de cette structure changeront.

C'est-à-dire que OrderSend ne remplit pas la structure de données de la commande, mais renvoie le ticket de commande ou moins 1. Et la structure de la commande n'est remplie que par OrderSelect. Et ensuite, à partir de cette structure, nous pouvons obtenir les données de cet ordre.

int FindTicket()
   {
   int oldticket;
   int tick=0;
   ticket=0;
   
   
   for(int cnt = OrdersTotal ()-1; cnt>=0; cnt--)
      {
      if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
         {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            {
            oldticket = OrderTicket();
            if (oldticket > ticket)
               {
               ticket = oldticket;
               tick = OrderTicket();
               }
            }
         }
      }
   return(tick); 
   }              
int TickF = FindTicket();
int CalculateProfitHistory() 
{
  double _point;
  int    i, _ototal = OrdersHistoryTotal(), _profit=0;
  for   (i = 0; i < OrdersHistoryTotal(); i++) 
  {
    if (OrderSelect(TickF, SELECT_BY_TICKET, MODE_HISTORY)) 
    {
      if (OrderSymbol() == Symbol())
      {
        if (OrderMagicNumber() == Magic) 
        {
           _point = MarketInfo(OrderSymbol(), MODE_POINT);
           if (_point == 0) 
           {
              if (StringFind(OrderSymbol(), "") < 0) 
                 _point = 0.0001; 
              else _point = 0.01;
           }   
           if (OrderType() == OP_BUY) 
           {
              _profit += int((MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice())/_point);
           }
           if (OrderType()==OP_SELL) 
           {
              _profit += int((OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK))/_point);
           }
         }
      }
    }
  }
  return(_profit);
}

Dans la première fonction, nous trouvons le ticket d'ordre requis et la deuxième fonction doit calculer le profit de tous les ordres fermés après ce ticket. Le bénéfice des commandes antérieures ne m'intéresse pas. Mais le second ne le calcule pas correctement. Lorsqu'un ordre est ouvert, ces 2 fonctions sont appelées et donc il devrait être égal à 0, mais il ne l'est pas.
PS a suivi votre conseil, a abandonné les tableaux)
12ème boîte ci-dessus)

 
makssub #:

Dans la première fonction, je trouve le ticket de l'ordre requis, et la seconde fonction doit calculer le profit de tous les ordres fermés après ce ticket. Je ne suis pas intéressé par le profit de ceux qui l'ont précédé.
PS a suivi votre conseil, j'ai refusé les tableaux)
le 12ème carré du haut)

La première fonction trouve le ticket avec le numéro le plus élevé, si les tickets augmentent avec les numéros))). À l'itération suivante de la boucle, le ticket de l'ordre suivant le plus élevé est comparé au ticket de l'ordre précédent. La sélection de la commande remplit la structure de la commande, et OrderTicket récupère la valeur du ticket dans cette structure.

Écrivez ou lisez vous-même ce que fait chaque ligne de code.

Dans la deuxième fonction, OrderSelect remplira la structure de commande avec les mêmes données de ticket)

 
Valeriy Yastremskiy #:

La première fonction trouve le ticket avec le numéro le plus élevé, si les tickets augmentent avec les numéros))). À l'itération suivante de la boucle, le ticket de l'ordre suivant le plus élevé est comparé au ticket de l'ordre précédent. La sélection de la commande remplit la structure de la commande, et OrderTicket récupère la valeur du ticket dans cette structure.

Écrivez ou lisez vous-même ce que fait chaque ligne de code.

Dans la deuxième fonction, OrderSelect remplira la structure de commande avec les mêmes données de ticket)

Je l'ai épelé, mais il semble que la logique soit mauvaise en ce qui concerne cette langue. Pouvez-vous me dire comment déterminer le ticket du dernier ordre ouvert ?

Comment calculer le profit de tous les ordres fermés qui le suivent ?

 
makssub #:

Je l'ai épelé, mais il semble que la logique soit mauvaise par rapport à cette langue. Pouvez-vous me dire comment déterminer le ticket du dernier ordre ouvert ?

Comment calculer le profit de tous les ordres fermés qui le suivent ?

Au moment de l'ouverture d'une commande. Ce devrait être le plus grand.) Et nous ne devrions pas utiliser le numéro de commande. Ou bien nous devons stocker dans notre base les numéros de commande, les tickets, l'état des commandes et le temps d'ouverture/fermeture.

 if(OrderSelect(Ticket, SELECT_BY_TICKET)==true) // Если выбор рыночного ордера произошел успешно
        {
         if(OrderCloseTime()==0)              // Если наш рыночный ордер не закрыт           {
            
            //           Alert("Наш рыночный ордер жив, Модифицируем его если нужно ");
            if(Tral_Stop!=0 || Tral_Profit!=0)
          {     ModifyTral(); }
            return;
           }
         if(OrderCloseTime()!=0)              // Если наш рыночный ордер закрылся
         {
Alert("Our market order has closed. The Adviser's work is completed ",
                  " Swap = ", OrderSwap(), " Commission = ", OrderCommission(),"Profit/loss = ",OrderProfit());
         // ..... // получаем профит и считаем общий профит например
         }

Et il est préférable de se souvenir de la logique jusqu'au bout. C'est plus facile alors. Il est préférable de commencer par les données nécessaires, et il devrait y avoir suffisamment de données pour une décision).

Nous avons un temps ouvert de commandes (non en attente). Nous avons leurs billets. Nous avons un prix ouvert, un SL et un TP pour chaque ordre de marché. Et il y a un temps de fermeture de l'ordre. Et après la clôture de l'ordre, le champ Profit est rempli.

Ce sont les données dont nous avons besoin pour créer la logique à partir de ces champs.

L'expression "ordres fermés suivant le dernier ordre ouvert" n'est pas du tout définie. Ils peuvent aller par numéro, par ticket et par heure.

 
Valeriy Yastremskiy #:

Avant l'heure d'ouverture de la commande. Il devrait être le plus grand)

Vous l'écrivez correctement, mais le code semble un peu compliqué ))))).

Je le ferais de la façon dont vous le dites :

int GetTicketLastOpenOrder()
{
   int ticket = -1;
   datetime t = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderType() <= OP_SELL && OrderOpenTime() > t)
      {
         ticket = OrderTicket();
         t = OrderOpenTime();
      }
   }
   return(ticket);
}


ZS : OrderSelect() par numéro de ticket prendra beaucoup plus de temps à exécuter qu'une simple recherche par ordres ouverts

 
Igor Makanu #:

Vous l'écrivez correctement, mais le code est un peu alambiqué )))).

Il suffit de suivre vos instructions :


S : OrderSelect() par numéro de ticket prendra beaucoup plus de temps à exécuter qu'une simple énumération des ordres ouverts

Merci Igor, c'est juste quand ils ne comprennent pas l'essence, le bon code pour quelque chose ne transmet pas l'essence, donc je demande de mettre des algorithmes pas compliqués en mots)))).

 
Valeriy Yastremskiy #:

Avant l'heure d'ouverture de la commande. Ce devrait être le plus grand) Et seulement pas par numéro de commande, et souvent la billetterie n'est pas utile non plus. Vous pouvez également mémoriser les numéros de commande, les tickets, l'état des commandes et les heures d'ouverture/de fermeture dans votre base de données.

Et il est préférable de se souvenir de la logique jusqu'au bout. C'est plus facile alors. Il est préférable de commencer par les données nécessaires, et il devrait y avoir suffisamment de données pour une décision).

Nous avons un temps ouvert de commandes (non en attente). Nous avons leurs billets. Nous avons un prix ouvert, un SL et un TP pour chaque ordre de marché. Et il y a un temps de fermeture de l'ordre. Et après la clôture de l'ordre, le champ Profit est rempli.

Ce sont les données dont nous avons besoin pour créer la logique à partir de ces champs.

L'expression "ordres fermés suivant le dernier ordre ouvert" n'est pas du tout définie. Ils peuvent aller par numéro, par ticket et par heure.

Merci beaucoup pour vos réponses. J'ai mis en œuvre certaines de vos suggestions.
J'ai écrit une fonction qui trouve la bonne coche.
J'ai écrit une fonction qui compte le profit de tous les ordres fermés après le tick d'ordre désiré de la fonction sélectionnée. Il ne me reste plus qu'à le corriger selon vos recommandations et à ajouter un contrôle par heure, etc.

tpl = NormalizeDouble(Bid - ProfitLock*Point, Digits);
            ticket = OrderSend (Symbol(), OP_SELL, lastlot, Bid, Slippage, 0, tpl, "",Magic, 0, Red);


double CalculateProfitHistory()
{
double order=0,op=0;
int cnt=0;
datetime time=0;
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
      if(OrderSelect(Tick,SELECT_BY_TICKET,MODE_HISTORY))
      {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
         {
            
            
            op += OrderProfit();
            order +=op;
            cnt++;
            
         }
      }
      }
   return(order);
  }

La seule chose qui me perturbe maintenant est qu'il ne le calcule pas correctement. Si le résultat de l'essai est de 0,02, il calcule et écrit 0,1300 dans Commentaire. Pouvez-vous me dire ce qui ne va pas ?

 
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2021.09.02
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...
Raison: