Таблица всех сделок. Доступ через MQL5

 

Как организовать получение таблицы сделок? Пока не важно из индикатора или из советника. Если периодически (в OnTimer() или в OnTick()) получать историю тиков через CopyTicks - будут складываться в массив MqlTick.

Но простой анализ этого массива не даст ответа - были новые сделки или нет, ибо сравнивать время тика не всегда верно, так как в одну миллисекунду может быть несколько сделок:

Тики 

 
Karputov Vladimir:

Как организовать получение таблицы сделок? Пока не важно из индикатора или из советника. Если периодически (в OnTimer() или в OnTick()) получать историю тиков через CopyTicks - будут складываться в массив MqlTick.

Но простой анализ этого массива не даст ответа - были новые сделки или нет, ибо сравнивать время тика не всегда верно, так как в одну миллисекунду может быть несколько сделок:

 

Используйте событие onBookEvent() оно срабатывает на каждое изменение стакана.

 
Karputov Vladimir:

Как организовать получение таблицы сделок? Пока не важно из индикатора или из советника. Если периодически (в OnTimer() или в OnTick()) получать историю тиков через CopyTicks - будут складываться в массив MqlTick.

Но простой анализ этого массива не даст ответа - были новые сделки или нет, ибо сравнивать время тика не всегда верно, так как в одну миллисекунду может быть несколько сделок: 

Используйте секундные отсечки. Например в MqlTick или даже в OnEvent копируйте новые тики поступившие в течении последней секунды в массив. Разница между предыдущем запомненным значением, и текущем размером массива и будет указывать на количество новых тиков.
 
prostotrader:

Используйте событие onBookEvent() оно срабатывает на каждое изменение стакана.

Стакан - это, если грубо, "дёрганье тикового графика" - это не обязательно изменение в таблице всех сделок.

 

Vasiliy Sokolov:
Используйте секундные отсечки. Например в MqlTick или даже в OnEvent копируйте новые тики поступившие в течении последней секунды в массив. Разница между предыдущем запомненным значением, и текущем размером массива и будет указывать на количество новых тиков.
Что-то вроде маски делать: 0-1-0-1, и если маска стабильна примерно с пяти и десяти строках - значит гарантированное совпадение?
 
Karputov Vladimir:

Стакан - это, если грубо, "дёрганье тикового графика" - это не обязательно изменение в таблице всех сделок.


Если подумать немного, то обязательно будут все сделки.

Вот простенький пример индикатора "Лента всех сделок"

//+------------------------------------------------------------------+
//|                                                    DealsLent.mq5 |
//|                                     Copyright 2016, prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
input int  Ticks     = 100; //Тики 

#property indicator_separate_window

#property indicator_buffers 2
#property indicator_plots   2

//--- plot Label1
#property indicator_label1  "Sell"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Label1
#property indicator_label2  "Buy"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- indicator buffers
double SellBuffer[];
double BuyBuffer[];
double sell_deals;
double buy_deals;
long curr_time;
int event_cnt;
bool on_call;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   curr_time=0;
   if(!MarketBookAdd(Symbol()))
     {
      Print(__FUNCTION__,": Стакан символа "+Symbol()+" не добавден!");
      return( INIT_FAILED );
     }
//--- Period 
   if(Period()!=PERIOD_M1)
     {
      Print("Ошибка! Период графика должен быть 'M1'");
      return( INIT_FAILED );
     }
//---  
   IndicatorSetInteger(INDICATOR_DIGITS,0);
   IndicatorSetString(INDICATOR_SHORTNAME,"DealsLent");
//---  
   SetIndexBuffer(0,SellBuffer,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   ArraySetAsSeries(SellBuffer,true);
//---
   SetIndexBuffer(1,BuyBuffer,INDICATOR_DATA);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   ArraySetAsSeries(BuyBuffer,true);
//--- 
   event_cnt=0;
   on_call=false;
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+  
void OnDeinit(const int reason)
  {
   MarketBookRelease(Symbol());
   if(reason==REASON_INITFAILED)
     {
      int window=ChartWindowFind(ChartID(),"DealsLent");
      ChartIndicatorDelete(ChartID(),window,"DealsLent");
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator On book event function                          |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
   MqlTick ticks[];
   if(symbol==Symbol())
     {
      if(curr_time==0)
        {
         if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,1)==1)
           {
            curr_time=ticks[0].time_msc;
           }
        }
      else
        {
         sell_deals= 0;
         buy_deals = 0;
         if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,Ticks)==Ticks)
           {
            for(int i=0; i<Ticks; i++)
              {
               if(ticks[i].time_msc!=curr_time)
                 {
                  if(( ticks[i].flags  &TICK_FLAG_BUY)==TICK_FLAG_BUY)
                    {
                     buy_deals++;
                    }
                  else
                  if(( ticks[i].flags  &TICK_FLAG_SELL)==TICK_FLAG_SELL)
                    {
                     sell_deals++;
                    }
                 }
              }
           }
         curr_time=ticks[0].time_msc;
         double price[];
         on_call=true;
         OnCalculate(event_cnt,event_cnt,0,price);
        }
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   if(prev_calculated==0)
     {
      ArrayInitialize(SellBuffer,EMPTY_VALUE);
      ArrayInitialize(BuyBuffer,EMPTY_VALUE);
     }
   else
     {
      if(rates_total==event_cnt)
        {
         if(on_call)
           {
            on_call=false;
            //---        
            for(int i=rates_total-1; i>0; i--)
              {
               SellBuffer[i]= SellBuffer[i-1];
               BuyBuffer[i] = BuyBuffer[i-1];
              }
            SellBuffer[0]= double(sell_deals);
            BuyBuffer[0] = double(buy_deals);
           }
        }
      else
        {
         if(on_call)
           {
            on_call=false;
            SellBuffer[0]= double(sell_deals);
            BuyBuffer[0] = double(buy_deals);
           }
         else
           {
            SellBuffer[0]= SellBuffer[1];
            BuyBuffer[0] = BuyBuffer[1];
           }
        }
     }
   event_cnt=rates_total;
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

 


 
prostotrader:

Если подумать немного, то обязательно будут все сделки.

Вот простенький пример индикатора "Лента всех сделок"

 


Не удалось запустить:

2016.08.24 15:54:41.700 DealsLent (RTS-12.16,M1)        array out of range in 'DealsLent.mq5' (118,25)

 Ошибка

 
Karputov Vladimir:

Не удалось запустить:

 

void OnBookEvent(const string &symbol)
  {
   MqlTick ticks[];
   if(symbol==Symbol())
     {
      if(curr_time==0)
        {
         if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,1)==1)
           {
            curr_time=ticks[0].time_msc;
           }
        }
      else
        {
         sell_deals= 0;
         buy_deals = 0;
         if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,Ticks)==Ticks)
           {
            for(int i=0; i<Ticks; i++)
              {
               if(ticks[i].time_msc!=curr_time)
                 {
                  if(( ticks[i].flags  &TICK_FLAG_BUY)==TICK_FLAG_BUY)
                    {
                     buy_deals++;
                    }
                  else
                  if(( ticks[i].flags  &TICK_FLAG_SELL)==TICK_FLAG_SELL)
                    {
                     sell_deals++;
                    }
                 }
              }
             curr_time=ticks[0].time_msc; 
             double price[];
             on_call=true;
             OnCalculate(event_cnt,event_cnt,0,price);
           }
        }
     }
  }
 
Karputov Vladimir:

Стакан - это, если грубо, "дёрганье тикового графика" - это не обязательно изменение в таблице всех сделок. 

Что-то вроде маски делать: 0-1-0-1, и если маска стабильна примерно с пяти и десяти строках - значит гарантированное совпадение?
Да.
 

Karputov Vladimir 

дарю полнофункциональный индикатор "Лента всех сделок"

//+------------------------------------------------------------------+
//|                                                    DealsLent.mq5 |
//|                                     Copyright 2016, prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Label1
#property indicator_label1  "Sell"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Label1
#property indicator_label2  "Buy"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- indicator buffers
double SellBuffer[];
double BuyBuffer[];
double sell_deals;
double buy_deals;
ulong start_time;
int event_cnt;
bool on_call;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   start_time=0;
   if(!MarketBookAdd(Symbol()))
     {
      Print(__FUNCTION__,": Стакан символа "+Symbol()+" не добавден!");
      return( INIT_FAILED );
     }
//--- Bars
  int bars=Bars(Symbol(),PERIOD_CURRENT);
  if (bars<3)
  {
    Print(__FUNCTION__,": Не достаточно баров на текущем таймфрейме!");
    return( INIT_FAILED );
  }     
//---  
   IndicatorSetInteger(INDICATOR_DIGITS,0);
   IndicatorSetString(INDICATOR_SHORTNAME,"DealsLent");
//---  
   SetIndexBuffer(0,SellBuffer,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   ArraySetAsSeries(SellBuffer,true);
//---
   SetIndexBuffer(1,BuyBuffer,INDICATOR_DATA);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   ArraySetAsSeries(BuyBuffer,true);
//--- 
   event_cnt=0;
   on_call=false;
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+  
void OnDeinit(const int reason)
  {
   MarketBookRelease(Symbol());
   if(reason==REASON_INITFAILED)
     {
      int window=ChartWindowFind(ChartID(),"DealsLent");
      ChartIndicatorDelete(ChartID(),window,"DealsLent");
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator On book event function                          |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
   MqlTick ticks[];
   if(symbol==Symbol())
     {
      if(start_time==0)
        {
         if(CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,0,1)==1)
           {
            start_time=ulong(ticks[0].time_msc);
           }
        }
      else
        {
         sell_deals= 0;
         buy_deals = 0;
         int copied= CopyTicks(Symbol(),ticks,COPY_TICKS_ALL,start_time,0);
         if(copied>0)
           {
            for(int i=0; i<copied; i++)
              {
               if(( ticks[i].flags  &TICK_FLAG_BUY)==TICK_FLAG_BUY)
                 {
                  buy_deals++;
                 }
               else
               if(( ticks[i].flags  &TICK_FLAG_SELL)==TICK_FLAG_SELL)
                 {
                  sell_deals++;
                 }
              }
            start_time=ulong(ticks[copied - 1].time_msc);
            double price[];
            on_call=true;
            OnCalculate(event_cnt,event_cnt,0,price);
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   if(prev_calculated==0)
     {
      ArrayInitialize(SellBuffer,EMPTY_VALUE);
      ArrayInitialize(BuyBuffer,EMPTY_VALUE);
     }
   else
     {
      if(rates_total==event_cnt)
        {
         if(on_call)
           {
            on_call=false;
            //---        
            for(int i=rates_total-1; i>0; i--)
              {
               SellBuffer[i]= SellBuffer[i-1];
               BuyBuffer[i] = BuyBuffer[i-1];
              }
            SellBuffer[0]= double(sell_deals);
            BuyBuffer[0] = double(buy_deals);
           }
        }
      else
        {
         if(on_call)
           {
            on_call=false;
            SellBuffer[0]= double(sell_deals);
            BuyBuffer[0] = double(buy_deals);
           }
         else
           {
            SellBuffer[0]= SellBuffer[1];
            BuyBuffer[0] = BuyBuffer[1];
           }
        }
     }
   event_cnt=rates_total;
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
prostotrader:

Karputov Vladimir 

дарю полнофункциональный индикатор "Лента всех сделок" 

Вот спасибо !! на днях  об этом идея  в голове кружила 
 
Нашёл ошибку и оптимизировал работу.
Файлы:
DealsLent.mq5  6 kb
Причина обращения: