English 中文 Español Deutsch 日本語 Português
Чтение новостей в формате RSS средствами MQL4

Чтение новостей в формате RSS средствами MQL4

MetaTrader 4Примеры | 11 июля 2011, 08:29
7 056 8
vgs
vgs


Вступление

В данной статье рассматриватся пример чтения RSS разметки средствами MQL4, используя функции из статьи "Разбор HTML средствами MQL4". Предполагается, что читатель читал статью или хотя бы имеет общее понимание изложенных в ней идей.


Что такое RSS и зачем он нам в MQL4?

RSS - это XML-формат, предназначенный для передачи различного рода информации от одного источника к другому.

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

RSS может быть собран (или прочитан) различными специальными программами (читалками) и доставлен пользователю в удобном для него виде. В этой статье мы попытаемся сделать заготовку, на базе которой можно будет сделать, например, новостной индикатор или просто RSS-читалку, только на языке MQL4. Какая информация нас интересует в RSS? Это, конечно же, новости.

Как уже было сказано выше, RSS - это по сути XML-документ. Что же такое XML?

Xml (eXtensible Markup Language - расширяемый язык разметки) - текстовый формат, предназначенный для хранения структурированных данных. Визуально структура может быть представлена в виде дерева элементов. Элементы XML описываются тегами.

Пример простого XML-документа:

<!--?xml version="1.0" encoding="windows-1252"?-->
<weeklyevents>
        <event>
                <title>Rightmove HPI m/m</title>
                <country>GBP</country>
                <date><!--[CDATA[05-15-2011]]--></date>
                <time><!--[CDATA[23:01]]--></time>
                <impact><!--[CDATA[Medium]]--></impact>
                <forecast>
                <previous><!--[CDATA[1.7%]]--></previous>
        </forecast></event>
</weeklyevents>


Реализация

Как мы видим из примера выше, XML чем-то напоминает HTML. Поэтому, чтобы не "изобретать велосипед", мы воспользуемся кодом из статьи "Разбор HTML средствами MQL4".

Первое что нам необходимо, это подключить функции разбора HTML к нашему проекту (индикатору). Для этого скачаем файл ReportHTMLtoCSV-2.mq4 и положим его в папочку experts/include. Поскольку файл мы будем использовать как функциональную библиотеку, в нем нужно закомментировать функцию start().

Также предлагаю переименовать файл (например в HTMLTagsLib.mq4) просто для наглядности.

Файл готов, подключаем его к индикатору (файл заготовки для индикатора можно будет скачать в приложении к статье):

#include <htmltagslib.mq4>

Теперь нам нужно подключить стандартную библиотеку Windows "wininet.dll" для работы со ссылками:

#include <winuser32.mqh>
#import "wininet.dll"
  int InternetAttemptConnect(int x);
  int InternetOpenA(string sAgent, int lAccessType, 
                    string sProxyName = "", string sProxyBypass = "", 
                    int lFlags = 0);
  int InternetOpenUrlA(int hInternetSession, string sUrl, 
                       string sHeaders = "", int lHeadersLength = 0,
                       int lFlags = 0, int lContext = 0);
  int InternetReadFile(int hFile, int& sBuffer[], int lNumBytesToRead, 
                       int& lNumberOfBytesRead[]);
  int InternetCloseHandle(int hInet);
#import

Для чтения URL будем использовать функцию ReadWebResource(string url). Работа этой функции не является темой для данной статьи, поэтому мы не будем на ней останавливаться.

Нас интересуют только входные и выходные аргументы. Функции передается ссылка, которую нужно прочитать, возвращает функция содержимое ресурса в виде строки.

Для анализа тегов мы будем использовать две функции из файла HTMLTagsLib.mq4: FillTagStructure() и GetContent(). Работа этих функций подробно описана в статье "Разбор HTML средствами MQL4". Следует отметить, что входные данные для анализа передаются в виде массива, поэтому после получения данных их нужно преобразовать в массив при помощи функции ReadWebResource(string url).

В этом нам поможет функция ArrayFromString():

//+------------------------------------------------------------------+
int ArrayFromString(string & webResData[], string inputStr, string divider) 
{   
   if (inputStr == "") 
   {
     Print ("Не задана входная строка"); 
     return(0);
   }
   if (divider == "") 
   {
      Print ("Не задан разделитель"); 
      return(0);
   }
   int i, stringCounter = 0;
   
   string tmpChar, tmpString, tmpArr[64000];   
   int inputStringLen = StringLen(inputStr);
   for (i = 0; i < inputStringLen; i++ ) 
   {
      tmpChar = StringSubstr(inputStr, i, 1);
      tmpString = tmpString + tmpChar;
      tmpArr[stringCounter] = tmpString; 
      if (tmpChar == divider) 
      {          
          stringCounter++;
          tmpString = "";
      }               
   }
   if (stringCounter > 0) 
   {
      ArrayResize(webResData, stringCounter);   
      for (i = 0; i < stringCounter; i++) webResData[i] = tmpArr[i];
   }
   return (stringCounter);
}

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

Теперь наши данные подготовлены для анализа.

В следующем фрагменте мы анализируем данные и выводим значения тегов title и country в консоль терминала:

   string webRss = ReadWebResource(rssUrl);
   int i, stringsCount = ArrayFromString(webResData, webRss, ">");      
            
   string tags[];    // массив для хранения тегов
   int startPos[][2];// координаты начала тега
   int endPos[][2];  // координатры конца тега
   
   FillTagStructure(tags, startPos, endPos, webResData);
   int tagsNumber = ArraySize(tags);
   
   string text = "";
   string currTag;
   int start[1][2];
   int end[1][2];
  
   for (i = 0; i < tagsNumber; i++)
      {
      currTag = tags[i];     

      if (currTag == "<weeklyevents>")
         {
            Print("Начало блока новостей;");
         }

      if (currTag == "<event>")
         {
            text = "";
            start[0][0] = -1;
            start[0][1] = -1;
         }

      if (currTag == "<title>")
         {// координаты начальной позиции для выборки содержимого между тегами
            start[0][0] = endPos[i][0];
            start[0][1] = endPos[i][1];
         }
                 
      if (currTag == "</title>")
         {// координаты конечной позиции для выборки содержимого между тегами
            end[0][0] = startPos[i][0];
            end[0][1] = startPos[i][1];
            text = text + GetContent(webResData, start, end) + ";";
         }

      if (currTag == "<country>")
         {// координаты начальной позиции для выборки содержимого между тегами
            start[0][0] = endPos[i][0];
            start[0][1] = endPos[i][1];
         }
                       
      if (currTag == "</country>")
         {// координаты конечной позиции для выборки содержимого между тегами
            end[0][0] = startPos[i][0];
            end[0][1] = startPos[i][1];
            text = text + GetContent(webResData, start, end) + " ;";
         }

      if (currTag == "</event>")
         {
            Print(text);
         }

      if (currTag == "</weeklyevents>")
         {
            Print("конец новостей;");
         }

      }

С помощью функции FillTagStructure() мы получаем количество и структуру тегов, а с помощью функции GetContent() - их значение.

Результат работы скрипта:

Рис 1. Результат работы скрипта NewsRss

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


Выводы

В статье рассмотрен способ чтения RSS средствами MQL4 с использованием функций анализа HTML-тегов. О недостатках данного способа достаточно сказано в статье "Разбор HTML средствами MQL4". От себя хочу добавить, что к недостаткам реализации можно отнести некоторое "неудобство" использования функций в коде, в отличии от других стандартных библиотек для чтения XML.

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


Прикрепленные файлы |
HTMLTagsLib.mqh (9.91 KB)
NewsRSS.mq4 (6.02 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (8)
Evgeny Potapov
Evgeny Potapov | 2 июн. 2012 в 02:33
В целом, программа работает
И могла бы быть довольно полезной, если бы не проблема устаревших страниц.
Старые RSS новости нам, извините, не нужны...
urubamba
urubamba | 9 мар. 2016 в 09:36

запустил пример - выдает "Ошибка при вызове InternetOpenUrlA()"

url взят из примера: http://www.forexfactory.com/ffcal_week_this.xml

в настройках "Разрешить WebRequest" установлен "http://forexfactory.com" и с ним исправно работает другой советник 

разрешить импорт DLL - установлен

 в чем глюк?

 

заранее спасибо 

Dmitriy Domanyuk
Dmitriy Domanyuk | 17 мар. 2016 в 11:11
urubamba:

запустил пример - выдает "Ошибка при вызове InternetOpenUrlA()"

url взят из примера: http://www.forexfactory.com/ffcal_week_this.xml

в настройках "Разрешить WebRequest" установлен "http://forexfactory.com" и с ним исправно работает другой советник 

разрешить импорт DLL - установлен

 в чем глюк?

 

заранее спасибо 

У меня аналогично. Решили проблему ?
MetaQuotes
MetaQuotes | 17 мар. 2016 в 13:27
urubamba:

запустил пример - выдает "Ошибка при вызове InternetOpenUrlA()"

url взят из примера: http://www.forexfactory.com/ffcal_week_this.xml

в настройках "Разрешить WebRequest" установлен "http://forexfactory.com" и с ним исправно работает другой советник 

разрешить импорт DLL - установлен

 в чем глюк?

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

Но еще лучше использовать штатный WebRequest и никаких DLL не надо будет.

urubamba
urubamba | 20 мар. 2016 в 05:40
Dmitriy Domanyuk:
У меня аналогично. Решили проблему ?
MetaQuotes Software Corp.:

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

Но еще лучше использовать штатный WebRequest и никаких DLL не надо будет.

Спасибо!))
Пользовательские графические элементы управления.  Часть 1. Создание простого элемента управления Пользовательские графические элементы управления. Часть 1. Создание простого элемента управления
В статье рассматриваются общие принципы разработки графических элементов управления, выполняется подготовка средств для быстрой и удобной работы с графическими объектами, приводится пример создания простого элемента управления для ввода текстовых или числовых данных и пример его использования.
Как добавить новые языки интерфейса в платформу MetaTrader 5 Как добавить новые языки интерфейса в платформу MetaTrader 5
Пользовательский интерфейс платформы MetaTrader 5 переведен на большинство самых распространенных языков. Не беда, если вашего родного языка не окажется в списке поддерживаемых. В MetaTrader 5 изначально была заложена полная поддержка Unicode, а для перевода пользовательского интерфейса была создана специальная утилита MultiLanguage Pack. С ее помощью любой пользователь по своему желанию может перевести интерфейс клиентских компонентов платформы MetaTrader 5 на любой язык мира. В этой статье мы детально рассмотрим весь процесс добавления новых языков интерфейса.
Пользовательские графические элементы управления. Часть 2. Библиотека элементов управления Пользовательские графические элементы управления. Часть 2. Библиотека элементов управления
Во второй статье серии "Пользовательские графические элементы управления" представлена библиотека элементов управления для решения основных задач, возникающих при обеспечении взаимодействия между программой (советником, скриптом, индикатором) и ее пользователем. Библиотека содержит множество классов (CInputBox, CSpinInputBox, CCheckBox, CRadioGroup, CVSсrollBar, CHSсrollBar, CList, CListMS, CComBox, CHMenu, CVMenu, CHProgress, CDialer, CDialerInputBox, CTable) и примеров их использования.
Создание собственных критериев оптимизации параметров эксперта Создание собственных критериев оптимизации параметров эксперта
Терминал МetaTrader 5 дает новые возможности для оптимизации параметров создаваемых экспертов. Кроме уже имеющихся в тестере критериев оптимизации, разработчики получили инструмент для создания собственных критериев. Это открывает поистине безграничные возможности в тестировании и оптимизации экспертов. В статье рассматриваются практические способы построения таких критериев - как простых, так и достаточно сложных.