Индикаторы: SuperTrend

 

SuperTrend:

С трендовым индикатором SuperTrend работать очень просто: как только его цвет изменяется на зелёный, значит, начинается восходящий тренд, а если на красный, значит, начинается падение цены. Недостаток один - запаздывание, но, тем не менее, он пользуется спросом у трейдеров. Для наилучших результатов индикатор лучше использовать в качестве подтверждения на вход в рынок.

Автор: Nikolay Kositsin

Индикатор SuperTrend

 

Николай! Какой из ваших детищ  с наименьшим запаздыванием и с меньшим количеством ложных сигналов (если конечно, это вообще можно определить)

 
Makser:

Николай! Какой из ваших детищ  с наименьшим запаздыванием и с меньшим количеством ложных сигналов (если конечно, это вообще можно определить)

Вот вопрос, так вопрос. Я так на кроссах, а в последнее время и на всём остальном использую JFatlSpeed. Но только на четырёхчасовиках. А отскоки  ловлю на пятиминутках по X2MA_BBx9.
 

Так что это совершенно не мой стиль программирования.

Вы не видите дерева за деревьями = вы не видите код за всеми комментариями.

Кроме того, входной параметр '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 тоже может чему-то научиться, например, как определять буферы графиков в одной строке.

Файлы:
supertrend.mq5  11 kb
Utils.mqh  7 kb
 

Отто,

это:

      TrendUp[bar]=NULL;                                 // очистите все буферы
      TrendDn[bar]=NULL;
      SignUp [bar]=NULL;
      SignDn [bar]=NULL;

опасно. NULL имеет тип'void'. Когда-нибудь позже, чтобы сделать MT5 еще быстрее, возможно, ничего не будет присваиваться (тогда останется старое значение) или будет создаваться случайное значение при изменении ячейки памяти.

Имхо, было бы лучше использовать _symbol для символа и либо EMPTY_VALUE, либо 0 непосредственно для значений. Так вы дадите небытию существо ;)

 
Как я могу получить
 
Я хочу использовать этот индикатор
 
ka03ht8096:
Как я могу получить

Шаг 1:

Шаг 2:

 
Какой вход является множителем и значением ATR?
 

есть ли у вас это для mt4