Плавное изменения цвета по ADX ..КАК ето реализовать ?? - страница 2

 

Вы не можете изменять цвет отдельных частей графических объектов и индикаторных буферов

В вашем коде вы должны для каждого объекта дать свое уникальное имя (обычно применяется индекс по времени) :

 

ObjectCreate(StringConcatenate("dashADX", Time[index]), OBJ_TREND, 0, Close[index], Time[index], Close[index+1], Time[index+1]);//создаём OBJ_TREND длинной в толщину одной свечи
 
(int index, int& iDash)    {//два параметра - номер бара, который всегда равен 0 в старте и пробегается в цикле в init()  ...index !!!!??? как он считает
 
OGRE:
(int index, int& iDash)    {//два параметра - номер бара, который всегда равен 0 в старте и пробегается в цикле в init()  ...index !!!!??? как он считает


Нет. Если делать по совету FAQ, то iDash и передача по ссылке не нужны. Только int index, а там уже просто.

Как работает? Когда ты объявляешь переменную на глобальном уровне, а потом в разных функциях её используешь параллельно, то в этих разных функциях каждая функция работает не с переменной, а с её копией.  Когда ты хочешь изменить значение переменной, используемой в функции, из другой функции, из её внутренностей, ты передаёшь эту переменную в ту функцию, которая должна её изменять, по ссылке на адрес переменной. То есть ты передаёшь фактически уже не название используемой переменной, а её адрес в памяти. И когда ты меняешь значение переменной, ты меняешь не значение её копии, как обычно, а её непосредственное значение (не копии) по её собственному адресу. Сам долго выл, и не одну неделю, вот это всё медленно и мучительно понимая, осознавая. То есть 

//объявление на глобальном уровне
int i=0;
double d=0.0;
strings="";

int (double, string... - здесь это не важно) MyFunction (int i, double d, string s){
  //какие-то действия, изменяющие i, d, s
  return(какое-то_возвращаемое_значение);
}

int start(){
  MyFunction(i, d, s);//вызов функции,возвращающей ОДНО (естественно) значение
  //использование (точнее, попытка использования) i, d, s:
  Print(i, d, s);//или Alert, здесь не важно
  //так вот, они будут равны 0, 0.0 и "" соответственно.
}

 а это вариант со ссылками:

//объявление на глобальном уровне
int i=0;
double d=0.0;
strings="";

int (double, string... - здесь это не важно) MyFunction (int& i, double& d, string& s){
  //какие-то действия, изменяющие i, d, s
  return(какое-то_возвращаемое_значение);
}

int start(){
  MyFunction(i, d, s);//вызов функции,возвращающей ОДНО (естественно) значение
  //использование (точнее, попытка использования) i, d, s:
  Print(i, d, s);//или Alert, здесь не важно
  //так вот, они будут равны изменённым в MyFunction() значениям.
}

 Ребята поправят, если я неправ. То есть тогда, когда тебе НЕ надо изменять значения переменных так, что они потом где-то ещё изменённые будут использоваться, передавать именно по ссылке переменные в функцию не нужно.

 
FAQ:

Вы не можете изменять цвет отдельных частей графических объектов и индикаторных буферов. 

Ну-ну... Вверху - цена с градацией по разности между +DI и -DI с перезаливкой линии в каждой точке, в первом подокне - эта сама разность, пропущенная через экспотенциальный фильтр-увеличилку, чтобы реагировать быстрее на изменение значения около нуля и медленнее - на изменение значения на границах диапазона (т.е. выше +50 и ниже -50),а второе подокно - разложение текущего цвета линии, которая цветная сверху, по RGB.

 
gyfto:

Ну-ну... 


Что за ну-ну? Это или не индикаторные буферы или терминал не МТ4. Если это МТ4, то не индикатрный буфер, а рисование графическими объектами, что не есть гуд.
 

Нашли чем заморочиться...  Лучше цифровое значение отслеживать, а не визуальное. Вдруг усложнение кода по цвету и ни к чему?

Т.е. я о чем....

Если цвет - некий показатель, то сначала получите его числовое значение. 100%-но уверен, что задача упростится. до 2-х 3-х цветов. А об этом уже Вам рассказали. 

 
Integer:

Что за ну-ну? Это или не индикаторные буферы или терминал не МТ4. Если это МТ4, то не индикатрный буфер, а рисование графическими объектами, что не есть гуд.


1. Сначала перебором всех возможных функций распределения в Википедии взял функцию фильтра отсюда, см. функция распределения. Получилось следующее:

 

 Зачем? Среднестатистический диапазон разности +DI и -DI от -50 до +50, за пределы бывает редко. Поэтому, чтобы усилить градацию на цвета на рабочем диапазоне и уменьшить на редко наблюдаемом, использовал фильтр. В кодах выглядело так:

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
extern int periodADX=14;
double ExtMapBuffer1[];

int init(){
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   return(0);
}

int start(){
   for(int i=Bars-1; i>=0; i--){
      double delta=iADX(NULL, 0, periodADX, PRICE_CLOSE, MODE_PLUSDI, i) - iADX(NULL, 0, periodADX, PRICE_CLOSE, MODE_MINUSDI, i);
      delta/=100;
      if(delta<0) delta=0.5*MathExp(5*delta); else delta=1-0.5*MathExp(-5*delta);
      ExtMapBuffer1[i]=delta;
   }
   return(0);
}

 2. Затем протестил разложение разности +DI и -DI по RGB:

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Green
#property indicator_color3 Blue

extern int       periodADX=14;
extern double    Staturation=1.0;
extern double    Lightness=0.5;
double Hue;
double red[];
double green[];
double blue[];

int init(){
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,red);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,green);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,blue);
   return(0);
}

int start(){
   int    counted_bars=IndicatorCounted();
   for(int i=Bars-1; i>=0; i--){
      double delta=iADX(NULL, 0, periodADX, PRICE_CLOSE, MODE_PLUSDI, i) - iADX(NULL, 0, periodADX, PRICE_CLOSE, MODE_MINUSDI, i);
      delta/=100;
      if(delta<0) Hue=0.5*MathExp(5*delta); else Hue=1-0.5*MathExp(-5*delta);
           if(Staturation==0){
                   red[i]=Lightness*255;
                   green[i]=Lightness*255;
                   blue[i]=Lightness*255;
           }else{
                   double var_2;
                   if(Lightness<0.5) var_2=Lightness*(1.0+Staturation); else var_2=(Lightness+Staturation)-(Staturation*Lightness);
                   double var_1=2.0*Lightness-var_2;
                   red[i]=255.0*Hue_To_RGB(var_1,var_2,Hue+(1.0/3.0));
                   green[i]=255.0*Hue_To_RGB(var_1,var_2,Hue);
                   blue[i]=255.0*Hue_To_RGB(var_1,var_2,Hue-(1.0/3.0));
           }
   }
   return(0);
}

double Hue_To_RGB(double v1,double v2,double vH){
        if(vH<0) vH+=1.0;
        if(vH>1.0) vH-=1.0;
        if((6.0*vH)<1.0) return(v1+(v2-v1)*6.0*vH);
        if((2.0*vH)<1.0) return(v2);
        if((3.0*vH)<2.0) return(v1+(v2-v1)*((2.0/3.0)-vH)*6.0);
        return(v1);
}

 3. И, наконец, продолжая пользоваться что дни выходные, также поместил цикл по всей истории в start():

#property indicator_chart_window

extern int periodADX=14;
extern double Staturation=1.0;//значение насыщенности
extern double Lightness=0.5;//значение светлоты
double Hue;//будет значением оттенка (по нему мы и идём по радуге)

int deinit(){
        ObjectsDeleteAll(0, OBJ_TREND);//в деинициализации также в цикле удаляем все OBJ_TREND
}

int start(){//в старте
   for(int i=Bars-1; i>=0; i--) ColorDash(i);//в цикле по всей истории перерисовываем линию цены
}

void ColorDash(int index){//один параметр - индекс. Ничего не передаёт обратно (void)
        double delta = iADX(NULL, 0, periodADX, PRICE_CLOSE, MODE_PLUSDI, index) - iADX(NULL, 0, periodADX, PRICE_CLOSE, MODE_MINUSDI, index);//получаем разницу +DI и -DI
        //NB! каждый отдельно меняется от 0 до 100, т.е. их разница меняется от -100 (0 минус 100) до +100 (100 минус 0)
        delta/=100;//область допустимых значений +100...-100 переводим в О.Д.З. +1.0...-1.0
        if(delta<0) Hue=0.5*MathExp(5*delta); else Hue=1-0.5*MathExp(-5*delta);//пропускаем дельту через увеличилку
        color RGB = HSLtoRGB(Hue, Staturation, Lightness);//конвертируем цветовую модель HSL в цветовую модель RGB
        string name=StringConcatenate("dashADX", Time[index]);//формируем имя линии по совету FAQ
        ObjectCreate(name, OBJ_TREND, 0, Time[index], Close[index], Time[index+1], Close[index+1]);//создаём OBJ_TREND длинной в толщину одной свечи
        ObjectSet(name, OBJPROP_COLOR, RGB);//и меняем цвет OBJ_TREND в зависимости от разности +DI и -DI
        ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID);//а также выполняем следующие перестраховки: это сплошная линия (не пунктирная и прочее)
        ObjectSet(name, OBJPROP_WIDTH, 2);//также она имеет ширину 2 пикселя (как и обычная линия цены)
        ObjectSet(name, OBJPROP_RAY, false);//и нарисованная трендовая линия это не луч, а отрезок
}

double Hue_To_RGB(double v1,double v2,double vH){
        if(vH<0) vH+=1.0;
        if(vH>1.0) vH-=1.0;
        if((6.0*vH)<1.0) return(v1+(v2-v1)*6.0*vH);
        if((2.0*vH)<1.0) return(v2);
        if((3.0*vH)<2.0) return(v1+(v2-v1)*((2.0/3.0)-vH)*6.0);
        return(v1);
}

color HSLtoRGB(double aH,double aS,double aL){
        if(aS==0){
                double oR=aL*255;
                double oG=aL*255;
                double oB=aL*255;
        }else{//сюда
                double var_2;
                if(aL<0.5) var_2=aL*(1.0+aS); else var_2=(aL+aS)-(aS*aL);
                double var_1=2.0*aL-var_2;
                oR=255.0*Hue_To_RGB(var_1,var_2,aH+(1.0/3.0));
                oG=255.0*Hue_To_RGB(var_1,var_2,aH);
                oB=255.0*Hue_To_RGB(var_1,var_2,aH-(1.0/3.0));
        }
        return(0x10000*oB+0x100*oG+oR);
}

 4. Да, рисование графическими объектами. Нет, не показатель, только для визуализации.

 И вопрос по терминологии: какой фильтр считается фильтром высоких частот, какой низких? Или это вообще не фильтр (см. п. 1) в собственном смысле этого слова?

 
gyfto:


1. Сначала перебором всех возможных функций распределения в Википедии взял функцию фильтра отсюда, см. функция распределения. Получилось следующее:

 

 Зачем? Среднестатистический диапазон разности +DI и -DI от -50 до +50, за пределы бывает редко. Поэтому, чтобы усилить градацию на цвета на рабочем диапазоне и уменьшить на редко наблюдаемом, использовал фильтр. В кодах выглядело так:

 2. Затем протестил разложение разности +DI и -DI по RGB:

 3. И, наконец, продолжая пользоваться что дни выходные, также поместил цикл по всей истории в start():

 4. Да, рисование графическими объектами. Нет, не показатель, только для визуализации.

 И вопрос по терминологии: какой фильтр считается фильтром высоких частот, какой низких? Или это вообще не фильтр (см. п. 1) в собственном смысле этого слова?


Вы серьезно или прикалываетесь? 
 
gyfto:


 И вопрос по терминологии: какой фильтр считается фильтром высоких частот, какой низких? Или это вообще не фильтр (см. п. 1) в собственном смысле этого слова?

ФВЧ - это когда количество отфильтрованных колебаний за период больше чем у ФНЧ за такой же период (на пальцах). Т.е. вы хотите отфильтровать ВЧ и НЧ, оставив средние частоты. Тогда проще выделить средние частоты, не забирая высокие и низкие. Следовательно нужен ФСЧ и баста.

... PS:

а вообще глянув в википедию, я ничего нового не увидел, как функцию нормального распределения плотности вероятности. Т.е. по 0,17 по краям вырезаем (в целом 0,33, вы обзываете это ФНЧ и ФВЧ). 

Применимо же к рынку - это будет наилучшим образом похоже на:

- (цена) среднюю линию через центр бара и 2 линии по краям, отрезав от верхнего/нижнего края ценового бара по 0,17.

- (плотность колебаний цены) срезаный на 0,33 объем внизу графика

Зачем заморачиваться цветами - не пойму???

 
gyfto : так что насчет "ну,ну" - можете вы изменять цвет отдельных частей индикаторного буфера, или графобъекта ?
Причина обращения: