Tuesday, December 8, 2015

How to detect fractals in MT4 (+code sample)

When your DIY MT4 programing project requires you to implement swing detection or breakout levels, it's almost impossible not to think about working with fractals.

However, the MT4 fractals don't allow you to change the 2-bar lookback period that the Bill Williams indicator uses to find where the market made a swing lower or higher.
In some cases, you may want to have this period adjustable, so you can validate a fractal only if 5 or more bars are swinging lower and lower before a low fractal is formed.

As you know, the default behavior of the default fractal indicator uses repainting. So it prints the lower fractal as soon as the market steps 2 consecutive candles lower, before waiting for the next 2 candles to be closed and the swing confirmed. Later, if the middle candle was broken below, price went lower and lower, the fractal will be repainted.

You may also want to configure this confirmation period to 1 full candle or even more with a '5-bar fractal'. So how do you implement a custom fractal checking function in MQL4? Here're a few lines of code that will guide you, the sample is pretty straightfoward.


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool fractal_lower(int idx)
  {
   for(int i=1; i<=CANDLES; i++)
     {
      if(Low[idx+i]<=Low[idx]) return false;
     }

   for(int i=1; i<=CANDLES; i++)
     {
      if(idx-i>=0 && Low[idx-i]<=Low[idx]) return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool fractal_upper(int idx)
  {
   for(int i=1; i<=CANDLES; i++)
     {
      if(High[idx+i]>=High[idx]) return false;
     }

   for(int i=1; i<=CANDLES; i++)
     {
      if(idx-i>=0 && High[idx-i]>=High[idx]) return false;
     }
   return true;
  }

Saturday, October 24, 2015

How to manually confirm a trade taken by the EA

Automated trading is great, you can have your strategy execute the transactions with near perfect precision at the right time, at the right level.
But what happens when you're not 100% confident on the rules of your strategy and you believe that you need your own discretion to choose which signals should turn into market orders and which should be ignored (due to aspects that cannot be put into mathematical formulas)?

MT4 programming can also allow you to create semi-automated Expert Advisors. This basically means that you are able to create an EA that runs continuously, checking the markets for a valid trade setup, but it does not place the orders without you confirming what is has found.
Whenever a valid setup is detected, a popup will appear, asking you if you want to continue by placing an order or ignore this signal and wait for a better one.
Here's how you can do this:



bool ManuallyConfirmed(int sign) // BUY - sign=1, SELL - sign=-1 
  {
   if(!_AskForManualConfirmation) return true;

   string s_type="BUY";
   if(sign<0) s_type="SELL";

   return Verify(WindowExpertName()+ " wants to open a "+s_type+" trade on "+Symbol()+", "+timeFrameToString(Period())+". Do you allow it?");
  }

This function takes an int parameter signaling the type of the trade (buy or sell), and returns true or false after the user has manually confirmed or denied the trade operation.

bool Verify(string message,string subject="Manual confirmation required")
  {
   return (MessageBox(message,subject,MB_YESNO)==IDYES);
  }

The fucntion Verify uses the MQL4 function MessageBos and returns true if the user confirmed (IDYES).

And once you have these 2 functions, all you need to do is call the ManuallyConfirmed function once you have a BUY or SELL signal, and only open the trade if it returns true.

      bool confirmed=ManuallyConfirmed(sign);
      if(confirmed)
        {
             // OPEN BUY or SELL here
         }

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.