Обсуждение статьи "Написание биржевых индикаторов с контролем объема на примере индикатора дельты" - страница 9

 
Aleksey Vyazmikin:

Если брать открытый интерес, то это Вы такой код имели ввиду?

Проторгованная дельта, это я относительно индикатора, в ветке которой идет наш диалог

Значит Вы суммируете эти дельты плавающим окном (к примеру последние 100) или по нарастающей (n+1 с определенной даты, к примеру с даты начала текущего дня), за какой период? Почему за этот период?

Ну да, такой код примерно. Если в %, то * 100. Это больше для роботов подходит, визуально лучше абсолютные значения смотреть.ИМХО.

У меня ряд окон под разные тактики. Как-то так:


 

Исходя из того что фьючерс начинает активно торговаться (и для некоторых рынков глобально определять цены активов, как н-р 6B,6E,RB,CL,GC) как только он становится самым ближним, то дельту следует суммировать с начала этой даты. 

Если работать с дельтой на акциях, то там гораздо сложнее определиться с точкой отсчета. В реальности большинство систем (типа ClusterDelta) берут фиксированное скользящее окно, н-р 90 баров. Однако если хорошо подумать, то там наверное правильнее брать за точки какой-то ценовой экстремум в прошлом, н-р за 30 дней

 

господин козицын,

Поздравляю с отличной работой! Это лучший индикатор дельты на сегодняшний день, очень быстрый.

Я пытаюсь модифицировать его, чтобы строить только положительные значения с другим цветом для покупки / продажи дельты (лучше всего, чтобы сравнить размер гистограммы баров), без успеха, Вы можете дать несколько подсказок, как это сделать или сообщение, где должны быть изменены оригинальный код?

Еще один вопрос, можно ли построить вертикальную гистограмму вместо горизонтальной? Я пытаюсь построить вертикальную гистограмму с помощью https://www.mql5.com/ru/articles/2714, но она не выводит никаких значений, более того, я пытаюсь вывести значения объема на вертикальной гистограмме, и она не выводит ни одного короля объема (я использую NormalizeDouble для преобразования из long в double).

Спасибо большое!

Statistical distributions in the form of histograms without indicator buffers and arrays
Statistical distributions in the form of histograms without indicator buffers and arrays
  • www.mql5.com
Histograms allow researchers to visually evaluate the distribution of statistical data grouped by the frequency of their penetration into a certain (predetermined) interval. Histograms and their use in the statistical data analysis are a well-studied topic with multiple articles devoted to it [1, 2, 3, 4, 5, 6, 7] and a large number of CodeBase...
[Удален]  
frcardim:

господин козицын,

Поздравляю за отличную работу! Это лучший индикатор Delta на сегодняшний день, очень быстрый.

Спасибо!

Я пытаюсь модифицировать его, чтобы строить только положительные значения с другим цветом для покупки / продажи дельты (лучше всего сравнить размер баров гистограммы), без успеха, Вы можете дать несколько подсказок, как это сделать или сообщение, где должны быть изменены оригинальный код?

Замените функцию DisplayValues() на эту:

//+------------------------------------------------------------------+
//| Отображение значений индикатора|
//+------------------------------------------------------------------+
void DisplayValues(const int index,// Номер свечи
                   const long sumVolBuy,// Суммарный объем покупок
                   const long sumVolSell,          // Суммарный объем продаж
                   const int line                  // Номер строки вызова функции
                   )
  {
//--- Проверяем корректность номеров свечи
   if(index<0) // Если некорректный номер
     {
      Print(__FUNCTION__,": ОШИБКА! Некорректный номер свечи '",index,"'");
      return;                                       // Выходим
     }
//--- Рассчитаем дельту
   const double delta=double(sumVolBuy-sumVolSell);
//--- Заносим значения в буферы
   //bufDelta[ index ]= delta; // Записываем значение дельты
   bufDelta[ index ]= (delta>0) ? delta : -delta;  // Записываем значение дельты
   bufDeltaColor[ index ] =(delta>0) ?  0 : 1;     // Записываем цвет значения
   bufBuyVol[ index ] = (double)sumVolBuy;         // Записываем сумму покупок
   bufSellVol[ index ]=(double)sumVolSell;         // Записываем сумму продаж
  }

Еще один вопрос, можно ли построить вертикальную гистограмму вместо горизонтальной?

В данном индикаторе это невозможно.
 

Господин Козицын,


Прежде всего, поздравляю!!! Отличная, отличная, отличная работа!!! Это то, что я искал.

Однако, этот индикатор - половина моего желания. Я хотел бы нарисовать полосу Болинджера над дельтой индикатора, чтобы показать мне, где поток денег больше, чем нормальное поведение. Я пробовал это сделать, но не смог увидеть линии полос в одном окне. Не могли бы вы мне помочь?

Большое спасибо!!!


Родриго Пимента

[Удален]  
rpimentaf:

Не могли бы вы мне помочь?

Спасибо большое!!!


Родриго Пимента

Извините, но я не работаю с BB.

Вы можете использовать Freelance для своей задачи.

 
Alexey Kozitsyn:

Вообще на нашем рынке с использованием тиков и стакана можно очень круты вещи делать. 

Согласен с вами. Дельту смотрю давно, использую не часто  ツ

Индикатор у вас замечательный получился, у меня он даже на выходные работает!

Дельту смотрю на таймфреймах меньше минуты, когда цена пробивает локальный хай и вместо стопов(синяя дельта) появляются рыночные продажи. Обычно после такого сетапа, цена делает коррекцию.

картинка

Ну это так, просто по теме.

Вопрос у меня в другом. Недавно начал учится писать индикаторы. Потихоньку осваиваю, методом научного тыка и копипаста.

Захотелось написать индикатор дивергенции дельты. Это кода у АП баров дельта продажная(красная), у даун баров синяя.

С помощью вашего индикатора, через iCustom мой работает нормально. 

Но так как я учусь, мне интересно написать по своему. А по своему не работает (.   Уже третий день над ним бьюсь, а он не поддаётся. Если не трудно скажите в чём ошибка.

Логика определения дельты такая: так как мне не нужна дельта на текущем баре , я решил, что можно посчитать дельту, используя тиковый объем предыдущего бара OnCalculate, tick_volume[] , в качестве количества тиков при копировании CopyTicks. Метаэдитор кампилируе, но выдаёт предупреждение о том, что я использую разные типы данных   в тиковом объёме long, а в CopyTicks надо количеств указывать в uint.   Время начала копирования берём там же time[],

При тестировании в тестере выдаёт ошибку "Array out of range"  , и я не могу понять за какие пределы он уходит и как вообще определить, что поменять, чтобы индюк пусть не заработал, но хотя бы эту ошибку убрать.

Вот код индюка, сильно не смейтесь плиз.

#property indicator_chart_window 
#property indicator_buffers 5 
#property indicator_plots   1
  
#property indicator_label1  "Diver_handl" 
#property indicator_type1   DRAW_COLOR_CANDLES 
//--- зададим 2 цвета для раскраски свечей (они хранятся в буфере цвета) 
#property indicator_color1  clrRed,clrBlue
#property indicator_style1  STYLE_SOLID 
#property indicator_width1  1 // толщина отрисовки линии, здесь вроде как нафик не нужна

//--- input параметры 
//--- индикаторные буферы
double         ColorCandlesBuffer1[];//буфера свечей
double         ColorCandlesBuffer2[];
double         ColorCandlesBuffer3[];
double         ColorCandlesBuffer4[];
double         ColorCandlesColors[]; // Буфер цвета

string symbol;  //--- имя символа 
double _Delta;
//+------------------------------------------------------------------+ 
//| Custom indicator initialization function                         | 
//+------------------------------------------------------------------+ 
int OnInit()
  {
//--- indicator buffers mapping 
   SetIndexBuffer(0,ColorCandlesBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,ColorCandlesBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,ColorCandlesBuffer3,INDICATOR_DATA);
   SetIndexBuffer(3,ColorCandlesBuffer4,INDICATOR_DATA);
   SetIndexBuffer(4,ColorCandlesColors,INDICATOR_COLOR_INDEX);
   
//--- пустое значение(значение которое не будет рисоваться) 
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   
//--- имя символа, по которому рисуются бары 
   symbol=_Symbol;
   
//--- установим отображение символа  
   PlotIndexSetString(0,PLOT_LABEL,symbol+" Open;"+symbol+" High;"+symbol+" Low;"+symbol+" Close");
   IndicatorSetString(INDICATOR_SHORTNAME,"Diver("+symbol+")");
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+ 
//| Custom indicator iteration function                              | 
//+------------------------------------------------------------------+ 
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[])
  {
   int i,limit;
   int buf_size=rates_total-prev_calculated;
   if(rates_total<2)
      return(0);

   if(prev_calculated<3)
     {
      limit=1;
      // инициализируем массивы, пустыми значениями
      ArrayInitialize(ColorCandlesBuffer1,EMPTY_VALUE);
      ArrayInitialize(ColorCandlesBuffer2,EMPTY_VALUE);
      ArrayInitialize(ColorCandlesBuffer3,EMPTY_VALUE);
      ArrayInitialize(ColorCandlesBuffer4,EMPTY_VALUE);
      ArrayInitialize(ColorCandlesColors,EMPTY_VALUE);
     }
   else limit=rates_total-1;

   MqlTick Ticks[];   //обьявляем массив который будет заполнен тиковыми данными
   
   for(i=limit; i<rates_total-1; i++)
     {
      CopyTicks(Symbol(),Ticks,COPY_TICKS_TRADE,0,tick_volume[i]);  // копируем в массив Ticks, тиковые данные в количестве равном тиковому объёму в свече tick_volume[i]
      SetBarData(time[i],Ticks,i,_Delta,tick_volume[i]);// функция в подвале ↓

      if(open[i-1]<close[i-1] && _Delta<0)
        {
         ColorCandlesBuffer1[i-1]=open[i-1];
         ColorCandlesBuffer2[i-1]=high[i-1];
         ColorCandlesBuffer3[i-1]=low[i];
         ColorCandlesBuffer4[i-1]=close[i];
         ColorCandlesColors[i-1]=1;
        }
      else if(open[i]>close[i] && _Delta>0)
        {
         ColorCandlesBuffer1[i-1]=open[i-1];
         ColorCandlesBuffer2[i-1]=high[i-1];
         ColorCandlesBuffer3[i-1]=low[i];
         ColorCandlesBuffer4[i-1]=close[i];
         ColorCandlesColors[i-1]=0;
        }
      else
        {
         ColorCandlesBuffer1[i]=0.0;
         ColorCandlesBuffer2[i]=0.0;
         ColorCandlesBuffer3[i]=0.0;
         ColorCandlesBuffer4[i]=0.0;
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
// Заполняет бар соответствующими ему тиками
void SetBarData(const datetime TimeBar,const MqlTick &Ticks[],int &Pos,double &Delta,const long vol)
  {
  int i=0;
   while(i<vol)
     {
      MqlTick Tick=Ticks[Pos];  // копируем в переменную показания буфера с тиковыми данными
      if(i>=vol)
         break;   // когда i санет равна тиковому обьёму , вайл †
      if((bool)(Tick.flags  &TICK_FLAG_BUY))  //если флаг бай прибавляем к дельте
         Delta+=(double)Tick.volume;
      else if((bool)(Tick.flags  &TICK_FLAG_SELL)) //если флаг селл отнимаем от дельты
         Delta-=(double)Tick.volume;
      i++;
     }
   return;
  }
//+------------------------------------------------------------------+
Экспериментировал много, так что могут остаться артефакты от предыдущих экспериментов, в виде объявленных но не используемых переменных. 
[Удален]  
s22aa:

Если не трудно скажите в чём ошибка.

Точное место с ошибкой не вижу на первый взгляд, но, для начала, посмотрите как в моем индикаторе происходит работа с CopyTicks(). В частности возврат значения и обработка возможных ошибок.

Да, если происходит выход за пределы массива... смотрите сколько значений в массиве и к какому элементу Вы обращаетесь. Также можете после получения данных сделать распринтовку первого и последнего значения, чтобы понять, все ли данные были получены.

 
Alexey Kozitsyn:

посмотрите как в моем индикаторе происходит работа с CopyTicks().

Ух, там всё сложно. Тики копируются и по отрезку времени и по количеству. В общем система дублирована не хуже чем у космонавтов)))

Нашёл я где надичил.

MqlTick Tick = Ticks[Pos];

Я в переменную пытаюсь скопировать массив. Странно почему компилятор на это никак не реагирует, а когда запускаешь в тестере, тестер зависает. 

Попробую придумать как нибудь по другому.
 
s22aa:

Я в переменную пытаюсь скопировать массив.


Нет, не это. Это правильно. Совсем запутался. Утро ночи мудренее. Завтра, всё получится.