| //+------------------------------------------------------------------+
|
| //| TkzVerify.mq5 |
|
| //| Decodes a .tkz archive, measures decoding speed and compares |
|
| //| every chunk with the tick history of the terminal. |
|
| //+------------------------------------------------------------------+
|
| #property copyright "TKZ tick compression"
|
| #property version "1.1"
|
| #property description "Decodes a .tkz archive and compares it with the terminal tick history."
|
| #property script_show_inputs
|
|
|
| #include "../lib/TkzArchive.mqh"
|
|
|
| enum ENUM_TKZ_TICKS
|
| {
|
| TKZ_TICKS_ALL=0, // All ticks (COPY_TICKS_ALL)
|
| TKZ_TICKS_INFO=1 // Bid/Ask changes only (COPY_TICKS_INFO)
|
| };
|
|
|
| input string InpFile=""; // Archive file (empty = <chart symbol>.tkz)
|
| input bool InpCommon=false; // File is in the common data folder
|
| input bool InpCompare=true; // Compare with the terminal tick history
|
| input ENUM_TKZ_TICKS InpTicks=TKZ_TICKS_ALL; // Tick selection used for the export
|
| input string InpSymbol=""; // Symbol to compare with (empty = from the archive)
|
|
|
| //+------------------------------------------------------------------+
|
| void OnStart()
|
| {
|
| string file=(InpFile=="") ? _Symbol+".tkz" : InpFile;
|
| CTkzReader reader;
|
| if(!reader.Open(file,InpCommon))
|
| {
|
| PrintFormat("TKZ: cannot open %s: %s",file,reader.LastError());
|
| return;
|
| }
|
| if(reader.LastError()!="")
|
| PrintFormat("TKZ: warning while scanning %s: %s",file,reader.LastError());
|
| string sym=(InpSymbol=="") ? reader.ArchiveSymbol() : InpSymbol;
|
| uint flags=(InpTicks==TKZ_TICKS_INFO) ? COPY_TICKS_INFO : COPY_TICKS_ALL;
|
| bool compare=InpCompare;
|
| if(compare && !SymbolSelect(sym,true))
|
| {
|
| PrintFormat("TKZ: symbol %s is not available, comparison disabled",sym);
|
| compare=false;
|
| }
|
| PrintFormat("TKZ: %s: symbol %s, %d chunks, %I64d ticks",file,reader.ArchiveSymbol(),reader.ChunkCount(),reader.TickCount());
|
|
|
| MqlTick ticks[];
|
| MqlTick hist[];
|
| long total=0;
|
| long bytes=TKZ_FILE_HEADER_SIZE;
|
| int bad=0;
|
| int compared=0;
|
| ulong dec_us=0;
|
| for(int i=0; i<reader.ChunkCount() && !IsStopped(); i++)
|
| {
|
| STkzChunkInfo info;
|
| reader.GetChunkInfo(i,info);
|
| bytes+=info.total_size;
|
| ulong t0=GetMicrosecondCount();
|
| int n=reader.ReadChunk(i,ticks);
|
| dec_us+=GetMicrosecondCount()-t0;
|
| if(n<0)
|
| {
|
| PrintFormat("TKZ: chunk %d: decode error: %s",i,reader.LastError());
|
| bad++;
|
| continue;
|
| }
|
| total+=n;
|
| if(!compare || n==0)
|
| continue;
|
| ResetLastError();
|
| int h=CopyTicksRange(sym,hist,flags,(ulong)info.min_msc,(ulong)info.max_msc);
|
| if(h!=n)
|
| {
|
| PrintFormat("TKZ: chunk %d (%s .. %s): %d ticks in the archive, %d in the history (error %d)",i,
|
| TimeToString((datetime)(info.min_msc/1000)),TimeToString((datetime)(info.max_msc/1000)),n,h,GetLastError());
|
| bad++;
|
| continue;
|
| }
|
| int diff=-1;
|
| for(int k=0; k<n; k++)
|
| if(ticks[k].time_msc!=hist[k].time_msc || ticks[k].bid!=hist[k].bid || ticks[k].ask!=hist[k].ask)
|
| {
|
| diff=k;
|
| break;
|
| }
|
| if(diff>=0)
|
| {
|
| PrintFormat("TKZ: chunk %d: first difference at tick %d: archive %I64d %.8f %.8f, history %I64d %.8f %.8f",i,diff,
|
| ticks[diff].time_msc,ticks[diff].bid,ticks[diff].ask,hist[diff].time_msc,hist[diff].bid,hist[diff].ask);
|
| bad++;
|
| }
|
| else
|
| compared++;
|
| Comment(StringFormat("TKZ verify: chunk %d of %d",i+1,reader.ChunkCount()));
|
| }
|
| reader.Close();
|
| Comment("");
|
| double dec_s=(double)dec_us/1e6;
|
| if(total>0)
|
| PrintFormat("TKZ: %I64d ticks, %I64d bytes (%.4f bytes/tick), decode %.2f s (%.0f ticks/s)",
|
| total,bytes,(double)bytes/(double)total,dec_s,dec_s>0 ? (double)total/dec_s : 0.0);
|
| if(compare)
|
| PrintFormat("TKZ: %d chunks identical to the history, %d chunks with problems",compared,bad);
|
| else
|
| PrintFormat("TKZ: %d chunks with decode problems",bad);
|
| }
|
| //+------------------------------------------------------------------+
|