Skip to content

Commit

Permalink
In the middle of Indicator::GetValue -> GetMixedValue refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
nseam committed Oct 29, 2021
1 parent b4b53f4 commit 1e59d35
Show file tree
Hide file tree
Showing 71 changed files with 250 additions and 212 deletions.
248 changes: 138 additions & 110 deletions Indicator.struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,109 +45,147 @@ struct ChartParams;
#include "SerializerNode.enum.h"
#include "Storage/ValueStorage.indicator.h"

// Type-less value for IndicatorDataEntryValue structure.
union IndicatorDataEntryTypelessValue {
double vdbl;
float vflt;
int vint;
long vlong;
};

// Type-aware value for IndicatorDataEntry class.
struct IndicatorDataEntryValue {
unsigned char flags;
IndicatorDataEntryTypelessValue value;

// Returns type of the value.
ENUM_DATATYPE GetDataType() { return (ENUM_DATATYPE)((flags & 0xF0) >> 4); }

// Sets type of the value.
void SetDataType(ENUM_DATATYPE _type) {
// CLearing type.
flags &= 0x0F;

// Setting type.
flags |= (unsigned char)_type << 4;
}

// Union operators.
template <typename T>
T operator*(const T _value) {
return Get<T>() * _value;
}
template <typename T>
T operator+(const T _value) {
return Get<T>() + _value;
}
template <typename T>
T operator-(const T _value) {
return Get<T>() - _value;
}
template <typename T>
T operator/(const T _value) {
return Get<T>() / _value;
}
template <typename T>
bool operator!=(const T _value) {
return Get<T>() != _value;
}
template <typename T>
bool operator<(const T _value) {
return Get<T>() < _value;
}
template <typename T>
bool operator<=(const T _value) {
return Get<T>() <= _value;
}
template <typename T>
bool operator==(const T _value) {
return Get<T>() == _value;
}
template <typename T>
bool operator>(const T _value) {
return Get<T>() > _value;
}
template <typename T>
bool operator>=(const T _value) {
return Get<T>() >= _value;
}
template <typename T>
void operator=(const T _value) {
Set(_value);
}
// Checkers.
template <typename T>
bool IsGt(T _value) {
return Get<T>() > _value;
}
template <typename T>
bool IsLt(T _value) {
return Get<T>() < _value;
}
// Getters.
double GetDbl() { return value.vdbl; }
float GetFloat() { return value.vflt; }
int GetInt() { return value.vint; }
long GetLong() { return value.vlong; }
template <typename T>
void Get(T &_out) {
_out = Get<T>();
}
template <typename T>
T Get() {
T _v;
Get(_v);
return _v;
}
void Get(double &_out) { _out = value.vdbl; }
void Get(float &_out) { _out = value.vflt; }
void Get(int &_out) { _out = value.vint; }
void Get(long &_out) { _out = value.vlong; }
// Setters.
template <typename T>
void Set(T _value) {
Set(_value);
}
void Set(double _value) {
value.vdbl = _value;
SetDataType(TYPE_DOUBLE);
}
void Set(float _value) {
value.vflt = _value;
SetDataType(TYPE_FLOAT);
}
void Set(int _value) {
value.vint = _value;
SetDataType(TYPE_INT);
}
void Set(unsigned int _value) {
value.vint = (int)_value;
SetDataType(TYPE_UINT);
}
void Set(long _value) {
value.vlong = _value;
SetDataType(TYPE_LONG);
}
void Set(unsigned long _value) {
value.vlong = (long)_value;
SetDataType(TYPE_ULONG);
}
// Serializers.
// SERIALIZER_EMPTY_STUB
SerializerNodeType Serialize(Serializer &_s);
// To string
template <typename T>
string ToString() {
return (string)Get<T>();
}
};

/* Structure for indicator data entry. */
struct IndicatorDataEntry {
long timestamp; // Timestamp of the entry's bar.
unsigned short flags; // Indicator entry flags.
union IndicatorDataEntryValue {
double vdbl;
float vflt;
int vint;
long vlong;
// Union operators.
template <typename T>
T operator*(const T _value) {
return Get<T>() * _value;
}
template <typename T>
T operator+(const T _value) {
return Get<T>() + _value;
}
template <typename T>
T operator-(const T _value) {
return Get<T>() - _value;
}
template <typename T>
T operator/(const T _value) {
return Get<T>() / _value;
}
template <typename T>
bool operator!=(const T _value) {
return Get<T>() != _value;
}
template <typename T>
bool operator<(const T _value) {
return Get<T>() < _value;
}
template <typename T>
bool operator<=(const T _value) {
return Get<T>() <= _value;
}
template <typename T>
bool operator==(const T _value) {
return Get<T>() == _value;
}
template <typename T>
bool operator>(const T _value) {
return Get<T>() > _value;
}
template <typename T>
bool operator>=(const T _value) {
return Get<T>() >= _value;
}
template <typename T>
void operator=(const T _value) {
Set(_value);
}
// Checkers.
template <typename T>
bool IsGt(T _value) {
return Get<T>() > _value;
}
template <typename T>
bool IsLt(T _value) {
return Get<T>() < _value;
}
// Getters.
double GetDbl() { return vdbl; }
float GetFloat() { return vflt; }
int GetInt() { return vint; }
long GetLong() { return vlong; }
template <typename T>
void Get(T &_out) {
_out = Get<T>();
}
template <typename T>
T Get() {
T _v;
Get(_v);
return _v;
}
void Get(double &_out) { _out = vdbl; }
void Get(float &_out) { _out = vflt; }
void Get(int &_out) { _out = vint; }
void Get(long &_out) { _out = vlong; }
// Setters.
template <typename T>
void Set(T _value) {
Set(_value);
}
void Set(double _value) { vdbl = _value; }
void Set(float _value) { vflt = _value; }
void Set(int _value) { vint = _value; }
void Set(unsigned int _value) { vint = (int)_value; }
void Set(long _value) { vlong = _value; }
void Set(unsigned long _value) { vlong = (long)_value; }
// Serializers.
// SERIALIZER_EMPTY_STUB
SerializerNodeType Serialize(Serializer &_s);
// To string
template <typename T>
string ToString() {
return (string)Get<T>();
}
};

ARRAY(IndicatorDataEntryValue, values);

// Constructors.
Expand Down Expand Up @@ -288,17 +326,7 @@ struct IndicatorDataEntry {
int GetMonth() { return DateTimeStatic::Month(timestamp); }
int GetYear() { return DateTimeStatic::Year(timestamp); }
long GetTime() { return timestamp; };
ENUM_DATATYPE GetDataType() {
if (CheckFlags(INDI_ENTRY_FLAG_IS_REAL)) {
return CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED) ? TYPE_DOUBLE : TYPE_FLOAT;
} else {
if (CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) {
return CheckFlags(INDI_ENTRY_FLAG_IS_UNSIGNED) ? TYPE_ULONG : TYPE_LONG;
} else {
return CheckFlags(INDI_ENTRY_FLAG_IS_UNSIGNED) ? TYPE_UINT : TYPE_INT;
}
}
}
ENUM_DATATYPE GetDataType(int _mode) { return values[_mode].GetDataType(); }
ushort GetDataTypeFlags(ENUM_DATATYPE _dt) {
switch (_dt) {
case TYPE_BOOL:
Expand Down
27 changes: 16 additions & 11 deletions Indicator.struct.serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,26 @@ SerializerNodeType IndicatorDataEntry::Serialize(Serializer &_s) {
// this work? _s.Pass(THIS_REF, (string)i, GetEntry(i), SERIALIZER_FIELD_FLAG_DYNAMIC |
// SERIALIZER_FIELD_FLAG_FEATURE); // Can this work?

switch (GetDataType()) {
switch (values[i].GetDataType()) {
case TYPE_DOUBLE:
_s.Pass(THIS_REF, (string)i, values[i].vdbl, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
_s.Pass(THIS_REF, (string)i, values[i].value.vdbl,
SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
break;
case TYPE_FLOAT:
_s.Pass(THIS_REF, (string)i, values[i].vflt, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
_s.Pass(THIS_REF, (string)i, values[i].value.vflt,
SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
break;
case TYPE_INT:
case TYPE_UINT:
if (CheckFlags(INDI_ENTRY_FLAG_IS_BITWISE)) {
// Split for each bit and pass 0 or 1.
for (int j = 0; j < sizeof(int) * 8; ++j) {
int _value = (values[i].vint & (1 << j)) != 0;
int _value = (values[i].value.vint & (1 << j)) != 0;
_s.Pass(THIS_REF, StringFormat("%d@%d", i, j), _value, SERIALIZER_FIELD_FLAG_FEATURE);
}
} else {
_s.Pass(THIS_REF, (string)i, values[i].vint, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
_s.Pass(THIS_REF, (string)i, values[i].value.vint,
SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
}
break;
case TYPE_LONG:
Expand All @@ -71,7 +74,8 @@ SerializerNodeType IndicatorDataEntry::Serialize(Serializer &_s) {
*/
SetUserError(ERR_INVALID_PARAMETER);
} else {
_s.Pass(THIS_REF, (string)i, values[i].vlong, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
_s.Pass(THIS_REF, (string)i, values[i].value.vlong,
SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
}
break;
default:
Expand All @@ -83,11 +87,12 @@ SerializerNodeType IndicatorDataEntry::Serialize(Serializer &_s) {
}

/* Method to serialize IndicatorDataEntry's IndicatorDataEntryValue union. */
SerializerNodeType IndicatorDataEntry::IndicatorDataEntryValue::Serialize(Serializer &_s) {
_s.Pass(THIS_REF, "vdbl", vdbl);
_s.Pass(THIS_REF, "vflt", vflt);
_s.Pass(THIS_REF, "vint", vint);
_s.Pass(THIS_REF, "vlong", vlong);
SerializerNodeType IndicatorDataEntryValue::Serialize(Serializer &_s) {
_s.Pass(THIS_REF, "flags", flags);
_s.Pass(THIS_REF, "vdbl", value.vdbl);
_s.Pass(THIS_REF, "vflt", value.vflt);
_s.Pass(THIS_REF, "vint", value.vint);
_s.Pass(THIS_REF, "vlong", value.vlong);
return SerializerNodeObject;
};

Expand Down
16 changes: 6 additions & 10 deletions IndicatorBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class Chart;
#include "Indicator.struct.h"
#include "Indicator.struct.serialize.h"
#include "Indicator.struct.signal.h"
#include "Math.h"
#include "Object.mqh"
#include "Refs.mqh"
#include "Serializer.mqh"
Expand Down Expand Up @@ -835,18 +834,15 @@ class IndicatorBase : public Chart {
return value_storages[_mode];
}

/**
* Returns indicator value for a given shift and mode.
*/
template <typename T>
T GetValue(int _shift = 0, int _mode = -1) {
T _result;
int _index = _mode != -1 ? _mode : GetDataSourceMode();
GetEntry(_shift).values[_index].Get(_result);
ResetLastError();
return _result;
T GetValue(int _shift = 0, int _mode = 0) {
T _out;
GetMixedValue(_shift, _mode).Get(_out);
return _out;
}

virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) = NULL;

/**
* Returns price corresponding to indicator value for a given shift and mode.
*
Expand Down
2 changes: 1 addition & 1 deletion Indicators/Bitwise/Indi_Candle.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Indi_Candle : public Indicator<CandleParams> {
/**
* Returns the indicator's value.
*/
virtual double GetValue(int _mode = 0, int _shift = 0) {
virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) {
double _value = EMPTY_VALUE;
BarOHLC _ohlcs[1];

Expand Down
2 changes: 1 addition & 1 deletion Indicators/Bitwise/Indi_Pattern.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class Indi_Pattern : public Indicator<IndiPatternParams> {
/**
* Returns the indicator's value.
*/
virtual uint GetValue(int _mode = 0, int _shift = 0) {
virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) {
int i;
BarOHLC _ohlcs[8];

Expand Down
5 changes: 3 additions & 2 deletions Indicators/Indi_AC.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ double iAC(string _symbol, int _tf, int _shift) { return Indi_AC::iAC(_symbol, (
struct IndiACParams : IndicatorParams {
// Struct constructor.
IndiACParams(int _shift = 0) : IndicatorParams(INDI_AC, 1, TYPE_DOUBLE) {
SetDataSourceType(IDATA_ICUSTOM);
SetDataValueRange(IDATA_RANGE_MIXED);
SetCustomIndicatorName("Examples\\Accelerator");
shift = _shift;
Expand Down Expand Up @@ -97,8 +98,8 @@ class Indi_AC : public Indicator<IndiACParams> {
/**
* Returns the indicator's value.
*/
virtual double GetValue(int _mode = 0, int _shift = 0) {
double _value = EMPTY_VALUE;
virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) {
IndicatorDataEntryValue _value = EMPTY_VALUE;
switch (iparams.idstype) {
case IDATA_BUILTIN:
istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle;
Expand Down
Loading

0 comments on commit 1e59d35

Please sign in to comment.