English 中文 Español Deutsch 日本語 Português
Alert и Comment для внешних индикаторов. Мультивалютный анализ посредством внешнего сканирования

Alert и Comment для внешних индикаторов. Мультивалютный анализ посредством внешнего сканирования

MetaTrader 4Примеры | 23 ноября 2009, 08:14
5 018 4
Vladimir
Vladimir

Введение

В предыдущих статьях мы рассмотрели возможность получения информации от индикаторов, которые используют в качестве источника информации значки из таблицы Wingdings, отображенные на графике. Статья "Alert и Comment для внешних индикаторов" и создание Алертов от индикаторов, которые используют для хранения информации индикаторные буфера статья "Alert и Comment для внешних индикаторов (часть вторая)", а информация выводится изменением цвета.

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

Как мы уже видели, само получение значений из индикаторных буферов не является сложной процедурой и значимой нагрузкой на процессор, поэтому введем в наш индикатор возможность вывода мультивалютной информации.

Нагрузка на глаза, которую получает трейдер от непрерывного наблюдения за графиками, является очень значительной, если количество доступных инструментов большое. Поэтому часто трейдером выбираются несколько валют, и торговля происходит исключительно по ним.

В дальнейшем может оказаться, что была возможность провести сделку или ряд сделок по другой валютной паре, той, график которой не был открыт в нужный момент на экране. Поэтому есть потребность в мультивалютном анализе доступных инструментов.

Исходя из этого, я предлагаю использовать функцию "Alert" в качестве способа оперативного вывода информации об изменениях, происходящих в списке доступных инструментов, от внешнего индикатора.


Alert мультивалютного индикатора

Вначале рассмотрим код блока обработки информации, получаемой из индикаторных буферов внешнего индикатора.

double buffer1, buffer2, buffer12, buffer22;
// Анализируем первый и второй бар графиков
            buffer1  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 1);
            buffer12 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 2);
            buffer2  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 1);
            buffer22 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 2);
            if(buffer12<=buffer22&&buffer1>buffer2)
               {
                  Alert (text+"UP"); // Есть пересечение
                  send_email (text+"UP");
                  return (1);
               }
            if(buffer12>=buffer22&&buffer1<buffer2)
               {
                  Alert (text+"DN"); // Есть пересечение
                  send_email (text+"DN");
                  return (1);
               } 
            return (0);

Как видим, здесь все просто, и мы в прошлой статье уже рассматривали подобную логику. В прошлый раз было использовано изменение цвета выводимых буферов, а здесь мы используем значения расположения данных буферов относительно друг друга.

Всю эту обработку вынесем в отдельный блок. Мультивалютный и мультитаймфреймный анализ потребует многократного использования этой процедуры.

Список доступных инструментов вынесем во внешний файл, что позволит в дальнейшем упростить процедуру внесения в него изменений и дополнений. При таком подходе, для изменения списка доступных инструментов пользователь может самостоятельно создать заново или внести изменения в файл доступных инструментов, не меняя программного кода индикатора.

В конце статьи показана процедура создания собственного файла доступных инструментов.

Подпрограмма считывания информации из файла взята отсюда.

//+------------------------------------------------------------------+
//|                                           SymbolList_fromSet.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
void LoadFileToSymbol()
   {
      {
              int file_handle = FileOpen(SetFile_name + ".set", FILE_READ);
              //---- Если возникла ошибка
              if(file_handle < 0)
                {
                         Print("Ошибка №", GetLastError(), " при открытии файла!!!");
                         return(-1);
                }
              int SymbolsCount = 0;
              while(true)
                {
                         Symbols[SymbolsCount] = FileReadString(file_handle);
                         //---- Если достигнут конец файла, останавливаемся
                         if(GetLastError() == 4099) 
                             break;
                         if(FileIsEnding(file_handle)) 
                             break;
                         SymbolsCount ++;
                         ArrayResize(Symbols, SymbolsCount + 1);
                }
              FileClose(file_handle);
      }
   
   }  
//--------------------------------------------------------------+

Теперь, после подготовки массива инструментов, нам остается сделать мультитаймфреймную обработку каждого инструмента.

Текущий таймфрейм будет использоваться нами для расчетов как стартовый.

// Анализируем массив символов (Расчет на текущем и всех нижних таймфреймах)
         for (int i=0; i<ArraySize(Symbols); i++)
            {  Total = 0;
               switch (Period())
                  {
                     case 43200: Total = Total +  process ( Symbols[i], 43200);
                     case 10080: Total = Total +  process ( Symbols[i], 10080);
                     case  1440: Total = Total +  process ( Symbols[i],  1440);
                     case   240: Total = Total +  process ( Symbols[i],   240);
                     case    60: Total = Total +  process ( Symbols[i],    60);
                     case    30: Total = Total +  process ( Symbols[i],    30);
                     case    15: Total = Total +  process ( Symbols[i],    15);
                     case     5: Total = Total +  process ( Symbols[i],     5);
//                     case     1: Total = Total +  process ( Symbols[i],     1);
                  }

Расчет производится от текущего таймфрейма и до самого меньшего. Поэтому если вам необходим расчет алерта, начиная с дневного таймфрейма, значит график с индикатором должен быть активирован на дневном таймфрейме. Если нужно получить сигнал, начиная с часового таймфрейма, значит и график будет часовым и т.д. Перерасчет индикатора происходит только на каждом новом баре.

Такой подход сделал оперирование перерасчетом индикатора удобным для пользователя: простое переключение рабочего таймфрейма позволяет не вводить в код дополнительные параметры и расчетные функции.

Строка работы на минутном таймфрейме закомментирована. Если кому-то потребуется применять индикатор на минутном таймфрейме, - раскомментируйте строку.

//                     case     1: Total = Total +  AlertComment ( Symbols[i],     1);


В качестве источника информации для нашего индикатора используем индикатор 2MA_forAlert.mq4 в приложении к статье. 2MA_forAlert - это простой индикатор, отображающий две линии МА. Также можно использовать любой другой, имеющий два буфера (две линии). Стохастик, МАКД и др.

Вот как выглядит алерт терминала с применением разных индикаторов:

Буферы, где хранятся значения линий, могут иметь разный порядок. Например:

0 - главная линия

1 - сигнальная линия

или

0 - сигнальная линия

1 - главная линия

Поэтому при использовании внешнего индикатора нужно самостоятельно определить последовательность использования линий. В случае некорректного извещения алерта, изменить входные параметры.

extern int       ExtBuff1      = 0;
extern int       ExtBuff2      = 1;

В качестве параметров можно использовать все 8 допустимых буферов (цифры от 0 до 7)

В связи с тем, что индикатор использует внешний файл со списком инструментов, я покажу, как его сформировать в терминале.

Вначале мы в окне данных создаем все необходимые инструменты, для этого:

1. Открываем все доступные инструменты.


2. Оставляем только те, по которым будем получать сигналы.

Инструментов должно быть ровно столько, сколько предполагается использовать в торговле.


3. Затем сохраняем файл, для чего кликаем в окне "Обзор рынка" правой кнопкой мыши


4. Файл сохраняем в папке для хранения файлов экспертов метатрейдера


Имя файла вы можете назначить произвольное, но расширение файла .set изменять нельзя. В указанном примере используется файл forexall.set

extern string    SetFile_name  = "forexall"; // Файл, содержащий символы инструментов пользователя

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

Если же вы сохранили файл в папке по умолчанию \experts\symbolsets, то обязательно скопируйте его в папку \experts\files метатрейдера, так как это единственная папка, из которой индикатор может открыть файл (ограничения метатрейдера). В дальнейшем в индикаторе нужно ввести имя файла, который будет обрабатываться для считывания из него информации о доступных инструментах.

Для тех пользователей, кто желает получать информацию по электронной почте о работе мультивалютного сканера в индикаторе предусмотрена и такая возможность. Установите в параметр true и получайте сигналы по почте.

extern bool      Signal_email  = false;

Есть такие пользователи которые создают в дальнейшем переадресацию и получают сигналы посредством СМС на свой телефон. У каждого свой подход.

Все индикаторы должны находиться в папке \experts\indicators Метатрейдера.


Заключение

Таким образом, используя возможности Алерта, можно построить информационное пространство из различных модулей, не прибегая к изучению программирования или поиску специалиста, который запрограммирует идею. Главное в нашем деле - вовремя получать информацию.

И в заключение, представляю полный код индикатора - Алерта.

//+------------------------------------------------------------------+
//|                                                    Alert_MT4.mq4 |
//|                                      Copyright © 2009, Fibook.ru |
//|                                             http://www.fibook.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Fibook.ru"
#property link      "http://www.fibook.ru"

#property indicator_chart_window

extern string    SetFile_name="forexall"; // Файл содержащий символы инструментов пользователя
extern string    nameIndicator = "input indicator name";
extern int       ExtBuff1      = 0;
extern int       ExtBuff2      = 1;
extern string    UserText      = "Cross";
extern bool      Signal_email  = false;

string Symbols[1],text;
int expBars=0;
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
// Если нет нового бара, то выходим
   if(!isNewBar()) return;
   int Total;
//---- Проверка на ошибки входных параметров
   if(ControlError()==false) return;
//---- Загружаем в массив Symbols символы из файла
   LoadFileToSymbol();
//----

// Анализируем массив символов (Расчет на текущем и всех нижних таймфреймах)
   for(int i=0;i<ArraySize(Symbols);i++)
     {
      Total=0;
      switch(Period())
        {
         case 43200: Total = Total +  process ( Symbols[i], 43200);
         case 10080: Total = Total +  process ( Symbols[i], 10080);
         case  1440: Total = Total +  process ( Symbols[i],  1440);
         case   240: Total = Total +  process ( Symbols[i],   240);
         case    60: Total = Total +  process ( Symbols[i],    60);
         case    30: Total = Total +  process ( Symbols[i],    30);
         case    15: Total = Total +  process ( Symbols[i],    15);
         case     5: Total = Total +  process ( Symbols[i],     5);
         //                     case     1: Total = Total +  process ( Symbols[i],     1);
        }
      if(Total>1)
        {
         text=StringConcatenate(" Warning!!!      ",Symbols[i]," have ",UserText," for ",Total," TF");
         Alert(text);
         send_email(text);
        }
     }

//----
   return(0);
  }
//+------------------------------------------------------------------+

int process(string Sym_,int TF)
  {
   text=StringConcatenate(Sym_," ",TF," indicator ",nameIndicator," Crossing line ");
   double buffer1,buffer2,buffer12,buffer22;
// Анализируем первый и второй бар графиков
   buffer1  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 1);
   buffer12 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 2);
   buffer2  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 1);
   buffer22 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 2);
   if(buffer12<=buffer22 && buffer1>buffer2)
     {
      Alert(text+"UP"); // Есть пересечение
      send_email(text+"UP");
      return(1);
     }
   if(buffer12>=buffer22 && buffer1<buffer2)
     {
      Alert(text+"DN"); // Есть пересечение
      send_email(text+"DN");
      return(1);
     }
   return(0);

  }
//+------------------------------------------------------------------+
//|                                           SymbolList_fromSet.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+

void LoadFileToSymbol()
  {
     {
      int file_handle=FileOpen(SetFile_name+".set",FILE_READ);
      //---- Если возникла ошибка
      if(file_handle<0)
        {
         Print("Ошибка №",GetLastError()," при открытии файла!!!");
         return(-1);
        }
      int SymbolsCount=0;
      while(true)
        {
         Symbols[SymbolsCount]=FileReadString(file_handle);
         //---- Если достигнут конец файла, останавливаемся
         if(GetLastError()==4099)
            break;
         if(FileIsEnding(file_handle))
            break;
         SymbolsCount++;
         ArrayResize(Symbols,SymbolsCount+1);
        }
      FileClose(file_handle);
     }

  }
//--------------------------------------------------------------+
void send_email(string text)
  {
   if(Signal_email==true) SendMail("Alert ",text);
  }
//--------------------------------------------------------------+
bool ControlError()
  {
// Проверим ввели ли имя индикатора
   if(nameIndicator=="input indicator name")
     {
      Alert("Введите название индикатора ");
      return(false);
     }
// Проверим есть ли файл с символами
   int handle;
   handle=FileOpen(SetFile_name+".set",FILE_CSV|FILE_READ,';');
   if(handle<1)
     {
      Alert("Файл ",SetFile_name,".set не обнаружен, последняя ошибка ",GetLastError());
      return(false);
     }
// Проверим на ошибку назначение входных переменных буферов анализируемого индикатора
   if(ExtBuff1>7 || ExtBuff2>7)
     {
      Alert("Некорректные параметры буфера ExtBuff1 или ExtBuff2");
      return(false);
     }
   if(ExtBuff1==ExtBuff2)
     {
      Alert("Ошибка: ExtBuff1 и ExtBuff2 не могут быть равны");
      return(false);
     }

   return(true);
  }
/*--------------------------------------------------------------+
 |Функция возвращает true, если появится новый бар, иначе false |
 +--------------------------------------------------------------*/
bool isNewBar()
  {
   bool res=false;
   if(expBars!=Bars)
     {
      expBars=Bars;
      res=true;
     }
   return(res);
  }
//+------------------------------------------------------------------+

Прикрепленные файлы |
2MA_forAlert.mq4 (2.76 KB)
Alert_MT4.mq4 (6.15 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (4)
Sergey Kravchuk
Sergey Kravchuk | 23 нояб. 2009 в 22:54

Алерт?!... Это вот то надоедливое окошко, вспрыгивающее в самый неподходящий момент и закрывающее собою график и в котором толком то отобразить ничего нельзя? :((

А чем вам обычные графики-то не подошли? Там же можно не только факт пересечения отловить, но подход и отход до линии пересечения. Ну или текстовый объект в окне индикатора - там хоть цвет да шрифт могут привлечь внимание к уже прошедшему событию (например текст о пересечении будет красным и жирным на протяжении пяти минут после пересечения). Да и звук можно собственный записать и при пересечении воспроизвести не просто "трынь" а содержательную фразу: "пересечение такогото уровня на такой то паре"....

Vladimir
Vladimir | 24 нояб. 2009 в 10:28
ForexTools:

Алерт?!... Это вот то надоедливое окошко, вспрыгивающее в самый неподходящий момент и закрывающее собою график и в котором толком то отобразить ничего нельзя? :((

А чем вам обычные графики-то не подошли? Там же можно не только факт пересечения отловить, но подход и отход до линии пересечения. Ну или текстовый объект в окне индикатора - там хоть цвет да шрифт могут привлечь внимание к уже прошедшему событию (например текст о пересечении будет красным и жирным на протяжении пяти минут после пересечения). Да и звук можно собственный записать и при пересечении воспроизвести не просто "трынь" а содержательную фразу: "пересечение такогото уровня на такой то паре"....


Алерт - это просто.

Прочитал информацию Алерта, открыл график, присоединил шаблон и анализируй..

Можно и графический интерфейс сделать, можно и в файл вывести. Это не сложно.

Но в любом случае, открываем нужный график, присоединяем шаблон и анализируем.


В статье написано как можно анализировать всю корзину доступных инструментов (или часть ее) на всех таймфреймах, которые пользователь посчитает для себя необходимыми. А после анализа открыть только те, где произошли события. (Например пересечения линий).

А если корзина состоит из 12 или больше валютных пар? Тяжеловато будет наблюдать за любым индикатором.


А по вашему предложению нужно сделать так:

Присоединить индикатор на график.

Последовательно переключить все таймфреймы с которыми работает трейдер.

Провести анализ.

Такие же действия провести со всеми анализируемыми инструментами.


Я абсолютно не возражаю против указанного метода. И против мнемоники в отображении индикаторов не возражаю.

Это как раз то, что нужно делать после того как трейдер получил информацию о событии произошедшем на конкретной валютной паре и конкретном таймфрейме (таймфреймах). Так пусть этим займется компьютер.


Мой подход избавляет от постоянного наблюдения. А значит бережем глаза. Экономим ресурсы компьютера. А дальше кому что по вкусу. Совершенствуем ММ или торговую систему, тестируем советников, пьем чай или кофе)))


Прибыльного трейдинга господа в любимом деле и отменного здоровья, чтобы прибылью пользоваться для души, для семьи и себе во благо.

Sergey Kravchuk
Sergey Kravchuk | 24 нояб. 2009 в 13:45
Vladlv:

А по вашему предложению нужно сделать так:

Присоединить индикатор на график.

Последовательно переключить все таймфреймы с которыми работает трейдер.

Провести анализ.

Такие же действия провести со всеми анализируемыми инструментами.

совершенно не обязательно. Все ваши коды остаются без изменений. Для того чтобы, проанализировать чужие таймы и пары совсем не обязательно по ним ручками лазить. iOpen и иже с ними с легкостью могут это сделать за вас. Но вот чем отображать результат такого осмотра - это вопрос. Когда линия контрольного индикатора во флете уляжется вдоль вашей сигнальной линии и каждый тик будет пересекать ее то туда то сюда, вы быстренько поймете почему я назвал то окошко надоедливым ;) а вот текстовая строка на графике такого напряга вызывать не будет
Vladimir
Vladimir | 24 нояб. 2009 в 16:38
ForexTools:
Vladlv:

А по вашему предложению нужно сделать так:

Присоединить индикатор на график.

Последовательно переключить все таймфреймы с которыми работает трейдер.

Провести анализ.

Такие же действия провести со всеми анализируемыми инструментами.

совершенно не обязательно. Все ваши коды остаются без изменений. Для того чтобы, проанализировать чужие таймы и пары совсем не обязательно по ним ручками лазить. iOpen и иже с ними с легкостью могут это сделать за вас. Но вот чем отображать результат такого осмотра - это вопрос. Когда линия контрольного индикатора во флете уляжется вдоль вашей сигнальной линии и каждый тик будет пересекать ее то туда то сюда, вы быстренько поймете почему я назвал то окошко надоедливым ;) а вот текстовая строка на графике такого напряга вызывать не будет

Совершенно верно, если индикатор работает на каждый тик, только я в этом индикаторе сделал работу индикатора один раз в период на котором он прикреплен.

Если на часовом, то он будет показывать раз в час. Если на 15 минутах, то раз в 15 минут.

И вообще, идея статьи показать, как можно реализовать сканирование индикаторов и получение результатов этого действия посредством языка MQL. А отображение информации это уже другая тема. Можно и комментом вывести, и в отдельное окно, чтобы коммент не закрывался свечами на графике.

Про вывод многострочного коммента здесь уже был материал, так что желающие его реализовать могут воспользоваться.

Автоматическое создание документации к программам на MQL5 Автоматическое создание документации к программам на MQL5
Большинство Java программистов знакомы с автоматическим созданием документации, которая может быть создана при помощи программы JavaDocs. В мире C++ также есть несколько автоматических генераторов документации, одними из лидеров являются программы Microsoft's SandCastle и Doxygen. В статье описано, как можно использовать программу Doxygen для создания структурированных файлов справки HTML для программ, написанных на MQL5. Результаты данной работы убедили меня использовать Doxygen (или похожие программы) в будущем для создания документации к любому моему коду на MQL5, это значительно облегчает его понимание и использование.
Библиотека матричной алгебры LibMatrix (часть первая) Библиотека матричной алгебры LibMatrix (часть первая)
Автор знакомит читателей с простой библиотекой матричной алгебры. Рассматриваются основные функции и их особенности.
Переход на новые рельсы: пользовательские индикаторы в MQL5 Переход на новые рельсы: пользовательские индикаторы в MQL5
Я не буду перечислять все новые возможности и особенности нового терминала и языка. Их действительно много, и некоторые новинки вполне достойны освещения в отдельной статье. Вы не увидите здесь кода, написанного по принципам объектно-ориентированного программирования — это слишком серьезная тема для того, чтобы просто быть упомянутой в контексте как дополнительная вкусность для кодописателей. В этой статье остановимся подробней на индикаторах, их строении, отображении, видах, а также особенностях их написания по сравнению с MQL4.
Особенности работы с числами типа double в MQL4 Особенности работы с числами типа double в MQL4
В данной заметке собраны советы по решению наиболее часто возникающих ошибок при работе с числами типа double в программах на MQL4.