Озвучивание ботов.

  • Автор темы Автор темы AlanTrade
  • Дата начала Дата начала

AlanTrade

Интересующийся
Добрый день, форумчане.
Помогите корректно организовать звук в индикаторе. Стандартные средства МТ4 работают плохо.
Как я понимаю, в момент начала бара от различных графиков возникает поток сигналов на воспроизведение в Windows. В очередь они не ставятся и проигрываются последние, остальные теряются. Из двух стоящих рядом функций PlaySound() воспроизводится только одна. Это вносит кашу, да и организация сообщений грузит программу.
Видится решение в использовании средств waveOut API или Winampa. Формирование в индикаторе чего-то вроде плейлиста и передачу воспроизведения внешнему устройству. Это ещё должно и разгрузить терминал. В общем, проблема в организации очереди.
Гуглил. Подробного описания для чайников не нашел, а самому разобраться в вопросе ума пока не хватило.
Если кто решал эту задачу, подскажите. Думаю, это будет интересно многим.
 

javckin

Почетный гражданин
extern bool OnSound = TRUE;
extern string SoundCloseProfit = "Alarm01";
if (OnSound) PlaySound(SoundCloseProfit);
Причем здесь Sleep? это задержка,пауза,не пишите если не знаете.
 

javckin

Почетный гражданин
Добрый день, форумчане.
Помогите корректно организовать звук в индикаторе. Стандартные средства МТ4 работают плохо.
Как я понимаю, в момент начала бара от различных графиков возникает поток сигналов на воспроизведение в Windows. В очередь они не ставятся и проигрываются последние, остальные теряются. Из двух стоящих рядом функций PlaySound() воспроизводится только одна. Это вносит кашу, да и организация сообщений грузит программу.
Видится решение в использовании средств waveOut API или Winampa. Формирование в индикаторе чего-то вроде плейлиста и передачу воспроизведения внешнему устройству. Это ещё должно и разгрузить терминал. В общем, проблема в организации очереди.
Гуглил. Подробного описания для чайников не нашел, а самому разобраться в вопросе ума пока не хватило.
Если кто решал эту задачу, подскажите. Думаю, это будет интересно многим.

значит размещенная строка (if (OnSound) PlaySound(SoundCloseProfit);) прописана не корректно не там где положено.
 

Mahesvara

Интересующийся
extern bool OnSound = TRUE;
extern string SoundCloseProfit = "Alarm01";
if (OnSound) PlaySound(SoundCloseProfit);
Причем здесь Sleep? это задержка,пауза,не пишите если не знаете.

читаем внимательно исходный пост - "Из двух стоящих рядом функций PlaySound() воспроизводится только одна."

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

javckin

Почетный гражданин
читаем внимательно исходный пост - "Из двух стоящих рядом функций PlaySound() воспроизводится только одна."

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

Из двух стоящих рядом функций PlaySound()-зачем это вообще нужно лишний раз нагружать процессор и нагружать терминал. ГЛУПОСТЬ.
 

javckin

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

AlanTrade

Интересующийся
Из двух стоящих рядом функций PlaySound()-зачем это вообще нужно лишний раз нагружать процессор и нагружать терминал. ГЛУПОСТЬ.

Объясняю, чтобы не выглядеть столь глупым.
Работа в интрадей, почти скальпинг, на 2-3 инструментах. Чтобы не пропустить события и чтобы к концу дня не выпадали глаза, использую звуковое оповещение. На активном рынке, в моменты открытия свечей на нескольких ТФ, возникает каша, или, по вашему, ламбада. Как раз слушать её я не любитель, поэтому хотелось бы выстроить их в очередь. Штатные средства МТ4, как я понимаю, это не позволяют сделать.
По поводу двух стоящих рядом PlaySound объясняю "зачем это вообще нужно".
if(Sobitie_1)
{
PlaySound("Symbol.wav");
PlaySound("Sobitie.wav");
PlaySound("Period.wav");
}
 

Ugar

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

AlanTrade

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

Не совсем понятно о системе таймеров. Программа может иметь только 1 таймер. Да и как её организовать, эту очередь, если каждый из полутора десятков открытых индикаторов норовит вперёд пролезть. :question:

Момент, конечно, важен, но не до такой же степени. Не Баха слушать будем. 0.2-0.5 сек сообщение.
 

MrGreen86

Гуру форума
Не совсем понятно о системе таймеров. Программа может иметь только 1 таймер. Да и как её организовать, эту очередь, если каждый из полутора десятков открытых индикаторов норовит вперёд пролезть. :question:

Момент, конечно, важен, но не до такой же степени. Не Баха слушать будем. 0.2-0.5 сек сообщение.

самый просто способ в решении вашего вопроса, чтобы второй индикатор постоянно воспроизводил звук с задержкой не зависимо от первого.
как это сделать:
PHP:
Expand Collapse Copy
// вставить в начало кода
uint next_signal = 0;

void OnInit() { // найти таку же функцию или функцию init(). 
   EventSetMillisecondTimer(100); // вставить это в любой части
   }
   
// вот эту функцию вставить целиком
void OnTimer() {
   if(next_signal!=0 && GetTickCount() >= next_signal+1000) {
      next_signal = 0;
      PlaySound(sound_file);
      }
   }
   
// там где нужен звук вставить вместо PlaySound()
next_signal = GetTickCount();

там где next_signal+1000 изменяя 1000 можно регулировать задержку в милисекундах.
 

MrGreen86

Гуру форума
Более сложный вариант, это ставить где-то рядом индикатор менеджер звуков. А эти 2+ индикатора пусть сообщают ему через глобальные переменные о том что нужно подать сигнал и какой.
Вот как это сделать:
вставить в индикатор там где есть сигнал:
PHP:
Expand Collapse Copy
GlobalVariableSet("SM_"+"indicator_name",1);
разумеется indicator_name нужно заменить на имя индикатора
вместо цифры (1) указать номер звукового файла, это будет зависить от того как вы это организуете это в менеджере сигналов.

Вот сам менеджер сигналов:
PHP:
Expand Collapse Copy
#property strict
#property indicator_chart_window

input int      signal_shift_ms   = 1000;

uint last_signal = 0;
//<<<<<<<<
int OnInit() {
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
   }
//<<<<<<<<
void OnTimer() {
   if(GetTickCount() - last_signal < signal_shift_ms) return;
   
   for(int i=GlobalVariablesTotal()-1;i>=0;i--) {
      string glob_name = GlobalVariableName(i);
      if(StringFind(glob_name,"SM_",0)<0) continue;
      int glob_value = (int)GlobalVariableGet(glob_name);
      if(glob_value==0) continue;
      switch(glob_value) {
         case 0: PlaySound("ok.wav"); break;    
         case 1: PlaySound("alert.wav"); break;
         // тут можете дописать свои звуки со своими кодами 
         default: break;
         }
      GlobalVariableDel(glob_name);
      last_signal = GetTickCount();
      }
   }
//<<<<<<<<
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[]) {
   return(rates_total);
   }
//<<<<<<<<

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

Ugar

Гуру форума
Не совсем понятно о системе таймеров. Программа может иметь только 1 таймер. Да и как её организовать, эту очередь, если каждый из полутора десятков открытых индикаторов норовит вперёд пролезть. :question:

Момент, конечно, важен, но не до такой же степени. Не Баха слушать будем. 0.2-0.5 сек сообщение.
Простейший таймер это запомнить время, и сравнивать его с текущим, если прошло заданное количество секунд, сигнал и сброс запомненого времени. Если объединить много таких таймеров, по количеству сигналов - система таймеров. Остаётся организовать очередь из сигналов.
Если все сигналы в пределах одной программы, то очередь можно сделать внутри неё. Если же сигналы в куче индикаторов, то надо делать отдельный индикатор сигнальщик, в нём сделать очередь. Все остальные индикаторы передают ему сигналы через глобальные переменные или файл.
 

AlanTrade

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

Так понятней. Я сразу подумал об OnTimer. К такому решению мы, похоже, все и придём.
Хотя выстроить очередь в одной программе, думаю, можно будет и без таймеров.
Но, всё же остаётся мечта разгрузить терминал и передать функцию соблюдения очереди и воспроизведения системе.Чую, что там она уже решена штатными средствами.
Благодарю.):
 

MrGreen86

Гуру форума
Так понятней. Я сразу подумал об OnTimer. К такому решению мы, похоже, все и придём.
Хотя выстроить очередь в одной программе, думаю, можно будет и без таймеров.
Но, всё же остаётся мечта разгрузить терминал и передать функцию соблюдения очереди и воспроизведения системе.Чую, что там она уже решена штатными средствами.
Благодарю.):

Не решена )
выше я вам дал готовое решение с очередью.
 

AlanTrade

Интересующийся
Более сложный вариант, это ставить где-то рядом индикатор менеджер звуков. А эти 2+ индикатора пусть сообщают ему через глобальные переменные о том что нужно подать сигнал и какой.
Вот как это сделать:
вставить в индикатор там где есть сигнал:
PHP:
Expand Collapse Copy
GlobalVariableSet("SM_"+"indicator_name",1);
разумеется indicator_name нужно заменить на имя индикатора
вместо цифры (1) указать номер звукового файла, это будет зависить от того как вы это организуете это в менеджере сигналов.

Вот сам менеджер сигналов: ...


Спасибо MrGreen86 за доходчивый ответ. Если не найду информации, как переложить эту проблему с терминала на систему, буду делать примерно так.):
Немного смущает постоянная работа с глобальными переменными. Говорят, они тормозят работу, сам не проверял, но стараюсь минимизировать количество обращений к ним.):
 

Ugar

Гуру форума
Немного смущает постоянная работа с глобальными переменными. Говорят, они тормозят работу, сам не проверял, но стараюсь минимизировать количество обращений к ним.):
Может потому что у меня мощный проц и диск SSD, но 1000000 записей и чтений из GV, заняло 204 миллисекунд. Итого запись + чтение занимает 204 наносекунды. Я бы не сказал что это тормозит терминал. Код простейшего скрипта для проверки
void OnStart()
{
//---
int i, n=1000000;
string name="test";
double vol=1;
uint Start=GetTickCount();
for(i=0; i<n; i++)
{
GlobalVariableSet(name,vol);
vol=GlobalVariableGet(name);
}

Print(n," записей и чтений ",GetTickCount()-Start," ms");
}
 
Последнее редактирование:

AlanTrade

Интересующийся
Может потому что у меня мощный проц и диск SSD, но 1000000 записей и чтений из GV, заняло 204 миллисекунд. Итого запись + чтение занимает 204 наносекунды. Я бы не сказал что это тормозит терминал. Код простейшего скрипта для проверки ...

}

Спасибо, попробую.
 
Верх