session-levels/tests/mql5/Scripts/DumpIndicator/DumpIndicator.mq5
92 lines
4.3 KiB
MQL5
//+------------------------------------------------------------------+
//| DumpIndicator.mq5 |
//| Copyright 2026, Allan Niñal |
//| https://www.allanninal.dev/mql5 |
//+------------------------------------------------------------------+
//| Test tool: writes every bar of a custom indicator's buffers, |
//| with the bars it saw, for each symbol and timeframe, to |
//| Common\Files\dump\<tag>_<SYMBOL>_<TF>.csv |
//| columns: time,open,high,low,close,b<k>... (EMPTY_VALUE -> blank) |
//| so a Python reference can be compared bar by bar. Read-only. |
//+------------------------------------------------------------------+
// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0 (see LICENSE)
#property copyright "Copyright 2026, Allan Niñal <https://www.allanninal.dev/mql5>"
#property version "1.00"
#property script_show_inputs
#include <IndTest\Params.mqh>
input string InpIndicator = "SessionLevels\\SessionLevels"; // indicator path under MQL5\Indicators
input string InpParams = ""; // parameters, "d:1.0|i:10|b:false" (empty = defaults)
input string InpBuffers = "0,2,3"; // buffer indexes to write
input string InpSymbols = "EURUSD,XAUUSD"; // symbols
input string InpTFs = "H1"; // timeframes: M1,M5,M15,M30,H1,H4,D1,W1
input string InpTag = "dump"; // file name prefix
input bool InpCloseWhenDone = false; // close the terminal when finished (batch runs)
void OnStart()
{
int bufs[];
int nb=ParseInts(InpBuffers,bufs);
string syms[],tfs[];
int ns=StringSplit(InpSymbols,',',syms),nt=StringSplit(InpTFs,',',tfs);
int h=FileOpen("dump\\"+InpTag+"_DONE.txt",FILE_WRITE|FILE_TXT|FILE_ANSI|FILE_COMMON);
for(int s=0; s<ns && !IsStopped(); s++)
for(int t=0; t<nt && !IsStopped(); t++)
{
ENUM_TIMEFRAMES tf=TfFromName(tfs[t]);
SymbolSelect(syms[s],true);
int ind=MakeHandle(syms[s],tf,InpIndicator,InpParams);
if(ind==INVALID_HANDLE)
{
PrintFormat("DumpIndicator: %s %s: cannot create the indicator (%d)",syms[s],tfs[t],GetLastError());
continue;
}
int bars=0;
for(int k=0; k<120 && !IsStopped(); k++) // wait until the terminal has the bars and the indicator ran
{
bars=Bars(syms[s],tf);
if(bars>0 && BarsCalculated(ind)==bars && SeriesInfoInteger(syms[s],tf,SERIES_SYNCHRONIZED))
break;
Sleep(500);
}
MqlRates r[];
int got=CopyRates(syms[s],tf,0,bars,r);
double b[][1];
string name=StringFormat("dump\\%s_%s_%s.csv",InpTag,syms[s],tfs[t]);
int f=FileOpen(name,FILE_WRITE|FILE_TXT|FILE_ANSI|FILE_COMMON);
string head="time,open,high,low,close";
for(int j=0; j<nb; j++)
head+=",b"+IntegerToString(bufs[j]);
FileWriteString(f,head+"\n");
double v[];
double cols[];
ArrayResize(cols,got*nb);
for(int j=0; j<nb; j++)
{
if(CopyBuffer(ind,bufs[j],0,got,v)!=got)
PrintFormat("DumpIndicator: %s %s buffer %d: short copy",syms[s],tfs[t],bufs[j]);
for(int i=0; i<got && i<ArraySize(v); i++)
cols[i*nb+j]=v[i];
}
for(int i=0; i<got; i++)
{
string line=StringFormat("%I64d,%.10g,%.10g,%.10g,%.10g",(long)r[i].time,r[i].open,r[i].high,r[i].low,r[i].close);
for(int j=0; j<nb; j++)
line+=(cols[i*nb+j]==EMPTY_VALUE ? "," : ","+StringFormat("%.10g",cols[i*nb+j]));
FileWriteString(f,line+"\n");
}
FileClose(f);
IndicatorRelease(ind);
PrintFormat("DumpIndicator: %s %s: %d bars",syms[s],tfs[t],got);
if(h!=INVALID_HANDLE)
FileWriteString(h,StringFormat("%s %s %d\n",syms[s],tfs[t],got));
}
if(h!=INVALID_HANDLE)
{
FileWriteString(h,"DONE\n");
FileClose(h);
}
if(InpCloseWhenDone)
TerminalClose(0);
}
//+------------------------------------------------------------------+