Download MetaTrader 5
To add comments, please log in or register
They are already making profit from their signals. Publish your signal and join them!
Franco
374
Franco 2010.06.11 16:25 

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

 

Franco
374
Franco 2010.06.11 16:32  

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 

Samuel Olowoyo
2236
Samuel Olowoyo 2010.06.11 18:49  

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 

 

Franco
374
Franco 2010.06.12 11:01  

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! 

Paul
784
Paul 2010.06.12 12:54  
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");}

 

Franco
374
Franco 2010.06.12 20:11  
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
Franco
374
Franco 2010.06.12 20:36  

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:

 

Paul
784
Paul 2010.06.13 05:10  
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

Franco
374
Franco 2010.06.13 12:24  
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.
/
To add comments, please log in or register