Price cross MA, EA entry signal problem. Please help!

 

Hello, I am coding an entry signal where when price opens below an MA line and close above it, go long and vice versa.

The code I have done is shown below, the problem i am stuck with is the "sig" value.

When the short condition is fulfilled, sig valued -1, but when the very next candle starts, sig turns to 1 without long condition triggered. It doesn't stay -1.

Appreciate if anyone who can kindly help with this problem, i want the "sig" to stay -1 or 1 after one short or long condition is fulfilled, because i need to wait for other signals, and turn to 1 or -1 when the opposite entry condition is fulfilled.


void OnTick()                                                                                           
   {

double sig;    
//--- Price ----------------------------------------------------------------------------------------
MqlRates PriceInfo[];                                                                               
ArraySetAsSeries(PriceInfo,true);                                                                   
CopyRates(_Symbol,_Period,0,3,PriceInfo);                                                           

//---- MA -----------------------------------------------------------------------------------------
double Array[];                                                                                     
int ma = iMA(_Symbol,_Period,5,0,MODE_SMA,PRICE_CLOSE);                                             
ArraySetAsSeries(Array,true);                                                                       
CopyBuffer(ma,0,0,3,Array);                                                                         
                                                                                                                                                                                                    //
double Close1 = PriceInfo[1].close;    double Open1 = PriceInfo[1].open;                            
double Close2 = PriceInfo[2].close;    double Open2 = PriceInfo[2].open;                            
                                                                                                    
if(((Open1 < Array[1]) && (Close1 > Array[1]))||                             
   ((Open2 < Close2 <Array[2])&&(Array[1] < Open1 < Close1)))                                   
   {sig = 1;} 
                                                                                                                                                                                     
if(((Open1 > Array[1]) && (Close1 < Array[1]))||                             
   ((Open2 > Close2 >Array[2])&&(Array[1] > Open1 > Close1)))                                   
   {sig = -1;}
                                                                                  
Comment ("\n",
         "open1=",Open1,
         "\n",
         "Close1 = ", Close1,
         "\n",
         "linevalue = ",Array[1],
         "\n",
         "signal = ",sig,
         "\n"                                                                                   
          );           

}
 
Freda Z:

Hello, I am coding an entry signal where when price opens below an MA line and close above it, go long and vice versa.

Notice that you're going to take action when a candle closes? Good. So why not do the checks when the next candle opens? You just need to add a new bar check, and from there access all previous values with a shift >= 1.

You don't even need CopyRates to do this.

int MAhandle;

int OnInit()
  {
   MAhandle=iMA(_Symbol,_Period,5,0,MODE_SMA,PRICE_CLOSE);
   if(MAhandle==INVALID_HANDLE) { Print("invalid iMA handle"); return INIT_FAILED; }
   return INIT_SUCCEEDED;
  }

void OnTick()                                                                                           
  {
   bool sellsig=false;
   bool buysig=false;

   if(IsNewBar())
     {
      static double buffer[1];
      int shift=1;
      int amount=1;
      if(CopyBuffer(MAhandle,MAIN_LINE,shift,amount,buffer)!=amount) { Print("CopyBuffer failed, error: ",GetLastError()); ExpertRemove(); return; }
      double ma1=buffer[0];
      double open1=iOpen(_Symbol,_Period,shift);
      double close1=iClose(_Symbol,_Period,shift);
      if(open1<ma1 && close1>ma1) buysig=true;
      if(open1>ma1 && close1<ma1) sellsig=true;
     }
   ... maintain/open/close positions etc
  }
 
Freda Z:

Hello, I am coding an entry signal where when price opens below an MA line and close above it, go long and vice versa.

The code I have done is shown below, the problem i am stuck with is the "sig" value.

When the short condition is fulfilled, sig valued -1, but when the very next candle starts, sig turns to 1 without long condition triggered. It doesn't stay -1.

Appreciate if anyone who can kindly help with this problem, i want the "sig" to stay -1 or 1 after one short or long condition is fulfilled, because i need to wait for other signals, and turn to 1 or -1 when the opposite entry condition is fulfilled.


if I understand it correctly, you want "sig" to

- stay 1 once it has been set to 1 or

- stay -1 once it has been set to -1

if so, then why not just forbid the opposite condition to become true by saying

if (sig!=-1)
  {
   if(((Open1 < Array[1]) && (Close1 > Array[1]))||                             
     ((Open2 < Close2 <Array[2])&&(Array[1] < Open1 < Close1)))                                   
     {sig = 1;}
  } 
if (sig!=1)
  {                                                                                                                                                                                     
   if(((Open1 > Array[1]) && (Close1 < Array[1]))||                             
      ((Open2 > Close2 >Array[2])&&(Array[1] > Open1 > Close1)))                                   
      {sig = -1;}
  }

In order to allow "sig" to ever change its value again, you can simply define sig=0 once you are okay with it to change again (e.g. because your other entry criteria are met or you are out of the trade again...). I guess this should work.

 
Chris70:

if I understand it correctly, you want "sig" to

- stay 1 once it has been set to 1 or

- stay -1 once it has been set to -1

if so, then why not just forbid the opposite condition to become true by saying

In order to allow "sig" to ever change its value again, you can simply define sig=0 once you are okay with it to change again (e.g. because your other entry criteria are met or you are out of the trade again...). I guess this should work.

Hi Chris,

Thanks for the help, you understand me correctly, but sadly the modification didnt work. The sig just kept changing to 1, i also have tried to put sig equal to -1 repeatetively when it should be -1 and it wasnt. The whole thing didnt make any difference because the original coding should do the work already. After several tryouts I finally found the problem, it is because I reintroduce sig on every tick. So a simple global variable sig should solve the problem. Thanks you again for the reply and help.

 
lippmaje:

Notice that you're going to take action when a candle closes? Good. So why not do the checks when the next candle opens? You just need to add a new bar check, and from there access all previous values with a shift >= 1.

You don't even need CopyRates to do this.

Hi lippmaje,

Thank you again for the help. I think the codings i posted do make checks on the previous candle (and the candle before the previous one if necessary). I see that your codings are much simpler and faster in real trading, thanks for the advanced codes, I'll replace the old lines with your more efficient ones.

 

Great.

Here's the function to detect a new bar:

bool IsNewBar()
  {
   static datetime lastBarTime=0;
   datetime thisBarTime=iTime(_Symbol,_Period,0);
   if(thisBarTime==lastBarTime) return false;
   lastBarTime=thisBarTime;
   return true;
  }

void OnTick()
  {
   bool isNewBar=IsNewBar();
   if(isNewBar)
     {
      // heavy stuff going on here...
     }
   // normal operations here...
  }
Reason: