//+------------------------------------------------------------------+ //| 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; } } } }
Sample
Analysis
Market Information Used:
Indicator Curves created:
Indicators Used:
Custom Indicators Used:
Order Management characteristics:
Other Features: