Библиотеки: Expert - страница 2

 
fxsaber:

О, эти русские хакеры... Ну зачем останавливать все эксперты, если слегка просрали? 

Кстати, у тебя еще и ошибка. Static не работает. 

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

Кстати, у тебя еще и ошибка. Static не работает. 

Не увидел здесь ошибки

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Вопросы от начинающих MQL5 MT5 MetaTrader 5

fxsaber, 2018.08.02 17:09

// Оставанивливает работу всех советников, если сработал SL.

#include <MT4Orders.mqh>      // https://www.mql5.com/ru/code/16006
#include <fxsaber\Expert.mqh> // https://www.mql5.com/ru/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;
}
 
// Индикатор обрубает все попытки торговли через советники. Разрешает только руками торговать.
// Чтобы не было соблазна отключить его во время работы Терминала, индикатор находится в невидимом режиме.

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

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


ЗЫ Если перезагружать Терминал, то можно иногда столкнуться (MT5 build 1881) с его зависанием в процессах. Побороть возможно насильным снятием соответствующего процесса terminal64.exe и удалением MetaTrader 5\Bases\Custom\history\Timer\*.hcc.

 
Спасибо. Потрясающе! 
 

В Статье автор очень подробно осветил нюансы результатов исполнения данной библиотеки. Рекомендую ознакомиться.

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

В МТ4, как оказалось, отсутствует намного больше, чем FileSave и FileLoad (которые пишутся в 3 строках каждая):

  1. Нет CHART_EXPERT_NAME (и нечем заменить, разве что после исправления всех остальных нюансов — тегом name).

У себя, в составе некоего проекта, я решил это так (тегом "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

Где SubstringParser имеет такой код:

#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 "";
         }
      }
};

Т.е. сохраняем шаблон графика, считываем его, распарсиваем и находим имя эксперта. Костыль ещё тот, но работает пока (около пары месяцев) исправно. Полагаю, что в случае использования обычного HDD слишком часто баловаться этим не следует (к примеру, на каждом тике). Надеюсь, когда-нибудь в MQL4 появится CHART_EXPERT_NAME

 
Будет ли новая версия с поддержкой запуска скриптов?
 
Stanislav Korotky:
Будет ли новая версия с поддержкой запуска скриптов?

Этот пример не работает?

 
fxsaber:

Этот пример не работает?

Он не очень похож на мой вариант использования. Основной вопрос по примеру - что будет если название музыкального файла указывать в параметре скрипта, а не кидать через глобальные переменные? Могу скинуть свой проект в личку.

 
Stanislav Korotky:

Он не очень похож на мой вариант использования. Основной вопрос по примеру - что будет если название музыкального файла указывать в параметре скрипта, а не кидать через глобальные переменные?

Совсем не помню причины, но вариант со входным параметром напрашивается сразу. Раз в примере так вывернулся, видимо, в этом состоит ограничение MT5.