Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1498

 
jarikn:
Ребята. помогите прикрутить алерт к индикатору. 

к индикаторам в которых:

int start()

int init()

int deinit()

прикручивать что-то, это не уважать ни себя ни других..

возьмите на себя труд и переделайте к современным интерфейсам

 
Aleksei Stepanenko:

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

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

Или так:

Согласен, что в объёмном коде можно легко упустить момент нежелательного изменения переменной (X). С этой позиции, обращение к главной функции каждый раз, когда нужно узнать, что там с X, будет правильным. Но вот в чем вопрос. Если главная функция рассчитывает и выводит несколько различных значений (X, Y, Z) и достаточно объёмна, а Х по ходу программы используется многократно, не будет ли такой подход излишне потреблять вычислительные мощности? Т.е. чтобы узнать Х мы раз за разом гоняем целый блок, где помимо Х также пересчитываются  Y и Z, которые, допустим, были нужны только раз. Поэтому, если в алгоритм заложено последовательное изменение и перезапись Х от очередной функции к функции, то это, возможно, сложнее для программиста (требует больше внимания и проверок на ошибки), но потом легче для машины.

 
Maxim Kuznetsov:

к индикаторам в которых:

int start()

int init()

int deinit()

прикручивать что-то, это не уважать ни себя ни других..

возьмите на себя труд и переделайте к современным интерфейсам

Так и покажите, как это должно выглядеть на современных интерфейсах. Человек судя по всему не программировал ни разу (иначе бы он и с алертом разобрался без нас). Он просто нашёл где-то код, принёс сюда и хочет алерт.

 
Oleksandr Nozemtsev:

Но вот в чем вопрос. Если главная функция рассчитывает и выводит несколько различных значений (X, Y, Z) и достаточно объёмна, а Х по ходу программы используется многократно

int X=0;

void OnTick()
   {
   if(УсловиеДляРедкогоРасчёта) X=ТяжёлыйРедкийРасчёт();
   
   ЛекийПостоянныйРасчёт(X);
   }   
   
 
Ilya Prozumentov:

Так и покажите, как это должно выглядеть на современных интерфейсах. Человек судя по всему не программировал ни разу (иначе бы он и с алертом разобрался без нас). Он просто нашёл где-то код, принёс сюда и хочет алерт.

в каких помойках вы берёте такие "индикаторы" и "советники" ?? но если патокать, то источник не иссякнет..

на сайте подобного нету уже давным давно.

хочет переноса - пусть заводит отдельную тему "старинный индикатор перенести в современный MQL5(4)". Там помогут, объяснят и будет полезно всем. 

или во фриланс

 
Maxim Kuznetsov:

но если патокать

От слова "патока", что ли?

 
jarikn:
Ребята. помогите прикрутить алерт к индикатору. 
#property copyright "Subu"
#property link      "http://www.google.com"
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_width1 2
#property indicator_width2 2
#property indicator_chart_window

double UpArrow[];
double DownArrow[];
extern int ShiftArrow = -2;
extern bool FilterBullBearCandle = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(0, 233);
   SetIndexBuffer(0, UpArrow);
   SetIndexEmptyValue(0,0.0);
   SetIndexShift(0,ShiftArrow);
   SetIndexStyle(1, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(1, 234);
   SetIndexBuffer(1, DownArrow);
   SetIndexEmptyValue(1,0.0);
   SetIndexShift(1,ShiftArrow);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start(){
   int counted_bars=IndicatorCounted();
   int limit, i;
//---- last counted bar will be recounted

   limit=Bars-counted_bars;
//----
   for(i = 1; i < limit; i++){
      DownArrow[i] = 0;
      UpArrow[i] = 0;
      if(High[i+2]>High[i+1] && Low[i+2]>Low[i+1] && High[i+2]>High[i+3] && Low[i+2]>Low[i+3]){
         if( Open[i+1]>Close[i+1] && Close[i+2] > Close[i+1]){
            if(FilterBullBearCandle){
               if( Open[i+2]>Close[i+2]){
                  DownArrow[i] = High[i+2] +0.0003;//Low[i+2] + (High[i+2]-Low[i+2]);
                  if(counted_bars > 0) Alert("Signal down: ", DownArrow[i]);
               }
            }
            else{
                DownArrow[i] = High[i+2] +0.0003;//Low[i+2] + (High[i+2]-Low[i+2]);
                if(counted_bars > 0) Alert("Signal down: ", DownArrow[i]);
            }
         }
      }
      if(High[i+2]<High[i+1] && Low[i+2]<Low[i+1] && High[i+2]<High[i+3] && Low[i+2]<Low[i+3]){
         if(Open[i+1]<Close[i+1] && Close[i+2] < Close[i+1]){
            if(FilterBullBearCandle){
               if( Open[i+2]<Close[i+2]){
                  UpArrow[i] = Low[i+2] - 0.0003;//High[i+2] - (High[i+2]-Low[i+2]);
                  if(counted_bars > 0) Alert("Signal up: ", UpArrow[i]);
               }
            }
            else{
               UpArrow[i] = Low[i+2] - 0.0003;//High[i+2] - (High[i+2]-Low[i+2]);
               if(counted_bars > 0) Alert("Signal up: ", UpArrow[i]);
            }
         }
      }
   }
   return(0);
}
 
Подскажите по mql5 как в функцию передать open,close и ТД из OnCalculate не через параметры функции, чтоб при вызове функции мне не пришлось каждый раз в параметры вписывать открытие закрытие свечей

исходник 
myfunc(int index, double open[], double close[], double high[], double low[] и тд);

хочу
myfunc(int index)

а все данные баров (prev,rates, open[]...и ТД) подсасывались как то внутри функции

 
jarikn:
Ребята. помогите прикрутить алерт к индикатору. 

прикрутил - не помню код из кодобазы и автора - которому нужно сказать спасибо! - если узнает свой код - говорю ему спасибо!

а вот Ваш индикатор - у меня получился - только на мт5 с Алертом.

//+------------------------------------------------------------------+
//|                                                       jarikn.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
//---- номер версии индикатора
#property version   "1.00"
//---- отрисовка индикатора в главном окне
#property indicator_chart_window
//---- для расчета и отрисовки индикатора использовано два буфера
#property indicator_buffers 2
//---- использовано всего два графических построения
#property indicator_plots   2
//+----------------------------------------------+
//|  Параметры отрисовки бычьго индикатора       |
//+----------------------------------------------+
//---- отрисовка индикатора 1 в виде символа
#property indicator_type1   DRAW_ARROW
//---- в качестве цвета бычей линии индикатора использован розовый цвет
#property indicator_color1  Lime
//---- толщина линии индикатора 1 равна 4
#property indicator_width1  2
//---- отображение метки медвежьей линии индикатора
#property indicator_label1  "jarikn Buy"
//+----------------------------------------------+
//|  Параметры отрисовки медвежьего индикатора   |
//+----------------------------------------------+
//---- отрисовка индикатора 2 в виде символа
#property indicator_type2   DRAW_ARROW
//---- в качестве цвета медвежьей линии индикатора использован зеленый цвет
#property indicator_color2  Magenta
//---- толщина линии индикатора 2 равна 4
#property indicator_width2  2
//---- отображение метки бычьей линии индикатора
#property indicator_label2  "jarikn Sell"
//+----------------------------------------------------+
//| перечисление для вариантов транслируемых сигналов  |
//+----------------------------------------------------+
enum ENUM_SIGNAL_MODE
  {
   MODE_SIGNAL,  //Сигналы пробоя
   MODE_TREND    //Сигналы пробоя и тренда
  };
//+----------------------------------------------+
//| Входные параметры индикатора                 |
//+----------------------------------------------+
input int  ShiftArrow = 0;
input group  "---- Входные переменные для алертов ----"
input ENUM_SIGNAL_MODE SignMode=MODE_SIGNAL; //Вариант подачи сигнала
input uint NumberofBar=0;                    //Номер бара для подачи сигнала
input bool SoundON=true;                     //Разрешение алерта
input uint NumberofAlerts=1;                 //Количество алертов
input bool EMailON=false;                    //Разрешение почтовой отправки сигнала
input bool PushON=false;                     //Разрешение отправки сигнала на мобильный
//--- indicator buffers
//---- объявление динамических массивов, которые будут в
//---- дальнейшем использованы в качестве индикаторных буферов
double UpArrow[];
double DownArrow[];

int StartBars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   StartBars=5;
//---- превращение динамического массива в индикаторный буфер
   SetIndexBuffer(0,UpArrow,INDICATOR_DATA);
//---- осуществление сдвига начала отсчета отрисовки индикатора 1
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartBars);
//--- создание метки для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"jarikn Buy");
//---- символ для индикатора
   PlotIndexSetInteger(0,PLOT_ARROW,108);
//---- индексация элементов в буфере как в таймсерии
   ArraySetAsSeries(UpArrow,true);
//--- line shifts when drawing
   PlotIndexSetInteger(0,PLOT_SHIFT,ShiftArrow);
//---- превращение динамического массива в индикаторный буфер
   SetIndexBuffer(1,DownArrow,INDICATOR_DATA);
//---- осуществление сдвига начала отсчета отрисовки индикатора 2
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,StartBars);
//--- создание метки для отображения в DataWindow
   PlotIndexSetString(1,PLOT_LABEL,"jarikn Sell");
//---- символ для индикатора
   PlotIndexSetInteger(1,PLOT_ARROW,108);
//---- индексация элементов в буфере как в таймсерии
   ArraySetAsSeries(DownArrow,true);
//--- line shifts when drawing
   PlotIndexSetInteger(1,PLOT_SHIFT,ShiftArrow);
//---- установка формата точности отображения индикатора
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---- имя для окон данных и лэйба для субъокон
   string short_name="jarikn";
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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(rates_total<StartBars)
      return(0);
   int limit,i;
//---- расчет стартового номера first для цикла пересчета баров
   if(prev_calculated>rates_total || prev_calculated<=0) // проверка на первый старт расчета индикатора
      limit=rates_total-StartBars;   // стартовый номер для расчета всех баров
   else
      limit=rates_total-prev_calculated; // стартовый номер для расчета новых баров
//---- индексация элементов в массивах как в таймсериях
   ArraySetAsSeries(Open,true);
   ArraySetAsSeries(High,true);
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Close,true);
//----
   for(i = 0; i <= limit; i++)
     {
      DownArrow[i] = 0;
      UpArrow[i] = 0;
      if(High[i+2]>High[i+1] && Low[i+2]>Low[i+1] && High[i+2]>High[i+3] && Low[i+2]>Low[i+3])
         if(Open[i+1]>Close[i+1] && Close[i+2] > Close[i+1])
           {
            if(Open[i+2]>Close[i+2])
               DownArrow[i] = High[i+2] +0.0003;//Low[i+2] + (High[i+2]-Low[i+2]);
           }
      if(High[i+2]<High[i+1] && Low[i+2]<Low[i+1] && High[i+2]<High[i+3] && Low[i+2]<Low[i+3])
         if(Open[i+1]<Close[i+1] && Close[i+2] < Close[i+1])
           {
            if(Open[i+2]<Close[i+2])
               UpArrow[i] = Low[i+2] - 0.0003;//High[i+2] - (High[i+2]-Low[i+2]);
           }
     }
//--- alert
   BuySignal("Alert BuySignal",UpArrow,0,rates_total,prev_calculated,Close,spread);
   SellSignal("Alert SellSignal",DownArrow,0,rates_total,prev_calculated,Close,spread);
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Buy signal function                                              |
//+------------------------------------------------------------------+
void BuySignal(string SignalSirname,// текст имени индикатора для почтовых и пуш-сигналов
               double &ColorArray[],// цветовой индексный буфер
               int ColorIndex,// индекс цвета в цветовом индескном буфере для подачи сигнала
               const int Rates_total,     // текущее количество баров
               const int Prev_calculated, // количество баров на предыдущем тике
               const double &Close[],     // цена закрытия
               const int &Spread[])       // спред
  {
//---
   static uint counter=0;
   if(Rates_total!=Prev_calculated)
      counter=0;
   bool BuySignal=false;
   bool SeriesTest=ArrayGetAsSeries(ColorArray);
   int index,index1;
   if(SeriesTest)
     {
      index=int(NumberofBar);
      index1=index+1;
     }
   else
     {
      index=Rates_total-int(NumberofBar)-1;
      index1=index-1;
     }
   if(SignMode==MODE_SIGNAL)
     {
      if(ColorArray[index1]!=ColorIndex && ColorArray[index]==ColorIndex)
         BuySignal=true;
     }
   else
     {
      if(ColorArray[index]==ColorIndex)
         BuySignal=true;
     }
   if(BuySignal && counter<=NumberofAlerts)
     {
      counter++;
      MqlDateTime tm;
      TimeToStruct(TimeCurrent(),tm);
      string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min);
      SeriesTest=ArrayGetAsSeries(Close);
      if(SeriesTest)
         index=int(NumberofBar);
      else
         index=Rates_total-int(NumberofBar)-1;
      double Ask=Close[index];
      double Bid=Close[index];
      SeriesTest=ArrayGetAsSeries(Spread);
      if(SeriesTest)
         index=int(NumberofBar);
      else
         index=Rates_total-int(NumberofBar)-1;
      Bid+=_Point*Spread[index];
      string sAsk=DoubleToString(Ask,_Digits);
      string sBid=DoubleToString(Bid,_Digits);
      string sPeriod=GetStringTimeframe(ChartPeriod());
      if(SignMode==MODE_SIGNAL || (SignMode==MODE_TREND && ColorArray[index1]!=ColorIndex))
        {
         if(SoundON)
            Alert("BUY signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);
         if(EMailON)
            SendMail(SignalSirname+": BUY signal alert","BUY signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
         if(PushON)
            SendNotification(SignalSirname+": BUY signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
        }
      else
        {
         if(SoundON)
            Alert("Up Trend signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);
         if(EMailON)
            SendMail(SignalSirname+": Up Trend signal alert","BUY signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
         if(PushON)
            SendNotification(SignalSirname+": Up Trend signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| Sell signal function                                             |
//+------------------------------------------------------------------+
void SellSignal(string SignalSirname,// текст имени индикатора для почтовых и пуш-сигналов
                double &ColorArray[],       // цветовой индексный буфер
                int ColorIndex,             // индекс цвета в цветовом индескном буфере для подачи сигнала
                const int Rates_total,     // текущее количество баров
                const int Prev_calculated, // количество баров на предыдущем тике
                const double &Close[],     // цена закрытия
                const int &Spread[])       // спред
  {
//---
   static uint counter=0;
   if(Rates_total!=Prev_calculated)
      counter=0;
   bool SellSignal=false;
   bool SeriesTest=ArrayGetAsSeries(ColorArray);
   int index,index1;
   if(SeriesTest)
     {
      index=int(NumberofBar);
      index1=index+1;
     }
   else
     {
      index=Rates_total-int(NumberofBar)-1;
      index1=index-1;
     }
   if(SignMode==MODE_SIGNAL)
     {
      if(ColorArray[index1]!=ColorIndex && ColorArray[index]==ColorIndex)
         SellSignal=true;
     }
   else
     {
      if(ColorArray[index]==ColorIndex)
         SellSignal=true;
     }
   if(SellSignal && counter<=NumberofAlerts)
     {
      counter++;
      MqlDateTime tm;
      TimeToStruct(TimeCurrent(),tm);
      string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min);
      SeriesTest=ArrayGetAsSeries(Close);
      if(SeriesTest)
         index=int(NumberofBar);
      else
         index=Rates_total-int(NumberofBar)-1;
      double Ask=Close[index];
      double Bid=Close[index];
      SeriesTest=ArrayGetAsSeries(Spread);
      if(SeriesTest)
         index=int(NumberofBar);
      else
         index=Rates_total-int(NumberofBar)-1;
      Bid+=_Point*Spread[index];
      string sAsk=DoubleToString(Ask,_Digits);
      string sBid=DoubleToString(Bid,_Digits);
      string sPeriod=GetStringTimeframe(ChartPeriod());
      if(SignMode==MODE_SIGNAL || (SignMode==MODE_TREND && ColorArray[index1]!=ColorIndex))
        {
         if(SoundON)
            Alert("SELL signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);
         if(EMailON)
            SendMail(SignalSirname+": SELL signal alert","SELL signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
         if(PushON)
            SendNotification(SignalSirname+": SELL signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
        }
      else
        {
         if(SoundON)
            Alert("Down trend signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);
         if(EMailON)
            SendMail(SignalSirname+": Down trend signal alert","SELL signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
         if(PushON)
            SendNotification(SignalSirname+": Down trend signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);
        }
     }
//---
  }
//+------------------------------------------------------------------+
//|  Получение таймфрейма в виде строки                              |
//+------------------------------------------------------------------+
string GetStringTimeframe(ENUM_TIMEFRAMES timeframe)
  {
//----
   return(StringSubstr(EnumToString(timeframe),7,-1));
//----
  }
//+------------------------------------------------------------------+
 
Алексей КоКоКо:
а все данные баров (prev,rates, open[]...и ТД) подсасывались как то внутри функции

Как это подсасывались? Так?

void MyFunc()
   {
   double high=iHigh(symbol,frame,0);

   }
Причина обращения: