Files
include/OLAP/GUI/OLAPGUI_Opts.mqh
T
2025-02-07 19:13:59 +03:30

150 lines
9.0 KiB
Plaintext

//+------------------------------------------------------------------+
//| OLAPGUI_Opts.mqh |
//| Copyright (c) 2019-2020, Marketeer |
//| https://www.mql5.com/en/users/marketeer |
//| Online Analytical Processing of trading hypercubes |
//| https://www.mql5.com/en/articles/6602 |
//| https://www.mql5.com/en/articles/6603 |
//| https://www.mql5.com/en/articles/7656 |
//+------------------------------------------------------------------+
#include <OLAP/GUI/OLAPGUI.mqh>
#define MAX_ALGO_CHOICES 9 // NB: this is the number of aggregators (most lengthy row in settings)
template<typename S, typename F>
class OLAPDialog: public OLAPDialogBase
{
private:
OLAPEngine<S,F> *olapcore;
OLAPDisplay *olapdisplay;
public:
OLAPDialog(OLAPEngine<S,F> &olapimpl);
~OLAPDialog(void);
virtual int process() override;
virtual void setup() override;
void setPrintLog(const bool printLog)
{
if(CheckPointer(olapdisplay) != POINTER_INVALID) olapdisplay.setPrintLog(printLog);
}
};
template<typename S, typename F>
OLAPDialog::OLAPDialog(OLAPEngine<S,F> &olapimpl)
{
curveType = CURVE_POINTS;
olapcore = &olapimpl;
olapdisplay = new OLAPDisplay(&this);
}
template<typename S, typename F>
OLAPDialog::~OLAPDialog(void)
{
delete olapdisplay;
}
template<typename S, typename F>
void OLAPDialog::setup() override
{
static const string _settings[ALGO_NUMBER][MAX_ALGO_CHOICES] =
{
// enum AGGREGATORS 1:1, default - sum
{"sum", "average", "max", "min", "count", "profit factor", "progressive total", "identity", "variance"},
// enum RECORD_FIELDS 1:1, default - profit amount
{""},
// enum SORT_BY, default - none
{"none", "value ascending", "value descending", "label ascending", "label descending"},
// enum ENUM_CURVE_TYPE partially, default - points
{"points", "lines", "points/lines", "steps", "histogram"}
};
static const int _defaults[ALGO_NUMBER] = {0, FIELD_PROFIT, 0, 0};
const int std = EnumSize<F,PackedEnum>(0);
const int fields = std + customFieldCount;
ArrayResize(settings, fields);
ArrayResize(selectors, fields);
selectors[0] = "(<selector>/field)"; // none
selectors[1] = "<serial number>"; // the only selector, which can be chosen explicitly, it correspods to the 'index' field
for(int i = 0; i < ALGO_NUMBER; i++)
{
if(i == 1) // pure fields
{
for(int j = 0; j < fields; j++)
{
settings[j][i] = j < std ? Record::legendFromEnum((F)j) : customFields[j - std];
}
}
else
{
for(int j = 0; j < MAX_ALGO_CHOICES; j++)
{
settings[j][i] = _settings[i][j];
}
}
}
for(int j = 2; j < fields; j++) // 0-th is none
{
selectors[j] = j < std ? Record::legendFromEnum((F)j) : customFields[j - std];
}
ArrayCopy(defaults, _defaults);
}
template<typename S, typename F>
int OLAPDialog::process() override
{
SELECTORS Selectors[4];
ENUM_FIELDS Fields[4];
AGGREGATORS at = (AGGREGATORS)m_algo[0].Value();
ENUM_FIELDS af = (ENUM_FIELDS)(AGGREGATORS)m_algo[1].Value();
SORT_BY sb = (SORT_BY)m_algo[2].Value();
if(at == AGGREGATOR_IDENTITY)
{
Print("Sorting is disabled for Identity");
sb = SORT_BY_NONE;
}
ArrayInitialize(Selectors, SELECTOR_NONE);
ArrayInitialize(Fields, FIELD_NONE);
int matches[2] =
{
SELECTOR_NONE,
SELECTOR_INDEX
};
for(int i = 0; i < AXES_NUMBER; i++)
{
if(!m_axis[i].IsVisible()) continue;
int v = (int)m_axis[i].Value();
if(v < 2) // selectors (which is specialized for a field already)
{
Selectors[i] = (SELECTORS)matches[v];
}
else // pure fields
{
Selectors[i] = at == AGGREGATOR_IDENTITY ? SELECTOR_SCALAR : SELECTOR_QUANTS;
Fields[i] = (ENUM_FIELDS)(v);
}
}
m_plot.CurvesRemoveAll();
if(at == AGGREGATOR_IDENTITY || at == AGGREGATOR_COUNT) af = FIELD_NONE;
m_plot.InitXAxis(at != AGGREGATOR_PROGRESSIVE ? new AxisCustomizer(m_plot.getGraphic(), false, false, false, at == AGGREGATOR_IDENTITY) : NULL);
m_plot.InitYAxis(at == AGGREGATOR_IDENTITY ? new AxisCustomizer(m_plot.getGraphic(), true, false, false, true) : NULL);
m_button_ok.Text("Processing...");
return olapcore.process(Selectors, Fields, at, af, olapdisplay, sb);
}