//+------------------------------------------------------------------+ //| //| Copyright 2007, MetaQuotes Software Corp. | //| | //+------------------------------------------------------------------+ #property copyright "Copyright 2007, MetaQuotes Software Corp." #property link "" #property indicator_chart_window #property indicator_buffers 1 #property indicator_color1 White //---- indicator parameters extern int Depth=12; extern int Deviation=5; extern int Backstep=3; extern int epsX=5; extern int epsY=80; //---- indicator buffers double ZZ[]; double HH[]; double LL[]; int level=3; // recounting's depth bool downloadhistory=false; #define pi 3.14159265 #define phi 1.61803399 #define FX5_Square "FX5_Square" #define FX5_Spiral "FX5_Spiral:#" //---- input parameters extern int radius = 7; extern double goldenSpiralCycle = 1.5;//1; extern double accurity = 0.1618;//0.2; extern bool clockWiseSpiral = true; extern color spiralColor1 = Blue; extern color spiralColor2 = Red; //+------------------------------------------------------------------+ int init() { //---- indicators IndicatorBuffers(3); SetIndexBuffer(0, ZZ); SetIndexStyle(0,DRAW_SECTION); SetIndexStyle(1,DRAW_ARROW); SetIndexBuffer(1,HH); SetIndexStyle(2,DRAW_ARROW); SetIndexBuffer(2,LL); SetIndexEmptyValue(0,0.0); SetIndexEmptyValue(1,0.0); SetIndexEmptyValue(2,0.0); IndicatorShortName("ZigZag("+Depth+","+Deviation+","+Backstep+")"); if(VerifyParams() == -1) return(-1); CreateSquare(); return(0); } //+------------------------------------------------------------------+ int deinit() { DeleteSpiral(); ObjectDelete(FX5_Square); ObjectDelete("cross"); ObjectDelete("near"); Comment(" "); return(0); } //+------------------------------------------------------------------+ int start() { //---- int i, counted_bars = IndicatorCounted(); int limit,counterZ,whatlookfor; int shift,back,lasthighpos,lastlowpos; double val,res; double curlow,curhigh,lasthigh,lastlow; if (counted_bars==0 && downloadhistory) // history was downloaded { ArrayInitialize(ZZ,0.0); ArrayInitialize(HH,0.0); ArrayInitialize(LL,0.0); } if (counted_bars==0) { limit=Bars-Depth; downloadhistory=true; } if (counted_bars>0) { while (counterZ=0;i--) { ZZ[i]=0.0; LL[i]=0.0; HH[i]=0.0; } } for(shift=limit; shift>=0; shift--) { val=Low[iLowest(NULL,0,MODE_LOW,Depth,shift)]; if(val==lastlow) val=0.0; else { lastlow=val; if((Low[shift]-val)>(Deviation*Point)) val=0.0; else { for(back=1; back<=Backstep; back++) { res=LL[shift+back]; if((res!=0)&&(res>val)) LL[shift+back]=0.0; } } } if (Low[shift]==val) LL[shift]=val; else LL[shift]=0.0; //--- high val=High[iHighest(NULL,0,MODE_HIGH,Depth,shift)]; if(val==lasthigh) val=0.0; else { lasthigh=val; if((val-High[shift])>(Deviation*Point)) val=0.0; else { for(back=1; back<=Backstep; back++) { res=HH[shift+back]; if((res!=0)&&(res=0;shift--) { res=0.0; switch(whatlookfor) { case 0: // look for peak or lawn if (lastlow==0 && lasthigh==0) { if (HH[shift]!=0) { lasthigh=High[shift]; lasthighpos=shift; whatlookfor=-1; ZZ[shift]=lasthigh; res=1; } if (LL[shift]!=0) { lastlow=Low[shift]; lastlowpos=shift; whatlookfor=1; ZZ[shift]=lastlow; res=1; } } break; case 1: // look for peak if (LL[shift]!=0.0 && LL[shift]lasthigh && LL[shift]==0.0) { ZZ[lasthighpos]=0.0; lasthighpos=shift; lasthigh=HH[shift]; ZZ[shift]=lasthigh; } if (LL[shift]!=0.0 && HH[shift]==0.0) { lastlow=LL[shift]; lastlowpos=shift; ZZ[shift]=lastlow; whatlookfor=1; } break; default: return; } } DeleteSpiral(); DrawSpiral(); CheckSpiral(); return(0); } //------------------------------------------------------------------ void CheckSpiral() { string name[]; bool check[]; int cross=0, near=0, j, s, i, n=ObjectSelect(0, OBJ_TREND, FX5_Spiral, name); // взяли все отрезки datetime dt1, dt2, dtmin=Time[0]; double pr1, pr2, pr; // самую дальнюю спираль for (i=0; i=High[i]){ ch=ZZ[i]; ih=i; if (cl<0) continue; for (j=il; j<=ih; j++) { if (dtmin>Time[ih]) stop=true; pr=ch+(cl-ch)*(ih-j)/(ih-il); for (s=0; s=pr2 && dt1<=Time[j] && dt2>=Time[j]) { if (!check[s]) cross++; check[s]=true; ObjectSet(name[s], OBJPROP_COLOR, Orange); ObjectSet(name[s], OBJPROP_WIDTH, 3); if (((pr1<=ZZ[i]+epsY*Point && pr1>=ZZ[i]-epsY*Point) || (pr2<=ZZ[i]+epsY*Point && pr2>=ZZ[i]-epsY*Point) || (pr1>=ZZ[i]+epsY*Point && pr2<=ZZ[i]-epsY*Point)) && ((dt1<=Time[i-epsX] && dt1>=Time[i+epsX]) || (dt2<=Time[i-epsX] && dt2>=Time[i+epsX])|| (dt1<=Time[i-epsX] && dt2>=Time[i+epsX]))){ near++; ObjectSet(name[s], OBJPROP_COLOR, Red); ObjectSet(name[s], OBJPROP_WIDTH, 3); } }}}} else if (ZZ[i]<=Low[i]) { cl=ZZ[i]; il=i; if (ch<0) continue; for (j=ih; j<=il; j++) { if (dtmin>Time[il]) stop=true; pr=cl+(ch-cl)*(il-j)/(il-ih); for (s=0; s=pr2 && dt1<=Time[j] && dt2>=Time[j]) { if (!check[s]) cross++; check[s]=true; ObjectSet(name[s], OBJPROP_COLOR, Orange); ObjectSet(name[s], OBJPROP_WIDTH, 3); if (((pr1<=ZZ[i]+epsY*Point && pr1>=ZZ[i]-epsY*Point) || (pr2<=ZZ[i]+epsY*Point && pr2>=ZZ[i]-epsY*Point) || (pr1>=ZZ[i]+epsY*Point && pr2<=ZZ[i]-epsY*Point))&& ((dt1<=Time[i-epsX] && dt1>=Time[i+epsX]) || (dt2<=Time[i-epsX] && dt2>=Time[i+epsX])|| (dt1<=Time[i-epsX] && dt2>=Time[i+epsX]))){ near++; ObjectSet(name[s], OBJPROP_COLOR, Red); ObjectSet(name[s], OBJPROP_WIDTH, 3); } }}}} } Print ("Найдено Пересечений: "+cross); Print ("Найдено вблизи вершин: "+near); } //+------------------------------------------------------------------+ void DrawSpiral() { // In polar coordinates the basic spiral equation is: // r = a * e ^ (Theta * cot Alpah) // for golden spiral: cot Alpha = 2/pi * ln(phi) double squareTime_1 = ObjectGet(FX5_Square, OBJPROP_TIME1); double squareTime_2 = ObjectGet(FX5_Square, OBJPROP_TIME2); double squarePrice_1 = ObjectGet(FX5_Square, OBJPROP_PRICE1); //---- int squareShift_1 = iBarShift(NULL, 0, squareTime_1, false); int squareShift_2 = iBarShift(NULL, 0, squareTime_2, false); //---- double r0 = MathAbs(squareShift_2 - squareShift_1); double a = 0; double x0 = squareShift_1; double y0 = squarePrice_1; //---- double cotAlpha = (1/(2 * goldenSpiralCycle *pi)) * MathLog(phi); double x1 = 0; double y1 = 0; for(int i = 0; i < 1000; i++) { double Theta = a * pi / 4; double r = r0 * MathExp(Theta * cotAlpha); //---- if (clockWiseSpiral == false) Theta = -Theta; //---- double x2 = r * MathCos(Theta); double y2 = r * MathSin(Theta); a += accurity; //---- string label=FX5_Spiral+i; DrawLine(x1, y1, x2, y2, label); //---- x1 = x2; y1 = y2; } } //+------------------------------------------------------------------+ void DrawLine(double x1, double y1, double x2, double y2, string label) { double squareTime_1 = ObjectGet(FX5_Square, OBJPROP_TIME1); double squareTime_2 = ObjectGet(FX5_Square, OBJPROP_TIME2); double squarePrice_1 = ObjectGet(FX5_Square, OBJPROP_PRICE1); double squarePrice_2 = ObjectGet(FX5_Square, OBJPROP_PRICE2); //---- int squareShift_1 = iBarShift(NULL, 0, squareTime_1, false); int squareShift_2 = iBarShift(NULL, 0, squareTime_2, false); double scale=((squarePrice_2-squarePrice_1)/Point)/(squareShift_2-squareShift_1); scale = MathAbs(scale); //---- int timeShift1 = squareShift_1 + MathRound(x1); int timeShift2 = squareShift_1 + MathRound(x2); //---- double price1 = squarePrice_1 + NormalizeDouble(y1* scale * Point, Digits); double price2 = squarePrice_1 + NormalizeDouble(y2* scale * Point, Digits); //---- if((x2 >= 0 && y2 >= 0) || (x2 <= 0 && y2 <= 0)) color lineColor=spiralColor1; else lineColor = spiralColor2; ObjectDelete(label); ObjectCreate(label, OBJ_TREND, 0, GetTime(timeShift1), price1, GetTime(timeShift2), price2, 0, 0); ObjectSet(label, OBJPROP_RAY, 0); ObjectSet(label, OBJPROP_COLOR, lineColor); } //+------------------------------------------------------------------+ datetime GetTime(int timeShift) { if(timeShift >= 0) return(Time[timeShift]); datetime timeFrame = Time[0] - Time[1]; datetime time = Time[0] - timeFrame * timeShift; return(time); } //+------------------------------------------------------------------+ void CreateSquare() { double priceRange = WindowPriceMax(0) - WindowPriceMin(0); double barsCount = WindowBarsPerChart(); // double barsCount = 133; //Square scale double chartScale = (priceRange / Point) / barsCount; //---- int x1 = 10000; int x2 = 10000 + radius; double y1 = High[x1]; double y2 = y1 + 20 * Point * chartScale; //---- string label = FX5_Square; ObjectDelete(label); ObjectCreate(label, OBJ_RECTANGLE, 0, Time[x1], y1, Time[x2], y2, 0, 0); ObjectSet(label, OBJPROP_RAY, 0); ObjectSet(label, OBJPROP_COLOR, spiralColor1); } //+------------------------------------------------------------------+ void DeleteSpiral() { for(int i = ObjectsTotal() - 1; i >= 0; i--) { string label = ObjectName(i); if(StringSubstr(label, 0, 12) != FX5_Spiral) continue; ObjectDelete(label); } } //+------------------------------------------------------------------+ int ObjectSelect(int wnd, int type, string pref, string &name[]) { string st, names[]; int i, k, n=ObjectsTotal(); ArrayResize(names, n); for (i=0; i=0) if (ObjectFind(st)!=wnd) continue; if (type>=0) if (ObjectType(st)!=type) continue; if (pref!="") if (StringSubstr(st, 0, StringLen(pref))!=pref) continue; names[k]=st; k++; } ArrayResize(name, k); for (i=0; i