//+-------------------------------------------------------------------------------------------------------------------+
//| kosma-2.02.mq4 |
//| pu6ka@mail.ru |
//+-------------------------------------------------------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 7
#property indicator_color1 Magenta
#property indicator_color4 Yellow
#property indicator_color5 Yellow
#property indicator_color6 Green
#property indicator_color7 Red
extern int fast = 12;
extern int slow = 26;
extern int sig = 9;
extern int k = 1; // êîýô.óìíîæåíèÿ ïàðàìåòðîâ OsMA
extern int n = 2; // êîë-âî áàðîâ ñïðàâà/ñëåâà íà÷èíàÿ ñ êîòîðîãî ñ÷èòàåòñÿ ïèê/âïàäèíà
extern bool drawDivergenceLines = true; // îòîáðàæàòü èëè íåò ëèíèè äèâåðãåíöèè, ñòðåëêè íà îñíîâíîì ãðàôèêå
int history=15000;
double OsMA[];
double bullishDivergence[];
double bearishDivergence[];
double peak[];
double trough[];
double bulliShift[];
double beariShift[];
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE,0,1);
SetIndexStyle(3,DRAW_ARROW);
SetIndexStyle(4,DRAW_ARROW);
SetIndexStyle(5,DRAW_ARROW);
SetIndexStyle(6,DRAW_ARROW);
//----
SetIndexBuffer(0, OsMA); // Áóôåð èíäèêàòîðà äëÿ ìàññèâà OsMA[]
SetIndexBuffer(1, bullishDivergence); // çàíîñÿòñÿ çíà÷åíèÿ äëÿ îòðàæåíèÿ ñòðåëêè "ââåðõ"
SetIndexBuffer(2, bearishDivergence); // çàíîñÿòñÿ çíà÷åíèÿ äëÿ îòðàæåíèÿ ñòðåëêè "âíèç"
SetIndexBuffer(3, peak); // çàíîñèì çíà÷åíèÿ èçãèáîâ íàâåðõó
SetIndexBuffer(4, trough); // çàíîñèì çíà÷åíèÿ èçãèáîâ ñíèçó
SetIndexBuffer(5, bulliShift); // çàíîñÿòñÿ çíà÷åíèÿ äëÿ îòðàæåíèÿ ñòðåëêè "ââåðõ" ñî ñìåùåíèåì
SetIndexBuffer(6, beariShift); // çàíîñÿòñÿ çíà÷åíèÿ äëÿ îòðàæåíèÿ ñòðåëêè "âíèç" ñî ñìåùåíèåì
//----
SetIndexArrow(5, 233); // Íàçíà÷åíèå çíà÷êà "ñòðåëêà ââåðõ" äëÿ bullishDivergence
SetIndexArrow(6, 234); // Íàçíà÷åíèå çíà÷êà "ñòðåëêà âíèç" äëÿ bearishDivergence
SetIndexArrow(3, 116); // Íàçíà÷åíèå çíà÷êà èçãèáîâ íàâåðõó
SetIndexArrow(4, 116); // Íàçíà÷åíèå çíà÷êà èçãèáîâ ñíèçó
//----
IndicatorDigits(Digits+2);
IndicatorShortName("kosma-2.02 ("+fast+","+slow+","+sig+")"+" k"+k+" n"+n);
return(0);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
int deinit()
{
for(int i=ObjectsTotal()-1; i>=0; i--)
{
string label=ObjectName(i);
if(StringSubstr(label,0,14)!="DivergenceLine")
continue;
ObjectDelete(label);
}
return(0);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
int start()
{
int countedBars = IndicatorCounted(); // Êîë-âî íåèçìåíåííûõ áàðîâ
if(countedBars < 0) countedBars = 0; // Îáíóëèì, åñëè çíà÷åíèå ìåíüøå 0.
CalculateIndicator(countedBars);
return(0);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
void CalculateIndicator(int countedBars)
{
int j=Bars-countedBars; // Èíäåêñ ïåðâîãî íåïîñ÷èòàííîãî áàðà
if(countedBars==0) j-=2*n+1;
for(int i=j; i>=0; i--)
{
CalculateOsMA(i);
CatchBullishDivergence(i+n);
CatchBearishDivergence(i+n);
}
}
//+-------------------------------------------------------------------------------------------------------------------+
//| Çàïîëíåíèå çíà÷åíèÿìè áóôåðíîãî ìàññèâà OsMA[] |
//+-------------------------------------------------------------------------------------------------------------------+
void CalculateOsMA(int i)
{
OsMA[i]=iOsMA(NULL,0,fast*k,slow*k,sig*k,PRICE_WEIGHTED,i);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| Äèâåðãåíöèÿ óêàçûâàþùàÿ ñòðåëêó "ââåðõ" |
//+-------------------------------------------------------------------------------------------------------------------+
void CatchBullishDivergence(int shift) // shift = i+n
{
int idTrough=IsIndicatorTrough(shift); // èíäåêñ ãîðáà, ïîëó÷àåì ïî ïåðåáîðó âëåâî îò íàéäåíîé âïàäèíû
if(idTrough < 0) return; // âïàäèíà îòñóòñòâóåò
int currentTrough = shift; // èíäåêñ ÿìû, ðàç äîøëè ñþäà, n-é áàð ñàìûé íèçêèé
int lastTrough = GetIndicatorLastTrough(idTrough); // Ïîëó÷èëè èíäåêñ ïðåäïîñëåäíåé âïàäèíû
// Åñëè òåê.ÿìà âûøå ïðåäûäóùåé è öåíà Low òåê.ÿìû íèæå öåíû Low ïðåäûäóùåé ÿìû èíäèêàòîðà - òàêîé äèâåð >
if(OsMA[currentTrough]>OsMA[lastTrough] && Low[currentTrough]<Low[lastTrough])
{
bullishDivergence[currentTrough]=OsMA[currentTrough]; // ïåðåäàåì çíà÷.OsMA â ìàññèâ ñî ñòðåëî÷íûì áóôåðîì
bulliShift[currentTrough-n]=OsMA[currentTrough]; // ïåðåäàåì çíà÷.OsMA â ìàññèâ ñî ñòðåëî÷íûì áóôåðîì
if(drawDivergenceLines) DrawArrowOnChart(currentTrough,1);
//trough[shift] = EMPTY_VALUE; // óáåðåì íàëîæåíèå íà îäèí èíäåêñ äâóõ çíà÷êîâ
if(drawDivergenceLines==true) // ïðîðèñîâêà ëèíèé, åñëè âûáðàíî true â ãëîá.ïåðåìåííîé
{
DrawPriceTrendLine(Time[currentTrough],Time[lastTrough],Low[currentTrough],
Low[lastTrough],Green,STYLE_SOLID);
DrawIndicatorTrendLine(Time[currentTrough],Time[lastTrough],OsMA[currentTrough],
OsMA[lastTrough],Green,STYLE_SOLID);
}
}
// Åñëè òåê.ÿìà íèæå ïðåäûäóùåé è öåíà Low òåê.ÿìû âûøå öåíû ïðåäûäóùåé ÿìû èíäèêàòîðà - òàêîé äèâåð <
if(OsMA[currentTrough]<OsMA[lastTrough] && Low[currentTrough]>Low[lastTrough])
{
bullishDivergence[currentTrough]=OsMA[currentTrough]; // ïåðåäàåì çíà÷.OsMA â ìàññèâ ñî ñòðåëî÷íûì áóôåðîì
bulliShift[currentTrough-n]=OsMA[currentTrough]; // ïåðåäàåì çíà÷.OsMA â ìàññèâ ñî ñòðåëî÷íûì áóôåðîì
if(drawDivergenceLines) DrawArrowOnChart(currentTrough,1);
//trough[shift] = EMPTY_VALUE; // óáåðåì íàëîæåíèå íà îäèí èíäåêñ äâóõ çíà÷êîâ
if(drawDivergenceLines==true) // ïðîðèñîâêà ëèíèé, åñëè âûáðàíî true â ãëîá.ïåðåìåííîé
{
DrawPriceTrendLine(Time[currentTrough],Time[lastTrough],Low[currentTrough],
Low[lastTrough],Green,STYLE_DOT);
DrawIndicatorTrendLine(Time[currentTrough],Time[lastTrough],OsMA[currentTrough],
OsMA[lastTrough],Green,STYLE_DOT);
}
}
}
//+-------------------------------------------------------------------------------------------------------------------+
//| Äèâåðãåíöèÿ óêàçûâàþùàÿ ñòðåëêó "âíèç" |
//+-------------------------------------------------------------------------------------------------------------------+
void CatchBearishDivergence(int shift) // shift = i+n
{
int idPeak=IsIndicatorPeak(shift); // èíäåêñ âïàäèíû, ïîëó÷àåì ïî ïåðåáîðó âëåâî îò íàéäåíîãî ïèêà
if(idPeak<0) return; // ïèê îòñóòñòâóåò
int currentPeak = shift; // èíäåêñ ïèêà, ðàç äîøëè ñþäà, n-é áàð ñàìûé âûñîêèé
int lastPeak = GetIndicatorLastPeak(idPeak); // ïîëó÷èëè èíäåêñ ïðåäïîñëåäíåãî ïèêà
// Åñëè òåê.ïèê íèæå ïðåäûäóùåãî è öåíà òåê.ïèêà âûøå öåíû ïðåäûäóùåãî ïèêà èíäèêàòîðà - òàêîé äèâåð <
if(lastPeak>=0&&OsMA[currentPeak]<OsMA[lastPeak] && High[currentPeak]>High[lastPeak])
{
bearishDivergence[currentPeak]=OsMA[currentPeak]; // çàïèñûâàåì â ìàññèâ çíà÷åíèå ÎñÌÀ
beariShift[currentPeak-n]=OsMA[currentPeak]; // çàïèñûâàåì â ìàññèâ çíà÷åíèå ÎñÌÀ
if(drawDivergenceLines) DrawArrowOnChart(currentPeak,2);
//peak[shift] = EMPTY_VALUE; // óáåðåì íàëîæåíèå íà îäèí èíäåêñ äâóõ çíà÷êîâ
if(drawDivergenceLines==true) // ïðîðèñîâêà ëèíèé, åñëè âûáðàíî true â ãëîá.ïåðåìåííîé
{
DrawPriceTrendLine(Time[currentPeak],Time[lastPeak],High[currentPeak],
High[lastPeak],Red,STYLE_SOLID);
DrawIndicatorTrendLine(Time[currentPeak],Time[lastPeak],OsMA[currentPeak],
OsMA[lastPeak],Red,STYLE_SOLID);
}
}
// Åñëè òåê.ïèê âûøå ïðåäûäóùåãî è öåíà òåê.ïèêà íèæå öåíû ïðåäûäóùåãî ïèêà èíäèêàòîðà - òàêîé äèâåð >
if(lastPeak>=0&&OsMA[currentPeak]>OsMA[lastPeak] && High[currentPeak]<High[lastPeak])
{
bearishDivergence[currentPeak]=OsMA[currentPeak]; // çàïèñûâàåì â ìàññèâ çíà÷åíèå ÎñÌÀ
beariShift[currentPeak-n]=OsMA[currentPeak]; // çàïèñûâàåì â ìàññèâ çíà÷åíèå ÎñÌÀ
if(drawDivergenceLines) DrawArrowOnChart(currentPeak,2);
//peak[shift] = EMPTY_VALUE; // óáåðåì íàëîæåíèå íà îäèí èíäåêñ äâóõ çíà÷êîâ
if(drawDivergenceLines==true) // ïðîðèñîâêà ëèíèé, åñëè âûáðàíî true â ãëîá.ïåðåìåííîé
{
DrawPriceTrendLine(Time[currentPeak],Time[lastPeak],High[currentPeak],
High[lastPeak],Red,STYLE_DOT);
DrawIndicatorTrendLine(Time[currentPeak],Time[lastPeak],OsMA[currentPeak],
OsMA[lastPeak],Red,STYLE_DOT);
}
}
}
//+-------------------------------------------------------------------------------------------------------------------+
//| Ô-ÿ â ïåðâîì öèêëå for îïð-åò íàëè÷èå ïèêà /\ ïåðåáèðàÿ óêàçàííîå ÷èñëî n-áàðîâ ñëåâà è ñïðàâà îò èñêîìîé ñâå÷è. |
//| Èñêîìàÿ ñâå÷à îïðåäåëÿåòñÿ îò òåêóùåãî áàðà, êàê ïðàâèëî íóëåâîãî (à íà èñòîðèè îò i-ãî), íà n-áàðîâ âëåâî. |
//| Äàëåå, åñëè ïèê, îòâå÷àþùèé óñëîâèÿì, ñóùåñòâóåò, äåëàåì ïåðåáîð âãëóáü èñòîðèè. ÎñÌÀ âãëóáü ïàäàåò, åñëè ïîÿâ- |
//| ëÿåòñÿ èçãèá íàâåðõ, òîãäà âîçâðàùàåì ýòîò èíäåêñ áàðà. Âî âñåõ îñòàëüíûõ ñëó÷àÿõ ôóíêöèÿ âîçâðàùàåò (-1) |
//| Âî âòîðîì öèêëå for ìîæíî èñêàòü èçãèáû ÎñÌÀ íå íà 1 áàð, à íà áîëüøå, ÷òîá èãíîðèðîâàòü íåçíà÷èòåëüíûå êîëåáàíèÿ |
//+-------------------------------------------------------------------------------------------------------------------+
int IsIndicatorPeak(int shift) // èùåì ïèê íà shift = i+n
{
int i,m=0;
for(i=0; i<n; i++)
{ //
if((OsMA[shift+i]>OsMA[shift+i+1] && OsMA[shift-i]>OsMA[shift-i-1]) ||
(OsMA[shift]>OsMA[shift+i+1] && OsMA[shift]>OsMA[shift-i-1]))
{
m++; continue;
}
else return(-1); // âåðíåì çíà÷åíèå òåê.ôóíêöèè "false"
}
if(m==n)
{
peak[shift] = OsMA[shift]; // çàíîñèì â ìàññèâ ïîëó÷èâøèéñÿ èçãèá
for(i = shift + n; i < Bars; i++) // ïåðåñ÷èòûâàåì âñå áàðû OsMA ïàäàåò íàçàä â èñòîðèþ
if(OsMA[i] < OsMA[i+1]) // OsMA èçîãíóëàñü, òåê.çíà÷ ìåíüøå i+1
return(i); // ïîëó÷èì èíäåêñ áàðà íà êîòîðîì èçãèá-âïàäèíà
}
return(-1); // âåðíåì çíà÷åíèå òåê.ôóíêöèè "false"
}
//+-------------------------------------------------------------------------------------------------------------------+
//| Ô-ÿ â ïåðâîì öèêëå for îïð-åò íàëè÷èå âïàäèíû V ïåðåáèðàÿ óêàçàííîå ÷èñëî n-áàðîâ ñëåâà è ñïðàâà îò èñêîìîé ñâå÷è.|
//| Èñêîìàÿ ñâå÷à îïðåäåëÿåòñÿ îò òåêóùåãî áàðà, êàê ïðàâèëî íóëåâîãî (à íà èñòîðèè îò i-ãî), íà n-áàðîâ âëåâî. |
//| Äàëåå, åñëè âïàäèíà, îòâå÷àþùàÿ óñëîâèÿì, ñóùåñòâóåò, äåëàåì ïåðåáîð âãëóáü èñòîðèè. ÎñÌÀ âãëóáü ðàñòåò, åñëè ïî- |
//| ÿâëÿåòñÿ èçãèá âíèç, òîãäà âîçâðàùàåì ýòîò èíäåêñ áàðà. Âî âñåõ îñòàëüíûõ ñëó÷àÿõ ôóíêöèÿ âîçâðàùàåò (-1) |
//| Âî âòîðîì öèêëå for ìîæíî èñêàòü èçãèáû ÎñÌÀ íå íà 1 áàð, à íà áîëüøå, ÷òîá èãíîðèðîâàòü íåçíà÷èòåëüíûå êîëåáàíèÿ |
//+-------------------------------------------------------------------------------------------------------------------+
int IsIndicatorTrough(int shift) // èùåì èçãèá V íà shift = i + n
{
int i,m=0;
for(i=0; i<n; i++)
{ //
if((OsMA[shift+i]<OsMA[shift+i+1] && OsMA[shift-i]<OsMA[shift-i-1]) ||
(OsMA[shift]<OsMA[shift+i+1] && OsMA[shift]<OsMA[shift-i-1]))
{
m++; continue;
}
else return(-1); // âåðíåì çíà÷åíèå òåê.ôóíêöèè "false"
}
if(m==n)
{
trough[shift] = OsMA[shift]; // çàíîñèì â ìàññèâ ïîëó÷èâøèéñÿ èçãèá
for(i = shift + n; i < Bars-n; i++) // ïåðåñ÷èòûâàåì âñå áàðû OsMA ðàñòåò íàçàä â èñòîðèþ
{
if(OsMA[i] > OsMA[i+1]) // OsMA èçîãíóëàñü, òåê.çíà÷ áîëüøå i+1
return(i); // ïîëó÷èì èíäåêñ áàðà íà êîòîðîì èçãèá-ãîðá
}
}
return(-1); // âåðíåì çíà÷åíèå òåê.ôóíêöèè "false"
}
//+-------------------------------------------------------------------------------------------------------------------+
//| Íàõîæäåíèå ïðåäïîñëåäíåãî ïèêà |
//| Âûñ÷èòûâàåòñÿ, êàê äâà ñîñåäíèõ áàðà ñëåâà è ñïðàâà íèæå èñêîìîãî |
//+-------------------------------------------------------------------------------------------------------------------+
int GetIndicatorLastPeak(int idPeak)
{
for(int i=idPeak+1; i<Bars; i++) // ïåðåñ÷èòûâàåì âñå áàðû ïîñëå âïàäèíû çà ïèêîì
{
if(peak[i]!=NULL && peak[i]!=EMPTY_VALUE) // íàõîäèì ïèê ïî óñëîâèþ
return(i); // ïîëó÷àåì èíäåêñ ïèêà
}
return(-1);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| Íàõîæäåíèå ïðåäïîñëåäíåé âïàäèíû |
//| Íàõîäèì ïîñëåäíåå íåïóñòîå çíà÷åíèå â ìàññèâå trough[i] |
//+-------------------------------------------------------------------------------------------------------------------+
int GetIndicatorLastTrough(int idTrough)
{
for(int i= idTrough+1; i<history; i++)
{ // ïåðåñ÷èòûâàåì âñå áàðû ïîñëå ãîðáà çà âïàäèíîé
if(trough[i] != NULL && trough[i] != EMPTY_VALUE) // íàõîäèì âïàäèíó ïî óñëîâèþ
return(i); // ïîëó÷àåì èíäåêñ âïàäèíû
}
return(-1);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1,datetime x2,double y1,
double y2,color lineColor,double style)
{
string label="DivergenceLine2.1# "+DoubleToStr(x1,0);
ObjectDelete(label);
ObjectCreate(label,OBJ_TREND,0,x1,y1,x2,y2,0,0);
ObjectSet(label,OBJPROP_RAY,0);
ObjectSet(label,OBJPROP_COLOR,lineColor);
ObjectSet(label,OBJPROP_STYLE,style);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
void DrawIndicatorTrendLine(datetime x1,datetime x2,double y1,
double y2,color lineColor,double style)
{
int indicatorWindow=WindowFind("kosma-2.02 ("+fast+","+slow+","+sig+")"+" k"+k+" n"+n);
if(indicatorWindow<0)
return;
string label="DivergenceLine2.1$# "+DoubleToStr(x1,0);
ObjectDelete(label);
ObjectCreate(label,OBJ_TREND,indicatorWindow,x1,y1,x2,y2,0,0);
ObjectSet(label,OBJPROP_RAY,0);
ObjectSet(label,OBJPROP_COLOR,lineColor);
ObjectSet(label,OBJPROP_STYLE,style);
}
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
void DrawArrowOnChart(int shift,int updn)
{
string label="DivergenceLine2.1# "+DoubleToStr(Time[shift-n]+updn,0);
ObjectDelete(label);
if(updn==1)
{
ObjectCreate(label,OBJ_ARROW,0,Time[shift-n],Low[shift-n]);
ObjectSet(label,OBJPROP_ARROWCODE,233);
ObjectSet(label,OBJPROP_COLOR,Green);
}
if(updn==2)
{
ObjectCreate(label,OBJ_ARROW,0,Time[shift-n],High[shift-n]);
ObjectSet(label,OBJPROP_ARROWCODE,234);
ObjectSet(label,OBJPROP_COLOR,Red);
}
}
//+-------------------------------------------------------------------------------------------------------------------+
//| |
//+-------------------------------------------------------------------------------------------------------------------+
Comments