Не могу придумать как покрасить индикатор

 
Хотел на индикаторе RSI покрасить в красный цвет то, что вылазиет за уровни 30 и 70, но ни как не соображу как это можно сделать на MQL4 и вообще такое возможно?
 
можно, только стоит ли ведь красота требует жертв.
Берешь вместо одной линии две разных цветов присваиваешь им в определенном интервале одно и тоже значение, как только значение индикатора "зашкаливает" разрываешь ту что отрисовывается сверху, таким образом на этом промежутке верхняя рисоваться не будет и из под нее будет видна нижняя, та которая не видна на остальном промежутке. А так это уже давно реализовано есть стандартный триколор (если не убрали).
Гораздо труднее использовать такой прием для стилей зигзаг, если интересно попробуй, получится дай знать, очень нужно.
 
Я так и думал, рисовать двумя линиями, но вот как разорвать одну линию, массив идет непрерывный. Что присваивать, когда не нужно что бы было видно? Может присвоить величину уровня? Но это как то не очень красиво получится.
 
присвой значение EMPTY_VALUE
 
Кому интересно, вот что получилось:
#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 30
#property indicator_level2 70
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 DodgerBlue
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double RSIColorBuffer[];
double PosBuffer[];
double NegBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
   IndicatorBuffers(4);
//---- indicator line
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, RSIColorBuffer);

   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(1, RSIBuffer);
//---- 2 additional buffers are used for counting.
   SetIndexBuffer(2,PosBuffer);
   SetIndexBuffer(3,NegBuffer);
//---- name for DataWindow and indicator subwindow label
   short_name="RSI Color("+RSIPeriod+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
   SetIndexLabel(1,"");
//----
   SetIndexDrawBegin(0,RSIPeriod);
   SetIndexDrawBegin(1,RSIPeriod);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int    i,counted_bars=IndicatorCounted();
   double rel,negative,positive;
//----
   if(Bars<=RSIPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=RSIPeriod;i++) 
      {
        RSIBuffer[Bars-i]=0.0;
        RSIColorBuffer[Bars-i]=0.0;
      }
//----
   i=Bars-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=Bars-counted_bars-1;
   while(i>=0)
     {
      double sumn=0.0,sump=0.0;
      if(i==Bars-RSIPeriod-1)
        {
         int k=Bars-2;
         //---- initial accumulation
         while(k>=i)
           {
            rel=Close[k]-Close[k+1];
            if(rel>0) sump+=rel;
            else      sumn-=rel;
            k--;
           }
         positive=sump/RSIPeriod;
         negative=sumn/RSIPeriod;
        }
      else
        {
         //---- smoothed moving average
         rel=Close[i]-Close[i+1];
         if(rel>0) sump=rel;
         else      sumn=-rel;
         positive=(PosBuffer[i+1]*(RSIPeriod-1)+sump)/RSIPeriod;
         negative=(NegBuffer[i+1]*(RSIPeriod-1)+sumn)/RSIPeriod;
        }
      PosBuffer[i]=positive;
      NegBuffer[i]=negative;
      if(negative==0.0) RSIBuffer[i]=0.0;
      else
       {
         negative = 100.0-100.0/(1+positive/negative);
         RSIColorBuffer[i] = negative;
         if ((negative > indicator_level2)||(negative < indicator_level1)) negative = EMPTY_VALUE;
         RSIBuffer[i] = negative;
       }
      i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
Neep, спасибо за индикатор.
Получилось довольно интересно.
Можно ещё подумать как сделать, чтоб снизу - синим, сверху красным, а посредине - серым.

Этот индикатор неплохо кореллируется с моим разворотным индикатором.
(По сути - это инд. скорости. Бежевая - текущий ТФ, зелёная - ближайший больший ТФ, красная - следующий больший)
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
// Priliv.mq4 
// Разворотный индикатор.
// Сергей Ковалёв, Днепропетровск, sk@mail.dnepr.net
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//
//
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 White
#property indicator_color2 Wheat
#property indicator_color3 DarkSeaGreen
#property indicator_color4 DarkSalmon
//--------------------------------------------------------------------------------------------------------------------
double Buf_1[];                                                            // Буффер опорной MA
double Buf_2[];                                                            // Буффер индикатора текущего ТФ
double Buf_3[];                                                            // Буффер индикатора ближайшего большего ТФ
double Buf_4[];                                                            // Буффер индикатора следующего большего ТФ
double MA_0, MA_11, MA_12, MA_13, MA_14;
double Polzun_1[21],Polzun_2[21],Polzun_3[21],Line[21];
double KK=1.2;
double K=5;
//--------------------------------------------------------------------------------------------------------------------
int i,n,k, counted_bars, K2, K3, Period_MA_2, Period_MA_3;
int Period_MA_0 = 8;
int Period_MA_1 = 21;
int Kol_Line=20;
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int init()
   {
   switch(Period())
      {
      case     1: K2=5; K3=15;    break;
      case     5: K2=3; K3= 6;    break;
      case    15: K2=2; K3= 4;    break;
      case    30: K2=2; K3= 8;    break;
      case    60: K2=4; K3=24;    break;
      case   240: K2=6; K3=42;    break;
      case  1440: K2=7; K3=30;    break;
      case 10080: K2=4; K3= 0;    break;
      case 43200: K2=0; K3= 0;    break;
      }
   Polzun_1[1]=20;
   Polzun_2[1]=Polzun_1[1]*K2; Period_MA_2=Period_MA_1*K2;
   Polzun_3[1]=Polzun_1[1]*K3; Period_MA_3=Period_MA_1*K3;
   
//--------------------------------------------------------------------------------------------------------------------
   SetIndexStyle (0,DRAW_LINE);
   SetIndexBuffer(0,Buf_1);
//--------------------------------------------------------------------------------------------------------------------
   SetIndexStyle (1,DRAW_LINE);
   SetIndexBuffer(1,Buf_2);
//--------------------------------------------------------------------------------------------------------------------
   SetIndexStyle (2,DRAW_LINE);
   SetIndexBuffer(2,Buf_3);
//--------------------------------------------------------------------------------------------------------------------
   SetIndexStyle (3,DRAW_LINE);
   SetIndexBuffer(3,Buf_4);
//--------------------------------------------------------------------------------------------------------------------
   return(0);
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int start()
   {
   counted_bars=IndicatorCounted();
   i=Bars-counted_bars-1;
//--------------------------------------------------------------------------------------------------------------------
   for (n=2;n<=Kol_Line;n++)
      {
      k=n-1;   
      Polzun_1[n]=Polzun_1[k]/KK;
      Polzun_2[n]=Polzun_2[k]/KK;
      Polzun_3[n]=Polzun_3[k]/KK;
      }
//====================================================================================================================
   while(i>=0)
      {
//--------------------------------------------------------------------------------------------------------------------
      MA_0  = iMA( NULL, 0, Period_MA_0, 0, MODE_LWMA, PRICE_TYPICAL, i                );     
      Buf_1[i]=MA_0;                                                       // Опорная МА
//--------------------------------------------------------------------------------------------------------------------
      Buf_2[i]= 0;
      MA_11 = iMA( NULL, 0, Period_MA_1, 0, MODE_LWMA, PRICE_TYPICAL, i             ); 
      for (n=1;n<=Kol_Line;n++)
         {
         MA_12 = iMA( NULL, 0, Period_MA_1, 0, MODE_LWMA, PRICE_TYPICAL, i +Polzun_1[n]);
         Line[n] = MA_11-MA_12;                                   
         Buf_2[i] = Buf_2[i]+Line[n];
         }
      Buf_2[i]= MA_0 + K*Buf_2[i]/Kol_Line;
//--------------------------------------------------------------------------------------------------------------------
      Buf_3[i]= 0;
      MA_11 = iMA( NULL, 0, Period_MA_2, 0, MODE_LWMA, PRICE_TYPICAL, i             ); 
      for (n=1;n<=Kol_Line;n++)
         {
         MA_12 = iMA( NULL, 0, Period_MA_2, 0, MODE_LWMA, PRICE_TYPICAL, i +Polzun_2[n]);
         Line[n] = MA_11-MA_12;                                   
         Buf_3[i] = Buf_3[i]+Line[n];
         }
      Buf_3[i]= iMA( NULL, 0, Period_MA_0*K2, 0, MODE_LWMA, PRICE_TYPICAL, i) + K*Buf_3[i]/Kol_Line;
      if (K2==0)Buf_3[i]=0;
//--------------------------------------------------------------------------------------------------------------------
      Buf_4[i]= 0;
      MA_11 = iMA( NULL, 0, Period_MA_3, 0, MODE_LWMA, PRICE_TYPICAL, i             ); 
      for (n=1;n<=Kol_Line;n++)
         {
         MA_12 = iMA( NULL, 0, Period_MA_3, 0, MODE_LWMA, PRICE_TYPICAL, i +Polzun_3[n]);
         Line[n] = MA_11-MA_12;                                   
         Buf_4[i] = Buf_4[i]+Line[n];
         }
      Buf_4[i]= iMA( NULL, 0, Period_MA_0*K3, 0, MODE_LWMA, PRICE_TYPICAL, i) + K*Buf_4[i]/Kol_Line;
      if (K3==0)Buf_4[i]=0;
//--------------------------------------------------------------------------------------------------------------------
     i--;
     }
//====================================================================================================================
   return(0);
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int deinit()
   {
   return(0);
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
/*
 
Ещё я подумал..
Может быть, попробовать как-то учитывать угол наклона тренда?
По индикатору за пределами коридора 30-70 предполагается принятие торговых решений.
Наверное, оно должно быть разное для горизонтального и наклонного тренда.
Например, при сильном движении вверх можно смещать уровни - 40-80, а при движении вниз - 20-60.
Разумеется, уровни текущего коридора должны быть не жёсткими, а вычислены в зависимости от угла наклона тренда.
 
...Можно ещё подумать как сделать, чтоб снизу - синим, сверху красным, а посредине - серым...


#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 30
#property indicator_level2 70
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 DodgerBlue
#property indicator_color3 Gray
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSITopBuffer[];
double RSIMiddleBuffer[];
double RSIBottomBuffer[];
double PosBuffer[];
double NegBuffer[];

int init()
  {
   string short_name;
   IndicatorBuffers(5);
//---- indicator line
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, RSITopBuffer);

   SetIndexStyle(2, DRAW_LINE);
   SetIndexBuffer(2, RSIMiddleBuffer);
   
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(1, RSIBottomBuffer);
//---- 2 additional buffers are used for counting.
   SetIndexBuffer(3,PosBuffer);
   SetIndexBuffer(4,NegBuffer);
//---- name for DataWindow and indicator subwindow label
   short_name="RSI Color("+RSIPeriod+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
//----
   SetIndexDrawBegin(0,RSIPeriod);
   SetIndexDrawBegin(1,RSIPeriod);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int    i,counted_bars=IndicatorCounted();
   double rel,negative,positive;
//----
   if(Bars<=RSIPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=RSIPeriod;i++) 
      {
        RSIMiddleBuffer[Bars-i]=0.0;
        RSITopBuffer[Bars-i]=0.0;
        RSIBottomBuffer[Bars-i]=0.0;
      }
//----
   i=Bars-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=Bars-counted_bars-1;
   while(i>=0)
     {
      double sumn=0.0,sump=0.0;
      if(i==Bars-RSIPeriod-1)
        {
         int k=Bars-2;
         //---- initial accumulation
         while(k>=i)
           {
            rel=Close[k]-Close[k+1];
            if(rel>0) sump+=rel;
            else      sumn-=rel;
            k--;
           }
         positive=sump/RSIPeriod;
         negative=sumn/RSIPeriod;
        }
      else
        {
         //---- smoothed moving average
         rel=Close[i]-Close[i+1];
         if(rel>0) sump=rel;
         else      sumn=-rel;
         positive=(PosBuffer[i+1]*(RSIPeriod-1)+sump)/RSIPeriod;
         negative=(NegBuffer[i+1]*(RSIPeriod-1)+sumn)/RSIPeriod;
        }
      PosBuffer[i]=positive;
      NegBuffer[i]=negative;
      if(negative==0.0) RSIMiddleBuffer[i]=0.0;
      else
       {
         negative = 100.0-100.0/(1+positive/negative);
         RSITopBuffer[i] = negative;
         if (negative > indicator_level2) RSIBottomBuffer[i] = EMPTY_VALUE;
           else RSIBottomBuffer[i] = negative;
         if ((negative > indicator_level2)||(negative < indicator_level1)) RSIMiddleBuffer[i] = EMPTY_VALUE;
           else RSIMiddleBuffer[i] = negative;
       }
      i--;
     }
//----
   return(0);
  }



Может быть, попробовать как-то учитывать угол наклона тренда? ... Например, при сильном движении вверх можно смещать уровни - 40-80, а при движении вниз - 20-60

Тогда можно вообще написать 2 функции уровней от наклона тренда:
1. LevelTop = f(AngleTrend);
2. LevelBottom = f(AngleTrend)
Тогда получатся динамические уровни :-)
Но..., думаю что не стоит менять уровни, так как на истории измененные уровни, будут вводить путаницу. И второе: а как учитывать угол наклона тренда? Как определить тренд ли это?

Причина обращения: