Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 1498

 
jarikn:
Leute, helft mir, einen Alarm mit dem Indikator zu verbinden.

zu den Indikatoren, in denen:

int start()

int init()

int deinit()

Etwas aufzuschrauben bedeutet nicht, sich selbst oder andere zu respektieren...

sich die Mühe machen, das Design auf moderne Schnittstellen umzustellen

 
Aleksei Stepanenko:

Wenn Sie eine globale Variable in einer Funktion ändern, wird sie sich ändern. Dies ist jedoch eine gefährliche Art der Programmierung, da der Code mit der Zeit wächst und es zu unübersichtlichen Zuweisungen in verschiedenen Funktionen des Programms kommt.

Im Programm gibt es eine Hauptfunktion, in der Sie die Zuweisung der globalen Variablen vornehmen. Und bei anderen Funktionen machen Sie es so:

Oder so:

Ich stimme zu, dass man in umfangreichem Code leicht den Sinn einer unerwünschten Variablenänderung (X) übersehen kann. Unter diesem Gesichtspunkt ist es richtig, die Hauptfunktion jedes Mal aufzurufen, wenn Sie herausfinden wollen, was mit X nicht in Ordnung ist. Aber hier ist die Frage. Wenn die Hauptfunktion mehrere verschiedene Werte (X, Y, Z) berechnet und ausgibt und ziemlich groß ist, während X im Laufe des Programms wiederholt verwendet wird, verbraucht dieser Ansatz dann nicht übermäßig viel Rechenleistung? D.h., um X zu erhalten, führen wir wiederholt einen ganzen Block durch, in dem wir zusätzlich zu X auch Y und Z neu berechnen , was, sagen wir, nur einmal nötig war. Wenn der Algorithmus also eine sequentielle Änderung und Überschreibung von X von einer Funktion zur anderen beinhaltet, kann er für einen Programmierer komplizierter sein (erfordert mehr Aufmerksamkeit und Prüfungen auf Fehler), aber für die Maschine ist er einfacher.

 
Maxim Kuznetsov:

zu den Indikatoren, in denen:

int start()

int init()

int deinit()

Etwas aufzuschrauben bedeutet nicht, sich selbst oder andere zu respektieren...

Machen Sie sich die Mühe, das Design auf moderne Schnittstellen umzustellen

Zeigen Sie mir also, wie es auf modernen Schnittstellen aussehen muss. Der Mann hat offenbar noch nie gecodet (sonst hätte er den Alert ohne uns herausgefunden). Er hat den Code irgendwo gefunden, ihn hierher gebracht und will eine Ausschreibung.

 
Oleksandr Nozemtsev:

Aber hier ist die Frage. Wenn die Hauptfunktion mehrere verschiedene Werte (X, Y, Z) berechnet und ausgibt und ziemlich groß ist und X auf dem Weg dorthin viele Male verwendet wird

int X=0;

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

Zeigen Sie uns, wie es auf modernen Schnittstellen aussehen sollte. Es scheint, dass der Mann nie programmiert hat (sonst hätte er den Alarm ohne uns herausgefunden). Er hat den Code irgendwo gefunden, ihn hierher gebracht und will eine Ausschreibung.

Woher bekommen Sie solche "Indikatoren" und "Ratgeber"? aber wenn Sie es schmelzen, wird die Quelle nicht versiegen...

so etwas gibt es auf der Website schon lange nicht mehr.

Wenn der Hersteller dieser Indikatoren nicht erfolgreich war, ist der Markt zum neuen MQL5(4) übergegangen. Sie werden dort helfen und Dinge erklären, und das wird für alle nützlich sein.

oder gehen Sie zu Freiberufler

 
Maxim Kuznetsov:

aber wenn Melasse

Von dem Wort Melasse, nicht wahr?

 
jarikn:
Leute, helft mir, einen Alarm an den Indikator anzuhängen.
#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);
}
 
Bitte beraten Sie mql5, wie man der Funktion open,close und TD von OnCalculate nicht über die Funktionsparameter übergeben kann, so dass ich nicht jedes Mal das Öffnen und Schließen von Candlesticks in die Parameter beim Aufruf der Funktion schreiben muss

Quelle
myfunc(int index, double open[], double close[], double high[], double low[] usw.)

Ich möchte
myfunc(int index)

und alle Taktdaten (prev,rates, open[]...etc.) werden in diese Funktion geschrieben

 
jarikn :
Leute. helfen, die Warnung an der Anzeige zu befestigen.

geschraubt - ich erinnere mich nicht an den Code aus der Codebasis und an den Autor - dem ich danken muss! - wenn er seinen Code erkennt - sage ich ihm danke!

und hier ist Ihr Indikator - ich habe es getan - nur auf MT5 mit Alert.

 //+------------------------------------------------------------------+
//|                                                       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 ));
//----
  }
//+------------------------------------------------------------------+
 
Алексей КоКоКо:
und alle Taktdaten (prev,rates, open[]...und TD) wurden irgendwie in die Funktion gesaugt

Wie wurde es angesaugt? Etwa so?

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

   }
Grund der Beschwerde: