Стандарт для SendNotification()

 

Есть некоторые ограничения на использование функции SendNotification(), описанные в справочнике:

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

В связи с этим возникает необходимость синхронизации всех советников, индикаторов и прочих программ, использующих функцию SendNotification();

Предлагаю следующий вариант:

int controller=0, timeShift;;
string sendNotificationUsers="SendNotificationUsers";

int OnInit()
  {
   if(!GlobalVariableCheck(sendNotificationUsers)){
      GlobalVariableSet(sendNotificationUsers,6);
      timeShift=6;
   }else {
      GlobalVariableSet(sendNotificationUsers,GlobalVariableGet(sendNotificationUsers)+6);
      timeShift=GlobalVariableGet(sendNotificationUsers);
      }
   return(INIT_SUCCEEDED);
  }


int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(controller<rates_total){
      if(TimeCurrent() >= Time[0]+timeShift){

        // полезный код

    controller=rates_total;
      }
   }
}



void OnDeinit(const int reason)
  {
     if(GlobalVariableCheck(sendNotificationUsers)){
        if(GlobalVariableGet(sendNotificationUsers)>6){
            GlobalVariableSet(sendNotificationUsers,GlobalVariableGet(sendNotificationUsers)-6);
        }else GlobalVariableDel(sendNotificationUsers);
     }
  }

Объявляется глобальная переменная SendNotificationUsers, которая регистрирует количество программ, использующих SendNotification(). Она же является параметром сдвига по времени на 6 секунд, чтобы вписаться в ограничения. При добавлении программы, она проверяет существует ли такая переменная, если да, то увеличивает на 6 секунд, если нет, создает и устанавливает значение 6. Обратно при деинициализации: если больше шести , уменьшает значение на 6, иначе - удаляет.

Что скажете?

 

Может проще сохранять по методу fifo сообщения и выдавать их из пула по таймеру при наличии в пуле данных? После выдачи естественно из пула выданные сообщения подчищать. 

Как вариант можно еще объединять данные пула и выдавать пользователю сразу несколько данных одним сообщением.

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

 
Alexandr Gavrilin:

Может проще сохранять по методу fifo сообщения и выдавать их из пула по таймеру при наличии в пуле данных? После выдачи естественно из пула выданные сообщения подчищать. 

Как вариант можно еще объединять данные пула и выдавать пользователю сразу несколько данных одним сообщением.

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

Это некоторый вариант списка? Файл, по-моему, сложнее... Внутри терминала можно другими способами, без глобальных переменных, организовать синхронизацию?

Глобальные переменные нежелательно часто использовать?
 

Глобалки можно юзать, проблем нет. Только для однозначности доступа используйте ***SetOnCondition, иначе 2 индикатора одновременно поменяют значение переменной, или один поменяет, а второй обломится.

А вот с логикой в коде, мне кажется, есть проблема. Time[0] тут ни каким боком.

 
Andrey Khatimlianskii:

Глобалки можно юзать, проблем нет. Только для однозначности доступа используйте ***SetOnCondition, иначе 2 индикатора одновременно поменяют значение переменной, или один поменяет, а второй обломится.

А вот с логикой в коде, мне кажется, есть проблема. Time[0] тут ни каким боком.

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

Time[0] нужен для сдвига по времени. Грубо говоря, появился новый бар -> первый индикатор со смещением в 6 секунд срабатывает на 6той секунде после появления бара и засыпает до последующего бара -> второй индикатор со смещением 12 секунд срабатывает на 12 секунде после появления нового бара и засыпает... и так далее

Шурует нормально, вот прям щас 3 уведомления пришли с разницей в 6 секунд каждое. То есть код рабочий. нужно только чтобы все писали по стандарту... чтобы у разных программистов этот момент был синхронизован

 
Yevhenii Levchenko:

Все норм с изменением значения переменной при выключении и повторном запуске терминала (через принт вывожу и показывает значения корреткно), а вот при перекомпиляции все индикаторы одновременно увеличивают значение переменной.

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


Yevhenii Levchenko:

Time[0] нужен для сдвига по времени. Грубо говоря, появился новый бар -> первый индикатор со смещением в 6 секунд срабатывает на 6той секунде после появления бара и засыпает до последующего бара -> второй индикатор со смещением 12 секунд срабатывает на 12 секунде после появления нового бара и засыпает... и так далее 

А 2 сообщения за бар отправлять нельзя?


Yevhenii Levchenko:

Шурует нормально, вот прям щас 3 уведомления пришли с разницей в 6 секунд каждое. То есть код рабочий. нужно только чтобы все писали по стандарту... чтобы у разных программистов этот момент был синхронизован

На стандарт не тянет...

Нужно оформить в виде библиотеки и предусмотреть все возможные нюансы.

 
Andrey Khatimlianskii:

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

Какие еще случаи могут быть? Над SetOnCondition нужно помозговать

Andrey Khatimlianskii:

А 2 сообщения за бар отправлять нельзя?

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

В баре можно уместить столько сообщений, сколько влезет в бар. главное чтобы соблюдались условия. В минуту можно отправить 10 сообщений, то есть, грубо говоря, одно сообщение на каждые 6 секунд (учитывая расчеты индикатора, этот период будет чуть больше)... Для этого и взял сдвиг на 6 секунд от начала бара

Andrey Khatimlianskii:

Нужно оформить в виде библиотеки и предусмотреть все возможные нюансы.

Вот для этого тема и была создана
 
Andrey Khatimlianskii:

На стандарт не тянет...

И на простую поделку не тянет, не только на стандарт,

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

 
TheXpert:

И на простую поделку не тянет, не только на стандарт,

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

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

 
Yevhenii Levchenko:

Есть некоторые ограничения на использование функции SendNotification(), описанные в справочнике:

В связи с этим возникает необходимость синхронизации всех советников, индикаторов и прочих программ, использующих функцию SendNotification();

Предлагаю следующий вариант:

Объявляется глобальная переменная SendNotificationUsers, которая регистрирует количество программ, использующих SendNotification(). Она же является параметром сдвига по времени на 6 секунд, чтобы вписаться в ограничения. При добавлении программы, она проверяет существует ли такая переменная, если да, то увеличивает на 6 секунд, если нет, создает и устанавливает значение 6. Обратно при деинициализации: если больше шести , уменьшает значение на 6, иначе - удаляет.

Что скажете?

пишется большой-большой "робот" который занимается отчётами, скриншотами и всякими уведомлениями. Сами по отдельности совы/индюки/скрипты не должны пользоваться SendXXX

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

Замечательная функция EventChartCustom вкупе с глоб.переменными вполне походит чтобы сделать протокол общения с таким роботом.

А какой будет протокол : кто первым напишем подобное, удобно,красиво и доступно, тот и прав ; тут заранее не договоришься :-)

 
Maxim Kuznetsov:

пишется большой-большой "робот" который занимается отчётами, скриншотами и всякими уведомлениями. Сами по отдельности совы/индюки/скрипты не должны пользоваться SendXXX

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

Замечательная функция EventChartCustom вкупе с глоб.переменными вполне походит чтобы сделать протокол общения с таким роботом.

А какой будет протокол : кто первым напишем подобное, удобно,красиво и доступно, тот и прав ; тут заранее не договоришься :-)

О! Идея!

Это получается, что сначала цепляем робота на график. Он создает глобальную переменную в которой помещается ChartID (на котором он сидит)? И туда все шлют свои сообщения. А робот их пихает в массив(?) и потихонечку разгребает его согласно ограничений функции SendNotification?

Так?
Причина обращения: