MQL5Book/Include/TickFilter.mqh

137 lines
3.7 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:09:41 +02:00
//+------------------------------------------------------------------+
//| TickFilter.mqh |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Several methods of prunning ticks for faster optimization and |
//| lower resource consumption |
//+------------------------------------------------------------------+
class TickFilter
{
public:
enum FILTER_MODE
{
NONE,
SEQUENCE,
FLUTTER,
FRACTALS,
};
static int filter(FILTER_MODE mode, MqlTick &data[])
{
switch(mode)
{
case SEQUENCE: return filterBySequences(data);
case FLUTTER: return filterBySpreadFlutter(data);
case FRACTALS: return filterByFractals(data);
}
return ArraySize(data);
}
static int filterBySequences(MqlTick &data[])
{
const int size = ArraySize(data);
if(size < 3) return size;
int index = 2;
bool dirUp = data[1].bid - data[0].bid + data[1].ask - data[0].ask > 0;
for(int i = 2; i < size; i++)
{
if(dirUp)
{
if(data[i].bid - data[i - 1].bid + data[i].ask - data[i - 1].ask < 0)
{
dirUp = false;
data[index++] = data[i];
}
}
else
{
if(data[i].bid - data[i - 1].bid + data[i].ask - data[i - 1].ask > 0)
{
dirUp = true;
data[index++] = data[i];
}
}
}
return ArrayResize(data, index);
}
static int filterBySpreadFlutter(MqlTick &data[])
{
const int size = ArraySize(data);
if(size < 3) return size;
bool dirUp = true;
int index = 0;
double priceMinMax = -DBL_MAX;
for(int i = 0; i < size; i++)
{
const double bid = data[i].bid;
const double ask = data[i].ask;
if(dirUp)
{
if(bid > priceMinMax)
{
priceMinMax = bid;
data[index++] = data[i];
}
else if(ask <= priceMinMax)
{
priceMinMax = ask;
dirUp = false;
data[index++] = data[i];
}
}
else
{
if(ask < priceMinMax)
{
priceMinMax = ask;
data[index++] = data[i];
}
else if(bid >= priceMinMax)
{
priceMinMax = bid;
dirUp = true;
data[index++] = data[i];
}
}
}
return ArrayResize(data, index);
}
static int filterByFractals(MqlTick &data[])
{
int index = 1;
const int size = ArraySize(data);
if(size < 3) return size;
for(int i = 1; i < size - 2; i++)
{
if((data[i].bid < data[i - 1].bid && data[i].bid < data[i + 1].bid)
|| (data[i].ask > data[i - 1].ask && data[i].ask > data[i + 1].ask))
{
data[index++] = data[i];
}
}
return ArrayResize(data, index);
}
};
//+------------------------------------------------------------------+
/*
Example outputs:
Create new custom symbol 'EURUSD.TckFltr-SEQUENCE'?
Done ticks - read: 37682157, written: 19896830, ratio: 52.8%
*/
//+------------------------------------------------------------------+