GridMACD-TS

Author: pengie
Orders Execution
It automatically opens orders when conditions are reachedIt Closes Orders by itself Checks for the total of open ordersIt can change open orders parameters, due to possible stepping strategy
Indicators Used
MACD Histogram
0 Views
0 Downloads
0 Favorites

Profitability Reports

AUD/USD Oct 2024 - Jan 2025
83.00 %
Total Trades 840
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff -1.15
Gross Profit 4861.60
Gross Loss -5827.10
Total Net Profit -965.50
-100%
-50%
0%
50%
100%
NZD/USD Oct 2024 - Jan 2025
79.00 %
Total Trades 769
Won Trades 516
Lost trades 253
Win Rate 0.67 %
Expected payoff -1.45
Gross Profit 4200.60
Gross Loss -5317.30
Total Net Profit -1116.70
-100%
-50%
0%
50%
100%
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++;
   }
   
}  

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---