150 lines
9.0 KiB
Plaintext
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);
|
|
}
|