//+------------------------------------------------------------------+ //| Goertzel browser | //| | //+------------------------------------------------------------------+ #property copyright "www.forex-tsd.com" #property link "www.forex-tsd.com" #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 PaleVioletRed #property indicator_width1 2 // // // // // extern string TimeFrame = "Current time frame"; extern int Price = PRICE_CLOSE; extern int BarToCalculate = 1; extern int StartAtCycle = 1; extern int UseTopCycles = 2; extern bool UseCosineForWaves = true; extern bool UseAdditionForSteps = false; extern bool UseSquaredAmp = true; extern int MaxPer = 120; extern int SampleSize = 0; extern int WindowSizePast = 100; extern int WindowSizeFuture = 100; extern color FutureLineColor = PaleVioletRed; extern int FutureLineStyle = STYLE_DOT; extern int FutureLineDisplace = 0; extern bool UseCycleList = false; extern int Cycle1 = 1; extern int Cycle2 = 1; extern int Cycle3 = 1; extern int Cycle4 = 1; extern int Cycle5 = 1; extern int Offset = 0; extern bool SubtractNoise = false; extern bool ListOfCyclesVisible = true; extern string ListOfCyclesID = "GortzelBrowser"; extern int ListOfCyclesCorner = 1; extern color ListOfCyclesTextColor = DimGray; extern color ListOfCyclesValueColor = PaleVioletRed; extern bool Interpolate = true; // // // // // double values[]; double goertzel[]; double goertzelFuture[]; double workPast[][30]; double workFuture[][30]; string name; int ListOfCyclesWindow; string indicatorFileName; bool calculateValue; int timeFrame; //+------------------------------------------------------------------ //| //+------------------------------------------------------------------ // // // // // int init() { IndicatorDigits(6); IndicatorBuffers(3); SetIndexBuffer(0, goertzel); SetIndexBuffer(1, goertzelFuture); SetIndexBuffer(2, values); // // // // // MaxPer = MathMax(MaxPer,2); SampleSize = MathMax(SampleSize,3*MaxPer); WindowSizePast = MathMax(WindowSizePast,3*MaxPer); BarToCalculate = MathMax(BarToCalculate,0); indicatorFileName = WindowExpertName(); timeFrame = stringToTimeFrame(TimeFrame); calculateValue = TimeFrame=="calculateValue"; if (!calculateValue) ListOfCyclesID = timeFrameToString(timeFrame)+" "+ListOfCyclesID; name = ListOfCyclesID+" - Gortzel browser ("+BarToCalculate+")"; IndicatorShortName(name); return (0); } // // // // // int deinit() { string searchFor = ListOfCyclesID+":"; int searchLength = StringLen(searchFor); for (int i=ObjectsTotal()-1; i>=0; i--) { string name = ObjectName(i); if (StringSubstr(name,0,searchLength) == searchFor) ObjectDelete(name); } return (0); } //+------------------------------------------------------------------ //| //+------------------------------------------------------------------ // // // // // int start() { int counted_bars = IndicatorCounted(); int limit,i,k; if(counted_bars < 0) return(-1); if(counted_bars > 0) counted_bars--; limit = MathMin(Bars-counted_bars,Bars-1); if (Bars < 3*MaxPer) { Comment(" Not Enough bars: you need 3*MaxPer -> " + DoubleToStr(3 * MaxPer, 0)); return (0); } // // // // // if (calculateValue || timeFrame==Period()) { ListOfCyclesWindow = WindowFind(name); for(i = limit; i >= 0; i--) values[i] = iMA(NULL,0,1,0,MODE_SMA,Price,i); int number_of_cycles = iGoertzel(BarToCalculate,WindowSizePast,workPast,WindowSizeFuture,workFuture,UseCosineForWaves,UseAdditionForSteps,UseSquaredAmp); showCycles(number_of_cycles); // // // // // for (i=0; i 0) goertzel[i] += workPast[i][Cycle1-1]; if (Cycle2 > 0) goertzel[i] += workPast[i][Cycle2-1]; if (Cycle3 > 0) goertzel[i] += workPast[i][Cycle3-1]; if (Cycle4 > 0) goertzel[i] += workPast[i][Cycle4-1]; if (Cycle5 > 0) goertzel[i] += workPast[i][Cycle5-1]; } else { for (k=StartAtCycle-1; k 0) goertzelFuture[i] += workFuture[i][Cycle1-1]; if (Cycle2 > 0) goertzelFuture[i] += workFuture[i][Cycle2-1]; if (Cycle3 > 0) goertzelFuture[i] += workFuture[i][Cycle3-1]; if (Cycle4 > 0) goertzelFuture[i] += workFuture[i][Cycle4-1]; if (Cycle5 > 0) goertzelFuture[i] += workFuture[i][Cycle5-1]; } else { for (k=StartAtCycle-1; k0; i--) { string cname = ListOfCyclesID+":l:"+i; ObjectCreate(cname,OBJ_TREND,ListOfCyclesWindow,0,0); ObjectSet(cname,OBJPROP_TIME1, Time[0]+Period()*60*(WindowSizeFuture-i+skip)-FutureLineDisplace); ObjectSet(cname,OBJPROP_TIME2, Time[0]+Period()*60*(WindowSizeFuture-i+skip+1)-FutureLineDisplace); ObjectSet(cname,OBJPROP_PRICE1,goertzelFuture[i]); ObjectSet(cname,OBJPROP_PRICE2,goertzelFuture[i-1]); ObjectSet(cname,OBJPROP_RAY,false); ObjectSet(cname,OBJPROP_COLOR,FutureLineColor); ObjectSet(cname,OBJPROP_STYLE,FutureLineStyle); } // // // // // SetIndexDrawBegin(0,Bars-WindowSizePast+1); return(0); } // // // // // limit = MathMin(Bars-1,WindowSizePast*timeFrame/Period()); for (i=limit;i>=0; i--) { int y = iBarShift(NULL,timeFrame,Time[i]); goertzel[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Price,BarToCalculate,StartAtCycle,UseTopCycles,UseCosineForWaves,UseAdditionForSteps,UseSquaredAmp, MaxPer,SampleSize,WindowSizePast,WindowSizeFuture,FutureLineColor,FutureLineStyle,Period()*60,UseCycleList,Cycle1,Cycle2,Cycle3,Cycle4,Cycle5,Offset,SubtractNoise, ListOfCyclesVisible,ListOfCyclesID,ListOfCyclesCorner,ListOfCyclesTextColor,ListOfCyclesValueColor,0,y); // // // // // if (!Interpolate || y==iBarShift(NULL,timeFrame,Time[i-1])) continue; interpolate(goertzel,iTime(NULL,timeFrame,y),i); } SetIndexDrawBegin(0,Bars-WindowSizePast*(timeFrame/Period())+1); return (0); } //+------------------------------------------------------------------- //| //+------------------------------------------------------------------- // // // // // void interpolate(double& buffer[], datetime time, int i) { for (int n = 1; (i+n) < Bars && Time[i+n] >= time; n++) continue; // // // // // if (buffer[i] == EMPTY_VALUE || buffer[i+n] == EMPTY_VALUE) n=-1; double increment = (buffer[i+n] - buffer[i])/ n; for (int k = 1; k < n; k++) buffer[i+k] = buffer[i] + k*increment; } //+------------------------------------------------------------------ //| //+------------------------------------------------------------------ // // // // // double goeWork1[]; double goeWork2[]; double goeWork3[]; double goeWork4[]; double cyclebuffer[]; double amplitudebuffer[]; double phasebuffer[]; #define pi 3.141592653589793238462643383279502884197169399375105820974944592 // // // // // int iGoertzel(int forBar, int numBarsPast, double& goeWorkPast[][], int numBarsFuture, double& goeWorkFuture[][], bool useCosine = true, bool useAddition = true, bool squaredAmp=true) { int sample = MathMin(Bars-forBar,SampleSize); if (ArraySize(goeWork4)!=sample+1) { ArrayResize(goeWork1,sample+1); ArrayResize(goeWork2,sample+1); ArrayResize(goeWork3,sample+1); ArrayResize(goeWork4,sample+1); } if (ArraySize(cyclebuffer)!=MaxPer+1) { ArrayResize(cyclebuffer ,MaxPer+1); ArrayResize(amplitudebuffer,MaxPer+1); ArrayResize(phasebuffer ,MaxPer+1); } if (ArrayRange(goeWorkPast,0) !=numBarsPast) ArrayResize(goeWorkPast ,numBarsPast); if (ArrayRange(goeWorkFuture,0)!=numBarsFuture) ArrayResize(goeWorkFuture,numBarsFuture); // // // // // double temp1 = values[forBar + sample-1]; double temp2 = (values[forBar] - temp1) / (sample-1); double temp3; for (int k = sample; k>0; k--) { goeWork4[k] = values[forBar+k-1] - (temp1 + temp2*(sample-k)); goeWork3[k] = 0; } goeWork3[0]=0; // // // // // for (k = 2; k <= MaxPer; k++) { double w = 0; double x = 0; double y = 0; double z = MathPow(k, -1); temp1 = 2.0 * MathCos(2.0 * pi * z); for (int i = sample; i > 0; i--) { w = temp1 * x - y + goeWork4[i]; y = x; x = w; } temp2 = x - y / 2.0 * temp1; if (temp2 == 0.0) temp2 = 0.0000001; temp3 = y * MathSin(2.0 * pi * z); // // // // // if(squaredAmp==true) goeWork1[k] = MathPow(temp2,2)+MathPow(temp3,2); else goeWork1[k] = MathSqrt(MathPow(temp2,2)+MathPow(temp3,2)); goeWork2[k] = MathArctan(temp3/temp2); if (temp2 < 0.0) goeWork2[k] += pi; else if (temp3 < 0.0) goeWork2[k] += 2.0 * pi; } // // // // // for (k = 3; k < MaxPer; k++) if (goeWork1[k] > goeWork1[k+1] && goeWork1[k] > goeWork1[k-1]) goeWork3[k] = k * MathPow(10, -4); else goeWork3[k] = 0.0; // // // extract cycles // // int number_of_cycles = 0; for (i = 0; i 0.0) { cyclebuffer[number_of_cycles] = MathRound(10000.0 * goeWork3[i]); amplitudebuffer[number_of_cycles] = goeWork1[i]; phasebuffer[number_of_cycles] = goeWork2[i]; number_of_cycles++; } // // // order cycles // // for (i = 0; i < number_of_cycles-1; i++) for (k = i+1; k < number_of_cycles; k++) if (amplitudebuffer[k] > amplitudebuffer[i]) { y = amplitudebuffer[i]; w = cyclebuffer[i]; x = phasebuffer[i]; amplitudebuffer[i] = amplitudebuffer[k]; cyclebuffer[i] = cyclebuffer[k]; phasebuffer[i] = phasebuffer[k]; amplitudebuffer[k] = y; cyclebuffer[k] = w; phasebuffer[k] = x; } // // // calculate waves // // for (i=0; i=0; i--) { string name = ObjectName(i); if (StringSubstr(name,0,searchLength) == searchFor) ObjectDelete(name); } } // // // // // double xpos1[] = {232,210,147,97,52,10}; double xpos2[] = {10,75,95,160,212,255}; void showCycle(int cycleNo, int totalCycles, double period, double amplitude, double phase) { double xpos[6]; int ypos; // // // // // if (ListOfCyclesCorner== 2 || ListOfCyclesCorner==3) ypos = (totalCycles-cycleNo+1)*11; else ypos = cycleNo*11; if (ListOfCyclesCorner== 1 || ListOfCyclesCorner==3) ArrayCopy(xpos,xpos1); else ArrayCopy(xpos,xpos2); // // // // // if (period==-1) if (ListOfCyclesCorner== 1 || ListOfCyclesCorner==3) setElement(cycleNo+"-6",xpos[5],ypos,ListOfCyclesTextColor ,"* amplitude multiplier : 10^"+DoubleToStr(amplitude,0),8); else setElement(cycleNo+"-6",xpos[0],ypos,ListOfCyclesTextColor ,"* amplitude multiplier : 10^"+DoubleToStr(amplitude,0),8); else { setElement(cycleNo+"-0",xpos[0],ypos,ListOfCyclesTextColor ,cycleNo+" period :"); setElement(cycleNo+"-1",xpos[1],ypos,ListOfCyclesValueColor,DoubleToStr(period,0)); setElement(cycleNo+"-2",xpos[2],ypos,ListOfCyclesTextColor ,"amplitude :"); setElement(cycleNo+"-3",xpos[3],ypos,ListOfCyclesValueColor,DoubleToStr(amplitude,4)); setElement(cycleNo+"-4",xpos[4],ypos,ListOfCyclesTextColor ,"phase :"); setElement(cycleNo+"-5",xpos[5],ypos,ListOfCyclesValueColor,DoubleToStr(phase,2)); } } // // // // // void setElement(string element, int x, int y, color ecolor=Silver, string text = "", int fontsize = 9, string fontname="Arial", int angle=0) { string name = ListOfCyclesID+":"+element; ObjectCreate(name, OBJ_LABEL, ListOfCyclesWindow, 0, 0); ObjectSet(name, OBJPROP_XDISTANCE, x); ObjectSet(name, OBJPROP_YDISTANCE, y); ObjectSet(name, OBJPROP_BACK, FALSE); ObjectSet(name, OBJPROP_CORNER, ListOfCyclesCorner); ObjectSet(name, OBJPROP_ANGLE, angle); ObjectSetText(name, text, fontsize, fontname, ecolor); } //+------------------------------------------------------------------- //| //+------------------------------------------------------------------- // // // // // string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"}; int iTfTable[] = {1,5,15,30,60,240,1440,10080,43200}; // // // // // int stringToTimeFrame(string tfs) { tfs = stringUpperCase(tfs); for (int i=ArraySize(iTfTable)-1; i>=0; i--) if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(MathMax(iTfTable[i],Period())); return(Period()); } string timeFrameToString(int tf) { for (int i=ArraySize(iTfTable)-1; i>=0; i--) if (tf==iTfTable[i]) return(sTfTable[i]); return(""); } // // // // // string stringUpperCase(string str) { string s = str; for (int length=StringLen(str)-1; length>=0; length--) { int char = StringGetChar(s, length); if((char > 96 && char < 123) || (char > 223 && char < 256)) s = StringSetChar(s, length, char - 32); else if(char > -33 && char < 0) s = StringSetChar(s, length, char + 224); } return(s); }