Need some help with EA, something not right here

 

Hello,

I'm pretty confused at the moment, I always programmed EA's in MQL4 with no trouble, but everything seems to be going wrong with MQL5.  Please help me and see what I am doing wrong.

Just for starters I programmed an easy EMA cross, but it wont work.  I have tried everything.  Below is the code and a screen shot of how the EA behaved.

Would appreciate any help.

Thanks! 

#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <EA.mqh>
#include <Trade\Trade.mqh>

input ENUM_TIMEFRAMES tf  = PERIOD_H1;
input int      emaslow = 18;
input int      emafast = 4;
input int      emashift = 0;


 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
MqlTick latest_price;      // To be used for getting recent/latest price quotes
  
SymbolInfoTick(_Symbol,latest_price);
CTrade trade;

if (newbar() == false) {return;}
                      
double bsl = NormalizeDouble(latest_price.ask - 500*_Point,_Digits);
double btp = NormalizeDouble(latest_price.ask + 500*_Point,_Digits);     

double ssl = NormalizeDouble(latest_price.ask + 500*_Point,_Digits);
double stp = NormalizeDouble(latest_price.ask - 500*_Point,_Digits); 

                               
 if(EMA_Cross(emafast,emaslow,emashift,tf) == "CrossedDown") 
 {
 trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.1,latest_price.ask,bsl,btp,"");
 }
 
 if(EMA_Cross(emafast,emaslow,emashift,tf) == "CrossedUp") 
 {
 trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,0.1,latest_price.ask,ssl,stp,"");
 }  

  
  }
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| EMA Cross                                                        |
//+------------------------------------------------------------------+

string EMA_Cross(int fast,int slow, int shift,ENUM_TIMEFRAMES tf)
{
double Fast_EMA[];
double Slow_EMA[];
int FastEMAHandle = iMA(Symbol(),tf,fast,shift,MODE_EMA,PRICE_CLOSE);
int SlowEMAHandle = iMA(Symbol(),tf,slow,shift,MODE_EMA,PRICE_CLOSE);
      
if(CopyBuffer(FastEMAHandle,0,0,4,Fast_EMA)<=0) {return(0);}
if(CopyBuffer(SlowEMAHandle,0,0,4,Slow_EMA)<=0) {return(0);}

if (Fast_EMA[1] < Slow_EMA[1] && Fast_EMA[2] > Slow_EMA[2]) {return("CrossedDown");}
if (Fast_EMA[1] > Slow_EMA[1] && Fast_EMA[2] < Slow_EMA[2]) {return("CrossedUp");}

return(0);
}
      

 

 

Just so that if you are wondering if I am crazy, I switched the buy and sell if statement because for some reason the right way around according to what happens is not right.

But that is not the issue here, the issue is the orders are not places where there is a cross 

 

Hi,

I looked through the code and It is doing exactly what you have coded. Let's take a look at your code:

if (Fast_EMA[1] < Slow_EMA[1] && Fast_EMA[2] > Slow_EMA[2]) {return("CrossedDown");}
if (Fast_EMA[1] > Slow_EMA[1] && Fast_EMA[2] < Slow_EMA[2]) {return("CrossedUp");}

Remember that at this point, you are on Bar 0, it means you are checking if there has been a cross before the current bar (Bar 0). Which means the crossing must have happened on Bars 2 and 1 as stated in your code

In the picture below, the crossing took place within point A/B but at Bar 2, one was still higher than the other. The crosses actually took place between Bar 2 and 1 in both cases displayed in the image you attached. 

Maybe you should try and move your mouse over the MA indicator at the points I marked A and B respectively, you will discover that the values of both MAs are not the same. 

 

Hope this helps 

 

 

Ok, I modified the code:

 

#include <EA.mqh>
#include <Trade\Trade.mqh>

input ENUM_TIMEFRAMES tf  = PERIOD_H1;
input int      emaslow = 50;
input int      emafast = 18;
input int      emashift = 0;


 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
MqlTick latest_price;      // To be used for getting recent/latest price quotes
  
SymbolInfoTick(_Symbol,latest_price);
CTrade trade;

if (newbar() == false) {return;}

                          
double bsl = NormalizeDouble(latest_price.ask - 500*_Point,_Digits);
double btp = NormalizeDouble(latest_price.ask + 500*_Point,_Digits);     

double ssl = NormalizeDouble(latest_price.ask + 500*_Point,_Digits);
double stp = NormalizeDouble(latest_price.ask - 500*_Point,_Digits); 

                               
 if(EMA_Cross(emafast,emaslow,emashift,tf) == "CrossedDown") 
 {
 trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,0.1,latest_price.ask,ssl,stp,"");
 }
 
 if(EMA_Cross(emafast,emaslow,emashift,tf) == "CrossedUp") 
 {
 trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.1,latest_price.ask,bsl,btp,"");
 }  

  
  }
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| EMA Cross                                                        |
//+------------------------------------------------------------------+

string EMA_Cross(int fast,int slow, int shift,ENUM_TIMEFRAMES tf)
{
double Fast_EMA[];
double Slow_EMA[];
int FastEMAHandle = iMA(_Symbol,tf,fast,shift,MODE_EMA,PRICE_CLOSE);
int SlowEMAHandle = iMA(_Symbol,tf,slow,shift,MODE_EMA,PRICE_CLOSE);


      
      
if(CopyBuffer(FastEMAHandle,0,0,4,Fast_EMA)<=0) {return(0);}
if(CopyBuffer(SlowEMAHandle,0,0,4,Slow_EMA)<=0) {return(0);}

if (Fast_EMA[0] < Slow_EMA[0] && Fast_EMA[1] > Slow_EMA[1]) {return("CrossedUp");}
if (Fast_EMA[0] > Slow_EMA[0] && Fast_EMA[1] < Slow_EMA[1]) {return("CrossedDown");}



return(0);
}
      
      



 


As you can see, one of the cross were picked up but a bit late, and the last one was not picked up.  I guess that the crosses takes way too long, and by the time the bars are analysed they don't pick up the cross.

Another thing, on some of the cross the opposite order is placed, I'm not sure why it does that. 

Do you maybe have better code for me that will detect any cross more accurately?  Would really appreciate it.

And thank you for your help! 

 
Saidar:

Ok, I modified the code:

 

 

As you can see, one of the cross were picked up but a bit late, and the last one was not picked up.  I guess that the crosses takes way too long, and by the time the bars are analysed they don't pick up the cross.

Another thing, on some of the cross the opposite order is placed, I'm not sure why it does that. 

Do you maybe have better code for me that will detect any cross more accurately?  Would really appreciate it.

And thank you for your help! 

1. You need to use latest_price.bid when selling, so I doubt that it would ever enter a sell order with your current code.

2. Your formulas are back to front and should include an equality for completeness, see corrected below

3. I find the documentation about this rather confusing, but think you need to set the EMAs to a data series using ArraySetAsSeries

 

if(CopyBuffer(FastEMAHandle,0,0,4,Fast_EMA)<=0) {return(0);}
if(CopyBuffer(SlowEMAHandle,0,0,4,Slow_EMA)<=0) {return(0);}


ArraySetAsSeries(Fast_EMA,true);
ArraySetAsSeries(Slow_EMA,true);

if (Fast_EMA[0] > Slow_EMA[0] && Fast_EMA[1] <= Slow_EMA[1]) {return("CrossedUp");}
if (Fast_EMA[0] < Slow_EMA[0] && Fast_EMA[1] >= Slow_EMA[1]) {return("CrossedDown");}
 
Everyone thanks for your help, I will correct the code and see if it is working.  Yes MQL5 has some new stuff that I dont really understand
 

Ok,  I tested the new code, but I'm not yet where I want it to be.

Some crosses are not picked up, others are way too late.

Is there anyway to make this whole process more accurate?  I cannot see how writing an EA or a good alert indicator is possible if the line cross of any two lines are not perfected.

#include <EA.mqh>
#include <Trade\Trade.mqh>

input ENUM_TIMEFRAMES tf  = PERIOD_H1;
input int      emaslow = 18;
input int      emafast = 4;
input int      emashift = 0;


 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
MqlTick latest_price;      // To be used for getting recent/latest price quotes
  
SymbolInfoTick(_Symbol,latest_price);
CTrade trade;

if (newbar() == false) {return;}

                          
double bsl = NormalizeDouble(latest_price.ask - 500*_Point,_Digits);
double btp = NormalizeDouble(latest_price.ask + 500*_Point,_Digits);     

double ssl = NormalizeDouble(latest_price.bid + 500*_Point,_Digits);
double stp = NormalizeDouble(latest_price.bid - 500*_Point,_Digits); 

  
if(EMA_Cross(emafast,emaslow,emashift,tf) == "CrossedUp") 
{
trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.1,latest_price.ask,bsl,btp,"");
}    
                               
if(EMA_Cross(emafast,emaslow,emashift,tf) == "CrossedDown") 
{
trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,0.1,latest_price.bid,ssl,stp,"");
}
 

  
  }
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| EMA Cross                                                        |
//+------------------------------------------------------------------+

string EMA_Cross(int fast,int slow, int shift,ENUM_TIMEFRAMES tf)
{
double Fast_EMA[];
double Slow_EMA[];
int FastEMAHandle = iMA(_Symbol,tf,fast,shift,MODE_EMA,PRICE_CLOSE);
int SlowEMAHandle = iMA(_Symbol,tf,slow,shift,MODE_EMA,PRICE_CLOSE);
 
if(CopyBuffer(FastEMAHandle,0,0,4,Fast_EMA)<=0) {return(0);}
if(CopyBuffer(SlowEMAHandle,0,0,4,Slow_EMA)<=0) {return(0);}

ArraySetAsSeries(Fast_EMA,true);
ArraySetAsSeries(Slow_EMA,true);

if (Fast_EMA[0] > Slow_EMA[0] && Fast_EMA[1] <= Slow_EMA[1]) {return("CrossedUp");}
if (Fast_EMA[0] < Slow_EMA[0] && Fast_EMA[1] >= Slow_EMA[1]) {return("CrossedDown");}


return(0);
}
      
      



 Maybe if it will help, here is the function for the newbar() that I am using:

 

bool newbar ()
{
 static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar=false;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return(0);
     }

//--- EA should only check for new trade if we have a new bar
return(IsNewBar);


}

 

And here is the results:

 

 
Saidar:

Ok,  I tested the new code, but I'm not yet where I want it to be.

Some crosses are not picked up, others are way too late.

Is there anyway to make this whole process more accurate?  I cannot see how writing an EA or a good alert indicator is possible if the line cross of any two lines are not perfected.

 Maybe if it will help, here is the function for the newbar() that I am using:

 

 

And here is the results:

 

Sorry, should have picked up on this last time: it's probable that your code works OK with shift = 1 & 2 (as you originally had it), but not with shift = 0 & 1, because a shift = 0 cross event will not necessarily occur at exactly the same time as a newbar().  In your last screenshot, the short entries look fine, with the TP 500 below and SL 500 above kicking in as expected.

Also, if a sl/tp has not been hit, your code as written will simply exit an open position with the opposite order.

Paul

 
phampton:

Sorry, should have picked up on this last time: it's probable that your code works OK with shift = 1 & 2 (as you originally had it), but not with shift = 0 & 1, because a shift = 0 cross event will not necessarily occur at exactly the same time as a newbar().  In your last screenshot, the short entries look fine, with the TP 500 below and SL 500 above kicking in as expected.

Also, if a sl/tp has not been hit, your code as written will simply exit an open position with the opposite order.

Paul

phampton,

Is there a way to shift the EMA negative, like you can do manually when adding an EMA to your chart?  When I put in a value of -2 in the shift part of the iMA it wont work.  Only positive numbers work.

Yes you are right with the last part, that is something that I don't understand.  In MQL4 you just opened orders, they did not close each other.

What should I do to modify the code so that what you said won't happen:

 "Also, if a sl/tp has not been hit, your code as written will simply exit an open position with the opposite order."

Also how do I close an order that I want to close ?  I don't understand this at all 

I actually opened a new thread here for this problem:

https://www.mql5.com/en/forum/1185/page1

Order problems
  • www.mql5.com
It acts like the stop loss or take profit for the previousorder.
Reason: