//+------------------------------------------------------------------+ //| Divergency.mq4 | //| Copyright © Trofimov, 2008 | //+------------------------------------------------------------------+ #property copyright "Copyright © Trofimov, 2008" #property link "" #property indicator_separate_window #property indicator_buffers 4 #property indicator_color1 DarkSlateBlue #property indicator_width1 2 #property indicator_color2 Red #property indicator_width2 2 #property indicator_color3 FireBrick #property indicator_width3 1 #property indicator_color4 DarkGreen #property indicator_width4 1 #property indicator_maximum 1 #property indicator_minimum -1 extern double Delta=0.002; // - ìèíèìàëüíîå ðàññòîÿíèå ìåæäó ìèíèìóìîì è ìàêñèìóìîì int ExtremumPoint=3; // - êîëè÷åñòâî òî÷åê ïî êîòîðûì îïðåäåëÿþòñÿ ýêñòðåìóìû. Ìîæåò áûòü ëþáûì íå÷¸òíûì çíà÷åíèåì áîëüøå åäèíèöû (Íàïðèìåð: 3,5,7,9....) int Buffer=500; // - ðàçìåð áóôåðà ìàññèâà Stochastic[] int CurBuffer; // - òåêóùèé (ïîñëåäíèé çàïîëíåííûé) áóôåðíûé èíäåêñ ìàññèâà Stochastic[] double Stochastic[]; int UpStochIdx[2]; // - ìàññèâ, ñîäåðæàùèé áóôåðíûå èíäåêñû òð¸õ ïîñëåäíèõ ìàêñèìóìîâ int DnStochIdx[2]; // - ìàññèâ, ñîäåðæàùèé áóôåðíûå èíäåêñû òð¸õ ïîñëåäíèõ ìèíèìóìîâ int CurrentCandle; datetime LastTime; //---- Ìàññèâ äàííûõ èíäèêàòîðà double StochBuffer[]; double EndLimit[]; double StochUp[],StochDn[]; //+------------------------------------------------------------------+ int init() { //if(Buffer==0) Buffer=Bars; ArrayResize(Stochastic, Buffer); IndicatorBuffers(4); //---- ïàðàìåòðû ðèñîâàíèÿ (óñòàíîâêà íà÷àëüíîãî áàðà) SetIndexDrawBegin(0,Buffer); //---- 2 ðàñïðåäåëåííûõ áóôåðà èíäèêàòîðà SetIndexBuffer(0,StochBuffer); SetIndexBuffer(1,EndLimit); SetIndexBuffer(2,StochUp); SetIndexBuffer(3,StochDn); //---- èìÿ èíäèêàòîðà è ïîäñêàçêè äëÿ ëèíèé IndicatorShortName("DivMACD("+DoubleToStr(Delta,3)+")"); SetIndexLabel(0,"Divergency"); SetIndexLabel(1,"Limit"); SetIndexLabel(2,"Top"); SetIndexLabel(3,"Low"); //--- ñòèëü îòðèñîâêè SetIndexStyle(0, DRAW_HISTOGRAM); SetIndexStyle(1, DRAW_HISTOGRAM); SetIndexStyle(2, DRAW_ARROW); SetIndexStyle(3, DRAW_ARROW); SetIndexArrow(2, 108); SetIndexArrow(3, 108); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { static int OldUpStochIdx,OldDnStochIdx; int limit; // Ïðîïóùåííûå áàðû int counted_bars=IndicatorCounted(); //---- îáõîäèì âîçìîæíûå îøèáêè if(counted_bars<0) return(-1); //---- íîâûå áàðû íå ïîÿâèëèñü è ïîýòîìó íè÷åãî ðèñîâàòü íå íóæíî limit=Bars-counted_bars-1; //---- îñíîâíîé öèêë for(int i=limit; i>=0; i--) { CurrentCandle=i+1;//-ýòî ïîëíîñòüþ ñôîðìèðîâàâøàÿñÿ ñâå÷à if(LastTime!=iTime(NULL,0,CurrentCandle)) { AddStochastic(); LastTime=iTime(NULL,0,CurrentCandle); //Èíäèêàòîð ïåðåñå÷åíèÿ ãðàíèö 20/80 //EndLimit[i]=0; if(OldUpStochIdx!=UpStochIdx[0]) { if(Stochastic[UpStochIdx[0]]>80) { EndLimit[i]=-0.5; OldUpStochIdx=UpStochIdx[0]; } } if(OldDnStochIdx!=DnStochIdx[0]) { if(Stochastic[DnStochIdx[0]]<20) { EndLimit[i]=0.5; OldDnStochIdx=DnStochIdx[0]; } } //Èíäèêàòîð äèâåðãåíöèè //StochBuffer[i]=0; if(VectorStochastic(true)<0 && VectorPrice(true)>0) { if(GetIndexNormal(UpStochIdx[0])<GetIndexNormal(DnStochIdx[0])) {//åñëè ïîñëåäíèé ìèíèìóì ñòàðåå ïîñëåäíåãî ìàêñèìóìà StochBuffer[i]=-1; } } if(VectorStochastic(false)>0 && VectorPrice(false)<0) { if(GetIndexNormal(UpStochIdx[0])>GetIndexNormal(DnStochIdx[0])) {//åñëè ïîñëåäíèé ìàêñèìóì ñòàðåå ïîñëåäíåãî ìèíèìóìà StochBuffer[i]=1; } } //Print("===== ",TimeToStr(LastTime)," ====="); } } return(0); } //+------------------------------------------------------------------+ int AddStochastic() { //Äîáàâëÿåò íîâîå çíà÷åíèå ñòîõàñòèêà â ìàññèâ if(CurBuffer==0) CurBuffer=Buffer-1; else CurBuffer--; Stochastic[CurBuffer]=iMACD(NULL,0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, CurrentCandle); //Stochastic[CurBuffer]=iStochastic(NULL,0,5,3,3,MODE_EMA,0,MODE_MAIN,CurrentCandle); //Ïðîâåðêà íà âîçíèêíîâåíèå ýêñòðåìóìà int countUp, countDn; int idxTop=(ExtremumPoint-1)/2; // - íîðìàëüíûé èíäåêñ âåðøèíû for (int i = idxTop-1; i >= 0 ; i--) { //Öûêë íîðìàëüíîãî èíäåêñà if(Stochastic[GetIndexBuffer(i)]<Stochastic[GetIndexBuffer(i+1)] && Stochastic[GetIndexBuffer(idxTop+(idxTop-i))]<Stochastic[GetIndexBuffer(idxTop+(idxTop-i)-1)]) { countUp++; } if(Stochastic[GetIndexBuffer(i)]>Stochastic[GetIndexBuffer(i+1)] && Stochastic[GetIndexBuffer(idxTop+(idxTop-i))]>Stochastic[GetIndexBuffer(idxTop+(idxTop-i)-1)]) { countDn++; } } //Next i if(countUp==idxTop) { //âåðøèíà îêàçàëàñü ìàêñèìóìîì if(GetIndexNormal(DnStochIdx[0])<GetIndexNormal(UpStochIdx[0])) { //Åñëè ïðåäûäóùèì ñòîèò ìèíèìóì if(Stochastic[GetIndexBuffer(idxTop)]-Stochastic[DnStochIdx[0]]>Delta){ //Åñëè ìåæäó ïðåäûäóùèì ìèíèìóìîì è ïðåäïîëîæèòåëüíûì ìàêñèìóìîì ðàñòîÿíèå ïî âåðòèêàëè áîëüøå Delta UpStochIdx[2]=UpStochIdx[1]; UpStochIdx[1]=UpStochIdx[0]; UpStochIdx[0]=GetIndexBuffer(idxTop); StochUp[CurrentCandle-1]=Stochastic[UpStochIdx[0]]; } } else { //Åñëè ïðåäûäóùèì ñòîèò ìàêñèìóì if(Stochastic[UpStochIdx[0]]<Stochastic[GetIndexBuffer(idxTop)]) { //åñëè ïðåäûäóùèé ìàêñèìóì áûë ìåíüøå íàñòîÿùåãî StochUp[CurrentCandle-2+GetIndexNormal(UpStochIdx[0])]=EMPTY_VALUE; //StochUp[CurrentCandle-1+idxTop]=Stochastic[GetIndexBuffer(idxTop)]; StochUp[CurrentCandle-1]=Stochastic[GetIndexBuffer(idxTop)]; UpStochIdx[0]=GetIndexBuffer(idxTop); } } } else if(countDn==idxTop) { //âåðøèíà îêàçàëàñü ìèíèìóìîì if(GetIndexNormal(UpStochIdx[0])<GetIndexNormal(DnStochIdx[0])) { //Åñëè ïðåäûäóùèì ñòîèò ìàêñèìóì if(Stochastic[UpStochIdx[0]]-Stochastic[GetIndexBuffer(idxTop)]>Delta){ //Åñëè ìåæäó ïðåäûäóùèì ìàêñèñóìîì è ïðåäïîëîæèòåëüíûì ìèíèìóìîì ðàñòîÿíèå ïî âåðòèêàëè áîëüøå Delta DnStochIdx[2]=DnStochIdx[1]; DnStochIdx[1]=DnStochIdx[0]; DnStochIdx[0]=GetIndexBuffer(idxTop); StochDn[CurrentCandle-1]=Stochastic[DnStochIdx[0]]; } } else { //Åñëè ïðåäûäóùèì ñòîèò ìèíèìóì if(Stochastic[DnStochIdx[0]]>Stochastic[GetIndexBuffer(idxTop)]) { //åñëè ïðåäûäóùèé ìèíèìóì áûë áîëüøå íàñòîÿùåãî StochDn[CurrentCandle-2+GetIndexNormal(DnStochIdx[0])]=EMPTY_VALUE; //StochDn[CurrentCandle-1+idxTop]=Stochastic[GetIndexBuffer(idxTop)]; StochDn[CurrentCandle-1]=Stochastic[GetIndexBuffer(idxTop)]; DnStochIdx[0]=GetIndexBuffer(idxTop); } } } return(0); } //+------------------------------------------------------------------+ int GetIndexBuffer(int Idx) { //âîçâðàùàåò áóôåðíûé èíäåêñ ìàññèâà, ãäå Idx - íîðìàëüíûé èíäåêñ if(Idx>Buffer-1) { Print("Íåäîïóñòèìîå çíà÷åíèå èíäåêñà äëÿ ìàññèâà"); return(-1); } int retIndex=CurBuffer+Idx; if(retIndex>Buffer-1) retIndex=retIndex-Buffer; return(retIndex); } //+------------------------------------------------------------------+ int GetIndexNormal(int IdxBuf) { //âîçâðàùàåò íîðìàëüíûé èíäåêñ, ãäå IdxBuf - áóôåðíûé èíäåêñ ìàññèâà if(IdxBuf>Buffer-1) { Print("Íåäîïóñòèìîå çíà÷åíèå èíäåêñà äëÿ ìàññèâà"); return(-1); } int retIndex=IdxBuf-CurBuffer; if(retIndex<0) retIndex=retIndex+Buffer; return(retIndex); } //+------------------------------------------------------------------+ int VectorStochastic(bool MaxMin) { //âîçâðàùàåò íàïðàâëåíèå òðåíäîâîé ëèíèè, ïðîâåä¸ííîé ÷åðåç âåðøèíû ñòîõàñòèêà: //1 - ââåðõ, -1 - âíèç, 0 - ãîðèçîíòàëüíî //MaxMin - òèïû àíàëèçèðóåìûõ âåðøèí: true - ìàêñèìóìû, false - ìèíèìóìû if(MaxMin) { //Print("Stochastic[UpStochIdx[0]]="+Stochastic[UpStochIdx[0]],", Stochastic[UpStochIdx[1]]="+Stochastic[UpStochIdx[1]]); if(Stochastic[UpStochIdx[0]]>Stochastic[UpStochIdx[1]]) { //Print("Stochastic[0]="+Stochastic[UpStochIdx[0]],", Stochastic[1]="+Stochastic[UpStochIdx[1]],", return 1"); return(1); } else if(Stochastic[UpStochIdx[0]]<Stochastic[UpStochIdx[1]]) { //Print("Stochastic[0]="+Stochastic[UpStochIdx[0]],", Stochastic[1]="+Stochastic[UpStochIdx[1]],", return -1"); return(-1); } } else { //Print("Stochastic[DnStochIdx[0]]="+Stochastic[DnStochIdx[0]],", Stochastic[DnStochIdx[1]]="+Stochastic[DnStochIdx[1]]); if(Stochastic[DnStochIdx[0]]>Stochastic[DnStochIdx[1]]) { //Print("Stochastic[0]="+Stochastic[DnStochIdx[0]],", Stochastic[1]="+Stochastic[DnStochIdx[1]],", return 1"); return(1); } else if(Stochastic[DnStochIdx[0]]<Stochastic[DnStochIdx[1]]) { //Print("Stochastic[0]="+Stochastic[DnStochIdx[0]],", Stochastic[1]="+Stochastic[DnStochIdx[1]],", return -1"); return(-1); } } return(0); } //+------------------------------------------------------------------+ int VectorPrice(bool MaxMin) { //âîçâðàùàåò íàïðàâëåíèå òðåíäîâîé ëèíèè, ïðîâåä¸ííîé ÷åðåç ïèêè ñâå÷åé òåêóùåãî ãðàôèêà: //1 - ââåðõ, -1 - âíèç, 0 - ãîðèçîíòàëüíî //MaxMin - òèïû àíàëèçèðóåìûõ ïèêîâ: true - High, false - Low int Extremum0,Extremum1; if(MaxMin) { Extremum0=iHighest(NULL,0,MODE_HIGH,GetIndexNormal(DnStochIdx[0]),CurrentCandle); Extremum1=iHighest(NULL,0,MODE_HIGH,GetIndexNormal(DnStochIdx[1])-GetIndexNormal(DnStochIdx[0]),GetIndexNormal(DnStochIdx[0])+CurrentCandle); //Print("High[Extremum0]=",High[Extremum0],", High[Extremum1]=",High[Extremum1]); if(High[Extremum0]>High[Extremum1]) { //Print("High[0]=",High[Extremum0],", High[1]=",High[Extremum1],", return 1"); return(1); } else { //Print("High[0]=",High[Extremum0],", High[1]=",High[Extremum1],", return -1"); return(-1); } } else { Extremum0=iLowest(NULL,0,MODE_LOW,GetIndexNormal(UpStochIdx[0]),CurrentCandle); Extremum1=iLowest(NULL,0,MODE_LOW,GetIndexNormal(UpStochIdx[1])-GetIndexNormal(UpStochIdx[0]),GetIndexNormal(UpStochIdx[0])+CurrentCandle); //Print("Low[Extremum0]=",Low[Extremum0],", Low[Extremum1]=",Low[Extremum1]); if(Low[Extremum0]>Low[Extremum1]) { //Print("Low[0]=",Low[Extremum0],", Low[1]=",Low[Extremum1],", return 1"); return(1); } else { //Print("Low[0]=",Low[Extremum0],", Low[1]=",Low[Extremum1],", return -1"); return(-1); } } return(0); } //+------------------------------------------------------------------+
Sample
Analysis
Market Information Used:
Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar
Indicator Curves created:
Implements a curve of type DRAW_HISTOGRAM
Implements a curve of type DRAW_ARROW
Indicators Used:
MACD Histogram
Custom Indicators Used:
Order Management characteristics:
Other Features: