подсчет реального объема по фьючерсам

 

Привет всем!

Открыт демосчет в ***

Написал небольшой индюк для подсчета реального объема торговли на фьючерсах (евродоллар, нефть, золото, и др.)

//+------------------------------------------------------------------+
//|                                                            1.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

MqlTick tick_array[];   // массив для приема тиков
MqlTick lasttick;
long Volume;
double Buy,Sell,V,ask,bid,last;
string symb;
int BARS;
uint flag;
ENUM_TIMEFRAMES per;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   symb=_Symbol;
   per=_Period;
//---
   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[])
  {
//---

   Volume=volume[rates_total-1];

   if(SymbolInfoTick(symb,lasttick)) 
   {
   bid=lasttick.bid;
   ask=lasttick.ask;
   last=lasttick.last;
   flag=lasttick.flags;

   string s;
   if(lasttick.flags & TICK_FLAG_BID)    s+="BID|";
   if(lasttick.flags & TICK_FLAG_ASK)    s+="ASK|";
   if(lasttick.flags & TICK_FLAG_LAST)   s+="LAST|";
   if(lasttick.flags & TICK_FLAG_VOLUME) s+="VOL|";
   if(lasttick.flags & TICK_FLAG_BUY)    s+="BUY|";
   if(lasttick.flags & TICK_FLAG_SELL)   s+="SELL|";
  //Print(s);

   iif(s=="LAST|VOL|BUY|" || s=="VOL|BUY|") Buy=Buy+lasttick.volume; else
   if(s=="LAST|VOL|SELL|" || s=="VOL|SELL|") Sell=Sell+lasttick.volume; 
   V=Buy+Sell;
   }
   IsNewBar();

   show();
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
bool IsNewBar()
  {
   if(BARS!=Bars(symb,per))
     {
      BARS=Bars(symb,per);
      Print("Volume= ",V,"  Buy= ",Buy,"  Sell= ",Sell);
      Buy=0; Sell=0; V=0;

      return(true);
     }
   return(false);
  }
//-----------------------------
void show()
  {

   string text1="\n\nVolume           "+(string)Volume+
                "\n\nBuy: "+(string)Buy+"   Sell= "+(string)Sell
                ;
   Comment(text1);
  }
//-----------------------------------------------  

Обнаружил существенное различие в результате подсчета объема "Volume=volume[rates_total-1];"  и SymbolInfoTick. Сравнил с биржевой информацией СМЕ, оказалось, "Volume=volume[rates_total-1];" выдает правильный общий объем торгов, а "SymbolInfoTick" существенно занижает объемы, в среднем на 20-30%.

Вопрос к разработчикам МТ5. В чем может быть причина?

 
Наверное, объемы по изменению Bid / Ask тоже следует учитывать.
 
SemenTalonov:
Наверное, объемы по изменению Bid / Ask тоже следует учитывать.
Да, я тоже это заметил. Проверил результаты по индикаторам нинзи / amp. Тоже не совпадает. То бай больше, то сел. Те же 20-30% Хотя не ясно, чем изменения  по Ask-Bid могут влиять на Buy-Sell как итог сделки. Тем более, для этого указаны соответствующие флаги.  Брал флаг только по volume, с фильтрацией по last>=ask   - buy, last<=bid   -sell  Тоже врет.
 
Если значение volume[] является производным от данных по тикам, значит Ваша формула расчета результирующего объема не верна. Когда я задал вопрос на эту тему, никто из участников не смог на него ответить.
 
SemenTalonov:
Если значение volume[] является производным от данных по тикам, значит Ваша формула расчета результирующего объема не верна. Когда я задал вопрос на эту тему, никто из участников не смог на него ответить.

Извините, не понял Вашу мысль.  Собственно ставил задачу получить реальные объемы торгов по фьючам с разбивкой по бай и селл. В нинзе это делается фильтрацией поступающих объемов по last>=ask   - buy, last<=bid   -sell В МТ5, как я понимаю, для этого есть функция "OnCalculate" и SymbolInfoTick. Первая выдает правильный общий объем, вторая - нет. Поэтому и хотел обратиться к разработчикам. Полагаю, большинство участников форума торгует на форексе, там нет реального объема и они его не используют.

Кстати в тему. Попробовал использовать метод нинзи, с таким кодом

long volume1;

//-------------------------
volume=volume1;
Volume=volume[rates_total-1];

if (Volume>Volume1) 
     {
      bid=SymbolInfoDouble(symb,SYMBOL_BID); 
      ask=SymbolInfoDouble(symb,SYMBOL_ASK);
      last=SymbolInfoDouble(symb,SYMBOL_LAST); 

      if (ask<=last) Buy=Buy+(Volume-Volume1); else
      if (bid>=last) Sell=Sell+(Volume-Volume1);
      
       V=V+(Volume-Volume1);
      }

Тоже пропускает большой объем. Но эта тема была как-то описана: это происходит за счет значений бид, аск, ласт превышающих Digits.

Рекомендовали по ценам  bid=NormalizeDouble(SymbolInfoDouble(symb,SYMBOL_BID),_Digits), но и это не помогает. Посмотрел пропускаемый объем, картина примерно такая: bid=55.51 ask=55.53, last=55.52 !! То есть сделка проходит внутри спреда!?  Предположил, что NormalizeDouble не дает результата и попробовал так:

      if (ask-_Point<last) Buy=Buy+(Volume-Volume1); else
      if (bid+_Point>last) Sell=Sell+(Volume-Volume1);

То есть "сузил" границу между и бидом и аском до нуля, сумма Бай и Селл полностью совпала с volume[rates_total-1];, НО!  Величины Бай и Селл различаются от результата Нинзи, которую считаю эталоном. Опять таки 20-30% в ту или другую сторону

 
Попробуйте изучить CopyTick.
 
Dmitriy Skub:
Попробуйте изучить CopyTick.
Спасибо попробую как-нибудь. А как-то проще не можете объяснить ситуацию? Может быть, на примерах? Всегда был уверен, что все гениальное - просто.
 
rjurip1:
Спасибо попробую как-нибудь. А как-то проще не можете объяснить ситуацию? 

Там нечего изучать. CopyTick возвращает массив тиков за указанный период времени а SymbolInfoTick последний тик. Формат возвращаемых данных один и тот же, структура MqlTick.

Может ли SymbolInfoTick пропускать тики? стоит проверить..

rjurip1:

, там нет реального объема и они его не используют.

Уж не знаю насколько он реальный, но volume[] в отличии от tick_volume[](в индикаторах) заявлен именно как реальный.

rjurip1:

bid=55.51 ask=55.53, last=55.52 !! То есть сделка проходит внутри спреда!?  

Я так понимаю.. last это цена последней сделки, а она могла быть совершена по предыдущей цене. Т.е. весь объем на 55.52 был выкуплен/продан, вследствие чего и изменилось значение Bid/Ask.

 
rjurip1:
Спасибо попробую как-нибудь. А как-то проще не можете объяснить ситуацию? Может быть, на примерах? Всегда был уверен, что все гениальное - просто.

В сервисдеск ошибку отправьте. Они или исправят ее в терминале (к след. релизу) илу укажут на вашу ошибку.
Потом поделитесь тут результатом. Интересно...

 
SemenTalonov:

Там нечего изучать. CopyTick возвращает массив тиков за указанный период времени а SymbolInfoTick последний тик. Формат возвращаемых данных один и тот же, структура MqlTick.

Может ли SymbolInfoTick пропускать тики? стоит проверить..

Уж не знаю насколько он реальный, но volume[] в отличии от tick_volume[](в индикаторах) заявлен именно как реальный.

Я так понимаю.. last это цена последней сделки, а она могла быть совершена по предыдущей цене. Т.е. весь объем на 55.52 был выкуплен/продан, вследствие чего и изменилось значение Bid/Ask.

Проверил, как и по докам SymbolInfoTick  повторяет инфу, даже если она не изменилась. Изменения только по времени тиков и флагам. Но что удивляет volume[rates_total-1]; проводит изменения объема, а SymbolInfoTick показывает флаг изменения ask  или bid, и нет флага изменения объема! Как такое может быть? Полагаю, программный баг. И last всегда должен соответствовать или ask или bid. Конечно, возможна ситуация изменения last, bid, ask с одновременным изменением  volume.  И это проверял. Может меняется ask, bid  и без изменения объемов (по правилам биржи)  расширение спреда в малоликвидный период.Но все проверяется в ликвидный период с контрольной проверкой по Нинзятрейдер.

По второму. Что такое volume[] в отличии от tick_volume[]? Это то, что вам выдает брокер. На фьючерсах, это реальные объемы, проводимые на бирже. Дата фид нужно получать от брокера зарегистрированного на бирже. Нефть WTI биржа СМЕ Nymex - основные торги. Тики, это - просто дергание цены, но и в этом случае лучше эту инфу получать от брокера))

 
elibrarius:

В сервисдеск ошибку отправьте. Они или исправят ее в терминале (к след. релизу) илу укажут на вашу ошибку.
Потом поделитесь тут результатом. Интересно...

К сожалению, "сервисдеск" в профиле убрали. Приходится обращаться к общественности ))