Tester issues during simualtion of EA which set buylimit orders

 
Hello Folks,

I've recently created a simple EA which works in the 30min timeframe. Goal of this EA is to set a buylimit order each time a new Candlestick is generated. The limit order is set 30 pips above the open price, a stop loss is set at the open price.

If the limit order is not triggered it expires after 25 minutes. I tested this EA with the MT4 tester but is looks like the limit order is triggered randomly. Refer to the following pic

Fig1

As you can see on the 20/09/2013 at 13.00 and 17.30 the tester triggered the limit order even though the price never reached this level. At 17.00 the limit order was 26 pips above the maximum price reached by the candlestick.

I posted hereafter the EA code. Hope somebody can help me.

extern int MagicNumber = 1061101;
extern bool SignalMail = False;
extern int ActiveNews = 0;
extern double Lots = 1;
extern bool UseStopLoss = False;
extern int StopLoss = 0;
extern int UseTrend1W = 1; 
extern double Delta = 100; 
extern bool EachTickMode = False;
extern int Slippage = 5;
extern bool UseTakeProfit = False;
extern int TakeProfit = 0;
extern bool UseTrailingStop = False;
extern int TrailingStop = 0;
extern bool UseBreakevenAfter = False;
extern int BreakevenAfter = 0;

int BarCount;
int Current;
bool TickCheck = False;
bool Chiuso;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init() {
   BarCount = Bars;

   if (EachTickMode) Current = 0; else Current = 1;

   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit() {
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start() {
   int Order = SIGNAL_NONE;
   int Total, Ticket;
   double StopLossLevel, TakeProfitLevel;

   if (EachTickMode && Bars != BarCount) TickCheck = False;
   Total = OrdersTotal();
   Order = SIGNAL_NONE;

   //+------------------------------------------------------------------+
   //| Variable Begin                                                   |
   //+------------------------------------------------------------------+

// Expiration
datetime expiration = TimeCurrent() + 1500; 
   
//uptrend / downtrend 
int trend;
if (UseTrend1W == 0) trend = 1; 
double SMA1W_26_0 = iMA(NULL, PERIOD_D1, 26, 0, MODE_SMA, PRICE_CLOSE, Current + 0);
double SMA1W_26_1 = iMA(NULL, PERIOD_D1, 26, 0, MODE_SMA, PRICE_CLOSE, Current + 1);
double SMA1W_4_0 = iMA(NULL, PERIOD_D1, 4, 0, MODE_SMA, PRICE_CLOSE, Current + 0);
double SMA1W_4_1 = iMA(NULL, PERIOD_D1, 4, 0, MODE_SMA, PRICE_CLOSE, Current + 1);
double SMA1W_26 = (SMA1W_26_0 - SMA1W_26_1)/SMA1W_26_1;
double SMA1W_4 = (SMA1W_4_0-SMA1W_4_1)/SMA1W_4_1;
if (SMA1W_4 >= SMA1W_26 && UseTrend1W == 1) trend = 1;
if (SMA1W_4 < SMA1W_26 && UseTrend1W == 1 && SMA1W_4_0 < SMA1W_26_0) trend = -1;
if (SMA1W_4 < SMA1W_26 && UseTrend1W == 1 && SMA1W_4_0 > SMA1W_26_0) trend = 1;

double MACD_1W_0 = iMACD(NULL, PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
double MACD_1W_1 = iMACD(NULL, PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
double MACDSIG_1W_0 = iMACD(NULL, PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);

if (MACD_1W_0 >= MACDSIG_1W_0 && UseTrend1W == 2) trend = 1;
if (MACD_1W_0 < MACDSIG_1W_0  && UseTrend1W == 2) trend = -1;

if (MACD_1W_0 >= MACD_1W_1 && UseTrend1W == 3) trend = 1;
if (MACD_1W_0 < MACD_1W_1  && UseTrend1W == 3) trend = -1;
   
double Close0 = iClose(NULL, 0, Current + 0);
double CloseDelta0 = Close0 - Delta/100000;
double CloseDeltaMinus0 = Close0 + Delta/100000;
  
   //+------------------------------------------------------------------+
   //| Variable End                                                     |
   //+------------------------------------------------------------------+

   //Check position
   bool IsTrade = False;

   for (int i = 0; i < Total; i ++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
         IsTrade = True;                                                    
         if(OrderType() == OP_BUY) {                                        
            //Close

            //+------------------------------------------------------------------+
            //| Signal Begin(Exit Buy)                                           |
            //+------------------------------------------------------------------+

            //+------------------------------------------------------------------+
            //| Signal End(Exit Buy)                                             |
            //+------------------------------------------------------------------+

            if (Order == SIGNAL_CLOSEBUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
              Chiuso = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, MediumSeaGreen);
                
                if (Chiuso == true) {
                if (SignalMail) SendMail("[NTS_Buy_Close]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Close Buy");
                            } 
               if (Chiuso == false) {
               if (SignalMail) SendMail("[ERROR NTS_Buy_Close]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Close Buy");
             }
               if (!EachTickMode) BarCount = Bars;
               IsTrade = False;
               continue;
            }
            //Trailing stop
            if(UseTrailingStop && TrailingStop > 0) {                 
               if(Bid - OrderOpenPrice() > Point * TrailingStop) {
                  if(OrderStopLoss() < Bid - Point * TrailingStop) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Bid - Point * TrailingStop, OrderTakeProfit(), 0, MediumSeaGreen);
                     if (!EachTickMode) BarCount = Bars;
                     continue;
                  }
               }
            }
            //Breakeven Buy
         if(UseBreakevenAfter && BreakevenAfter > 0) { 
            if(Bid - OrderOpenPrice() > Point * BreakevenAfter) {
               if(OrderStopLoss() < OrderOpenPrice() ) {
                OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() , OrderTakeProfit(), 0, MediumSeaGreen);
                  if (!EachTickMode) BarCount = Bars;
                     continue;
                  }
               }
            }  
         // end Breakeven Buy
            
         } else {
            //Close

            //+------------------------------------------------------------------+
            //| Signal Begin(Exit Sell)                                          |
            //+------------------------------------------------------------------+

            //+------------------------------------------------------------------+
            //| Signal End(Exit Sell)                                            |
            //+------------------------------------------------------------------+

            if (Order == SIGNAL_CLOSESELL && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
               OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, DarkOrange);
               if (SignalMail) SendMail("[NTS_Buy_Close]", "[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Close Sell");
               if (!EachTickMode) BarCount = Bars;
               IsTrade = False;
               continue;
            }
             //Trailing stop
            if(UseTrailingStop && TrailingStop > 0) {                 
               if((OrderOpenPrice() - Ask) > (Point * TrailingStop)) {
                  if((OrderStopLoss() > (Ask + Point * TrailingStop)) || (OrderStopLoss() == 0)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Ask + Point * TrailingStop, OrderTakeProfit(), 0, DarkOrange);
                     if (!EachTickMode) BarCount = Bars;
                     continue;
                  }
               }
            }
         }
      }
   }

   //+------------------------------------------------------------------+
   //| Signal Begin(Entry)                                              |
   //+------------------------------------------------------------------+

if (ActiveNews > 0 ) Order = SIGNAL_BUY;
   
      //+------------------------------------------------------------------+
   //| Signal End                                                       |
   //+------------------------------------------------------------------+

   //Buy
   if (Order == SIGNAL_BUY &&  ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
      if(!IsTrade) {
         //Check free margin
         if (AccountFreeMargin() < (1000 * Lots)) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }

         if (UseStopLoss) StopLossLevel = CloseDeltaMinus0 - StopLoss * Point; else StopLossLevel = 0.0; 
         if (UseTakeProfit) TakeProfitLevel = CloseDeltaMinus0 + TakeProfit * Point; else TakeProfitLevel = 0.0; 
         
          RefreshRates();
         Ticket = OrderSend(Symbol(), OP_BUYSTOP, Lots, CloseDeltaMinus0, Slippage, StopLossLevel, TakeProfitLevel, "Buy(#" + MagicNumber + ")", MagicNumber, expiration, DodgerBlue);
         if(Ticket > 0) {

            if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) {
                                Print("BUY order opened : ", OrderOpenPrice());
                                
             if (SignalMail) SendMail("[NTS_Buy_Open]", "Position " + Lots + " [" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Open Sell. SL = " + StopLossLevel);
                }
                        }  
for (int j = 0; j < 10; j ++) {
                if(Ticket < 0) { 
                                  if (SignalMail) SendMail("[ERROR NTS_Buy_Open]", "Position " + Lots + " [" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Open Sell. SL = " + StopLossLevel);
                                Print("Error opening BUY order : ", GetLastError());
 Sleep (10000);
 RefreshRates();
         Ticket = OrderSend(Symbol(), OP_BUYLIMIT, Lots, CloseDeltaMinus0, Slippage, StopLossLevel, TakeProfitLevel, "Buy(#" + MagicNumber + ")", MagicNumber, expiration, DodgerBlue);
       }
   }

         if (EachTickMode) TickCheck = True;
         if (!EachTickMode) BarCount = Bars;
         return(0);
      }
   }
}
 
dimada:
Hello Folks,

I've recently created a simple EA which works in the 30min timeframe. Goal of this EA is to set a buylimit order each time a new Candlestick is generated. The limit order is set 30 pips above the open price, a stop loss is set at the open price.

If the limit order is not triggered it expires after 25 minutes. I tested this EA with the MT4 tester but is looks like the limit order is triggered randomly. Refer to the following pic


As you can see on the 20/09/2013 at 13.00 and 17.30 the tester triggered the limit order even though the price never reached this level. At 17.00 the limit order was 26 pips above the maximum price reached by the candlestick.

A Buy is entered at the Ask price, the chart is drawn by the Bid price, you can't see from the chart what the Ask price was . . . how do you know the Ask price didn't reach your Buy trades opening price ? what was the spread ?
 

Are you kidding ??

set a buylimit order each time a new Candlestick is generated. The limit order is set 30 pips above

how is that possible

this is all nonsens you bring

 

Your first sentence is absolutely correct and it could explain why the price was triggered in the candlestick of 13.00 (refer to the picture I posted in the first post), but I set the spread to 5 in the tester, therefore I cannot understand why the limit order was triggered again at 17.00, in this case the difference by the candlestick price and the order is 26 pips (or 260 ponit in terms of MT4 EA).

What do you think?

Ah, by the way I found a mistake in my code: the ordersend command was set as op_buystop. I corrected it but the error is still there.

 
deVries can you explain better wher is the nonsense? what do you mean? I don't want to play smart here...just understand...
 
dimada:
deVries can you explain better wher is the nonsense? what do you mean? I don't want to play smart here...just understand...


If i see what you wrote and look to the code of the EA that has to do what you wrote

then i think you 're kidding here if you know something about coding

then you don't post you open buylimit above a running candle

otherwise you just copied a program did a little change on it and you have no idea what you're doing

 
Never said I'm a programmer...just a newbie like everybody at the beginning.
However I understand what you are trying to tell me: open buylimit above a running candle. I Should use a buystop order instead.
 

I solved the issue guys, I used the buylimiy and buystop orders in a wrong way. Moreover when I set a trailing stop with my code the EA start to work uncorrectly...need some work on this side

Thanks for the help!

 
dimada:
Never said I'm a programmer...just a newbie like everybody at the beginning.
However I understand what you are trying to tell me: open buylimit above a running candle. I Should use a buystop order instead.


It is not only you should use buystop it is also

is your code compiling correctly ??

then also what is this doing ?? on your strategy.....

//uptrend / downtrend 
int trend;
if (UseTrend1W == 0) trend = 1; 
double SMA1W_26_0 = iMA(NULL, PERIOD_D1, 26, 0, MODE_SMA, PRICE_CLOSE, Current + 0);
double SMA1W_26_1 = iMA(NULL, PERIOD_D1, 26, 0, MODE_SMA, PRICE_CLOSE, Current + 1);
double SMA1W_4_0 = iMA(NULL, PERIOD_D1, 4, 0, MODE_SMA, PRICE_CLOSE, Current + 0);
double SMA1W_4_1 = iMA(NULL, PERIOD_D1, 4, 0, MODE_SMA, PRICE_CLOSE, Current + 1);
double SMA1W_26 = (SMA1W_26_0 - SMA1W_26_1)/SMA1W_26_1;
double SMA1W_4 = (SMA1W_4_0-SMA1W_4_1)/SMA1W_4_1;
if (SMA1W_4 >= SMA1W_26 && UseTrend1W == 1) trend = 1;
if (SMA1W_4 < SMA1W_26 && UseTrend1W == 1 && SMA1W_4_0 < SMA1W_26_0) trend = -1;
if (SMA1W_4 < SMA1W_26 && UseTrend1W == 1 && SMA1W_4_0 > SMA1W_26_0) trend = 1;

double MACD_1W_0 = iMACD(NULL, PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
double MACD_1W_1 = iMACD(NULL, PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
double MACDSIG_1W_0 = iMACD(NULL, PERIOD_D1,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);

if (MACD_1W_0 >= MACDSIG_1W_0 && UseTrend1W == 2) trend = 1;
if (MACD_1W_0 < MACDSIG_1W_0  && UseTrend1W == 2) trend = -1;

if (MACD_1W_0 >= MACD_1W_1 && UseTrend1W == 3) trend = 1;
if (MACD_1W_0 < MACD_1W_1  && UseTrend1W == 3) trend = -1;
 
This part should be a screener on the 1D-timeframe which allows the EA to enter, on the 30min timeframe, only those trades which are following the daily trend. If the external variable UseTrend1W is set to 0 then no screener is active, all trades are triggered. If the external variable UseTrend1W is set to 2, 3 or 4 then it activates three different screeners on the 1D timeframe.
However, disregard this part, it is not active at the moment (as you can see variable trades is not called during the trade triggering).
When I'll introduce this screener I will optimize per UseTrend1W to understand which screener work better.

Did I explain myself correctly? Again, I'm a newbie, sometimes it's hard to deal with the correct terminology.

Coming back to the original post: I corrected the EA and fixed the Trailing Stop issue also. It works now. If you think it can be useful I can post the code.

 
dimada:
This part should be a screener on the 1D-timeframe which allows the EA to enter, on the 30min timeframe, only those trades which are following the daily trend. If the external variable UseTrend1W is set to 0 then no screener is active, all trades are triggered. If the external variable UseTrend1W is set to 2, 3 or 4 then it activates three different screeners on the 1D timeframe.
However, disregard this part, it is not active at the moment (as you can see variable trades is not called during the trade triggering).
When I'll introduce this screener I will optimize per UseTrend1W to understand which screener work better.

Did I explain myself correctly? Again, I'm a newbie, sometimes it's hard to deal with the correct terminology.

Coming back to the original post: I corrected the EA and fixed the Trailing Stop issue also. It works now. If you think it can be useful I can post the code.



this moment your code is nothing doing with the outcome of trend

don't see SIGNAL_...... defined

for checking trades see

count down Loops and Closing or Deleting Orders - MQL4 forum

and modifying don't try modify your trade every point difference on an account where EURUSD is 5 Digits

Reason: