Отправлено: 16.12.16 05:39. Заголовок: Паттерны ПрайсЭкшен через структуру
Игорь добрый день! Перенесу сюда свои мытарства с перепрограммированием индикатора по паттернам под свои нужды. В той ветке я показал, что кое-какие сдвиги к получению желаемого мной результата есть. В текущем варианте как вы видели по картинкам он уже отрисовывает паттерны и их цели, способен перекрасить паттерны, если его таргет пробит. Вопрос по удалению перекрытых паттернов пока откладываю на потом, поскольку возник более актуальный. Повторю здесь кусок кода, где происходят главные события с паттернами: Скрытый текст
цитата:
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;
Но тут где-то собака зарылась, не пойму относительно отображения EnumToString(pattern.getTarget), которая определяется отдельной функцией (кстати подобными строками перекрашиваются паттерны):
Так вот... Eсли медвежий паттерн отработан (WORKED) - то окрашивается он как отработанный, и в подписи к нему EnumToString(pattern.getTarget) пишет WORKED, а вот с бычьими почему-то не пишет... окрашивает как отработанный, но в подписи и в принте пишет что он актуальный (см. рис). Как побороть это недоразумение? Сдается мне что тут вина в implicit enum conversion в строке g_patterns[patternArray].getTarget = getTarget, его энум Скрытый текст
Кроме этого таких предупреждений еще два штуки есть по коду в строках: g_patterns[patternArray].patternType = patternDir, его Энум выглядит так Скрытый текст
Ну и все они в структуре объявлены и инициализированы вот так patternType = NONE_TYPE; patternName = NONE_INDEX; getTarget = NONE; И на всякий случай функция GetData Скрытый текст
цитата:
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 - == Конец ===============================================================
Просмотрев немного по истории, точной закономерности не выявил, но вот покажу участок, где стрелками показаны два по рассраске отработанных бычьих паттерна, между ними 8 свечей (две стрелки указывают на один и тот паттерн). Но подписи у них разные... тот что ниже слева - пишет WORKED, а тот что через 8 свечей справа - ACTUAL.
Чо к чему... не пойму А главное как так-то? Может в коде какого дополнительного условия не хватает в функции IsActualPattern? Или это не понятные примудрусти какие-то в функции строки подписи? Скрытый текст
Отправлено: 16.12.16 18:57. Заголовок: evbut пишет: Но тут..
evbut пишет:
цитата:
Но тут где-то собака зарылась, не пойму относительно отображения EnumToString(pattern.getTarget), которая определяется отдельной функцией (кстати подобными строками перекрашиваются паттерны):
Проблема в том, что нужно прерывать цикл после того, как найден пробой цели. А у Вас после этого проверяются свечи далее. Они могут не достигать цели. В итоге паттерн будет снова подписан как WORKED. Таким образом, проблема будет не только с бычьими, но и с медвежьими паттернами.
Таким образом, проблема будет не только с бычьими, но и с медвежьими паттернами.
Оно так и есть, я лишь на примере бычьих показал... Какими-то участками то бычьи, то медвежьи не верно запоминает (( Не думал, что один и тот же код по разному воспринимается переменными, в частности enum... В общем и эта проблема решилась... Оставил код определения факта отработки такой же как и для цвета, а энум оставил такой
цитата:
enum ENUM_GET_TARGET { ACTUAL, //Актуальный WORKED };
Ведь по хорошему нет же паттерна с типом NONE, неопределенным цветом, с неизвесным таргетом и прочими отсутствующими характеристиками в базе данных паттерна.
Отправлено: 19.12.16 16:23. Заголовок: evbut пишет: В обще..
evbut пишет:
цитата:
В общем и эта проблема решилась... Оставил код определения факта отработки такой же как и для цвета, а энум оставил такой
Перечисление в данном случае не при чем. Не нужно было его менять. NONE - это тип неопределенного паттерна. Он необходим для правильной работы индикатора. По всей видимости, Вы не поняли, в чем именно проблема. В таком случае попытаюсь объяснить еще раз. В приведенном коде видно, что проверка достижения цели паттерна происходит на всем участке истории от момента формирования паттерна до нулевого бара. И это правильно. Но упущен важный момент: когда найдено достижение цели паттерна, требуется прекращение дальнейшего хода цикла. К примеру, найден паттерн на баре с индексом 5. После этого запускается цикл поиска достижения цели от бара с индексом 4 до текущего бара (с индексом 0). Допустим, цель достигнута на 3-ем баре, а после этого цена откатила и больше не достигала цели. Приведенный код поставит на 3-ем баре признак WORKED, но потом перейдет к барам 2, 1 и 0, где цель не достигнута, и вернет признак ACTUAL обратно. А нужно сделать так, чтобы признак ACTUAL уже не мог быть установлен, если признак WORKED имеется.
По всей видимости, Вы не поняли, в чем именно проблема. В таком случае попытаюсь объяснить еще раз. ... Но упущен важный момент: когда найдено достижение цели паттерна, требуется прекращение дальнейшего хода цикла. ...
Этот момент я понимаю, не вразумлю только в каком месте цикла нужно брикнуть, чтоб срабатывала проверка Новый обнаруженный паттерн обозначает как ACTUAL, но не перепроверяется на актуальность база паттернов ладе на новой свече... Видимо для этого дела лучше делать отдельную функцию ведь эта проверка всего лишь условие не являющееся обязательным - if(ShowWorkedpattern) - чтобы вносить ее в БД
Отправлено: 21.12.16 07:24. Заголовок: evbut пишет: Этот м..
evbut пишет:
цитата:
Этот момент я понимаю, не вразумлю только в каком месте цикла нужно брикнуть, чтоб срабатывала проверка
Как только обнаружено достижение цели (WORKED) нужно выходить из цикла, чтобы не перезаписать вновь значение ACTUAL. Хотя в Вашем случае более уместно добавить проверку в цикл k:
Отправлено: 21.12.16 05:45. Заголовок: Scriptong пишет: К ..
Scriptong пишет:
цитата:
К примеру, найден паттерн на баре с индексом 5. После этого запускается цикл поиска достижения цели от бара с индексом 4 до текущего бара (с индексом 0). Допустим, цель достигнута на 3-ем баре, а после этого цена откатила и больше не достигала цели. Приведенный код поставит на 3-ем баре признак WORKED, но потом перейдет к барам 2, 1 и 0, где цель не достигнута, и вернет признак ACTUAL обратно. А нужно сделать так, чтобы признак ACTUAL уже не мог быть установлен, если признак WORKED имеется.
А принты не говорят об этом, а показывают отработан паттерн. Вывел специально текстовое описание паттерна, которое показывает тип паттерна и его отработанность... Все говорит о том, что Ваша верная логическая цепочка не работает дальше момента, когда цель достигнута на 3-ьем баре, на барах со 2 по 0 факт WORKED не переписывается. Или я самообманываюсь?
Объясните почему в энуме по отработке стоит оставить NONE? Ведь по сути у паттерна не может быть такого состояния. Как только паттерн обнаружился он по факту ACTUAL пусть даже на долю секунды на минутном графике при выходе новостей и бешенной скорости изменения цены.
Игорь, подскажите, как заставить индикатор рисовать в тестере? Тяжко на минутном графике даже выжидать как он работает в реале )) Но таки высмотрел такой момент.Функцию 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;
Как бы функция работает и новые паттерны рисует, и алерт срабатывает но...- почему-то не перекрашивает паттерны в цвет отработанных в режиме онлайн, только после обновления графика или переключением таймфреймов. В OnCalculate вот так прописано
цитата:
int total; int limit=GetRecalcIndex(total,rates_total,prev_calculated); // Определим первый расчетный бар
for(int i=limit; i>0; i--) // Обработаем все новые бары { FindAndShowPatterns(i); ChartRedraw(); } return rates_total;
Как я и предполагал, здесь недоработка. Функция не содержит кода, который изменяет цвет объекта, если он уже создан. Посмотрите внимательно: если объект уже существует, то будет изменена только его цена, но не цвет. Нужно в таких случаях изменять еще и цвет:
цитата:
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); }
Как я и предполагал, здесь недоработка. Функция не содержит кода, который изменяет цвет объекта, если он уже создан. Посмотрите внимательно: если объект уже существует, то будет изменена только его цена, но не цвет. Нужно в таких случаях изменять еще и цвет:
Добавил не достающую строку, всю равно не перекрашивает (( Вся перекраска происходит только после обновления графика или в момент инициализации индикатора. Такое ощущение, что чего-то не хватает, где-то чего не учел я - не соображу... уже голову наизнанку вывернул. Уже и функцию цвета переделал под манер функции проверки 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; // ЦВет паттерна
//+-------------------------------------------------------------------------------------+ //| Удаление всех объектов, созданных индикатором | //+-------------------------------------------------------------------------------------+ 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;
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;
Добавил не достающую строку, всю равно не перекрашивает (( Вся перекраска происходит только после обновления графика или в момент инициализации индикатора. Такое ощущение, что чего-то не хватает, где-то чего не учел я - не соображу... уже голову наизнанку вывернул. Уже и функцию цвета переделал под манер функции проверки ACTUAL или WORKED паттерн (ее пока оставил, ибо не удобно следить). Видно надо перекур сделать ))
Давайте тогда уже весь индикатор (приаттачьте через dropmefiles или любой другой ресурс). Ведь по обрывку кода трудно что-то сказать.
Все даты в формате GMT
2 час. Хитов сегодня: 0
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет