Friday, September 25, 2015

How to solve rectangle overlapping issue in MQL4

Are you having trouble fitting the rectangles one on top of the other without the colors mixing or creating color gaps if they both have the same color?
That's not an easy one to solve, since MT4 does not allow you to set any priorities between rectangle objects. So you're left with 2 pretty complex solutions:

1. Either build your overlapping rectangles form out of small blocks that do not overlap.
2. Add a rectangle over the overlapping part and make its color complementary to the color of the recntagle that serves as background. That will nulify its RGB values and allow the rectangle on top to be displayed without any interference. 

Here is a function that I've managed to find (courtesy of the mql5 community, which gives you the "masking" color for background rectangle. 


color MaskColour(color back, color front, color chartBackground) {
   back ^= front;
   back ^= chartBackground;
   return back;
}

I've only altered it to remove the chartBackground as a parameter and read the chart background color automatically.


color mask_color(color back,color front)
  {
   color chartBackground=(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND);
   back^=front;
   back^=chartBackground;
   return(back);
  }

Thursday, September 17, 2015

How to check if a new candle has been opened from an MT4 Expert Advisor

When programming an MT4 robot, you often need to perform certain actions only at the beginning of a new candle. This can be either for execution speed reasons or because of the logic flow of your trading system.

Here is a boolean (true/false) MQL4 function that returns true whenever a new candle has closed/opened on the given timeframe:


bool IsNewCandle(int tf=0)
  {
   static datetime timeLastCandle=0;
   if(iTime(Symbol(),tf,0)==timeLastCandle)
      return (false);
   timeLastCandle=iTime(Symbol(),tf,0);
   return(true);
  }

Let me know if you would have done it differently.

Friday, September 11, 2015

How to properly check if 2 MAs (or any 2 indicator buffers) have just intersected

When building an EA, it is a very common thing to check if a faster MA has just crossed above or below a slower MA.
In other cases, you may be interested to know if the main line of an oscillator has crossed above or below its signal line. In other cases, there are different buffers and you just want to know if they crossed and take a certain action as a result to that.

Here's an example with 2 MAs:

int candleIdx=0;
double fasterMA = iMA(Symbol(), Period(), 50, 0, MODE_EMA, PRICE_CLOSE,candleIdx);
double slowerMA = iMA(Symbol(), Period(), 100, 0, MODE_EMA, PRICE_CLOSE,candleIdx);

Above we have selected the values of the 50 EMA and 100 EMA on the current symbol, current timeframe, at the most recent candle (index=0).
However, we cannot just check whether the faster MA is above the slower MA and determine that the trend has changed bullish based on that. Perhaps the faster MA has been above the slower MA for a long time already. We also need to know where the faster MA was one candle back, relative to the slower MA. If it was below, and now it's above, there's a bullish cross right there. 

So here's the MQL4 code for selecting the values of the MAs for the previous candles:

int candleIdx=0;
double fasterMA = iMA(Symbol(), Period(), 50, 0, MODE_EMA, PRICE_CLOSE,candleIdx+1);
double slowerMA = iMA(Symbol(), Period(), 100, 0, MODE_EMA, PRICE_CLOSE,candleIdx+1);

Now you just need to make the checks and perform the right action in case of a MA crossover.

if (fasterMA>slowerMA && fasterMA_lastBar<=slowerMA_lastBar){
// bullish crossover - do something
}
if (fasterMA<slowerMA && fasterMA_lastBar>=slowerMA_lastBar){
// bearish crossover - do something
}

Additional notes:
- if you want the crossover to be confirmed by the end of the candle (no "repainting" such to speak), then you need to look at the candles with indexes 1 and 2 instead of 0 and 1 - so initializing the candleIdx with value 1 will do just that
- this kind of verification can be applied on any 2 indicator buffers to check the trigger for opening or  closing an opened order

Don't hesitate to send me suggestions for topics you want covered.
Keep on learning MT4 programming, you're doing great!

Nick.

Thursday, September 10, 2015

How to calculate what lot-size to use in your MT4 EA

Here is a function I've just written and tested, called CalculateLots. What it does is that it takes a risk percentage (i.e. 2%) and the stop-loss distance in pips (i.e. 30 pips) and it gives back what the lotsize shoud be so that when the trades hits its 30 pips stop-loss, it losses exactly 2% of the account balance.
Check it out.


double CalculateLots(double riskPercentage, double stopLoss)
  {

   double pipValue=MarketInfo(Symbol(),MODE_TICKVALUE);
   double point=MarketInfo(Symbol(),MODE_POINT);
   double pip=GetPip(Symbol());

   double StopLoss=TriggerDistance;

   double lots=(AccountBalance())*riskPercentage/100/(stopLoss*(pip/point)*pipValue);

   double lotStep=MarketInfo(Symbol(),MODE_LOTSTEP);
   int digits = 0;
   if(lotStep<= 0.01)
      digits=2;
   else if(lotStep<=0.1)
                    digits=1;
   lots=NormalizeDouble(lots,digits);

   double minLots=MarketInfo(Symbol(),MODE_MINLOT);
   if(lots<minLots)
      lots=minLots;

   double maxLots=MarketInfo(Symbol(),MODE_MAXLOT);
   if(lots>maxLots)
      lots=maxLots;

   return (lots);
  }

Moreover, if you do not give a cr@p about what your balance is and how much you're losing relative to that, but you only want to ensure that the SL does not exceed a certain amount of dollars, let's say $50, all you need to do differently is to replace AccountBalance()*riskPercentage/100 with your variable or constant that stores this USD amount.
Good luck learning Metatrader programming, share your ideas and questions below. Thanks!

Wednesday, September 9, 2015

Calculating the distance in pips for SL and TP (based on USD amount) in Metatrader 4

I know I said in my last post that I would do a generic version of a function for closing all orders (both BUY and SELL), but that's simply too easy. Until I get a request for it in the comments, we'll go further to learning more interesting MT4 programming stuff.

For instance, let's assume you want your 0.5 lots orders to either lose $30, or win $30 (when the TP is hit), but you don't know how many pips the EA should set the stoploss and takeprofit from the open price.
Here is how you calculate that:



double GetPipDistanceForAmount(string symbol,double amount,double lots)
  {
   double pipValue=MarketInfo(Symbol(),MODE_TICKVALUE);
   double point=MarketInfo(symbol,MODE_POINT);

   return  ((amount/lots)/pipValue)*point;
  }


The inputs are the amount in dollars you want to lose or gain (i.e. 30) and the volume of the trade (i.e. 0.5 lots).
This function will get you the number of pips you need to set the SL or the TP from the entry price so that you lose or win exactly $30 dollars with a 0.5 lots.
Let me know if this is useful to you and whether you need any help.

If however you do know how many pips your SL and TP should have, but you also want them to lose or gain a specific amount of USD (or whatever the account base currency is), then you need to dynamically calculate the lot-size, while keeping the SL and TP distance and their won/lost amount fixed. Following next, precisely that.

Monday, September 7, 2015

How to close all orders in MT4

In order to close all open market orders that are opened in MT4, you need to write and then call a similar function to the one below:


void CloseBuyOrders(string symbol=NULL,int magicNumber=-1)
  {
   int total=OrdersTotal();
   for(int b=0; b<=total-1; b++)
     {
      if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
        {
         if((OrderMagicNumber()==magicNumber || magicNumber==-1) && (OrderSymbol()==symbol || StringLen(symbol)==0) && OrderType()==OP_BUY)
           {
            ResetLastError();
            color arrowColor=clrSteelBlue;
            if(!_ShowArrows) arrowColor=clrNONE;
            if(!OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),10,arrowColor))
              {
               Print("Failed to close order in "+__FUNCTION__+", error="+(string)GetLastError());
               return;
              }
            else
              {
               total=OrdersTotal();
               b--;
              }
           }
        }
     }
  }

As you can clearly see in the name of this MQL4 function, this is supposed to close the BUY positions only. A function/method for SELL orders would be quite the same, except for one difference - can you guess what that is? Post in the comments below if you know what needs to be changed in the "CloseSellOrders" function.

In the next post I'll probably do a generic function for closing both BUY and SELL orders, or only the type that was sent as a parameter. Thanks for learning MT4 with me!