DannyBass  

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!

Lorentzos Roussos  
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
fractal_both=3//both (also known as headache)
};
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;
double          price2,opposite_price2;//for headache fractals
                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);
}
DannyBass  
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   😊