GridMACD-TS





#property copyright "pengie"
#include <stdlib.mqh>
extern string EAName = "GridMACD";
extern int magic = 1012;
extern int initialGridInterval = 15;
extern int subsequentGridInterval = 15;
extern int maxOrders = 25;
extern int maxProfit = 250;
extern double lots = 0.1;
extern int slippage = 3;
extern int minOppOrders = 3;  // Close if breakeven or slight profit if there is opposite orders that are more than or equal to minOppOrders.
extern int maxOppOrders = 10;  // Close if there are opposite orders that are more than or equal to maxOppOrders.
extern bool shutdownGrid = false; // If true, will close all orders and not open any new orders.
extern int traling = 30;
double buyEntry = 0.0;
double sellEntry = 0.0;
int curBuy = 0;
int curSell = 0;

int init()
{
	magic = GenerateMagicNumber(magic, Symbol(), Period());
	EAName = GenerateComment(EAName, magic, Period());
	curBuy = CountOrders(Symbol(), magic, OP_BUY);
	curSell = CountOrders(Symbol(), magic, OP_SELL);	
	
	return (0);
}

int deinit()
{
	return (0);
}

int start()
{  
   int ticket;
   if (buyEntry==0.0 || sellEntry==0.0 || buyEntry==10000.0)
   {
      double minBuyEntry = 10000;
      double maxSellEntry = 0;
      for (ticket=GetFirstTicketByMagic(magic); ticket!=0; ticket=GetNextTicket())
      {
        OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
        switch (OrderType())
        {
           case OP_BUY:{
               
               if(OrderStopLoss() <   Bid - (traling*Point))
               moveSL(OrderTicket(),Bid - traling*Point);  
               
              if (OrderOpenPrice()<minBuyEntry) minBuyEntry = OrderOpenPrice();
             break; 
           }
           case OP_SELL:
           {
               if(OrderStopLoss() >  Bid + (traling*Point))
               moveSL(OrderTicket(),Bid + traling*Point);
                 
              if (OrderOpenPrice()>maxSellEntry) maxSellEntry = OrderOpenPrice();
              break;
           }   
        }   
      }
      buyEntry = minBuyEntry - initialGridInterval*Point;
      sellEntry = maxSellEntry + initialGridInterval*Point;   
   }

   double prevMACD = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 2);
   double curMACD = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
	
	int totalOrders = CountOrdersIfMagic(magic);
	if (((prevMACD<0 && curMACD>0) || (prevMACD>0 && curMACD<0)) && totalOrders==0 && !shutdownGrid)
	{
      buyEntry = Ask;
      curBuy = 1;
      OrderSend(Symbol(), OP_BUYSTOP, lots, buyEntry+initialGridInterval*Point, slippage, 0, 0, EAName, magic , 0, Green);
      	    
      sellEntry = Bid;
      curSell = 1;
      OrderSend(Symbol(), OP_SELLSTOP, lots, sellEntry-initialGridInterval*Point, slippage, 0, 0, EAName, magic , 0, Red);   
	}
	
	if (CountOrders(Symbol(), magic, OP_BUY)>0 && CountOrders(Symbol(), magic, OP_BUYSTOP)==0 && totalOrders<maxOrders)
	{
      if (OrderSend(Symbol(), OP_BUYSTOP, lots, buyEntry+initialGridInterval*Point+curBuy*subsequentGridInterval*Point, slippage, 0, 0, EAName, magic , 0, Green)==-1)
      {
         Print(Symbol(), ", Buystop=", buyEntry+initialGridInterval*Point+curBuy*subsequentGridInterval*Point);
      }
      curBuy++;
	}

	if (CountOrders(Symbol(), magic, OP_SELL)>0 && CountOrders(Symbol(), magic, OP_SELLSTOP)==0 && totalOrders<maxOrders)
	{
      if (OrderSend(Symbol(), OP_SELLSTOP, lots, sellEntry-initialGridInterval*Point-curSell*subsequentGridInterval*Point, slippage, 0, 0, EAName, magic , 0, Red)==-1)
      {
         Print(Symbol(), ", Sellstop=", sellEntry-initialGridInterval*Point-curSell*subsequentGridInterval*Point);
      }
      curSell++;
	}
	
	int totalPips = 0;
	double totalProfits = 0.0;
	for (ticket=GetFirstTicketByMagic(magic); ticket!=0; ticket=GetNextTicket())
	{
      OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
      switch (OrderType())
      {
         case OP_BUY:
            totalPips += (Bid-OrderOpenPrice())/Point;
            totalProfits += OrderProfit();
            break;
            
         case OP_SELL:
            totalPips += (OrderOpenPrice()-Ask)/Point;
            totalProfits += OrderProfit();
            break;
      }   
	}
	Comment(StringConcatenate("Total pips=",totalPips,"\nTotal profits=",totalProfits,"\n"));
	
	int buyOrders = CountOrders(Symbol(), magic, OP_BUY);
	int sellOrders = CountOrders(Symbol(), magic, OP_SELL);
	int oppOrders = 0;
	if (buyOrders > sellOrders) oppOrders = sellOrders;
	else oppOrders = buyOrders;
	int stopGrid = 0;
	if ((oppOrders>=minOppOrders && totalPips>=0) || oppOrders>=maxOppOrders) stopGrid = 1;	
	if (shutdownGrid || totalPips>=maxProfit || stopGrid || totalOrders==maxOrders)
	{
		DeleteAllPendingOrders(magic);
		CloseAllOrders(magic);
		curBuy = 0;
		curSell = 0;
		buyEntry = 0.0;
		sellEntry = 0.0;	
	}
	
	return (0);
}

int DeleteAllPendingOrders(int magic)
{
	for (int ticket=GetFirstTicketByMagic(magic); ticket!=0; ticket=GetNextTicket())
	{
      OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
      switch (OrderType())
      {
         case OP_BUYSTOP:
         case OP_SELLSTOP:
            OrderDelete(ticket);
            break;
      }   
	}
	return (0);
}

int CloseAllOrders(int magic)
{
	for (int ticket=GetFirstTicketByMagic(magic); ticket!=0; ticket=GetNextTicket())
	{
      OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
      switch (OrderType())
      {
         case OP_BUY:
            OrderClose(ticket, OrderLots(), Bid, slippage, CLR_NONE);
            break;
            
         case OP_SELL:
            OrderClose(ticket, OrderLots(), Ask, slippage, CLR_NONE);
            break;
      } 
	}
	return (0);
}

int GenerateMagicNumber(int seed, string symbol, int timeFrame)
{
   int isymbol = 0;
   if (symbol == "EURUSD") isymbol = 1;
   else if (symbol == "GBPUSD") isymbol = 2;
   else if (symbol == "USDJPY") isymbol = 3;
   else if (symbol == "USDCHF") isymbol = 4;
   else if (symbol == "AUDUSD") isymbol = 5;
   else if (symbol == "USDCAD") isymbol = 6;
   else if (symbol == "EURGBP") isymbol = 7;
   else if (symbol == "EURJPY") isymbol = 8;
   else if (symbol == "EURCHF") isymbol = 9;
   else if (symbol == "EURAUD") isymbol = 10;
   else if (symbol == "EURCAD") isymbol = 11;
   else if (symbol == "GBPUSD") isymbol = 12;
   else if (symbol == "GBPJPY") isymbol = 13;
   else if (symbol == "GBPCHF") isymbol = 14;
   else if (symbol == "GBPAUD") isymbol = 15;
   else if (symbol == "GBPCAD") isymbol = 16;
   return (StrToInteger(StringConcatenate(seed, isymbol, timeFrame)));
}

string GenerateComment(string EAName, int magic, int timeFrame)
{
   return (StringConcatenate(EAName, "-", magic, "-", timeFrame));
}

int CountOrders(string symbol="", int magicNumber=-1, int cmd=-1)
{
	int totalOrders = 0;
	int maxOrders = OrdersTotal();
	for (int i=0; i<maxOrders; i++)
	{
		OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
		if ((symbol=="" || OrderSymbol()==symbol) &&
			  (magicNumber==-1 || OrderMagicNumber()==magicNumber) &&
			  (cmd==-1 || OrderType()==cmd)) 
		{
			totalOrders++;	
		}
	}
	return (totalOrders);
}

int CountOrdersIfMagic(int magicNumber)
{
	return (CountOrders("", magicNumber, -1));
}

int t_index = 0;
string t_symbol = "";
int t_magicNumber = -1;
int t_cmd = -1;

int GetFirstTicketByMagic(int magicNumber)
{
	return (GetFirstTicket("", magicNumber, -1));
}

int GetFirstTicket(string symbol="", int magicNumber=-1, int cmd=-1)
{
	t_symbol = symbol;
	t_magicNumber = magicNumber;
	t_cmd = cmd;
	
	int maxOrders = OrdersTotal();
	for (t_index=maxOrders-1; t_index>=0; t_index--)
	{
		OrderSelect(t_index, SELECT_BY_POS, MODE_TRADES);
		if ((t_symbol=="" || OrderSymbol()==t_symbol) &&
			  (t_magicNumber==-1 || OrderMagicNumber()==t_magicNumber) &&
			  (t_cmd==-1 || OrderType()==t_cmd))
		{			
			return (OrderTicket());
		}	
	}
	return (0);
}

int GetNextTicket()
{
	for (t_index--; t_index>=0; t_index--)
	{
		OrderSelect(t_index, SELECT_BY_POS, MODE_TRADES);
		if ((t_symbol=="" || OrderSymbol()==t_symbol) &&
			  (t_magicNumber==-1 || OrderMagicNumber()==t_magicNumber) &&
			  (t_cmd==-1 || OrderType()==t_cmd))
		{
			return (OrderTicket());
		}	
	}
	return (0);
}

bool moveSL(int ticket,double stoploss)
{
   
   if(!IsTradeAllowed())
   return (false);
   
   if(MathAbs(Ask-stoploss)/Point < MarketInfo(Symbol(),MODE_STOPLEVEL)) 
   {
      Print("STOP LOSS too close ",Bid," SL ",stoploss);
      return(false);
   }
   
   int error;
   
   int MAXRETRIES = 5;
   int retries = 0;
   while(!OrderModify(ticket,OrderOpenPrice(), stoploss, OrderTakeProfit(), 0,CLR_NONE))
   {
      error = GetLastError();
      
      if(error>1)   
      Print("MoveSL failed with error #",ErrorDescription(error)," CurrentSL ",OrderStopLoss()," NewSL ",stoploss);
       
      Sleep(1000);
            
      RefreshRates();
            
      if(retries >= MAXRETRIES) 
      return(false);
      else
      retries++;
   }
   
}  



Sample





Analysis



Market Information Used:



Indicator Curves created:


Indicators Used:

MACD Histogram


Custom Indicators Used:

Order Management characteristics:

It automatically opens orders when conditions are reached
It Closes Orders by itself
Checks for the total of open orders
It can change open orders parameters, due to possible stepping strategy

Other Features:

BackTest : EURUSD on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDJPY on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2009-12-01 to 2010-01-17 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDCAD on H1

From 2009-12-01 to 2010-01-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2009-08-01 to 2009-10-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-05-01 to 2010-05-31 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-06-01 to 2010-06-30 Profit Factor:0.00 Total Net Profit:0.00

Request Backtest for GridMACD-TS


From : (yyyy/mm/dd) To: (yyyy/mm/dd)

Pair: Period: