// --------------------------------------------------------------------------- // Ïîèñê ýêñòðåìóìîâ ïî Ëàððè Âèëüÿìñó // // Îïèñàíèå ïàðàìåòðîâ: // // LimitForShowLabel - Ìèíèìàëüíûé óðîâåíü îòîáðàæåíèÿ ìåòîê // MinimalLineLevel - Ìèíèìàëüíûé óðîâåíü äëÿ ëèíèé çèãçàãà // MaximalLineLevel - Ìàêñèìàëüíûé óðîâåíü äëÿ ëèíèé çàèãçàãà // OptimizeZigZag - Îïòèìèçàöèÿ çèãçàãà // (óáèðàåì ïîäðÿä èäóùèå ìèíèìóìû èëè ìàêñèìóìû) // ColorMaximum - Öâåò ìåòîê ìàêñèìóìîâ // ColorMinimum - Öâåò ìåòîê ìèíèìóìîâ // ColorLines - Öâåò ëèíèé çèãçàãà // OffsetForMaximums - Ñìåùåíèå ìåòîê äëÿ ìàêñèìóìîâ â ïóíêòàõ // OffsetForMinimums - Ñìåùåíèå ìåòîê äëÿ ìèíèìóìîâ â ïóíêòàõ // // Âåðñèÿ 2 - Äîáàâëåíî ïîñòðîåíèå ëèíèé çèãçàãà ïî íàéäåííûì ýêñòðåìóìàì // Âåðñèÿ 3 - Ïàðàìåòð îãðàíè÷åíèÿ îòðèñîâêè ëèíèé çèãçàãà íàìåðÿííî // çàäðàí - îí îñîáî è íå íóæåí â áîëüøèíñòâå ñëó÷àåâ. // Äîïîëíèòåëüíî äîáàâëåí ïîëåçíûé ôëàã - îòðèñîâêà òîëüêî // ïåðâîãî óðîâíÿ ýêñòðåìóìîâ. // Ââåäåíà ìîäèôèêàöèÿ â àëãîðèòì - ò.ê. îáíàðóæèëîñü, ÷òî ÷àñòî // âñòðå÷àåòñÿ òàêîé îñîáûé ñëó÷àé - ýêñòðåìóì âûäåëÿåòñÿ, äàæå // åñëè ñ îäíîé ñòîðîíû ïðåäûäóùèé ýêñòðåìóì òàêîãî æå óðîâíÿ // ìåíüøå, à ñ äðóãîé - áîëüøå èëè ÐÀÂÅÍ òåêóùåìó (ñðàáàòûâàíèå // ïî ôðîíòó). // Âåðñèÿ 4 - Èç ïîñòðîåíèÿ çèãçàãîâ èñêëþ÷åíû ñëó÷àè òèïà "äâà ìàêñèìóìà, // èäóùèå ïîäðÿä". Èñïðàâëåíà îøèáêà ñ âûäåëåíèåì ýêñòðåìóìà, // ïîòåíöèàëüíî ñïîñîáíàÿ ïðèâîäèòü ê áåñêîíå÷íîìó öèêëó. // Âåðñèÿ 5 - Èñïðàâëåíà ëîãè÷åñêàÿ îøèáêà, äàþùàÿ íåâåðíûé ðåçóëüòàò â // ðåäêîì êðàåâîì ñëó÷àå. Ââåäåíû áîëåå ëîãè÷íûå ïàðàìåòðû. // Óëó÷øåí îïòèìèçàòîð ëèíèé çèãçàãà. // Âåðñèÿ 6 - Èñïðàâëåíà îøèáêà ñ ïîðÿäêîì îòðèñîâêè ëèíèé èçãçàãà. Èç-çà // ýòîãî ìîãëè "âûïàñòü" íåêîòîðûå ýêñòðåìóìû. // --------------------------------------------------------------------------- #property show_inputs #define PREFIX_TEXT "t_" #define PREFIX_LINE "l_" #define FONT_SIZE 10 extern int LimitForShowLabel = 1; extern int MinimalLineLevel = 1; extern int MaximalLineLevel = 1; extern bool OptimizeZigZag = true; extern color ColorMaximum = C'0,255,0'; extern color ColorMinimum = C'255,0,0'; extern color ColorLines = C'255,255,255'; extern int OffsetForMaximums = 150; extern int OffsetForMinimums = 10; int maximum[], minimum[]; // Èíèöèàëèçàöèÿ int init() { // Ðàçìåðû è ñîäåðæèìîå ìàññèâîâ ArrayResize(maximum, Bars); ArrayResize(minimum, Bars); ArrayInitialize(maximum, 0); ArrayInitialize(minimum, 0); // Óäàëåíèå ñòàðûõ îòìåòîê ObjectsDeleteAll(0, OBJ_TEXT); ObjectsDeleteAll(0, OBJ_TREND); return(0); } // Òî÷êà âõîäà int start() { int i = 1; while(pass(i)) i++; draw_result(i - 1); return(0); } // Ïðîõîä ïî óðîâíþ // Âîçâðàùàåò true, åñëè áûëè íàéäåíû ýêñòðåìóìû çàäàííîãî óðîâíÿ bool pass(int level) { return(pass_maximum(level) || pass_minimum(level)); } // Ïîèñê ìåíüøåãî èëè ðàâíîãî ìàêñèìóìà ñëåâà //  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî áîëüøîå ÷èñëî double find_left_maximum(int bar) { int i, level = maximum[bar]; for(i = bar + 1; i < Bars; i++) { if(maximum[i] >= level) { return(High[i]); } } // Äîøëè äî êîíöà èñòîðèè return(High[bar] + 1); } // Ïîèñê ìåíüøåãî èëè ðàâíîãî ìàêñèìóìà ñïðàâà //  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî áîëüøîå ÷èñëî double find_right_maximum(int bar) { int i, level = maximum[bar]; for(i = bar - 1; i >= 0; i--) { if(maximum[i] >= level) { return(High[i]); } } // Äîøëè äî íà÷àëà èñòîðèè return(High[bar] + 1); } // Ïðîõîä ïî ìàêñèìóìàì äëÿ óðîâíÿ // Âîçâðàùàåò true, åñëè áûëè íàéäåíû ìàêñèìóìû bool pass_maximum(int level) { int i, limit = Bars - 2, prev = level - 1, result = false; for(i = 1; i < limit; i++) { if(maximum[i] == prev) { double l = find_left_maximum(i); double r = find_right_maximum(i); if((l <= High[i] && r < High[i]) || (l < High[i] && r <= High[i])) { maximum[i] = level; result = true; } } } return(result); } // Ïîèñê ìåíüøåãî èëè ðàâíîãî ìèíèìóìà ñëåâà //  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî ìåíüøåå ÷èñëî double find_left_minimum(int bar) { int i, level = minimum[bar]; for(i = bar + 1; i < Bars; i++) { if(minimum[i] >= level) { return(Low[i]); } } // Äîøëè äî êîíöà èñòîðèè return(Low[bar] - 1); } // Ïîèñê ìåíüøåãî èëè ðàâíîãî ìèíèìóìà ñïðàâà //  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî ìåíüøåå ÷èñëî double find_right_minimum(int bar) { int i, level = minimum[bar]; for(i = bar - 1; i >= 0; i--) { if(minimum[i] >= level) { return(Low[i]); } } // Äîøëè äî íà÷àëà èñòîðèè return(Low[bar] - 1); } // Ïðîõîä ïî ìèíèìóìàì äëÿ óðîâíÿ // Âîçâðàùàåò true, åñëè áûëè íàéäåíû ìèíèìóìû bool pass_minimum(int level) { int i, limit = Bars - 2, prev = level - 1, result = false; for(i = 1; i < limit; i++) { if(minimum[i] == prev) { double l = find_left_minimum(i); double r = find_right_minimum(i); if((l >= Low[i] && r > Low[i]) || (l > Low[i] && r >= Low[i])) { minimum[i] = level; result = true; } } } return(result); } // Îïòèìèçàöèÿ ìèíèìóìîâ void optimize_minimums(int bar, int level) { int i; for(i = bar + 1; i < Bars; i++) { if(minimum[i] >= level) { if(Low[i] < Low[bar]) { minimum[bar] = 0; } else { minimum[i] = 0; } break; } } } // Îïòèìèçàöèÿ ìàêñèìóìîâ void optimize_maximums(int bar, int level) { int i; for(i = bar + 1; i < Bars; i++) { if(maximum[i] >= level) { if(High[i] > High[bar]) { maximum[bar] = 0; } else { maximum[i] = 0; } break; } } } // Îïòèìèçàöèÿ çèãçàãà äëÿ çàäàííîãî óðîâíÿ void optimize_level(int level) { int i, j = 0; for(i = Bars - 1; i >= 0; i--) { if(maximum[i] >= level) { if(j == 1) { optimize_maximums(i, level); } else { j = 1; } } if(minimum[i] >= level) { if(j == -1) { optimize_minimums(i, level); } else { j = -1; } } } } // Ïîñòðîåíèå îòäåëüíîé ëèíèè void build_line(int level, int bar_to, datetime time_from, double price_from, datetime time_to, double price_to) { string n = StringConcatenate(PREFIX_LINE, level, "_", bar_to); ObjectCreate(n, OBJ_TREND, 0, time_from, price_from, time_to, price_to); ObjectSet(n, OBJPROP_COLOR, ColorLines); ObjectSet(n, OBJPROP_RAY, 0); } // Îòðèñîâêà ðåçóëüòàòîâ // Ïîëó÷àåìûé ïàðàìåòð - íîìåð ïîñëåäíåãî íàéäåííîãî óðîâíÿ void draw_result(int last_level) { int i, j, k; string n; double prev_price; datetime prev_time; // Îòðèñîâêà öèôð óðîâíåé for(i = 0; i < Bars; i++) { if(maximum[i] >= LimitForShowLabel) { n = StringConcatenate(PREFIX_TEXT, i, "_max_", maximum[i]); ObjectCreate(n, OBJ_TEXT, 0, Time[i], High[i] + OffsetForMaximums * Point); ObjectSet(n, OBJPROP_COLOR, ColorMaximum); ObjectSetText(n, "" + maximum[i], FONT_SIZE); } if(minimum[i] >= LimitForShowLabel) { n = StringConcatenate(PREFIX_TEXT, i, "_min_", minimum[i]); ObjectCreate(n, OBJ_TEXT, 0, Time[i], Low[i] - OffsetForMinimums * Point); ObjectSet(n, OBJPROP_COLOR, ColorMinimum); ObjectSetText(n, "" + minimum[i], FONT_SIZE); } } // Ìàêñèìàëüíûé óðîâåíü ëèíèè ðåàëüíî if(last_level > MaximalLineLevel) { k = MaximalLineLevel; } else { k = last_level; } // Îòðèñîâêà ëèíèé çèãçàãà for(i = MinimalLineLevel; i <= k; i++) { if(OptimizeZigZag) { optimize_level(i); } prev_price = -1; for(j = Bars - 1; j >= 0; j--) { if(maximum[j] >= i) { if(prev_price > 0) { build_line(i, j, prev_time, prev_price, Time[j], High[j]); } prev_time = Time[j]; prev_price = High[j]; } if(minimum[j] >= i) { if(prev_price > 0) { build_line(i, j, prev_time, prev_price, Time[j], Low[j]); } prev_time = Time[j]; prev_price = Low[j]; } } } }
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
Series array that contains open time of each bar
Indicator Curves created:
Indicators Used:
Custom Indicators Used:
Order Management characteristics:
Other Features: