//+------------------------------------------------------------------+
//| Indicator_Painting.mq4 |
//| Copyright © 2009, TheXpert |
//| theforexpert@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, TheXpert"
#property link "theforexpert@gmail.com"
// ====================================================
// Íåîáõîäèìî ïîëîæèòü â ïàïêó /Experts/Libraries âàøåãî òåðìèíàëà
// ====================================================
#property library
// ====================================================
// Ðàçìåòêà âåðøèí è âïàäèí
// ====================================================
void MarkExtremums(
double values[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double& extremums[], // áóôåð äëÿ ðàçìåòêè ýêñòðåìóìîâ
int startIndex, // íà÷àëüíûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int endIndex, // êîíå÷íûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int direction, // DIR_TOP âåðøèíû DIR_BOTTOM âïàäèíû DIR_ALL è âåðøèíû è âïàäèíû
double emptyValueUsed) // èñïîëüçóåìîå ïóñòîå çíà÷åíèå
{
// íàõîäèì ïðèðàùåíèå äëÿ èíäåêñà â öèêëå
int di = -1;
if (endIndex > startIndex) di = 1;
// ðàñêðàøèâàåì
for (int i = startIndex; (i >= startIndex && i <= endIndex) || (i >= endIndex && i <= startIndex); i += di)
{
// äëÿ ïðîâåðêè îòíîñèòåëüíî òåêóùåãî èíäåêñà íàì íàäî
// èñòîðèÿ ãëóáèíîé íà 2 áîëüøå, åñëè ýòî íå òàê, ìîæíî íå ïðîâåðÿòü
if (i + 2 >= Bars)
{
continue;
}
// ïðîâåðêà íà ïóñòûå çíà÷åíèÿ, åñëè îíè åñòü, ïðîâåðêà íå èìååò ñìûñëà
if (
values[i] == emptyValueUsed ||
values[i + 1] == emptyValueUsed ||
values[i + 2] == emptyValueUsed ||
values[i] == EMPTY_VALUE ||
values[i + 1] == EMPTY_VALUE ||
values[i + 2] == EMPTY_VALUE
)
{
continue;
}
// çàòèðàåì òåêóùåå çíà÷åíèå ìàðêèðîâî÷íîãî áóôåðà
if (di < 0) extremums[i + 1] = EMPTY_VALUE;
// óñëîâèå ïåðåñå÷åíèÿ -- ïðîñòîé ñëó÷àé
if ((values[i] - values[i + 1])*(values[i + 1] - values[i + 2]) < 0 && (values[i] - values[i + 1])*direction >= 0)
{
// åñëè ïåðåñå÷åíèå èìååò ìåñòî áûòü
extremums[i + 1] = values[i + 1];
continue;
}
// óñëîâèå ïåðåñå÷åíèÿ -- ñëîæíûé ñëó÷àé -- êîãäà âåðøèíà âêëþ÷àåò â ñåáÿ
// íåñêîëüêî áàðîâ ñ îäèíàêîâûìè çíà÷åíèÿìè
if (values[i + 1] == values[i + 2] && values[i] != values[i + 1] && (values[i] - values[i + 1])*direction >= 0)
{
// èìååòñÿ ïîòåíöèàëüíûé ýêñòðåìóì -- ïðîâåðÿåì íà âøèâîñòü
// äëÿ ýòîãî íàõîäèì âòîðîé åå êîíåö.
int index = i + 2;
bool found = false;
while (index < Bars && values[index] != emptyValueUsed && values[index] != EMPTY_VALUE)
{
if (values[i + 2] != values[index])
{
// óðà, âòîðîé êîíåö íàéäåí
found = true;
break;
}
index++;
}
if (!found)
{
// èëè äîøëè äî êîíöà èñòîðèè, èëè íàòêíóëèñü íà ïóñòîå çíà÷åíèå
// â îáîèõ ñëó÷àÿõ ñ÷èòàåì ÷òî ýêñòðåìóìà íåò
continue;
}
// ïðîâåðÿåì êîíöû íà ïåðåñå÷åíèå
if ((values[i] - values[i + 1])*(values[i + 1] - values[index]) < 0)
{
// ïåðåñå÷åíèå åñòü
extremums[i + 1] = values[i + 1];
} // else -- èìååò ìåñòî òî÷êà ïåðåãèáà, ïîìå÷àòü íå íàäî
}
}
}
// ====================================================
// Ðàçìåòêà ïåðåñå÷åíèé
// ====================================================
void MarkCrosses(
double values1[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double values2[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double& crosses[], // áóôåð äëÿ ðàçìåòêè ïåðåñå÷åíèé
int startIndex, // íà÷àëüíûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int endIndex, // êîíå÷íûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int direction, // CROSS_UP ïåðåñå÷åíèå ââåðõ CROSS_DOWN âíèç CROSS_ALL âñå
double emptyValueUsed) // èñïîëüçóåìîå ïóñòîå çíà÷åíèå
{
// íàõîäèì ïðèðàùåíèå äëÿ èíäåêñà â öèêëå
int di = -1;
if (endIndex > startIndex) di = 1;
// ðàñêðàøèâàåì
for (int i = startIndex; (i >= startIndex && i <= endIndex) || (i >= endIndex && i <= startIndex); i += di)
{
// íàäî èñòîðèÿ íà 1 áàð íàçàä, èíà÷å íåò ñìûñëà ïðîâåðÿòü
if (i + 1 >= Bars)
{
continue;
}
// åñëè õîòÿ áû îäíî çíà÷åíèå ïóñòî, ïðîâåðÿòü íåò ñìûñëà
if (
values1[i] == emptyValueUsed ||
values1[i + 1] == emptyValueUsed ||
values2[i] == emptyValueUsed ||
values2[i + 1] == emptyValueUsed ||
values1[i] == EMPTY_VALUE ||
values1[i + 1] == EMPTY_VALUE ||
values2[i] == EMPTY_VALUE ||
values2[i + 1] == EMPTY_VALUE
)
{
continue;
}
// ÷èñòèì òåêóùåå çíà÷åíèå
if (di < 0) crosses[i] = EMPTY_VALUE;
// ïðîâåðêà íà ïåðåñå÷åíèå (ïðîñòîé ñëó÷àé)
if ((values1[i] - values2[i])*(values1[i + 1] - values2[i + 1]) < 0 && (values1[i] - values2[i])*direction >= 0)
{
crosses[i] = values2[i];
continue;
}
// óñëîâèå ïåðåñå÷åíèÿ -- ñëîæíûé ñëó÷àé -- êîãäà ïåðåñå÷åíèå âêëþ÷àåò â ñåáÿ
// íåñêîëüêî áàðîâ ñ îäèíàêîâûìè çíà÷åíèÿìè
if (values1[i + 1] == values2[i + 1] && values1[i] != values2[i] && (values1[i] - values2[i])*direction >= 0)
{
// èìååòñÿ ïîòåíöèàëüíîå ïåðåñå÷åíèå -- ïðîâåðÿåì íà âøèâîñòü
// äëÿ ýòîãî íàõîäèì âòîðîé åå êîíåö.
int index = i + 1;
bool found = false;
while (
index < Bars &&
values1[index] != emptyValueUsed &&
values1[index] != EMPTY_VALUE &&
values2[index] != emptyValueUsed &&
values2[index] != EMPTY_VALUE)
{
if (values1[index] != values2[index])
{
// óðà, âòîðîé êîíåö íàéäåí
found = true;
break;
}
index++;
}
if (!found)
{
// èëè äîøëè äî êîíöà èñòîðèè, èëè íàòêíóëèñü íà ïóñòîå çíà÷åíèå
// â îáîèõ ñëó÷àÿõ ñ÷èòàåì ÷òî ïåðåñå÷åíèÿ íåò
continue;
}
// ïðîâåðÿåì êîíöû íà ïåðåñå÷åíèå
if ((values1[i] - values2[i])*(values1[index] - values2[index]) < 0)
{
// ïåðåñå÷åíèå åñòü
crosses[i] = values2[i];
} // else èìååò ìåñòî êàñàíèå -- íå ïîìå÷àåì
}
}
}
// ====================================================
// Ðàçìåòêà ïåðåñå÷åíèé c óðîâíåì
// ====================================================
void MarkLevelCrosses(
double values[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double level, // óðîâåíü äëÿ ïðîâåðêè íà ïåðåñå÷åíèå
double& crosses[], // áóôåð äëÿ ðàçìåòêè ïåðåñå÷åíèé
int startIndex, // íà÷àëüíûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int endIndex, // êîíå÷íûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int direction, // CROSS_UP ïåðåñå÷åíèå ââåðõ DROSS_DOWN âíèç CROSS_ALL âñå
double emptyValueUsed) // èñïîëüçóåìîå ïóñòîå çíà÷åíèå
{
// íàõîäèì ïðèðàùåíèå äëÿ èíäåêñà â öèêëå
int di = -1;
if (endIndex > startIndex) di = 1;
// ðàñêðàøèâàåì
for (int i = startIndex; (i >= startIndex && i <= endIndex) || (i >= endIndex && i <= startIndex); i += di)
{
// íàäî èñòîðèÿ íà 1 áàð íàçàä, èíà÷å íåò ñìûñëà ïðîâåðÿòü
if (i + 1 >= Bars)
{
continue;
}
// åñëè õîòÿ áû îäíî çíà÷åíèå ïóñòî, ïðîâåðÿòü íåò ñìûñëà
if (
values[i] == emptyValueUsed ||
values[i + 1] == emptyValueUsed ||
values[i] == EMPTY_VALUE ||
values[i + 1] == EMPTY_VALUE
)
{
continue;
}
// ÷èñòèì òåêóùåå çíà÷åíèå
if (di < 0) crosses[i] = EMPTY_VALUE;
// ïðîâåðêà íà ïåðåñå÷åíèå (ïðîñòîé ñëó÷àé)
if ((values[i] - level)*(values[i + 1] - level) < 0 && (values[i] - level)*direction >= 0)
{
crosses[i] = level;
continue;
}
// óñëîâèå ïåðåñå÷åíèÿ -- ñëîæíûé ñëó÷àé -- êîãäà ïåðåñå÷åíèå âêëþ÷àåò â ñåáÿ
// íåñêîëüêî áàðîâ ñ îäèíàêîâûìè çíà÷åíèÿìè
if (values[i + 1] == level && values[i] != level && (values[i] - level)*direction >= 0)
{
// èìååòñÿ ïîòåíöèàëüíîå ïåðåñå÷åíèå -- ïðîâåðÿåì íà âøèâîñòü
// äëÿ ýòîãî íàõîäèì âòîðîé åå êîíåö.
int index = i + 1;
bool found = false;
while (
index < Bars &&
values[index] != emptyValueUsed &&
values[index] != EMPTY_VALUE)
{
if (values[index] != level)
{
// óðà, âòîðîé êîíåö íàéäåí
found = true;
break;
}
index++;
}
if (!found)
{
// èëè äîøëè äî êîíöà èñòîðèè, èëè íàòêíóëèñü íà ïóñòîå çíà÷åíèå
// â îáîèõ ñëó÷àÿõ ñ÷èòàåì ÷òî ïåðåñå÷åíèÿ íåò
continue;
}
// ïðîâåðÿåì êîíöû íà ïåðåñå÷åíèå
if ((values[i] - level)*(values[index] - level) < 0)
{
// ïåðåñå÷åíèå åñòü
crosses[i] = level;
} // else èìååò ìåñòî êàñàíèå -- íå ïîìå÷àåì
}
}
}
// ====================================================
// Ðàçìåòêà óðîâíåé
// ====================================================
void MarkLevel(
double values[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double& level[], // áóôåð äëÿ ðàçìåòêè ïåðåñå÷åíèé
int startIndex, // íà÷àëüíûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int endIndex, // êîíå÷íûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
double levelValue, // çíà÷åíèå óðîâíÿ
int condition, // ìåíüøå (LESS_THAN = -1) èëè áîëüøå óðîâíÿ (GREATER_THAN = 1)
double emptyValueUsed) // èñïîëüçóåìîå ïóñòîå çíà÷åíèå
{
int Depth = 2;
// ×òîáû íå îñòàâàëîñü ìóñîðà íà 1 áàðå, çàãëÿäûâàåì íà 1 áàð íàçàä
if (endIndex > startIndex)
{
endIndex = MathMax(endIndex, Depth);
}
else
{
startIndex = MathMax(startIndex, Depth);
}
// íàõîäèì ïðèðàùåíèå äëÿ èíäåêñà â öèêëå
int di = -1;
if (endIndex > startIndex) di = 1;
// ðàñêðàøèâàåì
for (int i = startIndex; (i >= startIndex && i <= endIndex) || (i >= endIndex && i <= startIndex); i += di)
{
if (values[i] == EMPTY_VALUE || values[i] == emptyValueUsed)
{
continue;
}
if (di < 0) level[i] = EMPTY_VALUE;
// çà óðîâíåì
if ((values[i] - levelValue)*condition >= 0)
{
level[i] = values[i];
// åñëè ïðåäûäóùèé íå çà óðîâíåì
if ((values[i + 1] - levelValue)*condition < 0 && values[i + 1] != emptyValueUsed && values[i + 1] != EMPTY_VALUE)
{
// ìåòèì è åãî òîæå, íî çíà÷åíèåì óðîâíÿ
level[i + 1] = levelValue;
}
}
// åñëè òåêóùèé íå çà óðîâíåì
else
{
// åñëè ïðåäûäóùèé çà óðîâíåì
if ((values[i + 1] - levelValue)*condition >= 0 && values[i + 1] != EMPTY_VALUE && values[i + 1] != emptyValueUsed)
{
// ìåòèì è åãî òîæå, íî çíà÷åíèåì óðîâíÿ
level[i] = levelValue;
}
}
}
}
// ====================================================
// Ðàçìåòêà äèíàìè÷åñêèõ óðîâíåé
// ====================================================
void MarkDynamicLevel(
double values[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double dynamicLevel[], // çíà÷åíèÿ äèíàìè÷åñêîãî óðîâíÿ äëÿ ïðîâåðêè
double& level[], // áóôåð äëÿ ðàçìåòêè ïåðåñå÷åíèé
int startIndex, // íà÷àëüíûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int endIndex, // êîíå÷íûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int condition, // ìåíüøå (LESS_THAN = -1) èëè áîëüøå óðîâíÿ (GREATER_THAN = 1)
double emptyValueUsed) // èñïîëüçóåìîå ïóñòîå çíà÷åíèå
{
int Depth = 2;
// ×òîáû íå îñòàâàëîñü ìóñîðà íà 1 áàðå, çàãëÿäûâàåì íà 1 áàð íàçàä
if (endIndex > startIndex)
{
endIndex = MathMax(endIndex, Depth);
}
else
{
startIndex = MathMax(startIndex, Depth);
}
// íàõîäèì ïðèðàùåíèå äëÿ èíäåêñà â öèêëå
int di = -1;
if (endIndex > startIndex) di = 1;
// ðàñêðàøèâàåì
for (int i = startIndex; (i >= startIndex && i <= endIndex) || (i >= endIndex && i <= startIndex); i += di)
{
if (values[i] == EMPTY_VALUE || values[i] == emptyValueUsed)
{
continue;
}
if (di < 0) level[i] = EMPTY_VALUE;
// çà óðîâíåì
if ((values[i] - dynamicLevel[i])*condition >= 0)
{
level[i] = values[i];
// åñëè ïðåäûäóùèé íå çà óðîâíåì
if ((values[i + 1] - dynamicLevel[i + 1])*condition < 0 && values[i + 1] != emptyValueUsed && values[i + 1] != EMPTY_VALUE)
{
// ìåòèì è åãî òîæå, íî çíà÷åíèåì óðîâíÿ
level[i + 1] = dynamicLevel[i + 1];
}
}
// åñëè òåêóùèé íå çà óðîâíåì
else
{
// åñëè ïðåäûäóùèé çà óðîâíåì
if ((values[i + 1] - dynamicLevel[i + 1])*condition >= 0 && values[i + 1] != EMPTY_VALUE && values[i + 1] != emptyValueUsed)
{
// ìåòèì è åãî òîæå, íî çíà÷åíèåì óðîâíÿ
level[i] = dynamicLevel[i];
}
}
}
}
// ====================================================
// Ðàçìåòêà íàïðàâëåíèÿ (ââåðõ)
// ====================================================
void MarkGrowing(
double values[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double& growing1[], // 1-é áóôåð äëÿ ðàçìåòêè íàïðàâëåíèÿ
double& growing2[], // 2-é áóôåð äëÿ ðàçìåòêè íàïðàâëåíèÿ
int startIndex, // íà÷àëüíûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int endIndex, // êîíå÷íûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
double emptyValueUsed) // èñïîëüçóåìîå ïóñòîå çíà÷åíèå
{
// íàõîäèì ïðèðàùåíèå äëÿ èíäåêñà â öèêëå
int di = -1;
if (endIndex > startIndex) di = 1;
// Ìåòèì óðîâíè ðîñòà
for (int i = startIndex; (i >= startIndex && i <= endIndex) || (i >= endIndex && i <= startIndex); i += di)
{
// äëÿ ïðîâåðêè îòíîñèòåëüíî òåêóùåãî èíäåêñà íàì íàäî
// èñòîðèÿ ãëóáèíîé íà 2 áîëüøå, åñëè ýòî íå òàê, ìîæíî íå ïðîâåðÿòü
if (i + 1 >= Bars)
{
continue;
}
// ïðîâåðêà íà ïóñòûå çíà÷åíèÿ, åñëè îíè åñòü, ïðîâåðêà íå èìååò ñìûñëà
if (
values[i] == emptyValueUsed ||
values[i + 1] == emptyValueUsed ||
values[i] == EMPTY_VALUE ||
values[i + 1] == EMPTY_VALUE
)
{
continue;
}
// îáíóëÿåì òåêóùèå çíà÷åíèÿ
if (di < 0) growing1[i] = EMPTY_VALUE;
if (di < 0) growing2[i] = EMPTY_VALUE;
// åñëè ðàñòåò
if (values[i] > values[i + 1])
{
// è ðîñëî íà ïðåäûäóùåì áàðå
if (values[i + 1] > values[i + 2])
{
// ïèøåì â òåêóùèé áóôåð ðîñòà
if (growing1[i + 1] != EMPTY_VALUE) growing1[i] = values[i];
else growing2[i] = values[i];
}
// åñëè íà ïðåäûäóùåì áàðå íå ðîñëî
else
{
// ïèøåì â áóôåð êîòîðûé íå èñïîëüçîâàëñÿ ïîñëåäíèå 2 áàðà
// (1 òàêîé äîëæåí áûòü îáÿçàòåëüíî)
if (growing2[i + 2] == EMPTY_VALUE)
{
growing2[i] = values[i];
growing2[i + 1] = values[i + 1];
}
else
{
growing1[i] = values[i];
growing1[i + 1] = values[i + 1];
}
}
}
// óäàëåíèå ðàñêðàñêè õâîñòèêà åñëè íå ðàñòåò
else if (i == 0)
{
if (growing1[i + 1] != EMPTY_VALUE && growing1[i + 2] == EMPTY_VALUE)
{
growing1[i + 1] = EMPTY_VALUE;
}
if (growing2[i + 1] != EMPTY_VALUE && growing2[i + 2] == EMPTY_VALUE)
{
growing2[i + 1] = EMPTY_VALUE;
}
}
}
}
// ====================================================
// Ðàçìåòêà íàïðàâëåíèÿ (âíèç)
// ====================================================
void MarkReducing(
double values[], // çíà÷åíèÿ äëÿ ïðîâåðêè
double& reducing1[], // 1-é áóôåð äëÿ ðàçìåòêè íàïðàâëåíèÿ
double& reducing2[], // 2-é áóôåð äëÿ ðàçìåòêè íàïðàâëåíèÿ
int startIndex, // íà÷àëüíûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
int endIndex, // êîíå÷íûé èíäåêñ äëÿ ïðîâåðêè (âêëþ÷àåòñÿ)
double emptyValueUsed) // èñïîëüçóåìîå ïóñòîå çíà÷åíèå
{
// íàõîäèì ïðèðàùåíèå äëÿ èíäåêñà â öèêëå
int di = -1;
if (endIndex > startIndex) di = 1;
// Ìåòèì óðîâíè ïàäåíèÿ
for (int i = startIndex; (i >= startIndex && i <= endIndex) || (i >= endIndex && i <= startIndex); i += di)
{
// äëÿ ïðîâåðêè îòíîñèòåëüíî òåêóùåãî èíäåêñà íàì íàäî
// èñòîðèÿ ãëóáèíîé íà 2 áîëüøå, åñëè ýòî íå òàê, ìîæíî íå ïðîâåðÿòü
if (i + 1 >= Bars)
{
continue;
}
// ïðîâåðêà íà ïóñòûå çíà÷åíèÿ, åñëè îíè åñòü, ïðîâåðêà íå èìååò ñìûñëà
if (
values[i] == emptyValueUsed ||
values[i + 1] == emptyValueUsed ||
values[i] == EMPTY_VALUE ||
values[i + 1] == EMPTY_VALUE
)
{
continue;
}
// îáíóëÿåì òåêóùèå çíà÷åíèÿ
if (di < 0) reducing1[i] = EMPTY_VALUE;
if (di < 0) reducing2[i] = EMPTY_VALUE;
// åñëè ïàäàåò
if (values[i] < values[i + 1])
{
// è ïàäàëî íà ïðåäûäóùåì áàðå
if (values[i + 1] < values[i + 2])
{
// ïèøåì â òåêóùèé áóôåð ïàäåíèÿ
if (reducing1[i + 1] != EMPTY_VALUE) reducing1[i] = values[i];
else reducing2[i] = values[i];
}
// åñëè íà ïðåäûäóùåì áàðå íå ïàäàëî
else
{
// ïèøåì â áóôåð êîòîðûé íå èñïîëüçîâàëñÿ ïîñëåäíèå 2 áàðà
// (1 òàêîé äîëæåí áûòü îáÿçàòåëüíî)
if (reducing2[i + 2] == EMPTY_VALUE)
{
reducing2[i] = values[i];
reducing2[i + 1] = values[i + 1];
}
else
{
reducing1[i] = values[i];
reducing1[i + 1] = values[i + 1];
}
}
}
// óäàëåíèå ðàñêðàñêè õâîñòèêà åñëè íå ðàñòåò
else if (i == 0)
{
if (reducing1[i + 1] != EMPTY_VALUE && reducing1[i + 2] == EMPTY_VALUE)
{
reducing1[i + 1] = EMPTY_VALUE;
}
if (reducing2[i + 1] != EMPTY_VALUE && reducing2[i + 2] == EMPTY_VALUE)
{
reducing2[i + 1] = EMPTY_VALUE;
}
}
}
}
Comments