237 lines
5.8 KiB
MQL5
237 lines
5.8 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| GenerateCases.mq5 |
|
||
|
|
//| CalendarDifference Test Generator |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property script_show_inputs
|
||
|
|
|
||
|
|
#include "..\TimeUtils.mqh"
|
||
|
|
|
||
|
|
input int RandomPairs = 100000;
|
||
|
|
|
||
|
|
const datetime MIN_TIME = D'1970.01.01 00:00:00';
|
||
|
|
const datetime MAX_TIME = D'3000.12.31 23:59:59';
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
// SplitMix64
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
struct SplitMix64
|
||
|
|
{
|
||
|
|
ulong state;
|
||
|
|
|
||
|
|
SplitMix64()
|
||
|
|
{
|
||
|
|
state = (ulong)GetTickCount64();
|
||
|
|
}
|
||
|
|
|
||
|
|
ulong Next()
|
||
|
|
{
|
||
|
|
ulong z = (state += 0x9E3779B97F4A7C15);
|
||
|
|
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9;
|
||
|
|
z = (z ^ (z >> 27)) * 0x94D049BB133111EB;
|
||
|
|
return z ^ (z >> 31);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
SplitMix64 RNG;
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
string ISO(datetime t)
|
||
|
|
{
|
||
|
|
MqlDateTime s;
|
||
|
|
TimeToStructFast(t, s);
|
||
|
|
|
||
|
|
return StringFormat("%04d-%02d-%02dT%02d:%02d:%02d",
|
||
|
|
s.year,
|
||
|
|
s.mon,
|
||
|
|
s.day,
|
||
|
|
s.hour,
|
||
|
|
s.min,
|
||
|
|
s.sec);
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
void WritePair(int file,
|
||
|
|
datetime from,
|
||
|
|
datetime to)
|
||
|
|
{
|
||
|
|
MqlDateTime diff;
|
||
|
|
CalendarDifference(from, to, diff);
|
||
|
|
|
||
|
|
FileWrite(file,
|
||
|
|
ISO(from),
|
||
|
|
ISO(to),
|
||
|
|
diff.year,
|
||
|
|
diff.mon,
|
||
|
|
diff.day,
|
||
|
|
diff.hour,
|
||
|
|
diff.min,
|
||
|
|
diff.sec);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Writes the pair only if both timestamps are in range |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void WritePairIfValid(const int file,
|
||
|
|
const datetime from,
|
||
|
|
const datetime to)
|
||
|
|
{
|
||
|
|
if(to < MIN_TIME || to > MAX_TIME)
|
||
|
|
return;
|
||
|
|
|
||
|
|
WritePair(file, from, to);
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
datetime RandomTime()
|
||
|
|
{
|
||
|
|
ulong span = (ulong)(MAX_TIME - MIN_TIME);
|
||
|
|
|
||
|
|
return (datetime)(MIN_TIME + (datetime)(RNG.Next() % span));
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
void GenerateMonthEnds(int file)
|
||
|
|
{
|
||
|
|
for(int year=1970; year<=3000; year++)
|
||
|
|
{
|
||
|
|
for(int month=1; month<=12; month++)
|
||
|
|
{
|
||
|
|
int last=DaysInMonth(year,month);
|
||
|
|
|
||
|
|
for(int day=MathMax(1,last-3); day<=last; day++)
|
||
|
|
{
|
||
|
|
datetime t=DateFrom(year,month,day);
|
||
|
|
|
||
|
|
WritePairIfValid(file, t, AddDays(t, -2));
|
||
|
|
WritePairIfValid(file, t, AddDays(t, -1));
|
||
|
|
WritePairIfValid(file, t, AddDays(t, 1));
|
||
|
|
WritePairIfValid(file, t, AddDays(t, 2));
|
||
|
|
|
||
|
|
WritePairIfValid(file, t, AddMonths(t, -1));
|
||
|
|
WritePairIfValid(file, t, AddMonths(t, 1));
|
||
|
|
|
||
|
|
WritePairIfValid(file, t, AddYears(t, -1));
|
||
|
|
WritePairIfValid(file, t, AddYears(t, 1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
void GenerateLeapYears(int file)
|
||
|
|
{
|
||
|
|
for(int year=1970; year<=3000; year++)
|
||
|
|
{
|
||
|
|
if(!IsLeapYear(year))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
datetime feb28=DateFrom(year,2,28);
|
||
|
|
|
||
|
|
WritePairIfValid(file,feb28,AddDays(feb28,1));
|
||
|
|
WritePairIfValid(file,feb28,AddDays(feb28,2));
|
||
|
|
|
||
|
|
datetime feb29=DateFrom(year,2,29);
|
||
|
|
|
||
|
|
WritePairIfValid(file,feb29,AddYears(feb29,1));
|
||
|
|
WritePairIfValid(file,feb29,AddYears(feb29,4));
|
||
|
|
|
||
|
|
WritePairIfValid(file,feb29,AddMonths(feb29,12));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
void GenerateYearBoundaries(int file)
|
||
|
|
{
|
||
|
|
for(int year=1970; year<=3000; year++)
|
||
|
|
{
|
||
|
|
datetime end=DateFrom(year,12,31,23,59,59);
|
||
|
|
|
||
|
|
WritePairIfValid(file,end,AddSeconds(end,1));
|
||
|
|
WritePairIfValid(file,end,AddDays(end,1));
|
||
|
|
WritePairIfValid(file,end,AddMonths(end,1));
|
||
|
|
WritePairIfValid(file,end,AddYears(end,1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
void GenerateQuarterBoundaries(int file)
|
||
|
|
{
|
||
|
|
const int months[]={3,6,9,12};
|
||
|
|
|
||
|
|
for(int year=1970; year<=3000; year++)
|
||
|
|
{
|
||
|
|
for(int i=0;i<4;i++)
|
||
|
|
{
|
||
|
|
int month=months[i];
|
||
|
|
|
||
|
|
datetime t=DateFrom(
|
||
|
|
year,
|
||
|
|
month,
|
||
|
|
DaysInMonth(year,month));
|
||
|
|
|
||
|
|
WritePairIfValid(file,t,AddDays(t,1));
|
||
|
|
WritePairIfValid(file,t,AddMonths(t,3));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
void GenerateRandom(int file)
|
||
|
|
{
|
||
|
|
for(int i=0;i<RandomPairs;i++)
|
||
|
|
{
|
||
|
|
WritePairIfValid(file,
|
||
|
|
RandomTime(),
|
||
|
|
RandomTime());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------------------
|
||
|
|
|
||
|
|
void OnStart()
|
||
|
|
{
|
||
|
|
int file = FileOpen(
|
||
|
|
"CalendarDifferenceCases.csv",
|
||
|
|
FILE_WRITE | FILE_CSV | FILE_ANSI,
|
||
|
|
','
|
||
|
|
);
|
||
|
|
|
||
|
|
if(file == INVALID_HANDLE)
|
||
|
|
{
|
||
|
|
Print("FileOpen() failed. Error = ", GetLastError());
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
FileWrite(file,
|
||
|
|
"from",
|
||
|
|
"to",
|
||
|
|
"years",
|
||
|
|
"months",
|
||
|
|
"days",
|
||
|
|
"hours",
|
||
|
|
"minutes",
|
||
|
|
"seconds");
|
||
|
|
|
||
|
|
GenerateMonthEnds(file);
|
||
|
|
|
||
|
|
GenerateLeapYears(file);
|
||
|
|
|
||
|
|
GenerateQuarterBoundaries(file);
|
||
|
|
|
||
|
|
GenerateYearBoundaries(file);
|
||
|
|
|
||
|
|
GenerateRandom(file);
|
||
|
|
|
||
|
|
FileClose(file);
|
||
|
|
|
||
|
|
Print("CalendarDifferenceCases.csv generated.");
|
||
|
|
}
|
||
|
|
|