Индикаторы: Гистограмма объемов другая интерпритация - страница 2

 

Пожалуйста, код доработал, убрал лишние if и т.п. Можно удобно обозначить вертикальной линией начало тренда/флэта, например, и смотреть объем по ходу тренда/флэта

// Объём расчитыватся от Low до High.
#property indicator_chart_window

extern int Period_ind = 55; //Число баров на которых вычислять индикатор
extern string Vertical_Line_Name = "Vertical Line 10408";//Имя вертикальной линии, вправо от которой строить индикатор
extern color clObj = Blue; //Цвет гистограммы
extern int UpdateInterval = 100; //вычисление индикатора не чаще чем каждые 100 миллисекунд

double Hist[],price_step;
datetime CountTime = 0;
int OpenVolume=0,items;

int init()
{
price_step=Point*50;//Делаю шаг 0.0005 вместо 0.00001, чтобы уменьшить количество вычислений, точность остается нормальной
return(0);
}

int start()
{
static int last_time = 0;
int cur_time,k,n,i,time_i,MaxVolume,Bars_number;
double max,min,t1,t2,t3,t4,znamen,Price_i;

if (UpdateInterval != 0)//always update or update only after certain interval
{
cur_time = GetTickCount();
if (MathAbs(cur_time - last_time) < UpdateInterval) return (0);
last_time = cur_time;
}

Bars_number=iBarShift(NULL,0,ObjectGet(Vertical_Line_Name,0),TRUE);//Определяем номер бара, на котором проведена вертикальная линия
if(Bars_number==-1) Bars_number=WindowFirstVisibleBar();//если вертикальная линия не найдена, строим индикатор от первого видимого бара на графике
k=Bars_number-Period_ind;//ищем начальный бар, смещенный на Period_ind вправо от вертикальной линии
if(k<0)
{
Period_ind=Period_ind+k;//уменьшим Period_ind на k
k=0;//в этом случае все вычисляем от нулевого бара
}
if (OpenVolume != Volume[0])//вычислять индикатор при изменении объема
{
max = High[iHighest( NULL, 0, MODE_HIGH, Period_ind, k)];
min = Low [iLowest ( NULL, 0, MODE_LOW, Period_ind, k)];
items = MathRound((max - min) / price_step);

ArrayResize(Hist, items);
ArrayInitialize(Hist, 0);

for (i = k; i <= Bars_number; i++)
{
t1 = Low[i];
t2 = MathMin(Open[i],Close[i]);
t3 = MathMax(Open[i],Close[i]);
t4 = High[i];
znamen = t4 - t1;

if (znamen != 0.0)
{
for (Price_i = t1; Price_i <= t4; Price_i += price_step)
{
n = MathRound((Price_i - min) / price_step);
if (Price_i <= t2) Hist[n] += Volume[i]*(t2-t1)/znamen;
else if (Price_i <= t3) Hist[n] += Volume[i]*(t3-t2)/znamen;
else if (Price_i <= t4) Hist[n] += Volume[i]*(t4-t3)/znamen;
}
}
}
for (i = 0; i <= items; i++) ObjectDelete("VH"+i);

MaxVolume = Hist[ArrayMaximum(Hist)];
for (i = 0; i <= items; i++)
{
if (MaxVolume != 0) Hist[i] = MathRound(Period_ind * Hist[i] / MaxVolume );
if (Hist[i] > 0)
{
time_i = Bars_number-Hist[i];
ObjectCreate("VH"+i, OBJ_RECTANGLE, 0, Time[Bars_number], min + i*price_step, Time[time_i], min + (i+1)*price_step);
ObjectSet("VH"+i, OBJPROP_STYLE,0);
ObjectSet("VH"+i, OBJPROP_COLOR, clObj);
ObjectSet("VH"+i, OBJPROP_BACK, true);
}
}
}
OpenVolume = Volume[0];
return(0);
}

int deinit()
{
for (int i = 0; i <= items; i++) ObjectDelete("VH"+i);
return(0);
}

 

Спасибо, 5555. Отличный индикатор получился!

Автору персональный респект.

 

Отлично!+10, а как поставить 2 индикатора в одно окно чтобы отображались оба? 

 

я заменил "VH" везде в тексте индюка на Vertical_Line_Name - имя вертикальной линии. Теперь к каждой вертикальной линии можно привязать свой индикатор, который не будет путаться с другими.

 

Изобретаем велосипед :-)

Но ведь зато свой! ))))))))))

 
5555:

я заменил "VH" везде в тексте индюка на Vertical_Line_Name - имя вертикальной линии. Теперь к каждой вертикальной линии можно привязать свой индикатор, который не будет путаться с другими.

Спасибо

а как сделать 2 линии в одном индикаторе и к ним профиль с разными цветами и фрейм от М1 до D1 ?

Интересно, что гистограммы всех индикаторов чтоя привел в предыдущем посте сильно отличаются

еще https://www.mql5.com/ru/forum/107904/page2

https://www.mql5.com/ru/forum/107810/page4#70908

Yurixx 09.02.2009 11:15

https://www.mql5.com/ru/forum/114318/page18#140576
Рыночный профиль - хорошая штука, но к квантованию отношения не имеет. Со значительно большей долей правомерности его можно назвать
статистическим профилем, поскольку смысл того, что он показывает, заключается в распределении котировок за определенный период времени
по всему диапазону значений цены.
С моей точки зрения, к квантованию больше отношения имеют уровни Мюррея (/ru/code/7870), хотя у них свои недостатки: эквидистантность и привязка к нулю.

 
5555:

Пожалуйста, код доработал, убрал лишние if и т.п. Можно удобно обозначить вертикальной линией начало тренда/флэта, например, и смотреть объем по ходу тренда/флэта


Доработки принял во внимание. Спорить не буду. Это на любителя. Я только заметил, что усреднение изменяет диаграмму "вверх". Поставь индюк с шагом 0.0005 вместо и 0.00001. Разница очевидна. Надо покумекать, как это исправить. Пока времени нет.

И ещё может линию среднего объёма здесать?? т.е. суммировать полученный объём и делить на число участков. Получится машка по оъёму.

У меня немного другая реализация. Я её часто использую в кодах, она немного лучше, чем среднее. В сапромате это называется момент инерции (центр тяжести фигуры). в коде это выглядит так:

      double summA, summXA;
      int x0;
      for (i = 0; i <= items; i++)
      {
         if (MaxVolume != 0) 
         {
            Hist[i] = MathRound(Amplitude * Hist[i] / MaxVolume );
            summXA += i*Hist[i];
            summA += Hist[i];
         }
      }
      x0 = MathRound(summXA/summA);
      Srednee[0] = min + x0*Point;

x0 - точка равновесия для диаграммы. Srednee[0] - значение точки равновесия на графике на граффике.

 
5555:

а как сделать 2 линии в одном индикаторе и к ним профиль с разными цветами и фрейм от М1 до D1 ?

 

Сделать можно,но получится некрасивый код. Проще провести две линии на графике и на каждую линию повесить свой индюк(благо каждая линия имеет свое имя, которое задается в индюке).

Насчет фрейма от М1 до Д1 не понял, что вы имеете в виду: брать данные для вычисления с этих таймфреймов и рисовать на своем рабочем таймфрейме? Лично я сделал версию для себя которая берет данные с М1,но результат получился хуже чем если брать данные с рабочего таймфрейма.

 
5555:

Лично я сделал версию для себя которая берет данные с М1,но результат получился хуже чем если брать данные с рабочего таймфрейма.


Но использовать результаты М1 намного точнее, чем брать с рабочего тайма.

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