From b26dfa50dbc3e7b9ae0b44df12c71650c1c47750 Mon Sep 17 00:00:00 2001 From: kenorb Date: Mon, 27 Jun 2022 01:32:23 +0100 Subject: [PATCH] Fixes timeframe handling Indicator/Util: Adds more methods for iCustom5 --- Indicator.mqh | 29 ++++++++++++---- IndicatorBase.h | 7 ---- IndicatorData.mqh | 6 ++-- Storage/ValueStorage.indicator.h | 4 +-- Util.h | 59 ++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 18 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index 461bcc8f2..49670df3e 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -73,6 +73,17 @@ double iCustom5(string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C 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); } +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, K _k, L _l, M _m, 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, _k, _l, _m); + 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 COMMA _k COMMA _l COMMA _m); +} #endif /** @@ -87,9 +98,7 @@ class Indicator : public IndicatorData { protected: /* Protected methods */ - bool Init() { - return InitDraw(); - } + bool Init() { return InitDraw(); } /** * Initialize indicator data drawing on custom data. @@ -129,7 +138,8 @@ class Indicator : public IndicatorData { /** * Class constructor. */ - Indicator(const TS& _iparams, const IndicatorDataParams& _idparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) + Indicator(const TS& _iparams, const IndicatorDataParams& _idparams, IndicatorData* _indi_src = NULL, + int _indi_mode = 0) : IndicatorData(_idparams, _indi_src, _indi_mode) { iparams = _iparams; Init(); @@ -380,7 +390,8 @@ class Indicator : public IndicatorData { return true; } - if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE)) == IDATA_INDICATOR && GetDataSourceRaw() == NULL && _try_initialize) { + if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE)) == IDATA_INDICATOR && + GetDataSourceRaw() == NULL && _try_initialize) { SetDataSource(OnDataSourceRequest()); } @@ -402,6 +413,11 @@ class Indicator : public IndicatorData { */ // ENUM_TIMEFRAMES GetTf() { return Get(CHART_PARAM_TF); } + /** + * Gets indicator's time-frame. + */ + ENUM_TIMEFRAMES GetTf() { return iparams.tf.GetTf(); } + /** * Gets indicator's signals. * @@ -605,7 +621,8 @@ class Indicator : public IndicatorData { int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); // Print("Drawing ", GetName(), iparams.indi_data != NULL ? (" (over " + iparams.indi_data.GetName() + ")") : ""); for (int i = 0; i < _max_modes; ++i) - draw.DrawLineTo(GetName() + "_" + IntegerToString(i) + "_" + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)), + draw.DrawLineTo(GetName() + "_" + IntegerToString(i) + "_" + + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)), GetBarTime(0), GetEntry(0)[i], iparams.draw_window); } } diff --git a/IndicatorBase.h b/IndicatorBase.h index 39deaab62..94b662314 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -320,18 +320,11 @@ class IndicatorBase : public Chart { */ // virtual bool ToString() = NULL; // @fixme? - /* Methods to get rid of */ - /** * Gets indicator's symbol. */ string GetSymbol() { return Get(CHART_PARAM_SYMBOL); } - /** - * Gets indicator's time-frame. - */ - ENUM_TIMEFRAMES GetTf() { return Get(CHART_PARAM_TF); } - /* Defines MQL backward compatible methods */ double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, int _mode, int _shift) { diff --git a/IndicatorData.mqh b/IndicatorData.mqh index 21e374cee..0bc982946 100644 --- a/IndicatorData.mqh +++ b/IndicatorData.mqh @@ -474,8 +474,8 @@ class IndicatorData : public IndicatorBase { /* Getters */ - int GetBarsCalculated() { - int _bars = Bars(GetSymbol(), GetTf()); + int GetBarsCalculated(ENUM_TIMEFRAMES _tf = NULL) { + int _bars = Bars(GetSymbol(), _tf); if (!idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IS_FED))) { // Calculating start_bar. @@ -521,7 +521,7 @@ class IndicatorData : public IndicatorBase { Ref _indi = FetchDataSource(_type); if (!_indi.IsSet()) { Alert(GetFullName(), " does not define required indicator type ", EnumToString(_type), " for symbol ", - GetSymbol(), ", and timeframe ", GetTf(), "!"); + GetSymbol(), "!"); DebugBreak(); } else { indicators.Set((int)_type, _indi); diff --git a/Storage/ValueStorage.indicator.h b/Storage/ValueStorage.indicator.h index 928386577..6744660e6 100644 --- a/Storage/ValueStorage.indicator.h +++ b/Storage/ValueStorage.indicator.h @@ -51,8 +51,8 @@ class IndicatorBufferValueStorage : public HistoryValueStorage { /** * Constructor. */ - IndicatorBufferValueStorage(IndicatorData *_indi, int _mode = 0, bool _is_series = false) - : indicator(_indi), mode(_mode), HistoryValueStorage(_indi.GetSymbol(), _indi.GetTf()) {} + IndicatorBufferValueStorage(IndicatorData *_indi, int _mode = 0, ENUM_TIMEFRAMES _tf = NULL, bool _is_series = false) + : indicator(_indi), mode(_mode), HistoryValueStorage(_indi.GetSymbol(), _tf) {} /** * Fetches value from a given shift. Takes into consideration as-series flag. diff --git a/Util.h b/Util.h index 904fde211..a4a012cda 100644 --- a/Util.h +++ b/Util.h @@ -304,6 +304,65 @@ class Util { SerializerConversions::ValueToString(_l) + SerializerConversions::ValueToString(_m); } + /** + * 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, const N _n) { + 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) + + SerializerConversions::ValueToString(_n); + } + + /** + * 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, const N _n, const O _o) { + 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) + + SerializerConversions::ValueToString(_n) + SerializerConversions::ValueToString(_o); + } + + /** + * 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, const N _n, const O _o, + const P _p) { + 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) + + SerializerConversions::ValueToString(_n) + SerializerConversions::ValueToString(_o) + + SerializerConversions::ValueToString(_p); + } + /** * Creates string with separator if string was not empty. */