Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 122

 

J'ai décidé d'ajouter à la question précédente.

1)

Supposons que j'ai un signal - lorsque le spread s'élargit fortement (aux nouvelles).

Fermer toutes les transactions en cours

Mais les ordres ne se contenteront pas de se fermer ou de s'ouvrir pendant les nouvelles.

Par conséquent, si nous prenons une commande, disons, OrderClose, la mettons dans une boucle + Sleep (3000) et l'exécutons jusqu'à ce qu'elle se ferme

2)

Si nous lions une variable interne dans le bouton et assignons la valeur appuyé/fermé à la possibilité d'ouverture de l'ordre, cela fonctionnera-t-il en temps réel ?

 
trader781:

J'ai décidé d'ajouter à la question précédente.

1)

Supposons que j'ai un signal - lorsque le spread s'élargit fortement (aux nouvelles).

Fermer toutes les transactions en cours

Mais les ordres ne se contenteront pas de se fermer ou de s'ouvrir pendant les actualités.

Par conséquent, si nous prenons une commande, disons, OrderClose, la mettons dans une boucle + Sleep (3000) et l'exécutons jusqu'à ce qu'elle se ferme

2)

Si nous lions une variable interne dans le bouton et assignons la valeur appuyé/fermé à la possibilité d'ouverture de l'ordre, cela fonctionnera-t-il en temps réel ?

1) Ce n'est pas Sleep(3000) mais la gestion des erreurs qui aide.
 

Salutations, j'écris un indicateur qui dessine l'historique des commandes sur un graphique, code:

//+------------------------------------------------------------------+
//|                                                      history.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

extern int        MagicNumber                = 1110;
extern datetime   HistoryOrdersFromDateTime  = 0;
extern color      SellColor                  = clrRed;
extern color      BuyColor                   = clrBlue;
extern color      ProfitColor                = clrWhite;
extern bool       DeleteHistoryOrders        = false;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

void start()
{
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
      {
         if(HistoryOrdersFromDateTime<OrderCloseTime())
         {
            if((TimeCurrent()-OrderCloseTime())>60)
               HistoryOrders();
         }
      }
   }
}

void HistoryOrders()
{
   double b=OrderOpenPrice(), d=OrderClosePrice(), lots=OrderLots(), Profit=0;
   datetime a=OrderOpenTime(), c=OrderCloseTime(), close_time;
   string Ticket=(string)OrderTicket(), type="Sell", symbol=OrderSymbol(), comment=OrderComment(), Background;
   color col=SellColor;
   if(OrderType()==0) {col=BuyColor; type="Buy";}

   if(DeleteHistoryOrders==false)
   {
      //Начальная точка
      ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJ_ARROW,0,a,b);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_ARROWCODE,1);
      
      //Линия  
      ObjectCreate("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJ_TREND,0,a,b,c,d);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_WIDTH,1);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_STYLE,STYLE_DOT);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_RAY,0);
  
      //Конечная точка
      ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJ_ARROW,0,c,d);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_ARROWCODE,3);

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               Ticket=(string)OrderTicket();
            }  
         }      
      }
      
      //Размер фона  
      for(int i=2; i<StringLen(DoubleToString(Profit,2)); i++)
         StringAdd(Background,"g");
      
      //Фон профита
      ObjectCreate("#"+Ticket+" Background",OBJ_TEXT,0,c,d);
      ObjectSet("#"+Ticket+" Background",OBJPROP_ANCHOR,ANCHOR_LOWER);
      ObjectSetText("#"+Ticket+" Background",Background,10,"Webdings",col);
      ObjectSet("#"+Ticket+" Background",OBJPROP_PRICE1,d);
      ObjectSet("#"+Ticket+" Background",OBJPROP_TIME1,c+Period());
  
      //Профит
      ObjectCreate("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJ_TEXT,0,c,d);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_ANCHOR,ANCHOR_LOWER);
      ObjectSetText("#"+Ticket+" Profit: "+DoubleToString(Profit,2),DoubleToString(Profit,2),10,"Arial",ProfitColor);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_PRICE1,d);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_TIME1,c+Period());
   } else ObjectsDeleteAll(0, "#"+Ticket+" ");  
}

void OnDeinit(const int reason)
{  
   //Удалаение истории ордеров
   for(int i=0; i<OrdersHistoryTotal(); i++)
   {
      DeleteHistoryOrders=true;
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         HistoryOrders();
   }
}

L'indicateur dessine correctement les transactions individuelles (ligne>arrière-plan>profit), mais il y a un petit "bug" dans l'affichage des ensembles d'ordres fermés (capture d'écran jointe), les lignes sont superposées sur l'arrière-plan et le profit (ligne(1)>arrière-plan>profit>ligne(2)>ligne(3)>ligne(4) .. . .).

Il devrait se présenter comme suit : (ligne(1)>ligne(2)>ligne(3)>ligne(4) . . . . >fon>profit). Les diverses manipulations n'ont pas abouti, merci d'aider à les affiner.

Dossiers :
 
ilnur17021992:

Bonjour, j'écris un indicateur qui affiche l'historique des commandes sur un graphique,


L'indicateur rend correctement une transaction unique (ligne>arrière-plan>profit), mais dans l'affichage d'un ensemble d'ordres fermés il y a un petit "shoosh" (je joins une capture d'écran), les lignes (ligne(1)>arrière-plan>profit>ligne(2)>ligne(3)>ligne(4) ... . ).

Il devrait être le suivant : (ligne(1)>ligne(2)>ligne(3)>ligne(4) . . . . >fon>profit). Les diverses manipulations n'ont pas abouti, merci d'aider à les affiner.

Essayez d'affecter des lignes et des icônes à la propriété OBJPROP_BACK en arrière-plan.
ObjectSetInteger - Графические объекты - Справочник MQL4
ObjectSetInteger - Графические объекты - Справочник MQL4
  • docs.mql4.com
ObjectSetInteger - Графические объекты - Справочник MQL4
 
Alexey Viktorov:
Essayez d'attribuer la propriété OBJPROP_BACK aux lignes et aux icônes en arrière-plan.
Les lignes sont dessinées en arrière-plan (derrière les chandeliers) alors que le dessin devrait être au-dessus des chandeliers : chandeliers>lignes>profit arrière-plan>profit
Dossiers :
 
ilnur17021992:
Ce n'est pas une option, donc les lignes sont en arrière-plan (derrière les chandeliers), et le dessin devrait être au-dessus des chandeliers : chandeliers>lignes>profit>profit arrière-plan
Ensuite, seulement la séquence de dessin sur le tableau. Ou bien, lorsque nous dessinons l'arrière-plan et le profit, nous devrions vérifier l'existence de ces objets en fonction du temps, lire la valeur du profit dans l'objet OBJ_TEXT et l'ajouter au profit de l'ordre en cours. Ensuite, nous devrions supprimer l'arrière-plan et le profit et les dessiner à nouveau.
Au passage, cela permet de se débarrasser d'un cycle supplémentaire pour le calcul des bénéfices.

Vous pouvez le faire
      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               Ticket=(string)OrderTicket();
            }  
         }      
      }
vous définissez le bénéfice au début, en même temps que tous les autres paramètres de l'ordre.

ps S'il vous plaît. Placez une photo avec ce bouton
 
Alexey Viktorov:
Ensuite, seulement la séquence de dessin sur le tableau. Ou bien, lorsque l'on dessine l'arrière-plan et le profit, il faut vérifier la disponibilité de ces objets par temps, lire la valeur du profit dans l'objet OBJ_TEXT et l'ajouter au profit de l'ordre en cours. Ensuite, nous devrions supprimer l'arrière-plan et le profit et les dessiner à nouveau.
À propos, cela élimine la nécessité d'un cycle supplémentaire pour le calcul du bénéfice.
Vous définissez le bénéfice au départ, en même temps que tous les autres paramètres de la commande.

Comment puis-je définir cette séquence de dessin, disons, dessiner d'abord tous les points et les lignes qui les relient, puis procéder au dessin du fond et du profit ?

 
ilnur17021992:

Comment puis-je définir cette séquence de dessin, disons, dessiner d'abord tous les points et les lignes qui les relient, puis procéder au dessin du fond et du profit ?

Eh bien, si par ma première supposition, alors oui. Et puis j'ai immédiatement eu une pensée impromptue et je n'ai pas supprimé la première phrase, mais je préfère la seconde.

Vous feriez mieux d'envisager cette variante.

ObjectFind() puis si l'objet est trouvé ObjectGetString() le convertit de texte en nombre, ajoute le bénéfice de la dernière commande à la valeur obtenue, supprime le OBJ_TEXT obsolète et en dessine un nouveau.
Si c'est le premier ou le seul ordre clôturé sur cette barre, nous dessinons simplement
OBJ_TEXT et c'est tout.
Pour faciliter les choses, nous devrions spécifier l'heure d'ouverture du bar au lieu du ticket. Ou le ticket est nécessaire pour la suite des opérations ?

 
Alexey Viktorov:
Eh bien, si je me fie à ma première supposition, c'est le cas. Et puis j'ai immédiatement eu une pensée impromptue et je n'ai pas supprimé la première phrase, mais je préfère la seconde.

Vous feriez mieux d'envisager cette variante.

ObjectFind() puis si l'objet est trouvé ObjectGetString() le convertit de texte en nombre, ajoute le bénéfice de la dernière commande à la valeur obtenue, supprime le OBJ_TEXT obsolète et en dessine un nouveau.
Si c'est le premier ou le seul ordre clôturé sur cette barre, nous dessinons simplement
OBJ_TEXT et c'est tout.
Pour faciliter les choses, nous devrions spécifier l'heure d'ouverture du bar au lieu du ticket. Ou le ticket est nécessaire pour la suite des opérations ?

Oui, le billet est nécessaire pour l'analyse ultérieure de l'histoire. Merci pour le conseil sur le redécoupage. J'ai résolu le problème un peu plus facilement en ajoutant cette vérification et en redessinant le code :

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               ProfitTicket=(string)OrderTicket();
               CountOrders++;
            }  
         }      
      }
      
      //Перерисовка фона и профита
      if(CountOrders>1)
      {  
         ObjectDelete("#"+Ticket+" Background");
         ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
         Ticket=ProfitTicket;      
      }

Je ne sais pas si c'est correct, mais en principe cela dessine comme cela devrait être (lignes>fon>profit) :

 
ilnur17021992:

Oui, le ticket est nécessaire pour analyser l'histoire par la suite. J'ai résolu le problème un peu plus facilement en ajoutant une telle vérification et un redessin au code :

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               ProfitTicket=(string)OrderTicket();
               CountOrders++;
            }  
         }      
      }
      
      //Перерисовка фона и профита
      if(CountOrders>1)
      {  
         ObjectDelete("#"+Ticket+" Background");
         ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
         Ticket=ProfitTicket;      
      }

En gros, il dessine correctement (lignes>arrière-plan>bénéfice) :

Eh bien, c'est bien, je suis heureux pour vous.