Check previous candle size before opening trade

 

Hi everyone..total noob here! You've been warned. I just want to say ahead of time that I did run a search on the forum and couldn't find what I was looking for, most likely because of the amount of information that is one here (A LOT!).

With that said, what I am attempting to do is create, very primitively, an EA that opens a trade when price closes above/below the 34EMA, but I want it to check to make sure that the previously closed candle body (open to close) did not change by more than 30 pips. There are other check I want to add for when to close, but I'll leave it at this for now. Any help would be appreciated!! Code included. Yes I did start this with the sample MA EA that came with MT4 and I don't know what a lot of it means, but I do know other forms of coding/programming so I catch on pretty quick.


Code:

//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "Moving Average sample expert advisor"

#define MAGICMA  20131111
//--- Inputs
input double Lots          =0.1;
input int    MovingPeriod  =34;
input int    MovingShift   =0;
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break


//--- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma;
   int    res;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_EMA,PRICE_CLOSE,0);
//--- sell conditions
   if(Open[1]>ma && Close[1]<ma || Open[0]>ma && Close[0]<ma && Open[1]-Close[1] <= 0.0030)
     {
      res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//--- buy conditions
   if(Open[1]<ma && Close[1]>ma || Open[0]<ma && Close[0]>ma && Close[1]-Open[1] <= 0.0030)
     {
      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double ma;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_EMA,PRICE_CLOSE,0);
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      //--- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma)
           
           
           {
            if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,White))
               Print("OrderClose error ",GetLastError());
           
           
           }
         break;
        
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma)
         
      
         {
           
           {
            if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White))
               Print("OrderClose error ",GetLastError());
           }
         break;
        
        
        }
     }
//---
  }}
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//---
  }
//+------------------------------------------------------------------+
 

Hi Jon,

First things first, since you're working with MT4 you have to specify the compiler that you want to use. You always want to use the new compiler, so always begin your MQL4 projects with 

#property strict

https://docs.mql4.com/mql4changes#compiler_difference


Next, there seem to be a lot of room for improvement with your opening logic. Let's see how we can improve it..

    if(Open[1]<ma && Close[1]>ma || Open[0]<ma && Close[0]>ma && Close[1]-Open[1] <= 0.0030)
       ...
if((Open[1]<ma && Close[1]>ma || Open[0]<ma && Close[0]>ma) && fabs(Close[1]-Open[1]) <= 300*_Point)
       ...
Updated MQL4 - MQL4 Reference
Updated MQL4 - MQL4 Reference
  • docs.mql4.com
Starting from build 600, MQL4 programming language has been completely revised reaching the level of MQL5 - now you can develop trading robots in MQL4/5 using the unified MetaEditor development environment, single style, libraries and debugging tools. MQL4 is popular among automated system developers due to the ease of learning and a huge...
 
  1. Never mix ands and ors together. Always parenthese
      if(  Open[1]<ma && Close[1]>ma  ||  Open[0]<ma && Close[0]>ma  && Close[1]-Open[1] <= 0.0030)  ambiguous
      if( (Open[1]<ma && Close[1]>ma) || (Open[0]<ma && Close[0]>ma  && Close[1]-Open[1] <= 0.0030)) did you mean this?
      if(  Open[1]<ma &&(Close[1]>ma  ||  Open[0]<ma)&& Close[0]>ma  && Close[1]-Open[1] <= 0.0030)  or this?
      if(((Open[1]<ma && Close[1]>ma) || (Open[0]<ma)&& Close[0]>ma))&& Close[1]-Open[1] <= 0.0030)  or this?
  2. Write self-documenting code
    bool crossUp1 = Open[1]<ma && Close[1]>ma;
    bool crossUp0 = Open[0]<ma && Close[0]>ma;
    bool small1   = Close[1]-Open[1] <= 0.0030;
    if( (crossUp1 || crossUp0) && small1)
  3. Don't hard code constants. Code breaks on JPY pairs. If you want 30 pips compute what a pip is and use it.
              How to manage JPY pairs with parameters? - MQL4 and MetaTrader 4 - MQL4 programming forum

 
nicholishen:

Hi Jon,

First things first, since you're working with MT4 you have to specify the compiler that you want to use. You always want to use the new compiler, so always begin your MQL4 projects with 

https://docs.mql4.com/mql4changes#compiler_difference


Next, there seem to be a lot of room for improvement with your opening logic. Let's see how we can improve it..

whroeder1:
  1. Never mix ands and ors together. Always parenthese
  2. Write self-documenting code
  3. Don't hard code constants. Code breaks on JPY pairs. If you want 30 pips compute what a pip is and use it.
              How to manage JPY pairs with parameters? - MQL4 and MetaTrader 4 - MQL4 programming forum

Thank you both for replying so quickly! I will try to implement these corrections/improvements next chance I get and I will update.

nicholishen: I will read up on the compiler and try your code to see if it gives me the desired result, I'll keep you updated.


whroeder1:

1. Like I said, I'm a total noob at mql4, so I'm not even entirely sure what the results of those differences in coding are. I will test them all and let you know.

2. I'm definitely working my way up to this. I haven't quite learned it yet but it is definitely something I will do.

3. I will try to keep from doing this. At the moment, I'm not too concerned with it only because this is intended for non-JPY pairs.


Again thank you both for your input and assistance!

 

Hi whroeder1 and nicholishen


I test all the improvements and corrections you provided. Up to now, moving around the parenthesis to correctly group the code has resolved the problem with the EA taking trades after 30+pip bodies. Thank you guys so much for the suggestions! I'm going to keep improving it, as I've come across some other issues, but I'm going to open another topic for it because it is not related to this issue.

Reason: