Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 208

 
Bonjour, je peux vous aider.
Pour l'instant, je ne teste la condition que sur un seul 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); }

Je veux vérifier l'état de différents instruments.

De sorte que les externes peuvent s'écrire comme suit

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


 
Sile Si:
Bonjour, je peux vous aider.
Pour l'instant, je ne teste la condition que sur un seul instrument.

Je veux vérifier l'état de différents instruments.

Je veux pouvoir l'écrire dans les externes comme ceci



Utiliser un tableau au lieu d'une variable

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

et le vérifier dans la boucle.

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]);
 }

Pour entrer tout cela par l'entrée, vous avez besoin d'une chaîne de caractères

"EURUSD, GBPUSD, USDJPY, USDCHF"

dans l'entrée pour la diviser et la mettre dans un tableau. Il existe des fonctions de chaîne pour cela. Et vous pouvez trouver des exemples de telles manipulations dans CodeBase.

 
Alexey Viktorov:    Utiliser un tableau au lieu d'une variable
string SYMBOL_N[4] = "EURUSD, GBPUSD, USDJPY, USDCHF";

La meilleure définition d'un tableau est la suivante

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

Il est préférable de définir le tableau comme suit

C'est exactement ça. Mais le compilateur nous parle très clairement de l'inattention.
 

Bonjour. J'ai un problème avec les indicateurs, cela se produit généralement sur m1 et m5. Cela ressemble à un saut sur tous les indicateurs de la fenêtre du sous-sol et de la fenêtre principale en même temps, comme on peut le voir sur les captures d'écran. Le code d'un des indicateurs.

#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:

Utiliser un tableau au lieu d'une variable

et le vérifier dans la boucle.

Pour entrer tout cela via la saisie, vous avez besoin d'une chaîne de caractères

Inite split et le mettre dans un tableau. Il existe des fonctions de chaîne pour cela. Et vous pouvez trouver des exemples de telles manipulations dans CodeBase.


Merci, cela semble fonctionner, mais si une condition sur plusieurs paires est remplie en même temps, l'alerte ne porte que sur une seule paire.

Parfois, il est simplement indiqué "UP" sans paire de devises. Comment le réparer ?


#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:

Merci, cela semble fonctionner, mais si la condition sur plusieurs paires est remplie en même temps, l'alerte ne porte que sur une seule paire.

Parfois, il est simplement indiqué "UP" sans la paire de devises. Comment le réparer ?



Pourquoi avez-vous besoin de boucler pendant 100 itérations ? Pourquoi avez-vous besoin de centaines de tableaux ?

Pourquoi ne pas le rendre dynamique, et augmenter sa taille et remplir le tableau lorsque vous trouvez un nouveau symbole dans la chaîne d'initialisation?

Et ensuite boucler le nombre d'itérations sur la taille du tableau rempli.

Avez-vous vérifié ce que vous avez dans le tableau ?

 
Sile Si:

Merci, cela semble fonctionner, mais si la condition sur plusieurs paires est remplie en même temps, l'alerte ne porte que sur une seule paire.

Parfois, il est simplement indiqué "UP" sans la paire de devises. Comment puis-je le réparer ?




Faites-le comme ceci

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


Dob. Et dans l'inite, augmentez le tableau au fur et à mesure que vous y ajoutez une valeur.

 
Sile Si:

Merci, cela semble fonctionner, mais si la condition sur plusieurs paires est remplie en même temps, l'alerte ne porte que sur une seule paire.

Parfois, il est simplement indiqué "UP" sans la paire de devises. Comment le réparer ?

Eh bien, essayez :

//+------------------------------------------------------------------+
//|                                                         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);
}
//+------------------------------------------------------------------+

A propos de "...mais si simultanément sur plusieurs paires la condition est remplie, l'alerte ne porte que sur une seule paire..." je dirai ceci :

Vous vérifiez l'heure d'un symbole, mais vous l'écrivez dans une seule variable pour tous les symboles que vous avez. Naturellement, et il n'y aura une alerte que sur le tout premier symbole de cette barre actuelle. Vous avez besoin d'un tableau de structures avec deux champs pour chaque symbole - le champ du nom et le champ de l'heure, et vous y inscrivez déjà les heures d'alerte pour chaque symbole.

Par exemple, comme ceci :

//+------------------------------------------------------------------+
//|                                                         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:

Merci, cela semble fonctionner, mais si la condition sur plusieurs paires est remplie en même temps, l'alerte ne porte que sur une seule paire.

Parfois, il est simplement indiqué "UP" sans la paire de devises. Comment puis-je le réparer ?



Le problème se situe dans cette ligne

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

Puisque je vérifie plusieurs devises sur une barre, en plus du temps, je devrais également vérifier la devise pour éviter de répéter l'alerte sur une barre et un symbole mais permettre de faire une alerte sur la même barre avec un symbole différent. A première vue, nous avons besoin d'un tableau supplémentaire avec des drapeaux indiquant si le symbole est vu ou non.

En général, soit vous ajoutez un contrôle de symbole à cette ligne, soit vous répétez le cycle uniquement à condition qu'une nouvelle barre s'ouvre. Mais j'ai peur que lorsqu'il y a une nouvelle barre sur le symbole avec cet indicateur, la nouvelle barre n'a pas encore été dessinée sur l'autre symbole.

Conclusion : nous devons solliciter les muscles de notre tête pour déterminer si une nouvelle barre apparaît sur chaque symbole séparément, mais en même temps pour ne pas étirer le nombre de lignes à l'infini. Je n'ai pas de solution toute faite. Et je n'aime pas le suggérer en écrivant du code...

Raison: