Skip to content

Commit

Permalink
Indicator: Adds template for indicator param struct [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
kenorb committed Sep 28, 2021
1 parent c11504c commit 191f167
Show file tree
Hide file tree
Showing 78 changed files with 1,167 additions and 1,517 deletions.
2 changes: 1 addition & 1 deletion Action.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class Action {
#ifdef INDICATOR_MQH
case ACTION_TYPE_INDICATOR:
if (Object::IsValid(_entry.obj)) {
_result = ((Indicator *)_entry.obj).ExecuteAction((ENUM_INDICATOR_ACTION)_entry.action_id);
_result = ((Indicator<IndicatorParams> *)_entry.obj).ExecuteAction((ENUM_INDICATOR_ACTION)_entry.action_id);
} else {
_result = false;
_entry.AddFlags(ACTION_ENTRY_FLAG_IS_INVALID);
Expand Down
2 changes: 1 addition & 1 deletion Condition.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class Condition {
#ifdef INDICATOR_MQH
case COND_TYPE_INDICATOR:
if (Object::IsValid(_entry.obj)) {
_result = ((Indicator *)_entry.obj).CheckCondition((ENUM_INDICATOR_CONDITION)_entry.cond_id, _entry.args);
_result = ((Indicator<IndicatorParams> *)_entry.obj).CheckCondition((ENUM_INDICATOR_CONDITION)_entry.cond_id, _entry.args);
} else {
// Static method not supported.
_result = false;
Expand Down
7 changes: 4 additions & 3 deletions DrawIndicator.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ class DrawPoint {
DrawPoint(datetime _time = NULL, double _value = 0) : time(_time), value(_value) {}
};

template <typename IDT>
class DrawIndicator {
protected:
color color_line;
Draw* draw;
Indicator* indi;
Indicator<IDT>* indi;

public:
// Object variables.
Expand All @@ -67,8 +68,8 @@ class DrawIndicator {
/**
* Class constructor.
*/
DrawIndicator(Indicator* _indi) : indi(_indi) {
color_line = Object::IsValid(_indi) ? _indi.GetParams().indi_color : clrRed;
DrawIndicator(Indicator<IDT> *_indi) : indi(_indi) {
// color_line = Object::IsValid(_indi) ? _indi.GetParams().indi_color : clrRed; // @fixme
draw = new Draw();
}

Expand Down
2 changes: 1 addition & 1 deletion EA.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ class EA {
if (eparams.CheckFlagDataStore(EA_DATA_STORE_INDICATOR)) {
for (DictStructIterator<long, Ref<Strategy>> iter = strats.Begin(); iter.IsValid(); ++iter) {
Strategy *_strati = iter.Value().Ptr();
Indicator *_indi = _strati.GetIndicator();
Indicator<IndicatorParams> *_indi = _strati.GetIndicator();
if (_indi != NULL) {
ENUM_TIMEFRAMES _itf = _indi.GetParams().tf.GetTf();
IndicatorDataEntry _ientry = _indi.GetEntry();
Expand Down
124 changes: 68 additions & 56 deletions Indicator.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Chart;

#ifndef __MQL4__
// Defines global functions (for MQL4 backward compatibility).
bool IndicatorBuffers(int _count) { return Indicator::SetIndicatorBuffers(_count); }
bool IndicatorBuffers(int _count) { return Indicator<IndicatorParams>::SetIndicatorBuffers(_count); }
int IndicatorCounted(int _value = 0) {
static int prev_calculated = 0;
// https://docs.mql4.com/customind/indicatorcounted
Expand All @@ -63,20 +63,22 @@ int IndicatorCounted(int _value = 0) {
/**
* Class to deal with indicators.
*/
template <typename TS>
class Indicator : public Chart {
protected:
// Structs.
BufferStruct<IndicatorDataEntry> idata;
DrawIndicator* draw;
IndicatorParams iparams;
DrawIndicator<TS>* draw;
IndicatorState istate;
void* mydata;
bool is_feeding; // Whether FeedHistoryEntries is already working.
bool is_fed; // Whether FeedHistoryEntries already done its job.
DictStruct<int, Ref<Indicator>> indicators; // Indicators list keyed by id.
bool indicator_builtin;
ARRAY(ValueStorage<double>*, value_storages);
Indicator<IndicatorParams>* indi_src; // // Indicator used as data source.
IndicatorCalculateCache<double> cache;
TS iparams;

public:
/* Indicator enumerations */
Expand All @@ -96,20 +98,19 @@ class Indicator : public Chart {
/**
* Class constructor.
*/
Indicator() {}
Indicator(IndicatorParams& _iparams) : Chart(_iparams.GetTf()), draw(NULL), is_feeding(false), is_fed(false) {
iparams = _iparams;
Indicator() : indi_src(NULL) {}
Indicator(TS& _iparams)
: Chart(_iparams.GetTf()), draw(NULL), iparams(_iparams), is_feeding(false), is_fed(false), indi_src(NULL) {
SetName(_iparams.name != "" ? _iparams.name : EnumToString(iparams.itype));
Init();
}
Indicator(const IndicatorParams& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT)
: Chart(_tf), draw(NULL), is_feeding(false), is_fed(false) {
iparams = _iparams;
Indicator(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT)
: Chart(_tf), draw(NULL), iparams(_iparams), is_feeding(false), is_fed(false), indi_src(NULL) {
SetName(_iparams.name != "" ? _iparams.name : EnumToString(iparams.itype));
Init();
}
Indicator(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "")
: Chart(_tf), draw(NULL), is_feeding(false), is_fed(false) {
: Chart(_tf), draw(NULL), is_feeding(false), is_fed(false), indi_src(NULL) {
iparams.SetIndicatorType(_itype);
iparams.SetShift(_shift);
SetName(_name != "" ? _name : EnumToString(iparams.itype));
Expand All @@ -129,13 +130,13 @@ class Indicator : public Chart {
}
}

if (iparams.indi_data_source != NULL && iparams.indi_managed) {
if (indi_src != NULL && iparams.indi_managed) {
// User selected custom, managed data source.
if (CheckPointer(iparams.indi_data_source) == POINTER_INVALID) {
if (CheckPointer(indi_src) == POINTER_INVALID) {
DebugBreak();
}
delete iparams.indi_data_source;
iparams.indi_data_source = NULL;
delete indi_src;
indi_src = NULL;
}
}

Expand All @@ -151,7 +152,7 @@ class Indicator : public Chart {
*/
bool InitDraw() {
if (iparams.is_draw && !Object::IsValid(draw)) {
draw = new DrawIndicator(&this);
draw = new DrawIndicator<TS>(&this);
draw.SetColorLine(iparams.indi_color);
}
return iparams.is_draw;
Expand Down Expand Up @@ -419,6 +420,39 @@ class Indicator : public Chart {
return _is_valid;
}

/**
* CopyBuffer() method to be used on Indicator instance with ValueStorage buffer.
*
* Note that data will be copied so that the oldest element will be located at the start of the physical memory
* allocated for the array
*/
/*
static int CopyBuffer(Indicator<IndicatorParms>* _indi, int _mode, int _start, int _count, ValueStorage<T>& _buffer,
int _rates_total) { int _num_copied = 0; int _buffer_size = ArraySize(_buffer);
if (_buffer_size < _rates_total) {
_buffer_size = ArrayResize(_buffer, _rates_total);
}
for (int i = _start; i < _count; ++i) {
IndicatorDataEntry _entry = _indi.GetEntry(i);
if (!_entry.IsValid()) {
break;
}
T _value = _entry.GetValue<T>(_mode);
// Print(_value);
_buffer[_buffer_size - i - 1] = _value;
++_num_copied;
}
return _num_copied;
}
*/

/**
* Validates currently selected indicator used as data source.
*/
Expand Down Expand Up @@ -494,20 +528,20 @@ class Indicator : public Chart {
/**
* Whether data source is selected.
*/
bool HasDataSource() { return iparams.GetDataSource() != NULL || iparams.GetDataSourceId() != -1; }
bool HasDataSource() { return GetDataSource() != NULL || iparams.GetDataSourceId() != -1; }

/**
* Returns currently selected data source without any validation.
*/
Indicator* GetDataSourceRaw() { return iparams.GetDataSource(); }
Indicator<TS>* GetDataSourceRaw() { return GetDataSource(); }

/**
* Returns currently selected data source doing validation.
*/
Indicator* GetDataSource() {
Indicator* _result = NULL;
if (iparams.GetDataSource() != NULL) {
_result = iparams.GetDataSource();
Indicator<TS>* GetDataSource() {
Indicator<TS>* _result = NULL;
if (GetDataSource() != NULL) {
_result = GetDataSource();
} else if (iparams.GetDataSourceId() != -1) {
int _source_id = iparams.GetDataSourceId();

Expand Down Expand Up @@ -694,7 +728,7 @@ class Indicator : public Chart {

/* Getters */

int GetDataSourceMode() { return iparams.GetDataSourceMode(); }
int GetDataSourceMode() { return GetDataSourceMode(); }

/**
* Returns the highest bar's index (shift).
Expand Down Expand Up @@ -917,6 +951,15 @@ class Indicator : public Chart {
Chart::Set<T>(_param, _value);
}

/**
* Sets indicator data source.
*/
template <typename TSA>
void SetDataSource(Indicator<TSA>* _indi, bool _managed = true, int _input_mode = -1) {
indi_src = _indi;
iparams.SetDataSource(-1, _input_mode, _managed);
}

/**
* Sets name of the indicator.
*/
Expand Down Expand Up @@ -1144,7 +1187,7 @@ class Indicator : public Chart {

ValueStorage<double>* GetValueStorage(int _mode = 0) {
if (value_storages[_mode] == NULL) {
value_storages[_mode] = new IndicatorBufferValueStorage<double>(THIS_PTR, _mode);
value_storages[_mode] = new IndicatorBufferValueStorage<double, TS>(THIS_PTR, _mode);
}
return value_storages[_mode];
}
Expand Down Expand Up @@ -1294,6 +1337,7 @@ class Indicator : public Chart {
/**
* BarsCalculated() method to be used on Indicator instance.
*/
/*
int BarsCalculated(Indicator* _indi, int _bars_required) {
if (_bars_required == 0) {
return _bars_required;
Expand Down Expand Up @@ -1321,38 +1365,6 @@ int BarsCalculated(Indicator* _indi, int _bars_required) {
return _valid_history_count;
}

/**
* CopyBuffer() method to be used on Indicator instance with ValueStorage buffer.
*
* Note that data will be copied so that the oldest element will be located at the start of the physical memory
* allocated for the array
*/
template <typename T>
int CopyBuffer(Indicator* _indi, int _mode, int _start, int _count, ValueStorage<T>& _buffer, int _rates_total) {
int _num_copied = 0;
int _buffer_size = ArraySize(_buffer);

if (_buffer_size < _rates_total) {
_buffer_size = ArrayResize(_buffer, _rates_total);
}

for (int i = _start; i < _count; ++i) {
IndicatorDataEntry _entry = _indi.GetEntry(i);

if (!_entry.IsValid()) {
break;
}

T _value = _entry.GetValue<T>(_mode);

// Print(_value);

_buffer[_buffer_size - i - 1] = _value;
++_num_copied;
}

return _num_copied;
}
*/

#endif
12 changes: 1 addition & 11 deletions Indicator.struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,6 @@ struct IndicatorParams {
color indi_color; // Indicator color.
int indi_data_source_id; // Id of the indicator to be used as data source.
int indi_data_source_mode; // Mode used as input from data source.
Indicator *indi_data_source; // Custom indicator to be used as data source.
bool indi_managed; // Whether indicator should be owned by indicator.
ARRAY(DataParamEntry, input_params); // Indicator input params.
int indi_mode; // Index of indicator data to be used as data source.
Expand All @@ -385,7 +384,6 @@ struct IndicatorParams {
max_buffers(10),
idstype(_idstype),
idvrange(IDATA_RANGE_UNKNOWN),
indi_data_source(NULL),
indi_data_source_id(-1),
indi_data_source_mode(0),
itype(_itype),
Expand All @@ -404,7 +402,6 @@ struct IndicatorParams {
max_buffers(10),
idstype(_idstype),
idvrange(IDATA_RANGE_UNKNOWN),
indi_data_source(NULL),
indi_data_source_id(-1),
indi_data_source_mode(0),
is_draw(false),
Expand All @@ -417,7 +414,6 @@ struct IndicatorParams {
void Init() {}
/* Getters */
string GetCustomIndicatorName() { return custom_indi_name; }
Indicator *GetDataSource() { return indi_data_source; }
int GetDataSourceId() { return indi_data_source_id; }
int GetDataSourceMode() { return indi_data_source_mode; }
color GetIndicatorColor() { return indi_color; }
Expand Down Expand Up @@ -465,15 +461,9 @@ struct IndicatorParams {
draw_window = _window;
}
void SetIndicatorColor(color _clr) { indi_color = _clr; }
void SetDataSource(int _id, int _input_mode = -1) {
void SetDataSource(int _id, int _input_mode = -1, bool _managed = true) {
indi_data_source_id = _id;
indi_data_source_mode = _input_mode;
idstype = IDATA_INDICATOR;
}
void SetDataSource(Indicator *_indi, bool _managed = true, int _input_mode = -1) {
indi_data_source_id = -1;
indi_data_source = _indi;
indi_data_source_mode = _input_mode;
indi_managed = _managed;
idstype = IDATA_INDICATOR;
}
Expand Down
6 changes: 3 additions & 3 deletions Indicator.struct.serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ SerializerNodeType IndicatorDataEntry::Serialize(Serializer &_s) {
_s.Pass(THIS_REF, "datetime", timestamp, SERIALIZER_FIELD_FLAG_DYNAMIC);
_s.Pass(THIS_REF, "flags", flags, SERIALIZER_FIELD_FLAG_DYNAMIC);
for (int i = 0; i < _asize; i++) {
// _s.Pass(THIS_REF, (string)i, values[i], SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); // Can this
// work? _s.Pass(THIS_REF, (string)i, GetEntry(i), SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); //
// Can this work?
// _s.Pass(THIS_REF, (string)i, values[i], SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); // Can
// this work? _s.Pass(THIS_REF, (string)i, GetEntry(i), SERIALIZER_FIELD_FLAG_DYNAMIC |
// SERIALIZER_FIELD_FLAG_FEATURE); // Can this work?

if (CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLE)) {
_s.Pass(THIS_REF, (string)i, values[i].vdbl, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
Expand Down
3 changes: 2 additions & 1 deletion Indicator.struct.signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ struct IndicatorSignal {

// Constructors.
IndicatorSignal(int _signals = 0) : signals(_signals) {}
IndicatorSignal(ARRAY_REF(IndicatorDataEntry, _data), IndicatorParams &_ip, ChartParams &_cp, int _m1 = 0, int _m2 = 0)
IndicatorSignal(ARRAY_REF(IndicatorDataEntry, _data), IndicatorParams &_ip, ChartParams &_cp, int _m1 = 0,
int _m2 = 0)
: signals(0) {
CalcSignals(_data, _ip, _cp, _m1, _m2);
}
Expand Down
Loading

0 comments on commit 191f167

Please sign in to comment.