diff --git a/Bar.struct.h b/Bar.struct.h
index 366b0d30e..bbd8f5a42 100644
--- a/Bar.struct.h
+++ b/Bar.struct.h
@@ -33,11 +33,16 @@
// Includes.
#include "Bar.enum.h"
#include "Chart.enum.h"
+#include "ISerializable.h"
#include "Serializer.mqh"
#include "SerializerNode.enum.h"
/* Struct for storing OHLC values. */
-struct BarOHLC {
+struct BarOHLC
+#ifndef __MQL__
+ : public ISerializable
+#endif
+{
datetime time;
float open, high, low, close;
// Struct constructor.
@@ -231,7 +236,7 @@ struct BarEntry {
// Serializers.
void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {}
SerializerNodeType Serialize(Serializer &s) {
- s.PassStruct(this, "ohlc", ohlc, SERIALIZER_FIELD_FLAG_DYNAMIC);
+ s.PassStruct(THIS_REF, "ohlc", ohlc, SERIALIZER_FIELD_FLAG_DYNAMIC);
return SerializerNodeObject;
}
string ToCSV() { return StringFormat("%s", ohlc.ToCSV()); }
diff --git a/Chart.struct.h b/Chart.struct.h
index cc7b19b0f..28c960683 100644
--- a/Chart.struct.h
+++ b/Chart.struct.h
@@ -126,25 +126,7 @@ struct ChartStatic {
#endif
}
- /**
- * Wrapper struct that returns open time of each bar of the current chart.
- *
- * @see: https://docs.mql4.com/predefined/time
- */
- struct ChartBarTime {
- protected:
- string symbol;
- ENUM_TIMEFRAMES tf;
-
- public:
- ChartBarTime() : symbol(_Symbol), tf(PERIOD_CURRENT) {}
- datetime operator[](const int _shift) const { return Get(symbol, tf, _shift); }
- static datetime Get(const string _symbol, const ENUM_TIMEFRAMES _tf, const int _shift) {
- return ChartStatic::iTime(_symbol, _tf, _shift);
- }
- };
-
- /**
+/**
* Wrapper struct that returns close prices of each bar of the current chart.
*
* @see: https://docs.mql4.com/predefined/close
@@ -460,3 +442,21 @@ struct ChartPriceOpen {
*/
static long ID() { return ::ChartID(); }
};
+
+/**
+ * Wrapper struct that returns open time of each bar of the current chart.
+ *
+ * @see: https://docs.mql4.com/predefined/time
+ */
+struct ChartBarTime {
+ protected:
+ string symbol;
+ ENUM_TIMEFRAMES tf;
+
+ public:
+ ChartBarTime() : symbol(_Symbol), tf(PERIOD_CURRENT) {}
+ datetime operator[](const int _shift) const { return Get(symbol, tf, _shift); }
+ static datetime Get(const string _symbol, const ENUM_TIMEFRAMES _tf, const int _shift) {
+ return ChartStatic::iTime(_symbol, _tf, _shift);
+ }
+};
diff --git a/Chart.struct.tf.h b/Chart.struct.tf.h
index 89468cd43..64962cdfc 100644
--- a/Chart.struct.tf.h
+++ b/Chart.struct.tf.h
@@ -229,6 +229,8 @@ struct ChartTf {
SerializerNodeType Serialize(Serializer& s);
};
+#include "Serializer.mqh"
+
/* Method to serialize ChartTf structure. */
SerializerNodeType ChartTf::Serialize(Serializer& s) {
s.PassEnum(THIS_REF, "tf", tf);
diff --git a/Data.struct.h b/Data.struct.h
index 4f0deaa0d..288c3d735 100644
--- a/Data.struct.h
+++ b/Data.struct.h
@@ -36,8 +36,8 @@ struct MqlParam;
// Includes.
#include "Data.enum.h"
-#include "Serializer.mqh"
#include "SerializerNode.enum.h"
+#include "SymbolInfo.struct.h"
#ifndef __MQL__
/**
@@ -54,6 +54,56 @@ struct MqlParam {
double double_value; // Field to store a double type.
string string_value; // Field to store a string type.
};
+ MqlParam() { type = (ENUM_DATATYPE)WRONG_VALUE; }
+
+ MqlParam(const MqlParam &_r) { THIS_REF = _r; }
+
+ MqlParam &operator=(const MqlParam &_r) {
+ type = _r.type;
+ switch (type) {
+ case TYPE_BOOL:
+ case TYPE_CHAR:
+ case TYPE_INT:
+ case TYPE_LONG:
+ case TYPE_SHORT:
+ case TYPE_UINT:
+ case TYPE_ULONG:
+ case TYPE_USHORT:
+ case TYPE_UCHAR:
+ case TYPE_COLOR:
+ case TYPE_DATETIME:
+ integer_value = _r.integer_value;
+ break;
+ case TYPE_DOUBLE:
+ case TYPE_FLOAT:
+ double_value = _r.double_value;
+ break;
+ case TYPE_STRING:
+ string_value = _r.string_value;
+ }
+ }
+
+ MqlParam(long _value) {
+ type = ENUM_DATATYPE::TYPE_LONG;
+ integer_value = _value;
+ }
+ MqlParam(int _value) {
+ type = ENUM_DATATYPE::TYPE_INT;
+ integer_value = _value;
+ }
+ MqlParam(bool _value) {
+ type = ENUM_DATATYPE::TYPE_BOOL;
+ integer_value = _value ? 1 : 0;
+ }
+ MqlParam(float _value) {
+ type = ENUM_DATATYPE::TYPE_FLOAT;
+ double_value = (double)_value;
+ }
+ MqlParam(double _value) {
+ type = ENUM_DATATYPE::TYPE_DOUBLE;
+ double_value = _value;
+ }
+ ~MqlParam() {}
};
#endif
@@ -66,6 +116,7 @@ struct MqlParam {
*/
struct DataParamEntry : public MqlParam {
public:
+ DataParamEntry(const DataParamEntry &_r) { ((MqlParam &)THIS_REF) = ((MqlParam &)_r); }
// Struct operators.
void operator=(const bool _value) {
type = TYPE_BOOL;
@@ -126,6 +177,8 @@ struct DataParamEntry : public MqlParam {
SerializerNodeType Serialize(Serializer &s);
};
+#include "Serializer.mqh"
+
/* Method to serialize DataParamEntry struct. */
SerializerNodeType DataParamEntry::Serialize(Serializer &s) {
s.PassEnum(THIS_REF, "type", type, SERIALIZER_FIELD_FLAG_HIDDEN);
diff --git a/DateTime.mqh b/DateTime.mqh
index 61b0c8d89..986fe52f1 100644
--- a/DateTime.mqh
+++ b/DateTime.mqh
@@ -212,7 +212,7 @@ class DateTime {
* @return
* Returns true when the condition is met.
*/
- static bool CheckCondition(ENUM_DATETIME_CONDITION _cond, DataParamEntry REF(_args)[]) {
+ static bool CheckCondition(ENUM_DATETIME_CONDITION _cond, ARRAY_REF(DataParamEntry, _args)) {
switch (_cond) {
case DATETIME_COND_IS_PEAK_HOUR:
return DateTimeStatic::IsPeakHour();
diff --git a/DateTime.struct.h b/DateTime.struct.h
index fb26b4cb7..2d74dff72 100644
--- a/DateTime.struct.h
+++ b/DateTime.struct.h
@@ -76,120 +76,6 @@ struct DateTimeStatic {
#endif
}
- struct DateTimeEntry : MqlDateTime {
- int week_of_year;
- // Struct constructors.
- DateTimeEntry() { SetDateTime(); }
- DateTimeEntry(datetime _dt) { SetDateTime(_dt); }
- // Getters.
- int GetDayOfMonth() { return day; }
- int GetDayOfWeek() {
- // Returns the zero-based day of week.
- // (0-Sunday, 1-Monday, ... , 6-Saturday).
- return day_of_week;
- }
- int GetDayOfYear() { return day_of_year + 1; } // Zero-based day of year (1st Jan = 0).
- int GetHour() { return hour; }
- int GetMinute() { return min; }
- int GetMonth() { return mon; }
- int GetSeconds() { return sec; }
- // int GetWeekOfYear() { return week_of_year; } // @todo
- int GetValue(ENUM_DATETIME_UNIT _unit) {
- int _result = -1;
- switch (_unit) {
- case DATETIME_SECOND:
- return GetSeconds();
- case DATETIME_MINUTE:
- return GetMinute();
- case DATETIME_HOUR:
- return GetHour();
- case DATETIME_DAY:
- return GetDayOfMonth();
- case DATETIME_WEEK:
- return -1; // return WeekOfYear(); // @todo
- case DATETIME_MONTH:
- return GetMonth();
- case DATETIME_YEAR:
- return GetYear();
- default:
- break;
- }
- return _result;
- }
- unsigned int GetValue(unsigned int _unit) {
- if ((_unit & (DATETIME_DAY | DATETIME_WEEK)) != 0) {
- return GetDayOfWeek();
- } else if ((_unit & (DATETIME_DAY | DATETIME_MONTH)) != 0) {
- return GetDayOfMonth();
- } else if ((_unit & (DATETIME_DAY | DATETIME_YEAR)) != 0) {
- return GetDayOfYear();
- }
- return GetValue((ENUM_DATETIME_UNIT)_unit);
- }
- int GetYear() { return year; }
- datetime GetTimestamp() { return StructToTime(THIS_REF); }
- // Setters.
- void SetDateTime() { TimeToStruct(TimeCurrent(), THIS_REF); }
- void SetDateTime(datetime _dt) { TimeToStruct(_dt, THIS_REF); }
- void SetDayOfMonth(int _value) {
- day = _value;
- day_of_week = DateTimeStatic::DayOfWeek(); // Zero-based day of week.
- day_of_year = DateTimeStatic::DayOfYear(); // Zero-based day of year.
- }
- void SetDayOfYear(int _value) {
- day_of_year = _value - 1; // Sets zero-based day of year.
- day = DateTimeStatic::Month(); // Sets day of month (1..31).
- day_of_week = DateTimeStatic::DayOfWeek(); // Zero-based day of week.
- }
- void SetHour(int _value) { hour = _value; }
- void SetMinute(int _value) { min = _value; }
- void SetMonth(int _value) { mon = _value; }
- void SetSeconds(int _value) { sec = _value; }
- void SetWeekOfYear(int _value) {
- week_of_year = _value;
- // day = @todo;
- // day_of_week = @todo;
- // day_of_year = @todo;
- }
- void SetValue(ENUM_DATETIME_UNIT _unit, int _value) {
- switch (_unit) {
- case DATETIME_SECOND:
- SetSeconds(_value);
- break;
- case DATETIME_MINUTE:
- SetMinute(_value);
- break;
- case DATETIME_HOUR:
- SetHour(_value);
- break;
- case DATETIME_DAY:
- SetDayOfMonth(_value);
- break;
- case DATETIME_WEEK:
- SetWeekOfYear(_value);
- break;
- case DATETIME_MONTH:
- SetMonth(_value);
- break;
- case DATETIME_YEAR:
- SetYear(_value);
- break;
- default:
- break;
- }
- }
- void SetValue(unsigned short _unit, int _value) {
- if ((_unit & (DATETIME_DAY | DATETIME_MONTH)) != 0) {
- SetDayOfMonth(_value);
- } else if ((_unit & (DATETIME_DAY | DATETIME_YEAR)) != 0) {
- SetDayOfYear(_value);
- } else {
- SetValue((ENUM_DATETIME_UNIT)_unit, _value);
- }
- }
- void SetYear(int _value) { year = _value; }
-};
-
/**
* Returns the current zero-based day of the week of the last known server time.
*/
@@ -339,3 +225,124 @@ struct DateTimeStatic {
#endif
}
};
+
+struct DateTimeEntry : MqlDateTime {
+ int week_of_year;
+ // Struct constructors.
+ DateTimeEntry() { SetDateTime(); }
+ DateTimeEntry(datetime _dt) { SetDateTime(_dt); }
+ DateTimeEntry(MqlDateTime& _dt) {
+ // @fixit Should also set day of week.
+ ((MqlDateTime)THIS_REF) = _dt;
+#ifndef __MQL__
+ throw NotImplementedException();
+#endif
+ }
+ // Getters.
+ int GetDayOfMonth() { return day; }
+ int GetDayOfWeek() {
+ // Returns the zero-based day of week.
+ // (0-Sunday, 1-Monday, ... , 6-Saturday).
+ return day_of_week;
+ }
+ int GetDayOfYear() { return day_of_year + 1; } // Zero-based day of year (1st Jan = 0).
+ int GetHour() { return hour; }
+ int GetMinute() { return min; }
+ int GetMonth() { return mon; }
+ int GetSeconds() { return sec; }
+ // int GetWeekOfYear() { return week_of_year; } // @todo
+ int GetValue(ENUM_DATETIME_UNIT _unit) {
+ int _result = -1;
+ switch (_unit) {
+ case DATETIME_SECOND:
+ return GetSeconds();
+ case DATETIME_MINUTE:
+ return GetMinute();
+ case DATETIME_HOUR:
+ return GetHour();
+ case DATETIME_DAY:
+ return GetDayOfMonth();
+ case DATETIME_WEEK:
+ return -1; // return WeekOfYear(); // @todo
+ case DATETIME_MONTH:
+ return GetMonth();
+ case DATETIME_YEAR:
+ return GetYear();
+ default:
+ break;
+ }
+ return _result;
+ }
+ unsigned int GetValue(unsigned int _unit) {
+ if ((_unit & (DATETIME_DAY | DATETIME_WEEK)) != 0) {
+ return GetDayOfWeek();
+ } else if ((_unit & (DATETIME_DAY | DATETIME_MONTH)) != 0) {
+ return GetDayOfMonth();
+ } else if ((_unit & (DATETIME_DAY | DATETIME_YEAR)) != 0) {
+ return GetDayOfYear();
+ }
+ return GetValue((ENUM_DATETIME_UNIT)_unit);
+ }
+ int GetYear() { return year; }
+ datetime GetTimestamp() { return StructToTime(THIS_REF); }
+ // Setters.
+ void SetDateTime() { TimeToStruct(TimeCurrent(), THIS_REF); }
+ void SetDateTime(datetime _dt) { TimeToStruct(_dt, THIS_REF); }
+ void SetDayOfMonth(int _value) {
+ day = _value;
+ day_of_week = DateTimeStatic::DayOfWeek(); // Zero-based day of week.
+ day_of_year = DateTimeStatic::DayOfYear(); // Zero-based day of year.
+ }
+ void SetDayOfYear(int _value) {
+ day_of_year = _value - 1; // Sets zero-based day of year.
+ day = DateTimeStatic::Month(); // Sets day of month (1..31).
+ day_of_week = DateTimeStatic::DayOfWeek(); // Zero-based day of week.
+ }
+ void SetHour(int _value) { hour = _value; }
+ void SetMinute(int _value) { min = _value; }
+ void SetMonth(int _value) { mon = _value; }
+ void SetSeconds(int _value) { sec = _value; }
+ void SetWeekOfYear(int _value) {
+ week_of_year = _value;
+ // day = @todo;
+ // day_of_week = @todo;
+ // day_of_year = @todo;
+ }
+ void SetValue(ENUM_DATETIME_UNIT _unit, int _value) {
+ switch (_unit) {
+ case DATETIME_SECOND:
+ SetSeconds(_value);
+ break;
+ case DATETIME_MINUTE:
+ SetMinute(_value);
+ break;
+ case DATETIME_HOUR:
+ SetHour(_value);
+ break;
+ case DATETIME_DAY:
+ SetDayOfMonth(_value);
+ break;
+ case DATETIME_WEEK:
+ SetWeekOfYear(_value);
+ break;
+ case DATETIME_MONTH:
+ SetMonth(_value);
+ break;
+ case DATETIME_YEAR:
+ SetYear(_value);
+ break;
+ default:
+ break;
+ }
+ }
+ void SetValue(unsigned short _unit, int _value) {
+ if ((_unit & (DATETIME_DAY | DATETIME_MONTH)) != 0) {
+ SetDayOfMonth(_value);
+ } else if ((_unit & (DATETIME_DAY | DATETIME_YEAR)) != 0) {
+ SetDayOfYear(_value);
+ } else {
+ SetValue((ENUM_DATETIME_UNIT)_unit, _value);
+ }
+ }
+ void SetYear(int _value) { year = _value; }
+};
diff --git a/File.mqh b/File.mqh
index dc928f1fd..4fe3dcb6b 100644
--- a/File.mqh
+++ b/File.mqh
@@ -30,7 +30,8 @@
*/
// Includes.
-#include "Terminal.mqh"
+#include "Terminal.define.h"
+#include "Terminal.enum.h"
#ifndef __MQL__
enum ENUM_FILE_PROPERTY_INTEGER {
diff --git a/ISerializable.h b/ISerializable.h
new file mode 100644
index 000000000..b00d8d4d1
--- /dev/null
+++ b/ISerializable.h
@@ -0,0 +1,39 @@
+//+------------------------------------------------------------------+
+//| EA31337 framework |
+//| Copyright 2016-2021, EA31337 Ltd |
+//| https://github.com/EA31337 |
+//+------------------------------------------------------------------+
+
+/*
+ * This file is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * @file
+ * Serializable interface.
+ */
+
+#ifndef __MQL__
+// Allows the preprocessor to include a header file when it is needed.
+#pragma once
+#endif
+
+enum SerializerNodeType;
+class Serializer;
+
+class ISerializable {
+ public:
+ virtual SerializerNodeType Serialize(Serializer &s) = 0;
+};
diff --git a/Indicator.struct.h b/Indicator.struct.h
index c1188b475..5800feeec 100644
--- a/Indicator.struct.h
+++ b/Indicator.struct.h
@@ -124,20 +124,6 @@ struct IndicatorCalculateCache {
int GetPrevCalculated(int _prev_calculated) { return prev_calculated; }
};
-#ifndef __MQL__
-/**
- * The structure of input parameters of indicators.
- *
- * @see: https://www.mql5.com/en/docs/constants/structures/mqlparam
- */
-struct MqlParam {
- ENUM_DATATYPE type; // Type of the input parameter, value of ENUM_DATATYPE.
- long integer_value; // Field to store an integer type.
- double double_value; // Field to store a double type.
- string string_value; // Field to store a string type.
-};
-#endif
-
/* Structure for indicator data entry. */
struct IndicatorDataEntry {
long timestamp; // Timestamp of the entry's bar.
@@ -374,11 +360,7 @@ struct IndicatorDataEntry {
values[2].Get(_out3);
values[3].Get(_out4);
};
- DataParamEntry GetEntry(int _index = 0) {
- DataParamEntry _entry;
- _entry.type = GetDataType();
- return _entry;
- }
+
// Getters.
int GetDayOfYear() { return DateTimeStatic::DayOfYear(timestamp); }
int GetMonth() { return DateTimeStatic::Month(timestamp); }
diff --git a/Log.mqh b/Log.mqh
index 07192d540..9e617a293 100644
--- a/Log.mqh
+++ b/Log.mqh
@@ -25,7 +25,6 @@
#include "Collection.mqh"
#include "DateTime.mqh"
#include "Object.mqh"
-#include "Terminal.mqh"
// Prevents processing this includes file for the second time.
#ifndef LOG_MQH
@@ -149,12 +148,8 @@ class Log : public Object {
/**
* Reports an last error.
*/
- bool AddLastError(string prefix = "", string suffix = "") {
- return Add(V_ERROR, Terminal::GetLastErrorText(), prefix, suffix);
- }
- bool AddLastError(string prefix, long suffix) {
- return Add(V_ERROR, Terminal::GetLastErrorText(), prefix, StringFormat("%d", suffix));
- }
+ bool AddLastError(string prefix = "", string suffix = "");
+ bool AddLastError(string prefix, long suffix);
/**
* Reports an error.
@@ -185,7 +180,7 @@ class Log : public Object {
* Link this instance with another log instance.
*/
void Link(Log *_log) {
- _log.SetLevel(log_level); // Sets the same level as this instance.
+ PTR_ATTRIB(_log, SetLevel(log_level)); // Sets the same level as this instance.
// @todo: Make sure we're not linking the same instance twice.
logs.Add(_log);
}
@@ -243,7 +238,7 @@ class Log : public Object {
for (lid = 0; lid < logs.GetSize(); lid++) {
Log *_log = logs.GetByIndex(lid);
if (Object::IsValid(_log)) {
- _log.Flush();
+ PTR_ATTRIB(_log, Flush());
}
}
last_entry = -1;
@@ -272,7 +267,7 @@ class Log : public Object {
for (lid = 0; lid < logs.GetSize(); lid++) {
_log = logs.GetByIndex(lid);
if (Object::IsValid(_log)) {
- result += _log.ToString();
+ result += PTR_ATTRIB(_log, ToString());
}
}
@@ -284,7 +279,7 @@ class Log : public Object {
*/
bool SaveToFile(string new_filename, ENUM_LOG_LEVEL _log_level) {
string filepath = new_filename != "" ? new_filename : filename;
- int handle = FileOpen(filepath, FILE_WRITE | FILE_CSV, ": ");
+ int handle = FileOpen(filepath, FILE_WRITE | FILE_CSV, ': ');
if (handle != INVALID_HANDLE) {
for (int i = 0; i < ArraySize(data); i++) {
if (data[i].log_level <= _log_level) {
@@ -302,7 +297,7 @@ class Log : public Object {
bool SaveToFile(string new_filename = "") { return SaveToFile(new_filename, log_level); }
template
- void Erase(T REF(A)[], int iPos) {
+ void Erase(ARRAY_REF(T, A), int iPos) {
int iLast = ArraySize(A) - 1;
A[iPos].timestamp = A[iLast].timestamp;
A[iPos].msg = A[iLast].msg;
@@ -324,4 +319,17 @@ class Log : public Object {
return false;
}
};
+
+#include "Terminal.mqh"
+
+/**
+ * Reports last error.
+ */
+bool Log::AddLastError(string prefix, string suffix) {
+ return Add(V_ERROR, Terminal::GetLastErrorText(), prefix, suffix);
+}
+bool Log::AddLastError(string prefix, long suffix) {
+ return Add(V_ERROR, Terminal::GetLastErrorText(), prefix, StringFormat("%d", suffix));
+}
+
#endif
diff --git a/Refs.mqh b/Refs.mqh
index 090895135..290e3bff5 100644
--- a/Refs.mqh
+++ b/Refs.mqh
@@ -102,12 +102,18 @@ class ReferenceCounter {
/**
* ReferenceCounter class allocator.
*/
- static ReferenceCounter* alloc() {
- // @todo Enhance with linked-list object reuse.
- return new ReferenceCounter();
- }
+ static ReferenceCounter* alloc();
};
+/**
+ * ReferenceCounter class allocator.
+ */
+ReferenceCounter* ReferenceCounter::alloc() {
+ // @todo Enhance with linked-list object reuse.
+ return new ReferenceCounter();
+}
+
+
/**
* Base class for reference-counted objects.
*/
@@ -130,7 +136,7 @@ class Dynamic {
#endif
// Only dynamic objects are reference-counted.
ptr_ref_counter = ReferenceCounter::alloc();
- ptr_ref_counter.ptr_object = THIS_PTR;
+ PTR_ATTRIB(ptr_ref_counter, ptr_object) = THIS_PTR;
} else {
// For objects allocated on the stack we don't use reference counting.
ptr_ref_counter = NULL;
@@ -141,8 +147,8 @@ class Dynamic {
* Destructor.
*/
~Dynamic() {
- if (ptr_ref_counter.num_strong_refs == 0 &&
- ptr_ref_counter.num_weak_refs == 0) {
+ if (PTR_ATTRIB(ptr_ref_counter, num_strong_refs) == 0 &&
+ PTR_ATTRIB(ptr_ref_counter, num_weak_refs) == 0) {
#ifdef __MQL__
if (CheckPointer(ptr_ref_counter) == POINTER_DYNAMIC) {
#else
@@ -159,11 +165,13 @@ class Dynamic {
Dynamic(const Dynamic& right) {
ptr_ref_counter = NULL;
- if (CheckPointer(&this) != POINTER_DYNAMIC && CheckPointer(&right) == POINTER_DYNAMIC) {
+#ifdef __MQL__
+ if (CheckPointer(THIS_PTR) != POINTER_DYNAMIC && CheckPointer(&right) == POINTER_DYNAMIC) {
Print(
"Dynamic object misuse: Invoking copy constructor: STACK OBJECT = HEAP OBJECT. Remember that you can only "
"assign heap-allocated objects to heap-allocated objects!");
}
+#endif
}
void operator=(const Dynamic& right) {
diff --git a/Serializer.mqh b/Serializer.mqh
index edec0e17a..c00c00be1 100644
--- a/Serializer.mqh
+++ b/Serializer.mqh
@@ -27,10 +27,10 @@
// Includes.
#include "Serializer.define.h"
#include "Serializer.enum.h"
-#include "SerializerConverter.mqh"
#include "SerializerNode.mqh"
#include "SerializerNodeIterator.mqh"
#include "SerializerNodeParam.mqh"
+#include "SerializerConverter.mqh"
#define SERIALIZER_DEFAULT_FP_PRECISION 8
@@ -78,7 +78,11 @@ class Serializer {
*/
void Enter(SerializerEnterMode mode = SerializerEnterObject, string key = "") {
if (IsWriting()) {
- SerializerNodeParam* nameParam = (key != NULL && key != "") ? SerializerNodeParam::FromString(key) : NULL;
+ #ifdef __MQL__
+ SerializerNodeParam* nameParam = (key != "" && key != "") ? SerializerNodeParam::FromString(key) : NULL;
+ #else
+ SerializerNodeParam* nameParam = (key != "") ? SerializerNodeParam::FromString(key) : NULL;
+ #endif
// When writing, we need to make parent->child structure. It is not
// required when reading, because structure is full done by parsing the
@@ -86,7 +90,7 @@ class Serializer {
_node = new SerializerNode(mode == SerializerEnterObject ? SerializerNodeObject : SerializerNodeArray, _node,
nameParam);
- if (_node.GetParent() != NULL) _node.GetParent().AddChild(_node);
+ if (PTR_ATTRIB(_node, GetParent()) != NULL) PTR_ATTRIB(PTR_ATTRIB(_node, GetParent()), AddChild(_node));
if (_root == NULL) _root = _node;
} else {
@@ -99,15 +103,15 @@ class Serializer {
if (key != "") {
// We need to enter object that matches given key.
- for (unsigned int i = 0; i < _node.NumChildren(); ++i) {
- child = _node.GetChild(i);
- if (child.GetKeyParam().AsString(false, false) == key) {
+ for (unsigned int i = 0; i < PTR_ATTRIB(_node, NumChildren()); ++i) {
+ child = PTR_ATTRIB(_node, GetChild(i));
+ if (PTR_ATTRIB(PTR_ATTRIB(child, GetKeyParam()), AsString(false, false)) == key) {
_node = child;
return;
}
}
} else if (key == "") {
- _node = _node.GetNextChild();
+ _node = PTR_ATTRIB(_node, GetNextChild());
}
}
}
@@ -115,7 +119,7 @@ class Serializer {
/**
* Leaves current object/array. Used in custom Serialize() method.
*/
- void Leave() { _node = _node.GetParent(); }
+ void Leave() { _node = PTR_ATTRIB(_node, GetParent()); }
/**
* Checks whether we are in serialization process. Used in custom Serialize() method.
@@ -130,22 +134,26 @@ class Serializer {
/**
* Checks whether current node is inside array. Used in custom Serialize() method.
*/
- bool IsArray() { return _mode == Unserialize && _node != NULL && _node.GetType() == SerializerNodeArray; }
+ bool IsArray() {
+ return _mode == Unserialize && _node != NULL && PTR_ATTRIB(_node, GetType()) == SerializerNodeArray;
+ }
/**
* Returns number of array items inside current array.
*/
- unsigned int NumArrayItems() { return _node != NULL ? _node.NumChildren() : 0; }
+ unsigned int NumArrayItems() { return _node != NULL ? PTR_ATTRIB(_node, NumChildren()) : 0; }
/**
* Checks whether current node is an object. Used in custom Serialize() method.
*/
- bool IsObject() { return _mode == Unserialize && _node != NULL && _node.GetType() == SerializerNodeObject; }
+ bool IsObject() {
+ return _mode == Unserialize && _node != NULL && PTR_ATTRIB(_node, GetType()) == SerializerNodeObject;
+ }
/**
* Returns number of child nodes.
*/
- unsigned int NumChildren() { return _node ? _node.NumChildren() : 0; }
+ unsigned int NumChildren() { return _node ? PTR_ATTRIB(_node, NumChildren()) : 0; }
/**
* Returns root node or NULL. Could be used after unserialization.
@@ -155,7 +163,7 @@ class Serializer {
/**
* Returns child node for a given index or NULL.
*/
- SerializerNode* GetChild(unsigned int index) { return _node ? _node.GetChild(index) : NULL; }
+ SerializerNode* GetChild(unsigned int index) { return _node ? PTR_ATTRIB(_node, GetChild(index)) : NULL; }
/**
* Returns floating-point precision.
@@ -266,11 +274,11 @@ class Serializer {
}
void Next() {
- if (_node.GetParent() == NULL) {
+ if (PTR_ATTRIB(_node, GetParent()) == NULL) {
return;
}
- _node = _node.GetParent().GetNextChild();
+ _node = PTR_ATTRIB(PTR_ATTRIB(_node, GetParent()), GetNextChild());
}
/**
@@ -410,138 +418,7 @@ class Serializer {
return NULL;
}
- static string ValueToString(datetime value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
-#ifdef __MQL5__
- return (includeQuotes ? "\"" : "") + TimeToString(value) + (includeQuotes ? "\"" : "");
-#else
- return (includeQuotes ? "\"" : "") + TimeToStr(value) + (includeQuotes ? "\"" : "");
-#endif
- }
-
- static string ValueToString(bool value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
- return (includeQuotes ? "\"" : "") + (value ? "true" : "false") + (includeQuotes ? "\"" : "");
- }
-
- static string ValueToString(int value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
- return (includeQuotes ? "\"" : "") + IntegerToString(value) + (includeQuotes ? "\"" : "");
- }
-
- static string ValueToString(long value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
- return (includeQuotes ? "\"" : "") + IntegerToString(value) + (includeQuotes ? "\"" : "");
- }
-
- static string ValueToString(string value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
- string output = includeQuotes ? "\"" : "";
- unsigned short _char;
-
- for (unsigned short i = 0; i < StringLen(value); ++i) {
-#ifdef __MQL5__
- _char = StringGetCharacter(value, i);
-#else
- _char = StringGetChar(value, i);
-#endif
- if (escape) {
- switch (_char) {
- case '"':
- output += "\\\"";
- continue;
- case '/':
- output += "\\/";
- continue;
- case '\n':
- if (escape) output += "\\n";
- continue;
- case '\r':
- if (escape) output += "\\r";
- continue;
- case '\t':
- if (escape) output += "\\t";
- continue;
- case '\\':
- if (escape) output += "\\\\";
- continue;
- }
- }
-
-#ifdef __MQL5__
- output += ShortToString(StringGetCharacter(value, i));
-#else
- output += ShortToString(StringGetChar(value, i));
-#endif
- }
-
- return output + (includeQuotes ? "\"" : "");
- }
-
- static string ValueToString(float value, bool includeQuotes = false, bool escape = true, int _fp_precision = 6) {
- return (includeQuotes ? "\"" : "") + StringFormat("%." + IntegerToString(_fp_precision) + "f", value) +
- (includeQuotes ? "\"" : "");
- }
-
- static string ValueToString(double value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
- return (includeQuotes ? "\"" : "") + StringFormat("%." + IntegerToString(_fp_precision) + "f", value) +
- (includeQuotes ? "\"" : "");
- }
-
- static string ValueToString(Object* _obj, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
- return (includeQuotes ? "\"" : "") + ((Object*)_obj).ToString() + (includeQuotes ? "\"" : "");
- }
- template
- static string ValueToString(T value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
- return StringFormat("%s%s%s", (includeQuotes ? "\"" : ""), value, (includeQuotes ? "\"" : ""));
- }
- static string UnescapeString(string value) {
- string output = "";
- unsigned short _char1;
- unsigned short _char2;
-
- for (unsigned short i = 0; i < StringLen(value); ++i) {
-#ifdef __MQL5__
- _char1 = StringGetCharacter(value, i);
- _char2 = StringGetCharacter(value, i + 1);
-#else
- _char1 = StringGetChar(value, i);
- _char2 = StringGetChar(value, i + 1);
-#endif
- if (_char1 == '\\') {
- switch (_char2) {
- case '"':
- output += "\"";
- i++;
- continue;
- case '/':
- output += "/";
- i++;
- continue;
- case 'n':
- output += "\n";
- i++;
- continue;
- case 'r':
- output += "\r";
- i++;
- continue;
- case 't':
- output += "\t";
- i++;
- continue;
- case '\\':
- output += "\\";
- i++;
- continue;
- }
- }
-
-#ifdef __MQL5__
- output += ShortToString(StringGetCharacter(value, i));
-#else
- output += ShortToString(StringGetChar(value, i));
-#endif
- }
-
- return output;
- }
-
+
template
static SerializerConverter MakeStubObject(int _serializer_flags = SERIALIZER_FLAG_INCLUDE_ALL, int _n1 = 1,
int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {
diff --git a/SerializerConversions.h b/SerializerConversions.h
new file mode 100644
index 000000000..b8dc387a9
--- /dev/null
+++ b/SerializerConversions.h
@@ -0,0 +1,169 @@
+//+------------------------------------------------------------------+
+//| EA31337 framework |
+//| Copyright 2016-2021, EA31337 Ltd |
+//| https://github.com/EA31337 |
+//+------------------------------------------------------------------+
+
+/*
+ * This file is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * @file
+ * Serializer data conversion methods.
+ */
+
+#ifndef __MQL__
+// Allows the preprocessor to include a header file when it is needed.
+#pragma once
+#endif
+
+#include "Refs.struct.h"
+#include "Object.mqh"
+
+class SerializerConversions {
+ public:
+ static string ValueToString(datetime value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+#ifndef __MQL4__
+ return (includeQuotes ? "\"" : "") + TimeToString(value) + (includeQuotes ? "\"" : "");
+#else
+ return (includeQuotes ? "\"" : "") + TimeToStr(value) + (includeQuotes ? "\"" : "");
+#endif
+ }
+
+ static string ValueToString(bool value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+ return string(includeQuotes ? "\"" : "") + (value ? "true" : "false") + (includeQuotes ? "\"" : "");
+ }
+
+ static string ValueToString(int value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+ return string(includeQuotes ? "\"" : "") + IntegerToString(value) + (includeQuotes ? "\"" : "");
+ }
+
+ static string ValueToString(long value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+ return string(includeQuotes ? "\"" : "") + IntegerToString(value) + (includeQuotes ? "\"" : "");
+ }
+
+ static string ValueToString(string value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+ string output = includeQuotes ? "\"" : "";
+ unsigned short _char;
+
+ for (unsigned short i = 0; i < StringLen(value); ++i) {
+#ifndef __MQL4__
+ _char = StringGetCharacter(value, i);
+#else
+ _char = StringGetChar(value, i);
+#endif
+ if (escape) {
+ switch (_char) {
+ case '"':
+ output += "\\\"";
+ continue;
+ case '/':
+ output += "\\/";
+ continue;
+ case '\n':
+ if (escape) output += "\\n";
+ continue;
+ case '\r':
+ if (escape) output += "\\r";
+ continue;
+ case '\t':
+ if (escape) output += "\\t";
+ continue;
+ case '\\':
+ if (escape) output += "\\\\";
+ continue;
+ }
+ }
+
+#ifndef __MQL4__
+ output += ShortToString(StringGetCharacter(value, i));
+#else
+ output += ShortToString(StringGetChar(value, i));
+#endif
+ }
+
+ return output + (includeQuotes ? "\"" : "");
+ }
+
+ static string ValueToString(float value, bool includeQuotes = false, bool escape = true, int _fp_precision = 6) {
+ return (includeQuotes ? "\"" : "") + StringFormat("%." + IntegerToString(_fp_precision) + "f", value) +
+ (includeQuotes ? "\"" : "");
+ }
+
+ static string ValueToString(double value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+ return (includeQuotes ? "\"" : "") + StringFormat("%." + IntegerToString(_fp_precision) + "f", value) +
+ (includeQuotes ? "\"" : "");
+ }
+
+ static string ValueToString(Object& _obj, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+ return (includeQuotes ? "\"" : "") + ((Object&)_obj).ToString() + (includeQuotes ? "\"" : "");
+ }
+ template
+ static string ValueToString(T value, bool includeQuotes = false, bool escape = true, int _fp_precision = 8) {
+ return StringFormat("%s%s%s", (includeQuotes ? "\"" : ""), value, (includeQuotes ? "\"" : ""));
+ }
+ static string UnescapeString(string value) {
+ string output = "";
+ unsigned short _char1;
+ unsigned short _char2;
+
+ for (unsigned short i = 0; i < StringLen(value); ++i) {
+#ifndef __MQL4__
+ _char1 = StringGetCharacter(value, i);
+ _char2 = StringGetCharacter(value, i + 1);
+#else
+ _char1 = StringGetChar(value, i);
+ _char2 = StringGetChar(value, i + 1);
+#endif
+ if (_char1 == '\\') {
+ switch (_char2) {
+ case '"':
+ output += "\"";
+ i++;
+ continue;
+ case '/':
+ output += "/";
+ i++;
+ continue;
+ case 'n':
+ output += "\n";
+ i++;
+ continue;
+ case 'r':
+ output += "\r";
+ i++;
+ continue;
+ case 't':
+ output += "\t";
+ i++;
+ continue;
+ case '\\':
+ output += "\\";
+ i++;
+ continue;
+ }
+ }
+
+#ifndef __MQL4__
+ output += ShortToString(StringGetCharacter(value, i));
+#else
+ output += ShortToString(StringGetChar(value, i));
+#endif
+ }
+
+ return output;
+ }
+};
diff --git a/SerializerConverter.mqh b/SerializerConverter.mqh
index 8f442454d..803e81754 100644
--- a/SerializerConverter.mqh
+++ b/SerializerConverter.mqh
@@ -60,10 +60,10 @@ class SerializerConverter {
*/
SerializerConverter* Precision(int _fp_precision) {
if (root_node == NULL) {
- return &this;
+ return THIS_PTR;
}
- root_node.OverrideFloatingPointPrecision(_fp_precision);
- return &this;
+ PTR_ATTRIB(root_node, OverrideFloatingPointPrecision(_fp_precision));
+ return THIS_PTR;
}
template
diff --git a/SerializerDict.mqh b/SerializerDict.mqh
index 5efb2393c..68ebde3fc 100644
--- a/SerializerDict.mqh
+++ b/SerializerDict.mqh
@@ -25,12 +25,6 @@
#define SERIALIZER_DICT_MQH
// Includes.
-#include "Dict.mqh"
-#include "DictObject.mqh"
-#include "DictStruct.mqh"
-#include "Matrix.mqh"
-#include "Object.mqh"
-#include "Serializer.mqh"
#include "SerializerNode.mqh"
enum ENUM_SERIALIZER_DICT_FLAGS {};
diff --git a/SerializerNode.mqh b/SerializerNode.mqh
index 05947a73a..5d347aad4 100644
--- a/SerializerNode.mqh
+++ b/SerializerNode.mqh
@@ -26,7 +26,6 @@
// Includes.
#include "SerializerNode.enum.h"
-#include "SerializerNodeIterator.mqh"
#include "SerializerNodeParam.mqh"
class SerializerNode {
@@ -82,7 +81,8 @@ class SerializerNode {
/**
* Checks whether node has specified key.
*/
- bool HasKey() { return _key != NULL && _key._string != ""; }
+ bool HasKey() { return _key != NULL && PTR_ATTRIB(_key, _string) != "";
+ }
/**
* Checks whether node is an array.
@@ -104,7 +104,7 @@ class SerializerNode {
*/
bool IsValuesContainer() {
return (_type == SerializerNodeArray || _type == SerializerNodeObject) && _numChildren > 0 &&
- !_children[0].IsContainer();
+ !PTR_ATTRIB(_children[0], IsContainer());
}
/**
@@ -115,7 +115,7 @@ class SerializerNode {
/**
* Returns key specified for a node or empty string (not a NULL).
*/
- string Key() { return _key != NULL ? _key.AsString(false, false) : ""; }
+ string Key() { return _key != NULL ? PTR_ATTRIB(_key, AsString(false, false)) : ""; }
/**
* Returns tree size in bytes.
@@ -124,7 +124,7 @@ class SerializerNode {
int _result = 0;
if (!IsContainer()) {
- switch (_value.GetType()) {
+ switch (PTR_ATTRIB(_value, GetType())) {
case SerializerNodeParamBool:
_result += 1;
break;
@@ -135,12 +135,12 @@ class SerializerNode {
_result += 4;
break;
case SerializerNodeParamString:
- _result += StringLen(_value._string) + 1;
+ _result += StringLen(PTR_ATTRIB(_value, _string)) + 1;
break;
}
}
- for (unsigned int i = 0; i < _numChildren; ++i) _result += _children[i].BinarySize();
+ for (unsigned int i = 0; i < _numChildren; ++i) _result += PTR_ATTRIB(_children[i], BinarySize());
return _result;
}
@@ -152,11 +152,11 @@ class SerializerNode {
SerializerNodeParam* _value_param = GetValueParam();
if (_value_param != NULL) {
- _value_param.SetFloatingPointPrecision(_fp_precision);
+ PTR_ATTRIB(_value_param, SetFloatingPointPrecision(_fp_precision));
}
for (unsigned int i = 0; i < _numChildren; ++i) {
- _children[i].OverrideFloatingPointPrecision(_fp_precision);
+ PTR_ATTRIB(_children[i], OverrideFloatingPointPrecision(_fp_precision));
}
}
@@ -168,7 +168,7 @@ class SerializerNode {
unsigned int _result = 0;
- for (unsigned int i = 0; i < _numChildren; ++i) _result += _children[i].TotalNumChildren();
+ for (unsigned int i = 0; i < _numChildren; ++i) _result += PTR_ATTRIB(_children[i], TotalNumChildren());
return _result;
}
@@ -182,9 +182,9 @@ class SerializerNode {
if (GetParent() == NULL) {
for (i = 0; i < _numChildren; ++i) {
if (IsObject())
- _result += _children[i].MaximumNumChildrenInDeepEnd();
+ _result += PTR_ATTRIB(_children[i], MaximumNumChildrenInDeepEnd());
else
- _result = MathMax(_result, _children[i].MaximumNumChildrenInDeepEnd());
+ _result = MathMax(_result, PTR_ATTRIB(_children[i], MaximumNumChildrenInDeepEnd()));
}
return _result;
@@ -192,7 +192,7 @@ class SerializerNode {
if (IsObject() || IsArray()) {
for (i = 0; i < _numChildren; ++i) {
- _result += _children[i].MaximumNumChildrenInDeepEnd();
+ _result += PTR_ATTRIB(_children[i], MaximumNumChildrenInDeepEnd());
}
return _result;
}
@@ -211,8 +211,8 @@ class SerializerNode {
}
for (unsigned int i = 0; i < _numChildren; ++i) {
- if (_children[i].GetType() == SerializerNodeArray || _children[i].GetType() == SerializerNodeObject) {
- _sum += _children[i].MaximumNumContainersInDeepEnd();
+ if (PTR_ATTRIB(_children[i], GetType()) == SerializerNodeArray || PTR_ATTRIB(_children[i], GetType()) == SerializerNodeObject) {
+ _sum += PTR_ATTRIB(_children[i], MaximumNumContainersInDeepEnd());
}
}
@@ -259,7 +259,7 @@ class SerializerNode {
void AddChild(SerializerNode* child) {
if (_numChildren == ArraySize(_children)) ArrayResize(_children, _numChildren + 10);
- child._index = (int)_numChildren;
+ PTR_ATTRIB(child, _index) = (int)_numChildren;
_children[_numChildren++] = child;
}
@@ -295,8 +295,8 @@ class SerializerNode {
bool IsLast() {
if (!_parent) return true;
- for (unsigned int i = 0; i < _parent.NumChildren(); ++i) {
- if (_parent.GetChild(i) == &this && i != _parent.NumChildren() - 1) return false;
+ for (unsigned int i = 0; i < PTR_ATTRIB(_parent, NumChildren()); ++i) {
+ if (PTR_ATTRIB(_parent, GetChild(i)) == THIS_PTR && i != PTR_ATTRIB(_parent, NumChildren() - 1)) return false;
}
return true;
@@ -314,10 +314,10 @@ class SerializerNode {
repr += ident;
- if (GetKeyParam() != NULL && GetKeyParam().AsString(false, false) != "")
- repr += GetKeyParam().AsString(false, true) + ":" + (trimWhitespaces ? "" : " ");
+ if (GetKeyParam() != NULL && PTR_ATTRIB(GetKeyParam(), AsString(false, false)) != "")
+ repr += PTR_ATTRIB(GetKeyParam(), AsString(false, true)) + ":" + (trimWhitespaces ? "" : " ");
- if (GetValueParam() != NULL) repr += GetValueParam().AsString(false, true);
+ if (GetValueParam() != NULL) repr += PTR_ATTRIB(GetValueParam(), AsString(false, true));
switch (GetType()) {
case SerializerNodeObject:
@@ -330,7 +330,7 @@ class SerializerNode {
if (HasChildren()) {
for (unsigned int j = 0; j < NumChildren(); ++j) {
- repr += GetChild(j).ToString(trimWhitespaces, indentSize, indent + 1);
+ repr += PTR_ATTRIB(GetChild(j), ToString(trimWhitespaces, indentSize, indent + 1));
}
}
diff --git a/SerializerNodeIterator.mqh b/SerializerNodeIterator.mqh
index 58ac9fca4..3a1f0f00f 100644
--- a/SerializerNodeIterator.mqh
+++ b/SerializerNodeIterator.mqh
@@ -24,6 +24,8 @@
#ifndef JSON_ITERATOR_MQH
#define JSON_ITERATOR_MQH
+#include "SerializerNode.mqh"
+
class SerializerNode;
class Serializer;
@@ -52,7 +54,8 @@ class SerializerNodeIterator {
/**
* Returns current node or NULL.
*/
- SerializerNode* Node() { return !IsValid() ? NULL : _collection.GetChild(_index); }
+ SerializerNode* Node() { return !IsValid() ? NULL : PTR_ATTRIB(_collection, GetChild(_index));
+ }
/**
* Returns current node index.
@@ -67,22 +70,26 @@ class SerializerNodeIterator {
/**
* Checks whether iterator is still valid.
*/
- bool IsValid() { return _index < _collection.NumChildren(); }
+ bool IsValid() { return _index < PTR_ATTRIB(_collection, NumChildren());
+ }
/**
* Returns current's child key or empty string.
*/
- const string Key() { return !IsValid() ? "" : _collection.GetChild(_index).Key(); }
+ const string Key() { return !IsValid() ? "" : PTR_ATTRIB(PTR_ATTRIB(_collection, GetChild(_index)), Key());
+ }
/**
* Checks whether current child has key.
*/
- bool HasKey() { return !IsValid() ? false : _collection.GetChild(_index).HasKey(); }
+ bool HasKey() { return !IsValid() ? false : PTR_ATTRIB(PTR_ATTRIB(_collection, GetChild(_index)), HasKey());
+ }
/**
* Checks whether current child is a container.
*/
- bool IsContainer() { return !IsValid() ? false : _collection.GetChild(_index).IsContainer(); }
+ bool IsContainer() { return !IsValid() ? false : PTR_ATTRIB(PTR_ATTRIB(_collection, GetChild(_index)), IsContainer());
+ }
};
template
diff --git a/SerializerNodeParam.mqh b/SerializerNodeParam.mqh
index 1321e01ec..0ef237931 100644
--- a/SerializerNodeParam.mqh
+++ b/SerializerNodeParam.mqh
@@ -21,6 +21,7 @@
*/
// Prevents processing this includes file for the second time.
+#include "SerializerConversions.h"
#ifndef JSON_PARAM_MQH
#define JSON_PARAM_MQH
@@ -69,42 +70,22 @@ class SerializerNodeParam {
/**
* Returns new SerializerNodeParam object from given source value.
*/
- static SerializerNodeParam* FromBool(long value) {
- SerializerNodeParam* param = new SerializerNodeParam();
- param._type = SerializerNodeParamBool;
- param._integral._bool = value;
- return param;
- }
+ static SerializerNodeParam* FromBool(long value);
/**
* Returns new SerializerNodeParam object from given source value.
*/
- static SerializerNodeParam* FromLong(long value) {
- SerializerNodeParam* param = new SerializerNodeParam();
- param._type = SerializerNodeParamLong;
- param._integral._long = value;
- return param;
- }
+ static SerializerNodeParam* FromLong(long value);
/**
* Returns new SerializerNodeParam object from given source value.
*/
- static SerializerNodeParam* FromDouble(double value) {
- SerializerNodeParam* param = new SerializerNodeParam();
- param._type = SerializerNodeParamDouble;
- param._integral._double = value;
- return param;
- }
+ static SerializerNodeParam* FromDouble(double value);
/**
* Returns new SerializerNodeParam object from given source value.
*/
- static SerializerNodeParam* FromString(string& value) {
- SerializerNodeParam* param = new SerializerNodeParam();
- param._type = SerializerNodeParamString;
- param._string = value;
- return param;
- }
+ static SerializerNodeParam* FromString(string& value);
/**
* Returns new SerializerNodeParam object from given source value.
@@ -178,13 +159,14 @@ class SerializerNodeParam {
int _fp_precision = 8) {
switch (_type) {
case SerializerNodeParamBool:
- return Serializer::ValueToString(_integral._bool, includeQuotes, escapeString, _fp_precision);
+ return SerializerConversions::ValueToString(_integral._bool, includeQuotes, escapeString, _fp_precision);
case SerializerNodeParamLong:
- return Serializer::ValueToString(_integral._long, includeQuotes, escapeString, _fp_precision);
+ return SerializerConversions::ValueToString(_integral._long, includeQuotes, escapeString, _fp_precision);
case SerializerNodeParamDouble:
- return Serializer::ValueToString(_integral._double, includeQuotes, escapeString, _fp_precision);
+ return SerializerConversions::ValueToString(_integral._double, includeQuotes, escapeString, _fp_precision);
case SerializerNodeParamString:
- return Serializer::ValueToString(_string, includeQuotes || forceQuotesOnString, escapeString, _fp_precision);
+ return SerializerConversions::ValueToString(_string, includeQuotes || forceQuotesOnString, escapeString,
+ _fp_precision);
}
#ifdef __debug__
@@ -311,4 +293,46 @@ class SerializerNodeParam {
string ConvertTo(string) { return ToString(); }
};
+/**
+ * Returns new SerializerNodeParam object from given source value.
+ */
+SerializerNodeParam* SerializerNodeParam::FromBool(long value) {
+ SerializerNodeParam* param = new SerializerNodeParam();
+ PTR_ATTRIB(param, _type) = SerializerNodeParamBool;
+ PTR_ATTRIB(param, _integral)._bool = value;
+ return param;
+}
+
+/**
+ * Returns new SerializerNodeParam object from given source value.
+ */
+SerializerNodeParam* SerializerNodeParam::FromLong(long value) {
+ SerializerNodeParam* param = new SerializerNodeParam();
+ PTR_ATTRIB(param, _type) = SerializerNodeParamLong;
+ PTR_ATTRIB(param, _integral)._long = value;
+ return param;
+}
+
+/**
+ * Returns new SerializerNodeParam object from given source value.
+ */
+SerializerNodeParam* SerializerNodeParam::FromDouble(double value) {
+ SerializerNodeParam* param = new SerializerNodeParam();
+ PTR_ATTRIB(param, _type) = SerializerNodeParamDouble;
+ PTR_ATTRIB(param, _integral)._double = value;
+ return param;
+}
+
+/**
+ * Returns new SerializerNodeParam object from given source value.
+ */
+SerializerNodeParam* SerializerNodeParam::FromString(string& value) {
+ SerializerNodeParam* param = new SerializerNodeParam();
+ PTR_ATTRIB(param, _type) = SerializerNodeParamString;
+ PTR_ATTRIB(param, _string) = value;
+ return param;
+}
+
+
+
#endif
diff --git a/SymbolInfo.enum.h b/SymbolInfo.enum.h
index 9e7cb7741..59a3ffdfc 100644
--- a/SymbolInfo.enum.h
+++ b/SymbolInfo.enum.h
@@ -30,31 +30,6 @@
#pragma once
#endif
-// Enum constants.
-const ENUM_SYMBOL_INFO_DOUBLE market_dcache[] = {SYMBOL_MARGIN_INITIAL,
- SYMBOL_MARGIN_LIMIT,
- SYMBOL_MARGIN_LONG,
- SYMBOL_MARGIN_MAINTENANCE,
- SYMBOL_MARGIN_SHORT,
- SYMBOL_MARGIN_STOP,
- SYMBOL_MARGIN_STOPLIMIT,
- SYMBOL_POINT,
- SYMBOL_SWAP_LONG,
- SYMBOL_SWAP_SHORT,
- SYMBOL_TRADE_CONTRACT_SIZE,
- SYMBOL_TRADE_TICK_SIZE,
- SYMBOL_TRADE_TICK_VALUE,
- SYMBOL_TRADE_TICK_VALUE_LOSS,
- SYMBOL_TRADE_TICK_VALUE_PROFIT,
- SYMBOL_VOLUME_LIMIT,
- SYMBOL_VOLUME_MAX,
- SYMBOL_VOLUME_MIN,
- SYMBOL_VOLUME_STEP};
-const ENUM_SYMBOL_INFO_INTEGER market_icache[] = {
- SYMBOL_DIGITS, SYMBOL_EXPIRATION_MODE, SYMBOL_FILLING_MODE,
- SYMBOL_ORDER_MODE, SYMBOL_SWAP_MODE, SYMBOL_SWAP_ROLLOVER3DAYS,
- SYMBOL_TRADE_CALC_MODE, SYMBOL_TRADE_EXEMODE, SYMBOL_TRADE_MODE};
-
#ifndef __MQL5__
// Methods of swap calculation at position transfer.
// @see: https://www.mql5.com/en/docs/constants/environment_state/marketinfoconstants#enum_symbol_swap_mode
@@ -279,24 +254,6 @@ enum ENUM_SYMBOL_TRADE_EXECUTION {
SYMBOL_TRADE_EXECUTION_EXCHANGE, // Exchange execution.
};
-/**
- * Enumeration for the swap calculation modes.
- *
- * @docs
- * https://www.mql5.com/en/docs/constants/environment_state/marketinfoconstants
- */
-enum ENUM_SYMBOL_SWAP_MODE {
- SYMBOL_SWAP_MODE_DISABLED, // Swaps disabled (no swaps).
- SYMBOL_SWAP_MODE_POINTS, // Swaps are charged in points.
- SYMBOL_SWAP_MODE_CURRENCY_SYMBOL, // Swaps are charged in money in base currency of the symbol.
- SYMBOL_SWAP_MODE_CURRENCY_MARGIN, // Swaps are charged in money in margin currency of the symbol.
- SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT, // Swaps are charged in money, in client deposit currency.
- SYMBOL_SWAP_MODE_INTEREST_CURRENT, // Swaps are charged as the specified annual interest.
- SYMBOL_SWAP_MODE_INTEREST_OPEN, // Swaps are charged as the specified annual interest from the open price.
- SYMBOL_SWAP_MODE_REOPEN_CURRENT, // Swaps are charged by reopening positions.
- SYMBOL_SWAP_MODE_REOPEN_BID, // Swaps are charged by reopening positions.
-};
-
/**
* Enumeration for the option right modes.
*
@@ -514,3 +471,30 @@ enum ENUM_SYMBOL_INDUSTRY {
INDUSTRY_UTILITIES_LAST, // End of the utilities services types enumeration.
};
#endif
+
+// Enum constants.
+const ENUM_SYMBOL_INFO_INTEGER market_icache[] = {
+ SYMBOL_DIGITS, SYMBOL_EXPIRATION_MODE, SYMBOL_FILLING_MODE,
+ SYMBOL_ORDER_MODE, SYMBOL_SWAP_MODE, SYMBOL_SWAP_ROLLOVER3DAYS,
+ SYMBOL_TRADE_CALC_MODE, SYMBOL_TRADE_EXEMODE, SYMBOL_TRADE_MODE};
+
+// Enum constants.
+const ENUM_SYMBOL_INFO_DOUBLE market_dcache[] = {SYMBOL_MARGIN_INITIAL,
+ SYMBOL_MARGIN_LIMIT,
+ SYMBOL_MARGIN_LONG,
+ SYMBOL_MARGIN_MAINTENANCE,
+ SYMBOL_MARGIN_SHORT,
+ SYMBOL_MARGIN_STOP,
+ SYMBOL_MARGIN_STOPLIMIT,
+ SYMBOL_POINT,
+ SYMBOL_SWAP_LONG,
+ SYMBOL_SWAP_SHORT,
+ SYMBOL_TRADE_CONTRACT_SIZE,
+ SYMBOL_TRADE_TICK_SIZE,
+ SYMBOL_TRADE_TICK_VALUE,
+ SYMBOL_TRADE_TICK_VALUE_LOSS,
+ SYMBOL_TRADE_TICK_VALUE_PROFIT,
+ SYMBOL_VOLUME_LIMIT,
+ SYMBOL_VOLUME_MAX,
+ SYMBOL_VOLUME_MIN,
+ SYMBOL_VOLUME_STEP};
diff --git a/SymbolInfo.mqh b/SymbolInfo.mqh
index 41d10751f..0e3affbe5 100644
--- a/SymbolInfo.mqh
+++ b/SymbolInfo.mqh
@@ -48,7 +48,7 @@ class SymbolInfo : public Object {
string symbol; // Current symbol pair.
MqlTick last_tick; // Stores the latest prices of the symbol.
Ref logger;
- MqlTick tick_data[]; // Stores saved ticks.
+ ARRAY(MqlTick, tick_data); // Stores saved ticks.
SymbolInfoEntry s_entry; // Symbol entry.
SymbolInfoProp sprops; // Symbol properties.
double pip_size; // Value of pip size.
@@ -62,7 +62,7 @@ class SymbolInfo : public Object {
*/
SymbolInfo(string _symbol = NULL, Log *_logger = NULL)
: logger(_logger != NULL ? _logger : new Log),
- symbol(_symbol == NULL ? _Symbol : _symbol),
+ symbol(_symbol == "" ? _Symbol : _symbol),
pip_size(GetPipSize()),
symbol_digits(GetDigits()) {
Select();
@@ -111,10 +111,10 @@ class SymbolInfo : public Object {
return _last_tick;
}
MqlTick GetTick() {
- if (!SymbolInfoTick(this.symbol, this.last_tick)) {
- Logger().Error("Cannot return current prices!", __FUNCTION__);
+ if (!SymbolInfoTick(symbol, last_tick)) {
+ GetLogger().Error("Cannot return current prices!", __FUNCTION__);
}
- return this.last_tick;
+ return last_tick;
}
/**
@@ -193,7 +193,7 @@ class SymbolInfo : public Object {
static double GetSessionVolume(string _symbol) {
return SymbolInfo::SymbolInfoDouble(_symbol, SYMBOL_SESSION_VOLUME);
}
- double GetSessionVolume() { return this.GetSessionVolume(this.symbol); }
+ double GetSessionVolume() { return SymbolInfo::GetSessionVolume(symbol); }
/**
* Time of the last quote
@@ -203,7 +203,7 @@ class SymbolInfo : public Object {
* - https://www.mql5.com/en/docs/constants/environment_state/marketinfoconstants#enum_symbol_info_double
*/
static datetime GetQuoteTime(string _symbol) { return (datetime)SymbolInfo::SymbolInfoInteger(_symbol, SYMBOL_TIME); }
- datetime GetQuoteTime() { return GetQuoteTime(this.symbol); }
+ datetime GetQuoteTime() { return GetQuoteTime(symbol); }
/**
* Get current open price depending on the operation type.
@@ -610,27 +610,27 @@ class SymbolInfo : public Object {
*/
bool SaveTick(MqlTick &_tick) {
static int _index = 0;
- if (_index++ >= ArraySize(this.tick_data) - 1) {
- if (ArrayResize(this.tick_data, _index + 100, 1000) < 0) {
- Logger().Error(StringFormat("Cannot resize array (size: %d)!", _index), __FUNCTION__);
+ if (_index++ >= ArraySize(tick_data) - 1) {
+ if (ArrayResize(tick_data, _index + 100, 1000) < 0) {
+ GetLogger().Error(StringFormat("Cannot resize array (size: %d)!", _index), __FUNCTION__);
return false;
}
}
- this.tick_data[_index] = this.GetTick();
+ tick_data[_index] = GetTick();
return true;
}
/**
* Empties the tick array.
*/
- bool ResetTicks() { return ArrayResize(this.tick_data, 0, 100) != -1; }
+ bool ResetTicks() { return ArrayResize(tick_data, 0, 100) != -1; }
/* Setters */
/**
* Overrides the last tick.
*/
- void SetTick(MqlTick &_tick) { this.last_tick = _tick; }
+ void SetTick(MqlTick &_tick) { last_tick = _tick; }
/**
* Returns the value of a corresponding property of the symbol.
@@ -676,12 +676,7 @@ class SymbolInfo : public Object {
*
*/
static long SymbolInfoInteger(string name, ENUM_SYMBOL_INFO_INTEGER prop_id) {
-#ifdef __MQLBUILD__
return ::SymbolInfoInteger(name, prop_id);
-#else
- printf("@fixme: %s\n", "SymbolInfo::SymbolInfoInteger()");
- return 0;
-#endif
}
/**
@@ -717,7 +712,7 @@ class SymbolInfo : public Object {
*/
string ToString() {
return StringFormat(
- "Symbol: %s, Last Ask/Bid: %g/%g, Last Price/Session Volume: %d/%g, Point size: %g, Pip size: %g, " +
+ string("Symbol: %s, Last Ask/Bid: %g/%g, Last Price/Session Volume: %d/%g, Point size: %g, Pip size: %g, ") +
"Tick size: %g (%g pts), Tick value: %g (%g/%g), " + "Digits: %d, Spread: %d pts, Trade stops level: %d, " +
"Trade contract size: %g, Min lot: %g, Max lot: %g, Lot step: %g, " +
"Freeze level: %d, Swap (long/short/mode): %g/%g/%d, Margin initial (maintenance): %g (%g)",
@@ -732,14 +727,14 @@ class SymbolInfo : public Object {
*/
string ToCSV(bool _header = false) {
return !_header
- ? StringFormat(
- "%s,%g,%g,%d,%g,%g,%g," + "%g,%g,%g,%g,%g," + "%d,%d,%d," + "%g,%g,%g,%g," + "%d,%g,%g,%d,%g,%g",
- GetSymbol(), GetLastAsk(), GetLastBid(), GetLastVolume(), GetSessionVolume(), GetPointSize(),
- GetPipSize(), GetTickSize(), GetTradeTickSize(), GetTickValue(), GetTickValueProfit(),
- GetTickValueLoss(), GetDigits(), GetSpread(), GetTradeStopsLevel(), GetTradeContractSize(),
- GetVolumeMin(), GetVolumeMax(), GetVolumeStep(), GetFreezeLevel(), GetSwapLong(), GetSwapShort(),
- GetSwapMode(), GetMarginInit(), GetMarginMaintenance())
- : "Symbol,Last Ask,Last Bid,Last Volume,Session Volume,Point Size,Pip Size," +
+ ? StringFormat(string("%s,%g,%g,%d,%g,%g,%g,") + "%g,%g,%g,%g,%g," + "%d,%d,%d," + "%g,%g,%g,%g," +
+ "%d,%g,%g,%d,%g,%g",
+ GetSymbol(), GetLastAsk(), GetLastBid(), GetLastVolume(), GetSessionVolume(),
+ GetPointSize(), GetPipSize(), GetTickSize(), GetTradeTickSize(), GetTickValue(),
+ GetTickValueProfit(), GetTickValueLoss(), GetDigits(), GetSpread(), GetTradeStopsLevel(),
+ GetTradeContractSize(), GetVolumeMin(), GetVolumeMax(), GetVolumeStep(), GetFreezeLevel(),
+ GetSwapLong(), GetSwapShort(), GetSwapMode(), GetMarginInit(), GetMarginMaintenance())
+ : string("Symbol,Last Ask,Last Bid,Last Volume,Session Volume,Point Size,Pip Size,") +
"Tick Size,Tick Size (pts),Tick Value,Tick Value Profit,Tick Value Loss," +
"Digits,Spread (pts),Trade Stops," + "Trade Contract Size,Min Lot,Max Lot,Lot Step," +
"Freeze level, Swap Long, Swap Short, Swap Mode, Margin Init";
@@ -761,6 +756,6 @@ class SymbolInfo : public Object {
/**
* Returns Log handler.
*/
- Log *Logger() { return logger.Ptr(); }
+ Log& GetLogger() { return PTR_ATTRIB(logger, Ptr()); }
};
#endif // SYMBOLINFO_MQH
diff --git a/SymbolInfo.struct.h b/SymbolInfo.struct.h
index 2733169c6..471c0b398 100644
--- a/SymbolInfo.struct.h
+++ b/SymbolInfo.struct.h
@@ -31,10 +31,34 @@
#endif
// Includes.
-#include "SerializerNode.mqh"
+#include "ISerializable.h"
+#include "Serializer.mqh"
+#include "Chart.define.h"
+
+#ifndef __MQL__
+/**
+ * Structure for storing the latest prices of the symbol.
+ * @docs
+ * https://www.mql5.com/en/docs/constants/structures/mqltick
+ */
+struct MqlTick {
+ datetime time; // Time of the last prices update.
+ double ask; // Current Ask price.
+ double bid; // Current Bid price.
+ double last; // Price of the last deal (last).
+ double volume_real; // Volume for the current last price with greater accuracy.
+ long time_msc; // Time of a price last update in milliseconds.
+ unsigned int flags; // Tick flags.
+ unsigned long volume; // Volume for the current last price.
+};
+#endif
// Defines struct to store symbol data.
-struct SymbolInfoEntry {
+struct SymbolInfoEntry
+#ifndef __MQL__
+ : public ISerializable
+#endif
+{
double bid; // Current Bid price.
double ask; // Current Ask price.
double last; // Price of the last deal.
@@ -42,12 +66,12 @@ struct SymbolInfoEntry {
unsigned long volume; // Volume for the current last price.
// Constructor.
SymbolInfoEntry() : bid(0), ask(0), last(0), spread(0), volume(0) {}
- SymbolInfoEntry(const MqlTick& _tick, const string _symbol = NULL) {
+ SymbolInfoEntry(const MqlTick& _tick, const string _symbol = "") {
bid = _tick.bid;
ask = _tick.ask;
last = _tick.last;
volume = _tick.volume;
- spread = SymbolInfo::GetRealSpread(bid, ask, SymbolInfo::GetDigits(_symbol));
+ spread = (unsigned int)round((ask - bid) * pow(10, ::SymbolInfoInteger(_symbol, SYMBOL_DIGITS)));
}
// Getters
string ToCSV() { return StringFormat("%g,%g,%g,%g,%d", bid, ask, last, spread, volume); }
@@ -57,11 +81,11 @@ struct SymbolInfoEntry {
#endif
void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {}
SerializerNodeType Serialize(Serializer& _s) {
- _s.Pass(this, "ask", ask);
- _s.Pass(this, "bid", bid);
- _s.Pass(this, "last", last);
- _s.Pass(this, "spread", spread);
- _s.Pass(this, "volume", volume);
+ _s.Pass(THIS_REF, "ask", ask);
+ _s.Pass(THIS_REF, "bid", bid);
+ _s.Pass(THIS_REF, "last", last);
+ _s.Pass(THIS_REF, "spread", spread);
+ _s.Pass(THIS_REF, "volume", volume);
return SerializerNodeObject;
}
};
@@ -75,28 +99,10 @@ struct SymbolInfoProp {
// Serializers.
void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {}
SerializerNodeType Serialize(Serializer& _s) {
- _s.Pass(this, "pip_value", pip_value);
- _s.Pass(this, "pip_digits", pip_digits);
- _s.Pass(this, "pts_per_pip", pts_per_pip);
- _s.Pass(this, "vol_digits", vol_digits);
+ _s.Pass(THIS_REF, "pip_value", pip_value);
+ _s.Pass(THIS_REF, "pip_digits", pip_digits);
+ _s.Pass(THIS_REF, "pts_per_pip", pts_per_pip);
+ _s.Pass(THIS_REF, "vol_digits", vol_digits);
return SerializerNodeObject;
}
};
-
-#ifndef __MQL__
-/**
- * Structure for storing the latest prices of the symbol.
- * @docs
- * https://www.mql5.com/en/docs/constants/structures/mqltick
- */
-struct MqlTick {
- datetime time; // Time of the last prices update.
- double ask; // Current Ask price.
- double bid; // Current Bid price.
- double last; // Price of the last deal (last).
- double volume_real; // Volume for the current last price with greater accuracy.
- long time_msc; // Time of a price last update in milliseconds.
- unsigned int flags; // Tick flags.
- unsigned long volume; // Volume for the current last price.
-};
-#endif
diff --git a/Terminal.enum.h b/Terminal.enum.h
index 171e7063e..c1f2dbe83 100644
--- a/Terminal.enum.h
+++ b/Terminal.enum.h
@@ -179,4 +179,23 @@ enum ENUM_TERMINAL_INFO_STRING {
TERMINAL_NAME, // Terminal name (string).
TERMINAL_PATH, // Folder from which the terminal is started (string).
};
+
+/**
+ * Uninitialization reason codes are returned by the UninitializeReason() function.
+ *
+ * @docs
+ * - https://www.mql5.com/en/docs/constants/namedconstants/uninit
+ */
+enum ENUM_UNINIT_REASON {
+ REASON_PROGRAM = 0,
+ REASON_REMOVE = 1,
+ REASON_RECOMPILE = 2,
+ REASON_CHARTCHANGE = 3,
+ REASON_CHARTCLOSE = 4,
+ REASON_PARAMETERS = 5,
+ REASON_ACCOUNT = 6,
+ REASON_TEMPLATE = 7,
+ REASON_INITFAILED = 8,
+ REASON_CLOSE = 9,
+};
#endif
diff --git a/Terminal.mqh b/Terminal.mqh
index 86f2a52cf..8f04c7fee 100644
--- a/Terminal.mqh
+++ b/Terminal.mqh
@@ -30,7 +30,6 @@
*/
// Forward declaration.
-class Log;
class Terminal;
// Prevents processing this includes file for the second time.
@@ -38,8 +37,8 @@ class Terminal;
#define TERMINAL_MQH
// Includes.
-#include "DateTime.mqh"
-#include "Log.mqh"
+#include "Convert.mqh"
+#include "Data.struct.h"
#include "Object.mqh"
#include "Refs.mqh"
#include "String.mqh"
@@ -47,12 +46,6 @@ class Terminal;
#include "Terminal.enum.h"
#include "Terminal.struct.h"
-// Defines macros (for MQL4 backward compatibility).
-#ifndef __MQL4__
-// @docs: https://docs.mql4.com/chart_operations/windowexpertname
-string WindowExpertName(void) { return Terminal::WindowExpertName(); }
-#endif
-
#ifdef __MQL5__
// Provide backward compatibility for MQL4 in MQL5.
//#include "MQL4.mqh"
@@ -65,16 +58,11 @@ string WindowExpertName(void) { return Terminal::WindowExpertName(); }
* Class to provide functions that return parameters of the current terminal.
*/
class Terminal : public Object {
- public:
- // Class variables.
- Ref logger;
-
- protected:
public:
/**
* Class constructor.
*/
- Terminal(Log *_logger = NULL) : logger(_logger != NULL ? _logger : new Log) {}
+ Terminal() {}
/**
* Class deconstructor.
@@ -760,17 +748,6 @@ class Terminal : public Object {
*/
static string GetLastErrorText() { return GetErrorText(GetLastError()); }
- /**
- * Check for the last error and and log it.
- */
- void CheckLastError() {
- if (GetLastError() > 0) {
- int _err = GetLastError();
- Logger().Error(GetErrorText(_err), StringFormat("%d", _err));
- }
- ResetLastError();
- }
-
/**
* Get text description based on the uninitialization reason code.
*/
@@ -781,10 +758,10 @@ class Terminal : public Object {
text = "EA terminated its operation by calling the ExpertRemove() function.";
break;
case REASON_REMOVE: // 1 (implemented for the indicators only)
- text = "Program " + __FILE__ + " has been deleted from the chart.";
+ text = string("Program ") + __FILE__ + " has been deleted from the chart.";
break;
case REASON_RECOMPILE: // 2 (implemented for the indicators)
- text = "Program " + __FILE__ + " has been recompiled.";
+ text = string("Program ") + __FILE__ + " has been recompiled.";
break;
case REASON_CHARTCHANGE: // 3
text = "Symbol or chart period has been changed.";
@@ -897,14 +874,14 @@ class Terminal : public Object {
* @return
* Returns true when the condition is met.
*/
- bool CheckCondition(ENUM_TERMINAL_CONDITION _cond, DataParamEntry REF(_args)[]) {
+ bool CheckCondition(ENUM_TERMINAL_CONDITION _cond, ARRAY_REF(DataParamEntry, _args)) {
long _arg1l = ArraySize(_args) > 0 ? Convert::MqlParamToInteger(_args[0]) : WRONG_VALUE;
long _arg2l = ArraySize(_args) > 1 ? Convert::MqlParamToInteger(_args[1]) : WRONG_VALUE;
switch (_cond) {
case TERMINAL_COND_IS_CONNECTED:
return !IsConnected();
default:
- Logger().Error(StringFormat("Invalid terminal condition: %s!", EnumToString(_cond), __FUNCTION__));
+ Print(StringFormat("Invalid terminal condition: %s!", EnumToString(_cond), __FUNCTION__));
return false;
}
}
@@ -953,20 +930,20 @@ class Terminal : public Object {
* Returns textual representation of the Terminal class.
*/
string ToString(string _sep = "; ") {
- return StringFormat("Allow DLL: %s", (string)IsDllsAllowed()) + _sep +
- StringFormat("Allow Libraries: %s", (string)IsLibrariesAllowed()) + _sep +
+ return StringFormat("Allow DLL: %s", IsDllsAllowed() ? "Yes" : "No") + _sep +
+ StringFormat("Allow Libraries: %s", IsLibrariesAllowed() ? "Yes" : "No") + _sep +
StringFormat("CPUs: %d", GetCpuCores()) + _sep +
// StringFormat("Community account: %s", (string)HasCommunityAccount()) + _sep +
// StringFormat("Community balance: %.2f", GetCommunityBalance()) + _sep +
// StringFormat("Community connection: %s", (string)IsCommunityConnected()) + _sep +
StringFormat("Disk space: %d", GetDiskSpace()) + _sep +
- StringFormat("Enabled FTP: %s", (string)IsFtpEnabled()) + _sep +
- StringFormat("Enabled e-mail: %s", (string)IsEmailEnabled()) + _sep +
+ StringFormat("Enabled FTP: %s", IsFtpEnabled() ? "Yes" : "No") + _sep +
+ StringFormat("Enabled e-mail: %s", IsEmailEnabled() ? "Yes" : "No") + _sep +
// StringFormat("Enabled notifications: %s", (string)IsNotificationsEnabled()) + _sep +
- StringFormat("IsOptimization: %s", (string)IsOptimization()) + _sep +
- StringFormat("IsRealtime: %s", (string)IsRealtime()) + _sep +
- StringFormat("IsTesting: %s", (string)IsTesting()) + _sep +
- StringFormat("IsVisual: %s", (string)IsVisualMode()) + _sep +
+ StringFormat("IsOptimization: %s", IsOptimization() ? "Yes" : "No") + _sep +
+ StringFormat("IsRealtime: %s", IsRealtime() ? "Yes" : "No") + _sep +
+ StringFormat("IsTesting: %s", IsTesting() ? "Yes" : "No") + _sep +
+ StringFormat("IsVisual: %s", IsVisualMode() ? "Yes" : "No") + _sep +
// StringFormat("MQ ID: %s", (string)HasMetaQuotesId()) + _sep +
StringFormat("Memory (free): %d", GetFreeMemory()) + _sep +
StringFormat("Memory (physical): %d", GetPhysicalMemory()) + _sep +
@@ -977,33 +954,22 @@ class Terminal : public Object {
StringFormat("Path (Terminal): %s", GetTerminalPath()) + _sep +
StringFormat("Program name: %s", WindowExpertName()) + _sep +
StringFormat("Screen DPI: %d", GetScreenDpi()) + _sep + StringFormat("Terminal build: %d", GetBuild()) +
- _sep + StringFormat("Terminal code page: %d", (string)GetCodePage()) + _sep +
+ _sep + StringFormat("Terminal code page: %d", IntegerToString(GetCodePage()) + _sep +
StringFormat("Terminal company: %s", GetCompany()) + _sep +
- StringFormat("Terminal connected: %s", (string)IsConnected()) + _sep +
+ StringFormat("Terminal connected: %s", IsConnected() ? "Yes" : "No") + _sep +
StringFormat("Terminal language: %s", GetLanguage()) + _sep + StringFormat("Terminal name: %s", GetName()) +
_sep + StringFormat("Termnal max bars: %d", GetMaxBars()) + _sep +
- StringFormat("Trade allowed: %s", (string)IsTradeAllowed()) + _sep +
- StringFormat("Trade context busy: %s", (string)IsTradeContextBusy()) + _sep +
- StringFormat("Trade perm: %s", (string)CheckPermissionToTrade()) + _sep +
+ StringFormat("Trade allowed: %s", IsTradeAllowed() ? "Yes" : "No") + _sep +
+ StringFormat("Trade context busy: %s", IsTradeContextBusy() ? "Yes" : "No") + _sep +
+ StringFormat("Trade perm: %s", CheckPermissionToTrade() ? "Yes" : "No") + _sep +
StringFormat("Trade ping (last): %d", GetPingLast());
}
+};
- /**
- * Returns Terminal handler.
- */
- Terminal *TerminalHandler() {
-#ifdef __MQLBUILD__
- return GetPointer(this);
-#else
- return (Terminal *)this;
+// Defines macros (for MQL4 backward compatibility).
+#ifndef __MQL4__
+// @docs: https://docs.mql4.com/chart_operations/windowexpertname
+string WindowExpertName(void) { return Terminal::WindowExpertName(); }
#endif
- }
-
- /* Class handlers */
- /**
- * Returns Log handler.
- */
- Log *Logger() { return logger.Ptr(); }
-};
#endif // TERMINAL_MQH
diff --git a/Terminal.struct.h b/Terminal.struct.h
index 798a56801..cb4e58da7 100644
--- a/Terminal.struct.h
+++ b/Terminal.struct.h
@@ -29,17 +29,3 @@
// Allows the preprocessor to include a header file when it is needed.
#pragma once
#endif
-
-#ifndef __MQL__
-/**
- * Enumeration for the return codes.
- * @docs
- * https://www.mql5.com/en/docs/basis/function/events
- */
-enum ENUM_INIT_RETCODE {
- INIT_SUCCEEDED = 0, // Successful initialization.
- INIT_FAILED = 1, // Initialization failed.
- INIT_PARAMETERS_INCORRECT, // Incorrect set of input parameters.
- INIT_AGENT_NOT_SUITABLE, // The agent is not suitable for testing.
-};
-#endif