Caractéristiques du langage mql5, subtilités et techniques - page 207

 
mktr8591:

Un exemple concret d'utilisation - dans la bibliothèque Virtual, la classe VIRTUAL contient static const VIRTUAL_DELETE VirtualDelete ;

Il peut être remplacé par static const VIRTUAL static_Virtual ;

(et bien sûr déplacer le destructeur vers VIRTUAL) .

Vous ne pouvez pas. Les nouveaux objets n'appellent pas leur destructeur lorsque le programme est terminé.

 
fxsaber:

Vous ne pouvez pas. Les nouveaux objets n'appellent pas leur propre destructeur lorsque le programme est terminé.

Je suis désolé, je ne comprends pas en quoi VIRTUAL_DELETE est nouveau ?
 
mktr8591:
Désolé, je ne sais pas où dans VIRTUAL_DELETE nouveau ?

Dans VIRTUAL::Create.


ZZZ Le fil de discussion ne porte pas sur Virtual...

 

Extraire votre fenêtre d'alerte.

#ifdef __MQL5__
  #include <WinAPI\WinAPI.mqh>
#else // #ifdef __MQL5__
  #define long int
    #define  pack(A)  
      #include <WinAPI\WinAPI.mqh>
    #undef  pack
  #undef long
  
  #undef  HANDLE
  #define  HANDLE int
#endif // #ifdef __MQL5__ #else

uint GetProcessID( const HANDLE Handle )
{
  uint ID = 0;
  
  user32::GetWindowThreadProcessId(Handle, ID);
  
  return(ID);
}

// Возвращает хендл Alert-окна.
HANDLE GetAlertHandle( void )
{  
  static HANDLE Handle = 0;
  
  if (!Handle)
  {
    static const string AlertCaptions[] = {"Alert", "Алерт"};
    static const uint ProcessID = GetProcessID((HANDLE)::ChartGetInteger(0, CHART_WINDOW_HANDLE));  
    
    for (int i = 0; i < sizeof(AlertCaptions) / 12; i++)  
    {
      Handle = user32::FindWindowW("#32770", AlertCaptions[i]);
      
      if (Handle && (GetProcessID(Handle) == ProcessID))
        break;
      else
        Handle = 0;
    }
  }
    
  return(Handle);
}
 

Charge du CPU pendant les événements personnalisés.

void OnInit()
{
  EventChartCustom(0, 0, 0, 0, NULL);
}

void OnChartEvent( const int id, const long&, const double&, const string& )
{
  if (id == CHARTEVENT_CUSTOM)
  {
    Sleep(0); // Без этой строки будет 100%-я нагрузка ядра CPU.
    
    EventChartCustom(0, 0, 0, 0, NULL);
  }
}
 
 

Parfois, DEAL_TIME est inférieur à DEAL_ORDER_TIME_SETUP. Ce doit être un bug dans le logiciel des courtiers.

// Показывает ордера, которые имеют время выставления ПОЗЖЕ сделок, которые породил.
#property script_show_inputs

input datetime inFrom = D'2021.06.01';

void OnStart()
{
  if (HistorySelect(inFrom, INT_MAX))
    for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
    {
      const ulong Deal = HistoryDealGetTicket(i);
      const ulong Order = HistoryDealGetInteger(Deal, DEAL_ORDER);
      
      if ((HistoryOrderGetInteger(Order, ORDER_TICKET) == Order) &&
          (HistoryOrderGetInteger(Order, ORDER_TIME_SETUP_MSC) > HistoryDealGetInteger(Deal, DEAL_TIME_MSC)))
        Print((string)Order + " - " + (string)Deal);
    }
}


Voici comment cela se présente dans l'interface graphique.


 
fxsaber:

Parfois, DEAL_TIME est inférieur à DEAL_ORDER_TIME_SETUP. Ce doit être un bug dans le logiciel des courtiers.


Voici à quoi cela ressemble dans l'interface graphique.


Probablement, c'est un bug.

Mais il est possible de le faire normalement, n'est-ce pas ? Si l'utilisateur/le logiciel modifie l'ordre limite après l'exécution partielle, l'ORDER_TIME_SETUP sera mis à jour.

 
mktr8591:

Mais c'est aussi possible, non ? Si l'ordre limité est modifié par l'utilisateur/le logiciel après l'exécution partielle, ORDER_TIME_SETUP est mis à jour.

Ce champ est une constante. Il est écrit en même temps que le billet.

 
fxsaber:

Ce champ est une constante. Il est écrit en même temps que le billet.

Apparemment, j'ai mal compris la situation des échanges.

La façon dont je l'ai imaginé : la limite en attente a été exécutée par plusieurs transactions. Pendant ce temps, il était suspendu dans les commandes en direct et le champ ORDER_TIME_SETUP n'était pas une constante. Après le dernier échange, il est entré dans l'histoire. À ce moment-là, ORDER_TIME_SETUP est devenu une constante.

Ou pas ?