Download MetaTrader 5

Prevent EA from getting restarted every time when switched to another time period

To add comments, please log in or register
Sign up for MQL5.community to post your Forum topic
gvdraganov
33
gvdraganov 2014.12.18 13:09 

Thanks for reading this.


My goal is to have the code run in the background unaffected by me changing the time period (M1, M5 etc.). Right now, once the time period is changed, the code gets restarted from the top and my whole "Counter"-logic (see code below) doesn't work.


Goal of the EA: check all time periods of a symbol every 5 min for certain logic and notify me if condition true. Here, for testing purposes I have left the condition to simply RSI>30.


Regarding the 5 min time interval: Since I am a complete beginner and couldn't figure out how to do it with EventSetTimer, I thought of a more basic way to work around it using the current minutes and asking whether they are equal to 0,5,10,15,20 etc.


If someone has an idea how to:

a. make it not get restarted every time I change the time period (perhaps another handling function might be better or instead of EA to run it as a script (?!) )

b. apply the 5 min condition in a nicer/smarter/shorter way,


I would be extremely grateful.


Many thanks in advance and have a great day!


Code here:


bool Counter=false;
int Periods[9];

int start()
  {
   double Cur_Min =Minute();
   if (Counter==false && (Cur_Min==0||Cur_Min==5||Cur_Min==10||Cur_Min==15||Cur_Min==20||Cur_Min==25||Cur_Min==30||Cur_Min==35||Cur_Min==40||Cur_Min==45||Cur_Min==50||Cur_Min==55))
      {
      Counter=true;
      Executor();
      }
   if (Counter==true && (Cur_Min==4||Cur_Min==9||Cur_Min==14||Cur_Min==19||Cur_Min==24||Cur_Min==29||Cur_Min==34||Cur_Min==39||Cur_Min==44||Cur_Min==49||Cur_Min==54||Cur_Min==59))
      {
      Counter=false;
      }
   return;
  }
//----------------------------------------
int Executor()
  {
      double MACD = 0.0;
      double RSI = 0.0;
      
      Periods[0]=PERIOD_M1;
      Periods[1]=PERIOD_M5;
      Periods[2]=PERIOD_M15;
      Periods[3]=PERIOD_M30;   
      Periods[4]=PERIOD_H1;  
      Periods[5]=PERIOD_H4;
      Periods[6]=PERIOD_D1;
      Periods[7]=PERIOD_W1;  
      Periods[8]=PERIOD_MN1;
      
         for(int M=0;M<9;M++)
            {
               MACD = iMACD(NULL,Periods[M],12,26,9,PRICE_CLOSE,MODE_MAIN,0);
               RSI = iRSI(NULL,Periods[M],14,PRICE_CLOSE,0);
               if(RSI>30)
               Alert(Symbol(),", M",Periods[M],", ",RSI);
            }
   return;
  }
Carl Schreiber
6589
Carl Schreiber 2014.12.18 13:16  

You can't, the EAs and the indicators are restarted in case of a timeframe change.

You can only attach your EA to a chart and leave it as it is.

To see what happens open a different chart and watch this.

gvdraganov
33
gvdraganov 2014.12.18 14:16  

Is there a way to do it as a script then?


In the end, my idea was to then expand it to multiple symbols (100 or more) and have it search on all of them for my logic every 5 min.. It would be a mess if I have each and every chart twice.

Carl Schreiber
6589
Carl Schreiber 2014.12.18 14:41  

Your EA can open a new chart ChartOpen() (in the reference) in case of special situations and close it again ChartClose() ?

gvdraganov
33
gvdraganov 2014.12.18 18:40  

Thanks a lot!


I think I am getting closer to what I wanted. I changed it to pop-up the window only if the condition is true. The only thing now if to figure out how to open the chart in the template I use. Any idea?


#define N_minutes 60000
int Periods[9];
string Charts[3];

int start()
 {
      double MACD = 0.0;
      double RSI = 0.0;
      
      Periods[0]=PERIOD_M1;
      Periods[1]=PERIOD_M5;
      Periods[2]=PERIOD_M15;
      Periods[3]=PERIOD_M30;   
      Periods[4]=PERIOD_H1;  
      Periods[5]=PERIOD_H4;
      Periods[6]=PERIOD_D1;
      Periods[7]=PERIOD_W1;  
      Periods[8]=PERIOD_MN1;
     
      Charts[0]="EURUSD";
      Charts[1]="GBPUSD";
      Charts[3]="USDJPY";
      
      for(int N=0;N<3;N++)
         {
            for(int M=0;M<9;M++)
               {
                  MACD = iMACD(Charts[N],Periods[M],12,26,9,PRICE_CLOSE,MODE_MAIN,0);
                  RSI = iRSI(Charts[N],Periods[M],14,PRICE_CLOSE,0);
                  if(RSI>70)
                  {
                  Alert(Symbol(),", M",Periods[M],", ",RSI);
                  long IDChart = ChartOpen( Charts[N], Periods[M]);
                  }
               }
          }
     Sleep(5*N_minutes);
     return;
  }
whroeder1
14504
whroeder1 2014.12.18 19:30  
Nocciolate: open the chart in the template I use. Any idea?

EAname.tpl, default.tpl, tester.tpl are the defaults.

No point initializing constant arrays each tickYou can simplify initializing arrays with constants
int Periods[9];
string Charts[3];

int start()
 {
      double MACD = 0.0;
      double RSI = 0.0;

      Periods[0]=PERIOD_M1;
      Periods[1]=PERIOD_M5;
      Periods[2]=PERIOD_M15;
      Periods[3]=PERIOD_M30;
      Periods[4]=PERIOD_H1;
      Periods[5]=PERIOD_H4;
      Periods[6]=PERIOD_D1;
      Periods[7]=PERIOD_W1;
      Periods[8]=PERIOD_MN1;

      Charts[0]="EURUSD";
      Charts[1]="GBPUSD";
      Charts[3]="USDJPY";

      for(int N=0;N<3;N++)
int Periods[] = {PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30,
                 PERIOD_H1, PERIOD_H4, PERIOD_D1PERIOD_W1,
                 PERIOD_MN1};
string Charts[] = {"EURUSD", "GBPUSD", "USDJPY"};
int start()
{
      double MACD = 0.0;
      double RSI = 0.0;
      for(int N=0;N<3;N++)

Carl Schreiber
6589
Carl Schreiber 2014.12.18 19:45  
Nocciolate:

Thanks a lot!

I think I am getting closer to what I wanted. I changed it to pop-up the window only if the condition is true. The only thing now if to figure out how to open the chart in the template I use. Any idea?

I think ChartApplyTemplate() is what you are looking for.

gvdraganov
33
gvdraganov 2014.12.21 11:23  

Thanks a whole lot guys! I got so far as to make it run and even apply the template to all newly opened charts (where condition true). The very last thing I am struggling on is to have it first check whether the chart hasn't been already open, and if not, only then pop it up. Otherwise, bring the already opened chart to top. I tried with Can't get it to run though. Any ideas?


#include <WinUser32.mqh>
#import "user32.dll"
#import
#define N_minutes 60000
extern int templateIndex = 4;


int Periods[] = {PERIOD_M5, PERIOD_M15, PERIOD_M30,
                 PERIOD_H1, PERIOD_H4, PERIOD_D1,  PERIOD_W1,
                 PERIOD_MN1};
string Charts[] = {"EURUSD", "GBPUSD", "USDJPY"};
double MACD;
double RSI;


int start()
     {
         for(int N=0;N<3;N++)

         {
            for(int M=0;M<8;M++)
               {
                  MACD = iMACD(Charts[N],Periods[M],12,26,9,PRICE_CLOSE,MODE_MAIN,0);
                  RSI = iRSI(Charts[N],Periods[M],14,PRICE_CLOSE,0);
                  if(RSI>70)
                  {
                     Alert(Charts[N],", M",Periods[M],", ",RSI);
                  
                  
                  
                     if(WindowHandle(Charts[N],Periods[M])==true)
                        {
                        ChartSetInteger(WindowHandle(Charts[N],Periods[M]),CHART_BRING_TO_TOP);
                        PostMessageA(WindowHandle(Charts[N],Periods[M]),WM_COMMAND,34800+templateIndex,0);
                        }
                     else
                        {  
                        long IDChart = ChartOpen(Charts[N],Periods[M]);
                        PostMessageA(WindowHandle(Charts[N],Periods[M]),WM_COMMAND,34800+templateIndex,0);
                        }
                  
                  
                  
                  }
               }
         }
         Sleep(5*N_minutes);
         return;
     }
Carl Schreiber
6589
Carl Schreiber 2014.12.21 11:58  

I was struggling with exactly the same problem. :(

The simplest way does not work: I stored the the chartID in a global variable checking whether it exists.. but the global vars are double and the ChartID is long and so big (close to the long limit - why the hell? Only 100 are allowed!) and the twice casted values (long->double->long) differ from the initial ChartID!

So you have to use either a file or you use or you have to count the chart yourself.

The good thing about GolbalValues is you can use GlobalVariableTemp() which exists only while the terminal is running (no need to update and admin the files).

gvdraganov
33
gvdraganov 2014.12.22 07:39  

I managed to figure out how to partially solve the problem. If the chart is already open, it at least doesn't create a new one and alerts it's open. Now I am trying to figure out how to bring it on top, if existing chart found.

Here's what I have so far

// remains the same 

                  MACD = iMACD(Charts[N],Periods[M],12,26,9,PRICE_CLOSE,MODE_MAIN,0);
                  RSI = iRSI(Charts[N],Periods[M],14,PRICE_CLOSE,0);
                  if(RSI>70)
                     {
                        if(WindowHandle(Charts[N],Periods[M])>0)
                           {
                              Alert(Charts[N],", M",Periods[M],", ",RSI, " / Chart already opened");
                           }
                        else
                           {  
                              long IDChart = ChartOpen(Charts[N],Periods[M]);
                              PostMessageA(WindowHandle(Charts[N],Periods[M]),WM_COMMAND,34800+templateIndex,0);
                              Alert(Charts[N],", M",Periods[M],", ",RSI, " / New chart opened");
                           }
                                  
                     }

// remains the same


Here's the idea I had for the bringing on top, but it still doesn't work entirely. (I have left couple of empty alerts (X,Y,Z,Done,Works) for testing purposes - just to see how the loops go..). The only thing left is to figure out how to make it go into the "Works"-IF loop.


string Charts[] = {"EURUSD", "GBPUSD"};
int Periods[] = {PERIOD_M5, PERIOD_M15};


int init()
{
   for(int N=0;N<2;N++)
      {
         Alert("X");
         for(int M=0;M<2;M++)
            {
               Alert("Y");
               int i=0,limit=100;
               while(i<limit)
                  {
                     long currChart,prevChart=ChartFirst();
                     long chartid=ChartFirst();
                     if(currChart<0)
                        {
                           Alert("Done");
                           i=limit;
                        }
                     Alert("Z");
                     if(ChartSymbol(chartid)==Charts[N] && ChartPeriod(chartid)==Periods[M])
                        {
                        Alert("Works");
                        i=limit;
                        }
                     currChart=ChartNext(prevChart);
                     Alert(currChart);

                     prevChart=currChart;
                     i++;
                  }
            }
      }
}
     
     
Carl Schreiber
6589
Carl Schreiber 2014.12.22 08:37  

Why don't you put the values of the if(..) in the Alert("Z") one line above?

Then you can see why it doesn't become true?

12
To add comments, please log in or register