# Fractal

Hello guys! Trying to get the latest fractal value and I came up with this:

```double GetLowFractal()
{
double val=0;
for(int i=0; i<300; i++)
{

val=iFractals(NULL,0,MODE_LOWER,i);
if(val!=0)
break;

}
return NormalizeDouble(val,_Digits);
}```

it works, but am just wondering if any other simple version that I cannot see.

Also, this is a function which returns this double. How can I get the latest fractal value without  wrighting a separate function like this.

I need this value for trailing stoploss. So I have a trailingstop function. How can I get latest fractal value inside trailing function, without writing another function.

Thanks!

DannyBass:

Hello guys! Trying to get the latest fractal value and I came up with this:

it works, but am just wondering if any other simple version that I cannot see.

Also, this is a function which returns this double. How can I get the latest fractal value without  wrighting a separate function like this.

I need this value for trailing stoploss. So I have a trailingstop function. How can I get latest fractal value inside trailing function, without writing another function.

Thanks!

Hi , here is a generic fractal finder . Although you are going to need a modification pertaining to a fractal being above or below a specific price

```#property strict

int OnInit()
{
//test lets find the 3 first fractals
fractal_info fA,fB,fC;
//1st , can be anywhere before bar 1
bool foundA=find_a_fractal_before_this_bar(0,1,true,true,3,3,0,0,3,fA);
//we send before 0 because its non inclusive of the bar before
//if a is found
if(foundA){
Print("Found A");
//we look for the bar using the result's time before the new search
int aI=iBarShift(_Symbol,_Period,fA.time,true);
bool foundB=find_a_fractal_before_this_bar(aI,aI+1,true,true,3,3,0,0,3,fB);
//if b is found
if(foundB){
Print("Found B");
//we look for the bar again using the result's time
int bI=iBarShift(_Symbol,_Period,fB.time,true);
bool foundC=find_a_fractal_before_this_bar(bI,bI+1,true,true,3,3,0,0,3,fC);
//if c is found
if(foundC){
Print("Found C");
//lets display the fractals (note if the fractal is type both we are not checking for that in the display
createMark(fA.time,fA.price,clrOrange,2,"FractalA");
createMark(fB.time,fB.price,clrOrange,2,"FractalB");
createMark(fC.time,fC.price,clrOrange,2,"FractalC");
}
}

}

//---
return(INIT_SUCCEEDED);
}

enum type_of_fractal{
fractal_void=0,//nothing
fractal_high=1,//high
fractal_low=2,//low
};
struct fractal_info{
bool            valid;
datetime        time;
int             bar_index;//trust this only at the time of return ! If the asset changes bar when the result is returned this bar index is no longer valid!
type_of_fractal type;
double          price,opposite_price;
fractal_info(void){reset();}
~fractal_info(void){reset();}
void reset(){
time=0;
type=fractal_void;
price=0.0;//redundant
price2=0.0;//
opposite_price=0.0;
opposite_price2=0.0;
bar_index=-1;
valid=false;
}
void set(datetime _time,type_of_fractal _type,double _price1,double _opposite_price1,double _price2,double _opposite_price2,int _i){
valid=true;
time=_time;
type=_type;
price=_price1;
price2=_price2;
opposite_price=_opposite_price1;
opposite_price2=_opposite_price2;
bar_index=_i;
}
void set(datetime _time,type_of_fractal _type,double _price,double _opposite_price,int _i){
set(_time,_type,_price,_opposite_price,0.0,0.0,_i);
}

};

bool find_a_fractal_before_this_bar(int before_this_bar,//you want the fractal to be before this bar index
int latest_closed_bar_or_simulation_of,//the latest CLOSED bar , live or in simulation (its important to maintain symmetry past-future)
bool allow_highs,//look for highs ?
bool allow_lows,//look for lows ?
int left_bars,//bars to the left of the fractal
int right_bars,//bars to the right of the fractal
int min_left_side,//minimum accepted left side size , OR , 0
int min_right_side,//minimum accepted right side size , OR , 0
int max_equals,//max equal price skips
fractal_info &result//we will send the results there
){
/*
fractals are ridiculously simple
you want highs of bars to the left and highs of bars to the right of a bar to be below the high
for an up fractal
and the opposite
The only concern is the right bars you need to check.
So if we were at bar [0] in live execution
and we need to find fractals with 2 left bars and 2 right bars
the last right bar can be up to recent as bar [1]
So the first eligible bar for being a fractal is
Last Closed Bar + Right Bars , so [1+2] bar [3] (we add because mt4 has 0 to the right in the index of bars)
So latest closed bar or simulation of becomes the limit of our search to the right side
we just need to remember that whichever bar we are testing in the past we are supposedly at the open price and open time
of that bar (in the simulation) so the most recent available bar (if said bar is X) would be X+1.
Before this bar and latest closed bar can be equal no issue there .
*/
//so , reset the result
bool found=false;
result.reset();
//start searching
//lets declare the bar indexes in a simpler manner
//the "before this bar" turns to b
int b=before_this_bar;
//the "latest" turns to x
int x=latest_closed_bar_or_simulation_of;
//the bar to start from
int from=0;
//so we need the first candidate to be up to x and before b non including b
//If 1st candidate is at b+1 then
from=b+1;
//it must also have its last right side bar up to x
if((x+right_bars)>from){from=x+right_bars;}
//also if we reach the bars limit we must stop
int bar_limit=Bars-2;
//loop into bars
for(int i=from;i<=bar_limit;i++)
{
int equal_skips=0;
bool eligible_high=false,eligible_low=false;
//test high
if(allow_highs){
eligible_high=true;
double price=High[i];
//keep tabs on the sides size
double max_right_side_size=0.0,max_left_side_size=0.0;
//secondary loop into the bars surrounding our fractal candidate
int test_from=i-right_bars;
int test_to=i+left_bars;
int test_nav=test_from;
while(eligible_high&&test_nav<=test_to){
//if this is not the same bar as i
if(test_nav!=i){
//if we are on the right side - accept only lower than i's high price
if(test_nav<i)
{
if(High[test_nav]>=price){eligible_high=false;}
//we check for the max distance to the right
if((price-High[test_nav])>max_right_side_size){max_right_side_size=price-High[test_nav];}
}
//if we are on the left side
else if(test_nav>i){
//we can accept equals here up to the max allowed
if(High[test_nav]>price||(High[test_nav]==price&&equal_skips>=max_equals)){eligible_high=false;}
else if(High[test_nav]==price&&equal_skips<max_equals){
//on equals we need to count the skip
equal_skips++;
//and extend the search area to the left
test_to++;
}
//we check for the max distance to the left
if((price-High[test_nav])>max_left_side_size){max_left_side_size=price-High[test_nav];}
}
}
//increase the test bar
test_nav++;
}
//if eligible high , test the side sizes
if(eligible_high){
if(min_left_side>0&&((int)(max_left_side_size/_Point))<min_left_side){eligible_high=false;}
if(min_right_side>0&&((int)(max_right_side_size/_Point))<min_right_side){eligible_high=false;}
}
}//test high ends here
//test low
if(allow_lows){
eligible_low=true;
double price=Low[i];
//keep tabs on the sides size
double max_right_side_size=0.0,max_left_side_size=0.0;
//secondary loop into the bars surrounding our fractal candidate
int test_from=i-right_bars;
int test_to=i+left_bars;
int test_nav=test_from;
while(eligible_low&&test_nav<=test_to){
//if this is not the same bar as i
if(test_nav!=i){
//if we are on the right side - accept only higher than i's low price
if(test_nav<i)
{
if(Low[test_nav]<=price){eligible_low=false;}
//we check for the max distance to the right
if((Low[test_nav]-price)>max_right_side_size){max_right_side_size=Low[test_nav]-price;}
}
//if we are on the left side
else if(test_nav>i){
//we can accept equals here up to the max allowed
if(Low[test_nav]<price||(Low[test_nav]==price&&equal_skips>=max_equals)){eligible_low=false;}
else if(Low[test_nav]==price&&equal_skips<max_equals){
//on equals we need to count the skip
equal_skips++;
//and extend the search area to the left
test_to++;
}
//we check for the max distance to the left
if((Low[test_nav]-price)>max_left_side_size){max_left_side_size=Low[test_nav]-price;}
}
}
//increase the test bar
test_nav++;
}
//if eligible low , test the side sizes
if(eligible_low){
if(min_left_side>0&&((int)(max_left_side_size/_Point))<min_left_side){eligible_low=false;}
if(min_right_side>0&&((int)(max_right_side_size/_Point))<min_right_side){eligible_low=false;}
}
}//test low ends here
//if eligible high or eligible low bounce
if(eligible_high||eligible_low){
if(eligible_high&&!eligible_low){
result.set(Time[i],fractal_high,High[i],Low[i],i);
}
else if(eligible_high&&eligible_low){
result.set(Time[i],fractal_both,High[i],Low[i],Low[i],High[i],i);//the high price is price 1 in both
}
else if(!eligible_high&&eligible_low){
result.set(Time[i],fractal_low,Low[i],High[i],i);
}
found=true;
break;
}
}
//loop into bars ends here
return(found);
}

void createMark(datetime time,double price,color clr,int width,string name){
ObjectCreate(ChartID(),name,OBJ_ARROW,0,time,price);
ObjectSetInteger(ChartID(),name,OBJPROP_COLOR,clr);
ObjectSetInteger(ChartID(),name,OBJPROP_WIDTH,width);
}```

Lorentzos Roussos #:

Hi , here is a generic fractal finder . Although you are going to need a modification pertaining to a fractal being above or below a specific price

Thanks..but ...OMG   😊