Индикатор тиков, работающий в MT5 на истории (нужна помощь)

 

Всем привет. Пытаюсь вместе с программистом разработать индикатор тиков, который бы работал на истории (на последних Х барах/свечах).

Суть индикатора простая, он должен отображать в виде гистограмм

  • выше нуля - считать и отображать тики и пункты (пройденные по этим тикам) по ask
  • ниже нуля - считать и отображать тики и пункты (пройденные по этим тикам) по bid

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

Код индикатора прикрепляю

//+------------------------------------------------------------------+
//|                                               TicksVolume v2.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Игорь и Юрий"
#property link      "https://www.mql5.com"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   4
//--- plot UpBuffer
#property indicator_label1 "Pips Up"
#property indicator_type1  DRAW_HISTOGRAM
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 4
//--- plot UpTick
#property indicator_label2 "Tick Up"
#property indicator_type2  DRAW_HISTOGRAM
#property indicator_color2 clrGreen
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//--- plot UpBuffer
#property indicator_label3 "Pips Down"
#property indicator_type3  DRAW_HISTOGRAM
#property indicator_color3 clrYellow
#property indicator_style3 STYLE_SOLID
#property indicator_width3 4
//--- plot UpTick
#property indicator_label4 "Tick Down"
#property indicator_type4  DRAW_HISTOGRAM
#property indicator_color4 clrRed
#property indicator_style4 STYLE_SOLID
#property indicator_width4 2
//--- plot level line
#property indicator_level1 1
#property indicator_levelcolor clrGray
#property indicator_levelstyle STYLE_SOLID
//--- Inputs variables
enum var
{
   var1 = 1, // Ticks
   var2 = 2, // Pips
   var3 = 3, // Ticks & Pips
};
input int LastBars = 100;
input var Variant = var1;
input bool Logs = false;
//--- Indicator buffer
double UpBuffer[],DnBuffer[],UpBuffer2[],DnBuffer2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0,UpBuffer2, INDICATOR_DATA);
   SetIndexBuffer(1,UpBuffer, INDICATOR_DATA);
   SetIndexBuffer(2,DnBuffer2, INDICATOR_DATA);
   SetIndexBuffer(3,DnBuffer, INDICATOR_DATA);
  
   IndicatorSetString(INDICATOR_SHORTNAME,"TicksVolume");
   IndicatorSetInteger(INDICATOR_DIGITS,0);
   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 pos=prev_calculated-3;
   if(pos < 1) pos=1;
   
   MqlTick ticks_array[];
   double _Bid=0,_Ask=0,Bid=0,Ask=0;
   for(int i=pos; i<rates_total; i++)
   {
      if(i < rates_total-LastBars-2)
      {
         UpBuffer[i] = 0;
         DnBuffer[i] = 0;
         UpBuffer2[i] = 0;
         DnBuffer2[i] = 0;
         continue;
      }
      
      if(i+1 < rates_total)
         CopyTicksRange(_Symbol,ticks_array,COPY_TICKS_INFO,(ulong)time[i]*1000,(ulong)time[i+1]*1000);
      else CopyTicksRange(_Symbol,ticks_array,COPY_TICKS_INFO,(ulong)time[i]*1000,(ulong)TimeCurrent()*1000);
      
      int uptick=0, dntick=0, uppips=0, dnpips=0;
      for(int j=ArraySize(ticks_array)-1; j>=0; j--)
      {
         Bid=ticks_array[j].bid;
         Ask=ticks_array[j].ask;
         
         if(_Bid == 0) break;
         //if(Bid>_Bid || (_Bid==Bid && _Ask>Ask)) 
         //if(ticks_array[j].flags == 4)
         if(Ask != _Ask)
         {
            uppips += (MathAbs(Ask-_Ask)/_Point);
            uptick++;
         }
         //if(Bid<_Bid || (_Bid==Bid && _Ask<Ask)) 
         //if(ticks_array[j].flags == 2)
         if(Bid != _Bid)
         {
            dnpips += (MathAbs(Bid-_Bid)/_Point);
            dntick++;
         }
         _Bid = Bid;
         _Ask = Ask;
      }
      if(_Bid == 0) 
      {
         _Bid = Bid; 
         _Ask = Ask;
         if(UpBuffer[i-1] == 0)
         {
            UpBuffer[i] = 0;
            DnBuffer[i] = 0;
            UpBuffer2[i] = 0;
            DnBuffer2[i] = 0;
         }
         continue;
      }
      
      if(Variant == var1)
      {
         UpBuffer[i] = uptick;
         DnBuffer[i] = -dntick;
         UpBuffer2[i] = 0;
         DnBuffer2[i] = 0;
      }
      else if(Variant == var2)
      {
         UpBuffer[i] = uppips;
         DnBuffer[i] = -dnpips;
         UpBuffer2[i] = 0;
         DnBuffer2[i] = 0;
      }
      else
      {
         UpBuffer[i] = uptick;
         DnBuffer[i] = -dntick;
         UpBuffer2[i] = uppips;
         DnBuffer2[i] = -dnpips;
      }
   }
   
   if(Logs)
      Print(" UpTicks "+DoubleToString(UpBuffer[rates_total-1],0)+
            " DownTicks "+DoubleToString(DnBuffer[rates_total-1],0)+
            " TotalTicks "+ArraySize(ticks_array)+
            " TicksInBar "+tick_volume[rates_total-1]);
   
   return(rates_total);
  }
//+------------------------------------------------------------------+

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



Файлы:
acde83befc.jpg  210 kb
 
В кодобазе видел нечто подобное. Автор fxsuber.
 
Dmitriy Skub:
В кодобазе видел нечто подобное. Автор fxsuber.
Да, я тоже видел, написал ему
 
Igor Yeremenko:

Код индикатора прикрепляю

Смысл индикатора не уловил. Но поиск "time_msc" дал нулевой результат. Значит, как минимум, есть проблемы с тиками одинакового времени.

Посмотрел внимательнее. Это напрашивается.
CopyTicksRange(_Symbol,ticks_array,COPY_TICKS_INFO,(ulong)time[i]*1000,(ulong)time[i+1]*1000 - 1);
 
Кто сказал, что количество тиков = количеству пунктов? 
Тик ведь может быть и вверх и вниз, в таком случае цена никакие пункты не проходит, а болтается на месте... 
Ты смотришь по барам, но в пределах бара тиковый график мог нарисовать синусоиду, т.е. тиков много, а колебания вокруг нуля. 
Даже если МТ прислал тик с флагом BUY, это не всегда значит, что цена изменилась 
Механика флага TICK_FLAG_BUY / TICK_FLAG_SELL
Механика флага TICK_FLAG_BUY / TICK_FLAG_SELL
  • 2018.07.08
  • www.mql5.com
Доки говорят, что флаг показывает когда на тике произошла сделка на покупку, но не говорят, что подразумевается в виду под термином "сделка...
 
fxsaber:

Смысл индикатора не уловил. Но поиск "time_msc" дал нулевой результат. Значит, как минимум, есть проблемы с тиками одинакового времени.

Посмотрел внимательнее. Это напрашивается.

cмысл индикатора простой

  1. отделить тики ask и bid по отдельности
  2. отделить тики от движения цены на этих тиках (согласно пункта 1)
 
...:
Кто сказал, что количество тиков = количеству пунктов? 

Никто так не сказал, поэтому в идикаторе для тиков и пунктов выводится 2 разных столбца гистограммы

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