Индикаторов много и у каждого свои сигналы. Но при этом обработка оповещений и отправка оповещений - это повторяющийся алгоритм, думаю будет лучше, если разделить функционал:
- Отдельный класс, пока назову его "Alerts", который ведёт подсчёт сигналов и занимается отправкой оповещений.
- А в индикаторах будет блок, который ищет сигналы и передаёт название сигнала в объект класса "Alerts".
Формат вывода оповещений ещё не определён, но уже есть такие кандидаты:
- Alert
- Push
- Comment
- вывод графического объекта на график
- ...
Этот список имело бы смысл реализовывать в виде плагина на универсальном интерфейсе с условным названием Action, т.е. абстрактным и расширяемым. Например, чтобы любой желающий мог потом сделать сохранение в базу, отправку на сайт через WebRequest или - что самое интересное - в некое централизованное хранилище сигналов (также с вариантами хранения, начиная, например, с простейшего на глобальных переменных), откуда эксперты могли бы считывать сигналы. Плюсы очевидны, но есть и минус: поскольку система плагинов основывается на позднем связывании, не получится во входном параметре индикатора зашить удобный список доступных действий. Или я пока не могу придумать как это сделать наглядно - кроме как через некую интерфейсную панель с объектами.
В принципе, наиболее правильно, если бы сама платформа (терминал) позволял для алерта указывать параметрическую информацию о торговом смысле алерта, а не просто какую-то строку. Но это все мечты.
...не получится во входном параметре индикатора зашить удобный список доступных действий...
Да, именно это большая проблема. Допустим класс "Alerts" имеет пять методов (пересечения там всякие, или больше меньше ...) - но вот всё это засунуть во входные параметры нельзя. Максимально, что можно сделать во входных параметрах (чтобы иметь возможность выбора) - это Перечисления. Но это получается не динамический метод. Всё нужно "зашивать" во входные параметры заранее.
В общем пока пойду таким путём: класс "Alerts" будет только принимать описание сигнала и вести подсчёт - определять можно ещё просигналить или нужно пропустить.
Не по плану, но всё же индикатор с индикацией. "MACD and lines" - рисует вертикальные линии в местах, где сигнальная линия пересекает ноль:
Возможно добавлю стиль DRAW_FILLING - так будет явно видны зоны для покупок и для продаж.
Не по плану, но всё же индикатор с индикацией. "MACD and lines" - рисует вертикальные линии в местах, где сигнальная линия пересекает ноль:
Возможно добавлю стиль DRAW_FILLING - так будет явно видны зоны для покупок и для продаж.
Данный код был доработан:
- убраны вертикальные линии
- стиль рисования теперь DRAW_FILLING
- можно выбирать для какой линии (основной или сигнальной) рисуется индикатор
и размещён в КодоБазе: MACD Crossing the zero level
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Tribute_penny, 2017.10.31 22:17
Добрый день, уважаемые форумчане! Искал здесь, но к сожалению пока не нашел.
Последняя закрытая свеча пересекла в любую сторону скользящее - из ЭВМ раздается однократно звук, либо сообщение на электропочту, либо еще какой-то сигнал со звуком (смс и т.д.).
Может у кого-то есть что-нибудь подобное уже написанное?
Оповещение об пересечении индикатором Moving Average бара N:
Alert Crossing MovingAverage Nth Bar:
Сигнал (звуковой файл, уведомление на email, push) при пересечении индикатором iMA (Moving Average, MA) бара под номером N.
Входные параметры:
- period of ma - период усреднения индикатора Moving Average
- ma_shift - смешение индикатора Moving Average
- ma_method - тип усреднения индикатора Moving Average
- applied_price - цена на которой идёт расчёт индикатора Moving Average
- Play sound - флаг проигрывания звукового файла
- sound_filename - название звукового файла
- Send mail - флаг отсылки уведомления на email
- Send notification - флаг отсылки push
- N bar - номер бара, для которого проверяется пересечение с индикатором Moving Average
Спасибо! Я переделал индикатор под пересечение главной линии MACD с сигнальной, но там ума не надо, унутри все нужное есть... сам бы ни за что не смог сделать.
PlaySound бы еще добавить с возможностью устанавливать свой wav файл. Поскриплю мозгами на выходных, для меня это сложная задача :)
Спасибо! Я переделал индикатор под пересечение главной линии MACD с сигнальной, но там ума не надо, унутри все нужное есть... сам бы ни за что не смог сделать.
PlaySound бы еще добавить с возможностью устанавливать свой wav файл. Поскриплю мозгами на выходных, для меня это сложная задача :)
В любом случае выкладывайте свой MQL5 код - если будут вопросы.
В любом случае выкладывайте свой MQL5 код - если будут вопросы.
Владимир, выкладываю. Я совершенно не умею программировать, поэтому приходится использовать чисто смекалку. В MT4 было легче, в МТ5 у меня даже замечательную функцию iCustom не получается использовать :(
Индикатор должен сигнализировать взаимное расположение основной и сигнальной линий MACD и проигрывать задаваемые пользователем звуковые файлы при пересечении этих линий сверху вниз и снизу вверх (соответственно, можно сделать 2 речевых файла, чтобы они говорили что и куда пересеклось, для каждого инструмента. Хотя я лично торгую только фьюч на индекс РТС).
Вопрос - туда ли я воткнул функцию PlaySound, и не будет ли она звонить пока свечка не закончится? Как ограничить число повторов, я не знаю...
Те места, которые я менял, я отметил значками ?????????? в примечаниях чтобы сразу было заметно. Там четыре строчки всего...
PS сейчас воткнул его на график, так он стал безостановочно квакать, видать, пытаясь подать сигналы за всю историю графика...
//+------------------------------------------------------------------+ //| MACD Crossing the zero level.mq5 | //| Copyright © 2017, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2017, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" #property description "Moving Average Convergence/Divergence and lines" #property description "Filling crossing the zero level" #include <MovingAverages.mqh> //--- indicator settings #property indicator_chart_window #property indicator_buffers 6 #property indicator_plots 1 #property indicator_label1 "Crossing" #property indicator_type1 DRAW_FILLING #property indicator_color1 clrRed,clrBlue #property indicator_width1 1 //+------------------------------------------------------------------+ //| Base crossing line | //+------------------------------------------------------------------+ enum BASE_CROSSING_LINE { MACD=0, // MACD Signal=1, // Signal }; //--- input parameters input int InpFastEMA=2; // Fast EMA period input int InpSlowEMA=800; // Slow EMA period input int InpSignalSMA=64; // Signal SMA period input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // Applied price input string sound_UP = "alert.wav"; // Play sound file name ?????????????????????????????????????? input string sound_DOWN = "wait.wav"; // Play sound file name ?????????????????????????? input BASE_CROSSING_LINE InpBaseCrossingLine=Signal; // Crossing the zero level //--- indicator buffers double ExtCrossingBuffer1[]; double ExtCrossingBuffer2[]; double ExtMacdBuffer[]; double ExtSignalBuffer[]; double ExtFastMaBuffer[]; double ExtSlowMaBuffer[]; //--- MA handles int ExtFastMaHandle; int ExtSlowMaHandle; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ExtCrossingBuffer1,INDICATOR_DATA); SetIndexBuffer(1,ExtCrossingBuffer2,INDICATOR_DATA); SetIndexBuffer(2,ExtMacdBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(3,ExtSignalBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(4,ExtFastMaBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(5,ExtSlowMaBuffer,INDICATOR_CALCULATIONS); //--- sets first bar from what index will be drawn if(InpBaseCrossingLine==Signal) { PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpSignalSMA-1); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,InpSignalSMA-1); } //--- name for Dindicator subwindow label IndicatorSetString(INDICATOR_SHORTNAME,"MACD Crossing the zero level("+string(InpFastEMA)+","+string(InpSlowEMA)+","+string(InpSignalSMA)+")"); //--- get MA handles ExtFastMaHandle=iMA(NULL,0,InpFastEMA,0,MODE_EMA,InpAppliedPrice); ExtSlowMaHandle=iMA(NULL,0,InpSlowEMA,0,MODE_EMA,InpAppliedPrice); //--- initialization done } //+------------------------------------------------------------------+ //| Moving Averages Convergence/Divergence | //+------------------------------------------------------------------+ 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[]) { //--- check for data if(rates_total<InpSignalSMA) return(0); //--- not all data may be calculated int calculated=BarsCalculated(ExtFastMaHandle); if(calculated<rates_total) { Print("Not all data of ExtFastMaHandle is calculated (",calculated,"bars ). Error",GetLastError()); return(0); } calculated=BarsCalculated(ExtSlowMaHandle); if(calculated<rates_total) { Print("Not all data of ExtSlowMaHandle is calculated (",calculated,"bars ). Error",GetLastError()); return(0); } //--- we can copy not all data int to_copy; if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total; else { to_copy=rates_total-prev_calculated; if(prev_calculated>0) to_copy++; } //--- get Fast EMA buffer if(IsStopped()) return(0); //Checking for stop flag if(CopyBuffer(ExtFastMaHandle,0,0,to_copy,ExtFastMaBuffer)<=0) { Print("Getting fast EMA is failed! Error",GetLastError()); return(0); } //--- get SlowSMA buffer if(IsStopped()) return(0); //Checking for stop flag if(CopyBuffer(ExtSlowMaHandle,0,0,to_copy,ExtSlowMaBuffer)<=0) { Print("Getting slow SMA is failed! Error",GetLastError()); return(0); } //--- int limit; if(prev_calculated==0) limit=0; else limit=prev_calculated-1; //--- calculate MACD for(int i=limit;i<rates_total && !IsStopped();i++) ExtMacdBuffer[i]=ExtFastMaBuffer[i]-ExtSlowMaBuffer[i]; //--- calculate Signal SimpleMAOnBuffer(rates_total,prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer); //--- draw or move line for(int i=limit;i<rates_total && !IsStopped();i++) { if(InpBaseCrossingLine==Signal) { if(ExtSignalBuffer[i]<ExtMacdBuffer[i]) // uptrend ???????????????????????????????? { ExtCrossingBuffer1[i]=low[i]; ExtCrossingBuffer2[i]=0.0; } else // downtrend { ExtCrossingBuffer1[i]=0.0; ExtCrossingBuffer2[i]=low[i]; } if(ExtMacdBuffer[i]<ExtSignalBuffer[i] && ExtMacdBuffer[i+1]>ExtSignalBuffer[i+1]) // change to downtrend ????????????????????????? { PlaySound(sound_DOWN); } if(ExtMacdBuffer[i]>ExtSignalBuffer[i] && ExtMacdBuffer[i+1]<ExtSignalBuffer[i+1]) // change to uptrend ????????????????????????? { PlaySound(sound_UP); } } } //--- OnCalculate done. Return new prev_calculated. return(rates_total); } //+------------------------------------------------------------------+
Владимир, выкладываю. Я совершенно не умею программировать, поэтому приходится использовать чисто смекалку. В MT4 было легче, в МТ5 у меня даже замечательную функцию iCustom не получается использовать :(
Индикатор должен сигнализировать взаимное расположение основной и сигнальной линий MACD и проигрывать задаваемые пользователем звуковые файлы при пересечении этих линий сверху вниз и снизу вверх (соответственно, можно сделать 2 речевых файла, чтобы они говорили что и куда пересеклось, для каждого инструмента. Хотя я лично торгую только фьюч на индекс РТС).
Вопрос - туда ли я воткнул функцию PlaySound, и не будет ли она звонить пока свечка не закончится? Как ограничить число повторов, я не знаю...
Те места, которые я менял, я отметил значками ?????????? в примечаниях чтобы сразу было заметно. Там четыре строчки всего...
Да, будет пиликать без умолку.
Здесь нужно два момента учесть:
- когда prev_calculated == 0 (такое при первом запуске, при подкачке истории) - это означает, что нужно пересчитывать весь индикатор на всю историю, звук не нужно включать
- второе: знонилку звуковую нужно вынести в отдельную функцию, в которой считать кол-во повторов, величину паузы между сигналами

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Здесь будут модернизированные стандартные индикаторы: каждый индикатор будет давать оповещение для своих сигналов.
Например технический индикатор Схождение/Расхождение Скользящих Средних (Moving Average Convergence/Divergence, MACD) может выдавать сигнал Пересечения:
Пересечения
Основное правило торговли с помощью MACD построено на пересечениях индикатора со своей сигнальной линией: когда Moving Average Convergence/Divergence опускается ниже сигнальной линии — следует продавать, а когда поднимается выше сигнальной линии — покупать. В качестве сигналов к покупке/продаже также используются пересечения MACD нулевой линии вверх/вниз.
Значит модернизированный индикатор MACD при поступлении такого сигнала будет сигнализировать пользователю - на таком-то символе, на таком-то таймфрейме появился сигнал "Пересечения". Формат вывода оповещений ещё не определён, но уже есть такие кандидаты: