Please HELP with executing code once per bar

 

Hi please help.

Below is a test code for placing arrows and sending e-mails based on two conditions. When attached to a chart, it backfills when conditions are met. This is intentional.

I am unable to limit the e-mails to one per bar when the conditions are met. I am currently trying to use Time[0] == TimeCurrent() to identify the first tick of the bar but it is not working.

Can someone please tell me how I can make the code execute only at the first tick of each bar as opposed to every tick?

Thanks

 

Here's my example:

#property indicator_chart_window
extern double MA_Period;
extern double MA_Shift;
//----------
int start(){
static datetime Close_Time;
//----------
double Simple_MA=iMA(NULL,0,MA_Period,MA_Shift,MODE_SMA,PRICE_CLOSE,1);
//----------
if (Close_Time != Time[0])
{
   if (Close[1] > Simple_MA)
   {
      Alert("Bar Closed ABOVE Simple_MA");
      SendMail("From MetaTrader Bar Closed ABOVE Simple_MA At: ",Close[1]);
      Close_Time=Time[0];
   }
   
   if (Close[1] < Simple_MA)
   {
      Alert("Bar Closed BELOW Simple_MA");
      SendMail("From MetaTrader Bar Closed BELOW Simple_MA At: ",Close[1]);
      Close_Time=Time[0];
   }
}
//----------
return(0);}
 
texcan:

Hi please help.

Below is a test code for placing arrows and sending e-mails based on two conditions. When attached to a chart, it backfills when conditions are met. This is intentional.

I am unable to limit the e-mails to one per bar when the conditions are met. I am currently trying to use Time[0] == TimeCurrent() to identify the first tick of the bar but it is not working.

Can someone please tell me how I can make the code execute only at the first tick of each bar as opposed to every tick?

Thanks

The following works for me...

      if( LastSignal != Time[0] )
      {
           // do whatever you want to do once per bar,
           // then reset the global variable...
           LastSignal = Time[0];
      }
Good luck, let me know how it goes, Helmut
 
engcomp:

The following works for me...

Good luck, let me know how it goes, Helmut


Hi engcomp & Ubzen
Your codes appears to be similar. I tried using them but I still get multiple e-mails per bar. I hae posted my code and would appreciate your feedback
thanks again.

//====================================================

// Custom indicator that sends e-mail and places arrows. Problem is that it sends multiple e-mails.


#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Aqua
#property indicator_color2 Orange

extern int MA_Type = MODE_SMA;
extern int Period_MA_1 = 48;

double ma48;

double Bull[];
double Bear[];

int init()
{
//---- indicators
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 225);
SetIndexBuffer(0, Bull);

SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 226);
SetIndexBuffer(1, Bear);

return(0);
}

int start()
{

int counted_bars = IndicatorCounted();
int i;
int limit;
if(counted_bars < 0)
return(-1);
if(counted_bars > 0)
counted_bars--;
limit = Bars - counted_bars;
for(i=0; i<=limit; i++)
{

ma48 = iMA(Symbol(),0,Period_MA_1,0,MA_Type,Close[i+1],i);

if ( Close[i+1] > ma48 )
{ Bull[i] = Low[i] - 0.0005; }

if( Close[i+1] < ma48 )
{ Bear[i] = High[i] + 0.0005; }


static datetime Close_Time;

if ( Close_Time != Time[0])
{//

if ( Close[i+1] > ma48 )
{ SendMail("EUR up", "test" ) ; }

if( Close[i+1] < ma48 )
{ SendMail("EUR down", "test") ; }
}//


}
return(0);
}

 

  1. You never update Close_Time
 

- Please use the SRC button left of the camera button when you submit code.

- I'll recommend learning to code EA's first instead of indicators, easier to test.

- You're forgetting to set the time-stamp. Here:

- If it's still not working, you may wanna change static datetime to just datetime. 

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Aqua 
#property indicator_color2 Orange

extern int MA_Type = MODE_SMA;
extern int Period_MA_1 = 48;

double ma48; 

double Bull[];
double Bear[];

int init()
{
//---- indicators
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 225);
SetIndexBuffer(0, Bull);

SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 226);
SetIndexBuffer(1, Bear);

return(0);
}

int start()
{

int counted_bars = IndicatorCounted();
int i;
int limit;
if(counted_bars < 0) 
return(-1);
if(counted_bars > 0) 
counted_bars--;
limit = Bars - counted_bars;
for(i=0; i<=limit; i++)
{

ma48 = iMA(Symbol(),0,Period_MA_1,0,MA_Type,Close[i+1],i);

if ( Close[i+1] > ma48 )
{ Bull[i] = Low[i] - 0.0005; } 

if( Close[i+1] < ma48 )
{ Bear[i] = High[i] + 0.0005; }


static datetime Close_Time;

if ( Close_Time != Time[0])
{
   if ( Close[i+1] > ma48 )
   {
      SendMail("EUR up", "test" );
       Close_Time = Time[0]; //You are forgetting to set Time-Stamp.
   }

   if( Close[i+1] < ma48 )
   {
      SendMail("EUR down", "test");
       Close_Time = Time[0]; //You are forgetting to set Time-Stamp.
   }
}


}
return(0);
}
 
texcan:

int start()

...

static datetime Close_Time;

May I suggest that you declare Close_Time as a global variable (above init() and start())?

If you read my post again, you will see that that is what I do, and it works for me.

And don't forget to update it as WHRoeder and ubzen suggest, or read my post again.

Please report back, Helmut

 

MT Devs recommend the following:

//---- do thing only for first tiks of new bar
   if(Volume[0]>1) return;

It will exit the function if other but the first tick of a bar!!! anything after this line will be executed only once...

Volume is tick volume in MT. U can use variations like if (Volume = 1) ...some code...; However try to stay with the first variation as ticks can come very fast and your code to skip the mail... or use Sleep(10000) to allow 10sec pause (Sleep works only if in experts not indicators)

Good luck U should be fine with the above...

 
kmtm:

MT Devs recommend the following: [...]

No, they don't. Checks on Volume[0] are not reliable (except in backtesting).

For examples of the many discussions of this, and the alternative to use instead, see topics such as https://www.mql5.com/en/forum/109887, https://www.mql5.com/en/forum/125732, and https://www.mql5.com/en/forum/125906.

 
jjc:

No, they don't. Checks on Volume[0] are not reliable (except in backtesting).

For examples of the many discussions of this, and the alternative to use instead, see topics such as https://www.mql5.com/en/forum/109887, https://www.mql5.com/en/forum/125732, and https://www.mql5.com/en/forum/125906.

I don't like it either but, Devs use it in their indicators. It's true you can loose a signal once in a while during connection problems but for "email trading" it should be fine.

Comparing bar time as suggested earlier or making the for loop execute only once per bar is of course better...

"except in backtesting" - don't know where you got this from but in back testing ticks do not exist at all... they can only be emulated in a tester... only their volume exist so checking for ticks in history data is nonsense.

I don't also like some elements in the above code and the fact that works backwards... it often creates problems with processing the last bar.

regards...

 
ubzen:

- Please use the SRC button left of the camera button when you submit code.

- I'll recommend learning to code EA's first instead of indicators, easier to test.

- You're forgetting to set the time-stamp. Here:

- If it's still not working, you may wanna change static datetime to just datetime.


Hi everyone,
I tried your suggestions and it seems to work nicely. I essentially used Ubzen's code (thanks)
I will try and expand on it and let you know if it still works.

Cheers.

Reason: