Обсуждение статьи "Работа с таймсериями в библиотеке DoEasy (Часть 39): Индикаторы на основе библиотеки - подготовка данных и события таймсерий"

 

Опубликована статья Работа с таймсериями в библиотеке DoEasy (Часть 39): Индикаторы на основе библиотеки - подготовка данных и события таймсерий:

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

Скомпилируем индикатор и запустим на графике символа, с которым долго не работали, предварительно выставив в настройках работу с текущим символом, и выберем работу с заданным списком таймфреймов. Запуск на долго неиспользуемых символах заставит индикатор подгружать недостающие данные и сообщать об этом в журнале и на графике:


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

Счёт 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, Демонстрационный счёт MetaTrader 5
--- Инициализация библиотеки "DoEasy" ---
Работа только с текущим символом: "USDCAD"
Работа с заданным списком таймфреймов:
"M1"  "M5"  "M15" "M30" "H1"  "H4"  "D1"  "W1"  "MN1"
Таймсерия символа USDCAD: 
- Таймсерия "USDCAD" M1: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" M5: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" M15: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" M30: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" H1: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" H4: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" D1: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" W1: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
- Таймсерия "USDCAD" MN1: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0
Время инициализации библиотеки: 00:00:01.406
Таймсерия "USDCAD" M1 создана успешно:
- Таймсерия "USDCAD" M1: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 5001
Таймсерия "USDCAD" M5 создана успешно:
- Таймсерия "USDCAD" M5: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 5741
Таймсерия "USDCAD" M15 создана успешно:
- Таймсерия "USDCAD" M15: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 5247
Таймсерия "USDCAD" M30 создана успешно:
- Таймсерия "USDCAD" M30: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 5123
Таймсерия "USDCAD" H1 создана успешно:
- Таймсерия "USDCAD" H1: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 6257
Таймсерия "USDCAD" H4 создана успешно:
- Таймсерия "USDCAD" H4: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 6232
Таймсерия "USDCAD" D1 создана успешно:
- Таймсерия "USDCAD" D1: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 5003
Таймсерия "USDCAD" W1 создана успешно:
- Таймсерия "USDCAD" W1: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 1403
Таймсерия "USDCAD" MN1 создана успешно:
- Таймсерия "USDCAD" MN1: Запрошено: 1000, Фактически: 323, Создано: 323, На сервере: 323
Новый бар на USDCAD M1: 2020.03.19 12:18
Новый бар на USDCAD M1: 2020.03.19 12:19
Новый бар на USDCAD M1: 2020.03.19 12:20
Новый бар на USDCAD M5: 2020.03.19 12:20

Автор: Artyom Trishkin

[Удален]  

В статье ошибка?

библиотека работает в таймере если индикатор запущен на графике символа, и в OnCalculate() по тикам — если индикатор запущен в тестере.

Или я не правильно понял?
 
Сергей Таболин:

В статье ошибка?

библиотека работает в таймере если индикатор запущен на графике символа, и в OnCalculate() по тикам — если индикатор запущен в тестере.

Или я не правильно понял?
Всё верно. Так и есть.
 

Привет,

Я пытаюсь вывести некоторые параметры последнего "полного" бара в журнал, но я предполагаю, что я либо не обновил сохраненные данные серии, либо не отсортировал их (но я также не могу понять, как отсортировать их по времени и получить нужный мне бар), мой результат всегда 2-й бар в истории, никогда не обновленные данные реального времени предыдущего полного бара... Далее я хочу сравнить размер последнего полного бара с предыдущими 10-20 барами, любой толчок в правильном направлении будет оценен по достоинству!

Явыполняю это действие по событию "Новый бар":

   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //--- Событие "Новый бар"
      if(idx==SERIES_EVENTS_NEW_BAR)
        {
         Print(TextByLanguage("Новый бар на","New Bar on "),sparam," ",TimeframeDescription((ENUM_TIMEFRAMES)dparam),": ",TimeToString(lparam));

        
//--- печать последнего полного размера бара на каждом новом баре 
         // Получите объект Symbol из переданной строки param 
         CSymbol *symbol=engine.GetSymbolObjByName(sparam);
         if(symbol==NULL)
            return;
         // Получите последний полный бар (текущий -1 справа от графика) для данного таймфрейма
         CBar *bar=engine.SeriesGetBar(symbol.Name(),(ENUM_TIMEFRAMES)dparam,1);
         if(bar==NULL)
            return;            
         //--- Отобразите данные, полученные от объекта bar
         Print(TextByLanguage("Бар \","Data from Bar \"")+symbol.Name()+"\" "+TimeframeDescription((ENUM_TIMEFRAMES)dparam)+": "+TimeToString(bar.Time(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+
            " H: "+DoubleToString(bar.High(),symbol.Digits())+
            " L: "+DoubleToString(bar.Low(),symbol.Digits())+
            " Size: "+DoubleToString(bar.Size(),symbol.Digits()));        
        
        }
     }

Прилагаю скриншот результатов работы журнала

Файлы:
Example.jpg  102 kb
 
iabbott :

Привет,

Я пытаюсь вывести некоторые параметры последнего "полного" бара в журнал, но я предполагаю, что я либо не обновил сохраненные данные серии, либо не отсортировал их (но я также не могу понять, как отсортировать их по времени и получить нужный мне бар), мой результат всегда 2-й бар в истории, никогда не обновленные данные реального времени предыдущего полного бара... Далее я хочу сравнить размер последнего полного бара с предыдущими 10-20 барами, любой толчок в правильном направлении будет оценен по достоинству!

Я выполняю это действие по событию "Новый бар":

Прилагаю скриншот результатов работы журнала

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

Какие бары таймфрейма вы хотите получать при открытии нового бара?

 

Привет,

Я только что добавил этот блок кода в событие нового бара советника Pt39 TestDoEasy, без каких-либо других изменений (строка 544 в приложении).

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

Спасибо

Файлы:
 

Есть новости?

Может, я что-то не так делаю? Мне кажется, что если бы это была проблема с библиотекой, то кто-то нашел бы ее гораздо раньше, чем сейчас :)

Спасибо!

 
iabbott:

Есть новости?

Может, я что-то не так делаю? Мне кажется, что если бы это была проблема с библиотекой, то кто-то нашел бы ее гораздо раньше, чем сейчас :)

Спасибо!

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

Привет, Артём, есть ли у вас конкретные идеи по поводу того, что библиотека должна писать в комментариях к графику, используя ::Comment(), как вы это делаете в CEngine::SeriesSync()?

void CEngine::SeriesSync(SDataCalculate &data_calculate,const uint required=0)
  {
//...
      //--- Отобразите пустые данные временного ряда в виде комментария к графику и попробуйте синхронизировать временной ряд с данными сервера
      ::Comment(series.Header(),": ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_WAIT_FOR_SYNC));
      ::ChartRedraw(::ChartID());

//...
            //--- отобразите комментарий к графику и запись в журнале с пересозданными данными временного ряда
            ::Comment(series.Header(),": OK");
            ::ChartRedraw(::ChartID());
            Print(series.Header()," ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_CREATED_OK),":");
            series.PrintShort();

//...
     //--- Удалить все комментарии
      ::Comment("");
      ::ChartRedraw(::ChartID());
  }

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

 
Dima Diall :

Привет, Артём, есть ли у вас конкретные идеи по поводу библиотеки для записи комментариев к графику, используя ::Comment(), как это сделано в CEngine::SeriesSync()?

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

Если в будущем планируется работа с графиками, то стандартных комментариев не будет.

 

Здравствуйте - при более внимательном рассмотрении кода обработчика событий я заметил, что вы используете разные методы для разбора источника события... в одних случаях он основан на параметре id события графика из OnChartEvent() а в других вы извлекаете его из параметра lparam через engine.EventSource(lparam) - есть ли конкретная причина, почему она отличается в каждом случае?

void OnDoEasyEvent(const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   int idx=id-CHARTEVENT_CUSTOM;
//--- Получите (1) время события в миллисекундах, (2) причину и (3) источник из lparam, а также (4) установите точное время события
   ushort msc=engine.EventMSC(lparam);
   ushort reason=engine.EventReason(lparam);
   ushort source=engine.EventSource(lparam);
   long time=TimeCurrent()*1000+msc;
   
//--- Обработка событий, связанных с символами
   if(source==COLLECTION_SYMBOLS_ID)
     {
      //...
     }
//--- Handling account events
   else if(source==COLLECTION_ACCOUNT_ID)
     {
      //...
     }
//--- Handling market watch window events
   else if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling timeseries events
   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling trading events
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      //...
     }