Обработчик тиков для профиля объемов

 

Не понимаю где ошибка в обработке тиков для профилей ALL & TRADE

//+------------------------------------------------------------------+
//| Расчет профиля (объём и дельта)                                  |
//+------------------------------------------------------------------+
void CalculateProfile(const MqlTick &ticks[], PROFILE_TYPE profile_type, 
                      double &p_min, double &p_max, double &p_step, 
                      double &volume_profile[], double &delta_profile[], 
                      int &max_delta_buy, int &max_delta_sell, 
                      string frame_name) 
{
   int tick_count = ArraySize(ticks);
   if(tick_count == 0) return;
   
   p_min = ticks[0].last;
   p_max = ticks[0].last;
   for(int i = 1; i < tick_count; i++) 
   {
      if(ticks[i].last < p_min) p_min = ticks[i].last;
      if(ticks[i].last > p_max) p_max = ticks[i].last;
   }
   
   p_step = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE) * PriceAggregation;
   if(p_step <= 0) p_step = _Point * PriceAggregation;
   
   p_min = NormalizeDouble(MathFloor(p_min / p_step) * p_step, _Digits);
   p_max = NormalizeDouble(MathCeil(p_max / p_step) * p_step, _Digits);
   int levels = (int)((p_max - p_min) / p_step) + 1;
   
   if(levels > ArraySize(volume_profile)) 
   {
      ArrayResize(volume_profile, levels);
      ArrayResize(delta_profile, levels);
   }
   ArrayFill(volume_profile, 0, levels, 0);
   ArrayFill(delta_profile, 0, levels, 0);
   
   double max_volume = 0;
   int poc_volume = -1;
   max_delta_buy = -1;
   max_delta_sell = -1;
   double max_buy_delta = 0;
   double max_sell_delta = 0;
   double limit_sell_volume = 0, limit_buy_volume = 0;
   double total_delta = 0;
   
   for(int i = 0; i < tick_count; i++) 
   {
      if(AnalysisMode == TICKS_TO_VLINE && ticks[i].time > vline_time) continue;
      
      double price = NormalizeDouble(ticks[i].last, _Digits);
      int level = (int)((price - p_min) / p_step);
      
      if(level >= 0 && level < levels) 
      {
         double delta = 0;
         double volume = (double)ticks[i].volume;
         
         {
            
            if(double(ticks[i].flags & TICK_FLAG_BUY)!=0 ) 
            {
               delta = volume;
            } 
            else 
            if(double(ticks[i].flags & TICK_FLAG_SELL)!=0 ) 
            {
               delta = -volume;
            }
            else
            {
               delta = 0;
            }
            
            volume_profile[level] += volume;
            delta_profile[level] += delta;
            total_delta += delta;
            
            Print("Tick ", i, ": flags=", ticks[i].flags, ", delta=", delta, ", volume=", volume, ", price=", price);
         }
         
         if(volume_profile[level] > max_volume) 
         {
            max_volume = volume_profile[level];
            poc_volume = level;
         }
         
         if(delta_profile[level] > max_buy_delta) 
         {
            max_buy_delta = delta_profile[level];
            max_delta_buy = level;
         }
         if(delta_profile[level] < max_sell_delta) 
         {
            max_sell_delta = delta_profile[level];
            max_delta_sell = level;
         }
      }
   }
   if(max_delta_buy >= 0 && max_delta_sell >= 0) 
   {
      limit_sell_volume = volume_profile[max_delta_buy] - delta_profile[max_delta_buy];
      limit_buy_volume = volume_profile[max_delta_sell] + delta_profile[max_delta_sell];
   }
   if(frame_name == frame1_name) 
   {
      max_volume1 = max_volume;
      poc_volume1 = poc_volume;
      max_buy_delta1 = (max_delta_buy >= 0) ? delta_profile[max_delta_buy] : 0;
      max_sell_delta1 = (max_delta_sell >= 0) ? delta_profile[max_delta_sell] : 0;
      max_buy_price1 = (max_delta_buy >= 0) ? p_min + max_delta_buy * p_step : 0;
      max_sell_price1 = (max_delta_sell >= 0) ? p_min + max_delta_sell * p_step : 0;
      limit_sell_volume1 = limit_sell_volume;
      limit_buy_volume1 = limit_buy_volume;
      total_delta1 = total_delta;
   } 
   else if(frame_name == frame2_name) 
   {
      max_volume2 = max_volume;
      poc_volume2 = poc_volume;
      max_buy_delta2 = (max_delta_buy >= 0) ? delta_profile[max_delta_buy] : 0;
      max_sell_delta2 = (max_delta_sell >= 0) ? delta_profile[max_delta_sell] : 0;
      max_buy_price2 = (max_delta_buy >= 0) ? p_min + max_delta_buy * p_step : 0;
      max_sell_price2 = (max_delta_sell >= 0) ? p_min + max_delta_sell * p_step : 0;
      limit_sell_volume2 = limit_sell_volume;
      limit_buy_volume2 = limit_buy_volume;
      total_delta2 = total_delta;
   }
   else if(frame_name == frame3_name) 
   {
      max_volume3 = max_volume;
      poc_volume3 = poc_volume;
      max_buy_delta3 = (max_delta_buy >= 0) ? delta_profile[max_delta_buy] : 0;
      max_sell_delta3 = (max_delta_sell >= 0) ? delta_profile[max_delta_sell] : 0;
      max_buy_price3 = (max_delta_buy >= 0) ? p_min + max_delta_buy * p_step : 0;
      max_sell_price3 = (max_delta_sell >= 0) ? p_min + max_delta_sell * p_step : 0;
      limit_sell_volume3 = limit_sell_volume;
      limit_buy_volume3 = limit_buy_volume;
      total_delta3 = total_delta;
   }
   else if(frame_name == frame4_name) 
   {
      max_volume4 = max_volume;
      poc_volume4 = poc_volume;
      max_buy_delta4 = (max_delta_buy >= 0) ? delta_profile[max_delta_buy] : 0;
      max_sell_delta4 = (max_delta_sell >= 0) ? delta_profile[max_delta_sell] : 0;
      max_buy_price4 = (max_delta_buy >= 0) ? p_min + max_delta_buy * p_step : 0;
      max_sell_price4 = (max_delta_sell >= 0) ? p_min + max_delta_sell * p_step : 0;
      limit_sell_volume4 = limit_sell_volume;
      limit_buy_volume4 = limit_buy_volume;
      total_delta4 = total_delta;
   }
Файлы:
9__VP__7_1.mq5  77 kb
 
не понимаю, где мы должны увидеть ошибку
 

ух, понял вопрос :) у себя делал подобное только с запросами торговых тиков (там где был объём), тогда все профили и POCи были такими же, как в объёмных торговых терминалах.

В TICKS_ALL (COPY_TICKS_ALL) будет всё и запросы цены (bid, ask) и торговые тики,  для реальных объёмов абсолютно не нужное, для тиковых объёмов (форекс) только изменение bid и ask (COPY_TICKS_INFO)

PS "Тяжелый" эксперт получился, хотя функционал тут скорее индикаторный, кэширование тиков нужно, CopyTicks/CopyTicksRange довольно медленный...

 
а, ещё обнаружил, что вы рисуете гистограмму OBJ_RECTANGLE (и не удаляете за собой при удалении советника), это очень медленно работает, надо переходить на OBJ_BITMAP/CANVAS тогда можно будет чуть ли не онланй отслеживать изменения.