help for write my first EA in mql4

 
hello

I try to make my first EA in MQL4 but i got many error and warning that i couldn't pass those.

this is my first simple code Thanks for anyone who can help me

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                                                       trader92 |
//|                                       https://www.test.com |
//+------------------------------------------------------------------+
#property copyright "trader92"
#property link      "https://www.test.com"
#property version   "1.00"
#property strict
//--- input parameters
string Symbol();
int cmd=0;
double MODE_BID=Bid ;
int slippage=1;
double stoploss=0;
double TakeProfit=(Ask+2*Point);
const string comment=NULL;
int magic=0;
datetime expiration = 0;
color arrow_color=clrNONE;
  
int  TimeMinute(datetime);
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  
  }
//+------------------------------------------------------------------+
int start()
  {
  if(TimeMinute(time_sever)==("12:20"))
  OrderSend(Symbol(),0,0.01 ,Bid ,1,0,Ask+2*Point,NULL,0,0,clrNONE);
  return (0);
  }

 

Hey bro, welcome to mql4. I'll do my best to steer you in the right direction with what little I know.

if(TimeMinute(time_sever)==("12:20"))


- time_server is something you have created, therefor MT4 won't be able to understand what it is until you declare it, which must be done with everything that you input (generally what's uncoloured)

To declare it you need to know what type of variable it is, as an example if the value is 0 (no decimal place) it's an integer. For other type's of variables see https://docs.mql4.com/basis/variables

time_server probably wants to be a 'datetime' variable.  

Usually you want to declare before the init() function. Again look at the documentation.

So, 

if(time_server == "12:20")

 won't work either as time_server returns a value of the variable type datetime, therefor when it see's "12:20" it doesn't understand whether it is equal to (==) simply because one is a datetime variable whilst the other is a script ("words") variable

 I'm not too sure what "12:20" should be, so sorry I cant help more in this regard its not something I've much knowledge on. 

 

OrderSend tripped me up a few times, and it's not something you can work out with common sense so you just have to know the rules,  

OrderSend returns an integer value that you have to cradle,

 what you want is something like this ;

if ( OrderSend( Symbol(), OP_BUY, LotSize, Ask, 13,(Ask - (500*Point())),(Ask+(9999*Point())), "XFSEA", Order_Magic1, 0, Green ) < 0)


feel free to just grab and customise this as I did before you.

So, if OrderSend() returns an integer of a value < 0 it has failed to send the order, therefor you want to know why, and in my code I do this with this function;  

               {
               _GetLastError = GetLastError();
               Alert( "Error OrderSend B1# ", _GetLastError );
               break;
               }

 This basically just tells you what went wrong when trying to send the order, then you can work out what's going wrong by plugging that GetLastError value into google.

 So, for your exert customised with mine it would be something like this

if (OrderSend(Symbol(), OP_SELL, 0.01, Ask, 1, StopLoss, Ask+ (2*Point()),NULL,0,0,clrNONE)<0)

               {
               _GetLastError = GetLastError();
               Alert( "Error OrderSend B1# ", _GetLastError );
               break;
               } 

else return(0);

Remember ; if your opening a Buy you need to use the Ask price, If your opening a SELL position it needs to use the Bid price, I have one OrderSend function for buys and another for sells (although this is probably a bit messy it's easier for me to comprehend).

instead of Point it's Point() 

Instead of Ask+2*Point its best to divide the Ask bit and the 2*Point() bit so instead  use  Ask + (2*Point())

 

 

 ...

 

As a side note the only way I managed to learn was through sheer perseverance and the assistance of the wonderful members of this community, if you get a response from whroeder or honest knave, take it like you would the word of god.

Also I found reading through other peoples EA's was very helpful, I spent some time customising parts of other peoples code and began to build knowledge slowly through modification rather than straight up genesis, I think of my code's like Frankenstein's monster, made with lots of bits of different people all stuck together to make one thing.  

http://www.forexfactory.com/showthread.php?t=161982 this was the first EA I looked through as I understood the stochastic indicator and so it was easier for me to comprehend what was going on, although in all honesty I stared blankly at it for a good week before I started to get any modicum of comprehension..  I'd advise you do something similar with an EA that's free that uses a indicator or a rule set which is simple to understand and which you already have a decent grasp of.

 

 Good luck and fare ye well.

Variables - Language Basics - MQL4 Reference
Variables - Language Basics - MQL4 Reference
  • docs.mql4.com
Variables - Language Basics - MQL4 Reference
 
xanderhinds ,thanks so much for your help
 
thanks for help

one other dear in other forum help me too and this is correct for time:

if(Hour() == StartHour && Minute() == StartMinute && Seconds()==StartSeconds)
that we can define StartHour , StartMinute , StartSeconds :

input int StartHour = 10 ;
input int StartMinute = 14;
input int StartSeconds = 00 ;
and problem with OrderSend function solved with insert int ticket at the first of that :

int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,Ask+(TP*Point),comment,magic,0,0);
and when we write OrderSend then insert "(" we can see help task over that

I hope I can improve my skill to be able to help others, as soon as possible :)
 

Just a few comments that may help you.

---------------------- 

You shouldn't have both void OnTick() and int start() in your EA.

OnTick() = new way

start() = old way 

Just use OnTick()

e.g. 

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  if(TimeMinute(time_sever)==("12:20"))
  OrderSend(Symbol(),0,0.01 ,Bid ,1,0,Ask+2*Point,NULL,0,0,clrNONE);
  return (0);
  }

----------------------

if(Hour() == StartHour && Minute() == StartMinute && Seconds()==StartSeconds)
that we can define StartHour , StartMinute , StartSeconds :

input int StartHour = 10 ;
input int StartMinute = 14;
input int StartSeconds = 00 ;

If you want to run some code based purely on time, do not place it in OnTick(). Use OnTimer() instead.

The reason is that OnTick() is called every time a tick arrives.

If no tick arrives at 10:14:00, the code does not run.

Also, if multiple ticks arrive at 10:14:00 your code will try to open multiple orders.

----------------------

int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,Ask+(TP*Point),comment,magic,0,0);

You should get into the habit of checking the return code of your functions. Here is a good explanation why. 

If "ticket" is < 0, then OrderSend() failed. You could use GetLastError() to see why i.e. invalid lot size, invalid stops etc.

---------------------- 

HTH

 
honest_knave:

Just a few comments that may help you.


thanks so much

I have used your help
But the code is not working correctly

//+------------------------------------------------------------------+
//|                                                         test14.mq4 |
//|                                                         test14 |
//|                                             https://www.test14.com |
//+------------------------------------------------------------------+
#property copyright "test14"
#property link      "https://www.test14.com"
#property version   "1.14"
#property strict

//--- input parameters
input double Lots = 0.1;
input int  TP = 200;
input int  SL = 200;
input int slippage = 3;
input string comment = "MyOrder";
input int magic = 1234;
input int StartHour = 10 ;
input int StartMinute = 14;
input int StartSeconds = 00 ;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
    GetLastError();          
              
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+


void OnTimer (){

if(Hour() == StartHour && Minute() == StartMinute && Seconds()==StartSeconds)
{
OnTick();
}
}


void OnTick()
  {
//---

  
    int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,Ask+(TP*Point),comment,magic,0,0);
  
  if( ticket > 0 )
   {
   Alert("Order placed # ", ticket);
   }
else
   {
   Alert("Order Send failed, error # ", GetLastError() );
   }
  
  }
//---
 
//+------------------------------------------------------------------+
//|                                                       test14.mq4 |
//|                                                           test14 |
//|                                           https://www.test14.com |
//+------------------------------------------------------------------+
#property copyright "test14"
#property link      "https://www.test14.com"
#property version   "1.14"
#property strict

//--- input parameters
input double Lots = 0.1;
input int  TP = 200;
input int  SL = 200;
input int slippage = 3;
input string comment = "MyOrder";
input int magic = 1234;
input int StartHour = 10 ;
input int StartMinute = 14;
input int StartSeconds = 00 ;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   EventSetTimer(1);              
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  
  }

//+------------------------------------------------------------------+
//| OnTimer()                                                        |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(Hour() == StartHour && Minute() == StartMinute && Seconds()==StartSeconds)
     {
      int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,Ask+(TP*Point),comment,magic,0,0);
      if( ticket > 0 )
        {
         Alert("Order placed # ", ticket);
        }
      else
        {
         Alert("Order Send failed, error # ", GetLastError() );
        }
     }
  }


//---

Uncompiled / untested.

It is a little rough around the edges.

In theory, it should open 1 order a day (and 1 order only) because the timer only gets called once per second. In theory.

There are some refinements you could make to ensure it behaves correctly, which you can explore as you get more used to MQL4.

Please note that OnTimer() does not work in backtesting. You'll need to test your code by forward testing in demo mode.

Otherwise, you will need to change your approach so it works in OnTick(). Here is an example:

#property strict

#define  DAY 86400 // day is 86400 seconds
#define  HOUR 3600 // hour is 3600 seconds
#define  MINUTE 60 // minute is 60 seconds

input double Lots    = 0.1;
input int    TP      = 200;
input string comment = "MyOrder";
input int    magic   = 1234;

input int StartHour   = 10;
input int StartMinute = 14;
datetime  NextTrade   = StartHour*HOUR + StartMinute*MINUTE;

//+--------------------------------------------------------------------------------------+
//| OnInit()                                                                             |
//+--------------------------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }

//+--------------------------------------------------------------------------------------+
//| OnDeinit()                                                                           |
//+--------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }

//+--------------------------------------------------------------------------------------+
//| OnTick()                                                                             |
//+--------------------------------------------------------------------------------------+
void OnTick()
  {
   datetime now = TimeCurrent();
   if(now >= NextTrade)
     {
      if(OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,Ask+(TP*Point),comment,magic,0,0) < 0)
        {
         printf("OrderSend() failed. Error code: %i", GetLastError());
        }
      else
        {
         datetime midnight = now - (now % DAY);
         NextTrade = midnight + DAY + StartHour*HOUR + StartMinute*MINUTE;
         printf("Next Trade scheduled for %s", TimeToString(NextTrade));
        }
     }
  }
There are still some issues with this code, notably with trading close to midnight and/or history gaps. But, best to walk before we run 
 
Thank so much for your code

It seems to be working properly

 
honest_knave:
void OnTimer(){
   if(Hour() == StartHour && Minute() == StartMinute && Seconds()==StartSeconds)

Uncompiled / untested.

  1. Can't use those functions (or TimeCurrent) in OnTick, as there may be no ticks for minutes - "Free-of-Holes" Charts - MQL4 Articles. Must estimate server time. See 'Zero Lag Timer' indicator by 'madhatt30' for MetaTrader 4 and my comment/attachment at Indicators: Zero Lag Timer - Articles, Library comments - MQL5 programming forum
  2.    datetime now = TimeCurrent();
       datetime midnight = now - (now % DAY);
       NextTrade = midnight + DAY + StartHour*HOUR + StartMinute*MINUTE;
       if(now >= NextTrade){
          if(OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,Ask+(TP*Point),comment,magic,0,0) < 0)
            :
    This works on the first tick past the stated time.
 
Thanks so much for your answer
 
whroeder1:
  1. Can't use those functions (or TimeCurrent) in OnTick, as there may be no ticks for minutes - "Free-of-Holes" Charts - MQL4 Articles. Must estimate server time. See 'Zero Lag Timer' indicator by 'madhatt30' for MetaTrader 4 and my comment/attachment at Indicators: Zero Lag Timer - Articles, Library comments - MQL5 programming forum
  2.    datetime now = TimeCurrent();
       datetime midnight = now - (now % DAY);
       NextTrade = midnight + DAY + StartHour*HOUR + StartMinute*MINUTE;
       if(now >= NextTrade){
          if(OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,Ask+(TP*Point),comment,magic,0,0) < 0)
            :
    This works on the first tick past the stated time.

I agree with the sentiment - there are most definitely shortcomings in using TimeCurrent() and Hour() / Minute() / Second(), namely you are reliant upon a tick coming in albeit on any of the enabled symbols in the terminal. However they can be used.

There are more advanced ways to achieve a more accurate result, of which you have posted some very good links. Indeed there are substantial shortcomings in the OnTick method I posted too... midnight being crossed after NextTrade has passed but before the next tick comes, and dealing with history load to set the initial value of NextTrade to name just a couple.

But to quote myself to the OP: "best to walk before we run" and that is very much where I pitched the post 

Reason: