Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 208

 
Hello, help please.
Right now I'm only testing the condition on one 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); }

I want to check the condition on different instruments.

So that the external ones can be written as follows

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


 
Sile Si:
Hello, help please.
Right now I'm only testing the condition on one instrument.

I want to check the condition on different instruments.

I want to be able to write it in the external ones like this



Use an array instead of a variable

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

and check it in the loop.

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

To enter all this through the input, you need a string

"EURUSD, GBPUSD, USDJPY, USDCHF"

in the input to split it and put it into an array. There are string functions for this. And you can find examples of such manipulations in CodeBase.

 
Alexey Viktorov:    Use an array instead of a variable
string SYMBOL_N[4] = "EURUSD, GBPUSD, USDJPY, USDCHF";

An array is best defined as follows

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

It is better to set the array as follows

That's exactly right. But the compiler tells us about inattention quite clearly.
 

Hello. I have a problem with the indicators, it usually happens on m1 and m5. It looks like a jump on all indicators of the basement window and the main one at the same time, can be seen on the screenshots. The code of one of the indicators.

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

Use an array instead of a variable

and check it in the loop.

To enter all this via input you need a string

Inite split and shove it into an array. There are string functions for this. And you can find examples of such manipulations in CodeBase.


Thanks, it seems to work, but if a condition is fulfilled on several pairs at the same time, the alert is only on one pair.

Sometimes it just says "UP" without currency pair. How to fix it?


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

Thanks, it seems to be working, but if the condition on several pairs is fulfilled at the same time, the alert is only on one pair.

Sometimes it just says "UP" without the currency pair. How to fix it?



Why do you need to loop for 100 iterations? Why do you need 100's of array?

Why not make it dynamic, and increase its size and fill the array as you find a new symbol in the initializing string?

And then loop in the number of iterations on the size of the filled array.

Have you checked what you have in the array?

 
Sile Si:

Thanks, it seems to be working, but if the condition on several pairs is fulfilled at the same time, the alert is only on one pair.

Sometimes it just says "UP" without the currency pair. How can I fix it?




Make it like this

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


Dob. And in the inite, increase the array as you add a value to it

 
Sile Si:

Thank you, it seems to be working, but if a condition is met on several pairs at the same time, the alert is only on one pair.

Sometimes it just says "UP" without the currency pair. How to fix it?

Well, try it:

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

About "...but if simultaneously on several pairs the condition is fulfilled, the alert is only on one pair..." I will say this:

You check the time on a symbol, but you write it into one single variable for all the symbols you have. Naturally, and there will only be an alert on the very first symbol on this current bar. You need an array of structures with two fields for each symbol - name field and time field, and already write alert times for each symbol into it.

For example, like this:

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

Thanks, it seems to be working, but if the condition on several pairs is fulfilled at the same time, the alert is only on one pair.

Sometimes it just says "UP" without the currency pair. How can I fix it?



The problem is in this line

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

Since I check several currencies on one bar, besides time I should also check the currency to avoid repeating the alert on one bar and one symbol but allow making an alert on the same bar with a different symbol. At first glance, we need one more array with flags whether the symbol is viewed or not.

In general either add symbol check to this line, or repeat cycle only on condition of new bar opening. But I have a fear that when there is a new bar on the symbol with this indicator, the new bar has not yet been drawn on the other symbol.

The conclusion: we must strain our head muscles to determine whether a new bar appears on each symbol separately, but at the same time not to stretch the number of lines to infinity. I have no ready-made solution. And I don't like to suggest it by writing code...

Reason: