Проблемы с Services. MarketBookAdd(symbol) - страница 2

 
Stanislav Korotky #:

Здесь поподробнее, пожалуйста.

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

В MQL5 советник может загружать на график шаблон. Шаблон можно прочитать и вытащить из него параметры запуска советника(это уже мои фантазии). Вот здесь это все реализовано. https://www.mql5.com/ru/code/19003

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

Expert
Expert
  • 2017.08.28
  • www.mql5.com
Библиотека чтения/записи параметров произвольных советников.
 
Stanislav Korotky #:

Здесь поподробнее, пожалуйста.

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

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

 
pivomoe #:

В MQL5 советник может загружать на график шаблон. Шаблон можно прочитать и вытащить из него параметры запуска советника(это уже мои фантазии). Вот здесь это все реализовано. https://www.mql5.com/ru/code/19003

Про эту библиотеку я в курсе, тоже пользовался, но в данном контексте есть 2 минуса (о которых я собственно уже раньше и писал). 1) если предполагается наличие запускающего эксперта помимо сервиса, то ценность сервиса как такового имхо отсутствует, потому что тогда проще все делать в том эксперте. 2) я не уверен, что подписка на стакан останется, если график закрыть, и значит из сервиса нужно дополнительно мониторить статус и воссоздавать при необходимости. В результате - скорее всего, механизм событий OnBookEvent будет более экономно грузить машину, чем бесконечный цикл в сервисе, тупо запрашивающий стаканы, когда они, может быть, не обновлялись, и проверяющий жив ли чарт. Даже на живом чарте частенько бывали ситуации, когда подписка отваливалась и её нужно было возобновлять.

 
Stanislav Korotky #:

Про эту библиотеку я в курсе, тоже пользовался, но в данном контексте есть 2 минуса (о которых я собственно уже раньше и писал). 1) если предполагается наличие запускающего эксперта помимо сервиса, то ценность сервиса как такового имхо отсутствует, потому что тогда проще все делать в том эксперте. 2) я не уверен, что подписка на стакан останется, если график закрыть, и значит из сервиса нужно дополнительно мониторить статус и воссоздавать при необходимости. В результате - скорее всего, механизм событий OnBookEvent будет более экономно грузить машину, чем бесконечный цикл в сервисе, тупо запрашивающий стаканы, когда они, может быть, не обновлялись, и проверяющий жив ли чарт. Даже на живом чарте частенько бывали ситуации, когда подписка отваливалась и её нужно было возобновлять.

   Скажу, как я использую стаканы в сервисах. Есть несколько десятков советников торгующих. Выставляющих ордера. Советник может вылететь из-за деления на ноль или может не выйти из какого то цикла. Или может не попадать в какую то часть кода. Не все ошибки можно сразу найти. Тогда ему на помощь приходит сервис, который отслеживает все ордера и их положение в стакане. Если ордер долго стоит в не правильном месте, то он сам начинает управлять ордером. Может и просигнализировать о том, что такой то советник не правильно себя ведет.

 
pivomoe #:

В MQL5 советник может загружать на график шаблон. Шаблон можно прочитать и вытащить из него параметры запуска советника(это уже мои фантазии). Вот здесь это все реализовано. https://www.mql5.com/ru/code/19003

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

Для этого нужен чарт, а у сервиса нет доступа к чартам (это его фича, ага).


pivomoe #:

   Скажу, как я использую стаканы в сервисах. Есть несколько десятков советников торгующих. Выставляющих ордера. Советник может вылететь из-за деления на ноль или может не выйти из какого то цикла. Или может не попадать в какую то часть кода. Не все ошибки можно сразу найти. Тогда ему на помощь приходит сервис, который отслеживает все ордера и их положение в стакане. Если ордер долго стоит в не правильном месте, то он сам начинает управлять ордером. Может и просигнализировать о том, что такой то советник не правильно себя ведет.

Сервис точно так же вылетит при делении на 0 и не продолжит работу.

 
Andrey Khatimlianskii #:
у сервиса нет доступа к чартам

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

 
Andrey Khatimlianskii #:

Для этого нужен чарт, а у сервиса нет доступа к чартам (это его фича, ага).

 У меня при старте терминала сервис запускает все шаблоны из папки. 

 
Artyom Trishkin #:

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

pivomoe #:

 У меня при старте терминала сервис запускает все шаблоны из папки. 

Да, действительно.

Я, видимо, запомнил, что сервисы не умеют отслеживать OnChartEvent, и поставил на них пометку "не работают с чартами".

Переосмыслю.

 

Вот такой вариант сработал.
Запускаем, удаляем индикатор из сервиса.

//+------------------------------------------------------------------+
//|                                                   TEST_INDIC.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Service: запуск/удаление кастомного индикатора                   |
//+------------------------------------------------------------------+
#property service
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"


//входные параметры
input string IndicatorName = "Examples\\Custom Moving Average"; // путь/имя индикатора
input int    SubWindow     = 0;                                 // окно графика (0 = основное)

//переменные
int  handle_ind = INVALID_HANDLE;
long chart_id;



//+------------------------------------------------------------------+
//| Service start                                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   //присваеваем индикатору короткое имя, надо для ChartIndicatorDelete
   IndicatorSetString(INDICATOR_SHORTNAME, IndicatorName);
   
   //-----------------------------------------------------------------
   //первый открытый график в терминале 
   //должен совпадать с SYMBOL и PERIOD из iCustom
   //в данном примере "EURUSD", PERIOD_M1
   chart_id = ChartFirst();   
   if(chart_id < 0)
   {
      Print("Нет открытых графиков!");
      return;
   }

   //-----------------------------------------------------------------
   //создаём хэндл кастомного индикатора
   handle_ind = iCustom("EURUSD", PERIOD_M1, IndicatorName, 14,0,0);
   if(handle_ind == INVALID_HANDLE)
   {
      Print("Ошибка создания индикатора: ", IndicatorName);
      return;
   }

   //-----------------------------------------------------------------
   //добавляем индикатор на график
   if(ChartIndicatorAdd(chart_id, SubWindow, handle_ind))
      Print("Индикатор '", IndicatorName, "' добавлен на график ", chart_id);
   else
      Print("Ошибка добавления индикатора");




   //-----------------------------------------------------------------
   //спим 10 сек
   Sleep(10000);
   
   //удаляем индикатор с графика
   //очень странное решение, что функция ChartIndicatorDelete, 
   //требует именно INDICATOR_SHORTNAME созданное ранее, а не простую переменную IndicatorName
   //поэтому требуется вызывать ChartIndicatorName чтоб получить ранее созданное имя INDICATOR_SHORTNAME
   //так же ChartIndicatorName не принтует короткое имя, но при этом сам индикатор удаляется
   if(ChartIndicatorDelete(chart_id, SubWindow, ChartIndicatorName(chart_id, SubWindow, 0)))
      Print("Индикатор '", ChartIndicatorName(chart_id, SubWindow, 0), "' удалён с графика ", chart_id);
   else
      Print("Ошибка удаления индикатора");
   
   
}
 
//так же ChartIndicatorName не принтует короткое имя, но при этом сам индикатор удаляется

Отвечаю сам, на своё недопонимание  ))
Так как индикатор уже ChartIndicatorDelete 
то в принте уже и нет ChartIndicatorName