Hi, thanks for the response.
No lines just finding a particular fractal at a point such as the fractal just before MACD crossed and putting a text object there. Or the one just after with a text object. Or even the subsequent one after that if I want.
Marking text objects like A,B,C wave type of thing.
My current code works but seems littered was hoping to shorten it and get rid of what seems like almost redundant functions with the smallest exceptions.
I'll post the code when I get back to my trading desk.
Thanks
Here is the code. As you noticed the A_low(),A_high,B_low,B_high functions all need some counting of histogram to a point. Then I have to select the !=0 fractal.
bool A_high() { { if(!histo()) { ObjectSet ("B1",OBJPROP_BGCOLOR,clrBlack); //up fibo turns black val1=0; for (int i=histodowncount; val1==0; i++) { val1=iFractals(NULL, 0, MODE_UPPER, i); A = val1; if(A!=0) { atime=Time[i]; Print(atime); ObjectSet("B6",OBJPROP_BGCOLOR,clrRed); ObjectSet("B16",OBJPROP_TIME1,atime); ObjectSet("B16",OBJPROP_PRICE1,A); ObjectSet("B16",OBJPROP_ANCHOR,ANCHOR_LOWER); ObjectSetString(0,"B16",OBJPROP_TOOLTIP,"A High = "+DoubleToStr(A,4)); //A_close=Close[i]; //Print(A, " A high Located at bar ",i," atime = ",atime); //Print("A close = ",A_close); return(true); } } } else ObjectSet("B6",OBJPROP_BGCOLOR,clrBlack); } return(false); }So instead of the for loop where I need !=0 values to find fractals I thought maybe UPPER_MODE in an array and LOWER_MODE fractals in another arrray might help me to easier select fractals by index as needed instead of this littered functions I have now. I was curious if this was a thing and if it might be a preferred method that coders would regularly use ?
Thanks
I see , you can create a generic fractal finder and then step it in by calling it as many times as you need to get the fractals you need .
The comments explain the processes
#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); }
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I have been using fractals and finding them in the chart by counting i-- or i++ and also if(fractal != 0) depending on which fractals I'm looking for.
Although this method works, it creates a lot littered and requires duplication in other code sometimes.
I am rethinking my code and I'm curious if guru coders would put this all in an array first and then count.
I could put all UPPER_MODE fractals in an array and all LOWER_MODE fractals in an array and count to that index instead. Instead of worrying about !=0 each time, I would put all !=0 items in the array only that way I know they are all actual values of fractals.
What do you think ?
Is this a reasonable thing to do ? OR is this not something the pros would do.
Please advise
Thanks