From e00601c1f70657488ec0f18d944c3a909759c979 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 2 Jun 2021 18:42:00 +0200 Subject: [PATCH] WIP. Refactoring of MQL code to be compatible with C++. --- Bar.struct.h | 9 +- Chart.struct.h | 38 +++--- Chart.struct.tf.h | 2 + Data.struct.h | 55 ++++++++- DateTime.mqh | 2 +- DateTime.struct.h | 235 +++++++++++++++++++------------------ File.mqh | 3 +- ISerializable.h | 39 ++++++ Indicator.struct.h | 20 +--- Log.mqh | 32 +++-- Refs.mqh | 24 ++-- Serializer.mqh | 171 ++++----------------------- SerializerConversions.h | 169 ++++++++++++++++++++++++++ SerializerConverter.mqh | 6 +- SerializerDict.mqh | 6 - SerializerNode.mqh | 44 +++---- SerializerNodeIterator.mqh | 17 ++- SerializerNodeParam.mqh | 80 ++++++++----- SymbolInfo.enum.h | 70 +++++------ SymbolInfo.mqh | 51 ++++---- SymbolInfo.struct.h | 68 ++++++----- Terminal.enum.h | 19 +++ Terminal.mqh | 84 ++++--------- Terminal.struct.h | 14 --- 24 files changed, 695 insertions(+), 563 deletions(-) create mode 100644 ISerializable.h create mode 100644 SerializerConversions.h 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