Libraries: Expert - page 2

 
fxsaber:

Oh, those Russian hackers.... Well, why stop all the experts when you're a little screwed?

By the way, you also have a bug. Static doesn't work.

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

By the way, you also have a bug. Static doesn't work.

I did not see an error here

Forum on trading, automated trading systems and testing trading strategies.

Questions from beginners MQL5 MT5 MetaTrader 5

fxsaber, 2018.08.02 17:09

// Stops all Expert Advisors if SL is triggered.

#include <MT4Orders.mqh>      // https://www.mql5.com/en/code/16006
#include <fxsaber\Expert.mqh> // https://www.mql5.com/en/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;
}
 
// The indicator cuts off all attempts to trade via Expert Advisors. It only allows to trade with hands.
// To avoid temptation to switch it off while the Terminal is running, the indicator is in invisible mode.

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

#include <Symbol.mqh>         // https://www.mql5.com/en/code/18855
#include <fxsaber\Expert.mqh> // https://www.mql5.com/en/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);
}


HI If you restart the terminal, you may sometimes encounter (MT5 build 1881) that it hangs in processes. You can overcome this by forcibly removing the corresponding terminal64.exe process and deleting MetaTrader 5\Bases\Custom\history\Timer\*.hcc.

 
Thank you. Awesome!
 

In the article the author has highlighted in great detail the nuances of the results of this library. I recommend to read it.

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

MT4 happens to be missing a lot more than FileSave and FileLoad (which are written in 3 lines each):

  1. No CHART_EXPERT_NAME (and there is nothing to replace it with, except after fixing all the other nuances - the name tag).

In my project, I solved it this way (with the "name" tag):

      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

Where SubstringParser has this 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 "";
         }
      }
};

I.e. save the chart template, read it, parse it and find the name of the Expert Advisor. It's still a crutch, but it works well so far (for about a couple of months). I think that if you use a regular HDD, you should not do this too often (for example, on every tick). I hope CHART_EXPERT_NAME will appear in MQL4 someday .

 
Will there be a new version with support for running scripts?
 
Stanislav Korotky:
Will there be a new version with support for running scripts?

Doesthis example not work?

 
fxsaber:

This example doesn't work?

It is not very similar to my use case. The main question about the example is what happens if the name of the music file is specified in a script parameter, instead of throwing it through global variables? I can send you my project in a private message.

 
Stanislav Korotky:

It is not very similar to my use case. The main question about the example is what happens if the name of the music file is specified in a script parameter instead of being thrown through global variables?

I don't remember the reason at all, but the option with an input parameter is immediately suggested. Since the example is so twisted, it must be a limitation of MT5.