Форум » Консультации по программированию » Паттерны ПрайсЭкшен через структуру » Ответить

Паттерны ПрайсЭкшен через структуру

evbut: Игорь добрый день! Перенесу сюда свои мытарства с перепрограммированием индикатора по паттернам под свои нужды. В той ветке я показал, что кое-какие сдвиги к получению желаемого мной результата есть. В текущем варианте как вы видели по картинкам он уже отрисовывает паттерны и их цели, способен перекрасить паттерны, если его таргет пробит. Вопрос по удалению перекрытых паттернов пока откладываю на потом, поскольку возник более актуальный. Повторю здесь кусок кода, где происходят главные события с паттернами: [more] [quote]void FindAndShowPatterns(int index) { int startBar, patternDir,patternName; GetData(index,startBar,patternDir,patternName); double lowPrice = ND(Low[iLowest(NULL, 0, MODE_LOW, // Нижняя граница паттерна startBar - index + 1, index)]); double highPrice = ND(High[iHighest(NULL, 0, MODE_HIGH, // Верхняя граница паттерна startBar - index + 1, index)]); double patternHeight = highPrice - lowPrice; double BuyTP = ND(lowPrice + patternHeight * FiboTarget / 100.0); double SellTP = ND(highPrice - patternHeight * FiboTarget / 100.0); // string nameofpattern = PatternName(patternName); int patternArray = ArraySize(g_patterns); if(patternDir !=0) { if( ArrayResize(g_patterns, patternArray+1, ARRAY_RESERVE_SIZE) < 0) { Alert(WindowExpertName(),(g_isRussianLang)? ": Недостаточно памяти для продолжения работы программы. Индикатор отключен.": ": Not enough memory to continue work the program. Indicator is turned off."); } g_patterns[patternArray].patternType = patternDir; g_patterns[patternArray].patternName = patternName; g_patterns[patternArray].leftBarIndex = startBar; g_patterns[patternArray].rightBarIndex = index; g_patterns[patternArray].patternHighPrice = highPrice; g_patterns[patternArray].patternLowPrice = lowPrice; if(patternDir == BEAR_TYPE) g_patterns[patternArray].patternColor = RegcolorBears; else g_patterns[patternArray].patternColor = RegcolorBulls; if(patternDir == BULL_TYPE) g_patterns[patternArray].patternTarget = BuyTP; else g_patterns[patternArray].patternTarget = SellTP; //Проверка паттерна на отработку таргета if(IsShowWorked) for(int i = ArraySize(g_patterns)-1; i >= 0; i--) { if(g_patterns.patternType == BEAR_TYPE) { for(int k = g_patterns.rightBarIndex-1; k >= 0; k--) { if(iLow(NULL, 0, k) < g_patterns.patternTarget) g_patterns.patternColor = WorkColor; } } if(g_patterns.patternType == BULL_TYPE) { for(int k = g_patterns.rightBarIndex-1; k >= 0; k--) { if(iHigh(NULL, 0, k) > g_patterns.patternTarget) g_patterns.patternColor = WorkColor; } } } // == Запишем факт отработки паттерна ====================== int getTarget = IsActualPattern(g_patterns[patternArray]); g_patterns[patternArray].getTarget = getTarget; // === Отрисуем паттерны =========== /*if(!IsShowALLPatterns) DeleteAnyPattern(g_patterns[patternArray], index); */ // Удаление перекрытых паттернов if(IsRectangleShow) { string name = GetUniqueID(g_patterns[patternArray], FIRST_PART); /*string name = GetObjectName(g_patterns[patternArray].rightBarIndex, g_patterns[patternArray].patternType, FIRST_PART);// Имя объекта паттерна*/ ShowRectangle(name, Time[g_patterns[patternArray].leftBarIndex], g_patterns[patternArray].patternLowPrice, Time[g_patterns[patternArray].rightBarIndex],g_patterns[patternArray].patternHighPrice, "",g_patterns[patternArray].patternColor); } /*string name = GetObjectName(g_patterns[patternArray].rightBarIndex, g_patterns[patternArray].patternType, SECOND_PART);// Имя объекта паттерна */ string name = GetUniqueID(g_patterns[patternArray], SECOND_PART); ShowTarget(name, Time[g_patterns[patternArray].leftBarIndex], g_patterns[patternArray].patternTarget, Time[g_patterns[patternArray].rightBarIndex], g_patterns[patternArray].patternTarget, "",g_patterns[patternArray].patternColor); [/quote][/more] Отображает он все как мне хотелось бы. При наведении мышки на паттерн отображает информацию из функции GetUniqueID: [quote]string GetUniqueID(const Pattern & pattern, string middlePart) { return(PREFIX + EnumToString(pattern.patternName)+EnumToString(pattern.getTarget)+"_" +EnumToString(pattern.patternType)+ middlePart + string(Time[pattern.rightBarIndex])); } [/quote] Но тут где-то собака зарылась, не пойму относительно отображения EnumToString(pattern.getTarget), которая определяется отдельной функцией (кстати подобными строками перекрашиваются паттерны): [quote] int IsActualPattern(Pattern &pattern) { for(int i = ArraySize(g_patterns)-1; i >= 0; i--) { if(g_patterns.patternType == BEAR_TYPE) { for(int k = g_patterns.rightBarIndex-1; k >= 0; k--) { if(iLow(NULL, 0, k) < g_patterns.patternTarget) g_patterns.getTarget = WORKED; else g_patterns.getTarget = ACTUAL; } } if(g_patterns.patternType == BULL_TYPE) { for(int k = g_patterns.rightBarIndex-1; k >= 0; k--) { if(iHigh(NULL, 0, k) > g_patterns.patternTarget) g_patterns.getTarget = WORKED; else g_patterns.getTarget = ACTUAL; } } } return (g_patterns[ArraySize(g_patterns)-1].getTarget); } [/quote] Так вот... Eсли медвежий паттерн отработан (WORKED) - то окрашивается он как отработанный, и в подписи к нему EnumToString(pattern.getTarget) пишет WORKED, а вот с бычьими почему-то не пишет... окрашивает как отработанный, но в подписи и в принте пишет что он актуальный (см. рис). Как побороть это недоразумение? Сдается мне что тут вина в implicit enum conversion в строке g_patterns[patternArray].getTarget = getTarget, его энум [more][quote] enum ENUM_GET_TARGET { NONE , ACTUAL, //Actual pattern WORKED //Worked pattern }; [/quote][/more] Кроме этого таких предупреждений еще два штуки есть по коду в строках: g_patterns[patternArray].patternType = patternDir, его Энум выглядит так [more][quote] enum ENUM_PATTERN_TYPE { NONE_TYPE, //0 - No pattern BULL_TYPE, //1 - Bull pattern BEAR_TYPE, //2 - bear pattern }; [/quote][/more] и g_patterns[patternArray].patternName = patternName, его энум [more][quote] enum ENUM_PATTERN_NAME { NONE_INDEX = -1, RAILS_ = 0, OVB_ = 1, PPR_ = 2 }; [/quote][/more] Ну и все они в структуре объявлены и инициализированы вот так patternType = NONE_TYPE; patternName = NONE_INDEX; getTarget = NONE; И на всякий случай функция GetData [more][quote] void GetData(int index, int& startBar, int &type, int &patternName) { //- 1 - == Определим тип найденного паттерна по направлению ===================== if(IsBullsRailsPattern(index)|| IsBUOVBPattern(index) || IsBullsPPRPattern(index)) type = BULL_TYPE; if(IsBearsRailsPattern(index) || IsBEOVBPattern(index)|| IsBearsPPRPattern(index)) type = BEAR_TYPE; //- 1 - == Конец =============================================================== //- 2 - == Определим левую границу найденного паттерна ========================= if(IsBullsPPRPattern(index) || IsBearsPPRPattern(index)) startBar = index+2; if(IsBUOVBPattern(index) || IsBEOVBPattern(index)|| IsBearsRailsPattern(index) || IsBullsRailsPattern(index)) startBar = index+1; //- 2 - == Конец =============================================================== //- 3 - == Ообозначим паттерн по названию======================================= if(IsBullsRailsPattern(index) || IsBearsRailsPattern(index)) patternName = RAILS_; if(IsBUOVBPattern(index) || IsBEOVBPattern(index)) patternName = OVB_; if(IsBullsPPRPattern(index)|| IsBearsPPRPattern(index)) patternName = PPR_; //- 3 - == Конец =============================================================== } [/quote][/more] Ткните, плиз носом, как победить этот недуг Просмотрев немного по истории, точной закономерности не выявил, но вот покажу участок, где стрелками показаны два по рассраске отработанных бычьих паттерна, между ними 8 свечей (две стрелки указывают на один и тот паттерн). Но подписи у них разные... тот что ниже слева - пишет WORKED, а тот что через 8 свечей справа - ACTUAL. Чо к чему... не пойму А главное как так-то? Может в коде какого дополнительного условия не хватает в функции IsActualPattern? Или это не понятные примудрусти какие-то в функции строки подписи? [more][quote] //+-------------------------------------------------------------------------------------+ string GetUniqueID(const Pattern & pattern, string middlePart) { return(PREFIX + EnumToString(pattern.patternName)+EnumToString(pattern.getTarget)+"_" +EnumToString(pattern.patternType)+ "\n"+ middlePart +"\n" + "TARGET = " + DoubleToString(pattern.patternTarget,_Digits)); } [/quote][/more]

Ответов - 87, стр: 1 2 3 4 5 6 All

Scriptong: evbut пишет: Но тут где-то собака зарылась, не пойму относительно отображения EnumToString(pattern.getTarget), которая определяется отдельной функцией (кстати подобными строками перекрашиваются паттерны): Проблема в том, что нужно прерывать цикл после того, как найден пробой цели. А у Вас после этого проверяются свечи далее. Они могут не достигать цели. В итоге паттерн будет снова подписан как WORKED. Таким образом, проблема будет не только с бычьими, но и с медвежьими паттернами.

evbut: Scriptong пишет: Таким образом, проблема будет не только с бычьими, но и с медвежьими паттернами. Оно так и есть, я лишь на примере бычьих показал... Какими-то участками то бычьи, то медвежьи не верно запоминает (( Не думал, что один и тот же код по разному воспринимается переменными, в частности enum... В общем и эта проблема решилась... Оставил код определения факта отработки такой же как и для цвета, а энум оставил такой enum ENUM_GET_TARGET { ACTUAL, //Актуальный WORKED }; Ведь по хорошему нет же паттерна с типом NONE, неопределенным цветом, с неизвесным таргетом и прочими отсутствующими характеристиками в базе данных паттерна.

Scriptong: evbut пишет: В общем и эта проблема решилась... Оставил код определения факта отработки такой же как и для цвета, а энум оставил такой Перечисление в данном случае не при чем. Не нужно было его менять. NONE - это тип неопределенного паттерна. Он необходим для правильной работы индикатора. По всей видимости, Вы не поняли, в чем именно проблема. В таком случае попытаюсь объяснить еще раз. В приведенном коде видно, что проверка достижения цели паттерна происходит на всем участке истории от момента формирования паттерна до нулевого бара. И это правильно. Но упущен важный момент: когда найдено достижение цели паттерна, требуется прекращение дальнейшего хода цикла. К примеру, найден паттерн на баре с индексом 5. После этого запускается цикл поиска достижения цели от бара с индексом 4 до текущего бара (с индексом 0). Допустим, цель достигнута на 3-ем баре, а после этого цена откатила и больше не достигала цели. Приведенный код поставит на 3-ем баре признак WORKED, но потом перейдет к барам 2, 1 и 0, где цель не достигнута, и вернет признак ACTUAL обратно. А нужно сделать так, чтобы признак ACTUAL уже не мог быть установлен, если признак WORKED имеется.


evbut: Scriptong пишет: По всей видимости, Вы не поняли, в чем именно проблема. В таком случае попытаюсь объяснить еще раз. ... Но упущен важный момент: когда найдено достижение цели паттерна, требуется прекращение дальнейшего хода цикла. ... Этот момент я понимаю, не вразумлю только в каком месте цикла нужно брикнуть, чтоб срабатывала проверка Новый обнаруженный паттерн обозначает как ACTUAL, но не перепроверяется на актуальность база паттернов ладе на новой свече... Видимо для этого дела лучше делать отдельную функцию ведь эта проверка всего лишь условие не являющееся обязательным - if(ShowWorkedpattern) - чтобы вносить ее в БД

Scriptong: evbut пишет: Этот момент я понимаю, не вразумлю только в каком месте цикла нужно брикнуть, чтоб срабатывала проверка Как только обнаружено достижение цели (WORKED) нужно выходить из цикла, чтобы не перезаписать вновь значение ACTUAL. Хотя в Вашем случае более уместно добавить проверку в цикл k: int IsActualPattern(Pattern &pattern) { for(int i = ArraySize(g_patterns)-1; i >= 0; i--) { if(g_patterns.patternType == BEAR_TYPE) { for(int k = g_patterns.rightBarIndex-1; k >= 0 && g_patterns.patternTarget == ACTUAL; k--) { if(iLow(NULL, 0, k) < g_patterns.patternTarget) g_patterns.getTarget = WORKED; else g_patterns.getTarget = ACTUAL; } } if(g_patterns.patternType == BULL_TYPE) { for(int k = g_patterns.rightBarIndex-1; k >= 0 && g_patterns.patternTarget == ACTUAL; k--) { if(iHigh(NULL, 0, k) > g_patterns.patternTarget) g_patterns.getTarget = WORKED; else g_patterns.getTarget = ACTUAL; } } } return (g_patterns[ArraySize(g_patterns)-1].getTarget); }

evbut: Scriptong пишет: К примеру, найден паттерн на баре с индексом 5. После этого запускается цикл поиска достижения цели от бара с индексом 4 до текущего бара (с индексом 0). Допустим, цель достигнута на 3-ем баре, а после этого цена откатила и больше не достигала цели. Приведенный код поставит на 3-ем баре признак WORKED, но потом перейдет к барам 2, 1 и 0, где цель не достигнута, и вернет признак ACTUAL обратно. А нужно сделать так, чтобы признак ACTUAL уже не мог быть установлен, если признак WORKED имеется. А принты не говорят об этом, а показывают отработан паттерн. Вывел специально текстовое описание паттерна, которое показывает тип паттерна и его отработанность... Все говорит о том, что Ваша верная логическая цепочка не работает дальше момента, когда цель достигнута на 3-ьем баре, на барах со 2 по 0 факт WORKED не переписывается. Или я самообманываюсь? //+-------------------------------------------------------------------------------------+ //| Актуален ли паттерна | //+-------------------------------------------------------------------------------------+ ENUM_GET_TARGET IsActualPattern(Pattern &pattern) { for(int i=ArraySize(g_patterns)-1; i>=0; i--) { if(g_patterns.patternType==BEAR_TYPE) { for(int k=g_patterns.rightBarIndex; k>=0; k--) { if(iLow(NULL,0,k)<g_patterns.patternTarget) g_patterns.getTarget=WORKED; } } if(g_patterns.patternType==BULL_TYPE) { for(int k=g_patterns.rightBarIndex; k>=0; k--) { if(iHigh(NULL,0,k)>g_patterns.patternTarget) g_patterns.getTarget=WORKED; } } } return (g_patterns[ArraySize(g_patterns)-1].getTarget); } Объясните почему в энуме по отработке стоит оставить NONE? Ведь по сути у паттерна не может быть такого состояния. Как только паттерн обнаружился он по факту ACTUAL пусть даже на долю секунды на минутном графике при выходе новостей и бешенной скорости изменения цены.

Scriptong: evbut пишет: Объясните почему в энуме по отработке стоит оставить NONE? Ведь по сути у паттерна не может быть такого состояния. В момент инициализации паттерна такое значение может быть. То есть когда паттерна нет (он не ACTUAL и не WORKED).

evbut: Игорь, подскажите, как заставить индикатор рисовать в тестере? Тяжко на минутном графике даже выжидать как он работает в реале )) Но таки высмотрел такой момент.Функцию FindAndShowPatterns малость переделал void FindAndShowPatterns(int index) { int startBar=GetStartBar(index); double lowPrice=Low[iLowest(NULL,0,MODE_LOW,// Нижняя граница паттерна startBar-index+1,index)]; double highPrice=High[iHighest(NULL,0,MODE_HIGH,// Верхняя граница паттерна startBar-index+1,index)]; double patternHeight=highPrice-lowPrice; double BuyTP=lowPrice+patternHeight*FiboTarget/100.0; double SellTP=highPrice-patternHeight*FiboTarget/100.0; int patternArray=ArraySize(g_patterns); if(PatternDir(index)!=0) { if(ArrayResize(g_patterns,patternArray+1,ARRAY_RESERVE_SIZE)<0) { Alert(WindowExpertName(),(g_isRussianLang)? ": Недостаточно памяти для продолжения работы программы. Индикатор отключен.": ": Not enough memory to continue work the program. Indicator is turned off."); } g_patterns[patternArray].patternType = PatternDir(index); g_patterns[patternArray].patternName = Name(index); g_patterns[patternArray].leftBarIndex = startBar; g_patterns[patternArray].rightBarIndex = index; g_patterns[patternArray].patternHighPrice = highPrice; g_patterns[patternArray].patternLowPrice = lowPrice; if(PatternDir(index)==BULL_TYPE) g_patterns[patternArray].patternTarget = BuyTP; else g_patterns[patternArray].patternTarget = SellTP; // Is pattern Worked? g_patterns[patternArray].getTarget = IsPatternWorked(g_patterns[patternArray]); // Base on getTarget define Pattern COLOR ... if(IsPatternWorked(g_patterns[patternArray]) == ACTUAL) { if(PatternDir(index)==BEAR_TYPE ) g_patterns[patternArray].patternColor = RegcolorBears; else g_patterns[patternArray].patternColor = RegcolorBulls; } else g_patterns[patternArray].patternColor = WorkColor; // === Отрисуем паттерны =========== if(IsRectangleShow) { string name=GetUniqueID(g_patterns[patternArray],FIRST_PART); ShowRectangle(name,Time[g_patterns[patternArray].leftBarIndex],g_patterns[patternArray].patternLowPrice, Time[g_patterns[patternArray].rightBarIndex],g_patterns[patternArray].patternHighPrice, "",g_patterns[patternArray].patternColor); } if(showtarget) { string name=GetUniqueID(g_patterns[patternArray],SECOND_PART); ShowTarget(name,Time[g_patterns[patternArray].leftBarIndex],g_patterns[patternArray].patternTarget, Time[g_patterns[patternArray].rightBarIndex],g_patterns[patternArray].patternTarget, "",g_patterns[patternArray].patternColor); } // ALERT static datetime lastAlert = 0; SignalOnPattern(g_patterns[patternArray], isAlert,index,lastAlert,soundpattern); } } Как бы функция работает и новые паттерны рисует, и алерт срабатывает но...- почему-то не перекрашивает паттерны в цвет отработанных в режиме онлайн, только после обновления графика или переключением таймфреймов. В OnCalculate вот так прописано int total; int limit=GetRecalcIndex(total,rates_total,prev_calculated); // Определим первый расчетный бар for(int i=limit; i>0; i--) // Обработаем все новые бары { FindAndShowPatterns(i); ChartRedraw(); } return rates_total; НЕ пойму почему, подскажите, пожалуйста

Scriptong: evbut пишет: НЕ пойму почему, подскажите, пожалуйста Скорее всего, проблема в функции отображения паттерна. Покажите ее код (ShowRectangle)

evbut: Scriptong пишет: Покажите ее код (ShowRectangle) void ShowRectangle(string name,datetime time1,double price1,datetime time2, double price2,string toolTip,color clr) { if(ObjectFind(name)<0) // Если объект не существует { ObjectCreate(0,name,OBJ_RECTANGLE,0,time1,price1,time2,price2); ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false); ObjectSetInteger(0,name,OBJPROP_WIDTH,LineWidth); ObjectSetInteger(0,name,OBJPROP_STYLE,LineStyle); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_BACK,FillRectangle); ObjectSetString(0,name,OBJPROP_TOOLTIP,toolTip); return; } ObjectMove(name,0, time1, price1); // Перемещение существующего объекта ObjectMove(name, 1, time2, price2); // Перемещение существующего объекта }

Scriptong: evbut пишет: Покажите ее код (ShowRectangle) Как я и предполагал, здесь недоработка. Функция не содержит кода, который изменяет цвет объекта, если он уже создан. Посмотрите внимательно: если объект уже существует, то будет изменена только его цена, но не цвет. Нужно в таких случаях изменять еще и цвет: void ShowRectangle(string name,datetime time1,double price1,datetime time2, double price2,string toolTip,color clr) { if(ObjectFind(name)<0) // Если объект не существует { ObjectCreate(0,name,OBJ_RECTANGLE,0,time1,price1,time2,price2); ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false); ObjectSetInteger(0,name,OBJPROP_WIDTH,LineWidth); ObjectSetInteger(0,name,OBJPROP_STYLE,LineStyle); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_BACK,FillRectangle); ObjectSetString(0,name,OBJPROP_TOOLTIP,toolTip); return; } ObjectMove(name,0, time1, price1); // Перемещение существующего объекта ObjectMove(name, 1, time2, price2); // Перемещение существующего объекта ObjectSetInteger(0,name,OBJPROP_COLOR,clr); }

evbut: Scriptong пишет: Как я и предполагал, здесь недоработка. Функция не содержит кода, который изменяет цвет объекта, если он уже создан. Посмотрите внимательно: если объект уже существует, то будет изменена только его цена, но не цвет. Нужно в таких случаях изменять еще и цвет: Добавил не достающую строку, всю равно не перекрашивает (( Вся перекраска происходит только после обновления графика или в момент инициализации индикатора. Такое ощущение, что чего-то не хватает, где-то чего не учел я - не соображу... уже голову наизнанку вывернул. Уже и функцию цвета переделал под манер функции проверки ACTUAL или WORKED паттерн (ее пока оставил, ибо не удобно следить). Видно надо перекур сделать )) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_GET_TARGET { NONE, ACTUAL,//Актуальный WORKED }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_PATTERN_TYPE { NONE_TYPE, //0 - No pattern BULL_TYPE, //1 - Bull pattern BEAR_TYPE, //2 - bear pattern }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_FUNCTION_RESULT { FUNCTION_RESULT_OK, // The successful ending of function run FUNCTION_RESULT_ALRIGHT, // The not successful ending of function run but no has critical errors FUNCTION_RESULT_FATAL // The fatal error ending of function run }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_PATTEN_NAME { NONE_INDEX=-1, RAILS_= 0, OVB_ = 1, PPR_ = 2 }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct Pattern { ENUM_PATTERN_TYPE patternType; // Тип паттерна (бычий, медвежий) ENUM_PATTEN_NAME patternName; // Индекс имени паттерна ENUM_GET_TARGET getTarget; // Отработан ли патерна int leftBarIndex; // Индекс левого бара паттерна int rightBarIndex; // Индекс правого бара паттерна double patternLowPrice; // Нижняя цена паттерна double patternHighPrice; // Верхняя цена паттерна double patternHeight; // Высота паттерна double patternTarget; // Уровень цели бычьего паттерна color patternColor; // ЦВет паттерна Pattern() { Init(); } void Init() { patternType = NONE_TYPE; patternName = NONE_INDEX; getTarget = NONE; leftBarIndex = -1; rightBarIndex = -1; patternTarget = 0.0; patternLowPrice = 0.0; patternHighPrice = 0.0; patternHeight = 0.0; patternColor = clrNONE; } }; Pattern g_patterns[]; // Массив всех паттернов //+-------------------------------------------------------------------------------------+ //| Custom indicator initialization function | //+-------------------------------------------------------------------------------------+ int OnInit() { if(!IsTuningParametersCorrect()) return INIT_FAILED; g_activate = true; return INIT_SUCCEEDED; } //+-------------------------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+-------------------------------------------------------------------------------------+ void OnDeinit(const int reason) { DeleteAllObjects(); } bool IsTuningParametersCorrect() { g_isRussianLang=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian"); return(true); } //+-------------------------------------------------------------------------------------+ //| Удаление всех объектов, созданных индикатором | //+-------------------------------------------------------------------------------------+ void DeleteAllObjects() { for(int i=ObjectsTotal()-1; i>=0; i--) if(StringSubstr(ObjectName(i),0,StringLen(PREFIX))==PREFIX) ObjectDelete(ObjectName(i)); } //+-------------------------------------------------------------------------------------+ //| Определение индекса бара, с которого необходимо производить перерасчет | //+-------------------------------------------------------------------------------------+ int GetRecalcIndex(int &total,const int ratesTotal,const int prevCalculated) { total=ratesTotal-3; if(indBarsCount>0 && indBarsCount<total) total=MathMin(indBarsCount,total); if(prevCalculated<ratesTotal-1) { DeleteAllObjects(); return (total); } return (MathMin(ratesTotal - prevCalculated, total)); } //+-------------------------------------------------------------------------------------+ //| Отображение графического объекта - прямоугольника | //+-------------------------------------------------------------------------------------+ void ShowRectangle(string name,datetime time1,double price1,datetime time2, double price2,string toolTip,color clr) { if(ObjectFind(0,name)<0) // Если объект не существует { ObjectCreate(0,name,OBJ_RECTANGLE,0,time1,price1,time2,price2); ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false); ObjectSetInteger(0,name,OBJPROP_WIDTH,LineWidth); ObjectSetInteger(0,name,OBJPROP_STYLE,LineStyle); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_BACK,FillRectangle); ObjectSetString(0,name,OBJPROP_TOOLTIP,toolTip); return; } ObjectMove(0,name,0, time1, price1); // Перемещение существующего объекта ObjectMove(0,name, 1, time2, price2); // Перемещение существующего объекта ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetString(0,name,OBJPROP_TOOLTIP,toolTip); } //+-------------------------------------------------------------------------------------+ //| Определение типа паттерна по направлению | //+-------------------------------------------------------------------------------------+ ENUM_PATTERN_TYPE PatternDir(int index) { if(IsBullsRailsPattern(index) || IsBUOVBPattern(index) || IsBullsPPRPattern(index)) return BULL_TYPE; if(IsBearsRailsPattern(index) || IsBEOVBPattern(index) || IsBearsPPRPattern(index)) return BEAR_TYPE; return NONE_TYPE; } //+-------------------------------------------------------------------------------------+ //| Зададим имя паттерна | //+-------------------------------------------------------------------------------------+ ENUM_PATTEN_NAME NamePattern(int index) { if(IsBullsRailsPattern(index) || IsBearsRailsPattern(index)) return RAILS_; if(IsBUOVBPattern(index) || IsBEOVBPattern(index)) return OVB_; if(IsBullsPPRPattern(index) || IsBearsPPRPattern(index)) return PPR_; return NONE_INDEX; } //+-----------------------------------------------------------------------------+ //| Определение левой гранийы паттерна | //+-----------------------------------------------------------------------------+ int GetStartBar(int index) { if(IsBullsPPRPattern(index) || IsBearsPPRPattern(index)) return index+2; if(IsBUOVBPattern(index) || IsBEOVBPattern(index) || IsBearsRailsPattern(index) || IsBullsRailsPattern(index)) return index+1; return 0; } //+-----------------------------------------------------------------------------+ //| Отрисуем паттерны | //+-----------------------------------------------------------------------------+ void ShowPatterns( Pattern& pattern) { if(IsRectangleShow) { string name=GetUniqueID(pattern,FIRST_PART); ShowRectangle(name,Time[pattern.leftBarIndex],pattern.patternLowPrice, Time[pattern.rightBarIndex],pattern.patternHighPrice, "",pattern.patternColor); } if(showtarget) { string name=GetUniqueID(pattern,SECOND_PART); ShowTarget(name,Time[pattern.leftBarIndex],pattern.patternTarget, Time[pattern.rightBarIndex],pattern.patternTarget, "",pattern.patternColor); } // ALERT if(isAlert) { static datetime lastAlert = 0; SignalOnPattern(pattern, isAlert,0,lastAlert,soundpattern); } } //+-----------------------------------------------------------------------------+ //| Заполнение массива и отрисовка паттернов | //+-----------------------------------------------------------------------------+ ENUM_FUNCTION_RESULT FillDBPatterns(int index) { if(PatternDir(index)!=0) { ENUM_PATTERN_TYPE newPattern = PatternDir(index); ENUM_PATTEN_NAME newPatternName = NamePattern(index); int startBar = GetStartBar(index); int endBar = index; double lowPrice = Low[iLowest(NULL,0,MODE_LOW,// Нижняя граница паттерна startBar-endBar+1,endBar)]; double highPrice = High[iHighest(NULL,0,MODE_HIGH,// Верхняя граница паттерна startBar-endBar+1,endBar)]; double patternHeight = highPrice - lowPrice; double BuyTP = lowPrice + patternHeight * FiboTarget / 100.0; double SellTP = highPrice - patternHeight * FiboTarget / 100.0; int patternArray=ArraySize(g_patterns); if(ArrayResize(g_patterns,patternArray + 1, ARRAY_RESERVE_SIZE) < 0) { Alert(WindowExpertName(),(g_isRussianLang)? ": Недостаточно памяти для продолжения работы программы. Индикатор отключен.": ": Not enough memory to continue work the program. Indicator is turned off."); return FUNCTION_RESULT_FATAL; } g_patterns[patternArray].patternType = newPattern; g_patterns[patternArray].patternName = newPatternName; g_patterns[patternArray].leftBarIndex = startBar; g_patterns[patternArray].rightBarIndex = endBar; g_patterns[patternArray].patternHighPrice = highPrice; g_patterns[patternArray].patternLowPrice = lowPrice; if(newPattern == BULL_TYPE) g_patterns[patternArray].patternTarget = BuyTP; else g_patterns[patternArray].patternTarget = SellTP; g_patterns[patternArray].patternColor = RecolorPattern(g_patterns[patternArray]); Print(" Pattetn Count " +string(patternArray) + // " Pattern Start Bar " + g_patterns[patternArray].leftBarIndex + " Pattern End Bar " + string(g_patterns[patternArray].rightBarIndex) + " Pattern Type " + EnumToString(g_patterns[patternArray].patternType) + " Pattern Name " + EnumToString(g_patterns[patternArray].patternName)+ " Pattern Target " + DoubleToString(g_patterns[patternArray].patternTarget,_Digits) + // " Pattern High " + g_patterns[patternArray].patternHighPrice + " Is Pattern ACTUAL " + EnumToString(g_patterns[patternArray].getTarget)); } return FUNCTION_RESULT_OK; } //+-------------------------------------------------------------------------------------+ //| Recolor by pattern actuality | //+-------------------------------------------------------------------------------------+ color RecolorPattern(Pattern &pattern) { for(int i=ArraySize(g_patterns)-1; i>=0; i--) { if(g_patterns.patternType == BEAR_TYPE) { for(int k = g_patterns.rightBarIndex; k >= 0; k--) { if(ShowWorkedPattern && iLow(NULL,0,k) < g_patterns.patternTarget) { g_patterns.patternColor = WorkColor; break; } else g_patterns.patternColor = RegcolorBears; } } if(g_patterns.patternType == BULL_TYPE) { for(int k = g_patterns.rightBarIndex; k >= 0; k--) { if(ShowWorkedPattern && iHigh(NULL,0,k )> g_patterns.patternTarget) { g_patterns.patternColor = WorkColor; break; } else g_patterns.patternColor = RegcolorBulls; } } } return (g_patterns[ArraySize(g_patterns)-1].patternColor); } //+-------------------------------------------------------------------------------------+ //| Process the specified bar | //+-------------------------------------------------------------------------------------+ bool ProcessBar(int index) { if(PatternDir(index)) { ENUM_FUNCTION_RESULT result = FillDBPatterns(index); if (result == FUNCTION_RESULT_FATAL) return false; if (result == FUNCTION_RESULT_ALRIGHT) return true; ShowPatterns(g_patterns[ArraySize(g_patterns)-1]); } return true; } //+-------------------------------------------------------------------------------------+ //| Display Value | //+-------------------------------------------------------------------------------------+ bool ShowIndicatorData(int limit, int total) { for (int i = limit; i > 0; i--) ProcessBar(i); return true; } //+-------------------------------------------------------------------------------------+ //| Custom indicator iteration function | //+-------------------------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { // - 1 - == Организационные действия ==================================================== int total; // Индекс наиболее раннего в истории.. // ..бара int limit=GetRecalcIndex(total,rates_total,prev_calculated); // Определим первый расчетный бар if (!ShowIndicatorData(limit, total)) g_activate = false; WindowRedraw(); return rates_total; }

Scriptong: evbut пишет: Добавил не достающую строку, всю равно не перекрашивает (( Вся перекраска происходит только после обновления графика или в момент инициализации индикатора. Такое ощущение, что чего-то не хватает, где-то чего не учел я - не соображу... уже голову наизнанку вывернул. Уже и функцию цвета переделал под манер функции проверки ACTUAL или WORKED паттерн (ее пока оставил, ибо не удобно следить). Видно надо перекур сделать )) Давайте тогда уже весь индикатор (приаттачьте через dropmefiles или любой другой ресурс). Ведь по обрывку кода трудно что-то сказать.

evbut: Scriptong пишет: Давайте тогда уже весь индикатор Тынц Ссыль действительна 6 дней

Scriptong: evbut пишет: Тынц Ссыль действительна 6 дней Скачал. Посмотрю уже в следующем году



полная версия страницы