Trader’s Tech – Writing Your Own EA Part 35 – Reusable Code

Forex RobotIf you’re new to this series and want to check it out from the beginning, you can find that here. And look here for a list of all the programming articles.

In Part 34 we discussed the MarketInfo() function as it relates to the PcntTradeSize() function. Today we’ll talk about using the PcntTradeSize() and MAXover() functions in our EA.

For starters, we’re going to substitute the MAXover() function for our IsThereACrossover() function in the start() function. Change the line:

CrossOver = IsThereACrossOver();

to:

CrossOver = MAXover(MODE_SMA,MA1,MA2,0,0);

Obviously, we have gained no benefit by using this function in this case because we had already written the code to handle this job. So we actually created extra work. But, the EA is more malleable now because we can test with other moving average types without significant code modification. Reusing code really only benefits you when you RE use it. ;)

Also, don’t forget to put the #include statement at the beginning of the EA:

#include <MAXover.mqh>

While we’re at it, let’s go ahead and put the #include statement for the PcntTradeSize() function.

#include <PcntTradeSize.mqh>

The changes to use the PcntTradeSize() function are a little more elaborate. We’ll actually be adding new functionality to the EA with this function. To begin with, we’ll want to change our external variable LotSize to a new variable called RiskPcnt. Old line:

extern double    LotSize=0.01;

will be changed to:

extern double    RiskPcnt=2.0;

Then in the OpenTrade() function, replace the line:

TradeSize = LotSize;

with:

TradeSize = PcntTradeSize(Symbol(),SLPips,RiskPcnt);

It’s as simple as that. Reusable code is so cool!

Oh. I forgot to mention, we can completely remove the IsThereACrossover() function code. We don’t need it anymore. One cool thing about the MT4 compiler is that it will recognize unused functions and remove them automatically from the final compilation. So you could group regularly used functions into a single include file (we programmers call that a library) and the compiler will just not compile any function in the library that’s not used.

Just to be sure we’re all on the same page, here is our program in it’s most recent form:

 

//+------------------------------------------------------------------+
//|                                                     SMACross.mq4 |
//|                                  Copyright 2013, T Black & Assoc |
//|                                    http://www.winnersedgetrading.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, T Black & Assoc"
#property link      "http://www.winnersedgetrading.com"
#include 
#include 

//--- input parameters
extern double    RiskPcnt=2.0;
extern int       MA1=3;
extern int       MA2=30;
extern int       SLPips=15;
extern int       TPPips=25;
extern int       MagicNumber=1234567;

static datetime LastTradeTime = 0;
double AdjPoint;   

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   int FiveDig;
   if(Digits == 5 || Digits == 3)
      FiveDig = 10;
   else
      FiveDig = 1;

   AdjPoint = Point * FiveDig;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----

//----
   return(0);
  }

bool NewBar()
   {
   datetime CurrBarTime = iTime(NULL,0,0);
   bool NewBar = false;
   if(CurrBarTime > LastTradeTime)
      {
      NewBar = true;
      }

   return(NewBar);
   }

bool IsThereAnOpenTrade()
   {
   bool OpenTrade = false;
   int i;
   for (i = 0; i < OrdersTotal(); i++)       
      {       
      OrderSelect(i,SELECT_BY_POS);       
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)          
         {          
         OpenTrade = true;          
         break;          
         }       
      }    
   return(OpenTrade);    
   }           
void OpenTrade(int TradeDir)    
   {    
   double TP,SL,TradeSize;    
   int Ticket;    
   bool ModifyResult;    

   TradeSize = PcntTradeSize(Symbol(),SLPips,RiskPcnt);    
   if(TradeDir == 1)  //Long Trade       
      {       
      TP = Bid + (TPPips * AdjPoint);       
      SL = Bid  - (SLPips * AdjPoint);       
      while(IsTradeContextBusy())  //our loop for the busy trade context          
         Sleep(100);  //sleep for 100 ms and test the trade context again       
      RefreshRates();  //refreshing all the variables when the                        
      //trade context is no longer busy       
      Print("Long Trade Price=",Ask,", SL=",SL,", TP=",TP,", Size=",TradeSize);       
      Ticket = OrderSend(Symbol(),OP_BUY,NormalizeDouble(TradeSize,2),                         
               NormalizeDouble(Ask,Digits),2.0,0.0,0.0,"Trade Comment",                         
               MagicNumber,Blue);       
      if(Ticket >= 0)
         {
         while(IsTradeContextBusy())
            Sleep(100);
         RefreshRates();
         OrderSelect(Ticket,SELECT_BY_TICKET);
         ModifyResult = OrderModify(Ticket,OrderOpenPrice(),
                                    NormalizeDouble(SL,Digits),
                                    NormalizeDouble(TP,Digits),0,Blue);
         if(!ModifyResult)
            Alert("Stop Loss and Take Profit not set on order ",Ticket);
         }  //if(Ticket >= 0)
      else
         {
         Alert("Trade Not Entered");
         }  //else
      }  //if(TradeDir == 1)
   if(TradeDir == -1)
      {
      TP = Ask - (TPPips * AdjPoint);
      SL = Ask + (SLPips * AdjPoint);
      while(IsTradeContextBusy())  //our loop for the busy trade context
         Sleep(100);  //sleep for 100 ms and test the trade context again
      RefreshRates();  //refreshing all the variables when the 
                      //trade context is no longer busy
      Print("Short Trade Price=",Bid,", SL=",SL,", TP=",TP,", Size=",TradeSize);
      Ticket = OrderSend(Symbol(),OP_SELL,NormalizeDouble(TradeSize,2),
                        NormalizeDouble(Bid,Digits),2.0,0.0,0.0,"Trade Comment",
                        MagicNumber,Blue);
      if(Ticket >= 0)
         {
         while(IsTradeContextBusy())
            Sleep(100);
         RefreshRates();
         OrderSelect(Ticket,SELECT_BY_TICKET);
         ModifyResult = OrderModify(Ticket,OrderOpenPrice(),
                                    NormalizeDouble(SL,Digits),
                                    NormalizeDouble(TP,Digits),0,Blue);
         if(!ModifyResult)
            Alert("Stop Loss and Take Profit not set on order ",Ticket);
         }  //if(Ticket >= 0)
      else
         {
         Alert("Trade Not Entered");
         }  //else
      }  //if(TradeDir == -1)
   }  //void OpenTrade()     

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
   {
   int CrossOver;
   if(!IsThereAnOpenTrade())
      {
      //Enter code that executes if there is no open trade here.
      CrossOver = MAXover(MODE_SMA,MA1,MA2,0,0);
      if(CrossOver != 0)
         {
         //Enter code that executes if there is a crossover
         if(NewBar())
           {
           //Set LastTradeTime to iTime(NULL,0,0)
           LastTradeTime = iTime(NULL,0,0);
           //Enter code to trigger a trade
           OpenTrade(CrossOver);
           }
         }
      }
   }
//+------------------------------------------------------------------+

As you already know, this WordPress editor is not ideal for posting program code. Thanks to Nathan, we’ve posted this to Amazon for you to download. Just go here to download the file.

That wraps us up for another day. Next time we’ll look at the strategy tester some more. Thanks for your attention and please follow me on Twitter and LinkedIn.

Tim

 

here_for_you_001

1359774937_facebook 1359774984_linkedin 1359774949_twitter 1359774960_google 1359774973_rss 1360027635_youtube

Connect_With_Winners_Edge

Get trade set ups everyday!

 

 

Follow our social media:
1359774937_facebook 1359774984_linkedin 1359774949_twitter 1359774960_google 1359774973_rss 1360027635_youtube

Winner’s Edge Trading, as seen on:

Winner's Edge Trading in the news