Derivatemarkt-Kurse in MT5

 

Liebe Moderatoren!

Bitte verschieben Sie die Beiträge aus dem Thema "Clearing auf der merits????*

die nichts mit dem Clearing zu tun haben, hier.

Форум трейдеров - MQL5.community
Форум трейдеров - MQL5.community
  • www.mql5.com
MQL5: форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
 

Bitte helfen Sie, einen Fehler im Code zu finden, oder bestätigen Sie, dass CopyTicks() nicht korrekt funktioniert.

Problem: Tick-Skipping, wenn mit CopyTicks() kopiert wird

Reihenfolge der Arbeitsschritte:

Code

//+------------------------------------------------------------------+
//|                                                ABL_Collector.mq5 |
//|                                     Copyright 2021, prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
input string StTime =  "07:00:00";  //Начало сбора тиков
input string EndTime = "23:50:00";  //Конец сбора тиков
//---
struct MARKET_DATA
  {
   int               cnt;
   datetime          time[];
   ulong             time_msc[];
   double            ask[];
   double            bid[];
   double            last[];
   long              volume[];
   string            flags[];
   ulong             mem_time;
   int               skip_cnt;
   MqlTick           ticks[];
  } m_data;
int f_handle;
datetime start_time, end_time;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   m_data.cnt = 0;
   m_data.mem_time = 0;
   ArrayResize(m_data.time, 5000000, 5000000);
   ArrayResize(m_data.time_msc, 5000000, 5000000);
   ArrayResize(m_data.ask, 5000000, 5000000);
   ArrayResize(m_data.bid, 5000000, 5000000);
   ArrayResize(m_data.last, 5000000, 5000000);
   ArrayResize(m_data.volume, 5000000, 5000000);
   ArrayResize(m_data.flags, 5000000, 5000000);
   f_handle = FileOpen("ABL_Colletor.csv", FILE_WRITE|FILE_CSV);
   if(f_handle == INVALID_HANDLE)
     {
      Alert("Не создан *.CSV файл!");
      return(INIT_FAILED);
     }
   else
     {
      FileWrite(f_handle, "Symbol: ", Symbol());
      FileWrite(f_handle, "Tick num", "Date", "Tick time", "ASK", "BID", "LAST", "VOLUME", "Tick Flags");
     }
   start_time = StringToTime(StTime);
   end_time = StringToTime(EndTime);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(f_handle != INVALID_HANDLE)
     {
      ulong a_time = m_data.time_msc[0];
      for(int i = 0; i<m_data.cnt; i++)
        {
         if(a_time != m_data.time_msc[i])
           {
            FileWrite(f_handle, "");
            a_time = m_data.time_msc[i];
           }
         FileWrite(f_handle, IntegerToString(i + 1),
                   TimeToString(m_data.time[i], TIME_DATE),
                   TimeToString(m_data.time[i], TIME_SECONDS) + "." + StringFormat("%03i", m_data.time_msc[i]%1000),
                   DoubleToString(m_data.ask[i], Digits()),
                   DoubleToString(m_data.bid[i], Digits()),
                   DoubleToString(m_data.last[i], Digits()),
                   string(m_data.volume[i]),
                   m_data.flags[i]);

        }
     }
   ArrayResize(m_data.time, 0, -1);
   ArrayResize(m_data.time_msc, 0, -1);
   ArrayResize(m_data.ask, 0, -1);
   ArrayResize(m_data.bid, 0, -1);
   ArrayResize(m_data.last, 0, -1);
   ArrayResize(m_data.volume, 0, -1);
   ArrayResize(m_data.flags, 0, -1);
  }
//+------------------------------------------------------------------+
//| Expert fill data function                                        |
//+------------------------------------------------------------------+
void FillData(const int skip, const int t_cnt)
  {
   string c_flags;
   m_data.skip_cnt = 0;                                                      //Обнуляем счетчик тиков с одним временем (последним)
   for(int i = skip; i < t_cnt; i++)
     {
      c_flags = "";
      m_data.ask[m_data.cnt] = m_data.ticks[i].ask;                                              //Сохраняем значения
      m_data.bid[m_data.cnt] = m_data.ticks[i].bid;
      m_data.last[m_data.cnt] = m_data.ticks[i].last;
      m_data.volume[m_data.cnt] = long(m_data.ticks[i].volume_real);
      m_data.time[m_data.cnt] = m_data.ticks[i].time;
      m_data.time_msc[m_data.cnt] = m_data.ticks[i].time_msc;
      //Собираем все флаги
      if((m_data.ticks[i].flags&TICK_FLAG_ASK) == TICK_FLAG_ASK)
         c_flags += " TICK_FLAG_ASK,";    
      if((m_data.ticks[i].flags&TICK_FLAG_BID) == TICK_FLAG_BID)
         c_flags += " TICK_FLAG_BID,";
      if((m_data.ticks[i].flags&TICK_FLAG_LAST) == TICK_FLAG_LAST)
         c_flags += " TICK_FLAG_LAST,";
      if((m_data.ticks[i].flags&TICK_FLAG_BUY) == TICK_FLAG_BUY)
         c_flags += " TICK_FLAG_BUY,";
      if((m_data.ticks[i].flags&TICK_FLAG_SELL) == TICK_FLAG_SELL)
         c_flags += " TICK_FLAG_SELL,";
      if((m_data.ticks[i].flags&TICK_FLAG_VOLUME) == TICK_FLAG_VOLUME)
         c_flags += " TICK_FLAG_VOLUME,";
      int f_len = StringLen(c_flags);                                                          //Кастрируем последнюю запятую в строке
      if(f_len > 1)
        {
         StringSetCharacter(c_flags, f_len - 1, ushort(" "));
         StringTrimRight(c_flags);
        }
      m_data.flags[m_data.cnt] = c_flags + " (" + string(m_data.ticks[i].flags) + ")";         //Записываем флаги
      m_data.cnt++;                                                                            //Увеличиваем счетчик всех записей
      if(m_data.mem_time == ulong(m_data.ticks[i].time_msc))
         m_data.skip_cnt++;                                                  //Увеличиваем счетчик тиков с последним (одинаковым) временем
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   datetime cur_time = TimeTradeServer();                                 //Берем текущее время сервера
   if((cur_time >=start_time)&&(cur_time<end_time))                       //Проверка времени торговли
     {
      int result = 0;
      if(m_data.mem_time == 0)                                             //Проверка на 1-ю запись
        {
         result = CopyTicks(Symbol(), m_data.ticks, COPY_TICKS_ALL, 0, 20); //Копируем последние 20 тиков
         if(result >= 1)
           {
            m_data.mem_time = ulong(m_data.ticks[result-1].time_msc);        //Запоминаем время последнего тика
            FillData(0, result);                                             //Сохраняем данные
           }
        }
      else  //Последующие записи
        {
         result = CopyTicks(Symbol(), m_data.ticks, COPY_TICKS_ALL, m_data.mem_time, 1000); //Копируем тики с запомненного времени
         if(result >= 1)                                                                    //плюс последующие тики (если есть)
           {
            if(m_data.mem_time < ulong(m_data.ticks[result-1].time_msc))    //Проверяем, изменилось ли время последнего тика
              {
               m_data.mem_time = ulong(m_data.ticks[result-1].time_msc);     //Запоминаем время последнего тика
               FillData(m_data.skip_cnt, result);                            //Сохраняем данные, минус уже сохраненные с
              }                                                               //предыдущим последнем временем (m_data.skip_cnt)
           }
        }
     }
  }
//+------------------------------------------------------------------+

Nachdem der Expert Advisor funktioniert, erhalten wir die Datei ABL_Colletor.csv (in der Zip-Datei)

Ich speichere Zecken aus dem Terminal

Ich erhalte GAZR-12.21.csv (in zip)

Vergleich der Dateien in GAZR-12.21_mix.csv.xlsx ( in der Zip-Datei)

Dateien:
Files_lost.zip  74 kb
 
Wo liegt also das Problem? Gibt es Unstimmigkeiten in den Zitaten?
 
Ich sehe keine Fehler im Quellcode. Ich nehme an, dass es ohne Auslassungen funktioniert, wenn Sie COPY_TICKS_ALL durch einen anderen Wert ersetzen.
 
Mihail Marchukajtes #:
Wo liegt also das Problem? Gibt es Unstimmigkeiten in den Zitaten?

Existieren.

Physisch sind Anführungszeichen im Terminal vorhanden, aber sie können nichtalle abgerufen werden(COPY_TICKS_ALL).

 
fxsaber #:
Ich kann keinen Fehler im Quellcode erkennen. Ich nehme an, dass es ohne Lücken funktioniert, wenn Sie COPY_TICKS_ALL durch einen anderen Wert ersetzen.

Ich werde es jetzt ausprobieren, aber es sollte auch mit COPY_TICKS_ALL funktionieren.

 

Ja, in der Tat, mit dem COPY_TICKS_TRADE-Flag, keine Skips, aber ich brauche sowohl Trades und Gebote fragt,

wieder eine Krücke?

result = CopyTicks(Symbol(), m_data.ticks, COPY_TICKS_TRADE, m_data.mem_time, 1000);
//плюс
result = CopyTicks(Symbol(), m_data.ticks, COPY_TICKS_INFO, m_data.mem_time, 1000);

Aber 2 große Probleme entstehen sofort.

1. Wie man die Zeit "synchronisiert"

2. So überprüfen Sie ASK und BID auf ihre Korrektheit

 
prostotrader #:

Ja, in der Tat, mit dem COPY_TICKS_TRADE-Flag, keine Skips, aber ich brauche sowohl Trades und fragt mit Geboten,

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

Neuer MetaTrader 5 build 3081: Verbesserungen in MQL5 Services und aktualisiertes Design

fxsaber, 2021.10.19 16:30

Zwei verschiedene Threads (INFO und LAST) werden künstlich zu einem ALL-flow zusammengefasst.

In derselben Millisekunde gab die Börse im INFO-Fluss einen Geldkurs von 36800 an. Und im LAST-flow gab es eine Menge Angebote. Wenn die Zeit in Nanosekunden gemessen würde, wäre der INFO-Preis natürlich später als die Geschäfte.


MT5 benötigt Zeit, um die Streams zusammenzuführen und zu synchronisieren. Aus diesem Grund kann es bei der Erstellung des aktuellen Tickverlaufs zu erheblichen Verzögerungen in Echtzeit kommen. Es können Millisekunden verloren gehen.

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Neuer MetaTrader 5 build 3081: Verbesserungen in MQL5 Services und aktualisiertes Design

fxsaber, 2021.10.19 16:38

Ich denke, wenn Sie den Book-Stream im Terminal überwachen und ihn mit den frischen CopyTicks vergleichen, werden Sie eine Menge Abweichungen feststellen. Im Nachhinein betrachtet, wird es aber ziemlich gut sein.

 
fxsaber #:

Die Geschäfte der Börse laufen in einem separaten Strom, ja,

sowie fragen und bieten.

COPY_TICKS_ALL nimmt Stichproben aus diesen beiden Strömen, es ist nur nicht richtig gemacht.

Und diese Probe kann nicht Millisekunden dauern, weil beide Threads "durchgängig" Zeit haben, nicht in getrennten Threads!

Ich habe eine Krücke gebaut, die zu funktionieren scheint.

//+------------------------------------------------------------------+
//|                                                ABL_Collector.mq5 |
//|                                     Copyright 2021, prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
input string StTime =  "07:00:00";  //Начало сбора тиков
input string EndTime = "23:50:00";  //Конец сбора тиков
//---
struct MARKET_DATA
{
   datetime time;
   ulong    time_msc;
   double   ask;
   double   bid;
   double   last;
   long     volume;
   string   flags;
};
struct A_DATA
{
  int         cnt;
  ulong       m_time_info;
  ulong       m_time_trade;
  int         s_cnt_info;
  int         s_cnt_trade;
  MqlTick     ticks_trade[];
  MqlTick     ticks_info[];
  MARKET_DATA m_data[];
}a_data;
  
int f_handle;
datetime start_time, end_time;
//+------------------------------------------------------------------+
//| Expert Array fast sort function                                  |
//+------------------------------------------------------------------+
void ArrayFastSort(MARKET_DATA &array[], const int size)
{
   ulong msc_val;
   MARKET_DATA temp;
   MARKET_DATA tmp_arr[];
   ArrayResize(tmp_arr, size, size);
   for(int i = 0; i < size; i++)
   {
     tmp_arr[i] = array[i];   
   }
   int n[] = {9,5,3,2,1};
   int i, j, z, y;
   for(z = 0;z < 5;z++)
   {
     y = n[z];
     for(i = y;i < size;i++)
     {
       msc_val = tmp_arr[i].time_msc;
       temp = tmp_arr[i];
       for(j = i - y; j >= 0 && msc_val < tmp_arr[j].time_msc; j -= y)
       {
         tmp_arr[j + y] = tmp_arr[j];
       }
       tmp_arr[j + y] = temp;
     }
  }
  for(i = 0; i < size; i++)
  {
    msc_val = tmp_arr[i].time_msc;
    for(j = 0; j < size; j++)
    {
      if(array[j].time_msc == 0) continue;
      if(msc_val == array[j].time_msc)
      {
        tmp_arr[i] = array[j];
        array[j].time_msc = 0;
        break;
      }
    }   
  }
  for(i = 0; i < size; i++)
  {
    array[i] = tmp_arr[i];   
  }
}
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   a_data.cnt = 0;
   a_data.m_time_info = 0;
   a_data.m_time_trade = 0;
   ArrayResize(a_data.m_data, 5000000, 5000000);
   f_handle = FileOpen("ABL_Colletor.csv", FILE_WRITE|FILE_CSV);
   if(f_handle == INVALID_HANDLE)
     {
      Alert("Не создан *.CSV файл!");
      return(INIT_FAILED);
     }
   else
     {
      FileWrite(f_handle, "Symbol: ", Symbol());
      FileWrite(f_handle, "Tick num", "Date", "Tick time", "ASK", "BID", "LAST", "VOLUME", "Tick Flags");
     }
   start_time = StringToTime(StTime);
   end_time = StringToTime(EndTime);
   int result = CopyTicks(Symbol(), a_data.ticks_info, COPY_TICKS_ALL, 0, 1);
   if(result >= 1)
   {
     a_data.m_time_info = a_data.ticks_info[0].time_msc;
     a_data.m_time_trade = a_data.ticks_info[0].time_msc;
   }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(f_handle != INVALID_HANDLE)
  {
    ArrayFastSort(a_data.m_data, a_data.cnt);
    ulong a_time = a_data.m_data[0].time_msc;
    for(int i = 0; i < a_data.cnt; i++)
    {
      if(a_time != a_data.m_data[i].time_msc)
      {
        FileWrite(f_handle, "");
        a_time = a_data.m_data[i].time_msc;
      }
      FileWrite(f_handle, IntegerToString(i + 1),
                TimeToString(a_data.m_data[i].time, TIME_DATE),
                TimeToString(a_data.m_data[i].time, TIME_SECONDS) + "." + StringFormat("%03i", a_data.m_data[i].time_msc%1000),
                DoubleToString(a_data.m_data[i].ask, Digits()),
                DoubleToString(a_data.m_data[i].bid, Digits()),
                DoubleToString(a_data.m_data[i].last, Digits()),
                string(a_data.m_data[i].volume),
                a_data.m_data[i].flags);

    }
  }
  ArrayResize(a_data.m_data, 0, -1);
  Print("Collect ticks DONE!");
}
//+------------------------------------------------------------------+
//| Expert fill data function                                        |
//+------------------------------------------------------------------+
void FillData(const int skip, const int t_cnt, ulong &mem_time, int &skip_cnt, MqlTick &ticks[])
{
  string c_flags;
  skip_cnt = 0;
  for(int i = skip; i < t_cnt; i++)
  {
    c_flags = "";
    a_data.m_data[a_data.cnt].ask = ticks[i].ask;                                           
    a_data.m_data[a_data.cnt].bid = ticks[i].bid;
    a_data.m_data[a_data.cnt].last = ticks[i].last;
    a_data.m_data[a_data.cnt].volume = long(ticks[i].volume_real);
    a_data.m_data[a_data.cnt].time = ticks[i].time;
    a_data.m_data[a_data.cnt].time_msc = ticks[i].time_msc;
//---
    if((ticks[i].flags&TICK_FLAG_ASK) == TICK_FLAG_ASK)
      c_flags += " TICK_FLAG_ASK,";    
    if((ticks[i].flags&TICK_FLAG_BID) == TICK_FLAG_BID)
      c_flags += " TICK_FLAG_BID,";
    if((ticks[i].flags&TICK_FLAG_LAST) == TICK_FLAG_LAST)
      c_flags += " TICK_FLAG_LAST,";
    if((ticks[i].flags&TICK_FLAG_BUY) == TICK_FLAG_BUY)
      c_flags += " TICK_FLAG_BUY,";
    if((ticks[i].flags&TICK_FLAG_SELL) == TICK_FLAG_SELL)
      c_flags += " TICK_FLAG_SELL,";
    if((ticks[i].flags&TICK_FLAG_VOLUME) == TICK_FLAG_VOLUME)
      c_flags += " TICK_FLAG_VOLUME,";
    int f_len = StringLen(c_flags); 
    if(f_len > 1)
    {
       StringSetCharacter(c_flags, f_len - 1, ushort(" "));
       StringTrimRight(c_flags);
    } 
    a_data.m_data[a_data.cnt].flags = c_flags + " (" + string(ticks[i].flags) + ")"; 
    a_data.cnt++;                                                                    
    if(mem_time == ulong(ticks[i].time_msc)) skip_cnt++;    
  }
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
  datetime cur_time = TimeTradeServer();                            
  if((cur_time >=start_time)&&(cur_time<end_time))                  
  {
      int result = 0;
      result = CopyTicks(Symbol(), a_data.ticks_info, COPY_TICKS_INFO, a_data.m_time_info, 1000);
      if(result >= 1)
      {
        if(a_data.m_time_info < ulong(a_data.ticks_info[result -1].time_msc))
        {
          a_data.m_time_info = a_data.ticks_info[result -1].time_msc;
          FillData(a_data.s_cnt_info, result, a_data.m_time_info, a_data.s_cnt_info, a_data.ticks_info);
        }
      }
      result = CopyTicks(Symbol(), a_data.ticks_trade, COPY_TICKS_TRADE, a_data.m_time_trade, 1000);
      if(result >= 1)
      {
        if(a_data.m_time_trade < ulong(a_data.ticks_trade[result -1].time_msc))
        {
          a_data.m_time_trade = a_data.ticks_trade[result -1].time_msc;
          FillData(a_data.s_cnt_trade, result, a_data.m_time_trade, a_data.s_cnt_trade, a_data.ticks_trade);
        }
    }
  }
}
//+------------------------------------------------------------------+

Sie können es verwenden, wenn jemand Angebote einholen muss.

Schade, dass Nachfragen und Gebote nicht mit der Börse abgeglichen werden können.

 

Zusammenfassung der Untersuchung von CopyTicks() CopyTicksRange()

Bild 3101, real, Offen

1. Wenn das Kennzeichen COPY_TICKS_ALL verwendet wird, werden Transaktionen übersprungen,

beiVerwendung des FlagsCOPY_TICKS_TRADE- korrekt angezeigt werden.

2. Etwas Unvorstellbares geschieht mit Zitaten (ASK/BID)

Die Geschäfte werden zu Preisen ausgeführt, die nicht existieren


Transaktionen werden zum entgegengesetzten Preis ausgeführt (statt ASK wird BID verwendet)

Überspringen von Zitaten

Das ist eine wichtige Frage:

Wenn es eine große Preisdiskrepanz gibt, was ist dann im Terminal?

Zu welchen Preisen werden wir gehandelt?

Quelldateien im ZIP-Archiv


Dateien:
 
prostotrader #:

2. Bei den Kursen ist etwas Unvorstellbares im Gange (ASK/BID)

Die Geschäfte werden zu den falschen Preisen gemacht

Tun Sie dies in einem Thread, den die MQs nicht ignorieren, und in der Art des ersten Beitrags in diesem Thread.

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

Testen von 'CopyTicks'

Dmitriy Skub, 2015.03.24 09:17

Beginnen wir mit einem einfachen Beispiel - der Lautstärke. Unten sehen Sie ein Bild der entdeckten Störung. Von Zeit zu Zeit gibt es "Doppelgänger" in den Bänden.