乐于分享
好东西不私藏

全网最稳!全自动多周期智能通道指标EA源码

全网最稳!全自动多周期智能通道指标EA源码
大家好,我是EA侠。
不知道大家有没有发现一件事情,市面上普通的通道指标,都是单周期画线、乱画线、滞后严重,根本没法用。
所以侠哥今天给大家带来一个真正的硬核神器,也是我自己一直在用的:全自动多周期智能通道指标

它不是那种花里胡哨的垃圾指标,它的底层是最小二乘法加权算法,不用你手动画线、不用你调参数、不用你找高低点,全程全自动识别有效趋势通道

它最大的核心亮点,就是支持九周期全周期共振扫描

从一分钟、五分钟、十五分钟,一直到小时线、日线、周线、月线,全周期同时运算!大周期帮你定整体趋势方向,小周期帮你抓精准入场点位,多周期通道重合,就是高概率稳定行情

而且它自带专业级多重过滤,彻底杜绝无效通道、杂波行情。

自带黄金分割过滤、通道宽度过滤、极值高低点过滤,太窄、太宽、不稳定的垃圾通道,它直接帮你过滤掉,只留给你高胜率有效通道

趋势行情,你可以开启极值模式,通道紧贴高低点,完美跟随趋势走完全程;震荡行情,用等宽通道模式,上轨压力高抛、下轨支撑低吸,买卖位置一目了然。

可视化做得也特别舒服,自动上色、自动填充通道区间、自动画趋势辅助线,整张盘面干净清晰,新手一眼看懂支撑压力,老手直接用来共振抓拐点

源码侠哥放下面了,需要你们解析一下,不会的可以问侠哥:wzc10106
#property strict#property copyright ""classCDebuggerFix{ } ExtDebuggerFix;#property  indicator_chart_window#property  indicator_buffers 2//---- indicator parametersextern int     StartBar    =  0;         // from what point the data analysis begins, 0 - from the current one.extern int     BarAnalys   =  400;       // the number of bars for analysis in each period up to and including daytime. Not more than 2000!extern double  k_width     =  4;         // channel width factorextern int     accuracy    =  50;        // accuracy of modeling 1-no accuracy, if BarAnalys-max. accuracy. The higher the accuracy, the slower the indicatorextern double  Filter      =  0.55;      // filter the depth of forming a new channel, it is advisable to use the range 0.382-0.618extern double  MinWidth    =  0;         // the minimum average weighted channel width in points, (with smaller width channels will not be formed)extern double  MaxWidth    =  10000;     // the maximum average weighted channel width in points, (with a wider width channels will not be formed)extern bool    Ray         =  true;      // a sign of continuation of the channel; true - ray, false - segmentextern bool    MaxMin      =  true;      // To build a channel taking into account extreme extremes?                                         // -true - Yes. For the construction to pass through extreme extremes, the width coefficient k_width should be large, for example 100                                         // -false - No. In this case, the upper and lower boundary of the channel is equidistant from the central axis of the channel (the center of the "mass")extern bool    color_fill  =  true;      // Fill channels?//---- indicator buffersdouble     Channels[1000];double     Wid[];double     Vertical[];double     Width[2000];double     WidthU[2000];double     WidthD[2000];double     ChannelR[2000];double     ChannelL[2000];double     Channel[20][9];int preBars=0;int p[9]={43200,10080,1440,240,60,30,15,5,1};int FinishL;int tick=0;int bar=0;int b=0;int key=0;double sumPlus=0;double sumMinus=0;double yOptR,yOptL;int prexL=0;int prexR=0;double ma=0;int  prevxR=-5;int  prevp=0;int prevper=-5;double sum1=0;double sum2=0;double curdeltaMax=-10000;double curdeltaMin=10000;int Start=0;//+------------------------------------------------------------------+//|                                                                  |//+------------------------------------------------------------------+void OnDeinit(const int reason)  {   Comment("");   ObjectDelete("channels_start");   for(int i=0;i<20;i++)     {      ObjectDelete("LineChannel9_"+DoubleToStr(i,0));      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" UP");      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" DOWN");      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" TRIUP");      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" TRIDown");      ObjectDelete("Vertical_9_"+DoubleToStr(i,0));     }  }//+------------------------------------------------------------------+//| Custom indicator initialization function                         |//+------------------------------------------------------------------+int OnInit()  {//---- drawing settings   IndicatorDigits(Digits+1);//---- indicator buffers mapping   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);   SetIndexStyle(0,DRAW_NONE);   SetIndexStyle(1,DRAW_NONE);   IndicatorDigits(Digits+1);//---- indicator buffers mapping   SetIndexBuffer(0,Wid);   SetIndexBuffer(1,Vertical);//---- indicator buffers mapping// SetIndexBuffer(0,Canals);//   IndicatorDigits(20);//---- initialization done   return(INIT_SUCCEEDED);  }//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int OnCalculate(const int rates_total,                const int prev_calculated,                const datetime &time[],                const double &open[],                const double &high[],                const double &low[],                const double &close[],                const long &tick_volume[],                const long &volume[],                const int &spread[])  {//LoadHist();   int i;   if(StartBar!=0 && Start==0) Start=StartBar;   int j=AllChannels();   Channels[0]=j;                                       //Number of generated channels   if(j>0)     {      for(i=0; i<j; i++)        {         Channels[7*i+1] = Channel[i][0];                //Width         Channels[7*i+2] = Channel[i][1];                //The current i-left channel boundary         Channels[7*i+3] = Channel[i][2];                //Channel formation period         Channels[7*i+4] = Channel[i][3];                //yOptR         Channels[7*i+5] = Channel[i][4];                //yOptL         Channels[7*i+6] = Channel[i][5]/Point;          //increment in points per bar every minute or channel angle, positive-up, negative-down         Channels[7*i+7] = Channel[i][6];                //length in current period bars         Channels[7*i+8] = Channel[i][7];                //Width Up         Channels[7*i+9] = Channel[i][8];                //Width Doun        }      BildCanals(j);     }   return(rates_total);  }//+------------------------------------------------------------------+//|                                                                  |//+------------------------------------------------------------------+void OnChartEvent(const int id,                  const long &lparam,                  const double &dparam,                  const string &sparam)  {   double y;   int j,i;   int      window=0;   datetime ttt;   if(id==CHARTEVENT_KEYDOWN) key=(int)lparam;   if(id==CHARTEVENT_MOUSE_MOVE && key==17)// pressed the CTRL key     {      ChartXYToTimePrice(0,(int)lparam,(int)dparam,window,ttt,y);      if(ttt!=0) Start=iBarShift(NULL,0,ttt,false);      j=AllChannels();      Channels[0]=j;                                     //Number of generated channels      if(j>0)        {         for(i=0; i<j; i++)           {            Channels[7*i+1] = Channel[i][0];                //Width            Channels[7*i+2] = Channel[i][1];                //The current i-left channel boundary            Channels[7*i+3] = Channel[i][2];                //Channel formation period            Channels[7*i+4] = Channel[i][3];                //yOptR            Channels[7*i+5] = Channel[i][4];                //yOptL            Channels[7*i+6] = Channel[i][5]/Point;          //increment in points per bar every minute or channel angle, positive-up, negative-down            Channels[7*i+7] = Channel[i][6];                //length in current period bars            Channels[7*i+8] = Channel[i][7];                //Width Up            Channels[7*i+9] = Channel[i][8];                //Width Doun           }         BildCanals(j);        }     }  }//+------------------------------------------------------------------+///////////////////////////// Functions/////////////////////////////////+------------------------------------------------------------------+int BildCanals(int j)//Data about the channels are in the array Channel[20][7]  {   string name;   datetime x1,x2;   double y1,y2;   int i;   int  color_i2[40]= //     {      0x339966,0xFF33CC,0x3399FF,0xFF9920,0x993333,0xFF0066,0x66CCFF,0x9933CC,0x336600,0x006699,      0xCC0099,0x33CCCC,0x6633FF,0x00FF66,0xCC99FF,0x3333FF,0x666633,0xCC66CC,0x00CCFF,0x996666,      0xFF6666,0x0000FF,0xCC6666,0x006600,0x660099,0x66FF66,0xFFCC00,0x6666FF,0xFFFF33,0xCC0000,      0x33FFFF,0xCC33FF,0x33FF33,0x9999FF,0x996600,0x333399,0x99CC99,0x0066CC,0xCC9900,0x00CCCC    };   int color_i[40]=    {      0x194C33,0x7F1966,0x14C97F,0x7F4C10,0x4C1919,0x7F0033,0x33667F,0x4C1966,0x193300,0x00334C,      0x66004C,0x196666,0x33197F,0x007F33,0x664C7F,0x19197F,0x333319,0x663366,0x00667F,0x4C3333,      0x7F3333,0x00007F,0x663333,0x003300,0x33004C,0x337F33,0x7F6600,0x33337F,0x7F7F19,0x660000,      0x197F7F,0x66197F,0x197F19,0x4C4C7F,0x4C3300,0x1914C9,0x466C4C,0x003366,0x664C00,0x006666    };   for(i=j;i<20;i++)     {      ObjectDelete("LineChannel9_"+DoubleToStr(i,0));      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" UP");      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" DOWN");      ObjectDelete("Vertical_9_"+DoubleToStr(i,0));      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" TRIUP");      ObjectDelete("LineChannel9_"+DoubleToStr(i,0)+" TRIDown");      Channel[i][2]=0;      Channel[i][1]=0;      Channel[i][0]=0;     }// Comment("Number of channels = ",j);// string comm="Number of channels = ";// comm=comm+(string)j;// for(i=0; i<j; i++)//   { comm=comm+"\n"+"Channel № "+DoubleToStr((i+1),0)+" : Width - "+DoubleToStr(Channel[i][0],0)+", channel length -  "+DoubleToStr(Channel[i][6],0)+" bars for the period "+DoubleToStr(Channel[i][2],0);}// Comment(comm);   for(i=0; i<j; i++)     {      x1 = iTime(NULL,0,Start);      y1 = Channel[i][3];      y2 = Channel[i][4];      if(iTime(NULL,0,(Bars-1))<=iTime(NULL,(int)Channel[i][2],(int)Channel[i][1]))        {         x2=iTime(NULL,(int)Channel[i][2],(int)Channel[i][1]);        }      else        {         x2=iTime(NULL,0,(Bars-1));         if(Channel[i][6]!=0) y2=y1-((iBarShift(NULL,(int)Channel[i][2],x2,FALSE)-iBarShift(NULL,(int)Channel[i][2],x1,FALSE))/Channel[i][6])*(y1-Channel[i][4]);        }      name="LineChannel9_"+DoubleToStr(i,0);      if(ObjectFind(name)==-1)        {         if(!ObjectCreate(name,OBJ_TREND,0,x2,y2,x1,y1)) Comment("Error 0 = ",GetLastError());         ObjectSet(name,OBJPROP_RAY,FALSE);         ObjectSet(name,OBJPROP_COLOR,color_i[i]);         ObjectSet(name,OBJPROP_STYLE,STYLE_DOT);         ObjectSet(name,OBJPROP_RAY,Ray);         if(MaxMin==true)            ObjectCreate(name+" UP",OBJ_TREND,0,x2,(y2+Point*Channel[i][7]),x1,(y1+Point*Channel[i][7]));         else            ObjectCreate(name+" UP",OBJ_TREND,0,x2,(y2+k_width*Point*Channel[i][0]),x1,(y1+k_width*Point*Channel[i][0]));         ObjectSet(name+" UP",OBJPROP_RAY,FALSE);         ObjectSet(name+" UP",OBJPROP_COLOR,color_i[i]);         ObjectSet(name+" UP",OBJPROP_STYLE,STYLE_DASH);         ObjectSet(name+" UP",OBJPROP_RAY,Ray);         if(MaxMin==true)            ObjectCreate(name+" DOWN",OBJ_TREND,0,x2,(y2+Point*Channel[i][8]),x1,(y1+Point*Channel[i][8]));         else            ObjectCreate(name+" DOWN",OBJ_TREND,0,x2,(y2-k_width*Point*Channel[i][0]),x1,(y1-k_width*Point*Channel[i][0]));         ObjectSet(name+" DOWN",OBJPROP_RAY,FALSE);         ObjectSet(name+" DOWN",OBJPROP_COLOR,color_i[i]);         ObjectSet(name+" DOWN",OBJPROP_STYLE,STYLE_DASH);         ObjectSet(name+" DOWN",OBJPROP_RAY,Ray);         if(color_fill==true)           {            ObjectCreate(name+" TRIUP",OBJ_TRIANGLE,0,x2,(y2+Point*Channel[i][7]),x1,(y1+Point*Channel[i][7]),x2,(y2+Point*Channel[i][8]));            ObjectSet(name+" TRIUP",OBJPROP_COLOR,color_i2[i]);            ObjectCreate(name+" TRIDown",OBJ_TRIANGLE,0,x1,(y1+Point*Channel[i][7]),x1,(y1+Point*Channel[i][8]),x2,(y2+Point*Channel[i][8]));            ObjectSet(name+" TRIDown",OBJPROP_COLOR,color_i2[i]);           }         if(!ObjectCreate("Vertical_9_"+DoubleToStr(i,0),OBJ_VLINE,0,x2,8)) Comment("Ошибка 0 = ",GetLastError());         ObjectSet("Vertical_9_"+DoubleToStr(i,0),OBJPROP_COLOR,color_i[i]);         ObjectSet("Vertical_9_"+DoubleToStr(i,0),OBJPROP_STYLE,STYLE_DOT);        }      else        {         if(!ObjectMove(name,0,x2,y2)) Comment("Ошибка 1 = ",GetLastError());         if(!ObjectMove(name,1,x1,y1)) Comment("Ошибка 2 = ",GetLastError());         if(MaxMin==true)           {            ObjectMove(name+" UP",0,x2,y2+Point*Channel[i][7]);            ObjectMove(name+" UP",1,x1,y1+Point*Channel[i][7]);            ObjectMove(name+" DOWN",0,x2,y2+Point*Channel[i][8]);            ObjectMove(name+" DOWN",1,x1,y1+Point*Channel[i][8]);            if(color_fill==true)              {               ObjectMove(name+" TRIUP",0,x2,(y2+Point*Channel[i][7]));               ObjectMove(name+" TRIUP",1,x1,(y1+Point*Channel[i][7]));               ObjectMove(name+" TRIUP",2,x2,(y2+Point*Channel[i][8]));               ObjectMove(name+" TRIDown",0,x1,(y1+Point*Channel[i][7]));               ObjectMove(name+" TRIDown",1,x1,(y1+Point*Channel[i][8]));               ObjectMove(name+" TRIDown",2,x2,(y2+Point*Channel[i][8]));              }           }         else           {            ObjectMove(name+" UP",0,x2,y2+k_width*Point*Channel[i][0]);            ObjectMove(name+" UP",1,x1,y1+k_width*Point*Channel[i][0]);            ObjectMove(name+" DOWN",0,x2,y2-k_width*Point*Channel[i][0]);            ObjectMove(name+" DOWN",1,x1,y1-k_width*Point*Channel[i][0]);           }        }     }   return(0);  }////////////////////////////////////////////////////////int AllChannels()  {   int i1=0,i2,i3,jj,sdv,err=0;   int k=0;   int i=0;   int lastper;   int St,Fin;   datetime S,F,prevS,CurStart;   int lastmin;   double lmin=1000000;   double premin=0;   lastper=9;   CurStart=iTime(NULL,Period(),Start);   if(Start==0) CurStart=iTime(NULL,1,0);   int l5=iBarShift(NULL,p[0],CurStart,FALSE)+BarAnalys;   if(iBars(NULL,p[0])<l5) l5=iBars(NULL,p[0])-1;   prevS=iTime(NULL,p[0],l5);   if(prevS==0) {err=GetLastError(); Print("Error iTime ",err," ",(iBarShift(NULL,p[0],CurStart,FALSE)));}   ArrayInitialize(Vertical,0);   ArrayInitialize(Wid,0);   for(jj=0;jj<lastper;jj++)     {      if(jj==8) // if the minute period         S = CurStart;      else S=iTime(NULL,p[jj+1],(iBarShift(NULL,p[jj+1],CurStart,FALSE)+BarAnalys));      F=prevS;      prevS=S;      St=iBarShift(NULL,p[jj],CurStart,FALSE);      Fin=iBarShift(NULL,p[jj],F,FALSE);      if(St==0 && Fin==0)  return(0);      sdv=(iBarShift(NULL,p[jj],S,FALSE))-St-7;      if(jj!=8) {ArrWidth(St,Fin,sdv,p[jj]); }      else  {ArrWidth(St,Fin,0,p[jj]);}      lastmin=Fin+1;      if(jj==0) lmin=10000000;      if(jj==0) premin=Width[Fin-St-1];      if(Fin>iBarShift(NULL,p[jj],S,FALSE))         for(i=Fin-1; i>(iBarShift(NULL,p[jj],S,FALSE))-1; i--)           {            int hhh=iBarShift(NULL,p[jj],S,FALSE);            if(iTime(NULL,0,Bars-1)<=iTime(NULL,p[jj],i))              {               i3=iBarShift(NULL,0,iTime(NULL,p[jj],i),FALSE);               for(i2=0;i2<=p[jj]/Period();i2++)                 {                  if((i3-i2)>=0) Wid[i3-i2]=Width[i-St];                  if(i!=St && Wid[i3-i2]==0)                    {                     printf("width for some reason is zero");                    }                 }              }            if(Width[i-St]<lmin) {lmin=Width[i-St];lastmin=i;}            if(i>St) if(Width[i-St]<=Width[i-St-1] && Width[i-St]<=Width[i-St+1])               if(lastmin==i)                 {                  if(Width[i-St]<premin*Filter && Width[i-St]>MinWidth && Width[i-St]<MaxWidth)                    {                     if(i1>0for(k=0; k<i1; k++)                       {                        if(Width[i-St]!=0if((Channel[k][0]/Width[i-St])<1.2 && (Channel[k][0]/Width[i-St])>0.8) i1=k;                       }                     if(iTime(NULL,0,Bars-1)<=iTime(NULL,p[jj],i)) Vertical[i3]=Width[i-St];                     Channel[i1][0]= Width[i-St];                                //Width Up                     Channel[i1][1]= i;                                          //The current i-left channel boundary                     Channel[i1][2]= p[jj];                                      //Period                     Channel[i1][3]= ChannelR[i-St];                             //yOptR                     Channel[i1][4]= ChannelL[i-St];                             //yOptL                     if((i-St)*p[jj]!=0                     Channel[i1][5]=(ChannelR[i-St]-ChannelL[i-St])/((i-St)*p[jj]);  //bar increment                     Channel[i1][6]=(i-St);                                      //length in bars                     Channel[i1][7]= WidthU[i-St];                               //Width Up                     Channel[i1][8]= WidthD[i-St];                               //Width Down                     premin=Width[i-St];                     i1++;                    }                 }           }     }   return(i1);  }//////////////////////////////////////////////////////////////////////double ArrWidth(int Start1,int Finish,int Sdvig,int per) // constructing an array of the width of the central line from Start1 to Finish  {   Width[0]=0;   if(Sdvig<0) Sdvig=0;   yOptR=iOpen(NULL,per,Start1);   int d,i1,i;   double dC,dR,dL;   int p1=0;   int lnz=Sdvig;   for(i=(1+Sdvig); i<(Finish-Start1); i++)     {      if(accuracy!=0) p1=(int)MathFloor((i-1)/accuracy);      i=i+p1;      Width[i]=MinChannel2(Start1,i+Start1,per);     // if(Width[i]<1) Print(per," ",Start1," ",i+Start1);      if(MaxMin==true)        {         if( k_width*Width[i]<curdeltaMax/Point) WidthU[i]=(curdeltaMax/Point+k_width*Width[i])/2else WidthU[i]=curdeltaMax/Point;         if(-k_width*Width[i]>curdeltaMin/Point) WidthD[i]=(curdeltaMin/Point-k_width*Width[i])/2else WidthD[i]=curdeltaMin/Point;        }      ChannelL[i]  = yOptL;      ChannelR[i]  = yOptR;      d=i-lnz;      if(d!=0)        {         dC=(Width[i]-Width[lnz])/d;         dR=(ChannelR[i]-ChannelR[lnz])/d;         dL=(ChannelL[i]-ChannelL[lnz])/d;        }      else {dC=0;dR=0; dL=0;}      if(d>1)         for(i1=1;i1<d;i1++)           {            Width[lnz+i1]=Width[lnz+i1-1]+dC;            ChannelL[lnz+i1]  = ChannelL[lnz+i1-1]+dL;            ChannelR[lnz+i1]  = ChannelR[lnz+i1-1]+dR;           }      lnz=i;     }   return(0);  }///////////////////////////////////////////////////////double MinChannel2(int xR,int xL,int per)  {   int n,p3,p2=xL-xR;   double j1,j2,j3,d;   p3=2*p2+1;   j1 = p3 + 1;   j2 = p3*(p3+1)/2;   j3 = p3*(p3+1)*(2*p3+1)/6;   if(prevxR!=xR || prevper!=per)     {      prevp=0;      sum1=0;      sum2=0;     }   for(n=prevp; n<=p2; n++)     {      sum2+=iHigh(NULL,per,n+xR)+iLow(NULL,per,n+xR);      if(iOpen(NULL,per,n+xR)>=iClose(NULL,per,n+xR))         sum1+=iHigh(NULL,per,n+xR)*2*n+iLow(NULL,per,n+xR)*(2*n+1);      else         sum1+=iLow(NULL,per,n+xR)*2*n+iHigh(NULL,per,n+xR)*(2*n+1);     }   prevxR=xR;   prevp=p2+1;   prevper=per;   d=(j2*sum2-j1*sum1)/(j2*j2-j1*j3);   yOptR = (sum1-j3*d)/j2;   yOptL = d*2*p2+yOptR;   return(SumPlus2(xL,xR,yOptR,yOptL,per)/(p2+1));  }///////////////////////////////////////////////////////double SumPlus2(int xL1,int xR1,double yR1,double yL1,int per)  {   double curLinePrice,curdelta,curdeltaH,curdeltaL,delta=0;   curdeltaMax=-100000;   curdeltaMin=100000;   int i = xR1;   if(xL1==xR1)return(0);   delta = (yL1-yR1)/(xL1-xR1);   curLinePrice=yR1;   sumPlus=0;   while(i<=xL1)     {      curdelta=iOpen(NULL,per,i)-curLinePrice;      curdeltaH = iHigh(NULL,per,i) - curLinePrice;      curdeltaL = iLow(NULL,per,i) - curLinePrice;      if(curdeltaMax<curdeltaH) curdeltaMax=curdeltaH;      if(curdeltaMin>curdeltaL) curdeltaMin=curdeltaL;      if(curdelta>0) sumPlus=sumPlus+curdelta;      curLinePrice=curLinePrice+delta;      i++;     }   return(sumPlus/Point);  }////////////////////////////////////////////////////////////////////////////////////void LoadHist()  {   int iPeriod[9];   iPeriod[0]=1;   iPeriod[1]=5;   iPeriod[2]=15;   iPeriod[3]=30;   iPeriod[4]=60;   iPeriod[5]=240;   iPeriod[6]=1440;   iPeriod[7]=10080;   iPeriod[8]=43200;   for(int iii=0;iii<9;iii++)     {      datetime open=iTime(Symbol(),iPeriod[iii],0);      int error=GetLastError();      while(error==4066)        {         Comment("Historical data was not uploaded for ",iPeriod[iii]," period, you need to reboot the indicator or go to another timeframe");         Sleep(10000);         open = iTime(Symbol(), iPeriod[iii], 0);         error=GetLastError();        }     }  }//+------------------------------------------------------------------+ 由于时间有限加上对源码的追溯做不到最终解释权,所以我们提供的源码EA仅仅只能用来做模拟测试使用,严格禁止商业使用和跑实盘!