diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 33d83342a..87fd10d78 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -1,3 +1,7 @@ --- +# MD013 line-length - Line length MD013: line_length: 120 +# MD033 no-inline-html - Inline HTML +MD033: + allowed_elements: [details] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50a765f76..b73b0ad64 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.1.0 + rev: v4.0.1 hooks: - id: check-added-large-files - id: check-byte-order-marker @@ -14,12 +14,12 @@ repos: - id: trailing-whitespace - repo: https://github.com/igorshubovych/markdownlint-cli.git - rev: v0.23.1 + rev: v0.29.0 hooks: - id: markdownlint - repo: https://github.com/adrienverge/yamllint.git - rev: v1.23.0 + rev: v1.26.3 hooks: - id: yamllint args: ["-c", ".yamllint", "-s"] diff --git a/Bar.enum.h b/Bar.enum.h index e4c834f7e..ac73beba5 100644 --- a/Bar.enum.h +++ b/Bar.enum.h @@ -32,10 +32,10 @@ /* Pivot Point calculation method. */ enum ENUM_PP_TYPE { - PP_CAMARILLA = 1, // A set of eight levels which resemble support and resistance values + PP_CAMARILLA = 1, // Camarilla: A set of eight levels which resemble support and resistance values PP_CLASSIC = 2, // Classic pivot point PP_FIBONACCI = 3, // Fibonacci pivot point - PP_FLOOR = 4, // Most basic and popular type of pivots used in Forex trading technical analysis + PP_FLOOR = 4, // Floor: Most basic and popular type of pivots used in Forex trading technical analysis PP_TOM_DEMARK = 5, // Tom DeMark's pivot point (predicted lows and highs of the period) PP_WOODIE = 6, // Woodie's pivot point are giving more weight to the Close price of the previous period }; diff --git a/Chart.struct.static.h b/Chart.struct.static.h index d99b1e523..0c728bcc4 100644 --- a/Chart.struct.static.h +++ b/Chart.struct.static.h @@ -80,7 +80,7 @@ struct ChartStatic { #else // __MQL5__ ARRAY(double, _arr); ArraySetAsSeries(_arr, true); - return (_shift >= 0 && CopyClose(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : -1; + return (_shift >= 0 && CopyClose(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : 0; #endif } @@ -95,7 +95,7 @@ struct ChartStatic { #else // __MQL5__ ARRAY(double, _arr); ArraySetAsSeries(_arr, true); - return (_shift >= 0 && CopyHigh(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : -1; + return (_shift >= 0 && CopyHigh(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : 0; #endif } @@ -152,7 +152,7 @@ struct ChartStatic { #else // __MQL5__ ARRAY(double, _arr); ArraySetAsSeries(_arr, true); - return (_shift >= 0 && CopyLow(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : -1; + return (_shift >= 0 && CopyLow(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : 0; #endif } @@ -209,7 +209,7 @@ struct ChartStatic { #else // __MQL5__ ARRAY(double, _arr); ArraySetAsSeries(_arr, true); - return (_shift >= 0 && CopyOpen(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : -1; + return (_shift >= 0 && CopyOpen(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : 0; #endif } @@ -268,7 +268,7 @@ struct ChartStatic { ARRAY(datetime, _arr); // ENUM_TIMEFRAMES _tf = MQL4::TFMigrate(_tf); // @todo: Improves performance by caching values. - return (_shift >= 0 && ::CopyTime(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : -1; + return (_shift >= 0 && ::CopyTime(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : 0; #endif } @@ -289,7 +289,7 @@ struct ChartStatic { #else // __MQL5__ ARRAY(long, _arr); ArraySetAsSeries(_arr, true); - return (_shift >= 0 && CopyTickVolume(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : -1; + return (_shift >= 0 && CopyTickVolume(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : 0; #endif } diff --git a/Convert.mqh b/Convert.mqh index 072f8b6b2..c2ce4c3e3 100644 --- a/Convert.mqh +++ b/Convert.mqh @@ -29,7 +29,7 @@ #include "Array.mqh" #include "Order.enum.h" #include "SymbolInfo.enum.h" -#include "SymbolInfo.static.h" +#include "SymbolInfo.struct.static.h" /** * Class to provide conversion methods. diff --git a/EA.mqh b/EA.mqh index 785c82b22..f499717d7 100644 --- a/EA.mqh +++ b/EA.mqh @@ -58,7 +58,6 @@ class EA { Account *account; DictStruct> strats; Log logger; - Ref market; Terminal terminal; // Data variables. @@ -79,8 +78,7 @@ class EA { /** * Class constructor. */ - EA(EAParams &_params) - : account(new Account), market(new Market(_params.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_SYMBOL)))) { + EA(EAParams &_params) : account(new Account) { eparams = _params; estate.Set(STRUCT_ENUM(EAState, EA_STATE_FLAG_ON_INIT), true); UpdateStateFlags(); @@ -94,9 +92,6 @@ class EA { Trade _trade(_tparams, _cparams); trade.Set(_Symbol, _trade); logger.Link(_trade.GetLogger()); - // trade.GetByKey(_Symbol).GetLogger().Error("Test"); - // logger.Flush(); - // Loads existing trades by magic number. } /** @@ -113,19 +108,16 @@ class EA { /* Getters */ /** - * Gets EA parameter value. + * Gets EA state flag value. */ - template - T Get(STRUCT_ENUM(EAParams, ENUM_EA_PARAM_PROP) _param) { - return eparams.Get(_param); - } + bool Get(STRUCT_ENUM(EAState, ENUM_EA_STATE_FLAGS) _prop) { return estate.Get(_prop); } /** - * Gets EA state flag value. + * Gets EA parameter value. */ template - T Get(STRUCT_ENUM(EAState, ENUM_EA_STATE_FLAGS) _prop) { - return estate.Get(_prop); + T Get(STRUCT_ENUM(EAParams, ENUM_EA_PARAM_PROP) _param) { + return eparams.Get(_param); } /** @@ -204,6 +196,11 @@ class EA { eparams.Set(_param, _value); } + /** + * Sets EA state flag value. + */ + void Set(STRUCT_ENUM(EAState, ENUM_EA_STATE_FLAGS) _prop, bool _value) { estate.Set(_prop, _value); } + /** * Sets an strategy parameter value for all strategies. */ @@ -226,31 +223,6 @@ class EA { } } - /** - * Sets an strategy parameter value for all strategies. - */ - /* @fixme - template - void Set(ENUM_TRADE_PARAM _param, T _value, ENUM_TIMEFRAMES _tf) { - for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { - Strategy *_strat = iter.Value().Ptr(); - _strat.Set(_param, _value); - } - } - */ - - /** - * Sets an strategy parameter value for the given timeframe. - */ - /* @fixme - template - void Set(ENUM_TRADE_PARAM _param, T _value) { - for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { - Set(_param, _value); - } - } - */ - /* Processing methods */ /** @@ -292,6 +264,8 @@ class EA { _strat.OnOrderClose(ORDER_TYPE_SELL); } } + _trade_allowed &= _trade.IsTradeAllowed(); + _trade_allowed &= !_strat.IsSuspended(); if (_trade_allowed) { float _sig_open = _signal.GetSignalOpen(); unsigned int _sig_f = eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_SIGNAL_FILTER)); @@ -327,13 +301,13 @@ class EA { _signal.Set(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_FLAG_PROCESSED), true); } else { _last_error = GetLastError(); - switch (_last_error) { - case ERR_NOT_ENOUGH_MEMORY: - logger.Error(StringFormat("Not enough money to open trades! Code: %d", _last_error), __FUNCTION_LINE__, - _strat.GetName()); - logger.Warning(StringFormat("Suspending strategy.", _last_error), __FUNCTION_LINE__, _strat.GetName()); - _strat.Suspended(true); - break; + if (_last_error > 0) { + logger.Warning(StringFormat("Error: %d", _last_error), __FUNCTION_LINE__, _strat.GetName()); + ResetLastError(); + } + if (_trade.Get(TRADE_STATE_MONEY_NOT_ENOUGH)) { + logger.Warning(StringFormat("Suspending strategy.", _last_error), __FUNCTION_LINE__, _strat.GetName()); + _strat.Suspended(true); } } } @@ -383,7 +357,6 @@ class EA { virtual EAProcessResult ProcessTick() { if (estate.IsEnabled()) { MqlTick _tick = SymbolInfoStatic::GetTick(_Symbol); - GetMarket().SetTick(_tick); eresults.Reset(); if (estate.IsActive()) { ProcessPeriods(); @@ -401,9 +374,9 @@ class EA { eresults.stg_processed_periods++; } if (_strat.TickFilter(_tick)) { - _can_trade &= _can_trade && !_strat.IsSuspended(); - _can_trade &= _can_trade && !_strat.CheckCondition(STRAT_COND_TRADE_COND, TRADE_COND_HAS_STATE, - TRADE_STATE_TRADE_CANNOT); + _can_trade &= !_strat.IsSuspended(); + _can_trade &= + !_strat.CheckCondition(STRAT_COND_TRADE_COND, TRADE_COND_HAS_STATE, TRADE_STATE_TRADE_CANNOT); TradeSignalEntry _sentry = GetStrategySignalEntry(_strat, _can_trade, _strat.Get(STRAT_PARAM_SHIFT)); if (_sentry.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_SIGNALS)) > 0) { TradeSignal _signal(_sentry); @@ -752,6 +725,7 @@ class EA { _strat.Ptr().Set(STRAT_PARAM_ID, _magic_no); _strat.Ptr().Set(STRAT_PARAM_TF, _tf); _strat.Ptr().Set(STRAT_PARAM_TYPE, _type); + _strat.Ptr().OnInit(); if (!strats.KeyExists(_magic_no)) { _result &= strats.Set(_magic_no, _strat); } else { @@ -1044,11 +1018,6 @@ class EA { return NULL; } - /** - * Returns pointer to Terminal object. - */ - Market *GetMarket() { return market.Ptr(); } - /** * Returns pointer to Market object. */ @@ -1064,11 +1033,6 @@ class EA { */ DictStruct> *GetStrategies() { return GetPointer(strats); } - /** - * Gets EA params. - */ - EAParams GetParams() { return eparams; } - /** * Gets EA state. */ @@ -1086,21 +1050,11 @@ class EA { */ Log *GetLogger() { return GetPointer(logger); } - /** - * Gets pointer to market details. - */ - Market *Market() { return market.Ptr(); } - /** * Gets reference to strategies. */ DictStruct> *Strategies() { return &strats; } - /** - * Gets pointer to symbol details. - */ - SymbolInfo *SymbolInfo() { return (SymbolInfo *)GetMarket(); } - /* Setters */ /* Virtual methods */ @@ -1176,12 +1130,6 @@ class EA { SerializerNodeType Serialize(Serializer &_s) { _s.Pass(THIS_REF, "account", account, SERIALIZER_FIELD_FLAG_DYNAMIC); - // In MQL it will be: Market* _market = GetMarket(); - // In C++ it will be: Market& _market = GetMarket(); - // It is needed as PassObject() expects reference to object instead of its pointer. - MAKE_REF_FROM_PTR(Market, _market, GetMarket()); - _s.PassObject(THIS_REF, "market", _market, SERIALIZER_FIELD_FLAG_DYNAMIC); - for (DictStructIterator> _iter = GetStrategies().Begin(); _iter.IsValid(); ++_iter) { Strategy *_strat = _iter.Value().Ptr(); // @fixme: GH-422 @@ -1192,6 +1140,8 @@ class EA { _s.Pass(THIS_REF, "strat:params:" + _sname, _sparams); _s.Pass(THIS_REF, "strat:results:" + _sname, _sresults); } + _s.PassObject(THIS_REF, "trade", trade); + _s.PassObject(THIS_REF, "tsm", tsm); return SerializerNodeObject; } }; diff --git a/Indicator.define.h b/Indicator.define.h index 08c221d64..6743cba67 100644 --- a/Indicator.define.h +++ b/Indicator.define.h @@ -33,13 +33,15 @@ // Defines macros. #define COMMA , #define DUMMY -#define ICUSTOM_DEF(PARAMS) \ + +#define ICUSTOM_DEF(SET_HANDLE, PARAMS) \ double _res[]; \ if (_handle == NULL || _handle == INVALID_HANDLE) { \ if ((_handle = ::iCustom(_symbol, _tf, _name PARAMS)) == INVALID_HANDLE) { \ SetUserError(ERR_USER_INVALID_HANDLE); \ return EMPTY_VALUE; \ } \ + SET_HANDLE; \ } \ int _bars_calc = ::BarsCalculated(_handle); \ if (GetLastError() > 0) { \ @@ -49,7 +51,7 @@ return EMPTY_VALUE; \ } \ if (::CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { \ - return EMPTY_VALUE; \ + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; \ } \ return _res[0]; @@ -123,6 +125,6 @@ class DrawIndicator; } \ } \ if (CopyBuffer(_handle, MODE, SHIFT, 1, _res) < 0) { \ - return EMPTY_VALUE; \ + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; \ } \ return _res[0]; diff --git a/IndicatorBase.h b/IndicatorBase.h index 10858ee95..df0cb4388 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -54,6 +54,7 @@ class Chart; #include "Storage/ValueStorage.h" #include "Storage/ValueStorage.indicator.h" #include "Storage/ValueStorage.native.h" +#include "Util.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compatibility). @@ -66,6 +67,21 @@ int IndicatorCounted(int _value = 0) { } #endif +#ifdef __MQL5__ +// Defines global functions (for MQL5 forward compatibility). +template +double iCustom5(string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i, + J _j, int _mode, int _shift) { + ResetLastError(); + static Dict _handlers; + string _key = Util::MakeKey(_symbol, (string)_tf, _name, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j); + int _handle = _handlers.GetByKey(_key); + ICUSTOM_DEF(_handlers.Set(_key, _handle), + COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i COMMA _j); +} +#endif + /** * Class to deal with indicators. */ @@ -123,7 +139,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(DUMMY); + ICUSTOM_DEF(;, DUMMY); #endif } @@ -132,7 +148,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a); + ICUSTOM_DEF(;, COMMA _a); #endif } @@ -141,7 +157,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b); + ICUSTOM_DEF(;, COMMA _a COMMA _b); #endif } @@ -151,7 +167,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c); #endif } @@ -161,7 +177,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d); #endif } @@ -171,7 +187,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e); #endif } @@ -181,7 +197,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _f, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f); #endif } @@ -191,7 +207,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _f, _g, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g); #endif } @@ -201,7 +217,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _f, _g, _h, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h); #endif } @@ -211,7 +227,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _f, _g, _h, _i, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i); #endif } @@ -222,7 +238,7 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i COMMA _j); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i COMMA _j); #endif } @@ -233,7 +249,19 @@ class IndicatorBase : public Object { #ifdef __MQL4__ return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _mode, _shift); #else // __MQL5__ - ICUSTOM_DEF(COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i COMMA _j COMMA _k); + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i COMMA _j COMMA _k); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, E _e, F _f, + G _g, H _h, I _i, J _j, K _k, L _l, M _m, int _mode, int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c COMMA _d COMMA _e COMMA _f COMMA _g COMMA _h COMMA _i COMMA _j COMMA _k + COMMA _l COMMA _m); #endif } diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index 1e1b53c89..96befe0cf 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -26,7 +26,10 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). -double iAC(string _symbol, int _tf, int _shift) { return Indi_AC::iAC(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); } +double iAC(string _symbol, int _tf, int _shift) { + ResetLastError(); + return Indi_AC::iAC(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); +} #endif // Structs. @@ -88,7 +91,7 @@ class Indi_AC : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index be697f1e7..aaa0c8658 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -25,7 +25,10 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). -double iAD(string _symbol, int _tf, int _shift) { return Indi_AD::iAD(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); } +double iAD(string _symbol, int _tf, int _shift) { + ResetLastError(); + return Indi_AD::iAD(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); +} #endif // Structs. @@ -89,7 +92,7 @@ class Indi_AD : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index 161c4340c..d02d11225 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -27,6 +27,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iADX(string _symbol, int _tf, int _period, int _ap, int _mode, int _shift) { + ResetLastError(); return Indi_ADX::iADX(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_APPLIED_PRICE)_ap, (ENUM_INDI_ADX_LINE)_mode, _shift); } @@ -66,7 +67,7 @@ class Indi_ADX : public Indicator { * Class constructor. */ Indi_ADX(IndiADXParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_ADX(ENUM_TIMEFRAMES _tf) : Indicator(INDI_ADX, _tf) {} + Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ADX, _tf, _shift) {} /** * Returns the indicator value. @@ -105,7 +106,7 @@ class Indi_ADX : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 0e1e71f58..0e48422d2 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -28,15 +28,15 @@ #include "Price/Indi_Price.mqh" // Structs. -struct IndiAIndiMAParams : IndicatorParams { +struct IndiAMAParams : IndicatorParams { unsigned int period; unsigned int fast_period; unsigned int slow_period; unsigned int ama_shift; ENUM_APPLIED_PRICE applied_price; // Struct constructor. - IndiAIndiMAParams(int _period = 10, int _fast_period = 2, int _slow_period = 30, int _ama_shift = 0, - ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL, int _shift = 0) + IndiAMAParams(int _period = 10, int _fast_period = 2, int _slow_period = 30, int _ama_shift = 0, + ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL, int _shift = 0) : period(_period), fast_period(_fast_period), slow_period(_slow_period), @@ -53,7 +53,7 @@ struct IndiAIndiMAParams : IndicatorParams { break; } }; - IndiAIndiMAParams(IndiAIndiMAParams &_params, ENUM_TIMEFRAMES _tf) { + IndiAMAParams(IndiAMAParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; tf = _tf; }; @@ -62,12 +62,12 @@ struct IndiAIndiMAParams : IndicatorParams { /** * Implements the AMA indicator. */ -class Indi_AMA : public Indicator { +class Indi_AMA : public Indicator { public: /** * Class constructor. */ - Indi_AMA(IndiAIndiMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; + Indi_AMA(IndiAMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_AMA, _tf, _shift){}; /** diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index 5f58c329e..cbda37d66 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -25,7 +25,10 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). -double iAO(string _symbol, int _tf, int _shift) { return Indi_AO::iAO(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); } +double iAO(string _symbol, int _tf, int _shift) { + ResetLastError(); + return Indi_AO::iAO(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); +} #endif // Structs. @@ -91,7 +94,7 @@ class Indi_AO : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index 43ce100da..304edb113 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iATR(string _symbol, int _tf, int _period, int _shift) { + ResetLastError(); return Indi_ATR::iATR(_symbol, (ENUM_TIMEFRAMES)_tf, _period, _shift); } #endif @@ -93,7 +94,7 @@ class Indi_ATR : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index ccf61862a..22fe7b7de 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -27,6 +27,7 @@ // Defines global functions (for MQL4 backward compability). double iAlligator(string _symbol, int _tf, int _jp, int _js, int _tp, int _ts, int _lp, int _ls, int _ma_method, int _ap, int _mode, int _shift) { + ResetLastError(); return Indi_Alligator::iAlligator(_symbol, (ENUM_TIMEFRAMES)_tf, _jp, _js, _tp, _ts, _lp, _ls, (ENUM_MA_METHOD)_ma_method, (ENUM_APPLIED_PRICE)_ap, (ENUM_ALLIGATOR_LINE)_mode, _shift); @@ -152,7 +153,7 @@ class Indi_Alligator : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_BWMFI.mqh b/Indicators/Indi_BWMFI.mqh index b9f92dac4..4b0318366 100644 --- a/Indicators/Indi_BWMFI.mqh +++ b/Indicators/Indi_BWMFI.mqh @@ -25,7 +25,10 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). -double iBWMFI(string _symbol, int _tf, int _shift) { return Indi_BWMFI::iBWMFI(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); } +double iBWMFI(string _symbol, int _tf, int _shift) { + ResetLastError(); + return Indi_BWMFI::iBWMFI(_symbol, (ENUM_TIMEFRAMES)_tf, _shift); +} #endif // Enumerations. @@ -102,7 +105,7 @@ class Indi_BWMFI : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Bands.mqh b/Indicators/Indi_Bands.mqh index 7a3d1eabd..6e15f6d9e 100644 --- a/Indicators/Indi_Bands.mqh +++ b/Indicators/Indi_Bands.mqh @@ -34,11 +34,13 @@ // Defines global functions (for MQL4 backward compability). double iBands(string _symbol, int _tf, int _period, double _deviation, int _bands_shift, int _ap, int _mode, int _shift) { + ResetLastError(); return Indi_Bands::iBands(_symbol, (ENUM_TIMEFRAMES)_tf, _period, _deviation, _bands_shift, (ENUM_APPLIED_PRICE)_ap, (ENUM_BANDS_LINE)_mode, _shift); } double iBandsOnArray(double &_arr[], int _total, int _period, double _deviation, int _bands_shift, int _mode, int _shift) { + ResetLastError(); return Indi_Bands::iBandsOnArray(_arr, _total, _period, _deviation, _bands_shift, _mode, _shift); } #endif @@ -91,7 +93,7 @@ class Indi_Bands : public Indicator { */ Indi_Bands(IndiBandsParams &_p, IndicatorBase *_indi_src = NULL, int _mode = 0) : Indicator(_p, _indi_src, _mode) {} - Indi_Bands(ENUM_TIMEFRAMES _tf) : Indicator(INDI_BANDS, _tf) {} + Indi_Bands(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BANDS, _tf, _shift) {} /** * Returns the indicator value. @@ -128,7 +130,7 @@ class Indi_Bands : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index edba3d8c1..57eae631e 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iBearsPower(string _symbol, int _tf, int _period, int _ap, int _shift) { + ResetLastError(); return Indi_BearsPower::iBearsPower(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_APPLIED_PRICE)_ap, _shift); } #endif @@ -57,7 +58,7 @@ class Indi_BearsPower : public Indicator { */ Indi_BearsPower(IndiBearsPowerParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_BearsPower(ENUM_TIMEFRAMES _tf) : Indicator(INDI_BEARS, _tf) {} + Indi_BearsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BEARS, _tf, _shift) {} /** * Returns the indicator value. @@ -94,7 +95,7 @@ class Indi_BearsPower : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index 895204aa7..79244878d 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iBullsPower(string _symbol, int _tf, int _period, int _ap, int _shift) { + ResetLastError(); return Indi_BullsPower::iBullsPower(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_APPLIED_PRICE)_ap, _shift); } #endif @@ -57,7 +58,7 @@ class Indi_BullsPower : public Indicator { */ Indi_BullsPower(IndiBullsPowerParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_BullsPower(ENUM_TIMEFRAMES _tf) : Indicator(INDI_BULLS, _tf) {} + Indi_BullsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BULLS, _tf, _shift) {} /** * Returns the indicator value. @@ -94,7 +95,7 @@ class Indi_BullsPower : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index b264310f0..721b034f9 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -64,7 +64,7 @@ class Indi_CCI : public Indicator { * Class constructor. */ Indi_CCI(IndiCCIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_CCI(ENUM_TIMEFRAMES _tf) : Indicator(INDI_CCI, _tf) {} + Indi_CCI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_CCI, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_DEMA.mqh b/Indicators/Indi_DEMA.mqh index 30e350a51..291bf8bee 100644 --- a/Indicators/Indi_DEMA.mqh +++ b/Indicators/Indi_DEMA.mqh @@ -69,7 +69,7 @@ class Indi_DEMA : public Indicator { * Class constructor. */ Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_DEMA(ENUM_TIMEFRAMES _tf) : Indicator(INDI_DEMA, _tf) {} + Indi_DEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_DEMA, _tf, _shift) {} /** * Updates the indicator value. @@ -102,7 +102,7 @@ class Indi_DEMA : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #else diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index c614fb54d..299687be0 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iDeMarker(string _symbol, int _tf, int _period, int _shift) { + ResetLastError(); return Indi_DeMarker::iDeMarker(_symbol, (ENUM_TIMEFRAMES)_tf, _period, _shift); } #endif @@ -56,7 +57,7 @@ class Indi_DeMarker : public Indicator { */ Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_DeMarker(ENUM_TIMEFRAMES _tf) : Indicator(INDI_DEMARKER, _tf) {} + Indi_DeMarker(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_DEMARKER, _tf, _shift) {} /** * Returns the indicator value. @@ -92,7 +93,7 @@ class Indi_DeMarker : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Drawer.mqh b/Indicators/Indi_Drawer.mqh index 429fdd5e4..957b25106 100644 --- a/Indicators/Indi_Drawer.mqh +++ b/Indicators/Indi_Drawer.mqh @@ -45,7 +45,9 @@ class Indi_Drawer : public Indicator { : Indicator(_p, _indi_src), redis(true) { Init(); } - Indi_Drawer(ENUM_TIMEFRAMES _tf) : Indicator(INDI_DRAWER, _tf), redis(true) { Init(); } + Indi_Drawer(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_DRAWER, _tf, _shift), redis(true) { + Init(); + } void Init() { // Drawer is always ready. diff --git a/Indicators/Indi_Envelopes.mqh b/Indicators/Indi_Envelopes.mqh index 25c70ab90..7f81e699d 100644 --- a/Indicators/Indi_Envelopes.mqh +++ b/Indicators/Indi_Envelopes.mqh @@ -31,11 +31,13 @@ // Defines global functions (for MQL4 backward compability). double iEnvelopes(string _symbol, int _tf, int _period, int _ma_method, int _ma_shift, int _ap, double _deviation, int _mode, int _shift) { + ResetLastError(); return Indi_Envelopes::iEnvelopes(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_MA_METHOD)_ma_method, _ma_shift, (ENUM_APPLIED_PRICE)_ap, _deviation, _mode, _shift); } double iEnvelopesOnArray(double &_arr[], int _total, int _ma_period, int _ma_method, int _ma_shift, double _deviation, int _mode, int _shift) { + ResetLastError(); return Indi_Envelopes::iEnvelopesOnArray(_arr, _total, _ma_period, (ENUM_MA_METHOD)_ma_method, _ma_shift, _deviation, _mode, _shift); } @@ -81,7 +83,7 @@ class Indi_Envelopes : public Indicator { */ Indi_Envelopes(IndiEnvelopesParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Envelopes(ENUM_TIMEFRAMES _tf) : Indicator(INDI_ENVELOPES, _tf) {} + Indi_Envelopes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ENVELOPES, _tf, _shift) {} /** * Returns the indicator value. @@ -129,7 +131,7 @@ class Indi_Envelopes : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index 83cab40c3..24c6fd029 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -37,6 +37,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iForce(string _symbol, int _tf, int _period, int _ma_method, int _ap, int _shift) { + ResetLastError(); return Indi_Force::iForce(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_MA_METHOD)_ma_method, (ENUM_APPLIED_PRICE)_ap, _shift); } @@ -71,7 +72,7 @@ class Indi_Force : public Indicator { * Class constructor. */ Indi_Force(IndiForceParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Force(ENUM_TIMEFRAMES _tf) : Indicator(INDI_FORCE, _tf) {} + Indi_Force(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_FORCE, _tf, _shift) {} /** * Returns the indicator value. @@ -107,7 +108,7 @@ class Indi_Force : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Fractals.mqh b/Indicators/Indi_Fractals.mqh index 72d4025ff..e19757578 100644 --- a/Indicators/Indi_Fractals.mqh +++ b/Indicators/Indi_Fractals.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iFractals(string _symbol, int _tf, int _mode, int _shift) { + ResetLastError(); return Indi_Fractals::iFractals(_symbol, (ENUM_TIMEFRAMES)_tf, (ENUM_LO_UP_LINE)_mode, _shift); } #endif @@ -92,7 +93,7 @@ class Indi_Fractals : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Gator.mqh b/Indicators/Indi_Gator.mqh index 1047a5532..3a5d336f5 100644 --- a/Indicators/Indi_Gator.mqh +++ b/Indicators/Indi_Gator.mqh @@ -34,6 +34,7 @@ // Defines global functions (for MQL4 backward compability). double iGator(string _symbol, int _tf, int _jp, int _js, int _tp, int _ts, int _lp, int _ls, int _ma_method, int _ap, int _mode, int _shift) { + ResetLastError(); return Indi_Gator::iGator(_symbol, (ENUM_TIMEFRAMES)_tf, _jp, _js, _tp, _ts, _lp, _ls, (ENUM_MA_METHOD)_ma_method, (ENUM_APPLIED_PRICE)_ap, (ENUM_GATOR_HISTOGRAM)_mode, _shift); } @@ -108,7 +109,7 @@ class Indi_Gator : public Indicator { * Class constructor. */ Indi_Gator(IndiGatorParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Gator(ENUM_TIMEFRAMES _tf) : Indicator(INDI_GATOR, _tf) {} + Indi_Gator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_GATOR, _tf, _shift) {} /** * Returns the indicator value. @@ -159,7 +160,7 @@ class Indi_Gator : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index 8ea32e487..32881967c 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -120,7 +120,7 @@ class Indi_HeikenAshi : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index e0b6638a6..9996abab1 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iIchimoku(string _symbol, int _tf, int _ts, int _ks, int _ssb, int _mode, int _shift) { + ResetLastError(); return Indi_Ichimoku::iIchimoku(_symbol, (ENUM_TIMEFRAMES)_tf, _ts, _ks, _ssb, _mode, _shift); } #endif @@ -92,7 +93,7 @@ class Indi_Ichimoku : public Indicator { */ Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Ichimoku(ENUM_TIMEFRAMES _tf) : Indicator(INDI_ICHIMOKU, _tf) {} + Indi_Ichimoku(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ICHIMOKU, _tf, _shift) {} /** * Returns the indicator value. @@ -132,7 +133,7 @@ class Indi_Ichimoku : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index 9e39298b3..98862a147 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -36,11 +36,13 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iMA(string _symbol, int _tf, int _ma_period, int _ma_shift, int _ma_method, int _ap, int _shift) { + ResetLastError(); return Indi_MA::iMA(_symbol, (ENUM_TIMEFRAMES)_tf, _ma_period, _ma_shift, (ENUM_MA_METHOD)_ma_method, (ENUM_APPLIED_PRICE)_ap, _shift); } double iMAOnArray(double &_arr[], int _total, int _period, int _ma_shift, int _ma_method, int _shift, IndicatorCalculateCache *_cache = NULL) { + ResetLastError(); return Indi_MA::iMAOnArray(_arr, _total, _period, _ma_shift, _ma_method, _shift, _cache); } #endif @@ -78,7 +80,7 @@ class Indi_MA : public Indicator { * Class constructor. */ Indi_MA(IndiMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_MA(ENUM_TIMEFRAMES _tf) : Indicator(INDI_MA, _tf) {} + Indi_MA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MA, _tf, _shift) {} /** * Returns the indicator value. @@ -115,7 +117,7 @@ class Indi_MA : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index a54fa8e9e..1a3227f4f 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iMACD(string _symbol, int _tf, int _ema_fp, int _ema_sp, int _signal_period, int _ap, int _mode, int _shift) { + ResetLastError(); return Indi_MACD::iMACD(_symbol, (ENUM_TIMEFRAMES)_tf, _ema_fp, _ema_sp, _signal_period, (ENUM_APPLIED_PRICE)_ap, (ENUM_SIGNAL_LINE)_mode, _shift); } @@ -64,7 +65,7 @@ class Indi_MACD : public Indicator { * Class constructor. */ Indi_MACD(IndiMACDParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_MACD(ENUM_TIMEFRAMES _tf) : Indicator(INDI_MACD, _tf) {} + Indi_MACD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MACD, _tf, _shift) {} /** * Returns the indicator value. @@ -104,7 +105,7 @@ class Indi_MACD : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index d1aef98ac..a416e7179 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iMFI(string _symbol, int _tf, int _period, int _shift) { + ResetLastError(); return Indi_MFI::iMFI(_symbol, (ENUM_TIMEFRAMES)_tf, _period, _shift); } #endif @@ -56,7 +57,7 @@ class Indi_MFI : public Indicator { * Class constructor. */ Indi_MFI(IndiMFIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_MFI(ENUM_TIMEFRAMES _tf) : Indicator(INDI_MFI, _tf) {} + Indi_MFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MFI, _tf, _shift) {} /** * Calculates the Money Flow Index indicator and returns its value. @@ -101,7 +102,7 @@ class Indi_MFI : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 55cbb16c4..ed4b19f4d 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -36,6 +36,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iMomentum(string _symbol, int _tf, int _period, int _ap, int _shift) { + ResetLastError(); return Indi_Momentum::iMomentum(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_APPLIED_PRICE)_ap, _shift); } #endif @@ -67,7 +68,7 @@ class Indi_Momentum : public Indicator { */ Indi_Momentum(IndiMomentumParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Momentum(ENUM_TIMEFRAMES _tf) : Indicator(INDI_MOMENTUM, _tf) {} + Indi_Momentum(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MOMENTUM, _tf, _shift) {} /** * Returns the indicator value. @@ -103,7 +104,7 @@ class Indi_Momentum : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index f5fcb1754..61a93b422 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iOBV(string _symbol, int _tf, int _av, int _shift) { + ResetLastError(); return Indi_OBV::iOBV(_symbol, (ENUM_TIMEFRAMES)_tf, (ENUM_APPLIED_VOLUME)_av, _shift); } #endif @@ -108,7 +109,7 @@ class Indi_OBV : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index 40f0f883d..959d0fbfa 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iOsMA(string _symbol, int _tf, int _ema_fp, int _ema_sp, int _signal_period, int _ap, int _shift) { + ResetLastError(); return Indi_OsMA::iOsMA(_symbol, (ENUM_TIMEFRAMES)_tf, _ema_fp, _ema_sp, _signal_period, (ENUM_APPLIED_PRICE)_ap, _shift); } @@ -63,7 +64,7 @@ class Indi_OsMA : public Indicator { * Class constructor. */ Indi_OsMA(IndiOsMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_OsMA(ENUM_TIMEFRAMES _tf) : Indicator(INDI_OSMA, _tf) {} + Indi_OsMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_OSMA, _tf, _shift) {} /** * Returns the indicator value. @@ -101,7 +102,7 @@ class Indi_OsMA : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_PriceFeeder.mqh b/Indicators/Indi_PriceFeeder.mqh index 740d28099..4f6793150 100644 --- a/Indicators/Indi_PriceFeeder.mqh +++ b/Indicators/Indi_PriceFeeder.mqh @@ -63,7 +63,7 @@ class Indi_PriceFeeder : public Indicator { Indi_PriceFeeder(const double& _price_data[], int _total = 0) : Indicator(INDI_PRICE_FEEDER) { ArrayCopy(iparams.price_data, _price_data); }; - Indi_PriceFeeder(ENUM_TIMEFRAMES _tf) : Indicator(INDI_PRICE_FEEDER, _tf) {} + Indi_PriceFeeder(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_PRICE_FEEDER, _tf, _shift) {} void SetPrices(const double& _price_data[], int _total = 0) { iparams = IndiPriceFeederParams(_price_data, _total); } diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index c67bb4251..2f9c4c612 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -34,9 +34,11 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iRSI(string _symbol, int _tf, int _period, int _ap, int _shift) { + ResetLastError(); return Indi_RSI::iRSI(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_APPLIED_PRICE)_ap, _shift); } double iRSIOnArray(double &_arr[], int _total, int _period, int _shift) { + ResetLastError(); return Indi_RSI::iRSIOnArray(_arr, _total, _period, _shift); } #endif @@ -94,7 +96,7 @@ class Indi_RSI : public Indicator { * Class constructor. */ Indi_RSI(IndiRSIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_RSI(ENUM_TIMEFRAMES _tf) : Indicator(INDI_RSI, _tf) {} + Indi_RSI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_RSI, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index b1789c89c..e9ea90041 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iRVI(string _symbol, int _tf, int _period, int _mode, int _shift) { + ResetLastError(); return Indi_RVI::iRVI(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_SIGNAL_LINE)_mode, _shift); } #endif @@ -55,7 +56,7 @@ class Indi_RVI : public Indicator { * Class constructor. */ Indi_RVI(const IndiRVIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_RVI(ENUM_TIMEFRAMES _tf) : Indicator(INDI_RVI, _tf) {} + Indi_RVI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_RVI, _tf, _shift) {} /** * Returns the indicator value. @@ -93,7 +94,7 @@ class Indi_RVI : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_SAR.mqh b/Indicators/Indi_SAR.mqh index 550f13103..0410e3335 100644 --- a/Indicators/Indi_SAR.mqh +++ b/Indicators/Indi_SAR.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iSAR(string _symbol, int _tf, double _step, double _max, int _shift) { + ResetLastError(); return Indi_SAR::iSAR(_symbol, (ENUM_TIMEFRAMES)_tf, _step, _max, _shift); } #endif @@ -56,7 +57,7 @@ class Indi_SAR : public Indicator { * Class constructor. */ Indi_SAR(IndiSARParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_SAR(ENUM_TIMEFRAMES _tf) : Indicator(INDI_SAR, _tf) {} + Indi_SAR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_SAR, _tf, _shift) {} /** * Returns the indicator value. @@ -92,7 +93,7 @@ class Indi_SAR : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index 2a5057b7a..4d8f42dff 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -36,10 +36,12 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iStdDev(string _symbol, int _tf, int _ma_period, int _ma_shift, int _ma_method, int _ap, int _shift) { + ResetLastError(); return Indi_StdDev::iStdDev(_symbol, (ENUM_TIMEFRAMES)_tf, _ma_period, _ma_shift, (ENUM_MA_METHOD)_ma_method, (ENUM_APPLIED_PRICE)_ap, _shift); } double iStdDevOnArray(double &_arr[], int _total, int _ma_period, int _ma_shift, int _ma_method, int _shift) { + ResetLastError(); return Indi_StdDev::iStdDevOnArray(_arr, _total, _ma_period, _ma_shift, (ENUM_MA_METHOD)_ma_method, _shift); } #endif @@ -77,7 +79,7 @@ class Indi_StdDev : public Indicator { * Class constructor. */ Indi_StdDev(IndiStdDevParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_StdDev(ENUM_TIMEFRAMES _tf) : Indicator(INDI_STDDEV, _tf) {} + Indi_StdDev(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_STDDEV, _tf, _shift) {} /** * Calculates the Standard Deviation indicator and returns its value. @@ -113,7 +115,7 @@ class Indi_StdDev : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index 55e2bf1be..b23472ac9 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -27,6 +27,7 @@ // Defines global functions (for MQL4 backward compability). double iStochastic(string _symbol, int _tf, int _kperiod, int _dperiod, int _slowing, int _ma_method, int _pf, int _mode, int _shift) { + ResetLastError(); return Indi_Stochastic::iStochastic(_symbol, (ENUM_TIMEFRAMES)_tf, _kperiod, _dperiod, _slowing, (ENUM_MA_METHOD)_ma_method, (ENUM_STO_PRICE)_pf, _mode, _shift); } @@ -67,7 +68,7 @@ class Indi_Stochastic : public Indicator { * Class constructor. */ Indi_Stochastic(IndiStochParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Stochastic(ENUM_TIMEFRAMES _tf) : Indicator(INDI_STOCHASTIC, _tf) {} + Indi_Stochastic(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_STOCHASTIC, _tf, _shift) {} /** * Calculates the Stochastic Oscillator and returns its value. @@ -109,7 +110,7 @@ class Indi_Stochastic : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif @@ -139,9 +140,7 @@ class Indi_Stochastic : public Indicator { /** * Checks if indicator entry values are valid. */ - virtual bool IsValidEntry(IndicatorDataEntry &_entry) { - return _entry.IsWithinRange(0, 101); - } + virtual bool IsValidEntry(IndicatorDataEntry &_entry) { return _entry.IsWithinRange(0, 101); } /* Getters */ diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index bfffc6d72..f47d322c7 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -26,6 +26,7 @@ #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). double iWPR(string _symbol, int _tf, int _period, int _shift) { + ResetLastError(); return Indi_WPR::iWPR(_symbol, (ENUM_TIMEFRAMES)_tf, _period, _shift); } #endif @@ -55,7 +56,7 @@ class Indi_WPR : public Indicator { * Class constructor. */ Indi_WPR(IndiWPRParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_WPR(ENUM_TIMEFRAMES _tf) : Indicator(INDI_WPR, _tf) {} + Indi_WPR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_WPR, _tf, _shift) {} /** * Calculates the Larry Williams' Percent Range and returns its value. @@ -91,7 +92,7 @@ class Indi_WPR : public Indicator { } } if (CopyBuffer(_handle, 0, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #endif diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index 5942ed644..7d7ea0c0e 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -64,7 +64,7 @@ class Indi_ZigZag : public Indicator { * Class constructor. */ Indi_ZigZag(IndiZigZagParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_ZigZag(ENUM_TIMEFRAMES _tf) : Indicator(INDI_ZIGZAG, _tf) {} + Indi_ZigZag(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ZIGZAG, _tf, _shift) {} /** * Returns value for ZigZag indicator. @@ -94,7 +94,7 @@ class Indi_ZigZag : public Indicator { } } if (CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { - return EMPTY_VALUE; + return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; } return _res[0]; #else diff --git a/Order.struct.h b/Order.struct.h index 0fbda897c..d2bda532e 100644 --- a/Order.struct.h +++ b/Order.struct.h @@ -34,7 +34,7 @@ #include "Data.struct.h" #include "Order.enum.h" #include "Serializer.mqh" -#include "SymbolInfo.static.h" +#include "SymbolInfo.struct.static.h" #include "Terminal.mqh" #ifndef __MQL5__ diff --git a/README.md b/README.md index b467a9154..475d5a24a 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ Projects implementing this framework: Multi-strategy trading robot. - [EA31337-strategies](https://github.com/EA31337/EA31337-strategies): EA strategies. +- [EA31337-indicators-other](https://github.com/EA31337/EA31337-indicators-other): + 3rd party indicators ## Conversion @@ -65,6 +67,8 @@ This framework can be used to convert your MQL4 code to be compatible with both Find below the table of conversion (replace code on left with the right one): +
+ | MQL4 (original) | MQL4 & MQL5 (replace with) | Required include file | |:---------------------|:---------------------------|:----------------------| | `WindowRedraw()` | `Chart::WindowRedraw()` | `Chart.mqh` | @@ -124,21 +128,27 @@ Find below the table of conversion (replace code on left with the right one): | `OrderType()` | `OrderStatic::Type()` | `Order.struct.h` | | `OrdersTotal()` | `TradeStatic::TotalActive()` | `Trade.mqh` | +
+ Here are the special [predefined variables](https://docs.mql4.com/predefined) conversion: +
+ | MQL4 (original) | MQL4 & MQL5 (replace with) | Required include file | -|:---------------------|:-----------------------------|:-----------------| -| `Ask` | `SymbolInfo::GetAsk()` | `SymbolInfo.mqh` | -| `Bars` | `Chart::iBars()` | `Chart.mqh` | -| `Bid` | `SymbolInfo::GetBid()` | `SymbolInfo.mqh` | -| `Close[]` | `Chart::iClose()` | `Chart.mqh` | -| `Digits` | `SymbolInfo::GetDigits()` | `SymbolInfo.mqh` | -| `High[]` | `Chart::iHigh()` | `Chart.mqh` | -| `Low[]` | `Chart::iLow()` | `Chart.mqh` | -| `Open[]` | `Chart::iOpen()` | `Chart.mqh` | -| `Point` | `SymbolInfo::GetPointSize()` | `SymbolInfo.mqh` | -| `Time[]` | `Chart::iTime()` | `Chart.mqh` | -| `Volume[]` | `Chart::iVolume()` | `Chart.mqh` | +|:---------------------|:-----------------------------|:--------------------| +| `Ask` | `SymbolInfo::GetAsk()` | `SymbolInfo.struct.static.h` | +| `Bars` | `ChartStatic::iBars()` | `Chart.struct.static.h` | +| `Bid` | `SymbolInfo::GetBid()` | `SymbolInfo.struct.static.h` | +| `Close[]` | `ChartStatic::iClose()` | `Chart.struct.static.h` | +| `Digits` | `SymbolInfo::GetDigits()` | `SymbolInfo.struct.static.h` | +| `High[]` | `ChartStatic::iHigh()` | `Chart.struct.static.h` | +| `Low[]` | `ChartStatic::iLow()` | `Chart.struct.static.h` | +| `Open[]` | `ChartStatic::iOpen()` | `Chart.struct.static.h` | +| `Point` | `SymbolInfo::GetPointSize()` | `SymbolInfo.struct.static.h` | +| `Time[]` | `ChartStatic::iTime()` | `Chart.struct.static.h` | +| `Volume[]` | `ChartStatic::iVolume()` | `Chart.struct.static.h` | + +
## Classes diff --git a/Strategy.mqh b/Strategy.mqh index a4ffb6e83..b391942e5 100644 --- a/Strategy.mqh +++ b/Strategy.mqh @@ -93,8 +93,7 @@ class Strategy : public Object { Dict ddata; Dict fdata; Dict idata; - Dict indicators_unmanaged; // Indicators list (unmanaged). - DictStruct> indicators_managed; // Indicators list (managed). + DictStruct> indicators; // Indicators list. DictStruct tasks; Log logger; // Log instance. MqlTick last_tick; @@ -147,11 +146,7 @@ class Strategy : public Object { /** * Class deconstructor. */ - ~Strategy() { - for (DictIterator iter = indicators_unmanaged.Begin(); iter.IsValid(); ++iter) { - delete iter.Value(); - } - } + ~Strategy() {} /* Processing methods */ @@ -245,10 +240,8 @@ class Strategy : public Object { * Returns handler to the strategy's indicator class. */ IndicatorBase *GetIndicator(int _id = 0) { - if (indicators_managed.KeyExists(_id)) { - return indicators_managed[_id].Ptr(); - } else if (indicators_unmanaged.KeyExists(_id)) { - return indicators_unmanaged[_id]; + if (indicators.KeyExists(_id)) { + return indicators[_id].Ptr(); } Alert("Missing indicator id ", _id); @@ -258,7 +251,7 @@ class Strategy : public Object { /** * Returns strategy's indicators. */ - DictStruct> GetIndicators() { return indicators_managed; } + DictStruct> GetIndicators() { return indicators; } /* Struct getters */ @@ -513,13 +506,9 @@ class Strategy : public Object { /** * Sets reference to indicator. */ - void SetIndicator(IndicatorBase *_indi, int _id = 0, bool _managed = true) { - if (_managed) { - Ref _ref = _indi; - indicators_managed.Set(_id, _ref); - } else { - indicators_unmanaged.Set(_id, _indi); - } + void SetIndicator(IndicatorBase *_indi, int _id = 0) { + Ref _ref = _indi; + indicators.Set(_id, _ref); } /* Static setters */ diff --git a/SymbolInfo.mqh b/SymbolInfo.mqh index d4f1957ec..a277b0c8c 100644 --- a/SymbolInfo.mqh +++ b/SymbolInfo.mqh @@ -31,8 +31,8 @@ class SymbolInfo; #include "SymbolInfo.define.h" #include "SymbolInfo.enum.h" #include "SymbolInfo.enum.symbols.h" -#include "SymbolInfo.static.h" #include "SymbolInfo.struct.h" +#include "SymbolInfo.struct.static.h" // Includes. #include "Log.mqh" diff --git a/SymbolInfo.struct.h b/SymbolInfo.struct.h index 04ea0e0b5..ba2dc565d 100644 --- a/SymbolInfo.struct.h +++ b/SymbolInfo.struct.h @@ -33,7 +33,7 @@ // Includes. #include "ISerializable.h" #include "MqlTick.h" -#include "SymbolInfo.static.h" +#include "SymbolInfo.struct.static.h" // Defines struct to store symbol data. struct SymbolInfoEntry diff --git a/SymbolInfo.static.h b/SymbolInfo.struct.static.h similarity index 99% rename from SymbolInfo.static.h rename to SymbolInfo.struct.static.h index 3ce588682..7133cc0a3 100644 --- a/SymbolInfo.static.h +++ b/SymbolInfo.struct.static.h @@ -30,9 +30,9 @@ #include "Std.h" /** - * Class to provide symbol information. + * Struct to provide symbol information. */ -class SymbolInfoStatic { +struct SymbolInfoStatic { public: /** * Get the current symbol pair from the current chart. diff --git a/Terminal.define.h b/Terminal.define.h index 7484aafb7..d5105b86d 100644 --- a/Terminal.define.h +++ b/Terminal.define.h @@ -81,6 +81,14 @@ #define ERR_INVALID_PARAMETER 4003 // Wrong parameter when calling the system function. #endif +// MQL defines. +#ifdef __MQL4__ +#define MQL_VER 4 +#else +#define MQL_VER 5 +#endif +#define MQL_EXT ".ex" + (string)MQL_VER + #ifdef __MQL4__ // The resolution of display on the screen in a number of Dots in a line per Inch (DPI). // By knowing the value, you can set the size of graphical objects, diff --git a/Trade.enum.h b/Trade.enum.h index df3e2e810..0c4fa402d 100644 --- a/Trade.enum.h +++ b/Trade.enum.h @@ -32,17 +32,19 @@ // Trade actions. enum ENUM_TRADE_ACTION { - TRADE_ACTION_CALC_LOT_SIZE = 1, // Recalculate lot size - TRADE_ACTION_ORDER_CLOSE_LEAST_LOSS, // Close order with least loss - TRADE_ACTION_ORDER_CLOSE_LEAST_PROFIT, // Close order with least profit - TRADE_ACTION_ORDER_CLOSE_MOST_LOSS, // Close order with most loss - TRADE_ACTION_ORDER_CLOSE_MOST_PROFIT, // Close order with most profit - TRADE_ACTION_ORDER_OPEN, // Open order - TRADE_ACTION_ORDERS_CLOSE_ALL, // Close open sell orders - TRADE_ACTION_ORDERS_CLOSE_BY_TYPE, // Close open orders by type (args) - TRADE_ACTION_ORDERS_CLOSE_IN_PROFIT, // Close open orders in profit - TRADE_ACTION_ORDERS_CLOSE_IN_TREND, // Close open orders in trend - TRADE_ACTION_ORDERS_CLOSE_IN_TREND_NOT, // Close open orders NOT in trend + TRADE_ACTION_CALC_LOT_SIZE = 1, // Recalculate lot size + TRADE_ACTION_ORDER_CLOSE_LEAST_LOSS, // Close order with least loss + TRADE_ACTION_ORDER_CLOSE_LEAST_PROFIT, // Close order with least profit + TRADE_ACTION_ORDER_CLOSE_MOST_LOSS, // Close order with most loss + TRADE_ACTION_ORDER_CLOSE_MOST_PROFIT, // Close order with most profit + TRADE_ACTION_ORDER_OPEN, // Open order + TRADE_ACTION_ORDERS_CLOSE_ALL, // Close open sell orders + TRADE_ACTION_ORDERS_CLOSE_BY_TYPE, // Close open orders by type (args) + TRADE_ACTION_ORDERS_CLOSE_IN_PROFIT, // Close open orders in profit + TRADE_ACTION_ORDERS_CLOSE_IN_TREND, // Close open orders in trend + TRADE_ACTION_ORDERS_CLOSE_IN_TREND_NOT, // Close open orders NOT in trend + TRADE_ACTION_ORDERS_CLOSE_SIDE_IN_LOSS, // Close orders in loss side + TRADE_ACTION_ORDERS_CLOSE_SIDE_IN_PROFIT, // Close orders in profit side // TRADE_ACTION_ORDERS_REMOVE_ALL_PENDING, TRADE_ACTION_ORDERS_LIMIT_SET, // Set orders per period limit TRADE_ACTION_STATE_ADD, // Add trade specific state (1 arg) diff --git a/Trade.mqh b/Trade.mqh index 5f2229a06..254f6bbff 100644 --- a/Trade.mqh +++ b/Trade.mqh @@ -641,7 +641,7 @@ HistorySelect(0, TimeCurrent()); // Select history for access. StringFormat("Code: %d, Msg: %s", _last_error, Terminal::GetErrorText(_last_error))); tstats.Add(TRADE_STAT_ORDERS_ERRORS); // Pass-through. - case ERR_NO_ERROR: + case ERR_NO_ERROR: // 0 orders_active.Set(_order.Get(ORDER_PROP_TICKET), _ref_order); order_last = _order; tstates.AddState(TRADE_STATE_ORDERS_ACTIVE); @@ -649,9 +649,15 @@ HistorySelect(0, TimeCurrent()); // Select history for access. // Trigger: OnOrder(); _result = true; break; - case TRADE_RETCODE_INVALID: - logger.Error("Cannot process order!", __FUNCTION_LINE__, - StringFormat("Code: %d, Msg: %s", _last_error, Terminal::GetErrorText(_last_error))); + case TRADE_RETCODE_INVALID: // 10013 + logger.Error("Cannot process order!", __FUNCTION_LINE__, StringFormat("Code: %d", _last_error)); + _result = false; + break; + case TRADE_RETCODE_NO_MONEY: // 10019 + logger.Error("Not enough money to complete the request!", __FUNCTION_LINE__, + StringFormat("Code: %d", _last_error)); + tstates.AddState(TRADE_STATE_MONEY_NOT_ENOUGH); + _result = false; break; default: logger.Error("Cannot add order!", __FUNCTION_LINE__, @@ -660,7 +666,7 @@ HistorySelect(0, TimeCurrent()); // Select history for access. _result = false; break; } - UpdateStates(true); + UpdateStates(_result); return _result; } @@ -1337,11 +1343,10 @@ HistorySelect(0, TimeCurrent()); // Select history for access. * Returns true on no errors. * */ - bool UpdateStates(bool _force = false) { + void UpdateStates(bool _force = false) { static datetime _last_check = 0; - static unsigned int _states_prev = tstates.GetStates(); - ResetLastError(); if (_force || _last_check + 60 < TimeCurrent()) { + static unsigned int _states_prev = tstates.GetStates(); // Infrequent checks (each minute). /* Limit checks */ tstates.SetState(TRADE_STATE_PERIOD_LIMIT_REACHED, tparams.IsLimitGe(tstats)); @@ -1390,7 +1395,6 @@ HistorySelect(0, TimeCurrent()); // Select history for access. _states_prev = tstates.GetStates(); } } - return GetLastError() == ERR_NO_ERROR; } /* Normalization methods */ @@ -1900,6 +1904,27 @@ HistorySelect(0, TimeCurrent()); // Select history for access. RefreshActiveOrders(true); } break; + case TRADE_ACTION_ORDERS_CLOSE_SIDE_IN_LOSS: + if (Get(TRADE_STATE_ORDERS_ACTIVE) && orders_active.Size() > 0) { + ENUM_ORDER_TYPE _order_types1[] = {ORDER_TYPE_BUY, ORDER_TYPE_SELL}; + ENUM_ORDER_TYPE _order_type_profitable = + _oquery_ref.Ptr() + .FindPropBySum( + _order_types1, ORDER_PROP_PROFIT, ORDER_TYPE); + _result &= + OrdersCloseViaCmd(Order::NegateOrderType(_order_type_profitable), ORDER_REASON_CLOSED_BY_ACTION) >= 0; + } + break; + case TRADE_ACTION_ORDERS_CLOSE_SIDE_IN_PROFIT: + if (Get(TRADE_STATE_ORDERS_ACTIVE) && orders_active.Size() > 0) { + ENUM_ORDER_TYPE _order_types2[] = {ORDER_TYPE_BUY, ORDER_TYPE_SELL}; + ENUM_ORDER_TYPE _order_type_profitable2 = + _oquery_ref.Ptr() + .FindPropBySum( + _order_types2, ORDER_PROP_PROFIT, ORDER_TYPE); + _result &= OrdersCloseViaCmd(_order_type_profitable2, ORDER_REASON_CLOSED_BY_ACTION) >= 0; + } + break; case TRADE_ACTION_ORDERS_LIMIT_SET: // Sets the new limits. tparams.SetLimits((ENUM_TRADE_STAT_TYPE)_args[0].integer_value, (ENUM_TRADE_STAT_PERIOD)_args[1].integer_value, diff --git a/Util.h b/Util.h index 8ba6dbb2a..77d7665cc 100644 --- a/Util.h +++ b/Util.h @@ -108,6 +108,106 @@ class Util { SeparatedMaybe(SerializerConversions::ValueToString(_f)) + SerializerConversions::ValueToString(_g); } + /** + * Creates string-based key using given variables. + */ + template + static string MakeKey(const A _a, const B _b, const C _c, const D _d, const E _e, const F _f, const G _g, + const H _h) { + return SeparatedMaybe(SerializerConversions::ValueToString(_a)) + + SeparatedMaybe(SerializerConversions::ValueToString(_b)) + + SeparatedMaybe(SerializerConversions::ValueToString(_c)) + + SeparatedMaybe(SerializerConversions::ValueToString(_d)) + + SeparatedMaybe(SerializerConversions::ValueToString(_e)) + + SeparatedMaybe(SerializerConversions::ValueToString(_f)) + SerializerConversions::ValueToString(_g) + + SerializerConversions::ValueToString(_h); + } + + /** + * Creates string-based key using given variables. + */ + template + static string MakeKey(const A _a, const B _b, const C _c, const D _d, const E _e, const F _f, const G _g, const H _h, + const I _i) { + return SeparatedMaybe(SerializerConversions::ValueToString(_a)) + + SeparatedMaybe(SerializerConversions::ValueToString(_b)) + + SeparatedMaybe(SerializerConversions::ValueToString(_c)) + + SeparatedMaybe(SerializerConversions::ValueToString(_d)) + + SeparatedMaybe(SerializerConversions::ValueToString(_e)) + + SeparatedMaybe(SerializerConversions::ValueToString(_f)) + SerializerConversions::ValueToString(_g) + + SerializerConversions::ValueToString(_h) + SerializerConversions::ValueToString(_i); + } + + /** + * Creates string-based key using given variables. + */ + template + static string MakeKey(const A _a, const B _b, const C _c, const D _d, const E _e, const F _f, const G _g, const H _h, + const I _i, const J _j) { + return SeparatedMaybe(SerializerConversions::ValueToString(_a)) + + SeparatedMaybe(SerializerConversions::ValueToString(_b)) + + SeparatedMaybe(SerializerConversions::ValueToString(_c)) + + SeparatedMaybe(SerializerConversions::ValueToString(_d)) + + SeparatedMaybe(SerializerConversions::ValueToString(_e)) + + SeparatedMaybe(SerializerConversions::ValueToString(_f)) + SerializerConversions::ValueToString(_g) + + SerializerConversions::ValueToString(_h) + SerializerConversions::ValueToString(_i) + + SerializerConversions::ValueToString(_j); + } + + /** + * Creates string-based key using given variables. + */ + template + static string MakeKey(const A _a, const B _b, const C _c, const D _d, const E _e, const F _f, const G _g, const H _h, + const I _i, const J _j, const K _k) { + return SeparatedMaybe(SerializerConversions::ValueToString(_a)) + + SeparatedMaybe(SerializerConversions::ValueToString(_b)) + + SeparatedMaybe(SerializerConversions::ValueToString(_c)) + + SeparatedMaybe(SerializerConversions::ValueToString(_d)) + + SeparatedMaybe(SerializerConversions::ValueToString(_e)) + + SeparatedMaybe(SerializerConversions::ValueToString(_f)) + SerializerConversions::ValueToString(_g) + + SerializerConversions::ValueToString(_h) + SerializerConversions::ValueToString(_i) + + SerializerConversions::ValueToString(_j) + SerializerConversions::ValueToString(_k); + } + + /** + * Creates string-based key using given variables. + */ + template + static string MakeKey(const A _a, const B _b, const C _c, const D _d, const E _e, const F _f, const G _g, const H _h, + const I _i, const J _j, const K _k, const L _l) { + return SeparatedMaybe(SerializerConversions::ValueToString(_a)) + + SeparatedMaybe(SerializerConversions::ValueToString(_b)) + + SeparatedMaybe(SerializerConversions::ValueToString(_c)) + + SeparatedMaybe(SerializerConversions::ValueToString(_d)) + + SeparatedMaybe(SerializerConversions::ValueToString(_e)) + + SeparatedMaybe(SerializerConversions::ValueToString(_f)) + SerializerConversions::ValueToString(_g) + + SerializerConversions::ValueToString(_h) + SerializerConversions::ValueToString(_i) + + SerializerConversions::ValueToString(_j) + SerializerConversions::ValueToString(_k) + + SerializerConversions::ValueToString(_l); + } + + /** + * Creates string-based key using given variables. + */ + template + static string MakeKey(const A _a, const B _b, const C _c, const D _d, const E _e, const F _f, const G _g, const H _h, + const I _i, const J _j, const K _k, const L _l, const M _m) { + return SeparatedMaybe(SerializerConversions::ValueToString(_a)) + + SeparatedMaybe(SerializerConversions::ValueToString(_b)) + + SeparatedMaybe(SerializerConversions::ValueToString(_c)) + + SeparatedMaybe(SerializerConversions::ValueToString(_d)) + + SeparatedMaybe(SerializerConversions::ValueToString(_e)) + + SeparatedMaybe(SerializerConversions::ValueToString(_f)) + SerializerConversions::ValueToString(_g) + + SerializerConversions::ValueToString(_h) + SerializerConversions::ValueToString(_i) + + SerializerConversions::ValueToString(_j) + SerializerConversions::ValueToString(_k) + + SerializerConversions::ValueToString(_l) + SerializerConversions::ValueToString(_m); + } + /** * Creates string with separator if string was not empty. */ diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index c95c13c93..5d44e708b 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -410,7 +410,7 @@ bool InitIndicators() { indis.Push(new Indi_ADXW(adxw_params)); // AMA. - IndiAIndiMAParams ama_params(); + IndiAMAParams ama_params(); indis.Push(new Indi_AMA(ama_params)); // Chaikin Oscillator.