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

 
Aleksey Vyazmikin:

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

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

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

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

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


 

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

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

 
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:

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


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

 
s22aa:

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

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

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

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

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

 
А нельзя ли по цене сделать дельту горизонтальных объемов ?
 
__zeus__:
А нельзя ли по цене сделать дельту горизонтальных объемов ?

Можно. Только это гораздо сложнее. И тема отдельной статьи.

 
Alexey Kozitsyn:

Можно. Только это гораздо сложнее. И тема отдельной статьи

Прикрутить бы дельту к этому чудесному индикатору https://www.mql5.com/ru/code/15440

Volume Profile + Range v6.0
Volume Profile + Range v6.0
  • www.mql5.com
Индикатор Volume Profile + Range v6.0 (бывший TPO). Распределение сделок по ценовым уровням на заданном временном участке. Показывается в виде гистограммы. Ширина гистограммы на данном уровне означает, условно, количество сделок, проведенных на ней. Если брокер предоставляет данные по реальному объёму, индикатор может показывать распределение и...
Причина обращения: