Now, when I run this in Strategy tester visual mode (H4 TF) none of the trades that should be taken are taken. Instead, something like the attached image happens.
In that small cluster, nearly 2-300 trades were executed AND closed, and they weren't even according to my signal!
So my questions are:
1) Where am I going wrong with my signal code?
2) Why are so many trades being placed and closed at once?
Your help is always very appreciated.
Thanks!
(1) You're almost there already, albeit I don't see any Bands set-up.
(2) The prb is:
double TwentyEMA = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,1); double MACDmain = iMACD(NULL,0,MACDfast,MACDslow,MACDsignal,PRICE_CLOSE,MODE_MAIN,1); double MACDsignal = iMACD(NULL,0,MACDfast,MACDslow,MACDsignal,PRICE_CLOSE,MODE_SIGNAL,1);
TwentyEMA, MACDmain, MACDsignal --- they all remain SAME values, during test. This is because they are not iterating on every bar, but remains "lock" at Bar=1, as you hard-coded '1' in the iMA(.....1), iMACD(...1), respectively.
These variables may work for forward demo/live because with each new bar, bar=1 is different. Unfortunately, for Strategy Tester, this is not the case.
Hope this helps.
(1) You're almost there already, albeit I don't see any Bands set-up.
(2) The prb is:
TwentyEMA, MACDmain, MACDsignal --- they all remain SAME values, during test. This is because they are not iterating on every bar, but remains "lock" at Bar=1, as you hard-coded '1' in the iMA(.....1), iMACD(...1), respectively.
These variables may work for forward demo/live because with each new bar, bar=1 is different. Unfortunately, for Strategy Tester, this is not the case.
Hope this helps.
Thanks - Yeah, the bands concept was more from visual observation, but I couldn't find what to use for the middle band(as opposed to MODE_UPPER and MODE_LOWER), so I used a 20EMA instead.
I didn't exactly get what you meant by "SAME values, during test. This is because they are not iterating on every bar, but remains "lock" at Bar=1, as you hard-coded '1' in the iMA(.....1), iMACD(...1), respectively."
Does this mean that it gets stuck on the value assigned at the first bar in the test?
I tried changing it to zero(since the for loop assigns the value in each iteration) and results instantly got better, now I'm getting 50% accuracy, but it still opens and closes trades way too fast, and takes way too many trades.
I'm attaching a picture of an ideal signal - perhaps that can clear it up a little - please check the picture against my code - thanks in advance
The candle where the line is should be the entry. MACD(shift 1) would have crossed, plus, if you shift 3-4 candles back, the entire candle is below the EMA. The EA completely misses these trades.
for(int a = OrdersTotal(); a >= 0; a--) { OrderSelect(a,SELECT_BY_POS,MODE_TRADES); if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == OP_BUY)
1) If OrderSelect fails then everything thereafter are bogus.
2) OrderSelect fails because the positions are 0 through OrdersTotal() -1 and the first select uses OrderSelect( OrdersTotal )
3) The thought is to select all buy orders so ONE statement - put a brace after the end of the if, the FOR doesn't need one.
for(int pos = OrdersTotal() - 1 ; pos >= 0; pos--) if( OrderSelect(pos, SELECT_BY_POS,MODE_TRADES) && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber ){ if (OrderType() == OP_BUY){ ... } else if (OrderType() == OP_SELL){ ... }
if(Close[1] < TwentyEMA - Window * Point) Closed = OrderClose(OrderTicket(),OrderLots(),Bid,MarketInfo(Symbol(),MODE_SPREAD),CLR_NONE);//If the close is below the if(Closed) IsTrade = False;
What is Closed when closed[1] > TewentyEMA?if(Close[1] < TwentyEMA - Window * Point){ Closed = OrderClose(OrderTicket(),OrderLots(),Bid,MarketInfo(Symbol(),MODE_SPREAD),CLR_NONE);//If the close is below the if(Closed) IsTrade = False; }
- What is Window * point - on a 5 digit broker it is ONE pip
//++++ These are adjusted for 5 digit brokers. int pips2points; // slippage 3 pips 3=points 30=points double pips2dbl; // Stoploss 15 pips 0.0015 0.00150 int Digits.pips; // DoubleToStr(dbl/pips2dbl, Digits.pips) int init(){ if (Digits % 2 == 1){ // DE30=1/JPY=3/EURUSD=5 https://www.mql5.com/en/forum/135345 pips2dbl = Point*10; pips2points = 10; Digits.pips = 1; } else { pips2dbl = Point; pips2points = 1; Digits.pips = 0; } // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
Window * pips2dbl is 10 pips on either. if(OrderStopLoss() > SellStop + Window*Point) OrderModify(OrderTicket(),... if(Close[1] > TwentyEMA + Window * Point) Closed = OrderClose(OrderTicket(),...
Always test return codesif(OrderStopLoss() > SellStop + Window*Point){ if (!OrderModify(OrderTicket(),OrderOpenPrice(),SellStop,0,0,CLR_NONE)) Alert("OrderModify failed: ", GetLastError()); if(Close[1] > TwentyEMA + Window * Point){ if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),MarketInfo(Symbol(),MODE_SPREAD),CLR_NONE)) Alert("OrderClosed failed: ",GetLastError()); else IsTrade = false; } }
Does this mean that it gets stuck on the value assigned at the first bar in the test? NO.
int Ticket; bool IsTrade = false; bool BuyOne, SellOne; double TwentyEMA,MACDmain,MACDsignal; <----- declare at GLOBAL LEVEL, instead of in start() //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- if(Digits == 5) { Window = Window * 10; } //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- Also, good to have some check for new Bar logic here. (test mode). TwentyEMA = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,1);OK. '0' is fine, too. MACDmain = iMACD(NULL,0,MACDfast,MACDslow,MACDsignal,PRICE_CLOSE,MODE_MAIN,1);OK.'0' is fine, too. MACDsignal = iMACD(NULL,0,MACDfast,MACDslow,MACDsignal,PRICE_CLOSE,MODE_SIGNAL,1);OK.'0' is fine, too. then, if(MACDmain > MACDsignal) //MACD cross to the upside Get all your signals processed early, before executions - buy, sell, close. { for(int i = 1; i <=4; i++) { double EMA = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,i); //The for loop tests whether a crossover double EMA2 = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,i+1); //happened or not. A candle opening below if(Close[i] > EMA && Open[i] < EMA && Close[i+1] < EMA2) //the MA and closing above it signals a cross { //with the additional confirmation of the close of BuyOne = true; //previous candle being below the MA break; } continue; } } //SELL if(MACDmain < MACDsignal) //MACD cross to the downside { for(int j = 1; j <=4; j++) { EMA = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,j); //Same principle as the BUY signal except in reverse EMA2 = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,j+1); if(Close[j] < EMA && Open[j] > EMA && Close[j+1] > EMA2) { SellOne = true; break; } continue; } } //End Check conditions You may also use/add the above signals to help the closing of orders if(OrdersTotal()>0){....closing...
Thanks for the pointers, guys! Am working on it - will keep you updated.
Cheers
So I made the changes, but still doesn't work properly. It takes one valid trade, then immediately after that trade closes it opens hundreds of positions:
Any ideas? I declared the indicator vars globally, I changed the OrderSelecT() to what WHRoeder suggested. Am attaching a picture of visual mode on the next post
//+------------------------------------------------------------------+ //| MACD Bands.mq4 | //| Gulzaar | //| http://gulzaarfx.blogspot.com | //+------------------------------------------------------------------+ #property copyright "Gulzaar" #property link "http://gulzaarfx.blogspot.com" //External Variables//------------------------- extern double Lots = 0.1; extern int MagicNumber = 78652; extern int fast = 21, slow = 55, signal = 8, Window = 10; //Global Variables//--------------------------- int Ticket; bool IsTrade = false; bool BuyOne, SellOne; bool Closed; double TwentyEMA, MACDmain, MACDsignal; int BarTrade; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- if(Digits == 5) { Window = Window * 10; } //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- TwentyEMA = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,1); MACDmain = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,1); MACDsignal = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,1); //Check Open positions for(int pos = OrdersTotal() - 1; pos >= 0; pos--){ OrderSelect(OrderTicket(),SELECT_BY_POS,MODE_TRADES); if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) { IsTrade = true; double BuyStop = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,0); //Change the StopLoss to reflect the Lower Bollinger band for that candle if(OrderStopLoss() < BuyStop + Window * Point) OrderModify(OrderTicket(),OrderOpenPrice(),BuyStop,0,0,CLR_NONE); if(Close[1] < TwentyEMA - Window * Point) Closed = OrderClose(OrderTicket(),OrderLots(),Bid,MarketInfo(Symbol(),MODE_SPREAD),CLR_NONE);//If the close is below the if(Closed) IsTrade = False; //middle band(20EMA) close the //order } else if (OrderType() == OP_SELL){ IsTrade = true; double SellStop = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0);//Same principle as above if(OrderStopLoss() > SellStop + Window*Point) OrderModify(OrderTicket(),OrderOpenPrice(),SellStop,0,0,CLR_NONE); if(Close[1] > TwentyEMA + Window * Point) Closed = OrderClose(OrderTicket(),OrderLots(),Ask,MarketInfo(Symbol(),MODE_SPREAD),CLR_NONE); if(Closed) IsTrade = false; } } //Check conditions //BUY if(MACDmain > MACDsignal) //MACD cross to the upside { for(int i = 1; i <=4; i++) { double EMA = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,i); //The for loop tests whether a crossover double EMA2 = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,i+1); //happened or not. A candle opening below if(Close[i] > EMA && Open[i] < EMA && Close[i+1] < EMA2) //the MA and closing above it signals a cross { //with the additional confirmation of the close of BuyOne = true; //previous candle being below the MA break; } continue; } } //SELL if(MACDmain < MACDsignal) //MACD cross to the downside { for(int j = 1; j <=4; j++) { EMA = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,j); //Same principle as the BUY signal except in reverse EMA2 = iMA(NULL,0,20,0,MODE_EMA,PRICE_CLOSE,j+1); if(Close[j] < EMA && Open[j] > EMA && Close[j+1] > EMA2) { SellOne = true; break; } continue; } } //End Check conditions if(BuyOne == true && IsTrade == false && BarTrade != Bars) { Ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,MarketInfo(Symbol(),MODE_SPREAD),0,0,NULL,MagicNumber,0,Green); int BarTrade = Bars; //The trade only executes on a new bar if (Ticket==-1) ShowERROR(Ticket,0,0); } if(SellOne == true && IsTrade == false && BarTrade != Bars) { Ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,MarketInfo(Symbol(),MODE_SPREAD),0,0,NULL,MagicNumber,0,Red); BarTrade = Bars; if (Ticket==-1) ShowERROR(Ticket,0,0); } //---- return(0); } } //+------------------------------------------------------------------+ void ShowERROR(int Ticket,double SL,double TP) { int err=GetLastError(); switch ( err ) { case 1: return; case 2: Alert("No connection with the trading server ", Ticket," ",Symbol());return; case 130: Alert("Error close foot Ticket ", Ticket," ",Symbol());return; case 134: Alert("Not enough money ", Ticket," ",Symbol());return; case 146: Alert("Error Subsystem busy trade ", Ticket," ",Symbol());return; case 129: Alert("Error Invalid price ", Ticket," ",Symbol());return; case 131: Alert("Error Invalid volume ", Ticket," ",Symbol());return; default: Alert("Error : ",err, " ", Ticket," ",Symbol());return; } }

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi,
I am working on an EA that is based on MACD and bollinger bands. The idea is that when MACD crosses and price crossing the middle bollinger band coincide, price rides the band all the way up or down.
I have attempted to code this, and have explained in the comments what I intend each snippet of code to be.