GridMACD-TS1m

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
2900.00 %
Total Trades 14
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff 3.60
Gross Profit 52.20
Gross Loss -1.80
Total Net Profit 50.40
-100%
-50%
0%
50%
100%
NZD/USD Oct 2024 - Jan 2025
0.00 %
Total Trades 0
Won Trades 0
Lost trades 0
Win Rate 0.0 %
Expected payoff 0.00
Gross Profit 0.00
Gross Loss 0.00
Total Net Profit 0.00
-100%
-50%
0%
50%
100%
GridMACD-TS1m
#property copyright "pengie"
#include <stdlib.mqh>
extern string EAName = "GridMACD";
extern int magic = 1012;
extern int initialGridInterval = 20;
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;   
   }

//===these are the original MACD settings for use as default on suggested 1hr timeframe charts:
// 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);
//===end of comment.

   double prevMACD = iMACD(Symbol(), 0, 720, 1560, 9, PRICE_CLOSE, MODE_MAIN, 2);
   double curMACD = iMACD(Symbol(), 0, 720, 1560, 9, PRICE_CLOSE, MODE_MAIN, 1);

//   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 ---