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

 
Hallo, bitte um Hilfe.
Im Moment teste ich die Bedingung nur an einem Instrument.
string SYMBOL_N = "EURUSD";

if(iOpen(SYMBOL_N, PERIOD_CURRENT, 1)< iClose(SYMBOL_N, PERIOD_CURRENT, 1)&&iOpen(SYMBOL_N, PERIOD_CURRENT, 2)> iClose(SYMBOL_N, PERIOD_CURRENT, 2));
{Alert("UP" SYMBOL_N); }

Ich möchte den Zustand verschiedener Instrumente überprüfen.

So können die externen wie folgt geschrieben werden

input string SYMBOL_N = "EURUSD, GBPUSD, USDJPY, USDCHF";


 
Sile Si:
Hallo, bitte um Hilfe.
Im Moment teste ich die Bedingung nur an einem Instrument.

Ich möchte den Zustand der verschiedenen Instrumente überprüfen.

Ich möchte in der Lage sein, es in den externen wie folgt zu schreiben



Ein Array statt einer Variablen verwenden

string SYMBOL_N[4] = "EURUSD, GBPUSD, USDJPY, USDCHF";

und überprüfen Sie es in der Schleife.

for(int i = 0; i < 4; i++)
 {
  if(iOpen(SYMBOL_N[i], PERIOD_CURRENT, 1)< iClose(SYMBOL_N[i], PERIOD_CURRENT, 1)&&iOpen(SYMBOL_N[i], PERIOD_CURRENT, 2)> iClose(SYMBOL_N[i], PERIOD_CURRENT, 2));
   Alert("UP" SYMBOL_N[i]);
 }

Um all dies über die Eingabe einzugeben, benötigen Sie eine Zeichenkette

"EURUSD, GBPUSD, USDJPY, USDCHF"

in der Eingabe, um sie aufzuteilen und in ein Array zu stellen. Hierfür gibt es String-Funktionen. Beispiele für solche Manipulationen finden Sie in CodeBase.

 
Alexey Viktorov:    Ein Array statt einer Variablen verwenden
string SYMBOL_N[4] = "EURUSD, GBPUSD, USDJPY, USDCHF";

Ein Array ist am besten wie folgt definiert

   string SYMBOL_N[4] = {"EURUSD", "GBPUSD", "USDJPY", "USDCHF"};
 
STARIJ:

Es ist besser, das Array wie folgt einzustellen

Das ist genau richtig. Aber der Compiler sagt uns ganz klar, was Unaufmerksamkeit ist.
 

Hallo. Ich habe ein Problem mit den Blinkern, es passiert normalerweise auf m1 und m5. Es sieht aus wie ein Sprung auf allen Anzeigen des Kellerfensters und des Hauptfensters gleichzeitig, wie auf den Screenshots zu sehen ist. Der Code eines der Indikatoren.

#property indicator_chart_window
#property indicator_buffers 8
#property  indicator_color1 Blue 
#property  indicator_color2 Green
#property  indicator_color3 Green
#property  indicator_color4 Red 
#property  indicator_color5 LightSeaGreen
#property  indicator_color6 Red
#property  indicator_color7 LightSeaGreen
#property  indicator_color7 LightSeaGreen

extern bool sig_Vred=false;
extern bool sig_Vsea=false;
extern bool sig_Vgreen=false;
extern bool sig_Ngreen=false;
extern bool sig_Nsea=false;
extern bool sig_Nred=false;
extern int    BandsPeriod=70;
extern int    BandsShift=0;
extern int    PeriodsATR= 70;
static int sig, my;
static double plus;
//static string gn2, gnm, gns;

double MovingBuffer[];
double UpperBuffer[];
double UpperBmax[];
double UpperBuffer2[];
double LowerBuffer[];
double LowerBmax[];
double LowerBuffer2[];

int init()
  {
   SetIndexBuffer(0,MovingBuffer);    SetIndexStyle(0,DRAW_NONE); 
   SetIndexBuffer(1,UpperBuffer);     SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2,LowerBuffer);     SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(3,UpperBmax);       SetIndexStyle(3,DRAW_LINE);
   SetIndexBuffer(4,UpperBuffer2);    SetIndexStyle(4,DRAW_LINE);//,STYLE_SOLID,2);
   SetIndexBuffer(5,LowerBmax);       SetIndexStyle(5,DRAW_LINE);  
   SetIndexBuffer(6,LowerBuffer2);    SetIndexStyle(6,DRAW_LINE);//,STYLE_SOLID,2);
   SetIndexDrawBegin(0,BandsPeriod+BandsShift);
   SetIndexDrawBegin(1,BandsPeriod+BandsShift);
   SetIndexDrawBegin(2,BandsPeriod+BandsShift);
   SetIndexDrawBegin(3,BandsPeriod+BandsShift);
   SetIndexDrawBegin(4,BandsPeriod+BandsShift);
   SetIndexDrawBegin(5,BandsPeriod+BandsShift);
   SetIndexDrawBegin(6,BandsPeriod+BandsShift);
   
   if(Digits==5){if(Close[0]>1)plus=0.0001; else plus=0.00007;}
   if(Digits==3){if(Close[0]>100)plus=0.01; else plus=0.007;}    
   if(Period()<10)plus=0;  if(Period()>60)plus=plus*2;
   if(Period()>1) my=0; else  my=3;

   return(0);
  }

int start()
  {
   static datetime time0;
   static double hig, loww;
   if(time0!=Time[0]){ time0=Time[0]; hig=0; loww=1000;}
   if((High[0]>hig)||(Low[0]<loww))  {hig=High[0]+plus; loww=Low[0]-plus;
   
   int    i,k,counted_bars=IndicatorCounted();
   double deviation;
   double sum,oldval;
   
   if(Bars<=BandsPeriod) return(0);

   if(counted_bars<1)
      for(i=1;i<=BandsPeriod;i++)
        {
         MovingBuffer[Bars-i]=EMPTY_VALUE;
         UpperBuffer[Bars-i]=EMPTY_VALUE;
         UpperBmax[Bars-i]=EMPTY_VALUE;
         UpperBuffer2[Bars-i]=EMPTY_VALUE;
         LowerBuffer[Bars-i]=EMPTY_VALUE;
         LowerBmax[Bars-i]=EMPTY_VALUE;
         LowerBuffer2[Bars-i]=EMPTY_VALUE;
        }

   int limit=Bars-counted_bars;
   if(counted_bars>0) limit++;
   for(i=0; i<limit; i++)
      MovingBuffer[i]=iMA(NULL,0,BandsPeriod,BandsShift,my,PRICE_CLOSE,i);

   i=Bars-BandsPeriod+1;
   if(counted_bars>BandsPeriod-1) i=Bars-counted_bars-1; if(Period()==1)i++;
   while(i>=0)
     {
      sum=0.0;
      k=i+BandsPeriod-1;
      oldval=MovingBuffer[i];
      
      deviation=iATR(NULL,0,PeriodsATR,i);
      UpperBmax[i]=oldval+deviation*6.618;
      UpperBuffer2[i]=oldval+deviation*4.236;
      UpperBuffer[i]=oldval+deviation*1.618;
      LowerBuffer[i]=oldval-deviation*1.618;
      LowerBuffer2[i]=oldval-deviation*4.236;
      LowerBmax[i]=oldval-deviation*6.618; 
      i--; 
     }
          
     if(sig_Vred==true && sig==0 && Close[0]>UpperBmax[0]){sig=1; Alert(Symbol()+" Vred "+Period());}// if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if(sig_Nred==true && sig==0 && Close[0]<LowerBmax[0]){sig=1; Alert(Symbol()+" Nred "+Period());}// if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}  
     if(sig_Vsea==true && sig==0 && Close[0]>UpperBuffer2[0]){sig=1; Alert(Symbol()+" Vsea "+Period());}// if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if(sig_Nsea==true && sig==0 && Close[0]<LowerBuffer2[0]){sig=1; Alert(Symbol()+" Nsea "+Period());}// if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if(sig_Vgreen==true && sig==0 && Close[0]>UpperBuffer[0]){sig=1; Alert(Symbol()+" Vgreen "+Period());}// if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if(sig_Ngreen==true && sig==0 && Close[0]<LowerBuffer[0]){sig=1; Alert(Symbol()+" Ngreen "+Period());}// if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
      
     }
   return(0);
  }
 
Alexey Viktorov:

Ein Array statt einer Variablen verwenden

und überprüfen Sie es in der Schleife.

Um all dies über die Eingabe einzugeben, benötigen Sie einen String

Inite split und schiebe es in ein Array. Hierfür gibt es String-Funktionen. Beispiele für solche Manipulationen finden Sie in CodeBase.


Danke, es scheint zu funktionieren, aber wenn eine Bedingung für mehrere Paare gleichzeitig erfüllt ist, wird die Meldung nur für ein Paar angezeigt.

Manchmal steht dort nur "UP" ohne Währungspaar. Wie kann man das beheben?


#property strict
#property indicator_chart_window

extern string Symbols = "EURUSD, GBPUSD, USDJPY"; //

string symbols_arr[100];
datetime time_b;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
        IndicatorShortName("UP DN");
        SetSymbols(Symbols);
//---
   return(INIT_SUCCEEDED);
  }
  void SetSymbols(string text) {

  int i = 0, j;

  for(i=0; i<100; i++)
   symbols_arr[i]="";

   i=0;
   string fValue;
   string Str = text;

   while (StringLen(Str)>0) 
   {
      j = StringFind(Str, ",");
      if(j>=0) 
      {
         fValue = StringSubstr(Str, 0, j);
         Str    = StringSubstr(Str, j+1);
      } else {
         fValue = Str;
         Str    = "";
      }
      fValue=StringTrimLeft(fValue);
      fValue=StringTrimRight(fValue);
      symbols_arr[i]=fValue;
      i++;
   }
   
   //colCount = i;
}
// ----------------- 
//+------------------------------------------------------------------+
//| 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[])
  {
//---


for(int i = 0; i < 100; i++)
 {
  if(iOpen(symbols_arr[i], PERIOD_CURRENT, 1)< iClose(symbols_arr[i], PERIOD_CURRENT, 1)&&iOpen(symbols_arr[i], PERIOD_CURRENT, 2)> iClose(symbols_arr[i], PERIOD_CURRENT, 2))
  {
   if(time_b!=iTime(symbols_arr[i], PERIOD_CURRENT, 0))
   {
   Alert("UP - " ,symbols_arr[i]);
   time_b=iTime(symbols_arr[i], PERIOD_CURRENT, 0);
   }
  }
 }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+----


 
Sile Si:

Danke, es scheint zu funktionieren, aber wenn die Bedingung für mehrere Paare gleichzeitig erfüllt ist, wird die Meldung nur für ein Paar angezeigt.

Manchmal steht dort nur "UP" ohne das Währungspaar. Wie kann man das beheben?



Warum brauchen Sie eine Schleife mit 100 Iterationen? Wozu brauchen Sie 100er-Arrays?

Warum machen Sie es nicht dynamisch, vergrößern es und füllen das Array, wenn Sie ein neues Symbol in der Initialisierungszeichenfolge finden?

Die Anzahl der Iterationen hängt dann von der Größe des gefüllten Arrays ab.

Haben Sie überprüft, was Sie im Array haben?

 
Sile Si:

Danke, es scheint zu funktionieren, aber wenn die Bedingung für mehrere Paare gleichzeitig erfüllt ist, wird die Meldung nur für ein Paar angezeigt.

Manchmal steht dort nur "UP" ohne das Währungspaar. Wie kann ich es reparieren?




Mach es so

int Size_symbols=ArraySize(symbols_arr)
 
for(int i = 0; i < Size_symbols; i++)
  { 
   //  бла..бла..бла
  }


Dob. Und in der Inite vergrößern Sie das Array, wenn Sie ihm einen Wert hinzufügen

 
Sile Si:

Danke, es scheint zu funktionieren, aber wenn die Bedingung für mehrere Paare gleichzeitig erfüllt ist, wird die Meldung nur für ein Paar angezeigt.

Manchmal steht dort nur "UP" ohne das Währungspaar. Wie kann man das beheben?

Probieren Sie es aus:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|              Copyright 2017, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Artem A. Trishkin, Skype artmedia70"
#property link      "https://login.mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict
#property indicator_chart_window

input string Symbols = "EURUSD, GBPUSD, USDJPY"; // Список символов, разделитель - запятая

string symbols_array[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorShortName("UP DN");
   ushort sz=SetSymbols(Symbols,symbols_array);
   if(sz==0) {
      Print("Список символов пуст!");
      return(INIT_FAILED);
      }
//---
   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[])
  {
//---
   static datetime time_b=0,time_s=0;
   for(int i=0; i<ArraySize(symbols_array); i++) {
      if(Condition(symbols_array[i],1)==ORDER_TYPE_BUY) {
         if(time_b!=iTime(symbols_array[i],PERIOD_CURRENT,0)) {
            Alert("UP - " ,symbols_array[i]);
            time_b=iTime(symbols_array[i],PERIOD_CURRENT,0);
            }
         }
      if(Condition(symbols_array[i],1)==ORDER_TYPE_SELL) {
         if(time_s!=iTime(symbols_array[i],PERIOD_CURRENT,0)) {
            Alert("Down - " ,symbols_array[i]);
            time_s=iTime(symbols_array[i],PERIOD_CURRENT,0);
            }
         }
      }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Condition(string symbol_name,int shift) {
   MqlRates array[];
   if(CopyRates(symbol_name,PERIOD_CURRENT,shift,2,array)==2){
      if(array[0].open<array[0].close && array[1].open>array[1].close) return(ORDER_TYPE_BUY);
      if(array[0].open>array[0].close && array[1].open<array[1].close) return(ORDER_TYPE_SELL);
      }
   return(WRONG_VALUE);
}
//+------------------------------------------------------------------+
ushort SetSymbols(string symbols_list,string &array[]){
   symbols_list+=","; // Добавим признак конца строки
   short beg=WRONG_VALUE, end=1, len=(short)StringLen(symbols_list);
   string sy="";
   Print(__FUNCTION__," > ",symbols_list); // Посмотрим символы в строке
   while(beg<len) {
      beg++;
      end=(short)StringFind(symbols_list,",",beg);
      if(end==beg || end<0) continue;
      sy=StringSubstr(symbols_list,beg,end-beg);
      if(CheckSymbol(sy,array) || !IsPresentSymbol(sy)) continue;
      ushort sz=(ushort)ArraySize(array);
      ArrayResize(array,sz+1);
      array[sz]=sy;
      //--- Посмотрим корректность найденного символа и записи его в массив
      Print("beg=",IntegerToString(beg,2,'0'),", end=",IntegerToString(end,2,'0'),", sy=|",sy,"|",", in array[",sz,"]=",array[sz]);
      }
   return((ushort)ArraySize(array));
}
//+------------------------------------------------------------------+
bool CheckSymbol(string symbol_name,string &array[]){
   for(short i=0; i<ArraySize(array); i++) if(array[i]==symbol_name) return(true);
   return(false);
}
//+------------------------------------------------------------------+
bool IsPresentSymbol(string symbol_name){
   for(ushort i=0; i<SymbolsTotal(false); i++){
      if(SymbolName(i,false)==symbol_name) {
         SymbolSelect(symbol_name,true);
         return(true);
         }
      }
   return(false);
}
//+------------------------------------------------------------------+

Zu "...aber wenn die Bedingung bei mehreren Paaren gleichzeitig erfüllt ist, erfolgt die Ausschreibung nur bei einem Paar..." möchte ich Folgendes sagen:

Sie prüfen die Zeit eines Symbols, aber Sie schreiben sie in eine einzige Variable für alle Symbole, die Sie haben. Natürlich wird nur das allererste Symbol auf dem aktuellen Balken alarmiert. Sie benötigen ein Array von Strukturen mit zwei Feldern für jedes Symbol - Namensfeld und Zeitfeld, und schreiben bereits Alarmzeiten für jedes Symbol hinein.

Zum Beispiel so:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|              Copyright 2017, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Artem A. Trishkin, Skype artmedia70"
#property link      "https://login.mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict
#property indicator_chart_window

input string Symbols = "EURUSD, GBPUSD, USDJPY"; // Список символов, разделитель - запятая
//---
struct SSymbolsData
  {
   string   name;       // Имя символа
   datetime time_alert; // Время последнего алерта
  };
SSymbolsData symbols_array[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorShortName("UP DN");
   ushort sz=SetSymbols(Symbols,symbols_array);
   if(sz==0) {
      Print("Список символов пуст!");
      return(INIT_FAILED);
      }
//---
   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[])
  {
//---
   for(int i=0; i<ArraySize(symbols_array); i++) {
      if(Condition(symbols_array[i].name,1)==ORDER_TYPE_BUY) {
         datetime tm=iTime(symbols_array[i].name,PERIOD_CURRENT,0);
         if(symbols_array[i].time_alert!=tm) {
            Alert("UP - " ,symbols_array[i].name,", time: ",TimeToString(tm,TIME_DATE|TIME_MINUTES));
            symbols_array[i].time_alert=tm;
            }
         }
      if(Condition(symbols_array[i].name,1)==ORDER_TYPE_SELL) {
         datetime tm=iTime(symbols_array[i].name,PERIOD_CURRENT,0);
         if(symbols_array[i].time_alert!=tm) {
            Alert("Down - " ,symbols_array[i].name,", time: ",TimeToString(tm,TIME_DATE|TIME_MINUTES));
            symbols_array[i].time_alert=tm;
            }
         }
      }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Condition(string symbol_name,int shift) {
   MqlRates array[];
   if(CopyRates(symbol_name,PERIOD_CURRENT,shift,2,array)==2){
      if(array[0].open<array[0].close && array[1].open>array[1].close) return(ORDER_TYPE_BUY);
      if(array[0].open>array[0].close && array[1].open<array[1].close) return(ORDER_TYPE_SELL);
      }
   return(WRONG_VALUE);
}
//+------------------------------------------------------------------+
ushort SetSymbols(string symbols_list,SSymbolsData &array[]){
   symbols_list+=","; // Добавим признак конца строки
   short beg=WRONG_VALUE, end=1, len=(short)StringLen(symbols_list);
   string sy="";
   Print(__FUNCTION__," > ",symbols_list); // Посмотрим символы в строке
   while(beg<len) {
      beg++;
      end=(short)StringFind(symbols_list,",",beg);
      if(end==beg || end<0) continue;
      sy=StringSubstr(symbols_list,beg,end-beg);
      if(CheckSymbol(sy,array) || !IsPresentSymbol(sy)) continue;
      ushort sz=(ushort)ArraySize(array);
      ArrayResize(array,sz+1);
      array[sz].name=sy;
      array[sz].time_alert=0;
      //--- Посмотрим корректность найденного символа и записи его в массив
      Print("beg=",IntegerToString(beg,2,'0'),", end=",IntegerToString(end,2,'0'),", sy=|",sy,"|",", in array[",sz,"]=",array[sz].name);
      }
   return((ushort)ArraySize(array));
}
//+------------------------------------------------------------------+
bool CheckSymbol(string symbol_name,SSymbolsData &array[]){
   for(short i=0; i<ArraySize(array); i++) if(array[i].name==symbol_name) return(true);
   return(false);
}
//+------------------------------------------------------------------+
bool IsPresentSymbol(string symbol_name){
   for(ushort i=0; i<SymbolsTotal(false); i++){
      if(SymbolName(i,false)==symbol_name) {
         SymbolSelect(symbol_name,true);
         return(true);
         }
      }
   return(false);
}
//+------------------------------------------------------------------+
 
Sile Si:

Danke, es scheint zu funktionieren, aber wenn die Bedingung für mehrere Paare gleichzeitig erfüllt ist, wird die Meldung nur für ein Paar angezeigt.

Manchmal steht dort nur "UP" ohne das Währungspaar. Wie kann ich es reparieren?



Das Problem liegt in dieser Zeile

if(time_b!=iTime(symbols_arr[i], PERIOD_CURRENT, 0))

Da ich mehrere Währungen auf einem Balken prüfe, sollte ich neben der Zeit auch die Währung prüfen, um zu vermeiden, dass die Warnung auf einem Balken und einem Symbol wiederholt wird, sondern eine Warnung auf demselben Balken mit einem anderen Symbol zu ermöglichen. Auf den ersten Blick brauchen wir ein weiteres Array mit Flags, die anzeigen, ob das Symbol angezeigt wird oder nicht.

Im Allgemeinen kann man entweder eine Symbolprüfung in diese Zeile einfügen oder den Zyklus nur unter der Bedingung wiederholen, dass sich ein neuer Balken öffnet. Aber ich habe die Befürchtung, dass, wenn es einen neuen Balken auf dem Symbol mit diesem Indikator gibt, der neue Balken noch nicht auf dem anderen Symbol gezeichnet worden ist.

Die Schlussfolgerung: Wir müssen unsere Kopfmuskeln anstrengen, um festzustellen, ob ein neuer Balken auf jedem einzelnen Symbol erscheint, aber gleichzeitig die Anzahl der Zeilen nicht ins Unendliche zu dehnen. Ich habe keine fertige Lösung. Und ich mag es nicht vorschlagen, indem ich Code schreibe...

Grund der Beschwerde: