Bibliothèque: Expert - page 2

 
fxsaber:

Oh, ces pirates russes.... Pourquoi arrêter tous les experts quand on est un peu dans la merde ?

Au fait, vous avez aussi un bogue. La statique ne fonctionne pas.

 
Алексей Тарабанов:

D'ailleurs, vous avez également un bogue. La statique ne fonctionne pas.

Je n'ai pas vu d'erreur ici

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading.

Questions des débutants MQL5 MT5 MetaTrader 5

fxsaber, 2018.08.02 17:09

// Arrête tous les Expert Advisors si le SL est déclenché.

#include <MT4Orders.mqh>      // https://www.mql5.com/fr/code/16006
#include <fxsaber\Expert.mqh> // https://www.mql5.com/fr/code/19003

void OnTrade()
{
  static int PrevTotal = OrdersHistoryTotal();
  const int Total = OrdersHistoryTotal();
  
  for (int i = Total - 1; i >= PrevTotal; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderCloseReason() == DEAL_REASON_SL))
    {
      long Chart = ChartFirst();
  
      while (Chart != -1)
      {
        if ((Chart != ChartID()) && EXPERT::Is(Chart))
          EXPERT::Remove(Chart);
  
        Chart = ChartNext(Chart);
      }

      break;
    }        
    
  PrevTotal = Total;
}
 
// L'indicateur coupe court à toute tentative de négociation par le biais d'Expert Advisors. Il ne permet de négocier qu'avec les mains.
// Pour éviter toute tentation de l'éteindre lorsque le terminal est en marche, l'indicateur est en mode invisible.

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

#include <Symbol.mqh>         // https://www.mql5.com/fr/code/18855
#include <fxsaber\Expert.mqh> // https://www.mql5.com/fr/code/19003

void MyAlert( const string Str )
{
  string StrArray[];
  
  for (int i = StringSplit(Str, '\n', StrArray) - 1; i >= 0; i--)
    Alert(StrArray[i]);
}

bool NextOnCalculate( const string SymbName = NULL )
{
  const SYMBOL Symb(SymbName);
  
  MqlRates Rates[1] = {0};
  Rates[0].time = TimeCurrent();
          
  return(Symb.IsCustom() ? Symb.CloneRates(Rates) : ChartSetSymbolPeriod(0, _Symbol, _Period));
}

const SYMBOL SymbTimer("Timer");

void OnInit()
{
  if (_Symbol == SymbTimer.Name)
    ChartIndicatorGet(0, 0, ChartIndicatorName(0, 0, 0));    
  else if (SymbTimer.IsExist() && SymbTimer.On() && NextOnCalculate(SymbTimer.Name))
  {
    iCustom(SymbTimer.Name, PERIOD_CURRENT,
            ".." + StringSubstr(MQLInfoString(MQL_PROGRAM_PATH), StringLen(TerminalInfoString(TERMINAL_PATH)) + 5));
    
    SymbTimer.Off(); 
  }
}

string GetExpertData( const ulong Chart = 0 )
{
  string Str = NULL;

  MqlParam Parameters[];
  string Names[];

  if (EXPERT::Parameters(Chart, Parameters, Names))
  {
    Str += "\n" + ::ChartSymbol(Chart) + " " + ::EnumToString(::ChartPeriod(Chart)) + " " + Parameters[0].string_value + "\n";

    const int Amount = ::ArraySize(Names);

    for (int i = 0; i < Amount; i++)
      Str += (string)i + ": "+ Names[i] + " = " + Parameters[i + 1].string_value + "\n";
  }

  return(Str);
}

void Active( const int AlertTime = 5 )
{
  static const uint StartTime = GetTickCount();
  static uint PrevInterval = 0;
  const uint Interval = (GetTickCount() - StartTime) / 1000;
  const string Str = MQLInfoString(MQL_PROGRAM_NAME) + ": I've been watching you for " + TimeToString(Interval, TIME_SECONDS);
    
  long Chart = ChartFirst();

  if (Chart != -1)  
    do
    {
      if (EXPERT::Is(Chart))
        MyAlert(GetExpertData(Chart) + "Removed - " + (string)EXPERT::Remove(Chart));
        
      ChartSetString(Chart, CHART_COMMENT,  Str);
      ChartRedraw(Chart);
    }
    while ((Chart = ChartNext(Chart)) != -1);    
  else if (!(Interval % AlertTime) && (Interval != PrevInterval))
  {
    MyAlert(Str);
    
    PrevInterval = Interval;
  }
}

int OnCalculate( const int, const int, const int, const double &[] )
{
  static int i = 0;
  
  if ((_Symbol == SymbTimer.Name) && NextOnCalculate())
    Active();
  else if (i++ > 0)
    ChartIndicatorDelete(0, 0, ChartIndicatorName(0, 0, ChartIndicatorsTotal(0, 0) - 1));           
    
  return(0);
}


ZY Si vous redémarrez le terminal, vous pouvez parfois rencontrer (MT5 build 1881) qu'il se bloque dans les processus. Il est possible d'y remédier en supprimant de force le processus correspondant terminal64.exe et en supprimant MetaTrader 5\Bases\Custom\history\Timer\*.hcc.

 
Merci. C'est génial !
 

Dans l'article, l'auteur a mis en évidence de manière très détaillée les nuances des résultats de cette bibliothèque. Je vous en recommande la lecture.

Методы дистанционного управления работой советников
Методы дистанционного управления работой советников
  • www.mql5.com
В наше время информационных технологий использование различных роботов и электронных экспертов для торговли на финансовых рынках стало довольно обычным явлением. Главными преимуществами электронных экспертов принято считать безукоризненное выполнение алгоритма и безустанная работа 24 часа в сутки. Для их круглосуточного использования арендуются...
 
Andrey Khatimlianskii:

Il se trouve que MT4 manque bien plus que FileSave et FileLoad (qui sont écrits en 3 lignes chacun) :

  1. Pas de CHART_EXPERT_NAME (et il n'y a rien pour le remplacer, sauf après avoir réglé toutes les autres nuances - la balise name).

Dans mon projet, j'ai résolu le problème de cette manière (avec la balise "name") :

      void Update()
      {                
         long chartId = ChartFirst();
         
         while(chartId > 0)
         {
            #ifdef __MQL4__
            string chartEAName = GetChartEAName(chartId);
            #endif 
            
            #ifdef __MQL5__     
            string chartEAName = ChartGetString(chartId, CHART_EXPERT_NAME);
            #endif
            
            if(chartEAName == m_eaName)
            {
               // ...
            }
            
            chartId = ChartNext(chartId);
         }
      }
      
      #ifdef __MQL4__
      string GetChartEAName(const long chartId)
      {
         if(!SaveTemplate(chartId))
         {
            return "";
         }
         
         string result = "";
         
         int handle = FileOpen("ea_name_checking.tpl",FILE_TXT|FILE_READ);
         if(handle == INVALID_HANDLE)
         {
            Print
            (
               "Error in ", __FILE__,", line ", __LINE__,
               ": can't open template file 'ea_name_checking.tpl', error code = ", GetLastError()
            );
         }
         else
         {
            string text = "";
            
            while(!FileIsEnding(handle)) 
            { 
               text = text + FileReadString(handle, (uint)FileSize(handle)) +"\r\n";
            }
            
            SubstringParser eaSectionTextParser(text, "<expert>", "</expert>");            
            string eaSectionText = eaSectionTextParser.Get();
            
            if(StringTrimLeft(StringTrimRight(eaSectionText)) != "")
            {
               SubstringParser eaNameParser(eaSectionText, "name=","\r\n");
               string eaName = StringTrimLeft(StringTrimRight(eaNameParser.Get()));
               
               if(eaName != "")               
               {
                  result = eaName;
               }
            }            
         }
         
         FileClose(handle);
         FileDelete("ea_name_checking.tpl");
         
         return result;
      }
      
      bool SaveTemplate(const long chartId)
      {
         ResetLastError();
         
         if(!ChartSaveTemplate(chartId, "\\Files\\ea_name_checking.tpl"))
         {            
            Print
            (
               "Error in ", __FILE__,", line ", __LINE__,
               ": can't save template to the file 'ea_name_checking.tpl', error code = ", GetLastError()
            );
            
            return false;
         }
         
         return true;
      }      
      #endif

Là où SubstringParser a ce code :

#property strict

class SubstringParser
{
   private:
      string m_text;
      string m_subStart;
      string m_subEnd;
   
   public:
      SubstringParser(const string text, const string subStart, const string subEnd)
      {
         m_text = text;
         m_subStart = subStart;
         m_subEnd = subEnd;
      }
      
      string Get()
      {
         int startPhraseLengt = StringLen(m_subStart);
         int startPos = StringFind(m_text, m_subStart) + startPhraseLengt;
         int endPos = StringFind(m_text, m_subEnd, startPos);
                 
         if(startPos >= startPhraseLengt && endPos > startPos)
         {
            return StringSubstr(m_text, startPos, endPos - startPos);      
         }
         else
         {
            return "";
         }
      }
};

C'est-à-dire enregistrer le modèle de graphique, le lire, l'analyser et trouver le nom de l'Expert Advisor. C'est encore une béquille, mais cela fonctionne bien jusqu'à présent (depuis environ deux mois). Je pense que si vous utilisez un disque dur normal, vous ne devriez pas faire cela trop souvent (par exemple, à chaque tic-tac). J'espère que CHART_EXPERT_NAME apparaîtra un jour dans MQL4.

 
Une nouvelle version sera-t-elle disponible avec la possibilité d'exécuter des scripts ?
 
Stanislav Korotky:
Une nouvelle version sera-t-elle disponible avec la possibilité d'exécuter des scripts ?

Cet exemple ne fonctionne-t-il pas ?

 
fxsaber:

Cet exemple ne fonctionne pas ?

Il n'est pas très similaire à mon cas d'utilisation. La question principale de l'exemple est de savoir ce qui se passe si le nom du fichier musical est spécifié dans un paramètre du script, au lieu de le lancer à travers les variables globales. Je peux vous envoyer mon projet par message privé.

 
Stanislav Korotky:

Ce n'est pas très similaire à mon cas d'utilisation. La principale question concernant l'exemple est la suivante : que se passe-t-il si le nom du fichier musical est spécifié dans un paramètre du script au lieu d'être transmis par des variables globales ?

Je ne me souviens pas du tout des raisons, mais l'option d'un paramètre d'entrée est immédiatement suggérée. Puisque l'exemple est si tordu, il doit s'agir d'une limitation de MT5.