Николай! Какой из ваших детищ с наименьшим запаздыванием и с меньшим количеством ложных сигналов (если конечно, это вообще можно определить)
Николай! Какой из ваших детищ с наименьшим запаздыванием и с меньшим количеством ложных сигналов (если конечно, это вообще можно определить)
Так что это совершенно не мой стиль программирования.
Вы не видите дерева за деревьями = вы не видите код за всеми комментариями.
Кроме того, входной параметр 'shift' вообще не используется.
Я перепрограммировал это в своем стиле, возможно, "суперпрограммисты" могут взять лист из моей книги.
//+------------------------------------------------------------------+ //|Супертренд.mq5 | //| Оригинальный код найден на https://www.mql5.com/ru/code/527 | //| Оригинальный код от Джейсона Робинсона, переписанный Николаем Косициным | //| Улучшено инж. Отто Паузером по прозвищу Кроненчакра | //+------------------------------------------------------------------+ //--- inckudes #include <Utils.mqh> //--- общие свойства #property copyright COPY #property link LINK #property version "1.00" //--- свойства индикатора #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 //--- входные параметры input int CCIPeriod = 50; // Период индикатора CCI input int ATRPeriod = 5; // Период индикатора ATR input int Level = 0; // Уровень активации CCI //---- индикаторные буферы double ATR[], CCI[]; double TrendUp[], TrendDn[]; double SignUp[], SignDn[]; //---- глобальные переменные int min_rates_total; int ATR_Handle, CCI_Handle; //+------------------------------------------------------------------+ //| Пользовательская функция инициализации индикатора | //+------------------------------------------------------------------+ int OnInit() { min_rates_total=MathMax(CCIPeriod,ATRPeriod); CCI_Handle=iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL); if(InvalidHandle(CCI_Handle,"iCCI")) return(INIT_FAILED); ATR_Handle=iATR(NULL,0,ATRPeriod); if(InvalidHandle(ATR_Handle,"iATR")) return(INIT_FAILED); string shortname=IndiShortName("Supertrend",CCIPeriod,ATRPeriod); IndicatorSetString(INDICATOR_SHORTNAME,shortname); IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1); InitBuffer(TrendUp,DRAW_LINE ,"Supertrend Up" ,clrLime,min_rates_total,0 ,2,true); InitBuffer(TrendDn,DRAW_LINE ,"Supertrend Down" ,clrRed ,min_rates_total,0 ,2,true); InitBuffer(SignUp ,DRAW_ARROW,"Supertrend signal Buy" ,clrLime,min_rates_total,108,1,true); InitBuffer(SignDn ,DRAW_ARROW,"Supertrend signal Sell",clrRed ,min_rates_total,108,1,true); ArraySetAsSeries(ATR,true); ArraySetAsSeries(CCI,true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Пользовательская функция итерации индикатора | //+------------------------------------------------------------------+ 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[]) { if // проверка ( BarsCalculated(CCI_Handle)<rates_total || // проверьте индикатор CCI BarsCalculated(ATR_Handle)<rates_total || // проверьте индикатор ATR rates_total<min_rates_total // проверьте, достаточно ли баров ) return(0); // попробуйте следующий тик int limit,to_copy,bar; ArraySetAsSeries(high,true); // необходимо устанавливать AsSeries каждый тик ArraySetAsSeries(low ,true); if(prev_calculated>rates_total || prev_calculated<=0) // проверка первого запуска расчета индикатора limit=rates_total-min_rates_total; // начальный индекс для расчета всех баров else limit=rates_total-prev_calculated; // начальный индекс для расчета новых баров to_copy=limit+1; // копируем ATR-данные в буфер if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(0); to_copy++; // копируем CCI-данные в буфер if(CopyBuffer(CCI_Handle,0,0,to_copy,CCI)<=0) return(0); for(bar=limit; bar>=0; bar--) // основной цикл расчета { TrendUp[bar]=NULL; // очистите все буферы TrendDn[bar]=NULL; SignUp [bar]=NULL; SignDn [bar]=NULL; // вычислите линии if(CCI[bar]>=Level && CCI[bar+1]<Level) TrendUp[bar]=TrendDn[bar+1]; if(CCI[bar]<=Level && CCI[bar+1]>Level) TrendDn[bar]=TrendUp[bar+1]; if(CCI[bar]>Level) { TrendUp[bar]=low[bar]-ATR[bar]; if(TrendUp[bar]<TrendUp[bar+1] && CCI[bar+1]>=Level) TrendUp[bar]=TrendUp[bar+1]; } if(CCI[bar]<Level) { TrendDn[bar]=high[bar]+ATR[bar]; if(TrendDn[bar]>TrendDn[bar+1] && CCI[bar+1]<=Level) TrendDn[bar]=TrendDn[bar+1]; } if(TrendDn[bar+1]!=0.0 && TrendUp[bar]!=0.0) SignUp[bar]=TrendUp[bar]; // проверка сигнала UP if(TrendUp[bar+1]!=0.0 && TrendDn[bar]!=0.0) SignDn[bar]=TrendDn[bar]; // проверка сигнала DOWN } return(rates_total); }
//+------------------------------------------------------------------+ //|Утилиты.mqh | //| Copyright © 2018, Ing. Отто Паузер | //| https://www.mql5.com/ru/users/kronenchakra | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| определения| //+------------------------------------------------------------------+ #define COPY "Copyright © 2018, Ing. Otto Pauser" #define LINK "https://www.mql5.com/ru/users/kronenchakra" #define SPACER "---------------------" //+------------------------------------------------------------------+ //| аббревиатуры| //+------------------------------------------------------------------+ #define PRICE ENUM_APPLIED_PRICE #define TIMEF ENUM_TIMEFRAMES //+------------------------------------------------------------------+ //| Вспомогательные функции| //+------------------------------------------------------------------+ void InitBuffer(double &_buffer[], ENUM_DRAW_TYPE _type, string _label, color _color, int _begin, int _arrow=159, int _width=1, bool _series=false) { static int idx=0; // инициализируем bufferindex в 0 SetIndexBuffer (idx,_buffer); // инициализация буфера ArrayInitialize (_buffer ,NULL); // инициализация буфера ArraySetAsSeries (_buffer ,_series); // установить AsSeries // установить свойства PlotIndexSetInteger(idx,PLOT_DRAW_TYPE ,_type ); PlotIndexSetInteger(idx,PLOT_LINE_COLOR ,_color); PlotIndexSetInteger(idx,PLOT_LINE_WIDTH ,_width); PlotIndexSetInteger(idx,PLOT_DRAW_BEGIN ,_begin); PlotIndexSetInteger(idx,PLOT_ARROW ,_arrow); PlotIndexSetString (idx,PLOT_LABEL ,_label); PlotIndexSetDouble (idx,PLOT_EMPTY_VALUE,NULL ); idx++; // увеличиваем буфериндекс для следующего вызова } bool InvalidHandle(int _handle, string _msg) { if(_handle==INVALID_HANDLE) // проверьте ручку Alert("*ERROR* creating "+_msg+" handle."); // информация return(_handle==INVALID_HANDLE); // верните true, если недействительно } string IndiShortName(string _name, int val_1, int val_2=NULL, int val_3=NULL) { string result=_name+"("+IntegerToString(val_1); if(val_2!=NULL) result=result+","+IntegerToString(val_2); if(val_3!=NULL) result=result+","+IntegerToString(val_3); return(result+")"); } //+------------------------------------------------------------------+ //| Функции вычисления| //+------------------------------------------------------------------+ double StdDeviation(int position,const double &price[],const double &MAprice[],int period) { int i; double StdDev_dTmp=0.0; if(position<period) return(StdDev_dTmp); // проверить положение for(i=0;i<period;i++) // calcualte StdDev StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2); StdDev_dTmp=MathSqrt(StdDev_dTmp/period); return(StdDev_dTmp); // возвращаем вычисленное значение }
Сразу все выглядит довольно понятно.
Возможно, MetaQutes тоже может чему-то научиться, например, как определять буферы графиков в одной строке.
Отто,
это:
TrendUp[bar]=NULL; // очистите все буферы TrendDn[bar]=NULL; SignUp [bar]=NULL; SignDn [bar]=NULL;
опасно. NULL имеет тип'void'. Когда-нибудь позже, чтобы сделать MT5 еще быстрее, возможно, ничего не будет присваиваться (тогда останется старое значение) или будет создаваться случайное значение при изменении ячейки памяти.
Имхо, было бы лучше использовать _symbol для символа и либо EMPTY_VALUE, либо 0 непосредственно для значений. Так вы дадите небытию существо ;)
Как я могу получить
Шаг 1: 
Шаг 2: 
есть ли у вас это для mt4
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
SuperTrend:
С трендовым индикатором SuperTrend работать очень просто: как только его цвет изменяется на зелёный, значит, начинается восходящий тренд, а если на красный, значит, начинается падение цены. Недостаток один - запаздывание, но, тем не менее, он пользуется спросом у трейдеров. Для наилучших результатов индикатор лучше использовать в качестве подтверждения на вход в рынок.
Автор: Nikolay Kositsin