Fractal Breakdown EA

Hello,

I’ve been using this free EA and it’s working amazingly well so far, I’ve been using the EUR/USD 15M time frame, the losses are many but small while the wins are fewer but huge. I only have a problem with it, it doesn’t really follow Bill Williams recommendations on fractal breakouts and since I don’t know how to code I’m trying my luck here. Bill Williams says the correct way to trade fractal break outs is to put a limit order 1 tick (pip) above or below the fractal yet this EA puts these right on the fractal and I would like to get that changed to 1 pip below the fractal for shorts and 2 pips above the fractal for longs, the reason for 2 pips is the limit order gets triggered by the ask price so that accounts for my spread. Also this should also apply for the stop loss, currently it’s putting the stop loss exactly at the the first fractal and I would like to be 2 pips above the opposite fractal for shorts and 1 pip below the opposite fractal for longs.

Example pic:


Here’s the code:

//+------------------------------------------------------------------+
//|                                            Fractal_Breakdown.mq4 |
//|                               Copyright © 2012, Gehtsoft USA LLC |
//|                                            http://fxcodebase.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, Gehtsoft USA LLC"
#property link      "http://fxcodebase.com"

#define MAGICMA  20050643

extern int Frames=2;
extern int Shift=0;
extern double Lots=0.1;

datetime LastTime;
int TicketB, TicketS, TicketBS, TicketSS;

int Fractals(int bar)
{
 bool Up=true;
 bool Dn=true;
 int i;
 for (i=1;i<=Frames;i++)
 {
  if (High[bar+Frames+i]>=High[bar+Frames] || High[bar+Frames-i]>=High[bar+Frames]) Up=false;
  if (Low[bar+Frames+i]<=Low[bar+Frames] || Low[bar+Frames-i]<=Low[bar+Frames]) Dn=false;
 }
 if (Up)
 {
  if (Dn)
  {
   return (2); // Up and Dn
  }
  else
  {
   return (1); // Up
  }
 }
 else
 {
  if (Dn)
  {
   return (-1); // Dn
  }
  else
  {
   return (0); // None
  }
 }
}

int FindUpFractal(int bar)
{
 int bar_=bar;
 int Fr;
 while (bar_<Bars-Frames)
 {
  Fr=Fractals(bar_);
  if (Fr==2 || Fr==1) return (bar_);
  bar_++;
 }
 return (-1);
}

int FindDnFractal(int bar)
{
 int bar_=bar;
 int Fr;
 while (bar_<Bars-Frames)
 {
  Fr=Fractals(bar_);
  if (Fr==2 || Fr==-1) return (bar_);
  bar_++;
 }
 return (-1);
}

int init()
{
 LastTime=Time[0];
 return(0);
}

int deinit()
{

 return(0);
}
  
void CalculateOrders(string symbol)
{
 TicketB=0; TicketS=0; TicketBS=0; TicketSS=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) TicketB=OrderTicket();
   if(OrderType()==OP_SELL) TicketS=OrderTicket();
   if(OrderType()==OP_BUYSTOP) TicketBS=OrderTicket();
   if(OrderType()==OP_SELLSTOP) TicketSS=OrderTicket();
  }
 }
 return ;  
}  
  

int start()
{
 int Frac;
 int res;
 double OpenPrice;
 double SL;
 int UpFractal, DnFractal;
 UpFractal=-1;
 DnFractal=-1;
 if (LastTime!=Time[0])
 {
  UpFractal=FindUpFractal(1);
  DnFractal=FindDnFractal(1);
  if (UpFractal>0)  // Up fractal
  {
   CalculateOrders(Symbol());
   if (TicketB==0 && TicketBS==0)
   {
    OpenPrice=High[Frames+UpFractal]+Shift*Point;
    res=OrderSend(Symbol(),OP_BUYSTOP,Lots,OpenPrice,5,0,0,"",MAGICMA,0,Blue);
   }
   if (TicketBS!=0)
   {
    OpenPrice=High[Frames+UpFractal]+Shift*Point;
    OrderSelect(TicketBS,SELECT_BY_TICKET);
    if (OpenPrice!=OrderOpenPrice()) OrderModify(TicketBS,OpenPrice,OrderStopLoss(),0,0);
   }
   if (TicketS!=0)
   {
    SL=High[Frames+UpFractal]+Shift*Point;
    OrderSelect(TicketS,SELECT_BY_TICKET);
    if (SL!=OrderStopLoss()) OrderModify(TicketS,0,SL,0,0);
   }
   if (TicketSS!=0)
   {
    SL=High[Frames+UpFractal]+Shift*Point;
    OrderSelect(TicketSS,SELECT_BY_TICKET);
    if (SL!=OrderStopLoss()) OrderModify(TicketSS,OrderOpenPrice(),SL,0,0);
   }
  }
  if (DnFractal>0) // Dn fractal
  {
   CalculateOrders(Symbol());
   if (TicketS==0 && TicketSS==0)
   {
    OpenPrice=Low[Frames+DnFractal]-Shift*Point;
    res=OrderSend(Symbol(),OP_SELLSTOP,Lots,OpenPrice,5,0,0,"",MAGICMA,0,Blue);
   }
   if (TicketSS!=0)
   {
    OpenPrice=Low[Frames+DnFractal]-Shift*Point;
    OrderSelect(TicketSS,SELECT_BY_TICKET);
    if (OpenPrice!=OrderOpenPrice()) OrderModify(TicketSS,OpenPrice,OrderStopLoss(),0,0);
   }
   if (TicketB!=0)
   {
    SL=Low[Frames+DnFractal]-Shift*Point;
    OrderSelect(TicketB,SELECT_BY_TICKET);
    if (SL!=OrderStopLoss()) OrderModify(TicketB,0,SL,0,0);
   }
   if (TicketBS!=0)
   {
    SL=Low[Frames+DnFractal]-Shift*Point;
    OrderSelect(TicketBS,SELECT_BY_TICKET);
    if (SL!=OrderStopLoss()) OrderModify(TicketBS,OrderOpenPrice(),SL,0,0);
   }
  }
  LastTime=Time[0];
 }
 return(0);
}


If someone could make this change it would be great, thanks in advance.

Why change something that’s working amazingly well?

Looks good. But any way to optimize it for other pairs?

To make it better, that would be a good enough reason

Hey Ecerejo,

I am surprised this system works “amazingly well” considering its simplicity… however, what you want to do is already embedded in the code, you must change the “shift” parameters for the EA

The parts of the code with the open price and stop losses are:



OpenPrice=High[Frames+UpFractal]+Shift*Point;

SL=Low[Frames+DnFractal]-Shift*Point;

OpenPrice=Low[Frames+DnFractal]-Shift*Point;

SL=High[Frames+UpFractal]+Shift*Point;


Shift is an external variable that you can set to have a little margin on entry and stop losses, it is multiplied by point so if your broker uses 5 point (1.12345) and you want to set a 2 pip margin you must set shift as 20

Is this what you are looking for?

Hello Spino,

Yes it is, I had no idea what what the “shift” setting was for. I see a “Frames” setting also do you know what this setting is for? Right now is set to 2.

Yes so far it works but I do a little work before I run it, I use it on the 15M EURUSD but at 8am London I check the trend on the 1hour chart by looking at the Awesome Indicator and at the HMA 40 period if these two tell me to go short than I load the EA on the 15M to go short only. I usually stop the EA in the evening 8PM London time. So far I’m happy with the results even though it requires some work on my part, I get early anyways so I can do it. If I knew how to code perhaps I would attempt adding some filters to it but I can’t.

I’m also testing it on GBPUSD, USDCHF and USDCAD but using Renko with wicks, I do exatly the same I first check the trend on the 12 pip renko chart and then run the EA on the 4 pip chart. I’m also happy with the results but I will continue testing it until satisfied with it.

Thanks for the clarification. :slight_smile:

Here’s GBPUSD - 4H
Shift = 35 (to make up the spread for longs, my average spread for this pair e 2.5 pips so 2.5 + 1 = 35)


I will have a better look to find what is the frame variable

How did you get that result in back test if you actually apply manual filters? Can you share all the details of that back test?

I didn’t really use any manual filters for this one, I only used the shift to 35 ticks. When using a specific pair I tend to choose the ones that tend to trend better, the pair must get into strong trends from time to time for this ea to work, a ranging pair would probably wipe out your account, it makes sence. So if you going to use it with both options enabled (Shorts and Longs) you better choose a pair that gets into strong trends.

Now let’s look at it in another way, the GBPUSD started a very strong downtrend last year on July 16th til April 13th of this year, if you were to noticed this downtrend on the daily chart and run this EA on the 4H Chart for shorts only you would of done very well, here’s the graph for shorts only from that date through april 13th:


Unlike the first one, this one barely went to negative territory, the line just kept going up and this is what I mean, this EA will do well if you there is intervention from you, let it run only after your technical analysis tells you the direction of the trend. I really think I can work well as long as your technical analysis is correct.
Below is a pic using a 200 HMA and the Awesome Indy to confirm the downtrend. Perhaps if you were to stop the EA every time you notice a pullback like the one on the pic when the awesome crossed the 0 line and then re-enable it at the first red bar you might even done better.


Nice!

I tried a similar strategy and I confirm the ranging periods wipe the account, I am still finding hard to code something to detect the strange of the trend…

So if I well understand this code is not using the function iFractals (native) to find the fractal, it uses a loop that checks highs and low, the “frames” variable tells the code ho many bars to check

Frames = 2 is the default fractal where the high is with two lower bars before and after
I wouldn’t change that.

Yes i did notice that, I do have a fractal level indicator and the only variable that it has is “fractalbars” which has the same effect, if you set it at 3 than it only gives you a fractal point if you have at least 3 bars on each side instead of 2.

Can somebody add to this EA a trailing fractal stop loss so it follows alone when price is trending?

EA Not Work well in todays market condition i.e (2020-23 Y24 yr